@sanity/validation 3.0.0-dev-preview.22 → 3.0.0-findability.53
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/lib/index.esm.js +289 -6
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +297 -6
- package/lib/index.js.map +1 -1
- package/package.json +4 -4
package/lib/index.esm.js
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
const _excluded = ["value", "type", "path", "parent"];
|
|
2
|
+
|
|
2
3
|
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
4
|
+
|
|
3
5
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
6
|
+
|
|
4
7
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
8
|
+
|
|
5
9
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
10
|
+
|
|
6
11
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
12
|
+
|
|
7
13
|
import { cloneDeep, get, memoize, flatten, uniqBy } from 'lodash';
|
|
8
14
|
import { isKeyedObject, isReference, isBlock, isBlockSchemaType, isSpanSchemaType, isTypedObject } from '@sanity/types';
|
|
9
15
|
import formatDate from 'date-fns/format';
|
|
@@ -17,6 +23,7 @@ const ValidationError = class ValidationError2 {
|
|
|
17
23
|
this.children = options.children;
|
|
18
24
|
this.operation = options.operation;
|
|
19
25
|
}
|
|
26
|
+
|
|
20
27
|
cloneWithMessage(msg) {
|
|
21
28
|
return new ValidationError2(msg, {
|
|
22
29
|
paths: this.paths,
|
|
@@ -24,49 +31,66 @@ const ValidationError = class ValidationError2 {
|
|
|
24
31
|
operation: this.operation
|
|
25
32
|
});
|
|
26
33
|
}
|
|
34
|
+
|
|
27
35
|
};
|
|
36
|
+
|
|
28
37
|
var escapeRegex = string => {
|
|
29
38
|
return string.replace(/[\^\$\.\*\+\-\?\=\!\:\|\\\/\(\)\[\]\{\}\,]/g, "\\$&");
|
|
30
39
|
};
|
|
40
|
+
|
|
31
41
|
function pathToString() {
|
|
32
42
|
let path = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
33
43
|
return path.reduce((target, segment, i) => {
|
|
34
44
|
const segmentType = typeof segment;
|
|
45
|
+
|
|
35
46
|
if (segmentType === "number") {
|
|
36
47
|
return "".concat(target, "[").concat(segment, "]");
|
|
37
48
|
}
|
|
49
|
+
|
|
38
50
|
if (segmentType === "string") {
|
|
39
51
|
const separator = i === 0 ? "" : ".";
|
|
40
52
|
return "".concat(target).concat(separator).concat(segment);
|
|
41
53
|
}
|
|
54
|
+
|
|
42
55
|
if (isKeyedObject(segment)) {
|
|
43
56
|
return "".concat(target, "[_key==\"").concat(segment._key, "\"]");
|
|
44
57
|
}
|
|
58
|
+
|
|
45
59
|
throw new Error("Unsupported path segment \"".concat(segment, "\""));
|
|
46
60
|
}, "");
|
|
47
61
|
}
|
|
62
|
+
|
|
48
63
|
function isNonNullable$1(t) {
|
|
49
64
|
return t !== null || t !== void 0;
|
|
50
65
|
}
|
|
66
|
+
|
|
51
67
|
function convertToValidationMarker(validatorResult, level, context) {
|
|
52
68
|
var _a;
|
|
69
|
+
|
|
53
70
|
if (!context) {
|
|
54
71
|
throw new Error("missing context");
|
|
55
72
|
}
|
|
73
|
+
|
|
56
74
|
if (validatorResult === true) return [];
|
|
75
|
+
|
|
57
76
|
if (Array.isArray(validatorResult)) {
|
|
58
77
|
return validatorResult.flatMap(child => convertToValidationMarker(child, level, context)).filter(isNonNullable$1);
|
|
59
78
|
}
|
|
79
|
+
|
|
60
80
|
if (typeof validatorResult === "string") {
|
|
61
81
|
return convertToValidationMarker(new ValidationError(validatorResult), level, context);
|
|
62
82
|
}
|
|
83
|
+
|
|
63
84
|
if (!(validatorResult instanceof ValidationError)) {
|
|
64
85
|
if (typeof (validatorResult == null ? void 0 : validatorResult.message) !== "string") {
|
|
65
86
|
throw new Error("".concat(pathToString(context.path), ": Validator must return 'true' if valid or an error message as a string on errors"));
|
|
66
87
|
}
|
|
88
|
+
|
|
67
89
|
return convertToValidationMarker(new ValidationError(validatorResult.message, validatorResult), level, context);
|
|
68
90
|
}
|
|
91
|
+
|
|
69
92
|
const results = [];
|
|
93
|
+
|
|
70
94
|
if (!((_a = validatorResult.paths) == null ? void 0 : _a.length)) {
|
|
71
95
|
return [{
|
|
72
96
|
level: level || "error",
|
|
@@ -74,85 +98,113 @@ function convertToValidationMarker(validatorResult, level, context) {
|
|
|
74
98
|
path: context.path || []
|
|
75
99
|
}];
|
|
76
100
|
}
|
|
101
|
+
|
|
77
102
|
return results.concat(validatorResult.paths.map(path => ({
|
|
78
103
|
path: (context.path || []).concat(path),
|
|
79
104
|
level: level || "error",
|
|
80
105
|
item: validatorResult
|
|
81
106
|
})));
|
|
82
107
|
}
|
|
108
|
+
|
|
83
109
|
const _toString = {}.toString;
|
|
84
110
|
const builtIns = [Object, Function, Array, String, Boolean, Number, Date, RegExp, Error];
|
|
111
|
+
|
|
85
112
|
function isBuiltIn(_constructor) {
|
|
86
113
|
for (let i = 0; i < builtIns.length; i++) {
|
|
87
114
|
if (builtIns[i] === _constructor) return true;
|
|
88
115
|
}
|
|
116
|
+
|
|
89
117
|
return false;
|
|
90
118
|
}
|
|
119
|
+
|
|
91
120
|
function typeString(obj) {
|
|
92
121
|
const stringType = _toString.call(obj).slice(8, -1);
|
|
122
|
+
|
|
93
123
|
if (obj === null || obj === void 0) return stringType.toLowerCase();
|
|
94
124
|
const constructorType = obj.constructor;
|
|
95
125
|
if (constructorType && !isBuiltIn(constructorType)) return constructorType.name;
|
|
96
126
|
return stringType;
|
|
97
127
|
}
|
|
128
|
+
|
|
98
129
|
function deepEquals(a, b) {
|
|
99
130
|
if (a === b) {
|
|
100
131
|
return true;
|
|
101
132
|
}
|
|
133
|
+
|
|
102
134
|
if (Array.isArray(a) && Array.isArray(b)) {
|
|
103
135
|
if (a.length != b.length) return false;
|
|
136
|
+
|
|
104
137
|
for (let i = 0; i < a.length; i++) {
|
|
105
138
|
if (!deepEquals(a[i], b[i])) {
|
|
106
139
|
return false;
|
|
107
140
|
}
|
|
108
141
|
}
|
|
142
|
+
|
|
109
143
|
return true;
|
|
110
144
|
}
|
|
145
|
+
|
|
111
146
|
if (Array.isArray(a) != Array.isArray(b)) {
|
|
112
147
|
return false;
|
|
113
148
|
}
|
|
149
|
+
|
|
114
150
|
if (a && b && typeof a === "object" && typeof b === "object") {
|
|
115
151
|
const keys = Object.keys(a);
|
|
152
|
+
|
|
116
153
|
if (keys.length !== Object.keys(b).length) {
|
|
117
154
|
return false;
|
|
118
155
|
}
|
|
156
|
+
|
|
119
157
|
if (a instanceof Date && b instanceof Date) {
|
|
120
158
|
return a.getTime() === b.getTime();
|
|
121
159
|
}
|
|
160
|
+
|
|
122
161
|
if (a instanceof Date != b instanceof Date) {
|
|
123
162
|
return false;
|
|
124
163
|
}
|
|
164
|
+
|
|
125
165
|
if (a instanceof RegExp && b instanceof RegExp) {
|
|
126
166
|
return a.toString() == b.toString();
|
|
127
167
|
}
|
|
168
|
+
|
|
128
169
|
if (a instanceof RegExp != b instanceof RegExp) {
|
|
129
170
|
return false;
|
|
130
171
|
}
|
|
172
|
+
|
|
131
173
|
for (let i = 0; i < keys.length; i++) {
|
|
132
174
|
if (keys[i] === "_key") {
|
|
133
175
|
continue;
|
|
134
176
|
}
|
|
177
|
+
|
|
135
178
|
if (!Object.prototype.hasOwnProperty.call(b, keys[i])) {
|
|
136
179
|
return false;
|
|
137
180
|
}
|
|
138
181
|
}
|
|
182
|
+
|
|
139
183
|
for (let i = 0; i < keys.length; i++) {
|
|
140
184
|
const key = keys[i];
|
|
185
|
+
|
|
141
186
|
if (key === "_key") {
|
|
142
187
|
continue;
|
|
143
188
|
}
|
|
189
|
+
|
|
144
190
|
if (!deepEquals(a[key], b[key])) {
|
|
145
191
|
return false;
|
|
146
192
|
}
|
|
147
193
|
}
|
|
194
|
+
|
|
148
195
|
return true;
|
|
149
196
|
}
|
|
197
|
+
|
|
150
198
|
return false;
|
|
151
199
|
}
|
|
200
|
+
|
|
152
201
|
const SLOW_VALIDATOR_TIMEOUT = 5e3;
|
|
202
|
+
|
|
153
203
|
const formatValidationErrors = options => {
|
|
154
204
|
var _a;
|
|
205
|
+
|
|
155
206
|
let message;
|
|
207
|
+
|
|
156
208
|
if (options.message) {
|
|
157
209
|
message = options.message;
|
|
158
210
|
} else if (options.results.length === 1) {
|
|
@@ -160,23 +212,28 @@ const formatValidationErrors = options => {
|
|
|
160
212
|
} else {
|
|
161
213
|
message = "[".concat(options.results.map(err => err.item.message).join(" - ".concat(options.operation, " - ")), "]");
|
|
162
214
|
}
|
|
215
|
+
|
|
163
216
|
return new ValidationError(message, {
|
|
164
217
|
children: options.results.length > 1 ? options.results : void 0,
|
|
165
218
|
operation: options.operation
|
|
166
219
|
});
|
|
167
220
|
};
|
|
221
|
+
|
|
168
222
|
const genericValidators = {
|
|
169
223
|
type: (expected, value, message) => {
|
|
170
224
|
const actualType = typeString(value);
|
|
225
|
+
|
|
171
226
|
if (actualType !== expected && actualType !== "undefined") {
|
|
172
227
|
return message || "Expected type \"".concat(expected, "\", got \"").concat(actualType, "\"");
|
|
173
228
|
}
|
|
229
|
+
|
|
174
230
|
return true;
|
|
175
231
|
},
|
|
176
232
|
presence: (expected, value, message) => {
|
|
177
233
|
if (value === void 0 && expected === "required") {
|
|
178
234
|
return message || "Value is required";
|
|
179
235
|
}
|
|
236
|
+
|
|
180
237
|
return true;
|
|
181
238
|
},
|
|
182
239
|
all: async (children, value, message, context) => {
|
|
@@ -201,9 +258,11 @@ const genericValidators = {
|
|
|
201
258
|
},
|
|
202
259
|
valid: (allowedValues, actual, message) => {
|
|
203
260
|
const valueType = typeof actual;
|
|
261
|
+
|
|
204
262
|
if (valueType === "undefined") {
|
|
205
263
|
return true;
|
|
206
264
|
}
|
|
265
|
+
|
|
207
266
|
const value = (valueType === "number" || valueType === "string") && "".concat(actual);
|
|
208
267
|
const strValue = value && value.length > 30 ? "".concat(value.slice(0, 30), "\u2026") : value;
|
|
209
268
|
const defaultMessage = value ? "Value \"".concat(strValue, "\" did not match any allowed values") : "Value did not match any allowed values";
|
|
@@ -214,86 +273,106 @@ const genericValidators = {
|
|
|
214
273
|
console.warn("Custom validator at ".concat(pathToString(context.path), " has taken more than ").concat(SLOW_VALIDATOR_TIMEOUT, "ms to respond"));
|
|
215
274
|
}, SLOW_VALIDATOR_TIMEOUT);
|
|
216
275
|
let result;
|
|
276
|
+
|
|
217
277
|
try {
|
|
218
278
|
result = await fn(value, context);
|
|
219
279
|
} finally {
|
|
220
280
|
clearTimeout(slowTimer);
|
|
221
281
|
}
|
|
282
|
+
|
|
222
283
|
if (typeof result === "string") return message || result;
|
|
223
284
|
return result;
|
|
224
285
|
}
|
|
225
286
|
};
|
|
287
|
+
|
|
226
288
|
const booleanValidators = _objectSpread(_objectSpread({}, genericValidators), {}, {
|
|
227
289
|
presence: (flag, value, message) => {
|
|
228
290
|
if (flag === "required" && typeof value !== "boolean") {
|
|
229
291
|
return message || "Required";
|
|
230
292
|
}
|
|
293
|
+
|
|
231
294
|
return true;
|
|
232
295
|
}
|
|
233
296
|
});
|
|
297
|
+
|
|
234
298
|
const precisionRx = /(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/;
|
|
299
|
+
|
|
235
300
|
const numberValidators = _objectSpread(_objectSpread({}, genericValidators), {}, {
|
|
236
301
|
integer: (_unused, value, message) => {
|
|
237
302
|
if (!Number.isInteger(value)) {
|
|
238
303
|
return message || "Must be an integer";
|
|
239
304
|
}
|
|
305
|
+
|
|
240
306
|
return true;
|
|
241
307
|
},
|
|
242
308
|
precision: (limit, value, message) => {
|
|
243
309
|
if (value === void 0) return true;
|
|
244
310
|
const places = value.toString().match(precisionRx);
|
|
245
311
|
const decimals = Math.max((places[1] ? places[1].length : 0) - (places[2] ? parseInt(places[2], 10) : 0), 0);
|
|
312
|
+
|
|
246
313
|
if (decimals > limit) {
|
|
247
314
|
return message || "Max precision is ".concat(limit);
|
|
248
315
|
}
|
|
316
|
+
|
|
249
317
|
return true;
|
|
250
318
|
},
|
|
251
319
|
min: (minNum, value, message) => {
|
|
252
320
|
if (value >= minNum) {
|
|
253
321
|
return true;
|
|
254
322
|
}
|
|
323
|
+
|
|
255
324
|
return message || "Must be greater than or equal ".concat(minNum);
|
|
256
325
|
},
|
|
257
326
|
max: (maxNum, value, message) => {
|
|
258
327
|
if (value <= maxNum) {
|
|
259
328
|
return true;
|
|
260
329
|
}
|
|
330
|
+
|
|
261
331
|
return message || "Must be less than or equal ".concat(maxNum);
|
|
262
332
|
},
|
|
263
333
|
greaterThan: (num, value, message) => {
|
|
264
334
|
if (value > num) {
|
|
265
335
|
return true;
|
|
266
336
|
}
|
|
337
|
+
|
|
267
338
|
return message || "Must be greater than ".concat(num);
|
|
268
339
|
},
|
|
269
340
|
lessThan: (maxNum, value, message) => {
|
|
270
341
|
if (value < maxNum) {
|
|
271
342
|
return true;
|
|
272
343
|
}
|
|
344
|
+
|
|
273
345
|
return message || "Must be less than ".concat(maxNum);
|
|
274
346
|
}
|
|
275
347
|
});
|
|
348
|
+
|
|
276
349
|
const DUMMY_ORIGIN = "http://sanity";
|
|
277
350
|
const emailRegex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
|
351
|
+
|
|
278
352
|
const isRelativeUrl = url => /^\.*\//.test(url);
|
|
353
|
+
|
|
279
354
|
const stringValidators = _objectSpread(_objectSpread({}, genericValidators), {}, {
|
|
280
355
|
min: (minLength, value, message) => {
|
|
281
356
|
if (!value || value.length >= minLength) {
|
|
282
357
|
return true;
|
|
283
358
|
}
|
|
359
|
+
|
|
284
360
|
return message || "Must be at least ".concat(minLength, " characters long");
|
|
285
361
|
},
|
|
286
362
|
max: (maxLength, value, message) => {
|
|
287
363
|
if (!value || value.length <= maxLength) {
|
|
288
364
|
return true;
|
|
289
365
|
}
|
|
366
|
+
|
|
290
367
|
return message || "Must be at most ".concat(maxLength, " characters long");
|
|
291
368
|
},
|
|
292
369
|
length: (wantedLength, value, message) => {
|
|
293
370
|
const strValue = value || "";
|
|
371
|
+
|
|
294
372
|
if (strValue.length === wantedLength) {
|
|
295
373
|
return true;
|
|
296
374
|
}
|
|
375
|
+
|
|
297
376
|
return message || "Must be exactly ".concat(wantedLength, " characters long");
|
|
298
377
|
},
|
|
299
378
|
uri: (constraints, value, message) => {
|
|
@@ -307,41 +386,52 @@ const stringValidators = _objectSpread(_objectSpread({}, genericValidators), {},
|
|
|
307
386
|
} = options;
|
|
308
387
|
const allowRelative = options.allowRelative || relativeOnly;
|
|
309
388
|
let url;
|
|
389
|
+
|
|
310
390
|
try {
|
|
311
391
|
url = allowRelative ? new URL(strValue, DUMMY_ORIGIN) : new URL(strValue);
|
|
312
392
|
} catch (err) {
|
|
313
393
|
return message || "Not a valid URL";
|
|
314
394
|
}
|
|
395
|
+
|
|
315
396
|
if (relativeOnly && url.origin !== DUMMY_ORIGIN) {
|
|
316
397
|
return message || "Only relative URLs are allowed";
|
|
317
398
|
}
|
|
399
|
+
|
|
318
400
|
if (!allowRelative && url.origin === DUMMY_ORIGIN && isRelativeUrl(strValue)) {
|
|
319
401
|
return message || "Relative URLs are not allowed";
|
|
320
402
|
}
|
|
403
|
+
|
|
321
404
|
if (!allowCredentials && (url.username || url.password)) {
|
|
322
405
|
return message || "Username/password not allowed";
|
|
323
406
|
}
|
|
407
|
+
|
|
324
408
|
const urlScheme = url.protocol.replace(/:$/, "");
|
|
325
409
|
const matchesAllowedScheme = options.scheme.some(scheme => scheme.test(urlScheme));
|
|
410
|
+
|
|
326
411
|
if (!matchesAllowedScheme) {
|
|
327
412
|
return message || "Does not match allowed protocols/schemes";
|
|
328
413
|
}
|
|
414
|
+
|
|
329
415
|
return true;
|
|
330
416
|
},
|
|
331
417
|
stringCasing: (casing, value, message) => {
|
|
332
418
|
const strValue = value || "";
|
|
419
|
+
|
|
333
420
|
if (casing === "uppercase" && strValue !== strValue.toLocaleUpperCase()) {
|
|
334
421
|
return message || "Must be all uppercase letters";
|
|
335
422
|
}
|
|
423
|
+
|
|
336
424
|
if (casing === "lowercase" && strValue !== strValue.toLocaleLowerCase()) {
|
|
337
425
|
return message || "Must be all lowercase letters";
|
|
338
426
|
}
|
|
427
|
+
|
|
339
428
|
return true;
|
|
340
429
|
},
|
|
341
430
|
presence: (flag, value, message) => {
|
|
342
431
|
if (flag === "required" && !value) {
|
|
343
432
|
return message || "Required";
|
|
344
433
|
}
|
|
434
|
+
|
|
345
435
|
return true;
|
|
346
436
|
},
|
|
347
437
|
regex: (options, value, message) => {
|
|
@@ -353,85 +443,106 @@ const stringValidators = _objectSpread(_objectSpread({}, genericValidators), {},
|
|
|
353
443
|
const regName = name || "\"".concat(pattern.toString(), "\"");
|
|
354
444
|
const strValue = value || "";
|
|
355
445
|
const matches = pattern.test(strValue);
|
|
446
|
+
|
|
356
447
|
if (!invert && !matches || invert && matches) {
|
|
357
448
|
const defaultMessage = invert ? "Should not match ".concat(regName, "-pattern") : "Does not match ".concat(regName, "-pattern");
|
|
358
449
|
return message || defaultMessage;
|
|
359
450
|
}
|
|
451
|
+
|
|
360
452
|
return true;
|
|
361
453
|
},
|
|
362
454
|
email: (_unused, value, message) => {
|
|
363
455
|
const strValue = "".concat(value || "").trim();
|
|
456
|
+
|
|
364
457
|
if (!strValue || emailRegex.test(strValue)) {
|
|
365
458
|
return true;
|
|
366
459
|
}
|
|
460
|
+
|
|
367
461
|
return message || "Must be a valid email address";
|
|
368
462
|
}
|
|
369
463
|
});
|
|
464
|
+
|
|
370
465
|
const arrayValidators = _objectSpread(_objectSpread({}, genericValidators), {}, {
|
|
371
466
|
min: (minLength, value, message) => {
|
|
372
467
|
if (!value || value.length >= minLength) {
|
|
373
468
|
return true;
|
|
374
469
|
}
|
|
470
|
+
|
|
375
471
|
return message || "Must have at least ".concat(minLength, " items");
|
|
376
472
|
},
|
|
377
473
|
max: (maxLength, value, message) => {
|
|
378
474
|
if (!value || value.length <= maxLength) {
|
|
379
475
|
return true;
|
|
380
476
|
}
|
|
477
|
+
|
|
381
478
|
return message || "Must have at most ".concat(maxLength, " items");
|
|
382
479
|
},
|
|
383
480
|
length: (wantedLength, value, message) => {
|
|
384
481
|
if (!value || value.length === wantedLength) {
|
|
385
482
|
return true;
|
|
386
483
|
}
|
|
484
|
+
|
|
387
485
|
return message || "Must have exactly ".concat(wantedLength, " items");
|
|
388
486
|
},
|
|
389
487
|
presence: (flag, value, message) => {
|
|
390
488
|
if (flag === "required" && !value) {
|
|
391
489
|
return message || "Required";
|
|
392
490
|
}
|
|
491
|
+
|
|
393
492
|
return true;
|
|
394
493
|
},
|
|
395
494
|
valid: (allowedValues, values, message) => {
|
|
396
495
|
const valueType = typeof values;
|
|
496
|
+
|
|
397
497
|
if (valueType === "undefined") {
|
|
398
498
|
return true;
|
|
399
499
|
}
|
|
500
|
+
|
|
400
501
|
const paths = [];
|
|
502
|
+
|
|
401
503
|
for (let i = 0; i < values.length; i++) {
|
|
402
504
|
const value = values[i];
|
|
505
|
+
|
|
403
506
|
if (allowedValues.some(expected => deepEquals(expected, value))) {
|
|
404
507
|
continue;
|
|
405
508
|
}
|
|
509
|
+
|
|
406
510
|
const pathSegment = value && value._key ? {
|
|
407
511
|
_key: value._key
|
|
408
512
|
} : i;
|
|
409
513
|
paths.push([pathSegment]);
|
|
410
514
|
}
|
|
515
|
+
|
|
411
516
|
return paths.length === 0 ? true : new ValidationError(message || "Value did not match any allowed values", {
|
|
412
517
|
paths
|
|
413
518
|
});
|
|
414
519
|
},
|
|
415
520
|
unique: (_unused, value, message) => {
|
|
416
521
|
const dupeIndices = [];
|
|
522
|
+
|
|
417
523
|
if (!value) {
|
|
418
524
|
return true;
|
|
419
525
|
}
|
|
526
|
+
|
|
420
527
|
for (let x = 0; x < value.length; x++) {
|
|
421
528
|
for (let y = x + 1; y < value.length; y++) {
|
|
422
529
|
const itemA = value[x];
|
|
423
530
|
const itemB = value[y];
|
|
531
|
+
|
|
424
532
|
if (!deepEquals(itemA, itemB)) {
|
|
425
533
|
continue;
|
|
426
534
|
}
|
|
535
|
+
|
|
427
536
|
if (dupeIndices.indexOf(x) === -1) {
|
|
428
537
|
dupeIndices.push(x);
|
|
429
538
|
}
|
|
539
|
+
|
|
430
540
|
if (dupeIndices.indexOf(y) === -1) {
|
|
431
541
|
dupeIndices.push(y);
|
|
432
542
|
}
|
|
433
543
|
}
|
|
434
544
|
}
|
|
545
|
+
|
|
435
546
|
const paths = dupeIndices.map(idx => {
|
|
436
547
|
const item = value[idx];
|
|
437
548
|
const pathSegment = item && item._key ? {
|
|
@@ -444,44 +555,57 @@ const arrayValidators = _objectSpread(_objectSpread({}, genericValidators), {},
|
|
|
444
555
|
}) : true;
|
|
445
556
|
}
|
|
446
557
|
});
|
|
558
|
+
|
|
447
559
|
const metaKeys = ["_key", "_type", "_weak"];
|
|
560
|
+
|
|
448
561
|
const objectValidators = _objectSpread(_objectSpread({}, genericValidators), {}, {
|
|
449
562
|
presence: (expected, value, message) => {
|
|
450
563
|
if (expected !== "required") {
|
|
451
564
|
return true;
|
|
452
565
|
}
|
|
566
|
+
|
|
453
567
|
const keys = value && Object.keys(value).filter(key => !metaKeys.includes(key));
|
|
568
|
+
|
|
454
569
|
if (value === void 0 || keys && keys.length === 0) {
|
|
455
570
|
return message || "Required";
|
|
456
571
|
}
|
|
572
|
+
|
|
457
573
|
return true;
|
|
458
574
|
},
|
|
459
575
|
reference: async (_unused, value, message, context) => {
|
|
460
576
|
if (!value) {
|
|
461
577
|
return true;
|
|
462
578
|
}
|
|
579
|
+
|
|
463
580
|
if (!isReference(value)) {
|
|
464
581
|
return message || true;
|
|
465
582
|
}
|
|
583
|
+
|
|
466
584
|
const {
|
|
467
585
|
type,
|
|
468
586
|
getDocumentExists
|
|
469
587
|
} = context;
|
|
588
|
+
|
|
470
589
|
if (!type) {
|
|
471
590
|
throw new Error("`type` was not provided in validation context");
|
|
472
591
|
}
|
|
592
|
+
|
|
473
593
|
if ("weak" in type && type.weak) {
|
|
474
594
|
return true;
|
|
475
595
|
}
|
|
596
|
+
|
|
476
597
|
if (!getDocumentExists) {
|
|
477
598
|
throw new Error("`getDocumentExists` was not provided in validation context");
|
|
478
599
|
}
|
|
600
|
+
|
|
479
601
|
const exists = await getDocumentExists({
|
|
480
602
|
id: value._ref
|
|
481
603
|
});
|
|
604
|
+
|
|
482
605
|
if (!exists) {
|
|
483
606
|
return "This reference must be published";
|
|
484
607
|
}
|
|
608
|
+
|
|
485
609
|
return true;
|
|
486
610
|
},
|
|
487
611
|
assetRequired: (flag, value, message) => {
|
|
@@ -489,82 +613,106 @@ const objectValidators = _objectSpread(_objectSpread({}, genericValidators), {},
|
|
|
489
613
|
const assetType = flag.assetType || "Asset";
|
|
490
614
|
return message || "".concat(assetType, " required");
|
|
491
615
|
}
|
|
616
|
+
|
|
492
617
|
return true;
|
|
493
618
|
}
|
|
494
619
|
});
|
|
620
|
+
|
|
495
621
|
function isRecord$1(obj) {
|
|
496
622
|
return typeof obj === "object" && obj !== null && !Array.isArray(obj);
|
|
497
623
|
}
|
|
624
|
+
|
|
498
625
|
const isoDate = /^(?:[-+]\d{2})?(?:\d{4}(?!\d{2}\b))(?:(-?)(?:(?:0[1-9]|1[0-2])(?:\1(?:[12]\d|0[1-9]|3[01]))?|W(?:[0-4]\d|5[0-2])(?:-?[1-7])?|(?:00[1-9]|0[1-9]\d|[12]\d{2}|3(?:[0-5]\d|6[1-6])))(?![T]$|[T][\d]+Z$)(?:[T\s](?:(?:(?:[01]\d|2[0-3])(?:(:?)[0-5]\d)?|24:?00)(?:[.,]\d+(?!:))?)(?:\2[0-5]\d(?:[.,]\d+)?)?(?:[Z]|(?:[+-])(?:[01]\d|2[0-3])(?::?[0-5]\d)?)?)?)?$/;
|
|
626
|
+
|
|
499
627
|
const getFormattedDate = function () {
|
|
500
628
|
let type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
|
|
501
629
|
let value = arguments.length > 1 ? arguments[1] : undefined;
|
|
502
630
|
let options = arguments.length > 2 ? arguments[2] : undefined;
|
|
503
631
|
let format = "yyyy-MM-dd";
|
|
632
|
+
|
|
504
633
|
if (options && options.dateFormat) {
|
|
505
634
|
format = options.dateFormat;
|
|
506
635
|
}
|
|
636
|
+
|
|
507
637
|
if (type === "date") {
|
|
508
638
|
return formatDate(new Date(value), format);
|
|
509
639
|
}
|
|
640
|
+
|
|
510
641
|
if (options && options.timeFormat) {
|
|
511
642
|
format += " ".concat(options.timeFormat);
|
|
512
643
|
} else {
|
|
513
644
|
format += " HH:mm";
|
|
514
645
|
}
|
|
646
|
+
|
|
515
647
|
return formatDate(new Date(value), format);
|
|
516
648
|
};
|
|
649
|
+
|
|
517
650
|
function parseDate(date) {
|
|
518
651
|
let throwOnError = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
519
652
|
if (!date) return null;
|
|
520
653
|
if (date === "now") return new Date();
|
|
521
654
|
const parsed = new Date(date);
|
|
522
655
|
const isInvalid = isNaN(parsed.getTime());
|
|
656
|
+
|
|
523
657
|
if (isInvalid && throwOnError) {
|
|
524
658
|
throw new Error("Unable to parse \"".concat(date, "\" to a date"));
|
|
525
659
|
}
|
|
660
|
+
|
|
526
661
|
return isInvalid ? null : parsed;
|
|
527
662
|
}
|
|
663
|
+
|
|
528
664
|
const dateValidators = _objectSpread(_objectSpread({}, genericValidators), {}, {
|
|
529
665
|
type: (_unused, value, message) => {
|
|
530
666
|
const strVal = "".concat(value);
|
|
667
|
+
|
|
531
668
|
if (!strVal || isoDate.test(value)) {
|
|
532
669
|
return true;
|
|
533
670
|
}
|
|
671
|
+
|
|
534
672
|
return message || "Must be a valid ISO-8601 formatted date string";
|
|
535
673
|
},
|
|
536
674
|
min: (minDate, value, message, context) => {
|
|
537
675
|
const dateVal = parseDate(value);
|
|
676
|
+
|
|
538
677
|
if (!dateVal) {
|
|
539
678
|
return true;
|
|
540
679
|
}
|
|
680
|
+
|
|
541
681
|
if (!value || dateVal >= parseDate(minDate, true)) {
|
|
542
682
|
return true;
|
|
543
683
|
}
|
|
684
|
+
|
|
544
685
|
if (!context.type) {
|
|
545
686
|
throw new Error("`type` was not provided in validation context.");
|
|
546
687
|
}
|
|
688
|
+
|
|
547
689
|
const dateTimeOptions = isRecord$1(context.type.options) ? context.type.options : {};
|
|
548
690
|
const date = getFormattedDate(context.type.name, minDate, dateTimeOptions);
|
|
549
691
|
return message || "Must be at or after ".concat(date);
|
|
550
692
|
},
|
|
551
693
|
max: (maxDate, value, message, context) => {
|
|
552
694
|
const dateVal = parseDate(value);
|
|
695
|
+
|
|
553
696
|
if (!dateVal) {
|
|
554
697
|
return true;
|
|
555
698
|
}
|
|
699
|
+
|
|
556
700
|
if (!value || dateVal <= parseDate(maxDate, true)) {
|
|
557
701
|
return true;
|
|
558
702
|
}
|
|
703
|
+
|
|
559
704
|
if (!context.type) {
|
|
560
705
|
throw new Error("`type` was not provided in validation context.");
|
|
561
706
|
}
|
|
707
|
+
|
|
562
708
|
const dateTimeOptions = isRecord$1(context.type.options) ? context.type.options : {};
|
|
563
709
|
const date = getFormattedDate(context.type.name, maxDate, dateTimeOptions);
|
|
564
710
|
return message || "Must be at or before ".concat(date);
|
|
565
711
|
}
|
|
566
712
|
});
|
|
713
|
+
|
|
567
714
|
var _a;
|
|
715
|
+
|
|
568
716
|
const typeValidators = {
|
|
569
717
|
Boolean: booleanValidators,
|
|
570
718
|
Number: numberValidators,
|
|
@@ -573,13 +721,16 @@ const typeValidators = {
|
|
|
573
721
|
Object: objectValidators,
|
|
574
722
|
Date: dateValidators
|
|
575
723
|
};
|
|
724
|
+
|
|
576
725
|
const getBaseType = type => {
|
|
577
726
|
return type && type.type ? getBaseType(type.type) : type;
|
|
578
727
|
};
|
|
728
|
+
|
|
579
729
|
const isFieldRef = constraint => {
|
|
580
730
|
if (typeof constraint !== "object" || !constraint) return false;
|
|
581
731
|
return constraint.type === Rule.FIELD_REF;
|
|
582
732
|
};
|
|
733
|
+
|
|
583
734
|
const EMPTY_ARRAY = [];
|
|
584
735
|
const FIELD_REF = Symbol("FIELD_REF");
|
|
585
736
|
const ruleConstraintTypes$1 = ["Array", "Boolean", "Date", "Number", "Object", "String"];
|
|
@@ -596,29 +747,34 @@ const Rule = (_a = class {
|
|
|
596
747
|
this._typeDef = typeDef;
|
|
597
748
|
this.reset();
|
|
598
749
|
}
|
|
750
|
+
|
|
599
751
|
_mergeRequired(next) {
|
|
600
752
|
if (this._required === "required" || next._required === "required") return "required";
|
|
601
753
|
if (this._required === "optional" || next._required === "optional") return "optional";
|
|
602
754
|
return void 0;
|
|
603
755
|
}
|
|
756
|
+
|
|
604
757
|
error(message) {
|
|
605
758
|
const rule = this.clone();
|
|
606
759
|
rule._level = "error";
|
|
607
760
|
rule._message = message || void 0;
|
|
608
761
|
return rule;
|
|
609
762
|
}
|
|
763
|
+
|
|
610
764
|
warning(message) {
|
|
611
765
|
const rule = this.clone();
|
|
612
766
|
rule._level = "warning";
|
|
613
767
|
rule._message = message || void 0;
|
|
614
768
|
return rule;
|
|
615
769
|
}
|
|
770
|
+
|
|
616
771
|
info(message) {
|
|
617
772
|
const rule = this.clone();
|
|
618
773
|
rule._level = "info";
|
|
619
774
|
rule._message = message || void 0;
|
|
620
775
|
return rule;
|
|
621
776
|
}
|
|
777
|
+
|
|
622
778
|
reset() {
|
|
623
779
|
this._type = this._type || void 0;
|
|
624
780
|
this._rules = (this._rules || []).filter(rule => rule.flag === "type");
|
|
@@ -628,9 +784,11 @@ const Rule = (_a = class {
|
|
|
628
784
|
this._fieldRules = void 0;
|
|
629
785
|
return this;
|
|
630
786
|
}
|
|
787
|
+
|
|
631
788
|
isRequired() {
|
|
632
789
|
return this._required === "required";
|
|
633
790
|
}
|
|
791
|
+
|
|
634
792
|
clone() {
|
|
635
793
|
const rule = new _a();
|
|
636
794
|
rule._type = this._type;
|
|
@@ -642,6 +800,7 @@ const Rule = (_a = class {
|
|
|
642
800
|
rule._typeDef = this._typeDef;
|
|
643
801
|
return rule;
|
|
644
802
|
}
|
|
803
|
+
|
|
645
804
|
cloneWithRules(rules) {
|
|
646
805
|
const rule = this.clone();
|
|
647
806
|
const newRules = /* @__PURE__ */new Set();
|
|
@@ -649,6 +808,7 @@ const Rule = (_a = class {
|
|
|
649
808
|
if (curr.flag === "type") {
|
|
650
809
|
rule._type = curr.constraint;
|
|
651
810
|
}
|
|
811
|
+
|
|
652
812
|
newRules.add(curr.flag);
|
|
653
813
|
});
|
|
654
814
|
rule._rules = rule._rules.filter(curr => {
|
|
@@ -658,10 +818,12 @@ const Rule = (_a = class {
|
|
|
658
818
|
}).concat(rules);
|
|
659
819
|
return rule;
|
|
660
820
|
}
|
|
821
|
+
|
|
661
822
|
merge(rule) {
|
|
662
823
|
if (this._type && rule._type && this._type !== rule._type) {
|
|
663
824
|
throw new Error("merge() failed: conflicting types");
|
|
664
825
|
}
|
|
826
|
+
|
|
665
827
|
const newRule = this.cloneWithRules(rule._rules);
|
|
666
828
|
newRule._type = this._type || rule._type;
|
|
667
829
|
newRule._message = this._message || rule._message;
|
|
@@ -669,11 +831,14 @@ const Rule = (_a = class {
|
|
|
669
831
|
newRule._level = this._level === "error" ? rule._level : this._level;
|
|
670
832
|
return newRule;
|
|
671
833
|
}
|
|
834
|
+
|
|
672
835
|
type(targetType) {
|
|
673
836
|
const type = "".concat(targetType.slice(0, 1).toUpperCase()).concat(targetType.slice(1));
|
|
837
|
+
|
|
674
838
|
if (!ruleConstraintTypes$1.includes(type)) {
|
|
675
839
|
throw new Error("Unknown type \"".concat(targetType, "\""));
|
|
676
840
|
}
|
|
841
|
+
|
|
677
842
|
const rule = this.cloneWithRules([{
|
|
678
843
|
flag: "type",
|
|
679
844
|
constraint: type
|
|
@@ -681,18 +846,21 @@ const Rule = (_a = class {
|
|
|
681
846
|
rule._type = type;
|
|
682
847
|
return rule;
|
|
683
848
|
}
|
|
849
|
+
|
|
684
850
|
all(children) {
|
|
685
851
|
return this.cloneWithRules([{
|
|
686
852
|
flag: "all",
|
|
687
853
|
constraint: children
|
|
688
854
|
}]);
|
|
689
855
|
}
|
|
856
|
+
|
|
690
857
|
either(children) {
|
|
691
858
|
return this.cloneWithRules([{
|
|
692
859
|
flag: "either",
|
|
693
860
|
constraint: children
|
|
694
861
|
}]);
|
|
695
862
|
}
|
|
863
|
+
|
|
696
864
|
optional() {
|
|
697
865
|
const rule = this.cloneWithRules([{
|
|
698
866
|
flag: "presence",
|
|
@@ -701,6 +869,7 @@ const Rule = (_a = class {
|
|
|
701
869
|
rule._required = "optional";
|
|
702
870
|
return rule;
|
|
703
871
|
}
|
|
872
|
+
|
|
704
873
|
required() {
|
|
705
874
|
const rule = this.cloneWithRules([{
|
|
706
875
|
flag: "presence",
|
|
@@ -709,36 +878,42 @@ const Rule = (_a = class {
|
|
|
709
878
|
rule._required = "required";
|
|
710
879
|
return rule;
|
|
711
880
|
}
|
|
881
|
+
|
|
712
882
|
custom(fn) {
|
|
713
883
|
return this.cloneWithRules([{
|
|
714
884
|
flag: "custom",
|
|
715
885
|
constraint: fn
|
|
716
886
|
}]);
|
|
717
887
|
}
|
|
888
|
+
|
|
718
889
|
block(fn) {
|
|
719
890
|
return this.cloneWithRules([{
|
|
720
891
|
flag: "custom",
|
|
721
892
|
constraint: fn
|
|
722
893
|
}]);
|
|
723
894
|
}
|
|
895
|
+
|
|
724
896
|
min(len) {
|
|
725
897
|
return this.cloneWithRules([{
|
|
726
898
|
flag: "min",
|
|
727
899
|
constraint: len
|
|
728
900
|
}]);
|
|
729
901
|
}
|
|
902
|
+
|
|
730
903
|
max(len) {
|
|
731
904
|
return this.cloneWithRules([{
|
|
732
905
|
flag: "max",
|
|
733
906
|
constraint: len
|
|
734
907
|
}]);
|
|
735
908
|
}
|
|
909
|
+
|
|
736
910
|
length(len) {
|
|
737
911
|
return this.cloneWithRules([{
|
|
738
912
|
flag: "length",
|
|
739
913
|
constraint: len
|
|
740
914
|
}]);
|
|
741
915
|
}
|
|
916
|
+
|
|
742
917
|
valid(value) {
|
|
743
918
|
const values = Array.isArray(value) ? value : [value];
|
|
744
919
|
return this.cloneWithRules([{
|
|
@@ -746,55 +921,65 @@ const Rule = (_a = class {
|
|
|
746
921
|
constraint: values
|
|
747
922
|
}]);
|
|
748
923
|
}
|
|
924
|
+
|
|
749
925
|
integer() {
|
|
750
926
|
return this.cloneWithRules([{
|
|
751
927
|
flag: "integer"
|
|
752
928
|
}]);
|
|
753
929
|
}
|
|
930
|
+
|
|
754
931
|
precision(limit) {
|
|
755
932
|
return this.cloneWithRules([{
|
|
756
933
|
flag: "precision",
|
|
757
934
|
constraint: limit
|
|
758
935
|
}]);
|
|
759
936
|
}
|
|
937
|
+
|
|
760
938
|
positive() {
|
|
761
939
|
return this.cloneWithRules([{
|
|
762
940
|
flag: "min",
|
|
763
941
|
constraint: 0
|
|
764
942
|
}]);
|
|
765
943
|
}
|
|
944
|
+
|
|
766
945
|
negative() {
|
|
767
946
|
return this.cloneWithRules([{
|
|
768
947
|
flag: "lessThan",
|
|
769
948
|
constraint: 0
|
|
770
949
|
}]);
|
|
771
950
|
}
|
|
951
|
+
|
|
772
952
|
greaterThan(num) {
|
|
773
953
|
return this.cloneWithRules([{
|
|
774
954
|
flag: "greaterThan",
|
|
775
955
|
constraint: num
|
|
776
956
|
}]);
|
|
777
957
|
}
|
|
958
|
+
|
|
778
959
|
lessThan(num) {
|
|
779
960
|
return this.cloneWithRules([{
|
|
780
961
|
flag: "lessThan",
|
|
781
962
|
constraint: num
|
|
782
963
|
}]);
|
|
783
964
|
}
|
|
965
|
+
|
|
784
966
|
uppercase() {
|
|
785
967
|
return this.cloneWithRules([{
|
|
786
968
|
flag: "stringCasing",
|
|
787
969
|
constraint: "uppercase"
|
|
788
970
|
}]);
|
|
789
971
|
}
|
|
972
|
+
|
|
790
973
|
lowercase() {
|
|
791
974
|
return this.cloneWithRules([{
|
|
792
975
|
flag: "stringCasing",
|
|
793
976
|
constraint: "lowercase"
|
|
794
977
|
}]);
|
|
795
978
|
}
|
|
979
|
+
|
|
796
980
|
regex(pattern, a, b) {
|
|
797
981
|
var _a2, _b;
|
|
982
|
+
|
|
798
983
|
const name = typeof a === "string" ? a : (_a2 = a == null ? void 0 : a.name) != null ? _a2 : b == null ? void 0 : b.name;
|
|
799
984
|
const invert = typeof a === "string" ? false : (_b = a == null ? void 0 : a.invert) != null ? _b : b == null ? void 0 : b.invert;
|
|
800
985
|
const constraint = {
|
|
@@ -807,23 +992,28 @@ const Rule = (_a = class {
|
|
|
807
992
|
constraint
|
|
808
993
|
}]);
|
|
809
994
|
}
|
|
995
|
+
|
|
810
996
|
email() {
|
|
811
997
|
return this.cloneWithRules([{
|
|
812
998
|
flag: "email"
|
|
813
999
|
}]);
|
|
814
1000
|
}
|
|
1001
|
+
|
|
815
1002
|
uri(opts) {
|
|
816
1003
|
const optsScheme = (opts == null ? void 0 : opts.scheme) || ["http", "https"];
|
|
817
1004
|
const schemes = Array.isArray(optsScheme) ? optsScheme : [optsScheme];
|
|
1005
|
+
|
|
818
1006
|
if (!schemes.length) {
|
|
819
1007
|
throw new Error("scheme must have at least 1 scheme specified");
|
|
820
1008
|
}
|
|
1009
|
+
|
|
821
1010
|
const constraint = {
|
|
822
1011
|
options: {
|
|
823
1012
|
scheme: schemes.map(scheme => {
|
|
824
1013
|
if (!(scheme instanceof RegExp) && typeof scheme !== "string") {
|
|
825
1014
|
throw new Error("scheme must be a RegExp or a String");
|
|
826
1015
|
}
|
|
1016
|
+
|
|
827
1017
|
return typeof scheme === "string" ? new RegExp("^".concat(escapeRegex(scheme), "$")) : scheme;
|
|
828
1018
|
}),
|
|
829
1019
|
allowRelative: (opts == null ? void 0 : opts.allowRelative) || false,
|
|
@@ -836,32 +1026,39 @@ const Rule = (_a = class {
|
|
|
836
1026
|
constraint
|
|
837
1027
|
}]);
|
|
838
1028
|
}
|
|
1029
|
+
|
|
839
1030
|
unique() {
|
|
840
1031
|
return this.cloneWithRules([{
|
|
841
1032
|
flag: "unique"
|
|
842
1033
|
}]);
|
|
843
1034
|
}
|
|
1035
|
+
|
|
844
1036
|
reference() {
|
|
845
1037
|
return this.cloneWithRules([{
|
|
846
1038
|
flag: "reference"
|
|
847
1039
|
}]);
|
|
848
1040
|
}
|
|
1041
|
+
|
|
849
1042
|
fields(rules) {
|
|
850
1043
|
if (this._type !== "Object") {
|
|
851
1044
|
throw new Error("fields() can only be called on an object type");
|
|
852
1045
|
}
|
|
1046
|
+
|
|
853
1047
|
const rule = this.cloneWithRules([]);
|
|
854
1048
|
rule._fieldRules = rules;
|
|
855
1049
|
return rule;
|
|
856
1050
|
}
|
|
1051
|
+
|
|
857
1052
|
assetRequired() {
|
|
858
1053
|
const base = getBaseType(this._typeDef);
|
|
859
1054
|
let assetType;
|
|
1055
|
+
|
|
860
1056
|
if (base && ["image", "file"].includes(base.name)) {
|
|
861
1057
|
assetType = base.name === "image" ? "Image" : "File";
|
|
862
1058
|
} else {
|
|
863
1059
|
assetType = "Asset";
|
|
864
1060
|
}
|
|
1061
|
+
|
|
865
1062
|
return this.cloneWithRules([{
|
|
866
1063
|
flag: "assetRequired",
|
|
867
1064
|
constraint: {
|
|
@@ -869,62 +1066,80 @@ const Rule = (_a = class {
|
|
|
869
1066
|
}
|
|
870
1067
|
}]);
|
|
871
1068
|
}
|
|
1069
|
+
|
|
872
1070
|
async validate(value, context) {
|
|
873
1071
|
if (!context) {
|
|
874
1072
|
throw new Error("missing context");
|
|
875
1073
|
}
|
|
1074
|
+
|
|
876
1075
|
const valueIsEmpty = value === null || value === void 0;
|
|
1076
|
+
|
|
877
1077
|
if (valueIsEmpty && this._required === "optional") {
|
|
878
1078
|
return EMPTY_ARRAY;
|
|
879
1079
|
}
|
|
1080
|
+
|
|
880
1081
|
const rules = this._required === void 0 && valueIsEmpty ? this._rules.filter(curr => curr.flag === "custom") : this._rules;
|
|
881
1082
|
const validators = this._type && typeValidators[this._type] || genericValidators;
|
|
882
1083
|
const results = await Promise.all(rules.map(async curr => {
|
|
883
1084
|
if (curr.flag === void 0) {
|
|
884
1085
|
throw new Error('Invalid rule, did not contain "flag"-property');
|
|
885
1086
|
}
|
|
1087
|
+
|
|
886
1088
|
const validator = validators[curr.flag];
|
|
1089
|
+
|
|
887
1090
|
if (!validator) {
|
|
888
1091
|
const forType = this._type ? "type \"".concat(this._type, "\"") : "rule without declared type";
|
|
889
1092
|
throw new Error("Validator for flag \"".concat(curr.flag, "\" not found for ").concat(forType));
|
|
890
1093
|
}
|
|
1094
|
+
|
|
891
1095
|
let specConstraint = "constraint" in curr ? curr.constraint : null;
|
|
1096
|
+
|
|
892
1097
|
if (isFieldRef(specConstraint)) {
|
|
893
1098
|
specConstraint = get(context.parent, specConstraint.path);
|
|
894
1099
|
}
|
|
1100
|
+
|
|
895
1101
|
let result;
|
|
1102
|
+
|
|
896
1103
|
try {
|
|
897
1104
|
result = await validator(specConstraint, value, this._message, context);
|
|
898
1105
|
} catch (err) {
|
|
899
1106
|
const errorFromException = new ValidationError("".concat(pathToString(context.path), ": Exception occurred while validating value: ").concat(err.message));
|
|
900
1107
|
return convertToValidationMarker(errorFromException, "error", context);
|
|
901
1108
|
}
|
|
1109
|
+
|
|
902
1110
|
return convertToValidationMarker(result, this._level, context);
|
|
903
1111
|
}));
|
|
904
1112
|
return results.flat();
|
|
905
1113
|
}
|
|
1114
|
+
|
|
906
1115
|
}, _a.FIELD_REF = FIELD_REF, _a.array = def => new _a(def).type("Array"), _a.object = def => new _a(def).type("Object"), _a.string = def => new _a(def).type("String"), _a.number = def => new _a(def).type("Number"), _a.boolean = def => new _a(def).type("Boolean"), _a.dateTime = def => new _a(def).type("Date"), _a.valueOfField = path => ({
|
|
907
1116
|
type: FIELD_REF,
|
|
908
1117
|
path
|
|
909
1118
|
}), _a);
|
|
1119
|
+
|
|
910
1120
|
const requestIdleCallbackShim = function requestIdleCallbackShim2(callback, options) {
|
|
911
1121
|
const start = Date.now();
|
|
912
1122
|
return window.setTimeout(() => {
|
|
913
1123
|
callback({
|
|
914
1124
|
didTimeout: false,
|
|
1125
|
+
|
|
915
1126
|
timeRemaining() {
|
|
916
1127
|
return Math.max(0, Date.now() - start);
|
|
917
1128
|
}
|
|
1129
|
+
|
|
918
1130
|
});
|
|
919
1131
|
}, 0);
|
|
920
1132
|
};
|
|
1133
|
+
|
|
921
1134
|
const cancelIdleCallbackShim = function cancelIdleCallbackShim2(handle) {
|
|
922
1135
|
return window.clearTimeout(handle);
|
|
923
1136
|
};
|
|
1137
|
+
|
|
924
1138
|
const win = typeof window === "undefined" ? void 0 : window;
|
|
925
1139
|
const requestIdleCallback = (win == null ? void 0 : win.requestIdleCallback) || requestIdleCallbackShim;
|
|
926
1140
|
const cancelIdleCallback = (win == null ? void 0 : win.cancelIdleCallback) || cancelIdleCallbackShim;
|
|
927
1141
|
const memoizedWarnOnArraySlug = memoize(warnOnArraySlug);
|
|
1142
|
+
|
|
928
1143
|
function getDocumentIds(id) {
|
|
929
1144
|
const isDraft = id.indexOf("drafts.") === 0;
|
|
930
1145
|
return {
|
|
@@ -932,6 +1147,7 @@ function getDocumentIds(id) {
|
|
|
932
1147
|
draft: isDraft ? id : "drafts.".concat(id)
|
|
933
1148
|
};
|
|
934
1149
|
}
|
|
1150
|
+
|
|
935
1151
|
function serializePath(path) {
|
|
936
1152
|
return path.reduce((target, part, i) => {
|
|
937
1153
|
const isIndex = typeof part === "number";
|
|
@@ -941,6 +1157,7 @@ function serializePath(path) {
|
|
|
941
1157
|
return "".concat(target).concat(add);
|
|
942
1158
|
}, "");
|
|
943
1159
|
}
|
|
1160
|
+
|
|
944
1161
|
const defaultIsUnique = (slug, context) => {
|
|
945
1162
|
const {
|
|
946
1163
|
getClient,
|
|
@@ -949,12 +1166,15 @@ const defaultIsUnique = (slug, context) => {
|
|
|
949
1166
|
type
|
|
950
1167
|
} = context;
|
|
951
1168
|
const schemaOptions = type == null ? void 0 : type.options;
|
|
1169
|
+
|
|
952
1170
|
if (!document) {
|
|
953
1171
|
throw new Error("`document` was not provided in validation context.");
|
|
954
1172
|
}
|
|
1173
|
+
|
|
955
1174
|
if (!path) {
|
|
956
1175
|
throw new Error("`path` was not provided in validation context.");
|
|
957
1176
|
}
|
|
1177
|
+
|
|
958
1178
|
const disableArrayWarning = (schemaOptions == null ? void 0 : schemaOptions.disableArrayWarning) || false;
|
|
959
1179
|
const {
|
|
960
1180
|
published,
|
|
@@ -962,9 +1182,11 @@ const defaultIsUnique = (slug, context) => {
|
|
|
962
1182
|
} = getDocumentIds(document._id);
|
|
963
1183
|
const docType = document._type;
|
|
964
1184
|
const atPath = serializePath(path.concat("current"));
|
|
1185
|
+
|
|
965
1186
|
if (!disableArrayWarning && atPath.includes("[]")) {
|
|
966
1187
|
memoizedWarnOnArraySlug(serializePath(path));
|
|
967
1188
|
}
|
|
1189
|
+
|
|
968
1190
|
const constraints = ["_type == $docType", "!(_id in [$draft, $published])", "".concat(atPath, " == $slug")].join(" && ");
|
|
969
1191
|
return getClient({
|
|
970
1192
|
apiVersion: "2022-09-09"
|
|
@@ -977,34 +1199,46 @@ const defaultIsUnique = (slug, context) => {
|
|
|
977
1199
|
tag: "validation.slug-is-unique"
|
|
978
1200
|
});
|
|
979
1201
|
};
|
|
1202
|
+
|
|
980
1203
|
function warnOnArraySlug(serializedPath) {
|
|
981
1204
|
console.warn(["Slug field at path ".concat(serializedPath, " is within an array and cannot be automatically checked for uniqueness"), "If you need to check for uniqueness, provide your own \"isUnique\" method", "To disable this message, set `disableArrayWarning: true` on the slug `options` field"].join("\n"));
|
|
982
1205
|
}
|
|
1206
|
+
|
|
983
1207
|
const slugValidator = async (value, context) => {
|
|
984
1208
|
var _a;
|
|
1209
|
+
|
|
985
1210
|
if (!value) {
|
|
986
1211
|
return true;
|
|
987
1212
|
}
|
|
1213
|
+
|
|
988
1214
|
if (typeof value !== "object") {
|
|
989
1215
|
return "Slug must be an object";
|
|
990
1216
|
}
|
|
1217
|
+
|
|
991
1218
|
const slugValue = value.current;
|
|
1219
|
+
|
|
992
1220
|
if (!slugValue) {
|
|
993
1221
|
return "Slug must have a value";
|
|
994
1222
|
}
|
|
1223
|
+
|
|
995
1224
|
const options = (_a = context == null ? void 0 : context.type) == null ? void 0 : _a.options;
|
|
996
1225
|
const isUnique = (options == null ? void 0 : options.isUnique) || defaultIsUnique;
|
|
1226
|
+
|
|
997
1227
|
const slugContext = _objectSpread(_objectSpread({}, context), {}, {
|
|
998
1228
|
parent: context.parent,
|
|
999
1229
|
type: context.type,
|
|
1000
1230
|
defaultIsUnique
|
|
1001
1231
|
});
|
|
1232
|
+
|
|
1002
1233
|
const wasUnique = await isUnique(slugValue, slugContext);
|
|
1234
|
+
|
|
1003
1235
|
if (wasUnique) {
|
|
1004
1236
|
return true;
|
|
1005
1237
|
}
|
|
1238
|
+
|
|
1006
1239
|
return "Slug is already in use";
|
|
1007
1240
|
};
|
|
1241
|
+
|
|
1008
1242
|
const ruleConstraintTypes = {
|
|
1009
1243
|
array: true,
|
|
1010
1244
|
boolean: true,
|
|
@@ -1013,7 +1247,9 @@ const ruleConstraintTypes = {
|
|
|
1013
1247
|
object: true,
|
|
1014
1248
|
string: true
|
|
1015
1249
|
};
|
|
1250
|
+
|
|
1016
1251
|
const isRuleConstraint = typeString => typeString in ruleConstraintTypes;
|
|
1252
|
+
|
|
1017
1253
|
function getTypeChain(type, visited) {
|
|
1018
1254
|
if (!type) return [];
|
|
1019
1255
|
if (visited.has(type)) return [];
|
|
@@ -1021,15 +1257,20 @@ function getTypeChain(type, visited) {
|
|
|
1021
1257
|
const next = type.type ? getTypeChain(type.type, visited) : [];
|
|
1022
1258
|
return [...next, type];
|
|
1023
1259
|
}
|
|
1260
|
+
|
|
1024
1261
|
function baseRuleReducer(inputRule, type) {
|
|
1025
1262
|
let baseRule = inputRule;
|
|
1263
|
+
|
|
1026
1264
|
if (isRuleConstraint(type.jsonType)) {
|
|
1027
1265
|
baseRule = baseRule.type(type.jsonType);
|
|
1028
1266
|
}
|
|
1267
|
+
|
|
1029
1268
|
const typeOptionsList = (type == null ? void 0 : type.options) && typeof type.options === "object" && "list" in type.options && type.options.list;
|
|
1269
|
+
|
|
1030
1270
|
if (Array.isArray(typeOptionsList)) {
|
|
1031
1271
|
baseRule = baseRule.valid(typeOptionsList.map(option => extractValueFromListOption(option, type)));
|
|
1032
1272
|
}
|
|
1273
|
+
|
|
1033
1274
|
if (type.name === "datetime") return baseRule.type("Date");
|
|
1034
1275
|
if (type.name === "date") return baseRule.type("Date");
|
|
1035
1276
|
if (type.name === "url") return baseRule.uri();
|
|
@@ -1038,6 +1279,7 @@ function baseRuleReducer(inputRule, type) {
|
|
|
1038
1279
|
if (type.name === "email") return baseRule.email();
|
|
1039
1280
|
return baseRule;
|
|
1040
1281
|
}
|
|
1282
|
+
|
|
1041
1283
|
function hasValueField(typeDef) {
|
|
1042
1284
|
if (!typeDef) return false;
|
|
1043
1285
|
if (!("fields" in typeDef) && typeDef.type) return hasValueField(typeDef.type);
|
|
@@ -1045,58 +1287,79 @@ function hasValueField(typeDef) {
|
|
|
1045
1287
|
if (!Array.isArray(typeDef.fields)) return false;
|
|
1046
1288
|
return typeDef.fields.some(field => field.name === "value");
|
|
1047
1289
|
}
|
|
1290
|
+
|
|
1048
1291
|
function extractValueFromListOption(option, typeDef) {
|
|
1049
1292
|
if (typeDef.jsonType === "object" && hasValueField(typeDef)) return option;
|
|
1050
1293
|
return option.value === void 0 ? option : option.value;
|
|
1051
1294
|
}
|
|
1295
|
+
|
|
1052
1296
|
function normalizeValidationRules(typeDef) {
|
|
1053
1297
|
if (!typeDef) {
|
|
1054
1298
|
return [];
|
|
1055
1299
|
}
|
|
1300
|
+
|
|
1056
1301
|
const validation = typeDef.validation;
|
|
1302
|
+
|
|
1057
1303
|
if (Array.isArray(validation)) {
|
|
1058
1304
|
return validation.flatMap(i => normalizeValidationRules(_objectSpread(_objectSpread({}, typeDef), {}, {
|
|
1059
1305
|
validation: i
|
|
1060
1306
|
})));
|
|
1061
1307
|
}
|
|
1308
|
+
|
|
1062
1309
|
if (validation instanceof Rule) {
|
|
1063
1310
|
return [validation];
|
|
1064
1311
|
}
|
|
1312
|
+
|
|
1065
1313
|
const baseRule = Object.values(getTypeChain(typeDef, /* @__PURE__ */new Set()).reduce((acc, type) => {
|
|
1066
1314
|
acc[type.name] = type;
|
|
1067
1315
|
return acc;
|
|
1068
1316
|
}, {})).reduce(baseRuleReducer, new Rule(typeDef));
|
|
1317
|
+
|
|
1069
1318
|
if (!validation) {
|
|
1070
1319
|
return [baseRule];
|
|
1071
1320
|
}
|
|
1321
|
+
|
|
1072
1322
|
return normalizeValidationRules(_objectSpread(_objectSpread({}, typeDef), {}, {
|
|
1073
1323
|
validation: validation(baseRule)
|
|
1074
1324
|
}));
|
|
1075
1325
|
}
|
|
1326
|
+
|
|
1076
1327
|
const isRecord = maybeRecord => typeof maybeRecord === "object" && maybeRecord !== null && !Array.isArray(maybeRecord);
|
|
1328
|
+
|
|
1077
1329
|
const isNonNullable = value => value !== null && value !== void 0;
|
|
1330
|
+
|
|
1078
1331
|
function resolveTypeForArrayItem(item, candidates) {
|
|
1079
1332
|
if (candidates.length === 1) return candidates[0];
|
|
1333
|
+
|
|
1080
1334
|
const itemType = isTypedObject(item) && item._type;
|
|
1335
|
+
|
|
1081
1336
|
const primitive = item === void 0 || item === null || !itemType && typeString(item).toLowerCase();
|
|
1337
|
+
|
|
1082
1338
|
if (primitive && primitive !== "object") {
|
|
1083
1339
|
return candidates.find(candidate => candidate.jsonType === primitive);
|
|
1084
1340
|
}
|
|
1341
|
+
|
|
1085
1342
|
return candidates.find(candidate => {
|
|
1086
1343
|
var _a;
|
|
1344
|
+
|
|
1087
1345
|
return ((_a = candidate.type) == null ? void 0 : _a.name) === itemType;
|
|
1088
1346
|
}) || candidates.find(candidate => candidate.name === itemType) || candidates.find(candidate => candidate.name === "object" && primitive === "object");
|
|
1089
1347
|
}
|
|
1348
|
+
|
|
1090
1349
|
const EMPTY_MARKERS = [];
|
|
1350
|
+
|
|
1091
1351
|
async function validateDocument(getClient, doc, schema, context) {
|
|
1092
1352
|
return validateDocumentObservable(getClient, doc, schema, context).toPromise();
|
|
1093
1353
|
}
|
|
1354
|
+
|
|
1094
1355
|
function validateDocumentObservable(getClient, doc, schema, context) {
|
|
1095
1356
|
const documentType = schema.get(doc._type);
|
|
1357
|
+
|
|
1096
1358
|
if (!documentType) {
|
|
1097
1359
|
console.warn('Schema type for object type "%s" not found, skipping validation', doc._type);
|
|
1098
1360
|
return of(EMPTY_MARKERS);
|
|
1099
1361
|
}
|
|
1362
|
+
|
|
1100
1363
|
const client = getClient({
|
|
1101
1364
|
apiVersion: "2021-06-07"
|
|
1102
1365
|
});
|
|
@@ -1119,6 +1382,7 @@ function validateDocumentObservable(getClient, doc, schema, context) {
|
|
|
1119
1382
|
console.warn('`configContext.client` is deprecated and will be removed in the next release! Use `context.getClient({apiVersion: "2021-06-07"})` instead');
|
|
1120
1383
|
return original;
|
|
1121
1384
|
}
|
|
1385
|
+
|
|
1122
1386
|
});
|
|
1123
1387
|
}, {});
|
|
1124
1388
|
return validateItemObservable(validationOptions).pipe(catchError(err => {
|
|
@@ -1131,14 +1395,16 @@ function validateDocumentObservable(getClient, doc, schema, context) {
|
|
|
1131
1395
|
}]);
|
|
1132
1396
|
}));
|
|
1133
1397
|
}
|
|
1398
|
+
|
|
1134
1399
|
function validateItemObservable(_ref) {
|
|
1135
1400
|
let {
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1401
|
+
value,
|
|
1402
|
+
type,
|
|
1403
|
+
path = [],
|
|
1404
|
+
parent
|
|
1405
|
+
} = _ref,
|
|
1406
|
+
restOfContext = _objectWithoutProperties(_ref, _excluded);
|
|
1407
|
+
|
|
1142
1408
|
const rules = normalizeValidationRules(type);
|
|
1143
1409
|
const selfChecks = rules.map(rule => defer(() => rule.validate(value, _objectSpread(_objectSpread({}, restOfContext), {}, {
|
|
1144
1410
|
parent,
|
|
@@ -1148,6 +1414,7 @@ function validateItemObservable(_ref) {
|
|
|
1148
1414
|
let nestedChecks = [];
|
|
1149
1415
|
const selfIsRequired = rules.some(rule => rule.isRequired());
|
|
1150
1416
|
const shouldRunNestedObjectValidation = (type == null ? void 0 : type.jsonType) === "object" && (!!value || (value === null || value === void 0) && selfIsRequired);
|
|
1417
|
+
|
|
1151
1418
|
if (shouldRunNestedObjectValidation) {
|
|
1152
1419
|
const fieldTypes = type.fields.reduce((acc, field) => {
|
|
1153
1420
|
acc[field.name] = field.type;
|
|
@@ -1174,7 +1441,9 @@ function validateItemObservable(_ref) {
|
|
|
1174
1441
|
type: field.type
|
|
1175
1442
|
}))));
|
|
1176
1443
|
}
|
|
1444
|
+
|
|
1177
1445
|
const shouldRunNestedValidationForArrays = (type == null ? void 0 : type.jsonType) === "array" && Array.isArray(value);
|
|
1446
|
+
|
|
1178
1447
|
if (shouldRunNestedValidationForArrays) {
|
|
1179
1448
|
nestedChecks = nestedChecks.concat(value.map((item, index) => validateItemObservable(_objectSpread(_objectSpread({}, restOfContext), {}, {
|
|
1180
1449
|
parent: value,
|
|
@@ -1185,7 +1454,9 @@ function validateItemObservable(_ref) {
|
|
|
1185
1454
|
type: resolveTypeForArrayItem(item, type.of)
|
|
1186
1455
|
}))));
|
|
1187
1456
|
}
|
|
1457
|
+
|
|
1188
1458
|
const shouldRunNestedValidationForMarkDefs = isBlock(value) && value.markDefs.length && isBlockSchemaType(type);
|
|
1459
|
+
|
|
1189
1460
|
if (shouldRunNestedValidationForMarkDefs) {
|
|
1190
1461
|
const [spanChildrenField] = type.fields;
|
|
1191
1462
|
const spanType = spanChildrenField.type.of.find(isSpanSchemaType);
|
|
@@ -1202,13 +1473,16 @@ function validateItemObservable(_ref) {
|
|
|
1202
1473
|
type: annotations.get(markDef._type)
|
|
1203
1474
|
}))));
|
|
1204
1475
|
}
|
|
1476
|
+
|
|
1205
1477
|
return defer(() => merge([...selfChecks, ...nestedChecks])).pipe(mergeMap(validateNode => concat(idle(), validateNode), 40), mergeAll(), toArray(), map(flatten), map(results => {
|
|
1206
1478
|
if (rules.some(rule => rule._fieldRules)) {
|
|
1207
1479
|
return uniqBy(results, rule => JSON.stringify(rule));
|
|
1208
1480
|
}
|
|
1481
|
+
|
|
1209
1482
|
return results;
|
|
1210
1483
|
}));
|
|
1211
1484
|
}
|
|
1485
|
+
|
|
1212
1486
|
function idle(timeout) {
|
|
1213
1487
|
return new Observable(observer => {
|
|
1214
1488
|
const handle = requestIdleCallback(() => {
|
|
@@ -1219,41 +1493,50 @@ function idle(timeout) {
|
|
|
1219
1493
|
return () => cancelIdleCallback(handle);
|
|
1220
1494
|
});
|
|
1221
1495
|
}
|
|
1496
|
+
|
|
1222
1497
|
function traverse(typeDef, visited) {
|
|
1223
1498
|
if (visited.has(typeDef)) {
|
|
1224
1499
|
return;
|
|
1225
1500
|
}
|
|
1501
|
+
|
|
1226
1502
|
visited.add(typeDef);
|
|
1227
1503
|
typeDef.validation = normalizeValidationRules(typeDef);
|
|
1504
|
+
|
|
1228
1505
|
if ("fields" in typeDef) {
|
|
1229
1506
|
for (const field of typeDef.fields) {
|
|
1230
1507
|
traverse(field.type, visited);
|
|
1231
1508
|
}
|
|
1232
1509
|
}
|
|
1510
|
+
|
|
1233
1511
|
if ("of" in typeDef) {
|
|
1234
1512
|
for (const candidate of typeDef.of) {
|
|
1235
1513
|
traverse(candidate, visited);
|
|
1236
1514
|
}
|
|
1237
1515
|
}
|
|
1516
|
+
|
|
1238
1517
|
if (typeDef.annotations) {
|
|
1239
1518
|
for (const annotation of typeDef.annotations) {
|
|
1240
1519
|
traverse(annotation, visited);
|
|
1241
1520
|
}
|
|
1242
1521
|
}
|
|
1243
1522
|
}
|
|
1523
|
+
|
|
1244
1524
|
function inferFromSchemaType(typeDef) {
|
|
1245
1525
|
traverse(typeDef, /* @__PURE__ */new Set());
|
|
1246
1526
|
return typeDef;
|
|
1247
1527
|
}
|
|
1528
|
+
|
|
1248
1529
|
function inferFromSchema(schema) {
|
|
1249
1530
|
const typeNames = schema.getTypeNames();
|
|
1250
1531
|
typeNames.forEach(typeName => {
|
|
1251
1532
|
const schemaType = schema.get(typeName);
|
|
1533
|
+
|
|
1252
1534
|
if (schemaType) {
|
|
1253
1535
|
inferFromSchemaType(schemaType);
|
|
1254
1536
|
}
|
|
1255
1537
|
});
|
|
1256
1538
|
return schema;
|
|
1257
1539
|
}
|
|
1540
|
+
|
|
1258
1541
|
export { Rule, inferFromSchema, inferFromSchemaType, validateDocument, validateDocumentObservable };
|
|
1259
1542
|
//# sourceMappingURL=index.esm.js.map
|