z-schema 3.18.4 → 3.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/ZSchema-browser-min.js +1 -1
- package/dist/ZSchema-browser-min.js.map +1 -1
- package/dist/ZSchema-browser-test.js +1439 -671
- package/dist/ZSchema-browser.js +501 -157
- package/package.json +15 -17
- package/src/Errors.js +1 -0
- package/src/JsonValidation.js +6 -1
- package/src/Report.js +2 -1
- package/src/SchemaCache.js +9 -1
- package/src/Utils.js +14 -4
- package/src/ZSchema.js +41 -21
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "z-schema",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.21.0",
|
|
4
4
|
"description": "JSON schema validator",
|
|
5
5
|
"homepage": "https://github.com/zaggino/z-schema",
|
|
6
6
|
"authors": [
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"README.md"
|
|
32
32
|
],
|
|
33
33
|
"scripts": {
|
|
34
|
-
"prepublish": "grunt",
|
|
35
|
-
"test": "
|
|
34
|
+
"prepublish": "npm test && grunt",
|
|
35
|
+
"test": "jasmine-node test/ && grunt lint"
|
|
36
36
|
},
|
|
37
37
|
"testling": {
|
|
38
38
|
"scripts": [
|
|
@@ -60,26 +60,24 @@
|
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"lodash.get": "^4.0.0",
|
|
62
62
|
"lodash.isequal": "^4.0.0",
|
|
63
|
-
"validator": "^
|
|
63
|
+
"validator": "^10.0.0"
|
|
64
64
|
},
|
|
65
65
|
"optionalDependencies": {
|
|
66
66
|
"commander": "^2.7.1"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
|
-
"coveralls": "
|
|
69
|
+
"coveralls": "^3.0.0",
|
|
70
70
|
"grunt": "^1.0.1",
|
|
71
|
-
"grunt-cli": "latest",
|
|
72
71
|
"grunt-browserify": "^5.2.0",
|
|
73
|
-
"grunt-
|
|
74
|
-
"grunt-contrib-
|
|
75
|
-
"grunt-contrib-
|
|
76
|
-
"grunt-contrib-
|
|
77
|
-
"grunt-
|
|
78
|
-
"grunt-
|
|
79
|
-
"grunt-
|
|
80
|
-
"
|
|
81
|
-
"jasmine-
|
|
82
|
-
"
|
|
83
|
-
"remapify": "latest"
|
|
72
|
+
"grunt-cli": "^1.2.0",
|
|
73
|
+
"grunt-contrib-copy": "^1.0.0",
|
|
74
|
+
"grunt-contrib-jasmine": "^1.1.0",
|
|
75
|
+
"grunt-contrib-jshint": "^1.1.0",
|
|
76
|
+
"grunt-contrib-uglify": "^3.1.0",
|
|
77
|
+
"grunt-jscs": "^3.0.1",
|
|
78
|
+
"grunt-lineending": "^1.0.0",
|
|
79
|
+
"jasmine-node": "^1.14.5",
|
|
80
|
+
"jasmine-reporters": "^2.2.1",
|
|
81
|
+
"remapify": "^2.1.0"
|
|
84
82
|
}
|
|
85
83
|
}
|
package/src/Errors.js
CHANGED
|
@@ -5,6 +5,7 @@ module.exports = {
|
|
|
5
5
|
INVALID_TYPE: "Expected type {0} but found type {1}",
|
|
6
6
|
INVALID_FORMAT: "Object didn't pass validation for format {0}: {1}",
|
|
7
7
|
ENUM_MISMATCH: "No enum match for: {0}",
|
|
8
|
+
ENUM_CASE_MISMATCH: "Enum does not match case for: {0}",
|
|
8
9
|
ANY_OF_MISSING: "Data does not match any schemas from 'anyOf'",
|
|
9
10
|
ONE_OF_MISSING: "Data does not match any schemas from 'oneOf'",
|
|
10
11
|
ONE_OF_MULTIPLE: "Data is valid against more than one schema from 'oneOf'",
|
package/src/JsonValidation.js
CHANGED
|
@@ -246,15 +246,20 @@ var JsonValidators = {
|
|
|
246
246
|
enum: function (report, schema, json) {
|
|
247
247
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.1.2
|
|
248
248
|
var match = false,
|
|
249
|
+
caseInsensitiveMatch = false,
|
|
249
250
|
idx = schema.enum.length;
|
|
250
251
|
while (idx--) {
|
|
251
252
|
if (Utils.areEqual(json, schema.enum[idx])) {
|
|
252
253
|
match = true;
|
|
253
254
|
break;
|
|
255
|
+
} else if (Utils.areEqual(json, schema.enum[idx]), { caseInsensitiveComparison: true }) {
|
|
256
|
+
caseInsensitiveMatch = true;
|
|
254
257
|
}
|
|
255
258
|
}
|
|
259
|
+
|
|
256
260
|
if (match === false) {
|
|
257
|
-
|
|
261
|
+
var error = caseInsensitiveMatch && this.options.enumCaseInsensitiveComparison ? "ENUM_CASE_MISMATCH" : "ENUM_MISMATCH";
|
|
262
|
+
report.addError(error, [json], null, schema.description);
|
|
258
263
|
}
|
|
259
264
|
},
|
|
260
265
|
/*
|
package/src/Report.js
CHANGED
|
@@ -57,7 +57,8 @@ Report.prototype.processAsyncTasks = function (timeout, callback) {
|
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
if
|
|
60
|
+
// finish if tasks are completed or there are any errors and breaking on first error was requested
|
|
61
|
+
if (tasksCount === 0 || (this.errors.length > 0 && this.options.breakOnFirstError)) {
|
|
61
62
|
finish();
|
|
62
63
|
return;
|
|
63
64
|
}
|
package/src/SchemaCache.js
CHANGED
|
@@ -121,7 +121,15 @@ exports.getSchemaByUri = function (report, uri, root) {
|
|
|
121
121
|
|
|
122
122
|
var remoteReport = new Report(report);
|
|
123
123
|
if (SchemaCompilation.compileSchema.call(this, remoteReport, result)) {
|
|
124
|
-
|
|
124
|
+
var savedOptions = this.options;
|
|
125
|
+
try {
|
|
126
|
+
// If custom validationOptions were provided to setRemoteReference(),
|
|
127
|
+
// use them instead of the default options
|
|
128
|
+
this.options = result.__$validationOptions || this.options;
|
|
129
|
+
SchemaValidation.validateSchema.call(this, remoteReport, result);
|
|
130
|
+
} finally {
|
|
131
|
+
this.options = savedOptions;
|
|
132
|
+
}
|
|
125
133
|
}
|
|
126
134
|
var remoteReportIsValid = remoteReport.isValid();
|
|
127
135
|
if (!remoteReportIsValid) {
|
package/src/Utils.js
CHANGED
|
@@ -41,7 +41,11 @@ exports.whatIs = function (what) {
|
|
|
41
41
|
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
-
exports.areEqual = function areEqual(json1, json2) {
|
|
44
|
+
exports.areEqual = function areEqual(json1, json2, options) {
|
|
45
|
+
|
|
46
|
+
options = options || {};
|
|
47
|
+
var caseInsensitiveComparison = options.caseInsensitiveComparison || false;
|
|
48
|
+
|
|
45
49
|
// http://json-schema.org/latest/json-schema-core.html#rfc.section.3.6
|
|
46
50
|
|
|
47
51
|
// Two JSON values are said to be equal if and only if:
|
|
@@ -52,6 +56,12 @@ exports.areEqual = function areEqual(json1, json2) {
|
|
|
52
56
|
if (json1 === json2) {
|
|
53
57
|
return true;
|
|
54
58
|
}
|
|
59
|
+
if (
|
|
60
|
+
caseInsensitiveComparison === true &&
|
|
61
|
+
typeof json1 === "string" && typeof json2 === "string" &&
|
|
62
|
+
json1.toUpperCase() === json2.toUpperCase()) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
55
65
|
|
|
56
66
|
var i, len;
|
|
57
67
|
|
|
@@ -64,7 +74,7 @@ exports.areEqual = function areEqual(json1, json2) {
|
|
|
64
74
|
// items at the same index are equal according to this definition; or
|
|
65
75
|
len = json1.length;
|
|
66
76
|
for (i = 0; i < len; i++) {
|
|
67
|
-
if (!areEqual(json1[i], json2[i])) {
|
|
77
|
+
if (!areEqual(json1[i], json2[i], { caseInsensitiveComparison: caseInsensitiveComparison })) {
|
|
68
78
|
return false;
|
|
69
79
|
}
|
|
70
80
|
}
|
|
@@ -76,13 +86,13 @@ exports.areEqual = function areEqual(json1, json2) {
|
|
|
76
86
|
// have the same set of property names; and
|
|
77
87
|
var keys1 = Object.keys(json1);
|
|
78
88
|
var keys2 = Object.keys(json2);
|
|
79
|
-
if (!areEqual(keys1, keys2)) {
|
|
89
|
+
if (!areEqual(keys1, keys2, { caseInsensitiveComparison: caseInsensitiveComparison })) {
|
|
80
90
|
return false;
|
|
81
91
|
}
|
|
82
92
|
// values for a same property name are equal according to this definition.
|
|
83
93
|
len = keys1.length;
|
|
84
94
|
for (i = 0; i < len; i++) {
|
|
85
|
-
if (!areEqual(json1[keys1[i]], json2[keys1[i]])) {
|
|
95
|
+
if (!areEqual(json1[keys1[i]], json2[keys1[i]], { caseInsensitiveComparison: caseInsensitiveComparison })) {
|
|
86
96
|
return false;
|
|
87
97
|
}
|
|
88
98
|
}
|
package/src/ZSchema.js
CHANGED
|
@@ -22,6 +22,8 @@ var defaultOptions = {
|
|
|
22
22
|
forceAdditional: false,
|
|
23
23
|
// assume additionalProperties and additionalItems are defined as "false" where appropriate
|
|
24
24
|
assumeAdditional: false,
|
|
25
|
+
// do case insensitive comparison for enums
|
|
26
|
+
enumCaseInsensitiveComparison: false,
|
|
25
27
|
// force items to be defined on "array" types
|
|
26
28
|
forceItems: false,
|
|
27
29
|
// force minItems to be defined on "array" types
|
|
@@ -60,15 +62,8 @@ var defaultOptions = {
|
|
|
60
62
|
customValidator: null
|
|
61
63
|
};
|
|
62
64
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
*/
|
|
66
|
-
function ZSchema(options) {
|
|
67
|
-
this.cache = {};
|
|
68
|
-
this.referenceCache = [];
|
|
69
|
-
|
|
70
|
-
this.setRemoteReference("http://json-schema.org/draft-04/schema", Draft4Schema);
|
|
71
|
-
this.setRemoteReference("http://json-schema.org/draft-04/hyper-schema", Draft4HyperSchema);
|
|
65
|
+
function normalizeOptions(options) {
|
|
66
|
+
var normalized;
|
|
72
67
|
|
|
73
68
|
// options
|
|
74
69
|
if (typeof options === "object") {
|
|
@@ -94,22 +89,40 @@ function ZSchema(options) {
|
|
|
94
89
|
}
|
|
95
90
|
}
|
|
96
91
|
|
|
97
|
-
|
|
92
|
+
normalized = options;
|
|
98
93
|
} else {
|
|
99
|
-
|
|
94
|
+
normalized = Utils.clone(defaultOptions);
|
|
100
95
|
}
|
|
101
96
|
|
|
102
|
-
if (
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
97
|
+
if (normalized.strictMode === true) {
|
|
98
|
+
normalized.forceAdditional = true;
|
|
99
|
+
normalized.forceItems = true;
|
|
100
|
+
normalized.forceMaxLength = true;
|
|
101
|
+
normalized.forceProperties = true;
|
|
102
|
+
normalized.noExtraKeywords = true;
|
|
103
|
+
normalized.noTypeless = true;
|
|
104
|
+
normalized.noEmptyStrings = true;
|
|
105
|
+
normalized.noEmptyArrays = true;
|
|
111
106
|
}
|
|
112
107
|
|
|
108
|
+
return normalized;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/*
|
|
112
|
+
constructor
|
|
113
|
+
*/
|
|
114
|
+
function ZSchema(options) {
|
|
115
|
+
this.cache = {};
|
|
116
|
+
this.referenceCache = [];
|
|
117
|
+
this.validateOptions = {};
|
|
118
|
+
|
|
119
|
+
this.options = normalizeOptions(options);
|
|
120
|
+
|
|
121
|
+
// Disable strict validation for the built-in schemas
|
|
122
|
+
var metaschemaOptions = normalizeOptions({ });
|
|
123
|
+
|
|
124
|
+
this.setRemoteReference("http://json-schema.org/draft-04/schema", Draft4Schema, metaschemaOptions);
|
|
125
|
+
this.setRemoteReference("http://json-schema.org/draft-04/hyper-schema", Draft4HyperSchema, metaschemaOptions);
|
|
113
126
|
}
|
|
114
127
|
|
|
115
128
|
/*
|
|
@@ -148,6 +161,8 @@ ZSchema.prototype.validate = function (json, schema, options, callback) {
|
|
|
148
161
|
}
|
|
149
162
|
if (!options) { options = {}; }
|
|
150
163
|
|
|
164
|
+
this.validateOptions = options;
|
|
165
|
+
|
|
151
166
|
var whatIs = Utils.whatIs(schema);
|
|
152
167
|
if (whatIs !== "string" && whatIs !== "object") {
|
|
153
168
|
var e = new Error("Invalid .validate call - schema must be an string or object but " + whatIs + " was passed!");
|
|
@@ -257,12 +272,17 @@ ZSchema.prototype.getMissingRemoteReferences = function () {
|
|
|
257
272
|
}
|
|
258
273
|
return missingRemoteReferences;
|
|
259
274
|
};
|
|
260
|
-
ZSchema.prototype.setRemoteReference = function (uri, schema) {
|
|
275
|
+
ZSchema.prototype.setRemoteReference = function (uri, schema, validationOptions) {
|
|
261
276
|
if (typeof schema === "string") {
|
|
262
277
|
schema = JSON.parse(schema);
|
|
263
278
|
} else {
|
|
264
279
|
schema = Utils.cloneDeep(schema);
|
|
265
280
|
}
|
|
281
|
+
|
|
282
|
+
if (validationOptions) {
|
|
283
|
+
schema.__$validationOptions = normalizeOptions(validationOptions);
|
|
284
|
+
}
|
|
285
|
+
|
|
266
286
|
SchemaCache.cacheSchemaByUri.call(this, uri, schema);
|
|
267
287
|
};
|
|
268
288
|
ZSchema.prototype.getResolvedSchema = function (schema) {
|