first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,126 @@
# `errors/errors.ts`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Stable error code registry, per-code metadata, and the concrete
`ClipboardError` class for the `@suaveplan/clipboard` package. Every error
path inside the manager, fallback, permissions, and security modules
surfaces one of these codes so consumers can match programmatically
without inspecting message strings. Codes are namespaced under
`CLIPBOARD.*` and registered via the shared `defineCodes` helper from
`@suaveplan/error` so the runtime values, the literal union type, and the
metadata table stay in lock-step.
## Features
- Eight stable codes: `API_UNAVAILABLE`, `PERMISSION_DENIED`,
`FALLBACK_FAILED`, `INSECURE_CONTEXT`, `NO_CONTENT`, `READ_FAILED`,
`DOCUMENT_UNAVAILABLE`, `QUEUE_DRAINED`.
- Per-code metadata: `httpStatus`, `retryable`, `severity`, `description`.
- `ClipboardError extends SuaveplanError<ClipboardErrorCode>` — preserves
cause chains, supports OTel span events, and integrates with the
project's typed-error contract.
- `asClipboardError(code, cause, fallbackMessage)` lifts unknown thrown
values into the typed hierarchy at every catch site.
## Usage: Basic
```ts
import {
CLIPBOARD_CODES,
ClipboardError,
} from "@suaveplan/clipboard";
try {
// ...
} catch (cause) {
throw new ClipboardError(
CLIPBOARD_CODES.READ_FAILED,
"Clipboard read rejected",
{ cause: cause instanceof Error ? cause : new Error(String(cause)) },
);
}
```
## Usage: Advanced
```ts
import {
asClipboardError,
CLIPBOARD_CODES,
CLIPBOARD_ERROR_METADATA,
} from "@suaveplan/clipboard";
function decide(err: unknown): { retry: boolean; status: number } {
if (
err instanceof Error &&
"code" in err &&
typeof (err as { code?: string }).code === "string" &&
(err as { code: string }).code.startsWith("CLIPBOARD.")
) {
const meta =
CLIPBOARD_ERROR_METADATA[
(err as { code: keyof typeof CLIPBOARD_ERROR_METADATA })
.code
];
return { retry: meta.retryable, status: meta.httpStatus };
}
const lifted = asClipboardError(
CLIPBOARD_CODES.READ_FAILED,
err,
"Unknown clipboard failure.",
);
return {
retry: lifted.metadata.retryable,
status: lifted.metadata.httpStatus,
};
}
```
## API Reference
### `CLIPBOARD_CODES`
`Readonly<Record<<key>, "CLIPBOARD.<key>">>` produced by `defineCodes`.
The runtime values are namespaced strings; the type infers a literal
union for exhaustive matching.
### `CLIPBOARD_ERROR_METADATA`
`Readonly<Record<ClipboardErrorCode, ClipboardCodeMetadata>>` — frozen map
from each code to its `httpStatus`, `retryable`, `severity`, and
`description` fields.
### `ClipboardCodeMetadata`
Interface with `httpStatus: number`, `severity: "info" | "warning" | "error"`,
`retryable: boolean`, `description: string`.
### `ClipboardError`
Concrete subclass of `SuaveplanError<ClipboardErrorCode>`. Constructor
signature: `new ClipboardError(code, message, options?)`. Exposes a
`.metadata` getter that returns the row from
`CLIPBOARD_ERROR_METADATA`.
### `asClipboardError(code, cause, fallbackMessage)`
Lifts an arbitrary `unknown` thrown value into a `ClipboardError`,
preserving the cause chain. Uses `cause.message` when available and
`fallbackMessage` otherwise. Always returns a `ClipboardError` with the
supplied code.
## Implementation Notes
The package version of `defineCodes` is the canonical helper from
`@suaveplan/error`; every package uses the same pattern so cross-
cutting tooling (registry validators, retention checks, OpenSpec
conformance) can introspect every namespace identically. Codes are
intentionally namespaced strings rather than enums so they remain JSON-
serialisable and stable across versions. The metadata table is `Object.freeze`-d
so mutation is a typecheck error and a runtime error; reviewers can
diff additions in pull requests without worrying about silent rewrites.