Schema

Delightfully simple, feature packed and customisable tool for validation and sanitization of any kind of data. Can be used on the client side as well as on the server side.

Source code is hosted on GitHub

  • Works with React, React Native, Angular, Vue or NodeJs

  • Plentitude of validation methods for different data types

  • Many useful sanitization methods for data normalization

  • Typed from tail to toe for amazing developer experience

  • Very intuitive and easy to use

  • Extremely flexible and extendable

  • Supports sync and async logic

  • Encourages you to build reusable schemas

  • Combine multiple schemas into more complex ones

  • Conditionally connect schemas for complex scenarios

  • Write custom validation and sanitization logic with ease

  • Easily override error messages

  • Comes translated into 6 different languages (English, German, French, Italian, Spanish and Russian)

  • Easily add a new language or override translation

yarn add @corets/schema

Concepts

There are two ways to run validations. For simple things like one-liners where you simply want to know if a value matches certain criteria, and get a true or false as result, you can use the Schema.test() method. For proper validation, with error messages instead of a simple true / false, you can use the Schema.validate() method.

Every schema specialises on a specific data type and comes with various assertion and sanitization methods. Some methods you'll be able to find on every schema, others are exclusive to a specific kind of schema.

Assertions are used for validation purposes to ensure that a value is valid.

Sanitization methods are called before validation and are used to normalise the underlying values. For example, you can ensure that a string is capitalised and all object keys are camel-cased. Sanitization can help you reduce the number of validation errors by proactively fixing them in the first place. All sanitization methods start with the prefix to, for example: string.toTrimmed(), string.toCamelCase().

Check out this React form library, it has a support for schemas and changes the way you work with forms:

Quick start

Here is an example of all the available schemas and how to import them:

import { 
    string, 
    number, 
    array, 
    boolean, 
    date, 
    object, 
    mixed 
} from "@corets/schema"

Let's describe a simple user object.

  • Property email must be of type string and a valid email address

  • Property fullName must be a string between 3 and 100 characters

  • Property roles must be an array containing at least one role, valid roles are admin, publisher and developer, no duplicates are allowed

  • Property tags must be an array of strings, each at least 3 characters long and consisting of letters and dashes

This schema contains some validation as well as some sanitization logic.

import { array, object, string } from "@corets/schema"

const roles = ["admin", "publisher", "developer"]

const userSchema = object({  
    email: string().email(),  
    fullName: string().min(3).max(100),  
    roles: array().min(1).someOf(roles).toUnique(),  
    tags: array(string().min(3).alphaDashes())
})

Quick check if an object is valid according to the schema:

const valid = userSchema.test({ ... })

if (valid) {
    // continue ...
}

Get a detailed list of errors:

const errors = userSchema.validate({ ... })

if ( ! errors) {
    // continue ...
}

The errors object would look something like this:

{  
    "field": ["first error", "second error"],  
    "nested.field": ["first error", "second error"],
}

Run sanitizers without any validation:

const sanitizedValue = userSchema.sanitize({ ... })

Test, validate and sanitize at the same time:

const [valid, sanitizedValue] = userSchema.sanitizeAndTest({ ... })
const [errors, sanitizedValue] = userSchema.sanitizeAndValidate({ ... })

Combining schemas

Schemas can be freely combined with one another. When describing arrays and objects there is no way around this. Here is an example of two schemas being combined:

import { array, string } from "@corets/schema"

const usernameSchema = string().alphaNumeric().between(3, 10)
const usernameListSchema = array(usernameSchema).min(3)
const errors = usernameListSchema.validate(["foo", "bar", "baz"])

Consider writing schemas that are reusable.

Conditional validations

Schemas can be logically linked together using methods Schema.and(), Schema.or() and Schema.also(). A Schema.and() relation will only be executed if the parent schema, that it is linked to, could validate successfully. A Schema.or() relation will only execute if the parent schema failed, the alternative schema will be attempted instead. A Schema.also() relation will execute regardless of the validation status of the parent schema.

Example of a Schema.and() relation, this schema will first ensure that the value is a string, and only if the first validation passes, it will test if the value is a numeric string:

import { string } from "@corets/schema"

string().and(string().numeric())

Example of a Schema.or() relation, this schema will first check if the value is a number, and only if it's not, it will test if that value is a numeric string:

import { number, string } from "@corets/schema"

number().or(string().numeric())

Example of an Schema.also() relation, this schema will execute both parts regardless of the validation outcome of the parent schema:

import { string } from "@corets/schema"

string().also(string().numeric())

Conditional schemas can be wrapped into a function, this allows you to define schemas dynamically during the validation:

import { string } from "@corets/schema"

string().and(() => string().numeric())
string().or(() => string().numeric())
string().also(() => string().numeric())

You can freely define validations and sanitizers at runtime using logical links.

Logical links can be used to attach custom validation logic:

import { string } from "@corets/schema"

string().min(3).max(20)
    .and(async (v) => await isUsernameTaken(v) && "Username is already taken")

Custom validations

Methods Schema.and(), Schema.or() and Schema.also() do not always have to return another schema. They can be used for your custom validation functions. A custom validation function can return either another schema, a validation result, or an error message.

Example of a validation function returning an error message:

import { number } from "@corets/schema"

const customValidation = (value: any) => value < 12 && "Must be bigger than 12"

number().and(customValidation)
number().or(customValidation)
number().also(customValidation)

You can also return multiple error messages at once using an array.

Example of a validation function returning a schema:

import { string } from "@corets/schema"

const customValidation = (value: any) => value.includes("@") && string().email()

string().and(customValidation)
string().or(customValidation)
string().also(customValidation)

Example of a validation function returning schema validation errors:

import { string } from "@corets/schema"

const customValidation = (value: any) => 
    value.includes("@") && string().email().verify(value)

string().and(customValidation)
string().or(customValidation)
string().also(customValidation)

Custom sanitizers

You can add a custom sanitizer with the method Schema.map(), here is an example of a sanitizer that converts everything to a string:

import { string } from "@corets/schema"

const customSanitizer = (value: any) => value.toString()
const sanitizedValue = string().map(customSanitizer).sanitize(1234)

Translations

All the translation logic is handled by this library:

You can change default language:

import { schemaTranslator } from "@corets/schema"

schemaTranslator.setLanguage("en")

You can also request a specific language during validation:

import { string } from "@corets/schema"

string().validate("foo", { language: "ru", fallbackLanguage: "en" })
string().verify("foo", { language: "ru", fallbackLanguage: "en" })
string().sanitizeAndValidate("foo", { language: "ru", fallbackLanguage: "en" })
string().sanitizeAndVerify("foo", { language: "ru", fallbackLanguage: "en" })

Get a full list of all translations:

import { schemaTranslator } from "@corets/schema"

console.log(schemaTranslator.getTranslations())

You can find all locales here. For further examples of how to replace translations, add new languages, etc., please have a look at the @corets/translator docs.

Schema.test()

This method simply indicates whether a value is valid or not by returning a boolean.

Example of a failed assertion:

import { string } from "@corets/schema"

const schema = string().min(3).alphaNumeric()
// false
const valid = schema.test("foo-bar")

if (valid) {
    // continue ...
}

Schema.validate()

This method returns a validation result containing detailed error messages about why a value did not pass validation.

Example of a failed validation:

import { string } from "@corets/schema"

const schema = string().min(3).alphaNumeric()
const errors = schema.validate("foo-bar")

if ( ! errors) {
    // continue ...
}

This is what the validation result might look like:

{  
    "field": ["first error", "second error"],  
    "nested.field": ["first error", "second error"],
}

When validating anything but an object, you'll find all the error messages under the key self.

Schema.verify()

This method works the same as Schema.validate(), except it returns errors in a slightly different format. This format contains additional information about each error message and can be used for further processing of validation errors.

Example of a failed validation:

import { string } from "@corets/schema"

const errors = string().min(10).verify("foo")

Here is an example of how the error messages would look like:

[  
    {    
        "type": "string_min",    
        "message": "Must be at least \"2\" characters long",    
        "args": [10],    
        "value": "foo",    
        "link": undefined,    
        "path": undefined  
    }
]

Schema.sanitize()

This method applies sanitizers and returns the sanitized value:

import { string } from "@corets/schema"

const schema = string().toTrimmed().toCamelCase()
const value = schema.sanitize("  foo bar  ")

All sanitization methods start with the prefix to, for example: string.toTrimmed().

Schema.sanitizeAndTest()

This method applies sanitizers on the underlying value and runs validation against the sanitized version. It returns a boolean indicating whether the value is valid, and the sanitized version of the value. Basically this calls the methods Schema.sanitize() and Schema.test() sequentially.

Example of a successful test with sanitizers:

import { string } from "@corets/schema"

const schema = string().min(4).toCamelCase()
const [valid, value] = schema.sanitizeAndTest("foo bar")

Example of a failed test with sanitizers:

import { string } from "@corets/schema"

const schema = string().min(4).toTrimmed()
const [valid, value] = schema.sanitizeAndTest("  foo  ")

As you can see, even though the string " foo " has a length greater than 4. During the sanitization, value gets trimmed, becomes"foo" and therefore the test will fail.

All sanitization methods start with the prefix to, for example: string.toTrimmed().

Schema.sanitizeAndValidate()

This method applies sanitizers on the underlying value and runs validation against the sanitized version. It returns a validation result containing detailed error messages about why a value did not pass validation, and the sanitized version of the value. Basically this calls the methods Schema.sanitize() and Schema.validate() sequentially.

Example of a successful validation with sanitizers:

import { string } from "@corets/schema"

const schema = string().min(4).toCamelCase()
const [errors, value] = schema.sanitizeAndValidate("foo bar")

Example of a failed validation with sanitizers:

import { string } from "@corets/schema"

const schema = string().min(4).toTrimmed()
const [errors, value] = schema.sanitizeAndValidate("  foo  ")

This is what the errors would look like:

{  
    "self": ["Must be at least \"4\" characters long"],
}

Schema.sanitizeAndVerify()

This method works exactly the same as Schema.anitizeAndValidate() except that it returns error messages in a different format with additional information that can be used for further processing. Take a look at Schema.verify() to learn more about its use cases.

All sanitization methods start with the prefix to, for example: string.toTrimmed().

Schema.testAsync()

This is an async version of the Schema.test() method, that allows you to use async validators and sanitizers.

This library has no async validation or sanitization methods itself, but you can add your own.

Schema.validateAsync()

This is an async version of the Schema.validate() method, that allows you to use async validators.

This library has no async validation or sanitization methods itself, but you can add your own.

Schema.verifyAsync()

This is an async version of the Schema.verify() method, that allows you to use async validators.

This library has no async validation or sanitization methods itself, but you can add your own.

Schema.sanitizeAsync()

This is an async version of the Schema.sanitize() method, that allows you to use async sanitizers.

This library has no async validation or sanitization methods itself, but you can add your own.

Schema.sanitizeAndTestAsync()

This is an async version of the Schema.sanitizeAndTest() method, that allows you to use async validators and sanitizers.

This library has no async validation or sanitization methods itself, but you can add your own.

Schema.sanitizeAndValidateAsync()

This is an async version of the Schema.sanitizeAndValidate() method, that allows you to use async validators and sanitizers.

This library has no async validation or sanitization methods itself, but you can add your own.

Schema.sanitizeAndVerifyAsync()

This is an async version of the Schema.sanitizeAndVerify() method, that allows you to use async validators and sanitizers.

This library has no async validation or sanitization methods itself, but you can add your own.

Schema.also()

Connects multiple schemas or attaches a custom validation function to a schema. Connections made with this link are invoked regardless of the status of the parent schema. This is perfect when you try to combine multiple schemas or attach a custom validation function to a schema to make it behave like one single unit.

import { string } from "@corets/schema"

const usernameSchema = string().alphaNumeric()
const advancedUsernameSchema = string().min(3).max(20).also(usernameSchema)
const uniqueUsernameSchema = advancedUsernameSchema.also(
    async (v) => await isUsernameTaken(v) && "Username already taken"
)

See also custom validations for more examples.

Schema.and()

Logically connects multiple schemas, or a custom validation function to a schema. Schemas and validation functions connected using this link will only be executed if the parent schema validated successfully. This is a good way to connect expensive validation logic, like a database call, and make sure that it is only invoked when it's really necessary.

import { string } from "@corets/schema"

const usernameSchema = string().alphaNumeric()
const advancedUsernameSchema = string().min(3).max(20).and(usernameSchema)
const uniqueUsernameSchema = advancedUsernameSchema.and(
    async (v) => await isUsernameTaken(v) && "Username already taken"
)

See also custom validations and conditional validations for more examples.

Schema.or()

Logically connects multiple schemas, or a custom validation function to a schema. Schemas and validation functions connected using this link will only be executed if the parent schema validation has failed. This is useful if you want to provide an alternative validation procedure.

import { string } from "@corets/schema"

const usernameOrEmail = string()
    .alphaNumeric().min(3).max(20)
    .or(v => v.includes("@") && string().email())

See also custom validations and conditional validations for more examples.

Schema.map()

Attach a custom sanitizer function to a schema.

import { mixed } from "@corets/schema"

mixed().map(v => v.toString())

See also custom sanitizers for more examples.

schema()

This factory is used as a central entry point to create any kind of schema by providing the default value first.

import { schema } from "@corets/schema"

const stringSchema = schema("foo").string()

The example above is equivalent to this:

import { string } from "@corets/schema"

const schema = string().toDefault("foo")

Defining a default value is optional, but might be useful when validating forms.

schema.string()

Create a new string() schema starting with the default value:

import { schema } from "@corets/schema"

schema("foo").string()

schema.number()

Create a new number() schema starting with the default value:

import { schema } from "@corets/schema"

schema(123).number()

schema.boolean()

Create a new boolean() schema starting with the default value:

import { schema } from "@corets/schema"

schema(true).boolean()

schema.date()

Create a new date() schema starting with the default value:

import { schema } from "@corets/schema"

schema(new Date()).date()

schema.array()

Create a new array() schema starting with the default value:

import { schema } from "@corets/schema"

schema(["foo"]).array()

schema.object()

Create a new object() schema starting with the default value:

import { schema } from "@corets/schema"

schema({ foo: "bar" }).object()

schema.mixed()

Create a new mixed() schema starting with the default value:

import { schema } from "@corets/schema"

schema("foo").mixed()

string()

Contains various validators and sanitisers for strings:

import { string } from "@corets/schema"

string()

Create a schema instance without the factory function:

import { StringSchema } from "@corets/schema"

new StringSchema()

string.required()

Value must be a non-empty string:

import { string } from "@corets/schema"

string().required()
string().required(true, "Message")
string().required(() => true, () => "Message")

string.optional()

Value might be a string, opposite of string.required():

import { string } from "@corets/schema"

string().optional()
string().optional("Message")
string().optional(() => "Message")

string.equals()

String must be equal to the given value:

import { string } from "@corets/schema"

string().equals("foo")
string().equals("foo", "Message")
string().equals(() => "foo", () => "Message")

string.length()

String must have an exact length:

import { string } from "@corets/schema"

string().length(3)
string().length(3, "Message")
string().length(() => 3, () => "Message")

string.min()

String must not be shorter than given value:

import { string } from "@corets/schema"

string().min(3)
string().min(3, "Message")
string().min(() => 3, () => "Message")

string.max()

String must not be longer than given value:

import { string } from "@corets/schema"

string().max(3)
string().max(3, "Message")
string().max(() => 3, () => "Message")

string.between()

String must have a length between min and max:

import { string } from "@corets/schema"

string().between(3, 6)
string().between(3, 6, "Message")
string().between(() => 3, () => 6, () => "Message")

string.matches()

String must match given RegExp:

import { string } from "@corets/schema"

string().matches(/^red/)
string().matches(/^red/, "Message")
string().matches(() => /^red/, () => "Message")

string.email()

String must be a valid email address:

import { string } from "@corets/schema"

string().email()
string().email("Message")
string().email(() => "Message")

string.url()

String must be a valid URL:

import { string } from "@corets/schema"

string().url()
string().url("Message")
string().url(() => "Message")

string.startsWith()

String must start with a given value:

import { string } from "@corets/schema"

string().startsWith("foo")
string().startsWith("foo", "Message")
string().startsWith(() => "foo", () => "Message")

string.endsWith()

String must end with a given value:

import { string } from "@corets/schema"

string().endsWith("foo")
string().endsWith("foo", "Message")
string().endsWith(() => "foo", () => "Message")

string.includes()

String must include a given substring:

import { string } from "@corets/schema"

string().includes("foo")
string().includes("foo", "Message")
string().includes(() => "foo", () => "Message")

string.omits()

String must not include a given substring:

import { string } from "@corets/schema"

string().omits("foo")
string().omits("foo", "Message")
string().omits(() => "foo", () => "Message")

string.oneOf()

String must be one of the whitelisted values:

import { string } from "@corets/schema"

string().oneOf(["foo", "bar"])
string().oneOf(["foo", "bar"], "Message")
string().oneOf(() => ["foo", "bar"], () => "Message")

string.noneOf()

String must not be one of the blacklisted values:

import { string } from "@corets/schema"

string().noneOf(["foo", "bar"])
string().noneOf(["foo", "bar"], "Message")
string().noneOf(() => ["foo", "bar"], () => "Message")

string.numeric()

String must contain numbers only, including floats:

import { string } from "@corets/schema"

string().numeric()
string().numeric("Message")
string().numeric(() => "Message")

string.alpha()

String must contain letters only:

import { string } from "@corets/schema"

string().alpha()
string().alpha("Message")
string().alpha(() => "Message")

string.alphaNumeric()

String must contain numbers and letters only:

import { string } from "@corets/schema"

string().alphaNumeric()
string().alphaNumeric("Message")
string().alphaNumeric(() => "Message")

string.alphaDashes()

String must contain letters and dashes - only:

import { string } from "@corets/schema"

string().alphaDashes()
string().alphaDashes("Message")
string().alphaDashes(() => "Message")

string.alphaUnderscores()

String must contain letters and underscores _ only:

import { string } from "@corets/schema"

string().alphaUnderscores()
string().alphaUnderscores("Message")
string().alphaUnderscores(() => "Message")

string.alphaNumericDashes()

String must contain letters, numbers and dashes only:

import { string } from "@corets/schema"

string().alphaNumericDashes()
string().alphaNumericDashes("Message")
string().alphaNumericDashes(() => "Message")

string.alphaNumericUnderscores()

String must contain letters, numbers and underscores only:

import { string } from "@corets/schema"

string().alphaNumericUnderscores()
string().alphaNumericUnderscores("Message")
string().alphaNumericUnderscores(() => "Message")

string.date()

String must be a valid ISO date string:

import { string } from "@corets/schema"

string().date()
string().date("Message")
string().date(() => "Message")

string.dateBefore()

String must be a valid ISO date string before the given date:

import { string } from "@corets/schema"

string().dateBefore(new Date())
string().dateBefore(new Date(), "Message")
string().dateBefore(() => new Date(), () => "Message")

string.dateBeforeOrEqual()

Similar to string.dateBefore(), but allows dates to be equal:

import { string } from "@corets/schema"

string().dateBeforeOrEqual(new Date())
string().dateBeforeOrEqual(new Date(), "Message")
string().dateBeforeOrEqual(() => new Date(), () => "Message")

string.dateAfter()

String must be a valid ISO date string after the given date:

import { string } from "@corets/schema"

string().dateAfter(new Date())
string().dateAfter(new Date(), "Message")
string().dateAfter(() => new Date(), () => "Message")

string.dateAfterOrEqual()

Similar to string.dateAfter(), but allows dates to be equal:

import { string } from "@corets/schema"

string().dateAfterOrEqual(new Date())
string().dateAfterOrEqual(new Date(), "Message")
string().dateAfterOrEqual(() => new Date(), () => "Message")

string.dateBetween()

String must be a valid ISO date string between the two given dates:

import { string } from "@corets/schema"

string().dateBetween(new Date(), new Date())
string().dateBetween(new Date(), new Date(), "Message")
string().dateBetween(() => new Date(), () => new Date(), () => "Message")

string.dateBetweenOrEqual()

Similar to string.dateBetween(), but allows dates to be equal:

import { string } from "@corets/schema"

string().dateBetweenOrEqual(new Date(), new Date())
string().dateBetweenOrEqual(new Date(), new Date(), "Message")
string().dateBetweenOrEqual(() => new Date(), () => new Date(), () => "Message")

string.time()

String must be a valid ISO time string:

import { string } from "@corets/schema"

string().time()
string().time("Message")
string().time(() => "Message")

string.timeBefore()

String must be a valid time string before the given time:

import { string } from "@corets/schema"

string().timeBefore("10:00")
string().timeBefore("10:00", "Message")
string().timeBefore(() => "10:00", () => "Message")

string.timeBeforeOrEqual()

Similar to string.timeBefore(), but allows times to be equal:

import { string } from "@corets/schema"

string().timeBeforeOrEqual("10:00")
string().timeBeforeOrEqual("10:00", "Message")
string().timeBeforeOrEqual(() => "10:00", () => "Message")

string.timeAfter()

String must be a valid time string after the given time:

import { string } from "@corets/schema"

string().timeAfter("10:00")
string().timeAfter("10:00", "Message")
string().timeAfter(() => "10:00", () => "Message")

string.timeAfterOrEqual()

Similar to string.timeAfter(), but allows times to be equal:

import { string } from "@corets/schema"

string().timeAfterOrEqual("10:00")
string().timeAfterOrEqual("10:00", "Message")
string().timeAfterOrEqual(() => "10:00", () => "Message")

string.timeBetween()

String must be a valid time string between the two given times:

import { string } from "@corets/schema"

string().timeBetween("10:00", "15:00")
string().timeBetween("10:00", "15:00", "Message")
string().timeBetween(() => "10:00", () => "15:00", () => "Message")

string.timeBetweenOrEqual()

Similar to string.timeBetween(), but allows times to be equal:

import { string } from "@corets/schema"

string().timeBetweenOrEqual("10:00", "15:00")
string().timeBetweenOrEqual("10:00", "15:00", "Message")
string().timeBetweenOrEqual(() => "10:00", () => "15:00", () => "Message")

string.dateTime()

String must be a valid ISO date time string:

import { string } from "@corets/schema"

string().dateTime()
string().dateTime("Message")
string().dateTime(() => "Message")

string.toDefault()

Provide a fallback value in case the underlying value is not a string:

import { string } from "@corets/schema"

string().toDefault("default value")
string().toDefault("default value")
string().toDefault(() => "default value")

string.toUpperCase()

Convert string to all upper case:

import { string } from "@corets/schema"

string().toUpperCase()

string.toLowerCase()

Convert string to all lower case:

import { string } from "@corets/schema"

string().toLowerCase()

string.toCapitalized()

Capitalize first letter:

import { string } from "@corets/schema"

string().toCapitalized()

string.toCamelCase()

Convert string to camelCase:

import { string } from "@corets/schema"

string().toCamelCase()

string.toSnakeCase()

Convert string to snake_case:

import { string } from "@corets/schema"

string().toSnakeCase()

string.toKebabCase()

Convert string to kebab-case:

import { string } from "@corets/schema"

string().toKebabCase()

string.toConstantCase()

Convert string to CONSTANT_CASE:

import { string } from "@corets/schema"

string().toConstantCase()

string.toTrimmed()

Trim surrounding whitespace:

import { string } from "@corets/schema"

string().toTrimmed()

number()

Contains various validators and sanitizers for numbers:

import { number } from "@corets/schema"

number()

Create a schema instance without the factory function:

import { NumberSchema } from "@corets/schema"

new NumberSchema()

number.required()

Value must be a number:

import { number } from "@corets/schema"

number().required()
number().required("Message")
number().required(() => false, () => "Message")

number.optional()

Value might be a number, opposite of number.required():

import { number } from "@corets/schema"

number().optional()
number().optional("Message")
number().optional(() => "Message")

number.equals()

Number must be equal to the given value:

import { number } from "@corets/schema"

number().equals(3)
number().equals(3, "Message")
number().equals(() => 3, () => "Message")

number.min()

Number must not be smaller than the given value:

import { number } from "@corets/schema"

number().min(5)
number().min(5, "Message")
number().min(() => 5, () => "Message")

number.max()

Number must not be bigger than the given value:

import { number } from "@corets/schema"

number().max(10)
number().max(10, "Message")
number().max(() => 10, () => "Message")

number.between()

Number must be between the two given numbers:

import { number } from "@corets/schema"

number().between(5, 10)
number().between(5, 10, "Message")
number().between(() => 5, () => 10, () => "Message")

number.between()

Number must be positive - bigger than zero:

import { number } from "@corets/schema"

number().positive()
number().positive("Message")
number().positive(() => "Message")

number.negative()

Number must be negative:

import { number } from "@corets/schema"

number().negative()
number().negative("Message")
number().negative(() => "Message")

number.integer()

Number must be an integer:

import { number } from "@corets/schema"

number().integer()
number().integer("Message")
number().integer(() => "Message")

number.oneOf()

Number must be one of the whitelisted values:

import { number } from "@corets/schema"

number().oneOf([10, 20])
number().oneOf([10, 20], "Message")
number().oneOf(() => [10, 20], () => "Message")

number.noneOf()

Number must not be one of the blacklisted values:

import { number } from "@corets/schema"

number().noneOf([10, 20])
number().noneOf([10, 20], "Message")
number().noneOf(() => [10, 20], () => "Message")

number.toDefault()

Default value in case the underlying value is not a number:

import { number } from "@corets/schema"

number().toDefault(10)
number().toDefault(() => 10)

number.toRounded()

Round value using lodash.round():

import { number } from "@corets/schema"

const precision = 2

number().toRounded()
number().toRounded(precision)
number().toRounded(() => precision)

number.toFloored()

Round value using lodash.floor():

import { number } from "@corets/schema"

const precision = 2

number().toFloored()
number().toFloored(precision)
number().toFloored(() => precision)

number.toCeiled()

Round value using lodash.ceil():

import { number } from "@corets/schema"

const precision = 2

number().toCeiled()
number().toCeiled(precision)
number().toCeiled(() => precision)

number.toTrunced()

Trunc value using Math.trunc()(drops everything after the decimal point):

import { number } from "@corets/schema"

number().toTrunced()

boolean()

Contains various validators and sanitizers for booleans:

import { boolean } from "@corets/schema"

boolean()

Create a schema instance without the factory function:

import { BooleanSchema } from "@corets/schema"

new BooleanSchema()

boolean.required()

Value must be a boolean:

import { boolean } from "@corets/schema"

boolean().required()
boolean().required(false, "Message")
boolean().required(() => false, () =>"Message")

boolean.optional()

Value might be a boolean, opposite of boolean.required():

import { boolean } from "@corets/schema"

boolean().optional()
boolean().optional("Message")
boolean().optional(() => "Message")

boolean.equals()

Number must be equal to the given value:

import { boolean } from "@corets/schema"

boolean().equals(true)
boolean().equals(true, "Message")
boolean().equals(() => true, () => "Message")

boolean.toDefault()

Provide a fallback value in case the underlying value is not a boolean:

import { boolean } from "@corets/schema"

boolean().toDefault(true)
boolean().toDefault(() => true)

date()

Contains various validators and sanitizers for dates:

import { date } from "@corets/schema"

date()

Create a schema instance without the factory function:

import { DateSchema } from "@corets/schema"

new DateSchema()

date.required()

Value must be a date:

import { date } from "@corets/schema"

date().required()
date().required(false, "Message")
date().required(() => false, () => "Message")

date.optional()

Value might be a date, opposite of date.required():

import { date } from "@corets/schema"

date().optional()
date().optional("Message")
date().optional(() => "Message")

date.equals()

Date must be equal to the given value:

import { date } from "@corets/schema"

date().equals(new Date())
date().equals(new Date(), "Message")
date().equals(() => new Date(), () => "Message")

date.after()

Underlying value must be after the given date:

import { date } from "@corets/schema"

date().after(new Date())
date().after(new Date(), "Message")
date().after(() => new Date(), () => "Message")

date.before()

Underlying value must be before the given date:

import { date } from "@corets/schema"

date().before(new Date())
date().before(new Date(), "Message")
date().before(() => new Date(), () => "Message")

date.between()

Underlying value must be between the two dates:

import { date } from "@corets/schema"

date().between(new Date(), new Date())
date().between(new Date(), new Date(), "Message")
date().between(() => new Date(), () => new Date(), () => "Message")

date.toDefault()

Provide a fallback value in case the underlying value is not a date:

import { date } from "@corets/schema"

date().toDefault(new Date())
date().toDefault(new Date(), "Message")
date().toDefault(() => new Date(), () => "Message")

array()

Contains various validators and sanitizers for arrays:

import { array, string } from "@corets/schema"

array()

Create a schema instance without the factory function:

import { ArraySchema } from "@corets/schema"

new ArraySchema()

Create an array schema with a separate schema for its children:

import { array, string } from "@corets/schema"

array(string().min(2))

array.required()

Value must be an array:

import { array } from "@corets/schema"

array().required()
array().required(false, "Message")
array().required(() => false, () => "Message")

array.optional()

Value might be a array, opposite of array.required():

import { array } from "@corets/schema"

array().optional()
array().optional("Message")
array().optional(() => "Message")

array.equals()

Array must be equal to the given value:

import { array } from "@corets/schema"

array().equals([1, 2])
array().equals([1, 2], "Message")
array().equals(() => [1, 2], () => "Message")

array.length()

Array must have an exact length:

import { array } from "@corets/schema"

array().length(3)
array().length(3, "Message")
array().length(() => 3, () => "Message")

array.min()

Array must not be shorter than the given length:

import { array } from "@corets/schema"

array().min(3)
array().min(3, "Message")
array().min(() => 3, () => "Message")

array.max()

Array must not be longer than the given length:

import { array } from "@corets/schema"

array().max(3)
array().max(3, "Message")
array().max(() => 3, () => "Message")

array.between()

Array must have a length between the two given values:

import { array } from "@corets/schema"

array().between(3, 5)
array().between(3, 5, "Message")
array().between(() => 3, () => 5, () => "Message")

array.someOf()

Array must only contain whitelisted values:

import { array } from "@corets/schema"

array().someOf([3, 4])
array().someOf([3, 4], "Message")
array().someOf(() => [3, 4], () => "Message")

array.noneOf()

Array must not contain any of the blacklisted values:

import { array } from "@corets/schema"

array().noneOf([3, 4])
array().noneOf([3, 4], "Message")
array().noneOf(() => [3, 4], () => "Message")

array.shape()

Specify a schema for array children, every item must be valid according to the given schema:

import { array, string } from "@corets/schema"

array().shape(string().min(3))
array().shape(() => string().min(3))

You can pass a shape directly to the array() method too:

import { array, string } from "@corets/schema"

array(string().min(3))
array(() => string().min(3))

array.toDefault()

Provide a default value in case the underlying value is not an array:

import { array } from "@corets/schema"

array().toDefault([1, 2])
array().toDefault(() => [1, 2])

array.toFiltered()

Filter out invalid array items manually:

import { array } from "@corets/schema"

const isString = (value) => typeof value === "string"

array().toFiltered(isString)

array.toMapped()

Map every array item manually:

import { array } from "@corets/schema"

const toUpperCase = (value) => typeof value === "string" 
    ? value.toUpperCase() 
    : value

array().toMapped(toUpperCase)

array.toCompact()

Filter out all falsey values like null, undefined, "" and 0:

import { array } from "@corets/schema"

array().toCompact()

array.toUnique()

Filter out all duplicate values:

import { array } from "@corets/schema"

array().toUnique()

object()

Contains various validators and sanitizers for objects:

import { object, string } from "@corets/schema"

object()

Create a schema instance without the factory function:

import { ObjectSchema } from "@corets/schema"

new ObjectSchema()

Create an object schema with a separate schema for each property:

import { object, string } from "@corets/schema"

object({
    foo: string().min(2)
})

object.required()

Value must be an object:

import { object } from "@corets/schema"

object().required()
object().required(false, "Message")
object().required(() => false, () => "Message")

object.optional()

Value might be an object, opposite of object.required():

import { object } from "@corets/schema"

object().optional()
object().optional("Message")
object().optional(() => "Message")

object.equals()

Underlying value must be equal to the given value:

import { object } from "@corets/schema"

object().equals({foo: "bar"})
object().equals({foo: "bar"}, "Message")
object().equals(() => {foo: "bar"}, () => "Message")

object.shape()

Shape an object and set up schemas for all of its properties:

import { object, string } from "@corets/schema"

object().shape({
    firstName: string().min(3).max(20) 
})

You can pass a shape directly to the object() method too:

import { object, string } from "@corets/schema"

object({ 
    firstName: string().min(3).max(20) 
})

object.allowUnknownKeys()

Allow object to contain keys that have not been configured through object.shape():

import { object, string } from "@corets/schema"

object({ 
    firstName: string().min(3).max(20) 
}).allowUnknownKeys()

object.forbidUnknownKeys()

Forbid object to contain keys that have not been configured through object.shape():

import { object, string } from "@corets/schema"

object({ 
    firstName: string().min(3).max(20) 
}).forbidUnknownKeys()

object.shapeUnknownKeys()

Shape unknown object keys to make sure they adhere to a certain standard:

import { object, string } from "@corets/schema"

object({ 
    firstName: string().min(3).max(20) 
}).shapeUnknownKeys(string().min(3).toCamelCase())

object.shapeUnknownValues()

Shape unknown object values to make sure they adhere to a standard:

import { object, string } from "@corets/schema"

object({ 
    firstName: string().min(3).max(20) 
}).shapeUnknownValues(string().min(3).max(20))

object.toDefault()

Provide a fallback value in case the underlying value is not an object:

import { object } from "@corets/schema"

object().toDefault({ title: "Foo" })
object().toDefault(() => ({ title: "Foo" }))

object.toCamelCaseKeys()

Transform all object keys to camelCase:

import { object } from "@corets/schema"

object().toCamelCaseKeys()
// disable deep mapping
object().toCamelCaseKeys(false)

object.toSnakeCaseKeys()

Transform all object keys to snake_case:

import { object } from "@corets/schema"

object().toSnakeCaseKeys()
// disable deep mapping
object().toSnakeCaseKeys(false)

object.toKebabCaseKeys()

Transform all object keys to kebab-case:

import { object } from "@corets/schema"

object().toKebabCaseKeys()
// disable deep mapping
object().toKebabCaseKeys(false)

object.toConstantCaseKeys()

Transform all object keys to CONSTANT_CASE:

import { object } from "@corets/schema"

object().toConstantCaseKeys()
// disable deep mapping
object().toConstantCaseKeys(false)

object.toMappedValues()

Transform all object values:

import { object } from "@corets/schema"

object().toMappedValues((value, key) => value)
// disable deep mapping
object().toConstantCaseKeys(false)

object.toMappedKeys()

Transform all object keys:

import { object } from "@corets/schema"

object().toMappedKeys((value, key) => key)
// disable deep mapping
object().toMappedKeys((value, key) => key, false)

mixed()

Contains various validators and sanitizers for mixed data types:

import { mixed } from "@corets/schema"

mixed()

Create a schema instance without the factory function:

import { MixedSchema } from "@corets/schema"

new MixedSchema()

mixed.required()

Value must not be null nor undefined:

import { mixed } from "@corets/schema"

mixed().required()
mixed().required(false, "Message")
mixed().required(() => false, () => "Message")

mixed.optional()

Value might als be a null or undefined, opposite of mixed.required():

import { mixed } from "@corets/schema"

mixed().optional()
mixed().optional("Message")
mixed().optional(() => "Message")

mixed.equals()

Underlying value must be equal to the given value:

import { mixed } from "@corets/schema"

mixed().equals("yolo")
mixed().equals("yolo", "Message")
mixed().equals(() => "yolo", () => "Message")

mixed.oneOf()

Underlying value must be one of the whitelisted values:

import { mixed } from "@corets/schema"

mixed().oneOf(["foo", "bar"])
mixed().oneOf(["foo", "bar"], "Message")
mixed().oneOf(() => ["foo", "bar"], () => "Message")

mixed.noneOf()

Underlying value must not be one of the blacklisted values:

import { mixed } from "@corets/schema"

mixed().noneOf(["foo", "bar"])
mixed().noneOf(["foo", "bar"], "Message")
mixed().noneOf(() => ["foo", "bar"], () => "Message")

mixed.toDefault()

Provide a fallback value in case the underlying value is null or undefined:

import { mixed } from "@corets/schema"

mixed().toDefault("foo")
mixed().toDefault("foo", "Message")
mixed().toDefault(() => "foo", () => "Message")

Last updated