@fncts/base 0.0.33 → 0.0.35
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/_cjs/collection/immutable/Conc/api.cjs +1 -4
- package/_cjs/collection/immutable/Conc/api.cjs.map +1 -1
- package/_cjs/collection/immutable/HashMap/api.cjs +4 -7
- package/_cjs/collection/immutable/HashMap/api.cjs.map +1 -1
- package/_cjs/collection/immutable/HashSet/api.cjs +4 -7
- package/_cjs/collection/immutable/HashSet/api.cjs.map +1 -1
- package/_cjs/collection/immutable/ImmutableArray/api.cjs +6 -9
- package/_cjs/collection/immutable/ImmutableArray/api.cjs.map +1 -1
- package/_cjs/collection/immutable/ImmutableArray/instances.cjs.map +1 -1
- package/_cjs/control/Pure/api.cjs +8 -20
- package/_cjs/control/Pure/api.cjs.map +1 -1
- package/_cjs/data/Cause/api.cjs +2 -8
- package/_cjs/data/Cause/api.cjs.map +1 -1
- package/_cjs/data/Data.cjs +121 -0
- package/_cjs/data/Data.cjs.map +1 -0
- package/_cjs/data/Datum/api.cjs +2 -8
- package/_cjs/data/Datum/api.cjs.map +1 -1
- package/_cjs/data/DatumEither/api.cjs +2 -8
- package/_cjs/data/DatumEither/api.cjs.map +1 -1
- package/_cjs/data/Either/api.cjs +6 -24
- package/_cjs/data/Either/api.cjs.map +1 -1
- package/_cjs/data/Either/definition.cjs +1 -0
- package/_cjs/data/Either/definition.cjs.map +1 -1
- package/_cjs/data/Either/destructors.cjs +3 -3
- package/_cjs/data/Either/destructors.cjs.map +1 -1
- package/_cjs/data/Either/instances.cjs +7 -27
- package/_cjs/data/Either/instances.cjs.map +1 -1
- package/_cjs/data/EitherT/api.cjs +2 -8
- package/_cjs/data/EitherT/api.cjs.map +1 -1
- package/_cjs/data/Exit/api.cjs +3 -3
- package/_cjs/data/Exit/api.cjs.map +1 -1
- package/_cjs/data/Exit/constructors.cjs +1 -4
- package/_cjs/data/Exit/constructors.cjs.map +1 -1
- package/_cjs/data/Exit/definition.cjs +2 -0
- package/_cjs/data/Exit/definition.cjs.map +1 -1
- package/_cjs/data/Guard/api.cjs +4 -2
- package/_cjs/data/Guard/api.cjs.map +1 -1
- package/_cjs/data/Maybe/api.cjs +1 -4
- package/_cjs/data/Maybe/api.cjs.map +1 -1
- package/_cjs/data/Maybe/definition.cjs +1 -0
- package/_cjs/data/Maybe/definition.cjs.map +1 -1
- package/_cjs/data/Maybe/instances.cjs +13 -46
- package/_cjs/data/Maybe/instances.cjs.map +1 -1
- package/_cjs/data/Showable/show.cjs.map +1 -1
- package/_cjs/data/Tag/definition.cjs +8 -0
- package/_cjs/data/Tag/definition.cjs.map +1 -1
- package/_cjs/data/These/instances.cjs +0 -11
- package/_cjs/data/These/instances.cjs.map +1 -1
- package/_cjs/json/EitherJson.cjs +0 -18
- package/_cjs/json/EitherJson.cjs.map +1 -1
- package/_cjs/json/MaybeJson.cjs +0 -16
- package/_cjs/json/MaybeJson.cjs.map +1 -1
- package/_cjs/json/TheseJson.cjs +0 -22
- package/_cjs/json/TheseJson.cjs.map +1 -1
- package/_cjs/optics/Optional/definition.cjs +1 -4
- package/_cjs/optics/Optional/definition.cjs.map +1 -1
- package/_cjs/optics/Prism/definition.cjs +1 -4
- package/_cjs/optics/Prism/definition.cjs.map +1 -1
- package/_cjs/typeclass/MonadExcept.cjs +1 -4
- package/_cjs/typeclass/MonadExcept.cjs.map +1 -1
- package/_mjs/collection/immutable/Conc/api.mjs +1 -4
- package/_mjs/collection/immutable/Conc/api.mjs.map +1 -1
- package/_mjs/collection/immutable/HashMap/api.mjs +4 -7
- package/_mjs/collection/immutable/HashMap/api.mjs.map +1 -1
- package/_mjs/collection/immutable/HashSet/api.mjs +4 -7
- package/_mjs/collection/immutable/HashSet/api.mjs.map +1 -1
- package/_mjs/collection/immutable/ImmutableArray/api.mjs +6 -9
- package/_mjs/collection/immutable/ImmutableArray/api.mjs.map +1 -1
- package/_mjs/collection/immutable/ImmutableArray/instances.mjs.map +1 -1
- package/_mjs/control/Pure/api.mjs +8 -20
- package/_mjs/control/Pure/api.mjs.map +1 -1
- package/_mjs/data/Cause/api.mjs +2 -8
- package/_mjs/data/Cause/api.mjs.map +1 -1
- package/_mjs/data/Data.mjs +110 -0
- package/_mjs/data/Data.mjs.map +1 -0
- package/_mjs/data/Datum/api.mjs +2 -8
- package/_mjs/data/Datum/api.mjs.map +1 -1
- package/_mjs/data/DatumEither/api.mjs +2 -8
- package/_mjs/data/DatumEither/api.mjs.map +1 -1
- package/_mjs/data/Either/api.mjs +6 -24
- package/_mjs/data/Either/api.mjs.map +1 -1
- package/_mjs/data/Either/definition.mjs +1 -0
- package/_mjs/data/Either/definition.mjs.map +1 -1
- package/_mjs/data/Either/destructors.mjs +3 -3
- package/_mjs/data/Either/destructors.mjs.map +1 -1
- package/_mjs/data/Either/instances.mjs +6 -25
- package/_mjs/data/Either/instances.mjs.map +1 -1
- package/_mjs/data/EitherT/api.mjs +2 -8
- package/_mjs/data/EitherT/api.mjs.map +1 -1
- package/_mjs/data/Exit/api.mjs +2 -2
- package/_mjs/data/Exit/api.mjs.map +1 -1
- package/_mjs/data/Exit/constructors.mjs +1 -4
- package/_mjs/data/Exit/constructors.mjs.map +1 -1
- package/_mjs/data/Exit/definition.mjs +2 -0
- package/_mjs/data/Exit/definition.mjs.map +1 -1
- package/_mjs/data/Guard/api.mjs +5 -3
- package/_mjs/data/Guard/api.mjs.map +1 -1
- package/_mjs/data/Maybe/api.mjs +1 -4
- package/_mjs/data/Maybe/api.mjs.map +1 -1
- package/_mjs/data/Maybe/definition.mjs +1 -0
- package/_mjs/data/Maybe/definition.mjs.map +1 -1
- package/_mjs/data/Maybe/instances.mjs +0 -31
- package/_mjs/data/Maybe/instances.mjs.map +1 -1
- package/_mjs/data/Showable/show.mjs.map +1 -1
- package/_mjs/data/Tag/definition.mjs +7 -0
- package/_mjs/data/Tag/definition.mjs.map +1 -1
- package/_mjs/data/These/instances.mjs +0 -10
- package/_mjs/data/These/instances.mjs.map +1 -1
- package/_mjs/json/EitherJson.mjs +0 -15
- package/_mjs/json/EitherJson.mjs.map +1 -1
- package/_mjs/json/MaybeJson.mjs +0 -13
- package/_mjs/json/MaybeJson.mjs.map +1 -1
- package/_mjs/json/TheseJson.mjs +0 -19
- package/_mjs/json/TheseJson.mjs.map +1 -1
- package/_mjs/optics/Optional/definition.mjs +1 -4
- package/_mjs/optics/Optional/definition.mjs.map +1 -1
- package/_mjs/optics/Prism/definition.mjs +1 -4
- package/_mjs/optics/Prism/definition.mjs.map +1 -1
- package/_mjs/typeclass/MonadExcept.mjs +1 -4
- package/_mjs/typeclass/MonadExcept.mjs.map +1 -1
- package/_src/collection/immutable/Conc/api.ts +4 -4
- package/_src/collection/immutable/HashMap/api.ts +4 -4
- package/_src/collection/immutable/HashSet/api.ts +4 -4
- package/_src/collection/immutable/ImmutableArray/api.ts +4 -4
- package/_src/collection/immutable/ImmutableArray/instances.ts +0 -2
- package/_src/control/Pure/api.ts +4 -7
- package/_src/control.ts +0 -2
- package/_src/data/Cause/api.ts +8 -8
- package/_src/data/Data.ts +144 -0
- package/_src/data/Datum/api.ts +8 -8
- package/_src/data/DatumEither/api.ts +8 -8
- package/_src/data/Either/api.ts +18 -18
- package/_src/data/Either/definition.ts +2 -1
- package/_src/data/Either/destructors.ts +3 -3
- package/_src/data/Either/instances.ts +12 -31
- package/_src/data/EitherT/api.ts +8 -8
- package/_src/data/Exit/api.ts +2 -2
- package/_src/data/Exit/constructors.ts +1 -1
- package/_src/data/Exit/definition.ts +2 -0
- package/_src/data/Guard/api.ts +6 -3
- package/_src/data/Maybe/api.ts +4 -4
- package/_src/data/Maybe/definition.ts +1 -0
- package/_src/data/Maybe/instances.ts +0 -39
- package/_src/data/Showable/show.ts +1 -1
- package/_src/data/Tag/definition.ts +8 -0
- package/_src/data/These/instances.ts +0 -22
- package/_src/data.ts +1 -0
- package/_src/global.ts +0 -8
- package/_src/json/EitherJson.ts +0 -7
- package/_src/json/MaybeJson.ts +0 -7
- package/_src/json/TheseJson.ts +0 -7
- package/_src/optics/Optional/definition.ts +4 -4
- package/_src/optics/Prism/definition.ts +1 -1
- package/_src/typeclass/MonadExcept.ts +1 -1
- package/control.d.ts +0 -2
- package/data/Data.d.ts +31 -0
- package/data/Either/definition.d.ts +2 -1
- package/data/Either/destructors.d.ts +1 -4
- package/data/Either/instances.d.ts +0 -6
- package/data/Exit/api.d.ts +2 -2
- package/data/Exit/definition.d.ts +2 -0
- package/data/Guard/api.d.ts +1 -2
- package/data/Maybe/definition.d.ts +1 -0
- package/data/Maybe/instances.d.ts +0 -12
- package/data/Showable/show.d.ts +1 -1
- package/data/Tag/definition.d.ts +5 -0
- package/data/These/instances.d.ts +0 -6
- package/data.d.ts +1 -0
- package/global.d.ts +0 -8
- package/json/EitherJson.d.ts +0 -6
- package/json/MaybeJson.d.ts +0 -6
- package/json/TheseJson.d.ts +0 -6
- package/package.json +2 -2
- package/_cjs/control/CompletablePromise.cjs +0 -21
- package/_cjs/control/CompletablePromise.cjs.map +0 -1
- package/_cjs/control/InterruptiblePromise.cjs +0 -23
- package/_cjs/control/InterruptiblePromise.cjs.map +0 -1
- package/_cjs/data/DecodeError/definition.cjs +0 -240
- package/_cjs/data/DecodeError/definition.cjs.map +0 -1
- package/_cjs/data/DecodeError/instances.cjs +0 -6
- package/_cjs/data/DecodeError/instances.cjs.map +0 -1
- package/_cjs/data/DecodeError.cjs +0 -28
- package/_cjs/data/DecodeError.cjs.map +0 -1
- package/_cjs/data/Decoder/api.cjs +0 -572
- package/_cjs/data/Decoder/api.cjs.map +0 -1
- package/_cjs/data/Decoder/definition.cjs +0 -30
- package/_cjs/data/Decoder/definition.cjs.map +0 -1
- package/_cjs/data/Decoder.cjs +0 -28
- package/_cjs/data/Decoder.cjs.map +0 -1
- package/_cjs/data/Encoder/api.cjs +0 -315
- package/_cjs/data/Encoder/api.cjs.map +0 -1
- package/_cjs/data/Encoder/definition.cjs +0 -22
- package/_cjs/data/Encoder/definition.cjs.map +0 -1
- package/_cjs/data/Encoder.cjs +0 -28
- package/_cjs/data/Encoder.cjs.map +0 -1
- package/_mjs/control/CompletablePromise.mjs +0 -15
- package/_mjs/control/CompletablePromise.mjs.map +0 -1
- package/_mjs/control/InterruptiblePromise.mjs +0 -15
- package/_mjs/control/InterruptiblePromise.mjs.map +0 -1
- package/_mjs/data/DecodeError/definition.mjs +0 -209
- package/_mjs/data/DecodeError/definition.mjs.map +0 -1
- package/_mjs/data/DecodeError/instances.mjs +0 -2
- package/_mjs/data/DecodeError/instances.mjs.map +0 -1
- package/_mjs/data/DecodeError.mjs +0 -5
- package/_mjs/data/DecodeError.mjs.map +0 -1
- package/_mjs/data/Decoder/api.mjs +0 -542
- package/_mjs/data/Decoder/api.mjs.map +0 -1
- package/_mjs/data/Decoder/definition.mjs +0 -22
- package/_mjs/data/Decoder/definition.mjs.map +0 -1
- package/_mjs/data/Decoder.mjs +0 -5
- package/_mjs/data/Decoder.mjs.map +0 -1
- package/_mjs/data/Encoder/api.mjs +0 -279
- package/_mjs/data/Encoder/api.mjs.map +0 -1
- package/_mjs/data/Encoder/definition.mjs +0 -15
- package/_mjs/data/Encoder/definition.mjs.map +0 -1
- package/_mjs/data/Encoder.mjs +0 -5
- package/_mjs/data/Encoder.mjs.map +0 -1
- package/_src/control/CompletablePromise.ts +0 -23
- package/_src/control/InterruptiblePromise.ts +0 -23
- package/_src/data/DecodeError/definition.ts +0 -267
- package/_src/data/DecodeError/instances.ts +0 -0
- package/_src/data/DecodeError.ts +0 -5
- package/_src/data/Decoder/api.ts +0 -696
- package/_src/data/Decoder/definition.ts +0 -31
- package/_src/data/Decoder.ts +0 -5
- package/_src/data/Encoder/api.ts +0 -381
- package/_src/data/Encoder/definition.ts +0 -16
- package/_src/data/Encoder.ts +0 -5
- package/control/CompletablePromise.d.ts +0 -13
- package/control/InterruptiblePromise.d.ts +0 -12
- package/data/DecodeError/definition.d.ts +0 -148
- package/data/DecodeError/instances.d.ts +0 -1
- package/data/DecodeError.d.ts +0 -2
- package/data/Decoder/api.d.ts +0 -214
- package/data/Decoder/definition.d.ts +0 -27
- package/data/Decoder.d.ts +0 -2
- package/data/Encoder/api.d.ts +0 -214
- package/data/Encoder/definition.d.ts +0 -16
- package/data/Encoder.d.ts +0 -2
package/_src/data/Decoder/api.ts
DELETED
@@ -1,696 +0,0 @@
|
|
1
|
-
import type { Brand, Validation } from "@fncts/base/data/Branded";
|
2
|
-
import type { DecodeError } from "@fncts/base/data/DecodeError";
|
3
|
-
import type { Literal } from "@fncts/typelevel/Any";
|
4
|
-
import type { Check } from "@fncts/typelevel/Check";
|
5
|
-
import type { OptionalKeys, RequiredKeys } from "@fncts/typelevel/Object";
|
6
|
-
|
7
|
-
import { BrandedError } from "@fncts/base/data/DecodeError";
|
8
|
-
import { EmptyError } from "@fncts/base/data/DecodeError";
|
9
|
-
import { OptionalIndexError } from "@fncts/base/data/DecodeError";
|
10
|
-
import {
|
11
|
-
CompoundError,
|
12
|
-
LiteralError,
|
13
|
-
MemberError,
|
14
|
-
MissingKeyError,
|
15
|
-
OptionalKeyError,
|
16
|
-
PrimitiveError,
|
17
|
-
RequiredKeyError,
|
18
|
-
UnionError,
|
19
|
-
} from "@fncts/base/data/DecodeError";
|
20
|
-
import { Decoder } from "@fncts/base/data/Decoder/definition";
|
21
|
-
import { pipe } from "@fncts/base/data/function";
|
22
|
-
import { isNull, isUndefined } from "@fncts/base/util/predicates";
|
23
|
-
|
24
|
-
/**
|
25
|
-
* @tsplus pipeable fncts.Decoder __call
|
26
|
-
*/
|
27
|
-
export function decode(input: unknown) {
|
28
|
-
return <A>(self: Decoder<A>): These<DecodeError, A> => {
|
29
|
-
return self.decode(input);
|
30
|
-
};
|
31
|
-
}
|
32
|
-
|
33
|
-
export function fromGuard<A>(guard: Guard<A>, onFalse: (i: unknown) => DecodeError, label: string): Decoder<A> {
|
34
|
-
return Decoder((a) => (guard.is(a) ? These.right(a) : These.left(onFalse(a))), label);
|
35
|
-
}
|
36
|
-
|
37
|
-
/**
|
38
|
-
* @tsplus implicit
|
39
|
-
*/
|
40
|
-
export const string: Decoder<string> = fromGuard(String.Guard, (u) => new PrimitiveError(u, "string"), "string");
|
41
|
-
|
42
|
-
/**
|
43
|
-
* @tsplus implicit
|
44
|
-
*/
|
45
|
-
export const number: Decoder<number> = fromGuard(Number.Guard, (u) => new PrimitiveError(u, "number"), "number");
|
46
|
-
|
47
|
-
/**
|
48
|
-
* @tsplus implicit
|
49
|
-
*/
|
50
|
-
export const boolean: Decoder<boolean> = fromGuard(Boolean.Guard, (u) => new PrimitiveError(u, "boolean"), "boolean");
|
51
|
-
|
52
|
-
/**
|
53
|
-
* @tsplus implicit
|
54
|
-
*/
|
55
|
-
export const bigint: Decoder<bigint> = fromGuard(BigInt.Guard, (u) => new PrimitiveError(u, "bigint"), "bigint");
|
56
|
-
|
57
|
-
/**
|
58
|
-
* @tsplus static fncts.DecoderOps object
|
59
|
-
* @tsplus implicit
|
60
|
-
*/
|
61
|
-
export const object: Decoder<object> = fromGuard(Object.Guard, (u) => new PrimitiveError(u, "{}"), "{}");
|
62
|
-
|
63
|
-
/**
|
64
|
-
* @tsplus static fncts.DecoderOps unknown
|
65
|
-
*/
|
66
|
-
export const unknown: Decoder<unknown> = Decoder(These.right, "unknown");
|
67
|
-
|
68
|
-
/**
|
69
|
-
* @tsplus static fncts.DecoderOps null
|
70
|
-
* @tsplus implicit
|
71
|
-
*/
|
72
|
-
export const _null: Decoder<null> = fromGuard(Guard(isNull), (u) => new PrimitiveError(u, "null"), "null");
|
73
|
-
|
74
|
-
/**
|
75
|
-
* @tsplus static fncts.DecoderOps undefined
|
76
|
-
* @tsplus implicit
|
77
|
-
*/
|
78
|
-
export const _undefined: Decoder<undefined> = fromGuard(
|
79
|
-
Guard(isUndefined),
|
80
|
-
(u) => new PrimitiveError(u, "undefined"),
|
81
|
-
"undefined",
|
82
|
-
);
|
83
|
-
|
84
|
-
/**
|
85
|
-
* @tsplus static fncts.DecoderOps nullable
|
86
|
-
*/
|
87
|
-
export function nullable<A>(/** @tsplus implicit local */ base: Decoder<A>): Decoder<A | null | undefined> {
|
88
|
-
return Derive();
|
89
|
-
}
|
90
|
-
|
91
|
-
/**
|
92
|
-
* @tsplus derive fncts.Decoder lazy
|
93
|
-
* @tsplus static fncts.DecoderOps lazy
|
94
|
-
*/
|
95
|
-
export function deriveLazy<A>(f: (_: Decoder<A>) => Decoder<A>): Decoder<A> {
|
96
|
-
let cached: Decoder<A> | undefined;
|
97
|
-
const decoder: Decoder<A> = Decoder((u) => {
|
98
|
-
if (!cached) {
|
99
|
-
cached = f(decoder);
|
100
|
-
}
|
101
|
-
return cached.decode(u);
|
102
|
-
}, "[Recursive]");
|
103
|
-
return decoder;
|
104
|
-
}
|
105
|
-
|
106
|
-
/**
|
107
|
-
* @tsplus static fncts.DecoderOps literal
|
108
|
-
*/
|
109
|
-
export function literal<A extends Literal>(value: A): Decoder<A> {
|
110
|
-
return Decoder(
|
111
|
-
(u) => (u === value ? These.right(u as A) : These.left(new LiteralError(u, Vector(value)))),
|
112
|
-
value.toString(),
|
113
|
-
);
|
114
|
-
}
|
115
|
-
|
116
|
-
/**
|
117
|
-
* @tsplus derive fncts.Decoder<_> 20
|
118
|
-
*/
|
119
|
-
export function deriveLiteral<A extends string | number | boolean>(
|
120
|
-
...[value]: Check<Check.IsLiteral<A> & Check.Not<Check.IsUnion<A>>> extends Check.True ? [value: A] : never
|
121
|
-
): Decoder<A> {
|
122
|
-
return Decoder.literal(value);
|
123
|
-
}
|
124
|
-
|
125
|
-
/**
|
126
|
-
* @tsplus static fncts.DecoderOps union
|
127
|
-
* @tsplus derive fncts.Decoder<|> 30
|
128
|
-
*/
|
129
|
-
export function union<A extends ReadonlyArray<unknown>>(
|
130
|
-
...elements: {
|
131
|
-
[K in keyof A]: Decoder<A[K]>;
|
132
|
-
}
|
133
|
-
): Decoder<A[number]> {
|
134
|
-
const label = elements.map((decoder) => decoder.label).join(" | ");
|
135
|
-
return Decoder((u) => {
|
136
|
-
const errors: Array<MemberError> = [];
|
137
|
-
for (const decoder of elements) {
|
138
|
-
const result = decoder.decode(u);
|
139
|
-
if (result.isLeft()) {
|
140
|
-
errors.push(new MemberError(decoder.label, result.left));
|
141
|
-
} else {
|
142
|
-
return These.rightOrBoth(result.leftMaybe, result.right);
|
143
|
-
}
|
144
|
-
}
|
145
|
-
return These.left(new UnionError(label, Vector.from(errors)));
|
146
|
-
}, label);
|
147
|
-
}
|
148
|
-
|
149
|
-
/**
|
150
|
-
* @tsplus static fncts.DecoderOps struct
|
151
|
-
*/
|
152
|
-
export function struct<A extends Record<string, any>>(fields: {
|
153
|
-
[K in keyof A]: Decoder<A[K]>;
|
154
|
-
}): Decoder<A> {
|
155
|
-
let label = "{";
|
156
|
-
let first = true;
|
157
|
-
for (const k in fields) {
|
158
|
-
if (first) {
|
159
|
-
label += ` ${k}: ${(fields[k] as Decoder<any>).label}`;
|
160
|
-
} else {
|
161
|
-
label += `, ${k}: ${(fields[k] as Decoder<any>).label}`;
|
162
|
-
}
|
163
|
-
first = false;
|
164
|
-
}
|
165
|
-
if (label.length > 1) {
|
166
|
-
label += " ";
|
167
|
-
}
|
168
|
-
label += "}";
|
169
|
-
|
170
|
-
return Decoder((u) => {
|
171
|
-
const recordResult = object.decode(u);
|
172
|
-
if (recordResult.isLeft()) {
|
173
|
-
return recordResult;
|
174
|
-
}
|
175
|
-
const input = recordResult.right;
|
176
|
-
let errored = false;
|
177
|
-
const errors: Array<RequiredKeyError | OptionalKeyError> = [];
|
178
|
-
const decoded = {} as A;
|
179
|
-
for (const key in fields) {
|
180
|
-
if (!(key in input)) {
|
181
|
-
errors.push(new RequiredKeyError(key, new MissingKeyError(key)));
|
182
|
-
errored = true;
|
183
|
-
} else {
|
184
|
-
// @ts-expect-error
|
185
|
-
const res = (fields[key] as Decoder<any>).decode(input[key as string]);
|
186
|
-
res.match2(
|
187
|
-
(e) => {
|
188
|
-
errored = true;
|
189
|
-
errors.push(new RequiredKeyError(key, e));
|
190
|
-
},
|
191
|
-
(warning, a) => {
|
192
|
-
decoded[key as keyof A] = a;
|
193
|
-
if (warning.isJust()) {
|
194
|
-
errors.push(new RequiredKeyError(key, warning.value));
|
195
|
-
}
|
196
|
-
},
|
197
|
-
);
|
198
|
-
}
|
199
|
-
}
|
200
|
-
if (errored) {
|
201
|
-
return These.left(new CompoundError("struct", Vector.from(errors)));
|
202
|
-
}
|
203
|
-
if (errors.length !== 0) {
|
204
|
-
return These.both(new CompoundError("struct", Vector.from(errors)), decoded);
|
205
|
-
}
|
206
|
-
return These.right(decoded);
|
207
|
-
}, label);
|
208
|
-
}
|
209
|
-
|
210
|
-
/**
|
211
|
-
* @tsplus static fncts.DecoderOps partial
|
212
|
-
*/
|
213
|
-
export function partial<A extends Record<string, any>>(fields: {
|
214
|
-
[K in keyof A]: Decoder<A[K]>;
|
215
|
-
}): Decoder<Partial<A>> {
|
216
|
-
let label = "{";
|
217
|
-
let first = true;
|
218
|
-
for (const k in fields) {
|
219
|
-
if (first) {
|
220
|
-
label += ` ${k}?: ${(fields[k] as Decoder<any>).label}`;
|
221
|
-
} else {
|
222
|
-
label += `, ${k}?: ${(fields[k] as Decoder<any>).label}`;
|
223
|
-
}
|
224
|
-
first = false;
|
225
|
-
}
|
226
|
-
if (label.length > 1) {
|
227
|
-
label += " ";
|
228
|
-
}
|
229
|
-
label += "}";
|
230
|
-
|
231
|
-
return Decoder((u) => {
|
232
|
-
const recordResult = object.decode(u);
|
233
|
-
if (recordResult.isLeft()) {
|
234
|
-
return recordResult;
|
235
|
-
}
|
236
|
-
const input = recordResult.right;
|
237
|
-
let errored = false;
|
238
|
-
const errors: Array<RequiredKeyError | OptionalKeyError> = [];
|
239
|
-
const decoded = {} as A;
|
240
|
-
for (const key in fields) {
|
241
|
-
// @ts-expect-error
|
242
|
-
if (key in input && typeof input[key as string] !== "undefined") {
|
243
|
-
// @ts-expect-error
|
244
|
-
const res = (fields[key] as Decoder<any>).decode(input[key as string]);
|
245
|
-
res.match2(
|
246
|
-
(e) => {
|
247
|
-
errored = true;
|
248
|
-
errors.push(new OptionalKeyError(key, e));
|
249
|
-
},
|
250
|
-
(warning, a) => {
|
251
|
-
decoded[key as keyof A] = a;
|
252
|
-
if (warning.isJust()) {
|
253
|
-
errors.push(new RequiredKeyError(key, warning.value));
|
254
|
-
}
|
255
|
-
},
|
256
|
-
);
|
257
|
-
}
|
258
|
-
}
|
259
|
-
if (errored) {
|
260
|
-
return These.left(new CompoundError("struct", Vector.from(errors)));
|
261
|
-
}
|
262
|
-
if (errors.length !== 0) {
|
263
|
-
return These.both(new CompoundError("struct", Vector.from(errors)), decoded);
|
264
|
-
}
|
265
|
-
return These.right(decoded);
|
266
|
-
}, label);
|
267
|
-
}
|
268
|
-
|
269
|
-
/**
|
270
|
-
* @tsplus derive fncts.Decoder<_> 20
|
271
|
-
*/
|
272
|
-
export function deriveStruct<A extends Record<string, any>>(
|
273
|
-
...[requiredFields, optionalFields]: Check<Check.IsStruct<A>> extends Check.True
|
274
|
-
? [
|
275
|
-
...[
|
276
|
-
requiredFields: {
|
277
|
-
[k in RequiredKeys<A>]: Decoder<A[k]>;
|
278
|
-
},
|
279
|
-
],
|
280
|
-
...([OptionalKeys<A>] extends [never]
|
281
|
-
? []
|
282
|
-
: [
|
283
|
-
optionalFields: {
|
284
|
-
[k in OptionalKeys<A>]: Decoder<NonNullable<A[k]>>;
|
285
|
-
},
|
286
|
-
]),
|
287
|
-
]
|
288
|
-
: never
|
289
|
-
): Decoder<A> {
|
290
|
-
let label = "{";
|
291
|
-
let first = true;
|
292
|
-
for (const k in requiredFields) {
|
293
|
-
if (first) {
|
294
|
-
// @ts-expect-error
|
295
|
-
label += ` ${k}: ${(requiredFields[k] as Decoder<any>).label}`;
|
296
|
-
} else {
|
297
|
-
// @ts-expect-error
|
298
|
-
label += `, ${k}: ${(requiredFields[k] as Decoder<any>).label}`;
|
299
|
-
}
|
300
|
-
first = false;
|
301
|
-
}
|
302
|
-
if (optionalFields) {
|
303
|
-
for (const k in optionalFields) {
|
304
|
-
if (first) {
|
305
|
-
label += ` ${k}?: ${(optionalFields[k] as Decoder<any>).label}`;
|
306
|
-
} else {
|
307
|
-
label += `, ${k}?: ${(optionalFields[k] as Decoder<any>).label}`;
|
308
|
-
}
|
309
|
-
}
|
310
|
-
}
|
311
|
-
if (label.length > 1) {
|
312
|
-
label += " ";
|
313
|
-
}
|
314
|
-
label += "}";
|
315
|
-
|
316
|
-
return Decoder((u) => {
|
317
|
-
const recordResult = object.decode(u);
|
318
|
-
if (recordResult.isLeft()) {
|
319
|
-
return recordResult;
|
320
|
-
}
|
321
|
-
const input = recordResult.right;
|
322
|
-
let errored = false;
|
323
|
-
const errors: Array<RequiredKeyError | OptionalKeyError> = [];
|
324
|
-
const decoded = {} as A;
|
325
|
-
for (const key in requiredFields) {
|
326
|
-
if (!(key in input)) {
|
327
|
-
errors.push(new RequiredKeyError(key, new MissingKeyError(key)));
|
328
|
-
errored = true;
|
329
|
-
} else {
|
330
|
-
// @ts-expect-error
|
331
|
-
const res = (requiredFields[key] as Decoder<any>).decode(input[key]);
|
332
|
-
res.match2(
|
333
|
-
(e) => {
|
334
|
-
errored = true;
|
335
|
-
errors.push(new RequiredKeyError(key, e));
|
336
|
-
},
|
337
|
-
(warning, a) => {
|
338
|
-
decoded[key as keyof A] = a;
|
339
|
-
if (warning.isJust()) {
|
340
|
-
errors.push(new RequiredKeyError(key, warning.value));
|
341
|
-
}
|
342
|
-
},
|
343
|
-
);
|
344
|
-
}
|
345
|
-
}
|
346
|
-
if (optionalFields) {
|
347
|
-
for (const key in optionalFields) {
|
348
|
-
// @ts-expect-error
|
349
|
-
if (key in input && typeof input[key as string] !== "undefined") {
|
350
|
-
// @ts-expect-error
|
351
|
-
const res = (optionalFields[key] as Decoder<any>).decode(input[key as string]);
|
352
|
-
res.match2(
|
353
|
-
(e) => {
|
354
|
-
errored = true;
|
355
|
-
errors.push(new OptionalKeyError(key, e));
|
356
|
-
},
|
357
|
-
(warning, a) => {
|
358
|
-
decoded[key as keyof A] = a;
|
359
|
-
if (warning.isJust()) {
|
360
|
-
errors.push(new RequiredKeyError(key, warning.value));
|
361
|
-
}
|
362
|
-
},
|
363
|
-
);
|
364
|
-
}
|
365
|
-
}
|
366
|
-
}
|
367
|
-
if (errored) {
|
368
|
-
return These.left(new CompoundError("struct", Vector.from(errors)));
|
369
|
-
}
|
370
|
-
if (errors.length !== 0) {
|
371
|
-
return These.both(new CompoundError("struct", Vector.from(errors)), decoded);
|
372
|
-
}
|
373
|
-
return These.right(decoded);
|
374
|
-
}, label);
|
375
|
-
}
|
376
|
-
|
377
|
-
/**
|
378
|
-
* @tsplus derive fncts.Decoder[fncts.Array]<_> 10
|
379
|
-
*/
|
380
|
-
export function deriveArray<A extends Array<any>>(
|
381
|
-
...[element]: [A] extends [Array<infer _A>]
|
382
|
-
? Check<Check.IsEqual<A, Array<_A>>> extends Check.True
|
383
|
-
? [element: Decoder<_A>]
|
384
|
-
: never
|
385
|
-
: never
|
386
|
-
): Decoder<A> {
|
387
|
-
return Decoder((u) => {
|
388
|
-
if (Array.isArray(u)) {
|
389
|
-
const errors = Vector.emptyPushable<DecodeError>();
|
390
|
-
let failed = false;
|
391
|
-
const out = Array(u.length);
|
392
|
-
for (let i = 0; i < u.length; i++) {
|
393
|
-
const decoded = element.decode(u[i]!);
|
394
|
-
decoded.match2(
|
395
|
-
(err) => {
|
396
|
-
failed = true;
|
397
|
-
errors.push(new OptionalIndexError(i, err));
|
398
|
-
},
|
399
|
-
(warning, value) => {
|
400
|
-
out[i] = value;
|
401
|
-
if (warning.isJust()) {
|
402
|
-
errors.push(warning.value);
|
403
|
-
}
|
404
|
-
},
|
405
|
-
);
|
406
|
-
}
|
407
|
-
if (failed) {
|
408
|
-
return These.left(new CompoundError("Array", errors));
|
409
|
-
}
|
410
|
-
return These.rightOrBoth(errors.length > 0 ? Just(new CompoundError("Array", errors)) : Nothing(), out as A);
|
411
|
-
}
|
412
|
-
return These.left(new PrimitiveError(u, "Array"));
|
413
|
-
}, `Array<${element.label}>`);
|
414
|
-
}
|
415
|
-
|
416
|
-
/**
|
417
|
-
* @tsplus static fncts.DecoderOps array
|
418
|
-
*/
|
419
|
-
export function array<A>(base: Decoder<A>): Decoder<Array<A>> {
|
420
|
-
return Derive();
|
421
|
-
}
|
422
|
-
|
423
|
-
/**
|
424
|
-
* @tsplus derive fncts.Decoder[fncts.ReadonlyArray]<_> 10
|
425
|
-
*/
|
426
|
-
export function deriveReadonlyArray<A extends ReadonlyArray<any>>(
|
427
|
-
...[element]: [A] extends [ReadonlyArray<infer _A>]
|
428
|
-
? Check<Check.IsEqual<A, ReadonlyArray<_A>>> extends Check.True
|
429
|
-
? [element: Decoder<_A>]
|
430
|
-
: never
|
431
|
-
: never
|
432
|
-
): Decoder<A> {
|
433
|
-
return Decoder((u) => deriveArray(element).decode(u) as These<DecodeError, A>, `ReadonlyArray<${element.label}>`);
|
434
|
-
}
|
435
|
-
|
436
|
-
/**
|
437
|
-
* @tsplus static fncts.DecoderOps readonlyArray
|
438
|
-
*/
|
439
|
-
export function readonlyArray<A>(base: Decoder<A>): Decoder<ReadonlyArray<A>> {
|
440
|
-
return Derive();
|
441
|
-
}
|
442
|
-
|
443
|
-
/**
|
444
|
-
* @tsplus derive fncts.Decoder<_> 15
|
445
|
-
*/
|
446
|
-
export function deriveRecord<A extends Record<string, any>>(
|
447
|
-
...[keyGuard, valueDecoder, requiredKeysRecord]: [A] extends [Record<infer X, infer Y>]
|
448
|
-
? Check<Check.Not<Check.IsUnion<A>> & Check.IsEqual<A, Record<X, Y>>> extends Check.True
|
449
|
-
? [
|
450
|
-
keyGuard: Guard<X>,
|
451
|
-
valueDecoder: Decoder<Y>,
|
452
|
-
requiredKeysRecord: {
|
453
|
-
[k in X]: 0;
|
454
|
-
},
|
455
|
-
]
|
456
|
-
: never
|
457
|
-
: never
|
458
|
-
): Decoder<A> {
|
459
|
-
return Decoder((u) => {
|
460
|
-
const recordResult = Derive<Decoder<object>>().decode(u);
|
461
|
-
if (recordResult.isLeft()) {
|
462
|
-
return recordResult;
|
463
|
-
}
|
464
|
-
const asRecord = recordResult.right;
|
465
|
-
const errors: Array<RequiredKeyError | OptionalKeyError> = [];
|
466
|
-
let errored = false;
|
467
|
-
const missing = new Set(Object.keys(requiredKeysRecord));
|
468
|
-
const res = {};
|
469
|
-
for (const k in asRecord) {
|
470
|
-
if (keyGuard.is(k)) {
|
471
|
-
// @ts-expect-error
|
472
|
-
const valueResult = valueDecoder.decode(asRecord[k]);
|
473
|
-
valueResult.match2(
|
474
|
-
(e) => {
|
475
|
-
errored = true;
|
476
|
-
errors.push(new (k in requiredKeysRecord ? RequiredKeyError : OptionalKeyError)(k, e));
|
477
|
-
},
|
478
|
-
(warning, a) => {
|
479
|
-
missing.delete(k);
|
480
|
-
// @ts-expect-error
|
481
|
-
res[k] = a;
|
482
|
-
if (warning.isJust()) {
|
483
|
-
errors.push(new (k in requiredKeysRecord ? RequiredKeyError : OptionalKeyError)(k, warning.value));
|
484
|
-
}
|
485
|
-
},
|
486
|
-
);
|
487
|
-
}
|
488
|
-
}
|
489
|
-
if (errored) {
|
490
|
-
return These.left(new CompoundError("record", Vector.from(errors)));
|
491
|
-
}
|
492
|
-
if (errors.length > 0) {
|
493
|
-
return These.both(new CompoundError("record", Vector.from(errors)), res as A);
|
494
|
-
}
|
495
|
-
if (missing.size > 0) {
|
496
|
-
return These.left(
|
497
|
-
new CompoundError(
|
498
|
-
"record",
|
499
|
-
Vector.from(missing).map((k) => new MissingKeyError(k)),
|
500
|
-
),
|
501
|
-
);
|
502
|
-
}
|
503
|
-
return These.right(res as A);
|
504
|
-
}, `Record<string, ${valueDecoder.label}>`);
|
505
|
-
}
|
506
|
-
|
507
|
-
/**
|
508
|
-
* @tsplus static fncts.DecoderOps record
|
509
|
-
*/
|
510
|
-
export function record<A>(codomain: Decoder<A>): Decoder<Record<string, A>> {
|
511
|
-
return Derive();
|
512
|
-
}
|
513
|
-
|
514
|
-
/**
|
515
|
-
* @tsplus derive fncts.Decoder[fncts.ImmutableArray]<_> 10
|
516
|
-
*/
|
517
|
-
export function deriveImmutableArray<A extends ImmutableArray<any>>(
|
518
|
-
...[array, elem]: [A] extends [ImmutableArray<infer _A>]
|
519
|
-
? Check<Check.IsEqual<A, ImmutableArray<_A>>> extends Check.True
|
520
|
-
? [array: Decoder<Array<_A>>, elem: Decoder<_A>]
|
521
|
-
: never
|
522
|
-
: never
|
523
|
-
): Decoder<A> {
|
524
|
-
return Decoder((u) => array.decode(u).map((as) => new ImmutableArray(as) as A), `ImmutableArray<${elem.label}>`);
|
525
|
-
}
|
526
|
-
|
527
|
-
/**
|
528
|
-
* @tsplus static fncts.DecoderOps immutableArray
|
529
|
-
*/
|
530
|
-
export function immutableArray<A>(base: Decoder<A>): Decoder<ImmutableArray<A>> {
|
531
|
-
return Derive();
|
532
|
-
}
|
533
|
-
|
534
|
-
/**
|
535
|
-
* @tsplus derive fncts.Decoder[fncts.ImmutableNonEmptyArray]<_> 10
|
536
|
-
*/
|
537
|
-
export function deriveImmutableNonEmptyArray<A extends ImmutableNonEmptyArray<any>>(
|
538
|
-
...[array, elem]: [A] extends [ImmutableNonEmptyArray<infer _A>]
|
539
|
-
? Check<Check.IsEqual<A, ImmutableNonEmptyArray<_A>>> extends Check.True
|
540
|
-
? [array: Decoder<Array<_A>>, elem: Decoder<_A>]
|
541
|
-
: never
|
542
|
-
: never
|
543
|
-
): Decoder<A> {
|
544
|
-
return Decoder(
|
545
|
-
(u) =>
|
546
|
-
array.decode(u).match2(These.left, (warn, as) => {
|
547
|
-
if (as.isNonEmpty()) {
|
548
|
-
return These.right(new ImmutableNonEmptyArray(as) as A);
|
549
|
-
} else {
|
550
|
-
const err = new EmptyError(as);
|
551
|
-
return warn.match(
|
552
|
-
() => These.left(err),
|
553
|
-
(err0) => These.left(new CompoundError(`ImmutableNonEmptyArray<${elem.label}>`, Vector(err0, err))),
|
554
|
-
);
|
555
|
-
}
|
556
|
-
}),
|
557
|
-
`ImmutableNonEmptyArray<${elem.label}>`,
|
558
|
-
);
|
559
|
-
}
|
560
|
-
|
561
|
-
/**
|
562
|
-
* @tsplus static fncts.DecoderOps immutableNonEmptyArray
|
563
|
-
*/
|
564
|
-
export function immutableNonEmptyArray<A>(base: Decoder<A>): Decoder<ImmutableNonEmptyArray<A>> {
|
565
|
-
return Derive();
|
566
|
-
}
|
567
|
-
|
568
|
-
/**
|
569
|
-
* @tsplus derive fncts.Decoder[fncts.Conc]<_> 10
|
570
|
-
*/
|
571
|
-
export function deriveConc<A extends Conc<any>>(
|
572
|
-
...[array, elem]: [A] extends [Conc<infer _A>]
|
573
|
-
? Check<Check.IsEqual<A, Conc<_A>>> extends Check.True
|
574
|
-
? [array: Decoder<Array<_A>>, elem: Decoder<_A>]
|
575
|
-
: never
|
576
|
-
: never
|
577
|
-
): Decoder<A> {
|
578
|
-
return Decoder((u) => array.decode(u).map((a) => Conc.from(a) as A), `Conc<${elem.label}>`);
|
579
|
-
}
|
580
|
-
|
581
|
-
/**
|
582
|
-
* @tsplus static fncts.DecoderOps conc
|
583
|
-
*/
|
584
|
-
export function conc<A>(base: Decoder<A>): Decoder<Conc<A>> {
|
585
|
-
return Derive();
|
586
|
-
}
|
587
|
-
|
588
|
-
/**
|
589
|
-
* @tsplus derive fncts.Decoder<_> 10
|
590
|
-
*/
|
591
|
-
export function deriveValidation<A extends Brand.Valid<any, any>>(
|
592
|
-
...[base, brands]: Check<Brand.IsValidated<A>> extends Check.True
|
593
|
-
? [
|
594
|
-
base: Decoder<Brand.Unbranded<A>>,
|
595
|
-
brands: {
|
596
|
-
[K in keyof A[Brand.valid] & string]: Validation<A[Brand.valid][K], K>;
|
597
|
-
},
|
598
|
-
]
|
599
|
-
: never
|
600
|
-
): Decoder<A> {
|
601
|
-
const label = "Brand<" + Object.keys(brands).join(" & ") + ">";
|
602
|
-
return Decoder(
|
603
|
-
(u) =>
|
604
|
-
base.decode(u).match2(These.left, (warning, value) => {
|
605
|
-
const failedBrands: Array<string> = [];
|
606
|
-
for (const brand in brands) {
|
607
|
-
if (!brands[brand]!.validate(value as any)) {
|
608
|
-
failedBrands.push(brand);
|
609
|
-
}
|
610
|
-
}
|
611
|
-
if (failedBrands.length > 0) {
|
612
|
-
const error = new BrandedError(label, Vector.from(failedBrands));
|
613
|
-
return warning.match(
|
614
|
-
() => These.left(error),
|
615
|
-
(warning) => These.left(new CompoundError(label, Vector(warning, error))),
|
616
|
-
);
|
617
|
-
}
|
618
|
-
return These.rightOrBoth(warning, value as A);
|
619
|
-
}),
|
620
|
-
label,
|
621
|
-
);
|
622
|
-
}
|
623
|
-
|
624
|
-
/**
|
625
|
-
* @tsplus static fncts.DecoderOps validation
|
626
|
-
*/
|
627
|
-
export function validation<A, B extends ReadonlyArray<Validation<A, any>>>(...validations: B) {
|
628
|
-
return (
|
629
|
-
base: Decoder<A>,
|
630
|
-
): Decoder<A & { [K in keyof B]: B[K] extends Validation<any, infer S> ? Brand.Valid<A, S> : never }[number]> =>
|
631
|
-
Decoder(
|
632
|
-
(u) =>
|
633
|
-
base.decode(u).match2(These.left, (warning, value) => {
|
634
|
-
let failed = false;
|
635
|
-
for (const validation of validations) {
|
636
|
-
if (!validation.validate(value)) {
|
637
|
-
failed = true;
|
638
|
-
}
|
639
|
-
}
|
640
|
-
if (failed) {
|
641
|
-
const error = new BrandedError(base.label, Vector());
|
642
|
-
return warning.match(
|
643
|
-
() => These.left(error),
|
644
|
-
(warning) => These.left(new CompoundError(base.label, Vector(warning, error))),
|
645
|
-
);
|
646
|
-
}
|
647
|
-
return These.rightOrBoth(
|
648
|
-
warning,
|
649
|
-
value as A & { [K in keyof B]: B[K] extends Validation<any, infer S> ? Brand.Valid<A, S> : never }[number],
|
650
|
-
);
|
651
|
-
}),
|
652
|
-
base.label,
|
653
|
-
);
|
654
|
-
}
|
655
|
-
|
656
|
-
/**
|
657
|
-
* @tsplus derive fncts.Decoder<_> 10
|
658
|
-
*/
|
659
|
-
export function deriveTuple<A extends ReadonlyArray<unknown>>(
|
660
|
-
...[components]: Check<Check.IsTuple<A>> extends Check.True ? [components: { [K in keyof A]: Decoder<A[K]> }] : never
|
661
|
-
): Decoder<A> {
|
662
|
-
const label = `[ ${components.map((d) => d.label).join(", ")} ]`;
|
663
|
-
return Decoder((u) => {
|
664
|
-
if (Array.isArray(u)) {
|
665
|
-
const errors = Vector.emptyPushable<DecodeError>();
|
666
|
-
let failed = false;
|
667
|
-
const out = Array(u.length);
|
668
|
-
for (let i = 0; i < components.length; i++) {
|
669
|
-
const decoded = components[i]!.decode(u[i]!);
|
670
|
-
decoded.match2(
|
671
|
-
(err) => {
|
672
|
-
failed = true;
|
673
|
-
errors.push(new OptionalIndexError(i, err));
|
674
|
-
},
|
675
|
-
(warning, value) => {
|
676
|
-
out[i] = value;
|
677
|
-
if (warning.isJust()) {
|
678
|
-
errors.push(warning.value);
|
679
|
-
}
|
680
|
-
},
|
681
|
-
);
|
682
|
-
}
|
683
|
-
if (failed) {
|
684
|
-
return These.left(new CompoundError("Array", errors));
|
685
|
-
}
|
686
|
-
}
|
687
|
-
return These.left(new PrimitiveError(u, "Array"));
|
688
|
-
}, label);
|
689
|
-
}
|
690
|
-
|
691
|
-
/**
|
692
|
-
* @tsplus static fncts.DecoderOps tuple
|
693
|
-
*/
|
694
|
-
export function tuple<A extends ReadonlyArray<unknown>>(...components: { [K in keyof A]: Decoder<A[K]> }): Decoder<A> {
|
695
|
-
return deriveTuple(components as [never]).unsafeCoerce();
|
696
|
-
}
|