jsonschema
Advanced tools
Comparing version 1.1.0 to 1.1.1
@@ -47,3 +47,3 @@ 'use strict'; | ||
var result = new ValidatorResult(instance, schema, options, ctx); | ||
var types = (schema.type instanceof Array) ? schema.type : [schema.type]; | ||
var types = Array.isArray(schema.type) ? schema.type : [schema.type]; | ||
if (!types.some(this.testType.bind(this, instance, schema, options, ctx))) { | ||
@@ -62,4 +62,8 @@ var list = types.map(function (v) { | ||
function testSchema(instance, options, ctx, schema){ | ||
return this.validateSchema(instance, schema, options, ctx).valid; | ||
function testSchema(instance, options, ctx, callback, schema){ | ||
var res = this.validateSchema(instance, schema, options, ctx); | ||
if (! res.valid && callback instanceof Function) { | ||
callback(res); | ||
} | ||
return res.valid; | ||
} | ||
@@ -81,9 +85,16 @@ | ||
var result = new ValidatorResult(instance, schema, options, ctx); | ||
if (!(schema.anyOf instanceof Array)){ | ||
var inner = new ValidatorResult(instance, schema, options, ctx); | ||
if (!Array.isArray(schema.anyOf)){ | ||
throw new SchemaError("anyOf must be an array"); | ||
} | ||
if (!schema.anyOf.some(testSchema.bind(this, instance, options, ctx))) { | ||
if (!schema.anyOf.some( | ||
testSchema.bind( | ||
this, instance, options, ctx, function(res){inner.importErrors(res);} | ||
))) { | ||
var list = schema.anyOf.map(function (v, i) { | ||
return (v.id && ('<' + v.id + '>')) || (v.title && JSON.stringify(v.title)) || (v['$ref'] && ('<' + v['$ref'] + '>')) || '[subschema '+i+']'; | ||
}); | ||
if (options.nestedErrors) { | ||
result.importErrors(inner); | ||
} | ||
result.addError({ | ||
@@ -111,3 +122,3 @@ name: 'anyOf', | ||
} | ||
if (!(schema.allOf instanceof Array)){ | ||
if (!Array.isArray(schema.allOf)){ | ||
throw new SchemaError("allOf must be an array"); | ||
@@ -145,7 +156,11 @@ } | ||
} | ||
if (!(schema.oneOf instanceof Array)){ | ||
if (!Array.isArray(schema.oneOf)){ | ||
throw new SchemaError("oneOf must be an array"); | ||
} | ||
var result = new ValidatorResult(instance, schema, options, ctx); | ||
var count = schema.oneOf.filter(testSchema.bind(this, instance, options, ctx)).length; | ||
var inner = new ValidatorResult(instance, schema, options, ctx); | ||
var count = schema.oneOf.filter( | ||
testSchema.bind( | ||
this, instance, options, ctx, function(res) {inner.importErrors(res);} | ||
) ).length; | ||
var list = schema.oneOf.map(function (v, i) { | ||
@@ -155,2 +170,5 @@ return (v.id && ('<' + v.id + '>')) || (v.title && JSON.stringify(v.title)) || (v['$ref'] && ('<' + v['$ref'] + '>')) || '[subschema '+i+']'; | ||
if (count!==1) { | ||
if (options.nestedErrors) { | ||
result.importErrors(inner); | ||
} | ||
result.addError({ | ||
@@ -320,3 +338,3 @@ name: 'oneOf', | ||
validators.items = function validateItems (instance, schema, options, ctx) { | ||
if (!(instance instanceof Array)) { | ||
if (!Array.isArray(instance)) { | ||
return null; | ||
@@ -330,3 +348,3 @@ } | ||
instance.every(function (value, i) { | ||
var items = (schema.items instanceof Array) ? (schema.items[i] || schema.additionalItems) : schema.items; | ||
var items = Array.isArray(schema.items) ? (schema.items[i] || schema.additionalItems) : schema.items; | ||
if (items === undefined) { | ||
@@ -590,3 +608,3 @@ return true; | ||
validators.minItems = function validateMinItems (instance, schema, options, ctx) { | ||
if (!(instance instanceof Array)) { | ||
if (!Array.isArray(instance)) { | ||
return null; | ||
@@ -612,3 +630,3 @@ } | ||
validators.maxItems = function validateMaxItems (instance, schema, options, ctx) { | ||
if (!(instance instanceof Array)) { | ||
if (!Array.isArray(instance)) { | ||
return null; | ||
@@ -637,3 +655,3 @@ } | ||
var result = new ValidatorResult(instance, schema, options, ctx); | ||
if (!(instance instanceof Array)) { | ||
if (!Array.isArray(instance)) { | ||
return result; | ||
@@ -680,3 +698,3 @@ } | ||
validators.uniqueItems = function validateUniqueItems (instance, schema, options, ctx) { | ||
if (!(instance instanceof Array)) { | ||
if (!Array.isArray(instance)) { | ||
return null; | ||
@@ -716,3 +734,3 @@ } | ||
} | ||
if (dep instanceof Array) { | ||
if (Array.isArray(dep)) { | ||
dep.forEach(function (prop) { | ||
@@ -753,3 +771,3 @@ if (instance[prop] === undefined) { | ||
validators['enum'] = function validateEnum (instance, schema, options, ctx) { | ||
if (!(schema['enum'] instanceof Array)) { | ||
if (!Array.isArray(schema['enum'])) { | ||
throw new SchemaError("enum expects an array", schema); | ||
@@ -785,3 +803,3 @@ } | ||
if(!notTypes) return null; | ||
if(!(notTypes instanceof Array)) notTypes=[notTypes]; | ||
if(!Array.isArray(notTypes)) notTypes=[notTypes]; | ||
notTypes.forEach(function (type) { | ||
@@ -788,0 +806,0 @@ if (self.testType(instance, schema, options, ctx, type)) { |
@@ -62,11 +62,11 @@ 'use strict'; | ||
} else if (res && res.errors) { | ||
var errs = this.errors; | ||
res.errors.forEach(function (v) { | ||
errs.push(v); | ||
}); | ||
Array.prototype.push.apply(this.errors, res.errors); | ||
} | ||
}; | ||
function stringizer (v,i){ | ||
return i+': '+v.toString()+'\n'; | ||
} | ||
ValidatorResult.prototype.toString = function toString(res) { | ||
return this.errors.map(function(v,i){ return i+': '+v.toString()+'\n'; }).join(''); | ||
return this.errors.map(stringizer).join(''); | ||
}; | ||
@@ -214,3 +214,30 @@ | ||
module.exports.deepMerge = function deepMerge (target, src) { | ||
function deepMerger (target, dst, e, i) { | ||
if (typeof e === 'object') { | ||
dst[i] = deepMerge(target[i], e) | ||
} else { | ||
if (target.indexOf(e) === -1) { | ||
dst.push(e) | ||
} | ||
} | ||
} | ||
function copyist (src, dst, key) { | ||
dst[key] = src[key]; | ||
} | ||
function copyistWithDeepMerge (target, src, dst, key) { | ||
if (typeof src[key] !== 'object' || !src[key]) { | ||
dst[key] = src[key]; | ||
} | ||
else { | ||
if (!target[key]) { | ||
dst[key] = src[key]; | ||
} else { | ||
dst[key] = deepMerge(target[key], src[key]) | ||
} | ||
} | ||
} | ||
function deepMerge (target, src) { | ||
var array = Array.isArray(src); | ||
@@ -222,29 +249,8 @@ var dst = array && [] || {}; | ||
dst = dst.concat(target); | ||
src.forEach(function (e, i) { | ||
if (typeof e === 'object') { | ||
dst[i] = deepMerge(target[i], e) | ||
} else { | ||
if (target.indexOf(e) === -1) { | ||
dst.push(e) | ||
} | ||
} | ||
}); | ||
src.forEach(deepMerger.bind(null, target, dst)); | ||
} else { | ||
if (target && typeof target === 'object') { | ||
Object.keys(target).forEach(function (key) { | ||
dst[key] = target[key]; | ||
}); | ||
Object.keys(target).forEach(copyist.bind(null, target, dst)); | ||
} | ||
Object.keys(src).forEach(function (key) { | ||
if (typeof src[key] !== 'object' || !src[key]) { | ||
dst[key] = src[key]; | ||
} | ||
else { | ||
if (!target[key]) { | ||
dst[key] = src[key]; | ||
} else { | ||
dst[key] = deepMerge(target[key], src[key]) | ||
} | ||
} | ||
}); | ||
Object.keys(src).forEach(copyistWithDeepMerge.bind(null, target, src, dst)); | ||
} | ||
@@ -255,2 +261,4 @@ | ||
module.exports.deepMerge = deepMerge; | ||
/** | ||
@@ -274,2 +282,5 @@ * Validates instance against the provided schema | ||
function pathEncoder (v) { | ||
return '/'+encodeURIComponent(v).replace(/~/g,'%7E'); | ||
} | ||
/** | ||
@@ -283,3 +294,3 @@ * Accept an Array of property names and return a JSON Pointer URI fragment | ||
// the slash is encoded by encodeURIComponent | ||
return a.map(function(v){ return '/'+encodeURIComponent(v).replace(/~/g,'%7E'); }).join(''); | ||
return a.map(pathEncoder).join(''); | ||
}; |
@@ -160,2 +160,12 @@ 'use strict'; | ||
/** | ||
* @param Object schema | ||
* @return mixed schema uri or false | ||
*/ | ||
function shouldResolve(schema) { | ||
var ref = (typeof schema === 'string') ? schema : schema.$ref; | ||
if (typeof ref=='string') return ref; | ||
return false; | ||
} | ||
/** | ||
* Validates an instance against the schema (the actual work horse) | ||
@@ -170,3 +180,2 @@ * @param instance | ||
Validator.prototype.validateSchema = function validateSchema (instance, schema, options, ctx) { | ||
var self = this; | ||
var result = new ValidatorResult(instance, schema, options, ctx); | ||
@@ -177,31 +186,12 @@ if (!schema) { | ||
/** | ||
* @param Object schema | ||
* @return mixed schema uri or false | ||
*/ | ||
function shouldResolve(schema) { | ||
var ref = (typeof schema === 'string') ? schema : schema.$ref; | ||
if (typeof ref=='string') return ref; | ||
return false; | ||
} | ||
/** | ||
* @param Object schema | ||
* @param SchemaContext ctx | ||
* @returns Object schema or resolved schema | ||
*/ | ||
function resolve(schema, ctx) { | ||
var ref; | ||
if(ref = shouldResolve(schema)) { | ||
return self.resolve(schema, ref, ctx).subschema; | ||
} | ||
return schema; | ||
} | ||
if (schema['extends']) { | ||
if (schema['extends'] instanceof Array) { | ||
schema['extends'].forEach(function (s) { | ||
schema = helpers.deepMerge(schema, resolve(s, ctx)); | ||
}); | ||
var schemaobj = {schema: schema, ctx: ctx}; | ||
schema['extends'].forEach(this.schemaTraverser.bind(this, schemaobj)); | ||
schema = schemaobj.schema; | ||
schemaobj.schema = null; | ||
schemaobj.ctx = null; | ||
schemaobj = null; | ||
} else { | ||
schema = helpers.deepMerge(schema, resolve(schema['extends'], ctx)); | ||
schema = helpers.deepMerge(schema, this.superResolve(schema['extends'], ctx)); | ||
} | ||
@@ -222,5 +212,5 @@ } | ||
var validatorErr = null; | ||
var validator = self.attributes[key]; | ||
var validator = this.attributes[key]; | ||
if (validator) { | ||
validatorErr = validator.call(self, instance, schema, options, ctx); | ||
validatorErr = validator.call(this, instance, schema, options, ctx); | ||
} else if (options.allowUnknownAttributes === false) { | ||
@@ -246,2 +236,26 @@ // This represents an error with the schema itself, not an invalid instance | ||
* @param Object schema | ||
* @param SchemaContext ctx | ||
* @returns Object schema or resolved schema | ||
*/ | ||
Validator.prototype.schemaTraverser = function schemaTraverser (schemaobj, s) { | ||
schemaobj.schema = helpers.deepMerge(schemaobj.schema, this.superResolve(s, schemaobj.ctx)); | ||
} | ||
/** | ||
* @private | ||
* @param Object schema | ||
* @param SchemaContext ctx | ||
* @returns Object schema or resolved schema | ||
*/ | ||
Validator.prototype.superResolve = function superResolve (schema, ctx) { | ||
var ref; | ||
if(ref = shouldResolve(schema)) { | ||
return this.resolve(schema, ref, ctx).subschema; | ||
} | ||
return schema; | ||
} | ||
/** | ||
* @private | ||
* @param Object schema | ||
* @param Object switchSchema | ||
@@ -248,0 +262,0 @@ * @param SchemaContext ctx |
{ | ||
"author": "Tom de Grunt <tom@degrunt.nl>", | ||
"name": "jsonschema", | ||
"version": "1.1.0", | ||
"version": "1.1.1", | ||
"license": "MIT", | ||
@@ -12,2 +12,3 @@ "dependencies": { | ||
"main": "./lib", | ||
"typings": "./lib/index.d.ts", | ||
"devDependencies": { | ||
@@ -14,0 +15,0 @@ "mocha": "~1.8.2", |
@@ -126,2 +126,4 @@ [![Build Status](https://secure.travis-ci.org/tdegrunt/jsonschema.svg)](http://travis-ci.org/tdegrunt/jsonschema) | ||
When `oneOf` or `anyOf` validations fail, errors that caused any of the sub-schemas referenced therein to fail are not reported, unless `options.nestedErrors` is truthy. This option may be useful when troubleshooting validation errors in complex schemas. | ||
### Custom properties | ||
@@ -128,0 +130,0 @@ Specify your own JSON Schema properties with the validator.attributes property: |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
72033
14
1957
213