awaitly 1.34.0 → 2.0.0
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/{duration.d.ts → di-BDlT7InM.d.cts} +15 -1
- package/dist/{duration.d.cts → di-BbFFfO8y.d.ts} +15 -1
- package/dist/errors-DtXvrCiO.d.cts +708 -0
- package/dist/errors-DtXvrCiO.d.ts +708 -0
- package/dist/index.cjs +4594 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1970 -141
- package/dist/index.d.ts +1970 -141
- package/dist/index.js +4398 -1
- package/dist/index.js.map +1 -1
- package/dist/result.cjs +641 -1
- package/dist/result.cjs.map +1 -1
- package/dist/result.d.cts +35 -5
- package/dist/result.d.ts +35 -5
- package/dist/result.js +561 -1
- package/dist/result.js.map +1 -1
- package/dist/testing.cjs +4202 -8
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +2 -6
- package/dist/testing.d.ts +2 -6
- package/dist/testing.js +4154 -8
- package/dist/testing.js.map +1 -1
- package/dist/{run-entry-D2MmJFj9.d.cts → types-B8NfNRGX.d.ts} +1152 -1499
- package/dist/{run-entry-Dduz-is2.d.ts → types-BZ2f4MRR.d.cts} +1152 -1499
- package/dist/workflow.cjs +7096 -6
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +3346 -22
- package/dist/workflow.d.ts +3346 -22
- package/dist/workflow.js +6929 -6
- package/dist/workflow.js.map +1 -1
- package/package.json +13 -178
- package/dist/adapters.cjs +0 -7
- package/dist/adapters.cjs.map +0 -1
- package/dist/adapters.d.cts +0 -179
- package/dist/adapters.d.ts +0 -179
- package/dist/adapters.js +0 -7
- package/dist/adapters.js.map +0 -1
- package/dist/batch.cjs +0 -7
- package/dist/batch.cjs.map +0 -1
- package/dist/batch.d.cts +0 -200
- package/dist/batch.d.ts +0 -200
- package/dist/batch.js +0 -7
- package/dist/batch.js.map +0 -1
- package/dist/bind-deps.cjs +0 -2
- package/dist/bind-deps.cjs.map +0 -1
- package/dist/bind-deps.d.cts +0 -28
- package/dist/bind-deps.d.ts +0 -28
- package/dist/bind-deps.js +0 -2
- package/dist/bind-deps.js.map +0 -1
- package/dist/cache.cjs +0 -2
- package/dist/cache.cjs.map +0 -1
- package/dist/cache.d.cts +0 -269
- package/dist/cache.d.ts +0 -269
- package/dist/cache.js +0 -2
- package/dist/cache.js.map +0 -1
- package/dist/circuit-breaker.cjs +0 -7
- package/dist/circuit-breaker.cjs.map +0 -1
- package/dist/circuit-breaker.d.cts +0 -211
- package/dist/circuit-breaker.d.ts +0 -211
- package/dist/circuit-breaker.js +0 -7
- package/dist/circuit-breaker.js.map +0 -1
- package/dist/conditional.cjs +0 -2
- package/dist/conditional.cjs.map +0 -1
- package/dist/conditional.d.cts +0 -252
- package/dist/conditional.d.ts +0 -252
- package/dist/conditional.js +0 -2
- package/dist/conditional.js.map +0 -1
- package/dist/core.cjs +0 -7
- package/dist/core.cjs.map +0 -1
- package/dist/core.d.cts +0 -5
- package/dist/core.d.ts +0 -5
- package/dist/core.js +0 -7
- package/dist/core.js.map +0 -1
- package/dist/di-COl5oFnR.d.cts +0 -15
- package/dist/di-CyDj_JyZ.d.ts +0 -15
- package/dist/diagnostics.cjs +0 -8
- package/dist/diagnostics.cjs.map +0 -1
- package/dist/diagnostics.d.cts +0 -68
- package/dist/diagnostics.d.ts +0 -68
- package/dist/diagnostics.js +0 -8
- package/dist/diagnostics.js.map +0 -1
- package/dist/durable.cjs +0 -11
- package/dist/durable.cjs.map +0 -1
- package/dist/durable.d.cts +0 -9
- package/dist/durable.d.ts +0 -9
- package/dist/durable.js +0 -11
- package/dist/durable.js.map +0 -1
- package/dist/duration.cjs +0 -2
- package/dist/duration.cjs.map +0 -1
- package/dist/duration.js +0 -2
- package/dist/duration.js.map +0 -1
- package/dist/engine.cjs +0 -11
- package/dist/engine.cjs.map +0 -1
- package/dist/engine.d.cts +0 -115
- package/dist/engine.d.ts +0 -115
- package/dist/engine.js +0 -11
- package/dist/engine.js.map +0 -1
- package/dist/errors.cjs +0 -2
- package/dist/errors.cjs.map +0 -1
- package/dist/errors.d.cts +0 -361
- package/dist/errors.d.ts +0 -361
- package/dist/errors.js +0 -2
- package/dist/errors.js.map +0 -1
- package/dist/fetch.cjs +0 -7
- package/dist/fetch.cjs.map +0 -1
- package/dist/fetch.d.cts +0 -86
- package/dist/fetch.d.ts +0 -86
- package/dist/fetch.js +0 -7
- package/dist/fetch.js.map +0 -1
- package/dist/flow.cjs +0 -7
- package/dist/flow.cjs.map +0 -1
- package/dist/flow.d.cts +0 -163
- package/dist/flow.d.ts +0 -163
- package/dist/flow.js +0 -7
- package/dist/flow.js.map +0 -1
- package/dist/functional.cjs +0 -2
- package/dist/functional.cjs.map +0 -1
- package/dist/functional.d.cts +0 -444
- package/dist/functional.d.ts +0 -444
- package/dist/functional.js +0 -2
- package/dist/functional.js.map +0 -1
- package/dist/guards-BodHXLzX.d.cts +0 -72
- package/dist/guards-CeWoQ8fn.d.ts +0 -72
- package/dist/hitl-BPE_1UiM.d.cts +0 -468
- package/dist/hitl-byp570uC.d.ts +0 -468
- package/dist/hitl.cjs +0 -7
- package/dist/hitl.cjs.map +0 -1
- package/dist/hitl.d.cts +0 -442
- package/dist/hitl.d.ts +0 -442
- package/dist/hitl.js +0 -7
- package/dist/hitl.js.map +0 -1
- package/dist/index-BYT3amEz.d.ts +0 -417
- package/dist/index-C_ak66jy.d.cts +0 -417
- package/dist/match-entry-DjI2bLpD.d.cts +0 -209
- package/dist/match-entry-DjI2bLpD.d.ts +0 -209
- package/dist/match.cjs +0 -2
- package/dist/match.cjs.map +0 -1
- package/dist/match.d.cts +0 -1
- package/dist/match.d.ts +0 -1
- package/dist/match.js +0 -2
- package/dist/match.js.map +0 -1
- package/dist/otel.cjs +0 -2
- package/dist/otel.cjs.map +0 -1
- package/dist/otel.d.cts +0 -188
- package/dist/otel.d.ts +0 -188
- package/dist/otel.js +0 -2
- package/dist/otel.js.map +0 -1
- package/dist/persistence-entry-DOMx3woy.d.ts +0 -822
- package/dist/persistence-entry-ymCA4iDu.d.cts +0 -822
- package/dist/persistence.cjs +0 -2
- package/dist/persistence.cjs.map +0 -1
- package/dist/persistence.d.cts +0 -7
- package/dist/persistence.d.ts +0 -7
- package/dist/persistence.js +0 -2
- package/dist/persistence.js.map +0 -1
- package/dist/policies.cjs +0 -2
- package/dist/policies.cjs.map +0 -1
- package/dist/policies.d.cts +0 -379
- package/dist/policies.d.ts +0 -379
- package/dist/policies.js +0 -2
- package/dist/policies.js.map +0 -1
- package/dist/ratelimit.cjs +0 -7
- package/dist/ratelimit.cjs.map +0 -1
- package/dist/ratelimit.d.cts +0 -458
- package/dist/ratelimit.d.ts +0 -458
- package/dist/ratelimit.js +0 -7
- package/dist/ratelimit.js.map +0 -1
- package/dist/reliability.cjs +0 -11
- package/dist/reliability.cjs.map +0 -1
- package/dist/reliability.d.cts +0 -11
- package/dist/reliability.d.ts +0 -11
- package/dist/reliability.js +0 -11
- package/dist/reliability.js.map +0 -1
- package/dist/resolver.cjs +0 -7
- package/dist/resolver.cjs.map +0 -1
- package/dist/resolver.d.cts +0 -68
- package/dist/resolver.d.ts +0 -68
- package/dist/resolver.js +0 -7
- package/dist/resolver.js.map +0 -1
- package/dist/resource.cjs +0 -7
- package/dist/resource.cjs.map +0 -1
- package/dist/resource.d.cts +0 -174
- package/dist/resource.d.ts +0 -174
- package/dist/resource.js +0 -7
- package/dist/resource.js.map +0 -1
- package/dist/result/retry.cjs +0 -2
- package/dist/result/retry.cjs.map +0 -1
- package/dist/result/retry.d.cts +0 -70
- package/dist/result/retry.d.ts +0 -70
- package/dist/result/retry.js +0 -2
- package/dist/result/retry.js.map +0 -1
- package/dist/retry.cjs +0 -2
- package/dist/retry.cjs.map +0 -1
- package/dist/retry.d.cts +0 -388
- package/dist/retry.d.ts +0 -388
- package/dist/retry.js +0 -2
- package/dist/retry.js.map +0 -1
- package/dist/run.cjs +0 -7
- package/dist/run.cjs.map +0 -1
- package/dist/run.d.cts +0 -4
- package/dist/run.d.ts +0 -4
- package/dist/run.js +0 -7
- package/dist/run.js.map +0 -1
- package/dist/saga.cjs +0 -11
- package/dist/saga.cjs.map +0 -1
- package/dist/saga.d.cts +0 -164
- package/dist/saga.d.ts +0 -164
- package/dist/saga.js +0 -11
- package/dist/saga.js.map +0 -1
- package/dist/singleflight.cjs +0 -2
- package/dist/singleflight.cjs.map +0 -1
- package/dist/singleflight.d.cts +0 -145
- package/dist/singleflight.d.ts +0 -145
- package/dist/singleflight.js +0 -2
- package/dist/singleflight.js.map +0 -1
- package/dist/slugs.cjs +0 -2
- package/dist/slugs.cjs.map +0 -1
- package/dist/slugs.d.cts +0 -67
- package/dist/slugs.d.ts +0 -67
- package/dist/slugs.js +0 -2
- package/dist/slugs.js.map +0 -1
- package/dist/streaming.cjs +0 -9
- package/dist/streaming.cjs.map +0 -1
- package/dist/streaming.d.cts +0 -596
- package/dist/streaming.d.ts +0 -596
- package/dist/streaming.js +0 -9
- package/dist/streaming.js.map +0 -1
- package/dist/tagged-error.cjs +0 -2
- package/dist/tagged-error.cjs.map +0 -1
- package/dist/tagged-error.d.cts +0 -275
- package/dist/tagged-error.d.ts +0 -275
- package/dist/tagged-error.js +0 -2
- package/dist/tagged-error.js.map +0 -1
- package/dist/types-DQmzO9f4.d.ts +0 -323
- package/dist/types-qBUOYi-4.d.cts +0 -323
- package/dist/webhook.cjs +0 -7
- package/dist/webhook.cjs.map +0 -1
- package/dist/webhook.d.cts +0 -499
- package/dist/webhook.d.ts +0 -499
- package/dist/webhook.js +0 -7
- package/dist/webhook.js.map +0 -1
package/dist/tagged-error.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";var d=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var k=(r,e)=>{for(var n in e)d(r,n,{get:e[n],enumerable:!0})},_=(r,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of x(e))!h.call(r,a)&&a!==n&&d(r,a,{get:()=>e[a],enumerable:!(o=m(e,a))||o.enumerable});return r};var b=r=>_(d({},"__esModule",{value:!0}),r);var H={};k(H,{TaggedError:()=>c});module.exports=b(H);var P={"step-require-id":"step-require-id","step-no-immediate-execution":"step-no-immediate-execution","step-require-thunk-for-key":"step-require-thunk-for-key","step-no-bare-await":"step-no-bare-await","step-no-try-catch-wrap":"step-no-try-catch-wrap","step-stable-cache-keys":"step-stable-cache-keys","workflow-no-floating":"workflow-no-floating","workflow-options-position":"workflow-options-position","workflow-callback-shape":"workflow-callback-shape","workflow-no-callable-form":"workflow-no-callable-form","workflow-no-dynamic-import":"workflow-no-dynamic-import","result-no-floating":"result-no-floating","result-require-handling":"result-require-handling","result-no-double-wrap":"result-no-double-wrap","result-no-manual-propagation":"result-no-manual-propagation","result-no-direct-ok-err":"result-no-direct-ok-err","error-check-unexpected-first":"error-check-unexpected-first","error-access-cause":"error-access-cause","error-normalize":"error-normalize","error-no-throw-in-deps":"error-no-throw-in-deps","concurrency-no-promise-all":"concurrency-no-promise-all","concurrency-no-promise-race":"concurrency-no-promise-race","concurrency-no-promise-allsettled":"concurrency-no-promise-allsettled","runtime-step-timeout":"runtime-step-timeout","runtime-step-aborted":"runtime-step-aborted","runtime-retry-exhausted":"runtime-retry-exhausted","runtime-rate-limit":"runtime-rate-limit","runtime-circuit-open":"runtime-circuit-open","runtime-unexpected":"runtime-unexpected","runtime-resolver-not-found":"runtime-resolver-not-found","runtime-saga-compensation":"runtime-saga-compensation"};function y(r){return`https://jagreehal.github.io/awaitly/rules/#${r}`}var S=Object.keys(P);var u=class extends Error{_tag};function c(r,e){return class extends u{_tag=r;constructor(n,o){let a=e?.message?e.message(n??{}):r;if(super(a),this.name=r,e?.slug!==void 0){if(!e.hint)throw new TypeError(`TaggedError: 'hint' is required when 'slug' is set (slug: "${e.slug}")`);Object.defineProperty(this,"code",{value:e.slug,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"hint",{value:e.hint,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"docsUrl",{value:y(e.slug),enumerable:!0,writable:!1,configurable:!1})}if(Object.setPrototypeOf(this,new.target.prototype),n&&typeof n=="object"){let t;if(e?.slug!==void 0){let{_tag:l,name:f,message:w,stack:E,code:p,hint:O,docsUrl:A,...T}=n;t=T}else{let{_tag:l,name:f,message:w,stack:E,...p}=n;t=p}let s=Object.prototype.hasOwnProperty.call(t,"cause"),g=s?t.cause:void 0;s&&delete t.cause;let i=o?.cause!==void 0;if(s&&i)throw new TypeError("TaggedError: cannot provide 'cause' in props when also setting ErrorOptions.cause");Object.assign(this,t),s&&(this.cause=g),i&&(this.cause=o?.cause)}else o?.cause!==void 0&&(this.cause=o.cause)}}}Object.defineProperty(c,Symbol.hasInstance,{value:r=>r instanceof u});(a=>{function r(t){return t instanceof Error}a.isError=r;function e(t){return t instanceof u}a.isTaggedError=e;function n(t,s){let g=t._tag,i=s[g];return i(t)}a.match=n;function o(t,s,g){let i=t._tag,l=s[i];return l?l(t):g(t)}a.matchPartial=o})(c||={});0&&(module.exports={TaggedError});
|
|
2
|
-
//# sourceMappingURL=tagged-error.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tagged-error-entry.ts","../src/slugs.ts","../src/tagged-error.ts"],"sourcesContent":["/**\n * awaitly/tagged-error\n *\n * Tagged error classes: type-safe errors with discriminated unions.\n *\n * @example\n * ```typescript\n * import { TaggedError, type TagOf, type PropsOf } from 'awaitly/tagged-error';\n *\n * class UserNotFound extends TaggedError('UserNotFound')<{ userId: string }> {}\n * class InsufficientFunds extends TaggedError('InsufficientFunds', {\n * message: (p: { required: number; available: number }) =>\n * `Need ${p.required}, have ${p.available}`,\n * }) {}\n *\n * const error = new UserNotFound({ userId: '123' });\n * error._tag // 'UserNotFound'\n * error.userId // '123'\n * ```\n */\n\nexport {\n // Factory function\n TaggedError,\n\n // Types\n type TaggedErrorBase,\n type TaggedErrorOptions,\n type TaggedErrorCreateOptions,\n type TaggedErrorConstructor,\n\n // Type utilities\n type TagOf,\n type ErrorByTag,\n type PropsOf,\n} from \"./tagged-error\";\n","/**\n * awaitly/slugs\n *\n * Source-of-truth slug namespace. Every concept that surfaces as a runtime\n * error, lint rule, static-analyzer diagnostic, visualizer event, or skill rule\n * has exactly one canonical kebab-case slug here.\n *\n * Slugs are public API. Renames are a major version bump. Adds are non-breaking.\n *\n * Categories:\n * - step-* step() discipline\n * - workflow-* createWorkflow / run / runWithState shape\n * - result-* Result usage\n * - error-* Boundary handling\n * - concurrency-* step.all/map/race vs Promise.*\n * - runtime-* Failures only observable at runtime\n */\n\nexport const AWAITLY_SLUGS = {\n // --- step-* ---\n \"step-require-id\": \"step-require-id\",\n \"step-no-immediate-execution\": \"step-no-immediate-execution\",\n \"step-require-thunk-for-key\": \"step-require-thunk-for-key\",\n \"step-no-bare-await\": \"step-no-bare-await\",\n \"step-no-try-catch-wrap\": \"step-no-try-catch-wrap\",\n \"step-stable-cache-keys\": \"step-stable-cache-keys\",\n\n // --- workflow-* ---\n \"workflow-no-floating\": \"workflow-no-floating\",\n \"workflow-options-position\": \"workflow-options-position\",\n \"workflow-callback-shape\": \"workflow-callback-shape\",\n \"workflow-no-callable-form\": \"workflow-no-callable-form\",\n \"workflow-no-dynamic-import\": \"workflow-no-dynamic-import\",\n\n // --- result-* ---\n \"result-no-floating\": \"result-no-floating\",\n \"result-require-handling\": \"result-require-handling\",\n \"result-no-double-wrap\": \"result-no-double-wrap\",\n \"result-no-manual-propagation\": \"result-no-manual-propagation\",\n \"result-no-direct-ok-err\": \"result-no-direct-ok-err\",\n\n // --- error-* ---\n \"error-check-unexpected-first\": \"error-check-unexpected-first\",\n \"error-access-cause\": \"error-access-cause\",\n \"error-normalize\": \"error-normalize\",\n \"error-no-throw-in-deps\": \"error-no-throw-in-deps\",\n\n // --- concurrency-* ---\n \"concurrency-no-promise-all\": \"concurrency-no-promise-all\",\n \"concurrency-no-promise-race\": \"concurrency-no-promise-race\",\n \"concurrency-no-promise-allsettled\": \"concurrency-no-promise-allsettled\",\n\n // --- runtime-* ---\n \"runtime-step-timeout\": \"runtime-step-timeout\",\n \"runtime-step-aborted\": \"runtime-step-aborted\",\n \"runtime-retry-exhausted\": \"runtime-retry-exhausted\",\n \"runtime-rate-limit\": \"runtime-rate-limit\",\n \"runtime-circuit-open\": \"runtime-circuit-open\",\n \"runtime-unexpected\": \"runtime-unexpected\",\n \"runtime-resolver-not-found\": \"runtime-resolver-not-found\",\n \"runtime-saga-compensation\": \"runtime-saga-compensation\",\n} as const;\n\n/** All canonical awaitly slugs as a string-literal union. */\nexport type AwaitlySlug = keyof typeof AWAITLY_SLUGS;\n\n/** Categories derived from slug prefixes. */\nexport type AwaitlySlugCategory =\n | \"step\"\n | \"workflow\"\n | \"result\"\n | \"error\"\n | \"concurrency\"\n | \"runtime\";\n\n/** Returns the category (prefix) of a slug. */\nexport function slugCategory(slug: AwaitlySlug): AwaitlySlugCategory {\n return slug.split(\"-\")[0] as AwaitlySlugCategory;\n}\n\n/**\n * Returns the canonical docs URL for a slug. Resolves to the matching\n * anchored section on the consolidated rule index page.\n */\nexport function slugDocsUrl(slug: AwaitlySlug): string {\n return `https://jagreehal.github.io/awaitly/rules/#${slug}`;\n}\n\n/** Type guard: is a string a known awaitly slug? */\nexport function isAwaitlySlug(value: string): value is AwaitlySlug {\n return Object.prototype.hasOwnProperty.call(AWAITLY_SLUGS, value);\n}\n\n/** All slugs as an array. */\n// Object.keys returns string[] — cast is safe because AWAITLY_SLUGS is `as const`\n// and the module's keys are never mutated.\nexport const ALL_SLUGS: readonly AwaitlySlug[] = Object.keys(\n AWAITLY_SLUGS\n) as AwaitlySlug[];\n","/**\n * awaitly/tagged-error\n *\n * Factory for creating tagged error types with exhaustive pattern matching.\n * Enables TypeScript to enforce that all error variants are handled.\n *\n * @example\n * ```typescript\n * // Define error types (Props via generic)\n * class NotFoundError extends TaggedError(\"NotFoundError\")<{\n * id: string;\n * resource: string;\n * }> {}\n *\n * // Define with type-safe message (Props inferred from callback annotation)\n * class ValidationError extends TaggedError(\"ValidationError\", {\n * message: (p: { field: string; reason: string }) => `Invalid ${p.field}: ${p.reason}`,\n * }) {}\n *\n * // Create instances\n * const error = new NotFoundError({ id: \"123\", resource: \"User\" });\n *\n * // Runtime type check: instanceof TaggedError works!\n * console.log(error instanceof TaggedError); // true\n *\n * // Exhaustive matching\n * type AppError = NotFoundError | ValidationError;\n * const message = TaggedError.match(error as AppError, {\n * NotFoundError: (e) => `Missing: ${e.resource} ${e.id}`,\n * ValidationError: (e) => `Invalid ${e.field}: ${e.reason}`,\n * });\n * ```\n */\n\nimport { type AwaitlySlug, slugDocsUrl } from \"./slugs\";\n\n/**\n * Options for Error constructor (compatible with ES2022 ErrorOptions).\n */\nexport interface TaggedErrorOptions {\n cause?: unknown;\n}\n\n/**\n * Options for TaggedError factory with type-safe message callback.\n */\nexport interface TaggedErrorCreateOptions<Props extends Record<string, unknown>> {\n /** Custom message generator from props. Annotate parameter for type safety. */\n message: (props: Props) => string;\n /**\n * Canonical awaitly slug for this error class. When set, instances carry\n * `code`, `hint`, and `docsUrl` populated from the slugs namespace.\n * Required together with `hint` for awaitly-system errors.\n */\n slug?: AwaitlySlug;\n /**\n * One-line \"do X instead\" guidance shown alongside the error.\n * Required when `slug` is set.\n */\n hint?: string;\n}\n\n/**\n * Base interface for all tagged errors.\n */\nexport interface TaggedErrorBase extends Error {\n readonly _tag: string;\n /** Canonical slug for awaitly-system errors. Undefined for user errors that opt out. */\n readonly code?: AwaitlySlug;\n /** One-line guidance. Undefined when no slug is set. */\n readonly hint?: string;\n /** Canonical docs URL. Undefined when no slug is set. */\n readonly docsUrl?: string;\n}\n\n/**\n * Internal base class for instanceof checks.\n * All TaggedError-created classes extend this.\n * @internal\n */\nclass InternalTaggedErrorBase extends Error implements TaggedErrorBase {\n readonly _tag!: string;\n}\n\n/**\n * Instance type for factory-created TaggedErrors.\n */\ntype TaggedErrorInstance<Tag extends string, Props> = TaggedErrorBase & {\n readonly _tag: Tag;\n} & Readonly<Props>;\n\n/**\n * Constructor args type - conditionally optional based on whether Props has required fields.\n * - If Props is empty or all properties are optional: props argument is optional\n * - If Props has any required properties: props argument is required\n * @internal\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\ntype ConstructorArgs<Props extends Record<string, unknown>> = {} extends Props\n ? [props?: Props | void, options?: TaggedErrorOptions]\n : [props: Props, options?: TaggedErrorOptions];\n\n/**\n * Constructor type returned by TaggedError factory.\n */\nexport interface TaggedErrorConstructor<\n Tag extends string,\n Props extends Record<string, unknown>,\n> {\n new (...args: ConstructorArgs<Props>): TaggedErrorInstance<Tag, Props>;\n readonly prototype: TaggedErrorInstance<Tag, Props>;\n}\n\n/**\n * Generic class factory type that allows `<Props>` parameterization.\n * This enables the Effect.js-style syntax: `class X extends TaggedError(\"X\")<Props> {}`\n * @internal\n */\nexport interface TaggedErrorClassFactory<Tag extends string> {\n new <Props extends Record<string, unknown> = Record<string, never>>(\n ...args: ConstructorArgs<Props>\n ): TaggedErrorInstance<Tag, Props>;\n}\n\n/**\n * Helper type to extract return type from a function type.\n * @internal\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype FnReturnType<T> = T extends (...args: any[]) => infer R ? R : never;\n\n/**\n * Helper type to get union of return types from all handlers.\n * @internal\n */\ntype HandlersReturnType<H> = { [K in keyof H]: FnReturnType<H[K]> }[keyof H];\n\n/**\n * Helper type to extract keys whose values are definitely functions (not undefined).\n * Only excludes a tag from the fallback type if its handler is guaranteed to be\n * a function. Keys where the value type includes undefined are NOT excluded,\n * ensuring type safety with dynamic/conditional handlers.\n * @internal\n */\ntype DefinitelyHandledKeys<H> = {\n [K in keyof H]-?: undefined extends H[K] ? never : K;\n}[keyof H];\n\n/**\n * Factory function to create tagged error classes.\n *\n * Two usage patterns:\n *\n * 1. **Props via generic** (default message is tag name):\n * ```typescript\n * class NotFoundError extends TaggedError(\"NotFoundError\")<{ id: string }> {}\n * ```\n *\n * 2. **Props inferred from message callback** (type-safe message):\n * ```typescript\n * class NotFoundError extends TaggedError(\"NotFoundError\", {\n * message: (p: { id: string }) => `Not found: ${p.id}`,\n * }) {}\n * ```\n *\n * Both support `instanceof TaggedError` checks at runtime.\n *\n * @param tag - The unique tag string for this error type\n * @param options - Optional configuration with message generator (annotate param for type safety)\n * @returns A class constructor that can be extended\n */\n\n// Overload 1: No options - use <Props> generic syntax, default message is tag\nfunction TaggedError<Tag extends string>(\n tag: Tag\n): TaggedErrorClassFactory<Tag>;\n\n// Overload 2: With message option - Props inferred from callback parameter annotation\nfunction TaggedError<Tag extends string, Props extends Record<string, unknown>>(\n tag: Tag,\n options: TaggedErrorCreateOptions<Props>\n): TaggedErrorConstructor<Tag, Props>;\n\n// Implementation\nfunction TaggedError<Tag extends string, Props extends Record<string, unknown>>(\n tag: Tag,\n options?: TaggedErrorCreateOptions<Props>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n return class extends InternalTaggedErrorBase {\n override readonly _tag: Tag = tag;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(props?: any, errorOptions?: TaggedErrorOptions) {\n // Generate message: call callback if provided (even for prop-less errors), else use tag\n const message = options?.message ? options.message(props ?? {}) : tag;\n\n super(message);\n this.name = tag;\n\n // Spine fields: populate when factory was given a slug\n if (options?.slug !== undefined) {\n if (!options.hint) {\n throw new TypeError(\n `TaggedError: 'hint' is required when 'slug' is set (slug: \"${options.slug}\")`\n );\n }\n Object.defineProperty(this, \"code\", {\n value: options.slug,\n enumerable: true,\n writable: false,\n configurable: false,\n });\n Object.defineProperty(this, \"hint\", {\n value: options.hint,\n enumerable: true,\n writable: false,\n configurable: false,\n });\n Object.defineProperty(this, \"docsUrl\", {\n value: slugDocsUrl(options.slug),\n enumerable: true,\n writable: false,\n configurable: false,\n });\n }\n\n // Maintains proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, new.target.prototype);\n\n // Assign props to instance, stripping reserved keys:\n // - _tag: discriminant for pattern matching (cannot be forged)\n // - name, message, stack: Error internals (preserve for logging/debugging)\n // - code, hint, docsUrl: spine fields stripped when slug is set, to prevent\n // Object.assign from clobbering the non-configurable/non-writable own props\n // Note: 'cause' is allowed as a user prop (common for domain errors)\n if (props && typeof props === \"object\") {\n let safeProps: Record<string, unknown>;\n if (options?.slug !== undefined) {\n const {\n _tag: _,\n name: _n,\n message: _m,\n stack: _s,\n code: _c,\n hint: _h,\n docsUrl: _d,\n ...rest\n } = props;\n safeProps = rest;\n } else {\n const {\n _tag: _,\n name: _n,\n message: _m,\n stack: _s,\n ...rest\n } = props;\n safeProps = rest;\n }\n\n const hasUserCause = Object.prototype.hasOwnProperty.call(\n safeProps,\n \"cause\"\n );\n const userCause = hasUserCause\n ? (safeProps as { cause?: unknown }).cause\n : undefined;\n if (hasUserCause) {\n delete (safeProps as { cause?: unknown }).cause;\n }\n\n const hasOptionsCause = errorOptions?.cause !== undefined;\n if (hasUserCause && hasOptionsCause) {\n throw new TypeError(\n \"TaggedError: cannot provide 'cause' in props when also setting ErrorOptions.cause\"\n );\n }\n\n Object.assign(this, safeProps);\n\n if (hasUserCause) {\n (this as { cause?: unknown }).cause = userCause;\n }\n if (hasOptionsCause) {\n (this as { cause?: unknown }).cause = errorOptions?.cause;\n }\n } else if (errorOptions?.cause !== undefined) {\n (this as { cause?: unknown }).cause = errorOptions.cause;\n }\n }\n };\n}\n\n// Add Symbol.hasInstance so `instanceof TaggedError` works\nObject.defineProperty(TaggedError, Symbol.hasInstance, {\n value: (instance: unknown): boolean => instance instanceof InternalTaggedErrorBase,\n});\n\n/**\n * Namespace for static methods on TaggedError.\n */\n// eslint-disable-next-line @typescript-eslint/no-namespace\nnamespace TaggedError {\n /**\n * Type guard to check if a value is an Error instance.\n */\n export function isError(value: unknown): value is Error {\n return value instanceof Error;\n }\n\n /**\n * Type guard to check if a value is a TaggedError instance.\n * Uses the same check as `instanceof TaggedError` - only genuine\n * TaggedError instances (created via the factory) pass this guard.\n */\n export function isTaggedError(value: unknown): value is TaggedErrorBase {\n return value instanceof InternalTaggedErrorBase;\n }\n\n /**\n * Exhaustively matches on a tagged error, requiring handlers for all variants.\n *\n * TypeScript will error if any variant in the error union is not handled.\n *\n * @remarks When to use: You want compile-time enforcement that every tagged variant is handled.\n *\n * @param error - The tagged error to match\n * @param handlers - Object mapping _tag values to handler functions\n * @returns The return value of the matched handler\n *\n * @example\n * ```typescript\n * type AppError = NotFoundError | ValidationError;\n *\n * const message = TaggedError.match(error, {\n * NotFoundError: (e) => `Not found: ${e.id}`,\n * ValidationError: (e) => `Invalid: ${e.field}`,\n * });\n * ```\n */\n export function match<\n E extends TaggedErrorBase,\n H extends { [K in E[\"_tag\"]]: (e: Extract<E, { _tag: K }>) => unknown },\n >(error: E, handlers: H): HandlersReturnType<H> {\n const tag = error._tag as E[\"_tag\"];\n const handler = handlers[tag];\n return handler(\n error as Extract<E, { _tag: typeof tag }>\n ) as HandlersReturnType<H>;\n }\n\n /**\n * Partially matches on a tagged error with a fallback for unhandled variants.\n *\n * The fallback receives variants that are NOT definitely handled. A tag is\n * considered \"definitely handled\" only if its handler is a function (not\n * `undefined`). This ensures type safety even with dynamic/conditional handlers:\n *\n * ```typescript\n * const maybeHandle = featureFlag ? (e) => e.id : undefined;\n * TaggedError.matchPartial(\n * error,\n * { NotFoundError: maybeHandle }, // maybeHandle might be undefined\n * (e) => e._tag // e correctly includes NotFoundError\n * );\n * ```\n *\n * @param error - The tagged error to match\n * @param handlers - Partial object mapping _tag values to handler functions\n * @param otherwise - Fallback handler for unmatched variants\n * @returns The return value of the matched handler or fallback\n *\n * @example\n * ```typescript\n * const message = TaggedError.matchPartial(\n * error,\n * { NotFoundError: (e) => `Not found: ${e.id}` },\n * (e) => `Other error: ${e.message}`\n * );\n * ```\n */\n export function matchPartial<\n E extends TaggedErrorBase,\n H extends Partial<{\n [K in E[\"_tag\"]]: (e: Extract<E, { _tag: K }>) => unknown;\n }>,\n T,\n >(\n error: E,\n handlers: H,\n otherwise: (e: Exclude<E, { _tag: DefinitelyHandledKeys<H> }>) => T\n ): HandlersReturnType<H> | T {\n const tag = error._tag as E[\"_tag\"];\n const handler = handlers[tag];\n if (handler) {\n return handler(\n error as Extract<E, { _tag: typeof tag }>\n ) as HandlersReturnType<H>;\n }\n return otherwise(error as Exclude<E, { _tag: DefinitelyHandledKeys<H> }>);\n }\n}\n\nexport { TaggedError };\n\n/**\n * Helper type to extract the _tag literal type from a TaggedError.\n *\n * @example\n * ```typescript\n * class MyError extends TaggedError(\"MyError\")<{ id: string }> {}\n * type Tag = TagOf<MyError>; // \"MyError\"\n * ```\n */\nexport type TagOf<E extends TaggedErrorBase> = E[\"_tag\"];\n\n/**\n * Helper type to extract a specific variant from a TaggedError union by tag.\n *\n * @example\n * ```typescript\n * type AppError = NotFoundError | ValidationError;\n * type NotFound = ErrorByTag<AppError, \"NotFoundError\">; // NotFoundError\n * ```\n */\nexport type ErrorByTag<\n E extends TaggedErrorBase,\n Tag extends E[\"_tag\"],\n> = Extract<E, { _tag: Tag }>;\n\n/**\n * Reserved keys that are stripped from user props at runtime.\n * These keys cannot be used as user-defined properties:\n * - _tag: discriminant for pattern matching\n * - name, message, stack: Error internals (preserved for logging/debugging)\n * - code, hint, docsUrl: spine fields (non-configurable own properties when slug is set)\n *\n * Note: 'cause' is NOT reserved - it can be used as a user prop.\n */\ntype ReservedErrorKeys = \"_tag\" | \"name\" | \"message\" | \"stack\" | \"code\" | \"hint\" | \"docsUrl\";\n\n/**\n * Helper type to extract props from a TaggedError.\n * Excludes reserved keys that are stripped at runtime.\n *\n * @example\n * ```typescript\n * class MyError extends TaggedError(\"MyError\")<{ id: string }> {}\n * type Props = PropsOf<MyError>; // { id: string }\n *\n * // 'cause' is allowed as a user prop\n * class DomainError extends TaggedError(\"DomainError\")<{ cause: { field: string } }> {}\n * type DomainProps = PropsOf<DomainError>; // { cause: { field: string } }\n * ```\n */\nexport type PropsOf<E extends TaggedErrorBase> = Omit<E, ReservedErrorKeys>;\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iBAAAE,IAAA,eAAAC,EAAAH,GCkBO,IAAMI,EAAgB,CAE3B,kBAAmB,kBACnB,8BAA+B,8BAC/B,6BAA8B,6BAC9B,qBAAsB,qBACtB,yBAA0B,yBAC1B,yBAA0B,yBAG1B,uBAAwB,uBACxB,4BAA6B,4BAC7B,0BAA2B,0BAC3B,4BAA6B,4BAC7B,6BAA8B,6BAG9B,qBAAsB,qBACtB,0BAA2B,0BAC3B,wBAAyB,wBACzB,+BAAgC,+BAChC,0BAA2B,0BAG3B,+BAAgC,+BAChC,qBAAsB,qBACtB,kBAAmB,kBACnB,yBAA0B,yBAG1B,6BAA8B,6BAC9B,8BAA+B,8BAC/B,oCAAqC,oCAGrC,uBAAwB,uBACxB,uBAAwB,uBACxB,0BAA2B,0BAC3B,qBAAsB,qBACtB,uBAAwB,uBACxB,qBAAsB,qBACtB,6BAA8B,6BAC9B,4BAA6B,2BAC/B,EAuBO,SAASC,EAAYC,EAA2B,CACrD,MAAO,8CAA8CA,CAAI,EAC3D,CAUO,IAAMC,EAAoC,OAAO,KACtDC,CACF,EClBA,IAAMC,EAAN,cAAsC,KAAiC,CAC5D,IACX,EAsGA,SAASC,EACPC,EACAC,EAEK,CACL,OAAO,cAAcH,CAAwB,CACzB,KAAYE,EAG9B,YAAYE,EAAaC,EAAmC,CAE1D,IAAMC,EAAUH,GAAS,QAAUA,EAAQ,QAAQC,GAAS,CAAC,CAAC,EAAIF,EAMlE,GAJA,MAAMI,CAAO,EACb,KAAK,KAAOJ,EAGRC,GAAS,OAAS,OAAW,CAC/B,GAAI,CAACA,EAAQ,KACX,MAAM,IAAI,UACR,8DAA8DA,EAAQ,IAAI,IAC5E,EAEF,OAAO,eAAe,KAAM,OAAQ,CAClC,MAAOA,EAAQ,KACf,WAAY,GACZ,SAAU,GACV,aAAc,EAChB,CAAC,EACD,OAAO,eAAe,KAAM,OAAQ,CAClC,MAAOA,EAAQ,KACf,WAAY,GACZ,SAAU,GACV,aAAc,EAChB,CAAC,EACD,OAAO,eAAe,KAAM,UAAW,CACrC,MAAOI,EAAYJ,EAAQ,IAAI,EAC/B,WAAY,GACZ,SAAU,GACV,aAAc,EAChB,CAAC,CACH,CAWA,GARA,OAAO,eAAe,KAAM,WAAW,SAAS,EAQ5CC,GAAS,OAAOA,GAAU,SAAU,CACtC,IAAII,EACJ,GAAIL,GAAS,OAAS,OAAW,CAC/B,GAAM,CACJ,KAAMM,EACN,KAAMC,EACN,QAASC,EACT,MAAOC,EACP,KAAMC,EACN,KAAMC,EACN,QAASC,EACT,GAAGC,CACL,EAAIZ,EACJI,EAAYQ,CACd,KAAO,CACL,GAAM,CACJ,KAAMP,EACN,KAAMC,EACN,QAASC,EACT,MAAOC,EACP,GAAGI,CACL,EAAIZ,EACJI,EAAYQ,CACd,CAEA,IAAMC,EAAe,OAAO,UAAU,eAAe,KACnDT,EACA,OACF,EACMU,EAAYD,EACbT,EAAkC,MACnC,OACAS,GACF,OAAQT,EAAkC,MAG5C,IAAMW,EAAkBd,GAAc,QAAU,OAChD,GAAIY,GAAgBE,EAClB,MAAM,IAAI,UACR,mFACF,EAGF,OAAO,OAAO,KAAMX,CAAS,EAEzBS,IACD,KAA6B,MAAQC,GAEpCC,IACD,KAA6B,MAAQd,GAAc,MAExD,MAAWA,GAAc,QAAU,SAChC,KAA6B,MAAQA,EAAa,MAEvD,CACF,CACF,CAGA,OAAO,eAAeJ,EAAa,OAAO,YAAa,CACrD,MAAQmB,GAA+BA,aAAoBpB,CAC7D,CAAC,GAMSC,GAAV,CAIS,SAASoB,EAAQC,EAAgC,CACtD,OAAOA,aAAiB,KAC1B,CAFOrB,EAAS,QAAAoB,EAST,SAASE,EAAcD,EAA0C,CACtE,OAAOA,aAAiBtB,CAC1B,CAFOC,EAAS,cAAAsB,EAyBT,SAASC,EAGdC,EAAUC,EAAoC,CAC9C,IAAMxB,EAAMuB,EAAM,KACZE,EAAUD,EAASxB,CAAG,EAC5B,OAAOyB,EACLF,CACF,CACF,CATOxB,EAAS,MAAAuB,EAyCT,SAASI,EAOdH,EACAC,EACAG,EAC2B,CAC3B,IAAM3B,EAAMuB,EAAM,KACZE,EAAUD,EAASxB,CAAG,EAC5B,OAAIyB,EACKA,EACLF,CACF,EAEKI,EAAUJ,CAAuD,CAC1E,CAnBOxB,EAAS,aAAA2B,IA/ER3B,IAAA","names":["tagged_error_entry_exports","__export","TaggedError","__toCommonJS","AWAITLY_SLUGS","slugDocsUrl","slug","ALL_SLUGS","AWAITLY_SLUGS","InternalTaggedErrorBase","TaggedError","tag","options","props","errorOptions","message","slugDocsUrl","safeProps","_","_n","_m","_s","_c","_h","_d","rest","hasUserCause","userCause","hasOptionsCause","instance","isError","value","isTaggedError","match","error","handlers","handler","matchPartial","otherwise"]}
|
package/dist/tagged-error.d.cts
DELETED
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
import { AwaitlySlug } from './slugs.cjs';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* awaitly/tagged-error
|
|
5
|
-
*
|
|
6
|
-
* Factory for creating tagged error types with exhaustive pattern matching.
|
|
7
|
-
* Enables TypeScript to enforce that all error variants are handled.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```typescript
|
|
11
|
-
* // Define error types (Props via generic)
|
|
12
|
-
* class NotFoundError extends TaggedError("NotFoundError")<{
|
|
13
|
-
* id: string;
|
|
14
|
-
* resource: string;
|
|
15
|
-
* }> {}
|
|
16
|
-
*
|
|
17
|
-
* // Define with type-safe message (Props inferred from callback annotation)
|
|
18
|
-
* class ValidationError extends TaggedError("ValidationError", {
|
|
19
|
-
* message: (p: { field: string; reason: string }) => `Invalid ${p.field}: ${p.reason}`,
|
|
20
|
-
* }) {}
|
|
21
|
-
*
|
|
22
|
-
* // Create instances
|
|
23
|
-
* const error = new NotFoundError({ id: "123", resource: "User" });
|
|
24
|
-
*
|
|
25
|
-
* // Runtime type check: instanceof TaggedError works!
|
|
26
|
-
* console.log(error instanceof TaggedError); // true
|
|
27
|
-
*
|
|
28
|
-
* // Exhaustive matching
|
|
29
|
-
* type AppError = NotFoundError | ValidationError;
|
|
30
|
-
* const message = TaggedError.match(error as AppError, {
|
|
31
|
-
* NotFoundError: (e) => `Missing: ${e.resource} ${e.id}`,
|
|
32
|
-
* ValidationError: (e) => `Invalid ${e.field}: ${e.reason}`,
|
|
33
|
-
* });
|
|
34
|
-
* ```
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Options for Error constructor (compatible with ES2022 ErrorOptions).
|
|
39
|
-
*/
|
|
40
|
-
interface TaggedErrorOptions {
|
|
41
|
-
cause?: unknown;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Options for TaggedError factory with type-safe message callback.
|
|
45
|
-
*/
|
|
46
|
-
interface TaggedErrorCreateOptions<Props extends Record<string, unknown>> {
|
|
47
|
-
/** Custom message generator from props. Annotate parameter for type safety. */
|
|
48
|
-
message: (props: Props) => string;
|
|
49
|
-
/**
|
|
50
|
-
* Canonical awaitly slug for this error class. When set, instances carry
|
|
51
|
-
* `code`, `hint`, and `docsUrl` populated from the slugs namespace.
|
|
52
|
-
* Required together with `hint` for awaitly-system errors.
|
|
53
|
-
*/
|
|
54
|
-
slug?: AwaitlySlug;
|
|
55
|
-
/**
|
|
56
|
-
* One-line "do X instead" guidance shown alongside the error.
|
|
57
|
-
* Required when `slug` is set.
|
|
58
|
-
*/
|
|
59
|
-
hint?: string;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Base interface for all tagged errors.
|
|
63
|
-
*/
|
|
64
|
-
interface TaggedErrorBase extends Error {
|
|
65
|
-
readonly _tag: string;
|
|
66
|
-
/** Canonical slug for awaitly-system errors. Undefined for user errors that opt out. */
|
|
67
|
-
readonly code?: AwaitlySlug;
|
|
68
|
-
/** One-line guidance. Undefined when no slug is set. */
|
|
69
|
-
readonly hint?: string;
|
|
70
|
-
/** Canonical docs URL. Undefined when no slug is set. */
|
|
71
|
-
readonly docsUrl?: string;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Instance type for factory-created TaggedErrors.
|
|
75
|
-
*/
|
|
76
|
-
type TaggedErrorInstance<Tag extends string, Props> = TaggedErrorBase & {
|
|
77
|
-
readonly _tag: Tag;
|
|
78
|
-
} & Readonly<Props>;
|
|
79
|
-
/**
|
|
80
|
-
* Constructor args type - conditionally optional based on whether Props has required fields.
|
|
81
|
-
* - If Props is empty or all properties are optional: props argument is optional
|
|
82
|
-
* - If Props has any required properties: props argument is required
|
|
83
|
-
* @internal
|
|
84
|
-
*/
|
|
85
|
-
type ConstructorArgs<Props extends Record<string, unknown>> = {} extends Props ? [props?: Props | void, options?: TaggedErrorOptions] : [props: Props, options?: TaggedErrorOptions];
|
|
86
|
-
/**
|
|
87
|
-
* Constructor type returned by TaggedError factory.
|
|
88
|
-
*/
|
|
89
|
-
interface TaggedErrorConstructor<Tag extends string, Props extends Record<string, unknown>> {
|
|
90
|
-
new (...args: ConstructorArgs<Props>): TaggedErrorInstance<Tag, Props>;
|
|
91
|
-
readonly prototype: TaggedErrorInstance<Tag, Props>;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Generic class factory type that allows `<Props>` parameterization.
|
|
95
|
-
* This enables the Effect.js-style syntax: `class X extends TaggedError("X")<Props> {}`
|
|
96
|
-
* @internal
|
|
97
|
-
*/
|
|
98
|
-
interface TaggedErrorClassFactory<Tag extends string> {
|
|
99
|
-
new <Props extends Record<string, unknown> = Record<string, never>>(...args: ConstructorArgs<Props>): TaggedErrorInstance<Tag, Props>;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Helper type to extract return type from a function type.
|
|
103
|
-
* @internal
|
|
104
|
-
*/
|
|
105
|
-
type FnReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
|
|
106
|
-
/**
|
|
107
|
-
* Helper type to get union of return types from all handlers.
|
|
108
|
-
* @internal
|
|
109
|
-
*/
|
|
110
|
-
type HandlersReturnType<H> = {
|
|
111
|
-
[K in keyof H]: FnReturnType<H[K]>;
|
|
112
|
-
}[keyof H];
|
|
113
|
-
/**
|
|
114
|
-
* Helper type to extract keys whose values are definitely functions (not undefined).
|
|
115
|
-
* Only excludes a tag from the fallback type if its handler is guaranteed to be
|
|
116
|
-
* a function. Keys where the value type includes undefined are NOT excluded,
|
|
117
|
-
* ensuring type safety with dynamic/conditional handlers.
|
|
118
|
-
* @internal
|
|
119
|
-
*/
|
|
120
|
-
type DefinitelyHandledKeys<H> = {
|
|
121
|
-
[K in keyof H]-?: undefined extends H[K] ? never : K;
|
|
122
|
-
}[keyof H];
|
|
123
|
-
/**
|
|
124
|
-
* Factory function to create tagged error classes.
|
|
125
|
-
*
|
|
126
|
-
* Two usage patterns:
|
|
127
|
-
*
|
|
128
|
-
* 1. **Props via generic** (default message is tag name):
|
|
129
|
-
* ```typescript
|
|
130
|
-
* class NotFoundError extends TaggedError("NotFoundError")<{ id: string }> {}
|
|
131
|
-
* ```
|
|
132
|
-
*
|
|
133
|
-
* 2. **Props inferred from message callback** (type-safe message):
|
|
134
|
-
* ```typescript
|
|
135
|
-
* class NotFoundError extends TaggedError("NotFoundError", {
|
|
136
|
-
* message: (p: { id: string }) => `Not found: ${p.id}`,
|
|
137
|
-
* }) {}
|
|
138
|
-
* ```
|
|
139
|
-
*
|
|
140
|
-
* Both support `instanceof TaggedError` checks at runtime.
|
|
141
|
-
*
|
|
142
|
-
* @param tag - The unique tag string for this error type
|
|
143
|
-
* @param options - Optional configuration with message generator (annotate param for type safety)
|
|
144
|
-
* @returns A class constructor that can be extended
|
|
145
|
-
*/
|
|
146
|
-
declare function TaggedError<Tag extends string>(tag: Tag): TaggedErrorClassFactory<Tag>;
|
|
147
|
-
declare function TaggedError<Tag extends string, Props extends Record<string, unknown>>(tag: Tag, options: TaggedErrorCreateOptions<Props>): TaggedErrorConstructor<Tag, Props>;
|
|
148
|
-
/**
|
|
149
|
-
* Namespace for static methods on TaggedError.
|
|
150
|
-
*/
|
|
151
|
-
declare namespace TaggedError {
|
|
152
|
-
/**
|
|
153
|
-
* Type guard to check if a value is an Error instance.
|
|
154
|
-
*/
|
|
155
|
-
function isError(value: unknown): value is Error;
|
|
156
|
-
/**
|
|
157
|
-
* Type guard to check if a value is a TaggedError instance.
|
|
158
|
-
* Uses the same check as `instanceof TaggedError` - only genuine
|
|
159
|
-
* TaggedError instances (created via the factory) pass this guard.
|
|
160
|
-
*/
|
|
161
|
-
function isTaggedError(value: unknown): value is TaggedErrorBase;
|
|
162
|
-
/**
|
|
163
|
-
* Exhaustively matches on a tagged error, requiring handlers for all variants.
|
|
164
|
-
*
|
|
165
|
-
* TypeScript will error if any variant in the error union is not handled.
|
|
166
|
-
*
|
|
167
|
-
* @remarks When to use: You want compile-time enforcement that every tagged variant is handled.
|
|
168
|
-
*
|
|
169
|
-
* @param error - The tagged error to match
|
|
170
|
-
* @param handlers - Object mapping _tag values to handler functions
|
|
171
|
-
* @returns The return value of the matched handler
|
|
172
|
-
*
|
|
173
|
-
* @example
|
|
174
|
-
* ```typescript
|
|
175
|
-
* type AppError = NotFoundError | ValidationError;
|
|
176
|
-
*
|
|
177
|
-
* const message = TaggedError.match(error, {
|
|
178
|
-
* NotFoundError: (e) => `Not found: ${e.id}`,
|
|
179
|
-
* ValidationError: (e) => `Invalid: ${e.field}`,
|
|
180
|
-
* });
|
|
181
|
-
* ```
|
|
182
|
-
*/
|
|
183
|
-
function match<E extends TaggedErrorBase, H extends {
|
|
184
|
-
[K in E["_tag"]]: (e: Extract<E, {
|
|
185
|
-
_tag: K;
|
|
186
|
-
}>) => unknown;
|
|
187
|
-
}>(error: E, handlers: H): HandlersReturnType<H>;
|
|
188
|
-
/**
|
|
189
|
-
* Partially matches on a tagged error with a fallback for unhandled variants.
|
|
190
|
-
*
|
|
191
|
-
* The fallback receives variants that are NOT definitely handled. A tag is
|
|
192
|
-
* considered "definitely handled" only if its handler is a function (not
|
|
193
|
-
* `undefined`). This ensures type safety even with dynamic/conditional handlers:
|
|
194
|
-
*
|
|
195
|
-
* ```typescript
|
|
196
|
-
* const maybeHandle = featureFlag ? (e) => e.id : undefined;
|
|
197
|
-
* TaggedError.matchPartial(
|
|
198
|
-
* error,
|
|
199
|
-
* { NotFoundError: maybeHandle }, // maybeHandle might be undefined
|
|
200
|
-
* (e) => e._tag // e correctly includes NotFoundError
|
|
201
|
-
* );
|
|
202
|
-
* ```
|
|
203
|
-
*
|
|
204
|
-
* @param error - The tagged error to match
|
|
205
|
-
* @param handlers - Partial object mapping _tag values to handler functions
|
|
206
|
-
* @param otherwise - Fallback handler for unmatched variants
|
|
207
|
-
* @returns The return value of the matched handler or fallback
|
|
208
|
-
*
|
|
209
|
-
* @example
|
|
210
|
-
* ```typescript
|
|
211
|
-
* const message = TaggedError.matchPartial(
|
|
212
|
-
* error,
|
|
213
|
-
* { NotFoundError: (e) => `Not found: ${e.id}` },
|
|
214
|
-
* (e) => `Other error: ${e.message}`
|
|
215
|
-
* );
|
|
216
|
-
* ```
|
|
217
|
-
*/
|
|
218
|
-
function matchPartial<E extends TaggedErrorBase, H extends Partial<{
|
|
219
|
-
[K in E["_tag"]]: (e: Extract<E, {
|
|
220
|
-
_tag: K;
|
|
221
|
-
}>) => unknown;
|
|
222
|
-
}>, T>(error: E, handlers: H, otherwise: (e: Exclude<E, {
|
|
223
|
-
_tag: DefinitelyHandledKeys<H>;
|
|
224
|
-
}>) => T): HandlersReturnType<H> | T;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Helper type to extract the _tag literal type from a TaggedError.
|
|
229
|
-
*
|
|
230
|
-
* @example
|
|
231
|
-
* ```typescript
|
|
232
|
-
* class MyError extends TaggedError("MyError")<{ id: string }> {}
|
|
233
|
-
* type Tag = TagOf<MyError>; // "MyError"
|
|
234
|
-
* ```
|
|
235
|
-
*/
|
|
236
|
-
type TagOf<E extends TaggedErrorBase> = E["_tag"];
|
|
237
|
-
/**
|
|
238
|
-
* Helper type to extract a specific variant from a TaggedError union by tag.
|
|
239
|
-
*
|
|
240
|
-
* @example
|
|
241
|
-
* ```typescript
|
|
242
|
-
* type AppError = NotFoundError | ValidationError;
|
|
243
|
-
* type NotFound = ErrorByTag<AppError, "NotFoundError">; // NotFoundError
|
|
244
|
-
* ```
|
|
245
|
-
*/
|
|
246
|
-
type ErrorByTag<E extends TaggedErrorBase, Tag extends E["_tag"]> = Extract<E, {
|
|
247
|
-
_tag: Tag;
|
|
248
|
-
}>;
|
|
249
|
-
/**
|
|
250
|
-
* Reserved keys that are stripped from user props at runtime.
|
|
251
|
-
* These keys cannot be used as user-defined properties:
|
|
252
|
-
* - _tag: discriminant for pattern matching
|
|
253
|
-
* - name, message, stack: Error internals (preserved for logging/debugging)
|
|
254
|
-
* - code, hint, docsUrl: spine fields (non-configurable own properties when slug is set)
|
|
255
|
-
*
|
|
256
|
-
* Note: 'cause' is NOT reserved - it can be used as a user prop.
|
|
257
|
-
*/
|
|
258
|
-
type ReservedErrorKeys = "_tag" | "name" | "message" | "stack" | "code" | "hint" | "docsUrl";
|
|
259
|
-
/**
|
|
260
|
-
* Helper type to extract props from a TaggedError.
|
|
261
|
-
* Excludes reserved keys that are stripped at runtime.
|
|
262
|
-
*
|
|
263
|
-
* @example
|
|
264
|
-
* ```typescript
|
|
265
|
-
* class MyError extends TaggedError("MyError")<{ id: string }> {}
|
|
266
|
-
* type Props = PropsOf<MyError>; // { id: string }
|
|
267
|
-
*
|
|
268
|
-
* // 'cause' is allowed as a user prop
|
|
269
|
-
* class DomainError extends TaggedError("DomainError")<{ cause: { field: string } }> {}
|
|
270
|
-
* type DomainProps = PropsOf<DomainError>; // { cause: { field: string } }
|
|
271
|
-
* ```
|
|
272
|
-
*/
|
|
273
|
-
type PropsOf<E extends TaggedErrorBase> = Omit<E, ReservedErrorKeys>;
|
|
274
|
-
|
|
275
|
-
export { type ErrorByTag, type PropsOf, type TagOf, TaggedError, type TaggedErrorBase, type TaggedErrorConstructor, type TaggedErrorCreateOptions, type TaggedErrorOptions };
|
package/dist/tagged-error.d.ts
DELETED
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
import { AwaitlySlug } from './slugs.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* awaitly/tagged-error
|
|
5
|
-
*
|
|
6
|
-
* Factory for creating tagged error types with exhaustive pattern matching.
|
|
7
|
-
* Enables TypeScript to enforce that all error variants are handled.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```typescript
|
|
11
|
-
* // Define error types (Props via generic)
|
|
12
|
-
* class NotFoundError extends TaggedError("NotFoundError")<{
|
|
13
|
-
* id: string;
|
|
14
|
-
* resource: string;
|
|
15
|
-
* }> {}
|
|
16
|
-
*
|
|
17
|
-
* // Define with type-safe message (Props inferred from callback annotation)
|
|
18
|
-
* class ValidationError extends TaggedError("ValidationError", {
|
|
19
|
-
* message: (p: { field: string; reason: string }) => `Invalid ${p.field}: ${p.reason}`,
|
|
20
|
-
* }) {}
|
|
21
|
-
*
|
|
22
|
-
* // Create instances
|
|
23
|
-
* const error = new NotFoundError({ id: "123", resource: "User" });
|
|
24
|
-
*
|
|
25
|
-
* // Runtime type check: instanceof TaggedError works!
|
|
26
|
-
* console.log(error instanceof TaggedError); // true
|
|
27
|
-
*
|
|
28
|
-
* // Exhaustive matching
|
|
29
|
-
* type AppError = NotFoundError | ValidationError;
|
|
30
|
-
* const message = TaggedError.match(error as AppError, {
|
|
31
|
-
* NotFoundError: (e) => `Missing: ${e.resource} ${e.id}`,
|
|
32
|
-
* ValidationError: (e) => `Invalid ${e.field}: ${e.reason}`,
|
|
33
|
-
* });
|
|
34
|
-
* ```
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Options for Error constructor (compatible with ES2022 ErrorOptions).
|
|
39
|
-
*/
|
|
40
|
-
interface TaggedErrorOptions {
|
|
41
|
-
cause?: unknown;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Options for TaggedError factory with type-safe message callback.
|
|
45
|
-
*/
|
|
46
|
-
interface TaggedErrorCreateOptions<Props extends Record<string, unknown>> {
|
|
47
|
-
/** Custom message generator from props. Annotate parameter for type safety. */
|
|
48
|
-
message: (props: Props) => string;
|
|
49
|
-
/**
|
|
50
|
-
* Canonical awaitly slug for this error class. When set, instances carry
|
|
51
|
-
* `code`, `hint`, and `docsUrl` populated from the slugs namespace.
|
|
52
|
-
* Required together with `hint` for awaitly-system errors.
|
|
53
|
-
*/
|
|
54
|
-
slug?: AwaitlySlug;
|
|
55
|
-
/**
|
|
56
|
-
* One-line "do X instead" guidance shown alongside the error.
|
|
57
|
-
* Required when `slug` is set.
|
|
58
|
-
*/
|
|
59
|
-
hint?: string;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Base interface for all tagged errors.
|
|
63
|
-
*/
|
|
64
|
-
interface TaggedErrorBase extends Error {
|
|
65
|
-
readonly _tag: string;
|
|
66
|
-
/** Canonical slug for awaitly-system errors. Undefined for user errors that opt out. */
|
|
67
|
-
readonly code?: AwaitlySlug;
|
|
68
|
-
/** One-line guidance. Undefined when no slug is set. */
|
|
69
|
-
readonly hint?: string;
|
|
70
|
-
/** Canonical docs URL. Undefined when no slug is set. */
|
|
71
|
-
readonly docsUrl?: string;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Instance type for factory-created TaggedErrors.
|
|
75
|
-
*/
|
|
76
|
-
type TaggedErrorInstance<Tag extends string, Props> = TaggedErrorBase & {
|
|
77
|
-
readonly _tag: Tag;
|
|
78
|
-
} & Readonly<Props>;
|
|
79
|
-
/**
|
|
80
|
-
* Constructor args type - conditionally optional based on whether Props has required fields.
|
|
81
|
-
* - If Props is empty or all properties are optional: props argument is optional
|
|
82
|
-
* - If Props has any required properties: props argument is required
|
|
83
|
-
* @internal
|
|
84
|
-
*/
|
|
85
|
-
type ConstructorArgs<Props extends Record<string, unknown>> = {} extends Props ? [props?: Props | void, options?: TaggedErrorOptions] : [props: Props, options?: TaggedErrorOptions];
|
|
86
|
-
/**
|
|
87
|
-
* Constructor type returned by TaggedError factory.
|
|
88
|
-
*/
|
|
89
|
-
interface TaggedErrorConstructor<Tag extends string, Props extends Record<string, unknown>> {
|
|
90
|
-
new (...args: ConstructorArgs<Props>): TaggedErrorInstance<Tag, Props>;
|
|
91
|
-
readonly prototype: TaggedErrorInstance<Tag, Props>;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Generic class factory type that allows `<Props>` parameterization.
|
|
95
|
-
* This enables the Effect.js-style syntax: `class X extends TaggedError("X")<Props> {}`
|
|
96
|
-
* @internal
|
|
97
|
-
*/
|
|
98
|
-
interface TaggedErrorClassFactory<Tag extends string> {
|
|
99
|
-
new <Props extends Record<string, unknown> = Record<string, never>>(...args: ConstructorArgs<Props>): TaggedErrorInstance<Tag, Props>;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Helper type to extract return type from a function type.
|
|
103
|
-
* @internal
|
|
104
|
-
*/
|
|
105
|
-
type FnReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
|
|
106
|
-
/**
|
|
107
|
-
* Helper type to get union of return types from all handlers.
|
|
108
|
-
* @internal
|
|
109
|
-
*/
|
|
110
|
-
type HandlersReturnType<H> = {
|
|
111
|
-
[K in keyof H]: FnReturnType<H[K]>;
|
|
112
|
-
}[keyof H];
|
|
113
|
-
/**
|
|
114
|
-
* Helper type to extract keys whose values are definitely functions (not undefined).
|
|
115
|
-
* Only excludes a tag from the fallback type if its handler is guaranteed to be
|
|
116
|
-
* a function. Keys where the value type includes undefined are NOT excluded,
|
|
117
|
-
* ensuring type safety with dynamic/conditional handlers.
|
|
118
|
-
* @internal
|
|
119
|
-
*/
|
|
120
|
-
type DefinitelyHandledKeys<H> = {
|
|
121
|
-
[K in keyof H]-?: undefined extends H[K] ? never : K;
|
|
122
|
-
}[keyof H];
|
|
123
|
-
/**
|
|
124
|
-
* Factory function to create tagged error classes.
|
|
125
|
-
*
|
|
126
|
-
* Two usage patterns:
|
|
127
|
-
*
|
|
128
|
-
* 1. **Props via generic** (default message is tag name):
|
|
129
|
-
* ```typescript
|
|
130
|
-
* class NotFoundError extends TaggedError("NotFoundError")<{ id: string }> {}
|
|
131
|
-
* ```
|
|
132
|
-
*
|
|
133
|
-
* 2. **Props inferred from message callback** (type-safe message):
|
|
134
|
-
* ```typescript
|
|
135
|
-
* class NotFoundError extends TaggedError("NotFoundError", {
|
|
136
|
-
* message: (p: { id: string }) => `Not found: ${p.id}`,
|
|
137
|
-
* }) {}
|
|
138
|
-
* ```
|
|
139
|
-
*
|
|
140
|
-
* Both support `instanceof TaggedError` checks at runtime.
|
|
141
|
-
*
|
|
142
|
-
* @param tag - The unique tag string for this error type
|
|
143
|
-
* @param options - Optional configuration with message generator (annotate param for type safety)
|
|
144
|
-
* @returns A class constructor that can be extended
|
|
145
|
-
*/
|
|
146
|
-
declare function TaggedError<Tag extends string>(tag: Tag): TaggedErrorClassFactory<Tag>;
|
|
147
|
-
declare function TaggedError<Tag extends string, Props extends Record<string, unknown>>(tag: Tag, options: TaggedErrorCreateOptions<Props>): TaggedErrorConstructor<Tag, Props>;
|
|
148
|
-
/**
|
|
149
|
-
* Namespace for static methods on TaggedError.
|
|
150
|
-
*/
|
|
151
|
-
declare namespace TaggedError {
|
|
152
|
-
/**
|
|
153
|
-
* Type guard to check if a value is an Error instance.
|
|
154
|
-
*/
|
|
155
|
-
function isError(value: unknown): value is Error;
|
|
156
|
-
/**
|
|
157
|
-
* Type guard to check if a value is a TaggedError instance.
|
|
158
|
-
* Uses the same check as `instanceof TaggedError` - only genuine
|
|
159
|
-
* TaggedError instances (created via the factory) pass this guard.
|
|
160
|
-
*/
|
|
161
|
-
function isTaggedError(value: unknown): value is TaggedErrorBase;
|
|
162
|
-
/**
|
|
163
|
-
* Exhaustively matches on a tagged error, requiring handlers for all variants.
|
|
164
|
-
*
|
|
165
|
-
* TypeScript will error if any variant in the error union is not handled.
|
|
166
|
-
*
|
|
167
|
-
* @remarks When to use: You want compile-time enforcement that every tagged variant is handled.
|
|
168
|
-
*
|
|
169
|
-
* @param error - The tagged error to match
|
|
170
|
-
* @param handlers - Object mapping _tag values to handler functions
|
|
171
|
-
* @returns The return value of the matched handler
|
|
172
|
-
*
|
|
173
|
-
* @example
|
|
174
|
-
* ```typescript
|
|
175
|
-
* type AppError = NotFoundError | ValidationError;
|
|
176
|
-
*
|
|
177
|
-
* const message = TaggedError.match(error, {
|
|
178
|
-
* NotFoundError: (e) => `Not found: ${e.id}`,
|
|
179
|
-
* ValidationError: (e) => `Invalid: ${e.field}`,
|
|
180
|
-
* });
|
|
181
|
-
* ```
|
|
182
|
-
*/
|
|
183
|
-
function match<E extends TaggedErrorBase, H extends {
|
|
184
|
-
[K in E["_tag"]]: (e: Extract<E, {
|
|
185
|
-
_tag: K;
|
|
186
|
-
}>) => unknown;
|
|
187
|
-
}>(error: E, handlers: H): HandlersReturnType<H>;
|
|
188
|
-
/**
|
|
189
|
-
* Partially matches on a tagged error with a fallback for unhandled variants.
|
|
190
|
-
*
|
|
191
|
-
* The fallback receives variants that are NOT definitely handled. A tag is
|
|
192
|
-
* considered "definitely handled" only if its handler is a function (not
|
|
193
|
-
* `undefined`). This ensures type safety even with dynamic/conditional handlers:
|
|
194
|
-
*
|
|
195
|
-
* ```typescript
|
|
196
|
-
* const maybeHandle = featureFlag ? (e) => e.id : undefined;
|
|
197
|
-
* TaggedError.matchPartial(
|
|
198
|
-
* error,
|
|
199
|
-
* { NotFoundError: maybeHandle }, // maybeHandle might be undefined
|
|
200
|
-
* (e) => e._tag // e correctly includes NotFoundError
|
|
201
|
-
* );
|
|
202
|
-
* ```
|
|
203
|
-
*
|
|
204
|
-
* @param error - The tagged error to match
|
|
205
|
-
* @param handlers - Partial object mapping _tag values to handler functions
|
|
206
|
-
* @param otherwise - Fallback handler for unmatched variants
|
|
207
|
-
* @returns The return value of the matched handler or fallback
|
|
208
|
-
*
|
|
209
|
-
* @example
|
|
210
|
-
* ```typescript
|
|
211
|
-
* const message = TaggedError.matchPartial(
|
|
212
|
-
* error,
|
|
213
|
-
* { NotFoundError: (e) => `Not found: ${e.id}` },
|
|
214
|
-
* (e) => `Other error: ${e.message}`
|
|
215
|
-
* );
|
|
216
|
-
* ```
|
|
217
|
-
*/
|
|
218
|
-
function matchPartial<E extends TaggedErrorBase, H extends Partial<{
|
|
219
|
-
[K in E["_tag"]]: (e: Extract<E, {
|
|
220
|
-
_tag: K;
|
|
221
|
-
}>) => unknown;
|
|
222
|
-
}>, T>(error: E, handlers: H, otherwise: (e: Exclude<E, {
|
|
223
|
-
_tag: DefinitelyHandledKeys<H>;
|
|
224
|
-
}>) => T): HandlersReturnType<H> | T;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Helper type to extract the _tag literal type from a TaggedError.
|
|
229
|
-
*
|
|
230
|
-
* @example
|
|
231
|
-
* ```typescript
|
|
232
|
-
* class MyError extends TaggedError("MyError")<{ id: string }> {}
|
|
233
|
-
* type Tag = TagOf<MyError>; // "MyError"
|
|
234
|
-
* ```
|
|
235
|
-
*/
|
|
236
|
-
type TagOf<E extends TaggedErrorBase> = E["_tag"];
|
|
237
|
-
/**
|
|
238
|
-
* Helper type to extract a specific variant from a TaggedError union by tag.
|
|
239
|
-
*
|
|
240
|
-
* @example
|
|
241
|
-
* ```typescript
|
|
242
|
-
* type AppError = NotFoundError | ValidationError;
|
|
243
|
-
* type NotFound = ErrorByTag<AppError, "NotFoundError">; // NotFoundError
|
|
244
|
-
* ```
|
|
245
|
-
*/
|
|
246
|
-
type ErrorByTag<E extends TaggedErrorBase, Tag extends E["_tag"]> = Extract<E, {
|
|
247
|
-
_tag: Tag;
|
|
248
|
-
}>;
|
|
249
|
-
/**
|
|
250
|
-
* Reserved keys that are stripped from user props at runtime.
|
|
251
|
-
* These keys cannot be used as user-defined properties:
|
|
252
|
-
* - _tag: discriminant for pattern matching
|
|
253
|
-
* - name, message, stack: Error internals (preserved for logging/debugging)
|
|
254
|
-
* - code, hint, docsUrl: spine fields (non-configurable own properties when slug is set)
|
|
255
|
-
*
|
|
256
|
-
* Note: 'cause' is NOT reserved - it can be used as a user prop.
|
|
257
|
-
*/
|
|
258
|
-
type ReservedErrorKeys = "_tag" | "name" | "message" | "stack" | "code" | "hint" | "docsUrl";
|
|
259
|
-
/**
|
|
260
|
-
* Helper type to extract props from a TaggedError.
|
|
261
|
-
* Excludes reserved keys that are stripped at runtime.
|
|
262
|
-
*
|
|
263
|
-
* @example
|
|
264
|
-
* ```typescript
|
|
265
|
-
* class MyError extends TaggedError("MyError")<{ id: string }> {}
|
|
266
|
-
* type Props = PropsOf<MyError>; // { id: string }
|
|
267
|
-
*
|
|
268
|
-
* // 'cause' is allowed as a user prop
|
|
269
|
-
* class DomainError extends TaggedError("DomainError")<{ cause: { field: string } }> {}
|
|
270
|
-
* type DomainProps = PropsOf<DomainError>; // { cause: { field: string } }
|
|
271
|
-
* ```
|
|
272
|
-
*/
|
|
273
|
-
type PropsOf<E extends TaggedErrorBase> = Omit<E, ReservedErrorKeys>;
|
|
274
|
-
|
|
275
|
-
export { type ErrorByTag, type PropsOf, type TagOf, TaggedError, type TaggedErrorBase, type TaggedErrorConstructor, type TaggedErrorCreateOptions, type TaggedErrorOptions };
|
package/dist/tagged-error.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var T={"step-require-id":"step-require-id","step-no-immediate-execution":"step-no-immediate-execution","step-require-thunk-for-key":"step-require-thunk-for-key","step-no-bare-await":"step-no-bare-await","step-no-try-catch-wrap":"step-no-try-catch-wrap","step-stable-cache-keys":"step-stable-cache-keys","workflow-no-floating":"workflow-no-floating","workflow-options-position":"workflow-options-position","workflow-callback-shape":"workflow-callback-shape","workflow-no-callable-form":"workflow-no-callable-form","workflow-no-dynamic-import":"workflow-no-dynamic-import","result-no-floating":"result-no-floating","result-require-handling":"result-require-handling","result-no-double-wrap":"result-no-double-wrap","result-no-manual-propagation":"result-no-manual-propagation","result-no-direct-ok-err":"result-no-direct-ok-err","error-check-unexpected-first":"error-check-unexpected-first","error-access-cause":"error-access-cause","error-normalize":"error-normalize","error-no-throw-in-deps":"error-no-throw-in-deps","concurrency-no-promise-all":"concurrency-no-promise-all","concurrency-no-promise-race":"concurrency-no-promise-race","concurrency-no-promise-allsettled":"concurrency-no-promise-allsettled","runtime-step-timeout":"runtime-step-timeout","runtime-step-aborted":"runtime-step-aborted","runtime-retry-exhausted":"runtime-retry-exhausted","runtime-rate-limit":"runtime-rate-limit","runtime-circuit-open":"runtime-circuit-open","runtime-unexpected":"runtime-unexpected","runtime-resolver-not-found":"runtime-resolver-not-found","runtime-saga-compensation":"runtime-saga-compensation"};function p(t){return`https://jagreehal.github.io/awaitly/rules/#${t}`}var h=Object.keys(T);var g=class extends Error{_tag};function c(t,r){return class extends g{_tag=t;constructor(o,s){let l=r?.message?r.message(o??{}):t;if(super(l),this.name=t,r?.slug!==void 0){if(!r.hint)throw new TypeError(`TaggedError: 'hint' is required when 'slug' is set (slug: "${r.slug}")`);Object.defineProperty(this,"code",{value:r.slug,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"hint",{value:r.hint,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"docsUrl",{value:p(r.slug),enumerable:!0,writable:!1,configurable:!1})}if(Object.setPrototypeOf(this,new.target.prototype),o&&typeof o=="object"){let e;if(r?.slug!==void 0){let{_tag:u,name:y,message:f,stack:w,code:d,hint:m,docsUrl:x,...E}=o;e=E}else{let{_tag:u,name:y,message:f,stack:w,...d}=o;e=d}let n=Object.prototype.hasOwnProperty.call(e,"cause"),i=n?e.cause:void 0;n&&delete e.cause;let a=s?.cause!==void 0;if(n&&a)throw new TypeError("TaggedError: cannot provide 'cause' in props when also setting ErrorOptions.cause");Object.assign(this,e),n&&(this.cause=i),a&&(this.cause=s?.cause)}else s?.cause!==void 0&&(this.cause=s.cause)}}}Object.defineProperty(c,Symbol.hasInstance,{value:t=>t instanceof g});(l=>{function t(e){return e instanceof Error}l.isError=t;function r(e){return e instanceof g}l.isTaggedError=r;function o(e,n){let i=e._tag,a=n[i];return a(e)}l.match=o;function s(e,n,i){let a=e._tag,u=n[a];return u?u(e):i(e)}l.matchPartial=s})(c||={});export{c as TaggedError};
|
|
2
|
-
//# sourceMappingURL=tagged-error.js.map
|