@tldraw/validate 5.2.0-canary.7ad657f9f0c0 → 5.2.0-canary.7b3dfe568083

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.
@@ -712,7 +712,8 @@ export declare class UnionValidator<Key extends string, Config extends UnionVali
712
712
  */
713
713
  constructor(key: Key, config: Config, unknownValueValidation: (value: object, variant: string) => UnknownValue, useNumberKeys: boolean);
714
714
  private expectObject;
715
- private getMatchingSchemaAndVariant;
715
+ private getVariant;
716
+ private getMatchingSchema;
716
717
  /**
717
718
  * Returns a new UnionValidator that can handle unknown variants using the provided function.
718
719
  *
package/dist-cjs/index.js CHANGED
@@ -41,7 +41,7 @@ var T = __toESM(require("./lib/validation"), 1);
41
41
  var import_validation = require("./lib/validation");
42
42
  (0, import_utils.registerTldrawLibraryVersion)(
43
43
  "@tldraw/validate",
44
- "5.2.0-canary.7ad657f9f0c0",
44
+ "5.2.0-canary.7b3dfe568083",
45
45
  "cjs"
46
46
  );
47
47
  //# sourceMappingURL=index.js.map
@@ -103,15 +103,11 @@ class ValidationError extends Error {
103
103
  path;
104
104
  name = "ValidationError";
105
105
  }
106
- function prefixError(path, fn) {
107
- try {
108
- return fn();
109
- } catch (err) {
110
- if (err instanceof ValidationError) {
111
- throw new ValidationError(err.rawMessage, [path, ...err.path]);
112
- }
113
- throw new ValidationError(err.toString(), [path]);
106
+ function rethrowPrefixed(path, err) {
107
+ if (err instanceof ValidationError) {
108
+ throw new ValidationError(err.rawMessage, [path, ...err.path]);
114
109
  }
110
+ throw new ValidationError(err.toString(), [path]);
115
111
  }
116
112
  function typeToString(value) {
117
113
  if (value === null) return "null";
@@ -340,7 +336,11 @@ class Validator {
340
336
  check(nameOrCheckFn, checkFn) {
341
337
  if (typeof nameOrCheckFn === "string") {
342
338
  return this.refine((value) => {
343
- prefixError(`(check ${nameOrCheckFn})`, () => checkFn(value));
339
+ try {
340
+ checkFn(value);
341
+ } catch (err) {
342
+ rethrowPrefixed(`(check ${nameOrCheckFn})`, err);
343
+ }
344
344
  return value;
345
345
  });
346
346
  } else {
@@ -362,17 +362,10 @@ class ArrayOfValidator extends Validator {
362
362
  (value) => {
363
363
  const arr = array.validate(value);
364
364
  for (let i = 0; i < arr.length; i++) {
365
- if (IS_DEV) {
366
- prefixError(i, () => itemValidator.validate(arr[i]));
367
- } else {
368
- try {
369
- itemValidator.validate(arr[i]);
370
- } catch (err) {
371
- if (err instanceof ValidationError) {
372
- throw new ValidationError(err.rawMessage, [i, ...err.path]);
373
- }
374
- throw new ValidationError(err.toString(), [i]);
375
- }
365
+ try {
366
+ itemValidator.validate(arr[i]);
367
+ } catch (err) {
368
+ rethrowPrefixed(i, err);
376
369
  }
377
370
  }
378
371
  return arr;
@@ -388,46 +381,26 @@ class ArrayOfValidator extends Validator {
388
381
  const item = arr[i];
389
382
  if (i >= knownGoodValue.length) {
390
383
  isDifferent = true;
391
- if (IS_DEV) {
392
- prefixError(i, () => itemValidator.validate(item));
393
- } else {
394
- try {
395
- itemValidator.validate(item);
396
- } catch (err) {
397
- if (err instanceof ValidationError) {
398
- throw new ValidationError(err.rawMessage, [i, ...err.path]);
399
- }
400
- throw new ValidationError(err.toString(), [i]);
401
- }
384
+ try {
385
+ itemValidator.validate(item);
386
+ } catch (err) {
387
+ rethrowPrefixed(i, err);
402
388
  }
403
389
  continue;
404
390
  }
405
391
  if (Object.is(knownGoodValue[i], item)) {
406
392
  continue;
407
393
  }
408
- if (IS_DEV) {
409
- const checkedItem = prefixError(
410
- i,
411
- () => itemValidator.validateUsingKnownGoodVersion(knownGoodValue[i], item)
394
+ try {
395
+ const checkedItem = itemValidator.validateUsingKnownGoodVersion(
396
+ knownGoodValue[i],
397
+ item
412
398
  );
413
399
  if (!Object.is(checkedItem, knownGoodValue[i])) {
414
400
  isDifferent = true;
415
401
  }
416
- } else {
417
- try {
418
- const checkedItem = itemValidator.validateUsingKnownGoodVersion(
419
- knownGoodValue[i],
420
- item
421
- );
422
- if (!Object.is(checkedItem, knownGoodValue[i])) {
423
- isDifferent = true;
424
- }
425
- } catch (err) {
426
- if (err instanceof ValidationError) {
427
- throw new ValidationError(err.rawMessage, [i, ...err.path]);
428
- }
429
- throw new ValidationError(err.toString(), [i]);
430
- }
402
+ } catch (err) {
403
+ rethrowPrefixed(i, err);
431
404
  }
432
405
  }
433
406
  return isDifferent ? newValue : knownGoodValue;
@@ -483,33 +456,28 @@ class ObjectValidator extends Validator {
483
456
  * shouldAllowUnknownProperties - Whether to allow properties not defined in config
484
457
  */
485
458
  constructor(config, shouldAllowUnknownProperties = false) {
459
+ const configKeys = [];
460
+ const configValidators = [];
461
+ for (const [key, validator] of Object.entries(config)) {
462
+ configKeys.push(key);
463
+ configValidators.push(validator);
464
+ }
486
465
  super(
487
466
  (object2) => {
488
467
  if (typeof object2 !== "object" || object2 === null) {
489
468
  throw new ValidationError(`Expected object, got ${typeToString(object2)}`);
490
469
  }
491
- for (const key in config) {
492
- if (!(0, import_utils.hasOwnProperty)(config, key)) continue;
493
- const validator = config[key];
494
- if (IS_DEV) {
495
- prefixError(key, () => {
496
- ;
497
- validator.validate((0, import_utils.getOwnProperty)(object2, key));
498
- });
499
- } else {
500
- try {
501
- ;
502
- validator.validate((0, import_utils.getOwnProperty)(object2, key));
503
- } catch (err) {
504
- if (err instanceof ValidationError) {
505
- throw new ValidationError(err.rawMessage, [key, ...err.path]);
506
- }
507
- throw new ValidationError(err.toString(), [key]);
508
- }
470
+ for (let i = 0; i < configKeys.length; i++) {
471
+ const key = configKeys[i];
472
+ try {
473
+ configValidators[i].validate((0, import_utils.getOwnProperty)(object2, key));
474
+ } catch (err) {
475
+ rethrowPrefixed(key, err);
509
476
  }
510
477
  }
511
478
  if (!shouldAllowUnknownProperties) {
512
- for (const key of Object.keys(object2)) {
479
+ for (const key in object2) {
480
+ if (!(0, import_utils.hasOwnProperty)(object2, key)) continue;
513
481
  if (!(0, import_utils.hasOwnProperty)(config, key)) {
514
482
  throw new ValidationError(`Unexpected property`, [key]);
515
483
  }
@@ -525,43 +493,26 @@ class ObjectValidator extends Validator {
525
493
  throw new ValidationError(`Expected object, got ${typeToString(newValue)}`);
526
494
  }
527
495
  let isDifferent = false;
528
- for (const key in config) {
529
- if (!(0, import_utils.hasOwnProperty)(config, key)) continue;
530
- const validator = config[key];
496
+ for (let i = 0; i < configKeys.length; i++) {
497
+ const key = configKeys[i];
531
498
  const prev = (0, import_utils.getOwnProperty)(knownGoodValue, key);
532
499
  const next = (0, import_utils.getOwnProperty)(newValue, key);
533
500
  if (Object.is(prev, next)) {
534
501
  continue;
535
502
  }
536
- if (IS_DEV) {
537
- const checked = prefixError(key, () => {
538
- const validatable = validator;
539
- if (validatable.validateUsingKnownGoodVersion) {
540
- return validatable.validateUsingKnownGoodVersion(prev, next);
541
- } else {
542
- return validatable.validate(next);
543
- }
544
- });
503
+ try {
504
+ const validator = configValidators[i];
505
+ const checked = validator.validateUsingKnownGoodVersion ? validator.validateUsingKnownGoodVersion(prev, next) : validator.validate(next);
545
506
  if (!Object.is(checked, prev)) {
546
507
  isDifferent = true;
547
508
  }
548
- } else {
549
- try {
550
- const validatable = validator;
551
- const checked = validatable.validateUsingKnownGoodVersion ? validatable.validateUsingKnownGoodVersion(prev, next) : validatable.validate(next);
552
- if (!Object.is(checked, prev)) {
553
- isDifferent = true;
554
- }
555
- } catch (err) {
556
- if (err instanceof ValidationError) {
557
- throw new ValidationError(err.rawMessage, [key, ...err.path]);
558
- }
559
- throw new ValidationError(err.toString(), [key]);
560
- }
509
+ } catch (err) {
510
+ rethrowPrefixed(key, err);
561
511
  }
562
512
  }
563
513
  if (!shouldAllowUnknownProperties) {
564
- for (const key of Object.keys(newValue)) {
514
+ for (const key in newValue) {
515
+ if (!(0, import_utils.hasOwnProperty)(newValue, key)) continue;
565
516
  if (!(0, import_utils.hasOwnProperty)(config, key)) {
566
517
  throw new ValidationError(`Unexpected property`, [key]);
567
518
  }
@@ -574,10 +525,13 @@ class ObjectValidator extends Validator {
574
525
  }
575
526
  }
576
527
  }
577
- for (const key of Object.keys(knownGoodValue)) {
578
- if (!(0, import_utils.hasOwnProperty)(newValue, key)) {
579
- isDifferent = true;
580
- break;
528
+ if (!isDifferent) {
529
+ for (const key in knownGoodValue) {
530
+ if (!(0, import_utils.hasOwnProperty)(knownGoodValue, key)) continue;
531
+ if (!(0, import_utils.hasOwnProperty)(newValue, key)) {
532
+ isDifferent = true;
533
+ break;
534
+ }
581
535
  }
582
536
  }
583
537
  return isDifferent ? newValue : knownGoodValue;
@@ -633,29 +587,35 @@ class UnionValidator extends Validator {
633
587
  super(
634
588
  (input) => {
635
589
  this.expectObject(input);
636
- const { matchingSchema, variant } = this.getMatchingSchemaAndVariant(input);
590
+ const matchingSchema = this.getMatchingSchema(input);
637
591
  if (matchingSchema === void 0) {
638
- return this.unknownValueValidation(input, variant);
592
+ return this.unknownValueValidation(input, this.getVariant(input));
593
+ }
594
+ try {
595
+ return matchingSchema.validate(input);
596
+ } catch (err) {
597
+ rethrowPrefixed(`(${key} = ${this.getVariant(input)})`, err);
639
598
  }
640
- return prefixError(`(${key} = ${variant})`, () => matchingSchema.validate(input));
641
599
  },
642
600
  (prevValue, newValue) => {
643
601
  this.expectObject(newValue);
644
602
  this.expectObject(prevValue);
645
- const { matchingSchema, variant } = this.getMatchingSchemaAndVariant(newValue);
603
+ const matchingSchema = this.getMatchingSchema(newValue);
646
604
  if (matchingSchema === void 0) {
647
- return this.unknownValueValidation(newValue, variant);
605
+ return this.unknownValueValidation(newValue, this.getVariant(newValue));
648
606
  }
649
- if ((0, import_utils.getOwnProperty)(prevValue, key) !== (0, import_utils.getOwnProperty)(newValue, key)) {
650
- return prefixError(`(${key} = ${variant})`, () => matchingSchema.validate(newValue));
651
- }
652
- return prefixError(`(${key} = ${variant})`, () => {
607
+ try {
608
+ if ((0, import_utils.getOwnProperty)(prevValue, key) !== (0, import_utils.getOwnProperty)(newValue, key)) {
609
+ return matchingSchema.validate(newValue);
610
+ }
653
611
  if (matchingSchema.validateUsingKnownGoodVersion) {
654
612
  return matchingSchema.validateUsingKnownGoodVersion(prevValue, newValue);
655
613
  } else {
656
614
  return matchingSchema.validate(newValue);
657
615
  }
658
- });
616
+ } catch (err) {
617
+ rethrowPrefixed(`(${key} = ${this.getVariant(newValue)})`, err);
618
+ }
659
619
  }
660
620
  );
661
621
  this.key = key;
@@ -672,7 +632,13 @@ class UnionValidator extends Validator {
672
632
  throw new ValidationError(`Expected an object, got ${typeToString(value)}`, []);
673
633
  }
674
634
  }
675
- getMatchingSchemaAndVariant(object2) {
635
+ getVariant(object2) {
636
+ return (0, import_utils.getOwnProperty)(object2, this.key);
637
+ }
638
+ // Returns the matching schema for the object's variant, or undefined if the variant is
639
+ // unknown. The variant itself is only needed on cold paths (unknown variants and errors),
640
+ // so this avoids allocating a `{ matchingSchema, variant }` result per validation.
641
+ getMatchingSchema(object2) {
676
642
  const variant = (0, import_utils.getOwnProperty)(object2, this.key);
677
643
  if (!this.useNumberKeys && typeof variant !== "string") {
678
644
  throw new ValidationError(
@@ -686,8 +652,7 @@ class UnionValidator extends Validator {
686
652
  );
687
653
  }
688
654
  }
689
- const matchingSchema = (0, import_utils.hasOwnProperty)(this.config, variant) ? this.config[variant] : void 0;
690
- return { matchingSchema, variant };
655
+ return (0, import_utils.hasOwnProperty)(this.config, variant) ? this.config[variant] : void 0;
691
656
  }
692
657
  /**
693
658
  * Returns a new UnionValidator that can handle unknown variants using the provided function.
@@ -722,21 +687,11 @@ class DictValidator extends Validator {
722
687
  }
723
688
  for (const key in object2) {
724
689
  if (!(0, import_utils.hasOwnProperty)(object2, key)) continue;
725
- if (IS_DEV) {
726
- prefixError(key, () => {
727
- keyValidator.validate(key);
728
- valueValidator.validate(object2[key]);
729
- });
730
- } else {
731
- try {
732
- keyValidator.validate(key);
733
- valueValidator.validate(object2[key]);
734
- } catch (err) {
735
- if (err instanceof ValidationError) {
736
- throw new ValidationError(err.rawMessage, [key, ...err.path]);
737
- }
738
- throw new ValidationError(err.toString(), [key]);
739
- }
690
+ try {
691
+ keyValidator.validate(key);
692
+ valueValidator.validate(object2[key]);
693
+ } catch (err) {
694
+ rethrowPrefixed(key, err);
740
695
  }
741
696
  }
742
697
  return object2;
@@ -754,21 +709,11 @@ class DictValidator extends Validator {
754
709
  const next = newObj[key];
755
710
  if (!(0, import_utils.hasOwnProperty)(knownGoodValue, key)) {
756
711
  isDifferent = true;
757
- if (IS_DEV) {
758
- prefixError(key, () => {
759
- keyValidator.validate(key);
760
- valueValidator.validate(next);
761
- });
762
- } else {
763
- try {
764
- keyValidator.validate(key);
765
- valueValidator.validate(next);
766
- } catch (err) {
767
- if (err instanceof ValidationError) {
768
- throw new ValidationError(err.rawMessage, [key, ...err.path]);
769
- }
770
- throw new ValidationError(err.toString(), [key]);
771
- }
712
+ try {
713
+ keyValidator.validate(key);
714
+ valueValidator.validate(next);
715
+ } catch (err) {
716
+ rethrowPrefixed(key, err);
772
717
  }
773
718
  continue;
774
719
  }
@@ -776,29 +721,13 @@ class DictValidator extends Validator {
776
721
  if (Object.is(prev, next)) {
777
722
  continue;
778
723
  }
779
- if (IS_DEV) {
780
- const checked = prefixError(key, () => {
781
- if (valueValidator.validateUsingKnownGoodVersion) {
782
- return valueValidator.validateUsingKnownGoodVersion(prev, next);
783
- } else {
784
- return valueValidator.validate(next);
785
- }
786
- });
724
+ try {
725
+ const checked = valueValidator.validateUsingKnownGoodVersion ? valueValidator.validateUsingKnownGoodVersion(prev, next) : valueValidator.validate(next);
787
726
  if (!Object.is(checked, prev)) {
788
727
  isDifferent = true;
789
728
  }
790
- } else {
791
- try {
792
- const checked = valueValidator.validateUsingKnownGoodVersion ? valueValidator.validateUsingKnownGoodVersion(prev, next) : valueValidator.validate(next);
793
- if (!Object.is(checked, prev)) {
794
- isDifferent = true;
795
- }
796
- } catch (err) {
797
- if (err instanceof ValidationError) {
798
- throw new ValidationError(err.rawMessage, [key, ...err.path]);
799
- }
800
- throw new ValidationError(err.toString(), [key]);
801
- }
729
+ } catch (err) {
730
+ rethrowPrefixed(key, err);
802
731
  }
803
732
  }
804
733
  if (!isDifferent) {
@@ -988,10 +917,17 @@ function isValidJson(value) {
988
917
  return true;
989
918
  }
990
919
  if (Array.isArray(value)) {
991
- return value.every(isValidJson);
920
+ for (let i = 0; i < value.length; i++) {
921
+ if (!isValidJson(value[i])) return false;
922
+ }
923
+ return true;
992
924
  }
993
925
  if (isPlainObject(value)) {
994
- return Object.values(value).every(isValidJson);
926
+ for (const key in value) {
927
+ if (!(0, import_utils.hasOwnProperty)(value, key)) continue;
928
+ if (!isValidJson(value[key])) return false;
929
+ }
930
+ return true;
995
931
  }
996
932
  return false;
997
933
  }
@@ -1024,7 +960,8 @@ const jsonValue = new Validator(
1024
960
  return isDifferent ? newValue : knownGoodValue;
1025
961
  } else if (isPlainObject(knownGoodValue) && isPlainObject(newValue)) {
1026
962
  let isDifferent = false;
1027
- for (const key of Object.keys(newValue)) {
963
+ for (const key in newValue) {
964
+ if (!(0, import_utils.hasOwnProperty)(newValue, key)) continue;
1028
965
  if (!(0, import_utils.hasOwnProperty)(knownGoodValue, key)) {
1029
966
  isDifferent = true;
1030
967
  jsonValue.validate(newValue[key]);
@@ -1040,10 +977,13 @@ const jsonValue = new Validator(
1040
977
  isDifferent = true;
1041
978
  }
1042
979
  }
1043
- for (const key of Object.keys(knownGoodValue)) {
1044
- if (!(0, import_utils.hasOwnProperty)(newValue, key)) {
1045
- isDifferent = true;
1046
- break;
980
+ if (!isDifferent) {
981
+ for (const key in knownGoodValue) {
982
+ if (!(0, import_utils.hasOwnProperty)(knownGoodValue, key)) continue;
983
+ if (!(0, import_utils.hasOwnProperty)(newValue, key)) {
984
+ isDifferent = true;
985
+ break;
986
+ }
1047
987
  }
1048
988
  }
1049
989
  return isDifferent ? newValue : knownGoodValue;
@@ -1087,16 +1027,22 @@ function numberUnion(key, config) {
1087
1027
  function model(name, validator) {
1088
1028
  return new Validator(
1089
1029
  (value) => {
1090
- return prefixError(name, () => validator.validate(value));
1030
+ try {
1031
+ return validator.validate(value);
1032
+ } catch (err) {
1033
+ rethrowPrefixed(name, err);
1034
+ }
1091
1035
  },
1092
1036
  (prevValue, newValue) => {
1093
- return prefixError(name, () => {
1037
+ try {
1094
1038
  if (validator.validateUsingKnownGoodVersion) {
1095
1039
  return validator.validateUsingKnownGoodVersion(prevValue, newValue);
1096
1040
  } else {
1097
1041
  return validator.validate(newValue);
1098
1042
  }
1099
- });
1043
+ } catch (err) {
1044
+ rethrowPrefixed(name, err);
1045
+ }
1100
1046
  }
1101
1047
  );
1102
1048
  }