import type { HttpVerb } from "../vite"; type OneOrMany = T | T[]; type NoParams = {}; type AllKeys = T extends T ? keyof T : never; type Simplify = T extends unknown ? { [K in keyof T]: T[K]; } : never; type IsObject = T extends object ? T extends any[] ? 0 : T extends (...args: any[]) => any ? 0 : 1 : 0; type SuperSet = T & { [K in AllKeys as K extends keyof T ? never : K]?: never; }; type SuperSets = Omit & { [P in K]: Simplify>; }; export type Awaitable = Promise | T; export type Verb = Uppercase; export interface Platform { } export interface Context { readonly url: URL; readonly request: Request; readonly method: TVerb; readonly route: TRoute["path"]; readonly params: TRoute["params"]; readonly meta: NormalizedMeta; readonly platform: Platform; readonly serializedGlobals: Record; readonly parent: Context | undefined; render(template: Marko.Template, input: T, init?: ResponseInit): Response; fetch(resource: string | URL | Request, init?: RequestInit): Promise; redirect(to: string | URL, status?: number): Response; back(fallback?: string | URL, status?: number): Response; } export type MultiRouteContext = TRoute extends any ? TVerb extends any ? Context>, TVerb> : never : never; export type ParamsObject = Record; export type InputObject = Record; export type NextFunction = () => Awaitable; export type HandlerLike = Awaitable>>; export type RouteHandlerResult = Response | typeof MarkoRun.NotHandled | typeof MarkoRun.NotMatched | null | void; export type RouteHandler = (context: MultiRouteContext, next: NextFunction) => Awaitable; export interface Route { path: Path; params: Params; meta: Meta; } type DefineRoutes> = { [K in keyof T]: K extends string ? T[K] extends { meta: infer Meta; } ? Route, Meta, K> : Route, any, K> : never; }; type DefinePaths, TVerb extends "get" | "post"> = { [K in keyof T]: K extends string ? T[K] extends { verb: infer V; } ? V extends TVerb ? K : never : never : never; }[keyof T]; export type DefineApp; }> = { routes: DefineRoutes; getPaths: DefinePaths; postPaths: DefinePaths; }; export interface RouteWithHandler extends Route { handler: RouteHandler; } export type Fetch = (request: Request, platform: TPlatform) => Promise; export type Match = (method: string, pathname: string) => RouteWithHandler | null; export type Invoke = (route: RouteWithHandler | null, request: Request, platform: TPlatform) => Promise; export interface RuntimeModule { fetch(...args: Parameters>): ReturnType>; match: Match; invoke(...args: Parameters>): ReturnType>; } type Member = T extends T ? (U extends T ? T : never) : never; type PathParamKeys = Path extends `${infer _}$${infer Param}/${infer Rest}` ? [Unescape, ...PathParamKeys] : Path extends `${infer _}$$${infer Param}` ? [Unescape] : Path extends `${infer _}$${infer Param}` ? [Unescape] : []; type Unescape = Escaped extends `\`${infer Value}\`` ? Value : Escaped; type PathParams> = 0 extends Keys["length"] ? NoParams : { [K in Keys[number]]: string; }; type Segments = T extends "" ? Acc : T extends `${infer Left}/${infer Rest}` ? Segments : [...Acc, T]; type GTE = A["length"] extends B["length"] ? 1 : A extends [infer _Ha, ...infer Ta] ? B extends [infer _Hb, ...infer Tb] ? GTE : 1 : 0; type MatchSegments = A extends `${infer P}/${string}*` ? 1 extends GTE, Segments

> ? `${P}/${string}` : never : Segments["length"] extends Segments["length"] ? A : never; type PathPattern = T extends `${infer Left}/\${${string}}/${infer Rest}` ? PathPattern<`${Left}/${string}/${Rest}`> : T extends `${infer Left}/\${...${string}}` ? PathPattern<`${Left}/${string}*`> : T extends `${infer Left}/\${${string}}` ? PathPattern<`${Left}/${string}`> : T; type ValidatePath = Paths | (Path extends `/${string}` ? MatchSegments, Path>, Path> : Path); type ValidateHref = Href extends `${infer P}#${infer H}?${infer Q}` ? `${ValidatePath}#${H}?${Q}` : Href extends `${infer P}?${infer Q}` ? `${ValidatePath}?${Q}` : Href extends `${infer P}#${infer H}` ? `${ValidatePath}#${H}` : ValidatePath; type NormalizedMetaObject = IsObject extends 1 ? TVerb extends keyof T ? Simplify & T[TVerb]> : Simplify> : never; export type NormalizedMeta = IsObject extends 1 ? { [K in TVerb]: NormalizedMetaObject; }[TVerb] : T; export type NormalizedMetaLookup = { [K in Verb]: IsObject extends 1 ? NormalizedMetaObject : T; }; export interface AppData { } export type Routes = AppData extends { routes: infer T; } ? T : Record; export type AnyRoute = Routes[keyof Routes]; export type HandlerTypeFn = AppData extends { routes: any; } ? > = HandlerLike>>(handler: T) => T : >(handler: T) => T; type DefaultAPI = keyof Exclude | Marko.Body | string> extends "content" ? "tags" : "class"; type TemplateAPI = T extends { api: infer API; } ? API : DefaultAPI; export type LayoutInput = TemplateAPI extends "tags" ? { content: Marko.Body; } : { renderBody: Marko.Body; }; export type GetPaths = AppData extends { getPaths: infer T; } ? T : string; export type PostPaths = AppData extends { postPaths: infer T; } ? T : string; export type GetablePath = ValidatePath; export type GetableHref = ValidateHref; export type PostablePath = ValidatePath; export type PostableHref = ValidateHref; export {};