import { AddressInfo } from "node:net"; import { IncomingMessage, Server, ServerResponse } from "node:http"; import { PerMessageDeflateOptions } from "ws"; import { ServerApp } from "@askrjs/server"; //#region src/client-address.d.ts /** * Reserved request header containing the TCP peer address authenticated by the Node adapter. * Any value supplied by the HTTP client is overwritten before application dispatch. */ export declare const CLIENT_ADDRESS_HEADER = "x-askr-client-address"; /** Normalizes the socket peer address used for the adapter-authenticated request header. */ export declare function normalizeClientAddress(address: string | undefined): string; //#endregion //#region src/contracts.d.ts /** Options controlling how WebSocket upgrades are handled on a Node server. */ export interface NodeWebSocketOptions { /** Milliseconds to wait for a peer to acknowledge a close handshake before the socket is force-closed. */ readonly closeTimeout?: number; /** Maximum allowed size, in bytes, of a single WebSocket message. */ readonly maxPayload?: number; /** Maximum number of body bytes read from a rejected upgrade request before the connection is destroyed. */ readonly maxRejectionBodyBytes?: number; /** Enables or configures the permessage-deflate WebSocket extension. */ readonly perMessageDeflate?: boolean | PerMessageDeflateOptions; /** Origins allowed to open a WebSocket connection; when omitted, all origins are allowed. */ readonly allowedOrigins?: readonly string[]; } /** Options shared by anything that turns Node HTTP requests into `@askrjs/server` fetch calls. */ export interface NodeHandlerOptions { /** Base URL used to resolve request paths into absolute URLs. */ readonly baseUrl?: string; /** Hosts allowed in the request's `Host` header; requests for other hosts are rejected. */ readonly allowedHosts?: readonly string[]; } /** Options for {@link listen}, controlling how the Node HTTP server binds and behaves. */ export interface ListenOptions extends NodeHandlerOptions { /** Port to listen on; defaults to an ephemeral port when omitted. */ port?: number; /** Host/address to bind to. */ host?: string; /** Allows binding to a non-loopback host without the usual safety check. */ allowPublicBind?: boolean; /** Maximum length of the queue of pending connections. */ backlog?: number; /** Aborting this signal stops the server. */ signal?: AbortSignal; /** Node HTTP server `requestTimeout`, enforced from server construction, in milliseconds. */ requestTimeout?: number; /** Node HTTP server `headersTimeout`, enforced from server construction, in milliseconds. */ headersTimeout?: number; /** Node HTTP server `keepAliveTimeout`, in milliseconds. */ keepAliveTimeout?: number; /** Enables WebSocket support, optionally with detailed options. */ websocket?: boolean | NodeWebSocketOptions; } /** Options for {@link serve}, extending {@link ListenOptions} with static asset serving and shutdown behavior. */ export interface ServeOptions extends ListenOptions { /** Serves static files from this directory before falling back to the application. */ readonly assets?: { readonly root: string; /** Returns true when an extension-bearing path must bypass static serving. */ readonly exclude?: (pathname: string) => boolean; }; /** OS signals that trigger a graceful shutdown; pass `false` to disable automatic shutdown handling. */ readonly signals?: false | readonly NodeJS.Signals[]; } /** A running application returned by {@link serve}. */ export interface ServedApplication { /** The underlying Node HTTP server. */ readonly server: import("node:http").Server; /** The base URL the server is listening on. */ readonly url: string; /** Gracefully shuts down the server, any WebSocket connections, and the application. */ close(): Promise; } /** Connect/Express-style `next` callback used to hand off unhandled requests. */ export type ConnectNext = (error?: unknown) => void; /** A Node-style request handler compatible with `http.Server` and Connect-style middleware chains. */ export type NodeHandler = (request: IncomingMessage, response: ServerResponse, next?: ConnectNext) => void; //#endregion //#region src/handler.d.ts /** * Wraps an `@askrjs/server` application as a Node-style request handler. * * Converts each incoming `IncomingMessage`/`ServerResponse` pair into a web * `Request`, dispatches it through `app.fetch`, and writes the resulting web * `Response` back to Node. Errors are reported to `next` when provided, * otherwise a minimal 400/500 response is written directly. * * @param app - The application to dispatch requests to. * @param options - Options controlling base URL resolution and host validation. * @returns A handler usable with `http.createServer` or Connect-style middleware. */ export declare function createNodeHandler(app: ServerApp, options: NodeHandlerOptions): NodeHandler; //#endregion //#region src/listen.d.ts /** A Node HTTP server that is guaranteed to be listening for connections. */ export type ListeningServer = Server & { address(): AddressInfo | string | null; }; /** * Starts a Node HTTP server for an `@askrjs/server` application and resolves once it is listening. * * Optionally installs WebSocket support and wires up graceful shutdown on * `options.signal`. Unlike {@link serve}, this does not serve static assets * or install OS signal handlers. * * @param app - The application to serve. * @param options - Listen options such as port, host, timeouts, and WebSocket support. * @returns A promise resolving to the listening server once it has bound successfully. * @example * const server = await listen(app, { port: 3000 }); */ export declare function listen(app: ServerApp, options?: ListenOptions): Promise; //#endregion //#region src/serve.d.ts /** * Serves an `@askrjs/server` application over Node HTTP, with optional static * asset serving, WebSocket support, and graceful shutdown on OS signals or an * abort signal. * * Requests for paths with a file extension are first checked against * `options.assets.root` (path-traversal safe, following symlinks) and served * directly with appropriate `content-type`/`cache-control` headers before * falling back to the application handler. HTML responses from the * application get a `no-cache` header when they don't already set * `cache-control`. * * @param app - The application to serve; may expose an optional `close()` for cleanup. * @param options - Serve options such as port, host, static assets, and shutdown signals. * @returns The served application, including its bound `url` and a `close()` for shutdown. * @example * const app = await serve(myApp, { port: 3000, assets: { root: "./public" } }); * // ... * await app.close(); */ export declare function serve(app: ServerApp & { close?: () => void | Promise; }, options?: ServeOptions): Promise; //#endregion