@devp0nt/error0 1.0.0-next.4 → 1.0.0-next.40
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 +379 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.d.cts +177 -415
- package/dist/esm/index.d.ts +177 -415
- package/dist/esm/index.js +301 -347
- package/dist/esm/index.js.map +1 -1
- package/package.json +45 -22
- package/src/index.test.ts +315 -478
- package/src/index.ts +637 -506
- package/dist/cjs/index.js +0 -435
- package/dist/cjs/index.js.map +0 -1
package/src/index.ts
CHANGED
|
@@ -1,585 +1,716 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
// TODO: В эррор0 добавить ориджинал
|
|
7
|
-
// TODO: store tags as array from all causes
|
|
8
|
-
// TODO: not use self stack if toError0
|
|
9
|
-
// TODO: fix default message in extended error0, should be used in constuctor of Error0
|
|
10
|
-
// TODO: remove defaults prop from getPropsFromUnknown
|
|
11
|
-
// TODO: code has enum type, fn to check if code exists
|
|
12
|
-
|
|
13
|
-
export interface Error0Input {
|
|
14
|
-
message?: string
|
|
15
|
-
tag?: string
|
|
16
|
-
code?: string
|
|
17
|
-
httpStatus?: HttpStatusCode | HttpStatusCodeString
|
|
18
|
-
expected?: boolean | ExpectedFn
|
|
19
|
-
clientMessage?: string
|
|
20
|
-
cause?: Error0Cause
|
|
21
|
-
stack?: string
|
|
22
|
-
meta?: Meta0.Meta0OrValueTypeNullish
|
|
23
|
-
zodError?: ZodError
|
|
24
|
-
axiosError?: AxiosError
|
|
1
|
+
export type ErrorExtensionPropOptions<TInputValue, TOutputValue, TError extends Error0 = Error0> = {
|
|
2
|
+
input: (value: TInputValue) => TOutputValue
|
|
3
|
+
output: (error: TError) => TOutputValue
|
|
4
|
+
serialize: (value: TOutputValue, error: TError, isPublic: boolean) => unknown
|
|
25
5
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
6
|
+
export type ErrorExtensionCopmputedFn<TOutputValue, TError extends Error0 = Error0> = (error: TError) => TOutputValue
|
|
7
|
+
export type ErrorExtensionMethodFn<
|
|
8
|
+
TOutputValue,
|
|
9
|
+
TArgs extends unknown[] = unknown[],
|
|
10
|
+
TError extends Error0 = Error0,
|
|
11
|
+
> = (error: TError, ...args: TArgs) => TOutputValue
|
|
12
|
+
export type ErrorExtensionRefineResult<TOutputProps extends Record<string, unknown>> = Partial<TOutputProps> | undefined
|
|
13
|
+
export type ErrorExtensionRefineFn<
|
|
14
|
+
TError extends Error0 = Error0,
|
|
15
|
+
TOutputProps extends Record<string, unknown> = Record<never, never>,
|
|
16
|
+
> = ((error: TError) => void) | ((error: TError) => ErrorExtensionRefineResult<TOutputProps>)
|
|
17
|
+
type ErrorMethodRecord = {
|
|
18
|
+
args: unknown[]
|
|
19
|
+
output: unknown
|
|
40
20
|
}
|
|
41
21
|
|
|
42
|
-
type
|
|
43
|
-
type
|
|
44
|
-
type
|
|
45
|
-
|
|
46
|
-
|
|
22
|
+
export type ErrorExtensionProps = { [key: string]: ErrorExtensionPropOptions<any, any> }
|
|
23
|
+
export type ErrorExtensionComputed = { [key: string]: ErrorExtensionCopmputedFn<any> }
|
|
24
|
+
export type ErrorExtensionMethods = { [key: string]: ErrorExtensionMethodFn<any, any[]> }
|
|
25
|
+
|
|
26
|
+
export type ErrorExtension<
|
|
27
|
+
TProps extends ErrorExtensionProps = Record<never, never>,
|
|
28
|
+
TComputed extends ErrorExtensionComputed = Record<never, never>,
|
|
29
|
+
TMethods extends ErrorExtensionMethods = Record<never, never>,
|
|
30
|
+
> = {
|
|
31
|
+
props?: TProps
|
|
32
|
+
computed?: TComputed
|
|
33
|
+
methods?: TMethods
|
|
34
|
+
refine?: Array<ErrorExtensionRefineFn<Error0, ExtensionOutputProps<TProps>>>
|
|
35
|
+
}
|
|
36
|
+
type AddPropToExtensionProps<
|
|
37
|
+
TProps extends ErrorExtensionProps,
|
|
38
|
+
TKey extends string,
|
|
39
|
+
TInputValue,
|
|
40
|
+
TOutputValue,
|
|
41
|
+
> = 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
|
+
type AddMethodToExtensionMethods<
|
|
48
|
+
TMethods extends ErrorExtensionMethods,
|
|
49
|
+
TKey extends string,
|
|
50
|
+
TArgs extends unknown[],
|
|
51
|
+
TOutputValue,
|
|
52
|
+
> = TMethods & Record<TKey, ErrorExtensionMethodFn<TOutputValue, TArgs>>
|
|
53
|
+
type ExtensionOutputProps<TProps extends ErrorExtensionProps> = {
|
|
54
|
+
[TKey in keyof TProps]: TProps[TKey] extends ErrorExtensionPropOptions<any, infer TOutputValue> ? TOutputValue : never
|
|
55
|
+
}
|
|
56
|
+
export type ErrorExtensionsMap = {
|
|
57
|
+
props: Record<string, { input: unknown; output: unknown }>
|
|
58
|
+
computed: Record<string, unknown>
|
|
59
|
+
methods: Record<string, ErrorMethodRecord>
|
|
60
|
+
}
|
|
61
|
+
export type IsEmptyObject<T> = keyof T extends never ? true : false
|
|
62
|
+
export type ErrorInputBase = {
|
|
63
|
+
cause?: unknown
|
|
64
|
+
}
|
|
65
|
+
export type ErrorInput<TExtensionsMap extends ErrorExtensionsMap> =
|
|
66
|
+
IsEmptyObject<TExtensionsMap['props']> extends true
|
|
67
|
+
? ErrorInputBase
|
|
68
|
+
: ErrorInputBase &
|
|
69
|
+
Partial<{
|
|
70
|
+
[TKey in keyof TExtensionsMap['props']]: TExtensionsMap['props'][TKey]['input']
|
|
71
|
+
}>
|
|
72
|
+
|
|
73
|
+
type ErrorOutputProps<TExtensionsMap extends ErrorExtensionsMap> = {
|
|
74
|
+
[TKey in keyof TExtensionsMap['props']]: TExtensionsMap['props'][TKey]['output']
|
|
75
|
+
}
|
|
76
|
+
type ErrorOutputComputed<TExtensionsMap extends ErrorExtensionsMap> = {
|
|
77
|
+
[TKey in keyof TExtensionsMap['computed']]: TExtensionsMap['computed'][TKey]
|
|
78
|
+
}
|
|
79
|
+
type ErrorOutputMethods<TExtensionsMap extends ErrorExtensionsMap> = {
|
|
80
|
+
[TKey in keyof TExtensionsMap['methods']]: TExtensionsMap['methods'][TKey] extends {
|
|
81
|
+
args: infer TArgs extends unknown[]
|
|
82
|
+
output: infer TOutput
|
|
83
|
+
}
|
|
84
|
+
? (...args: TArgs) => TOutput
|
|
85
|
+
: never
|
|
86
|
+
}
|
|
87
|
+
export type ErrorOutput<TExtensionsMap extends ErrorExtensionsMap> = ErrorOutputProps<TExtensionsMap> &
|
|
88
|
+
ErrorOutputComputed<TExtensionsMap> &
|
|
89
|
+
ErrorOutputMethods<TExtensionsMap>
|
|
90
|
+
|
|
91
|
+
type ErrorStaticMethods<TExtensionsMap extends ErrorExtensionsMap> = {
|
|
92
|
+
[TKey in keyof TExtensionsMap['methods']]: TExtensionsMap['methods'][TKey] extends {
|
|
93
|
+
args: infer TArgs extends unknown[]
|
|
94
|
+
output: infer TOutput
|
|
95
|
+
}
|
|
96
|
+
? (error: unknown, ...args: TArgs) => TOutput
|
|
97
|
+
: never
|
|
98
|
+
}
|
|
47
99
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
public readonly httpStatus?: Error0GeneralProps['httpStatus']
|
|
54
|
-
public readonly expected?: Error0GeneralProps['expected']
|
|
55
|
-
public readonly clientMessage?: Error0GeneralProps['clientMessage']
|
|
56
|
-
public readonly anyMessage?: Error0GeneralProps['anyMessage']
|
|
57
|
-
public override readonly cause?: Error0GeneralProps['cause']
|
|
58
|
-
public readonly meta?: Meta0.Meta0OrValueTypeNullish
|
|
59
|
-
public readonly zodError?: Error0GeneralProps['zodError']
|
|
60
|
-
public readonly axiosError?: Error0GeneralProps['axiosError']
|
|
61
|
-
|
|
62
|
-
static defaultMessage = 'Unknown error'
|
|
63
|
-
static defaultCode?: Error0GeneralProps['code']
|
|
64
|
-
static defaultHttpStatus?: Error0GeneralProps['httpStatus']
|
|
65
|
-
static defaultExpected?: Error0GeneralProps['expected']
|
|
66
|
-
static defaultClientMessage?: Error0GeneralProps['clientMessage']
|
|
67
|
-
static defaultMeta?: Meta0.Meta0OrValueTypeNullish
|
|
68
|
-
|
|
69
|
-
public readonly propsOriginal: Error0GeneralProps
|
|
70
|
-
|
|
71
|
-
constructor(message: string)
|
|
72
|
-
constructor(input: Error0Input)
|
|
73
|
-
constructor(message: string, input: Error0Input)
|
|
74
|
-
constructor(error: Error)
|
|
75
|
-
constructor(error: Error, input: Error0Input)
|
|
76
|
-
constructor(value: unknown)
|
|
77
|
-
constructor(value: unknown, input: Error0Input)
|
|
78
|
-
constructor(...args: unknown[]) {
|
|
79
|
-
const input: Partial<Error0Input> = {}
|
|
80
|
-
if (args[0] instanceof Error) {
|
|
81
|
-
input.cause = args[0]
|
|
82
|
-
} else if (typeof args[0] === 'object' && args[0] !== null) {
|
|
83
|
-
Object.assign(input, args[0])
|
|
84
|
-
} else if (typeof args[0] === 'string') {
|
|
85
|
-
input.message = args[0]
|
|
86
|
-
}
|
|
87
|
-
if (typeof args[1] === 'object' && args[1] !== null) {
|
|
88
|
-
Object.assign(input, args[1])
|
|
89
|
-
}
|
|
90
|
-
const safeInput = Error0._safeParseInput(input)
|
|
100
|
+
type EmptyExtensionsMap = {
|
|
101
|
+
props: Record<never, { input: never; output: never }>
|
|
102
|
+
computed: Record<never, never>
|
|
103
|
+
methods: Record<never, ErrorMethodRecord>
|
|
104
|
+
}
|
|
91
105
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
106
|
+
type ErrorExtensionResolved = {
|
|
107
|
+
props: Record<string, ErrorExtensionPropOptions<unknown, unknown>>
|
|
108
|
+
computed: Record<string, ErrorExtensionCopmputedFn<unknown>>
|
|
109
|
+
methods: Record<string, ErrorExtensionMethodFn<unknown>>
|
|
110
|
+
refine: Array<ErrorExtensionRefineFn<Error0, Record<string, unknown>>>
|
|
111
|
+
}
|
|
96
112
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
meta,
|
|
190
|
-
zodError: error0Input.zodError,
|
|
191
|
-
axiosError: error0Input.axiosError,
|
|
192
|
-
}
|
|
193
|
-
result.expected = this._normalizeSelfExpected(
|
|
194
|
-
result,
|
|
195
|
-
typeof error0Input.expected === 'boolean' || typeof error0Input.expected === 'function'
|
|
196
|
-
? error0Input.expected
|
|
197
|
-
: meta.expected || this.defaultExpected,
|
|
198
|
-
)
|
|
199
|
-
result.stack = this._removeConstructorStackPart(stack)
|
|
200
|
-
return result
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
public static _getSelfPropsFloated(causesProps: Error0GeneralProps[]): Error0GeneralProps {
|
|
204
|
-
const cause = this._getClosestPropValue(causesProps, 'cause')
|
|
205
|
-
const stack = this._mergeStack(causesProps[1]?.stack, causesProps[0]?.stack)
|
|
206
|
-
const closestTag = this._getClosestPropValue(causesProps, 'tag')
|
|
207
|
-
const meta = this._getMergedMetaValue(causesProps)
|
|
208
|
-
const tag = Meta0.getFinalTag(meta, closestTag)
|
|
209
|
-
const propsFloated: Error0GeneralProps = {
|
|
210
|
-
message: this._getClosestPropValue(causesProps, 'message'),
|
|
211
|
-
tag,
|
|
212
|
-
code: this._getClosestPropValue(causesProps, 'code'),
|
|
213
|
-
httpStatus: this._getClosestPropValue(causesProps, 'httpStatus'),
|
|
214
|
-
expected: this._isExpected(causesProps),
|
|
215
|
-
clientMessage: this._getClosestPropValue(causesProps, 'clientMessage'),
|
|
216
|
-
cause,
|
|
217
|
-
stack,
|
|
218
|
-
anyMessage: causesProps[0].anyMessage,
|
|
219
|
-
meta,
|
|
220
|
-
zodError: this._getClosestPropValue(causesProps, 'zodError'),
|
|
221
|
-
axiosError: this._getClosestPropValue(causesProps, 'axiosError'),
|
|
222
|
-
}
|
|
223
|
-
return propsFloated
|
|
113
|
+
type ExtensionPropsMapOf<TExtension extends ErrorExtension> = {
|
|
114
|
+
[TKey in keyof NonNullable<TExtension['props']>]: NonNullable<
|
|
115
|
+
TExtension['props']
|
|
116
|
+
>[TKey] extends ErrorExtensionPropOptions<infer TInputValue, infer TOutputValue>
|
|
117
|
+
? { input: TInputValue; output: TOutputValue }
|
|
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
|
|
125
|
+
: never
|
|
126
|
+
}
|
|
127
|
+
type ExtensionMethodsMapOf<TExtension extends ErrorExtension> = {
|
|
128
|
+
[TKey in keyof NonNullable<TExtension['methods']>]: NonNullable<TExtension['methods']>[TKey] extends (
|
|
129
|
+
error: Error0,
|
|
130
|
+
...args: infer TArgs extends unknown[]
|
|
131
|
+
) => infer TOutput
|
|
132
|
+
? { args: TArgs; output: TOutput }
|
|
133
|
+
: never
|
|
134
|
+
}
|
|
135
|
+
type ErrorExtensionsMapOfExtension<TExtension extends ErrorExtension> = {
|
|
136
|
+
props: ExtensionPropsMapOf<TExtension>
|
|
137
|
+
computed: ExtensionComputedMapOf<TExtension>
|
|
138
|
+
methods: ExtensionMethodsMapOf<TExtension>
|
|
139
|
+
}
|
|
140
|
+
type ExtendErrorExtensionsMap<TMap extends ErrorExtensionsMap, TExtension extends ErrorExtension> = {
|
|
141
|
+
props: TMap['props'] & ErrorExtensionsMapOfExtension<TExtension>['props']
|
|
142
|
+
computed: TMap['computed'] & ErrorExtensionsMapOfExtension<TExtension>['computed']
|
|
143
|
+
methods: TMap['methods'] & ErrorExtensionsMapOfExtension<TExtension>['methods']
|
|
144
|
+
}
|
|
145
|
+
type ExtendErrorExtensionsMapWithProp<
|
|
146
|
+
TMap extends ErrorExtensionsMap,
|
|
147
|
+
TKey extends string,
|
|
148
|
+
TInputValue,
|
|
149
|
+
TOutputValue,
|
|
150
|
+
> = 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
|
+
type ExtendErrorExtensionsMapWithMethod<
|
|
160
|
+
TMap extends ErrorExtensionsMap,
|
|
161
|
+
TKey extends string,
|
|
162
|
+
TArgs extends unknown[],
|
|
163
|
+
TOutputValue,
|
|
164
|
+
> = ExtendErrorExtensionsMap<
|
|
165
|
+
TMap,
|
|
166
|
+
ErrorExtension<Record<never, never>, Record<never, never>, Record<TKey, ErrorExtensionMethodFn<TOutputValue, TArgs>>>
|
|
167
|
+
>
|
|
168
|
+
|
|
169
|
+
type ExtensionsMapOf<TClass> = TClass extends { __extensionsMap?: infer TExtensionsMap }
|
|
170
|
+
? TExtensionsMap extends ErrorExtensionsMap
|
|
171
|
+
? TExtensionsMap
|
|
172
|
+
: EmptyExtensionsMap
|
|
173
|
+
: EmptyExtensionsMap
|
|
174
|
+
|
|
175
|
+
type ExtensionsMapFromParts<
|
|
176
|
+
TProps extends ErrorExtensionProps,
|
|
177
|
+
TComputed extends ErrorExtensionComputed,
|
|
178
|
+
TMethods extends ErrorExtensionMethods,
|
|
179
|
+
> = ErrorExtensionsMapOfExtension<ErrorExtension<TProps, TComputed, TMethods>>
|
|
180
|
+
type ErrorInstanceOfMap<TMap extends ErrorExtensionsMap> = Error0 & ErrorOutput<TMap>
|
|
181
|
+
type BuilderError0<
|
|
182
|
+
TProps extends ErrorExtensionProps,
|
|
183
|
+
TComputed extends ErrorExtensionComputed,
|
|
184
|
+
TMethods extends ErrorExtensionMethods,
|
|
185
|
+
> = Error0 & ErrorOutput<ExtensionsMapFromParts<TProps, TComputed, TMethods>>
|
|
186
|
+
|
|
187
|
+
type ExtensionOfBuilder<TBuilder> =
|
|
188
|
+
TBuilder extends ExtensionError0<infer TProps, infer TComputed, infer TMethods>
|
|
189
|
+
? ErrorExtension<TProps, TComputed, TMethods>
|
|
190
|
+
: never
|
|
191
|
+
|
|
192
|
+
export type ErrorFlowPolicy = 'instance' | 'error0' | 'likeError0' | 'all'
|
|
193
|
+
|
|
194
|
+
export class ExtensionError0<
|
|
195
|
+
TProps extends ErrorExtensionProps = Record<never, never>,
|
|
196
|
+
TComputed extends ErrorExtensionComputed = Record<never, never>,
|
|
197
|
+
TMethods extends ErrorExtensionMethods = Record<never, never>,
|
|
198
|
+
> {
|
|
199
|
+
private readonly _extension: ErrorExtension<ErrorExtensionProps, ErrorExtensionComputed, ErrorExtensionMethods>
|
|
200
|
+
|
|
201
|
+
readonly Infer = undefined as unknown as {
|
|
202
|
+
props: TProps
|
|
203
|
+
computed: TComputed
|
|
204
|
+
methods: TMethods
|
|
224
205
|
}
|
|
225
206
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
207
|
+
constructor(extension?: ErrorExtension<ErrorExtensionProps, ErrorExtensionComputed, ErrorExtensionMethods>) {
|
|
208
|
+
this._extension = {
|
|
209
|
+
props: { ...(extension?.props ?? {}) },
|
|
210
|
+
computed: { ...(extension?.computed ?? {}) },
|
|
211
|
+
methods: { ...(extension?.methods ?? {}) },
|
|
212
|
+
refine: [...(extension?.refine ?? [])],
|
|
231
213
|
}
|
|
232
214
|
}
|
|
233
215
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
try {
|
|
240
|
-
return JSON.stringify(axiosError.response?.data)
|
|
241
|
-
} catch {
|
|
242
|
-
return undefined
|
|
243
|
-
}
|
|
244
|
-
})(),
|
|
245
|
-
axiosStatus: axiosError.response?.status,
|
|
246
|
-
},
|
|
247
|
-
}
|
|
216
|
+
prop<TKey extends string, TInputValue, TOutputValue>(
|
|
217
|
+
key: TKey,
|
|
218
|
+
value: ErrorExtensionPropOptions<TInputValue, TOutputValue, BuilderError0<TProps, TComputed, TMethods>>,
|
|
219
|
+
): ExtensionError0<AddPropToExtensionProps<TProps, TKey, TInputValue, TOutputValue>, TComputed, TMethods> {
|
|
220
|
+
return this.extend('prop', key, value)
|
|
248
221
|
}
|
|
249
222
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
):
|
|
254
|
-
|
|
255
|
-
Object.assign(error0Props, extraError0Props, { meta: metaValue })
|
|
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)
|
|
256
228
|
}
|
|
257
229
|
|
|
258
|
-
|
|
230
|
+
method<TKey extends string, TArgs extends unknown[], TOutputValue>(
|
|
231
|
+
key: TKey,
|
|
232
|
+
value: ErrorExtensionMethodFn<TOutputValue, TArgs, BuilderError0<TProps, TComputed, TMethods>>,
|
|
233
|
+
): ExtensionError0<TProps, TComputed, AddMethodToExtensionMethods<TMethods, TKey, TArgs, TOutputValue>> {
|
|
234
|
+
return this.extend('method', key, value)
|
|
235
|
+
}
|
|
259
236
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
if (typeof expectedProvided === 'function') {
|
|
265
|
-
return expectedProvided(error0Props)
|
|
266
|
-
}
|
|
267
|
-
return expectedProvided
|
|
237
|
+
refine(
|
|
238
|
+
value: ErrorExtensionRefineFn<BuilderError0<TProps, TComputed, TMethods>, ExtensionOutputProps<TProps>>,
|
|
239
|
+
): ExtensionError0<TProps, TComputed, TMethods> {
|
|
240
|
+
return this.extend('refine', value)
|
|
268
241
|
}
|
|
269
242
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
243
|
+
extend<TKey extends string, TInputValue, TOutputValue>(
|
|
244
|
+
kind: 'prop',
|
|
245
|
+
key: TKey,
|
|
246
|
+
value: ErrorExtensionPropOptions<TInputValue, TOutputValue, BuilderError0<TProps, TComputed, TMethods>>,
|
|
247
|
+
): ExtensionError0<AddPropToExtensionProps<TProps, TKey, TInputValue, TOutputValue>, TComputed, TMethods>
|
|
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>
|
|
253
|
+
extend<TKey extends string, TArgs extends unknown[], TOutputValue>(
|
|
254
|
+
kind: 'method',
|
|
255
|
+
key: TKey,
|
|
256
|
+
value: ErrorExtensionMethodFn<TOutputValue, TArgs, BuilderError0<TProps, TComputed, TMethods>>,
|
|
257
|
+
): ExtensionError0<TProps, TComputed, AddMethodToExtensionMethods<TMethods, TKey, TArgs, TOutputValue>>
|
|
258
|
+
extend(
|
|
259
|
+
kind: 'refine',
|
|
260
|
+
value: ErrorExtensionRefineFn<BuilderError0<TProps, TComputed, TMethods>, ExtensionOutputProps<TProps>>,
|
|
261
|
+
): ExtensionError0<TProps, TComputed, TMethods>
|
|
262
|
+
extend(
|
|
263
|
+
kind: 'prop' | 'computed' | 'method' | 'refine',
|
|
264
|
+
keyOrValue: string | ErrorExtensionRefineFn<any, any>,
|
|
265
|
+
value?:
|
|
266
|
+
| ErrorExtensionPropOptions<unknown, unknown, any>
|
|
267
|
+
| ErrorExtensionCopmputedFn<unknown, any>
|
|
268
|
+
| ErrorExtensionMethodFn<unknown, unknown[], any>,
|
|
269
|
+
): ExtensionError0<any, any, any> {
|
|
270
|
+
const nextProps: ErrorExtensionProps = { ...(this._extension.props ?? {}) }
|
|
271
|
+
const nextComputed: ErrorExtensionComputed = { ...(this._extension.computed ?? {}) }
|
|
272
|
+
const nextMethods: ErrorExtensionMethods = { ...(this._extension.methods ?? {}) }
|
|
273
|
+
const nextRefine: Array<ErrorExtensionRefineFn<Error0, Record<string, unknown>>> = [
|
|
274
|
+
...(this._extension.refine ?? []),
|
|
275
|
+
]
|
|
276
|
+
if (kind === 'prop') {
|
|
277
|
+
const key = keyOrValue as string
|
|
278
|
+
if (value === undefined) {
|
|
279
|
+
throw new Error('ExtensionError0.extend("prop", key, value) requires value')
|
|
280
|
+
}
|
|
281
|
+
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')
|
|
275
286
|
}
|
|
276
|
-
|
|
277
|
-
|
|
287
|
+
nextComputed[key] = value as ErrorExtensionCopmputedFn<any>
|
|
288
|
+
} else if (kind === 'method') {
|
|
289
|
+
const key = keyOrValue as string
|
|
290
|
+
if (value === undefined) {
|
|
291
|
+
throw new Error('ExtensionError0.extend("method", key, value) requires value')
|
|
278
292
|
}
|
|
293
|
+
nextMethods[key] = value as ErrorExtensionMethodFn<any, any[]>
|
|
294
|
+
} else {
|
|
295
|
+
nextRefine.push(keyOrValue as ErrorExtensionRefineFn<Error0, Record<string, unknown>>)
|
|
279
296
|
}
|
|
280
|
-
return
|
|
297
|
+
return new ExtensionError0({
|
|
298
|
+
props: nextProps,
|
|
299
|
+
computed: nextComputed,
|
|
300
|
+
methods: nextMethods,
|
|
301
|
+
refine: nextRefine,
|
|
302
|
+
})
|
|
281
303
|
}
|
|
304
|
+
}
|
|
282
305
|
|
|
283
|
-
|
|
306
|
+
export type ClassError0<TExtensionsMap extends ErrorExtensionsMap = EmptyExtensionsMap> = {
|
|
307
|
+
new (message: string, input?: ErrorInput<TExtensionsMap>): Error0 & ErrorOutput<TExtensionsMap>
|
|
308
|
+
new (input: { message: string } & ErrorInput<TExtensionsMap>): Error0 & ErrorOutput<TExtensionsMap>
|
|
309
|
+
readonly __extensionsMap?: TExtensionsMap
|
|
310
|
+
from: (error: unknown) => Error0 & ErrorOutput<TExtensionsMap>
|
|
311
|
+
serialize: (error: unknown, isPublic?: boolean) => object
|
|
312
|
+
extend: {
|
|
313
|
+
<TBuilder extends ExtensionError0>(
|
|
314
|
+
extension: TBuilder,
|
|
315
|
+
): ClassError0<ExtendErrorExtensionsMap<TExtensionsMap, ExtensionOfBuilder<TBuilder>>>
|
|
316
|
+
<TKey extends string, TInputValue, TOutputValue>(
|
|
317
|
+
kind: 'prop',
|
|
318
|
+
key: TKey,
|
|
319
|
+
value: ErrorExtensionPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<TExtensionsMap>>,
|
|
320
|
+
): 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
|
+
<TKey extends string, TArgs extends unknown[], TOutputValue>(
|
|
327
|
+
kind: 'method',
|
|
328
|
+
key: TKey,
|
|
329
|
+
value: ErrorExtensionMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<TExtensionsMap>>,
|
|
330
|
+
): ClassError0<ExtendErrorExtensionsMapWithMethod<TExtensionsMap, TKey, TArgs, TOutputValue>>
|
|
331
|
+
(
|
|
332
|
+
kind: 'refine',
|
|
333
|
+
value: ErrorExtensionRefineFn<ErrorInstanceOfMap<TExtensionsMap>, ErrorOutputProps<TExtensionsMap>>,
|
|
334
|
+
): ClassError0<TExtensionsMap>
|
|
335
|
+
}
|
|
336
|
+
extension: () => ExtensionError0
|
|
337
|
+
} & ErrorStaticMethods<TExtensionsMap>
|
|
284
338
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
anyMessage: this.defaultMessage,
|
|
295
|
-
cause: undefined,
|
|
296
|
-
stack: undefined,
|
|
297
|
-
zodError: undefined,
|
|
298
|
-
axiosError: undefined,
|
|
299
|
-
meta: {},
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
const message = 'message' in error && typeof error.message === 'string' ? error.message : undefined
|
|
303
|
-
const clientMessage =
|
|
304
|
-
'clientMessage' in error && typeof error.clientMessage === 'string'
|
|
305
|
-
? error.clientMessage
|
|
306
|
-
: defaults?.clientMessage || undefined
|
|
307
|
-
const result: Error0GeneralProps = {
|
|
308
|
-
message,
|
|
309
|
-
code: 'code' in error && typeof error.code === 'string' ? error.code : defaults?.code || undefined,
|
|
310
|
-
clientMessage,
|
|
311
|
-
anyMessage: clientMessage || message || this.defaultMessage,
|
|
312
|
-
expected: undefined,
|
|
313
|
-
stack: 'stack' in error && typeof error.stack === 'string' ? error.stack : undefined,
|
|
314
|
-
tag: 'tag' in error && typeof error.tag === 'string' ? error.tag : defaults?.tag || undefined,
|
|
315
|
-
cause: 'cause' in error ? error.cause : defaults?.cause || undefined,
|
|
316
|
-
meta:
|
|
317
|
-
'meta' in error && typeof error.meta === 'object' && error.meta !== null
|
|
318
|
-
? Meta0.getValue(error.meta as Meta0.ValueType)
|
|
319
|
-
: Meta0.getValue(defaults?.meta) || {},
|
|
320
|
-
httpStatus:
|
|
321
|
-
'httpStatus' in error && typeof error.httpStatus === 'number' && error.httpStatus in HttpStatusCode
|
|
322
|
-
? error.httpStatus
|
|
323
|
-
: typeof defaults?.httpStatus === 'string'
|
|
324
|
-
? HttpStatusCode[defaults.httpStatus]
|
|
325
|
-
: defaults?.httpStatus,
|
|
326
|
-
zodError:
|
|
327
|
-
'zodError' in error && error.zodError instanceof ZodError
|
|
328
|
-
? error.zodError
|
|
329
|
-
: error instanceof ZodError
|
|
330
|
-
? error
|
|
331
|
-
: defaults?.zodError,
|
|
332
|
-
axiosError:
|
|
333
|
-
'axiosError' in error && isAxiosError(error.axiosError)
|
|
334
|
-
? error.axiosError
|
|
335
|
-
: isAxiosError(error)
|
|
336
|
-
? error
|
|
337
|
-
: defaults?.axiosError,
|
|
338
|
-
}
|
|
339
|
-
result.expected = this._normalizeSelfExpected(
|
|
340
|
-
result,
|
|
341
|
-
'expected' in error && (typeof error.expected === 'boolean' || typeof error.expected === 'function')
|
|
342
|
-
? (error.expected as ExpectedFn)
|
|
343
|
-
: defaults?.expected || undefined,
|
|
344
|
-
)
|
|
345
|
-
if (result.zodError) {
|
|
346
|
-
this._assignError0Props(result, this._getExtraError0PropsByZodError(result.zodError))
|
|
347
|
-
}
|
|
348
|
-
if (result.axiosError) {
|
|
349
|
-
this._assignError0Props(result, this._getExtraError0PropsByAxiosError(result.axiosError))
|
|
350
|
-
}
|
|
351
|
-
return result
|
|
339
|
+
export class Error0 extends Error {
|
|
340
|
+
static readonly __extensionsMap?: EmptyExtensionsMap
|
|
341
|
+
protected static _extensions: ErrorExtension[] = []
|
|
342
|
+
|
|
343
|
+
private static readonly _emptyExtension: ErrorExtensionResolved = {
|
|
344
|
+
props: {},
|
|
345
|
+
computed: {},
|
|
346
|
+
methods: {},
|
|
347
|
+
refine: [],
|
|
352
348
|
}
|
|
353
349
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
if (!causeProps.cause) {
|
|
361
|
-
return causesProps
|
|
350
|
+
private static _getResolvedExtension(this: typeof Error0): ErrorExtensionResolved {
|
|
351
|
+
const resolved: ErrorExtensionResolved = {
|
|
352
|
+
props: {},
|
|
353
|
+
computed: {},
|
|
354
|
+
methods: {},
|
|
355
|
+
refine: [],
|
|
362
356
|
}
|
|
363
|
-
|
|
364
|
-
|
|
357
|
+
for (const extension of this._extensions) {
|
|
358
|
+
Object.assign(resolved.props, extension.props ?? this._emptyExtension.props)
|
|
359
|
+
Object.assign(resolved.computed, extension.computed ?? this._emptyExtension.computed)
|
|
360
|
+
Object.assign(resolved.methods, extension.methods ?? this._emptyExtension.methods)
|
|
361
|
+
resolved.refine.push(...(extension.refine ?? this._emptyExtension.refine))
|
|
365
362
|
}
|
|
366
|
-
return
|
|
363
|
+
return resolved
|
|
367
364
|
}
|
|
368
365
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
366
|
+
constructor(message: string, input?: ErrorInput<EmptyExtensionsMap>)
|
|
367
|
+
constructor(input: { message: string } & ErrorInput<EmptyExtensionsMap>)
|
|
368
|
+
constructor(
|
|
369
|
+
...args:
|
|
370
|
+
| [message: string, input?: ErrorInput<EmptyExtensionsMap>]
|
|
371
|
+
| [{ message: string } & ErrorInput<EmptyExtensionsMap>]
|
|
372
|
+
) {
|
|
373
|
+
const [first, second] = args
|
|
374
|
+
const input = typeof first === 'string' ? { message: first, ...(second ?? {}) } : first
|
|
375
|
+
|
|
376
|
+
super(input.message, { cause: input.cause })
|
|
377
|
+
this.name = 'Error0'
|
|
375
378
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
379
|
+
const ctor = this.constructor as typeof Error0
|
|
380
|
+
const extension = ctor._getResolvedExtension()
|
|
381
|
+
|
|
382
|
+
for (const [key, prop] of Object.entries(extension.props)) {
|
|
383
|
+
if (key in input) {
|
|
384
|
+
const ownValue = (input as Record<string, unknown>)[key]
|
|
385
|
+
;(this as Record<string, unknown>)[key] = prop.input(ownValue)
|
|
386
|
+
} else {
|
|
387
|
+
Object.defineProperty(this, key, {
|
|
388
|
+
get: () => prop.output(this),
|
|
389
|
+
set: (value) => {
|
|
390
|
+
Object.defineProperty(this, key, {
|
|
391
|
+
value,
|
|
392
|
+
writable: true,
|
|
393
|
+
enumerable: true,
|
|
394
|
+
configurable: true,
|
|
395
|
+
})
|
|
396
|
+
},
|
|
397
|
+
enumerable: true,
|
|
398
|
+
configurable: true,
|
|
399
|
+
})
|
|
384
400
|
}
|
|
385
401
|
}
|
|
386
|
-
|
|
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
|
+
}
|
|
387
418
|
}
|
|
388
419
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
// }
|
|
398
|
-
// }
|
|
399
|
-
// return undefined
|
|
400
|
-
// }
|
|
401
|
-
|
|
402
|
-
public static _getFilledPropValues<TPropKey extends keyof Error0Input>(
|
|
403
|
-
causesProps: Error0GeneralProps[],
|
|
404
|
-
propKey: TPropKey,
|
|
405
|
-
): NonNullable<Error0GeneralProps[TPropKey]>[] {
|
|
406
|
-
const values: NonNullable<Error0GeneralProps[TPropKey]>[] = []
|
|
407
|
-
for (const causeProps of causesProps) {
|
|
408
|
-
const propValue = causeProps[propKey]
|
|
409
|
-
if (isFilled(propValue)) {
|
|
410
|
-
values.push(propValue as NonNullable<Error0GeneralProps[TPropKey]>)
|
|
420
|
+
private static readonly isSelfProperty = (object: object, key: string): boolean => {
|
|
421
|
+
const d = Object.getOwnPropertyDescriptor(object, key)
|
|
422
|
+
if (!d) return false
|
|
423
|
+
if (typeof d.get === 'function' || typeof d.set === 'function') {
|
|
424
|
+
if ('name' in object && object.name === 'Error0') {
|
|
425
|
+
return false
|
|
426
|
+
} else {
|
|
427
|
+
return true
|
|
411
428
|
}
|
|
412
429
|
}
|
|
413
|
-
return
|
|
430
|
+
return true
|
|
414
431
|
}
|
|
415
432
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
return {}
|
|
420
|
-
} else if (metas.length === 1) {
|
|
421
|
-
return metas[0]
|
|
422
|
-
} else {
|
|
423
|
-
return Meta0.mergeValues(metas[0], ...metas.slice(1))
|
|
433
|
+
static own(error: object, key: string): unknown {
|
|
434
|
+
if (this.isSelfProperty(error, key)) {
|
|
435
|
+
return (error as Record<string, unknown>)[key]
|
|
424
436
|
}
|
|
437
|
+
return undefined
|
|
438
|
+
}
|
|
439
|
+
own(key: string): unknown {
|
|
440
|
+
const ctor = this.constructor as typeof Error0
|
|
441
|
+
return ctor.own(this, key)
|
|
425
442
|
}
|
|
426
443
|
|
|
427
|
-
|
|
444
|
+
static flow(error: object, key: string, policy: ErrorFlowPolicy = 'likeError0'): unknown[] {
|
|
445
|
+
return this.causes(error, policy).map((cause) => {
|
|
446
|
+
const causeRecord = cause as Record<string, unknown>
|
|
447
|
+
if (this.isSelfProperty(causeRecord, key)) {
|
|
448
|
+
return causeRecord[key]
|
|
449
|
+
}
|
|
450
|
+
return undefined
|
|
451
|
+
})
|
|
452
|
+
}
|
|
453
|
+
flow(key: string, policy: ErrorFlowPolicy = 'likeError0'): unknown[] {
|
|
454
|
+
const ctor = this.constructor as typeof Error0
|
|
455
|
+
return ctor.flow(this, key, policy)
|
|
456
|
+
}
|
|
428
457
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
458
|
+
static causes(error: object, policy: ErrorFlowPolicy = 'all'): object[] {
|
|
459
|
+
const causes: object[] = []
|
|
460
|
+
let current: unknown = error
|
|
461
|
+
const maxDepth = 99
|
|
462
|
+
const seen = new Set<unknown>()
|
|
463
|
+
|
|
464
|
+
for (let depth = 0; depth < maxDepth; depth += 1) {
|
|
465
|
+
if (!current || typeof current !== 'object') {
|
|
466
|
+
break
|
|
467
|
+
}
|
|
468
|
+
if (seen.has(current)) {
|
|
469
|
+
break
|
|
470
|
+
}
|
|
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
|
+
seen.add(current)
|
|
485
|
+
causes.push(current)
|
|
486
|
+
current = (current as { cause?: unknown }).cause
|
|
436
487
|
}
|
|
437
|
-
removeAllLinesContains('at new Error0')
|
|
438
|
-
removeAllLinesContains('at _toError0')
|
|
439
|
-
removeAllLinesContains('at Error0.from')
|
|
440
|
-
removeAllLinesContains('at Error0._toError0')
|
|
441
|
-
return lines.join('\n')
|
|
442
|
-
}
|
|
443
488
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
return
|
|
489
|
+
return causes
|
|
490
|
+
}
|
|
491
|
+
causes(policy: ErrorFlowPolicy = 'all'): object[] {
|
|
492
|
+
const ctor = this.constructor as typeof Error0
|
|
493
|
+
return ctor.causes(this, policy)
|
|
449
494
|
}
|
|
450
495
|
|
|
451
|
-
|
|
496
|
+
static is(error: unknown): error is Error0 {
|
|
497
|
+
return error instanceof this
|
|
498
|
+
}
|
|
452
499
|
|
|
453
500
|
static isError0(error: unknown): error is Error0 {
|
|
454
501
|
return error instanceof Error0
|
|
455
502
|
}
|
|
456
503
|
|
|
457
|
-
static
|
|
458
|
-
|
|
459
|
-
|
|
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
|
+
)
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
static from(error: unknown): Error0 {
|
|
512
|
+
if (this.is(error)) {
|
|
513
|
+
return error
|
|
460
514
|
}
|
|
515
|
+
if (this.isLikeError0(error)) {
|
|
516
|
+
return this._fromLikeError0(error)
|
|
517
|
+
}
|
|
518
|
+
return this._fromNonError0(error)
|
|
519
|
+
}
|
|
461
520
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
521
|
+
private static _applyRefine(error: Error0): Error0 {
|
|
522
|
+
const extension = this._getResolvedExtension()
|
|
523
|
+
for (const refine of extension.refine) {
|
|
524
|
+
const refined = refine(error as any)
|
|
525
|
+
if (refined && typeof refined === 'object') {
|
|
526
|
+
Object.assign(error as unknown as Record<string, unknown>, refined)
|
|
465
527
|
}
|
|
466
528
|
}
|
|
467
|
-
|
|
468
|
-
return false
|
|
529
|
+
return error
|
|
469
530
|
}
|
|
470
531
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
532
|
+
private static _fromLikeError0(error: unknown): Error0 {
|
|
533
|
+
const message = this._extractMessage(error)
|
|
534
|
+
if (typeof error !== 'object' || error === null) {
|
|
535
|
+
return this._applyRefine(new this(message, { cause: error }))
|
|
474
536
|
}
|
|
475
537
|
|
|
476
|
-
|
|
477
|
-
|
|
538
|
+
const errorRecord = error as Record<string, unknown>
|
|
539
|
+
const recreated = new this(message)
|
|
540
|
+
const temp = new this(message, { cause: errorRecord })
|
|
541
|
+
const extension = this._getResolvedExtension()
|
|
542
|
+
for (const [key, prop] of Object.entries(extension.props)) {
|
|
543
|
+
const value = prop.output(temp)
|
|
544
|
+
if (value !== undefined) {
|
|
545
|
+
;(recreated as unknown as Record<string, unknown>)[key] = value
|
|
546
|
+
}
|
|
478
547
|
}
|
|
548
|
+
;(recreated as unknown as { cause?: unknown }).cause = errorRecord.cause
|
|
549
|
+
if (typeof errorRecord.stack === 'string') {
|
|
550
|
+
recreated.stack = errorRecord.stack
|
|
551
|
+
}
|
|
552
|
+
return this._applyRefine(recreated)
|
|
553
|
+
}
|
|
479
554
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
555
|
+
private static _fromNonError0(error: unknown): Error0 {
|
|
556
|
+
const message = this._extractMessage(error)
|
|
557
|
+
return this._applyRefine(new this(message, { cause: error }))
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
private static _extractMessage(error: unknown): string {
|
|
561
|
+
return (
|
|
562
|
+
(typeof error === 'string'
|
|
563
|
+
? error
|
|
564
|
+
: typeof error === 'object' && error !== null && 'message' in error && typeof error.message === 'string'
|
|
565
|
+
? error.message
|
|
566
|
+
: undefined) || 'Unknown error'
|
|
567
|
+
)
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
private static _extendWithExtension(
|
|
571
|
+
this: typeof Error0,
|
|
572
|
+
extension: ErrorExtension<ErrorExtensionProps, ErrorExtensionComputed, ErrorExtensionMethods>,
|
|
573
|
+
): ClassError0 {
|
|
574
|
+
const Base = this as unknown as typeof Error0
|
|
575
|
+
const Error0Extended = class Error0 extends Base {}
|
|
576
|
+
;(Error0Extended as typeof Error0)._extensions = [...Base._extensions, extension]
|
|
577
|
+
|
|
578
|
+
const resolved = (Error0Extended as typeof Error0)._getResolvedExtension()
|
|
579
|
+
for (const [key, method] of Object.entries(resolved.methods)) {
|
|
580
|
+
Object.defineProperty((Error0Extended as typeof Error0).prototype, key, {
|
|
581
|
+
value: function (...args: unknown[]) {
|
|
582
|
+
return method(this as Error0, ...args)
|
|
583
|
+
},
|
|
584
|
+
writable: true,
|
|
585
|
+
enumerable: true,
|
|
586
|
+
configurable: true,
|
|
587
|
+
})
|
|
588
|
+
Object.defineProperty(Error0Extended, key, {
|
|
589
|
+
value: function (error: unknown, ...args: unknown[]) {
|
|
590
|
+
return method(this.from(error), ...args)
|
|
591
|
+
},
|
|
592
|
+
writable: true,
|
|
593
|
+
enumerable: true,
|
|
594
|
+
configurable: true,
|
|
484
595
|
})
|
|
485
596
|
}
|
|
486
597
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
598
|
+
return Error0Extended as unknown as ClassError0
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
private static _extensionFromBuilder(
|
|
602
|
+
extension: ExtensionError0,
|
|
603
|
+
): ErrorExtension<ErrorExtensionProps, ErrorExtensionComputed, ErrorExtensionMethods> {
|
|
604
|
+
const extensionRecord = extension as unknown as {
|
|
605
|
+
_extension: ErrorExtension<ErrorExtensionProps, ErrorExtensionComputed, ErrorExtensionMethods>
|
|
606
|
+
}
|
|
607
|
+
return {
|
|
608
|
+
props: { ...(extensionRecord._extension.props ?? {}) },
|
|
609
|
+
computed: { ...(extensionRecord._extension.computed ?? {}) },
|
|
610
|
+
methods: { ...(extensionRecord._extension.methods ?? {}) },
|
|
611
|
+
refine: [...(extensionRecord._extension.refine ?? [])],
|
|
492
612
|
}
|
|
613
|
+
}
|
|
493
614
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
615
|
+
static extend<TThis extends typeof Error0, TBuilder extends ExtensionError0>(
|
|
616
|
+
this: TThis,
|
|
617
|
+
extension: TBuilder,
|
|
618
|
+
): ClassError0<ExtendErrorExtensionsMap<ExtensionsMapOf<TThis>, ExtensionOfBuilder<TBuilder>>>
|
|
619
|
+
static extend<TThis extends typeof Error0, TKey extends string, TInputValue, TOutputValue>(
|
|
620
|
+
this: TThis,
|
|
621
|
+
kind: 'prop',
|
|
622
|
+
key: TKey,
|
|
623
|
+
value: ErrorExtensionPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<ExtensionsMapOf<TThis>>>,
|
|
624
|
+
): 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
|
+
static extend<TThis extends typeof Error0, TKey extends string, TArgs extends unknown[], TOutputValue>(
|
|
632
|
+
this: TThis,
|
|
633
|
+
kind: 'method',
|
|
634
|
+
key: TKey,
|
|
635
|
+
value: ErrorExtensionMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<ExtensionsMapOf<TThis>>>,
|
|
636
|
+
): ClassError0<ExtendErrorExtensionsMapWithMethod<ExtensionsMapOf<TThis>, TKey, TArgs, TOutputValue>>
|
|
637
|
+
static extend<TThis extends typeof Error0>(
|
|
638
|
+
this: TThis,
|
|
639
|
+
kind: 'refine',
|
|
640
|
+
value: ErrorExtensionRefineFn<ErrorInstanceOfMap<ExtensionsMapOf<TThis>>, ErrorOutputProps<ExtensionsMapOf<TThis>>>,
|
|
641
|
+
): ClassError0<ExtensionsMapOf<TThis>>
|
|
642
|
+
static extend(
|
|
643
|
+
this: typeof Error0,
|
|
644
|
+
first: ExtensionError0 | 'prop' | 'computed' | 'method' | 'refine',
|
|
645
|
+
key?: string | ErrorExtensionRefineFn<any, any>,
|
|
646
|
+
value?:
|
|
647
|
+
| ErrorExtensionPropOptions<unknown, unknown>
|
|
648
|
+
| ErrorExtensionCopmputedFn<unknown>
|
|
649
|
+
| ErrorExtensionMethodFn<unknown>,
|
|
650
|
+
): ClassError0 {
|
|
651
|
+
if (first instanceof ExtensionError0) {
|
|
652
|
+
return this._extendWithExtension(this._extensionFromBuilder(first))
|
|
653
|
+
}
|
|
654
|
+
if (first === 'refine') {
|
|
655
|
+
if (typeof key !== 'function') {
|
|
656
|
+
throw new Error('Error0.extend("refine", value) requires refine function')
|
|
498
657
|
}
|
|
658
|
+
return this._extendWithExtension({
|
|
659
|
+
refine: [key],
|
|
660
|
+
})
|
|
661
|
+
}
|
|
662
|
+
if (typeof key !== 'string' || value === undefined) {
|
|
663
|
+
throw new Error('Error0.extend(kind, key, value) requires key and value')
|
|
499
664
|
}
|
|
500
665
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
defaultCode?: Error0GeneralProps['code']
|
|
511
|
-
defaultHttpStatus?: Error0GeneralProps['httpStatus']
|
|
512
|
-
defaultExpected?: Error0GeneralProps['expected']
|
|
513
|
-
defaultClientMessage?: Error0GeneralProps['clientMessage']
|
|
514
|
-
defaultMeta?: Meta0.Meta0OrValueTypeNullish
|
|
515
|
-
}) {
|
|
516
|
-
const parent = this
|
|
517
|
-
return class Error0 extends parent {
|
|
518
|
-
static override defaultMessage = props.defaultMessage ?? parent.defaultMessage
|
|
519
|
-
static override defaultCode = props.defaultCode ?? parent.defaultCode
|
|
520
|
-
static override defaultHttpStatus = props.defaultHttpStatus ?? parent.defaultHttpStatus
|
|
521
|
-
static override defaultExpected = props.defaultExpected ?? parent.defaultExpected
|
|
522
|
-
static override defaultClientMessage = props.defaultClientMessage ?? parent.defaultClientMessage
|
|
523
|
-
static override defaultMeta = Meta0.extend(props.defaultMeta, parent.defaultMeta)
|
|
666
|
+
if (first === 'prop') {
|
|
667
|
+
return this._extendWithExtension({
|
|
668
|
+
props: { [key]: value as ErrorExtensionPropOptions<unknown, unknown> },
|
|
669
|
+
})
|
|
670
|
+
}
|
|
671
|
+
if (first === 'computed') {
|
|
672
|
+
return this._extendWithExtension({
|
|
673
|
+
computed: { [key]: value as ErrorExtensionCopmputedFn<unknown> },
|
|
674
|
+
})
|
|
524
675
|
}
|
|
676
|
+
return this._extendWithExtension({
|
|
677
|
+
methods: { [key]: value as ErrorExtensionMethodFn<unknown> },
|
|
678
|
+
})
|
|
525
679
|
}
|
|
526
680
|
|
|
527
|
-
static
|
|
528
|
-
|
|
529
|
-
props: {
|
|
530
|
-
defaultMessage?: Error0GeneralProps['message']
|
|
531
|
-
defaultCode?: Error0GeneralProps['code']
|
|
532
|
-
defaultHttpStatus?: Error0GeneralProps['httpStatus']
|
|
533
|
-
defaultExpected?: Error0GeneralProps['expected']
|
|
534
|
-
defaultClientMessage?: Error0GeneralProps['clientMessage']
|
|
535
|
-
defaultMeta?: Meta0.Meta0OrValueTypeNullish
|
|
536
|
-
},
|
|
537
|
-
): T {
|
|
538
|
-
return Object.fromEntries(Object.entries(classes).map(([name, Class]) => [name, Class.extend(props)])) as T
|
|
681
|
+
static extension(): ExtensionError0 {
|
|
682
|
+
return new ExtensionError0()
|
|
539
683
|
}
|
|
540
684
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
clientMessage: this.clientMessage,
|
|
549
|
-
anyMessage: this.anyMessage,
|
|
550
|
-
cause: this.cause,
|
|
551
|
-
meta: Meta0.getValue(this.meta),
|
|
552
|
-
stack: this.stack,
|
|
553
|
-
__I_AM_ERROR_0: this.__I_AM_ERROR_0,
|
|
685
|
+
static serialize(error: unknown, isPublic = true): object {
|
|
686
|
+
const error0 = this.from(error)
|
|
687
|
+
const jsonWithUndefined: Record<string, unknown> = {
|
|
688
|
+
name: error0.name,
|
|
689
|
+
message: error0.message,
|
|
690
|
+
cause: error0.cause,
|
|
691
|
+
stack: error0.stack,
|
|
554
692
|
}
|
|
693
|
+
|
|
694
|
+
const extension = this._getResolvedExtension()
|
|
695
|
+
for (const [key, prop] of Object.entries(extension.props)) {
|
|
696
|
+
const value = prop.output(error0)
|
|
697
|
+
const jsonValue = prop.serialize(value, error0, isPublic)
|
|
698
|
+
if (jsonValue !== undefined) {
|
|
699
|
+
jsonWithUndefined[key] = jsonValue
|
|
700
|
+
} else {
|
|
701
|
+
try {
|
|
702
|
+
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
703
|
+
delete jsonWithUndefined[key]
|
|
704
|
+
} catch {
|
|
705
|
+
// ignore
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
return Object.fromEntries(Object.entries(jsonWithUndefined).filter(([, value]) => value !== undefined)) as object
|
|
555
710
|
}
|
|
556
|
-
static toJSON(error: unknown, inputOverride?: Error0Input) {
|
|
557
|
-
const error0 = this.from(error, inputOverride)
|
|
558
|
-
return error0.toJSON()
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
toResponse(data?: Record<string, unknown>) {
|
|
562
|
-
return Response.json(
|
|
563
|
-
{
|
|
564
|
-
...this.toJSON(),
|
|
565
|
-
...data,
|
|
566
|
-
},
|
|
567
|
-
{
|
|
568
|
-
status: this.httpStatus,
|
|
569
|
-
statusText: this.message,
|
|
570
|
-
},
|
|
571
|
-
)
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
711
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
712
|
+
serialize(isPublic = true): object {
|
|
713
|
+
const ctor = this.constructor as typeof Error0
|
|
714
|
+
return ctor.serialize(this, isPublic)
|
|
715
|
+
}
|
|
578
716
|
}
|
|
579
|
-
|
|
580
|
-
export const e0s = {
|
|
581
|
-
Default: Error0,
|
|
582
|
-
Expected: Error0.extend({
|
|
583
|
-
defaultExpected: true,
|
|
584
|
-
}) as typeof Error0,
|
|
585
|
-
} satisfies Error0.Collection
|