schema-shield 1.0.0 → 1.0.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 +38 -12
- package/dist/formats.d.ts.map +1 -1
- package/dist/index.d.ts +14 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1445 -447
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +1445 -447
- package/dist/keywords/array-keywords.d.ts.map +1 -1
- package/dist/keywords/object-keywords.d.ts.map +1 -1
- package/dist/keywords/other-keywords.d.ts.map +1 -1
- package/dist/keywords/string-keywords.d.ts.map +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/deep-freeze.d.ts +5 -0
- package/dist/utils/deep-freeze.d.ts.map +1 -0
- package/dist/utils/has-changed.d.ts +2 -0
- package/dist/utils/has-changed.d.ts.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/{utils.d.ts → utils/main-utils.d.ts} +3 -6
- package/dist/utils/main-utils.d.ts.map +1 -0
- package/dist/utils/pattern-matcher.d.ts +3 -0
- package/dist/utils/pattern-matcher.d.ts.map +1 -0
- package/lib/formats.ts +402 -84
- package/lib/index.ts +494 -46
- package/lib/keywords/array-keywords.ts +215 -21
- package/lib/keywords/number-keywords.ts +1 -1
- package/lib/keywords/object-keywords.ts +218 -113
- package/lib/keywords/other-keywords.ts +229 -76
- package/lib/keywords/string-keywords.ts +97 -7
- package/lib/types.ts +4 -5
- package/lib/utils/deep-freeze.ts +208 -0
- package/lib/utils/has-changed.ts +51 -0
- package/lib/utils/index.ts +4 -0
- package/lib/utils/main-utils.ts +190 -0
- package/lib/utils/pattern-matcher.ts +66 -0
- package/package.json +1 -1
- package/dist/utils.d.ts.map +0 -1
- package/lib/utils.ts +0 -362
package/dist/index.js
CHANGED
|
@@ -21,11 +21,11 @@ var lib_exports = {};
|
|
|
21
21
|
__export(lib_exports, {
|
|
22
22
|
SchemaShield: () => SchemaShield,
|
|
23
23
|
ValidationError: () => ValidationError,
|
|
24
|
-
deepClone: () =>
|
|
24
|
+
deepClone: () => deepCloneUnfreeze
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(lib_exports);
|
|
27
27
|
|
|
28
|
-
// lib/utils.ts
|
|
28
|
+
// lib/utils/main-utils.ts
|
|
29
29
|
var ValidationError = class extends Error {
|
|
30
30
|
message;
|
|
31
31
|
item;
|
|
@@ -100,158 +100,8 @@ function getDefinedErrorFunctionForKey(key, schema, failFast) {
|
|
|
100
100
|
defineError
|
|
101
101
|
);
|
|
102
102
|
}
|
|
103
|
-
function hasChanged(prev, current) {
|
|
104
|
-
if (Array.isArray(prev)) {
|
|
105
|
-
if (Array.isArray(current) === false) {
|
|
106
|
-
return true;
|
|
107
|
-
}
|
|
108
|
-
if (prev.length !== current.length) {
|
|
109
|
-
return true;
|
|
110
|
-
}
|
|
111
|
-
for (let i = 0; i < current.length; i++) {
|
|
112
|
-
if (hasChanged(prev[i], current[i])) {
|
|
113
|
-
return true;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return false;
|
|
117
|
-
}
|
|
118
|
-
if (typeof prev === "object" && prev !== null) {
|
|
119
|
-
if (typeof current !== "object" || current === null) {
|
|
120
|
-
return true;
|
|
121
|
-
}
|
|
122
|
-
for (const key in current) {
|
|
123
|
-
if (hasChanged(prev[key], current[key])) {
|
|
124
|
-
return true;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
for (const key in prev) {
|
|
128
|
-
if (hasChanged(prev[key], current[key])) {
|
|
129
|
-
return true;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return false;
|
|
133
|
-
}
|
|
134
|
-
return Object.is(prev, current) === false;
|
|
135
|
-
}
|
|
136
|
-
function isObject(data) {
|
|
137
|
-
return typeof data === "object" && data !== null && !Array.isArray(data);
|
|
138
|
-
}
|
|
139
|
-
function areCloseEnough(a, b, epsilon = 1e-15) {
|
|
140
|
-
return Math.abs(a - b) <= epsilon * Math.max(Math.abs(a), Math.abs(b));
|
|
141
|
-
}
|
|
142
|
-
function deepClone(obj, cloneClassInstances = false, seen = /* @__PURE__ */ new WeakMap()) {
|
|
143
|
-
if (typeof obj === "undefined" || obj === null || typeof obj !== "object") {
|
|
144
|
-
return obj;
|
|
145
|
-
}
|
|
146
|
-
if (seen.has(obj)) {
|
|
147
|
-
return seen.get(obj);
|
|
148
|
-
}
|
|
149
|
-
let clone;
|
|
150
|
-
if (typeof structuredClone === "function") {
|
|
151
|
-
clone = structuredClone(obj);
|
|
152
|
-
seen.set(obj, clone);
|
|
153
|
-
return clone;
|
|
154
|
-
}
|
|
155
|
-
switch (true) {
|
|
156
|
-
case Array.isArray(obj): {
|
|
157
|
-
clone = [];
|
|
158
|
-
seen.set(obj, clone);
|
|
159
|
-
for (let i = 0, l = obj.length; i < l; i++) {
|
|
160
|
-
clone[i] = deepClone(obj[i], cloneClassInstances, seen);
|
|
161
|
-
}
|
|
162
|
-
return clone;
|
|
163
|
-
}
|
|
164
|
-
case obj instanceof Date: {
|
|
165
|
-
clone = new Date(obj.getTime());
|
|
166
|
-
seen.set(obj, clone);
|
|
167
|
-
return clone;
|
|
168
|
-
}
|
|
169
|
-
case obj instanceof RegExp: {
|
|
170
|
-
clone = new RegExp(obj.source, obj.flags);
|
|
171
|
-
seen.set(obj, clone);
|
|
172
|
-
return clone;
|
|
173
|
-
}
|
|
174
|
-
case obj instanceof Map: {
|
|
175
|
-
clone = /* @__PURE__ */ new Map();
|
|
176
|
-
seen.set(obj, clone);
|
|
177
|
-
for (const [key, value] of obj.entries()) {
|
|
178
|
-
clone.set(
|
|
179
|
-
deepClone(key, cloneClassInstances, seen),
|
|
180
|
-
deepClone(value, cloneClassInstances, seen)
|
|
181
|
-
);
|
|
182
|
-
}
|
|
183
|
-
return clone;
|
|
184
|
-
}
|
|
185
|
-
case obj instanceof Set: {
|
|
186
|
-
clone = /* @__PURE__ */ new Set();
|
|
187
|
-
seen.set(obj, clone);
|
|
188
|
-
for (const value of obj.values()) {
|
|
189
|
-
clone.add(deepClone(value, cloneClassInstances, seen));
|
|
190
|
-
}
|
|
191
|
-
return clone;
|
|
192
|
-
}
|
|
193
|
-
case obj instanceof ArrayBuffer: {
|
|
194
|
-
clone = obj.slice(0);
|
|
195
|
-
seen.set(obj, clone);
|
|
196
|
-
return clone;
|
|
197
|
-
}
|
|
198
|
-
case ArrayBuffer.isView(obj): {
|
|
199
|
-
clone = new obj.constructor(obj.buffer.slice(0));
|
|
200
|
-
seen.set(obj, clone);
|
|
201
|
-
return clone;
|
|
202
|
-
}
|
|
203
|
-
case (typeof Buffer !== "undefined" && obj instanceof Buffer): {
|
|
204
|
-
clone = Buffer.from(obj);
|
|
205
|
-
seen.set(obj, clone);
|
|
206
|
-
return clone;
|
|
207
|
-
}
|
|
208
|
-
case obj instanceof Error: {
|
|
209
|
-
clone = new obj.constructor(obj.message);
|
|
210
|
-
seen.set(obj, clone);
|
|
211
|
-
break;
|
|
212
|
-
}
|
|
213
|
-
case (obj instanceof Promise || obj instanceof WeakMap || obj instanceof WeakSet): {
|
|
214
|
-
clone = obj;
|
|
215
|
-
seen.set(obj, clone);
|
|
216
|
-
return clone;
|
|
217
|
-
}
|
|
218
|
-
case (obj.constructor && obj.constructor !== Object): {
|
|
219
|
-
if (!cloneClassInstances) {
|
|
220
|
-
clone = obj;
|
|
221
|
-
seen.set(obj, clone);
|
|
222
|
-
return clone;
|
|
223
|
-
}
|
|
224
|
-
clone = Object.create(Object.getPrototypeOf(obj));
|
|
225
|
-
seen.set(obj, clone);
|
|
226
|
-
break;
|
|
227
|
-
}
|
|
228
|
-
default: {
|
|
229
|
-
clone = {};
|
|
230
|
-
seen.set(obj, clone);
|
|
231
|
-
const keys = Reflect.ownKeys(obj);
|
|
232
|
-
for (let i = 0, l = keys.length; i < l; i++) {
|
|
233
|
-
const key = keys[i];
|
|
234
|
-
clone[key] = deepClone(
|
|
235
|
-
obj[key],
|
|
236
|
-
cloneClassInstances,
|
|
237
|
-
seen
|
|
238
|
-
);
|
|
239
|
-
}
|
|
240
|
-
return clone;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
const descriptors = Object.getOwnPropertyDescriptors(obj);
|
|
244
|
-
for (const key of Reflect.ownKeys(descriptors)) {
|
|
245
|
-
const descriptor = descriptors[key];
|
|
246
|
-
if ("value" in descriptor) {
|
|
247
|
-
descriptor.value = deepClone(descriptor.value, cloneClassInstances, seen);
|
|
248
|
-
}
|
|
249
|
-
Object.defineProperty(clone, key, descriptor);
|
|
250
|
-
}
|
|
251
|
-
return clone;
|
|
252
|
-
}
|
|
253
103
|
function isCompiledSchema(subSchema) {
|
|
254
|
-
return
|
|
104
|
+
return !!subSchema && typeof subSchema === "object" && !Array.isArray(subSchema) && "$validate" in subSchema;
|
|
255
105
|
}
|
|
256
106
|
function getNamedFunction(name, fn) {
|
|
257
107
|
return Object.defineProperty(fn, "name", { value: name });
|
|
@@ -289,45 +139,297 @@ function resolvePath(root, path) {
|
|
|
289
139
|
}
|
|
290
140
|
return;
|
|
291
141
|
}
|
|
142
|
+
function areCloseEnough(a, b, epsilon = 1e-15) {
|
|
143
|
+
return Math.abs(a - b) <= epsilon * Math.max(Math.abs(a), Math.abs(b));
|
|
144
|
+
}
|
|
292
145
|
|
|
293
146
|
// lib/formats.ts
|
|
294
147
|
var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
295
148
|
var DURATION_REGEX = /^P(?!$)((\d+Y)?(\d+M)?(\d+W)?(\d+D)?)(T(?=\d)(\d+H)?(\d+M)?(\d+S)?)?$/;
|
|
296
|
-
var DATE_TIME_REGEX = /^(\d{4})-(0[0-9]|1[0-2])-(\d{2})T(0[0-9]|1\d|2[0-3]):([0-5]\d):((?:[0-5]\d|60))(?:.\d+)?(?:([+-])(0[0-9]|1\d|2[0-3]):([0-5]\d)|Z)?$/i;
|
|
297
149
|
var URI_REGEX = /^[a-zA-Z][a-zA-Z0-9+\-.]*:[^\s]*$/;
|
|
298
150
|
var EMAIL_REGEX = /^(?!\.)(?!.*\.$)[a-z0-9!#$%&'*+/=?^_`{|}~-]{1,20}(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]{1,21}){0,2}@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,60}[a-z0-9])?){0,3}$/i;
|
|
299
|
-
var IPV4_REGEX = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])$/;
|
|
300
|
-
var IPV6_REGEX = /(?:\s+|:::+|^\w{5,}|\w{5}$|^:{1}\w|\w:{1}$)/;
|
|
301
|
-
var IPV6_SHORT_REGEX = /^[0-9a-fA-F:.]*$/;
|
|
302
|
-
var IPV6_FULL_REGEX = /^(?:(?:[0-9a-fA-F]{1,4}:){7}(?:[0-9a-fA-F]{1,4}|:))$/;
|
|
303
|
-
var IPV6_INVALID_CHAR_REGEX = /(?:[0-9a-fA-F]{5,}|\D[0-9a-fA-F]{3}:)/;
|
|
304
|
-
var IPV6_FAST_FAIL_REGEX = /^(?:(?:(?:[0-9a-fA-F]{1,4}(?::|$)){1,6}))|(?:::(?:[0-9a-fA-F]{1,4})){0,5}$/;
|
|
305
151
|
var HOSTNAME_REGEX = /^[a-z0-9][a-z0-9-]{0,62}(?:\.[a-z0-9][a-z0-9-]{0,62})*[a-z0-9]$/i;
|
|
306
152
|
var DATE_REGEX = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
307
|
-
var JSON_POINTER_REGEX = /^\/(?:[^~]|~0|~1)*$/;
|
|
308
|
-
var RELATIVE_JSON_POINTER_REGEX = /^([0-9]+)(#|\/(?:[^~]|~0|~1)*)?$/;
|
|
309
153
|
var TIME_REGEX = /^([01]\d|2[0-3]):([0-5]\d):([0-5]\d)(\.\d+)?(Z|([+-])([01]\d|2[0-3]):([0-5]\d))$/;
|
|
310
154
|
var URI_REFERENCE_REGEX = /^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#((?![^#]*\\)[^#]*))?/i;
|
|
311
|
-
var URI_TEMPLATE_REGEX = /^(?:[^{}]|\{[^}]+\})*$/;
|
|
312
155
|
var IRI_REGEX = /^[a-zA-Z][a-zA-Z0-9+\-.]*:[^\s]*$/;
|
|
313
156
|
var IRI_REFERENCE_REGEX = /^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#((?![^#]*\\)[^#]*))?/i;
|
|
314
157
|
var IDN_EMAIL_REGEX = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;
|
|
315
158
|
var IDN_HOSTNAME_REGEX = /^[^\s!@#$%^&*()_+\=\[\]{};':"\\|,<>\/?]+$/;
|
|
316
|
-
var BACK_SLASH_REGEX = /\\/;
|
|
317
159
|
var DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
160
|
+
function isDigitCharCode(code) {
|
|
161
|
+
return code >= 48 && code <= 57;
|
|
162
|
+
}
|
|
163
|
+
function parseTwoDigits(data, index) {
|
|
164
|
+
const first = data.charCodeAt(index) - 48;
|
|
165
|
+
const second = data.charCodeAt(index + 1) - 48;
|
|
166
|
+
if (first < 0 || first > 9 || second < 0 || second > 9) {
|
|
167
|
+
return -1;
|
|
168
|
+
}
|
|
169
|
+
return first * 10 + second;
|
|
170
|
+
}
|
|
171
|
+
function parseFourDigits(data, index) {
|
|
172
|
+
const a = data.charCodeAt(index) - 48;
|
|
173
|
+
const b = data.charCodeAt(index + 1) - 48;
|
|
174
|
+
const c = data.charCodeAt(index + 2) - 48;
|
|
175
|
+
const d = data.charCodeAt(index + 3) - 48;
|
|
176
|
+
if (a < 0 || a > 9 || b < 0 || b > 9 || c < 0 || c > 9 || d < 0 || d > 9) {
|
|
177
|
+
return -1;
|
|
178
|
+
}
|
|
179
|
+
return a * 1e3 + b * 100 + c * 10 + d;
|
|
180
|
+
}
|
|
181
|
+
function isValidIpv4Range(data, start, end) {
|
|
182
|
+
let segmentCount = 0;
|
|
183
|
+
let segmentStart = start;
|
|
184
|
+
for (let i = start; i <= end; i++) {
|
|
185
|
+
if (i !== end && data.charCodeAt(i) !== 46) {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const segmentLength = i - segmentStart;
|
|
189
|
+
if (segmentLength < 1 || segmentLength > 3) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
if (segmentLength > 1 && data.charCodeAt(segmentStart) === 48) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
let value = 0;
|
|
196
|
+
for (let j = segmentStart; j < i; j++) {
|
|
197
|
+
const digit = data.charCodeAt(j) - 48;
|
|
198
|
+
if (digit < 0 || digit > 9) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
value = value * 10 + digit;
|
|
202
|
+
}
|
|
203
|
+
if (value > 255) {
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
segmentCount++;
|
|
207
|
+
segmentStart = i + 1;
|
|
208
|
+
}
|
|
209
|
+
return segmentCount === 4;
|
|
210
|
+
}
|
|
211
|
+
function isValidIpv4(data) {
|
|
212
|
+
return isValidIpv4Range(data, 0, data.length);
|
|
213
|
+
}
|
|
214
|
+
function isHexCharCode(code) {
|
|
215
|
+
return code >= 48 && code <= 57 || code >= 65 && code <= 70 || code >= 97 && code <= 102;
|
|
216
|
+
}
|
|
217
|
+
function isValidIpv6(data) {
|
|
218
|
+
const length = data.length;
|
|
219
|
+
if (length === 0) {
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
let hasColon = false;
|
|
223
|
+
let hasDoubleColon = false;
|
|
224
|
+
let hextetCount = 0;
|
|
225
|
+
let i = 0;
|
|
226
|
+
while (i < length) {
|
|
227
|
+
if (data.charCodeAt(i) === 58) {
|
|
228
|
+
hasColon = true;
|
|
229
|
+
if (i + 1 < length && data.charCodeAt(i + 1) === 58) {
|
|
230
|
+
if (hasDoubleColon) {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
hasDoubleColon = true;
|
|
234
|
+
i += 2;
|
|
235
|
+
if (i === length) {
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
const segmentStart = i;
|
|
243
|
+
let segmentLength = 0;
|
|
244
|
+
while (i < length && isHexCharCode(data.charCodeAt(i))) {
|
|
245
|
+
segmentLength++;
|
|
246
|
+
if (segmentLength > 4) {
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
i++;
|
|
250
|
+
}
|
|
251
|
+
if (segmentLength === 0) {
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
if (i < length && data.charCodeAt(i) === 46) {
|
|
255
|
+
if (!hasColon) {
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
if (!isValidIpv4Range(data, segmentStart, length)) {
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
if (hasDoubleColon) {
|
|
262
|
+
return hextetCount < 6;
|
|
263
|
+
}
|
|
264
|
+
return hextetCount === 6;
|
|
265
|
+
}
|
|
266
|
+
hextetCount++;
|
|
267
|
+
if (hextetCount > 8) {
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
if (i === length) {
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
if (data.charCodeAt(i) !== 58) {
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
hasColon = true;
|
|
277
|
+
i++;
|
|
278
|
+
if (i === length) {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
if (data.charCodeAt(i) === 58) {
|
|
282
|
+
if (hasDoubleColon) {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
hasDoubleColon = true;
|
|
286
|
+
i++;
|
|
287
|
+
if (i === length) {
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
if (!hasColon) {
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
if (hasDoubleColon) {
|
|
296
|
+
return hextetCount < 8;
|
|
297
|
+
}
|
|
298
|
+
return hextetCount === 8;
|
|
299
|
+
}
|
|
300
|
+
function isValidJsonPointer(data) {
|
|
301
|
+
if (data === "") {
|
|
302
|
+
return true;
|
|
303
|
+
}
|
|
304
|
+
if (data.charCodeAt(0) !== 47) {
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
for (let i = 1; i < data.length; i++) {
|
|
308
|
+
if (data.charCodeAt(i) !== 126) {
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
const next = data.charCodeAt(i + 1);
|
|
312
|
+
if (next !== 48 && next !== 49) {
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
i++;
|
|
316
|
+
}
|
|
317
|
+
return true;
|
|
318
|
+
}
|
|
319
|
+
function isValidRelativeJsonPointer(data) {
|
|
320
|
+
if (data.length === 0) {
|
|
321
|
+
return true;
|
|
322
|
+
}
|
|
323
|
+
let i = 0;
|
|
324
|
+
while (i < data.length) {
|
|
325
|
+
const code = data.charCodeAt(i);
|
|
326
|
+
if (code < 48 || code > 57) {
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
i++;
|
|
330
|
+
}
|
|
331
|
+
if (i === 0) {
|
|
332
|
+
return false;
|
|
333
|
+
}
|
|
334
|
+
if (i === data.length) {
|
|
335
|
+
return true;
|
|
336
|
+
}
|
|
337
|
+
if (data.charCodeAt(i) === 35) {
|
|
338
|
+
return i + 1 === data.length;
|
|
339
|
+
}
|
|
340
|
+
if (data.charCodeAt(i) !== 47) {
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
for (i = i + 1; i < data.length; i++) {
|
|
344
|
+
if (data.charCodeAt(i) !== 126) {
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
const next = data.charCodeAt(i + 1);
|
|
348
|
+
if (next !== 48 && next !== 49) {
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
i++;
|
|
352
|
+
}
|
|
353
|
+
return true;
|
|
354
|
+
}
|
|
355
|
+
function isValidUriTemplate(data) {
|
|
356
|
+
for (let i = 0; i < data.length; i++) {
|
|
357
|
+
const code = data.charCodeAt(i);
|
|
358
|
+
if (code === 125) {
|
|
359
|
+
return false;
|
|
360
|
+
}
|
|
361
|
+
if (code !== 123) {
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
const closeIndex = data.indexOf("}", i + 1);
|
|
365
|
+
if (closeIndex === -1 || closeIndex === i + 1) {
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
i = closeIndex;
|
|
369
|
+
}
|
|
370
|
+
return true;
|
|
371
|
+
}
|
|
318
372
|
var Formats = {
|
|
319
373
|
["date-time"](data) {
|
|
320
|
-
const
|
|
321
|
-
if (
|
|
374
|
+
const length = data.length;
|
|
375
|
+
if (length < 19) {
|
|
376
|
+
return false;
|
|
377
|
+
}
|
|
378
|
+
if (data.charCodeAt(4) !== 45 || data.charCodeAt(7) !== 45 || data.charCodeAt(13) !== 58 || data.charCodeAt(16) !== 58) {
|
|
379
|
+
return false;
|
|
380
|
+
}
|
|
381
|
+
const tCode = data.charCodeAt(10);
|
|
382
|
+
if (tCode !== 84 && tCode !== 116) {
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
385
|
+
const year = parseFourDigits(data, 0);
|
|
386
|
+
const month = parseTwoDigits(data, 5);
|
|
387
|
+
const day = parseTwoDigits(data, 8);
|
|
388
|
+
const hour = parseTwoDigits(data, 11);
|
|
389
|
+
const minute = parseTwoDigits(data, 14);
|
|
390
|
+
const second = parseTwoDigits(data, 17);
|
|
391
|
+
if (year < 0 || month < 0 || day < 0 || hour < 0 || minute < 0 || second < 0) {
|
|
392
|
+
return false;
|
|
393
|
+
}
|
|
394
|
+
if (hour > 23 || minute > 59 || second > 60) {
|
|
395
|
+
return false;
|
|
396
|
+
}
|
|
397
|
+
let cursor = 19;
|
|
398
|
+
let offsetSign = null;
|
|
399
|
+
let offsetHour = 0;
|
|
400
|
+
let offsetMinute = 0;
|
|
401
|
+
if (cursor < length && data.charCodeAt(cursor) === 46) {
|
|
402
|
+
cursor++;
|
|
403
|
+
const fracStart = cursor;
|
|
404
|
+
while (cursor < length && isDigitCharCode(data.charCodeAt(cursor))) {
|
|
405
|
+
cursor++;
|
|
406
|
+
}
|
|
407
|
+
if (cursor === fracStart) {
|
|
408
|
+
return false;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
if (cursor < length) {
|
|
412
|
+
const tzCode = data.charCodeAt(cursor);
|
|
413
|
+
if (tzCode === 90 || tzCode === 122) {
|
|
414
|
+
cursor++;
|
|
415
|
+
} else if (tzCode === 43 || tzCode === 45) {
|
|
416
|
+
offsetSign = tzCode === 43 ? "+" : "-";
|
|
417
|
+
if (cursor + 6 > length || data.charCodeAt(cursor + 3) !== 58) {
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
offsetHour = parseTwoDigits(data, cursor + 1);
|
|
421
|
+
offsetMinute = parseTwoDigits(data, cursor + 4);
|
|
422
|
+
if (offsetHour < 0 || offsetMinute < 0 || offsetHour > 23 || offsetMinute > 59) {
|
|
423
|
+
return false;
|
|
424
|
+
}
|
|
425
|
+
cursor += 6;
|
|
426
|
+
} else {
|
|
427
|
+
return false;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
if (cursor !== length) {
|
|
322
431
|
return false;
|
|
323
432
|
}
|
|
324
|
-
const [, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr] = match;
|
|
325
|
-
const year = Number(yearStr);
|
|
326
|
-
const month = Number(monthStr);
|
|
327
|
-
const day = Number(dayStr);
|
|
328
|
-
const hour = Number(hourStr);
|
|
329
|
-
const minute = Number(minuteStr);
|
|
330
|
-
const second = Number(secondStr);
|
|
331
433
|
if (month < 1 || month > 12) {
|
|
332
434
|
return false;
|
|
333
435
|
}
|
|
@@ -338,8 +440,19 @@ var Formats = {
|
|
|
338
440
|
if (!maxDays || day > maxDays) {
|
|
339
441
|
return false;
|
|
340
442
|
}
|
|
341
|
-
if (second === 60
|
|
342
|
-
|
|
443
|
+
if (second === 60) {
|
|
444
|
+
let utcTotalMinutes = hour * 60 + minute;
|
|
445
|
+
if (offsetSign) {
|
|
446
|
+
const offsetTotalMinutes = offsetHour * 60 + offsetMinute;
|
|
447
|
+
utcTotalMinutes += offsetSign === "+" ? -offsetTotalMinutes : offsetTotalMinutes;
|
|
448
|
+
utcTotalMinutes %= 24 * 60;
|
|
449
|
+
if (utcTotalMinutes < 0) {
|
|
450
|
+
utcTotalMinutes += 24 * 60;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
if (utcTotalMinutes !== 23 * 60 + 59) {
|
|
454
|
+
return false;
|
|
455
|
+
}
|
|
343
456
|
}
|
|
344
457
|
return true;
|
|
345
458
|
},
|
|
@@ -350,42 +463,10 @@ var Formats = {
|
|
|
350
463
|
return EMAIL_REGEX.test(data);
|
|
351
464
|
},
|
|
352
465
|
ipv4(data) {
|
|
353
|
-
return
|
|
466
|
+
return isValidIpv4(data);
|
|
354
467
|
},
|
|
355
|
-
// ipv6: isMyIpValid({ version: 6 }),
|
|
356
468
|
ipv6(data) {
|
|
357
|
-
|
|
358
|
-
return true;
|
|
359
|
-
}
|
|
360
|
-
if (data.indexOf(":") === -1 || IPV6_REGEX.test(data)) {
|
|
361
|
-
return false;
|
|
362
|
-
}
|
|
363
|
-
const hasIpv4 = data.indexOf(".") !== -1;
|
|
364
|
-
let addressParts = data;
|
|
365
|
-
if (hasIpv4) {
|
|
366
|
-
addressParts = data.split(":");
|
|
367
|
-
const ipv4Part = addressParts.pop();
|
|
368
|
-
if (!IPV4_REGEX.test(ipv4Part)) {
|
|
369
|
-
return false;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
const isShortened = data.indexOf("::") !== -1;
|
|
373
|
-
const ipv6Part = hasIpv4 ? addressParts.join(":") : data;
|
|
374
|
-
if (isShortened) {
|
|
375
|
-
if (ipv6Part.split("::").length - 1 > 1) {
|
|
376
|
-
return false;
|
|
377
|
-
}
|
|
378
|
-
if (!IPV6_SHORT_REGEX.test(ipv6Part)) {
|
|
379
|
-
return false;
|
|
380
|
-
}
|
|
381
|
-
return IPV6_FAST_FAIL_REGEX.test(ipv6Part);
|
|
382
|
-
}
|
|
383
|
-
const isIpv6Valid = IPV6_FULL_REGEX.test(ipv6Part);
|
|
384
|
-
const hasInvalidChar = IPV6_INVALID_CHAR_REGEX.test(ipv6Part);
|
|
385
|
-
if (hasIpv4) {
|
|
386
|
-
return isIpv6Valid || !hasInvalidChar;
|
|
387
|
-
}
|
|
388
|
-
return isIpv6Valid && !hasInvalidChar;
|
|
469
|
+
return isValidIpv6(data);
|
|
389
470
|
},
|
|
390
471
|
hostname(data) {
|
|
391
472
|
return HOSTNAME_REGEX.test(data);
|
|
@@ -417,28 +498,22 @@ var Formats = {
|
|
|
417
498
|
}
|
|
418
499
|
},
|
|
419
500
|
"json-pointer"(data) {
|
|
420
|
-
|
|
421
|
-
return true;
|
|
422
|
-
}
|
|
423
|
-
return JSON_POINTER_REGEX.test(data);
|
|
501
|
+
return isValidJsonPointer(data);
|
|
424
502
|
},
|
|
425
503
|
"relative-json-pointer"(data) {
|
|
426
|
-
|
|
427
|
-
return true;
|
|
428
|
-
}
|
|
429
|
-
return RELATIVE_JSON_POINTER_REGEX.test(data);
|
|
504
|
+
return isValidRelativeJsonPointer(data);
|
|
430
505
|
},
|
|
431
506
|
time(data) {
|
|
432
507
|
return TIME_REGEX.test(data);
|
|
433
508
|
},
|
|
434
509
|
"uri-reference"(data) {
|
|
435
|
-
if (
|
|
510
|
+
if (data.includes("\\")) {
|
|
436
511
|
return false;
|
|
437
512
|
}
|
|
438
513
|
return URI_REFERENCE_REGEX.test(data);
|
|
439
514
|
},
|
|
440
515
|
"uri-template"(data) {
|
|
441
|
-
return
|
|
516
|
+
return isValidUriTemplate(data);
|
|
442
517
|
},
|
|
443
518
|
duration(data) {
|
|
444
519
|
return DURATION_REGEX.test(data);
|
|
@@ -451,7 +526,7 @@ var Formats = {
|
|
|
451
526
|
return IRI_REGEX.test(data);
|
|
452
527
|
},
|
|
453
528
|
"iri-reference"(data) {
|
|
454
|
-
if (
|
|
529
|
+
if (data.includes("\\")) {
|
|
455
530
|
return false;
|
|
456
531
|
}
|
|
457
532
|
return IRI_REFERENCE_REGEX.test(data);
|
|
@@ -468,7 +543,7 @@ var Formats = {
|
|
|
468
543
|
// lib/types.ts
|
|
469
544
|
var Types = {
|
|
470
545
|
object(data) {
|
|
471
|
-
return
|
|
546
|
+
return data !== null && typeof data === "object" && !Array.isArray(data);
|
|
472
547
|
},
|
|
473
548
|
array(data) {
|
|
474
549
|
return Array.isArray(data);
|
|
@@ -491,16 +566,124 @@ var Types = {
|
|
|
491
566
|
// Not implemented yet
|
|
492
567
|
timestamp: false,
|
|
493
568
|
int8: false,
|
|
494
|
-
|
|
569
|
+
uint8: false,
|
|
495
570
|
int16: false,
|
|
496
|
-
|
|
571
|
+
uint16: false,
|
|
497
572
|
int32: false,
|
|
498
|
-
|
|
573
|
+
uint32: false,
|
|
499
574
|
float32: false,
|
|
500
575
|
float64: false
|
|
501
576
|
};
|
|
502
577
|
|
|
578
|
+
// lib/utils/has-changed.ts
|
|
579
|
+
function hasChanged(prev, current) {
|
|
580
|
+
if (Object.is(prev, current)) {
|
|
581
|
+
return false;
|
|
582
|
+
}
|
|
583
|
+
if (Array.isArray(prev)) {
|
|
584
|
+
if (Array.isArray(current) === false) {
|
|
585
|
+
return true;
|
|
586
|
+
}
|
|
587
|
+
if (prev.length !== current.length) {
|
|
588
|
+
return true;
|
|
589
|
+
}
|
|
590
|
+
for (let i = 0; i < current.length; i++) {
|
|
591
|
+
if (hasChanged(prev[i], current[i])) {
|
|
592
|
+
return true;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
return false;
|
|
596
|
+
}
|
|
597
|
+
if (typeof prev === "object" && prev !== null) {
|
|
598
|
+
if (typeof current !== "object" || current === null) {
|
|
599
|
+
return true;
|
|
600
|
+
}
|
|
601
|
+
for (const key in current) {
|
|
602
|
+
if (hasChanged(prev[key], current[key])) {
|
|
603
|
+
return true;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
for (const key in prev) {
|
|
607
|
+
if (key in current) {
|
|
608
|
+
continue;
|
|
609
|
+
}
|
|
610
|
+
if (hasChanged(prev[key], void 0)) {
|
|
611
|
+
return true;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
return false;
|
|
615
|
+
}
|
|
616
|
+
return true;
|
|
617
|
+
}
|
|
618
|
+
|
|
503
619
|
// lib/keywords/array-keywords.ts
|
|
620
|
+
function isUniquePrimitive(value) {
|
|
621
|
+
return value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
622
|
+
}
|
|
623
|
+
function getArrayBucketKey(value) {
|
|
624
|
+
const length = value.length;
|
|
625
|
+
if (length === 0) {
|
|
626
|
+
return "0";
|
|
627
|
+
}
|
|
628
|
+
const first = value[0];
|
|
629
|
+
const last = value[length - 1];
|
|
630
|
+
const firstType = first === null ? "null" : typeof first;
|
|
631
|
+
const lastType = last === null ? "null" : typeof last;
|
|
632
|
+
let firstArrayMarker = "";
|
|
633
|
+
if (Array.isArray(first)) {
|
|
634
|
+
const firstSignature = getPrimitiveArraySignature(first);
|
|
635
|
+
firstArrayMarker = firstSignature === null ? `a:${first.length}` : firstSignature;
|
|
636
|
+
}
|
|
637
|
+
let lastArrayMarker = "";
|
|
638
|
+
if (Array.isArray(last)) {
|
|
639
|
+
const lastSignature = getPrimitiveArraySignature(last);
|
|
640
|
+
lastArrayMarker = lastSignature === null ? `a:${last.length}` : lastSignature;
|
|
641
|
+
}
|
|
642
|
+
return `${length}:${firstType}:${firstArrayMarker}:${lastType}:${lastArrayMarker}`;
|
|
643
|
+
}
|
|
644
|
+
function getObjectShapeKey(value) {
|
|
645
|
+
const keys = Object.keys(value).sort();
|
|
646
|
+
return `${keys.length}:${keys.join("")}`;
|
|
647
|
+
}
|
|
648
|
+
function getPrimitiveArraySignature(value) {
|
|
649
|
+
const length = value.length;
|
|
650
|
+
if (length === 0) {
|
|
651
|
+
return "a:0";
|
|
652
|
+
}
|
|
653
|
+
if (!isUniquePrimitive(value[0]) || !isUniquePrimitive(value[length - 1])) {
|
|
654
|
+
return null;
|
|
655
|
+
}
|
|
656
|
+
let signature = `a:${length}:`;
|
|
657
|
+
for (let i = 0; i < length; i++) {
|
|
658
|
+
const item = value[i];
|
|
659
|
+
if (item === null) {
|
|
660
|
+
signature += "l;";
|
|
661
|
+
continue;
|
|
662
|
+
}
|
|
663
|
+
if (typeof item === "string") {
|
|
664
|
+
signature += `s${item.length}:${item};`;
|
|
665
|
+
continue;
|
|
666
|
+
}
|
|
667
|
+
if (typeof item === "number") {
|
|
668
|
+
if (Number.isNaN(item)) {
|
|
669
|
+
signature += "n:NaN;";
|
|
670
|
+
continue;
|
|
671
|
+
}
|
|
672
|
+
if (Object.is(item, -0)) {
|
|
673
|
+
signature += "n:-0;";
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
676
|
+
signature += `n:${item};`;
|
|
677
|
+
continue;
|
|
678
|
+
}
|
|
679
|
+
if (typeof item === "boolean") {
|
|
680
|
+
signature += item ? "b:1;" : "b:0;";
|
|
681
|
+
continue;
|
|
682
|
+
}
|
|
683
|
+
return null;
|
|
684
|
+
}
|
|
685
|
+
return signature;
|
|
686
|
+
}
|
|
504
687
|
var ArrayKeywords = {
|
|
505
688
|
// lib/keywords/array-keywords.ts
|
|
506
689
|
items(schema, data, defineError) {
|
|
@@ -591,18 +774,28 @@ var ArrayKeywords = {
|
|
|
591
774
|
return defineError("Array is too long", { data });
|
|
592
775
|
},
|
|
593
776
|
additionalItems(schema, data, defineError) {
|
|
594
|
-
if (!
|
|
777
|
+
if (!Array.isArray(data) || !Array.isArray(schema.items)) {
|
|
595
778
|
return;
|
|
596
779
|
}
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
780
|
+
let tupleLength = schema._tupleItemsLength;
|
|
781
|
+
if (tupleLength === void 0) {
|
|
782
|
+
tupleLength = schema.items.length;
|
|
783
|
+
Object.defineProperty(schema, "_tupleItemsLength", {
|
|
784
|
+
value: tupleLength,
|
|
785
|
+
enumerable: false,
|
|
786
|
+
configurable: false,
|
|
787
|
+
writable: false
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
if (data.length <= tupleLength) {
|
|
601
791
|
return;
|
|
602
792
|
}
|
|
603
|
-
if (
|
|
793
|
+
if (schema.additionalItems === false) {
|
|
794
|
+
return defineError("Array is too long", { data });
|
|
795
|
+
}
|
|
796
|
+
if (schema.additionalItems && typeof schema.additionalItems === "object" && !Array.isArray(schema.additionalItems)) {
|
|
604
797
|
if (isCompiledSchema(schema.additionalItems)) {
|
|
605
|
-
for (let i =
|
|
798
|
+
for (let i = tupleLength; i < data.length; i++) {
|
|
606
799
|
const error = schema.additionalItems.$validate(data[i]);
|
|
607
800
|
if (error) {
|
|
608
801
|
return defineError("Array item is invalid", {
|
|
@@ -626,25 +819,84 @@ var ArrayKeywords = {
|
|
|
626
819
|
if (len <= 1) {
|
|
627
820
|
return;
|
|
628
821
|
}
|
|
822
|
+
if (len <= 8) {
|
|
823
|
+
for (let i = 0; i < len; i++) {
|
|
824
|
+
const left = data[i];
|
|
825
|
+
for (let j = i + 1; j < len; j++) {
|
|
826
|
+
const right = data[j];
|
|
827
|
+
if (left === right) {
|
|
828
|
+
return defineError("Array items are not unique", { data: right });
|
|
829
|
+
}
|
|
830
|
+
if (typeof left === "number" && typeof right === "number" && Number.isNaN(left) && Number.isNaN(right)) {
|
|
831
|
+
return defineError("Array items are not unique", { data: right });
|
|
832
|
+
}
|
|
833
|
+
if (left && right && typeof left === "object" && typeof right === "object" && !hasChanged(left, right)) {
|
|
834
|
+
return defineError("Array items are not unique", { data: right });
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
629
840
|
const primitiveSeen = /* @__PURE__ */ new Set();
|
|
841
|
+
let primitiveArraySignatures;
|
|
842
|
+
let arrayBuckets;
|
|
843
|
+
let objectBuckets;
|
|
630
844
|
for (let i = 0; i < len; i++) {
|
|
631
845
|
const item = data[i];
|
|
632
|
-
|
|
633
|
-
if (item === null || type === "string" || type === "number" || type === "boolean") {
|
|
846
|
+
if (isUniquePrimitive(item)) {
|
|
634
847
|
if (primitiveSeen.has(item)) {
|
|
635
848
|
return defineError("Array items are not unique", { data: item });
|
|
636
849
|
}
|
|
637
850
|
primitiveSeen.add(item);
|
|
638
851
|
continue;
|
|
639
852
|
}
|
|
640
|
-
if (item
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
853
|
+
if (!item || typeof item !== "object") {
|
|
854
|
+
continue;
|
|
855
|
+
}
|
|
856
|
+
if (Array.isArray(item)) {
|
|
857
|
+
const signature = getPrimitiveArraySignature(item);
|
|
858
|
+
if (signature !== null) {
|
|
859
|
+
if (!primitiveArraySignatures) {
|
|
860
|
+
primitiveArraySignatures = /* @__PURE__ */ new Set();
|
|
861
|
+
}
|
|
862
|
+
if (primitiveArraySignatures.has(signature)) {
|
|
644
863
|
return defineError("Array items are not unique", { data: item });
|
|
645
864
|
}
|
|
865
|
+
primitiveArraySignatures.add(signature);
|
|
866
|
+
continue;
|
|
867
|
+
}
|
|
868
|
+
if (!arrayBuckets) {
|
|
869
|
+
arrayBuckets = /* @__PURE__ */ new Map();
|
|
870
|
+
}
|
|
871
|
+
const bucketKey2 = getArrayBucketKey(item);
|
|
872
|
+
let candidates2 = arrayBuckets.get(bucketKey2);
|
|
873
|
+
if (!candidates2) {
|
|
874
|
+
candidates2 = [];
|
|
875
|
+
arrayBuckets.set(bucketKey2, candidates2);
|
|
876
|
+
}
|
|
877
|
+
for (let j = 0; j < candidates2.length; j++) {
|
|
878
|
+
if (!hasChanged(candidates2[j], item)) {
|
|
879
|
+
return defineError("Array items are not unique", { data: item });
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
candidates2.push(item);
|
|
883
|
+
continue;
|
|
884
|
+
}
|
|
885
|
+
if (!objectBuckets) {
|
|
886
|
+
objectBuckets = /* @__PURE__ */ new Map();
|
|
887
|
+
}
|
|
888
|
+
const bucketKey = getObjectShapeKey(item);
|
|
889
|
+
let candidates = objectBuckets.get(bucketKey);
|
|
890
|
+
if (!candidates) {
|
|
891
|
+
candidates = [];
|
|
892
|
+
objectBuckets.set(bucketKey, candidates);
|
|
893
|
+
}
|
|
894
|
+
for (let j = 0; j < candidates.length; j++) {
|
|
895
|
+
if (!hasChanged(candidates[j], item)) {
|
|
896
|
+
return defineError("Array items are not unique", { data: item });
|
|
646
897
|
}
|
|
647
898
|
}
|
|
899
|
+
candidates.push(item);
|
|
648
900
|
}
|
|
649
901
|
},
|
|
650
902
|
contains(schema, data, defineError) {
|
|
@@ -660,8 +912,9 @@ var ArrayKeywords = {
|
|
|
660
912
|
}
|
|
661
913
|
return defineError("Array must not contain any items", { data });
|
|
662
914
|
}
|
|
915
|
+
const containsValidate = schema.contains.$validate;
|
|
663
916
|
for (let i = 0; i < data.length; i++) {
|
|
664
|
-
const error =
|
|
917
|
+
const error = containsValidate(data[i]);
|
|
665
918
|
if (!error) {
|
|
666
919
|
return;
|
|
667
920
|
}
|
|
@@ -671,6 +924,140 @@ var ArrayKeywords = {
|
|
|
671
924
|
}
|
|
672
925
|
};
|
|
673
926
|
|
|
927
|
+
// lib/utils/deep-freeze.ts
|
|
928
|
+
function isPlainObject(value) {
|
|
929
|
+
if (!value || typeof value !== "object") {
|
|
930
|
+
return false;
|
|
931
|
+
}
|
|
932
|
+
const proto = Object.getPrototypeOf(value);
|
|
933
|
+
return proto === Object.prototype || proto === null;
|
|
934
|
+
}
|
|
935
|
+
function canUseStructuredClone(value) {
|
|
936
|
+
if (typeof structuredClone !== "function") {
|
|
937
|
+
return false;
|
|
938
|
+
}
|
|
939
|
+
if (typeof Buffer !== "undefined" && value instanceof Buffer) {
|
|
940
|
+
return false;
|
|
941
|
+
}
|
|
942
|
+
return Array.isArray(value) || isPlainObject(value) || value instanceof Date || value instanceof RegExp || value instanceof Map || value instanceof Set || value instanceof ArrayBuffer || ArrayBuffer.isView(value);
|
|
943
|
+
}
|
|
944
|
+
function deepCloneUnfreeze(obj, cloneClassInstances = false, seen = /* @__PURE__ */ new WeakMap()) {
|
|
945
|
+
if (typeof obj === "undefined" || obj === null || typeof obj !== "object") {
|
|
946
|
+
return obj;
|
|
947
|
+
}
|
|
948
|
+
const source = obj;
|
|
949
|
+
if (seen.has(source)) {
|
|
950
|
+
return seen.get(source);
|
|
951
|
+
}
|
|
952
|
+
if (canUseStructuredClone(source)) {
|
|
953
|
+
const cloned = structuredClone(source);
|
|
954
|
+
seen.set(source, cloned);
|
|
955
|
+
return cloned;
|
|
956
|
+
}
|
|
957
|
+
let clone;
|
|
958
|
+
switch (true) {
|
|
959
|
+
case Array.isArray(source): {
|
|
960
|
+
clone = [];
|
|
961
|
+
seen.set(source, clone);
|
|
962
|
+
for (let i = 0, l = source.length; i < l; i++) {
|
|
963
|
+
clone[i] = deepCloneUnfreeze(source[i], cloneClassInstances, seen);
|
|
964
|
+
}
|
|
965
|
+
return clone;
|
|
966
|
+
}
|
|
967
|
+
case source instanceof Date: {
|
|
968
|
+
clone = new Date(source.getTime());
|
|
969
|
+
seen.set(source, clone);
|
|
970
|
+
return clone;
|
|
971
|
+
}
|
|
972
|
+
case source instanceof RegExp: {
|
|
973
|
+
clone = new RegExp(source.source, source.flags);
|
|
974
|
+
seen.set(source, clone);
|
|
975
|
+
return clone;
|
|
976
|
+
}
|
|
977
|
+
case source instanceof Map: {
|
|
978
|
+
clone = /* @__PURE__ */ new Map();
|
|
979
|
+
seen.set(source, clone);
|
|
980
|
+
for (const [key, value] of source.entries()) {
|
|
981
|
+
clone.set(
|
|
982
|
+
deepCloneUnfreeze(key, cloneClassInstances, seen),
|
|
983
|
+
deepCloneUnfreeze(value, cloneClassInstances, seen)
|
|
984
|
+
);
|
|
985
|
+
}
|
|
986
|
+
return clone;
|
|
987
|
+
}
|
|
988
|
+
case source instanceof Set: {
|
|
989
|
+
clone = /* @__PURE__ */ new Set();
|
|
990
|
+
seen.set(source, clone);
|
|
991
|
+
for (const value of source.values()) {
|
|
992
|
+
clone.add(deepCloneUnfreeze(value, cloneClassInstances, seen));
|
|
993
|
+
}
|
|
994
|
+
return clone;
|
|
995
|
+
}
|
|
996
|
+
case source instanceof ArrayBuffer: {
|
|
997
|
+
clone = source.slice(0);
|
|
998
|
+
seen.set(source, clone);
|
|
999
|
+
return clone;
|
|
1000
|
+
}
|
|
1001
|
+
case ArrayBuffer.isView(source): {
|
|
1002
|
+
clone = new source.constructor(source.buffer.slice(0));
|
|
1003
|
+
seen.set(source, clone);
|
|
1004
|
+
return clone;
|
|
1005
|
+
}
|
|
1006
|
+
case (typeof Buffer !== "undefined" && source instanceof Buffer): {
|
|
1007
|
+
clone = Buffer.from(source);
|
|
1008
|
+
seen.set(source, clone);
|
|
1009
|
+
return clone;
|
|
1010
|
+
}
|
|
1011
|
+
case source instanceof Error: {
|
|
1012
|
+
clone = new source.constructor(source.message);
|
|
1013
|
+
seen.set(source, clone);
|
|
1014
|
+
break;
|
|
1015
|
+
}
|
|
1016
|
+
case (source instanceof Promise || source instanceof WeakMap || source instanceof WeakSet): {
|
|
1017
|
+
clone = source;
|
|
1018
|
+
seen.set(source, clone);
|
|
1019
|
+
return clone;
|
|
1020
|
+
}
|
|
1021
|
+
case (source.constructor && source.constructor !== Object): {
|
|
1022
|
+
if (!cloneClassInstances) {
|
|
1023
|
+
clone = source;
|
|
1024
|
+
seen.set(source, clone);
|
|
1025
|
+
return clone;
|
|
1026
|
+
}
|
|
1027
|
+
clone = Object.create(Object.getPrototypeOf(source));
|
|
1028
|
+
seen.set(source, clone);
|
|
1029
|
+
break;
|
|
1030
|
+
}
|
|
1031
|
+
default: {
|
|
1032
|
+
clone = {};
|
|
1033
|
+
seen.set(source, clone);
|
|
1034
|
+
const keys = Reflect.ownKeys(source);
|
|
1035
|
+
for (let i = 0, l = keys.length; i < l; i++) {
|
|
1036
|
+
const key = keys[i];
|
|
1037
|
+
clone[key] = deepCloneUnfreeze(
|
|
1038
|
+
source[key],
|
|
1039
|
+
cloneClassInstances,
|
|
1040
|
+
seen
|
|
1041
|
+
);
|
|
1042
|
+
}
|
|
1043
|
+
return clone;
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
const descriptors = Object.getOwnPropertyDescriptors(source);
|
|
1047
|
+
for (const key of Reflect.ownKeys(descriptors)) {
|
|
1048
|
+
const descriptor = descriptors[key];
|
|
1049
|
+
if ("value" in descriptor) {
|
|
1050
|
+
descriptor.value = deepCloneUnfreeze(
|
|
1051
|
+
descriptor.value,
|
|
1052
|
+
cloneClassInstances,
|
|
1053
|
+
seen
|
|
1054
|
+
);
|
|
1055
|
+
}
|
|
1056
|
+
Object.defineProperty(clone, key, descriptor);
|
|
1057
|
+
}
|
|
1058
|
+
return clone;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
674
1061
|
// lib/keywords/number-keywords.ts
|
|
675
1062
|
var NumberKeywords = {
|
|
676
1063
|
minimum(schema, data, defineError, instance) {
|
|
@@ -739,15 +1126,129 @@ var NumberKeywords = {
|
|
|
739
1126
|
}
|
|
740
1127
|
};
|
|
741
1128
|
|
|
1129
|
+
// lib/utils/pattern-matcher.ts
|
|
1130
|
+
var REGEX_META_CHARS = /[\\.^$*+?()[\]{}|]/;
|
|
1131
|
+
function hasRegexMeta(value) {
|
|
1132
|
+
return REGEX_META_CHARS.test(value);
|
|
1133
|
+
}
|
|
1134
|
+
var PATTERN_CACHE = /* @__PURE__ */ new Map();
|
|
1135
|
+
function compilePatternMatcher(pattern) {
|
|
1136
|
+
const cached = PATTERN_CACHE.get(pattern);
|
|
1137
|
+
if (cached) {
|
|
1138
|
+
return cached;
|
|
1139
|
+
}
|
|
1140
|
+
let compiled;
|
|
1141
|
+
if (pattern.length === 0) {
|
|
1142
|
+
compiled = (_value) => true;
|
|
1143
|
+
} else if (!hasRegexMeta(pattern)) {
|
|
1144
|
+
compiled = (value) => value.includes(pattern);
|
|
1145
|
+
} else {
|
|
1146
|
+
const patternLength = pattern.length;
|
|
1147
|
+
if (patternLength >= 2 && pattern[0] === "^" && pattern[patternLength - 1] === "$") {
|
|
1148
|
+
const inner = pattern.slice(1, -1);
|
|
1149
|
+
if (!hasRegexMeta(inner)) {
|
|
1150
|
+
if (inner.length === 0) {
|
|
1151
|
+
compiled = (value) => value.length === 0;
|
|
1152
|
+
} else {
|
|
1153
|
+
compiled = (value) => value === inner;
|
|
1154
|
+
}
|
|
1155
|
+
} else {
|
|
1156
|
+
compiled = new RegExp(pattern, "u");
|
|
1157
|
+
}
|
|
1158
|
+
} else if (pattern[0] === "^") {
|
|
1159
|
+
const inner = pattern.slice(1);
|
|
1160
|
+
if (!hasRegexMeta(inner)) {
|
|
1161
|
+
if (inner.length === 0) {
|
|
1162
|
+
compiled = (_value) => true;
|
|
1163
|
+
} else {
|
|
1164
|
+
compiled = (value) => value.startsWith(inner);
|
|
1165
|
+
}
|
|
1166
|
+
} else {
|
|
1167
|
+
compiled = new RegExp(pattern, "u");
|
|
1168
|
+
}
|
|
1169
|
+
} else if (pattern[patternLength - 1] === "$") {
|
|
1170
|
+
const inner = pattern.slice(0, -1);
|
|
1171
|
+
if (!hasRegexMeta(inner)) {
|
|
1172
|
+
if (inner.length === 0) {
|
|
1173
|
+
compiled = (_value) => true;
|
|
1174
|
+
} else {
|
|
1175
|
+
compiled = (value) => value.endsWith(inner);
|
|
1176
|
+
}
|
|
1177
|
+
} else {
|
|
1178
|
+
compiled = new RegExp(pattern, "u");
|
|
1179
|
+
}
|
|
1180
|
+
} else {
|
|
1181
|
+
compiled = new RegExp(pattern, "u");
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
PATTERN_CACHE.set(pattern, compiled);
|
|
1185
|
+
return compiled;
|
|
1186
|
+
}
|
|
1187
|
+
|
|
742
1188
|
// lib/keywords/object-keywords.ts
|
|
1189
|
+
var PATTERN_KEY_CACHE_LIMIT = 512;
|
|
1190
|
+
function getPatternPropertyEntries(schema) {
|
|
1191
|
+
let entries = schema._patternPropertyEntries;
|
|
1192
|
+
if (entries) {
|
|
1193
|
+
return entries;
|
|
1194
|
+
}
|
|
1195
|
+
if (!schema.patternProperties || typeof schema.patternProperties !== "object" || Array.isArray(schema.patternProperties)) {
|
|
1196
|
+
return void 0;
|
|
1197
|
+
}
|
|
1198
|
+
const patternKeys = Object.keys(schema.patternProperties);
|
|
1199
|
+
entries = new Array(patternKeys.length);
|
|
1200
|
+
for (let i = 0; i < patternKeys.length; i++) {
|
|
1201
|
+
const key = patternKeys[i];
|
|
1202
|
+
const compiledMatcher = compilePatternMatcher(key);
|
|
1203
|
+
const match = compiledMatcher instanceof RegExp ? (value) => compiledMatcher.test(value) : compiledMatcher;
|
|
1204
|
+
entries[i] = {
|
|
1205
|
+
schemaProp: schema.patternProperties[key],
|
|
1206
|
+
match
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1209
|
+
Object.defineProperty(schema, "_patternPropertyEntries", {
|
|
1210
|
+
value: entries,
|
|
1211
|
+
enumerable: false,
|
|
1212
|
+
configurable: false,
|
|
1213
|
+
writable: false
|
|
1214
|
+
});
|
|
1215
|
+
return entries;
|
|
1216
|
+
}
|
|
1217
|
+
function getPatternKeyMatchIndexes(schema, key, entries) {
|
|
1218
|
+
let cache = schema._patternKeyMatchIndexCache;
|
|
1219
|
+
if (cache) {
|
|
1220
|
+
const cached = cache.get(key);
|
|
1221
|
+
if (cached) {
|
|
1222
|
+
return cached;
|
|
1223
|
+
}
|
|
1224
|
+
} else {
|
|
1225
|
+
cache = /* @__PURE__ */ new Map();
|
|
1226
|
+
Object.defineProperty(schema, "_patternKeyMatchIndexCache", {
|
|
1227
|
+
value: cache,
|
|
1228
|
+
enumerable: false,
|
|
1229
|
+
configurable: false,
|
|
1230
|
+
writable: false
|
|
1231
|
+
});
|
|
1232
|
+
}
|
|
1233
|
+
const indexes = [];
|
|
1234
|
+
for (let i = 0; i < entries.length; i++) {
|
|
1235
|
+
if (entries[i].match(key)) {
|
|
1236
|
+
indexes.push(i);
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
if (cache.size < PATTERN_KEY_CACHE_LIMIT) {
|
|
1240
|
+
cache.set(key, indexes);
|
|
1241
|
+
}
|
|
1242
|
+
return indexes;
|
|
1243
|
+
}
|
|
743
1244
|
var ObjectKeywords = {
|
|
744
1245
|
required(schema, data, defineError) {
|
|
745
|
-
if (!
|
|
1246
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
746
1247
|
return;
|
|
747
1248
|
}
|
|
748
1249
|
for (let i = 0; i < schema.required.length; i++) {
|
|
749
1250
|
const key = schema.required[i];
|
|
750
|
-
if (!
|
|
1251
|
+
if (!Object.prototype.hasOwnProperty.call(data, key)) {
|
|
751
1252
|
return defineError("Required property is missing", {
|
|
752
1253
|
item: key,
|
|
753
1254
|
data: data[key]
|
|
@@ -757,7 +1258,7 @@ var ObjectKeywords = {
|
|
|
757
1258
|
return;
|
|
758
1259
|
},
|
|
759
1260
|
properties(schema, data, defineError) {
|
|
760
|
-
if (!
|
|
1261
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
761
1262
|
return;
|
|
762
1263
|
}
|
|
763
1264
|
let propKeys = schema._propKeys;
|
|
@@ -770,22 +1271,21 @@ var ObjectKeywords = {
|
|
|
770
1271
|
writable: false
|
|
771
1272
|
});
|
|
772
1273
|
}
|
|
773
|
-
let
|
|
774
|
-
if (
|
|
775
|
-
|
|
776
|
-
Object.defineProperty(schema, "
|
|
777
|
-
value:
|
|
1274
|
+
let requiredSet = schema._requiredSet;
|
|
1275
|
+
if (requiredSet === void 0) {
|
|
1276
|
+
requiredSet = Array.isArray(schema.required) ? new Set(schema.required) : null;
|
|
1277
|
+
Object.defineProperty(schema, "_requiredSet", {
|
|
1278
|
+
value: requiredSet,
|
|
778
1279
|
enumerable: false,
|
|
779
1280
|
configurable: false,
|
|
780
1281
|
writable: false
|
|
781
1282
|
});
|
|
782
1283
|
}
|
|
783
|
-
const required = requiredKeys || [];
|
|
784
1284
|
for (let i = 0; i < propKeys.length; i++) {
|
|
785
1285
|
const key = propKeys[i];
|
|
786
1286
|
const schemaProp = schema.properties[key];
|
|
787
1287
|
if (!Object.prototype.hasOwnProperty.call(data, key)) {
|
|
788
|
-
if (
|
|
1288
|
+
if (requiredSet && requiredSet.has(key) && schemaProp && typeof schemaProp === "object" && !Array.isArray(schemaProp) && "default" in schemaProp) {
|
|
789
1289
|
const error = schemaProp.$validate(schemaProp.default);
|
|
790
1290
|
if (error) {
|
|
791
1291
|
return defineError("Default property is invalid", {
|
|
@@ -794,7 +1294,7 @@ var ObjectKeywords = {
|
|
|
794
1294
|
data: schemaProp.default
|
|
795
1295
|
});
|
|
796
1296
|
}
|
|
797
|
-
data[key] =
|
|
1297
|
+
data[key] = deepCloneUnfreeze(schemaProp.default);
|
|
798
1298
|
}
|
|
799
1299
|
continue;
|
|
800
1300
|
}
|
|
@@ -821,7 +1321,7 @@ var ObjectKeywords = {
|
|
|
821
1321
|
return;
|
|
822
1322
|
},
|
|
823
1323
|
values(schema, data, defineError) {
|
|
824
|
-
if (!
|
|
1324
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
825
1325
|
return;
|
|
826
1326
|
}
|
|
827
1327
|
const valueSchema = schema.values;
|
|
@@ -829,9 +1329,10 @@ var ObjectKeywords = {
|
|
|
829
1329
|
if (typeof validate !== "function") {
|
|
830
1330
|
return;
|
|
831
1331
|
}
|
|
832
|
-
const
|
|
833
|
-
|
|
834
|
-
|
|
1332
|
+
for (const key in data) {
|
|
1333
|
+
if (!Object.prototype.hasOwnProperty.call(data, key)) {
|
|
1334
|
+
continue;
|
|
1335
|
+
}
|
|
835
1336
|
const error = validate(data[key]);
|
|
836
1337
|
if (error) {
|
|
837
1338
|
return defineError("Property is invalid", {
|
|
@@ -843,58 +1344,61 @@ var ObjectKeywords = {
|
|
|
843
1344
|
}
|
|
844
1345
|
},
|
|
845
1346
|
maxProperties(schema, data, defineError) {
|
|
846
|
-
if (!
|
|
1347
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
847
1348
|
return;
|
|
848
1349
|
}
|
|
849
|
-
|
|
1350
|
+
let count = 0;
|
|
1351
|
+
for (const key in data) {
|
|
1352
|
+
if (!Object.prototype.hasOwnProperty.call(data, key)) {
|
|
1353
|
+
continue;
|
|
1354
|
+
}
|
|
1355
|
+
count++;
|
|
1356
|
+
if (count > schema.maxProperties) {
|
|
1357
|
+
return defineError("Too many properties", { data });
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
return;
|
|
850
1361
|
},
|
|
851
1362
|
minProperties(schema, data, defineError) {
|
|
852
|
-
if (!
|
|
1363
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
853
1364
|
return;
|
|
854
1365
|
}
|
|
1366
|
+
let count = 0;
|
|
1367
|
+
for (const key in data) {
|
|
1368
|
+
if (!Object.prototype.hasOwnProperty.call(data, key)) {
|
|
1369
|
+
continue;
|
|
1370
|
+
}
|
|
1371
|
+
count++;
|
|
1372
|
+
if (count >= schema.minProperties) {
|
|
1373
|
+
return;
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
855
1376
|
return defineError("Too few properties", { data });
|
|
856
1377
|
},
|
|
857
1378
|
additionalProperties(schema, data, defineError) {
|
|
858
|
-
if (!
|
|
1379
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
859
1380
|
return;
|
|
860
1381
|
}
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
1382
|
+
let apValidate = schema._apValidate;
|
|
1383
|
+
if (apValidate === void 0) {
|
|
1384
|
+
apValidate = isCompiledSchema(schema.additionalProperties) ? schema.additionalProperties.$validate : null;
|
|
1385
|
+
Object.defineProperty(schema, "_apValidate", {
|
|
1386
|
+
value: apValidate,
|
|
1387
|
+
enumerable: false,
|
|
1388
|
+
configurable: false,
|
|
1389
|
+
writable: false
|
|
868
1390
|
});
|
|
869
1391
|
}
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
patternList.push({
|
|
875
|
-
regex: new RegExp(pattern, "u"),
|
|
876
|
-
key: pattern
|
|
877
|
-
});
|
|
1392
|
+
const patternEntries = getPatternPropertyEntries(schema);
|
|
1393
|
+
for (const key in data) {
|
|
1394
|
+
if (!Object.prototype.hasOwnProperty.call(data, key)) {
|
|
1395
|
+
continue;
|
|
878
1396
|
}
|
|
879
|
-
Object.
|
|
880
|
-
value: patternList,
|
|
881
|
-
enumerable: false
|
|
882
|
-
});
|
|
883
|
-
}
|
|
884
|
-
for (let i = 0; i < keys.length; i++) {
|
|
885
|
-
const key = keys[i];
|
|
886
|
-
if (schema.properties && schema.properties.hasOwnProperty(key)) {
|
|
1397
|
+
if (schema.properties && Object.prototype.hasOwnProperty.call(schema.properties, key)) {
|
|
887
1398
|
continue;
|
|
888
1399
|
}
|
|
889
|
-
if (
|
|
890
|
-
|
|
891
|
-
for (let j = 0; j < patternList.length; j++) {
|
|
892
|
-
if (patternList[j].regex.test(key)) {
|
|
893
|
-
match = true;
|
|
894
|
-
break;
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
if (match) {
|
|
1400
|
+
if (patternEntries && patternEntries.length) {
|
|
1401
|
+
if (getPatternKeyMatchIndexes(schema, key, patternEntries).length > 0) {
|
|
898
1402
|
continue;
|
|
899
1403
|
}
|
|
900
1404
|
}
|
|
@@ -904,8 +1408,8 @@ var ObjectKeywords = {
|
|
|
904
1408
|
data: data[key]
|
|
905
1409
|
});
|
|
906
1410
|
}
|
|
907
|
-
if (
|
|
908
|
-
const error =
|
|
1411
|
+
if (apValidate) {
|
|
1412
|
+
const error = apValidate(data[key]);
|
|
909
1413
|
if (error) {
|
|
910
1414
|
return defineError("Additional properties are invalid", {
|
|
911
1415
|
item: key,
|
|
@@ -918,55 +1422,46 @@ var ObjectKeywords = {
|
|
|
918
1422
|
return;
|
|
919
1423
|
},
|
|
920
1424
|
patternProperties(schema, data, defineError) {
|
|
921
|
-
if (!
|
|
1425
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
922
1426
|
return;
|
|
923
1427
|
}
|
|
924
|
-
|
|
925
|
-
if (!
|
|
926
|
-
|
|
927
|
-
const patterns = Object.keys(schema.patternProperties || {});
|
|
928
|
-
for (let i = 0; i < patterns.length; i++) {
|
|
929
|
-
const pattern = patterns[i];
|
|
930
|
-
patternList.push({
|
|
931
|
-
regex: new RegExp(pattern, "u"),
|
|
932
|
-
key: pattern
|
|
933
|
-
});
|
|
934
|
-
}
|
|
935
|
-
Object.defineProperty(schema, "_patternPropertiesList", {
|
|
936
|
-
value: patternList,
|
|
937
|
-
enumerable: false
|
|
938
|
-
});
|
|
1428
|
+
const patternEntries = getPatternPropertyEntries(schema);
|
|
1429
|
+
if (!patternEntries || patternEntries.length === 0) {
|
|
1430
|
+
return;
|
|
939
1431
|
}
|
|
940
|
-
const
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
data: data[key]
|
|
952
|
-
});
|
|
953
|
-
}
|
|
954
|
-
}
|
|
1432
|
+
for (const key in data) {
|
|
1433
|
+
if (!Object.prototype.hasOwnProperty.call(data, key)) {
|
|
1434
|
+
continue;
|
|
1435
|
+
}
|
|
1436
|
+
const matchingIndexes = getPatternKeyMatchIndexes(schema, key, patternEntries);
|
|
1437
|
+
if (matchingIndexes.length === 0) {
|
|
1438
|
+
if (schema.additionalProperties === false && !(schema.properties && Object.prototype.hasOwnProperty.call(schema.properties, key))) {
|
|
1439
|
+
return defineError("Additional properties are not allowed", {
|
|
1440
|
+
item: key,
|
|
1441
|
+
data: data[key]
|
|
1442
|
+
});
|
|
955
1443
|
}
|
|
956
1444
|
continue;
|
|
957
1445
|
}
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
if (
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
1446
|
+
for (let j = 0; j < matchingIndexes.length; j++) {
|
|
1447
|
+
const schemaProp = patternEntries[matchingIndexes[j]].schemaProp;
|
|
1448
|
+
if (typeof schemaProp === "boolean") {
|
|
1449
|
+
if (schemaProp === false) {
|
|
1450
|
+
return defineError("Property is not allowed", {
|
|
1451
|
+
item: key,
|
|
1452
|
+
data: data[key]
|
|
1453
|
+
});
|
|
1454
|
+
}
|
|
1455
|
+
continue;
|
|
1456
|
+
}
|
|
1457
|
+
if ("$validate" in schemaProp) {
|
|
1458
|
+
const error = schemaProp.$validate(data[key]);
|
|
1459
|
+
if (error) {
|
|
1460
|
+
return defineError("Property is invalid", {
|
|
1461
|
+
item: key,
|
|
1462
|
+
cause: error,
|
|
1463
|
+
data: data[key]
|
|
1464
|
+
});
|
|
970
1465
|
}
|
|
971
1466
|
}
|
|
972
1467
|
}
|
|
@@ -974,13 +1469,17 @@ var ObjectKeywords = {
|
|
|
974
1469
|
return;
|
|
975
1470
|
},
|
|
976
1471
|
propertyNames(schema, data, defineError) {
|
|
977
|
-
if (!
|
|
1472
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
978
1473
|
return;
|
|
979
1474
|
}
|
|
980
1475
|
const pn = schema.propertyNames;
|
|
981
1476
|
if (typeof pn === "boolean") {
|
|
982
|
-
if (pn === false
|
|
983
|
-
|
|
1477
|
+
if (pn === false) {
|
|
1478
|
+
for (const key in data) {
|
|
1479
|
+
if (Object.prototype.hasOwnProperty.call(data, key)) {
|
|
1480
|
+
return defineError("Properties are not allowed", { data });
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
984
1483
|
}
|
|
985
1484
|
return;
|
|
986
1485
|
}
|
|
@@ -1003,7 +1502,7 @@ var ObjectKeywords = {
|
|
|
1003
1502
|
}
|
|
1004
1503
|
},
|
|
1005
1504
|
dependencies(schema, data, defineError) {
|
|
1006
|
-
if (!
|
|
1505
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
1007
1506
|
return;
|
|
1008
1507
|
}
|
|
1009
1508
|
for (const key in schema.dependencies) {
|
|
@@ -1065,99 +1564,194 @@ var ObjectKeywords = {
|
|
|
1065
1564
|
};
|
|
1066
1565
|
|
|
1067
1566
|
// lib/keywords/other-keywords.ts
|
|
1567
|
+
function toBranchEntry(item) {
|
|
1568
|
+
if (item && typeof item === "object" && !Array.isArray(item)) {
|
|
1569
|
+
if ("$validate" in item && typeof item.$validate === "function") {
|
|
1570
|
+
return { kind: "validate", validate: item.$validate };
|
|
1571
|
+
}
|
|
1572
|
+
return { kind: "alwaysValid" };
|
|
1573
|
+
}
|
|
1574
|
+
if (typeof item === "boolean") {
|
|
1575
|
+
return { kind: item ? "alwaysValid" : "alwaysInvalid" };
|
|
1576
|
+
}
|
|
1577
|
+
return { kind: "literal", value: item };
|
|
1578
|
+
}
|
|
1579
|
+
function getBranchEntries(schema, key) {
|
|
1580
|
+
const cacheKey = `_${key}BranchEntries`;
|
|
1581
|
+
let entries = schema[cacheKey];
|
|
1582
|
+
if (entries) {
|
|
1583
|
+
return entries;
|
|
1584
|
+
}
|
|
1585
|
+
const source = schema[key] || [];
|
|
1586
|
+
entries = [];
|
|
1587
|
+
for (let i = 0; i < source.length; i++) {
|
|
1588
|
+
entries.push(toBranchEntry(source[i]));
|
|
1589
|
+
}
|
|
1590
|
+
Object.defineProperty(schema, cacheKey, {
|
|
1591
|
+
value: entries,
|
|
1592
|
+
enumerable: false,
|
|
1593
|
+
configurable: false,
|
|
1594
|
+
writable: false
|
|
1595
|
+
});
|
|
1596
|
+
return entries;
|
|
1597
|
+
}
|
|
1068
1598
|
var OtherKeywords = {
|
|
1069
1599
|
enum(schema, data, defineError) {
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
const
|
|
1073
|
-
|
|
1074
|
-
|
|
1600
|
+
let enumCache = schema._enumCache;
|
|
1601
|
+
if (!enumCache) {
|
|
1602
|
+
const primitiveSet = /* @__PURE__ */ new Set();
|
|
1603
|
+
const objectValues = [];
|
|
1604
|
+
const list = schema.enum;
|
|
1605
|
+
for (let i = 0; i < list.length; i++) {
|
|
1606
|
+
const enumItem = list[i];
|
|
1607
|
+
if (enumItem !== null && typeof enumItem === "object") {
|
|
1608
|
+
objectValues.push(enumItem);
|
|
1609
|
+
} else {
|
|
1610
|
+
primitiveSet.add(enumItem);
|
|
1611
|
+
}
|
|
1075
1612
|
}
|
|
1076
|
-
|
|
1077
|
-
|
|
1613
|
+
enumCache = { primitiveSet, objectValues };
|
|
1614
|
+
Object.defineProperty(schema, "_enumCache", {
|
|
1615
|
+
value: enumCache,
|
|
1616
|
+
enumerable: false,
|
|
1617
|
+
configurable: false,
|
|
1618
|
+
writable: false
|
|
1619
|
+
});
|
|
1620
|
+
}
|
|
1621
|
+
if (!(typeof data === "number" && Number.isNaN(data)) && enumCache.primitiveSet.has(data)) {
|
|
1622
|
+
return;
|
|
1623
|
+
}
|
|
1624
|
+
if (data !== null && typeof data === "object") {
|
|
1625
|
+
for (let i = 0; i < enumCache.objectValues.length; i++) {
|
|
1626
|
+
if (!hasChanged(enumCache.objectValues[i], data)) {
|
|
1627
|
+
return;
|
|
1628
|
+
}
|
|
1078
1629
|
}
|
|
1079
1630
|
}
|
|
1080
1631
|
return defineError("Value is not one of the allowed values", { data });
|
|
1081
1632
|
},
|
|
1082
1633
|
allOf(schema, data, defineError) {
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
}
|
|
1634
|
+
const branches = getBranchEntries(schema, "allOf");
|
|
1635
|
+
if (branches.length === 1) {
|
|
1636
|
+
const onlyBranch = branches[0];
|
|
1637
|
+
if (onlyBranch.kind === "validate") {
|
|
1638
|
+
const error = onlyBranch.validate(data);
|
|
1639
|
+
if (error) {
|
|
1640
|
+
return defineError("Value is not valid", { cause: error, data });
|
|
1090
1641
|
}
|
|
1091
|
-
|
|
1642
|
+
return;
|
|
1092
1643
|
}
|
|
1093
|
-
if (
|
|
1094
|
-
|
|
1095
|
-
|
|
1644
|
+
if (onlyBranch.kind === "alwaysValid") {
|
|
1645
|
+
return;
|
|
1646
|
+
}
|
|
1647
|
+
if (onlyBranch.kind === "alwaysInvalid") {
|
|
1648
|
+
return defineError("Value is not valid", { data });
|
|
1649
|
+
}
|
|
1650
|
+
if (data !== onlyBranch.value) {
|
|
1651
|
+
return defineError("Value is not valid", { data });
|
|
1652
|
+
}
|
|
1653
|
+
return;
|
|
1654
|
+
}
|
|
1655
|
+
for (let i = 0; i < branches.length; i++) {
|
|
1656
|
+
const branch = branches[i];
|
|
1657
|
+
if (branch.kind === "validate") {
|
|
1658
|
+
const error = branch.validate(data);
|
|
1659
|
+
if (error) {
|
|
1660
|
+
return defineError("Value is not valid", { cause: error, data });
|
|
1096
1661
|
}
|
|
1097
1662
|
continue;
|
|
1098
1663
|
}
|
|
1099
|
-
if (
|
|
1664
|
+
if (branch.kind === "alwaysValid") {
|
|
1665
|
+
continue;
|
|
1666
|
+
}
|
|
1667
|
+
if (branch.kind === "alwaysInvalid") {
|
|
1668
|
+
return defineError("Value is not valid", { data });
|
|
1669
|
+
}
|
|
1670
|
+
if (data !== branch.value) {
|
|
1100
1671
|
return defineError("Value is not valid", { data });
|
|
1101
1672
|
}
|
|
1102
1673
|
}
|
|
1103
1674
|
return;
|
|
1104
1675
|
},
|
|
1105
1676
|
anyOf(schema, data, defineError) {
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
continue;
|
|
1677
|
+
const branches = getBranchEntries(schema, "anyOf");
|
|
1678
|
+
if (branches.length === 1) {
|
|
1679
|
+
const onlyBranch = branches[0];
|
|
1680
|
+
if (onlyBranch.kind === "validate") {
|
|
1681
|
+
const error = onlyBranch.validate(data);
|
|
1682
|
+
if (!error) {
|
|
1683
|
+
return;
|
|
1114
1684
|
}
|
|
1685
|
+
return defineError("Value is not valid", { data });
|
|
1686
|
+
}
|
|
1687
|
+
if (onlyBranch.kind === "alwaysValid") {
|
|
1115
1688
|
return;
|
|
1116
|
-
}
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1689
|
+
}
|
|
1690
|
+
if (onlyBranch.kind === "alwaysInvalid") {
|
|
1691
|
+
return defineError("Value is not valid", { data });
|
|
1692
|
+
}
|
|
1693
|
+
if (data === onlyBranch.value) {
|
|
1694
|
+
return;
|
|
1695
|
+
}
|
|
1696
|
+
return defineError("Value is not valid", { data });
|
|
1697
|
+
}
|
|
1698
|
+
for (let i = 0; i < branches.length; i++) {
|
|
1699
|
+
const branch = branches[i];
|
|
1700
|
+
if (branch.kind === "validate") {
|
|
1701
|
+
const error = branch.validate(data);
|
|
1702
|
+
if (!error) {
|
|
1123
1703
|
return;
|
|
1124
1704
|
}
|
|
1705
|
+
continue;
|
|
1706
|
+
}
|
|
1707
|
+
if (branch.kind === "alwaysValid") {
|
|
1708
|
+
return;
|
|
1709
|
+
}
|
|
1710
|
+
if (branch.kind === "alwaysInvalid") {
|
|
1711
|
+
continue;
|
|
1712
|
+
}
|
|
1713
|
+
if (data === branch.value) {
|
|
1714
|
+
return;
|
|
1125
1715
|
}
|
|
1126
1716
|
}
|
|
1127
1717
|
return defineError("Value is not valid", { data });
|
|
1128
1718
|
},
|
|
1129
1719
|
oneOf(schema, data, defineError) {
|
|
1130
|
-
const
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
if (
|
|
1136
|
-
|
|
1137
|
-
if (!error) {
|
|
1138
|
-
validCount++;
|
|
1139
|
-
if (validCount > 1) {
|
|
1140
|
-
return defineError("Value is not valid", { data });
|
|
1141
|
-
}
|
|
1142
|
-
}
|
|
1143
|
-
continue;
|
|
1144
|
-
}
|
|
1145
|
-
validCount++;
|
|
1146
|
-
if (validCount > 1) {
|
|
1147
|
-
return defineError("Value is not valid", { data });
|
|
1720
|
+
const branches = getBranchEntries(schema, "oneOf");
|
|
1721
|
+
if (branches.length === 1) {
|
|
1722
|
+
const onlyBranch = branches[0];
|
|
1723
|
+
if (onlyBranch.kind === "validate") {
|
|
1724
|
+
const error = onlyBranch.validate(data);
|
|
1725
|
+
if (!error) {
|
|
1726
|
+
return;
|
|
1148
1727
|
}
|
|
1149
|
-
|
|
1728
|
+
return defineError("Value is not valid", { data });
|
|
1150
1729
|
}
|
|
1151
|
-
if (
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1730
|
+
if (onlyBranch.kind === "alwaysValid") {
|
|
1731
|
+
return;
|
|
1732
|
+
}
|
|
1733
|
+
if (onlyBranch.kind === "alwaysInvalid") {
|
|
1734
|
+
return defineError("Value is not valid", { data });
|
|
1735
|
+
}
|
|
1736
|
+
if (data === onlyBranch.value) {
|
|
1737
|
+
return;
|
|
1738
|
+
}
|
|
1739
|
+
return defineError("Value is not valid", { data });
|
|
1740
|
+
}
|
|
1741
|
+
let validCount = 0;
|
|
1742
|
+
for (let i = 0; i < branches.length; i++) {
|
|
1743
|
+
const branch = branches[i];
|
|
1744
|
+
let isValid = false;
|
|
1745
|
+
if (branch.kind === "validate") {
|
|
1746
|
+
isValid = !branch.validate(data);
|
|
1747
|
+
} else if (branch.kind === "alwaysValid") {
|
|
1748
|
+
isValid = true;
|
|
1749
|
+
} else if (branch.kind === "alwaysInvalid") {
|
|
1750
|
+
isValid = false;
|
|
1751
|
+
} else {
|
|
1752
|
+
isValid = data === branch.value;
|
|
1159
1753
|
}
|
|
1160
|
-
if (
|
|
1754
|
+
if (isValid) {
|
|
1161
1755
|
validCount++;
|
|
1162
1756
|
if (validCount > 1) {
|
|
1163
1757
|
return defineError("Value is not valid", { data });
|
|
@@ -1173,7 +1767,7 @@ var OtherKeywords = {
|
|
|
1173
1767
|
if (data === schema.const) {
|
|
1174
1768
|
return;
|
|
1175
1769
|
}
|
|
1176
|
-
if (
|
|
1770
|
+
if (data && typeof data === "object" && !Array.isArray(data) && schema.const && typeof schema.const === "object" && !Array.isArray(schema.const) && !hasChanged(data, schema.const) || Array.isArray(data) && Array.isArray(schema.const) && !hasChanged(data, schema.const)) {
|
|
1177
1771
|
return;
|
|
1178
1772
|
}
|
|
1179
1773
|
return defineError("Value is not valid", { data });
|
|
@@ -1215,11 +1809,11 @@ var OtherKeywords = {
|
|
|
1215
1809
|
}
|
|
1216
1810
|
return;
|
|
1217
1811
|
}
|
|
1218
|
-
if (
|
|
1812
|
+
if (schema.not && typeof schema.not === "object" && !Array.isArray(schema.not)) {
|
|
1219
1813
|
if ("$validate" in schema.not) {
|
|
1220
1814
|
const error = schema.not.$validate(data);
|
|
1221
1815
|
if (!error) {
|
|
1222
|
-
return defineError("Value is not valid", {
|
|
1816
|
+
return defineError("Value is not valid", { data });
|
|
1223
1817
|
}
|
|
1224
1818
|
return;
|
|
1225
1819
|
}
|
|
@@ -1229,6 +1823,9 @@ var OtherKeywords = {
|
|
|
1229
1823
|
},
|
|
1230
1824
|
$ref(schema, data, defineError, instance) {
|
|
1231
1825
|
if (schema._resolvedRef) {
|
|
1826
|
+
if (schema.$validate !== schema._resolvedRef) {
|
|
1827
|
+
schema.$validate = schema._resolvedRef;
|
|
1828
|
+
}
|
|
1232
1829
|
return schema._resolvedRef(data);
|
|
1233
1830
|
}
|
|
1234
1831
|
const refPath = schema.$ref;
|
|
@@ -1243,11 +1840,14 @@ var OtherKeywords = {
|
|
|
1243
1840
|
return;
|
|
1244
1841
|
}
|
|
1245
1842
|
schema._resolvedRef = targetSchema.$validate;
|
|
1843
|
+
schema.$validate = schema._resolvedRef;
|
|
1246
1844
|
return schema._resolvedRef(data);
|
|
1247
1845
|
}
|
|
1248
1846
|
};
|
|
1249
1847
|
|
|
1250
1848
|
// lib/keywords/string-keywords.ts
|
|
1849
|
+
var PATTERN_MATCH_CACHE_LIMIT = 512;
|
|
1850
|
+
var FORMAT_RESULT_CACHE_LIMIT = 512;
|
|
1251
1851
|
var StringKeywords = {
|
|
1252
1852
|
minLength(schema, data, defineError) {
|
|
1253
1853
|
if (typeof data !== "string" || data.length >= schema.minLength) {
|
|
@@ -1265,12 +1865,14 @@ var StringKeywords = {
|
|
|
1265
1865
|
if (typeof data !== "string") {
|
|
1266
1866
|
return;
|
|
1267
1867
|
}
|
|
1268
|
-
let
|
|
1269
|
-
|
|
1868
|
+
let patternMatch = schema._patternMatch;
|
|
1869
|
+
let patternMatchCache = schema._patternMatchCache;
|
|
1870
|
+
if (!patternMatch) {
|
|
1270
1871
|
try {
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1872
|
+
const compiled = compilePatternMatcher(schema.pattern);
|
|
1873
|
+
patternMatch = compiled instanceof RegExp ? (value) => compiled.test(value) : compiled;
|
|
1874
|
+
Object.defineProperty(schema, "_patternMatch", {
|
|
1875
|
+
value: patternMatch,
|
|
1274
1876
|
enumerable: false,
|
|
1275
1877
|
configurable: false,
|
|
1276
1878
|
writable: false
|
|
@@ -1282,7 +1884,25 @@ var StringKeywords = {
|
|
|
1282
1884
|
});
|
|
1283
1885
|
}
|
|
1284
1886
|
}
|
|
1285
|
-
if (
|
|
1887
|
+
if (!patternMatchCache) {
|
|
1888
|
+
patternMatchCache = /* @__PURE__ */ new Map();
|
|
1889
|
+
Object.defineProperty(schema, "_patternMatchCache", {
|
|
1890
|
+
value: patternMatchCache,
|
|
1891
|
+
enumerable: false,
|
|
1892
|
+
configurable: false,
|
|
1893
|
+
writable: false
|
|
1894
|
+
});
|
|
1895
|
+
} else if (patternMatchCache.has(data)) {
|
|
1896
|
+
if (patternMatchCache.get(data)) {
|
|
1897
|
+
return;
|
|
1898
|
+
}
|
|
1899
|
+
return defineError("Value does not match the pattern", { data });
|
|
1900
|
+
}
|
|
1901
|
+
const isMatch = patternMatch(data);
|
|
1902
|
+
if (patternMatchCache.size < PATTERN_MATCH_CACHE_LIMIT) {
|
|
1903
|
+
patternMatchCache.set(data, isMatch);
|
|
1904
|
+
}
|
|
1905
|
+
if (isMatch) {
|
|
1286
1906
|
return;
|
|
1287
1907
|
}
|
|
1288
1908
|
return defineError("Value does not match the pattern", { data });
|
|
@@ -1294,6 +1914,8 @@ var StringKeywords = {
|
|
|
1294
1914
|
return;
|
|
1295
1915
|
}
|
|
1296
1916
|
let formatValidate = schema._formatValidate;
|
|
1917
|
+
let formatResultCacheEnabled = schema._formatResultCacheEnabled;
|
|
1918
|
+
let formatResultCache = schema._formatResultCache;
|
|
1297
1919
|
if (formatValidate === void 0) {
|
|
1298
1920
|
formatValidate = instance.getFormat(schema.format);
|
|
1299
1921
|
Object.defineProperty(schema, "_formatValidate", {
|
|
@@ -1303,7 +1925,46 @@ var StringKeywords = {
|
|
|
1303
1925
|
writable: false
|
|
1304
1926
|
});
|
|
1305
1927
|
}
|
|
1306
|
-
if (!formatValidate
|
|
1928
|
+
if (!formatValidate) {
|
|
1929
|
+
return;
|
|
1930
|
+
}
|
|
1931
|
+
if (formatResultCacheEnabled === void 0) {
|
|
1932
|
+
formatResultCacheEnabled = instance.isDefaultFormatValidator(
|
|
1933
|
+
schema.format,
|
|
1934
|
+
formatValidate
|
|
1935
|
+
);
|
|
1936
|
+
Object.defineProperty(schema, "_formatResultCacheEnabled", {
|
|
1937
|
+
value: formatResultCacheEnabled,
|
|
1938
|
+
enumerable: false,
|
|
1939
|
+
configurable: false,
|
|
1940
|
+
writable: false
|
|
1941
|
+
});
|
|
1942
|
+
}
|
|
1943
|
+
if (!formatResultCacheEnabled) {
|
|
1944
|
+
if (formatValidate(data)) {
|
|
1945
|
+
return;
|
|
1946
|
+
}
|
|
1947
|
+
return defineError("Value does not match the format", { data });
|
|
1948
|
+
}
|
|
1949
|
+
if (!formatResultCache) {
|
|
1950
|
+
formatResultCache = /* @__PURE__ */ new Map();
|
|
1951
|
+
Object.defineProperty(schema, "_formatResultCache", {
|
|
1952
|
+
value: formatResultCache,
|
|
1953
|
+
enumerable: false,
|
|
1954
|
+
configurable: false,
|
|
1955
|
+
writable: false
|
|
1956
|
+
});
|
|
1957
|
+
} else if (formatResultCache.has(data)) {
|
|
1958
|
+
if (formatResultCache.get(data)) {
|
|
1959
|
+
return;
|
|
1960
|
+
}
|
|
1961
|
+
return defineError("Value does not match the format", { data });
|
|
1962
|
+
}
|
|
1963
|
+
const isValid = formatValidate(data);
|
|
1964
|
+
if (formatResultCache.size < FORMAT_RESULT_CACHE_LIMIT) {
|
|
1965
|
+
formatResultCache.set(data, isValid);
|
|
1966
|
+
}
|
|
1967
|
+
if (isValid) {
|
|
1307
1968
|
return;
|
|
1308
1969
|
}
|
|
1309
1970
|
return defineError("Value does not match the format", { data });
|
|
@@ -1366,6 +2027,9 @@ var SchemaShield = class {
|
|
|
1366
2027
|
getFormat(format) {
|
|
1367
2028
|
return this.formats[format];
|
|
1368
2029
|
}
|
|
2030
|
+
isDefaultFormatValidator(format, validator) {
|
|
2031
|
+
return Formats[format] === validator;
|
|
2032
|
+
}
|
|
1369
2033
|
addKeyword(name, validator, overwrite = false) {
|
|
1370
2034
|
if (this.keywords[name] && !overwrite) {
|
|
1371
2035
|
throw new ValidationError(`Keyword "${name}" already exists`);
|
|
@@ -1388,20 +2052,39 @@ var SchemaShield = class {
|
|
|
1388
2052
|
this.idRegistry.clear();
|
|
1389
2053
|
const compiledSchema = this.compileSchema(schema);
|
|
1390
2054
|
this.rootSchema = compiledSchema;
|
|
1391
|
-
|
|
2055
|
+
if (compiledSchema._hasRef === true) {
|
|
2056
|
+
this.linkReferences(compiledSchema);
|
|
2057
|
+
}
|
|
1392
2058
|
if (!compiledSchema.$validate) {
|
|
1393
|
-
if (
|
|
2059
|
+
if (schema === false) {
|
|
2060
|
+
const defineError = getDefinedErrorFunctionForKey(
|
|
2061
|
+
"oneOf",
|
|
2062
|
+
compiledSchema,
|
|
2063
|
+
this.failFast
|
|
2064
|
+
);
|
|
2065
|
+
compiledSchema.$validate = getNamedFunction(
|
|
2066
|
+
"Validate_False",
|
|
2067
|
+
(data) => defineError("Value is not valid", { data })
|
|
2068
|
+
);
|
|
2069
|
+
} else if (schema === true) {
|
|
2070
|
+
compiledSchema.$validate = getNamedFunction(
|
|
2071
|
+
"Validate_Any",
|
|
2072
|
+
() => {
|
|
2073
|
+
}
|
|
2074
|
+
);
|
|
2075
|
+
} else if (this.isSchemaLike(schema) === false) {
|
|
1394
2076
|
throw new ValidationError("Invalid schema");
|
|
2077
|
+
} else {
|
|
2078
|
+
compiledSchema.$validate = getNamedFunction(
|
|
2079
|
+
"Validate_Any",
|
|
2080
|
+
() => {
|
|
2081
|
+
}
|
|
2082
|
+
);
|
|
1395
2083
|
}
|
|
1396
|
-
compiledSchema.$validate = getNamedFunction(
|
|
1397
|
-
"Validate_Any",
|
|
1398
|
-
() => {
|
|
1399
|
-
}
|
|
1400
|
-
);
|
|
1401
2084
|
}
|
|
1402
2085
|
const validate = (data) => {
|
|
1403
2086
|
this.rootSchema = compiledSchema;
|
|
1404
|
-
const clonedData = this.immutable ?
|
|
2087
|
+
const clonedData = this.immutable ? deepCloneUnfreeze(data) : data;
|
|
1405
2088
|
const res = compiledSchema.$validate(clonedData);
|
|
1406
2089
|
if (res) {
|
|
1407
2090
|
return { data: clonedData, error: res, valid: false };
|
|
@@ -1411,8 +2094,181 @@ var SchemaShield = class {
|
|
|
1411
2094
|
validate.compiledSchema = compiledSchema;
|
|
1412
2095
|
return validate;
|
|
1413
2096
|
}
|
|
2097
|
+
isPlainObject(value) {
|
|
2098
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
2099
|
+
}
|
|
2100
|
+
isTrivialAlwaysValidSubschema(value) {
|
|
2101
|
+
return value === true || this.isPlainObject(value) && Object.keys(value).length === 0;
|
|
2102
|
+
}
|
|
2103
|
+
shallowArrayEquals(a, b) {
|
|
2104
|
+
if (a === b) {
|
|
2105
|
+
return true;
|
|
2106
|
+
}
|
|
2107
|
+
if (a.length !== b.length) {
|
|
2108
|
+
return false;
|
|
2109
|
+
}
|
|
2110
|
+
for (let i = 0; i < a.length; i++) {
|
|
2111
|
+
if (a[i] !== b[i]) {
|
|
2112
|
+
return false;
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
return true;
|
|
2116
|
+
}
|
|
2117
|
+
flattenAssociativeBranches(key, branches) {
|
|
2118
|
+
const out = [];
|
|
2119
|
+
for (let i = 0; i < branches.length; i++) {
|
|
2120
|
+
const item = branches[i];
|
|
2121
|
+
if (this.isPlainObject(item) && Object.keys(item).length === 1 && Array.isArray(item[key])) {
|
|
2122
|
+
const nested = this.flattenAssociativeBranches(key, item[key]);
|
|
2123
|
+
for (let j = 0; j < nested.length; j++) {
|
|
2124
|
+
out.push(nested[j]);
|
|
2125
|
+
}
|
|
2126
|
+
continue;
|
|
2127
|
+
}
|
|
2128
|
+
out.push(item);
|
|
2129
|
+
}
|
|
2130
|
+
return out;
|
|
2131
|
+
}
|
|
2132
|
+
flattenSingleWrapperOneOf(branches) {
|
|
2133
|
+
let current = branches;
|
|
2134
|
+
while (current.length === 1) {
|
|
2135
|
+
const item = current[0];
|
|
2136
|
+
if (this.isPlainObject(item) && Object.keys(item).length === 1 && Array.isArray(item.oneOf)) {
|
|
2137
|
+
current = item.oneOf;
|
|
2138
|
+
continue;
|
|
2139
|
+
}
|
|
2140
|
+
break;
|
|
2141
|
+
}
|
|
2142
|
+
return current;
|
|
2143
|
+
}
|
|
2144
|
+
normalizeSchemaForCompile(schema) {
|
|
2145
|
+
let normalized = schema;
|
|
2146
|
+
const schemaKeys = Object.keys(schema);
|
|
2147
|
+
const hasOnlyKey = (key) => schemaKeys.length === 1 && schemaKeys[0] === key;
|
|
2148
|
+
const setNormalized = (key, value) => {
|
|
2149
|
+
if (normalized === schema) {
|
|
2150
|
+
normalized = { ...schema };
|
|
2151
|
+
}
|
|
2152
|
+
normalized[key] = value;
|
|
2153
|
+
};
|
|
2154
|
+
if (Array.isArray(schema.allOf)) {
|
|
2155
|
+
const flattenedAllOf = this.flattenAssociativeBranches(
|
|
2156
|
+
"allOf",
|
|
2157
|
+
schema.allOf
|
|
2158
|
+
).filter(
|
|
2159
|
+
(item) => !(this.isPlainObject(item) && Object.keys(item).length === 0)
|
|
2160
|
+
);
|
|
2161
|
+
if (hasOnlyKey("allOf") && flattenedAllOf.length === 1 && this.isPlainObject(flattenedAllOf[0])) {
|
|
2162
|
+
return flattenedAllOf[0];
|
|
2163
|
+
}
|
|
2164
|
+
if (!this.shallowArrayEquals(flattenedAllOf, schema.allOf)) {
|
|
2165
|
+
setNormalized("allOf", flattenedAllOf);
|
|
2166
|
+
}
|
|
2167
|
+
}
|
|
2168
|
+
if (Array.isArray(schema.anyOf)) {
|
|
2169
|
+
const flattenedAnyOf = this.flattenAssociativeBranches(
|
|
2170
|
+
"anyOf",
|
|
2171
|
+
schema.anyOf
|
|
2172
|
+
);
|
|
2173
|
+
if (hasOnlyKey("anyOf") && flattenedAnyOf.length === 1 && this.isPlainObject(flattenedAnyOf[0])) {
|
|
2174
|
+
return flattenedAnyOf[0];
|
|
2175
|
+
}
|
|
2176
|
+
if (!this.shallowArrayEquals(flattenedAnyOf, schema.anyOf)) {
|
|
2177
|
+
setNormalized("anyOf", flattenedAnyOf);
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
if (Array.isArray(schema.oneOf)) {
|
|
2181
|
+
const flattenedOneOf = this.flattenSingleWrapperOneOf(schema.oneOf);
|
|
2182
|
+
if (hasOnlyKey("oneOf") && flattenedOneOf.length === 1 && this.isPlainObject(flattenedOneOf[0])) {
|
|
2183
|
+
return flattenedOneOf[0];
|
|
2184
|
+
}
|
|
2185
|
+
if (!this.shallowArrayEquals(flattenedOneOf, schema.oneOf)) {
|
|
2186
|
+
setNormalized("oneOf", flattenedOneOf);
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
return normalized;
|
|
2190
|
+
}
|
|
2191
|
+
markSchemaHasRef(schema) {
|
|
2192
|
+
if (schema._hasRef === true) {
|
|
2193
|
+
return;
|
|
2194
|
+
}
|
|
2195
|
+
Object.defineProperty(schema, "_hasRef", {
|
|
2196
|
+
value: true,
|
|
2197
|
+
enumerable: false,
|
|
2198
|
+
configurable: false,
|
|
2199
|
+
writable: false
|
|
2200
|
+
});
|
|
2201
|
+
}
|
|
2202
|
+
shouldSkipKeyword(schema, key) {
|
|
2203
|
+
const value = schema[key];
|
|
2204
|
+
switch (key) {
|
|
2205
|
+
case "required":
|
|
2206
|
+
return Array.isArray(value) && value.length === 0;
|
|
2207
|
+
case "uniqueItems":
|
|
2208
|
+
return value === false;
|
|
2209
|
+
case "properties":
|
|
2210
|
+
case "patternProperties":
|
|
2211
|
+
case "dependencies":
|
|
2212
|
+
return this.isPlainObject(value) && Object.keys(value).length === 0;
|
|
2213
|
+
case "propertyNames":
|
|
2214
|
+
case "items":
|
|
2215
|
+
return value === true;
|
|
2216
|
+
case "additionalProperties":
|
|
2217
|
+
if (value === true) {
|
|
2218
|
+
return true;
|
|
2219
|
+
}
|
|
2220
|
+
return value === false && this.isPlainObject(schema.patternProperties) && Object.keys(schema.patternProperties).length > 0;
|
|
2221
|
+
case "additionalItems":
|
|
2222
|
+
return value === true || !Array.isArray(schema.items);
|
|
2223
|
+
case "allOf": {
|
|
2224
|
+
if (!Array.isArray(value)) {
|
|
2225
|
+
return false;
|
|
2226
|
+
}
|
|
2227
|
+
if (value.length === 0) {
|
|
2228
|
+
return true;
|
|
2229
|
+
}
|
|
2230
|
+
for (let i = 0; i < value.length; i++) {
|
|
2231
|
+
if (this.isTrivialAlwaysValidSubschema(value[i])) {
|
|
2232
|
+
continue;
|
|
2233
|
+
}
|
|
2234
|
+
return false;
|
|
2235
|
+
}
|
|
2236
|
+
return true;
|
|
2237
|
+
}
|
|
2238
|
+
case "anyOf": {
|
|
2239
|
+
if (!Array.isArray(value)) {
|
|
2240
|
+
return false;
|
|
2241
|
+
}
|
|
2242
|
+
for (let i = 0; i < value.length; i++) {
|
|
2243
|
+
if (this.isTrivialAlwaysValidSubschema(value[i])) {
|
|
2244
|
+
return true;
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
return false;
|
|
2248
|
+
}
|
|
2249
|
+
default:
|
|
2250
|
+
return false;
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
hasRequiredDefaults(schema) {
|
|
2254
|
+
const properties = schema.properties;
|
|
2255
|
+
if (!this.isPlainObject(properties)) {
|
|
2256
|
+
return false;
|
|
2257
|
+
}
|
|
2258
|
+
const keys = Object.keys(properties);
|
|
2259
|
+
for (let i = 0; i < keys.length; i++) {
|
|
2260
|
+
const subSchema = properties[keys[i]];
|
|
2261
|
+
if (this.isPlainObject(subSchema) && "default" in subSchema) {
|
|
2262
|
+
return true;
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
return false;
|
|
2266
|
+
}
|
|
2267
|
+
isDefaultTypeValidator(type, validator) {
|
|
2268
|
+
return Types[type] === validator;
|
|
2269
|
+
}
|
|
1414
2270
|
compileSchema(schema) {
|
|
1415
|
-
if (!
|
|
2271
|
+
if (!schema || typeof schema !== "object" || Array.isArray(schema)) {
|
|
1416
2272
|
if (schema === true) {
|
|
1417
2273
|
schema = { anyOf: [{}] };
|
|
1418
2274
|
} else if (schema === false) {
|
|
@@ -1421,11 +2277,16 @@ var SchemaShield = class {
|
|
|
1421
2277
|
schema = { oneOf: [schema] };
|
|
1422
2278
|
}
|
|
1423
2279
|
}
|
|
1424
|
-
|
|
2280
|
+
schema = this.normalizeSchemaForCompile(schema);
|
|
2281
|
+
const compiledSchema = deepCloneUnfreeze(
|
|
2282
|
+
schema
|
|
2283
|
+
);
|
|
2284
|
+
let schemaHasRef = false;
|
|
1425
2285
|
if (typeof schema.$id === "string") {
|
|
1426
2286
|
this.idRegistry.set(schema.$id, compiledSchema);
|
|
1427
2287
|
}
|
|
1428
2288
|
if ("$ref" in schema) {
|
|
2289
|
+
schemaHasRef = true;
|
|
1429
2290
|
const refValidator = this.getKeyword("$ref");
|
|
1430
2291
|
if (refValidator) {
|
|
1431
2292
|
const defineError = getDefinedErrorFunctionForKey(
|
|
@@ -1443,6 +2304,7 @@ var SchemaShield = class {
|
|
|
1443
2304
|
)
|
|
1444
2305
|
);
|
|
1445
2306
|
}
|
|
2307
|
+
this.markSchemaHasRef(compiledSchema);
|
|
1446
2308
|
return compiledSchema;
|
|
1447
2309
|
}
|
|
1448
2310
|
const validators = [];
|
|
@@ -1456,11 +2318,18 @@ var SchemaShield = class {
|
|
|
1456
2318
|
const types = Array.isArray(schema.type) ? schema.type : schema.type.split(",").map((t) => t.trim());
|
|
1457
2319
|
const typeFunctions = [];
|
|
1458
2320
|
const typeNames = [];
|
|
2321
|
+
const defaultTypeNames = [];
|
|
2322
|
+
let allTypesDefault = true;
|
|
1459
2323
|
for (const type2 of types) {
|
|
1460
2324
|
const validator = this.getType(type2);
|
|
1461
2325
|
if (validator) {
|
|
1462
2326
|
typeFunctions.push(validator);
|
|
1463
2327
|
typeNames.push(validator.name);
|
|
2328
|
+
if (this.isDefaultTypeValidator(type2, validator)) {
|
|
2329
|
+
defaultTypeNames.push(type2);
|
|
2330
|
+
} else {
|
|
2331
|
+
allTypesDefault = false;
|
|
2332
|
+
}
|
|
1464
2333
|
}
|
|
1465
2334
|
}
|
|
1466
2335
|
if (typeFunctions.length === 0) {
|
|
@@ -1472,7 +2341,118 @@ var SchemaShield = class {
|
|
|
1472
2341
|
}
|
|
1473
2342
|
let combinedTypeValidator;
|
|
1474
2343
|
let typeMethodName = "";
|
|
1475
|
-
if (typeFunctions.length === 1) {
|
|
2344
|
+
if (typeFunctions.length === 1 && allTypesDefault) {
|
|
2345
|
+
const singleTypeName = defaultTypeNames[0];
|
|
2346
|
+
typeMethodName = singleTypeName;
|
|
2347
|
+
switch (singleTypeName) {
|
|
2348
|
+
case "object":
|
|
2349
|
+
combinedTypeValidator = (data) => {
|
|
2350
|
+
if (data === null || typeof data !== "object" || Array.isArray(data)) {
|
|
2351
|
+
return defineTypeError("Invalid type", { data });
|
|
2352
|
+
}
|
|
2353
|
+
};
|
|
2354
|
+
break;
|
|
2355
|
+
case "array":
|
|
2356
|
+
combinedTypeValidator = (data) => {
|
|
2357
|
+
if (!Array.isArray(data)) {
|
|
2358
|
+
return defineTypeError("Invalid type", { data });
|
|
2359
|
+
}
|
|
2360
|
+
};
|
|
2361
|
+
break;
|
|
2362
|
+
case "string":
|
|
2363
|
+
combinedTypeValidator = (data) => {
|
|
2364
|
+
if (typeof data !== "string") {
|
|
2365
|
+
return defineTypeError("Invalid type", { data });
|
|
2366
|
+
}
|
|
2367
|
+
};
|
|
2368
|
+
break;
|
|
2369
|
+
case "number":
|
|
2370
|
+
combinedTypeValidator = (data) => {
|
|
2371
|
+
if (typeof data !== "number") {
|
|
2372
|
+
return defineTypeError("Invalid type", { data });
|
|
2373
|
+
}
|
|
2374
|
+
};
|
|
2375
|
+
break;
|
|
2376
|
+
case "integer":
|
|
2377
|
+
combinedTypeValidator = (data) => {
|
|
2378
|
+
if (typeof data !== "number" || !Number.isInteger(data)) {
|
|
2379
|
+
return defineTypeError("Invalid type", { data });
|
|
2380
|
+
}
|
|
2381
|
+
};
|
|
2382
|
+
break;
|
|
2383
|
+
case "boolean":
|
|
2384
|
+
combinedTypeValidator = (data) => {
|
|
2385
|
+
if (typeof data !== "boolean") {
|
|
2386
|
+
return defineTypeError("Invalid type", { data });
|
|
2387
|
+
}
|
|
2388
|
+
};
|
|
2389
|
+
break;
|
|
2390
|
+
case "null":
|
|
2391
|
+
combinedTypeValidator = (data) => {
|
|
2392
|
+
if (data !== null) {
|
|
2393
|
+
return defineTypeError("Invalid type", { data });
|
|
2394
|
+
}
|
|
2395
|
+
};
|
|
2396
|
+
break;
|
|
2397
|
+
default: {
|
|
2398
|
+
const singleTypeFn = typeFunctions[0];
|
|
2399
|
+
combinedTypeValidator = (data) => {
|
|
2400
|
+
if (!singleTypeFn(data)) {
|
|
2401
|
+
return defineTypeError("Invalid type", { data });
|
|
2402
|
+
}
|
|
2403
|
+
};
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
} else if (typeFunctions.length > 1 && allTypesDefault) {
|
|
2407
|
+
typeMethodName = defaultTypeNames.join("_OR_");
|
|
2408
|
+
const allowsObject = defaultTypeNames.includes("object");
|
|
2409
|
+
const allowsArray = defaultTypeNames.includes("array");
|
|
2410
|
+
const allowsString = defaultTypeNames.includes("string");
|
|
2411
|
+
const allowsNumber = defaultTypeNames.includes("number");
|
|
2412
|
+
const allowsInteger = defaultTypeNames.includes("integer");
|
|
2413
|
+
const allowsBoolean = defaultTypeNames.includes("boolean");
|
|
2414
|
+
const allowsNull = defaultTypeNames.includes("null");
|
|
2415
|
+
combinedTypeValidator = (data) => {
|
|
2416
|
+
const dataType = typeof data;
|
|
2417
|
+
if (dataType === "number") {
|
|
2418
|
+
if (allowsNumber || allowsInteger && Number.isInteger(data)) {
|
|
2419
|
+
return;
|
|
2420
|
+
}
|
|
2421
|
+
return defineTypeError("Invalid type", { data });
|
|
2422
|
+
}
|
|
2423
|
+
if (dataType === "string") {
|
|
2424
|
+
if (allowsString) {
|
|
2425
|
+
return;
|
|
2426
|
+
}
|
|
2427
|
+
return defineTypeError("Invalid type", { data });
|
|
2428
|
+
}
|
|
2429
|
+
if (dataType === "boolean") {
|
|
2430
|
+
if (allowsBoolean) {
|
|
2431
|
+
return;
|
|
2432
|
+
}
|
|
2433
|
+
return defineTypeError("Invalid type", { data });
|
|
2434
|
+
}
|
|
2435
|
+
if (dataType === "object") {
|
|
2436
|
+
if (data === null) {
|
|
2437
|
+
if (allowsNull) {
|
|
2438
|
+
return;
|
|
2439
|
+
}
|
|
2440
|
+
return defineTypeError("Invalid type", { data });
|
|
2441
|
+
}
|
|
2442
|
+
if (Array.isArray(data)) {
|
|
2443
|
+
if (allowsArray) {
|
|
2444
|
+
return;
|
|
2445
|
+
}
|
|
2446
|
+
return defineTypeError("Invalid type", { data });
|
|
2447
|
+
}
|
|
2448
|
+
if (allowsObject) {
|
|
2449
|
+
return;
|
|
2450
|
+
}
|
|
2451
|
+
return defineTypeError("Invalid type", { data });
|
|
2452
|
+
}
|
|
2453
|
+
return defineTypeError("Invalid type", { data });
|
|
2454
|
+
};
|
|
2455
|
+
} else if (typeFunctions.length === 1) {
|
|
1476
2456
|
typeMethodName = typeNames[0];
|
|
1477
2457
|
const singleTypeFn = typeFunctions[0];
|
|
1478
2458
|
combinedTypeValidator = (data) => {
|
|
@@ -1491,72 +2471,90 @@ var SchemaShield = class {
|
|
|
1491
2471
|
return defineTypeError("Invalid type", { data });
|
|
1492
2472
|
};
|
|
1493
2473
|
}
|
|
1494
|
-
const typeAdapter = (_s, data) => combinedTypeValidator(data);
|
|
1495
2474
|
validators.push({
|
|
1496
|
-
|
|
1497
|
-
|
|
2475
|
+
name: typeMethodName,
|
|
2476
|
+
validate: getNamedFunction(typeMethodName, combinedTypeValidator)
|
|
1498
2477
|
});
|
|
1499
2478
|
activeNames.push(typeMethodName);
|
|
1500
2479
|
}
|
|
1501
2480
|
const { type, $id, $ref, $validate, required, ...otherKeys } = schema;
|
|
1502
|
-
const keyOrder = required ? [...Object.keys(otherKeys), "required"] : Object.keys(otherKeys);
|
|
2481
|
+
const keyOrder = required ? this.hasRequiredDefaults(schema) ? [...Object.keys(otherKeys), "required"] : ["required", ...Object.keys(otherKeys)] : Object.keys(otherKeys);
|
|
1503
2482
|
for (const key of keyOrder) {
|
|
1504
2483
|
const keywordFn = this.getKeyword(key);
|
|
1505
|
-
if (keywordFn) {
|
|
1506
|
-
|
|
1507
|
-
key,
|
|
1508
|
-
schema[key],
|
|
1509
|
-
this.failFast
|
|
1510
|
-
);
|
|
1511
|
-
const fnName = keywordFn.name || key;
|
|
1512
|
-
validators.push({
|
|
1513
|
-
fn: keywordFn,
|
|
1514
|
-
defineError
|
|
1515
|
-
});
|
|
1516
|
-
activeNames.push(fnName);
|
|
2484
|
+
if (!keywordFn) {
|
|
2485
|
+
continue;
|
|
1517
2486
|
}
|
|
2487
|
+
if (this.shouldSkipKeyword(schema, key)) {
|
|
2488
|
+
continue;
|
|
2489
|
+
}
|
|
2490
|
+
const defineError = getDefinedErrorFunctionForKey(
|
|
2491
|
+
key,
|
|
2492
|
+
schema[key],
|
|
2493
|
+
this.failFast
|
|
2494
|
+
);
|
|
2495
|
+
const fnName = keywordFn.name || key;
|
|
2496
|
+
validators.push({
|
|
2497
|
+
name: fnName,
|
|
2498
|
+
validate: getNamedFunction(
|
|
2499
|
+
fnName,
|
|
2500
|
+
(data) => keywordFn(compiledSchema, data, defineError, this)
|
|
2501
|
+
)
|
|
2502
|
+
});
|
|
2503
|
+
activeNames.push(fnName);
|
|
1518
2504
|
}
|
|
1519
2505
|
const literalKeywords = ["enum", "const", "default", "examples"];
|
|
1520
2506
|
for (const key of keyOrder) {
|
|
1521
2507
|
if (literalKeywords.includes(key)) {
|
|
1522
2508
|
continue;
|
|
1523
2509
|
}
|
|
1524
|
-
if (
|
|
2510
|
+
if (schema[key] && typeof schema[key] === "object" && !Array.isArray(schema[key])) {
|
|
1525
2511
|
if (key === "properties") {
|
|
1526
2512
|
for (const subKey of Object.keys(schema[key])) {
|
|
1527
|
-
|
|
2513
|
+
const compiledSubSchema2 = this.compileSchema(
|
|
1528
2514
|
schema[key][subKey]
|
|
1529
2515
|
);
|
|
2516
|
+
if (compiledSubSchema2._hasRef === true) {
|
|
2517
|
+
schemaHasRef = true;
|
|
2518
|
+
}
|
|
2519
|
+
compiledSchema[key][subKey] = compiledSubSchema2;
|
|
1530
2520
|
}
|
|
1531
2521
|
continue;
|
|
1532
2522
|
}
|
|
1533
|
-
|
|
2523
|
+
const compiledSubSchema = this.compileSchema(schema[key]);
|
|
2524
|
+
if (compiledSubSchema._hasRef === true) {
|
|
2525
|
+
schemaHasRef = true;
|
|
2526
|
+
}
|
|
2527
|
+
compiledSchema[key] = compiledSubSchema;
|
|
1534
2528
|
continue;
|
|
1535
2529
|
}
|
|
1536
2530
|
if (Array.isArray(schema[key])) {
|
|
1537
2531
|
for (let i = 0; i < schema[key].length; i++) {
|
|
1538
2532
|
if (this.isSchemaLike(schema[key][i])) {
|
|
1539
|
-
|
|
2533
|
+
const compiledSubSchema = this.compileSchema(schema[key][i]);
|
|
2534
|
+
if (compiledSubSchema._hasRef === true) {
|
|
2535
|
+
schemaHasRef = true;
|
|
2536
|
+
}
|
|
2537
|
+
compiledSchema[key][i] = compiledSubSchema;
|
|
1540
2538
|
}
|
|
1541
2539
|
}
|
|
1542
2540
|
continue;
|
|
1543
2541
|
}
|
|
1544
2542
|
}
|
|
2543
|
+
if (schemaHasRef) {
|
|
2544
|
+
this.markSchemaHasRef(compiledSchema);
|
|
2545
|
+
}
|
|
1545
2546
|
if (validators.length === 0) {
|
|
1546
2547
|
return compiledSchema;
|
|
1547
2548
|
}
|
|
1548
2549
|
if (validators.length === 1) {
|
|
1549
2550
|
const v = validators[0];
|
|
1550
|
-
compiledSchema.$validate = getNamedFunction(
|
|
1551
|
-
activeNames[0],
|
|
1552
|
-
(data) => v.fn(compiledSchema, data, v.defineError, this)
|
|
1553
|
-
);
|
|
2551
|
+
compiledSchema.$validate = getNamedFunction(v.name, v.validate);
|
|
1554
2552
|
} else {
|
|
1555
2553
|
const compositeName = "Validate_" + activeNames.join("_AND_");
|
|
1556
2554
|
const masterValidator = (data) => {
|
|
1557
2555
|
for (let i = 0; i < validators.length; i++) {
|
|
1558
2556
|
const v = validators[i];
|
|
1559
|
-
const error = v.
|
|
2557
|
+
const error = v.validate(data);
|
|
1560
2558
|
if (error) {
|
|
1561
2559
|
return error;
|
|
1562
2560
|
}
|
|
@@ -1571,7 +2569,7 @@ var SchemaShield = class {
|
|
|
1571
2569
|
return compiledSchema;
|
|
1572
2570
|
}
|
|
1573
2571
|
isSchemaLike(subSchema) {
|
|
1574
|
-
if (
|
|
2572
|
+
if (subSchema && typeof subSchema === "object" && !Array.isArray(subSchema)) {
|
|
1575
2573
|
if ("type" in subSchema) {
|
|
1576
2574
|
return true;
|
|
1577
2575
|
}
|