decoders 2.2.0-test2 → 2.2.0-test3

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.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/_utils.ts","../src/format.ts"],"sourcesContent":["import type { Annotation } from './annotate';\nimport type { Scalar } from './Decoder';\n\n// Two spaces of indentation\nexport const INDENT = ' ';\n\nexport function lazyval<V>(value: (() => V) | V): V {\n return typeof value === 'function' ? (value as () => V)() : value;\n}\n\n/**\n * Subtract two sets. Why isn't this a standard method on Sets?\n */\nexport function subtract<C extends Scalar>(xs: Set<C>, ys: Set<C>): Set<C> {\n const result = new Set<C>();\n for (const x of xs) {\n if (!ys.has(x)) {\n result.add(x);\n }\n }\n return result;\n}\n\n/**\n * Is value is a valid Date instance, then return that. If not, then return\n * null.\n */\nexport function asDate(value: unknown): Date | null {\n //\n // `x instanceof Date` checks are unreliable across stack frames (that\n // information might get lost by the JS runtime), so we'll have to reside\n // to more runtime inspection checks.\n //\n // Taken from https://stackoverflow.com/a/44198641\n //\n return !!value &&\n Object.prototype.toString.call(value) === '[object Date]' &&\n !isNaN(value as number)\n ? (value as Date)\n : null;\n}\n\nexport function isPojo(value: unknown): value is Record<string, unknown> {\n return (\n value !== null &&\n value !== undefined &&\n typeof value === 'object' &&\n // This still seems to be the only reliable way to determine whether\n // something is a pojo... ¯\\_(ツ)_/¯\n Object.prototype.toString.call(value) === '[object Object]'\n );\n}\n\nexport function isMultiline(s: string): boolean {\n return s.indexOf('\\n') >= 0;\n}\n\nexport function indent(s: string, prefix: string = INDENT): string {\n if (isMultiline(s)) {\n return s\n .split('\\n')\n .map((line) => `${prefix}${line}`)\n .join('\\n');\n } else {\n return `${prefix}${s}`;\n }\n}\n\n/**\n * Walks the annotation tree and emits the annotation's key path within the\n * object tree, and the message as a series of messages (array of strings).\n */\nexport function summarize(\n ann: Annotation,\n keypath: readonly (number | string)[] = [],\n): string[] {\n const result: string[] = [];\n\n if (ann.type === 'array') {\n const items = ann.items;\n let index = 0;\n for (const ann of items) {\n for (const item of summarize(ann, [...keypath, index++])) {\n // Collect to results\n result.push(item);\n }\n }\n } else if (ann.type === 'object') {\n const fields = ann.fields;\n for (const key of Object.keys(fields)) {\n const value = fields[key];\n for (const item of summarize(value, [...keypath, key])) {\n // Collect to results\n result.push(item);\n }\n }\n }\n\n const text = ann.text;\n if (!text) {\n return result;\n }\n\n let prefix: string;\n if (keypath.length === 0) {\n prefix = '';\n } else if (keypath.length === 1) {\n prefix =\n typeof keypath[0] === 'number'\n ? `Value at index ${keypath[0]}: `\n : `Value at key ${JSON.stringify(keypath[0])}: `;\n } else {\n prefix = `Value at keypath ${keypath.map(String).join('.')}: `;\n }\n return [...result, `${prefix}${text}`];\n}\n","import { summarize as _summarize, asDate, INDENT, indent, isMultiline } from './_utils';\nimport type { Annotation, ArrayAnnotation, ObjectAnnotation } from './annotate';\n\nexport type Formatter = (err: Annotation) => string | Error;\n\nfunction serializeString(s: string, width: number = 80): string {\n // Full string\n // Abbreviated to $maxlen i.e. \"Vincent Driess...\" [truncated]\n let ser = JSON.stringify(s);\n if (ser.length <= width) {\n return ser;\n }\n\n // Cut off a bit\n const truncated = `${s.substring(0, width - 15)}...`;\n ser = `${JSON.stringify(truncated)} [truncated]`;\n return ser;\n}\n\nfunction serializeArray(annotation: ArrayAnnotation, prefix: string): string {\n const { items } = annotation;\n if (items.length === 0) {\n return '[]';\n }\n\n const result: string[] = [];\n for (const item of items) {\n const [ser, ann] = serializeAnnotation(item, `${prefix}${INDENT}`);\n result.push(`${prefix}${INDENT}${ser}${','}`);\n if (ann !== undefined) {\n result.push(indent(ann, `${prefix}${INDENT}`));\n }\n }\n return ['[', ...result, `${prefix}]`].join('\\n');\n}\n\nfunction serializeObject(annotation: ObjectAnnotation, prefix: string): string {\n const { fields } = annotation;\n\n const fieldNames = Object.keys(fields);\n if (fieldNames.length === 0) {\n return '{}';\n }\n\n const result: string[] = [];\n for (const key of fieldNames) {\n const valueAnnotation = fields[key];\n const kser = serializeValue(key);\n\n const valPrefix = `${prefix}${INDENT}${' '.repeat(kser.length + 2)}`;\n const [vser, vann] = serializeAnnotation(valueAnnotation, `${prefix}${INDENT}`);\n\n result.push(`${prefix}${INDENT}${kser}: ${vser},`);\n if (vann !== undefined) {\n result.push(indent(vann, valPrefix));\n }\n }\n return ['{', ...result, `${prefix}}`].join('\\n');\n}\n\nexport function serializeValue(value: unknown): string {\n if (typeof value === 'string') {\n return serializeString(value);\n } else if (typeof value === 'number' || typeof value === 'boolean') {\n return value.toString();\n } else if (value === null) {\n return 'null';\n } else if (value === undefined) {\n return 'undefined';\n } else {\n const valueAsDate = asDate(value);\n if (valueAsDate !== null) {\n return `new Date(${JSON.stringify(valueAsDate.toISOString())})`;\n } else if (value instanceof Date) {\n // NOTE: Using `instanceof Date` is unreliable way of checking dates.\n // If this case occurs (and it didn't pass the prior asDate())\n // check, then this must be the case where it's an invalid date.\n return '(Invalid Date)';\n } else {\n return '(unserializable)';\n }\n }\n}\n\nexport function serializeAnnotation(\n ann: Annotation,\n prefix: string = '',\n): [string, string | undefined] {\n // The serialized data (the input object echoed back)\n let serialized;\n if (ann.type === 'array') {\n serialized = serializeArray(ann, prefix);\n } else if (ann.type === 'object') {\n serialized = serializeObject(ann, prefix);\n } else if (ann.type === 'function') {\n serialized = '<function>';\n } else if (ann.type === 'circular-ref') {\n serialized = '<circular ref>';\n } else if (ann.type === 'unknown') {\n serialized = '???';\n } else {\n serialized = serializeValue(ann.value);\n }\n\n const text = ann.text;\n if (text !== undefined) {\n const sep = '^'.repeat(isMultiline(serialized) ? 1 : serialized.length);\n return [serialized, [sep, text].join(isMultiline(text) ? '\\n' : ' ')];\n } else {\n return [serialized, undefined];\n }\n}\n\nexport function formatInline(ann: Annotation): string {\n const [serialized, annotation] = serializeAnnotation(ann);\n if (annotation !== undefined) {\n return `${serialized}\\n${annotation}`;\n } else {\n return serialized;\n }\n}\n\nexport function formatShort(ann: Annotation): string {\n return _summarize(ann, []).join('\\n');\n}\n"],"mappings":";AAIO,IAAM,SAAS;AAEf,SAAS,QAAW,OAAyB;AAClD,SAAO,OAAO,UAAU,aAAc,MAAkB,IAAI;AAC9D;AAKO,SAAS,SAA2B,IAAY,IAAoB;AACzE,QAAM,SAAS,oBAAI,IAAO;AAC1B,aAAW,KAAK,IAAI;AAClB,QAAI,CAAC,GAAG,IAAI,CAAC,GAAG;AACd,aAAO,IAAI,CAAC;AAAA,IACd;AAAA,EACF;AACA,SAAO;AACT;AAMO,SAAS,OAAO,OAA6B;AAQlD,SAAO,CAAC,CAAC,SACP,OAAO,UAAU,SAAS,KAAK,KAAK,MAAM,mBAC1C,CAAC,MAAM,KAAe,IACnB,QACD;AACN;AAEO,SAAS,OAAO,OAAkD;AACvE,SACE,UAAU,QACV,UAAU,UACV,OAAO,UAAU;AAAA;AAAA,EAGjB,OAAO,UAAU,SAAS,KAAK,KAAK,MAAM;AAE9C;AAEO,SAAS,YAAY,GAAoB;AAC9C,SAAO,EAAE,QAAQ,IAAI,KAAK;AAC5B;AAEO,SAAS,OAAO,GAAW,SAAiB,QAAgB;AACjE,MAAI,YAAY,CAAC,GAAG;AAClB,WAAO,EACJ,MAAM,IAAI,EACV,IAAI,CAAC,SAAS,GAAG,MAAM,GAAG,IAAI,EAAE,EAChC,KAAK,IAAI;AAAA,EACd,OAAO;AACL,WAAO,GAAG,MAAM,GAAG,CAAC;AAAA,EACtB;AACF;AAMO,SAAS,UACd,KACA,UAAwC,CAAC,GAC/B;AACV,QAAM,SAAmB,CAAC;AAE1B,MAAI,IAAI,SAAS,SAAS;AACxB,UAAM,QAAQ,IAAI;AAClB,QAAI,QAAQ;AACZ,eAAWA,QAAO,OAAO;AACvB,iBAAW,QAAQ,UAAUA,MAAK,CAAC,GAAG,SAAS,OAAO,CAAC,GAAG;AAExD,eAAO,KAAK,IAAI;AAAA,MAClB;AAAA,IACF;AAAA,EACF,WAAW,IAAI,SAAS,UAAU;AAChC,UAAM,SAAS,IAAI;AACnB,eAAW,OAAO,OAAO,KAAK,MAAM,GAAG;AACrC,YAAM,QAAQ,OAAO,GAAG;AACxB,iBAAW,QAAQ,UAAU,OAAO,CAAC,GAAG,SAAS,GAAG,CAAC,GAAG;AAEtD,eAAO,KAAK,IAAI;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,OAAO,IAAI;AACjB,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AAEA,MAAI;AACJ,MAAI,QAAQ,WAAW,GAAG;AACxB,aAAS;AAAA,EACX,WAAW,QAAQ,WAAW,GAAG;AAC/B,aACE,OAAO,QAAQ,CAAC,MAAM,WAClB,kBAAkB,QAAQ,CAAC,CAAC,OAC5B,gBAAgB,KAAK,UAAU,QAAQ,CAAC,CAAC,CAAC;AAAA,EAClD,OAAO;AACL,aAAS,oBAAoB,QAAQ,IAAI,MAAM,EAAE,KAAK,GAAG,CAAC;AAAA,EAC5D;AACA,SAAO,CAAC,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,EAAE;AACvC;;;AC9GA,SAAS,gBAAgB,GAAW,QAAgB,IAAY;AAG9D,MAAI,MAAM,KAAK,UAAU,CAAC;AAC1B,MAAI,IAAI,UAAU,OAAO;AACvB,WAAO;AAAA,EACT;AAGA,QAAM,YAAY,GAAG,EAAE,UAAU,GAAG,QAAQ,EAAE,CAAC;AAC/C,QAAM,GAAG,KAAK,UAAU,SAAS,CAAC;AAClC,SAAO;AACT;AAEA,SAAS,eAAe,YAA6B,QAAwB;AAC3E,QAAM,EAAE,MAAM,IAAI;AAClB,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,SAAmB,CAAC;AAC1B,aAAW,QAAQ,OAAO;AACxB,UAAM,CAAC,KAAK,GAAG,IAAI,oBAAoB,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE;AACjE,WAAO,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE;AAC5C,QAAI,QAAQ,QAAW;AACrB,aAAO,KAAK,OAAO,KAAK,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;AAAA,IAC/C;AAAA,EACF;AACA,SAAO,CAAC,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,EAAE,KAAK,IAAI;AACjD;AAEA,SAAS,gBAAgB,YAA8B,QAAwB;AAC7E,QAAM,EAAE,OAAO,IAAI;AAEnB,QAAM,aAAa,OAAO,KAAK,MAAM;AACrC,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO;AAAA,EACT;AAEA,QAAM,SAAmB,CAAC;AAC1B,aAAW,OAAO,YAAY;AAC5B,UAAM,kBAAkB,OAAO,GAAG;AAClC,UAAM,OAAO,eAAe,GAAG;AAE/B,UAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,OAAO,KAAK,SAAS,CAAC,CAAC;AAClE,UAAM,CAAC,MAAM,IAAI,IAAI,oBAAoB,iBAAiB,GAAG,MAAM,GAAG,MAAM,EAAE;AAE9E,WAAO,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG;AACjD,QAAI,SAAS,QAAW;AACtB,aAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAAA,IACrC;AAAA,EACF;AACA,SAAO,CAAC,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,EAAE,KAAK,IAAI;AACjD;AAEO,SAAS,eAAe,OAAwB;AACrD,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,gBAAgB,KAAK;AAAA,EAC9B,WAAW,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW;AAClE,WAAO,MAAM,SAAS;AAAA,EACxB,WAAW,UAAU,MAAM;AACzB,WAAO;AAAA,EACT,WAAW,UAAU,QAAW;AAC9B,WAAO;AAAA,EACT,OAAO;AACL,UAAM,cAAc,OAAO,KAAK;AAChC,QAAI,gBAAgB,MAAM;AACxB,aAAO,YAAY,KAAK,UAAU,YAAY,YAAY,CAAC,CAAC;AAAA,IAC9D,WAAW,iBAAiB,MAAM;AAIhC,aAAO;AAAA,IACT,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEO,SAAS,oBACd,KACA,SAAiB,IACa;AAE9B,MAAI;AACJ,MAAI,IAAI,SAAS,SAAS;AACxB,iBAAa,eAAe,KAAK,MAAM;AAAA,EACzC,WAAW,IAAI,SAAS,UAAU;AAChC,iBAAa,gBAAgB,KAAK,MAAM;AAAA,EAC1C,WAAW,IAAI,SAAS,YAAY;AAClC,iBAAa;AAAA,EACf,WAAW,IAAI,SAAS,gBAAgB;AACtC,iBAAa;AAAA,EACf,WAAW,IAAI,SAAS,WAAW;AACjC,iBAAa;AAAA,EACf,OAAO;AACL,iBAAa,eAAe,IAAI,KAAK;AAAA,EACvC;AAEA,QAAM,OAAO,IAAI;AACjB,MAAI,SAAS,QAAW;AACtB,UAAM,MAAM,IAAI,OAAO,YAAY,UAAU,IAAI,IAAI,WAAW,MAAM;AACtE,WAAO,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE,KAAK,YAAY,IAAI,IAAI,OAAO,GAAG,CAAC;AAAA,EACtE,OAAO;AACL,WAAO,CAAC,YAAY,MAAS;AAAA,EAC/B;AACF;AAEO,SAAS,aAAa,KAAyB;AACpD,QAAM,CAAC,YAAY,UAAU,IAAI,oBAAoB,GAAG;AACxD,MAAI,eAAe,QAAW;AAC5B,WAAO,GAAG,UAAU;AAAA,EAAK,UAAU;AAAA,EACrC,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAEO,SAAS,YAAY,KAAyB;AACnD,SAAO,UAAW,KAAK,CAAC,CAAC,EAAE,KAAK,IAAI;AACtC;","names":["ann"]}
package/dist/format.d.mts DELETED
@@ -1,9 +0,0 @@
1
- import { A as Annotation } from './annotate-0PUmWHxH.mjs';
2
-
3
- type Formatter = (err: Annotation) => string | Error;
4
- declare function serializeValue(value: unknown): string;
5
- declare function serializeAnnotation(ann: Annotation, prefix?: string): [string, string | undefined];
6
- declare function formatInline(ann: Annotation): string;
7
- declare function formatShort(ann: Annotation): string;
8
-
9
- export { type Formatter, formatInline, formatShort, serializeAnnotation, serializeValue };
package/dist/format.d.ts DELETED
@@ -1,9 +0,0 @@
1
- import { A as Annotation } from './annotate-0PUmWHxH.js';
2
-
3
- type Formatter = (err: Annotation) => string | Error;
4
- declare function serializeValue(value: unknown): string;
5
- declare function serializeAnnotation(ann: Annotation, prefix?: string): [string, string | undefined];
6
- declare function formatInline(ann: Annotation): string;
7
- declare function formatShort(ann: Annotation): string;
8
-
9
- export { type Formatter, formatInline, formatShort, serializeAnnotation, serializeValue };
package/dist/format.js DELETED
@@ -1,13 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
-
3
-
4
-
5
-
6
- var _chunkRUMDX66Ljs = require('./chunk-RUMDX66L.js');
7
-
8
-
9
-
10
-
11
-
12
- exports.formatInline = _chunkRUMDX66Ljs.formatInline; exports.formatShort = _chunkRUMDX66Ljs.formatShort; exports.serializeAnnotation = _chunkRUMDX66Ljs.serializeAnnotation; exports.serializeValue = _chunkRUMDX66Ljs.serializeValue;
13
- //# sourceMappingURL=format.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":""}
package/dist/format.mjs DELETED
@@ -1,13 +0,0 @@
1
- import {
2
- formatInline,
3
- formatShort,
4
- serializeAnnotation,
5
- serializeValue
6
- } from "./chunk-ZTKFAKRL.mjs";
7
- export {
8
- formatInline,
9
- formatShort,
10
- serializeAnnotation,
11
- serializeValue
12
- };
13
- //# sourceMappingURL=format.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/dist/index.d.mts DELETED
@@ -1,454 +0,0 @@
1
- import { A as Annotation } from './annotate-0PUmWHxH.mjs';
2
- import { Result } from './result.mjs';
3
-
4
- type Scalar = string | number | boolean | symbol | undefined | null;
5
- type DecodeResult<T> = Result<T, Annotation>;
6
- type AcceptanceFn<T, InputT = unknown> = (blob: InputT, ok: (value: T) => DecodeResult<T>, err: (msg: string | Annotation) => DecodeResult<T>) => DecodeResult<T>;
7
- type Decoder<T> = {
8
- /**
9
- * Verifies untrusted input. Either returns a value, or throws a decoding
10
- * error.
11
- */
12
- verify(blob: unknown, formatterFn?: (ann: Annotation) => string | Error): T;
13
- /**
14
- * Verifies untrusted input. Either returns a value, or returns undefined.
15
- */
16
- value(blob: unknown): T | undefined;
17
- /**
18
- * Verifies untrusted input. Always returns a DecodeResult, which is either
19
- * an "ok" value or an "error" annotation.
20
- */
21
- decode(blob: unknown): DecodeResult<T>;
22
- /**
23
- * Build a new decoder from the the current one, with an extra acceptance
24
- * criterium.
25
- */
26
- refine<N extends T>(predicate: (value: T) => value is N, msg: string): Decoder<N>;
27
- refine(predicate: (value: T) => boolean, msg: string): Decoder<T>;
28
- /**
29
- * Build a new decoder from the current one, with an extra rejection
30
- * criterium.
31
- */
32
- reject(rejectFn: (value: T) => string | Annotation | null): Decoder<T>;
33
- /**
34
- * Build a new decoder from the current one, modifying its outputted value.
35
- */
36
- transform<V>(transformFn: (value: T) => V): Decoder<V>;
37
- /**
38
- * Build a new decoder from the current one, with a mutated error message
39
- * in case of a rejection.
40
- */
41
- describe(message: string): Decoder<T>;
42
- /**
43
- * Chain together the current decoder with another acceptance function.
44
- */
45
- then<V>(next: AcceptanceFn<V, T>): Decoder<V>;
46
- peek_UNSTABLE<V>(next: AcceptanceFn<V, [unknown, T]>): Decoder<V>;
47
- };
48
- /**
49
- * Helper type to return the "type" of a Decoder.
50
- *
51
- * You can use it on types:
52
- *
53
- * DecoderType<Decoder<string>> // string
54
- * DecoderType<Decoder<number[]>> // number[]
55
- *
56
- * Or on "values", by using the `typeof` keyword:
57
- *
58
- * DecoderType<typeof string> // string
59
- * DecoderType<typeof truthy> // boolean
60
- *
61
- */
62
- type DecoderType<D extends Decoder<any>> = D extends Decoder<infer T> ? T : never;
63
- /**
64
- * Defines a new `Decoder<T>`, by implementing a custom acceptance function.
65
- * The function receives three arguments:
66
- *
67
- * 1. `blob` - the raw/unknown input (aka your external data)
68
- * 2. `ok` - Call `ok(value)` to accept the input and return ``value``
69
- * 3. `err` - Call `err(message)` to reject the input with error ``message``
70
- *
71
- * The expected return value should be a `DecodeResult<T>`, which can be
72
- * obtained by returning the result of calling the provided `ok` or `err`
73
- * helper functions. Please note that `ok()` and `err()` don't perform side
74
- * effects! You'll need to _return_ those values.
75
- */
76
- declare function define<T>(fn: AcceptanceFn<T>): Decoder<T>;
77
-
78
- type JSONValue = null | string | number | boolean | JSONObject | JSONArray;
79
- type JSONObject = {
80
- [key: string]: JSONValue | undefined;
81
- };
82
- type JSONArray = JSONValue[];
83
- /**
84
- * Accepts objects that contain only valid JSON values.
85
- */
86
- declare const jsonObject: Decoder<JSONObject>;
87
- /**
88
- * Accepts arrays that contain only valid JSON values.
89
- */
90
- declare const jsonArray: Decoder<JSONArray>;
91
- /**
92
- * Accepts any value that's a valid JSON value.
93
- *
94
- * In other words: any value returned by `JSON.parse()` should decode without
95
- * failure.
96
- *
97
- * ```typescript
98
- * type JSONValue =
99
- * | null
100
- * | string
101
- * | number
102
- * | boolean
103
- * | { [string]: JSONValue }
104
- * | JSONValue[]
105
- * ```
106
- */
107
- declare const json: Decoder<JSONValue>;
108
-
109
- /**
110
- * Accepts and returns only the literal `null` value.
111
- */
112
- declare const null_: Decoder<null>;
113
- /**
114
- * Accepts and returns only the literal `undefined` value.
115
- */
116
- declare const undefined_: Decoder<undefined>;
117
- /**
118
- * Accepts whatever the given decoder accepts, or `undefined`.
119
- *
120
- * If a default value is explicitly provided, return that instead in the
121
- * `undefined` case.
122
- */
123
- declare function optional<T>(decoder: Decoder<T>): Decoder<T | undefined>;
124
- declare function optional<T, C extends Scalar>(decoder: Decoder<T>, defaultValue: (() => C) | C): Decoder<NonNullable<T> | C>;
125
- declare function optional<T, V>(decoder: Decoder<T>, defaultValue: (() => V) | V): Decoder<NonNullable<T> | V>;
126
- /**
127
- * Accepts whatever the given decoder accepts, or `null`.
128
- *
129
- * If a default value is explicitly provided, return that instead in the `null`
130
- * case.
131
- */
132
- declare function nullable<T>(decoder: Decoder<T>): Decoder<T | null>;
133
- declare function nullable<T, C extends Scalar>(decoder: Decoder<T>, defaultValue: (() => C) | C): Decoder<NonNullable<T> | C>;
134
- declare function nullable<T, V>(decoder: Decoder<T>, defaultValue: (() => V) | V): Decoder<NonNullable<T> | V>;
135
- /**
136
- * Accepts whatever the given decoder accepts, or `null`, or `undefined`.
137
- *
138
- * If a default value is explicitly provided, return that instead in the
139
- * `null`/`undefined` case.
140
- */
141
- declare function maybe<T>(decoder: Decoder<T>): Decoder<T | null | undefined>;
142
- declare function maybe<T, C extends Scalar>(decoder: Decoder<T>, defaultValue: (() => C) | C): Decoder<NonNullable<T> | C>;
143
- declare function maybe<T, V>(decoder: Decoder<T>, defaultValue: (() => V) | V): Decoder<NonNullable<T> | V>;
144
- /**
145
- * Accepts only the given constant value.
146
- */
147
- declare function constant<C extends Scalar>(value: C): Decoder<C>;
148
- /**
149
- * Accepts anything, completely ignores it, and always returns the provided
150
- * value instead.
151
- *
152
- * This is useful to manually add extra fields to object decoders.
153
- */
154
- declare function always<C extends Scalar>(value: C): Decoder<C>;
155
- declare function always<T>(value: (() => T) | T): Decoder<T>;
156
- /**
157
- * Alias of always.
158
- */
159
- declare const hardcoded: typeof always;
160
- /**
161
- * Accepts anything and returns it unchanged.
162
- *
163
- * Useful for situation in which you don't know or expect a specific type. Of
164
- * course, the downside is that you won't know the type of the value statically
165
- * and you'll have to further refine it yourself.
166
- */
167
- declare const unknown: Decoder<unknown>;
168
- /**
169
- * Alias of unknown.
170
- */
171
- declare const mixed: Decoder<unknown>;
172
-
173
- /**
174
- * Accepts any array, but doesn't validate its items further.
175
- *
176
- * "poja" means "plain old JavaScript array", a play on `pojo()`.
177
- */
178
- declare const poja: Decoder<unknown[]>;
179
- /**
180
- * Accepts arrays of whatever the given decoder accepts.
181
- */
182
- declare function array<T>(decoder: Decoder<T>): Decoder<T[]>;
183
- /**
184
- * Like `array()`, but will reject arrays with 0 elements.
185
- */
186
- declare function nonEmptyArray<T>(decoder: Decoder<T>): Decoder<[T, ...T[]]>;
187
- /**
188
- * Similar to `array()`, but returns the result as an [ES6
189
- * Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set).
190
- */
191
- declare function set<T>(decoder: Decoder<T>): Decoder<Set<T>>;
192
- /**
193
- * Accepts a tuple (an array with exactly _n_ items) of values accepted by the
194
- * _n_ given decoders.
195
- */
196
- declare function tuple<A>(a: Decoder<A>): Decoder<[A]>;
197
- declare function tuple<A, B>(a: Decoder<A>, b: Decoder<B>): Decoder<[A, B]>;
198
- declare function tuple<A, B, C>(a: Decoder<A>, b: Decoder<B>, c: Decoder<C>): Decoder<[A, B, C]>;
199
- declare function tuple<A, B, C, D>(a: Decoder<A>, b: Decoder<B>, c: Decoder<C>, d: Decoder<D>): Decoder<[A, B, C, D]>;
200
- declare function tuple<A, B, C, D, E>(a: Decoder<A>, b: Decoder<B>, c: Decoder<C>, d: Decoder<D>, e: Decoder<E>): Decoder<[A, B, C, D, E]>;
201
- declare function tuple<A, B, C, D, E, F>(a: Decoder<A>, b: Decoder<B>, c: Decoder<C>, d: Decoder<D>, e: Decoder<E>, f: Decoder<F>): Decoder<[A, B, C, D, E, F]>;
202
-
203
- /**
204
- * Accepts and returns booleans.
205
- */
206
- declare const boolean: Decoder<boolean>;
207
- /**
208
- * Accepts anything and will return its "truth" value. Will never reject.
209
- */
210
- declare const truthy: Decoder<boolean>;
211
- /**
212
- * Accepts numbers, but return their boolean representation.
213
- */
214
- declare const numericBoolean: Decoder<boolean>;
215
-
216
- /**
217
- * Accepts and returns `Date` instances.
218
- */
219
- declare const date: Decoder<Date>;
220
- /**
221
- * Accepts [ISO8601](https://en.wikipedia.org/wiki/ISO_8601)-formatted strings,
222
- * returns them as `Date` instances.
223
- *
224
- * This is very useful for working with dates in APIs: serialize them as
225
- * `.toISOString()` when sending, decode them with `iso8601` when receiving.
226
- */
227
- declare const iso8601: Decoder<Date>;
228
-
229
- type RequiredKeys<T extends object> = {
230
- [K in keyof T]: undefined extends T[K] ? never : K;
231
- }[keyof T];
232
- /**
233
- * Transforms an object type, by marking all fields that contain "undefined"
234
- * with a question mark, i.e. allowing implicit-undefineds when
235
- * explicit-undefined are also allowed.
236
- *
237
- * For example, if:
238
- *
239
- * type User = {
240
- * name: string;
241
- * age: number | null | undefined;
242
- * }
243
- *
244
- * Then UndefinedToOptional<User> will become equivalent to:
245
- *
246
- * {
247
- * name: string;
248
- * age?: number | null | undefined;
249
- * ^
250
- * Note the question mark
251
- * }
252
- */
253
- type UndefinedToOptional<T extends object> = Resolve<Pick<Required<T>, RequiredKeys<T>> & Partial<T>>;
254
- type Resolve<T> = T extends (...args: readonly unknown[]) => unknown ? T : {
255
- [K in keyof T]: T[K];
256
- };
257
-
258
- type ObjectDecoderType<T> = UndefinedToOptional<{
259
- [K in keyof T]: T[K] extends Decoder<infer V> ? V : never;
260
- }>;
261
- /**
262
- * Accepts any "plain old JavaScript object", but doesn't validate its keys or
263
- * values further.
264
- */
265
- declare const pojo: Decoder<Record<string, unknown>>;
266
- /**
267
- * Accepts objects with fields matching the given decoders. Extra fields that
268
- * exist on the input object are ignored and will not be returned.
269
- */
270
- declare function object(decodersByKey: Record<any, never>): Decoder<Record<string, never>>;
271
- declare function object<DS extends Record<string, Decoder<any>>>(decodersByKey: DS): Decoder<ObjectDecoderType<DS>>;
272
- /**
273
- * Like `object()`, but will reject inputs that contain extra fields that are
274
- * not specified explicitly.
275
- */
276
- declare function exact(decodersByKey: Record<any, never>): Decoder<Record<string, never>>;
277
- declare function exact<O extends Record<string, Decoder<any>>>(decodersByKey: O): Decoder<{
278
- [K in keyof ObjectDecoderType<O>]: ObjectDecoderType<O>[K];
279
- }>;
280
- /**
281
- * Like `object()`, but will pass through any extra fields on the input object
282
- * unvalidated that will thus be of `unknown` type statically.
283
- */
284
- declare function inexact(decodersByKey: Record<any, never>): Decoder<Record<string, unknown>>;
285
- declare function inexact<O extends Record<string, Decoder<any>>>(decodersByKey: O): Decoder<{
286
- [K in keyof ObjectDecoderType<O>]: ObjectDecoderType<O>[K];
287
- } & Record<string, unknown>>;
288
- /**
289
- * Accepts objects where all values match the given decoder, and returns the
290
- * result as a `Record<string, T>`.
291
- *
292
- * The main difference between `object()` and `dict()` is that you'd typically
293
- * use `object()` if this is a record-like object, where all field names are
294
- * known and the values are heterogeneous. Whereas with `dict()` the keys are
295
- * typically dynamic and the values homogeneous, like in a dictionary,
296
- * a lookup table, or a cache.
297
- */
298
- declare function dict<T>(decoder: Decoder<T>): Decoder<Record<string, T>>;
299
- /**
300
- * Similar to `dict()`, but returns the result as a `Map<string, T>` (an [ES6
301
- * Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map))
302
- * instead.
303
- */
304
- declare function mapping<T>(decoder: Decoder<T>): Decoder<Map<string, T>>;
305
-
306
- type Values<T extends object> = T[keyof T];
307
- type DecoderTypes<T> = T extends readonly Decoder<infer U>[] ? U : never;
308
- /**
309
- * Accepts values accepted by any of the given decoders.
310
- *
311
- * The decoders are tried on the input one by one, in the given order. The
312
- * first one that accepts the input "wins". If all decoders reject the input,
313
- * the input gets rejected.
314
- */
315
- declare function either<T extends readonly Decoder<any>[]>(...decoders: T): Decoder<DecoderTypes<T>>;
316
- /**
317
- * Accepts any value that is strictly-equal (using `===`) to one of the
318
- * specified values.
319
- */
320
- declare function oneOf<C extends Scalar>(constants: readonly C[]): Decoder<C>;
321
- /**
322
- * If you are decoding tagged unions you may want to use the `taggedUnion()`
323
- * decoder instead of the general purpose `either()` decoder to get better
324
- * error messages and better performance.
325
- *
326
- * This decoder is optimized for [tagged
327
- * unions](https://en.wikipedia.org/wiki/Tagged_union), i.e. a union of
328
- * objects where one field is used as the discriminator.
329
- *
330
- * ```ts
331
- * const A = object({ tag: constant('A'), foo: string });
332
- * const B = object({ tag: constant('B'), bar: number });
333
- *
334
- * const AorB = taggedUnion('tag', { A, B });
335
- * // ^^^
336
- * ```
337
- *
338
- * Decoding now works in two steps:
339
- *
340
- * 1. Look at the `'tag'` field in the incoming object (this is the field
341
- * that decides which decoder will be used)
342
- * 2. If the value is `'A'`, then decoder `A` will be used. If it's `'B'`, then
343
- * decoder `B` will be used. Otherwise, this will fail.
344
- *
345
- * This is effectively equivalent to `either(A, B)`, but will provide better
346
- * error messages and is more performant at runtime because it doesn't have to
347
- * try all decoders one by one.
348
- */
349
- declare function taggedUnion<O extends Record<string, Decoder<any>>>(field: string, mapping: O): Decoder<Values<{
350
- [key in keyof O]: DecoderType<O[key]>;
351
- }>>;
352
-
353
- /**
354
- * Accepts and returns strings.
355
- */
356
- declare const string: Decoder<string>;
357
- /**
358
- * Like `string`, but will reject the empty string or strings containing only whitespace.
359
- */
360
- declare const nonEmptyString: Decoder<string>;
361
- /**
362
- * Accepts and returns strings that match the given regular expression.
363
- */
364
- declare function regex(regex: RegExp, msg: string): Decoder<string>;
365
- /**
366
- * Accepts and returns strings that are syntactically valid email addresses.
367
- * (This will not mean that the email address actually exist.)
368
- */
369
- declare const email: Decoder<string>;
370
- /**
371
- * Accepts strings that are valid URLs, returns the value as a URL instance.
372
- */
373
- declare const url: Decoder<URL>;
374
- /**
375
- * Accepts strings that are valid URLs, but only HTTPS ones. Returns the value
376
- * as a URL instance.
377
- */
378
- declare const httpsUrl: Decoder<URL>;
379
- /**
380
- * Accepts strings that are valid
381
- * [UUIDs](https://en.wikipedia.org/wiki/universally_unique_identifier)
382
- * (universally unique identifier).
383
- */
384
- declare const uuid: Decoder<string>;
385
- /**
386
- * Like `uuid`, but only accepts
387
- * [UUIDv1](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_%28date-time_and_MAC_address%29)
388
- * strings.
389
- */
390
- declare const uuidv1: Decoder<string>;
391
- /**
392
- * Like `uuid`, but only accepts
393
- * [UUIDv4](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_%28random%29)
394
- * strings.
395
- */
396
- declare const uuidv4: Decoder<string>;
397
-
398
- interface Klass<T> extends Function {
399
- new (...args: readonly any[]): T;
400
- }
401
- type Instance<K> = K extends Klass<infer T> ? T : never;
402
- /**
403
- * Accepts any value that is an ``instanceof`` the given class.
404
- */
405
- declare function instanceOf<K extends Klass<any>>(klass: K): Decoder<Instance<K>>;
406
- /**
407
- * Lazily evaluate the given decoder. This is useful to build self-referential
408
- * types for recursive data structures.
409
- */
410
- declare function lazy<T>(decoderFn: () => Decoder<T>): Decoder<T>;
411
- /**
412
- * Pre-process the data input before passing it into the decoder. This gives
413
- * you the ability to arbitrarily customize the input on the fly before passing
414
- * it to the decoder. Of course, the input value at that point is still of
415
- * ``unknown`` type, so you will have to deal with that accordingly.
416
- */
417
- declare function prep<T>(mapperFn: (blob: unknown) => unknown, decoder: Decoder<T>): Decoder<T>;
418
- /**
419
- * Rejects all inputs, and always fails with the given error message. May be
420
- * useful for explicitly disallowing keys, or for testing purposes.
421
- */
422
- declare function never(msg: string): Decoder<never>;
423
- /**
424
- * Alias of never().
425
- */
426
- declare const fail: typeof never;
427
-
428
- /**
429
- * Accepts any valid ``number`` value.
430
- *
431
- * This also accepts special values like `NaN` and `Infinity`. Unless you
432
- * want to deliberately accept those, you'll likely want to use the
433
- * `number` decoder instead.
434
- */
435
- declare const anyNumber: Decoder<number>;
436
- /**
437
- * Accepts finite numbers (can be integer or float values). Values `NaN`,
438
- * or positive and negative `Infinity` will get rejected.
439
- */
440
- declare const number: Decoder<number>;
441
- /**
442
- * Accepts only finite whole numbers.
443
- */
444
- declare const integer: Decoder<number>;
445
- /**
446
- * Accepts only non-negative (zero or positive) finite numbers.
447
- */
448
- declare const positiveNumber: Decoder<number>;
449
- /**
450
- * Accepts only non-negative (zero or positive) finite whole numbers.
451
- */
452
- declare const positiveInteger: Decoder<number>;
453
-
454
- export { type DecodeResult, type Decoder, type DecoderType, type JSONArray, type JSONObject, type JSONValue, type Scalar, always, anyNumber, array, boolean, constant, date, define, dict, either, email, exact, fail, hardcoded, httpsUrl, inexact, instanceOf, integer, iso8601, json, jsonArray, jsonObject, lazy, mapping, maybe, mixed, never, nonEmptyArray, nonEmptyString, null_, nullable, number, numericBoolean, object, oneOf, optional, poja, pojo, positiveInteger, positiveNumber, prep, regex, set, string, taggedUnion, truthy, tuple, undefined_, unknown, url, uuid, uuidv1, uuidv4 };