@sanity/validation 3.0.0-v3-pkg-utils.54 → 3.0.0-v3-pkg-utils.59

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