pax_global_header 0000666 0000000 0000000 00000000064 13075146637 0014526 g ustar 00root root 0000000 0000000 52 comment=8641c6b23a04aae7f73ddece698fa598266dc5ae
ajv-5.0.0/ 0000775 0000000 0000000 00000000000 13075146637 0012310 5 ustar 00root root 0000000 0000000 ajv-5.0.0/.codeclimate.yml 0000664 0000000 0000000 00000000036 13075146637 0015361 0 ustar 00root root 0000000 0000000 exclude_paths:
- lib/dotjs/**
ajv-5.0.0/.eslintrc.yml 0000664 0000000 0000000 00000001213 13075146637 0014731 0 ustar 00root root 0000000 0000000 extends: eslint:recommended
env:
node: true
browser: true
rules:
block-scoped-var: 2
callback-return: 2
complexity: [2, 13]
curly: [2, multi-or-nest, consistent]
dot-location: [2, property]
dot-notation: 2
indent: [2, 2, SwitchCase: 1]
linebreak-style: [2, unix]
new-cap: 2
no-console: [2, allow: [warn, error]]
no-else-return: 2
no-eq-null: 2
no-fallthrough: 2
no-invalid-this: 2
no-return-assign: 2
no-shadow: 1
no-trailing-spaces: 2
no-use-before-define: [2, nofunc]
quotes: [2, single, avoid-escape]
semi: [2, always]
strict: [2, global]
valid-jsdoc: [2, requireReturn: false]
no-control-regex: 0
ajv-5.0.0/.github/ 0000775 0000000 0000000 00000000000 13075146637 0013650 5 ustar 00root root 0000000 0000000 ajv-5.0.0/.github/ISSUE_TEMPLATE.md 0000664 0000000 0000000 00000002513 13075146637 0016356 0 ustar 00root root 0000000 0000000
**What version of Ajv are you using? Does the issue happen if you use the latest version?**
**Ajv options object (see https://github.com/epoberezkin/ajv#options):**
```javascript
```
**JSON Schema (please make it as small as possible to reproduce the issue):**
```json
```
**Data (please make it as small as posssible to reproduce the issue):**
```json
```
**Your code (please use `options`, `schema` and `data` as variables):**
```javascript
```
**Validation result, data AFTER validation, error messages:**
```
```
**What results did you expect?**
**Are you going to resolve the issue?**
ajv-5.0.0/.github/PULL_REQUEST_TEMPLATE.md 0000664 0000000 0000000 00000001027 13075146637 0017451 0 ustar 00root root 0000000 0000000
**What issue does this pull request resolve?**
**What changes did you make?**
**Is there anything that requires more attention while reviewing?**
ajv-5.0.0/.gitignore 0000664 0000000 0000000 00000001172 13075146637 0014301 0 ustar 00root root 0000000 0000000 # Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
.DS_Store
# Compiled templates
lib/dotjs/*.js
# Browserified tests
.browser
# bundles
dist/
ajv-5.0.0/.gitmodules 0000664 0000000 0000000 00000000217 13075146637 0014465 0 ustar 00root root 0000000 0000000 [submodule "spec/JSON-Schema-Test-Suite"]
path = spec/JSON-Schema-Test-Suite
url = https://github.com/json-schema/JSON-Schema-Test-Suite.git
ajv-5.0.0/.tonic_example.js 0000664 0000000 0000000 00000000663 13075146637 0015560 0 ustar 00root root 0000000 0000000 var Ajv = require('ajv');
var ajv = Ajv({allErrors: true});
var schema = {
"properties": {
"foo": { "type": "string" },
"bar": { "type": "number", "maximum": 3 }
}
};
var validate = ajv.compile(schema);
test({"foo": "abc", "bar": 2});
test({"foo": 2, "bar": 4});
function test(data) {
var valid = validate(data);
if (valid) console.log('Valid!');
else console.log('Invalid: ' + ajv.errorsText(validate.errors));
} ajv-5.0.0/.travis.yml 0000664 0000000 0000000 00000000703 13075146637 0014421 0 ustar 00root root 0000000 0000000 language: node_js
before_script:
- git submodule update --init
- npm install -g codeclimate-test-reporter
node_js:
- "0.12"
- "4"
- "5"
- "6"
- "7"
after_script:
- codeclimate-test-reporter < coverage/lcov.info
- coveralls < coverage/lcov.info
- scripts/travis-gh-pages
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/9cab5fe0c9595511cd81
on_success: change
on_failure: always
on_start: never
ajv-5.0.0/COERCION.md 0000664 0000000 0000000 00000010162 13075146637 0014033 0 ustar 00root root 0000000 0000000 # Ajv type coercion rules
To enable type coercion pass option `coerceTypes` to Ajv with `true` or `array` (it is `false` by default). See [example](https://github.com/epoberezkin/ajv#coercing-data-types).
The coercion rules are different from JavaScript:
- to validate user input as expected
- to have the coercion reversible
- to correctly validate cases where different types are required in subschemas (e.g., in `anyOf`).
Type coercion only happens if there is `type` keyword and if without coercion the validation would have failed. If coercion to the required type succeeds then the validation continues to other keywords, otherwise the validation fails.
If there are multiple types allowed in `type` keyword the coercion will only happen if none of the types match the data and some of the scalar types are present (coercion to/from `object`/`array` is not possible). In this case the validating function will try coercing the data to each type in order until some of them succeeds.
Application of these rules can have some unexpected consequences. Ajv may coerce the same value multiple times (this is why coercion reversibility is required) as needed at different points in the schema. This is particularly evident when using `oneOf`, which must test all of the subschemas. Ajv will coerce the type for each subschema, possibly resulting in unexpected failure if it can coerce to match more than one of the subschemas. Even if it succeeds, Ajv will not backtrack, so you'll get the type of the final coercion even if that's not the one that allowed the data to pass validation. If possible, structure your schema with `anyOf`, which won't validate subsequent subschemas as soon as it encounters one subschema that matches.
Possible type coercions:
|from type →
to type ↓|string|number|boolean|null|array*|
|---|:-:|:-:|:-:|:-:|:-:|
|string |-|`x`→`""+x`|`false`→`"false"`
`true`→`"true"`|`null`→`""`|`[x]`→`x`|
|number /
integer|Valid number /
integer: `x`→`+x`
|-|`false`→`0`
`true`→`1`|`null`→`0`|`[x]`→`x`|
|boolean |`"false"`→`false`
`"true"`→`true`
`"abc"`⇸
`""`⇸|`0`→`false`
`1`→`true`
`x`⇸|-|`null`→`false`|`[false]`→`false`
`[true]`→`true`|
|null |`""`→`null`
`"null"`⇸
`"abc"`⇸|`0`→`null`
`x`⇸|`false`→`null`
`true`⇸|-|`[null]`→`null`|
|array* |`x`→`[x]`|`x`→`[x]`|`false`→`[false]`
`true`→`[true]`|`null`→`[null]`|-|
\* Requires option `{coerceTypes: 'array'}`
## Coercion from string values
#### To number type
Coercion to `number` is possible if the string is a valid number, `+data` is used.
#### To integer type
Coercion to `integer` is possible if the string is a valid number without fractional part (`data % 1 === 0`).
#### To boolean type
Unlike JavaScript, only these strings can be coerced to `boolean`:
- `"true"` -> `true`
- `"false"` -> `false`
#### To null type
Empty string is coerced to `null`, other strings can't be coerced.
## Coercion from number values
#### To string type
Always possible, `'' + data` is used
#### To boolean type
Unlike JavaScript, only these numbers can be coerced to `boolean`:
- `1` -> `true`
- `0` -> `false`
#### To null type
`0` coerces to `null`, other numbers can't be coerced.
## Coercion from boolean values
#### To string type
- `true` -> `"true"`
- `false` -> `"false"`
#### To number/integer types
- `true` -> `1`
- `false` -> `0`
#### To null type
`false` coerces to `null`, `true` can't be coerced.
## Coercion from null
#### To string type
`null` coerses to the empty string.
#### To number/integer types
`null` coerces to `0`
#### To boolean type
`null` coerces to `false`
## Coercion to and from array
These coercions require that the option `coerceTypes` is `"array"`.
If a scalar data is present and array is required, Ajv wraps scalar data in an array.
If an array with one item is present and a scalar is required, Ajv coerces array into its item.
- `"foo"` -> `[ "foo" ]`
- `[ "foo" ]` -> `"foo"`
ajv-5.0.0/CONTRIBUTING.md 0000664 0000000 0000000 00000016742 13075146637 0014553 0 ustar 00root root 0000000 0000000 # Contributing
Thank you for your help making Ajv better! Every contribution is appreciated. If you plan to implement a new feature or some other change please create an issue first, to make sure that your work is not lost.
- [Documentation](#documentation)
- [Issues](#issues)
- [Bug reports](#bug-reports)
- [Change proposals](#changes)
- [Browser and compatibility issues](#compatibility)
- [JSON schema standard](#json-schema)
- [Ajv usage questions](#usage)
- [Code](#code)
- [Development](#development)
- [Pull requests](#pull-requests)
- [Contributions license](#contributions-license)
## Documentation
Ajv has a lot of features and maintaining documentation takes time. I appreciate the time you spend correcting or clarifying the documentation.
## Issues
Before submitting the issue please search the existing issues and also review [Frequently Asked Questions](https://github.com/epoberezkin/ajv/blob/master/FAQ.md).
I would really appreciate the time you spend providing all the information and reducing both your schema and data to the smallest possible size when they still have the issue. Simplifying the issue also makes it more valuable for other users (in cases it turns out to be an incorrect usage rather than a bug).
#### Bug reports
Please make sure to include the following information in the issue:
1. What version of Ajv are you using? Does the issue happen if you use the latest version?
2. Ajv options object (see https://github.com/epoberezkin/ajv#options).
3. JSON schema and the data you are validating (please make it as small as possible to reproduce the issue).
4. Your code (please use `options`, `schema` and `data` as variables).
5. Validation result, data AFTER validation, error messages.
6. What results did you expect?
[Create bug report](https://github.com/epoberezkin/ajv/issues/new).
#### Change proposals
[Create a proposal](https://github.com/epoberezkin/ajv/issues/new?labels=suggestion&body=**What%20version%20of%20Ajv%20you%20are%20you%20using%3F**%0A%0A**What%20problem%20do%20you%20want%20to%20solve%3F**%0A%0A**What%20do%20you%20think%20is%20the%20correct%20solution%20to%20problem?**%0A%0A**Will%20you%20be%20able%20to%20implement%20it%3F**%0A%0A) for a new feature, option or some other improvement.
Please include this information:
1. The version of Ajv you are using.
2. The problem you want to solve.
3. What do you think is the correct solution to problem?
4. Will you be able to implement it?
If you’re requesting a change, it would be helpful to include this as well:
1. What you did.
2. What you would like to happen.
3. What actually happened.
Please include as much details as possible.
#### Browser and compatibility issues
[Create an issue](https://github.com/epoberezkin/ajv/issues/new?labels=compatibility&body=**The%20version%20of%20Ajv%20you%20are%20using**%0A%0A**The%20environment%20you%20have%20the%20problem%20with.**%0A%0A**Your%20code%20(please%20make%20it%20as%20small%20as%20possible%20to%20reproduce%20the%20issue).**%0A%0A**If%20your%20issue%20is%20in%20the%20browser,%20please%20list%20the%20other%20packages%20loaded%20in%20the%20page%20in%20the%20order%20they%20are%20loaded.%20Please%20check%20if%20the%20issue%20gets%20resolved%20(or%20results%20change)%20if%20you%20move%20Ajv%20bundle%20closer%20to%20the%20top.**%0A%0A**Results%20in%20node.js%20v4.**%0A%0A**Results%20and%20error%20messages%20in%20your%20platform.**%0A%0A) to report a compatibility problem that only happens in a particular environemnt (when your code works correctly in node.js v4 in linux systems but fails in some other environment).
Please include this information:
1. The version of Ajv you are using.
2. The environment you have the problem with.
3. Your code (please make it as small as possible to reproduce the issue).
4. If your issue is in the browser, please list the other packages loaded in the page in the order they are loaded. Please check if the issue gets resolved (or results change) if you move Ajv bundle closer to the top.
5. Results in node.js v4.
6. Results and error messages in your platform.
#### Using JSON schema standard
Ajv implements JSON schema standard draft 4 and the proposed extensions for the next version of the standard (available when you use the option `v5: true`).
If the issue is related to using v5 extensions please submit it as a [bug report](https://github.com/epoberezkin/ajv/issues/new).
If it is a general issue related to using the standard keywords included in JSON Schema or implementing some advanced validation logic please ask the question on [Stack Overflow](http://stackoverflow.com/questions/ask?tags=jsonschema,ajv) (my account is [esp](http://stackoverflow.com/users/1816503/esp)) or submitting the question to [JSON-Schema.org](https://github.com/json-schema-org/json-schema-spec/issues/new). Please mention @epoberezkin.
#### Ajv usage questions
The best place to ask a question about using Ajv is [Gitter chat](https://gitter.im/ajv-validator/ajv).
If the question is advanced, it can be submitted to [Stack Overflow](http://stackoverflow.com/questions/ask?tags=jsonschema,ajv).
## Code
Thanks a lot for considering contributing to Ajv. Many very useful features were created by its users.
#### Development
Running tests:
```bash
npm install
git submodule update --init
npm test
```
The full test suite runs for 3 minutes. If your change is trivial you can run quick test before committing (10 sec) and then disable pre-commit hook:
```bash
npm run test-fast
git commit -nm 'type: message'
```
All validation functions are generated using doT templates in [dot](https://github.com/epoberezkin/ajv/tree/master/lib/dot) folder. Templates are precompiled so doT is not a run-time dependency.
`npm run build` - compiles templates to [dotjs](https://github.com/epoberezkin/ajv/tree/master/lib/dotjs) folder.
`npm run watch` - automatically compiles templates when files in dot folder change
#### Pull requests
To make accepting your changes faster please follow these steps:
1. Submit an [issue with the bug](https://github.com/epoberezkin/ajv/issues/new) or with the proposed change (unless the contribution is to fix the documentation typos and mistakes).
2. Please describe the proposed api and implementation plan (unless the issue is a relatively simple bug and fixing it doesn't change any api).
3. Once agreed, please write as little code as possible to achieve the desired result.
4. Please avoid unnecessary changes, refactoring or changing coding styles as part of your change (unless the change was proposed as refactoring).
5. Please follow the coding conventions even if they are not validated (and/or you use different conventions in your code).
6. Please run the tests before committing your code.
7. If tests fail in Travis after you make a PR please investigate and fix the issue.
#### Contributions license
When contributing the code you confirm that:
1. Your contribution is created by you.
2. You have the right to submit it under the MIT license.
3. You understand and agree that your contribution is public, will be stored indefinitely, can be redistributed as the part of Ajv or another related package under MIT license, modified or completely removed from Ajv.
4. You grant irrevocable MIT license to use your contribution as part of Ajv or another related package.
5. You waive all rights to your contribution.
6. Unless you request otherwise, you can be mentioned as the author of the contribution in the Ajv documentation and change log.
ajv-5.0.0/CUSTOM.md 0000664 0000000 0000000 00000051316 13075146637 0013652 0 ustar 00root root 0000000 0000000 # Defining custom keywords
## Contents
- Define keyword with:
- [validation function](#define-keyword-with-validation-function)
- [compilation function](#define-keyword-with-compilation-function)
- [macro function](#define-keyword-with-macro-function)
- [inline compilation function](#define-keyword-with-inline-compilation-function)
- [Schema compilation context](#schema-compilation-context)
- [Validation time variables](#validation-time-variables)
- [Ajv utilities](#ajv-utilities)
- [Reporting errors in custom keywords](#reporting-errors-in-custom-keywords)
- [Short-circuit validation](#short-circuit-validation)
### Define keyword with validation function
Validation function will be called during data validation and it will be passed:
- schema
- data
- parent schema
- current data path
- parent data object
- the property name in the parent data object
- the root data
The access to the parent data object and the current property name allow to create keywords that modify the validated data (`modifying` option MUST be used in keyword definition in this case).
The function should return validation result as boolean. It can return an array of validation errors via `.errors` property of itself (otherwise a standard error will be used).
This way to define keywords is useful for:
- testing your keywords before converting them to compiled/inlined keywords
- defining keywords that do not depend on the schema value (e.g., when the value is always `true`). In this case you can add option `schema: false` to the keyword definition and the schemas won't be passed to the validation function, it will only receive the same 4 parameters as compiled validation function (see the next section).
- defining keywords where the schema is a value used in some expression.
- defining keywords that support [$data reference](https://github.com/epoberezkin/ajv#data-reference) - in this case validation function is required, either as the only option or in addition to compile, macro or inline function (see below).
__Please note__: In cases when validation flow is different depending on the schema and you have to use `if`s, this way to define keywords will have worse performance than compiled keyword returning different validation functions depending on the schema.
Example. `constant` keyword (a synonym for draft6 keyword `const`, it is equivalent to `enum` keyword with one item):
```javascript
ajv.addKeyword('constant', { validate: function (schema, data) {
return typeof schema == 'object' && schema !== null
? deepEqual(schema, data)
: schema === data;
}, errors: false });
var schema = { "constant": 2 };
var validate = ajv.compile(schema);
console.log(validate(2)); // true
console.log(validate(3)); // false
var schema = { "constant": { "foo": "bar" } };
var validate = ajv.compile(schema);
console.log(validate({foo: 'bar'})); // true
console.log(validate({foo: 'baz'})); // false
```
`const` keyword is already available in Ajv.
__Please note:__ If the keyword does not define custom errors (see [Reporting errors in custom keywords](#reporting-errors-in-custom-keywords)) pass `errors: false` in its definition; it will make generated code more efficient.
To add asynchronous keyword pass `async: true` in its definition.
### Define keyword with "compilation" function
Compilation function will be called during schema compilation. It will be passed schema, parent schema and [schema compilation context](#schema-compilation-context) and it should return a validation function. This validation function will be passed during validation:
- data
- current data path
- parent data object
- the property name in the parent data object
- the root data
The access to the parent data object and the current property name allow to create keywords that modify the validated data (`modifying` option MUST be used).
The function should return validation result as boolean. It can return an array of validation errors via `.errors` property of itself (otherwise a standard error will be used).
In some cases it is the best approach to define keywords, but it has the performance cost of an extra function call during validation. If keyword logic can be expressed via some other JSON-schema then `macro` keyword definition is more efficient (see below).
All custom keywords types can have an optional `metaSchema` property in their definitions. It is a schema against which the value of keyword will be validated during schema compilation.
Example. `range` and `exclusiveRange` keywords using compiled schema:
```javascript
ajv.addKeyword('range', { type: 'number', compile: function (sch, parentSchema) {
var min = sch[0];
var max = sch[1];
return parentSchema.exclusiveRange === true
? function (data) { return data > min && data < max; }
: function (data) { return data >= min && data <= max; }
}, errors: false, metaSchema: {
type: 'array',
items: [ { type: 'number' }, { type: 'number' } ],
additionalItems: false
} });
var schema = { "range": [2, 4], "exclusiveRange": true };
var validate = ajv.compile(schema);
console.log(validate(2.01)); // true
console.log(validate(3.99)); // true
console.log(validate(2)); // false
console.log(validate(4)); // false
```
See note on custom errors and asynchronous keywords in the previous section.
### Define keyword with "macro" function
"Macro" function is called during schema compilation. It is passed schema, parent schema and [schema compilation context](#schema-compilation-context) and it should return another schema that will be applied to the data in addition to the original schema.
It is the most efficient approach (in cases when the keyword logic can be expressed with another JSON-schema) because it is usually easy to implement and there is no extra function call during validation.
In addition to the errors from the expanded schema macro keyword will add its own error in case validation fails.
Example. `range` and `exclusiveRange` keywords from the previous example defined with macro:
```javascript
ajv.addKeyword('range', { type: 'number', macro: function (schema, parentSchema) {
return {
minimum: schema[0],
maximum: schema[1],
exclusiveMinimum: !!parentSchema.exclusiveRange,
exclusiveMaximum: !!parentSchema.exclusiveRange
};
}, metaSchema: {
type: 'array',
items: [ { type: 'number' }, { type: 'number' } ],
additionalItems: false
} });
```
Example. `contains` keyword from version 5 proposals that requires that the array has at least one item matching schema (see https://github.com/json-schema/json-schema/wiki/contains-(v5-proposal)):
```javascript
ajv.addKeyword('contains', { type: 'array', macro: function (schema) {
return { "not": { "items": { "not": schema } } };
} });
var schema = {
"contains": {
"type": "number",
"minimum": 4,
"exclusiveMinimum": true
}
};
var validate = ajv.compile(schema);
console.log(validate([1,2,3])); // false
console.log(validate([2,3,4])); // false
console.log(validate([3,4,5])); // true, number 5 matches schema inside "contains"
```
`contains` keyword is already available in Ajv with option `v5: true`.
See the example of defining recursive macro keyword `deepProperties` in the [test](https://github.com/epoberezkin/ajv/blob/master/spec/custom.spec.js#L151).
### Define keyword with "inline" compilation function
Inline compilation function is called during schema compilation. It is passed four parameters: `it` (the current schema compilation context), `keyword` (added in v3.0 to allow defining multiple keywords with a single function), `schema` and `parentSchema` and it should return the code (as a string) that will be inlined in the code of compiled schema. This code can be either an expression that evaluates to the validation result (boolean) or a set of statements that assigns the validation result to a variable.
While it can be more challenging to define keywords with "inline" functions, it has several advantages:
- the best performance
- the precise control over validation process
- access to the parent data and the path to the currently validated data
- access to Ajv utilities via `it.util`
Example `even` keyword:
```javascript
ajv.addKeyword('even', { type: 'number', inline: function (it, keyword, schema) {
var op = schema ? '===' : '!==';
return 'data' + (it.dataLevel || '') + ' % 2 ' + op + ' 0';
}, metaSchema: { type: 'boolean' } });
var schema = { "even": true };
var validate = ajv.compile(schema);
console.log(validate(2)); // true
console.log(validate(3)); // false
```
`'data' + (it.dataLevel || '')` in the example above is the reference to the currently validated data. Also note that `schema` (keyword schema) is the same as `it.schema.even`, so schema is not strictly necessary here - it is passed for convenience.
Example `range` keyword defined using [doT template](https://github.com/olado/doT):
```javascript
// {% raw %}
var doT = require('dot');
var inlineRangeTemplate = doT.compile("\
{{ \
var $data = 'data' + (it.dataLevel || '') \
, $min = it.schema.range[0] \
, $max = it.schema.range[1] \
, $gt = it.schema.exclusiveRange ? '>' : '>=' \
, $lt = it.schema.exclusiveRange ? '<' : '<='; \
}} \
var valid{{=it.level}} = {{=$data}} {{=$gt}} {{=$min}} && {{=$data}} {{=$lt}} {{=$max}}; \
");
ajv.addKeyword('range', {
type: 'number',
inline: inlineRangeTemplate,
statements: true,
metaSchema: {
type: 'array',
items: [ { type: 'number' }, { type: 'number' } ],
additionalItems: false
}
});
// {% endraw %}
```
`'valid' + it.level` in the example above is the expected name of the variable that should be set to the validation result.
Property `statements` in the keyword definition should be set to `true` if the validation code sets the variable instead of evaluating to the validation result.
The main challenge of defining inline keywords is that you have to write both the code that will execute during schema compilation (compile-time) and the code that will execute during data validation (validation-time - this code can be generated either using strings concatenation or using templates, see the examples below).
Ajv uses [doT templates](https://github.com/olado/doT) to generate the code of validation functions that makes it easier to separate compile-time and validation-time code because of the different syntax used in templates and in the code. Ajv also uses different variable names for compile-time and validation-time variables to make it easier to differentiate - compile-time variable names start with $ character.
Also you have to bear in mind that while compile-time variables exist in the scope of the function you wrote to compile the keyword, so they are isolated, validation-time variables share the scope with all the variables in the scope of a single validation function. So if your keyword has subschemas you have to append the schema level (`it.level`) to the variable names.
See [schema compilation context](#schema-compilation-context) for more information on which properties and utilities from the schema compilation context you can use.
## Schema compilation context
The first parameter passed to inline keyword compilation function (and the 3rd parameter passed to compile and macro keyword functions) is `it`, the schema compilation context. All the properties and functions documented here are safe to use in your keywords, they won't be renamed or change their meaning without major version change.
`it` object has the following properties:
- _level_ - the level of the current schema, `0` on the top level, `1` in subschemas (e.g. schemas in `properties` or `anyOf` keyword). The value of this property should be appended to the validation-time variables you use in the generated code.
- _dataLevel_ - the level of the currently validated data. It can be used to access both the property names and the data on all levels from the top. See [Validation time variables](#validation-time-variables).
- _schema_ - current level schema. The value of your keyword is `it.schema[keyword]`. This value is also passed as the 3rd parameter to the inline compilation function and the current level schema as the 4th parameter.
- _schemaPath_ - the validation time expression that evaluates to the property name of the current schema.
- _baseId_ - the current schema base URI that should be used as the base for resolving URIs in references ($ref).
- _async_ - truthy if the current schema is asynchronous.
- _opts_ - Ajv instance option. You should not be changing them.
- _formats_ - all formats available in Ajv instance, including the custom ones.
- _compositeRule_ - boolean indicating that the current schema is inside the compound keyword where failing some rule doesn't mean validation failure (`anyOf`, `oneOf`, `not`, `if` in `switch`). This flag is used to determine whether you can return validation result immediately after any error in case the option `allErrors` is not `true. You only need to do it if you have many steps in your keywords and potentially can define multiple errors.
- _validate_ - the function you need to use to compile subschemas in your keywords (see the [implementation](https://github.com/epoberezkin/ajv/blob/master/lib/dot/v5/switch.jst) of `switch` keyword for example).
- _util_ - [Ajv utilities](#ajv-utilities) you can use in your inline compilation functions.
- _self_ - Ajv instance.
## Validation time variables
There is a number of variables and expressions you can use in the generated (validation-time) code of your keywords.
- `'data' + (it.dataLevel || '')` - the variable name for the data at the current level.
- `'data' + ((it.dataLevel-1)||'')` - parent data if `it.dataLevel > 0`.
- `'rootData'` - the root data.
- `it.dataPathArr[it.dataLevel]` - the name of the property in the parent object that points to the current data if `it.dataLevel > 0`.
- `'validate.schema'` - top level schema of the current validation function at validation-time.
- `'validate.schema' + it.schemaPath` - current level schema available at validation time (the same schema at compile time is `it.schema`).
- `'validate.schema' + it.schemaPath + '.' + keyword` - the value of your custom keyword at validation-time. Keyword is passed as the second parameter to the inline compilation function to allow using the same function to compile multiple keywords.
- `'valid' + it.level` - the variable that you have to declare and to assign the validation result to if your keyword returns statements rather than expression (`statements: true`).
- `'errors'` - the number of encountered errors. See [Reporting errors in custom keywords](https://github.com/epoberezkin/ajv/blob/master/CUSTOM.md#reporting-errors-in-custom-keywords).
- `'vErrors'` - the array with errors collected so far. See [Reporting errors in custom keywords](https://github.com/epoberezkin/ajv/blob/master/CUSTOM.md#reporting-errors-in-custom-keywords).
## Ajv utilities
There are sevral useful functions you can use in your inline keywords. These functions are available as properties of `it.util` object:
##### .copy(Object obj[, Object target]) -> Object
Clone or extend the object. If one object is passed, it is cloned. If two objects are passed, the second object is extended with the properties of the first.
##### .toHash(Array arr) -> Object
Converts the array of strings to the object where each string becomes the key with the value of `true`.
```javascript
it.util.toHash(['a', 'b', 'c']) // { a: true, b: true, c: true }
```
##### .getProperty(String key) -> String
Converts the string that is the key/index to access the property/item to the JavaScript syntax to access the property (either "." notation or "[...]" notation).
```javascript
it.util.getProperty('a') // ".a"
it.util.getProperty('1') // "['1']"
it.util.getProperty("a'b") // "['a\\'b']"
it.util.getProperty(1) // "[1]"
```
##### .schemaHasRules(Object schema, Object rules) -> String
Determines whether the passed schema has rules that should be validated. This function should be used before calling `it.validate` to compile subschemas.
```javascript
it.util.schemaHasRules(schema, it.RULES.all) // true or false
```
##### .escapeQuotes(String str) -> String
Escapes single quotes in the string, so it can be inserted in the generated code inside the string constant with the single quotes.
##### .toQuotedString(String str) -> String
Converts the string to the JavaScript string constant in single quotes (using the escaped string).
```javascript
it.util.toQuotedString("a'b") // "'a\\'b'"
```
##### .getData(String jsonPointer, Number dataLevel, Array paths) -> String
Returns the validation-time expression to safely access data based on the passed [relative json pointer](https://tools.ietf.org/html/draft-luff-relative-json-pointer-00) (See [examples](https://gist.github.com/geraintluff/5911303)).
```javascript
it.util.getData('2/test/1', it.dataLevel, it.dataPathArr)
// The result depends on the current level
// if it.dataLevel is 3 the result is "data1 && data1.test && data1.test[1]"
```
##### .escapeJsonPointer(String str) -> String
Converts the property name to the JSON-Pointer fragment.
##### .unescapeJsonPointer (String str) -> String
Converts JSON-Pointer fragment to the property name.
##### .unescapeFragment(String str) -> String
Converts the property name to the JSON-Pointer fragment that can be used in URI.
##### .escapeFragment(String str) -> String
Converts the JSON-Pointer fragment from URI to the property name.
## Reporting errors in custom keywords
All custom keywords but macro keywords can optionally create custom error messages.
Synchronous validating and compiled keywords should define errors by assigning them to `.errors` property of the validation function. Asynchronous keywords can return promise that rejects with `new Ajv.ValidationError(errors)`, where `errors` is an array of custom validation errors (if you don't want to define custom errors in asynchronous keyword, its validation function can return the promise that resolves with `false`).
Inline custom keyword should increase error counter `errors` and add error to `vErrors` array (it can be null). This can be done for both synchronous and asynchronous keywords. See [example range keyword](https://github.com/epoberezkin/ajv/blob/master/spec/custom_rules/range_with_errors.jst).
When inline keyword performs validation Ajv checks whether it created errors by comparing errors count before and after validation. To skip this check add option `errors` (can be `"full"`, `true` or `false`) to keyword definition:
```javascript
ajv.addKeyword('range', {
type: 'number',
inline: inlineRangeTemplate,
statements: true,
errors: true // keyword should create custom errors when validation fails
// errors: 'full' // created errors should have dataPath already set
// errors: false // keyword never creates errors, Ajv will add a default error
});
```
Each error object should at least have properties `keyword`, `message` and `params`, other properties will be added.
Inlined keywords can optionally define `dataPath` and `schemaPath` properties in error objects, that will be assigned by Ajv unless `errors` option of the keyword is `"full"`.
If custom keyword doesn't create errors, the default error will be created in case the keyword fails validation (see [Validation errors](https://github.com/epoberezkin/ajv#validation-errors)).
## Short-circuit validation
In some cases inline keyword can terminate validation and return the result as soon as it encounters the error. It is only practical if the keyword you define has many criteria to validate and you want it to be able to fail fast. You only need to do it if your keyword defines errors itself, otherwise Ajv will return when it creates the default error (if the conditions below are met).
Two conditions should be checked before keyword can return the result:
- option `allErrors` should not be used (`!it.opts.allErrors` should be true).
- the current schema should not be inside composite rule (e.g. `not` or `anyOf`), when failing some keyword does not mean failing the validation (`!it.compositeRule` should be true).
If these conditions are met your keyword can immediately return result. In case the current schema is synchronous (`it.async` is not `true`) you can add this to keyword's generated code when it encounters error `err`:
```javascript
if (vErrors === null) vErrors = [err];
else vErrors.push(err);
validate.errors = vErrors;
return false;
```
In case the current schema is asynchronous (it.async is truthy) to return result you need:
```javascript
if (vErrors === null) vErrors = [err];
else vErrors.push(err);
throw new ValidationError(vErrors); // ValidationError is in the scope
```
In case `allErrors` option is used the keyword should continue validation after it encounters an error trying to find as many errors as possible.
If `allErrors` option is not used but `it.compositeRule` is truthy the keyword may short-circuit its own validation but it should not return the final validation result.
ajv-5.0.0/FAQ.md 0000664 0000000 0000000 00000015272 13075146637 0013250 0 ustar 00root root 0000000 0000000 # Frequently Asked Questions
The purpose of this document is to help find answers quicker. I am happy to continue the discussion about these issues, so please comment on some of the issues mentioned below or create a new issue if it seems more appropriate.
## Ajv API for returning validation errors
See [#65](https://github.com/epoberezkin/ajv/issues/65), [#212](https://github.com/epoberezkin/ajv/issues/212), [#236](https://github.com/epoberezkin/ajv/issues/236), [#242](https://github.com/epoberezkin/ajv/issues/242), [#256](https://github.com/epoberezkin/ajv/issues/256).
##### Why Ajv assigns errors as a property of validation function (or instance) instead of returning an object with validation results and errors?
The reasons are history (other fast validators with the same api) and performance (returning boolean is faster). Although more code is written to process errors than to handle successful results, almost all server-side validations pass. The existing API is more efficient from the performance point of view.
Ajv also supports asynchronous validation (with custom asynchronous formats and keywords) that returns a promise that either resolves to `true` or rejects with an error.
##### Would errors get overwritten in case of "concurrent" validations?
No. There is no concurrency in JavaScript - it is single-threaded. While a validation is run no other JavaScript code (that can access the same memory) can be executed. As long as the errors are used in the same execution block, the errors will not be overwritten.
##### Can we change / extend API to add a method that would return errors (rather than assign them to `errors` property)?
No. In many cases there is a module responsible for the validation in the application, usually to load schemas and to process errors. This module is the right place to introduce any custom API. Convenience is a subjective thing, changing or extending API purely because of convenience would either break backward compatibility (even if it's done in a new major version it still complicates migration) or bloat API (making it more difficult to maintain).
## Additional properties inside compound keywords anyOf, oneOf, etc.
See [#127](https://github.com/epoberezkin/ajv/issues/127), [#129](https://github.com/epoberezkin/ajv/issues/129), [#134](https://github.com/epoberezkin/ajv/issues/134), [#140](https://github.com/epoberezkin/ajv/issues/140), [#193](https://github.com/epoberezkin/ajv/issues/193), [#205](https://github.com/epoberezkin/ajv/issues/205), [#238](https://github.com/epoberezkin/ajv/issues/238), [#264](https://github.com/epoberezkin/ajv/issues/264).
##### Why the keyword `additionalProperties: false` fails validation when some properties are "declared" inside a subschema in `anyOf`/etc.?
The keyword `additionalProperties` creates the restriction on validated data based on its own value (`false` or schema object) and on the keywords `properties` and `patternProperties` in the SAME schema object. JSON-schema validators must NOT take into account properties used in other schema objects.
While you can expect that the schema below would allow the objects either with properties `foo` and `bar` or with properties `foo` and `baz` and all other properties will be prohibited, this schema will only allow objects with one property `foo` (an empty object and any non-objects will also be valid):
```json
{
"properties": { "foo": { "type": "number" } },
"additionalProperties": false,
"oneOf": [
{ "properties": { "bar": { "type": "number" } } },
{ "properties": { "baz": { "type": "number" } } }
]
}
```
The reason for that is that `additionalProperties` keyword ignores properties inside `oneOf` keyword subschemas. That's not the limitation of Ajv or any other validator, that's how it must work according to the standard (and if you consider all the problems with the alternatives it is the only sensible way to define this keyword).
There are several ways to implement the described logic that would allow two properties, please see the suggestions in the issues mentioned above.
##### Why the validation fails when I use option `removeAdditional` with the keyword `anyOf`/etc.?
This problem is related to the problem explained above - properties treated as additional in the sence of `additionalProperties` keyword, based on `properties`/`patternProperties` keyword in the same schema object.
See the exemple in [Filtering Data](https://github.com/epoberezkin/ajv#filtering-data) section of readme.
## Generating schemas with resolved references ($ref)
See [#22](https://github.com/epoberezkin/ajv/issues/22), [#125](https://github.com/epoberezkin/ajv/issues/125), [#146](https://github.com/epoberezkin/ajv/issues/146), [#228](https://github.com/epoberezkin/ajv/issues/228), [#336](https://github.com/epoberezkin/ajv/issues/336), [#454](https://github.com/epoberezkin/ajv/issues/454).
##### Why Ajv does not replace references ($ref) with the actual referenced schemas as some validators do?
1. The scope of Ajv is validating data against JSON-Schemas; inlining referenced schemas is not necessary for validation. When Ajv generates code for validation it either inlines the code of referenced schema or uses function calls. Doing schema manipulation is more complex and out of scope.
2. When schemas are recursive (or mutually recursive) resolving references would result in self-referencing recursive data-structures that can be difficult to process.
3. There are cases when such inlining would also require adding (or modyfing) `id` attribute in the inlined schema fragment to make the resulting schema equivalent.
There were many conversations about the meaning of `$ref` in [JSON-Schema GitHub organisation](https://github.com/json-schema-org). The consesus is that while it is possible to treat `$ref` as schema inclusion with two caveats (above), this interpretation is unnecessary complex. A more efficient approach is to treat `$ref` as a delegation, i.e. a special keyword that validates the current data instance against the referenced schema. The analogy with programming languages is that `$ref` is a function call rather than a macro. See [here](https://github.com/json-schema-org/json-schema-spec/issues/279), for example.
##### How can I generate a schema where `$ref` keywords are replaced with referenced schemas?
There are two possible approaches:
1. Write code to traverse schema and replace every `$ref` with the referenced schema. An additional limitation is that `"$ref"` inside keywords "properties", "patternProperties" and "dependencies" means property name (or pattern) rather than the reference to another schema.
2. Use a specially constructed JSON Schema with a [custom keyword](https://github.com/epoberezkin/ajv/blob/master/CUSTOM.md) to traverse and modify your schema.
ajv-5.0.0/KEYWORDS.md 0000664 0000000 0000000 00000060070 13075146637 0014104 0 ustar 00root root 0000000 0000000 # JSON-Schema validation keywords
In a simple way, JSON schema is an object with validation keywords.
The keywords and their values define what rules the data should satisfy to be valid.
## Keywords
- [type](#type)
- [Keywords for numbers](#keywords-for-numbers)
- [maximum / minimum and exclusiveMaximum / exclusiveMinimum](#maximum--minimum-and-exclusivemaximum--exclusiveminimum) (CHANGED in draft 6)
- [multipleOf](#multipleof)
- [Keywords for strings](#keywords-for-strings)
- [maxLength/minLength](#maxlength--minlength)
- [pattern](#pattern)
- [format](#format)
- [formatMaximum / formatMinimum and formatExclusiveMaximum / formatExclusiveMinimum](#formatmaximum--formatminimum-and-formatexclusivemaximum--formatexclusiveminimum-proposed) (proposed)
- [Keywords for arrays](#keywords-for-arrays)
- [maxItems/minItems](#maxitems--minitems)
- [uniqueItems](#uniqueitems)
- [items](#items)
- [additionalItems](#additionalitems)
- [contains](#contains) (NEW in draft 6)
- [Keywords for objects](#keywords-for-objects)
- [maxProperties/minProperties](#maxproperties--minproperties)
- [required](#required)
- [properties](#properties)
- [patternProperties](#patternproperties)
- [additionalProperties](#additionalproperties)
- [dependencies](#dependencies)
- [propertyNames](#propertynames) (NEW in draft 6)
- [patternGroups](#patterngroups-deprecated) (deprecated)
- [patternRequired](#patternrequired-proposed) (proposed)
- [Keywords for all types](#keywords-for-all-types)
- [enum](#enum)
- [const](#const) (NEW in draft 6)
- [Compound keywords](#compound-keywords)
- [not](#not)
- [oneOf](#oneof)
- [anyOf](#anyof)
- [allOf](#allof)
- [switch](#switch-proposed) (proposed)
## `type`
`type` keyword requires that the data is of certain type (or some of types). Its value can be a string (the allowed type) or an array of strings (multiple allowed types).
Type can be: number, integer, string, boolean, array, object or null.
__Examples__
1. _schema_: `{ "type": "number" }`
_valid_: `1`, `1.5`
_invalid_: `"abc"`, `"1"`, `[]`, `{}`, `null`, `true`
2. _schema_: `{ "type": "integer" }`
_valid_: `1`, `2`
_invalid_: `"abc"`, `"1"`, `1.5`, `[]`, `{}`, `null`, `true`
3. _schema_: `{ "type": ["number", "string"] }`
_valid_: `1`, `1.5`, `"abc"`, `"1"`
_invalid_: `[]`, `{}`, `null`, `true`
All examples above are JSON schemas that only require data to be of certain type to be valid.
Most other keywords apply only to a particular type of data. If the data is of different type, the keyword will not apply and the data will be considered valid.
## Keywords for numbers
### `maximum` / `minimum` and `exclusiveMaximum` / `exclusiveMinimum`
The value of keyword `maximum` (`minimum`) should be a number. This value is the maximum (minimum) allowed value for the data to be valid.
Draft 4: The value of keyword `exclusiveMaximum` (`exclusiveMinimum`) should be a boolean value. These keyword cannot be used without `maximum` (`minimum`). If this keyword value is equal to `true`, the data should not be equal to the value in `maximum` (`minimum`) keyword to be valid.
Draft 6: The value of keyword `exclusiveMaximum` (`exclusiveMinimum`) should be a number. This value is the exclusive maximum (minimum) allowed value for the data to be valid (the data equal to this keyword value is invalid).
Ajv supports both draft 4 and draft 6 syntaxes.
__Examples__
1. _schema_: `{ "maximum": 5 }`
_valid_: `4`, `5`, any non-number (`"abc"`, `[]`, `{}`, `null`, `true`)
_invalid_: `6`, `7`
2. _schema_: `{ "minimum": 5 }`
_valid_: `5`, `6`, any non-number (`"abc"`, `[]`, `{}`, `null`, `true`)
_invalid_: `4`, `4.5`
3. _schema_:
draft 4: `{ "minimum": 5, "exclusiveMinimum": true }`
draft 6: `{ "exclusiveMinimum": 5 }`
_valid_: `6`, `7`, any non-number (`"abc"`, `[]`, `{}`, `null`, `true`)
_invalid_: `4.5`, `5`
### `multipleOf`
The value of the keyword should be a number. The data to be valid should be a multiple of the keyword value (i.e. the result of division of the data on the value should be integer).
__Examples__
1. _schema_: `{ "multipleOf": 5 }`
_valid_: `5`, `10`, any non-number (`"abc"`, `[]`, `{}`, `null`, `true`)
_invalid_: `1`, `4`
2. _schema_: `{ "multipleOf": 2.5 }`
_valid_: `2.5`, `5`, `7.5`, any non-number (`"abc"`, `[]`, `{}`, `null`, `true`)
_invalid_: `1`, `4`
## Keywords for strings
### `maxLength` / `minLength`
The value of the keywords should be a number. The data to be valid should have length satisfying this rule. Unicode pairs are counted as a single character.
__Examples__
1. _schema_: `{ "maxLength": 5 }`
_valid_: `"abc"`, `"abcde"`, any non-string (`1`, `[]`, `{}`, `null`, `true`)
_invalid_: `"abcdef"`
2. _schema_: `{ "minLength": 2 }`
_valid_: `"ab"`, `"😀😀"`, any non-string (`1`, `[]`, `{}`, `null`, `true`)
_invalid_: `"a"`, `"😀"`
### `pattern`
The value of the keyword should be a string. The data to be valid should match the regular expression defined by the keyword value.
Ajv uses `new RegExp(value)` to create the regular expression that will be used to test data.
__Example__
_schema_: `{ "pattern": "[abc]+" }`
_valid_: `"a"`, `"abcd"`, `"cde"`, any non-string (`1`, `[]`, `{}`, `null`, `true`)
_invalid_: `"def"`, `""`
### `format`
The value of the keyword should be a string. The data to be valid should match the format with this name.
Ajv defines these formats: date, date-time, uri, email, hostname, ipv4, ipv6, regex.
__Example__
_schema_: `{ "format": "ipv4" }`
_valid_: `"192.168.0.1"`, any non-string (`1`, `[]`, `{}`, `null`, `true`)
_invalid_: `"abc"`
### `formatMaximum` / `formatMinimum` and `formatExclusiveMaximum` / `formatExclusiveMinimum` (proposed)
Defined in [ajv-keywords](https://github.com/epoberezkin/ajv-keywords) package.
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.
Ajv defines comparison rules for formats `"date"`, `"time"` and `"date-time".
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.
__Example__
_schema_:
```json
{
"format": "date",
"formatMaximum": "2016-02-06",
"formatExclusiveMaximum": true
}
```
_valid_: `"2015-12-31"`, `"2016-02-05"`, any non-string
_invalid_: `"2016-02-06"`, `"2016-02-07"`, `"abc"`
## Keywords for arrays
### `maxItems` / `minItems`
The value of the keywords should be a number. The data array to be valid should not have more (less) items than the keyword value.
__Example__
_schema_: `{ "maxItems": 3 }`
_valid_: `[]`, `[1]`, `["1", 2, "3"]`, any non-array (`"abc"`, `1`, `{}`, `null`, `true`)
_invalid_: `[1, 2, 3, 4]`
### `uniqueItems`
The value of the keyword should be a boolean. If the keyword value is `true`, the data array to be valid should have unique items.
__Example__
_schema_: `{ "uniqueItems": true }`
_valid_: `[]`, `[1]`, `["1", 2, "3"]`, any non-array (`"abc"`, `1`, `{}`, `null`, `true`)
_invalid_: `[1, 2, 1]`, `[{ "a": 1, "b": 2 }, { "b": 2, "a": 1 }]`
### `items`
The value of the keyword should be an object or an array of objects.
If the keyword value is an object, then for the data array to be valid each item of the array should be valid according to the schema in this value. In this case the "additionalItems" keyword is ignored.
If the keyword value is an array, then items with indeces less than the number of items in the keyword should be valid according to the schemas with the same indeces. Whether additional items are valid will depend on "additionalItems" keyword.
__Examples__
1. _schema_: `{ "items": { "type": "integer" } }`
_valid_: `[1,2,3]`, `[]`, any non-array (`1`, `"abc"`, `{}`, `null`, `true`)
_invalid_: `[1,"abc"]`
2. _schema_:
```json
{
"items": [
{ "type": "integer" },
{ "type": "string" }
]
}
```
_valid_: `[1]`, `[1, "abc"]`, `[1, "abc", 2]`, `[]`, any non-array (`1`, `"abc"`, `{}`, `null`, `true`)
_invalid_: `["abc", 1]`, `["abc"]`
### `additionalItems`
The value of the keyword should be a boolean or an object.
If "items" keyword is not present or it is an object, "additionalItems" keyword is ignored regardless of its value.
If "items" keyword is an array and data array has not more items than the length of "items" keyword value, "additionalItems" keyword is also ignored.
If the length of data array is bigger than the length of "items" keyword value than the result of the validation depends on the value of "additionalItems" keyword:
- `false`: data is invalid
- `true`: data is valid
- an object: data is valid if all additional items (i.e. items with indeces greater or equal than "items" keyword value length) are valid according to the schema in "assitionalItems" keyword.
__Examples__
1. _schema_: `{ "additionalItems": { "type": "integer" } }`
any data is valid against such schema - "additionalItems" is ignored.
2. _schema_:
```json
{
"items": { "type": "integer" },
"additionalItems": { "type": "string" }
}
```
_valid_: `[]`, `[1, 2]`, any non-array ("additionalItems" is ignored)
_invalid_: `[1, "abc"]`, (any array with some items other than integers)
3. _schema_:
```json
{
"items": [
{ "type": "integer" },
{ "type": "integer" }
],
"additionalItems": true
}
```
_valid_: `[]`, `[1, 2]`, `[1, 2, 3]`, `[1, 2, "abc"]`, any non-array
_invalid_: `["abc"]`, `[1, "abc", 3]`
4. _schema_:
```json
{
"items": [
{ "type": "integer" },
{ "type": "integer" }
],
"additionalItems": { "type": "string" }
}
```
_valid_: `[]`, `[1, 2]`, `[1, 2, "abc"]`, any non-array
_invalid_: `["abc"]`, `[1, 2, 3]`
### `contains`
The value of the keyword is a JSON-schema. The array is valid if it contains at least one item that is valid according to this schema.
__Example__
_schema_: `{ "contains": { "type": "integer" } }`
_valid_: `[1]`, `[1, "foo"]`, any array with at least one integer, any non-array
_invalid_: `[]`, `["foo", "bar"]`, any array without integers
The schema from the example above is equivalent to:
```json
{
"not": {
"type": "array",
"items": {
"not": { "type": "integer" }
}
}
}
```
## Keywords for objects
### `maxProperties` / `minProperties`
The value of the keywords should be a number. The data object to be valid should have not more (less) properties than the keyword value.
__Example__
_schema_: `{ "maxProperties": 2 }`
_valid_: `{}`, `{"a": 1}`, `{"a": "1", "b": 2}`, any non-object
_invalid_: `{"a": 1, "b": 2, "c": 3}`
### `required`
The value of the keyword should be an array of unique strings. The data object to be valid should contain all properties with names equal to the elements in the keyword value.
__Example__
_schema_: `{ "required": ["a", "b"] }`
_valid_: `{"a": 1, "b": 2}`, `{"a": 1, "b": 2, "c": 3}`, any non-object
_invalid_: `{}`, `{"a": 1}`, `{"c": 3, "d":4}`
### `properties`
The value of the keyword should be a map with keys equal to data object properties. Each value in the map should be a JSON schema. For data object to be valid the corresponding values in data object properties should be valid according to these schemas.
__Please note__: `properties` keyword does not require that the properties mentioned in it are present in the object (see examples).
__Example__
_schema_:
```json
{
"properties": {
"foo": { "type": "string" },
"bar": {
"type": "number",
"minimum": 2
}
}
}
```
_valid_: `{}`, `{"foo": "a"}`, `{"foo": "a", "bar": 2}`, any non-object
_invalid_: `{"foo": 1}`, `{"foo": "a", "bar": 1}`
### `patternProperties`
The value of this keyword should be a map where keys should be regular expressions and the values should be JSON schemas. For data object to be valid the values in data object properties that match regular expression(s) should be valid according to the corresponding schema(s).
When the value in data object property matches multiple regular expressions it should be valid according to all the schemas for all matched regular expressions.
__Please note__: `patternProperties` keyword does not require that properties matching patterns are present in the object (see examples).
__Example__
_schema_:
```json
{
"patternProperties": {
"^fo.*$": { "type": "string" },
"^ba.*$": { "type": "number" }
}
}
```
_valid_: `{}`, `{"foo": "a"}`, `{"foo": "a", "bar": 1}`, any non-object
_invalid_: `{"foo": 1}`, `{"foo": "a", "bar": "b"}`
### `additionalProperties`
The value of the keyword should be either a boolean or a JSON schema.
If the value is `true` the keyword is ignored.
If the value is `false` the data object to be valid should not have "additional properties" (i.e. properties other than those used in "properties" keyword and those that match patterns in "patternProperties" keyword).
If the value is a schema for the data object to be valid the values in all "additional properties" should be valid according to this schema.
__Examples__
1. _schema_:
```json
{
"properties": {
"foo": { "type": "number" }
},
"patternProperties": {
"^.*r$": { "type": "number" }
},
"additionalProperties": false
}
```
_valid_: `{}`, `{"foo": 1}`, `{"foo": 1, "bar": 2}`, any non-object
_invalid_: `{"a": 3}`, `{"foo": 1, "baz": 3}`
2. _schema_:
```json
{
"properties": {
"foo": { "type": "number" }
},
"patternProperties": {
"^.*r$": { "type": "number" }
},
"additionalProperties": { "type": "string" }
}
```
_valid_: `{}`, `{"a": "b"}`, `{"foo": 1}`, `{"foo": 1, "bar": 2}`, `{"foo": 1, "bar": 2, "a": "b"}`, any non-object
_invalid_: `{"a": 3}`, `{"foo": 1, "baz": 3}`
3. _schema_:
```json
{
"properties": {
"foo": { "type": "number" }
},
"additionalProperties": false,
"anyOf": [
"properties": {
"bar": { "type": "number" }
},
"properties": {
"baz": { "type": "number" }
}
]
}
```
_valid_: `{}`, `{"foo": 1}`, any non-object
_invalid_: `{"bar": 2}`, `{"baz": 3}`, `{"foo": 1, "bar": 2}`, etc.
### `dependencies`
The value of the keyword is a map with keys equal to data object properties. Each value in the map should be either an array of unique property names ("property dependency") or a JSON schema ("schema dependency").
For property dependency, if the data object contains a property that is a key in the keyword value, then to be valid the data object should also contain all properties from the array of properties.
For schema dependency, if the data object contains a property that is a key in the keyword value, then to be valid the data object itself (NOT the property value) should be valid according to the schema.
__Examples__
1. _schema (property dependency)_:
```json
{
"dependencies": {
"foo": ["bar", "baz"]
}
}
```
_valid_: `{"foo": 1, "bar": 2, "baz": 3}`, `{}`, `{"a": 1}`, any non-object
_invalid_: `{"foo": 1}`, `{"foo": 1, "bar": 2}`, `{"foo": 1, "baz": 3}`
2. _schema (schema dependency)_:
```json
{
"dependencies": {
"foo": {
"properties": {
"bar": { "type": "number" }
}
}
}
}
```
_valid_: `{}`, `{"foo": 1}`, `{"foo": 1, "bar": 2}`, `{"a": 1}`, any non-object
_invalid_: `{"foo": 1, "bar": "a"}`
### `propertyNames`
The value of this keyword is a JSON schema.
For data object to be valid each property name in this object should be valid according to this schema.
__Example__
_schema_:
```json
{
"propertyNames": { "format": "email" }
}
```
_valid_: `{"foo@bar.com": "any", "bar@bar.com": "any"}`, any non-object
_invalid_: `{"foo": "any value"}`
### `patternGroups` (deprecated)
This keyword is only provided for backward compatibility, it will be removed in the next major version. To use it, pass option `patternGroups: true`.
The value of this keyword should be a map where keys should be regular expressions and the values should be objects with the following properties:
- `schema` (required) - should be a JSON schema. For data object to be valid the values in data object properties that match regular expression(s) should be valid according to the corresponding `schema`(s).
- `maximum` / `minimum` (optional) - should be integers. For data object to be valid the number of properties that match regular expression(s) should be within limits set by `minimum`(s) and `maximum`(s).
__Example__
_schema_:
```json
{
"patternGroups": {
"^[a-z]+$": {
"minimum": 1,
"schema": { "type": "string" }
},
"^[0-9]+$": {
"minimum": 1,
"schema": { "type": "integer" }
}
}
}
```
_valid_: `{ "foo": "bar", "1": "2" }`, any non-object
_invalid_: `{}`, `{ "foo": "bar" }`, `{ "1": "2" }`
### `patternRequired` (proposed)
Defined in [ajv-keywords](https://github.com/epoberezkin/ajv-keywords) package.
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.
__Examples__
1. _schema_: `{ "patternRequired": [ "f.*o" ] }`
_valid_: `{ "foo": 1 }`, `{ "-fo-": 1 }`, `{ "foo": 1, "bar": 2 }`, any non-object
_invalid_: `{}`, `{ "bar": 2 }`, `{ "Foo": 1 }`,
2. _schema_: `{ "patternRequired": [ "f.*o", "b.*r" ] }`
_valid_: `{ "foo": 1, "bar": 2 }`, `{ "foobar": 3 }`, any non-object
_invalid_: `{}`, `{ "foo": 1 }`, `{ "bar": 2 }`
## Keywords for all types
### `enum`
The value of the keyword should be an array of unique items of any types. The data is valid if it is deeply equal to one of items in the array.
__Example__
_schema_: `{ "enum": [ 2, "foo", {"foo": "bar" }, [1, 2, 3] ] }`
_valid_: `2`, `"foo"`, `{"foo": "bar"}`, `[1, 2, 3]`
_invalid_: `1`, `"bar"`, `{"foo": "baz"}`, `[1, 2, 3, 4]`, any value not in the array
### `const`
The value of this keyword can be anything. The data is valid if it is deeply equal to the value of the keyword.
__Example__
_schema_: `{ "const": "foo" }`
_valid_: `"foo"`
_invalid_: any other value
The same can be achieved with `enum` keyword using the array with one item. But `const` keyword is more than just a syntax sugar for `enum`. In combination with the [$data reference](https://github.com/epoberezkin/ajv#data-reference) it allows to define equality relations between different parts of the data. This cannot be achieved with `enum` keyword even with `$data` reference because `$data` cannot be used in place of one item - it can only be used in place of the whole array in `enum` keyword.
__Example__
_schema_:
```json
{
"properties": {
"foo": { "type": "number" },
"bar": { "const": { "$data": "1/foo" } }
}
}
```
_valid_: `{ "foo": 1, "bar": 1 }`, `{}`
_invalid_: `{ "foo": 1 }`, `{ "bar": 1 }`, `{ "foo": 1, "bar": 2 }`
## Compound keywords
### `not`
The value of the keyword should be a JSON schema. The data is valid if it is invalid according to this schema.
__Examples__
1. _schema_: `{ "not": { "minimum": 3 } }`
_valid_: `1`, `2`
_invalid_: `3`, `4`, any non-number
2. _schema_:
```json
{
"not": {
"items": {
"not": { "type": "string" }
}
}
}
```
_valid_: `["a"]`, `[1, "a"]`, any array containing at least one string
_invalid_: `[]`, `[1]`, any non-array, any array not containing strings
### `oneOf`
The value of the keyword should be an array of JSON schemas. The data is valid if it matches exactly one JSON schema from this array. Validators have to validate data against all schemas to establish validity according to this keyword.
__Example__
_schema_:
```json
{
"oneOf": [
{ "maximum": 3 },
{ "type": "integer" }
]
}
```
_valid_: `1.5`, `2.5`, `4`, `5`, any non-number
_invalid_: `2`, `3`, `4.5`, `5.5`
### `anyOf`
The value of the keyword should be an array of JSON schemas. The data is valid if it is valid according to one or more JSON schemas in this array. Validators only need to validate data against schemas in order until the first schema matches (or until all schemas have been tried). For this reason validating against this keyword is faster than against "oneOf" keyword in most cases.
__Example__
_schema_:
```json
{
"anyOf": [
{ "maximum": 3 },
{ "type": "integer" }
]
}
```
_valid_: `1.5`, `2`, `2.5`, `3`, `4`, `5`, any non-number
_invalid_: `4.5`, `5.5`
### `allOf`
The value of the keyword should be an array of JSON schemas. The data is valid if it is valid according to all JSON schemas in this array.
__Example__
_schema_:
```json
{
"allOf": [
{ "maximum": 3 },
{ "type": "integer" }
]
}
```
_valid_: `2`, `3`
_invalid_: `1.5`, `2.5`, `4`, `4.5`, `5`, `5.5`, any non-number
### `switch` (proposed)
Defined in [ajv-keywords](https://github.com/epoberezkin/ajv-keywords) package.
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.
__Examples__
1. _schema_:
```json
{
"switch": [
{
"if": { "properties": { "power": { "minimum": 9000 } } },
"then": { "required": [ "disbelief" ] },
"continue": true
},
{ "then": { "required": [ "confidence" ] } }
]
}
```
_valid_:
- `{ "power": 9000, "disbelief": true, "confidence": true }`
- `{ "confidence": true }`
- `{ "power": 1000, "confidence": true }`
_invalid_:
- `{ "power": 9000 }` (`disbelief` & `confidence` are required)
- `{ "power": 9000, "disbelief": true }` (`confidence` is always required)
- `{ "power": 1000 }`
- `{}`
2. _schema_:
```json
{
"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 }
]
}
```
_valid_: `1`, `5`, `10`, `20`, `50`, `100`, `200`, `500`, `1000`
_invalid_:
- `-1`, `0` (<1)
- `2000` (>1000)
- `11`, `57`, `123` (any number with more than one non-zero digit)
- non-integers
ajv-5.0.0/LICENSE 0000664 0000000 0000000 00000002075 13075146637 0013321 0 ustar 00root root 0000000 0000000 The MIT License (MIT)
Copyright (c) 2015 Evgeny Poberezkin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
ajv-5.0.0/README.md 0000664 0000000 0000000 00000206225 13075146637 0013576 0 ustar 00root root 0000000 0000000
# Ajv: Another JSON Schema Validator
The fastest JSON Schema validator for node.js and browser with draft 6 support.
[](https://travis-ci.org/epoberezkin/ajv)
[](https://www.npmjs.com/package/ajv)
[](https://www.npmjs.com/package/ajv)
[](https://codeclimate.com/github/epoberezkin/ajv)
[](https://coveralls.io/github/epoberezkin/ajv?branch=master)
[](https://gitter.im/ajv-validator/ajv)
__Please note__:
[JSON-Schema draft-06](https://trac.tools.ietf.org/html/draft-wright-json-schema-validation-01) is published.
[Ajv version 5.0.0](https://github.com/epoberezkin/ajv/releases/tag/5.0.0) is released.
You can still use [Ajv version 4](https://github.com/epoberezkin/ajv/tree/v4): `npm install ajv@^4`.
## Contents
- [Performance](#performance)
- [Features](#features)
- [Getting started](#getting-started)
- [Frequently Asked Questions](https://github.com/epoberezkin/ajv/blob/master/FAQ.md)
- [Using in browser](#using-in-browser)
- [Command line interface](#command-line-interface)
- Validation
- [Keywords](#validation-keywords)
- [Formats](#formats)
- [$data reference](#data-reference)
- NEW: [$merge and $patch keywords](#merge-and-patch-keywords)
- [Defining custom keywords](#defining-custom-keywords)
- [Asynchronous schema compilation](#asynchronous-schema-compilation)
- [Asynchronous validation](#asynchronous-validation)
- Modifying data during validation
- [Filtering data](#filtering-data)
- [Assigning defaults](#assigning-defaults)
- [Coercing data types](#coercing-data-types)
- API
- [Methods](#api)
- [Options](#options)
- [Validation errors](#validation-errors)
- [Related packages](#related-packages)
- [Packages using Ajv](#some-packages-using-ajv)
- [Tests, Contributing, History, License](#tests)
## Performance
Ajv generates code using [doT templates](https://github.com/olado/doT) to turn JSON schemas into super-fast validation functions that are efficient for v8 optimization.
Currently Ajv is the fastest and the most standard compliant validator according to these benchmarks:
- [json-schema-benchmark](https://github.com/ebdrup/json-schema-benchmark) - 50% faster than the second place
- [jsck benchmark](https://github.com/pandastrike/jsck#benchmarks) - 20-190% faster
- [z-schema benchmark](https://rawgit.com/zaggino/z-schema/master/benchmark/results.html)
- [themis benchmark](https://cdn.rawgit.com/playlyfe/themis/master/benchmark/results.html)
Performace of different validators by [json-schema-benchmark](https://github.com/ebdrup/json-schema-benchmark):
[](https://github.com/ebdrup/json-schema-benchmark/blob/master/README.md#performance)
## Features
- Ajv implements full JSON Schema [draft 6](http://json-schema.org/) and draft 4 standards:
- all validation keywords (see [JSON-Schema validation keywords](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md))
- full support of remote refs (remote schemas have to be added with `addSchema` or compiled to be available)
- support of circular references between schemas
- correct string lengths for strings with unicode pairs (can be turned off)
- [formats](#formats) defined by JSON Schema draft 4 standard and custom formats (can be turned off)
- [validates schemas against meta-schema](#api-validateschema)
- supports [browsers](#using-in-browser) and nodejs 0.10-6.x
- [asynchronous loading](#asynchronous-schema-compilation) of referenced schemas during compilation
- "All errors" validation mode with [option allErrors](#options)
- [error messages with parameters](#validation-errors) describing error reasons to allow creating custom error messages
- i18n error messages support with [ajv-i18n](https://github.com/epoberezkin/ajv-i18n) package
- [filtering data](#filtering-data) from additional properties
- [assigning defaults](#assigning-defaults) to missing properties and items
- [coercing data](#coercing-data-types) to the types specified in `type` keywords
- [custom keywords](#defining-custom-keywords)
- draft-6 keywords `const`, `contains` and `propertyNames`
- draft-6 boolean schemas (`true`/`false` as a schema to always pass/fail).
- keywords `switch`, `patternRequired`, `formatMaximum` / `formatMinimum` and `formatExclusiveMaximum` / `formatExclusiveMinimum` from [JSON-schema extension proposals](https://github.com/json-schema/json-schema/wiki/v5-Proposals) with [ajv-keywords](https://github.com/epoberezkin/ajv-keywords) package
- [$data reference](#data-reference) to use values from the validated data as values for the schema keywords
- [asynchronous validation](#asynchronous-validation) of custom formats and keywords
Currently Ajv is the only validator that passes all the tests from [JSON Schema Test Suite](https://github.com/json-schema/JSON-Schema-Test-Suite) (according to [json-schema-benchmark](https://github.com/ebdrup/json-schema-benchmark), apart from the test that requires that `1.0` is not an integer that is impossible to satisfy in JavaScript).
## Install
```
npm install ajv
```
To install a stable beta version [5.0.4](https://github.com/epoberezkin/ajv/releases/tag/5.0.4-beta.3) (see [migration guide from 4.x.x](https://github.com/epoberezkin/ajv/releases/tag/5.0.1-beta.0)):
```
npm install ajv@^5.0.4-beta
```
## Getting started
Try it in the node REPL: https://tonicdev.com/npm/ajv
The fastest validation call:
```javascript
var Ajv = require('ajv');
var ajv = new Ajv(); // options can be passed, e.g. {allErrors: true}
var validate = ajv.compile(schema);
var valid = validate(data);
if (!valid) console.log(validate.errors);
```
or with less code
```javascript
// ...
var valid = ajv.validate(schema, data);
if (!valid) console.log(ajv.errors);
// ...
```
or
```javascript
// ...
ajv.addSchema(schema, 'mySchema');
var valid = ajv.validate('mySchema', data);
if (!valid) console.log(ajv.errorsText());
// ...
```
See [API](#api) and [Options](#options) for more details.
Ajv compiles schemas to functions and caches them in all cases (using schema serialized with [json-stable-stringify](https://github.com/substack/json-stable-stringify) or a custom function as a key), so that the next time the same schema is used (not necessarily the same object instance) it won't be compiled again.
The best performance is achieved when using compiled functions returned by `compile` or `getSchema` methods (there is no additional function call).
__Please note__: every time validation function or `ajv.validate` are called `errors` property is overwritten. You need to copy `errors` array reference to another variable if you want to use it later (e.g., in the callback). See [Validation errors](#validation-errors)
## Using in browser
You can require Ajv directly from the code you browserify - in this case Ajv will be a part of your bundle.
If you need to use Ajv in several bundles you can create a separate UMD bundle using `npm run bundle` script (thanks to [siddo420](https://github.com/siddo420)).
Then you need to load Ajv in the browser:
```html
```
This bundle can be used with different module systems or creates global `Ajv` if no module system is found.
The browser bundle is available on [cdnjs](https://cdnjs.com/libraries/ajv).
Ajv is tested with these browsers:
[](https://saucelabs.com/u/epoberezkin)
__Please note__: some frameworks, e.g. Dojo, may redefine global require in such way that is not compatible with CommonJS module format. In such case Ajv bundle has to be loaded before the framework and then you can use global Ajv (see issue [#234](https://github.com/epoberezkin/ajv/issues/234)).
## Command line interface
CLI is available as a separate npm package [ajv-cli](https://github.com/jessedc/ajv-cli). It supports:
- compiling JSON-schemas to test their validity
- BETA: generating standalone module exporting a validation function to be used without Ajv (using [ajv-pack](https://github.com/epoberezkin/ajv-pack))
- migrate schemas to draft-06 (using [json-schema-migrate](https://github.com/epoberezkin/json-schema-migrate))
- validating data file(s) against JSON-schema
- testing expected validity of data against JSON-schema
- referenced schemas
- custom meta-schemas
- files in JSON and JavaScript format
- all Ajv options
- reporting changes in data after validation in [JSON-patch](https://tools.ietf.org/html/rfc6902) format
## Validation keywords
Ajv supports all validation keywords from draft 4 of JSON-schema standard:
- [type](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#type)
- [for numbers](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#keywords-for-numbers) - maximum, minimum, exclusiveMaximum, exclusiveMinimum, multipleOf
- [for strings](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#keywords-for-strings) - maxLength, minLength, pattern, format
- [for arrays](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#keywords-for-arrays) - maxItems, minItems, uniqueItems, items, additionalItems, [contains](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#contains)
- [for objects](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#keywords-for-objects) - maxProperties, minproperties, required, properties, patternProperties, additionalProperties, dependencies, [propertyNames](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#propertynames)
- [for all types](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#keywords-for-all-types) - enum, [const](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#const)
- [compound keywords](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#compound-keywords) - not, oneOf, anyOf, allOf
With [ajv-keywords](https://github.com/epoberezkin/ajv-keywords) package Ajv also supports validation keywords from [JSON-Schema extension proposals](https://github.com/json-schema/json-schema/wiki/v5-Proposals) for JSON-schema standard:
- [switch](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#switch-proposed) - conditional validation with a sequence of if/then clauses
- [patternRequired](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#patternrequired-proposed) - like `required` but with patterns that some property should match.
- [formatMaximum, formatMinimum, formatExclusiveMaximum, formatExclusiveMinimum](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#formatmaximum--formatminimum-and-exclusiveformatmaximum--exclusiveformatminimum-proposed) - setting limits for date, time, etc.
See [JSON-Schema validation keywords](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md) for more details.
## Formats
The following formats are supported for string validation with "format" keyword:
- _date_: full-date according to [RFC3339](http://tools.ietf.org/html/rfc3339#section-5.6).
- _time_: time with optional time-zone.
- _date-time_: date-time from the same source (time-zone is mandatory). `date`, `time` and `date-time` validate ranges in `full` mode and only regexp in `fast` mode (see [options](#options)).
- _uri_: full uri with optional protocol.
- _url_: [URL record](https://url.spec.whatwg.org/#concept-url).
- _email_: email address.
- _hostname_: host name acording to [RFC1034](http://tools.ietf.org/html/rfc1034#section-3.5).
- _ipv4_: IP address v4.
- _ipv6_: IP address v6.
- _regex_: tests whether a string is a valid regular expression by passing it to RegExp constructor.
- _uuid_: Universally Unique IDentifier according to [RFC4122](http://tools.ietf.org/html/rfc4122).
- _json-pointer_: JSON-pointer according to [RFC6901](https://tools.ietf.org/html/rfc6901).
- _relative-json-pointer_: relative JSON-pointer according to [this draft](http://tools.ietf.org/html/draft-luff-relative-json-pointer-00).
There are two modes of format validation: `fast` and `full`. This mode affects formats `date`, `time`, `date-time`, `uri`, `email`, and `hostname`. See [Options](#options) for details.
You can add additional formats and replace any of the formats above using [addFormat](#api-addformat) method.
The option `unknownFormats` allows to change the behaviour in case an unknown format is encountered - Ajv can either fail schema compilation (default) or ignore it (default in versions before 5.0.0). You also can whitelist specific format(s) to be ignored. See [Options](#options) for details.
You can find patterns used for format validation and the sources that were used in [formats.js](https://github.com/epoberezkin/ajv/blob/master/lib/compile/formats.js).
## $data reference
With `$data` option you can use values from the validated data as the values for the schema keywords. See [proposal](https://github.com/json-schema/json-schema/wiki/$data-(v5-proposal)) for more information about how it works.
`$data` reference is supported in the keywords: const, enum, format, maximum/minimum, exclusiveMaximum / exclusiveMinimum, maxLength / minLength, maxItems / minItems, maxProperties / minProperties, formatMaximum / formatMinimum, formatExclusiveMaximum / formatExclusiveMinimum, multipleOf, pattern, required, uniqueItems.
The value of "$data" should be a [JSON-pointer](https://tools.ietf.org/html/rfc6901) to the data (the root is always the top level data object, even if the $data reference is inside a referenced subschema) or a [relative JSON-pointer](http://tools.ietf.org/html/draft-luff-relative-json-pointer-00) (it is relative to the current point in data; if the $data reference is inside a referenced subschema it cannot point to the data outside of the root level for this subschema).
Examples.
This schema requires that the value in property `smaller` is less or equal than the value in the property larger:
```javascript
var schema = {
"properties": {
"smaller": {
"type": "number",
"maximum": { "$data": "1/larger" }
},
"larger": { "type": "number" }
}
};
var validData = {
smaller: 5,
larger: 7
};
```
This schema requires that the properties have the same format as their field names:
```javascript
var schema = {
"additionalProperties": {
"type": "string",
"format": { "$data": "0#" }
}
};
var validData = {
'date-time': '1963-06-19T08:30:06.283185Z',
email: 'joe.bloggs@example.com'
}
```
`$data` reference is resolved safely - it won't throw even if some property is undefined. If `$data` resolves to `undefined` the validation succeeds (with the exclusion of `const` keyword). If `$data` resolves to incorrect type (e.g. not "number" for maximum keyword) the validation fails.
## $merge and $patch keywords
With the package [ajv-merge-patch](https://github.com/epoberezkin/ajv-merge-patch) you can use the keywords `$merge` and `$patch` that allow extending JSON-schemas with patches using formats [JSON Merge Patch (RFC 7396)](https://tools.ietf.org/html/rfc7396) and [JSON Patch (RFC 6902)](https://tools.ietf.org/html/rfc6902).
To add keywords `$merge` and `$patch` to Ajv instance use this code:
```javascript
require('ajv-merge-patch')(ajv);
```
Examples.
Using `$merge`:
```json
{
"$merge": {
"source": {
"type": "object",
"properties": { "p": { "type": "string" } },
"additionalProperties": false
},
"with": {
"properties": { "q": { "type": "number" } }
}
}
}
```
Using `$patch`:
```json
{
"$patch": {
"source": {
"type": "object",
"properties": { "p": { "type": "string" } },
"additionalProperties": false
},
"with": [
{ "op": "add", "path": "/properties/q", "value": { "type": "number" } }
]
}
}
```
The schemas above are equivalent to this schema:
```json
{
"type": "object",
"properties": {
"p": { "type": "string" },
"q": { "type": "number" }
},
"additionalProperties": false
}
```
The properties `source` and `with` in the keywords `$merge` and `$patch` can use absolute or relative `$ref` to point to other schemas previously added to the Ajv instance or to the fragments of the current schema.
See the package [ajv-merge-patch](https://github.com/epoberezkin/ajv-merge-patch) for more information.
## Defining custom keywords
The advantages of using custom keywords are:
- allow creating validation scenarios that cannot be expressed using JSON-Schema
- simplify your schemas
- help bringing a bigger part of the validation logic to your schemas
- make your schemas more expressive, less verbose and closer to your application domain
- implement custom data processors that modify your data (`modifying` option MUST be used in keyword definition) and/or create side effects while the data is being validated
If a keyword is used only for side-effects and its validation result is pre-defined, use option `valid: true/false` in keyword definition to simplify both generated code (no error handling in case of `valid: true`) and your keyword functions (no need to return any validation result).
The concerns you have to be aware of when extending JSON-schema standard with custom keywords are the portability and understanding of your schemas. You will have to support these custom keywords on other platforms and to properly document these keywords so that everybody can understand them in your schemas.
You can define custom keywords with [addKeyword](#api-addkeyword) method. Keywords are defined on the `ajv` instance level - new instances will not have previously defined keywords.
Ajv allows defining keywords with:
- validation function
- compilation function
- macro function
- inline compilation function that should return code (as string) that will be inlined in the currently compiled schema.
Example. `range` and `exclusiveRange` keywords using compiled schema:
```javascript
ajv.addKeyword('range', { type: 'number', compile: function (sch, parentSchema) {
var min = sch[0];
var max = sch[1];
return parentSchema.exclusiveRange === true
? function (data) { return data > min && data < max; }
: function (data) { return data >= min && data <= max; }
} });
var schema = { "range": [2, 4], "exclusiveRange": true };
var validate = ajv.compile(schema);
console.log(validate(2.01)); // true
console.log(validate(3.99)); // true
console.log(validate(2)); // false
console.log(validate(4)); // false
```
Several custom keywords (typeof, instanceof, range and propertyNames) are defined in [ajv-keywords](https://github.com/epoberezkin/ajv-keywords) package - they can be used for your schemas and as a starting point for your own custom keywords.
See [Defining custom keywords](https://github.com/epoberezkin/ajv/blob/master/CUSTOM.md) for more details.
## Asynchronous schema compilation
During asynchronous compilation remote references are loaded using supplied function. See `compileAsync` [method](#api-compileAsync) and `loadSchema` [option](#options).
Example:
```javascript
var ajv = new Ajv({ loadSchema: loadSchema });
ajv.compileAsync(schema).then(function (validate) {
var valid = validate(data);
// ...
});
function loadSchema(uri) {
return request.json(uri).then(function (res) {
if (res.statusCode >= 400)
throw new Error('Loading error: ' + res.statusCode);
return res.body;
});
}
```
__Please note__: [Option](#options) `missingRefs` should NOT be set to `"ignore"` or `"fail"` for asynchronous compilation to work.
## Asynchronous validation
Example in node REPL: https://tonicdev.com/esp/ajv-asynchronous-validation
You can define custom formats and keywords that perform validation asyncronously by accessing database or some service. You should add `async: true` in the keyword or format defnition (see [addFormat](#api-addformat), [addKeyword](#api-addkeyword) and [Defining custom keywords](#defining-custom-keywords)).
If your schema uses asynchronous formats/keywords or refers to some schema that contains them it should have `"$async": true` keyword so that Ajv can compile it correctly. If asynchronous format/keyword or reference to asynchronous schema is used in the schema without `$async` keyword Ajv will throw an exception during schema compilation.
__Please note__: all asynchronous subschemas that are referenced from the current or other schemas should have `"$async": true` keyword as well, otherwise the schema compilation will fail.
Validation function for an asynchronous custom format/keyword should return a promise that resolves with `true` or `false` (or rejects with `new Ajv.ValidationError(errors)` if you want to return custom errors from the keyword function). Ajv compiles asynchronous schemas to either [es7 async functions](http://tc39.github.io/ecmascript-asyncawait/) that can optionally be transpiled with [nodent](https://github.com/MatAtBread/nodent) or with [regenerator](https://github.com/facebook/regenerator) or to [generator functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*) that can be optionally transpiled with regenerator as well. You can also supply any other transpiler as a function. See [Options](#options).
The compiled validation function has `$async: true` property (if the schema is asynchronous), so you can differentiate these functions if you are using both syncronous and asynchronous schemas.
If you are using generators, the compiled validation function can be either wrapped with [co](https://github.com/tj/co) (default) or returned as generator function, that can be used directly, e.g. in [koa](http://koajs.com/) 1.0. `co` is a small library, it is included in Ajv (both as npm dependency and in the browser bundle).
Async functions are currently supported in Chrome 55, Firefox 52, Node 7 (with --harmony-async-await) and MS Edge 13 (with flag).
Generator functions are currently supported in Chrome, Firefox and node.js.
If you are using Ajv in other browsers or in older versions of node.js you should use one of available transpiling options. All provided async modes use global Promise class. If your platform does not have Promise you should use a polyfill that defines it.
Validation result will be a promise that resolves with validated data or rejects with an exception `Ajv.ValidationError` that has the array of validation errors in `errors` property.
Example:
```javascript
/**
* Default mode is non-transpiled generator function wrapped with `co`.
* Using package ajv-async (https://github.com/epoberezkin/ajv-async)
* you can auto-detect the best async mode.
* In this case, without "async" and "transpile" options
* (or with option {async: true})
* Ajv will choose the first supported/installed option in this order:
* 1. native async function
* 2. native generator function wrapped with co
* 3. es7 async functions transpiled with nodent
* 4. es7 async functions transpiled with regenerator
*/
var setupAsync = require('ajv-async');
var ajv = setupAsync(new Ajv);
ajv.addKeyword('idExists', {
async: true,
type: 'number',
validate: checkIdExists
});
function checkIdExists(schema, data) {
return knex(schema.table)
.select('id')
.where('id', data)
.then(function (rows) {
return !!rows.length; // true if record is found
});
}
var schema = {
"$async": true,
"properties": {
"userId": {
"type": "integer",
"idExists": { "table": "users" }
},
"postId": {
"type": "integer",
"idExists": { "table": "posts" }
}
}
};
var validate = ajv.compile(schema);
validate({ userId: 1, postId: 19 }))
.then(function (data) {
console.log('Data is valid', data); // { userId: 1, postId: 19 }
})
.catch(function (err) {
if (!(err instanceof Ajv.ValidationError)) throw err;
// data is invalid
console.log('Validation errors:', err.errors);
});
```
### Using transpilers with asyncronous validation functions.
To use a transpiler you should separately install it (or load its bundle in the browser).
Ajv npm package includes minified browser bundles of regenerator and nodent in dist folder.
#### Using nodent
```javascript
var setupAsync = require('ajv-async');
var ajv = new Ajv({ /* async: 'es7', */ transpile: 'nodent' });
setupAsync(ajv);
var validate = ajv.compile(schema); // transpiled es7 async function
validate(data).then(successFunc).catch(errorFunc);
```
`npm install nodent` or use `nodent.min.js` from dist folder of npm package.
#### Using regenerator
```javascript
var setupAsync = require('ajv-async');
var ajv = new Ajv({ /* async: 'es7', */ transpile: 'regenerator' });
setupAsync(ajv);
var validate = ajv.compile(schema); // transpiled es7 async function
validate(data).then(successFunc).catch(errorFunc);
```
`npm install regenerator` or use `regenerator.min.js` from dist folder of npm package.
#### Using other transpilers
```javascript
var ajv = new Ajv({ async: 'es7', processCode: transpileFunc });
var validate = ajv.compile(schema); // transpiled es7 async function
validate(data).then(successFunc).catch(errorFunc);
```
See [Options](#options).
#### Comparison of async modes
|mode|transpile
speed*|run-time
speed*|bundle
size|
|---|:-:|:-:|:-:|
|es7 async
(native)|-|0.75|-|
|generators
(native)|-|1.0|-|
|es7.nodent|1.35|1.1|215Kb|
|es7.regenerator|1.0|2.7|1109Kb|
|regenerator|1.0|3.2|1109Kb|
\* Relative performance in node v.7, smaller is better.
[nodent](https://github.com/MatAtBread/nodent) has several advantages:
- much smaller browser bundle than regenerator
- almost the same performance of generated code as native generators in nodejs and the latest Chrome
- much better performace than native generators in other browsers
- works in IE 9 (regenerator does not)
## Filtering data
With [option `removeAdditional`](#options) (added by [andyscott](https://github.com/andyscott)) you can filter data during the validation.
This option modifies original data.
Example:
```javascript
var ajv = new Ajv({ removeAdditional: true });
var schema = {
"additionalProperties": false,
"properties": {
"foo": { "type": "number" },
"bar": {
"additionalProperties": { "type": "number" },
"properties": {
"baz": { "type": "string" }
}
}
}
}
var data = {
"foo": 0,
"additional1": 1, // will be removed; `additionalProperties` == false
"bar": {
"baz": "abc",
"additional2": 2 // will NOT be removed; `additionalProperties` != false
},
}
var validate = ajv.compile(schema);
console.log(validate(data)); // true
console.log(data); // { "foo": 0, "bar": { "baz": "abc", "additional2": 2 }
```
If `removeAdditional` option in the example above were `"all"` then both `additional1` and `additional2` properties would have been removed.
If the option were `"failing"` then property `additional1` would have been removed regardless of its value and property `additional2` would have been removed only if its value were failing the schema in the inner `additionalProperties` (so in the example above it would have stayed because it passes the schema, but any non-number would have been removed).
__Please note__: If you use `removeAdditional` option with `additionalProperties` keyword inside `anyOf`/`oneOf` keywords your validation can fail with this schema, for example:
```json
{
"type": "object",
"oneOf": [
{
"properties": {
"foo": { "type": "string" }
},
"required": [ "foo" ],
"additionalProperties": false
},
{
"properties": {
"bar": { "type": "integer" }
},
"required": [ "bar" ],
"additionalProperties": false
}
]
}
```
The intention of the schema above is to allow objects with either the string property "foo" or the integer property "bar", but not with both and not with any other properties.
With the option `removeAdditional: true` the validation will pass for the object `{ "foo": "abc"}` but will fail for the object `{"bar": 1}`. It happens because while the first subschema in `oneOf` is validated, the property `bar` is removed because it is an additional property according to the standard (because it is not included in `properties` keyword in the same schema).
While this behaviour is unexpected (issues [#129](https://github.com/epoberezkin/ajv/issues/129), [#134](https://github.com/epoberezkin/ajv/issues/134)), it is correct. To have the expected behaviour (both objects are allowed and additional properties are removed) the schema has to be refactored in this way:
```json
{
"type": "object",
"properties": {
"foo": { "type": "string" },
"bar": { "type": "integer" }
},
"additionalProperties": false,
"oneOf": [
{ "required": [ "foo" ] },
{ "required": [ "bar" ] }
]
}
```
The schema above is also more efficient - it will compile into a faster function.
## Assigning defaults
With [option `useDefaults`](#options) Ajv will assign values from `default` keyword in the schemas of `properties` and `items` (when it is the array of schemas) to the missing properties and items.
This option modifies original data.
__Please note__: by default the default value is inserted in the generated validation code as a literal (starting from v4.0), so the value inserted in the data will be the deep clone of the default in the schema.
If you need to insert the default value in the data by reference pass the option `useDefaults: "shared"`.
Inserting defaults by reference can be faster (in case you have an object in `default`) and it allows to have dynamic values in defaults, e.g. timestamp, without recompiling the schema. The side effect is that modifying the default value in any validated data instance will change the default in the schema and in other validated data instances. See example 3 below.
Example 1 (`default` in `properties`):
```javascript
var ajv = new Ajv({ useDefaults: true });
var schema = {
"type": "object",
"properties": {
"foo": { "type": "number" },
"bar": { "type": "string", "default": "baz" }
},
"required": [ "foo", "bar" ]
};
var data = { "foo": 1 };
var validate = ajv.compile(schema);
console.log(validate(data)); // true
console.log(data); // { "foo": 1, "bar": "baz" }
```
Example 2 (`default` in `items`):
```javascript
var schema = {
"type": "array",
"items": [
{ "type": "number" },
{ "type": "string", "default": "foo" }
]
}
var data = [ 1 ];
var validate = ajv.compile(schema);
console.log(validate(data)); // true
console.log(data); // [ 1, "foo" ]
```
Example 3 (inserting "defaults" by reference):
```javascript
var ajv = new Ajv({ useDefaults: 'shared' });
var schema = {
properties: {
foo: {
default: { bar: 1 }
}
}
}
var validate = ajv.compile(schema);
var data = {};
console.log(validate(data)); // true
console.log(data); // { foo: { bar: 1 } }
data.foo.bar = 2;
var data2 = {};
console.log(validate(data2)); // true
console.log(data2); // { foo: { bar: 2 } }
```
`default` keywords in other cases are ignored:
- not in `properties` or `items` subschemas
- in schemas inside `anyOf`, `oneOf` and `not` (see [#42](https://github.com/epoberezkin/ajv/issues/42))
- in `if` subschema of `switch` keyword
- in schemas generated by custom macro keywords
## Coercing data types
When you are validating user inputs all your data properties are usually strings. The option `coerceTypes` allows you to have your data types coerced to the types specified in your schema `type` keywords, both to pass the validation and to use the correctly typed data afterwards.
This option modifies original data.
__Please note__: if you pass a scalar value to the validating function its type will be coerced and it will pass the validation, but the value of the variable you pass won't be updated because scalars are passed by value.
Example 1:
```javascript
var ajv = new Ajv({ coerceTypes: true });
var schema = {
"type": "object",
"properties": {
"foo": { "type": "number" },
"bar": { "type": "boolean" }
},
"required": [ "foo", "bar" ]
};
var data = { "foo": "1", "bar": "false" };
var validate = ajv.compile(schema);
console.log(validate(data)); // true
console.log(data); // { "foo": 1, "bar": false }
```
Example 2 (array coercions):
```javascript
var ajv = new Ajv({ coerceTypes: 'array' });
var schema = {
"properties": {
"foo": { "type": "array", "items": { "type": "number" } },
"bar": { "type": "boolean" }
}
};
var data = { "foo": "1", "bar": ["false"] };
var validate = ajv.compile(schema);
console.log(validate(data)); // true
console.log(data); // { "foo": [1], "bar": false }
```
The coercion rules, as you can see from the example, are different from JavaScript both to validate user input as expected and to have the coercion reversible (to correctly validate cases where different types are defined in subschemas of "anyOf" and other compound keywords).
See [Coercion rules](https://github.com/epoberezkin/ajv/blob/master/COERCION.md) for details.
## API
##### new Ajv(Object options) -> Object
Create Ajv instance.
All the instance methods below are bound to the instance, so they can be used without the instance.
##### .compile(Object schema) -> Function<Object data>
Generate validating function and cache the compiled schema for future use.
Validating function returns boolean and has properties `errors` with the errors from the last validation (`null` if there were no errors) and `schema` with the reference to the original schema.
Unless the option `validateSchema` is false, the schema will be validated against meta-schema and if schema is invalid the error will be thrown. See [options](#options).
##### .compileAsync(Object schema [, Boolean meta] [, Function callback]) -> Promise
Asyncronous version of `compile` method that loads missing remote schemas using asynchronous function in `options.loadSchema`. This function returns a Promise that resolves to a validation function. An optional callback passed to `compileAsync` will be called with 2 parameters: error (or null) and validating function. The returned promise will reject (and callback if passed will be called with an error) when:
- missing schema can't be loaded (`loadSchema` returns the Promise that rejects).
- the schema containing missing reference is loaded, but the reference cannot be resolved.
- schema (or some referenced schema) is invalid.
The function compiles schema and loads the first missing schema (or meta-schema), until all missing schemas are loaded.
You can asynchronously compile meta-schema by passing `true` as the second parameter.
See example in [Asynchronous compilation](#asynchronous-schema-compilation).
##### .validate(Object schema|String key|String ref, data) -> Boolean
Validate data using passed schema (it will be compiled and cached).
Instead of the schema you can use the key that was previously passed to `addSchema`, the schema id if it was present in the schema or any previously resolved reference.
Validation errors will be available in the `errors` property of Ajv instance (`null` if there were no errors).
__Please note__: every time this method is called the errors are overwritten so you need to copy them to another variable if you want to use them later.
If the schema is asynchronous (has `$async` keyword on the top level) this method returns a Promise. See [Asynchronous validation](#asynchronous-validation).
##### .addSchema(Array<Object>|Object schema [, String key])
Add schema(s) to validator instance. This method does not compile schemas (but it still validates them). Because of that dependencies can be added in any order and circular dependencies are supported. It also prevents unnecessary compilation of schemas that are containers for other schemas but not used as a whole.
Array of schemas can be passed (schemas should have ids), the second parameter will be ignored.
Key can be passed that can be used to reference the schema and will be used as the schema id if there is no id inside the schema. If the key is not passed, the schema id will be used as the key.
Once the schema is added, it (and all the references inside it) can be referenced in other schemas and used to validate data.
Although `addSchema` does not compile schemas, explicit compilation is not required - the schema will be compiled when it is used first time.
By default the schema is validated against meta-schema before it is added, and if the schema does not pass validation the exception is thrown. This behaviour is controlled by `validateSchema` option.
##### .addMetaSchema(Array<Object>|Object schema [, String key])
Adds meta schema(s) that can be used to validate other schemas. That function should be used instead of `addSchema` because there may be instance options that would compile a meta schema incorrectly (at the moment it is `removeAdditional` option).
There is no need to explicitly add draft 6 meta schema (http://json-schema.org/draft-06/schema and http://json-schema.org/schema) - it is added by default, unless option `meta` is set to `false`. You only need to use it if you have a changed meta-schema that you want to use to validate your schemas. See `validateSchema`.
##### .validateSchema(Object schema) -> Boolean
Validates schema. This method should be used to validate schemas rather than `validate` due to the inconsistency of `uri` format in JSON-Schema standard.
By default this method is called automatically when the schema is added, so you rarely need to use it directly.
If schema doesn't have `$schema` property it is validated against draft 6 meta-schema (option `meta` should not be false).
If schema has `$schema` property then the schema with this id (that should be previously added) is used to validate passed schema.
Errors will be available at `ajv.errors`.
##### .getSchema(String key) -> Function<Object data>
Retrieve compiled schema previously added with `addSchema` by the key passed to `addSchema` or by its full reference (id). Returned validating function has `schema` property with the reference to the original schema.
##### .removeSchema([Object schema|String key|String ref|RegExp pattern])
Remove added/cached schema. Even if schema is referenced by other schemas it can be safely removed as dependent schemas have local references.
Schema can be removed using:
- key passed to `addSchema`
- it's full reference (id)
- RegExp that should match schema id or key (meta-schemas won't be removed)
- actual schema object that will be stable-stringified to remove schema from cache
If no parameter is passed all schemas but meta-schemas will be removed and the cache will be cleared.
##### .addFormat(String name, String|RegExp|Function|Object format)
Add custom format to validate strings or numbers. It can also be used to replace pre-defined formats for Ajv instance.
Strings are converted to RegExp.
Function should return validation result as `true` or `false`.
If object is passed it should have properties `validate`, `compare` and `async`:
- _validate_: a string, RegExp or a function as described above.
- _compare_: an optional comparison function that accepts two strings and compares them according to the format meaning. This function is used with keywords `formatMaximum`/`formatMinimum` (defined in [ajv-keywords](https://github.com/epoberezkin/ajv-keywords) package). It should return `1` if the first value is bigger than the second value, `-1` if it is smaller and `0` if it is equal.
- _async_: an optional `true` value if `validate` is an asynchronous function; in this case it should return a promise that resolves with a value `true` or `false`.
- _type_: an optional type of data that the format applies to. It can be `"string"` (default) or `"number"` (see https://github.com/epoberezkin/ajv/issues/291#issuecomment-259923858). If the type of data is different, the validation will pass.
Custom formats can be also added via `formats` option.
##### .addKeyword(String keyword, Object definition)
Add custom validation keyword to Ajv instance.
Keyword should be different from all standard JSON schema keywords and different from previously defined keywords. There is no way to redefine keywords or to remove keyword definition from the instance.
Keyword must start with a letter, `_` or `$`, and may continue with letters, numbers, `_`, `$`, or `-`.
It is recommended to use an application-specific prefix for keywords to avoid current and future name collisions.
Example Keywords:
- `"xyz-example"`: valid, and uses prefix for the xyz project to avoid name collisions.
- `"example"`: valid, but not recommended as it could collide with future versions of JSON schema etc.
- `"3-example"`: invalid as numbers are not allowed to be the first character in a keyword
Keyword definition is an object with the following properties:
- _type_: optional string or array of strings with data type(s) that the keyword applies to. If not present, the keyword will apply to all types.
- _validate_: validating function
- _compile_: compiling function
- _macro_: macro function
- _inline_: compiling function that returns code (as string)
- _schema_: an optional `false` value used with "validate" keyword to not pass schema
- _metaSchema_: an optional meta-schema for keyword schema
- _modifying_: `true` MUST be passed if keyword modifies data
- _valid_: pass `true`/`false` to pre-define validation result, the result returned from validation function will be ignored. This option cannot be used with macro keywords.
- _$data_: an optional `true` value to support [$data reference](#data-reference) as the value of custom keyword. The reference will be resolved at validation time. If the keyword has meta-schema it would be extended to allow $data and it will be used to validate the resolved value. Supporting $data reference requires that keyword has validating function (as the only option or in addition to compile, macro or inline function).
- _async_: an optional `true` value if the validation function is asynchronous (whether it is compiled or passed in _validate_ property); in this case it should return a promise that resolves with a value `true` or `false`. This option is ignored in case of "macro" and "inline" keywords.
- _errors_: an optional boolean indicating whether keyword returns errors. If this property is not set Ajv will determine if the errors were set in case of failed validation.
_compile_, _macro_ and _inline_ are mutually exclusive, only one should be used at a time. _validate_ can be used separately or in addition to them to support $data reference.
__Please note__: If the keyword is validating data type that is different from the type(s) in its definition, the validation function will not be called (and expanded macro will not be used), so there is no need to check for data type inside validation function or inside schema returned by macro function (unless you want to enforce a specific type and for some reason do not want to use a separate `type` keyword for that). In the same way as standard keywords work, if the keyword does not apply to the data type being validated, the validation of this keyword will succeed.
See [Defining custom keywords](#defining-custom-keywords) for more details.
##### .getKeyword(String keyword) -> Object|Boolean
Returns custom keyword definition, `true` for pre-defined keywords and `false` if the keyword is unknown.
##### .removeKeyword(String keyword)
Removes custom or pre-defined keyword so you can redefine them.
While this method can be used to extend pre-defined keywords, it can also be used to completely change their meaning - it may lead to unexpected results.
__Please note__: schemas compiled before the keyword is removed will continue to work without changes. To recompile schemas use `removeSchema` method and compile them again.
##### .errorsText([Array<Object> errors [, Object options]]) -> String
Returns the text with all errors in a String.
Options can have properties `separator` (string used to separate errors, ", " by default) and `dataVar` (the variable name that dataPaths are prefixed with, "data" by default).
## Options
Defaults:
```javascript
{
// validation and reporting options:
$data: false,
allErrors: false,
verbose: false,
jsonPointers: false,
uniqueItems: true,
unicode: true,
format: 'fast',
formats: {},
unknownFormats: true,
schemas: {},
// referenced schema options:
schemaId: undefined // recommended '$id'
missingRefs: true,
extendRefs: 'ignore', // recommended 'fail'
loadSchema: undefined, // function(uri: string): Promise {}
// options to modify validated data:
removeAdditional: false,
useDefaults: false,
coerceTypes: false,
// asynchronous validation options:
async: 'co*',
transpile: undefined, // requires ajv-async package
// advanced options:
meta: true,
validateSchema: true,
addUsedSchema: true,
inlineRefs: true,
passContext: false,
loopRequired: Infinity,
ownProperties: false,
multipleOfPrecision: false,
errorDataPath: 'object',
messages: true,
sourceCode: false,
processCode: undefined, // function (str: string): string {}
cache: new Cache,
serialize: undefined
}
```
##### Validation and reporting options
- _$data_: support [$data references]([$data reference](#data-reference)). Draft 6 meta-schema that is added by default will be extended to allow them. If you want to use another meta-schema you need to use $dataMetaSchema method to add support for $data reference. See [API](#api).
- _allErrors_: check all rules collecting all errors. Default is to return after the first error.
- _verbose_: include the reference to the part of the schema (`schema` and `parentSchema`) and validated data in errors (false by default).
- _jsonPointers_: set `dataPath` propery of errors using [JSON Pointers](https://tools.ietf.org/html/rfc6901) instead of JavaScript property access notation.
- _uniqueItems_: validate `uniqueItems` keyword (true by default).
- _unicode_: calculate correct length of strings with unicode pairs (true by default). Pass `false` to use `.length` of strings that is faster, but gives "incorrect" lengths of strings with unicode pairs - each unicode pair is counted as two characters.
- _format_: formats validation mode ('fast' by default). Pass 'full' for more correct and slow validation or `false` not to validate formats at all. E.g., 25:00:00 and 2015/14/33 will be invalid time and date in 'full' mode but it will be valid in 'fast' mode.
- _formats_: an object with custom formats. Keys and values will be passed to `addFormat` method.
- _unknownFormats_: handling of unknown formats. Option values:
- `true` (default) - if an unknown format is encountered the exception is thrown during schema compilation. If `format` keyword value is [$data reference](#data-reference) and it is unknown the validation will fail.
- `[String]` - an array of unknown format names that will be ignored. This option can be used to allow usage of third party schemas with format(s) for which you don't have definitions, but still fail if another unknown format is used. If `format` keyword value is [$data reference](#data-reference) and it is not in this array the validation will fail.
- `"ignore"` - to log warning during schema compilation and always pass validation (the default behaviour in versions before 5.0.0). This option is not recommended, as it allows to mistype format name and it won't be validated without any error message. This behaviour is required by JSON-schema specification.
- _schemas_: an array or object of schemas that will be added to the instance. If the order is important, pass array. In this case schemas must have IDs in them. Otherwise the object can be passed - `addSchema(value, key)` will be called for each schema in this object.
##### Referenced schema options
- _schemaId_: this option defines which keywords are used as schema URI. Option value:
- `"$id"` (recommended) - only use `$id` keyword as schema URI (as specified in JSON-Schema draft-06), ignore `id` keyword (if it is present a warning will be logged).
- `"id"` - only use `id` keyword as schema URI (as specified in JSON-Schema draft-04), ignore `$id` keyword (if it is present a warning will be logged).
- `undefined` (default) - use both `$id` and `id` keywords as schema URI. If both are present (in the same schema object) and different the exception will be thrown during schema compilation.
- _missingRefs_: handling of missing referenced schemas. Option values:
- `true` (default) - if the reference cannot be resolved during compilation the exception is thrown. The thrown error has properties `missingRef` (with hash fragment) and `missingSchema` (without it). Both properties are resolved relative to the current base id (usually schema id, unless it was substituted).
- `"ignore"` - to log error during compilation and always pass validation.
- `"fail"` - to log error and successfully compile schema but fail validation if this rule is checked.
- _extendRefs_: validation of other keywords when `$ref` is present in the schema. Option values:
- `"ignore"` (default) - when `$ref` is used other keywords are ignored (as per [JSON Reference](https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03#section-3) standard). A warning will be logged during the schema compilation.
- `"fail"` (recommended) - if other validation keywords are used together with `$ref` the exception will be thrown when the schema is compiled. This option is recomended to make sure schema has no keywords that are ignored, which can be confusing.
- `true` - validate all keywords in the schemas with `$ref` (the default behaviour in versions before 5.0.0).
- _loadSchema_: asynchronous function that will be used to load remote schemas when `compileAsync` [method](#api-compileAsync) is used and some reference is missing (option `missingRefs` should NOT be 'fail' or 'ignore'). This function should accept remote schema uri as a parameter and return a Promise that resolves to a schema. See example in [Asynchronous compilation](#asynchronous-schema-compilation).
##### Options to modify validated data
- _removeAdditional_: remove additional properties - see example in [Filtering data](#filtering-data). This option is not used if schema is added with `addMetaSchema` method. Option values:
- `false` (default) - not to remove additional properties
- `"all"` - all additional properties are removed, regardless of `additionalProperties` keyword in schema (and no validation is made for them).
- `true` - only additional properties with `additionalProperties` keyword equal to `false` are removed.
- `"failing"` - additional properties that fail schema validation will be removed (where `additionalProperties` keyword is `false` or schema).
- _useDefaults_: replace missing properties and items with the values from corresponding `default` keywords. Default behaviour is to ignore `default` keywords. This option is not used if schema is added with `addMetaSchema` method. See examples in [Assigning defaults](#assigning-defaults). Option values:
- `false` (default) - do not use defaults
- `true` - insert defaults by value (safer and slower, object literal is used).
- `"shared"` - insert defaults by reference (faster). If the default is an object, it will be shared by all instances of validated data. If you modify the inserted default in the validated data, it will be modified in the schema as well.
- _coerceTypes_: change data type of data to match `type` keyword. See the example in [Coercing data types](#coercing-data-types) and [coercion rules](https://github.com/epoberezkin/ajv/blob/master/COERCION.md). Option values:
- `false` (default) - no type coercion.
- `true` - coerce scalar data types.
- `"array"` - in addition to coercions between scalar types, coerce scalar data to an array with one element and vice versa (as required by the schema).
##### Asynchronous validation options
- _async_: determines how Ajv compiles asynchronous schemas (see [Asynchronous validation](#asynchronous-validation)) to functions. Option values:
- `"*"` / `"co*"` (default) - compile to generator function ("co*" - wrapped with `co.wrap`). If generators are not supported and you don't provide `processCode` option (or `transpile` option if you use [ajv-async](https://github.com/epoberezkin/ajv-async) package), the exception will be thrown when async schema is compiled.
- `"es7"` - compile to es7 async function. Unless your platform supports them you need to provide `processCode`/`transpile` option. According to [compatibility table](http://kangax.github.io/compat-table/es7/)) async functions are supported by:
- Firefox 52,
- Chrome 55,
- Node.js 7 (with `--harmony-async-await`),
- MS Edge 13 (with flag).
- `undefined`/`true` - auto-detect async mode. It requires [ajv-async](https://github.com/epoberezkin/ajv-async) package. If transpile option is not passed ajv-async will choose the first of supported/installed async/transpile modes in this order:
- "es7" (native async functions),
- "co*" (native generators with co.wrap),
- "es7"/"nodent",
- "co*"/"regenerator" during the creation of the Ajv instance.
If none of the options is available the exception will be thrown.
- _transpile_: Requires [ajv-async](https://github.com/epoberezkin/ajv-async) package. It determines whether Ajv transpiles compiled asynchronous validation function. Option values:
- `"nodent"` - transpile with [nodent](https://github.com/MatAtBread/nodent). If nodent is not installed, the exception will be thrown. nodent can only transpile es7 async functions; it will enforce this mode.
- `"regenerator"` - transpile with [regenerator](https://github.com/facebook/regenerator). If regenerator is not installed, the exception will be thrown.
- a function - this function should accept the code of validation function as a string and return transpiled code. This option allows you to use any other transpiler you prefer. If you are passing a function, you can simply pass it to `processCode` option without using ajv-async.
##### Advanced options
- _meta_: add [meta-schema](http://json-schema.org/documentation.html) so it can be used by other schemas (true by default). If an object is passed, it will be used as the default meta-schema for schemas that have no `$schema` keyword. This default meta-schema MUST have `$schema` keyword.
- _validateSchema_: validate added/compiled schemas against meta-schema (true by default). `$schema` property in the schema can either be http://json-schema.org/schema or http://json-schema.org/draft-04/schema or absent (draft-4 meta-schema will be used) or can be a reference to the schema previously added with `addMetaSchema` method. Option values:
- `true` (default) - if the validation fails, throw the exception.
- `"log"` - if the validation fails, log error.
- `false` - skip schema validation.
- _addUsedSchema_: by default methods `compile` and `validate` add schemas to the instance if they have `$id` (or `id`) property that doesn't start with "#". If `$id` is present and it is not unique the exception will be thrown. Set this option to `false` to skip adding schemas to the instance and the `$id` uniqueness check when these methods are used. This option does not affect `addSchema` method.
- _inlineRefs_: Affects compilation of referenced schemas. Option values:
- `true` (default) - the referenced schemas that don't have refs in them are inlined, regardless of their size - that substantially improves performance at the cost of the bigger size of compiled schema functions.
- `false` - to not inline referenced schemas (they will be compiled as separate functions).
- integer number - to limit the maximum number of keywords of the schema that will be inlined.
- _passContext_: pass validation context to custom keyword functions. If this option is `true` and you pass some context to the compiled validation function with `validate.call(context, data)`, the `context` will be available as `this` in your custom keywords. By default `this` is Ajv instance.
- _loopRequired_: by default `required` keyword is compiled into a single expression (or a sequence of statements in `allErrors` mode). In case of a very large number of properties in this keyword it may result in a very big validation function. Pass integer to set the number of properties above which `required` keyword will be validated in a loop - smaller validation function size but also worse performance.
- _ownProperties_: by default Ajv iterates over all enumerable object properties; when this option is `true` only own enumerable object properties (i.e. found directly on the object rather than on its prototype) are iterated. Contributed by @mbroadst.
- _multipleOfPrecision_: by default `multipleOf` keyword is validated by comparing the result of division with parseInt() of that result. It works for dividers that are bigger than 1. For small dividers such as 0.01 the result of the division is usually not integer (even when it should be integer, see issue [#84](https://github.com/epoberezkin/ajv/issues/84)). If you need to use fractional dividers set this option to some positive integer N to have `multipleOf` validated using this formula: `Math.abs(Math.round(division) - division) < 1e-N` (it is slower but allows for float arithmetics deviations).
- _errorDataPath_: set `dataPath` to point to 'object' (default) or to 'property' when validating keywords `required`, `additionalProperties` and `dependencies`.
- _messages_: Include human-readable messages in errors. `true` by default. `false` can be passed when custom messages are used (e.g. with [ajv-i18n](https://github.com/epoberezkin/ajv-i18n)).
- _sourceCode_: add `sourceCode` property to validating function (for debugging; this code can be different from the result of toString call).
- _processCode_: an optional function to process generated code before it is passed to Function constructor. It can be used to either beautify (the validating function is generated without line-breaks) or to transpile code. Starting from version 5.0.0 this option replaced options:
- `beautify` that formatted the generated function using [js-beautify](https://github.com/beautify-web/js-beautify). If you want to beautify the generated code pass `require('js-beautify').js_beautify`.
- `transpile` that transpiled asynchronous validation function. You can still use `transpile` option with [ajv-async](https://github.com/epoberezkin/ajv-async) package. See [Asynchronous validation](#asynchronous-validation) for more information.
- _cache_: an optional instance of cache to store compiled schemas using stable-stringified schema as a key. For example, set-associative cache [sacjs](https://github.com/epoberezkin/sacjs) can be used. If not passed then a simple hash is used which is good enough for the common use case (a limited number of statically defined schemas). Cache should have methods `put(key, value)`, `get(key)`, `del(key)` and `clear()`.
- _serialize_: an optional function to serialize schema to cache key. Pass `false` to use schema itself as a key (e.g., if WeakMap used as a cache). By default [json-stable-stringify](https://github.com/substack/json-stable-stringify) is used.
## Validation errors
In case of validation failure Ajv assigns the array of errors to `.errors` property of validation function (or to `.errors` property of Ajv instance in case `validate` or `validateSchema` methods were called). In case of [asynchronous validation](#asynchronous-validation) the returned promise is rejected with the exception of the class `Ajv.ValidationError` that has `.errors` poperty.
### Error objects
Each error is an object with the following properties:
- _keyword_: validation keyword.
- _dataPath_: the path to the part of the data that was validated. By default `dataPath` uses JavaScript property access notation (e.g., `".prop[1].subProp"`). When the option `jsonPointers` is true (see [Options](#options)) `dataPath` will be set using JSON pointer standard (e.g., `"/prop/1/subProp"`).
- _schemaPath_: the path (JSON-pointer as a URI fragment) to the schema of the keyword that failed validation.
- _params_: the object with the additional information about error that can be used to create custom error messages (e.g., using [ajv-i18n](https://github.com/epoberezkin/ajv-i18n) package). See below for parameters set by all keywords.
- _message_: the standard error message (can be excluded with option `messages` set to false).
- _schema_: the schema of the keyword (added with `verbose` option).
- _parentSchema_: the schema containing the keyword (added with `verbose` option)
- _data_: the data validated by the keyword (added with `verbose` option).
__Please note__: `propertyNames` keyword schema validation errors have an additional property `propertyName`, `dataPath` points to the object. After schema validation for each property name, if it is invalid an additional error is added with the property `keyword` equal to `"propertyNames"`.
### Error parameters
Properties of `params` object in errors depend on the keyword that failed validation.
- `maxItems`, `minItems`, `maxLength`, `minLength`, `maxProperties`, `minProperties` - property `limit` (number, the schema of the keyword).
- `additionalItems` - property `limit` (the maximum number of allowed items in case when `items` keyword is an array of schemas and `additionalItems` is false).
- `additionalProperties` - property `additionalProperty` (the property not used in `properties` and `patternProperties` keywords).
- `dependencies` - properties:
- `property` (dependent property),
- `missingProperty` (required missing dependency - only the first one is reported currently)
- `deps` (required dependencies, comma separated list as a string),
- `depsCount` (the number of required dependedncies).
- `format` - property `format` (the schema of the keyword).
- `maximum`, `minimum` - properties:
- `limit` (number, the schema of the keyword),
- `exclusive` (boolean, the schema of `exclusiveMaximum` or `exclusiveMinimum`),
- `comparison` (string, comparison operation to compare the data to the limit, with the data on the left and the limit on the right; can be "<", "<=", ">", ">=")
- `multipleOf` - property `multipleOf` (the schema of the keyword)
- `pattern` - property `pattern` (the schema of the keyword)
- `required` - property `missingProperty` (required property that is missing).
- `propertyNames` - property `propertyName` (an invalid property name).
- `patternRequired` (in ajv-keywords) - property `missingPattern` (required pattern that did not match any property).
- `type` - property `type` (required type(s), a string, can be a comma-separated list)
- `uniqueItems` - properties `i` and `j` (indices of duplicate items).
- `enum` - property `allowedValues` pointing to the array of values (the schema of the keyword).
- `$ref` - property `ref` with the referenced schema URI.
- custom keywords (in case keyword definition doesn't create errors) - property `keyword` (the keyword name).
## Related packages
- [ajv-cli](https://github.com/epoberezkin/ajv-cli) - command line interface for Ajv
- [ajv-i18n](https://github.com/epoberezkin/ajv-i18n) - internationalised error messages
- [ajv-merge-patch](https://github.com/epoberezkin/ajv-merge-patch) - keywords $merge and $patch.
- [ajv-keywords](https://github.com/epoberezkin/ajv-keywords) - several custom keywords that can be used with Ajv (typeof, instanceof, range, propertyNames)
## Some packages using Ajv
- [webpack](https://github.com/webpack/webpack) - a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser
- [jsonscript-js](https://github.com/JSONScript/jsonscript-js) - the interpreter for [JSONScript](http://www.jsonscript.org) - scripted processing of existing endpoints and services
- [osprey-method-handler](https://github.com/mulesoft-labs/osprey-method-handler) - Express middleware for validating requests and responses based on a RAML method object, used in [osprey](https://github.com/mulesoft/osprey) - validating API proxy generated from a RAML definition
- [har-validator](https://github.com/ahmadnassri/har-validator) - HTTP Archive (HAR) validator
- [jsoneditor](https://github.com/josdejong/jsoneditor) - a web-based tool to view, edit, format, and validate JSON http://jsoneditoronline.org
- [JSON Schema Lint](https://github.com/nickcmaynard/jsonschemalint) - a web tool to validate JSON/YAML document against a single JSON-schema http://jsonschemalint.com
- [objection](https://github.com/vincit/objection.js) - SQL-friendly ORM for node.js
- [table](https://github.com/gajus/table) - formats data into a string table
- [ripple-lib](https://github.com/ripple/ripple-lib) - a JavaScript API for interacting with [Ripple](https://ripple.com) in Node.js and the browser
- [restbase](https://github.com/wikimedia/restbase) - distributed storage with REST API & dispatcher for backend services built to provide a low-latency & high-throughput API for Wikipedia / Wikimedia content
- [hippie-swagger](https://github.com/CacheControl/hippie-swagger) - [Hippie](https://github.com/vesln/hippie) wrapper that provides end to end API testing with swagger validation
- [react-form-controlled](https://github.com/seeden/react-form-controlled) - React controlled form components with validation
- [rabbitmq-schema](https://github.com/tjmehta/rabbitmq-schema) - a schema definition module for RabbitMQ graphs and messages
- [@query/schema](https://www.npmjs.com/package/@query/schema) - stream filtering with a URI-safe query syntax parsing to JSON Schema
- [chai-ajv-json-schema](https://github.com/peon374/chai-ajv-json-schema) - chai plugin to us JSON-schema with expect in mocha tests
- [grunt-jsonschema-ajv](https://github.com/SignpostMarv/grunt-jsonschema-ajv) - Grunt plugin for validating files against JSON-Schema
- [extract-text-webpack-plugin](https://github.com/webpack-contrib/extract-text-webpack-plugin) - extract text from bundle into a file
- [electron-builder](https://github.com/electron-userland/electron-builder) - a solution to package and build a ready for distribution Electron app
- [addons-linter](https://github.com/mozilla/addons-linter) - Mozilla Add-ons Linter
- [gh-pages-generator](https://github.com/epoberezkin/gh-pages-generator) - multi-page site generator converting markdown files to GitHub pages
## Tests
```
npm install
git submodule update --init
npm test
```
## Contributing
All validation functions are generated using doT templates in [dot](https://github.com/epoberezkin/ajv/tree/master/lib/dot) folder. Templates are precompiled so doT is not a run-time dependency.
`npm run build` - compiles templates to [dotjs](https://github.com/epoberezkin/ajv/tree/master/lib/dotjs) folder.
`npm run watch` - automatically compiles templates when files in dot folder change
Please see [Contributing guidelines](https://github.com/epoberezkin/ajv/blob/master/CONTRIBUTING.md)
## Changes history
See https://github.com/epoberezkin/ajv/releases
__Please note__: [Changes in version 5.0.0](https://github.com/epoberezkin/ajv/releases/tag/5.0.0).
[Changes in version 4.6.0](https://github.com/epoberezkin/ajv/releases/tag/4.6.0).
[Changes in version 4.0.0](https://github.com/epoberezkin/ajv/releases/tag/4.0.0).
[Changes in version 3.0.0](https://github.com/epoberezkin/ajv/releases/tag/3.0.0).
[Changes in version 2.0.0](https://github.com/epoberezkin/ajv/releases/tag/2.0.0).
## License
[MIT](https://github.com/epoberezkin/ajv/blob/master/LICENSE)
ajv-5.0.0/bower.json 0000664 0000000 0000000 00000000634 13075146637 0014324 0 ustar 00root root 0000000 0000000 {
"name": "ajv",
"description": "Another JSON Schema Validator",
"main": "dist/ajv.min.js",
"authors": [
"Evgeny Poberezkin"
],
"license": "MIT",
"keywords": [
"JSON",
"schema",
"validator"
],
"homepage": "https://github.com/epoberezkin/ajv",
"moduleType": [
"amd",
"globals",
"node"
],
"ignore": [
"node_modules",
"bower_components",
"spec"
]
}
ajv-5.0.0/circle.yml 0000664 0000000 0000000 00000001203 13075146637 0014270 0 ustar 00root root 0000000 0000000 machine:
node:
version: 4
general:
branches:
ignore:
- gh-pages
checkout:
post:
- git submodule sync
- git submodule update --init
dependencies:
post:
- wget https://saucelabs.com/downloads/sc-latest-linux.tar.gz
- tar -xzf sc-latest-linux.tar.gz
test:
override:
- cd sc-*-linux && ./bin/sc --user $SAUCE_USERNAME --api-key $SAUCE_ACCESS_KEY --readyfile ~/sauce_is_ready:
background: true
- while [ ! -e ~/sauce_is_ready ]; do sleep 1; done
- scripts/prepare-tests
- karma start karma.sauce.js
post:
- killall --wait sc # wait for Sauce Connect to close the tunnel
ajv-5.0.0/karma.conf.js 0000664 0000000 0000000 00000003141 13075146637 0014664 0 ustar 00root root 0000000 0000000 // Karma configuration
// Generated on Thu Mar 13 2014 14:12:04 GMT-0700 (PDT)
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha'],
// list of files / patterns to load in the browser
files: [
'dist/ajv.min.js',
'node_modules/chai/chai.js',
'dist/regenerator.min.js',
'dist/nodent.min.js',
'node_modules/bluebird/js/browser/bluebird.core.min.js',
'.browser/*.spec.js'
],
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['dots'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
browsers: ['Chrome'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: true,
browserNoActivityTimeout: 90000
});
};
ajv-5.0.0/karma.sauce.js 0000664 0000000 0000000 00000007063 13075146637 0015046 0 ustar 00root root 0000000 0000000 'use strict';
var fs = require('fs');
module.exports = function(config) {
// Use ENV vars on Travis and sauce.json locally to get credentials
if (!process.env.SAUCE_USERNAME) {
if (!fs.existsSync('sauce.json')) {
console.log('Create a sauce.json with your credentials based on the sauce-sample.json file.');
process.exit(1);
} else {
process.env.SAUCE_USERNAME = require('./sauce').username;
process.env.SAUCE_ACCESS_KEY = require('./sauce').accessKey;
}
}
// Browsers to run on Sauce Labs
var customLaunchers = {
'SL_Chrome_27': {
base: 'SauceLabs',
browserName: 'chrome',
version: '27'
},
// 'SL_Chrome_37': {
// base: 'SauceLabs',
// browserName: 'chrome',
// version: '37'
// },
'SL_Chrome': {
base: 'SauceLabs',
browserName: 'chrome'
},
'SL_InternetExplorer_9': {
base: 'SauceLabs',
browserName: 'internet explorer',
version: '9'
},
'SL_InternetExplorer_10': {
base: 'SauceLabs',
browserName: 'internet explorer',
version: '10'
},
'SL_InternetExplorer_11': {
base: 'SauceLabs',
browserName: 'internet explorer',
version: '11' // default
},
'SL_MicrosoftEdge': {
base: 'SauceLabs',
browserName: 'MicrosoftEdge'
},
'SL_FireFox_17': {
base: 'SauceLabs',
browserName: 'firefox',
version: '17'
},
// 'SL_FireFox_24': {
// base: 'SauceLabs',
// browserName: 'firefox',
// version: '24'
// },
'SL_FireFox': {
base: 'SauceLabs',
browserName: 'firefox'
},
'SL_Safari_5': {
base: 'SauceLabs',
browserName: 'safari',
version: '5' // default
},
// 'SL_Safari_7': {
// base: 'SauceLabs',
// browserName: 'safari',
// version: '7'
// },
'SL_Safari_9': {
base: 'SauceLabs',
browserName: 'safari',
version: '9'
},
'SL_iPhone_8': {
base: 'SauceLabs',
browserName: 'iphone',
version: '8.4'
},
'SL_iPhone_9': {
base: 'SauceLabs',
browserName: 'iphone',
version: '9.2'
}
// 'SL_Android_4': {
// base: 'SauceLabs',
// browserName: 'android',
// version: '4'
// }
};
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha'],
// list of files / patterns to load in the browser
files: [
'dist/ajv.min.js',
'node_modules/chai/chai.js',
'dist/nodent.min.js',
'node_modules/bluebird/js/browser/bluebird.core.min.js',
'.browser/*.spec.js'
],
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['dots', 'saucelabs'],
// web server port
port: 9876,
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
sauceLabs: {
testName: 'Ajv',
'idleTimeout': 900
},
captureTimeout: 1200000,
browserNoActivityTimeout: 600000,
browserDisconnectTimeout: 60000,
customLaunchers: customLaunchers,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: Object.keys(customLaunchers),
singleRun: true
});
};
ajv-5.0.0/lib/ 0000775 0000000 0000000 00000000000 13075146637 0013056 5 ustar 00root root 0000000 0000000 ajv-5.0.0/lib/$data.js 0000664 0000000 0000000 00000002027 13075146637 0014372 0 ustar 00root root 0000000 0000000 'use strict';
var KEYWORDS = [
'multipleOf',
'maximum',
'exclusiveMaximum',
'minimum',
'exclusiveMinimum',
'maxLength',
'minLength',
'pattern',
'additionalItems',
'maxItems',
'minItems',
'uniqueItems',
'maxProperties',
'minProperties',
'required',
'additionalProperties',
'enum',
'format',
'const'
];
module.exports = function (metaSchema, keywordsJsonPointers) {
for (var i=0; i