function Ajv(opts) {
if (!(this instanceof Ajv)) return new Ajv(opts);
opts = this._opts = util.copy(opts) || {};
this._schemas = {};
this._refs = {};
this._fragments = {};
this._formats = formats(opts.format);
var schemaUriFormat = this._schemaUriFormat = this._formats['uri-reference'];
this._schemaUriFormatFunc = function (str) { return schemaUriFormat.test(str); };
this._cache = opts.cache || new Cache;
this._loadingSchemas = {};
this._compilations = [];
this.RULES = rules();
this._getId = chooseGetId(opts);
opts.loopRequired = opts.loopRequired || Infinity;
if (opts.errorDataPath == 'property') opts._errorDataPathProperty = true;
if (opts.serialize === undefined) opts.serialize = stableStringify;
this._metaOpts = getMetaSchemaOptions(this);
if (opts.formats) addInitialFormats(this);
addDraft6MetaSchema(this);
if (typeof opts.meta == 'object') this.addMetaSchema(opts.meta);
addInitialSchemas(this);
if (opts.patternGroups) patternGroups(this);
}n/a
function MissingRefError(baseId, ref, message) {
this.message = message || MissingRefError.message(baseId, ref);
this.missingRef = resolve.url(baseId, ref);
this.missingSchema = resolve.normalizeId(resolve.fullPath(this.missingRef));
}n/a
function ValidationError(errors) {
this.message = 'validation failed';
this.errors = errors;
this.ajv = this.validation = true;
}...
You can define custom formats and keywords that perform validation asyncronously by accessing database or some service. You should
add `async: true` in the keyword or format defnition (see [addFormat](#api-addformat), [addKeyword](#api-addkeyword) and [Defining
custom keywords](#defining-custom-keywords)).
If your schema uses asynchronous formats/keywords or refers to some schema that contains them it should have `"$async":
true` keyword so that Ajv can compile it correctly. If asynchronous format/keyword or reference to asynchronous schema is used in
the schema without `$async` keyword Ajv will throw an exception during schema compilation.
__Please note__: all asynchronous subschemas that are referenced from the current or other schemas should have `"$async"
;: true` keyword as well, otherwise the schema compilation will fail.
Validation function for an asynchronous custom format/keyword should return a promise that resolves with `true` or `false` (or rejects
with `new Ajv.ValidationError(errors)` if you want to return custom errors from the
keyword function). Ajv compiles asynchronous schemas to either [es7 async functions](http://tc39.github.io/ecmascript-asyncawait
/) that can optionally be transpiled with [nodent](https://github.com/MatAtBread/nodent) or with [regenerator](https://github.com
/facebook/regenerator) or to [generator functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/
function*) that can be optionally transpiled with regenerator as well. You can also supply any other transpiler as a function. See
[Options](#options).
The compiled validation function has `$async: true` property (if the schema is asynchronous), so you can differentiate these functions
if you are using both syncronous and asynchronous schemas.
If you are using generators, the compiled validation function can be either wrapped with [co](https://github.com/tj/co) (default
) or returned as generator function, that can be used directly, e.g. in [koa](http://koajs.com/) 1.0. `co` is a small library, it
is included in Ajv (both as npm dependency and in the browser bundle).
Async functions are currently supported in Chrome 55, Firefox 52, Node 7 (with --harmony-async-await) and MS Edge 13 (with flag).
...function Cache() {
this._cache = {};
}n/a
function MissingRefError(baseId, ref, message) {
this.message = message || MissingRefError.message(baseId, ref);
this.missingRef = resolve.url(baseId, ref);
this.missingSchema = resolve.normalizeId(resolve.fullPath(this.missingRef));
}n/a
message = function (baseId, ref) {
return 'can\'t resolve reference ' + ref + ' from id ' + baseId;
}n/a
function MissingRefError(baseId, ref, message) {
this.message = message || MissingRefError.message(baseId, ref);
this.missingRef = resolve.url(baseId, ref);
this.missingSchema = resolve.normalizeId(resolve.fullPath(this.missingRef));
}n/a
function ValidationError(errors) {
this.message = 'validation failed';
this.errors = errors;
this.ajv = this.validation = true;
}...
You can define custom formats and keywords that perform validation asyncronously by accessing database or some service. You should
add `async: true` in the keyword or format defnition (see [addFormat](#api-addformat), [addKeyword](#api-addkeyword) and [Defining
custom keywords](#defining-custom-keywords)).
If your schema uses asynchronous formats/keywords or refers to some schema that contains them it should have `"$async":
true` keyword so that Ajv can compile it correctly. If asynchronous format/keyword or reference to asynchronous schema is used in
the schema without `$async` keyword Ajv will throw an exception during schema compilation.
__Please note__: all asynchronous subschemas that are referenced from the current or other schemas should have `"$async"
;: true` keyword as well, otherwise the schema compilation will fail.
Validation function for an asynchronous custom format/keyword should return a promise that resolves with `true` or `false` (or rejects
with `new Ajv.ValidationError(errors)` if you want to return custom errors from the
keyword function). Ajv compiles asynchronous schemas to either [es7 async functions](http://tc39.github.io/ecmascript-asyncawait
/) that can optionally be transpiled with [nodent](https://github.com/MatAtBread/nodent) or with [regenerator](https://github.com
/facebook/regenerator) or to [generator functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/
function*) that can be optionally transpiled with regenerator as well. You can also supply any other transpiler as a function. See
[Options](#options).
The compiled validation function has `$async: true` property (if the schema is asynchronous), so you can differentiate these functions
if you are using both syncronous and asynchronous schemas.
If you are using generators, the compiled validation function can be either wrapped with [co](https://github.com/tj/co) (default
) or returned as generator function, that can be used directly, e.g. in [koa](http://koajs.com/) 1.0. `co` is a small library, it
is included in Ajv (both as npm dependency and in the browser bundle).
Async functions are currently supported in Chrome 55, Firefox 52, Node 7 (with --harmony-async-await) and MS Edge 13 (with flag).
...function ValidationError(errors) {
this.message = 'validation failed';
this.errors = errors;
this.ajv = this.validation = true;
}n/a
function Cache() {
this._cache = {};
}n/a
function Cache_clear() {
this._cache = {};
}n/a
function Cache_del(key) {
delete this._cache[key];
}n/a
function Cache_get(key) {
return this._cache[key];
}n/a
function Cache_put(key, value) {
this._cache[key] = value;
}n/a
function addKeyword(keyword, definition) {
/* jshint validthis: true */
/* eslint no-shadow: 0 */
var RULES = this.RULES;
if (RULES.keywords[keyword])
throw new Error('Keyword ' + keyword + ' is already defined');
if (!IDENTIFIER.test(keyword))
throw new Error('Keyword ' + keyword + ' is not a valid identifier');
if (definition) {
if (definition.macro && definition.valid !== undefined)
throw new Error('"valid" option cannot be used with macro keywords');
var dataType = definition.type;
if (Array.isArray(dataType)) {
var i, len = dataType.length;
for (i=0; i<len; i++) checkDataType(dataType[i]);
for (i=0; i<len; i++) _addRule(keyword, dataType[i], definition);
} else {
if (dataType) checkDataType(dataType);
_addRule(keyword, dataType, definition);
}
var $data = definition.$data === true && this._opts.$data;
if ($data && !definition.validate)
throw new Error('$data support: "validate" function is not defined');
var metaSchema = definition.metaSchema;
if (metaSchema) {
if ($data) {
metaSchema = {
anyOf: [
metaSchema,
{ '$ref': 'https://raw.githubusercontent.com/epoberezkin/ajv/master/lib/refs/$data.json#' }
]
};
}
definition.validateSchema = this.compile(metaSchema, true);
}
}
RULES.keywords[keyword] = RULES.all[keyword] = true;
function _addRule(keyword, dataType, definition) {
var ruleGroup;
for (var i=0; i<RULES.length; i++) {
var rg = RULES[i];
if (rg.type == dataType) {
ruleGroup = rg;
break;
}
}
if (!ruleGroup) {
ruleGroup = { type: dataType, rules: [] };
RULES.push(ruleGroup);
}
var rule = {
keyword: keyword,
definition: definition,
custom: true,
code: customRuleCode,
implements: definition.implements
};
ruleGroup.rules.push(rule);
RULES.custom[keyword] = rule;
}
function checkDataType(dataType) {
if (!RULES.types[dataType]) throw new Error('Unknown type ' + dataType);
}
}n/a
function getKeyword(keyword) {
/* jshint validthis: true */
var rule = this.RULES.custom[keyword];
return rule ? rule.definition : this.RULES.keywords[keyword] || false;
}n/a
function removeKeyword(keyword) {
/* jshint validthis: true */
var RULES = this.RULES;
delete RULES.keywords[keyword];
delete RULES.all[keyword];
delete RULES.custom[keyword];
for (var i=0; i<RULES.length; i++) {
var rules = RULES[i].rules;
for (var j=0; j<rules.length; j++) {
if (rules[j].keyword == keyword) {
rules.splice(j, 1);
break;
}
}
}
}n/a