/* This file is part of GNU Taler (C) 2022-2024 Taler Systems S.A. GNU Taler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Taler; see the file COPYING. If not, see */ import { useNavigationContext } from "./context/navigation.js"; export function urlPattern< T extends Record = Record, >(pattern: RegExp, reverse: (p: T) => string): RouteDefinition { return { pattern: new RegExp(pattern), url: reverse, }; } export type RouteDefinition = { pattern: RegExp; url: (p: T) => string; }; const nullRountDef = { pattern: new RegExp(/.*/), url: () => "", }; 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 * add params from searchParams * * @param path * @param params */ function findMatch, ROUTES extends keyof RM>( pagesMap: RM, pageList: Array, path: string, params: Record, ): 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); Object.entries(params).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 }; } } return undefined; } export function useCurrentLocation< DEF, RM extends RouteMap, ROUTES extends keyof RM, >(pagesMap: RM) { const pageList = Object.keys(pagesMap) as Array; const { path, params } = useNavigationContext(); return findMatch(pagesMap, pageList, path, params); }