fastest-validator
:zap: The fastest JS validator library for NodeJS.
If you like my work, please donate. Thank you!
Key features
- fast! Really!
- 15+ built-in validators
- custom validators
- nested objects & array handling
- strict object validation
- multiple validators
- customizable error messages
- programmable error object
- no dependencies
- unit tests & 100% coverage
How fast?
Very fast! ~5 million validations/sec (on Intel i7-4770K, Node.JS: 8.11.0)
√ validate with pre-compiled schema 5,460,129 rps
Compared to other popular libraries:
100x faster than Joi.
Would you like to test it?
$ git clone https://github.com/icebob/fastest-validator.git
$ cd fastest-validator
$ npm install
$ npm run bench
Installation
NPM
You can install it via NPM.
$ npm install fastest-validator --save
or
$ yarn add fastest-validator
Usage
Simple method
Call the validate
method with the object
and the schema
.
If performance is important, you won't use this method.
let Validator = require("fastest-validator");
let v = new Validator();
const schema = {
id: { type: "number", positive: true, integer: true },
name: { type: "string", min: 3, max: 255 },
status: "boolean"
};
console.log(v.validate({ id: 5, name: "John", status: true }, schema));
console.log(v.validate({ id: 5, name: "Al", status: true }, schema));
Try it on Runkit
Fast method
In this case, the first step is to compile the schema to a compiled "checker" function. After that, to validate your object, just call this "checker" function.
This method is ~10x faster than the "simple method".
let Validator = require("fastest-validator");
let v = new Validator();
var schema = {
id: { type: "number", positive: true, integer: true },
name: { type: "string", min: 3, max: 255 },
status: "boolean"
};
var check = v.compile(schema);
console.log(check({ id: 5, name: "John", status: true }));
console.log(check({ id: 2, name: "Adam" }));
Try it on Runkit
Browser usage
<script src="https://unpkg.com/fastest-validator"></script>
var v = new FastestValidator();
const schema = {
id: { type: "number", positive: true, integer: true },
name: { type: "string", min: 3, max: 255 },
status: "boolean"
};
const check = v.compile(schema);
console.log(check({ id: 5, name: "John", status: true }));
Optional & required fields
Every field in the schema will be required by default. If you'd like to define optional fields, set optional: true
.
let schema = {
name: { type: "string" },
age: { type: "number", optional: true }
}
v.validate({ name: "John", age: 42 }, schema);
v.validate({ name: "John" }, schema);
v.validate({ age: 42 }, schema);
Strict validation
Object properties which are not specified on the schema are ignored by default. If you set the $$strict
option to true
any aditional properties will result in an strictObject
error.
let schema = {
name: { type: "string" },
$$strict: true
}
v.validate({ name: "John" }, schema);
v.validate({ name: "John", age: 42 }, schema);
Multiple validators
It is possible to define more validators for a field. In this case, only one validator needs to succeed for the field to be valid.
let schema = {
cache: [
{ type: "string" },
{ type: "boolean" }
]
}
v.validate({ cache: true }, schema);
v.validate({ cache: "redis://" }, schema);
v.validate({ cache: 150 }, schema);
Built-in validators
any
This does not do type validation. Accepts any types.
let schema = {
prop: { type: "any" }
}
v.validate({ prop: true }, schema);
v.validate({ prop: 100 }, schema);
v.validate({ prop: "John" }, schema);
array
This is an Array
validator.
Simple example with strings:
let schema = {
roles: { type: "array", items: "string" }
}
v.validate({ roles: ["user"] }, schema);
v.validate({ roles: [] }, schema);
v.validate({ roles: "user" }, schema);
Example with only positive numbers:
let schema = {
list: { type: "array", min: 2, items: {
type: "number", positive: true, integer: true
} }
}
v.validate({ list: [2, 4] }, schema);
v.validate({ list: [1, 5, 8] }, schema);
v.validate({ list: [1] }, schema);
v.validate({ list: [1, -7] }, schema);
Example with an object list:
let schema = {
users: { type: "array", items: {
type: "object", props: {
id: { type: "number", positive: true },
name: { type: "string", empty: false },
status: "boolean"
}
} }
}
v.validate({
users: [
{ id: 1, name: "John", status: true },
{ id: 2, name: "Jane", status: true },
{ id: 3, name: "Bill", status: false }
]
}, schema);
Properties
Property | Default | Description |
---|
empty | true | If true, the validator accepts an empty array [] . |
min | null | Minimum count of elements. |
max | null | Maximum count of elements. |
length | null | Fix count of elements. |
contains | null | The array must contain this element too. |
enum | null | Every element must be an element of the enum array. |
Example for enum
:
let schema = {
roles: { type: "array", items: "string", enum: [ "user", "admin" ] }
}
v.validate({ roles: ["user"] }, schema);
v.validate({ roles: ["user", "admin"] }, schema);
v.validate({ roles: ["guest"] }, schema);
boolean
This is a Boolean
validator.
let schema = {
status: { type: "boolean" }
}
v.validate({ status: true }, schema);
v.validate({ status: false }, schema);
v.validate({ status: 1 }, schema);
v.validate({ status: "true" }, schema);
Properties
Property | Default | Description |
---|
convert | false | if true and the type is not Boolean , try to convert. 1 , "true" , "1" , "on" will be true. 0 , "false" , "0" , "off" will be false. |
date
This is a Date
validator.
let schema = {
dob: { type: "date" }
}
v.validate({ dob: new Date() }, schema);
v.validate({ dob: new Date(1488876927958) }, schema);
v.validate({ dob: 1488876927958 }, schema);
Properties
Property | Default | Description |
---|
convert | false | if true and the type is not Date , try to convert with new Date() . |
email
This is an e-mail address validator.
let schema = {
email: { type: "email" }
}
v.validate({ email: "john.doe@gmail.com" }, schema);
v.validate({ email: "james.123.45@mail.co.uk" }, schema);
v.validate({ email: "abc@gmail" }, schema);
Properties
Property | Default | Description |
---|
mode | quick | Checker method. Can be quick or precise . |
enum
This is an enum validator.
let schema = {
sex: { type: "enum", values: ["male", "female"] }
}
v.validate({ sex: "male" }, schema);
v.validate({ sex: "female" }, schema);
v.validate({ sex: "other" }, schema);
Properties
Property | Default | Description |
---|
values | null | The valid values. |
forbidden
This validator returns an error if the property exists in the object.
let schema = {
password: { type: "forbidden" }
}
v.validate({ user: "John" }, schema);
v.validate({ user: "John", password: "pass1234" }, schema);
function
This a Function
validator.
let schema = {
show: { type: "function" }
}
v.validate({ show: function() {} }, schema);
v.validate({ show: Date.now }, schema);
v.validate({ show: null }, schema);
number
This is a Number
validator.
let schema = {
age: { type: "number" }
}
v.validate({ age: 123 }, schema);
v.validate({ age: 5.65 }, schema);
v.validate({ age: "100" }, schema);
Properties
Property | Default | Description |
---|
min | null | Minimum value. |
max | null | Maximum value. |
equal | null | Fixed value. |
notEqual | null | Can't be equal to this value. |
integer | false | The value must be a non-decimal value. |
positive | false | The value must be greater than zero. |
negative | false | The value must be less than zero. |
convert | false | if true and the type is not Number , tries to convert with parseFloat . |
object
This is a nested object validator.
let schema = {
address: { type: "object", props: {
country: { type: "string" },
city: "string",
zip: "number"
} }
}
v.validate({
address: {
country: "Italy",
city: "Rome",
zip: 12345
}
}, schema);
v.validate({
address: {
country: "Italy",
city: "Rome"
}
}, schema);
Properties
Property | Default | Description |
---|
strict | false | if true any properties which are not defined on the schema will throw an error. |
string
This is a String
.
let schema = {
name: { type: "string" }
}
v.validate({ name: "John" }, schema);
v.validate({ name: "" }, schema);
v.validate({ name: 123 }, schema);
Properties
Property | Default | Description |
---|
empty | true | If true, the validator accepts an empty string "" . |
min | null | Minimum value length. |
max | null | Maximum value length. |
length | null | Fixed value length. |
pattern | null | Regex pattern. |
contains | null | The value must contain this text. |
enum | null | The value must be an element of the enum array. |
alpha | null | The value must be an alphabetic string. |
numeric | null | The value must be a numeric string. |
alphanum | null | The value must be an alphanumeric string. |
alphadash | null | The value must be an alphabetic string that contains dashes. |
url
This is an URL validator.
let schema = {
url: { type: "url" }
}
v.validate({ url: "http://google.com" }, schema);
v.validate({ url: "https://github.com/icebob" }, schema);
v.validate({ url: "www.facebook.com" }, schema);
uuid
This is an UUID validator.
let schema = {
uuid: { type: "uuid" }
}
v.validate({ uuid: "10ba038e-48da-487b-96e8-8d3b99b6d18a" }, schema);
v.validate({ uuid: "9a7b330a-a736-51e5-af7f-feaf819cdc9f" }, schema);
v.validate({ uuid: "10ba038e-48da-487b-96e8-8d3b99b6d18a", version: 5 }, schema);
Properties
Property | Default | Description |
---|
version | 4 | UUID version in range 1-5. |
mac
This is an MAC addresses validator.
let schema = {
mac: { type: "mac" }
}
v.validate({ mac: "01:C8:95:4B:65:FE" }, schema);
v.validate({ mac: "01:c8:95:4b:65:fe", schema);
v.validate({ mac: "01C8.954B.65FE" }, schema);
v.validate({ mac: "01c8.954b.65fe", schema);
v.validate({ mac: "01-C8-95-4B-65-FE" }, schema);
v.validate({ mac: "01-c8-95-4b-65-fe" }, schema);
v.validate({ mac: "01C8954B65FE" }, schema);
luhn
This is an Luhn validator.
Luhn algorithm checksum
Credit Card numbers, IMEI numbers, National Provider Identifier numbers and others
let schema = {
cc: { type: "luhn" }
}
v.validate({ cc: "452373989901198" }, schema);
v.validate({ cc: 452373989901198 }, schema);
v.validate({ cc: "4523-739-8990-1198" }, schema);
v.validate({ cc: "452373989901199" }, schema);
Custom validator
You can also create your custom validator.
let v = new Validator({
messages: {
evenNumber: "The '{field}' field must be an even number! Actual: {actual}"
}
});
v.add("even", value => {
if (value % 2 != 0)
return v.makeError("evenNumber", null, value);
return true;
});
const schema = {
name: { type: "string", min: 3, max: 255 },
age: { type: "even" }
};
console.log(v.validate({ name: "John", age: 20 }, schema));
console.log(v.validate({ name: "John", age: 19 }, schema));
Or you can use the custom
type with an inline checker function:
let v = new Validator({
messages: {
weightMin: "The weight must be greater than {expected}! Actual: {actual}"
}
});
const schema = {
name: { type: "string", min: 3, max: 255 },
weight: {
type: "custom",
minWeight: 10,
check(value, schema) {
return (value < schema.minWeight)
? this.makeError("weightMin", schema.minWeight, value)
: true;
}
}
};
console.log(v.validate({ name: "John", weight: 50 }, schema));
console.log(v.validate({ name: "John", weight: 8 }, schema));
Custom error messages (l10n)
You can set your custom messages in the validator constructor.
const Validator = require("fastest-validator");
const v = new Validator({
messages: {
stringMin: "A(z) '{field}' mező túl rövid. Minimum: {expected}, Jelenleg: {actual}",
stringMax: "A(z) '{field}' mező túl hosszú. Minimum: {expected}, Jelenleg: {actual}"
}
});
v.validate({ name: "John" }, { name: { type: "string", min: 6 }});
Personalised Messages
Sometimes the standard messages are too generic. You can customise messages per validation type per field:
const Validator = require("fastest-validator");
const v = new Validator();
const schema = {
firstname: {
type: "string",
min: 6,
messages: {
string: "Please check your firstname",
stringMin: "Your firstname is too short"
}
},
lastname: {
type: "string",
min: 6,
messages: {
string: "Please check your lastname",
stringMin: "Your lastname is too short"
}
}
}
v.validate({ firstname: "John", lastname: 23 }, schema );
Message types
Name | Default text |
---|
required | The '{field}' field is required! |
string | The '{field}' field must be a string! |
stringEmpty | The '{field}' field must not be empty! |
stringMin | The '{field}' field length must be greater than or equal to {expected} characters long! |
stringMax | The '{field}' field length must be less than or equal to {expected} characters long! |
stringLength | The '{field}' field length must be {expected} characters long! |
stringPattern | The '{field}' field fails to match the required pattern! |
stringContains | The '{field}' field must contain the '{expected}' text! |
stringEnum | The '{field}' field does not match any of the allowed values! |
number | The '{field}' field must be a number! |
numberMin | The '{field}' field must be greater than or equal to {expected}! |
numberMax | The '{field}' field must be less than or equal to {expected}! |
numberEqual | The '{field}' field must be equal with {expected}! |
numberNotEqual | The '{field}' field can't be equal with {expected}! |
numberInteger | The '{field}' field must be an integer! |
numberPositive | The '{field}' field must be a positive number! |
numberNegative | The '{field}' field must be a negative number! |
array | The '{field}' field must be an array! |
arrayEmpty | The '{field}' field must not be an empty array! |
arrayMin | The '{field}' field must contain at least {expected} items! |
arrayMax | The '{field}' field must contain less than or equal to {expected} items! |
arrayLength | The '{field}' field must contain {expected} items! |
arrayContains | The '{field}' field must contain the '{expected}' item! |
arrayEnum | The '{field} field value '{expected}' does not match any of the allowed values! |
boolean | The '{field}' field must be a boolean! |
function | The '{field}' field must be a function! |
date | The '{field}' field must be a Date! |
dateMin | The '{field}' field must be greater than or equal to {expected}! |
dateMax | The '{field}' field must be less than or equal to {expected}! |
forbidden | The '{field}' field is forbidden! |
email | The '{field}' field must be a valid e-mail! |
Message fields
Name | Description |
---|
field | The field name |
expected | The expected value |
actual | The actual value |
type | The field type |
Development
npm run dev
Test
npm test
Coverage report
-----------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-----------------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
lib | 100 | 100 | 100 | 100 | |
messages.js | 100 | 100 | 100 | 100 | |
validator.js | 100 | 100 | 100 | 100 | |
lib/helpers | 100 | 100 | 100 | 100 | |
deep-extend.js | 100 | 100 | 100 | 100 | |
flatten.js | 100 | 100 | 100 | 100 | |
lib/rules | 100 | 100 | 100 | 100 | |
any.js | 100 | 100 | 100 | 100 | |
array.js | 100 | 100 | 100 | 100 | |
boolean.js | 100 | 100 | 100 | 100 | |
custom.js | 100 | 100 | 100 | 100 | |
date.js | 100 | 100 | 100 | 100 | |
email.js | 100 | 100 | 100 | 100 | |
enum.js | 100 | 100 | 100 | 100 | |
forbidden.js | 100 | 100 | 100 | 100 | |
function.js | 100 | 100 | 100 | 100 | |
luhn.js | 100 | 100 | 100 | 100 | |
mac.js | 100 | 100 | 100 | 100 | |
number.js | 100 | 100 | 100 | 100 | |
object.js | 100 | 100 | 100 | 100 | |
string.js | 100 | 100 | 100 | 100 | |
url.js | 100 | 100 | 100 | 100 | |
uuid.js | 100 | 100 | 100 | 100 | |
-----------------|----------|----------|----------|----------|-------------------|
Contribution
Please send pull requests improving the usage and fixing bugs, improving documentation and providing better examples, or providing some tests, because these things are important.
License
fastest-validator is available under the MIT license.
Contact
Copyright (C) 2017 Icebob