{"id":13511881,"url":"https://github.com/icebob/fastest-validator","last_synced_at":"2025-05-13T23:05:02.143Z","repository":{"id":38083678,"uuid":"84318409","full_name":"icebob/fastest-validator","owner":"icebob","description":":zap: The fastest JS validator library for NodeJS","archived":false,"fork":false,"pushed_at":"2025-04-30T17:04:37.000Z","size":2322,"stargazers_count":1434,"open_issues_count":42,"forks_count":93,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-05-07T22:03:02.149Z","etag":null,"topics":["schema","schema-validation","validate","validator"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/icebob.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-03-08T12:34:44.000Z","updated_at":"2025-04-30T17:01:42.000Z","dependencies_parsed_at":"2024-01-05T21:00:40.768Z","dependency_job_id":"94cda309-5c3d-4b19-bcaa-3004de5787be","html_url":"https://github.com/icebob/fastest-validator","commit_stats":{"total_commits":588,"total_committers":54,"mean_commits":10.88888888888889,"dds":0.4965986394557823,"last_synced_commit":"d99b6ff1d77dad0cfb46da0818ab8dac33723ccd"},"previous_names":[],"tags_count":59,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icebob%2Ffastest-validator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icebob%2Ffastest-validator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icebob%2Ffastest-validator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icebob%2Ffastest-validator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/icebob","download_url":"https://codeload.github.com/icebob/fastest-validator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253197002,"owners_count":21869735,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["schema","schema-validation","validate","validator"],"created_at":"2024-08-01T03:01:16.063Z","updated_at":"2025-05-13T23:04:57.122Z","avatar_url":"https://github.com/icebob.png","language":"JavaScript","readme":"![Photos from @ikukevk](https://user-images.githubusercontent.com/306521/30183963-9c722dca-941c-11e7-9e83-c78377ad7f9d.jpg)\n\n![Node CI](https://github.com/icebob/fastest-validator/workflows/Node%20CI/badge.svg)\n[![Coverage Status](https://coveralls.io/repos/github/icebob/fastest-validator/badge.svg?branch=master)](https://coveralls.io/github/icebob/fastest-validator?branch=master)\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/75256e6ec26d42f5ab1dee109ae4d3ad)](https://www.codacy.com/app/mereg-norbert/fastest-validator?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=icebob/fastest-validator\u0026amp;utm_campaign=Badge_Grade)\n[![Known Vulnerabilities](https://snyk.io/test/github/icebob/fastest-validator/badge.svg)](https://snyk.io/test/github/icebob/fastest-validator)\n[![Size](https://badgen.net/bundlephobia/minzip/fastest-validator)](https://bundlephobia.com/result?p=fastest-validator)\n\n# fastest-validator [![NPM version](https://img.shields.io/npm/v/fastest-validator.svg)](https://www.npmjs.com/package/fastest-validator) [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=The%20fastest%20JS%20validator%20library%20for%20NodeJS\u0026url=https://github.com/icebob/fastest-validator\u0026via=Icebobcsi\u0026hashtags=nodejs,javascript)\n:zap: The fastest JS validator library for NodeJS | Browser | Deno.\n\n## Key features\n* blazing fast! Really!\n* 20+ built-in validators\n* many sanitizations\n* custom validators \u0026 aliases\n* nested objects \u0026 array handling\n* strict object validation\n* multiple validators\n* customizable error messages\n* programmable error object\n* no dependencies\n* unit tests \u0026 100% coverage\n\n## How fast?\nVery fast! 8 million validations/sec (on Intel i7-4770K, Node.JS: 12.14.1)\n```\n√ validate                            8,678,752 rps\n```\n\nCompared to other popular libraries:\n\n[![Result](https://user-images.githubusercontent.com/306521/68978853-404a8500-07fc-11ea-94e4-0c25546dad04.png)](https://github.com/icebob/validator-benchmark#result)\n\u003e 50x faster than Joi.\n\n**Would you like to test it?**\n\n```\n$ git clone https://github.com/icebob/fastest-validator.git\n$ cd fastest-validator\n$ npm install\n$ npm run bench\n```\n\n## Approach\nIn order to achieve lowest cost/highest performance redaction fastest-validator creates and compiles functions using the `Function` constructor. It's important to distinguish this from the dangers of a runtime eval, no user input is involved in creating the validation schema that compiles into the function. This is as safe as writing code normally and having it compiled by V8 in the usual way.\n\n# Installation\n\n## NPM\nYou can install it via [NPM](http://npmjs.org/).\n```\n$ npm i fastest-validator --save\n```\nor\n```\n$ yarn add fastest-validator\n```\n\n# Usage\n\n## Validate\nThe first step is to compile the schema to a compiled \"checker\" function. After that, to validate your object, just call this \"checker\" function.\n\u003e This method is the fastest.\n\n```js\nconst Validator = require(\"fastest-validator\");\n\nconst v = new Validator();\n\nconst schema = {\n    id: { type: \"number\", positive: true, integer: true },\n    name: { type: \"string\", min: 3, max: 255 },\n    status: \"boolean\" // short-hand def\n};\n\nconst check = v.compile(schema);\n\nconsole.log(\"First:\", check({ id: 5, name: \"John\", status: true }));\n// Returns: true\n\nconsole.log(\"Second:\", check({ id: 2, name: \"Adam\" }));\n/* Returns an array with errors:\n    [\n        {\n            type: 'required',\n            field: 'status',\n            message: 'The \\'status\\' field is required!'\n        }\n    ]\n*/\n```\n[Try it on Repl.it](https://repl.it/@icebob/fastest-validator-fast)\n\n### Halting\n\nIf you want to halt immediately after the first error:\n```js\nconst v = new Validator({ haltOnFirstError: true });\n```\n\n## Browser usage\n```html\n\u003cscript src=\"https://unpkg.com/fastest-validator\"\u003e\u003c/script\u003e\n```\n\n```js\nconst v = new FastestValidator();\n\nconst schema = {\n    id: { type: \"number\", positive: true, integer: true },\n    name: { type: \"string\", min: 3, max: 255 },\n    status: \"boolean\" // short-hand def\n};\n\nconst check = v.compile(schema);\n\nconsole.log(check({ id: 5, name: \"John\", status: true }));\n// Returns: true\n```\n\n## Deno usage\nWith `esm.sh`, now Typescript is supported\n\n```js\nimport FastestValidator from \"https://esm.sh/fastest-validator@1\"\n\nconst v = new FastestValidator();\nconst check = v.compile({\n    name: \"string\",\n    age: \"number\",\n});\n\nconsole.log(check({ name: \"Erf\", age: 18 })); //true\n```\n\n## Supported frameworks\n- *Moleculer*: Natively supported\n- *Fastify*: By using [fastify-fv](https://github.com/erfanium/fastify-fv) \n- *Express*: By using [fastest-express-validator](https://github.com/muturgan/fastest-express-validator) \n\n\n# Optional, Required \u0026 Nullable fields\n## Optional\nEvery field in the schema will be required by default. If you'd like to define optional fields, set `optional: true`.\n\n```js\nconst schema = {\n    name: { type: \"string\" }, // required\n    age: { type: \"number\", optional: true }\n}\n\nconst check = v.compile(schema);\n\ncheck({ name: \"John\", age: 42 }); // Valid\ncheck({ name: \"John\" }); // Valid\ncheck({ age: 42 }); // Fail because name is required\n```\n\n## Nullable\nIf you want disallow `undefined` value but allow `null` value, use `nullable` instead of `optional`.\n```js\nconst schema = {\n    age: { type: \"number\", nullable: true }\n}\n\nconst check = v.compile(schema);\n\ncheck({ age: 42 }); // Valid\ncheck({ age: null }); // Valid\ncheck({ age: undefined }); // Fail because undefined is disallowed\ncheck({}); // Fail because undefined is disallowed\n```\n### Nullable and default values\n`null` is a valid input for nullable fields that has default value.\n\n```js\nconst schema = {\n   about: { type: \"string\", nullable: true, default: \"Hi! I'm using javascript\" }\n}\n\nconst check = v.compile(schema)\n\nconst object1 = { about: undefined }\ncheck(object1) // Valid\nobject1.about // is \"Hi! I'm using javascript\"\n\nconst object2 = { about: null }\ncheck(object2) // valid\nobject2.about // is null\n\ncheck({ about: \"Custom\" }) // Valid\n```\n### Considering `null` as a value\nIn specific case, you may want to consider `null` as a valid input even for a `required` field.  \n\nIt's useful in cases you want a field to be:\n - `required` and `null` without specifying `nullable: true` in its definition.\n - `required` and not `null` by specifying `nullable: false` in its definition.\n - `optional` **but specifically not** `null`.  \n\nTo be able to achieve this you'll have to set the `considerNullAsAValue` validator option to `true`. \n```js\nconst v = new Validator({considerNullAsAValue: true});\n\nconst schema = {foo: {type: \"number\"}, bar: {type: \"number\", optional: true, nullable: false}, baz: {type: \"number\", nullable: false}};\nconst check = v.compile(schema);\n\nconst object1 = {foo: null, baz: 1};\ncheck(object1); // valid (foo is required and can be null)\n\nconst object2 = {foo: 3, bar: null, baz: 1};\ncheck(object2); // not valid (bar is optional but can't be null)\n\nconst object3 = {foo: 3, baz: null};\ncheck(object3); // not valid (baz is required but can't be null)\n\n```\nWith this option set all fields will be considered _nullable_ by default.\n\n# Strict validation\nObject properties which are not specified on the schema are ignored by default. If you set the `$$strict` option to `true` any additional properties will result in an `strictObject` error.\n\n```js\nconst schema = {\n    name: { type: \"string\" }, // required\n    $$strict: true // no additional properties allowed\n}\n\nconst check = v.compile(schema);\n\ncheck({ name: \"John\" }); // Valid\ncheck({ name: \"John\", age: 42 }); // Fail\n```\n\n## Remove additional fields\nTo remove the additional fields in the object, set `$$strict: \"remove\"`.\n\n\n# Multiple validators\nIt is possible to define more validators for a field. In this case, only one validator needs to succeed for the field to be valid.\n\n```js\nconst schema = {\n    cache: [\n        { type: \"string\" },\n        { type: \"boolean\" }\n    ]\n}\n\nconst check = v.compile(schema);\n\ncheck({ cache: true }); // Valid\ncheck({ cache: \"redis://\" }); // Valid\ncheck({ cache: 150 }); // Fail\n```\n\n# Root element schema\nBasically the validator expects that you want to validate a Javascript object. If you want others, you can define the root level schema, as well. In this case set the `$$root: true` property.\n\n**Example to validate a `string` variable instead of `object`**\n```js\nconst schema = {\n    $$root: true,\n    type: \"string\", \n    min: 3, \n    max: 6\n};\n\nconst check = v.compile(schema);\n\ncheck(\"John\"); // Valid\ncheck(\"Al\"); // Fail, too short.\n```\n\n# Sanitizations\nThe library contains several sanitizers. **Please note, the sanitizers change the original checked object.**\n\n## Default values\nThe most common sanitizer is the `default` property. With it, you can define a default value for all properties. If the property value is `null`* or `undefined`, the validator set the defined default value into the property.\n\n**Static Default value example**:\n```js\nconst schema = {\n    roles: { type: \"array\", items: \"string\", default: [\"user\"] },\n    status: { type: \"boolean\", default: true },\n};\n\nconst check = v.compile(schema);\n\nconst obj = {}\n\ncheck(obj); // Valid\nconsole.log(obj);\n/*\n{\n    roles: [\"user\"],\n    status: true\n}\n*/\n``` \n**Dynamic Default value**:\nAlso you can use dynamic default value by defining a function that returns a value. For example, in the following code, if `createdAt` field not defined in object`, the validator sets the current time into the property:\n\n```js\nconst schema = {\n    createdAt: {\n        type: \"date\",\n        default: (schema, field, parent, context) =\u003e new Date()\n    }\n};\n\nconst check = v.compile(schema);\n\nconst obj = {}\n\ncheck(obj); // Valid\nconsole.log(obj);\n/*\n{\n    createdAt: Date(2020-07-25T13:17:41.052Z)\n}\n*/\n```\n\n# Shorthand definitions\nYou can use string-based shorthand validation definitions in the schema.\n\n```js\nconst schema = {\n    password: \"string|min:6\",\n    age: \"number|optional|integer|positive|min:0|max:99\", // additional properties\n    state: [\"boolean\", \"number|min:0|max:1\"] // multiple types\n}\n```\n\n### Array of X \n```js\nconst schema = {\n    foo: \"string[]\" // means array of string\n}\n\nconst check = v.compile(schema);\n\ncheck({ foo: [\"bar\"] }) // true\n```\n\n### Nested objects\n\n```js\nconst schema = {\n   dot: {\n      $$type: \"object\",\n      x: \"number\",  // object props here\n      y: \"number\",  // object props here\n   }, \n   circle: {\n      $$type: \"object|optional\", // using other shorthands\n      o: {\n         $$type: \"object\",\n         x: \"number\",\n         y: \"number\",\n      },\n      r: \"number\"\n   }\n};\n```\n\n# Alias definition\nYou can define custom aliases.\n\n```js\nv.alias('username', {\n    type: 'string',\n    min: 4,\n    max: 30\n    // ...\n});\n\nconst schema = {\n    username: \"username|max:100\", // Using the 'username' alias\n    password: \"string|min:6\",\n}\n```\n\n# Default options\nYou can set default rule options.\n\n```js\nconst v = new FastestValidator({\n    defaults: {\n        object: {\n            strict: \"remove\"\n        }\n    }\n});\n```\n# Label Option\nYou can use label names in error messages instead of property names.\n```js\nconst schema = {\n\temail: { type: \"email\", label: \"Email Address\" },\n};\nconst check = v.compile(schema);\n\nconsole.log(check({ email: \"notAnEmail\" }));\n\n/* Returns\n[\n  {\n    type: 'email',\n    message: \"The 'Email Address' field must be a valid e-mail.\",\n    field: 'email',\n    actual: 'notAnEmail',\n    label: 'Email Address'\n  }\n]\n*/\n```\n# Built-in validators\n\n## `any`\nThis does not do type validation. Accepts any types.\n\n```js\nconst schema = {\n    prop: { type: \"any\" }\n}\n\nconst check = v.compile(schema)\n\ncheck({ prop: true }); // Valid\ncheck({ prop: 100 }); // Valid\ncheck({ prop: \"John\" }); // Valid\n```\n\n## `array`\nThis is an `Array` validator.\n\n**Simple example with strings:**\n```js\nconst schema = {\n    roles: { type: \"array\", items: \"string\" }\n}\nconst check = v.compile(schema)\n\ncheck({ roles: [\"user\"] }); // Valid\ncheck({ roles: [] }); // Valid\ncheck({ roles: \"user\" }); // Fail\n```\n\n**Example with only positive numbers:**\n```js\nconst schema = {\n    list: { type: \"array\", min: 2, items: {\n        type: \"number\", positive: true, integer: true\n    } }\n}\nconst check = v.compile(schema)\n\ncheck({ list: [2, 4] }); // Valid\ncheck({ list: [1, 5, 8] }); // Valid\ncheck({ list: [1] }); // Fail (min 2 elements)\ncheck({ list: [1, -7] }); // Fail (negative number)\n```\n\n**Example with an object list:**\n```js\nconst schema = {\n    users: { type: \"array\", items: {\n        type: \"object\", props: {\n            id: { type: \"number\", positive: true },\n            name: { type: \"string\", empty: false },\n            status: \"boolean\"\n        }\n    } }\n}\nconst check = v.compile(schema)\n\ncheck({\n    users: [\n        { id: 1, name: \"John\", status: true },\n        { id: 2, name: \"Jane\", status: true },\n        { id: 3, name: \"Bill\", status: false }\n    ]\n}); // Valid\n```\n\n**Example for `enum`:**\n```js\nconst schema = {\n    roles: { type: \"array\", items: \"string\", enum: [ \"user\", \"admin\" ] }\n}\n\nconst check = v.compile(schema)\n\ncheck({ roles: [\"user\"] }); // Valid\ncheck({ roles: [\"user\", \"admin\"] }); // Valid\ncheck({ roles: [\"guest\"] }); // Fail\n```\n\n**Example for `unique`:**\n```js\nconst schema = {\n    roles: { type: \"array\", unique: true }\n}\nconst check = v.compile(schema);\n\ncheck({ roles: [\"user\"] }); // Valid\ncheck({ roles: [{role:\"user\"},{role:\"admin\"},{role:\"user\"}] }); // Valid\ncheck({ roles: [\"user\", \"admin\", \"user\"] }); // Fail\ncheck({ roles: [1, 2, 1] }); // Fail\n```\n\n**Example for `convert`:**\n\n```js\nconst schema = {\n    roles: { type: \"array\", items: 'string', convert: true }\n}\nconst check = v.compile(schema);\n\ncheck({ roles: [\"user\"] }); // Valid\ncheck({ roles: \"user\" }); // Valid\n// After both validation: roles = [\"user\"]\n```\n\n### Properties\nProperty | Default  | Description\n-------- | -------- | -----------\n`empty`  | `true`   | If `true`, the validator accepts an empty array `[]`.\n`min`  \t | `null`   | Minimum count of elements.\n`max`  \t | `null`   | Maximum count of elements.\n`length` | `null`   | Fix count of elements.\n`contains` | `null` | The array must contain this element too.\n`unique` | `null` | The array must be unique (array of objects is always unique).\n`enum`\t | `null`   | Every element must be an element of the `enum` array.\n`items`\t | `null`   | Schema for array items.\n`convert`| `null`   | Wrap value into array if different type provided\n\n## `boolean`\nThis is a `Boolean` validator.\n\n```js\nconst schema = {\n    status: { type: \"boolean\" }\n}\nconst check = v.compile(schema);\n\ncheck({ status: true }); // Valid\ncheck({ status: false }); // Valid\ncheck({ status: 1 }); // Fail\ncheck({ status: \"true\" }); // Fail\n```\n### Properties\nProperty | Default  | Description\n-------- | -------- | -----------\n`convert` | `false` | if `true` and the type is not `Boolean`, it will be converted. `1`, `\"true\"`, `\"1\"`, `\"on\"` will be true. `0`, `\"false\"`, `\"0\"`, `\"off\"` will be false. _It's a sanitizer, it will change the value in the original object._\n\n**Example for `convert`:**\n```js\nconst schema = {\n    status: { type: \"boolean\", convert: true}\n};\n\nconst check = v.compile(schema);\n\ncheck({ status: \"true\" }); // Valid\n```\n\n## `class`\nThis is a `Class` validator to check the value is an instance of a Class.\n\n```js\nconst schema = {\n    rawData: { type: \"class\", instanceOf: Buffer }\n}\nconst check = v.compile(schema);\n\ncheck({ rawData: Buffer.from([1, 2, 3]) }); // Valid\ncheck({ rawData: 100 }); // Fail\n```\n\n### Properties\nProperty | Default  | Description\n-------- | -------- | -----------\n`instanceOf` | `null` | Checked Class.\n\n## `currency`\nThis is a `Currency` validator to check if the value is a valid currency string.\n\n```js\nconst schema = {\n    money_amount: { type: \"currency\", currencySymbol: '$' }\n}\nconst check = v.compile(schema);\n\n\ncheck({ money_amount: '$12.99'}); // Valid\ncheck({ money_amount: '$0.99'}); // Valid\ncheck({ money_amount: '$12,345.99'}); // Valid\ncheck({ money_amount: '$123,456.99'}); // Valid\n\ncheck({ money_amount: '$1234,567.99'}); // Fail\ncheck({ money_amount: '$1,23,456.99'}); // Fail\ncheck({ money_amount: '$12,34.5.99' }); // Fail\n```\n\n### Properties\nProperty | Default  | Description\n-------- | -------- | -----------\n`currencySymbol` | `null` | The currency symbol expected in string (as prefix).\n`symbolOptional` | `false` | Toggle to make the symbol optional in string, although, if present it would only allow the currencySymbol.\n`thousandSeparator` | `,` | Thousand place separator character.\n`decimalSeparator` | `.` | Decimal place character.\n`customRegex` | `null` | Custom regular expression, to validate currency strings (For eg:  /[0-9]*/g).\n\n## `date`\nThis is a `Date` validator.\n\n```js\nconst schema = {\n    dob: { type: \"date\" }\n}\nconst check = v.compile(schema);\n\ncheck({ dob: new Date() }); // Valid\ncheck({ dob: new Date(1488876927958) }); // Valid\ncheck({ dob: 1488876927958 }); // Fail\n```\n\n### Properties\nProperty | Default  | Description\n-------- | -------- | -----------\n`convert`  | `false`| if `true` and the type is not `Date`, try to convert with `new Date()`. _It's a sanitizer, it will change the value in the original object._\n\n**Example for `convert`:**\n```js\nconst schema = {\n    dob: { type: \"date\", convert: true}\n};\n\nconst check = v.compile(schema);\n\ncheck({ dob: 1488876927958 }, ); // Valid\n```\n\n## `email`\nThis is an e-mail address validator.\n\n```js\nconst schema = {\n    email: { type: \"email\" }\n}\nconst check = v.compile(schema);\n\n\ncheck({ email: \"john.doe@gmail.com\" }); // Valid\ncheck({ email: \"james.123.45@mail.co.uk\" }); // Valid\ncheck({ email: \"abc@gmail\" }); // Fail\n```\n\n### Properties\nProperty | Default  | Description\n-------- | -------- | -----------\n`empty`  | `false`   | If `true`, the validator accepts an empty array `\"\"`.\n`mode`   | `quick`  | Checker method. Can be `quick` or `precise`.\n`normalize`   | `false`  | Normalize the e-mail address (trim \u0026 lower-case). _It's a sanitizer, it will change the value in the original object._\n`min`  \t | `null`   | Minimum value length.\n`max`  \t | `null`   | Maximum value length.\n\n## `enum`\nThis is an enum validator.\n\n```js\nconst schema = {\n    sex: { type: \"enum\", values: [\"male\", \"female\"] }\n}\nconst check = v.compile(schema);\n\n\ncheck({ sex: \"male\" }); // Valid\ncheck({ sex: \"female\" }); // Valid\ncheck({ sex: \"other\" }); // Fail\n```\n\n### Properties\nProperty | Default  | Description\n-------- | -------- | -----------\n`values` | `null`   | The valid values.\n\n## `equal`\nThis is an equal value validator. It checks a value with a static value or with another property.\n\n**Example with static value**:\n```js\nconst schema = {\n    agreeTerms: { type: \"equal\", value: true, strict: true } // strict means `===`\n}\nconst check = v.compile(schema);\n\ncheck({ agreeTerms: true }); // Valid\ncheck({ agreeTerms: false }); // Fail\n```\n\n**Example with other field**:\n```js\nconst schema = {\n    password: { type: \"string\", min: 6 },\n    confirmPassword: { type: \"equal\", field: \"password\" }\n}\nconst check = v.compile(schema);\n\ncheck({ password: \"123456\", confirmPassword: \"123456\" }); // Valid\ncheck({ password: \"123456\", confirmPassword: \"pass1234\" }); // Fail\n```\n\n### Properties\nProperty | Default  | Description\n-------- | -------- | -----------\n`value`  | `undefined`| The expected value. It can be any primitive types.\n`strict`  | `false`| if `true`, it uses strict equal `===` for checking.\n\n## `forbidden`\nThis validator returns an error if the property exists in the object.\n\n```js\nconst schema = {\n    password: { type: \"forbidden\" }\n}\nconst check = v.compile(schema);\n\n\ncheck({ user: \"John\" }); // Valid\ncheck({ user: \"John\", password: \"pass1234\" }); // Fail\n```\n\n### Properties\nProperty | Default  | Description\n-------- | -------- | -----------\n`remove` | `false`   | If `true`, the value will be removed in the original object. _It's a sanitizer, it will change the value in the original object._\n\n**Example for `remove`:**\n```js\nconst schema = {\n    user: { type: \"string\" },\n    token: { type: \"forbidden\", remove: true }\n};\nconst check = v.compile(schema);\n\n\nconst obj = {\n    user: \"John\",\n    token: \"123456\"\n}\n\ncheck(obj); // Valid\nconsole.log(obj);\n/*\n{\n    user: \"John\",\n    token: undefined\n}\n*/\n```\n\n## `function`\nThis a `Function` type validator.\n\n```js\nconst schema = {\n    show: { type: \"function\" }\n}\nconst check = v.compile(schema);\n\n\ncheck({ show: function() {} }); // Valid\ncheck({ show: Date.now }); // Valid\ncheck({ show: \"function\" }); // Fail\n```\n\n## `luhn`\nThis is an Luhn validator.\n[Luhn algorithm](https://en.wikipedia.org/wiki/Luhn_algorithm) checksum\nCredit Card numbers, IMEI numbers, National Provider Identifier numbers and others \n\n```js\nconst schema = {\n    cc: { type: \"luhn\" }\n}\nconst check = v.compile(schema);\n\ncheck({ cc: \"452373989901198\" }); // Valid\ncheck({ cc: 452373989901198 }); // Valid\ncheck({ cc: \"4523-739-8990-1198\" }); // Valid\ncheck({ cc: \"452373989901199\" }); // Fail\n```\n\n## `mac`\nThis is an MAC addresses validator. \n\n```js\nconst schema = {\n    mac: { type: \"mac\" }\n}\nconst check = v.compile(schema);\n\ncheck({ mac: \"01:C8:95:4B:65:FE\" }); // Valid\ncheck({ mac: \"01:c8:95:4b:65:fe\"); // Valid\ncheck({ mac: \"01C8.954B.65FE\" }); // Valid\ncheck({ mac: \"01c8.954b.65fe\"); // Valid\ncheck({ mac: \"01-C8-95-4B-65-FE\" }); // Valid\ncheck({ mac: \"01-c8-95-4b-65-fe\" }); // Valid\ncheck({ mac: \"01C8954B65FE\" }); // Fail\n```\n\n## `multi`\nThis is a multiple definitions validator. \n\n```js\nconst schema = {\n    status: { type: \"multi\", rules: [\n        { type: \"boolean\" },\n        { type: \"number\" }\n    ], default: true }\n}\nconst check = v.compile(schema);\n\ncheck({ status: true }); // Valid\ncheck({ status: false }); // Valid\ncheck({ status: 1 }); // Valid\ncheck({ status: 0 }); // Valid\ncheck({ status: \"yes\" }); // Fail\n```\n\n**Shorthand multiple definitions**:\n```js\nconst schema = {\n    status: [\n        \"boolean\",\n        \"number\"\n    ]\n}\nconst check = v.compile(schema);\n\ncheck({ status: true }); // Valid\ncheck({ status: false }); // Valid\ncheck({ status: 1 }); // Valid\ncheck({ status: 0 }); // Valid\ncheck({ status: \"yes\" }); // Fail\n```\n\n## `number`\nThis is a `Number` validator.\n\n```js\nconst schema = {\n    age: { type: \"number\" }\n}\nconst check = v.compile(schema);\n\ncheck({ age: 123 }); // Valid\ncheck({ age: 5.65 }); // Valid\ncheck({ age: \"100\" }); // Fail\n```\n\n### Properties\nProperty | Default  | Description\n-------- | -------- | -----------\n`min`  \t | `null`   | Minimum value.\n`max`  \t | `null`   | Maximum value.\n`equal`  | `null`   | Fixed value.\n`notEqual` | `null` | Can't be equal to this value.\n`integer` | `false` | The value must be a non-decimal value.\n`positive` | `false`| The value must be greater than zero.\n`negative` | `false`| The value must be less than zero.\n`convert`  | `false`| if `true` and the type is not `Number`, it's converted with `Number()`. _It's a sanitizer, it will change the value in the original object._\n\n## `object`\nThis is a nested object validator.\n\n```js\nconst schema = {\n    address: { type: \"object\", strict: true, props: {\n        country: { type: \"string\" },\n        city: \"string\", // short-hand\n        zip: \"number\" // short-hand\n    } }\n}\nconst check = v.compile(schema);\n\ncheck({\n    address: {\n        country: \"Italy\",\n        city: \"Rome\",\n        zip: 12345\n    }\n}); // Valid\n\ncheck({\n    address: {\n        country: \"Italy\",\n        city: \"Rome\"\n    }\n}); // Fail (\"The 'address.zip' field is required!\")\n\ncheck({\n    address: {\n        country: \"Italy\",\n        city: \"Rome\",\n        zip: 12345,\n        state: \"IT\"\n    }\n}); // Fail (\"The 'address.state' is an additional field!\")\n```\n\n### Properties\nProperty | Default  | Description\n-------- | -------- | -----------\n`strict`  | `false`| If `true` any properties which are not defined on the schema will throw an error. If `remove` all additional properties will be removed from the original object. _It's a sanitizer, it will change the original object._\n`minProps` | `null` | If set to a number N, will throw an error if the object has fewer than N properties.\n`maxProps` | `null` | If set to a number N, will throw an error if the object has more than N properties.\n\n```js\nschema = {\n    address: { type: \"object\", strict: \"remove\", props: {\n        country: { type: \"string\" },\n        city: \"string\", // short-hand\n        zip: \"number\" // short-hand\n    } }\n}\n\nlet obj = {\n    address: {\n        country: \"Italy\",\n        city: \"Rome\",\n        zip: 12345,\n        state: \"IT\"\n    }\n};\nconst check = v.compile(schema);\n\ncheck(obj); // Valid\nconsole.log(obj);\n/*\n{\n    address: {\n        country: \"Italy\",\n        city: \"Rome\",\n        zip: 12345\n    }   \n}\n*/\n```\n```js\nschema = {\n  address: {\n    type: \"object\",\n    minProps: 2,\n    props: {\n      country: { type: \"string\" },\n      city: { type: \"string\", optional: true },\n      zip: { type: \"number\", optional: true }\n    }\n  }\n}\nconst check = v.compile(schema);\n\n\nobj = {\n    address: {\n        country: \"Italy\",\n        city: \"Rome\",\n        zip: 12345,\n        state: \"IT\"\n    }\n}\n\ncheck(obj); // Valid\n\nobj = {\n    address: {\n        country: \"Italy\",\n    }\n}\n\ncheck(obj); // Fail\n// [\n//   {\n//     type: 'objectMinProps',\n//     message: \"The object 'address' must contain at least 2 properties.\",\n//     field: 'address',\n//     expected: 2,\n//     actual: 1\n//   }\n// ]\n```\n\n## `record`\nThis validator allows to check an object with arbitrary keys.\n\n```js\nconst schema = {\n    surnameGroups: {\n        type: 'record',\n        key: { type: 'string', alpha: true },\n        value: { type: 'array', items: 'string' }\n    }\n};\nconst check = v.compile(schema);\n\ncheck({ surnameGroups: { Doe: ['Jane', 'John'], Williams: ['Bill'] } }); // Valid\ncheck({ surnameGroups: { Doe1: ['Jane', 'John'] } }); // Fail\ncheck({ surnameGroups: { Doe: [1, 'Jane'] } }); // Fail\n```\n\n### Properties\nProperty | Default  | Description\n-------- |----------| -----------\n`key`    | `string` | Key validation rule (It is reasonable to use only the `string` rule).\n`value`  | `any`    | Value validation rule.\n\n## `string`\nThis is a `String` validator.\n\n```js\nconst schema = {\n    name: { type: \"string\" }\n}\nconst check = v.compile(schema);\n\ncheck({ name: \"John\" }); // Valid\ncheck({ name: \"\" }); // Valid\ncheck({ name: 123 }); // Fail\n```\n\n### Properties\nProperty | Default  | Description\n-------- | -------- | -----------\n`empty`  | `true`   | If `true`, the validator accepts an empty string `\"\"`.\n`min`  \t | `null`   | Minimum value length.\n`max`  \t | `null`   | Maximum value length.\n`length` | `null`   | Fixed value length.\n`pattern` | `null`   | Regex pattern.\n`contains` | `null`   | The value must contain this text.\n`enum`\t | `null`   | The value must be an element of the `enum` array.\n`alpha`   | `null`   | The value must be an alphabetic string.\n`numeric`   | `null`   | The value must be a numeric string.\n`alphanum`   | `null`   | The value must be an alphanumeric string.\n`alphadash`   | `null`   | The value must be an alphabetic string that contains dashes.\n`hex`   | `null`   | The value must be a hex string.\n`singleLine`   | `null`   | The value must be a single line string.\n`base64`   | `null`   | The value must be a base64 string.\n`trim`   | `null`   | If `true`, the value will be trimmed. _It's a sanitizer, it will change the value in the original object._\n`trimLeft`   | `null`   | If `true`, the value will be left trimmed. _It's a sanitizer, it will change the value in the original object._\n`trimRight`   | `null`   | If `true`, the value will be right trimmed. _It's a sanitizer, it will change the value in the original object._\n`padStart`   | `null`   | If it's a number, the value will be left padded. _It's a sanitizer, it will change the value in the original object._\n`padEnd`   | `null`   | If it's a number, the value will be right padded. _It's a sanitizer, it will change the value in the original object._\n`padChar`   | `\" \"`   | The padding character for the `padStart` and `padEnd`.\n`lowercase`   | `null`   | If `true`, the value will be lower-cased. _It's a sanitizer, it will change the value in the original object._\n`uppercase`   | `null`   | If `true`, the value will be upper-cased. _It's a sanitizer, it will change the value in the original object._\n`localeLowercase`   | `null`   | If `true`, the value will be locale lower-cased. _It's a sanitizer, it will change the value in the original object._\n`localeUppercase`   | `null`   | If `true`, the value will be locale upper-cased. _It's a sanitizer, it will change the value in the original object._\n`convert`  | `false`| if `true` and the type is not a `String`, it's converted with `String()`. _It's a sanitizer, it will change the value in the original object._\n\n**Sanitization example**\n```js\nconst schema = {\n    username: { type: \"string\", min: 3, trim: true, lowercase: true}\n}\nconst check = v.compile(schema);\n\nconst obj = {\n    username: \"   Icebob  \"\n};\n\ncheck(obj); // Valid\nconsole.log(obj);\n/*\n{\n    username: \"icebob\"\n}\n*/\n```\n\n## `tuple`\nThis validator checks if a value is an `Array` with the elements order as described by the schema.\n\n**Simple example:**\n```js\nconst schema = { list: \"tuple\" };\nconst check = v.compile(schema);\n\ncheck({ list: [] }); // Valid\ncheck({ list: [1, 2] }); // Valid\ncheck({ list: [\"RON\", 100, true] }); // Valid\ncheck({ list: 94 }); // Fail (not an array)\n```\n\n**Example with items:**\n```js\nconst schema = {\n    grade: { type: \"tuple\", items: [\"string\", \"number\"] }\n}\nconst check = v.compile(schema);\n\ncheck({ grade: [\"David\", 85] }); // Valid\ncheck({ grade: [85, \"David\"] }); // Fail (wrong position)\ncheck({ grade: [\"Cami\"] }); // Fail (require 2 elements)\n```\n\n**Example with a more detailed schema:**\n```js\nconst schema = {\n    location: { type: \"tuple\", items: [\n        \"string\",\n        { type: \"tuple\", empty: false, items: [\n            { type: \"number\", min: 35, max: 45 },\n            { type: \"number\", min: -75, max: -65 }\n        ] }\n    ] }\n}\nconst check = v.compile(schema);\n\ncheck({ location: ['New York', [40.7127281, -74.0060152]] }); // Valid\ncheck({ location: ['New York', [50.0000000, -74.0060152]] }); // Fail\ncheck({ location: ['New York', []] }); // Fail (empty array)\n```\n\n### Properties\nProperty | Default  | Description\n-------- | -------- | -----------\n`empty`  | `true`   | If `true`, the validator accepts an empty array `[]`.\n`items`\t | `undefined` | Exact schema of the value items\n\n## `url`\nThis is an URL validator.\n\n```js\nconst schema = {\n    url: { type: \"url\" }\n}\nconst check = v.compile(schema);\n\ncheck({ url: \"http://google.com\" }); // Valid\ncheck({ url: \"https://github.com/icebob\" }); // Valid\ncheck({ url: \"www.facebook.com\" }); // Fail\n```\n\n### Properties\nProperty | Default  | Description\n-------- | -------- | -----------\n`empty`  | `false`   | If `true`, the validator accepts an empty string `\"\"`.\n\n## `uuid`\nThis is an UUID validator. \n\n```js\nconst schema = {\n    uuid: { type: \"uuid\" }\n}\nconst check = v.compile(schema);\n\ncheck({ uuid: \"00000000-0000-0000-0000-000000000000\" }); // Valid Nil UUID\ncheck({ uuid: \"10ba038e-48da-487b-96e8-8d3b99b6d18a\" }); // Valid UUIDv4\ncheck({ uuid: \"9a7b330a-a736-51e5-af7f-feaf819cdc9f\" }); // Valid UUIDv5\ncheck({ uuid: \"10ba038e-48da-487b-96e8-8d3b99b6d18a\", version: 5 }); // Fail\n```\n### Properties\nProperty | Default  | Description\n-------- | -------- | -----------\n`version`  | `null`   | UUID version in range 0-6. The `null` disables version checking.\n\n## `objectID`\nYou can validate BSON/MongoDB ObjectID's\n```js\nconst  { ObjectID } = require(\"mongodb\") // or anywhere else \n\nconst schema = {\n    id: {\n        type: \"objectID\",\n        ObjectID // passing the ObjectID class\n    }  \n}\nconst check = v.compile(schema);\n\ncheck({ id: \"5f082780b00cc7401fb8e8fc\" }) // ok\ncheck({ id: new ObjectID() }) // ok\ncheck({ id: \"5f082780b00cc7401fb8e8\" }) // Error\n```\n\n**Pro tip:**  By using defaults props for objectID rule, No longer needed to pass `ObjectID` class in validation schema:\n\n```js\nconst  { ObjectID } = require(\"mongodb\") // or anywhere else \n\nconst v = new Validator({\n    defaults: {\n        objectID: {\n            ObjectID\n        }\n    }\n})\n\nconst schema = {\n    id: \"objectID\" \n}\n```\n\n### Properties\nProperty | Default  | Description\n-------- | -------- | -----------\n`convert`  | `false`   | If `true`, the validator converts ObjectID HexString representation to ObjectID `instance`, if `hexString` the validator converts to HexString\n\n# Custom validator\nYou can also create your custom validator.\n\n```js\nconst v = new Validator({\n    messages: {\n        // Register our new error message text\n        evenNumber: \"The '{field}' field must be an even number! Actual: {actual}\"\n    }\n});\n\n// Register a custom 'even' validator\nv.add(\"even\", function({ schema, messages }, path, context) {\n    return {\n        source: `\n            if (value % 2 != 0)\n                ${this.makeError({ type: \"evenNumber\",  actual: \"value\", messages })}\n\n            return value;\n        `\n    };\n});\n\nconst schema = {\n    name: { type: \"string\", min: 3, max: 255 },\n    age: { type: \"even\" }\n};\nconst check = v.compile(schema);\n\nconsole.log(check({ name: \"John\", age: 20 }, schema));\n// Returns: true\n\nconsole.log(check({ name: \"John\", age: 19 }, schema));\n/* Returns an array with errors:\n    [{\n        type: 'evenNumber',\n        expected: null,\n        actual: 19,\n        field: 'age',\n        message: 'The \\'age\\' field must be an even number! Actual: 19'\n    }]\n*/\n```\n\nOr you can use the `custom` type with an inline checker function:\n```js\nconst v = new Validator({\n    useNewCustomCheckerFunction: true, // using new version\n    messages: {\n        // Register our new error message text\n        weightMin: \"The weight must be greater than {expected}! Actual: {actual}\"\n    }\n});\n\nconst schema = {\n    name: { type: \"string\", min: 3, max: 255 },\n    weight: {\n        type: \"custom\",\n        minWeight: 10,\n        check(value, errors, schema) {\n            if (value \u003c minWeight) errors.push({ type: \"weightMin\", expected: schema.minWeight, actual: value });\n            if (value \u003e 100) value = 100\n            return value\n        }\n    }\n};\nconst check = v.compile(schema);\n\nconsole.log(check({ name: \"John\", weight: 50 }, schema));\n// Returns: true\n\nconsole.log(check({ name: \"John\", weight: 8 }, schema));\n/* Returns an array with errors:\n    [{\n        type: 'weightMin',\n        expected: 10,\n        actual: 8,\n        field: 'weight',\n        message: 'The weight must be greater than 10! Actual: 8'\n    }]\n*/\nconst o = { name: \"John\", weight: 110 }\nconsole.log(check(o, schema));\n/* Returns: true\n   o.weight is 100\n*/\n```\n\u003ePlease note: the custom function must return the `value`. It means you can also sanitize it.\n\n## Custom validation for built-in rules\nYou can define a `custom` function in the schema for built-in rules. With it you can extend any built-in rules.\n\n```js\nconst v = new Validator({\n    useNewCustomCheckerFunction: true, // using new version\n    messages: {\n        // Register our new error message text\n        phoneNumber: \"The phone number must be started with '+'!\"\n    }\n});\n\nconst schema = {\n    name: { type: \"string\", min: 3, max: 255 },\n    phone: { type: \"string\", length: 15, custom: (v, errors) =\u003e {\n            if (!v.startsWith(\"+\")) errors.push({ type: \"phoneNumber\" })\n            return v.replace(/[^\\d+]/g, \"\"); // Sanitize: remove all special chars except numbers\n        }\n    }\t\n};\nconst check = v.compile(schema);\n\n\nconsole.log(check({ name: \"John\", phone: \"+36-70-123-4567\" }));\n// Returns: true\n\nconsole.log(check({ name: \"John\", phone: \"36-70-123-4567\" }));\n/* Returns an array with errors:\n    [{\n        message: \"The phone number must be started with '+'!\",\n        field: 'phone',\n        type: 'phoneNumber'\n    }]\n*/\n```\n\n\u003ePlease note: the custom function must return the `value`. It means you can also sanitize it.\n\n### Chaining custom functions and global definitions\nYou can define the `custom` property as an array of functions, allowing you to chain various validation logics. \n\nAdditionally, you can define custom functions globally, making them reusable.\n```js\n\nlet v = new Validator({\n\tdebug: true,\n\tuseNewCustomCheckerFunction: true,\n\tmessages: {\n\t\t// Register our new error message text\n\t\tevenNumber: \"The '{field}' field must be an even number! Actual: {actual}\",\n\t\trealNumber: \"The '{field}' field must be a real number! Actual: {actual}\",\n\t\tnotPermitNumber: \"The '{field}'  cannot have the value  {actual}\",\n        compareGt: \"The '{field}' field must be greater than {gt}! Actual: {actual}\",\n        compareGte: \"The '{field}' field must be greater than or equal to {gte}! Actual: {actual}\",\n        compareLt: \"The '{field}' field must be less than {lt}! Actual: {actual}\",\n        compareLte: \"The '{field}' field must be less than or equal to {lte}! Actual: {actual}\"\n\t},\n\tcustomFunctions:{\n\t\teven: (value, errors)=\u003e{\n\t\t\tif(value % 2 != 0 ){\n\t\t\t\terrors.push({ type: \"evenNumber\",  actual: value });\n\t\t\t}\n\t\t\treturn value;\n\t\t},\n\t\treal: (value, errors)=\u003e{\n\t\t\tif(value \u003c0 ){\n\t\t\t\terrors.push({ type: \"realNumber\",  actual: value });\n\t\t\t}\n\t\t\treturn value;\n\t\t},\n        compare: (value, errors, schema)=\u003e{\n\t\t\t\tif( typeof schema.custom.gt===\"number\" \u0026\u0026 value \u003c= schema.custom.gt ){\n\t\t\t\t\terrors.push({ type: \"compareGt\",  actual: value, gt: schema.custom.gt });\n\t\t\t\t}\n\t\t\t\tif( typeof schema.custom.gte===\"number\" \u0026\u0026 value \u003c schema.custom.gte ){\n\t\t\t\t\terrors.push({ type: \"compareGte\",  actual: value, gte: schema.custom.gte });\n\t\t\t\t}\n\t\t\t\tif( typeof schema.custom.lt===\"number\" \u0026\u0026 value \u003e= schema.custom.lt ){\n\t\t\t\t\terrors.push({ type: \"compareLt\",  actual: value, lt: schema.custom.lt });\n\t\t\t\t}\n\t\t\t\tif( typeof schema.custom.lte===\"number\" \u0026\u0026 value \u003e schema.custom.lte ){\n\t\t\t\t\terrors.push({ type: \"compareLte\",  actual: value, lte: schema.custom.lte });\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\t}\n});\n\n\n\nconst schema = {\n\tpeople:{\n\t\ttype: \"number\",\n\t\tcustom: [\n            \"compare|gte:-100|lt:200\",  // extended definition with additional parameters - equal to: {type:\"compare\",gte:-100, lt:200}, \n\t\t\t\"even\",\n\t\t\t\"real\",\n\t\t\tfunction (value, errors){\n\t\t\t\tif(value === \"3\" ){\n\t\t\t\t\terrors.push({ type: \"notPermitNumber\",  actual: value });\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\t\t]\n\t}\n};\n\nconsole.log(v.validate({people:-200}, schema));\nconsole.log(v.validate({people:200}, schema));\nconsole.log(v.validate({people:5}, schema));\nconsole.log(v.validate({people:-5}, schema));\nconsole.log(v.validate({people:3}, schema));\n\n```\n\n\n\n\n## Asynchronous custom validations\nYou can also use async custom validators. This can be useful if you need to check something in a database or in a remote location.\nIn this case you should use `async/await` keywords, or return a `Promise` in the custom validator functions.\n\n\u003eThis implementation uses `async/await` keywords. So this feature works only on environments which [supports async/await](https://caniuse.com/async-functions):\n\u003e\n\u003e - Chrome \u003e 55\n\u003e - Firefox \u003e 52\n\u003e - Edge \u003e 15\n\u003e - NodeJS \u003e 8.x (or 7.6 with harmony)\n\u003e - Deno (all versions)\n\nTo enable async mode, you should set `$$async: true` in the root of your schema.\n\n**Example with custom checker function**\n```js\nconst v = new Validator({\n    useNewCustomCheckerFunction: true, // using new version\n    messages: {\n        // Register our new error message text\n        unique: \"The username is already exist\"\n    }\n});\n\nconst schema = {\n    $$async: true,\n    name: { type: \"string\" },\n    username: {\n        type: \"string\",\n        min: 2,\n        custom: async (v, errors) =\u003e {\n            // E.g. checking in the DB that the value is unique.\n            const res = await DB.checkUsername(v);\n            if (!res) \n                errors.push({ type: \"unique\", actual: value });\n\n            return v;\n        }\n    }\n    // ...\n};\n\nconst check = v.compile(schema);\n\nconst res = await check(user);\nconsole.log(\"Result:\", res);\n```\n\n\nThe compiled `check` function contains an `async` property, so  you can check if it returns a `Promise` or not.\n```js\nconst check = v.compile(schema);\nconsole.log(\"Is async?\", check.async);\n```\n\n## Meta information for custom validators\nYou can pass any extra meta information for the custom validators which is available via `context.meta`.\n\n```js\nconst schema = {\n    name: { type: \"string\", custom: (value, errors, schema, name, parent, context) =\u003e {\n        // Access to the meta\n        return context.meta.a;\n    } },\n};\nconst check = v.compile(schema);\n\nconst res = check(obj, {\n    // Passes meta information\n    meta: { a: \"from-meta\" }\n});\n```\n\n# Custom error messages (l10n)\nYou can set your custom messages in the validator constructor.\n\n```js\nconst Validator = require(\"fastest-validator\");\nconst v = new Validator({\n    messages: {\n        stringMin: \"A(z) '{field}' mező túl rövid. Minimum: {expected}, Jelenleg: {actual}\",\n        stringMax: \"A(z) '{field}' mező túl hosszú. Minimum: {expected}, Jelenleg: {actual}\"\n    }\n});\n\nconst schema = {\n    name: { type: \"string\", min: 6 }\n}\nconst check = v.compile(schema);\n\ncheck({ name: \"John\" });\n/* Returns:\n[\n    {\n        type: 'stringMin',\n        expected: 6,\n        actual: 4,\n        field: 'name',\n        message: 'A(z) \\'name\\' mező túl rövid. Minimum: 6, Jelenleg: 4'\n    }\n]\n*/\n```\n# Personalised Messages\nSometimes the standard messages are too generic. You can customize messages per validation type per field:\n\n```js\nconst Validator = require(\"fastest-validator\");\nconst v = new Validator();\nconst schema = {\n    firstname: {\n        type: \"string\",\n        min: 6,\n        messages: {\n            string: \"Please check your firstname\",\n            stringMin: \"Your firstname is too short\"\n        }\n    },\n    lastname: {\n        type: \"string\",\n        min: 6,\n        messages: {\n            string: \"Please check your lastname\",\n            stringMin: \"Your lastname is too short\"\n        }\n    }\n}\nconst check = v.compile(schema);\n\ncheck({ firstname: \"John\", lastname: 23 });\n/* Returns:\n[\n    {\n        type: 'stringMin',\n        expected: 6,\n        actual: 4,\n        field: 'firstname',\n        message: 'Your firstname is too short'\n    },\n    {\n        type: 'string',\n        expected: undefined,\n        actual: undefined,\n        field: 'lastname',\n        message: 'Please check your lastname'\n    }\n]\n*/\n```\n# Plugins\nYou can apply plugins:\n```js\n// Plugin Side\nfunction myPlugin(validator){\n    // you can modify validator here\n    // e.g.: validator.add(...)\n}\n\n// Validator Side\nconst v = new Validator();\nv.plugin(myPlugin)\n\n```\n\n# Message types\nName                | Default text\n------------------- | -------------\n`required`\t| The '{field}' field is required.\n`string`\t| The '{field}' field must be a string.\n`stringEmpty`\t| The '{field}' field must not be empty.\n`stringMin`\t| The '{field}' field length must be greater than or equal to {expected} characters long.\n`stringMax`\t| The '{field}' field length must be less than or equal to {expected} characters long.\n`stringLength`\t| The '{field}' field length must be {expected} characters long.\n`stringPattern`\t| The '{field}' field fails to match the required pattern.\n`stringContains`\t| The '{field}' field must contain the '{expected}' text.\n`stringEnum`\t| The '{field}' field does not match any of the allowed values.\n`stringNumeric`\t| The '{field}' field must be a numeric string.\n`stringAlpha`\t| The '{field}' field must be an alphabetic string.\n`stringAlphanum`\t| The '{field}' field must be an alphanumeric string.\n`stringAlphadash`\t| The '{field}' field must be an alphadash string.\n`stringHex`\t| The '{field}' field must be a hex string.\n`stringSingleLine`\t| The '{field}' field must be a single line string.\n`stringBase64`\t| The '{field}' field must be a base64 string.\n`number`\t| The '{field}' field must be a number.\n`numberMin`\t| The '{field}' field must be greater than or equal to {expected}.\n`numberMax`\t| The '{field}' field must be less than or equal to {expected}.\n`numberEqual`\t| The '{field}' field must be equal to {expected}.\n`numberNotEqual`\t| The '{field}' field can't be equal to {expected}.\n`numberInteger`\t| The '{field}' field must be an integer.\n`numberPositive`\t| The '{field}' field must be a positive number.\n`numberNegative`\t| The '{field}' field must be a negative number.\n`array`\t| The '{field}' field must be an array.\n`arrayEmpty`\t| The '{field}' field must not be an empty array.\n`arrayMin`\t| The '{field}' field must contain at least {expected} items.\n`arrayMax`\t| The '{field}' field must contain less than or equal to {expected} items.\n`arrayLength`\t| The '{field}' field must contain {expected} items.\n`arrayContains`\t| The '{field}' field must contain the '{expected}' item.\n`arrayUnique` | The '{actual}' value in '{field}' field does not unique the '{expected}' values.\n`arrayEnum`\t| The '{actual}' value in '{field}' field does not match any of the '{expected}' values.\n`tuple`\t| The '{field}' field must be an array.\n`tupleEmpty`\t| The '{field}' field must not be an empty array.\n`tupleLength`\t| The '{field}' field must contain {expected} items.\n`boolean`\t| The '{field}' field must be a boolean.\n`function`\t| The '{field}' field must be a function.\n`date`\t| The '{field}' field must be a Date.\n`dateMin`\t| The '{field}' field must be greater than or equal to {expected}.\n`dateMax`\t| The '{field}' field must be less than or equal to {expected}.\n`forbidden`\t| The '{field}' field is forbidden.\n`email` | The '{field}' field must be a valid e-mail.\n`emailEmpty` | The '{field}' field must not be empty.\n`emailMin` | The '{field}' field length must be greater than or equal to {expected} characters long.\n`emailMax` | The '{field}' field length must be less than or equal to {expected} characters long.\n`url`\t| The '{field}' field must be a valid URL.\n`enumValue`\t| The '{field}' field value '{expected}' does not match any of the allowed values.\n`equalValue`\t| The '{field}' field value must be equal to '{expected}'.\n`equalField`\t| The '{field}' field value must be equal to '{expected}' field value.\n`object`\t| The '{field}' must be an Object.\n`objectStrict`\t| The object '{field}' contains forbidden keys: '{actual}'.\n`objectMinProps` | \"The object '{field}' must contain at least {expected} properties.\n`objectMaxProps` | \"The object '{field}' must contain {expected} properties at most.\n`uuid`\t| The '{field}' field must be a valid UUID.\n`uuidVersion`\t| The '{field}' field must be a valid UUID version provided.\n`mac`\t| The '{field}' field must be a valid MAC address.\n`luhn`\t| The '{field}' field must be a valid checksum luhn.\n\n## Message fields\nName        | Description\n----------- | -------------\n`field`     | The field name\n`expected`  | The expected value\n`actual`    | The actual value\n\n# Pass custom metas\nIn some case, you will need to do something with the validation schema . \nLike reusing the validator to pass custom settings, you can use properties starting with `$$`\n\n````typescript\nconst check = v.compile({\n    $$name: 'Person',\n    $$description: 'write a description about this schema',\n    firstName: { type: \"string\" },\n    lastName: { type: \"string\" },\n    birthDate: { type: \"date\" }    \n});\n````\n\n# Development\n```\nnpm run dev\n```\n\n# Test\n```\nnpm test\n```\n\n## Coverage report\n```\n-----------------|----------|----------|----------|----------|-------------------|\nFile             |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |\n-----------------|----------|----------|----------|----------|-------------------|\nAll files        |      100 |    97.73 |      100 |      100 |                   |\n lib             |      100 |      100 |      100 |      100 |                   |\n  messages.js    |      100 |      100 |      100 |      100 |                   |\n  validator.js   |      100 |      100 |      100 |      100 |                   |\n lib/helpers     |      100 |      100 |      100 |      100 |                   |\n  deep-extend.js |      100 |      100 |      100 |      100 |                   |\n  flatten.js     |      100 |      100 |      100 |      100 |                   |\n lib/rules       |      100 |    96.43 |      100 |      100 |                   |\n  any.js         |      100 |      100 |      100 |      100 |                   |\n  array.js       |      100 |      100 |      100 |      100 |                   |\n  boolean.js     |      100 |      100 |      100 |      100 |                   |\n  custom.js      |      100 |       50 |      100 |      100 |                 6 |\n  date.js        |      100 |      100 |      100 |      100 |                   |\n  email.js       |      100 |      100 |      100 |      100 |                   |\n  enum.js        |      100 |       50 |      100 |      100 |                 6 |\n  equal.js       |      100 |      100 |      100 |      100 |                   |\n  forbidden.js   |      100 |      100 |      100 |      100 |                   |\n  function.js    |      100 |      100 |      100 |      100 |                   |\n  luhn.js        |      100 |      100 |      100 |      100 |                   |\n  mac.js         |      100 |      100 |      100 |      100 |                   |\n  multi.js       |      100 |      100 |      100 |      100 |                   |\n  number.js      |      100 |      100 |      100 |      100 |                   |\n  object.js      |      100 |      100 |      100 |      100 |                   |\n  string.js      |      100 |    95.83 |      100 |      100 |             55,63 |\n  tuple.js       |      100 |      100 |      100 |      100 |                   |\n  url.js         |      100 |      100 |      100 |      100 |                   |\n  uuid.js        |      100 |      100 |      100 |      100 |                   |\n-----------------|----------|----------|----------|----------|-------------------|\n```\n\n# Contribution\nPlease send pull requests improving the usage and fixing bugs, improving documentation and providing better examples, or providing some tests, because these things are important.\n\n# License\nfastest-validator is available under the [MIT license](https://tldrlegal.com/license/mit-license).\n\n# Contact\n\nCopyright (C) 2019 Icebob\n\n[![@icebob](https://img.shields.io/badge/github-icebob-green.svg)](https://github.com/icebob) [![@icebob](https://img.shields.io/badge/twitter-Icebobcsi-blue.svg)](https://twitter.com/Icebobcsi)\n","funding_links":[],"categories":["JavaScript","Modules","others"],"sub_categories":["Utils"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ficebob%2Ffastest-validator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ficebob%2Ffastest-validator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ficebob%2Ffastest-validator/lists"}