decoders 2.9.0-pre.4 → 2.9.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.
- package/dist/index.cjs +92 -46
- package/dist/index.d.cts +12 -7
- package/dist/index.d.ts +12 -7
- package/dist/index.js +92 -46
- package/package.json +5 -3
package/dist/index.cjs
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/lib/utils.ts
|
|
2
|
+
// @__NO_SIDE_EFFECTS__
|
|
2
3
|
function isNumber(value) {
|
|
3
4
|
return typeof value === "number";
|
|
4
5
|
}
|
|
6
|
+
// @__NO_SIDE_EFFECTS__
|
|
5
7
|
function isString(value) {
|
|
6
8
|
return typeof value === "string";
|
|
7
9
|
}
|
|
10
|
+
// @__NO_SIDE_EFFECTS__
|
|
8
11
|
function isBigInt(value) {
|
|
9
12
|
return typeof value === "bigint";
|
|
10
13
|
}
|
|
14
|
+
// @__NO_SIDE_EFFECTS__
|
|
11
15
|
function isDate(value) {
|
|
12
16
|
return !!value && Object.prototype.toString.call(value) === "[object Date]" && !isNaN(value);
|
|
13
17
|
}
|
|
18
|
+
// @__NO_SIDE_EFFECTS__
|
|
14
19
|
function isPromiseLike(value) {
|
|
15
20
|
return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
|
|
16
21
|
}
|
|
22
|
+
// @__NO_SIDE_EFFECTS__
|
|
17
23
|
function isPlainObject(value) {
|
|
18
24
|
return value !== null && typeof value === "object" && // This still seems to be the only reliable way to determine whether
|
|
19
25
|
// something is a pojo... ¯\_(ツ)_/¯
|
|
@@ -112,36 +118,40 @@ function public_annotateObject(obj, text) {
|
|
|
112
118
|
|
|
113
119
|
// src/lib/text.ts
|
|
114
120
|
var INDENT = " ";
|
|
121
|
+
// @__NO_SIDE_EFFECTS__
|
|
115
122
|
function isMultiline(s) {
|
|
116
123
|
return s.includes("\n");
|
|
117
124
|
}
|
|
125
|
+
// @__NO_SIDE_EFFECTS__
|
|
118
126
|
function indent(s, prefix = INDENT) {
|
|
119
|
-
if (isMultiline(s)) {
|
|
127
|
+
if (/* @__PURE__ */ isMultiline(s)) {
|
|
120
128
|
return s.split("\n").map((line) => `${prefix}${line}`).join("\n");
|
|
121
129
|
} else {
|
|
122
130
|
return `${prefix}${s}`;
|
|
123
131
|
}
|
|
124
132
|
}
|
|
125
133
|
var quotePattern = /'/g;
|
|
134
|
+
// @__NO_SIDE_EFFECTS__
|
|
126
135
|
function quote(value) {
|
|
127
136
|
return typeof value === "string" ? "'" + value.replace(quotePattern, "\\'") + "'" : value === void 0 ? "undefined" : JSON.stringify(value);
|
|
128
137
|
}
|
|
129
138
|
|
|
130
139
|
// src/core/format.ts
|
|
140
|
+
// @__NO_SIDE_EFFECTS__
|
|
131
141
|
function summarize(ann, keypath = []) {
|
|
132
142
|
const result = [];
|
|
133
143
|
if (ann.type === "array") {
|
|
134
144
|
const items = ann.items;
|
|
135
145
|
let index = 0;
|
|
136
146
|
for (const ann2 of items) {
|
|
137
|
-
for (const item of summarize(ann2, [...keypath, index++])) {
|
|
147
|
+
for (const item of /* @__PURE__ */ summarize(ann2, [...keypath, index++])) {
|
|
138
148
|
result.push(item);
|
|
139
149
|
}
|
|
140
150
|
}
|
|
141
151
|
} else if (ann.type === "object") {
|
|
142
152
|
const fields = ann.fields;
|
|
143
153
|
for (const [key, value] of fields) {
|
|
144
|
-
for (const item of summarize(value, [...keypath, key])) {
|
|
154
|
+
for (const item of /* @__PURE__ */ summarize(value, [...keypath, key])) {
|
|
145
155
|
result.push(item);
|
|
146
156
|
}
|
|
147
157
|
}
|
|
@@ -253,7 +263,7 @@ ${annotation}`;
|
|
|
253
263
|
}
|
|
254
264
|
}
|
|
255
265
|
function formatShort(ann) {
|
|
256
|
-
return summarize(ann, []).join("\n");
|
|
266
|
+
return (/* @__PURE__ */ summarize(ann, [])).join("\n");
|
|
257
267
|
}
|
|
258
268
|
function* iterAnnotation(ann, stack) {
|
|
259
269
|
if (ann.text) {
|
|
@@ -292,9 +302,11 @@ function formatAsIssues(ann) {
|
|
|
292
302
|
}
|
|
293
303
|
|
|
294
304
|
// src/core/Result.ts
|
|
305
|
+
// @__NO_SIDE_EFFECTS__
|
|
295
306
|
function ok(value) {
|
|
296
307
|
return { ok: true, value, error: void 0 };
|
|
297
308
|
}
|
|
309
|
+
// @__NO_SIDE_EFFECTS__
|
|
298
310
|
function err(error) {
|
|
299
311
|
return { ok: false, value: void 0, error };
|
|
300
312
|
}
|
|
@@ -321,6 +333,7 @@ ${formatted}`);
|
|
|
321
333
|
return formatted;
|
|
322
334
|
}
|
|
323
335
|
}
|
|
336
|
+
// @__NO_SIDE_EFFECTS__
|
|
324
337
|
function define(fn) {
|
|
325
338
|
function decode(blob) {
|
|
326
339
|
const makeFlexErr = (msg) => err(isAnnotation(msg) ? msg : public_annotate(blob, msg));
|
|
@@ -355,11 +368,11 @@ function define(fn) {
|
|
|
355
368
|
return self;
|
|
356
369
|
}
|
|
357
370
|
function chain(next) {
|
|
358
|
-
return define((blob, ok2, err2) => {
|
|
371
|
+
return /* @__PURE__ */ define((blob, ok2, err2) => {
|
|
359
372
|
const r1 = decode(blob);
|
|
360
373
|
if (!r1.ok) return r1;
|
|
361
|
-
const r2 = isDecoder(next) ? next : next(r1.value, ok2, err2);
|
|
362
|
-
return isDecoder(r2) ? r2.decode(r1.value) : r2;
|
|
374
|
+
const r2 = /* @__PURE__ */ isDecoder(next) ? next : next(r1.value, ok2, err2);
|
|
375
|
+
return /* @__PURE__ */ isDecoder(r2) ? r2.decode(r1.value) : r2;
|
|
363
376
|
});
|
|
364
377
|
}
|
|
365
378
|
function pipe(next) {
|
|
@@ -372,7 +385,7 @@ function define(fn) {
|
|
|
372
385
|
});
|
|
373
386
|
}
|
|
374
387
|
function describe(message) {
|
|
375
|
-
return define((blob, _, err2) => {
|
|
388
|
+
return /* @__PURE__ */ define((blob, _, err2) => {
|
|
376
389
|
const result = decode(blob);
|
|
377
390
|
if (result.ok) {
|
|
378
391
|
return result;
|
|
@@ -415,6 +428,7 @@ function brand2(decoder) {
|
|
|
415
428
|
_register2.add(decoder);
|
|
416
429
|
return decoder;
|
|
417
430
|
}
|
|
431
|
+
// @__NO_SIDE_EFFECTS__
|
|
418
432
|
function isDecoder(value) {
|
|
419
433
|
return _register2.has(value);
|
|
420
434
|
}
|
|
@@ -426,6 +440,7 @@ var poja = define((blob, ok2, err2) => {
|
|
|
426
440
|
}
|
|
427
441
|
return ok2(blob);
|
|
428
442
|
});
|
|
443
|
+
// @__NO_SIDE_EFFECTS__
|
|
429
444
|
function array(decoder) {
|
|
430
445
|
const decodeFn = decoder.decode;
|
|
431
446
|
return poja.chain((inputs, ok2, err2) => {
|
|
@@ -453,12 +468,14 @@ function array(decoder) {
|
|
|
453
468
|
function isNonEmpty(arr) {
|
|
454
469
|
return arr.length > 0;
|
|
455
470
|
}
|
|
471
|
+
// @__NO_SIDE_EFFECTS__
|
|
456
472
|
function nonEmptyArray(decoder) {
|
|
457
|
-
return array(decoder).refine(isNonEmpty, "Must be non-empty array");
|
|
473
|
+
return (/* @__PURE__ */ array(decoder)).refine(isNonEmpty, "Must be non-empty array");
|
|
458
474
|
}
|
|
459
|
-
var ntuple = (n) => poja.refine((arr) => arr.length === n, `Must be a ${n}-tuple`);
|
|
475
|
+
var ntuple = /* @__NO_SIDE_EFFECTS__ */ (n) => poja.refine((arr) => arr.length === n, `Must be a ${n}-tuple`);
|
|
476
|
+
// @__NO_SIDE_EFFECTS__
|
|
460
477
|
function tuple(...decoders) {
|
|
461
|
-
return ntuple(decoders.length).chain((blobs, ok2, err2) => {
|
|
478
|
+
return (/* @__PURE__ */ ntuple(decoders.length)).chain((blobs, ok2, err2) => {
|
|
462
479
|
let allOk = true;
|
|
463
480
|
const rvs = decoders.map((decoder, i) => {
|
|
464
481
|
const blob = blobs[i];
|
|
@@ -479,6 +496,7 @@ function tuple(...decoders) {
|
|
|
479
496
|
}
|
|
480
497
|
|
|
481
498
|
// src/lib/size-options.ts
|
|
499
|
+
// @__NO_SIDE_EFFECTS__
|
|
482
500
|
function bySizeOptions(options) {
|
|
483
501
|
const size = options.size;
|
|
484
502
|
const min2 = _nullishCoalesce(size, () => ( options.min));
|
|
@@ -501,6 +519,7 @@ function bySizeOptions(options) {
|
|
|
501
519
|
}
|
|
502
520
|
|
|
503
521
|
// src/misc.ts
|
|
522
|
+
// @__NO_SIDE_EFFECTS__
|
|
504
523
|
function instanceOf(klass) {
|
|
505
524
|
return define(
|
|
506
525
|
(blob, ok2, err2) => (
|
|
@@ -509,12 +528,15 @@ function instanceOf(klass) {
|
|
|
509
528
|
)
|
|
510
529
|
);
|
|
511
530
|
}
|
|
531
|
+
// @__NO_SIDE_EFFECTS__
|
|
512
532
|
function lazy(decoderFn) {
|
|
513
533
|
return define((blob) => decoderFn().decode(blob));
|
|
514
534
|
}
|
|
535
|
+
// @__NO_SIDE_EFFECTS__
|
|
515
536
|
function sized(decoder, options) {
|
|
516
537
|
return decoder.reject(bySizeOptions(options));
|
|
517
538
|
}
|
|
539
|
+
// @__NO_SIDE_EFFECTS__
|
|
518
540
|
function prep(mapperFn, decoder) {
|
|
519
541
|
return define((originalInput, _, err2) => {
|
|
520
542
|
let blob;
|
|
@@ -535,6 +557,7 @@ function prep(mapperFn, decoder) {
|
|
|
535
557
|
}
|
|
536
558
|
|
|
537
559
|
// src/lib/set-methods.ts
|
|
560
|
+
// @__NO_SIDE_EFFECTS__
|
|
538
561
|
function difference(xs, ys) {
|
|
539
562
|
const result = /* @__PURE__ */ new Set();
|
|
540
563
|
for (const x of xs) {
|
|
@@ -549,6 +572,7 @@ function difference(xs, ys) {
|
|
|
549
572
|
var pojo = define(
|
|
550
573
|
(blob, ok2, err2) => isPlainObject(blob) ? ok2(blob) : err2("Must be an object")
|
|
551
574
|
);
|
|
575
|
+
// @__NO_SIDE_EFFECTS__
|
|
552
576
|
function object(decoders) {
|
|
553
577
|
const knownKeys = new Set(Object.keys(decoders));
|
|
554
578
|
return pojo.chain((plainObj, ok2, err2) => {
|
|
@@ -591,6 +615,7 @@ function object(decoders) {
|
|
|
591
615
|
return ok2(record2);
|
|
592
616
|
});
|
|
593
617
|
}
|
|
618
|
+
// @__NO_SIDE_EFFECTS__
|
|
594
619
|
function exact(decoders) {
|
|
595
620
|
const allowedKeys = new Set(Object.keys(decoders));
|
|
596
621
|
const checked = pojo.reject((plainObj) => {
|
|
@@ -598,12 +623,13 @@ function exact(decoders) {
|
|
|
598
623
|
const extraKeys = difference(actualKeys, allowedKeys);
|
|
599
624
|
return extraKeys.size > 0 ? `Unexpected extra keys: ${Array.from(extraKeys).map(quote).join(", ")}` : null;
|
|
600
625
|
});
|
|
601
|
-
return checked.pipe(object(decoders));
|
|
626
|
+
return checked.pipe(/* @__PURE__ */ object(decoders));
|
|
602
627
|
}
|
|
628
|
+
// @__NO_SIDE_EFFECTS__
|
|
603
629
|
function inexact(decoders) {
|
|
604
630
|
return pojo.pipe((plainObj) => {
|
|
605
631
|
const allkeys = new Set(Object.keys(plainObj));
|
|
606
|
-
return object(decoders).transform((safepart) => {
|
|
632
|
+
return (/* @__PURE__ */ object(decoders)).transform((safepart) => {
|
|
607
633
|
const safekeys = new Set(Object.keys(decoders));
|
|
608
634
|
for (const k of safekeys) allkeys.add(k);
|
|
609
635
|
const rv = {};
|
|
@@ -630,6 +656,7 @@ function itemize(s) {
|
|
|
630
656
|
function nest(errText) {
|
|
631
657
|
return errText.startsWith(EITHER_PREFIX) ? errText.substring(EITHER_PREFIX.length) : itemize(errText);
|
|
632
658
|
}
|
|
659
|
+
// @__NO_SIDE_EFFECTS__
|
|
633
660
|
function either(...decoders) {
|
|
634
661
|
if (decoders.length === 0) {
|
|
635
662
|
throw new Error("Pass at least one decoder to either()");
|
|
@@ -648,6 +675,7 @@ function either(...decoders) {
|
|
|
648
675
|
return err2(text);
|
|
649
676
|
});
|
|
650
677
|
}
|
|
678
|
+
// @__NO_SIDE_EFFECTS__
|
|
651
679
|
function oneOf(constants) {
|
|
652
680
|
return define((blob, ok2, err2) => {
|
|
653
681
|
const index = constants.indexOf(blob);
|
|
@@ -657,28 +685,31 @@ function oneOf(constants) {
|
|
|
657
685
|
return err2(`Must be one of ${constants.map((value) => quote(value)).join(", ")}`);
|
|
658
686
|
});
|
|
659
687
|
}
|
|
688
|
+
// @__NO_SIDE_EFFECTS__
|
|
660
689
|
function enum_(enumObj) {
|
|
661
690
|
const values = Object.values(enumObj);
|
|
662
691
|
if (!values.some(isNumber)) {
|
|
663
|
-
return oneOf(values);
|
|
692
|
+
return /* @__PURE__ */ oneOf(values);
|
|
664
693
|
} else {
|
|
665
694
|
const nums = values.filter(isNumber);
|
|
666
695
|
const ignore = new Set(nums.map((val) => enumObj[val]));
|
|
667
696
|
const strings = values.filter(isString).filter((val) => !ignore.has(val));
|
|
668
|
-
return oneOf([...nums, ...strings]);
|
|
697
|
+
return /* @__PURE__ */ oneOf([...nums, ...strings]);
|
|
669
698
|
}
|
|
670
699
|
}
|
|
700
|
+
// @__NO_SIDE_EFFECTS__
|
|
671
701
|
function taggedUnion(field, mapping2) {
|
|
672
702
|
const scout = object({
|
|
673
|
-
[field]: prep(String, oneOf(Object.keys(mapping2)))
|
|
703
|
+
[field]: prep(String, /* @__PURE__ */ oneOf(Object.keys(mapping2)))
|
|
674
704
|
}).transform((o) => o[field]);
|
|
675
|
-
return select(
|
|
705
|
+
return /* @__PURE__ */ select(
|
|
676
706
|
scout,
|
|
677
707
|
// peek...
|
|
678
708
|
(key) => mapping2[key]
|
|
679
709
|
// ...then select
|
|
680
710
|
);
|
|
681
711
|
}
|
|
712
|
+
// @__NO_SIDE_EFFECTS__
|
|
682
713
|
function select(scout, selectFn) {
|
|
683
714
|
return define((blob) => {
|
|
684
715
|
const result = scout.decode(blob);
|
|
@@ -690,36 +721,42 @@ function select(scout, selectFn) {
|
|
|
690
721
|
function lazyval(value) {
|
|
691
722
|
return typeof value === "function" ? value() : value;
|
|
692
723
|
}
|
|
693
|
-
var null_ = constant(null);
|
|
694
|
-
var undefined_ = constant(void 0);
|
|
724
|
+
var null_ = /* @__PURE__ */ constant(null);
|
|
725
|
+
var undefined_ = /* @__PURE__ */ constant(void 0);
|
|
695
726
|
var nullish_ = define(
|
|
696
727
|
(blob, ok2, err2) => (
|
|
697
728
|
// Equiv to either(undefined_, null_), but combined for better error message
|
|
698
729
|
blob == null ? ok2(blob) : err2("Must be undefined or null")
|
|
699
730
|
)
|
|
700
731
|
);
|
|
732
|
+
// @__NO_SIDE_EFFECTS__
|
|
701
733
|
function optional(decoder, defaultValue) {
|
|
702
734
|
const rv = either(undefined_, decoder);
|
|
703
735
|
return arguments.length >= 2 ? rv.transform((value) => _nullishCoalesce(value, () => ( lazyval(defaultValue)))) : rv;
|
|
704
736
|
}
|
|
737
|
+
// @__NO_SIDE_EFFECTS__
|
|
705
738
|
function nullable(decoder, defaultValue) {
|
|
706
739
|
const rv = either(null_, decoder);
|
|
707
740
|
return arguments.length >= 2 ? rv.transform((value) => _nullishCoalesce(value, () => ( lazyval(defaultValue)))) : rv;
|
|
708
741
|
}
|
|
742
|
+
// @__NO_SIDE_EFFECTS__
|
|
709
743
|
function nullish(decoder, defaultValue) {
|
|
710
744
|
const rv = either(nullish_, decoder);
|
|
711
745
|
return arguments.length >= 2 ? rv.transform((value) => _nullishCoalesce(value, () => ( lazyval(defaultValue)))) : rv;
|
|
712
746
|
}
|
|
747
|
+
// @__NO_SIDE_EFFECTS__
|
|
713
748
|
function constant(value) {
|
|
714
749
|
return define(
|
|
715
750
|
(blob, ok2, err2) => blob === value ? ok2(value) : err2(`Must be ${typeof value === "symbol" ? String(value) : quote(value)}`)
|
|
716
751
|
);
|
|
717
752
|
}
|
|
753
|
+
// @__NO_SIDE_EFFECTS__
|
|
718
754
|
function always(value) {
|
|
719
755
|
return define(
|
|
720
756
|
typeof value === "function" ? (_, ok2) => ok2(value()) : (_, ok2) => ok2(value)
|
|
721
757
|
);
|
|
722
758
|
}
|
|
759
|
+
// @__NO_SIDE_EFFECTS__
|
|
723
760
|
function never(msg) {
|
|
724
761
|
return define((_, __, err2) => err2(msg));
|
|
725
762
|
}
|
|
@@ -734,6 +771,7 @@ var boolean = define((blob, ok2, err2) => {
|
|
|
734
771
|
var truthy = define((blob, ok2, _) => ok2(!!blob));
|
|
735
772
|
|
|
736
773
|
// src/collections.ts
|
|
774
|
+
// @__NO_SIDE_EFFECTS__
|
|
737
775
|
function record(fst, snd) {
|
|
738
776
|
const keyDecoder = snd !== void 0 ? fst : void 0;
|
|
739
777
|
const valueDecoder = _nullishCoalesce(snd, () => ( fst));
|
|
@@ -766,11 +804,13 @@ function record(fst, snd) {
|
|
|
766
804
|
}
|
|
767
805
|
});
|
|
768
806
|
}
|
|
807
|
+
// @__NO_SIDE_EFFECTS__
|
|
769
808
|
function setFromArray(decoder) {
|
|
770
809
|
return array(decoder).transform((items) => new Set(items));
|
|
771
810
|
}
|
|
811
|
+
// @__NO_SIDE_EFFECTS__
|
|
772
812
|
function mapping(decoder) {
|
|
773
|
-
return record(decoder).transform((obj) => new Map(Object.entries(obj)));
|
|
813
|
+
return (/* @__PURE__ */ record(decoder)).transform((obj) => new Map(Object.entries(obj)));
|
|
774
814
|
}
|
|
775
815
|
|
|
776
816
|
// src/strings.ts
|
|
@@ -778,78 +818,81 @@ var url_re = /^([A-Za-z]{2,12}(?:[+][A-Za-z]{2,12})?):\/\/(?:([^@:]*:?(?:[^@]+)?
|
|
|
778
818
|
var string = define(
|
|
779
819
|
(blob, ok2, err2) => isString(blob) ? ok2(blob) : err2("Must be string")
|
|
780
820
|
);
|
|
781
|
-
var nonEmptyString = regex(/\S/, "Must be non-empty string");
|
|
821
|
+
var nonEmptyString = /* @__PURE__ */ regex(/\S/, "Must be non-empty string");
|
|
822
|
+
// @__NO_SIDE_EFFECTS__
|
|
782
823
|
function regex(regex2, msg) {
|
|
783
824
|
return string.refine((s) => regex2.test(s), msg);
|
|
784
825
|
}
|
|
826
|
+
// @__NO_SIDE_EFFECTS__
|
|
785
827
|
function startsWith(prefix) {
|
|
786
828
|
return string.refine(
|
|
787
829
|
(s) => s.startsWith(prefix),
|
|
788
830
|
`Must start with '${prefix}'`
|
|
789
831
|
);
|
|
790
832
|
}
|
|
833
|
+
// @__NO_SIDE_EFFECTS__
|
|
791
834
|
function endsWith(suffix) {
|
|
792
835
|
return string.refine(
|
|
793
836
|
(s) => s.endsWith(suffix),
|
|
794
837
|
`Must end with '${suffix}'`
|
|
795
838
|
);
|
|
796
839
|
}
|
|
797
|
-
var email = regex(
|
|
840
|
+
var email = /* @__PURE__ */ regex(
|
|
798
841
|
// The almost perfect email regex, taken from https://emailregex.com/
|
|
799
842
|
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
|
|
800
843
|
"Must be email"
|
|
801
844
|
);
|
|
802
|
-
var urlString =
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
)
|
|
806
|
-
var url = either(
|
|
807
|
-
regex(url_re, "Must be URL").transform((value) => new URL(value)),
|
|
808
|
-
instanceOf(URL)
|
|
845
|
+
var urlString = /* @__PURE__ */ regex(url_re, "Must be URL");
|
|
846
|
+
var url = select(
|
|
847
|
+
unknown,
|
|
848
|
+
(blob) => typeof blob === "string" ? /* @__PURE__ */ urlString.transform((s) => new URL(s)) : /* @__PURE__ */ instanceOf(URL).describe("Must be URL")
|
|
809
849
|
);
|
|
810
|
-
var httpsUrl = url.refine(
|
|
850
|
+
var httpsUrl = /* @__PURE__ */ url.refine(
|
|
811
851
|
(value) => value.protocol === "https:",
|
|
812
|
-
"Must be
|
|
852
|
+
"Must be HTTPS URL"
|
|
813
853
|
);
|
|
814
|
-
var identifier = regex(
|
|
854
|
+
var identifier = /* @__PURE__ */ regex(
|
|
815
855
|
/^[a-z_][a-z0-9_]*$/i,
|
|
816
856
|
"Must be valid identifier"
|
|
817
857
|
);
|
|
858
|
+
// @__NO_SIDE_EFFECTS__
|
|
818
859
|
function nanoid(options) {
|
|
819
|
-
return sized(regex(/^[a-z0-9_-]+$/i, "Must be nano ID"), _nullishCoalesce(options, () => ( { size: 21 })));
|
|
860
|
+
return sized(/* @__PURE__ */ regex(/^[a-z0-9_-]+$/i, "Must be nano ID"), _nullishCoalesce(options, () => ( { size: 21 })));
|
|
820
861
|
}
|
|
821
|
-
var uuid = regex(
|
|
862
|
+
var uuid = /* @__PURE__ */ regex(
|
|
822
863
|
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
|
|
823
864
|
"Must be uuid"
|
|
824
865
|
);
|
|
825
866
|
var uuidv1 = (
|
|
826
867
|
// https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)
|
|
827
|
-
uuid.refine((value) => value[14] === "1", "Must be uuidv1")
|
|
868
|
+
/* @__PURE__ */ uuid.refine((value) => value[14] === "1", "Must be uuidv1")
|
|
828
869
|
);
|
|
829
870
|
var uuidv4 = (
|
|
830
871
|
// https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
|
|
831
|
-
uuid.refine((value) => value[14] === "4", "Must be uuidv4")
|
|
872
|
+
/* @__PURE__ */ uuid.refine((value) => value[14] === "4", "Must be uuidv4")
|
|
832
873
|
);
|
|
833
|
-
var decimal = regex(/^[0-9]+$/, "Must only contain digits");
|
|
834
|
-
var hexadecimal = regex(
|
|
874
|
+
var decimal = /* @__PURE__ */ regex(/^[0-9]+$/, "Must only contain digits");
|
|
875
|
+
var hexadecimal = /* @__PURE__ */ regex(
|
|
835
876
|
/^[0-9a-f]+$/i,
|
|
836
877
|
"Must only contain hexadecimal digits"
|
|
837
878
|
);
|
|
838
|
-
var numeric = decimal.transform(Number);
|
|
879
|
+
var numeric = /* @__PURE__ */ decimal.transform(Number);
|
|
839
880
|
|
|
840
881
|
// src/dates.ts
|
|
841
882
|
var iso8601_re = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:[.]\d+)?(?:Z|[+-]\d{2}:?\d{2})$/;
|
|
842
883
|
var date = define((blob, ok2, err2) => {
|
|
843
884
|
return isDate(blob) ? ok2(blob) : err2("Must be a Date");
|
|
844
885
|
});
|
|
845
|
-
var isoDateString = regex(
|
|
886
|
+
var isoDateString = /* @__PURE__ */ regex(
|
|
846
887
|
iso8601_re,
|
|
847
888
|
"Must be ISO8601 format"
|
|
848
889
|
).refine(
|
|
849
890
|
(value) => !Number.isNaN(new Date(value).getTime()),
|
|
850
891
|
"Must be valid date/time value"
|
|
851
892
|
);
|
|
852
|
-
var isoDate = isoDateString.transform(
|
|
893
|
+
var isoDate = /* @__PURE__ */ isoDateString.transform(
|
|
894
|
+
(value) => new Date(value)
|
|
895
|
+
);
|
|
853
896
|
var flexDate = select(
|
|
854
897
|
unknown,
|
|
855
898
|
(blob) => typeof blob === "string" ? isoDate : isDate(blob) ? date : never("Must be a Date or date string")
|
|
@@ -862,32 +905,35 @@ var datelike = flexDate;
|
|
|
862
905
|
var anyNumber = define(
|
|
863
906
|
(blob, ok2, err2) => isNumber(blob) ? ok2(blob) : err2("Must be number")
|
|
864
907
|
);
|
|
865
|
-
var number = anyNumber.refine(
|
|
908
|
+
var number = /* @__PURE__ */ anyNumber.refine(
|
|
866
909
|
(n) => Number.isFinite(n),
|
|
867
910
|
"Number must be finite"
|
|
868
911
|
);
|
|
869
|
-
var integer = number.refine(
|
|
912
|
+
var integer = /* @__PURE__ */ number.refine(
|
|
870
913
|
(n) => Number.isInteger(n),
|
|
871
914
|
"Number must be an integer"
|
|
872
915
|
);
|
|
873
|
-
var positiveNumber = number.refine(
|
|
916
|
+
var positiveNumber = /* @__PURE__ */ number.refine(
|
|
874
917
|
(n) => n >= 0 && !Object.is(n, -0),
|
|
875
918
|
"Number must be positive"
|
|
876
919
|
);
|
|
877
|
-
var positiveInteger = integer.refine(
|
|
920
|
+
var positiveInteger = /* @__PURE__ */ integer.refine(
|
|
878
921
|
(n) => n >= 0 && !Object.is(n, -0),
|
|
879
922
|
"Number must be positive"
|
|
880
923
|
);
|
|
924
|
+
// @__NO_SIDE_EFFECTS__
|
|
881
925
|
function min(min2, decoder = number) {
|
|
882
926
|
return decoder.reject(
|
|
883
927
|
(value) => value < min2 ? `Too low, must be at least ${min2}` : null
|
|
884
928
|
);
|
|
885
929
|
}
|
|
930
|
+
// @__NO_SIDE_EFFECTS__
|
|
886
931
|
function max(max2, decoder = number) {
|
|
887
932
|
return decoder.reject(
|
|
888
933
|
(value) => value > max2 ? `Too high, must be at most ${max2}` : null
|
|
889
934
|
);
|
|
890
935
|
}
|
|
936
|
+
// @__NO_SIDE_EFFECTS__
|
|
891
937
|
function between(min2, max2, decoder = number) {
|
|
892
938
|
return decoder.reject(
|
|
893
939
|
(value) => value < min2 ? `Too low, must be between ${min2} and ${max2}` : value > max2 ? `Too high, must be between ${min2} and ${max2}` : null
|
|
@@ -900,7 +946,7 @@ var bigint = define(
|
|
|
900
946
|
// src/json.ts
|
|
901
947
|
var jsonObject = lazy(() => record(json));
|
|
902
948
|
var jsonArray = lazy(() => array(json));
|
|
903
|
-
var json = either(
|
|
949
|
+
var json = /* @__PURE__ */ either(
|
|
904
950
|
null_,
|
|
905
951
|
string,
|
|
906
952
|
number,
|
package/dist/index.d.cts
CHANGED
|
@@ -423,11 +423,15 @@ type DistributiveRelax<T, Ks extends string | number | symbol> = T extends any ?
|
|
|
423
423
|
[K in Exclude<Ks, keyof T>]?: never;
|
|
424
424
|
}> : never;
|
|
425
425
|
|
|
426
|
-
type SizeOptions = {
|
|
427
|
-
|
|
426
|
+
type SizeOptions = Relax<{
|
|
427
|
+
size: number;
|
|
428
|
+
} | {
|
|
429
|
+
min: number;
|
|
428
430
|
max?: number;
|
|
429
|
-
|
|
430
|
-
|
|
431
|
+
} | {
|
|
432
|
+
min?: number;
|
|
433
|
+
max: number;
|
|
434
|
+
}>;
|
|
431
435
|
/**
|
|
432
436
|
* Anything with a .length or .size property, like strings, arrays, or sets.
|
|
433
437
|
*/
|
|
@@ -609,9 +613,10 @@ declare const httpsUrl: Decoder<URL>;
|
|
|
609
613
|
*/
|
|
610
614
|
declare const identifier: Decoder<string>;
|
|
611
615
|
/**
|
|
612
|
-
* Accepts and returns [
|
|
613
|
-
* values.
|
|
614
|
-
*
|
|
616
|
+
* Accepts and returns [Nano ID](https://zelark.github.io/nano-id-cc) string
|
|
617
|
+
* values. By default, expects a standard 21-char nanoid, but you can
|
|
618
|
+
* optionally specify different size constraints. It assumes the default nanoid
|
|
619
|
+
* alphabet.
|
|
615
620
|
*/
|
|
616
621
|
declare function nanoid(options?: SizeOptions): Decoder<string>;
|
|
617
622
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -423,11 +423,15 @@ type DistributiveRelax<T, Ks extends string | number | symbol> = T extends any ?
|
|
|
423
423
|
[K in Exclude<Ks, keyof T>]?: never;
|
|
424
424
|
}> : never;
|
|
425
425
|
|
|
426
|
-
type SizeOptions = {
|
|
427
|
-
|
|
426
|
+
type SizeOptions = Relax<{
|
|
427
|
+
size: number;
|
|
428
|
+
} | {
|
|
429
|
+
min: number;
|
|
428
430
|
max?: number;
|
|
429
|
-
|
|
430
|
-
|
|
431
|
+
} | {
|
|
432
|
+
min?: number;
|
|
433
|
+
max: number;
|
|
434
|
+
}>;
|
|
431
435
|
/**
|
|
432
436
|
* Anything with a .length or .size property, like strings, arrays, or sets.
|
|
433
437
|
*/
|
|
@@ -609,9 +613,10 @@ declare const httpsUrl: Decoder<URL>;
|
|
|
609
613
|
*/
|
|
610
614
|
declare const identifier: Decoder<string>;
|
|
611
615
|
/**
|
|
612
|
-
* Accepts and returns [
|
|
613
|
-
* values.
|
|
614
|
-
*
|
|
616
|
+
* Accepts and returns [Nano ID](https://zelark.github.io/nano-id-cc) string
|
|
617
|
+
* values. By default, expects a standard 21-char nanoid, but you can
|
|
618
|
+
* optionally specify different size constraints. It assumes the default nanoid
|
|
619
|
+
* alphabet.
|
|
615
620
|
*/
|
|
616
621
|
declare function nanoid(options?: SizeOptions): Decoder<string>;
|
|
617
622
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
// src/lib/utils.ts
|
|
2
|
+
// @__NO_SIDE_EFFECTS__
|
|
2
3
|
function isNumber(value) {
|
|
3
4
|
return typeof value === "number";
|
|
4
5
|
}
|
|
6
|
+
// @__NO_SIDE_EFFECTS__
|
|
5
7
|
function isString(value) {
|
|
6
8
|
return typeof value === "string";
|
|
7
9
|
}
|
|
10
|
+
// @__NO_SIDE_EFFECTS__
|
|
8
11
|
function isBigInt(value) {
|
|
9
12
|
return typeof value === "bigint";
|
|
10
13
|
}
|
|
14
|
+
// @__NO_SIDE_EFFECTS__
|
|
11
15
|
function isDate(value) {
|
|
12
16
|
return !!value && Object.prototype.toString.call(value) === "[object Date]" && !isNaN(value);
|
|
13
17
|
}
|
|
18
|
+
// @__NO_SIDE_EFFECTS__
|
|
14
19
|
function isPromiseLike(value) {
|
|
15
20
|
return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
|
|
16
21
|
}
|
|
22
|
+
// @__NO_SIDE_EFFECTS__
|
|
17
23
|
function isPlainObject(value) {
|
|
18
24
|
return value !== null && typeof value === "object" && // This still seems to be the only reliable way to determine whether
|
|
19
25
|
// something is a pojo... ¯\_(ツ)_/¯
|
|
@@ -112,36 +118,40 @@ function public_annotateObject(obj, text) {
|
|
|
112
118
|
|
|
113
119
|
// src/lib/text.ts
|
|
114
120
|
var INDENT = " ";
|
|
121
|
+
// @__NO_SIDE_EFFECTS__
|
|
115
122
|
function isMultiline(s) {
|
|
116
123
|
return s.includes("\n");
|
|
117
124
|
}
|
|
125
|
+
// @__NO_SIDE_EFFECTS__
|
|
118
126
|
function indent(s, prefix = INDENT) {
|
|
119
|
-
if (isMultiline(s)) {
|
|
127
|
+
if (/* @__PURE__ */ isMultiline(s)) {
|
|
120
128
|
return s.split("\n").map((line) => `${prefix}${line}`).join("\n");
|
|
121
129
|
} else {
|
|
122
130
|
return `${prefix}${s}`;
|
|
123
131
|
}
|
|
124
132
|
}
|
|
125
133
|
var quotePattern = /'/g;
|
|
134
|
+
// @__NO_SIDE_EFFECTS__
|
|
126
135
|
function quote(value) {
|
|
127
136
|
return typeof value === "string" ? "'" + value.replace(quotePattern, "\\'") + "'" : value === void 0 ? "undefined" : JSON.stringify(value);
|
|
128
137
|
}
|
|
129
138
|
|
|
130
139
|
// src/core/format.ts
|
|
140
|
+
// @__NO_SIDE_EFFECTS__
|
|
131
141
|
function summarize(ann, keypath = []) {
|
|
132
142
|
const result = [];
|
|
133
143
|
if (ann.type === "array") {
|
|
134
144
|
const items = ann.items;
|
|
135
145
|
let index = 0;
|
|
136
146
|
for (const ann2 of items) {
|
|
137
|
-
for (const item of summarize(ann2, [...keypath, index++])) {
|
|
147
|
+
for (const item of /* @__PURE__ */ summarize(ann2, [...keypath, index++])) {
|
|
138
148
|
result.push(item);
|
|
139
149
|
}
|
|
140
150
|
}
|
|
141
151
|
} else if (ann.type === "object") {
|
|
142
152
|
const fields = ann.fields;
|
|
143
153
|
for (const [key, value] of fields) {
|
|
144
|
-
for (const item of summarize(value, [...keypath, key])) {
|
|
154
|
+
for (const item of /* @__PURE__ */ summarize(value, [...keypath, key])) {
|
|
145
155
|
result.push(item);
|
|
146
156
|
}
|
|
147
157
|
}
|
|
@@ -253,7 +263,7 @@ ${annotation}`;
|
|
|
253
263
|
}
|
|
254
264
|
}
|
|
255
265
|
function formatShort(ann) {
|
|
256
|
-
return summarize(ann, []).join("\n");
|
|
266
|
+
return (/* @__PURE__ */ summarize(ann, [])).join("\n");
|
|
257
267
|
}
|
|
258
268
|
function* iterAnnotation(ann, stack) {
|
|
259
269
|
if (ann.text) {
|
|
@@ -292,9 +302,11 @@ function formatAsIssues(ann) {
|
|
|
292
302
|
}
|
|
293
303
|
|
|
294
304
|
// src/core/Result.ts
|
|
305
|
+
// @__NO_SIDE_EFFECTS__
|
|
295
306
|
function ok(value) {
|
|
296
307
|
return { ok: true, value, error: void 0 };
|
|
297
308
|
}
|
|
309
|
+
// @__NO_SIDE_EFFECTS__
|
|
298
310
|
function err(error) {
|
|
299
311
|
return { ok: false, value: void 0, error };
|
|
300
312
|
}
|
|
@@ -321,6 +333,7 @@ ${formatted}`);
|
|
|
321
333
|
return formatted;
|
|
322
334
|
}
|
|
323
335
|
}
|
|
336
|
+
// @__NO_SIDE_EFFECTS__
|
|
324
337
|
function define(fn) {
|
|
325
338
|
function decode(blob) {
|
|
326
339
|
const makeFlexErr = (msg) => err(isAnnotation(msg) ? msg : public_annotate(blob, msg));
|
|
@@ -355,11 +368,11 @@ function define(fn) {
|
|
|
355
368
|
return self;
|
|
356
369
|
}
|
|
357
370
|
function chain(next) {
|
|
358
|
-
return define((blob, ok2, err2) => {
|
|
371
|
+
return /* @__PURE__ */ define((blob, ok2, err2) => {
|
|
359
372
|
const r1 = decode(blob);
|
|
360
373
|
if (!r1.ok) return r1;
|
|
361
|
-
const r2 = isDecoder(next) ? next : next(r1.value, ok2, err2);
|
|
362
|
-
return isDecoder(r2) ? r2.decode(r1.value) : r2;
|
|
374
|
+
const r2 = /* @__PURE__ */ isDecoder(next) ? next : next(r1.value, ok2, err2);
|
|
375
|
+
return /* @__PURE__ */ isDecoder(r2) ? r2.decode(r1.value) : r2;
|
|
363
376
|
});
|
|
364
377
|
}
|
|
365
378
|
function pipe(next) {
|
|
@@ -372,7 +385,7 @@ function define(fn) {
|
|
|
372
385
|
});
|
|
373
386
|
}
|
|
374
387
|
function describe(message) {
|
|
375
|
-
return define((blob, _, err2) => {
|
|
388
|
+
return /* @__PURE__ */ define((blob, _, err2) => {
|
|
376
389
|
const result = decode(blob);
|
|
377
390
|
if (result.ok) {
|
|
378
391
|
return result;
|
|
@@ -415,6 +428,7 @@ function brand2(decoder) {
|
|
|
415
428
|
_register2.add(decoder);
|
|
416
429
|
return decoder;
|
|
417
430
|
}
|
|
431
|
+
// @__NO_SIDE_EFFECTS__
|
|
418
432
|
function isDecoder(value) {
|
|
419
433
|
return _register2.has(value);
|
|
420
434
|
}
|
|
@@ -426,6 +440,7 @@ var poja = define((blob, ok2, err2) => {
|
|
|
426
440
|
}
|
|
427
441
|
return ok2(blob);
|
|
428
442
|
});
|
|
443
|
+
// @__NO_SIDE_EFFECTS__
|
|
429
444
|
function array(decoder) {
|
|
430
445
|
const decodeFn = decoder.decode;
|
|
431
446
|
return poja.chain((inputs, ok2, err2) => {
|
|
@@ -453,12 +468,14 @@ function array(decoder) {
|
|
|
453
468
|
function isNonEmpty(arr) {
|
|
454
469
|
return arr.length > 0;
|
|
455
470
|
}
|
|
471
|
+
// @__NO_SIDE_EFFECTS__
|
|
456
472
|
function nonEmptyArray(decoder) {
|
|
457
|
-
return array(decoder).refine(isNonEmpty, "Must be non-empty array");
|
|
473
|
+
return (/* @__PURE__ */ array(decoder)).refine(isNonEmpty, "Must be non-empty array");
|
|
458
474
|
}
|
|
459
|
-
var ntuple = (n) => poja.refine((arr) => arr.length === n, `Must be a ${n}-tuple`);
|
|
475
|
+
var ntuple = /* @__NO_SIDE_EFFECTS__ */ (n) => poja.refine((arr) => arr.length === n, `Must be a ${n}-tuple`);
|
|
476
|
+
// @__NO_SIDE_EFFECTS__
|
|
460
477
|
function tuple(...decoders) {
|
|
461
|
-
return ntuple(decoders.length).chain((blobs, ok2, err2) => {
|
|
478
|
+
return (/* @__PURE__ */ ntuple(decoders.length)).chain((blobs, ok2, err2) => {
|
|
462
479
|
let allOk = true;
|
|
463
480
|
const rvs = decoders.map((decoder, i) => {
|
|
464
481
|
const blob = blobs[i];
|
|
@@ -479,6 +496,7 @@ function tuple(...decoders) {
|
|
|
479
496
|
}
|
|
480
497
|
|
|
481
498
|
// src/lib/size-options.ts
|
|
499
|
+
// @__NO_SIDE_EFFECTS__
|
|
482
500
|
function bySizeOptions(options) {
|
|
483
501
|
const size = options.size;
|
|
484
502
|
const min2 = size ?? options.min;
|
|
@@ -501,6 +519,7 @@ function bySizeOptions(options) {
|
|
|
501
519
|
}
|
|
502
520
|
|
|
503
521
|
// src/misc.ts
|
|
522
|
+
// @__NO_SIDE_EFFECTS__
|
|
504
523
|
function instanceOf(klass) {
|
|
505
524
|
return define(
|
|
506
525
|
(blob, ok2, err2) => (
|
|
@@ -509,12 +528,15 @@ function instanceOf(klass) {
|
|
|
509
528
|
)
|
|
510
529
|
);
|
|
511
530
|
}
|
|
531
|
+
// @__NO_SIDE_EFFECTS__
|
|
512
532
|
function lazy(decoderFn) {
|
|
513
533
|
return define((blob) => decoderFn().decode(blob));
|
|
514
534
|
}
|
|
535
|
+
// @__NO_SIDE_EFFECTS__
|
|
515
536
|
function sized(decoder, options) {
|
|
516
537
|
return decoder.reject(bySizeOptions(options));
|
|
517
538
|
}
|
|
539
|
+
// @__NO_SIDE_EFFECTS__
|
|
518
540
|
function prep(mapperFn, decoder) {
|
|
519
541
|
return define((originalInput, _, err2) => {
|
|
520
542
|
let blob;
|
|
@@ -535,6 +557,7 @@ function prep(mapperFn, decoder) {
|
|
|
535
557
|
}
|
|
536
558
|
|
|
537
559
|
// src/lib/set-methods.ts
|
|
560
|
+
// @__NO_SIDE_EFFECTS__
|
|
538
561
|
function difference(xs, ys) {
|
|
539
562
|
const result = /* @__PURE__ */ new Set();
|
|
540
563
|
for (const x of xs) {
|
|
@@ -549,6 +572,7 @@ function difference(xs, ys) {
|
|
|
549
572
|
var pojo = define(
|
|
550
573
|
(blob, ok2, err2) => isPlainObject(blob) ? ok2(blob) : err2("Must be an object")
|
|
551
574
|
);
|
|
575
|
+
// @__NO_SIDE_EFFECTS__
|
|
552
576
|
function object(decoders) {
|
|
553
577
|
const knownKeys = new Set(Object.keys(decoders));
|
|
554
578
|
return pojo.chain((plainObj, ok2, err2) => {
|
|
@@ -591,6 +615,7 @@ function object(decoders) {
|
|
|
591
615
|
return ok2(record2);
|
|
592
616
|
});
|
|
593
617
|
}
|
|
618
|
+
// @__NO_SIDE_EFFECTS__
|
|
594
619
|
function exact(decoders) {
|
|
595
620
|
const allowedKeys = new Set(Object.keys(decoders));
|
|
596
621
|
const checked = pojo.reject((plainObj) => {
|
|
@@ -598,12 +623,13 @@ function exact(decoders) {
|
|
|
598
623
|
const extraKeys = difference(actualKeys, allowedKeys);
|
|
599
624
|
return extraKeys.size > 0 ? `Unexpected extra keys: ${Array.from(extraKeys).map(quote).join(", ")}` : null;
|
|
600
625
|
});
|
|
601
|
-
return checked.pipe(object(decoders));
|
|
626
|
+
return checked.pipe(/* @__PURE__ */ object(decoders));
|
|
602
627
|
}
|
|
628
|
+
// @__NO_SIDE_EFFECTS__
|
|
603
629
|
function inexact(decoders) {
|
|
604
630
|
return pojo.pipe((plainObj) => {
|
|
605
631
|
const allkeys = new Set(Object.keys(plainObj));
|
|
606
|
-
return object(decoders).transform((safepart) => {
|
|
632
|
+
return (/* @__PURE__ */ object(decoders)).transform((safepart) => {
|
|
607
633
|
const safekeys = new Set(Object.keys(decoders));
|
|
608
634
|
for (const k of safekeys) allkeys.add(k);
|
|
609
635
|
const rv = {};
|
|
@@ -630,6 +656,7 @@ function itemize(s) {
|
|
|
630
656
|
function nest(errText) {
|
|
631
657
|
return errText.startsWith(EITHER_PREFIX) ? errText.substring(EITHER_PREFIX.length) : itemize(errText);
|
|
632
658
|
}
|
|
659
|
+
// @__NO_SIDE_EFFECTS__
|
|
633
660
|
function either(...decoders) {
|
|
634
661
|
if (decoders.length === 0) {
|
|
635
662
|
throw new Error("Pass at least one decoder to either()");
|
|
@@ -648,6 +675,7 @@ function either(...decoders) {
|
|
|
648
675
|
return err2(text);
|
|
649
676
|
});
|
|
650
677
|
}
|
|
678
|
+
// @__NO_SIDE_EFFECTS__
|
|
651
679
|
function oneOf(constants) {
|
|
652
680
|
return define((blob, ok2, err2) => {
|
|
653
681
|
const index = constants.indexOf(blob);
|
|
@@ -657,28 +685,31 @@ function oneOf(constants) {
|
|
|
657
685
|
return err2(`Must be one of ${constants.map((value) => quote(value)).join(", ")}`);
|
|
658
686
|
});
|
|
659
687
|
}
|
|
688
|
+
// @__NO_SIDE_EFFECTS__
|
|
660
689
|
function enum_(enumObj) {
|
|
661
690
|
const values = Object.values(enumObj);
|
|
662
691
|
if (!values.some(isNumber)) {
|
|
663
|
-
return oneOf(values);
|
|
692
|
+
return /* @__PURE__ */ oneOf(values);
|
|
664
693
|
} else {
|
|
665
694
|
const nums = values.filter(isNumber);
|
|
666
695
|
const ignore = new Set(nums.map((val) => enumObj[val]));
|
|
667
696
|
const strings = values.filter(isString).filter((val) => !ignore.has(val));
|
|
668
|
-
return oneOf([...nums, ...strings]);
|
|
697
|
+
return /* @__PURE__ */ oneOf([...nums, ...strings]);
|
|
669
698
|
}
|
|
670
699
|
}
|
|
700
|
+
// @__NO_SIDE_EFFECTS__
|
|
671
701
|
function taggedUnion(field, mapping2) {
|
|
672
702
|
const scout = object({
|
|
673
|
-
[field]: prep(String, oneOf(Object.keys(mapping2)))
|
|
703
|
+
[field]: prep(String, /* @__PURE__ */ oneOf(Object.keys(mapping2)))
|
|
674
704
|
}).transform((o) => o[field]);
|
|
675
|
-
return select(
|
|
705
|
+
return /* @__PURE__ */ select(
|
|
676
706
|
scout,
|
|
677
707
|
// peek...
|
|
678
708
|
(key) => mapping2[key]
|
|
679
709
|
// ...then select
|
|
680
710
|
);
|
|
681
711
|
}
|
|
712
|
+
// @__NO_SIDE_EFFECTS__
|
|
682
713
|
function select(scout, selectFn) {
|
|
683
714
|
return define((blob) => {
|
|
684
715
|
const result = scout.decode(blob);
|
|
@@ -690,36 +721,42 @@ function select(scout, selectFn) {
|
|
|
690
721
|
function lazyval(value) {
|
|
691
722
|
return typeof value === "function" ? value() : value;
|
|
692
723
|
}
|
|
693
|
-
var null_ = constant(null);
|
|
694
|
-
var undefined_ = constant(void 0);
|
|
724
|
+
var null_ = /* @__PURE__ */ constant(null);
|
|
725
|
+
var undefined_ = /* @__PURE__ */ constant(void 0);
|
|
695
726
|
var nullish_ = define(
|
|
696
727
|
(blob, ok2, err2) => (
|
|
697
728
|
// Equiv to either(undefined_, null_), but combined for better error message
|
|
698
729
|
blob == null ? ok2(blob) : err2("Must be undefined or null")
|
|
699
730
|
)
|
|
700
731
|
);
|
|
732
|
+
// @__NO_SIDE_EFFECTS__
|
|
701
733
|
function optional(decoder, defaultValue) {
|
|
702
734
|
const rv = either(undefined_, decoder);
|
|
703
735
|
return arguments.length >= 2 ? rv.transform((value) => value ?? lazyval(defaultValue)) : rv;
|
|
704
736
|
}
|
|
737
|
+
// @__NO_SIDE_EFFECTS__
|
|
705
738
|
function nullable(decoder, defaultValue) {
|
|
706
739
|
const rv = either(null_, decoder);
|
|
707
740
|
return arguments.length >= 2 ? rv.transform((value) => value ?? lazyval(defaultValue)) : rv;
|
|
708
741
|
}
|
|
742
|
+
// @__NO_SIDE_EFFECTS__
|
|
709
743
|
function nullish(decoder, defaultValue) {
|
|
710
744
|
const rv = either(nullish_, decoder);
|
|
711
745
|
return arguments.length >= 2 ? rv.transform((value) => value ?? lazyval(defaultValue)) : rv;
|
|
712
746
|
}
|
|
747
|
+
// @__NO_SIDE_EFFECTS__
|
|
713
748
|
function constant(value) {
|
|
714
749
|
return define(
|
|
715
750
|
(blob, ok2, err2) => blob === value ? ok2(value) : err2(`Must be ${typeof value === "symbol" ? String(value) : quote(value)}`)
|
|
716
751
|
);
|
|
717
752
|
}
|
|
753
|
+
// @__NO_SIDE_EFFECTS__
|
|
718
754
|
function always(value) {
|
|
719
755
|
return define(
|
|
720
756
|
typeof value === "function" ? (_, ok2) => ok2(value()) : (_, ok2) => ok2(value)
|
|
721
757
|
);
|
|
722
758
|
}
|
|
759
|
+
// @__NO_SIDE_EFFECTS__
|
|
723
760
|
function never(msg) {
|
|
724
761
|
return define((_, __, err2) => err2(msg));
|
|
725
762
|
}
|
|
@@ -734,6 +771,7 @@ var boolean = define((blob, ok2, err2) => {
|
|
|
734
771
|
var truthy = define((blob, ok2, _) => ok2(!!blob));
|
|
735
772
|
|
|
736
773
|
// src/collections.ts
|
|
774
|
+
// @__NO_SIDE_EFFECTS__
|
|
737
775
|
function record(fst, snd) {
|
|
738
776
|
const keyDecoder = snd !== void 0 ? fst : void 0;
|
|
739
777
|
const valueDecoder = snd ?? fst;
|
|
@@ -766,11 +804,13 @@ function record(fst, snd) {
|
|
|
766
804
|
}
|
|
767
805
|
});
|
|
768
806
|
}
|
|
807
|
+
// @__NO_SIDE_EFFECTS__
|
|
769
808
|
function setFromArray(decoder) {
|
|
770
809
|
return array(decoder).transform((items) => new Set(items));
|
|
771
810
|
}
|
|
811
|
+
// @__NO_SIDE_EFFECTS__
|
|
772
812
|
function mapping(decoder) {
|
|
773
|
-
return record(decoder).transform((obj) => new Map(Object.entries(obj)));
|
|
813
|
+
return (/* @__PURE__ */ record(decoder)).transform((obj) => new Map(Object.entries(obj)));
|
|
774
814
|
}
|
|
775
815
|
|
|
776
816
|
// src/strings.ts
|
|
@@ -778,78 +818,81 @@ var url_re = /^([A-Za-z]{2,12}(?:[+][A-Za-z]{2,12})?):\/\/(?:([^@:]*:?(?:[^@]+)?
|
|
|
778
818
|
var string = define(
|
|
779
819
|
(blob, ok2, err2) => isString(blob) ? ok2(blob) : err2("Must be string")
|
|
780
820
|
);
|
|
781
|
-
var nonEmptyString = regex(/\S/, "Must be non-empty string");
|
|
821
|
+
var nonEmptyString = /* @__PURE__ */ regex(/\S/, "Must be non-empty string");
|
|
822
|
+
// @__NO_SIDE_EFFECTS__
|
|
782
823
|
function regex(regex2, msg) {
|
|
783
824
|
return string.refine((s) => regex2.test(s), msg);
|
|
784
825
|
}
|
|
826
|
+
// @__NO_SIDE_EFFECTS__
|
|
785
827
|
function startsWith(prefix) {
|
|
786
828
|
return string.refine(
|
|
787
829
|
(s) => s.startsWith(prefix),
|
|
788
830
|
`Must start with '${prefix}'`
|
|
789
831
|
);
|
|
790
832
|
}
|
|
833
|
+
// @__NO_SIDE_EFFECTS__
|
|
791
834
|
function endsWith(suffix) {
|
|
792
835
|
return string.refine(
|
|
793
836
|
(s) => s.endsWith(suffix),
|
|
794
837
|
`Must end with '${suffix}'`
|
|
795
838
|
);
|
|
796
839
|
}
|
|
797
|
-
var email = regex(
|
|
840
|
+
var email = /* @__PURE__ */ regex(
|
|
798
841
|
// The almost perfect email regex, taken from https://emailregex.com/
|
|
799
842
|
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
|
|
800
843
|
"Must be email"
|
|
801
844
|
);
|
|
802
|
-
var urlString =
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
)
|
|
806
|
-
var url = either(
|
|
807
|
-
regex(url_re, "Must be URL").transform((value) => new URL(value)),
|
|
808
|
-
instanceOf(URL)
|
|
845
|
+
var urlString = /* @__PURE__ */ regex(url_re, "Must be URL");
|
|
846
|
+
var url = select(
|
|
847
|
+
unknown,
|
|
848
|
+
(blob) => typeof blob === "string" ? /* @__PURE__ */ urlString.transform((s) => new URL(s)) : /* @__PURE__ */ instanceOf(URL).describe("Must be URL")
|
|
809
849
|
);
|
|
810
|
-
var httpsUrl = url.refine(
|
|
850
|
+
var httpsUrl = /* @__PURE__ */ url.refine(
|
|
811
851
|
(value) => value.protocol === "https:",
|
|
812
|
-
"Must be
|
|
852
|
+
"Must be HTTPS URL"
|
|
813
853
|
);
|
|
814
|
-
var identifier = regex(
|
|
854
|
+
var identifier = /* @__PURE__ */ regex(
|
|
815
855
|
/^[a-z_][a-z0-9_]*$/i,
|
|
816
856
|
"Must be valid identifier"
|
|
817
857
|
);
|
|
858
|
+
// @__NO_SIDE_EFFECTS__
|
|
818
859
|
function nanoid(options) {
|
|
819
|
-
return sized(regex(/^[a-z0-9_-]+$/i, "Must be nano ID"), options ?? { size: 21 });
|
|
860
|
+
return sized(/* @__PURE__ */ regex(/^[a-z0-9_-]+$/i, "Must be nano ID"), options ?? { size: 21 });
|
|
820
861
|
}
|
|
821
|
-
var uuid = regex(
|
|
862
|
+
var uuid = /* @__PURE__ */ regex(
|
|
822
863
|
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
|
|
823
864
|
"Must be uuid"
|
|
824
865
|
);
|
|
825
866
|
var uuidv1 = (
|
|
826
867
|
// https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)
|
|
827
|
-
uuid.refine((value) => value[14] === "1", "Must be uuidv1")
|
|
868
|
+
/* @__PURE__ */ uuid.refine((value) => value[14] === "1", "Must be uuidv1")
|
|
828
869
|
);
|
|
829
870
|
var uuidv4 = (
|
|
830
871
|
// https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
|
|
831
|
-
uuid.refine((value) => value[14] === "4", "Must be uuidv4")
|
|
872
|
+
/* @__PURE__ */ uuid.refine((value) => value[14] === "4", "Must be uuidv4")
|
|
832
873
|
);
|
|
833
|
-
var decimal = regex(/^[0-9]+$/, "Must only contain digits");
|
|
834
|
-
var hexadecimal = regex(
|
|
874
|
+
var decimal = /* @__PURE__ */ regex(/^[0-9]+$/, "Must only contain digits");
|
|
875
|
+
var hexadecimal = /* @__PURE__ */ regex(
|
|
835
876
|
/^[0-9a-f]+$/i,
|
|
836
877
|
"Must only contain hexadecimal digits"
|
|
837
878
|
);
|
|
838
|
-
var numeric = decimal.transform(Number);
|
|
879
|
+
var numeric = /* @__PURE__ */ decimal.transform(Number);
|
|
839
880
|
|
|
840
881
|
// src/dates.ts
|
|
841
882
|
var iso8601_re = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:[.]\d+)?(?:Z|[+-]\d{2}:?\d{2})$/;
|
|
842
883
|
var date = define((blob, ok2, err2) => {
|
|
843
884
|
return isDate(blob) ? ok2(blob) : err2("Must be a Date");
|
|
844
885
|
});
|
|
845
|
-
var isoDateString = regex(
|
|
886
|
+
var isoDateString = /* @__PURE__ */ regex(
|
|
846
887
|
iso8601_re,
|
|
847
888
|
"Must be ISO8601 format"
|
|
848
889
|
).refine(
|
|
849
890
|
(value) => !Number.isNaN(new Date(value).getTime()),
|
|
850
891
|
"Must be valid date/time value"
|
|
851
892
|
);
|
|
852
|
-
var isoDate = isoDateString.transform(
|
|
893
|
+
var isoDate = /* @__PURE__ */ isoDateString.transform(
|
|
894
|
+
(value) => new Date(value)
|
|
895
|
+
);
|
|
853
896
|
var flexDate = select(
|
|
854
897
|
unknown,
|
|
855
898
|
(blob) => typeof blob === "string" ? isoDate : isDate(blob) ? date : never("Must be a Date or date string")
|
|
@@ -862,32 +905,35 @@ var datelike = flexDate;
|
|
|
862
905
|
var anyNumber = define(
|
|
863
906
|
(blob, ok2, err2) => isNumber(blob) ? ok2(blob) : err2("Must be number")
|
|
864
907
|
);
|
|
865
|
-
var number = anyNumber.refine(
|
|
908
|
+
var number = /* @__PURE__ */ anyNumber.refine(
|
|
866
909
|
(n) => Number.isFinite(n),
|
|
867
910
|
"Number must be finite"
|
|
868
911
|
);
|
|
869
|
-
var integer = number.refine(
|
|
912
|
+
var integer = /* @__PURE__ */ number.refine(
|
|
870
913
|
(n) => Number.isInteger(n),
|
|
871
914
|
"Number must be an integer"
|
|
872
915
|
);
|
|
873
|
-
var positiveNumber = number.refine(
|
|
916
|
+
var positiveNumber = /* @__PURE__ */ number.refine(
|
|
874
917
|
(n) => n >= 0 && !Object.is(n, -0),
|
|
875
918
|
"Number must be positive"
|
|
876
919
|
);
|
|
877
|
-
var positiveInteger = integer.refine(
|
|
920
|
+
var positiveInteger = /* @__PURE__ */ integer.refine(
|
|
878
921
|
(n) => n >= 0 && !Object.is(n, -0),
|
|
879
922
|
"Number must be positive"
|
|
880
923
|
);
|
|
924
|
+
// @__NO_SIDE_EFFECTS__
|
|
881
925
|
function min(min2, decoder = number) {
|
|
882
926
|
return decoder.reject(
|
|
883
927
|
(value) => value < min2 ? `Too low, must be at least ${min2}` : null
|
|
884
928
|
);
|
|
885
929
|
}
|
|
930
|
+
// @__NO_SIDE_EFFECTS__
|
|
886
931
|
function max(max2, decoder = number) {
|
|
887
932
|
return decoder.reject(
|
|
888
933
|
(value) => value > max2 ? `Too high, must be at most ${max2}` : null
|
|
889
934
|
);
|
|
890
935
|
}
|
|
936
|
+
// @__NO_SIDE_EFFECTS__
|
|
891
937
|
function between(min2, max2, decoder = number) {
|
|
892
938
|
return decoder.reject(
|
|
893
939
|
(value) => value < min2 ? `Too low, must be between ${min2} and ${max2}` : value > max2 ? `Too high, must be between ${min2} and ${max2}` : null
|
|
@@ -900,7 +946,7 @@ var bigint = define(
|
|
|
900
946
|
// src/json.ts
|
|
901
947
|
var jsonObject = lazy(() => record(json));
|
|
902
948
|
var jsonArray = lazy(() => array(json));
|
|
903
|
-
var json = either(
|
|
949
|
+
var json = /* @__PURE__ */ either(
|
|
904
950
|
null_,
|
|
905
951
|
string,
|
|
906
952
|
number,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "decoders",
|
|
3
|
-
"version": "2.9.0
|
|
3
|
+
"version": "2.9.0",
|
|
4
4
|
"description": "Elegant and battle-tested validation library for type-safe input data for TypeScript",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -37,10 +37,12 @@
|
|
|
37
37
|
"build": "tsup",
|
|
38
38
|
"docs": "npm run build && cp -r dist/ docs/decoders-latest-snapshot/ && cd docs && rm -rf .next && npm run dev",
|
|
39
39
|
"docs:update-sources": "node bin/update-source-lines.js",
|
|
40
|
-
"
|
|
40
|
+
"docs:update-redirects": "node bin/update-decoder-redirects.js",
|
|
41
|
+
"lint": "oxlint src/ test/ && prettier --list-different src/ test/ test-d/ && node bin/lint-side-effects.js",
|
|
41
42
|
"lint:package": "publint --strict && attw --pack",
|
|
42
|
-
"format": "oxlint --fix src/ test/ ; prettier --write src/ test/ test-d/ docs/content/ ; npm run docs:update-sources",
|
|
43
|
+
"format": "oxlint --fix src/ test/ ; prettier --write src/ test/ test-d/ docs/content/ ; npm run docs:update-sources ; npm run docs:update-redirects",
|
|
43
44
|
"test": "vitest run --coverage",
|
|
45
|
+
"test:treeshake": "npm run build && node bin/test-treeshake.js",
|
|
44
46
|
"test:completeness": "./bin/check.sh",
|
|
45
47
|
"test:typescript": "tsc --noEmit",
|
|
46
48
|
"test:types": "npm run build && tsd --typings ./dist/index.d.ts",
|