/** * Route DSL (SPEC.md §41). * * One declaration is the runtime and the documentation at once: it validates the * request, types the handler, serializes the response, and describes itself to the * Schema Registry, from which OpenAPI, the API Explorer and the SDK are generated * (SPEC.md §3.7, §42, §121). */ import type { Actor, AssemoraContext } from '@assemora/core'; import { type InferShape, type JsonSchema, type Schema, type Shape } from '@assemora/schema'; export type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete'; /** An application error a route can answer with (SPEC.md §46). */ export type ErrorDescriptor = { readonly code: string; readonly status: number; readonly description?: string; }; export type RouteRequest

= { readonly params: InferShape

; readonly query: InferShape; readonly body: InferShape; readonly headers: Readonly>; readonly actor: Actor | undefined; readonly context: AssemoraContext; /** * The adapter's own request object. An advanced escape hatch and deliberately * `unknown`: Fastify must not become part of a handler's type (SPEC.md §40, §41). */ readonly request: unknown; }; export type RouteDefinition

= { readonly params?: P; readonly query?: Q; readonly body?: B; /** The shape of a successful answer. Used to serialize it and to document it. */ readonly response?: Shape | Schema; readonly auth?: boolean; /** * What the audit log should call this door (SPEC.md §67). * * `rest` unless a route says otherwise. The MCP endpoint says `mcp`, because "an * agent did this through MCP" and "somebody did this over REST" are the two * things that column exists to tell apart. */ readonly source?: AssemoraContext['source']; readonly status?: number; readonly description?: string; readonly tags?: readonly string[]; readonly errors?: readonly ErrorDescriptor[]; /** * How many bytes this route accepts, when the server's own ceiling is the wrong one * (SPEC.md §85). * * Per route rather than one number for the process, because the route that takes an * upload is the only one that needs the wide ceiling: a limit generous enough for a * photograph is a memory amplifier on every other address, and every address is what * a single server-wide number widens. */ readonly bodyLimit?: number; handler(request: RouteRequest): Promise | R; }; export type Route = { readonly node: 'route'; readonly method: HttpMethod; readonly path: string; readonly params: Schema | undefined; readonly query: Schema | undefined; readonly body: Schema | undefined; readonly response: Schema | undefined; readonly auth: boolean; readonly source: AssemoraContext['source'] | undefined; /** * The API version this route was published under, if any (SPEC.md §47). * * Set by `server.version()`, never by a route declaration: a route says what it does * and a server says where it lives. The path already carries the version — this is * so a reader can group by it without parsing one. */ readonly version: string | undefined; readonly status: number; readonly description: string | undefined; readonly tags: readonly string[]; readonly errors: readonly ErrorDescriptor[]; /** What this route accepts, and the server's ceiling when it is `undefined`. */ readonly bodyLimit: number | undefined; handler(request: RouteRequest): Promise | unknown; }; /** How a route describes itself in the Schema Registry (SPEC.md §42). */ export type RouteDescriptor = { readonly name: string; readonly method: HttpMethod; readonly path: string; readonly description?: string; readonly tags: readonly string[]; readonly auth: boolean; readonly status: number; readonly params?: JsonSchema; readonly query?: JsonSchema; readonly body?: JsonSchema; readonly response?: JsonSchema; readonly errors: readonly ErrorDescriptor[]; readonly module?: string; /** Which API version published it, for a reader that groups without parsing paths. */ readonly version?: string; /** * The largest body it accepts, in bytes, when it is not the server's own. * * Described rather than only enforced: OpenAPI and the SDK are generated from this, * and a document that promises an upload the server answers `413` to is a document * that lies about the one thing the caller has to size (SPEC.md §42, §44). */ readonly bodyLimit?: number; }; declare module '@assemora/core' { interface RegistrySections { routes: RouteDescriptor; } } /** * ```ts * route.post('/auth/login', { * body: { email: email(), password: string().min(8) }, * response: { token: string() }, * handler: async ({ body }) => ({ token: await login(body) }), * }) * ``` */ export declare const route: { get:

(path: string, definition: RouteDefinition) => Route; post:

(path: string, definition: RouteDefinition) => Route; put:

(path: string, definition: RouteDefinition) => Route; patch:

(path: string, definition: RouteDefinition) => Route; delete:

(path: string, definition: RouteDefinition) => Route; }; /** `POST /auth/login` → `post /auth/login`, the name the registry keys on. */ export declare const routeName: (method: HttpMethod, path: string) => string; export declare const describeRoute: (definition: Route, module?: string) => RouteDescriptor; //# sourceMappingURL=route.d.ts.map