ajv-keywords
Custom JSON-Schema keywords for ajv validator
Contents
Install
npm install ajv-keywords
Usage
To add all available keywords:
var Ajv = require('ajv');
var ajv = new Ajv;
require('ajv-keywords')(ajv);
ajv.validate({ instanceof: 'RegExp' }, /.*/);
ajv.validate({ instanceof: 'RegExp' }, '.*');
To add a single keyword:
require('ajv-keywords')(ajv, 'instanceof');
To add multiple keywords:
require('ajv-keywords')(ajv, ['typeof', 'instanceof']);
To add a single keyword in browser (to avoid adding unused code):
require('ajv-keywords/keywords/instanceof')(ajv);
Keywords
typeof
Based on JavaScript typeof
operation.
The value of the keyword should be a string ("undefined"
, "string"
, "number"
, "object"
, "function"
, "boolean"
or "symbol"
) or array of strings.
To pass validation the result of typeof
operation on the value should be equal to the string (or one of the strings in the array).
ajv.validate({ typeof: 'undefined' }, undefined); // true
ajv.validate({ typeof: 'undefined' }, null); // false
ajv.validate({ typeof: ['undefined', 'object'] }, null); // true
instanceof
Based on JavaScript typeof
operation.
The value of the keyword should be a string ("Object"
, "Array"
, "Function"
, "Number"
, "String"
, "Date"
, "RegExp"
or "Buffer"
) or array of strings.
To pass validation the result of data instanceof ...
operation on the value should be true:
ajv.validate({ instanceof: 'Array' }, []); // true
ajv.validate({ instanceof: 'Array' }, {}); // false
ajv.validate({ instanceof: ['Array', 'Function'] }, funciton(){}); // true
You can add your own constructor function to be recognised by this keyword:
function MyClass() {}
var instanceofDefinition = require('ajv-keywords').get('instanceof').definition;
instanceofDefinition.CONSTRUCTORS.MyClass = MyClass;
ajv.validate({ instanceof: 'MyClass' }, new MyClass);
range
and exclusiveRange
Syntax sugar for the combination of minimum and maximum keywords, also fails schema compilation if there are no numbers in the range.
The value of this keyword must be the array consisting of two numbers, the second must be greater or equal than the first one.
If the validated value is not a number the validation passes, otherwise to pas validation the value should be greater (or equal) than the first number and smaller (or equal) than the second number in the array. If exclusiveRange
keyword is present in the same schema and its value is true, the validated value must not be equal to the range boundaries.
var schema = { range: [1, 3] };
ajv.validate(schema, 1);
ajv.validate(schema, 2);
ajv.validate(schema, 3);
ajv.validate(schema, 0.99);
ajv.validate(schema, 3.01);
var schema = { range: [1, 3], exclusiveRange: true };
ajv.validate(schema, 1.01);
ajv.validate(schema, 2);
ajv.validate(schema, 2.99);
ajv.validate(schema, 1);
ajv.validate(schema, 3);
propertyNames
This keyword allows to define the schema for the property names of the object. The value of this keyword should be a valid JSON schema (v5 schemas are supported with Ajv option {v5: true}
).
var schema = {
type: 'object'
propertyNames: {
anyOf: [
{ format: ipv4 },
{ format: hostname }
]
}
};
var validData = {
'192.128.0.1': {},
'test.example.com': {}
};
var invalidData = {
'1.2.3': {}
};
ajv.validate(schema, validData);
ajv.validate(schema, invalidData);
regexp
This keyword allows to use regular expressions with flags in schemas (the standard pattern
keyword does not support flags). The value of this keyword can be either a string (the result of regexp.toString()
) or an object with the properties pattern
and flags
(the same strings that should be passed to RegExp constructor).
var schema = {
type: 'object',
properties: {
foo: { regexp: '/foo/i' },
bar: { regexp: { pattern: 'bar', flags: 'i' } }
}
};
var validData = {
foo: 'Food',
bar: 'Barmen'
};
var invalidData = {
foo: 'fog',
bar: 'bad'
};
dynamicDefaults
This keyword allows to assign dynamic defaults to properties, such as timestamps, unique IDs etc.
This keyword only works if useDefaults
options is used and not inside anyOf
keywrods etc., in the same way as default keyword treated by Ajv.
The keyword should be added on the object level. Its value should be an object with each property corresponding to a property name, in the same way as in standard properties
keyword. The value of each property can be:
- an identifier of default function (a string)
- an object with properties
func
(an identifier) and args
(an object with parameters that will be passed to this function during schema compilation - see examples).
The properties used in dynamicDefaults
should not be added to required
keyword (or validation will fail), because unlike default
this keyword is processed after validation.
There are several predefined dynamic default functions:
"timestamp"
- current timestamp in milliseconds"datetime"' - current date and time as string (ISO, valid according to
date-time` format)"date"' - current date as string (ISO, valid according to
date` format)"time"
- current time as string (ISO, valid according to time
format)"random"
- pseudo-random number in [0, 1) interval"randomint"
- pseudo-random integer number. If string is used as a property value, the function will randomly return 0 or 1. If object {func: 'randomint', max: N}
is used then the default will be an integer number in [0, N) interval."seq"
- sequential integer number starting from 0. If string is used as a property value, the default sequence will be used. If object {func: 'seq', name: 'foo'}
is used then the sequence with name "foo"
will be used. Sequences are global, even if different ajv instances are used.
var schema = {
type: 'object',
dynamicDefaults: {
ts: 'datetime',
r: { func: 'randomint', max: 100 },
id: { func: 'seq', name: 'id' }
},
properties: {
ts: {
type: 'string',
format: 'datetime'
},
r: {
type: 'integer',
minimum: 0,
maximum: 100,
exclusiveMaximum: true
},
id: {
type: 'integer',
minimum: 0
}
}
};
var data = {};
ajv.validate(data);
data;
var data1 = {};
ajv.validate(data1);
data1;
ajv.validate(data1);
data1;
You can add your own dynamic default function to be recognised by this keyword:
var uuid = require('uuid');
function uuidV4() { return uuid.v4(); }
var definition = require('ajv-keywords').get('dynamicDefaults').definition;
definition.DEFAULTS.uuid = uuidV4;
var schema = {
dynamicDefaults: { id: 'uuid' },
properties: { id: { type: 'string', format: 'uuid' } }
};
var data = {};
ajv.validate(schema, data);
data;
var data1 = {};
ajv.validate(schema, data1);
data1;
You also can define dynamic default that accepts parameters, e.g. version of uuid:
var uuid = require('uuid');
function getUuid(args) {
var version = 'v' + (arvs && args.v || 4);
return function() {
return uuid[version]();
};
}
var definition = require('ajv-keywords').get('dynamicDefaults').definition;
definition.DEFAULTS.uuid = getUuid;
var schema = {
dynamicDefaults: {
id1: 'uuid',
id2: { func: 'uuid', v: 4 },
id3: { func: 'uuid', v: 1 }
}
};
License
MIT