# codes _(no submodules)_ ## Purpose Defines the stable, namespaced error-code registry for `@suaveplan/crypto-utils`. Every error thrown by this package carries a code from this registry, which lets callers type-narrow on `error.code` rather than relying on string matching against message text. ## Features - Single `defineCodes` call produces a frozen, read-only map of codes under the `CRYPTO.UTILS` namespace - Codes are plain string literals (`"CRYPTO.UTILS.PRIMITIVE_NOT_IMPLEMENTED"`, etc.) — safe to log, serialize, and compare across process boundaries - `CryptoUtilsCode` union type keeps downstream `catch` blocks fully typed without any runtime cost - Covers the full error surface of the package: encoding validation, byte-length mismatches, integer-range checks, Merkle-tree errors, RNG limits, and the primitive-not-implemented sentinel ## Usage: Basic Example ```ts import { CRYPTO_UTILS_CODES, type CryptoUtilsCode } from "@suaveplan/crypto-utils/errors/codes"; function handleError(code: CryptoUtilsCode): string { switch (code) { case CRYPTO_UTILS_CODES.ENCODING_INVALID_INPUT: return "The supplied string is not valid for the chosen encoding."; case CRYPTO_UTILS_CODES.PRIMITIVE_NOT_IMPLEMENTED: return "This cryptographic primitive has no native implementation yet."; default: return "Unknown crypto-utils error."; } } ``` ## Usage: Advanced Example Type-narrowing in a catch block using the `CryptoUtilsCode` union: ```ts import { CRYPTO_UTILS_CODES, type CryptoUtilsCode } from "@suaveplan/crypto-utils/errors/codes"; import { CryptoUtilsError } from "@suaveplan/crypto-utils/errors/crypto-utils-error"; async function safeHex(input: string): Promise { try { const { hexToBytes } = await import("@suaveplan/crypto-utils/encoding/hex/hex"); return hexToBytes(input); } catch (err) { if (err instanceof CryptoUtilsError) { const code: CryptoUtilsCode = err.code; if (code === CRYPTO_UTILS_CODES.ENCODING_INVALID_INPUT) { console.warn("Bad hex input, returning null:", err.message); return null; } } throw err; } } ``` ## API Reference ### `CRYPTO_UTILS_CODES` ```ts const CRYPTO_UTILS_CODES: { readonly PRIMITIVE_NOT_IMPLEMENTED: "CRYPTO.UTILS.PRIMITIVE_NOT_IMPLEMENTED"; readonly ENCODING_INVALID_INPUT: "CRYPTO.UTILS.ENCODING.INVALID_INPUT"; readonly BYTES_LENGTH_MISMATCH: "CRYPTO.UTILS.BYTES.LENGTH_MISMATCH"; readonly BYTES_INVALID_LENGTH: "CRYPTO.UTILS.BYTES.INVALID_LENGTH"; readonly INTEGER_OUT_OF_RANGE: "CRYPTO.UTILS.INTEGER.OUT_OF_RANGE"; readonly MERKLE_EMPTY_LEAVES: "CRYPTO.UTILS.MERKLE.EMPTY_LEAVES"; readonly MERKLE_INVALID_PROOF: "CRYPTO.UTILS.MERKLE.INVALID_PROOF"; readonly RNG_INVALID_LENGTH: "CRYPTO.UTILS.RNG.INVALID_LENGTH"; }; ``` Frozen registry produced by `defineCodes("CRYPTO.UTILS", [...])`. Dot-separated sub-namespaces (`ENCODING.INVALID_INPUT`, `BYTES.LENGTH_MISMATCH`, etc.) become underscore-keyed properties on the returned object. **Returns** — A read-only record whose values are opaque string literals suitable for stable logging and wire serialization. --- ### `CryptoUtilsCode` ```ts type CryptoUtilsCode = (typeof CRYPTO_UTILS_CODES)[keyof typeof CRYPTO_UTILS_CODES]; ``` Union of every string literal in `CRYPTO_UTILS_CODES`. Use this as the `code` parameter type in `catch` blocks or error-handler signatures to stay fully typed without importing the entire error object. ## Implementation Notes `defineCodes` (from `@suaveplan/error`) is the single source of truth for code formatting: it prepends the namespace, freezes the resulting object, and guarantees that each value is a unique string. This file owns no logic — it is a pure declaration layer. The dot-notation in the raw array entries (`"ENCODING.INVALID_INPUT"`) is a human-readable convention for grouping related codes within the namespace; the resulting object key uses the underscore-separated form (`ENCODING_INVALID_INPUT`). Consumers should always reference `CRYPTO_UTILS_CODES.*` constants rather than the raw string literals so that renames are caught at compile time. Adding a new code requires only appending a string to the `as const` array in this file and optionally adding a new subclass to the `errors/` directory. No numeric IDs, no registry migrations.