json-schema-library
Advanced tools
Comparing version 1.1.0 to 1.2.0
const emptyObject = {}; | ||
const Errors = require("./validation/errors"); | ||
const errors = require("./validation/errors"); | ||
/** | ||
* Returns the json schema of the given data-json-pointer | ||
* Returns the json-schema of a data-json-pointer | ||
* | ||
@@ -13,3 +13,3 @@ * @param {CoreInterface} core - validator | ||
* @param {String} pointer - json pointer in data to get the json schema for | ||
* @return {Object|Error} json schema object of json pointer or an error | ||
* @return {Object|Error} json schema object of the json-pointer or an error | ||
*/ | ||
@@ -21,3 +21,2 @@ function getSchema(core, schema, data, pointer = "#") { | ||
function _get(core, schema, frags, pointer, data = emptyObject) { | ||
@@ -30,7 +29,7 @@ if (frags.length === 0 || frags[0] === "") { | ||
schema = core.step(key, schema, data, pointer); // step schema | ||
if (schema instanceof Error) { | ||
if (schema && schema.type === "error") { | ||
return schema; | ||
} | ||
if (schema === false) { | ||
return new Errors.OneOfError({ value: data, schema, pointer }); | ||
return errors.oneOfError({ value: data, schema, pointer }); | ||
} | ||
@@ -37,0 +36,0 @@ data = data[key]; // step data |
@@ -7,7 +7,2 @@ /* eslint quote-props: 0 */ | ||
* | ||
* @TODO | ||
* - walk through schema by shared helper functions (dry) | ||
* - add support for oneOf | ||
* - add support for $ref | ||
* | ||
* @param {Object} schema - json schema | ||
@@ -14,0 +9,0 @@ * @param {Mixed} [data] - optional template data |
module.exports = { | ||
cores: { | ||
Interface: require("./cores/CoreInterface"), | ||
Draft04: require("./cores/Draft04"), | ||
JsonEditor: require("./cores/JsonEditor") | ||
Draft04: require("./cores/Draft04"), // core implementing draft04 specs | ||
JsonEditor: require("./cores/JsonEditor") // adjusted core of draft04 to better support the json-editor | ||
}, | ||
createSchemaOf: require("./createSchemaOf"), | ||
each: require("./each"), | ||
getSchema: require("./getSchema"), | ||
getTemplate: require("./getTemplate"), | ||
getTypeOf: require("./getTypeOf"), | ||
isValid: require("./isValid"), | ||
iterateSchema: require("./iterateSchema"), | ||
createSchemaOf: require("./createSchemaOf"), // creates a simple schema based on the given data | ||
each: require("./each"), // iterate over data, receiving each data-entry with its schema | ||
getSchema: require("./getSchema"), // get schema of data | ||
getChildSchemaSelection: require("./getChildSchemaSelection"), // get available child schemas | ||
getTemplate: require("./getTemplate"), // create data based which validates the given schema | ||
getTypeOf: require("./getTypeOf"), // returns the javascript datatype | ||
isValid: require("./isValid"), // returns a boolean if the schema is valid | ||
iterateSchema: require("./iterateSchema"), // iterates over a json-schema | ||
SchemaService: require("./SchemaService"), | ||
step: require("./step"), | ||
validate: require("./validate") | ||
step: require("./step"), // steps into a json-schema, returning the matching child-schema | ||
validate: require("./validate") // validates data by a schema | ||
}; |
@@ -36,8 +36,7 @@ const getTypeOf = require("./getTypeOf"); | ||
if (getTypeOf(schema.items) === "object") { | ||
Object.keys(schema.items).forEach((prop) => { | ||
iteratSchema(schema.items[prop], callback, gp.join(pointer, "items", prop)); | ||
}); | ||
iteratSchema(schema.items, callback, gp.join(pointer, "items")); | ||
return; | ||
} | ||
if (getTypeOf(schema.items === "array")) { | ||
if (getTypeOf(schema.items) === "array") { | ||
schema.items.forEach((itemSchema, index) => | ||
@@ -44,0 +43,0 @@ iteratSchema(itemSchema, callback, gp.join(pointer, "items", index))); |
@@ -37,3 +37,3 @@ const getTypeOf = require("./getTypeOf"); | ||
if (oneOfValue === undefined) { | ||
return new core.errors.MissingOneOfPropertyError({ property: oneOfProperty, pointer }); | ||
return core.errors.missingOneOfPropertyError({ property: oneOfProperty, pointer }); | ||
} | ||
@@ -45,3 +45,3 @@ | ||
if (oneOfPropertySchema instanceof Error) { | ||
if (oneOfPropertySchema && oneOfPropertySchema.type === "error") { | ||
return oneOfPropertySchema; | ||
@@ -55,3 +55,3 @@ } | ||
return new core.errors.OneOfPropertyError({ property: oneOfProperty, value: oneOfValue, pointer }); | ||
return core.errors.oneOfPropertyError({ property: oneOfProperty, value: oneOfValue, pointer }); | ||
} | ||
@@ -71,3 +71,3 @@ | ||
if (matches.length > 1) { | ||
return new core.errors.MultipleOneOfError({ value: data, pointer, matches }); | ||
return core.errors.multipleOneOfError({ value: data, pointer, matches }); | ||
} | ||
@@ -93,3 +93,3 @@ | ||
return new core.errors.OneOfError({ value: data, pointer, oneOf: schema.oneOf }); | ||
return core.errors.oneOfError({ value: data, pointer, oneOf: schema.oneOf }); | ||
}; |
@@ -23,6 +23,6 @@ /** | ||
if (matches.length > 1) { | ||
return new core.errors.MultipleOneOfError({ value: data, pointer, matches }); | ||
return core.errors.multipleOneOfError({ value: data, pointer, matches }); | ||
} | ||
return new core.errors.OneOfError({ value: data, pointer, oneOf: schema.oneOf }); | ||
return core.errors.oneOfError({ value: data, pointer, oneOf: schema.oneOf }); | ||
}; |
const getSchema = require("./getSchema"); | ||
const Core = require("./cores/JsonEditor"); | ||
const gp = require("gson-pointer"); | ||
const getParentPointer = require("gson-pointer/lib/common").getParentPointer; | ||
const getLastProperty = require("gson-pointer/lib/common").getLastProperty; | ||
function copy(value) { | ||
@@ -15,2 +19,3 @@ return JSON.parse(JSON.stringify(value)); | ||
this.data = data; | ||
this.cache = {}; | ||
} | ||
@@ -20,2 +25,3 @@ | ||
this.data = data; | ||
this.cache = {}; | ||
} | ||
@@ -26,7 +32,31 @@ | ||
this.core.rootSchema = schema; | ||
this.cache = {}; | ||
} | ||
get(pointer, data) { | ||
const schema = getSchema(this.core, this.schema, data || this.data, pointer); | ||
return copy(schema); | ||
if (data) { // possibly separate entry point | ||
const schema = getSchema(this.core, this.schema, data, pointer); | ||
return copy(schema); | ||
} | ||
if (pointer === "#") { // root | ||
return this.schema; | ||
} | ||
if (this.cache[pointer]) { // return cached result | ||
return this.cache[pointer]; | ||
} | ||
const parentPointer = getParentPointer(pointer); | ||
if (this.cache[parentPointer] == null) { | ||
// store parent (major performance improvement if its within oneof) | ||
const parentSchema = getSchema(this.core, this.schema, this.data, parentPointer); | ||
this.cache[parentPointer] = copy(parentSchema); | ||
} | ||
// step from parent to child | ||
const key = getLastProperty(pointer); | ||
const schema = getSchema(this.core, this.cache[parentPointer], gp.get(this.data, parentPointer), key); | ||
this.cache[pointer] = copy(schema); | ||
return this.cache[pointer]; | ||
} | ||
@@ -33,0 +63,0 @@ } |
const getTypeOf = require("./getTypeOf"); | ||
const createSchemaOf = require("./createSchemaOf"); | ||
const Errors = require("./validation/errors"); | ||
const errors = require("./validation/errors"); | ||
@@ -22,3 +22,3 @@ | ||
schema = core.resolveOneOf(schema, data, pointer); | ||
if (schema instanceof Error) { | ||
if (schema && schema.type === "error") { | ||
return schema; | ||
@@ -30,3 +30,3 @@ } | ||
return new Errors.OneOfPropertyError({ property: key, value: data, pointer }); | ||
return errors.oneOfPropertyError({ property: key, value: data, pointer }); | ||
} | ||
@@ -56,3 +56,3 @@ | ||
if (schema.additionalItems === false) { | ||
return new Errors.AdditionalItemsError({ key, value: data[key], pointer }); | ||
return errors.additionalItemsError({ key, value: data[key], pointer }); | ||
} | ||
@@ -59,0 +59,0 @@ |
@@ -15,14 +15,24 @@ const __ = require("./__"); | ||
module.exports = function createCustomError(name) { | ||
function CustomError(data) { | ||
const message = __(name, data); | ||
const error = Error.call(this, message); | ||
this.name = name; | ||
this.code = dashCase(name); | ||
this.stack = error.stack; | ||
this.message = message; | ||
this.data = data; | ||
} | ||
CustomError.prototype = Object.create(Error.prototype); | ||
CustomError.prototype.name = name; | ||
return CustomError; | ||
return function (data) { | ||
return { | ||
type: "error", | ||
name, | ||
code: dashCase(name), | ||
message: __(name, data), | ||
data | ||
}; | ||
}; | ||
// function CustomError(data) { | ||
// const message = __(name, data); | ||
// const error = Error.call(this, message); | ||
// this.name = name; | ||
// this.code = dashCase(name); | ||
// this.stack = error.stack; | ||
// this.message = message; | ||
// this.data = data; | ||
// } | ||
// CustomError.prototype = Object.create(Error.prototype); | ||
// CustomError.prototype.name = name; | ||
// return CustomError; | ||
}; |
module.exports = { | ||
errorsOnly(error) { | ||
return error instanceof Error; | ||
return error && error.type === "error"; | ||
} | ||
}; |
@@ -29,6 +29,6 @@ const getTypeOf = require("./getTypeOf"); | ||
if (receivedType !== expectedType) { | ||
return [new core.errors.TypeError({ received: receivedType, expected: expectedType, pointer })]; | ||
return [core.errors.typeError({ received: receivedType, expected: expectedType, pointer })]; | ||
} | ||
if (core.validateType[receivedType] == null) { | ||
return [new core.errors.InvalidTypeError({ receivedType, pointer })]; | ||
return [core.errors.invalidTypeError({ receivedType, pointer })]; | ||
} | ||
@@ -35,0 +35,0 @@ |
@@ -6,26 +6,26 @@ /* eslint no-invalid-this: 0 */ | ||
const errors = { | ||
AdditionalItemsError: createCustomError("AdditionalItemsError"), | ||
AdditionalPropertiesError: createCustomError("AdditionalPropertiesError"), | ||
EnumError: createCustomError("EnumError"), | ||
InvalidTypeError: createCustomError("InvalidTypeError"), | ||
MaximumError: createCustomError("MaximumError"), | ||
MaxItemsError: createCustomError("MaxItemsError"), | ||
MaxLengthError: createCustomError("MaxLengthError"), | ||
MaxPropertiesError: createCustomError("MaxPropertiesError"), | ||
MinimumError: createCustomError("MinimumError"), | ||
MinItemsError: createCustomError("MinItemsError"), | ||
MinLengthError: createCustomError("MinLengthError"), | ||
MinPropertiesError: createCustomError("MinPropertiesError"), | ||
MissingKeyError: createCustomError("MissingKeyError"), | ||
MissingOneOfPropertyError: createCustomError("MissingOneOfPropertyError"), | ||
MultipleOfError: createCustomError("MultipleOfError"), | ||
MultipleOneOfError: createCustomError("MultipleOneOfError"), | ||
NoAdditionalPropertiesError: createCustomError("NoAdditionalPropertiesError"), | ||
NotError: createCustomError("NotError"), | ||
OneOfError: createCustomError("OneOfError"), | ||
OneOfPropertyError: createCustomError("OneOfPropertyError"), | ||
PatternError: createCustomError("PatternError"), | ||
TypeError: createCustomError("TypeError"), | ||
UndefinedValueError: createCustomError("UndefinedValueError"), | ||
InvalidSchemaError: createCustomError("InvalidSchemaError") | ||
additionalItemsError: createCustomError("AdditionalItemsError"), | ||
additionalPropertiesError: createCustomError("AdditionalPropertiesError"), | ||
enumError: createCustomError("EnumError"), | ||
invalidTypeError: createCustomError("InvalidTypeError"), | ||
maximumError: createCustomError("MaximumError"), | ||
maxItemsError: createCustomError("MaxItemsError"), | ||
maxLengthError: createCustomError("MaxLengthError"), | ||
maxPropertiesError: createCustomError("MaxPropertiesError"), | ||
minimumError: createCustomError("MinimumError"), | ||
minItemsError: createCustomError("MinItemsError"), | ||
minLengthError: createCustomError("MinLengthError"), | ||
minPropertiesError: createCustomError("MinPropertiesError"), | ||
missingKeyError: createCustomError("MissingKeyError"), | ||
missingOneOfPropertyError: createCustomError("MissingOneOfPropertyError"), | ||
multipleOfError: createCustomError("MultipleOfError"), | ||
multipleOneOfError: createCustomError("MultipleOneOfError"), | ||
noAdditionalPropertiesError: createCustomError("NoAdditionalPropertiesError"), | ||
notError: createCustomError("NotError"), | ||
oneOfError: createCustomError("OneOfError"), | ||
oneOfPropertyError: createCustomError("OneOfPropertyError"), | ||
patternError: createCustomError("PatternError"), | ||
typeError: createCustomError("TypeError"), | ||
undefinedValueError: createCustomError("UndefinedValueError"), | ||
invalidSchemaError: createCustomError("InvalidSchemaError") | ||
}; | ||
@@ -32,0 +32,0 @@ |
@@ -19,3 +19,3 @@ // list of validation keywords: http://json-schema.org/latest/json-schema-validation.html#rfc.section.5 | ||
if (core.validate(schema.additionalProperties, value[property], pointer).length !== 0) { | ||
return new core.errors.AdditionalPropertiesError({ | ||
return core.errors.additionalPropertiesError({ | ||
schema: schema.additionalProperties, | ||
@@ -27,3 +27,3 @@ property: receivedProperties[i], | ||
} else { | ||
return new core.errors.NoAdditionalPropertiesError( | ||
return core.errors.noAdditionalPropertiesError( | ||
{ property: receivedProperties[i], properties: expectedProperties, pointer } | ||
@@ -39,3 +39,3 @@ ); | ||
if (schema.enum && schema.enum.indexOf(value) === -1) { | ||
return new core.errors.EnumError({ values: schema.enum, value, pointer }); | ||
return core.errors.enumError({ values: schema.enum, value, pointer }); | ||
} | ||
@@ -56,6 +56,6 @@ return undefined; | ||
if (schema.maximum && schema.maximum < value) { | ||
return new core.errors.MaximumError({ maximum: schema.maximum, length: value, pointer }); | ||
return core.errors.maximumError({ maximum: schema.maximum, length: value, pointer }); | ||
} | ||
if (schema.maximum && schema.exclusiveMaximum === true && schema.maximum === value) { | ||
return new core.errors.MaximumError({ maximum: schema.maximum, length: value, pointer }); | ||
return core.errors.maximumError({ maximum: schema.maximum, length: value, pointer }); | ||
} | ||
@@ -69,3 +69,3 @@ return undefined; | ||
if (schema.maxItems < value.length) { | ||
return new core.errors.MaxItemsError({ maxItems: schema.maxItems, length: value.length, pointer }); | ||
return core.errors.maxItemsError({ maxItems: schema.maxItems, length: value.length, pointer }); | ||
} | ||
@@ -79,3 +79,3 @@ return undefined; | ||
if (schema.maxLength < value.length) { | ||
return new core.errors.MaxLengthError({ maxLength: schema.maxLength, length: value.length, pointer }); | ||
return core.errors.maxLengthError({ maxLength: schema.maxLength, length: value.length, pointer }); | ||
} | ||
@@ -87,3 +87,3 @@ return undefined; | ||
if (isNaN(schema.maxProperties) === false && schema.maxProperties < propertyCount) { | ||
return new core.errors.MaxPropertiesError({ | ||
return core.errors.maxPropertiesError({ | ||
maxProperties: schema.maxProperties, | ||
@@ -101,3 +101,3 @@ length: propertyCount, | ||
if (schema.minLength > value.length) { | ||
return new core.errors.MinLengthError({ minLength: schema.minLength, length: value.length, pointer }); | ||
return core.errors.minLengthError({ minLength: schema.minLength, length: value.length, pointer }); | ||
} | ||
@@ -111,6 +111,6 @@ return undefined; | ||
if (schema.minimum > value) { | ||
return new core.errors.MinimumError({ minimum: schema.minimum, length: value, pointer }); | ||
return core.errors.minimumError({ minimum: schema.minimum, length: value, pointer }); | ||
} | ||
if (schema.exclusiveMinimum === true && schema.minimum === value) { | ||
return new core.errors.MinimumError({ minimum: schema.minimum, length: value, pointer }); | ||
return core.errors.minimumError({ minimum: schema.minimum, length: value, pointer }); | ||
} | ||
@@ -124,3 +124,3 @@ return undefined; | ||
if (schema.minItems > value.length) { | ||
return new core.errors.MinItemsError({ minItems: schema.minItems, length: value.length, pointer }); | ||
return core.errors.minItemsError({ minItems: schema.minItems, length: value.length, pointer }); | ||
} | ||
@@ -135,3 +135,3 @@ return undefined; | ||
if (schema.minProperties > propertyCount) { | ||
return new core.errors.MinPropertiesError({ | ||
return core.errors.minPropertiesError({ | ||
minProperties: schema.minProperties, | ||
@@ -148,3 +148,3 @@ length: propertyCount, pointer | ||
if ((value % schema.multipleOf) !== 0) { | ||
return new core.errors.MultipleOfError({ multipleOf: schema.multipleOf, value, pointer }); | ||
return core.errors.multipleOfError({ multipleOf: schema.multipleOf, value, pointer }); | ||
} | ||
@@ -156,3 +156,3 @@ return undefined; | ||
// @todo: pass errrors | ||
return new core.errors.NotError({ value, not: schema.not, pointer }); | ||
return core.errors.notError({ value, not: schema.not, pointer }); | ||
} | ||
@@ -163,3 +163,3 @@ return undefined; | ||
if (schema.pattern && (new RegExp(schema.pattern)).test(value) === false) { | ||
return new core.errors.PatternError({ pattern: schema.pattern, received: value, pointer }); | ||
return core.errors.patternError({ pattern: schema.pattern, received: value, pointer }); | ||
} | ||
@@ -166,0 +166,0 @@ return undefined; |
@@ -12,3 +12,3 @@ /** | ||
if (value == null) { | ||
return [new core.errors.UndefinedValueError({ pointer })]; | ||
return [core.errors.undefinedValueError({ pointer })]; | ||
} | ||
@@ -29,3 +29,3 @@ | ||
if (itemSchema instanceof Error) { | ||
if (itemSchema && itemSchema.type === "error") { | ||
return [itemSchema]; | ||
@@ -43,3 +43,3 @@ } | ||
if (value == null) { | ||
return [new core.errors.UndefinedValueError({ pointer })]; | ||
return [core.errors.undefinedValueError({ pointer })]; | ||
} | ||
@@ -61,3 +61,3 @@ | ||
if (value[key] === undefined) { | ||
errors.push(new core.errors.MissingKeyError({ key, pointer })); | ||
errors.push(core.errors.missingKeyError({ key, pointer })); | ||
} else { | ||
@@ -64,0 +64,0 @@ const keyErrors = core.validate(itemSchema, value[key], join(pointer, key)); |
{ | ||
"name": "json-schema-library", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"description": "Customizable and hackable json-validator and json-schema utilities for traversal, data generation and validation", | ||
@@ -33,3 +33,6 @@ "main": "lib/index.js", | ||
"gson-pointer": "^1.0.4" | ||
}, | ||
"publishConfig": { | ||
"registry": "http://registry.npmjs.org" | ||
} | ||
} |
@@ -17,3 +17,3 @@ # json-schema-library | ||
Either select an existing __validator__ (`core`) or create your own. Each __Core__ hold all functions that are required | ||
Either select an existing __validator__ (`core`) or create your own. Each __Core__ holds all functions that are required | ||
for the json-schema operations like validation. In order to overwrite a custom function you can either | ||
@@ -61,3 +61,3 @@ | ||
```js | ||
if (targetSchema instanceOf Error) { | ||
if (targetSchema.type === "error") { | ||
throw targetSchema; | ||
@@ -87,3 +87,3 @@ } | ||
const errors = core.validate({ type: "number" }, ""); | ||
// returns [TypeError] | ||
// returns { type: "TypeError" } | ||
``` | ||
@@ -144,2 +144,9 @@ | ||
#### getChildSchemaSelection | ||
Returns a list of possible schemas for the given child-property or index | ||
```js | ||
const listOfAvailableOptions = getChildSchemaSelection(core, schema, "childKey"); | ||
``` | ||
#### createSchemaOf(data) | ||
@@ -146,0 +153,0 @@ Creates a json-schema for the given input-data. |
@@ -5,5 +5,7 @@ # Tasks | ||
- [ ] profile performance | ||
- [ ] -- Refactor -- type validation as keyword (in validation/keywords) | ||
- [ ] -- Features -- Improve validation maps to add & hook (!) custom entries | ||
- [ ] -- Features -- Helper to find a json- and json-schema-pointer | ||
- [ ] -- Fix -- Return all errors in oneOf-validation | ||
@@ -10,0 +12,0 @@ **Milestone** add remaining draft04 features |
@@ -58,3 +58,3 @@ const path = require("path"); | ||
); | ||
expect(result).to.be.instanceof(Error); | ||
expect(result.type).to.eq("error"); | ||
expect(result.name).to.eq("OneOfError"); | ||
@@ -74,3 +74,3 @@ }); | ||
); | ||
expect(result).to.be.instanceof(Error); | ||
expect(result.type).to.eq("error"); | ||
expect(result.name).to.eq("MultipleOneOfError"); | ||
@@ -77,0 +77,0 @@ }); |
@@ -58,3 +58,3 @@ const path = require("path"); | ||
); | ||
expect(result).to.be.instanceof(Error); | ||
expect(result.type).to.eq("error"); | ||
expect(result.name).to.eq("OneOfError"); | ||
@@ -74,3 +74,3 @@ }); | ||
); | ||
expect(result).to.be.instanceof(Error); | ||
expect(result.type).to.eq("error"); | ||
expect(result.name).to.eq("MultipleOneOfError"); | ||
@@ -77,0 +77,0 @@ }); |
@@ -59,4 +59,7 @@ /* eslint quote-props: 0, no-unused-expressions: 0 */ | ||
items: { | ||
first: { type: "string" }, | ||
second: { type: "number" } | ||
type: "object", | ||
properties: { | ||
first: { type: "string" }, | ||
second: { type: "number" } | ||
} | ||
} | ||
@@ -67,5 +70,5 @@ }; | ||
expect(calls).to.have.length(3); | ||
expect(calls[1]).to.eq(rootSchema.items.first); | ||
expect(calls[2]).to.eq(rootSchema.items.second); | ||
expect(calls).to.have.length(4); | ||
expect(calls[2]).to.eq(rootSchema.items.properties.first); | ||
expect(calls[3]).to.eq(rootSchema.items.properties.second); | ||
}); | ||
@@ -72,0 +75,0 @@ |
@@ -109,3 +109,3 @@ /* eslint quote-props: 0 max-len: 0 */ | ||
expect(res).to.be.instanceof(Error); | ||
expect(res.type).to.eq("error"); | ||
expect(res.name).to.eq("MissingOneOfPropertyError"); | ||
@@ -124,3 +124,3 @@ }); | ||
expect(res).to.be.instanceof(Error); | ||
expect(res.type).to.eq("error"); | ||
expect(res.name).to.eq("OneOfPropertyError"); | ||
@@ -127,0 +127,0 @@ }); |
@@ -45,7 +45,7 @@ const expect = require("chai").expect; | ||
items: { | ||
title: { type: "string" } | ||
type: "string" | ||
} | ||
}); | ||
expect(res).to.deep.eq({ title: { type: "string" } }); | ||
expect(res).to.deep.eq({ type: "string" }); | ||
}); | ||
@@ -52,0 +52,0 @@ |
399012
62
4475
156