@nlozgachev/pipelined 0.12.0 → 0.14.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/LICENCE +28 -0
- package/README.md +1 -1
- package/{types/src/Types/NonEmptyList.d.ts → dist/NonEmptyList-BlGFjor5.d.mts} +4 -3
- package/dist/NonEmptyList-BlGFjor5.d.ts +30 -0
- package/dist/Task-Bd3gXPRQ.d.mts +677 -0
- package/dist/Task-BjAkkD6t.d.ts +677 -0
- package/dist/chunk-4TXC322E.mjs +136 -0
- package/dist/chunk-BYWKZLHM.mjs +10 -0
- package/dist/chunk-DBIC62UV.mjs +6 -0
- package/dist/chunk-FAZN3IWZ.mjs +554 -0
- package/dist/chunk-QPTGO5AS.mjs +150 -0
- package/dist/chunk-UV2HMF2A.mjs +514 -0
- package/dist/composition.d.mts +495 -0
- package/dist/composition.d.ts +495 -0
- package/dist/composition.js +188 -0
- package/dist/composition.mjs +58 -0
- package/dist/core.d.mts +2170 -0
- package/dist/core.d.ts +2170 -0
- package/dist/core.js +698 -0
- package/dist/core.mjs +42 -0
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +1421 -0
- package/dist/index.mjs +120 -0
- package/dist/types.d.mts +54 -0
- package/{types/src/Types/Brand.d.ts → dist/types.d.ts} +6 -4
- package/dist/types.js +41 -0
- package/dist/types.mjs +10 -0
- package/dist/utils.d.mts +1285 -0
- package/dist/utils.d.ts +1285 -0
- package/dist/utils.js +722 -0
- package/dist/utils.mjs +18 -0
- package/package.json +64 -69
- package/esm/mod.js +0 -3
- package/esm/package.json +0 -3
- package/esm/src/Composition/compose.js +0 -3
- package/esm/src/Composition/converge.js +0 -3
- package/esm/src/Composition/curry.js +0 -42
- package/esm/src/Composition/flip.js +0 -20
- package/esm/src/Composition/flow.js +0 -8
- package/esm/src/Composition/fn.js +0 -85
- package/esm/src/Composition/index.js +0 -13
- package/esm/src/Composition/juxt.js +0 -3
- package/esm/src/Composition/memoize.js +0 -66
- package/esm/src/Composition/not.js +0 -25
- package/esm/src/Composition/on.js +0 -12
- package/esm/src/Composition/pipe.js +0 -3
- package/esm/src/Composition/tap.js +0 -33
- package/esm/src/Composition/uncurry.js +0 -32
- package/esm/src/Core/Deferred.js +0 -30
- package/esm/src/Core/InternalTypes.js +0 -1
- package/esm/src/Core/Lens.js +0 -98
- package/esm/src/Core/Logged.js +0 -111
- package/esm/src/Core/Option.js +0 -191
- package/esm/src/Core/Optional.js +0 -160
- package/esm/src/Core/Predicate.js +0 -133
- package/esm/src/Core/Reader.js +0 -134
- package/esm/src/Core/Refinement.js +0 -115
- package/esm/src/Core/RemoteData.js +0 -211
- package/esm/src/Core/Result.js +0 -170
- package/esm/src/Core/State.js +0 -181
- package/esm/src/Core/Task.js +0 -223
- package/esm/src/Core/TaskOption.js +0 -106
- package/esm/src/Core/TaskResult.js +0 -127
- package/esm/src/Core/TaskValidation.js +0 -128
- package/esm/src/Core/These.js +0 -245
- package/esm/src/Core/Tuple.js +0 -112
- package/esm/src/Core/Validation.js +0 -212
- package/esm/src/Core/index.js +0 -18
- package/esm/src/Types/Brand.js +0 -28
- package/esm/src/Types/NonEmptyList.js +0 -14
- package/esm/src/Types/index.js +0 -2
- package/esm/src/Utils/Arr.js +0 -570
- package/esm/src/Utils/Dict.js +0 -421
- package/esm/src/Utils/Num.js +0 -124
- package/esm/src/Utils/Rec.js +0 -241
- package/esm/src/Utils/Str.js +0 -134
- package/esm/src/Utils/Uniq.js +0 -265
- package/esm/src/Utils/index.js +0 -6
- package/script/mod.js +0 -19
- package/script/package.json +0 -3
- package/script/src/Composition/compose.js +0 -6
- package/script/src/Composition/converge.js +0 -6
- package/script/src/Composition/curry.js +0 -48
- package/script/src/Composition/flip.js +0 -24
- package/script/src/Composition/flow.js +0 -11
- package/script/src/Composition/fn.js +0 -98
- package/script/src/Composition/index.js +0 -29
- package/script/src/Composition/juxt.js +0 -6
- package/script/src/Composition/memoize.js +0 -71
- package/script/src/Composition/not.js +0 -29
- package/script/src/Composition/on.js +0 -16
- package/script/src/Composition/pipe.js +0 -6
- package/script/src/Composition/tap.js +0 -37
- package/script/src/Composition/uncurry.js +0 -38
- package/script/src/Core/Deferred.js +0 -33
- package/script/src/Core/InternalTypes.js +0 -2
- package/script/src/Core/Lens.js +0 -101
- package/script/src/Core/Logged.js +0 -114
- package/script/src/Core/Option.js +0 -194
- package/script/src/Core/Optional.js +0 -163
- package/script/src/Core/Predicate.js +0 -136
- package/script/src/Core/Reader.js +0 -137
- package/script/src/Core/Refinement.js +0 -118
- package/script/src/Core/RemoteData.js +0 -214
- package/script/src/Core/Result.js +0 -173
- package/script/src/Core/State.js +0 -184
- package/script/src/Core/Task.js +0 -226
- package/script/src/Core/TaskOption.js +0 -109
- package/script/src/Core/TaskResult.js +0 -130
- package/script/src/Core/TaskValidation.js +0 -131
- package/script/src/Core/These.js +0 -248
- package/script/src/Core/Tuple.js +0 -115
- package/script/src/Core/Validation.js +0 -215
- package/script/src/Core/index.js +0 -34
- package/script/src/Types/Brand.js +0 -31
- package/script/src/Types/NonEmptyList.js +0 -18
- package/script/src/Types/index.js +0 -18
- package/script/src/Utils/Arr.js +0 -573
- package/script/src/Utils/Dict.js +0 -424
- package/script/src/Utils/Num.js +0 -127
- package/script/src/Utils/Rec.js +0 -244
- package/script/src/Utils/Str.js +0 -137
- package/script/src/Utils/Uniq.js +0 -268
- package/script/src/Utils/index.js +0 -22
- package/types/mod.d.ts +0 -4
- package/types/mod.d.ts.map +0 -1
- package/types/src/Composition/compose.d.ts +0 -33
- package/types/src/Composition/compose.d.ts.map +0 -1
- package/types/src/Composition/converge.d.ts +0 -21
- package/types/src/Composition/converge.d.ts.map +0 -1
- package/types/src/Composition/curry.d.ts +0 -43
- package/types/src/Composition/curry.d.ts.map +0 -1
- package/types/src/Composition/flip.d.ts +0 -21
- package/types/src/Composition/flip.d.ts.map +0 -1
- package/types/src/Composition/flow.d.ts +0 -56
- package/types/src/Composition/flow.d.ts.map +0 -1
- package/types/src/Composition/fn.d.ts +0 -76
- package/types/src/Composition/fn.d.ts.map +0 -1
- package/types/src/Composition/index.d.ts +0 -14
- package/types/src/Composition/index.d.ts.map +0 -1
- package/types/src/Composition/juxt.d.ts +0 -18
- package/types/src/Composition/juxt.d.ts.map +0 -1
- package/types/src/Composition/memoize.d.ts +0 -46
- package/types/src/Composition/memoize.d.ts.map +0 -1
- package/types/src/Composition/not.d.ts +0 -26
- package/types/src/Composition/not.d.ts.map +0 -1
- package/types/src/Composition/on.d.ts +0 -13
- package/types/src/Composition/on.d.ts.map +0 -1
- package/types/src/Composition/pipe.d.ts +0 -56
- package/types/src/Composition/pipe.d.ts.map +0 -1
- package/types/src/Composition/tap.d.ts +0 -31
- package/types/src/Composition/tap.d.ts.map +0 -1
- package/types/src/Composition/uncurry.d.ts +0 -54
- package/types/src/Composition/uncurry.d.ts.map +0 -1
- package/types/src/Core/Deferred.d.ts +0 -49
- package/types/src/Core/Deferred.d.ts.map +0 -1
- package/types/src/Core/InternalTypes.d.ts +0 -23
- package/types/src/Core/InternalTypes.d.ts.map +0 -1
- package/types/src/Core/Lens.d.ts +0 -118
- package/types/src/Core/Lens.d.ts.map +0 -1
- package/types/src/Core/Logged.d.ts +0 -126
- package/types/src/Core/Logged.d.ts.map +0 -1
- package/types/src/Core/Option.d.ts +0 -209
- package/types/src/Core/Option.d.ts.map +0 -1
- package/types/src/Core/Optional.d.ts +0 -158
- package/types/src/Core/Optional.d.ts.map +0 -1
- package/types/src/Core/Predicate.d.ts +0 -161
- package/types/src/Core/Predicate.d.ts.map +0 -1
- package/types/src/Core/Reader.d.ts +0 -156
- package/types/src/Core/Reader.d.ts.map +0 -1
- package/types/src/Core/Refinement.d.ts +0 -138
- package/types/src/Core/Refinement.d.ts.map +0 -1
- package/types/src/Core/RemoteData.d.ts +0 -197
- package/types/src/Core/RemoteData.d.ts.map +0 -1
- package/types/src/Core/Result.d.ts +0 -182
- package/types/src/Core/Result.d.ts.map +0 -1
- package/types/src/Core/State.d.ts +0 -192
- package/types/src/Core/State.d.ts.map +0 -1
- package/types/src/Core/Task.d.ts +0 -219
- package/types/src/Core/Task.d.ts.map +0 -1
- package/types/src/Core/TaskOption.d.ts +0 -121
- package/types/src/Core/TaskOption.d.ts.map +0 -1
- package/types/src/Core/TaskResult.d.ts +0 -119
- package/types/src/Core/TaskResult.d.ts.map +0 -1
- package/types/src/Core/TaskValidation.d.ts +0 -144
- package/types/src/Core/TaskValidation.d.ts.map +0 -1
- package/types/src/Core/These.d.ts +0 -225
- package/types/src/Core/These.d.ts.map +0 -1
- package/types/src/Core/Tuple.d.ts +0 -129
- package/types/src/Core/Tuple.d.ts.map +0 -1
- package/types/src/Core/Validation.d.ts +0 -203
- package/types/src/Core/Validation.d.ts.map +0 -1
- package/types/src/Core/index.d.ts +0 -19
- package/types/src/Core/index.d.ts.map +0 -1
- package/types/src/Types/Brand.d.ts.map +0 -1
- package/types/src/Types/NonEmptyList.d.ts.map +0 -1
- package/types/src/Types/index.d.ts +0 -3
- package/types/src/Types/index.d.ts.map +0 -1
- package/types/src/Utils/Arr.d.ts +0 -403
- package/types/src/Utils/Arr.d.ts.map +0 -1
- package/types/src/Utils/Dict.d.ts +0 -310
- package/types/src/Utils/Dict.d.ts.map +0 -1
- package/types/src/Utils/Num.d.ts +0 -110
- package/types/src/Utils/Num.d.ts.map +0 -1
- package/types/src/Utils/Rec.d.ts +0 -159
- package/types/src/Utils/Rec.d.ts.map +0 -1
- package/types/src/Utils/Str.d.ts +0 -128
- package/types/src/Utils/Str.d.ts.map +0 -1
- package/types/src/Utils/Uniq.d.ts +0 -179
- package/types/src/Utils/Uniq.d.ts.map +0 -1
- package/types/src/Utils/index.d.ts +0 -7
- package/types/src/Utils/index.d.ts.map +0 -1
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { Deferred } from "./Deferred.js";
|
|
2
|
-
import { Task } from "./Task.js";
|
|
3
|
-
import { Validation } from "./Validation.js";
|
|
4
|
-
export var TaskValidation;
|
|
5
|
-
(function (TaskValidation) {
|
|
6
|
-
/**
|
|
7
|
-
* Wraps a value in a valid TaskValidation.
|
|
8
|
-
*/
|
|
9
|
-
TaskValidation.valid = (value) => Task.resolve(Validation.valid(value));
|
|
10
|
-
/**
|
|
11
|
-
* Creates a failed TaskValidation with a single error.
|
|
12
|
-
*/
|
|
13
|
-
TaskValidation.invalid = (error) => Task.resolve(Validation.invalid(error));
|
|
14
|
-
/**
|
|
15
|
-
* Creates an invalid TaskValidation from multiple errors.
|
|
16
|
-
*/
|
|
17
|
-
TaskValidation.invalidAll = (errors) => Task.resolve(Validation.invalidAll(errors));
|
|
18
|
-
/**
|
|
19
|
-
* Lifts a Validation into a TaskValidation.
|
|
20
|
-
*/
|
|
21
|
-
TaskValidation.fromValidation = (validation) => Task.resolve(validation);
|
|
22
|
-
/**
|
|
23
|
-
* Creates a TaskValidation from a Promise-returning function.
|
|
24
|
-
* Catches any errors and transforms them using the onError function.
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```ts
|
|
28
|
-
* const fetchUser = (id: string): TaskValidation<string, User> =>
|
|
29
|
-
* TaskValidation.tryCatch(
|
|
30
|
-
* () => fetch(`/users/${id}`).then(r => r.json()),
|
|
31
|
-
* e => `Failed to fetch user: ${e}`
|
|
32
|
-
* );
|
|
33
|
-
* ```
|
|
34
|
-
*/
|
|
35
|
-
TaskValidation.tryCatch = (f, onError) => Task.from(() => f()
|
|
36
|
-
.then((Validation.valid))
|
|
37
|
-
.catch((e) => Validation.invalid(onError(e))));
|
|
38
|
-
/**
|
|
39
|
-
* Transforms the success value inside a TaskValidation.
|
|
40
|
-
*/
|
|
41
|
-
TaskValidation.map = (f) => (data) => Task.map(Validation.map(f))(data);
|
|
42
|
-
/**
|
|
43
|
-
* Applies a function wrapped in a TaskValidation to a value wrapped in a
|
|
44
|
-
* TaskValidation. Both Tasks run in parallel and errors from both sides
|
|
45
|
-
* are accumulated.
|
|
46
|
-
*
|
|
47
|
-
* @example
|
|
48
|
-
* ```ts
|
|
49
|
-
* pipe(
|
|
50
|
-
* TaskValidation.valid((name: string) => (age: number) => ({ name, age })),
|
|
51
|
-
* TaskValidation.ap(validateName(name)),
|
|
52
|
-
* TaskValidation.ap(validateAge(age))
|
|
53
|
-
* )();
|
|
54
|
-
* ```
|
|
55
|
-
*/
|
|
56
|
-
TaskValidation.ap = (arg) => (data) => Task.from(() => Promise.all([
|
|
57
|
-
Deferred.toPromise(data()),
|
|
58
|
-
Deferred.toPromise(arg()),
|
|
59
|
-
]).then(([vf, va]) => Validation.ap(va)(vf)));
|
|
60
|
-
/**
|
|
61
|
-
* Extracts a value from a TaskValidation by providing handlers for both cases.
|
|
62
|
-
*/
|
|
63
|
-
TaskValidation.fold = (onInvalid, onValid) => (data) => Task.map(Validation.fold(onInvalid, onValid))(data);
|
|
64
|
-
/**
|
|
65
|
-
* Pattern matches on a TaskValidation, returning a Task of the result.
|
|
66
|
-
*
|
|
67
|
-
* @example
|
|
68
|
-
* ```ts
|
|
69
|
-
* pipe(
|
|
70
|
-
* validateForm(input),
|
|
71
|
-
* TaskValidation.match({
|
|
72
|
-
* valid: data => save(data),
|
|
73
|
-
* invalid: errors => showErrors(errors)
|
|
74
|
-
* })
|
|
75
|
-
* )();
|
|
76
|
-
* ```
|
|
77
|
-
*/
|
|
78
|
-
TaskValidation.match = (cases) => (data) => Task.map(Validation.match(cases))(data);
|
|
79
|
-
/**
|
|
80
|
-
* Returns the success value or a default value if the TaskValidation is invalid.
|
|
81
|
-
* The default can be a different type, widening the result to `Task<A | B>`.
|
|
82
|
-
*/
|
|
83
|
-
TaskValidation.getOrElse = (defaultValue) => (data) => Task.map(Validation.getOrElse(defaultValue))(data);
|
|
84
|
-
/**
|
|
85
|
-
* Executes a side effect on the success value without changing the TaskValidation.
|
|
86
|
-
* Useful for logging or debugging.
|
|
87
|
-
*/
|
|
88
|
-
TaskValidation.tap = (f) => (data) => Task.map(Validation.tap(f))(data);
|
|
89
|
-
/**
|
|
90
|
-
* Recovers from an Invalid state by providing a fallback TaskValidation.
|
|
91
|
-
* The fallback receives the accumulated error list so callers can inspect which errors occurred.
|
|
92
|
-
* The fallback can produce a different success type, widening the result to `TaskValidation<E, A | B>`.
|
|
93
|
-
*/
|
|
94
|
-
TaskValidation.recover = (fallback) => (data) => Task.chain((validation) => Validation.isValid(validation) ? Task.resolve(validation) : fallback(validation.errors))(data);
|
|
95
|
-
/**
|
|
96
|
-
* Runs two TaskValidations concurrently and combines their results into a tuple.
|
|
97
|
-
* If both are Valid, returns Valid with both values. If either fails, accumulates
|
|
98
|
-
* errors from both sides.
|
|
99
|
-
*
|
|
100
|
-
* @example
|
|
101
|
-
* ```ts
|
|
102
|
-
* await TaskValidation.product(
|
|
103
|
-
* validateName(form.name),
|
|
104
|
-
* validateAge(form.age),
|
|
105
|
-
* )(); // Valid(["Alice", 30]) or Invalid([...errors])
|
|
106
|
-
* ```
|
|
107
|
-
*/
|
|
108
|
-
TaskValidation.product = (first, second) => Task.from(() => Promise.all([
|
|
109
|
-
Deferred.toPromise(first()),
|
|
110
|
-
Deferred.toPromise(second()),
|
|
111
|
-
]).then(([va, vb]) => Validation.product(va, vb)));
|
|
112
|
-
/**
|
|
113
|
-
* Runs all TaskValidations concurrently and collects results.
|
|
114
|
-
* If all are Valid, returns Valid with all values as an array.
|
|
115
|
-
* If any fail, returns Invalid with all accumulated errors.
|
|
116
|
-
*
|
|
117
|
-
* @example
|
|
118
|
-
* ```ts
|
|
119
|
-
* await TaskValidation.productAll([
|
|
120
|
-
* validateName(form.name),
|
|
121
|
-
* validateEmail(form.email),
|
|
122
|
-
* validateAge(form.age),
|
|
123
|
-
* ])(); // Valid([name, email, age]) or Invalid([...all errors])
|
|
124
|
-
* ```
|
|
125
|
-
*/
|
|
126
|
-
TaskValidation.productAll = (data) => Task.from(() => Promise.all(data.map((t) => Deferred.toPromise(t())))
|
|
127
|
-
.then((results) => Validation.productAll(results)));
|
|
128
|
-
})(TaskValidation || (TaskValidation = {}));
|
package/esm/src/Core/These.js
DELETED
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
export var These;
|
|
2
|
-
(function (These) {
|
|
3
|
-
/**
|
|
4
|
-
* Creates a These holding only a first value.
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```ts
|
|
8
|
-
* These.first(42); // { kind: "First", first: 42 }
|
|
9
|
-
* ```
|
|
10
|
-
*/
|
|
11
|
-
These.first = (value) => ({ kind: "First", first: value });
|
|
12
|
-
/**
|
|
13
|
-
* Creates a These holding only a second value.
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```ts
|
|
17
|
-
* These.second("warning"); // { kind: "Second", second: "warning" }
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
These.second = (value) => ({ kind: "Second", second: value });
|
|
21
|
-
/**
|
|
22
|
-
* Creates a These holding both a first and a second value simultaneously.
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* ```ts
|
|
26
|
-
* These.both(42, "Deprecated API used"); // { kind: "Both", first: 42, second: "Deprecated API used" }
|
|
27
|
-
* ```
|
|
28
|
-
*/
|
|
29
|
-
These.both = (first, second) => ({
|
|
30
|
-
kind: "Both",
|
|
31
|
-
first,
|
|
32
|
-
second,
|
|
33
|
-
});
|
|
34
|
-
/**
|
|
35
|
-
* Type guard — checks if a These holds only a first value.
|
|
36
|
-
*/
|
|
37
|
-
These.isFirst = (data) => data.kind === "First";
|
|
38
|
-
/**
|
|
39
|
-
* Type guard — checks if a These holds only a second value.
|
|
40
|
-
*/
|
|
41
|
-
These.isSecond = (data) => data.kind === "Second";
|
|
42
|
-
/**
|
|
43
|
-
* Type guard — checks if a These holds both values simultaneously.
|
|
44
|
-
*/
|
|
45
|
-
These.isBoth = (data) => data.kind === "Both";
|
|
46
|
-
/**
|
|
47
|
-
* Returns true if the These contains a first value (First or Both).
|
|
48
|
-
*/
|
|
49
|
-
These.hasFirst = (data) => data.kind === "First" || data.kind === "Both";
|
|
50
|
-
/**
|
|
51
|
-
* Returns true if the These contains a second value (Second or Both).
|
|
52
|
-
*/
|
|
53
|
-
These.hasSecond = (data) => data.kind === "Second" || data.kind === "Both";
|
|
54
|
-
/**
|
|
55
|
-
* Transforms the first value, leaving the second unchanged.
|
|
56
|
-
*
|
|
57
|
-
* @example
|
|
58
|
-
* ```ts
|
|
59
|
-
* pipe(These.first(5), These.mapFirst(n => n * 2)); // First(10)
|
|
60
|
-
* pipe(These.both(5, "warn"), These.mapFirst(n => n * 2)); // Both(10, "warn")
|
|
61
|
-
* pipe(These.second("warn"), These.mapFirst(n => n * 2)); // Second("warn")
|
|
62
|
-
* ```
|
|
63
|
-
*/
|
|
64
|
-
These.mapFirst = (f) => (data) => {
|
|
65
|
-
if (These.isSecond(data))
|
|
66
|
-
return data;
|
|
67
|
-
if (These.isFirst(data))
|
|
68
|
-
return These.first(f(data.first));
|
|
69
|
-
return These.both(f(data.first), data.second);
|
|
70
|
-
};
|
|
71
|
-
/**
|
|
72
|
-
* Transforms the second value, leaving the first unchanged.
|
|
73
|
-
*
|
|
74
|
-
* @example
|
|
75
|
-
* ```ts
|
|
76
|
-
* pipe(These.second("warn"), These.mapSecond(e => e.toUpperCase())); // Second("WARN")
|
|
77
|
-
* pipe(These.both(5, "warn"), These.mapSecond(e => e.toUpperCase())); // Both(5, "WARN")
|
|
78
|
-
* ```
|
|
79
|
-
*/
|
|
80
|
-
These.mapSecond = (f) => (data) => {
|
|
81
|
-
if (These.isFirst(data))
|
|
82
|
-
return data;
|
|
83
|
-
if (These.isSecond(data))
|
|
84
|
-
return These.second(f(data.second));
|
|
85
|
-
return These.both(data.first, f(data.second));
|
|
86
|
-
};
|
|
87
|
-
/**
|
|
88
|
-
* Transforms both the first and second values independently.
|
|
89
|
-
*
|
|
90
|
-
* @example
|
|
91
|
-
* ```ts
|
|
92
|
-
* pipe(
|
|
93
|
-
* These.both(5, "warn"),
|
|
94
|
-
* These.mapBoth(n => n * 2, e => e.toUpperCase())
|
|
95
|
-
* ); // Both(10, "WARN")
|
|
96
|
-
* ```
|
|
97
|
-
*/
|
|
98
|
-
These.mapBoth = (onFirst, onSecond) => (data) => {
|
|
99
|
-
if (These.isSecond(data))
|
|
100
|
-
return These.second(onSecond(data.second));
|
|
101
|
-
if (These.isFirst(data))
|
|
102
|
-
return These.first(onFirst(data.first));
|
|
103
|
-
return These.both(onFirst(data.first), onSecond(data.second));
|
|
104
|
-
};
|
|
105
|
-
/**
|
|
106
|
-
* Chains These computations by passing the first value to f.
|
|
107
|
-
* Second propagates unchanged; First and Both apply f to the first value.
|
|
108
|
-
*
|
|
109
|
-
* @example
|
|
110
|
-
* ```ts
|
|
111
|
-
* const double = (n: number): These<number, string> => These.first(n * 2);
|
|
112
|
-
*
|
|
113
|
-
* pipe(These.first(5), These.chainFirst(double)); // First(10)
|
|
114
|
-
* pipe(These.both(5, "warn"), These.chainFirst(double)); // First(10)
|
|
115
|
-
* pipe(These.second("warn"), These.chainFirst(double)); // Second("warn")
|
|
116
|
-
* ```
|
|
117
|
-
*/
|
|
118
|
-
These.chainFirst = (f) => (data) => {
|
|
119
|
-
if (These.isSecond(data))
|
|
120
|
-
return data;
|
|
121
|
-
return f(data.first);
|
|
122
|
-
};
|
|
123
|
-
/**
|
|
124
|
-
* Chains These computations by passing the second value to f.
|
|
125
|
-
* First propagates unchanged; Second and Both apply f to the second value.
|
|
126
|
-
*
|
|
127
|
-
* @example
|
|
128
|
-
* ```ts
|
|
129
|
-
* const shout = (s: string): These<number, string> => These.second(s.toUpperCase());
|
|
130
|
-
*
|
|
131
|
-
* pipe(These.second("warn"), These.chainSecond(shout)); // Second("WARN")
|
|
132
|
-
* pipe(These.both(5, "warn"), These.chainSecond(shout)); // Second("WARN")
|
|
133
|
-
* pipe(These.first(5), These.chainSecond(shout)); // First(5)
|
|
134
|
-
* ```
|
|
135
|
-
*/
|
|
136
|
-
These.chainSecond = (f) => (data) => {
|
|
137
|
-
if (These.isFirst(data))
|
|
138
|
-
return data;
|
|
139
|
-
return f(data.second);
|
|
140
|
-
};
|
|
141
|
-
/**
|
|
142
|
-
* Extracts a value from a These by providing handlers for all three cases.
|
|
143
|
-
*
|
|
144
|
-
* @example
|
|
145
|
-
* ```ts
|
|
146
|
-
* pipe(
|
|
147
|
-
* these,
|
|
148
|
-
* These.fold(
|
|
149
|
-
* a => `First: ${a}`,
|
|
150
|
-
* b => `Second: ${b}`,
|
|
151
|
-
* (a, b) => `Both: ${a} / ${b}`
|
|
152
|
-
* )
|
|
153
|
-
* );
|
|
154
|
-
* ```
|
|
155
|
-
*/
|
|
156
|
-
These.fold = (onFirst, onSecond, onBoth) => (data) => {
|
|
157
|
-
if (These.isSecond(data))
|
|
158
|
-
return onSecond(data.second);
|
|
159
|
-
if (These.isFirst(data))
|
|
160
|
-
return onFirst(data.first);
|
|
161
|
-
return onBoth(data.first, data.second);
|
|
162
|
-
};
|
|
163
|
-
/**
|
|
164
|
-
* Pattern matches on a These, returning the result of the matching case.
|
|
165
|
-
*
|
|
166
|
-
* @example
|
|
167
|
-
* ```ts
|
|
168
|
-
* pipe(
|
|
169
|
-
* these,
|
|
170
|
-
* These.match({
|
|
171
|
-
* first: a => `First: ${a}`,
|
|
172
|
-
* second: b => `Second: ${b}`,
|
|
173
|
-
* both: (a, b) => `Both: ${a} / ${b}`
|
|
174
|
-
* })
|
|
175
|
-
* );
|
|
176
|
-
* ```
|
|
177
|
-
*/
|
|
178
|
-
These.match = (cases) => (data) => {
|
|
179
|
-
if (These.isSecond(data))
|
|
180
|
-
return cases.second(data.second);
|
|
181
|
-
if (These.isFirst(data))
|
|
182
|
-
return cases.first(data.first);
|
|
183
|
-
return cases.both(data.first, data.second);
|
|
184
|
-
};
|
|
185
|
-
/**
|
|
186
|
-
* Returns the first value, or a default if the These has no first value.
|
|
187
|
-
* The default can be a different type, widening the result to `A | C`.
|
|
188
|
-
*
|
|
189
|
-
* @example
|
|
190
|
-
* ```ts
|
|
191
|
-
* pipe(These.first(5), These.getFirstOrElse(() => 0)); // 5
|
|
192
|
-
* pipe(These.both(5, "warn"), These.getFirstOrElse(() => 0)); // 5
|
|
193
|
-
* pipe(These.second("warn"), These.getFirstOrElse(() => 0)); // 0
|
|
194
|
-
* pipe(These.second("warn"), These.getFirstOrElse(() => null)); // null — typed as number | null
|
|
195
|
-
* ```
|
|
196
|
-
*/
|
|
197
|
-
These.getFirstOrElse = (defaultValue) => (data) => These.hasFirst(data) ? data.first : defaultValue();
|
|
198
|
-
/**
|
|
199
|
-
* Returns the second value, or a default if the These has no second value.
|
|
200
|
-
* The default can be a different type, widening the result to `B | D`.
|
|
201
|
-
*
|
|
202
|
-
* @example
|
|
203
|
-
* ```ts
|
|
204
|
-
* pipe(These.second("warn"), These.getSecondOrElse(() => "none")); // "warn"
|
|
205
|
-
* pipe(These.both(5, "warn"), These.getSecondOrElse(() => "none")); // "warn"
|
|
206
|
-
* pipe(These.first(5), These.getSecondOrElse(() => "none")); // "none"
|
|
207
|
-
* pipe(These.first(5), These.getSecondOrElse(() => null)); // null — typed as string | null
|
|
208
|
-
* ```
|
|
209
|
-
*/
|
|
210
|
-
These.getSecondOrElse = (defaultValue) => (data) => These.hasSecond(data) ? data.second : defaultValue();
|
|
211
|
-
/**
|
|
212
|
-
* Executes a side effect on the first value without changing the These.
|
|
213
|
-
* Useful for logging or debugging.
|
|
214
|
-
*
|
|
215
|
-
* @example
|
|
216
|
-
* ```ts
|
|
217
|
-
* pipe(These.first(5), These.tap(console.log)); // logs 5, returns First(5)
|
|
218
|
-
* ```
|
|
219
|
-
*/
|
|
220
|
-
These.tap = (f) => (data) => {
|
|
221
|
-
if (These.hasFirst(data))
|
|
222
|
-
f(data.first);
|
|
223
|
-
return data;
|
|
224
|
-
};
|
|
225
|
-
/**
|
|
226
|
-
* Swaps the roles of first and second values.
|
|
227
|
-
* - First(a) → Second(a)
|
|
228
|
-
* - Second(b) → First(b)
|
|
229
|
-
* - Both(a, b) → Both(b, a)
|
|
230
|
-
*
|
|
231
|
-
* @example
|
|
232
|
-
* ```ts
|
|
233
|
-
* These.swap(These.first(5)); // Second(5)
|
|
234
|
-
* These.swap(These.second("warn")); // First("warn")
|
|
235
|
-
* These.swap(These.both(5, "warn")); // Both("warn", 5)
|
|
236
|
-
* ```
|
|
237
|
-
*/
|
|
238
|
-
These.swap = (data) => {
|
|
239
|
-
if (These.isSecond(data))
|
|
240
|
-
return These.first(data.second);
|
|
241
|
-
if (These.isFirst(data))
|
|
242
|
-
return These.second(data.first);
|
|
243
|
-
return These.both(data.second, data.first);
|
|
244
|
-
};
|
|
245
|
-
})(These || (These = {}));
|
package/esm/src/Core/Tuple.js
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
export var Tuple;
|
|
2
|
-
(function (Tuple) {
|
|
3
|
-
/**
|
|
4
|
-
* Creates a pair from two values.
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```ts
|
|
8
|
-
* Tuple.make("Paris", 2_161_000); // ["Paris", 2161000]
|
|
9
|
-
* ```
|
|
10
|
-
*/
|
|
11
|
-
Tuple.make = (first, second) => [first, second];
|
|
12
|
-
/**
|
|
13
|
-
* Returns the first value from the pair.
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```ts
|
|
17
|
-
* Tuple.first(Tuple.make("Paris", 2_161_000)); // "Paris"
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
Tuple.first = (tuple) => tuple[0];
|
|
21
|
-
/**
|
|
22
|
-
* Returns the second value from the pair.
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* ```ts
|
|
26
|
-
* Tuple.second(Tuple.make("Paris", 2_161_000)); // 2161000
|
|
27
|
-
* ```
|
|
28
|
-
*/
|
|
29
|
-
Tuple.second = (tuple) => tuple[1];
|
|
30
|
-
/**
|
|
31
|
-
* Transforms the first value, leaving the second unchanged.
|
|
32
|
-
*
|
|
33
|
-
* @example
|
|
34
|
-
* ```ts
|
|
35
|
-
* pipe(Tuple.make("alice", 42), Tuple.mapFirst((s) => s.toUpperCase())); // ["ALICE", 42]
|
|
36
|
-
* ```
|
|
37
|
-
*/
|
|
38
|
-
Tuple.mapFirst = (f) => (tuple) => [f(tuple[0]), tuple[1]];
|
|
39
|
-
/**
|
|
40
|
-
* Transforms the second value, leaving the first unchanged.
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* ```ts
|
|
44
|
-
* pipe(Tuple.make("alice", 42), Tuple.mapSecond((n) => n * 2)); // ["alice", 84]
|
|
45
|
-
* ```
|
|
46
|
-
*/
|
|
47
|
-
Tuple.mapSecond = (f) => (tuple) => [tuple[0], f(tuple[1])];
|
|
48
|
-
/**
|
|
49
|
-
* Transforms both values independently in a single step.
|
|
50
|
-
*
|
|
51
|
-
* @example
|
|
52
|
-
* ```ts
|
|
53
|
-
* pipe(
|
|
54
|
-
* Tuple.make("alice", 42),
|
|
55
|
-
* Tuple.mapBoth(
|
|
56
|
-
* (name) => name.toUpperCase(),
|
|
57
|
-
* (score) => score * 2,
|
|
58
|
-
* ),
|
|
59
|
-
* ); // ["ALICE", 84]
|
|
60
|
-
* ```
|
|
61
|
-
*/
|
|
62
|
-
Tuple.mapBoth = (onFirst, onSecond) => (tuple) => [
|
|
63
|
-
onFirst(tuple[0]),
|
|
64
|
-
onSecond(tuple[1]),
|
|
65
|
-
];
|
|
66
|
-
/**
|
|
67
|
-
* Applies a binary function to both values, collapsing the pair into a single value.
|
|
68
|
-
* Useful as the final step when consuming a pair in a pipeline.
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* ```ts
|
|
72
|
-
* pipe(Tuple.make("Alice", 100), Tuple.fold((name, score) => `${name}: ${score}`));
|
|
73
|
-
* // "Alice: 100"
|
|
74
|
-
* ```
|
|
75
|
-
*/
|
|
76
|
-
Tuple.fold = (f) => (tuple) => f(tuple[0], tuple[1]);
|
|
77
|
-
/**
|
|
78
|
-
* Swaps the two values: `[A, B]` becomes `[B, A]`.
|
|
79
|
-
*
|
|
80
|
-
* @example
|
|
81
|
-
* ```ts
|
|
82
|
-
* Tuple.swap(Tuple.make("key", 1)); // [1, "key"]
|
|
83
|
-
* ```
|
|
84
|
-
*/
|
|
85
|
-
Tuple.swap = (tuple) => [tuple[1], tuple[0]];
|
|
86
|
-
/**
|
|
87
|
-
* Converts the pair to a heterogeneous readonly array `readonly (A | B)[]`.
|
|
88
|
-
*
|
|
89
|
-
* @example
|
|
90
|
-
* ```ts
|
|
91
|
-
* Tuple.toArray(Tuple.make("hello", 42)); // ["hello", 42]
|
|
92
|
-
* ```
|
|
93
|
-
*/
|
|
94
|
-
Tuple.toArray = (tuple) => [...tuple];
|
|
95
|
-
/**
|
|
96
|
-
* Runs a side effect with both values without changing the pair.
|
|
97
|
-
* Useful for logging or debugging in the middle of a pipeline.
|
|
98
|
-
*
|
|
99
|
-
* @example
|
|
100
|
-
* ```ts
|
|
101
|
-
* pipe(
|
|
102
|
-
* Tuple.make("Paris", 2_161_000),
|
|
103
|
-
* Tuple.tap((city, pop) => console.log(`${city}: ${pop}`)),
|
|
104
|
-
* Tuple.mapSecond((n) => n / 1_000_000),
|
|
105
|
-
* ); // logs "Paris: 2161000", returns ["Paris", 2.161]
|
|
106
|
-
* ```
|
|
107
|
-
*/
|
|
108
|
-
Tuple.tap = (f) => (tuple) => {
|
|
109
|
-
f(tuple[0], tuple[1]);
|
|
110
|
-
return tuple;
|
|
111
|
-
};
|
|
112
|
-
})(Tuple || (Tuple = {}));
|
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
export var Validation;
|
|
2
|
-
(function (Validation) {
|
|
3
|
-
/**
|
|
4
|
-
* Wraps a value in a valid Validation.
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```ts
|
|
8
|
-
* Validation.valid(42); // Valid(42)
|
|
9
|
-
* ```
|
|
10
|
-
*/
|
|
11
|
-
Validation.valid = (value) => ({
|
|
12
|
-
kind: "Valid",
|
|
13
|
-
value,
|
|
14
|
-
});
|
|
15
|
-
/**
|
|
16
|
-
* Creates an invalid Validation from a single error.
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```ts
|
|
20
|
-
* Validation.invalid("Invalid input");
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
Validation.invalid = (error) => ({
|
|
24
|
-
kind: "Invalid",
|
|
25
|
-
errors: [error],
|
|
26
|
-
});
|
|
27
|
-
/**
|
|
28
|
-
* Creates an invalid Validation from multiple errors.
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* ```ts
|
|
32
|
-
* Validation.invalidAll(["Invalid input"]);
|
|
33
|
-
* ```
|
|
34
|
-
*/
|
|
35
|
-
Validation.invalidAll = (errors) => ({
|
|
36
|
-
kind: "Invalid",
|
|
37
|
-
errors,
|
|
38
|
-
});
|
|
39
|
-
/**
|
|
40
|
-
* Type guard that checks if a Validation is valid.
|
|
41
|
-
*/
|
|
42
|
-
Validation.isValid = (data) => data.kind === "Valid";
|
|
43
|
-
/**
|
|
44
|
-
* Type guard that checks if a Validation is invalid.
|
|
45
|
-
*/
|
|
46
|
-
Validation.isInvalid = (data) => data.kind === "Invalid";
|
|
47
|
-
/**
|
|
48
|
-
* Transforms the success value inside a Validation.
|
|
49
|
-
*
|
|
50
|
-
* @example
|
|
51
|
-
* ```ts
|
|
52
|
-
* pipe(Validation.valid(5), Validation.map(n => n * 2)); // Valid(10)
|
|
53
|
-
* pipe(Validation.invalid("oops"), Validation.map(n => n * 2)); // Invalid(["oops"])
|
|
54
|
-
* ```
|
|
55
|
-
*/
|
|
56
|
-
Validation.map = (f) => (data) => Validation.isValid(data) ? Validation.valid(f(data.value)) : data;
|
|
57
|
-
/**
|
|
58
|
-
* Applies a function wrapped in a Validation to a value wrapped in a Validation.
|
|
59
|
-
* Accumulates errors from both sides.
|
|
60
|
-
*
|
|
61
|
-
* @example
|
|
62
|
-
* ```ts
|
|
63
|
-
* const add = (a: number) => (b: number) => a + b;
|
|
64
|
-
* pipe(
|
|
65
|
-
* Validation.valid(add),
|
|
66
|
-
* Validation.ap(Validation.valid(5)),
|
|
67
|
-
* Validation.ap(Validation.valid(3))
|
|
68
|
-
* ); // Valid(8)
|
|
69
|
-
*
|
|
70
|
-
* pipe(
|
|
71
|
-
* Validation.valid(add),
|
|
72
|
-
* Validation.ap(Validation.invalid<string, number>("bad a")),
|
|
73
|
-
* Validation.ap(Validation.invalid<string, number>("bad b"))
|
|
74
|
-
* ); // Invalid(["bad a", "bad b"])
|
|
75
|
-
* ```
|
|
76
|
-
*/
|
|
77
|
-
Validation.ap = (arg) => (data) => {
|
|
78
|
-
if (Validation.isValid(data) && Validation.isValid(arg))
|
|
79
|
-
return Validation.valid(data.value(arg.value));
|
|
80
|
-
const errors = [
|
|
81
|
-
...(Validation.isInvalid(data) ? data.errors : []),
|
|
82
|
-
...(Validation.isInvalid(arg) ? arg.errors : []),
|
|
83
|
-
];
|
|
84
|
-
return Validation.invalidAll(errors);
|
|
85
|
-
};
|
|
86
|
-
/**
|
|
87
|
-
* Extracts the value from a Validation by providing handlers for both cases.
|
|
88
|
-
*
|
|
89
|
-
* @example
|
|
90
|
-
* ```ts
|
|
91
|
-
* pipe(
|
|
92
|
-
* Validation.valid(42),
|
|
93
|
-
* Validation.fold(
|
|
94
|
-
* errors => `Errors: ${errors.join(", ")}`,
|
|
95
|
-
* value => `Value: ${value}`
|
|
96
|
-
* )
|
|
97
|
-
* );
|
|
98
|
-
* ```
|
|
99
|
-
*/
|
|
100
|
-
Validation.fold = (onInvalid, onValid) => (data) => Validation.isValid(data) ? onValid(data.value) : onInvalid(data.errors);
|
|
101
|
-
/**
|
|
102
|
-
* Pattern matches on a Validation, returning the result of the matching case.
|
|
103
|
-
*
|
|
104
|
-
* @example
|
|
105
|
-
* ```ts
|
|
106
|
-
* pipe(
|
|
107
|
-
* validation,
|
|
108
|
-
* Validation.match({
|
|
109
|
-
* valid: value => `Got ${value}`,
|
|
110
|
-
* invalid: errors => `Failed: ${errors.join(", ")}`
|
|
111
|
-
* })
|
|
112
|
-
* );
|
|
113
|
-
* ```
|
|
114
|
-
*/
|
|
115
|
-
Validation.match = (cases) => (data) => Validation.isValid(data) ? cases.valid(data.value) : cases.invalid(data.errors);
|
|
116
|
-
/**
|
|
117
|
-
* Returns the success value or a default value if the Validation is invalid.
|
|
118
|
-
* The default can be a different type, widening the result to `A | B`.
|
|
119
|
-
*
|
|
120
|
-
* @example
|
|
121
|
-
* ```ts
|
|
122
|
-
* pipe(Validation.valid(5), Validation.getOrElse(() => 0)); // 5
|
|
123
|
-
* pipe(Validation.invalid("oops"), Validation.getOrElse(() => 0)); // 0
|
|
124
|
-
* pipe(Validation.invalid("oops"), Validation.getOrElse(() => null)); // null — typed as number | null
|
|
125
|
-
* ```
|
|
126
|
-
*/
|
|
127
|
-
Validation.getOrElse = (defaultValue) => (data) => Validation.isValid(data) ? data.value : defaultValue();
|
|
128
|
-
/**
|
|
129
|
-
* Executes a side effect on the success value without changing the Validation.
|
|
130
|
-
*
|
|
131
|
-
* @example
|
|
132
|
-
* ```ts
|
|
133
|
-
* pipe(
|
|
134
|
-
* Validation.valid(5),
|
|
135
|
-
* Validation.tap(n => console.log("Value:", n)),
|
|
136
|
-
* Validation.map(n => n * 2)
|
|
137
|
-
* );
|
|
138
|
-
* ```
|
|
139
|
-
*/
|
|
140
|
-
Validation.tap = (f) => (data) => {
|
|
141
|
-
if (Validation.isValid(data))
|
|
142
|
-
f(data.value);
|
|
143
|
-
return data;
|
|
144
|
-
};
|
|
145
|
-
/**
|
|
146
|
-
* Recovers from an Invalid state by providing a fallback Validation.
|
|
147
|
-
* The fallback receives the accumulated error list so callers can inspect which errors occurred.
|
|
148
|
-
* The fallback can produce a different success type, widening the result to `Validation<E, A | B>`.
|
|
149
|
-
*/
|
|
150
|
-
Validation.recover = (fallback) => (data) => Validation.isValid(data) ? data : fallback(data.errors);
|
|
151
|
-
/**
|
|
152
|
-
* Recovers from an Invalid state unless the errors contain any of the blocked errors.
|
|
153
|
-
* The fallback can produce a different success type, widening the result to `Validation<E, A | B>`.
|
|
154
|
-
*/
|
|
155
|
-
Validation.recoverUnless = (blockedErrors, fallback) => (data) => Validation.isInvalid(data) &&
|
|
156
|
-
!data.errors.some((err) => blockedErrors.includes(err))
|
|
157
|
-
? fallback()
|
|
158
|
-
: data;
|
|
159
|
-
/**
|
|
160
|
-
* Combines two independent Validation instances into a tuple.
|
|
161
|
-
* If both are Valid, returns Valid with both values as a tuple.
|
|
162
|
-
* If either is Invalid, accumulates errors from both sides.
|
|
163
|
-
*
|
|
164
|
-
* @example
|
|
165
|
-
* ```ts
|
|
166
|
-
* Validation.product(
|
|
167
|
-
* Validation.valid("alice"),
|
|
168
|
-
* Validation.valid(30)
|
|
169
|
-
* ); // Valid(["alice", 30])
|
|
170
|
-
*
|
|
171
|
-
* Validation.product(
|
|
172
|
-
* Validation.invalid("Name required"),
|
|
173
|
-
* Validation.invalid("Age must be >= 0")
|
|
174
|
-
* ); // Invalid(["Name required", "Age must be >= 0"])
|
|
175
|
-
* ```
|
|
176
|
-
*/
|
|
177
|
-
Validation.product = (first, second) => {
|
|
178
|
-
if (Validation.isValid(first) && Validation.isValid(second))
|
|
179
|
-
return Validation.valid([first.value, second.value]);
|
|
180
|
-
const errors = [
|
|
181
|
-
...(Validation.isInvalid(first) ? first.errors : []),
|
|
182
|
-
...(Validation.isInvalid(second) ? second.errors : []),
|
|
183
|
-
];
|
|
184
|
-
return Validation.invalidAll(errors);
|
|
185
|
-
};
|
|
186
|
-
/**
|
|
187
|
-
* Combines a non-empty list of Validation instances, accumulating all errors.
|
|
188
|
-
* If all are Valid, returns Valid with all values collected into an array.
|
|
189
|
-
* If any are Invalid, returns Invalid with all accumulated errors.
|
|
190
|
-
*
|
|
191
|
-
* @example
|
|
192
|
-
* ```ts
|
|
193
|
-
* Validation.productAll([
|
|
194
|
-
* validateName(name),
|
|
195
|
-
* validateEmail(email),
|
|
196
|
-
* validateAge(age)
|
|
197
|
-
* ]);
|
|
198
|
-
* // Valid([name, email, age]) or Invalid([...all errors])
|
|
199
|
-
* ```
|
|
200
|
-
*/
|
|
201
|
-
Validation.productAll = (data) => {
|
|
202
|
-
const values = [];
|
|
203
|
-
const errors = [];
|
|
204
|
-
for (const v of data) {
|
|
205
|
-
if (Validation.isValid(v))
|
|
206
|
-
values.push(v.value);
|
|
207
|
-
else
|
|
208
|
-
errors.push(...v.errors);
|
|
209
|
-
}
|
|
210
|
-
return errors.length > 0 ? Validation.invalidAll(errors) : Validation.valid(values);
|
|
211
|
-
};
|
|
212
|
-
})(Validation || (Validation = {}));
|