import { compile, PathFunction, parse, pathToRegexp, Token, ParamData, } from './pathToRegexp.js'; import { ShortenPath } from './pathTypes.js'; const urlBaseCache: Record> = Object.create(null); export function getUrlBase(path: string): PathFunction { if (!(path in urlBaseCache)) { urlBaseCache[path] = compile(path); } return urlBaseCache[path]; } const urlTokensCache: Record> = Object.create(null); export function getUrlTokens(path: string): Set { if (!(path in urlTokensCache)) { urlTokensCache[path] = tokenMap(parse(path).tokens); } return urlTokensCache[path]; } const pathRegexCache: Record = Object.create(null); export function getPathRegex(path: string): RegExp { if (!(path in pathRegexCache)) { pathRegexCache[path] = pathToRegexp(path).regexp; } return pathRegexCache[path]; } function tokenMap(tokens: Token[]): Set { const tokenNames = new Set(); for (const token of tokens) { switch (token.type) { case 'param': case 'wildcard': tokenNames.add(token.name); break; case 'group': for (const name of tokenMap(token.tokens)) { tokenNames.add(name); } break; } } return tokenNames; } const proto = Object.prototype; const gpo = Object.getPrototypeOf; export function isPojo(obj: unknown): obj is Record { if (obj === null || typeof obj !== 'object') { return false; } return gpo(obj) === proto; } export function shortenPath(path: S): ShortenPath { const lastTokenIndex = Math.max(path.lastIndexOf(':'), path.lastIndexOf('*')); if (lastTokenIndex === -1) throw new Error( 'Resource path requires at least one :parameter or *wildcard', ); let shortUrlRoot: ShortenPath = path.substring(0, lastTokenIndex) as any; if (shortUrlRoot[shortUrlRoot.length - 1] === '/') shortUrlRoot = shortUrlRoot.substring( 0, shortUrlRoot.length - 1, ) as ShortenPath; return shortUrlRoot; }