ajv-keywords
Advanced tools
Comparing version 3.2.0 to 3.3.0
@@ -38,4 +38,8 @@ 'use strict'; | ||
function assignDefaults(data) { | ||
for (var prop in schema) | ||
if (data[prop] === undefined) data[prop] = funcs[prop](); | ||
for (var prop in schema){ | ||
if (data[prop] === undefined | ||
|| (it.opts.useDefaults == 'empty' | ||
&& (data[prop] === null || data[prop] === ''))) | ||
data[prop] = funcs[prop](); | ||
} | ||
return true; | ||
@@ -42,0 +46,0 @@ } |
@@ -14,3 +14,3 @@ 'use strict'; | ||
var rx = schema.match(/^\/(.*)\/([gimy]*)$/); | ||
var rx = schema.match(/^\/(.*)\/([gimuy]*)$/); | ||
if (rx) return new RegExp(rx[1], rx[2]); | ||
@@ -17,0 +17,0 @@ throw new Error('cannot parse string into RegExp'); |
'use strict'; | ||
module.exports = function defFunc (ajv) { | ||
var transform = { | ||
trimLeft: function (value) { | ||
return value.replace(/^[\s]+/, ''); | ||
}, | ||
trimRight: function (value) { | ||
return value.replace(/[\s]+$/, ''); | ||
}, | ||
trim: function (value) { | ||
return value.trim(); | ||
}, | ||
toLowerCase: function (value) { | ||
return value.toLowerCase(); | ||
}, | ||
toUpperCase: function (value) { | ||
return value.toUpperCase(); | ||
}, | ||
toEnumCase: function (value, cfg) { | ||
return cfg.hash[makeHashTableKey(value)] || value; | ||
} | ||
}; | ||
defFunc.definition = { | ||
@@ -10,7 +31,8 @@ type: 'string', | ||
compile: function (schema, parentSchema) { | ||
var cfg; | ||
// build hash table to enum values | ||
var hashtable = {}; | ||
if (schema == 'toEnumCase') { | ||
// build hash table to enum values | ||
cfg = {hash: {}}; | ||
if (schema.indexOf('toEnumCase') !== -1) { | ||
// requires `enum` in schema | ||
@@ -24,30 +46,9 @@ if (!parentSchema.enum) | ||
// requires all `enum` values have unique keys | ||
if (hashtable[k]) | ||
if (cfg.hash[k]) | ||
throw new Error('Invalid enum uniqueness. To use `transform:["toEnumCase"]`, all values must be unique when case insensitive.'); | ||
hashtable[k] = v; | ||
cfg.hash[k] = v; | ||
} | ||
} | ||
var transform = { | ||
trimLeft: function (value) { | ||
return value.replace(/^[\s]+/, ''); | ||
}, | ||
trimRight: function (value) { | ||
return value.replace(/[\s]+$/, ''); | ||
}, | ||
trim: function (value) { | ||
return value.trim(); | ||
}, | ||
toLowerCase: function (value) { | ||
return value.toLowerCase(); | ||
}, | ||
toUpperCase: function (value) { | ||
return value.toUpperCase(); | ||
}, | ||
toEnumCase: function (value) { | ||
return hashtable[makeHashTableKey(value)] || value; | ||
} | ||
}; | ||
return function (value, objectKey, object, key) { | ||
return function (data, dataPath, object, key) { | ||
// skip if value only | ||
@@ -57,6 +58,6 @@ if (!object) return; | ||
// apply transform in order provided | ||
for (var j = 0, l = schema.length; j < l; j++) { | ||
if (typeof object[key] !== 'string') continue; | ||
object[key] = transform[schema[j]](object[key]); | ||
} | ||
for (var j = 0, l = schema.length; j < l; j++) | ||
data = transform[schema[j]](data, cfg); | ||
object[key] = data; | ||
}; | ||
@@ -63,0 +64,0 @@ }, |
{ | ||
"name": "ajv-keywords", | ||
"version": "3.2.0", | ||
"version": "3.3.0", | ||
"description": "Custom JSON-Schema keywords for Ajv validator", | ||
@@ -42,3 +42,3 @@ "main": "index.js", | ||
"dot": "^1.1.1", | ||
"eslint": "^4.9.0", | ||
"eslint": "^5.0.0", | ||
"glob": "^7.1.1", | ||
@@ -45,0 +45,0 @@ "istanbul": "^0.4.3", |
558
README.md
@@ -18,19 +18,28 @@ # ajv-keywords | ||
- [Keywords](#keywords) | ||
- [typeof](#typeof) | ||
- [instanceof](#instanceof) | ||
- [range and exclusiveRange](#range-and-exclusiverange) | ||
- [switch](#switch) | ||
- [select/selectCases/selectDefault](#selectselectcasesselectdefault) (BETA) | ||
- [patternRequired](#patternrequired) | ||
- [prohibited](#prohibited) | ||
- [deepProperties](#deepproperties) | ||
- [deepRequired](#deeprequired) | ||
- [uniqueItemProperties](#uniqueitemproperties) | ||
- [regexp](#regexp) | ||
- [formatMaximum / formatMinimum and formatExclusiveMaximum / formatExclusiveMinimum](#formatmaximum--formatminimum-and-formatexclusivemaximum--formatexclusiveminimum) | ||
- [dynamicDefaults](#dynamicdefaults) | ||
- [transform](#transform) | ||
- [Types](#types) | ||
- [typeof](#typeof) | ||
- [instanceof](#instanceof) | ||
- [Keywords for numbers](#keywords-for-numbers) | ||
- [range and exclusiveRange](#range-and-exclusiverange) | ||
- [Keywords for strings](#keywords-for-strings) | ||
- [regexp](#regexp) | ||
- [formatMaximum / formatMinimum and formatExclusiveMaximum / formatExclusiveMinimum](#formatmaximum--formatminimum-and-formatexclusivemaximum--formatexclusiveminimum) | ||
- [transform](#transform)<sup>\*</sup> | ||
- [Keywords for arrays](#keywords-for-arrays) | ||
- [uniqueItemProperties](#uniqueitemproperties) | ||
- [Keywords for objects](#keywords-for-objects) | ||
- [patternRequired](#patternrequired) | ||
- [prohibited](#prohibited) | ||
- [deepProperties](#deepproperties) | ||
- [deepRequired](#deeprequired) | ||
- [Compound keywords](#compound-keywords) | ||
- [switch](#switch) | ||
- [select/selectCases/selectDefault](#selectselectcasesselectdefault) (BETA) | ||
- [Keywords for all types](#keywords-for-all-types) | ||
- [dynamicDefaults](#dynamicdefaults)<sup>\*</sup> | ||
- [License](#license) | ||
<sup>\*</sup> - keywords that modify data | ||
## Install | ||
@@ -77,4 +86,6 @@ | ||
### `typeof` | ||
### Types | ||
#### `typeof` | ||
Based on JavaScript `typeof` operation. | ||
@@ -93,3 +104,3 @@ | ||
### `instanceof` | ||
#### `instanceof` | ||
@@ -120,4 +131,6 @@ Based on JavaScript `instanceof` operation. | ||
### `range` and `exclusiveRange` | ||
### Keywords for numbers | ||
#### `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. | ||
@@ -146,149 +159,159 @@ | ||
### `switch` | ||
### Keywords for strings | ||
This keyword allows to perform advanced conditional validation. | ||
#### `regexp` | ||
The value of the keyword is the array of if/then clauses. Each clause is the object with the following properties: | ||
This keyword allows to use regular expressions with flags in schemas (the standard `pattern` keyword does not support flags). | ||
- `if` (optional) - the value is JSON-schema | ||
- `then` (required) - the value is JSON-schema or boolean | ||
- `continue` (optional) - the value is boolean | ||
This keyword applies only to strings. If the data is not a string, the validation succeeds. | ||
The validation process is dynamic; all clauses are executed sequentially in the following way: | ||
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). | ||
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 } | ||
] | ||
type: 'object', | ||
properties: { | ||
foo: { regexp: '/foo/i' }, | ||
bar: { regexp: { pattern: 'bar', flags: 'i' } } | ||
} | ||
}; | ||
var validItems = [1, 5, 10, 20, 50, 100, 200, 500, 1000]; | ||
var validData = { | ||
foo: 'Food', | ||
bar: 'Barmen' | ||
}; | ||
var invalidItems = [1, 0, 2000, 11, 57, 123, 'foo']; | ||
var invalidData = { | ||
foo: 'fog', | ||
bar: 'bad' | ||
}; | ||
``` | ||
__Please note__: this keyword is moved here from Ajv, mainly to preserve backward compatibility. It is unlikely to become a standard. It's preferable to use `if`/`then`/`else` keywords if possible, as they are likely to be added to the standard. The above schema is equivalent to (for example): | ||
#### `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. | ||
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 | ||
{ | ||
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 | ||
} | ||
} | ||
} | ||
require('ajv-keywords')(ajv, ['formatMinimum', 'formatMaximum']); | ||
var schema = { | ||
format: 'date', | ||
formatMinimum: '2016-02-06', | ||
formatMaximum: '2016-12-27', | ||
formatExclusiveMaximum: true | ||
} | ||
var validDataList = ['2016-02-06', '2016-12-26', 1]; | ||
var invalidDataList = ['2016-02-05', '2016-12-27', 'abc']; | ||
``` | ||
### `select`/`selectCases`/`selectDefault` | ||
#### `transform` | ||
These keywords allow to choose the schema to validate the data based on the value of some property in the validated data. | ||
This keyword allows a string to be modified before validation. | ||
These keywords must be present in the same schema object (`selectDefault` is optional). | ||
These keywords apply only to strings. If the data is not a string, the transform is skipped. | ||
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). | ||
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` | ||
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. | ||
**Supported options:** | ||
- `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 | ||
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. | ||
Options are applied in the order they are listed. | ||
The validation succeeds in one of the following cases: | ||
- the validation of data using selected schema succeeds, | ||
- none of the schemas is selected for validation, | ||
- the value of select is undefined (no property in the data that the data reference points to). | ||
Note: `toEnumCase` requires that all allowed values are unique when case insensitive. | ||
If `select` value (in data) is not a primitive type the validation fails. | ||
**Example: multiple options** | ||
```javascript | ||
require('ajv-keywords')(ajv, ['transform']); | ||
__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). | ||
var schema = { | ||
type: 'array', | ||
items: { | ||
type:'string', | ||
transform:['trim','toLowerCase'] | ||
} | ||
}; | ||
var data = [' MixCase ']; | ||
ajv.validate(schema, data); | ||
console.log(data); // ['mixcase'] | ||
``` | ||
**Example: `enumcase`** | ||
```javascript | ||
require('ajv-keywords')(ajv, 'select'); | ||
require('ajv-keywords')(ajv, ['transform']); | ||
var schema = { | ||
type: object, | ||
required: ['kind'], | ||
properties: { | ||
kind: { type: 'string' } | ||
}, | ||
select: { $data: '0/kind' }, | ||
selectCases: { | ||
foo: { | ||
required: ['foo'], | ||
properties: { | ||
kind: {}, | ||
foo: { type: 'string' } | ||
}, | ||
additionalProperties: false | ||
}, | ||
bar: { | ||
required: ['bar'], | ||
properties: { | ||
kind: {}, | ||
bar: { type: 'number' } | ||
}, | ||
additionalProperties: false | ||
} | ||
}, | ||
selectDefault: { | ||
propertyNames: { | ||
not: { enum: ['foo', 'bar'] } | ||
} | ||
type: 'array', | ||
items: { | ||
type:'string', | ||
transform:['trim','toEnumCase'], | ||
enum:['pH'] | ||
} | ||
}; | ||
var validDataList = [ | ||
{ kind: 'foo', foo: 'any' }, | ||
{ kind: 'bar', bar: 1 }, | ||
{ kind: 'anything_else', not_bar_or_foo: 'any value' } | ||
var data = ['ph',' Ph','PH','pH ']; | ||
ajv.validate(schema, data); | ||
console.log(data); // ['pH','pH','pH','pH'] | ||
``` | ||
### Keywords for arrays | ||
#### `uniqueItemProperties` | ||
The keyword allows to check that some properties in array items are unique. | ||
This keyword applies only to arrays. If the data is not an array, the validation succeeds. | ||
The value of this keyword must be an array of strings - property names that should have unique values across all items. | ||
```javascript | ||
var schema = { uniqueItemProperties: [ "id", "name" ] }; | ||
var validData = [ | ||
{ id: 1 }, | ||
{ id: 2 }, | ||
{ id: 3 } | ||
]; | ||
var invalidDataList = [ | ||
{ kind: 'foo' }, // no propery foo | ||
{ kind: 'bar' }, // no propery bar | ||
{ kind: 'foo', foo: 'any', another: 'any value' }, // additional property | ||
{ kind: 'bar', bar: 1, another: 'any value' }, // additional property | ||
{ kind: 'anything_else', foo: 'any' } // property foo not allowed | ||
{ kind: 'anything_else', bar: 1 } // property bar not allowed | ||
var invalidData1 = [ | ||
{ id: 1 }, | ||
{ id: 1 }, | ||
{ id: 3 } | ||
]; | ||
var invalidData2 = [ | ||
{ id: 1, name: "taco" }, | ||
{ id: 2, name: "taco" }, // duplicate "name" | ||
{ id: 3, name: "salsa" } | ||
]; | ||
``` | ||
__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). | ||
This keyword is contributed by [@blainesch](https://github.com/blainesch). | ||
### `patternRequired` | ||
### Keywords for objects | ||
#### `patternRequired` | ||
This keyword allows to require the presence of properties that match some pattern(s). | ||
@@ -312,3 +335,3 @@ | ||
### `prohibited` | ||
#### `prohibited` | ||
@@ -335,3 +358,3 @@ This keyword allows to prohibit that any of the properties in the list is present in the object. | ||
### `deepProperties` | ||
#### `deepProperties` | ||
@@ -392,3 +415,3 @@ This keyword allows to validate deep properties (identified by JSON pointers). | ||
### `deepRequired` | ||
#### `deepRequired` | ||
@@ -430,97 +453,156 @@ This keyword allows to check that some deep properties (identified by JSON pointers) are available. | ||
### `uniqueItemProperties` | ||
### Compound keywords | ||
The keyword allows to check that some properties in array items are unique. | ||
#### `switch` | ||
This keyword applies only to arrays. If the data is not an array, the validation succeeds. | ||
This keyword allows to perform advanced conditional validation. | ||
The value of this keyword must be an array of strings - property names that should have unique values across all items. | ||
The value of the keyword is the array of if/then clauses. Each clause is the object with the following properties: | ||
```javascript | ||
var schema = { uniqueItemProperties: [ "id", "name" ] }; | ||
- `if` (optional) - the value is JSON-schema | ||
- `then` (required) - the value is JSON-schema or boolean | ||
- `continue` (optional) - the value is boolean | ||
var validData = [ | ||
{ id: 1 }, | ||
{ id: 2 }, | ||
{ id: 3 } | ||
]; | ||
The validation process is dynamic; all clauses are executed sequentially in the following way: | ||
var invalidData1 = [ | ||
{ id: 1 }, | ||
{ id: 1 }, | ||
{ id: 3 } | ||
]; | ||
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. | ||
var invalidData2 = [ | ||
{ id: 1, name: "taco" }, | ||
{ id: 2, name: "taco" }, // duplicate "name" | ||
{ id: 3, name: "salsa" } | ||
]; | ||
``` | ||
```javascript | ||
require('ajv-keywords')(ajv, 'switch'); | ||
This keyword is contributed by [@blainesch](https://github.com/blainesch). | ||
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]; | ||
### `regexp` | ||
var invalidItems = [1, 0, 2000, 11, 57, 123, 'foo']; | ||
``` | ||
This keyword allows to use regular expressions with flags in schemas (the standard `pattern` keyword does not support flags). | ||
__Please note__: this keyword is moved here from Ajv, mainly to preserve backward compatibility. It is unlikely to become a standard. It's preferable to use `if`/`then`/`else` keywords if possible, as they are likely to be added to the standard. The above schema is equivalent to (for example): | ||
This keyword applies only to strings. If the data is not a string, the validation succeeds. | ||
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). | ||
```javascript | ||
var schema = { | ||
type: 'object', | ||
properties: { | ||
foo: { regexp: '/foo/i' }, | ||
bar: { regexp: { pattern: 'bar', flags: 'i' } } | ||
{ | ||
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 | ||
} | ||
} | ||
} | ||
}; | ||
} | ||
``` | ||
var validData = { | ||
foo: 'Food', | ||
bar: 'Barmen' | ||
}; | ||
var invalidData = { | ||
foo: 'fog', | ||
bar: 'bad' | ||
}; | ||
``` | ||
#### `select`/`selectCases`/`selectDefault` | ||
These keywords allow to choose the schema to validate the data based on the value of some property in the validated data. | ||
### `formatMaximum` / `formatMinimum` and `formatExclusiveMaximum` / `formatExclusiveMinimum` | ||
These keywords must be present in the same schema object (`selectDefault` is optional). | ||
These keywords allow to define minimum/maximum constraints when the format keyword defines ordering. | ||
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). | ||
These keywords apply only to strings. If the data is not a string, the validation succeeds. | ||
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 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. | ||
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. | ||
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 validation succeeds in one of the following cases: | ||
- the validation of data using selected schema succeeds, | ||
- none of the schemas is selected for validation, | ||
- the value of select is undefined (no property in the data that the data reference points to). | ||
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. | ||
If `select` value (in data) is not a primitive type the validation fails. | ||
__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, ['formatMinimum', 'formatMaximum']); | ||
require('ajv-keywords')(ajv, 'select'); | ||
var schema = { | ||
format: 'date', | ||
formatMinimum: '2016-02-06', | ||
formatMaximum: '2016-12-27', | ||
formatExclusiveMaximum: true | ||
} | ||
type: object, | ||
required: ['kind'], | ||
properties: { | ||
kind: { type: 'string' } | ||
}, | ||
select: { $data: '0/kind' }, | ||
selectCases: { | ||
foo: { | ||
required: ['foo'], | ||
properties: { | ||
kind: {}, | ||
foo: { type: 'string' } | ||
}, | ||
additionalProperties: false | ||
}, | ||
bar: { | ||
required: ['bar'], | ||
properties: { | ||
kind: {}, | ||
bar: { type: 'number' } | ||
}, | ||
additionalProperties: false | ||
} | ||
}, | ||
selectDefault: { | ||
propertyNames: { | ||
not: { enum: ['foo', 'bar'] } | ||
} | ||
} | ||
}; | ||
var validDataList = ['2016-02-06', '2016-12-26', 1]; | ||
var validDataList = [ | ||
{ kind: 'foo', foo: 'any' }, | ||
{ kind: 'bar', bar: 1 }, | ||
{ kind: 'anything_else', not_bar_or_foo: 'any value' } | ||
]; | ||
var invalidDataList = ['2016-02-05', '2016-12-27', 'abc']; | ||
var invalidDataList = [ | ||
{ kind: 'foo' }, // no propery foo | ||
{ kind: 'bar' }, // no propery bar | ||
{ kind: 'foo', foo: 'any', another: 'any value' }, // additional property | ||
{ kind: 'bar', bar: 1, another: 'any value' }, // additional property | ||
{ kind: 'anything_else', foo: 'any' } // property foo not allowed | ||
{ kind: 'anything_else', bar: 1 } // property bar not allowed | ||
]; | ||
``` | ||
__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). | ||
### `dynamicDefaults` | ||
### Keywords for all types | ||
#### `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](https://github.com/epoberezkin/ajv#assigning-defaults). | ||
This keyword only works if `useDefaults` options is used and not inside `anyOf` keywords etc., in the same way as [default keyword treated by Ajv](https://github.com/epoberezkin/ajv#assigning-defaults). | ||
@@ -541,4 +623,4 @@ 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: | ||
- `"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. | ||
- `"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', args: { 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', args: { name: 'foo'} }` is used then the sequence with name `"foo"` will be used. Sequences are global, even if different ajv instances are used. | ||
@@ -550,4 +632,4 @@ ```javascript | ||
ts: 'datetime', | ||
r: { func: 'randomint', max: 100 }, | ||
id: { func: 'seq', name: 'id' } | ||
r: { func: 'randomint', args: { max: 100 } }, | ||
id: { func: 'seq', args: { name: 'id' } } | ||
}, | ||
@@ -557,3 +639,3 @@ properties: { | ||
type: 'string', | ||
format: 'datetime' | ||
format: 'date-time' | ||
}, | ||
@@ -563,4 +645,3 @@ r: { | ||
minimum: 0, | ||
maximum: 100, | ||
exclusiveMaximum: true | ||
exclusiveMaximum: 100 | ||
}, | ||
@@ -586,2 +667,39 @@ id: { | ||
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. | ||
```javascript | ||
var schema = { | ||
allOf: [ | ||
{ | ||
dynamicDefaults: { | ||
ts: 'datetime', | ||
r: { func: 'randomint', args: { min: 5, max: 100 } }, | ||
id: { func: 'seq', args: { name: 'id' } } | ||
} | ||
}, | ||
{ | ||
type: 'object', | ||
properties: { | ||
ts: { | ||
type: 'string' | ||
}, | ||
r: { | ||
type: 'number', | ||
minimum: 5, | ||
exclusiveMaximum: 100 | ||
}, | ||
id: { | ||
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 } | ||
``` | ||
You can add your own dynamic default function to be recognised by this keyword: | ||
@@ -636,63 +754,5 @@ | ||
### `transform` | ||
This keyword allows a string to be modified before validation. | ||
These keywords apply only to strings. If the data is not a string, the transform is skipped. | ||
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` | ||
**Supported options:** | ||
- `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 | ||
Options are applied in the order they are listed. | ||
Note: `toEnumCase` requires that all allowed values are unique when case insensitive. | ||
**Example: multiple options** | ||
```javascript | ||
require('ajv-keywords')(ajv, ['transform']); | ||
var schema = { | ||
type: 'array', | ||
items: { | ||
type:'string', | ||
transform:['trim','lowercase'] | ||
} | ||
}; | ||
var data = [' MixCase ']; | ||
avj.validate(schema, data); | ||
console.log(data); // ['mixcase'] | ||
``` | ||
**Example: `enumcase`** | ||
```javascript | ||
require('ajv-keywords')(ajv, ['transform']); | ||
var schema = { | ||
type: 'array', | ||
items: { | ||
type:'string', | ||
transform:['trim','enumcase'], | ||
enum:['pH'] | ||
} | ||
}; | ||
var data = ['ph',' Ph','PH','pH ']; | ||
avj.validate(schema, data); | ||
console.log(data); // ['pH','pH','pH','pH'] | ||
``` | ||
## 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
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
66623
1050
744