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,95 @@
# oauth-client-error
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Defines the stable error-code registry and typed error class for `@suaveplan/oauth-client`. All runtime failures thrown by this package originate from `OAuthClientError`, which extends `SuaveplanError` to provide deterministic error codes, cause-chain traversal, structured context, and OTel span-event integration inherited from `@suaveplan/error`.
Having a single error hierarchy makes it straightforward for callers to distinguish OAuth-specific failures (via `instanceof OAuthClientError`) from other application errors and to map codes to user-facing messages without pattern-matching raw strings.
## Features
- `OAUTH_CLIENT_CODES` — stable, tree-shakeable code registry produced by `defineCodes("OAUTH_CLIENT", …)`.
- Codes for every failure domain: authorization, token exchange, token refresh, token revocation, token expiry, state/PKCE mismatch, OIDC discovery, config validation, ID-token validation, and unknown-provider lookups.
- `OAuthClientErrorCode` — union type derived directly from the registry, providing exhaustive narrowing.
- `OAuthClientError` — public constructor extending `SuaveplanError<OAuthClientErrorCode>` with `name = "OAuthClientError"`.
## Usage: Basic Example
```ts
import { OAuthClientError, OAUTH_CLIENT_CODES } from "@suaveplan/oauth-client/errors";
throw new OAuthClientError(
OAUTH_CLIENT_CODES.INVALID_STATE,
"oauth.state.mismatch",
);
```
## Usage: Advanced Example
```ts
import { OAuthClientError, OAUTH_CLIENT_CODES } from "@suaveplan/oauth-client/errors";
try {
const tokens = await client.handleCallback(code, state, storedState, verifier);
} catch (err) {
if (err instanceof OAuthClientError) {
switch (err.code) {
case OAUTH_CLIENT_CODES.INVALID_STATE:
// CSRF attack or stale session — abort
break;
case OAUTH_CLIENT_CODES.TOKEN_EXCHANGE_FAILED:
// Show user-facing error with err.context?.statusCode
break;
default:
throw err;
}
}
}
```
## API Reference
### `OAUTH_CLIENT_CODES`
```ts
const OAUTH_CLIENT_CODES: {
AUTHORIZATION_FAILED: string;
TOKEN_EXCHANGE_FAILED: string;
TOKEN_REQUEST_FAILED: string;
TOKEN_REFRESH_FAILED: string;
TOKEN_REVOKE_FAILED: string;
TOKEN_EXPIRED: string;
INVALID_STATE: string;
PKCE_MISMATCH: string;
DISCOVERY_FAILED: string;
INVALID_CONFIG: string;
INVALID_ID_TOKEN: string;
UNKNOWN_PROVIDER: string;
}
```
Stable code registry. Each value is a namespaced string such as `"OAUTH_CLIENT.INVALID_STATE"`.
### `OAuthClientErrorCode`
Union type of all values in `OAUTH_CLIENT_CODES`. Useful for exhaustive `switch` statements.
### `OAuthClientError`
```ts
class OAuthClientError extends SuaveplanError<OAuthClientErrorCode> {
constructor(code: OAuthClientErrorCode, messageKey: string, options?: SuaveplanErrorOptions): void;
}
```
- `code` — one of `OAUTH_CLIENT_CODES` values.
- `messageKey` — i18n message key (e.g. `"oauth.state.mismatch"`).
- `options.cause` — original error to attach as the causal chain.
- `options.context` — arbitrary structured metadata surfaced by `@suaveplan/error`.
## Implementation Notes
`defineCodes` produces a frozen object whose values are stable across builds and minifiers — no runtime reflection or `Object.keys` enumeration is needed by callers. The `noUselessConstructor` biome lint suppression is intentional: the explicit `public constructor` widens the protected base constructor to public access, which is a meaningful API contract not enforced by inheritance alone.