# Schema

Source code is hosted on [GitHub](https://github.com/corets/schema)

* **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**

{% tabs %}
{% tab title="yarn" %}

```bash
yarn add @corets/schema
```

{% endtab %}

{% tab title="npm" %}

```bash
npm install --save @corets/schema
```

{% endtab %}
{% endtabs %}

## 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()`](/services/schema.md#schematest) method. For proper validation, with error messages instead of a simple `true` / `false`, you can use the [`Schema.validate()`](/services/schema.md#schemavalidate) 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()`](/services/schema.md#stringtotrimmed), [`string.toCamelCase()`](/services/schema.md#stringtocamelcase).

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

{% content-ref url="/pages/-MeeF80BrEndyj5EzdPB" %}
[Form](/services/form.md)
{% endcontent-ref %}

## Quick start <a href="#quick-start" id="quick-start"></a>

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

```typescript
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.

```typescript
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:

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

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

Get a detailed list of errors:

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

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

The errors object would look something like this:

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

Run sanitizers without any validation:

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

Test, validate and sanitize at the same time:

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

## Combining schemas <a href="#combining-schemas" id="combining-schemas"></a>

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:

```typescript
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"])
```

{% hint style="info" %}
Consider writing schemas that are reusable.
{% endhint %}

## Conditional validations <a href="#conditional-validations" id="conditional-validations"></a>

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

Example of a [`Schema.and()`](/services/schema.md#schemaand) 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:

```typescript
import { string } from "@corets/schema"

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

Example of a [`Schema.or()`](/services/schema.md#schemaor) 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:

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

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

Example of an [`Schema.also()`](/services/schema.md#schemaalso) relation, this schema will execute both parts regardless of the validation outcome of the parent schema:

```typescript
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:

```typescript
import { string } from "@corets/schema"

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

{% hint style="info" %}
You can freely define validations and sanitizers at runtime using logical links.
{% endhint %}

Logical links can be used to attach custom validation logic:

```typescript
import { string } from "@corets/schema"

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

## Custom validations <a href="#custom-validations" id="custom-validations"></a>

Methods [`Schema.and()`](/services/schema.md#schemaand), [`Schema.or()`](/services/schema.md#schemaor) and [`Schema.also()`](/services/schema.md#schemaalso) 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:

```typescript
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)
```

{% hint style="info" %}
You can also return multiple error messages at once using an array.
{% endhint %}

Example of a validation function returning a schema:

```typescript
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:

```typescript
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 <a href="#custom-sanitizers" id="custom-sanitizers"></a>

You can add a custom sanitizer with the method [`Schema.map()`](/services/schema.md#schemamap), here is an example of a sanitizer that converts everything to a string:

```typescript
import { string } from "@corets/schema"

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

## Translations <a href="#translations" id="translations"></a>

All the translation logic is handled by this library:

{% content-ref url="/pages/-MeeFAgcZV96KXm0W1WU" %}
[Translator](/services/translator.md)
{% endcontent-ref %}

You can change default language:

```typescript
import { schemaTranslator } from "@corets/schema"

schemaTranslator.setLanguage("en")
```

You can also request a specific language during validation:

```typescript
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:

```typescript
import { schemaTranslator } from "@corets/schema"

console.log(schemaTranslator.getTranslations())
```

{% hint style="info" %}
You can find all locales [here](https://github.com/corets/schema/tree/master/src/locales). For further examples of how to replace translations, add new languages, etc., please have a look at the [@corets/translator](/services/translator.md) docs.
{% endhint %}

## Schema.test() <a href="#schematest" id="schematest"></a>

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

Example of a failed assertion:

```typescript
import { string } from "@corets/schema"

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

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

## Schema.validate() <a href="#schemavalidate" id="schemavalidate"></a>

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

Example of a failed validation:

```typescript
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:

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

{% hint style="info" %}
When validating anything but an object, you'll find all the error messages under the key **self**.
{% endhint %}

## Schema.verify() <a href="#schemaverify" id="schemaverify"></a>

This method works the same as [`Schema.validate()`](/services/schema.md#schemavalidate), 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:

```typescript
import { string } from "@corets/schema"

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

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

```typescript
[  
    {    
        "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:

```typescript
import { string } from "@corets/schema"

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

{% hint style="info" %}
All sanitization methods start with the prefix **to**, for example: [string.**toTrimmed()**](/services/schema.md#stringtotrimmed).
{% endhint %}

## Schema.sanitizeAndTest() <a href="#schemasanitizeandtest" id="schemasanitizeandtest"></a>

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()`](/services/schema.md#schema-sanitize) and [`Schema.test()`](/services/schema.md#schematest) sequentially.

Example of a successful test with sanitizers:

```typescript
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:

```typescript
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.

{% hint style="info" %}
All sanitization methods start with the prefix **to**, for example: [string.**toTrimmed()**](/services/schema.md#stringtotrimmed).
{% endhint %}

## Schema.sanitizeAndValidate() <a href="#schemasanitizeandvalidate" id="schemasanitizeandvalidate"></a>

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()`](/services/schema.md#schema-sanitize) and [`Schema.validate()`](/services/schema.md#schemavalidate) sequentially.

Example of a successful validation with sanitizers:

```typescript
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:

```typescript
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:

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

## Schema.sanitizeAndVerify() <a href="#schemasanitizeandverify" id="schemasanitizeandverify"></a>

This method works exactly the same as [`Schema.anitizeAndValidate()`](/services/schema.md#schemasanitizeandvalidate) 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()`](/services/schema.md#schemaverify) to learn more about its use cases.

{% hint style="info" %}
All sanitization methods start with the prefix **to**, for example: [string.**toTrimmed()**](/services/schema.md#stringtotrimmed).
{% endhint %}

## Schema.testAsync() <a href="#schematestasync" id="schematestasync"></a>

This is an async version of the [`Schema.test()`](/services/schema.md#schematest) method, that allows you to use async validators and sanitizers.

{% hint style="info" %}
This library has no async validation or sanitization methods itself, but you can add your own.
{% endhint %}

## Schema.validateAsync() <a href="#schemavalidateasync" id="schemavalidateasync"></a>

This is an async version of the [`Schema.validate()`](/services/schema.md#schemavalidate) method, that allows you to use async validators.

{% hint style="info" %}
This library has no async validation or sanitization methods itself, but you can add your own.
{% endhint %}

## Schema.verifyAsync() <a href="#schemaverifyasync" id="schemaverifyasync"></a>

This is an async version of the [`Schema.verify()`](/services/schema.md#schemaverify) method, that allows you to use async validators.

{% hint style="info" %}
This library has no async validation or sanitization methods itself, but you can add your own.
{% endhint %}

## Schema.sanitizeAsync() <a href="#schemasanitizeasync" id="schemasanitizeasync"></a>

This is an async version of the [`Schema.sanitize()`](/services/schema.md#schema-sanitize) method, that allows you to use async sanitizers.

{% hint style="info" %}
This library has no async validation or sanitization methods itself, but you can add your own.
{% endhint %}

## Schema.sanitizeAndTestAsync() <a href="#schemasanitizeandtestasync" id="schemasanitizeandtestasync"></a>

This is an async version of the [`Schema.sanitizeAndTest()`](/services/schema.md#schemasanitizeandtest) method, that allows you to use async validators and sanitizers.

{% hint style="info" %}
This library has no async validation or sanitization methods itself, but you can add your own.
{% endhint %}

## Schema.sanitizeAndValidateAsync() <a href="#schemasanitizeandvalidateasync" id="schemasanitizeandvalidateasync"></a>

This is an async version of the [`Schema.sanitizeAndValidate()`](/services/schema.md#schemasanitizeandvalidate) method, that allows you to use async validators and sanitizers.

{% hint style="info" %}
This library has no async validation or sanitization methods itself, but you can add your own.
{% endhint %}

## Schema.sanitizeAndVerifyAsync() <a href="#schemasanitizeandverifyasync" id="schemasanitizeandverifyasync"></a>

This is an async version of the [`Schema.sanitizeAndVerify()`](/services/schema.md#schemasanitizeandverify) method, that allows you to use async validators and sanitizers.

{% hint style="info" %}
This library has no async validation or sanitization methods itself, but you can add your own.
{% endhint %}

## Schema.also() <a href="#schemaalso" id="schemaalso"></a>

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.

```typescript
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"
)
```

{% hint style="info" %}
See also [custom validations](/services/schema.md#custom-validations) for more examples.
{% endhint %}

## Schema.and() <a href="#schemaand" id="schemaand"></a>

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.

```typescript
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"
)
```

{% hint style="info" %}
See also [custom validations](/services/schema.md#conditional-validations) and [conditional validations](/services/schema.md#conditional-validations) for more examples.
{% endhint %}

## Schema.or() <a href="#schemaor" id="schemaor"></a>

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.

```typescript
import { string } from "@corets/schema"

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

{% hint style="info" %}
See also [custom validations](/services/schema.md#conditional-validations) and [conditional validations](/services/schema.md#conditional-validations) for more examples.
{% endhint %}

## Schema.map() <a href="#schemamap" id="schemamap"></a>

Attach a custom sanitizer function to a schema.

```typescript
import { mixed } from "@corets/schema"

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

{% hint style="info" %}
See also [custom sanitizers](/services/schema.md#custom-sanitizers) for more examples.
{% endhint %}

## schema() <a href="#schema-1" id="schema-1"></a>

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

```typescript
import { schema } from "@corets/schema"

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

The example above is equivalent to this:

```typescript
import { string } from "@corets/schema"

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

{% hint style="info" %}
Defining a default value is optional, but might be useful when validating forms.
{% endhint %}

## schema.string() <a href="#schemastring" id="schemastring"></a>

Create a new [`string()`](/services/schema.md#string) schema starting with the default value:

```typescript
import { schema } from "@corets/schema"

schema("foo").string()
```

## schema.number() <a href="#schemanumber" id="schemanumber"></a>

Create a new [`number()`](/services/schema.md#number) schema starting with the default value:

```typescript
import { schema } from "@corets/schema"

schema(123).number()
```

## schema.boolean() <a href="#schemaboolean" id="schemaboolean"></a>

Create a new [`boolean()`](/services/schema.md#boolean) schema starting with the default value:

```typescript
import { schema } from "@corets/schema"

schema(true).boolean()
```

## schema.date() <a href="#schemadate" id="schemadate"></a>

Create a new [`date()`](/services/schema.md#date) schema starting with the default value:

```typescript
import { schema } from "@corets/schema"

schema(new Date()).date()
```

## schema.array() <a href="#schemaarray" id="schemaarray"></a>

Create a new [`array()`](/services/schema.md#array) schema starting with the default value:

```typescript
import { schema } from "@corets/schema"

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

## schema.object() <a href="#schemaobject" id="schemaobject"></a>

Create a new [`object()`](/services/schema.md#object) schema starting with the default value:

```typescript
import { schema } from "@corets/schema"

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

## schema.mixed() <a href="#schemamixed" id="schemamixed"></a>

Create a new [`mixed()`](/services/schema.md#mixed) schema starting with the default value:

```typescript
import { schema } from "@corets/schema"

schema("foo").mixed()
```

## string() <a href="#string" id="string"></a>

Contains various validators and sanitisers for strings:

```typescript
import { string } from "@corets/schema"

string()
```

Create a schema instance without the factory function:

```typescript
import { StringSchema } from "@corets/schema"

new StringSchema()
```

## string.required() <a href="#stringrequired" id="stringrequired"></a>

Value must be a non-empty string:

```typescript
import { string } from "@corets/schema"

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

## string.optional() <a href="#stringoptional" id="stringoptional"></a>

Value might be a string, opposite of [`string.required()`](/services/schema.md#stringrequired):

```typescript
import { string } from "@corets/schema"

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

## string.equals() <a href="#stringequals" id="stringequals"></a>

String must be equal to the given value:

```typescript
import { string } from "@corets/schema"

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

## string.length() <a href="#stringlength" id="stringlength"></a>

String must have an exact length:

```typescript
import { string } from "@corets/schema"

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

## string.min() <a href="#stringmin" id="stringmin"></a>

String must not be shorter than given value:

```typescript
import { string } from "@corets/schema"

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

## string.max() <a href="#stringmax" id="stringmax"></a>

String must not be longer than given value:

```typescript
import { string } from "@corets/schema"

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

## string.between() <a href="#stringbetween" id="stringbetween"></a>

String must have a length between min and max:

```typescript
import { string } from "@corets/schema"

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

## string.matches() <a href="#stringmatches" id="stringmatches"></a>

String must match given RegExp:

```typescript
import { string } from "@corets/schema"

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

## string.email() <a href="#stringemail" id="stringemail"></a>

String must be a valid email address:

```typescript
import { string } from "@corets/schema"

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

## string.url() <a href="#stringurl" id="stringurl"></a>

String must be a valid URL:

```typescript
import { string } from "@corets/schema"

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

## string.startsWith() <a href="#stringstartswith" id="stringstartswith"></a>

String must start with a given value:

```typescript
import { string } from "@corets/schema"

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

## string.endsWith() <a href="#stringendswith" id="stringendswith"></a>

String must end with a given value:

```typescript
import { string } from "@corets/schema"

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

## string.includes() <a href="#stringincludes" id="stringincludes"></a>

String must include a given substring:

```typescript
import { string } from "@corets/schema"

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

## string.omits() <a href="#stringomits" id="stringomits"></a>

String must not include a given substring:

```typescript
import { string } from "@corets/schema"

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

## string.oneOf() <a href="#stringoneof" id="stringoneof"></a>

String must be one of the whitelisted values:

```typescript
import { string } from "@corets/schema"

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

## string.noneOf() <a href="#stringnoneof" id="stringnoneof"></a>

String must not be one of the blacklisted values:

```typescript
import { string } from "@corets/schema"

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

## string.numeric() <a href="#stringnumeric" id="stringnumeric"></a>

String must contain numbers only, including floats:

```typescript
import { string } from "@corets/schema"

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

## string.alpha() <a href="#stringalpha" id="stringalpha"></a>

String must contain letters only:

```typescript
import { string } from "@corets/schema"

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

## string.alphaNumeric() <a href="#stringalphanumeric" id="stringalphanumeric"></a>

String must contain numbers and letters only:

```typescript
import { string } from "@corets/schema"

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

## string.alphaDashes() <a href="#stringalphadashes" id="stringalphadashes"></a>

String must contain letters and dashes `-` only:

```typescript
import { string } from "@corets/schema"

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

## string.alphaUnderscores() <a href="#stringalphaunderscores" id="stringalphaunderscores"></a>

String must contain letters and underscores `_` only:

```typescript
import { string } from "@corets/schema"

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

## string.alphaNumericDashes() <a href="#stringalphanumericdashes" id="stringalphanumericdashes"></a>

String must contain letters, numbers and dashes only:

```typescript
import { string } from "@corets/schema"

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

## string.alphaNumericUnderscores() <a href="#stringalphanumericunderscores" id="stringalphanumericunderscores"></a>

String must contain letters, numbers and underscores only:

```typescript
import { string } from "@corets/schema"

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

## string.date() <a href="#stringdate" id="stringdate"></a>

String must be a valid ISO date string:

```typescript
import { string } from "@corets/schema"

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

## string.dateBefore() <a href="#stringdatebefore" id="stringdatebefore"></a>

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

```typescript
import { string } from "@corets/schema"

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

## string.dateBeforeOrEqual() <a href="#stringdatebeforeorsame" id="stringdatebeforeorsame"></a>

Similar to [`string.dateBefore()`](/services/schema.md#stringdatebefore), but allows dates to be equal:

```typescript
import { string } from "@corets/schema"

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

## string.dateAfter() <a href="#stringdateafter" id="stringdateafter"></a>

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

```typescript
import { string } from "@corets/schema"

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

## string.dateAfterOrEqual() <a href="#stringdateafterorsame" id="stringdateafterorsame"></a>

Similar to [`string.dateAfter()`](/services/schema.md#stringdateafter), but allows dates to be equal:

```typescript
import { string } from "@corets/schema"

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

## string.dateBetween() <a href="#stringdatebetween" id="stringdatebetween"></a>

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

```typescript
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() <a href="#stringdatebetweenorsame" id="stringdatebetweenorsame"></a>

Similar to [`string.dateBetween()`](/services/schema.md#stringdatebetween), but allows dates to be equal:

```typescript
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() <a href="#stringtime" id="stringtime"></a>

String must be a valid ISO time string:

```typescript
import { string } from "@corets/schema"

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

## string.timeBefore() <a href="#stringtimebefore" id="stringtimebefore"></a>

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

```typescript
import { string } from "@corets/schema"

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

## string.timeBeforeOrEqual() <a href="#stringtimebeforeorsame" id="stringtimebeforeorsame"></a>

Similar to [`string.timeBefore()`](/services/schema.md#stringtimebefore), but allows times to be equal:

```typescript
import { string } from "@corets/schema"

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

## string.timeAfter() <a href="#stringtimeafter" id="stringtimeafter"></a>

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

```typescript
import { string } from "@corets/schema"

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

## string.timeAfterOrEqual() <a href="#stringtimeafterorsame" id="stringtimeafterorsame"></a>

Similar to [`string.timeAfter()`](/services/schema.md#stringtimeafter), but allows times to be equal:

```typescript
import { string } from "@corets/schema"

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

## string.timeBetween() <a href="#stringtimebetween" id="stringtimebetween"></a>

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

```typescript
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() <a href="#stringtimebetweenorsame" id="stringtimebetweenorsame"></a>

Similar to [`string.timeBetween()`](/services/schema.md#stringtimebetween), but allows times to be equal:

```typescript
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() <a href="#stringdatetime" id="stringdatetime"></a>

String must be a valid ISO date time string:

```typescript
import { string } from "@corets/schema"

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

## string.toDefault() <a href="#stringtodefault" id="stringtodefault"></a>

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

```typescript
import { string } from "@corets/schema"

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

## string.toUpperCase() <a href="#stringtouppercase" id="stringtouppercase"></a>

Convert string to all upper case:

```typescript
import { string } from "@corets/schema"

string().toUpperCase()
```

## string.toLowerCase() <a href="#stringtolowercase" id="stringtolowercase"></a>

Convert string to all lower case:

```typescript
import { string } from "@corets/schema"

string().toLowerCase()
```

## string.toCapitalized() <a href="#stringtocapitalized" id="stringtocapitalized"></a>

Capitalize first letter:

```typescript
import { string } from "@corets/schema"

string().toCapitalized()
```

## string.toCamelCase() <a href="#stringtocamelcase" id="stringtocamelcase"></a>

Convert string to `camelCase`:

```typescript
import { string } from "@corets/schema"

string().toCamelCase()
```

## string.toSnakeCase() <a href="#stringtosnakecase" id="stringtosnakecase"></a>

Convert string to `snake_case`:

```typescript
import { string } from "@corets/schema"

string().toSnakeCase()
```

## string.toKebabCase() <a href="#stringtokebabcase" id="stringtokebabcase"></a>

Convert string to `kebab-case`:

```typescript
import { string } from "@corets/schema"

string().toKebabCase()
```

## string.toConstantCase() <a href="#stringtoconstantcase" id="stringtoconstantcase"></a>

Convert string to `CONSTANT_CASE`:

```typescript
import { string } from "@corets/schema"

string().toConstantCase()
```

## string.toTrimmed() <a href="#stringtotrimmed" id="stringtotrimmed"></a>

Trim surrounding whitespace:

```typescript
import { string } from "@corets/schema"

string().toTrimmed()
```

## number() <a href="#number" id="number"></a>

Contains various validators and sanitizers for numbers:

```typescript
import { number } from "@corets/schema"

number()
```

Create a schema instance without the factory function:

```typescript
import { NumberSchema } from "@corets/schema"

new NumberSchema()
```

## number.required() <a href="#numberrequired" id="numberrequired"></a>

Value must be a number:

```typescript
import { number } from "@corets/schema"

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

## number.optional() <a href="#numberoptional" id="numberoptional"></a>

Value might be a number, opposite of [`number.required()`](/services/schema.md#numberrequired):

```typescript
import { number } from "@corets/schema"

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

## number.equals() <a href="#numberequals" id="numberequals"></a>

Number must be equal to the given value:

```typescript
import { number } from "@corets/schema"

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

## number.min() <a href="#numbermin" id="numbermin"></a>

Number must not be smaller than the given value:

```typescript
import { number } from "@corets/schema"

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

## number.max() <a href="#numbermax" id="numbermax"></a>

Number must not be bigger than the given value:

```typescript
import { number } from "@corets/schema"

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

## number.between() <a href="#numberbetween" id="numberbetween"></a>

Number must be between the two given numbers:

```typescript
import { number } from "@corets/schema"

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

## number.between() <a href="#numberbetween-1" id="numberbetween-1"></a>

Number must be positive - bigger than zero:

```typescript
import { number } from "@corets/schema"

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

## number.negative() <a href="#numbernegative" id="numbernegative"></a>

Number must be negative:

```typescript
import { number } from "@corets/schema"

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

## number.integer() <a href="#numberinteger" id="numberinteger"></a>

Number must be an integer:

```typescript
import { number } from "@corets/schema"

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

## number.oneOf() <a href="#numberoneof" id="numberoneof"></a>

Number must be one of the whitelisted values:

```typescript
import { number } from "@corets/schema"

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

## number.noneOf() <a href="#numbernoneof" id="numbernoneof"></a>

Number must not be one of the blacklisted values:

```typescript
import { number } from "@corets/schema"

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

## number.toDefault() <a href="#numbertodefault" id="numbertodefault"></a>

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

```typescript
import { number } from "@corets/schema"

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

## number.toRounded() <a href="#numbertorounded" id="numbertorounded"></a>

Round value using [`lodash.round()`](https://lodash.com/docs/4.17.15#round):

```typescript
import { number } from "@corets/schema"

const precision = 2

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

## number.toFloored() <a href="#numbertofloored" id="numbertofloored"></a>

Round value using [`lodash.floor()`](https://lodash.com/docs/4.17.15#floor):

```typescript
import { number } from "@corets/schema"

const precision = 2

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

## number.toCeiled() <a href="#numbertoceiled" id="numbertoceiled"></a>

Round value using [`lodash.ceil()`](https://lodash.com/docs/4.17.15#ceil):

```typescript
import { number } from "@corets/schema"

const precision = 2

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

## number.toTrunced() <a href="#numbertotrunced" id="numbertotrunced"></a>

Trunc value using [`Math.trunc()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc)(drops everything after the decimal point):

```typescript
import { number } from "@corets/schema"

number().toTrunced()
```

## boolean() <a href="#boolean" id="boolean"></a>

Contains various validators and sanitizers for booleans:

```typescript
import { boolean } from "@corets/schema"

boolean()
```

Create a schema instance without the factory function:

```typescript
import { BooleanSchema } from "@corets/schema"

new BooleanSchema()
```

## boolean.required() <a href="#booleanrequired" id="booleanrequired"></a>

Value must be a boolean:

```typescript
import { boolean } from "@corets/schema"

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

## boolean.optional() <a href="#booleanoptional" id="booleanoptional"></a>

Value might be a boolean, opposite of [`boolean.required()`](/services/schema.md#booleanrequired):

```typescript
import { boolean } from "@corets/schema"

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

## boolean.equals() <a href="#booleanequals" id="booleanequals"></a>

Number must be equal to the given value:

```typescript
import { boolean } from "@corets/schema"

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

## boolean.toDefault() <a href="#booleantodefault" id="booleantodefault"></a>

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

```typescript
import { boolean } from "@corets/schema"

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

## date() <a href="#date" id="date"></a>

Contains various validators and sanitizers for dates:

```typescript
import { date } from "@corets/schema"

date()
```

Create a schema instance without the factory function:

```typescript
import { DateSchema } from "@corets/schema"

new DateSchema()
```

## date.required() <a href="#daterequired" id="daterequired"></a>

Value must be a date:

```typescript
import { date } from "@corets/schema"

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

## date.optional() <a href="#dateoptional" id="dateoptional"></a>

Value might be a date, opposite of [`date.required()`](/services/schema.md#daterequired):

```typescript
import { date } from "@corets/schema"

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

## date.equals() <a href="#dateequals" id="dateequals"></a>

Date must be equal to the given value:

```typescript
import { date } from "@corets/schema"

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

## date.after() <a href="#dateafter" id="dateafter"></a>

Underlying value must be after the given date:

```typescript
import { date } from "@corets/schema"

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

## date.before() <a href="#datebefore" id="datebefore"></a>

Underlying value must be before the given date:

```typescript
import { date } from "@corets/schema"

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

## date.between() <a href="#datebetween" id="datebetween"></a>

Underlying value must be between the two dates:

```typescript
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() <a href="#datetodefault" id="datetodefault"></a>

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

```typescript
import { date } from "@corets/schema"

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

## array() <a href="#array" id="array"></a>

Contains various validators and sanitizers for arrays:

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

array()
```

Create a schema instance without the factory function:

```typescript
import { ArraySchema } from "@corets/schema"

new ArraySchema()
```

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

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

array(string().min(2))
```

## array.required() <a href="#arrayrequired" id="arrayrequired"></a>

Value must be an array:

```typescript
import { array } from "@corets/schema"

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

## array.optional() <a href="#arrayoptional" id="arrayoptional"></a>

Value might be a array, opposite of [`array.required()`](/services/schema.md#arrayrequired):

```typescript
import { array } from "@corets/schema"

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

## array.equals() <a href="#arrayequals" id="arrayequals"></a>

Array must be equal to the given value:

```typescript
import { array } from "@corets/schema"

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

## array.length() <a href="#arraylength" id="arraylength"></a>

Array must have an exact length:

```typescript
import { array } from "@corets/schema"

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

## array.min() <a href="#arraymin" id="arraymin"></a>

Array must not be shorter than the given length:

```typescript
import { array } from "@corets/schema"

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

## array.max() <a href="#arraymax" id="arraymax"></a>

Array must not be longer than the given length:

```typescript
import { array } from "@corets/schema"

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

## array.between() <a href="#arraybetween" id="arraybetween"></a>

Array must have a length between the two given values:

```typescript
import { array } from "@corets/schema"

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

## array.someOf() <a href="#arraysomeof" id="arraysomeof"></a>

Array must only contain whitelisted values:

```typescript
import { array } from "@corets/schema"

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

## array.noneOf() <a href="#arraynoneof" id="arraynoneof"></a>

Array must not contain any of the blacklisted values:

```typescript
import { array } from "@corets/schema"

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

## array.shape() <a href="#arrayshape" id="arrayshape"></a>

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

```typescript
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()`](/services/schema.md#array) method too:

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

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

## array.toDefault() <a href="#arraytodefault" id="arraytodefault"></a>

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

```typescript
import { array } from "@corets/schema"

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

## array.toFiltered() <a href="#arraytofiltered" id="arraytofiltered"></a>

Filter out invalid array items manually:

```typescript
import { array } from "@corets/schema"

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

array().toFiltered(isString)
```

## array.toMapped() <a href="#arraytomapped" id="arraytomapped"></a>

Map every array item manually:

```typescript
import { array } from "@corets/schema"

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

array().toMapped(toUpperCase)
```

## array.toCompact() <a href="#arraytocompact" id="arraytocompact"></a>

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

```typescript
import { array } from "@corets/schema"

array().toCompact()
```

## array.toUnique() <a href="#arraytounique" id="arraytounique"></a>

Filter out all duplicate values:

```typescript
import { array } from "@corets/schema"

array().toUnique()
```

## object() <a href="#object" id="object"></a>

Contains various validators and sanitizers for objects:

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

object()
```

Create a schema instance without the factory function:

```typescript
import { ObjectSchema } from "@corets/schema"

new ObjectSchema()
```

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

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

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

## object.required() <a href="#objectrequired" id="objectrequired"></a>

Value must be an object:

```typescript
import { object } from "@corets/schema"

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

## object.optional() <a href="#objectoptional" id="objectoptional"></a>

Value might be an object, opposite of [`object.required()`](/services/schema.md#objectrequired):

```typescript
import { object } from "@corets/schema"

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

## object.equals() <a href="#objectequals" id="objectequals"></a>

Underlying value must be equal to the given value:

```typescript
import { object } from "@corets/schema"

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

## object.shape() <a href="#objectshape" id="objectshape"></a>

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

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

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

You can pass a shape directly to the [`object()`](/services/schema.md#object) method too:

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

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

## object.allowUnknownKeys() <a href="#objectallowunknownkeys" id="objectallowunknownkeys"></a>

Allow object to contain keys that have not been configured through [`object.shape()`](/services/schema.md#objectshape):

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

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

## object.forbidUnknownKeys() <a href="#objectdisallowunknownkeys" id="objectdisallowunknownkeys"></a>

Forbid object to contain keys that have not been configured through [`object.shape()`](/services/schema.md#objectshape):

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

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

## object.shapeUnknownKeys() <a href="#objectshapeunknownkeys" id="objectshapeunknownkeys"></a>

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

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

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

## object.shapeUnknownValues() <a href="#objectshapeunknownvalues" id="objectshapeunknownvalues"></a>

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

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

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

## object.toDefault() <a href="#objecttodefault" id="objecttodefault"></a>

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

```typescript
import { object } from "@corets/schema"

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

## object.toCamelCaseKeys() <a href="#objecttocamelcasekeys" id="objecttocamelcasekeys"></a>

Transform all object keys to `camelCase`:

```typescript
import { object } from "@corets/schema"

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

## object.toSnakeCaseKeys() <a href="#objecttosnakecasekeys" id="objecttosnakecasekeys"></a>

Transform all object keys to `snake_case`:

```typescript
import { object } from "@corets/schema"

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

## object.toKebabCaseKeys() <a href="#objecttokebabcasekeys" id="objecttokebabcasekeys"></a>

Transform all object keys to `kebab-case`:

```typescript
import { object } from "@corets/schema"

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

## object.toConstantCaseKeys() <a href="#objecttoconstantcasekeys" id="objecttoconstantcasekeys"></a>

Transform all object keys to `CONSTANT_CASE`:

```typescript
import { object } from "@corets/schema"

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

## object.toMappedValues() <a href="#objecttomappedvalues" id="objecttomappedvalues"></a>

Transform all object values:

```typescript
import { object } from "@corets/schema"

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

## object.toMappedKeys() <a href="#objecttomappedkeys" id="objecttomappedkeys"></a>

Transform all object keys:

```typescript
import { object } from "@corets/schema"

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

## mixed() <a href="#mixed" id="mixed"></a>

Contains various validators and sanitizers for mixed data types:

```typescript
import { mixed } from "@corets/schema"

mixed()
```

Create a schema instance without the factory function:

```typescript
import { MixedSchema } from "@corets/schema"

new MixedSchema()
```

## mixed.required() <a href="#mixedrequired" id="mixedrequired"></a>

Value must not be `null` nor `undefined`:

```typescript
import { mixed } from "@corets/schema"

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

## mixed.optional() <a href="#mixedoptional" id="mixedoptional"></a>

Value might als be a `null` or `undefined`, opposite of [`mixed.required()`](/services/schema.md#mixedrequired):

```typescript
import { mixed } from "@corets/schema"

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

## mixed.equals() <a href="#mixedequals" id="mixedequals"></a>

Underlying value must be equal to the given value:

```typescript
import { mixed } from "@corets/schema"

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

## mixed.oneOf() <a href="#mixedoneof" id="mixedoneof"></a>

Underlying value must be one of the whitelisted values:

```typescript
import { mixed } from "@corets/schema"

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

## mixed.noneOf() <a href="#mixednoneof" id="mixednoneof"></a>

Underlying value must not be one of the blacklisted values:

```typescript
import { mixed } from "@corets/schema"

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

## mixed.toDefault() <a href="#mixedtodefault" id="mixedtodefault"></a>

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

```typescript
import { mixed } from "@corets/schema"

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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.corets.io/services/schema.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
