schema-shield 0.0.5 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +194 -66
- package/dist/formats.d.ts.map +1 -1
- package/dist/index.d.ts +13 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +705 -348
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +705 -348
- 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.d.ts +6 -5
- package/dist/utils.d.ts.map +1 -1
- package/lib/formats.ts +125 -130
- package/lib/index.ts +247 -96
- package/lib/keywords/array-keywords.ts +60 -46
- package/lib/keywords/object-keywords.ts +155 -53
- package/lib/keywords/other-keywords.ts +68 -28
- package/lib/keywords/string-keywords.ts +32 -6
- package/lib/types.ts +1 -13
- package/lib/utils.ts +202 -44
- package/package.json +2 -2
- package/tsconfig.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -53,14 +53,18 @@ var ValidationError = class extends Error {
|
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
55
|
};
|
|
56
|
-
|
|
56
|
+
var FAIL_FAST_DEFINE_ERROR = () => true;
|
|
57
|
+
function getDefinedErrorFunctionForKey(key, schema, failFast) {
|
|
58
|
+
if (failFast) {
|
|
59
|
+
return FAIL_FAST_DEFINE_ERROR;
|
|
60
|
+
}
|
|
57
61
|
const KeywordError = new ValidationError(`Invalid ${key}`);
|
|
58
62
|
KeywordError.keyword = key;
|
|
59
63
|
KeywordError.schema = schema;
|
|
60
64
|
const defineError = (message, options = {}) => {
|
|
61
65
|
KeywordError.message = message;
|
|
62
66
|
KeywordError.item = options.item;
|
|
63
|
-
KeywordError.cause = options.cause;
|
|
67
|
+
KeywordError.cause = options.cause && options.cause !== true ? options.cause : void 0;
|
|
64
68
|
KeywordError.data = options.data;
|
|
65
69
|
return KeywordError;
|
|
66
70
|
};
|
|
@@ -69,34 +73,38 @@ function getDefinedErrorFunctionForKey(key, schema) {
|
|
|
69
73
|
defineError
|
|
70
74
|
);
|
|
71
75
|
}
|
|
72
|
-
function
|
|
73
|
-
if (Array.isArray(
|
|
74
|
-
if (
|
|
75
|
-
return
|
|
76
|
+
function hasChanged(prev, current) {
|
|
77
|
+
if (Array.isArray(prev)) {
|
|
78
|
+
if (Array.isArray(current) === false) {
|
|
79
|
+
return true;
|
|
76
80
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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;
|
|
80
87
|
}
|
|
81
88
|
}
|
|
82
|
-
return
|
|
89
|
+
return false;
|
|
83
90
|
}
|
|
84
|
-
if (typeof
|
|
85
|
-
if (
|
|
86
|
-
return
|
|
91
|
+
if (typeof prev === "object" && prev !== null) {
|
|
92
|
+
if (typeof current !== "object" || current === null) {
|
|
93
|
+
return true;
|
|
87
94
|
}
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
95
|
+
for (const key in current) {
|
|
96
|
+
if (hasChanged(prev[key], current[key])) {
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
91
99
|
}
|
|
92
|
-
for (const key
|
|
93
|
-
if (
|
|
94
|
-
return
|
|
100
|
+
for (const key in prev) {
|
|
101
|
+
if (hasChanged(prev[key], current[key])) {
|
|
102
|
+
return true;
|
|
95
103
|
}
|
|
96
104
|
}
|
|
97
|
-
return
|
|
105
|
+
return false;
|
|
98
106
|
}
|
|
99
|
-
return
|
|
107
|
+
return Object.is(prev, current) === false;
|
|
100
108
|
}
|
|
101
109
|
function isObject(data) {
|
|
102
110
|
return typeof data === "object" && data !== null && !Array.isArray(data);
|
|
@@ -104,27 +112,116 @@ function isObject(data) {
|
|
|
104
112
|
function areCloseEnough(a, b, epsilon = 1e-15) {
|
|
105
113
|
return Math.abs(a - b) <= epsilon * Math.max(Math.abs(a), Math.abs(b));
|
|
106
114
|
}
|
|
107
|
-
function deepClone(obj) {
|
|
108
|
-
if (
|
|
109
|
-
const result = [];
|
|
110
|
-
for (let i = 0; i < obj.length; i++) {
|
|
111
|
-
result[i] = deepClone(obj[i]);
|
|
112
|
-
}
|
|
113
|
-
return result;
|
|
114
|
-
}
|
|
115
|
-
if (obj && obj.constructor && obj.constructor.name !== "Object") {
|
|
115
|
+
function deepClone(obj, cloneClassInstances = false, seen = /* @__PURE__ */ new WeakMap()) {
|
|
116
|
+
if (typeof obj === "undefined" || obj === null || typeof obj !== "object") {
|
|
116
117
|
return obj;
|
|
117
118
|
}
|
|
118
|
-
if (
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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;
|
|
124
214
|
}
|
|
125
|
-
return result;
|
|
126
215
|
}
|
|
127
|
-
|
|
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;
|
|
128
225
|
}
|
|
129
226
|
function isCompiledSchema(subSchema) {
|
|
130
227
|
return isObject(subSchema) && "$validate" in subSchema;
|
|
@@ -132,82 +229,86 @@ function isCompiledSchema(subSchema) {
|
|
|
132
229
|
function getNamedFunction(name, fn) {
|
|
133
230
|
return Object.defineProperty(fn, "name", { value: name });
|
|
134
231
|
}
|
|
232
|
+
function resolvePath(root, path) {
|
|
233
|
+
if (!path || path === "#") {
|
|
234
|
+
return root;
|
|
235
|
+
}
|
|
236
|
+
if (path.startsWith("#/")) {
|
|
237
|
+
const parts = path.split("/").slice(1);
|
|
238
|
+
let current = root;
|
|
239
|
+
for (const part of parts) {
|
|
240
|
+
const decodedUriPart = decodeURIComponent(part);
|
|
241
|
+
const key = decodedUriPart.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
242
|
+
if (current && typeof current === "object" && key in current) {
|
|
243
|
+
current = current[key];
|
|
244
|
+
} else {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return current;
|
|
249
|
+
}
|
|
250
|
+
if (!path.includes("#")) {
|
|
251
|
+
if (root.definitions && root.definitions[path]) {
|
|
252
|
+
return root.definitions[path];
|
|
253
|
+
}
|
|
254
|
+
if (root.defs && root.defs[path]) {
|
|
255
|
+
return root.defs[path];
|
|
256
|
+
}
|
|
257
|
+
if (root.$id && typeof root.$id === "string") {
|
|
258
|
+
if (root.$id === path || root.$id.endsWith("/" + path)) {
|
|
259
|
+
return root;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
135
265
|
|
|
136
266
|
// lib/formats.ts
|
|
267
|
+
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
|
+
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
|
+
var URI_REGEX = /^[a-zA-Z][a-zA-Z0-9+\-.]*:[^\s]*$/;
|
|
271
|
+
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
|
+
var HOSTNAME_REGEX = /^[a-z0-9][a-z0-9-]{0,62}(?:\.[a-z0-9][a-z0-9-]{0,62})*[a-z0-9]$/i;
|
|
279
|
+
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
|
+
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
|
+
var URI_REFERENCE_REGEX = /^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#((?![^#]*\\)[^#]*))?/i;
|
|
284
|
+
var URI_TEMPLATE_REGEX = /^(?:[^{}]|\{[^}]+\})*$/;
|
|
285
|
+
var IRI_REGEX = /^[a-zA-Z][a-zA-Z0-9+\-.]*:[^\s]*$/;
|
|
286
|
+
var IRI_REFERENCE_REGEX = /^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#((?![^#]*\\)[^#]*))?/i;
|
|
287
|
+
var IDN_EMAIL_REGEX = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;
|
|
288
|
+
var IDN_HOSTNAME_REGEX = /^[^\s!@#$%^&*()_+\=\[\]{};':"\\|,<>\/?]+$/;
|
|
289
|
+
var BACK_SLASH_REGEX = /\\/;
|
|
290
|
+
var DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
137
291
|
var Formats = {
|
|
138
292
|
["date-time"](data) {
|
|
139
|
-
const match = data.match(
|
|
140
|
-
/^(\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
|
|
141
|
-
);
|
|
293
|
+
const match = data.match(DATE_TIME_REGEX);
|
|
142
294
|
if (!match) {
|
|
143
295
|
return false;
|
|
144
296
|
}
|
|
145
|
-
|
|
146
|
-
|
|
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
|
+
if (month < 1 || month > 12) {
|
|
147
305
|
return false;
|
|
148
306
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
yearStr,
|
|
152
|
-
monthStr,
|
|
153
|
-
,
|
|
154
|
-
hourStr,
|
|
155
|
-
minuteStr,
|
|
156
|
-
secondStr,
|
|
157
|
-
timezoneSign,
|
|
158
|
-
timezoneHourStr,
|
|
159
|
-
timezoneMinuteStr
|
|
160
|
-
] = match;
|
|
161
|
-
let year = Number(yearStr);
|
|
162
|
-
let month = Number(monthStr);
|
|
163
|
-
let hour = Number(hourStr);
|
|
164
|
-
let minute = Number(minuteStr);
|
|
165
|
-
let second = Number(secondStr);
|
|
166
|
-
if (timezoneSign === "-" || timezoneSign === "+") {
|
|
167
|
-
const timezoneHour = Number(timezoneHourStr);
|
|
168
|
-
const timezoneMinute = Number(timezoneMinuteStr);
|
|
169
|
-
if (timezoneSign === "-") {
|
|
170
|
-
hour += timezoneHour;
|
|
171
|
-
minute += timezoneMinute;
|
|
172
|
-
} else if (timezoneSign === "+") {
|
|
173
|
-
hour -= timezoneHour;
|
|
174
|
-
minute -= timezoneMinute;
|
|
175
|
-
}
|
|
176
|
-
if (minute > 59) {
|
|
177
|
-
hour += 1;
|
|
178
|
-
minute -= 60;
|
|
179
|
-
} else if (minute < 0) {
|
|
180
|
-
hour -= 1;
|
|
181
|
-
minute += 60;
|
|
182
|
-
}
|
|
183
|
-
if (hour > 23) {
|
|
184
|
-
day += 1;
|
|
185
|
-
hour -= 24;
|
|
186
|
-
} else if (hour < 0) {
|
|
187
|
-
day -= 1;
|
|
188
|
-
hour += 24;
|
|
189
|
-
}
|
|
190
|
-
if (day > 31) {
|
|
191
|
-
month += 1;
|
|
192
|
-
day -= 31;
|
|
193
|
-
} else if (day < 1) {
|
|
194
|
-
month -= 1;
|
|
195
|
-
day += 31;
|
|
196
|
-
}
|
|
197
|
-
if (month > 12) {
|
|
198
|
-
year += 1;
|
|
199
|
-
month -= 12;
|
|
200
|
-
} else if (month < 1) {
|
|
201
|
-
year -= 1;
|
|
202
|
-
month += 12;
|
|
203
|
-
}
|
|
204
|
-
if (year < 0) {
|
|
205
|
-
return false;
|
|
206
|
-
}
|
|
307
|
+
if (day < 1) {
|
|
308
|
+
return false;
|
|
207
309
|
}
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
if (day > maxDays) {
|
|
310
|
+
const maxDays = month === 2 ? year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) ? 29 : 28 : DAYS_IN_MONTH[month - 1];
|
|
311
|
+
if (!maxDays || day > maxDays) {
|
|
211
312
|
return false;
|
|
212
313
|
}
|
|
213
314
|
if (second === 60 && (minute !== 59 || hour !== 23)) {
|
|
@@ -216,24 +317,20 @@ var Formats = {
|
|
|
216
317
|
return true;
|
|
217
318
|
},
|
|
218
319
|
uri(data) {
|
|
219
|
-
return
|
|
320
|
+
return URI_REGEX.test(data);
|
|
220
321
|
},
|
|
221
322
|
email(data) {
|
|
222
|
-
return
|
|
223
|
-
data
|
|
224
|
-
);
|
|
323
|
+
return EMAIL_REGEX.test(data);
|
|
225
324
|
},
|
|
226
325
|
ipv4(data) {
|
|
227
|
-
return
|
|
228
|
-
data
|
|
229
|
-
);
|
|
326
|
+
return IPV4_REGEX.test(data);
|
|
230
327
|
},
|
|
231
328
|
// ipv6: isMyIpValid({ version: 6 }),
|
|
232
329
|
ipv6(data) {
|
|
233
330
|
if (data === "::") {
|
|
234
331
|
return true;
|
|
235
332
|
}
|
|
236
|
-
if (data.indexOf(":") === -1 ||
|
|
333
|
+
if (data.indexOf(":") === -1 || IPV6_REGEX.test(data)) {
|
|
237
334
|
return false;
|
|
238
335
|
}
|
|
239
336
|
const hasIpv4 = data.indexOf(".") !== -1;
|
|
@@ -241,9 +338,7 @@ var Formats = {
|
|
|
241
338
|
if (hasIpv4) {
|
|
242
339
|
addressParts = data.split(":");
|
|
243
340
|
const ipv4Part = addressParts.pop();
|
|
244
|
-
if (
|
|
245
|
-
ipv4Part
|
|
246
|
-
)) {
|
|
341
|
+
if (!IPV4_REGEX.test(ipv4Part)) {
|
|
247
342
|
return false;
|
|
248
343
|
}
|
|
249
344
|
}
|
|
@@ -253,32 +348,38 @@ var Formats = {
|
|
|
253
348
|
if (ipv6Part.split("::").length - 1 > 1) {
|
|
254
349
|
return false;
|
|
255
350
|
}
|
|
256
|
-
if (
|
|
351
|
+
if (!IPV6_SHORT_REGEX.test(ipv6Part)) {
|
|
257
352
|
return false;
|
|
258
353
|
}
|
|
259
|
-
return
|
|
260
|
-
ipv6Part
|
|
261
|
-
);
|
|
354
|
+
return IPV6_FAST_FAIL_REGEX.test(ipv6Part);
|
|
262
355
|
}
|
|
263
|
-
const isIpv6Valid =
|
|
264
|
-
const hasInvalidChar =
|
|
265
|
-
ipv6Part
|
|
266
|
-
);
|
|
356
|
+
const isIpv6Valid = IPV6_FULL_REGEX.test(ipv6Part);
|
|
357
|
+
const hasInvalidChar = IPV6_INVALID_CHAR_REGEX.test(ipv6Part);
|
|
267
358
|
if (hasIpv4) {
|
|
268
359
|
return isIpv6Valid || !hasInvalidChar;
|
|
269
360
|
}
|
|
270
361
|
return isIpv6Valid && !hasInvalidChar;
|
|
271
362
|
},
|
|
272
363
|
hostname(data) {
|
|
273
|
-
return
|
|
274
|
-
data
|
|
275
|
-
);
|
|
364
|
+
return HOSTNAME_REGEX.test(data);
|
|
276
365
|
},
|
|
277
366
|
date(data) {
|
|
278
|
-
|
|
367
|
+
const match = DATE_REGEX.exec(data);
|
|
368
|
+
if (!match) {
|
|
279
369
|
return false;
|
|
280
370
|
}
|
|
281
|
-
|
|
371
|
+
const [, yearStr, monthStr, dayStr] = match;
|
|
372
|
+
const year = Number(yearStr);
|
|
373
|
+
const month = Number(monthStr);
|
|
374
|
+
const day = Number(dayStr);
|
|
375
|
+
if (month < 1 || month > 12) {
|
|
376
|
+
return false;
|
|
377
|
+
}
|
|
378
|
+
if (day < 1) {
|
|
379
|
+
return false;
|
|
380
|
+
}
|
|
381
|
+
const maxDays = month === 2 ? year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) ? 29 : 28 : DAYS_IN_MONTH[month - 1];
|
|
382
|
+
return !!maxDays && day <= maxDays;
|
|
282
383
|
},
|
|
283
384
|
regex(data) {
|
|
284
385
|
try {
|
|
@@ -292,39 +393,49 @@ var Formats = {
|
|
|
292
393
|
if (data === "") {
|
|
293
394
|
return true;
|
|
294
395
|
}
|
|
295
|
-
return
|
|
396
|
+
return JSON_POINTER_REGEX.test(data);
|
|
296
397
|
},
|
|
297
398
|
"relative-json-pointer"(data) {
|
|
298
399
|
if (data === "") {
|
|
299
400
|
return true;
|
|
300
401
|
}
|
|
301
|
-
return
|
|
402
|
+
return RELATIVE_JSON_POINTER_REGEX.test(data);
|
|
302
403
|
},
|
|
303
404
|
time(data) {
|
|
304
|
-
return
|
|
305
|
-
data
|
|
306
|
-
);
|
|
405
|
+
return TIME_REGEX.test(data);
|
|
307
406
|
},
|
|
308
407
|
"uri-reference"(data) {
|
|
309
|
-
if (
|
|
408
|
+
if (BACK_SLASH_REGEX.test(data)) {
|
|
310
409
|
return false;
|
|
311
410
|
}
|
|
312
|
-
return
|
|
313
|
-
data
|
|
314
|
-
);
|
|
411
|
+
return URI_REFERENCE_REGEX.test(data);
|
|
315
412
|
},
|
|
316
413
|
"uri-template"(data) {
|
|
317
|
-
return
|
|
318
|
-
|
|
319
|
-
|
|
414
|
+
return URI_TEMPLATE_REGEX.test(data);
|
|
415
|
+
},
|
|
416
|
+
duration(data) {
|
|
417
|
+
return DURATION_REGEX.test(data);
|
|
418
|
+
},
|
|
419
|
+
uuid(data) {
|
|
420
|
+
return UUID_REGEX.test(data);
|
|
421
|
+
},
|
|
422
|
+
// IRI is like URI but allows Unicode. We reuse a permissive logic.
|
|
423
|
+
iri(data) {
|
|
424
|
+
return IRI_REGEX.test(data);
|
|
320
425
|
},
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
426
|
+
"iri-reference"(data) {
|
|
427
|
+
if (BACK_SLASH_REGEX.test(data)) {
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
return IRI_REFERENCE_REGEX.test(data);
|
|
431
|
+
},
|
|
432
|
+
// Best-effort structural validation for IDN (no punycode/tables)
|
|
433
|
+
"idn-email"(data) {
|
|
434
|
+
return IDN_EMAIL_REGEX.test(data);
|
|
435
|
+
},
|
|
436
|
+
"idn-hostname"(data) {
|
|
437
|
+
return IDN_HOSTNAME_REGEX.test(data);
|
|
438
|
+
}
|
|
328
439
|
};
|
|
329
440
|
|
|
330
441
|
// lib/types.ts
|
|
@@ -333,10 +444,7 @@ var Types = {
|
|
|
333
444
|
return isObject(data);
|
|
334
445
|
},
|
|
335
446
|
array(data) {
|
|
336
|
-
|
|
337
|
-
return true;
|
|
338
|
-
}
|
|
339
|
-
return typeof data === "object" && data !== null && "length" in data && "0" in data && Object.keys(data).length - 1 === data.length;
|
|
447
|
+
return Array.isArray(data);
|
|
340
448
|
},
|
|
341
449
|
string(data) {
|
|
342
450
|
return typeof data === "string";
|
|
@@ -367,6 +475,7 @@ var Types = {
|
|
|
367
475
|
|
|
368
476
|
// lib/keywords/array-keywords.ts
|
|
369
477
|
var ArrayKeywords = {
|
|
478
|
+
// lib/keywords/array-keywords.ts
|
|
370
479
|
items(schema, data, defineError) {
|
|
371
480
|
if (!Array.isArray(data)) {
|
|
372
481
|
return;
|
|
@@ -381,11 +490,11 @@ var ArrayKeywords = {
|
|
|
381
490
|
}
|
|
382
491
|
if (Array.isArray(schemaItems)) {
|
|
383
492
|
const schemaItemsLength = schemaItems.length;
|
|
384
|
-
const itemsLength =
|
|
493
|
+
const itemsLength = schemaItemsLength < dataLength ? schemaItemsLength : dataLength;
|
|
385
494
|
for (let i = 0; i < itemsLength; i++) {
|
|
386
495
|
const schemaItem = schemaItems[i];
|
|
387
496
|
if (typeof schemaItem === "boolean") {
|
|
388
|
-
if (schemaItem === false &&
|
|
497
|
+
if (schemaItem === false && data[i] !== void 0) {
|
|
389
498
|
return defineError("Array item is not allowed", {
|
|
390
499
|
item: i,
|
|
391
500
|
data: data[i]
|
|
@@ -393,8 +502,9 @@ var ArrayKeywords = {
|
|
|
393
502
|
}
|
|
394
503
|
continue;
|
|
395
504
|
}
|
|
396
|
-
|
|
397
|
-
|
|
505
|
+
const validate2 = schemaItem && schemaItem.$validate;
|
|
506
|
+
if (typeof validate2 === "function") {
|
|
507
|
+
const error = validate2(data[i]);
|
|
398
508
|
if (error) {
|
|
399
509
|
return defineError("Array item is invalid", {
|
|
400
510
|
item: i,
|
|
@@ -406,26 +516,32 @@ var ArrayKeywords = {
|
|
|
406
516
|
}
|
|
407
517
|
return;
|
|
408
518
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
519
|
+
const validate = schemaItems && schemaItems.$validate;
|
|
520
|
+
if (typeof validate !== "function") {
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
for (let i = 0; i < dataLength; i++) {
|
|
524
|
+
const error = validate(data[i]);
|
|
525
|
+
if (error) {
|
|
526
|
+
return defineError("Array item is invalid", {
|
|
527
|
+
item: i,
|
|
528
|
+
cause: error,
|
|
529
|
+
data: data[i]
|
|
530
|
+
});
|
|
419
531
|
}
|
|
420
532
|
}
|
|
421
|
-
return;
|
|
422
533
|
},
|
|
423
534
|
elements(schema, data, defineError) {
|
|
424
|
-
if (!Array.isArray(data)
|
|
535
|
+
if (!Array.isArray(data)) {
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
const elementsSchema = schema.elements;
|
|
539
|
+
const validate = elementsSchema && elementsSchema.$validate;
|
|
540
|
+
if (typeof validate !== "function") {
|
|
425
541
|
return;
|
|
426
542
|
}
|
|
427
543
|
for (let i = 0; i < data.length; i++) {
|
|
428
|
-
const error =
|
|
544
|
+
const error = validate(data[i]);
|
|
429
545
|
if (error) {
|
|
430
546
|
return defineError("Array item is invalid", {
|
|
431
547
|
item: i,
|
|
@@ -434,7 +550,6 @@ var ArrayKeywords = {
|
|
|
434
550
|
});
|
|
435
551
|
}
|
|
436
552
|
}
|
|
437
|
-
return;
|
|
438
553
|
},
|
|
439
554
|
minItems(schema, data, defineError) {
|
|
440
555
|
if (!Array.isArray(data) || data.length >= schema.minItems) {
|
|
@@ -480,28 +595,30 @@ var ArrayKeywords = {
|
|
|
480
595
|
if (!Array.isArray(data) || !schema.uniqueItems) {
|
|
481
596
|
return;
|
|
482
597
|
}
|
|
483
|
-
const
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
itemStr = String(item);
|
|
598
|
+
const len = data.length;
|
|
599
|
+
if (len <= 1) {
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
const primitiveSeen = /* @__PURE__ */ new Set();
|
|
603
|
+
for (let i = 0; i < len; i++) {
|
|
604
|
+
const item = data[i];
|
|
605
|
+
const type = typeof item;
|
|
606
|
+
if (item === null || type === "string" || type === "number" || type === "boolean") {
|
|
607
|
+
if (primitiveSeen.has(item)) {
|
|
608
|
+
return defineError("Array items are not unique", { data: item });
|
|
609
|
+
}
|
|
610
|
+
primitiveSeen.add(item);
|
|
611
|
+
continue;
|
|
498
612
|
}
|
|
499
|
-
if (
|
|
500
|
-
|
|
613
|
+
if (item && typeof item === "object") {
|
|
614
|
+
for (let j = 0; j < i; j++) {
|
|
615
|
+
const prev = data[j];
|
|
616
|
+
if (prev && typeof prev === "object" && !hasChanged(prev, item)) {
|
|
617
|
+
return defineError("Array items are not unique", { data: item });
|
|
618
|
+
}
|
|
619
|
+
}
|
|
501
620
|
}
|
|
502
|
-
unique.add(itemStr);
|
|
503
621
|
}
|
|
504
|
-
return;
|
|
505
622
|
},
|
|
506
623
|
contains(schema, data, defineError) {
|
|
507
624
|
if (!Array.isArray(data)) {
|
|
@@ -597,7 +714,6 @@ var NumberKeywords = {
|
|
|
597
714
|
|
|
598
715
|
// lib/keywords/object-keywords.ts
|
|
599
716
|
var ObjectKeywords = {
|
|
600
|
-
// Object
|
|
601
717
|
required(schema, data, defineError) {
|
|
602
718
|
if (!isObject(data)) {
|
|
603
719
|
return;
|
|
@@ -617,16 +733,46 @@ var ObjectKeywords = {
|
|
|
617
733
|
if (!isObject(data)) {
|
|
618
734
|
return;
|
|
619
735
|
}
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
736
|
+
let propKeys = schema._propKeys;
|
|
737
|
+
if (!propKeys) {
|
|
738
|
+
propKeys = Object.keys(schema.properties || {});
|
|
739
|
+
Object.defineProperty(schema, "_propKeys", {
|
|
740
|
+
value: propKeys,
|
|
741
|
+
enumerable: false,
|
|
742
|
+
configurable: false,
|
|
743
|
+
writable: false
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
let requiredKeys = schema._requiredKeys;
|
|
747
|
+
if (requiredKeys === void 0) {
|
|
748
|
+
requiredKeys = Array.isArray(schema.required) ? schema.required : null;
|
|
749
|
+
Object.defineProperty(schema, "_requiredKeys", {
|
|
750
|
+
value: requiredKeys,
|
|
751
|
+
enumerable: false,
|
|
752
|
+
configurable: false,
|
|
753
|
+
writable: false
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
const required = requiredKeys || [];
|
|
757
|
+
for (let i = 0; i < propKeys.length; i++) {
|
|
758
|
+
const key = propKeys[i];
|
|
759
|
+
const schemaProp = schema.properties[key];
|
|
760
|
+
if (!Object.prototype.hasOwnProperty.call(data, key)) {
|
|
761
|
+
if (required.length && required.indexOf(key) !== -1 && isObject(schemaProp) && "default" in schemaProp) {
|
|
762
|
+
const error = schemaProp.$validate(schemaProp.default);
|
|
763
|
+
if (error) {
|
|
764
|
+
return defineError("Default property is invalid", {
|
|
765
|
+
item: key,
|
|
766
|
+
cause: error,
|
|
767
|
+
data: schemaProp.default
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
data[key] = deepClone(schemaProp.default);
|
|
625
771
|
}
|
|
626
772
|
continue;
|
|
627
773
|
}
|
|
628
|
-
if (typeof
|
|
629
|
-
if (
|
|
774
|
+
if (typeof schemaProp === "boolean") {
|
|
775
|
+
if (schemaProp === false) {
|
|
630
776
|
return defineError("Property is not allowed", {
|
|
631
777
|
item: key,
|
|
632
778
|
data: data[key]
|
|
@@ -634,8 +780,8 @@ var ObjectKeywords = {
|
|
|
634
780
|
}
|
|
635
781
|
continue;
|
|
636
782
|
}
|
|
637
|
-
if ("$validate" in
|
|
638
|
-
const error =
|
|
783
|
+
if (schemaProp && "$validate" in schemaProp) {
|
|
784
|
+
const error = schemaProp.$validate(data[key]);
|
|
639
785
|
if (error) {
|
|
640
786
|
return defineError("Property is invalid", {
|
|
641
787
|
item: key,
|
|
@@ -648,12 +794,18 @@ var ObjectKeywords = {
|
|
|
648
794
|
return;
|
|
649
795
|
},
|
|
650
796
|
values(schema, data, defineError) {
|
|
651
|
-
if (!isObject(data)
|
|
797
|
+
if (!isObject(data)) {
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
const valueSchema = schema.values;
|
|
801
|
+
const validate = valueSchema && valueSchema.$validate;
|
|
802
|
+
if (typeof validate !== "function") {
|
|
652
803
|
return;
|
|
653
804
|
}
|
|
654
805
|
const keys = Object.keys(data);
|
|
655
|
-
for (
|
|
656
|
-
const
|
|
806
|
+
for (let i = 0; i < keys.length; i++) {
|
|
807
|
+
const key = keys[i];
|
|
808
|
+
const error = validate(data[key]);
|
|
657
809
|
if (error) {
|
|
658
810
|
return defineError("Property is invalid", {
|
|
659
811
|
item: key,
|
|
@@ -662,7 +814,6 @@ var ObjectKeywords = {
|
|
|
662
814
|
});
|
|
663
815
|
}
|
|
664
816
|
}
|
|
665
|
-
return;
|
|
666
817
|
},
|
|
667
818
|
maxProperties(schema, data, defineError) {
|
|
668
819
|
if (!isObject(data) || Object.keys(data).length <= schema.maxProperties) {
|
|
@@ -681,15 +832,37 @@ var ObjectKeywords = {
|
|
|
681
832
|
return;
|
|
682
833
|
}
|
|
683
834
|
const keys = Object.keys(data);
|
|
684
|
-
|
|
685
|
-
|
|
835
|
+
let apIsCompiled = schema._apIsCompiled;
|
|
836
|
+
if (apIsCompiled === void 0) {
|
|
837
|
+
apIsCompiled = isCompiledSchema(schema.additionalProperties);
|
|
838
|
+
Object.defineProperty(schema, "_apIsCompiled", {
|
|
839
|
+
value: apIsCompiled,
|
|
840
|
+
enumerable: false
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
let patternList = schema._patternPropertiesList;
|
|
844
|
+
if (schema.patternProperties && !patternList) {
|
|
845
|
+
patternList = [];
|
|
846
|
+
for (const pattern in schema.patternProperties) {
|
|
847
|
+
patternList.push({
|
|
848
|
+
regex: new RegExp(pattern, "u"),
|
|
849
|
+
key: pattern
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
Object.defineProperty(schema, "_patternPropertiesList", {
|
|
853
|
+
value: patternList,
|
|
854
|
+
enumerable: false
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
for (let i = 0; i < keys.length; i++) {
|
|
858
|
+
const key = keys[i];
|
|
686
859
|
if (schema.properties && schema.properties.hasOwnProperty(key)) {
|
|
687
860
|
continue;
|
|
688
861
|
}
|
|
689
|
-
if (
|
|
862
|
+
if (patternList && patternList.length) {
|
|
690
863
|
let match = false;
|
|
691
|
-
for (
|
|
692
|
-
if (
|
|
864
|
+
for (let j = 0; j < patternList.length; j++) {
|
|
865
|
+
if (patternList[j].regex.test(key)) {
|
|
693
866
|
match = true;
|
|
694
867
|
break;
|
|
695
868
|
}
|
|
@@ -704,7 +877,7 @@ var ObjectKeywords = {
|
|
|
704
877
|
data: data[key]
|
|
705
878
|
});
|
|
706
879
|
}
|
|
707
|
-
if (
|
|
880
|
+
if (apIsCompiled && isCompiledSchema(schema.additionalProperties)) {
|
|
708
881
|
const error = schema.additionalProperties.$validate(data[key]);
|
|
709
882
|
if (error) {
|
|
710
883
|
return defineError("Additional properties are invalid", {
|
|
@@ -721,12 +894,30 @@ var ObjectKeywords = {
|
|
|
721
894
|
if (!isObject(data)) {
|
|
722
895
|
return;
|
|
723
896
|
}
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
897
|
+
let patternList = schema._patternPropertiesList;
|
|
898
|
+
if (!patternList) {
|
|
899
|
+
patternList = [];
|
|
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
|
+
});
|
|
912
|
+
}
|
|
913
|
+
const dataKeys = Object.keys(data);
|
|
914
|
+
for (let p = 0; p < patternList.length; p++) {
|
|
915
|
+
const { regex, key: patternKey } = patternList[p];
|
|
916
|
+
const schemaProp = schema.patternProperties[patternKey];
|
|
917
|
+
if (typeof schemaProp === "boolean") {
|
|
918
|
+
if (schemaProp === false) {
|
|
919
|
+
for (let i = 0; i < dataKeys.length; i++) {
|
|
920
|
+
const key = dataKeys[i];
|
|
730
921
|
if (regex.test(key)) {
|
|
731
922
|
return defineError("Property is not allowed", {
|
|
732
923
|
item: key,
|
|
@@ -737,13 +928,11 @@ var ObjectKeywords = {
|
|
|
737
928
|
}
|
|
738
929
|
continue;
|
|
739
930
|
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
if (
|
|
744
|
-
const error =
|
|
745
|
-
data[key]
|
|
746
|
-
);
|
|
931
|
+
if ("$validate" in schemaProp) {
|
|
932
|
+
for (let i = 0; i < dataKeys.length; i++) {
|
|
933
|
+
const key = dataKeys[i];
|
|
934
|
+
if (regex.test(key)) {
|
|
935
|
+
const error = schemaProp.$validate(data[key]);
|
|
747
936
|
if (error) {
|
|
748
937
|
return defineError("Property is invalid", {
|
|
749
938
|
item: key,
|
|
@@ -761,24 +950,30 @@ var ObjectKeywords = {
|
|
|
761
950
|
if (!isObject(data)) {
|
|
762
951
|
return;
|
|
763
952
|
}
|
|
764
|
-
|
|
765
|
-
|
|
953
|
+
const pn = schema.propertyNames;
|
|
954
|
+
if (typeof pn === "boolean") {
|
|
955
|
+
if (pn === false && Object.keys(data).length > 0) {
|
|
766
956
|
return defineError("Properties are not allowed", { data });
|
|
767
957
|
}
|
|
958
|
+
return;
|
|
768
959
|
}
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
960
|
+
const validate = pn && pn.$validate;
|
|
961
|
+
if (typeof validate !== "function") {
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
for (const key in data) {
|
|
965
|
+
if (!Object.prototype.hasOwnProperty.call(data, key)) {
|
|
966
|
+
continue;
|
|
967
|
+
}
|
|
968
|
+
const error = validate(key);
|
|
969
|
+
if (error) {
|
|
970
|
+
return defineError("Property name is invalid", {
|
|
971
|
+
item: key,
|
|
972
|
+
cause: error,
|
|
973
|
+
data: data[key]
|
|
974
|
+
});
|
|
779
975
|
}
|
|
780
976
|
}
|
|
781
|
-
return;
|
|
782
977
|
},
|
|
783
978
|
dependencies(schema, data, defineError) {
|
|
784
979
|
if (!isObject(data)) {
|
|
@@ -827,7 +1022,6 @@ var ObjectKeywords = {
|
|
|
827
1022
|
else: false,
|
|
828
1023
|
default: false,
|
|
829
1024
|
// Not implemented yet
|
|
830
|
-
$ref: false,
|
|
831
1025
|
definitions: false,
|
|
832
1026
|
$id: false,
|
|
833
1027
|
$schema: false,
|
|
@@ -846,17 +1040,14 @@ var ObjectKeywords = {
|
|
|
846
1040
|
// lib/keywords/other-keywords.ts
|
|
847
1041
|
var OtherKeywords = {
|
|
848
1042
|
enum(schema, data, defineError) {
|
|
849
|
-
const
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
const enumItem = schema.enum[i];
|
|
1043
|
+
const list = schema.enum;
|
|
1044
|
+
for (let i = 0; i < list.length; i++) {
|
|
1045
|
+
const enumItem = list[i];
|
|
853
1046
|
if (enumItem === data) {
|
|
854
1047
|
return;
|
|
855
1048
|
}
|
|
856
|
-
if (
|
|
857
|
-
|
|
858
|
-
return;
|
|
859
|
-
}
|
|
1049
|
+
if (enumItem !== null && data !== null && typeof enumItem === "object" && typeof data === "object" && !hasChanged(enumItem, data)) {
|
|
1050
|
+
return;
|
|
860
1051
|
}
|
|
861
1052
|
}
|
|
862
1053
|
return defineError("Value is not one of the allowed values", { data });
|
|
@@ -909,27 +1100,40 @@ var OtherKeywords = {
|
|
|
909
1100
|
return defineError("Value is not valid", { data });
|
|
910
1101
|
},
|
|
911
1102
|
oneOf(schema, data, defineError) {
|
|
1103
|
+
const list = schema.oneOf;
|
|
912
1104
|
let validCount = 0;
|
|
913
|
-
for (let i = 0; i <
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
1105
|
+
for (let i = 0; i < list.length; i++) {
|
|
1106
|
+
const sub = list[i];
|
|
1107
|
+
if (isObject(sub)) {
|
|
1108
|
+
if ("$validate" in sub) {
|
|
1109
|
+
const error = sub.$validate(data);
|
|
917
1110
|
if (!error) {
|
|
918
1111
|
validCount++;
|
|
1112
|
+
if (validCount > 1) {
|
|
1113
|
+
return defineError("Value is not valid", { data });
|
|
1114
|
+
}
|
|
919
1115
|
}
|
|
920
1116
|
continue;
|
|
921
1117
|
}
|
|
922
1118
|
validCount++;
|
|
1119
|
+
if (validCount > 1) {
|
|
1120
|
+
return defineError("Value is not valid", { data });
|
|
1121
|
+
}
|
|
923
1122
|
continue;
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
1123
|
+
}
|
|
1124
|
+
if (typeof sub === "boolean") {
|
|
1125
|
+
if (Boolean(data) === sub) {
|
|
1126
|
+
validCount++;
|
|
1127
|
+
if (validCount > 1) {
|
|
1128
|
+
return defineError("Value is not valid", { data });
|
|
928
1129
|
}
|
|
929
|
-
continue;
|
|
930
1130
|
}
|
|
931
|
-
|
|
932
|
-
|
|
1131
|
+
continue;
|
|
1132
|
+
}
|
|
1133
|
+
if (data === sub) {
|
|
1134
|
+
validCount++;
|
|
1135
|
+
if (validCount > 1) {
|
|
1136
|
+
return defineError("Value is not valid", { data });
|
|
933
1137
|
}
|
|
934
1138
|
}
|
|
935
1139
|
}
|
|
@@ -939,12 +1143,15 @@ var OtherKeywords = {
|
|
|
939
1143
|
return defineError("Value is not valid", { data });
|
|
940
1144
|
},
|
|
941
1145
|
const(schema, data, defineError) {
|
|
942
|
-
if (data === schema.const
|
|
1146
|
+
if (data === schema.const) {
|
|
1147
|
+
return;
|
|
1148
|
+
}
|
|
1149
|
+
if (isObject(data) && isObject(schema.const) && !hasChanged(data, schema.const) || Array.isArray(data) && Array.isArray(schema.const) && !hasChanged(data, schema.const)) {
|
|
943
1150
|
return;
|
|
944
1151
|
}
|
|
945
1152
|
return defineError("Value is not valid", { data });
|
|
946
1153
|
},
|
|
947
|
-
if(schema, data
|
|
1154
|
+
if(schema, data) {
|
|
948
1155
|
if ("then" in schema === false && "else" in schema === false) {
|
|
949
1156
|
return;
|
|
950
1157
|
}
|
|
@@ -992,6 +1199,24 @@ var OtherKeywords = {
|
|
|
992
1199
|
return defineError("Value is not valid", { data });
|
|
993
1200
|
}
|
|
994
1201
|
return defineError("Value is not valid", { data });
|
|
1202
|
+
},
|
|
1203
|
+
$ref(schema, data, defineError, instance) {
|
|
1204
|
+
if (schema._resolvedRef) {
|
|
1205
|
+
return schema._resolvedRef(data);
|
|
1206
|
+
}
|
|
1207
|
+
const refPath = schema.$ref;
|
|
1208
|
+
let targetSchema = instance.getSchemaRef(refPath);
|
|
1209
|
+
if (!targetSchema) {
|
|
1210
|
+
targetSchema = instance.getSchemaById(refPath);
|
|
1211
|
+
}
|
|
1212
|
+
if (!targetSchema) {
|
|
1213
|
+
return defineError(`Missing reference: ${refPath}`);
|
|
1214
|
+
}
|
|
1215
|
+
if (!targetSchema.$validate) {
|
|
1216
|
+
return;
|
|
1217
|
+
}
|
|
1218
|
+
schema._resolvedRef = targetSchema.$validate;
|
|
1219
|
+
return schema._resolvedRef(data);
|
|
995
1220
|
}
|
|
996
1221
|
};
|
|
997
1222
|
|
|
@@ -1013,9 +1238,22 @@ var StringKeywords = {
|
|
|
1013
1238
|
if (typeof data !== "string") {
|
|
1014
1239
|
return;
|
|
1015
1240
|
}
|
|
1016
|
-
|
|
1017
|
-
if (patternRegexp
|
|
1018
|
-
|
|
1241
|
+
let patternRegexp = schema._patternRegexp;
|
|
1242
|
+
if (!patternRegexp) {
|
|
1243
|
+
try {
|
|
1244
|
+
patternRegexp = new RegExp(schema.pattern, "u");
|
|
1245
|
+
Object.defineProperty(schema, "_patternRegexp", {
|
|
1246
|
+
value: patternRegexp,
|
|
1247
|
+
enumerable: false,
|
|
1248
|
+
configurable: false,
|
|
1249
|
+
writable: false
|
|
1250
|
+
});
|
|
1251
|
+
} catch (error) {
|
|
1252
|
+
return defineError("Invalid regular expression", {
|
|
1253
|
+
data,
|
|
1254
|
+
cause: error
|
|
1255
|
+
});
|
|
1256
|
+
}
|
|
1019
1257
|
}
|
|
1020
1258
|
if (patternRegexp.test(data)) {
|
|
1021
1259
|
return;
|
|
@@ -1028,7 +1266,16 @@ var StringKeywords = {
|
|
|
1028
1266
|
if (typeof data !== "string") {
|
|
1029
1267
|
return;
|
|
1030
1268
|
}
|
|
1031
|
-
|
|
1269
|
+
let formatValidate = schema._formatValidate;
|
|
1270
|
+
if (formatValidate === void 0) {
|
|
1271
|
+
formatValidate = instance.getFormat(schema.format);
|
|
1272
|
+
Object.defineProperty(schema, "_formatValidate", {
|
|
1273
|
+
value: formatValidate,
|
|
1274
|
+
enumerable: false,
|
|
1275
|
+
configurable: false,
|
|
1276
|
+
writable: false
|
|
1277
|
+
});
|
|
1278
|
+
}
|
|
1032
1279
|
if (!formatValidate || formatValidate(data)) {
|
|
1033
1280
|
return;
|
|
1034
1281
|
}
|
|
@@ -1051,10 +1298,15 @@ var SchemaShield = class {
|
|
|
1051
1298
|
formats = {};
|
|
1052
1299
|
keywords = {};
|
|
1053
1300
|
immutable = false;
|
|
1301
|
+
rootSchema = null;
|
|
1302
|
+
idRegistry = /* @__PURE__ */ new Map();
|
|
1303
|
+
failFast = true;
|
|
1054
1304
|
constructor({
|
|
1055
|
-
immutable = false
|
|
1305
|
+
immutable = false,
|
|
1306
|
+
failFast = true
|
|
1056
1307
|
} = {}) {
|
|
1057
1308
|
this.immutable = immutable;
|
|
1309
|
+
this.failFast = failFast;
|
|
1058
1310
|
for (const [type, validator] of Object.entries(Types)) {
|
|
1059
1311
|
if (validator) {
|
|
1060
1312
|
this.addType(type, validator);
|
|
@@ -1096,26 +1348,38 @@ var SchemaShield = class {
|
|
|
1096
1348
|
getKeyword(keyword) {
|
|
1097
1349
|
return this.keywords[keyword];
|
|
1098
1350
|
}
|
|
1351
|
+
getSchemaRef(path) {
|
|
1352
|
+
if (!this.rootSchema) {
|
|
1353
|
+
return;
|
|
1354
|
+
}
|
|
1355
|
+
return resolvePath(this.rootSchema, path);
|
|
1356
|
+
}
|
|
1357
|
+
getSchemaById(id) {
|
|
1358
|
+
return this.idRegistry.get(id);
|
|
1359
|
+
}
|
|
1099
1360
|
compile(schema) {
|
|
1361
|
+
this.idRegistry.clear();
|
|
1100
1362
|
const compiledSchema = this.compileSchema(schema);
|
|
1363
|
+
this.rootSchema = compiledSchema;
|
|
1364
|
+
this.linkReferences(compiledSchema);
|
|
1101
1365
|
if (!compiledSchema.$validate) {
|
|
1102
1366
|
if (this.isSchemaLike(schema) === false) {
|
|
1103
1367
|
throw new ValidationError("Invalid schema");
|
|
1104
1368
|
}
|
|
1105
1369
|
compiledSchema.$validate = getNamedFunction(
|
|
1106
|
-
"
|
|
1370
|
+
"Validate_Any",
|
|
1107
1371
|
() => {
|
|
1108
1372
|
}
|
|
1109
1373
|
);
|
|
1110
1374
|
}
|
|
1111
1375
|
const validate = (data) => {
|
|
1376
|
+
this.rootSchema = compiledSchema;
|
|
1112
1377
|
const clonedData = this.immutable ? deepClone(data) : data;
|
|
1113
|
-
const
|
|
1114
|
-
|
|
1115
|
-
data: clonedData,
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
};
|
|
1378
|
+
const res = compiledSchema.$validate(clonedData);
|
|
1379
|
+
if (res) {
|
|
1380
|
+
return { data: clonedData, error: res, valid: false };
|
|
1381
|
+
}
|
|
1382
|
+
return { data: clonedData, error: null, valid: true };
|
|
1119
1383
|
};
|
|
1120
1384
|
validate.compiledSchema = compiledSchema;
|
|
1121
1385
|
return validate;
|
|
@@ -1123,99 +1387,113 @@ var SchemaShield = class {
|
|
|
1123
1387
|
compileSchema(schema) {
|
|
1124
1388
|
if (!isObject(schema)) {
|
|
1125
1389
|
if (schema === true) {
|
|
1126
|
-
schema = {
|
|
1127
|
-
anyOf: [{}]
|
|
1128
|
-
};
|
|
1390
|
+
schema = { anyOf: [{}] };
|
|
1129
1391
|
} else if (schema === false) {
|
|
1130
|
-
schema = {
|
|
1131
|
-
oneOf: []
|
|
1132
|
-
};
|
|
1392
|
+
schema = { oneOf: [] };
|
|
1133
1393
|
} else {
|
|
1134
|
-
schema = {
|
|
1135
|
-
oneOf: [schema]
|
|
1136
|
-
};
|
|
1394
|
+
schema = { oneOf: [schema] };
|
|
1137
1395
|
}
|
|
1138
1396
|
}
|
|
1139
1397
|
const compiledSchema = deepClone(schema);
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1398
|
+
if (typeof schema.$id === "string") {
|
|
1399
|
+
this.idRegistry.set(schema.$id, compiledSchema);
|
|
1400
|
+
}
|
|
1401
|
+
if ("$ref" in schema) {
|
|
1402
|
+
const refValidator = this.getKeyword("$ref");
|
|
1403
|
+
if (refValidator) {
|
|
1404
|
+
const defineError = getDefinedErrorFunctionForKey(
|
|
1405
|
+
"$ref",
|
|
1406
|
+
schema["$ref"],
|
|
1407
|
+
this.failFast
|
|
1408
|
+
);
|
|
1409
|
+
compiledSchema.$validate = getNamedFunction(
|
|
1410
|
+
"Validate_Reference",
|
|
1411
|
+
(data) => refValidator(
|
|
1412
|
+
compiledSchema,
|
|
1413
|
+
data,
|
|
1414
|
+
defineError,
|
|
1415
|
+
this
|
|
1416
|
+
)
|
|
1417
|
+
);
|
|
1418
|
+
}
|
|
1419
|
+
return compiledSchema;
|
|
1420
|
+
}
|
|
1421
|
+
const validators = [];
|
|
1422
|
+
const activeNames = [];
|
|
1143
1423
|
if ("type" in schema) {
|
|
1424
|
+
const defineTypeError = getDefinedErrorFunctionForKey(
|
|
1425
|
+
"type",
|
|
1426
|
+
schema,
|
|
1427
|
+
this.failFast
|
|
1428
|
+
);
|
|
1144
1429
|
const types = Array.isArray(schema.type) ? schema.type : schema.type.split(",").map((t) => t.trim());
|
|
1145
|
-
|
|
1146
|
-
|
|
1430
|
+
const typeFunctions = [];
|
|
1431
|
+
const typeNames = [];
|
|
1432
|
+
for (const type2 of types) {
|
|
1433
|
+
const validator = this.getType(type2);
|
|
1147
1434
|
if (validator) {
|
|
1148
|
-
|
|
1149
|
-
|
|
1435
|
+
typeFunctions.push(validator);
|
|
1436
|
+
typeNames.push(validator.name);
|
|
1150
1437
|
}
|
|
1151
1438
|
}
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1439
|
+
if (typeFunctions.length === 0) {
|
|
1440
|
+
throw getDefinedErrorFunctionForKey(
|
|
1441
|
+
"type",
|
|
1442
|
+
schema,
|
|
1443
|
+
this.failFast
|
|
1444
|
+
)("Invalid type for schema", { data: schema.type });
|
|
1445
|
+
}
|
|
1446
|
+
let combinedTypeValidator;
|
|
1447
|
+
let typeMethodName = "";
|
|
1448
|
+
if (typeFunctions.length === 1) {
|
|
1449
|
+
typeMethodName = typeNames[0];
|
|
1450
|
+
const singleTypeFn = typeFunctions[0];
|
|
1451
|
+
combinedTypeValidator = (data) => {
|
|
1452
|
+
if (!singleTypeFn(data)) {
|
|
1453
|
+
return defineTypeError("Invalid type", { data });
|
|
1164
1454
|
}
|
|
1165
|
-
|
|
1166
|
-
} else
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
(
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
return;
|
|
1173
|
-
}
|
|
1455
|
+
};
|
|
1456
|
+
} else {
|
|
1457
|
+
typeMethodName = typeNames.join("_OR_");
|
|
1458
|
+
combinedTypeValidator = (data) => {
|
|
1459
|
+
for (let i = 0; i < typeFunctions.length; i++) {
|
|
1460
|
+
if (typeFunctions[i](data)) {
|
|
1461
|
+
return;
|
|
1174
1462
|
}
|
|
1175
|
-
return defineTypeError("Invalid type", { data });
|
|
1176
1463
|
}
|
|
1464
|
+
return defineTypeError("Invalid type", { data });
|
|
1465
|
+
};
|
|
1466
|
+
}
|
|
1467
|
+
const typeAdapter = (_s, data) => combinedTypeValidator(data);
|
|
1468
|
+
validators.push({
|
|
1469
|
+
fn: getNamedFunction(typeMethodName, typeAdapter),
|
|
1470
|
+
defineError: defineTypeError
|
|
1471
|
+
});
|
|
1472
|
+
activeNames.push(typeMethodName);
|
|
1473
|
+
}
|
|
1474
|
+
const { type, $id, $ref, $validate, required, ...otherKeys } = schema;
|
|
1475
|
+
const keyOrder = required ? [...Object.keys(otherKeys), "required"] : Object.keys(otherKeys);
|
|
1476
|
+
for (const key of keyOrder) {
|
|
1477
|
+
const keywordFn = this.getKeyword(key);
|
|
1478
|
+
if (keywordFn) {
|
|
1479
|
+
const defineError = getDefinedErrorFunctionForKey(
|
|
1480
|
+
key,
|
|
1481
|
+
schema[key],
|
|
1482
|
+
this.failFast
|
|
1177
1483
|
);
|
|
1484
|
+
const fnName = keywordFn.name || key;
|
|
1485
|
+
validators.push({
|
|
1486
|
+
fn: keywordFn,
|
|
1487
|
+
defineError
|
|
1488
|
+
});
|
|
1489
|
+
activeNames.push(fnName);
|
|
1178
1490
|
}
|
|
1179
1491
|
}
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1492
|
+
const literalKeywords = ["enum", "const", "default", "examples"];
|
|
1493
|
+
for (const key of keyOrder) {
|
|
1494
|
+
if (literalKeywords.includes(key)) {
|
|
1183
1495
|
continue;
|
|
1184
1496
|
}
|
|
1185
|
-
const keywordValidator = this.getKeyword(key);
|
|
1186
|
-
if (keywordValidator) {
|
|
1187
|
-
const defineError = getDefinedErrorFunctionForKey(key, schema[key]);
|
|
1188
|
-
if (compiledSchema.$validate) {
|
|
1189
|
-
const prevValidator = compiledSchema.$validate;
|
|
1190
|
-
methodName += `_AND_${keywordValidator.name}`;
|
|
1191
|
-
compiledSchema.$validate = getNamedFunction(
|
|
1192
|
-
methodName,
|
|
1193
|
-
(data) => {
|
|
1194
|
-
const error = prevValidator(data);
|
|
1195
|
-
if (error) {
|
|
1196
|
-
return error;
|
|
1197
|
-
}
|
|
1198
|
-
return keywordValidator(
|
|
1199
|
-
compiledSchema,
|
|
1200
|
-
data,
|
|
1201
|
-
defineError,
|
|
1202
|
-
this
|
|
1203
|
-
);
|
|
1204
|
-
}
|
|
1205
|
-
);
|
|
1206
|
-
} else {
|
|
1207
|
-
methodName = keywordValidator.name;
|
|
1208
|
-
compiledSchema.$validate = getNamedFunction(
|
|
1209
|
-
methodName,
|
|
1210
|
-
(data) => keywordValidator(
|
|
1211
|
-
compiledSchema,
|
|
1212
|
-
data,
|
|
1213
|
-
defineError,
|
|
1214
|
-
this
|
|
1215
|
-
)
|
|
1216
|
-
);
|
|
1217
|
-
}
|
|
1218
|
-
}
|
|
1219
1497
|
if (isObject(schema[key])) {
|
|
1220
1498
|
if (key === "properties") {
|
|
1221
1499
|
for (const subKey of Object.keys(schema[key])) {
|
|
@@ -1229,12 +1507,39 @@ var SchemaShield = class {
|
|
|
1229
1507
|
continue;
|
|
1230
1508
|
}
|
|
1231
1509
|
if (Array.isArray(schema[key])) {
|
|
1232
|
-
|
|
1233
|
-
(
|
|
1234
|
-
|
|
1510
|
+
for (let i = 0; i < schema[key].length; i++) {
|
|
1511
|
+
if (this.isSchemaLike(schema[key][i])) {
|
|
1512
|
+
compiledSchema[key][i] = this.compileSchema(schema[key][i]);
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1235
1515
|
continue;
|
|
1236
1516
|
}
|
|
1237
|
-
|
|
1517
|
+
}
|
|
1518
|
+
if (validators.length === 0) {
|
|
1519
|
+
return compiledSchema;
|
|
1520
|
+
}
|
|
1521
|
+
if (validators.length === 1) {
|
|
1522
|
+
const v = validators[0];
|
|
1523
|
+
compiledSchema.$validate = getNamedFunction(
|
|
1524
|
+
activeNames[0],
|
|
1525
|
+
(data) => v.fn(compiledSchema, data, v.defineError, this)
|
|
1526
|
+
);
|
|
1527
|
+
} else {
|
|
1528
|
+
const compositeName = "Validate_" + activeNames.join("_AND_");
|
|
1529
|
+
const masterValidator = (data) => {
|
|
1530
|
+
for (let i = 0; i < validators.length; i++) {
|
|
1531
|
+
const v = validators[i];
|
|
1532
|
+
const error = v.fn(compiledSchema, data, v.defineError, this);
|
|
1533
|
+
if (error) {
|
|
1534
|
+
return error;
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
return;
|
|
1538
|
+
};
|
|
1539
|
+
compiledSchema.$validate = getNamedFunction(
|
|
1540
|
+
compositeName,
|
|
1541
|
+
masterValidator
|
|
1542
|
+
);
|
|
1238
1543
|
}
|
|
1239
1544
|
return compiledSchema;
|
|
1240
1545
|
}
|
|
@@ -1251,7 +1556,59 @@ var SchemaShield = class {
|
|
|
1251
1556
|
}
|
|
1252
1557
|
return false;
|
|
1253
1558
|
}
|
|
1559
|
+
linkReferences(root) {
|
|
1560
|
+
const stack = [root];
|
|
1561
|
+
while (stack.length > 0) {
|
|
1562
|
+
const node = stack.pop();
|
|
1563
|
+
if (!node || typeof node !== "object")
|
|
1564
|
+
continue;
|
|
1565
|
+
if (typeof node.$ref === "string" && typeof node.$validate === "function" && node.$validate.name === "Validate_Reference") {
|
|
1566
|
+
const refPath = node.$ref;
|
|
1567
|
+
let target = this.getSchemaRef(refPath);
|
|
1568
|
+
if (typeof target === "undefined") {
|
|
1569
|
+
target = this.getSchemaById(refPath);
|
|
1570
|
+
}
|
|
1571
|
+
if (typeof target === "boolean") {
|
|
1572
|
+
if (target === true) {
|
|
1573
|
+
node.$validate = getNamedFunction("Validate_Ref_True", () => {
|
|
1574
|
+
});
|
|
1575
|
+
} else {
|
|
1576
|
+
const defineError = getDefinedErrorFunctionForKey(
|
|
1577
|
+
"$ref",
|
|
1578
|
+
node,
|
|
1579
|
+
this.failFast
|
|
1580
|
+
);
|
|
1581
|
+
node.$validate = getNamedFunction(
|
|
1582
|
+
"Validate_Ref_False",
|
|
1583
|
+
(_data) => defineError("Value is not valid")
|
|
1584
|
+
);
|
|
1585
|
+
}
|
|
1586
|
+
continue;
|
|
1587
|
+
}
|
|
1588
|
+
if (target && typeof target.$validate === "function") {
|
|
1589
|
+
node.$validate = target.$validate;
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
for (const key in node) {
|
|
1593
|
+
const value = node[key];
|
|
1594
|
+
if (!value)
|
|
1595
|
+
continue;
|
|
1596
|
+
if (Array.isArray(value)) {
|
|
1597
|
+
for (let i = 0; i < value.length; i++) {
|
|
1598
|
+
const v = value[i];
|
|
1599
|
+
if (v && typeof v === "object") {
|
|
1600
|
+
stack.push(v);
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
} else if (typeof value === "object") {
|
|
1604
|
+
stack.push(value);
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1254
1609
|
};
|
|
1255
1610
|
export {
|
|
1256
|
-
SchemaShield
|
|
1611
|
+
SchemaShield,
|
|
1612
|
+
ValidationError,
|
|
1613
|
+
deepClone
|
|
1257
1614
|
};
|