wellcrafted 0.25.0 → 0.26.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.
@@ -1,22 +1,44 @@
1
- import { Err } from "../result-DRq8PMRe.js";
1
+ import { Err } from "../result-DolxQXIZ.js";
2
2
 
3
3
  //#region src/error/types.d.ts
4
-
5
4
  /**
6
- * Helper type that adds a context property only when TContext is not never.
7
- * When TContext is never, returns an empty object (no context property).
8
- * When TContext is a real type, returns { context: TContext } (required property).
5
+ * Base type for any tagged error, used as a constraint for cause parameters.
6
+ */
7
+ type AnyTaggedError = {
8
+ name: string;
9
+ message: string;
10
+ };
11
+ /**
12
+ * Helper type that adds a context property.
13
+ * - When TContext is undefined (default): context is OPTIONAL with loose typing
14
+ * - When TContext includes undefined (e.g., `{ foo: string } | undefined`): context is OPTIONAL but typed
15
+ * - When TContext is a specific type without undefined: context is REQUIRED with that exact type
16
+ *
17
+ * This allows users to specify "optional but typed" context by passing a union with undefined.
9
18
  */
10
- type WithContext<TContext> = [TContext] extends [never] ? {} : {
19
+ type WithContext<TContext> = [TContext] extends [undefined] ? {
20
+ context?: Record<string, unknown>;
21
+ } : [undefined] extends [TContext] ? {
22
+ context?: Exclude<TContext, undefined>;
23
+ } : {
11
24
  context: TContext;
12
25
  };
13
26
  /**
14
- * Helper type that adds a cause property only when TCause is not never.
15
- * When TCause is never, returns an empty object (no cause property).
16
- * When TCause is a real type, returns { cause: TCause } (required property).
27
+ * Helper type that adds a cause property.
28
+ * - When TCause is undefined (default): cause is OPTIONAL, any tagged error allowed
29
+ * - When TCause includes undefined (e.g., `NetworkError | undefined`): cause is OPTIONAL, constrained
30
+ * - When TCause is a specific type: cause is OPTIONAL but constrained to that type
31
+ *
32
+ * Note: cause is always optional at runtime (errors can be created without causes),
33
+ * but when TCause is specified, it constrains what cause types are allowed.
34
+ * Using brackets to prevent distributive conditional behavior with union types.
17
35
  */
18
- type WithCause<TCause> = [TCause] extends [never] ? {} : {
19
- cause: TCause;
36
+ type WithCause<TCause> = [TCause] extends [undefined] ? {
37
+ cause?: AnyTaggedError;
38
+ } : [undefined] extends [TCause] ? {
39
+ cause?: Exclude<TCause, undefined>;
40
+ } : {
41
+ cause?: TCause;
20
42
  };
21
43
  /**
22
44
  * Creates a tagged error type for type-safe error handling.
@@ -27,41 +49,47 @@ type WithCause<TCause> = [TCause] extends [never] ? {} : {
27
49
  * an error propagated through your application layers.
28
50
  *
29
51
  * **Type Parameter Behavior:**
30
- * - When `TContext` is `never` (default): No `context` property exists
31
- * - When `TContext` is specified: `context` is a **required** property
32
- * - When `TCause` is `never` (default): No `cause` property exists
33
- * - When `TCause` is specified: `cause` is a **required** property
52
+ * - When `TContext` is `undefined` (default): `context` is OPTIONAL with type `Record<string, unknown>`
53
+ * - When `TContext` is `{ ... } | undefined`: `context` is OPTIONAL but typed (use union for optional typed context)
54
+ * - When `TContext` is specified without undefined: `context` is REQUIRED with that exact type
55
+ * - When `TCause` is `undefined` (default): `cause` is OPTIONAL, any `AnyTaggedError` allowed
56
+ * - When `TCause` is specified: `cause` is OPTIONAL but constrained to that type
34
57
  *
35
58
  * @template TName - The error name (discriminator for tagged unions)
36
- * @template TContext - Additional context data for the error (default: never = no context property)
37
- * @template TCause - The type of error that caused this error (default: never = no cause property)
59
+ * @template TContext - Additional context data for the error (default: undefined = optional loose context)
60
+ * @template TCause - The type of error that caused this error (default: undefined = optional any cause)
38
61
  *
39
62
  * @example
40
63
  * ```ts
41
- * // Simple error without context or cause (properties don't exist)
64
+ * // Flexible error (context and cause optional, loosely typed)
42
65
  * type ValidationError = TaggedError<"ValidationError">;
43
66
  * const validationError: ValidationError = {
44
67
  * name: "ValidationError",
45
68
  * message: "Input is required"
46
69
  * };
47
- * // validationError.context // Property 'context' does not exist
70
+ * // validationError.context is optional, typed as Record<string, unknown> | undefined
48
71
  *
49
- * // Error with required context
72
+ * // Error with required context (fixed context mode)
50
73
  * type NetworkError = TaggedError<"NetworkError", { host: string; port: number }>;
51
74
  * const networkError: NetworkError = {
52
75
  * name: "NetworkError",
53
76
  * message: "Socket timeout",
54
77
  * context: { host: "db.example.com", port: 5432 } // Required!
55
78
  * };
56
- * const host = networkError.context.host; // No optional chaining needed
79
+ * const host = networkError.context.host; // Type-safe, no optional chaining needed
57
80
  *
58
- * // Type-safe error chaining with required cause
81
+ * // Error with OPTIONAL but TYPED context (union with undefined)
82
+ * type LogError = TaggedError<"LogError", { file: string; line: number } | undefined>;
83
+ * const logError1: LogError = { name: "LogError", message: "Parse failed" }; // OK - no context
84
+ * const logError2: LogError = { name: "LogError", message: "Parse failed", context: { file: "app.ts", line: 42 } }; // OK - typed context
85
+ *
86
+ * // Error with fixed context and constrained cause type
59
87
  * type DatabaseError = TaggedError<"DatabaseError", { operation: string }, NetworkError>;
60
88
  * const dbError: DatabaseError = {
61
89
  * name: "DatabaseError",
62
90
  * message: "Failed to connect to database",
63
91
  * context: { operation: "connect" }, // Required!
64
- * cause: networkError // Required!
92
+ * cause: networkError // Optional, but must be NetworkError if provided
65
93
  * };
66
94
  *
67
95
  * // Discriminated unions still work
@@ -75,7 +103,7 @@ type WithCause<TCause> = [TCause] extends [never] ? {} : {
75
103
  * }
76
104
  * ```
77
105
  */
78
- type TaggedError<TName extends string = string, TContext = never, TCause = never> = Readonly<{
106
+ type TaggedError<TName extends string = string, TContext extends Record<string, unknown> | undefined = undefined, TCause extends AnyTaggedError | undefined = undefined> = Readonly<{
79
107
  name: TName;
80
108
  message: string;
81
109
  } & WithContext<TContext> & WithCause<TCause>>;
@@ -117,13 +145,6 @@ type TaggedError<TName extends string = string, TContext = never, TCause = never
117
145
  * ```
118
146
  */
119
147
  declare function extractErrorMessage(error: unknown): string;
120
- /**
121
- * Base type for any tagged error, used as a constraint for cause parameters.
122
- */
123
- type AnyTaggedError = {
124
- name: string;
125
- message: string;
126
- };
127
148
  /**
128
149
  * Replaces the "Error" suffix with "Err" suffix in error type names.
129
150
  *
@@ -138,133 +159,103 @@ type AnyTaggedError = {
138
159
  */
139
160
  type ReplaceErrorWithErr<T extends `${string}Error`> = T extends `${infer TBase}Error` ? `${TBase}Err` : never;
140
161
  /**
141
- * Return type when neither context nor cause are constrained.
142
- * Both factory functions accept any context and cause at call time.
162
+ * Return type when neither context nor cause are constrained (flexible mode).
163
+ * Context and cause are optional with loose typing.
143
164
  */
144
165
  type FlexibleFactories<TName extends `${string}Error`> = { [K in TName]: FlexibleErrorConstructor<K> } & { [K in ReplaceErrorWithErr<TName>]: FlexibleErrConstructor<TName> };
145
166
  /**
146
- * Return type when context is fixed but cause is flexible.
147
- * Context shape is locked, but cause can be any TaggedError at call time.
167
+ * Return type when context is fixed.
168
+ * Context is required with exact type; cause is optional.
148
169
  */
149
170
  type ContextFixedFactories<TName extends `${string}Error`, TContext extends Record<string, unknown>> = { [K in TName]: ContextFixedErrorConstructor<K, TContext> } & { [K in ReplaceErrorWithErr<TName>]: ContextFixedErrConstructor<TName, TContext> };
150
171
  /**
151
172
  * Return type when both context and cause are fixed.
152
- * Both shapes are locked at factory creation time.
173
+ * Context is required; cause is optional but constrained to specific type.
153
174
  */
154
175
  type BothFixedFactories<TName extends `${string}Error`, TContext extends Record<string, unknown>, TCause extends AnyTaggedError> = { [K in TName]: BothFixedErrorConstructor<K, TContext, TCause> } & { [K in ReplaceErrorWithErr<TName>]: BothFixedErrConstructor<TName, TContext, TCause> };
155
176
  /**
156
177
  * Creates plain TaggedError objects with flexible context and cause.
157
- * Uses function overloads to precisely match return types to inputs.
178
+ * Single signature: context and cause are optional with loose typing.
158
179
  */
159
- type FlexibleErrorConstructor<TName extends string> = {
160
- (input: {
161
- message: string;
162
- }): TaggedError<TName, never, never>;
163
- <TContext extends Record<string, unknown>>(input: {
164
- message: string;
165
- context: TContext;
166
- }): TaggedError<TName, TContext, never>;
167
- <TCause extends AnyTaggedError>(input: {
168
- message: string;
169
- cause: TCause;
170
- }): TaggedError<TName, never, TCause>;
171
- <TContext extends Record<string, unknown>, TCause extends AnyTaggedError>(input: {
172
- message: string;
173
- context: TContext;
174
- cause: TCause;
175
- }): TaggedError<TName, TContext, TCause>;
176
- };
180
+ type FlexibleErrorConstructor<TName extends string> = (input: {
181
+ message: string;
182
+ context?: Record<string, unknown>;
183
+ cause?: AnyTaggedError;
184
+ }) => TaggedError<TName>;
177
185
  /**
178
186
  * Creates Err-wrapped TaggedError objects with flexible context and cause.
187
+ * Single signature: context and cause are optional with loose typing.
179
188
  */
180
- type FlexibleErrConstructor<TName extends string> = {
181
- (input: {
182
- message: string;
183
- }): Err<TaggedError<TName, never, never>>;
184
- <TContext extends Record<string, unknown>>(input: {
185
- message: string;
186
- context: TContext;
187
- }): Err<TaggedError<TName, TContext, never>>;
188
- <TCause extends AnyTaggedError>(input: {
189
- message: string;
190
- cause: TCause;
191
- }): Err<TaggedError<TName, never, TCause>>;
192
- <TContext extends Record<string, unknown>, TCause extends AnyTaggedError>(input: {
193
- message: string;
194
- context: TContext;
195
- cause: TCause;
196
- }): Err<TaggedError<TName, TContext, TCause>>;
197
- };
189
+ type FlexibleErrConstructor<TName extends string> = (input: {
190
+ message: string;
191
+ context?: Record<string, unknown>;
192
+ cause?: AnyTaggedError;
193
+ }) => Err<TaggedError<TName>>;
198
194
  /**
199
- * Creates plain TaggedError objects with fixed context but flexible cause.
200
- * Context is always required. Cause is optional and inferred at call site.
195
+ * Creates plain TaggedError objects with fixed context.
196
+ * Single signature: context is required, cause is optional.
201
197
  */
202
- type ContextFixedErrorConstructor<TName extends string, TContext extends Record<string, unknown>> = {
203
- (input: {
204
- message: string;
205
- context: TContext;
206
- }): TaggedError<TName, TContext, never>;
207
- <TCause extends AnyTaggedError>(input: {
208
- message: string;
209
- context: TContext;
210
- cause: TCause;
211
- }): TaggedError<TName, TContext, TCause>;
212
- };
198
+ type ContextFixedErrorConstructor<TName extends string, TContext extends Record<string, unknown>> = (input: {
199
+ message: string;
200
+ context: TContext;
201
+ cause?: AnyTaggedError;
202
+ }) => TaggedError<TName, TContext>;
213
203
  /**
214
- * Creates Err-wrapped TaggedError objects with fixed context but flexible cause.
204
+ * Creates Err-wrapped TaggedError objects with fixed context.
205
+ * Single signature: context is required, cause is optional.
215
206
  */
216
- type ContextFixedErrConstructor<TName extends string, TContext extends Record<string, unknown>> = {
217
- (input: {
218
- message: string;
219
- context: TContext;
220
- }): Err<TaggedError<TName, TContext, never>>;
221
- <TCause extends AnyTaggedError>(input: {
222
- message: string;
223
- context: TContext;
224
- cause: TCause;
225
- }): Err<TaggedError<TName, TContext, TCause>>;
226
- };
207
+ type ContextFixedErrConstructor<TName extends string, TContext extends Record<string, unknown>> = (input: {
208
+ message: string;
209
+ context: TContext;
210
+ cause?: AnyTaggedError;
211
+ }) => Err<TaggedError<TName, TContext>>;
227
212
  /**
228
213
  * Creates plain TaggedError objects with both context and cause fixed.
229
- * Context is required. Cause is optional but must match the specified type.
214
+ * Single signature: context is required, cause is optional but constrained.
230
215
  */
231
- type BothFixedErrorConstructor<TName extends string, TContext extends Record<string, unknown>, TCause extends AnyTaggedError> = {
232
- (input: {
233
- message: string;
234
- context: TContext;
235
- }): TaggedError<TName, TContext, never>;
236
- (input: {
237
- message: string;
238
- context: TContext;
239
- cause: TCause;
240
- }): TaggedError<TName, TContext, TCause>;
241
- };
216
+ type BothFixedErrorConstructor<TName extends string, TContext extends Record<string, unknown>, TCause extends AnyTaggedError> = (input: {
217
+ message: string;
218
+ context: TContext;
219
+ cause?: TCause;
220
+ }) => TaggedError<TName, TContext, TCause>;
242
221
  /**
243
222
  * Creates Err-wrapped TaggedError objects with both context and cause fixed.
223
+ * Single signature: context is required, cause is optional but constrained.
244
224
  */
245
- type BothFixedErrConstructor<TName extends string, TContext extends Record<string, unknown>, TCause extends AnyTaggedError> = {
246
- (input: {
247
- message: string;
248
- context: TContext;
249
- }): Err<TaggedError<TName, TContext, never>>;
250
- (input: {
251
- message: string;
252
- context: TContext;
253
- cause: TCause;
254
- }): Err<TaggedError<TName, TContext, TCause>>;
255
- };
225
+ type BothFixedErrConstructor<TName extends string, TContext extends Record<string, unknown>, TCause extends AnyTaggedError> = (input: {
226
+ message: string;
227
+ context: TContext;
228
+ cause?: TCause;
229
+ }) => Err<TaggedError<TName, TContext, TCause>>;
256
230
  /**
257
231
  * Creates two factory functions for building tagged errors with type-safe error chaining.
258
232
  *
233
+ * @deprecated Use `defineError()` instead for a cleaner fluent API:
234
+ * ```ts
235
+ * // Before
236
+ * const { FileError } = createTaggedError<'FileError', { path: string }>('FileError')
237
+ *
238
+ * // After
239
+ * const { FileError } = defineError('FileError')
240
+ * .withContext<{ path: string }>()
241
+ * ```
242
+ *
259
243
  * Given an error name like "NetworkError", this returns:
260
244
  * - `NetworkError`: Creates a plain TaggedError object
261
245
  * - `NetworkErr`: Creates a TaggedError object wrapped in an Err result
262
246
  *
263
247
  * **Three usage modes:**
264
248
  *
265
- * 1. **Flexible mode** (no type params): Context and cause are optional, any shape accepted
266
- * 2. **Fixed context mode** (TContext specified): Context is required with that exact shape
267
- * 3. **Both fixed mode** (TContext + TCause): Context required, cause (if provided) must match
249
+ * 1. **Flexible mode** (no type params): Context and cause are optional, loosely typed
250
+ * 2. **Fixed context mode** (TContext specified): Context is required with exact shape
251
+ * 3. **Both fixed mode** (TContext + TCause): Context required, cause constrained
252
+ *
253
+ * **ReturnType works correctly in all modes:**
254
+ * ```ts
255
+ * const { NetworkError } = createTaggedError('NetworkError');
256
+ * type NetworkError = ReturnType<typeof NetworkError>;
257
+ * // = TaggedError<'NetworkError'> with optional context/cause
258
+ * ```
268
259
  *
269
260
  * @template TName - The name of the error type (must end with "Error")
270
261
  * @template TContext - Optional fixed context shape (makes context required)
@@ -273,10 +264,14 @@ type BothFixedErrConstructor<TName extends string, TContext extends Record<strin
273
264
  *
274
265
  * @example
275
266
  * ```ts
276
- * // Mode 1: Flexible - context optional, any shape
267
+ * // Mode 1: Flexible - context and cause optional, loosely typed
277
268
  * const { NetworkError, NetworkErr } = createTaggedError('NetworkError');
278
269
  * NetworkError({ message: 'Connection failed' });
279
270
  * NetworkError({ message: 'Timeout', context: { url: 'https://...' } });
271
+ * NetworkError({ message: 'Failed', cause: otherError });
272
+ *
273
+ * // Type annotation works with ReturnType:
274
+ * type NetworkError = ReturnType<typeof NetworkError>;
280
275
  *
281
276
  * // Mode 2: Fixed context - context REQUIRED with exact shape
282
277
  * type BlobContext = { filename: string; code: 'INVALID' | 'TOO_LARGE' };
@@ -293,6 +288,149 @@ type BothFixedErrConstructor<TName extends string, TContext extends Record<strin
293
288
  declare function createTaggedError<TName extends `${string}Error`>(name: TName): FlexibleFactories<TName>;
294
289
  declare function createTaggedError<TName extends `${string}Error`, TContext extends Record<string, unknown>>(name: TName): ContextFixedFactories<TName, TContext>;
295
290
  declare function createTaggedError<TName extends `${string}Error`, TContext extends Record<string, unknown>, TCause extends AnyTaggedError>(name: TName): BothFixedFactories<TName, TContext, TCause>;
291
+ /**
292
+ * Helper type that determines optionality based on whether T includes undefined.
293
+ * - If T includes undefined → property is optional
294
+ * - If T does not include undefined → property is required
295
+ */
296
+ type OptionalIfUndefined<T, TKey extends string> = undefined extends T ? { [K in TKey]?: Exclude<T, undefined> } : { [K in TKey]: T };
297
+ /**
298
+ * Input type for error constructors with fluent API context/cause handling.
299
+ */
300
+ type ErrorInput<TContext extends Record<string, unknown> | undefined, TCause extends AnyTaggedError | undefined> = {
301
+ message: string;
302
+ } & (TContext extends undefined ? {
303
+ context?: Record<string, unknown>;
304
+ } : OptionalIfUndefined<TContext, "context">) & (TCause extends undefined ? {
305
+ cause?: AnyTaggedError;
306
+ } : OptionalIfUndefined<TCause, "cause">);
307
+ /**
308
+ * The factories object returned by defineError and its builder methods.
309
+ */
310
+ type ErrorFactories<TName extends `${string}Error`, TContext extends Record<string, unknown> | undefined, TCause extends AnyTaggedError | undefined> = { [K in TName]: (input: ErrorInput<TContext, TCause>) => TaggedError<TName, TContext, TCause> } & { [K in ReplaceErrorWithErr<TName>]: (input: ErrorInput<TContext, TCause>) => Err<TaggedError<TName, TContext, TCause>> };
311
+ /**
312
+ * Builder interface for the fluent defineError API.
313
+ * Provides chaining methods and the error factories.
314
+ */
315
+ type ErrorBuilder<TName extends `${string}Error`, TContext extends Record<string, unknown> | undefined = undefined, TCause extends AnyTaggedError | undefined = undefined> = ErrorFactories<TName, TContext, TCause> & {
316
+ /**
317
+ * Constrains the context type for this error.
318
+ *
319
+ * Optionality is determined by whether the type includes `undefined`:
320
+ * - `withContext<T>()` where T doesn't include undefined → context is **required**
321
+ * - `withContext<T | undefined>()` → context is **optional** but typed when provided
322
+ *
323
+ * @typeParam T - The shape of the context object. Include `| undefined` to make optional.
324
+ *
325
+ * @example Required context
326
+ * ```ts
327
+ * const { FileError } = defineError('FileError')
328
+ * .withContext<{ path: string }>()
329
+ *
330
+ * FileError({ message: 'Not found', context: { path: '/etc/config' } }) // OK
331
+ * FileError({ message: 'Not found' }) // Type error: context required
332
+ * ```
333
+ *
334
+ * @example Optional but typed context
335
+ * ```ts
336
+ * const { LogError } = defineError('LogError')
337
+ * .withContext<{ file: string; line: number } | undefined>()
338
+ *
339
+ * LogError({ message: 'Parse error' }) // OK
340
+ * LogError({ message: 'Parse error', context: { file: 'app.ts', line: 42 } }) // OK
341
+ * ```
342
+ */
343
+ withContext<T extends Record<string, unknown> | undefined>(): ErrorBuilder<TName, T, TCause>;
344
+ /**
345
+ * Constrains the cause type for this error.
346
+ *
347
+ * Optionality is determined by whether the type includes `undefined`:
348
+ * - `withCause<T>()` where T doesn't include undefined → cause is **required**
349
+ * - `withCause<T | undefined>()` → cause is **optional** but typed when provided
350
+ *
351
+ * Since cause is typically optional, include `| undefined` in most cases.
352
+ *
353
+ * @typeParam T - The allowed cause type(s). Include `| undefined` to make optional.
354
+ *
355
+ * @example Optional typed cause (common)
356
+ * ```ts
357
+ * const { ServiceError } = defineError('ServiceError')
358
+ * .withCause<DbError | CacheError | undefined>()
359
+ *
360
+ * ServiceError({ message: 'Failed' }) // OK
361
+ * ServiceError({ message: 'Failed', cause: dbError }) // OK
362
+ * ```
363
+ *
364
+ * @example Required cause (for wrapper errors)
365
+ * ```ts
366
+ * const { UnhandledError } = defineError('UnhandledError')
367
+ * .withCause<AnyTaggedError>()
368
+ *
369
+ * UnhandledError({ message: 'Unexpected', cause: originalError }) // OK
370
+ * UnhandledError({ message: 'Unexpected' }) // Type error: cause required
371
+ * ```
372
+ */
373
+ withCause<T extends AnyTaggedError | undefined>(): ErrorBuilder<TName, TContext, T>;
374
+ };
375
+ /**
376
+ * Defines a new tagged error type with a fluent builder API.
377
+ *
378
+ * Returns an object containing:
379
+ * - `{Name}Error`: Factory function that creates plain TaggedError objects
380
+ * - `{Name}Err`: Factory function that creates Err-wrapped TaggedError objects
381
+ * - `withContext<T>()`: Chain method to constrain context type
382
+ * - `withCause<T>()`: Chain method to constrain cause type
383
+ *
384
+ * **Default behavior (no chaining):**
385
+ * - `context` is optional and accepts any `Record<string, unknown>`
386
+ * - `cause` is optional and accepts any `AnyTaggedError`
387
+ *
388
+ * **Optionality via type unions:**
389
+ * Both `withContext` and `withCause` determine optionality based on whether
390
+ * the type includes `undefined`:
391
+ * - `T` without undefined → property is required
392
+ * - `T | undefined` → property is optional but typed when provided
393
+ *
394
+ * @template TName - The name of the error type (must end with "Error")
395
+ * @param name - The name of the error type
396
+ *
397
+ * @example Simple error (flexible mode)
398
+ * ```ts
399
+ * const { NetworkError, NetworkErr } = defineError('NetworkError')
400
+ *
401
+ * NetworkError({ message: 'Connection failed' })
402
+ * NetworkError({ message: 'Timeout', context: { url: 'https://...' } })
403
+ * ```
404
+ *
405
+ * @example Required context
406
+ * ```ts
407
+ * const { ApiError, ApiErr } = defineError('ApiError')
408
+ * .withContext<{ endpoint: string; status: number }>()
409
+ *
410
+ * ApiError({ message: 'Failed', context: { endpoint: '/users', status: 500 } })
411
+ * // ApiError({ message: 'Failed' }) // Type error: context required
412
+ * ```
413
+ *
414
+ * @example Optional typed cause
415
+ * ```ts
416
+ * const { ServiceError } = defineError('ServiceError')
417
+ * .withCause<DbError | CacheError | undefined>()
418
+ *
419
+ * ServiceError({ message: 'Failed' }) // OK
420
+ * ServiceError({ message: 'Failed', cause: dbError }) // OK, typed
421
+ * ```
422
+ *
423
+ * @example Full example with both
424
+ * ```ts
425
+ * const { UserServiceError } = defineError('UserServiceError')
426
+ * .withContext<{ userId: string }>()
427
+ * .withCause<RepoError | undefined>()
428
+ *
429
+ * // Type extraction works
430
+ * type UserServiceError = ReturnType<typeof UserServiceError>
431
+ * ```
432
+ */
433
+ declare function defineError<TName extends `${string}Error`>(name: TName): ErrorBuilder<TName>;
296
434
  //#endregion
297
- export { TaggedError, createTaggedError, extractErrorMessage };
435
+ export { AnyTaggedError, TaggedError, createTaggedError, defineError, extractErrorMessage };
298
436
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/error/types.ts","../../src/error/utils.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/error/types.ts","../../src/error/utils.ts"],"sourcesContent":[],"mappings":";;;;;;AAGY,KAAA,cAAA,GAAc;EAUrB,IAAA,EAAA,MAAA;EAAW,OAAA,EAAA,MAAA;CAAA;;;;;;AAIO;AAAA;;KAJlB,WAgBqB,CAAA,QAAA,CAAA,GAAA,CAhBI,QAgBJ,CAAA,SAAA,CAAA,SAAA,CAAA,GAAA;EAAM,OACnB,CAAA,EAhBE,MAgBF,CAAA,MAAA,EAAA,OAAA,CAAA;CAAc,GAAA,CAAA,SACH,CAAA,SAAA,CAhBA,QAgBA,CAAA,GAAA;EAAM,OACR,CAAA,EAhBN,OAgBM,CAhBE,QAgBF,EAAA,SAAA,CAAA;CAAM,GAAA;EAAP,OACP,EAhBC,QAgBD;AAAM,CAAA;AAiEpB;;;;;;;;;;AAIY,KAzEP,SAyEO,CAAA,MAAA,CAAA,GAAA,CAzEc,MAyEd,CAAA,SAAA,CAAA,SAAA,CAAA,GAAA;UAxEC;yBACW;UACV,QAAQ;ACMtB,CAAA,GAAgB;EAgEX,KAAA,CAAA,EDrES,MCqET;CAAmB;;;AACmB;AAAA;;;;;;;;;AAae;AAAA;;;;;;;;;;;;AAaI;AAAA;;;;;;;;;;;;;;;AAcH;AAAA;;;;;;AAmB1C;AAAA;;;;;;;AAUR;AAAA;;;;;;AAiBgB,KD3Fb,WC2Fa,CAAA,cAAA,MAAA,GAAA,MAAA,EAAA,iBDzFP,MCyFO,CAAA,MAAA,EAAA,OAAA,CAAA,GAAA,SAAA,GAAA,SAAA,EAAA,eDxFT,cCwFS,GAAA,SAAA,GAAA,SAAA,CAAA,GDvFrB,QCuFqB,CAAA;EAAQ,IAA3B,EDrFE,KCqFF;EAAW,OAAA,EAAA,MAAA;AAAA,CAAA,GDnFZ,WCyFA,CDzFY,QCyFZ,CAAA,GDxFH,SCwF6B,CDxFnB,MCwFmB,CAAA,CAAA;;;;ADhM/B;AAA+D;;;;;;;;AAcxC;AAAA;;;;;;;;AAgBH;AAiEpB;;;;;;;;;;AAIY;;;;AChEZ;AAgEK,iBAhEW,mBAAA,CAgEQ,KAAA,EAAA,OAAA,CAAA,EAAA,MAAA;;;;AACmB;AAAA;;;;;;;;KADtC,mBAc+B,CAAA,UAAA,GAAA,MAAA,OAAA,CAAA,GAbnC,CAamC,SAAA,GAAA,KAAA,MAAA,OAAA,GAAA,GAbE,KAaF,KAAA,GAAA,KAAA;AAAsB;AAAA;;;KAHrD,iBAcE,CAAA,cAAA,GAAA,MAAA,OAAA,CAAA,GAAA,QAbA,KAaqC,GAb7B,wBAa6B,CAbJ,CAaI,CAAA,EAAC,GAAA,QAXtC,mBAWQ,CAXY,KAWZ,CAAA,GAXqB,sBAWrB,CAX4C,KAW5C,CAAA,EAA4B;;;;;AAEmB,KANzD,qBAMyD,CAAA,cAAA,GAAA,MAAA,OAAA,EAAA,iBAJ5C,MAI4C,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA,GAAA,QAFvD,KASF,GATU,4BASQ,CATqB,CASrB,EATwB,QASxB,CAAA,EAAA,GAAA,QAPhB,mBASW,CATS,KAST,CAAA,GATkB,0BASlB,CAT6C,KAS7C,EAToD,QASpD,CAAA,EAAM;;;;;KAFnB,kBAKU,CAAA,cAAA,GAAA,MAAA,OAAA,EAAA,iBAHG,MAGH,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,eAFC,cAED,CAAA,GAAA,QAAR,KAEoB,GAFZ,yBAEY,CAFc,CAEd,EAFiB,QAEjB,EAF2B,MAE3B,CAAA,EAAK,GAAA,QAAzB,mBACL,CADyB,KACzB,CAAA,GADkC,uBAClC,CAAA,KAAA,EACA,QADA,EAEA,MAFA,CAAA,EAAK;;;AADoD;AAAA;KAetD,wBAAwB,CAAA,cAAA,MAAA,CAAA,GAAA,CAAA,KAAA,EAAA;EAAA,OAElB,EAAA,MAAA;EAAM,OACR,CAAA,EADE,MACF,CAAA,MAAA,EAAA,OAAA,CAAA;EAAc,KACL,CAAA,EADT,cACS;CAAK,EAAA,GAAjB,WAAA,CAAY,KAAZ,CAAA;AAAW;AAAA;;;KAMZ,sBAGI,CAAA,cAAA,MAAA,CAAA,GAAA,CAAA,KAAA,EAAA;EAAc,OACD,EAAA,MAAA;EAAK,OAAjB,CAAA,EAFC,MAED,CAAA,MAAA,EAAA,OAAA,CAAA;EAAW,KAAf,CAAA,EADG,cACH;AAAG,CAAA,EAAA,GAAH,GAAG,CAAC,WAAD,CAAa,KAAb,CAAA,CAAA;AAAA;;;;KAUJ,4BAMI,CAAA,cAAA,MAAA,EAAA,iBAJS,MAIT,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA,GAAA,CAAA,KAAA,EAAA;EAAc,OACL,EAAA,MAAA;EAAK,OAAE,EAFf,QAEe;EAAQ,KAA3B,CAAA,EADG,cACH;AAAW,CAAA,EAAA,GAAX,WAAW,CAAC,KAAD,EAAQ,QAAR,CAAA;AAAA;;;;KAMZ,0BAMI,CAAA,cAAA,MAAA,EAAA,iBAJS,MAIT,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA,GAAA,CAAA,KAAA,EAAA;EAAc,OACD,EAAA,MAAA;EAAK,OAAE,EAFnB,QAEmB;EAAQ,KAA3B,CAAA,EADD,cACC;CAAW,EAAA,GAAf,GAAA,CAAI,WAAJ,CAAgB,KAAhB,EAAuB,QAAvB,CAAA,CAAA;AAAG;AAAA;;;KAUJ,yBAGW,CAAA,cAAA,MAAA,EAAA,iBADE,MACF,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,eAAA,cAAA,CAAA,GAAA,CAAA,KAAA,EAAA;EAAc,OAGpB,EAAA,MAAA;EAAQ,OACT,EADC,QACD;EAAM,KACG,CAAA,EADT,MACS;CAAK,EAAA,GAAjB,WAAmB,CAAP,KAAO,EAAA,QAAA,EAAU,MAAV,CAAA;;;AAAR;AAAA;KAMZ,uBAAuB,CAAA,cAAA,MAAA,EAAA,iBAEV,MAFU,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,eAGZ,cAHY,CAAA,GAAA,CAAA,KAAA,EAAA;EAAA,OAEV,EAAA,MAAA;EAAM,OACR,EAGN,QAHM;EAAc,KAGpB,CAAA,EACD,MADC;CAAQ,EAAA,GAEZ,GADG,CACC,WADD,CACa,KADb,EACoB,QADpB,EAC8B,MAD9B,CAAA,CAAA;;;;;;AACA;AAiET;;;;;AAEoB;AAGpB;;;;;;;AAGqC;AAGrC;;;;;;;;;AAIkC;AAA0B;;;;;;;;AAsCzC;AAAA;;;;;;;;;;;;AAaI;AAAA;;;;;;AAWO,iBA7Ed,iBA6Ec,CAAA,cAAA,GAAA,MAAA,OAAA,CAAA,CAAA,IAAA,EA5EvB,KA4EuB,CAAA,EA3E3B,iBA2E2B,CA3ET,KA2ES,CAAA;AAArB,iBAxEO,iBAwEP,CAAA,cAAA,GAAA,MAAA,OAAA,EAAA,iBAtES,MAsET,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA,CAAA,IAAA,EArED,KAqEC,CAAA,EArEO,qBAqEP,CArE6B,KAqE7B,EArEoC,QAqEpC,CAAA;AACS,iBAnEF,iBAmEE,CAAA,cAAA,GAAA,MAAA,OAAA,EAAA,iBAjEA,MAiEA,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,eAhEF,cAgEE,CAAA,CAAA,IAAA,EA/DV,KA+DU,CAAA,EA/DF,kBA+DE,CA/DiB,KA+DjB,EA/DwB,QA+DxB,EA/DkC,MA+DlC,CAAA;;;;;;KA3Bb,mBA8Be,CAAA,CAAA,EAAA,aAAA,MAAA,CAAA,GAAA,SAAA,SA9BiD,CA8BjD,GAAA,QA7BT,IA6BmB,IA7BX,OA6BW,CA7BH,CA6BG,EAAA,SAAA,CAAA,EAAM,GAAA,QA5BzB,IA6BW,GA7BJ,CA6BI,EAAK;;;;AAAlB,KAxBJ,UAwBI,CAAA,iBAvBS,MAuBT,CAAA,MAAA,EAAA,OAAA,CAAA,GAAA,SAAA,EAAA,eAtBO,cAsBP,GAAA,SAAA,CAAA,GAAA;EAOJ,OAAA,EAAA,MAAY;CAAA,GAAA,CA5BU,QA4BV,SAAA,SAAA,GAAA;EAAA,OAEC,CAAA,EA7BH,MA6BG,CAAA,MAAA,EAAA,OAAA,CAAA;CAAM,GA5BrB,mBA6Ba,CA7BO,QA6BP,EAAA,SAAA,CAAA,CAAA,GAAA,CA5Bd,MA4Bc,SAAA,SAAA,GAAA;EAAc,KACX,CAAA,EA5BL,cA4BK;CAAK,GA3BpB,mBA2BsB,CA3BF,MA2BE,EAAA,OAAA,CAAA,CAAA;;;;KAtBrB,cAmDH,CAAA,cAAA,GAAA,MAAA,OAAA,EAAA,iBAjDgB,MAiDhB,CAAA,MAAA,EAAA,OAAA,CAAA,GAAA,SAAA,EAAA,eAhDc,cAgDd,GAAA,SAAA,CAAA,GAAA,QA9CK,KA+CL,GAAA,CAAA,KAAA,EA9CO,UA8CP,CA9CkB,QA8ClB,EA9C4B,MA8C5B,CAAA,EAAA,GA7CI,WA6CJ,CA7CgB,KA6ChB,EA7CuB,QA6CvB,EA7CiC,MA6CjC,CAAA,EAAC,GAAA,QA3CI,mBAyCwD,CAzCpC,KAyCoC,CAAA,GAAA,CAAA,KAAA,EAxCtD,UAwCsD,CAxC3C,QAwC2C,EAxCjC,MAwCiC,CAAA,EAAA,GAvCzD,GAuCyD,CAvCrD,WAuCqD,CAvCzC,KAuCyC,EAvClC,QAuCkC,EAvCxB,MAuCwB,CAAA,CAAA,EAAY;;;;;AAmCX,KAnE3D,YAmE2D,CAAA,cAAA,GAAA,MAAA,OAAA,EAAA,iBAjE9C,MAiE8C,CAAA,MAAA,EAAA,OAAA,CAAA,GAAA,SAAA,GAAA,SAAA,EAAA,eAhEhD,cAgEgD,GAAA,SAAA,GAAA,SAAA,CAAA,GA/D5D,cA+D4D,CA/D7C,KA+D6C,EA/DtC,QA+DsC,EA/D5B,MA+D4B,CAAA,GAAA;EAqEhD;;;;;AAED;;;;;;;;;;;;;;;;;;;;;;wBA1GQ,wCAAwC,aAC7D,OACA,GACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAgCmB,+BAA+B,aAClD,OACA,UACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkEc,kDACT,QACJ,aAAa"}
@@ -75,7 +75,86 @@ function createTaggedError(name) {
75
75
  [errName]: errConstructor
76
76
  };
77
77
  }
78
+ /**
79
+ * Defines a new tagged error type with a fluent builder API.
80
+ *
81
+ * Returns an object containing:
82
+ * - `{Name}Error`: Factory function that creates plain TaggedError objects
83
+ * - `{Name}Err`: Factory function that creates Err-wrapped TaggedError objects
84
+ * - `withContext<T>()`: Chain method to constrain context type
85
+ * - `withCause<T>()`: Chain method to constrain cause type
86
+ *
87
+ * **Default behavior (no chaining):**
88
+ * - `context` is optional and accepts any `Record<string, unknown>`
89
+ * - `cause` is optional and accepts any `AnyTaggedError`
90
+ *
91
+ * **Optionality via type unions:**
92
+ * Both `withContext` and `withCause` determine optionality based on whether
93
+ * the type includes `undefined`:
94
+ * - `T` without undefined → property is required
95
+ * - `T | undefined` → property is optional but typed when provided
96
+ *
97
+ * @template TName - The name of the error type (must end with "Error")
98
+ * @param name - The name of the error type
99
+ *
100
+ * @example Simple error (flexible mode)
101
+ * ```ts
102
+ * const { NetworkError, NetworkErr } = defineError('NetworkError')
103
+ *
104
+ * NetworkError({ message: 'Connection failed' })
105
+ * NetworkError({ message: 'Timeout', context: { url: 'https://...' } })
106
+ * ```
107
+ *
108
+ * @example Required context
109
+ * ```ts
110
+ * const { ApiError, ApiErr } = defineError('ApiError')
111
+ * .withContext<{ endpoint: string; status: number }>()
112
+ *
113
+ * ApiError({ message: 'Failed', context: { endpoint: '/users', status: 500 } })
114
+ * // ApiError({ message: 'Failed' }) // Type error: context required
115
+ * ```
116
+ *
117
+ * @example Optional typed cause
118
+ * ```ts
119
+ * const { ServiceError } = defineError('ServiceError')
120
+ * .withCause<DbError | CacheError | undefined>()
121
+ *
122
+ * ServiceError({ message: 'Failed' }) // OK
123
+ * ServiceError({ message: 'Failed', cause: dbError }) // OK, typed
124
+ * ```
125
+ *
126
+ * @example Full example with both
127
+ * ```ts
128
+ * const { UserServiceError } = defineError('UserServiceError')
129
+ * .withContext<{ userId: string }>()
130
+ * .withCause<RepoError | undefined>()
131
+ *
132
+ * // Type extraction works
133
+ * type UserServiceError = ReturnType<typeof UserServiceError>
134
+ * ```
135
+ */
136
+ function defineError(name) {
137
+ const createBuilder = () => {
138
+ const errorConstructor = (input) => ({
139
+ name,
140
+ ...input
141
+ });
142
+ const errName = name.replace(/Error$/, "Err");
143
+ const errConstructor = (input) => Err(errorConstructor(input));
144
+ return {
145
+ [name]: errorConstructor,
146
+ [errName]: errConstructor,
147
+ withContext() {
148
+ return createBuilder();
149
+ },
150
+ withCause() {
151
+ return createBuilder();
152
+ }
153
+ };
154
+ };
155
+ return createBuilder();
156
+ }
78
157
 
79
158
  //#endregion
80
- export { createTaggedError, extractErrorMessage };
159
+ export { createTaggedError, defineError, extractErrorMessage };
81
160
  //# sourceMappingURL=index.js.map