z-schema 12.0.4 → 12.1.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.
Files changed (176) hide show
  1. package/bin/z-schema +7 -2
  2. package/cjs/index.d.ts +541 -530
  3. package/cjs/index.js +3963 -7740
  4. package/dist/errors.d.mts +64 -0
  5. package/dist/errors.mjs +67 -0
  6. package/dist/format-validators.d.mts +14 -0
  7. package/dist/format-validators.mjs +261 -0
  8. package/dist/index.d.mts +10 -0
  9. package/dist/index.mjs +7 -0
  10. package/dist/json-schema-versions.d.mts +137 -0
  11. package/dist/json-schema-versions.mjs +11 -0
  12. package/dist/json-schema.d.mts +61 -0
  13. package/dist/json-schema.mjs +53 -0
  14. package/dist/json-validation.mjs +441 -0
  15. package/dist/report.d.mts +97 -0
  16. package/dist/report.mjs +194 -0
  17. package/dist/schema-cache.d.mts +23 -0
  18. package/dist/schema-cache.mjs +144 -0
  19. package/dist/schema-compiler.d.mts +23 -0
  20. package/dist/schema-compiler.mjs +265 -0
  21. package/dist/schema-validator.d.mts +15 -0
  22. package/dist/schema-validator.mjs +446 -0
  23. package/dist/schemas/draft-04-schema.mjs +125 -0
  24. package/dist/schemas/draft-06-schema.mjs +126 -0
  25. package/dist/schemas/draft-07-schema.mjs +141 -0
  26. package/dist/schemas/draft-2019-09-meta-applicator.mjs +46 -0
  27. package/dist/schemas/draft-2019-09-meta-content.mjs +15 -0
  28. package/dist/schemas/draft-2019-09-meta-core.mjs +52 -0
  29. package/dist/schemas/draft-2019-09-meta-format.mjs +11 -0
  30. package/dist/schemas/draft-2019-09-meta-meta-data.mjs +31 -0
  31. package/dist/schemas/draft-2019-09-meta-validation.mjs +80 -0
  32. package/dist/schemas/draft-2019-09-schema.mjs +39 -0
  33. package/dist/schemas/draft-2020-12-meta-applicator.mjs +45 -0
  34. package/dist/schemas/draft-2020-12-meta-content.mjs +15 -0
  35. package/dist/schemas/draft-2020-12-meta-core.mjs +46 -0
  36. package/dist/schemas/draft-2020-12-meta-format-annotation.mjs +11 -0
  37. package/dist/schemas/draft-2020-12-meta-format-assertion.mjs +11 -0
  38. package/dist/schemas/draft-2020-12-meta-meta-data.mjs +31 -0
  39. package/dist/schemas/draft-2020-12-meta-unevaluated.mjs +14 -0
  40. package/dist/schemas/draft-2020-12-meta-validation.mjs +80 -0
  41. package/dist/schemas/draft-2020-12-schema.mjs +55 -0
  42. package/dist/utils/array.mjs +54 -0
  43. package/dist/utils/base64.mjs +21 -0
  44. package/dist/utils/clone.mjs +42 -0
  45. package/dist/utils/constants.mjs +16 -0
  46. package/dist/utils/date.mjs +19 -0
  47. package/dist/utils/hostname.mjs +73 -0
  48. package/dist/utils/json.mjs +34 -0
  49. package/dist/utils/properties.mjs +11 -0
  50. package/dist/utils/schema-regex.mjs +49 -0
  51. package/dist/utils/symbols.mjs +5 -0
  52. package/dist/utils/time.mjs +42 -0
  53. package/dist/utils/unicode.mjs +12 -0
  54. package/dist/utils/uri.mjs +12 -0
  55. package/dist/utils/what-is.mjs +23 -0
  56. package/dist/validation/array.mjs +57 -0
  57. package/dist/validation/combinators.mjs +62 -0
  58. package/dist/validation/numeric.mjs +38 -0
  59. package/dist/validation/object.mjs +109 -0
  60. package/dist/validation/ref.mjs +49 -0
  61. package/dist/validation/shared.mjs +97 -0
  62. package/dist/validation/string.mjs +88 -0
  63. package/dist/validation/type.mjs +32 -0
  64. package/dist/z-schema-base.d.mts +85 -0
  65. package/dist/z-schema-base.mjs +230 -0
  66. package/dist/z-schema-options.d.mts +35 -0
  67. package/dist/z-schema-options.mjs +55 -0
  68. package/dist/z-schema-reader.d.mts +6 -0
  69. package/dist/z-schema-reader.mjs +10 -0
  70. package/dist/z-schema-versions.mjs +67 -0
  71. package/dist/z-schema.d.mts +193 -0
  72. package/dist/z-schema.mjs +300 -0
  73. package/package.json +49 -64
  74. package/src/index.ts +3 -3
  75. package/src/schema-compiler.ts +30 -10
  76. package/src/schema-validator.ts +1 -1
  77. package/src/utils/schema-regex.ts +13 -2
  78. package/src/z-schema-base.ts +1 -1
  79. package/src/z-schema-versions.ts +1 -2
  80. package/src/z-schema.ts +0 -1
  81. package/umd/ZSchema.js +5934 -8110
  82. package/umd/ZSchema.min.js +2 -1
  83. package/dist/errors.js +0 -72
  84. package/dist/format-validators.js +0 -392
  85. package/dist/index.js +0 -5
  86. package/dist/json-schema-versions.js +0 -8
  87. package/dist/json-schema.js +0 -84
  88. package/dist/json-validation.js +0 -728
  89. package/dist/package.json +0 -3
  90. package/dist/report.js +0 -265
  91. package/dist/schema-cache.js +0 -211
  92. package/dist/schema-compiler.js +0 -415
  93. package/dist/schema-validator.js +0 -721
  94. package/dist/schemas/draft-04-schema.json +0 -149
  95. package/dist/schemas/draft-06-schema.json +0 -155
  96. package/dist/schemas/draft-07-schema.json +0 -172
  97. package/dist/schemas/draft-2019-09-meta-applicator.json +0 -52
  98. package/dist/schemas/draft-2019-09-meta-content.json +0 -12
  99. package/dist/schemas/draft-2019-09-meta-core.json +0 -53
  100. package/dist/schemas/draft-2019-09-meta-format.json +0 -10
  101. package/dist/schemas/draft-2019-09-meta-meta-data.json +0 -32
  102. package/dist/schemas/draft-2019-09-meta-validation.json +0 -94
  103. package/dist/schemas/draft-2019-09-schema.json +0 -41
  104. package/dist/schemas/draft-2020-12-meta-applicator.json +0 -44
  105. package/dist/schemas/draft-2020-12-meta-content.json +0 -12
  106. package/dist/schemas/draft-2020-12-meta-core.json +0 -47
  107. package/dist/schemas/draft-2020-12-meta-format-annotation.json +0 -10
  108. package/dist/schemas/draft-2020-12-meta-format-assertion.json +0 -10
  109. package/dist/schemas/draft-2020-12-meta-meta-data.json +0 -32
  110. package/dist/schemas/draft-2020-12-meta-unevaluated.json +0 -11
  111. package/dist/schemas/draft-2020-12-meta-validation.json +0 -94
  112. package/dist/schemas/draft-2020-12-schema.json +0 -57
  113. package/dist/types/errors.d.ts +0 -64
  114. package/dist/types/format-validators.d.ts +0 -11
  115. package/dist/types/index.d.ts +0 -14
  116. package/dist/types/json-schema-versions.d.ts +0 -142
  117. package/dist/types/json-schema.d.ts +0 -66
  118. package/dist/types/json-validation.d.ts +0 -6
  119. package/dist/types/report.d.ts +0 -94
  120. package/dist/types/schema-cache.d.ts +0 -27
  121. package/dist/types/schema-compiler.d.ts +0 -31
  122. package/dist/types/schema-validator.d.ts +0 -10
  123. package/dist/types/utils/array.d.ts +0 -9
  124. package/dist/types/utils/base64.d.ts +0 -2
  125. package/dist/types/utils/clone.d.ts +0 -2
  126. package/dist/types/utils/constants.d.ts +0 -19
  127. package/dist/types/utils/date.d.ts +0 -1
  128. package/dist/types/utils/hostname.d.ts +0 -2
  129. package/dist/types/utils/json.d.ts +0 -9
  130. package/dist/types/utils/properties.d.ts +0 -1
  131. package/dist/types/utils/schema-regex.d.ts +0 -10
  132. package/dist/types/utils/symbols.d.ts +0 -2
  133. package/dist/types/utils/time.d.ts +0 -12
  134. package/dist/types/utils/unicode.d.ts +0 -5
  135. package/dist/types/utils/uri.d.ts +0 -4
  136. package/dist/types/utils/what-is.d.ts +0 -4
  137. package/dist/types/validation/array.d.ts +0 -12
  138. package/dist/types/validation/combinators.d.ts +0 -10
  139. package/dist/types/validation/numeric.d.ts +0 -8
  140. package/dist/types/validation/object.d.ts +0 -13
  141. package/dist/types/validation/ref.d.ts +0 -11
  142. package/dist/types/validation/shared.d.ts +0 -26
  143. package/dist/types/validation/string.d.ts +0 -9
  144. package/dist/types/validation/type.d.ts +0 -6
  145. package/dist/types/z-schema-base.d.ts +0 -87
  146. package/dist/types/z-schema-options.d.ts +0 -35
  147. package/dist/types/z-schema-reader.d.ts +0 -4
  148. package/dist/types/z-schema-versions.d.ts +0 -1
  149. package/dist/types/z-schema.d.ts +0 -191
  150. package/dist/utils/array.js +0 -69
  151. package/dist/utils/base64.js +0 -29
  152. package/dist/utils/clone.js +0 -59
  153. package/dist/utils/constants.js +0 -19
  154. package/dist/utils/date.js +0 -21
  155. package/dist/utils/hostname.js +0 -146
  156. package/dist/utils/json.js +0 -70
  157. package/dist/utils/properties.js +0 -10
  158. package/dist/utils/schema-regex.js +0 -52
  159. package/dist/utils/symbols.js +0 -2
  160. package/dist/utils/time.js +0 -50
  161. package/dist/utils/unicode.js +0 -12
  162. package/dist/utils/uri.js +0 -15
  163. package/dist/utils/what-is.js +0 -32
  164. package/dist/validation/array.js +0 -127
  165. package/dist/validation/combinators.js +0 -106
  166. package/dist/validation/numeric.js +0 -97
  167. package/dist/validation/object.js +0 -237
  168. package/dist/validation/ref.js +0 -70
  169. package/dist/validation/shared.js +0 -136
  170. package/dist/validation/string.js +0 -170
  171. package/dist/validation/type.js +0 -55
  172. package/dist/z-schema-base.js +0 -286
  173. package/dist/z-schema-options.js +0 -99
  174. package/dist/z-schema-reader.js +0 -7
  175. package/dist/z-schema-versions.js +0 -110
  176. package/dist/z-schema.js +0 -287
package/dist/package.json DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "type": "module"
3
- }
package/dist/report.js DELETED
@@ -1,265 +0,0 @@
1
- import { Errors, getValidateError } from './errors.js';
2
- import { shallowClone } from './utils/clone.js';
3
- import { MAX_ASYNC_TIMEOUT } from './utils/constants.js';
4
- import { get } from './utils/json.js';
5
- import { jsonSymbol, schemaSymbol } from './utils/symbols.js';
6
- import { isAbsoluteUri } from './utils/uri.js';
7
- import { isObject } from './utils/what-is.js';
8
- const ASYNC_TIMEOUT_POLL_MS = 10;
9
- export class Report {
10
- asyncTasks = [];
11
- commonErrorMessage;
12
- __$recursiveAnchorStack = [];
13
- __$dynamicScopeStack = [];
14
- __validationResultCache = new Map();
15
- errors = [];
16
- json;
17
- path = [];
18
- schemaPath = [];
19
- rootSchema;
20
- parentReport;
21
- options;
22
- reportOptions;
23
- validateOptions = {};
24
- constructor(parentOrOptions, reportOptionsOrValidate, validateOptions) {
25
- this.parentReport = parentOrOptions instanceof Report ? parentOrOptions : undefined;
26
- this.options = parentOrOptions instanceof Report ? parentOrOptions.options : parentOrOptions || {};
27
- if (parentOrOptions instanceof Report) {
28
- // subreport
29
- this.reportOptions = reportOptionsOrValidate || {};
30
- this.validateOptions = validateOptions || parentOrOptions.validateOptions;
31
- this.__$recursiveAnchorStack = [...parentOrOptions.__$recursiveAnchorStack];
32
- this.__$dynamicScopeStack = [...parentOrOptions.__$dynamicScopeStack];
33
- this.__validationResultCache = parentOrOptions.__validationResultCache;
34
- }
35
- else {
36
- // primary
37
- this.reportOptions = {};
38
- this.validateOptions = reportOptionsOrValidate || {};
39
- this.__$recursiveAnchorStack = [];
40
- this.__$dynamicScopeStack = [];
41
- this.__validationResultCache = new Map();
42
- }
43
- }
44
- isValid() {
45
- if (this.asyncTasks.length > 0) {
46
- throw new Error("Async tasks pending, can't answer isValid");
47
- }
48
- return this.errors.length === 0;
49
- }
50
- addAsyncTask(fn, args, asyncTaskResultProcessFn) {
51
- this.asyncTasks.push([fn, args, asyncTaskResultProcessFn]);
52
- }
53
- /**
54
- * Like {@link addAsyncTask}, but automatically saves the current `path` and
55
- * restores it around `processFn`. This eliminates the manual
56
- * path-save/restore boilerplate that every async-aware validator would
57
- * otherwise need.
58
- */
59
- addAsyncTaskWithPath(fn, args, processFn) {
60
- const pathBefore = shallowClone(this.path);
61
- this.asyncTasks.push([
62
- fn,
63
- args,
64
- (result) => {
65
- const backup = this.path;
66
- this.path = pathBefore;
67
- processFn(result);
68
- this.path = backup;
69
- },
70
- ]);
71
- }
72
- getAncestor(id) {
73
- if (!this.parentReport) {
74
- return undefined;
75
- }
76
- if (this.parentReport.getSchemaId() === id) {
77
- return this.parentReport;
78
- }
79
- return this.parentReport.getAncestor(id);
80
- }
81
- processAsyncTasks(timeout, callback) {
82
- const validationTimeout = Math.min(Math.max(timeout || 2000, 0), MAX_ASYNC_TIMEOUT);
83
- const timeoutAt = Date.now() + validationTimeout;
84
- let tasksCount = this.asyncTasks.length;
85
- let timedOut = false;
86
- const finish = () => {
87
- setTimeout(() => {
88
- const valid = this.errors.length === 0;
89
- const err = valid ? undefined : getValidateError({ details: this.errors });
90
- callback(err, valid);
91
- }, 0);
92
- };
93
- const respond = (asyncTaskResultProcessFn) => (asyncTaskResult) => {
94
- if (timedOut) {
95
- return;
96
- }
97
- asyncTaskResultProcessFn(asyncTaskResult);
98
- if (--tasksCount === 0) {
99
- finish();
100
- }
101
- };
102
- // finish if tasks are completed or there are any errors and breaking on first error was requested
103
- if (tasksCount === 0 || (this.errors.length > 0 && this.options.breakOnFirstError)) {
104
- finish();
105
- return;
106
- }
107
- for (let i = 0; i < this.asyncTasks.length; i++) {
108
- const [fn, fnArgs, processFn] = this.asyncTasks[i];
109
- const respondCallback = respond(processFn);
110
- fn(...fnArgs, respondCallback);
111
- }
112
- const checkTimeout = () => {
113
- if (timedOut || tasksCount <= 0) {
114
- return;
115
- }
116
- if (Date.now() >= timeoutAt) {
117
- timedOut = true;
118
- this.addError('ASYNC_TIMEOUT', [tasksCount, validationTimeout]);
119
- callback(getValidateError({ details: this.errors }), false);
120
- return;
121
- }
122
- setTimeout(checkTimeout, ASYNC_TIMEOUT_POLL_MS);
123
- };
124
- setTimeout(checkTimeout, ASYNC_TIMEOUT_POLL_MS);
125
- }
126
- getPath(returnPathAsString) {
127
- let path = [];
128
- if (this.parentReport) {
129
- path = path.concat(this.parentReport.path);
130
- }
131
- path = path.concat(this.path);
132
- if (returnPathAsString !== true) {
133
- // Sanitize the path segments (http://tools.ietf.org/html/rfc6901#section-4)
134
- return ('#/' +
135
- path
136
- .map(function (segment) {
137
- segment = segment.toString();
138
- if (isAbsoluteUri(segment)) {
139
- return 'uri(' + segment + ')';
140
- }
141
- return segment.replace(/~/g, '~0').replace(/\//g, '~1');
142
- })
143
- .join('/'));
144
- }
145
- return path;
146
- }
147
- getSchemaPath() {
148
- let schemaPath = [];
149
- if (this.parentReport) {
150
- schemaPath = schemaPath.concat(this.parentReport.schemaPath);
151
- }
152
- schemaPath = schemaPath.concat(this.schemaPath);
153
- return schemaPath;
154
- }
155
- getSchemaId() {
156
- if (!this.rootSchema) {
157
- return undefined;
158
- }
159
- // get the error path as an array
160
- let path = [];
161
- if (this.parentReport) {
162
- path = path.concat(this.parentReport.path);
163
- }
164
- path = path.concat(this.path);
165
- // try to find id in the error path
166
- while (path.length > 0) {
167
- const obj = get(this.rootSchema, path);
168
- if (obj && obj.id) {
169
- return obj.id;
170
- }
171
- path.pop();
172
- }
173
- // return id of the root
174
- return this.rootSchema.id;
175
- }
176
- hasError(errCode, errParams) {
177
- for (let idx = 0; idx < this.errors.length; idx++) {
178
- if (this.errors[idx].code === errCode) {
179
- // assume match
180
- let match = true;
181
- // check the params too
182
- for (let idx2 = 0; idx2 < this.errors[idx].params.length; idx2++) {
183
- if (this.errors[idx].params[idx2] !== errParams[idx2]) {
184
- match = false;
185
- }
186
- }
187
- // if match, return true
188
- if (match) {
189
- return match;
190
- }
191
- }
192
- }
193
- return false;
194
- }
195
- addError(errCode, errParams, subReports, schema, keyword) {
196
- if (!errCode) {
197
- throw new Error('No errorCode passed into addError()');
198
- }
199
- this.addCustomError(errCode, Errors[errCode], errParams, subReports, schema, keyword);
200
- }
201
- // this returns the root object being validated (the one passed into validator.validate)
202
- getJson() {
203
- if (this.json) {
204
- return this.json;
205
- }
206
- if (this.parentReport) {
207
- return this.parentReport.getJson();
208
- }
209
- return undefined;
210
- }
211
- addCustomError(errorCode, errorMessage, params, subReports, schema, keyword) {
212
- if (typeof this.reportOptions.maxErrors === 'number' && this.errors.length >= this.reportOptions.maxErrors) {
213
- return;
214
- }
215
- if (!errorMessage) {
216
- throw new Error('No errorMessage known for code ' + errorCode);
217
- }
218
- params = params || [];
219
- for (let idx = 0; idx < params.length; idx++) {
220
- const param = params[idx] === null || isObject(params[idx]) ? JSON.stringify(params[idx]) : params[idx];
221
- errorMessage = errorMessage.replace('{' + idx + '}', param.toString());
222
- }
223
- const err = {
224
- code: errorCode,
225
- params: params,
226
- message: errorMessage,
227
- path: this.getPath(this.options.reportPathAsArray),
228
- schemaPath: this.getSchemaPath(),
229
- schemaId: this.getSchemaId(),
230
- keyword: keyword,
231
- };
232
- err[schemaSymbol] = schema;
233
- err[jsonSymbol] = this.getJson();
234
- if (schema && typeof schema === 'string') {
235
- err.description = schema;
236
- }
237
- else if (schema && typeof schema === 'object') {
238
- if (schema.title) {
239
- err.title = schema.title;
240
- }
241
- if (schema.description) {
242
- err.description = schema.description;
243
- }
244
- }
245
- if (subReports != null) {
246
- if (!Array.isArray(subReports)) {
247
- subReports = [subReports];
248
- }
249
- err.inner = [];
250
- for (const subReport of subReports) {
251
- for (const error of subReport.errors) {
252
- err.inner.push(error);
253
- }
254
- }
255
- if (err.inner.length === 0) {
256
- err.inner = undefined;
257
- }
258
- }
259
- // Check if this error code should be excluded
260
- if (Array.isArray(this.validateOptions.excludeErrors) && this.validateOptions.excludeErrors.includes(errorCode)) {
261
- return;
262
- }
263
- this.errors.push(err);
264
- }
265
- }
@@ -1,211 +0,0 @@
1
- import { findId, getId } from './json-schema.js';
2
- import { Report } from './report.js';
3
- import { deepClone } from './utils/clone.js';
4
- import { decodeJSONPointer } from './utils/json.js';
5
- import { getQueryPath, getRemotePath, isAbsoluteUri } from './utils/uri.js';
6
- import { normalizeOptions } from './z-schema-options.js';
7
- // Normalize a URI into a cache key, rejecting keys that could pollute Object.prototype.
8
- function getSafeRemotePath(uri) {
9
- const remotePath = getRemotePath(uri);
10
- if (!remotePath) {
11
- return undefined;
12
- }
13
- if (remotePath === '__proto__' || remotePath === 'constructor' || remotePath === 'prototype') {
14
- return undefined;
15
- }
16
- return remotePath;
17
- }
18
- const getEffectiveId = (schema) => {
19
- let id = getId(schema);
20
- if ((!id || !isAbsoluteUri(id)) && typeof schema.id === 'string' && isAbsoluteUri(schema.id)) {
21
- id = schema.id;
22
- }
23
- return id;
24
- };
25
- /**
26
- * Shared logic for registering a remote reference schema.
27
- * Used by both the static `ZSchema.setRemoteReference()` (global cache) and
28
- * the instance `validator.setRemoteReference()` (instance cache).
29
- */
30
- export function prepareRemoteSchema(schema, uri, validationOptions, maxCloneDepth) {
31
- let _schema;
32
- if (typeof schema === 'string') {
33
- _schema = JSON.parse(schema);
34
- }
35
- else {
36
- _schema = deepClone(schema, maxCloneDepth);
37
- }
38
- if (!_schema.id) {
39
- _schema.id = uri;
40
- }
41
- if (validationOptions) {
42
- _schema.__$validationOptions = normalizeOptions(validationOptions);
43
- }
44
- return _schema;
45
- }
46
- export class SchemaCache {
47
- validator;
48
- static global_cache = Object.create(null);
49
- cache = Object.create(null);
50
- constructor(validator) {
51
- this.validator = validator;
52
- }
53
- static cacheSchemaByUri(uri, schema) {
54
- const remotePath = getSafeRemotePath(uri);
55
- if (remotePath) {
56
- this.global_cache[remotePath] = schema;
57
- }
58
- }
59
- cacheSchemaByUri(uri, schema) {
60
- const remotePath = getSafeRemotePath(uri);
61
- if (remotePath) {
62
- this.cache[remotePath] = schema;
63
- }
64
- }
65
- removeFromCacheByUri(uri) {
66
- const remotePath = getSafeRemotePath(uri);
67
- if (remotePath) {
68
- delete this.cache[remotePath];
69
- }
70
- }
71
- checkCacheForUri(uri) {
72
- const remotePath = getSafeRemotePath(uri);
73
- return remotePath ? this.cache[remotePath] != null : false;
74
- }
75
- getSchema(report, refOrSchema) {
76
- if (Array.isArray(refOrSchema)) {
77
- return refOrSchema.map((i) => this.getSchema(report, i));
78
- }
79
- if (typeof refOrSchema === 'string') {
80
- // ref input
81
- return this.getSchemaByUri(report, refOrSchema);
82
- }
83
- // no caching done on this, but we need to return a clone so we can mutate it
84
- return deepClone(refOrSchema, this.validator.options.maxRecursionDepth);
85
- }
86
- fromCache(path) {
87
- if (path === '__proto__' || path === 'constructor' || path === 'prototype') {
88
- return undefined;
89
- }
90
- let found = this.cache[path];
91
- if (found) {
92
- return found;
93
- }
94
- found = SchemaCache.global_cache[path];
95
- if (found) {
96
- // Clone once from global cache into instance cache so subsequent lookups
97
- // never deep-clone again for the same path on this instance.
98
- const clone = deepClone(found, this.validator.options.maxRecursionDepth);
99
- if (!clone.id || (!isAbsoluteUri(clone.id) && isAbsoluteUri(path))) {
100
- clone.id = path;
101
- }
102
- this.cache[path] = clone;
103
- return clone;
104
- }
105
- return undefined;
106
- }
107
- getSchemaByUri(report, uri, root) {
108
- if (root && !isAbsoluteUri(uri)) {
109
- const rootId = getEffectiveId(root);
110
- if (rootId && isAbsoluteUri(rootId)) {
111
- const hashIndex = rootId.indexOf('#');
112
- const rootBase = hashIndex === -1 ? rootId : rootId.slice(0, hashIndex);
113
- try {
114
- uri = new URL(uri, rootBase).toString();
115
- }
116
- catch {
117
- // keep original uri when URL construction fails
118
- }
119
- }
120
- }
121
- const remotePath = getSafeRemotePath(uri);
122
- const queryPath = getQueryPath(uri);
123
- let result;
124
- let resolvedFromAncestor = false;
125
- if (remotePath) {
126
- const ancestorReport = report.getAncestor(remotePath);
127
- if (ancestorReport?.rootSchema) {
128
- result = ancestorReport.rootSchema;
129
- resolvedFromAncestor = true;
130
- }
131
- }
132
- if (!result && root && remotePath) {
133
- const rootId = getEffectiveId(root);
134
- const rootRemotePath = rootId ? getRemotePath(rootId) : undefined;
135
- if (rootRemotePath && rootRemotePath === remotePath) {
136
- result = root;
137
- }
138
- }
139
- if (!result) {
140
- result = remotePath ? this.fromCache(remotePath) : root;
141
- }
142
- if (result && remotePath && isAbsoluteUri(remotePath) && (!result.id || !isAbsoluteUri(result.id))) {
143
- result.id = remotePath;
144
- }
145
- if (result && remotePath) {
146
- // we need to avoid compiling schemas in a recursive loop
147
- const compileRemote = result !== root && !resolvedFromAncestor;
148
- // now we need to compile and validate resolved schema (in case it's not already)
149
- if (compileRemote) {
150
- report.path.push(remotePath);
151
- let remoteReport;
152
- let usesAncestorReport = false;
153
- const anscestorReport = result.id ? report.getAncestor(result.id) : undefined;
154
- if (anscestorReport) {
155
- remoteReport = anscestorReport;
156
- usesAncestorReport = true;
157
- }
158
- else {
159
- remoteReport = new Report(report);
160
- const noCache = result.id && isAbsoluteUri(result.id) ? false : true;
161
- if (this.validator.sc.compileSchema(remoteReport, result, { noCache })) {
162
- const savedOptions = this.validator.options;
163
- try {
164
- // If custom validationOptions were provided to setRemoteReference(),
165
- // use them instead of the default options
166
- this.validator.options = result.__$validationOptions || this.validator.options;
167
- const parentSchemaUri = typeof result.$schema === 'string' ? getRemotePath(result.$schema) : undefined;
168
- const currentSchemaUri = report.getSchemaId();
169
- const parentSchemaIsCompiling = !!parentSchemaUri &&
170
- parentSchemaUri.length > 0 &&
171
- (currentSchemaUri === parentSchemaUri || !!report.getAncestor(parentSchemaUri));
172
- if (!parentSchemaIsCompiling) {
173
- this.validator.sv.validateSchema(remoteReport, result);
174
- }
175
- }
176
- finally {
177
- this.validator.options = savedOptions;
178
- }
179
- }
180
- }
181
- const remoteReportIsValid = usesAncestorReport ? true : remoteReport.isValid();
182
- if (!remoteReportIsValid) {
183
- report.addError('REMOTE_NOT_VALID', [uri], remoteReport);
184
- }
185
- report.path.pop();
186
- if (!remoteReportIsValid) {
187
- return undefined;
188
- }
189
- }
190
- }
191
- const resourceRoot = result;
192
- if (result && queryPath) {
193
- const parts = queryPath.split('/');
194
- for (let idx = 0, lim = parts.length; result && idx < lim; idx++) {
195
- const key = decodeJSONPointer(parts[idx]);
196
- if (idx === 0) {
197
- // it's an id
198
- result = findId(result, key, remotePath, remotePath, this.validator.options.maxRecursionDepth);
199
- }
200
- else {
201
- // it's a path behind id
202
- result = result[key];
203
- }
204
- }
205
- }
206
- if (result && typeof result === 'object' && resourceRoot && typeof resourceRoot === 'object') {
207
- result.__$resourceRoot = resourceRoot;
208
- }
209
- return result;
210
- }
211
- }