@nice-code/error 0.7.0 → 0.9.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.
Files changed (35) hide show
  1. package/build/index.d.ts +913 -0
  2. package/build/index.js +1004 -933
  3. package/build/index.js.map +1 -0
  4. package/package.json +5 -4
  5. package/build/types/NiceError/NiceError.d.ts +0 -148
  6. package/build/types/NiceError/NiceError.enums.d.ts +0 -5
  7. package/build/types/NiceError/NiceError.types.d.ts +0 -204
  8. package/build/types/NiceError/NiceErrorHydrated.d.ts +0 -51
  9. package/build/types/NiceError/nice_error.static.d.ts +0 -2
  10. package/build/types/NiceErrorDefined/NiceErrorDefined.d.ts +0 -135
  11. package/build/types/NiceErrorDefined/defineNiceError.d.ts +0 -7
  12. package/build/types/NiceErrorDefined/err.d.ts +0 -59
  13. package/build/types/NiceErrorHandler/NiceErrorHandler.d.ts +0 -23
  14. package/build/types/NiceErrorHandler/NiceErrorHandler.types.d.ts +0 -82
  15. package/build/types/NiceErrorHandler/handleWith.d.ts +0 -8
  16. package/build/types/example/error_usage_example.d.ts +0 -41
  17. package/build/types/index.d.ts +0 -18
  18. package/build/types/internal/index.d.ts +0 -1
  19. package/build/types/internal/nice_core_errors.d.ts +0 -49
  20. package/build/types/test/helpers/nice_error_testing.static.d.ts +0 -3
  21. package/build/types/test/helpers/test_utils.d.ts +0 -1
  22. package/build/types/utils/castAndHydrate.d.ts +0 -35
  23. package/build/types/utils/castNiceError.d.ts +0 -15
  24. package/build/types/utils/inspectPotentialError/inspectPotentialError.d.ts +0 -2
  25. package/build/types/utils/inspectPotentialError/inspectPotentialError.enums.d.ts +0 -9
  26. package/build/types/utils/inspectPotentialError/inspectPotentialError.types.d.ts +0 -51
  27. package/build/types/utils/isNiceErrorObject.d.ts +0 -12
  28. package/build/types/utils/isRegularErrorObject.d.ts +0 -2
  29. package/build/types/utils/jsErrorOrCastJsError.d.ts +0 -1
  30. package/build/types/utils/logger.d.ts +0 -3
  31. package/build/types/utils/matchFirst.d.ts +0 -35
  32. package/build/types/utils/packError/causePack.d.ts +0 -2
  33. package/build/types/utils/packError/msgPack.d.ts +0 -2
  34. package/build/types/utils/packError/packError.d.ts +0 -3
  35. package/build/types/utils/packError/packError.enums.d.ts +0 -5
@@ -0,0 +1,913 @@
1
+ //#region src/utils/packError/packError.enums.d.ts
2
+ declare enum EErrorPackType {
3
+ no_pack = "no_pack",
4
+ msg_pack = "msg_pack",
5
+ cause_pack = "cause_pack"
6
+ }
7
+ //#endregion
8
+ //#region src/NiceError/NiceError.enums.d.ts
9
+ declare enum EContextSerializedState {
10
+ serde_unset = "serde_unset",
11
+ unhydrated = "unhydrated",
12
+ hydrated = "hydrated"
13
+ }
14
+ //#endregion
15
+ //#region src/NiceError/NiceError.types.d.ts
16
+ interface IRegularErrorJsonObject extends Omit<Error, "stack"> {
17
+ name: string;
18
+ message: string;
19
+ stack?: string | undefined;
20
+ cause?: unknown;
21
+ }
22
+ type JSONSerializableValue = string | number | boolean | null | {
23
+ [key: string]: JSONSerializableValue;
24
+ } | JSONSerializableValue[];
25
+ interface ISerializationDefinition<C, D extends JSONSerializableValue> {
26
+ toJsonSerializable: (context: C) => D;
27
+ fromJsonSerializable: (obj: D) => C;
28
+ }
29
+ /** Describes the context attached to a single error id. */
30
+ interface INiceErrorContextDefinition<C, D extends JSONSerializableValue = JSONSerializableValue> {
31
+ required?: boolean;
32
+ serialization?: ISerializationDefinition<C, D>;
33
+ }
34
+ /**
35
+ * A single entry in a NiceErrorDefined schema.
36
+ * `C` is the context value type (defaults to `never` = no context).
37
+ */
38
+ interface INiceErrorIdMetadata<C = never, D extends JSONSerializableValue = JSONSerializableValue> {
39
+ context?: [C] extends [never] ? never : INiceErrorContextDefinition<C, D>;
40
+ /** Static message string OR a function that receives the context value and returns a string. */
41
+ message?: [C] extends [never] ? string : string | ((context: C) => string);
42
+ httpStatusCode?: [C] extends [never] ? number : number | ((context: C) => number);
43
+ }
44
+ /** A record mapping error-id string keys to their metadata. */
45
+ type TNiceErrorSchema = Record<string, INiceErrorIdMetadata<any>>;
46
+ /** Extracts the raw context value type `C` from a single schema entry. */
47
+ type TExtractContextType<M> = M extends INiceErrorIdMetadata<infer C> ? C : never;
48
+ /**
49
+ * Given a schema entry M, returns the context argument type expected by `fromId`:
50
+ *
51
+ * - `C = never` → `undefined` (no context field on this id)
52
+ * - `C` defined, `required: true` → `C` (context is a required argument)
53
+ * - `C` defined, `required` absent/false → `C | undefined` (context is optional)
54
+ *
55
+ * Note: `required: true` must be a literal `true` for TypeScript to narrow correctly.
56
+ * Use the `err()` helper (which preserves literal types) rather than writing schema
57
+ * entries inline without `as const`.
58
+ */
59
+ type ExtractFromIdContextArg<M> = M extends INiceErrorIdMetadata<infer C> ? [C] extends [never] ? undefined : M extends {
60
+ context: {
61
+ required: true;
62
+ };
63
+ } ? C : C | undefined : undefined;
64
+ /**
65
+ * No custom serializer is defined for this error id's context.
66
+ * `value` holds the typed context directly (plain JSON-safe value, or `undefined`
67
+ * if the context was optional and not provided).
68
+ *
69
+ * This state is safe across a JSON round-trip because no type information is lost.
70
+ */
71
+ type TContextStateNoSerialization<C> = {
72
+ kind: EContextSerializedState.serde_unset; /** The typed context value (or `undefined` if optional and not provided). */
73
+ value: C | undefined;
74
+ };
75
+ /**
76
+ * A custom serializer is defined, but the context has **not** been deserialized
77
+ * from its JSON-wire form yet.
78
+ *
79
+ * This state occurs after `castNiceError` reconstructs an error from a serialized
80
+ * payload. `value` is absent — the raw serialized representation is in `serialized`.
81
+ *
82
+ * Call `niceErrorDefined.hydrate(error)` to reconstruct the typed context via
83
+ * `fromJsonSerializable` and advance to the `"hydrated"` state.
84
+ */
85
+ type TContextStateUnhydrated = {
86
+ kind: EContextSerializedState.unhydrated; /** The JSON-serializable representation of the original context. */
87
+ serialized: JSONSerializableValue;
88
+ };
89
+ /**
90
+ * A custom serializer is defined, and the context is fully deserialized to its
91
+ * original typed value.
92
+ *
93
+ * This state is set when the error is first created via `fromId`/`fromContext`,
94
+ * or after `niceErrorDefined.hydrate(error)` reconstructs it.
95
+ *
96
+ * Note: `toJsonObject()` intentionally downgrades this to `"unhydrated"` on
97
+ * output so the flag cannot survive a JSON round-trip as a false positive.
98
+ */
99
+ type TContextStateHydrated<C> = {
100
+ kind: EContextSerializedState.hydrated; /** The typed context value — the original value as provided at error creation. */
101
+ value: C; /** The JSON-serializable representation (produced by `toJsonSerializable`). */
102
+ serialized: JSONSerializableValue;
103
+ };
104
+ /**
105
+ * Runtime context state — union of all three lifecycle states.
106
+ * Stored in `_errorDataMap` on a live `NiceError` instance.
107
+ */
108
+ type TContextState<C> = TContextStateNoSerialization<C> | TContextStateUnhydrated | TContextStateHydrated<C>;
109
+ /**
110
+ * Wire-safe context state — excludes `"hydrated"` because `toJsonObject()` downgrades
111
+ * it to `"unhydrated"` before serialization. This is the only state that appears in
112
+ * `INiceErrorJsonObject` and on errors reconstructed via `castNiceError`.
113
+ */
114
+ type TSerializedContextState<C> = TContextStateNoSerialization<C> | TContextStateUnhydrated;
115
+ /**
116
+ * Runtime reconciled data for a single error id, stored in `_errorDataMap`.
117
+ * Uses the full `TContextState` union (including `"hydrated"`).
118
+ */
119
+ type TErrorReconciledData<SCHEMA extends TNiceErrorSchema, K extends keyof SCHEMA> = {
120
+ contextState: TContextState<TExtractContextType<SCHEMA[K]>>;
121
+ message: string;
122
+ httpStatusCode: number;
123
+ timeAdded: number;
124
+ };
125
+ /**
126
+ * Wire-safe reconciled data — uses `TSerializedContextState` (no `"hydrated"`).
127
+ * This is the shape stored in `INiceErrorJsonObject.errorData` and transmitted
128
+ * over the wire. `"hydrated"` is excluded so that the serialization state can
129
+ * never be trusted after a JSON round-trip.
130
+ */
131
+ type TSerializedErrorReconciledData<SCHEMA extends TNiceErrorSchema, K extends TSchemaNiceErrorId<SCHEMA>> = {
132
+ contextState: TSerializedContextState<TExtractContextType<SCHEMA[K]>>;
133
+ message: string;
134
+ httpStatusCode: number;
135
+ timeAdded: number;
136
+ };
137
+ type TErrorDataForIdMap<SCHEMA extends TNiceErrorSchema, K extends TSchemaNiceErrorId<SCHEMA> = TSchemaNiceErrorId<SCHEMA>> = { [key in K]?: TErrorReconciledData<SCHEMA, K> };
138
+ /** Wire-safe version of `TErrorDataForIdMap`. Used in `INiceErrorJsonObject`. */
139
+ type TSerializedErrorDataMap<SCHEMA extends TNiceErrorSchema> = { [K in TSchemaNiceErrorId<SCHEMA>]?: TSerializedErrorReconciledData<SCHEMA, K> };
140
+ /**
141
+ * The Partial record that `fromContext` accepts: callers supply one or more
142
+ * { [errorId]: contextValue } entries and NiceError stores them all.
143
+ */
144
+ type TFromContextInput<SCHEMA extends TNiceErrorSchema> = { [K in TSchemaNiceErrorId<SCHEMA>]?: TExtractContextType<SCHEMA[K]> | undefined };
145
+ /**
146
+ * Resolves the args tuple for `fromId` / `addId`:
147
+ *
148
+ * - No context on this id → `[id]`
149
+ * - Context defined, `required: true` → `[id, context]`
150
+ * - Context defined, `required` absent/false → `[id] | [id, context]`
151
+ */
152
+ type FromIdArgs<ERR_DEF extends INiceErrorDomainProps, K extends TDomainNiceErrorId<ERR_DEF>> = [ExtractFromIdContextArg<ERR_DEF["schema"][K]>] extends [undefined] ? [id: K] : [undefined] extends [ExtractFromIdContextArg<ERR_DEF["schema"][K]>] ? [id: K] | [id: K, context: NonNullable<ExtractFromIdContextArg<ERR_DEF["schema"][K]>>] : [id: K, context: ExtractFromIdContextArg<ERR_DEF["schema"][K]>];
153
+ interface IPackErrorAs_Base {
154
+ packAs: EErrorPackType;
155
+ }
156
+ interface IPackErrorAs_MatchEnvVar extends IPackErrorAs_Base {
157
+ matchEnvVar: string;
158
+ }
159
+ interface IDefineNewNiceErrorDomainOptions<ERR_DOMAIN extends string = string, SCHEMA extends TNiceErrorSchema = TNiceErrorSchema> {
160
+ defaultHttpStatusCode?: number;
161
+ defaultMessage?: string;
162
+ packAs?: () => EErrorPackType | void;
163
+ domain: ERR_DOMAIN;
164
+ schema: SCHEMA;
165
+ }
166
+ interface INiceErrorDomainProps<ERR_DOMAINS extends string[] = string[], SCHEMA extends TNiceErrorSchema = TNiceErrorSchema> {
167
+ packAs?: () => EErrorPackType | void;
168
+ defaultHttpStatusCode?: number;
169
+ defaultMessage?: string;
170
+ domain: ERR_DOMAINS[number];
171
+ allDomains: ERR_DOMAINS;
172
+ schema: SCHEMA;
173
+ }
174
+ interface INiceErrorJsonObject<ERR_DEF extends INiceErrorDomainProps = INiceErrorDomainProps, ID extends TDomainNiceErrorId<ERR_DEF> = TDomainNiceErrorId<ERR_DEF>> {
175
+ name: "NiceError";
176
+ def: Omit<ERR_DEF, "schema">;
177
+ ids: ID[];
178
+ /** Wire-safe error data — context is in `"raw_unset"` or `"unhydrated"` state only. */
179
+ errorData: TSerializedErrorDataMap<ERR_DEF["schema"]>;
180
+ wasntNice: boolean;
181
+ message: string;
182
+ httpStatusCode: number;
183
+ /** The stack trace of the NiceError at the point it was created. */
184
+ stack?: string;
185
+ cause?: unknown;
186
+ originError?: IRegularErrorJsonObject | undefined;
187
+ timeCreated: number;
188
+ }
189
+ type TSchemaNiceErrorId<SCHEMA extends TNiceErrorSchema> = keyof SCHEMA & string;
190
+ type TDomainNiceErrorId<ERR_DEF extends INiceErrorDomainProps> = TSchemaNiceErrorId<ERR_DEF["schema"]>;
191
+ /**
192
+ * The widest ERR_DEF used when creating a NiceError without a definition
193
+ * (bare construction, castNiceError, etc.).
194
+ *
195
+ * Uses the base `INiceErrorDefinedProps` defaults (`string[]` domains,
196
+ * `TNiceErrorSchema` schema) so that type-guard narrowing via `is()` works
197
+ * correctly — `string & "specific_domain"` narrows to `"specific_domain"`
198
+ * instead of collapsing the intersection to `never`.
199
+ */
200
+ type TUnknownNiceErrorDef = INiceErrorDomainProps;
201
+ /**
202
+ * Wide id type for bare / cast NiceErrors that have no schema.
203
+ * Using `string` (rather than a literal `"unknown"`) ensures that
204
+ * `is()` type-guard intersections narrow cleanly: `string & K` = `K`.
205
+ */
206
+ type TUnknownNiceErrorId = string;
207
+ //#endregion
208
+ //#region src/NiceError/NiceErrorHydrated.d.ts
209
+ /**
210
+ * Resolves the args tuple for `addId` — mirrors `FromIdArgs` exactly so that
211
+ * optional vs required context is consistent across both `fromId` and `addId`.
212
+ *
213
+ * - No context on this id → `[id]`
214
+ * - Context defined, `required: true` → `[id, context]`
215
+ * - Context defined, `required` absent/false → `[id] | [id, context]`
216
+ */
217
+ type AddIdArgs<ERR_DEF extends INiceErrorDomainProps, K extends TDomainNiceErrorId<ERR_DEF>> = [ExtractFromIdContextArg<ERR_DEF["schema"][K]>] extends [undefined] ? [id: K] : [undefined] extends [ExtractFromIdContextArg<ERR_DEF["schema"][K]>] ? [id: K] | [id: K, context: NonNullable<ExtractFromIdContextArg<ERR_DEF["schema"][K]>>] : [id: K, context: ExtractFromIdContextArg<ERR_DEF["schema"][K]>];
218
+ /** Full-featured construction from NiceErrorDefined.fromId / fromContext. */
219
+ interface INiceErrorHydratedOptions<ERR_DEF extends INiceErrorDomainProps, ID extends TDomainNiceErrorId<ERR_DEF>> extends INiceErrorOptions<ERR_DEF, ID> {
220
+ def: ERR_DEF;
221
+ niceErrorDefined: NiceErrorDomain<ERR_DEF>;
222
+ }
223
+ declare class NiceErrorHydrated<ERR_DEF extends INiceErrorDomainProps = TUnknownNiceErrorDef,
224
+ /**
225
+ * Union of active error-id keys.
226
+ * - After `fromId(id)`: exactly one key.
227
+ * - After `fromContext({...})`: a union of all supplied keys.
228
+ * - After `hasOneOfIds([a,b])`: narrows to that subset.
229
+ * - Default (bare construction / castNiceError): `TUnknownNiceErrorId`.
230
+ */
231
+ ACTIVE_IDS extends TDomainNiceErrorId<ERR_DEF> = TDomainNiceErrorId<ERR_DEF>> extends NiceError<ERR_DEF, ACTIVE_IDS> {
232
+ readonly def: ERR_DEF;
233
+ private readonly niceErrorDefined;
234
+ constructor(options: INiceErrorHydratedOptions<ERR_DEF, ACTIVE_IDS>);
235
+ /**
236
+ * Returns a **new** `NiceErrorHydrated` with additional id+context entries merged in.
237
+ * The returned error's `ACTIVE_IDS` is the union of the original ids and the
238
+ * newly supplied keys.
239
+ *
240
+ * ```ts
241
+ * const err = errDef.fromId("id_a", { a: 1 })
242
+ * .addContext({ id_b: { b: "x" } });
243
+ * err.getIds(); // ["id_a", "id_b"]
244
+ * ```
245
+ */
246
+ addContext<INPUT extends TFromContextInput<ERR_DEF["schema"]>>(context: INPUT & Record<Exclude<keyof INPUT, keyof ERR_DEF["schema"] & string>, never>): NiceErrorHydrated<ERR_DEF, ACTIVE_IDS | (keyof INPUT & string)>;
247
+ /**
248
+ * Returns a **new** `NiceErrorHydrated` with an additional error id (and its context,
249
+ * if the schema requires one). Equivalent to `addContext({ [id]: context })`
250
+ * but mirrors the `fromId` ergonomics for single-id additions.
251
+ */
252
+ addId<K extends TDomainNiceErrorId<ERR_DEF>>(...args: AddIdArgs<ERR_DEF, K>): NiceErrorHydrated<ERR_DEF, ACTIVE_IDS | K>;
253
+ }
254
+ //#endregion
255
+ //#region src/NiceErrorDefined/NiceErrorDefined.d.ts
256
+ type ChildDef<PARENT_DEF extends INiceErrorDomainProps, SUB extends IDefineNewNiceErrorDomainOptions> = {
257
+ domain: SUB["domain"];
258
+ allDomains: [SUB["domain"], ...PARENT_DEF["allDomains"]];
259
+ schema: SUB["schema"];
260
+ };
261
+ /**
262
+ * Extracts the union of keys present in a `TFromContextInput` object.
263
+ * e.g. `{ invalid_credentials: {...} }` → `"invalid_credentials"`
264
+ */
265
+ type KeysOfContextInput<INPUT> = keyof INPUT & string;
266
+ /**
267
+ * Infers the strongly-typed `NiceError` class type from a `NiceErrorDefined` instance.
268
+ *
269
+ * `ACTIVE_IDS` is set to the full union of all schema keys. Use `hasId` /
270
+ * `hasOneOfIds` to narrow further at the call site.
271
+ *
272
+ * @example
273
+ * ```ts
274
+ * const err_user_auth = defineNiceError({ domain: "err_user_auth", schema: { ... } });
275
+ * type TUserAuthError = InferNiceError<typeof err_user_auth>;
276
+ * // → NiceError<{ domain: "err_user_auth"; ... }, keyof schema>
277
+ * ```
278
+ */
279
+ type InferNiceError<T extends NiceErrorDomain<any>> = T extends NiceErrorDomain<infer ERR_DEF> ? NiceError<ERR_DEF, keyof ERR_DEF["schema"] & string> : never;
280
+ /**
281
+ * Infers the strongly-typed `NiceErrorHydrated` class type from a `NiceErrorDefined` instance.
282
+ *
283
+ * Use this when you need the builder methods (`addId`, `addContext`) as part of
284
+ * the inferred type — e.g. for function return types or variable annotations.
285
+ *
286
+ * @example
287
+ * ```ts
288
+ * const err_user_auth = defineNiceError({ domain: "err_user_auth", schema: { ... } });
289
+ * type TUserAuthErrorHydrated = InferNiceErrorHydrated<typeof err_user_auth>;
290
+ * // → NiceErrorHydrated<{ domain: "err_user_auth"; ... }, keyof schema>
291
+ * ```
292
+ */
293
+ type InferNiceErrorHydrated<T extends NiceErrorDomain<any>> = T extends NiceErrorDomain<infer ERR_DEF> ? NiceErrorHydrated<ERR_DEF, keyof ERR_DEF["schema"] & string> : never;
294
+ declare class NiceErrorDomain<ERR_DEF extends INiceErrorDomainProps = INiceErrorDomainProps> {
295
+ readonly domain: ERR_DEF["domain"];
296
+ readonly allDomains: ERR_DEF["allDomains"];
297
+ readonly defaultHttpStatusCode?: number;
298
+ readonly defaultMessage?: string;
299
+ /** Kept for runtime use (message resolution, httpStatusCode, context serialization, etc.). */
300
+ private readonly _schema;
301
+ private _definedChildNiceErrors;
302
+ private _definedParentNiceError?;
303
+ /** Set by `.packAs()` — explicit per-instance override, takes priority over `_packAsFn`. */
304
+ private _setPack?;
305
+ /** Set at definition time — called dynamically each time an error is created. */
306
+ private _packAsFn?;
307
+ constructor(definition: ERR_DEF);
308
+ /**
309
+ * Creates a child domain that inherits this domain in `allDomains`.
310
+ * The child has its own schema and its own domain string.
311
+ */
312
+ createChildDomain<SUB extends IDefineNewNiceErrorDomainOptions>(subErrorDef: SUB & { [K in Exclude<keyof SUB, keyof IDefineNewNiceErrorDomainOptions>]: never }): NiceErrorDomain<ChildDef<ERR_DEF, SUB>>;
313
+ protected addParentNiceErrorDefined<PARENT_DEF extends INiceErrorDomainProps>(parentError: NiceErrorDomain<PARENT_DEF>): void;
314
+ protected addChildNiceErrorDefined<CHILD_DEF extends INiceErrorDomainProps>(child: NiceErrorDomain<CHILD_DEF>): void;
315
+ packAs(pack: EErrorPackType): this;
316
+ private createError;
317
+ /**
318
+ * Promotes a plain `NiceError<ERR_DEF>` back into a `NiceErrorHydrated` so
319
+ * that builder methods (`addId`, `addContext`, etc.) are available again.
320
+ *
321
+ * For each active id, if the context is in the `"unhydrated"` state (i.e. the
322
+ * error was reconstructed from a JSON payload), `hydrate` calls
323
+ * `fromJsonSerializable` to reconstruct the typed value and advances the state
324
+ * to `"hydrated"`. Ids already in `"hydrated"` or `"raw_unset"` state
325
+ * are passed through unchanged.
326
+ *
327
+ * @throws If `error.def.domain` does not match this definition's domain. Use
328
+ * `niceErrorDefined.is(error)` before calling `hydrate` to ensure compatibility.
329
+ *
330
+ * ```ts
331
+ * const raw = castNiceError(apiResponseBody);
332
+ *
333
+ * if (err_user_auth.is(raw)) {
334
+ * const hydrated = err_user_auth.hydrate(raw);
335
+ * // hydrated.getContext("invalid_credentials") — fully typed, no throw
336
+ * // hydrated.addId / addContext — available again
337
+ * }
338
+ * ```
339
+ */
340
+ hydrate<ACTIVE_IDS extends TDomainNiceErrorId<ERR_DEF> = TDomainNiceErrorId<ERR_DEF>>(error: NiceError<ERR_DEF, ACTIVE_IDS> | INiceErrorJsonObject<ERR_DEF, ACTIVE_IDS>): NiceErrorHydrated<ERR_DEF, ACTIVE_IDS>;
341
+ /**
342
+ * Creates a `NiceErrorHydrated` for a single error id.
343
+ *
344
+ * - `id` autocompletes to the schema keys.
345
+ * - The second argument `context` is required / optional / absent based on
346
+ * whether the schema entry declares `context.required: true`.
347
+ * - The returned error has `ACTIVE_IDS` narrowed to exactly `K`, so
348
+ * `getContext(id)` is immediately strongly typed.
349
+ */
350
+ fromId<K extends keyof ERR_DEF["schema"] & string>(...args: FromIdArgs<ERR_DEF, K>): NiceErrorHydrated<ERR_DEF, K>;
351
+ fromContext<INPUT extends TFromContextInput<ERR_DEF["schema"]>>(context: INPUT & Record<Exclude<keyof INPUT, keyof ERR_DEF["schema"]>, never>): NiceErrorHydrated<ERR_DEF, KeysOfContextInput<INPUT>>;
352
+ /**
353
+ * Returns `true` if `error` is a `NiceError` whose `def.domain` exactly matches
354
+ * this definition's domain.
355
+ *
356
+ * Use this after `castNiceError` to narrow an unknown error to this specific
357
+ * domain before accessing its typed ids/context:
358
+ *
359
+ * ```ts
360
+ * const caught = castNiceError(e);
361
+ *
362
+ * if (err_user_auth.is(caught)) {
363
+ * // caught is now NiceError<typeof err_user_auth's ERR_DEF>
364
+ * const hydrated = err_user_auth.hydrate(caught);
365
+ * const { username } = hydrated.getContext("invalid_credentials");
366
+ * }
367
+ * ```
368
+ */
369
+ isExact(error: unknown): error is NiceError<ERR_DEF, keyof ERR_DEF["schema"] & string>;
370
+ isThisOrChild(error: unknown): boolean;
371
+ /**
372
+ * Returns `true` if this domain appears anywhere in the target's ancestry
373
+ * chain (including an exact domain match).
374
+ *
375
+ * Accepts either a `NiceErrorDefined` (domain definition) or a `NiceError`
376
+ * instance (extracts the domain from its `def`).
377
+ */
378
+ isParentOf(target: NiceErrorDomain<any> | NiceError<any, any>): boolean;
379
+ private _buildDef;
380
+ private _resolveMessage;
381
+ private _resolveHttpStatusCode;
382
+ reconcileErrorDataForId(id: keyof ERR_DEF["schema"] & string, context: TFromContextInput<ERR_DEF["schema"]>[typeof id]): TErrorReconciledData<ERR_DEF["schema"], typeof id>;
383
+ }
384
+ //#endregion
385
+ //#region src/NiceErrorHandler/NiceErrorHandler.types.d.ts
386
+ type MaybePromise<T> = T | Promise<T>;
387
+ /**
388
+ * Broad handler signature used internally for storage and dispatch.
389
+ */
390
+ type TBroadErrorHandler<E extends NiceError = NiceError, RES = unknown> = (action: E) => MaybePromise<RES>;
391
+ /**
392
+ * Handler registered via forDomain.
393
+ *
394
+ * `act.input` is typed as the union of input types for every action in `ACT_DOM`,
395
+ * and `act.coreAction` carries the matching schema — the same narrowing you get
396
+ * from `forActionIds` over all action IDs in the domain.
397
+ */
398
+ type TErrorHandlerForDomain<ERR_DOM extends INiceErrorDomainProps> = (error: NiceErrorHydrated<ERR_DOM>) => MaybePromise<unknown>;
399
+ /**
400
+ * Handler registered via forActionId — receives a specific action ID, with
401
+ * the primed action's input narrowed to that ID's schema.
402
+ */
403
+ type TErrorIdHandlerForDomain<ERR_DOM extends INiceErrorDomainProps, ID extends TDomainNiceErrorId<ERR_DOM>> = (error: NiceErrorHydrated<ERR_DOM, ID>) => MaybePromise<unknown>;
404
+ declare enum EErrorHandlerTargetType {
405
+ ids = "ids",
406
+ domain = "domain",
407
+ default = "default"
408
+ }
409
+ type TErrorHandlerTarget = ({
410
+ type: EErrorHandlerTargetType.ids;
411
+ domain: string;
412
+ ids: string[];
413
+ } | {
414
+ type: EErrorHandlerTargetType.domain;
415
+ domain: string;
416
+ } | {
417
+ type: EErrorHandlerTargetType.default;
418
+ }) & {
419
+ identifier: string;
420
+ };
421
+ /**
422
+ * A single case in a `handleWith` / `handleWithAsync` call.
423
+ *
424
+ * Construct via `forDomain` or `forIds` — do not build this object directly.
425
+ */
426
+ interface IErrorHandlerConfig<ERR extends NiceError<any, any> = NiceError<any, any>, RES = unknown> {
427
+ /**
428
+ * Duck-typed reference to the domain definition.
429
+ * Needs only `isExact()` and `hydrate()` at runtime — avoids any circular value import.
430
+ * @internal
431
+ */
432
+ readonly target: TErrorHandlerTarget;
433
+ readonly _matcher: (action: ERR) => boolean;
434
+ readonly _requester: TBroadErrorHandler<ERR, RES>;
435
+ }
436
+ interface IErrorHandleAttempt_Success<RES = void> {
437
+ handled: true;
438
+ result: RES;
439
+ target: TErrorHandlerTarget;
440
+ }
441
+ interface IErrorHandleAttempt_Failure {
442
+ handled: false;
443
+ result?: undefined;
444
+ targets: TErrorHandlerTarget[];
445
+ }
446
+ type TErrorHandleAttempt<RES = void> = IErrorHandleAttempt_Success<RES> | IErrorHandleAttempt_Failure;
447
+ interface IHandleErrorOptions {
448
+ throwOnUnhandled?: boolean;
449
+ }
450
+ type THandleErrorWithPromiseInspection<RES = void> = {
451
+ isPromise: false;
452
+ matched: true;
453
+ target: TErrorHandlerTarget;
454
+ handlerResponse: RES;
455
+ } | {
456
+ isPromise: true;
457
+ matched: true;
458
+ target: TErrorHandlerTarget;
459
+ handlerPromise: Promise<RES>;
460
+ } | {
461
+ matched: false;
462
+ attemptedTargets: TErrorHandlerTarget[];
463
+ };
464
+ type THandleResponse<RES = unknown> = {
465
+ handled: false;
466
+ } | {
467
+ handled: true;
468
+ isPromise: boolean;
469
+ response: RES;
470
+ };
471
+ //#endregion
472
+ //#region src/NiceErrorHandler/NiceErrorHandler.d.ts
473
+ declare class NiceErrorHandler<RES_DEF = never, RES = never> {
474
+ private handlerConfigs;
475
+ private _defaultRequester?;
476
+ handleErrorWithPromiseInspection(error: NiceError<any, any>, options?: IHandleErrorOptions): THandleErrorWithPromiseInspection<RES | RES_DEF>;
477
+ /**
478
+ * Register a handler that fires for **any** error whose domain matches `domain`.
479
+ * The handler receives a fully hydrated error — `getContext`, `addId`, and `addContext`
480
+ * are all available. First matching case wins.
481
+ */
482
+ forDomain<DEF extends INiceErrorDomainProps, H_RES = void>(domain: NiceErrorDomain<DEF>, handler: (error: NiceErrorHydrated<DEF, TDomainNiceErrorId<DEF>>) => MaybePromise<H_RES>): NiceErrorHandler<RES_DEF, RES | H_RES>;
483
+ forId<DEF extends INiceErrorDomainProps, ID extends TDomainNiceErrorId<DEF>, H_RES = void>(domain: NiceErrorDomain<DEF>, id: ID, handler: (error: NiceErrorHydrated<DEF, ID>) => MaybePromise<H_RES>): NiceErrorHandler<RES_DEF, RES | H_RES>;
484
+ forIds<DEF extends INiceErrorDomainProps, IDS extends TDomainNiceErrorId<DEF>[], H_RES = void>(domain: NiceErrorDomain<DEF>, ids: IDS, handler: (error: NiceErrorHydrated<DEF, IDS[number]>) => MaybePromise<H_RES>): NiceErrorHandler<RES_DEF, RES | H_RES>;
485
+ /**
486
+ * Register a fallback handler that fires when no other case matches.
487
+ * Only one default handler can be registered — calling this twice replaces the previous one.
488
+ */
489
+ setDefaultHandler<H_RES>(handler: (error: NiceError<any, any>) => MaybePromise<H_RES>): NiceErrorHandler<H_RES, RES>;
490
+ }
491
+ //#endregion
492
+ //#region src/NiceError/NiceError.d.ts
493
+ type ContextOf<S extends TNiceErrorSchema, K extends keyof S> = TExtractContextType<S[K]>;
494
+ /** Full-featured construction from NiceErrorDefined.fromId / fromContext. */
495
+ interface INiceErrorOptions<ERR_DEF extends INiceErrorDomainProps, ID extends TDomainNiceErrorId<ERR_DEF> = TDomainNiceErrorId<ERR_DEF>> {
496
+ def: Omit<ERR_DEF, "schema">;
497
+ /** Primary id is first entry in ids. */
498
+ ids: ID[];
499
+ /** All active ids with their messages, http status codes, and context state. */
500
+ errorData: TErrorDataForIdMap<ERR_DEF["schema"]>;
501
+ message: string;
502
+ wasntNice?: boolean;
503
+ httpStatusCode?: number;
504
+ originError?: IRegularErrorJsonObject | undefined;
505
+ timeCreated?: number;
506
+ }
507
+ declare class NiceError<ERR_DEF extends INiceErrorDomainProps = TUnknownNiceErrorDef,
508
+ /**
509
+ * Union of active error-id keys.
510
+ * - After `fromId(id)`: exactly one key.
511
+ * - After `fromContext({...})`: a union of all supplied keys.
512
+ * - After `hasOneOfIds([a,b])`: narrows to that subset.
513
+ * - Default (bare construction / castNiceError): `TUnknownNiceErrorId`.
514
+ */
515
+ ACTIVE_IDS extends TDomainNiceErrorId<ERR_DEF> = TDomainNiceErrorId<ERR_DEF>> extends Error {
516
+ readonly name: "NiceError";
517
+ readonly def: Omit<ERR_DEF, "schema">;
518
+ /** Primary id is first entry in ids. */
519
+ readonly ids: ACTIVE_IDS[];
520
+ readonly wasntNice: boolean;
521
+ readonly httpStatusCode: number;
522
+ readonly timeCreated: number;
523
+ readonly cleanMessage: string;
524
+ originError?: IRegularErrorJsonObject;
525
+ _packedState?: {
526
+ packedAs: EErrorPackType.cause_pack;
527
+ cause: unknown;
528
+ } | {
529
+ packedAs: EErrorPackType.msg_pack;
530
+ message: string;
531
+ } | undefined;
532
+ /** Internal: all active id → reconciled data pairs. */
533
+ protected readonly _errorDataMap: TErrorDataForIdMap<ERR_DEF["schema"]>;
534
+ constructor(options: INiceErrorOptions<ERR_DEF, ACTIVE_IDS>);
535
+ /**
536
+ * Type guard: returns `true` if this error was created with (or contains) the
537
+ * given `id`. After the guard, `getContext(id)` will be strongly typed.
538
+ */
539
+ hasId<ID extends keyof ERR_DEF["schema"] & string>(id: ID): this is NiceError<ERR_DEF, ID>;
540
+ /**
541
+ * Returns `true` if this error contains **at least one** of the supplied ids.
542
+ * Narrows `ACTIVE_IDS` to the matching subset of `IDS`.
543
+ */
544
+ hasOneOfIds<IDS extends ReadonlyArray<keyof ERR_DEF["schema"] & string>>(ids: IDS): this is NiceError<ERR_DEF, IDS[number]>;
545
+ /** `true` when this error was created with more than one id (via `fromContext`). */
546
+ get hasMultiple(): boolean;
547
+ /** Returns all active error ids on this instance. */
548
+ getIds(): Array<ACTIVE_IDS>;
549
+ /**
550
+ * Returns the typed context value for the given error id.
551
+ *
552
+ * TypeScript will only allow you to call this with an id that is part of
553
+ * `ACTIVE_IDS` (i.e. an id confirmed via `hasId` / `hasOneOfIds`, or passed
554
+ * to `fromId` / `fromContext`).
555
+ *
556
+ * @throws If the context is in the `"unhydrated"` state — the error was
557
+ * reconstructed from a JSON payload and its context has a custom serializer
558
+ * that hasn't been run yet. Call `niceErrorDefined.hydrate(error)` first.
559
+ */
560
+ getContext<ID extends ACTIVE_IDS>(id: ID): ContextOf<ERR_DEF["schema"], ID>;
561
+ getErrorDataForId<ID extends ACTIVE_IDS>(id: ID): TErrorReconciledData<ERR_DEF["schema"], ID> | undefined;
562
+ withOriginError(error: unknown): this;
563
+ /**
564
+ * Returns `true` if `other` has the same domain and the exact same set of
565
+ * active error ids as this error (order-independent).
566
+ *
567
+ * Useful for deduplication, retry logic, and asserting that two errors
568
+ * represent the same "kind" of problem without comparing context values.
569
+ *
570
+ * ```ts
571
+ * const a = err_auth.fromId("invalid_credentials", { username: "alice" });
572
+ * const b = err_auth.fromId("invalid_credentials", { username: "bob" });
573
+ * a.matches(b); // true — same domain + same id set
574
+ *
575
+ * const c = err_auth.fromId("account_locked");
576
+ * a.matches(c); // false — same domain, different id
577
+ * ```
578
+ */
579
+ matches(other: NiceError<any, any>): boolean;
580
+ toJsonObject(): INiceErrorJsonObject<ERR_DEF>;
581
+ toJSON(): INiceErrorJsonObject<ERR_DEF>;
582
+ toJsonString(): string;
583
+ toHttpResponse(): Response;
584
+ hydrate(definedNiceError: NiceErrorDomain<ERR_DEF>): NiceErrorHydrated<ERR_DEF, ACTIVE_IDS>;
585
+ /**
586
+ * Iterates `cases` in order, finds the first whose domain matches this error
587
+ * (via `is()`), optionally further filters by active ids, hydrates the error,
588
+ * calls the handler, and returns `true`. Returns `false` if no case matched.
589
+ *
590
+ * Build cases with `forDomain` (any id in the domain) or `forIds` (specific
591
+ * id subset). Handlers are invoked synchronously — any returned Promise is
592
+ * not awaited. Use `handleWithAsync` when handlers are async.
593
+ *
594
+ * @example
595
+ * ```ts
596
+ * const handled = error.handleWith([
597
+ * forIds(err_feature, ["not_found"], (h) => {
598
+ * res.status(404).json({ missing: h.getContext("not_found").resource });
599
+ * }),
600
+ * forDomain(err_feature, (h) => {
601
+ * matchFirst(h, {
602
+ * forbidden: ({ userId }) => res.status(403).json({ userId }),
603
+ * _: () => res.status(500).end(),
604
+ * });
605
+ * }),
606
+ * forDomain(err_service, (h) => {
607
+ * res.status(h.httpStatusCode).json({ error: h.message });
608
+ * }),
609
+ * ]);
610
+ * if (!handled) next(error);
611
+ * ```
612
+ */
613
+ handleWithSync<RD, R>(handlerInput: NiceErrorHandler<RD, R> | ReadonlyArray<NiceErrorHandler<RD, R>>, handlerOptions?: IHandleErrorOptions): R | RD | undefined;
614
+ /**
615
+ * Same matching logic as `handleWith`, but `await`s the handler's returned
616
+ * Promise before resolving. Use this when your handlers perform async work
617
+ * (database writes, HTTP calls, etc.).
618
+ *
619
+ * @example
620
+ * ```ts
621
+ * const handled = await error.handleWithAsync([
622
+ * forDomain(err_payments, async (h) => {
623
+ * await db.logFailedPayment(h);
624
+ * await notifyOps(h.message);
625
+ * }),
626
+ * ]);
627
+ * ```
628
+ */
629
+ handleWithAsync<RD, R>(handlerInput: NiceErrorHandler<RD, R> | ReadonlyArray<NiceErrorHandler<RD, R>>, handlerOptions?: IHandleErrorOptions): Promise<R | RD | undefined>;
630
+ get isPacked(): boolean;
631
+ pack(packType?: EErrorPackType): this;
632
+ unpack(): this;
633
+ }
634
+ //#endregion
635
+ //#region src/utils/inspectPotentialError/inspectPotentialError.enums.d.ts
636
+ declare enum EInspectErrorResultType {
637
+ nullish = "nullish",
638
+ niceErrorObject = "niceErrorObject",
639
+ niceError = "niceError",
640
+ jsError = "jsError",
641
+ jsErrorObject = "jsErrorObject",
642
+ jsDataType = "jsDataType",
643
+ jsOther = "jsOther"
644
+ }
645
+ //#endregion
646
+ //#region src/utils/inspectPotentialError/inspectPotentialError.types.d.ts
647
+ interface IInspectErrorResult_Base<T extends EInspectErrorResultType> {
648
+ type: T;
649
+ }
650
+ interface IInspectErrorResult_Nullish extends IInspectErrorResult_Base<EInspectErrorResultType.nullish> {
651
+ value: null | undefined;
652
+ }
653
+ interface IInspectErrorResult_JsError extends IInspectErrorResult_Base<EInspectErrorResultType.jsError> {
654
+ jsError: Error;
655
+ }
656
+ interface IInspectErrorResult_JsErrorObject extends IInspectErrorResult_Base<EInspectErrorResultType.jsErrorObject> {
657
+ jsErrorObject: IRegularErrorJsonObject;
658
+ }
659
+ /**
660
+ * JS DATA TYPES
661
+ */
662
+ interface IInspectErrorResult_JsDataType_String extends IInspectErrorResult_Base<EInspectErrorResultType.jsDataType> {
663
+ jsDataType: "string";
664
+ jsDataValue: string;
665
+ }
666
+ interface IInspectErrorResult_JsDataType_Number extends IInspectErrorResult_Base<EInspectErrorResultType.jsDataType> {
667
+ jsDataType: "number";
668
+ jsDataValue: number;
669
+ }
670
+ interface IInspectErrorResult_JsDataType_Boolean extends IInspectErrorResult_Base<EInspectErrorResultType.jsDataType> {
671
+ jsDataType: "boolean";
672
+ jsDataValue: boolean;
673
+ }
674
+ interface IInspectErrorResult_JsDataType_Object extends IInspectErrorResult_Base<EInspectErrorResultType.jsDataType> {
675
+ jsDataType: "object";
676
+ jsDataValue: object;
677
+ }
678
+ type TInspectErrorResult_JsDataType = IInspectErrorResult_JsDataType_String | IInspectErrorResult_JsDataType_Number | IInspectErrorResult_JsDataType_Boolean | IInspectErrorResult_JsDataType_Object;
679
+ /**
680
+ * Catch-all for any other JS data type that doesn't fit the above categories (e.g. symbol, bigint, function, etc.)
681
+ */
682
+ interface IInspectErrorResult_JsOther extends IInspectErrorResult_Base<EInspectErrorResultType.jsOther> {
683
+ jsDataValue: unknown;
684
+ }
685
+ //#endregion
686
+ //#region src/internal/nice_core_errors.d.ts
687
+ declare const err_nice: NiceErrorDomain<{
688
+ domain: "err_nice";
689
+ allDomains: ["err_nice"];
690
+ schema: {};
691
+ }>;
692
+ declare enum EErrId_CastNotNice {
693
+ js_error = "native_error",
694
+ js_error_like_object = "js_error_like_object",
695
+ nullish_value = "nullish_value",
696
+ js_data_type = "js_data_type",
697
+ js_other = "js_other"
698
+ }
699
+ declare const err_cast_not_nice: NiceErrorDomain<{
700
+ domain: string;
701
+ allDomains: [string, "err_nice"];
702
+ schema: {
703
+ native_error: INiceErrorIdMetadata<IInspectErrorResult_JsError, JSONSerializableValue> & {
704
+ context: {
705
+ required: true;
706
+ };
707
+ };
708
+ js_error_like_object: INiceErrorIdMetadata<IInspectErrorResult_JsErrorObject, JSONSerializableValue> & {
709
+ context: {
710
+ required: true;
711
+ };
712
+ };
713
+ nullish_value: INiceErrorIdMetadata<IInspectErrorResult_Nullish, JSONSerializableValue> & {
714
+ context: {
715
+ required: true;
716
+ };
717
+ };
718
+ js_data_type: INiceErrorIdMetadata<TInspectErrorResult_JsDataType, JSONSerializableValue> & {
719
+ context: {
720
+ required: true;
721
+ };
722
+ };
723
+ js_other: INiceErrorIdMetadata<IInspectErrorResult_JsOther, JSONSerializableValue> & {
724
+ context: {
725
+ required: true;
726
+ };
727
+ };
728
+ };
729
+ }>;
730
+ declare const err_nice_handler: NiceErrorDomain<{
731
+ domain: string;
732
+ allDomains: [string, "err_nice"];
733
+ schema: {};
734
+ }>;
735
+ //#endregion
736
+ //#region src/NiceErrorDefined/defineNiceError.d.ts
737
+ declare const defineNiceError: <ERR_DOMAIN extends string, SCHEMA extends TNiceErrorSchema>(definition: IDefineNewNiceErrorDomainOptions<ERR_DOMAIN, SCHEMA>) => NiceErrorDomain<{
738
+ domain: ERR_DOMAIN;
739
+ allDomains: [ERR_DOMAIN];
740
+ schema: SCHEMA;
741
+ }>;
742
+ //#endregion
743
+ //#region src/NiceErrorDefined/err.d.ts
744
+ /**
745
+ * Schema entry factory — the idiomatic way to define a single error id in a
746
+ * `NiceErrorDefined` schema.
747
+ *
748
+ * Using `err()` instead of writing schema entries as plain object literals
749
+ * ensures TypeScript resolves the context argument as **required** vs **optional**
750
+ * correctly in `fromId` / `addId` call sites.
751
+ *
752
+ * How `required` affects the call site:
753
+ *
754
+ * | Schema entry | `fromId("id")` | `fromId("id", ctx)` |
755
+ * |------------------------------------|----------------|---------------------|
756
+ * | `err()` / `err({ ... })` | ✓ | ✗ (no context) |
757
+ * | `err<C>({ context: {} })` | ✓ | ✓ (optional ctx) |
758
+ * | `err<C>({ context: { required: true } })` | ✗ | ✓ (required ctx) |
759
+ *
760
+ * @example
761
+ * ```ts
762
+ * // No context — `fromId("not_found")` takes no second argument.
763
+ * not_found: err({ message: "Resource not found", httpStatusCode: 404 }),
764
+ *
765
+ * // Optional context — second arg accepted but not required.
766
+ * rate_limited: err<{ retryAfter: number }>({
767
+ * message: (ctx) => ctx ? `Retry after ${ctx.retryAfter}s` : "Rate limited",
768
+ * httpStatusCode: 429,
769
+ * context: {},
770
+ * }),
771
+ *
772
+ * // Required context — `fromId("invalid_input", { field: "email" })` (second arg is required).
773
+ * invalid_input: err<{ field: string }>({
774
+ * message: ({ field }) => `Invalid value for field: ${field}`,
775
+ * httpStatusCode: 422,
776
+ * context: { required: true },
777
+ * }),
778
+ *
779
+ * // Required context with custom serialization (for non-JSON-safe context values).
780
+ * fs_error: err<{ cause: NodeJS.ErrnoException }>({
781
+ * message: ({ cause }) => `File system error: ${cause.message}`,
782
+ * context: {
783
+ * required: true,
784
+ * serialization: {
785
+ * toJsonSerializable: ({ cause }) => ({ code: cause.code, message: cause.message }),
786
+ * fromJsonSerializable: (obj) => ({ cause: Object.assign(new Error(obj.message), obj) }),
787
+ * },
788
+ * },
789
+ * }),
790
+ * ```
791
+ */
792
+ declare function err<C, D extends JSONSerializableValue = Record<string, any>>(meta: INiceErrorIdMetadata<C, D> & {
793
+ context: INiceErrorContextDefinition<C, D> & {
794
+ required: true;
795
+ };
796
+ }): INiceErrorIdMetadata<C> & {
797
+ context: {
798
+ required: true;
799
+ };
800
+ };
801
+ declare function err<C = never>(meta?: INiceErrorIdMetadata<C>): INiceErrorIdMetadata<C>;
802
+ //#endregion
803
+ //#region src/NiceErrorHandler/handleWith.d.ts
804
+ declare function forDomain<DEF extends INiceErrorDomainProps, H_RES = void>(domain: NiceErrorDomain<DEF>, handler: (error: NiceErrorHydrated<DEF, TDomainNiceErrorId<DEF>>) => MaybePromise<H_RES>): NiceErrorHandler<never, H_RES>;
805
+ declare function forId<DEF extends INiceErrorDomainProps, ID extends TDomainNiceErrorId<DEF>, H_RES = void>(domain: NiceErrorDomain<DEF>, id: ID, handler: (error: NiceErrorHydrated<DEF, ID>) => MaybePromise<H_RES>): NiceErrorHandler<never, H_RES>;
806
+ declare function forIds<DEF extends INiceErrorDomainProps, IDS extends TDomainNiceErrorId<DEF>[], H_RES = void>(domain: NiceErrorDomain<DEF>, ids: IDS, handler: (error: NiceErrorHydrated<DEF, IDS[number]>) => MaybePromise<H_RES>): NiceErrorHandler<never, H_RES>;
807
+ //#endregion
808
+ //#region src/utils/castAndHydrate.d.ts
809
+ /**
810
+ * Combines `castNiceError`, `is()`, and `hydrate()` in a single call — the
811
+ * idiomatic way to handle an unknown value arriving from a remote boundary
812
+ * (API response, message queue, IPC, etc.) when you have a specific domain in mind.
813
+ *
814
+ * - Casts `value` to a `NiceError` using `castNiceError`.
815
+ * - If the result belongs to `niceErrorDefined`'s domain (`is()` returns `true`),
816
+ * hydrates it and returns a fully-typed `NiceErrorHydrated`.
817
+ * - Otherwise returns the raw cast `NiceError` (which may be a `wasntNice` error
818
+ * if `value` was not a NiceError at all).
819
+ *
820
+ * @example
821
+ * ```ts
822
+ * // In an Express error handler:
823
+ * app.use((err, req, res, next) => {
824
+ * const error = castAndHydrate(err, err_user_auth);
825
+ *
826
+ * if (err_user_auth.is(error)) {
827
+ * // error is NiceErrorHydrated — getContext / addId available
828
+ * const result = matchFirst(error, {
829
+ * invalid_credentials: ({ username }) => res.status(401).json({ username }),
830
+ * account_locked: () => res.status(403).json({ locked: true }),
831
+ * });
832
+ * if (result) return;
833
+ * }
834
+ *
835
+ * next(err);
836
+ * });
837
+ * ```
838
+ */
839
+ declare function castAndHydrate<ERR_DEF extends INiceErrorDomainProps>(value: unknown, niceErrorDefined: NiceErrorDomain<ERR_DEF>): NiceErrorHydrated<ERR_DEF, keyof ERR_DEF["schema"] & string> | NiceError;
840
+ //#endregion
841
+ //#region src/utils/castNiceError.d.ts
842
+ /**
843
+ * Casts any unknown value into a `NiceError`.
844
+ *
845
+ * - If the value is already a `NiceError` instance, it is returned as-is.
846
+ * - If the value is a plain `Error`, it is wrapped with the original as `originError`.
847
+ * - If the value is a JSON-serialised `NiceError` object (e.g. from an API
848
+ * response), a best-effort `NiceError` is re-created from it.
849
+ * - For all other values, a generic `NiceError` is created with a descriptive
850
+ * message.
851
+ *
852
+ * After casting, use `NiceErrorDefined.is(error)` to narrow the error to a
853
+ * specific domain and access its strongly-typed ids and context.
854
+ */
855
+ declare const castNiceError: (error: unknown) => NiceError;
856
+ //#endregion
857
+ //#region src/utils/isNiceErrorObject.d.ts
858
+ /**
859
+ * Returns `true` if `obj` is a JSON-serialised `NiceError` object matching the
860
+ * current wire format (contextState-based errorData entries).
861
+ *
862
+ * Validates:
863
+ * - Top-level shape (`name`, `message`, `wasntNice`, `httpStatusCode`, `def`)
864
+ * - Each `errorData` entry has a `contextState` with a valid `kind` discriminant
865
+ * (`"no_serialization"` or `"unhydrated"`) — rejecting payloads in the old
866
+ * format (`context` / `serialized` fields) to prevent silent data corruption.
867
+ */
868
+ declare function isNiceErrorObject(obj: unknown): obj is INiceErrorJsonObject;
869
+ //#endregion
870
+ //#region src/utils/isRegularErrorObject.d.ts
871
+ declare function isRegularErrorJsonObject(obj: unknown): obj is IRegularErrorJsonObject;
872
+ //#endregion
873
+ //#region src/utils/matchFirst.d.ts
874
+ /**
875
+ * Handler map for `matchFirst`. Each key is an error id (from `ACTIVE_IDS`) and
876
+ * the value is a function that receives the typed context for that id.
877
+ *
878
+ * The `_` key is an optional fallback that runs when no id-specific handler matched.
879
+ */
880
+ type TMatchFirstHandlers<ERR_DEF extends INiceErrorDomainProps, ACTIVE_IDS extends keyof ERR_DEF["schema"] & string, RESULT> = { [K in ACTIVE_IDS]?: (context: TExtractContextType<ERR_DEF["schema"][K]>) => RESULT } & {
881
+ _?: () => RESULT;
882
+ };
883
+ /**
884
+ * Pattern-matches an error against a map of id → handler functions, returning the
885
+ * result of the first handler whose id is active on the error.
886
+ *
887
+ * - Ids are tested in the order returned by `error.getIds()`.
888
+ * - If no id-specific handler matched and `_` is provided, the fallback is called.
889
+ * - Returns `undefined` when neither any id handler nor the fallback fires.
890
+ *
891
+ * **Requires hydrated context.** If any matched id is in the `"unhydrated"` state,
892
+ * `getContext` will throw. Call `niceErrorDefined.hydrate(error)` beforehand when
893
+ * working with errors deserialized from a JSON payload.
894
+ *
895
+ * @example
896
+ * ```ts
897
+ * const result = matchFirst(error, {
898
+ * invalid_credentials: ({ username }) => `Wrong password for ${username}`,
899
+ * account_locked: () => "Account is locked",
900
+ * _: () => "Unknown auth error",
901
+ * });
902
+ * ```
903
+ */
904
+ declare function matchFirst<ERR_DEF extends INiceErrorDomainProps, ACTIVE_IDS extends keyof ERR_DEF["schema"] & string, RESULT>(error: NiceError<ERR_DEF, ACTIVE_IDS>, handlers: TMatchFirstHandlers<ERR_DEF, ACTIVE_IDS, RESULT>): RESULT | undefined;
905
+ //#endregion
906
+ //#region src/utils/packError/causePack.d.ts
907
+ declare const causePack: <E extends NiceError<any, any>>(error: E) => E;
908
+ //#endregion
909
+ //#region src/utils/packError/msgPack.d.ts
910
+ declare const msgPack: <E extends NiceError<any, any>>(error: E) => E;
911
+ //#endregion
912
+ export { EErrId_CastNotNice, EErrorHandlerTargetType, EErrorPackType, ExtractFromIdContextArg, FromIdArgs, IDefineNewNiceErrorDomainOptions, IErrorHandleAttempt_Failure, IErrorHandleAttempt_Success, IErrorHandlerConfig, IHandleErrorOptions, INiceErrorContextDefinition, INiceErrorDomainProps, INiceErrorHydratedOptions, INiceErrorIdMetadata, INiceErrorJsonObject, INiceErrorOptions, IPackErrorAs_Base, IPackErrorAs_MatchEnvVar, IRegularErrorJsonObject, InferNiceError, InferNiceErrorHydrated, JSONSerializableValue, MaybePromise, NiceError, NiceErrorDomain, NiceErrorHandler, NiceErrorHydrated, TBroadErrorHandler, TContextState, TContextStateHydrated, TContextStateNoSerialization, TContextStateUnhydrated, TDomainNiceErrorId, TErrorDataForIdMap, TErrorHandleAttempt, TErrorHandlerForDomain, TErrorHandlerTarget, TErrorIdHandlerForDomain, TErrorReconciledData, TExtractContextType, TFromContextInput, THandleErrorWithPromiseInspection, THandleResponse, TMatchFirstHandlers, TNiceErrorSchema, TSchemaNiceErrorId, TSerializedContextState, TSerializedErrorDataMap, TSerializedErrorReconciledData, TUnknownNiceErrorDef, TUnknownNiceErrorId, castAndHydrate, castNiceError, causePack, defineNiceError, err, err_cast_not_nice, err_nice, err_nice_handler, forDomain, forId, forIds, isNiceErrorObject, isRegularErrorJsonObject, matchFirst, msgPack };
913
+ //# sourceMappingURL=index.d.ts.map