import type { IncomingHttpHeaders } from "node:http"; import type { RequestAttribution } from "@velum-labs/routekit-contracts"; import type { RouteKitPlatform } from "@velum-labs/routekit-runtime/effect"; import { type Context, Effect } from "effect"; import type { BackendRequest, BackendRequestOptions } from "../providers/backend.js"; import type { GatewayDialect } from "../observability/provenance.js"; export type EndpointContext = Readonly<{ method: string; url: URL; headers: IncomingHttpHeaders; transport: EndpointTransport; platform?: Context.Context; }>; export declare function withEndpointPlatform(context: EndpointContext, options: BackendRequestOptions): BackendRequestOptions; export type EndpointTransport = Readonly<{ readJson(): Effect.Effect; writeJson(status: number, value: unknown): void; setHeader(name: string, value: string): void; pipe(upstream: Response): void; dispatch(call: EndpointModelCall): void; }>; export type EndpointAuthenticator = (context: EndpointContext) => void; export type EndpointObserver = (endpoint: string, operation: string, context: EndpointContext) => void; export declare class EndpointAuthenticationError extends Error { constructor(); } export type EndpointModelCall = Readonly<{ dialect: GatewayDialect; body: unknown; defaultModel: string | undefined; attribution?: Partial; invoke: (callId: string, signal: AbortSignal, onAttribution: NonNullable) => BackendRequest; }>; export type EndpointProgram = Effect.Effect; /** * Base for concrete endpoint modules. Node HTTP is adapted once at the server * boundary; endpoint logic sees only transport-neutral headers, URL metadata, * request decoding, response encoding, upstream piping, and model dispatch. */ export declare abstract class GatewayEndpoint { readonly name: string; private readonly authenticateRequest; private readonly executeOperation; private readonly observer?; constructor(name: string, authenticateRequest: EndpointAuthenticator, executeOperation: (context: EndpointContext, operation: Operation) => EndpointProgram, observer?: EndpointObserver | undefined); abstract matches(method: string, path: string): boolean; protected abstract decodeOperation(context: EndpointContext): Operation; handle(context: EndpointContext): EndpointProgram; }