@devp0nt/error0 1.0.0-next.40 → 1.0.0-next.41
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/dist/cjs/index.cjs +61 -98
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +55 -59
- package/dist/esm/index.d.ts +55 -59
- package/dist/esm/index.js +61 -98
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.test.ts +66 -86
- package/src/index.ts +140 -213
package/src/index.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
export type ErrorExtensionPropOptions<TInputValue, TOutputValue, TError extends Error0 = Error0> = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
init: (input: TInputValue) => TOutputValue
|
|
3
|
+
resolve: (options: {
|
|
4
|
+
value: TOutputValue | undefined
|
|
5
|
+
flow: Array<TOutputValue | undefined>
|
|
6
|
+
error: TError
|
|
7
|
+
}) => TOutputValue | undefined
|
|
8
|
+
serialize: (options: { value: TOutputValue; error: TError; isPublic: boolean }) => unknown
|
|
9
|
+
deserialize: (options: { value: unknown; serialized: Record<string, unknown> }) => TOutputValue | undefined
|
|
5
10
|
}
|
|
6
|
-
export type ErrorExtensionCopmputedFn<TOutputValue, TError extends Error0 = Error0> = (error: TError) => TOutputValue
|
|
7
11
|
export type ErrorExtensionMethodFn<
|
|
8
12
|
TOutputValue,
|
|
9
13
|
TArgs extends unknown[] = unknown[],
|
|
@@ -20,16 +24,13 @@ type ErrorMethodRecord = {
|
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
export type ErrorExtensionProps = { [key: string]: ErrorExtensionPropOptions<any, any> }
|
|
23
|
-
export type ErrorExtensionComputed = { [key: string]: ErrorExtensionCopmputedFn<any> }
|
|
24
27
|
export type ErrorExtensionMethods = { [key: string]: ErrorExtensionMethodFn<any, any[]> }
|
|
25
28
|
|
|
26
29
|
export type ErrorExtension<
|
|
27
30
|
TProps extends ErrorExtensionProps = Record<never, never>,
|
|
28
|
-
TComputed extends ErrorExtensionComputed = Record<never, never>,
|
|
29
31
|
TMethods extends ErrorExtensionMethods = Record<never, never>,
|
|
30
32
|
> = {
|
|
31
33
|
props?: TProps
|
|
32
|
-
computed?: TComputed
|
|
33
34
|
methods?: TMethods
|
|
34
35
|
refine?: Array<ErrorExtensionRefineFn<Error0, ExtensionOutputProps<TProps>>>
|
|
35
36
|
}
|
|
@@ -39,11 +40,6 @@ type AddPropToExtensionProps<
|
|
|
39
40
|
TInputValue,
|
|
40
41
|
TOutputValue,
|
|
41
42
|
> = TProps & Record<TKey, ErrorExtensionPropOptions<TInputValue, TOutputValue>>
|
|
42
|
-
type AddComputedToExtensionComputed<
|
|
43
|
-
TComputed extends ErrorExtensionComputed,
|
|
44
|
-
TKey extends string,
|
|
45
|
-
TOutputValue,
|
|
46
|
-
> = TComputed & Record<TKey, ErrorExtensionCopmputedFn<TOutputValue>>
|
|
47
43
|
type AddMethodToExtensionMethods<
|
|
48
44
|
TMethods extends ErrorExtensionMethods,
|
|
49
45
|
TKey extends string,
|
|
@@ -54,8 +50,7 @@ type ExtensionOutputProps<TProps extends ErrorExtensionProps> = {
|
|
|
54
50
|
[TKey in keyof TProps]: TProps[TKey] extends ErrorExtensionPropOptions<any, infer TOutputValue> ? TOutputValue : never
|
|
55
51
|
}
|
|
56
52
|
export type ErrorExtensionsMap = {
|
|
57
|
-
props: Record<string, {
|
|
58
|
-
computed: Record<string, unknown>
|
|
53
|
+
props: Record<string, { init: unknown; resolve: unknown }>
|
|
59
54
|
methods: Record<string, ErrorMethodRecord>
|
|
60
55
|
}
|
|
61
56
|
export type IsEmptyObject<T> = keyof T extends never ? true : false
|
|
@@ -67,14 +62,11 @@ export type ErrorInput<TExtensionsMap extends ErrorExtensionsMap> =
|
|
|
67
62
|
? ErrorInputBase
|
|
68
63
|
: ErrorInputBase &
|
|
69
64
|
Partial<{
|
|
70
|
-
[TKey in keyof TExtensionsMap['props']]: TExtensionsMap['props'][TKey]['
|
|
65
|
+
[TKey in keyof TExtensionsMap['props']]: TExtensionsMap['props'][TKey]['init']
|
|
71
66
|
}>
|
|
72
67
|
|
|
73
68
|
type ErrorOutputProps<TExtensionsMap extends ErrorExtensionsMap> = {
|
|
74
|
-
[TKey in keyof TExtensionsMap['props']]
|
|
75
|
-
}
|
|
76
|
-
type ErrorOutputComputed<TExtensionsMap extends ErrorExtensionsMap> = {
|
|
77
|
-
[TKey in keyof TExtensionsMap['computed']]: TExtensionsMap['computed'][TKey]
|
|
69
|
+
[TKey in keyof TExtensionsMap['props']]?: TExtensionsMap['props'][TKey]['resolve']
|
|
78
70
|
}
|
|
79
71
|
type ErrorOutputMethods<TExtensionsMap extends ErrorExtensionsMap> = {
|
|
80
72
|
[TKey in keyof TExtensionsMap['methods']]: TExtensionsMap['methods'][TKey] extends {
|
|
@@ -85,7 +77,6 @@ type ErrorOutputMethods<TExtensionsMap extends ErrorExtensionsMap> = {
|
|
|
85
77
|
: never
|
|
86
78
|
}
|
|
87
79
|
export type ErrorOutput<TExtensionsMap extends ErrorExtensionsMap> = ErrorOutputProps<TExtensionsMap> &
|
|
88
|
-
ErrorOutputComputed<TExtensionsMap> &
|
|
89
80
|
ErrorOutputMethods<TExtensionsMap>
|
|
90
81
|
|
|
91
82
|
type ErrorStaticMethods<TExtensionsMap extends ErrorExtensionsMap> = {
|
|
@@ -98,14 +89,12 @@ type ErrorStaticMethods<TExtensionsMap extends ErrorExtensionsMap> = {
|
|
|
98
89
|
}
|
|
99
90
|
|
|
100
91
|
type EmptyExtensionsMap = {
|
|
101
|
-
props: Record<never, {
|
|
102
|
-
computed: Record<never, never>
|
|
92
|
+
props: Record<never, { init: never; resolve: never }>
|
|
103
93
|
methods: Record<never, ErrorMethodRecord>
|
|
104
94
|
}
|
|
105
95
|
|
|
106
96
|
type ErrorExtensionResolved = {
|
|
107
97
|
props: Record<string, ErrorExtensionPropOptions<unknown, unknown>>
|
|
108
|
-
computed: Record<string, ErrorExtensionCopmputedFn<unknown>>
|
|
109
98
|
methods: Record<string, ErrorExtensionMethodFn<unknown>>
|
|
110
99
|
refine: Array<ErrorExtensionRefineFn<Error0, Record<string, unknown>>>
|
|
111
100
|
}
|
|
@@ -114,14 +103,7 @@ type ExtensionPropsMapOf<TExtension extends ErrorExtension> = {
|
|
|
114
103
|
[TKey in keyof NonNullable<TExtension['props']>]: NonNullable<
|
|
115
104
|
TExtension['props']
|
|
116
105
|
>[TKey] extends ErrorExtensionPropOptions<infer TInputValue, infer TOutputValue>
|
|
117
|
-
? {
|
|
118
|
-
: never
|
|
119
|
-
}
|
|
120
|
-
type ExtensionComputedMapOf<TExtension extends ErrorExtension> = {
|
|
121
|
-
[TKey in keyof NonNullable<TExtension['computed']>]: NonNullable<
|
|
122
|
-
TExtension['computed']
|
|
123
|
-
>[TKey] extends ErrorExtensionCopmputedFn<infer TOutputValue>
|
|
124
|
-
? TOutputValue
|
|
106
|
+
? { init: TInputValue; resolve: TOutputValue }
|
|
125
107
|
: never
|
|
126
108
|
}
|
|
127
109
|
type ExtensionMethodsMapOf<TExtension extends ErrorExtension> = {
|
|
@@ -134,12 +116,10 @@ type ExtensionMethodsMapOf<TExtension extends ErrorExtension> = {
|
|
|
134
116
|
}
|
|
135
117
|
type ErrorExtensionsMapOfExtension<TExtension extends ErrorExtension> = {
|
|
136
118
|
props: ExtensionPropsMapOf<TExtension>
|
|
137
|
-
computed: ExtensionComputedMapOf<TExtension>
|
|
138
119
|
methods: ExtensionMethodsMapOf<TExtension>
|
|
139
120
|
}
|
|
140
121
|
type ExtendErrorExtensionsMap<TMap extends ErrorExtensionsMap, TExtension extends ErrorExtension> = {
|
|
141
122
|
props: TMap['props'] & ErrorExtensionsMapOfExtension<TExtension>['props']
|
|
142
|
-
computed: TMap['computed'] & ErrorExtensionsMapOfExtension<TExtension>['computed']
|
|
143
123
|
methods: TMap['methods'] & ErrorExtensionsMapOfExtension<TExtension>['methods']
|
|
144
124
|
}
|
|
145
125
|
type ExtendErrorExtensionsMapWithProp<
|
|
@@ -148,14 +128,6 @@ type ExtendErrorExtensionsMapWithProp<
|
|
|
148
128
|
TInputValue,
|
|
149
129
|
TOutputValue,
|
|
150
130
|
> = ExtendErrorExtensionsMap<TMap, ErrorExtension<Record<TKey, ErrorExtensionPropOptions<TInputValue, TOutputValue>>>>
|
|
151
|
-
type ExtendErrorExtensionsMapWithComputed<
|
|
152
|
-
TMap extends ErrorExtensionsMap,
|
|
153
|
-
TKey extends string,
|
|
154
|
-
TOutputValue,
|
|
155
|
-
> = ExtendErrorExtensionsMap<
|
|
156
|
-
TMap,
|
|
157
|
-
ErrorExtension<Record<never, never>, Record<TKey, ErrorExtensionCopmputedFn<TOutputValue>>>
|
|
158
|
-
>
|
|
159
131
|
type ExtendErrorExtensionsMapWithMethod<
|
|
160
132
|
TMap extends ErrorExtensionsMap,
|
|
161
133
|
TKey extends string,
|
|
@@ -163,7 +135,7 @@ type ExtendErrorExtensionsMapWithMethod<
|
|
|
163
135
|
TOutputValue,
|
|
164
136
|
> = ExtendErrorExtensionsMap<
|
|
165
137
|
TMap,
|
|
166
|
-
ErrorExtension<Record<never, never>, Record<
|
|
138
|
+
ErrorExtension<Record<never, never>, Record<TKey, ErrorExtensionMethodFn<TOutputValue, TArgs>>>
|
|
167
139
|
>
|
|
168
140
|
|
|
169
141
|
type ExtensionsMapOf<TClass> = TClass extends { __extensionsMap?: infer TExtensionsMap }
|
|
@@ -174,40 +146,29 @@ type ExtensionsMapOf<TClass> = TClass extends { __extensionsMap?: infer TExtensi
|
|
|
174
146
|
|
|
175
147
|
type ExtensionsMapFromParts<
|
|
176
148
|
TProps extends ErrorExtensionProps,
|
|
177
|
-
TComputed extends ErrorExtensionComputed,
|
|
178
149
|
TMethods extends ErrorExtensionMethods,
|
|
179
|
-
> = ErrorExtensionsMapOfExtension<ErrorExtension<TProps,
|
|
150
|
+
> = ErrorExtensionsMapOfExtension<ErrorExtension<TProps, TMethods>>
|
|
180
151
|
type ErrorInstanceOfMap<TMap extends ErrorExtensionsMap> = Error0 & ErrorOutput<TMap>
|
|
181
|
-
type BuilderError0<
|
|
182
|
-
TProps
|
|
183
|
-
TComputed extends ErrorExtensionComputed,
|
|
184
|
-
TMethods extends ErrorExtensionMethods,
|
|
185
|
-
> = Error0 & ErrorOutput<ExtensionsMapFromParts<TProps, TComputed, TMethods>>
|
|
152
|
+
type BuilderError0<TProps extends ErrorExtensionProps, TMethods extends ErrorExtensionMethods> = Error0 &
|
|
153
|
+
ErrorOutput<ExtensionsMapFromParts<TProps, TMethods>>
|
|
186
154
|
|
|
187
155
|
type ExtensionOfBuilder<TBuilder> =
|
|
188
|
-
TBuilder extends ExtensionError0<infer TProps, infer
|
|
189
|
-
? ErrorExtension<TProps, TComputed, TMethods>
|
|
190
|
-
: never
|
|
191
|
-
|
|
192
|
-
export type ErrorFlowPolicy = 'instance' | 'error0' | 'likeError0' | 'all'
|
|
156
|
+
TBuilder extends ExtensionError0<infer TProps, infer TMethods> ? ErrorExtension<TProps, TMethods> : never
|
|
193
157
|
|
|
194
158
|
export class ExtensionError0<
|
|
195
159
|
TProps extends ErrorExtensionProps = Record<never, never>,
|
|
196
|
-
TComputed extends ErrorExtensionComputed = Record<never, never>,
|
|
197
160
|
TMethods extends ErrorExtensionMethods = Record<never, never>,
|
|
198
161
|
> {
|
|
199
|
-
private readonly _extension: ErrorExtension<ErrorExtensionProps,
|
|
162
|
+
private readonly _extension: ErrorExtension<ErrorExtensionProps, ErrorExtensionMethods>
|
|
200
163
|
|
|
201
164
|
readonly Infer = undefined as unknown as {
|
|
202
165
|
props: TProps
|
|
203
|
-
computed: TComputed
|
|
204
166
|
methods: TMethods
|
|
205
167
|
}
|
|
206
168
|
|
|
207
|
-
constructor(extension?: ErrorExtension<ErrorExtensionProps,
|
|
169
|
+
constructor(extension?: ErrorExtension<ErrorExtensionProps, ErrorExtensionMethods>) {
|
|
208
170
|
this._extension = {
|
|
209
171
|
props: { ...(extension?.props ?? {}) },
|
|
210
|
-
computed: { ...(extension?.computed ?? {}) },
|
|
211
172
|
methods: { ...(extension?.methods ?? {}) },
|
|
212
173
|
refine: [...(extension?.refine ?? [])],
|
|
213
174
|
}
|
|
@@ -215,60 +176,44 @@ export class ExtensionError0<
|
|
|
215
176
|
|
|
216
177
|
prop<TKey extends string, TInputValue, TOutputValue>(
|
|
217
178
|
key: TKey,
|
|
218
|
-
value: ErrorExtensionPropOptions<TInputValue, TOutputValue, BuilderError0<TProps,
|
|
219
|
-
): ExtensionError0<AddPropToExtensionProps<TProps, TKey, TInputValue, TOutputValue>,
|
|
179
|
+
value: ErrorExtensionPropOptions<TInputValue, TOutputValue, BuilderError0<TProps, TMethods>>,
|
|
180
|
+
): ExtensionError0<AddPropToExtensionProps<TProps, TKey, TInputValue, TOutputValue>, TMethods> {
|
|
220
181
|
return this.extend('prop', key, value)
|
|
221
182
|
}
|
|
222
183
|
|
|
223
|
-
computed<TKey extends string, TOutputValue>(
|
|
224
|
-
key: TKey,
|
|
225
|
-
value: ErrorExtensionCopmputedFn<TOutputValue, BuilderError0<TProps, TComputed, TMethods>>,
|
|
226
|
-
): ExtensionError0<TProps, AddComputedToExtensionComputed<TComputed, TKey, TOutputValue>, TMethods> {
|
|
227
|
-
return this.extend('computed', key, value)
|
|
228
|
-
}
|
|
229
|
-
|
|
230
184
|
method<TKey extends string, TArgs extends unknown[], TOutputValue>(
|
|
231
185
|
key: TKey,
|
|
232
|
-
value: ErrorExtensionMethodFn<TOutputValue, TArgs, BuilderError0<TProps,
|
|
233
|
-
): ExtensionError0<TProps,
|
|
186
|
+
value: ErrorExtensionMethodFn<TOutputValue, TArgs, BuilderError0<TProps, TMethods>>,
|
|
187
|
+
): ExtensionError0<TProps, AddMethodToExtensionMethods<TMethods, TKey, TArgs, TOutputValue>> {
|
|
234
188
|
return this.extend('method', key, value)
|
|
235
189
|
}
|
|
236
190
|
|
|
237
191
|
refine(
|
|
238
|
-
value: ErrorExtensionRefineFn<BuilderError0<TProps,
|
|
239
|
-
): ExtensionError0<TProps,
|
|
192
|
+
value: ErrorExtensionRefineFn<BuilderError0<TProps, TMethods>, ExtensionOutputProps<TProps>>,
|
|
193
|
+
): ExtensionError0<TProps, TMethods> {
|
|
240
194
|
return this.extend('refine', value)
|
|
241
195
|
}
|
|
242
196
|
|
|
243
197
|
extend<TKey extends string, TInputValue, TOutputValue>(
|
|
244
198
|
kind: 'prop',
|
|
245
199
|
key: TKey,
|
|
246
|
-
value: ErrorExtensionPropOptions<TInputValue, TOutputValue, BuilderError0<TProps,
|
|
247
|
-
): ExtensionError0<AddPropToExtensionProps<TProps, TKey, TInputValue, TOutputValue>,
|
|
248
|
-
extend<TKey extends string, TOutputValue>(
|
|
249
|
-
kind: 'computed',
|
|
250
|
-
key: TKey,
|
|
251
|
-
value: ErrorExtensionCopmputedFn<TOutputValue, BuilderError0<TProps, TComputed, TMethods>>,
|
|
252
|
-
): ExtensionError0<TProps, AddComputedToExtensionComputed<TComputed, TKey, TOutputValue>, TMethods>
|
|
200
|
+
value: ErrorExtensionPropOptions<TInputValue, TOutputValue, BuilderError0<TProps, TMethods>>,
|
|
201
|
+
): ExtensionError0<AddPropToExtensionProps<TProps, TKey, TInputValue, TOutputValue>, TMethods>
|
|
253
202
|
extend<TKey extends string, TArgs extends unknown[], TOutputValue>(
|
|
254
203
|
kind: 'method',
|
|
255
204
|
key: TKey,
|
|
256
|
-
value: ErrorExtensionMethodFn<TOutputValue, TArgs, BuilderError0<TProps,
|
|
257
|
-
): ExtensionError0<TProps,
|
|
205
|
+
value: ErrorExtensionMethodFn<TOutputValue, TArgs, BuilderError0<TProps, TMethods>>,
|
|
206
|
+
): ExtensionError0<TProps, AddMethodToExtensionMethods<TMethods, TKey, TArgs, TOutputValue>>
|
|
258
207
|
extend(
|
|
259
208
|
kind: 'refine',
|
|
260
|
-
value: ErrorExtensionRefineFn<BuilderError0<TProps,
|
|
261
|
-
): ExtensionError0<TProps,
|
|
209
|
+
value: ErrorExtensionRefineFn<BuilderError0<TProps, TMethods>, ExtensionOutputProps<TProps>>,
|
|
210
|
+
): ExtensionError0<TProps, TMethods>
|
|
262
211
|
extend(
|
|
263
|
-
kind: 'prop' | '
|
|
212
|
+
kind: 'prop' | 'method' | 'refine',
|
|
264
213
|
keyOrValue: string | ErrorExtensionRefineFn<any, any>,
|
|
265
|
-
value?:
|
|
266
|
-
|
|
267
|
-
| ErrorExtensionCopmputedFn<unknown, any>
|
|
268
|
-
| ErrorExtensionMethodFn<unknown, unknown[], any>,
|
|
269
|
-
): ExtensionError0<any, any, any> {
|
|
214
|
+
value?: ErrorExtensionPropOptions<unknown, unknown, any> | ErrorExtensionMethodFn<unknown, unknown[], any>,
|
|
215
|
+
): ExtensionError0<any, any> {
|
|
270
216
|
const nextProps: ErrorExtensionProps = { ...(this._extension.props ?? {}) }
|
|
271
|
-
const nextComputed: ErrorExtensionComputed = { ...(this._extension.computed ?? {}) }
|
|
272
217
|
const nextMethods: ErrorExtensionMethods = { ...(this._extension.methods ?? {}) }
|
|
273
218
|
const nextRefine: Array<ErrorExtensionRefineFn<Error0, Record<string, unknown>>> = [
|
|
274
219
|
...(this._extension.refine ?? []),
|
|
@@ -279,12 +224,6 @@ export class ExtensionError0<
|
|
|
279
224
|
throw new Error('ExtensionError0.extend("prop", key, value) requires value')
|
|
280
225
|
}
|
|
281
226
|
nextProps[key] = value as ErrorExtensionPropOptions<any, any>
|
|
282
|
-
} else if (kind === 'computed') {
|
|
283
|
-
const key = keyOrValue as string
|
|
284
|
-
if (value === undefined) {
|
|
285
|
-
throw new Error('ExtensionError0.extend("computed", key, value) requires value')
|
|
286
|
-
}
|
|
287
|
-
nextComputed[key] = value as ErrorExtensionCopmputedFn<any>
|
|
288
227
|
} else if (kind === 'method') {
|
|
289
228
|
const key = keyOrValue as string
|
|
290
229
|
if (value === undefined) {
|
|
@@ -296,7 +235,6 @@ export class ExtensionError0<
|
|
|
296
235
|
}
|
|
297
236
|
return new ExtensionError0({
|
|
298
237
|
props: nextProps,
|
|
299
|
-
computed: nextComputed,
|
|
300
238
|
methods: nextMethods,
|
|
301
239
|
refine: nextRefine,
|
|
302
240
|
})
|
|
@@ -308,7 +246,18 @@ export type ClassError0<TExtensionsMap extends ErrorExtensionsMap = EmptyExtensi
|
|
|
308
246
|
new (input: { message: string } & ErrorInput<TExtensionsMap>): Error0 & ErrorOutput<TExtensionsMap>
|
|
309
247
|
readonly __extensionsMap?: TExtensionsMap
|
|
310
248
|
from: (error: unknown) => Error0 & ErrorOutput<TExtensionsMap>
|
|
311
|
-
serialize: (error: unknown, isPublic?: boolean) =>
|
|
249
|
+
serialize: (error: unknown, isPublic?: boolean) => Record<string, unknown>
|
|
250
|
+
prop: <TKey extends string, TInputValue, TOutputValue>(
|
|
251
|
+
key: TKey,
|
|
252
|
+
value: ErrorExtensionPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<TExtensionsMap>>,
|
|
253
|
+
) => ClassError0<ExtendErrorExtensionsMapWithProp<TExtensionsMap, TKey, TInputValue, TOutputValue>>
|
|
254
|
+
method: <TKey extends string, TArgs extends unknown[], TOutputValue>(
|
|
255
|
+
key: TKey,
|
|
256
|
+
value: ErrorExtensionMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<TExtensionsMap>>,
|
|
257
|
+
) => ClassError0<ExtendErrorExtensionsMapWithMethod<TExtensionsMap, TKey, TArgs, TOutputValue>>
|
|
258
|
+
refine: (
|
|
259
|
+
value: ErrorExtensionRefineFn<ErrorInstanceOfMap<TExtensionsMap>, ErrorOutputProps<TExtensionsMap>>,
|
|
260
|
+
) => ClassError0<TExtensionsMap>
|
|
312
261
|
extend: {
|
|
313
262
|
<TBuilder extends ExtensionError0>(
|
|
314
263
|
extension: TBuilder,
|
|
@@ -318,11 +267,6 @@ export type ClassError0<TExtensionsMap extends ErrorExtensionsMap = EmptyExtensi
|
|
|
318
267
|
key: TKey,
|
|
319
268
|
value: ErrorExtensionPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<TExtensionsMap>>,
|
|
320
269
|
): ClassError0<ExtendErrorExtensionsMapWithProp<TExtensionsMap, TKey, TInputValue, TOutputValue>>
|
|
321
|
-
<TKey extends string, TOutputValue>(
|
|
322
|
-
kind: 'computed',
|
|
323
|
-
key: TKey,
|
|
324
|
-
value: ErrorExtensionCopmputedFn<TOutputValue, ErrorInstanceOfMap<TExtensionsMap>>,
|
|
325
|
-
): ClassError0<ExtendErrorExtensionsMapWithComputed<TExtensionsMap, TKey, TOutputValue>>
|
|
326
270
|
<TKey extends string, TArgs extends unknown[], TOutputValue>(
|
|
327
271
|
kind: 'method',
|
|
328
272
|
key: TKey,
|
|
@@ -342,7 +286,6 @@ export class Error0 extends Error {
|
|
|
342
286
|
|
|
343
287
|
private static readonly _emptyExtension: ErrorExtensionResolved = {
|
|
344
288
|
props: {},
|
|
345
|
-
computed: {},
|
|
346
289
|
methods: {},
|
|
347
290
|
refine: [],
|
|
348
291
|
}
|
|
@@ -350,13 +293,11 @@ export class Error0 extends Error {
|
|
|
350
293
|
private static _getResolvedExtension(this: typeof Error0): ErrorExtensionResolved {
|
|
351
294
|
const resolved: ErrorExtensionResolved = {
|
|
352
295
|
props: {},
|
|
353
|
-
computed: {},
|
|
354
296
|
methods: {},
|
|
355
297
|
refine: [],
|
|
356
298
|
}
|
|
357
299
|
for (const extension of this._extensions) {
|
|
358
300
|
Object.assign(resolved.props, extension.props ?? this._emptyExtension.props)
|
|
359
|
-
Object.assign(resolved.computed, extension.computed ?? this._emptyExtension.computed)
|
|
360
301
|
Object.assign(resolved.methods, extension.methods ?? this._emptyExtension.methods)
|
|
361
302
|
resolved.refine.push(...(extension.refine ?? this._emptyExtension.refine))
|
|
362
303
|
}
|
|
@@ -382,10 +323,10 @@ export class Error0 extends Error {
|
|
|
382
323
|
for (const [key, prop] of Object.entries(extension.props)) {
|
|
383
324
|
if (key in input) {
|
|
384
325
|
const ownValue = (input as Record<string, unknown>)[key]
|
|
385
|
-
;(this as Record<string, unknown>)[key] = prop.
|
|
326
|
+
;(this as Record<string, unknown>)[key] = prop.init(ownValue)
|
|
386
327
|
} else {
|
|
387
328
|
Object.defineProperty(this, key, {
|
|
388
|
-
get: () => prop.
|
|
329
|
+
get: () => prop.resolve({ value: undefined, flow: this.flow(key), error: this }),
|
|
389
330
|
set: (value) => {
|
|
390
331
|
Object.defineProperty(this, key, {
|
|
391
332
|
value,
|
|
@@ -399,22 +340,6 @@ export class Error0 extends Error {
|
|
|
399
340
|
})
|
|
400
341
|
}
|
|
401
342
|
}
|
|
402
|
-
|
|
403
|
-
for (const [key, computed] of Object.entries(extension.computed)) {
|
|
404
|
-
Object.defineProperty(this, key, {
|
|
405
|
-
get: () => computed(this),
|
|
406
|
-
set: (value) => {
|
|
407
|
-
Object.defineProperty(this, key, {
|
|
408
|
-
value,
|
|
409
|
-
writable: true,
|
|
410
|
-
enumerable: true,
|
|
411
|
-
configurable: true,
|
|
412
|
-
})
|
|
413
|
-
},
|
|
414
|
-
enumerable: true,
|
|
415
|
-
configurable: true,
|
|
416
|
-
})
|
|
417
|
-
}
|
|
418
343
|
}
|
|
419
344
|
|
|
420
345
|
private static readonly isSelfProperty = (object: object, key: string): boolean => {
|
|
@@ -441,79 +366,62 @@ export class Error0 extends Error {
|
|
|
441
366
|
return ctor.own(this, key)
|
|
442
367
|
}
|
|
443
368
|
|
|
444
|
-
static flow(error: object, key: string
|
|
445
|
-
return this.causes(error,
|
|
446
|
-
|
|
447
|
-
if (this.isSelfProperty(causeRecord, key)) {
|
|
448
|
-
return causeRecord[key]
|
|
449
|
-
}
|
|
450
|
-
return undefined
|
|
369
|
+
static flow(error: object, key: string): unknown[] {
|
|
370
|
+
return this.causes(error, true).map((cause) => {
|
|
371
|
+
return this.own(cause, key)
|
|
451
372
|
})
|
|
452
373
|
}
|
|
453
|
-
flow(key: string
|
|
374
|
+
flow(key: string): unknown[] {
|
|
454
375
|
const ctor = this.constructor as typeof Error0
|
|
455
|
-
return ctor.flow(this, key
|
|
376
|
+
return ctor.flow(this, key)
|
|
456
377
|
}
|
|
457
378
|
|
|
458
|
-
static causes(error:
|
|
459
|
-
|
|
379
|
+
static causes(error: unknown, instancesOnly?: false): unknown[]
|
|
380
|
+
static causes<T extends typeof Error0>(this: T, error: unknown, instancesOnly: true): Array<InstanceType<T>>
|
|
381
|
+
static causes(error: unknown, instancesOnly?: boolean): unknown[] {
|
|
382
|
+
const causes: unknown[] = []
|
|
460
383
|
let current: unknown = error
|
|
461
384
|
const maxDepth = 99
|
|
462
385
|
const seen = new Set<unknown>()
|
|
463
|
-
|
|
464
386
|
for (let depth = 0; depth < maxDepth; depth += 1) {
|
|
465
|
-
if (!current || typeof current !== 'object') {
|
|
466
|
-
break
|
|
467
|
-
}
|
|
468
387
|
if (seen.has(current)) {
|
|
469
388
|
break
|
|
470
389
|
}
|
|
471
|
-
if (policy === 'instance') {
|
|
472
|
-
if (!this.is(current)) {
|
|
473
|
-
break
|
|
474
|
-
}
|
|
475
|
-
} else if (policy === 'error0') {
|
|
476
|
-
if (!this.isError0(current)) {
|
|
477
|
-
break
|
|
478
|
-
}
|
|
479
|
-
} else if (policy === 'likeError0') {
|
|
480
|
-
if (!this.isLikeError0(current)) {
|
|
481
|
-
break
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
390
|
seen.add(current)
|
|
485
|
-
|
|
391
|
+
if (!instancesOnly || this.is(current)) {
|
|
392
|
+
causes.push(current)
|
|
393
|
+
}
|
|
394
|
+
if (!current || typeof current !== 'object') {
|
|
395
|
+
break
|
|
396
|
+
}
|
|
486
397
|
current = (current as { cause?: unknown }).cause
|
|
487
398
|
}
|
|
488
|
-
|
|
489
399
|
return causes
|
|
490
400
|
}
|
|
491
|
-
causes(
|
|
401
|
+
causes<T extends typeof Error0>(this: T, instancesOnly?: false): [InstanceType<T>, ...unknown[]]
|
|
402
|
+
causes<T extends typeof Error0>(this: T, instancesOnly: true): [InstanceType<T>, ...Array<InstanceType<T>>]
|
|
403
|
+
causes(instancesOnly?: boolean): unknown[] {
|
|
492
404
|
const ctor = this.constructor as typeof Error0
|
|
493
|
-
|
|
405
|
+
if (instancesOnly) {
|
|
406
|
+
return ctor.causes(this, true)
|
|
407
|
+
}
|
|
408
|
+
return ctor.causes(this)
|
|
494
409
|
}
|
|
495
410
|
|
|
496
|
-
static is(error: unknown): error is
|
|
411
|
+
static is<T extends typeof Error0>(this: T, error: unknown): error is InstanceType<T> {
|
|
497
412
|
return error instanceof this
|
|
498
413
|
}
|
|
499
414
|
|
|
500
|
-
static
|
|
501
|
-
return error
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
static isLikeError0(error: unknown): error is Error0 | object {
|
|
505
|
-
return (
|
|
506
|
-
error instanceof Error0 ||
|
|
507
|
-
(typeof error === 'object' && error !== null && 'name' in error && error.name === 'Error0')
|
|
508
|
-
)
|
|
415
|
+
static isSerialized(error: unknown): error is Record<string, unknown> {
|
|
416
|
+
return !this.is(error) && typeof error === 'object' && error !== null && 'name' in error && error.name === 'Error0'
|
|
509
417
|
}
|
|
510
418
|
|
|
511
419
|
static from(error: unknown): Error0 {
|
|
512
420
|
if (this.is(error)) {
|
|
513
421
|
return error
|
|
514
422
|
}
|
|
515
|
-
if (this.
|
|
516
|
-
return this.
|
|
423
|
+
if (this.isSerialized(error)) {
|
|
424
|
+
return this._fromSerialized(error)
|
|
517
425
|
}
|
|
518
426
|
return this._fromNonError0(error)
|
|
519
427
|
}
|
|
@@ -529,27 +437,33 @@ export class Error0 extends Error {
|
|
|
529
437
|
return error
|
|
530
438
|
}
|
|
531
439
|
|
|
532
|
-
private static
|
|
440
|
+
private static _fromSerialized(error: unknown): Error0 {
|
|
533
441
|
const message = this._extractMessage(error)
|
|
534
442
|
if (typeof error !== 'object' || error === null) {
|
|
535
443
|
return this._applyRefine(new this(message, { cause: error }))
|
|
536
444
|
}
|
|
537
|
-
|
|
538
445
|
const errorRecord = error as Record<string, unknown>
|
|
539
446
|
const recreated = new this(message)
|
|
540
|
-
const temp = new this(message, { cause: errorRecord })
|
|
541
447
|
const extension = this._getResolvedExtension()
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
if (
|
|
448
|
+
const propsEntries = Object.entries(extension.props)
|
|
449
|
+
for (const [key, prop] of propsEntries) {
|
|
450
|
+
if (!(key in errorRecord)) {
|
|
451
|
+
continue
|
|
452
|
+
}
|
|
453
|
+
try {
|
|
454
|
+
const value = prop.deserialize({ value: errorRecord[key], serialized: errorRecord })
|
|
545
455
|
;(recreated as unknown as Record<string, unknown>)[key] = value
|
|
456
|
+
} catch {
|
|
457
|
+
// ignore
|
|
546
458
|
}
|
|
547
459
|
}
|
|
548
|
-
|
|
549
|
-
|
|
460
|
+
// we do not serialize causes
|
|
461
|
+
// ;(recreated as unknown as { cause?: unknown }).cause = errorRecord.cause
|
|
462
|
+
const isStackInProps = propsEntries.some(([key]) => key === 'stack')
|
|
463
|
+
if (typeof errorRecord.stack === 'string' && !isStackInProps) {
|
|
550
464
|
recreated.stack = errorRecord.stack
|
|
551
465
|
}
|
|
552
|
-
return
|
|
466
|
+
return recreated
|
|
553
467
|
}
|
|
554
468
|
|
|
555
469
|
private static _fromNonError0(error: unknown): Error0 {
|
|
@@ -569,7 +483,7 @@ export class Error0 extends Error {
|
|
|
569
483
|
|
|
570
484
|
private static _extendWithExtension(
|
|
571
485
|
this: typeof Error0,
|
|
572
|
-
extension: ErrorExtension<ErrorExtensionProps,
|
|
486
|
+
extension: ErrorExtension<ErrorExtensionProps, ErrorExtensionMethods>,
|
|
573
487
|
): ClassError0 {
|
|
574
488
|
const Base = this as unknown as typeof Error0
|
|
575
489
|
const Error0Extended = class Error0 extends Base {}
|
|
@@ -600,18 +514,40 @@ export class Error0 extends Error {
|
|
|
600
514
|
|
|
601
515
|
private static _extensionFromBuilder(
|
|
602
516
|
extension: ExtensionError0,
|
|
603
|
-
): ErrorExtension<ErrorExtensionProps,
|
|
517
|
+
): ErrorExtension<ErrorExtensionProps, ErrorExtensionMethods> {
|
|
604
518
|
const extensionRecord = extension as unknown as {
|
|
605
|
-
_extension: ErrorExtension<ErrorExtensionProps,
|
|
519
|
+
_extension: ErrorExtension<ErrorExtensionProps, ErrorExtensionMethods>
|
|
606
520
|
}
|
|
607
521
|
return {
|
|
608
522
|
props: { ...(extensionRecord._extension.props ?? {}) },
|
|
609
|
-
computed: { ...(extensionRecord._extension.computed ?? {}) },
|
|
610
523
|
methods: { ...(extensionRecord._extension.methods ?? {}) },
|
|
611
524
|
refine: [...(extensionRecord._extension.refine ?? [])],
|
|
612
525
|
}
|
|
613
526
|
}
|
|
614
527
|
|
|
528
|
+
static prop<TThis extends typeof Error0, TKey extends string, TInputValue, TOutputValue>(
|
|
529
|
+
this: TThis,
|
|
530
|
+
key: TKey,
|
|
531
|
+
value: ErrorExtensionPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<ExtensionsMapOf<TThis>>>,
|
|
532
|
+
): ClassError0<ExtendErrorExtensionsMapWithProp<ExtensionsMapOf<TThis>, TKey, TInputValue, TOutputValue>> {
|
|
533
|
+
return this.extend('prop', key, value)
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
static method<TThis extends typeof Error0, TKey extends string, TArgs extends unknown[], TOutputValue>(
|
|
537
|
+
this: TThis,
|
|
538
|
+
key: TKey,
|
|
539
|
+
value: ErrorExtensionMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<ExtensionsMapOf<TThis>>>,
|
|
540
|
+
): ClassError0<ExtendErrorExtensionsMapWithMethod<ExtensionsMapOf<TThis>, TKey, TArgs, TOutputValue>> {
|
|
541
|
+
return this.extend('method', key, value)
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
static refine<TThis extends typeof Error0>(
|
|
545
|
+
this: TThis,
|
|
546
|
+
value: ErrorExtensionRefineFn<ErrorInstanceOfMap<ExtensionsMapOf<TThis>>, ErrorOutputProps<ExtensionsMapOf<TThis>>>,
|
|
547
|
+
): ClassError0<ExtensionsMapOf<TThis>> {
|
|
548
|
+
return this.extend('refine', value)
|
|
549
|
+
}
|
|
550
|
+
|
|
615
551
|
static extend<TThis extends typeof Error0, TBuilder extends ExtensionError0>(
|
|
616
552
|
this: TThis,
|
|
617
553
|
extension: TBuilder,
|
|
@@ -622,12 +558,6 @@ export class Error0 extends Error {
|
|
|
622
558
|
key: TKey,
|
|
623
559
|
value: ErrorExtensionPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<ExtensionsMapOf<TThis>>>,
|
|
624
560
|
): ClassError0<ExtendErrorExtensionsMapWithProp<ExtensionsMapOf<TThis>, TKey, TInputValue, TOutputValue>>
|
|
625
|
-
static extend<TThis extends typeof Error0, TKey extends string, TOutputValue>(
|
|
626
|
-
this: TThis,
|
|
627
|
-
kind: 'computed',
|
|
628
|
-
key: TKey,
|
|
629
|
-
value: ErrorExtensionCopmputedFn<TOutputValue, ErrorInstanceOfMap<ExtensionsMapOf<TThis>>>,
|
|
630
|
-
): ClassError0<ExtendErrorExtensionsMapWithComputed<ExtensionsMapOf<TThis>, TKey, TOutputValue>>
|
|
631
561
|
static extend<TThis extends typeof Error0, TKey extends string, TArgs extends unknown[], TOutputValue>(
|
|
632
562
|
this: TThis,
|
|
633
563
|
kind: 'method',
|
|
@@ -641,12 +571,9 @@ export class Error0 extends Error {
|
|
|
641
571
|
): ClassError0<ExtensionsMapOf<TThis>>
|
|
642
572
|
static extend(
|
|
643
573
|
this: typeof Error0,
|
|
644
|
-
first: ExtensionError0 | 'prop' | '
|
|
574
|
+
first: ExtensionError0 | 'prop' | 'method' | 'refine',
|
|
645
575
|
key?: string | ErrorExtensionRefineFn<any, any>,
|
|
646
|
-
value?:
|
|
647
|
-
| ErrorExtensionPropOptions<unknown, unknown>
|
|
648
|
-
| ErrorExtensionCopmputedFn<unknown>
|
|
649
|
-
| ErrorExtensionMethodFn<unknown>,
|
|
576
|
+
value?: ErrorExtensionPropOptions<unknown, unknown> | ErrorExtensionMethodFn<unknown>,
|
|
650
577
|
): ClassError0 {
|
|
651
578
|
if (first instanceof ExtensionError0) {
|
|
652
579
|
return this._extendWithExtension(this._extensionFromBuilder(first))
|
|
@@ -668,11 +595,6 @@ export class Error0 extends Error {
|
|
|
668
595
|
props: { [key]: value as ErrorExtensionPropOptions<unknown, unknown> },
|
|
669
596
|
})
|
|
670
597
|
}
|
|
671
|
-
if (first === 'computed') {
|
|
672
|
-
return this._extendWithExtension({
|
|
673
|
-
computed: { [key]: value as ErrorExtensionCopmputedFn<unknown> },
|
|
674
|
-
})
|
|
675
|
-
}
|
|
676
598
|
return this._extendWithExtension({
|
|
677
599
|
methods: { [key]: value as ErrorExtensionMethodFn<unknown> },
|
|
678
600
|
})
|
|
@@ -682,31 +604,36 @@ export class Error0 extends Error {
|
|
|
682
604
|
return new ExtensionError0()
|
|
683
605
|
}
|
|
684
606
|
|
|
685
|
-
static serialize(error: unknown, isPublic = true):
|
|
607
|
+
static serialize(error: unknown, isPublic = true): Record<string, unknown> {
|
|
686
608
|
const error0 = this.from(error)
|
|
687
|
-
const
|
|
609
|
+
const json: Record<string, unknown> = {
|
|
688
610
|
name: error0.name,
|
|
689
611
|
message: error0.message,
|
|
690
|
-
|
|
691
|
-
|
|
612
|
+
// we do not serialize causes, it is enough that we have floated props and refine helper
|
|
613
|
+
// cause: error0.cause,
|
|
692
614
|
}
|
|
693
615
|
|
|
694
616
|
const extension = this._getResolvedExtension()
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
703
|
-
delete jsonWithUndefined[key]
|
|
704
|
-
} catch {
|
|
705
|
-
// ignore
|
|
617
|
+
const propsEntries = Object.entries(extension.props)
|
|
618
|
+
for (const [key, prop] of propsEntries) {
|
|
619
|
+
try {
|
|
620
|
+
const value = prop.resolve({ value: error0.own(key), flow: error0.flow(key), error: error0 })
|
|
621
|
+
const jsonValue = prop.serialize({ value, error: error0, isPublic })
|
|
622
|
+
if (jsonValue !== undefined) {
|
|
623
|
+
json[key] = jsonValue
|
|
706
624
|
}
|
|
625
|
+
} catch {
|
|
626
|
+
// ignore
|
|
707
627
|
}
|
|
708
628
|
}
|
|
709
|
-
|
|
629
|
+
const isStackInProps = propsEntries.some(([key]) => key === 'stack')
|
|
630
|
+
if (!isStackInProps && typeof error0.stack === 'string') {
|
|
631
|
+
json.stack = error0.stack
|
|
632
|
+
}
|
|
633
|
+
return Object.fromEntries(Object.entries(json).filter(([, value]) => value !== undefined)) as Record<
|
|
634
|
+
string,
|
|
635
|
+
unknown
|
|
636
|
+
>
|
|
710
637
|
}
|
|
711
638
|
|
|
712
639
|
serialize(isPublic = true): object {
|