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,82 @@
# `options` — Zod-validated options for `createStaticPrincipalResolver`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Owns the runtime contract between the test harness call site and the
resolver factory. The schema validates both the outer options bag
(`{ principal, nullForPaths?, applyTo? }`) and the nested `Principal` shape
(non-empty `id`, readonly `scopes`, optional `tenantId`, default-`{}`
`claims`). On failure it raises a typed `AuthStaticPrincipalError` carrying
the originating Zod issues — splitting between `INVALID_OPTIONS` (anything
outside `principal`) and `INVALID_PRINCIPAL` (anything inside it).
This module is the only place the package touches Zod at runtime. Keeping it
isolated lets the resolver factory stay a thin three-line function and lets
the conformance test target the resolver behaviour without invoking schema
side-effects.
## Features
- Strict outer schema — unknown keys at the top level reject with
`INVALID_OPTIONS`.
- Discriminated error codes: `principal` issues map to `INVALID_PRINCIPAL`;
everything else maps to `INVALID_OPTIONS`.
- Pre-flight type check rejects non-object inputs with `INVALID_OPTIONS`
before Zod sees them — a cleaner message than the Zod default for `null` /
arrays.
- `claims` defaults to `{}` so callers don't have to write
`claims: {}` for the common case.
## Usage: Basic
```ts
import { parseStaticPrincipalResolverOptions } from "@suaveplan/api-auth-static-principal/resolver";
const opts = parseStaticPrincipalResolverOptions({
principal: {
id: "u_1",
scopes: ["billing:write"],
tenantId: "acme",
claims: { email: "user@acme.test" },
},
});
```
## Usage: Advanced
Validate options that include both `applyTo` and `nullForPaths`:
```ts
import { parseStaticPrincipalResolverOptions } from "@suaveplan/api-auth-static-principal/resolver";
const opts = parseStaticPrincipalResolverOptions({
principal: { id: "u_1", scopes: [], claims: {} },
nullForPaths: ["/webhooks/*", "/healthz"],
applyTo: (req) => !req.headers.has("x-skip-auth"),
});
```
## API Reference
| Symbol | Kind | Description |
| -------------------------------------------- | -------- | ----------------------------------------------------------------- |
| `StaticPrincipalResolverOptionsSchema` | Zod | Strict object schema for the outer bag. |
| `parseStaticPrincipalResolverOptions(raw)` | function | Returns the validated options or throws `AuthStaticPrincipalError`. |
## Implementation Notes
The pre-flight `typeof`/`Array.isArray` check lets the function return a
single canonical error for "you handed me something that isn't an object" —
Zod's own behaviour on `null` is to emit
`{ code: "invalid_type", expected: "object" }`, which is correct but verbose.
Splitting into a pre-flight + Zod pass is one extra branch but keeps the
caller-facing failure message stable.
`claims` is recorded as `z.record(z.unknown())` so any free-form JWT/claims
payload validates. Coercing to readonly happens at the TypeScript boundary
(`StaticPrincipalResolverOptions`), not in Zod — Zod's `.readonly()` is
type-level only and would re-wrap arrays at runtime unnecessarily.