baggz / amanda Goto Github PK
View Code? Open in Web Editor NEWJSON Schema validator
Home Page: https://github.com/Baggz/Amanda
License: MIT License
JSON Schema validator
Home Page: https://github.com/Baggz/Amanda
License: MIT License
var amanda = require('amanda')
var person = {
type: 'object',
properties: {
age: {
type: 'number',
minimum: 1,
}
}
}
amanda({age: -1}, person, function(error){
console.log(error)
})
this code should throw an error, but it doesn't.
This attribute indicates if the value of the instance (if the instance is a number) can not equal the number defined by the "maximum" attribute. This is false by default, meaning the instance value can be less then or equal to the maximum value.
Me again. In a real use-case, I had to check if a field named 'name' was equal to the concatenation of the field 'identifier', a dash and of the field 'language'. Issue is these values are currently being hand-written to JSON files, so I can't enforce that in an admin interface thus far - and this has shown me the lack of support for this kind of check within amanda (I may be wrong). The solution I found was to get the current JSON-parsed object and make it available globally in a variable (ugly but functional). One other detail is that, of course, this validation runs in custom validators.
So adding this support (cross-field checks) maybe by allowing access to the object being validated would be a great plus in my opinion.
Hello,
In the https://github.com/Baggz/Amanda/blob/master/docs/json/comparison.md file, one can see in the union types, the element of the array can be a schema.
But it seems that is not currently supported :
C:\Documents and Settings\raphael>node -v
v0.6.15
C:\Documents and Settings\raphael>npm -v
1.1.16
C:\Documents and Settings\raphael>npm install amanda
npm http GET https://registry.npmjs.org/amanda
npm http 304 https://registry.npmjs.org/amanda
[email protected] ./node_modules/amanda
C:\Documents and Settings\raphael>node
var schema = {type:'array', items: {type:['string', {type:'object'} ]}};
undefined
var strings = ["a","b","c","d"];
undefined
var objects = [{a:'a'},{b:'b'}];
undefined
var cb=function(error){console.log(error);}
undefined
validator.validate(strings, schema, cb);
undefined
undefined
validator.validate(objects, schema, cb);
Error: Type 'string,[object Object]' is not supported.
at C:\Documents and Settings\raphael\node_modules\amanda\releases\latest\amanda.js:1050:23
at Array.some (native)
at Object.type (C:\Documents and Settings\raphael\node_modules\amanda\releases\latest\amanda.js:1047:42)
at C:\Documents and Settings\raphael\node_modules\amanda\releases\latest\amanda.js:1736:32
at C:\Documents and Settings\raphael\node_modules\amanda\releases\latest\amanda.js:86:24
at C:\Documents and Settings\raphael\node_modules\amanda\releases\latest\amanda.js:78:30
at C:\Documents and Settings\raphael\node_modules\amanda\releases\latest\amanda.js:1744:20
at C:\Documents and Settings\raphael\node_modules\amanda\releases\latest\amanda.js:86:24
at C:\Documents and Settings\raphael\node_modules\amanda\releases\latest\amanda.js:78:30
at C:\Documents and Settings\raphael\node_modules\amanda\releases\latest\amanda.js:1744:20
This script
amanda = require 'amanda'
assert = require 'assert'
schema =
type: "array"
items:
type: "object"
properties:
a: type: "string"
b: type: "string"
c: type: "string"
d: type: "string"
e: type: "string"
id: type: "number"
"bool": type: "boolean"
data = [
{"id": 1, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 2, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 3, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 4, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 5, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 6, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 7, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 8, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 9, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 10, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 11, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 12, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 13, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 14, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 15, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 16, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 17, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 18, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 19, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 20, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 21, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 22, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 23, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"},
{"id": 24, "a": "a", "bool": true, "b": "b", "c": "c", "d": "d", "e": "e"}
]
amanda.validate data, schema, (err) ->
console.error 'error', err
will produce
almad@namtar /tmp/xoxo $ coffee amanda-test.coffee
RangeError: Maximum call stack size exceeded
Creating a schema and then calling the validate method with added custom validators while setting { singleError: false }
on the method call returns no errors to the callback. Removing the { singleError: false }
makes it work again. It seems the issue lies not on the value provided for singleError
, as passing { singleError: true }
also breaks the validation error returns. My tests have shown that, even though the error objects are not returned, the custom methods do run.
This attribute defines a schema for all properties that are not explicitly defined in an object type definition. If specified, the value MUST be a schema or a boolean. If false is provided, no additional properties are allowed beyond the properties defined in the schema. The default value is an empty schema which allows any value for additional properties.
This attribute defines the maximum value of the instance property when the type of the instance value is a number.
when running this code:
var schema = {type: 'object'};
amanda.validate([], schema, function(error) {console.log('error:', error);});
an error is returned with the wrong message.
actual:
'The '' property must be a/an 'object'. The type of the property is 'object''
expected:
'The '' property must be a/an 'object'. The type of the property is 'array''
This attribute defines the minimum number of values in an array when the array is the instance value.
Often I have a situation in a game, that a schema will be used by different other schemas. Like a position will be used by an unit, in a move way and so on. I know you can validate the object with more than one schema or simply write the conditions into every schema. But both for me is like an anti pattern and not update friendly...
So I wrote a validator and want to share it with you, because I think it could be useful for the standard distribution as well.
var amanda = require('./../lib/amanda.js');
amanda.addValidator('validates',function(property, propertyValue, validator, propertyValidators, callback) {
if( typeof validator === 'array' ){
// if validator value is an array then try to validate all schemas
for( var i=0,e=validator.length; i<e; i++ ) amanda.validate( propertyValue, validator[i], function(e){
return (e)? callback(e) : callback();
});
}
else{
amanda.validate( propertyValue, validator, function(e){
return (e)? callback(e) : callback();
});
}
});
var sPos = {
type:'object',
properties:{
x:{ type:'number', required:true },
y:{ type:'number', required:true }
}
};
var positions = {
type:'array',
items:{
validates:sPos
}
};
var dPos = {
type:'object',
properties:{
p1:{
validates:sPos,
required:true
},
p2:{
validates:sPos,
required:true
}
}
}
console.log("starting");
amanda.validate( { x:0,y:0 }, sPos , function(e){
if(e) throw Error("failed");
console.log("t1 success");
});
amanda.validate( [{ x:0,y:0 },{ x:0,y:0 },{ x:0,y:0 },{ x:0,y:0 }], positions , function(e){
if(e) throw Error("failed");
console.log("t2 success");
});
amanda.validate( { p1:{ x:0,y:0 }, p2:{ x:0,y:0 } }, dPos, function(e){
if(e) throw Error("failed");
console.log("t3 success");
});
This attribute indicates if the value of the instance (if the instance is a number) can not equal the number defined by the "minimum" attribute. This is false by default, meaning the instance value can be greater then or equal to the minimum value.
This attribute defines what value the number instance must be divisible by with no remainder (the result of the division must be an integer.) The value of this attribute SHOULD NOT be 0.
It was very hard to me to find out that the callback will every time called by your library. Often I only need to do some things if the validation fails, else not...
cool would be
amanda.validate( obj, schema, { onlyErrorCallback:true }, function(e){
// do something on error case
});
// do things when validation was successful
BTW: great library :D
Trying to validate the following ISO 8601 date-time:
2012-07-18T14:14Z
^\d{4}-(?:0[0-9]{1}|1[0-2]{1})-[0-9]{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$ doesnt seem to match
I tried one here:
http://underground.infovark.com/2008/07/22/iso-date-validation-regex/
^(\d{4})\D?(0[1-9]|1[0-2])\D?([12]\d|0[1-9]|3[01])(\D?([01]\d|2[0-3])\D?([0-5]\d)\D?([0-5]\d)?\D?(\d{3})?([zZ]|([+-])([01]\d|2[0-3])\D?([0-5]\d)?)?)?$
And it is able to match the date-time.
Both "Schema" and "Object" links from https://github.com/Baggz/Amanda/blob/master/docs/json/methods/validate.md end up with 404
If I validate a property to be email format, the error message on failed validation is something like this:
The ‘email’ does not match the ‘/^(?:[\w!#$%&'_+-/=?^`{|}~]+.)_[\w!#$%&'*+-/=?^`{|}~]+@(?:(?:(?:a-zA-Z0-9{0,61}[a-zA-Z0-9]?.)+a-zA-Z0-9{0,61}[a-zA-Z0-9]?)|(?:[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5]).){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])]))$/’ pattern.
I think this might be useful to know the pattern that its being compared against for the developer, but as a user this error message is like waaaa?
Not necessarily a bug, but I imagine a more friendly error message would be that 'email' was not a valid email address.
This fragment from documentation is wrong:
/**
* Schema
*/
var schema = {
type: 'object',
additionalProperties: 'false',
properties: {
name: {
type: 'string'
},
surname: {
type: 'string'
}
}
};
Code only supports boolean value for additionalProperties attribute.
But the real problem is that at the end of additionalPropertiesAttribute function (amanda.js source file) should be some throw or "callback" attribute call with error info about illegal state. Right now this string value leads to correct end of validation and no "callback" call.
I noticed that README.md links to draft3. Is this documentation old? Or does Amanda need work to be updated to draft4? Cheers!
Hi!
I am getting the error
JSON schema is not valid! invalid type: object (expected [object Object]/array) at path "/items"
when parsing the schema.
{ "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "required": true }, "label": { "type": "string", "required" : true } } } }
Is that error compliant with JSON Schema Internet Draft?
Hi,
For Relax NG support maybe this lib is a good head start:
https://github.com/mangalam-research/salve.git
I'm just googling along for a Relax NG js library, maybe it's useful :-)
Amanda is not present at http://json-schema.org/implementations.html.
This attribute defines the minimum value of the instance property when the type of the instance value is a number.
The 0.4.3 revision of Amanda seems to break validation of schemas that support 'falsey' values.
For instance, if I had a schema with a boolean property, Amanda 0.4.2 would allow values of true
and false
, but would not allow a value of undefined
(or a non-boolean value). In version 0.4.3, only true
is allowed - false
is treated as undefined
, despite being a legal boolean value. Indeed, the error message I get from Amanda 0.4.3 in this case is:
Error: The 'booleanProperty' property is required.
The 'booleanProperty' property must be a 'boolean'. The type of the property is 'undefined'.
Looks like the regression is in commit 54b712d, to fix special characters; instead of checking whether the property is defined (which it used to), it now checks to see whether it is 'falsey':
- return (previousValue && isDefined(previousValue[currentValue])) ? previousValue[currentValue] : undefined;
+ return (source[property]) ? source[property] : undefined;
No pull request because I'm not sure what the initial problem with special characters was, but it should be fixable with the following, or an explicit check for undefined
, on line 9 of src/engines/json/getProperty.js:
return (isDefined(source[property])) ? source[property] : undefined;
Great project, by the way!
Hi,
I'm currently comparing some JSON Schema validators and would like to know whether you support the extends attribute for schema "inheritance"
Thanks
in tests/json/objects.js
change
var schema = {
type: 'object',
properties: {
name: {
type: 'string'
}
}
};
to
var schema = {
type: 'object',
properties: {
_name: {
type: 'string'
}
}
};
and run tests npm test
failed.
Is this an expected behavior?
This attribute defines the maximum number of values in an array when the array is the instance value.
Hey guys,
I was missing this little part of the spec but I was surprised to find that it wasn't harder than this to implement:
var json = require('amanda')('json');
json.addAttribute('extends', function(property, propertyValue, attributeValue, propertyAttributes, callback) {
return this.validateSchema(propertyValue,attributeValue,'',callback)
})
Should I make this into a PR?
This attribute defines a URI of a schema that contains the full representation of this schema. When a validator encounters this attribute, it SHOULD replace the current schema with the schema referenced by the value's URI (if known and available) and revalidate the instance. This URI MAY be relative or absolute, and relative URIs SHOULD be resolved against the URI of the current schema.
It would be useful to be able to specify custom error messages directly on the Amanda schema definition. I'd suggest accepting an object in the lines of
message: {
regex: { text: "Your custom message here" }
type: { text: "Your custom message 2 here" }
}
which would be parsed upon a failed validation. The property names of the message object would be the name of the Amanda validator that should consume them.
A lot of the links inside the documentation dont link to the correct pages. Just a heads up.
Following exception stack is printed:
Uncaught exception: TypeError: Object.keys called on non-object, stack:
at Function.keys (native)
at keys (/root/nef/node_modules/amanda/releases/latest/amanda.js:334:17)
at Object.additionalProperties (/root/nef/node_modules/amanda/releases/latest/amanda.js:472:22)
at Validation.validateProperty.iterator (/root/nef/node_modules/amanda/releases/latest/amanda.js:1821:26)
at Array.addToQueue [as 0] (/root/nef/node_modules/amanda/releases/latest/amanda.js:86:16)
at asyncEach (/root/nef/node_modules/amanda/releases/latest/amanda.js:111:20)
at each (/root/nef/node_modules/amanda/releases/latest/amanda.js:118:22)
at Validation.validateProperty (/root/nef/node_modules/amanda/releases/latest/amanda.js:1840:10)
at Validation.validateSchema (/root/nef/node_modules/amanda/releases/latest/amanda.js:1856:15)
at Validation.validateItems (/root/nef/node_modules/amanda/releases/latest/amanda.js:1668:19)
when validating following data:
'tpool0/fs0'
according to following scheme:
{
type: 'object',
properties: {
name: { type: 'string', required: true },
id: schemata.guid
},
additionalProperties: false
};
apparently the data are not valid, as data are plain string and according to schema object is expected nevertheless amanda should report error properly and it shouldn't throw uncaught exception. The problem is in additionalPropertiesAttribute(). Before the method tries to get object properties by keys(propertyValue) it should check if the value which it is operating on is indeed an object and if not it should bail out from the function. Something like this:
/**
* AdditionalProperties
*/
var additionalPropertiesAttribute = function additionalProperties(property, propertyValue, attributeValue, propertyAttributes, callback) {
var self = this;
/**
* {
* additionalProperties: true,
* ...
* }
*/
if (attributeValue === true) {
return callback();
}
if (!isObject(propertyValue)) {
return callback();
}
// Filter the forbidden properties
var propertyKeys = keys(propertyValue);
...
I've reviewed some JSON Schema validation libraries and found this one solid, but the async-only validation bugs me a lot. I've noticed that most other similar libraries support synchronous calls, and I tried to figure out how much work it would require to make Amanda optionally sync as well but got a bit stuck in the search. How hard would it be to allow sync calls at this stage? Async mostly makes sense for bigger amounts of data, but for most a sync call would make more sense.
This attribute indicates that all items in an array instance MUST be unique (contains no two identical values). Two instance are consider equal if they are both of the same type and: are null; or are booleans/numbers/strings and have the same value; or are arrays, contains the same number of items, and each item in the array is equal to the corresponding item in the other array; or are objects, contains the same property names, and each property in the object is equal to the corresponding property in the other object.
var messageSchema = {
type: 'object',
properties: {
Action: {
required: true,
type: 'string'
},
Data: {
required: true,
type: 'object',
}
}
};
if I validate against
{
Action: "GetAllPools",
Data: { }
}
I will get an error message saying that Data is required. I have not required any properties be on Data however with my schema. If I add a random property to Data it will validate against the schema.
This provides a definition for additional items in an array instance when tuple definitions of the items is provided. This can be false to indicate additional items in the array are not allowed, or it can be a schema that defines the schema of the additional items.
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.