diff options
author | Florian Dold <florian.dold@gmail.com> | 2017-08-14 05:01:11 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2017-08-14 05:02:09 +0200 |
commit | 363723fc84f7b8477592e0105aeb331ec9a017af (patch) | |
tree | 29f92724f34131bac64d6a318dd7e30612e631c7 /node_modules/ajv-keywords | |
parent | 5634e77ad96bfe1818f6b6ee70b7379652e5487f (diff) | |
download | wallet-core-363723fc84f7b8477592e0105aeb331ec9a017af.tar.xz |
node_modules
Diffstat (limited to 'node_modules/ajv-keywords')
19 files changed, 468 insertions, 179 deletions
diff --git a/node_modules/ajv-keywords/README.md b/node_modules/ajv-keywords/README.md index e432391d6..9334531a0 100644 --- a/node_modules/ajv-keywords/README.md +++ b/node_modules/ajv-keywords/README.md @@ -1,11 +1,13 @@ # ajv-keywords -Custom JSON-Schema keywords for [ajv](https://github.com/epoberezkin/ajv) validator +Custom JSON-Schema keywords for [Ajv](https://github.com/epoberezkin/ajv) validator [![Build Status](https://travis-ci.org/epoberezkin/ajv-keywords.svg?branch=master)](https://travis-ci.org/epoberezkin/ajv-keywords) [![npm version](https://badge.fury.io/js/ajv-keywords.svg)](https://www.npmjs.com/package/ajv-keywords) [![npm downloads](https://img.shields.io/npm/dm/ajv-keywords.svg)](https://www.npmjs.com/package/ajv-keywords) [![Coverage Status](https://coveralls.io/repos/github/epoberezkin/ajv-keywords/badge.svg?branch=master)](https://coveralls.io/github/epoberezkin/ajv-keywords?branch=master) +[![Greenkeeper badge](https://badges.greenkeeper.io/epoberezkin/ajv-keywords.svg)](https://greenkeeper.io/) +[![Gitter](https://img.shields.io/gitter/room/ajv-validator/ajv.svg)](https://gitter.im/ajv-validator/ajv) ## Contents @@ -16,12 +18,16 @@ Custom JSON-Schema keywords for [ajv](https://github.com/epoberezkin/ajv) valida - [typeof](#typeof) - [instanceof](#instanceof) - [range and exclusiveRange](#range-and-exclusiverange) - - [propertyNames](#propertynames) - [if/then/else](#ifthenelse) + - [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) - [License](#license) @@ -93,7 +99,7 @@ To pass validation the result of `data instanceof ...` operation on the value sh ``` ajv.validate({ instanceof: 'Array' }, []); // true ajv.validate({ instanceof: 'Array' }, {}); // false -ajv.validate({ instanceof: ['Array', 'Function'] }, funciton(){}); // true +ajv.validate({ instanceof: ['Array', 'Function'] }, function(){}); // true ``` You can add your own constructor function to be recognised by this keyword: @@ -133,66 +139,200 @@ ajv.validate(schema, 3); // false ``` -### `propertyNames` +### `if`/`then`/`else` + +These keywords allow to implement conditional validation. Their values should be valid JSON-schemas. -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}`). +If the data is valid according to the sub-schema in `if` keyword, then the result is equal to the result of data validation against the sub-schema in `then` keyword, otherwise - in `else` keyword (if `else` is absent, the validation succeeds). ```javascript +require('ajv-keywords')(ajv, 'if'); + var schema = { - type: 'object' - propertyNames: { - anyOf: [ - { format: ipv4 }, - { format: hostname } - ] + type: 'array', + items: { + type: 'integer', + minimum: 1, + if: { maximum: 10 }, + then: { multipleOf: 2 }, + else: { multipleOf: 5 } } }; -var validData = { - '192.128.0.1': {}, - 'test.example.com': {} -}; +var validItems = [ 2, 4, 6, 8, 10, 15, 20, 25 ]; // etc. -var invalidData = { - '1.2.3': {} -}; +var invalidItems = [ 1, 3, 5, 11, 12 ]; // etc. -ajv.validate(schema, validData); // true -ajv.validate(schema, invalidData); // false +ajv.validate(schema, validItems); // true +ajv.validate(schema, invalidItems); // false ``` -__Please note__: This keyword will be added to the next version of the JSON-Schema standard (draft-6), after it is published the keyword will be included in Ajv as standard validation keyword. +This keyword is [proposed](https://github.com/json-schema-org/json-schema-spec/issues/180) for the future version of JSON-Schema standard. -### `if`/`then`/`else` +### `switch` -These keywords allow to implement conditional validation. Their values should be valid JSON-schemas. At the moment it requires using Ajv with v5 option. +This keyword allows to perform advanced conditional validation. -If the data is valid according to the sub-schema in `if` keyword, then the result is equal to the result of data validation against the sub-schema in `then` keyword, otherwise - in `else` keyword (if `else` is absent, the validation succeeds). +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, 'if'); +require('ajv-keywords')(ajv, 'switch'); var schema = { type: 'array', items: { type: 'integer', - minimum: 1, - if: { maximum: 10 }, - then: { multipleOf: 2 }, - else: { multipleOf: 5 } + '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 = [ 2, 4, 6, 8, 10, 15, 20, 25 ]; // etc. +var validItems = [1, 5, 10, 20, 50, 100, 200, 500, 1000]; -var invalidItems = [ 1, 3, 5, 11, 12 ]; // etc. +var invalidItems = [1, 0, 2000, 11, 57, 123, 'foo']; +``` -ajv.validate(schema, validItems); // true -ajv.validate(schema, invalidItems); // false +__Please note__: this keyword is moved here from Ajv, mainly to preserve beckward compatibility. It is unlikely to become a standard. It's preferreable 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): + +```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 + } + } + } +} ``` -This keyword is [proposed](https://github.com/json-schema-org/json-schema-spec/issues/180) for the future version of JSON-Schema standard. + +### `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. + +These keywords must be present in the same schema object (`selectDefault` is optional). + +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 `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 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). + +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, 'select'); + +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'] } + } + } +}; + +var validDataList = [ + { kind: 'foo', foo: 'any' }, + { kind: 'bar', bar: 1 }, + { kind: 'anything_else', not_bar_or_foo: 'any value' } +]; + +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 ouside 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). + + +### `patternRequired` + +This keyword allows to require the presense of properties that match some pattern(s). + +This keyword applies only to objects. If the data is not an object, the validation succeeds. + +The value of this keyword should be an array of strings, each string being a regular expression. For data object to be valid each regular expression in this array should match at least one property name in the data object. + +If the array contains multiple regular expressions, more than one expression can match the same property name. + +```javascript +var schema = { patternRequired: [ 'f.*o', 'b.*r' ] }; + +var validData = { foo: 1, bar: 2 }; +var alsoValidData = { foobar: 3 }; + +var invalidDataList = [ {}, { foo: 1 }, { bar: 2 } ]; +``` ### `prohibited` @@ -217,14 +357,20 @@ var invalidDataList = [ ``` -### `deepRequired` +### `deepProperties` -This keyword allows to check that some deep properties (identified by JSON pointers) are available. The value should be an array of JSON pointers to the data, starting from the current position in data. +This keyword allows to validate deep properties (identified by JSON pointers). + +This keyword applies only to objects. If the data is not an object, the validation succeeds. + +The value should be an object, where keys are JSON pointers to the data, starting from the current position in data, and the values are JSON schemas. For data object to be valid the value of each JSON pointer should be valid according to the corresponding schema. ```javascript var schema = { type: 'object', - deepRequired: ["/users/1/role"] + deepProperties: { + "/users/1/role": { "enum": ["admin"] } + } }; var validData = { @@ -237,29 +383,48 @@ var validData = { ] }; +var alsoValidData = { + users: { + "1": { + id: 123, + role: 'admin' + } + } +}; + var invalidData = { users: [ {}, { - id: 123 + id: 123, + role: 'user' } ] }; + +var alsoInvalidData = { + users: { + "1": { + id: 123, + role: 'user' + } + } +}; ``` -See [json-schema-org/json-schema-spec#203](https://github.com/json-schema-org/json-schema-spec/issues/203#issue-197211916) for an example of the equivalent schema without `deepRequired` keyword. +### `deepRequired` + +This keyword allows to check that some deep properties (identified by JSON pointers) are available. -## `deepProperties` +This keyword applies only to objects. If the data is not an object, the validation succeeds. -This keyword allows to validate deep properties (identified by JSON pointers). The value should be an object, where keys are JSON pointers to the data, starting from the current position in data, and the values are corresponding schemas. +The value should be an array of JSON pointers to the data, starting from the current position in data. For data object to be valid each JSON pointer should be some existing part of the data. ```javascript var schema = { type: 'object', - deepProperties: { - "/users/1/role": { "enum": ["admin"] } - } + deepRequired: ["/users/1/role"] }; var validData = { @@ -272,39 +437,59 @@ var validData = { ] }; -var alsoValidData = { - users: { - "1": { - id: 123, - role: 'admin' - } - } -}; - var invalidData = { users: [ {}, { - id: 123, - role: 'user' + id: 123 } ] }; +``` -var alsoInvalidData = { - users: { - "1": { - id: 123, - role: 'user' - } - } -}; +See [json-schema-org/json-schema-spec#203](https://github.com/json-schema-org/json-schema-spec/issues/203#issue-197211916) for an example of the equivalent schema without `deepRequired` keyword. + + +### `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 accross all items. + +```javascript +var schema = { uniqueItemProperties: [ "id", "name" ] }; + +var validData = [ + { id: 1 }, + { id: 2 }, + { id: 3 } +]; + +var invalidData1 = [ + { id: 1 }, + { id: 1 }, + { id: 3 } +]; + +var invalidData2 = [ + { id: 1, name: "taco" }, + { id: 2, name: "taco" }, // duplicate "name" + { id: 3, name: "salsa" } +]; ``` +This keyword is contributed by [@blainesch](https://github.com/blainesch). + ### `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). +This keyword allows to use regular expressions with flags in schemas (the standard `pattern` keyword does not support flags). + +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 = { @@ -327,6 +512,34 @@ var invalidData = { ``` +### `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 +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']; +``` + + ### `dynamicDefaults` This keyword allows to assign dynamic defaults to properties, such as timestamps, unique IDs etc. @@ -440,4 +653,4 @@ var schema = { ## License -[MIT](https://github.com/JSONScript/ajv-keywords/blob/master/LICENSE) +[MIT](https://github.com/epoberezkin/ajv-keywords/blob/master/LICENSE) diff --git a/node_modules/ajv-keywords/keywords/_formatLimit.js b/node_modules/ajv-keywords/keywords/_formatLimit.js index 96541dd64..2ae8e007c 100644 --- a/node_modules/ajv-keywords/keywords/_formatLimit.js +++ b/node_modules/ajv-keywords/keywords/_formatLimit.js @@ -12,9 +12,6 @@ var COMPARE_FORMATS = { module.exports = function (minMax) { var keyword = 'format' + minMax; return function defFunc(ajv) { - if (ajv.RULES.keywords[keyword]) - return console.warn('Keyword', keyword, 'is already defined'); - defFunc.definition = { type: 'string', inline: require('./dotjs/_formatLimit'), @@ -53,7 +50,8 @@ function extendFormats(ajv) { var formats = ajv._formats; for (var name in COMPARE_FORMATS) { var format = formats[name]; - if (typeof format != 'object') + // the last condition is needed if it's RegExp from another window + if (typeof format != 'object' || format instanceof RegExp || !format.validate) format = formats[name] = { validate: format }; if (!format.compare) format.compare = COMPARE_FORMATS[name]; diff --git a/node_modules/ajv-keywords/keywords/_util.js b/node_modules/ajv-keywords/keywords/_util.js new file mode 100644 index 000000000..eebd07aad --- /dev/null +++ b/node_modules/ajv-keywords/keywords/_util.js @@ -0,0 +1,15 @@ +'use strict'; + +module.exports = { + metaSchemaRef: metaSchemaRef +}; + +var META_SCHEMA_ID = 'http://json-schema.org/draft-06/schema'; + +function metaSchemaRef(ajv) { + var defaultMeta = ajv._opts.defaultMeta; + if (typeof defaultMeta == 'string') return { $ref: defaultMeta }; + if (ajv.getSchema(META_SCHEMA_ID)) return { $ref: META_SCHEMA_ID }; + console.warn('meta schema not defined'); + return {}; +} diff --git a/node_modules/ajv-keywords/keywords/deepProperties.js b/node_modules/ajv-keywords/keywords/deepProperties.js index daa87426a..3dac5fb55 100644 --- a/node_modules/ajv-keywords/keywords/deepProperties.js +++ b/node_modules/ajv-keywords/keywords/deepProperties.js @@ -1,5 +1,7 @@ 'use strict'; +var util = require('./_util'); + module.exports = function defFunc(ajv) { defFunc.definition = { type: 'object', @@ -11,14 +13,11 @@ module.exports = function defFunc(ajv) { }, metaSchema: { type: 'object', - patternProperties: { - '^(\\/([^~\\/]|~0|~1)*)*(\\/)?$': { - $ref: ajv._opts.v5 - ? 'https://raw.githubusercontent.com/epoberezkin/ajv/master/lib/refs/json-schema-v5.json#' - : 'http://json-schema.org/draft-04/schema#' - } + propertyNames: { + type: 'string', + format: 'json-pointer' }, - additionalProperties: false + additionalProperties: util.metaSchemaRef(ajv) } }; diff --git a/node_modules/ajv-keywords/keywords/dot/_formatLimit.jst b/node_modules/ajv-keywords/keywords/dot/_formatLimit.jst index af16b88d8..f74096551 100644 --- a/node_modules/ajv-keywords/keywords/dot/_formatLimit.jst +++ b/node_modules/ajv-keywords/keywords/dot/_formatLimit.jst @@ -33,7 +33,7 @@ var {{=$valid}} = undefined; {{ var $schemaFormat = it.schema.format - , $isDataFormat = it.opts.v5 && $schemaFormat.$data + , $isDataFormat = it.opts.$data && $schemaFormat.$data , $closingBraces = ''; }} @@ -58,7 +58,7 @@ var {{=$valid}} = undefined; var $isMax = $keyword == 'formatMaximum' , $exclusiveKeyword = 'formatExclusive' + ($isMax ? 'Maximum' : 'Minimum') , $schemaExcl = it.schema[$exclusiveKeyword] - , $isDataExcl = it.opts.v5 && $schemaExcl && $schemaExcl.$data + , $isDataExcl = it.opts.$data && $schemaExcl && $schemaExcl.$data , $op = $isMax ? '<' : '>' , $result = 'result' + $lvl; }} diff --git a/node_modules/ajv-keywords/keywords/dot/patternRequired.jst b/node_modules/ajv-keywords/keywords/dot/patternRequired.jst index 9af2cdc9d..6f82f6265 100644 --- a/node_modules/ajv-keywords/keywords/dot/patternRequired.jst +++ b/node_modules/ajv-keywords/keywords/dot/patternRequired.jst @@ -4,16 +4,21 @@ {{ var $key = 'key' + $lvl + , $idx = 'idx' + $lvl , $matched = 'patternMatched' + $lvl + , $dataProperties = 'dataProperties' + $lvl , $closingBraces = '' , $ownProperties = it.opts.ownProperties; }} var {{=$valid}} = true; +{{? $ownProperties }} + var {{=$dataProperties}} = undefined; +{{?}} + {{~ $schema:$pProperty }} var {{=$matched}} = false; - for (var {{=$key}} in {{=$data}}) { - {{# def.checkOwnProperty }} + {{# def.iterateProperties }} {{=$matched}} = {{= it.usePattern($pProperty) }}.test({{=$key}}); if ({{=$matched}}) break; } diff --git a/node_modules/ajv-keywords/keywords/dot/switch.jst b/node_modules/ajv-keywords/keywords/dot/switch.jst index 7b2906a60..389678e34 100644 --- a/node_modules/ajv-keywords/keywords/dot/switch.jst +++ b/node_modules/ajv-keywords/keywords/dot/switch.jst @@ -10,7 +10,7 @@ {{# def._validateSwitchRule:if }} {{ $it.createErrors = true; }} {{# def.resetCompositeRule }} - {{=$ifPassed}} = valid{{=$it.level}}; + {{=$ifPassed}} = {{=$nextValid}}; #}} {{## def.validateThen: @@ -18,7 +18,7 @@ {{? $sch.then === false }} {{# def.error:'switch' }} {{?}} - var valid{{=$it.level}} = {{= $sch.then }}; + var {{=$nextValid}} = {{= $sch.then }}; {{??}} {{# def._validateSwitchRule:then }} {{?}} @@ -68,6 +68,6 @@ var {{=$ifPassed}}; {{= $closingBraces }} -var {{=$valid}} = valid{{=$it.level}}; +var {{=$valid}} = {{=$nextValid}}; {{# def.cleanUp }} diff --git a/node_modules/ajv-keywords/keywords/dotjs/_formatLimit.js b/node_modules/ajv-keywords/keywords/dotjs/_formatLimit.js index b2c5093df..fc56e2064 100644 --- a/node_modules/ajv-keywords/keywords/dotjs/_formatLimit.js +++ b/node_modules/ajv-keywords/keywords/dotjs/_formatLimit.js @@ -1,5 +1,5 @@ 'use strict'; -module.exports = function generate__formatLimit(it, $keyword) { +module.exports = function generate__formatLimit(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; @@ -16,7 +16,7 @@ module.exports = function generate__formatLimit(it, $keyword) { return out; } var $schemaFormat = it.schema.format, - $isDataFormat = it.opts.v5 && $schemaFormat.$data, + $isDataFormat = it.opts.$data && $schemaFormat.$data, $closingBraces = ''; if ($isDataFormat) { var $schemaValueFormat = it.util.getData($schemaFormat.$data, $dataLvl, it.dataPathArr), @@ -34,7 +34,7 @@ module.exports = function generate__formatLimit(it, $keyword) { var $isMax = $keyword == 'formatMaximum', $exclusiveKeyword = 'formatExclusive' + ($isMax ? 'Maximum' : 'Minimum'), $schemaExcl = it.schema[$exclusiveKeyword], - $isDataExcl = it.opts.v5 && $schemaExcl && $schemaExcl.$data, + $isDataExcl = it.opts.$data && $schemaExcl && $schemaExcl.$data, $op = $isMax ? '<' : '>', $result = 'result' + $lvl; var $isData = it.opts.$data && $schema && $schema.$data, diff --git a/node_modules/ajv-keywords/keywords/dotjs/patternRequired.js b/node_modules/ajv-keywords/keywords/dotjs/patternRequired.js index e20df98ca..31bd0b683 100644 --- a/node_modules/ajv-keywords/keywords/dotjs/patternRequired.js +++ b/node_modules/ajv-keywords/keywords/dotjs/patternRequired.js @@ -1,5 +1,5 @@ 'use strict'; -module.exports = function generate_patternRequired(it, $keyword) { +module.exports = function generate_patternRequired(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; @@ -7,29 +7,35 @@ module.exports = function generate_patternRequired(it, $keyword) { var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; - var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; var $key = 'key' + $lvl, + $idx = 'idx' + $lvl, $matched = 'patternMatched' + $lvl, + $dataProperties = 'dataProperties' + $lvl, $closingBraces = '', $ownProperties = it.opts.ownProperties; out += 'var ' + ($valid) + ' = true;'; + if ($ownProperties) { + out += ' var ' + ($dataProperties) + ' = undefined;'; + } var arr1 = $schema; if (arr1) { var $pProperty, i1 = -1, l1 = arr1.length - 1; while (i1 < l1) { $pProperty = arr1[i1 += 1]; - out += ' var ' + ($matched) + ' = false; for (var ' + ($key) + ' in ' + ($data) + ') { '; + out += ' var ' + ($matched) + ' = false; '; if ($ownProperties) { - out += ' if (!Object.prototype.hasOwnProperty.call(' + ($data) + ', ' + ($key) + ')) continue; '; + out += ' ' + ($dataProperties) + ' = ' + ($dataProperties) + ' || Object.keys(' + ($data) + '); for (var ' + ($idx) + '=0; ' + ($idx) + '<' + ($dataProperties) + '.length; ' + ($idx) + '++) { var ' + ($key) + ' = ' + ($dataProperties) + '[' + ($idx) + ']; '; + } else { + out += ' for (var ' + ($key) + ' in ' + ($data) + ') { '; } out += ' ' + ($matched) + ' = ' + (it.usePattern($pProperty)) + '.test(' + ($key) + '); if (' + ($matched) + ') break; } '; var $missingPattern = it.util.escapeQuotes($pProperty); out += ' if (!' + ($matched) + ') { ' + ($valid) + ' = false; var err = '; /* istanbul ignore else */ if (it.createErrors !== false) { - out += ' { keyword: \'' + ($errorKeyword || 'patternRequired') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingPattern: \'' + ($missingPattern) + '\' } '; + out += ' { keyword: \'' + ('patternRequired') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingPattern: \'' + ($missingPattern) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \'should have property matching pattern \\\'' + ($missingPattern) + '\\\'\' '; } diff --git a/node_modules/ajv-keywords/keywords/dotjs/switch.js b/node_modules/ajv-keywords/keywords/dotjs/switch.js index f0e843fe0..d6de28bf9 100644 --- a/node_modules/ajv-keywords/keywords/dotjs/switch.js +++ b/node_modules/ajv-keywords/keywords/dotjs/switch.js @@ -1,5 +1,5 @@ 'use strict'; -module.exports = function generate_switch(it, $keyword) { +module.exports = function generate_switch(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; @@ -7,7 +7,6 @@ module.exports = function generate_switch(it, $keyword) { var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; - var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; var $errs = 'errs__' + $lvl; @@ -41,14 +40,14 @@ module.exports = function generate_switch(it, $keyword) { $it.baseId = $currentBaseId; $it.createErrors = true; it.compositeRule = $it.compositeRule = $wasComposite; - out += ' ' + ($ifPassed) + ' = valid' + ($it.level) + '; if (' + ($ifPassed) + ') { '; + out += ' ' + ($ifPassed) + ' = ' + ($nextValid) + '; if (' + ($ifPassed) + ') { '; if (typeof $sch.then == 'boolean') { if ($sch.then === false) { var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { - out += ' { keyword: \'' + ($errorKeyword || 'switch') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { caseIndex: ' + ($caseIndex) + ' } '; + out += ' { keyword: \'' + ('switch') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { caseIndex: ' + ($caseIndex) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should pass "switch" keyword validation\' '; } @@ -71,7 +70,7 @@ module.exports = function generate_switch(it, $keyword) { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } } - out += ' var valid' + ($it.level) + ' = ' + ($sch.then) + '; '; + out += ' var ' + ($nextValid) + ' = ' + ($sch.then) + '; '; } else { $it.schema = $sch.then; $it.schemaPath = $schemaPath + '[' + $caseIndex + '].then'; @@ -88,7 +87,7 @@ module.exports = function generate_switch(it, $keyword) { $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { - out += ' { keyword: \'' + ($errorKeyword || 'switch') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { caseIndex: ' + ($caseIndex) + ' } '; + out += ' { keyword: \'' + ('switch') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { caseIndex: ' + ($caseIndex) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should pass "switch" keyword validation\' '; } @@ -111,7 +110,7 @@ module.exports = function generate_switch(it, $keyword) { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } } - out += ' var valid' + ($it.level) + ' = ' + ($sch.then) + '; '; + out += ' var ' + ($nextValid) + ' = ' + ($sch.then) + '; '; } else { $it.schema = $sch.then; $it.schemaPath = $schemaPath + '[' + $caseIndex + '].then'; @@ -123,7 +122,7 @@ module.exports = function generate_switch(it, $keyword) { $shouldContinue = $sch.continue } } - out += '' + ($closingBraces) + 'var ' + ($valid) + ' = valid' + ($it.level) + '; '; + out += '' + ($closingBraces) + 'var ' + ($valid) + ' = ' + ($nextValid) + '; '; out = it.util.cleanUpCode(out); return out; } diff --git a/node_modules/ajv-keywords/keywords/if.js b/node_modules/ajv-keywords/keywords/if.js index 014b0dc0b..8a8fc95ee 100644 --- a/node_modules/ajv-keywords/keywords/if.js +++ b/node_modules/ajv-keywords/keywords/if.js @@ -1,7 +1,7 @@ 'use strict'; module.exports = function defFunc(ajv) { - if (!ajv._opts.v5) console.warn('keywords if/then/else require v5 option'); + if (!ajv.RULES.keywords.switch) require('./switch')(ajv); defFunc.definition = { macro: function (schema, parentSchema) { diff --git a/node_modules/ajv-keywords/keywords/index.js b/node_modules/ajv-keywords/keywords/index.js index 931aa6ad3..06b68b776 100644 --- a/node_modules/ajv-keywords/keywords/index.js +++ b/node_modules/ajv-keywords/keywords/index.js @@ -2,17 +2,18 @@ module.exports = { 'instanceof': require('./instanceof'), - propertyNames: require('./propertyNames'), range: require('./range'), regexp: require('./regexp'), 'typeof': require('./typeof'), dynamicDefaults: require('./dynamicDefaults'), 'if': require('./if'), prohibited: require('./prohibited'), + uniqueItemProperties: require('./uniqueItemProperties'), deepProperties: require('./deepProperties'), - deepRequired: require('./deepRequired') - // formatMinimum: require('./formatMinimum'), - // formatMaximum: require('./formatMaximum'), - // patternRequired: require('./patternRequired'), - // 'switch': require('./switch') + deepRequired: require('./deepRequired'), + formatMinimum: require('./formatMinimum'), + formatMaximum: require('./formatMaximum'), + patternRequired: require('./patternRequired'), + 'switch': require('./switch'), + select: require('./select') }; diff --git a/node_modules/ajv-keywords/keywords/patternRequired.js b/node_modules/ajv-keywords/keywords/patternRequired.js index f3f4ee903..046f313fd 100644 --- a/node_modules/ajv-keywords/keywords/patternRequired.js +++ b/node_modules/ajv-keywords/keywords/patternRequired.js @@ -1,9 +1,6 @@ 'use strict'; module.exports = function defFunc(ajv) { - if (ajv.RULES.keywords.patternRequired) - return console.warn('Keyword patternRequired is already defined'); - defFunc.definition = { type: 'object', inline: require('./dotjs/patternRequired'), diff --git a/node_modules/ajv-keywords/keywords/propertyNames.js b/node_modules/ajv-keywords/keywords/propertyNames.js deleted file mode 100644 index 987f236c0..000000000 --- a/node_modules/ajv-keywords/keywords/propertyNames.js +++ /dev/null @@ -1,51 +0,0 @@ -'use strict'; - -module.exports = function defFunc(ajv) { - defFunc.definition = { - type: 'object', - compile: function(schema) { - var validate = ajv.compile(schema); - return ajv._opts.allErrors ? vAllErrors : vBreakOnError; - - function vBreakOnError(data) { - for (var prop in data) { - if (!validate(prop)) { - vBreakOnError.errors = validate.errors; - addPropertyNameError(vBreakOnError.errors, prop); - return false; - } - } - return true; - } - - function vAllErrors(data) { - var errors = []; - for (var prop in data) { - if (!validate(prop)) { - errors = errors.concat(validate.errors); - addPropertyNameError(errors, prop); - } - } - if (errors.length) vAllErrors.errors = errors; - return errors.length == 0; - } - - function addPropertyNameError(errors, propName) { - errors.push({ - keyword: 'propertyNames', - params: { propertyName: propName }, - message: 'should have valid property name of "' + propName + '"' - }); - } - }, - metaSchema: { - $ref: ajv._opts.v5 - ? 'https://raw.githubusercontent.com/epoberezkin/ajv/master/lib/refs/json-schema-v5.json#' - : 'http://json-schema.org/draft-04/schema#' - }, - errors: true - }; - - ajv.addKeyword('propertyNames', defFunc.definition); - return ajv; -}; diff --git a/node_modules/ajv-keywords/keywords/range.js b/node_modules/ajv-keywords/keywords/range.js index 3f25ac24f..9c1fd3ffd 100644 --- a/node_modules/ajv-keywords/keywords/range.js +++ b/node_modules/ajv-keywords/keywords/range.js @@ -10,12 +10,9 @@ module.exports = function defFunc(ajv) { validateRangeSchema(min, max, exclusive); - return { - minimum: min, - exclusiveMinimum: exclusive, - maximum: max, - exclusiveMaximum: exclusive - }; + return exclusive === true + ? {exclusiveMinimum: min, exclusiveMaximum: max} + : {minimum: min, maximum: max}; }, metaSchema: { type: 'array', diff --git a/node_modules/ajv-keywords/keywords/select.js b/node_modules/ajv-keywords/keywords/select.js new file mode 100644 index 000000000..f79c6c7a0 --- /dev/null +++ b/node_modules/ajv-keywords/keywords/select.js @@ -0,0 +1,79 @@ +'use strict'; + +var util = require('./_util'); + +module.exports = function defFunc(ajv) { + if (!ajv._opts.$data) { + console.warn('keyword select requires $data option'); + return ajv; + } + var metaSchemaRef = util.metaSchemaRef(ajv); + var compiledCaseSchemas = []; + + defFunc.definition = { + validate: function v(schema, data, parentSchema) { + if (parentSchema.selectCases === undefined) + throw new Error('keyword "selectCases" is absent'); + var compiled = getCompiledSchemas(parentSchema, false); + var validate = compiled.cases[schema]; + if (validate === undefined) validate = compiled.default; + if (typeof validate == 'boolean') return validate; + var valid = validate(data); + if (!valid) v.errors = validate.errors; + return valid; + }, + $data: true, + metaSchema: { type: ['string', 'number', 'boolean', 'null'] } + }; + + ajv.addKeyword('select', defFunc.definition); + ajv.addKeyword('selectCases', { + compile: function (schemas, parentSchema) { + var compiled = getCompiledSchemas(parentSchema); + for (var value in schemas) + compiled.cases[value] = compileOrBoolean(schemas[value]); + return function() { return true; }; + }, + valid: true, + metaSchema: { + type: 'object', + additionalProperties: metaSchemaRef + } + }); + ajv.addKeyword('selectDefault', { + compile: function (schema, parentSchema) { + var compiled = getCompiledSchemas(parentSchema); + compiled.default = compileOrBoolean(schema); + return function() { return true; }; + }, + valid: true, + metaSchema: metaSchemaRef + }); + return ajv; + + + function getCompiledSchemas(parentSchema, create) { + var compiled; + compiledCaseSchemas.some(function (c) { + if (c.parentSchema === parentSchema) { + compiled = c; + return true; + } + }); + if (!compiled && create !== false) { + compiled = { + parentSchema: parentSchema, + cases: {}, + default: true + }; + compiledCaseSchemas.push(compiled); + } + return compiled; + } + + function compileOrBoolean(schema) { + return typeof schema == 'boolean' + ? schema + : ajv.compile(schema); + } +}; diff --git a/node_modules/ajv-keywords/keywords/switch.js b/node_modules/ajv-keywords/keywords/switch.js index 8c22bf8b9..5b0f3f830 100644 --- a/node_modules/ajv-keywords/keywords/switch.js +++ b/node_modules/ajv-keywords/keywords/switch.js @@ -1,12 +1,11 @@ 'use strict'; +var util = require('./_util'); + module.exports = function defFunc(ajv) { - if (ajv.RULES.keywords.switch) - return console.warn('Keyword switch is already defined'); + if (ajv.RULES.keywords.switch && ajv.RULES.keywords.if) return; - var metaSchemaUri = ajv._opts.v5 - ? 'https://raw.githubusercontent.com/epoberezkin/ajv/master/lib/refs/json-schema-v5.json#' - : 'http://json-schema.org/draft-04/schema#'; + var metaSchemaRef = util.metaSchemaRef(ajv); defFunc.definition = { inline: require('./dotjs/switch'), @@ -17,11 +16,11 @@ module.exports = function defFunc(ajv) { items: { required: [ 'then' ], properties: { - 'if': { $ref: metaSchemaUri }, + 'if': metaSchemaRef, 'then': { anyOf: [ { type: 'boolean' }, - { $ref: metaSchemaUri } + metaSchemaRef ] }, 'continue': { type: 'boolean' } diff --git a/node_modules/ajv-keywords/keywords/uniqueItemProperties.js b/node_modules/ajv-keywords/keywords/uniqueItemProperties.js new file mode 100644 index 000000000..2a8e7e841 --- /dev/null +++ b/node_modules/ajv-keywords/keywords/uniqueItemProperties.js @@ -0,0 +1,32 @@ +'use strict'; + +module.exports = function defFunc(ajv) { + defFunc.definition = { + type: 'array', + compile: function(keys, parentSchema, it) { + var equal = it.util.equal; + return function(data) { + if (data.length > 1) { + for (var k=0; k < keys.length; k++) { + var key = keys[k]; + for (var i = data.length; i--;) { + if (typeof data[i] != 'object') continue; + for (var j = i; j--;) { + if (typeof data[j] == 'object' && equal(data[i][key], data[j][key])) + return false; + } + } + } + } + return true; + }; + }, + metaSchema: { + type: 'array', + items: {type: 'string'} + } + }; + + ajv.addKeyword('uniqueItemProperties', defFunc.definition); + return ajv; +}; diff --git a/node_modules/ajv-keywords/package.json b/node_modules/ajv-keywords/package.json index 485b8eb5e..6d5ae698e 100644 --- a/node_modules/ajv-keywords/package.json +++ b/node_modules/ajv-keywords/package.json @@ -1,7 +1,7 @@ { "name": "ajv-keywords", - "version": "1.5.1", - "description": "Custom JSON-Schema keywords for ajv validator", + "version": "2.1.0", + "description": "Custom JSON-Schema keywords for Ajv validator", "main": "index.js", "scripts": { "build": "node node_modules/ajv/scripts/compile-dots.js node_modules/ajv/lib keywords", @@ -31,11 +31,11 @@ }, "homepage": "https://github.com/epoberezkin/ajv-keywords#readme", "peerDependencies": { - "ajv": ">=4.10.0" + "ajv": ">=5.0.0" }, "devDependencies": { - "ajv": "^4.10.0", - "ajv-pack": "^0.2.0", + "ajv": "^5.0.0", + "ajv-pack": "^0.3.0", "chai": "^3.5.0", "coveralls": "^2.11.9", "dot": "^1.1.1", @@ -43,7 +43,7 @@ "glob": "^7.1.1", "istanbul": "^0.4.3", "js-beautify": "^1.6.4", - "json-schema-test": "^1.2.1", + "json-schema-test": "^1.3.0", "mocha": "^3.0.2", "pre-commit": "^1.1.3", "uuid": "^3.0.1" |