{"id":13454662,"url":"https://github.com/schema-inspector/schema-inspector","last_synced_at":"2026-01-15T22:20:49.710Z","repository":{"id":12904610,"uuid":"15581810","full_name":"schema-inspector/schema-inspector","owner":"schema-inspector","description":"Schema-Inspector is a simple JavaScript object sanitization and validation module.","archived":false,"fork":false,"pushed_at":"2024-12-03T23:52:58.000Z","size":1937,"stargazers_count":503,"open_issues_count":1,"forks_count":45,"subscribers_count":10,"default_branch":"master","last_synced_at":"2026-01-13T04:11:59.695Z","etag":null,"topics":["data-cleaning","javascript","sanitization","validation"],"latest_commit_sha":null,"homepage":"http://schema-inspector.github.io/schema-inspector/","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/schema-inspector.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-01-02T11:07:52.000Z","updated_at":"2025-08-23T19:30:15.000Z","dependencies_parsed_at":"2022-08-30T22:30:08.942Z","dependency_job_id":"db38650d-d3a1-4d5d-bf96-313499ed545c","html_url":"https://github.com/schema-inspector/schema-inspector","commit_stats":{"total_commits":147,"total_committers":22,"mean_commits":6.681818181818182,"dds":0.5510204081632653,"last_synced_commit":"bba84e8b60e8537f94f2c0e96f50c0350b4e414e"},"previous_names":["atinux/schema-inspector"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/schema-inspector/schema-inspector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schema-inspector%2Fschema-inspector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schema-inspector%2Fschema-inspector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schema-inspector%2Fschema-inspector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schema-inspector%2Fschema-inspector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/schema-inspector","download_url":"https://codeload.github.com/schema-inspector/schema-inspector/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schema-inspector%2Fschema-inspector/sbom","scorecard":{"id":17326,"data":{"date":"2025-08-04","repo":{"name":"github.com/schema-inspector/schema-inspector","commit":"bca22fb7ae0deda378216c4ef4e27ec453e1f293"},"scorecard":{"version":"v5.2.1-28-gc1d103a9","commit":"c1d103a9bb9f635ec7260bf9aa0699466fa4be0e"},"score":4.5,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":2,"reason":"Found 6/27 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/codeql-analysis.yml:1","Warn: no topLevel permission defined: .github/workflows/lint.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/schema-inspector/schema-inspector/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/schema-inspector/schema-inspector/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/schema-inspector/schema-inspector/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/schema-inspector/schema-inspector/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/schema-inspector/schema-inspector/lint.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/schema-inspector/schema-inspector/lint.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/schema-inspector/schema-inspector/test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/schema-inspector/schema-inspector/test.yml/master?enable=pin","Warn: npmCommand not pinned by hash: .github/workflows/lint.yml:24","Warn: npmCommand not pinned by hash: .github/workflows/test.yml:26","Info:   0 out of   8 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#branch-protection"}},{"name":"SAST","score":7,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 0 commits out of 18 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-14T16:04:51.301Z","repository_id":12904610,"created_at":"2025-08-14T16:04:51.301Z","updated_at":"2025-08-14T16:04:51.301Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28472626,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-15T22:13:38.078Z","status":"ssl_error","status_checked_at":"2026-01-15T22:12:11.737Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["data-cleaning","javascript","sanitization","validation"],"created_at":"2024-07-31T08:00:56.508Z","updated_at":"2026-01-15T22:20:49.695Z","avatar_url":"https://github.com/schema-inspector.png","language":"JavaScript","funding_links":[],"categories":["Packages","包","JavaScript"],"sub_categories":["Data validation","数据验证"],"readme":"\u003c!-- markdownlint-disable MD041 MD033 MD024 --\u003e\n\n# schema-inspector\n\n![Lint workflow](https://github.com/schema-inspector/schema-inspector/actions/workflows/lint.yml/badge.svg)\n![CodeQL workflow](https://github.com/schema-inspector/schema-inspector/actions/workflows/codeql-analysis.yml/badge.svg)\n![Test workflow](https://github.com/schema-inspector/schema-inspector/actions/workflows/test.yml/badge.svg)\n\n[![NPM version](https://badge.fury.io/js/schema-inspector.png)](http://badge.fury.io/js/schema-inspector)\n\nSchema-Inspector is a powerful tool to sanitize and validate JS objects.\nIt's designed to work both client-side and server-side and to be scalable with allowing asynchronous and synchronous calls.\n\n**See a live example:** \u003chttp://schema-inspector.github.io/schema-inspector/\u003e\n\n## Installation\n\n### Node.js\n\n\u003cpre\u003enpm install schema-inspector\u003c/pre\u003e\n\n### Browser\n\nBower uses have reported success using the library this way, using bower overrides in `bower.json`.\n\n![image](https://user-images.githubusercontent.com/37461352/111504514-808a8200-8726-11eb-8cbc-09c35d9c0c81.png)\n\nBower is not officially-supported as a build tool and references to it will be removed from the repository in versions 3.0.0+.\n\n## Comparison with JSON Schema\n\n`schema-inspector` is not compatable with JSON Schema. They are two different ways to validate data.\nHowever, the main difference is that `schema-inspector` supports sanitization of data.\n\n## Notable changelogs\n\n### Version 2.0.0\n\nTo fix a security vulnerability in the 1.x.x email Regex expression used, a new Regex expression was used which may be\nless flexible than the expression used in 1.x.x. Therefore, version 2.0.0 was released with this new expression. It's\nhighly-recommended to upgrade to this new version after testing it.\n\nIf you need the old, insecure behavior, use version 1.x.x or use the custom validation function feature for your field\nand perform email address validation any way you like.\n\n### Version 2.0.3\n\nThe email address regular expression was changed again in this version, this time to the new approach towards email address validation that the library will use from now on. For details, see [How email address validation works](#v_pattern_email).\n\n## How it looks like\n\n[![schema-inspector demo](http://schema-inspector.github.io/schema-inspector/images/doc/example.png)](http://schema-inspector.github.io/schema-inspector/)\n*Click to see it live!*\n\n## Usage\n\n```javascript\nvar inspector = require('schema-inspector');\n\n// Data that we want to sanitize and validate\nvar data = {\n    firstname: 'sterling  ',\n    lastname: '  archer',\n    jobs: 'Special agent, cocaine Dealer',\n    email: 'NEVER!',\n};\n\n// Sanitization Schema\nvar sanitization = {\n    type: 'object',\n    properties: {\n        firstname: { type: 'string', rules: ['trim', 'title'] },\n        lastname: { type: 'string', rules: ['trim', 'title'] },\n        jobs: {\n            type: 'array',\n            splitWith: ',',\n            items: { type: 'string', rules: ['trim', 'title'] },\n        },\n        email: { type: 'string', rules: ['trim', 'lower'] },\n    },\n};\n// Let's update the data\ninspector.sanitize(sanitization, data);\n/*\ndata is now:\n{\n    firstname: 'Sterling',\n    lastname: 'Archer',\n    jobs: ['Special Agent', 'Cocaine Dealer'],\n    email: 'never!'\n}\n*/\n\n// Validation schema\nvar validation = {\n    type: 'object',\n    properties: {\n        firstname: { type: 'string', minLength: 1 },\n        lastname: { type: 'string', minLength: 1 },\n        jobs: {\n            type: 'array',\n            items: { type: 'string', minLength: 1 },\n        },\n        email: { type: 'string', pattern: 'email' },\n    },\n};\nvar result = inspector.validate(validation, data);\nif (!result.valid)\n    console.log(result.format());\n/*\n Property @.email: must match [email], but is equal to \"never!\"\n*/\n```\n\n**Tips:** it's recommended to use one schema for the sanitization and another for the validation,\n\n## In the browser\n\n```html\n\u003cscript type=\"text/javascript\" src=\"async.js\"\u003e\u003c/script\u003e\n\u003cscript type=\"text/javascript\" src=\"schema-inspector.js\"\u003e\u003c/script\u003e\n\u003cscript type=\"text/javascript\"\u003e\n    var schema = { /* ... */ };\n    var candidate = { /* ... */ };\n    SchemaInspector.validate(schema, candidate, function (err, result) {\n    if (!result.valid)\n        return alert(result.format());\n });\n\u003c/script\u003e\n```\n\nIn the example below, the `inspector` variable will be used.  For the client-side use `SchemaInspector` instead of `inspector`.\n\n## Documentation\n\n### Validation\n\n* [type](#v_type)\n* [optional](#v_optional)\n* [pattern](#v_pattern)\n* [minLength, maxLength, exactLength](#v_length)\n* [lt, lte, gt, gte, eq, ne](#v_comparators)\n* [multipleOf](#v_multipleOf)\n* [someKeys](#v_someKeys)\n* [strict](#v_strict)\n* [exec](#v_exec)\n* [properties](#v_properties)\n* [items](#v_items)\n* [alias](#v_alias)\n* [error](#v_error)\n* [code](#v_code)\n\n### Sanitization\n\n* [type](#s_type)\n* [def](#s_def)\n* [optional](#s_optional)\n* [rules](#s_rules)\n* [min, max](#s_comparators)\n* [minLength, maxLength](#s_length)\n* [strict](#s_strict)\n* [exec](#s_exec)\n* [properties](#s_properties)\n* [items](#s_items)\n\n### Custom fields\n\n* [punctual use](#cf_punctual)\n* [extension](#cf_extension)\n* [context](#cf_context)\n\n### Asynchronous call\n\n* [How to](#how-to)\n\n### Thanks to\n\n* [Benjamin Gressier](https://twitter.com/NikitaJS) (major contributor of this awesome module)\n\n## Validation\n\n\u003ch3 id=\"v_type\"\u003etype\u003c/h3\u003e\n\n* **type**: string, array of string.\n* **usable on**: any.\n* **possible values**\n  * `string`\n  * `number`\n  * `integer`\n  * `boolean`\n  * `null`\n  * `date` (instanceof Date), you can use the `validDate: true` to check if the date is valid\n  * `object` (typeof element === 'object') *Note: array, null, or dates don't match the object type*\n  * `array` (constructor === Array)\n  * A function (candidate isinstance)\n  * `any` (it can be anything)\n\nAllow to check property type. If the given value is incorrect, then type is not\nchecked.\n\n### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nfunction Class() {}\n\nvar schema = {\n    type: 'object',\n    properties: {\n        lorem: { type: 'number' },\n        ipsum: { type: 'any' },\n        dolor: { type: ['number', 'string', 'null'] },\n        sit: { type: Class },\n    },\n};\n\nvar c1 = {\n    lorem: 12,\n    ipsum: 'sit amet',\n    dolor: 23,\n    sit: new Class(),\n};\nvar c2 = {\n    lorem: 12,\n    ipsum: 34,\n    dolor: 'sit amet',\n    sit: new Class(),\n};\nvar c3 = {\n    lorem: 12,\n    ipsum: ['sit amet'],\n    dolor: null,\n    sit: new Class(),\n};\nvar c4 = {\n    lorem: '12',\n    ipsum: 'sit amet',\n    dolor: new Date(),\n    sit: {},\n};\n\ninspector.validate(schema, c1); // Valid\ninspector.validate(schema, c2); // Valid\ninspector.validate(schema, c3); // Valid\ninspector.validate(schema, c4); // Invalid: @.lorem must be a number, @dolor must be a number, a string or null, @.sit must be an instance of Class, but is object\n```\n\n---------------------------------------\n\n\u003ch3 id=\"v_optional\"\u003eoptional\u003c/h3\u003e\n\n* **type**: boolean.\n* **default**: false.\n* **usable on**: any.\n\nThis field indicates whether or not property has to exist.\n\n#### Example\n\n```javascript\nvar inspector = require('Roadspector');\n\nvar schema1 = {\n    type: 'object',\n    properties: {\n        lorem: { type: 'any', optional: true },\n    },\n};\n\nvar schema2 = {\n    type: 'object',\n    properties: {\n        lorem: { type: 'any', optional: false }, // default value\n    },\n};\n\nvar c1 = { lorem: 'ipsum' };\nvar c2 = {};\n\ninspector.validate(schema1, c1); // Valid\ninspector.validate(schema1, c2); // Valid\ninspector.validate(schema2, c1); // Valid\ninspector.validate(schema2, c2); // Invalid: \"@.lorem\" is missing and not optional\n```\n\n---------------------------------------\n\n\u003ch3 id=\"v_uniqueness\"\u003euniqueness\u003c/h3\u003e\n\n* **type**: boolean.\n* **default**: false.\n* **usable on**: array, string.\n\nIf true, then we ensure no element in candidate exists more than once.\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = {\n    type: 'array',\n    uniqueness: true,\n};\n\nvar c1 = [12, 23, 34, 45];\nvar c2 = [12, 23, 34, 12];\n\ninspector.validate(schema, c1); // Valid\ninspector.validate(schema, c2); // Invalid: 12 exists twice in @.\n```\n\n---------------------------------------\n\n\u003ch3 id=\"v_pattern\"\u003epattern\u003c/h3\u003e\n\n* **type**: string, RegExp object, array of string and RegExp.\n* **usable on**: string.\n* Possible values as a string: `void`, `url`, `date-time`, `date`,\n`coolDateTime`, `time`, `color`, `email`, `numeric`, `integer`, `decimal`, `v4uuid`,\n`alpha`, `alphaNumeric`, `alphaDash`, `javascript`, `upperString`, `lowerString`.\n\nAsk Schema-Inspector to check whether or not a given matches provided patterns.\nWhen a pattern is a RegExp, it directly test the string with it. When it's a\nstring, it's an alias of a built-in RegExp that the library supports. For example, using the string `email` causes the built-in RegExp for email addresses to be used.\n\n\u003ch4 id=\"v_pattern_email\"\u003eHow email address validation works\u003c/h4\u003e\n\nIt is a very flexible regular expression, so that the library is only designed to catch obvious mistakes a user might make in the front end of a system that would have a 100% chance to cause email delivery to fail. An exception is made to forbid email addresses that lack a domain (used only by internal systems). It is based on the recommended regular expression posted on [www.regular-expressions.info](https://www.regular-expressions.info/email.html), modified to allow lowercase alphabetic characters too.\n\nYou should perform more thorough checking of email addresses that involves checking whether delivery to the email address would succeed or fail, from your server side code. This library should only be used as basic front end validation for user convenience (e.g. an error displayed in the front end before they submit a form vs. a system failure that may not make it clear to them what went wrong).\n\nIf you want to validate strings more strictly than this, you should use your own custom regular expression instead of the `email` pattern.\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema1 = {\n    type: 'array',\n    items: { type: 'string', pattern: /^[A-C]/ },\n};\n\nvar c1 = ['Alorem', 'Bipsum', 'Cdolor', 'DSit amet'];\n\nvar schema2 = {\n    type: 'array',\n    items: { type: 'string', pattern: 'email' },\n};\n\nvar c2 = ['lorem@ipsum.com', 'dolor@sit.com', 'amet@consectetur'];\n\ninspector.validate(schema1, c1); // Invalid: @[3] ('DSit amet') does not match /^[A-C]/\ninspector.validate(schema2, c2); // Invalid: @[2] ('amet@consectetur') does not match \"email\" pattern.\n```\n\n---------------------------------------\n\n\u003ch3 id=\"v_length\"\u003eminLength, maxLength, exactLength\u003c/h3\u003e\n\n* **type**: integer.\n* **usable on**: array, string.\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = {\n    type: 'object',\n    properties: {\n        lorem: { type: 'string', minLength: 4, maxLength: 8 },\n        ipsum: { type: 'array', exactLength: 6 },\n    },\n};\nvar c1 = {\n    lorem: '12345',\n    ipsum: [1, 2, 3, 4, 5, 6],\n};\n\nvar c2 = {\n    lorem: '123456789',\n    ipsum: [1, 2, 3, 4, 5],\n};\n\ninspector.validate(schema, c1); // Valid\ninspector.validate(schema, c2); // Invalid: @.lorem must have a length between 4 and 8 (here 9)\n// and @.ipsum must have a length of 6 (here 5)\n```\n\n---------------------------------------\n\n\u003ch3 id=\"v_comparators\"\u003elt, lte, gt, gte, eq, ne\u003c/h3\u003e\n\n* **type**: number (string, number and boolean for eq).\n* **usable on**: number (string, number and boolean for eq).\n\nCheck whether comparison is true:\n\n* lt: `\u003c`\n* lte: `\u003c=`\n* gt: `\u003e`\n* gte: `\u003e=`\n* eq: `===`\n* ne: `!==`\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = {\n    type: 'object',\n    properties: {\n        lorem: { type: 'number', gt: 0, lt: 5 }, // Between ]0; 5[\n        ipsum: { type: 'number', gte: 0, lte: 5 }, // Between [0; 5]\n        dolor: { type: 'number', eq: [0, 3, 6, 9] }, // Equal to 0, 3, 6 or 9\n        sit: { type: 'number', ne: [0, 3, 6, 9] }, // Not equal to 0, 3, 6 nor 9\n    },\n};\n\nvar c1 = { lorem: 3, ipsum: 0, dolor: 6, sit: 2 };\nvar c2 = { lorem: 0, ipsum: -1, dolor: 5, sit: 3 };\n\ninspector.validate(schema, c1); // Valid\ninspector.validate(schema, c2); // Invalid\n```\n\n---------------------------------------\n\n\u003ch3 id=\"v_multipleOf\"\u003emultipleOf\u003c/h3\u003e\n\n* **type**: number\n* **usable on**: number, array\n\nCheck whether the candidate is a multiple of the provided option. If the candidate is an array of numbers, it performs this validation on each number in the array.\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = {\n    type: 'number',\n    multipleOf: 2 // Even\n};\n\nvar c1 = 100;\nvar c2 = 73;\n\ninspector.validate(schema, c1); // Valid\ninspector.validate(schema, c2); // Invalid: 73 is not divisible by 2\n```\n\n---------------------------------------\n\n\u003ch3 id=\"v_someKeys\"\u003esomeKeys\u003c/h3\u003e\n\n* **type**: array of string.\n* **usable on**: object.\n\nCheck whether one of the given keys exists in object (useful when they are\noptional).\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = {\n    type: 'object',\n    someKeys: ['lorem', 'ipsum'],\n    properties: {\n        lorem: { type: 'any', optional: true },\n        ipsum: { type: 'any', optional: true },\n        dolor: { type: 'any' },\n    },\n};\n\nvar c1 = { lorem: 0, ipsum: 1, dolor: 2 };\nvar c2 = { lorem: 0, dolor: 2 };\nvar c3 = { dolor: 2 };\n\ninspector.validate(schema, c1); // Valid\ninspector.validate(schema, c2); // Valid\ninspector.validate(schema, c3); // Invalid: Neither @.lorem nor @.ipsum is in c3.\n```\n\n---------------------------------------\n\n\u003ch3 id=\"v_strict\"\u003estrict\u003c/h3\u003e\n\n* **type**: boolean.\n* **default**: false.\n* **usable on**: object.\n\nOnly keys provided in field \"properties\" may exist in the object. Strict will be ignored if properties has the special key '*'.\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = {\n    type: 'object',\n    strict: true,\n    properties: {\n        lorem: { type: 'any' },\n        ipsum: { type: 'any' },\n        dolor: { type: 'any' },\n    },\n};\n\nvar c1 = { lorem: 0, ipsum: 1, dolor: 2 };\nvar c2 = { lorem: 0, ipsum: 1, dolor: 2, sit: 3 };\n\ninspector.validate(schema, c1); // Valid\ninspector.validate(schema, c2); // Invalid: @.sit should not exist.\n```\n\n---------------------------------------\n\n\u003ch3 id=\"v_exec\"\u003eexec\u003c/h3\u003e\n\n* **type**: function, array of function.\n* **usable on**: any.\n\nCustom checker =). \"exec\" functions take two three parameter\n(schema, post [, callback]). To report an error, use `this.report([message], [code])`.\nVery useful to make some custom validation.\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = {\n    type: 'object',\n    properties: {\n        lorem: {\n            type: 'number',\n            exec: function (schema, post) {\n                // here schema === schema.properties.lorem and post === @.lorem\n                if (post === 3) {\n                    // As soon as `this.report()` is called, candidate is not valid.\n                    this.report('must not equal 3 =('); // Ok...it's exactly like \"ne: 3\"\n                }\n            },\n        },\n    },\n};\n\nvar c1 = { lorem: 2 };\nvar c2 = { lorem: 3 };\n\ninspector.validate(schema, c1); // Valid\ninspector.validate(schema, c2); // Invalid: \"@.lorem must not equal 3 =(\".\n```\n\n---------------------------------------\n\n\u003ch3 id=\"v_properties\"\u003eproperties\u003c/h3\u003e\n\n* **type**: object.\n* **usable on**: object.\n\nFor each property in the field \"properties\", whose value must be a schema,\nvalidation is called deeper in object.\n\nThe special property '*' is validated against any properties not specifically listed.\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = {\n    type: 'object',\n    properties: {\n        lorem: {\n            type: 'object',\n            properties: {\n                ipsum: {\n                    type: 'object',\n                    properties: {\n                        dolor: { type: 'string' },\n                    },\n                },\n            },\n        },\n        consectetur: { type: 'string' },\n        '*': { type: 'integer' },\n    },\n};\n\nvar c1 = {\n    lorem: {\n        ipsum: {\n            dolor: 'sit amet',\n        },\n    },\n    consectetur: 'adipiscing elit',\n    adipiscing: 12,\n};\nvar c2 = {\n    lorem: {\n        ipsum: {\n            dolor: 12,\n        },\n    },\n    consectetur: 'adipiscing elit',\n};\n\ninspector.validate(schema, c1); // Valid\ninspector.validate(schema, c2); // Invalid: @.lorem.ipsum.dolor must be a string.\n```\n\n---------------------------------------\n\n\u003ch3 id=\"v_items\"\u003eitems\u003c/h3\u003e\n\n* **type**: object, array of object.\n* **usable on**: array.\n\nAllow to apply schema validation for each element in an array. If it's an\nobject, then it's a schema which will be used for all the element. If it's an\narray of object, then it's an array of schema and each element in an array will\nbe checked with the schema which has the same position in the array.\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema1 = {\n    type: 'array',\n    items: { type: 'number' },\n};\n\nvar schema2 = {\n    type: 'array',\n    items: [{ type: 'number' }, { type: 'number' }, { type: 'string' }],\n};\n\nvar c1 = [1, 2, 3];\nvar c2 = [1, 2, 'string!'];\n\ninspector.validate(schema1, c1); // Valid\ninspector.validate(schema1, c2); // Invalid: @[2] must be a number.\ninspector.validate(schema2, c1); // Invalid: @[2] must be a string.\ninspector.validate(schema2, c2); // Valid\n```\n\n---------------------------------------\n\n\u003ch3 id=\"v_alias\"\u003ealias\u003c/h3\u003e\n\n* **type**: string.\n* **usable on**: any.\n\nAllow to display a more explicit property name if an error is encounted.\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema1 = {\n    type: 'object',\n    properties: {\n        _id: { type: 'string' },\n    },\n};\n\nvar schema2 = {\n    type: 'object',\n    properties: {\n        _id: { alias: 'id', type: 'string' },\n    },\n};\n\nvar c1 = { _id: 1234567890 };\n\nvar r1 = inspector.validate(schema1, c1);\nvar r2 = inspector.validate(schema2, c1);\nconsole.log(r1.format()); // Property @._id: must be string, but is number\nconsole.log(r2.format()); // Property id (@._id): must be string, but is number\n```\n\n---------------------------------------\n\n\u003ch3 id=\"v_error\"\u003eerror\u003c/h3\u003e\n\n* **type**: string.\n* **usable on**: any.\n\nThis field contains a user sentence for displaying a more explicit message if\nan error is encounted.\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema1 = {\n    type: 'object',\n    properties: {\n        _id: { type: 'string' },\n    },\n};\n\nvar schema2 = {\n    type: 'object',\n    properties: {\n        _id: { type: 'string', error: 'must be a valid ID.' },\n    },\n};\n\nvar c1 = { _id: 1234567890 };\n\nvar r1 = inspector.validate(schema1, c1);\nvar r2 = inspector.validate(schema2, c1);\nconsole.log(r1.format()); // Property @._id: must be string, but is number.\nconsole.log(r2.format()); // Property @._id: must be a valid ID.\n```\n\n---------------------------------------\n\n\u003ch3 id=\"v_code\"\u003ecode\u003c/h3\u003e\n\n* **type**: string.\n* **usable on**: any.\n\nThis field contains a user code for displaying a more uniform system to personnalize error message.\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema1 = {\n    type: 'object',\n    properties: {\n        _id: { type: 'string' },\n    },\n};\n\nvar schema2 = {\n    type: 'object',\n    properties: {\n        _id: { type: 'string', code: 'id-format' },\n    },\n};\n\nvar c1 = { _id: 1234567890 };\n\nvar r1 = inspector.validate(schema1, c1);\nvar r2 = inspector.validate(schema2, c1);\nconsole.log(r1.error[0].code); // null\nconsole.log(r2.error[0].code); // 'id-format'\n```\n\n## Sanitization\n\n\u003ch3 id=\"s_type\"\u003etype\u003c/h3\u003e\n\n* **type**: string.\n* **usable on**: any.\n* **possible values**\n  * `number`\n  * `integer`\n  * `string`\n  * `boolean`\n  * `date` (constructor === Date)\n  * `object` (constructor === Object)\n  * `array` (constructor === Array)\n\nCast property to the given type according to the following description:\n\n* **to number from**:\n  * string (ex: \"12.34\" -\u003e 12.34)\n![sanitization string to number](http://schema-inspector.github.io/schema-inspector/images/doc/sanitization-type-string-to-number.gif)\n  * date (ex: new Date(\"2014-01-01\") -\u003e 1388534400000)\n![sanitization string to number](http://schema-inspector.github.io/schema-inspector/images/doc/sanitization-type-date-to-number.gif)\n* **to integer from**:\n  * number\n    * 12.34 -\u003e 12\n  * string\n    * \"12.34\" -\u003e 12\n  * boolean\n    * true -\u003e 1\n    * false -\u003e 0\n  * date\n    * new Date(\"2014-01-01\") -\u003e 1388534400000\n* **to string from**:\n  * boolean\n    * true -\u003e \"true\"\n  * number\n    * 12.34 -\u003e \"12.34\"\n  * integer\n    * 12 -\u003e \"12\"\n  * date\n    * new Date(\"2014-01-01\") -\u003e \"Wed Jan 01 2014 01:00:00 GMT+0100 (CET)\"\n  * array\n    * [12, 23, 44] -\u003e '12,34,45'\n    * To join with a custom string, use **joinWith** key (example: { type: \"string\", joinWith: \"|\" } will transform [12, 23, 44] to \"12|23|44\").\n* **to date from**:\n  * number / integer\n    * 1361790386000 -\u003e Wed Jan 01 2014 01:00:00 GMT+0100 (CET)\n  * string\n    * \"2014-01-01 -\u003e Wed Jan 01 2014 01:00:00 GMT+0100 (CET)\n    * \"Wed Jan 01 2014 01:00:00 GMT+0100 (CET)\" -\u003e Wed Jan 01 2014 01:00:00 GMT+0100 (CET)\n* **to object from**:\n  * string\n    * '{\"love\":\"open source\"}' -\u003e { love: \"open source\" }\n* **to array from**:\n  * string    (\"one,two,three\" -\u003e [\"one\", \"two\", \"three\"], '[1,\"two\",{\"three\":true}]' -\u003e [ 1, 'two', { three: true } ])\n  * anything except undefined and array  (23 -\u003e [ 23 ])\n  * To split with a custom string (other than \",\"), use the key **splitWith** (example: { type: \"array\", splitWith: \"|\"\" } will transform \"one|two|three\" to [\"one\", \"two\", \"three\"]).*\n\n### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = {\n    type: 'array',\n    items: { type: 'string' },\n};\n\nvar c = [12.23, -34, true, false, 'true', 'false', [123, 234, 345], { obj: \"yes\" }];\n\nvar r = inspector.sanitize(schema, c);\n/*\nr.data: [ '12.23', '-34', 'true', 'false', 'true', 'false', '123,234,345', '{\"obj\":\"yes\"}' ]\n*/\n```\n\n---------------------------------------\n\n\u003ch3 id=\"s_def\"\u003edef\u003c/h3\u003e\n\n* **type**: any.\n* **usable on**: any.\n\nDefine default value if property does not exist, or if type casting is to fail\nbecause entry type is not valid (cf [type](#s_type)).\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = {\n    type: 'object',\n    properties: {\n        lorem: { type: 'number', def: 10 },\n        ipsum: { type: 'string', def: 'NikitaJS', optional: false },\n        dolor: { type: 'string' },\n    },\n};\n\nvar c = {\n    lorem: [12, 23], // convertion to number is about to fail\n    // (array -\u003e number is not possible)\n    // ipsum is not privided\n    dolor: 'sit amet', // \"dolor\" is already a string\n};\n\nvar r = inspector.sanitize(schema, c);\n/*\nr.data: {\n    lorem: 10,\n    ipsum: 'NikitaJS',\n    dolor: 'sit amet'\n}\n*/\n```\n\n---------------------------------------\n\n\u003ch3 id=\"s_optional\"\u003eoptional\u003c/h3\u003e\n\n* **type**: boolean.\n* **default**: true.\n* **usable on**: any.\n\nProperty is set to `schema.def` if not provided and if optional is `false`.\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = {\n    type: 'object',\n    properties: {\n        lorem: { type: 'number', optional: false, def: 12 },\n        ipsum: { type: 'string', optional: true, def: 23 },\n        dolor: { type: 'string', def: 'NikitaJS', def: 34 }, // (optional: true)\n    },\n};\n\nvar c = {};\n\nvar r = inspector.sanitize(schema, c);\n/*\nr.data: {\n    lorem: 12 // Only lorem is set to 12 because it is not optional.\n}\n*/\n```\n\n---------------------------------------\n\n\u003ch3 id=\"s_rules\"\u003erules\u003c/h3\u003e\n\n* **type**: string, array of string.\n* **usable on**: string.\n* **possible values**:\n  * `upper`: Every character will be changed to uppercase.\n  * `lower`: Every character will be changed to lowercase.\n  * `title`: For each word (/\\S*/g), first letter will be changed to uppercase, and the rest to lowercase.\n  * `capitalize`: Only the first letter of the string will be changed to uppercase, the rest to lowercase.\n  * `ucfirst`: Only the first letter of the string will be changed to uppercase, the rest is not modified.\n  * `trim`: Remove extra spaces.\n\nApply the given rule to a string. If several rules are given (array), then they\nare applied in the same order than in the array.\n\n![sanitization min/max](http://schema-inspector.github.io/schema-inspector/images/doc/sanitization-rules.gif)\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = {\n    type: 'object',\n    properties: {\n        lorem: { type: 'string', rules: 'upper' },\n        ipsum: { type: 'string', rules: ['trim', 'title'] },\n    },\n};\n\nvar c = {\n    lorem: ' tHiS is sParTa! ',\n    ipsum: '   tHiS is sParTa!    ',\n};\n\nvar r = inspector.sanitize(schema, c);\n/*\nr.data: {\n    lorem: ' THIS IS SPARTA! ',\n    ipsum: 'This Is Sparta!' // has been trimed, then titled\n}\n*/\n```\n\n---------------------------------------\n\n\u003ch3 id=\"s_comparators\"\u003emin, max\u003c/h3\u003e\n\n* **type**: string, number.\n* **usable on**: string, number.\n\nDefine minimum and maximum value for a property. If it's less than minimum,\nthen it's set to minimum. If it's greater than maximum, then it's set to\nmaximum.\n\n![sanitization min/max](http://schema-inspector.github.io/schema-inspector/images/doc/sanitization-min-max.gif)\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = {\n    type: 'array',\n    items: { type: 'number', min: 10, max: 20 },\n};\n\nvar c = [5, 10, 15, 20, 25];\n\nvar r = inspector.sanitize(schema, c);\n/*\n r.data: [10, 10, 15, 20, 20]\n c[0] (5) was less than min (10), so it's been set to 10.\n c[4] (25) was greater than max (20), so it's been set to 20.\n*/\n```\n\n---------------------------------------\n\n\u003ch3 id=\"s_length\"\u003eminLength, maxLength\u003c/h3\u003e\n\n* **type**: integer.\n* **usable on**: string.\n\nAdjust string length to the given number.\n\n__TODO:__ We must be able to choose which character we want to fill the string with.\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = {\n    type: 'array',\n    items: { type: 'string', minLength: 8, maxLength: 11 },\n};\n\nvar c = ['short', 'mediumSize', 'tooLongForThisSchema'];\n\nvar r = inspector.sanitize(schema, c);\n/*\n r.data: ['short---', 'mediumSize', 'tooLongForT']\n*/\n```\n\n---------------------------------------\n\n\u003ch3 id=\"s_strict\"\u003estrict\u003c/h3\u003e\n\n* **type**: boolean.\n* **default**: false.\n* **usable on**: any.\n\nOnly key provided in field \"properties\" will exist in object, others will be deleted.\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = {\n    type: 'object',\n    strict: true,\n    properties: {\n        good: { type: 'string' },\n    },\n};\n\nvar c = {\n    good: 'yes',\n    bad: 'nope',\n};\n\nvar r = inspector.sanitize(schema, c);\n/*\nr.data: {\n    good: 'yes'\n}\n*/\n```\n\n---------------------------------------\n\n\u003ch3 id=\"s_exec\"\u003eexec\u003c/h3\u003e\n\n* **type**: function, array of functions.\n* **usable on**: any.\n\nCustom checker =). \"exec\" functions take two three parameter\n(schema, post [, callback]), and must return the new value. To report an\nsanitization, use `this.report([message])`. Very useful to make some custom\nsanitization.\n\n__NB:__ If you don't want to return a differant value, simply return `post`,\ndo not return nothing (if you do so, the new value will be `undefined`).\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = {\n    type: 'array',\n    items: {\n        type: 'string',\n        exec: function (schema, post) {\n            if (typeof post === 'string' \u0026\u0026 !/^nikita$/i.test(post)) {\n                this.report();\n                return '_INVALID_';\n            }\n            return post;\n        },\n    },\n};\n\nvar c = ['Nikita', 'lol', 'NIKITA', 'thisIsGonnaBeSanitized!'];\n\nvar r = inspector.sanitize(schema, c);\n/*\n r.data: [ 'Nikita', '_INVALID_', 'NIKITA', '_INVALID_' ]\n*/\n```\n\n---------------------------------------\n\n\u003ch3 id=\"s_properties\"\u003eproperties\u003c/h3\u003e\n\n* **type**: object.\n* **usable on**: object.\n\nWork the same way as [validation \"properties\"](#v_properties).\n\n---------------------------------------\n\n\u003ch3 id=\"s_items\"\u003eitems\u003c/h3\u003e\n\n* **type**: object, array of object.\n* **usable on**: array.\n\nWork the same way as [validation \"items\"](#v_items).\n\n## Custom fields\n\n\u003ch3 id=\"cf_punctual\"\u003epunctual use\u003c/h3\u003e\n\nWhen you need to use the same function in `exec` field several time, instead of\nsaving the function and declaring `exec` several times, just use custom field.\nFirst you have to provide a hash containing a function for each custom field you\nwant to inject. Then you can call them in your schema with $\"your field name\".\nFor example if you\nprovide a custom field called \"superiorMod\", you can access it with name\n\"$superiorMod\".\n\n\u003c!-- markdownlint-disable-next-line MD001 --\u003e\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = {\n    type: 'object',\n    properties: {\n        lorem: { type: 'number', $divisibleBy: 5 },\n        ipsum: { type: 'number', $divisibleBy: 3 },\n    },\n};\n\nvar custom = {\n    divisibleBy: function (schema, candidate) {\n        var dvb = schema.$divisibleBy;\n        if (candidate % dvb !== 0) {\n            this.report('must be divisible by ' + dvb);\n        }\n    },\n};\n\nvar c = {\n    lorem: 10,\n    ipsum: 8,\n};\ninspector.validate(schema, candidate, custom); // Invalid: \"@.ipsum must be divisible by 3\"\n```\n\n---------------------------------------\n\n\u003ch3 id=\"cf_extension\"\u003eextension\u003c/h3\u003e\n\nSometime you want to use a custom field everywhere in your program, so you may\nextend Schema-Inspector to do so. Just call the method\n_inspector.Validation.extend(customFieldObject)_ or\n_inspector.Sanitization.extend(customFieldObject)_. If you want to reset, simply call\n_inspector.Validation.reset()_ or _inspector.Sanitization.reset()_. You also can remove a\nspecific field by calling _inspector.Validation.remove(field)_ or\n_inspector.Sanitization.remove(field)_.\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar custom = {\n    divisibleBy: function (schema, candidate) {\n        var dvb = schema.$divisibleBy;\n        if (candidate % dvb !== 0) {\n            this.report('must be divisible by ' + dvb);\n        }\n    },\n};\n\nvar schema = {\n    type: 'object',\n    properties: {\n        lorem: { type: 'number', $divisibleBy: 5 },\n        ipsum: { type: 'number', $divisibleBy: 3 },\n    },\n};\n\ninspector.Validation.extend(custom);\n\nvar candidate = {\n    lorem: 10,\n    ipsum: 8,\n};\n\ninspector.validate(schema, candidate);\n/*\n As you can see, no more object than schema and candidate has been provided.\n Therefore we can use `$divisibleBy` everywhere in all schemas, for each\n inspector.validate() call.\n*/\n```\n\n---------------------------------------\n\n\u003ch3 id=\"cf_context\"\u003eContext\u003c/h3\u003e\n\nEvery function you declare as a custom parameter, or with `exec` field will be\ncalled with a context. This context allows you to access properties, like\n`this.report()` function, but also `this.origin`, which is equal to the object\nsent to `inspector.validate()` or `inspector.sanitize()`.\n\n#### Example\n\n```javascript\n// ...\nvar schema = { /* ... */ };\nvar custom = {\n    divisibleBy: function (schema, candidate) {\n        // this.origin === [12, 23, 34, 45]\n        // ...\n    },\n};\nvar candidate = [12, 23, 34, 45];\nvar result = inspector.validate(schema, candidate, custom);\n// ...\n```\n\n## Asynchronous call\n\n### How to\n\nAll of the examples above used synchronous calls (the simplest). But sometimes you\nwant to call validation or sanitization asynchronously, in particular with\n`exec` and custom fields. It's pretty simple: To do so, just send a callback\nas extra parameter. It takes 2 parameters: error and result. Actually\nSchema-Inspector should send back no error as it should not throw any if called\nsynchronously. But if you want to send back and error in your custom function,\ninspection will be interrupted, and you will be able to retrieve it in your\ncallback.\n\nYou also have to declare a callback in your `exec` or custom function to make\nSchema-Inspector call it asynchronously, else it will be call synchronously.\nThat means you may use `exec` synchronous function normally even during\nand asynchronous call.\n\n#### Example\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = { /* ... */ };\nvar candidate = { /* ... */ };\n\ninspector.validate(schema, candidate, function (err, result) {\n    console.log(result.format());\n});\n```\n\n#### Example with custom field\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = { /* ... */ };\nvar candidate = { /* ... */ };\nvar custom = { /* ... */ };\n\ninspector.validate(schema, candidate, custom, function (err, result) {\n    console.log(result.format());\n});\n```\n\nHere is a full example where you may have to use it:\n\n```javascript\nvar inspector = require('schema-inspector');\n\nvar schema = {\n    type: 'object',\n    properties: {\n        lorem: { type: 'number', $divisibleBy: 4 },\n        ipsum: { type: 'number', $divisibleBy: 5 },\n        dolor: { type: 'number', $divisibleBy: 0, optional: true },\n    },\n};\n\nvar custom = {\n    divisibleBy: function (schema, candidate, callback) {\n        // Third parameter is declared:\n        // Schema-Inspector will wait this function to call this `callback` to keep running.\n        var dvb = schema.$divisibleBy;\n        if (typeof dvb !== 'number' || typeof candidate !== 'number') {\n            return callback();\n        }\n        var self = this;\n        process.nextTick(function () {\n            if (dvb === 0) {\n                return callback(\n                    new Error('Schema error: Divisor must not equal 0')\n                );\n            }\n            var r = candidate / dvb;\n            if ((r | 0) !== r) {\n                self.report('should be divisible by ' + dvb);\n            }\n            callback();\n        });\n    },\n};\n\nvar candidate = {\n    lorem: 12,\n    ipsum: 25,\n};\n\ninspector.validate(schema, candidate, custom, function (err, result) {\n    console.log(result.format());\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschema-inspector%2Fschema-inspector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fschema-inspector%2Fschema-inspector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschema-inspector%2Fschema-inspector/lists"}