@devp0nt/error0 1.0.0-next.41 → 1.0.0-next.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +77 -73
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +109 -100
- package/dist/esm/index.d.ts +109 -100
- package/dist/esm/index.js +76 -72
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.test.ts +68 -36
- package/src/index.ts +258 -239
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export type ErrorExtensionPropOptions<TInputValue, TOutputValue, TError extends Error0 = Error0> = {\n init: (input: TInputValue) => TOutputValue\n resolve: (options: {\n value: TOutputValue | undefined\n flow: Array<TOutputValue | undefined>\n error: TError\n }) => TOutputValue | undefined\n serialize: (options: { value: TOutputValue; error: TError; isPublic: boolean }) => unknown\n deserialize: (options: { value: unknown; serialized: Record<string, unknown> }) => TOutputValue | undefined\n}\nexport type ErrorExtensionMethodFn<\n TOutputValue,\n TArgs extends unknown[] = unknown[],\n TError extends Error0 = Error0,\n> = (error: TError, ...args: TArgs) => TOutputValue\nexport type ErrorExtensionRefineResult<TOutputProps extends Record<string, unknown>> = Partial<TOutputProps> | undefined\nexport type ErrorExtensionRefineFn<\n TError extends Error0 = Error0,\n TOutputProps extends Record<string, unknown> = Record<never, never>,\n> = ((error: TError) => void) | ((error: TError) => ErrorExtensionRefineResult<TOutputProps>)\ntype ErrorMethodRecord = {\n args: unknown[]\n output: unknown\n}\n\nexport type ErrorExtensionProps = { [key: string]: ErrorExtensionPropOptions<any, any> }\nexport type ErrorExtensionMethods = { [key: string]: ErrorExtensionMethodFn<any, any[]> }\n\nexport type ErrorExtension<\n TProps extends ErrorExtensionProps = Record<never, never>,\n TMethods extends ErrorExtensionMethods = Record<never, never>,\n> = {\n props?: TProps\n methods?: TMethods\n refine?: Array<ErrorExtensionRefineFn<Error0, ExtensionOutputProps<TProps>>>\n}\ntype AddPropToExtensionProps<\n TProps extends ErrorExtensionProps,\n TKey extends string,\n TInputValue,\n TOutputValue,\n> = TProps & Record<TKey, ErrorExtensionPropOptions<TInputValue, TOutputValue>>\ntype AddMethodToExtensionMethods<\n TMethods extends ErrorExtensionMethods,\n TKey extends string,\n TArgs extends unknown[],\n TOutputValue,\n> = TMethods & Record<TKey, ErrorExtensionMethodFn<TOutputValue, TArgs>>\ntype ExtensionOutputProps<TProps extends ErrorExtensionProps> = {\n [TKey in keyof TProps]: TProps[TKey] extends ErrorExtensionPropOptions<any, infer TOutputValue> ? TOutputValue : never\n}\nexport type ErrorExtensionsMap = {\n props: Record<string, { init: unknown; resolve: unknown }>\n methods: Record<string, ErrorMethodRecord>\n}\nexport type IsEmptyObject<T> = keyof T extends never ? true : false\nexport type ErrorInputBase = {\n cause?: unknown\n}\nexport type ErrorInput<TExtensionsMap extends ErrorExtensionsMap> =\n IsEmptyObject<TExtensionsMap['props']> extends true\n ? ErrorInputBase\n : ErrorInputBase &\n Partial<{\n [TKey in keyof TExtensionsMap['props']]: TExtensionsMap['props'][TKey]['init']\n }>\n\ntype ErrorOutputProps<TExtensionsMap extends ErrorExtensionsMap> = {\n [TKey in keyof TExtensionsMap['props']]?: TExtensionsMap['props'][TKey]['resolve']\n}\ntype ErrorOutputMethods<TExtensionsMap extends ErrorExtensionsMap> = {\n [TKey in keyof TExtensionsMap['methods']]: TExtensionsMap['methods'][TKey] extends {\n args: infer TArgs extends unknown[]\n output: infer TOutput\n }\n ? (...args: TArgs) => TOutput\n : never\n}\nexport type ErrorOutput<TExtensionsMap extends ErrorExtensionsMap> = ErrorOutputProps<TExtensionsMap> &\n ErrorOutputMethods<TExtensionsMap>\n\ntype ErrorStaticMethods<TExtensionsMap extends ErrorExtensionsMap> = {\n [TKey in keyof TExtensionsMap['methods']]: TExtensionsMap['methods'][TKey] extends {\n args: infer TArgs extends unknown[]\n output: infer TOutput\n }\n ? (error: unknown, ...args: TArgs) => TOutput\n : never\n}\n\ntype EmptyExtensionsMap = {\n props: Record<never, { init: never; resolve: never }>\n methods: Record<never, ErrorMethodRecord>\n}\n\ntype ErrorExtensionResolved = {\n props: Record<string, ErrorExtensionPropOptions<unknown, unknown>>\n methods: Record<string, ErrorExtensionMethodFn<unknown>>\n refine: Array<ErrorExtensionRefineFn<Error0, Record<string, unknown>>>\n}\n\ntype ExtensionPropsMapOf<TExtension extends ErrorExtension> = {\n [TKey in keyof NonNullable<TExtension['props']>]: NonNullable<\n TExtension['props']\n >[TKey] extends ErrorExtensionPropOptions<infer TInputValue, infer TOutputValue>\n ? { init: TInputValue; resolve: TOutputValue }\n : never\n}\ntype ExtensionMethodsMapOf<TExtension extends ErrorExtension> = {\n [TKey in keyof NonNullable<TExtension['methods']>]: NonNullable<TExtension['methods']>[TKey] extends (\n error: Error0,\n ...args: infer TArgs extends unknown[]\n ) => infer TOutput\n ? { args: TArgs; output: TOutput }\n : never\n}\ntype ErrorExtensionsMapOfExtension<TExtension extends ErrorExtension> = {\n props: ExtensionPropsMapOf<TExtension>\n methods: ExtensionMethodsMapOf<TExtension>\n}\ntype ExtendErrorExtensionsMap<TMap extends ErrorExtensionsMap, TExtension extends ErrorExtension> = {\n props: TMap['props'] & ErrorExtensionsMapOfExtension<TExtension>['props']\n methods: TMap['methods'] & ErrorExtensionsMapOfExtension<TExtension>['methods']\n}\ntype ExtendErrorExtensionsMapWithProp<\n TMap extends ErrorExtensionsMap,\n TKey extends string,\n TInputValue,\n TOutputValue,\n> = ExtendErrorExtensionsMap<TMap, ErrorExtension<Record<TKey, ErrorExtensionPropOptions<TInputValue, TOutputValue>>>>\ntype ExtendErrorExtensionsMapWithMethod<\n TMap extends ErrorExtensionsMap,\n TKey extends string,\n TArgs extends unknown[],\n TOutputValue,\n> = ExtendErrorExtensionsMap<\n TMap,\n ErrorExtension<Record<never, never>, Record<TKey, ErrorExtensionMethodFn<TOutputValue, TArgs>>>\n>\n\ntype ExtensionsMapOf<TClass> = TClass extends { __extensionsMap?: infer TExtensionsMap }\n ? TExtensionsMap extends ErrorExtensionsMap\n ? TExtensionsMap\n : EmptyExtensionsMap\n : EmptyExtensionsMap\n\ntype ExtensionsMapFromParts<\n TProps extends ErrorExtensionProps,\n TMethods extends ErrorExtensionMethods,\n> = ErrorExtensionsMapOfExtension<ErrorExtension<TProps, TMethods>>\ntype ErrorInstanceOfMap<TMap extends ErrorExtensionsMap> = Error0 & ErrorOutput<TMap>\ntype BuilderError0<TProps extends ErrorExtensionProps, TMethods extends ErrorExtensionMethods> = Error0 &\n ErrorOutput<ExtensionsMapFromParts<TProps, TMethods>>\n\ntype ExtensionOfBuilder<TBuilder> =\n TBuilder extends ExtensionError0<infer TProps, infer TMethods> ? ErrorExtension<TProps, TMethods> : never\n\nexport class ExtensionError0<\n TProps extends ErrorExtensionProps = Record<never, never>,\n TMethods extends ErrorExtensionMethods = Record<never, never>,\n> {\n private readonly _extension: ErrorExtension<ErrorExtensionProps, ErrorExtensionMethods>\n\n readonly Infer = undefined as unknown as {\n props: TProps\n methods: TMethods\n }\n\n constructor(extension?: ErrorExtension<ErrorExtensionProps, ErrorExtensionMethods>) {\n this._extension = {\n props: { ...(extension?.props ?? {}) },\n methods: { ...(extension?.methods ?? {}) },\n refine: [...(extension?.refine ?? [])],\n }\n }\n\n prop<TKey extends string, TInputValue, TOutputValue>(\n key: TKey,\n value: ErrorExtensionPropOptions<TInputValue, TOutputValue, BuilderError0<TProps, TMethods>>,\n ): ExtensionError0<AddPropToExtensionProps<TProps, TKey, TInputValue, TOutputValue>, TMethods> {\n return this.extend('prop', key, value)\n }\n\n method<TKey extends string, TArgs extends unknown[], TOutputValue>(\n key: TKey,\n value: ErrorExtensionMethodFn<TOutputValue, TArgs, BuilderError0<TProps, TMethods>>,\n ): ExtensionError0<TProps, AddMethodToExtensionMethods<TMethods, TKey, TArgs, TOutputValue>> {\n return this.extend('method', key, value)\n }\n\n refine(\n value: ErrorExtensionRefineFn<BuilderError0<TProps, TMethods>, ExtensionOutputProps<TProps>>,\n ): ExtensionError0<TProps, TMethods> {\n return this.extend('refine', value)\n }\n\n extend<TKey extends string, TInputValue, TOutputValue>(\n kind: 'prop',\n key: TKey,\n value: ErrorExtensionPropOptions<TInputValue, TOutputValue, BuilderError0<TProps, TMethods>>,\n ): ExtensionError0<AddPropToExtensionProps<TProps, TKey, TInputValue, TOutputValue>, TMethods>\n extend<TKey extends string, TArgs extends unknown[], TOutputValue>(\n kind: 'method',\n key: TKey,\n value: ErrorExtensionMethodFn<TOutputValue, TArgs, BuilderError0<TProps, TMethods>>,\n ): ExtensionError0<TProps, AddMethodToExtensionMethods<TMethods, TKey, TArgs, TOutputValue>>\n extend(\n kind: 'refine',\n value: ErrorExtensionRefineFn<BuilderError0<TProps, TMethods>, ExtensionOutputProps<TProps>>,\n ): ExtensionError0<TProps, TMethods>\n extend(\n kind: 'prop' | 'method' | 'refine',\n keyOrValue: string | ErrorExtensionRefineFn<any, any>,\n value?: ErrorExtensionPropOptions<unknown, unknown, any> | ErrorExtensionMethodFn<unknown, unknown[], any>,\n ): ExtensionError0<any, any> {\n const nextProps: ErrorExtensionProps = { ...(this._extension.props ?? {}) }\n const nextMethods: ErrorExtensionMethods = { ...(this._extension.methods ?? {}) }\n const nextRefine: Array<ErrorExtensionRefineFn<Error0, Record<string, unknown>>> = [\n ...(this._extension.refine ?? []),\n ]\n if (kind === 'prop') {\n const key = keyOrValue as string\n if (value === undefined) {\n throw new Error('ExtensionError0.extend(\"prop\", key, value) requires value')\n }\n nextProps[key] = value as ErrorExtensionPropOptions<any, any>\n } else if (kind === 'method') {\n const key = keyOrValue as string\n if (value === undefined) {\n throw new Error('ExtensionError0.extend(\"method\", key, value) requires value')\n }\n nextMethods[key] = value as ErrorExtensionMethodFn<any, any[]>\n } else {\n nextRefine.push(keyOrValue as ErrorExtensionRefineFn<Error0, Record<string, unknown>>)\n }\n return new ExtensionError0({\n props: nextProps,\n methods: nextMethods,\n refine: nextRefine,\n })\n }\n}\n\nexport type ClassError0<TExtensionsMap extends ErrorExtensionsMap = EmptyExtensionsMap> = {\n new (message: string, input?: ErrorInput<TExtensionsMap>): Error0 & ErrorOutput<TExtensionsMap>\n new (input: { message: string } & ErrorInput<TExtensionsMap>): Error0 & ErrorOutput<TExtensionsMap>\n readonly __extensionsMap?: TExtensionsMap\n from: (error: unknown) => Error0 & ErrorOutput<TExtensionsMap>\n serialize: (error: unknown, isPublic?: boolean) => Record<string, unknown>\n prop: <TKey extends string, TInputValue, TOutputValue>(\n key: TKey,\n value: ErrorExtensionPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<TExtensionsMap>>,\n ) => ClassError0<ExtendErrorExtensionsMapWithProp<TExtensionsMap, TKey, TInputValue, TOutputValue>>\n method: <TKey extends string, TArgs extends unknown[], TOutputValue>(\n key: TKey,\n value: ErrorExtensionMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<TExtensionsMap>>,\n ) => ClassError0<ExtendErrorExtensionsMapWithMethod<TExtensionsMap, TKey, TArgs, TOutputValue>>\n refine: (\n value: ErrorExtensionRefineFn<ErrorInstanceOfMap<TExtensionsMap>, ErrorOutputProps<TExtensionsMap>>,\n ) => ClassError0<TExtensionsMap>\n extend: {\n <TBuilder extends ExtensionError0>(\n extension: TBuilder,\n ): ClassError0<ExtendErrorExtensionsMap<TExtensionsMap, ExtensionOfBuilder<TBuilder>>>\n <TKey extends string, TInputValue, TOutputValue>(\n kind: 'prop',\n key: TKey,\n value: ErrorExtensionPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<TExtensionsMap>>,\n ): ClassError0<ExtendErrorExtensionsMapWithProp<TExtensionsMap, TKey, TInputValue, TOutputValue>>\n <TKey extends string, TArgs extends unknown[], TOutputValue>(\n kind: 'method',\n key: TKey,\n value: ErrorExtensionMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<TExtensionsMap>>,\n ): ClassError0<ExtendErrorExtensionsMapWithMethod<TExtensionsMap, TKey, TArgs, TOutputValue>>\n (\n kind: 'refine',\n value: ErrorExtensionRefineFn<ErrorInstanceOfMap<TExtensionsMap>, ErrorOutputProps<TExtensionsMap>>,\n ): ClassError0<TExtensionsMap>\n }\n extension: () => ExtensionError0\n} & ErrorStaticMethods<TExtensionsMap>\n\nexport class Error0 extends Error {\n static readonly __extensionsMap?: EmptyExtensionsMap\n protected static _extensions: ErrorExtension[] = []\n\n private static readonly _emptyExtension: ErrorExtensionResolved = {\n props: {},\n methods: {},\n refine: [],\n }\n\n private static _getResolvedExtension(this: typeof Error0): ErrorExtensionResolved {\n const resolved: ErrorExtensionResolved = {\n props: {},\n methods: {},\n refine: [],\n }\n for (const extension of this._extensions) {\n Object.assign(resolved.props, extension.props ?? this._emptyExtension.props)\n Object.assign(resolved.methods, extension.methods ?? this._emptyExtension.methods)\n resolved.refine.push(...(extension.refine ?? this._emptyExtension.refine))\n }\n return resolved\n }\n\n constructor(message: string, input?: ErrorInput<EmptyExtensionsMap>)\n constructor(input: { message: string } & ErrorInput<EmptyExtensionsMap>)\n constructor(\n ...args:\n | [message: string, input?: ErrorInput<EmptyExtensionsMap>]\n | [{ message: string } & ErrorInput<EmptyExtensionsMap>]\n ) {\n const [first, second] = args\n const input = typeof first === 'string' ? { message: first, ...(second ?? {}) } : first\n\n super(input.message, { cause: input.cause })\n this.name = 'Error0'\n\n const ctor = this.constructor as typeof Error0\n const extension = ctor._getResolvedExtension()\n\n for (const [key, prop] of Object.entries(extension.props)) {\n if (key in input) {\n const ownValue = (input as Record<string, unknown>)[key]\n ;(this as Record<string, unknown>)[key] = prop.init(ownValue)\n } else {\n Object.defineProperty(this, key, {\n get: () => prop.resolve({ value: undefined, flow: this.flow(key), error: this }),\n set: (value) => {\n Object.defineProperty(this, key, {\n value,\n writable: true,\n enumerable: true,\n configurable: true,\n })\n },\n enumerable: true,\n configurable: true,\n })\n }\n }\n }\n\n private static readonly isSelfProperty = (object: object, key: string): boolean => {\n const d = Object.getOwnPropertyDescriptor(object, key)\n if (!d) return false\n if (typeof d.get === 'function' || typeof d.set === 'function') {\n if ('name' in object && object.name === 'Error0') {\n return false\n } else {\n return true\n }\n }\n return true\n }\n\n static own(error: object, key: string): unknown {\n if (this.isSelfProperty(error, key)) {\n return (error as Record<string, unknown>)[key]\n }\n return undefined\n }\n own(key: string): unknown {\n const ctor = this.constructor as typeof Error0\n return ctor.own(this, key)\n }\n\n static flow(error: object, key: string): unknown[] {\n return this.causes(error, true).map((cause) => {\n return this.own(cause, key)\n })\n }\n flow(key: string): unknown[] {\n const ctor = this.constructor as typeof Error0\n return ctor.flow(this, key)\n }\n\n static causes(error: unknown, instancesOnly?: false): unknown[]\n static causes<T extends typeof Error0>(this: T, error: unknown, instancesOnly: true): Array<InstanceType<T>>\n static causes(error: unknown, instancesOnly?: boolean): unknown[] {\n const causes: unknown[] = []\n let current: unknown = error\n const maxDepth = 99\n const seen = new Set<unknown>()\n for (let depth = 0; depth < maxDepth; depth += 1) {\n if (seen.has(current)) {\n break\n }\n seen.add(current)\n if (!instancesOnly || this.is(current)) {\n causes.push(current)\n }\n if (!current || typeof current !== 'object') {\n break\n }\n current = (current as { cause?: unknown }).cause\n }\n return causes\n }\n causes<T extends typeof Error0>(this: T, instancesOnly?: false): [InstanceType<T>, ...unknown[]]\n causes<T extends typeof Error0>(this: T, instancesOnly: true): [InstanceType<T>, ...Array<InstanceType<T>>]\n causes(instancesOnly?: boolean): unknown[] {\n const ctor = this.constructor as typeof Error0\n if (instancesOnly) {\n return ctor.causes(this, true)\n }\n return ctor.causes(this)\n }\n\n static is<T extends typeof Error0>(this: T, error: unknown): error is InstanceType<T> {\n return error instanceof this\n }\n\n static isSerialized(error: unknown): error is Record<string, unknown> {\n return !this.is(error) && typeof error === 'object' && error !== null && 'name' in error && error.name === 'Error0'\n }\n\n static from(error: unknown): Error0 {\n if (this.is(error)) {\n return error\n }\n if (this.isSerialized(error)) {\n return this._fromSerialized(error)\n }\n return this._fromNonError0(error)\n }\n\n private static _applyRefine(error: Error0): Error0 {\n const extension = this._getResolvedExtension()\n for (const refine of extension.refine) {\n const refined = refine(error as any)\n if (refined && typeof refined === 'object') {\n Object.assign(error as unknown as Record<string, unknown>, refined)\n }\n }\n return error\n }\n\n private static _fromSerialized(error: unknown): Error0 {\n const message = this._extractMessage(error)\n if (typeof error !== 'object' || error === null) {\n return this._applyRefine(new this(message, { cause: error }))\n }\n const errorRecord = error as Record<string, unknown>\n const recreated = new this(message)\n const extension = this._getResolvedExtension()\n const propsEntries = Object.entries(extension.props)\n for (const [key, prop] of propsEntries) {\n if (!(key in errorRecord)) {\n continue\n }\n try {\n const value = prop.deserialize({ value: errorRecord[key], serialized: errorRecord })\n ;(recreated as unknown as Record<string, unknown>)[key] = value\n } catch {\n // ignore\n }\n }\n // we do not serialize causes\n // ;(recreated as unknown as { cause?: unknown }).cause = errorRecord.cause\n const isStackInProps = propsEntries.some(([key]) => key === 'stack')\n if (typeof errorRecord.stack === 'string' && !isStackInProps) {\n recreated.stack = errorRecord.stack\n }\n return recreated\n }\n\n private static _fromNonError0(error: unknown): Error0 {\n const message = this._extractMessage(error)\n return this._applyRefine(new this(message, { cause: error }))\n }\n\n private static _extractMessage(error: unknown): string {\n return (\n (typeof error === 'string'\n ? error\n : typeof error === 'object' && error !== null && 'message' in error && typeof error.message === 'string'\n ? error.message\n : undefined) || 'Unknown error'\n )\n }\n\n private static _extendWithExtension(\n this: typeof Error0,\n extension: ErrorExtension<ErrorExtensionProps, ErrorExtensionMethods>,\n ): ClassError0 {\n const Base = this as unknown as typeof Error0\n const Error0Extended = class Error0 extends Base {}\n ;(Error0Extended as typeof Error0)._extensions = [...Base._extensions, extension]\n\n const resolved = (Error0Extended as typeof Error0)._getResolvedExtension()\n for (const [key, method] of Object.entries(resolved.methods)) {\n Object.defineProperty((Error0Extended as typeof Error0).prototype, key, {\n value: function (...args: unknown[]) {\n return method(this as Error0, ...args)\n },\n writable: true,\n enumerable: true,\n configurable: true,\n })\n Object.defineProperty(Error0Extended, key, {\n value: function (error: unknown, ...args: unknown[]) {\n return method(this.from(error), ...args)\n },\n writable: true,\n enumerable: true,\n configurable: true,\n })\n }\n\n return Error0Extended as unknown as ClassError0\n }\n\n private static _extensionFromBuilder(\n extension: ExtensionError0,\n ): ErrorExtension<ErrorExtensionProps, ErrorExtensionMethods> {\n const extensionRecord = extension as unknown as {\n _extension: ErrorExtension<ErrorExtensionProps, ErrorExtensionMethods>\n }\n return {\n props: { ...(extensionRecord._extension.props ?? {}) },\n methods: { ...(extensionRecord._extension.methods ?? {}) },\n refine: [...(extensionRecord._extension.refine ?? [])],\n }\n }\n\n static prop<TThis extends typeof Error0, TKey extends string, TInputValue, TOutputValue>(\n this: TThis,\n key: TKey,\n value: ErrorExtensionPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<ExtensionsMapOf<TThis>>>,\n ): ClassError0<ExtendErrorExtensionsMapWithProp<ExtensionsMapOf<TThis>, TKey, TInputValue, TOutputValue>> {\n return this.extend('prop', key, value)\n }\n\n static method<TThis extends typeof Error0, TKey extends string, TArgs extends unknown[], TOutputValue>(\n this: TThis,\n key: TKey,\n value: ErrorExtensionMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<ExtensionsMapOf<TThis>>>,\n ): ClassError0<ExtendErrorExtensionsMapWithMethod<ExtensionsMapOf<TThis>, TKey, TArgs, TOutputValue>> {\n return this.extend('method', key, value)\n }\n\n static refine<TThis extends typeof Error0>(\n this: TThis,\n value: ErrorExtensionRefineFn<ErrorInstanceOfMap<ExtensionsMapOf<TThis>>, ErrorOutputProps<ExtensionsMapOf<TThis>>>,\n ): ClassError0<ExtensionsMapOf<TThis>> {\n return this.extend('refine', value)\n }\n\n static extend<TThis extends typeof Error0, TBuilder extends ExtensionError0>(\n this: TThis,\n extension: TBuilder,\n ): ClassError0<ExtendErrorExtensionsMap<ExtensionsMapOf<TThis>, ExtensionOfBuilder<TBuilder>>>\n static extend<TThis extends typeof Error0, TKey extends string, TInputValue, TOutputValue>(\n this: TThis,\n kind: 'prop',\n key: TKey,\n value: ErrorExtensionPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<ExtensionsMapOf<TThis>>>,\n ): ClassError0<ExtendErrorExtensionsMapWithProp<ExtensionsMapOf<TThis>, TKey, TInputValue, TOutputValue>>\n static extend<TThis extends typeof Error0, TKey extends string, TArgs extends unknown[], TOutputValue>(\n this: TThis,\n kind: 'method',\n key: TKey,\n value: ErrorExtensionMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<ExtensionsMapOf<TThis>>>,\n ): ClassError0<ExtendErrorExtensionsMapWithMethod<ExtensionsMapOf<TThis>, TKey, TArgs, TOutputValue>>\n static extend<TThis extends typeof Error0>(\n this: TThis,\n kind: 'refine',\n value: ErrorExtensionRefineFn<ErrorInstanceOfMap<ExtensionsMapOf<TThis>>, ErrorOutputProps<ExtensionsMapOf<TThis>>>,\n ): ClassError0<ExtensionsMapOf<TThis>>\n static extend(\n this: typeof Error0,\n first: ExtensionError0 | 'prop' | 'method' | 'refine',\n key?: string | ErrorExtensionRefineFn<any, any>,\n value?: ErrorExtensionPropOptions<unknown, unknown> | ErrorExtensionMethodFn<unknown>,\n ): ClassError0 {\n if (first instanceof ExtensionError0) {\n return this._extendWithExtension(this._extensionFromBuilder(first))\n }\n if (first === 'refine') {\n if (typeof key !== 'function') {\n throw new Error('Error0.extend(\"refine\", value) requires refine function')\n }\n return this._extendWithExtension({\n refine: [key],\n })\n }\n if (typeof key !== 'string' || value === undefined) {\n throw new Error('Error0.extend(kind, key, value) requires key and value')\n }\n\n if (first === 'prop') {\n return this._extendWithExtension({\n props: { [key]: value as ErrorExtensionPropOptions<unknown, unknown> },\n })\n }\n return this._extendWithExtension({\n methods: { [key]: value as ErrorExtensionMethodFn<unknown> },\n })\n }\n\n static extension(): ExtensionError0 {\n return new ExtensionError0()\n }\n\n static serialize(error: unknown, isPublic = true): Record<string, unknown> {\n const error0 = this.from(error)\n const json: Record<string, unknown> = {\n name: error0.name,\n message: error0.message,\n // we do not serialize causes, it is enough that we have floated props and refine helper\n // cause: error0.cause,\n }\n\n const extension = this._getResolvedExtension()\n const propsEntries = Object.entries(extension.props)\n for (const [key, prop] of propsEntries) {\n try {\n const value = prop.resolve({ value: error0.own(key), flow: error0.flow(key), error: error0 })\n const jsonValue = prop.serialize({ value, error: error0, isPublic })\n if (jsonValue !== undefined) {\n json[key] = jsonValue\n }\n } catch {\n // ignore\n }\n }\n const isStackInProps = propsEntries.some(([key]) => key === 'stack')\n if (!isStackInProps && typeof error0.stack === 'string') {\n json.stack = error0.stack\n }\n return Object.fromEntries(Object.entries(json).filter(([, value]) => value !== undefined)) as Record<\n string,\n unknown\n >\n }\n\n serialize(isPublic = true): object {\n const ctor = this.constructor as typeof Error0\n return ctor.serialize(this, isPublic)\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["type IsUnknown<T> = unknown extends T ? ([T] extends [unknown] ? true : false) : false\ntype NormalizeUnknownToUndefined<T> = IsUnknown<T> extends true ? undefined : T\ntype IsOnlyUndefined<T> = [Exclude<T, undefined>] extends [never] ? true : false\ntype InferFirstArg<TFn> = TFn extends (...args: infer TArgs) => unknown\n ? TArgs extends [infer TFirst, ...unknown[]]\n ? TFirst\n : undefined\n : undefined\ntype InferPluginPropInput<TProp extends ErrorPluginPropOptions<any, any, any>> = NormalizeUnknownToUndefined<\n InferFirstArg<TProp['init']>\n>\ntype ErrorPluginPropInit<TInputValue, TOutputValue> = ((input: TInputValue) => TOutputValue) | (() => TOutputValue)\ntype ErrorPluginPropSerialize<TOutputValue, TError extends Error0> =\n | ((options: { value: TOutputValue; error: TError; isPublic: boolean }) => unknown)\n | false\ntype ErrorPluginPropDeserialize<TOutputValue> =\n | ((options: { value: unknown; serialized: Record<string, unknown> }) => TOutputValue | undefined)\n | false\n\nexport type ErrorPluginPropOptions<TInputValue, TOutputValue, TError extends Error0 = Error0> = {\n init: ErrorPluginPropInit<TInputValue, TOutputValue>\n resolve: (options: {\n value: TOutputValue | undefined\n flow: Array<TOutputValue | undefined>\n error: TError\n }) => TOutputValue | undefined\n serialize: ErrorPluginPropSerialize<TOutputValue, TError>\n deserialize: ErrorPluginPropDeserialize<TOutputValue>\n}\nexport type ErrorPluginMethodFn<TOutputValue, TArgs extends unknown[] = unknown[], TError extends Error0 = Error0> = (\n error: TError,\n ...args: TArgs\n) => TOutputValue\nexport type ErrorPluginAdaptResult<TOutputProps extends Record<string, unknown>> = Partial<TOutputProps> | undefined\nexport type ErrorPluginAdaptFn<\n TError extends Error0 = Error0,\n TOutputProps extends Record<string, unknown> = Record<never, never>,\n> = ((error: TError) => void) | ((error: TError) => ErrorPluginAdaptResult<TOutputProps>)\ntype ErrorMethodRecord = {\n args: unknown[]\n output: unknown\n}\n\nexport type ErrorPluginProps = { [key: string]: ErrorPluginPropOptions<any, any> }\nexport type ErrorPluginMethods = { [key: string]: ErrorPluginMethodFn<any, any[]> }\n\nexport type ErrorPlugin<\n TProps extends ErrorPluginProps = Record<never, never>,\n TMethods extends ErrorPluginMethods = Record<never, never>,\n> = {\n props?: TProps\n methods?: TMethods\n adapt?: Array<ErrorPluginAdaptFn<Error0, PluginOutputProps<TProps>>>\n}\ntype AddPropToPluginProps<TProps extends ErrorPluginProps, TKey extends string, TInputValue, TOutputValue> = TProps &\n Record<TKey, ErrorPluginPropOptions<TInputValue, TOutputValue>>\ntype AddMethodToPluginMethods<\n TMethods extends ErrorPluginMethods,\n TKey extends string,\n TArgs extends unknown[],\n TOutputValue,\n> = TMethods & Record<TKey, ErrorPluginMethodFn<TOutputValue, TArgs>>\ntype PluginOutputProps<TProps extends ErrorPluginProps> = {\n [TKey in keyof TProps]: TProps[TKey] extends ErrorPluginPropOptions<any, infer TOutputValue> ? TOutputValue : never\n}\nexport type ErrorPluginsMap = {\n props: Record<string, { init: unknown; resolve: unknown }>\n methods: Record<string, ErrorMethodRecord>\n}\nexport type IsEmptyObject<T> = keyof T extends never ? true : false\nexport type ErrorInputBase = {\n cause?: unknown\n}\ntype ErrorInputPluginProps<TPluginsMap extends ErrorPluginsMap> = {\n [TKey in keyof TPluginsMap['props'] as IsOnlyUndefined<TPluginsMap['props'][TKey]['init']> extends true\n ? never\n : TKey]?: TPluginsMap['props'][TKey]['init']\n}\nexport type ErrorInput<TPluginsMap extends ErrorPluginsMap> =\n IsEmptyObject<TPluginsMap['props']> extends true\n ? ErrorInputBase\n : ErrorInputBase & ErrorInputPluginProps<TPluginsMap>\n\ntype ErrorOutputProps<TPluginsMap extends ErrorPluginsMap> = {\n [TKey in keyof TPluginsMap['props']]: TPluginsMap['props'][TKey]['resolve'] | undefined\n}\ntype ErrorOutputMethods<TPluginsMap extends ErrorPluginsMap> = {\n [TKey in keyof TPluginsMap['methods']]: TPluginsMap['methods'][TKey] extends {\n args: infer TArgs extends unknown[]\n output: infer TOutput\n }\n ? (...args: TArgs) => TOutput\n : never\n}\nexport type ErrorOutput<TPluginsMap extends ErrorPluginsMap> = ErrorOutputProps<TPluginsMap> &\n ErrorOutputMethods<TPluginsMap>\n\ntype ErrorStaticMethods<TPluginsMap extends ErrorPluginsMap> = {\n [TKey in keyof TPluginsMap['methods']]: TPluginsMap['methods'][TKey] extends {\n args: infer TArgs extends unknown[]\n output: infer TOutput\n }\n ? (error: unknown, ...args: TArgs) => TOutput\n : never\n}\n\ntype EmptyPluginsMap = {\n props: Record<never, { init: never; resolve: never }>\n methods: Record<never, ErrorMethodRecord>\n}\n\ntype ErrorPluginResolved = {\n props: Record<string, ErrorPluginPropOptions<unknown, unknown>>\n methods: Record<string, ErrorPluginMethodFn<unknown>>\n adapt: Array<ErrorPluginAdaptFn<Error0, Record<string, unknown>>>\n}\n\ntype PluginPropsMapOf<TPlugin extends ErrorPlugin> = {\n [TKey in keyof NonNullable<TPlugin['props']>]: NonNullable<TPlugin['props']>[TKey] extends ErrorPluginPropOptions<\n any,\n infer TOutputValue\n >\n ? { init: InferPluginPropInput<NonNullable<TPlugin['props']>[TKey]>; resolve: TOutputValue }\n : never\n}\ntype PluginMethodsMapOf<TPlugin extends ErrorPlugin> = {\n [TKey in keyof NonNullable<TPlugin['methods']>]: NonNullable<TPlugin['methods']>[TKey] extends (\n error: Error0,\n ...args: infer TArgs extends unknown[]\n ) => infer TOutput\n ? { args: TArgs; output: TOutput }\n : never\n}\ntype ErrorPluginsMapOfPlugin<TPlugin extends ErrorPlugin> = {\n props: PluginPropsMapOf<TPlugin>\n methods: PluginMethodsMapOf<TPlugin>\n}\ntype ExtendErrorPluginsMap<TMap extends ErrorPluginsMap, TPlugin extends ErrorPlugin> = {\n props: TMap['props'] & ErrorPluginsMapOfPlugin<TPlugin>['props']\n methods: TMap['methods'] & ErrorPluginsMapOfPlugin<TPlugin>['methods']\n}\ntype ExtendErrorPluginsMapWithProp<\n TMap extends ErrorPluginsMap,\n TKey extends string,\n TInputValue,\n TOutputValue,\n> = ExtendErrorPluginsMap<TMap, ErrorPlugin<Record<TKey, ErrorPluginPropOptions<TInputValue, TOutputValue>>>>\ntype ExtendErrorPluginsMapWithMethod<\n TMap extends ErrorPluginsMap,\n TKey extends string,\n TArgs extends unknown[],\n TOutputValue,\n> = ExtendErrorPluginsMap<\n TMap,\n ErrorPlugin<Record<never, never>, Record<TKey, ErrorPluginMethodFn<TOutputValue, TArgs>>>\n>\n\ntype PluginsMapOf<TClass> = TClass extends { __pluginsMap?: infer TPluginsMap }\n ? TPluginsMap extends ErrorPluginsMap\n ? TPluginsMap\n : EmptyPluginsMap\n : EmptyPluginsMap\n\ntype PluginsMapFromParts<\n TProps extends ErrorPluginProps,\n TMethods extends ErrorPluginMethods,\n> = ErrorPluginsMapOfPlugin<ErrorPlugin<TProps, TMethods>>\ntype ErrorInstanceOfMap<TMap extends ErrorPluginsMap> = Error0 & ErrorOutput<TMap>\ntype BuilderError0<TProps extends ErrorPluginProps, TMethods extends ErrorPluginMethods> = Error0 &\n ErrorOutput<PluginsMapFromParts<TProps, TMethods>>\n\ntype PluginOfBuilder<TBuilder> =\n TBuilder extends PluginError0<infer TProps, infer TMethods> ? ErrorPlugin<TProps, TMethods> : never\n\nexport class PluginError0<\n TProps extends ErrorPluginProps = Record<never, never>,\n TMethods extends ErrorPluginMethods = Record<never, never>,\n> {\n private readonly _plugin: ErrorPlugin<ErrorPluginProps, ErrorPluginMethods>\n\n readonly Infer = undefined as unknown as {\n props: TProps\n methods: TMethods\n }\n\n constructor(plugin?: ErrorPlugin<ErrorPluginProps, ErrorPluginMethods>) {\n this._plugin = {\n props: { ...(plugin?.props ?? {}) },\n methods: { ...(plugin?.methods ?? {}) },\n adapt: [...(plugin?.adapt ?? [])],\n }\n }\n\n prop<TKey extends string, TInputValue, TOutputValue>(\n key: TKey,\n value: ErrorPluginPropOptions<TInputValue, TOutputValue, BuilderError0<TProps, TMethods>>,\n ): PluginError0<AddPropToPluginProps<TProps, TKey, TInputValue, TOutputValue>, TMethods> {\n return this.use('prop', key, value)\n }\n\n method<TKey extends string, TArgs extends unknown[], TOutputValue>(\n key: TKey,\n value: ErrorPluginMethodFn<TOutputValue, TArgs, BuilderError0<TProps, TMethods>>,\n ): PluginError0<TProps, AddMethodToPluginMethods<TMethods, TKey, TArgs, TOutputValue>> {\n return this.use('method', key, value)\n }\n\n adapt(\n value: ErrorPluginAdaptFn<BuilderError0<TProps, TMethods>, PluginOutputProps<TProps>>,\n ): PluginError0<TProps, TMethods> {\n return this.use('adapt', value)\n }\n\n use<TKey extends string, TInputValue, TOutputValue>(\n kind: 'prop',\n key: TKey,\n value: ErrorPluginPropOptions<TInputValue, TOutputValue, BuilderError0<TProps, TMethods>>,\n ): PluginError0<AddPropToPluginProps<TProps, TKey, TInputValue, TOutputValue>, TMethods>\n use<TKey extends string, TArgs extends unknown[], TOutputValue>(\n kind: 'method',\n key: TKey,\n value: ErrorPluginMethodFn<TOutputValue, TArgs, BuilderError0<TProps, TMethods>>,\n ): PluginError0<TProps, AddMethodToPluginMethods<TMethods, TKey, TArgs, TOutputValue>>\n use(\n kind: 'adapt',\n value: ErrorPluginAdaptFn<BuilderError0<TProps, TMethods>, PluginOutputProps<TProps>>,\n ): PluginError0<TProps, TMethods>\n use(\n kind: 'prop' | 'method' | 'adapt',\n keyOrValue: string | ErrorPluginAdaptFn<any, any>,\n value?: ErrorPluginPropOptions<unknown, unknown, any> | ErrorPluginMethodFn<unknown, unknown[], any>,\n ): PluginError0<any, any> {\n const nextProps: ErrorPluginProps = { ...(this._plugin.props ?? {}) }\n const nextMethods: ErrorPluginMethods = { ...(this._plugin.methods ?? {}) }\n const nextAdapt: Array<ErrorPluginAdaptFn<Error0, Record<string, unknown>>> = [...(this._plugin.adapt ?? [])]\n if (kind === 'prop') {\n const key = keyOrValue as string\n if (value === undefined) {\n throw new Error('PluginError0.use(\"prop\", key, value) requires value')\n }\n nextProps[key] = value as ErrorPluginPropOptions<any, any>\n } else if (kind === 'method') {\n const key = keyOrValue as string\n if (value === undefined) {\n throw new Error('PluginError0.use(\"method\", key, value) requires value')\n }\n nextMethods[key] = value as ErrorPluginMethodFn<any, any[]>\n } else {\n nextAdapt.push(keyOrValue as ErrorPluginAdaptFn<Error0, Record<string, unknown>>)\n }\n return new PluginError0({\n props: nextProps,\n methods: nextMethods,\n adapt: nextAdapt,\n })\n }\n}\n\nexport type ClassError0<TPluginsMap extends ErrorPluginsMap = EmptyPluginsMap> = {\n new (message: string, input?: ErrorInput<TPluginsMap>): Error0 & ErrorOutput<TPluginsMap>\n new (input: { message: string } & ErrorInput<TPluginsMap>): Error0 & ErrorOutput<TPluginsMap>\n readonly __pluginsMap?: TPluginsMap\n from: (error: unknown) => Error0 & ErrorOutput<TPluginsMap>\n serialize: (error: unknown, isPublic?: boolean) => Record<string, unknown>\n prop: <TKey extends string, TInputValue, TOutputValue>(\n key: TKey,\n value: ErrorPluginPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<TPluginsMap>>,\n ) => ClassError0<ExtendErrorPluginsMapWithProp<TPluginsMap, TKey, TInputValue, TOutputValue>>\n method: <TKey extends string, TArgs extends unknown[], TOutputValue>(\n key: TKey,\n value: ErrorPluginMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<TPluginsMap>>,\n ) => ClassError0<ExtendErrorPluginsMapWithMethod<TPluginsMap, TKey, TArgs, TOutputValue>>\n adapt: (\n value: ErrorPluginAdaptFn<ErrorInstanceOfMap<TPluginsMap>, ErrorOutputProps<TPluginsMap>>,\n ) => ClassError0<TPluginsMap>\n use: {\n <TBuilder extends PluginError0>(\n plugin: TBuilder,\n ): ClassError0<ExtendErrorPluginsMap<TPluginsMap, PluginOfBuilder<TBuilder>>>\n <TKey extends string, TInputValue, TOutputValue>(\n kind: 'prop',\n key: TKey,\n value: ErrorPluginPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<TPluginsMap>>,\n ): ClassError0<ExtendErrorPluginsMapWithProp<TPluginsMap, TKey, TInputValue, TOutputValue>>\n <TKey extends string, TArgs extends unknown[], TOutputValue>(\n kind: 'method',\n key: TKey,\n value: ErrorPluginMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<TPluginsMap>>,\n ): ClassError0<ExtendErrorPluginsMapWithMethod<TPluginsMap, TKey, TArgs, TOutputValue>>\n (\n kind: 'adapt',\n value: ErrorPluginAdaptFn<ErrorInstanceOfMap<TPluginsMap>, ErrorOutputProps<TPluginsMap>>,\n ): ClassError0<TPluginsMap>\n }\n plugin: () => PluginError0\n} & ErrorStaticMethods<TPluginsMap>\n\nexport class Error0 extends Error {\n static readonly __pluginsMap?: EmptyPluginsMap\n protected static _plugins: ErrorPlugin[] = []\n\n private static readonly _emptyPlugin: ErrorPluginResolved = {\n props: {},\n methods: {},\n adapt: [],\n }\n\n private static _getResolvedPlugin(this: typeof Error0): ErrorPluginResolved {\n const resolved: ErrorPluginResolved = {\n props: {},\n methods: {},\n adapt: [],\n }\n for (const plugin of this._plugins) {\n Object.assign(resolved.props, plugin.props ?? this._emptyPlugin.props)\n Object.assign(resolved.methods, plugin.methods ?? this._emptyPlugin.methods)\n resolved.adapt.push(...(plugin.adapt ?? this._emptyPlugin.adapt))\n }\n return resolved\n }\n\n constructor(message: string, input?: ErrorInput<EmptyPluginsMap>)\n constructor(input: { message: string } & ErrorInput<EmptyPluginsMap>)\n constructor(\n ...args:\n | [message: string, input?: ErrorInput<EmptyPluginsMap>]\n | [{ message: string } & ErrorInput<EmptyPluginsMap>]\n ) {\n const [first, second] = args\n const input = typeof first === 'string' ? { message: first, ...(second ?? {}) } : first\n\n super(input.message, { cause: input.cause })\n this.name = 'Error0'\n\n const ctor = this.constructor as typeof Error0\n const plugin = ctor._getResolvedPlugin()\n\n for (const [key, prop] of Object.entries(plugin.props)) {\n if (key in input) {\n const ownValue = (input as Record<string, unknown>)[key]\n ;(this as Record<string, unknown>)[key] = prop.init(ownValue)\n } else {\n Object.defineProperty(this, key, {\n get: () => prop.resolve({ value: undefined, flow: this.flow(key), error: this }),\n set: (value) => {\n Object.defineProperty(this, key, {\n value,\n writable: true,\n enumerable: true,\n configurable: true,\n })\n },\n enumerable: true,\n configurable: true,\n })\n }\n }\n }\n\n private static readonly isSelfProperty = (object: object, key: string): boolean => {\n const d = Object.getOwnPropertyDescriptor(object, key)\n if (!d) return false\n if (typeof d.get === 'function' || typeof d.set === 'function') {\n if ('name' in object && object.name === 'Error0') {\n return false\n } else {\n return true\n }\n }\n return true\n }\n\n static own(error: object, key: string): unknown {\n if (this.isSelfProperty(error, key)) {\n return (error as Record<string, unknown>)[key]\n }\n return undefined\n }\n own(key: string): unknown {\n const ctor = this.constructor as typeof Error0\n return ctor.own(this, key)\n }\n\n static flow(error: object, key: string): unknown[] {\n return this.causes(error, true).map((cause) => {\n return this.own(cause, key)\n })\n }\n flow(key: string): unknown[] {\n const ctor = this.constructor as typeof Error0\n return ctor.flow(this, key)\n }\n\n static causes(error: unknown, instancesOnly?: false): unknown[]\n static causes<T extends typeof Error0>(this: T, error: unknown, instancesOnly: true): Array<InstanceType<T>>\n static causes(error: unknown, instancesOnly?: boolean): unknown[] {\n const causes: unknown[] = []\n let current: unknown = error\n const maxDepth = 99\n const seen = new Set<unknown>()\n for (let depth = 0; depth < maxDepth; depth += 1) {\n if (seen.has(current)) {\n break\n }\n seen.add(current)\n if (!instancesOnly || this.is(current)) {\n causes.push(current)\n }\n if (!current || typeof current !== 'object') {\n break\n }\n current = (current as { cause?: unknown }).cause\n }\n return causes\n }\n causes<T extends typeof Error0>(this: T, instancesOnly?: false): [InstanceType<T>, ...unknown[]]\n causes<T extends typeof Error0>(this: T, instancesOnly: true): [InstanceType<T>, ...Array<InstanceType<T>>]\n causes(instancesOnly?: boolean): unknown[] {\n const ctor = this.constructor as typeof Error0\n if (instancesOnly) {\n return ctor.causes(this, true)\n }\n return ctor.causes(this)\n }\n\n static is<T extends typeof Error0>(this: T, error: unknown): error is InstanceType<T> {\n return error instanceof this\n }\n\n static isSerialized(error: unknown): error is Record<string, unknown> {\n return !this.is(error) && typeof error === 'object' && error !== null && 'name' in error && error.name === 'Error0'\n }\n\n static from(error: unknown): Error0 {\n if (this.is(error)) {\n return error\n }\n if (this.isSerialized(error)) {\n return this._fromSerialized(error)\n }\n return this._fromNonError0(error)\n }\n\n private static _applyAdapt(error: Error0): Error0 {\n const plugin = this._getResolvedPlugin()\n for (const adapt of plugin.adapt) {\n const adapted = adapt(error as any)\n if (adapted && typeof adapted === 'object') {\n Object.assign(error as unknown as Record<string, unknown>, adapted)\n }\n }\n return error\n }\n\n private static _fromSerialized(error: unknown): Error0 {\n const message = this._extractMessage(error)\n if (typeof error !== 'object' || error === null) {\n return this._applyAdapt(new this(message, { cause: error }))\n }\n const errorRecord = error as Record<string, unknown>\n const recreated = new this(message)\n const plugin = this._getResolvedPlugin()\n const propsEntries = Object.entries(plugin.props)\n for (const [key, prop] of propsEntries) {\n if (prop.deserialize === false) {\n continue\n }\n if (!(key in errorRecord)) {\n continue\n }\n try {\n const value = prop.deserialize({ value: errorRecord[key], serialized: errorRecord })\n ;(recreated as unknown as Record<string, unknown>)[key] = value\n } catch {\n // ignore\n }\n }\n // we do not serialize causes\n // ;(recreated as unknown as { cause?: unknown }).cause = errorRecord.cause\n const isStackInProps = propsEntries.some(([key]) => key === 'stack')\n if (typeof errorRecord.stack === 'string' && !isStackInProps) {\n recreated.stack = errorRecord.stack\n }\n return recreated\n }\n\n private static _fromNonError0(error: unknown): Error0 {\n const message = this._extractMessage(error)\n return this._applyAdapt(new this(message, { cause: error }))\n }\n\n private static _extractMessage(error: unknown): string {\n return (\n (typeof error === 'string'\n ? error\n : typeof error === 'object' && error !== null && 'message' in error && typeof error.message === 'string'\n ? error.message\n : undefined) || 'Unknown error'\n )\n }\n\n private static _useWithPlugin(\n this: typeof Error0,\n plugin: ErrorPlugin<ErrorPluginProps, ErrorPluginMethods>,\n ): ClassError0 {\n const Base = this as unknown as typeof Error0\n const Error0Extended = class Error0 extends Base {}\n ;(Error0Extended as typeof Error0)._plugins = [...Base._plugins, plugin]\n\n const resolved = (Error0Extended as typeof Error0)._getResolvedPlugin()\n for (const [key, method] of Object.entries(resolved.methods)) {\n Object.defineProperty((Error0Extended as typeof Error0).prototype, key, {\n value: function (...args: unknown[]) {\n return method(this as Error0, ...args)\n },\n writable: true,\n enumerable: true,\n configurable: true,\n })\n Object.defineProperty(Error0Extended, key, {\n value: function (error: unknown, ...args: unknown[]) {\n return method(this.from(error), ...args)\n },\n writable: true,\n enumerable: true,\n configurable: true,\n })\n }\n\n return Error0Extended as unknown as ClassError0\n }\n\n private static _pluginFromBuilder(plugin: PluginError0): ErrorPlugin<ErrorPluginProps, ErrorPluginMethods> {\n const pluginRecord = plugin as unknown as {\n _plugin: ErrorPlugin<ErrorPluginProps, ErrorPluginMethods>\n }\n return {\n props: { ...(pluginRecord._plugin.props ?? {}) },\n methods: { ...(pluginRecord._plugin.methods ?? {}) },\n adapt: [...(pluginRecord._plugin.adapt ?? [])],\n }\n }\n\n static prop<TThis extends typeof Error0, TKey extends string, TInputValue, TOutputValue>(\n this: TThis,\n key: TKey,\n value: ErrorPluginPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<PluginsMapOf<TThis>>>,\n ): ClassError0<ExtendErrorPluginsMapWithProp<PluginsMapOf<TThis>, TKey, TInputValue, TOutputValue>> {\n return this.use('prop', key, value)\n }\n\n static method<TThis extends typeof Error0, TKey extends string, TArgs extends unknown[], TOutputValue>(\n this: TThis,\n key: TKey,\n value: ErrorPluginMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<PluginsMapOf<TThis>>>,\n ): ClassError0<ExtendErrorPluginsMapWithMethod<PluginsMapOf<TThis>, TKey, TArgs, TOutputValue>> {\n return this.use('method', key, value)\n }\n\n static adapt<TThis extends typeof Error0>(\n this: TThis,\n value: ErrorPluginAdaptFn<ErrorInstanceOfMap<PluginsMapOf<TThis>>, ErrorOutputProps<PluginsMapOf<TThis>>>,\n ): ClassError0<PluginsMapOf<TThis>> {\n return this.use('adapt', value)\n }\n\n static use<TThis extends typeof Error0, TBuilder extends PluginError0>(\n this: TThis,\n plugin: TBuilder,\n ): ClassError0<ExtendErrorPluginsMap<PluginsMapOf<TThis>, PluginOfBuilder<TBuilder>>>\n static use<TThis extends typeof Error0, TKey extends string, TInputValue, TOutputValue>(\n this: TThis,\n kind: 'prop',\n key: TKey,\n value: ErrorPluginPropOptions<TInputValue, TOutputValue, ErrorInstanceOfMap<PluginsMapOf<TThis>>>,\n ): ClassError0<ExtendErrorPluginsMapWithProp<PluginsMapOf<TThis>, TKey, TInputValue, TOutputValue>>\n static use<TThis extends typeof Error0, TKey extends string, TArgs extends unknown[], TOutputValue>(\n this: TThis,\n kind: 'method',\n key: TKey,\n value: ErrorPluginMethodFn<TOutputValue, TArgs, ErrorInstanceOfMap<PluginsMapOf<TThis>>>,\n ): ClassError0<ExtendErrorPluginsMapWithMethod<PluginsMapOf<TThis>, TKey, TArgs, TOutputValue>>\n static use<TThis extends typeof Error0>(\n this: TThis,\n kind: 'adapt',\n value: ErrorPluginAdaptFn<ErrorInstanceOfMap<PluginsMapOf<TThis>>, ErrorOutputProps<PluginsMapOf<TThis>>>,\n ): ClassError0<PluginsMapOf<TThis>>\n static use(\n this: typeof Error0,\n first: PluginError0 | 'prop' | 'method' | 'adapt',\n key?: string | ErrorPluginAdaptFn<any, any>,\n value?: ErrorPluginPropOptions<unknown, unknown> | ErrorPluginMethodFn<unknown>,\n ): ClassError0 {\n if (first instanceof PluginError0) {\n return this._useWithPlugin(this._pluginFromBuilder(first))\n }\n if (first === 'adapt') {\n if (typeof key !== 'function') {\n throw new Error('Error0.use(\"adapt\", value) requires adapt function')\n }\n return this._useWithPlugin({\n adapt: [key],\n })\n }\n if (typeof key !== 'string' || value === undefined) {\n throw new Error('Error0.use(kind, key, value) requires key and value')\n }\n\n if (first === 'prop') {\n return this._useWithPlugin({\n props: { [key]: value as ErrorPluginPropOptions<unknown, unknown> },\n })\n }\n return this._useWithPlugin({\n methods: { [key]: value as ErrorPluginMethodFn<unknown> },\n })\n }\n\n static plugin(): PluginError0 {\n return new PluginError0()\n }\n\n static serialize(error: unknown, isPublic = true): Record<string, unknown> {\n const error0 = this.from(error)\n const json: Record<string, unknown> = {\n name: error0.name,\n message: error0.message,\n // we do not serialize causes, it is enough that we have floated props and adapt helper\n // cause: error0.cause,\n }\n\n const plugin = this._getResolvedPlugin()\n const propsEntries = Object.entries(plugin.props)\n for (const [key, prop] of propsEntries) {\n if (prop.serialize === false) {\n continue\n }\n try {\n const value = prop.resolve({ value: error0.own(key), flow: error0.flow(key), error: error0 })\n const jsonValue = prop.serialize({ value, error: error0, isPublic })\n if (jsonValue !== undefined) {\n json[key] = jsonValue\n }\n } catch {\n // ignore\n }\n }\n const isStackInProps = propsEntries.some(([key]) => key === 'stack')\n if (!isStackInProps && typeof error0.stack === 'string') {\n json.stack = error0.stack\n }\n return Object.fromEntries(Object.entries(json).filter(([, value]) => value !== undefined)) as Record<\n string,\n unknown\n >\n }\n\n serialize(isPublic = true): object {\n const ctor = this.constructor as typeof Error0\n return ctor.serialize(this, isPublic)\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
package/src/index.test.ts
CHANGED
|
@@ -20,7 +20,7 @@ const fixStack = (stack: string | undefined) => {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
describe('Error0', () => {
|
|
23
|
-
const
|
|
23
|
+
const statusPlugin = Error0.plugin()
|
|
24
24
|
.prop('status', {
|
|
25
25
|
init: (input: number) => input,
|
|
26
26
|
resolve: ({ flow }) => flow.find(Boolean),
|
|
@@ -31,7 +31,7 @@ describe('Error0', () => {
|
|
|
31
31
|
|
|
32
32
|
const codes = ['NOT_FOUND', 'BAD_REQUEST', 'UNAUTHORIZED'] as const
|
|
33
33
|
type Code = (typeof codes)[number]
|
|
34
|
-
const
|
|
34
|
+
const codePlugin = Error0.plugin().use('prop', 'code', {
|
|
35
35
|
init: (input: Code) => input,
|
|
36
36
|
resolve: ({ flow }) => flow.find(Boolean),
|
|
37
37
|
serialize: ({ value, isPublic }) => (isPublic ? undefined : value),
|
|
@@ -52,8 +52,8 @@ describe('Error0', () => {
|
|
|
52
52
|
`)
|
|
53
53
|
})
|
|
54
54
|
|
|
55
|
-
it('with direct prop
|
|
56
|
-
const AppError = Error0.
|
|
55
|
+
it('with direct prop plugin', () => {
|
|
56
|
+
const AppError = Error0.use('prop', 'status', {
|
|
57
57
|
init: (input: number) => input,
|
|
58
58
|
resolve: ({ flow }) => flow.find(Boolean),
|
|
59
59
|
serialize: ({ value }) => value,
|
|
@@ -73,7 +73,7 @@ describe('Error0', () => {
|
|
|
73
73
|
expectTypeOf<typeof AppError>().toExtend<ClassError0>()
|
|
74
74
|
})
|
|
75
75
|
|
|
76
|
-
it('class helpers prop/method/
|
|
76
|
+
it('class helpers prop/method/adapt mirror use API', () => {
|
|
77
77
|
const AppError = Error0.prop('status', {
|
|
78
78
|
init: (value: number) => value,
|
|
79
79
|
resolve: ({ value, flow }) => {
|
|
@@ -83,7 +83,7 @@ describe('Error0', () => {
|
|
|
83
83
|
deserialize: ({ value }) => (typeof value === 'number' ? value : undefined),
|
|
84
84
|
})
|
|
85
85
|
.method('isStatus', (error, expectedStatus: number) => error.status === expectedStatus)
|
|
86
|
-
.
|
|
86
|
+
.adapt((error) => {
|
|
87
87
|
if (error.cause instanceof Error && error.status === undefined) {
|
|
88
88
|
return { status: 500 }
|
|
89
89
|
}
|
|
@@ -97,8 +97,8 @@ describe('Error0', () => {
|
|
|
97
97
|
expectTypeOf<typeof AppError>().toExtend<ClassError0>()
|
|
98
98
|
})
|
|
99
99
|
|
|
100
|
-
it('with defined
|
|
101
|
-
const AppError = Error0.
|
|
100
|
+
it('with defined plugin', () => {
|
|
101
|
+
const AppError = Error0.use(statusPlugin)
|
|
102
102
|
const error = new AppError('test', { status: 400 })
|
|
103
103
|
expect(error).toBeInstanceOf(AppError)
|
|
104
104
|
expect(error).toBeInstanceOf(Error0)
|
|
@@ -112,9 +112,9 @@ describe('Error0', () => {
|
|
|
112
112
|
`)
|
|
113
113
|
})
|
|
114
114
|
|
|
115
|
-
it('twice
|
|
116
|
-
const AppError1 = Error0.
|
|
117
|
-
const AppError2 = AppError1.
|
|
115
|
+
it('twice used Error0 extends previous by types', () => {
|
|
116
|
+
const AppError1 = Error0.use(statusPlugin)
|
|
117
|
+
const AppError2 = AppError1.use(codePlugin)
|
|
118
118
|
const error1 = new AppError1('test', { status: 400 })
|
|
119
119
|
const error2 = new AppError2('test', { status: 400, code: 'NOT_FOUND' })
|
|
120
120
|
expect(error1.status).toBe(400)
|
|
@@ -129,7 +129,7 @@ describe('Error0', () => {
|
|
|
129
129
|
})
|
|
130
130
|
|
|
131
131
|
it('can have cause', () => {
|
|
132
|
-
const AppError = Error0.
|
|
132
|
+
const AppError = Error0.use(statusPlugin)
|
|
133
133
|
const anotherError = new Error('another error')
|
|
134
134
|
const error = new AppError('test', { status: 400, cause: anotherError })
|
|
135
135
|
expect(error.status).toBe(400)
|
|
@@ -143,7 +143,7 @@ describe('Error0', () => {
|
|
|
143
143
|
})
|
|
144
144
|
|
|
145
145
|
it('can have many causes', () => {
|
|
146
|
-
const AppError = Error0.
|
|
146
|
+
const AppError = Error0.use(statusPlugin)
|
|
147
147
|
const anotherError = new Error('another error')
|
|
148
148
|
const error1 = new AppError('test1', { status: 400, cause: anotherError })
|
|
149
149
|
const error2 = new AppError('test2', { status: 400, cause: error1 })
|
|
@@ -153,7 +153,7 @@ describe('Error0', () => {
|
|
|
153
153
|
})
|
|
154
154
|
|
|
155
155
|
it('properties floating', () => {
|
|
156
|
-
const AppError = Error0.
|
|
156
|
+
const AppError = Error0.use(statusPlugin).use(codePlugin)
|
|
157
157
|
const anotherError = new Error('another error')
|
|
158
158
|
const error1 = new AppError('test1', { status: 400, cause: anotherError })
|
|
159
159
|
const error2 = new AppError('test2', { code: 'NOT_FOUND', cause: error1 })
|
|
@@ -164,8 +164,8 @@ describe('Error0', () => {
|
|
|
164
164
|
expect(Error0.causes(error2)).toEqual([error2, error1, anotherError])
|
|
165
165
|
})
|
|
166
166
|
|
|
167
|
-
it('serialize uses identity by default and skips undefined
|
|
168
|
-
const AppError = Error0.
|
|
167
|
+
it('serialize uses identity by default and skips undefined plugin values', () => {
|
|
168
|
+
const AppError = Error0.use(statusPlugin).prop('code', {
|
|
169
169
|
init: (input: string) => input,
|
|
170
170
|
resolve: ({ flow }) => flow.find(Boolean),
|
|
171
171
|
serialize: () => undefined,
|
|
@@ -177,14 +177,14 @@ describe('Error0', () => {
|
|
|
177
177
|
expect('code' in json).toBe(false)
|
|
178
178
|
})
|
|
179
179
|
|
|
180
|
-
it('serialize keeps stack by default without stack
|
|
181
|
-
const AppError = Error0.
|
|
180
|
+
it('serialize keeps stack by default without stack plugin', () => {
|
|
181
|
+
const AppError = Error0.use(statusPlugin)
|
|
182
182
|
const error = new AppError('test', { status: 500 })
|
|
183
183
|
const json = AppError.serialize(error)
|
|
184
184
|
expect(json.stack).toBe(error.stack)
|
|
185
185
|
})
|
|
186
186
|
|
|
187
|
-
it('stack
|
|
187
|
+
it('stack plugin can customize serialization of stack prop', () => {
|
|
188
188
|
const AppError = Error0.prop('stack', {
|
|
189
189
|
init: (input: string) => input,
|
|
190
190
|
resolve: ({ value }) => (typeof value === 'string' ? value : undefined),
|
|
@@ -196,8 +196,8 @@ describe('Error0', () => {
|
|
|
196
196
|
expect('stack' in json).toBe(false)
|
|
197
197
|
})
|
|
198
198
|
|
|
199
|
-
it('.serialize() -> .from() roundtrip keeps
|
|
200
|
-
const AppError = Error0.
|
|
199
|
+
it('.serialize() -> .from() roundtrip keeps plugin values', () => {
|
|
200
|
+
const AppError = Error0.use(statusPlugin).use(codePlugin)
|
|
201
201
|
const error = new AppError('test', { status: 409, code: 'NOT_FOUND' })
|
|
202
202
|
const json = AppError.serialize(error, false)
|
|
203
203
|
const recreated = AppError.from(json)
|
|
@@ -208,7 +208,7 @@ describe('Error0', () => {
|
|
|
208
208
|
})
|
|
209
209
|
|
|
210
210
|
it('.serialize() floated props and not serialize causes', () => {
|
|
211
|
-
const AppError = Error0.
|
|
211
|
+
const AppError = Error0.use(statusPlugin).use(codePlugin)
|
|
212
212
|
const error1 = new AppError('test', { status: 409 })
|
|
213
213
|
const error2 = new AppError('test', { code: 'NOT_FOUND', cause: error1 })
|
|
214
214
|
const json = AppError.serialize(error2, false)
|
|
@@ -218,7 +218,7 @@ describe('Error0', () => {
|
|
|
218
218
|
})
|
|
219
219
|
|
|
220
220
|
it('serialize can hide props for public output', () => {
|
|
221
|
-
const AppError = Error0.
|
|
221
|
+
const AppError = Error0.use(statusPlugin).use(codePlugin)
|
|
222
222
|
const error = new AppError('test', { status: 401, code: 'NOT_FOUND' })
|
|
223
223
|
const privateJson = AppError.serialize(error, false)
|
|
224
224
|
const publicJson = AppError.serialize(error, true)
|
|
@@ -226,6 +226,38 @@ describe('Error0', () => {
|
|
|
226
226
|
expect('code' in publicJson).toBe(false)
|
|
227
227
|
})
|
|
228
228
|
|
|
229
|
+
it('prop init without input arg infers undefined-only constructor input', () => {
|
|
230
|
+
const AppError = Error0.prop('computed', {
|
|
231
|
+
init: () => undefined as number | undefined,
|
|
232
|
+
resolve: ({ flow }) => flow.find((item) => typeof item === 'number'),
|
|
233
|
+
serialize: ({ value }) => value,
|
|
234
|
+
deserialize: ({ value }) => (typeof value === 'number' ? value : undefined),
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
const error = new AppError('test')
|
|
238
|
+
expect(error.computed).toBe(undefined)
|
|
239
|
+
expectTypeOf<typeof error.computed>().toEqualTypeOf<number | undefined>()
|
|
240
|
+
|
|
241
|
+
// @ts-expect-error - computed input is disallowed when init has no input arg
|
|
242
|
+
// eslint-disable-next-line no-new
|
|
243
|
+
new AppError('test', { computed: 123 })
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
it('serialize/deserialize can be set to false to disable them', () => {
|
|
247
|
+
const AppError = Error0.prop('status', {
|
|
248
|
+
init: (input: number) => input,
|
|
249
|
+
resolve: ({ value, flow }) => value ?? flow.find((item) => typeof item === 'number'),
|
|
250
|
+
serialize: false,
|
|
251
|
+
deserialize: false,
|
|
252
|
+
})
|
|
253
|
+
const error = new AppError('test', { status: 401 })
|
|
254
|
+
const json = AppError.serialize(error)
|
|
255
|
+
expect('status' in json).toBe(false)
|
|
256
|
+
|
|
257
|
+
const recreated = AppError.from({ ...json, status: 999 })
|
|
258
|
+
expect(recreated.status).toBe(undefined)
|
|
259
|
+
})
|
|
260
|
+
|
|
229
261
|
it('by default error0 created from another error has same message', () => {
|
|
230
262
|
const schema = z.object({
|
|
231
263
|
x: z.string(),
|
|
@@ -237,16 +269,16 @@ describe('Error0', () => {
|
|
|
237
269
|
expect(error.message).toBe(parsedError.message)
|
|
238
270
|
})
|
|
239
271
|
|
|
240
|
-
it('
|
|
272
|
+
it('adapt message and other props via direct transformations', () => {
|
|
241
273
|
const schema = z.object({
|
|
242
274
|
x: z.string(),
|
|
243
275
|
})
|
|
244
276
|
const parseResult = schema.safeParse({ x: 123 })
|
|
245
277
|
const parsedError = parseResult.error
|
|
246
278
|
assert.ok(parsedError)
|
|
247
|
-
const AppError = Error0.
|
|
248
|
-
.
|
|
249
|
-
.
|
|
279
|
+
const AppError = Error0.use(statusPlugin)
|
|
280
|
+
.use(codePlugin)
|
|
281
|
+
.use('adapt', (error) => {
|
|
250
282
|
if (error.cause instanceof ZodError) {
|
|
251
283
|
error.status = 422
|
|
252
284
|
error.code = 'NOT_FOUND'
|
|
@@ -263,16 +295,16 @@ describe('Error0', () => {
|
|
|
263
295
|
expect(error1.code).toBe(undefined)
|
|
264
296
|
})
|
|
265
297
|
|
|
266
|
-
it('
|
|
298
|
+
it('adapt message and other props via return output values from plugin', () => {
|
|
267
299
|
const schema = z.object({
|
|
268
300
|
x: z.string(),
|
|
269
301
|
})
|
|
270
302
|
const parseResult = schema.safeParse({ x: 123 })
|
|
271
303
|
const parsedError = parseResult.error
|
|
272
304
|
assert.ok(parsedError)
|
|
273
|
-
const AppError = Error0.
|
|
274
|
-
.
|
|
275
|
-
.
|
|
305
|
+
const AppError = Error0.use(statusPlugin)
|
|
306
|
+
.use(codePlugin)
|
|
307
|
+
.adapt((error) => {
|
|
276
308
|
if (error.cause instanceof ZodError) {
|
|
277
309
|
error.message = `Validation Error: ${error.message}`
|
|
278
310
|
return {
|
|
@@ -293,7 +325,7 @@ describe('Error0', () => {
|
|
|
293
325
|
})
|
|
294
326
|
|
|
295
327
|
it('expected prop can be realized to send or not to send error to your error tracker', () => {
|
|
296
|
-
const AppError = Error0.
|
|
328
|
+
const AppError = Error0.use(statusPlugin)
|
|
297
329
|
.prop('expected', {
|
|
298
330
|
init: (input: boolean) => input,
|
|
299
331
|
resolve: ({ flow }) => flow.find((value) => typeof value === 'boolean'),
|
|
@@ -322,13 +354,13 @@ describe('Error0', () => {
|
|
|
322
354
|
|
|
323
355
|
// we will have no variants
|
|
324
356
|
// becouse you can thorw any errorm and when you do AppError.from(yourError)
|
|
325
|
-
// can use
|
|
357
|
+
// can use adapt to assign desired props to error, it is enough for transport
|
|
326
358
|
// you even can create computed or method to retrieve your error, so no problems with variants
|
|
327
359
|
|
|
328
360
|
// it('can create and recongnize variant', () => {
|
|
329
|
-
// const AppError = Error0.
|
|
330
|
-
// .
|
|
331
|
-
// .
|
|
361
|
+
// const AppError = Error0.use(statusPlugin)
|
|
362
|
+
// .use(codePlugin)
|
|
363
|
+
// .use('prop', 'userId', {
|
|
332
364
|
// input: (value: string) => value,
|
|
333
365
|
// output: (error) => {
|
|
334
366
|
// for (const value of error.flow('userId')) {
|