decoders 2.3.0-beta.1 → 2.3.0-beta.3
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 +96 -52
- package/dist/index.d.cts +68 -30
- package/dist/index.d.ts +68 -30
- package/dist/index.js +94 -50
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/lib/utils.ts
|
|
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
|
+
function isNumber(value) {
|
|
3
|
+
return typeof value === "number";
|
|
4
|
+
}
|
|
5
|
+
function isString(value) {
|
|
6
|
+
return typeof value === "string";
|
|
7
|
+
}
|
|
8
|
+
function isBigInt(value) {
|
|
9
|
+
return typeof value === "bigint";
|
|
10
|
+
}
|
|
2
11
|
function isDate(value) {
|
|
3
12
|
return !!value && Object.prototype.toString.call(value) === "[object Date]" && !isNaN(value);
|
|
4
13
|
}
|
|
@@ -380,9 +389,6 @@ function isNonEmpty(arr) {
|
|
|
380
389
|
function nonEmptyArray(decoder) {
|
|
381
390
|
return array(decoder).refine(isNonEmpty, "Must be non-empty array");
|
|
382
391
|
}
|
|
383
|
-
function set(decoder) {
|
|
384
|
-
return array(decoder).transform((items) => new Set(items));
|
|
385
|
-
}
|
|
386
392
|
var ntuple = (n) => poja.refine((arr) => arr.length === n, `Must be a ${n}-tuple`);
|
|
387
393
|
function tuple(...decoders) {
|
|
388
394
|
return ntuple(decoders.length).then((blobs, ok2, err2) => {
|
|
@@ -453,7 +459,7 @@ function object(decoders) {
|
|
|
453
459
|
return pojo.then((plainObj, ok2, err2) => {
|
|
454
460
|
const actualKeys = new Set(Object.keys(plainObj));
|
|
455
461
|
const missingKeys = difference(knownKeys, actualKeys);
|
|
456
|
-
const
|
|
462
|
+
const record2 = {};
|
|
457
463
|
let errors = null;
|
|
458
464
|
for (const key of Object.keys(decoders)) {
|
|
459
465
|
const decoder = decoders[key];
|
|
@@ -462,7 +468,7 @@ function object(decoders) {
|
|
|
462
468
|
if (result.ok) {
|
|
463
469
|
const value = result.value;
|
|
464
470
|
if (value !== void 0) {
|
|
465
|
-
|
|
471
|
+
record2[key] = value;
|
|
466
472
|
}
|
|
467
473
|
missingKeys.delete(key);
|
|
468
474
|
} else {
|
|
@@ -489,7 +495,7 @@ function object(decoders) {
|
|
|
489
495
|
}
|
|
490
496
|
return err2(objAnn);
|
|
491
497
|
}
|
|
492
|
-
return ok2(
|
|
498
|
+
return ok2(record2);
|
|
493
499
|
});
|
|
494
500
|
}
|
|
495
501
|
function exact(decoders) {
|
|
@@ -527,41 +533,6 @@ function inexact(decoders) {
|
|
|
527
533
|
return decoder.decode(plainObj);
|
|
528
534
|
});
|
|
529
535
|
}
|
|
530
|
-
function dict(decoder) {
|
|
531
|
-
return pojo.then((plainObj, ok2, err2) => {
|
|
532
|
-
let rv = {};
|
|
533
|
-
let errors = null;
|
|
534
|
-
for (const key of Object.keys(plainObj)) {
|
|
535
|
-
const value = plainObj[key];
|
|
536
|
-
const result = decoder.decode(value);
|
|
537
|
-
if (result.ok) {
|
|
538
|
-
if (errors === null) {
|
|
539
|
-
rv[key] = result.value;
|
|
540
|
-
}
|
|
541
|
-
} else {
|
|
542
|
-
rv = {};
|
|
543
|
-
if (errors === null) {
|
|
544
|
-
errors = /* @__PURE__ */ new Map();
|
|
545
|
-
}
|
|
546
|
-
errors.set(key, result.error);
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
if (errors !== null) {
|
|
550
|
-
return err2(merge(public_annotateObject(plainObj), errors));
|
|
551
|
-
} else {
|
|
552
|
-
return ok2(rv);
|
|
553
|
-
}
|
|
554
|
-
});
|
|
555
|
-
}
|
|
556
|
-
function mapping(decoder) {
|
|
557
|
-
return dict(decoder).transform(
|
|
558
|
-
(obj) => new Map(
|
|
559
|
-
// This is effectively Object.entries(obj), but in a way that Flow
|
|
560
|
-
// will know the types are okay
|
|
561
|
-
Object.keys(obj).map((key) => [key, obj[key]])
|
|
562
|
-
)
|
|
563
|
-
);
|
|
564
|
-
}
|
|
565
536
|
|
|
566
537
|
// src/unions.ts
|
|
567
538
|
var EITHER_PREFIX = "Either:\n";
|
|
@@ -600,6 +571,17 @@ function oneOf(constants) {
|
|
|
600
571
|
);
|
|
601
572
|
});
|
|
602
573
|
}
|
|
574
|
+
function enum_(enumObj) {
|
|
575
|
+
const values = Object.values(enumObj);
|
|
576
|
+
if (!values.some(isNumber)) {
|
|
577
|
+
return oneOf(values);
|
|
578
|
+
} else {
|
|
579
|
+
const nums = values.filter(isNumber);
|
|
580
|
+
const ignore = new Set(nums.map((val) => enumObj[val]));
|
|
581
|
+
const strings = values.filter(isString).filter((val) => !ignore.has(val));
|
|
582
|
+
return oneOf([...nums, ...strings]);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
603
585
|
function taggedUnion(field, mapping2) {
|
|
604
586
|
const scout = object({
|
|
605
587
|
[field]: prep(String, oneOf(Object.keys(mapping2)))
|
|
@@ -625,9 +607,9 @@ function lazyval(value) {
|
|
|
625
607
|
var null_ = constant(null);
|
|
626
608
|
var undefined_ = constant(void 0);
|
|
627
609
|
var nullish_ = define(
|
|
628
|
-
(blob, ok2, err2) =>
|
|
629
|
-
//
|
|
630
|
-
err2("Must be undefined or null")
|
|
610
|
+
(blob, ok2, err2) => (
|
|
611
|
+
// Equiv to either(undefined_, null_), but combined for better error message
|
|
612
|
+
blob == null ? ok2(blob) : err2("Must be undefined or null")
|
|
631
613
|
)
|
|
632
614
|
);
|
|
633
615
|
function optional(decoder, defaultValue) {
|
|
@@ -665,7 +647,7 @@ var mixed = unknown;
|
|
|
665
647
|
|
|
666
648
|
// src/numbers.ts
|
|
667
649
|
var anyNumber = define(
|
|
668
|
-
(blob, ok2, err2) =>
|
|
650
|
+
(blob, ok2, err2) => isNumber(blob) ? ok2(blob) : err2("Must be number")
|
|
669
651
|
);
|
|
670
652
|
var number = anyNumber.refine(
|
|
671
653
|
(n) => Number.isFinite(n),
|
|
@@ -675,10 +657,16 @@ var integer = number.refine(
|
|
|
675
657
|
(n) => Number.isInteger(n),
|
|
676
658
|
"Number must be an integer"
|
|
677
659
|
);
|
|
678
|
-
var positiveNumber = number.refine(
|
|
679
|
-
|
|
660
|
+
var positiveNumber = number.refine(
|
|
661
|
+
(n) => n >= 0 && !Object.is(n, -0),
|
|
662
|
+
"Number must be positive"
|
|
663
|
+
);
|
|
664
|
+
var positiveInteger = integer.refine(
|
|
665
|
+
(n) => n >= 0 && !Object.is(n, -0),
|
|
666
|
+
"Number must be positive"
|
|
667
|
+
);
|
|
680
668
|
var bigint = define(
|
|
681
|
-
(blob, ok2, err2) =>
|
|
669
|
+
(blob, ok2, err2) => isBigInt(blob) ? ok2(blob) : err2("Must be bigint")
|
|
682
670
|
);
|
|
683
671
|
|
|
684
672
|
// src/booleans.ts
|
|
@@ -688,10 +676,53 @@ var boolean = define((blob, ok2, err2) => {
|
|
|
688
676
|
var truthy = define((blob, ok2, _) => ok2(!!blob));
|
|
689
677
|
var numericBoolean = number.transform((n) => !!n);
|
|
690
678
|
|
|
679
|
+
// src/collections.ts
|
|
680
|
+
function record(fst, snd) {
|
|
681
|
+
const keyDecoder = snd !== void 0 ? fst : void 0;
|
|
682
|
+
const valueDecoder = snd !== void 0 ? snd : fst;
|
|
683
|
+
return pojo.then((input, ok2, err2) => {
|
|
684
|
+
let rv = {};
|
|
685
|
+
const errors = /* @__PURE__ */ new Map();
|
|
686
|
+
for (const [key, value] of Object.entries(input)) {
|
|
687
|
+
const keyResult = _optionalChain([keyDecoder, 'optionalAccess', _2 => _2.decode, 'call', _3 => _3(key)]);
|
|
688
|
+
if (_optionalChain([keyResult, 'optionalAccess', _4 => _4.ok]) === false) {
|
|
689
|
+
return err2(
|
|
690
|
+
public_annotate(
|
|
691
|
+
input,
|
|
692
|
+
`Invalid key ${JSON.stringify(key)}: ${formatShort(keyResult.error)}`
|
|
693
|
+
)
|
|
694
|
+
);
|
|
695
|
+
}
|
|
696
|
+
const k = _nullishCoalesce(_optionalChain([keyResult, 'optionalAccess', _5 => _5.value]), () => ( key));
|
|
697
|
+
const result = valueDecoder.decode(value);
|
|
698
|
+
if (result.ok) {
|
|
699
|
+
if (errors.size === 0) {
|
|
700
|
+
rv[k] = result.value;
|
|
701
|
+
}
|
|
702
|
+
} else {
|
|
703
|
+
errors.set(key, result.error);
|
|
704
|
+
rv = {};
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
if (errors.size > 0) {
|
|
708
|
+
return err2(merge(public_annotateObject(input), errors));
|
|
709
|
+
} else {
|
|
710
|
+
return ok2(rv);
|
|
711
|
+
}
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
var dict = record;
|
|
715
|
+
function set(decoder) {
|
|
716
|
+
return array(decoder).transform((items) => new Set(items));
|
|
717
|
+
}
|
|
718
|
+
function mapping(decoder) {
|
|
719
|
+
return record(decoder).transform((obj) => new Map(Object.entries(obj)));
|
|
720
|
+
}
|
|
721
|
+
|
|
691
722
|
// src/strings.ts
|
|
692
723
|
var url_re = /^([A-Za-z]{3,9}(?:[+][A-Za-z]{3,9})?):\/\/(?:([-;:&=+$,\w]+)@)?(?:([A-Za-z0-9.-]+)(?::([0-9]{2,5}))?)(\/(?:[-+~%/.,\w]*)?(?:\?[-+=&;%@.,/\w]*)?(?:#[.,!/\w]*)?)?$/;
|
|
693
724
|
var string = define(
|
|
694
|
-
(blob, ok2, err2) =>
|
|
725
|
+
(blob, ok2, err2) => isString(blob) ? ok2(blob) : err2("Must be string")
|
|
695
726
|
);
|
|
696
727
|
var nonEmptyString = regex(/\S/, "Must be non-empty string");
|
|
697
728
|
function regex(regex2, msg) {
|
|
@@ -722,6 +753,12 @@ var uuidv4 = (
|
|
|
722
753
|
// https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
|
|
723
754
|
uuid.refine((value) => value[14] === "4", "Must be uuidv4")
|
|
724
755
|
);
|
|
756
|
+
var decimal = regex(/^[0-9]+$/, "Must only contain digits");
|
|
757
|
+
var hexadecimal = regex(
|
|
758
|
+
/^[0-9a-f]+$/i,
|
|
759
|
+
"Must only contain hexadecimal digits"
|
|
760
|
+
);
|
|
761
|
+
var numeric = decimal.transform(Number);
|
|
725
762
|
|
|
726
763
|
// src/dates.ts
|
|
727
764
|
var iso8601_re = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:[.]\d+)?(?:Z|[+-]\d{2}:?\d{2})$/;
|
|
@@ -741,9 +778,10 @@ var iso8601 = (
|
|
|
741
778
|
}
|
|
742
779
|
)
|
|
743
780
|
);
|
|
781
|
+
var datelike = either(date, iso8601).describe("Must be a Date or date string");
|
|
744
782
|
|
|
745
783
|
// src/json.ts
|
|
746
|
-
var jsonObject = lazy(() =>
|
|
784
|
+
var jsonObject = lazy(() => record(json));
|
|
747
785
|
var jsonArray = lazy(() => array(json));
|
|
748
786
|
var json = either(
|
|
749
787
|
null_,
|
|
@@ -813,4 +851,10 @@ var json = either(
|
|
|
813
851
|
|
|
814
852
|
|
|
815
853
|
|
|
816
|
-
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+
|
|
860
|
+
exports.always = always; exports.anyNumber = anyNumber; exports.array = array; exports.bigint = bigint; exports.boolean = boolean; exports.constant = constant; exports.date = date; exports.datelike = datelike; exports.decimal = decimal; exports.define = define; exports.dict = dict; exports.either = either; exports.email = email; exports.enum_ = enum_; exports.err = err; exports.exact = exact; exports.fail = fail; exports.formatInline = formatInline; exports.formatShort = formatShort; exports.hardcoded = hardcoded; exports.hexadecimal = hexadecimal; exports.httpsUrl = httpsUrl; exports.inexact = inexact; exports.instanceOf = instanceOf; exports.integer = integer; exports.iso8601 = iso8601; exports.json = json; exports.jsonArray = jsonArray; exports.jsonObject = jsonObject; exports.lazy = lazy; exports.mapping = mapping; exports.maybe = maybe; exports.mixed = mixed; exports.never = never; exports.nonEmptyArray = nonEmptyArray; exports.nonEmptyString = nonEmptyString; exports.null_ = null_; exports.nullable = nullable; exports.nullish = nullish; exports.number = number; exports.numeric = numeric; exports.numericBoolean = numericBoolean; exports.object = object; exports.ok = ok; exports.oneOf = oneOf; exports.optional = optional; exports.poja = poja; exports.pojo = pojo; exports.positiveInteger = positiveInteger; exports.positiveNumber = positiveNumber; exports.prep = prep; exports.record = record; exports.regex = regex; exports.select = select; exports.set = set; exports.string = string; exports.taggedUnion = taggedUnion; exports.truthy = truthy; exports.tuple = tuple; exports.undefined_ = undefined_; exports.unknown = unknown; exports.url = url; exports.uuid = uuid; exports.uuidv1 = uuidv1; exports.uuidv4 = uuidv4;
|
package/dist/index.d.cts
CHANGED
|
@@ -162,11 +162,6 @@ declare function array<T>(decoder: Decoder<T>): Decoder<T[]>;
|
|
|
162
162
|
* Like `array()`, but will reject arrays with 0 elements.
|
|
163
163
|
*/
|
|
164
164
|
declare function nonEmptyArray<T>(decoder: Decoder<T>): Decoder<[T, ...T[]]>;
|
|
165
|
-
/**
|
|
166
|
-
* Similar to `array()`, but returns the result as an [ES6
|
|
167
|
-
* Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set).
|
|
168
|
-
*/
|
|
169
|
-
declare function set<T>(decoder: Decoder<T>): Decoder<Set<T>>;
|
|
170
165
|
type TupleDecoderType<Ds extends readonly Decoder<unknown>[]> = {
|
|
171
166
|
[K in keyof Ds]: DecoderType<Ds[K]>;
|
|
172
167
|
};
|
|
@@ -205,8 +200,9 @@ declare function nullable<T>(decoder: Decoder<T>): Decoder<T | null>;
|
|
|
205
200
|
declare function nullable<T, C extends Scalar>(decoder: Decoder<T>, defaultValue: (() => C) | C): Decoder<NonNullable<T> | C>;
|
|
206
201
|
declare function nullable<T, V>(decoder: Decoder<T>, defaultValue: (() => V) | V): Decoder<NonNullable<T> | V>;
|
|
207
202
|
/**
|
|
208
|
-
* @deprecated
|
|
209
|
-
*
|
|
203
|
+
* @deprecated Will get removed in a future version.
|
|
204
|
+
*
|
|
205
|
+
* Alias of `nullish()`.
|
|
210
206
|
*/
|
|
211
207
|
declare const maybe: typeof nullish;
|
|
212
208
|
/**
|
|
@@ -236,12 +232,13 @@ declare function always<T>(value: (() => T) | T): Decoder<T>;
|
|
|
236
232
|
*/
|
|
237
233
|
declare function never(msg: string): Decoder<never>;
|
|
238
234
|
/**
|
|
239
|
-
* Alias of never()
|
|
235
|
+
* Alias of `never()`.
|
|
240
236
|
*/
|
|
241
237
|
declare const fail: typeof never;
|
|
242
238
|
/**
|
|
243
|
-
*
|
|
244
|
-
*
|
|
239
|
+
* Alias of `always()`.
|
|
240
|
+
*
|
|
241
|
+
* @deprecated Will get removed in a future version.
|
|
245
242
|
*/
|
|
246
243
|
declare const hardcoded: typeof always;
|
|
247
244
|
/**
|
|
@@ -253,8 +250,9 @@ declare const hardcoded: typeof always;
|
|
|
253
250
|
*/
|
|
254
251
|
declare const unknown: Decoder<unknown>;
|
|
255
252
|
/**
|
|
256
|
-
*
|
|
257
|
-
*
|
|
253
|
+
* Alias of `unknown`.
|
|
254
|
+
*
|
|
255
|
+
* @deprecated Will get removed in a future version.
|
|
258
256
|
*/
|
|
259
257
|
declare const mixed: Decoder<unknown>;
|
|
260
258
|
|
|
@@ -268,9 +266,41 @@ declare const boolean: Decoder<boolean>;
|
|
|
268
266
|
declare const truthy: Decoder<boolean>;
|
|
269
267
|
/**
|
|
270
268
|
* Accepts numbers, but return their boolean representation.
|
|
269
|
+
*
|
|
270
|
+
* @deprecated This decoder will be removed in a future version. You can use
|
|
271
|
+
* `truthy` to get almost the same effect.
|
|
271
272
|
*/
|
|
272
273
|
declare const numericBoolean: Decoder<boolean>;
|
|
273
274
|
|
|
275
|
+
/**
|
|
276
|
+
* Accepts objects where all values match the given decoder, and returns the
|
|
277
|
+
* result as a `Record<string, V>`.
|
|
278
|
+
*/
|
|
279
|
+
declare function record<V>(valueDecoder: Decoder<V>): Decoder<Record<string, V>>;
|
|
280
|
+
/**
|
|
281
|
+
* Accepts objects where all keys and values match the given decoders, and
|
|
282
|
+
* returns the result as a `Record<K, V>`. The given key decoder must return
|
|
283
|
+
* strings.
|
|
284
|
+
*/
|
|
285
|
+
declare function record<K extends string, V>(keyDecoder: Decoder<K>, valueDecoder: Decoder<V>): Decoder<Record<K, V>>;
|
|
286
|
+
/**
|
|
287
|
+
* @deprecated Will get removed in a future version.
|
|
288
|
+
*
|
|
289
|
+
* Alias of `record()`.
|
|
290
|
+
*/
|
|
291
|
+
declare const dict: typeof record;
|
|
292
|
+
/**
|
|
293
|
+
* Similar to `array()`, but returns the result as an [ES6
|
|
294
|
+
* Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set).
|
|
295
|
+
*/
|
|
296
|
+
declare function set<T>(decoder: Decoder<T>): Decoder<Set<T>>;
|
|
297
|
+
/**
|
|
298
|
+
* Similar to `record()`, but returns the result as a `Map<string, T>` (an [ES6
|
|
299
|
+
* Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map))
|
|
300
|
+
* instead.
|
|
301
|
+
*/
|
|
302
|
+
declare function mapping<T>(decoder: Decoder<T>): Decoder<Map<string, T>>;
|
|
303
|
+
|
|
274
304
|
/**
|
|
275
305
|
* Accepts and returns `Date` instances.
|
|
276
306
|
*/
|
|
@@ -283,6 +313,12 @@ declare const date: Decoder<Date>;
|
|
|
283
313
|
* `.toISOString()` when sending, decode them with `iso8601` when receiving.
|
|
284
314
|
*/
|
|
285
315
|
declare const iso8601: Decoder<Date>;
|
|
316
|
+
/**
|
|
317
|
+
* Accepts either a Date, or an ISO date string, returns a Date instance.
|
|
318
|
+
* This is commonly useful to build decoders that can be reused to validate
|
|
319
|
+
* object with Date instances as well as objects coming from JSON payloads.
|
|
320
|
+
*/
|
|
321
|
+
declare const datelike: Decoder<Date>;
|
|
286
322
|
|
|
287
323
|
type JSONValue = null | string | number | boolean | JSONObject | JSONArray;
|
|
288
324
|
type JSONObject = {
|
|
@@ -420,23 +456,6 @@ declare function exact<Ds extends Record<string, Decoder<unknown>>>(decoders: Ds
|
|
|
420
456
|
*/
|
|
421
457
|
declare function inexact(decoders: Record<any, never>): Decoder<Record<string, unknown>>;
|
|
422
458
|
declare function inexact<Ds extends Record<string, Decoder<unknown>>>(decoders: Ds): Decoder<ObjectDecoderType<Ds> & Record<string, unknown>>;
|
|
423
|
-
/**
|
|
424
|
-
* Accepts objects where all values match the given decoder, and returns the
|
|
425
|
-
* result as a `Record<string, T>`.
|
|
426
|
-
*
|
|
427
|
-
* The main difference between `object()` and `dict()` is that you'd typically
|
|
428
|
-
* use `object()` if this is a record-like object, where all field names are
|
|
429
|
-
* known and the values are heterogeneous. Whereas with `dict()` the keys are
|
|
430
|
-
* typically dynamic and the values homogeneous, like in a dictionary,
|
|
431
|
-
* a lookup table, or a cache.
|
|
432
|
-
*/
|
|
433
|
-
declare function dict<T>(decoder: Decoder<T>): Decoder<Record<string, T>>;
|
|
434
|
-
/**
|
|
435
|
-
* Similar to `dict()`, but returns the result as a `Map<string, T>` (an [ES6
|
|
436
|
-
* Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map))
|
|
437
|
-
* instead.
|
|
438
|
-
*/
|
|
439
|
-
declare function mapping<T>(decoder: Decoder<T>): Decoder<Map<string, T>>;
|
|
440
459
|
|
|
441
460
|
/**
|
|
442
461
|
* Accepts and returns strings.
|
|
@@ -482,6 +501,21 @@ declare const uuidv1: Decoder<string>;
|
|
|
482
501
|
* strings.
|
|
483
502
|
*/
|
|
484
503
|
declare const uuidv4: Decoder<string>;
|
|
504
|
+
/**
|
|
505
|
+
* Accepts and returns strings with decimal digits only (base-10).
|
|
506
|
+
* To convert these to numbers, use the `numeric` decoder.
|
|
507
|
+
*/
|
|
508
|
+
declare const decimal: Decoder<string>;
|
|
509
|
+
/**
|
|
510
|
+
* Accepts and returns strings with hexadecimal digits only (base-16).
|
|
511
|
+
*/
|
|
512
|
+
declare const hexadecimal: Decoder<string>;
|
|
513
|
+
/**
|
|
514
|
+
* Accepts valid numerical strings (in base-10) and returns them as a number.
|
|
515
|
+
* To only accept numerical strings and keep them as string values, use the
|
|
516
|
+
* `decimal` decoder.
|
|
517
|
+
*/
|
|
518
|
+
declare const numeric: Decoder<number>;
|
|
485
519
|
|
|
486
520
|
/**
|
|
487
521
|
* Accepts values accepted by any of the given decoders.
|
|
@@ -496,6 +530,10 @@ declare function either<TDecoders extends readonly Decoder<unknown>[], T = Decod
|
|
|
496
530
|
* specified values.
|
|
497
531
|
*/
|
|
498
532
|
declare function oneOf<C extends Scalar>(constants: readonly C[]): Decoder<C>;
|
|
533
|
+
/**
|
|
534
|
+
* Accepts and return an enum value.
|
|
535
|
+
*/
|
|
536
|
+
declare function enum_<TEnum extends Record<string, string | number>>(enumObj: TEnum): Decoder<TEnum[keyof TEnum]>;
|
|
499
537
|
/**
|
|
500
538
|
* If you are decoding tagged unions you may want to use the `taggedUnion()`
|
|
501
539
|
* decoder instead of the general purpose `either()` decoder to get better
|
|
@@ -536,4 +574,4 @@ declare function taggedUnion<O extends Record<string, Decoder<unknown>>, T = Dec
|
|
|
536
574
|
*/
|
|
537
575
|
declare function select<T, D extends Decoder<unknown>>(scout: Decoder<T>, selectFn: (result: T) => D): Decoder<DecoderType<D>>;
|
|
538
576
|
|
|
539
|
-
export { type DecodeResult, type Decoder, type DecoderType, type Err, type Formatter, type JSONArray, type JSONObject, type JSONValue, type Ok, type Result, type Scalar, always, anyNumber, array, bigint, boolean, constant, date, define, dict, either, email, err, exact, fail, formatInline, formatShort, hardcoded, httpsUrl, inexact, instanceOf, integer, iso8601, json, jsonArray, jsonObject, lazy, mapping, maybe, mixed, never, nonEmptyArray, nonEmptyString, null_, nullable, nullish, number, numericBoolean, object, ok, oneOf, optional, poja, pojo, positiveInteger, positiveNumber, prep, regex, select, set, string, taggedUnion, truthy, tuple, undefined_, unknown, url, uuid, uuidv1, uuidv4 };
|
|
577
|
+
export { type DecodeResult, type Decoder, type DecoderType, type Err, type Formatter, type JSONArray, type JSONObject, type JSONValue, type Ok, type Result, type Scalar, always, anyNumber, array, bigint, boolean, constant, date, datelike, decimal, define, dict, either, email, enum_, err, exact, fail, formatInline, formatShort, hardcoded, hexadecimal, httpsUrl, inexact, instanceOf, integer, iso8601, json, jsonArray, jsonObject, lazy, mapping, maybe, mixed, never, nonEmptyArray, nonEmptyString, null_, nullable, nullish, number, numeric, numericBoolean, object, ok, oneOf, optional, poja, pojo, positiveInteger, positiveNumber, prep, record, regex, select, set, string, taggedUnion, truthy, tuple, undefined_, unknown, url, uuid, uuidv1, uuidv4 };
|
package/dist/index.d.ts
CHANGED
|
@@ -162,11 +162,6 @@ declare function array<T>(decoder: Decoder<T>): Decoder<T[]>;
|
|
|
162
162
|
* Like `array()`, but will reject arrays with 0 elements.
|
|
163
163
|
*/
|
|
164
164
|
declare function nonEmptyArray<T>(decoder: Decoder<T>): Decoder<[T, ...T[]]>;
|
|
165
|
-
/**
|
|
166
|
-
* Similar to `array()`, but returns the result as an [ES6
|
|
167
|
-
* Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set).
|
|
168
|
-
*/
|
|
169
|
-
declare function set<T>(decoder: Decoder<T>): Decoder<Set<T>>;
|
|
170
165
|
type TupleDecoderType<Ds extends readonly Decoder<unknown>[]> = {
|
|
171
166
|
[K in keyof Ds]: DecoderType<Ds[K]>;
|
|
172
167
|
};
|
|
@@ -205,8 +200,9 @@ declare function nullable<T>(decoder: Decoder<T>): Decoder<T | null>;
|
|
|
205
200
|
declare function nullable<T, C extends Scalar>(decoder: Decoder<T>, defaultValue: (() => C) | C): Decoder<NonNullable<T> | C>;
|
|
206
201
|
declare function nullable<T, V>(decoder: Decoder<T>, defaultValue: (() => V) | V): Decoder<NonNullable<T> | V>;
|
|
207
202
|
/**
|
|
208
|
-
* @deprecated
|
|
209
|
-
*
|
|
203
|
+
* @deprecated Will get removed in a future version.
|
|
204
|
+
*
|
|
205
|
+
* Alias of `nullish()`.
|
|
210
206
|
*/
|
|
211
207
|
declare const maybe: typeof nullish;
|
|
212
208
|
/**
|
|
@@ -236,12 +232,13 @@ declare function always<T>(value: (() => T) | T): Decoder<T>;
|
|
|
236
232
|
*/
|
|
237
233
|
declare function never(msg: string): Decoder<never>;
|
|
238
234
|
/**
|
|
239
|
-
* Alias of never()
|
|
235
|
+
* Alias of `never()`.
|
|
240
236
|
*/
|
|
241
237
|
declare const fail: typeof never;
|
|
242
238
|
/**
|
|
243
|
-
*
|
|
244
|
-
*
|
|
239
|
+
* Alias of `always()`.
|
|
240
|
+
*
|
|
241
|
+
* @deprecated Will get removed in a future version.
|
|
245
242
|
*/
|
|
246
243
|
declare const hardcoded: typeof always;
|
|
247
244
|
/**
|
|
@@ -253,8 +250,9 @@ declare const hardcoded: typeof always;
|
|
|
253
250
|
*/
|
|
254
251
|
declare const unknown: Decoder<unknown>;
|
|
255
252
|
/**
|
|
256
|
-
*
|
|
257
|
-
*
|
|
253
|
+
* Alias of `unknown`.
|
|
254
|
+
*
|
|
255
|
+
* @deprecated Will get removed in a future version.
|
|
258
256
|
*/
|
|
259
257
|
declare const mixed: Decoder<unknown>;
|
|
260
258
|
|
|
@@ -268,9 +266,41 @@ declare const boolean: Decoder<boolean>;
|
|
|
268
266
|
declare const truthy: Decoder<boolean>;
|
|
269
267
|
/**
|
|
270
268
|
* Accepts numbers, but return their boolean representation.
|
|
269
|
+
*
|
|
270
|
+
* @deprecated This decoder will be removed in a future version. You can use
|
|
271
|
+
* `truthy` to get almost the same effect.
|
|
271
272
|
*/
|
|
272
273
|
declare const numericBoolean: Decoder<boolean>;
|
|
273
274
|
|
|
275
|
+
/**
|
|
276
|
+
* Accepts objects where all values match the given decoder, and returns the
|
|
277
|
+
* result as a `Record<string, V>`.
|
|
278
|
+
*/
|
|
279
|
+
declare function record<V>(valueDecoder: Decoder<V>): Decoder<Record<string, V>>;
|
|
280
|
+
/**
|
|
281
|
+
* Accepts objects where all keys and values match the given decoders, and
|
|
282
|
+
* returns the result as a `Record<K, V>`. The given key decoder must return
|
|
283
|
+
* strings.
|
|
284
|
+
*/
|
|
285
|
+
declare function record<K extends string, V>(keyDecoder: Decoder<K>, valueDecoder: Decoder<V>): Decoder<Record<K, V>>;
|
|
286
|
+
/**
|
|
287
|
+
* @deprecated Will get removed in a future version.
|
|
288
|
+
*
|
|
289
|
+
* Alias of `record()`.
|
|
290
|
+
*/
|
|
291
|
+
declare const dict: typeof record;
|
|
292
|
+
/**
|
|
293
|
+
* Similar to `array()`, but returns the result as an [ES6
|
|
294
|
+
* Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set).
|
|
295
|
+
*/
|
|
296
|
+
declare function set<T>(decoder: Decoder<T>): Decoder<Set<T>>;
|
|
297
|
+
/**
|
|
298
|
+
* Similar to `record()`, but returns the result as a `Map<string, T>` (an [ES6
|
|
299
|
+
* Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map))
|
|
300
|
+
* instead.
|
|
301
|
+
*/
|
|
302
|
+
declare function mapping<T>(decoder: Decoder<T>): Decoder<Map<string, T>>;
|
|
303
|
+
|
|
274
304
|
/**
|
|
275
305
|
* Accepts and returns `Date` instances.
|
|
276
306
|
*/
|
|
@@ -283,6 +313,12 @@ declare const date: Decoder<Date>;
|
|
|
283
313
|
* `.toISOString()` when sending, decode them with `iso8601` when receiving.
|
|
284
314
|
*/
|
|
285
315
|
declare const iso8601: Decoder<Date>;
|
|
316
|
+
/**
|
|
317
|
+
* Accepts either a Date, or an ISO date string, returns a Date instance.
|
|
318
|
+
* This is commonly useful to build decoders that can be reused to validate
|
|
319
|
+
* object with Date instances as well as objects coming from JSON payloads.
|
|
320
|
+
*/
|
|
321
|
+
declare const datelike: Decoder<Date>;
|
|
286
322
|
|
|
287
323
|
type JSONValue = null | string | number | boolean | JSONObject | JSONArray;
|
|
288
324
|
type JSONObject = {
|
|
@@ -420,23 +456,6 @@ declare function exact<Ds extends Record<string, Decoder<unknown>>>(decoders: Ds
|
|
|
420
456
|
*/
|
|
421
457
|
declare function inexact(decoders: Record<any, never>): Decoder<Record<string, unknown>>;
|
|
422
458
|
declare function inexact<Ds extends Record<string, Decoder<unknown>>>(decoders: Ds): Decoder<ObjectDecoderType<Ds> & Record<string, unknown>>;
|
|
423
|
-
/**
|
|
424
|
-
* Accepts objects where all values match the given decoder, and returns the
|
|
425
|
-
* result as a `Record<string, T>`.
|
|
426
|
-
*
|
|
427
|
-
* The main difference between `object()` and `dict()` is that you'd typically
|
|
428
|
-
* use `object()` if this is a record-like object, where all field names are
|
|
429
|
-
* known and the values are heterogeneous. Whereas with `dict()` the keys are
|
|
430
|
-
* typically dynamic and the values homogeneous, like in a dictionary,
|
|
431
|
-
* a lookup table, or a cache.
|
|
432
|
-
*/
|
|
433
|
-
declare function dict<T>(decoder: Decoder<T>): Decoder<Record<string, T>>;
|
|
434
|
-
/**
|
|
435
|
-
* Similar to `dict()`, but returns the result as a `Map<string, T>` (an [ES6
|
|
436
|
-
* Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map))
|
|
437
|
-
* instead.
|
|
438
|
-
*/
|
|
439
|
-
declare function mapping<T>(decoder: Decoder<T>): Decoder<Map<string, T>>;
|
|
440
459
|
|
|
441
460
|
/**
|
|
442
461
|
* Accepts and returns strings.
|
|
@@ -482,6 +501,21 @@ declare const uuidv1: Decoder<string>;
|
|
|
482
501
|
* strings.
|
|
483
502
|
*/
|
|
484
503
|
declare const uuidv4: Decoder<string>;
|
|
504
|
+
/**
|
|
505
|
+
* Accepts and returns strings with decimal digits only (base-10).
|
|
506
|
+
* To convert these to numbers, use the `numeric` decoder.
|
|
507
|
+
*/
|
|
508
|
+
declare const decimal: Decoder<string>;
|
|
509
|
+
/**
|
|
510
|
+
* Accepts and returns strings with hexadecimal digits only (base-16).
|
|
511
|
+
*/
|
|
512
|
+
declare const hexadecimal: Decoder<string>;
|
|
513
|
+
/**
|
|
514
|
+
* Accepts valid numerical strings (in base-10) and returns them as a number.
|
|
515
|
+
* To only accept numerical strings and keep them as string values, use the
|
|
516
|
+
* `decimal` decoder.
|
|
517
|
+
*/
|
|
518
|
+
declare const numeric: Decoder<number>;
|
|
485
519
|
|
|
486
520
|
/**
|
|
487
521
|
* Accepts values accepted by any of the given decoders.
|
|
@@ -496,6 +530,10 @@ declare function either<TDecoders extends readonly Decoder<unknown>[], T = Decod
|
|
|
496
530
|
* specified values.
|
|
497
531
|
*/
|
|
498
532
|
declare function oneOf<C extends Scalar>(constants: readonly C[]): Decoder<C>;
|
|
533
|
+
/**
|
|
534
|
+
* Accepts and return an enum value.
|
|
535
|
+
*/
|
|
536
|
+
declare function enum_<TEnum extends Record<string, string | number>>(enumObj: TEnum): Decoder<TEnum[keyof TEnum]>;
|
|
499
537
|
/**
|
|
500
538
|
* If you are decoding tagged unions you may want to use the `taggedUnion()`
|
|
501
539
|
* decoder instead of the general purpose `either()` decoder to get better
|
|
@@ -536,4 +574,4 @@ declare function taggedUnion<O extends Record<string, Decoder<unknown>>, T = Dec
|
|
|
536
574
|
*/
|
|
537
575
|
declare function select<T, D extends Decoder<unknown>>(scout: Decoder<T>, selectFn: (result: T) => D): Decoder<DecoderType<D>>;
|
|
538
576
|
|
|
539
|
-
export { type DecodeResult, type Decoder, type DecoderType, type Err, type Formatter, type JSONArray, type JSONObject, type JSONValue, type Ok, type Result, type Scalar, always, anyNumber, array, bigint, boolean, constant, date, define, dict, either, email, err, exact, fail, formatInline, formatShort, hardcoded, httpsUrl, inexact, instanceOf, integer, iso8601, json, jsonArray, jsonObject, lazy, mapping, maybe, mixed, never, nonEmptyArray, nonEmptyString, null_, nullable, nullish, number, numericBoolean, object, ok, oneOf, optional, poja, pojo, positiveInteger, positiveNumber, prep, regex, select, set, string, taggedUnion, truthy, tuple, undefined_, unknown, url, uuid, uuidv1, uuidv4 };
|
|
577
|
+
export { type DecodeResult, type Decoder, type DecoderType, type Err, type Formatter, type JSONArray, type JSONObject, type JSONValue, type Ok, type Result, type Scalar, always, anyNumber, array, bigint, boolean, constant, date, datelike, decimal, define, dict, either, email, enum_, err, exact, fail, formatInline, formatShort, hardcoded, hexadecimal, httpsUrl, inexact, instanceOf, integer, iso8601, json, jsonArray, jsonObject, lazy, mapping, maybe, mixed, never, nonEmptyArray, nonEmptyString, null_, nullable, nullish, number, numeric, numericBoolean, object, ok, oneOf, optional, poja, pojo, positiveInteger, positiveNumber, prep, record, regex, select, set, string, taggedUnion, truthy, tuple, undefined_, unknown, url, uuid, uuidv1, uuidv4 };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
// src/lib/utils.ts
|
|
2
|
+
function isNumber(value) {
|
|
3
|
+
return typeof value === "number";
|
|
4
|
+
}
|
|
5
|
+
function isString(value) {
|
|
6
|
+
return typeof value === "string";
|
|
7
|
+
}
|
|
8
|
+
function isBigInt(value) {
|
|
9
|
+
return typeof value === "bigint";
|
|
10
|
+
}
|
|
2
11
|
function isDate(value) {
|
|
3
12
|
return !!value && Object.prototype.toString.call(value) === "[object Date]" && !isNaN(value);
|
|
4
13
|
}
|
|
@@ -380,9 +389,6 @@ function isNonEmpty(arr) {
|
|
|
380
389
|
function nonEmptyArray(decoder) {
|
|
381
390
|
return array(decoder).refine(isNonEmpty, "Must be non-empty array");
|
|
382
391
|
}
|
|
383
|
-
function set(decoder) {
|
|
384
|
-
return array(decoder).transform((items) => new Set(items));
|
|
385
|
-
}
|
|
386
392
|
var ntuple = (n) => poja.refine((arr) => arr.length === n, `Must be a ${n}-tuple`);
|
|
387
393
|
function tuple(...decoders) {
|
|
388
394
|
return ntuple(decoders.length).then((blobs, ok2, err2) => {
|
|
@@ -453,7 +459,7 @@ function object(decoders) {
|
|
|
453
459
|
return pojo.then((plainObj, ok2, err2) => {
|
|
454
460
|
const actualKeys = new Set(Object.keys(plainObj));
|
|
455
461
|
const missingKeys = difference(knownKeys, actualKeys);
|
|
456
|
-
const
|
|
462
|
+
const record2 = {};
|
|
457
463
|
let errors = null;
|
|
458
464
|
for (const key of Object.keys(decoders)) {
|
|
459
465
|
const decoder = decoders[key];
|
|
@@ -462,7 +468,7 @@ function object(decoders) {
|
|
|
462
468
|
if (result.ok) {
|
|
463
469
|
const value = result.value;
|
|
464
470
|
if (value !== void 0) {
|
|
465
|
-
|
|
471
|
+
record2[key] = value;
|
|
466
472
|
}
|
|
467
473
|
missingKeys.delete(key);
|
|
468
474
|
} else {
|
|
@@ -489,7 +495,7 @@ function object(decoders) {
|
|
|
489
495
|
}
|
|
490
496
|
return err2(objAnn);
|
|
491
497
|
}
|
|
492
|
-
return ok2(
|
|
498
|
+
return ok2(record2);
|
|
493
499
|
});
|
|
494
500
|
}
|
|
495
501
|
function exact(decoders) {
|
|
@@ -527,41 +533,6 @@ function inexact(decoders) {
|
|
|
527
533
|
return decoder.decode(plainObj);
|
|
528
534
|
});
|
|
529
535
|
}
|
|
530
|
-
function dict(decoder) {
|
|
531
|
-
return pojo.then((plainObj, ok2, err2) => {
|
|
532
|
-
let rv = {};
|
|
533
|
-
let errors = null;
|
|
534
|
-
for (const key of Object.keys(plainObj)) {
|
|
535
|
-
const value = plainObj[key];
|
|
536
|
-
const result = decoder.decode(value);
|
|
537
|
-
if (result.ok) {
|
|
538
|
-
if (errors === null) {
|
|
539
|
-
rv[key] = result.value;
|
|
540
|
-
}
|
|
541
|
-
} else {
|
|
542
|
-
rv = {};
|
|
543
|
-
if (errors === null) {
|
|
544
|
-
errors = /* @__PURE__ */ new Map();
|
|
545
|
-
}
|
|
546
|
-
errors.set(key, result.error);
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
if (errors !== null) {
|
|
550
|
-
return err2(merge(public_annotateObject(plainObj), errors));
|
|
551
|
-
} else {
|
|
552
|
-
return ok2(rv);
|
|
553
|
-
}
|
|
554
|
-
});
|
|
555
|
-
}
|
|
556
|
-
function mapping(decoder) {
|
|
557
|
-
return dict(decoder).transform(
|
|
558
|
-
(obj) => new Map(
|
|
559
|
-
// This is effectively Object.entries(obj), but in a way that Flow
|
|
560
|
-
// will know the types are okay
|
|
561
|
-
Object.keys(obj).map((key) => [key, obj[key]])
|
|
562
|
-
)
|
|
563
|
-
);
|
|
564
|
-
}
|
|
565
536
|
|
|
566
537
|
// src/unions.ts
|
|
567
538
|
var EITHER_PREFIX = "Either:\n";
|
|
@@ -600,6 +571,17 @@ function oneOf(constants) {
|
|
|
600
571
|
);
|
|
601
572
|
});
|
|
602
573
|
}
|
|
574
|
+
function enum_(enumObj) {
|
|
575
|
+
const values = Object.values(enumObj);
|
|
576
|
+
if (!values.some(isNumber)) {
|
|
577
|
+
return oneOf(values);
|
|
578
|
+
} else {
|
|
579
|
+
const nums = values.filter(isNumber);
|
|
580
|
+
const ignore = new Set(nums.map((val) => enumObj[val]));
|
|
581
|
+
const strings = values.filter(isString).filter((val) => !ignore.has(val));
|
|
582
|
+
return oneOf([...nums, ...strings]);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
603
585
|
function taggedUnion(field, mapping2) {
|
|
604
586
|
const scout = object({
|
|
605
587
|
[field]: prep(String, oneOf(Object.keys(mapping2)))
|
|
@@ -625,9 +607,9 @@ function lazyval(value) {
|
|
|
625
607
|
var null_ = constant(null);
|
|
626
608
|
var undefined_ = constant(void 0);
|
|
627
609
|
var nullish_ = define(
|
|
628
|
-
(blob, ok2, err2) =>
|
|
629
|
-
//
|
|
630
|
-
err2("Must be undefined or null")
|
|
610
|
+
(blob, ok2, err2) => (
|
|
611
|
+
// Equiv to either(undefined_, null_), but combined for better error message
|
|
612
|
+
blob == null ? ok2(blob) : err2("Must be undefined or null")
|
|
631
613
|
)
|
|
632
614
|
);
|
|
633
615
|
function optional(decoder, defaultValue) {
|
|
@@ -665,7 +647,7 @@ var mixed = unknown;
|
|
|
665
647
|
|
|
666
648
|
// src/numbers.ts
|
|
667
649
|
var anyNumber = define(
|
|
668
|
-
(blob, ok2, err2) =>
|
|
650
|
+
(blob, ok2, err2) => isNumber(blob) ? ok2(blob) : err2("Must be number")
|
|
669
651
|
);
|
|
670
652
|
var number = anyNumber.refine(
|
|
671
653
|
(n) => Number.isFinite(n),
|
|
@@ -675,10 +657,16 @@ var integer = number.refine(
|
|
|
675
657
|
(n) => Number.isInteger(n),
|
|
676
658
|
"Number must be an integer"
|
|
677
659
|
);
|
|
678
|
-
var positiveNumber = number.refine(
|
|
679
|
-
|
|
660
|
+
var positiveNumber = number.refine(
|
|
661
|
+
(n) => n >= 0 && !Object.is(n, -0),
|
|
662
|
+
"Number must be positive"
|
|
663
|
+
);
|
|
664
|
+
var positiveInteger = integer.refine(
|
|
665
|
+
(n) => n >= 0 && !Object.is(n, -0),
|
|
666
|
+
"Number must be positive"
|
|
667
|
+
);
|
|
680
668
|
var bigint = define(
|
|
681
|
-
(blob, ok2, err2) =>
|
|
669
|
+
(blob, ok2, err2) => isBigInt(blob) ? ok2(blob) : err2("Must be bigint")
|
|
682
670
|
);
|
|
683
671
|
|
|
684
672
|
// src/booleans.ts
|
|
@@ -688,10 +676,53 @@ var boolean = define((blob, ok2, err2) => {
|
|
|
688
676
|
var truthy = define((blob, ok2, _) => ok2(!!blob));
|
|
689
677
|
var numericBoolean = number.transform((n) => !!n);
|
|
690
678
|
|
|
679
|
+
// src/collections.ts
|
|
680
|
+
function record(fst, snd) {
|
|
681
|
+
const keyDecoder = snd !== void 0 ? fst : void 0;
|
|
682
|
+
const valueDecoder = snd !== void 0 ? snd : fst;
|
|
683
|
+
return pojo.then((input, ok2, err2) => {
|
|
684
|
+
let rv = {};
|
|
685
|
+
const errors = /* @__PURE__ */ new Map();
|
|
686
|
+
for (const [key, value] of Object.entries(input)) {
|
|
687
|
+
const keyResult = keyDecoder?.decode(key);
|
|
688
|
+
if (keyResult?.ok === false) {
|
|
689
|
+
return err2(
|
|
690
|
+
public_annotate(
|
|
691
|
+
input,
|
|
692
|
+
`Invalid key ${JSON.stringify(key)}: ${formatShort(keyResult.error)}`
|
|
693
|
+
)
|
|
694
|
+
);
|
|
695
|
+
}
|
|
696
|
+
const k = keyResult?.value ?? key;
|
|
697
|
+
const result = valueDecoder.decode(value);
|
|
698
|
+
if (result.ok) {
|
|
699
|
+
if (errors.size === 0) {
|
|
700
|
+
rv[k] = result.value;
|
|
701
|
+
}
|
|
702
|
+
} else {
|
|
703
|
+
errors.set(key, result.error);
|
|
704
|
+
rv = {};
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
if (errors.size > 0) {
|
|
708
|
+
return err2(merge(public_annotateObject(input), errors));
|
|
709
|
+
} else {
|
|
710
|
+
return ok2(rv);
|
|
711
|
+
}
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
var dict = record;
|
|
715
|
+
function set(decoder) {
|
|
716
|
+
return array(decoder).transform((items) => new Set(items));
|
|
717
|
+
}
|
|
718
|
+
function mapping(decoder) {
|
|
719
|
+
return record(decoder).transform((obj) => new Map(Object.entries(obj)));
|
|
720
|
+
}
|
|
721
|
+
|
|
691
722
|
// src/strings.ts
|
|
692
723
|
var url_re = /^([A-Za-z]{3,9}(?:[+][A-Za-z]{3,9})?):\/\/(?:([-;:&=+$,\w]+)@)?(?:([A-Za-z0-9.-]+)(?::([0-9]{2,5}))?)(\/(?:[-+~%/.,\w]*)?(?:\?[-+=&;%@.,/\w]*)?(?:#[.,!/\w]*)?)?$/;
|
|
693
724
|
var string = define(
|
|
694
|
-
(blob, ok2, err2) =>
|
|
725
|
+
(blob, ok2, err2) => isString(blob) ? ok2(blob) : err2("Must be string")
|
|
695
726
|
);
|
|
696
727
|
var nonEmptyString = regex(/\S/, "Must be non-empty string");
|
|
697
728
|
function regex(regex2, msg) {
|
|
@@ -722,6 +753,12 @@ var uuidv4 = (
|
|
|
722
753
|
// https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
|
|
723
754
|
uuid.refine((value) => value[14] === "4", "Must be uuidv4")
|
|
724
755
|
);
|
|
756
|
+
var decimal = regex(/^[0-9]+$/, "Must only contain digits");
|
|
757
|
+
var hexadecimal = regex(
|
|
758
|
+
/^[0-9a-f]+$/i,
|
|
759
|
+
"Must only contain hexadecimal digits"
|
|
760
|
+
);
|
|
761
|
+
var numeric = decimal.transform(Number);
|
|
725
762
|
|
|
726
763
|
// src/dates.ts
|
|
727
764
|
var iso8601_re = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:[.]\d+)?(?:Z|[+-]\d{2}:?\d{2})$/;
|
|
@@ -741,9 +778,10 @@ var iso8601 = (
|
|
|
741
778
|
}
|
|
742
779
|
)
|
|
743
780
|
);
|
|
781
|
+
var datelike = either(date, iso8601).describe("Must be a Date or date string");
|
|
744
782
|
|
|
745
783
|
// src/json.ts
|
|
746
|
-
var jsonObject = lazy(() =>
|
|
784
|
+
var jsonObject = lazy(() => record(json));
|
|
747
785
|
var jsonArray = lazy(() => array(json));
|
|
748
786
|
var json = either(
|
|
749
787
|
null_,
|
|
@@ -761,16 +799,20 @@ export {
|
|
|
761
799
|
boolean,
|
|
762
800
|
constant,
|
|
763
801
|
date,
|
|
802
|
+
datelike,
|
|
803
|
+
decimal,
|
|
764
804
|
define,
|
|
765
805
|
dict,
|
|
766
806
|
either,
|
|
767
807
|
email,
|
|
808
|
+
enum_,
|
|
768
809
|
err,
|
|
769
810
|
exact,
|
|
770
811
|
fail,
|
|
771
812
|
formatInline,
|
|
772
813
|
formatShort,
|
|
773
814
|
hardcoded,
|
|
815
|
+
hexadecimal,
|
|
774
816
|
httpsUrl,
|
|
775
817
|
inexact,
|
|
776
818
|
instanceOf,
|
|
@@ -790,6 +832,7 @@ export {
|
|
|
790
832
|
nullable,
|
|
791
833
|
nullish,
|
|
792
834
|
number,
|
|
835
|
+
numeric,
|
|
793
836
|
numericBoolean,
|
|
794
837
|
object,
|
|
795
838
|
ok,
|
|
@@ -800,6 +843,7 @@ export {
|
|
|
800
843
|
positiveInteger,
|
|
801
844
|
positiveNumber,
|
|
802
845
|
prep,
|
|
846
|
+
record,
|
|
803
847
|
regex,
|
|
804
848
|
select,
|
|
805
849
|
set,
|