@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/src/index.ts CHANGED
@@ -1,55 +1,69 @@
1
- export type ErrorExtensionPropOptions<TInputValue, TOutputValue, TError extends Error0 = Error0> = {
2
- init: (input: TInputValue) => TOutputValue
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: (options: { value: TOutputValue; error: TError; isPublic: boolean }) => unknown
9
- deserialize: (options: { value: unknown; serialized: Record<string, unknown> }) => TOutputValue | undefined
27
+ serialize: ErrorPluginPropSerialize<TOutputValue, TError>
28
+ deserialize: ErrorPluginPropDeserialize<TOutputValue>
10
29
  }
11
- export type ErrorExtensionMethodFn<
12
- TOutputValue,
13
- TArgs extends unknown[] = unknown[],
14
- TError extends Error0 = Error0,
15
- > = (error: TError, ...args: TArgs) => TOutputValue
16
- export type ErrorExtensionRefineResult<TOutputProps extends Record<string, unknown>> = Partial<TOutputProps> | undefined
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) => ErrorExtensionRefineResult<TOutputProps>)
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 ErrorExtensionProps = { [key: string]: ErrorExtensionPropOptions<any, any> }
27
- export type ErrorExtensionMethods = { [key: string]: ErrorExtensionMethodFn<any, any[]> }
44
+ export type ErrorPluginProps = { [key: string]: ErrorPluginPropOptions<any, any> }
45
+ export type ErrorPluginMethods = { [key: string]: ErrorPluginMethodFn<any, any[]> }
28
46
 
29
- export type ErrorExtension<
30
- TProps extends ErrorExtensionProps = Record<never, never>,
31
- TMethods extends ErrorExtensionMethods = Record<never, never>,
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
- refine?: Array<ErrorExtensionRefineFn<Error0, ExtensionOutputProps<TProps>>>
53
+ adapt?: Array<ErrorPluginAdaptFn<Error0, PluginOutputProps<TProps>>>
36
54
  }
37
- type AddPropToExtensionProps<
38
- TProps extends ErrorExtensionProps,
39
- TKey extends string,
40
- TInputValue,
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, ErrorExtensionMethodFn<TOutputValue, TArgs>>
49
- type ExtensionOutputProps<TProps extends ErrorExtensionProps> = {
50
- [TKey in keyof TProps]: TProps[TKey] extends ErrorExtensionPropOptions<any, infer TOutputValue> ? TOutputValue : never
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 ErrorExtensionsMap = {
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
- export type ErrorInput<TExtensionsMap extends ErrorExtensionsMap> =
61
- IsEmptyObject<TExtensionsMap['props']> extends true
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<TExtensionsMap extends ErrorExtensionsMap> = {
69
- [TKey in keyof TExtensionsMap['props']]?: TExtensionsMap['props'][TKey]['resolve']
84
+ type ErrorOutputProps<TPluginsMap extends ErrorPluginsMap> = {
85
+ [TKey in keyof TPluginsMap['props']]: TPluginsMap['props'][TKey]['resolve'] | undefined
70
86
  }
71
- type ErrorOutputMethods<TExtensionsMap extends ErrorExtensionsMap> = {
72
- [TKey in keyof TExtensionsMap['methods']]: TExtensionsMap['methods'][TKey] extends {
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<TExtensionsMap extends ErrorExtensionsMap> = ErrorOutputProps<TExtensionsMap> &
80
- ErrorOutputMethods<TExtensionsMap>
95
+ export type ErrorOutput<TPluginsMap extends ErrorPluginsMap> = ErrorOutputProps<TPluginsMap> &
96
+ ErrorOutputMethods<TPluginsMap>
81
97
 
82
- type ErrorStaticMethods<TExtensionsMap extends ErrorExtensionsMap> = {
83
- [TKey in keyof TExtensionsMap['methods']]: TExtensionsMap['methods'][TKey] extends {
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 EmptyExtensionsMap = {
107
+ type EmptyPluginsMap = {
92
108
  props: Record<never, { init: never; resolve: never }>
93
109
  methods: Record<never, ErrorMethodRecord>
94
110
  }
95
111
 
96
- type ErrorExtensionResolved = {
97
- props: Record<string, ErrorExtensionPropOptions<unknown, unknown>>
98
- methods: Record<string, ErrorExtensionMethodFn<unknown>>
99
- refine: Array<ErrorExtensionRefineFn<Error0, Record<string, unknown>>>
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 ExtensionPropsMapOf<TExtension extends ErrorExtension> = {
103
- [TKey in keyof NonNullable<TExtension['props']>]: NonNullable<
104
- TExtension['props']
105
- >[TKey] extends ErrorExtensionPropOptions<infer TInputValue, infer TOutputValue>
106
- ? { init: TInputValue; resolve: TOutputValue }
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 ExtensionMethodsMapOf<TExtension extends ErrorExtension> = {
110
- [TKey in keyof NonNullable<TExtension['methods']>]: NonNullable<TExtension['methods']>[TKey] extends (
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 ErrorExtensionsMapOfExtension<TExtension extends ErrorExtension> = {
118
- props: ExtensionPropsMapOf<TExtension>
119
- methods: ExtensionMethodsMapOf<TExtension>
134
+ type ErrorPluginsMapOfPlugin<TPlugin extends ErrorPlugin> = {
135
+ props: PluginPropsMapOf<TPlugin>
136
+ methods: PluginMethodsMapOf<TPlugin>
120
137
  }
121
- type ExtendErrorExtensionsMap<TMap extends ErrorExtensionsMap, TExtension extends ErrorExtension> = {
122
- props: TMap['props'] & ErrorExtensionsMapOfExtension<TExtension>['props']
123
- methods: TMap['methods'] & ErrorExtensionsMapOfExtension<TExtension>['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 ExtendErrorExtensionsMapWithProp<
126
- TMap extends ErrorExtensionsMap,
142
+ type ExtendErrorPluginsMapWithProp<
143
+ TMap extends ErrorPluginsMap,
127
144
  TKey extends string,
128
145
  TInputValue,
129
146
  TOutputValue,
130
- > = ExtendErrorExtensionsMap<TMap, ErrorExtension<Record<TKey, ErrorExtensionPropOptions<TInputValue, TOutputValue>>>>
131
- type ExtendErrorExtensionsMapWithMethod<
132
- TMap extends ErrorExtensionsMap,
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
- > = ExtendErrorExtensionsMap<
153
+ > = ExtendErrorPluginsMap<
137
154
  TMap,
138
- ErrorExtension<Record<never, never>, Record<TKey, ErrorExtensionMethodFn<TOutputValue, TArgs>>>
155
+ ErrorPlugin<Record<never, never>, Record<TKey, ErrorPluginMethodFn<TOutputValue, TArgs>>>
139
156
  >
140
157
 
141
- type ExtensionsMapOf<TClass> = TClass extends { __extensionsMap?: infer TExtensionsMap }
142
- ? TExtensionsMap extends ErrorExtensionsMap
143
- ? TExtensionsMap
144
- : EmptyExtensionsMap
145
- : EmptyExtensionsMap
146
-
147
- type ExtensionsMapFromParts<
148
- TProps extends ErrorExtensionProps,
149
- TMethods extends ErrorExtensionMethods,
150
- > = ErrorExtensionsMapOfExtension<ErrorExtension<TProps, TMethods>>
151
- type ErrorInstanceOfMap<TMap extends ErrorExtensionsMap> = Error0 & ErrorOutput<TMap>
152
- type BuilderError0<TProps extends ErrorExtensionProps, TMethods extends ErrorExtensionMethods> = Error0 &
153
- ErrorOutput<ExtensionsMapFromParts<TProps, TMethods>>
154
-
155
- type ExtensionOfBuilder<TBuilder> =
156
- TBuilder extends ExtensionError0<infer TProps, infer TMethods> ? ErrorExtension<TProps, TMethods> : never
157
-
158
- export class ExtensionError0<
159
- TProps extends ErrorExtensionProps = Record<never, never>,
160
- TMethods extends ErrorExtensionMethods = Record<never, never>,
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 _extension: ErrorExtension<ErrorExtensionProps, ErrorExtensionMethods>
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(extension?: ErrorExtension<ErrorExtensionProps, ErrorExtensionMethods>) {
170
- this._extension = {
171
- props: { ...(extension?.props ?? {}) },
172
- methods: { ...(extension?.methods ?? {}) },
173
- refine: [...(extension?.refine ?? [])],
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: ErrorExtensionPropOptions<TInputValue, TOutputValue, BuilderError0<TProps, TMethods>>,
180
- ): ExtensionError0<AddPropToExtensionProps<TProps, TKey, TInputValue, TOutputValue>, TMethods> {
181
- return this.extend('prop', key, value)
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: ErrorExtensionMethodFn<TOutputValue, TArgs, BuilderError0<TProps, TMethods>>,
187
- ): ExtensionError0<TProps, AddMethodToExtensionMethods<TMethods, TKey, TArgs, TOutputValue>> {
188
- return this.extend('method', key, value)
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
- refine(
192
- value: ErrorExtensionRefineFn<BuilderError0<TProps, TMethods>, ExtensionOutputProps<TProps>>,
193
- ): ExtensionError0<TProps, TMethods> {
194
- return this.extend('refine', value)
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
- extend<TKey extends string, TInputValue, TOutputValue>(
214
+ use<TKey extends string, TInputValue, TOutputValue>(
198
215
  kind: 'prop',
199
216
  key: TKey,
200
- value: ErrorExtensionPropOptions<TInputValue, TOutputValue, BuilderError0<TProps, TMethods>>,
201
- ): ExtensionError0<AddPropToExtensionProps<TProps, TKey, TInputValue, TOutputValue>, TMethods>
202
- extend<TKey extends string, TArgs extends unknown[], TOutputValue>(
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: ErrorExtensionMethodFn<TOutputValue, TArgs, BuilderError0<TProps, TMethods>>,
206
- ): ExtensionError0<TProps, AddMethodToExtensionMethods<TMethods, TKey, TArgs, TOutputValue>>
207
- extend(
208
- kind: 'refine',
209
- value: ErrorExtensionRefineFn<BuilderError0<TProps, TMethods>, ExtensionOutputProps<TProps>>,
210
- ): ExtensionError0<TProps, TMethods>
211
- extend(
212
- kind: 'prop' | 'method' | 'refine',
213
- keyOrValue: string | ErrorExtensionRefineFn<any, any>,
214
- value?: ErrorExtensionPropOptions<unknown, unknown, any> | ErrorExtensionMethodFn<unknown, unknown[], any>,
215
- ): ExtensionError0<any, any> {
216
- const nextProps: ErrorExtensionProps = { ...(this._extension.props ?? {}) }
217
- const nextMethods: ErrorExtensionMethods = { ...(this._extension.methods ?? {}) }
218
- const nextRefine: Array<ErrorExtensionRefineFn<Error0, Record<string, unknown>>> = [
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('ExtensionError0.extend("prop", key, value) requires value')
239
+ throw new Error('PluginError0.use("prop", key, value) requires value')
225
240
  }
226
- nextProps[key] = value as ErrorExtensionPropOptions<any, any>
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('ExtensionError0.extend("method", key, value) requires value')
245
+ throw new Error('PluginError0.use("method", key, value) requires value')
231
246
  }
232
- nextMethods[key] = value as ErrorExtensionMethodFn<any, any[]>
247
+ nextMethods[key] = value as ErrorPluginMethodFn<any, any[]>
233
248
  } else {
234
- nextRefine.push(keyOrValue as ErrorExtensionRefineFn<Error0, Record<string, unknown>>)
249
+ nextAdapt.push(keyOrValue as ErrorPluginAdaptFn<Error0, Record<string, unknown>>)
235
250
  }
236
- return new ExtensionError0({
251
+ return new PluginError0({
237
252
  props: nextProps,
238
253
  methods: nextMethods,
239
- refine: nextRefine,
254
+ adapt: nextAdapt,
240
255
  })
241
256
  }
242
257
  }
243
258
 
244
- export type ClassError0<TExtensionsMap extends ErrorExtensionsMap = EmptyExtensionsMap> = {
245
- new (message: string, input?: ErrorInput<TExtensionsMap>): Error0 & ErrorOutput<TExtensionsMap>
246
- new (input: { message: string } & ErrorInput<TExtensionsMap>): Error0 & ErrorOutput<TExtensionsMap>
247
- readonly __extensionsMap?: TExtensionsMap
248
- from: (error: unknown) => Error0 & ErrorOutput<TExtensionsMap>
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: ErrorExtensionPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<TExtensionsMap>>,
253
- ) => ClassError0<ExtendErrorExtensionsMapWithProp<TExtensionsMap, TKey, TInputValue, TOutputValue>>
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: ErrorExtensionMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<TExtensionsMap>>,
257
- ) => ClassError0<ExtendErrorExtensionsMapWithMethod<TExtensionsMap, TKey, TArgs, TOutputValue>>
258
- refine: (
259
- value: ErrorExtensionRefineFn<ErrorInstanceOfMap<TExtensionsMap>, ErrorOutputProps<TExtensionsMap>>,
260
- ) => ClassError0<TExtensionsMap>
261
- extend: {
262
- <TBuilder extends ExtensionError0>(
263
- extension: TBuilder,
264
- ): ClassError0<ExtendErrorExtensionsMap<TExtensionsMap, ExtensionOfBuilder<TBuilder>>>
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: ErrorExtensionPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<TExtensionsMap>>,
269
- ): ClassError0<ExtendErrorExtensionsMapWithProp<TExtensionsMap, TKey, TInputValue, TOutputValue>>
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: ErrorExtensionMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<TExtensionsMap>>,
274
- ): ClassError0<ExtendErrorExtensionsMapWithMethod<TExtensionsMap, TKey, TArgs, TOutputValue>>
288
+ value: ErrorPluginMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<TPluginsMap>>,
289
+ ): ClassError0<ExtendErrorPluginsMapWithMethod<TPluginsMap, TKey, TArgs, TOutputValue>>
275
290
  (
276
- kind: 'refine',
277
- value: ErrorExtensionRefineFn<ErrorInstanceOfMap<TExtensionsMap>, ErrorOutputProps<TExtensionsMap>>,
278
- ): ClassError0<TExtensionsMap>
291
+ kind: 'adapt',
292
+ value: ErrorPluginAdaptFn<ErrorInstanceOfMap<TPluginsMap>, ErrorOutputProps<TPluginsMap>>,
293
+ ): ClassError0<TPluginsMap>
279
294
  }
280
- extension: () => ExtensionError0
281
- } & ErrorStaticMethods<TExtensionsMap>
295
+ plugin: () => PluginError0
296
+ } & ErrorStaticMethods<TPluginsMap>
282
297
 
283
298
  export class Error0 extends Error {
284
- static readonly __extensionsMap?: EmptyExtensionsMap
285
- protected static _extensions: ErrorExtension[] = []
299
+ static readonly __pluginsMap?: EmptyPluginsMap
300
+ protected static _plugins: ErrorPlugin[] = []
286
301
 
287
- private static readonly _emptyExtension: ErrorExtensionResolved = {
302
+ private static readonly _emptyPlugin: ErrorPluginResolved = {
288
303
  props: {},
289
304
  methods: {},
290
- refine: [],
305
+ adapt: [],
291
306
  }
292
307
 
293
- private static _getResolvedExtension(this: typeof Error0): ErrorExtensionResolved {
294
- const resolved: ErrorExtensionResolved = {
308
+ private static _getResolvedPlugin(this: typeof Error0): ErrorPluginResolved {
309
+ const resolved: ErrorPluginResolved = {
295
310
  props: {},
296
311
  methods: {},
297
- refine: [],
312
+ adapt: [],
298
313
  }
299
- for (const extension of this._extensions) {
300
- Object.assign(resolved.props, extension.props ?? this._emptyExtension.props)
301
- Object.assign(resolved.methods, extension.methods ?? this._emptyExtension.methods)
302
- resolved.refine.push(...(extension.refine ?? this._emptyExtension.refine))
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<EmptyExtensionsMap>)
308
- constructor(input: { message: string } & ErrorInput<EmptyExtensionsMap>)
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<EmptyExtensionsMap>]
312
- | [{ message: string } & ErrorInput<EmptyExtensionsMap>]
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 extension = ctor._getResolvedExtension()
336
+ const plugin = ctor._getResolvedPlugin()
322
337
 
323
- for (const [key, prop] of Object.entries(extension.props)) {
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 _applyRefine(error: Error0): Error0 {
430
- const extension = this._getResolvedExtension()
431
- for (const refine of extension.refine) {
432
- const refined = refine(error as any)
433
- if (refined && typeof refined === 'object') {
434
- Object.assign(error as unknown as Record<string, unknown>, refined)
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._applyRefine(new this(message, { cause: error }))
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 extension = this._getResolvedExtension()
448
- const propsEntries = Object.entries(extension.props)
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._applyRefine(new this(message, { cause: error }))
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 _extendWithExtension(
502
+ private static _useWithPlugin(
485
503
  this: typeof Error0,
486
- extension: ErrorExtension<ErrorExtensionProps, ErrorExtensionMethods>,
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)._extensions = [...Base._extensions, extension]
508
+ ;(Error0Extended as typeof Error0)._plugins = [...Base._plugins, plugin]
491
509
 
492
- const resolved = (Error0Extended as typeof Error0)._getResolvedExtension()
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 _extensionFromBuilder(
516
- extension: ExtensionError0,
517
- ): ErrorExtension<ErrorExtensionProps, ErrorExtensionMethods> {
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: { ...(extensionRecord._extension.props ?? {}) },
523
- methods: { ...(extensionRecord._extension.methods ?? {}) },
524
- refine: [...(extensionRecord._extension.refine ?? [])],
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: ErrorExtensionPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<ExtensionsMapOf<TThis>>>,
532
- ): ClassError0<ExtendErrorExtensionsMapWithProp<ExtensionsMapOf<TThis>, TKey, TInputValue, TOutputValue>> {
533
- return this.extend('prop', key, value)
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: ErrorExtensionMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<ExtensionsMapOf<TThis>>>,
540
- ): ClassError0<ExtendErrorExtensionsMapWithMethod<ExtensionsMapOf<TThis>, TKey, TArgs, TOutputValue>> {
541
- return this.extend('method', key, value)
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 refine<TThis extends typeof Error0>(
560
+ static adapt<TThis extends typeof Error0>(
545
561
  this: TThis,
546
- value: ErrorExtensionRefineFn<ErrorInstanceOfMap<ExtensionsMapOf<TThis>>, ErrorOutputProps<ExtensionsMapOf<TThis>>>,
547
- ): ClassError0<ExtensionsMapOf<TThis>> {
548
- return this.extend('refine', value)
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 extend<TThis extends typeof Error0, TBuilder extends ExtensionError0>(
567
+ static use<TThis extends typeof Error0, TBuilder extends PluginError0>(
552
568
  this: TThis,
553
- extension: TBuilder,
554
- ): ClassError0<ExtendErrorExtensionsMap<ExtensionsMapOf<TThis>, ExtensionOfBuilder<TBuilder>>>
555
- static extend<TThis extends typeof Error0, TKey extends string, TInputValue, TOutputValue>(
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: ErrorExtensionPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<ExtensionsMapOf<TThis>>>,
560
- ): ClassError0<ExtendErrorExtensionsMapWithProp<ExtensionsMapOf<TThis>, TKey, TInputValue, TOutputValue>>
561
- static extend<TThis extends typeof Error0, TKey extends string, TArgs extends unknown[], TOutputValue>(
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: ErrorExtensionMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<ExtensionsMapOf<TThis>>>,
566
- ): ClassError0<ExtendErrorExtensionsMapWithMethod<ExtensionsMapOf<TThis>, TKey, TArgs, TOutputValue>>
567
- static extend<TThis extends typeof Error0>(
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: 'refine',
570
- value: ErrorExtensionRefineFn<ErrorInstanceOfMap<ExtensionsMapOf<TThis>>, ErrorOutputProps<ExtensionsMapOf<TThis>>>,
571
- ): ClassError0<ExtensionsMapOf<TThis>>
572
- static extend(
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: ExtensionError0 | 'prop' | 'method' | 'refine',
575
- key?: string | ErrorExtensionRefineFn<any, any>,
576
- value?: ErrorExtensionPropOptions<unknown, unknown> | ErrorExtensionMethodFn<unknown>,
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 ExtensionError0) {
579
- return this._extendWithExtension(this._extensionFromBuilder(first))
594
+ if (first instanceof PluginError0) {
595
+ return this._useWithPlugin(this._pluginFromBuilder(first))
580
596
  }
581
- if (first === 'refine') {
597
+ if (first === 'adapt') {
582
598
  if (typeof key !== 'function') {
583
- throw new Error('Error0.extend("refine", value) requires refine function')
599
+ throw new Error('Error0.use("adapt", value) requires adapt function')
584
600
  }
585
- return this._extendWithExtension({
586
- refine: [key],
601
+ return this._useWithPlugin({
602
+ adapt: [key],
587
603
  })
588
604
  }
589
605
  if (typeof key !== 'string' || value === undefined) {
590
- throw new Error('Error0.extend(kind, key, value) requires key and value')
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._extendWithExtension({
595
- props: { [key]: value as ErrorExtensionPropOptions<unknown, unknown> },
610
+ return this._useWithPlugin({
611
+ props: { [key]: value as ErrorPluginPropOptions<unknown, unknown> },
596
612
  })
597
613
  }
598
- return this._extendWithExtension({
599
- methods: { [key]: value as ErrorExtensionMethodFn<unknown> },
614
+ return this._useWithPlugin({
615
+ methods: { [key]: value as ErrorPluginMethodFn<unknown> },
600
616
  })
601
617
  }
602
618
 
603
- static extension(): ExtensionError0 {
604
- return new ExtensionError0()
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 refine helper
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 extension = this._getResolvedExtension()
617
- const propsEntries = Object.entries(extension.props)
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 })