@nice-code/error 0.0.15

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 (32) hide show
  1. package/README.md +1 -0
  2. package/build/index.js +2747 -0
  3. package/build/types/NiceError/NiceError.d.ts +141 -0
  4. package/build/types/NiceError/NiceError.enums.d.ts +5 -0
  5. package/build/types/NiceError/NiceError.types.d.ts +199 -0
  6. package/build/types/NiceError/NiceErrorHydrated.d.ts +49 -0
  7. package/build/types/NiceError/nice_error.static.d.ts +2 -0
  8. package/build/types/NiceErrorDefined/NiceErrorDefined.d.ts +135 -0
  9. package/build/types/NiceErrorDefined/defineNiceError.d.ts +7 -0
  10. package/build/types/NiceErrorDefined/err.d.ts +59 -0
  11. package/build/types/example/error_usage_example.d.ts +41 -0
  12. package/build/types/index.d.ts +16 -0
  13. package/build/types/internal/index.d.ts +1 -0
  14. package/build/types/internal/nice_core_errors.d.ts +44 -0
  15. package/build/types/test/helpers/nice_error_testing.static.d.ts +3 -0
  16. package/build/types/test/helpers/test_utils.d.ts +1 -0
  17. package/build/types/utils/castAndHydrate.d.ts +35 -0
  18. package/build/types/utils/castNiceError.d.ts +15 -0
  19. package/build/types/utils/handleWith.d.ts +49 -0
  20. package/build/types/utils/inspectPotentialError/inspectPotentialError.d.ts +2 -0
  21. package/build/types/utils/inspectPotentialError/inspectPotentialError.enums.d.ts +9 -0
  22. package/build/types/utils/inspectPotentialError/inspectPotentialError.types.d.ts +51 -0
  23. package/build/types/utils/isNiceErrorObject.d.ts +12 -0
  24. package/build/types/utils/isRegularErrorObject.d.ts +2 -0
  25. package/build/types/utils/jsErrorOrCastJsError.d.ts +1 -0
  26. package/build/types/utils/logger.d.ts +3 -0
  27. package/build/types/utils/matchFirst.d.ts +35 -0
  28. package/build/types/utils/packError/causePack.d.ts +2 -0
  29. package/build/types/utils/packError/msgPack.d.ts +2 -0
  30. package/build/types/utils/packError/packError.d.ts +3 -0
  31. package/build/types/utils/packError/packError.enums.d.ts +5 -0
  32. package/package.json +37 -0
@@ -0,0 +1,44 @@
1
+ import type { IInspectErrorResult_JsError, IInspectErrorResult_JsErrorObject, IInspectErrorResult_JsOther, IInspectErrorResult_Nullish, TInspectErrorResult_JsDataType } from "../utils/inspectPotentialError/inspectPotentialError.types";
2
+ export declare const err_nice: import("..").NiceErrorDefined<{
3
+ domain: "err_nice";
4
+ allDomains: ["err_nice"];
5
+ schema: {};
6
+ }>;
7
+ export declare enum EErrId_CastNotNice {
8
+ js_error = "native_error",
9
+ js_error_like_object = "js_error_like_object",
10
+ nullish_value = "nullish_value",
11
+ js_data_type = "js_data_type",
12
+ js_other = "js_other"
13
+ }
14
+ export declare const err_cast_not_nice: import("..").NiceErrorDefined<{
15
+ domain: string;
16
+ allDomains: [string, "err_nice"];
17
+ schema: {
18
+ native_error: import("..").INiceErrorIdMetadata<IInspectErrorResult_JsError, import("..").JSONSerializableValue> & {
19
+ context: {
20
+ required: true;
21
+ };
22
+ };
23
+ js_error_like_object: import("..").INiceErrorIdMetadata<IInspectErrorResult_JsErrorObject, import("..").JSONSerializableValue> & {
24
+ context: {
25
+ required: true;
26
+ };
27
+ };
28
+ nullish_value: import("..").INiceErrorIdMetadata<IInspectErrorResult_Nullish, import("..").JSONSerializableValue> & {
29
+ context: {
30
+ required: true;
31
+ };
32
+ };
33
+ js_data_type: import("..").INiceErrorIdMetadata<TInspectErrorResult_JsDataType, import("..").JSONSerializableValue> & {
34
+ context: {
35
+ required: true;
36
+ };
37
+ };
38
+ js_other: import("..").INiceErrorIdMetadata<IInspectErrorResult_JsOther, import("..").JSONSerializableValue> & {
39
+ context: {
40
+ required: true;
41
+ };
42
+ };
43
+ };
44
+ }>;
@@ -0,0 +1,3 @@
1
+ import type { INiceErrorOptions } from "../../NiceError/NiceError";
2
+ import type { INiceErrorDefinedProps } from "../../NiceError/NiceError.types";
3
+ export declare const nice_error_test_options: INiceErrorOptions<INiceErrorDefinedProps, keyof INiceErrorDefinedProps["schema"]>;
@@ -0,0 +1 @@
1
+ export declare const isVal: <T>(input: unknown, val: T) => input is T;
@@ -0,0 +1,35 @@
1
+ import { NiceError } from "../NiceError/NiceError";
2
+ import type { INiceErrorDefinedProps } from "../NiceError/NiceError.types";
3
+ import { NiceErrorHydrated } from "../NiceError/NiceErrorHydrated";
4
+ import type { NiceErrorDefined } from "../NiceErrorDefined/NiceErrorDefined";
5
+ /**
6
+ * Combines `castNiceError`, `is()`, and `hydrate()` in a single call — the
7
+ * idiomatic way to handle an unknown value arriving from a remote boundary
8
+ * (API response, message queue, IPC, etc.) when you have a specific domain in mind.
9
+ *
10
+ * - Casts `value` to a `NiceError` using `castNiceError`.
11
+ * - If the result belongs to `niceErrorDefined`'s domain (`is()` returns `true`),
12
+ * hydrates it and returns a fully-typed `NiceErrorHydrated`.
13
+ * - Otherwise returns the raw cast `NiceError` (which may be a `wasntNice` error
14
+ * if `value` was not a NiceError at all).
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * // In an Express error handler:
19
+ * app.use((err, req, res, next) => {
20
+ * const error = castAndHydrate(err, err_user_auth);
21
+ *
22
+ * if (err_user_auth.is(error)) {
23
+ * // error is NiceErrorHydrated — getContext / addId available
24
+ * const result = matchFirst(error, {
25
+ * invalid_credentials: ({ username }) => res.status(401).json({ username }),
26
+ * account_locked: () => res.status(403).json({ locked: true }),
27
+ * });
28
+ * if (result) return;
29
+ * }
30
+ *
31
+ * next(err);
32
+ * });
33
+ * ```
34
+ */
35
+ export declare function castAndHydrate<ERR_DEF extends INiceErrorDefinedProps>(value: unknown, niceErrorDefined: NiceErrorDefined<ERR_DEF>): NiceErrorHydrated<ERR_DEF, keyof ERR_DEF["schema"] & string> | NiceError;
@@ -0,0 +1,15 @@
1
+ import { NiceError } from "../NiceError/NiceError";
2
+ /**
3
+ * Casts any unknown value into a `NiceError`.
4
+ *
5
+ * - If the value is already a `NiceError` instance, it is returned as-is.
6
+ * - If the value is a plain `Error`, it is wrapped with the original as `originError`.
7
+ * - If the value is a JSON-serialised `NiceError` object (e.g. from an API
8
+ * response), a best-effort `NiceError` is re-created from it.
9
+ * - For all other values, a generic `NiceError` is created with a descriptive
10
+ * message.
11
+ *
12
+ * After casting, use `NiceErrorDefined.is(error)` to narrow the error to a
13
+ * specific domain and access its strongly-typed ids and context.
14
+ */
15
+ export declare const castNiceError: (error: unknown) => NiceError;
@@ -0,0 +1,49 @@
1
+ import type { INiceErrorDefinedProps } from "../NiceError/NiceError.types";
2
+ import type { NiceErrorHydrated } from "../NiceError/NiceErrorHydrated";
3
+ import type { NiceErrorDefined } from "../NiceErrorDefined/NiceErrorDefined";
4
+ /**
5
+ * A single case in a `handleWith` / `handleWithAsync` call.
6
+ *
7
+ * Construct via `forDomain` or `forIds` — do not build this object directly.
8
+ */
9
+ export interface IErrorCase<DEF extends INiceErrorDefinedProps, IDS extends keyof DEF["schema"] & string> {
10
+ }
11
+ /**
12
+ * Builds a case that fires for any error whose domain exactly matches `domain`.
13
+ * The handler receives the fully-hydrated error, narrowed to all schema ids.
14
+ *
15
+ * Use with `error.handleWith([...])` (sync) or `error.handleWithAsync([...])` (async).
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * error.handleWith([
20
+ * forDomain(err_payments, (h) => {
21
+ * matchFirst(h, {
22
+ * payment_failed: ({ reason }) => res.status(402).json({ reason }),
23
+ * card_expired: () => res.status(402).json({ expired: true }),
24
+ * });
25
+ * }),
26
+ * ]);
27
+ * ```
28
+ */
29
+ export declare function forDomain<DEF extends INiceErrorDefinedProps>(domain: NiceErrorDefined<DEF>, handler: (error: NiceErrorHydrated<DEF, keyof DEF["schema"] & string>) => void | Promise<void>): IErrorCase<DEF, keyof DEF["schema"] & string>;
30
+ /**
31
+ * Builds a case that fires only if the error's domain matches `domain` **and**
32
+ * at least one of `ids` is active on the error.
33
+ * The handler receives the fully-hydrated error, narrowed to `IDS[number]`.
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * error.handleWith([
38
+ * forIds(err_feature, ["not_found", "forbidden"], (h) => {
39
+ * // h.getContext("not_found") and h.getContext("forbidden") are both available
40
+ * if (h.hasId("not_found")) res.status(404).json({ missing: h.getContext("not_found").resource });
41
+ * if (h.hasId("forbidden")) res.status(403).json({ denied: true });
42
+ * }),
43
+ *
44
+ * // Fallback: any other err_feature error
45
+ * forDomain(err_feature, (h) => res.status(500).json({ error: h.message })),
46
+ * ]);
47
+ * ```
48
+ */
49
+ export declare function forIds<DEF extends INiceErrorDefinedProps, IDS extends ReadonlyArray<keyof DEF["schema"] & string>>(domain: NiceErrorDefined<DEF>, ids: IDS, handler: (error: NiceErrorHydrated<DEF, IDS[number]>) => void | Promise<void>): IErrorCase<DEF, IDS[number]>;
@@ -0,0 +1,2 @@
1
+ import { type TInspectErrorResult } from "./inspectPotentialError.types";
2
+ export declare const inspectPotentialError: (potentialError: unknown) => TInspectErrorResult;
@@ -0,0 +1,9 @@
1
+ export declare enum EInspectErrorResultType {
2
+ nullish = "nullish",
3
+ niceErrorObject = "niceErrorObject",
4
+ niceError = "niceError",
5
+ jsError = "jsError",
6
+ jsErrorObject = "jsErrorObject",
7
+ jsDataType = "jsDataType",
8
+ jsOther = "jsOther"
9
+ }
@@ -0,0 +1,51 @@
1
+ import type { NiceError } from "../../NiceError/NiceError";
2
+ import type { INiceErrorJsonObject, IRegularErrorJsonObject } from "../../NiceError/NiceError.types";
3
+ import type { EInspectErrorResultType } from "./inspectPotentialError.enums";
4
+ export interface IInspectErrorResult_Base<T extends EInspectErrorResultType> {
5
+ type: T;
6
+ }
7
+ export interface IInspectErrorResult_Nullish extends IInspectErrorResult_Base<EInspectErrorResultType.nullish> {
8
+ value: null | undefined;
9
+ }
10
+ export interface IInspectErrorResult_NiceErrorObject extends IInspectErrorResult_Base<EInspectErrorResultType.niceErrorObject> {
11
+ niceErrorObject: INiceErrorJsonObject;
12
+ }
13
+ export interface IInspectErrorResult_NiceError extends IInspectErrorResult_Base<EInspectErrorResultType.niceError> {
14
+ niceError: NiceError;
15
+ }
16
+ export interface IInspectErrorResult_JsError extends IInspectErrorResult_Base<EInspectErrorResultType.jsError> {
17
+ jsError: Error;
18
+ }
19
+ export interface IInspectErrorResult_JsErrorObject extends IInspectErrorResult_Base<EInspectErrorResultType.jsErrorObject> {
20
+ jsErrorObject: IRegularErrorJsonObject;
21
+ }
22
+ /**
23
+ * JS DATA TYPES
24
+ */
25
+ export interface IInspectErrorResult_JsDataType_String extends IInspectErrorResult_Base<EInspectErrorResultType.jsDataType> {
26
+ jsDataType: "string";
27
+ jsDataValue: string;
28
+ }
29
+ export interface IInspectErrorResult_JsDataType_Number extends IInspectErrorResult_Base<EInspectErrorResultType.jsDataType> {
30
+ jsDataType: "number";
31
+ jsDataValue: number;
32
+ }
33
+ export interface IInspectErrorResult_JsDataType_Boolean extends IInspectErrorResult_Base<EInspectErrorResultType.jsDataType> {
34
+ jsDataType: "boolean";
35
+ jsDataValue: boolean;
36
+ }
37
+ export interface IInspectErrorResult_JsDataType_Object extends IInspectErrorResult_Base<EInspectErrorResultType.jsDataType> {
38
+ jsDataType: "object";
39
+ jsDataValue: object;
40
+ }
41
+ export type TInspectErrorResult_JsDataType = IInspectErrorResult_JsDataType_String | IInspectErrorResult_JsDataType_Number | IInspectErrorResult_JsDataType_Boolean | IInspectErrorResult_JsDataType_Object;
42
+ /**
43
+ * Catch-all for any other JS data type that doesn't fit the above categories (e.g. symbol, bigint, function, etc.)
44
+ */
45
+ export interface IInspectErrorResult_JsOther extends IInspectErrorResult_Base<EInspectErrorResultType.jsOther> {
46
+ jsDataValue: unknown;
47
+ }
48
+ /**
49
+ * Union of all possible results from inspectPotentialError
50
+ */
51
+ export type TInspectErrorResult = IInspectErrorResult_Nullish | IInspectErrorResult_NiceErrorObject | IInspectErrorResult_NiceError | IInspectErrorResult_JsError | IInspectErrorResult_JsErrorObject | TInspectErrorResult_JsDataType | IInspectErrorResult_JsOther;
@@ -0,0 +1,12 @@
1
+ import { type INiceErrorJsonObject } from "../NiceError/NiceError.types";
2
+ /**
3
+ * Returns `true` if `obj` is a JSON-serialised `NiceError` object matching the
4
+ * current wire format (contextState-based errorData entries).
5
+ *
6
+ * Validates:
7
+ * - Top-level shape (`name`, `message`, `wasntNice`, `httpStatusCode`, `def`)
8
+ * - Each `errorData` entry has a `contextState` with a valid `kind` discriminant
9
+ * (`"no_serialization"` or `"unhydrated"`) — rejecting payloads in the old
10
+ * format (`context` / `serialized` fields) to prevent silent data corruption.
11
+ */
12
+ export declare function isNiceErrorObject(obj: unknown): obj is INiceErrorJsonObject;
@@ -0,0 +1,2 @@
1
+ import type { IRegularErrorJsonObject } from "../NiceError/NiceError.types";
2
+ export declare function isRegularErrorJsonObject(obj: unknown): obj is IRegularErrorJsonObject;
@@ -0,0 +1 @@
1
+ export declare function jsErrorOrCastJsError(error: unknown, logMessage?: boolean): Error;
@@ -0,0 +1,3 @@
1
+ import { Logger } from "tslog";
2
+ export declare const logger_NiceError: Logger<unknown>;
3
+ export declare const logger_NiceError_testing: Logger<unknown>;
@@ -0,0 +1,35 @@
1
+ import { NiceError } from "../NiceError/NiceError";
2
+ import type { INiceErrorDefinedProps, TExtractContextType } from "../NiceError/NiceError.types";
3
+ /**
4
+ * Handler map for `matchFirst`. Each key is an error id (from `ACTIVE_IDS`) and
5
+ * the value is a function that receives the typed context for that id.
6
+ *
7
+ * The `_` key is an optional fallback that runs when no id-specific handler matched.
8
+ */
9
+ export type TMatchFirstHandlers<ERR_DEF extends INiceErrorDefinedProps, ACTIVE_IDS extends keyof ERR_DEF["schema"] & string, RESULT> = {
10
+ [K in ACTIVE_IDS]?: (context: TExtractContextType<ERR_DEF["schema"][K]>) => RESULT;
11
+ } & {
12
+ _?: () => RESULT;
13
+ };
14
+ /**
15
+ * Pattern-matches an error against a map of id → handler functions, returning the
16
+ * result of the first handler whose id is active on the error.
17
+ *
18
+ * - Ids are tested in the order returned by `error.getIds()`.
19
+ * - If no id-specific handler matched and `_` is provided, the fallback is called.
20
+ * - Returns `undefined` when neither any id handler nor the fallback fires.
21
+ *
22
+ * **Requires hydrated context.** If any matched id is in the `"unhydrated"` state,
23
+ * `getContext` will throw. Call `niceErrorDefined.hydrate(error)` beforehand when
24
+ * working with errors deserialized from a JSON payload.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * const result = matchFirst(error, {
29
+ * invalid_credentials: ({ username }) => `Wrong password for ${username}`,
30
+ * account_locked: () => "Account is locked",
31
+ * _: () => "Unknown auth error",
32
+ * });
33
+ * ```
34
+ */
35
+ export declare function matchFirst<ERR_DEF extends INiceErrorDefinedProps, ACTIVE_IDS extends keyof ERR_DEF["schema"] & string, RESULT>(error: NiceError<ERR_DEF, ACTIVE_IDS>, handlers: TMatchFirstHandlers<ERR_DEF, ACTIVE_IDS, RESULT>): RESULT | undefined;
@@ -0,0 +1,2 @@
1
+ import type { NiceError } from "../../NiceError/NiceError";
2
+ export declare const causePack: <E extends NiceError<any, any>>(error: E) => E;
@@ -0,0 +1,2 @@
1
+ import type { NiceError } from "../../NiceError/NiceError";
2
+ export declare const msgPack: <E extends NiceError<any, any>>(error: E) => E;
@@ -0,0 +1,3 @@
1
+ import type { NiceError } from "../../NiceError/NiceError";
2
+ import type { EErrorPackType } from "./packError.enums";
3
+ export declare const packError: <E extends NiceError<any, any>>(error: E, packType?: EErrorPackType) => E;
@@ -0,0 +1,5 @@
1
+ export declare enum EErrorPackType {
2
+ no_pack = "no_pack",
3
+ msg_pack = "msg_pack",
4
+ cause_pack = "cause_pack"
5
+ }
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@nice-code/error",
3
+ "main": "build/index.js",
4
+ "module": "build/index.js",
5
+ "types": "build/types/index.d.ts",
6
+ "type": "module",
7
+ "version": "0.0.15",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./build/types/index.d.ts",
11
+ "import": "./build/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "build",
16
+ "package.json",
17
+ "README.md"
18
+ ],
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "scripts": {
23
+ "type-check": "bunx tsc --noEmit",
24
+ "type-check-watch": "bunx tsc --noEmit --watch",
25
+ "vitest": "vitest --typecheck",
26
+ "vitest-agent": "vitest --typecheck --reporter=agent",
27
+ "clean-build": "bunx rimraf build",
28
+ "build": "bun run clean-build && bun run build.ts && bun run build-types",
29
+ "build-types": "tsc --project tsconfig.build.json",
30
+ "example": "bun run ./src/example/error_usage_example.ts"
31
+ },
32
+ "dependencies": {
33
+ "http-status-codes": "^2.3.0",
34
+ "valibot": "1.3.1",
35
+ "tslog": "^4.10.2"
36
+ }
37
+ }