lp-simulation-environment/simulator/src/main/resources/static/deps/opt/ZSchema-browser.js
// This comes from https://github.com/zaggino/z-schema Version 3.1.2
// with ZSchema variable imported to global scope ready to be used by "new ZSchema()" call.
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};
process.nextTick = (function () {
var canSetImmediate = typeof window !== 'undefined'
&& window.setImmediate;
var canPost = typeof window !== 'undefined'
&& window.postMessage && window.addEventListener
;
if (canSetImmediate) {
return function (f) { return window.setImmediate(f) };
}
if (canPost) {
var queue = [];
window.addEventListener('message', function (ev) {
var source = ev.source;
if ((source === window || source === null) && ev.data === 'process-tick') {
ev.stopPropagation();
if (queue.length > 0) {
var fn = queue.shift();
fn();
}
}
}, true);
return function nextTick(fn) {
queue.push(fn);
window.postMessage('process-tick', '*');
};
}
return function nextTick(fn) {
setTimeout(fn, 0);
};
})();
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.binding = function (name) {
throw new Error('process.binding is not supported');
}
// TODO(shtylman)
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
},{}],2:[function(require,module,exports){
"use strict";
module.exports = {
INVALID_TYPE: "Expected type {0} but found type {1}",
INVALID_FORMAT: "Object didn't pass validation for format {0}: {1}",
ENUM_MISMATCH: "No enum match for: {0}",
ANY_OF_MISSING: "Data does not match any schemas from 'anyOf'",
ONE_OF_MISSING: "Data does not match any schemas from 'oneOf'",
ONE_OF_MULTIPLE: "Data is valid against more than one schema from 'oneOf'",
NOT_PASSED: "Data matches schema from 'not'",
// Array errors
ARRAY_LENGTH_SHORT: "Array is too short ({0}), minimum {1}",
ARRAY_LENGTH_LONG: "Array is too long ({0}), maximum {1}",
ARRAY_UNIQUE: "Array items are not unique (indexes {0} and {1})",
ARRAY_ADDITIONAL_ITEMS: "Additional items not allowed",
// Numeric errors
MULTIPLE_OF: "Value {0} is not a multiple of {1}",
MINIMUM: "Value {0} is less than minimum {1}",
MINIMUM_EXCLUSIVE: "Value {0} is equal or less than exclusive minimum {1}",
MAXIMUM: "Value {0} is greater than maximum {1}",
MAXIMUM_EXCLUSIVE: "Value {0} is equal or greater than exclusive maximum {1}",
// Object errors
OBJECT_PROPERTIES_MINIMUM: "Too few properties defined ({0}), minimum {1}",
OBJECT_PROPERTIES_MAXIMUM: "Too many properties defined ({0}), maximum {1}",
OBJECT_MISSING_REQUIRED_PROPERTY: "Missing required property: {0}",
OBJECT_ADDITIONAL_PROPERTIES: "Additional properties not allowed: {0}",
OBJECT_DEPENDENCY_KEY: "Dependency failed - key must exist: {0} (due to key: {1})",
// String errors
MIN_LENGTH: "String is too short ({0} chars), minimum {1}",
MAX_LENGTH: "String is too long ({0} chars), maximum {1}",
PATTERN: "String does not match pattern {0}: {1}",
// Schema validation errors
KEYWORD_TYPE_EXPECTED: "Keyword '{0}' is expected to be of type '{1}'",
KEYWORD_UNDEFINED_STRICT: "Keyword '{0}' must be defined in strict mode",
KEYWORD_UNEXPECTED: "Keyword '{0}' is not expected to appear in the schema",
KEYWORD_MUST_BE: "Keyword '{0}' must be {1}",
KEYWORD_DEPENDENCY: "Keyword '{0}' requires keyword '{1}'",
KEYWORD_PATTERN: "Keyword '{0}' is not a valid RegExp pattern: {1}",
KEYWORD_VALUE_TYPE: "Each element of keyword '{0}' array must be a '{1}'",
UNKNOWN_FORMAT: "There is no validation function for format '{0}'",
CUSTOM_MODE_FORCE_PROPERTIES: "{0} must define at least one property if present",
// Remote errors
REF_UNRESOLVED: "Reference has not been resolved during compilation: {0}",
UNRESOLVABLE_REFERENCE: "Reference could not be resolved: {0}",
SCHEMA_NOT_REACHABLE: "Validator was not able to read schema with uri: {0}",
SCHEMA_TYPE_EXPECTED: "Schema is expected to be of type 'object'",
SCHEMA_NOT_AN_OBJECT: "Schema is not an object: {0}",
ASYNC_TIMEOUT: "{0} asynchronous task(s) have timed out after {1} ms",
PARENT_SCHEMA_VALIDATION_FAILED: "Schema failed to validate against its parent schema, see inner errors for details."
};
},{}],3:[function(require,module,exports){
/*jshint maxlen: false*/
var FormatValidators = {
"date": function (date) {
if (typeof date !== "string") {
return true;
}
// full-date from http://tools.ietf.org/html/rfc3339#section-5.6
var matches = /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/.exec(date);
if (matches === null) {
return false;
}
// var year = matches[1];
// var month = matches[2];
// var day = matches[3];
if (matches[2] < "01" || matches[2] > "12" || matches[3] < "01" || matches[3] > "31") {
return false;
}
return true;
},
"date-time": function (dateTime) {
if (typeof dateTime !== "string") {
return true;
}
// date-time from http://tools.ietf.org/html/rfc3339#section-5.6
var s = dateTime.toLowerCase().split("t");
if (!FormatValidators.date(s[0])) {
return false;
}
var matches = /^([0-9]{2}):([0-9]{2}):([0-9]{2})(.[0-9]+)?(z|([+-][0-9]{2}:[0-9]{2}))$/.exec(s[1]);
if (matches === null) {
return false;
}
// var hour = matches[1];
// var minute = matches[2];
// var second = matches[3];
// var fraction = matches[4];
// var timezone = matches[5];
if (matches[1] > "23" || matches[2] > "59" || matches[3] > "59") {
return false;
}
return true;
},
"email": function (email) {
if (typeof email !== "string") {
return true;
}
// use regex from owasp: https://www.owasp.org/index.php/OWASP_Validation_Regex_Repository
return /^[a-zA-Z0-9+&*-]+(?:\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,7}$/.test(email);
},
"hostname": function (hostname) {
if (typeof hostname !== "string") {
return true;
}
/*
http://json-schema.org/latest/json-schema-validation.html#anchor114
A string instance is valid against this attribute if it is a valid
representation for an Internet host name, as defined by RFC 1034, section 3.1 [RFC1034].
http://tools.ietf.org/html/rfc1034#section-3.5
<digit> ::= any one of the ten digits 0 through 9
var digit = /[0-9]/;
<letter> ::= any one of the 52 alphabetic characters A through Z in upper case and a through z in lower case
var letter = /[a-zA-Z]/;
<let-dig> ::= <letter> | <digit>
var letDig = /[0-9a-zA-Z]/;
<let-dig-hyp> ::= <let-dig> | "-"
var letDigHyp = /[-0-9a-zA-Z]/;
<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
var ldhStr = /[-0-9a-zA-Z]+/;
<label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
var label = /[a-zA-Z](([-0-9a-zA-Z]+)?[0-9a-zA-Z])?/;
<subdomain> ::= <label> | <subdomain> "." <label>
var subdomain = /^[a-zA-Z](([-0-9a-zA-Z]+)?[0-9a-zA-Z])?(\.[a-zA-Z](([-0-9a-zA-Z]+)?[0-9a-zA-Z])?)*$/;
<domain> ::= <subdomain> | " "
var domain = null;
*/
var valid = /^[a-zA-Z](([-0-9a-zA-Z]+)?[0-9a-zA-Z])?(\.[a-zA-Z](([-0-9a-zA-Z]+)?[0-9a-zA-Z])?)*$/.test(hostname);
if (valid) {
// the sum of all label octets and label lengths is limited to 255.
if (hostname.length > 255) { return false; }
// Each node has a label, which is zero to 63 octets in length
var labels = hostname.split(".");
for (var i = 0; i < labels.length; i++) { if (labels[i].length > 63) { return false; } }
}
return valid;
},
"host-name": function (hostname) {
return FormatValidators.hostname.call(this, hostname);
},
"ipv4": function (ipv4) {
if (typeof ipv4 !== "string") { return true; }
if (ipv4.indexOf(".") === -1) { return false; }
// https://www.owasp.org/index.php/OWASP_Validation_Regex_Repository
return /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipv4);
},
"ipv6": function (ipv6) {
// Stephen Ryan at Dartware @ http://forums.intermapper.com/viewtopic.php?t=452
return typeof ipv6 !== "string" || /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/.test(ipv6);
},
"regex": function (str) {
try {
RegExp(str);
return true;
} catch (e) {
return false;
}
},
"uri": function (uri) {
if (this.options.strictUris) {
return FormatValidators["strict-uri"].apply(this, arguments);
}
// https://github.com/zaggino/z-schema/issues/18
// RegExp from http://tools.ietf.org/html/rfc3986#appendix-B
return typeof uri !== "string" || RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?").test(uri);
},
"strict-uri": function (uri) {
// http://mathiasbynens.be/demo/url-regex
// https://gist.github.com/dperini/729294
return typeof uri !== "string" || RegExp(
"^" +
// protocol identifier
"(?:(?:https?|ftp)://)" +
// user:pass authentication
"(?:\\S+(?::\\S*)?@)?" +
"(?:" +
// IP address exclusion
// private & local networks
"(?!10(?:\\.\\d{1,3}){3})" +
"(?!127(?:\\.\\d{1,3}){3})" +
"(?!169\\.254(?:\\.\\d{1,3}){2})" +
"(?!192\\.168(?:\\.\\d{1,3}){2})" +
"(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" +
// IP address dotted notation octets
// excludes loopback network 0.0.0.0
// excludes reserved space >= 224.0.0.0
// excludes network & broacast addresses
// (first & last IP address of each class)
"(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" +
"(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" +
"(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" +
"|" +
// host name
"(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)" +
// domain name
"(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*" +
// TLD identifier
"(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" +
")" +
// port number
"(?::\\d{2,5})?" +
// resource path
"(?:/[^\\s]*)?" +
"$", "i"
).test(uri);
}
};
module.exports = FormatValidators;
},{}],4:[function(require,module,exports){
"use strict";
var FormatValidators = require("./FormatValidators"),
Report = require("./Report"),
Utils = require("./Utils");
var JsonValidators = {
multipleOf: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.1.2
if (typeof json !== "number") {
return;
}
if (Utils.whatIs(json / schema.multipleOf) !== "integer") {
report.addError("MULTIPLE_OF", [json, schema.multipleOf], null, schema.description);
}
},
maximum: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.2.2
if (typeof json !== "number") {
return;
}
if (schema.exclusiveMaximum !== true) {
if (json > schema.maximum) {
report.addError("MAXIMUM", [json, schema.maximum], null, schema.description);
}
} else {
if (json >= schema.maximum) {
report.addError("MAXIMUM_EXCLUSIVE", [json, schema.maximum], null, schema.description);
}
}
},
exclusiveMaximum: function () {
// covered in maximum
},
minimum: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.3.2
if (typeof json !== "number") {
return;
}
if (schema.exclusiveMinimum !== true) {
if (json < schema.minimum) {
report.addError("MINIMUM", [json, schema.minimum], null, schema.description);
}
} else {
if (json <= schema.minimum) {
report.addError("MINIMUM_EXCLUSIVE", [json, schema.minimum], null, schema.description);
}
}
},
exclusiveMinimum: function () {
// covered in minimum
},
maxLength: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.1.2
if (typeof json !== "string") {
return;
}
if (json.length > schema.maxLength) {
report.addError("MAX_LENGTH", [json.length, schema.maxLength], null, schema.description);
}
},
minLength: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.2.2
if (typeof json !== "string") {
return;
}
if (json.length < schema.minLength) {
report.addError("MIN_LENGTH", [json.length, schema.minLength], null, schema.description);
}
},
pattern: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.3.2
if (typeof json !== "string") {
return;
}
if (RegExp(schema.pattern).test(json) === false) {
report.addError("PATTERN", [schema.pattern, json], null, schema.description);
}
},
additionalItems: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.1.2
if (!Array.isArray(json)) {
return;
}
// if the value of "additionalItems" is boolean value false and the value of "items" is an array,
// the json is valid if its size is less than, or equal to, the size of "items".
if (schema.additionalItems === false && Array.isArray(schema.items)) {
if (json.length > schema.items.length) {
report.addError("ARRAY_ADDITIONAL_ITEMS", null, null, schema.description);
}
}
},
items: function () { /*report, schema, json*/
// covered in additionalItems
},
maxItems: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.2.2
if (!Array.isArray(json)) {
return;
}
if (json.length > schema.maxItems) {
report.addError("ARRAY_LENGTH_LONG", [json.length, schema.maxItems], null, schema.description);
}
},
minItems: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.3.2
if (!Array.isArray(json)) {
return;
}
if (json.length < schema.minItems) {
report.addError("ARRAY_LENGTH_SHORT", [json.length, schema.minItems], null, schema.description);
}
},
uniqueItems: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.4.2
if (!Array.isArray(json)) {
return;
}
if (schema.uniqueItems === true) {
var matches = [];
if (Utils.isUniqueArray(json, matches) === false) {
report.addError("ARRAY_UNIQUE", matches, null, schema.description);
}
}
},
maxProperties: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.1.2
if (Utils.whatIs(json) !== "object") {
return;
}
var keysCount = Object.keys(json).length;
if (keysCount > schema.maxProperties) {
report.addError("OBJECT_PROPERTIES_MAXIMUM", [keysCount, schema.maxProperties], null, schema.description);
}
},
minProperties: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.2.2
if (Utils.whatIs(json) !== "object") {
return;
}
var keysCount = Object.keys(json).length;
if (keysCount < schema.minProperties) {
report.addError("OBJECT_PROPERTIES_MINIMUM", [keysCount, schema.minProperties], null, schema.description);
}
},
required: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.3.2
if (Utils.whatIs(json) !== "object") {
return;
}
var idx = schema.required.length;
while (idx--) {
var requiredPropertyName = schema.required[idx];
if (json[requiredPropertyName] === undefined) {
report.addError("OBJECT_MISSING_REQUIRED_PROPERTY", [requiredPropertyName], null, schema.description);
}
}
},
additionalProperties: function (report, schema, json) {
// covered in properties and patternProperties
if (schema.properties === undefined && schema.patternProperties === undefined) {
return JsonValidators.properties.call(this, report, schema, json);
}
},
patternProperties: function (report, schema, json) {
// covered in properties
if (schema.properties === undefined) {
return JsonValidators.properties.call(this, report, schema, json);
}
},
properties: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.4.2
if (Utils.whatIs(json) !== "object") {
return;
}
var properties = schema.properties !== undefined ? schema.properties : {};
var patternProperties = schema.patternProperties !== undefined ? schema.patternProperties : {};
if (schema.additionalProperties === false) {
// The property set of the json to validate.
var s = Object.keys(json);
// The property set from "properties".
var p = Object.keys(properties);
// The property set from "patternProperties".
var pp = Object.keys(patternProperties);
// remove from "s" all elements of "p", if any;
s = Utils.difference(s, p);
// for each regex in "pp", remove all elements of "s" which this regex matches.
var idx = pp.length;
while (idx--) {
var regExp = RegExp(pp[idx]),
idx2 = s.length;
while (idx2--) {
if (regExp.test(s[idx2]) === true) {
s.splice(idx2, 1);
}
}
}
// Validation of the json succeeds if, after these two steps, set "s" is empty.
if (s.length > 0) {
report.addError("OBJECT_ADDITIONAL_PROPERTIES", [s], null, schema.description);
}
}
},
dependencies: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.5.2
if (Utils.whatIs(json) !== "object") {
return;
}
var keys = Object.keys(schema.dependencies),
idx = keys.length;
while (idx--) {
// iterate all dependencies
var dependencyName = keys[idx];
if (json[dependencyName]) {
var dependencyDefinition = schema.dependencies[dependencyName];
if (Utils.whatIs(dependencyDefinition) === "object") {
// if dependency is a schema, validate against this schema
exports.validate.call(this, report, dependencyDefinition, json);
} else { // Array
// if dependency is an array, object needs to have all properties in this array
var idx2 = dependencyDefinition.length;
while (idx2--) {
var requiredPropertyName = dependencyDefinition[idx2];
if (json[requiredPropertyName] === undefined) {
report.addError("OBJECT_DEPENDENCY_KEY", [requiredPropertyName, dependencyName], null, schema.description);
}
}
}
}
}
},
enum: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.1.2
var match = false,
idx = schema.enum.length;
while (idx--) {
if (Utils.areEqual(json, schema.enum[idx])) {
match = true;
break;
}
}
if (match === false) {
report.addError("ENUM_MISMATCH", [json], null, schema.description);
}
},
/*
type: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.2.2
// type is handled before this is called so ignore
},
*/
allOf: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.3.2
var idx = schema.allOf.length;
while (idx--) {
if (exports.validate.call(this, report, schema.allOf[idx], json) === false) {
break;
}
}
},
anyOf: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.4.2
var subReports = [],
passed = false,
idx = schema.anyOf.length;
while (idx-- && passed === false) {
var subReport = new Report(report);
subReports.push(subReport);
passed = exports.validate.call(this, subReport, schema.anyOf[idx], json);
}
if (passed === false) {
report.addError("ANY_OF_MISSING", undefined, subReports, schema.description);
}
},
oneOf: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.5.2
var passes = 0,
subReports = [],
idx = schema.oneOf.length;
while (idx--) {
var subReport = new Report(report);
subReports.push(subReport);
if (exports.validate.call(this, subReport, schema.oneOf[idx], json) === true) {
passes++;
}
}
if (passes === 0) {
report.addError("ONE_OF_MISSING", undefined, subReports, schema.description);
} else if (passes > 1) {
report.addError("ONE_OF_MULTIPLE", null, null, schema.description);
}
},
not: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.6.2
var subReport = new Report(report);
if (exports.validate.call(this, subReport, schema.not, json) === true) {
report.addError("NOT_PASSED", null, null, schema.description);
}
},
definitions: function () { /*report, schema, json*/
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.7.2
// nothing to do here
},
format: function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.7.2
var formatValidatorFn = FormatValidators[schema.format];
if (typeof formatValidatorFn === "function") {
if (formatValidatorFn.length === 2) {
// async
report.addAsyncTask(formatValidatorFn, [json], function (result) {
if (result !== true) {
report.addError("INVALID_FORMAT", [schema.format, json], null, schema.description);
}
});
} else {
// sync
if (formatValidatorFn.call(this, json) !== true) {
report.addError("INVALID_FORMAT", [schema.format, json], null, schema.description);
}
}
} else {
report.addError("UNKNOWN_FORMAT", [schema.format], null, schema.description);
}
}
};
var recurseArray = function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.8.2
var idx = json.length;
// If "items" is an array, this situation, the schema depends on the index:
// if the index is less than, or equal to, the size of "items",
// the child instance must be valid against the corresponding schema in the "items" array;
// otherwise, it must be valid against the schema defined by "additionalItems".
if (Array.isArray(schema.items)) {
while (idx--) {
// equal to doesnt make sense here
if (idx < schema.items.length) {
report.path.push(idx.toString());
exports.validate.call(this, report, schema.items[idx], json[idx]);
report.path.pop();
} else {
// might be boolean, so check that it's an object
if (typeof schema.additionalItems === "object") {
report.path.push(idx.toString());
exports.validate.call(this, report, schema.additionalItems, json[idx]);
report.path.pop();
}
}
}
} else if (typeof schema.items === "object") {
// If items is a schema, then the child instance must be valid against this schema,
// regardless of its index, and regardless of the value of "additionalItems".
while (idx--) {
report.path.push(idx.toString());
exports.validate.call(this, report, schema.items, json[idx]);
report.path.pop();
}
}
};
var recurseObject = function (report, schema, json) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.8.3
// If "additionalProperties" is absent, it is considered present with an empty schema as a value.
// In addition, boolean value true is considered equivalent to an empty schema.
var additionalProperties = schema.additionalProperties;
if (additionalProperties === true || additionalProperties === undefined) {
additionalProperties = {};
}
// p - The property set from "properties".
var p = schema.properties ? Object.keys(schema.properties) : [];
// pp - The property set from "patternProperties". Elements of this set will be called regexes for convenience.
var pp = schema.patternProperties ? Object.keys(schema.patternProperties) : [];
// m - The property name of the child.
var keys = Object.keys(json),
idx = keys.length;
while (idx--) {
var m = keys[idx],
propertyValue = json[m];
// s - The set of schemas for the child instance.
var s = [];
// 1. If set "p" contains value "m", then the corresponding schema in "properties" is added to "s".
if (p.indexOf(m) !== -1) {
s.push(schema.properties[m]);
}
// 2. For each regex in "pp", if it matches "m" successfully, the corresponding schema in "patternProperties" is added to "s".
var idx2 = pp.length;
while (idx2--) {
var regexString = pp[idx2];
if (RegExp(regexString).test(m) === true) {
s.push(schema.patternProperties[regexString]);
}
}
// 3. The schema defined by "additionalProperties" is added to "s" if and only if, at this stage, "s" is empty.
if (s.length === 0 && additionalProperties !== false) {
s.push(additionalProperties);
}
// we are passing tests even without this assert because this is covered by properties check
// if s is empty in this stage, no additionalProperties are allowed
// report.expect(s.length !== 0, 'E001', m);
// Instance property value must pass all schemas from s
idx2 = s.length;
while (idx2--) {
report.path.push(m);
exports.validate.call(this, report, s[idx2], propertyValue);
report.path.pop();
}
}
};
exports.validate = function (report, schema, json) {
// check if schema is an object
var to = Utils.whatIs(schema);
if (to !== "object") {
report.addError("SCHEMA_NOT_AN_OBJECT", [to], null, schema.description);
return false;
}
// check if schema is empty, everything is valid against empty schema
var keys = Object.keys(schema);
if (keys.length === 0) {
return true;
}
// this method can be called recursively, so we need to remember our root
var isRoot = false;
if (!report.rootSchema) {
report.rootSchema = schema;
isRoot = true;
}
// follow schema.$ref keys
if (schema.$ref !== undefined) {
// avoid infinite loop with maxRefs
var maxRefs = 99;
while (schema.$ref && maxRefs > 0) {
if (!schema.__$refResolved) {
report.addError("REF_UNRESOLVED", [schema.$ref], null, schema.description);
break;
} else if (schema.__$refResolved === schema) {
break;
} else {
schema = schema.__$refResolved;
keys = Object.keys(schema);
}
maxRefs--;
}
if (maxRefs === 0) {
throw new Error("Circular dependency by $ref references!");
}
}
// type checking first
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.2.2
var jsonType = Utils.whatIs(json);
if (schema.type) {
if (typeof schema.type === "string") {
if (jsonType !== schema.type && (jsonType !== "integer" || schema.type !== "number")) {
report.addError("INVALID_TYPE", [schema.type, jsonType], null, schema.description);
return false;
}
} else {
if (schema.type.indexOf(jsonType) === -1 && (jsonType !== "integer" || schema.type.indexOf("number") === -1)) {
report.addError("INVALID_TYPE", [schema.type, jsonType], null, schema.description);
return false;
}
}
}
// now iterate all the keys in schema and execute validation methods
var idx = keys.length;
while (idx--) {
if (JsonValidators[keys[idx]]) {
JsonValidators[keys[idx]].call(this, report, schema, json);
if (report.errors.length) { break; }
}
}
if (jsonType === "array") {
recurseArray.call(this, report, schema, json);
} else if (jsonType === "object") {
recurseObject.call(this, report, schema, json);
}
// we don't need the root pointer anymore
if (isRoot) {
report.rootSchema = undefined;
}
// return valid just to be able to break at some code points
return report.errors.length === 0;
};
},{"./FormatValidators":3,"./Report":6,"./Utils":10}],5:[function(require,module,exports){
// Number.isFinite polyfill
// http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite
if (typeof Number.isFinite !== "function") {
Number.isFinite = function isFinite(value) {
// 1. If Type(number) is not Number, return false.
if (typeof value !== "number") {
return false;
}
// 2. If number is NaN, +∞, or −∞, return false.
if (value !== value || value === Infinity || value === -Infinity) {
return false;
}
// 3. Otherwise, return true.
return true;
};
}
},{}],6:[function(require,module,exports){
(function (process){
"use strict";
var Errors = require("./Errors");
function Report(parentOrOptions) {
this.parentReport = parentOrOptions instanceof Report ?
parentOrOptions :
undefined;
this.options = parentOrOptions instanceof Report ?
parentOrOptions.options :
parentOrOptions || {};
this.errors = [];
this.path = [];
this.asyncTasks = [];
}
Report.prototype.isValid = function () {
if (this.asyncTasks.length > 0) {
throw new Error("Async tasks pending, can't answer isValid");
}
return this.errors.length === 0;
};
Report.prototype.addAsyncTask = function (fn, args, asyncTaskResultProcessFn) {
this.asyncTasks.push([fn, args, asyncTaskResultProcessFn]);
};
Report.prototype.processAsyncTasks = function (timeout, callback) {
var validationTimeout = timeout || 2000,
tasksCount = this.asyncTasks.length,
idx = tasksCount,
timedOut = false,
self = this;
function finish() {
process.nextTick(function () {
var valid = self.errors.length === 0,
err = valid ? undefined : self.errors;
callback(err, valid);
});
}
function respond(asyncTaskResultProcessFn) {
return function (asyncTaskResult) {
if (timedOut) { return; }
asyncTaskResultProcessFn(asyncTaskResult);
if (--tasksCount === 0) {
finish();
}
};
}
if (tasksCount === 0 || this.errors.length > 0) {
finish();
return;
}
while (idx--) {
var task = this.asyncTasks[idx];
task[0].apply(null, task[1].concat(respond(task[2])));
}
setTimeout(function () {
if (tasksCount > 0) {
timedOut = true;
self.addError("ASYNC_TIMEOUT", [tasksCount, validationTimeout]);
callback(self.errors, false);
}
}, validationTimeout);
};
Report.prototype.getPath = function () {
var path = [];
if (this.parentReport) {
path = path.concat(this.parentReport.path);
}
path = path.concat(this.path);
if (this.options.reportPathAsArray !== true) {
// Sanitize the path segments (http://tools.ietf.org/html/rfc6901#section-4)
path = "#/" + path.map(function (segment) {
return segment.replace("~", "~0").replace("/", "~1");
}).join("/");
}
return path;
};
Report.prototype.addError = function (errorCode, params, subReports, schemaDescription) {
if (!errorCode) { throw new Error("No errorCode passed into addError()"); }
if (!Errors[errorCode]) { throw new Error("No errorMessage known for code " + errorCode); }
params = params || [];
var idx = params.length,
errorMessage = Errors[errorCode];
while (idx--) {
errorMessage = errorMessage.replace("{" + idx + "}", params[idx]);
}
var err = {
code: errorCode,
params: params,
message: errorMessage,
path: this.getPath()
};
if (schemaDescription) {
err.description = schemaDescription;
}
if (subReports != null) {
if (!Array.isArray(subReports)) {
subReports = [subReports];
}
err.inner = [];
idx = subReports.length;
while (idx--) {
var subReport = subReports[idx],
idx2 = subReport.errors.length;
while (idx2--) {
err.inner.push(subReport.errors[idx2]);
}
}
if (err.inner.length === 0) {
err.inner = undefined;
}
}
this.errors.push(err);
};
module.exports = Report;
}).call(this,require("+NscNm"))
},{"+NscNm":1,"./Errors":2}],7:[function(require,module,exports){
"use strict";
var SchemaCompilation = require("./SchemaCompilation");
var SchemaValidation = require("./SchemaValidation");
function decodeJSONPointer(str) {
// http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07#section-3
return decodeURIComponent(str).replace(/~[0-1]/g, function (x) {
return x === "~1" ? "/" : "~";
});
}
function getRemotePath(uri) {
var io = uri.indexOf("#");
return io === -1 ? uri : uri.slice(0, io);
}
function getQueryPath(uri) {
var io = uri.indexOf("#");
var res = io === -1 ? undefined : uri.slice(io + 1);
// WARN: do not slice slash, #/ means take root and go down from it
// if (res && res[0] === "/") { res = res.slice(1); }
return res;
}
function findId(schema, id) {
// process only arrays and objects
if (typeof schema !== "object" || schema === null) {
return;
}
// no id means root so return itself
if (!id) {
return schema;
}
if (schema.id) {
if (schema.id === id || schema.id[0] === "#" && schema.id.substring(1) === id) {
return schema;
}
}
var idx, result;
if (Array.isArray(schema)) {
idx = schema.length;
while (idx--) {
result = findId(schema[idx], id);
if (result) { return result; }
}
} else {
var keys = Object.keys(schema);
idx = keys.length;
while (idx--) {
var k = keys[idx];
if (k.indexOf("__$") === 0) {
continue;
}
result = findId(schema[k], id);
if (result) { return result; }
}
}
}
exports.cacheSchemaByUri = function (uri, schema) {
var remotePath = getRemotePath(uri);
if (remotePath) {
this.cache[remotePath] = schema;
}
};
exports.removeFromCacheByUri = function (uri) {
var remotePath = getRemotePath(uri);
if (remotePath) {
this.cache[remotePath] = undefined;
}
};
exports.checkCacheForUri = function (uri) {
var remotePath = getRemotePath(uri);
return remotePath ? this.cache[remotePath] != null : false;
};
exports.getSchemaByUri = function (report, uri, root) {
var remotePath = getRemotePath(uri),
queryPath = getQueryPath(uri),
result = remotePath ? this.cache[remotePath] : root;
if (result && remotePath) {
// we need to avoid compiling schemas in a recursive loop
var compileRemote = result !== root;
// now we need to compile and validate resolved schema (in case it's not already)
if (compileRemote) {
report.path.push(remotePath);
var ok = SchemaCompilation.compileSchema.call(this, report, result);
if (ok) { ok = SchemaValidation.validateSchema.call(this, report, result); }
report.path.pop();
if (!ok) { return undefined; }
}
}
if (result && queryPath) {
var parts = queryPath.split("/");
for (var idx = 0, lim = parts.length; idx < lim; idx++) {
var key = decodeJSONPointer(parts[idx]);
if (idx === 0) { // it's an id
result = findId(result, key);
} else { // it's a path behind id
result = result[key];
}
}
}
return result;
};
exports.getRemotePath = getRemotePath;
},{"./SchemaCompilation":8,"./SchemaValidation":9}],8:[function(require,module,exports){
"use strict";
var Report = require("./Report");
var SchemaCache = require("./SchemaCache");
function isAbsoluteUri(uri) {
return /^https?:\/\//.test(uri);
}
function isRelativeUri(uri) {
// relative URIs that end with a hash sign, issue #56
return /.+#/.test(uri);
}
function mergeReference(scope, ref) {
if (isAbsoluteUri(ref)) {
return ref;
}
var joinedScope = scope.join(""),
isScopeAbsolute = isAbsoluteUri(joinedScope),
isScopeRelative = isRelativeUri(joinedScope),
isRefRelative = isRelativeUri(ref),
toRemove;
if (isScopeAbsolute && isRefRelative) {
toRemove = joinedScope.match(/\/[^\/]*$/);
if (toRemove) {
joinedScope = joinedScope.slice(0, toRemove.index + 1);
}
} else if (isScopeRelative && isRefRelative) {
joinedScope = "";
} else {
toRemove = joinedScope.match(/[^#/]+$/);
if (toRemove) {
joinedScope = joinedScope.slice(0, toRemove.index);
}
}
var res = joinedScope + ref;
res = res.replace(/##/, "#");
return res;
}
function collectReferences(obj, results, scope, path) {
results = results || [];
scope = scope || [];
path = path || [];
if (typeof obj !== "object" || obj === null) {
return results;
}
if (typeof obj.id === "string") {
scope.push(obj.id);
}
if (typeof obj.$ref === "string") {
results.push({
ref: mergeReference(scope, obj.$ref),
key: "$ref",
obj: obj,
path: path.join("/")
});
}
if (typeof obj.$schema === "string") {
results.push({
ref: mergeReference(scope, obj.$schema),
key: "$schema",
obj: obj,
path: path.join("/")
});
}
var idx;
if (Array.isArray(obj)) {
idx = obj.length;
while (idx--) {
path.push(idx);
collectReferences(obj[idx], results, scope, path);
path.pop();
}
} else {
var keys = Object.keys(obj);
idx = keys.length;
while (idx--) {
// do not recurse through resolved references and other z-schema props
if (keys[idx].indexOf("__$") === 0) { continue; }
path.push(keys[idx]);
collectReferences(obj[keys[idx]], results, scope, path);
path.pop();
}
}
if (typeof obj.id === "string") {
scope.pop();
}
return results;
}
var compileArrayOfSchemasLoop = function (mainReport, arr) {
var idx = arr.length,
compiledCount = 0;
while (idx--) {
// try to compile each schema separately
var report = new Report(mainReport);
var isValid = exports.compileSchema.call(this, report, arr[idx]);
if (isValid) { compiledCount++; }
// copy errors to report
mainReport.errors = mainReport.errors.concat(report.errors);
}
return compiledCount;
};
var compileArrayOfSchemas = function (report, arr) {
var compiled = 0,
lastLoopCompiled;
do {
// remove all UNRESOLVABLE_REFERENCE errors before compiling array again
var idx = report.errors.length;
while (idx--) {
if (report.errors[idx].code === "UNRESOLVABLE_REFERENCE") {
report.errors.splice(idx, 1);
}
}
// remember how many were compiled in the last loop
lastLoopCompiled = compiled;
// count how many are compiled now
compiled = compileArrayOfSchemasLoop.call(this, report, arr);
// keep repeating if not all compiled and at least one more was compiled in the last loop
} while (compiled !== arr.length && compiled !== lastLoopCompiled);
return report.isValid();
};
exports.compileSchema = function (report, schema) {
// if schema is a string, assume it's a uri
if (typeof schema === "string") {
var loadedSchema = SchemaCache.getSchemaByUri.call(this, report, schema);
if (!loadedSchema) {
report.addError("SCHEMA_NOT_REACHABLE", [schema]);
return false;
}
schema = loadedSchema;
}
// if schema is an array, assume it's an array of schemas
if (Array.isArray(schema)) {
return compileArrayOfSchemas.call(this, report, schema);
}
// if we have an id than it should be cached already (if this instance has compiled it)
if (schema.__$compiled && schema.id && SchemaCache.checkCacheForUri.call(this, schema.id) === false) {
schema.__$compiled = undefined;
}
// do not re-compile schemas
if (schema.__$compiled) {
return true;
}
if (schema.id) {
// add this to our schemaCache (before compilation in case we have references including id)
SchemaCache.cacheSchemaByUri.call(this, schema.id, schema);
}
// collect all references that need to be resolved - $ref and $schema
var refs = collectReferences.call(this, schema),
idx = refs.length;
while (idx--) {
// resolve all the collected references into __xxxResolved pointer
var refObj = refs[idx];
var response = SchemaCache.getSchemaByUri.call(this, report, refObj.ref, schema);
if (!response) {
if (!isAbsoluteUri(refObj.ref) || this.options.ignoreUnresolvableReferences !== true) {
report.path.push(refObj.path);
report.addError("UNRESOLVABLE_REFERENCE", [refObj.ref]);
report.path.pop();
return false;
}
}
// this might create circular references
refObj.obj["__" + refObj.key + "Resolved"] = response;
}
var isValid = report.isValid();
if (isValid) {
schema.__$compiled = true;
} else {
if (schema.id) {
// remove this schema from schemaCache because it failed to compile
SchemaCache.removeFromCacheByUri.call(this, schema.id);
}
}
return isValid;
};
},{"./Report":6,"./SchemaCache":7}],9:[function(require,module,exports){
"use strict";
var FormatValidators = require("./FormatValidators"),
JsonValidation = require("./JsonValidation"),
Report = require("./Report"),
Utils = require("./Utils");
var SchemaValidators = {
$ref: function (report, schema) {
// http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07
// http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03
if (typeof schema.$ref !== "string") {
report.addError("KEYWORD_TYPE_EXPECTED", ["$ref", "string"]);
}
},
$schema: function (report, schema) {
// http://json-schema.org/latest/json-schema-core.html#rfc.section.6
if (typeof schema.$schema !== "string") {
report.addError("KEYWORD_TYPE_EXPECTED", ["$schema", "string"]);
}
},
multipleOf: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.1.1
if (typeof schema.multipleOf !== "number") {
report.addError("KEYWORD_TYPE_EXPECTED", ["multipleOf", "number"]);
} else if (schema.multipleOf <= 0) {
report.addError("KEYWORD_MUST_BE", ["multipleOf", "strictly greater than 0"]);
}
},
maximum: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.2.1
if (typeof schema.maximum !== "number") {
report.addError("KEYWORD_TYPE_EXPECTED", ["maximum", "number"]);
}
},
exclusiveMaximum: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.2.1
if (typeof schema.exclusiveMaximum !== "boolean") {
report.addError("KEYWORD_TYPE_EXPECTED", ["exclusiveMaximum", "boolean"]);
} else if (schema.maximum === undefined) {
report.addError("KEYWORD_DEPENDENCY", ["exclusiveMaximum", "maximum"]);
}
},
minimum: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.3.1
if (typeof schema.minimum !== "number") {
report.addError("KEYWORD_TYPE_EXPECTED", ["minimum", "number"]);
}
},
exclusiveMinimum: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.3.1
if (typeof schema.exclusiveMinimum !== "boolean") {
report.addError("KEYWORD_TYPE_EXPECTED", ["exclusiveMinimum", "boolean"]);
} else if (schema.minimum === undefined) {
report.addError("KEYWORD_DEPENDENCY", ["exclusiveMinimum", "minimum"]);
}
},
maxLength: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.1.1
if (Utils.whatIs(schema.maxLength) !== "integer") {
report.addError("KEYWORD_TYPE_EXPECTED", ["maxLength", "integer"]);
} else if (schema.maxLength < 0) {
report.addError("KEYWORD_MUST_BE", ["maxLength", "greater than, or equal to 0"]);
}
},
minLength: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.2.1
if (Utils.whatIs(schema.minLength) !== "integer") {
report.addError("KEYWORD_TYPE_EXPECTED", ["minLength", "integer"]);
} else if (schema.minLength < 0) {
report.addError("KEYWORD_MUST_BE", ["minLength", "greater than, or equal to 0"]);
}
},
pattern: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.3.1
if (typeof schema.pattern !== "string") {
report.addError("KEYWORD_TYPE_EXPECTED", ["pattern", "string"]);
} else {
try {
RegExp(schema.pattern);
} catch (e) {
report.addError("KEYWORD_PATTERN", ["pattern", schema.pattern]);
}
}
},
additionalItems: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.1.1
var type = Utils.whatIs(schema.additionalItems);
if (type !== "boolean" && type !== "object") {
report.addError("KEYWORD_TYPE_EXPECTED", ["additionalItems", ["boolean", "object"]]);
} else if (type === "object") {
report.path.push("additionalItems");
exports.validateSchema.call(this, report, schema.additionalItems);
report.path.pop();
}
},
items: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.1.1
var type = Utils.whatIs(schema.items);
if (type === "object") {
report.path.push("items");
exports.validateSchema.call(this, report, schema.items);
report.path.pop();
} else if (type === "array") {
var idx = schema.items.length;
while (idx--) {
report.path.push("items");
report.path.push(idx.toString());
exports.validateSchema.call(this, report, schema.items[idx]);
report.path.pop();
report.path.pop();
}
} else {
report.addError("KEYWORD_TYPE_EXPECTED", ["items", ["array", "object"]]);
}
// custom - strict mode
if (this.options.forceAdditional === true && schema.additionalItems === undefined && Array.isArray(schema.items)) {
report.addError("KEYWORD_UNDEFINED_STRICT", ["additionalItems"]);
}
// custome - assume defined false mode
if (this.options.assumeAdditional === true && schema.additionalItems === undefined && Array.isArray(schema.items)) {
schema.additionalItems = false;
}
},
maxItems: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.2.1
if (typeof schema.maxItems !== "number") {
report.addError("KEYWORD_TYPE_EXPECTED", ["maxItems", "integer"]);
} else if (schema.maxItems < 0) {
report.addError("KEYWORD_MUST_BE", ["maxItems", "greater than, or equal to 0"]);
}
},
minItems: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.3.1
if (Utils.whatIs(schema.minItems) !== "integer") {
report.addError("KEYWORD_TYPE_EXPECTED", ["minItems", "integer"]);
} else if (schema.minItems < 0) {
report.addError("KEYWORD_MUST_BE", ["minItems", "greater than, or equal to 0"]);
}
},
uniqueItems: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.4.1
if (typeof schema.uniqueItems !== "boolean") {
report.addError("KEYWORD_TYPE_EXPECTED", ["uniqueItems", "boolean"]);
}
},
maxProperties: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.1.1
if (Utils.whatIs(schema.maxProperties) !== "integer") {
report.addError("KEYWORD_TYPE_EXPECTED", ["maxProperties", "integer"]);
} else if (schema.maxProperties < 0) {
report.addError("KEYWORD_MUST_BE", ["maxProperties", "greater than, or equal to 0"]);
}
},
minProperties: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.2.1
if (Utils.whatIs(schema.minProperties) !== "integer") {
report.addError("KEYWORD_TYPE_EXPECTED", ["minProperties", "integer"]);
} else if (schema.minProperties < 0) {
report.addError("KEYWORD_MUST_BE", ["minProperties", "greater than, or equal to 0"]);
}
},
required: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.3.1
if (Utils.whatIs(schema.required) !== "array") {
report.addError("KEYWORD_TYPE_EXPECTED", ["required", "array"]);
} else if (schema.required.length === 0) {
report.addError("KEYWORD_MUST_BE", ["required", "an array with at least one element"]);
} else {
var idx = schema.required.length;
while (idx--) {
if (typeof schema.required[idx] !== "string") {
report.addError("KEYWORD_VALUE_TYPE", ["required", "string"]);
}
}
if (Utils.isUniqueArray(schema.required) === false) {
report.addError("KEYWORD_MUST_BE", ["required", "an array with unique items"]);
}
}
},
additionalProperties: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.4.1
var type = Utils.whatIs(schema.additionalProperties);
if (type !== "boolean" && type !== "object") {
report.addError("KEYWORD_TYPE_EXPECTED", ["additionalProperties", ["boolean", "object"]]);
} else if (type === "object") {
report.path.push("additionalProperties");
exports.validateSchema.call(this, report, schema.additionalProperties);
report.path.pop();
}
},
properties: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.4.1
if (Utils.whatIs(schema.properties) !== "object") {
report.addError("KEYWORD_TYPE_EXPECTED", ["properties", "object"]);
return;
}
var keys = Object.keys(schema.properties),
idx = keys.length;
while (idx--) {
var key = keys[idx],
val = schema.properties[key];
report.path.push("properties");
report.path.push(key);
exports.validateSchema.call(this, report, val);
report.path.pop();
report.path.pop();
}
// custom - strict mode
if (this.options.forceAdditional === true && schema.additionalProperties === undefined) {
report.addError("KEYWORD_UNDEFINED_STRICT", ["additionalProperties"]);
}
// custome - assume defined false mode
if (this.options.assumeAdditional === true && schema.additionalProperties === undefined) {
schema.additionalProperties = false;
}
// custom - forceProperties
if (this.options.forceProperties === true && keys.length === 0) {
report.addError("CUSTOM_MODE_FORCE_PROPERTIES", ["properties"]);
}
},
patternProperties: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.4.1
if (Utils.whatIs(schema.patternProperties) !== "object") {
report.addError("KEYWORD_TYPE_EXPECTED", ["patternProperties", "object"]);
return;
}
var keys = Object.keys(schema.patternProperties),
idx = keys.length;
while (idx--) {
var key = keys[idx],
val = schema.patternProperties[key];
try {
RegExp(key);
} catch (e) {
report.addError("KEYWORD_PATTERN", ["patternProperties", key]);
}
report.path.push("patternProperties");
report.path.push(key.toString());
exports.validateSchema.call(this, report, val);
report.path.pop();
report.path.pop();
}
// custom - forceProperties
if (this.options.forceProperties === true && keys.length === 0) {
report.addError("CUSTOM_MODE_FORCE_PROPERTIES", ["patternProperties"]);
}
},
dependencies: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.5.1
if (Utils.whatIs(schema.dependencies) !== "object") {
report.addError("KEYWORD_TYPE_EXPECTED", ["dependencies", "object"]);
} else {
var keys = Object.keys(schema.dependencies),
idx = keys.length;
while (idx--) {
var schemaKey = keys[idx],
schemaDependency = schema.dependencies[schemaKey],
type = Utils.whatIs(schemaDependency);
if (type === "object") {
report.path.push("dependencies");
report.path.push(schemaKey);
exports.validateSchema.call(this, report, schemaDependency);
report.path.pop();
report.path.pop();
} else if (type === "array") {
var idx2 = schemaDependency.length;
if (idx2 === 0) {
report.addError("KEYWORD_MUST_BE", ["dependencies", "not empty array"]);
}
while (idx2--) {
if (typeof schemaDependency[idx2] !== "string") {
report.addError("KEYWORD_VALUE_TYPE", ["dependensices", "string"]);
}
}
if (Utils.isUniqueArray(schemaDependency) === false) {
report.addError("KEYWORD_MUST_BE", ["dependencies", "an array with unique items"]);
}
} else {
report.addError("KEYWORD_VALUE_TYPE", ["dependencies", "object or array"]);
}
}
}
},
enum: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.1.1
if (Array.isArray(schema.enum) === false) {
report.addError("KEYWORD_TYPE_EXPECTED", ["enum", "array"]);
} else if (schema.enum.length === 0) {
report.addError("KEYWORD_MUST_BE", ["enum", "an array with at least one element"]);
} else if (Utils.isUniqueArray(schema.enum) === false) {
report.addError("KEYWORD_MUST_BE", ["enum", "an array with unique elements"]);
}
},
type: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.2.1
var primitiveTypes = ["array", "boolean", "integer", "number", "null", "object", "string"],
primitiveTypeStr = primitiveTypes.join(","),
isArray = Array.isArray(schema.type);
if (isArray) {
var idx = schema.type.length;
while (idx--) {
if (primitiveTypes.indexOf(schema.type[idx]) === -1) {
report.addError("KEYWORD_TYPE_EXPECTED", ["type", primitiveTypeStr]);
}
}
if (Utils.isUniqueArray(schema.type) === false) {
report.addError("KEYWORD_MUST_BE", ["type", "an object with unique properties"]);
}
} else if (typeof schema.type === "string") {
if (primitiveTypes.indexOf(schema.type) === -1) {
report.addError("KEYWORD_TYPE_EXPECTED", ["type", primitiveTypeStr]);
}
} else {
report.addError("KEYWORD_TYPE_EXPECTED", ["type", ["string", "array"]]);
}
if (this.options.noEmptyStrings === true) {
if (schema.type === "string" || isArray && schema.type.indexOf("string") !== -1) {
if (schema.minLength === undefined) {
schema.minLength = 1;
}
}
}
if (this.options.noEmptyArrays === true) {
if (schema.type === "array" || isArray && schema.type.indexOf("array") !== -1) {
if (schema.minItems === undefined) {
schema.minItems = 1;
}
}
}
if (this.options.forceProperties === true) {
if (schema.type === "object" || isArray && schema.type.indexOf("object") !== -1) {
if (schema.properties === undefined && schema.patternProperties === undefined) {
report.addError("KEYWORD_UNDEFINED_STRICT", ["properties"]);
}
}
}
if (this.options.forceItems === true) {
if (schema.type === "array" || isArray && schema.type.indexOf("array") !== -1) {
if (schema.items === undefined) {
report.addError("KEYWORD_UNDEFINED_STRICT", ["items"]);
}
}
}
if (this.options.forceMaxLength === true) {
if (schema.type === "string" || isArray && schema.type.indexOf("string") !== -1) {
if (schema.maxLength === undefined && schema.format === undefined && schema.enum === undefined) {
report.addError("KEYWORD_UNDEFINED_STRICT", ["maxLength"]);
}
}
}
},
allOf: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.3.1
if (Array.isArray(schema.allOf) === false) {
report.addError("KEYWORD_TYPE_EXPECTED", ["allOf", "array"]);
} else if (schema.allOf.length === 0) {
report.addError("KEYWORD_MUST_BE", ["allOf", "an array with at least one element"]);
} else {
var idx = schema.allOf.length;
while (idx--) {
report.path.push("allOf");
report.path.push(idx.toString());
exports.validateSchema.call(this, report, schema.allOf[idx]);
report.path.pop();
report.path.pop();
}
}
},
anyOf: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.4.1
if (Array.isArray(schema.anyOf) === false) {
report.addError("KEYWORD_TYPE_EXPECTED", ["anyOf", "array"]);
} else if (schema.anyOf.length === 0) {
report.addError("KEYWORD_MUST_BE", ["anyOf", "an array with at least one element"]);
} else {
var idx = schema.anyOf.length;
while (idx--) {
report.path.push("anyOf");
report.path.push(idx.toString());
exports.validateSchema.call(this, report, schema.anyOf[idx]);
report.path.pop();
report.path.pop();
}
}
},
oneOf: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.5.1
if (Array.isArray(schema.oneOf) === false) {
report.addError("KEYWORD_TYPE_EXPECTED", ["oneOf", "array"]);
} else if (schema.oneOf.length === 0) {
report.addError("KEYWORD_MUST_BE", ["oneOf", "an array with at least one element"]);
} else {
var idx = schema.oneOf.length;
while (idx--) {
report.path.push("oneOf");
report.path.push(idx.toString());
exports.validateSchema.call(this, report, schema.oneOf[idx]);
report.path.pop();
report.path.pop();
}
}
},
not: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.6.1
if (Utils.whatIs(schema.not) !== "object") {
report.addError("KEYWORD_TYPE_EXPECTED", ["not", "object"]);
} else {
report.path.push("not");
exports.validateSchema.call(this, report, schema.not);
report.path.pop();
}
},
definitions: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.7.1
if (Utils.whatIs(schema.definitions) !== "object") {
report.addError("KEYWORD_TYPE_EXPECTED", ["definitions", "object"]);
} else {
var keys = Object.keys(schema.definitions),
idx = keys.length;
while (idx--) {
var key = keys[idx],
val = schema.definitions[key];
report.path.push("definitions");
report.path.push(key);
exports.validateSchema.call(this, report, val);
report.path.pop();
report.path.pop();
}
}
},
format: function (report, schema) {
if (typeof schema.format !== "string") {
report.addError("KEYWORD_TYPE_EXPECTED", ["format", "string"]);
} else {
if (FormatValidators[schema.format] === undefined) {
report.addError("UNKNOWN_FORMAT", [schema.format]);
}
}
},
id: function (report, schema) {
// http://json-schema.org/latest/json-schema-core.html#rfc.section.7.2
if (typeof schema.id !== "string") {
report.addError("KEYWORD_TYPE_EXPECTED", ["id", "string"]);
}
},
title: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1
if (typeof schema.title !== "string") {
report.addError("KEYWORD_TYPE_EXPECTED", ["title", "string"]);
}
},
description: function (report, schema) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1
if (typeof schema.description !== "string") {
report.addError("KEYWORD_TYPE_EXPECTED", ["description", "string"]);
}
},
"default": function (/* report, schema */) {
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.2
// There are no restrictions placed on the value of this keyword.
}
};
var validateArrayOfSchemas = function (report, arr) {
var idx = arr.length;
while (idx--) {
exports.validateSchema.call(this, report, arr[idx]);
}
return report.isValid();
};
exports.validateSchema = function (report, schema) {
// if schema is an array, assume it's an array of schemas
if (Array.isArray(schema)) {
return validateArrayOfSchemas.call(this, report, schema);
}
// do not revalidate schema that has already been validated once
if (schema.__$validated) {
return true;
}
// if $schema is present, this schema should validate against that $schema
var hasParentSchema = schema.$schema && schema.id !== schema.$schema;
if (hasParentSchema) {
if (schema.__$schemaResolved && schema.__$schemaResolved !== schema) {
var subReport = new Report(report);
var valid = JsonValidation.validate.call(this, subReport, schema.__$schemaResolved, schema);
if (valid === false) {
report.addError("PARENT_SCHEMA_VALIDATION_FAILED", null, subReport);
}
} else {
if (this.options.ignoreUnresolvableReferences !== true) {
report.addError("REF_UNRESOLVED", [schema.$schema]);
}
}
}
if (this.options.noTypeless === true) {
// issue #36 - inherit type to anyOf, oneOf, allOf if noTypeless is defined
if (schema.type !== undefined) {
var schemas = [];
if (Array.isArray(schema.anyOf)) { schemas = schemas.concat(schema.anyOf); }
if (Array.isArray(schema.oneOf)) { schemas = schemas.concat(schema.oneOf); }
if (Array.isArray(schema.allOf)) { schemas = schemas.concat(schema.allOf); }
schemas.forEach(function (sch) {
if (!sch.type) { sch.type = schema.type; }
});
}
// end issue #36
if (schema.type === undefined &&
schema.anyOf === undefined &&
schema.oneOf === undefined &&
schema.not === undefined &&
schema.$ref === undefined) {
report.addError("KEYWORD_UNDEFINED_STRICT", ["type"]);
}
}
var keys = Object.keys(schema),
idx = keys.length;
while (idx--) {
var key = keys[idx];
if (key.indexOf("__") === 0) { continue; }
if (SchemaValidators[key] !== undefined) {
SchemaValidators[key].call(this, report, schema);
} else if (!hasParentSchema) {
if (this.options.noExtraKeywords === true) {
report.addError("KEYWORD_UNEXPECTED", [key]);
}
}
}
var isValid = report.isValid();
if (isValid) {
schema.__$validated = true;
}
return isValid;
};
},{"./FormatValidators":3,"./JsonValidation":4,"./Report":6,"./Utils":10}],10:[function(require,module,exports){
"use strict";
exports.whatIs = function (what) {
var to = typeof what;
if (to === "object") {
if (what === null) {
return "null";
}
if (Array.isArray(what)) {
return "array";
}
return "object"; // typeof what === 'object' && what === Object(what) && !Array.isArray(what);
}
if (to === "number") {
if (Number.isFinite(what)) {
if (what % 1 === 0) {
return "integer";
} else {
return "number";
}
}
if (Number.isNaN(what)) {
return "not-a-number";
}
return "unknown-number";
}
return to; // undefined, boolean, string, function
};
exports.areEqual = function areEqual(json1, json2) {
// http://json-schema.org/latest/json-schema-core.html#rfc.section.3.6
// Two JSON values are said to be equal if and only if:
// both are nulls; or
// both are booleans, and have the same value; or
// both are strings, and have the same value; or
// both are numbers, and have the same mathematical value; or
if (json1 === json2) {
return true;
}
var i, len;
// both are arrays, and:
if (Array.isArray(json1) && Array.isArray(json2)) {
// have the same number of items; and
if (json1.length !== json2.length) {
return false;
}
// items at the same index are equal according to this definition; or
len = json1.length;
for (i = 0; i < len; i++) {
if (!areEqual(json1[i], json2[i])) {
return false;
}
}
return true;
}
// both are objects, and:
if (exports.whatIs(json1) === "object" && exports.whatIs(json2) === "object") {
// have the same set of property names; and
var keys1 = Object.keys(json1);
var keys2 = Object.keys(json2);
if (!areEqual(keys1, keys2)) {
return false;
}
// values for a same property name are equal according to this definition.
len = keys1.length;
for (i = 0; i < len; i++) {
if (!areEqual(json1[keys1[i]], json2[keys1[i]])) {
return false;
}
}
return true;
}
return false;
};
exports.isUniqueArray = function (arr, indexes) {
var i, j, l = arr.length;
for (i = 0; i < l; i++) {
for (j = i + 1; j < l; j++) {
if (exports.areEqual(arr[i], arr[j])) {
if (indexes) { indexes.push(i, j); }
return false;
}
}
}
return true;
};
exports.difference = function (bigSet, subSet) {
var arr = [],
idx = bigSet.length;
while (idx--) {
if (subSet.indexOf(bigSet[idx]) === -1) {
arr.push(bigSet[idx]);
}
}
return arr;
};
// NOT a deep version of clone
exports.clone = function (src) {
if (typeof src !== "object" || src === null) { return src; }
var res, idx;
if (Array.isArray(src)) {
res = [];
idx = src.length;
while (idx--) {
res[idx] = src[idx];
}
} else {
res = {};
var keys = Object.keys(src);
idx = keys.length;
while (idx--) {
var key = keys[idx];
res[key] = src[key];
}
}
return res;
};
},{}],"C768cZ":[function(require,module,exports){
"use strict";
require("./Polyfills");
var Report = require("./Report");
var FormatValidators = require("./FormatValidators");
var JsonValidation = require("./JsonValidation");
var SchemaCache = require("./SchemaCache");
var SchemaCompilation = require("./SchemaCompilation");
var SchemaValidation = require("./SchemaValidation");
var Utils = require("./Utils");
/*
default options
*/
var defaultOptions = {
// default timeout for all async tasks
asyncTimeout: 2000,
// force additionalProperties and additionalItems to be defined on "object" and "array" types
forceAdditional: false,
// assume additionalProperties and additionalItems are defined as "false" where appropriate
assumeAdditional: false,
// force items to be defined on "array" types
forceItems: false,
// force maxLength to be defined on "string" types
forceMaxLength: false,
// force properties or patternProperties to be defined on "object" types
forceProperties: false,
// ignore references that cannot be resolved (remote schemas) // TODO: make sure this is only for remote schemas, not local ones
ignoreUnresolvableReferences: false,
// disallow usage of keywords that this validator can't handle
noExtraKeywords: false,
// disallow usage of schema's without "type" defined
noTypeless: false,
// disallow zero length strings in validated objects
noEmptyStrings: false,
// disallow zero length arrays in validated objects
noEmptyArrays: false,
// forces "uri" format to be in fully rfc3986 compliant
strictUris: false,
// turn on some of the above
strictMode: false,
// report error paths as an array of path segments to get to the offending node
reportPathAsArray: false
};
/*
constructor
*/
function ZSchema(options) {
this.cache = {};
// options
if (typeof options === "object") {
var keys = Object.keys(options),
idx = keys.length;
while (idx--) {
var key = keys[idx];
if (defaultOptions[key] === undefined) {
throw new Error("Unexpected option passed to constructor: " + key);
}
}
this.options = options;
} else {
this.options = Utils.clone(defaultOptions);
}
if (this.options.strictMode === true) {
this.options.forceAdditional = true;
this.options.forceItems = true;
this.options.forceMaxLength = true;
this.options.forceProperties = true;
this.options.noExtraKeywords = true;
this.options.noTypeless = true;
this.options.noEmptyStrings = true;
this.options.noEmptyArrays = true;
}
}
/*
instance methods
*/
ZSchema.prototype.compileSchema = function (schema) {
var report = new Report(this.options);
if (typeof schema === "string") {
schema = SchemaCache.getSchemaByUri.call(this, report, schema);
}
SchemaCompilation.compileSchema.call(this, report, schema);
this.lastReport = report;
return report.isValid();
};
ZSchema.prototype.validateSchema = function (schema) {
var report = new Report(this.options);
if (typeof schema === "string") {
schema = SchemaCache.getSchemaByUri.call(this, report, schema);
}
var compiled = SchemaCompilation.compileSchema.call(this, report, schema);
if (compiled) { SchemaValidation.validateSchema.call(this, report, schema); }
this.lastReport = report;
return report.isValid();
};
ZSchema.prototype.validate = function (json, schema, callback) {
var report = new Report(this.options);
if (typeof schema === "string") {
schema = SchemaCache.getSchemaByUri.call(this, report, schema);
}
var compiled = SchemaCompilation.compileSchema.call(this, report, schema);
if (!compiled) {
this.lastReport = report;
return false;
}
var validated = SchemaValidation.validateSchema.call(this, report, schema);
if (!validated) {
this.lastReport = report;
return false;
}
JsonValidation.validate.call(this, report, schema, json);
if (callback) {
report.processAsyncTasks(this.options.asyncTimeout, callback);
return;
} else if (report.asyncTasks.length > 0) {
throw new Error("This validation has async tasks and cannot be done in sync mode, please provide callback argument.");
}
// assign lastReport so errors are retrievable in sync mode
this.lastReport = report;
return report.isValid();
};
ZSchema.prototype.getLastErrors = function () {
return this.lastReport.errors.length > 0 ? this.lastReport.errors : undefined;
};
ZSchema.prototype.getMissingReferences = function () {
var res = [],
idx = this.lastReport.errors.length;
while (idx--) {
var error = this.lastReport.errors[idx];
if (error.code === "UNRESOLVABLE_REFERENCE") {
var reference = error.params[0];
if (res.indexOf(reference) === -1) {
res.push(reference);
}
}
}
return res;
};
ZSchema.prototype.getMissingRemoteReferences = function () {
var missingReferences = this.getMissingReferences(),
missingRemoteReferences = [],
idx = missingReferences.length;
while (idx--) {
var remoteReference = SchemaCache.getRemotePath(missingReferences[idx]);
if (remoteReference && missingRemoteReferences.indexOf(remoteReference) === -1) {
missingRemoteReferences.push(remoteReference);
}
}
return missingRemoteReferences;
};
ZSchema.prototype.setRemoteReference = function (uri, schema) {
if (typeof schema === "string") {
schema = JSON.parse(schema);
}
SchemaCache.cacheSchemaByUri.call(this, uri, schema);
};
/*
static methods
*/
ZSchema.registerFormat = function (formatName, validatorFunction) {
FormatValidators[formatName] = validatorFunction;
};
ZSchema.registerFormatter = function (/* formatterName, formatterFunction */) {
};
module.exports = ZSchema;
},{"./FormatValidators":3,"./JsonValidation":4,"./Polyfills":5,"./Report":6,"./SchemaCache":7,"./SchemaCompilation":8,"./SchemaValidation":9,"./Utils":10}],"ZSchema":[function(require,module,exports){
module.exports=require('C768cZ');
},{}]},{},[2,3,4,5,6,7,8,9,10,"C768cZ"]);
var ZSchema = require("ZSchema");