import type { ContractLike, ResolveContract } from "./contract-like.js"; import type { AddedCtxFromHooks, Handler, RouteHook } from "./http.js"; import type { AnyUseCaseLike, AnyUseCaseRouteDef, UseCaseRouteDef, ValidatedRouteInputs } from "./use-case-route.js"; /** * Route registration that connects a contract to the handler implementing it. * * Most apps keep route definitions in `features//routes.ts` and * compose them with `defineRoutes(...)`. */ export type HandlerRouteDef[] = readonly RouteHook[]> = { /** * Contract builder or plain contract config for this route. */ contract: CLike; /** * Route-scoped hooks that run after group hooks and before the handler. */ hooks?: Hooks; /** * Handler that implements the contract. */ handle: Handler, ResolveContract>; useCase?: never; input?: never; status?: never; }; /** * Route registration for one contract. * * Routes either bind the contract directly to a use case (`{ contract, * useCase }`) or implement a full handler (`{ contract, handle }`). The full * handler form is the escape hatch for response headers, streaming, native * `Response` values, and multi-status handling. */ export type RouteDef[] = readonly RouteHook[]> = HandlerRouteDef | AnyUseCaseRouteDef; type AnyRouteDef = RouteDef; type PlainRouteDef = RouteDef; type AnyContractRouteDef = RouteDef; declare const ROUTE_GROUP_KIND = "beignet.route-group"; /** * Named collection of related route registrations. * * Route groups colocate feature routes and can apply scoped route hooks to * every route in the group. `defineRoutes(...)` flattens them before server * registration while preserving those hooks. */ export type RouteGroup = { /** * Internal marker used by `defineRoutes(...)`. */ kind: typeof ROUTE_GROUP_KIND; /** * Human-readable group name. */ name: string; /** * Hooks applied to every route in this group. */ hooks?: readonly RouteHook[]; /** * Route definitions in this group. */ routes: Routes; }; type RouteInput = AnyContractRouteDef | AnyRouteDef | RouteGroup; type ContextualRouteInput = PlainRouteDef | RouteGroup; /** * App-bound builder for one route registration. */ export type RouteDefinitionBuilder = { [] = readonly []>(route: UseCaseRouteDef): UseCaseRouteDef; [] = readonly []>(route: HandlerRouteDef): HandlerRouteDef; }; /** * App-bound builder for a named route group. */ export type RouteGroupBuilder = { [] = readonly [], const R extends readonly PlainRouteDef>[] = readonly PlainRouteDef>[]>(group: { name: string; hooks?: GroupHooks; routes: R & ValidatedRouteInputs, R>; }): RouteGroup; [] = readonly [], const R extends readonly AnyRouteDef[] = readonly AnyRouteDef[]>(group: { name: string; hooks?: GroupHooks; routes: R & ValidatedRouteInputs, R>; }): RouteGroup; }; /** * Route declaration builders bound to an application context type. */ export interface Routes { /** Define one route registration. */ defineRoute: RouteDefinitionBuilder; /** Define a named group of related route registrations. */ defineRouteGroup: RouteGroupBuilder; } type RoutesFromInput = Input extends RouteGroup ? Routes : Input extends AnyRouteDef ? readonly [Input] : readonly []; type FlattenRouteInputs = number extends Inputs["length"] ? readonly AnyRouteDef[] : Inputs extends readonly [infer First, ...infer Rest] ? readonly [...RoutesFromInput, ...FlattenRouteInputs] : readonly []; type ContractsFromRouteList[]> = { readonly [Index in keyof Routes]: Routes[Index] extends RouteDef ? ResolveContract : never; }; /** * Define and flatten route registrations with strong type inference. * * Pass route definitions and route groups here before `createServer(...)`. * Group entries are flattened so downstream tooling receives one route list. * * @example * ```ts * const routes = defineRoutes([ * { contract: listPosts, useCase: listPostsUseCase }, * ]); * ``` */ export declare function defineRoutes[] = readonly ContextualRouteInput[]>(routes: R & ValidatedRouteInputs): FlattenRouteInputs; export declare function defineRoutes[] = readonly RouteInput[]>(routes: R & ValidatedRouteInputs): FlattenRouteInputs; /** * Extract contract configs from a route list. * * Use this to drive clients, OpenAPI, and docs from the same route list passed * to `createServer(...)`. */ export declare function contractsFromRoutes[]>(routes: R): ContractsFromRouteList; /** * Create route declaration builders bound to an application context type. * * Call this once in `lib/routes.ts`, then import the app-bound builders from * feature route files. * * @example * ```ts * export const { defineRoute, defineRouteGroup } = * createRoutes(); * ``` */ export declare function createRoutes(): Routes; export {}; //# sourceMappingURL=route-definitions.d.ts.map