@typed/guard 0.7.2 → 1.0.0-beta.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 +98 -0
- package/dist/index.d.ts +247 -3
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +176 -4
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +314 -0
- package/package.json +18 -24
- package/src/index.test.ts +370 -0
- package/src/index.ts +661 -3
- package/tsconfig.json +4 -26
- package/.nvmrc +0 -1
- package/biome.json +0 -36
- package/dist/ExtensibleFunction.d.ts +0 -1
- package/dist/ExtensibleFunction.js +0 -7
- package/dist/ExtensibleFunction.js.map +0 -1
- package/dist/Guard.d.ts +0 -143
- package/dist/Guard.js +0 -95
- package/dist/Guard.js.map +0 -1
- package/dist/Guardable.d.ts +0 -10
- package/dist/Guardable.js +0 -13
- package/dist/Guardable.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/readme.md +0 -199
- package/src/ExtensibleFunction.test.ts +0 -102
- package/src/ExtensibleFunction.ts +0 -8
- package/src/Guard.test.ts +0 -189
- package/src/Guard.ts +0 -536
- package/src/Guardable.test.ts +0 -18
- package/src/Guardable.ts +0 -22
package/src/index.ts
CHANGED
|
@@ -1,3 +1,661 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @since 1.0.0
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type * as Cause from "effect/Cause";
|
|
6
|
+
import * as Effect from "effect/Effect";
|
|
7
|
+
import { dual } from "effect/Function";
|
|
8
|
+
import type * as Layer from "effect/Layer";
|
|
9
|
+
import * as Option from "effect/Option";
|
|
10
|
+
import type * as Predicate from "effect/Predicate";
|
|
11
|
+
import * as Schema from "effect/Schema";
|
|
12
|
+
import type { ParseOptions } from "effect/SchemaAST";
|
|
13
|
+
import type * as ServiceMap from "effect/ServiceMap";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @since 1.0.0
|
|
17
|
+
*/
|
|
18
|
+
export type Guard<in I, out O, out E = never, out R = never> = (
|
|
19
|
+
input: I,
|
|
20
|
+
) => Effect.Effect<Option.Option<O>, E, R>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @since 1.0.0
|
|
24
|
+
*/
|
|
25
|
+
export namespace Guard {
|
|
26
|
+
/**
|
|
27
|
+
* @since 1.0.0
|
|
28
|
+
*/
|
|
29
|
+
export type Input<T> = [T] extends [Guard<infer I, infer _R, infer _E, infer _O>]
|
|
30
|
+
? I
|
|
31
|
+
: [T] extends [AsGuard<infer I, infer _R, infer _E, infer _O>]
|
|
32
|
+
? I
|
|
33
|
+
: never;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @since 1.0.0
|
|
37
|
+
*/
|
|
38
|
+
export type Services<T> = [T] extends [Guard<infer _I, infer _O, infer _E, infer R>]
|
|
39
|
+
? R
|
|
40
|
+
: [T] extends [AsGuard<infer _I, infer _O, infer _E, infer R>]
|
|
41
|
+
? R
|
|
42
|
+
: never;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @since 1.0.0
|
|
46
|
+
*/
|
|
47
|
+
export type Error<T> = [T] extends [Guard<infer _I, infer _O, infer E, infer _R>]
|
|
48
|
+
? E
|
|
49
|
+
: [T] extends [AsGuard<infer _I, infer _O, infer E, infer _R>]
|
|
50
|
+
? E
|
|
51
|
+
: never;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @since 1.0.0
|
|
55
|
+
*/
|
|
56
|
+
export type Output<T> = [T] extends [Guard<infer _I, infer O, infer _E, infer _R>]
|
|
57
|
+
? O
|
|
58
|
+
: [T] extends [AsGuard<infer _I, infer O, infer _E, infer _R>]
|
|
59
|
+
? O
|
|
60
|
+
: never;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @since 1.0.0
|
|
65
|
+
*/
|
|
66
|
+
export interface AsGuard<in I, out O, out E = never, out R = never> {
|
|
67
|
+
readonly asGuard: () => Guard<I, O, E, R>;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @since 1.0.0
|
|
72
|
+
*/
|
|
73
|
+
export type GuardInput<I, O, E = never, R = never> = Guard<I, O, E, R> | AsGuard<I, O, E, R>;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @since 1.0.0
|
|
77
|
+
*/
|
|
78
|
+
export const getGuard = <I, O, E = never, R = never>(
|
|
79
|
+
guard: GuardInput<I, O, E, R>,
|
|
80
|
+
): Guard<I, O, E, R> => ("asGuard" in guard ? guard.asGuard() : guard);
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @since 1.0.0
|
|
84
|
+
*/
|
|
85
|
+
export const pipe: {
|
|
86
|
+
<O, B, E2, R2>(
|
|
87
|
+
output: GuardInput<O, B, E2, R2>,
|
|
88
|
+
): <I, R, E>(input: GuardInput<I, O, E, R>) => Guard<I, B, E | E2, R | R2>;
|
|
89
|
+
<I, O, E, R, B, E2, R2>(
|
|
90
|
+
input: GuardInput<I, O, E, R>,
|
|
91
|
+
output: GuardInput<O, B, E2, R2>,
|
|
92
|
+
): Guard<I, B, E | E2, R | R2>;
|
|
93
|
+
} = dual(2, function flatMap<
|
|
94
|
+
I,
|
|
95
|
+
O,
|
|
96
|
+
E,
|
|
97
|
+
R,
|
|
98
|
+
B,
|
|
99
|
+
E2,
|
|
100
|
+
R2,
|
|
101
|
+
>(input: GuardInput<I, O, E, R>, output: GuardInput<O, B, E2, R2>): Guard<I, B, E | E2, R | R2> {
|
|
102
|
+
const g1 = getGuard(input);
|
|
103
|
+
const g2 = getGuard(output);
|
|
104
|
+
return (i) =>
|
|
105
|
+
Effect.flatMapEager(
|
|
106
|
+
g1(i),
|
|
107
|
+
Option.match({
|
|
108
|
+
onNone: () => Effect.succeedNone,
|
|
109
|
+
onSome: g2,
|
|
110
|
+
}),
|
|
111
|
+
);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @since 1.0.0
|
|
116
|
+
*/
|
|
117
|
+
export const mapEffect: {
|
|
118
|
+
<O, B, E2, R2>(
|
|
119
|
+
f: (o: O) => Effect.Effect<B, E2, R2>,
|
|
120
|
+
): <I, R, E>(guard: GuardInput<I, O, E, R>) => Guard<I, B, E | E2, R | R2>;
|
|
121
|
+
<I, O, E, R, B, E2, R2>(
|
|
122
|
+
guard: GuardInput<I, O, E, R>,
|
|
123
|
+
f: (o: O) => Effect.Effect<B, E2, R2>,
|
|
124
|
+
): Guard<I, B, E | E2, R | R2>;
|
|
125
|
+
} = dual(2, function mapEffect<
|
|
126
|
+
I,
|
|
127
|
+
O,
|
|
128
|
+
E,
|
|
129
|
+
R,
|
|
130
|
+
B,
|
|
131
|
+
E2,
|
|
132
|
+
R2,
|
|
133
|
+
>(guard: GuardInput<I, O, E, R>, f: (o: O) => Effect.Effect<B, E2, R2>): Guard<
|
|
134
|
+
I,
|
|
135
|
+
B,
|
|
136
|
+
E | E2,
|
|
137
|
+
R | R2
|
|
138
|
+
> {
|
|
139
|
+
return pipe(guard, (o) => Effect.asSome(f(o)));
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @since 1.0.0
|
|
144
|
+
*/
|
|
145
|
+
export const map: {
|
|
146
|
+
<O, B>(f: (o: O) => B): <I, R, E>(guard: GuardInput<I, O, E, R>) => Guard<I, B, E, R>;
|
|
147
|
+
<I, O, E, R, B>(guard: GuardInput<I, O, E, R>, f: (o: O) => B): Guard<I, B, E, R>;
|
|
148
|
+
} = dual(2, function map<I, O, E, R, B>(guard: GuardInput<I, O, E, R>, f: (o: O) => B): Guard<
|
|
149
|
+
I,
|
|
150
|
+
B,
|
|
151
|
+
E,
|
|
152
|
+
R
|
|
153
|
+
> {
|
|
154
|
+
const g = getGuard(guard);
|
|
155
|
+
return (i) => Effect.mapEager(g(i), Option.map(f));
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* @since 1.0.0
|
|
160
|
+
*/
|
|
161
|
+
export const tap: {
|
|
162
|
+
<O, B, E2 = never, R2 = never>(
|
|
163
|
+
f: (o: O) => void | Effect.Effect<B, E2, R2>,
|
|
164
|
+
): <I, R, E>(guard: GuardInput<I, O, E, R>) => Guard<I, O, E | E2, R | R2>;
|
|
165
|
+
<I, O, E, R, B, E2, R2>(
|
|
166
|
+
guard: GuardInput<I, O, E, R>,
|
|
167
|
+
f: (o: O) => void | Effect.Effect<B, E2, R2>,
|
|
168
|
+
): Guard<I, O, E | E2, R | R2>;
|
|
169
|
+
} = dual(2, function tap<
|
|
170
|
+
I,
|
|
171
|
+
O,
|
|
172
|
+
E,
|
|
173
|
+
R,
|
|
174
|
+
B,
|
|
175
|
+
E2,
|
|
176
|
+
R2,
|
|
177
|
+
>(guard: GuardInput<I, O, E, R>, f: (o: O) => void | Effect.Effect<B, E2, R2>): Guard<
|
|
178
|
+
I,
|
|
179
|
+
O,
|
|
180
|
+
E | E2,
|
|
181
|
+
R | R2
|
|
182
|
+
> {
|
|
183
|
+
return pipe(guard, (o) => {
|
|
184
|
+
const x = f(o);
|
|
185
|
+
if (Effect.isEffect(x)) return Effect.as(x, Option.some(o));
|
|
186
|
+
return Effect.succeedSome(o);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* @since 1.0.0
|
|
192
|
+
*/
|
|
193
|
+
export const filterMap: {
|
|
194
|
+
<O, B>(
|
|
195
|
+
f: (o: O) => Option.Option<B>,
|
|
196
|
+
): <I, R, E>(guard: GuardInput<I, O, E, R>) => Guard<I, B, E, R>;
|
|
197
|
+
<I, O, E, R, B>(guard: GuardInput<I, O, E, R>, f: (o: O) => Option.Option<B>): Guard<I, B, E, R>;
|
|
198
|
+
} = dual(
|
|
199
|
+
2,
|
|
200
|
+
<I, O, E, R, B>(
|
|
201
|
+
guard: GuardInput<I, O, E, R>,
|
|
202
|
+
f: (o: O) => Option.Option<B>,
|
|
203
|
+
): Guard<I, B, E, R> => {
|
|
204
|
+
const g = getGuard(guard);
|
|
205
|
+
return (i) => Effect.mapEager(g(i), Option.filterMap(f));
|
|
206
|
+
},
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* @since 1.0.0
|
|
211
|
+
*/
|
|
212
|
+
export const filter: {
|
|
213
|
+
<O, O2 extends O>(
|
|
214
|
+
predicate: (o: O) => o is O2,
|
|
215
|
+
): <I, R, E>(guard: GuardInput<I, O, E, R>) => Guard<I, O, E, R>;
|
|
216
|
+
<O>(predicate: (o: O) => boolean): <I, R, E>(guard: GuardInput<I, O, E, R>) => Guard<I, O, E, R>;
|
|
217
|
+
<I, O, E, R, O2 extends O>(
|
|
218
|
+
guard: GuardInput<I, O, E, R>,
|
|
219
|
+
predicate: (o: O) => o is O2,
|
|
220
|
+
): Guard<I, O, E, R>;
|
|
221
|
+
<I, O, E, R>(guard: GuardInput<I, O, E, R>, predicate: (o: O) => boolean): Guard<I, O, E, R>;
|
|
222
|
+
} = dual(
|
|
223
|
+
2,
|
|
224
|
+
<I, O, E, R>(guard: GuardInput<I, O, E, R>, predicate: (o: O) => boolean): Guard<I, O, E, R> => {
|
|
225
|
+
const g = getGuard(guard);
|
|
226
|
+
return (i) => Effect.mapEager(g(i), Option.filter(predicate));
|
|
227
|
+
},
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* @since 1.0.0
|
|
232
|
+
*/
|
|
233
|
+
export function any<const GS extends Readonly<Record<string, GuardInput<any, any, any, any>>>>(
|
|
234
|
+
guards: GS,
|
|
235
|
+
): Guard<AnyInput<GS>, AnyOutput<GS>, Guard.Error<GS[keyof GS]>, Guard.Services<GS[keyof GS]>> {
|
|
236
|
+
const entries = Object.entries(guards).map(([k, v]) => [k, getGuard(v)] as const);
|
|
237
|
+
return (i: AnyInput<GS>) =>
|
|
238
|
+
Effect.gen(function* () {
|
|
239
|
+
for (const [_tag, guard] of entries) {
|
|
240
|
+
const match = yield* guard(i);
|
|
241
|
+
if (Option.isSome(match)) {
|
|
242
|
+
return Option.some({ _tag, value: match.value } as AnyOutput<GS>);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return Option.none();
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* @since 1.0.0
|
|
251
|
+
*/
|
|
252
|
+
export type AnyInput<GS extends Readonly<Record<string, GuardInput<any, any, any, any>>>> =
|
|
253
|
+
UnionToIntersection<Guard.Input<GS[keyof GS]>>;
|
|
254
|
+
|
|
255
|
+
type UnionToIntersection<T> = (T extends any ? (x: T) => any : never) extends (x: infer R) => any
|
|
256
|
+
? R
|
|
257
|
+
: never;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* @since 1.0.0
|
|
261
|
+
*/
|
|
262
|
+
export type AnyOutput<GS extends Readonly<Record<string, GuardInput<any, any, any, any>>>> = [
|
|
263
|
+
{
|
|
264
|
+
[K in keyof GS]: { readonly _tag: K; readonly value: Guard.Output<GS[K]> };
|
|
265
|
+
}[keyof GS],
|
|
266
|
+
] extends [infer R]
|
|
267
|
+
? R
|
|
268
|
+
: never;
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* @since 1.0.0
|
|
272
|
+
*/
|
|
273
|
+
export function liftPredicate<A, B extends A>(predicate: Predicate.Refinement<A, B>): Guard<A, B>;
|
|
274
|
+
export function liftPredicate<A>(predicate: Predicate.Predicate<A>): Guard<A, A>;
|
|
275
|
+
export function liftPredicate<A>(predicate: Predicate.Predicate<A>): Guard<A, A> {
|
|
276
|
+
return (a) => Effect.succeed(predicate(a) ? Option.some(a) : Option.none());
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* @since 1.0.0
|
|
281
|
+
*/
|
|
282
|
+
export const catchCause: {
|
|
283
|
+
<E, O2, E2, R2>(
|
|
284
|
+
f: (e: Cause.Cause<E>) => Effect.Effect<O2, E2, R2>,
|
|
285
|
+
): <I, O, R>(guard: GuardInput<I, O, E, R>) => Guard<I, O | O2, E2, R | R2>;
|
|
286
|
+
<I, O, E, R, O2, E2, R2>(
|
|
287
|
+
guard: GuardInput<I, O, E, R>,
|
|
288
|
+
f: (e: Cause.Cause<E>) => Effect.Effect<O2, E2, R2>,
|
|
289
|
+
): Guard<I, O | O2, E2, R | R2>;
|
|
290
|
+
} = dual(2, function catchCause<
|
|
291
|
+
I,
|
|
292
|
+
O,
|
|
293
|
+
E,
|
|
294
|
+
R,
|
|
295
|
+
O2,
|
|
296
|
+
E2,
|
|
297
|
+
R2,
|
|
298
|
+
>(guard: GuardInput<I, O, E, R>, f: (e: Cause.Cause<E>) => Effect.Effect<O2, E2, R2>): Guard<
|
|
299
|
+
I,
|
|
300
|
+
O | O2,
|
|
301
|
+
E2,
|
|
302
|
+
R | R2
|
|
303
|
+
> {
|
|
304
|
+
const g = getGuard(guard);
|
|
305
|
+
return (i) => Effect.catchCause(g(i), (a) => Effect.asSome(f(a)));
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* @since 1.0.0
|
|
310
|
+
*/
|
|
311
|
+
export const catchAll: {
|
|
312
|
+
<E, O2, E2, R2>(
|
|
313
|
+
f: (e: E) => Effect.Effect<O2, E2, R2>,
|
|
314
|
+
): <I, O, R>(guard: GuardInput<I, O, E, R>) => Guard<I, O | O2, E2, R | R2>;
|
|
315
|
+
<I, O, E, R, O2, E2, R2>(
|
|
316
|
+
guard: GuardInput<I, O, E, R>,
|
|
317
|
+
f: (e: E) => Effect.Effect<O2, E2, R2>,
|
|
318
|
+
): Guard<I, O | O2, E2, R | R2>;
|
|
319
|
+
} = dual(2, function catchAll<
|
|
320
|
+
I,
|
|
321
|
+
O,
|
|
322
|
+
E,
|
|
323
|
+
R,
|
|
324
|
+
O2,
|
|
325
|
+
E2,
|
|
326
|
+
R2,
|
|
327
|
+
>(guard: GuardInput<I, O, E, R>, f: (e: E) => Effect.Effect<O2, E2, R2>): Guard<
|
|
328
|
+
I,
|
|
329
|
+
O | O2,
|
|
330
|
+
E2,
|
|
331
|
+
R | R2
|
|
332
|
+
> {
|
|
333
|
+
const g = getGuard(guard);
|
|
334
|
+
return (i) => Effect.catchEager(g(i), (a) => Effect.asSome(f(a)));
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
export { catchAll as catch };
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* @since 1.0.0
|
|
341
|
+
*/
|
|
342
|
+
export const catchTag: {
|
|
343
|
+
<E, K extends E extends { _tag: string } ? E["_tag"] : never, O2, E2, R2>(
|
|
344
|
+
tag: K,
|
|
345
|
+
f: (e: Extract<E, { _tag: K }>) => Effect.Effect<O2, E2, R2>,
|
|
346
|
+
): <I, O, R>(
|
|
347
|
+
guard: GuardInput<I, O, E, R>,
|
|
348
|
+
) => Guard<I, O | O2, E2 | Exclude<E, { _tag: K }>, R | R2>;
|
|
349
|
+
|
|
350
|
+
<I, O, E, R, K extends E extends { _tag: string } ? E["_tag"] : never, O2, E2, R2>(
|
|
351
|
+
guard: GuardInput<I, O, E, R>,
|
|
352
|
+
tag: K,
|
|
353
|
+
f: (e: Extract<E, { _tag: K }>) => Effect.Effect<O2, E2, R2>,
|
|
354
|
+
): Guard<I, O | O2, E2 | Exclude<E, { _tag: K }>, R | R2>;
|
|
355
|
+
} = dual(3, function catchTag<
|
|
356
|
+
I,
|
|
357
|
+
O,
|
|
358
|
+
E,
|
|
359
|
+
R,
|
|
360
|
+
K extends E extends { _tag: string } ? E["_tag"] : never,
|
|
361
|
+
O2,
|
|
362
|
+
E2,
|
|
363
|
+
R2,
|
|
364
|
+
>(guard: GuardInput<I, O, E, R>, tag: K, f: (e: Extract<E, { _tag: K }>) => Effect.Effect<O2, E2, R2>): Guard<
|
|
365
|
+
I,
|
|
366
|
+
O | O2,
|
|
367
|
+
Exclude<E, { _tag: K }> | E2,
|
|
368
|
+
R | R2
|
|
369
|
+
> {
|
|
370
|
+
const g = getGuard(guard);
|
|
371
|
+
return (i: I) => Effect.catchTag(g(i), tag as any, (e) => Effect.asSome(f(e)));
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* @since 1.0.0
|
|
376
|
+
*/
|
|
377
|
+
export const provide: {
|
|
378
|
+
<R2>(
|
|
379
|
+
provided: ServiceMap.ServiceMap<R2>,
|
|
380
|
+
): <I, O, E, R>(guard: GuardInput<I, O, E, R>) => Guard<I, O, E, Exclude<R, R2>>;
|
|
381
|
+
<R2, E2, R3>(
|
|
382
|
+
provided: Layer.Layer<R2, E2, R3>,
|
|
383
|
+
): <I, O, E, R>(guard: GuardInput<I, O, E, R>) => Guard<I, O, E | E2, Exclude<R, R2> | R3>;
|
|
384
|
+
|
|
385
|
+
<I, O, E, R, R2>(
|
|
386
|
+
guard: GuardInput<I, O, E, R>,
|
|
387
|
+
provided: ServiceMap.ServiceMap<R2>,
|
|
388
|
+
): Guard<I, O, E, Exclude<R, R2>>;
|
|
389
|
+
<I, O, E, R, R2, E2, R3>(
|
|
390
|
+
guard: GuardInput<I, O, E, R>,
|
|
391
|
+
provided: Layer.Layer<R2, E2, R3>,
|
|
392
|
+
): Guard<I, O, E | E2, Exclude<R, R2> | R3>;
|
|
393
|
+
} = dual(2, function provide<
|
|
394
|
+
I,
|
|
395
|
+
O,
|
|
396
|
+
E,
|
|
397
|
+
R,
|
|
398
|
+
R2,
|
|
399
|
+
>(guard: GuardInput<I, O, E, R>, provided: ServiceMap.ServiceMap<R2>): Guard<
|
|
400
|
+
I,
|
|
401
|
+
O,
|
|
402
|
+
E,
|
|
403
|
+
Exclude<R, R2>
|
|
404
|
+
> {
|
|
405
|
+
const g = getGuard(guard);
|
|
406
|
+
return (i) => Effect.provide(g(i), provided);
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* @since 1.0.0
|
|
411
|
+
*/
|
|
412
|
+
export const provideService: {
|
|
413
|
+
<Id, S>(
|
|
414
|
+
tag: ServiceMap.Service<Id, S>,
|
|
415
|
+
service: S,
|
|
416
|
+
): <I, O, E, R>(guard: GuardInput<I, O, E, R>) => Guard<I, O, E, Exclude<R, Id>>;
|
|
417
|
+
<I, O, E, R, Id, S>(
|
|
418
|
+
guard: GuardInput<I, O, E, R>,
|
|
419
|
+
tag: ServiceMap.Service<Id, S>,
|
|
420
|
+
service: S,
|
|
421
|
+
): Guard<I, O, E, Exclude<R, Id>>;
|
|
422
|
+
} = dual(3, function provideService<
|
|
423
|
+
I,
|
|
424
|
+
O,
|
|
425
|
+
E,
|
|
426
|
+
R,
|
|
427
|
+
Id,
|
|
428
|
+
S,
|
|
429
|
+
>(guard: GuardInput<I, O, E, R>, tag: ServiceMap.Service<Id, S>, service: S): Guard<
|
|
430
|
+
I,
|
|
431
|
+
O,
|
|
432
|
+
E,
|
|
433
|
+
Exclude<R, Id>
|
|
434
|
+
> {
|
|
435
|
+
const g = getGuard(guard);
|
|
436
|
+
return (i) => Effect.provideService(g(i), tag, service);
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* @since 1.0.0
|
|
441
|
+
*/
|
|
442
|
+
export const provideServiceEffect: {
|
|
443
|
+
<Id, S, E2, R2>(
|
|
444
|
+
tag: ServiceMap.Service<Id, S>,
|
|
445
|
+
service: Effect.Effect<S, E2, R2>,
|
|
446
|
+
): <I, O, E, R>(guard: GuardInput<I, O, E, R>) => Guard<I, O, E | E2, Exclude<R, Id> | R2>;
|
|
447
|
+
<I, O, E, R, Id, S, E2, R2>(
|
|
448
|
+
guard: GuardInput<I, O, E, R>,
|
|
449
|
+
tag: ServiceMap.Service<Id, S>,
|
|
450
|
+
service: Effect.Effect<S, E2, R2>,
|
|
451
|
+
): Guard<I, O, E | E2, Exclude<R, Id> | R2>;
|
|
452
|
+
} = dual(3, function provideServiceEffect<
|
|
453
|
+
I,
|
|
454
|
+
O,
|
|
455
|
+
E,
|
|
456
|
+
R,
|
|
457
|
+
Id,
|
|
458
|
+
S,
|
|
459
|
+
E2,
|
|
460
|
+
R2,
|
|
461
|
+
>(guard: GuardInput<I, O, E, R>, tag: ServiceMap.Service<Id, S>, service: Effect.Effect<S, E2, R2>): Guard<
|
|
462
|
+
I,
|
|
463
|
+
O,
|
|
464
|
+
E | E2,
|
|
465
|
+
Exclude<R, Id> | R2
|
|
466
|
+
> {
|
|
467
|
+
const g = getGuard(guard);
|
|
468
|
+
return (i) => Effect.provideServiceEffect(g(i), tag, service);
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
const parseOptions: ParseOptions = { errors: "all", onExcessProperty: "ignore" };
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* @since 1.0.0
|
|
475
|
+
*/
|
|
476
|
+
export function fromSchemaDecode<S extends Schema.Top>(
|
|
477
|
+
schema: S,
|
|
478
|
+
): Guard<S["Encoded"], S["Type"], Schema.SchemaError, S["DecodingServices"]> {
|
|
479
|
+
const decode_ = Schema.decodeEffect(schema);
|
|
480
|
+
return (i: S["Encoded"]) => Effect.asSome(decode_(i, parseOptions));
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* @since 1.0.0
|
|
485
|
+
*/
|
|
486
|
+
export function fromSchemaEncode<S extends Schema.Top>(
|
|
487
|
+
schema: S,
|
|
488
|
+
): Guard<S["Type"], S["Encoded"], Schema.SchemaError, S["EncodingServices"]> {
|
|
489
|
+
const encode_ = Schema.encodeEffect(schema);
|
|
490
|
+
return (a: S["Type"]) => Effect.asSome(encode_(a, parseOptions));
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* @since 1.0.0
|
|
495
|
+
*/
|
|
496
|
+
export const decode: {
|
|
497
|
+
<S extends Schema.Top>(
|
|
498
|
+
schema: S,
|
|
499
|
+
): <I, E = never, R = never>(
|
|
500
|
+
guard: GuardInput<I, S["Type"], E, R>,
|
|
501
|
+
) => Guard<I, S["Type"], Schema.SchemaError | E, R | S["DecodingServices"]>;
|
|
502
|
+
|
|
503
|
+
<I, O, E, R, S extends Schema.Top>(
|
|
504
|
+
guard: GuardInput<I, O, E, R>,
|
|
505
|
+
schema: S,
|
|
506
|
+
): Guard<I, S["Type"], Schema.SchemaError | E, R | S["DecodingServices"]>;
|
|
507
|
+
} = dual(2, function decode<
|
|
508
|
+
I,
|
|
509
|
+
O,
|
|
510
|
+
E,
|
|
511
|
+
R,
|
|
512
|
+
S extends Schema.Top,
|
|
513
|
+
>(guard: GuardInput<I, O, E, R>, schema: S): Guard<
|
|
514
|
+
I,
|
|
515
|
+
S["Type"],
|
|
516
|
+
Schema.SchemaError | E,
|
|
517
|
+
R | S["DecodingServices"]
|
|
518
|
+
> {
|
|
519
|
+
return pipe(guard, fromSchemaDecode(schema));
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* @since 1.0.0
|
|
524
|
+
*/
|
|
525
|
+
export const encode: {
|
|
526
|
+
<S extends Schema.Top>(
|
|
527
|
+
schema: S,
|
|
528
|
+
): <I, E = never, R = never>(
|
|
529
|
+
guard: GuardInput<I, S["Type"], E, R>,
|
|
530
|
+
) => Guard<I, S["Type"], Schema.SchemaError | E, R | S["EncodingServices"]>;
|
|
531
|
+
|
|
532
|
+
<I, O, E, R, S extends Schema.Top>(
|
|
533
|
+
guard: GuardInput<I, O, E, R>,
|
|
534
|
+
schema: S,
|
|
535
|
+
): Guard<I, S["Encoded"], Schema.SchemaError | E, R | S["EncodingServices"]>;
|
|
536
|
+
} = dual(2, function encode<
|
|
537
|
+
I,
|
|
538
|
+
O,
|
|
539
|
+
E,
|
|
540
|
+
R,
|
|
541
|
+
S extends Schema.Top,
|
|
542
|
+
>(guard: GuardInput<I, O, E, R>, schema: S): Guard<
|
|
543
|
+
I,
|
|
544
|
+
S["Encoded"],
|
|
545
|
+
Schema.SchemaError | E,
|
|
546
|
+
R | S["EncodingServices"]
|
|
547
|
+
> {
|
|
548
|
+
return pipe(guard, fromSchemaEncode(schema));
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* @since 1.0.0
|
|
553
|
+
*/
|
|
554
|
+
const let_: {
|
|
555
|
+
<K extends PropertyKey, B>(
|
|
556
|
+
key: K,
|
|
557
|
+
value: B,
|
|
558
|
+
): <I, O, E = never, R = never>(guard: Guard<I, O, E, R>) => Guard<I, O & { [k in K]: B }, E, R>;
|
|
559
|
+
|
|
560
|
+
<I, O, E, R, K extends PropertyKey, B>(
|
|
561
|
+
guard: Guard<I, O, E, R>,
|
|
562
|
+
key: K,
|
|
563
|
+
value: B,
|
|
564
|
+
): Guard<I, O & { [k in K]: B }, E, R>;
|
|
565
|
+
} = dual(3, function attachProperty<
|
|
566
|
+
I,
|
|
567
|
+
O,
|
|
568
|
+
E,
|
|
569
|
+
R,
|
|
570
|
+
K extends PropertyKey,
|
|
571
|
+
B,
|
|
572
|
+
>(guard: Guard<I, O, E, R>, key: K, value: B): Guard<I, O & { [k in K]: B }, E, R> {
|
|
573
|
+
return map(guard, (a) => ({ ...a, [key]: value }) as O & { [k in K]: B });
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
export {
|
|
577
|
+
/**
|
|
578
|
+
* @since 1.0.0
|
|
579
|
+
*/
|
|
580
|
+
let_ as let,
|
|
581
|
+
};
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* @since 1.0.0
|
|
585
|
+
*/
|
|
586
|
+
export const addTag: {
|
|
587
|
+
<B>(
|
|
588
|
+
value: B,
|
|
589
|
+
): <I, O, E = never, R = never>(
|
|
590
|
+
guard: GuardInput<I, O, E, R>,
|
|
591
|
+
) => Guard<I, O & { readonly _tag: B }, E, R>;
|
|
592
|
+
|
|
593
|
+
<I, O, E, R, B>(
|
|
594
|
+
guard: GuardInput<I, O, E, R>,
|
|
595
|
+
value: B,
|
|
596
|
+
): Guard<I, O & { readonly _tag: B }, E, R>;
|
|
597
|
+
} = dual(2, function attachProperty<I, O, E, R, B>(guard: GuardInput<I, O, E, R>, value: B): Guard<
|
|
598
|
+
I,
|
|
599
|
+
O & { readonly _tag: B },
|
|
600
|
+
E,
|
|
601
|
+
R
|
|
602
|
+
> {
|
|
603
|
+
return map(guard, (a) => ({ ...a, _tag: value }) as O & { readonly _tag: B });
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* @since 1.0.0
|
|
608
|
+
*/
|
|
609
|
+
export const bindTo: {
|
|
610
|
+
<K extends PropertyKey>(
|
|
611
|
+
key: K,
|
|
612
|
+
): <I, O, E, R>(guard: GuardInput<I, O, E, R>) => Guard<I, { [k in K]: O }, E, R>;
|
|
613
|
+
<I, O, E, R, K extends PropertyKey>(
|
|
614
|
+
guard: GuardInput<I, O, E, R>,
|
|
615
|
+
key: K,
|
|
616
|
+
): Guard<I, { [k in K]: O }, E, R>;
|
|
617
|
+
} = dual(
|
|
618
|
+
2,
|
|
619
|
+
<I, O, E, R, K extends PropertyKey>(
|
|
620
|
+
guard: GuardInput<I, O, E, R>,
|
|
621
|
+
key: K,
|
|
622
|
+
): Guard<I, { [k in K]: O }, E, R> => map(guard, (a) => ({ [key]: a }) as { [k in K]: O }),
|
|
623
|
+
);
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* @since 1.0.0
|
|
627
|
+
*/
|
|
628
|
+
export const bind: {
|
|
629
|
+
<I, O, E, R, K extends PropertyKey, B, E2, R2>(
|
|
630
|
+
key: K,
|
|
631
|
+
f: GuardInput<O, B, E2, R2>,
|
|
632
|
+
): (guard: GuardInput<I, O, E, R>) => Guard<I, O & { [k in K]: B }, E | E2, R | R2>;
|
|
633
|
+
|
|
634
|
+
<I, O, E, R, K extends PropertyKey, B, E2, R2>(
|
|
635
|
+
guard: GuardInput<I, O, E, R>,
|
|
636
|
+
key: K,
|
|
637
|
+
f: GuardInput<O, B, E2, R2>,
|
|
638
|
+
): Guard<I, O & { [k in K]: B }, E | E2, R | R2>;
|
|
639
|
+
} = dual(3, function bind<
|
|
640
|
+
I,
|
|
641
|
+
O,
|
|
642
|
+
E,
|
|
643
|
+
R,
|
|
644
|
+
K extends PropertyKey,
|
|
645
|
+
B,
|
|
646
|
+
E2,
|
|
647
|
+
R2,
|
|
648
|
+
>(guard: GuardInput<I, O, E, R>, key: K, f: GuardInput<O, B, E2, R2>): Guard<
|
|
649
|
+
I,
|
|
650
|
+
O & { [k in K]: B },
|
|
651
|
+
E | E2,
|
|
652
|
+
R | R2
|
|
653
|
+
> {
|
|
654
|
+
const f_ = bindTo(f, key);
|
|
655
|
+
return pipe(guard, (o) =>
|
|
656
|
+
Effect.mapEager(
|
|
657
|
+
f_(o),
|
|
658
|
+
Option.map((b) => ({ ...o, ...b })),
|
|
659
|
+
),
|
|
660
|
+
);
|
|
661
|
+
});
|
package/tsconfig.json
CHANGED
|
@@ -1,27 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
"lib": [
|
|
7
|
-
"ES2022",
|
|
8
|
-
"DOM"
|
|
9
|
-
],
|
|
10
|
-
"strict": true,
|
|
11
|
-
"esModuleInterop": true,
|
|
12
|
-
"skipLibCheck": true,
|
|
13
|
-
"forceConsistentCasingInFileNames": true,
|
|
14
|
-
"declaration": true,
|
|
15
|
-
"sourceMap": true,
|
|
16
|
-
"outDir": "dist",
|
|
17
|
-
"rootDir": "src"
|
|
18
|
-
},
|
|
19
|
-
"include": [
|
|
20
|
-
"src/**/*"
|
|
21
|
-
],
|
|
22
|
-
"exclude": [
|
|
23
|
-
"node_modules",
|
|
24
|
-
"dist",
|
|
25
|
-
"**/*.test.ts"
|
|
26
|
-
]
|
|
27
|
-
}
|
|
2
|
+
"extends": "../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": { "rootDir": "src", "outDir": "dist" },
|
|
4
|
+
"include": ["src"]
|
|
5
|
+
}
|
package/.nvmrc
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
22
|