z-schema 6.0.1 → 7.0.0-beta.1
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 +154 -137
- package/bin/z-schema +128 -124
- package/dist/Errors.js +50 -0
- package/dist/FormatValidators.js +136 -0
- package/{src → dist}/JsonValidation.js +186 -212
- package/dist/Report.js +220 -0
- package/{src → dist}/SchemaCache.js +67 -82
- package/{src → dist}/SchemaCompilation.js +89 -129
- package/dist/SchemaValidation.js +631 -0
- package/{src → dist}/Utils.js +96 -104
- package/dist/ZSchema-umd-min.js +1 -0
- package/dist/ZSchema-umd.js +13791 -0
- package/dist/ZSchema.cjs +13785 -0
- package/dist/ZSchema.js +366 -0
- package/dist/schemas/hyper-schema.json +156 -0
- package/dist/schemas/schema.json +151 -0
- package/dist/types/Errors.d.ts +44 -0
- package/dist/types/FormatValidators.d.ts +12 -0
- package/dist/types/JsonValidation.d.ts +37 -0
- package/dist/types/Report.d.ts +87 -0
- package/dist/types/SchemaCache.d.ts +26 -0
- package/dist/types/SchemaCompilation.d.ts +1 -0
- package/dist/types/SchemaValidation.d.ts +6 -0
- package/dist/types/Utils.d.ts +64 -0
- package/dist/types/ZSchema.d.ts +97 -0
- package/package.json +54 -43
- package/src/Errors.ts +56 -0
- package/src/FormatValidators.ts +136 -0
- package/src/JsonValidation.ts +624 -0
- package/src/Report.ts +337 -0
- package/src/SchemaCache.ts +189 -0
- package/src/SchemaCompilation.ts +293 -0
- package/src/SchemaValidation.ts +629 -0
- package/src/Utils.ts +286 -0
- package/src/ZSchema.ts +469 -0
- package/src/schemas/_ +0 -0
- package/dist/ZSchema-browser-min.js +0 -2
- package/dist/ZSchema-browser-min.js.map +0 -1
- package/dist/ZSchema-browser-test.js +0 -30633
- package/dist/ZSchema-browser.js +0 -13429
- package/index.d.ts +0 -175
- package/src/Errors.js +0 -60
- package/src/FormatValidators.js +0 -129
- package/src/Polyfills.js +0 -16
- package/src/Report.js +0 -299
- package/src/SchemaValidation.js +0 -619
- package/src/ZSchema.js +0 -409
|
@@ -1,70 +1,61 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var SchemaCache = require("./SchemaCache");
|
|
5
|
-
var Utils = require("./Utils");
|
|
6
|
-
|
|
1
|
+
import { Report } from './Report.js';
|
|
2
|
+
import { getSchemaByUri, checkCacheForUri, cacheSchemaByUri, removeFromCacheByUri } from './SchemaCache.js';
|
|
3
|
+
import * as Utils from './Utils.js';
|
|
7
4
|
function mergeReference(scope, ref) {
|
|
8
5
|
if (Utils.isAbsoluteUri(ref)) {
|
|
9
6
|
return ref;
|
|
10
7
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
toRemove;
|
|
17
|
-
|
|
8
|
+
let joinedScope = scope.join('');
|
|
9
|
+
const isScopeAbsolute = Utils.isAbsoluteUri(joinedScope);
|
|
10
|
+
const isScopeRelative = Utils.isRelativeUri(joinedScope);
|
|
11
|
+
const isRefRelative = Utils.isRelativeUri(ref);
|
|
12
|
+
let toRemove;
|
|
18
13
|
if (isScopeAbsolute && isRefRelative) {
|
|
19
|
-
toRemove = joinedScope.match(/\/[
|
|
14
|
+
toRemove = joinedScope.match(/\/[^/]*$/);
|
|
20
15
|
if (toRemove) {
|
|
21
16
|
joinedScope = joinedScope.slice(0, toRemove.index + 1);
|
|
22
17
|
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
}
|
|
19
|
+
else if (isScopeRelative && isRefRelative) {
|
|
20
|
+
joinedScope = '';
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
26
23
|
toRemove = joinedScope.match(/[^#/]+$/);
|
|
27
24
|
if (toRemove) {
|
|
28
25
|
joinedScope = joinedScope.slice(0, toRemove.index);
|
|
29
26
|
}
|
|
30
27
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
res = res.replace(/##/, "#");
|
|
28
|
+
let res = joinedScope + ref;
|
|
29
|
+
res = res.replace(/##/, '#');
|
|
34
30
|
return res;
|
|
35
31
|
}
|
|
36
|
-
|
|
37
32
|
function collectReferences(obj, results, scope, path) {
|
|
38
33
|
results = results || [];
|
|
39
34
|
scope = scope || [];
|
|
40
35
|
path = path || [];
|
|
41
|
-
|
|
42
|
-
if (typeof obj !== "object" || obj === null) {
|
|
36
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
43
37
|
return results;
|
|
44
38
|
}
|
|
45
|
-
|
|
46
|
-
if (typeof obj.id === "string") {
|
|
39
|
+
if (typeof obj.id === 'string') {
|
|
47
40
|
scope.push(obj.id);
|
|
48
41
|
}
|
|
49
|
-
|
|
50
|
-
if (typeof obj.$ref === "string" && typeof obj.__$refResolved === "undefined") {
|
|
42
|
+
if (typeof obj.$ref === 'string' && typeof obj.__$refResolved === 'undefined') {
|
|
51
43
|
results.push({
|
|
52
44
|
ref: mergeReference(scope, obj.$ref),
|
|
53
|
-
key:
|
|
45
|
+
key: '$ref',
|
|
54
46
|
obj: obj,
|
|
55
|
-
path: path.slice(0)
|
|
47
|
+
path: path.slice(0),
|
|
56
48
|
});
|
|
57
49
|
}
|
|
58
|
-
if (typeof obj.$schema ===
|
|
50
|
+
if (typeof obj.$schema === 'string' && typeof obj.__$schemaResolved === 'undefined') {
|
|
59
51
|
results.push({
|
|
60
52
|
ref: mergeReference(scope, obj.$schema),
|
|
61
|
-
key:
|
|
53
|
+
key: '$schema',
|
|
62
54
|
obj: obj,
|
|
63
|
-
path: path.slice(0)
|
|
55
|
+
path: path.slice(0),
|
|
64
56
|
});
|
|
65
57
|
}
|
|
66
|
-
|
|
67
|
-
var idx;
|
|
58
|
+
let idx;
|
|
68
59
|
if (Array.isArray(obj)) {
|
|
69
60
|
idx = obj.length;
|
|
70
61
|
while (idx--) {
|
|
@@ -72,46 +63,41 @@ function collectReferences(obj, results, scope, path) {
|
|
|
72
63
|
collectReferences(obj[idx], results, scope, path);
|
|
73
64
|
path.pop();
|
|
74
65
|
}
|
|
75
|
-
}
|
|
76
|
-
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
const keys = Object.keys(obj);
|
|
77
69
|
idx = keys.length;
|
|
78
70
|
while (idx--) {
|
|
79
71
|
// do not recurse through resolved references and other z-schema props
|
|
80
|
-
if (keys[idx].indexOf(
|
|
72
|
+
if (keys[idx].indexOf('__$') === 0) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
81
75
|
path.push(keys[idx]);
|
|
82
76
|
collectReferences(obj[keys[idx]], results, scope, path);
|
|
83
77
|
path.pop();
|
|
84
78
|
}
|
|
85
79
|
}
|
|
86
|
-
|
|
87
|
-
if (typeof obj.id === "string") {
|
|
80
|
+
if (typeof obj.id === 'string') {
|
|
88
81
|
scope.pop();
|
|
89
82
|
}
|
|
90
|
-
|
|
91
83
|
return results;
|
|
92
84
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
var idx = arr.length,
|
|
96
|
-
compiledCount = 0;
|
|
97
|
-
|
|
85
|
+
const compileArrayOfSchemasLoop = function (mainReport, arr) {
|
|
86
|
+
let idx = arr.length, compiledCount = 0;
|
|
98
87
|
while (idx--) {
|
|
99
|
-
|
|
100
88
|
// try to compile each schema separately
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if (isValid) {
|
|
104
|
-
|
|
89
|
+
const report = new Report(mainReport);
|
|
90
|
+
const isValid = compileSchema.call(this, report, arr[idx]);
|
|
91
|
+
if (isValid) {
|
|
92
|
+
compiledCount++;
|
|
93
|
+
}
|
|
105
94
|
// copy errors to report
|
|
106
95
|
mainReport.errors = mainReport.errors.concat(report.errors);
|
|
107
|
-
|
|
108
96
|
}
|
|
109
|
-
|
|
110
97
|
return compiledCount;
|
|
111
98
|
};
|
|
112
|
-
|
|
113
99
|
function findId(arr, id) {
|
|
114
|
-
|
|
100
|
+
let idx = arr.length;
|
|
115
101
|
while (idx--) {
|
|
116
102
|
if (arr[idx].id === id) {
|
|
117
103
|
return arr[idx];
|
|
@@ -119,40 +105,32 @@ function findId(arr, id) {
|
|
|
119
105
|
}
|
|
120
106
|
return null;
|
|
121
107
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
var compiled = 0,
|
|
126
|
-
lastLoopCompiled;
|
|
127
|
-
|
|
108
|
+
const compileArrayOfSchemas = function (report, arr) {
|
|
109
|
+
let compiled = 0, lastLoopCompiled;
|
|
128
110
|
do {
|
|
129
|
-
|
|
130
111
|
// remove all UNRESOLVABLE_REFERENCE errors before compiling array again
|
|
131
|
-
|
|
112
|
+
let idx = report.errors.length;
|
|
132
113
|
while (idx--) {
|
|
133
|
-
if (report.errors[idx].code ===
|
|
114
|
+
if (report.errors[idx].code === 'UNRESOLVABLE_REFERENCE') {
|
|
134
115
|
report.errors.splice(idx, 1);
|
|
135
116
|
}
|
|
136
117
|
}
|
|
137
|
-
|
|
138
118
|
// remember how many were compiled in the last loop
|
|
139
119
|
lastLoopCompiled = compiled;
|
|
140
|
-
|
|
141
120
|
// count how many are compiled now
|
|
142
121
|
compiled = compileArrayOfSchemasLoop.call(this, report, arr);
|
|
143
|
-
|
|
144
122
|
// fix __$missingReferences if possible
|
|
145
123
|
idx = arr.length;
|
|
146
124
|
while (idx--) {
|
|
147
|
-
|
|
125
|
+
const sch = arr[idx];
|
|
148
126
|
if (sch.__$missingReferences) {
|
|
149
|
-
|
|
127
|
+
let idx2 = sch.__$missingReferences.length;
|
|
150
128
|
while (idx2--) {
|
|
151
|
-
|
|
152
|
-
|
|
129
|
+
const refObj = sch.__$missingReferences[idx2];
|
|
130
|
+
const response = findId(arr, refObj.ref);
|
|
153
131
|
if (response) {
|
|
154
132
|
// this might create circular references
|
|
155
|
-
refObj.obj[
|
|
133
|
+
refObj.obj['__' + refObj.key + 'Resolved'] = response;
|
|
156
134
|
// it's resolved now so delete it
|
|
157
135
|
sch.__$missingReferences.splice(idx2, 1);
|
|
158
136
|
}
|
|
@@ -162,112 +140,97 @@ var compileArrayOfSchemas = function (report, arr) {
|
|
|
162
140
|
}
|
|
163
141
|
}
|
|
164
142
|
}
|
|
165
|
-
|
|
166
143
|
// keep repeating if not all compiled and at least one more was compiled in the last loop
|
|
167
144
|
} while (compiled !== arr.length && compiled !== lastLoopCompiled);
|
|
168
|
-
|
|
169
145
|
return report.isValid();
|
|
170
|
-
|
|
171
146
|
};
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
report.commonErrorMessage = "SCHEMA_COMPILATION_FAILED";
|
|
176
|
-
|
|
147
|
+
export function compileSchema(report, schema) {
|
|
148
|
+
report.commonErrorMessage = 'SCHEMA_COMPILATION_FAILED';
|
|
177
149
|
// if schema is a string, assume it's a uri
|
|
178
|
-
if (typeof schema ===
|
|
179
|
-
|
|
150
|
+
if (typeof schema === 'string') {
|
|
151
|
+
const loadedSchema = getSchemaByUri.call(this, report, schema);
|
|
180
152
|
if (!loadedSchema) {
|
|
181
|
-
report.addError(
|
|
153
|
+
report.addError('SCHEMA_NOT_REACHABLE', [schema]);
|
|
182
154
|
return false;
|
|
183
155
|
}
|
|
184
156
|
schema = loadedSchema;
|
|
185
157
|
}
|
|
186
|
-
|
|
187
158
|
// if schema is an array, assume it's an array of schemas
|
|
188
159
|
if (Array.isArray(schema)) {
|
|
189
160
|
return compileArrayOfSchemas.call(this, report, schema);
|
|
190
161
|
}
|
|
191
|
-
|
|
192
162
|
// if we have an id than it should be cached already (if this instance has compiled it)
|
|
193
|
-
if (schema.__$compiled && schema.id &&
|
|
163
|
+
if (schema.__$compiled && schema.id && checkCacheForUri.call(this, schema.id) === false) {
|
|
194
164
|
schema.__$compiled = undefined;
|
|
195
165
|
}
|
|
196
|
-
|
|
197
166
|
// do not re-compile schemas
|
|
198
167
|
if (schema.__$compiled) {
|
|
199
168
|
return true;
|
|
200
169
|
}
|
|
201
|
-
|
|
202
|
-
if (schema.id && typeof schema.id === "string") {
|
|
170
|
+
if (schema.id && typeof schema.id === 'string') {
|
|
203
171
|
// add this to our schemaCache (before compilation in case we have references including id)
|
|
204
|
-
|
|
172
|
+
cacheSchemaByUri.call(this, schema.id, schema);
|
|
205
173
|
}
|
|
206
|
-
|
|
207
174
|
// this method can be called recursively, so we need to remember our root
|
|
208
|
-
|
|
175
|
+
let isRoot = false;
|
|
209
176
|
if (!report.rootSchema) {
|
|
210
177
|
report.rootSchema = schema;
|
|
211
178
|
isRoot = true;
|
|
212
179
|
}
|
|
213
|
-
|
|
214
180
|
// delete all __$missingReferences from previous compilation attempts
|
|
215
|
-
|
|
181
|
+
const isValidExceptReferences = report.isValid();
|
|
216
182
|
delete schema.__$missingReferences;
|
|
217
|
-
|
|
218
183
|
// collect all references that need to be resolved - $ref and $schema
|
|
219
|
-
|
|
220
|
-
|
|
184
|
+
const refs = collectReferences.call(this, schema);
|
|
185
|
+
let idx = refs.length;
|
|
221
186
|
while (idx--) {
|
|
222
187
|
// resolve all the collected references into __xxxResolved pointer
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
188
|
+
const refObj = refs[idx];
|
|
189
|
+
let response = getSchemaByUri.call(this, report, refObj.ref, schema);
|
|
226
190
|
// we can try to use custom schemaReader if available
|
|
227
191
|
if (!response) {
|
|
228
|
-
|
|
192
|
+
const schemaReader = this.getSchemaReader();
|
|
229
193
|
if (schemaReader) {
|
|
230
194
|
// it's supposed to return a valid schema
|
|
231
|
-
|
|
195
|
+
const s = schemaReader(refObj.ref);
|
|
232
196
|
if (s) {
|
|
233
197
|
// it needs to have the id
|
|
234
198
|
s.id = refObj.ref;
|
|
235
199
|
// try to compile the schema
|
|
236
|
-
|
|
237
|
-
if (!
|
|
200
|
+
const subreport = new Report(report);
|
|
201
|
+
if (!compileSchema.call(this, subreport, s)) {
|
|
238
202
|
// copy errors to report
|
|
239
203
|
report.errors = report.errors.concat(subreport.errors);
|
|
240
|
-
}
|
|
241
|
-
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
response = getSchemaByUri.call(this, report, refObj.ref, schema);
|
|
242
207
|
}
|
|
243
208
|
}
|
|
244
209
|
}
|
|
245
210
|
}
|
|
246
|
-
|
|
247
211
|
if (!response) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
var ignoreUnresolvableRemotes = this.options.ignoreUnresolvableReferences === true;
|
|
253
|
-
|
|
212
|
+
const hasNotValid = report.hasError('REMOTE_NOT_VALID', [refObj.ref]);
|
|
213
|
+
const isAbsolute = Utils.isAbsoluteUri(refObj.ref);
|
|
214
|
+
let isDownloaded = false;
|
|
215
|
+
const ignoreUnresolvableRemotes = this.options.ignoreUnresolvableReferences === true;
|
|
254
216
|
if (isAbsolute) {
|
|
255
217
|
// we shouldn't add UNRESOLVABLE_REFERENCE for schemas we already have downloaded
|
|
256
218
|
// and set through setRemoteReference method
|
|
257
|
-
isDownloaded =
|
|
219
|
+
isDownloaded = checkCacheForUri.call(this, refObj.ref);
|
|
258
220
|
}
|
|
259
|
-
|
|
260
221
|
if (hasNotValid) {
|
|
261
222
|
// already has REMOTE_NOT_VALID error for this one
|
|
262
|
-
}
|
|
223
|
+
}
|
|
224
|
+
else if (ignoreUnresolvableRemotes && isAbsolute) {
|
|
263
225
|
// ignoreUnresolvableRemotes is on and remote isAbsolute
|
|
264
|
-
}
|
|
226
|
+
}
|
|
227
|
+
else if (isDownloaded) {
|
|
265
228
|
// remote is downloaded, so no UNRESOLVABLE_REFERENCE
|
|
266
|
-
}
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
267
231
|
Array.prototype.push.apply(report.path, refObj.path);
|
|
268
|
-
report.addError(
|
|
232
|
+
report.addError('UNRESOLVABLE_REFERENCE', [refObj.ref]);
|
|
269
233
|
report.path = report.path.slice(0, -refObj.path.length);
|
|
270
|
-
|
|
271
234
|
// pusblish unresolved references out
|
|
272
235
|
if (isValidExceptReferences) {
|
|
273
236
|
schema.__$missingReferences = schema.__$missingReferences || [];
|
|
@@ -276,24 +239,21 @@ exports.compileSchema = function (report, schema) {
|
|
|
276
239
|
}
|
|
277
240
|
}
|
|
278
241
|
// this might create circular references
|
|
279
|
-
refObj.obj[
|
|
242
|
+
refObj.obj['__' + refObj.key + 'Resolved'] = response;
|
|
280
243
|
}
|
|
281
|
-
|
|
282
|
-
var isValid = report.isValid();
|
|
244
|
+
const isValid = report.isValid();
|
|
283
245
|
if (isValid) {
|
|
284
246
|
schema.__$compiled = true;
|
|
285
|
-
}
|
|
286
|
-
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
if (schema.id && typeof schema.id === 'string') {
|
|
287
250
|
// remove this schema from schemaCache because it failed to compile
|
|
288
|
-
|
|
251
|
+
removeFromCacheByUri.call(this, schema.id);
|
|
289
252
|
}
|
|
290
253
|
}
|
|
291
|
-
|
|
292
254
|
// we don't need the root pointer anymore
|
|
293
255
|
if (isRoot) {
|
|
294
256
|
report.rootSchema = undefined;
|
|
295
257
|
}
|
|
296
|
-
|
|
297
258
|
return isValid;
|
|
298
|
-
|
|
299
|
-
};
|
|
259
|
+
}
|