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/<feature>/routes.ts` and
 * compose them with `defineRoutes(...)`.
 */
export type HandlerRouteDef<Ctx, CLike extends ContractLike = ContractLike, Hooks extends readonly RouteHook<Ctx, object>[] = readonly RouteHook<Ctx, object>[]> = {
    /**
     * 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<Ctx & AddedCtxFromHooks<Hooks>, ResolveContract<CLike>>;
    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<Ctx, CLike extends ContractLike = ContractLike, Hooks extends readonly RouteHook<Ctx, object>[] = readonly RouteHook<Ctx, object>[]> = HandlerRouteDef<Ctx, CLike, Hooks> | AnyUseCaseRouteDef<Ctx, CLike, Hooks>;
type AnyRouteDef = RouteDef<any, any>;
type PlainRouteDef<Ctx> = RouteDef<Ctx, any, readonly []>;
type AnyContractRouteDef<Ctx> = RouteDef<Ctx, any>;
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<Ctx, Routes extends readonly AnyRouteDef[] = readonly AnyRouteDef[]> = {
    /**
     * 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<Ctx, object>[];
    /**
     * Route definitions in this group.
     */
    routes: Routes;
};
type RouteInput<Ctx> = AnyContractRouteDef<Ctx> | AnyRouteDef | RouteGroup<Ctx, readonly AnyRouteDef[]>;
type ContextualRouteInput<Ctx> = PlainRouteDef<Ctx> | RouteGroup<Ctx, readonly AnyRouteDef[]>;
/**
 * App-bound builder for one route registration.
 */
export type RouteDefinitionBuilder<Ctx> = {
    <CLike extends ContractLike, UC extends AnyUseCaseLike, const Hooks extends readonly RouteHook<Ctx, object>[] = readonly []>(route: UseCaseRouteDef<Ctx, CLike, UC, Hooks>): UseCaseRouteDef<Ctx, CLike, UC, Hooks>;
    <CLike extends ContractLike, const Hooks extends readonly RouteHook<Ctx, object>[] = readonly []>(route: HandlerRouteDef<Ctx, CLike, Hooks>): HandlerRouteDef<Ctx, CLike, Hooks>;
};
/**
 * App-bound builder for a named route group.
 */
export type RouteGroupBuilder<Ctx> = {
    <const GroupHooks extends readonly RouteHook<Ctx, object>[] = readonly [], const R extends readonly PlainRouteDef<Ctx & AddedCtxFromHooks<GroupHooks>>[] = readonly PlainRouteDef<Ctx & AddedCtxFromHooks<GroupHooks>>[]>(group: {
        name: string;
        hooks?: GroupHooks;
        routes: R & ValidatedRouteInputs<Ctx & AddedCtxFromHooks<GroupHooks>, R>;
    }): RouteGroup<Ctx, R>;
    <const GroupHooks extends readonly RouteHook<Ctx, object>[] = readonly [], const R extends readonly AnyRouteDef[] = readonly AnyRouteDef[]>(group: {
        name: string;
        hooks?: GroupHooks;
        routes: R & ValidatedRouteInputs<Ctx & AddedCtxFromHooks<GroupHooks>, R>;
    }): RouteGroup<Ctx, R>;
};
/**
 * Route declaration builders bound to an application context type.
 */
export interface Routes<Ctx> {
    /** Define one route registration. */
    defineRoute: RouteDefinitionBuilder<Ctx>;
    /** Define a named group of related route registrations. */
    defineRouteGroup: RouteGroupBuilder<Ctx>;
}
type RoutesFromInput<Input> = Input extends RouteGroup<infer _Ctx, infer Routes> ? Routes : Input extends AnyRouteDef ? readonly [Input] : readonly [];
type FlattenRouteInputs<Inputs extends readonly unknown[]> = number extends Inputs["length"] ? readonly AnyRouteDef[] : Inputs extends readonly [infer First, ...infer Rest] ? readonly [...RoutesFromInput<First>, ...FlattenRouteInputs<Rest>] : readonly [];
type ContractsFromRouteList<Routes extends readonly RouteDef<any, any>[]> = {
    readonly [Index in keyof Routes]: Routes[Index] extends RouteDef<any, infer CLike> ? ResolveContract<CLike> : 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<AppContext>([
 *   { contract: listPosts, useCase: listPostsUseCase },
 * ]);
 * ```
 */
export declare function defineRoutes<Ctx, const R extends readonly ContextualRouteInput<Ctx>[] = readonly ContextualRouteInput<Ctx>[]>(routes: R & ValidatedRouteInputs<Ctx, R>): FlattenRouteInputs<R>;
export declare function defineRoutes<Ctx, const R extends readonly RouteInput<Ctx>[] = readonly RouteInput<Ctx>[]>(routes: R & ValidatedRouteInputs<Ctx, R>): FlattenRouteInputs<R>;
/**
 * 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<const R extends readonly RouteDef<any, any>[]>(routes: R): ContractsFromRouteList<R>;
/**
 * 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<AppContext>();
 * ```
 */
export declare function createRoutes<Ctx>(): Routes<Ctx>;
export {};
//# sourceMappingURL=route-definitions.d.ts.map