@kaumlaut/pure 0.5.2 → 2.0.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/LICENSE +21 -0
- package/README.md +3 -1
- package/dist/error-aware-guard/index.d.ts +186 -0
- package/dist/error-aware-guard/index.d.ts.map +1 -0
- package/dist/error-aware-guard/index.js +313 -0
- package/dist/fetch-state/index.d.ts +17 -4
- package/dist/fetch-state/index.d.ts.map +1 -1
- package/dist/fetch-state/index.js +30 -4
- package/dist/guard/index.d.ts +13 -1
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +18 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/maybe/index.d.ts +20 -2
- package/dist/maybe/index.d.ts.map +1 -1
- package/dist/maybe/index.js +36 -0
- package/dist/runtime/effect/fetch/index.d.ts +2 -2
- package/dist/runtime/effect/fetch/index.d.ts.map +1 -1
- package/dist/runtime/index.d.ts +2 -2
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/persistence/index.d.ts +2 -2
- package/dist/runtime/persistence/index.d.ts.map +1 -1
- package/package.json +12 -6
- package/docs/README.md +0 -23
- package/docs/clone.md +0 -45
- package/docs/fetch-state.md +0 -368
- package/docs/guard.md +0 -729
- package/docs/maybe.md +0 -481
- package/docs/parse.md +0 -47
- package/docs/pipe.md +0 -95
- package/docs/result.md +0 -363
- package/docs/runtime/effect/fetch.md +0 -169
- package/docs/runtime/effect/none.md +0 -19
- package/docs/runtime/effect.md +0 -179
- package/docs/runtime/persistence/none.md +0 -29
- package/docs/runtime/persistence/storage.md +0 -39
- package/docs/runtime/persistence.md +0 -63
- package/docs/runtime.md +0 -167
- package/docs/util.md +0 -33
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Max Kämmerer
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @kaumlaut/pure
|
|
2
2
|
|
|
3
|
+

|
|
4
|
+
|
|
3
5
|
Types and functions for a state runtime inspired by Elm and functional programming
|
|
4
6
|
|
|
5
|
-
- [API Reference](https://github.com/maxkaemmerer/pure
|
|
7
|
+
- [API Reference](https://github.com/maxkaemmerer/pure/blob/main/docs/README.md)
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provides easily composable generic type guards that track errors
|
|
3
|
+
* @module error-aware-guard
|
|
4
|
+
*/
|
|
5
|
+
import * as Guard from "@kaumlaut/pure/guard";
|
|
6
|
+
/**
|
|
7
|
+
* Represents a successful ErrorAwareGuard, containing the value
|
|
8
|
+
*/
|
|
9
|
+
export type SuccessResult<T> = {
|
|
10
|
+
readonly success: true;
|
|
11
|
+
readonly value: T;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Represents a failed ErrorAwareGuard, containing errors
|
|
15
|
+
*/
|
|
16
|
+
export type ErrorResult = {
|
|
17
|
+
readonly success: false;
|
|
18
|
+
readonly errors: string[];
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Represents the result of a ErrorAwareGuard
|
|
22
|
+
*/
|
|
23
|
+
export type ValidationResult<T> = SuccessResult<T> | ErrorResult;
|
|
24
|
+
/**
|
|
25
|
+
* Represents a function that returns a wrapped value on success or a wrapped error on failure
|
|
26
|
+
*/
|
|
27
|
+
export type ErrorAwareGuard<T> = (value: unknown) => ValidationResult<T>;
|
|
28
|
+
/**
|
|
29
|
+
* Creates an ErrorResult with the given errors
|
|
30
|
+
*/
|
|
31
|
+
export declare function fail(...errors: string[]): ErrorResult;
|
|
32
|
+
/**
|
|
33
|
+
* Creates an SuccessResult<T> with the given value
|
|
34
|
+
*/
|
|
35
|
+
export declare function pass<T>(value: T): SuccessResult<T>;
|
|
36
|
+
/**
|
|
37
|
+
* Takes a ValidationResult<T> and if it is an ErrorResult, prefixes every error with the given prefix.
|
|
38
|
+
*/
|
|
39
|
+
export declare function prefixErrors<T>(value: ValidationResult<T>, prefix: string): ValidationResult<T>;
|
|
40
|
+
/**
|
|
41
|
+
* Converts an ErrorAwareGuard<T> to a Guard<T>
|
|
42
|
+
*/
|
|
43
|
+
export declare function toGuard<T>(guard: ErrorAwareGuard<T>): Guard.Guard<T>;
|
|
44
|
+
/**
|
|
45
|
+
* Evaluates an ErrorAwareGuard<T> for given value
|
|
46
|
+
*/
|
|
47
|
+
export declare function check<T>(value: unknown, guard: ErrorAwareGuard<T>): value is T;
|
|
48
|
+
/**
|
|
49
|
+
* Combines a list of results. Returning a SuccessResult<T> if all of them are SucessResult<T>
|
|
50
|
+
* or returns an ErrorResult with combined errors if any of them are ErrorResult.
|
|
51
|
+
*/
|
|
52
|
+
export declare function combineResultsAll<T>(...results: ValidationResult<T>[]): ValidationResult<T>;
|
|
53
|
+
/**
|
|
54
|
+
* Combines two results. Returning a SuccessResult<T> if both of them are SucessResult<T>
|
|
55
|
+
* or returns an ErrorResult with combined errors if one is an ErrorResult.
|
|
56
|
+
*/
|
|
57
|
+
export declare function combineTwoResultsAnd<T1, T2>(a: ValidationResult<T1>, b: ValidationResult<T2>): ValidationResult<T1 & T2>;
|
|
58
|
+
/**
|
|
59
|
+
* Combines two results. Returning a SuccessResult<T> if either of them are SucessResult<T>
|
|
60
|
+
* or returns an ErrorResult with combined errors if both are an ErrorResult.
|
|
61
|
+
*/
|
|
62
|
+
export declare function combineTwoResultsOneOf<T1, T2>(a: ValidationResult<T1>, b: ValidationResult<T2>): ValidationResult<T1 | T2>;
|
|
63
|
+
/**
|
|
64
|
+
* Combines a list of results. Returning a SuccessResult<T> if either of them are SucessResult<T>
|
|
65
|
+
* or returns an ErrorResult with combined errors if all are an ErrorResult.
|
|
66
|
+
*/
|
|
67
|
+
export declare function combineResultsOneOf<T>(...results: ValidationResult<T>[]): ValidationResult<T>;
|
|
68
|
+
/**
|
|
69
|
+
* Converts a Guard<T> to an ErrorAwareGuard<T> with provided error factory function
|
|
70
|
+
*/
|
|
71
|
+
export declare function fromGuard<T>(guard: Guard.Guard<T>, createErrors: (value: unknown) => string[]): ErrorAwareGuard<T>;
|
|
72
|
+
/**
|
|
73
|
+
* First applies the predicateGuard and if it is a SuccessResult<T> passes the value to check.
|
|
74
|
+
* If check returns true it creates SuccessResult<T>.
|
|
75
|
+
* Otherwise an ErrorResult is created, containing the errors created by the error factory function.
|
|
76
|
+
*/
|
|
77
|
+
export declare function tryGuardIf<T, T2 extends T = T>(predicateGuard: ErrorAwareGuard<T>, check: (value: T) => value is T2, createErrors: (value: T) => string[]): ErrorAwareGuard<T2>;
|
|
78
|
+
/**
|
|
79
|
+
* Confirms that the given value passes both guards.
|
|
80
|
+
*/
|
|
81
|
+
export declare function isBoth<T1, T2>(a: ErrorAwareGuard<T1>, b: ErrorAwareGuard<T2>): ErrorAwareGuard<T1 & T2>;
|
|
82
|
+
/**
|
|
83
|
+
* Confirms that the given value passes all guards.
|
|
84
|
+
*/
|
|
85
|
+
export declare function isAll<T>(guards: ErrorAwareGuard<T>[]): ErrorAwareGuard<T>;
|
|
86
|
+
/**
|
|
87
|
+
* Confirms the value passes at least one of the given Guards.
|
|
88
|
+
*/
|
|
89
|
+
export declare function isOneOf<T1, T2>(a: ErrorAwareGuard<T1>, b: ErrorAwareGuard<T2>): ErrorAwareGuard<T1 | T2>;
|
|
90
|
+
/**
|
|
91
|
+
* Confirms the value is a list of items that all pass the given guard.
|
|
92
|
+
*/
|
|
93
|
+
export declare function isListOf<I, T extends I[]>(guard: ErrorAwareGuard<I>): ErrorAwareGuard<T>;
|
|
94
|
+
/**
|
|
95
|
+
* Confirms that the value is a number.
|
|
96
|
+
*/
|
|
97
|
+
export declare const isNumber: ErrorAwareGuard<number>;
|
|
98
|
+
/**
|
|
99
|
+
* Confirms that the value is a string.
|
|
100
|
+
*/
|
|
101
|
+
export declare const isString: <T extends string>(value: unknown) => ValidationResult<T>;
|
|
102
|
+
/**
|
|
103
|
+
* Confirms that the value is an exact string.
|
|
104
|
+
*/
|
|
105
|
+
export declare const isExactString: <T extends string>(expectedString: T) => ErrorAwareGuard<T>;
|
|
106
|
+
/**
|
|
107
|
+
* Confirms that the value is a boolean.
|
|
108
|
+
*/
|
|
109
|
+
export declare const isBool: ErrorAwareGuard<boolean>;
|
|
110
|
+
/**
|
|
111
|
+
* Confirms that the value is a float.
|
|
112
|
+
*/
|
|
113
|
+
export declare const isFloat: ErrorAwareGuard<number>;
|
|
114
|
+
/**
|
|
115
|
+
* Confirms that the value is an interger.
|
|
116
|
+
*/
|
|
117
|
+
export declare const isInt: ErrorAwareGuard<number>;
|
|
118
|
+
/**
|
|
119
|
+
* Confirms that the value is null.
|
|
120
|
+
*/
|
|
121
|
+
export declare const isNull: ErrorAwareGuard<null>;
|
|
122
|
+
/**
|
|
123
|
+
* Confirms that the value is undefined.
|
|
124
|
+
*/
|
|
125
|
+
export declare const isUndefined: ErrorAwareGuard<undefined>;
|
|
126
|
+
/**
|
|
127
|
+
* Confirms that the value is an object.
|
|
128
|
+
*/
|
|
129
|
+
export declare const isObject: ErrorAwareGuard<object>;
|
|
130
|
+
/**
|
|
131
|
+
* Always passes.
|
|
132
|
+
*/
|
|
133
|
+
export declare const isAlways: ErrorAwareGuard<unknown>;
|
|
134
|
+
/**
|
|
135
|
+
* Never passes.
|
|
136
|
+
*/
|
|
137
|
+
export declare const isNever: ErrorAwareGuard<unknown>;
|
|
138
|
+
/**
|
|
139
|
+
* Confirms that the value is a non-empty string.
|
|
140
|
+
*/
|
|
141
|
+
export declare const isNonEmptyString: ErrorAwareGuard<string>;
|
|
142
|
+
/**
|
|
143
|
+
* Confirms that the value is a string with specified length.
|
|
144
|
+
*/
|
|
145
|
+
export declare const isStringOfLength: (length: number) => ErrorAwareGuard<string>;
|
|
146
|
+
/**
|
|
147
|
+
* Confirms the value is a string and matches the given regular expression.
|
|
148
|
+
*/
|
|
149
|
+
export declare const isStringWithPattern: (pattern: RegExp) => ErrorAwareGuard<string>;
|
|
150
|
+
/**
|
|
151
|
+
* Confirms the value is a list with atleast one item and all items match the given guard.
|
|
152
|
+
*/
|
|
153
|
+
export declare const isNonEmptyListOf: <I, T extends I[]>(guard: ErrorAwareGuard<I>) => ErrorAwareGuard<T>;
|
|
154
|
+
/**
|
|
155
|
+
* Confirms the value is number between min and max inclusive.
|
|
156
|
+
* Meaning if the value equals min or max the guard passes.
|
|
157
|
+
*/
|
|
158
|
+
export declare const isNumberBetweenInclusive: (min: number, max: number) => ErrorAwareGuard<number>;
|
|
159
|
+
/**
|
|
160
|
+
* Confirms the value is either null or passes the given Guard.
|
|
161
|
+
*/
|
|
162
|
+
export declare const isNullOr: <T>(guard: ErrorAwareGuard<T>) => ErrorAwareGuard<T>;
|
|
163
|
+
export declare const isOneStringOf: <T extends string>(validValues: T[]) => ErrorAwareGuard<T>;
|
|
164
|
+
/**
|
|
165
|
+
* Confirms that the value is an object containing the specified key.
|
|
166
|
+
*/
|
|
167
|
+
export declare function isObjectWithKey<T extends object, K extends keyof T>(key: K): ErrorAwareGuard<T>;
|
|
168
|
+
/**
|
|
169
|
+
* Confirms that the value is an object containing the specified key the value matching the given guard.
|
|
170
|
+
*/
|
|
171
|
+
export declare function isObjectWithKeyMatchingGuard<T extends object, K extends keyof T>(key: K, guard: ErrorAwareGuard<T[K]>): ErrorAwareGuard<T>;
|
|
172
|
+
/**
|
|
173
|
+
* Confirms that the value is an object containing the specified keys.
|
|
174
|
+
*/
|
|
175
|
+
export declare function isObjectWithKeys<T extends object, K extends keyof T>(keys: K[]): ErrorAwareGuard<T>;
|
|
176
|
+
/**
|
|
177
|
+
* Confirms that the value is an object whose key value pairs match the corresponding type guards.
|
|
178
|
+
*/
|
|
179
|
+
export declare function isObjectWithKeysMatchingGuard<T extends object, K extends keyof T>(guards: {
|
|
180
|
+
[K in keyof T]: ErrorAwareGuard<T[K]>;
|
|
181
|
+
}): ErrorAwareGuard<T>;
|
|
182
|
+
/**
|
|
183
|
+
* Confirms the value is an object where every value matches the given guard.
|
|
184
|
+
*/
|
|
185
|
+
export declare function isObjectWithAllKeysMatchingGuard<T extends object, K extends keyof T>(guard: ErrorAwareGuard<T[K]>): ErrorAwareGuard<T>;
|
|
186
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/error-aware-guard/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provides easily composable generic type guards that track errors
|
|
3
|
+
* @module error-aware-guard
|
|
4
|
+
*/
|
|
5
|
+
import * as Guard from "@kaumlaut/pure/guard";
|
|
6
|
+
/**
|
|
7
|
+
* Creates an ErrorResult with the given errors
|
|
8
|
+
*/
|
|
9
|
+
export function fail(...errors) {
|
|
10
|
+
return {
|
|
11
|
+
success: false,
|
|
12
|
+
errors: [...errors],
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Creates an SuccessResult<T> with the given value
|
|
17
|
+
*/
|
|
18
|
+
export function pass(value) {
|
|
19
|
+
return {
|
|
20
|
+
success: true,
|
|
21
|
+
value,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Takes a ValidationResult<T> and if it is an ErrorResult, prefixes every error with the given prefix.
|
|
26
|
+
*/
|
|
27
|
+
export function prefixErrors(value, prefix) {
|
|
28
|
+
if (value.success === true) {
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
success: false,
|
|
33
|
+
errors: value.errors.map((it) => `${prefix}${it}`),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Converts an ErrorAwareGuard<T> to a Guard<T>
|
|
38
|
+
*/
|
|
39
|
+
export function toGuard(guard) {
|
|
40
|
+
return (value) => guard(value).success;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Evaluates an ErrorAwareGuard<T> for given value
|
|
44
|
+
*/
|
|
45
|
+
export function check(value, guard) {
|
|
46
|
+
return guard(value).success;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Combines a list of results. Returning a SuccessResult<T> if all of them are SucessResult<T>
|
|
50
|
+
* or returns an ErrorResult with combined errors if any of them are ErrorResult.
|
|
51
|
+
*/
|
|
52
|
+
export function combineResultsAll(...results) {
|
|
53
|
+
const successResult = results.find((it) => it.success);
|
|
54
|
+
if (successResult &&
|
|
55
|
+
successResult.success &&
|
|
56
|
+
results.every((it) => it.success)) {
|
|
57
|
+
return pass(successResult.value);
|
|
58
|
+
}
|
|
59
|
+
return fail(...results.reduce((all, result) => [
|
|
60
|
+
...all,
|
|
61
|
+
...(result.success === true ? [] : result.errors),
|
|
62
|
+
], []));
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Combines two results. Returning a SuccessResult<T> if both of them are SucessResult<T>
|
|
66
|
+
* or returns an ErrorResult with combined errors if one is an ErrorResult.
|
|
67
|
+
*/
|
|
68
|
+
export function combineTwoResultsAnd(a, b) {
|
|
69
|
+
if (a.success === true && b.success === true) {
|
|
70
|
+
return a;
|
|
71
|
+
}
|
|
72
|
+
return fail(...[a, b].reduce((all, result) => [...all, ...result.errors], []));
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Combines two results. Returning a SuccessResult<T> if either of them are SucessResult<T>
|
|
76
|
+
* or returns an ErrorResult with combined errors if both are an ErrorResult.
|
|
77
|
+
*/
|
|
78
|
+
export function combineTwoResultsOneOf(a, b) {
|
|
79
|
+
if (a.success === true) {
|
|
80
|
+
return a;
|
|
81
|
+
}
|
|
82
|
+
if (b.success === true) {
|
|
83
|
+
return b;
|
|
84
|
+
}
|
|
85
|
+
return fail(...[a, b].reduce((all, result) => [
|
|
86
|
+
...all,
|
|
87
|
+
...(result.success === true ? [] : result.errors),
|
|
88
|
+
], []));
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Combines a list of results. Returning a SuccessResult<T> if either of them are SucessResult<T>
|
|
92
|
+
* or returns an ErrorResult with combined errors if all are an ErrorResult.
|
|
93
|
+
*/
|
|
94
|
+
export function combineResultsOneOf(...results) {
|
|
95
|
+
const successResult = results.find((it) => it.success);
|
|
96
|
+
if (successResult.success) {
|
|
97
|
+
return pass(successResult.value);
|
|
98
|
+
}
|
|
99
|
+
return fail(...results.reduce((all, result) => [
|
|
100
|
+
...all,
|
|
101
|
+
...(result.success === true ? [] : result.errors),
|
|
102
|
+
], []));
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Converts a Guard<T> to an ErrorAwareGuard<T> with provided error factory function
|
|
106
|
+
*/
|
|
107
|
+
export function fromGuard(guard, createErrors) {
|
|
108
|
+
return (value) => {
|
|
109
|
+
if (guard(value)) {
|
|
110
|
+
return {
|
|
111
|
+
success: true,
|
|
112
|
+
value,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
success: false,
|
|
117
|
+
errors: createErrors(value),
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* First applies the predicateGuard and if it is a SuccessResult<T> passes the value to check.
|
|
123
|
+
* If check returns true it creates SuccessResult<T>.
|
|
124
|
+
* Otherwise an ErrorResult is created, containing the errors created by the error factory function.
|
|
125
|
+
*/
|
|
126
|
+
export function tryGuardIf(predicateGuard, check, createErrors) {
|
|
127
|
+
return (value) => {
|
|
128
|
+
const predicateResult = predicateGuard(value);
|
|
129
|
+
if (predicateResult.success === true) {
|
|
130
|
+
if (check(predicateResult.value)) {
|
|
131
|
+
return pass(predicateResult.value);
|
|
132
|
+
}
|
|
133
|
+
return fail(...createErrors(predicateResult.value));
|
|
134
|
+
}
|
|
135
|
+
return predicateResult;
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Confirms that the given value passes both guards.
|
|
140
|
+
*/
|
|
141
|
+
export function isBoth(a, b) {
|
|
142
|
+
return (value) => {
|
|
143
|
+
const resultA = a(value);
|
|
144
|
+
const resultB = b(value);
|
|
145
|
+
return combineTwoResultsAnd(resultA, resultB);
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Confirms that the given value passes all guards.
|
|
150
|
+
*/
|
|
151
|
+
export function isAll(guards) {
|
|
152
|
+
return (value) => {
|
|
153
|
+
return combineResultsAll(...guards.map((it) => it(value)));
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Confirms the value passes at least one of the given Guards.
|
|
158
|
+
*/
|
|
159
|
+
export function isOneOf(a, b) {
|
|
160
|
+
return (value) => {
|
|
161
|
+
const resultA = prefixErrors(a(value), "(A) ");
|
|
162
|
+
const resultB = prefixErrors(b(value), "(B) ");
|
|
163
|
+
const combinedResult = combineTwoResultsOneOf(resultA, resultB);
|
|
164
|
+
if (combinedResult.success === true) {
|
|
165
|
+
return pass(combinedResult.value);
|
|
166
|
+
}
|
|
167
|
+
return fail("Neither A nor B passed", ...combinedResult.errors);
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Confirms the value is a list of items that all pass the given guard.
|
|
172
|
+
*/
|
|
173
|
+
export function isListOf(guard) {
|
|
174
|
+
return (value) => {
|
|
175
|
+
if (!Array.isArray(value)) {
|
|
176
|
+
return fail("Not a list");
|
|
177
|
+
}
|
|
178
|
+
if (value.length === 0) {
|
|
179
|
+
return pass([]);
|
|
180
|
+
}
|
|
181
|
+
const results = value.map((value, index) => prefixErrors(guard(value), `[${index}] `));
|
|
182
|
+
if (results.every((it) => it.success)) {
|
|
183
|
+
return pass(value);
|
|
184
|
+
}
|
|
185
|
+
return combineResultsAll(fail("Not all items passed the Guard"), ...results.filter((it) => !it.success));
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Confirms that the value is a number.
|
|
190
|
+
*/
|
|
191
|
+
export const isNumber = fromGuard(Guard.isNumber, () => ["Not a number"]);
|
|
192
|
+
/**
|
|
193
|
+
* Confirms that the value is a string.
|
|
194
|
+
*/
|
|
195
|
+
export const isString = (value) => fromGuard((Guard.isString), () => ["Not a string"])(value);
|
|
196
|
+
/**
|
|
197
|
+
* Confirms that the value is an exact string.
|
|
198
|
+
*/
|
|
199
|
+
export const isExactString = (expectedString) => tryGuardIf((isString), Guard.isExactString(expectedString), () => [
|
|
200
|
+
`Not the exact string "${expectedString}"`,
|
|
201
|
+
]);
|
|
202
|
+
/**
|
|
203
|
+
* Confirms that the value is a boolean.
|
|
204
|
+
*/
|
|
205
|
+
export const isBool = fromGuard(Guard.isBool, () => ["Not a boolean"]);
|
|
206
|
+
/**
|
|
207
|
+
* Confirms that the value is a float.
|
|
208
|
+
*/
|
|
209
|
+
export const isFloat = fromGuard(Guard.isFloat, () => [
|
|
210
|
+
"Not a floating point number",
|
|
211
|
+
]);
|
|
212
|
+
/**
|
|
213
|
+
* Confirms that the value is an interger.
|
|
214
|
+
*/
|
|
215
|
+
export const isInt = fromGuard(Guard.isInt, () => ["Not an integer"]);
|
|
216
|
+
/**
|
|
217
|
+
* Confirms that the value is null.
|
|
218
|
+
*/
|
|
219
|
+
export const isNull = fromGuard(Guard.isNull, () => ["Not null"]);
|
|
220
|
+
/**
|
|
221
|
+
* Confirms that the value is undefined.
|
|
222
|
+
*/
|
|
223
|
+
export const isUndefined = fromGuard(Guard.isUndefined, () => [
|
|
224
|
+
"Not undefined",
|
|
225
|
+
]);
|
|
226
|
+
/**
|
|
227
|
+
* Confirms that the value is an object.
|
|
228
|
+
*/
|
|
229
|
+
export const isObject = fromGuard(Guard.isObject, () => ["Not an object"]);
|
|
230
|
+
/**
|
|
231
|
+
* Always passes.
|
|
232
|
+
*/
|
|
233
|
+
export const isAlways = fromGuard(Guard.isAlways, () => []);
|
|
234
|
+
/**
|
|
235
|
+
* Never passes.
|
|
236
|
+
*/
|
|
237
|
+
export const isNever = fromGuard(Guard.isNever, () => ["Never passes"]);
|
|
238
|
+
/**
|
|
239
|
+
* Confirms that the value is a non-empty string.
|
|
240
|
+
*/
|
|
241
|
+
export const isNonEmptyString = tryGuardIf(isString, (value) => value.length > 0, () => ["Is empty"]);
|
|
242
|
+
/**
|
|
243
|
+
* Confirms that the value is a string with specified length.
|
|
244
|
+
*/
|
|
245
|
+
export const isStringOfLength = (length) => tryGuardIf(isString, (value) => value.length === length, (value) => [
|
|
246
|
+
`String length was ${value.length} instead of expected ${length}`,
|
|
247
|
+
]);
|
|
248
|
+
/**
|
|
249
|
+
* Confirms the value is a string and matches the given regular expression.
|
|
250
|
+
*/
|
|
251
|
+
export const isStringWithPattern = (pattern) => tryGuardIf(isString, (value) => pattern.test(value), (value) => [`String ${value} did not match pattern ${pattern.source}`]);
|
|
252
|
+
/**
|
|
253
|
+
* Confirms the value is a list with atleast one item and all items match the given guard.
|
|
254
|
+
*/
|
|
255
|
+
export const isNonEmptyListOf = (guard) => tryGuardIf(isListOf(guard), (value) => value.length > 0, () => ["Not enough items"]);
|
|
256
|
+
/**
|
|
257
|
+
* Confirms the value is number between min and max inclusive.
|
|
258
|
+
* Meaning if the value equals min or max the guard passes.
|
|
259
|
+
*/
|
|
260
|
+
export const isNumberBetweenInclusive = (min, max) => tryGuardIf(isNumber, (value) => value >= min && value <= max, (value) => [`${value} is not between ${min} and ${max} (inclusively)`]);
|
|
261
|
+
/**
|
|
262
|
+
* Confirms the value is either null or passes the given Guard.
|
|
263
|
+
*/
|
|
264
|
+
export const isNullOr = (guard) => isOneOf(isNull, guard);
|
|
265
|
+
export const isOneStringOf = (validValues) => tryGuardIf((isString), (value) => validValues.includes(value), (value) => [`String ${value} is not one of ${validValues.join("|")}`]);
|
|
266
|
+
/**
|
|
267
|
+
* Confirms that the value is an object containing the specified key.
|
|
268
|
+
*/
|
|
269
|
+
export function isObjectWithKey(key) {
|
|
270
|
+
return tryGuardIf(isObject, (value) => key in value, () => [`Object does not have key ${key.toString()}`]);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Confirms that the value is an object containing the specified key the value matching the given guard.
|
|
274
|
+
*/
|
|
275
|
+
export function isObjectWithKeyMatchingGuard(key, guard) {
|
|
276
|
+
return (value) => {
|
|
277
|
+
const isObjectWithKeyResult = isObjectWithKey(key)(value);
|
|
278
|
+
if (isObjectWithKeyResult.success === false) {
|
|
279
|
+
return isObjectWithKeyResult;
|
|
280
|
+
}
|
|
281
|
+
const keyValueResult = guard(value[key]);
|
|
282
|
+
if (keyValueResult.success === true) {
|
|
283
|
+
return pass(isObjectWithKeyResult.value);
|
|
284
|
+
}
|
|
285
|
+
return prefixErrors(keyValueResult, `[${key.toString()}] `);
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Confirms that the value is an object containing the specified keys.
|
|
290
|
+
*/
|
|
291
|
+
export function isObjectWithKeys(keys) {
|
|
292
|
+
return isAll(keys.map((isObjectWithKey)));
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Confirms that the value is an object whose key value pairs match the corresponding type guards.
|
|
296
|
+
*/
|
|
297
|
+
export function isObjectWithKeysMatchingGuard(guards) {
|
|
298
|
+
return isAll(
|
|
299
|
+
// @ts-expect-error not error just a bad type system
|
|
300
|
+
Object.entries(guards).map(([key, guard]) => {
|
|
301
|
+
return isObjectWithKeyMatchingGuard(key, guard);
|
|
302
|
+
}));
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Confirms the value is an object where every value matches the given guard.
|
|
306
|
+
*/
|
|
307
|
+
export function isObjectWithAllKeysMatchingGuard(guard) {
|
|
308
|
+
return (value) => isAll(
|
|
309
|
+
// @ts-expect-error not error just a bad type system
|
|
310
|
+
Object.keys(value).map((key) => {
|
|
311
|
+
return isObjectWithKeyMatchingGuard(key, guard);
|
|
312
|
+
}))(value);
|
|
313
|
+
}
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
* Provides types and functions to represent fetch request states
|
|
3
3
|
* @module fetch-state
|
|
4
4
|
*/
|
|
5
|
-
import
|
|
5
|
+
import * as Guard from "@kaumlaut/pure/guard";
|
|
6
|
+
import * as ErrorAwareGuard from "@kaumlaut/pure/error-aware-guard";
|
|
6
7
|
/**
|
|
7
8
|
* Represents a failed fetch request
|
|
8
9
|
*/
|
|
9
10
|
export type Failed = {
|
|
10
|
-
|
|
11
|
+
errors: Readonly<string[]>;
|
|
11
12
|
type: "Failed";
|
|
12
13
|
};
|
|
13
14
|
/**
|
|
@@ -52,7 +53,7 @@ export declare function isSuccess<T>(state: FetchState<T>): state is Success<T>;
|
|
|
52
53
|
/**
|
|
53
54
|
* Creates a fetch state of type Failed
|
|
54
55
|
*/
|
|
55
|
-
export declare function fail(
|
|
56
|
+
export declare function fail(first: string, ...errors: string[]): Failed;
|
|
56
57
|
/**
|
|
57
58
|
* Creates a fetch state of type Loading
|
|
58
59
|
*/
|
|
@@ -72,7 +73,19 @@ if(isSuccess(value)){
|
|
|
72
73
|
console.error(value.error)
|
|
73
74
|
}
|
|
74
75
|
*/
|
|
75
|
-
export declare function attempt<T>(guard: Guard<T>,
|
|
76
|
+
export declare function attempt<T>(guard: Guard.Guard<T>, firstError?: string, ...errors: string[]): (data: unknown) => Success<T> | Failed;
|
|
77
|
+
/**
|
|
78
|
+
* Attempts to create a fetch state of type Success if the given guard passes.
|
|
79
|
+
* Otherwise creates a fetch state of type Failed with the errors from the ErrorAwareGuard.
|
|
80
|
+
* @example
|
|
81
|
+
const value = attemptErrorAware(isString)(3);
|
|
82
|
+
if(isSuccess(value)){
|
|
83
|
+
console.log(value.data)
|
|
84
|
+
} else if (isFailed(value)){
|
|
85
|
+
console.error(value.error)
|
|
86
|
+
}
|
|
87
|
+
*/
|
|
88
|
+
export declare function attemptErrorAware<T>(guard: ErrorAwareGuard.ErrorAwareGuard<T>): (data: unknown) => Success<T> | Failed;
|
|
76
89
|
/**
|
|
77
90
|
* A Utility function that allows to map the Failed fetch state to any other fetch state.
|
|
78
91
|
* The mapper function is only called if the given fetch state is Failed.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fetch-state/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fetch-state/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,KAAK,MAAM,sBAAsB,CAAC;AAC9C,OAAO,KAAK,eAAe,MAAM,kCAAkC,CAAC;AAEpE;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG;IACnB,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3B,IAAI,EAAE,QAAQ,CAAC;CAChB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,IAAI,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,SAAS,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI;IACvB,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAClB,IAAI,EAAE,SAAS,CAAC;CACjB,CAAC;AACF;;GAEG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,MAAM,GAAG,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AACjE;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,OAAO,CAEnE;AACD;;GAEG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,MAAM,CAEjE;AACD;;GAEG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,IAAI,CAE7D;AACD;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,CAEtE;AACD;;GAEG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAK/D;AACD;;GAEG;AACH,wBAAgB,IAAI,IAAI,OAAO,CAI9B;AACD;;GAEG;AACH,wBAAgB,IAAI,IAAI,IAAI,CAI3B;AACD;;;;;;;;;;GAUG;AACH,wBAAgB,OAAO,CAAC,CAAC,EACvB,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EACrB,UAAU,GAAE,MAA6E,EACzF,GAAG,MAAM,EAAE,MAAM,EAAE,GAClB,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAcxC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,KAAK,EAAE,eAAe,CAAC,eAAe,CAAC,CAAC,CAAC,GACxC,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAexC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,CAAC,EACzB,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,GACvC,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAQzC"}
|
|
@@ -25,10 +25,10 @@ export function isSuccess(state) {
|
|
|
25
25
|
/**
|
|
26
26
|
* Creates a fetch state of type Failed
|
|
27
27
|
*/
|
|
28
|
-
export function fail(
|
|
28
|
+
export function fail(first, ...errors) {
|
|
29
29
|
return {
|
|
30
30
|
type: "Failed",
|
|
31
|
-
|
|
31
|
+
errors: [first, ...errors],
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
@@ -58,7 +58,7 @@ if(isSuccess(value)){
|
|
|
58
58
|
console.error(value.error)
|
|
59
59
|
}
|
|
60
60
|
*/
|
|
61
|
-
export function attempt(guard,
|
|
61
|
+
export function attempt(guard, firstError = "Guard did not pass. Ensure the attempted data has the correct type", ...errors) {
|
|
62
62
|
return (data) => {
|
|
63
63
|
if (guard(data)) {
|
|
64
64
|
return {
|
|
@@ -68,7 +68,33 @@ export function attempt(guard, error = "Guard did not pass. Ensure the attempted
|
|
|
68
68
|
}
|
|
69
69
|
return {
|
|
70
70
|
type: "Failed",
|
|
71
|
-
|
|
71
|
+
errors: [firstError, ...errors],
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Attempts to create a fetch state of type Success if the given guard passes.
|
|
77
|
+
* Otherwise creates a fetch state of type Failed with the errors from the ErrorAwareGuard.
|
|
78
|
+
* @example
|
|
79
|
+
const value = attemptErrorAware(isString)(3);
|
|
80
|
+
if(isSuccess(value)){
|
|
81
|
+
console.log(value.data)
|
|
82
|
+
} else if (isFailed(value)){
|
|
83
|
+
console.error(value.error)
|
|
84
|
+
}
|
|
85
|
+
*/
|
|
86
|
+
export function attemptErrorAware(guard) {
|
|
87
|
+
return (data) => {
|
|
88
|
+
const result = guard(data);
|
|
89
|
+
if (result.success === true) {
|
|
90
|
+
return {
|
|
91
|
+
type: "Success",
|
|
92
|
+
data: result.value,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
type: "Failed",
|
|
97
|
+
errors: result.errors,
|
|
72
98
|
};
|
|
73
99
|
};
|
|
74
100
|
}
|
package/dist/guard/index.d.ts
CHANGED
|
@@ -6,14 +6,26 @@ export type Guard<T> = (value: unknown) => value is T;
|
|
|
6
6
|
* Confirms that the given value passes all guards.
|
|
7
7
|
*/
|
|
8
8
|
export declare function isAll<T>(guards: Guard<T>[]): (value: unknown) => value is T;
|
|
9
|
+
/**
|
|
10
|
+
* Confirms that the given value passes both guards.
|
|
11
|
+
*/
|
|
12
|
+
export declare function isBoth<T>(a: Guard<T>, b: Guard<T>): (value: unknown) => value is T;
|
|
9
13
|
/**
|
|
10
14
|
* Confirms that the value is a string.
|
|
11
15
|
*/
|
|
12
|
-
export declare function isString(value: unknown): value is
|
|
16
|
+
export declare function isString<T extends string>(value: unknown): value is T;
|
|
17
|
+
/**
|
|
18
|
+
* Confirms that the value is a non-empty string.
|
|
19
|
+
*/
|
|
20
|
+
export declare function isNonEmptyString(value: unknown): value is string;
|
|
13
21
|
/**
|
|
14
22
|
* Confirms that the value is a string with specified length.
|
|
15
23
|
*/
|
|
16
24
|
export declare function isStringOfLength(length: number): (value: unknown) => value is string;
|
|
25
|
+
/**
|
|
26
|
+
* Confirms that the value is an object.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isObject(value: unknown): value is object;
|
|
17
29
|
/**
|
|
18
30
|
* Confirms that the value is a number.
|
|
19
31
|
*/
|