/** * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ import { compile } from "path-to-regexp"; import type { RouteProps } from "react-router"; import { isDefined } from "./type-narrowing"; export interface UrlRouteProps extends RouteProps { path: string; } export interface URLParams

{ params?: P; query?: Q; fragment?: string; } export function buildURL

(path: string, { params, query, fragment }: URLParams = {}) { const pathBuilder = compile(String(path)); const queryParams = query ? new URLSearchParams(Object.entries(query)).toString() : ""; const parts = [ pathBuilder(params), queryParams && `?${queryParams}`, fragment && `#${fragment}`, ]; return parts.filter(isDefined).join(""); } export function buildURLPositional

(path: string) { return function (params?: P, query?: Q, fragment?: string): string { return buildURL(path, { params, query, fragment }); }; } export type UrlParamsFor = Pathname extends `${string}/:${infer A}?/${infer Tail}` ? Partial> & UrlParamsFor<`/${Tail}`> : Pathname extends `${string}/:${infer A}/${infer Tail}` ? Record & UrlParamsFor<`/${Tail}`> : Pathname extends `${string}/:${infer A}?` ? Partial> : Pathname extends `${string}/:${infer A}` ? Record : {}; export interface UrlBuilder { compile(params: UrlParamsFor, query?: object, fragment?: string): string; } export function urlBuilderFor(pathname: Pathname): UrlBuilder { return { compile: buildURLPositional(pathname), }; }