From 73e36c99037cef1ccc43bb80b67b19e0f44326fd Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 23 Feb 2024 08:30:43 -0300 Subject: return to form after 2fa cancelled --- packages/demobank-ui/src/route.ts | 100 +++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 33 deletions(-) (limited to 'packages/demobank-ui/src/route.ts') diff --git a/packages/demobank-ui/src/route.ts b/packages/demobank-ui/src/route.ts index 4b021d762..72c7802fb 100644 --- a/packages/demobank-ui/src/route.ts +++ b/packages/demobank-ui/src/route.ts @@ -15,43 +15,49 @@ */ import { useNavigationContext } from "./context/navigation.js"; +declare const __location: unique symbol; +/** + * special string that defined a location in the application + * + * this help to prevent wrong path + */ +export type AppLocation = string & { + [__location]: true; +}; +export type EmptyObject = Record; + export function urlPattern< - T extends Record = Record, + T extends Record = EmptyObject, >(pattern: RegExp, reverse: (p: T) => string): RouteDefinition { + const url = reverse as ((p: T) => AppLocation) return { pattern: new RegExp(pattern), - url: reverse, + url, }; } -export type RouteDefinition = { +/** + * defines a location in the app + * + * pattern: how a string will trigger this location + * url(): how a state serialize to a location + */ + +export type ObjectOf = Record | EmptyObject; + +export type RouteDefinition = EmptyObject> = { pattern: RegExp; - url: (p: T) => string; + url: (p: T) => AppLocation; }; const nullRountDef = { pattern: new RegExp(/.*/), - url: () => "", + url: () => "" as AppLocation, }; -export function buildNullRoutDefinition(): RouteDefinition { +export function buildNullRoutDefinition>(): RouteDefinition { return nullRountDef; } -export type RouteMap = { - [n in keyof T]: RouteDefinition; -}; - -export type RouteParamsType< - P, - T extends keyof P, -> = P[T] extends RouteDefinition ? ASD : never; - -type Location, NAME extends keyof T> = { - parent: T; - name: NAME; - values: RouteParamsType; -}; - /** * Search path in the pageList * get the values from the path found @@ -60,23 +66,28 @@ type Location, NAME extends keyof T> = { * @param path * @param params */ -function findMatch, ROUTES extends keyof RM>( - pagesMap: RM, - pageList: Array, +function findMatch>( + pagesMap: T, + pageList: Array, path: string, params: Record, -): Location | undefined { +): Location | undefined { for (let idx = 0; idx < pageList.length; idx++) { const name = pageList[idx]; const found = pagesMap[name].pattern.exec(path); if (found !== null) { - const values = - found.groups === undefined ? {} : structuredClone(found.groups); + const values = {} as Record Object.entries(params).forEach(([key, value]) => { values[key] = value; }); + if (found.groups !== undefined) { + Object.entries(found.groups).forEach(([key, value]) => { + values[key] = value; + }); + } + // @ts-expect-error values is a map string which is equivalent to the RouteParamsType return { name, parent: pagesMap, values }; } @@ -84,12 +95,35 @@ function findMatch, ROUTES extends keyof RM>( return undefined; } -export function useCurrentLocation< - DEF, - RM extends RouteMap, - ROUTES extends keyof RM, ->(pagesMap: RM) { - const pageList = Object.keys(pagesMap) as Array; +/** + * get the type of the params of a location + * + */ +type RouteParamsType< + RouteType, + Key extends keyof RouteType, +> = RouteType[Key] extends RouteDefinition ? ParamType : never; + +/** + * Helps to create a map of a type with the key + */ +type MapKeyValue = { + [Key in keyof Type]: Key extends string ? { + parent: Type, + name: Key, + values: RouteParamsType; + } : never; +} + +/** + * create a enumaration of value of a mapped type + */ +type EnumerationOf = T[keyof T] + +type Location = EnumerationOf> + +export function useCurrentLocation>>(pagesMap: T): Location | undefined { + const pageList = Object.keys(pagesMap as object) as Array; const { path, params } = useNavigationContext(); return findMatch(pagesMap, pageList, path, params); -- cgit v1.2.3