decoders 2.1.0 → 2.2.0-test2
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 +12 -12
- package/annotate-0PUmWHxH.d.ts +33 -0
- package/chunk-BPSZE2VX.js +13 -0
- package/chunk-RUMDX66L.js +179 -0
- package/dist/annotate-0PUmWHxH.d.mts +33 -0
- package/dist/annotate-0PUmWHxH.d.ts +33 -0
- package/dist/chunk-BPSZE2VX.js +13 -0
- package/dist/chunk-BPSZE2VX.js.map +1 -0
- package/dist/chunk-HBFFQIIN.mjs +13 -0
- package/dist/chunk-HBFFQIIN.mjs.map +1 -0
- package/dist/chunk-RUMDX66L.js +179 -0
- package/dist/chunk-RUMDX66L.js.map +1 -0
- package/dist/chunk-ZTKFAKRL.mjs +179 -0
- package/dist/chunk-ZTKFAKRL.mjs.map +1 -0
- package/dist/format.d.mts +9 -0
- package/dist/format.d.ts +9 -0
- package/dist/format.js +13 -0
- package/dist/format.js.map +1 -0
- package/dist/format.mjs +13 -0
- package/dist/format.mjs.map +1 -0
- package/dist/index.d.mts +454 -0
- package/dist/index.d.ts +454 -0
- package/dist/index.js +659 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +659 -0
- package/dist/index.mjs.map +1 -0
- package/dist/result.d.mts +26 -0
- package/dist/result.d.ts +26 -0
- package/dist/result.js +9 -0
- package/dist/result.js.map +1 -0
- package/dist/result.mjs +9 -0
- package/dist/result.mjs.map +1 -0
- package/format.d.ts +7 -4
- package/format.js +12 -116
- package/index.d.ts +454 -40
- package/index.js +659 -67
- package/package.json +163 -100
- package/result.d.ts +25 -15
- package/result.js +6 -18
- package/CHANGELOG.md +0 -670
- package/Decoder.d.ts +0 -94
- package/Decoder.js +0 -105
- package/Decoder.js.flow +0 -286
- package/Decoder.mjs +0 -101
- package/NotSupportedTSVersion.d.ts +0 -1
- package/_utils.d.ts +0 -9
- package/_utils.js +0 -80
- package/_utils.js.flow +0 -107
- package/_utils.mjs +0 -70
- package/annotate.d.ts +0 -62
- package/annotate.js +0 -145
- package/annotate.js.flow +0 -218
- package/annotate.mjs +0 -131
- package/format.js.flow +0 -128
- package/format.mjs +0 -110
- package/index.js.flow +0 -44
- package/index.mjs +0 -11
- package/lib/_helpers.d.ts +0 -79
- package/lib/arrays.d.ts +0 -59
- package/lib/arrays.js +0 -85
- package/lib/arrays.js.flow +0 -138
- package/lib/arrays.mjs +0 -75
- package/lib/basics.d.ts +0 -93
- package/lib/basics.js +0 -74
- package/lib/basics.js.flow +0 -124
- package/lib/basics.mjs +0 -60
- package/lib/booleans.d.ts +0 -16
- package/lib/booleans.js +0 -21
- package/lib/booleans.js.flow +0 -22
- package/lib/booleans.mjs +0 -15
- package/lib/dates.d.ts +0 -15
- package/lib/dates.js +0 -23
- package/lib/dates.js.flow +0 -40
- package/lib/dates.mjs +0 -17
- package/lib/json.d.ts +0 -35
- package/lib/json.js +0 -25
- package/lib/json.js.flow +0 -50
- package/lib/json.mjs +0 -18
- package/lib/numbers.d.ts +0 -31
- package/lib/numbers.js +0 -34
- package/lib/numbers.js.flow +0 -46
- package/lib/numbers.mjs +0 -25
- package/lib/objects.d.ts +0 -76
- package/lib/objects.js +0 -138
- package/lib/objects.js.flow +0 -238
- package/lib/objects.mjs +0 -128
- package/lib/strings.d.ts +0 -54
- package/lib/strings.js +0 -54
- package/lib/strings.js.flow +0 -90
- package/lib/strings.mjs +0 -40
- package/lib/unions.d.ts +0 -55
- package/lib/unions.js +0 -82
- package/lib/unions.js.flow +0 -155
- package/lib/unions.mjs +0 -75
- package/lib/utilities.d.ts +0 -40
- package/lib/utilities.js +0 -44
- package/lib/utilities.js.flow +0 -65
- package/lib/utilities.mjs +0 -35
- package/result.js.flow +0 -26
- package/result.mjs +0 -15
package/README.md
CHANGED
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/decoders)
|
|
4
4
|
[](https://github.com/nvie/decoders/actions)
|
|
5
|
-
[](https://coveralls.io/github/nvie/decoders?branch=main)
|
|
6
5
|
[](https://bundlephobia.com/result?p=decoders)
|
|
7
6
|
|
|
8
7
|
Elegant and battle-tested validation library for type-safe input data for
|
|
9
|
-
[TypeScript](https://www.typescriptlang.org/)
|
|
8
|
+
[TypeScript](https://www.typescriptlang.org/).
|
|
10
9
|
|
|
11
10
|
## Motivation
|
|
12
11
|
|
|
@@ -26,20 +25,20 @@ import { array, iso8601, number, object, optional, string } from 'decoders';
|
|
|
26
25
|
// Incoming data at runtime
|
|
27
26
|
//
|
|
28
27
|
const externalData = {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
id: 123,
|
|
29
|
+
name: 'Alison Roberts',
|
|
30
|
+
createdAt: '1994-01-11T12:26:37.024Z',
|
|
31
|
+
tags: ['foo', 'bar'],
|
|
33
32
|
};
|
|
34
33
|
|
|
35
34
|
//
|
|
36
35
|
// Write the decoder (= what you expect the data to look like)
|
|
37
36
|
//
|
|
38
37
|
const userDecoder = object({
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
id: number,
|
|
39
|
+
name: string,
|
|
40
|
+
createdAt: optional(iso8601),
|
|
41
|
+
tags: array(string),
|
|
43
42
|
});
|
|
44
43
|
|
|
45
44
|
//
|
|
@@ -133,8 +132,9 @@ const user = userDecoder.verify(externalData);
|
|
|
133
132
|
<div id="uuidv1"></div>
|
|
134
133
|
<div id="uuidv4"></div>
|
|
135
134
|
|
|
136
|
-
Documentation can be found on [https://decoders.cc](https://decoders.cc).
|
|
135
|
+
Documentation can be found on [https://decoders.cc](https://decoders.cc).
|
|
137
136
|
|
|
138
137
|
## Building your own decoders
|
|
139
138
|
|
|
140
|
-
There is a dedicated page in the docs that explains how to
|
|
139
|
+
There is a dedicated page in the docs that explains how to
|
|
140
|
+
[build your own decoders](https://decoders.cc/building-your-own.html) — it’s fun!
|
|
@@ -0,0 +1,33 @@
|
|
|
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
|
+
export type { Annotation as A };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/result.ts
|
|
2
|
+
function ok(value) {
|
|
3
|
+
return { ok: true, value, error: void 0 };
|
|
4
|
+
}
|
|
5
|
+
function err(error) {
|
|
6
|
+
return { ok: false, value: void 0, error };
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
exports.ok = ok; exports.err = err;
|
|
13
|
+
//# sourceMappingURL=chunk-BPSZE2VX.js.map
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// 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
|
+
}
|
|
66
|
+
|
|
67
|
+
// src/format.ts
|
|
68
|
+
function serializeString(s, width = 80) {
|
|
69
|
+
let ser = JSON.stringify(s);
|
|
70
|
+
if (ser.length <= width) {
|
|
71
|
+
return ser;
|
|
72
|
+
}
|
|
73
|
+
const truncated = `${s.substring(0, width - 15)}...`;
|
|
74
|
+
ser = `${JSON.stringify(truncated)} [truncated]`;
|
|
75
|
+
return ser;
|
|
76
|
+
}
|
|
77
|
+
function serializeArray(annotation, prefix) {
|
|
78
|
+
const { items } = annotation;
|
|
79
|
+
if (items.length === 0) {
|
|
80
|
+
return "[]";
|
|
81
|
+
}
|
|
82
|
+
const result = [];
|
|
83
|
+
for (const item of items) {
|
|
84
|
+
const [ser, ann] = serializeAnnotation(item, `${prefix}${INDENT}`);
|
|
85
|
+
result.push(`${prefix}${INDENT}${ser}${","}`);
|
|
86
|
+
if (ann !== void 0) {
|
|
87
|
+
result.push(indent(ann, `${prefix}${INDENT}`));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return ["[", ...result, `${prefix}]`].join("\n");
|
|
91
|
+
}
|
|
92
|
+
function serializeObject(annotation, prefix) {
|
|
93
|
+
const { fields } = annotation;
|
|
94
|
+
const fieldNames = Object.keys(fields);
|
|
95
|
+
if (fieldNames.length === 0) {
|
|
96
|
+
return "{}";
|
|
97
|
+
}
|
|
98
|
+
const result = [];
|
|
99
|
+
for (const key of fieldNames) {
|
|
100
|
+
const valueAnnotation = fields[key];
|
|
101
|
+
const kser = serializeValue(key);
|
|
102
|
+
const valPrefix = `${prefix}${INDENT}${" ".repeat(kser.length + 2)}`;
|
|
103
|
+
const [vser, vann] = serializeAnnotation(valueAnnotation, `${prefix}${INDENT}`);
|
|
104
|
+
result.push(`${prefix}${INDENT}${kser}: ${vser},`);
|
|
105
|
+
if (vann !== void 0) {
|
|
106
|
+
result.push(indent(vann, valPrefix));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return ["{", ...result, `${prefix}}`].join("\n");
|
|
110
|
+
}
|
|
111
|
+
function serializeValue(value) {
|
|
112
|
+
if (typeof value === "string") {
|
|
113
|
+
return serializeString(value);
|
|
114
|
+
} else if (typeof value === "number" || typeof value === "boolean") {
|
|
115
|
+
return value.toString();
|
|
116
|
+
} else if (value === null) {
|
|
117
|
+
return "null";
|
|
118
|
+
} else if (value === void 0) {
|
|
119
|
+
return "undefined";
|
|
120
|
+
} else {
|
|
121
|
+
const valueAsDate = asDate(value);
|
|
122
|
+
if (valueAsDate !== null) {
|
|
123
|
+
return `new Date(${JSON.stringify(valueAsDate.toISOString())})`;
|
|
124
|
+
} else if (value instanceof Date) {
|
|
125
|
+
return "(Invalid Date)";
|
|
126
|
+
} else {
|
|
127
|
+
return "(unserializable)";
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
function serializeAnnotation(ann, prefix = "") {
|
|
132
|
+
let serialized;
|
|
133
|
+
if (ann.type === "array") {
|
|
134
|
+
serialized = serializeArray(ann, prefix);
|
|
135
|
+
} else if (ann.type === "object") {
|
|
136
|
+
serialized = serializeObject(ann, prefix);
|
|
137
|
+
} else if (ann.type === "function") {
|
|
138
|
+
serialized = "<function>";
|
|
139
|
+
} else if (ann.type === "circular-ref") {
|
|
140
|
+
serialized = "<circular ref>";
|
|
141
|
+
} else if (ann.type === "unknown") {
|
|
142
|
+
serialized = "???";
|
|
143
|
+
} else {
|
|
144
|
+
serialized = serializeValue(ann.value);
|
|
145
|
+
}
|
|
146
|
+
const text = ann.text;
|
|
147
|
+
if (text !== void 0) {
|
|
148
|
+
const sep = "^".repeat(isMultiline(serialized) ? 1 : serialized.length);
|
|
149
|
+
return [serialized, [sep, text].join(isMultiline(text) ? "\n" : " ")];
|
|
150
|
+
} else {
|
|
151
|
+
return [serialized, void 0];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function formatInline(ann) {
|
|
155
|
+
const [serialized, annotation] = serializeAnnotation(ann);
|
|
156
|
+
if (annotation !== void 0) {
|
|
157
|
+
return `${serialized}
|
|
158
|
+
${annotation}`;
|
|
159
|
+
} else {
|
|
160
|
+
return serialized;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function formatShort(ann) {
|
|
164
|
+
return summarize(ann, []).join("\n");
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
exports.lazyval = lazyval; exports.subtract = subtract; exports.asDate = asDate; exports.isPojo = isPojo; exports.indent = indent; exports.summarize = summarize; exports.serializeValue = serializeValue; exports.serializeAnnotation = serializeAnnotation; exports.formatInline = formatInline; exports.formatShort = formatShort;
|
|
179
|
+
//# sourceMappingURL=chunk-RUMDX66L.js.map
|
|
@@ -0,0 +1,33 @@
|
|
|
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
|
+
export type { Annotation as A };
|
|
@@ -0,0 +1,33 @@
|
|
|
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
|
+
export type { Annotation as A };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/result.ts
|
|
2
|
+
function ok(value) {
|
|
3
|
+
return { ok: true, value, error: void 0 };
|
|
4
|
+
}
|
|
5
|
+
function err(error) {
|
|
6
|
+
return { ok: false, value: void 0, error };
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
exports.ok = ok; exports.err = err;
|
|
13
|
+
//# sourceMappingURL=chunk-BPSZE2VX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/result.ts"],"names":[],"mappings":";AAsBO,SAAS,GAAM,OAAiB;AACrC,SAAO,EAAE,IAAI,MAAM,OAAO,OAAO,OAAU;AAC7C;AAKO,SAAS,IAAO,OAAkB;AACvC,SAAO,EAAE,IAAI,OAAO,OAAO,QAAW,MAAM;AAC9C","sourcesContent":["/**\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"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/result.ts"],"sourcesContent":["/**\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"],"mappings":";AAsBO,SAAS,GAAM,OAAiB;AACrC,SAAO,EAAE,IAAI,MAAM,OAAO,OAAO,OAAU;AAC7C;AAKO,SAAS,IAAO,OAAkB;AACvC,SAAO,EAAE,IAAI,OAAO,OAAO,QAAW,MAAM;AAC9C;","names":[]}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// 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
|
+
}
|
|
66
|
+
|
|
67
|
+
// src/format.ts
|
|
68
|
+
function serializeString(s, width = 80) {
|
|
69
|
+
let ser = JSON.stringify(s);
|
|
70
|
+
if (ser.length <= width) {
|
|
71
|
+
return ser;
|
|
72
|
+
}
|
|
73
|
+
const truncated = `${s.substring(0, width - 15)}...`;
|
|
74
|
+
ser = `${JSON.stringify(truncated)} [truncated]`;
|
|
75
|
+
return ser;
|
|
76
|
+
}
|
|
77
|
+
function serializeArray(annotation, prefix) {
|
|
78
|
+
const { items } = annotation;
|
|
79
|
+
if (items.length === 0) {
|
|
80
|
+
return "[]";
|
|
81
|
+
}
|
|
82
|
+
const result = [];
|
|
83
|
+
for (const item of items) {
|
|
84
|
+
const [ser, ann] = serializeAnnotation(item, `${prefix}${INDENT}`);
|
|
85
|
+
result.push(`${prefix}${INDENT}${ser}${","}`);
|
|
86
|
+
if (ann !== void 0) {
|
|
87
|
+
result.push(indent(ann, `${prefix}${INDENT}`));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return ["[", ...result, `${prefix}]`].join("\n");
|
|
91
|
+
}
|
|
92
|
+
function serializeObject(annotation, prefix) {
|
|
93
|
+
const { fields } = annotation;
|
|
94
|
+
const fieldNames = Object.keys(fields);
|
|
95
|
+
if (fieldNames.length === 0) {
|
|
96
|
+
return "{}";
|
|
97
|
+
}
|
|
98
|
+
const result = [];
|
|
99
|
+
for (const key of fieldNames) {
|
|
100
|
+
const valueAnnotation = fields[key];
|
|
101
|
+
const kser = serializeValue(key);
|
|
102
|
+
const valPrefix = `${prefix}${INDENT}${" ".repeat(kser.length + 2)}`;
|
|
103
|
+
const [vser, vann] = serializeAnnotation(valueAnnotation, `${prefix}${INDENT}`);
|
|
104
|
+
result.push(`${prefix}${INDENT}${kser}: ${vser},`);
|
|
105
|
+
if (vann !== void 0) {
|
|
106
|
+
result.push(indent(vann, valPrefix));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return ["{", ...result, `${prefix}}`].join("\n");
|
|
110
|
+
}
|
|
111
|
+
function serializeValue(value) {
|
|
112
|
+
if (typeof value === "string") {
|
|
113
|
+
return serializeString(value);
|
|
114
|
+
} else if (typeof value === "number" || typeof value === "boolean") {
|
|
115
|
+
return value.toString();
|
|
116
|
+
} else if (value === null) {
|
|
117
|
+
return "null";
|
|
118
|
+
} else if (value === void 0) {
|
|
119
|
+
return "undefined";
|
|
120
|
+
} else {
|
|
121
|
+
const valueAsDate = asDate(value);
|
|
122
|
+
if (valueAsDate !== null) {
|
|
123
|
+
return `new Date(${JSON.stringify(valueAsDate.toISOString())})`;
|
|
124
|
+
} else if (value instanceof Date) {
|
|
125
|
+
return "(Invalid Date)";
|
|
126
|
+
} else {
|
|
127
|
+
return "(unserializable)";
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
function serializeAnnotation(ann, prefix = "") {
|
|
132
|
+
let serialized;
|
|
133
|
+
if (ann.type === "array") {
|
|
134
|
+
serialized = serializeArray(ann, prefix);
|
|
135
|
+
} else if (ann.type === "object") {
|
|
136
|
+
serialized = serializeObject(ann, prefix);
|
|
137
|
+
} else if (ann.type === "function") {
|
|
138
|
+
serialized = "<function>";
|
|
139
|
+
} else if (ann.type === "circular-ref") {
|
|
140
|
+
serialized = "<circular ref>";
|
|
141
|
+
} else if (ann.type === "unknown") {
|
|
142
|
+
serialized = "???";
|
|
143
|
+
} else {
|
|
144
|
+
serialized = serializeValue(ann.value);
|
|
145
|
+
}
|
|
146
|
+
const text = ann.text;
|
|
147
|
+
if (text !== void 0) {
|
|
148
|
+
const sep = "^".repeat(isMultiline(serialized) ? 1 : serialized.length);
|
|
149
|
+
return [serialized, [sep, text].join(isMultiline(text) ? "\n" : " ")];
|
|
150
|
+
} else {
|
|
151
|
+
return [serialized, void 0];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function formatInline(ann) {
|
|
155
|
+
const [serialized, annotation] = serializeAnnotation(ann);
|
|
156
|
+
if (annotation !== void 0) {
|
|
157
|
+
return `${serialized}
|
|
158
|
+
${annotation}`;
|
|
159
|
+
} else {
|
|
160
|
+
return serialized;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function formatShort(ann) {
|
|
164
|
+
return summarize(ann, []).join("\n");
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
exports.lazyval = lazyval; exports.subtract = subtract; exports.asDate = asDate; exports.isPojo = isPojo; exports.indent = indent; exports.summarize = summarize; exports.serializeValue = serializeValue; exports.serializeAnnotation = serializeAnnotation; exports.formatInline = formatInline; exports.formatShort = formatShort;
|
|
179
|
+
//# sourceMappingURL=chunk-RUMDX66L.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/_utils.ts","../src/format.ts"],"names":["ann"],"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 { 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"]}
|