UNPKG

@beignet/core

Version:

Core framework primitives for Beignet

75 lines 4.18 kB
import type { HttpContractConfig } from "../contracts/index.js"; import { type MemoInstrumentationEvent } from "../memo/index.js"; import type { AnyPorts } from "../ports/index.js"; import type { ContextSeed } from "./context.js"; import type { Handler, HttpRequestLike, HttpResponse, RouteHook, ServerCaughtErrorHook, ServerHook, ServerUnhandledErrorMapper } from "./http.js"; import type { ServerInstrumentationOptions } from "./instrumentation.js"; import { type RequestBodyOptions } from "./request-preparation.js"; import { type CompiledPath } from "./route-matching.js"; import type { TrustedRequestInfo } from "./trusted-proxy.js"; type RequestExecutorOptions<Ctx> = { instrumentation?: ServerInstrumentationOptions<Ctx> | false; validateResponses?: boolean; requestBody?: RequestBodyOptions; onCaughtError?: ServerCaughtErrorHook<Ctx>; mapUnhandledError?: ServerUnhandledErrorMapper<Ctx>; }; type ExecutionTarget<Ctx, C extends HttpContractConfig> = { contract: C; /** * Compiled route pattern. Only required when the executor is invoked * without pre-matched params. */ compiled?: CompiledPath; handler: Handler<Ctx, C>; /** * Success status whose response schema validation is skipped because the * use case bound to this route already validated its output against the * same schema object. */ responseValidationExemptStatus?: number; }; /** * Build the per-request execution pipeline once. * * The returned executor takes the contract, compiled pattern, and user handler * per invocation so fallback responses (404/405) can reuse a single pipeline * across requests instead of rebuilding it per unmatched request. */ export declare function createRequestExecutor<Ctx, FinalPorts extends AnyPorts, C extends HttpContractConfig>(options: RequestExecutorOptions<Ctx>, finalPorts: FinalPorts, contextRuntime: { createRequestContext: (req: HttpRequestLike, contract: HttpContractConfig, requestInfo: TrustedRequestInfo) => Promise<Ctx>; finalizeContext: (seed: ContextSeed<Ctx> | Ctx) => Ctx; resolveRequestInfo: (req: HttpRequestLike) => TrustedRequestInfo; }, hooks: ServerHook<Ctx, FinalPorts>[], routeHooks?: readonly RouteHook<unknown, object>[], optionsOverrides?: { skipRoutePreparation?: boolean; /** * Run the route through the full hook pipeline without contract * preparation: no query/path/header/body parsing or validation, and the * request body is left unconsumed for the handler. */ rawRoute?: boolean; }): (target: ExecutionTarget<Ctx, C>, req: HttpRequestLike, preMatchedParams?: Record<string, string>) => Promise<HttpResponse>; /** * Build a memo instrumentation recorder from the app ports, or undefined when * no instrumentation sink is wired. * * Resolved per execution rather than at route-build time because providers * contribute `ports.instrumentation`/`ports.devtools` during setup, after * routes are registered. */ export declare function createMemoScopeRecorder(ports: AnyPorts): ((event: MemoInstrumentationEvent) => void) | undefined; export declare function buildHandler<Ctx, FinalPorts extends AnyPorts, C extends HttpContractConfig>(options: RequestExecutorOptions<Ctx>, finalPorts: FinalPorts, contextRuntime: { createRequestContext: (req: HttpRequestLike, contract: HttpContractConfig, requestInfo: TrustedRequestInfo) => Promise<Ctx>; finalizeContext: (seed: ContextSeed<Ctx> | Ctx) => Ctx; resolveRequestInfo: (req: HttpRequestLike) => TrustedRequestInfo; }, contract: C, userHandler: Handler<Ctx, C>, hooks: ServerHook<Ctx, FinalPorts>[], routeHooks?: readonly RouteHook<unknown, object>[], optionsOverrides?: { skipRoutePreparation?: boolean; /** * Run the route through the full hook pipeline without contract * preparation: no query/path/header/body parsing or validation, and the * request body is left unconsumed for the handler. */ rawRoute?: boolean; }, responseValidationExemptStatus?: number): (req: HttpRequestLike, preMatchedParams?: Record<string, string>) => Promise<HttpResponse>; export {}; //# sourceMappingURL=request-executor.d.ts.map