z-schema 7.0.0 → 7.0.6

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.
Files changed (76) hide show
  1. package/README.md +7 -11
  2. package/bin/z-schema +0 -0
  3. package/cjs/index.d.ts +192 -117
  4. package/cjs/index.js +949 -998
  5. package/{src/FormatValidators.ts → dist/format-validators.js} +97 -65
  6. package/dist/index.js +1 -1
  7. package/dist/json-schema.js +40 -0
  8. package/dist/{JsonValidation.js → json-validation.js} +75 -69
  9. package/dist/{Report.js → report.js} +35 -45
  10. package/dist/schema-cache.js +109 -0
  11. package/dist/schema-compiler.js +255 -0
  12. package/dist/{SchemaValidation.js → schema-validator.js} +153 -149
  13. package/dist/types/{Errors.d.ts → errors.d.ts} +2 -0
  14. package/dist/types/format-validators.d.ts +10 -0
  15. package/dist/types/index.d.ts +10 -1
  16. package/dist/types/json-schema.d.ts +50 -0
  17. package/dist/types/json-validation.d.ts +7 -0
  18. package/dist/types/{Report.d.ts → report.d.ts} +22 -23
  19. package/dist/types/schema-cache.d.ts +17 -0
  20. package/dist/types/schema-compiler.d.ts +16 -0
  21. package/dist/types/schema-validator.d.ts +10 -0
  22. package/dist/types/utils/array.d.ts +2 -0
  23. package/dist/types/utils/clone.d.ts +2 -0
  24. package/dist/types/utils/json.d.ts +7 -0
  25. package/dist/types/utils/symbols.d.ts +2 -0
  26. package/dist/types/utils/unicode.d.ts +14 -0
  27. package/dist/types/utils/uri.d.ts +4 -0
  28. package/dist/types/utils/what-is.d.ts +3 -0
  29. package/dist/types/z-schema.d.ts +75 -0
  30. package/dist/utils/array.js +27 -0
  31. package/dist/utils/clone.js +61 -0
  32. package/dist/utils/json.js +59 -0
  33. package/dist/utils/symbols.js +2 -0
  34. package/dist/utils/unicode.js +45 -0
  35. package/dist/utils/uri.js +15 -0
  36. package/dist/utils/what-is.js +29 -0
  37. package/dist/{ZSchema.js → z-schema.js} +66 -77
  38. package/package.json +8 -4
  39. package/src/{Errors.ts → errors.ts} +4 -0
  40. package/src/format-validators.ts +191 -0
  41. package/src/index.ts +12 -1
  42. package/src/json-schema.ts +97 -0
  43. package/src/{JsonValidation.ts → json-validation.ts} +137 -127
  44. package/src/{Report.ts → report.ts} +60 -70
  45. package/src/schema-cache.ts +122 -0
  46. package/src/schema-compiler.ts +300 -0
  47. package/src/{SchemaValidation.ts → schema-validator.ts} +213 -215
  48. package/src/utils/array.ts +29 -0
  49. package/src/utils/clone.ts +63 -0
  50. package/src/utils/json.ts +74 -0
  51. package/src/utils/symbols.ts +3 -0
  52. package/src/utils/unicode.ts +43 -0
  53. package/src/utils/uri.ts +18 -0
  54. package/src/utils/what-is.ts +46 -0
  55. package/src/{ZSchema.ts → z-schema.ts} +108 -113
  56. package/umd/ZSchema.js +949 -998
  57. package/umd/ZSchema.min.js +1 -1
  58. package/dist/FormatValidators.js +0 -136
  59. package/dist/SchemaCache.js +0 -173
  60. package/dist/SchemaCompilation.js +0 -259
  61. package/dist/Utils.js +0 -266
  62. package/dist/types/FormatValidators.d.ts +0 -12
  63. package/dist/types/JsonValidation.d.ts +0 -37
  64. package/dist/types/SchemaCache.d.ts +0 -26
  65. package/dist/types/SchemaCompilation.d.ts +0 -1
  66. package/dist/types/SchemaValidation.d.ts +0 -6
  67. package/dist/types/Utils.d.ts +0 -64
  68. package/dist/types/ZSchema.d.ts +0 -97
  69. package/src/SchemaCache.ts +0 -189
  70. package/src/SchemaCompilation.ts +0 -293
  71. package/src/Utils.ts +0 -286
  72. /package/dist/{Errors.js → errors.js} +0 -0
  73. /package/dist/schemas/{hyper-schema.json → draft-04-hyper-schema.json} +0 -0
  74. /package/dist/schemas/{schema.json → draft-04-schema.json} +0 -0
  75. /package/src/schemas/{hyper-schema.json → draft-04-hyper-schema.json} +0 -0
  76. /package/src/schemas/{schema.json → draft-04-schema.json} +0 -0
@@ -1,293 +0,0 @@
1
- import { Report } from './Report.js';
2
- import { getSchemaByUri, checkCacheForUri, cacheSchemaByUri, removeFromCacheByUri } from './SchemaCache.js';
3
- import * as Utils from './Utils.js';
4
-
5
- function mergeReference(scope, ref) {
6
- if (Utils.isAbsoluteUri(ref)) {
7
- return ref;
8
- }
9
-
10
- let joinedScope = scope.join('');
11
- const isScopeAbsolute = Utils.isAbsoluteUri(joinedScope);
12
- const isScopeRelative = Utils.isRelativeUri(joinedScope);
13
- const isRefRelative = Utils.isRelativeUri(ref);
14
- let toRemove;
15
-
16
- if (isScopeAbsolute && isRefRelative) {
17
- toRemove = joinedScope.match(/\/[^/]*$/);
18
- if (toRemove) {
19
- joinedScope = joinedScope.slice(0, toRemove.index + 1);
20
- }
21
- } else if (isScopeRelative && isRefRelative) {
22
- joinedScope = '';
23
- } else {
24
- toRemove = joinedScope.match(/[^#/]+$/);
25
- if (toRemove) {
26
- joinedScope = joinedScope.slice(0, toRemove.index);
27
- }
28
- }
29
-
30
- let res = joinedScope + ref;
31
- res = res.replace(/##/, '#');
32
- return res;
33
- }
34
-
35
- function collectReferences(obj, results, scope, path) {
36
- results = results || [];
37
- scope = scope || [];
38
- path = path || [];
39
-
40
- if (typeof obj !== 'object' || obj === null) {
41
- return results;
42
- }
43
-
44
- if (typeof obj.id === 'string') {
45
- scope.push(obj.id);
46
- }
47
-
48
- if (typeof obj.$ref === 'string' && typeof obj.__$refResolved === 'undefined') {
49
- results.push({
50
- ref: mergeReference(scope, obj.$ref),
51
- key: '$ref',
52
- obj: obj,
53
- path: path.slice(0),
54
- });
55
- }
56
- if (typeof obj.$schema === 'string' && typeof obj.__$schemaResolved === 'undefined') {
57
- results.push({
58
- ref: mergeReference(scope, obj.$schema),
59
- key: '$schema',
60
- obj: obj,
61
- path: path.slice(0),
62
- });
63
- }
64
-
65
- let idx;
66
- if (Array.isArray(obj)) {
67
- idx = obj.length;
68
- while (idx--) {
69
- path.push(idx.toString());
70
- collectReferences(obj[idx], results, scope, path);
71
- path.pop();
72
- }
73
- } else {
74
- const keys = Object.keys(obj);
75
- idx = keys.length;
76
- while (idx--) {
77
- // do not recurse through resolved references and other z-schema props
78
- if (keys[idx].indexOf('__$') === 0) {
79
- continue;
80
- }
81
- path.push(keys[idx]);
82
- collectReferences(obj[keys[idx]], results, scope, path);
83
- path.pop();
84
- }
85
- }
86
-
87
- if (typeof obj.id === 'string') {
88
- scope.pop();
89
- }
90
-
91
- return results;
92
- }
93
-
94
- const compileArrayOfSchemasLoop = function (mainReport, arr) {
95
- let idx = arr.length,
96
- compiledCount = 0;
97
-
98
- while (idx--) {
99
- // try to compile each schema separately
100
- const report = new Report(mainReport);
101
- const isValid = compileSchema.call(this, report, arr[idx]);
102
- if (isValid) {
103
- compiledCount++;
104
- }
105
-
106
- // copy errors to report
107
- mainReport.errors = mainReport.errors.concat(report.errors);
108
- }
109
-
110
- return compiledCount;
111
- };
112
-
113
- function findId(arr, id) {
114
- let idx = arr.length;
115
- while (idx--) {
116
- if (arr[idx].id === id) {
117
- return arr[idx];
118
- }
119
- }
120
- return null;
121
- }
122
-
123
- const compileArrayOfSchemas = function (report, arr) {
124
- let compiled = 0,
125
- lastLoopCompiled;
126
-
127
- do {
128
- // remove all UNRESOLVABLE_REFERENCE errors before compiling array again
129
- let idx = report.errors.length;
130
- while (idx--) {
131
- if (report.errors[idx].code === 'UNRESOLVABLE_REFERENCE') {
132
- report.errors.splice(idx, 1);
133
- }
134
- }
135
-
136
- // remember how many were compiled in the last loop
137
- lastLoopCompiled = compiled;
138
-
139
- // count how many are compiled now
140
- compiled = compileArrayOfSchemasLoop.call(this, report, arr);
141
-
142
- // fix __$missingReferences if possible
143
- idx = arr.length;
144
- while (idx--) {
145
- const sch = arr[idx];
146
- if (sch.__$missingReferences) {
147
- let idx2 = sch.__$missingReferences.length;
148
- while (idx2--) {
149
- const refObj = sch.__$missingReferences[idx2];
150
- const response = findId(arr, refObj.ref);
151
- if (response) {
152
- // this might create circular references
153
- refObj.obj['__' + refObj.key + 'Resolved'] = response;
154
- // it's resolved now so delete it
155
- sch.__$missingReferences.splice(idx2, 1);
156
- }
157
- }
158
- if (sch.__$missingReferences.length === 0) {
159
- delete sch.__$missingReferences;
160
- }
161
- }
162
- }
163
-
164
- // keep repeating if not all compiled and at least one more was compiled in the last loop
165
- } while (compiled !== arr.length && compiled !== lastLoopCompiled);
166
-
167
- return report.isValid();
168
- };
169
-
170
- export function compileSchema(report, schema) {
171
- report.commonErrorMessage = 'SCHEMA_COMPILATION_FAILED';
172
-
173
- // if schema is a string, assume it's a uri
174
- if (typeof schema === 'string') {
175
- const loadedSchema = getSchemaByUri.call(this, report, schema);
176
- if (!loadedSchema) {
177
- report.addError('SCHEMA_NOT_REACHABLE', [schema]);
178
- return false;
179
- }
180
- schema = loadedSchema;
181
- }
182
-
183
- // if schema is an array, assume it's an array of schemas
184
- if (Array.isArray(schema)) {
185
- return compileArrayOfSchemas.call(this, report, schema);
186
- }
187
-
188
- // if we have an id than it should be cached already (if this instance has compiled it)
189
- if (schema.__$compiled && schema.id && checkCacheForUri.call(this, schema.id) === false) {
190
- schema.__$compiled = undefined;
191
- }
192
-
193
- // do not re-compile schemas
194
- if (schema.__$compiled) {
195
- return true;
196
- }
197
-
198
- if (schema.id && typeof schema.id === 'string') {
199
- // add this to our schemaCache (before compilation in case we have references including id)
200
- cacheSchemaByUri.call(this, schema.id, schema);
201
- }
202
-
203
- // this method can be called recursively, so we need to remember our root
204
- let isRoot = false;
205
- if (!report.rootSchema) {
206
- report.rootSchema = schema;
207
- isRoot = true;
208
- }
209
-
210
- // delete all __$missingReferences from previous compilation attempts
211
- const isValidExceptReferences = report.isValid();
212
- delete schema.__$missingReferences;
213
-
214
- // collect all references that need to be resolved - $ref and $schema
215
- const refs = collectReferences.call(this, schema);
216
- let idx = refs.length;
217
- while (idx--) {
218
- // resolve all the collected references into __xxxResolved pointer
219
- const refObj = refs[idx];
220
- let response = getSchemaByUri.call(this, report, refObj.ref, schema);
221
-
222
- // we can try to use custom schemaReader if available
223
- if (!response) {
224
- const schemaReader = this.getSchemaReader();
225
- if (schemaReader) {
226
- // it's supposed to return a valid schema
227
- const s = schemaReader(refObj.ref);
228
- if (s) {
229
- // it needs to have the id
230
- s.id = refObj.ref;
231
- // try to compile the schema
232
- const subreport = new Report(report);
233
- if (!compileSchema.call(this, subreport, s)) {
234
- // copy errors to report
235
- report.errors = report.errors.concat(subreport.errors);
236
- } else {
237
- response = getSchemaByUri.call(this, report, refObj.ref, schema);
238
- }
239
- }
240
- }
241
- }
242
-
243
- if (!response) {
244
- const hasNotValid = report.hasError('REMOTE_NOT_VALID', [refObj.ref]);
245
- const isAbsolute = Utils.isAbsoluteUri(refObj.ref);
246
- let isDownloaded = false;
247
- const ignoreUnresolvableRemotes = this.options.ignoreUnresolvableReferences === true;
248
-
249
- if (isAbsolute) {
250
- // we shouldn't add UNRESOLVABLE_REFERENCE for schemas we already have downloaded
251
- // and set through setRemoteReference method
252
- isDownloaded = checkCacheForUri.call(this, refObj.ref);
253
- }
254
-
255
- if (hasNotValid) {
256
- // already has REMOTE_NOT_VALID error for this one
257
- } else if (ignoreUnresolvableRemotes && isAbsolute) {
258
- // ignoreUnresolvableRemotes is on and remote isAbsolute
259
- } else if (isDownloaded) {
260
- // remote is downloaded, so no UNRESOLVABLE_REFERENCE
261
- } else {
262
- Array.prototype.push.apply(report.path, refObj.path);
263
- report.addError('UNRESOLVABLE_REFERENCE', [refObj.ref]);
264
- report.path = report.path.slice(0, -refObj.path.length);
265
-
266
- // pusblish unresolved references out
267
- if (isValidExceptReferences) {
268
- schema.__$missingReferences = schema.__$missingReferences || [];
269
- schema.__$missingReferences.push(refObj);
270
- }
271
- }
272
- }
273
- // this might create circular references
274
- refObj.obj['__' + refObj.key + 'Resolved'] = response;
275
- }
276
-
277
- const isValid = report.isValid();
278
- if (isValid) {
279
- schema.__$compiled = true;
280
- } else {
281
- if (schema.id && typeof schema.id === 'string') {
282
- // remove this schema from schemaCache because it failed to compile
283
- removeFromCacheByUri.call(this, schema.id);
284
- }
285
- }
286
-
287
- // we don't need the root pointer anymore
288
- if (isRoot) {
289
- report.rootSchema = undefined;
290
- }
291
-
292
- return isValid;
293
- }
package/src/Utils.ts DELETED
@@ -1,286 +0,0 @@
1
- export const jsonSymbol = Symbol.for('z-schema/json');
2
-
3
- export const schemaSymbol = Symbol.for('z-schema/schema');
4
-
5
- /**
6
- * @param {object} obj
7
- *
8
- * @returns {string[]}
9
- */
10
- export function sortedKeys(obj) {
11
- return Object.keys(obj).sort();
12
- }
13
-
14
- /**
15
- *
16
- * @param {string} uri
17
- *
18
- * @returns {boolean}
19
- */
20
- export function isAbsoluteUri(uri) {
21
- return /^https?:\/\//.test(uri);
22
- }
23
-
24
- /**
25
- *
26
- * @param {string} uri
27
- *
28
- * @returns {boolean}
29
- */
30
- export function isRelativeUri(uri) {
31
- // relative URIs that end with a hash sign, issue #56
32
- return /.+#/.test(uri);
33
- }
34
-
35
- export function whatIs(what) {
36
- const to = typeof what;
37
-
38
- if (to === 'object') {
39
- if (what === null) {
40
- return 'null';
41
- }
42
- if (Array.isArray(what)) {
43
- return 'array';
44
- }
45
- return 'object'; // typeof what === 'object' && what === Object(what) && !Array.isArray(what);
46
- }
47
-
48
- if (to === 'number') {
49
- if (Number.isFinite(what)) {
50
- if (what % 1 === 0) {
51
- return 'integer';
52
- } else {
53
- return 'number';
54
- }
55
- }
56
- if (Number.isNaN(what)) {
57
- return 'not-a-number';
58
- }
59
- return 'unknown-number';
60
- }
61
-
62
- return to; // undefined, boolean, string, function
63
- }
64
-
65
- /**
66
- *
67
- * @param {*} json1
68
- * @param {*} json2
69
- * @param {*} [options]
70
- *
71
- * @returns {boolean}
72
- */
73
- export function areEqual(json1, json2, options?) {
74
- options = options || {};
75
- const caseInsensitiveComparison = options.caseInsensitiveComparison || false;
76
-
77
- // http://json-schema.org/latest/json-schema-core.html#rfc.section.3.6
78
-
79
- // Two JSON values are said to be equal if and only if:
80
- // both are nulls; or
81
- // both are booleans, and have the same value; or
82
- // both are strings, and have the same value; or
83
- // both are numbers, and have the same mathematical value; or
84
- if (json1 === json2) {
85
- return true;
86
- }
87
- if (
88
- caseInsensitiveComparison === true &&
89
- typeof json1 === 'string' &&
90
- typeof json2 === 'string' &&
91
- json1.toUpperCase() === json2.toUpperCase()
92
- ) {
93
- return true;
94
- }
95
-
96
- let i, len;
97
-
98
- // both are arrays, and:
99
- if (Array.isArray(json1) && Array.isArray(json2)) {
100
- // have the same number of items; and
101
- if (json1.length !== json2.length) {
102
- return false;
103
- }
104
- // items at the same index are equal according to this definition; or
105
- len = json1.length;
106
- for (i = 0; i < len; i++) {
107
- if (!areEqual(json1[i], json2[i], { caseInsensitiveComparison: caseInsensitiveComparison })) {
108
- return false;
109
- }
110
- }
111
- return true;
112
- }
113
-
114
- // both are objects, and:
115
- if (whatIs(json1) === 'object' && whatIs(json2) === 'object') {
116
- // have the same set of property names; and
117
- const keys1 = sortedKeys(json1);
118
- const keys2 = sortedKeys(json2);
119
- if (!areEqual(keys1, keys2, { caseInsensitiveComparison: caseInsensitiveComparison })) {
120
- return false;
121
- }
122
- // values for a same property name are equal according to this definition.
123
- len = keys1.length;
124
- for (i = 0; i < len; i++) {
125
- if (!areEqual(json1[keys1[i]], json2[keys1[i]], { caseInsensitiveComparison: caseInsensitiveComparison })) {
126
- return false;
127
- }
128
- }
129
- return true;
130
- }
131
-
132
- return false;
133
- }
134
-
135
- /**
136
- *
137
- * @param {*[]} arr
138
- * @param {number[]} [indexes]
139
- *
140
- * @returns {boolean}
141
- */
142
- export function isUniqueArray(arr, indexes?) {
143
- let i;
144
- let j;
145
- const l = arr.length;
146
- for (i = 0; i < l; i++) {
147
- for (j = i + 1; j < l; j++) {
148
- if (areEqual(arr[i], arr[j])) {
149
- if (indexes) {
150
- indexes.push(i, j);
151
- }
152
- return false;
153
- }
154
- }
155
- }
156
- return true;
157
- }
158
-
159
- /**
160
- *
161
- * @param {*} bigSet
162
- * @param {*} subSet
163
- *
164
- * @returns {*[]}
165
- */
166
- export function difference(bigSet, subSet) {
167
- const arr = [];
168
- let idx = bigSet.length;
169
- while (idx--) {
170
- if (subSet.indexOf(bigSet[idx]) === -1) {
171
- arr.push(bigSet[idx]);
172
- }
173
- }
174
- return arr;
175
- }
176
-
177
- // NOT a deep version of clone
178
- export function clone(src) {
179
- if (typeof src === 'undefined') {
180
- return void 0;
181
- }
182
- if (typeof src !== 'object' || src === null) {
183
- return src;
184
- }
185
- let res, idx;
186
- if (Array.isArray(src)) {
187
- res = [];
188
- idx = src.length;
189
- while (idx--) {
190
- res[idx] = src[idx];
191
- }
192
- } else {
193
- res = {};
194
- const keys = Object.keys(src);
195
- idx = keys.length;
196
- while (idx--) {
197
- const key = keys[idx];
198
- res[key] = src[key];
199
- }
200
- }
201
- return res;
202
- }
203
-
204
- export function cloneDeep(src) {
205
- let vidx = 0;
206
- const visited = new Map();
207
- const cloned = [];
208
- function cloneDeepInner(src) {
209
- if (typeof src !== 'object' || src === null) {
210
- return src;
211
- }
212
-
213
- let res;
214
- let idx;
215
- const cidx = visited.get(src);
216
-
217
- if (cidx !== undefined) {
218
- return cloned[cidx];
219
- }
220
-
221
- visited.set(src, vidx++);
222
- if (Array.isArray(src)) {
223
- res = [];
224
- cloned.push(res);
225
- idx = src.length;
226
- while (idx--) {
227
- res[idx] = cloneDeepInner(src[idx]);
228
- }
229
- } else {
230
- res = {};
231
- cloned.push(res);
232
- const keys = Object.keys(src);
233
- idx = keys.length;
234
- while (idx--) {
235
- const key = keys[idx];
236
- res[key] = cloneDeepInner(src[key]);
237
- }
238
- }
239
- return res;
240
- }
241
- return cloneDeepInner(src);
242
- }
243
-
244
- /*
245
- following function comes from punycode.js library
246
- see: https://github.com/bestiejs/punycode.js
247
- */
248
- /**
249
- * Creates an array containing the numeric code points of each Unicode
250
- * character in the string. While JavaScript uses UCS-2 internally,
251
- * this function will convert a pair of surrogate halves (each of which
252
- * UCS-2 exposes as separate characters) into a single code point,
253
- * matching UTF-16.
254
- * @see `punycode.ucs2.encode`
255
- * @see <https://mathiasbynens.be/notes/javascript-encoding>
256
- * @memberOf punycode.ucs2
257
- * @name decode
258
- * @param {String} string The Unicode input string (UCS-2).
259
- * @returns {Array} The new array of code points.
260
- */
261
- export function ucs2decode(string) {
262
- const output = [];
263
- let counter = 0;
264
- const length = string.length;
265
- let value;
266
- let extra;
267
- while (counter < length) {
268
- value = string.charCodeAt(counter++);
269
- if (value >= 0xd800 && value <= 0xdbff && counter < length) {
270
- // high surrogate, and there is a next character
271
- extra = string.charCodeAt(counter++);
272
- if ((extra & 0xfc00) == 0xdc00) {
273
- // low surrogate
274
- output.push(((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000);
275
- } else {
276
- // unmatched surrogate; only append this code unit, in case the next
277
- // code unit is the high surrogate of a surrogate pair
278
- output.push(value);
279
- counter--;
280
- }
281
- } else {
282
- output.push(value);
283
- }
284
- }
285
- return output;
286
- }
File without changes