@sanity/validation 2.34.0 → 3.0.0-canary.186

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