ajv-keywords
Advanced tools
Comparing version 3.5.2 to 4.0.0-beta.0
@@ -1,7 +0,7 @@ | ||
declare module 'ajv-keywords' { | ||
import { Ajv } from 'ajv'; | ||
declare module "ajv-keywords" { | ||
import {Ajv} from "ajv" | ||
function keywords(ajv: Ajv, include?: string | string[]): Ajv; | ||
function keywords(ajv: Ajv, include?: string | string[]): Ajv | ||
export = keywords; | ||
export = keywords | ||
} |
{ | ||
"name": "ajv-keywords", | ||
"version": "3.5.2", | ||
"version": "4.0.0-beta.0", | ||
"description": "Custom JSON-Schema keywords for Ajv validator", | ||
"main": "index.js", | ||
"main": "dist/index.js", | ||
"typings": "ajv-keywords.d.ts", | ||
"scripts": { | ||
"build": "node node_modules/ajv/scripts/compile-dots.js node_modules/ajv/lib keywords", | ||
"build": "rm -rf dist && tsc", | ||
"prepublish": "npm run build", | ||
"prettier:write": "prettier --write \"./**/*.{md,json,yaml,js,ts}\"", | ||
"prettier:check": "prettier --list-different \"./**/*.{md,json,yaml,js,ts}\"", | ||
"test": "npm run build && npm run eslint && npm run test-cov", | ||
"eslint": "eslint index.js keywords/*.js spec", | ||
"test-spec": "mocha spec/*.spec.js -R spec", | ||
"test-cov": "istanbul cover -x 'spec/**' node_modules/mocha/bin/_mocha -- spec/*.spec.js -R spec" | ||
"eslint": "eslint \"src/**/*.*s\" \"spec/**/*.*s\" --ignore-pattern dotjs", | ||
"test-spec": "jest spec/*.ts", | ||
"test-cov": "jest spec/*.ts --coverage" | ||
}, | ||
@@ -25,5 +27,5 @@ "repository": { | ||
"files": [ | ||
"index.js", | ||
"ajv-keywords.d.ts", | ||
"keywords" | ||
"src", | ||
"dist", | ||
"ajv-keywords.d.ts" | ||
], | ||
@@ -37,19 +39,40 @@ "author": "Evgeny Poberezkin", | ||
"peerDependencies": { | ||
"ajv": "^6.9.1" | ||
"ajv": "^7.0.0-beta.2" | ||
}, | ||
"devDependencies": { | ||
"ajv": "^6.9.1", | ||
"ajv-pack": "^0.3.0", | ||
"@ajv-validator/config": "^0.2.3", | ||
"@types/jest": "^26.0.14", | ||
"@types/node": "^14.11.10", | ||
"@types/uuid": "^8.3.0", | ||
"@typescript-eslint/eslint-plugin": "^4.4.1", | ||
"@typescript-eslint/parser": "^4.4.1", | ||
"ajv": "^7.0.0-beta.2", | ||
"ajv-formats": "^0.3.4", | ||
"chai": "^4.2.0", | ||
"coveralls": "^3.0.2", | ||
"dot": "^1.1.1", | ||
"eslint": "^7.2.0", | ||
"eslint-config-prettier": "^6.13.0", | ||
"glob": "^7.1.3", | ||
"istanbul": "^0.4.3", | ||
"husky": "^4.3.0", | ||
"jest": "^26.5.3", | ||
"js-beautify": "^1.8.9", | ||
"json-schema-test": "^2.0.0", | ||
"mocha": "^8.0.1", | ||
"pre-commit": "^1.1.3", | ||
"lint-staged": "^10.4.2", | ||
"prettier": "^2.1.2", | ||
"ts-jest": "^26.4.1", | ||
"typescript": "^4.0.3", | ||
"uuid": "^8.1.0" | ||
}, | ||
"prettier": "@ajv-validator/config/prettierrc.json", | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "lint-staged && npm test" | ||
} | ||
}, | ||
"lint-staged": { | ||
"*.{md,json,yaml,js,ts}": "prettier --write" | ||
}, | ||
"dependencies": { | ||
"@types/chai": "^4.2.14" | ||
} | ||
} |
666
README.md
@@ -7,2 +7,3 @@ # ajv-keywords | ||
[![npm](https://img.shields.io/npm/v/ajv-keywords.svg)](https://www.npmjs.com/package/ajv-keywords) | ||
[![npm (beta)](https://img.shields.io/npm/v/ajv-keywords/beta)](https://www.npmjs.com/package/ajv-keywords/v/4.0.0-beta.0) | ||
[![npm downloads](https://img.shields.io/npm/dm/ajv-keywords.svg)](https://www.npmjs.com/package/ajv-keywords) | ||
@@ -13,2 +14,3 @@ [![Coverage Status](https://coveralls.io/repos/github/ajv-validator/ajv-keywords/badge.svg?branch=master)](https://coveralls.io/github/ajv-validator/ajv-keywords?branch=master) | ||
**Please note**: [ajv-keywords v4.0.0-beta](https://github.com/ajv-validator/ajv-keywords/releases/tag/v4.0.0-beta.0) should be used with [ajv v7 (beta)](https://github.com/ajv-validator/ajv/tree/v7-beta) | ||
@@ -27,3 +29,2 @@ ## Contents | ||
- [regexp](#regexp) | ||
- [formatMaximum / formatMinimum and formatExclusiveMaximum / formatExclusiveMinimum](#formatmaximum--formatminimum-and-formatexclusivemaximum--formatexclusiveminimum) | ||
- [transform](#transform)<sup>\*</sup> | ||
@@ -40,7 +41,5 @@ - [Keywords for arrays](#keywords-for-arrays) | ||
- [deepRequired](#deeprequired) | ||
- [Compound keywords](#compound-keywords) | ||
- [switch](#switch) (deprecated) | ||
- [select/selectCases/selectDefault](#selectselectcasesselectdefault) (BETA) | ||
- [dynamicDefaults](#dynamicdefaults)<sup>\*</sup> | ||
- [Keywords for all types](#keywords-for-all-types) | ||
- [dynamicDefaults](#dynamicdefaults)<sup>\*</sup> | ||
- [select/selectCases/selectDefault](#selectselectcasesselectdefault) | ||
- [Security contact](#security-contact) | ||
@@ -52,3 +51,2 @@ - [Open-source software support](#open-source-software-support) | ||
## Install | ||
@@ -60,3 +58,2 @@ | ||
## Usage | ||
@@ -67,8 +64,8 @@ | ||
```javascript | ||
var Ajv = require('ajv'); | ||
var ajv = new Ajv; | ||
require('ajv-keywords')(ajv); | ||
const Ajv = require("ajv") | ||
const ajv = new Ajv() | ||
require("ajv-keywords")(ajv) | ||
ajv.validate({ instanceof: 'RegExp' }, /.*/); // true | ||
ajv.validate({ instanceof: 'RegExp' }, '.*'); // false | ||
ajv.validate({instanceof: "RegExp"}, /.*/) // true | ||
ajv.validate({instanceof: "RegExp"}, ".*") // false | ||
``` | ||
@@ -79,3 +76,3 @@ | ||
```javascript | ||
require('ajv-keywords')(ajv, 'instanceof'); | ||
require("ajv-keywords")(ajv, "instanceof") | ||
``` | ||
@@ -86,12 +83,32 @@ | ||
```javascript | ||
require('ajv-keywords')(ajv, ['typeof', 'instanceof']); | ||
require("ajv-keywords")(ajv, ["typeof", "instanceof"]) | ||
``` | ||
To add a single keyword in browser (to avoid adding unused code): | ||
To add a single keyword directly (to avoid adding unused code): | ||
```javascript | ||
require('ajv-keywords/keywords/instanceof')(ajv); | ||
require("ajv-keywords/dist/keywords/select")(ajv, opts) | ||
``` | ||
To add all keywords via Ajv options: | ||
```javascript | ||
const ajv = new Ajv({keywords: require("ajv-keywords/dist/definitions")(opts)}) | ||
``` | ||
To add one or several keywords via options: | ||
```javascript | ||
const ajv = new Ajv({ | ||
keywords: [ | ||
require("ajv-keywords/dist/definitions/typeof")(), | ||
require("ajv-keywords/dist/definitions/instanceof")(), | ||
// select exports an array of 3 definitions - see "select" in docs | ||
...require("ajv-keywords/dist/definitions/select")(opts), | ||
], | ||
}) | ||
``` | ||
`opts` is an object with a property `defaultMeta` - URI of meta-schema to use for keywords that use subschemas (`select` and `deepProperties`). | ||
## Keywords | ||
@@ -105,13 +122,12 @@ | ||
The value of the keyword should be a string (`"undefined"`, `"string"`, `"number"`, `"object"`, `"function"`, `"boolean"` or `"symbol"`) or array of strings. | ||
The value of the keyword should be a string (`"undefined"`, `"string"`, `"number"`, `"object"`, `"function"`, `"boolean"` or `"symbol"`) or an 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). | ||
```javascript | ||
ajv.validate({typeof: "undefined"}, undefined) // true | ||
ajv.validate({typeof: "undefined"}, null) // false | ||
ajv.validate({typeof: ["undefined", "object"]}, null) // true | ||
``` | ||
ajv.validate({ typeof: 'undefined' }, undefined); // true | ||
ajv.validate({ typeof: 'undefined' }, null); // false | ||
ajv.validate({ typeof: ['undefined', 'object'] }, null); // true | ||
``` | ||
#### `instanceof` | ||
@@ -121,11 +137,11 @@ | ||
The value of the keyword should be a string (`"Object"`, `"Array"`, `"Function"`, `"Number"`, `"String"`, `"Date"`, `"RegExp"`, `"Promise"` or `"Buffer"`) or array of strings. | ||
The value of the keyword should be a string (`"Object"`, `"Array"`, `"Function"`, `"Number"`, `"String"`, `"Date"`, `"RegExp"` or `"Promise"`) or an array of strings. | ||
To pass validation the result of `data instanceof ...` operation on the value should be true: | ||
```javascript | ||
ajv.validate({instanceof: "Array"}, []) // true | ||
ajv.validate({instanceof: "Array"}, {}) // false | ||
ajv.validate({instanceof: ["Array", "Function"]}, function () {}) // true | ||
``` | ||
ajv.validate({ instanceof: 'Array' }, []); // true | ||
ajv.validate({ instanceof: 'Array' }, {}); // false | ||
ajv.validate({ instanceof: ['Array', 'Function'] }, function(){}); // true | ||
``` | ||
@@ -135,11 +151,8 @@ You can add your own constructor function to be recognised by this keyword: | ||
```javascript | ||
function MyClass() {} | ||
var instanceofDefinition = require('ajv-keywords').get('instanceof').definition; | ||
// or require('ajv-keywords/keywords/instanceof').definition; | ||
instanceofDefinition.CONSTRUCTORS.MyClass = MyClass; | ||
ajv.validate({ instanceof: 'MyClass' }, new MyClass); // true | ||
class MyClass {} | ||
const instanceofDef = require("ajv-keywords/dist/definitions/instanceof") | ||
instanceofDef.CONSTRUCTORS.MyClass = MyClass | ||
ajv.validate({instanceof: "MyClass"}, new MyClass()) // true | ||
``` | ||
### Keywords for numbers | ||
@@ -149,25 +162,24 @@ | ||
Syntax sugar for the combination of minimum and maximum keywords, also fails schema compilation if there are no numbers in the range. | ||
Syntax sugar for the combination of minimum and maximum keywords (or exclusiveMinimum and exclusiveMaximum), 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. | ||
The value of these keywords must be an 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 pass 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. | ||
If the validated value is not a number the validation passes, otherwise to pass validation the value should be greater (or equal) than the first number and smaller (or equal) than the second number in the array. | ||
```javascript | ||
var schema = { range: [1, 3] }; | ||
ajv.validate(schema, 1); // true | ||
ajv.validate(schema, 2); // true | ||
ajv.validate(schema, 3); // true | ||
ajv.validate(schema, 0.99); // false | ||
ajv.validate(schema, 3.01); // false | ||
const schema = {type: "number", range: [1, 3]} | ||
ajv.validate(schema, 1) // true | ||
ajv.validate(schema, 2) // true | ||
ajv.validate(schema, 3) // true | ||
ajv.validate(schema, 0.99) // false | ||
ajv.validate(schema, 3.01) // false | ||
var schema = { range: [1, 3], exclusiveRange: true }; | ||
ajv.validate(schema, 1.01); // true | ||
ajv.validate(schema, 2); // true | ||
ajv.validate(schema, 2.99); // true | ||
ajv.validate(schema, 1); // false | ||
ajv.validate(schema, 3); // false | ||
const schema = {type: "number", exclusiveRange: [1, 3]} | ||
ajv.validate(schema, 1.01) // true | ||
ajv.validate(schema, 2) // true | ||
ajv.validate(schema, 2.99) // true | ||
ajv.validate(schema, 1) // false | ||
ajv.validate(schema, 3) // false | ||
``` | ||
### Keywords for strings | ||
@@ -177,3 +189,3 @@ | ||
This keyword allows to use regular expressions with flags in schemas (the standard `pattern` keyword does not support flags). | ||
This keyword allows to use regular expressions with flags in schemas, and also without `"u"` flag when needed (the standard `pattern` keyword does not support flags and implies the presence of `"u"` flag). | ||
@@ -185,109 +197,79 @@ This keyword applies only to strings. If the data is not a string, the validation succeeds. | ||
```javascript | ||
var schema = { | ||
type: 'object', | ||
const schema = { | ||
type: "object", | ||
properties: { | ||
foo: { regexp: '/foo/i' }, | ||
bar: { regexp: { pattern: 'bar', flags: 'i' } } | ||
} | ||
}; | ||
foo: {type: "string", regexp: "/foo/i"}, | ||
bar: {type: "string", regexp: {pattern: "bar", flags: "i"}}, | ||
}, | ||
} | ||
var validData = { | ||
foo: 'Food', | ||
bar: 'Barmen' | ||
}; | ||
const validData = { | ||
foo: "Food", | ||
bar: "Barmen", | ||
} | ||
var invalidData = { | ||
foo: 'fog', | ||
bar: 'bad' | ||
}; | ||
``` | ||
#### `formatMaximum` / `formatMinimum` and `formatExclusiveMaximum` / `formatExclusiveMinimum` | ||
These keywords allow to define minimum/maximum constraints when the format keyword defines ordering. | ||
These keywords apply only to strings. If the data is not a string, the validation succeeds. | ||
The value of keyword `formatMaximum` (`formatMinimum`) should be a string. This value is the maximum (minimum) allowed value for the data to be valid as determined by `format` keyword. If `format` is not present schema compilation will throw exception. | ||
When this keyword is added, it defines comparison rules for formats `"date"`, `"time"` and `"date-time"`. Custom formats also can have comparison rules. See [addFormat](https://github.com/epoberezkin/ajv#api-addformat) method. | ||
The value of keyword `formatExclusiveMaximum` (`formatExclusiveMinimum`) should be a boolean value. These keyword cannot be used without `formatMaximum` (`formatMinimum`). If this keyword value is equal to `true`, the data to be valid should not be equal to the value in `formatMaximum` (`formatMinimum`) keyword. | ||
```javascript | ||
require('ajv-keywords')(ajv, ['formatMinimum', 'formatMaximum']); | ||
var schema = { | ||
format: 'date', | ||
formatMinimum: '2016-02-06', | ||
formatMaximum: '2016-12-27', | ||
formatExclusiveMaximum: true | ||
const invalidData = { | ||
foo: "fog", | ||
bar: "bad", | ||
} | ||
var validDataList = ['2016-02-06', '2016-12-26', 1]; | ||
var invalidDataList = ['2016-02-05', '2016-12-27', 'abc']; | ||
``` | ||
#### `transform` | ||
This keyword allows a string to be modified before validation. | ||
This keyword allows a string to be modified during validation. | ||
These keywords apply only to strings. If the data is not a string, the transform is skipped. | ||
This keyword applies only to strings. If the data is not a string, the `transform` keyword is ignored. | ||
There are limitation due to how ajv is written: | ||
- a stand alone string cannot be transformed. ie `data = 'a'; ajv.validate(schema, data);` | ||
- currently cannot work with `ajv-pack` | ||
A standalone string cannot be modified, i.e. `data = 'a'; ajv.validate(schema, data);`, because strings are passed by value | ||
**Supported options:** | ||
**Supported transformations:** | ||
- `trim`: remove whitespace from start and end | ||
- `trimLeft`: remove whitespace from start | ||
- `trimRight`: remove whitespace from end | ||
- `toLowerCase`: case string to all lower case | ||
- `toUpperCase`: case string to all upper case | ||
- `toEnumCase`: case string to match case in schema | ||
- `trimStart`/`trimLeft`: remove whitespace from start | ||
- `trimEnd`/`trimRight`: remove whitespace from end | ||
- `toLowerCase`: convert to lower case | ||
- `toUpperCase`: convert to upper case | ||
- `toEnumCase`: change string case to be equal to one of `enum` values in the schema | ||
Options are applied in the order they are listed. | ||
Transformations are applied in the order they are listed. | ||
Note: `toEnumCase` requires that all allowed values are unique when case insensitive. | ||
**Example: multiple options** | ||
**Example: multiple transformations** | ||
```javascript | ||
require('ajv-keywords')(ajv, ['transform']); | ||
require("ajv-keywords")(ajv, "transform") | ||
var schema = { | ||
type: 'array', | ||
const schema = { | ||
type: "array", | ||
items: { | ||
type:'string', | ||
transform:['trim','toLowerCase'] | ||
} | ||
}; | ||
type: "string", | ||
transform: ["trim", "toLowerCase"], | ||
}, | ||
} | ||
var data = [' MixCase ']; | ||
ajv.validate(schema, data); | ||
console.log(data); // ['mixcase'] | ||
const data = [" MixCase "] | ||
ajv.validate(schema, data) | ||
console.log(data) // ['mixcase'] | ||
``` | ||
**Example: `enumcase`** | ||
```javascript | ||
require('ajv-keywords')(ajv, ['transform']); | ||
require("ajv-keywords")(ajv, ["transform"]) | ||
var schema = { | ||
type: 'array', | ||
const schema = { | ||
type: "array", | ||
items: { | ||
type:'string', | ||
transform:['trim','toEnumCase'], | ||
enum:['pH'] | ||
} | ||
}; | ||
type: "string", | ||
transform: ["trim", "toEnumCase"], | ||
enum: ["pH"], | ||
}, | ||
} | ||
var data = ['ph',' Ph','PH','pH ']; | ||
ajv.validate(schema, data); | ||
console.log(data); // ['pH','pH','pH','pH'] | ||
const data = ["ph", " Ph", "PH", "pH "] | ||
ajv.validate(schema, data) | ||
console.log(data) // ['pH','pH','pH','pH'] | ||
``` | ||
### Keywords for arrays | ||
@@ -304,21 +286,20 @@ | ||
```javascript | ||
var schema = { uniqueItemProperties: [ "id", "name" ] }; | ||
const schema = { | ||
type: "array", | ||
uniqueItemProperties: ["id", "name"], | ||
} | ||
var validData = [ | ||
{ id: 1 }, | ||
{ id: 2 }, | ||
{ id: 3 } | ||
]; | ||
const validData = [{id: 1}, {id: 2}, {id: 3}] | ||
var invalidData1 = [ | ||
{ id: 1 }, | ||
{ id: 1 }, // duplicate "id" | ||
{ id: 3 } | ||
]; | ||
const invalidData1 = [ | ||
{id: 1}, | ||
{id: 1}, // duplicate "id" | ||
{id: 3}, | ||
] | ||
var invalidData2 = [ | ||
{ id: 1, name: "taco" }, | ||
{ id: 2, name: "taco" }, // duplicate "name" | ||
{ id: 3, name: "salsa" } | ||
]; | ||
const invalidData2 = [ | ||
{id: 1, name: "taco"}, | ||
{id: 2, name: "taco"}, // duplicate "name" | ||
{id: 3, name: "salsa"}, | ||
] | ||
``` | ||
@@ -328,3 +309,2 @@ | ||
### Keywords for objects | ||
@@ -347,3 +327,4 @@ | ||
```javascript | ||
var schema = { | ||
const schema = { | ||
type: "object", | ||
properties: { | ||
@@ -356,9 +337,8 @@ foo: {type: 'number'}, | ||
var validData = { foo: 1, bar: 2 }; | ||
var alsoValidData = { foo: 1, bar: 2, baz: 3 }; | ||
const validData = { foo: 1, bar: 2 }; | ||
const alsoValidData = { foo: 1, bar: 2, baz: 3 }; | ||
var invalidDataList = [ {}, { foo: 1 }, { bar: 2 } ]; | ||
const invalidDataList = [ {}, { foo: 1 }, { bar: 2 } ]; | ||
``` | ||
#### `anyRequired` | ||
@@ -373,13 +353,13 @@ | ||
```javascript | ||
var schema = { | ||
anyRequired: ['foo', 'bar'] | ||
}; | ||
const schema = { | ||
type: "object", | ||
anyRequired: ["foo", "bar"], | ||
} | ||
var validData = { foo: 1 }; | ||
var alsoValidData = { foo: 1, bar: 2 }; | ||
const validData = {foo: 1} | ||
const alsoValidData = {foo: 1, bar: 2} | ||
var invalidDataList = [ {}, { baz: 3 } ]; | ||
const invalidDataList = [{}, {baz: 3}] | ||
``` | ||
#### `oneRequired` | ||
@@ -394,13 +374,13 @@ | ||
```javascript | ||
var schema = { | ||
oneRequired: ['foo', 'bar'] | ||
}; | ||
const schema = { | ||
type: "object", | ||
oneRequired: ["foo", "bar"], | ||
} | ||
var validData = { foo: 1 }; | ||
var alsoValidData = { bar: 2, baz: 3 }; | ||
const validData = {foo: 1} | ||
const alsoValidData = {bar: 2, baz: 3} | ||
var invalidDataList = [ {}, { baz: 3 }, { foo: 1, bar: 2 } ]; | ||
const invalidDataList = [{}, {baz: 3}, {foo: 1, bar: 2}] | ||
``` | ||
#### `patternRequired` | ||
@@ -417,11 +397,13 @@ | ||
```javascript | ||
var schema = { patternRequired: [ 'f.*o', 'b.*r' ] }; | ||
const schema = { | ||
type: "object", | ||
patternRequired: ["f.*o", "b.*r"], | ||
} | ||
var validData = { foo: 1, bar: 2 }; | ||
var alsoValidData = { foobar: 3 }; | ||
const validData = {foo: 1, bar: 2} | ||
const alsoValidData = {foobar: 3} | ||
var invalidDataList = [ {}, { foo: 1 }, { bar: 2 } ]; | ||
const invalidDataList = [{}, {foo: 1}, {bar: 2}] | ||
``` | ||
#### `prohibited` | ||
@@ -435,18 +417,16 @@ | ||
``` | ||
var schema = { prohibited: ['foo', 'bar']}; | ||
```javascript | ||
const schema = { | ||
type: "object", | ||
prohibited: ["foo", "bar"], | ||
} | ||
var validData = { baz: 1 }; | ||
var alsoValidData = {}; | ||
const validData = {baz: 1} | ||
const alsoValidData = {} | ||
var invalidDataList = [ | ||
{ foo: 1 }, | ||
{ bar: 2 }, | ||
{ foo: 1, bar: 2} | ||
]; | ||
const invalidDataList = [{foo: 1}, {bar: 2}, {foo: 1, bar: 2}] | ||
``` | ||
__Please note__: `{prohibited: ['foo', 'bar']}` is equivalent to `{not: {anyRequired: ['foo', 'bar']}}` (i.e. it has the same validation result for any data). | ||
**Please note**: `{prohibited: ['foo', 'bar']}` is equivalent to `{not: {anyRequired: ['foo', 'bar']}}` (i.e. it has the same validation result for any data). | ||
#### `deepProperties` | ||
@@ -461,10 +441,10 @@ | ||
```javascript | ||
var schema = { | ||
type: 'object', | ||
const schema = { | ||
type: "object", | ||
deepProperties: { | ||
"/users/1/role": { "enum": ["admin"] } | ||
} | ||
}; | ||
"/users/1/role": {enum: ["admin"]}, | ||
}, | ||
} | ||
var validData = { | ||
const validData = { | ||
users: [ | ||
@@ -474,17 +454,17 @@ {}, | ||
id: 123, | ||
role: 'admin' | ||
} | ||
] | ||
}; | ||
role: "admin", | ||
}, | ||
], | ||
} | ||
var alsoValidData = { | ||
const alsoValidData = { | ||
users: { | ||
"1": { | ||
1: { | ||
id: 123, | ||
role: 'admin' | ||
} | ||
} | ||
}; | ||
role: "admin", | ||
}, | ||
}, | ||
} | ||
var invalidData = { | ||
const invalidData = { | ||
users: [ | ||
@@ -494,18 +474,17 @@ {}, | ||
id: 123, | ||
role: 'user' | ||
} | ||
] | ||
}; | ||
role: "user", | ||
}, | ||
], | ||
} | ||
var alsoInvalidData = { | ||
const alsoInvalidData = { | ||
users: { | ||
"1": { | ||
1: { | ||
id: 123, | ||
role: 'user' | ||
} | ||
} | ||
}; | ||
role: "user", | ||
}, | ||
}, | ||
} | ||
``` | ||
#### `deepRequired` | ||
@@ -520,8 +499,8 @@ | ||
```javascript | ||
var schema = { | ||
type: 'object', | ||
deepRequired: ["/users/1/role"] | ||
}; | ||
const schema = { | ||
type: "object", | ||
deepRequired: ["/users/1/role"], | ||
} | ||
var validData = { | ||
const validData = { | ||
users: [ | ||
@@ -531,15 +510,15 @@ {}, | ||
id: 123, | ||
role: 'admin' | ||
} | ||
] | ||
}; | ||
role: "admin", | ||
}, | ||
], | ||
} | ||
var invalidData = { | ||
const invalidData = { | ||
users: [ | ||
{}, | ||
{ | ||
id: 123 | ||
} | ||
] | ||
}; | ||
id: 123, | ||
}, | ||
], | ||
} | ||
``` | ||
@@ -549,76 +528,4 @@ | ||
### Keywords for all types | ||
### Compound keywords | ||
#### `switch` (deprecated) | ||
__Please note__: this keyword is provided to preserve backward compatibility with previous versions of Ajv. It is strongly recommended to use `if`/`then`/`else` keywords instead, as they have been added to the draft-07 of JSON Schema specification. | ||
This keyword allows to perform advanced conditional validation. | ||
The value of the keyword is the array of if/then clauses. Each clause is the object with the following properties: | ||
- `if` (optional) - the value is JSON-schema | ||
- `then` (required) - the value is JSON-schema or boolean | ||
- `continue` (optional) - the value is boolean | ||
The validation process is dynamic; all clauses are executed sequentially in the following way: | ||
1. `if`: | ||
1. `if` property is JSON-schema according to which the data is: | ||
1. valid => go to step 2. | ||
2. invalid => go to the NEXT clause, if this was the last clause the validation of `switch` SUCCEEDS. | ||
2. `if` property is absent => go to step 2. | ||
2. `then`: | ||
1. `then` property is `true` or it is JSON-schema according to which the data is valid => go to step 3. | ||
2. `then` property is `false` or it is JSON-schema according to which the data is invalid => the validation of `switch` FAILS. | ||
3. `continue`: | ||
1. `continue` property is `true` => go to the NEXT clause, if this was the last clause the validation of `switch` SUCCEEDS. | ||
2. `continue` property is `false` or absent => validation of `switch` SUCCEEDS. | ||
```javascript | ||
require('ajv-keywords')(ajv, 'switch'); | ||
var schema = { | ||
type: 'array', | ||
items: { | ||
type: 'integer', | ||
'switch': [ | ||
{ if: { not: { minimum: 1 } }, then: false }, | ||
{ if: { maximum: 10 }, then: true }, | ||
{ if: { maximum: 100 }, then: { multipleOf: 10 } }, | ||
{ if: { maximum: 1000 }, then: { multipleOf: 100 } }, | ||
{ then: false } | ||
] | ||
} | ||
}; | ||
var validItems = [1, 5, 10, 20, 50, 100, 200, 500, 1000]; | ||
var invalidItems = [1, 0, 2000, 11, 57, 123, 'foo']; | ||
``` | ||
The above schema is equivalent to (for example): | ||
```javascript | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'integer', | ||
if: { minimum: 1, maximum: 10 }, | ||
then: true, | ||
else: { | ||
if: { maximum: 100 }, | ||
then: { multipleOf: 10 }, | ||
else: { | ||
if: { maximum: 1000 }, | ||
then: { multipleOf: 100 }, | ||
else: false | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
#### `select`/`selectCases`/`selectDefault` | ||
@@ -630,9 +537,10 @@ | ||
The value of `select` keyword should be a [$data reference](https://github.com/epoberezkin/ajv/tree/5.0.2-beta.0#data-reference) that points to any primitive JSON type (string, number, boolean or null) in the data that is validated. You can also use a constant of primitive type as the value of this keyword (e.g., for debugging purposes). | ||
The value of `select` keyword should be a [\$data reference](https://github.com/ajv-validator/ajv/blob/v7-beta/docs/validation.md#data-reference) that points to any primitive JSON type (string, number, boolean or null) in the data that is validated. You can also use a constant of primitive type as the value of this keyword (e.g., for debugging purposes). | ||
The value of `selectCases` keyword must be an object where each property name is a possible string representation of the value of `select` keyword and each property value is a corresponding schema (from draft-06 it can be boolean) that must be used to validate the data. | ||
The value of `selectDefault` keyword is a schema (from draft-06 it can be boolean) that must be used to validate the data in case `selectCases` has no key equal to the stringified value of `select` keyword. | ||
The value of `selectDefault` keyword is a schema (also can be boolean) that must be used to validate the data in case `selectCases` has no key equal to the stringified value of `select` keyword. | ||
The validation succeeds in one of the following cases: | ||
- the validation of data using selected schema succeeds, | ||
@@ -644,10 +552,9 @@ - none of the schemas is selected for validation, | ||
__Please note__: these keywords require Ajv `$data` option to support [$data reference](https://github.com/epoberezkin/ajv/tree/5.0.2-beta.0#data-reference). | ||
**Please note**: these keywords require Ajv `$data` option to support [\$data reference](https://github.com/epoberezkin/ajv/tree/5.0.2-beta.0#data-reference). | ||
```javascript | ||
require('ajv-keywords')(ajv, 'select'); | ||
var schema = { | ||
type: object, | ||
const schema = { | ||
type: "object", | ||
required: ['kind'], | ||
@@ -683,3 +590,3 @@ properties: { | ||
var validDataList = [ | ||
const validDataList = [ | ||
{ kind: 'foo', foo: 'any' }, | ||
@@ -690,3 +597,3 @@ { kind: 'bar', bar: 1 }, | ||
var invalidDataList = [ | ||
const invalidDataList = [ | ||
{ kind: 'foo' }, // no propery foo | ||
@@ -701,7 +608,2 @@ { kind: 'bar' }, // no propery bar | ||
__Please note__: the current implementation is BETA. It does not allow using relative URIs in $ref keywords in schemas in `selectCases` and `selectDefault` that point outside of these schemas. The workaround is to use absolute URIs (that can point to any (sub-)schema added to Ajv, including those inside the current root schema where `select` is used). See [tests](https://github.com/epoberezkin/ajv-keywords/blob/v2.0.0/spec/tests/select.json#L314). | ||
### Keywords for all types | ||
#### `dynamicDefaults` | ||
@@ -715,6 +617,6 @@ | ||
- an identifier of default function (a string) | ||
- an identifier of dynamic 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. | ||
The properties used in `dynamicDefaults` should not be added to `required` keyword in the same schema (or validation will fail), because unlike `default` this keyword is processed after validation. | ||
@@ -732,73 +634,73 @@ There are several predefined dynamic default functions: | ||
```javascript | ||
var schema = { | ||
type: 'object', | ||
const schema = { | ||
type: "object", | ||
dynamicDefaults: { | ||
ts: 'datetime', | ||
r: { func: 'randomint', args: { max: 100 } }, | ||
id: { func: 'seq', args: { name: 'id' } } | ||
ts: "datetime", | ||
r: {func: "randomint", args: {max: 100}}, | ||
id: {func: "seq", args: {name: "id"}}, | ||
}, | ||
properties: { | ||
ts: { | ||
type: 'string', | ||
format: 'date-time' | ||
type: "string", | ||
format: "date-time", | ||
}, | ||
r: { | ||
type: 'integer', | ||
type: "integer", | ||
minimum: 0, | ||
exclusiveMaximum: 100 | ||
exclusiveMaximum: 100, | ||
}, | ||
id: { | ||
type: 'integer', | ||
minimum: 0 | ||
} | ||
} | ||
}; | ||
type: "integer", | ||
minimum: 0, | ||
}, | ||
}, | ||
} | ||
var data = {}; | ||
ajv.validate(data); // true | ||
data; // { ts: '2016-12-01T22:07:28.829Z', r: 25, id: 0 } | ||
const data = {} | ||
ajv.validate(data) // true | ||
data // { ts: '2016-12-01T22:07:28.829Z', r: 25, id: 0 } | ||
var data1 = {}; | ||
ajv.validate(data1); // true | ||
data1; // { ts: '2016-12-01T22:07:29.832Z', r: 68, id: 1 } | ||
const data1 = {} | ||
ajv.validate(data1) // true | ||
data1 // { ts: '2016-12-01T22:07:29.832Z', r: 68, id: 1 } | ||
ajv.validate(data1); // true | ||
data1; // didn't change, as all properties were defined | ||
ajv.validate(data1) // true | ||
data1 // didn't change, as all properties were defined | ||
``` | ||
When using the `useDefaults` option value `"empty"`, properties and items equal to `null` or `""` (empty string) will be considered missing and assigned defaults. Use the `allOf` [compound keyword](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#compound-keywords) to execute `dynamicDefaults` before validation. | ||
When using the `useDefaults` option value `"empty"`, properties and items equal to `null` or `""` (empty string) will be considered missing and assigned defaults. Use `allOf` [compound keyword](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#compound-keywords) to execute `dynamicDefaults` before validation. | ||
```javascript | ||
var schema = { | ||
const schema = { | ||
type: "object", | ||
allOf: [ | ||
{ | ||
dynamicDefaults: { | ||
ts: 'datetime', | ||
r: { func: 'randomint', args: { min: 5, max: 100 } }, | ||
id: { func: 'seq', args: { name: 'id' } } | ||
} | ||
ts: "datetime", | ||
r: {func: "randomint", args: {min: 5, max: 100}}, | ||
id: {func: "seq", args: {name: "id"}}, | ||
}, | ||
}, | ||
{ | ||
type: 'object', | ||
properties: { | ||
ts: { | ||
type: 'string' | ||
type: "string", | ||
}, | ||
r: { | ||
type: 'number', | ||
type: "number", | ||
minimum: 5, | ||
exclusiveMaximum: 100 | ||
exclusiveMaximum: 100, | ||
}, | ||
id: { | ||
type: 'integer', | ||
minimum: 0 | ||
} | ||
} | ||
} | ||
] | ||
}; | ||
type: "integer", | ||
minimum: 0, | ||
}, | ||
}, | ||
}, | ||
], | ||
} | ||
var data = { ts: '', r: null }; | ||
ajv.validate(data); // true | ||
data; // { ts: '2016-12-01T22:07:28.829Z', r: 25, id: 0 } | ||
const data = {ts: "", r: null} | ||
ajv.validate(data) // true | ||
data // { ts: '2016-12-01T22:07:28.829Z', r: 25, id: 0 } | ||
``` | ||
@@ -809,48 +711,44 @@ | ||
```javascript | ||
var uuid = require('uuid'); | ||
const uuid = require("uuid") | ||
function uuidV4() { return uuid.v4(); } | ||
const def = require("ajv-keywords/dist/definitions/dynamicDefaults") | ||
def.DEFAULTS.uuid = () => uuid.v4 | ||
var definition = require('ajv-keywords').get('dynamicDefaults').definition; | ||
// or require('ajv-keywords/keywords/dynamicDefaults').definition; | ||
definition.DEFAULTS.uuid = uuidV4; | ||
const schema = { | ||
dynamicDefaults: {id: "uuid"}, | ||
properties: {id: {type: "string", format: "uuid"}}, | ||
} | ||
var schema = { | ||
dynamicDefaults: { id: 'uuid' }, | ||
properties: { id: { type: 'string', format: 'uuid' } } | ||
}; | ||
const data = {} | ||
ajv.validate(schema, data) // true | ||
data // { id: 'a1183fbe-697b-4030-9bcc-cfeb282a9150' }; | ||
var data = {}; | ||
ajv.validate(schema, data); // true | ||
data; // { id: 'a1183fbe-697b-4030-9bcc-cfeb282a9150' }; | ||
var data1 = {}; | ||
ajv.validate(schema, data1); // true | ||
data1; // { id: '5b008de7-1669-467a-a5c6-70fa244d7209' } | ||
const data1 = {} | ||
ajv.validate(schema, data1) // true | ||
data1 // { id: '5b008de7-1669-467a-a5c6-70fa244d7209' } | ||
``` | ||
You also can define dynamic default that accepts parameters, e.g. version of uuid: | ||
You also can define dynamic default that accept parameters, e.g. version of uuid: | ||
```javascript | ||
var uuid = require('uuid'); | ||
const uuid = require("uuid") | ||
function getUuid(args) { | ||
var version = 'v' + (arvs && args.v || 4); | ||
return function() { | ||
return uuid[version](); | ||
}; | ||
const version = "v" + ((arvs && args.v) || "4") | ||
return uuid[version] | ||
} | ||
var definition = require('ajv-keywords').get('dynamicDefaults').definition; | ||
definition.DEFAULTS.uuid = getUuid; | ||
const def = require("ajv-keywords/dist/definitions/dynamicDefaults") | ||
def.DEFAULTS.uuid = getUuid | ||
var schema = { | ||
const schema = { | ||
dynamicDefaults: { | ||
id1: 'uuid', // v4 | ||
id2: { func: 'uuid', v: 4 }, // v4 | ||
id3: { func: 'uuid', v: 1 } // v1 | ||
} | ||
}; | ||
id1: "uuid", // v4 | ||
id2: {func: "uuid", v: 4}, // v4 | ||
id3: {func: "uuid", v: 1}, // v1 | ||
}, | ||
} | ||
``` | ||
**Please note**: dynamic default functions differented by the number of parameters they have (`function.length`). Functions that do not expect default must have one non-optional argument so that `function.length` > 0. | ||
@@ -865,3 +763,2 @@ ## Security contact | ||
## Open-source software support | ||
@@ -871,5 +768,4 @@ | ||
## License | ||
[MIT](https://github.com/epoberezkin/ajv-keywords/blob/master/LICENSE) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
124885
160
1870
2
22
1
733
1
+ Added@types/chai@^4.2.14
+ Added@types/chai@4.3.20(transitive)
+ Addedajv@7.2.4(transitive)
+ Addedjson-schema-traverse@1.0.0(transitive)
+ Addedrequire-from-string@2.0.2(transitive)
- Removedajv@6.12.6(transitive)
- Removedfast-json-stable-stringify@2.1.0(transitive)
- Removedjson-schema-traverse@0.4.1(transitive)