@samveys/http
Kernel, router, controllers, middleware, Problem Details, security headers, node driver, SSE, WebSocket
import { compilePattern, compressResponse, createHttpKernel, createHttpServer, createRouter, createWebSocketServer, … } from '@samveys/http'
Function (22)
compilePattern
Function
Compiles a route pattern. Segments are literals, `:name`, `:name?` (trailing only) or a final `*` / `*name`. Anything that looks like regex is rejected with SVS_E045.
function compilePattern(input: string): CompiledPattern;
Exported from packages/http/src/pattern.ts
compressResponse
Function
Streams the body through `encoding` and sets `Content-Encoding`, drops `Content-Length`, and adds `Accept-Encoding` to `Vary`. The body is piped, never buffered. Responses that should not be touched are returned unchanged: no body (so HEAD too), 204/304/1xx, an existing `Content-Encoding`, `Cache-Control: no-transform` (a handler's per-response opt-out), `text/event-stream`, already-compressed media types, and a known `Content-Length` below `threshold`.
function compressResponse(response: Response, encoding: CompressionEncoding, threshold: number): Response;
Exported from packages/http/src/compression.ts
createHttpKernel
Function
No documentation comment.
function createHttpKernel(app: AppContext, config?: ServerConfig): Promise<HttpKernel>;
Exported from packages/http/src/kernel.ts
createHttpServer
Function
Builds the kernel for a registered app and returns the server handle. On `app:terminating` the server shuts down gracefully (`stopAccepting` → `drain` → `driver.close`). `config` defaults to the `'http.config'` binding of the `http()` plugin.
function createHttpServer(app: AppContext, config?: ServerConfig): Promise<HttpServer>;
Exported from packages/http/src/plugin.ts
createRouter
Function
Creates an empty router. Patterns are compiled when a route is mounted (SVS_E045); `list()` checks duplicates (SVS_E046).
function createRouter(): Router;
Exported from packages/http/src/router.ts
createWebSocketServer
Function
Server that tracks every open connection, so shutdown can close them with 1001.
function createWebSocketServer(): {
Exported from packages/http/src/websocket.ts
defineController
Function
Declares a controller. Routes are named `<name>.<key>` unless a route sets `name`. Names, prefixes and routes are checked when the controller is mounted.
function defineController<const N extends string, const R extends Readonly<Record<string, RouteDefinition<any, any>>>>(name: N, options: ControllerOptions<R>): Controller<N, R>;
Exported from packages/http/src/router.ts
defineRoutes
Function
Declares a route file: `export default defineRoutes((router) => { router.get('/ping', () => 'pong') })`.
function defineRoutes(register: (router: Router) => void): RouteFile;
Exported from packages/http/src/router.ts
describeRoutes
Function
Every mounted route of `router` with its validation schemas, in match order.
function describeRoutes(router: Router): readonly RouteDescription[];
Exported from packages/http/src/describe.ts
formatSseEvent
Function
One event in the WHATWG `text/event-stream` format. Newlines in `id` and `event` are refused.
function formatSseEvent(event: SseEvent): string;
Exported from packages/http/src/sse.ts
generateRouteTypes
Function
Content of `.samveys/types/routes.d.ts`: one `RouteRegistry` key per named route.
function generateRouteTypes(entries: readonly RouteEntry[]): string;
Exported from packages/http/src/route-types.ts
http
Function
The `@samveys/http` plugin. List it in `samveys.config.ts`: it binds `'http.config'` (resolved config) and a lazily created `'http.router'`. Use `createHttpServer()` to run the server.
function http(config?: ServerConfig): import("@samveys/core").Plugin<ServerConfig | undefined>;
Exported from packages/http/src/plugin.ts
negotiateEncoding
Function
Picks the response encoding from an `Accept-Encoding` header value. Members with `q=0` are refused, `*` covers every coding not named, and equal q-values are broken by the order of `offered` (the server's preference). Returns `undefined` when nothing offered is acceptable (e.g. `identity` only). The header is parsed by splitting; no regular expression touches it.
function negotiateEncoding(acceptEncoding: string | null, offered: readonly CompressionEncoding[]): CompressionEncoding | undefined;
Exported from packages/http/src/compression.ts
node
Function
The built-in driver on `node:http`, `node:https` or `node:http2`. Response bodies are streamed by the kernel; this driver only owns the socket server, its timeouts and graceful close.
function node(options?: NodeDriverOptions): HttpDriver<NodeServer>;
Exported from packages/http/src/driver.ts
problemResponse
Function
`application/problem+json` response for RFC 9457 Problem Details. Status comes from `init` or the problem.
function problemResponse(problem: ProblemDetails, init?: ResponseInit): Response;
Exported from packages/http/src/response.ts
resolveServerConfig
Function
Applies the defaults documented on `ServerConfig` and validates the numbers.
function resolveServerConfig(config?: ServerConfig): ResolvedServerConfig;
Exported from packages/http/src/kernel.ts
route
Function
`route('users.show', { id: 7 })` → `/users/7`. Uses the router bound as `'http.router'` in the container scope of the current request (or `container.run()`); throws SVS_E051 for an unknown name, a missing or unknown parameter, or when no router is reachable (use `routeFrom` then).
function route<const N extends RouteName>(name: N, ...args: RouteParamsArg<N>): string;
Exported from packages/http/src/route-types.ts
routeFrom
Function
Same as `route()` for a router you hold (tests, scripts, outside a request).
function routeFrom<const N extends RouteName>(router: Router, name: N, ...args: RouteParamsArg<N>): string;
Exported from packages/http/src/route-types.ts
sse
Function
A Server-Sent Events response. The source gets the client's `Last-Event-ID`, so it can resume after a reconnect, and an `AbortSignal` that fires when the client goes away. ```ts router.get('/events', (ctx) => sse(ctx, async function* ({ lastEventId }) { for (const event of await eventsAfter(lastEventId)) yield { id: event.id, data: event } })) ```
function sse(ctx: HttpContext, source: SseSource, options?: SseOptions): Response;
Exported from packages/http/src/sse.ts
toResponse
Function
Converts a handler return value: `Response` as is, string → text, `undefined` → 204, anything else → JSON.
function toResponse(value: unknown): Response;
Exported from packages/http/src/response.ts
websockets
Function
WebSocket routes, served by `@samveys/http` on the HTTP port: ```ts websockets({ routes: [ws('/chat', { origins: ['https://app.example.com'] }, { message: (socket, data) => socket.send(data) })] }) ```
function websockets(options: WebSocketsOptions): import("@samveys/core").Plugin<WebSocketsOptions>;
Exported from packages/http/src/ws-plugin.ts
ws
Function
Declares a WebSocket route for `websockets({ routes: [...] })`.
function ws<M = string | Uint8Array>(path: string, options: WebSocketRouteOptions, handlers: WebSocketHandlers<M>): WebSocketRoute;
Exported from packages/http/src/ws-plugin.ts
Value (7)
CLOSE
Value
No documentation comment.
const CLOSE: Readonly<{
normal: 1000;
goingAway: 1001;
protocolError: 1002;
unsupportedData: 1003;
invalidPayload: 1007;
policyViolation: 1008;
messageTooBig: 1009;
internalError: 1011;
}>;
Exported from packages/http/src/websocket.ts
del
Value
No documentation comment.
const del: RouteBuilder<"DELETE">;
Exported from packages/http/src/router.ts
get
Value
Route builders. `delete` is a reserved word, so it is exported as `del` and as `routes.delete`.
const get: RouteBuilder<"GET">;
Exported from packages/http/src/router.ts
patch
Value
No documentation comment.
const patch: RouteBuilder<"PATCH">;
Exported from packages/http/src/router.ts
post
Value
No documentation comment.
const post: RouteBuilder<"POST">;
Exported from packages/http/src/router.ts
put
Value
No documentation comment.
const put: RouteBuilder<"PUT">;
Exported from packages/http/src/router.ts
routes
Value
All builders in one object: `routes.get(…)`, `routes.delete(…)`.
const routes: {
readonly get: RouteBuilder<"GET">;
readonly post: RouteBuilder<"POST">;
readonly put: RouteBuilder<"PUT">;
readonly patch: RouteBuilder<"PATCH">;
readonly delete: RouteBuilder<"DELETE">;
};
Exported from packages/http/src/router.ts
Interface (35)
CompressionOptions
Interface
No documentation comment.
interface CompressionOptions {
/** Encodings offered, in server preference order. Default `['zstd', 'br', 'gzip']`. */
readonly encodings?: readonly CompressionEncoding[];
/** Bodies with a known `Content-Length` below this many bytes are sent as is. Default 1024. */
readonly threshold?: number;
}
Exported from packages/http/src/contracts.ts
Controller
Interface
No documentation comment.
interface Controller<N extends string = string, R extends Readonly<Record<string, RouteDefinition<any, any>>> = Readonly<Record<string, RouteDefinition<any, any>>>> {
readonly kind: 'controller';
readonly name: N;
readonly prefix: string;
readonly use: readonly MiddlewareRef[];
readonly routes: R;
}
Exported from packages/http/src/contracts.ts
ControllerOptions
Interface
No documentation comment.
interface ControllerOptions<R extends Readonly<Record<string, RouteDefinition<any, any>>>> {
/** Default `/`. May contain params. */
readonly prefix?: string;
readonly use?: readonly MiddlewareRef[];
readonly routes: R;
}
Exported from packages/http/src/contracts.ts
FetchOptions
Interface
No documentation comment.
interface FetchOptions {
/** Aborts the request (client disconnect). */
readonly signal?: AbortSignal;
/** Remote address used for logging and trusted-proxy decisions. */
readonly remoteAddress?: string;
}
Exported from packages/http/src/contracts.ts
GroupOptions
Interface
No documentation comment.
interface GroupOptions {
readonly prefix?: string;
readonly use?: readonly MiddlewareRef[];
readonly plugins?: readonly GroupPluginRef[];
/** Prefix for automatic names of plain router routes in this group. */
readonly as?: string;
}
Exported from packages/http/src/contracts.ts
HttpDriver
Interface
No documentation comment.
interface HttpDriver<Native = unknown> {
readonly name: string;
/** `http.Server` | `https.Server` | `http2.Http2SecureServer` for the node driver; `undefined` before listen. */
readonly native: Native | undefined;
listen(kernel: HttpKernel, options: ListenOptions): Promise<AddressInfo>;
/** Stop accepting connections, close idle ones, wait for in-flight ones up to `timeout`, then force-close. */
close(options?: {
readonly timeout?: number;
}): Promise<void>;
/** Required: bodies are streamed without buffering. */
…
Show the whole declaration (14 lines)
interface HttpDriver<Native = unknown> {
readonly name: string;
/** `http.Server` | `https.Server` | `http2.Http2SecureServer` for the node driver; `undefined` before listen. */
readonly native: Native | undefined;
listen(kernel: HttpKernel, options: ListenOptions): Promise<AddressInfo>;
/** Stop accepting connections, close idle ones, wait for in-flight ones up to `timeout`, then force-close. */
close(options?: {
readonly timeout?: number;
}): Promise<void>;
/** Required: bodies are streamed without buffering. */
…interface HttpDriver<Native = unknown> {
readonly name: string;
/** `http.Server` | `https.Server` | `http2.Http2SecureServer` for the node driver; `undefined` before listen. */
readonly native: Native | undefined;
listen(kernel: HttpKernel, options: ListenOptions): Promise<AddressInfo>;
/** Stop accepting connections, close idle ones, wait for in-flight ones up to `timeout`, then force-close. */
close(options?: {
readonly timeout?: number;
}): Promise<void>;
/** Required: bodies are streamed without buffering. */
readonly streaming: true;
/** Forward WebSocket upgrade requests to `kernel.handleUpgrade`. */
upgrade?(kernel: HttpKernel): void;
}
Exported from packages/http/src/contracts.ts
HttpKernel
Interface
No documentation comment.
interface HttpKernel {
/** For Node-based drivers. Never rejects: errors become Problem Details responses. */
handleNode(req: IncomingMessage, res: ServerResponse): Promise<void>;
/** For Fetch API drivers and tests. Never rejects. */
fetch(request: Request, options?: FetchOptions): Promise<Response>;
/** For WebSocket upgrades; emits `http:upgrade`. Without a listener the socket gets 426 and is destroyed. */
handleUpgrade(req: IncomingMessage, socket: Duplex, head: Buffer): void;
/** Requests currently being handled. */
readonly inFlight: number;
/** Resolves when `inFlight` reaches 0, or after `timeout` ms (returns false then). */
…
Show the whole declaration (14 lines)
interface HttpKernel {
/** For Node-based drivers. Never rejects: errors become Problem Details responses. */
handleNode(req: IncomingMessage, res: ServerResponse): Promise<void>;
/** For Fetch API drivers and tests. Never rejects. */
fetch(request: Request, options?: FetchOptions): Promise<Response>;
/** For WebSocket upgrades; emits `http:upgrade`. Without a listener the socket gets 426 and is destroyed. */
handleUpgrade(req: IncomingMessage, socket: Duplex, head: Buffer): void;
/** Requests currently being handled. */
readonly inFlight: number;
/** Resolves when `inFlight` reaches 0, or after `timeout` ms (returns false then). */
…interface HttpKernel {
/** For Node-based drivers. Never rejects: errors become Problem Details responses. */
handleNode(req: IncomingMessage, res: ServerResponse): Promise<void>;
/** For Fetch API drivers and tests. Never rejects. */
fetch(request: Request, options?: FetchOptions): Promise<Response>;
/** For WebSocket upgrades; emits `http:upgrade`. Without a listener the socket gets 426 and is destroyed. */
handleUpgrade(req: IncomingMessage, socket: Duplex, head: Buffer): void;
/** Requests currently being handled. */
readonly inFlight: number;
/** Resolves when `inFlight` reaches 0, or after `timeout` ms (returns false then). */
drain(timeout: number): Promise<boolean>;
/** After this, new requests get 503 with `Connection: close`. */
stopAccepting(): void;
}
Exported from packages/http/src/contracts.ts
HttpRequestTraceContext
Interface
The object passed to `tracePromise` for `samveys:http.request`.
interface HttpRequestTraceContext {
readonly request: Request;
readonly ctx: HttpContext;
readonly span: HttpSpanInfo;
}
Exported from packages/http/src/contracts.ts
HttpServer
Interface
No documentation comment.
interface HttpServer {
readonly kernel: HttpKernel;
readonly driver: HttpDriver;
/** Starts the driver on the configured host and port and wires WebSocket upgrades. */
listen(): Promise<AddressInfo>;
/** Stops accepting, waits up to `timeout` ms for in-flight requests, then closes the driver. Safe to call twice. */
close(timeout?: number): Promise<void>;
}
Exported from packages/http/src/plugin.ts
HttpSpanInfo
Interface
OpenTelemetry semantic-convention attributes for the server span. An APM subscriber reads `context.span` on `tracing:samveys:http.request:asyncEnd` (or `end`) and needs no Samveys import.
interface HttpSpanInfo {
/** `{method} {http.route}` once a route matched (`GET /users/:id`), otherwise just `{method}`. Never the raw path. */
name: string;
readonly kind: 'server';
attributes: {
'http.request.method': string;
/** The route pattern; absent when no route matched. */
'http.route'?: string;
'url.path': string;
'url.scheme': string;
…
Show the whole declaration (17 lines)
interface HttpSpanInfo {
/** `{method} {http.route}` once a route matched (`GET /users/:id`), otherwise just `{method}`. Never the raw path. */
name: string;
readonly kind: 'server';
attributes: {
'http.request.method': string;
/** The route pattern; absent when no route matched. */
'http.route'?: string;
'url.path': string;
'url.scheme': string;
…interface HttpSpanInfo {
/** `{method} {http.route}` once a route matched (`GET /users/:id`), otherwise just `{method}`. Never the raw path. */
name: string;
readonly kind: 'server';
attributes: {
'http.request.method': string;
/** The route pattern; absent when no route matched. */
'http.route'?: string;
'url.path': string;
'url.scheme': string;
'http.response.status_code'?: number;
/** Set for 5xx only, e.g. `'500'`; 4xx and cancellations are not errors. */
'error.type'?: string;
};
/** `'error'` for 5xx, `'unset'` otherwise (4xx and client cancellation are not errors). */
status: 'unset' | 'error';
}
Exported from packages/http/src/contracts.ts
IdempotencyOptions
Interface
No documentation comment.
interface IdempotencyOptions {
/** How long a key and its response are kept. Default 24 h. */
readonly ttlMs?: number;
/** Require the header: a request without `Idempotency-Key` gets 400. Default false (runs normally). */
readonly required?: boolean;
/** Default: the `cache` container binding. */
readonly store?: IdempotencyStore;
/** Scopes keys, e.g. per user: `(ctx) => String(ctx.auth.user.id)`. Default: none. */
Exported from packages/http/src/contracts.ts
IdempotencyStore
Interface
The two operations idempotency needs; `@samveys/cache` stores satisfy it.
interface IdempotencyStore {
/** Stores `value` only when `key` is absent; true when stored. */
add(key: string, value: unknown, ttlMs: number): Promise<boolean>;
get(key: string): Promise<unknown>;
put(key: string, value: unknown, ttlMs: number): Promise<void>;
forget(key: string): Promise<boolean>;
}
Exported from packages/http/src/contracts.ts
ListenOptions
Interface
Locked public contracts of `@samveys/http` (design §7). Changing an exported type here changes the driver contract and needs an ADR.
interface ListenOptions {
readonly host: string;
readonly port: number;
/** Passed to the driver's server; forwarded to `node:http` options where they exist. */
readonly requestTimeout: number;
readonly headersTimeout: number;
readonly keepAliveTimeout: number;
}
Exported from packages/http/src/contracts.ts
NodeDriverOptions
Interface
No documentation comment.
interface NodeDriverOptions {
/** TLS material: serves `node:https`, or HTTP/2 when `http2` is true. */
readonly https?: {
readonly key: string | Buffer;
readonly cert: string | Buffer;
};
/** HTTP/2 over TLS with HTTP/1.1 fallback (`allowHTTP1`). Needs `https`. */
readonly http2?: boolean;
}
Exported from packages/http/src/driver.ts
ResponseHelpers
Interface
No documentation comment.
interface ResponseHelpers {
/** Headers merged into the final response (handler-set values win over defaults). */
readonly headers: Headers;
json(data: unknown, init?: ResponseInit): Response;
text(body: string, init?: ResponseInit): Response;
/** 201, optional `Location`. */
created(data?: unknown, location?: string): Response;
/** 204. */
noContent(): Response;
/**
…
Show the whole declaration (23 lines)
interface ResponseHelpers {
/** Headers merged into the final response (handler-set values win over defaults). */
readonly headers: Headers;
json(data: unknown, init?: ResponseInit): Response;
text(body: string, init?: ResponseInit): Response;
/** 201, optional `Location`. */
created(data?: unknown, location?: string): Response;
/** 204. */
noContent(): Response;
/**
…interface ResponseHelpers {
/** Headers merged into the final response (handler-set values win over defaults). */
readonly headers: Headers;
json(data: unknown, init?: ResponseInit): Response;
text(body: string, init?: ResponseInit): Response;
/** 201, optional `Location`. */
created(data?: unknown, location?: string): Response;
/** 204. */
noContent(): Response;
/**
* Default 302. Only paths starting with a single `/`, or absolute `http(s)://` URLs; anything else
* (`//host`, `/\host`, backslashes, `https:host`) throws a 400 `SVS_E047` "Unsafe redirect target".
*
* Warning: an absolute URL is accepted as is. When it comes from user input (a `?next=` parameter),
* the caller must check it against an allow-list of hosts first, or the route is an open redirect.
*/
redirect(location: string, status?: 301 | 302 | 303 | 307 | 308): Response;
/** Streams without buffering; never compressed when `contentType` is `text/event-stream`. */
stream(body: ReadableStream<Uint8Array> | AsyncIterable<Uint8Array | string>, init?: ResponseInit & {
readonly contentType?: string;
}): Response;
problem(problem: ProblemDetails, init?: ResponseInit): Response;
}
Exported from packages/http/src/contracts.ts
RouteBuilder
Interface
No documentation comment.
interface RouteBuilder<M extends HttpMethod> {
<const P extends string>(path: P, handler: Handler<P, {}>): RouteDefinition<P, {}> & {
readonly method: M;
};
<const P extends string, const S extends RouteOptions>(path: P, options: S, handler: Handler<P, S>): RouteDefinition<P, S> & {
readonly method: M;
};
}
Exported from packages/http/src/contracts.ts
RouteDefinition
Interface
Produced by `get()`, `post()`, … Not yet mounted: a controller or router gives it a full path and name.
interface RouteDefinition<P extends string = string, S extends RouteSchemas = RouteSchemas> {
readonly kind: 'route';
readonly method: HttpMethod;
readonly path: P;
readonly options: RouteOptions & S;
readonly handler: Handler<P, S>;
}
Exported from packages/http/src/contracts.ts
RouteDeprecation
Interface
No documentation comment.
interface RouteDeprecation {
/** When the route became deprecated. */
readonly at: Date | Temporal.Instant | string;
/** When the route stops working. */
readonly sunset?: Date | Temporal.Instant | string;
/** A page describing the replacement. */
readonly link?: string;
}
Exported from packages/http/src/contracts.ts
RouteDescription
Interface
A route with its schemas, for tools that describe the API (OpenAPI, typed clients).
interface RouteDescription {
readonly entry: RouteEntry;
readonly method: HttpMethod;
readonly schemas: {
readonly params?: StandardSchemaV1;
readonly query?: StandardSchemaV1;
readonly body?: StandardSchemaV1;
readonly response?: StandardSchemaV1;
};
readonly deprecated: boolean;
}
Exported from packages/http/src/describe.ts
RouteEntry
Interface
A mounted route, as shown by `svs route:list`.
interface RouteEntry {
/** `controller.key`, the `name` option, or `undefined` for anonymous router routes. */
readonly name: string | undefined;
readonly method: HttpMethod;
/** Full pattern including controller and group prefixes, e.g. `/users/:id`. */
readonly pattern: string;
/** Param names in pattern order; an optional `:id?` is listed as `id?`, a wildcard `*` as `wildcard`. */
readonly params: readonly string[];
readonly middleware: readonly string[];
readonly plugins: readonly string[];
…
Show the whole declaration (17 lines)
interface RouteEntry {
/** `controller.key`, the `name` option, or `undefined` for anonymous router routes. */
readonly name: string | undefined;
readonly method: HttpMethod;
/** Full pattern including controller and group prefixes, e.g. `/users/:id`. */
readonly pattern: string;
/** Param names in pattern order; an optional `:id?` is listed as `id?`, a wildcard `*` as `wildcard`. */
readonly params: readonly string[];
readonly middleware: readonly string[];
readonly plugins: readonly string[];
…interface RouteEntry {
/** `controller.key`, the `name` option, or `undefined` for anonymous router routes. */
readonly name: string | undefined;
readonly method: HttpMethod;
/** Full pattern including controller and group prefixes, e.g. `/users/:id`. */
readonly pattern: string;
/** Param names in pattern order; an optional `:id?` is listed as `id?`, a wildcard `*` as `wildcard`. */
readonly params: readonly string[];
readonly middleware: readonly string[];
readonly plugins: readonly string[];
readonly hasSchemas: {
readonly params: boolean;
readonly query: boolean;
readonly body: boolean;
readonly response: boolean;
};
}
Exported from packages/http/src/contracts.ts
RouteFile
Interface
Default export of a route file.
interface RouteFile {
readonly kind: 'routes';
register(router: Router): void;
}
Exported from packages/http/src/contracts.ts
RouteOptions
Interface
No documentation comment.
interface RouteOptions extends RouteSchemas {
/** Overrides the automatic `controller.key` name. */
readonly name?: string;
readonly use?: readonly MiddlewareRef[];
/** Per-route body limit in bytes. */
readonly bodyLimit?: number;
/** Per-route handler timeout in ms. */
readonly timeout?: number;
/**
* Marks the route deprecated (RFC 9745 / RFC 8594): every response carries
…
Show the whole declaration (20 lines)
interface RouteOptions extends RouteSchemas {
/** Overrides the automatic `controller.key` name. */
readonly name?: string;
readonly use?: readonly MiddlewareRef[];
/** Per-route body limit in bytes. */
readonly bodyLimit?: number;
/** Per-route handler timeout in ms. */
readonly timeout?: number;
/**
* Marks the route deprecated (RFC 9745 / RFC 8594): every response carries
…interface RouteOptions extends RouteSchemas {
/** Overrides the automatic `controller.key` name. */
readonly name?: string;
readonly use?: readonly MiddlewareRef[];
/** Per-route body limit in bytes. */
readonly bodyLimit?: number;
/** Per-route handler timeout in ms. */
readonly timeout?: number;
/**
* Marks the route deprecated (RFC 9745 / RFC 8594): every response carries
* `Deprecation: @<at>`, `Sunset: <HTTP date>` and `Link: <link>; rel="deprecation"`. Boot fails
* when `sunset` is before `at`.
*/
readonly deprecated?: RouteDeprecation;
/**
* @experimental Replays the stored response for a repeated `Idempotency-Key`. Needs a
* store: pass one, or register a `cache` binding (`@samveys/cache`). `true` uses a 24 h TTL.
*/
readonly idempotent?: boolean | IdempotencyOptions;
}
Exported from packages/http/src/contracts.ts
Router
Interface
No documentation comment.
interface Router {
get<const P extends string>(path: P, handler: Handler<P, {}>): void;
get<const P extends string, const S extends RouteOptions>(path: P, options: S, handler: Handler<P, S>): void;
post<const P extends string>(path: P, handler: Handler<P, {}>): void;
post<const P extends string, const S extends RouteOptions>(path: P, options: S, handler: Handler<P, S>): void;
put<const P extends string>(path: P, handler: Handler<P, {}>): void;
put<const P extends string, const S extends RouteOptions>(path: P, options: S, handler: Handler<P, S>): void;
patch<const P extends string>(path: P, handler: Handler<P, {}>): void;
patch<const P extends string, const S extends RouteOptions>(path: P, options: S, handler: Handler<P, S>): void;
delete<const P extends string>(path: P, handler: Handler<P, {}>): void;
…
Show the whole declaration (15 lines)
interface Router {
get<const P extends string>(path: P, handler: Handler<P, {}>): void;
get<const P extends string, const S extends RouteOptions>(path: P, options: S, handler: Handler<P, S>): void;
post<const P extends string>(path: P, handler: Handler<P, {}>): void;
post<const P extends string, const S extends RouteOptions>(path: P, options: S, handler: Handler<P, S>): void;
put<const P extends string>(path: P, handler: Handler<P, {}>): void;
put<const P extends string, const S extends RouteOptions>(path: P, options: S, handler: Handler<P, S>): void;
patch<const P extends string>(path: P, handler: Handler<P, {}>): void;
patch<const P extends string, const S extends RouteOptions>(path: P, options: S, handler: Handler<P, S>): void;
delete<const P extends string>(path: P, handler: Handler<P, {}>): void;
…interface Router {
get<const P extends string>(path: P, handler: Handler<P, {}>): void;
get<const P extends string, const S extends RouteOptions>(path: P, options: S, handler: Handler<P, S>): void;
post<const P extends string>(path: P, handler: Handler<P, {}>): void;
post<const P extends string, const S extends RouteOptions>(path: P, options: S, handler: Handler<P, S>): void;
put<const P extends string>(path: P, handler: Handler<P, {}>): void;
put<const P extends string, const S extends RouteOptions>(path: P, options: S, handler: Handler<P, S>): void;
patch<const P extends string>(path: P, handler: Handler<P, {}>): void;
patch<const P extends string, const S extends RouteOptions>(path: P, options: S, handler: Handler<P, S>): void;
delete<const P extends string>(path: P, handler: Handler<P, {}>): void;
delete<const P extends string, const S extends RouteOptions>(path: P, options: S, handler: Handler<P, S>): void;
/** Mount a route definition built with `get()`, `post()`, … */
add(route: RouteDefinition<any, any>): void;
controller(controller: Controller): void;
group(options: GroupOptions, register: (router: Router) => void): void;
Exported from packages/http/src/contracts.ts
RouteRegistry
Interface
No documentation comment.
interface RouteRegistry {
}
Exported from packages/http/src/contracts.ts
RouteSchemas
Interface
No documentation comment.
interface RouteSchemas {
readonly params?: StandardSchemaV1;
readonly query?: StandardSchemaV1;
readonly body?: StandardSchemaV1;
/** Output is what is sent: fields not in the schema are dropped. */
readonly response?: StandardSchemaV1;
}
Exported from packages/http/src/contracts.ts
SecurityHeadersOptions
Interface
No documentation comment.
interface SecurityHeadersOptions {
/** `false` disables. Default `max-age=31536000; includeSubDomains`. Sent only over HTTPS or when `trustProxy` reports https. */
readonly hsts?: string | false;
/** `false` disables. Default `default-src 'self'; frame-ancestors 'none'; base-uri 'self'; object-src 'none'`. */
readonly contentSecurityPolicy?: string | false;
/** Default `DENY`. */
readonly frameOptions?: 'DENY' | 'SAMEORIGIN' | false;
/** Default `no-referrer`. */
readonly referrerPolicy?: string | false;
}
Exported from packages/http/src/contracts.ts
ServerConfig
Interface
No documentation comment.
interface ServerConfig {
/** Default `node()`. */
readonly driver?: HttpDriver;
/** Default `0.0.0.0`. */
readonly host?: string;
/** Default 3333. */
readonly port?: number;
/** Handler timeout in ms; aborts `ctx.signal` and returns 503 (SVS_E044). Default 30000. */
readonly requestTimeout?: number;
/** Default 10000. */
…
Show the whole declaration (24 lines)
interface ServerConfig {
/** Default `node()`. */
readonly driver?: HttpDriver;
/** Default `0.0.0.0`. */
readonly host?: string;
/** Default 3333. */
readonly port?: number;
/** Handler timeout in ms; aborts `ctx.signal` and returns 503 (SVS_E044). Default 30000. */
readonly requestTimeout?: number;
/** Default 10000. */
…interface ServerConfig {
/** Default `node()`. */
readonly driver?: HttpDriver;
/** Default `0.0.0.0`. */
readonly host?: string;
/** Default 3333. */
readonly port?: number;
/** Handler timeout in ms; aborts `ctx.signal` and returns 503 (SVS_E044). Default 30000. */
readonly requestTimeout?: number;
/** Default 10000. */
readonly headersTimeout?: number;
/** Default 5000. */
readonly keepAliveTimeout?: number;
/** Max body bytes for JSON, form and text bodies. Default 1_048_576. */
readonly bodyLimit?: number;
readonly securityHeaders?: SecurityHeadersOptions;
/**
* Request header prefixes stripped before routing (CVE-2025-29927 lesson).
* Default `['x-samveys-']`. `x-middleware-subrequest` is always stripped.
*/
readonly internalHeaderPrefixes?: readonly string[];
/** Trust `X-Forwarded-*` from these proxy addresses. Default none. */
readonly trustProxy?: readonly string[] | boolean;
/** Route files to load: `() => import('#routes/api.ts')`, each exporting `defineRoutes(...)`. */
Exported from packages/http/src/contracts.ts
SseEvent
Interface
No documentation comment.
interface SseEvent {
readonly id?: string | number;
readonly event?: string;
/** Strings are sent as-is (split on newlines); other values as JSON. */
readonly data: unknown;
/** Reconnection delay for the client, in ms. */
readonly retry?: number;
}
Exported from packages/http/src/sse.ts
SseOptions
Interface
No documentation comment.
interface SseOptions {
/** A `: ping` comment line every so often keeps proxies from closing idle streams. Default 15 000. */
readonly keepAliveMs?: number;
/** Sent once at the start as `retry:`. */
readonly retryMs?: number;
}
Exported from packages/http/src/sse.ts
ValidatorAdapter
Interface
No documentation comment.
interface ValidatorAdapter {
/** True when this adapter handles `schema`. */
accepts(schema: unknown): boolean;
toStandard(schema: unknown): StandardSchemaV1;
}
Exported from packages/http/src/contracts.ts
WebSocketConnection
Interface
No documentation comment.
interface WebSocketConnection {
readonly id: string;
/** The negotiated subprotocol, if any. */
readonly protocol: string | undefined;
/** Per-connection scratch space (user id, joined channels). */
readonly data: Map<string, unknown>;
/** Strings go as text frames, bytes as binary, anything else as JSON text. */
send(message: string | Uint8Array | object): void;
close(code?: number, reason?: string): void;
readonly closed: boolean;
}
Exported from packages/http/src/websocket.ts
WebSocketHandlers
Interface
No documentation comment.
interface WebSocketHandlers<M = string | Uint8Array> {
open?(ws: WebSocketConnection, request: IncomingMessage): void | Promise<void>;
/** With a `schema`, `data` is the validated JSON value; an invalid message closes with 1008. */
message?(ws: WebSocketConnection, data: M): void | Promise<void>;
close?(ws: WebSocketConnection, code: number, reason: string): void | Promise<void>;
}
Exported from packages/http/src/websocket.ts
WebSocketRoute
Interface
No documentation comment.
interface WebSocketRoute {
readonly path: string;
readonly options: WebSocketRouteOptions;
readonly handlers: WebSocketHandlers<unknown>;
}
Exported from packages/http/src/websocket.ts
WebSocketRouteOptions
Interface
No documentation comment.
interface WebSocketRouteOptions {
/** Allowed `Origin` values. Required: browsers send it, and a missing check allows cross-site hijacking. Use `['*']` only for non-browser clients. */
readonly origins: readonly string[];
/** Runs before the handshake; return false (or throw) to answer 401. */
readonly auth?: (request: IncomingMessage) => boolean | Promise<boolean>;
Exported from packages/http/src/websocket.ts
WebSocketsOptions
Interface
No documentation comment.
interface WebSocketsOptions {
/** Routes by exact path. */
readonly routes: readonly WebSocketRoute[];
/** How long shutdown waits for close handshakes. Default 5000 ms. */
readonly shutdownTimeoutMs?: number;
}
Exported from packages/http/src/ws-plugin.ts
Type (17)
CompressionEncoding
Type
No documentation comment.
type CompressionEncoding = 'zstd' | 'br' | 'gzip';
Exported from packages/http/src/contracts.ts
GroupPluginRef
Type
Which plugins a route group enables for itself. Plugins must be registered with `scope: 'routes'`.
type GroupPluginRef = string | {
readonly pluginName: string;
} | {
readonly kind: 'plugin';
readonly name: string;
};
Exported from packages/http/src/contracts.ts
Handler
Type
No documentation comment.
type Handler<P extends string, S extends RouteSchemas> = (ctx: HandlerContext<P, S>) => HandlerReturn<S> | Promise<HandlerReturn<S>>;
Exported from packages/http/src/contracts.ts
HandlerContext
Type
What a handler receives: the HTTP context with params, query and body narrowed per route.
type HandlerContext<P extends string, S extends RouteSchemas> = Omit<HttpContext, 'params' | 'query' | 'body'> & {
/** Prefix params of a controller are present at runtime; only the route's own pattern is typed. */
readonly params: OutputOr<S['params'], PathParams<P>>;
readonly query: OutputOr<S['query'], QueryValues>;
readonly body: OutputOr<S['body'], undefined>;
readonly response: ResponseHelpers;
};
Exported from packages/http/src/contracts.ts
HandlerReturn
Type
Return a `Response`, a string (text/plain), `undefined` (204), or JSON-serializable data. With a `response` schema, data must match the schema input; extra fields are stripped.
type HandlerReturn<S extends RouteSchemas> = Response | (S['response'] extends StandardSchemaV1 ? InputOr<S['response'], unknown> : unknown);
Exported from packages/http/src/contracts.ts
HttpMethod
Type
No documentation comment.
type HttpMethod = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS';
Exported from packages/http/src/contracts.ts
Middleware
Type
No documentation comment.
type Middleware = (ctx: HttpContext, next: Next) => Response | Promise<Response>;
Exported from packages/http/src/contracts.ts
MiddlewareRef
Type
A middleware function, or the name given to `extend.middleware(name, …)`.
type MiddlewareRef = Middleware | string;
Exported from packages/http/src/contracts.ts
Next
Type
No documentation comment.
type Next = () => Promise<Response>;
Exported from packages/http/src/contracts.ts
NodeServer
Type
No documentation comment.
type NodeServer = HttpServer | HttpsServer | Http2SecureServer;
Exported from packages/http/src/driver.ts
PathParams
Type
Params derived from a pattern. Allowed segments: literals, `:name`, `:name?`, and a final `*` or `*name`. Free-form regex is rejected at boot (SVS_E045).
type PathParams<P extends string> = Simplify<SplitParams<P>>;
Exported from packages/http/src/contracts.ts
QueryValues
Type
No documentation comment.
type QueryValues = Readonly<Record<string, string | string[]>>;
Exported from packages/http/src/contracts.ts
ResolvedServerConfig
Type
Resolved values with defaults applied.
type ResolvedServerConfig = Required<Omit<ServerConfig, 'securityHeaders' | 'trustProxy' | 'compression'>> & {
readonly securityHeaders: Required<SecurityHeadersOptions>;
readonly trustProxy: readonly string[] | boolean;
readonly compression: Required<CompressionOptions> | false;
};
Exported from packages/http/src/contracts.ts
RouteName
Type
No documentation comment.
type RouteName = [keyof RouteRegistry] extends [never] ? string : keyof RouteRegistry & string;
Exported from packages/http/src/contracts.ts
RouteParamsArg
Type
No documentation comment.
type RouteParamsArg<N extends string> = N extends keyof RouteRegistry ? {} extends RouteRegistry[N] ? [params?: RouteRegistry[N] & {
readonly [key: string]: string | number | undefined;
}] : [params: RouteRegistry[N] & {
readonly [key: string]: string | number | undefined;
}] : [params?: Readonly<Record<string, string | number>>];
Exported from packages/http/src/contracts.ts
SseSource
Type
No documentation comment.
type SseSource = (context: {
readonly lastEventId: string | undefined;
readonly signal: AbortSignal;
}) => AsyncIterable<SseEvent>;
Exported from packages/http/src/sse.ts
WebSocketServer
Type
No documentation comment.
type WebSocketServer = ReturnType<typeof createWebSocketServer>;
Exported from packages/http/src/websocket.ts