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