Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
# error-codes
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Defines the stable `GRAPHQL.*` error-code registry for `@suaveplan/api-plugin-graphql` and the `GraphQLError` class consumers catch and discriminate on. Every failure path inside the package — Zod validation at `defineGraphQLPlugin`, role enforcement in `requireRoles`, argument validation in `validateArgs`, schema lookups, and duplicate-resolver registration — throws a `GraphQLError` carrying one of these codes.
Upstream threw bare `Error(...)` strings; policy (CLAUDE.md rules + AGENTS.md §13) requires typed errors extending `SuaveplanError`. This file replaces every upstream `throw new Error("Authentication required")` etc. with `throw new GraphQLError(GRAPHQL_CODES.UNAUTHENTICATED, ...)` so consumers can branch on `error.code` instead of `error.message`.
## Features
- 6 stable codes registered via `defineCodes("GRAPHQL", [...])`.
- `GraphQLError extends SuaveplanError<GraphQLErrorCode>` — `instanceof GraphQLError` narrows `code`.
- Optional `SuaveplanErrorOptions` (`cause`, `context`, `redact`) on every constructor call.
## Usage: Basic
```ts
import { GraphQLError, GRAPHQL_CODES } from "@suaveplan/api-plugin-graphql";
try {
plugin = defineGraphQLPlugin({ name: 1 as unknown as string, ...rest });
} catch (e) {
if (e instanceof GraphQLError && e.code === GRAPHQL_CODES.INVALID_INPUT) {
console.error("invalid options", e.cause);
}
}
```
## Usage: Advanced
```ts
import { GraphQLError, GRAPHQL_CODES } from "@suaveplan/api-plugin-graphql";
function safeAddResolver(c: ResolverComposer, t: string, f: string, fn: ResolverFn) {
if (c.hasResolver(t, f)) {
throw new GraphQLError(
GRAPHQL_CODES.DUPLICATE_RESOLVER,
`resolver already exists for ${t}.${f}`,
{ context: { typeName: t, fieldName: f } },
);
}
c.addResolver(t, f, fn);
}
```
## API Reference
| Symbol | Kind | Notes |
|---|---|---|
| `GRAPHQL_CODES` | const | `{ UNAUTHENTICATED, INSUFFICIENT_ROLE, VALIDATION_FAILED, INVALID_INPUT, TYPE_NOT_FOUND, DUPLICATE_RESOLVER }` — each value is the string `"GRAPHQL.<NAME>"`. |
| `GraphQLErrorCode` | type | Union of the six string literal codes. |
| `GraphQLError` | class | Extends `SuaveplanError<GraphQLErrorCode>`. Constructor: `(code, message, options?)`. `error.graphqlCode` mirrors `error.code`. |
## Implementation Notes
`defineCodes` (from `@suaveplan/error`) returns a frozen const record whose value type is preserved through `(typeof GRAPHQL_CODES)[keyof typeof GRAPHQL_CODES]`. This means `error.code` is the literal union, not `string`.
The base class constructor in `@suaveplan/error` is `protected`; we widen it to `public` so callers can construct errors directly when wrapping third-party failures (e.g. mapping a foreign cause). `graphqlCode` is a strongly-typed mirror of `.code` that survives transport boundaries even if a consumer narrows on `instanceof Error` instead of `instanceof GraphQLError`.
Every code in `GRAPHQL_CODES` is thrown from at least one production code path; the `src/api-plugin-graphql.spec-conformance.test.ts` file pins this invariant.