<commit_before><a href="https://github.com/spumko"><img src="https://raw.github.com/spumko/spumko/master/images/from.png" align="right" /></a>
![joi Logo](https://raw.github.com/spumko/joi/master/images/joi.png)

Object schema description language and validator for JavaScript objects.

Current version: **4.6.x**

[![Build Status](https://secure.travis-ci.org/spumko/joi.png)](http://travis-ci.org/spumko/joi)

[![Browser Support](https://ci.testling.com/spumko/joi.png)](https://ci.testling.com/spumko/joi)

## Table of Contents

<img src="https://raw.github.com/spumko/joi/master/images/validation.png" align="right" />
- [Example](#example)
- [Usage](#usage)
    - [`validate(value, schema, [options], callback)`](#validatevalue-schema-options-callback)
    - [`compile(schema)`](#compileschema)
    - [`assert(value, schema)`](#assertvalue-schema)
    - [`any`](#any)
        - [`any.allow(value)`](#anyallowvalue)
        - [`any.valid(value)`](#anyvalidvalue)
        - [`any.invalid(value)`](#anyinvalidvalue)
        - [`any.required()`](#anyrequired)
        - [`any.optional()`](#anyoptional)
        - [`any.forbidden()`](#anyforbidden)
        - [`any.description(desc)`](#anydescriptiondesc)
        - [`any.notes(notes)`](#anynotesnotes)
        - [`any.tags(tags)`](#anytagstags)
        - [`any.meta(meta)`](#anymetameta)
        - [`any.example(value)`](#anyexamplevalue)
        - [`any.unit(name)`](#anyunitname)
        - [`any.options(options)`](#anyoptionsoptions)
        - [`any.strict()`](#anystrict)
        - [`any.default(value)`](#anydefaultvalue)
        - [`any.concat(schema)`](#anyconcatschema)
        - [`any.when(ref, options)`](#anywhenref-options)
    - [`array`](#array)
        - [`array.includes(type)`](#arrayincludestype)
        - [`array.excludes(type)`](#arrayexcludestype)
        - [`array.min(limit)`](#arrayminlimit)
        - [`array.max(limit)`](#arraymaxlimit)
        - [`array.length(limit)`](#arraylengthlimit)
    - [`binary`](#binary)
      - [`binary.encoding(encoding)`](#binaryencodingencoding)
      - [`binary.min(limit)`](#binaryminlimit)
      - [`binary.max(limit)`](#binarymaxlimit)
      - [`binary.length(limit)`](#binarylengthlimit)
    - [`boolean()`](#boolean)
    - [`date`](#date)
        - [`date.min(date)`](#datemindate)
        - [`date.max(date)`](#datemaxdate)
    - [`func`](#func)
    - [`number`](#number)
        - [`number.min(limit)`](#numberminlimit)
        - [`number.max(limit)`](#numbermaxlimit)
        - [`number.integer()`](#numberinteger)
    - [`object`](#object)
        - [`object.keys([schema])`](#objectkeysschema)
        - [`object.min(limit)`](#objectminlimit)
        - [`object.max(limit)`](#objectmaxlimit)
        - [`object.length(limit)`](#objectlengthlimit)
        - [`object.pattern(regex, schema)`](#objectpatternregex-schema)
        - [`object.and(peers)`](#objectandpeers)
        - [`object.or(peers)`](#objectorpeers)
        - [`object.xor(peers)`](#objectxorpeers)
        - [`object.with(key, peers)`](#objectwithkey-peers)
        - [`object.without(key, peers)`](#objectwithoutkey-peers)
        - [`object.rename(from, to, [options])`](#objectrenamefrom-to-options)
        - [`object.assert(ref, schema, message)`](#objectassertref-schema-message)
        - [`object.unknown([allow])`](#objectunknownallow)
    - [`string`](#string)
        - [`string.insensitive()`](#stringinsensitive)
        - [`string.min(limit, [encoding])`](#stringminlimit-encoding)
        - [`string.max(limit, [encoding])`](#stringmaxlimit-encoding)
        - [`string.length(limit, [encoding])`](#stringlengthlimit-encoding)
        - [`string.regex(pattern)`](#stringregexpattern)
        - [`string.alphanum()`](#stringalphanum)
        - [`string.token()`](#stringtoken)
        - [`string.email()`](#stringemail)
        - [`string.guid()`](#stringguid)
        - [`string.isoDate()`](#stringisodate)
        - [`string.hostname()`](#stringhostname)
        - [`string.lowercase()`](#stringlowercase)
        - [`string.uppercase()`](#stringuppercase)
        - [`string.trim()`](#stringtrim)
    - [`alternatives`](#alternatives)
        - [`alternatives.try(schemas)`](#alternativestryschemas)
        - [`alternatives.when(ref, options)`](#alternativeswhenref-options)
    - [`ref(key, [options])`](#refkey-options)

# Example

```javascript
var Joi = require('joi');

var schema = Joi.object().keys({
    username: Joi.string().alphanum().min(3).max(30).required(),
    password: Joi.string().regex(/[<PASSWORD>}/),
    access_token: [Joi.string(), Joi.number()],
    birthyear: Joi.number().integer().min(1900).max(2013),
    email: Joi.string().email()
}).with('username', 'birthyear').without('password', 'access_token');

Joi.validate({ username: 'abc', birthyear: 1994 }, schema, function (err, value) { });  // err === null -> valid
```

The above schema defines the following constraints:
* `username`
    * a required string
    * must contain only alphanumeric characters
    * at least 3 characters long but no more than 30
    * must be accompanied by `birthyear`
* `password`
    * an optional string
    * must satisfy the custom regex
    * cannot appear together with `access_token`
* `access_token`
    * an optional, unconstrained string or number
* `birthyear`
    * an integer between 1900 and 2013
* `email`
    * a valid email address string

# Usage

Usage is a two steps process. First, a schema is constructed using the provided types and constraints:

```javascript
var schema = {
    a: Joi.string()
};
```

Note that **joi** schema objects are immutable which means every additional rule added (e.g. `.min(5)`) will return a
new schema object.

Then the value is validated against the schema:

```javascript
Joi.validate({ a: 'a string' }, schema, function (err, value) { });
```

If the value is valid, `null` is returned, otherwise an `Error` object.

The schema can be a plain JavaScript object where every key is assigned a **joi** type, or it can be a **joi** type directly:

```javascript
var schema = Joi.string().min(10);
```

If the schema is a **joi** type, the `schema.validate(value, callback)` can be called directly on the type. When passing a non-type schema object,
the module converts it internally to an object() type equivalent to:

```javascript
var schema = Joi.object().keys({
    a: Joi.string()
});
```

When validating a schema:
* Keys are optional by default.
* Strings are utf-8 encoded by default.
* Rules are defined in an additive fashion and evaluated in order after whitelist and blacklist checks.

### `validate(value, schema, [options], callback)`

Validates a value using the given schema and options where:
- `value` - the value being validated.
- `schema` - the validation schema. Can be a **joi** type object or a plain object where every key is assigned a **joi** type object.
- `options` - an optional object with the following optional keys:
  - `abortEarly` - when `true`, stops validation on the first error, otherwise returns all the errors found. Defaults to `true`.
  - `convert` - when `true`, attempts to cast values to the required types (e.g. a string to a number). Defaults to `true`.
  - `allowUnknown` - when `true`, allows object to contain unknown keys which are ignored. Defaults to `false`.
  - `skipFunctions` - when `true`, ignores unknown keys with a function value. Defaults to `false`.
  - `stripUnknown` - when `true`, unknown keys are deleted (only when value is an object). Defaults to `false`.
  - `language` - overrides individual error messages. Defaults to no override (`{}`).
  - `context` - provides an external data set to be used in [references](#refkey-options). Can only be set as an external option to
    `validate()` and not using `any.options()`.
- `callback` - the synchronous callback method using the signature `function(err, value)` where:
  - `err` - if validation failed, the error reason, otherwise `null`.
  - `value` - the validated value with any type conversions and other modifiers applied (the input is left unchanged). `value` can be
    incomplete if validation failed and `abortEarly` is `true`.

```javascript
var schema = {
    a: Joi.number()
};

var value = {
    a: '123'
};

Joi.validate(value, schema, function (err, value) { });
// err -> null
// value.a -> 123 (number, not string)<commit_msg>adding info about the validate callback being optional<commit_after><a href="https://github.com/spumko"><img src="https://raw.github.com/spumko/spumko/master/images/from.png" align="right" /></a>
![joi Logo](https://raw.github.com/spumko/joi/master/images/joi.png)

Object schema description language and validator for JavaScript objects.

Current version: **4.6.x**

[![Build Status](https://secure.travis-ci.org/spumko/joi.png)](http://travis-ci.org/spumko/joi)

[![Browser Support](https://ci.testling.com/spumko/joi.png)](https://ci.testling.com/spumko/joi)

## Table of Contents

<img src="https://raw.github.com/spumko/joi/master/images/validation.png" align="right" />
- [Example](#example)
- [Usage](#usage)
    - [`validate(value, schema, [options], [callback])`](#validatevalue-schema-options-callback)
    - [`compile(schema)`](#compileschema)
    - [`assert(value, schema)`](#assertvalue-schema)
    - [`any`](#any)
        - [`any.allow(value)`](#anyallowvalue)
        - [`any.valid(value)`](#anyvalidvalue)
        - [`any.invalid(value)`](#anyinvalidvalue)
        - [`any.required()`](#anyrequired)
        - [`any.optional()`](#anyoptional)
        - [`any.forbidden()`](#anyforbidden)
        - [`any.description(desc)`](#anydescriptiondesc)
        - [`any.notes(notes)`](#anynotesnotes)
        - [`any.tags(tags)`](#anytagstags)
        - [`any.meta(meta)`](#anymetameta)
        - [`any.example(value)`](#anyexamplevalue)
        - [`any.unit(name)`](#anyunitname)
        - [`any.options(options)`](#anyoptionsoptions)
        - [`any.strict()`](#anystrict)
        - [`any.default(value)`](#anydefaultvalue)
        - [`any.concat(schema)`](#anyconcatschema)
        - [`any.when(ref, options)`](#anywhenref-options)
    - [`array`](#array)
        - [`array.includes(type)`](#arrayincludestype)
        - [`array.excludes(type)`](#arrayexcludestype)
        - [`array.min(limit)`](#arrayminlimit)
        - [`array.max(limit)`](#arraymaxlimit)
        - [`array.length(limit)`](#arraylengthlimit)
    - [`binary`](#binary)
      - [`binary.encoding(encoding)`](#binaryencodingencoding)
      - [`binary.min(limit)`](#binaryminlimit)
      - [`binary.max(limit)`](#binarymaxlimit)
      - [`binary.length(limit)`](#binarylengthlimit)
    - [`boolean()`](#boolean)
    - [`date`](#date)
        - [`date.min(date)`](#datemindate)
        - [`date.max(date)`](#datemaxdate)
    - [`func`](#func)
    - [`number`](#number)
        - [`number.min(limit)`](#numberminlimit)
        - [`number.max(limit)`](#numbermaxlimit)
        - [`number.integer()`](#numberinteger)
    - [`object`](#object)
        - [`object.keys([schema])`](#objectkeysschema)
        - [`object.min(limit)`](#objectminlimit)
        - [`object.max(limit)`](#objectmaxlimit)
        - [`object.length(limit)`](#objectlengthlimit)
        - [`object.pattern(regex, schema)`](#objectpatternregex-schema)
        - [`object.and(peers)`](#objectandpeers)
        - [`object.or(peers)`](#objectorpeers)
        - [`object.xor(peers)`](#objectxorpeers)
        - [`object.with(key, peers)`](#objectwithkey-peers)
        - [`object.without(key, peers)`](#objectwithoutkey-peers)
        - [`object.rename(from, to, [options])`](#objectrenamefrom-to-options)
        - [`object.assert(ref, schema, message)`](#objectassertref-schema-message)
        - [`object.unknown([allow])`](#objectunknownallow)
    - [`string`](#string)
        - [`string.insensitive()`](#stringinsensitive)
        - [`string.min(limit, [encoding])`](#stringminlimit-encoding)
        - [`string.max(limit, [encoding])`](#stringmaxlimit-encoding)
        - [`string.length(limit, [encoding])`](#stringlengthlimit-encoding)
        - [`string.regex(pattern)`](#stringregexpattern)
        - [`string.alphanum()`](#stringalphanum)
        - [`string.token()`](#stringtoken)
        - [`string.email()`](#stringemail)
        - [`string.guid()`](#stringguid)
        - [`string.isoDate()`](#stringisodate)
        - [`string.hostname()`](#stringhostname)
        - [`string.lowercase()`](#stringlowercase)
        - [`string.uppercase()`](#stringuppercase)
        - [`string.trim()`](#stringtrim)
    - [`alternatives`](#alternatives)
        - [`alternatives.try(schemas)`](#alternativestryschemas)
        - [`alternatives.when(ref, options)`](#alternativeswhenref-options)
    - [`ref(key, [options])`](#refkey-options)

# Example

```javascript
var Joi = require('joi');

var schema = Joi.object().keys({
    username: Joi.string().alphanum().min(3).max(30).required(),
    password: Joi.string().regex(/[a-zA-Z0-9]{3,30}/),
    access_token: [Joi.string(), Joi.number()],
    birthyear: Joi.number().integer().min(1900).max(2013),
    email: Joi.string().email()
}).with('username', 'birthyear').without('password', 'access_token');

Joi.validate({ username: 'abc', birthyear: 1994 }, schema, function (err, value) { });  // err === null -> valid
```

The above schema defines the following constraints:
* `username`
    * a required string
    * must contain only alphanumeric characters
    * at least 3 characters long but no more than 30
    * must be accompanied by `birthyear`
* `password`
    * an optional string
    * must satisfy the custom regex
    * cannot appear together with `access_token`
* `access_token`
    * an optional, unconstrained string or number
* `birthyear`
    * an integer between 1900 and 2013
* `email`
    * a valid email address string

# Usage

Usage is a two steps process. First, a schema is constructed using the provided types and constraints:

```javascript
var schema = {
    a: Joi.string()
};
```

Note that **joi** schema objects are immutable which means every additional rule added (e.g. `.min(5)`) will return a
new schema object.

Then the value is validated against the schema:

```javascript
Joi.validate({ a: 'a string' }, schema, function (err, value) { });
```

If the value is valid, `null` is returned, otherwise an `Error` object.

The schema can be a plain JavaScript object where every key is assigned a **joi** type, or it can be a **joi** type directly:

```javascript
var schema = Joi.string().min(10);
```

If the schema is a **joi** type, the `schema.validate(value, callback)` can be called directly on the type. When passing a non-type schema object,
the module converts it internally to an object() type equivalent to:

```javascript
var schema = Joi.object().keys({
    a: Joi.string()
});
```

When validating a schema:
* Keys are optional by default.
* Strings are utf-8 encoded by default.
* Rules are defined in an additive fashion and evaluated in order after whitelist and blacklist checks.

### `validate(value, schema, [options], [callback])`

Validates a value using the given schema and options where:
- `value` - the value being validated.
- `schema` - the validation schema. Can be a **joi** type object or a plain object where every key is assigned a **joi** type object.
- `options` - an optional object with the following optional keys:
  - `abortEarly` - when `true`, stops validation on the first error, otherwise returns all the errors found. Defaults to `true`.
  - `convert` - when `true`, attempts to cast values to the required types (e.g. a string to a number). Defaults to `true`.
  - `allowUnknown` - when `true`, allows object to contain unknown keys which are ignored. Defaults to `false`.
  - `skipFunctions` - when `true`, ignores unknown keys with a function value. Defaults to `false`.
  - `stripUnknown` - when `true`, unknown keys are deleted (only when value is an object). Defaults to `false`.
  - `language` - overrides individual error messages. Defaults to no override (`{}`).
  - `context` - provides an external data set to be used in [references](#refkey-options). Can only be set as an external option to
    `validate()` and not using `any.options()`.
- `callback` - the optional synchronous callback method using the signature `function(err, value)` where:
  - `err` - if validation failed, the error reason, otherwise `null`.
  - `value` - the validated value with any type conversions and other modifiers applied (the input is left unchanged). `value` can be
    incomplete if validation failed and `abortEarly` is `true`.

```javascript
var schema = {
    a: Joi.number()
};

var value = {
    a: '123'
};

Joi.validate(value, schema, function (err, value) { });
// err -> null
// value.a -> 123 (number, not string)

// or
var result = Joi.validate(value, schema);
// assert.strictEqual(result.error, null);
// assert.deepEqual(result, {"error":null,"value":{"a":123}});
{'fraction_non_alphanumeric': 0.17675272382756987, 'fraction_numerical': 0.004973945997157745, 'mean_word_length': 3.7202347680268306, 'pattern_counts': {'":': 3, '<': 12, '<?xml version=': 0, '>': 18, 'https://': 14, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6357336', 'n_tokens_mistral': 5452, 'n_tokens_neox': 5132, 'n_words': 1276}