@devp0nt/error0 1.0.0-next.5 → 1.0.0-next.50

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.
Files changed (75) hide show
  1. package/dist/cjs/index.cjs +614 -0
  2. package/dist/cjs/index.cjs.map +1 -0
  3. package/dist/cjs/index.d.cts +336 -414
  4. package/dist/cjs/plugins/cause-serialize.cjs +41 -0
  5. package/dist/cjs/plugins/cause-serialize.cjs.map +1 -0
  6. package/dist/cjs/plugins/cause-serialize.d.cts +7 -0
  7. package/dist/cjs/plugins/code.cjs +38 -0
  8. package/dist/cjs/plugins/code.cjs.map +1 -0
  9. package/dist/cjs/plugins/code.d.cts +7 -0
  10. package/dist/cjs/plugins/expected.cjs +54 -0
  11. package/dist/cjs/plugins/expected.cjs.map +1 -0
  12. package/dist/cjs/plugins/expected.d.cts +36 -0
  13. package/dist/cjs/plugins/message-merge.cjs +39 -0
  14. package/dist/cjs/plugins/message-merge.cjs.map +1 -0
  15. package/dist/cjs/plugins/message-merge.d.cts +8 -0
  16. package/dist/cjs/plugins/meta.cjs +78 -0
  17. package/dist/cjs/plugins/meta.cjs.map +1 -0
  18. package/dist/cjs/plugins/meta.d.cts +7 -0
  19. package/dist/cjs/plugins/stack-merge.cjs +42 -0
  20. package/dist/cjs/plugins/stack-merge.cjs.map +1 -0
  21. package/dist/cjs/plugins/stack-merge.d.cts +8 -0
  22. package/dist/cjs/plugins/status.cjs +54 -0
  23. package/dist/cjs/plugins/status.cjs.map +1 -0
  24. package/dist/cjs/plugins/status.d.cts +8 -0
  25. package/dist/cjs/plugins/tags.cjs +73 -0
  26. package/dist/cjs/plugins/tags.cjs.map +1 -0
  27. package/dist/cjs/plugins/tags.d.cts +12 -0
  28. package/dist/esm/index.d.ts +336 -414
  29. package/dist/esm/index.js +530 -341
  30. package/dist/esm/index.js.map +1 -1
  31. package/dist/esm/plugins/cause-serialize.d.ts +7 -0
  32. package/dist/esm/plugins/cause-serialize.js +17 -0
  33. package/dist/esm/plugins/cause-serialize.js.map +1 -0
  34. package/dist/esm/plugins/code.d.ts +7 -0
  35. package/dist/esm/plugins/code.js +14 -0
  36. package/dist/esm/plugins/code.js.map +1 -0
  37. package/dist/esm/plugins/expected.d.ts +36 -0
  38. package/dist/esm/plugins/expected.js +30 -0
  39. package/dist/esm/plugins/expected.js.map +1 -0
  40. package/dist/esm/plugins/message-merge.d.ts +8 -0
  41. package/dist/esm/plugins/message-merge.js +15 -0
  42. package/dist/esm/plugins/message-merge.js.map +1 -0
  43. package/dist/esm/plugins/meta.d.ts +7 -0
  44. package/dist/esm/plugins/meta.js +54 -0
  45. package/dist/esm/plugins/meta.js.map +1 -0
  46. package/dist/esm/plugins/stack-merge.d.ts +8 -0
  47. package/dist/esm/plugins/stack-merge.js +18 -0
  48. package/dist/esm/plugins/stack-merge.js.map +1 -0
  49. package/dist/esm/plugins/status.d.ts +8 -0
  50. package/dist/esm/plugins/status.js +30 -0
  51. package/dist/esm/plugins/status.js.map +1 -0
  52. package/dist/esm/plugins/tags.d.ts +12 -0
  53. package/dist/esm/plugins/tags.js +49 -0
  54. package/dist/esm/plugins/tags.js.map +1 -0
  55. package/package.json +53 -23
  56. package/src/index.test.ts +689 -452
  57. package/src/index.ts +1163 -502
  58. package/src/plugins/cause-serialize.test.ts +53 -0
  59. package/src/plugins/cause-serialize.ts +15 -0
  60. package/src/plugins/code.test.ts +27 -0
  61. package/src/plugins/code.ts +12 -0
  62. package/src/plugins/expected.test.ts +47 -0
  63. package/src/plugins/expected.ts +31 -0
  64. package/src/plugins/message-merge.test.ts +32 -0
  65. package/src/plugins/message-merge.ts +19 -0
  66. package/src/plugins/meta.test.ts +32 -0
  67. package/src/plugins/meta.ts +59 -0
  68. package/src/plugins/stack-merge.test.ts +64 -0
  69. package/src/plugins/stack-merge.ts +20 -0
  70. package/src/plugins/status.test.ts +54 -0
  71. package/src/plugins/status.ts +29 -0
  72. package/src/plugins/tags.test.ts +74 -0
  73. package/src/plugins/tags.ts +51 -0
  74. package/dist/cjs/index.js +0 -435
  75. package/dist/cjs/index.js.map +0 -1
package/dist/esm/index.js CHANGED
@@ -1,400 +1,589 @@
1
- import { Meta0 } from "@devp0nt/meta0";
2
- import { HttpStatusCode, isAxiosError } from "axios";
3
- import get from "lodash/get.js";
4
- import { ZodError } from "zod";
5
- const isFilled = (value) => value !== null && value !== void 0 && value !== "";
6
- class Error0 extends Error {
7
- __I_AM_ERROR_0 = true;
8
- tag;
9
- code;
10
- httpStatus;
11
- expected;
12
- clientMessage;
13
- anyMessage;
14
- cause;
15
- meta;
16
- zodError;
17
- axiosError;
18
- static defaultMessage = "Unknown error";
19
- static defaultCode;
20
- static defaultHttpStatus;
21
- static defaultExpected;
22
- static defaultClientMessage;
23
- static defaultMeta;
24
- propsOriginal;
25
- constructor(...args) {
26
- const input = {};
27
- if (args[0] instanceof Error) {
28
- input.cause = args[0];
29
- } else if (typeof args[0] === "object" && args[0] !== null) {
30
- Object.assign(input, args[0]);
31
- } else if (typeof args[0] === "string") {
32
- input.message = args[0];
33
- }
34
- if (typeof args[1] === "object" && args[1] !== null) {
35
- Object.assign(input, args[1]);
36
- }
37
- const safeInput = Error0._safeParseInput(input);
38
- const message = safeInput.message || Error0.defaultMessage;
39
- super(message);
40
- Object.setPrototypeOf(this, this.constructor.prototype);
41
- this.name = "Error0";
42
- this.propsOriginal = this.constructor._getSelfGeneralProps({
43
- error0Input: safeInput,
44
- message,
45
- stack: safeInput.stack || this.stack
46
- });
47
- const causesProps = this.constructor._getCausesPropsFromError0Props(
48
- this.propsOriginal,
49
- this.constructor.defaultMaxLevel
50
- );
51
- const propsFloated = this.constructor._getSelfPropsFloated(causesProps);
52
- this.tag = propsFloated.tag;
53
- this.code = propsFloated.code;
54
- this.httpStatus = propsFloated.httpStatus;
55
- this.expected = propsFloated.expected;
56
- this.clientMessage = propsFloated.clientMessage;
57
- this.cause = propsFloated.cause;
58
- this.stack = propsFloated.stack;
59
- this.meta = propsFloated.meta;
60
- this.zodError = propsFloated.zodError;
61
- this.axiosError = propsFloated.axiosError;
62
- }
63
- // settings
64
- static defaultMaxLevel = 10;
65
- // props
66
- static _safeParseInput(error0Input) {
67
- const result = {};
68
- result.message = typeof error0Input.message === "string" ? error0Input.message : void 0;
69
- result.tag = typeof error0Input.tag === "string" ? error0Input.tag : void 0;
70
- result.code = typeof error0Input.code === "string" ? error0Input.code : void 0;
71
- result.httpStatus = typeof error0Input.httpStatus === "number" || typeof error0Input.httpStatus === "string" ? error0Input.httpStatus : void 0;
72
- result.expected = typeof error0Input.expected === "function" || typeof error0Input.expected === "boolean" ? error0Input.expected : void 0;
73
- result.clientMessage = typeof error0Input.clientMessage === "string" ? error0Input.clientMessage : void 0;
74
- result.cause = error0Input.cause;
75
- result.stack = typeof error0Input.stack === "string" ? error0Input.stack : void 0;
76
- result.meta = error0Input.meta instanceof Meta0 ? error0Input.meta : typeof error0Input.meta === "object" && error0Input.meta !== null ? error0Input.meta : void 0;
77
- result.zodError = error0Input.zodError instanceof ZodError ? error0Input.zodError : void 0;
78
- result.axiosError = isAxiosError(error0Input.axiosError) ? error0Input.axiosError : void 0;
79
- return result;
80
- }
81
- static _getSelfGeneralProps({
82
- error0Input,
83
- message,
84
- stack
85
- }) {
86
- const meta0 = Meta0.extend(error0Input.meta, this.defaultMeta);
87
- const meta = meta0.getValue();
88
- const finalTag = meta0.getFinalTag(error0Input.tag);
89
- const clientMessage = error0Input.clientMessage || this.defaultClientMessage;
90
- const result = {
91
- message: error0Input.message || this.defaultMessage,
92
- tag: finalTag,
93
- code: error0Input.code || meta.code || this.defaultCode,
94
- httpStatus: typeof error0Input.httpStatus === "number" ? error0Input.httpStatus : error0Input.httpStatus && typeof error0Input.httpStatus === "string" && error0Input.httpStatus in HttpStatusCode ? HttpStatusCode[error0Input.httpStatus] : meta.httpStatus || this.defaultHttpStatus,
95
- expected: void 0,
96
- clientMessage,
97
- anyMessage: clientMessage || message,
98
- cause: error0Input.cause,
99
- stack: void 0,
100
- meta,
101
- zodError: error0Input.zodError,
102
- axiosError: error0Input.axiosError
1
+ const RESERVED_STACK_PROP_ERROR = 'Error0: "stack" is a reserved prop key. Use .stack(...) plugin API instead';
2
+ const RESERVED_MESSAGE_PROP_ERROR = 'Error0: "message" is a reserved prop key. Use .message(...) plugin API instead';
3
+ class PluginError0 {
4
+ _plugin;
5
+ Infer = void 0;
6
+ constructor(plugin) {
7
+ this._plugin = {
8
+ props: { ...plugin?.props ?? {} },
9
+ methods: { ...plugin?.methods ?? {} },
10
+ adapt: [...plugin?.adapt ?? []],
11
+ stack: plugin?.stack,
12
+ cause: plugin?.cause,
13
+ message: plugin?.message
103
14
  };
104
- result.expected = this._normalizeSelfExpected(
105
- result,
106
- typeof error0Input.expected === "boolean" || typeof error0Input.expected === "function" ? error0Input.expected : meta.expected || this.defaultExpected
107
- );
108
- result.stack = this._removeConstructorStackPart(stack);
109
- return result;
110
- }
111
- static _getSelfPropsFloated(causesProps) {
112
- const cause = this._getClosestPropValue(causesProps, "cause");
113
- const stack = this._mergeStack(causesProps[1]?.stack, causesProps[0]?.stack);
114
- const closestTag = this._getClosestPropValue(causesProps, "tag");
115
- const meta = this._getMergedMetaValue(causesProps);
116
- const tag = Meta0.getFinalTag(meta, closestTag);
117
- const propsFloated = {
118
- message: this._getClosestPropValue(causesProps, "message"),
119
- tag,
120
- code: this._getClosestPropValue(causesProps, "code"),
121
- httpStatus: this._getClosestPropValue(causesProps, "httpStatus"),
122
- expected: this._isExpected(causesProps),
123
- clientMessage: this._getClosestPropValue(causesProps, "clientMessage"),
124
- cause,
125
- stack,
126
- anyMessage: causesProps[0].anyMessage,
127
- meta,
128
- zodError: this._getClosestPropValue(causesProps, "zodError"),
129
- axiosError: this._getClosestPropValue(causesProps, "axiosError")
130
- };
131
- return propsFloated;
132
15
  }
133
- // sepcial
134
- static _getExtraError0PropsByZodError(zodError) {
135
- return {
136
- message: `Zod Validation Error: ${zodError.message}`
137
- };
16
+ prop(key, value) {
17
+ return this.use("prop", key, value);
138
18
  }
139
- static _getExtraError0PropsByAxiosError(axiosError) {
140
- return {
141
- message: "Axios Error",
142
- meta: {
143
- axiosData: (() => {
144
- try {
145
- return JSON.stringify(axiosError.response?.data);
146
- } catch {
147
- return void 0;
148
- }
149
- })(),
150
- axiosStatus: axiosError.response?.status
151
- }
152
- };
19
+ method(key, value) {
20
+ return this.use("method", key, value);
153
21
  }
154
- static _assignError0Props(error0Props, extraError0Props) {
155
- const metaValue = Meta0.mergeValues(error0Props.meta, extraError0Props.meta);
156
- Object.assign(error0Props, extraError0Props, { meta: metaValue });
22
+ adapt(value) {
23
+ return this.use("adapt", value);
157
24
  }
158
- // expected
159
- static _normalizeSelfExpected(error0Props, expectedProvided) {
160
- if (typeof expectedProvided === "function") {
161
- return expectedProvided(error0Props);
162
- }
163
- return expectedProvided;
25
+ stack(value) {
26
+ return this.use("stack", value);
164
27
  }
165
- static _isExpected(causesProps) {
166
- let hasExpectedTrue = false;
167
- for (const causeProps of causesProps) {
168
- if (causeProps.expected === false) {
169
- return false;
28
+ cause(value) {
29
+ return this.use("cause", value);
30
+ }
31
+ message(value) {
32
+ return this.use("message", value);
33
+ }
34
+ use(kind, keyOrValue, value) {
35
+ const nextProps = { ...this._plugin.props ?? {} };
36
+ const nextMethods = { ...this._plugin.methods ?? {} };
37
+ const nextAdapt = [...this._plugin.adapt ?? []];
38
+ let nextStack = this._plugin.stack;
39
+ let nextCause = this._plugin.cause;
40
+ let nextMessage = this._plugin.message;
41
+ if (kind === "prop") {
42
+ const key = keyOrValue;
43
+ if (key === "stack") {
44
+ throw new Error(RESERVED_STACK_PROP_ERROR);
45
+ }
46
+ if (key === "message") {
47
+ throw new Error(RESERVED_MESSAGE_PROP_ERROR);
170
48
  }
171
- if (causeProps.expected === true) {
172
- hasExpectedTrue = true;
49
+ if (value === void 0) {
50
+ throw new Error('PluginError0.use("prop", key, value) requires value');
173
51
  }
52
+ nextProps[key] = value;
53
+ } else if (kind === "method") {
54
+ const key = keyOrValue;
55
+ if (value === void 0) {
56
+ throw new Error('PluginError0.use("method", key, value) requires value');
57
+ }
58
+ nextMethods[key] = value;
59
+ } else if (kind === "adapt") {
60
+ nextAdapt.push(keyOrValue);
61
+ } else if (kind === "stack") {
62
+ nextStack = keyOrValue;
63
+ } else if (kind === "cause") {
64
+ nextCause = keyOrValue;
65
+ } else {
66
+ nextMessage = keyOrValue;
174
67
  }
175
- return hasExpectedTrue;
68
+ return new PluginError0({
69
+ props: nextProps,
70
+ methods: nextMethods,
71
+ adapt: nextAdapt,
72
+ stack: nextStack,
73
+ cause: nextCause,
74
+ message: nextMessage
75
+ });
176
76
  }
177
- // getters
178
- static _getPropsFromUnknown(error, defaults) {
179
- if (typeof error !== "object" || error === null) {
180
- return {
181
- message: void 0,
182
- tag: void 0,
183
- code: void 0,
184
- httpStatus: void 0,
185
- expected: void 0,
186
- clientMessage: void 0,
187
- anyMessage: this.defaultMessage,
188
- cause: void 0,
189
- stack: void 0,
190
- zodError: void 0,
191
- axiosError: void 0,
192
- meta: {}
193
- };
194
- }
195
- const message = "message" in error && typeof error.message === "string" ? error.message : void 0;
196
- const clientMessage = "clientMessage" in error && typeof error.clientMessage === "string" ? error.clientMessage : defaults?.clientMessage || void 0;
197
- const result = {
198
- message,
199
- code: "code" in error && typeof error.code === "string" ? error.code : defaults?.code || void 0,
200
- clientMessage,
201
- anyMessage: clientMessage || message || this.defaultMessage,
202
- expected: void 0,
203
- stack: "stack" in error && typeof error.stack === "string" ? error.stack : void 0,
204
- tag: "tag" in error && typeof error.tag === "string" ? error.tag : defaults?.tag || void 0,
205
- cause: "cause" in error ? error.cause : defaults?.cause || void 0,
206
- meta: "meta" in error && typeof error.meta === "object" && error.meta !== null ? Meta0.getValue(error.meta) : Meta0.getValue(defaults?.meta) || {},
207
- httpStatus: "httpStatus" in error && typeof error.httpStatus === "number" && error.httpStatus in HttpStatusCode ? error.httpStatus : typeof defaults?.httpStatus === "string" ? HttpStatusCode[defaults.httpStatus] : defaults?.httpStatus,
208
- zodError: "zodError" in error && error.zodError instanceof ZodError ? error.zodError : error instanceof ZodError ? error : defaults?.zodError,
209
- axiosError: "axiosError" in error && isAxiosError(error.axiosError) ? error.axiosError : isAxiosError(error) ? error : defaults?.axiosError
77
+ }
78
+ const OWN_SYMBOL = Symbol("Error0.own");
79
+ class Error0 extends Error {
80
+ static __pluginsMap;
81
+ __pluginsMap;
82
+ static MAX_CAUSES_DEPTH = 99;
83
+ static _plugins = [];
84
+ static _resolvedPlugin;
85
+ static _emptyPlugin = {
86
+ props: {},
87
+ methods: {},
88
+ adapt: [],
89
+ stack: void 0,
90
+ cause: void 0,
91
+ message: void 0,
92
+ propKeys: [],
93
+ propEntries: [],
94
+ methodEntries: []
95
+ };
96
+ static _indexResolvedPlugin(resolved) {
97
+ return {
98
+ ...resolved,
99
+ propKeys: Object.keys(resolved.props),
100
+ propEntries: Object.entries(resolved.props),
101
+ methodEntries: Object.entries(resolved.methods)
210
102
  };
211
- result.expected = this._normalizeSelfExpected(
212
- result,
213
- "expected" in error && (typeof error.expected === "boolean" || typeof error.expected === "function") ? error.expected : defaults?.expected || void 0
214
- );
215
- if (result.zodError) {
216
- this._assignError0Props(result, this._getExtraError0PropsByZodError(result.zodError));
103
+ }
104
+ static _applyPlugin(resolved, plugin) {
105
+ if (plugin.props && "stack" in plugin.props) {
106
+ throw new Error(RESERVED_STACK_PROP_ERROR);
217
107
  }
218
- if (result.axiosError) {
219
- this._assignError0Props(result, this._getExtraError0PropsByAxiosError(result.axiosError));
108
+ if (plugin.props && "message" in plugin.props) {
109
+ throw new Error(RESERVED_MESSAGE_PROP_ERROR);
220
110
  }
221
- return result;
222
- }
223
- static _getCausesPropsFromUnknown(error, maxLevel) {
224
- if (!error) {
225
- return [];
111
+ Object.assign(resolved.props, plugin.props ?? this._emptyPlugin.props);
112
+ Object.assign(resolved.methods, plugin.methods ?? this._emptyPlugin.methods);
113
+ resolved.adapt.push(...plugin.adapt ?? this._emptyPlugin.adapt);
114
+ if (typeof plugin.stack !== "undefined") {
115
+ resolved.stack = plugin.stack;
226
116
  }
227
- const causeProps = this._getPropsFromUnknown(error);
228
- const causesProps = [causeProps];
229
- if (!causeProps.cause) {
230
- return causesProps;
117
+ if (typeof plugin.cause !== "undefined") {
118
+ resolved.cause = plugin.cause;
231
119
  }
232
- if (maxLevel > 0) {
233
- causesProps.push(...this._getCausesPropsFromUnknown(this._getPropsFromUnknown(causeProps.cause), maxLevel - 1));
120
+ if (typeof plugin.message !== "undefined") {
121
+ resolved.message = plugin.message;
234
122
  }
235
- return causesProps;
236
123
  }
237
- static _getCausesPropsFromError0Props(error0Props, maxLevel) {
238
- return [error0Props, ...this._getCausesPropsFromUnknown(error0Props.cause, maxLevel - 1)];
124
+ static _mergeResolvedPlugin(base, plugin) {
125
+ const merged = {
126
+ props: { ...base.props },
127
+ methods: { ...base.methods },
128
+ adapt: [...base.adapt],
129
+ stack: base.stack,
130
+ cause: base.cause,
131
+ message: base.message
132
+ };
133
+ this._applyPlugin(merged, plugin);
134
+ return this._indexResolvedPlugin(merged);
135
+ }
136
+ static _getResolvedPlugin() {
137
+ if (Object.prototype.hasOwnProperty.call(this, "_resolvedPlugin") && this._resolvedPlugin) {
138
+ return this._resolvedPlugin;
139
+ }
140
+ const resolved = {
141
+ props: {},
142
+ methods: {},
143
+ adapt: [],
144
+ propKeys: [],
145
+ propEntries: [],
146
+ methodEntries: []
147
+ };
148
+ for (const plugin of this._plugins) {
149
+ this._applyPlugin(resolved, plugin);
150
+ }
151
+ const indexed = this._indexResolvedPlugin(resolved);
152
+ Object.defineProperty(this, "_resolvedPlugin", {
153
+ value: indexed,
154
+ writable: true,
155
+ enumerable: false,
156
+ configurable: true
157
+ });
158
+ return indexed;
239
159
  }
240
- static _getClosestPropValue(causesProps, propKey) {
241
- for (const causeProps of causesProps) {
242
- const propValue = causeProps[propKey];
243
- if (isFilled(propValue)) {
244
- return propValue;
160
+ constructor(...args) {
161
+ const [first, second] = args;
162
+ const input = typeof first === "string" ? { message: first, ...second ?? {} } : first;
163
+ super(input.message, { cause: input.cause });
164
+ this.name = "Error0";
165
+ const ctor = this.constructor;
166
+ const plugin = ctor._getResolvedPlugin();
167
+ const ownStore = /* @__PURE__ */ Object.create(null);
168
+ Object.defineProperty(this, OWN_SYMBOL, { value: ownStore, writable: true, enumerable: false, configurable: true });
169
+ for (const [key, prop] of plugin.propEntries) {
170
+ if (key === "stack") {
171
+ continue;
172
+ }
173
+ Object.defineProperty(this, key, {
174
+ get: () => prop.resolve({
175
+ own: ownStore[key],
176
+ flow: this.flow(key),
177
+ error: this
178
+ }),
179
+ set: (value) => {
180
+ ownStore[key] = value;
181
+ },
182
+ enumerable: true,
183
+ configurable: true
184
+ });
185
+ if (key in input) {
186
+ const ownValue = input[key];
187
+ ownStore[key] = typeof prop.init === "function" ? prop.init(ownValue) : ownValue;
245
188
  }
246
189
  }
190
+ }
191
+ static _getOwnStore(object) {
192
+ const record = object;
193
+ const existing = record[OWN_SYMBOL];
194
+ if (existing && typeof existing === "object") {
195
+ return existing;
196
+ }
247
197
  return void 0;
248
198
  }
249
- // private static getClosestByGetter<TResult>(
250
- // causesProps: Error0GeneralProps[],
251
- // getter: (props: Error0GeneralProps) => TResult,
252
- // ): NonNullable<TResult> | undefined {
253
- // for (const causeProps of causesProps) {
254
- // const result = getter(causeProps)
255
- // if (isFilled(result)) {
256
- // return result
257
- // }
258
- // }
259
- // return undefined
260
- // }
261
- static _getFilledPropValues(causesProps, propKey) {
262
- const values = [];
263
- for (const causeProps of causesProps) {
264
- const propValue = causeProps[propKey];
265
- if (isFilled(propValue)) {
266
- values.push(propValue);
267
- }
199
+ static isOwnProperty = (object, key) => {
200
+ const ownStore = this._getOwnStore(object);
201
+ if (ownStore) {
202
+ return Object.prototype.hasOwnProperty.call(ownStore, key);
203
+ }
204
+ return !!Object.getOwnPropertyDescriptor(object, key);
205
+ };
206
+ static _ownByKey(error, key) {
207
+ const ownStore = this._getOwnStore(error);
208
+ if (ownStore) {
209
+ return ownStore[key];
210
+ }
211
+ return error[key];
212
+ }
213
+ static _flowByKey(error, key) {
214
+ const causes = this.causes(error, true);
215
+ const values = new Array(causes.length);
216
+ for (let i = 0; i < causes.length; i += 1) {
217
+ values[i] = this._ownByKey(causes[i], key);
268
218
  }
269
219
  return values;
270
220
  }
271
- static _getMergedMetaValue(causesProps) {
272
- const metas = this._getFilledPropValues(causesProps, "meta");
273
- if (metas.length === 0) {
274
- return {};
275
- } else if (metas.length === 1) {
276
- return metas[0];
277
- } else {
278
- return Meta0.mergeValues(metas[0], ...metas.slice(1));
221
+ static own(error, key) {
222
+ const error0 = this.from(error);
223
+ if (key === void 0) {
224
+ const ownValues = {};
225
+ const plugin = this._getResolvedPlugin();
226
+ for (const ownKey of plugin.propKeys) {
227
+ ownValues[ownKey] = this._ownByKey(error0, ownKey);
228
+ }
229
+ return ownValues;
279
230
  }
231
+ return this._ownByKey(error0, key);
280
232
  }
281
- // stack
282
- static _removeConstructorStackPart(stack) {
283
- if (!stack) {
284
- return stack;
233
+ own(key) {
234
+ const ctor = this.constructor;
235
+ if (key === void 0) {
236
+ return ctor.own(this);
285
237
  }
286
- let lines = stack.split("\n");
287
- const removeAllLinesContains = (search) => {
288
- lines = lines.filter((line) => !line.includes(search));
289
- };
290
- removeAllLinesContains("at new Error0");
291
- removeAllLinesContains("at _toError0");
292
- removeAllLinesContains("at Error0.from");
293
- removeAllLinesContains("at Error0._toError0");
294
- return lines.join("\n");
238
+ return ctor._ownByKey(this, key);
239
+ }
240
+ static flow(error, key) {
241
+ const error0 = this.from(error);
242
+ return this._flowByKey(error0, key);
295
243
  }
296
- static _mergeStack(prevStack, nextStack) {
297
- return [nextStack, prevStack].filter(Boolean).join("\n\n") || void 0;
244
+ flow(key) {
245
+ const ctor = this.constructor;
246
+ return ctor._flowByKey(this, key);
298
247
  }
299
- // transformations
300
- static isError0(error) {
301
- return error instanceof Error0;
248
+ static _resolveByKey(error, key, plugin) {
249
+ try {
250
+ const options = {
251
+ get own() {
252
+ return error.own(key);
253
+ },
254
+ get flow() {
255
+ return error.flow(key);
256
+ },
257
+ error
258
+ };
259
+ const prop = plugin.props[key];
260
+ const resolver = prop.resolve;
261
+ if (!resolver) {
262
+ return error[key];
263
+ }
264
+ return resolver(options);
265
+ } catch {
266
+ console.error(`Error0: failed to resolve property ${key}`, error);
267
+ return void 0;
268
+ }
302
269
  }
303
- static isLikelyError0(error) {
304
- if (error instanceof Error0) {
305
- return true;
270
+ static resolve(error) {
271
+ const error0 = this.from(error);
272
+ const resolved = {};
273
+ const plugin = this._getResolvedPlugin();
274
+ for (const key of plugin.propKeys) {
275
+ resolved[key] = this._resolveByKey(error0, key, plugin);
306
276
  }
307
- if (typeof error === "object" && error !== null) {
308
- if ("__I_AM_ERROR_0" in error && error.__I_AM_ERROR_0 === true) {
309
- return true;
277
+ return resolved;
278
+ }
279
+ resolve() {
280
+ const ctor = this.constructor;
281
+ return ctor.resolve(this);
282
+ }
283
+ static causes(error, instancesOnly) {
284
+ const causes = [];
285
+ let current = error;
286
+ const seen = /* @__PURE__ */ new Set();
287
+ let depth = 0;
288
+ while (depth < this.MAX_CAUSES_DEPTH) {
289
+ if (seen.has(current)) {
290
+ break;
291
+ }
292
+ seen.add(current);
293
+ if (!instancesOnly || this.is(current)) {
294
+ causes.push(current);
310
295
  }
296
+ if (!current || typeof current !== "object") {
297
+ break;
298
+ }
299
+ current = current.cause;
300
+ depth += 1;
301
+ }
302
+ return causes;
303
+ }
304
+ causes(instancesOnly) {
305
+ const ctor = this.constructor;
306
+ if (instancesOnly) {
307
+ return ctor.causes(this, true);
311
308
  }
312
- return false;
309
+ return ctor.causes(this);
313
310
  }
314
- static _toError0(error, inputOverride = {}) {
315
- if (error instanceof Error0) {
311
+ static is(error) {
312
+ return error instanceof this;
313
+ }
314
+ static isSerialized(error) {
315
+ return !this.is(error) && typeof error === "object" && error !== null && "name" in error && error.name === "Error0";
316
+ }
317
+ static from(error) {
318
+ if (this.is(error)) {
316
319
  return error;
317
320
  }
318
- if (typeof error === "string") {
319
- return new Error0(error, inputOverride);
321
+ if (this.isSerialized(error)) {
322
+ return this._fromSerialized(error);
320
323
  }
324
+ return this._fromNonError0(error);
325
+ }
326
+ static round(error, isPublic = false) {
327
+ return this.from(this.serialize(error, isPublic));
328
+ }
329
+ static _applyAdapt(error) {
330
+ const plugin = this._getResolvedPlugin();
331
+ for (const adapt of plugin.adapt) {
332
+ const adapted = adapt(error);
333
+ if (adapted && typeof adapted === "object") {
334
+ Object.assign(error, adapted);
335
+ }
336
+ }
337
+ return error;
338
+ }
339
+ static _fromSerialized(error) {
340
+ const message = this._extractMessage(error);
321
341
  if (typeof error !== "object" || error === null) {
322
- return new Error0({
323
- message: this.defaultMessage,
324
- ...inputOverride
325
- });
342
+ return this._applyAdapt(new this(message, { cause: error }));
326
343
  }
327
- const inputFromData = get(error, "data");
328
- if (inputFromData) {
329
- if (Error0.isLikelyError0(inputFromData)) {
330
- return this._toError0(inputFromData, inputOverride);
344
+ const errorRecord = error;
345
+ const recreated = new this(message);
346
+ const plugin = this._getResolvedPlugin();
347
+ for (const [key, prop] of plugin.propEntries) {
348
+ if (prop.deserialize === false) {
349
+ continue;
350
+ }
351
+ if (!(key in errorRecord)) {
352
+ continue;
353
+ }
354
+ try {
355
+ const value = prop.deserialize({ value: errorRecord[key], record: errorRecord });
356
+ recreated[key] = value;
357
+ } catch {
358
+ console.error(`Error0: failed to deserialize property ${key}`, errorRecord);
331
359
  }
332
360
  }
333
- const inputFromDataError0 = get(error, "data.error0");
334
- if (inputFromDataError0) {
335
- if (Error0.isLikelyError0(inputFromDataError0)) {
336
- return this._toError0(inputFromDataError0, inputOverride);
361
+ if ("stack" in errorRecord) {
362
+ try {
363
+ if (typeof errorRecord.stack === "string") {
364
+ recreated.stack = errorRecord.stack;
365
+ }
366
+ } catch {
367
+ console.error("Error0: failed to deserialize stack", errorRecord);
337
368
  }
338
369
  }
339
- return new Error0(this._getPropsFromUnknown(error, inputOverride));
370
+ const causePlugin = plugin.cause;
371
+ if (causePlugin?.serialize && "cause" in errorRecord) {
372
+ try {
373
+ if (this.isSerialized(errorRecord.cause)) {
374
+ ;
375
+ recreated.cause = this._fromSerialized(errorRecord.cause);
376
+ } else {
377
+ ;
378
+ recreated.cause = errorRecord.cause;
379
+ }
380
+ } catch {
381
+ console.error("Error0: failed to deserialize cause", errorRecord);
382
+ }
383
+ }
384
+ return recreated;
340
385
  }
341
- static from(error, inputOverride) {
342
- return this._toError0(error, inputOverride);
386
+ static _fromNonError0(error) {
387
+ const message = this._extractMessage(error);
388
+ return this._applyAdapt(new this(message, { cause: error }));
343
389
  }
344
- static extend(props) {
345
- const parent = this;
346
- return class Error0 extends parent {
347
- static defaultMessage = props.defaultMessage ?? parent.defaultMessage;
348
- static defaultCode = props.defaultCode ?? parent.defaultCode;
349
- static defaultHttpStatus = props.defaultHttpStatus ?? parent.defaultHttpStatus;
350
- static defaultExpected = props.defaultExpected ?? parent.defaultExpected;
351
- static defaultClientMessage = props.defaultClientMessage ?? parent.defaultClientMessage;
352
- static defaultMeta = Meta0.extend(props.defaultMeta, parent.defaultMeta);
353
- };
390
+ static _extractMessage(error) {
391
+ return (typeof error === "string" ? error : typeof error === "object" && error !== null && "message" in error && typeof error.message === "string" ? error.message : void 0) || "Unknown error";
354
392
  }
355
- static extendCollection(classes, props) {
356
- return Object.fromEntries(Object.entries(classes).map(([name, Class]) => [name, Class.extend(props)]));
393
+ static _useWithPlugin(plugin) {
394
+ const Base = this;
395
+ const Error0Extended = class Error0 extends Base {
396
+ };
397
+ Error0Extended._plugins = [...Base._plugins, plugin];
398
+ const resolved = this._mergeResolvedPlugin(Base._getResolvedPlugin(), plugin);
399
+ Error0Extended._resolvedPlugin = resolved;
400
+ for (const [key, method] of resolved.methodEntries) {
401
+ Object.defineProperty(Error0Extended.prototype, key, {
402
+ value: function(...args) {
403
+ return method(this, ...args);
404
+ },
405
+ writable: true,
406
+ enumerable: true,
407
+ configurable: true
408
+ });
409
+ Object.defineProperty(Error0Extended, key, {
410
+ value: function(error, ...args) {
411
+ return method(this.from(error), ...args);
412
+ },
413
+ writable: true,
414
+ enumerable: true,
415
+ configurable: true
416
+ });
417
+ }
418
+ return Error0Extended;
357
419
  }
358
- toJSON() {
420
+ static _pluginFromBuilder(plugin) {
421
+ const pluginRecord = plugin;
359
422
  return {
360
- message: this.message,
361
- tag: this.tag,
362
- code: this.code,
363
- httpStatus: this.httpStatus,
364
- expected: this.expected,
365
- clientMessage: this.clientMessage,
366
- anyMessage: this.anyMessage,
367
- cause: this.cause,
368
- meta: Meta0.getValue(this.meta),
369
- stack: this.stack,
370
- __I_AM_ERROR_0: this.__I_AM_ERROR_0
423
+ props: { ...pluginRecord._plugin.props ?? {} },
424
+ methods: { ...pluginRecord._plugin.methods ?? {} },
425
+ adapt: [...pluginRecord._plugin.adapt ?? []],
426
+ stack: pluginRecord._plugin.stack,
427
+ cause: pluginRecord._plugin.cause,
428
+ message: pluginRecord._plugin.message
371
429
  };
372
430
  }
373
- static toJSON(error, inputOverride) {
374
- const error0 = this.from(error, inputOverride);
375
- return error0.toJSON();
431
+ static use(first, key, value) {
432
+ if (first instanceof PluginError0) {
433
+ return this._useWithPlugin(this._pluginFromBuilder(first));
434
+ }
435
+ if (first === "stack") {
436
+ if (typeof key === "undefined") {
437
+ throw new Error('Error0.use("stack", value) requires stack plugin value');
438
+ }
439
+ if (typeof key !== "object" || key === null || typeof key.serialize !== "function") {
440
+ throw new Error('Error0.use("stack", value) expects { serialize: function }');
441
+ }
442
+ return this._useWithPlugin({
443
+ stack: key
444
+ });
445
+ }
446
+ if (first === "cause") {
447
+ if (typeof key === "undefined") {
448
+ throw new Error('Error0.use("cause", value) requires cause plugin value');
449
+ }
450
+ if (typeof key !== "object" || key === null || typeof key.serialize !== "function") {
451
+ throw new Error('Error0.use("cause", value) expects { serialize: function }');
452
+ }
453
+ return this._useWithPlugin({
454
+ cause: key
455
+ });
456
+ }
457
+ if (first === "message") {
458
+ if (typeof key === "undefined") {
459
+ throw new Error('Error0.use("message", value) requires message plugin value');
460
+ }
461
+ if (typeof key !== "object" || key === null || typeof key.serialize !== "function") {
462
+ throw new Error('Error0.use("message", value) expects { serialize: function }');
463
+ }
464
+ return this._useWithPlugin({
465
+ message: key
466
+ });
467
+ }
468
+ if (first === "adapt") {
469
+ if (typeof key !== "function") {
470
+ throw new Error('Error0.use("adapt", value) requires adapt function');
471
+ }
472
+ return this._useWithPlugin({
473
+ adapt: [key]
474
+ });
475
+ }
476
+ if (typeof key !== "string" || value === void 0) {
477
+ throw new Error("Error0.use(kind, key, value) requires key and value");
478
+ }
479
+ if (first === "prop") {
480
+ if (key === "stack") {
481
+ throw new Error(RESERVED_STACK_PROP_ERROR);
482
+ }
483
+ if (key === "message") {
484
+ throw new Error(RESERVED_MESSAGE_PROP_ERROR);
485
+ }
486
+ return this._useWithPlugin({
487
+ props: { [key]: value }
488
+ });
489
+ }
490
+ return this._useWithPlugin({
491
+ methods: { [key]: value }
492
+ });
493
+ }
494
+ static plugin() {
495
+ return new PluginError0();
376
496
  }
377
- toResponse(data) {
378
- return Response.json(
379
- {
380
- ...this.toJSON(),
381
- ...data
382
- },
383
- {
384
- status: this.httpStatus,
385
- statusText: this.message
497
+ static serialize(error, isPublic = true) {
498
+ const error0 = this.from(error);
499
+ const plugin = this._getResolvedPlugin();
500
+ const resolveByKey = (targetError, key, targetPlugin) => this._resolveByKey(targetError, key, targetPlugin);
501
+ const messagePlugin = plugin.message;
502
+ let serializedMessage = error0.message;
503
+ try {
504
+ if (messagePlugin) {
505
+ serializedMessage = messagePlugin.serialize({ value: error0.message, error: error0, isPublic });
386
506
  }
387
- );
507
+ } catch {
508
+ console.error("Error0: failed to serialize message", error0);
509
+ serializedMessage = error0.message;
510
+ }
511
+ const json = {
512
+ name: error0.name
513
+ // we do not serialize causes, it is enough that we have floated props and adapt helper
514
+ // cause: error0.cause,
515
+ };
516
+ if (serializedMessage !== void 0) {
517
+ json.message = serializedMessage;
518
+ }
519
+ for (const [key, prop] of plugin.propEntries) {
520
+ if (prop.serialize === false) {
521
+ continue;
522
+ }
523
+ try {
524
+ const options = {
525
+ get own() {
526
+ return error0.own(key);
527
+ },
528
+ get flow() {
529
+ return error0.flow(key);
530
+ },
531
+ get resolved() {
532
+ return resolveByKey(error0, key, plugin);
533
+ },
534
+ error: error0,
535
+ isPublic
536
+ };
537
+ const jsonValue = prop.serialize(options);
538
+ if (jsonValue !== void 0) {
539
+ json[key] = jsonValue;
540
+ }
541
+ } catch {
542
+ console.error(`Error0: failed to serialize property ${key}`, error0);
543
+ }
544
+ }
545
+ const stackPlugin = plugin.stack;
546
+ try {
547
+ let serializedStack;
548
+ if (stackPlugin) {
549
+ serializedStack = stackPlugin.serialize({ value: error0.stack, error: error0, isPublic });
550
+ } else {
551
+ serializedStack = error0.stack;
552
+ }
553
+ if (serializedStack !== void 0) {
554
+ json.stack = serializedStack;
555
+ }
556
+ } catch {
557
+ console.error("Error0: failed to serialize stack", error0);
558
+ }
559
+ const causePlugin = plugin.cause;
560
+ if (causePlugin?.serialize) {
561
+ try {
562
+ const serializedCause = causePlugin.serialize({
563
+ value: error0.cause,
564
+ error: error0,
565
+ isPublic
566
+ });
567
+ if (serializedCause !== void 0) {
568
+ json.cause = serializedCause;
569
+ }
570
+ } catch {
571
+ console.error("Error0: failed to serialize cause", error0);
572
+ }
573
+ }
574
+ return json;
575
+ }
576
+ serialize(isPublic = true) {
577
+ const ctor = this.constructor;
578
+ return ctor.serialize(this, isPublic);
579
+ }
580
+ round(isPublic = true) {
581
+ const ctor = this.constructor;
582
+ return ctor.round(this, isPublic);
388
583
  }
389
584
  }
390
- const e0s = {
391
- Default: Error0,
392
- Expected: Error0.extend({
393
- defaultExpected: true
394
- })
395
- };
396
585
  export {
397
586
  Error0,
398
- e0s
587
+ PluginError0
399
588
  };
400
589
  //# sourceMappingURL=index.js.map