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,74 @@
# `route-match`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
The `route-match` module defines `RouteMatch`, the shape every concrete
adapter yields after resolving an incoming `(method, url)` pair against the
router's registry. The host pipeline threads this value through middleware
into the handler — middleware can introspect `options` to react to per-route
flags (idempotent, rate-limit) without re-parsing.
`pluginOfRecord` is carried explicitly so the host can stamp telemetry
labels and the rollback journal with the plugin that owns the matched
route, even when middleware is mounted across plugin boundaries.
## Features
- `RouteMatch<Handler>` — generic over the handler type so adapters can
pin a specific call signature (Hono context vs. in-memory vs. worker
proxy).
- `params` — parsed path-segment captures, frozen.
- `options` — the parsed `RouteOptions` block (post-Zod defaults).
- `createRouteMatch(init)` — convenience factory that freezes the result.
## Usage: Basic
```ts
import { createRouteMatch } from "@suaveplan/api-router/route-match";
import { parseRouteOptions } from "@suaveplan/api-router/route-options";
const match = createRouteMatch({
method: "GET",
path: "/users/:id",
params: { id: "u_42" },
handler: async () => ({ ok: true }),
options: parseRouteOptions({ auth: "users.read" }),
pluginOfRecord: "auth",
});
```
## Usage: Advanced
```ts
import type { RouteMatch } from "@suaveplan/api-router/route-match";
type HonoHandler = (ctx: { req: unknown }) => Promise<Response>;
function dispatch(match: RouteMatch<HonoHandler>) {
// match.handler signature is narrowed to HonoHandler
return match.handler({ req: {} });
}
```
## API Reference
- `RouteMatch<Handler>` — `{ method, path, params, handler, options, pluginOfRecord }`.
- `AnyRouteHandler` — type-erased handler signature (`(...args) => unknown`).
- `createRouteMatch(init)` — returns a frozen `RouteMatch`.
## Implementation Notes
`Object.freeze` is applied in `createRouteMatch` so middleware that
accidentally tries to mutate the match throws in strict mode — this catches
a class of bugs where downstream middleware reaches into the upstream
match's `params` and mutates path captures. Adapters that construct
`RouteMatch` objects directly are expected to apply their own freezing
discipline; the helper is the recommended path.
The handler generic carries through to the consumer so generic dispatch
loops can keep type safety. Erasing to `AnyRouteHandler` is permitted at
the boundary between adapters (where the host can't know the concrete
signature), but per-adapter code should pin the type.