@devp0nt/error0 1.0.0-next.47 → 1.0.0-next.49

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 (57) hide show
  1. package/dist/cjs/index.cjs +165 -85
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs/index.d.cts +47 -16
  4. package/dist/cjs/plugins/cause-serialize.cjs +4 -1
  5. package/dist/cjs/plugins/cause-serialize.cjs.map +1 -1
  6. package/dist/cjs/plugins/cause-serialize.d.cts +3 -1
  7. package/dist/cjs/plugins/expected.cjs +7 -2
  8. package/dist/cjs/plugins/expected.cjs.map +1 -1
  9. package/dist/cjs/plugins/expected.d.cts +3 -1
  10. package/dist/cjs/plugins/message-merge.cjs +5 -2
  11. package/dist/cjs/plugins/message-merge.cjs.map +1 -1
  12. package/dist/cjs/plugins/message-merge.d.cts +4 -1
  13. package/dist/cjs/plugins/meta.cjs +7 -2
  14. package/dist/cjs/plugins/meta.cjs.map +1 -1
  15. package/dist/cjs/plugins/meta.d.cts +3 -1
  16. package/dist/cjs/plugins/stack-merge.cjs +6 -3
  17. package/dist/cjs/plugins/stack-merge.cjs.map +1 -1
  18. package/dist/cjs/plugins/stack-merge.d.cts +4 -1
  19. package/dist/cjs/plugins/tags.cjs +7 -2
  20. package/dist/cjs/plugins/tags.cjs.map +1 -1
  21. package/dist/cjs/plugins/tags.d.cts +3 -1
  22. package/dist/esm/index.d.ts +47 -16
  23. package/dist/esm/index.js +165 -85
  24. package/dist/esm/index.js.map +1 -1
  25. package/dist/esm/plugins/cause-serialize.d.ts +3 -1
  26. package/dist/esm/plugins/cause-serialize.js +4 -1
  27. package/dist/esm/plugins/cause-serialize.js.map +1 -1
  28. package/dist/esm/plugins/expected.d.ts +3 -1
  29. package/dist/esm/plugins/expected.js +7 -2
  30. package/dist/esm/plugins/expected.js.map +1 -1
  31. package/dist/esm/plugins/message-merge.d.ts +4 -1
  32. package/dist/esm/plugins/message-merge.js +5 -2
  33. package/dist/esm/plugins/message-merge.js.map +1 -1
  34. package/dist/esm/plugins/meta.d.ts +3 -1
  35. package/dist/esm/plugins/meta.js +7 -2
  36. package/dist/esm/plugins/meta.js.map +1 -1
  37. package/dist/esm/plugins/stack-merge.d.ts +4 -1
  38. package/dist/esm/plugins/stack-merge.js +6 -3
  39. package/dist/esm/plugins/stack-merge.js.map +1 -1
  40. package/dist/esm/plugins/tags.d.ts +3 -1
  41. package/dist/esm/plugins/tags.js +7 -2
  42. package/dist/esm/plugins/tags.js.map +1 -1
  43. package/package.json +1 -1
  44. package/src/index.test.ts +96 -23
  45. package/src/index.ts +229 -101
  46. package/src/plugins/cause-serialize.test.ts +6 -4
  47. package/src/plugins/cause-serialize.ts +13 -9
  48. package/src/plugins/expected.test.ts +4 -4
  49. package/src/plugins/expected.ts +16 -10
  50. package/src/plugins/message-merge.test.ts +3 -3
  51. package/src/plugins/message-merge.ts +17 -13
  52. package/src/plugins/meta.test.ts +2 -2
  53. package/src/plugins/meta.ts +28 -22
  54. package/src/plugins/stack-merge.test.ts +4 -4
  55. package/src/plugins/stack-merge.ts +18 -14
  56. package/src/plugins/tags.test.ts +2 -2
  57. package/src/plugins/tags.ts +24 -18
@@ -22,14 +22,17 @@ __export(stack_merge_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(stack_merge_exports);
24
24
  var import__ = require('../index.cjs');
25
- const stackMergePlugin = import__.Error0.plugin().use("stack", {
25
+ const stackMergePlugin = ({
26
+ hideWhenPublic = true,
27
+ delimiter = "\n"
28
+ } = {}) => import__.Error0.plugin().use("stack", {
26
29
  serialize: ({ error, isPublic }) => {
27
- if (isPublic) {
30
+ if (hideWhenPublic && isPublic) {
28
31
  return void 0;
29
32
  }
30
33
  return error.causes().map((cause) => {
31
34
  return cause instanceof Error ? cause.stack : void 0;
32
- }).filter((value) => typeof value === "string").join("\n");
35
+ }).filter((value) => typeof value === "string").join(delimiter);
33
36
  }
34
37
  });
35
38
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/plugins/stack-merge.ts"],"sourcesContent":["import { Error0 } from '../index.js'\n\nexport const stackMergePlugin = Error0.plugin().use('stack', {\n serialize: ({ error, isPublic }) => {\n if (isPublic) {\n return undefined\n }\n return error\n .causes()\n .map((cause) => {\n return cause instanceof Error ? cause.stack : undefined\n })\n .filter((value): value is string => typeof value === 'string')\n .join('\\n')\n },\n})\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAAuB;AAEhB,MAAM,mBAAmB,gBAAO,OAAO,EAAE,IAAI,SAAS;AAAA,EAC3D,WAAW,CAAC,EAAE,OAAO,SAAS,MAAM;AAClC,QAAI,UAAU;AACZ,aAAO;AAAA,IACT;AACA,WAAO,MACJ,OAAO,EACP,IAAI,CAAC,UAAU;AACd,aAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,IAChD,CAAC,EACA,OAAO,CAAC,UAA2B,OAAO,UAAU,QAAQ,EAC5D,KAAK,IAAI;AAAA,EACd;AACF,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../../src/plugins/stack-merge.ts"],"sourcesContent":["import { Error0 } from '../index.js'\n\nexport const stackMergePlugin = ({\n hideWhenPublic = true,\n delimiter = '\\n',\n}: { hideWhenPublic?: boolean; delimiter?: string } = {}) =>\n Error0.plugin().use('stack', {\n serialize: ({ error, isPublic }) => {\n if (hideWhenPublic && isPublic) {\n return undefined\n }\n return error\n .causes()\n .map((cause) => {\n return cause instanceof Error ? cause.stack : undefined\n })\n .filter((value): value is string => typeof value === 'string')\n .join(delimiter)\n },\n })\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAAuB;AAEhB,MAAM,mBAAmB,CAAC;AAAA,EAC/B,iBAAiB;AAAA,EACjB,YAAY;AACd,IAAsD,CAAC,MACrD,gBAAO,OAAO,EAAE,IAAI,SAAS;AAAA,EAC3B,WAAW,CAAC,EAAE,OAAO,SAAS,MAAM;AAClC,QAAI,kBAAkB,UAAU;AAC9B,aAAO;AAAA,IACT;AACA,WAAO,MACJ,OAAO,EACP,IAAI,CAAC,UAAU;AACd,aAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,IAChD,CAAC,EACA,OAAO,CAAC,UAA2B,OAAO,UAAU,QAAQ,EAC5D,KAAK,SAAS;AAAA,EACnB;AACF,CAAC;","names":[]}
@@ -1,5 +1,8 @@
1
1
  import { PluginError0 } from '../index.cjs';
2
2
 
3
- declare const stackMergePlugin: PluginError0<Record<never, never>, Record<never, never>>;
3
+ declare const stackMergePlugin: ({ hideWhenPublic, delimiter, }?: {
4
+ hideWhenPublic?: boolean;
5
+ delimiter?: string;
6
+ }) => PluginError0<Record<never, never>, Record<never, never>>;
4
7
 
5
8
  export { stackMergePlugin };
@@ -22,7 +22,7 @@ __export(tags_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(tags_exports);
24
24
  var import__ = require('../index.cjs');
25
- const tagsPlugin = import__.Error0.plugin().use("prop", "tags", {
25
+ const tagsPlugin = ({ hideWhenPublic = true } = {}) => import__.Error0.plugin().use("prop", "tags", {
26
26
  init: (input) => input,
27
27
  resolve: ({ flow }) => {
28
28
  const merged = [];
@@ -33,7 +33,12 @@ const tagsPlugin = import__.Error0.plugin().use("prop", "tags", {
33
33
  }
34
34
  return merged.length > 0 ? Array.from(new Set(merged)) : void 0;
35
35
  },
36
- serialize: ({ value, isPublic }) => isPublic ? void 0 : value,
36
+ serialize: ({ resolved, isPublic }) => {
37
+ if (hideWhenPublic && isPublic) {
38
+ return void 0;
39
+ }
40
+ return resolved;
41
+ },
37
42
  deserialize: ({ value }) => {
38
43
  if (!Array.isArray(value)) {
39
44
  return void 0;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/plugins/tags.ts"],"sourcesContent":["import { Error0 } from '../index.js'\n\nexport const tagsPlugin = Error0.plugin().use('prop', 'tags', {\n init: (input: string[]) => input,\n resolve: ({ flow }) => {\n const merged: string[] = []\n for (const value of flow) {\n if (Array.isArray(value)) {\n merged.push(...value.filter((item): item is string => typeof item === 'string'))\n }\n }\n return merged.length > 0 ? Array.from(new Set(merged)) : undefined\n },\n serialize: ({ value, isPublic }) => (isPublic ? undefined : value),\n deserialize: ({ value }) => {\n if (!Array.isArray(value)) {\n return undefined\n }\n return value.filter((item): item is string => typeof item === 'string')\n },\n})\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAAuB;AAEhB,MAAM,aAAa,gBAAO,OAAO,EAAE,IAAI,QAAQ,QAAQ;AAAA,EAC5D,MAAM,CAAC,UAAoB;AAAA,EAC3B,SAAS,CAAC,EAAE,KAAK,MAAM;AACrB,UAAM,SAAmB,CAAC;AAC1B,eAAW,SAAS,MAAM;AACxB,UAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,eAAO,KAAK,GAAG,MAAM,OAAO,CAAC,SAAyB,OAAO,SAAS,QAAQ,CAAC;AAAA,MACjF;AAAA,IACF;AACA,WAAO,OAAO,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,IAAI;AAAA,EAC3D;AAAA,EACA,WAAW,CAAC,EAAE,OAAO,SAAS,MAAO,WAAW,SAAY;AAAA,EAC5D,aAAa,CAAC,EAAE,MAAM,MAAM;AAC1B,QAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,aAAO;AAAA,IACT;AACA,WAAO,MAAM,OAAO,CAAC,SAAyB,OAAO,SAAS,QAAQ;AAAA,EACxE;AACF,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../../src/plugins/tags.ts"],"sourcesContent":["import { Error0 } from '../index.js'\n\nexport const tagsPlugin = ({ hideWhenPublic = true }: { hideWhenPublic?: boolean } = {}) =>\n Error0.plugin().use('prop', 'tags', {\n init: (input: string[]) => input,\n resolve: ({ flow }) => {\n const merged: string[] = []\n for (const value of flow) {\n if (Array.isArray(value)) {\n merged.push(...value.filter((item): item is string => typeof item === 'string'))\n }\n }\n return merged.length > 0 ? Array.from(new Set(merged)) : undefined\n },\n serialize: ({ resolved, isPublic }) => {\n if (hideWhenPublic && isPublic) {\n return undefined\n }\n return resolved\n },\n deserialize: ({ value }) => {\n if (!Array.isArray(value)) {\n return undefined\n }\n return value.filter((item): item is string => typeof item === 'string')\n },\n })\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAAuB;AAEhB,MAAM,aAAa,CAAC,EAAE,iBAAiB,KAAK,IAAkC,CAAC,MACpF,gBAAO,OAAO,EAAE,IAAI,QAAQ,QAAQ;AAAA,EAClC,MAAM,CAAC,UAAoB;AAAA,EAC3B,SAAS,CAAC,EAAE,KAAK,MAAM;AACrB,UAAM,SAAmB,CAAC;AAC1B,eAAW,SAAS,MAAM;AACxB,UAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,eAAO,KAAK,GAAG,MAAM,OAAO,CAAC,SAAyB,OAAO,SAAS,QAAQ,CAAC;AAAA,MACjF;AAAA,IACF;AACA,WAAO,OAAO,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,IAAI;AAAA,EAC3D;AAAA,EACA,WAAW,CAAC,EAAE,UAAU,SAAS,MAAM;AACrC,QAAI,kBAAkB,UAAU;AAC9B,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EACA,aAAa,CAAC,EAAE,MAAM,MAAM;AAC1B,QAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,aAAO;AAAA,IACT;AACA,WAAO,MAAM,OAAO,CAAC,SAAyB,OAAO,SAAS,QAAQ;AAAA,EACxE;AACF,CAAC;","names":[]}
@@ -1,5 +1,7 @@
1
1
  import { PluginError0, ErrorPluginPropOptions, Error0 } from '../index.cjs';
2
2
 
3
- declare const tagsPlugin: PluginError0<Record<never, never> & Record<"tags", ErrorPluginPropOptions<string[], string[], Error0, string[] | undefined>>, Record<never, never>>;
3
+ declare const tagsPlugin: ({ hideWhenPublic }?: {
4
+ hideWhenPublic?: boolean;
5
+ }) => PluginError0<Record<never, never> & Record<"tags", ErrorPluginPropOptions<string[], string[], Error0, string[] | undefined>>, Record<never, never>>;
4
6
 
5
7
  export { tagsPlugin };
@@ -6,22 +6,26 @@ type InferPluginPropInput<TProp extends ErrorPluginPropOptions<any, any, any, an
6
6
  init: infer TInit;
7
7
  } ? NormalizeUnknownToUndefined<InferFirstArg<TInit>> : undefined;
8
8
  type ErrorPluginPropInit<TInputValue, TOutputValue> = ((input: TInputValue) => TOutputValue) | (() => TOutputValue);
9
- type ErrorPluginPropSerialize<TOutputValue, TError extends Error0> = ((options: {
10
- value: TOutputValue;
9
+ type ErrorPluginPropSerializeOptions<TOutputValue, TError extends Error0, TResolveValue extends TOutputValue | undefined> = {
10
+ own: TOutputValue | undefined;
11
+ flow: Array<TOutputValue | undefined>;
12
+ resolved: TResolveValue;
11
13
  error: TError;
12
14
  isPublic: boolean;
13
- }) => unknown) | false;
15
+ };
16
+ type ErrorPluginPropSerialize<TOutputValue, TError extends Error0, TResolveValue extends TOutputValue | undefined> = ((options: ErrorPluginPropSerializeOptions<TOutputValue, TError, TResolveValue>) => unknown) | false;
14
17
  type ErrorPluginPropDeserialize<TOutputValue> = ((options: {
15
18
  value: unknown;
16
- serialized: Record<string, unknown>;
19
+ record: Record<string, unknown>;
17
20
  }) => TOutputValue | undefined) | false;
21
+ type ErrorPluginPropOptionsResolveOptions<TOutputValue, TError extends Error0> = {
22
+ own: TOutputValue | undefined;
23
+ flow: Array<TOutputValue | undefined>;
24
+ error: TError;
25
+ };
18
26
  type ErrorPluginPropOptionsBase<TOutputValue, TError extends Error0, TResolveValue extends TOutputValue | undefined> = {
19
- resolve: (options: {
20
- own: TOutputValue | undefined;
21
- flow: Array<TOutputValue | undefined>;
22
- error: TError;
23
- }) => TResolveValue;
24
- serialize: ErrorPluginPropSerialize<TResolveValue, TError>;
27
+ resolve: (options: ErrorPluginPropOptionsResolveOptions<TOutputValue, TError>) => TResolveValue;
28
+ serialize: ErrorPluginPropSerialize<TOutputValue, TError, TResolveValue>;
25
29
  deserialize: ErrorPluginPropDeserialize<TOutputValue>;
26
30
  };
27
31
  type ErrorPluginPropOptionsWithInit<TInputValue, TOutputValue, TError extends Error0, TResolveValue extends TOutputValue | undefined> = ErrorPluginPropOptionsBase<TOutputValue, TError, TResolveValue> & {
@@ -134,6 +138,17 @@ type EmptyPluginsMap = {
134
138
  }>;
135
139
  methods: Record<never, ErrorMethodRecord>;
136
140
  };
141
+ type ErrorPluginResolved = {
142
+ props: Record<string, ErrorPluginPropOptions<unknown>>;
143
+ methods: Record<string, ErrorPluginMethodFn<unknown>>;
144
+ adapt: Array<ErrorPluginAdaptFn<Error0, Record<string, unknown>>>;
145
+ stack?: ErrorPluginStack;
146
+ cause?: ErrorPluginCause;
147
+ message?: ErrorPluginMessage;
148
+ propKeys: string[];
149
+ propEntries: Array<[string, ErrorPluginPropOptions<unknown>]>;
150
+ methodEntries: Array<[string, ErrorPluginMethodFn<unknown>]>;
151
+ };
137
152
  type PluginPropsMapOf<TPlugin extends ErrorPlugin> = {
138
153
  [TKey in keyof NonNullable<TPlugin['props']>]: NonNullable<TPlugin['props']>[TKey] extends ErrorPluginPropOptions<any, infer TOutputValue, any, infer TResolveValue> ? {
139
154
  init: InferPluginPropInput<NonNullable<TPlugin['props']>[TKey]>;
@@ -164,8 +179,12 @@ type PluginsMapOfInstance<TInstance> = TInstance extends {
164
179
  __pluginsMap?: infer TPluginsMap;
165
180
  } ? TPluginsMap extends ErrorPluginsMap ? TPluginsMap : EmptyPluginsMap : EmptyPluginsMap;
166
181
  type PluginsMapFromParts<TProps extends ErrorPluginProps, TMethods extends ErrorPluginMethods> = ErrorPluginsMapOfPlugin<ErrorPlugin<TProps, TMethods>>;
167
- type ErrorInstanceOfMap<TMap extends ErrorPluginsMap> = Error0 & ErrorResolved<TMap>;
168
- type BuilderError0<TProps extends ErrorPluginProps, TMethods extends ErrorPluginMethods> = Error0 & ErrorResolved<PluginsMapFromParts<TProps, TMethods>>;
182
+ type ErrorInstanceOfMap<TMap extends ErrorPluginsMap> = Error0 & ErrorResolved<TMap> & ErrorOwnMethods<TMap> & ErrorResolveMethods<TMap> & {
183
+ readonly __pluginsMap?: TMap;
184
+ };
185
+ type BuilderError0<TProps extends ErrorPluginProps, TMethods extends ErrorPluginMethods> = Error0 & ErrorResolved<PluginsMapFromParts<TProps, TMethods>> & ErrorOwnMethods<PluginsMapFromParts<TProps, TMethods>> & ErrorResolveMethods<PluginsMapFromParts<TProps, TMethods>> & {
186
+ readonly __pluginsMap?: PluginsMapFromParts<TProps, TMethods>;
187
+ };
169
188
  type PluginOfBuilder<TBuilder> = TBuilder extends PluginError0<infer TProps, infer TMethods> ? ErrorPlugin<TProps, TMethods> : never;
170
189
  declare class PluginError0<TProps extends ErrorPluginProps = Record<never, never>, TMethods extends ErrorPluginMethods = Record<never, never>> {
171
190
  private readonly _plugin;
@@ -188,6 +207,7 @@ declare class PluginError0<TProps extends ErrorPluginProps = Record<never, never
188
207
  use(kind: 'message', value: ErrorPluginMessage<BuilderError0<TProps, TMethods>>): PluginError0<TProps, TMethods>;
189
208
  }
190
209
  type ClassError0<TPluginsMap extends ErrorPluginsMap = EmptyPluginsMap> = {
210
+ MAX_CAUSES_DEPTH: number;
191
211
  new (message: string, input?: ErrorInput<TPluginsMap>): Error0 & ErrorResolved<TPluginsMap> & ErrorOwnMethods<TPluginsMap> & ErrorResolveMethods<TPluginsMap> & {
192
212
  readonly __pluginsMap?: TPluginsMap;
193
213
  };
@@ -198,6 +218,11 @@ type ClassError0<TPluginsMap extends ErrorPluginsMap = EmptyPluginsMap> = {
198
218
  };
199
219
  readonly __pluginsMap?: TPluginsMap;
200
220
  from: (error: unknown) => Error0 & ErrorResolved<TPluginsMap> & ErrorOwnMethods<TPluginsMap> & ErrorResolveMethods<TPluginsMap>;
221
+ round: (error: unknown, isPublic?: boolean) => Error0 & ErrorResolved<TPluginsMap> & ErrorOwnMethods<TPluginsMap> & ErrorResolveMethods<TPluginsMap>;
222
+ causes: {
223
+ (error: unknown, instancesOnly?: false): unknown[];
224
+ (error: unknown, instancesOnly: true): Array<Error0 & ErrorResolved<TPluginsMap> & ErrorOwnMethods<TPluginsMap> & ErrorResolveMethods<TPluginsMap>>;
225
+ };
201
226
  resolve: (error: unknown) => ErrorResolvedProps<TPluginsMap>;
202
227
  serialize: (error: unknown, isPublic?: boolean) => Record<string, unknown>;
203
228
  own: {
@@ -219,14 +244,20 @@ type ClassError0<TPluginsMap extends ErrorPluginsMap = EmptyPluginsMap> = {
219
244
  declare class Error0 extends Error {
220
245
  static readonly __pluginsMap?: EmptyPluginsMap;
221
246
  readonly __pluginsMap?: EmptyPluginsMap;
247
+ static MAX_CAUSES_DEPTH: number;
222
248
  protected static _plugins: ErrorPlugin[];
249
+ protected static _resolvedPlugin?: ErrorPluginResolved;
223
250
  private static readonly _emptyPlugin;
251
+ private static _indexResolvedPlugin;
252
+ private static _applyPlugin;
253
+ private static _mergeResolvedPlugin;
224
254
  private static _getResolvedPlugin;
225
255
  constructor(message: string, input?: ErrorInput<EmptyPluginsMap>);
226
256
  constructor(input: {
227
257
  message: string;
228
258
  } & ErrorInput<EmptyPluginsMap>);
229
- private static readonly isSelfProperty;
259
+ private static _getOwnStore;
260
+ private static readonly isOwnProperty;
230
261
  private static _ownByKey;
231
262
  private static _flowByKey;
232
263
  static own<TThis extends typeof Error0>(this: TThis, error: unknown): ErrorOwnProps<PluginsMapOf<TThis>>;
@@ -234,13 +265,11 @@ declare class Error0 extends Error {
234
265
  own<TThis extends Error0>(this: TThis): ErrorOwnProps<PluginsMapOfInstance<TThis>>;
235
266
  own<TThis extends Error0, TKey extends keyof PluginsMapOfInstance<TThis>['props'] & string>(this: TThis, key: TKey): ErrorOwnProps<PluginsMapOfInstance<TThis>>[TKey];
236
267
  static flow<TThis extends typeof Error0, TKey extends keyof PluginsMapOf<TThis>['props'] & string>(this: TThis, error: unknown, key: TKey): Array<ErrorOwnProps<PluginsMapOf<TThis>>[TKey]>;
237
- static flow(error: unknown, key: string): unknown[];
238
268
  flow<TThis extends Error0, TKey extends keyof PluginsMapOfInstance<TThis>['props'] & string>(this: TThis, key: TKey): Array<ErrorOwnProps<PluginsMapOfInstance<TThis>>[TKey]>;
239
- flow(key: string): unknown[];
269
+ static _resolveByKey(error: Error0, key: string, plugin: ErrorPluginResolved): unknown;
240
270
  static resolve<TThis extends typeof Error0>(this: TThis, error: unknown): ErrorResolvedProps<PluginsMapOf<TThis>>;
241
271
  static resolve(error: unknown): Record<string, unknown>;
242
272
  resolve<TThis extends Error0>(this: TThis): ErrorResolvedProps<PluginsMapOfInstance<TThis>>;
243
- resolve(): Record<string, unknown>;
244
273
  static causes(error: unknown, instancesOnly?: false): unknown[];
245
274
  static causes<T extends typeof Error0>(this: T, error: unknown, instancesOnly: true): Array<InstanceType<T>>;
246
275
  causes<TThis extends Error0>(this: TThis, instancesOnly?: false): [TThis, ...unknown[]];
@@ -248,6 +277,7 @@ declare class Error0 extends Error {
248
277
  static is<T extends typeof Error0>(this: T, error: unknown): error is InstanceType<T>;
249
278
  static isSerialized(error: unknown): error is Record<string, unknown>;
250
279
  static from(error: unknown): Error0;
280
+ static round(error: unknown, isPublic?: boolean): Error0;
251
281
  private static _applyAdapt;
252
282
  private static _fromSerialized;
253
283
  private static _fromNonError0;
@@ -264,6 +294,7 @@ declare class Error0 extends Error {
264
294
  static plugin(): PluginError0;
265
295
  static serialize(error: unknown, isPublic?: boolean): Record<string, unknown>;
266
296
  serialize(isPublic?: boolean): Record<string, unknown>;
297
+ round<TThis extends Error0>(this: TThis, isPublic?: boolean): TThis;
267
298
  }
268
299
 
269
300
  export { type ClassError0, Error0, type ErrorInput, type ErrorInputBase, type ErrorPlugin, type ErrorPluginAdaptFn, type ErrorPluginAdaptResult, type ErrorPluginCause, type ErrorPluginCauseSerialize, type ErrorPluginMessage, type ErrorPluginMessageSerialize, type ErrorPluginMethodFn, type ErrorPluginMethods, type ErrorPluginPropOptions, type ErrorPluginProps, type ErrorPluginStack, type ErrorPluginStackSerialize, type ErrorPluginsMap, type ErrorResolved, type IsEmptyObject, PluginError0 };
package/dist/esm/index.js CHANGED
@@ -75,45 +75,87 @@ class PluginError0 {
75
75
  });
76
76
  }
77
77
  }
78
+ const OWN_SYMBOL = Symbol("Error0.own");
78
79
  class Error0 extends Error {
79
80
  static __pluginsMap;
80
81
  __pluginsMap;
82
+ static MAX_CAUSES_DEPTH = 99;
81
83
  static _plugins = [];
84
+ static _resolvedPlugin;
82
85
  static _emptyPlugin = {
83
86
  props: {},
84
87
  methods: {},
85
88
  adapt: [],
86
89
  stack: void 0,
87
90
  cause: void 0,
88
- message: void 0
91
+ message: void 0,
92
+ propKeys: [],
93
+ propEntries: [],
94
+ methodEntries: []
89
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)
102
+ };
103
+ }
104
+ static _applyPlugin(resolved, plugin) {
105
+ if (plugin.props && "stack" in plugin.props) {
106
+ throw new Error(RESERVED_STACK_PROP_ERROR);
107
+ }
108
+ if (plugin.props && "message" in plugin.props) {
109
+ throw new Error(RESERVED_MESSAGE_PROP_ERROR);
110
+ }
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;
116
+ }
117
+ if (typeof plugin.cause !== "undefined") {
118
+ resolved.cause = plugin.cause;
119
+ }
120
+ if (typeof plugin.message !== "undefined") {
121
+ resolved.message = plugin.message;
122
+ }
123
+ }
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
+ }
90
136
  static _getResolvedPlugin() {
137
+ if (Object.prototype.hasOwnProperty.call(this, "_resolvedPlugin") && this._resolvedPlugin) {
138
+ return this._resolvedPlugin;
139
+ }
91
140
  const resolved = {
92
141
  props: {},
93
142
  methods: {},
94
- adapt: []
143
+ adapt: [],
144
+ propKeys: [],
145
+ propEntries: [],
146
+ methodEntries: []
95
147
  };
96
148
  for (const plugin of this._plugins) {
97
- if (plugin.props && "stack" in plugin.props) {
98
- throw new Error(RESERVED_STACK_PROP_ERROR);
99
- }
100
- if (plugin.props && "message" in plugin.props) {
101
- throw new Error(RESERVED_MESSAGE_PROP_ERROR);
102
- }
103
- Object.assign(resolved.props, plugin.props ?? this._emptyPlugin.props);
104
- Object.assign(resolved.methods, plugin.methods ?? this._emptyPlugin.methods);
105
- resolved.adapt.push(...plugin.adapt ?? this._emptyPlugin.adapt);
106
- if (typeof plugin.stack !== "undefined") {
107
- resolved.stack = plugin.stack;
108
- }
109
- if (typeof plugin.cause !== "undefined") {
110
- resolved.cause = plugin.cause;
111
- }
112
- if (typeof plugin.message !== "undefined") {
113
- resolved.message = plugin.message;
114
- }
149
+ this._applyPlugin(resolved, plugin);
115
150
  }
116
- return resolved;
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;
117
159
  }
118
160
  constructor(...args) {
119
161
  const [first, second] = args;
@@ -122,37 +164,43 @@ class Error0 extends Error {
122
164
  this.name = "Error0";
123
165
  const ctor = this.constructor;
124
166
  const plugin = ctor._getResolvedPlugin();
125
- for (const [key, prop] of Object.entries(plugin.props)) {
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) {
126
170
  if (key === "stack") {
127
171
  continue;
128
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
+ });
129
185
  if (key in input) {
130
186
  const ownValue = input[key];
131
- if (typeof prop.init === "function") {
132
- ;
133
- this[key] = prop.init(ownValue);
134
- } else {
135
- ;
136
- this[key] = ownValue;
137
- }
138
- } else {
139
- Object.defineProperty(this, key, {
140
- get: () => prop.resolve({ own: void 0, flow: this.flow(key), error: this }),
141
- set: (value) => {
142
- Object.defineProperty(this, key, {
143
- value,
144
- writable: true,
145
- enumerable: true,
146
- configurable: true
147
- });
148
- },
149
- enumerable: true,
150
- configurable: true
151
- });
187
+ ownStore[key] = typeof prop.init === "function" ? prop.init(ownValue) : ownValue;
152
188
  }
153
189
  }
154
190
  }
155
- static isSelfProperty = (object, key) => {
191
+ static _getOwnStore(object) {
192
+ const record = object;
193
+ const existing = record[OWN_SYMBOL];
194
+ if (existing && typeof existing === "object") {
195
+ return existing;
196
+ }
197
+ return void 0;
198
+ }
199
+ static isOwnProperty = (object, key) => {
200
+ const ownStore = this._getOwnStore(object);
201
+ if (ownStore && Object.prototype.hasOwnProperty.call(ownStore, key)) {
202
+ return true;
203
+ }
156
204
  const d = Object.getOwnPropertyDescriptor(object, key);
157
205
  if (!d) return false;
158
206
  if (typeof d.get === "function" || typeof d.set === "function") {
@@ -165,22 +213,29 @@ class Error0 extends Error {
165
213
  return true;
166
214
  };
167
215
  static _ownByKey(error, key) {
168
- if (this.isSelfProperty(error, key)) {
216
+ const ownStore = this._getOwnStore(error);
217
+ if (ownStore && Object.prototype.hasOwnProperty.call(ownStore, key)) {
218
+ return ownStore[key];
219
+ }
220
+ if (this.isOwnProperty(error, key)) {
169
221
  return error[key];
170
222
  }
171
223
  return void 0;
172
224
  }
173
225
  static _flowByKey(error, key) {
174
- return this.causes(error, true).map((cause) => {
175
- return this._ownByKey(cause, key);
176
- });
226
+ const causes = this.causes(error, true);
227
+ const values = new Array(causes.length);
228
+ for (let i = 0; i < causes.length; i += 1) {
229
+ values[i] = this._ownByKey(causes[i], key);
230
+ }
231
+ return values;
177
232
  }
178
233
  static own(error, key) {
179
234
  const error0 = this.from(error);
180
235
  if (key === void 0) {
181
236
  const ownValues = {};
182
237
  const plugin = this._getResolvedPlugin();
183
- for (const ownKey of Object.keys(plugin.props)) {
238
+ for (const ownKey of plugin.propKeys) {
184
239
  ownValues[ownKey] = this._ownByKey(error0, ownKey);
185
240
  }
186
241
  return ownValues;
@@ -202,29 +257,34 @@ class Error0 extends Error {
202
257
  const ctor = this.constructor;
203
258
  return ctor._flowByKey(this, key);
204
259
  }
260
+ static _resolveByKey(error, key, plugin) {
261
+ try {
262
+ const options = {
263
+ get own() {
264
+ return error.own(key);
265
+ },
266
+ get flow() {
267
+ return error.flow(key);
268
+ },
269
+ error
270
+ };
271
+ const prop = plugin.props[key];
272
+ const resolver = prop.resolve;
273
+ if (!resolver) {
274
+ return error[key];
275
+ }
276
+ return resolver(options);
277
+ } catch {
278
+ console.error(`Error0: failed to resolve property ${key}`, error);
279
+ return void 0;
280
+ }
281
+ }
205
282
  static resolve(error) {
206
283
  const error0 = this.from(error);
207
284
  const resolved = {};
208
285
  const plugin = this._getResolvedPlugin();
209
- for (const [key, prop] of Object.entries(plugin.props)) {
210
- try {
211
- const options = Object.defineProperties(
212
- {
213
- error: error0
214
- },
215
- {
216
- own: {
217
- get: () => error0.own(key)
218
- },
219
- flow: {
220
- get: () => error0.flow(key)
221
- }
222
- }
223
- );
224
- resolved[key] = prop.resolve(options);
225
- } catch {
226
- console.error(`Error0: failed to resolve property ${key}`, error0);
227
- }
286
+ for (const key of plugin.propKeys) {
287
+ resolved[key] = this._resolveByKey(error0, key, plugin);
228
288
  }
229
289
  return resolved;
230
290
  }
@@ -235,9 +295,9 @@ class Error0 extends Error {
235
295
  static causes(error, instancesOnly) {
236
296
  const causes = [];
237
297
  let current = error;
238
- const maxDepth = 99;
239
298
  const seen = /* @__PURE__ */ new Set();
240
- for (let depth = 0; depth < maxDepth; depth += 1) {
299
+ let depth = 0;
300
+ while (depth < this.MAX_CAUSES_DEPTH) {
241
301
  if (seen.has(current)) {
242
302
  break;
243
303
  }
@@ -249,6 +309,7 @@ class Error0 extends Error {
249
309
  break;
250
310
  }
251
311
  current = current.cause;
312
+ depth += 1;
252
313
  }
253
314
  return causes;
254
315
  }
@@ -274,6 +335,9 @@ class Error0 extends Error {
274
335
  }
275
336
  return this._fromNonError0(error);
276
337
  }
338
+ static round(error, isPublic = false) {
339
+ return this.from(this.serialize(error, isPublic));
340
+ }
277
341
  static _applyAdapt(error) {
278
342
  const plugin = this._getResolvedPlugin();
279
343
  for (const adapt of plugin.adapt) {
@@ -292,8 +356,7 @@ class Error0 extends Error {
292
356
  const errorRecord = error;
293
357
  const recreated = new this(message);
294
358
  const plugin = this._getResolvedPlugin();
295
- const propsEntries = Object.entries(plugin.props);
296
- for (const [key, prop] of propsEntries) {
359
+ for (const [key, prop] of plugin.propEntries) {
297
360
  if (prop.deserialize === false) {
298
361
  continue;
299
362
  }
@@ -301,7 +364,7 @@ class Error0 extends Error {
301
364
  continue;
302
365
  }
303
366
  try {
304
- const value = prop.deserialize({ value: errorRecord[key], serialized: errorRecord });
367
+ const value = prop.deserialize({ value: errorRecord[key], record: errorRecord });
305
368
  recreated[key] = value;
306
369
  } catch {
307
370
  console.error(`Error0: failed to deserialize property ${key}`, errorRecord);
@@ -344,8 +407,9 @@ class Error0 extends Error {
344
407
  const Error0Extended = class Error0 extends Base {
345
408
  };
346
409
  Error0Extended._plugins = [...Base._plugins, plugin];
347
- const resolved = Error0Extended._getResolvedPlugin();
348
- for (const [key, method] of Object.entries(resolved.methods)) {
410
+ const resolved = this._mergeResolvedPlugin(Base._getResolvedPlugin(), plugin);
411
+ Error0Extended._resolvedPlugin = resolved;
412
+ for (const [key, method] of resolved.methodEntries) {
349
413
  Object.defineProperty(Error0Extended.prototype, key, {
350
414
  value: function(...args) {
351
415
  return method(this, ...args);
@@ -444,9 +508,8 @@ class Error0 extends Error {
444
508
  }
445
509
  static serialize(error, isPublic = true) {
446
510
  const error0 = this.from(error);
447
- const resolvedProps = this.resolve(error0);
448
- const resolvedRecord = resolvedProps;
449
511
  const plugin = this._getResolvedPlugin();
512
+ const resolveByKey = (targetError, key, targetPlugin) => this._resolveByKey(targetError, key, targetPlugin);
450
513
  const messagePlugin = plugin.message;
451
514
  let serializedMessage = error0.message;
452
515
  try {
@@ -458,24 +521,37 @@ class Error0 extends Error {
458
521
  serializedMessage = error0.message;
459
522
  }
460
523
  const json = {
461
- name: error0.name,
462
- message: serializedMessage
524
+ name: error0.name
463
525
  // we do not serialize causes, it is enough that we have floated props and adapt helper
464
526
  // cause: error0.cause,
465
527
  };
466
- const propsEntries = Object.entries(plugin.props);
467
- for (const [key, prop] of propsEntries) {
528
+ if (serializedMessage !== void 0) {
529
+ json.message = serializedMessage;
530
+ }
531
+ for (const [key, prop] of plugin.propEntries) {
468
532
  if (prop.serialize === false) {
469
533
  continue;
470
534
  }
471
535
  try {
472
- const value = resolvedRecord[key];
473
- const jsonValue = prop.serialize({ value, error: error0, isPublic });
536
+ const options = {
537
+ get own() {
538
+ return error0.own(key);
539
+ },
540
+ get flow() {
541
+ return error0.flow(key);
542
+ },
543
+ get resolved() {
544
+ return resolveByKey(error0, key, plugin);
545
+ },
546
+ error: error0,
547
+ isPublic
548
+ };
549
+ const jsonValue = prop.serialize(options);
474
550
  if (jsonValue !== void 0) {
475
551
  json[key] = jsonValue;
476
552
  }
477
553
  } catch {
478
- console.error(`Error0: failed to serialize property ${key}`, resolvedRecord);
554
+ console.error(`Error0: failed to serialize property ${key}`, error0);
479
555
  }
480
556
  }
481
557
  const stackPlugin = plugin.stack;
@@ -507,12 +583,16 @@ class Error0 extends Error {
507
583
  console.error("Error0: failed to serialize cause", error0);
508
584
  }
509
585
  }
510
- return Object.fromEntries(Object.entries(json).filter(([, value]) => value !== void 0));
586
+ return json;
511
587
  }
512
588
  serialize(isPublic = true) {
513
589
  const ctor = this.constructor;
514
590
  return ctor.serialize(this, isPublic);
515
591
  }
592
+ round(isPublic = true) {
593
+ const ctor = this.constructor;
594
+ return ctor.round(this, isPublic);
595
+ }
516
596
  }
517
597
  export {
518
598
  Error0,