import type { MatchParams } from '@remix-run/route-pattern/match'; import type { AnyMiddlewareChain, MiddlewareContext } from 'alien-middleware'; import type * as z from 'zod'; import { Promisable } from '../common.js'; import type { HttpAction } from '../http.js'; import type { InferRouteHandlerResult, InferResponseMapErrors, InferResponseMapSuccesses } from './response.js'; import type { RawBodySchema, RouteResponseMap, RouteSchema } from './schema.js'; type InferHandlerBody = T extends { body: infer TBody; } ? TBody extends RawBodySchema ? undefined : z.infer : undefined; type RequestContext = MiddlewareContext; /** * Error response returned by `ctx.error(status, body)` in route handlers. * * @remarks This is an opaque branded type returned by the error helper. Route * handlers may return it to signal a declared error response. */ export type RouteErrorResponse = Response & { __routeError__: true; }; /** Response returned by `ctx.success(status, body)` in route handlers. */ export type RouteSuccessResponse = Response & { __routeSuccess__: true; }; export type RouteRequestHandler = (context: RequestContext & TArgs & ([TErrors] extends [never] ? {} : { /** * Return a declared error response. * * @remarks Only statuses declared with `$error()` in the response * map are accepted. */ error: (...args: TEntry extends [infer S extends number, infer B] ? [status: S, body: B] : never) => RouteErrorResponse; }) & ([TSuccesses] extends [never] ? {} : { /** * Return a declared success response with an explicit status. * * @remarks Useful when a response map declares multiple 2xx statuses. */ success: (...args: TEntry extends [infer S extends number, infer B] ? [status: S, body: B] : never) => RouteSuccessResponse; })) => Promisable; export type InferActionHandler = TAction['schema'] extends { response: infer R extends RouteResponseMap; } ? TAction['method'] extends 'GET' ? RouteRequestHandler : MatchParams; query: TAction['schema'] extends { query: any; } ? z.infer : undefined; headers: TAction['schema'] extends { headers: any; } ? z.infer : undefined; }, InferRouteHandlerResult>, InferResponseMapErrors, InferResponseMapSuccesses> : RouteRequestHandler : MatchParams; body: InferHandlerBody; headers: TAction['schema'] extends { headers: any; } ? z.infer : undefined; }, InferRouteHandlerResult>, InferResponseMapErrors, InferResponseMapSuccesses> : TAction['method'] extends 'GET' ? RouteRequestHandler : MatchParams; query: TAction['schema'] extends { query: any; } ? z.infer : undefined; headers: TAction['schema'] extends { headers: any; } ? z.infer : undefined; }, InferRouteHandlerResult>> : RouteRequestHandler : MatchParams; body: InferHandlerBody; headers: TAction['schema'] extends { headers: any; } ? z.infer : undefined; }, InferRouteHandlerResult>>; export {};