decoders 2.2.0-test2 → 2.2.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/README.md +23 -11
- package/{index.js → dist/index.cjs} +194 -30
- package/dist/index.cjs.map +1 -0
- package/{index.d.ts → dist/index.d.cts} +63 -5
- package/dist/index.d.ts +63 -5
- package/dist/index.js +246 -82
- package/dist/index.js.map +1 -1
- package/package.json +23 -107
- package/annotate-0PUmWHxH.d.ts +0 -33
- package/chunk-BPSZE2VX.js +0 -13
- package/chunk-RUMDX66L.js +0 -179
- package/dist/annotate-0PUmWHxH.d.mts +0 -33
- package/dist/annotate-0PUmWHxH.d.ts +0 -33
- package/dist/chunk-BPSZE2VX.js +0 -13
- package/dist/chunk-BPSZE2VX.js.map +0 -1
- package/dist/chunk-HBFFQIIN.mjs +0 -13
- package/dist/chunk-HBFFQIIN.mjs.map +0 -1
- package/dist/chunk-RUMDX66L.js +0 -179
- package/dist/chunk-RUMDX66L.js.map +0 -1
- package/dist/chunk-ZTKFAKRL.mjs +0 -179
- package/dist/chunk-ZTKFAKRL.mjs.map +0 -1
- package/dist/format.d.mts +0 -9
- package/dist/format.d.ts +0 -9
- package/dist/format.js +0 -13
- package/dist/format.js.map +0 -1
- package/dist/format.mjs +0 -13
- package/dist/format.mjs.map +0 -1
- package/dist/index.d.mts +0 -454
- package/dist/index.mjs +0 -659
- package/dist/index.mjs.map +0 -1
- package/dist/result.d.mts +0 -26
- package/dist/result.d.ts +0 -26
- package/dist/result.js +0 -9
- package/dist/result.js.map +0 -1
- package/dist/result.mjs +0 -9
- package/dist/result.mjs.map +0 -1
- package/format.d.ts +0 -9
- package/format.js +0 -13
- package/result.d.ts +0 -26
- package/result.js +0 -9
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
Elegant and battle-tested validation library for type-safe input data for
|
|
8
8
|
[TypeScript](https://www.typescriptlang.org/).
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Introduction
|
|
11
11
|
|
|
12
12
|
Data entering your application from the outside world should not be trusted without
|
|
13
13
|
validation and often is of the `any` type, effectively disabling your type checker around
|
|
@@ -16,14 +16,12 @@ program's boundaries. This has two benefits: (1) your inputs are getting validat
|
|
|
16
16
|
(2) you can now statically know for sure the shape of the incoming data. **Decoders help
|
|
17
17
|
solve both of these problems at once.**
|
|
18
18
|
|
|
19
|
-
##
|
|
19
|
+
## Basic example
|
|
20
20
|
|
|
21
21
|
```typescript
|
|
22
22
|
import { array, iso8601, number, object, optional, string } from 'decoders';
|
|
23
23
|
|
|
24
|
-
//
|
|
25
24
|
// Incoming data at runtime
|
|
26
|
-
//
|
|
27
25
|
const externalData = {
|
|
28
26
|
id: 123,
|
|
29
27
|
name: 'Alison Roberts',
|
|
@@ -31,9 +29,7 @@ const externalData = {
|
|
|
31
29
|
tags: ['foo', 'bar'],
|
|
32
30
|
};
|
|
33
31
|
|
|
34
|
-
//
|
|
35
32
|
// Write the decoder (= what you expect the data to look like)
|
|
36
|
-
//
|
|
37
33
|
const userDecoder = object({
|
|
38
34
|
id: number,
|
|
39
35
|
name: string,
|
|
@@ -41,20 +37,36 @@ const userDecoder = object({
|
|
|
41
37
|
tags: array(string),
|
|
42
38
|
});
|
|
43
39
|
|
|
44
|
-
//
|
|
45
40
|
// Call .verify() on the incoming data
|
|
46
|
-
//
|
|
47
41
|
const user = userDecoder.verify(externalData);
|
|
48
42
|
// ^^^^
|
|
49
|
-
// TypeScript
|
|
50
|
-
//
|
|
43
|
+
// TypeScript automatically infers this type as:
|
|
51
44
|
// {
|
|
52
45
|
// id: number;
|
|
53
46
|
// name: string;
|
|
54
47
|
// createdAt?: Date;
|
|
55
48
|
// tags: string[];
|
|
56
49
|
// }
|
|
57
|
-
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm install decoders
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Requirements
|
|
59
|
+
|
|
60
|
+
You must set `strict: true` in your `tsconfig.json` in order for type inference to work
|
|
61
|
+
correctly!
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
// tsconfig.json
|
|
65
|
+
{
|
|
66
|
+
"compilerOptions": {
|
|
67
|
+
"strict": true
|
|
68
|
+
}
|
|
69
|
+
}
|
|
58
70
|
```
|
|
59
71
|
|
|
60
72
|
## Documentation
|
|
@@ -1,16 +1,68 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/_utils.ts
|
|
2
|
+
var INDENT = " ";
|
|
3
|
+
function lazyval(value) {
|
|
4
|
+
return typeof value === "function" ? value() : value;
|
|
5
|
+
}
|
|
6
|
+
function subtract(xs, ys) {
|
|
7
|
+
const result = /* @__PURE__ */ new Set();
|
|
8
|
+
for (const x of xs) {
|
|
9
|
+
if (!ys.has(x)) {
|
|
10
|
+
result.add(x);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return result;
|
|
14
|
+
}
|
|
15
|
+
function asDate(value) {
|
|
16
|
+
return !!value && Object.prototype.toString.call(value) === "[object Date]" && !isNaN(value) ? value : null;
|
|
17
|
+
}
|
|
18
|
+
function isPojo(value) {
|
|
19
|
+
return value !== null && value !== void 0 && typeof value === "object" && // This still seems to be the only reliable way to determine whether
|
|
20
|
+
// something is a pojo... ¯\_(ツ)_/¯
|
|
21
|
+
Object.prototype.toString.call(value) === "[object Object]";
|
|
22
|
+
}
|
|
23
|
+
function isMultiline(s) {
|
|
24
|
+
return s.indexOf("\n") >= 0;
|
|
25
|
+
}
|
|
26
|
+
function indent(s, prefix = INDENT) {
|
|
27
|
+
if (isMultiline(s)) {
|
|
28
|
+
return s.split("\n").map((line) => `${prefix}${line}`).join("\n");
|
|
29
|
+
} else {
|
|
30
|
+
return `${prefix}${s}`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function summarize(ann, keypath = []) {
|
|
34
|
+
const result = [];
|
|
35
|
+
if (ann.type === "array") {
|
|
36
|
+
const items = ann.items;
|
|
37
|
+
let index = 0;
|
|
38
|
+
for (const ann2 of items) {
|
|
39
|
+
for (const item of summarize(ann2, [...keypath, index++])) {
|
|
40
|
+
result.push(item);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
} else if (ann.type === "object") {
|
|
44
|
+
const fields = ann.fields;
|
|
45
|
+
for (const key of Object.keys(fields)) {
|
|
46
|
+
const value = fields[key];
|
|
47
|
+
for (const item of summarize(value, [...keypath, key])) {
|
|
48
|
+
result.push(item);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const text = ann.text;
|
|
53
|
+
if (!text) {
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
let prefix;
|
|
57
|
+
if (keypath.length === 0) {
|
|
58
|
+
prefix = "";
|
|
59
|
+
} else if (keypath.length === 1) {
|
|
60
|
+
prefix = typeof keypath[0] === "number" ? `Value at index ${keypath[0]}: ` : `Value at key ${JSON.stringify(keypath[0])}: `;
|
|
61
|
+
} else {
|
|
62
|
+
prefix = `Value at keypath ${keypath.map(String).join(".")}: `;
|
|
63
|
+
}
|
|
64
|
+
return [...result, `${prefix}${text}`];
|
|
65
|
+
}
|
|
14
66
|
|
|
15
67
|
// src/annotate.ts
|
|
16
68
|
var _register = /* @__PURE__ */ new WeakSet();
|
|
@@ -97,7 +149,7 @@ function annotate(value, text, seen) {
|
|
|
97
149
|
return annotateArray(value, text, seen);
|
|
98
150
|
}
|
|
99
151
|
}
|
|
100
|
-
if (
|
|
152
|
+
if (isPojo(value)) {
|
|
101
153
|
if (seen.has(value)) {
|
|
102
154
|
return circularRef(text);
|
|
103
155
|
} else {
|
|
@@ -116,14 +168,122 @@ function public_annotateObject(obj, text) {
|
|
|
116
168
|
return annotateObject(obj, text, /* @__PURE__ */ new WeakSet());
|
|
117
169
|
}
|
|
118
170
|
|
|
171
|
+
// src/format.ts
|
|
172
|
+
function serializeString(s, width = 80) {
|
|
173
|
+
let ser = JSON.stringify(s);
|
|
174
|
+
if (ser.length <= width) {
|
|
175
|
+
return ser;
|
|
176
|
+
}
|
|
177
|
+
const truncated = `${s.substring(0, width - 15)}...`;
|
|
178
|
+
ser = `${JSON.stringify(truncated)} [truncated]`;
|
|
179
|
+
return ser;
|
|
180
|
+
}
|
|
181
|
+
function serializeArray(annotation, prefix) {
|
|
182
|
+
const { items } = annotation;
|
|
183
|
+
if (items.length === 0) {
|
|
184
|
+
return "[]";
|
|
185
|
+
}
|
|
186
|
+
const result = [];
|
|
187
|
+
for (const item of items) {
|
|
188
|
+
const [ser, ann] = serializeAnnotation(item, `${prefix}${INDENT}`);
|
|
189
|
+
result.push(`${prefix}${INDENT}${ser}${","}`);
|
|
190
|
+
if (ann !== void 0) {
|
|
191
|
+
result.push(indent(ann, `${prefix}${INDENT}`));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return ["[", ...result, `${prefix}]`].join("\n");
|
|
195
|
+
}
|
|
196
|
+
function serializeObject(annotation, prefix) {
|
|
197
|
+
const { fields } = annotation;
|
|
198
|
+
const fieldNames = Object.keys(fields);
|
|
199
|
+
if (fieldNames.length === 0) {
|
|
200
|
+
return "{}";
|
|
201
|
+
}
|
|
202
|
+
const result = [];
|
|
203
|
+
for (const key of fieldNames) {
|
|
204
|
+
const valueAnnotation = fields[key];
|
|
205
|
+
const kser = serializeValue(key);
|
|
206
|
+
const valPrefix = `${prefix}${INDENT}${" ".repeat(kser.length + 2)}`;
|
|
207
|
+
const [vser, vann] = serializeAnnotation(valueAnnotation, `${prefix}${INDENT}`);
|
|
208
|
+
result.push(`${prefix}${INDENT}${kser}: ${vser},`);
|
|
209
|
+
if (vann !== void 0) {
|
|
210
|
+
result.push(indent(vann, valPrefix));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return ["{", ...result, `${prefix}}`].join("\n");
|
|
214
|
+
}
|
|
215
|
+
function serializeValue(value) {
|
|
216
|
+
if (typeof value === "string") {
|
|
217
|
+
return serializeString(value);
|
|
218
|
+
} else if (typeof value === "number" || typeof value === "boolean") {
|
|
219
|
+
return value.toString();
|
|
220
|
+
} else if (value === null) {
|
|
221
|
+
return "null";
|
|
222
|
+
} else if (value === void 0) {
|
|
223
|
+
return "undefined";
|
|
224
|
+
} else {
|
|
225
|
+
const valueAsDate = asDate(value);
|
|
226
|
+
if (valueAsDate !== null) {
|
|
227
|
+
return `new Date(${JSON.stringify(valueAsDate.toISOString())})`;
|
|
228
|
+
} else if (value instanceof Date) {
|
|
229
|
+
return "(Invalid Date)";
|
|
230
|
+
} else {
|
|
231
|
+
return "(unserializable)";
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
function serializeAnnotation(ann, prefix = "") {
|
|
236
|
+
let serialized;
|
|
237
|
+
if (ann.type === "array") {
|
|
238
|
+
serialized = serializeArray(ann, prefix);
|
|
239
|
+
} else if (ann.type === "object") {
|
|
240
|
+
serialized = serializeObject(ann, prefix);
|
|
241
|
+
} else if (ann.type === "function") {
|
|
242
|
+
serialized = "<function>";
|
|
243
|
+
} else if (ann.type === "circular-ref") {
|
|
244
|
+
serialized = "<circular ref>";
|
|
245
|
+
} else if (ann.type === "unknown") {
|
|
246
|
+
serialized = "???";
|
|
247
|
+
} else {
|
|
248
|
+
serialized = serializeValue(ann.value);
|
|
249
|
+
}
|
|
250
|
+
const text = ann.text;
|
|
251
|
+
if (text !== void 0) {
|
|
252
|
+
const sep = "^".repeat(isMultiline(serialized) ? 1 : serialized.length);
|
|
253
|
+
return [serialized, [sep, text].join(isMultiline(text) ? "\n" : " ")];
|
|
254
|
+
} else {
|
|
255
|
+
return [serialized, void 0];
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
function formatInline(ann) {
|
|
259
|
+
const [serialized, annotation] = serializeAnnotation(ann);
|
|
260
|
+
if (annotation !== void 0) {
|
|
261
|
+
return `${serialized}
|
|
262
|
+
${annotation}`;
|
|
263
|
+
} else {
|
|
264
|
+
return serialized;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
function formatShort(ann) {
|
|
268
|
+
return summarize(ann, []).join("\n");
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// src/result.ts
|
|
272
|
+
function ok(value) {
|
|
273
|
+
return { ok: true, value, error: void 0 };
|
|
274
|
+
}
|
|
275
|
+
function err(error) {
|
|
276
|
+
return { ok: false, value: void 0, error };
|
|
277
|
+
}
|
|
278
|
+
|
|
119
279
|
// src/Decoder.ts
|
|
120
280
|
function noThrow(fn) {
|
|
121
281
|
return (t) => {
|
|
122
282
|
try {
|
|
123
283
|
const v = fn(t);
|
|
124
|
-
return
|
|
284
|
+
return ok(v);
|
|
125
285
|
} catch (e) {
|
|
126
|
-
return
|
|
286
|
+
return err(public_annotate(t, e instanceof Error ? e.message : String(e)));
|
|
127
287
|
}
|
|
128
288
|
};
|
|
129
289
|
}
|
|
@@ -142,11 +302,11 @@ function define(fn) {
|
|
|
142
302
|
function decode(blob) {
|
|
143
303
|
return fn(
|
|
144
304
|
blob,
|
|
145
|
-
|
|
146
|
-
(msg) =>
|
|
305
|
+
ok,
|
|
306
|
+
(msg) => err(typeof msg === "string" ? public_annotate(blob, msg) : msg)
|
|
147
307
|
);
|
|
148
308
|
}
|
|
149
|
-
function verify(blob, formatter =
|
|
309
|
+
function verify(blob, formatter = formatInline) {
|
|
150
310
|
const result = decode(blob);
|
|
151
311
|
if (result.ok) {
|
|
152
312
|
return result.value;
|
|
@@ -215,13 +375,13 @@ function define(fn) {
|
|
|
215
375
|
|
|
216
376
|
// src/lib/objects.ts
|
|
217
377
|
var pojo = define(
|
|
218
|
-
(blob, ok2, err2) =>
|
|
378
|
+
(blob, ok2, err2) => isPojo(blob) ? ok2(blob) : err2("Must be an object")
|
|
219
379
|
);
|
|
220
380
|
function object2(decodersByKey) {
|
|
221
381
|
const knownKeys = new Set(Object.keys(decodersByKey));
|
|
222
382
|
return pojo.then((plainObj, ok2, err2) => {
|
|
223
383
|
const actualKeys = new Set(Object.keys(plainObj));
|
|
224
|
-
const missingKeys =
|
|
384
|
+
const missingKeys = subtract(knownKeys, actualKeys);
|
|
225
385
|
const record = {};
|
|
226
386
|
let errors = null;
|
|
227
387
|
for (const key of Object.keys(decodersByKey)) {
|
|
@@ -265,7 +425,7 @@ function exact(decodersByKey) {
|
|
|
265
425
|
const allowedKeys = new Set(Object.keys(decodersByKey));
|
|
266
426
|
const checked = pojo.reject((plainObj) => {
|
|
267
427
|
const actualKeys = new Set(Object.keys(plainObj));
|
|
268
|
-
const extraKeys =
|
|
428
|
+
const extraKeys = subtract(actualKeys, allowedKeys);
|
|
269
429
|
return extraKeys.size > 0 ? `Unexpected extra keys: ${Array.from(extraKeys).join(", ")}` : (
|
|
270
430
|
// Don't reject
|
|
271
431
|
null
|
|
@@ -367,7 +527,7 @@ var fail = never;
|
|
|
367
527
|
// src/lib/unions.ts
|
|
368
528
|
var EITHER_PREFIX = "Either:\n";
|
|
369
529
|
function itemize(s) {
|
|
370
|
-
return `-${
|
|
530
|
+
return `-${indent(s).substring(1)}`;
|
|
371
531
|
}
|
|
372
532
|
function nest(errText) {
|
|
373
533
|
return errText.startsWith(EITHER_PREFIX) ? errText.substr(EITHER_PREFIX.length) : itemize(errText);
|
|
@@ -386,7 +546,7 @@ function either(...decoders) {
|
|
|
386
546
|
errors.push(result.error);
|
|
387
547
|
}
|
|
388
548
|
}
|
|
389
|
-
const text = EITHER_PREFIX + errors.map((err3) => nest(
|
|
549
|
+
const text = EITHER_PREFIX + errors.map((err3) => nest(summarize(err3).join("\n"))).join("\n");
|
|
390
550
|
return err2(text);
|
|
391
551
|
});
|
|
392
552
|
}
|
|
@@ -426,15 +586,15 @@ var undefined_or_null = define(
|
|
|
426
586
|
);
|
|
427
587
|
function optional(decoder, defaultValue) {
|
|
428
588
|
const rv = either(undefined_, decoder);
|
|
429
|
-
return arguments.length >= 2 ? rv.transform((value) => _nullishCoalesce(value, () => (
|
|
589
|
+
return arguments.length >= 2 ? rv.transform((value) => _nullishCoalesce(value, () => ( lazyval(defaultValue)))) : rv;
|
|
430
590
|
}
|
|
431
591
|
function nullable(decoder, defaultValue) {
|
|
432
592
|
const rv = either(null_, decoder);
|
|
433
|
-
return arguments.length >= 2 ? rv.transform((value) => _nullishCoalesce(value, () => (
|
|
593
|
+
return arguments.length >= 2 ? rv.transform((value) => _nullishCoalesce(value, () => ( lazyval(defaultValue)))) : rv;
|
|
434
594
|
}
|
|
435
595
|
function maybe(decoder, defaultValue) {
|
|
436
596
|
const rv = either(undefined_or_null, decoder);
|
|
437
|
-
return arguments.length >= 2 ? rv.transform((value) => _nullishCoalesce(value, () => (
|
|
597
|
+
return arguments.length >= 2 ? rv.transform((value) => _nullishCoalesce(value, () => ( lazyval(defaultValue)))) : rv;
|
|
438
598
|
}
|
|
439
599
|
function constant(value) {
|
|
440
600
|
return define(
|
|
@@ -574,7 +734,7 @@ var uuidv4 = (
|
|
|
574
734
|
// src/lib/dates.ts
|
|
575
735
|
var iso8601_re = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:[.]\d+)?(?:Z|[+-]\d{2}:?\d{2})$/;
|
|
576
736
|
var date = define((blob, ok2, err2) => {
|
|
577
|
-
const date2 =
|
|
737
|
+
const date2 = asDate(blob);
|
|
578
738
|
return date2 !== null ? ok2(date2) : err2("Must be a Date");
|
|
579
739
|
});
|
|
580
740
|
var iso8601 = (
|
|
@@ -655,5 +815,9 @@ var json = either(
|
|
|
655
815
|
|
|
656
816
|
|
|
657
817
|
|
|
658
|
-
|
|
659
|
-
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
exports.always = always; exports.anyNumber = anyNumber; exports.array = array2; exports.boolean = boolean; exports.constant = constant; exports.date = date; exports.define = define; exports.dict = dict; exports.either = either; exports.email = email; exports.err = err; exports.exact = exact; exports.fail = fail; exports.formatInline = formatInline; exports.formatShort = formatShort; exports.hardcoded = hardcoded; 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.number = number; exports.numericBoolean = numericBoolean; exports.object = object2; 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.regex = regex; exports.set = set; exports.string = string; exports.taggedUnion = taggedUnion; exports.truthy = truthy; exports.tuple = tuple; exports.undefined_ = undefined_; exports.unknown = unknown2; exports.url = url; exports.uuid = uuid; exports.uuidv1 = uuidv1; exports.uuidv4 = uuidv4;
|
|
823
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/_utils.ts","../src/annotate.ts","../src/format.ts","../src/result.ts","../src/Decoder.ts","../src/lib/objects.ts","../src/lib/utilities.ts","../src/lib/unions.ts","../src/lib/basics.ts","../src/lib/arrays.ts","../src/lib/numbers.ts","../src/lib/booleans.ts","../src/lib/strings.ts","../src/lib/dates.ts","../src/lib/json.ts"],"names":["ann","err","value","ok","object","mapping","unknown","array","regex","date"],"mappings":"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","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 { isPojo } from './_utils';\n\nconst _register: WeakSet<Annotation> = new WeakSet();\n\nexport interface ObjectAnnotation {\n readonly type: 'object';\n readonly fields: { readonly [key: string]: Annotation };\n readonly text?: string;\n}\n\nexport interface ArrayAnnotation {\n readonly type: 'array';\n readonly items: readonly Annotation[];\n readonly text?: string;\n}\n\nexport interface ScalarAnnotation {\n readonly type: 'scalar';\n readonly value: unknown;\n readonly text?: string;\n}\n\nexport interface FunctionAnnotation {\n readonly type: 'function';\n readonly text?: string;\n}\n\nexport interface CircularRefAnnotation {\n readonly type: 'circular-ref';\n readonly text?: string;\n}\n\nexport interface UnknownAnnotation {\n readonly type: 'unknown';\n readonly value: unknown;\n readonly text?: string;\n}\n\nexport type Annotation =\n | ObjectAnnotation\n | ArrayAnnotation\n | ScalarAnnotation\n | FunctionAnnotation\n | CircularRefAnnotation\n | UnknownAnnotation;\n\nfunction brand<A extends Annotation>(ann: A): A {\n _register.add(ann);\n return ann;\n}\n\nexport function object(\n fields: { readonly [key: string]: Annotation },\n text?: string,\n): ObjectAnnotation {\n return brand({ type: 'object', fields, text });\n}\n\nexport function array(items: readonly Annotation[], text?: string): ArrayAnnotation {\n return brand({\n type: 'array',\n items,\n text,\n });\n}\n\nexport function func(text?: string): FunctionAnnotation {\n return brand({\n type: 'function',\n text,\n });\n}\n\nexport function unknown(value: unknown, text?: string): UnknownAnnotation {\n return brand({\n type: 'unknown',\n value,\n text,\n });\n}\n\nexport function scalar(value: unknown, text?: string): ScalarAnnotation {\n return brand({\n type: 'scalar',\n value,\n text,\n });\n}\n\nexport function circularRef(text?: string): CircularRefAnnotation {\n return brand({\n type: 'circular-ref',\n text,\n });\n}\n\n/**\n * Given an existing Annotation, set the annotation's text to a new value.\n */\nexport function updateText<A extends Annotation>(annotation: A, text?: string): A {\n if (text !== undefined) {\n return brand({ ...annotation, text });\n } else {\n return annotation;\n }\n}\n\n/**\n * Given an existing ObjectAnnotation, merges new Annotations in there.\n */\nexport function merge(\n objAnnotation: ObjectAnnotation,\n fields: { readonly [key: string]: Annotation },\n): ObjectAnnotation {\n const newFields = { ...objAnnotation.fields, ...fields };\n return object(newFields, objAnnotation.text);\n}\n\nexport function asAnnotation(thing: unknown): Annotation | undefined {\n return typeof thing === 'object' && thing !== null && _register.has(thing as Annotation)\n ? (thing as Annotation)\n : undefined;\n}\n\ntype RefSet = WeakSet<object>;\n\n/** @internal */\nfunction annotateArray(\n value: readonly unknown[],\n text: string | undefined,\n seen: RefSet,\n): ArrayAnnotation | CircularRefAnnotation {\n seen.add(value);\n\n const items = value.map((v) => annotate(v, undefined, seen));\n return array(items, text);\n}\n\n/** @internal */\nfunction annotateObject(\n obj: Record<string, unknown>,\n text: string | undefined,\n seen: RefSet,\n): ObjectAnnotation {\n seen.add(obj);\n\n const fields: Record<string, Annotation> = {};\n for (const key of Object.keys(obj)) {\n const value = obj[key];\n fields[key] = annotate(value, undefined, seen);\n }\n return object(fields, text);\n}\n\n/** @internal */\nfunction annotate(value: unknown, text: string | undefined, seen: RefSet): Annotation {\n if (\n value === null ||\n value === undefined ||\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean' ||\n typeof value === 'symbol' ||\n typeof (value as Record<string, unknown>).getMonth === 'function'\n ) {\n return scalar(value, text);\n }\n\n const ann = asAnnotation(value);\n if (ann) {\n return updateText(ann, text);\n }\n\n if (Array.isArray(value)) {\n // \"Circular references\" can only exist in objects or arrays\n if (seen.has(value)) {\n return circularRef(text);\n } else {\n return annotateArray(value, text, seen);\n }\n }\n\n if (isPojo(value)) {\n // \"Circular references\" can only exist in objects or arrays\n if (seen.has(value)) {\n return circularRef(text);\n } else {\n return annotateObject(value, text, seen);\n }\n }\n\n if (typeof value === 'function') {\n return func(text);\n }\n\n return unknown(value, text);\n}\n\nfunction public_annotate(value: unknown, text?: string): Annotation {\n return annotate(value, text, new WeakSet());\n}\n\nfunction public_annotateObject(\n obj: { readonly [field: string]: unknown },\n text?: string,\n): ObjectAnnotation {\n return annotateObject(obj, text, new WeakSet());\n}\n\nexport {\n // This construct just ensures the \"seen\" weakmap (used for circular\n // reference detection) isn't made part of the public API.\n public_annotate as annotate,\n public_annotateObject as annotateObject,\n\n /** @internal */\n annotate as __private_annotate,\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","/**\n * Result <value> <error>\n * = Ok <value>\n * | Err <error>\n */\nexport type Ok<T> = {\n readonly ok: true;\n readonly value: T;\n readonly error?: never;\n};\n\nexport type Err<E> = {\n readonly ok: false;\n readonly value?: never;\n readonly error: E;\n};\n\nexport type Result<T, E> = Ok<T> | Err<E>;\n\n/**\n * Create a new Result instance representing a successful computation.\n */\nexport function ok<T>(value: T): Ok<T> {\n return { ok: true, value, error: undefined };\n}\n\n/**\n * Create a new Result instance representing a failed computation.\n */\nexport function err<E>(error: E): Err<E> {\n return { ok: false, value: undefined, error };\n}\n","import { annotate } from './annotate';\nimport { formatInline } from './format';\nimport { err as makeErr, ok as makeOk } from './result';\nimport type { Annotation } from './annotate';\nimport type { Formatter } from './format';\nimport type { Result } from './result';\n\nexport type Scalar = string | number | boolean | symbol | undefined | null;\n\nexport type DecodeResult<T> = Result<T, Annotation>;\n\nexport type AcceptanceFn<T, InputT = unknown> = (\n blob: InputT,\n ok: (value: T) => DecodeResult<T>,\n err: (msg: string | Annotation) => DecodeResult<T>,\n) => DecodeResult<T>;\n\nexport interface Decoder<T> {\n /**\n * Verifies untrusted input. Either returns a value, or throws a decoding\n * error.\n */\n verify(blob: unknown, formatterFn?: (ann: Annotation) => string | Error): T;\n\n /**\n * Verifies untrusted input. Either returns a value, or returns undefined.\n */\n value(blob: unknown): T | undefined;\n\n /**\n * Verifies untrusted input. Always returns a DecodeResult, which is either\n * an \"ok\" value or an \"error\" annotation.\n */\n decode(blob: unknown): DecodeResult<T>;\n\n /**\n * Build a new decoder from the the current one, with an extra acceptance\n * criterium.\n */\n refine<N extends T>(predicate: (value: T) => value is N, msg: string): Decoder<N>;\n refine(predicate: (value: T) => boolean, msg: string): Decoder<T>;\n\n /**\n * Build a new decoder from the current one, with an extra rejection\n * criterium.\n */\n reject(rejectFn: (value: T) => string | Annotation | null): Decoder<T>;\n\n /**\n * Build a new decoder from the current one, modifying its outputted value.\n */\n transform<V>(transformFn: (value: T) => V): Decoder<V>;\n\n /**\n * Build a new decoder from the current one, with a mutated error message\n * in case of a rejection.\n */\n describe(message: string): Decoder<T>;\n\n /**\n * Chain together the current decoder with another acceptance function.\n */\n then<V>(next: AcceptanceFn<V, T>): Decoder<V>;\n\n // Experimental APIs (please don't rely on these yet)\n peek_UNSTABLE<V>(next: AcceptanceFn<V, [unknown, T]>): Decoder<V>;\n}\n\n/**\n * Helper type to return the \"type\" of a Decoder.\n *\n * You can use it on types:\n *\n * DecoderType<Decoder<string>> // string\n * DecoderType<Decoder<number[]>> // number[]\n *\n * Or on \"values\", by using the `typeof` keyword:\n *\n * DecoderType<typeof string> // string\n * DecoderType<typeof truthy> // boolean\n *\n */\nexport type DecoderType<D extends Decoder<any>> = D extends Decoder<infer T> ? T : never;\n\nfunction noThrow<T, V>(fn: (value: T) => V): (blob: T) => DecodeResult<V> {\n return (t) => {\n try {\n const v = fn(t);\n return makeOk(v);\n } catch (e) {\n return makeErr(annotate(t, e instanceof Error ? e.message : String(e)));\n }\n };\n}\n\nfunction format(err: Annotation, formatter: Formatter): Error {\n const formatted = formatter(err);\n\n // Formatter functions may return a string or an error for convenience of\n // writing them. If it already returns an Error, return it unmodified. If\n // it returns a string, wrap it in a \"Decoding error\" instance.\n if (typeof formatted === 'string') {\n const err = new Error(`\\n${formatted}`);\n err.name = 'Decoding error';\n return err;\n } else {\n return formatted;\n }\n}\n\n/**\n * Defines a new `Decoder<T>`, by implementing a custom acceptance function.\n * The function receives three arguments:\n *\n * 1. `blob` - the raw/unknown input (aka your external data)\n * 2. `ok` - Call `ok(value)` to accept the input and return ``value``\n * 3. `err` - Call `err(message)` to reject the input with error ``message``\n *\n * The expected return value should be a `DecodeResult<T>`, which can be\n * obtained by returning the result of calling the provided `ok` or `err`\n * helper functions. Please note that `ok()` and `err()` don't perform side\n * effects! You'll need to _return_ those values.\n */\nexport function define<T>(fn: AcceptanceFn<T>): Decoder<T> {\n /**\n * Verifies the untrusted/unknown input and either accepts or rejects it.\n *\n * Contrasted with `.verify()`, calls to `.decode()` will never fail and\n * instead return a result type.\n */\n function decode(blob: unknown): DecodeResult<T> {\n return fn(blob, makeOk, (msg: Annotation | string) =>\n makeErr(typeof msg === 'string' ? annotate(blob, msg) : msg),\n );\n }\n\n /**\n * Verifies the untrusted/unknown input and either accepts or rejects it.\n * When accepted, returns a value of type `T`. Otherwise fail with\n * a runtime error.\n */\n function verify(blob: unknown, formatter: Formatter = formatInline): T {\n const result = decode(blob);\n if (result.ok) {\n return result.value;\n } else {\n throw format(result.error, formatter);\n }\n }\n\n /**\n * Verifies the untrusted/unknown input and either accepts or rejects it.\n * When accepted, returns the decoded `T` value directly. Otherwise returns\n * `undefined`.\n *\n * Use this when you're not interested in programmatically handling the\n * error message.\n */\n function value(blob: unknown): T | undefined {\n return decode(blob).value;\n }\n\n /**\n * Accepts any value the given decoder accepts, and on success, will call\n * the given function **on the decoded result**. If the transformation\n * function throws an error, the whole decoder will fail using the error\n * message as the failure reason.\n */\n function transform<V>(transformFn: (result: T) => V): Decoder<V> {\n return then(noThrow(transformFn));\n }\n\n /**\n * Adds an extra predicate to a decoder. The new decoder is like the\n * original decoder, but only accepts values that also meet the\n * predicate.\n */\n function refine(predicateFn: (value: T) => boolean, errmsg: string): Decoder<T> {\n return reject((value) =>\n predicateFn(value)\n ? // Don't reject\n null\n : // Reject with the given error message\n errmsg,\n );\n }\n\n /**\n * Chain together the current decoder with another.\n *\n * > _**NOTE:** This is an advanced, low-level, API. It's not recommended\n * > to reach for this construct unless there is no other way. Most cases can\n * > be covered more elegantly by `.transform()` or `.refine()` instead._\n *\n * If the current decoder accepts an input, the resulting ``T`` value will\n * get passed into the given ``next`` acceptance function to further decide\n * whether or not the value should get accepted or rejected.\n *\n * This works similar to how you would `define()` a new decoder, except\n * that the ``blob`` param will now be ``T`` (a known type), rather than\n * ``unknown``. This will allow the function to make a stronger assumption\n * about its input and avoid re-refining inputs.\n *\n * If it helps, you can think of `define(...)` as equivalent to\n * `unknown.then(...)`.\n */\n function then<V>(next: AcceptanceFn<V, T>): Decoder<V> {\n return define((blob, ok, err) => {\n const result = decode(blob);\n return result.ok ? next(result.value, ok, err) : result;\n });\n }\n\n /**\n * Adds an extra predicate to a decoder. The new decoder is like the\n * original decoder, but only accepts values that aren't rejected by the\n * given function.\n *\n * The given function can return `null` to accept the decoded value, or\n * return a specific error message to reject.\n *\n * Unlike `.refine()`, you can use this function to return a dynamic error\n * message.\n */\n function reject(rejectFn: (value: T) => string | Annotation | null): Decoder<T> {\n return then((value, ok, err) => {\n const errmsg = rejectFn(value);\n return errmsg === null\n ? ok(value)\n : err(typeof errmsg === 'string' ? annotate(value, errmsg) : errmsg);\n });\n }\n\n /**\n * Uses the given decoder, but will use an alternative error message in\n * case it rejects. This can be used to simplify or shorten otherwise\n * long or low-level/technical errors.\n */\n function describe(message: string): Decoder<T> {\n return define((blob, _, err) => {\n // Decode using the given decoder...\n const result = decode(blob);\n if (result.ok) {\n return result;\n } else {\n // ...but in case of error, annotate this with the custom given\n // message instead\n return err(annotate(result.error, message));\n }\n });\n }\n\n /**\n * WARNING: This is an EXPERIMENTAL API that will likely change in the\n * future. Please DO NOT rely on it.\n *\n * Chain together the current decoder with another, but also pass along\n * the original input.\n *\n * This is like `.then()`, but instead of this function receiving just\n * the decoded result ``T``, it also receives the original input.\n *\n * This is an advanced, low-level, decoder.\n */\n function peek_UNSTABLE<V>(next: AcceptanceFn<V, [unknown, T]>): Decoder<V> {\n return define((blob, ok, err) => {\n const result = decode(blob);\n return result.ok ? next([blob, result.value], ok, err) : result;\n });\n }\n\n return Object.freeze({\n verify,\n value,\n decode,\n transform,\n refine,\n reject,\n describe,\n then,\n\n // EXPERIMENTAL - please DO NOT rely on this method\n peek_UNSTABLE,\n });\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { annotateObject, merge, updateText } from '../annotate';\nimport { define } from '../Decoder';\nimport { subtract, isPojo } from '../_utils';\nimport type { Annotation } from '../annotate';\nimport type { Decoder, DecodeResult } from '../Decoder';\nimport type { UndefinedToOptional } from './_helpers';\n\ntype ObjectDecoderType<T> = UndefinedToOptional<{\n [K in keyof T]: T[K] extends Decoder<infer V> ? V : never;\n}>;\n\n/**\n * Accepts any \"plain old JavaScript object\", but doesn't validate its keys or\n * values further.\n */\nexport const pojo: Decoder<Record<string, unknown>> = define((blob, ok, err) =>\n isPojo(blob) ? ok(blob) : err('Must be an object'),\n);\n\n/**\n * Accepts objects with fields matching the given decoders. Extra fields that\n * exist on the input object are ignored and will not be returned.\n */\nexport function object(decodersByKey: Record<any, never>): Decoder<Record<string, never>>;\nexport function object<DS extends Record<string, Decoder<any>>>(\n decodersByKey: DS,\n): Decoder<ObjectDecoderType<DS>>;\nexport function object<DS extends Record<string, Decoder<any>>>(\n decodersByKey: DS,\n): Decoder<ObjectDecoderType<DS>> {\n // Compute this set at decoder definition time\n const knownKeys = new Set(Object.keys(decodersByKey));\n\n return pojo.then((plainObj, ok, err) => {\n const actualKeys = new Set(Object.keys(plainObj));\n\n // At this point, \"missingKeys\" will also include all fields that may\n // validly be optional. We'll let the underlying decoder decide and\n // remove the key from this missing set if the decoder accepts the\n // value.\n const missingKeys = subtract(knownKeys, actualKeys);\n\n const record = {};\n let errors: Record<string, Annotation> | null = null;\n\n for (const key of Object.keys(decodersByKey)) {\n const decoder = decodersByKey[key];\n const rawValue = plainObj[key];\n const result: DecodeResult<unknown> = decoder.decode(rawValue);\n\n if (result.ok) {\n const value = result.value;\n if (value !== undefined) {\n // @ts-expect-error - look into this later\n record[key] = value;\n }\n\n // If this succeeded, remove the key from the missing keys\n // tracker\n missingKeys.delete(key);\n } else {\n const ann = result.error;\n\n // Keep track of the annotation, but don't return just yet. We\n // want to collect more error information.\n if (rawValue === undefined) {\n // Explicitly add it to the missing set if the value is\n // undefined. This covers explicit undefineds to be\n // treated the same as implicit undefineds (aka missing\n // keys).\n missingKeys.add(key);\n } else {\n if (errors === null) {\n errors = {};\n }\n errors[key] = ann;\n }\n }\n }\n\n // Deal with errors now. There are two classes of errors we want to\n // report. First of all, we want to report any inline errors in this\n // object. Lastly, any fields that are missing should be annotated on\n // the outer object itself.\n if (errors || missingKeys.size > 0) {\n let objAnn = annotateObject(plainObj);\n\n if (errors) {\n objAnn = merge(objAnn, errors);\n }\n\n if (missingKeys.size > 0) {\n const errMsg = Array.from(missingKeys)\n .map((key) => `\"${key}\"`)\n .join(', ');\n const pluralized = missingKeys.size > 1 ? 'keys' : 'key';\n objAnn = updateText(objAnn, `Missing ${pluralized}: ${errMsg}`);\n }\n\n return err(objAnn);\n }\n\n return ok(record as ObjectDecoderType<DS>);\n });\n}\n\n/**\n * Like `object()`, but will reject inputs that contain extra fields that are\n * not specified explicitly.\n */\nexport function exact(decodersByKey: Record<any, never>): Decoder<Record<string, never>>;\nexport function exact<O extends Record<string, Decoder<any>>>(\n decodersByKey: O,\n): Decoder<{ [K in keyof ObjectDecoderType<O>]: ObjectDecoderType<O>[K] }>;\nexport function exact<O extends Record<string, Decoder<any>>>(\n decodersByKey: O,\n): Decoder<{ [K in keyof ObjectDecoderType<O>]: ObjectDecoderType<O>[K] }> {\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n // Ditto (see above)\n\n // Compute this set at decoder definition time\n const allowedKeys = new Set(Object.keys(decodersByKey));\n\n // Check the inputted object for any unexpected extra keys\n const checked = pojo.reject((plainObj) => {\n const actualKeys = new Set(Object.keys(plainObj));\n const extraKeys = subtract(actualKeys, allowedKeys);\n return extraKeys.size > 0\n ? `Unexpected extra keys: ${Array.from(extraKeys).join(', ')}`\n : // Don't reject\n null;\n });\n\n // Defer to the \"object\" decoder for doing the real decoding work. Since\n // we made sure there are no superfluous keys in this structure, it's now\n // safe to force-cast it to an $Exact<> type.\n return checked.then(object(decodersByKey).decode);\n}\n\n/**\n * Like `object()`, but will pass through any extra fields on the input object\n * unvalidated that will thus be of `unknown` type statically.\n */\nexport function inexact(\n decodersByKey: Record<any, never>,\n): Decoder<Record<string, unknown>>;\nexport function inexact<O extends Record<string, Decoder<any>>>(\n decodersByKey: O,\n): Decoder<\n { [K in keyof ObjectDecoderType<O>]: ObjectDecoderType<O>[K] } & Record<string, unknown>\n>;\nexport function inexact<O extends Record<string, Decoder<any>>>(\n decodersByKey: O,\n): Decoder<\n { [K in keyof ObjectDecoderType<O>]: ObjectDecoderType<O>[K] } & Record<string, unknown>\n> {\n return pojo.then((plainObj) => {\n const allkeys = new Set(Object.keys(plainObj));\n const decoder = object(decodersByKey).transform((safepart) => {\n const safekeys = new Set(Object.keys(decodersByKey));\n\n // To account for hard-coded keys that aren't part of the input\n for (const k of safekeys) allkeys.add(k);\n\n const rv = {} as {\n [K in keyof ObjectDecoderType<O>]: ObjectDecoderType<O>[K];\n } & Record<string, unknown>;\n for (const k of allkeys) {\n if (safekeys.has(k)) {\n const value = safepart[k];\n if (value !== undefined) {\n // @ts-expect-error - look into this later\n rv[k] = value;\n }\n } else {\n // @ts-expect-error - look into this later\n rv[k] = plainObj[k];\n }\n }\n return rv;\n });\n return decoder.decode(plainObj);\n });\n}\n\n/**\n * Accepts objects where all values match the given decoder, and returns the\n * result as a `Record<string, T>`.\n *\n * The main difference between `object()` and `dict()` is that you'd typically\n * use `object()` if this is a record-like object, where all field names are\n * known and the values are heterogeneous. Whereas with `dict()` the keys are\n * typically dynamic and the values homogeneous, like in a dictionary,\n * a lookup table, or a cache.\n */\nexport function dict<T>(decoder: Decoder<T>): Decoder<Record<string, T>> {\n return pojo.then((plainObj, ok, err) => {\n let rv: Record<string, T> = {};\n let errors: Record<string, Annotation> | null = null;\n\n for (const key of Object.keys(plainObj)) {\n const value = plainObj[key];\n const result = decoder.decode(value);\n if (result.ok) {\n if (errors === null) {\n rv[key] = result.value;\n }\n } else {\n rv = {}; // Clear the success value so it can get garbage collected early\n if (errors === null) {\n errors = {};\n }\n errors[key] = result.error;\n }\n }\n\n if (errors !== null) {\n return err(merge(annotateObject(plainObj), errors));\n } else {\n return ok(rv);\n }\n });\n}\n\n/**\n * Similar to `dict()`, but returns the result as a `Map<string, T>` (an [ES6\n * Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map))\n * instead.\n */\nexport function mapping<T>(decoder: Decoder<T>): Decoder<Map<string, T>> {\n return dict(decoder).transform(\n (obj) =>\n new Map(\n // This is effectively Object.entries(obj), but in a way that Flow\n // will know the types are okay\n Object.keys(obj).map((key) => [key, obj[key]]),\n ),\n );\n}\n","import { annotate } from '../annotate';\nimport { define } from '../Decoder';\nimport type { Decoder } from '../Decoder';\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport interface Klass<T> extends Function {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n new (...args: readonly any[]): T;\n}\n\nexport type Instance<K> = K extends Klass<infer T> ? T : never;\n\n/**\n * Accepts any value that is an ``instanceof`` the given class.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function instanceOf<K extends Klass<any>>(klass: K): Decoder<Instance<K>> {\n return define((blob, ok, err) =>\n blob instanceof klass ? ok(blob) : err(`Must be ${klass.name} instance`),\n );\n}\n\n/**\n * Lazily evaluate the given decoder. This is useful to build self-referential\n * types for recursive data structures.\n */\nexport function lazy<T>(decoderFn: () => Decoder<T>): Decoder<T> {\n return define((blob) => decoderFn().decode(blob));\n}\n\n/**\n * Pre-process the data input before passing it into the decoder. This gives\n * you the ability to arbitrarily customize the input on the fly before passing\n * it to the decoder. Of course, the input value at that point is still of\n * ``unknown`` type, so you will have to deal with that accordingly.\n */\nexport function prep<T>(\n mapperFn: (blob: unknown) => unknown,\n decoder: Decoder<T>,\n): Decoder<T> {\n return define((originalInput, _, err) => {\n let blob;\n try {\n blob = mapperFn(originalInput);\n } catch (e: unknown) {\n return err(\n annotate(\n originalInput,\n // istanbul ignore next\n e instanceof Error ? e.message : String(e),\n ),\n );\n }\n\n const r = decoder.decode(blob);\n return r.ok ? r : err(annotate(originalInput, r.error.text));\n // ^^^^^^^^^^^^^\n // Annotates the _original_ input value\n // (instead of echoing back blob)\n });\n}\n\n/**\n * Rejects all inputs, and always fails with the given error message. May be\n * useful for explicitly disallowing keys, or for testing purposes.\n */\nexport function never(msg: string): Decoder<never> {\n return define((_, __, err) => err(msg));\n}\n\n/**\n * Alias of never().\n */\nexport const fail = never;\n","import { define } from '../Decoder';\nimport { indent, summarize } from '../_utils';\nimport { object } from './objects';\nimport { prep } from './utilities';\nimport type { Decoder, DecoderType, DecodeResult, Scalar } from '../Decoder';\nimport type { Ok } from '../result';\n\ntype Values<T extends object> = T[keyof T];\n\ntype DecoderTypes<T> = T extends readonly Decoder<infer U>[] ? U : never;\n\nconst EITHER_PREFIX = 'Either:\\n';\n\n/**\n * Indents and adds a dash in front of this (potentially multiline) string.\n */\nfunction itemize(s: string): string {\n return `-${indent(s).substring(1)}`;\n}\n\n/**\n * Nests another error as an item under a new-to-be-created \"Either error\". If\n * the given subitem already is an \"Either error\" of itself, don't indent, but\n * just \"inject\" its items at the same error level, for nicely flattened either\n * expressions.\n *\n * Avoids:\n *\n * Either:\n * - Either:\n * - Must be P\n * - Either:\n * - Must be Q\n * - Must be R\n * - Must be S\n *\n * And \"flattens\" these to:\n *\n * Either:\n * - Must be P\n * - Must be Q\n * - Must be R\n * - Must be S\n *\n */\nfunction nest(errText: string): string {\n return errText.startsWith(EITHER_PREFIX)\n ? errText.substr(EITHER_PREFIX.length)\n : itemize(errText);\n}\n\n/**\n * Accepts values accepted by any of the given decoders.\n *\n * The decoders are tried on the input one by one, in the given order. The\n * first one that accepts the input \"wins\". If all decoders reject the input,\n * the input gets rejected.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function either<T extends readonly Decoder<any>[]>(\n ...decoders: T\n): Decoder<DecoderTypes<T>> {\n if (decoders.length === 0) {\n throw new Error('Pass at least one decoder to either()');\n }\n\n return define((blob, _, err) => {\n // Collect errors here along the way\n const errors = [];\n\n for (let i = 0; i < decoders.length; i++) {\n const result: DecodeResult<unknown> = decoders[i].decode(blob);\n if (result.ok) {\n return result as Ok<DecoderTypes<T>>;\n } else {\n errors.push(result.error);\n }\n }\n\n // Decoding all alternatives failed, return the combined error message\n const text =\n EITHER_PREFIX + errors.map((err) => nest(summarize(err).join('\\n'))).join('\\n');\n return err(text);\n });\n}\n\n/**\n * Accepts any value that is strictly-equal (using `===`) to one of the\n * specified values.\n */\nexport function oneOf<C extends Scalar>(constants: readonly C[]): Decoder<C> {\n return define((blob, ok, err) => {\n const winner = constants.find((c) => c === blob);\n if (winner !== undefined) {\n return ok(winner);\n }\n return err(\n `Must be one of ${constants.map((value) => JSON.stringify(value)).join(', ')}`,\n );\n });\n}\n\n/**\n * If you are decoding tagged unions you may want to use the `taggedUnion()`\n * decoder instead of the general purpose `either()` decoder to get better\n * error messages and better performance.\n *\n * This decoder is optimized for [tagged\n * unions](https://en.wikipedia.org/wiki/Tagged_union), i.e. a union of\n * objects where one field is used as the discriminator.\n *\n * ```ts\n * const A = object({ tag: constant('A'), foo: string });\n * const B = object({ tag: constant('B'), bar: number });\n *\n * const AorB = taggedUnion('tag', { A, B });\n * // ^^^\n * ```\n *\n * Decoding now works in two steps:\n *\n * 1. Look at the `'tag'` field in the incoming object (this is the field\n * that decides which decoder will be used)\n * 2. If the value is `'A'`, then decoder `A` will be used. If it's `'B'`, then\n * decoder `B` will be used. Otherwise, this will fail.\n *\n * This is effectively equivalent to `either(A, B)`, but will provide better\n * error messages and is more performant at runtime because it doesn't have to\n * try all decoders one by one.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function taggedUnion<O extends Record<string, Decoder<any>>>(\n field: string,\n mapping: O,\n): Decoder<Values<{ [key in keyof O]: DecoderType<O[key]> }>> {\n const base: Decoder<string> = object({\n [field]: prep(String, oneOf(Object.keys(mapping))),\n }).transform((o) => o[field]);\n return base.peek_UNSTABLE(([blob, key]) => {\n const decoder = mapping[key];\n return decoder.decode(blob);\n });\n}\n","import { define } from '../Decoder';\nimport { either } from './unions';\nimport type { Decoder, Scalar } from '../Decoder';\nimport { lazyval } from '../_utils';\n\n/**\n * Accepts and returns only the literal `null` value.\n */\nexport const null_: Decoder<null> = define((blob, ok, err) =>\n blob === null ? ok(blob) : err('Must be null'),\n);\n\n/**\n * Accepts and returns only the literal `undefined` value.\n */\nexport const undefined_: Decoder<undefined> = define((blob, ok, err) =>\n blob === undefined ? ok(blob) : err('Must be undefined'),\n);\n\nconst undefined_or_null: Decoder<null | undefined> = define((blob, ok, err) =>\n blob === undefined || blob === null\n ? ok(blob)\n : // Combine error message into a single line for readability\n err('Must be undefined or null'),\n);\n\n/**\n * Accepts whatever the given decoder accepts, or `undefined`.\n *\n * If a default value is explicitly provided, return that instead in the\n * `undefined` case.\n */\nexport function optional<T>(decoder: Decoder<T>): Decoder<T | undefined>;\nexport function optional<T, C extends Scalar>(decoder: Decoder<T>, defaultValue: (() => C) | C): Decoder<NonNullable<T> | C>; // prettier-ignore\nexport function optional<T, V>(decoder: Decoder<T>, defaultValue: (() => V) | V): Decoder<NonNullable<T> | V>; // prettier-ignore\nexport function optional<T, V>(\n decoder: Decoder<T>,\n defaultValue?: (() => V) | V,\n): Decoder<T | V | undefined> {\n const rv = either(undefined_, decoder);\n return arguments.length >= 2\n ? rv.transform((value) => value ?? lazyval(defaultValue as (() => V) | V))\n : rv;\n}\n\n/**\n * Accepts whatever the given decoder accepts, or `null`.\n *\n * If a default value is explicitly provided, return that instead in the `null`\n * case.\n */\nexport function nullable<T>(decoder: Decoder<T>): Decoder<T | null>;\nexport function nullable<T, C extends Scalar>(decoder: Decoder<T>, defaultValue: (() => C) | C): Decoder<NonNullable<T> | C>; // prettier-ignore\nexport function nullable<T, V>(decoder: Decoder<T>, defaultValue: (() => V) | V): Decoder<NonNullable<T> | V>; // prettier-ignore\nexport function nullable<T, V>(\n decoder: Decoder<T>,\n defaultValue?: (() => V) | V,\n): Decoder<T | V | null> {\n const rv = either(null_, decoder);\n return arguments.length >= 2\n ? rv.transform((value) => value ?? lazyval(defaultValue as (() => V) | V))\n : rv;\n}\n\n/**\n * Accepts whatever the given decoder accepts, or `null`, or `undefined`.\n *\n * If a default value is explicitly provided, return that instead in the\n * `null`/`undefined` case.\n */\nexport function maybe<T>(decoder: Decoder<T>): Decoder<T | null | undefined>;\nexport function maybe<T, C extends Scalar>(decoder: Decoder<T>, defaultValue: (() => C) | C): Decoder<NonNullable<T> | C>; // prettier-ignore\nexport function maybe<T, V>(decoder: Decoder<T>, defaultValue: (() => V) | V): Decoder<NonNullable<T> | V>; // prettier-ignore\nexport function maybe<T, V>(\n decoder: Decoder<T>,\n defaultValue?: (() => V) | V,\n): Decoder<T | V | null | undefined> {\n const rv = either(undefined_or_null, decoder);\n return arguments.length >= 2\n ? rv.transform((value) => value ?? lazyval(defaultValue as (() => V) | V))\n : rv;\n}\n\n/**\n * Accepts only the given constant value.\n */\nexport function constant<C extends Scalar>(value: C): Decoder<C> {\n return define((blob, ok, err) =>\n blob === value ? ok(value) : err(`Must be constant ${String(value)}`),\n );\n}\n\n/**\n * Accepts anything, completely ignores it, and always returns the provided\n * value instead.\n *\n * This is useful to manually add extra fields to object decoders.\n */\nexport function always<C extends Scalar>(value: C): Decoder<C>;\nexport function always<T>(value: (() => T) | T): Decoder<T>;\nexport function always<T>(value: (() => T) | T): Decoder<T> {\n return define(\n typeof value === 'function'\n ? (_, ok) => ok((value as () => T)())\n : (_, ok) => ok(value),\n );\n}\n\n/**\n * Alias of always.\n */\nexport const hardcoded = always;\n\n/**\n * Accepts anything and returns it unchanged.\n *\n * Useful for situation in which you don't know or expect a specific type. Of\n * course, the downside is that you won't know the type of the value statically\n * and you'll have to further refine it yourself.\n */\nexport const unknown: Decoder<unknown> = define((blob, ok, _) => ok(blob));\n\n/**\n * Alias of unknown.\n */\nexport const mixed = unknown;\n","import { annotate } from '../annotate';\nimport { define } from '../Decoder';\nimport type { Annotation } from '../annotate';\nimport type { Decoder, DecodeResult } from '../Decoder';\n\n/**\n * Accepts any array, but doesn't validate its items further.\n *\n * \"poja\" means \"plain old JavaScript array\", a play on `pojo()`.\n */\nexport const poja: Decoder<unknown[]> = define((blob, ok, err) => {\n if (!Array.isArray(blob)) {\n return err('Must be an array');\n }\n return ok(blob as unknown[]);\n});\n\n/**\n * Given an array of Result instances, loop over them all and return:\n * - An [index, err] tuple, indicating the (index of the) first Err instance\n * encountered; or\n * - a new Ok with an array of all unwrapped Ok'ed values\n */\nfunction all<T>(\n items: readonly DecodeResult<T>[],\n blobs: readonly unknown[],\n\n // TODO: Make this less ugly\n ok: (value: T[]) => DecodeResult<T[]>,\n err: (ann: Annotation) => DecodeResult<T[]>,\n): DecodeResult<T[]> {\n const results: T[] = [];\n for (let index = 0; index < items.length; ++index) {\n const result = items[index];\n if (result.ok) {\n results.push(result.value);\n } else {\n const ann = result.error;\n\n // Rewrite the annotation to include the index information, and inject it into the original blob\n const clone = blobs.slice();\n clone.splice(\n index,\n 1,\n annotate(ann, ann.text ? `${ann.text} (at index ${index})` : `index ${index}`),\n );\n\n return err(annotate(clone));\n }\n }\n return ok(results);\n}\n\n/**\n * Accepts arrays of whatever the given decoder accepts.\n */\nexport function array<T>(decoder: Decoder<T>): Decoder<T[]> {\n const decodeFn = decoder.decode;\n return poja.then((blobs: readonly unknown[], ok, err) => {\n const results = blobs.map(decodeFn);\n return all(results, blobs, ok, err);\n });\n}\n\nfunction isNonEmpty<T>(arr: readonly T[]): arr is [T, ...T[]] {\n return arr.length > 0;\n}\n\n/**\n * Like `array()`, but will reject arrays with 0 elements.\n */\nexport function nonEmptyArray<T>(decoder: Decoder<T>): Decoder<[T, ...T[]]> {\n return array(decoder).refine(isNonEmpty, 'Must be non-empty array');\n}\n\n/**\n * Similar to `array()`, but returns the result as an [ES6\n * Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set).\n */\nexport function set<T>(decoder: Decoder<T>): Decoder<Set<T>> {\n return array(decoder).transform((items) => new Set(items));\n}\n\nconst ntuple = (n: number) =>\n poja.refine((arr) => arr.length === n, `Must be a ${n}-tuple`);\n\n/**\n * Accepts a tuple (an array with exactly _n_ items) of values accepted by the\n * _n_ given decoders.\n */\nexport function tuple<A>(a: Decoder<A>): Decoder<[A]>;\nexport function tuple<A, B>(a: Decoder<A>, b: Decoder<B>): Decoder<[A, B]>;\nexport function tuple<A, B, C>(\n a: Decoder<A>,\n b: Decoder<B>,\n c: Decoder<C>,\n): Decoder<[A, B, C]>;\nexport function tuple<A, B, C, D>(\n a: Decoder<A>,\n b: Decoder<B>,\n c: Decoder<C>,\n d: Decoder<D>,\n): Decoder<[A, B, C, D]>;\nexport function tuple<A, B, C, D, E>(\n a: Decoder<A>,\n b: Decoder<B>,\n c: Decoder<C>,\n d: Decoder<D>,\n e: Decoder<E>,\n): Decoder<[A, B, C, D, E]>;\nexport function tuple<A, B, C, D, E, F>(\n a: Decoder<A>,\n b: Decoder<B>,\n c: Decoder<C>,\n d: Decoder<D>,\n e: Decoder<E>,\n f: Decoder<F>,\n): Decoder<[A, B, C, D, E, F]>;\nexport function tuple(...decoders: readonly Decoder<unknown>[]): Decoder<unknown[]> {\n return ntuple(decoders.length).then((blobs, ok, err) => {\n let allOk = true;\n\n const rvs = decoders.map((decoder, i) => {\n const blob = blobs[i];\n const result = decoder.decode(blob);\n if (result.ok) {\n return result.value;\n } else {\n allOk = false;\n return result.error;\n }\n });\n\n if (allOk) {\n return ok(rvs);\n } else {\n // If a decoder error has happened while unwrapping all the\n // results, try to construct a good error message\n return err(annotate(rvs));\n }\n });\n}\n","import { define } from '../Decoder';\nimport type { Decoder } from '../Decoder';\n\n/**\n * Accepts any valid ``number`` value.\n *\n * This also accepts special values like `NaN` and `Infinity`. Unless you\n * want to deliberately accept those, you'll likely want to use the\n * `number` decoder instead.\n */\nexport const anyNumber: Decoder<number> = define((blob, ok, err) =>\n typeof blob === 'number' ? ok(blob) : err('Must be number'),\n);\n\n/**\n * Accepts finite numbers (can be integer or float values). Values `NaN`,\n * or positive and negative `Infinity` will get rejected.\n */\nexport const number: Decoder<number> = anyNumber.refine(\n (n) => Number.isFinite(n),\n 'Number must be finite',\n);\n\n/**\n * Accepts only finite whole numbers.\n */\nexport const integer: Decoder<number> = number.refine(\n (n) => Number.isInteger(n),\n 'Number must be an integer',\n);\n\n/**\n * Accepts only non-negative (zero or positive) finite numbers.\n */\nexport const positiveNumber: Decoder<number> = number\n .refine((n) => n >= 0, 'Number must be positive')\n .transform(Math.abs); // Just here to handle the -0 case\n\n/**\n * Accepts only non-negative (zero or positive) finite whole numbers.\n */\nexport const positiveInteger: Decoder<number> = integer\n .refine((n) => n >= 0, 'Number must be positive')\n .transform(Math.abs); // Just here to handle the -0 case\n","import { define } from '../Decoder';\nimport { number } from './numbers';\nimport type { Decoder } from '../Decoder';\n\n/**\n * Accepts and returns booleans.\n */\nexport const boolean: Decoder<boolean> = define((blob, ok, err) => {\n return typeof blob === 'boolean' ? ok(blob) : err('Must be boolean');\n});\n\n/**\n * Accepts anything and will return its \"truth\" value. Will never reject.\n */\nexport const truthy: Decoder<boolean> = define((blob, ok, _) => ok(!!blob));\n\n/**\n * Accepts numbers, but return their boolean representation.\n */\nexport const numericBoolean: Decoder<boolean> = number.transform((n) => !!n);\n","import { define } from '../Decoder';\nimport { either } from './unions';\nimport { instanceOf } from './utilities';\nimport type { Decoder } from '../Decoder';\n\n/** Match groups in this regex:\n * \\1 - the scheme\n * \\2 - the username/password (optional)\n * \\3 - the host\n * \\4 - the port (optional)\n * \\5 - the path (optional)\n */\nconst url_re =\n /^([A-Za-z]{3,9}(?:[+][A-Za-z]{3,9})?):\\/\\/(?:([-;:&=+$,\\w]+)@)?(?:([A-Za-z0-9.-]+)(?::([0-9]{2,5}))?)(\\/(?:[-+~%/.,\\w]*)?(?:\\?[-+=&;%@.,/\\w]*)?(?:#[.,!/\\w]*)?)?$/;\n\n/**\n * Accepts and returns strings.\n */\nexport const string: Decoder<string> = define((blob, ok, err) =>\n typeof blob === 'string' ? ok(blob) : err('Must be string'),\n);\n\n/**\n * Like `string`, but will reject the empty string or strings containing only whitespace.\n */\nexport const nonEmptyString: Decoder<string> = regex(/\\S/, 'Must be non-empty string');\n\n/**\n * Accepts and returns strings that match the given regular expression.\n */\nexport function regex(regex: RegExp, msg: string): Decoder<string> {\n return string.refine((s) => regex.test(s), msg);\n}\n\n/**\n * Accepts and returns strings that are syntactically valid email addresses.\n * (This will not mean that the email address actually exist.)\n */\nexport const email: Decoder<string> = regex(\n // The almost perfect email regex, taken from https://emailregex.com/\n /^(([^<>()[\\]\\\\.,;:\\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,}))$/,\n 'Must be email',\n);\n\n/**\n * Accepts strings that are valid URLs, returns the value as a URL instance.\n */\nexport const url: Decoder<URL> = either(\n regex(url_re, 'Must be URL').transform((value) => new URL(value)),\n instanceOf(URL),\n);\n\n/**\n * Accepts strings that are valid URLs, but only HTTPS ones. Returns the value\n * as a URL instance.\n */\nexport const httpsUrl: Decoder<URL> = url.refine(\n (value) => value.protocol === 'https:',\n 'Must be an HTTPS URL',\n);\n\n/**\n * Accepts strings that are valid\n * [UUIDs](https://en.wikipedia.org/wiki/universally_unique_identifier)\n * (universally unique identifier).\n */\nexport const uuid: Decoder<string> = regex(\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,\n 'Must be uuid',\n);\n\n/**\n * Like `uuid`, but only accepts\n * [UUIDv1](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_%28date-time_and_MAC_address%29)\n * strings.\n */\nexport const uuidv1: Decoder<string> =\n // https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)\n uuid.refine((value) => value[14] === '1', 'Must be uuidv1');\n\n/**\n * Like `uuid`, but only accepts\n * [UUIDv4](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_%28random%29)\n * strings.\n */\nexport const uuidv4: Decoder<string> =\n // https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)\n uuid.refine((value) => value[14] === '4', 'Must be uuidv4');\n","import { asDate } from '../_utils';\nimport { define } from '../Decoder';\nimport { regex } from './strings';\nimport type { Decoder } from '../Decoder';\n\n// Only matches the shape. This \"over-matches\" some values that still aren't\n// valid dates (like 9999-99-99), but those will be caught by JS Date's\n// internal validations\nconst iso8601_re =\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:[.]\\d+)?(?:Z|[+-]\\d{2}:?\\d{2})$/;\n\n/**\n * Accepts and returns `Date` instances.\n */\nexport const date: Decoder<Date> = define((blob, ok, err) => {\n const date = asDate(blob);\n return date !== null ? ok(date) : err('Must be a Date');\n});\n\n/**\n * Accepts [ISO8601](https://en.wikipedia.org/wiki/ISO_8601)-formatted strings,\n * returns them as `Date` instances.\n *\n * This is very useful for working with dates in APIs: serialize them as\n * `.toISOString()` when sending, decode them with `iso8601` when receiving.\n */\nexport const iso8601: Decoder<Date> =\n // Input itself needs to match the ISO8601 regex...\n regex(iso8601_re, 'Must be ISO8601 format').transform(\n // Make sure it is a _valid_ date\n (value: string) => {\n const date = new Date(value);\n if (isNaN(date.getTime())) {\n throw new Error('Must be valid date/time value');\n }\n return date;\n },\n );\n","import { array } from './arrays';\nimport { boolean } from './booleans';\nimport { dict } from './objects';\nimport { either } from './unions';\nimport { lazy } from './utilities';\nimport { null_ } from './basics';\nimport { number } from './numbers';\nimport { string } from './strings';\nimport type { Decoder } from '../Decoder';\n\nexport type JSONValue = null | string | number | boolean | JSONObject | JSONArray;\nexport type JSONObject = { [key: string]: JSONValue | undefined };\nexport type JSONArray = JSONValue[];\n\n/**\n * Accepts objects that contain only valid JSON values.\n */\nexport const jsonObject: Decoder<JSONObject> = lazy(() => dict(json));\n\n/**\n * Accepts arrays that contain only valid JSON values.\n */\nexport const jsonArray: Decoder<JSONArray> = lazy(() => array(json));\n\n/**\n * Accepts any value that's a valid JSON value.\n *\n * In other words: any value returned by `JSON.parse()` should decode without\n * failure.\n *\n * ```typescript\n * type JSONValue =\n * | null\n * | string\n * | number\n * | boolean\n * | { [string]: JSONValue }\n * | JSONValue[]\n * ```\n */\nexport const json: Decoder<JSONValue> = either(\n null_,\n string,\n number,\n boolean,\n jsonObject,\n jsonArray,\n).describe('Must be valid JSON value');\n"]}
|
|
@@ -1,10 +1,64 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
interface ObjectAnnotation {
|
|
2
|
+
readonly type: 'object';
|
|
3
|
+
readonly fields: {
|
|
4
|
+
readonly [key: string]: Annotation;
|
|
5
|
+
};
|
|
6
|
+
readonly text?: string;
|
|
7
|
+
}
|
|
8
|
+
interface ArrayAnnotation {
|
|
9
|
+
readonly type: 'array';
|
|
10
|
+
readonly items: readonly Annotation[];
|
|
11
|
+
readonly text?: string;
|
|
12
|
+
}
|
|
13
|
+
interface ScalarAnnotation {
|
|
14
|
+
readonly type: 'scalar';
|
|
15
|
+
readonly value: unknown;
|
|
16
|
+
readonly text?: string;
|
|
17
|
+
}
|
|
18
|
+
interface FunctionAnnotation {
|
|
19
|
+
readonly type: 'function';
|
|
20
|
+
readonly text?: string;
|
|
21
|
+
}
|
|
22
|
+
interface CircularRefAnnotation {
|
|
23
|
+
readonly type: 'circular-ref';
|
|
24
|
+
readonly text?: string;
|
|
25
|
+
}
|
|
26
|
+
interface UnknownAnnotation {
|
|
27
|
+
readonly type: 'unknown';
|
|
28
|
+
readonly value: unknown;
|
|
29
|
+
readonly text?: string;
|
|
30
|
+
}
|
|
31
|
+
type Annotation = ObjectAnnotation | ArrayAnnotation | ScalarAnnotation | FunctionAnnotation | CircularRefAnnotation | UnknownAnnotation;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Result <value> <error>
|
|
35
|
+
* = Ok <value>
|
|
36
|
+
* | Err <error>
|
|
37
|
+
*/
|
|
38
|
+
type Ok<T> = {
|
|
39
|
+
readonly ok: true;
|
|
40
|
+
readonly value: T;
|
|
41
|
+
readonly error?: never;
|
|
42
|
+
};
|
|
43
|
+
type Err<E> = {
|
|
44
|
+
readonly ok: false;
|
|
45
|
+
readonly value?: never;
|
|
46
|
+
readonly error: E;
|
|
47
|
+
};
|
|
48
|
+
type Result<T, E> = Ok<T> | Err<E>;
|
|
49
|
+
/**
|
|
50
|
+
* Create a new Result instance representing a successful computation.
|
|
51
|
+
*/
|
|
52
|
+
declare function ok<T>(value: T): Ok<T>;
|
|
53
|
+
/**
|
|
54
|
+
* Create a new Result instance representing a failed computation.
|
|
55
|
+
*/
|
|
56
|
+
declare function err<E>(error: E): Err<E>;
|
|
3
57
|
|
|
4
58
|
type Scalar = string | number | boolean | symbol | undefined | null;
|
|
5
59
|
type DecodeResult<T> = Result<T, Annotation>;
|
|
6
60
|
type AcceptanceFn<T, InputT = unknown> = (blob: InputT, ok: (value: T) => DecodeResult<T>, err: (msg: string | Annotation) => DecodeResult<T>) => DecodeResult<T>;
|
|
7
|
-
|
|
61
|
+
interface Decoder<T> {
|
|
8
62
|
/**
|
|
9
63
|
* Verifies untrusted input. Either returns a value, or throws a decoding
|
|
10
64
|
* error.
|
|
@@ -44,7 +98,7 @@ type Decoder<T> = {
|
|
|
44
98
|
*/
|
|
45
99
|
then<V>(next: AcceptanceFn<V, T>): Decoder<V>;
|
|
46
100
|
peek_UNSTABLE<V>(next: AcceptanceFn<V, [unknown, T]>): Decoder<V>;
|
|
47
|
-
}
|
|
101
|
+
}
|
|
48
102
|
/**
|
|
49
103
|
* Helper type to return the "type" of a Decoder.
|
|
50
104
|
*
|
|
@@ -451,4 +505,8 @@ declare const positiveNumber: Decoder<number>;
|
|
|
451
505
|
*/
|
|
452
506
|
declare const positiveInteger: Decoder<number>;
|
|
453
507
|
|
|
454
|
-
|
|
508
|
+
type Formatter = (err: Annotation) => string | Error;
|
|
509
|
+
declare function formatInline(ann: Annotation): string;
|
|
510
|
+
declare function formatShort(ann: Annotation): string;
|
|
511
|
+
|
|
512
|
+
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, 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, number, numericBoolean, object, ok, oneOf, optional, poja, pojo, positiveInteger, positiveNumber, prep, regex, set, string, taggedUnion, truthy, tuple, undefined_, unknown, url, uuid, uuidv1, uuidv4 };
|