@valbuild/core 0.79.3 → 0.80.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/dist/declarations/src/index.d.ts +4 -3
  2. package/dist/declarations/src/initSchema.d.ts +5 -5
  3. package/dist/declarations/src/schema/array.d.ts +10 -7
  4. package/dist/declarations/src/schema/boolean.d.ts +11 -8
  5. package/dist/declarations/src/schema/date.d.ts +10 -7
  6. package/dist/declarations/src/schema/file.d.ts +11 -8
  7. package/dist/declarations/src/schema/image.d.ts +11 -8
  8. package/dist/declarations/src/schema/index.d.ts +7 -5
  9. package/dist/declarations/src/schema/keyOf.d.ts +13 -10
  10. package/dist/declarations/src/schema/literal.d.ts +11 -8
  11. package/dist/declarations/src/schema/number.d.ts +14 -9
  12. package/dist/declarations/src/schema/object.d.ts +12 -9
  13. package/dist/declarations/src/schema/record.d.ts +11 -8
  14. package/dist/declarations/src/schema/richtext.d.ts +11 -8
  15. package/dist/declarations/src/schema/string.d.ts +13 -7
  16. package/dist/declarations/src/schema/union.d.ts +14 -10
  17. package/dist/declarations/src/source/remote.d.ts +1 -1
  18. package/dist/{index-041f7675.cjs.dev.js → index-5a7e1014.cjs.dev.js} +528 -280
  19. package/dist/{index-3ecf0ca6.cjs.prod.js → index-74fe6f44.cjs.prod.js} +528 -280
  20. package/dist/{index-1d5e4912.esm.js → index-bcc230b2.esm.js} +528 -280
  21. package/dist/valbuild-core.cjs.dev.js +1 -1
  22. package/dist/valbuild-core.cjs.prod.js +1 -1
  23. package/dist/valbuild-core.esm.js +1 -1
  24. package/package.json +1 -1
  25. package/patch/dist/valbuild-core-patch.cjs.dev.js +1 -1
  26. package/patch/dist/valbuild-core-patch.cjs.prod.js +1 -1
  27. package/patch/dist/valbuild-core-patch.esm.js +2 -2
@@ -188,6 +188,53 @@ var Schema = /*#__PURE__*/function () {
188
188
  _classCallCheck(this, Schema);
189
189
  }
190
190
  return _createClass(Schema, [{
191
+ key: "executeCustomValidateFunctions",
192
+ value: function executeCustomValidateFunctions(src, customValidateFunctions) {
193
+ var errors = [];
194
+ var _iterator = _createForOfIteratorHelper(customValidateFunctions),
195
+ _step;
196
+ try {
197
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
198
+ var customValidateFunction = _step.value;
199
+ try {
200
+ var result = customValidateFunction(src);
201
+ if (result) {
202
+ errors.push({
203
+ message: result,
204
+ value: src
205
+ });
206
+ }
207
+ } catch (err) {
208
+ errors.push({
209
+ message: "Error in custom validate function: ".concat(err instanceof Error ? err.message : String(err)),
210
+ value: src,
211
+ schemaError: true
212
+ });
213
+ }
214
+ }
215
+ } catch (err) {
216
+ _iterator.e(err);
217
+ } finally {
218
+ _iterator.f();
219
+ }
220
+ return errors;
221
+ }
222
+ /**
223
+ * Check if the **root** **type** of source is correct.
224
+ *
225
+ * The difference between assert and validate is:
226
+ * - assert verifies that the root **type** of the source is correct (it does not recurse down). Therefore, assert can be used as a runtime type check.
227
+ * - validate checks the **value** of the source in addition to the type. It recurses down the source.
228
+ *
229
+ * For example assert fails for a StringSchema if the source is not a string,
230
+ * it will not fail if the length is not correct.
231
+ * Validate will check the length and all other constraints.
232
+ *
233
+ * Assert is useful if you have a generic schema and need to make sure the root type is valid.
234
+ * When using assert, you must assert recursively if you want to verify the entire source.
235
+ * For example, if you have an object schema, you must assert each key / value pair manually.
236
+ */
237
+ }, {
191
238
  key: "appendValidationError",
192
239
  value:
193
240
  // remote(): Src extends RemoteCompatibleSource
@@ -198,24 +245,27 @@ var Schema = /*#__PURE__*/function () {
198
245
  // }
199
246
 
200
247
  /** MUTATES! since internal and perf sensitive */
201
- function appendValidationError(current, path, message, value) {
248
+ function appendValidationError(current, path, message, value, schemaError) {
202
249
  if (current) {
203
250
  if (current[path]) {
204
251
  current[path].push({
205
252
  message: message,
206
- value: value
253
+ value: value,
254
+ schemaError: schemaError
207
255
  });
208
256
  } else {
209
257
  current[path] = [{
210
258
  message: message,
211
- value: value
259
+ value: value,
260
+ schemaError: schemaError
212
261
  }];
213
262
  }
214
263
  return current;
215
264
  } else {
216
265
  return _defineProperty({}, path, [{
217
266
  message: message,
218
- value: value
267
+ value: value,
268
+ schemaError: schemaError
219
269
  }]);
220
270
  }
221
271
  }
@@ -330,11 +380,13 @@ var FileSchema = /*#__PURE__*/function (_Schema) {
330
380
  var _this;
331
381
  var opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
332
382
  var isRemote = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
383
+ var customValidateFunctions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
333
384
  _classCallCheck(this, FileSchema);
334
385
  _this = _callSuper(this, FileSchema);
335
386
  _this.options = options;
336
387
  _this.opt = opt;
337
388
  _this.isRemote = isRemote;
389
+ _this.customValidateFunctions = customValidateFunctions;
338
390
  return _this;
339
391
  }
340
392
  _inherits(FileSchema, _Schema);
@@ -345,60 +397,66 @@ var FileSchema = /*#__PURE__*/function (_Schema) {
345
397
  }
346
398
  }, {
347
399
  key: "validate",
348
- value: function validate(path, src) {
400
+ value: function validate(validationFunction) {
401
+ return new FileSchema(this.options, this.opt, this.isRemote, [].concat(_toConsumableArray(this.customValidateFunctions), [validationFunction]));
402
+ }
403
+ }, {
404
+ key: "executeValidate",
405
+ value: function executeValidate(path, src) {
406
+ var customValidationErrors = this.executeCustomValidateFunctions(src, this.customValidateFunctions);
349
407
  if (this.opt && (src === null || src === undefined)) {
350
- return false;
408
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : false;
351
409
  }
352
410
  if (src === null || src === undefined) {
353
- return _defineProperty({}, path, [{
411
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
354
412
  message: "Non-optional file was null or undefined.",
355
413
  value: src
356
- }]);
414
+ }]));
357
415
  }
358
416
  if (typeof src[FILE_REF_PROP] !== "string") {
359
- return _defineProperty({}, path, [{
417
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
360
418
  message: "File did not have a file reference string. Got: ".concat(_typeof(src[FILE_REF_PROP])),
361
419
  value: src
362
- }]);
420
+ }]));
363
421
  }
364
422
  if (this.isRemote && src[VAL_EXTENSION] !== "remote") {
365
- return _defineProperty({}, path, [{
423
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
366
424
  message: "Expected a remote file, but got a local file.",
367
425
  value: src,
368
426
  fixes: ["file:upload-remote"]
369
- }]);
427
+ }]));
370
428
  }
371
429
  if (this.isRemote && src[VAL_EXTENSION] === "remote") {
372
- return _defineProperty({}, path, [{
430
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
373
431
  message: "Remote file was not checked.",
374
432
  value: src,
375
433
  fixes: ["file:check-remote"]
376
- }]);
434
+ }]));
377
435
  }
378
436
  if (!this.isRemote && src[VAL_EXTENSION] === "remote") {
379
- return _defineProperty({}, path, [{
437
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
380
438
  message: "Expected locale file, but found remote.",
381
439
  value: src,
382
440
  fixes: ["file:download-remote"]
383
- }]);
441
+ }]));
384
442
  }
385
443
  if (src[VAL_EXTENSION] !== "file") {
386
- return _defineProperty({}, path, [{
444
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
387
445
  message: "File did not have the valid file extension type. Got: ".concat(src[VAL_EXTENSION]),
388
446
  value: src,
389
447
  fixes: ["file:change-extension", "file:check-metadata"]
390
- }]);
448
+ }]));
391
449
  }
392
- var _ref7 = this.options || {},
393
- accept = _ref7.accept;
394
- var _ref8 = src.metadata || {},
395
- mimeType = _ref8.mimeType;
450
+ var _ref8 = this.options || {},
451
+ accept = _ref8.accept;
452
+ var _ref9 = src.metadata || {},
453
+ mimeType = _ref9.mimeType;
396
454
  if (accept && mimeType && !mimeType.includes("/")) {
397
- return _defineProperty({}, path, [{
455
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
398
456
  message: "Invalid mime type format. Got: ".concat(mimeType),
399
457
  value: src,
400
458
  fixes: ["file:change-extension", "file:check-metadata"]
401
- }]);
459
+ }]));
402
460
  }
403
461
  if (accept && mimeType && mimeType.includes("/")) {
404
462
  var acceptedTypes = accept.split(",").map(function (type) {
@@ -415,45 +473,45 @@ var FileSchema = /*#__PURE__*/function (_Schema) {
415
473
  return acceptedType === mimeType;
416
474
  });
417
475
  if (!isValidMimeType) {
418
- return _defineProperty({}, path, [{
476
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
419
477
  message: "Mime type mismatch. Found '".concat(mimeType, "' but schema accepts '").concat(accept, "'"),
420
478
  value: src,
421
479
  fixes: ["file:change-extension", "file:check-metadata"]
422
- }]);
480
+ }]));
423
481
  }
424
482
  }
425
483
  var fileMimeType = Internal.filenameToMimeType(src[FILE_REF_PROP]);
426
484
  if (!fileMimeType) {
427
- return _defineProperty({}, path, [{
485
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
428
486
  message: "Could not determine mime type from file extension. Got: ".concat(src[FILE_REF_PROP]),
429
487
  value: src,
430
488
  fixes: ["file:change-extension", "file:check-metadata"]
431
- }]);
489
+ }]));
432
490
  }
433
491
  if (fileMimeType !== mimeType) {
434
- return _defineProperty({}, path, [{
492
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
435
493
  message: "Mime type and file extension not matching. Mime type is '".concat(mimeType, "' but file extension is '").concat(fileMimeType, "'"),
436
494
  value: src,
437
495
  fixes: ["file:change-extension", "file:check-metadata"]
438
- }]);
496
+ }]));
439
497
  }
440
498
  if (src.metadata) {
441
- return _defineProperty({}, path, [{
499
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
442
500
  message: "Found metadata, but it could not be validated. File metadata must be an object with the mimeType.",
443
501
  // These validation errors will have to be picked up by logic outside of this package and revalidated. Reasons: 1) we have to read files to verify the metadata, which is handled differently in different runtimes (Browser, QuickJS, Node.js); 2) we want to keep this package dependency free.
444
502
  value: src,
445
503
  fixes: ["file:check-metadata"]
446
- }]);
504
+ }]));
447
505
  }
448
- return _defineProperty({}, path, [{
506
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
449
507
  message: "Missing File metadata.",
450
508
  value: src,
451
509
  fixes: ["file:add-metadata"]
452
- }]);
510
+ }]));
453
511
  }
454
512
  }, {
455
- key: "assert",
456
- value: function assert(path, src) {
513
+ key: "executeAssert",
514
+ value: function executeAssert(path, src) {
457
515
  if (this.opt && src === null) {
458
516
  return {
459
517
  success: true,
@@ -507,13 +565,15 @@ var FileSchema = /*#__PURE__*/function (_Schema) {
507
565
  return new FileSchema(this.options, true);
508
566
  }
509
567
  }, {
510
- key: "serialize",
511
- value: function serialize() {
568
+ key: "executeSerialize",
569
+ value: function executeSerialize() {
570
+ var _this$customValidateF;
512
571
  return {
513
572
  type: "file",
514
573
  options: this.options,
515
574
  opt: this.opt,
516
- remote: this.isRemote
575
+ remote: this.isRemote,
576
+ customValidate: this.customValidateFunctions && ((_this$customValidateF = this.customValidateFunctions) === null || _this$customValidateF === void 0 ? void 0 : _this$customValidateF.length) > 0
517
577
  };
518
578
  }
519
579
  }, {
@@ -610,22 +670,27 @@ var ObjectSchema = /*#__PURE__*/function (_Schema) {
610
670
  function ObjectSchema(items) {
611
671
  var _this;
612
672
  var opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
673
+ var customValidateFunctions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
613
674
  _classCallCheck(this, ObjectSchema);
614
675
  _this = _callSuper(this, ObjectSchema);
615
676
  _this.items = items;
616
677
  _this.opt = opt;
678
+ _this.customValidateFunctions = customValidateFunctions;
617
679
  return _this;
618
680
  }
619
681
  _inherits(ObjectSchema, _Schema);
620
682
  return _createClass(ObjectSchema, [{
621
683
  key: "validate",
622
- value: function validate(path, src) {
623
- var _this2 = this;
684
+ value: function validate(validationFunction) {
685
+ return new ObjectSchema(this.items, this.opt, [].concat(_toConsumableArray(this.customValidateFunctions), [validationFunction]));
686
+ }
687
+ }, {
688
+ key: "executeValidate",
689
+ value: function executeValidate(path, src) {
624
690
  var error = false;
625
-
626
- // TODO: src should never be undefined
691
+ var customValidationErrors = this.executeCustomValidateFunctions(src, this.customValidateFunctions);
627
692
  if (this.opt && (src === null || src === undefined)) {
628
- return false;
693
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : false;
629
694
  }
630
695
  if (src === null) {
631
696
  return _defineProperty({}, path, [{
@@ -641,29 +706,41 @@ var ObjectSchema = /*#__PURE__*/function (_Schema) {
641
706
  message: "Expected 'object', got 'array'"
642
707
  }]);
643
708
  }
644
- Object.entries(this.items).forEach(function (_ref4) {
645
- var _ref5 = _slicedToArray(_ref4, 2),
646
- key = _ref5[0],
647
- schema = _ref5[1];
648
- var subPath = createValPathOfItem(path, key);
709
+ var _iterator = _createForOfIteratorHelper(customValidationErrors),
710
+ _step;
711
+ try {
712
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
713
+ var customValidationError = _step.value;
714
+ error = this.appendValidationError(error, path, customValidationError.message, src, customValidationError.schemaError);
715
+ }
716
+ } catch (err) {
717
+ _iterator.e(err);
718
+ } finally {
719
+ _iterator.f();
720
+ }
721
+ for (var _i = 0, _Object$entries = Object.entries(this.items); _i < _Object$entries.length; _i++) {
722
+ var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
723
+ _key = _Object$entries$_i[0],
724
+ schema = _Object$entries$_i[1];
725
+ var subPath = createValPathOfItem(path, _key);
649
726
  if (!subPath) {
650
- error = _this2.appendValidationError(error, path, "Internal error: could not create path at ".concat(!path && typeof path === "string" ? "<empty string>" : path, " at key ").concat(key),
727
+ error = this.appendValidationError(error, path, "Internal error: could not create path at ".concat(!path && typeof path === "string" ? "<empty string>" : path, " at key ").concat(_key),
651
728
  // Should! never happen
652
729
  src);
653
730
  } else {
654
- var subError = schema.validate(subPath, src[key]);
731
+ var subError = schema["executeValidate"](subPath, src[_key]);
655
732
  if (subError && error) {
656
733
  error = _objectSpread2(_objectSpread2({}, subError), error);
657
734
  } else if (subError) {
658
735
  error = subError;
659
736
  }
660
737
  }
661
- });
738
+ }
662
739
  return error;
663
740
  }
664
741
  }, {
665
- key: "assert",
666
- value: function assert(path, src) {
742
+ key: "executeAssert",
743
+ value: function executeAssert(path, src) {
667
744
  if (this.opt && src === null) {
668
745
  return {
669
746
  success: true,
@@ -697,18 +774,18 @@ var ObjectSchema = /*#__PURE__*/function (_Schema) {
697
774
  };
698
775
  }
699
776
  var errorsAtPath = [];
700
- for (var _i = 0, _Object$keys = Object.keys(this.items); _i < _Object$keys.length; _i++) {
701
- var _key = _Object$keys[_i];
702
- var subPath = createValPathOfItem(path, _key);
777
+ for (var _i2 = 0, _Object$keys = Object.keys(this.items); _i2 < _Object$keys.length; _i2++) {
778
+ var _key2 = _Object$keys[_i2];
779
+ var subPath = createValPathOfItem(path, _key2);
703
780
  if (!subPath) {
704
781
  errorsAtPath.push({
705
- message: "Internal error: could not create path at ".concat(!path && typeof path === "string" ? "<empty string>" : path, " at key ").concat(_key),
782
+ message: "Internal error: could not create path at ".concat(!path && typeof path === "string" ? "<empty string>" : path, " at key ").concat(_key2),
706
783
  // Should! never happen
707
784
  internalError: true
708
785
  });
709
- } else if (!(_key in src)) {
786
+ } else if (!(_key2 in src)) {
710
787
  errorsAtPath.push({
711
- message: "Expected key '".concat(_key, "' not found in object"),
788
+ message: "Expected key '".concat(_key2, "' not found in object"),
712
789
  typeError: true
713
790
  });
714
791
  }
@@ -730,17 +807,19 @@ var ObjectSchema = /*#__PURE__*/function (_Schema) {
730
807
  return new ObjectSchema(this.items, true);
731
808
  }
732
809
  }, {
733
- key: "serialize",
734
- value: function serialize() {
810
+ key: "executeSerialize",
811
+ value: function executeSerialize() {
812
+ var _this$customValidateF;
735
813
  return {
736
814
  type: "object",
737
- items: Object.fromEntries(Object.entries(this.items).map(function (_ref6) {
738
- var _ref7 = _slicedToArray(_ref6, 2),
739
- key = _ref7[0],
740
- schema = _ref7[1];
741
- return [key, schema.serialize()];
815
+ items: Object.fromEntries(Object.entries(this.items).map(function (_ref5) {
816
+ var _ref6 = _slicedToArray(_ref5, 2),
817
+ key = _ref6[0],
818
+ schema = _ref6[1];
819
+ return [key, schema["executeSerialize"]()];
742
820
  })),
743
- opt: this.opt
821
+ opt: this.opt,
822
+ customValidate: this.customValidateFunctions && ((_this$customValidateF = this.customValidateFunctions) === null || _this$customValidateF === void 0 ? void 0 : _this$customValidateF.length) > 0
744
823
  };
745
824
  }
746
825
  }, {
@@ -750,16 +829,16 @@ var ObjectSchema = /*#__PURE__*/function (_Schema) {
750
829
  if (src === null) {
751
830
  return res;
752
831
  }
753
- for (var _key2 in this.items) {
754
- var itemSrc = src[_key2];
832
+ for (var _key3 in this.items) {
833
+ var itemSrc = src[_key3];
755
834
  if (itemSrc === null || itemSrc === undefined) {
756
835
  continue;
757
836
  }
758
- var subPath = unsafeCreateSourcePath(sourcePath, _key2);
759
- var itemResult = this.items[_key2]["executePreview"](subPath, itemSrc);
837
+ var subPath = unsafeCreateSourcePath(sourcePath, _key3);
838
+ var itemResult = this.items[_key3]["executePreview"](subPath, itemSrc);
760
839
  for (var keyS in itemResult) {
761
- var _key3 = keyS;
762
- res[_key3] = itemResult[_key3];
840
+ var _key4 = keyS;
841
+ res[_key4] = itemResult[_key4];
763
842
  }
764
843
  }
765
844
  return res;
@@ -774,18 +853,25 @@ var ArraySchema = /*#__PURE__*/function (_Schema) {
774
853
  function ArraySchema(item) {
775
854
  var _this;
776
855
  var opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
856
+ var customValidateFunctions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
777
857
  _classCallCheck(this, ArraySchema);
778
858
  _this = _callSuper(this, ArraySchema);
779
859
  _defineProperty(_this, "previewInput", null);
780
860
  _this.item = item;
781
861
  _this.opt = opt;
862
+ _this.customValidateFunctions = customValidateFunctions;
782
863
  return _this;
783
864
  }
784
865
  _inherits(ArraySchema, _Schema);
785
866
  return _createClass(ArraySchema, [{
786
867
  key: "validate",
787
- value: function validate(path, src) {
788
- var assertRes = this.assert(path, src);
868
+ value: function validate(validationFunction) {
869
+ return new ArraySchema(this.item, this.opt, [].concat(_toConsumableArray(this.customValidateFunctions), [validationFunction]));
870
+ }
871
+ }, {
872
+ key: "executeValidate",
873
+ value: function executeValidate(path, src) {
874
+ var assertRes = this.executeAssert(path, src);
789
875
  if (!assertRes.success) {
790
876
  return assertRes.errors;
791
877
  }
@@ -799,7 +885,7 @@ var ArraySchema = /*#__PURE__*/function (_Schema) {
799
885
  i = _Object$entries$_i[1];
800
886
  var subPath = unsafeCreateSourcePath(path, Number(idx));
801
887
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
802
- var subError = this.item.validate(subPath, i);
888
+ var subError = this.item["executeValidate"](subPath, i);
803
889
  if (subError) {
804
890
  error = _objectSpread2(_objectSpread2({}, subError), error);
805
891
  }
@@ -810,8 +896,8 @@ var ArraySchema = /*#__PURE__*/function (_Schema) {
810
896
  return error;
811
897
  }
812
898
  }, {
813
- key: "assert",
814
- value: function assert(path, src) {
899
+ key: "executeAssert",
900
+ value: function executeAssert(path, src) {
815
901
  if (src === null && this.opt) {
816
902
  return {
817
903
  success: true,
@@ -855,12 +941,14 @@ var ArraySchema = /*#__PURE__*/function (_Schema) {
855
941
  return new ArraySchema(this.item, true);
856
942
  }
857
943
  }, {
858
- key: "serialize",
859
- value: function serialize() {
944
+ key: "executeSerialize",
945
+ value: function executeSerialize() {
946
+ var _this$customValidateF;
860
947
  return {
861
948
  type: "array",
862
- item: this.item.serialize(),
863
- opt: this.opt
949
+ item: this.item["executeSerialize"](),
950
+ opt: this.opt,
951
+ customValidate: this.customValidateFunctions && ((_this$customValidateF = this.customValidateFunctions) === null || _this$customValidateF === void 0 ? void 0 : _this$customValidateF.length) > 0
864
952
  };
865
953
  }
866
954
  }, {
@@ -940,36 +1028,47 @@ var LiteralSchema = /*#__PURE__*/function (_Schema) {
940
1028
  function LiteralSchema(value) {
941
1029
  var _this;
942
1030
  var opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1031
+ var customValidateFunctions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
943
1032
  _classCallCheck(this, LiteralSchema);
944
1033
  _this = _callSuper(this, LiteralSchema);
945
1034
  _this.value = value;
946
1035
  _this.opt = opt;
1036
+ _this.customValidateFunctions = customValidateFunctions;
947
1037
  return _this;
948
1038
  }
949
1039
  _inherits(LiteralSchema, _Schema);
950
1040
  return _createClass(LiteralSchema, [{
951
1041
  key: "validate",
952
- value: function validate(path, src) {
1042
+ value: function validate(validationFunction) {
1043
+ return new LiteralSchema(this.value, this.opt, [].concat(_toConsumableArray(this.customValidateFunctions), [validationFunction]));
1044
+ }
1045
+ }, {
1046
+ key: "executeValidate",
1047
+ value: function executeValidate(path, src) {
1048
+ var customValidationErrors = this.executeCustomValidateFunctions(src, this.customValidateFunctions);
953
1049
  if (this.opt && (src === null || src === undefined)) {
954
- return false;
1050
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : false;
955
1051
  }
956
1052
  if (typeof src !== "string") {
957
- return _defineProperty({}, path, [{
1053
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
958
1054
  message: "Expected 'string', got '".concat(_typeof(src), "'"),
959
1055
  value: src
960
- }]);
1056
+ }]));
961
1057
  }
962
1058
  if (src !== this.value) {
963
- return _defineProperty({}, path, [{
1059
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
964
1060
  message: "Expected literal '".concat(this.value, "', got '").concat(src, "'"),
965
1061
  value: src
966
- }]);
1062
+ }]));
1063
+ }
1064
+ if (customValidationErrors.length > 0) {
1065
+ return _defineProperty({}, path, customValidationErrors);
967
1066
  }
968
1067
  return false;
969
1068
  }
970
1069
  }, {
971
- key: "assert",
972
- value: function assert(path, src) {
1070
+ key: "executeAssert",
1071
+ value: function executeAssert(path, src) {
973
1072
  if (this.opt && src === null) {
974
1073
  return {
975
1074
  success: true,
@@ -1005,12 +1104,14 @@ var LiteralSchema = /*#__PURE__*/function (_Schema) {
1005
1104
  return new LiteralSchema(this.value, true);
1006
1105
  }
1007
1106
  }, {
1008
- key: "serialize",
1009
- value: function serialize() {
1107
+ key: "executeSerialize",
1108
+ value: function executeSerialize() {
1109
+ var _this$customValidateF;
1010
1110
  return {
1011
1111
  type: "literal",
1012
1112
  value: this.value,
1013
- opt: this.opt
1113
+ opt: this.opt,
1114
+ customValidate: this.customValidateFunctions && ((_this$customValidateF = this.customValidateFunctions) === null || _this$customValidateF === void 0 ? void 0 : _this$customValidateF.length) > 0
1014
1115
  };
1015
1116
  }
1016
1117
  }, {
@@ -1028,80 +1129,87 @@ var UnionSchema = /*#__PURE__*/function (_Schema) {
1028
1129
  function UnionSchema(key, items) {
1029
1130
  var _this;
1030
1131
  var opt = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
1132
+ var customValidateFunctions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
1031
1133
  _classCallCheck(this, UnionSchema);
1032
1134
  _this = _callSuper(this, UnionSchema);
1033
1135
  _this.key = key;
1034
1136
  _this.items = items;
1035
1137
  _this.opt = opt;
1138
+ _this.customValidateFunctions = customValidateFunctions;
1036
1139
  return _this;
1037
1140
  }
1038
1141
  _inherits(UnionSchema, _Schema);
1039
1142
  return _createClass(UnionSchema, [{
1040
1143
  key: "validate",
1041
- value: function validate(path, src) {
1144
+ value: function validate(validationFunction) {
1145
+ return new UnionSchema(this.key, this.items, this.opt, this.customValidateFunctions.concat(validationFunction));
1146
+ }
1147
+ }, {
1148
+ key: "executeValidate",
1149
+ value: function executeValidate(path, src) {
1150
+ var customValidationErrors = this.executeCustomValidateFunctions(src, this.customValidateFunctions);
1042
1151
  var unknownSrc = src;
1043
- var errors = false;
1044
1152
  if (this.opt && unknownSrc === null) {
1045
- return false;
1153
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : false;
1046
1154
  }
1047
1155
  if (!this.key) {
1048
- return _defineProperty({}, path, [{
1156
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1049
1157
  message: "Missing required first argument in union",
1050
1158
  schemaError: true
1051
- }]);
1159
+ }]));
1052
1160
  }
1053
1161
  var key = this.key;
1054
1162
  if (!Array.isArray(this.items)) {
1055
- return _defineProperty({}, path, [{
1163
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1056
1164
  message: "A union schema must take more than 1 schema arguments",
1057
1165
  schemaError: true
1058
- }]);
1166
+ }]));
1059
1167
  }
1060
1168
  if (typeof key === "string") {
1061
1169
  // tagged union
1062
1170
  if (this.items.some(function (item) {
1063
1171
  return !(item instanceof ObjectSchema);
1064
1172
  })) {
1065
- return _defineProperty({}, path, [{
1173
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1066
1174
  message: "Key is a string, so all schema items must be objects",
1067
1175
  schemaError: true
1068
- }]);
1176
+ }]));
1069
1177
  }
1070
1178
  var objectSchemas = this.items;
1071
1179
  var serializedSchemas = objectSchemas.map(function (schema) {
1072
- return schema.serialize();
1180
+ return schema["executeSerialize"]();
1073
1181
  });
1074
1182
  var illegalSchemas = serializedSchemas.filter(function (schema) {
1075
1183
  return !(schema.type === "object") || !(schema.items[key].type === "literal");
1076
1184
  });
1077
1185
  if (illegalSchemas.length > 0) {
1078
- return _defineProperty({}, path, [{
1186
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1079
1187
  message: "All schema items must be objects with a key: ".concat(key, " that is a literal schema. Found: ").concat(JSON.stringify(illegalSchemas, null, 2)),
1080
1188
  schemaError: true
1081
- }]);
1189
+ }]));
1082
1190
  }
1083
1191
  var serializedObjectSchemas = serializedSchemas;
1084
1192
  var optionalLiterals = serializedObjectSchemas.filter(function (schema) {
1085
1193
  return schema.items[key].opt;
1086
1194
  });
1087
1195
  if (optionalLiterals.length > 1) {
1088
- return _defineProperty({}, path, [{
1196
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1089
1197
  message: "Schema cannot have an optional keys: ".concat(key),
1090
1198
  schemaError: true
1091
- }]);
1199
+ }]));
1092
1200
  }
1093
1201
  if (_typeof(unknownSrc) !== "object") {
1094
- return _defineProperty({}, path, [{
1202
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1095
1203
  message: "Expected an object",
1096
1204
  typeError: true
1097
- }]);
1205
+ }]));
1098
1206
  }
1099
1207
  var objectSrc = unknownSrc;
1100
1208
  if (objectSrc[key] === undefined) {
1101
- return _defineProperty({}, path, [{
1209
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1102
1210
  message: "Missing required key: ".concat(key),
1103
1211
  typeError: true
1104
- }]);
1212
+ }]));
1105
1213
  }
1106
1214
  var foundSchemaLiterals = [];
1107
1215
  var _iterator = _createForOfIteratorHelper(serializedObjectSchemas),
@@ -1114,10 +1222,10 @@ var UnionSchema = /*#__PURE__*/function (_Schema) {
1114
1222
  if (!foundSchemaLiterals.includes(schemaKey.value)) {
1115
1223
  foundSchemaLiterals.push(schemaKey.value);
1116
1224
  } else {
1117
- return _defineProperty({}, path, [{
1225
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1118
1226
  message: "Found duplicate key in schema: ".concat(schemaKey.value),
1119
1227
  schemaError: true
1120
- }]);
1228
+ }]));
1121
1229
  }
1122
1230
  }
1123
1231
  }
@@ -1127,7 +1235,7 @@ var UnionSchema = /*#__PURE__*/function (_Schema) {
1127
1235
  _iterator.f();
1128
1236
  }
1129
1237
  var objectSchemaAtKey = objectSchemas.find(function (schema) {
1130
- return !schema.items[key].validate(path, objectSrc[key]);
1238
+ return !schema["items"][key]["executeValidate"](path, objectSrc[key]);
1131
1239
  });
1132
1240
  if (!objectSchemaAtKey) {
1133
1241
  var keyPath = createValPathOfItem(path, key);
@@ -1146,7 +1254,7 @@ var UnionSchema = /*#__PURE__*/function (_Schema) {
1146
1254
  }).join(", "))
1147
1255
  }]);
1148
1256
  }
1149
- var error = objectSchemaAtKey.validate(path, objectSrc);
1257
+ var error = objectSchemaAtKey["executeValidate"](path, objectSrc);
1150
1258
  if (error) {
1151
1259
  return error;
1152
1260
  }
@@ -1162,26 +1270,26 @@ var UnionSchema = /*#__PURE__*/function (_Schema) {
1162
1270
  var literalItems = [key].concat(_toConsumableArray(this.items));
1163
1271
  if (typeof unknownSrc === "string") {
1164
1272
  var isMatch = literalItems.some(function (item) {
1165
- return !item.validate(path, unknownSrc);
1273
+ return !item["executeValidate"](path, unknownSrc);
1166
1274
  });
1167
1275
  if (!isMatch) {
1168
- return _defineProperty({}, path, [{
1276
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1169
1277
  message: "Union must match one of the following: ".concat(literalItems.map(function (item) {
1170
- return "\"".concat(item.value, "\"");
1278
+ return "\"".concat(item["value"], "\"");
1171
1279
  }).join(", "))
1172
- }]);
1280
+ }]));
1173
1281
  }
1174
1282
  }
1175
1283
  } else {
1176
- return _defineProperty({}, path, [{
1284
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1177
1285
  message: "Expected a string or literal"
1178
- }]);
1286
+ }]));
1179
1287
  }
1180
- return errors;
1288
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : false;
1181
1289
  }
1182
1290
  }, {
1183
- key: "assert",
1184
- value: function assert(path, src) {
1291
+ key: "executeAssert",
1292
+ value: function executeAssert(path, src) {
1185
1293
  if (this.opt && src === null) {
1186
1294
  return {
1187
1295
  success: true,
@@ -1216,10 +1324,10 @@ var UnionSchema = /*#__PURE__*/function (_Schema) {
1216
1324
  };
1217
1325
  }
1218
1326
  if (this.key instanceof LiteralSchema) {
1219
- var _ref13;
1327
+ var _ref25;
1220
1328
  var success = false;
1221
1329
  var errors = {};
1222
- var _iterator2 = _createForOfIteratorHelper((_ref13 = [this.key]).concat.apply(_ref13, _toConsumableArray(this.items))),
1330
+ var _iterator2 = _createForOfIteratorHelper((_ref25 = [this.key]).concat.apply(_ref25, _toConsumableArray(this.items))),
1223
1331
  _step2;
1224
1332
  try {
1225
1333
  for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
@@ -1240,7 +1348,7 @@ var UnionSchema = /*#__PURE__*/function (_Schema) {
1240
1348
  }];
1241
1349
  continue;
1242
1350
  }
1243
- var res = itemSchema.assert(path, src);
1351
+ var res = itemSchema["executeAssert"](path, src);
1244
1352
  if (res.success) {
1245
1353
  success = true;
1246
1354
  break;
@@ -1280,7 +1388,7 @@ var UnionSchema = /*#__PURE__*/function (_Schema) {
1280
1388
  try {
1281
1389
  for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
1282
1390
  var _itemSchema = _step3.value;
1283
- var _res = _itemSchema.assert(path, src);
1391
+ var _res = _itemSchema["executeAssert"](path, src);
1284
1392
  if (_res.success) {
1285
1393
  _success = true;
1286
1394
  break;
@@ -1328,25 +1436,29 @@ var UnionSchema = /*#__PURE__*/function (_Schema) {
1328
1436
  return new UnionSchema(this.key, this.items, true);
1329
1437
  }
1330
1438
  }, {
1331
- key: "serialize",
1332
- value: function serialize() {
1439
+ key: "executeSerialize",
1440
+ value: function executeSerialize() {
1441
+ var _this$customValidateF2;
1333
1442
  if (typeof this.key === "string") {
1443
+ var _this$customValidateF;
1334
1444
  return {
1335
1445
  type: "union",
1336
1446
  key: this.key,
1337
1447
  items: this.items.map(function (o) {
1338
- return o.serialize();
1448
+ return o["executeSerialize"]();
1339
1449
  }),
1340
- opt: this.opt
1450
+ opt: this.opt,
1451
+ customValidate: this.customValidateFunctions && ((_this$customValidateF = this.customValidateFunctions) === null || _this$customValidateF === void 0 ? void 0 : _this$customValidateF.length) > 0
1341
1452
  };
1342
1453
  }
1343
1454
  return {
1344
1455
  type: "union",
1345
- key: this.key.serialize(),
1456
+ key: this.key["executeSerialize"](),
1346
1457
  items: this.items.map(function (o) {
1347
- return o.serialize();
1458
+ return o["executeSerialize"]();
1348
1459
  }),
1349
- opt: this.opt
1460
+ opt: this.opt,
1461
+ customValidate: this.customValidateFunctions && ((_this$customValidateF2 = this.customValidateFunctions) === null || _this$customValidateF2 === void 0 ? void 0 : _this$customValidateF2.length) > 0
1350
1462
  };
1351
1463
  }
1352
1464
  }, {
@@ -1365,9 +1477,9 @@ var UnionSchema = /*#__PURE__*/function (_Schema) {
1365
1477
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1366
1478
  function (item) {
1367
1479
  if (item instanceof ObjectSchema) {
1368
- var itemKey = item.items[unionKey];
1480
+ var itemKey = item["items"][unionKey];
1369
1481
  if (itemKey instanceof LiteralSchema) {
1370
- return _typeof(src) === "object" && unionKey in src && itemKey.value === src[unionKey];
1482
+ return _typeof(src) === "object" && unionKey in src && itemKey["value"] === src[unionKey];
1371
1483
  }
1372
1484
  }
1373
1485
  return false;
@@ -1405,11 +1517,13 @@ var ImageSchema = /*#__PURE__*/function (_Schema) {
1405
1517
  var _this;
1406
1518
  var opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1407
1519
  var isRemote = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
1520
+ var customValidateFunctions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
1408
1521
  _classCallCheck(this, ImageSchema);
1409
1522
  _this = _callSuper(this, ImageSchema);
1410
1523
  _this.options = options;
1411
1524
  _this.opt = opt;
1412
1525
  _this.isRemote = isRemote;
1526
+ _this.customValidateFunctions = customValidateFunctions;
1413
1527
  return _this;
1414
1528
  }
1415
1529
  _inherits(ImageSchema, _Schema);
@@ -1420,60 +1534,66 @@ var ImageSchema = /*#__PURE__*/function (_Schema) {
1420
1534
  }
1421
1535
  }, {
1422
1536
  key: "validate",
1423
- value: function validate(path, src) {
1537
+ value: function validate(validationFunction) {
1538
+ return new ImageSchema(this.options, this.opt, this.isRemote, [].concat(_toConsumableArray(this.customValidateFunctions), [validationFunction]));
1539
+ }
1540
+ }, {
1541
+ key: "executeValidate",
1542
+ value: function executeValidate(path, src) {
1543
+ var customValidationErrors = this.executeCustomValidateFunctions(src, this.customValidateFunctions);
1424
1544
  if (this.opt && (src === null || src === undefined)) {
1425
- return false;
1545
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : false;
1426
1546
  }
1427
1547
  if (src === null || src === undefined) {
1428
- return _defineProperty({}, path, [{
1548
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1429
1549
  message: "Non-optional image was null or undefined.",
1430
1550
  value: src
1431
- }]);
1551
+ }]));
1432
1552
  }
1433
1553
  if (this.isRemote && src[VAL_EXTENSION] !== "remote") {
1434
- return _defineProperty({}, path, [{
1554
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1435
1555
  message: "Expected a remote image, but got a local image.",
1436
1556
  value: src,
1437
1557
  fixes: ["image:upload-remote"]
1438
- }]);
1558
+ }]));
1439
1559
  }
1440
1560
  if (this.isRemote && src[VAL_EXTENSION] === "remote") {
1441
- return _defineProperty({}, path, [{
1561
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1442
1562
  message: "Remote image was not checked.",
1443
1563
  value: src,
1444
1564
  fixes: ["image:check-remote"]
1445
- }]);
1565
+ }]));
1446
1566
  }
1447
1567
  if (!this.isRemote && src[VAL_EXTENSION] === "remote") {
1448
- return _defineProperty({}, path, [{
1568
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1449
1569
  message: "Expected locale image, but found remote.",
1450
1570
  value: src,
1451
1571
  fixes: ["image:download-remote"]
1452
- }]);
1572
+ }]));
1453
1573
  }
1454
1574
  if (typeof src[FILE_REF_PROP] !== "string") {
1455
- return _defineProperty({}, path, [{
1575
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1456
1576
  message: "Image did not have a file reference string. Got: ".concat(_typeof(src[FILE_REF_PROP])),
1457
1577
  value: src
1458
- }]);
1578
+ }]));
1459
1579
  }
1460
1580
  if (src[VAL_EXTENSION] !== "file") {
1461
- return _defineProperty({}, path, [{
1581
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1462
1582
  message: "Image did not have the valid file extension type. Got: ".concat(src[VAL_EXTENSION]),
1463
1583
  value: src,
1464
1584
  fixes: ["image:change-extension", "image:check-metadata"]
1465
- }]);
1585
+ }]));
1466
1586
  }
1467
- var _ref7 = this.options || {},
1468
- accept = _ref7.accept;
1469
- var _ref8 = src.metadata || {},
1470
- mimeType = _ref8.mimeType;
1587
+ var _ref8 = this.options || {},
1588
+ accept = _ref8.accept;
1589
+ var _ref9 = src.metadata || {},
1590
+ mimeType = _ref9.mimeType;
1471
1591
  if (accept && mimeType && !mimeType.includes("/")) {
1472
- return _defineProperty({}, path, [{
1592
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1473
1593
  message: "Invalid mime type format. Got: '".concat(mimeType, "'"),
1474
1594
  value: src,
1475
1595
  fixes: ["image:check-metadata"]
1476
- }]);
1596
+ }]));
1477
1597
  }
1478
1598
  if (accept && mimeType && mimeType.includes("/")) {
1479
1599
  var acceptedTypes = accept.split(",").map(function (type) {
@@ -1490,53 +1610,53 @@ var ImageSchema = /*#__PURE__*/function (_Schema) {
1490
1610
  return acceptedType === mimeType;
1491
1611
  });
1492
1612
  if (!isValidMimeType) {
1493
- return _defineProperty({}, path, [{
1613
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1494
1614
  message: "Mime type mismatch. Found '".concat(mimeType, "' but schema accepts '").concat(accept, "'"),
1495
1615
  value: src,
1496
1616
  fixes: ["image:check-metadata"]
1497
- }]);
1617
+ }]));
1498
1618
  }
1499
1619
  }
1500
1620
  var fileMimeType = Internal.filenameToMimeType(src[FILE_REF_PROP]);
1501
1621
  if (!fileMimeType) {
1502
- return _defineProperty({}, path, [{
1622
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1503
1623
  message: "Could not determine mime type from file extension. Got: ".concat(src[FILE_REF_PROP]),
1504
1624
  value: src,
1505
1625
  fixes: ["image:check-metadata"]
1506
- }]);
1626
+ }]));
1507
1627
  }
1508
1628
  if (fileMimeType && mimeType && fileMimeType !== mimeType) {
1509
- return _defineProperty({}, path, [{
1629
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1510
1630
  message: "Mime type and file extension not matching. Mime type is '".concat(mimeType, "' but file extension is '").concat(fileMimeType, "'"),
1511
1631
  value: src,
1512
1632
  fixes: ["image:check-metadata"]
1513
- }]);
1633
+ }]));
1514
1634
  }
1515
1635
  if (src.metadata) {
1516
1636
  if (src.metadata.hotspot) {
1517
1637
  if (_typeof(src.metadata.hotspot) !== "object" || typeof src.metadata.hotspot.x !== "number" || typeof src.metadata.hotspot.y !== "number") {
1518
- return _defineProperty({}, path, [{
1638
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1519
1639
  message: "Hotspot must be an object with x and y as numbers.",
1520
1640
  value: src
1521
- }]);
1641
+ }]));
1522
1642
  }
1523
1643
  }
1524
- return _defineProperty({}, path, [{
1644
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1525
1645
  message: "Found metadata, but it could not be validated. Image metadata must be an object with the required props: width (positive number), height (positive number) and the mime type.",
1526
1646
  // These validation errors will have to be picked up by logic outside of this package and revalidated. Reasons: 1) we have to read files to verify the metadata, which is handled differently in different runtimes (Browser, QuickJS, Node.js); 2) we want to keep this package dependency free.
1527
1647
  value: src,
1528
1648
  fixes: ["image:check-metadata"]
1529
- }]);
1649
+ }]));
1530
1650
  }
1531
- return _defineProperty({}, path, [{
1651
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1532
1652
  message: "Could not validate Image metadata.",
1533
1653
  value: src,
1534
1654
  fixes: ["image:add-metadata"]
1535
- }]);
1655
+ }]));
1536
1656
  }
1537
1657
  }, {
1538
- key: "assert",
1539
- value: function assert(path, src) {
1658
+ key: "executeAssert",
1659
+ value: function executeAssert(path, src) {
1540
1660
  if (this.opt && src === null) {
1541
1661
  return {
1542
1662
  success: true,
@@ -1590,13 +1710,15 @@ var ImageSchema = /*#__PURE__*/function (_Schema) {
1590
1710
  return new ImageSchema(this.options, true, this.isRemote);
1591
1711
  }
1592
1712
  }, {
1593
- key: "serialize",
1594
- value: function serialize() {
1713
+ key: "executeSerialize",
1714
+ value: function executeSerialize() {
1715
+ var _this$customValidateF;
1595
1716
  return {
1596
1717
  type: "image",
1597
1718
  options: this.options,
1598
1719
  opt: this.opt,
1599
- remote: this.isRemote
1720
+ remote: this.isRemote,
1721
+ customValidate: this.customValidateFunctions && ((_this$customValidateF = this.customValidateFunctions) === null || _this$customValidateF === void 0 ? void 0 : _this$customValidateF.length) > 0
1600
1722
  };
1601
1723
  }
1602
1724
  }, {
@@ -1614,10 +1736,12 @@ var RichTextSchema = /*#__PURE__*/function (_Schema) {
1614
1736
  function RichTextSchema(options) {
1615
1737
  var _this;
1616
1738
  var opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1739
+ var customValidateFunctions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
1617
1740
  _classCallCheck(this, RichTextSchema);
1618
1741
  _this = _callSuper(this, RichTextSchema);
1619
1742
  _this.options = options;
1620
1743
  _this.opt = opt;
1744
+ _this.customValidateFunctions = customValidateFunctions;
1621
1745
  return _this;
1622
1746
  }
1623
1747
  _inherits(RichTextSchema, _Schema);
@@ -1637,28 +1761,37 @@ var RichTextSchema = /*#__PURE__*/function (_Schema) {
1637
1761
  }
1638
1762
  }, {
1639
1763
  key: "validate",
1640
- value: function validate(path, src) {
1641
- var assertRes = this.assert(path, src);
1764
+ value: function validate(validationFunction) {
1765
+ return new RichTextSchema(this.options, this.opt, [].concat(_toConsumableArray(this.customValidateFunctions), [validationFunction]));
1766
+ }
1767
+ }, {
1768
+ key: "executeValidate",
1769
+ value: function executeValidate(path, src) {
1770
+ var customValidationErrors = this.executeCustomValidateFunctions(src, this.customValidateFunctions);
1771
+ var assertRes = this.executeAssert(path, src);
1642
1772
  if (!assertRes.success) {
1643
- return _defineProperty({}, path, assertRes.errors[path]);
1773
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : assertRes.errors;
1644
1774
  }
1645
1775
  var nodes = assertRes.data;
1646
1776
  if (nodes === null && this.opt) {
1647
- return false;
1777
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : false;
1648
1778
  }
1649
1779
  if (nodes === null) {
1650
- return _defineProperty({}, path, [{
1780
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
1651
1781
  message: "Expected 'array', got 'null'",
1652
1782
  typeError: true
1653
- }]);
1783
+ }]));
1654
1784
  }
1655
1785
  var current = {};
1656
1786
  var typeErrorRes = this.internalValidate(path, nodes, current);
1657
1787
  if (typeErrorRes) {
1658
- return typeErrorRes;
1788
+ return customValidationErrors.length > 0 ? _objectSpread2(_defineProperty({}, path, customValidationErrors), typeErrorRes) : typeErrorRes;
1659
1789
  }
1660
1790
  if (Object.keys(current).length > 0) {
1661
- return current;
1791
+ return customValidationErrors.length > 0 ? _objectSpread2(_defineProperty({}, path, customValidationErrors), current) : current;
1792
+ }
1793
+ if (customValidationErrors.length > 0) {
1794
+ return _defineProperty({}, path, customValidationErrors);
1662
1795
  }
1663
1796
  return false;
1664
1797
  }
@@ -1755,7 +1888,7 @@ var RichTextSchema = /*#__PURE__*/function (_Schema) {
1755
1888
  }]);
1756
1889
  }
1757
1890
  var srcPath = unsafeCreateSourcePath(path, "src");
1758
- var imageValidationErrors = _typeof((_this2$options$inline4 = _this2.options.inline) === null || _this2$options$inline4 === void 0 ? void 0 : _this2$options$inline4.img) === "object" ? (_this2$options$inline5 = _this2.options.inline) === null || _this2$options$inline5 === void 0 ? void 0 : _this2$options$inline5.img.validate(srcPath, node.src) : new ImageSchema({}, false, false).validate(srcPath, node.src);
1891
+ var imageValidationErrors = _typeof((_this2$options$inline4 = _this2.options.inline) === null || _this2$options$inline4 === void 0 ? void 0 : _this2$options$inline4.img) === "object" ? (_this2$options$inline5 = _this2.options.inline) === null || _this2$options$inline5 === void 0 ? void 0 : _this2$options$inline5.img["executeValidate"](srcPath, node.src) : new ImageSchema({}, false, false)["executeValidate"](srcPath, node.src);
1759
1892
  if (imageValidationErrors) {
1760
1893
  for (var validationErrorPathS in imageValidationErrors) {
1761
1894
  var _current$validationEr;
@@ -1878,8 +2011,8 @@ var RichTextSchema = /*#__PURE__*/function (_Schema) {
1878
2011
  return false;
1879
2012
  }
1880
2013
  }, {
1881
- key: "assert",
1882
- value: function assert(path, src) {
2014
+ key: "executeAssert",
2015
+ value: function executeAssert(path, src) {
1883
2016
  if (this.opt && src === null) {
1884
2017
  return {
1885
2018
  success: true,
@@ -2026,8 +2159,9 @@ var RichTextSchema = /*#__PURE__*/function (_Schema) {
2026
2159
  return new RichTextSchema(this.options, true);
2027
2160
  }
2028
2161
  }, {
2029
- key: "serialize",
2030
- value: function serialize() {
2162
+ key: "executeSerialize",
2163
+ value: function executeSerialize() {
2164
+ var _this$customValidateF;
2031
2165
  var serializedOptions = {
2032
2166
  maxLength: this.options.maxLength,
2033
2167
  minLength: this.options.minLength,
@@ -2035,13 +2169,14 @@ var RichTextSchema = /*#__PURE__*/function (_Schema) {
2035
2169
  block: this.options.block,
2036
2170
  inline: this.options.inline && {
2037
2171
  a: this.options.inline.a,
2038
- img: this.options.inline.img && _typeof(this.options.inline.img) === "object" ? this.options.inline.img.serialize() : this.options.inline.img
2172
+ img: this.options.inline.img && _typeof(this.options.inline.img) === "object" ? this.options.inline.img["executeSerialize"]() : this.options.inline.img
2039
2173
  }
2040
2174
  };
2041
2175
  return {
2042
2176
  type: "richtext",
2043
2177
  opt: this.opt,
2044
- options: serializedOptions
2178
+ options: serializedOptions,
2179
+ customValidate: this.customValidateFunctions && ((_this$customValidateF = this.customValidateFunctions) === null || _this$customValidateF === void 0 ? void 0 : _this$customValidateF.length) > 0
2045
2180
  };
2046
2181
  }
2047
2182
  }, {
@@ -2059,48 +2194,68 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
2059
2194
  function RecordSchema(item) {
2060
2195
  var _this;
2061
2196
  var opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
2197
+ var customValidateFunctions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
2062
2198
  _classCallCheck(this, RecordSchema);
2063
2199
  _this = _callSuper(this, RecordSchema);
2064
2200
  _defineProperty(_this, "previewInput", null);
2065
2201
  _this.item = item;
2066
2202
  _this.opt = opt;
2203
+ _this.customValidateFunctions = customValidateFunctions;
2067
2204
  return _this;
2068
2205
  }
2069
2206
  _inherits(RecordSchema, _Schema);
2070
2207
  return _createClass(RecordSchema, [{
2071
2208
  key: "validate",
2072
- value: function validate(path, src) {
2209
+ value: function validate(validationFunction) {
2210
+ return new RecordSchema(this.item, this.opt, [].concat(_toConsumableArray(this.customValidateFunctions), [validationFunction]));
2211
+ }
2212
+ }, {
2213
+ key: "executeValidate",
2214
+ value: function executeValidate(path, src) {
2073
2215
  var _this2 = this;
2074
2216
  var error = false;
2217
+ var customValidationErrors = this.executeCustomValidateFunctions(src, this.customValidateFunctions);
2075
2218
  if (this.opt && (src === null || src === undefined)) {
2076
- return false;
2219
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : false;
2077
2220
  }
2078
2221
  if (src === null) {
2079
- return _defineProperty({}, path, [{
2222
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
2080
2223
  message: "Expected 'object', got 'null'"
2081
- }]);
2224
+ }]));
2082
2225
  }
2083
2226
  if (_typeof(src) !== "object") {
2084
- return _defineProperty({}, path, [{
2227
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
2085
2228
  message: "Expected 'object', got '".concat(_typeof(src), "'")
2086
- }]);
2229
+ }]));
2087
2230
  }
2088
2231
  if (Array.isArray(src)) {
2089
- return _defineProperty({}, path, [{
2232
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
2090
2233
  message: "Expected 'object', got 'array'"
2091
- }]);
2234
+ }]));
2092
2235
  }
2093
- Object.entries(src).forEach(function (_ref4) {
2094
- var _ref5 = _slicedToArray(_ref4, 2),
2095
- key = _ref5[0],
2096
- elem = _ref5[1];
2236
+ var _iterator = _createForOfIteratorHelper(customValidationErrors),
2237
+ _step;
2238
+ try {
2239
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
2240
+ var customValidationError = _step.value;
2241
+ error = this.appendValidationError(error, path, customValidationError.message, src, customValidationError.schemaError);
2242
+ }
2243
+ } catch (err) {
2244
+ _iterator.e(err);
2245
+ } finally {
2246
+ _iterator.f();
2247
+ }
2248
+ Object.entries(src).forEach(function (_ref5) {
2249
+ var _ref6 = _slicedToArray(_ref5, 2),
2250
+ key = _ref6[0],
2251
+ elem = _ref6[1];
2097
2252
  var subPath = createValPathOfItem(path, key);
2098
2253
  if (!subPath) {
2099
2254
  error = _this2.appendValidationError(error, path, "Internal error: could not create path at ".concat(!path && typeof path === "string" ? "<empty string>" : path, " at key ").concat(elem),
2100
2255
  // Should! never happen
2101
2256
  src);
2102
2257
  } else {
2103
- var subError = _this2.item.validate(subPath, elem);
2258
+ var subError = _this2.item["executeValidate"](subPath, elem);
2104
2259
  if (subError && error) {
2105
2260
  error = _objectSpread2(_objectSpread2({}, subError), error);
2106
2261
  } else if (subError) {
@@ -2111,8 +2266,8 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
2111
2266
  return error;
2112
2267
  }
2113
2268
  }, {
2114
- key: "assert",
2115
- value: function assert(path, src) {
2269
+ key: "executeAssert",
2270
+ value: function executeAssert(path, src) {
2116
2271
  if (this.opt && src === null) {
2117
2272
  return {
2118
2273
  success: true,
@@ -2148,12 +2303,14 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
2148
2303
  return new RecordSchema(this.item, true);
2149
2304
  }
2150
2305
  }, {
2151
- key: "serialize",
2152
- value: function serialize() {
2306
+ key: "executeSerialize",
2307
+ value: function executeSerialize() {
2308
+ var _this$customValidateF;
2153
2309
  return {
2154
2310
  type: "record",
2155
- item: this.item.serialize(),
2156
- opt: this.opt
2311
+ item: this.item["executeSerialize"](),
2312
+ opt: this.opt,
2313
+ customValidate: this.customValidateFunctions && ((_this$customValidateF = this.customValidateFunctions) === null || _this$customValidateF === void 0 ? void 0 : _this$customValidateF.length) > 0
2157
2314
  };
2158
2315
  }
2159
2316
  }, {
@@ -2191,10 +2348,10 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
2191
2348
  data: {
2192
2349
  layout: "list",
2193
2350
  parent: "record",
2194
- items: Object.entries(src).map(function (_ref6) {
2195
- var _ref7 = _slicedToArray(_ref6, 2),
2196
- key = _ref7[0],
2197
- val = _ref7[1];
2351
+ items: Object.entries(src).map(function (_ref7) {
2352
+ var _ref8 = _slicedToArray(_ref7, 2),
2353
+ key = _ref8[0],
2354
+ val = _ref8[1];
2198
2355
  // NB NB: display is actually defined by the user
2199
2356
  var _prepare = prepare({
2200
2357
  key: key,
@@ -2314,6 +2471,7 @@ function resolvePath(path, valModule, schema) {
2314
2471
  throw Error("Unexpected undefined part");
2315
2472
  }
2316
2473
  if (isArraySchema(resolvedSchema)) {
2474
+ var _resolvedSchema;
2317
2475
  if (Number.isNaN(Number(part))) {
2318
2476
  throw Error("Invalid path: array schema ".concat(JSON.stringify(resolvedSchema), " must have a number as path, but got ").concat(part, ". Path: ").concat(path));
2319
2477
  }
@@ -2321,8 +2479,9 @@ function resolvePath(path, valModule, schema) {
2321
2479
  throw Error("Schema type error: expected source to be type of array, but got ".concat(_typeof(resolvedSource)));
2322
2480
  }
2323
2481
  resolvedSource = resolvedSource[part];
2324
- resolvedSchema = resolvedSchema.item;
2482
+ resolvedSchema = resolvedSchema instanceof ArraySchema ? (_resolvedSchema = resolvedSchema) === null || _resolvedSchema === void 0 ? void 0 : _resolvedSchema["item"] : resolvedSchema.item;
2325
2483
  } else if (isRecordSchema(resolvedSchema)) {
2484
+ var _resolvedSchema2;
2326
2485
  if (typeof part !== "string") {
2327
2486
  throw Error("Invalid path: record schema ".concat(resolvedSchema, " must have path: ").concat(part, " as string"));
2328
2487
  }
@@ -2333,7 +2492,7 @@ function resolvePath(path, valModule, schema) {
2333
2492
  throw Error("Invalid path: record source did not have key ".concat(part, " from path: ").concat(path));
2334
2493
  }
2335
2494
  resolvedSource = resolvedSource[part];
2336
- resolvedSchema = resolvedSchema.item;
2495
+ resolvedSchema = resolvedSchema instanceof RecordSchema ? (_resolvedSchema2 = resolvedSchema) === null || _resolvedSchema2 === void 0 ? void 0 : _resolvedSchema2["item"] : resolvedSchema.item;
2337
2496
  } else if (isObjectSchema(resolvedSchema)) {
2338
2497
  if (_typeof(resolvedSource) !== "object") {
2339
2498
  throw Error("Schema type error: expected source to be type of object, but got ".concat(_typeof(resolvedSource)));
@@ -2342,7 +2501,7 @@ function resolvePath(path, valModule, schema) {
2342
2501
  throw Error("Invalid path: object source did not have key ".concat(part, " from path: ").concat(path));
2343
2502
  }
2344
2503
  resolvedSource = resolvedSource === null ? resolvedSource : resolvedSource[part];
2345
- resolvedSchema = resolvedSchema.items[part];
2504
+ resolvedSchema = resolvedSchema instanceof ObjectSchema ? resolvedSchema["items"][part] : resolvedSchema.items[part];
2346
2505
  // } else if (isI18nSchema(resolvedSchema)) {
2347
2506
  // if (!resolvedSchema.locales.includes(part)) {
2348
2507
  // throw Error(
@@ -2408,7 +2567,7 @@ function resolvePath(path, valModule, schema) {
2408
2567
  } else if (isRichTextSchema(resolvedSchema)) {
2409
2568
  if ("src" in resolvedSource && "tag" in resolvedSource && resolvedSource.tag === "img" && parts.length === 0) {
2410
2569
  var _resolvedSchema$optio, _resolvedSchema$optio2;
2411
- resolvedSchema = (_resolvedSchema$optio = resolvedSchema.options) !== null && _resolvedSchema$optio !== void 0 && (_resolvedSchema$optio = _resolvedSchema$optio.inline) !== null && _resolvedSchema$optio !== void 0 && _resolvedSchema$optio.img && typeof ((_resolvedSchema$optio2 = resolvedSchema.options) === null || _resolvedSchema$optio2 === void 0 || (_resolvedSchema$optio2 = _resolvedSchema$optio2.inline) === null || _resolvedSchema$optio2 === void 0 ? void 0 : _resolvedSchema$optio2.img) !== "boolean" ? resolvedSchema.options.inline.img : resolvedSchema;
2570
+ resolvedSchema = resolvedSchema instanceof RichTextSchema ? (_resolvedSchema$optio = resolvedSchema["options"]) !== null && _resolvedSchema$optio !== void 0 && (_resolvedSchema$optio = _resolvedSchema$optio.inline) !== null && _resolvedSchema$optio !== void 0 && _resolvedSchema$optio.img && typeof ((_resolvedSchema$optio2 = resolvedSchema["options"]) === null || _resolvedSchema$optio2 === void 0 || (_resolvedSchema$optio2 = _resolvedSchema$optio2.inline) === null || _resolvedSchema$optio2 === void 0 ? void 0 : _resolvedSchema$optio2.img) !== "boolean" ? resolvedSchema["options"].inline.img : resolvedSchema : resolvedSchema;
2412
2571
  }
2413
2572
  resolvedSource = resolvedSource[part];
2414
2573
  } else {
@@ -2455,6 +2614,7 @@ function safeResolvePath(path, valModule, schema) {
2455
2614
  };
2456
2615
  }
2457
2616
  if (isArraySchema(resolvedSchema)) {
2617
+ var _resolvedSchema3;
2458
2618
  if (Number.isNaN(Number(part))) {
2459
2619
  return {
2460
2620
  v: {
@@ -2482,8 +2642,9 @@ function safeResolvePath(path, valModule, schema) {
2482
2642
  };
2483
2643
  }
2484
2644
  resolvedSource = resolvedSource[part];
2485
- resolvedSchema = resolvedSchema.item;
2645
+ resolvedSchema = resolvedSchema instanceof ArraySchema ? (_resolvedSchema3 = resolvedSchema) === null || _resolvedSchema3 === void 0 ? void 0 : _resolvedSchema3["item"] : resolvedSchema.item;
2486
2646
  } else if (isRecordSchema(resolvedSchema)) {
2647
+ var _resolvedSchema4;
2487
2648
  if (typeof part !== "string") {
2488
2649
  return {
2489
2650
  v: {
@@ -2519,7 +2680,7 @@ function safeResolvePath(path, valModule, schema) {
2519
2680
  };
2520
2681
  }
2521
2682
  resolvedSource = resolvedSource[part];
2522
- resolvedSchema = resolvedSchema.item;
2683
+ resolvedSchema = resolvedSchema instanceof RecordSchema ? (_resolvedSchema4 = resolvedSchema) === null || _resolvedSchema4 === void 0 ? void 0 : _resolvedSchema4["item"] : resolvedSchema.item;
2523
2684
  } else if (isObjectSchema(resolvedSchema)) {
2524
2685
  if (resolvedSource === undefined) {
2525
2686
  return {
@@ -2548,7 +2709,7 @@ function safeResolvePath(path, valModule, schema) {
2548
2709
  };
2549
2710
  }
2550
2711
  resolvedSource = resolvedSource === null ? resolvedSource : resolvedSource[part];
2551
- resolvedSchema = resolvedSchema.items[part];
2712
+ resolvedSchema = resolvedSchema instanceof ObjectSchema ? resolvedSchema["items"][part] : resolvedSchema.items[part];
2552
2713
  // } else if (isI18nSchema(resolvedSchema)) {
2553
2714
  // if (!resolvedSchema.locales.includes(part)) {
2554
2715
  // throw Error(
@@ -2626,7 +2787,7 @@ function safeResolvePath(path, valModule, schema) {
2626
2787
  } else if (isRichTextSchema(resolvedSchema)) {
2627
2788
  if ("src" in resolvedSource && "tag" in resolvedSource && resolvedSource.tag === "img" && parts.length === 0) {
2628
2789
  var _resolvedSchema$optio3, _resolvedSchema$optio4;
2629
- resolvedSchema = (_resolvedSchema$optio3 = resolvedSchema.options) !== null && _resolvedSchema$optio3 !== void 0 && (_resolvedSchema$optio3 = _resolvedSchema$optio3.inline) !== null && _resolvedSchema$optio3 !== void 0 && _resolvedSchema$optio3.img && typeof ((_resolvedSchema$optio4 = resolvedSchema.options) === null || _resolvedSchema$optio4 === void 0 || (_resolvedSchema$optio4 = _resolvedSchema$optio4.inline) === null || _resolvedSchema$optio4 === void 0 ? void 0 : _resolvedSchema$optio4.img) !== "boolean" ? resolvedSchema.options.inline.img : resolvedSchema;
2790
+ resolvedSchema = resolvedSchema instanceof RichTextSchema ? (_resolvedSchema$optio3 = resolvedSchema["options"]) !== null && _resolvedSchema$optio3 !== void 0 && (_resolvedSchema$optio3 = _resolvedSchema$optio3.inline) !== null && _resolvedSchema$optio3 !== void 0 && _resolvedSchema$optio3.img && typeof ((_resolvedSchema$optio4 = resolvedSchema["options"]) === null || _resolvedSchema$optio4 === void 0 || (_resolvedSchema$optio4 = _resolvedSchema$optio4.inline) === null || _resolvedSchema$optio4 === void 0 ? void 0 : _resolvedSchema$optio4.img) !== "boolean" ? resolvedSchema["options"].inline.img : resolvedSchema : resolvedSchema;
2630
2791
  }
2631
2792
  resolvedSource = resolvedSource[part];
2632
2793
  } else {
@@ -2732,30 +2893,54 @@ var NumberSchema = /*#__PURE__*/function (_Schema) {
2732
2893
  function NumberSchema(options) {
2733
2894
  var _this;
2734
2895
  var opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
2896
+ var customValidateFunctions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
2735
2897
  _classCallCheck(this, NumberSchema);
2736
2898
  _this = _callSuper(this, NumberSchema);
2737
2899
  _this.options = options;
2738
2900
  _this.opt = opt;
2901
+ _this.customValidateFunctions = customValidateFunctions;
2739
2902
  return _this;
2740
2903
  }
2741
2904
  _inherits(NumberSchema, _Schema);
2742
2905
  return _createClass(NumberSchema, [{
2743
2906
  key: "validate",
2744
- value: function validate(path, src) {
2907
+ value: function validate(validationFunction) {
2908
+ return new NumberSchema(this.options, this.opt, [].concat(_toConsumableArray(this.customValidateFunctions), [validationFunction]));
2909
+ }
2910
+ }, {
2911
+ key: "executeValidate",
2912
+ value: function executeValidate(path, src) {
2913
+ var _this$options, _this$options2;
2914
+ var customValidationErrors = this.executeCustomValidateFunctions(src, this.customValidateFunctions);
2745
2915
  if (this.opt && (src === null || src === undefined)) {
2746
- return false;
2916
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : false;
2747
2917
  }
2748
2918
  if (typeof src !== "number") {
2749
- return _defineProperty({}, path, [{
2919
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
2750
2920
  message: "Expected 'number', got '".concat(_typeof(src), "'"),
2751
2921
  value: src
2752
- }]);
2922
+ }]));
2923
+ }
2924
+ if ((_this$options = this.options) !== null && _this$options !== void 0 && _this$options.max && src > this.options.max) {
2925
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
2926
+ message: "Expected 'number' less than ".concat(this.options.max),
2927
+ value: src
2928
+ }]));
2929
+ }
2930
+ if ((_this$options2 = this.options) !== null && _this$options2 !== void 0 && _this$options2.min && src < this.options.min) {
2931
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
2932
+ message: "Expected 'number' greater than ".concat(this.options.min),
2933
+ value: src
2934
+ }]));
2935
+ }
2936
+ if (customValidationErrors.length > 0) {
2937
+ return _defineProperty({}, path, customValidationErrors);
2753
2938
  }
2754
2939
  return false;
2755
2940
  }
2756
2941
  }, {
2757
- key: "assert",
2758
- value: function assert(path, src) {
2942
+ key: "executeAssert",
2943
+ value: function executeAssert(path, src) {
2759
2944
  if (this.opt && src === null) {
2760
2945
  return {
2761
2946
  success: true,
@@ -2791,12 +2976,28 @@ var NumberSchema = /*#__PURE__*/function (_Schema) {
2791
2976
  return new NumberSchema(this.options, true);
2792
2977
  }
2793
2978
  }, {
2794
- key: "serialize",
2795
- value: function serialize() {
2979
+ key: "max",
2980
+ value: function max(_max) {
2981
+ return new NumberSchema(_objectSpread2(_objectSpread2({}, this.options), {}, {
2982
+ max: _max
2983
+ }), this.opt);
2984
+ }
2985
+ }, {
2986
+ key: "min",
2987
+ value: function min(_min) {
2988
+ return new NumberSchema(_objectSpread2(_objectSpread2({}, this.options), {}, {
2989
+ min: _min
2990
+ }), this.opt);
2991
+ }
2992
+ }, {
2993
+ key: "executeSerialize",
2994
+ value: function executeSerialize() {
2995
+ var _this$customValidateF;
2796
2996
  return {
2797
2997
  type: "number",
2798
2998
  options: this.options,
2799
- opt: this.opt
2999
+ opt: this.opt,
3000
+ customValidate: this.customValidateFunctions && ((_this$customValidateF = this.customValidateFunctions) === null || _this$customValidateF === void 0 ? void 0 : _this$customValidateF.length) > 0
2800
3001
  };
2801
3002
  }
2802
3003
  }, {
@@ -2815,11 +3016,13 @@ var StringSchema = /*#__PURE__*/function (_Schema) {
2815
3016
  var _this;
2816
3017
  var opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
2817
3018
  var isRaw = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
3019
+ var customValidateFunctions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
2818
3020
  _classCallCheck(this, StringSchema);
2819
3021
  _this = _callSuper(this, StringSchema);
2820
3022
  _this.options = options;
2821
3023
  _this.opt = opt;
2822
3024
  _this.isRaw = isRaw;
3025
+ _this.customValidateFunctions = customValidateFunctions;
2823
3026
  return _this;
2824
3027
  }
2825
3028
 
@@ -2857,17 +3060,24 @@ var StringSchema = /*#__PURE__*/function (_Schema) {
2857
3060
  }
2858
3061
  }, {
2859
3062
  key: "regexp",
2860
- value: function regexp(_regexp) {
3063
+ value: function regexp(_regexp, message) {
2861
3064
  return new StringSchema(_objectSpread2(_objectSpread2({}, this.options), {}, {
2862
- regexp: _regexp
3065
+ regexp: _regexp,
3066
+ regExpMessage: message
2863
3067
  }), this.opt, this.isRaw);
2864
3068
  }
2865
3069
  }, {
2866
3070
  key: "validate",
2867
- value: function validate(path, src) {
3071
+ value: function validate(validationFunction) {
3072
+ return new StringSchema(this.options, this.opt, this.isRaw, this.customValidateFunctions.concat(validationFunction));
3073
+ }
3074
+ }, {
3075
+ key: "executeValidate",
3076
+ value: function executeValidate(path, src) {
2868
3077
  var _this$options, _this$options2, _this$options3;
3078
+ var errors = this.executeCustomValidateFunctions(src, this.customValidateFunctions);
2869
3079
  if (this.opt && (src === null || src === undefined)) {
2870
- return false;
3080
+ return errors.length > 0 ? _defineProperty({}, path, errors) : false;
2871
3081
  }
2872
3082
  if (typeof src !== "string") {
2873
3083
  return _defineProperty({}, path, [{
@@ -2875,7 +3085,6 @@ var StringSchema = /*#__PURE__*/function (_Schema) {
2875
3085
  value: src
2876
3086
  }]);
2877
3087
  }
2878
- var errors = [];
2879
3088
  if ((_this$options = this.options) !== null && _this$options !== void 0 && _this$options.maxLength && src.length > this.options.maxLength) {
2880
3089
  errors.push({
2881
3090
  message: "Expected string to be at most ".concat(this.options.maxLength, " characters long, got ").concat(src.length),
@@ -2890,7 +3099,7 @@ var StringSchema = /*#__PURE__*/function (_Schema) {
2890
3099
  }
2891
3100
  if ((_this$options3 = this.options) !== null && _this$options3 !== void 0 && _this$options3.regexp && !this.options.regexp.test(src)) {
2892
3101
  errors.push({
2893
- message: "Expected string to match reg exp: ".concat(this.options.regexp.toString(), ", got '").concat(src, "'"),
3102
+ message: this.options.regExpMessage || "Expected string to match reg exp: ".concat(this.options.regexp.toString(), ", got '").concat(src, "'"),
2894
3103
  value: src
2895
3104
  });
2896
3105
  }
@@ -2900,8 +3109,8 @@ var StringSchema = /*#__PURE__*/function (_Schema) {
2900
3109
  return false;
2901
3110
  }
2902
3111
  }, {
2903
- key: "assert",
2904
- value: function assert(path, src) {
3112
+ key: "executeAssert",
3113
+ value: function executeAssert(path, src) {
2905
3114
  if (this.opt && src === null) {
2906
3115
  return {
2907
3116
  success: true,
@@ -2933,21 +3142,24 @@ var StringSchema = /*#__PURE__*/function (_Schema) {
2933
3142
  return new StringSchema(this.options, this.opt, true);
2934
3143
  }
2935
3144
  }, {
2936
- key: "serialize",
2937
- value: function serialize() {
2938
- var _this$options4, _this$options5, _this$options6;
3145
+ key: "executeSerialize",
3146
+ value: function executeSerialize() {
3147
+ var _this$options4, _this$options5, _this$options6, _this$customValidateF, _this$customValidateF2;
2939
3148
  return {
2940
3149
  type: "string",
2941
3150
  options: {
2942
3151
  maxLength: (_this$options4 = this.options) === null || _this$options4 === void 0 ? void 0 : _this$options4.maxLength,
2943
3152
  minLength: (_this$options5 = this.options) === null || _this$options5 === void 0 ? void 0 : _this$options5.minLength,
2944
3153
  regexp: ((_this$options6 = this.options) === null || _this$options6 === void 0 ? void 0 : _this$options6.regexp) && {
3154
+ message: this.options.regExpMessage,
2945
3155
  source: this.options.regexp.source,
2946
3156
  flags: this.options.regexp.flags
2947
- }
3157
+ },
3158
+ customValidate: this.customValidateFunctions && ((_this$customValidateF = this.customValidateFunctions) === null || _this$customValidateF === void 0 ? void 0 : _this$customValidateF.length) > 0
2948
3159
  },
2949
3160
  opt: this.opt,
2950
- raw: this.isRaw
3161
+ raw: this.isRaw,
3162
+ customValidate: this.customValidateFunctions && ((_this$customValidateF2 = this.customValidateFunctions) === null || _this$customValidateF2 === void 0 ? void 0 : _this$customValidateF2.length) > 0
2951
3163
  };
2952
3164
  }
2953
3165
  }, {
@@ -2965,15 +3177,22 @@ var BooleanSchema = /*#__PURE__*/function (_Schema) {
2965
3177
  function BooleanSchema() {
2966
3178
  var _this;
2967
3179
  var opt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
3180
+ var customValidateFunctions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
2968
3181
  _classCallCheck(this, BooleanSchema);
2969
3182
  _this = _callSuper(this, BooleanSchema);
2970
3183
  _this.opt = opt;
3184
+ _this.customValidateFunctions = customValidateFunctions;
2971
3185
  return _this;
2972
3186
  }
2973
3187
  _inherits(BooleanSchema, _Schema);
2974
3188
  return _createClass(BooleanSchema, [{
2975
3189
  key: "validate",
2976
- value: function validate(path, src) {
3190
+ value: function validate(validationFunction) {
3191
+ return new BooleanSchema(this.opt, [].concat(_toConsumableArray(this.customValidateFunctions), [validationFunction]));
3192
+ }
3193
+ }, {
3194
+ key: "executeValidate",
3195
+ value: function executeValidate(path, src) {
2977
3196
  if (this.opt && (src === null || src === undefined)) {
2978
3197
  return false;
2979
3198
  }
@@ -2986,8 +3205,8 @@ var BooleanSchema = /*#__PURE__*/function (_Schema) {
2986
3205
  return false;
2987
3206
  }
2988
3207
  }, {
2989
- key: "assert",
2990
- value: function assert(path, src) {
3208
+ key: "executeAssert",
3209
+ value: function executeAssert(path, src) {
2991
3210
  if (this.opt && src === null) {
2992
3211
  return {
2993
3212
  success: true,
@@ -3023,11 +3242,13 @@ var BooleanSchema = /*#__PURE__*/function (_Schema) {
3023
3242
  return new BooleanSchema(true);
3024
3243
  }
3025
3244
  }, {
3026
- key: "serialize",
3027
- value: function serialize() {
3245
+ key: "executeSerialize",
3246
+ value: function executeSerialize() {
3247
+ var _this$customValidateF;
3028
3248
  return {
3029
3249
  type: "boolean",
3030
- opt: this.opt
3250
+ opt: this.opt,
3251
+ customValidate: this.customValidateFunctions && ((_this$customValidateF = this.customValidateFunctions) === null || _this$customValidateF === void 0 ? void 0 : _this$customValidateF.length) > 0
3031
3252
  };
3032
3253
  }
3033
3254
  }, {
@@ -3045,67 +3266,78 @@ var KeyOfSchema = /*#__PURE__*/function (_Schema) {
3045
3266
  function KeyOfSchema(schema, sourcePath) {
3046
3267
  var _this;
3047
3268
  var opt = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
3269
+ var customValidateFunctions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
3048
3270
  _classCallCheck(this, KeyOfSchema);
3049
3271
  _this = _callSuper(this, KeyOfSchema);
3050
3272
  _this.schema = schema;
3051
3273
  _this.sourcePath = sourcePath;
3052
3274
  _this.opt = opt;
3275
+ _this.customValidateFunctions = customValidateFunctions;
3053
3276
  return _this;
3054
3277
  }
3055
3278
  _inherits(KeyOfSchema, _Schema);
3056
3279
  return _createClass(KeyOfSchema, [{
3057
3280
  key: "validate",
3058
- value: function validate(path, src) {
3281
+ value: function validate(validationFunction) {
3282
+ return new KeyOfSchema(this.schema, this.sourcePath, this.opt, [].concat(_toConsumableArray(this.customValidateFunctions), [validationFunction]));
3283
+ }
3284
+ }, {
3285
+ key: "executeValidate",
3286
+ value: function executeValidate(path, src) {
3287
+ var customValidationErrors = this.executeCustomValidateFunctions(src, this.customValidateFunctions);
3059
3288
  if (this.opt && (src === null || src === undefined)) {
3060
- return false;
3289
+ return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : false;
3061
3290
  }
3062
3291
  if (!this.schema) {
3063
- return _defineProperty({}, path, [{
3292
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
3064
3293
  message: "Schema not found for module. keyOf must be used with a Val Module"
3065
- }]);
3294
+ }]));
3066
3295
  }
3067
3296
  var serializedSchema = this.schema;
3068
3297
  if (!(serializedSchema.type === "object" || serializedSchema.type === "record")) {
3069
- return _defineProperty({}, path, [{
3298
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
3070
3299
  message: "Schema in keyOf must be an 'object' or 'record'. Found '".concat(serializedSchema.type, "'")
3071
- }]);
3300
+ }]));
3072
3301
  }
3073
3302
  if (serializedSchema.opt && (src === null || src === undefined)) {
3074
3303
  return false;
3075
3304
  }
3076
3305
  if (serializedSchema.type === "record" && typeof src !== "string") {
3077
- return _defineProperty({}, path, [{
3306
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
3078
3307
  message: "Type of value in keyof (record) must be 'string'"
3079
- }]);
3308
+ }]));
3080
3309
  }
3081
3310
  if (serializedSchema.type === "object") {
3082
3311
  var keys = Object.keys(serializedSchema.items);
3083
3312
  if (!keys.includes(src)) {
3084
- return _defineProperty({}, path, [{
3313
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
3085
3314
  message: "Value of keyOf (object) must be: ".concat(keys.join(", "), ". Found: ").concat(src)
3086
- }]);
3315
+ }]));
3087
3316
  }
3088
3317
  }
3089
3318
  if (serializedSchema.type === "record") {
3090
3319
  if (typeof src !== "string") {
3091
- return _defineProperty({}, path, [{
3320
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
3092
3321
  message: "Value of keyOf (record) must be 'string'. Found: ".concat(_typeof(src))
3093
- }]);
3322
+ }]));
3094
3323
  }
3095
- return _defineProperty({}, path, [{
3324
+ return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
3096
3325
  fixes: ["keyof:check-keys"],
3097
3326
  message: "Did not validate keyOf (record). This error (keyof:check-keys) should typically be processed by Val internally. Seeing this error most likely means you have a Val version mismatch.",
3098
3327
  value: {
3099
3328
  key: src,
3100
3329
  sourcePath: this.sourcePath
3101
3330
  }
3102
- }]);
3331
+ }]));
3332
+ }
3333
+ if (customValidationErrors.length > 0) {
3334
+ return _defineProperty({}, path, customValidationErrors);
3103
3335
  }
3104
3336
  return false;
3105
3337
  }
3106
3338
  }, {
3107
- key: "assert",
3108
- value: function assert(path, src) {
3339
+ key: "executeAssert",
3340
+ value: function executeAssert(path, src) {
3109
3341
  if (this.opt && src === null) {
3110
3342
  return {
3111
3343
  success: true,
@@ -3176,8 +3408,9 @@ var KeyOfSchema = /*#__PURE__*/function (_Schema) {
3176
3408
  return new KeyOfSchema(this.schema, this.sourcePath, true);
3177
3409
  }
3178
3410
  }, {
3179
- key: "serialize",
3180
- value: function serialize() {
3411
+ key: "executeSerialize",
3412
+ value: function executeSerialize() {
3413
+ var _this$customValidateF;
3181
3414
  var path = this.sourcePath;
3182
3415
  if (!path) {
3183
3416
  throw new Error("Cannot serialize keyOf schema with empty selector. TIP: keyOf must be used with a Val Module of record schema.");
@@ -3202,7 +3435,8 @@ var KeyOfSchema = /*#__PURE__*/function (_Schema) {
3202
3435
  path: path,
3203
3436
  schema: serializedSchema,
3204
3437
  opt: this.opt,
3205
- values: values
3438
+ values: values,
3439
+ customValidate: this.customValidateFunctions && ((_this$customValidateF = this.customValidateFunctions) === null || _this$customValidateF === void 0 ? void 0 : _this$customValidateF.length) > 0
3206
3440
  };
3207
3441
  }
3208
3442
  }, {
@@ -3214,23 +3448,30 @@ var KeyOfSchema = /*#__PURE__*/function (_Schema) {
3214
3448
  }(Schema);
3215
3449
  var keyOf = function keyOf(valModule) {
3216
3450
  var _valModule$GetSchema;
3217
- return new KeyOfSchema(valModule === null || valModule === void 0 || (_valModule$GetSchema = valModule[GetSchema]) === null || _valModule$GetSchema === void 0 ? void 0 : _valModule$GetSchema.serialize(), getValPath(valModule));
3451
+ return new KeyOfSchema(valModule === null || valModule === void 0 || (_valModule$GetSchema = valModule[GetSchema]) === null || _valModule$GetSchema === void 0 ? void 0 : _valModule$GetSchema["executeSerialize"](), getValPath(valModule));
3218
3452
  };
3219
3453
 
3220
3454
  var DateSchema = /*#__PURE__*/function (_Schema) {
3221
3455
  function DateSchema(options) {
3222
3456
  var _this;
3223
3457
  var opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
3458
+ var customValidateFunctions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
3224
3459
  _classCallCheck(this, DateSchema);
3225
3460
  _this = _callSuper(this, DateSchema);
3226
3461
  _this.options = options;
3227
3462
  _this.opt = opt;
3463
+ _this.customValidateFunctions = customValidateFunctions;
3228
3464
  return _this;
3229
3465
  }
3230
3466
  _inherits(DateSchema, _Schema);
3231
3467
  return _createClass(DateSchema, [{
3232
3468
  key: "validate",
3233
- value: function validate(path, src) {
3469
+ value: function validate(validationFunction) {
3470
+ return new DateSchema(this.options, this.opt, [].concat(_toConsumableArray(this.customValidateFunctions), [validationFunction]));
3471
+ }
3472
+ }, {
3473
+ key: "executeValidate",
3474
+ value: function executeValidate(path, src) {
3234
3475
  var _this$options, _this$options2, _this$options3, _this$options4;
3235
3476
  if (this.opt && (src === null || src === undefined)) {
3236
3477
  return false;
@@ -3280,8 +3521,8 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
3280
3521
  return false;
3281
3522
  }
3282
3523
  }, {
3283
- key: "assert",
3284
- value: function assert(path, src) {
3524
+ key: "executeAssert",
3525
+ value: function executeAssert(path, src) {
3285
3526
  if (this.opt && src === null) {
3286
3527
  return {
3287
3528
  success: true,
@@ -3331,12 +3572,14 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
3331
3572
  return new DateSchema(this.options, true);
3332
3573
  }
3333
3574
  }, {
3334
- key: "serialize",
3335
- value: function serialize() {
3575
+ key: "executeSerialize",
3576
+ value: function executeSerialize() {
3577
+ var _this$customValidateF;
3336
3578
  return {
3337
3579
  type: "date",
3338
3580
  opt: this.opt,
3339
- options: this.options
3581
+ options: this.options,
3582
+ customValidate: this.customValidateFunctions && ((_this$customValidateF = this.customValidateFunctions) === null || _this$customValidateF === void 0 ? void 0 : _this$customValidateF.length) > 0
3340
3583
  };
3341
3584
  }
3342
3585
  }, {
@@ -4779,11 +5022,12 @@ function getFileHash(text) {
4779
5022
  }
4780
5023
 
4781
5024
  function deserializeSchema(serialized) {
4782
- var _serialized$options;
5025
+ var _serialized$options, _serialized$options2;
4783
5026
  switch (serialized.type) {
4784
5027
  case "string":
4785
5028
  return new StringSchema(_objectSpread2(_objectSpread2({}, serialized.options), {}, {
4786
- regexp: ((_serialized$options = serialized.options) === null || _serialized$options === void 0 ? void 0 : _serialized$options.regexp) && new RegExp(serialized.options.regexp.source, serialized.options.regexp.flags)
5029
+ regexp: ((_serialized$options = serialized.options) === null || _serialized$options === void 0 ? void 0 : _serialized$options.regexp) && new RegExp(serialized.options.regexp.source, serialized.options.regexp.flags),
5030
+ regExpMessage: (_serialized$options2 = serialized.options) === null || _serialized$options2 === void 0 || (_serialized$options2 = _serialized$options2.regexp) === null || _serialized$options2 === void 0 ? void 0 : _serialized$options2.message
4787
5031
  }), serialized.opt);
4788
5032
  case "literal":
4789
5033
  return new LiteralSchema(serialized.value, serialized.opt);
@@ -4811,12 +5055,12 @@ function deserializeSchema(serialized) {
4811
5055
  serialized.opt);
4812
5056
  case "richtext":
4813
5057
  {
4814
- var _serialized$options2, _serialized$options3;
5058
+ var _serialized$options3, _serialized$options4;
4815
5059
  var deserializedOptions = _objectSpread2(_objectSpread2({}, serialized.options || {}), {}, {
4816
- inline: _typeof((_serialized$options2 = serialized.options) === null || _serialized$options2 === void 0 || (_serialized$options2 = _serialized$options2.inline) === null || _serialized$options2 === void 0 ? void 0 : _serialized$options2.img) === "object" ? {
5060
+ inline: _typeof((_serialized$options3 = serialized.options) === null || _serialized$options3 === void 0 || (_serialized$options3 = _serialized$options3.inline) === null || _serialized$options3 === void 0 ? void 0 : _serialized$options3.img) === "object" ? {
4817
5061
  a: serialized.options.inline.a,
4818
5062
  img: deserializeSchema(serialized.options.inline.img)
4819
- } : (_serialized$options3 = serialized.options) === null || _serialized$options3 === void 0 ? void 0 : _serialized$options3.inline
5063
+ } : (_serialized$options4 = serialized.options) === null || _serialized$options4 === void 0 ? void 0 : _serialized$options4.inline
4820
5064
  });
4821
5065
  return new RichTextSchema(deserializedOptions, serialized.opt);
4822
5066
  }
@@ -4875,6 +5119,10 @@ var Internal = {
4875
5119
  hashToRemoteFileHash: hashToRemoteFileHash,
4876
5120
  splitRemoteRef: splitRemoteRef
4877
5121
  },
5122
+ validate: function validate(val, path, src) {
5123
+ var _getSchema;
5124
+ return val && ((_getSchema = getSchema(val)) === null || _getSchema === void 0 ? void 0 : _getSchema["executeValidate"](path, src));
5125
+ },
4878
5126
  isVal: isVal,
4879
5127
  isFile: isFile,
4880
5128
  createValPathOfItem: createValPathOfItem,