decoders 2.9.0-pre.5 → 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 +89 -40
- package/dist/index.d.cts +12 -7
- package/dist/index.d.ts +12 -7
- package/dist/index.js +89 -40
- package/package.json +3 -2
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,75 +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 = regex(url_re, "Must be URL");
|
|
845
|
+
var urlString = /* @__PURE__ */ regex(url_re, "Must be URL");
|
|
803
846
|
var url = select(
|
|
804
847
|
unknown,
|
|
805
|
-
(blob) => typeof blob === "string" ? urlString.transform((s) => new URL(s)) : instanceOf(URL).describe("Must be URL")
|
|
848
|
+
(blob) => typeof blob === "string" ? /* @__PURE__ */ urlString.transform((s) => new URL(s)) : /* @__PURE__ */ instanceOf(URL).describe("Must be URL")
|
|
806
849
|
);
|
|
807
|
-
var httpsUrl = url.refine(
|
|
850
|
+
var httpsUrl = /* @__PURE__ */ url.refine(
|
|
808
851
|
(value) => value.protocol === "https:",
|
|
809
852
|
"Must be HTTPS URL"
|
|
810
853
|
);
|
|
811
|
-
var identifier = regex(
|
|
854
|
+
var identifier = /* @__PURE__ */ regex(
|
|
812
855
|
/^[a-z_][a-z0-9_]*$/i,
|
|
813
856
|
"Must be valid identifier"
|
|
814
857
|
);
|
|
858
|
+
// @__NO_SIDE_EFFECTS__
|
|
815
859
|
function nanoid(options) {
|
|
816
|
-
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 })));
|
|
817
861
|
}
|
|
818
|
-
var uuid = regex(
|
|
862
|
+
var uuid = /* @__PURE__ */ regex(
|
|
819
863
|
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
|
|
820
864
|
"Must be uuid"
|
|
821
865
|
);
|
|
822
866
|
var uuidv1 = (
|
|
823
867
|
// https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)
|
|
824
|
-
uuid.refine((value) => value[14] === "1", "Must be uuidv1")
|
|
868
|
+
/* @__PURE__ */ uuid.refine((value) => value[14] === "1", "Must be uuidv1")
|
|
825
869
|
);
|
|
826
870
|
var uuidv4 = (
|
|
827
871
|
// https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
|
|
828
|
-
uuid.refine((value) => value[14] === "4", "Must be uuidv4")
|
|
872
|
+
/* @__PURE__ */ uuid.refine((value) => value[14] === "4", "Must be uuidv4")
|
|
829
873
|
);
|
|
830
|
-
var decimal = regex(/^[0-9]+$/, "Must only contain digits");
|
|
831
|
-
var hexadecimal = regex(
|
|
874
|
+
var decimal = /* @__PURE__ */ regex(/^[0-9]+$/, "Must only contain digits");
|
|
875
|
+
var hexadecimal = /* @__PURE__ */ regex(
|
|
832
876
|
/^[0-9a-f]+$/i,
|
|
833
877
|
"Must only contain hexadecimal digits"
|
|
834
878
|
);
|
|
835
|
-
var numeric = decimal.transform(Number);
|
|
879
|
+
var numeric = /* @__PURE__ */ decimal.transform(Number);
|
|
836
880
|
|
|
837
881
|
// src/dates.ts
|
|
838
882
|
var iso8601_re = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:[.]\d+)?(?:Z|[+-]\d{2}:?\d{2})$/;
|
|
839
883
|
var date = define((blob, ok2, err2) => {
|
|
840
884
|
return isDate(blob) ? ok2(blob) : err2("Must be a Date");
|
|
841
885
|
});
|
|
842
|
-
var isoDateString = regex(
|
|
886
|
+
var isoDateString = /* @__PURE__ */ regex(
|
|
843
887
|
iso8601_re,
|
|
844
888
|
"Must be ISO8601 format"
|
|
845
889
|
).refine(
|
|
846
890
|
(value) => !Number.isNaN(new Date(value).getTime()),
|
|
847
891
|
"Must be valid date/time value"
|
|
848
892
|
);
|
|
849
|
-
var isoDate = isoDateString.transform(
|
|
893
|
+
var isoDate = /* @__PURE__ */ isoDateString.transform(
|
|
894
|
+
(value) => new Date(value)
|
|
895
|
+
);
|
|
850
896
|
var flexDate = select(
|
|
851
897
|
unknown,
|
|
852
898
|
(blob) => typeof blob === "string" ? isoDate : isDate(blob) ? date : never("Must be a Date or date string")
|
|
@@ -859,32 +905,35 @@ var datelike = flexDate;
|
|
|
859
905
|
var anyNumber = define(
|
|
860
906
|
(blob, ok2, err2) => isNumber(blob) ? ok2(blob) : err2("Must be number")
|
|
861
907
|
);
|
|
862
|
-
var number = anyNumber.refine(
|
|
908
|
+
var number = /* @__PURE__ */ anyNumber.refine(
|
|
863
909
|
(n) => Number.isFinite(n),
|
|
864
910
|
"Number must be finite"
|
|
865
911
|
);
|
|
866
|
-
var integer = number.refine(
|
|
912
|
+
var integer = /* @__PURE__ */ number.refine(
|
|
867
913
|
(n) => Number.isInteger(n),
|
|
868
914
|
"Number must be an integer"
|
|
869
915
|
);
|
|
870
|
-
var positiveNumber = number.refine(
|
|
916
|
+
var positiveNumber = /* @__PURE__ */ number.refine(
|
|
871
917
|
(n) => n >= 0 && !Object.is(n, -0),
|
|
872
918
|
"Number must be positive"
|
|
873
919
|
);
|
|
874
|
-
var positiveInteger = integer.refine(
|
|
920
|
+
var positiveInteger = /* @__PURE__ */ integer.refine(
|
|
875
921
|
(n) => n >= 0 && !Object.is(n, -0),
|
|
876
922
|
"Number must be positive"
|
|
877
923
|
);
|
|
924
|
+
// @__NO_SIDE_EFFECTS__
|
|
878
925
|
function min(min2, decoder = number) {
|
|
879
926
|
return decoder.reject(
|
|
880
927
|
(value) => value < min2 ? `Too low, must be at least ${min2}` : null
|
|
881
928
|
);
|
|
882
929
|
}
|
|
930
|
+
// @__NO_SIDE_EFFECTS__
|
|
883
931
|
function max(max2, decoder = number) {
|
|
884
932
|
return decoder.reject(
|
|
885
933
|
(value) => value > max2 ? `Too high, must be at most ${max2}` : null
|
|
886
934
|
);
|
|
887
935
|
}
|
|
936
|
+
// @__NO_SIDE_EFFECTS__
|
|
888
937
|
function between(min2, max2, decoder = number) {
|
|
889
938
|
return decoder.reject(
|
|
890
939
|
(value) => value < min2 ? `Too low, must be between ${min2} and ${max2}` : value > max2 ? `Too high, must be between ${min2} and ${max2}` : null
|
|
@@ -897,7 +946,7 @@ var bigint = define(
|
|
|
897
946
|
// src/json.ts
|
|
898
947
|
var jsonObject = lazy(() => record(json));
|
|
899
948
|
var jsonArray = lazy(() => array(json));
|
|
900
|
-
var json = either(
|
|
949
|
+
var json = /* @__PURE__ */ either(
|
|
901
950
|
null_,
|
|
902
951
|
string,
|
|
903
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,75 +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 = regex(url_re, "Must be URL");
|
|
845
|
+
var urlString = /* @__PURE__ */ regex(url_re, "Must be URL");
|
|
803
846
|
var url = select(
|
|
804
847
|
unknown,
|
|
805
|
-
(blob) => typeof blob === "string" ? urlString.transform((s) => new URL(s)) : instanceOf(URL).describe("Must be URL")
|
|
848
|
+
(blob) => typeof blob === "string" ? /* @__PURE__ */ urlString.transform((s) => new URL(s)) : /* @__PURE__ */ instanceOf(URL).describe("Must be URL")
|
|
806
849
|
);
|
|
807
|
-
var httpsUrl = url.refine(
|
|
850
|
+
var httpsUrl = /* @__PURE__ */ url.refine(
|
|
808
851
|
(value) => value.protocol === "https:",
|
|
809
852
|
"Must be HTTPS URL"
|
|
810
853
|
);
|
|
811
|
-
var identifier = regex(
|
|
854
|
+
var identifier = /* @__PURE__ */ regex(
|
|
812
855
|
/^[a-z_][a-z0-9_]*$/i,
|
|
813
856
|
"Must be valid identifier"
|
|
814
857
|
);
|
|
858
|
+
// @__NO_SIDE_EFFECTS__
|
|
815
859
|
function nanoid(options) {
|
|
816
|
-
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 });
|
|
817
861
|
}
|
|
818
|
-
var uuid = regex(
|
|
862
|
+
var uuid = /* @__PURE__ */ regex(
|
|
819
863
|
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
|
|
820
864
|
"Must be uuid"
|
|
821
865
|
);
|
|
822
866
|
var uuidv1 = (
|
|
823
867
|
// https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)
|
|
824
|
-
uuid.refine((value) => value[14] === "1", "Must be uuidv1")
|
|
868
|
+
/* @__PURE__ */ uuid.refine((value) => value[14] === "1", "Must be uuidv1")
|
|
825
869
|
);
|
|
826
870
|
var uuidv4 = (
|
|
827
871
|
// https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
|
|
828
|
-
uuid.refine((value) => value[14] === "4", "Must be uuidv4")
|
|
872
|
+
/* @__PURE__ */ uuid.refine((value) => value[14] === "4", "Must be uuidv4")
|
|
829
873
|
);
|
|
830
|
-
var decimal = regex(/^[0-9]+$/, "Must only contain digits");
|
|
831
|
-
var hexadecimal = regex(
|
|
874
|
+
var decimal = /* @__PURE__ */ regex(/^[0-9]+$/, "Must only contain digits");
|
|
875
|
+
var hexadecimal = /* @__PURE__ */ regex(
|
|
832
876
|
/^[0-9a-f]+$/i,
|
|
833
877
|
"Must only contain hexadecimal digits"
|
|
834
878
|
);
|
|
835
|
-
var numeric = decimal.transform(Number);
|
|
879
|
+
var numeric = /* @__PURE__ */ decimal.transform(Number);
|
|
836
880
|
|
|
837
881
|
// src/dates.ts
|
|
838
882
|
var iso8601_re = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:[.]\d+)?(?:Z|[+-]\d{2}:?\d{2})$/;
|
|
839
883
|
var date = define((blob, ok2, err2) => {
|
|
840
884
|
return isDate(blob) ? ok2(blob) : err2("Must be a Date");
|
|
841
885
|
});
|
|
842
|
-
var isoDateString = regex(
|
|
886
|
+
var isoDateString = /* @__PURE__ */ regex(
|
|
843
887
|
iso8601_re,
|
|
844
888
|
"Must be ISO8601 format"
|
|
845
889
|
).refine(
|
|
846
890
|
(value) => !Number.isNaN(new Date(value).getTime()),
|
|
847
891
|
"Must be valid date/time value"
|
|
848
892
|
);
|
|
849
|
-
var isoDate = isoDateString.transform(
|
|
893
|
+
var isoDate = /* @__PURE__ */ isoDateString.transform(
|
|
894
|
+
(value) => new Date(value)
|
|
895
|
+
);
|
|
850
896
|
var flexDate = select(
|
|
851
897
|
unknown,
|
|
852
898
|
(blob) => typeof blob === "string" ? isoDate : isDate(blob) ? date : never("Must be a Date or date string")
|
|
@@ -859,32 +905,35 @@ var datelike = flexDate;
|
|
|
859
905
|
var anyNumber = define(
|
|
860
906
|
(blob, ok2, err2) => isNumber(blob) ? ok2(blob) : err2("Must be number")
|
|
861
907
|
);
|
|
862
|
-
var number = anyNumber.refine(
|
|
908
|
+
var number = /* @__PURE__ */ anyNumber.refine(
|
|
863
909
|
(n) => Number.isFinite(n),
|
|
864
910
|
"Number must be finite"
|
|
865
911
|
);
|
|
866
|
-
var integer = number.refine(
|
|
912
|
+
var integer = /* @__PURE__ */ number.refine(
|
|
867
913
|
(n) => Number.isInteger(n),
|
|
868
914
|
"Number must be an integer"
|
|
869
915
|
);
|
|
870
|
-
var positiveNumber = number.refine(
|
|
916
|
+
var positiveNumber = /* @__PURE__ */ number.refine(
|
|
871
917
|
(n) => n >= 0 && !Object.is(n, -0),
|
|
872
918
|
"Number must be positive"
|
|
873
919
|
);
|
|
874
|
-
var positiveInteger = integer.refine(
|
|
920
|
+
var positiveInteger = /* @__PURE__ */ integer.refine(
|
|
875
921
|
(n) => n >= 0 && !Object.is(n, -0),
|
|
876
922
|
"Number must be positive"
|
|
877
923
|
);
|
|
924
|
+
// @__NO_SIDE_EFFECTS__
|
|
878
925
|
function min(min2, decoder = number) {
|
|
879
926
|
return decoder.reject(
|
|
880
927
|
(value) => value < min2 ? `Too low, must be at least ${min2}` : null
|
|
881
928
|
);
|
|
882
929
|
}
|
|
930
|
+
// @__NO_SIDE_EFFECTS__
|
|
883
931
|
function max(max2, decoder = number) {
|
|
884
932
|
return decoder.reject(
|
|
885
933
|
(value) => value > max2 ? `Too high, must be at most ${max2}` : null
|
|
886
934
|
);
|
|
887
935
|
}
|
|
936
|
+
// @__NO_SIDE_EFFECTS__
|
|
888
937
|
function between(min2, max2, decoder = number) {
|
|
889
938
|
return decoder.reject(
|
|
890
939
|
(value) => value < min2 ? `Too low, must be between ${min2} and ${max2}` : value > max2 ? `Too high, must be between ${min2} and ${max2}` : null
|
|
@@ -897,7 +946,7 @@ var bigint = define(
|
|
|
897
946
|
// src/json.ts
|
|
898
947
|
var jsonObject = lazy(() => record(json));
|
|
899
948
|
var jsonArray = lazy(() => array(json));
|
|
900
|
-
var json = either(
|
|
949
|
+
var json = /* @__PURE__ */ either(
|
|
901
950
|
null_,
|
|
902
951
|
string,
|
|
903
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": {
|
|
@@ -38,10 +38,11 @@
|
|
|
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/",
|
|
41
|
+
"lint": "oxlint src/ test/ && prettier --list-different src/ test/ test-d/ && node bin/lint-side-effects.js",
|
|
42
42
|
"lint:package": "publint --strict && attw --pack",
|
|
43
43
|
"format": "oxlint --fix src/ test/ ; prettier --write src/ test/ test-d/ docs/content/ ; npm run docs:update-sources ; npm run docs:update-redirects",
|
|
44
44
|
"test": "vitest run --coverage",
|
|
45
|
+
"test:treeshake": "npm run build && node bin/test-treeshake.js",
|
|
45
46
|
"test:completeness": "./bin/check.sh",
|
|
46
47
|
"test:typescript": "tsc --noEmit",
|
|
47
48
|
"test:types": "npm run build && tsd --typings ./dist/index.d.ts",
|