ajv-validator / ajv Goto Github PK
View Code? Open in Web Editor NEWThe fastest JSON schema Validator. Supports JSON Schema draft-04/06/07/2019-09/2020-12 and JSON Type Definition (RFC8927)
Home Page: https://ajv.js.org
License: MIT License
The fastest JSON schema Validator. Supports JSON Schema draft-04/06/07/2019-09/2020-12 and JSON Type Definition (RFC8927)
Home Page: https://ajv.js.org
License: MIT License
The following schema fails to parse when using AJV but it does pass when pasted into http://jsonschemalint.com/draft4/
Is this a bug in AJV or am I doing something wrong with this schema that the linter isn't catching? I'm very new to AJV and JSON Schema so would definitely not rule out user error here. Thanks!
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Create User",
"description": "Create User POST Request",
"type": "object",
"properties": {
"data": {
"description": "Top level data object",
"type": "object",
"properties":{
"type": {"type":"string"},
"attributes": {
"type":"object",
"properties": {
"username":{"type":"string"},
"email":{"type":"string"},
"full-name":{"type":"string"},
"password":{"type":"string"},
"is-admin":{"type":"boolean"},
"enabled":{"type":"boolean"}
},
"required":["username", "email", "full-name", "password", "is-admin", "enabled"],
"additionalProperties": false
}
},
"required":["type", "attributes"],
"additionalProperties": false
}
},
"required": ["data"],
"additionalProperties": false
}
The error I get is:
SyntaxError: Unexpected identifier
at Ajv.compile (/Users/sarus/workspace/rest/node_modules/ajv/lib/compile/index.js:52:10)
at _addSchema (/Users/sarus/workspace/rest/node_modules/ajv/lib/ajv.js:163:38)
at Ajv.compile (/Users/sarus/workspace/rest/node_modules/ajv/lib/ajv.js:75:16)
at Object.<anonymous> (/Users/sarus/workspace/rest/lib/routes.js:20:20)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at new require (module.js:384:17)
at Object.module.exports.start (/Users/sarus/workspace/rest/lib/server.js:13:23)
at Object.<anonymous> (/Users/sarus/workspace/rest/hamachi.js:1:87)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
Error compiling schema, function code: validate = function (data, dataPath) { 'use strict'; validate.errors = null; var errors = 0; if ((data && typeof data === "object" && !Array.isArray(data))) { var missing0; if ( ( data.data === undefined && (missing0 = '.data') ) ) { validate.errors = [ { keyword: 'required', dataPath: (dataPath || '') + "" + missing0, message: 'property ' + missing0 + ' is required' }]; return false; } else { var errs0 = errors;var valid1 = true; var propertiesSchema0 = validate.schema.properties || {}; for (var key0 in data) { var isAdditional0 = propertiesSchema0[key0] === undefined; if (isAdditional0) { valid1 = false; validate.errors = [ { keyword: 'additionalProperties', dataPath: (dataPath || '') + "['" + key0 + "']", message: 'additional properties NOT allowed' }]; return false; break; } } if (valid1) { var data1 = data.data; if (data1 === undefined) { valid1 = true; } else { var errs_1 = errors; if ((data1 && typeof data1 === "object" && !Array.isArray(data1))) { var missing1; if ( ( data1.type === undefined && (missing1 = '.type') ) || ( data1.attributes === undefined && (missing1 = '.attributes') ) ) { var err = { keyword: 'required', dataPath: (dataPath || '') + ".data" + missing1, message: 'property ' + missing1 + ' is required' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; } else { var errs1 = errors;var valid2 = true; var propertiesSchema1 = validate.schema.properties.data.properties || {}; for (var key1 in data1) { var isAdditional1 = propertiesSchema1[key1] === undefined; if (isAdditional1) { valid2 = false; var err = { keyword: 'additionalProperties', dataPath: (dataPath || '') + ".data['" + key1 + "']", message: 'additional properties NOT allowed' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; break; } } if (valid2) { if (data1.type === undefined) { valid2 = true; } else { var errs_2 = errors; if (typeof data1.type !== "string") { var err = { keyword: 'type', dataPath: (dataPath || '') + ".data.type", message: 'should be string' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; } var valid2 = errors === errs_2; } if (valid2) { var data2 = data1.attributes; if (data2 === undefined) { valid2 = true; } else { var errs_2 = errors; if ((data2 && typeof data2 === "object" && !Array.isArray(data2))) { var missing2; if ( ( data2.username === undefined && (missing2 = '.username') ) || ( data2.email === undefined && (missing2 = '.email') ) || ( data2['full-name'] === undefined && (missing2 = '['full-name']') ) || ( data2.password === undefined && (missing2 = '.password') ) || ( data2['is-admin'] === undefined && (missing2 = '['is-admin']') ) || ( data2.enabled === undefined && (missing2 = '.enabled') ) ) { var err = { keyword: 'required', dataPath: (dataPath || '') + ".data.attributes" + missing2, message: 'property ' + missing2 + ' is required' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; } else { var errs2 = errors;var valid3 = true; var propertiesSchema2 = validate.schema.properties.data.properties.attributes.properties || {}; for (var key2 in data2) { var isAdditional2 = propertiesSchema2[key2] === undefined; if (isAdditional2) { valid3 = false; var err = { keyword: 'additionalProperties', dataPath: (dataPath || '') + ".data.attributes['" + key2 + "']", message: 'additional properties NOT allowed' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; break; } } if (valid3) { if (data2.username === undefined) { valid3 = true; } else { var errs_3 = errors; if (typeof data2.username !== "string") { var err = { keyword: 'type', dataPath: (dataPath || '') + ".data.attributes.username", message: 'should be string' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; } var valid3 = errors === errs_3; } if (valid3) { if (data2.email === undefined) { valid3 = true; } else { var errs_3 = errors; if (typeof data2.email !== "string") { var err = { keyword: 'type', dataPath: (dataPath || '') + ".data.attributes.email", message: 'should be string' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; } var valid3 = errors === errs_3; } if (valid3) { if (data2['full-name'] === undefined) { valid3 = true; } else { var errs_3 = errors; if (typeof data2['full-name'] !== "string") { var err = { keyword: 'type', dataPath: (dataPath || '') + ".data.attributes['full-name']", message: 'should be string' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; } var valid3 = errors === errs_3; } if (valid3) { if (data2.password === undefined) { valid3 = true; } else { var errs_3 = errors; if (typeof data2.password !== "string") { var err = { keyword: 'type', dataPath: (dataPath || '') + ".data.attributes.password", message: 'should be string' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; } var valid3 = errors === errs_3; } if (valid3) { if (data2['is-admin'] === undefined) { valid3 = true; } else { var errs_3 = errors; if (typeof data2['is-admin'] !== "boolean") { var err = { keyword: 'type', dataPath: (dataPath || '') + ".data.attributes['is-admin']", message: 'should be boolean' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; } var valid3 = errors === errs_3; } if (valid3) { if (data2.enabled === undefined) { valid3 = true; } else { var errs_3 = errors; if (typeof data2.enabled !== "boolean") { var err = { keyword: 'type', dataPath: (dataPath || '') + ".data.attributes.enabled", message: 'should be boolean' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; } var valid3 = errors === errs_3; } }}}}}} } } else { var err = { keyword: 'type', dataPath: (dataPath || '') + ".data.attributes", message: 'should be object' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; } var valid2 = errors === errs_2; } }} } } else { var err = { keyword: 'type', dataPath: (dataPath || '') + ".data", message: 'should be object' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; } var valid1 = errors === errs_1; } } } } else { validate.errors = [ { keyword: 'type', dataPath: (dataPath || '') + "", message: 'should be object' }]; return false; } return errors === 0; }
When schemas are added to a validator using 'addSchema', referenced schemas that contain internal references result in 'can't resolve reference' errors. This does not happen if the schemas are added to the validator (in the correct order) using 'compile'.
Here is a test that demonstrates the behaviour:
describe.only("references with 'definitions'", function () {
var ajv = require("ajv");
function spec(name) {
var method,
result,
validator;
validator = ajv();
method = validator[name];
method.call(validator, {
definitions: {
name: { type: "string" }
},
id: "http://schemas.domain.xyz/test/person.json#",
properties: {
name: { $ref: "#/definitions/name"}
},
type: "object"
});
method.call(validator, {
id: "http://schemas.domain.xyz/test/employee.json#",
properties: {
person: { $ref: "/test/person.json#" },
role: { type: "string" }
},
type: "object"
});
result = validator.validate("http://schemas.domain.xyz/test/employee.json#", {
person: {
name: "Alice"
},
role: "Programmer"
});
expect(result).to.be.true;
expect(validator.errors).to.be.null;
}
it("should be supported by 'addSchema'", function () {
spec("addSchema");
});
it("should be supported by 'compile'", function () {
spec("compile");
});
});
I've looked through the source and the issue appears to have something to do with the root that's passed to the 'compile' function.
When the schemas are added with 'compile', they are compiled independently; no root is passed for the referenced schema and its internal reference is resolved correctly. The 'resolveRef' function receives:
baseId = http://schemas.domain.xyz/test/person.json#
ref = #/definitions/name
When the schemas are added with 'addSchema', the referenced schema is compiled when the referencing schema is compiled and the referencing schema is passed as the root. In this case, the root appears to be used to resolve the referenced schema's internal reference. That is, the 'resolveRef' function receives:
baseId = http://schemas.domain.xyz/test/employee.json#
ref = #/definitions/name
Is is possible for validate function to resolve ids inside schemas ?
example :
var ajv = require('ajv')();
ajv.addSchema({
id: 'my-schema',
type: 'object',
definitions: {
foo: {
id: 'foo',
type: 'object',
required: ['bar']
}
}
}, 'my-schema');
ajv.validate(
'my-schema#/definitions/foo', {
bar: true
});
// throws Error: no schema with key or ref "my-schema#/definitions/foo"
We are working on Redis and I think it would be perfect if ajv can retrieve schemas from Redis async.
I am writing test cases using Jasmine and need to use ajv through my browser.
I have already attempted to use it with browserify but it doesn't seem to work. Please provide a quick example as to how to use it within browser after bundling the package using browserify.
Here is what I have done so far:
browserify node_modules/ajv/lib/ajv.js -o node_modules/ajv/lib/bundle.js
and added that into my jasmine Spec file using:
<script src="../../node_modules/ajv/lib/bundle.js"></script>
Then??
See skipped test in https://github.com/epoberezkin/ajv/blob/master/spec/async.spec.js
It can be a property inside properties
, patternProperties
or enum
keywords
See #61
Everything is working great, I'm just wondering what's the best way to make the errors easier to track down and fix in the data object.
For example, I get an error that looks like this:
{ keyword: "required",
dataPath: ".assetGroups['166'].previewUrl",
message: "should have required property .previewUrl" }
Tracking down assetGroup object 166 in an array of 200 of them, is not that easy. Maybe if I used some sort of a good JSON editor it would help. However, would it be possible to instead of showing number 166 perhaps use another property that is available on that assetGroup.
So let's say that my assetGroup object 166 looks like this:
{ id: "cats" }
Could the error message look more like
{ keyword: "required",
dataPath: ".assetGroups['166'].previewUrl",
prettyDataPath: "assetGroups[cats].previewUrl",
message: "should have required property .previewUrl" }
It would make it a lot easier for me to find the object if I search for "cats".
Or maybe there could be a way to use the dataPath to programatically work backwords in the data to get the full objects that relate to the error?
Any suggestions are welcome :)
We want to use ajv to validate complex configurations against predefined schemas, but our application is in German and English, so we would like to translate the error messages.
I guess the error messages are coming from def._errorMessages in lib/dot/definitions.def, so maybe we could choose one set of translations there, dependent of some variable, but I have no experience with dot-templating.
Sorry for the premature issue-creation, I accidentally hit some kind of github-shortcut.
Hi, I'm trying to get some clarity on a potential issue I'm seeing. In running the following:
const ajv = Ajv({verbose: false, allErrors: true});
ajv.addSchema([
require('./schemas/Currency.json'),
require('./schemas/PositiveFloatString.json'),
require('./schemas/Amount.json'),
require('./schemas/Party.json'),
])
function isValid(object, schemaName) {
return ajv.validate(schemaName, object);
}
function validate(object, schemaName) {
if (!isValid(object, schemaName)) {
return {
isValid: false,
errors: ajv.errors
};
}
return {
isValid: true
};
}
console.log(validator.validate({
entity: 'acct:[email protected]',
amount: {
currency: 'USD'
}
}, 'Party'));
I get the following:
{
isValid: false,
errors: [{
keyword: 'required',
dataPath: '.amount',
message: 'properties value, currency are required'
}]
}
Ideally I would like to see something more along the lines of:
{
isValid: false,
errors: [{
keyword: 'required',
dataPath: '.amount.value',
message: 'property value is required'
}]
}
I was wondering if this was an issue with my implementation / schemas or if it is a shortcoming of ajv?
Thanks in advance.
My schemas are as follows:
Party.json
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "Party",
"title": "Party",
"description": "Represents a single party to a payment.",
"type": "object",
"properties": {
"name": {
"$ref": "Account"
},
"amount": {
"description": "How much this party will send or receive in the payment.",
"$ref": "Amount"
}
},
"additionalProperties": false,
"required": ["name", "amount"]
}
Amount.json
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "Amount",
"title": "Amount",
"type": "object",
"properties": {
"value": {
"$ref": "PositiveFloatString"
},
"currency": {
"type": "string",
"$ref": "Currency"
}
},
"additionalProperties": false,
"required": ["value", "currency"]
}
PositiveFloatString.json
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "PositiveFloatString",
"title": "PositiveFloatString",
"description": "A string representation of a floating point number",
"type": "string",
"pattern": "^[+]?[0-9]*[.]?[0-9]+([eE][-+]?[0-9]+)?$"
}
Currency.json
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "Currency",
"title": "Currency",
"type": "string",
"pattern": "^(([a-zA-Z0-9]{3})|([a-fA-F0-9]{40}))$"
}
Are they supposed to be? Looks like they haven't been included since release like, 1.2 - how are people using it without manually compiling them (aka, installed from npm).
Correct me if I'm doing something wrong. Wrote this based on: http://spacetelescope.github.io/understanding-json-schema/index.html
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "testrec",
"type": "object",
"properties": {
"layout": {
"id": "layout",
"type": "object",
"properties": {
"layout": { "type": "string" },
"panels": {
"type": "array",
"items": {
"oneOf": [
{ "type": "string" },
{ "$ref": "layout" }
]
}
}
},
"required": [
"layout",
"panels"
]
}
}
}
See #43
Hello, I'm using Node.js v4.1.1 and Ajv v1.4.2
Test case
var Ajv = require("ajv"),
schema = {
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "/^\w+$/"
}
}
};
var ajv = Ajv();
var validate = ajv.compile(schema);
validate({name: "John"}); // returns false
console.log(validate.errors)
[ { keyword: 'pattern',
dataPath: '.name',
message: 'should match pattern "/^w+$/"' } ]
A couple of minor (subjective) things that would go a bit to helping out others (like me) get started committing.
bin/
to scripts/
, node modules normally reserve bin/
for CLIs that the module exposespre-commit
node module and remove bin/git-hook
- it would do very similar things in the end, except the pre-commit
module just works automatically (by default it'll run the tests, but you can change that if you only want to compile templates - I usually do both in my test script and I made that change with #33)package.json
"scripts"
- makes script discovery much easier and you can probably remove half the one liners you have in bin/
right now in favour of npm run bundle
, npm run pretest
, etc.karma
tests to the npm test
script - I only just discovered that it's even an option and I've glanced over it a dozen timesI can make a PR with these options enabled/disabled - just let me know which you don't want.
It would be perfect if ajv can create default object from the schema. Is there any way to put this feature on this lovely, fastest almost perfect ;) beauty?
i would like to remove all additional properties but dataPath is always empty when err type is additionalProperties!
"schema": {
"id": "http://localhost:1234/issue14b.json",
"type": "array",
"items": { "$ref": "buu.json#/definitions/buu" }
}
{
"id": "http://localhost:1234/buu.json",
"definitions": {
"buu": {
"type": "object",
"properties": {
"bar": { "$ref": "bar.json" }
}
}
}
}
{
"id": "http://localhost:1234/bar.json",
"type": "string"
}
Data:
[
{
"bar": "any string"
}
]
Loses resolution scope when it gets in definitions
I'm curious, but why did you use a custom notation instead of using JSON Pointers in error objects?
If a schema has a $ref and compileAsync is called on it while another compileAsync is running on it then ajv randomly throws. Here is an example:
var Ajv = require('ajv');
var schemas = {
"http://example.com/parent.json": {
"id": "http://example.com/parent.json",
"required": [
"a"
],
"properties": {
"a": { "$ref": "child.json" }
}
},
"http://example.com/child.json": {
"id": "http://example.com/child.json",
"required": [
"b"
],
"properties": {
"b": { "type": "string" }
}
}
};
var ajv = Ajv({
loadSchema: function(uri, callback) {
setTimeout(function() {
callback(null, schemas[uri]);
});
}
});
ajv.compileAsync(schemas["http://example.com/parent.json"], function(err, validate) {
console.log(validate({a: { b: "test"} }));
});
ajv.compileAsync(schemas["http://example.com/parent.json"], function(err, validate) {
console.log(validate({a: { b: "test"} }));
});
Which typically results in the exception:
Error: schema with key or id "http://example.com/child.json" already exists
Like jayschema, can you add a client command, like 'ajv'
ajv --externalschema=xxxxx my.schema.json
Thnak
Ami44
Hi
Can custom formats be async?
Thanks
Simon
When schema is added, before it is compiled, it is validated against schema in $schema
property (unless validateSchema
option is false). If $schema property is not present draft 4 meta-schema is used.
If validator instance has removeAdditional
option this schema validation may cause changing the schema (for draft 4 meta-schema it is prevented - it is compiled without this option even if this option is present).
The solution is to add removeAdditional
option to validate
method rather than to validator instance.
Given a JSONPath (or similar structure) and a schema, is there a good way to determine the type ('string', 'object', etc) for a value at that path?
JSONPath store.book[0].title
might resolve to 'string' against a schema for a book store record.
Would the best approach be to just navigate the schema structure directly?
In JSON schema it's often useful for declare defaults
, with the default value for an optional property. This is powerful for documentation, and many validators supports inserting the default into the validated object, this way you don't hardcode defaults into your code, but declare the defaults in your input schema.
Example A)
var Ajv = require('ajv');
var ajv = Ajv({mergeDefaults: true}); // Specify that we want defaults merged
var validate = ajv.compile({
type: "object",
properties: {
myProp: { // optional property
type: "string",
default: "Hello World" // default value
}
}
});
var data = {
someOtherProp: "another value"
};
validate(data); // true
console.log(data)
// {someOtherProp: "another value", myProp: "Hello World"}
This would be extremely useful, and doing this outside of the schema validation is hard, as you want to do this on all sub-objects as well, some of which may exist under an anyOf
, so you can't insert the defaults until you're sure which anyOf
branch is satisfied.
It's quite possible that this is a post processing step, as nested anyOf
branches means you sometimes can't do this until after everything is validated. A possible work around might be to insert the defaults into a clone of the existing object, that way multiple anyOf
branches shouldn't be a problem.
Note, this only really relevant for objects, but could also be done for arrays which has items: [{default: ...}, {default: ...}]
(though this is a corner case). It doesn't really make sense to do this when the top-level schema type is a value type like integer
as the input is either valid (ie. an integer) or invalid (ie. another type or null
).
Remark, after inserting a default value, validator should validate the default value too. This should ideally be done a schema compile-time. It is important to do this, because the default value of a property which has type: 'object'
may be {}
and the schema for that object may specify properties for this that has additional default values. It would also be nice to get errors about inconsistencies at compile-time.
Remote is added as http://localhost:1234/name.json:
{
"definitions": {
"orNull": {
"anyOf": [
{ "type": "null" },
{ "$ref": "#" }
]
}
},
"type": "string"
}
Schema:
{
"id": "http://localhost:1234/object",
"type": "object",
"properties": {
"name": { "$ref": "name.json#/definitions/orNull" }
}
}
Data should be valid (and is invalid for ajv):
{ "name": "foo" }
Data should be invalid (and is valid for ajv):
{
"name": {
"name": null
}
}
So essentially # in name.json refers to object.json instead of name.json.
See this test: https://github.com/epoberezkin/ajv/blob/master/spec/tests/issues/1_ids_in_refs.json
This is not working:
{
definitions: {
integer: {
id: '#integer',
type: 'integer'
}
},
$ref: '#integer'
}
This works though:
{
id: 'http://example.com/integer.json',
definitions: {
integer: {
id: '#integer',
type: 'integer'
}
},
$ref: '#integer'
}
This is ok too:
{
definitions: {
integer: {
type: 'integer'
}
},
$ref: '#/definitions/integer'
}
It seems like removeAdditional
can be failing in many cases unless the option validateSchema
is false.
The problem is that the schema used for schema validation (meta-schema in most cases) is compiled with this option too.
It would be extremely helpful to consumers if you provided a changelog or did releases and tags with each version. I find npm version
or mversion
to be extremely simple to use for this.
Edit: Did just see it at the bottom of the README. I think this is still valid though.
How use ajv with yield ?
have you an example ?
Thanks Ami44
Test: https://github.com/epoberezkin/ajv/blob/master/spec/tests/issues/2_root_ref_in_ref.json
This is not working:
{
definitions: {
arr: {
type: 'array',
items: { $ref: '#' }
}
},
type: 'object',
properties: {
name: { type: 'string' },
children: { $ref: '#/definitions/arr' }
}
}
arr
refers to #/definitions/arr
(wrong) rather than to the root (correct)See #61
so that doT is dev dependency only and there is no startup delay
I work with XML Soap calls quite a bit. So all the data comes back as strings. I was wondering if you would like your code to support strongly typing an object or if that would be better to do spin off. Or if some other library would be better suited for this?
That will substantially increase performance, especially when all properties are required
That will enable mutual (circular) references between schemas.
That is more complex than it seems because resolution could fail in the middle of resolution chain and the newly added schema may not contain the required reference but be inside some resolution chains.
So the resolutions that were stopped because they couldn't find the newly added schema (and also any IDs contained in it - another complication) have to be re-tried.
#2 has to be resolved, otherwise validation of some schemas will fail (including test schemas)
It shows empty string
var Ajv = require('ajv');
var schema = {
"$schema": "http://json-schema.org/draft-04/schema#",
"properties": { "id": { "type": "string", "format": "uri" } }
};
var ajv = Ajv({verbose:1});
var valid = ajv.compile(schema);
console.log(valid({"id": "urn:isbn:978-3-531-18621-4"}));
console.log(ajv.errorsText());
I get the following output
false
No errors
The version 1.1.0 release yesterday is causing issues here:
Error: Cannot find module '../dotjs/ref'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object.<anonymous> (/Users/ben/SiteTour/projects/api/node_modules/osprey-mock-service/node_modules/osprey/node_modules/osprey-method-handler/node_modules/ajv/lib/compile/_rules.js:5:11)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
What do you think - should I ask osprey-method-handler
to lock AJV version to the old 1.0.x
version, or perhaps AJV can release 1.1.0
as 2.0.0
instead in case other packages may hit the same issue?
Hi,
I have a rather complex JSON schema, with a required list of a sub object that has 19 items.
When I validate a JSON with the option allErrors turned on, the validation will fail, giving me a whole List of required Items which ajv claims to be missing, although I am sure they are there.
When I turn off allErrors OR reduce the required list to 10 or less items, the validation will pass.
Best regards M
I have two feature requests that may not be standards based but I think they'll be really useful:
1- An ajv function/method that can be provided with input data and returns TRUE or FALSE based on the input data as a first/final check, since there still are some things missing from JSON schema (or perhaps impossible the way I've written the schemas now).
2- A function that'd print the final JSON schema after replacing all $refs with actual content (ie. referenced schemas).
You can print warnings etc when they are used, so users know what they are doing.
Hi ! I have an issue with the following code :
var ajvFissiles = new Ajv().compile({
"type" : "object",
"patternProperties": {
"^.+$" : {
"type" : "object",
"properties" : {
"unit" : { "type" : "string", "enum" : ["ap", "ac", "ap", "af"]},
"density" : { "type" : ["string", "number"]},
"compositions" : { "type" : "array"}
},
"required" : ["unit", "compositions"],
"additionalProperties": false
}
},
"additionalProperties" : false
});
I get the following message :
Error compiling schema, function code: validate = function (data, dataPath) { 'use strict'; validate.errors = null; var errors = 0; if ((data && typeof data === "object" && !Array.isArray(data))) { var errs0 = errors;var valid1 = true; var propertiesSchema0 = validate.schema.properties || {}; for (var key0 in data) { var isAdditional0 = propertiesSchema0[key0] === undefined; if (isAdditional0) { if (/^.+$/.test(key0)) isAdditional0 = false; } if (isAdditional0) { valid1 = false; validate.errors = [ { keyword: 'additionalProperties', dataPath: (dataPath || '') + "['" + key0 + "']", message: 'additional properties NOT allowed' }]; return false; break; } } if (valid1) { for (var key0 in data) { if (/^.+$/.test(key0)) { var data1 = data[key0]; var errs_1 = errors; if ((data1 && typeof data1 === "object" && !Array.isArray(data1))) { if ( data1.unit === undefined || data1.compositions === undefined ) { var err = { keyword: 'required', dataPath: (dataPath || '') + "['" + key0 + "']", message: 'properties unit, compositions are required' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; } else { var errs1 = errors;var valid2 = true; var propertiesSchema1 = validate.schema.patternProperties.^.+$.properties || {}; for (var key1 in data1) { var isAdditional1 = propertiesSchema1[key1] === undefined; if (isAdditional1) { valid2 = false; var err = { keyword: 'additionalProperties', dataPath: (dataPath || '') + "['" + key0 + "']['" + key1 + "']", message: 'additional properties NOT allowed' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; break; } } if (valid2) { var data2 = data1.unit; if (data2 === undefined) { valid2 = true; } else { var errs_2 = errors; var enumSchema2 = validate.schema.patternProperties.^.+$.properties['unit'].enum , valid2 = false;for (var i2=0; i2<enumSchema2.length; i2++) if (equal(data2, enumSchema2[i2])) { valid2 = true; break; } if (!valid2) { var err = { keyword: 'enum', dataPath: (dataPath || '') + "['" + key0 + "'].unit", message: 'should be equal to one of values' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; } if (errors === errs_2) { if (typeof data2 !== "string") { var err = { keyword: 'type', dataPath: (dataPath || '') + "['" + key0 + "'].unit", message: 'should be string' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; } } var valid2 = errors === errs_2; } if (valid2) { var data2 = data1.density; if (data2 === undefined) { valid2 = true; } else { var errs_2 = errors; if (typeof data2 !== "string" && typeof data2 !== "number") { var err = { keyword: 'type', dataPath: (dataPath || '') + "['" + key0 + "'].density", message: 'should be string,number' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; } var valid2 = errors === errs_2; } if (valid2) { if (data1.compositions === undefined) { valid2 = true; } else { var errs_2 = errors; if (!Array.isArray(data1.compositions)) { var err = { keyword: 'type', dataPath: (dataPath || '') + "['" + key0 + "'].compositions", message: 'should be array' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; } var valid2 = errors === errs_2; } }}} } } else { var err = { keyword: 'type', dataPath: (dataPath || '') + "['" + key0 + "']", message: 'should be object' }; if (validate.errors === null) validate.errors = [err]; else validate.errors.push(err); errors++; } var valid1 = errors === errs_1; if (!valid1) break; } else valid1 = true; } } } else { validate.errors = [ { keyword: 'type', dataPath: (dataPath || '') + "", message: 'should be object' }]; return false; } return errors === 0; }
Do you have any idee ?
Hey, just wanted to say nice work on the performance improvements! It's great to see there's no upper limit in how fast a JSON validator for node can go. Caching the validator code internally is great and I guess does the trick for the benchmarks out there.
I was wondering, do you plan on introducing some caching configuration? A limit on the size/number of cached validator code, maybe together with some policy for purging stale validators (e.g. least recently used)? That would help a great deal in large-scale projects with lots of schemas, or when schemas are dynamically generated and can change a lot.
Keep up the good work!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.