Security News
ESLint is Now Language-Agnostic: Linting JSON, Markdown, and Beyond
ESLint has added JSON and Markdown linting support with new officially-supported plugins, expanding its versatility beyond JavaScript.
The Joi package is a powerful schema description language and data validator for JavaScript. It allows developers to create blueprints or schemas for JavaScript objects to ensure validation of key information. It is commonly used for validating data, such as configuration objects, request data in web applications, and more.
Object Schema Validation
This feature allows you to define a schema for an object, specifying the expected type of each property, and then validate data against this schema. The code sample demonstrates creating a schema for user data and validating an object against it.
{"const Joi = require('joi');\nconst schema = Joi.object({\n username: Joi.string().alphanum().min(3).max(30).required(),\n password: Joi.string().pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')),\n repeat_password: Joi.ref('password'),\n access_token: [Joi.string(), Joi.number()],\n birth_year: Joi.number().integer().min(1900).max(2013),\n email: Joi.string().email({ minDomainSegments: 2, tlds: { allow: ['com', 'net'] } })\n}).with('username', 'birth_year');\n\nconst dataToValidate = {\n username: 'abc',\n birth_year: 1994,\n email: 'test@example.com'\n};\n\nconst result = schema.validate(dataToValidate);\nconsole.log(result);"}
Type Casting
Joi can cast values to other types as part of the validation process. In this example, a string representing a number is cast to an actual number, and a string 'TRUE' is cast to a boolean true.
{"const Joi = require('joi');\nconst schema = Joi.object({\n age: Joi.number().integer(),\n active: Joi.string().trim().lowercase().valid('true', 'false').truthy('true').falsy('false').default(false).cast('boolean')\n});\n\nconst dataToValidate = {\n age: '30',\n active: 'TRUE'\n};\n\nconst result = schema.validate(dataToValidate, { convert: true });\nconsole.log(result.value); // { age: 30, active: true }"}
Custom Validation Messages
Joi allows you to specify custom validation messages for when data does not conform to the schema. This example shows how to set a custom message for a string that is too short.
{"const Joi = require('joi');\nconst schema = Joi.string().min(10).message('The string needs to be at least 10 characters long.');\n\nconst result = schema.validate('short');\nconsole.log(result.error); // Custom error message"}
Yup is a JavaScript schema builder for value parsing and validation. It is similar to Joi but is leaner and designed for browser usage as well as Node.js. It uses a similar API to Joi but is built with a different focus on client-side validation.
Ajv (Another JSON Schema Validator) is a fast JSON schema validator supporting JSON Schema draft-06/07/2019-09/2020-12 and JSON Type Definition (RFC 8927). It is different from Joi in that it uses a JSON-based schema definition rather than a fluent API.
Validator is a library of string validators and sanitizers. It is not a schema-based validation library like Joi but provides a set of string validation functions that can be used individually to validate specific types of input data.
Class-validator works with TypeScript and uses decorators to define validation rules within class definitions. It is different from Joi in that it integrates tightly with TypeScript and leverages its type system for validation.
Object schema description language and validator for JavaScript objects.
Current version: 2.4.x
var Joi = require('joi');
var schema = {
username: Joi.string().alphanum().min(3).max(30).with('birthyear').required(),
password: Joi.string().regex(/[a-zA-Z0-9]{3,30}/).without('access_token'),
access_token: [Joi.string(), Joi.number()],
birthyear: Joi.number().integer().min(1900).max(2013),
email: Joi.string().email()
};
var err = Joi.validate({ username: 'abc', birthyear: 1994 }, schema); // err === null -> valid
The above schema defines the following constraints:
username
birthyear
password
access_token
access_token
birthyear
email
Usage is a two steps process. First, a schema is constructed using the provided types and constraints:
var schema = {
a: Joi.string()
};
Then the value is validated against the schema:
var err = Joi.validate({ a: 'a string' }, schema);
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:
var schema = Joi.string().min(10);
If the schema is a joi type, the schema.validate(value)
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:
var schema = Joi.object({
a: Joi.string()
});
When validating a schema:
validate(value, schema, options)
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
, attepmts to cast values to the required types (e.g. a string to a number). Defaults to true
.modify
- when true
, converted values are written back to the provided value (only when value is an object). Defaults to false
.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
.languagePath
- the location of the language file used to localize error messages. Defaults to 'languages/en-us.json'
.var schema = {
a: Joi.number()
};
var value = {
a: '123'
};
var err = Joi.validate(value, schema, { modify: true });
// err -> null
// value.a -> 123 (number, not string)
any()
Generates a schema object that matches any data type.
var any = Joi.any();
any.valid('a');
var err = any.validate('a');
any.allow(value)
Whitelists a value where:
value
- the allowed value which can be of any type and will be matched against the validated value before applying any other rules.
value
can be an array of values, or multiple values can be passed as individual arguments.var schema = {
a: Joi.any().allow('a'),
b: Joi.any().allow('b', 'B'),
c: Joi.any().allow(['c', 'C'])
};
any.valid(value)
Adds the provided values into the allowed whitelist and marks them as the only valid values allowed where:
value
- the allowed value which can be of any type and will be matched against the validated value before applying any other rules.
value
can be an array of values, or multiple values can be passed as individual arguments.var schema = {
a: Joi.any().valid('a'),
b: Joi.any().valid('b', 'B'),
c: Joi.any().valid(['c', 'C'])
};
any.invalid(value)
Blacklists a value where:
value
- the forbidden value which can be of any type and will be matched against the validated value before applying any other rules.
value
can be an array of values, or multiple values can be passed as individual arguments.var schema = {
a: Joi.any().invalid('a'),
b: Joi.any().invalid('b', 'B'),
c: Joi.any().invalid(['c', 'C'])
};
any.required()
Marks a key as required which will not allow undefined
as value. All keys are optional by default.
var schema = {
a: Joi.any().required()
};
any.optional()
Marks a key as optional which will allow undefined
as values. Used to annotate the schema for readability as all keys are optional by default.
var schema = {
a: Joi.any().optional()
};
any.with(peer)
Requires the presence of another key whenever this value is present where:
peer
- the required key name that must appear together with the current value. peer
can be an array of values, or multiple values can be
passed as individual arguments.var schema = {
a: Joi.any().with('b'),
b: Joi.any()
};
any.without(peer)
Forbids the presence of another key whenever this value is present where:
peer
- the forbidden key name that must not appear together with the current value. peer
can be an array of values, or multiple values can be
passed as individual arguments.var schema = {
a: Joi.any().without('b'),
b: Joi.any()
};
any.xor(peer)
Defines an exclusive relationship with another key where this or one of the peers is required but not at the same time where:
peer
- the exclusive key name that must not appear together with the current value but where one of them is required. peer
can be an array
of values, or multiple values can be passed as individual arguments.var schema = {
a: Joi.any().xor('b'),
b: Joi.any()
};
any.or(peer)
Defines a relationship with another key where this or one of the peers is required (and more than one is allowed) where:
peer
- the key name that must appear if the current value is missing. peer
can be an array of values, or multiple
values can be passed as individual arguments.var schema = {
a: Joi.any().or('b'),
b: Joi.any()
};
description(desc)
Annotates the key where:
desc
- the description string.var schema = Joi.any().description('this key will match anything you give it');
any.notes(notes)
Annotates the key where:
notes
- the notes string or array of strings.var schema = Joi.any().notes(['this is special', 'this is important']);
any.tags(tags)
Annotates the key where:
tags
- the tag string or array of strings.var schema = Joi.any().tags(['api', 'user']);
any.options(options)
Overrides the global validate()
options for the current key and any sub-key where:
options
- an object with the same optional keys as Joi.validate(value, schema, options)
.var schema = {
a: Joi.any().options({ modify: true })
};
any.strict()
Sets the options.convert
options to false
which prevent type casting for the current key and any child keys.
var schema = {
a: Joi.any().strict()
};
any.rename(to, [options])
Renames a key to another name where:
to
- the new key name.options
- an optional object with the following optional keys:
move
- if true
, deletes the old key name, otherwise both old and new keys are kept. Defaults to false
.multiple
- if true
, allows renaming multiple keys to the same destination where the last rename wins. Defaults to false
.override
- if true
, allows renaming a key over an existing key. Defaults to false
.array()
Generates a schema object that matches an array data type.
Supports the following subset of the any()
type:
required()
optional()
with(peer)
without(peer)
xor(peer)
description(desc)
notes(notes)
tags(tags)
options(options)
rename(to, [options])
var array = Joi.array();
array.includes(Joi.string().valid('a', 'b'));
var err = array.validate(['a', 'b', 'a']);
array.includes(type)
List the types allowed for the array values where:
type
- a joi schema object to validate each array item against. type
can be an array of values, or multiple values can be passed as individual arguments.var schema = {
a: Joi.array().includes(Joi.string(), Joi.number())
};
array.excludes(type)
List the types forbidden for the array values where:
type
- a joi schema object to validate each array item against. type
can be an array of values, or multiple values can be passed as individual arguments.var schema = {
a: Joi.array().excludes(Joi.object())
};
array.min(limit)
Specifies the minimum number of items in the array where:
limit
- the lowest number of array items allowed.var schema = {
a: Joi.array().min(2)
};
array.max(limit)
Specifies the maximum number of items in the array where:
limit
- the highest number of array items allowed.var schema = {
a: Joi.array().max(10)
};
array.length(limit)
Specifies the exact number of items in the array where:
limit
- the number of array items allowed.var schema = {
a: Joi.array().length(5)
};
boolean()
Generates a schema object that matches a boolean data type (as well as the strings 'true', 'false', 'yes', and 'no'). Can also be called via bool()
.
Supports the same methods of the any()
type.
var boolean = Joi.boolean();
boolean.allow(null);
var err = boolean.validate(true);
date()
Generates a schema object that matches a date type (as well as a JavaScript date string or number of milliseconds).
Supports the same methods of the any()
type.
var date = Joi.date();
date.min('12-20-2012');
var err = date.validate('12-21-2012');
date.min(date)
Specifies the oldest date allowed where:
date
- the oldest date allowed.var schema = {
a: Joi.date().min('1-1-1974')
};
date.max(date)
Specifies the latest date allowed where:
date
- the latest date allowed.var schema = {
a: Joi.date().max('12-31-2020')
};
func()
Generates a schema object that matches a function type.
Supports the same methods of the any()
type.
var func = Joi.func();
func.allow(null);
var err = func.validate(function () {});
number()
Generates a schema object that matches a number data type (as well as strings that can be converted to numbers).
Supports the same methods of the any()
type.
var number = Joi.number();
number.min(1).max(10).integer();
var err = number.validate(5);
number.min(limit)
Specifies the minimum value where:
limit
- the minimum value allowed.var schema = {
a: Joi.number().min(2)
};
number.max(limit)
Specifies the maximum value where:
limit
- the maximum value allowed.var schema = {
a: Joi.number().max(10)
};
number.integer()
Requires the number to be an integer (no floating point).
var schema = {
a: Joi.number().integer()
};
object(schema)
Generates a schema object that matches an object data type (as well as JSON strings that parsed into objects) where:
schema
- optional object where each key is assinged a joi type object. If the schema is {}
no keys allowed.
Defaults to 'undefined' which allows any child key.Supports the same methods of the any()
type.
var object = Joi.object({
a: number.min(1).max(10).integer()
});
var err = object.validate({ a: 5 });
string()
Generates a schema object that matches a string data type. Note that empty strings are not allowed by default and must be enabled with allow('')
.
Supports the same methods of the any()
type.
var string = Joi.string();
string.min(1).max(10);
var err = string.validate('12345');
string.insensitive()
Allows the value to match any whitelist of blacklist item in a case insensitive comparison.
var schema = {
a: Joi.string().valid('a').insensitive()
};
string.min(limit)
Specifies the minimum number string characters where:
limit
- the minimum number of string characters required.var schema = {
a: Joi.string().min(2)
};
string.max(limit)
Specifies the maximum number of string characters where:
limit
- the maximum number of string characters allowed.var schema = {
a: Joi.string().max(10)
};
string.length(limit)
Specifies the exact string length required where:
limit
- the required string length.var schema = {
a: Joi.string().length(5)
};
string.regex(pattern)
Defines a regular expression rule where:
pattern
- a regular expression object the string value must match against.var schema = {
a: Joi.string().regex(/^[abc]+$/)
};
string.alphanum()
Requires the string value to only contain a-z, A-Z, and 0-9.
var schema = {
a: Joi.string().alphanum()
};
string.token()
Requires the string value to only contain a-z, A-Z, 0-9, and underscore _.
var schema = {
a: Joi.string().token()
};
string.email()
Requires the string value to be a valid email address.
var schema = {
a: Joi.string().email()
};
string.guid()
Requires the string value to be a valid GUID.
var schema = {
a: Joi.string().guid()
};
string.isoDate()
Requires the string value to be in valid ISO 8601 date format.
var schema = {
a: Joi.string().isoDate()
};
joi 2.0 is a complete rewrite of the previous version. While largely backward compatible, it includes a few changes that are not as well as a large number of bug fixes that dramatically changes existing behavior. The following is an incomplete list of changes. Please test your existing validation rules to ensure they behave as expected with this new version.
Joi.types
and Joi.Types
deprecated - use Joi.string()
etc. instead.{ languagePath: './file.json' }
). Use the .options()
method instead.noShortCircuit()
no longer supported - use the abortEarly
option instead.saveConversions
changed to modify
.skipConversions
changed to convert
(with reversed meaning).stripExtraKeys
changed to stripUnknown
.allowExtraKeys
changed to allowUnknown
.rename()
options:
deleteOrig
changed to move
.allowMult
changed to multiple
.allowOverwrite
changed to override
.nullOk()
and emptyOk()
are deprecated - use allow(null)
and allow('')
instead.number().float()
no longer supported.describe()
instead.string().alphanum()
no longer allows spaces and underscores and does not take an arguement.string().date()
no longer supported - use new date()
type.deny()
deprecated - use invalid()
instead.array().includes()
and array.excludes()
now validates correctly (not just the base type).allow()
, valid()
, and invalid()
values are now compared against the original and converted values (not just after conversion).string().min()
no longer implies required()
.FAQs
Object schema validation
The npm package joi receives a total of 8,609,340 weekly downloads. As such, joi popularity was classified as popular.
We found that joi demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 6 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
ESLint has added JSON and Markdown linting support with new officially-supported plugins, expanding its versatility beyond JavaScript.
Security News
Members Hub is conducting large-scale campaigns to artificially boost Discord server metrics, undermining community trust and platform integrity.
Security News
NIST has failed to meet its self-imposed deadline of clearing the NVD's backlog by the end of the fiscal year. Meanwhile, CVE's awaiting analysis have increased by 33% since June.