@jmnuf/ao
Version:
A simple typescript based full-stack api endpoint creator that is meant to somewhat follow web standards in its implementation.
35 lines (34 loc) • 2.93 kB
TypeScript
import type { AncientOne, RouteHandler } from "./ancients";
import type { HTTPMethod, ObjectValues, Prettify, ResponseData, SplitString, TuplePush, TupleRemove } from "./utils";
type FindPathParamNames<Path extends string> = FindPathParamNamesRec<SplitString<Path, "/", true>, []>;
type FindPathParamNamesRec<PathParts extends string[], Names extends string[]> = PathParts extends [] ? Names : PathParts extends [infer Head extends string, ...infer Tail extends string[]] ? Head extends `:${infer PathParam extends string}` ? FindPathParamNamesRec<Tail, TuplePush<Names, PathParam>> : FindPathParamNamesRec<Tail, Names> : never;
export type Apostle<Ancient extends AncientOne<any, Record<string, {
[M in Lowercase<HTTPMethod>]: RouteHandler<any, any>;
}>>> = Ancient extends AncientOne<infer Prefix extends string, any> ? ObjectValues<{
[Path in keyof Ancient["__TYPE_LEVEL_T"] as Path extends string ? Path : never]: Path extends string ? CreateRoutine<SplitString<`${Prefix}${Path}`, "/", true>, Path, Ancient["__TYPE_LEVEL_T"], FindPathParamNames<Path>> : never;
}> : never;
type CreateRoutine<PathParts extends string[], FullPath extends string, Handlers extends Record<string, {
[M in Lowercase<HTTPMethod>]: RouteHandler<any, any>;
}>, PathParamNames extends string[]> = PathParts extends [] ? {
[M in keyof Handlers[FullPath] as M extends "" ? never : Handlers[FullPath][M] extends never ? never : Handlers[FullPath][M] extends RouteHandler<any, any> ? M : never]: Handlers[FullPath][M] extends RouteHandler<infer Return, infer PathParams> ? PathParamNames extends [] ? (cfg?: {
query?: Record<string, string | string[]>;
}) => Promise<ResponseData<Return>> : Prettify<Omit<PathParams, PathParamNames[number]>> extends Record<string, never> ? (cfg?: {
query?: Record<string, string | string[]>;
}) => Promise<ResponseData<Return>> : (cfg: {
params: Prettify<Omit<PathParams, PathParamNames[number]>>;
query?: Record<string, string | string[]>;
}) => Promise<ResponseData<Return>> : never;
} : PathParts extends [infer Head extends string, ...infer Tail extends string[]] ? Head extends `:${infer PathParam}` ? Tail extends [] ? {
(params: {
[param in PathParam]: string;
}): CreateRoutine<[], FullPath, Handlers, PathParamNames>;
} & CreateRoutine<[], FullPath, Handlers, TupleRemove<PathParamNames, PathParam>> : (params: {
[param in PathParam]: string;
}) => CreateRoutine<Tail, FullPath, Handlers, Exclude<PathParamNames, PathParam>> : {
[path in Head]: CreateRoutine<Tail, FullPath, Handlers, PathParamNames>;
} : CreateRoutine<[], FullPath, Handlers, PathParamNames>;
export declare const DEBUG_PATHING_PROPERTY = "__DEBUG_PATHING__";
export declare function createApostle<Ancient extends AncientOne<any, Record<string, {
[M in Lowercase<HTTPMethod>]: RouteHandler<any, any>;
}>>>(origin: string): Apostle<Ancient>;
export {};