@tldraw/validate 4.2.0 → 4.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +37 -1
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/lib/validation.js +304 -68
- package/dist-cjs/lib/validation.js.map +3 -3
- package/dist-esm/index.d.mts +37 -1
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/validation.mjs +304 -68
- package/dist-esm/lib/validation.mjs.map +3 -3
- package/package.json +2 -2
- package/src/lib/validation.ts +355 -68
- package/src/test/validation.test.ts +38 -5
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
hasOwnProperty,
|
|
6
6
|
validateIndexKey
|
|
7
7
|
} from "@tldraw/utils";
|
|
8
|
+
const IS_DEV = process.env.NODE_ENV !== "production";
|
|
8
9
|
function formatPath(path) {
|
|
9
10
|
if (!path.length) {
|
|
10
11
|
return null;
|
|
@@ -81,10 +82,12 @@ class Validator {
|
|
|
81
82
|
*
|
|
82
83
|
* validationFn - Function that validates and returns a value of type T
|
|
83
84
|
* validateUsingKnownGoodVersionFn - Optional performance-optimized validation function
|
|
85
|
+
* skipSameValueCheck - Internal flag to skip dev check for validators that transform values
|
|
84
86
|
*/
|
|
85
|
-
constructor(validationFn, validateUsingKnownGoodVersionFn) {
|
|
87
|
+
constructor(validationFn, validateUsingKnownGoodVersionFn, skipSameValueCheck = false) {
|
|
86
88
|
this.validationFn = validationFn;
|
|
87
89
|
this.validateUsingKnownGoodVersionFn = validateUsingKnownGoodVersionFn;
|
|
90
|
+
this.skipSameValueCheck = skipSameValueCheck;
|
|
88
91
|
}
|
|
89
92
|
/**
|
|
90
93
|
* Validates an unknown value and returns it with the correct type. The returned value is
|
|
@@ -108,7 +111,7 @@ class Validator {
|
|
|
108
111
|
*/
|
|
109
112
|
validate(value) {
|
|
110
113
|
const validated = this.validationFn(value);
|
|
111
|
-
if (
|
|
114
|
+
if (IS_DEV && !this.skipSameValueCheck && !Object.is(value, validated)) {
|
|
112
115
|
throw new ValidationError("Validator functions must return the same value they were passed");
|
|
113
116
|
}
|
|
114
117
|
return validated;
|
|
@@ -269,7 +272,9 @@ class Validator {
|
|
|
269
272
|
return knownGoodValue;
|
|
270
273
|
}
|
|
271
274
|
return otherValidationFn(validated);
|
|
272
|
-
}
|
|
275
|
+
},
|
|
276
|
+
true
|
|
277
|
+
// skipSameValueCheck: refine is designed to transform values
|
|
273
278
|
);
|
|
274
279
|
}
|
|
275
280
|
check(nameOrCheckFn, checkFn) {
|
|
@@ -297,11 +302,25 @@ class ArrayOfValidator extends Validator {
|
|
|
297
302
|
(value) => {
|
|
298
303
|
const arr = array.validate(value);
|
|
299
304
|
for (let i = 0; i < arr.length; i++) {
|
|
300
|
-
|
|
305
|
+
if (IS_DEV) {
|
|
306
|
+
prefixError(i, () => itemValidator.validate(arr[i]));
|
|
307
|
+
} else {
|
|
308
|
+
try {
|
|
309
|
+
itemValidator.validate(arr[i]);
|
|
310
|
+
} catch (err) {
|
|
311
|
+
if (err instanceof ValidationError) {
|
|
312
|
+
throw new ValidationError(err.rawMessage, [i, ...err.path]);
|
|
313
|
+
}
|
|
314
|
+
throw new ValidationError(err.toString(), [i]);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
301
317
|
}
|
|
302
318
|
return arr;
|
|
303
319
|
},
|
|
304
320
|
(knownGoodValue, newValue) => {
|
|
321
|
+
if (Object.is(knownGoodValue, newValue)) {
|
|
322
|
+
return knownGoodValue;
|
|
323
|
+
}
|
|
305
324
|
if (!itemValidator.validateUsingKnownGoodVersion) return this.validate(newValue);
|
|
306
325
|
const arr = array.validate(newValue);
|
|
307
326
|
let isDifferent = knownGoodValue.length !== arr.length;
|
|
@@ -309,18 +328,46 @@ class ArrayOfValidator extends Validator {
|
|
|
309
328
|
const item = arr[i];
|
|
310
329
|
if (i >= knownGoodValue.length) {
|
|
311
330
|
isDifferent = true;
|
|
312
|
-
|
|
331
|
+
if (IS_DEV) {
|
|
332
|
+
prefixError(i, () => itemValidator.validate(item));
|
|
333
|
+
} else {
|
|
334
|
+
try {
|
|
335
|
+
itemValidator.validate(item);
|
|
336
|
+
} catch (err) {
|
|
337
|
+
if (err instanceof ValidationError) {
|
|
338
|
+
throw new ValidationError(err.rawMessage, [i, ...err.path]);
|
|
339
|
+
}
|
|
340
|
+
throw new ValidationError(err.toString(), [i]);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
313
343
|
continue;
|
|
314
344
|
}
|
|
315
345
|
if (Object.is(knownGoodValue[i], item)) {
|
|
316
346
|
continue;
|
|
317
347
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
348
|
+
if (IS_DEV) {
|
|
349
|
+
const checkedItem = prefixError(
|
|
350
|
+
i,
|
|
351
|
+
() => itemValidator.validateUsingKnownGoodVersion(knownGoodValue[i], item)
|
|
352
|
+
);
|
|
353
|
+
if (!Object.is(checkedItem, knownGoodValue[i])) {
|
|
354
|
+
isDifferent = true;
|
|
355
|
+
}
|
|
356
|
+
} else {
|
|
357
|
+
try {
|
|
358
|
+
const checkedItem = itemValidator.validateUsingKnownGoodVersion(
|
|
359
|
+
knownGoodValue[i],
|
|
360
|
+
item
|
|
361
|
+
);
|
|
362
|
+
if (!Object.is(checkedItem, knownGoodValue[i])) {
|
|
363
|
+
isDifferent = true;
|
|
364
|
+
}
|
|
365
|
+
} catch (err) {
|
|
366
|
+
if (err instanceof ValidationError) {
|
|
367
|
+
throw new ValidationError(err.rawMessage, [i, ...err.path]);
|
|
368
|
+
}
|
|
369
|
+
throw new ValidationError(err.toString(), [i]);
|
|
370
|
+
}
|
|
324
371
|
}
|
|
325
372
|
}
|
|
326
373
|
return isDifferent ? newValue : knownGoodValue;
|
|
@@ -380,11 +427,25 @@ class ObjectValidator extends Validator {
|
|
|
380
427
|
if (typeof object2 !== "object" || object2 === null) {
|
|
381
428
|
throw new ValidationError(`Expected object, got ${typeToString(object2)}`);
|
|
382
429
|
}
|
|
383
|
-
for (const
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
430
|
+
for (const key in config) {
|
|
431
|
+
if (!hasOwnProperty(config, key)) continue;
|
|
432
|
+
const validator = config[key];
|
|
433
|
+
if (IS_DEV) {
|
|
434
|
+
prefixError(key, () => {
|
|
435
|
+
;
|
|
436
|
+
validator.validate(getOwnProperty(object2, key));
|
|
437
|
+
});
|
|
438
|
+
} else {
|
|
439
|
+
try {
|
|
440
|
+
;
|
|
441
|
+
validator.validate(getOwnProperty(object2, key));
|
|
442
|
+
} catch (err) {
|
|
443
|
+
if (err instanceof ValidationError) {
|
|
444
|
+
throw new ValidationError(err.rawMessage, [key, ...err.path]);
|
|
445
|
+
}
|
|
446
|
+
throw new ValidationError(err.toString(), [key]);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
388
449
|
}
|
|
389
450
|
if (!shouldAllowUnknownProperties) {
|
|
390
451
|
for (const key of Object.keys(object2)) {
|
|
@@ -396,26 +457,46 @@ class ObjectValidator extends Validator {
|
|
|
396
457
|
return object2;
|
|
397
458
|
},
|
|
398
459
|
(knownGoodValue, newValue) => {
|
|
460
|
+
if (Object.is(knownGoodValue, newValue)) {
|
|
461
|
+
return knownGoodValue;
|
|
462
|
+
}
|
|
399
463
|
if (typeof newValue !== "object" || newValue === null) {
|
|
400
464
|
throw new ValidationError(`Expected object, got ${typeToString(newValue)}`);
|
|
401
465
|
}
|
|
402
466
|
let isDifferent = false;
|
|
403
|
-
for (const
|
|
467
|
+
for (const key in config) {
|
|
468
|
+
if (!hasOwnProperty(config, key)) continue;
|
|
469
|
+
const validator = config[key];
|
|
404
470
|
const prev = getOwnProperty(knownGoodValue, key);
|
|
405
471
|
const next = getOwnProperty(newValue, key);
|
|
406
472
|
if (Object.is(prev, next)) {
|
|
407
473
|
continue;
|
|
408
474
|
}
|
|
409
|
-
|
|
410
|
-
const
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
475
|
+
if (IS_DEV) {
|
|
476
|
+
const checked = prefixError(key, () => {
|
|
477
|
+
const validatable = validator;
|
|
478
|
+
if (validatable.validateUsingKnownGoodVersion) {
|
|
479
|
+
return validatable.validateUsingKnownGoodVersion(prev, next);
|
|
480
|
+
} else {
|
|
481
|
+
return validatable.validate(next);
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
if (!Object.is(checked, prev)) {
|
|
485
|
+
isDifferent = true;
|
|
486
|
+
}
|
|
487
|
+
} else {
|
|
488
|
+
try {
|
|
489
|
+
const validatable = validator;
|
|
490
|
+
const checked = validatable.validateUsingKnownGoodVersion ? validatable.validateUsingKnownGoodVersion(prev, next) : validatable.validate(next);
|
|
491
|
+
if (!Object.is(checked, prev)) {
|
|
492
|
+
isDifferent = true;
|
|
493
|
+
}
|
|
494
|
+
} catch (err) {
|
|
495
|
+
if (err instanceof ValidationError) {
|
|
496
|
+
throw new ValidationError(err.rawMessage, [key, ...err.path]);
|
|
497
|
+
}
|
|
498
|
+
throw new ValidationError(err.toString(), [key]);
|
|
415
499
|
}
|
|
416
|
-
});
|
|
417
|
-
if (!Object.is(checked, prev)) {
|
|
418
|
-
isDifferent = true;
|
|
419
500
|
}
|
|
420
501
|
}
|
|
421
502
|
if (!shouldAllowUnknownProperties) {
|
|
@@ -523,8 +604,13 @@ class UnionValidator extends Validator {
|
|
|
523
604
|
throw new ValidationError(
|
|
524
605
|
`Expected a string for key "${this.key}", got ${typeToString(variant)}`
|
|
525
606
|
);
|
|
526
|
-
} else if (this.useNumberKeys
|
|
527
|
-
|
|
607
|
+
} else if (this.useNumberKeys) {
|
|
608
|
+
const numVariant = Number(variant);
|
|
609
|
+
if (numVariant - numVariant !== 0) {
|
|
610
|
+
throw new ValidationError(
|
|
611
|
+
`Expected a number for key "${this.key}", got "${variant}"`
|
|
612
|
+
);
|
|
613
|
+
}
|
|
528
614
|
}
|
|
529
615
|
const matchingSchema = hasOwnProperty(this.config, variant) ? this.config[variant] : void 0;
|
|
530
616
|
return { matchingSchema, variant };
|
|
@@ -560,11 +646,24 @@ class DictValidator extends Validator {
|
|
|
560
646
|
if (typeof object2 !== "object" || object2 === null) {
|
|
561
647
|
throw new ValidationError(`Expected object, got ${typeToString(object2)}`);
|
|
562
648
|
}
|
|
563
|
-
for (const
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
649
|
+
for (const key in object2) {
|
|
650
|
+
if (!hasOwnProperty(object2, key)) continue;
|
|
651
|
+
if (IS_DEV) {
|
|
652
|
+
prefixError(key, () => {
|
|
653
|
+
keyValidator.validate(key);
|
|
654
|
+
valueValidator.validate(object2[key]);
|
|
655
|
+
});
|
|
656
|
+
} else {
|
|
657
|
+
try {
|
|
658
|
+
keyValidator.validate(key);
|
|
659
|
+
valueValidator.validate(object2[key]);
|
|
660
|
+
} catch (err) {
|
|
661
|
+
if (err instanceof ValidationError) {
|
|
662
|
+
throw new ValidationError(err.rawMessage, [key, ...err.path]);
|
|
663
|
+
}
|
|
664
|
+
throw new ValidationError(err.toString(), [key]);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
568
667
|
}
|
|
569
668
|
return object2;
|
|
570
669
|
},
|
|
@@ -572,36 +671,71 @@ class DictValidator extends Validator {
|
|
|
572
671
|
if (typeof newValue !== "object" || newValue === null) {
|
|
573
672
|
throw new ValidationError(`Expected object, got ${typeToString(newValue)}`);
|
|
574
673
|
}
|
|
674
|
+
const newObj = newValue;
|
|
575
675
|
let isDifferent = false;
|
|
576
|
-
|
|
676
|
+
let newKeyCount = 0;
|
|
677
|
+
for (const key in newObj) {
|
|
678
|
+
if (!hasOwnProperty(newObj, key)) continue;
|
|
679
|
+
newKeyCount++;
|
|
680
|
+
const next = newObj[key];
|
|
577
681
|
if (!hasOwnProperty(knownGoodValue, key)) {
|
|
578
682
|
isDifferent = true;
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
683
|
+
if (IS_DEV) {
|
|
684
|
+
prefixError(key, () => {
|
|
685
|
+
keyValidator.validate(key);
|
|
686
|
+
valueValidator.validate(next);
|
|
687
|
+
});
|
|
688
|
+
} else {
|
|
689
|
+
try {
|
|
690
|
+
keyValidator.validate(key);
|
|
691
|
+
valueValidator.validate(next);
|
|
692
|
+
} catch (err) {
|
|
693
|
+
if (err instanceof ValidationError) {
|
|
694
|
+
throw new ValidationError(err.rawMessage, [key, ...err.path]);
|
|
695
|
+
}
|
|
696
|
+
throw new ValidationError(err.toString(), [key]);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
583
699
|
continue;
|
|
584
700
|
}
|
|
585
|
-
const prev =
|
|
586
|
-
const next = value;
|
|
701
|
+
const prev = knownGoodValue[key];
|
|
587
702
|
if (Object.is(prev, next)) {
|
|
588
703
|
continue;
|
|
589
704
|
}
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
705
|
+
if (IS_DEV) {
|
|
706
|
+
const checked = prefixError(key, () => {
|
|
707
|
+
if (valueValidator.validateUsingKnownGoodVersion) {
|
|
708
|
+
return valueValidator.validateUsingKnownGoodVersion(prev, next);
|
|
709
|
+
} else {
|
|
710
|
+
return valueValidator.validate(next);
|
|
711
|
+
}
|
|
712
|
+
});
|
|
713
|
+
if (!Object.is(checked, prev)) {
|
|
714
|
+
isDifferent = true;
|
|
715
|
+
}
|
|
716
|
+
} else {
|
|
717
|
+
try {
|
|
718
|
+
const checked = valueValidator.validateUsingKnownGoodVersion ? valueValidator.validateUsingKnownGoodVersion(prev, next) : valueValidator.validate(next);
|
|
719
|
+
if (!Object.is(checked, prev)) {
|
|
720
|
+
isDifferent = true;
|
|
721
|
+
}
|
|
722
|
+
} catch (err) {
|
|
723
|
+
if (err instanceof ValidationError) {
|
|
724
|
+
throw new ValidationError(err.rawMessage, [key, ...err.path]);
|
|
725
|
+
}
|
|
726
|
+
throw new ValidationError(err.toString(), [key]);
|
|
595
727
|
}
|
|
596
|
-
});
|
|
597
|
-
if (!Object.is(checked, prev)) {
|
|
598
|
-
isDifferent = true;
|
|
599
728
|
}
|
|
600
729
|
}
|
|
601
|
-
|
|
602
|
-
|
|
730
|
+
if (!isDifferent) {
|
|
731
|
+
let oldKeyCount = 0;
|
|
732
|
+
for (const key in knownGoodValue) {
|
|
733
|
+
if (hasOwnProperty(knownGoodValue, key)) {
|
|
734
|
+
oldKeyCount++;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
if (oldKeyCount !== newKeyCount) {
|
|
603
738
|
isDifferent = true;
|
|
604
|
-
break;
|
|
605
739
|
}
|
|
606
740
|
}
|
|
607
741
|
return isDifferent ? newValue : knownGoodValue;
|
|
@@ -622,28 +756,125 @@ function typeofValidator(type) {
|
|
|
622
756
|
const unknown = new Validator((value) => value);
|
|
623
757
|
const any = new Validator((value) => value);
|
|
624
758
|
const string = typeofValidator("string");
|
|
625
|
-
const number =
|
|
626
|
-
if (Number.
|
|
759
|
+
const number = new Validator((value) => {
|
|
760
|
+
if (Number.isFinite(value)) {
|
|
761
|
+
return value;
|
|
762
|
+
}
|
|
763
|
+
if (typeof value !== "number") {
|
|
764
|
+
throw new ValidationError(`Expected number, got ${typeToString(value)}`);
|
|
765
|
+
}
|
|
766
|
+
if (value !== value) {
|
|
627
767
|
throw new ValidationError("Expected a number, got NaN");
|
|
628
768
|
}
|
|
629
|
-
|
|
630
|
-
|
|
769
|
+
throw new ValidationError(`Expected a finite number, got ${value}`);
|
|
770
|
+
});
|
|
771
|
+
const positiveNumber = new Validator((value) => {
|
|
772
|
+
if (Number.isFinite(value) && value >= 0) {
|
|
773
|
+
return value;
|
|
774
|
+
}
|
|
775
|
+
if (typeof value !== "number") {
|
|
776
|
+
throw new ValidationError(`Expected number, got ${typeToString(value)}`);
|
|
777
|
+
}
|
|
778
|
+
if (value !== value) {
|
|
779
|
+
throw new ValidationError("Expected a number, got NaN");
|
|
631
780
|
}
|
|
781
|
+
if (value < 0) {
|
|
782
|
+
throw new ValidationError(`Expected a positive number, got ${value}`);
|
|
783
|
+
}
|
|
784
|
+
throw new ValidationError(`Expected a finite number, got ${value}`);
|
|
632
785
|
});
|
|
633
|
-
const
|
|
634
|
-
if (value
|
|
786
|
+
const nonZeroNumber = new Validator((value) => {
|
|
787
|
+
if (Number.isFinite(value) && value > 0) {
|
|
788
|
+
return value;
|
|
789
|
+
}
|
|
790
|
+
if (typeof value !== "number") {
|
|
791
|
+
throw new ValidationError(`Expected number, got ${typeToString(value)}`);
|
|
792
|
+
}
|
|
793
|
+
if (value !== value) {
|
|
794
|
+
throw new ValidationError("Expected a number, got NaN");
|
|
795
|
+
}
|
|
796
|
+
if (value <= 0) {
|
|
797
|
+
throw new ValidationError(`Expected a non-zero positive number, got ${value}`);
|
|
798
|
+
}
|
|
799
|
+
throw new ValidationError(`Expected a finite number, got ${value}`);
|
|
800
|
+
});
|
|
801
|
+
const nonZeroFiniteNumber = new Validator((value) => {
|
|
802
|
+
if (Number.isFinite(value) && value !== 0) {
|
|
803
|
+
return value;
|
|
804
|
+
}
|
|
805
|
+
if (typeof value !== "number") {
|
|
806
|
+
throw new ValidationError(`Expected number, got ${typeToString(value)}`);
|
|
807
|
+
}
|
|
808
|
+
if (value !== value) {
|
|
809
|
+
throw new ValidationError("Expected a number, got NaN");
|
|
810
|
+
}
|
|
811
|
+
if (value === 0) {
|
|
812
|
+
throw new ValidationError(`Expected a non-zero number, got 0`);
|
|
813
|
+
}
|
|
814
|
+
throw new ValidationError(`Expected a finite number, got ${value}`);
|
|
635
815
|
});
|
|
636
|
-
const
|
|
637
|
-
if (value
|
|
816
|
+
const unitInterval = new Validator((value) => {
|
|
817
|
+
if (Number.isFinite(value) && value >= 0 && value <= 1) {
|
|
818
|
+
return value;
|
|
819
|
+
}
|
|
820
|
+
if (typeof value !== "number") {
|
|
821
|
+
throw new ValidationError(`Expected number, got ${typeToString(value)}`);
|
|
822
|
+
}
|
|
823
|
+
if (value !== value) {
|
|
824
|
+
throw new ValidationError("Expected a number, got NaN");
|
|
825
|
+
}
|
|
826
|
+
throw new ValidationError(`Expected a number between 0 and 1, got ${value}`);
|
|
638
827
|
});
|
|
639
|
-
const integer =
|
|
640
|
-
if (
|
|
828
|
+
const integer = new Validator((value) => {
|
|
829
|
+
if (Number.isInteger(value)) {
|
|
830
|
+
return value;
|
|
831
|
+
}
|
|
832
|
+
if (typeof value !== "number") {
|
|
833
|
+
throw new ValidationError(`Expected number, got ${typeToString(value)}`);
|
|
834
|
+
}
|
|
835
|
+
if (value !== value) {
|
|
836
|
+
throw new ValidationError("Expected a number, got NaN");
|
|
837
|
+
}
|
|
838
|
+
if (value - value !== 0) {
|
|
839
|
+
throw new ValidationError(`Expected a finite number, got ${value}`);
|
|
840
|
+
}
|
|
841
|
+
throw new ValidationError(`Expected an integer, got ${value}`);
|
|
641
842
|
});
|
|
642
|
-
const positiveInteger =
|
|
643
|
-
if (value
|
|
843
|
+
const positiveInteger = new Validator((value) => {
|
|
844
|
+
if (Number.isInteger(value) && value >= 0) {
|
|
845
|
+
return value;
|
|
846
|
+
}
|
|
847
|
+
if (typeof value !== "number") {
|
|
848
|
+
throw new ValidationError(`Expected number, got ${typeToString(value)}`);
|
|
849
|
+
}
|
|
850
|
+
if (value !== value) {
|
|
851
|
+
throw new ValidationError("Expected a number, got NaN");
|
|
852
|
+
}
|
|
853
|
+
if (value - value !== 0) {
|
|
854
|
+
throw new ValidationError(`Expected a finite number, got ${value}`);
|
|
855
|
+
}
|
|
856
|
+
if (value < 0) {
|
|
857
|
+
throw new ValidationError(`Expected a positive integer, got ${value}`);
|
|
858
|
+
}
|
|
859
|
+
throw new ValidationError(`Expected an integer, got ${value}`);
|
|
644
860
|
});
|
|
645
|
-
const nonZeroInteger =
|
|
646
|
-
if (value
|
|
861
|
+
const nonZeroInteger = new Validator((value) => {
|
|
862
|
+
if (Number.isInteger(value) && value > 0) {
|
|
863
|
+
return value;
|
|
864
|
+
}
|
|
865
|
+
if (typeof value !== "number") {
|
|
866
|
+
throw new ValidationError(`Expected number, got ${typeToString(value)}`);
|
|
867
|
+
}
|
|
868
|
+
if (value !== value) {
|
|
869
|
+
throw new ValidationError("Expected a number, got NaN");
|
|
870
|
+
}
|
|
871
|
+
if (value - value !== 0) {
|
|
872
|
+
throw new ValidationError(`Expected a finite number, got ${value}`);
|
|
873
|
+
}
|
|
874
|
+
if (value <= 0) {
|
|
875
|
+
throw new ValidationError(`Expected a non-zero positive integer, got ${value}`);
|
|
876
|
+
}
|
|
877
|
+
throw new ValidationError(`Expected an integer, got ${value}`);
|
|
647
878
|
});
|
|
648
879
|
const boolean = typeofValidator("boolean");
|
|
649
880
|
const bigint = typeofValidator("bigint");
|
|
@@ -809,13 +1040,14 @@ function optional(validator) {
|
|
|
809
1040
|
return validator.validate(value);
|
|
810
1041
|
},
|
|
811
1042
|
(knownGoodValue, newValue) => {
|
|
812
|
-
if (knownGoodValue === void 0 && newValue === void 0) return void 0;
|
|
813
1043
|
if (newValue === void 0) return void 0;
|
|
814
1044
|
if (validator.validateUsingKnownGoodVersion && knownGoodValue !== void 0) {
|
|
815
1045
|
return validator.validateUsingKnownGoodVersion(knownGoodValue, newValue);
|
|
816
1046
|
}
|
|
817
1047
|
return validator.validate(newValue);
|
|
818
|
-
}
|
|
1048
|
+
},
|
|
1049
|
+
// Propagate skipSameValueCheck from inner validator to allow refine wrappers
|
|
1050
|
+
validator instanceof Validator && validator.skipSameValueCheck
|
|
819
1051
|
);
|
|
820
1052
|
}
|
|
821
1053
|
function nullable(validator) {
|
|
@@ -830,7 +1062,9 @@ function nullable(validator) {
|
|
|
830
1062
|
return validator.validateUsingKnownGoodVersion(knownGoodValue, newValue);
|
|
831
1063
|
}
|
|
832
1064
|
return validator.validate(newValue);
|
|
833
|
-
}
|
|
1065
|
+
},
|
|
1066
|
+
// Propagate skipSameValueCheck from inner validator to allow refine wrappers
|
|
1067
|
+
validator instanceof Validator && validator.skipSameValueCheck
|
|
834
1068
|
);
|
|
835
1069
|
}
|
|
836
1070
|
function literalEnum(...values) {
|
|
@@ -918,6 +1152,7 @@ export {
|
|
|
918
1152
|
literal,
|
|
919
1153
|
literalEnum,
|
|
920
1154
|
model,
|
|
1155
|
+
nonZeroFiniteNumber,
|
|
921
1156
|
nonZeroInteger,
|
|
922
1157
|
nonZeroNumber,
|
|
923
1158
|
nullable,
|
|
@@ -932,6 +1167,7 @@ export {
|
|
|
932
1167
|
srcUrl,
|
|
933
1168
|
string,
|
|
934
1169
|
union,
|
|
1170
|
+
unitInterval,
|
|
935
1171
|
unknown,
|
|
936
1172
|
unknownObject
|
|
937
1173
|
};
|