@devp0nt/error0 1.0.0-next.41 → 1.0.0-next.42
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 +77 -73
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +109 -100
- package/dist/esm/index.d.ts +109 -100
- package/dist/esm/index.js +76 -72
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.test.ts +68 -36
- package/src/index.ts +258 -239
package/src/index.ts
CHANGED
|
@@ -1,55 +1,69 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
type IsUnknown<T> = unknown extends T ? ([T] extends [unknown] ? true : false) : false
|
|
2
|
+
type NormalizeUnknownToUndefined<T> = IsUnknown<T> extends true ? undefined : T
|
|
3
|
+
type IsOnlyUndefined<T> = [Exclude<T, undefined>] extends [never] ? true : false
|
|
4
|
+
type InferFirstArg<TFn> = TFn extends (...args: infer TArgs) => unknown
|
|
5
|
+
? TArgs extends [infer TFirst, ...unknown[]]
|
|
6
|
+
? TFirst
|
|
7
|
+
: undefined
|
|
8
|
+
: undefined
|
|
9
|
+
type InferPluginPropInput<TProp extends ErrorPluginPropOptions<any, any, any>> = NormalizeUnknownToUndefined<
|
|
10
|
+
InferFirstArg<TProp['init']>
|
|
11
|
+
>
|
|
12
|
+
type ErrorPluginPropInit<TInputValue, TOutputValue> = ((input: TInputValue) => TOutputValue) | (() => TOutputValue)
|
|
13
|
+
type ErrorPluginPropSerialize<TOutputValue, TError extends Error0> =
|
|
14
|
+
| ((options: { value: TOutputValue; error: TError; isPublic: boolean }) => unknown)
|
|
15
|
+
| false
|
|
16
|
+
type ErrorPluginPropDeserialize<TOutputValue> =
|
|
17
|
+
| ((options: { value: unknown; serialized: Record<string, unknown> }) => TOutputValue | undefined)
|
|
18
|
+
| false
|
|
19
|
+
|
|
20
|
+
export type ErrorPluginPropOptions<TInputValue, TOutputValue, TError extends Error0 = Error0> = {
|
|
21
|
+
init: ErrorPluginPropInit<TInputValue, TOutputValue>
|
|
3
22
|
resolve: (options: {
|
|
4
23
|
value: TOutputValue | undefined
|
|
5
24
|
flow: Array<TOutputValue | undefined>
|
|
6
25
|
error: TError
|
|
7
26
|
}) => TOutputValue | undefined
|
|
8
|
-
serialize:
|
|
9
|
-
deserialize:
|
|
27
|
+
serialize: ErrorPluginPropSerialize<TOutputValue, TError>
|
|
28
|
+
deserialize: ErrorPluginPropDeserialize<TOutputValue>
|
|
10
29
|
}
|
|
11
|
-
export type
|
|
12
|
-
|
|
13
|
-
TArgs
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
export type
|
|
17
|
-
export type ErrorExtensionRefineFn<
|
|
30
|
+
export type ErrorPluginMethodFn<TOutputValue, TArgs extends unknown[] = unknown[], TError extends Error0 = Error0> = (
|
|
31
|
+
error: TError,
|
|
32
|
+
...args: TArgs
|
|
33
|
+
) => TOutputValue
|
|
34
|
+
export type ErrorPluginAdaptResult<TOutputProps extends Record<string, unknown>> = Partial<TOutputProps> | undefined
|
|
35
|
+
export type ErrorPluginAdaptFn<
|
|
18
36
|
TError extends Error0 = Error0,
|
|
19
37
|
TOutputProps extends Record<string, unknown> = Record<never, never>,
|
|
20
|
-
> = ((error: TError) => void) | ((error: TError) =>
|
|
38
|
+
> = ((error: TError) => void) | ((error: TError) => ErrorPluginAdaptResult<TOutputProps>)
|
|
21
39
|
type ErrorMethodRecord = {
|
|
22
40
|
args: unknown[]
|
|
23
41
|
output: unknown
|
|
24
42
|
}
|
|
25
43
|
|
|
26
|
-
export type
|
|
27
|
-
export type
|
|
44
|
+
export type ErrorPluginProps = { [key: string]: ErrorPluginPropOptions<any, any> }
|
|
45
|
+
export type ErrorPluginMethods = { [key: string]: ErrorPluginMethodFn<any, any[]> }
|
|
28
46
|
|
|
29
|
-
export type
|
|
30
|
-
TProps extends
|
|
31
|
-
TMethods extends
|
|
47
|
+
export type ErrorPlugin<
|
|
48
|
+
TProps extends ErrorPluginProps = Record<never, never>,
|
|
49
|
+
TMethods extends ErrorPluginMethods = Record<never, never>,
|
|
32
50
|
> = {
|
|
33
51
|
props?: TProps
|
|
34
52
|
methods?: TMethods
|
|
35
|
-
|
|
53
|
+
adapt?: Array<ErrorPluginAdaptFn<Error0, PluginOutputProps<TProps>>>
|
|
36
54
|
}
|
|
37
|
-
type
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
TOutputValue,
|
|
42
|
-
> = TProps & Record<TKey, ErrorExtensionPropOptions<TInputValue, TOutputValue>>
|
|
43
|
-
type AddMethodToExtensionMethods<
|
|
44
|
-
TMethods extends ErrorExtensionMethods,
|
|
55
|
+
type AddPropToPluginProps<TProps extends ErrorPluginProps, TKey extends string, TInputValue, TOutputValue> = TProps &
|
|
56
|
+
Record<TKey, ErrorPluginPropOptions<TInputValue, TOutputValue>>
|
|
57
|
+
type AddMethodToPluginMethods<
|
|
58
|
+
TMethods extends ErrorPluginMethods,
|
|
45
59
|
TKey extends string,
|
|
46
60
|
TArgs extends unknown[],
|
|
47
61
|
TOutputValue,
|
|
48
|
-
> = TMethods & Record<TKey,
|
|
49
|
-
type
|
|
50
|
-
[TKey in keyof TProps]: TProps[TKey] extends
|
|
62
|
+
> = TMethods & Record<TKey, ErrorPluginMethodFn<TOutputValue, TArgs>>
|
|
63
|
+
type PluginOutputProps<TProps extends ErrorPluginProps> = {
|
|
64
|
+
[TKey in keyof TProps]: TProps[TKey] extends ErrorPluginPropOptions<any, infer TOutputValue> ? TOutputValue : never
|
|
51
65
|
}
|
|
52
|
-
export type
|
|
66
|
+
export type ErrorPluginsMap = {
|
|
53
67
|
props: Record<string, { init: unknown; resolve: unknown }>
|
|
54
68
|
methods: Record<string, ErrorMethodRecord>
|
|
55
69
|
}
|
|
@@ -57,30 +71,32 @@ export type IsEmptyObject<T> = keyof T extends never ? true : false
|
|
|
57
71
|
export type ErrorInputBase = {
|
|
58
72
|
cause?: unknown
|
|
59
73
|
}
|
|
60
|
-
|
|
61
|
-
|
|
74
|
+
type ErrorInputPluginProps<TPluginsMap extends ErrorPluginsMap> = {
|
|
75
|
+
[TKey in keyof TPluginsMap['props'] as IsOnlyUndefined<TPluginsMap['props'][TKey]['init']> extends true
|
|
76
|
+
? never
|
|
77
|
+
: TKey]?: TPluginsMap['props'][TKey]['init']
|
|
78
|
+
}
|
|
79
|
+
export type ErrorInput<TPluginsMap extends ErrorPluginsMap> =
|
|
80
|
+
IsEmptyObject<TPluginsMap['props']> extends true
|
|
62
81
|
? ErrorInputBase
|
|
63
|
-
: ErrorInputBase &
|
|
64
|
-
Partial<{
|
|
65
|
-
[TKey in keyof TExtensionsMap['props']]: TExtensionsMap['props'][TKey]['init']
|
|
66
|
-
}>
|
|
82
|
+
: ErrorInputBase & ErrorInputPluginProps<TPluginsMap>
|
|
67
83
|
|
|
68
|
-
type ErrorOutputProps<
|
|
69
|
-
[TKey in keyof
|
|
84
|
+
type ErrorOutputProps<TPluginsMap extends ErrorPluginsMap> = {
|
|
85
|
+
[TKey in keyof TPluginsMap['props']]: TPluginsMap['props'][TKey]['resolve'] | undefined
|
|
70
86
|
}
|
|
71
|
-
type ErrorOutputMethods<
|
|
72
|
-
[TKey in keyof
|
|
87
|
+
type ErrorOutputMethods<TPluginsMap extends ErrorPluginsMap> = {
|
|
88
|
+
[TKey in keyof TPluginsMap['methods']]: TPluginsMap['methods'][TKey] extends {
|
|
73
89
|
args: infer TArgs extends unknown[]
|
|
74
90
|
output: infer TOutput
|
|
75
91
|
}
|
|
76
92
|
? (...args: TArgs) => TOutput
|
|
77
93
|
: never
|
|
78
94
|
}
|
|
79
|
-
export type ErrorOutput<
|
|
80
|
-
ErrorOutputMethods<
|
|
95
|
+
export type ErrorOutput<TPluginsMap extends ErrorPluginsMap> = ErrorOutputProps<TPluginsMap> &
|
|
96
|
+
ErrorOutputMethods<TPluginsMap>
|
|
81
97
|
|
|
82
|
-
type ErrorStaticMethods<
|
|
83
|
-
[TKey in keyof
|
|
98
|
+
type ErrorStaticMethods<TPluginsMap extends ErrorPluginsMap> = {
|
|
99
|
+
[TKey in keyof TPluginsMap['methods']]: TPluginsMap['methods'][TKey] extends {
|
|
84
100
|
args: infer TArgs extends unknown[]
|
|
85
101
|
output: infer TOutput
|
|
86
102
|
}
|
|
@@ -88,228 +104,227 @@ type ErrorStaticMethods<TExtensionsMap extends ErrorExtensionsMap> = {
|
|
|
88
104
|
: never
|
|
89
105
|
}
|
|
90
106
|
|
|
91
|
-
type
|
|
107
|
+
type EmptyPluginsMap = {
|
|
92
108
|
props: Record<never, { init: never; resolve: never }>
|
|
93
109
|
methods: Record<never, ErrorMethodRecord>
|
|
94
110
|
}
|
|
95
111
|
|
|
96
|
-
type
|
|
97
|
-
props: Record<string,
|
|
98
|
-
methods: Record<string,
|
|
99
|
-
|
|
112
|
+
type ErrorPluginResolved = {
|
|
113
|
+
props: Record<string, ErrorPluginPropOptions<unknown, unknown>>
|
|
114
|
+
methods: Record<string, ErrorPluginMethodFn<unknown>>
|
|
115
|
+
adapt: Array<ErrorPluginAdaptFn<Error0, Record<string, unknown>>>
|
|
100
116
|
}
|
|
101
117
|
|
|
102
|
-
type
|
|
103
|
-
[TKey in keyof NonNullable<
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
118
|
+
type PluginPropsMapOf<TPlugin extends ErrorPlugin> = {
|
|
119
|
+
[TKey in keyof NonNullable<TPlugin['props']>]: NonNullable<TPlugin['props']>[TKey] extends ErrorPluginPropOptions<
|
|
120
|
+
any,
|
|
121
|
+
infer TOutputValue
|
|
122
|
+
>
|
|
123
|
+
? { init: InferPluginPropInput<NonNullable<TPlugin['props']>[TKey]>; resolve: TOutputValue }
|
|
107
124
|
: never
|
|
108
125
|
}
|
|
109
|
-
type
|
|
110
|
-
[TKey in keyof NonNullable<
|
|
126
|
+
type PluginMethodsMapOf<TPlugin extends ErrorPlugin> = {
|
|
127
|
+
[TKey in keyof NonNullable<TPlugin['methods']>]: NonNullable<TPlugin['methods']>[TKey] extends (
|
|
111
128
|
error: Error0,
|
|
112
129
|
...args: infer TArgs extends unknown[]
|
|
113
130
|
) => infer TOutput
|
|
114
131
|
? { args: TArgs; output: TOutput }
|
|
115
132
|
: never
|
|
116
133
|
}
|
|
117
|
-
type
|
|
118
|
-
props:
|
|
119
|
-
methods:
|
|
134
|
+
type ErrorPluginsMapOfPlugin<TPlugin extends ErrorPlugin> = {
|
|
135
|
+
props: PluginPropsMapOf<TPlugin>
|
|
136
|
+
methods: PluginMethodsMapOf<TPlugin>
|
|
120
137
|
}
|
|
121
|
-
type
|
|
122
|
-
props: TMap['props'] &
|
|
123
|
-
methods: TMap['methods'] &
|
|
138
|
+
type ExtendErrorPluginsMap<TMap extends ErrorPluginsMap, TPlugin extends ErrorPlugin> = {
|
|
139
|
+
props: TMap['props'] & ErrorPluginsMapOfPlugin<TPlugin>['props']
|
|
140
|
+
methods: TMap['methods'] & ErrorPluginsMapOfPlugin<TPlugin>['methods']
|
|
124
141
|
}
|
|
125
|
-
type
|
|
126
|
-
TMap extends
|
|
142
|
+
type ExtendErrorPluginsMapWithProp<
|
|
143
|
+
TMap extends ErrorPluginsMap,
|
|
127
144
|
TKey extends string,
|
|
128
145
|
TInputValue,
|
|
129
146
|
TOutputValue,
|
|
130
|
-
> =
|
|
131
|
-
type
|
|
132
|
-
TMap extends
|
|
147
|
+
> = ExtendErrorPluginsMap<TMap, ErrorPlugin<Record<TKey, ErrorPluginPropOptions<TInputValue, TOutputValue>>>>
|
|
148
|
+
type ExtendErrorPluginsMapWithMethod<
|
|
149
|
+
TMap extends ErrorPluginsMap,
|
|
133
150
|
TKey extends string,
|
|
134
151
|
TArgs extends unknown[],
|
|
135
152
|
TOutputValue,
|
|
136
|
-
> =
|
|
153
|
+
> = ExtendErrorPluginsMap<
|
|
137
154
|
TMap,
|
|
138
|
-
|
|
155
|
+
ErrorPlugin<Record<never, never>, Record<TKey, ErrorPluginMethodFn<TOutputValue, TArgs>>>
|
|
139
156
|
>
|
|
140
157
|
|
|
141
|
-
type
|
|
142
|
-
?
|
|
143
|
-
?
|
|
144
|
-
:
|
|
145
|
-
:
|
|
146
|
-
|
|
147
|
-
type
|
|
148
|
-
TProps extends
|
|
149
|
-
TMethods extends
|
|
150
|
-
> =
|
|
151
|
-
type ErrorInstanceOfMap<TMap extends
|
|
152
|
-
type BuilderError0<TProps extends
|
|
153
|
-
ErrorOutput<
|
|
154
|
-
|
|
155
|
-
type
|
|
156
|
-
TBuilder extends
|
|
157
|
-
|
|
158
|
-
export class
|
|
159
|
-
TProps extends
|
|
160
|
-
TMethods extends
|
|
158
|
+
type PluginsMapOf<TClass> = TClass extends { __pluginsMap?: infer TPluginsMap }
|
|
159
|
+
? TPluginsMap extends ErrorPluginsMap
|
|
160
|
+
? TPluginsMap
|
|
161
|
+
: EmptyPluginsMap
|
|
162
|
+
: EmptyPluginsMap
|
|
163
|
+
|
|
164
|
+
type PluginsMapFromParts<
|
|
165
|
+
TProps extends ErrorPluginProps,
|
|
166
|
+
TMethods extends ErrorPluginMethods,
|
|
167
|
+
> = ErrorPluginsMapOfPlugin<ErrorPlugin<TProps, TMethods>>
|
|
168
|
+
type ErrorInstanceOfMap<TMap extends ErrorPluginsMap> = Error0 & ErrorOutput<TMap>
|
|
169
|
+
type BuilderError0<TProps extends ErrorPluginProps, TMethods extends ErrorPluginMethods> = Error0 &
|
|
170
|
+
ErrorOutput<PluginsMapFromParts<TProps, TMethods>>
|
|
171
|
+
|
|
172
|
+
type PluginOfBuilder<TBuilder> =
|
|
173
|
+
TBuilder extends PluginError0<infer TProps, infer TMethods> ? ErrorPlugin<TProps, TMethods> : never
|
|
174
|
+
|
|
175
|
+
export class PluginError0<
|
|
176
|
+
TProps extends ErrorPluginProps = Record<never, never>,
|
|
177
|
+
TMethods extends ErrorPluginMethods = Record<never, never>,
|
|
161
178
|
> {
|
|
162
|
-
private readonly
|
|
179
|
+
private readonly _plugin: ErrorPlugin<ErrorPluginProps, ErrorPluginMethods>
|
|
163
180
|
|
|
164
181
|
readonly Infer = undefined as unknown as {
|
|
165
182
|
props: TProps
|
|
166
183
|
methods: TMethods
|
|
167
184
|
}
|
|
168
185
|
|
|
169
|
-
constructor(
|
|
170
|
-
this.
|
|
171
|
-
props: { ...(
|
|
172
|
-
methods: { ...(
|
|
173
|
-
|
|
186
|
+
constructor(plugin?: ErrorPlugin<ErrorPluginProps, ErrorPluginMethods>) {
|
|
187
|
+
this._plugin = {
|
|
188
|
+
props: { ...(plugin?.props ?? {}) },
|
|
189
|
+
methods: { ...(plugin?.methods ?? {}) },
|
|
190
|
+
adapt: [...(plugin?.adapt ?? [])],
|
|
174
191
|
}
|
|
175
192
|
}
|
|
176
193
|
|
|
177
194
|
prop<TKey extends string, TInputValue, TOutputValue>(
|
|
178
195
|
key: TKey,
|
|
179
|
-
value:
|
|
180
|
-
):
|
|
181
|
-
return this.
|
|
196
|
+
value: ErrorPluginPropOptions<TInputValue, TOutputValue, BuilderError0<TProps, TMethods>>,
|
|
197
|
+
): PluginError0<AddPropToPluginProps<TProps, TKey, TInputValue, TOutputValue>, TMethods> {
|
|
198
|
+
return this.use('prop', key, value)
|
|
182
199
|
}
|
|
183
200
|
|
|
184
201
|
method<TKey extends string, TArgs extends unknown[], TOutputValue>(
|
|
185
202
|
key: TKey,
|
|
186
|
-
value:
|
|
187
|
-
):
|
|
188
|
-
return this.
|
|
203
|
+
value: ErrorPluginMethodFn<TOutputValue, TArgs, BuilderError0<TProps, TMethods>>,
|
|
204
|
+
): PluginError0<TProps, AddMethodToPluginMethods<TMethods, TKey, TArgs, TOutputValue>> {
|
|
205
|
+
return this.use('method', key, value)
|
|
189
206
|
}
|
|
190
207
|
|
|
191
|
-
|
|
192
|
-
value:
|
|
193
|
-
):
|
|
194
|
-
return this.
|
|
208
|
+
adapt(
|
|
209
|
+
value: ErrorPluginAdaptFn<BuilderError0<TProps, TMethods>, PluginOutputProps<TProps>>,
|
|
210
|
+
): PluginError0<TProps, TMethods> {
|
|
211
|
+
return this.use('adapt', value)
|
|
195
212
|
}
|
|
196
213
|
|
|
197
|
-
|
|
214
|
+
use<TKey extends string, TInputValue, TOutputValue>(
|
|
198
215
|
kind: 'prop',
|
|
199
216
|
key: TKey,
|
|
200
|
-
value:
|
|
201
|
-
):
|
|
202
|
-
|
|
217
|
+
value: ErrorPluginPropOptions<TInputValue, TOutputValue, BuilderError0<TProps, TMethods>>,
|
|
218
|
+
): PluginError0<AddPropToPluginProps<TProps, TKey, TInputValue, TOutputValue>, TMethods>
|
|
219
|
+
use<TKey extends string, TArgs extends unknown[], TOutputValue>(
|
|
203
220
|
kind: 'method',
|
|
204
221
|
key: TKey,
|
|
205
|
-
value:
|
|
206
|
-
):
|
|
207
|
-
|
|
208
|
-
kind: '
|
|
209
|
-
value:
|
|
210
|
-
):
|
|
211
|
-
|
|
212
|
-
kind: 'prop' | 'method' | '
|
|
213
|
-
keyOrValue: string |
|
|
214
|
-
value?:
|
|
215
|
-
):
|
|
216
|
-
const nextProps:
|
|
217
|
-
const nextMethods:
|
|
218
|
-
const
|
|
219
|
-
...(this._extension.refine ?? []),
|
|
220
|
-
]
|
|
222
|
+
value: ErrorPluginMethodFn<TOutputValue, TArgs, BuilderError0<TProps, TMethods>>,
|
|
223
|
+
): PluginError0<TProps, AddMethodToPluginMethods<TMethods, TKey, TArgs, TOutputValue>>
|
|
224
|
+
use(
|
|
225
|
+
kind: 'adapt',
|
|
226
|
+
value: ErrorPluginAdaptFn<BuilderError0<TProps, TMethods>, PluginOutputProps<TProps>>,
|
|
227
|
+
): PluginError0<TProps, TMethods>
|
|
228
|
+
use(
|
|
229
|
+
kind: 'prop' | 'method' | 'adapt',
|
|
230
|
+
keyOrValue: string | ErrorPluginAdaptFn<any, any>,
|
|
231
|
+
value?: ErrorPluginPropOptions<unknown, unknown, any> | ErrorPluginMethodFn<unknown, unknown[], any>,
|
|
232
|
+
): PluginError0<any, any> {
|
|
233
|
+
const nextProps: ErrorPluginProps = { ...(this._plugin.props ?? {}) }
|
|
234
|
+
const nextMethods: ErrorPluginMethods = { ...(this._plugin.methods ?? {}) }
|
|
235
|
+
const nextAdapt: Array<ErrorPluginAdaptFn<Error0, Record<string, unknown>>> = [...(this._plugin.adapt ?? [])]
|
|
221
236
|
if (kind === 'prop') {
|
|
222
237
|
const key = keyOrValue as string
|
|
223
238
|
if (value === undefined) {
|
|
224
|
-
throw new Error('
|
|
239
|
+
throw new Error('PluginError0.use("prop", key, value) requires value')
|
|
225
240
|
}
|
|
226
|
-
nextProps[key] = value as
|
|
241
|
+
nextProps[key] = value as ErrorPluginPropOptions<any, any>
|
|
227
242
|
} else if (kind === 'method') {
|
|
228
243
|
const key = keyOrValue as string
|
|
229
244
|
if (value === undefined) {
|
|
230
|
-
throw new Error('
|
|
245
|
+
throw new Error('PluginError0.use("method", key, value) requires value')
|
|
231
246
|
}
|
|
232
|
-
nextMethods[key] = value as
|
|
247
|
+
nextMethods[key] = value as ErrorPluginMethodFn<any, any[]>
|
|
233
248
|
} else {
|
|
234
|
-
|
|
249
|
+
nextAdapt.push(keyOrValue as ErrorPluginAdaptFn<Error0, Record<string, unknown>>)
|
|
235
250
|
}
|
|
236
|
-
return new
|
|
251
|
+
return new PluginError0({
|
|
237
252
|
props: nextProps,
|
|
238
253
|
methods: nextMethods,
|
|
239
|
-
|
|
254
|
+
adapt: nextAdapt,
|
|
240
255
|
})
|
|
241
256
|
}
|
|
242
257
|
}
|
|
243
258
|
|
|
244
|
-
export type ClassError0<
|
|
245
|
-
new (message: string, input?: ErrorInput<
|
|
246
|
-
new (input: { message: string } & ErrorInput<
|
|
247
|
-
readonly
|
|
248
|
-
from: (error: unknown) => Error0 & ErrorOutput<
|
|
259
|
+
export type ClassError0<TPluginsMap extends ErrorPluginsMap = EmptyPluginsMap> = {
|
|
260
|
+
new (message: string, input?: ErrorInput<TPluginsMap>): Error0 & ErrorOutput<TPluginsMap>
|
|
261
|
+
new (input: { message: string } & ErrorInput<TPluginsMap>): Error0 & ErrorOutput<TPluginsMap>
|
|
262
|
+
readonly __pluginsMap?: TPluginsMap
|
|
263
|
+
from: (error: unknown) => Error0 & ErrorOutput<TPluginsMap>
|
|
249
264
|
serialize: (error: unknown, isPublic?: boolean) => Record<string, unknown>
|
|
250
265
|
prop: <TKey extends string, TInputValue, TOutputValue>(
|
|
251
266
|
key: TKey,
|
|
252
|
-
value:
|
|
253
|
-
) => ClassError0<
|
|
267
|
+
value: ErrorPluginPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<TPluginsMap>>,
|
|
268
|
+
) => ClassError0<ExtendErrorPluginsMapWithProp<TPluginsMap, TKey, TInputValue, TOutputValue>>
|
|
254
269
|
method: <TKey extends string, TArgs extends unknown[], TOutputValue>(
|
|
255
270
|
key: TKey,
|
|
256
|
-
value:
|
|
257
|
-
) => ClassError0<
|
|
258
|
-
|
|
259
|
-
value:
|
|
260
|
-
) => ClassError0<
|
|
261
|
-
|
|
262
|
-
<TBuilder extends
|
|
263
|
-
|
|
264
|
-
): ClassError0<
|
|
271
|
+
value: ErrorPluginMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<TPluginsMap>>,
|
|
272
|
+
) => ClassError0<ExtendErrorPluginsMapWithMethod<TPluginsMap, TKey, TArgs, TOutputValue>>
|
|
273
|
+
adapt: (
|
|
274
|
+
value: ErrorPluginAdaptFn<ErrorInstanceOfMap<TPluginsMap>, ErrorOutputProps<TPluginsMap>>,
|
|
275
|
+
) => ClassError0<TPluginsMap>
|
|
276
|
+
use: {
|
|
277
|
+
<TBuilder extends PluginError0>(
|
|
278
|
+
plugin: TBuilder,
|
|
279
|
+
): ClassError0<ExtendErrorPluginsMap<TPluginsMap, PluginOfBuilder<TBuilder>>>
|
|
265
280
|
<TKey extends string, TInputValue, TOutputValue>(
|
|
266
281
|
kind: 'prop',
|
|
267
282
|
key: TKey,
|
|
268
|
-
value:
|
|
269
|
-
): ClassError0<
|
|
283
|
+
value: ErrorPluginPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<TPluginsMap>>,
|
|
284
|
+
): ClassError0<ExtendErrorPluginsMapWithProp<TPluginsMap, TKey, TInputValue, TOutputValue>>
|
|
270
285
|
<TKey extends string, TArgs extends unknown[], TOutputValue>(
|
|
271
286
|
kind: 'method',
|
|
272
287
|
key: TKey,
|
|
273
|
-
value:
|
|
274
|
-
): ClassError0<
|
|
288
|
+
value: ErrorPluginMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<TPluginsMap>>,
|
|
289
|
+
): ClassError0<ExtendErrorPluginsMapWithMethod<TPluginsMap, TKey, TArgs, TOutputValue>>
|
|
275
290
|
(
|
|
276
|
-
kind: '
|
|
277
|
-
value:
|
|
278
|
-
): ClassError0<
|
|
291
|
+
kind: 'adapt',
|
|
292
|
+
value: ErrorPluginAdaptFn<ErrorInstanceOfMap<TPluginsMap>, ErrorOutputProps<TPluginsMap>>,
|
|
293
|
+
): ClassError0<TPluginsMap>
|
|
279
294
|
}
|
|
280
|
-
|
|
281
|
-
} & ErrorStaticMethods<
|
|
295
|
+
plugin: () => PluginError0
|
|
296
|
+
} & ErrorStaticMethods<TPluginsMap>
|
|
282
297
|
|
|
283
298
|
export class Error0 extends Error {
|
|
284
|
-
static readonly
|
|
285
|
-
protected static
|
|
299
|
+
static readonly __pluginsMap?: EmptyPluginsMap
|
|
300
|
+
protected static _plugins: ErrorPlugin[] = []
|
|
286
301
|
|
|
287
|
-
private static readonly
|
|
302
|
+
private static readonly _emptyPlugin: ErrorPluginResolved = {
|
|
288
303
|
props: {},
|
|
289
304
|
methods: {},
|
|
290
|
-
|
|
305
|
+
adapt: [],
|
|
291
306
|
}
|
|
292
307
|
|
|
293
|
-
private static
|
|
294
|
-
const resolved:
|
|
308
|
+
private static _getResolvedPlugin(this: typeof Error0): ErrorPluginResolved {
|
|
309
|
+
const resolved: ErrorPluginResolved = {
|
|
295
310
|
props: {},
|
|
296
311
|
methods: {},
|
|
297
|
-
|
|
312
|
+
adapt: [],
|
|
298
313
|
}
|
|
299
|
-
for (const
|
|
300
|
-
Object.assign(resolved.props,
|
|
301
|
-
Object.assign(resolved.methods,
|
|
302
|
-
resolved.
|
|
314
|
+
for (const plugin of this._plugins) {
|
|
315
|
+
Object.assign(resolved.props, plugin.props ?? this._emptyPlugin.props)
|
|
316
|
+
Object.assign(resolved.methods, plugin.methods ?? this._emptyPlugin.methods)
|
|
317
|
+
resolved.adapt.push(...(plugin.adapt ?? this._emptyPlugin.adapt))
|
|
303
318
|
}
|
|
304
319
|
return resolved
|
|
305
320
|
}
|
|
306
321
|
|
|
307
|
-
constructor(message: string, input?: ErrorInput<
|
|
308
|
-
constructor(input: { message: string } & ErrorInput<
|
|
322
|
+
constructor(message: string, input?: ErrorInput<EmptyPluginsMap>)
|
|
323
|
+
constructor(input: { message: string } & ErrorInput<EmptyPluginsMap>)
|
|
309
324
|
constructor(
|
|
310
325
|
...args:
|
|
311
|
-
| [message: string, input?: ErrorInput<
|
|
312
|
-
| [{ message: string } & ErrorInput<
|
|
326
|
+
| [message: string, input?: ErrorInput<EmptyPluginsMap>]
|
|
327
|
+
| [{ message: string } & ErrorInput<EmptyPluginsMap>]
|
|
313
328
|
) {
|
|
314
329
|
const [first, second] = args
|
|
315
330
|
const input = typeof first === 'string' ? { message: first, ...(second ?? {}) } : first
|
|
@@ -318,9 +333,9 @@ export class Error0 extends Error {
|
|
|
318
333
|
this.name = 'Error0'
|
|
319
334
|
|
|
320
335
|
const ctor = this.constructor as typeof Error0
|
|
321
|
-
const
|
|
336
|
+
const plugin = ctor._getResolvedPlugin()
|
|
322
337
|
|
|
323
|
-
for (const [key, prop] of Object.entries(
|
|
338
|
+
for (const [key, prop] of Object.entries(plugin.props)) {
|
|
324
339
|
if (key in input) {
|
|
325
340
|
const ownValue = (input as Record<string, unknown>)[key]
|
|
326
341
|
;(this as Record<string, unknown>)[key] = prop.init(ownValue)
|
|
@@ -426,12 +441,12 @@ export class Error0 extends Error {
|
|
|
426
441
|
return this._fromNonError0(error)
|
|
427
442
|
}
|
|
428
443
|
|
|
429
|
-
private static
|
|
430
|
-
const
|
|
431
|
-
for (const
|
|
432
|
-
const
|
|
433
|
-
if (
|
|
434
|
-
Object.assign(error as unknown as Record<string, unknown>,
|
|
444
|
+
private static _applyAdapt(error: Error0): Error0 {
|
|
445
|
+
const plugin = this._getResolvedPlugin()
|
|
446
|
+
for (const adapt of plugin.adapt) {
|
|
447
|
+
const adapted = adapt(error as any)
|
|
448
|
+
if (adapted && typeof adapted === 'object') {
|
|
449
|
+
Object.assign(error as unknown as Record<string, unknown>, adapted)
|
|
435
450
|
}
|
|
436
451
|
}
|
|
437
452
|
return error
|
|
@@ -440,13 +455,16 @@ export class Error0 extends Error {
|
|
|
440
455
|
private static _fromSerialized(error: unknown): Error0 {
|
|
441
456
|
const message = this._extractMessage(error)
|
|
442
457
|
if (typeof error !== 'object' || error === null) {
|
|
443
|
-
return this.
|
|
458
|
+
return this._applyAdapt(new this(message, { cause: error }))
|
|
444
459
|
}
|
|
445
460
|
const errorRecord = error as Record<string, unknown>
|
|
446
461
|
const recreated = new this(message)
|
|
447
|
-
const
|
|
448
|
-
const propsEntries = Object.entries(
|
|
462
|
+
const plugin = this._getResolvedPlugin()
|
|
463
|
+
const propsEntries = Object.entries(plugin.props)
|
|
449
464
|
for (const [key, prop] of propsEntries) {
|
|
465
|
+
if (prop.deserialize === false) {
|
|
466
|
+
continue
|
|
467
|
+
}
|
|
450
468
|
if (!(key in errorRecord)) {
|
|
451
469
|
continue
|
|
452
470
|
}
|
|
@@ -468,7 +486,7 @@ export class Error0 extends Error {
|
|
|
468
486
|
|
|
469
487
|
private static _fromNonError0(error: unknown): Error0 {
|
|
470
488
|
const message = this._extractMessage(error)
|
|
471
|
-
return this.
|
|
489
|
+
return this._applyAdapt(new this(message, { cause: error }))
|
|
472
490
|
}
|
|
473
491
|
|
|
474
492
|
private static _extractMessage(error: unknown): string {
|
|
@@ -481,15 +499,15 @@ export class Error0 extends Error {
|
|
|
481
499
|
)
|
|
482
500
|
}
|
|
483
501
|
|
|
484
|
-
private static
|
|
502
|
+
private static _useWithPlugin(
|
|
485
503
|
this: typeof Error0,
|
|
486
|
-
|
|
504
|
+
plugin: ErrorPlugin<ErrorPluginProps, ErrorPluginMethods>,
|
|
487
505
|
): ClassError0 {
|
|
488
506
|
const Base = this as unknown as typeof Error0
|
|
489
507
|
const Error0Extended = class Error0 extends Base {}
|
|
490
|
-
;(Error0Extended as typeof Error0).
|
|
508
|
+
;(Error0Extended as typeof Error0)._plugins = [...Base._plugins, plugin]
|
|
491
509
|
|
|
492
|
-
const resolved = (Error0Extended as typeof Error0).
|
|
510
|
+
const resolved = (Error0Extended as typeof Error0)._getResolvedPlugin()
|
|
493
511
|
for (const [key, method] of Object.entries(resolved.methods)) {
|
|
494
512
|
Object.defineProperty((Error0Extended as typeof Error0).prototype, key, {
|
|
495
513
|
value: function (...args: unknown[]) {
|
|
@@ -512,96 +530,94 @@ export class Error0 extends Error {
|
|
|
512
530
|
return Error0Extended as unknown as ClassError0
|
|
513
531
|
}
|
|
514
532
|
|
|
515
|
-
private static
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
const extensionRecord = extension as unknown as {
|
|
519
|
-
_extension: ErrorExtension<ErrorExtensionProps, ErrorExtensionMethods>
|
|
533
|
+
private static _pluginFromBuilder(plugin: PluginError0): ErrorPlugin<ErrorPluginProps, ErrorPluginMethods> {
|
|
534
|
+
const pluginRecord = plugin as unknown as {
|
|
535
|
+
_plugin: ErrorPlugin<ErrorPluginProps, ErrorPluginMethods>
|
|
520
536
|
}
|
|
521
537
|
return {
|
|
522
|
-
props: { ...(
|
|
523
|
-
methods: { ...(
|
|
524
|
-
|
|
538
|
+
props: { ...(pluginRecord._plugin.props ?? {}) },
|
|
539
|
+
methods: { ...(pluginRecord._plugin.methods ?? {}) },
|
|
540
|
+
adapt: [...(pluginRecord._plugin.adapt ?? [])],
|
|
525
541
|
}
|
|
526
542
|
}
|
|
527
543
|
|
|
528
544
|
static prop<TThis extends typeof Error0, TKey extends string, TInputValue, TOutputValue>(
|
|
529
545
|
this: TThis,
|
|
530
546
|
key: TKey,
|
|
531
|
-
value:
|
|
532
|
-
): ClassError0<
|
|
533
|
-
return this.
|
|
547
|
+
value: ErrorPluginPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<PluginsMapOf<TThis>>>,
|
|
548
|
+
): ClassError0<ExtendErrorPluginsMapWithProp<PluginsMapOf<TThis>, TKey, TInputValue, TOutputValue>> {
|
|
549
|
+
return this.use('prop', key, value)
|
|
534
550
|
}
|
|
535
551
|
|
|
536
552
|
static method<TThis extends typeof Error0, TKey extends string, TArgs extends unknown[], TOutputValue>(
|
|
537
553
|
this: TThis,
|
|
538
554
|
key: TKey,
|
|
539
|
-
value:
|
|
540
|
-
): ClassError0<
|
|
541
|
-
return this.
|
|
555
|
+
value: ErrorPluginMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<PluginsMapOf<TThis>>>,
|
|
556
|
+
): ClassError0<ExtendErrorPluginsMapWithMethod<PluginsMapOf<TThis>, TKey, TArgs, TOutputValue>> {
|
|
557
|
+
return this.use('method', key, value)
|
|
542
558
|
}
|
|
543
559
|
|
|
544
|
-
static
|
|
560
|
+
static adapt<TThis extends typeof Error0>(
|
|
545
561
|
this: TThis,
|
|
546
|
-
value:
|
|
547
|
-
): ClassError0<
|
|
548
|
-
return this.
|
|
562
|
+
value: ErrorPluginAdaptFn<ErrorInstanceOfMap<PluginsMapOf<TThis>>, ErrorOutputProps<PluginsMapOf<TThis>>>,
|
|
563
|
+
): ClassError0<PluginsMapOf<TThis>> {
|
|
564
|
+
return this.use('adapt', value)
|
|
549
565
|
}
|
|
550
566
|
|
|
551
|
-
static
|
|
567
|
+
static use<TThis extends typeof Error0, TBuilder extends PluginError0>(
|
|
552
568
|
this: TThis,
|
|
553
|
-
|
|
554
|
-
): ClassError0<
|
|
555
|
-
static
|
|
569
|
+
plugin: TBuilder,
|
|
570
|
+
): ClassError0<ExtendErrorPluginsMap<PluginsMapOf<TThis>, PluginOfBuilder<TBuilder>>>
|
|
571
|
+
static use<TThis extends typeof Error0, TKey extends string, TInputValue, TOutputValue>(
|
|
556
572
|
this: TThis,
|
|
557
573
|
kind: 'prop',
|
|
558
574
|
key: TKey,
|
|
559
|
-
value:
|
|
560
|
-
): ClassError0<
|
|
561
|
-
static
|
|
575
|
+
value: ErrorPluginPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<PluginsMapOf<TThis>>>,
|
|
576
|
+
): ClassError0<ExtendErrorPluginsMapWithProp<PluginsMapOf<TThis>, TKey, TInputValue, TOutputValue>>
|
|
577
|
+
static use<TThis extends typeof Error0, TKey extends string, TArgs extends unknown[], TOutputValue>(
|
|
562
578
|
this: TThis,
|
|
563
579
|
kind: 'method',
|
|
564
580
|
key: TKey,
|
|
565
|
-
value:
|
|
566
|
-
): ClassError0<
|
|
567
|
-
static
|
|
581
|
+
value: ErrorPluginMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<PluginsMapOf<TThis>>>,
|
|
582
|
+
): ClassError0<ExtendErrorPluginsMapWithMethod<PluginsMapOf<TThis>, TKey, TArgs, TOutputValue>>
|
|
583
|
+
static use<TThis extends typeof Error0>(
|
|
568
584
|
this: TThis,
|
|
569
|
-
kind: '
|
|
570
|
-
value:
|
|
571
|
-
): ClassError0<
|
|
572
|
-
static
|
|
585
|
+
kind: 'adapt',
|
|
586
|
+
value: ErrorPluginAdaptFn<ErrorInstanceOfMap<PluginsMapOf<TThis>>, ErrorOutputProps<PluginsMapOf<TThis>>>,
|
|
587
|
+
): ClassError0<PluginsMapOf<TThis>>
|
|
588
|
+
static use(
|
|
573
589
|
this: typeof Error0,
|
|
574
|
-
first:
|
|
575
|
-
key?: string |
|
|
576
|
-
value?:
|
|
590
|
+
first: PluginError0 | 'prop' | 'method' | 'adapt',
|
|
591
|
+
key?: string | ErrorPluginAdaptFn<any, any>,
|
|
592
|
+
value?: ErrorPluginPropOptions<unknown, unknown> | ErrorPluginMethodFn<unknown>,
|
|
577
593
|
): ClassError0 {
|
|
578
|
-
if (first instanceof
|
|
579
|
-
return this.
|
|
594
|
+
if (first instanceof PluginError0) {
|
|
595
|
+
return this._useWithPlugin(this._pluginFromBuilder(first))
|
|
580
596
|
}
|
|
581
|
-
if (first === '
|
|
597
|
+
if (first === 'adapt') {
|
|
582
598
|
if (typeof key !== 'function') {
|
|
583
|
-
throw new Error('Error0.
|
|
599
|
+
throw new Error('Error0.use("adapt", value) requires adapt function')
|
|
584
600
|
}
|
|
585
|
-
return this.
|
|
586
|
-
|
|
601
|
+
return this._useWithPlugin({
|
|
602
|
+
adapt: [key],
|
|
587
603
|
})
|
|
588
604
|
}
|
|
589
605
|
if (typeof key !== 'string' || value === undefined) {
|
|
590
|
-
throw new Error('Error0.
|
|
606
|
+
throw new Error('Error0.use(kind, key, value) requires key and value')
|
|
591
607
|
}
|
|
592
608
|
|
|
593
609
|
if (first === 'prop') {
|
|
594
|
-
return this.
|
|
595
|
-
props: { [key]: value as
|
|
610
|
+
return this._useWithPlugin({
|
|
611
|
+
props: { [key]: value as ErrorPluginPropOptions<unknown, unknown> },
|
|
596
612
|
})
|
|
597
613
|
}
|
|
598
|
-
return this.
|
|
599
|
-
methods: { [key]: value as
|
|
614
|
+
return this._useWithPlugin({
|
|
615
|
+
methods: { [key]: value as ErrorPluginMethodFn<unknown> },
|
|
600
616
|
})
|
|
601
617
|
}
|
|
602
618
|
|
|
603
|
-
static
|
|
604
|
-
return new
|
|
619
|
+
static plugin(): PluginError0 {
|
|
620
|
+
return new PluginError0()
|
|
605
621
|
}
|
|
606
622
|
|
|
607
623
|
static serialize(error: unknown, isPublic = true): Record<string, unknown> {
|
|
@@ -609,13 +625,16 @@ export class Error0 extends Error {
|
|
|
609
625
|
const json: Record<string, unknown> = {
|
|
610
626
|
name: error0.name,
|
|
611
627
|
message: error0.message,
|
|
612
|
-
// we do not serialize causes, it is enough that we have floated props and
|
|
628
|
+
// we do not serialize causes, it is enough that we have floated props and adapt helper
|
|
613
629
|
// cause: error0.cause,
|
|
614
630
|
}
|
|
615
631
|
|
|
616
|
-
const
|
|
617
|
-
const propsEntries = Object.entries(
|
|
632
|
+
const plugin = this._getResolvedPlugin()
|
|
633
|
+
const propsEntries = Object.entries(plugin.props)
|
|
618
634
|
for (const [key, prop] of propsEntries) {
|
|
635
|
+
if (prop.serialize === false) {
|
|
636
|
+
continue
|
|
637
|
+
}
|
|
619
638
|
try {
|
|
620
639
|
const value = prop.resolve({ value: error0.own(key), flow: error0.flow(key), error: error0 })
|
|
621
640
|
const jsonValue = prop.serialize({ value, error: error0, isPublic })
|