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