export type Params = Record; export type Search = Record; export type Listener = (location: Location) => void; export type Blocker = { id: string; message: string; }; export type Matcher = { isArea: boolean; name: string; ranking: number; path: (string | { name: string; union?: Set; })[]; search: Record; }> | undefined; }; export type RouteObject = Readonly<{ path: string; search: string; }>; export type Location = Readonly<{ path: readonly string[]; search: Readonly; raw: Readonly<{ path: string; search: string; }>; toString(): string; }>; export type NonEmptySplit = Value extends `${infer Head}${Separator}${infer Tail}` ? Head extends "" ? NonEmptySplit : [Head, ...NonEmptySplit] : Value extends "" ? [] : [Value]; export type PartialRecord = { [P in K]?: T | undefined; }; export type ExtractUnion = NonEmptySplit[number]; export type ExtractRequiredParam = Value extends `${infer Name}{${infer Union}}` ? Record> : Record; export type ExtractOptionalMultipleParam = Value extends `${infer Name}{${infer Union}}` ? PartialRecord[]> : PartialRecord; export type ExtractOptionalParam = Value extends `${infer Name}{${infer Union}}` ? PartialRecord> : PartialRecord; export type GetPathParams> = Parts extends [infer Head, ...infer Tail] ? Head extends `:${infer Name}` ? ExtractRequiredParam & GetPathParams : GetPathParams : {}; export type GetSearchParams> = Parts extends [infer Head, ...infer Tail] ? Head extends `:${infer Name}[]` ? ExtractOptionalMultipleParam & GetSearchParams : Head extends `:${infer Name}` ? ExtractOptionalParam & GetSearchParams : GetSearchParams : {}; type EnsureSlashPrefix = Value extends `/${string}` ? Value : `/${Value}`; export type ParseRoute> = CleanRoute extends `${infer Path}?${infer Search}` ? { path: Path; search: Search; } : { path: CleanRoute; search: ""; }; export type ParseRoutes> = { [K in keyof Routes]: ParseRoute; }; type AddPrefixOnNonEmpty = Value extends "" ? Value : `${Prefix}${Value}`; export type ConcatPaths, FixedPathB extends string = EnsureSlashPrefix> = FixedPathA extends "/" ? FixedPathB : FixedPathB extends "/" ? FixedPathA : `${FixedPathA}${FixedPathB}`; export type ConcatSearchs = SearchA extends "" ? SearchB : `${SearchA}${AddPrefixOnNonEmpty}`; export type ConcatRoutes, RouteObjectB extends RouteObject = ParseRoute, Path extends string = ConcatPaths, Search extends string = ConcatSearchs> = `${Path}${AddPrefixOnNonEmpty}`; export type PrependBasePath> = { [K in keyof Routes]: { path: ConcatPaths; search: Routes[K]["search"]; }; }; export type GetAreaRoutes> = { [K in keyof Routes as Routes[K]["path"] extends `${string}/*` ? K : never]: Routes[K]["path"] extends `${infer Rest}/*` ? { path: Rest; search: Routes[K]["search"]; } : never; }; type SimplifyParams = T extends Record ? {} : { [K in keyof T]: T[K]; }; export type GetRoutesParams> = { [K in keyof Routes]: SimplifyParams & GetSearchParams>; }; type NonOptionalProperties = Exclude<{ [K in keyof T]: T extends Record ? K : never; }[keyof T], undefined>; export type UnionToIntersection = (Union extends never ? never : (_: Union) => never) extends (_: infer Intersection) => void ? Intersection : never; export type ParamsArg = Params extends Record ? [] : NonOptionalProperties extends never ? [params?: { [K in keyof Params]: Params[K]; }] : [params: { [K in keyof Params]: Params[K]; }]; export type GetCreateURLFns> = { [RouteName in keyof RoutesParams]: (...params: ParamsArg>) => string; }; type RouteLike = { name: string; params: Params; }; type RouterLike = { getRoute: (...args: any[]) => RouteLike | undefined; }; type RemapRoute = { [N in Route["name"]]: Extract["params"]; }; export type InferRoutes = RemapRoute>>; export {};