@devp0nt/route0 1.0.0-next.26 → 1.0.0-next.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -350,6 +350,7 @@ class Routes {
350
350
  pathsOrdering;
351
351
  keysOrdering;
352
352
  ordered;
353
+ _;
353
354
  constructor({
354
355
  routes,
355
356
  isHydrated = false,
@@ -357,9 +358,9 @@ class Routes {
357
358
  keysOrdering,
358
359
  ordered
359
360
  }) {
360
- this.routes = isHydrated ? routes : Routes._hydrate(routes);
361
+ this.routes = isHydrated ? routes : Routes.hydrate(routes);
361
362
  if (!pathsOrdering || !keysOrdering || !ordered) {
362
- const ordering = Routes._makeOrdering(this.routes);
363
+ const ordering = Routes.makeOrdering(this.routes);
363
364
  this.pathsOrdering = ordering.pathsOrdering;
364
365
  this.keysOrdering = ordering.keysOrdering;
365
366
  this.ordered = this.keysOrdering.map((key) => this.routes[key]);
@@ -368,12 +369,19 @@ class Routes {
368
369
  this.keysOrdering = keysOrdering;
369
370
  this.ordered = ordered;
370
371
  }
372
+ this._ = {
373
+ getLocation: this.getLocation.bind(this),
374
+ override: this.override.bind(this),
375
+ pathsOrdering: this.pathsOrdering,
376
+ keysOrdering: this.keysOrdering,
377
+ ordered: this.ordered
378
+ };
371
379
  }
372
380
  static create(routes) {
373
381
  const instance = new Routes({ routes });
374
- return Routes._prettify(instance);
382
+ return Routes.prettify(instance);
375
383
  }
376
- static _prettify(instance) {
384
+ static prettify(instance) {
377
385
  Object.setPrototypeOf(instance, Routes.prototype);
378
386
  Object.defineProperty(instance, Symbol.toStringTag, {
379
387
  value: "Routes"
@@ -384,7 +392,7 @@ class Routes {
384
392
  Object.assign(instance, instance.routes);
385
393
  return instance;
386
394
  }
387
- static _hydrate(routes) {
395
+ static hydrate(routes) {
388
396
  const result = {};
389
397
  for (const key in routes) {
390
398
  if (Object.prototype.hasOwnProperty.call(routes, key)) {
@@ -404,8 +412,8 @@ class Routes {
404
412
  }
405
413
  return typeof input === "string" ? Route0.getLocation(input) : Route0.getLocation(input);
406
414
  }
407
- static _makeOrdering(routes) {
408
- const hydrated = Routes._hydrate(routes);
415
+ static makeOrdering(routes) {
416
+ const hydrated = Routes.hydrate(routes);
409
417
  const entries = Object.entries(hydrated);
410
418
  const getParts = (path) => {
411
419
  if (path === "/") return ["/"];
@@ -441,8 +449,13 @@ class Routes {
441
449
  keysOrdering: this.keysOrdering,
442
450
  ordered: this.keysOrdering.map((key) => newRoutes[key])
443
451
  });
444
- return Routes._prettify(instance);
452
+ return Routes.prettify(instance);
445
453
  }
454
+ static _ = {
455
+ prettify: Routes.prettify.bind(Routes),
456
+ hydrate: Routes.hydrate.bind(Routes),
457
+ makeOrdering: Routes.makeOrdering.bind(Routes)
458
+ };
446
459
  }
447
460
  // Annotate the CommonJS export names for ESM import in node:
448
461
  0 && (module.exports = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["// TODO: asterisk\n// TODO: when asterisk then query params will be extended also after extend\n// TODO: optional params\n// TODO: required search\n\n// TODO: .extension('.json') to not add additional / but just add some extension\n// TODO: search input can be boolean, or even object with qs\n// TODO: Роут0 три пусть три тоже сам генерится вероятно\n// TODO: Роут0 три мод, тогда там все ноуты кончаются на .селф\n// TODO: use splats in param definition \"*\"\n// TODO: ? check extend for search only .extend('&x&z')\n// TODO: .create(route, {useSearch, useParams})\n// TODO: Из пас экзакт, из пасвизквери экзает, из чилдрен, из парент, из экзактОр\n// TODO: isEqual, isChildren, isParent\n// TODO: extractParams, extractSearch\n// TODO: getPathDefinition respecting definitionParamPrefix, definitionSearchPrefix\n// TODO: prepend\n// TODO: Route0.createTree({base:{self: x, children: ...})\n// TODO: overrideTree\n// TODO: .create(route, {baseUrl, useLocation})\n// TODO: ? optional path params as @\n// TODO: prependMany, extendMany, overrideMany, with types\n// TODO: optional route params /x/:id?\n\nexport class Route0<TDefinition extends string> {\n readonly definition: TDefinition\n readonly pathDefinition: _PathDefinition<TDefinition>\n readonly paramsDefinition: _ParamsDefinition<TDefinition>\n readonly searchDefinition: _SearchDefinition<TDefinition>\n baseUrl: string\n\n private constructor(definition: TDefinition, config: RouteConfigInput = {}) {\n this.definition = definition\n this.pathDefinition = Route0._getPathDefinitionBydefinition(definition)\n this.paramsDefinition = Route0._getParamsDefinitionBydefinition(definition)\n this.searchDefinition = Route0._getSearchDefinitionBydefinition(definition)\n\n const { baseUrl } = config\n if (baseUrl && typeof baseUrl === 'string' && baseUrl.length) {\n this.baseUrl = baseUrl\n } else {\n const g = globalThis as unknown as { location?: { origin?: string } }\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (typeof g?.location?.origin === 'string' && g.location.origin.length > 0) {\n this.baseUrl = g.location.origin\n } else {\n this.baseUrl = 'https://example.com'\n }\n }\n }\n\n static create<TDefinition extends string>(\n definition: TDefinition | AnyRoute<TDefinition>,\n config?: RouteConfigInput,\n ): CallabelRoute<TDefinition> {\n if (typeof definition === 'function') {\n return definition\n }\n const original = typeof definition === 'object' ? definition : new Route0<TDefinition>(definition, config)\n const callable = original.get.bind(original)\n Object.setPrototypeOf(callable, original)\n Object.defineProperty(callable, Symbol.toStringTag, {\n value: original.definition,\n })\n return callable as never\n }\n\n private static _splitPathDefinitionAndSearchTailDefinition(definition: string) {\n const i = definition.indexOf('&')\n if (i === -1) return { pathDefinition: definition, searchTailDefinition: '' }\n return {\n pathDefinition: definition.slice(0, i),\n searchTailDefinition: definition.slice(i),\n }\n }\n\n private static _getAbsPath(baseUrl: string, pathWithSearch: string) {\n return new URL(pathWithSearch, baseUrl).toString().replace(/\\/$/, '')\n }\n\n private static _getPathDefinitionBydefinition<TDefinition extends string>(definition: TDefinition) {\n const { pathDefinition } = Route0._splitPathDefinitionAndSearchTailDefinition(definition)\n return pathDefinition as _PathDefinition<TDefinition>\n }\n\n private static _getParamsDefinitionBydefinition<TDefinition extends string>(\n definition: TDefinition,\n ): _ParamsDefinition<TDefinition> {\n const { pathDefinition } = Route0._splitPathDefinitionAndSearchTailDefinition(definition)\n const matches = Array.from(pathDefinition.matchAll(/:([A-Za-z0-9_]+)/g))\n const paramsDefinition = Object.fromEntries(matches.map((m) => [m[1], true]))\n const keysCount = Object.keys(paramsDefinition).length\n if (keysCount === 0) {\n return undefined as _ParamsDefinition<TDefinition>\n }\n return paramsDefinition as _ParamsDefinition<TDefinition>\n }\n\n private static _getSearchDefinitionBydefinition<TDefinition extends string>(\n definition: TDefinition,\n ): _SearchDefinition<TDefinition> {\n const { searchTailDefinition } = Route0._splitPathDefinitionAndSearchTailDefinition(definition)\n if (!searchTailDefinition) {\n return undefined as _SearchDefinition<TDefinition>\n }\n const keys = searchTailDefinition.split('&').filter(Boolean)\n const searchDefinition = Object.fromEntries(keys.map((k) => [k, true]))\n const keysCount = Object.keys(searchDefinition).length\n if (keysCount === 0) {\n return undefined as _SearchDefinition<TDefinition>\n }\n return searchDefinition as _SearchDefinition<TDefinition>\n }\n\n extend<TSuffixDefinition extends string>(\n suffixDefinition: TSuffixDefinition,\n ): CallabelRoute<PathExtended<TDefinition, TSuffixDefinition>> {\n const { pathDefinition: parentPathDefinition } = Route0._splitPathDefinitionAndSearchTailDefinition(this.definition)\n const { pathDefinition: suffixPathDefinition, searchTailDefinition: suffixSearchTailDefinition } =\n Route0._splitPathDefinitionAndSearchTailDefinition(suffixDefinition)\n const pathDefinition = `${parentPathDefinition}/${suffixPathDefinition}`.replace(/\\/{2,}/g, '/')\n const definition = `${pathDefinition}${suffixSearchTailDefinition}` as PathExtended<TDefinition, TSuffixDefinition>\n return Route0.create<PathExtended<TDefinition, TSuffixDefinition>>(definition, { baseUrl: this.baseUrl })\n }\n\n // has params\n get(\n input: OnlyIfHasParams<\n _ParamsDefinition<TDefinition>,\n WithParamsInput<TDefinition, { search?: undefined; abs?: false }>\n >,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, PathOnlyRouteValue<TDefinition>>\n get(\n input: OnlyIfHasParams<\n _ParamsDefinition<TDefinition>,\n WithParamsInput<TDefinition, { search: _SearchInput<TDefinition>; abs?: false }>\n >,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithSearchRouteValue<TDefinition>>\n get(\n input: OnlyIfHasParams<\n _ParamsDefinition<TDefinition>,\n WithParamsInput<TDefinition, { search?: undefined; abs: true }>\n >,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, AbsolutePathOnlyRouteValue<TDefinition>>\n get(\n input: OnlyIfHasParams<\n _ParamsDefinition<TDefinition>,\n WithParamsInput<TDefinition, { search: _SearchInput<TDefinition>; abs: true }>\n >,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, AbsoluteWithSearchRouteValue<TDefinition>>\n\n // no params\n get(...args: OnlyIfNoParams<_ParamsDefinition<TDefinition>, [], [never]>): PathOnlyRouteValue<TDefinition>\n get(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, { search?: undefined; abs?: false }>,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, PathOnlyRouteValue<TDefinition>>\n get(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, { search: _SearchInput<TDefinition>; abs?: false }>,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, WithSearchRouteValue<TDefinition>>\n get(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, { search?: undefined; abs: true }>,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, AbsolutePathOnlyRouteValue<TDefinition>>\n get(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, { search: _SearchInput<TDefinition>; abs: true }>,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, AbsoluteWithSearchRouteValue<TDefinition>>\n\n // implementation\n get(...args: any[]): string {\n const { searchInput, paramsInput, absInput } = ((): {\n searchInput: Record<string, string | number>\n paramsInput: Record<string, string | number>\n absInput: boolean\n } => {\n if (args.length === 0) {\n return { searchInput: {}, paramsInput: {}, absInput: false }\n }\n const input = args[0]\n if (typeof input !== 'object' || input === null) {\n // throw new Error(\"Invalid get route input: expected object\")\n return { searchInput: {}, paramsInput: {}, absInput: false }\n }\n const { search, abs, ...params } = input\n return { searchInput: search || {}, paramsInput: params, absInput: abs ?? false }\n })()\n\n // validate params\n const neededParamsKeys = this.paramsDefinition ? Object.keys(this.paramsDefinition) : []\n const providedParamsKeys = Object.keys(paramsInput)\n const notProvidedKeys = neededParamsKeys.filter((k) => !providedParamsKeys.includes(k))\n if (notProvidedKeys.length) {\n // throw new Error(`Missing params: not defined keys ${notProvidedKeys.map((k) => `\"${k}\"`).join(\", \")}.`)\n Object.assign(paramsInput, Object.fromEntries(notProvidedKeys.map((k) => [k, 'undefined'])))\n }\n\n // create url\n\n let url = this.pathDefinition as string\n // replace params\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n url = url.replace(/:([A-Za-z0-9_]+)/g, (_m, k) => encodeURIComponent(String(paramsInput?.[k] ?? '')))\n // search params\n const searchInputStringified = Object.fromEntries(Object.entries(searchInput).map(([k, v]) => [k, String(v)]))\n url = [url, new URLSearchParams(searchInputStringified).toString()].filter(Boolean).join('?')\n // dedupe slashes\n url = url.replace(/\\/{2,}/g, '/')\n // absolute\n url = absInput ? Route0._getAbsPath(this.baseUrl, url) : url\n\n return url\n }\n\n // has params\n flat(\n input: OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithParamsInput<TDefinition>>,\n abs?: false,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, PathOnlyRouteValue<TDefinition>>\n flat(\n input: OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithParamsInput<TDefinition, _SearchInput<TDefinition>>>,\n abs?: false,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithSearchRouteValue<TDefinition>>\n flat(\n input: OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithParamsInput<TDefinition>>,\n abs: true,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, AbsolutePathOnlyRouteValue<TDefinition>>\n flat(\n input: OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithParamsInput<TDefinition, _SearchInput<TDefinition>>>,\n abs: true,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, AbsoluteWithSearchRouteValue<TDefinition>>\n\n // no params\n flat(...args: OnlyIfNoParams<_ParamsDefinition<TDefinition>, [], [never]>): PathOnlyRouteValue<TDefinition>\n flat(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, Record<never, never>>,\n abs?: false,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, PathOnlyRouteValue<TDefinition>>\n flat(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, _SearchInput<TDefinition>>,\n abs?: false,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, WithSearchRouteValue<TDefinition>>\n flat(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, Record<never, never>>,\n abs: true,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, AbsolutePathOnlyRouteValue<TDefinition>>\n flat(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, _SearchInput<TDefinition>>,\n abs: true,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, AbsoluteWithSearchRouteValue<TDefinition>>\n\n // implementation\n flat(...args: any[]): string {\n const { searchInput, paramsInput, absInput } = ((): {\n searchInput: Record<string, string | number>\n paramsInput: Record<string, string | number>\n absInput: boolean\n } => {\n if (args.length === 0) {\n return { searchInput: {}, paramsInput: {}, absInput: false }\n }\n const input = args[0]\n if (typeof input !== 'object' || input === null) {\n // throw new Error(\"Invalid get route input: expected object\")\n return { searchInput: {}, paramsInput: {}, absInput: args[1] ?? false }\n }\n const paramsKeys = this.getParamsKeys()\n const paramsInput = paramsKeys.reduce<Record<string, string | number>>((acc, key) => {\n if (input[key] !== undefined) {\n acc[key] = input[key]\n }\n return acc\n }, {})\n const searchKeys = this.getSearchKeys()\n const searchInput = Object.keys(input)\n .filter((k) => {\n if (searchKeys.includes(k)) {\n return true\n }\n if (paramsKeys.includes(k)) {\n return false\n }\n return true\n })\n .reduce<Record<string, string | number>>((acc, key) => {\n acc[key] = input[key]\n return acc\n }, {})\n return { searchInput, paramsInput, absInput: args[1] ?? false }\n })()\n\n return this.get({ ...paramsInput, search: searchInput, abs: absInput } as never)\n }\n\n getParamsKeys(): string[] {\n return Object.keys(this.paramsDefinition || {})\n }\n getSearchKeys(): string[] {\n return Object.keys(this.searchDefinition || {})\n }\n getFlatKeys(): string[] {\n return [...this.getSearchKeys(), ...this.getParamsKeys()]\n }\n\n getDefinition(): string {\n return this.pathDefinition\n }\n\n clone(config?: RouteConfigInput): Route0<TDefinition> {\n return new Route0(this.definition, config)\n }\n\n getRegexString(): string {\n // Normalize the path definition (remove trailing slash except for root)\n const def =\n this.pathDefinition.length > 1 && this.pathDefinition.endsWith('/')\n ? this.pathDefinition.slice(0, -1)\n : this.pathDefinition\n\n // Replace :param with placeholders, escape regex special chars, then restore capture groups\n const pattern = def\n .replace(/:([A-Za-z0-9_]+)/g, '___PARAM___') // temporarily replace params with placeholder\n .replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') // escape regex special chars\n .replace(/___PARAM___/g, '([^/]+)') // replace placeholder with capture group\n\n return pattern\n }\n\n getRegex(): RegExp {\n return new RegExp(`^${this.getRegexString()}$`)\n }\n\n static getRegexString(routes: AnyRoute[] | AnyRoute): string {\n const routesArray = Array.isArray(routes) ? routes : [routes]\n return routesArray.map((route) => route.getRegexString()).join('|')\n }\n static getRegex(routes: AnyRoute[] | AnyRoute): RegExp {\n return new RegExp(`^(${Route0.getRegexString(routes)})$`)\n }\n\n static getLocation(href: `${string}://${string}`): UnknownLocation\n static getLocation(hrefRel: `/${string}`): UnknownLocation\n static getLocation(hrefOrHrefRel: string): UnknownLocation\n static getLocation(location: AnyLocation): UnknownLocation\n static getLocation(url: URL): UnknownLocation\n static getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation\n static getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation {\n if (hrefOrHrefRelOrLocation instanceof URL) {\n return Route0.getLocation(hrefOrHrefRelOrLocation.href)\n }\n if (typeof hrefOrHrefRelOrLocation !== 'string') {\n hrefOrHrefRelOrLocation = hrefOrHrefRelOrLocation.href || hrefOrHrefRelOrLocation.hrefRel\n }\n // Check if it's an absolute URL (starts with scheme://)\n const abs = /^[a-zA-Z][a-zA-Z\\d+\\-.]*:\\/\\//.test(hrefOrHrefRelOrLocation)\n\n // Use dummy base only if relative\n const base = abs ? undefined : 'http://example.com'\n const url = new URL(hrefOrHrefRelOrLocation, base)\n\n // Extract search params\n const searchParams = Object.fromEntries(url.searchParams.entries())\n\n // Normalize pathname (remove trailing slash except for root)\n let pathname = url.pathname\n if (pathname.length > 1 && pathname.endsWith('/')) {\n pathname = pathname.slice(0, -1)\n }\n\n // Common derived values\n const hrefRel = pathname + url.search + url.hash\n\n // Build the location object consistent with _GeneralLocation\n const location: UnknownLocation = {\n pathname,\n search: url.search,\n hash: url.hash,\n origin: abs ? url.origin : undefined,\n href: abs ? url.href : undefined,\n hrefRel,\n abs,\n\n // extra host-related fields (available even for relative with dummy base)\n host: abs ? url.host : undefined,\n hostname: abs ? url.hostname : undefined,\n port: abs ? url.port || undefined : undefined,\n\n // specific to UnknownLocation\n searchParams,\n params: undefined,\n route: undefined,\n exact: false,\n parent: false,\n children: false,\n }\n\n return location\n }\n\n getLocation(href: `${string}://${string}`): KnownLocation<TDefinition>\n getLocation(hrefRel: `/${string}`): KnownLocation<TDefinition>\n getLocation(hrefOrHrefRel: string): KnownLocation<TDefinition>\n getLocation(location: AnyLocation): KnownLocation<TDefinition>\n getLocation(url: AnyLocation): KnownLocation<TDefinition>\n getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): KnownLocation<TDefinition>\n getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): KnownLocation<TDefinition> {\n if (hrefOrHrefRelOrLocation instanceof URL) {\n return this.getLocation(hrefOrHrefRelOrLocation.href)\n }\n if (typeof hrefOrHrefRelOrLocation !== 'string') {\n hrefOrHrefRelOrLocation = hrefOrHrefRelOrLocation.href || hrefOrHrefRelOrLocation.hrefRel\n }\n const location = Route0.getLocation(hrefOrHrefRelOrLocation) as never as KnownLocation<TDefinition>\n location.route = this.definition as Definition<TDefinition>\n location.params = {}\n\n // Normalize pathname (no trailing slash except root)\n const pathname =\n location.pathname.length > 1 && location.pathname.endsWith('/')\n ? location.pathname.slice(0, -1)\n : location.pathname\n\n // Use getRegexString() to get the pattern\n const pattern = this.getRegexString()\n\n // Extract param names from the definition\n const paramNames: string[] = []\n const def =\n this.pathDefinition.length > 1 && this.pathDefinition.endsWith('/')\n ? this.pathDefinition.slice(0, -1)\n : this.pathDefinition\n def.replace(/:([A-Za-z0-9_]+)/g, (_m: string, name: string) => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-conversion\n paramNames.push(String(name))\n return ''\n })\n\n const exactRe = new RegExp(`^${pattern}$`)\n const parentRe = new RegExp(`^${pattern}(?:/.*)?$`) // route matches the beginning of the URL (may have more)\n const exactMatch = pathname.match(exactRe)\n\n // Fill params only for exact match (keeps behavior predictable)\n if (exactMatch) {\n const values = exactMatch.slice(1)\n const params = Object.fromEntries(paramNames.map((n, i) => [n, decodeURIComponent(values[i] ?? '')]))\n location.params = params\n } else {\n location.params = {}\n }\n\n const exact = !!exactMatch\n const parent = !exact && parentRe.test(pathname)\n\n // \"children\": the URL is a prefix of the route definition (params match any single segment)\n const getParts = (path: string) => (path === '/' ? ['/'] : path.split('/').filter(Boolean))\n const defParts = getParts(def)\n const pathParts = getParts(pathname)\n\n let isPrefix = true\n if (pathParts.length > defParts.length) {\n isPrefix = false\n } else {\n for (let i = 0; i < pathParts.length; i++) {\n const defPart = defParts[i]\n const pathPart = pathParts[i]\n if (!defPart) {\n isPrefix = false\n break\n }\n if (defPart.startsWith(':')) continue\n if (defPart !== pathPart) {\n isPrefix = false\n break\n }\n }\n }\n const children = !exact && isPrefix\n\n return {\n ...location,\n exact,\n parent,\n children,\n } as KnownLocation<TDefinition>\n }\n\n isSame(other: Route0<TDefinition>): boolean {\n return (\n this.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__') ===\n other.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__')\n )\n }\n static isSame(a: AnyRoute | string | undefined, b: AnyRoute | string | undefined): boolean {\n if ((!a && b) || (a && !b)) return false\n if (!a || !b) return true\n return Route0.create(a).isSame(Route0.create(b))\n }\n\n isChildren(other: Route0<TDefinition>): boolean {\n return (\n this.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__') ===\n other.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__')\n )\n }\n\n isParent(other: Route0<TDefinition>): boolean {\n return (\n other.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__') ===\n this.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__')\n )\n }\n\n isConflict(other: Route0<any>): boolean {\n const getParts = (path: string) => {\n if (path === '/') return ['/']\n return path.split('/').filter(Boolean)\n }\n\n const thisParts = getParts(this.pathDefinition)\n const otherParts = getParts(other.pathDefinition)\n\n // Different lengths = no conflict (one is deeper than the other)\n if (thisParts.length !== otherParts.length) {\n return false\n }\n\n // Check if all segments could match\n for (let i = 0; i < thisParts.length; i++) {\n const thisPart = thisParts[i]\n const otherPart = otherParts[i]\n\n // Both params = always match\n if (thisPart.startsWith(':') && otherPart.startsWith(':')) {\n continue\n }\n\n // One is param = can match\n if (thisPart.startsWith(':') || otherPart.startsWith(':')) {\n continue\n }\n\n // Both static = must be same\n if (thisPart !== otherPart) {\n return false\n }\n }\n\n return true\n }\n\n isMoreSpecificThan(other: Route0<any>): boolean {\n // More specific = should come earlier when conflicted\n // Static segments beat param segments at the same position\n const getParts = (path: string) => {\n if (path === '/') return ['/']\n return path.split('/').filter(Boolean)\n }\n\n const thisParts = getParts(this.pathDefinition)\n const otherParts = getParts(other.pathDefinition)\n\n // Compare segment by segment\n for (let i = 0; i < Math.min(thisParts.length, otherParts.length); i++) {\n const thisIsStatic = !thisParts[i].startsWith(':')\n const otherIsStatic = !otherParts[i].startsWith(':')\n\n if (thisIsStatic && !otherIsStatic) return true\n if (!thisIsStatic && otherIsStatic) return false\n }\n\n // All equal, use lexicographic\n return this.pathDefinition < other.pathDefinition\n }\n}\n\nexport class Routes<const T extends RoutesRecord = RoutesRecord> {\n readonly routes: RoutesRecordHydrated<T>\n readonly pathsOrdering: string[]\n readonly keysOrdering: string[]\n readonly ordered: CallabelRoute[]\n\n private constructor({\n routes,\n isHydrated = false,\n pathsOrdering,\n keysOrdering,\n ordered,\n }: {\n routes: RoutesRecordHydrated<T> | T\n isHydrated?: boolean\n pathsOrdering?: string[]\n keysOrdering?: string[]\n ordered?: CallabelRoute[]\n }) {\n this.routes = (\n isHydrated ? (routes as RoutesRecordHydrated<T>) : Routes._hydrate(routes)\n ) as RoutesRecordHydrated<T>\n if (!pathsOrdering || !keysOrdering || !ordered) {\n const ordering = Routes._makeOrdering(this.routes)\n this.pathsOrdering = ordering.pathsOrdering\n this.keysOrdering = ordering.keysOrdering\n this.ordered = this.keysOrdering.map((key) => this.routes[key])\n } else {\n this.pathsOrdering = pathsOrdering\n this.keysOrdering = keysOrdering\n this.ordered = ordered\n }\n }\n\n static create<const T extends RoutesRecord>(routes: T): RoutesPretty<T> {\n const instance = new Routes({ routes })\n return Routes._prettify(instance)\n }\n\n static _prettify<const T extends RoutesRecord>(instance: Routes<T>): RoutesPretty<T> {\n Object.setPrototypeOf(instance, Routes.prototype)\n Object.defineProperty(instance, Symbol.toStringTag, {\n value: 'Routes',\n })\n Object.assign(instance, {\n override: instance.override.bind(instance),\n })\n Object.assign(instance, instance.routes)\n return instance as unknown as RoutesPretty<T>\n }\n\n static _hydrate<const T extends RoutesRecord>(routes: T): RoutesRecordHydrated<T> {\n const result = {} as RoutesRecordHydrated<T>\n for (const key in routes) {\n if (Object.prototype.hasOwnProperty.call(routes, key)) {\n const value = routes[key]\n result[key] = (typeof value === 'string' ? Route0.create(value) : value) as CallabelRoute<T[typeof key]>\n }\n }\n return result\n }\n\n getLocation(href: `${string}://${string}`): UnknownLocation | ExactLocation\n getLocation(hrefRel: `/${string}`): UnknownLocation | ExactLocation\n getLocation(hrefOrHrefRel: string): UnknownLocation | ExactLocation\n getLocation(location: AnyLocation): UnknownLocation | ExactLocation\n getLocation(url: URL): UnknownLocation | ExactLocation\n getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation | ExactLocation\n getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation | ExactLocation {\n // Find the route that exactly matches the given location\n const input = hrefOrHrefRelOrLocation\n for (const route of this.ordered) {\n const loc = route.getLocation(hrefOrHrefRelOrLocation)\n if (loc.exact) {\n return loc\n }\n }\n // No exact match found, return UnknownLocation\n return typeof input === 'string' ? Route0.getLocation(input) : Route0.getLocation(input)\n }\n\n static _makeOrdering(routes: RoutesRecord): { pathsOrdering: string[]; keysOrdering: string[] } {\n const hydrated = Routes._hydrate(routes)\n const entries = Object.entries(hydrated)\n\n const getParts = (path: string) => {\n if (path === '/') return ['/']\n return path.split('/').filter(Boolean)\n }\n\n // Sort: shorter paths first, then by specificity, then alphabetically\n entries.sort(([_keyA, routeA], [_keyB, routeB]) => {\n const partsA = getParts(routeA.pathDefinition)\n const partsB = getParts(routeB.pathDefinition)\n\n // 1. Shorter paths first (by segment count)\n if (partsA.length !== partsB.length) {\n return partsA.length - partsB.length\n }\n\n // 2. Same length: check if they conflict\n if (routeA.isConflict(routeB)) {\n // Conflicting routes: more specific first\n if (routeA.isMoreSpecificThan(routeB)) return -1\n if (routeB.isMoreSpecificThan(routeA)) return 1\n }\n\n // 3. Same length, not conflicting or equal specificity: alphabetically\n return routeA.pathDefinition.localeCompare(routeB.pathDefinition)\n })\n\n const pathsOrdering = entries.map(([_key, route]) => route.definition)\n const keysOrdering = entries.map(([_key, route]) => _key)\n return { pathsOrdering, keysOrdering }\n }\n\n override(config: RouteConfigInput): RoutesPretty<T> {\n const newRoutes = {} as RoutesRecordHydrated<T>\n for (const key in this.routes) {\n if (Object.prototype.hasOwnProperty.call(this.routes, key)) {\n newRoutes[key] = this.routes[key].clone(config) as CallabelRoute<T[typeof key]>\n }\n }\n const instance = new Routes({\n routes: newRoutes,\n isHydrated: true,\n pathsOrdering: this.pathsOrdering,\n keysOrdering: this.keysOrdering,\n ordered: this.keysOrdering.map((key) => newRoutes[key]),\n })\n return Routes._prettify(instance)\n }\n}\n\n// main\n\nexport type AnyRoute<T extends Route0<string> | string = string> = T extends string ? Route0<T> : T\nexport type CallabelRoute<T extends Route0<string> | string = string> = AnyRoute<T> & AnyRoute<T>['get']\nexport type AnyRouteOrDefinition<T extends string = string> = AnyRoute<T> | CallabelRoute<T> | T\nexport type RouteConfigInput = {\n baseUrl?: string\n}\n\n// collection\n\nexport type RoutesRecord = Record<string, AnyRoute | string>\nexport type RoutesRecordHydrated<TRoutesRecord extends RoutesRecord = RoutesRecord> = {\n [K in keyof TRoutesRecord]: CallabelRoute<TRoutesRecord[K]>\n}\nexport type RoutesPretty<TRoutesRecord extends RoutesRecord = RoutesRecord> = RoutesRecordHydrated<TRoutesRecord> &\n Routes<TRoutesRecord>\nexport type ExtractRoutesKeys<TRoutes extends RoutesPretty | RoutesRecord> = TRoutes extends RoutesPretty\n ? keyof TRoutes['routes']\n : TRoutes extends RoutesRecord\n ? keyof TRoutes\n : never\nexport type ExtractRoute<\n TRoutes extends RoutesPretty | RoutesRecord,\n TKey extends keyof ExtractRoutesKeys<TRoutes>,\n> = TKey extends keyof TRoutes ? TRoutes[TKey] : never\n\n// public utils\n\nexport type Definition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['definition']\n : T extends string\n ? T\n : never\nexport type PathDefinition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['pathDefinition']\n : T extends string\n ? _PathDefinition<T>\n : never\nexport type ParamsDefinition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['paramsDefinition']\n : T extends string\n ? _ParamsDefinition<T>\n : undefined\nexport type SearchDefinition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['searchDefinition']\n : T extends string\n ? _SearchDefinition<T>\n : undefined\n\nexport type Extended<T extends AnyRoute | string | undefined, TSuffixDefinition extends string> = T extends AnyRoute\n ? Route0<PathExtended<T['definition'], TSuffixDefinition>>\n : T extends string\n ? Route0<PathExtended<T, TSuffixDefinition>>\n : T extends undefined\n ? Route0<TSuffixDefinition>\n : never\n\nexport type IsParent<T extends AnyRoute | string, TParent extends AnyRoute | string> = _IsParent<\n PathDefinition<T>,\n PathDefinition<TParent>\n>\nexport type IsChildren<T extends AnyRoute | string, TChildren extends AnyRoute | string> = _IsChildren<\n PathDefinition<T>,\n PathDefinition<TChildren>\n>\nexport type IsSame<T extends AnyRoute | string, TExact extends AnyRoute | string> = _IsSame<\n PathDefinition<T>,\n PathDefinition<TExact>\n>\nexport type IsSameParams<T1 extends AnyRoute | string, T2 extends AnyRoute | string> = _IsSameParams<\n ParamsDefinition<T1>,\n ParamsDefinition<T2>\n>\n\nexport type HasParams<T extends AnyRoute | string> =\n ExtractPathParams<PathDefinition<T>> extends infer U ? ([U] extends [never] ? false : true) : false\nexport type HasSearch<T extends AnyRoute | string> =\n NonEmpty<SearchTailDefinitionWithoutFirstAmp<Definition<T>>> extends infer Tail extends string\n ? AmpSplit<Tail> extends infer U\n ? [U] extends [never]\n ? false\n : true\n : false\n : false\n\nexport type ParamsOutput<T extends AnyRoute | string> = {\n [K in keyof ParamsDefinition<T>]: string\n}\nexport type SearchOutput<T extends AnyRoute | string = string> = Partial<\n {\n [K in keyof SearchDefinition<T>]?: string\n } & Record<string, string | undefined>\n>\nexport type StrictSearchOutput<T extends AnyRoute | string> = Partial<{\n [K in keyof SearchDefinition<T>]?: string | undefined\n}>\nexport type FlatOutput<T extends AnyRoute | string = string> =\n HasParams<Definition<T>> extends true ? ParamsOutput<T> & SearchOutput<T> : SearchOutput<T>\nexport type StrictFlatOutput<T extends AnyRoute | string> =\n HasParams<Definition<T>> extends true ? ParamsOutput<T> & StrictSearchOutput<T> : StrictSearchOutput<T>\nexport type ParamsInput<T extends AnyRoute | string = string> = _ParamsInput<PathDefinition<T>>\nexport type SearchInput<T extends AnyRoute | string = string> = _SearchInput<Definition<T>>\nexport type StrictSearchInput<T extends AnyRoute | string> = _StrictSearchInput<Definition<T>>\nexport type FlatInput<T extends AnyRoute | string> = _FlatInput<Definition<T>>\nexport type StrictFlatInput<T extends AnyRoute | string> = _StrictFlatInput<Definition<T>>\nexport type CanInputBeEmpty<T extends AnyRoute | string> = HasParams<Definition<T>> extends true ? false : true\n\n// location\n\nexport type LocationParams<TDefinition extends string> = {\n [K in keyof _ParamsDefinition<TDefinition>]: string\n}\nexport type LocationSearch<TDefinition extends string = string> = {\n [K in keyof _SearchDefinition<TDefinition>]: string | undefined\n} & Record<string, string | undefined>\n\nexport type _GeneralLocation = {\n pathname: string\n search: string\n hash: string\n origin?: string\n href?: string\n hrefRel: string\n abs: boolean\n port?: string\n host?: string\n hostname?: string\n}\nexport type UnknownLocation = _GeneralLocation & {\n params: undefined\n searchParams: SearchOutput\n route: undefined\n exact: false\n parent: false\n children: false\n}\nexport type UnmatchedLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & {\n params: Record<never, never>\n searchParams: SearchOutput<TRoute>\n route: Definition<TRoute>\n exact: false\n parent: false\n children: false\n}\nexport type ExactLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & {\n params: ParamsOutput<TRoute>\n searchParams: SearchOutput<TRoute>\n route: Definition<TRoute>\n exact: true\n parent: false\n children: false\n}\nexport type ParentLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & {\n params: Partial<ParamsOutput<TRoute>> // in fact maybe there will be whole params object, but does not matter now\n searchParams: SearchOutput<TRoute>\n route: Definition<TRoute>\n exact: false\n parent: true\n children: false\n}\nexport type ChildrenLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & {\n params: ParamsOutput<TRoute>\n searchParams: SearchOutput<TRoute>\n route: Definition<TRoute>\n exact: false\n parent: false\n children: true\n}\nexport type KnownLocation<TRoute extends AnyRoute | string = AnyRoute | string> =\n | UnmatchedLocation<TRoute>\n | ExactLocation<TRoute>\n | ParentLocation<TRoute>\n | ChildrenLocation<TRoute>\nexport type AnyLocation<TRoute extends AnyRoute = AnyRoute> = UnknownLocation | KnownLocation<TRoute>\n\n// internal utils\n\nexport type _PathDefinition<T extends string> = T extends string ? TrimSearchTailDefinition<T> : never\nexport type _ParamsDefinition<TDefinition extends string> =\n ExtractPathParams<PathDefinition<TDefinition>> extends infer U\n ? [U] extends [never]\n ? undefined\n : { [K in Extract<U, string>]: true }\n : undefined\nexport type _SearchDefinition<TDefinition extends string> =\n NonEmpty<SearchTailDefinitionWithoutFirstAmp<TDefinition>> extends infer Tail extends string\n ? AmpSplit<Tail> extends infer U\n ? [U] extends [never]\n ? undefined\n : { [K in Extract<U, string>]: true }\n : undefined\n : undefined\n\nexport type _ParamsInput<TDefinition extends string> =\n _ParamsDefinition<TDefinition> extends undefined\n ? Record<never, never>\n : {\n [K in keyof _ParamsDefinition<TDefinition>]: string | number\n }\nexport type _SearchInput<TDefinition extends string> =\n _SearchDefinition<TDefinition> extends undefined\n ? Record<string, string | number>\n : Partial<{\n [K in keyof _SearchDefinition<TDefinition>]: string | number\n }> &\n Record<string, string | number>\nexport type _StrictSearchInput<TDefinition extends string> = Partial<{\n [K in keyof _SearchDefinition<TDefinition>]: string | number\n}>\nexport type _FlatInput<TDefinition extends string> =\n HasParams<TDefinition> extends true\n ? _ParamsInput<TDefinition> & _SearchInput<TDefinition>\n : _SearchInput<TDefinition>\nexport type _StrictFlatInput<TDefinition extends string> =\n HasParams<TDefinition> extends true\n ? HasSearch<TDefinition> extends true\n ? _StrictSearchInput<TDefinition> & _ParamsInput<TDefinition>\n : _ParamsInput<TDefinition>\n : HasSearch<TDefinition> extends true\n ? _StrictSearchInput<TDefinition>\n : Record<never, never>\n\nexport type TrimSearchTailDefinition<S extends string> = S extends `${infer P}&${string}` ? P : S\nexport type SearchTailDefinitionWithoutFirstAmp<S extends string> = S extends `${string}&${infer T}` ? T : ''\nexport type SearchTailDefinitionWithFirstAmp<S extends string> = S extends `${string}&${infer T}` ? `&${T}` : ''\nexport type AmpSplit<S extends string> = S extends `${infer A}&${infer B}` ? A | AmpSplit<B> : S\n// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\nexport type NonEmpty<T> = [T] extends ['' | never] ? never : T\nexport type ExtractPathParams<S extends string> = S extends `${string}:${infer After}`\n ? After extends `${infer Name}/${infer Rest}`\n ? Name | ExtractPathParams<`/${Rest}`>\n : After\n : never\nexport type ReplacePathParams<S extends string> = S extends `${infer Head}:${infer Tail}`\n ? // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Tail extends `${infer _Param}/${infer Rest}`\n ? ReplacePathParams<`${Head}${string}/${Rest}`>\n : `${Head}${string}`\n : S\nexport type DedupeSlashes<S extends string> = S extends `${infer A}//${infer B}` ? DedupeSlashes<`${A}/${B}`> : S\nexport type EmptyRecord = Record<never, never>\nexport type JoinPath<Parent extends string, Suffix extends string> = DedupeSlashes<\n PathDefinition<Parent> extends infer A extends string\n ? PathDefinition<Suffix> extends infer B extends string\n ? A extends ''\n ? B extends ''\n ? ''\n : B extends `/${string}`\n ? B\n : `/${B}`\n : B extends ''\n ? A\n : A extends `${string}/`\n ? `${A}${B}`\n : B extends `/${string}`\n ? `${A}${B}`\n : `${A}/${B}`\n : never\n : never\n>\n\nexport type OnlyIfNoParams<TParams extends object | undefined, Yes, No = never> = TParams extends undefined ? Yes : No\nexport type OnlyIfHasParams<TParams extends object | undefined, Yes, No = never> = TParams extends undefined ? No : Yes\n\nexport type PathOnlyRouteValue<TDefinition extends string> = `${ReplacePathParams<PathDefinition<TDefinition>>}`\nexport type WithSearchRouteValue<TDefinition extends string> =\n `${ReplacePathParams<PathDefinition<TDefinition>>}?${string}`\nexport type AbsolutePathOnlyRouteValue<TDefinition extends string> =\n PathOnlyRouteValue<TDefinition> extends '/' ? string : `${string}${PathOnlyRouteValue<TDefinition>}`\nexport type AbsoluteWithSearchRouteValue<TDefinition extends string> = `${string}${WithSearchRouteValue<TDefinition>}`\n\nexport type PathExtended<\n TSourcedefinitionDefinition extends string,\n TSuffixdefinitionDefinition extends string,\n> = `${JoinPath<TSourcedefinitionDefinition, TSuffixdefinitionDefinition>}${SearchTailDefinitionWithFirstAmp<TSuffixdefinitionDefinition>}`\n\nexport type WithParamsInput<\n TDefinition extends string,\n T extends\n | {\n search?: _SearchInput<any>\n abs?: boolean\n }\n | undefined = undefined,\n> = _ParamsInput<TDefinition> & (T extends undefined ? Record<never, never> : T)\n\nexport type _IsSameParams<T1 extends object | undefined, T2 extends object | undefined> = T1 extends undefined\n ? T2 extends undefined\n ? true\n : false\n : T2 extends undefined\n ? false\n : T1 extends T2\n ? T2 extends T1\n ? true\n : false\n : false\n\nexport type _IsParent<T extends string, TParent extends string> = T extends TParent\n ? false\n : T extends `${TParent}${string}`\n ? true\n : false\nexport type _IsChildren<T extends string, TChildren extends string> = TChildren extends T\n ? false\n : TChildren extends `${T}${string}`\n ? true\n : false\nexport type _IsSame<T extends string, TExact extends string> = T extends TExact\n ? TExact extends T\n ? true\n : false\n : false\n"],"mappings":"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","names":["paramsInput","searchInput"]}
1
+ {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["// TODO: asterisk\n// TODO: when asterisk then query params will be extended also after extend\n// TODO: optional params\n// TODO: required search\n\n// TODO: .extension('.json') to not add additional / but just add some extension\n// TODO: search input can be boolean, or even object with qs\n// TODO: Роут0 три пусть три тоже сам генерится вероятно\n// TODO: Роут0 три мод, тогда там все ноуты кончаются на .селф\n// TODO: use splats in param definition \"*\"\n// TODO: ? check extend for search only .extend('&x&z')\n// TODO: .create(route, {useSearch, useParams})\n// TODO: Из пас экзакт, из пасвизквери экзает, из чилдрен, из парент, из экзактОр\n// TODO: isEqual, isChildren, isParent\n// TODO: extractParams, extractSearch\n// TODO: getPathDefinition respecting definitionParamPrefix, definitionSearchPrefix\n// TODO: prepend\n// TODO: Route0.createTree({base:{self: x, children: ...})\n// TODO: overrideTree\n// TODO: .create(route, {baseUrl, useLocation})\n// TODO: ? optional path params as @\n// TODO: prependMany, extendMany, overrideMany, with types\n// TODO: optional route params /x/:id?\n\nexport class Route0<TDefinition extends string> {\n readonly definition: TDefinition\n readonly pathDefinition: _PathDefinition<TDefinition>\n readonly paramsDefinition: _ParamsDefinition<TDefinition>\n readonly searchDefinition: _SearchDefinition<TDefinition>\n baseUrl: string\n\n private constructor(definition: TDefinition, config: RouteConfigInput = {}) {\n this.definition = definition\n this.pathDefinition = Route0._getPathDefinitionBydefinition(definition)\n this.paramsDefinition = Route0._getParamsDefinitionBydefinition(definition)\n this.searchDefinition = Route0._getSearchDefinitionBydefinition(definition)\n\n const { baseUrl } = config\n if (baseUrl && typeof baseUrl === 'string' && baseUrl.length) {\n this.baseUrl = baseUrl\n } else {\n const g = globalThis as unknown as { location?: { origin?: string } }\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (typeof g?.location?.origin === 'string' && g.location.origin.length > 0) {\n this.baseUrl = g.location.origin\n } else {\n this.baseUrl = 'https://example.com'\n }\n }\n }\n\n static create<TDefinition extends string>(\n definition: TDefinition | AnyRoute<TDefinition>,\n config?: RouteConfigInput,\n ): CallabelRoute<TDefinition> {\n if (typeof definition === 'function') {\n return definition\n }\n const original = typeof definition === 'object' ? definition : new Route0<TDefinition>(definition, config)\n const callable = original.get.bind(original)\n Object.setPrototypeOf(callable, original)\n Object.defineProperty(callable, Symbol.toStringTag, {\n value: original.definition,\n })\n return callable as never\n }\n\n private static _splitPathDefinitionAndSearchTailDefinition(definition: string) {\n const i = definition.indexOf('&')\n if (i === -1) return { pathDefinition: definition, searchTailDefinition: '' }\n return {\n pathDefinition: definition.slice(0, i),\n searchTailDefinition: definition.slice(i),\n }\n }\n\n private static _getAbsPath(baseUrl: string, pathWithSearch: string) {\n return new URL(pathWithSearch, baseUrl).toString().replace(/\\/$/, '')\n }\n\n private static _getPathDefinitionBydefinition<TDefinition extends string>(definition: TDefinition) {\n const { pathDefinition } = Route0._splitPathDefinitionAndSearchTailDefinition(definition)\n return pathDefinition as _PathDefinition<TDefinition>\n }\n\n private static _getParamsDefinitionBydefinition<TDefinition extends string>(\n definition: TDefinition,\n ): _ParamsDefinition<TDefinition> {\n const { pathDefinition } = Route0._splitPathDefinitionAndSearchTailDefinition(definition)\n const matches = Array.from(pathDefinition.matchAll(/:([A-Za-z0-9_]+)/g))\n const paramsDefinition = Object.fromEntries(matches.map((m) => [m[1], true]))\n const keysCount = Object.keys(paramsDefinition).length\n if (keysCount === 0) {\n return undefined as _ParamsDefinition<TDefinition>\n }\n return paramsDefinition as _ParamsDefinition<TDefinition>\n }\n\n private static _getSearchDefinitionBydefinition<TDefinition extends string>(\n definition: TDefinition,\n ): _SearchDefinition<TDefinition> {\n const { searchTailDefinition } = Route0._splitPathDefinitionAndSearchTailDefinition(definition)\n if (!searchTailDefinition) {\n return undefined as _SearchDefinition<TDefinition>\n }\n const keys = searchTailDefinition.split('&').filter(Boolean)\n const searchDefinition = Object.fromEntries(keys.map((k) => [k, true]))\n const keysCount = Object.keys(searchDefinition).length\n if (keysCount === 0) {\n return undefined as _SearchDefinition<TDefinition>\n }\n return searchDefinition as _SearchDefinition<TDefinition>\n }\n\n extend<TSuffixDefinition extends string>(\n suffixDefinition: TSuffixDefinition,\n ): CallabelRoute<PathExtended<TDefinition, TSuffixDefinition>> {\n const { pathDefinition: parentPathDefinition } = Route0._splitPathDefinitionAndSearchTailDefinition(this.definition)\n const { pathDefinition: suffixPathDefinition, searchTailDefinition: suffixSearchTailDefinition } =\n Route0._splitPathDefinitionAndSearchTailDefinition(suffixDefinition)\n const pathDefinition = `${parentPathDefinition}/${suffixPathDefinition}`.replace(/\\/{2,}/g, '/')\n const definition = `${pathDefinition}${suffixSearchTailDefinition}` as PathExtended<TDefinition, TSuffixDefinition>\n return Route0.create<PathExtended<TDefinition, TSuffixDefinition>>(definition, { baseUrl: this.baseUrl })\n }\n\n // has params\n get(\n input: OnlyIfHasParams<\n _ParamsDefinition<TDefinition>,\n WithParamsInput<TDefinition, { search?: undefined; abs?: false }>\n >,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, PathOnlyRouteValue<TDefinition>>\n get(\n input: OnlyIfHasParams<\n _ParamsDefinition<TDefinition>,\n WithParamsInput<TDefinition, { search: _SearchInput<TDefinition>; abs?: false }>\n >,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithSearchRouteValue<TDefinition>>\n get(\n input: OnlyIfHasParams<\n _ParamsDefinition<TDefinition>,\n WithParamsInput<TDefinition, { search?: undefined; abs: true }>\n >,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, AbsolutePathOnlyRouteValue<TDefinition>>\n get(\n input: OnlyIfHasParams<\n _ParamsDefinition<TDefinition>,\n WithParamsInput<TDefinition, { search: _SearchInput<TDefinition>; abs: true }>\n >,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, AbsoluteWithSearchRouteValue<TDefinition>>\n\n // no params\n get(...args: OnlyIfNoParams<_ParamsDefinition<TDefinition>, [], [never]>): PathOnlyRouteValue<TDefinition>\n get(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, { search?: undefined; abs?: false }>,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, PathOnlyRouteValue<TDefinition>>\n get(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, { search: _SearchInput<TDefinition>; abs?: false }>,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, WithSearchRouteValue<TDefinition>>\n get(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, { search?: undefined; abs: true }>,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, AbsolutePathOnlyRouteValue<TDefinition>>\n get(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, { search: _SearchInput<TDefinition>; abs: true }>,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, AbsoluteWithSearchRouteValue<TDefinition>>\n\n // implementation\n get(...args: any[]): string {\n const { searchInput, paramsInput, absInput } = ((): {\n searchInput: Record<string, string | number>\n paramsInput: Record<string, string | number>\n absInput: boolean\n } => {\n if (args.length === 0) {\n return { searchInput: {}, paramsInput: {}, absInput: false }\n }\n const input = args[0]\n if (typeof input !== 'object' || input === null) {\n // throw new Error(\"Invalid get route input: expected object\")\n return { searchInput: {}, paramsInput: {}, absInput: false }\n }\n const { search, abs, ...params } = input\n return { searchInput: search || {}, paramsInput: params, absInput: abs ?? false }\n })()\n\n // validate params\n const neededParamsKeys = this.paramsDefinition ? Object.keys(this.paramsDefinition) : []\n const providedParamsKeys = Object.keys(paramsInput)\n const notProvidedKeys = neededParamsKeys.filter((k) => !providedParamsKeys.includes(k))\n if (notProvidedKeys.length) {\n // throw new Error(`Missing params: not defined keys ${notProvidedKeys.map((k) => `\"${k}\"`).join(\", \")}.`)\n Object.assign(paramsInput, Object.fromEntries(notProvidedKeys.map((k) => [k, 'undefined'])))\n }\n\n // create url\n\n let url = this.pathDefinition as string\n // replace params\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n url = url.replace(/:([A-Za-z0-9_]+)/g, (_m, k) => encodeURIComponent(String(paramsInput?.[k] ?? '')))\n // search params\n const searchInputStringified = Object.fromEntries(Object.entries(searchInput).map(([k, v]) => [k, String(v)]))\n url = [url, new URLSearchParams(searchInputStringified).toString()].filter(Boolean).join('?')\n // dedupe slashes\n url = url.replace(/\\/{2,}/g, '/')\n // absolute\n url = absInput ? Route0._getAbsPath(this.baseUrl, url) : url\n\n return url\n }\n\n // has params\n flat(\n input: OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithParamsInput<TDefinition>>,\n abs?: false,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, PathOnlyRouteValue<TDefinition>>\n flat(\n input: OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithParamsInput<TDefinition, _SearchInput<TDefinition>>>,\n abs?: false,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithSearchRouteValue<TDefinition>>\n flat(\n input: OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithParamsInput<TDefinition>>,\n abs: true,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, AbsolutePathOnlyRouteValue<TDefinition>>\n flat(\n input: OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithParamsInput<TDefinition, _SearchInput<TDefinition>>>,\n abs: true,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, AbsoluteWithSearchRouteValue<TDefinition>>\n\n // no params\n flat(...args: OnlyIfNoParams<_ParamsDefinition<TDefinition>, [], [never]>): PathOnlyRouteValue<TDefinition>\n flat(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, Record<never, never>>,\n abs?: false,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, PathOnlyRouteValue<TDefinition>>\n flat(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, _SearchInput<TDefinition>>,\n abs?: false,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, WithSearchRouteValue<TDefinition>>\n flat(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, Record<never, never>>,\n abs: true,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, AbsolutePathOnlyRouteValue<TDefinition>>\n flat(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, _SearchInput<TDefinition>>,\n abs: true,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, AbsoluteWithSearchRouteValue<TDefinition>>\n\n // implementation\n flat(...args: any[]): string {\n const { searchInput, paramsInput, absInput } = ((): {\n searchInput: Record<string, string | number>\n paramsInput: Record<string, string | number>\n absInput: boolean\n } => {\n if (args.length === 0) {\n return { searchInput: {}, paramsInput: {}, absInput: false }\n }\n const input = args[0]\n if (typeof input !== 'object' || input === null) {\n // throw new Error(\"Invalid get route input: expected object\")\n return { searchInput: {}, paramsInput: {}, absInput: args[1] ?? false }\n }\n const paramsKeys = this.getParamsKeys()\n const paramsInput = paramsKeys.reduce<Record<string, string | number>>((acc, key) => {\n if (input[key] !== undefined) {\n acc[key] = input[key]\n }\n return acc\n }, {})\n const searchKeys = this.getSearchKeys()\n const searchInput = Object.keys(input)\n .filter((k) => {\n if (searchKeys.includes(k)) {\n return true\n }\n if (paramsKeys.includes(k)) {\n return false\n }\n return true\n })\n .reduce<Record<string, string | number>>((acc, key) => {\n acc[key] = input[key]\n return acc\n }, {})\n return { searchInput, paramsInput, absInput: args[1] ?? false }\n })()\n\n return this.get({ ...paramsInput, search: searchInput, abs: absInput } as never)\n }\n\n getParamsKeys(): string[] {\n return Object.keys(this.paramsDefinition || {})\n }\n getSearchKeys(): string[] {\n return Object.keys(this.searchDefinition || {})\n }\n getFlatKeys(): string[] {\n return [...this.getSearchKeys(), ...this.getParamsKeys()]\n }\n\n getDefinition(): string {\n return this.pathDefinition\n }\n\n clone(config?: RouteConfigInput): Route0<TDefinition> {\n return new Route0(this.definition, config)\n }\n\n getRegexString(): string {\n // Normalize the path definition (remove trailing slash except for root)\n const def =\n this.pathDefinition.length > 1 && this.pathDefinition.endsWith('/')\n ? this.pathDefinition.slice(0, -1)\n : this.pathDefinition\n\n // Replace :param with placeholders, escape regex special chars, then restore capture groups\n const pattern = def\n .replace(/:([A-Za-z0-9_]+)/g, '___PARAM___') // temporarily replace params with placeholder\n .replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') // escape regex special chars\n .replace(/___PARAM___/g, '([^/]+)') // replace placeholder with capture group\n\n return pattern\n }\n\n getRegex(): RegExp {\n return new RegExp(`^${this.getRegexString()}$`)\n }\n\n static getRegexString(routes: AnyRoute[] | AnyRoute): string {\n const routesArray = Array.isArray(routes) ? routes : [routes]\n return routesArray.map((route) => route.getRegexString()).join('|')\n }\n static getRegex(routes: AnyRoute[] | AnyRoute): RegExp {\n return new RegExp(`^(${Route0.getRegexString(routes)})$`)\n }\n\n static getLocation(href: `${string}://${string}`): UnknownLocation\n static getLocation(hrefRel: `/${string}`): UnknownLocation\n static getLocation(hrefOrHrefRel: string): UnknownLocation\n static getLocation(location: AnyLocation): UnknownLocation\n static getLocation(url: URL): UnknownLocation\n static getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation\n static getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation {\n if (hrefOrHrefRelOrLocation instanceof URL) {\n return Route0.getLocation(hrefOrHrefRelOrLocation.href)\n }\n if (typeof hrefOrHrefRelOrLocation !== 'string') {\n hrefOrHrefRelOrLocation = hrefOrHrefRelOrLocation.href || hrefOrHrefRelOrLocation.hrefRel\n }\n // Check if it's an absolute URL (starts with scheme://)\n const abs = /^[a-zA-Z][a-zA-Z\\d+\\-.]*:\\/\\//.test(hrefOrHrefRelOrLocation)\n\n // Use dummy base only if relative\n const base = abs ? undefined : 'http://example.com'\n const url = new URL(hrefOrHrefRelOrLocation, base)\n\n // Extract search params\n const searchParams = Object.fromEntries(url.searchParams.entries())\n\n // Normalize pathname (remove trailing slash except for root)\n let pathname = url.pathname\n if (pathname.length > 1 && pathname.endsWith('/')) {\n pathname = pathname.slice(0, -1)\n }\n\n // Common derived values\n const hrefRel = pathname + url.search + url.hash\n\n // Build the location object consistent with _GeneralLocation\n const location: UnknownLocation = {\n pathname,\n search: url.search,\n hash: url.hash,\n origin: abs ? url.origin : undefined,\n href: abs ? url.href : undefined,\n hrefRel,\n abs,\n\n // extra host-related fields (available even for relative with dummy base)\n host: abs ? url.host : undefined,\n hostname: abs ? url.hostname : undefined,\n port: abs ? url.port || undefined : undefined,\n\n // specific to UnknownLocation\n searchParams,\n params: undefined,\n route: undefined,\n exact: false,\n parent: false,\n children: false,\n }\n\n return location\n }\n\n getLocation(href: `${string}://${string}`): KnownLocation<TDefinition>\n getLocation(hrefRel: `/${string}`): KnownLocation<TDefinition>\n getLocation(hrefOrHrefRel: string): KnownLocation<TDefinition>\n getLocation(location: AnyLocation): KnownLocation<TDefinition>\n getLocation(url: AnyLocation): KnownLocation<TDefinition>\n getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): KnownLocation<TDefinition>\n getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): KnownLocation<TDefinition> {\n if (hrefOrHrefRelOrLocation instanceof URL) {\n return this.getLocation(hrefOrHrefRelOrLocation.href)\n }\n if (typeof hrefOrHrefRelOrLocation !== 'string') {\n hrefOrHrefRelOrLocation = hrefOrHrefRelOrLocation.href || hrefOrHrefRelOrLocation.hrefRel\n }\n const location = Route0.getLocation(hrefOrHrefRelOrLocation) as never as KnownLocation<TDefinition>\n location.route = this.definition as Definition<TDefinition>\n location.params = {}\n\n // Normalize pathname (no trailing slash except root)\n const pathname =\n location.pathname.length > 1 && location.pathname.endsWith('/')\n ? location.pathname.slice(0, -1)\n : location.pathname\n\n // Use getRegexString() to get the pattern\n const pattern = this.getRegexString()\n\n // Extract param names from the definition\n const paramNames: string[] = []\n const def =\n this.pathDefinition.length > 1 && this.pathDefinition.endsWith('/')\n ? this.pathDefinition.slice(0, -1)\n : this.pathDefinition\n def.replace(/:([A-Za-z0-9_]+)/g, (_m: string, name: string) => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-conversion\n paramNames.push(String(name))\n return ''\n })\n\n const exactRe = new RegExp(`^${pattern}$`)\n const parentRe = new RegExp(`^${pattern}(?:/.*)?$`) // route matches the beginning of the URL (may have more)\n const exactMatch = pathname.match(exactRe)\n\n // Fill params only for exact match (keeps behavior predictable)\n if (exactMatch) {\n const values = exactMatch.slice(1)\n const params = Object.fromEntries(paramNames.map((n, i) => [n, decodeURIComponent(values[i] ?? '')]))\n location.params = params\n } else {\n location.params = {}\n }\n\n const exact = !!exactMatch\n const parent = !exact && parentRe.test(pathname)\n\n // \"children\": the URL is a prefix of the route definition (params match any single segment)\n const getParts = (path: string) => (path === '/' ? ['/'] : path.split('/').filter(Boolean))\n const defParts = getParts(def)\n const pathParts = getParts(pathname)\n\n let isPrefix = true\n if (pathParts.length > defParts.length) {\n isPrefix = false\n } else {\n for (let i = 0; i < pathParts.length; i++) {\n const defPart = defParts[i]\n const pathPart = pathParts[i]\n if (!defPart) {\n isPrefix = false\n break\n }\n if (defPart.startsWith(':')) continue\n if (defPart !== pathPart) {\n isPrefix = false\n break\n }\n }\n }\n const children = !exact && isPrefix\n\n return {\n ...location,\n exact,\n parent,\n children,\n } as KnownLocation<TDefinition>\n }\n\n isSame(other: Route0<TDefinition>): boolean {\n return (\n this.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__') ===\n other.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__')\n )\n }\n static isSame(a: AnyRoute | string | undefined, b: AnyRoute | string | undefined): boolean {\n if ((!a && b) || (a && !b)) return false\n if (!a || !b) return true\n return Route0.create(a).isSame(Route0.create(b))\n }\n\n isChildren(other: Route0<TDefinition>): boolean {\n return (\n this.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__') ===\n other.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__')\n )\n }\n\n isParent(other: Route0<TDefinition>): boolean {\n return (\n other.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__') ===\n this.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__')\n )\n }\n\n isConflict(other: Route0<any>): boolean {\n const getParts = (path: string) => {\n if (path === '/') return ['/']\n return path.split('/').filter(Boolean)\n }\n\n const thisParts = getParts(this.pathDefinition)\n const otherParts = getParts(other.pathDefinition)\n\n // Different lengths = no conflict (one is deeper than the other)\n if (thisParts.length !== otherParts.length) {\n return false\n }\n\n // Check if all segments could match\n for (let i = 0; i < thisParts.length; i++) {\n const thisPart = thisParts[i]\n const otherPart = otherParts[i]\n\n // Both params = always match\n if (thisPart.startsWith(':') && otherPart.startsWith(':')) {\n continue\n }\n\n // One is param = can match\n if (thisPart.startsWith(':') || otherPart.startsWith(':')) {\n continue\n }\n\n // Both static = must be same\n if (thisPart !== otherPart) {\n return false\n }\n }\n\n return true\n }\n\n isMoreSpecificThan(other: Route0<any>): boolean {\n // More specific = should come earlier when conflicted\n // Static segments beat param segments at the same position\n const getParts = (path: string) => {\n if (path === '/') return ['/']\n return path.split('/').filter(Boolean)\n }\n\n const thisParts = getParts(this.pathDefinition)\n const otherParts = getParts(other.pathDefinition)\n\n // Compare segment by segment\n for (let i = 0; i < Math.min(thisParts.length, otherParts.length); i++) {\n const thisIsStatic = !thisParts[i].startsWith(':')\n const otherIsStatic = !otherParts[i].startsWith(':')\n\n if (thisIsStatic && !otherIsStatic) return true\n if (!thisIsStatic && otherIsStatic) return false\n }\n\n // All equal, use lexicographic\n return this.pathDefinition < other.pathDefinition\n }\n}\n\nexport class Routes<const T extends RoutesRecord = RoutesRecord> {\n private readonly routes: RoutesRecordHydrated<T>\n private readonly pathsOrdering: string[]\n private readonly keysOrdering: string[]\n private readonly ordered: CallabelRoute[]\n\n _: {\n getLocation: Routes<T>['getLocation']\n override: Routes<T>['override']\n pathsOrdering: Routes<T>['pathsOrdering']\n keysOrdering: Routes<T>['keysOrdering']\n ordered: Routes<T>['ordered']\n }\n\n private constructor({\n routes,\n isHydrated = false,\n pathsOrdering,\n keysOrdering,\n ordered,\n }: {\n routes: RoutesRecordHydrated<T> | T\n isHydrated?: boolean\n pathsOrdering?: string[]\n keysOrdering?: string[]\n ordered?: CallabelRoute[]\n }) {\n this.routes = (isHydrated ? (routes as RoutesRecordHydrated<T>) : Routes.hydrate(routes)) as RoutesRecordHydrated<T>\n if (!pathsOrdering || !keysOrdering || !ordered) {\n const ordering = Routes.makeOrdering(this.routes)\n this.pathsOrdering = ordering.pathsOrdering\n this.keysOrdering = ordering.keysOrdering\n this.ordered = this.keysOrdering.map((key) => this.routes[key])\n } else {\n this.pathsOrdering = pathsOrdering\n this.keysOrdering = keysOrdering\n this.ordered = ordered\n }\n this._ = {\n getLocation: this.getLocation.bind(this),\n override: this.override.bind(this),\n pathsOrdering: this.pathsOrdering,\n keysOrdering: this.keysOrdering,\n ordered: this.ordered,\n }\n }\n\n static create<const T extends RoutesRecord>(routes: T): RoutesPretty<T> {\n const instance = new Routes({ routes })\n return Routes.prettify(instance)\n }\n\n private static prettify<const T extends RoutesRecord>(instance: Routes<T>): RoutesPretty<T> {\n Object.setPrototypeOf(instance, Routes.prototype)\n Object.defineProperty(instance, Symbol.toStringTag, {\n value: 'Routes',\n })\n Object.assign(instance, {\n override: instance.override.bind(instance),\n })\n Object.assign(instance, instance.routes)\n return instance as unknown as RoutesPretty<T>\n }\n\n private static hydrate<const T extends RoutesRecord>(routes: T): RoutesRecordHydrated<T> {\n const result = {} as RoutesRecordHydrated<T>\n for (const key in routes) {\n if (Object.prototype.hasOwnProperty.call(routes, key)) {\n const value = routes[key]\n result[key] = (typeof value === 'string' ? Route0.create(value) : value) as CallabelRoute<T[typeof key]>\n }\n }\n return result\n }\n\n private getLocation(href: `${string}://${string}`): UnknownLocation | ExactLocation\n private getLocation(hrefRel: `/${string}`): UnknownLocation | ExactLocation\n private getLocation(hrefOrHrefRel: string): UnknownLocation | ExactLocation\n private getLocation(location: AnyLocation): UnknownLocation | ExactLocation\n private getLocation(url: URL): UnknownLocation | ExactLocation\n private getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation | ExactLocation\n private getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation | ExactLocation {\n // Find the route that exactly matches the given location\n const input = hrefOrHrefRelOrLocation\n for (const route of this.ordered) {\n const loc = route.getLocation(hrefOrHrefRelOrLocation)\n if (loc.exact) {\n return loc\n }\n }\n // No exact match found, return UnknownLocation\n return typeof input === 'string' ? Route0.getLocation(input) : Route0.getLocation(input)\n }\n\n private static makeOrdering(routes: RoutesRecord): { pathsOrdering: string[]; keysOrdering: string[] } {\n const hydrated = Routes.hydrate(routes)\n const entries = Object.entries(hydrated)\n\n const getParts = (path: string) => {\n if (path === '/') return ['/']\n return path.split('/').filter(Boolean)\n }\n\n // Sort: shorter paths first, then by specificity, then alphabetically\n entries.sort(([_keyA, routeA], [_keyB, routeB]) => {\n const partsA = getParts(routeA.pathDefinition)\n const partsB = getParts(routeB.pathDefinition)\n\n // 1. Shorter paths first (by segment count)\n if (partsA.length !== partsB.length) {\n return partsA.length - partsB.length\n }\n\n // 2. Same length: check if they conflict\n if (routeA.isConflict(routeB)) {\n // Conflicting routes: more specific first\n if (routeA.isMoreSpecificThan(routeB)) return -1\n if (routeB.isMoreSpecificThan(routeA)) return 1\n }\n\n // 3. Same length, not conflicting or equal specificity: alphabetically\n return routeA.pathDefinition.localeCompare(routeB.pathDefinition)\n })\n\n const pathsOrdering = entries.map(([_key, route]) => route.definition)\n const keysOrdering = entries.map(([_key, route]) => _key)\n return { pathsOrdering, keysOrdering }\n }\n\n private override(config: RouteConfigInput): RoutesPretty<T> {\n const newRoutes = {} as RoutesRecordHydrated<T>\n for (const key in this.routes) {\n if (Object.prototype.hasOwnProperty.call(this.routes, key)) {\n newRoutes[key] = this.routes[key].clone(config) as CallabelRoute<T[typeof key]>\n }\n }\n const instance = new Routes({\n routes: newRoutes,\n isHydrated: true,\n pathsOrdering: this.pathsOrdering,\n keysOrdering: this.keysOrdering,\n ordered: this.keysOrdering.map((key) => newRoutes[key]),\n })\n return Routes.prettify(instance)\n }\n\n static _ = {\n prettify: Routes.prettify.bind(Routes),\n hydrate: Routes.hydrate.bind(Routes),\n makeOrdering: Routes.makeOrdering.bind(Routes),\n }\n}\n\n// main\n\nexport type AnyRoute<T extends Route0<string> | string = string> = T extends string ? Route0<T> : T\nexport type CallabelRoute<T extends Route0<string> | string = string> = AnyRoute<T> & AnyRoute<T>['get']\nexport type AnyRouteOrDefinition<T extends string = string> = AnyRoute<T> | CallabelRoute<T> | T\nexport type RouteConfigInput = {\n baseUrl?: string\n}\n\n// collection\n\nexport type RoutesRecord = Record<string, AnyRoute | string>\nexport type RoutesRecordHydrated<TRoutesRecord extends RoutesRecord = RoutesRecord> = {\n [K in keyof TRoutesRecord]: CallabelRoute<TRoutesRecord[K]>\n}\nexport type RoutesPretty<TRoutesRecord extends RoutesRecord = RoutesRecord> = RoutesRecordHydrated<TRoutesRecord> &\n Routes<TRoutesRecord>\nexport type ExtractRoutesKeys<TRoutes extends RoutesPretty | RoutesRecord> = TRoutes extends RoutesPretty\n ? keyof TRoutes['routes']\n : TRoutes extends RoutesRecord\n ? keyof TRoutes\n : never\nexport type ExtractRoute<\n TRoutes extends RoutesPretty | RoutesRecord,\n TKey extends keyof ExtractRoutesKeys<TRoutes>,\n> = TKey extends keyof TRoutes ? TRoutes[TKey] : never\n\n// public utils\n\nexport type Definition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['definition']\n : T extends string\n ? T\n : never\nexport type PathDefinition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['pathDefinition']\n : T extends string\n ? _PathDefinition<T>\n : never\nexport type ParamsDefinition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['paramsDefinition']\n : T extends string\n ? _ParamsDefinition<T>\n : undefined\nexport type SearchDefinition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['searchDefinition']\n : T extends string\n ? _SearchDefinition<T>\n : undefined\n\nexport type Extended<T extends AnyRoute | string | undefined, TSuffixDefinition extends string> = T extends AnyRoute\n ? Route0<PathExtended<T['definition'], TSuffixDefinition>>\n : T extends string\n ? Route0<PathExtended<T, TSuffixDefinition>>\n : T extends undefined\n ? Route0<TSuffixDefinition>\n : never\n\nexport type IsParent<T extends AnyRoute | string, TParent extends AnyRoute | string> = _IsParent<\n PathDefinition<T>,\n PathDefinition<TParent>\n>\nexport type IsChildren<T extends AnyRoute | string, TChildren extends AnyRoute | string> = _IsChildren<\n PathDefinition<T>,\n PathDefinition<TChildren>\n>\nexport type IsSame<T extends AnyRoute | string, TExact extends AnyRoute | string> = _IsSame<\n PathDefinition<T>,\n PathDefinition<TExact>\n>\nexport type IsSameParams<T1 extends AnyRoute | string, T2 extends AnyRoute | string> = _IsSameParams<\n ParamsDefinition<T1>,\n ParamsDefinition<T2>\n>\n\nexport type HasParams<T extends AnyRoute | string> =\n ExtractPathParams<PathDefinition<T>> extends infer U ? ([U] extends [never] ? false : true) : false\nexport type HasSearch<T extends AnyRoute | string> =\n NonEmpty<SearchTailDefinitionWithoutFirstAmp<Definition<T>>> extends infer Tail extends string\n ? AmpSplit<Tail> extends infer U\n ? [U] extends [never]\n ? false\n : true\n : false\n : false\n\nexport type ParamsOutput<T extends AnyRoute | string> = {\n [K in keyof ParamsDefinition<T>]: string\n}\nexport type SearchOutput<T extends AnyRoute | string = string> = Partial<\n {\n [K in keyof SearchDefinition<T>]?: string\n } & Record<string, string | undefined>\n>\nexport type StrictSearchOutput<T extends AnyRoute | string> = Partial<{\n [K in keyof SearchDefinition<T>]?: string | undefined\n}>\nexport type FlatOutput<T extends AnyRoute | string = string> =\n HasParams<Definition<T>> extends true ? ParamsOutput<T> & SearchOutput<T> : SearchOutput<T>\nexport type StrictFlatOutput<T extends AnyRoute | string> =\n HasParams<Definition<T>> extends true ? ParamsOutput<T> & StrictSearchOutput<T> : StrictSearchOutput<T>\nexport type ParamsInput<T extends AnyRoute | string = string> = _ParamsInput<PathDefinition<T>>\nexport type SearchInput<T extends AnyRoute | string = string> = _SearchInput<Definition<T>>\nexport type StrictSearchInput<T extends AnyRoute | string> = _StrictSearchInput<Definition<T>>\nexport type FlatInput<T extends AnyRoute | string> = _FlatInput<Definition<T>>\nexport type StrictFlatInput<T extends AnyRoute | string> = _StrictFlatInput<Definition<T>>\nexport type CanInputBeEmpty<T extends AnyRoute | string> = HasParams<Definition<T>> extends true ? false : true\n\n// location\n\nexport type LocationParams<TDefinition extends string> = {\n [K in keyof _ParamsDefinition<TDefinition>]: string\n}\nexport type LocationSearch<TDefinition extends string = string> = {\n [K in keyof _SearchDefinition<TDefinition>]: string | undefined\n} & Record<string, string | undefined>\n\nexport type _GeneralLocation = {\n pathname: string\n search: string\n hash: string\n origin?: string\n href?: string\n hrefRel: string\n abs: boolean\n port?: string\n host?: string\n hostname?: string\n}\nexport type UnknownLocation = _GeneralLocation & {\n params: undefined\n searchParams: SearchOutput\n route: undefined\n exact: false\n parent: false\n children: false\n}\nexport type UnmatchedLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & {\n params: Record<never, never>\n searchParams: SearchOutput<TRoute>\n route: Definition<TRoute>\n exact: false\n parent: false\n children: false\n}\nexport type ExactLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & {\n params: ParamsOutput<TRoute>\n searchParams: SearchOutput<TRoute>\n route: Definition<TRoute>\n exact: true\n parent: false\n children: false\n}\nexport type ParentLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & {\n params: Partial<ParamsOutput<TRoute>> // in fact maybe there will be whole params object, but does not matter now\n searchParams: SearchOutput<TRoute>\n route: Definition<TRoute>\n exact: false\n parent: true\n children: false\n}\nexport type ChildrenLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & {\n params: ParamsOutput<TRoute>\n searchParams: SearchOutput<TRoute>\n route: Definition<TRoute>\n exact: false\n parent: false\n children: true\n}\nexport type KnownLocation<TRoute extends AnyRoute | string = AnyRoute | string> =\n | UnmatchedLocation<TRoute>\n | ExactLocation<TRoute>\n | ParentLocation<TRoute>\n | ChildrenLocation<TRoute>\nexport type AnyLocation<TRoute extends AnyRoute = AnyRoute> = UnknownLocation | KnownLocation<TRoute>\n\n// internal utils\n\nexport type _PathDefinition<T extends string> = T extends string ? TrimSearchTailDefinition<T> : never\nexport type _ParamsDefinition<TDefinition extends string> =\n ExtractPathParams<PathDefinition<TDefinition>> extends infer U\n ? [U] extends [never]\n ? undefined\n : { [K in Extract<U, string>]: true }\n : undefined\nexport type _SearchDefinition<TDefinition extends string> =\n NonEmpty<SearchTailDefinitionWithoutFirstAmp<TDefinition>> extends infer Tail extends string\n ? AmpSplit<Tail> extends infer U\n ? [U] extends [never]\n ? undefined\n : { [K in Extract<U, string>]: true }\n : undefined\n : undefined\n\nexport type _ParamsInput<TDefinition extends string> =\n _ParamsDefinition<TDefinition> extends undefined\n ? Record<never, never>\n : {\n [K in keyof _ParamsDefinition<TDefinition>]: string | number\n }\nexport type _SearchInput<TDefinition extends string> =\n _SearchDefinition<TDefinition> extends undefined\n ? Record<string, string | number>\n : Partial<{\n [K in keyof _SearchDefinition<TDefinition>]: string | number\n }> &\n Record<string, string | number>\nexport type _StrictSearchInput<TDefinition extends string> = Partial<{\n [K in keyof _SearchDefinition<TDefinition>]: string | number\n}>\nexport type _FlatInput<TDefinition extends string> =\n HasParams<TDefinition> extends true\n ? _ParamsInput<TDefinition> & _SearchInput<TDefinition>\n : _SearchInput<TDefinition>\nexport type _StrictFlatInput<TDefinition extends string> =\n HasParams<TDefinition> extends true\n ? HasSearch<TDefinition> extends true\n ? _StrictSearchInput<TDefinition> & _ParamsInput<TDefinition>\n : _ParamsInput<TDefinition>\n : HasSearch<TDefinition> extends true\n ? _StrictSearchInput<TDefinition>\n : Record<never, never>\n\nexport type TrimSearchTailDefinition<S extends string> = S extends `${infer P}&${string}` ? P : S\nexport type SearchTailDefinitionWithoutFirstAmp<S extends string> = S extends `${string}&${infer T}` ? T : ''\nexport type SearchTailDefinitionWithFirstAmp<S extends string> = S extends `${string}&${infer T}` ? `&${T}` : ''\nexport type AmpSplit<S extends string> = S extends `${infer A}&${infer B}` ? A | AmpSplit<B> : S\n// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\nexport type NonEmpty<T> = [T] extends ['' | never] ? never : T\nexport type ExtractPathParams<S extends string> = S extends `${string}:${infer After}`\n ? After extends `${infer Name}/${infer Rest}`\n ? Name | ExtractPathParams<`/${Rest}`>\n : After\n : never\nexport type ReplacePathParams<S extends string> = S extends `${infer Head}:${infer Tail}`\n ? // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Tail extends `${infer _Param}/${infer Rest}`\n ? ReplacePathParams<`${Head}${string}/${Rest}`>\n : `${Head}${string}`\n : S\nexport type DedupeSlashes<S extends string> = S extends `${infer A}//${infer B}` ? DedupeSlashes<`${A}/${B}`> : S\nexport type EmptyRecord = Record<never, never>\nexport type JoinPath<Parent extends string, Suffix extends string> = DedupeSlashes<\n PathDefinition<Parent> extends infer A extends string\n ? PathDefinition<Suffix> extends infer B extends string\n ? A extends ''\n ? B extends ''\n ? ''\n : B extends `/${string}`\n ? B\n : `/${B}`\n : B extends ''\n ? A\n : A extends `${string}/`\n ? `${A}${B}`\n : B extends `/${string}`\n ? `${A}${B}`\n : `${A}/${B}`\n : never\n : never\n>\n\nexport type OnlyIfNoParams<TParams extends object | undefined, Yes, No = never> = TParams extends undefined ? Yes : No\nexport type OnlyIfHasParams<TParams extends object | undefined, Yes, No = never> = TParams extends undefined ? No : Yes\n\nexport type PathOnlyRouteValue<TDefinition extends string> = `${ReplacePathParams<PathDefinition<TDefinition>>}`\nexport type WithSearchRouteValue<TDefinition extends string> =\n `${ReplacePathParams<PathDefinition<TDefinition>>}?${string}`\nexport type AbsolutePathOnlyRouteValue<TDefinition extends string> =\n PathOnlyRouteValue<TDefinition> extends '/' ? string : `${string}${PathOnlyRouteValue<TDefinition>}`\nexport type AbsoluteWithSearchRouteValue<TDefinition extends string> = `${string}${WithSearchRouteValue<TDefinition>}`\n\nexport type PathExtended<\n TSourcedefinitionDefinition extends string,\n TSuffixdefinitionDefinition extends string,\n> = `${JoinPath<TSourcedefinitionDefinition, TSuffixdefinitionDefinition>}${SearchTailDefinitionWithFirstAmp<TSuffixdefinitionDefinition>}`\n\nexport type WithParamsInput<\n TDefinition extends string,\n T extends\n | {\n search?: _SearchInput<any>\n abs?: boolean\n }\n | undefined = undefined,\n> = _ParamsInput<TDefinition> & (T extends undefined ? Record<never, never> : T)\n\nexport type _IsSameParams<T1 extends object | undefined, T2 extends object | undefined> = T1 extends undefined\n ? T2 extends undefined\n ? true\n : false\n : T2 extends undefined\n ? false\n : T1 extends T2\n ? T2 extends T1\n ? true\n : false\n : false\n\nexport type _IsParent<T extends string, TParent extends string> = T extends TParent\n ? false\n : T extends `${TParent}${string}`\n ? true\n : false\nexport type _IsChildren<T extends string, TChildren extends string> = TChildren extends T\n ? false\n : TChildren extends `${T}${string}`\n ? true\n : false\nexport type _IsSame<T extends string, TExact extends string> = T extends TExact\n ? TExact extends T\n ? true\n : false\n : false\n"],"mappings":"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","names":["paramsInput","searchInput"]}
@@ -83,25 +83,29 @@ declare class Route0<TDefinition extends string> {
83
83
  isMoreSpecificThan(other: Route0<any>): boolean;
84
84
  }
85
85
  declare class Routes<const T extends RoutesRecord = RoutesRecord> {
86
- readonly routes: RoutesRecordHydrated<T>;
87
- readonly pathsOrdering: string[];
88
- readonly keysOrdering: string[];
89
- readonly ordered: CallabelRoute[];
86
+ private readonly routes;
87
+ private readonly pathsOrdering;
88
+ private readonly keysOrdering;
89
+ private readonly ordered;
90
+ _: {
91
+ getLocation: Routes<T>['getLocation'];
92
+ override: Routes<T>['override'];
93
+ pathsOrdering: Routes<T>['pathsOrdering'];
94
+ keysOrdering: Routes<T>['keysOrdering'];
95
+ ordered: Routes<T>['ordered'];
96
+ };
90
97
  private constructor();
91
98
  static create<const T extends RoutesRecord>(routes: T): RoutesPretty<T>;
92
- static _prettify<const T extends RoutesRecord>(instance: Routes<T>): RoutesPretty<T>;
93
- static _hydrate<const T extends RoutesRecord>(routes: T): RoutesRecordHydrated<T>;
94
- getLocation(href: `${string}://${string}`): UnknownLocation | ExactLocation;
95
- getLocation(hrefRel: `/${string}`): UnknownLocation | ExactLocation;
96
- getLocation(hrefOrHrefRel: string): UnknownLocation | ExactLocation;
97
- getLocation(location: AnyLocation): UnknownLocation | ExactLocation;
98
- getLocation(url: URL): UnknownLocation | ExactLocation;
99
- getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation | ExactLocation;
100
- static _makeOrdering(routes: RoutesRecord): {
101
- pathsOrdering: string[];
102
- keysOrdering: string[];
99
+ private static prettify;
100
+ private static hydrate;
101
+ private getLocation;
102
+ private static makeOrdering;
103
+ private override;
104
+ static _: {
105
+ prettify: typeof Routes.prettify;
106
+ hydrate: typeof Routes.hydrate;
107
+ makeOrdering: typeof Routes.makeOrdering;
103
108
  };
104
- override(config: RouteConfigInput): RoutesPretty<T>;
105
109
  }
106
110
  type AnyRoute<T extends Route0<string> | string = string> = T extends string ? Route0<T> : T;
107
111
  type CallabelRoute<T extends Route0<string> | string = string> = AnyRoute<T> & AnyRoute<T>['get'];
@@ -83,25 +83,29 @@ declare class Route0<TDefinition extends string> {
83
83
  isMoreSpecificThan(other: Route0<any>): boolean;
84
84
  }
85
85
  declare class Routes<const T extends RoutesRecord = RoutesRecord> {
86
- readonly routes: RoutesRecordHydrated<T>;
87
- readonly pathsOrdering: string[];
88
- readonly keysOrdering: string[];
89
- readonly ordered: CallabelRoute[];
86
+ private readonly routes;
87
+ private readonly pathsOrdering;
88
+ private readonly keysOrdering;
89
+ private readonly ordered;
90
+ _: {
91
+ getLocation: Routes<T>['getLocation'];
92
+ override: Routes<T>['override'];
93
+ pathsOrdering: Routes<T>['pathsOrdering'];
94
+ keysOrdering: Routes<T>['keysOrdering'];
95
+ ordered: Routes<T>['ordered'];
96
+ };
90
97
  private constructor();
91
98
  static create<const T extends RoutesRecord>(routes: T): RoutesPretty<T>;
92
- static _prettify<const T extends RoutesRecord>(instance: Routes<T>): RoutesPretty<T>;
93
- static _hydrate<const T extends RoutesRecord>(routes: T): RoutesRecordHydrated<T>;
94
- getLocation(href: `${string}://${string}`): UnknownLocation | ExactLocation;
95
- getLocation(hrefRel: `/${string}`): UnknownLocation | ExactLocation;
96
- getLocation(hrefOrHrefRel: string): UnknownLocation | ExactLocation;
97
- getLocation(location: AnyLocation): UnknownLocation | ExactLocation;
98
- getLocation(url: URL): UnknownLocation | ExactLocation;
99
- getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation | ExactLocation;
100
- static _makeOrdering(routes: RoutesRecord): {
101
- pathsOrdering: string[];
102
- keysOrdering: string[];
99
+ private static prettify;
100
+ private static hydrate;
101
+ private getLocation;
102
+ private static makeOrdering;
103
+ private override;
104
+ static _: {
105
+ prettify: typeof Routes.prettify;
106
+ hydrate: typeof Routes.hydrate;
107
+ makeOrdering: typeof Routes.makeOrdering;
103
108
  };
104
- override(config: RouteConfigInput): RoutesPretty<T>;
105
109
  }
106
110
  type AnyRoute<T extends Route0<string> | string = string> = T extends string ? Route0<T> : T;
107
111
  type CallabelRoute<T extends Route0<string> | string = string> = AnyRoute<T> & AnyRoute<T>['get'];
package/dist/esm/index.js CHANGED
@@ -326,6 +326,7 @@ class Routes {
326
326
  pathsOrdering;
327
327
  keysOrdering;
328
328
  ordered;
329
+ _;
329
330
  constructor({
330
331
  routes,
331
332
  isHydrated = false,
@@ -333,9 +334,9 @@ class Routes {
333
334
  keysOrdering,
334
335
  ordered
335
336
  }) {
336
- this.routes = isHydrated ? routes : Routes._hydrate(routes);
337
+ this.routes = isHydrated ? routes : Routes.hydrate(routes);
337
338
  if (!pathsOrdering || !keysOrdering || !ordered) {
338
- const ordering = Routes._makeOrdering(this.routes);
339
+ const ordering = Routes.makeOrdering(this.routes);
339
340
  this.pathsOrdering = ordering.pathsOrdering;
340
341
  this.keysOrdering = ordering.keysOrdering;
341
342
  this.ordered = this.keysOrdering.map((key) => this.routes[key]);
@@ -344,12 +345,19 @@ class Routes {
344
345
  this.keysOrdering = keysOrdering;
345
346
  this.ordered = ordered;
346
347
  }
348
+ this._ = {
349
+ getLocation: this.getLocation.bind(this),
350
+ override: this.override.bind(this),
351
+ pathsOrdering: this.pathsOrdering,
352
+ keysOrdering: this.keysOrdering,
353
+ ordered: this.ordered
354
+ };
347
355
  }
348
356
  static create(routes) {
349
357
  const instance = new Routes({ routes });
350
- return Routes._prettify(instance);
358
+ return Routes.prettify(instance);
351
359
  }
352
- static _prettify(instance) {
360
+ static prettify(instance) {
353
361
  Object.setPrototypeOf(instance, Routes.prototype);
354
362
  Object.defineProperty(instance, Symbol.toStringTag, {
355
363
  value: "Routes"
@@ -360,7 +368,7 @@ class Routes {
360
368
  Object.assign(instance, instance.routes);
361
369
  return instance;
362
370
  }
363
- static _hydrate(routes) {
371
+ static hydrate(routes) {
364
372
  const result = {};
365
373
  for (const key in routes) {
366
374
  if (Object.prototype.hasOwnProperty.call(routes, key)) {
@@ -380,8 +388,8 @@ class Routes {
380
388
  }
381
389
  return typeof input === "string" ? Route0.getLocation(input) : Route0.getLocation(input);
382
390
  }
383
- static _makeOrdering(routes) {
384
- const hydrated = Routes._hydrate(routes);
391
+ static makeOrdering(routes) {
392
+ const hydrated = Routes.hydrate(routes);
385
393
  const entries = Object.entries(hydrated);
386
394
  const getParts = (path) => {
387
395
  if (path === "/") return ["/"];
@@ -417,8 +425,13 @@ class Routes {
417
425
  keysOrdering: this.keysOrdering,
418
426
  ordered: this.keysOrdering.map((key) => newRoutes[key])
419
427
  });
420
- return Routes._prettify(instance);
428
+ return Routes.prettify(instance);
421
429
  }
430
+ static _ = {
431
+ prettify: Routes.prettify.bind(Routes),
432
+ hydrate: Routes.hydrate.bind(Routes),
433
+ makeOrdering: Routes.makeOrdering.bind(Routes)
434
+ };
422
435
  }
423
436
  export {
424
437
  Route0,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["// TODO: asterisk\n// TODO: when asterisk then query params will be extended also after extend\n// TODO: optional params\n// TODO: required search\n\n// TODO: .extension('.json') to not add additional / but just add some extension\n// TODO: search input can be boolean, or even object with qs\n// TODO: Роут0 три пусть три тоже сам генерится вероятно\n// TODO: Роут0 три мод, тогда там все ноуты кончаются на .селф\n// TODO: use splats in param definition \"*\"\n// TODO: ? check extend for search only .extend('&x&z')\n// TODO: .create(route, {useSearch, useParams})\n// TODO: Из пас экзакт, из пасвизквери экзает, из чилдрен, из парент, из экзактОр\n// TODO: isEqual, isChildren, isParent\n// TODO: extractParams, extractSearch\n// TODO: getPathDefinition respecting definitionParamPrefix, definitionSearchPrefix\n// TODO: prepend\n// TODO: Route0.createTree({base:{self: x, children: ...})\n// TODO: overrideTree\n// TODO: .create(route, {baseUrl, useLocation})\n// TODO: ? optional path params as @\n// TODO: prependMany, extendMany, overrideMany, with types\n// TODO: optional route params /x/:id?\n\nexport class Route0<TDefinition extends string> {\n readonly definition: TDefinition\n readonly pathDefinition: _PathDefinition<TDefinition>\n readonly paramsDefinition: _ParamsDefinition<TDefinition>\n readonly searchDefinition: _SearchDefinition<TDefinition>\n baseUrl: string\n\n private constructor(definition: TDefinition, config: RouteConfigInput = {}) {\n this.definition = definition\n this.pathDefinition = Route0._getPathDefinitionBydefinition(definition)\n this.paramsDefinition = Route0._getParamsDefinitionBydefinition(definition)\n this.searchDefinition = Route0._getSearchDefinitionBydefinition(definition)\n\n const { baseUrl } = config\n if (baseUrl && typeof baseUrl === 'string' && baseUrl.length) {\n this.baseUrl = baseUrl\n } else {\n const g = globalThis as unknown as { location?: { origin?: string } }\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (typeof g?.location?.origin === 'string' && g.location.origin.length > 0) {\n this.baseUrl = g.location.origin\n } else {\n this.baseUrl = 'https://example.com'\n }\n }\n }\n\n static create<TDefinition extends string>(\n definition: TDefinition | AnyRoute<TDefinition>,\n config?: RouteConfigInput,\n ): CallabelRoute<TDefinition> {\n if (typeof definition === 'function') {\n return definition\n }\n const original = typeof definition === 'object' ? definition : new Route0<TDefinition>(definition, config)\n const callable = original.get.bind(original)\n Object.setPrototypeOf(callable, original)\n Object.defineProperty(callable, Symbol.toStringTag, {\n value: original.definition,\n })\n return callable as never\n }\n\n private static _splitPathDefinitionAndSearchTailDefinition(definition: string) {\n const i = definition.indexOf('&')\n if (i === -1) return { pathDefinition: definition, searchTailDefinition: '' }\n return {\n pathDefinition: definition.slice(0, i),\n searchTailDefinition: definition.slice(i),\n }\n }\n\n private static _getAbsPath(baseUrl: string, pathWithSearch: string) {\n return new URL(pathWithSearch, baseUrl).toString().replace(/\\/$/, '')\n }\n\n private static _getPathDefinitionBydefinition<TDefinition extends string>(definition: TDefinition) {\n const { pathDefinition } = Route0._splitPathDefinitionAndSearchTailDefinition(definition)\n return pathDefinition as _PathDefinition<TDefinition>\n }\n\n private static _getParamsDefinitionBydefinition<TDefinition extends string>(\n definition: TDefinition,\n ): _ParamsDefinition<TDefinition> {\n const { pathDefinition } = Route0._splitPathDefinitionAndSearchTailDefinition(definition)\n const matches = Array.from(pathDefinition.matchAll(/:([A-Za-z0-9_]+)/g))\n const paramsDefinition = Object.fromEntries(matches.map((m) => [m[1], true]))\n const keysCount = Object.keys(paramsDefinition).length\n if (keysCount === 0) {\n return undefined as _ParamsDefinition<TDefinition>\n }\n return paramsDefinition as _ParamsDefinition<TDefinition>\n }\n\n private static _getSearchDefinitionBydefinition<TDefinition extends string>(\n definition: TDefinition,\n ): _SearchDefinition<TDefinition> {\n const { searchTailDefinition } = Route0._splitPathDefinitionAndSearchTailDefinition(definition)\n if (!searchTailDefinition) {\n return undefined as _SearchDefinition<TDefinition>\n }\n const keys = searchTailDefinition.split('&').filter(Boolean)\n const searchDefinition = Object.fromEntries(keys.map((k) => [k, true]))\n const keysCount = Object.keys(searchDefinition).length\n if (keysCount === 0) {\n return undefined as _SearchDefinition<TDefinition>\n }\n return searchDefinition as _SearchDefinition<TDefinition>\n }\n\n extend<TSuffixDefinition extends string>(\n suffixDefinition: TSuffixDefinition,\n ): CallabelRoute<PathExtended<TDefinition, TSuffixDefinition>> {\n const { pathDefinition: parentPathDefinition } = Route0._splitPathDefinitionAndSearchTailDefinition(this.definition)\n const { pathDefinition: suffixPathDefinition, searchTailDefinition: suffixSearchTailDefinition } =\n Route0._splitPathDefinitionAndSearchTailDefinition(suffixDefinition)\n const pathDefinition = `${parentPathDefinition}/${suffixPathDefinition}`.replace(/\\/{2,}/g, '/')\n const definition = `${pathDefinition}${suffixSearchTailDefinition}` as PathExtended<TDefinition, TSuffixDefinition>\n return Route0.create<PathExtended<TDefinition, TSuffixDefinition>>(definition, { baseUrl: this.baseUrl })\n }\n\n // has params\n get(\n input: OnlyIfHasParams<\n _ParamsDefinition<TDefinition>,\n WithParamsInput<TDefinition, { search?: undefined; abs?: false }>\n >,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, PathOnlyRouteValue<TDefinition>>\n get(\n input: OnlyIfHasParams<\n _ParamsDefinition<TDefinition>,\n WithParamsInput<TDefinition, { search: _SearchInput<TDefinition>; abs?: false }>\n >,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithSearchRouteValue<TDefinition>>\n get(\n input: OnlyIfHasParams<\n _ParamsDefinition<TDefinition>,\n WithParamsInput<TDefinition, { search?: undefined; abs: true }>\n >,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, AbsolutePathOnlyRouteValue<TDefinition>>\n get(\n input: OnlyIfHasParams<\n _ParamsDefinition<TDefinition>,\n WithParamsInput<TDefinition, { search: _SearchInput<TDefinition>; abs: true }>\n >,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, AbsoluteWithSearchRouteValue<TDefinition>>\n\n // no params\n get(...args: OnlyIfNoParams<_ParamsDefinition<TDefinition>, [], [never]>): PathOnlyRouteValue<TDefinition>\n get(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, { search?: undefined; abs?: false }>,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, PathOnlyRouteValue<TDefinition>>\n get(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, { search: _SearchInput<TDefinition>; abs?: false }>,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, WithSearchRouteValue<TDefinition>>\n get(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, { search?: undefined; abs: true }>,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, AbsolutePathOnlyRouteValue<TDefinition>>\n get(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, { search: _SearchInput<TDefinition>; abs: true }>,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, AbsoluteWithSearchRouteValue<TDefinition>>\n\n // implementation\n get(...args: any[]): string {\n const { searchInput, paramsInput, absInput } = ((): {\n searchInput: Record<string, string | number>\n paramsInput: Record<string, string | number>\n absInput: boolean\n } => {\n if (args.length === 0) {\n return { searchInput: {}, paramsInput: {}, absInput: false }\n }\n const input = args[0]\n if (typeof input !== 'object' || input === null) {\n // throw new Error(\"Invalid get route input: expected object\")\n return { searchInput: {}, paramsInput: {}, absInput: false }\n }\n const { search, abs, ...params } = input\n return { searchInput: search || {}, paramsInput: params, absInput: abs ?? false }\n })()\n\n // validate params\n const neededParamsKeys = this.paramsDefinition ? Object.keys(this.paramsDefinition) : []\n const providedParamsKeys = Object.keys(paramsInput)\n const notProvidedKeys = neededParamsKeys.filter((k) => !providedParamsKeys.includes(k))\n if (notProvidedKeys.length) {\n // throw new Error(`Missing params: not defined keys ${notProvidedKeys.map((k) => `\"${k}\"`).join(\", \")}.`)\n Object.assign(paramsInput, Object.fromEntries(notProvidedKeys.map((k) => [k, 'undefined'])))\n }\n\n // create url\n\n let url = this.pathDefinition as string\n // replace params\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n url = url.replace(/:([A-Za-z0-9_]+)/g, (_m, k) => encodeURIComponent(String(paramsInput?.[k] ?? '')))\n // search params\n const searchInputStringified = Object.fromEntries(Object.entries(searchInput).map(([k, v]) => [k, String(v)]))\n url = [url, new URLSearchParams(searchInputStringified).toString()].filter(Boolean).join('?')\n // dedupe slashes\n url = url.replace(/\\/{2,}/g, '/')\n // absolute\n url = absInput ? Route0._getAbsPath(this.baseUrl, url) : url\n\n return url\n }\n\n // has params\n flat(\n input: OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithParamsInput<TDefinition>>,\n abs?: false,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, PathOnlyRouteValue<TDefinition>>\n flat(\n input: OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithParamsInput<TDefinition, _SearchInput<TDefinition>>>,\n abs?: false,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithSearchRouteValue<TDefinition>>\n flat(\n input: OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithParamsInput<TDefinition>>,\n abs: true,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, AbsolutePathOnlyRouteValue<TDefinition>>\n flat(\n input: OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithParamsInput<TDefinition, _SearchInput<TDefinition>>>,\n abs: true,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, AbsoluteWithSearchRouteValue<TDefinition>>\n\n // no params\n flat(...args: OnlyIfNoParams<_ParamsDefinition<TDefinition>, [], [never]>): PathOnlyRouteValue<TDefinition>\n flat(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, Record<never, never>>,\n abs?: false,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, PathOnlyRouteValue<TDefinition>>\n flat(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, _SearchInput<TDefinition>>,\n abs?: false,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, WithSearchRouteValue<TDefinition>>\n flat(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, Record<never, never>>,\n abs: true,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, AbsolutePathOnlyRouteValue<TDefinition>>\n flat(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, _SearchInput<TDefinition>>,\n abs: true,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, AbsoluteWithSearchRouteValue<TDefinition>>\n\n // implementation\n flat(...args: any[]): string {\n const { searchInput, paramsInput, absInput } = ((): {\n searchInput: Record<string, string | number>\n paramsInput: Record<string, string | number>\n absInput: boolean\n } => {\n if (args.length === 0) {\n return { searchInput: {}, paramsInput: {}, absInput: false }\n }\n const input = args[0]\n if (typeof input !== 'object' || input === null) {\n // throw new Error(\"Invalid get route input: expected object\")\n return { searchInput: {}, paramsInput: {}, absInput: args[1] ?? false }\n }\n const paramsKeys = this.getParamsKeys()\n const paramsInput = paramsKeys.reduce<Record<string, string | number>>((acc, key) => {\n if (input[key] !== undefined) {\n acc[key] = input[key]\n }\n return acc\n }, {})\n const searchKeys = this.getSearchKeys()\n const searchInput = Object.keys(input)\n .filter((k) => {\n if (searchKeys.includes(k)) {\n return true\n }\n if (paramsKeys.includes(k)) {\n return false\n }\n return true\n })\n .reduce<Record<string, string | number>>((acc, key) => {\n acc[key] = input[key]\n return acc\n }, {})\n return { searchInput, paramsInput, absInput: args[1] ?? false }\n })()\n\n return this.get({ ...paramsInput, search: searchInput, abs: absInput } as never)\n }\n\n getParamsKeys(): string[] {\n return Object.keys(this.paramsDefinition || {})\n }\n getSearchKeys(): string[] {\n return Object.keys(this.searchDefinition || {})\n }\n getFlatKeys(): string[] {\n return [...this.getSearchKeys(), ...this.getParamsKeys()]\n }\n\n getDefinition(): string {\n return this.pathDefinition\n }\n\n clone(config?: RouteConfigInput): Route0<TDefinition> {\n return new Route0(this.definition, config)\n }\n\n getRegexString(): string {\n // Normalize the path definition (remove trailing slash except for root)\n const def =\n this.pathDefinition.length > 1 && this.pathDefinition.endsWith('/')\n ? this.pathDefinition.slice(0, -1)\n : this.pathDefinition\n\n // Replace :param with placeholders, escape regex special chars, then restore capture groups\n const pattern = def\n .replace(/:([A-Za-z0-9_]+)/g, '___PARAM___') // temporarily replace params with placeholder\n .replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') // escape regex special chars\n .replace(/___PARAM___/g, '([^/]+)') // replace placeholder with capture group\n\n return pattern\n }\n\n getRegex(): RegExp {\n return new RegExp(`^${this.getRegexString()}$`)\n }\n\n static getRegexString(routes: AnyRoute[] | AnyRoute): string {\n const routesArray = Array.isArray(routes) ? routes : [routes]\n return routesArray.map((route) => route.getRegexString()).join('|')\n }\n static getRegex(routes: AnyRoute[] | AnyRoute): RegExp {\n return new RegExp(`^(${Route0.getRegexString(routes)})$`)\n }\n\n static getLocation(href: `${string}://${string}`): UnknownLocation\n static getLocation(hrefRel: `/${string}`): UnknownLocation\n static getLocation(hrefOrHrefRel: string): UnknownLocation\n static getLocation(location: AnyLocation): UnknownLocation\n static getLocation(url: URL): UnknownLocation\n static getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation\n static getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation {\n if (hrefOrHrefRelOrLocation instanceof URL) {\n return Route0.getLocation(hrefOrHrefRelOrLocation.href)\n }\n if (typeof hrefOrHrefRelOrLocation !== 'string') {\n hrefOrHrefRelOrLocation = hrefOrHrefRelOrLocation.href || hrefOrHrefRelOrLocation.hrefRel\n }\n // Check if it's an absolute URL (starts with scheme://)\n const abs = /^[a-zA-Z][a-zA-Z\\d+\\-.]*:\\/\\//.test(hrefOrHrefRelOrLocation)\n\n // Use dummy base only if relative\n const base = abs ? undefined : 'http://example.com'\n const url = new URL(hrefOrHrefRelOrLocation, base)\n\n // Extract search params\n const searchParams = Object.fromEntries(url.searchParams.entries())\n\n // Normalize pathname (remove trailing slash except for root)\n let pathname = url.pathname\n if (pathname.length > 1 && pathname.endsWith('/')) {\n pathname = pathname.slice(0, -1)\n }\n\n // Common derived values\n const hrefRel = pathname + url.search + url.hash\n\n // Build the location object consistent with _GeneralLocation\n const location: UnknownLocation = {\n pathname,\n search: url.search,\n hash: url.hash,\n origin: abs ? url.origin : undefined,\n href: abs ? url.href : undefined,\n hrefRel,\n abs,\n\n // extra host-related fields (available even for relative with dummy base)\n host: abs ? url.host : undefined,\n hostname: abs ? url.hostname : undefined,\n port: abs ? url.port || undefined : undefined,\n\n // specific to UnknownLocation\n searchParams,\n params: undefined,\n route: undefined,\n exact: false,\n parent: false,\n children: false,\n }\n\n return location\n }\n\n getLocation(href: `${string}://${string}`): KnownLocation<TDefinition>\n getLocation(hrefRel: `/${string}`): KnownLocation<TDefinition>\n getLocation(hrefOrHrefRel: string): KnownLocation<TDefinition>\n getLocation(location: AnyLocation): KnownLocation<TDefinition>\n getLocation(url: AnyLocation): KnownLocation<TDefinition>\n getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): KnownLocation<TDefinition>\n getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): KnownLocation<TDefinition> {\n if (hrefOrHrefRelOrLocation instanceof URL) {\n return this.getLocation(hrefOrHrefRelOrLocation.href)\n }\n if (typeof hrefOrHrefRelOrLocation !== 'string') {\n hrefOrHrefRelOrLocation = hrefOrHrefRelOrLocation.href || hrefOrHrefRelOrLocation.hrefRel\n }\n const location = Route0.getLocation(hrefOrHrefRelOrLocation) as never as KnownLocation<TDefinition>\n location.route = this.definition as Definition<TDefinition>\n location.params = {}\n\n // Normalize pathname (no trailing slash except root)\n const pathname =\n location.pathname.length > 1 && location.pathname.endsWith('/')\n ? location.pathname.slice(0, -1)\n : location.pathname\n\n // Use getRegexString() to get the pattern\n const pattern = this.getRegexString()\n\n // Extract param names from the definition\n const paramNames: string[] = []\n const def =\n this.pathDefinition.length > 1 && this.pathDefinition.endsWith('/')\n ? this.pathDefinition.slice(0, -1)\n : this.pathDefinition\n def.replace(/:([A-Za-z0-9_]+)/g, (_m: string, name: string) => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-conversion\n paramNames.push(String(name))\n return ''\n })\n\n const exactRe = new RegExp(`^${pattern}$`)\n const parentRe = new RegExp(`^${pattern}(?:/.*)?$`) // route matches the beginning of the URL (may have more)\n const exactMatch = pathname.match(exactRe)\n\n // Fill params only for exact match (keeps behavior predictable)\n if (exactMatch) {\n const values = exactMatch.slice(1)\n const params = Object.fromEntries(paramNames.map((n, i) => [n, decodeURIComponent(values[i] ?? '')]))\n location.params = params\n } else {\n location.params = {}\n }\n\n const exact = !!exactMatch\n const parent = !exact && parentRe.test(pathname)\n\n // \"children\": the URL is a prefix of the route definition (params match any single segment)\n const getParts = (path: string) => (path === '/' ? ['/'] : path.split('/').filter(Boolean))\n const defParts = getParts(def)\n const pathParts = getParts(pathname)\n\n let isPrefix = true\n if (pathParts.length > defParts.length) {\n isPrefix = false\n } else {\n for (let i = 0; i < pathParts.length; i++) {\n const defPart = defParts[i]\n const pathPart = pathParts[i]\n if (!defPart) {\n isPrefix = false\n break\n }\n if (defPart.startsWith(':')) continue\n if (defPart !== pathPart) {\n isPrefix = false\n break\n }\n }\n }\n const children = !exact && isPrefix\n\n return {\n ...location,\n exact,\n parent,\n children,\n } as KnownLocation<TDefinition>\n }\n\n isSame(other: Route0<TDefinition>): boolean {\n return (\n this.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__') ===\n other.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__')\n )\n }\n static isSame(a: AnyRoute | string | undefined, b: AnyRoute | string | undefined): boolean {\n if ((!a && b) || (a && !b)) return false\n if (!a || !b) return true\n return Route0.create(a).isSame(Route0.create(b))\n }\n\n isChildren(other: Route0<TDefinition>): boolean {\n return (\n this.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__') ===\n other.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__')\n )\n }\n\n isParent(other: Route0<TDefinition>): boolean {\n return (\n other.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__') ===\n this.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__')\n )\n }\n\n isConflict(other: Route0<any>): boolean {\n const getParts = (path: string) => {\n if (path === '/') return ['/']\n return path.split('/').filter(Boolean)\n }\n\n const thisParts = getParts(this.pathDefinition)\n const otherParts = getParts(other.pathDefinition)\n\n // Different lengths = no conflict (one is deeper than the other)\n if (thisParts.length !== otherParts.length) {\n return false\n }\n\n // Check if all segments could match\n for (let i = 0; i < thisParts.length; i++) {\n const thisPart = thisParts[i]\n const otherPart = otherParts[i]\n\n // Both params = always match\n if (thisPart.startsWith(':') && otherPart.startsWith(':')) {\n continue\n }\n\n // One is param = can match\n if (thisPart.startsWith(':') || otherPart.startsWith(':')) {\n continue\n }\n\n // Both static = must be same\n if (thisPart !== otherPart) {\n return false\n }\n }\n\n return true\n }\n\n isMoreSpecificThan(other: Route0<any>): boolean {\n // More specific = should come earlier when conflicted\n // Static segments beat param segments at the same position\n const getParts = (path: string) => {\n if (path === '/') return ['/']\n return path.split('/').filter(Boolean)\n }\n\n const thisParts = getParts(this.pathDefinition)\n const otherParts = getParts(other.pathDefinition)\n\n // Compare segment by segment\n for (let i = 0; i < Math.min(thisParts.length, otherParts.length); i++) {\n const thisIsStatic = !thisParts[i].startsWith(':')\n const otherIsStatic = !otherParts[i].startsWith(':')\n\n if (thisIsStatic && !otherIsStatic) return true\n if (!thisIsStatic && otherIsStatic) return false\n }\n\n // All equal, use lexicographic\n return this.pathDefinition < other.pathDefinition\n }\n}\n\nexport class Routes<const T extends RoutesRecord = RoutesRecord> {\n readonly routes: RoutesRecordHydrated<T>\n readonly pathsOrdering: string[]\n readonly keysOrdering: string[]\n readonly ordered: CallabelRoute[]\n\n private constructor({\n routes,\n isHydrated = false,\n pathsOrdering,\n keysOrdering,\n ordered,\n }: {\n routes: RoutesRecordHydrated<T> | T\n isHydrated?: boolean\n pathsOrdering?: string[]\n keysOrdering?: string[]\n ordered?: CallabelRoute[]\n }) {\n this.routes = (\n isHydrated ? (routes as RoutesRecordHydrated<T>) : Routes._hydrate(routes)\n ) as RoutesRecordHydrated<T>\n if (!pathsOrdering || !keysOrdering || !ordered) {\n const ordering = Routes._makeOrdering(this.routes)\n this.pathsOrdering = ordering.pathsOrdering\n this.keysOrdering = ordering.keysOrdering\n this.ordered = this.keysOrdering.map((key) => this.routes[key])\n } else {\n this.pathsOrdering = pathsOrdering\n this.keysOrdering = keysOrdering\n this.ordered = ordered\n }\n }\n\n static create<const T extends RoutesRecord>(routes: T): RoutesPretty<T> {\n const instance = new Routes({ routes })\n return Routes._prettify(instance)\n }\n\n static _prettify<const T extends RoutesRecord>(instance: Routes<T>): RoutesPretty<T> {\n Object.setPrototypeOf(instance, Routes.prototype)\n Object.defineProperty(instance, Symbol.toStringTag, {\n value: 'Routes',\n })\n Object.assign(instance, {\n override: instance.override.bind(instance),\n })\n Object.assign(instance, instance.routes)\n return instance as unknown as RoutesPretty<T>\n }\n\n static _hydrate<const T extends RoutesRecord>(routes: T): RoutesRecordHydrated<T> {\n const result = {} as RoutesRecordHydrated<T>\n for (const key in routes) {\n if (Object.prototype.hasOwnProperty.call(routes, key)) {\n const value = routes[key]\n result[key] = (typeof value === 'string' ? Route0.create(value) : value) as CallabelRoute<T[typeof key]>\n }\n }\n return result\n }\n\n getLocation(href: `${string}://${string}`): UnknownLocation | ExactLocation\n getLocation(hrefRel: `/${string}`): UnknownLocation | ExactLocation\n getLocation(hrefOrHrefRel: string): UnknownLocation | ExactLocation\n getLocation(location: AnyLocation): UnknownLocation | ExactLocation\n getLocation(url: URL): UnknownLocation | ExactLocation\n getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation | ExactLocation\n getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation | ExactLocation {\n // Find the route that exactly matches the given location\n const input = hrefOrHrefRelOrLocation\n for (const route of this.ordered) {\n const loc = route.getLocation(hrefOrHrefRelOrLocation)\n if (loc.exact) {\n return loc\n }\n }\n // No exact match found, return UnknownLocation\n return typeof input === 'string' ? Route0.getLocation(input) : Route0.getLocation(input)\n }\n\n static _makeOrdering(routes: RoutesRecord): { pathsOrdering: string[]; keysOrdering: string[] } {\n const hydrated = Routes._hydrate(routes)\n const entries = Object.entries(hydrated)\n\n const getParts = (path: string) => {\n if (path === '/') return ['/']\n return path.split('/').filter(Boolean)\n }\n\n // Sort: shorter paths first, then by specificity, then alphabetically\n entries.sort(([_keyA, routeA], [_keyB, routeB]) => {\n const partsA = getParts(routeA.pathDefinition)\n const partsB = getParts(routeB.pathDefinition)\n\n // 1. Shorter paths first (by segment count)\n if (partsA.length !== partsB.length) {\n return partsA.length - partsB.length\n }\n\n // 2. Same length: check if they conflict\n if (routeA.isConflict(routeB)) {\n // Conflicting routes: more specific first\n if (routeA.isMoreSpecificThan(routeB)) return -1\n if (routeB.isMoreSpecificThan(routeA)) return 1\n }\n\n // 3. Same length, not conflicting or equal specificity: alphabetically\n return routeA.pathDefinition.localeCompare(routeB.pathDefinition)\n })\n\n const pathsOrdering = entries.map(([_key, route]) => route.definition)\n const keysOrdering = entries.map(([_key, route]) => _key)\n return { pathsOrdering, keysOrdering }\n }\n\n override(config: RouteConfigInput): RoutesPretty<T> {\n const newRoutes = {} as RoutesRecordHydrated<T>\n for (const key in this.routes) {\n if (Object.prototype.hasOwnProperty.call(this.routes, key)) {\n newRoutes[key] = this.routes[key].clone(config) as CallabelRoute<T[typeof key]>\n }\n }\n const instance = new Routes({\n routes: newRoutes,\n isHydrated: true,\n pathsOrdering: this.pathsOrdering,\n keysOrdering: this.keysOrdering,\n ordered: this.keysOrdering.map((key) => newRoutes[key]),\n })\n return Routes._prettify(instance)\n }\n}\n\n// main\n\nexport type AnyRoute<T extends Route0<string> | string = string> = T extends string ? Route0<T> : T\nexport type CallabelRoute<T extends Route0<string> | string = string> = AnyRoute<T> & AnyRoute<T>['get']\nexport type AnyRouteOrDefinition<T extends string = string> = AnyRoute<T> | CallabelRoute<T> | T\nexport type RouteConfigInput = {\n baseUrl?: string\n}\n\n// collection\n\nexport type RoutesRecord = Record<string, AnyRoute | string>\nexport type RoutesRecordHydrated<TRoutesRecord extends RoutesRecord = RoutesRecord> = {\n [K in keyof TRoutesRecord]: CallabelRoute<TRoutesRecord[K]>\n}\nexport type RoutesPretty<TRoutesRecord extends RoutesRecord = RoutesRecord> = RoutesRecordHydrated<TRoutesRecord> &\n Routes<TRoutesRecord>\nexport type ExtractRoutesKeys<TRoutes extends RoutesPretty | RoutesRecord> = TRoutes extends RoutesPretty\n ? keyof TRoutes['routes']\n : TRoutes extends RoutesRecord\n ? keyof TRoutes\n : never\nexport type ExtractRoute<\n TRoutes extends RoutesPretty | RoutesRecord,\n TKey extends keyof ExtractRoutesKeys<TRoutes>,\n> = TKey extends keyof TRoutes ? TRoutes[TKey] : never\n\n// public utils\n\nexport type Definition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['definition']\n : T extends string\n ? T\n : never\nexport type PathDefinition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['pathDefinition']\n : T extends string\n ? _PathDefinition<T>\n : never\nexport type ParamsDefinition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['paramsDefinition']\n : T extends string\n ? _ParamsDefinition<T>\n : undefined\nexport type SearchDefinition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['searchDefinition']\n : T extends string\n ? _SearchDefinition<T>\n : undefined\n\nexport type Extended<T extends AnyRoute | string | undefined, TSuffixDefinition extends string> = T extends AnyRoute\n ? Route0<PathExtended<T['definition'], TSuffixDefinition>>\n : T extends string\n ? Route0<PathExtended<T, TSuffixDefinition>>\n : T extends undefined\n ? Route0<TSuffixDefinition>\n : never\n\nexport type IsParent<T extends AnyRoute | string, TParent extends AnyRoute | string> = _IsParent<\n PathDefinition<T>,\n PathDefinition<TParent>\n>\nexport type IsChildren<T extends AnyRoute | string, TChildren extends AnyRoute | string> = _IsChildren<\n PathDefinition<T>,\n PathDefinition<TChildren>\n>\nexport type IsSame<T extends AnyRoute | string, TExact extends AnyRoute | string> = _IsSame<\n PathDefinition<T>,\n PathDefinition<TExact>\n>\nexport type IsSameParams<T1 extends AnyRoute | string, T2 extends AnyRoute | string> = _IsSameParams<\n ParamsDefinition<T1>,\n ParamsDefinition<T2>\n>\n\nexport type HasParams<T extends AnyRoute | string> =\n ExtractPathParams<PathDefinition<T>> extends infer U ? ([U] extends [never] ? false : true) : false\nexport type HasSearch<T extends AnyRoute | string> =\n NonEmpty<SearchTailDefinitionWithoutFirstAmp<Definition<T>>> extends infer Tail extends string\n ? AmpSplit<Tail> extends infer U\n ? [U] extends [never]\n ? false\n : true\n : false\n : false\n\nexport type ParamsOutput<T extends AnyRoute | string> = {\n [K in keyof ParamsDefinition<T>]: string\n}\nexport type SearchOutput<T extends AnyRoute | string = string> = Partial<\n {\n [K in keyof SearchDefinition<T>]?: string\n } & Record<string, string | undefined>\n>\nexport type StrictSearchOutput<T extends AnyRoute | string> = Partial<{\n [K in keyof SearchDefinition<T>]?: string | undefined\n}>\nexport type FlatOutput<T extends AnyRoute | string = string> =\n HasParams<Definition<T>> extends true ? ParamsOutput<T> & SearchOutput<T> : SearchOutput<T>\nexport type StrictFlatOutput<T extends AnyRoute | string> =\n HasParams<Definition<T>> extends true ? ParamsOutput<T> & StrictSearchOutput<T> : StrictSearchOutput<T>\nexport type ParamsInput<T extends AnyRoute | string = string> = _ParamsInput<PathDefinition<T>>\nexport type SearchInput<T extends AnyRoute | string = string> = _SearchInput<Definition<T>>\nexport type StrictSearchInput<T extends AnyRoute | string> = _StrictSearchInput<Definition<T>>\nexport type FlatInput<T extends AnyRoute | string> = _FlatInput<Definition<T>>\nexport type StrictFlatInput<T extends AnyRoute | string> = _StrictFlatInput<Definition<T>>\nexport type CanInputBeEmpty<T extends AnyRoute | string> = HasParams<Definition<T>> extends true ? false : true\n\n// location\n\nexport type LocationParams<TDefinition extends string> = {\n [K in keyof _ParamsDefinition<TDefinition>]: string\n}\nexport type LocationSearch<TDefinition extends string = string> = {\n [K in keyof _SearchDefinition<TDefinition>]: string | undefined\n} & Record<string, string | undefined>\n\nexport type _GeneralLocation = {\n pathname: string\n search: string\n hash: string\n origin?: string\n href?: string\n hrefRel: string\n abs: boolean\n port?: string\n host?: string\n hostname?: string\n}\nexport type UnknownLocation = _GeneralLocation & {\n params: undefined\n searchParams: SearchOutput\n route: undefined\n exact: false\n parent: false\n children: false\n}\nexport type UnmatchedLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & {\n params: Record<never, never>\n searchParams: SearchOutput<TRoute>\n route: Definition<TRoute>\n exact: false\n parent: false\n children: false\n}\nexport type ExactLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & {\n params: ParamsOutput<TRoute>\n searchParams: SearchOutput<TRoute>\n route: Definition<TRoute>\n exact: true\n parent: false\n children: false\n}\nexport type ParentLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & {\n params: Partial<ParamsOutput<TRoute>> // in fact maybe there will be whole params object, but does not matter now\n searchParams: SearchOutput<TRoute>\n route: Definition<TRoute>\n exact: false\n parent: true\n children: false\n}\nexport type ChildrenLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & {\n params: ParamsOutput<TRoute>\n searchParams: SearchOutput<TRoute>\n route: Definition<TRoute>\n exact: false\n parent: false\n children: true\n}\nexport type KnownLocation<TRoute extends AnyRoute | string = AnyRoute | string> =\n | UnmatchedLocation<TRoute>\n | ExactLocation<TRoute>\n | ParentLocation<TRoute>\n | ChildrenLocation<TRoute>\nexport type AnyLocation<TRoute extends AnyRoute = AnyRoute> = UnknownLocation | KnownLocation<TRoute>\n\n// internal utils\n\nexport type _PathDefinition<T extends string> = T extends string ? TrimSearchTailDefinition<T> : never\nexport type _ParamsDefinition<TDefinition extends string> =\n ExtractPathParams<PathDefinition<TDefinition>> extends infer U\n ? [U] extends [never]\n ? undefined\n : { [K in Extract<U, string>]: true }\n : undefined\nexport type _SearchDefinition<TDefinition extends string> =\n NonEmpty<SearchTailDefinitionWithoutFirstAmp<TDefinition>> extends infer Tail extends string\n ? AmpSplit<Tail> extends infer U\n ? [U] extends [never]\n ? undefined\n : { [K in Extract<U, string>]: true }\n : undefined\n : undefined\n\nexport type _ParamsInput<TDefinition extends string> =\n _ParamsDefinition<TDefinition> extends undefined\n ? Record<never, never>\n : {\n [K in keyof _ParamsDefinition<TDefinition>]: string | number\n }\nexport type _SearchInput<TDefinition extends string> =\n _SearchDefinition<TDefinition> extends undefined\n ? Record<string, string | number>\n : Partial<{\n [K in keyof _SearchDefinition<TDefinition>]: string | number\n }> &\n Record<string, string | number>\nexport type _StrictSearchInput<TDefinition extends string> = Partial<{\n [K in keyof _SearchDefinition<TDefinition>]: string | number\n}>\nexport type _FlatInput<TDefinition extends string> =\n HasParams<TDefinition> extends true\n ? _ParamsInput<TDefinition> & _SearchInput<TDefinition>\n : _SearchInput<TDefinition>\nexport type _StrictFlatInput<TDefinition extends string> =\n HasParams<TDefinition> extends true\n ? HasSearch<TDefinition> extends true\n ? _StrictSearchInput<TDefinition> & _ParamsInput<TDefinition>\n : _ParamsInput<TDefinition>\n : HasSearch<TDefinition> extends true\n ? _StrictSearchInput<TDefinition>\n : Record<never, never>\n\nexport type TrimSearchTailDefinition<S extends string> = S extends `${infer P}&${string}` ? P : S\nexport type SearchTailDefinitionWithoutFirstAmp<S extends string> = S extends `${string}&${infer T}` ? T : ''\nexport type SearchTailDefinitionWithFirstAmp<S extends string> = S extends `${string}&${infer T}` ? `&${T}` : ''\nexport type AmpSplit<S extends string> = S extends `${infer A}&${infer B}` ? A | AmpSplit<B> : S\n// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\nexport type NonEmpty<T> = [T] extends ['' | never] ? never : T\nexport type ExtractPathParams<S extends string> = S extends `${string}:${infer After}`\n ? After extends `${infer Name}/${infer Rest}`\n ? Name | ExtractPathParams<`/${Rest}`>\n : After\n : never\nexport type ReplacePathParams<S extends string> = S extends `${infer Head}:${infer Tail}`\n ? // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Tail extends `${infer _Param}/${infer Rest}`\n ? ReplacePathParams<`${Head}${string}/${Rest}`>\n : `${Head}${string}`\n : S\nexport type DedupeSlashes<S extends string> = S extends `${infer A}//${infer B}` ? DedupeSlashes<`${A}/${B}`> : S\nexport type EmptyRecord = Record<never, never>\nexport type JoinPath<Parent extends string, Suffix extends string> = DedupeSlashes<\n PathDefinition<Parent> extends infer A extends string\n ? PathDefinition<Suffix> extends infer B extends string\n ? A extends ''\n ? B extends ''\n ? ''\n : B extends `/${string}`\n ? B\n : `/${B}`\n : B extends ''\n ? A\n : A extends `${string}/`\n ? `${A}${B}`\n : B extends `/${string}`\n ? `${A}${B}`\n : `${A}/${B}`\n : never\n : never\n>\n\nexport type OnlyIfNoParams<TParams extends object | undefined, Yes, No = never> = TParams extends undefined ? Yes : No\nexport type OnlyIfHasParams<TParams extends object | undefined, Yes, No = never> = TParams extends undefined ? No : Yes\n\nexport type PathOnlyRouteValue<TDefinition extends string> = `${ReplacePathParams<PathDefinition<TDefinition>>}`\nexport type WithSearchRouteValue<TDefinition extends string> =\n `${ReplacePathParams<PathDefinition<TDefinition>>}?${string}`\nexport type AbsolutePathOnlyRouteValue<TDefinition extends string> =\n PathOnlyRouteValue<TDefinition> extends '/' ? string : `${string}${PathOnlyRouteValue<TDefinition>}`\nexport type AbsoluteWithSearchRouteValue<TDefinition extends string> = `${string}${WithSearchRouteValue<TDefinition>}`\n\nexport type PathExtended<\n TSourcedefinitionDefinition extends string,\n TSuffixdefinitionDefinition extends string,\n> = `${JoinPath<TSourcedefinitionDefinition, TSuffixdefinitionDefinition>}${SearchTailDefinitionWithFirstAmp<TSuffixdefinitionDefinition>}`\n\nexport type WithParamsInput<\n TDefinition extends string,\n T extends\n | {\n search?: _SearchInput<any>\n abs?: boolean\n }\n | undefined = undefined,\n> = _ParamsInput<TDefinition> & (T extends undefined ? Record<never, never> : T)\n\nexport type _IsSameParams<T1 extends object | undefined, T2 extends object | undefined> = T1 extends undefined\n ? T2 extends undefined\n ? true\n : false\n : T2 extends undefined\n ? false\n : T1 extends T2\n ? T2 extends T1\n ? true\n : false\n : false\n\nexport type _IsParent<T extends string, TParent extends string> = T extends TParent\n ? false\n : T extends `${TParent}${string}`\n ? true\n : false\nexport type _IsChildren<T extends string, TChildren extends string> = TChildren extends T\n ? false\n : TChildren extends `${T}${string}`\n ? true\n : false\nexport type _IsSame<T extends string, TExact extends string> = T extends TExact\n ? TExact extends T\n ? true\n : false\n : false\n"],"mappings":"AAwBO,MAAM,OAAmC;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT;AAAA,EAEQ,YAAY,YAAyB,SAA2B,CAAC,GAAG;AAC1E,SAAK,aAAa;AAClB,SAAK,iBAAiB,OAAO,+BAA+B,UAAU;AACtE,SAAK,mBAAmB,OAAO,iCAAiC,UAAU;AAC1E,SAAK,mBAAmB,OAAO,iCAAiC,UAAU;AAE1E,UAAM,EAAE,QAAQ,IAAI;AACpB,QAAI,WAAW,OAAO,YAAY,YAAY,QAAQ,QAAQ;AAC5D,WAAK,UAAU;AAAA,IACjB,OAAO;AACL,YAAM,IAAI;AAEV,UAAI,OAAO,GAAG,UAAU,WAAW,YAAY,EAAE,SAAS,OAAO,SAAS,GAAG;AAC3E,aAAK,UAAU,EAAE,SAAS;AAAA,MAC5B,OAAO;AACL,aAAK,UAAU;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,OACL,YACA,QAC4B;AAC5B,QAAI,OAAO,eAAe,YAAY;AACpC,aAAO;AAAA,IACT;AACA,UAAM,WAAW,OAAO,eAAe,WAAW,aAAa,IAAI,OAAoB,YAAY,MAAM;AACzG,UAAM,WAAW,SAAS,IAAI,KAAK,QAAQ;AAC3C,WAAO,eAAe,UAAU,QAAQ;AACxC,WAAO,eAAe,UAAU,OAAO,aAAa;AAAA,MAClD,OAAO,SAAS;AAAA,IAClB,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,OAAe,4CAA4C,YAAoB;AAC7E,UAAM,IAAI,WAAW,QAAQ,GAAG;AAChC,QAAI,MAAM,GAAI,QAAO,EAAE,gBAAgB,YAAY,sBAAsB,GAAG;AAC5E,WAAO;AAAA,MACL,gBAAgB,WAAW,MAAM,GAAG,CAAC;AAAA,MACrC,sBAAsB,WAAW,MAAM,CAAC;AAAA,IAC1C;AAAA,EACF;AAAA,EAEA,OAAe,YAAY,SAAiB,gBAAwB;AAClE,WAAO,IAAI,IAAI,gBAAgB,OAAO,EAAE,SAAS,EAAE,QAAQ,OAAO,EAAE;AAAA,EACtE;AAAA,EAEA,OAAe,+BAA2D,YAAyB;AACjG,UAAM,EAAE,eAAe,IAAI,OAAO,4CAA4C,UAAU;AACxF,WAAO;AAAA,EACT;AAAA,EAEA,OAAe,iCACb,YACgC;AAChC,UAAM,EAAE,eAAe,IAAI,OAAO,4CAA4C,UAAU;AACxF,UAAM,UAAU,MAAM,KAAK,eAAe,SAAS,mBAAmB,CAAC;AACvE,UAAM,mBAAmB,OAAO,YAAY,QAAQ,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;AAC5E,UAAM,YAAY,OAAO,KAAK,gBAAgB,EAAE;AAChD,QAAI,cAAc,GAAG;AACnB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEA,OAAe,iCACb,YACgC;AAChC,UAAM,EAAE,qBAAqB,IAAI,OAAO,4CAA4C,UAAU;AAC9F,QAAI,CAAC,sBAAsB;AACzB,aAAO;AAAA,IACT;AACA,UAAM,OAAO,qBAAqB,MAAM,GAAG,EAAE,OAAO,OAAO;AAC3D,UAAM,mBAAmB,OAAO,YAAY,KAAK,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;AACtE,UAAM,YAAY,OAAO,KAAK,gBAAgB,EAAE;AAChD,QAAI,cAAc,GAAG;AACnB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEA,OACE,kBAC6D;AAC7D,UAAM,EAAE,gBAAgB,qBAAqB,IAAI,OAAO,4CAA4C,KAAK,UAAU;AACnH,UAAM,EAAE,gBAAgB,sBAAsB,sBAAsB,2BAA2B,IAC7F,OAAO,4CAA4C,gBAAgB;AACrE,UAAM,iBAAiB,GAAG,oBAAoB,IAAI,oBAAoB,GAAG,QAAQ,WAAW,GAAG;AAC/F,UAAM,aAAa,GAAG,cAAc,GAAG,0BAA0B;AACjE,WAAO,OAAO,OAAqD,YAAY,EAAE,SAAS,KAAK,QAAQ,CAAC;AAAA,EAC1G;AAAA;AAAA,EA4CA,OAAO,MAAqB;AAC1B,UAAM,EAAE,aAAa,aAAa,SAAS,KAAK,MAI3C;AACH,UAAI,KAAK,WAAW,GAAG;AACrB,eAAO,EAAE,aAAa,CAAC,GAAG,aAAa,CAAC,GAAG,UAAU,MAAM;AAAA,MAC7D;AACA,YAAM,QAAQ,KAAK,CAAC;AACpB,UAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAE/C,eAAO,EAAE,aAAa,CAAC,GAAG,aAAa,CAAC,GAAG,UAAU,MAAM;AAAA,MAC7D;AACA,YAAM,EAAE,QAAQ,KAAK,GAAG,OAAO,IAAI;AACnC,aAAO,EAAE,aAAa,UAAU,CAAC,GAAG,aAAa,QAAQ,UAAU,OAAO,MAAM;AAAA,IAClF,GAAG;AAGH,UAAM,mBAAmB,KAAK,mBAAmB,OAAO,KAAK,KAAK,gBAAgB,IAAI,CAAC;AACvF,UAAM,qBAAqB,OAAO,KAAK,WAAW;AAClD,UAAM,kBAAkB,iBAAiB,OAAO,CAAC,MAAM,CAAC,mBAAmB,SAAS,CAAC,CAAC;AACtF,QAAI,gBAAgB,QAAQ;AAE1B,aAAO,OAAO,aAAa,OAAO,YAAY,gBAAgB,IAAI,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;AAAA,IAC7F;AAIA,QAAI,MAAM,KAAK;AAGf,UAAM,IAAI,QAAQ,qBAAqB,CAAC,IAAI,MAAM,mBAAmB,OAAO,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC;AAEpG,UAAM,yBAAyB,OAAO,YAAY,OAAO,QAAQ,WAAW,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAC7G,UAAM,CAAC,KAAK,IAAI,gBAAgB,sBAAsB,EAAE,SAAS,CAAC,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAE5F,UAAM,IAAI,QAAQ,WAAW,GAAG;AAEhC,UAAM,WAAW,OAAO,YAAY,KAAK,SAAS,GAAG,IAAI;AAEzD,WAAO;AAAA,EACT;AAAA;AAAA,EAwCA,QAAQ,MAAqB;AAC3B,UAAM,EAAE,aAAa,aAAa,SAAS,KAAK,MAI3C;AACH,UAAI,KAAK,WAAW,GAAG;AACrB,eAAO,EAAE,aAAa,CAAC,GAAG,aAAa,CAAC,GAAG,UAAU,MAAM;AAAA,MAC7D;AACA,YAAM,QAAQ,KAAK,CAAC;AACpB,UAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAE/C,eAAO,EAAE,aAAa,CAAC,GAAG,aAAa,CAAC,GAAG,UAAU,KAAK,CAAC,KAAK,MAAM;AAAA,MACxE;AACA,YAAM,aAAa,KAAK,cAAc;AACtC,YAAMA,eAAc,WAAW,OAAwC,CAAC,KAAK,QAAQ;AACnF,YAAI,MAAM,GAAG,MAAM,QAAW;AAC5B,cAAI,GAAG,IAAI,MAAM,GAAG;AAAA,QACtB;AACA,eAAO;AAAA,MACT,GAAG,CAAC,CAAC;AACL,YAAM,aAAa,KAAK,cAAc;AACtC,YAAMC,eAAc,OAAO,KAAK,KAAK,EAClC,OAAO,CAAC,MAAM;AACb,YAAI,WAAW,SAAS,CAAC,GAAG;AAC1B,iBAAO;AAAA,QACT;AACA,YAAI,WAAW,SAAS,CAAC,GAAG;AAC1B,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT,CAAC,EACA,OAAwC,CAAC,KAAK,QAAQ;AACrD,YAAI,GAAG,IAAI,MAAM,GAAG;AACpB,eAAO;AAAA,MACT,GAAG,CAAC,CAAC;AACP,aAAO,EAAE,aAAAA,cAAa,aAAAD,cAAa,UAAU,KAAK,CAAC,KAAK,MAAM;AAAA,IAChE,GAAG;AAEH,WAAO,KAAK,IAAI,EAAE,GAAG,aAAa,QAAQ,aAAa,KAAK,SAAS,CAAU;AAAA,EACjF;AAAA,EAEA,gBAA0B;AACxB,WAAO,OAAO,KAAK,KAAK,oBAAoB,CAAC,CAAC;AAAA,EAChD;AAAA,EACA,gBAA0B;AACxB,WAAO,OAAO,KAAK,KAAK,oBAAoB,CAAC,CAAC;AAAA,EAChD;AAAA,EACA,cAAwB;AACtB,WAAO,CAAC,GAAG,KAAK,cAAc,GAAG,GAAG,KAAK,cAAc,CAAC;AAAA,EAC1D;AAAA,EAEA,gBAAwB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,QAAgD;AACpD,WAAO,IAAI,OAAO,KAAK,YAAY,MAAM;AAAA,EAC3C;AAAA,EAEA,iBAAyB;AAEvB,UAAM,MACJ,KAAK,eAAe,SAAS,KAAK,KAAK,eAAe,SAAS,GAAG,IAC9D,KAAK,eAAe,MAAM,GAAG,EAAE,IAC/B,KAAK;AAGX,UAAM,UAAU,IACb,QAAQ,qBAAqB,aAAa,EAC1C,QAAQ,uBAAuB,MAAM,EACrC,QAAQ,gBAAgB,SAAS;AAEpC,WAAO;AAAA,EACT;AAAA,EAEA,WAAmB;AACjB,WAAO,IAAI,OAAO,IAAI,KAAK,eAAe,CAAC,GAAG;AAAA,EAChD;AAAA,EAEA,OAAO,eAAe,QAAuC;AAC3D,UAAM,cAAc,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;AAC5D,WAAO,YAAY,IAAI,CAAC,UAAU,MAAM,eAAe,CAAC,EAAE,KAAK,GAAG;AAAA,EACpE;AAAA,EACA,OAAO,SAAS,QAAuC;AACrD,WAAO,IAAI,OAAO,KAAK,OAAO,eAAe,MAAM,CAAC,IAAI;AAAA,EAC1D;AAAA,EAQA,OAAO,YAAY,yBAAsE;AACvF,QAAI,mCAAmC,KAAK;AAC1C,aAAO,OAAO,YAAY,wBAAwB,IAAI;AAAA,IACxD;AACA,QAAI,OAAO,4BAA4B,UAAU;AAC/C,gCAA0B,wBAAwB,QAAQ,wBAAwB;AAAA,IACpF;AAEA,UAAM,MAAM,gCAAgC,KAAK,uBAAuB;AAGxE,UAAM,OAAO,MAAM,SAAY;AAC/B,UAAM,MAAM,IAAI,IAAI,yBAAyB,IAAI;AAGjD,UAAM,eAAe,OAAO,YAAY,IAAI,aAAa,QAAQ,CAAC;AAGlE,QAAI,WAAW,IAAI;AACnB,QAAI,SAAS,SAAS,KAAK,SAAS,SAAS,GAAG,GAAG;AACjD,iBAAW,SAAS,MAAM,GAAG,EAAE;AAAA,IACjC;AAGA,UAAM,UAAU,WAAW,IAAI,SAAS,IAAI;AAG5C,UAAM,WAA4B;AAAA,MAChC;AAAA,MACA,QAAQ,IAAI;AAAA,MACZ,MAAM,IAAI;AAAA,MACV,QAAQ,MAAM,IAAI,SAAS;AAAA,MAC3B,MAAM,MAAM,IAAI,OAAO;AAAA,MACvB;AAAA,MACA;AAAA;AAAA,MAGA,MAAM,MAAM,IAAI,OAAO;AAAA,MACvB,UAAU,MAAM,IAAI,WAAW;AAAA,MAC/B,MAAM,MAAM,IAAI,QAAQ,SAAY;AAAA;AAAA,MAGpC;AAAA,MACA,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ;AAEA,WAAO;AAAA,EACT;AAAA,EAQA,YAAY,yBAAiF;AAC3F,QAAI,mCAAmC,KAAK;AAC1C,aAAO,KAAK,YAAY,wBAAwB,IAAI;AAAA,IACtD;AACA,QAAI,OAAO,4BAA4B,UAAU;AAC/C,gCAA0B,wBAAwB,QAAQ,wBAAwB;AAAA,IACpF;AACA,UAAM,WAAW,OAAO,YAAY,uBAAuB;AAC3D,aAAS,QAAQ,KAAK;AACtB,aAAS,SAAS,CAAC;AAGnB,UAAM,WACJ,SAAS,SAAS,SAAS,KAAK,SAAS,SAAS,SAAS,GAAG,IAC1D,SAAS,SAAS,MAAM,GAAG,EAAE,IAC7B,SAAS;AAGf,UAAM,UAAU,KAAK,eAAe;AAGpC,UAAM,aAAuB,CAAC;AAC9B,UAAM,MACJ,KAAK,eAAe,SAAS,KAAK,KAAK,eAAe,SAAS,GAAG,IAC9D,KAAK,eAAe,MAAM,GAAG,EAAE,IAC/B,KAAK;AACX,QAAI,QAAQ,qBAAqB,CAAC,IAAY,SAAiB;AAE7D,iBAAW,KAAK,OAAO,IAAI,CAAC;AAC5B,aAAO;AAAA,IACT,CAAC;AAED,UAAM,UAAU,IAAI,OAAO,IAAI,OAAO,GAAG;AACzC,UAAM,WAAW,IAAI,OAAO,IAAI,OAAO,WAAW;AAClD,UAAM,aAAa,SAAS,MAAM,OAAO;AAGzC,QAAI,YAAY;AACd,YAAM,SAAS,WAAW,MAAM,CAAC;AACjC,YAAM,SAAS,OAAO,YAAY,WAAW,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,mBAAmB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AACpG,eAAS,SAAS;AAAA,IACpB,OAAO;AACL,eAAS,SAAS,CAAC;AAAA,IACrB;AAEA,UAAM,QAAQ,CAAC,CAAC;AAChB,UAAM,SAAS,CAAC,SAAS,SAAS,KAAK,QAAQ;AAG/C,UAAM,WAAW,CAAC,SAAkB,SAAS,MAAM,CAAC,GAAG,IAAI,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AACzF,UAAM,WAAW,SAAS,GAAG;AAC7B,UAAM,YAAY,SAAS,QAAQ;AAEnC,QAAI,WAAW;AACf,QAAI,UAAU,SAAS,SAAS,QAAQ;AACtC,iBAAW;AAAA,IACb,OAAO;AACL,eAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,cAAM,UAAU,SAAS,CAAC;AAC1B,cAAM,WAAW,UAAU,CAAC;AAC5B,YAAI,CAAC,SAAS;AACZ,qBAAW;AACX;AAAA,QACF;AACA,YAAI,QAAQ,WAAW,GAAG,EAAG;AAC7B,YAAI,YAAY,UAAU;AACxB,qBAAW;AACX;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,UAAM,WAAW,CAAC,SAAS;AAE3B,WAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,OAAqC;AAC1C,WACE,KAAK,eAAe,QAAQ,qBAAqB,WAAW,MAC5D,MAAM,eAAe,QAAQ,qBAAqB,WAAW;AAAA,EAEjE;AAAA,EACA,OAAO,OAAO,GAAkC,GAA2C;AACzF,QAAK,CAAC,KAAK,KAAO,KAAK,CAAC,EAAI,QAAO;AACnC,QAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,WAAO,OAAO,OAAO,CAAC,EAAE,OAAO,OAAO,OAAO,CAAC,CAAC;AAAA,EACjD;AAAA,EAEA,WAAW,OAAqC;AAC9C,WACE,KAAK,eAAe,QAAQ,qBAAqB,WAAW,MAC5D,MAAM,eAAe,QAAQ,qBAAqB,WAAW;AAAA,EAEjE;AAAA,EAEA,SAAS,OAAqC;AAC5C,WACE,MAAM,eAAe,QAAQ,qBAAqB,WAAW,MAC7D,KAAK,eAAe,QAAQ,qBAAqB,WAAW;AAAA,EAEhE;AAAA,EAEA,WAAW,OAA6B;AACtC,UAAM,WAAW,CAAC,SAAiB;AACjC,UAAI,SAAS,IAAK,QAAO,CAAC,GAAG;AAC7B,aAAO,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AAAA,IACvC;AAEA,UAAM,YAAY,SAAS,KAAK,cAAc;AAC9C,UAAM,aAAa,SAAS,MAAM,cAAc;AAGhD,QAAI,UAAU,WAAW,WAAW,QAAQ;AAC1C,aAAO;AAAA,IACT;AAGA,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,YAAM,WAAW,UAAU,CAAC;AAC5B,YAAM,YAAY,WAAW,CAAC;AAG9B,UAAI,SAAS,WAAW,GAAG,KAAK,UAAU,WAAW,GAAG,GAAG;AACzD;AAAA,MACF;AAGA,UAAI,SAAS,WAAW,GAAG,KAAK,UAAU,WAAW,GAAG,GAAG;AACzD;AAAA,MACF;AAGA,UAAI,aAAa,WAAW;AAC1B,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,mBAAmB,OAA6B;AAG9C,UAAM,WAAW,CAAC,SAAiB;AACjC,UAAI,SAAS,IAAK,QAAO,CAAC,GAAG;AAC7B,aAAO,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AAAA,IACvC;AAEA,UAAM,YAAY,SAAS,KAAK,cAAc;AAC9C,UAAM,aAAa,SAAS,MAAM,cAAc;AAGhD,aAAS,IAAI,GAAG,IAAI,KAAK,IAAI,UAAU,QAAQ,WAAW,MAAM,GAAG,KAAK;AACtE,YAAM,eAAe,CAAC,UAAU,CAAC,EAAE,WAAW,GAAG;AACjD,YAAM,gBAAgB,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG;AAEnD,UAAI,gBAAgB,CAAC,cAAe,QAAO;AAC3C,UAAI,CAAC,gBAAgB,cAAe,QAAO;AAAA,IAC7C;AAGA,WAAO,KAAK,iBAAiB,MAAM;AAAA,EACrC;AACF;AAEO,MAAM,OAAoD;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAED,YAAY;AAAA,IAClB;AAAA,IACA,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAMG;AACD,SAAK,SACH,aAAc,SAAqC,OAAO,SAAS,MAAM;AAE3E,QAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,SAAS;AAC/C,YAAM,WAAW,OAAO,cAAc,KAAK,MAAM;AACjD,WAAK,gBAAgB,SAAS;AAC9B,WAAK,eAAe,SAAS;AAC7B,WAAK,UAAU,KAAK,aAAa,IAAI,CAAC,QAAQ,KAAK,OAAO,GAAG,CAAC;AAAA,IAChE,OAAO;AACL,WAAK,gBAAgB;AACrB,WAAK,eAAe;AACpB,WAAK,UAAU;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,OAAO,OAAqC,QAA4B;AACtE,UAAM,WAAW,IAAI,OAAO,EAAE,OAAO,CAAC;AACtC,WAAO,OAAO,UAAU,QAAQ;AAAA,EAClC;AAAA,EAEA,OAAO,UAAwC,UAAsC;AACnF,WAAO,eAAe,UAAU,OAAO,SAAS;AAChD,WAAO,eAAe,UAAU,OAAO,aAAa;AAAA,MAClD,OAAO;AAAA,IACT,CAAC;AACD,WAAO,OAAO,UAAU;AAAA,MACtB,UAAU,SAAS,SAAS,KAAK,QAAQ;AAAA,IAC3C,CAAC;AACD,WAAO,OAAO,UAAU,SAAS,MAAM;AACvC,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,SAAuC,QAAoC;AAChF,UAAM,SAAS,CAAC;AAChB,eAAW,OAAO,QAAQ;AACxB,UAAI,OAAO,UAAU,eAAe,KAAK,QAAQ,GAAG,GAAG;AACrD,cAAM,QAAQ,OAAO,GAAG;AACxB,eAAO,GAAG,IAAK,OAAO,UAAU,WAAW,OAAO,OAAO,KAAK,IAAI;AAAA,MACpE;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAQA,YAAY,yBAAsF;AAEhG,UAAM,QAAQ;AACd,eAAW,SAAS,KAAK,SAAS;AAChC,YAAM,MAAM,MAAM,YAAY,uBAAuB;AACrD,UAAI,IAAI,OAAO;AACb,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO,OAAO,UAAU,WAAW,OAAO,YAAY,KAAK,IAAI,OAAO,YAAY,KAAK;AAAA,EACzF;AAAA,EAEA,OAAO,cAAc,QAA2E;AAC9F,UAAM,WAAW,OAAO,SAAS,MAAM;AACvC,UAAM,UAAU,OAAO,QAAQ,QAAQ;AAEvC,UAAM,WAAW,CAAC,SAAiB;AACjC,UAAI,SAAS,IAAK,QAAO,CAAC,GAAG;AAC7B,aAAO,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AAAA,IACvC;AAGA,YAAQ,KAAK,CAAC,CAAC,OAAO,MAAM,GAAG,CAAC,OAAO,MAAM,MAAM;AACjD,YAAM,SAAS,SAAS,OAAO,cAAc;AAC7C,YAAM,SAAS,SAAS,OAAO,cAAc;AAG7C,UAAI,OAAO,WAAW,OAAO,QAAQ;AACnC,eAAO,OAAO,SAAS,OAAO;AAAA,MAChC;AAGA,UAAI,OAAO,WAAW,MAAM,GAAG;AAE7B,YAAI,OAAO,mBAAmB,MAAM,EAAG,QAAO;AAC9C,YAAI,OAAO,mBAAmB,MAAM,EAAG,QAAO;AAAA,MAChD;AAGA,aAAO,OAAO,eAAe,cAAc,OAAO,cAAc;AAAA,IAClE,CAAC;AAED,UAAM,gBAAgB,QAAQ,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,MAAM,UAAU;AACrE,UAAM,eAAe,QAAQ,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI;AACxD,WAAO,EAAE,eAAe,aAAa;AAAA,EACvC;AAAA,EAEA,SAAS,QAA2C;AAClD,UAAM,YAAY,CAAC;AACnB,eAAW,OAAO,KAAK,QAAQ;AAC7B,UAAI,OAAO,UAAU,eAAe,KAAK,KAAK,QAAQ,GAAG,GAAG;AAC1D,kBAAU,GAAG,IAAI,KAAK,OAAO,GAAG,EAAE,MAAM,MAAM;AAAA,MAChD;AAAA,IACF;AACA,UAAM,WAAW,IAAI,OAAO;AAAA,MAC1B,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,eAAe,KAAK;AAAA,MACpB,cAAc,KAAK;AAAA,MACnB,SAAS,KAAK,aAAa,IAAI,CAAC,QAAQ,UAAU,GAAG,CAAC;AAAA,IACxD,CAAC;AACD,WAAO,OAAO,UAAU,QAAQ;AAAA,EAClC;AACF;","names":["paramsInput","searchInput"]}
1
+ {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["// TODO: asterisk\n// TODO: when asterisk then query params will be extended also after extend\n// TODO: optional params\n// TODO: required search\n\n// TODO: .extension('.json') to not add additional / but just add some extension\n// TODO: search input can be boolean, or even object with qs\n// TODO: Роут0 три пусть три тоже сам генерится вероятно\n// TODO: Роут0 три мод, тогда там все ноуты кончаются на .селф\n// TODO: use splats in param definition \"*\"\n// TODO: ? check extend for search only .extend('&x&z')\n// TODO: .create(route, {useSearch, useParams})\n// TODO: Из пас экзакт, из пасвизквери экзает, из чилдрен, из парент, из экзактОр\n// TODO: isEqual, isChildren, isParent\n// TODO: extractParams, extractSearch\n// TODO: getPathDefinition respecting definitionParamPrefix, definitionSearchPrefix\n// TODO: prepend\n// TODO: Route0.createTree({base:{self: x, children: ...})\n// TODO: overrideTree\n// TODO: .create(route, {baseUrl, useLocation})\n// TODO: ? optional path params as @\n// TODO: prependMany, extendMany, overrideMany, with types\n// TODO: optional route params /x/:id?\n\nexport class Route0<TDefinition extends string> {\n readonly definition: TDefinition\n readonly pathDefinition: _PathDefinition<TDefinition>\n readonly paramsDefinition: _ParamsDefinition<TDefinition>\n readonly searchDefinition: _SearchDefinition<TDefinition>\n baseUrl: string\n\n private constructor(definition: TDefinition, config: RouteConfigInput = {}) {\n this.definition = definition\n this.pathDefinition = Route0._getPathDefinitionBydefinition(definition)\n this.paramsDefinition = Route0._getParamsDefinitionBydefinition(definition)\n this.searchDefinition = Route0._getSearchDefinitionBydefinition(definition)\n\n const { baseUrl } = config\n if (baseUrl && typeof baseUrl === 'string' && baseUrl.length) {\n this.baseUrl = baseUrl\n } else {\n const g = globalThis as unknown as { location?: { origin?: string } }\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (typeof g?.location?.origin === 'string' && g.location.origin.length > 0) {\n this.baseUrl = g.location.origin\n } else {\n this.baseUrl = 'https://example.com'\n }\n }\n }\n\n static create<TDefinition extends string>(\n definition: TDefinition | AnyRoute<TDefinition>,\n config?: RouteConfigInput,\n ): CallabelRoute<TDefinition> {\n if (typeof definition === 'function') {\n return definition\n }\n const original = typeof definition === 'object' ? definition : new Route0<TDefinition>(definition, config)\n const callable = original.get.bind(original)\n Object.setPrototypeOf(callable, original)\n Object.defineProperty(callable, Symbol.toStringTag, {\n value: original.definition,\n })\n return callable as never\n }\n\n private static _splitPathDefinitionAndSearchTailDefinition(definition: string) {\n const i = definition.indexOf('&')\n if (i === -1) return { pathDefinition: definition, searchTailDefinition: '' }\n return {\n pathDefinition: definition.slice(0, i),\n searchTailDefinition: definition.slice(i),\n }\n }\n\n private static _getAbsPath(baseUrl: string, pathWithSearch: string) {\n return new URL(pathWithSearch, baseUrl).toString().replace(/\\/$/, '')\n }\n\n private static _getPathDefinitionBydefinition<TDefinition extends string>(definition: TDefinition) {\n const { pathDefinition } = Route0._splitPathDefinitionAndSearchTailDefinition(definition)\n return pathDefinition as _PathDefinition<TDefinition>\n }\n\n private static _getParamsDefinitionBydefinition<TDefinition extends string>(\n definition: TDefinition,\n ): _ParamsDefinition<TDefinition> {\n const { pathDefinition } = Route0._splitPathDefinitionAndSearchTailDefinition(definition)\n const matches = Array.from(pathDefinition.matchAll(/:([A-Za-z0-9_]+)/g))\n const paramsDefinition = Object.fromEntries(matches.map((m) => [m[1], true]))\n const keysCount = Object.keys(paramsDefinition).length\n if (keysCount === 0) {\n return undefined as _ParamsDefinition<TDefinition>\n }\n return paramsDefinition as _ParamsDefinition<TDefinition>\n }\n\n private static _getSearchDefinitionBydefinition<TDefinition extends string>(\n definition: TDefinition,\n ): _SearchDefinition<TDefinition> {\n const { searchTailDefinition } = Route0._splitPathDefinitionAndSearchTailDefinition(definition)\n if (!searchTailDefinition) {\n return undefined as _SearchDefinition<TDefinition>\n }\n const keys = searchTailDefinition.split('&').filter(Boolean)\n const searchDefinition = Object.fromEntries(keys.map((k) => [k, true]))\n const keysCount = Object.keys(searchDefinition).length\n if (keysCount === 0) {\n return undefined as _SearchDefinition<TDefinition>\n }\n return searchDefinition as _SearchDefinition<TDefinition>\n }\n\n extend<TSuffixDefinition extends string>(\n suffixDefinition: TSuffixDefinition,\n ): CallabelRoute<PathExtended<TDefinition, TSuffixDefinition>> {\n const { pathDefinition: parentPathDefinition } = Route0._splitPathDefinitionAndSearchTailDefinition(this.definition)\n const { pathDefinition: suffixPathDefinition, searchTailDefinition: suffixSearchTailDefinition } =\n Route0._splitPathDefinitionAndSearchTailDefinition(suffixDefinition)\n const pathDefinition = `${parentPathDefinition}/${suffixPathDefinition}`.replace(/\\/{2,}/g, '/')\n const definition = `${pathDefinition}${suffixSearchTailDefinition}` as PathExtended<TDefinition, TSuffixDefinition>\n return Route0.create<PathExtended<TDefinition, TSuffixDefinition>>(definition, { baseUrl: this.baseUrl })\n }\n\n // has params\n get(\n input: OnlyIfHasParams<\n _ParamsDefinition<TDefinition>,\n WithParamsInput<TDefinition, { search?: undefined; abs?: false }>\n >,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, PathOnlyRouteValue<TDefinition>>\n get(\n input: OnlyIfHasParams<\n _ParamsDefinition<TDefinition>,\n WithParamsInput<TDefinition, { search: _SearchInput<TDefinition>; abs?: false }>\n >,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithSearchRouteValue<TDefinition>>\n get(\n input: OnlyIfHasParams<\n _ParamsDefinition<TDefinition>,\n WithParamsInput<TDefinition, { search?: undefined; abs: true }>\n >,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, AbsolutePathOnlyRouteValue<TDefinition>>\n get(\n input: OnlyIfHasParams<\n _ParamsDefinition<TDefinition>,\n WithParamsInput<TDefinition, { search: _SearchInput<TDefinition>; abs: true }>\n >,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, AbsoluteWithSearchRouteValue<TDefinition>>\n\n // no params\n get(...args: OnlyIfNoParams<_ParamsDefinition<TDefinition>, [], [never]>): PathOnlyRouteValue<TDefinition>\n get(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, { search?: undefined; abs?: false }>,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, PathOnlyRouteValue<TDefinition>>\n get(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, { search: _SearchInput<TDefinition>; abs?: false }>,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, WithSearchRouteValue<TDefinition>>\n get(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, { search?: undefined; abs: true }>,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, AbsolutePathOnlyRouteValue<TDefinition>>\n get(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, { search: _SearchInput<TDefinition>; abs: true }>,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, AbsoluteWithSearchRouteValue<TDefinition>>\n\n // implementation\n get(...args: any[]): string {\n const { searchInput, paramsInput, absInput } = ((): {\n searchInput: Record<string, string | number>\n paramsInput: Record<string, string | number>\n absInput: boolean\n } => {\n if (args.length === 0) {\n return { searchInput: {}, paramsInput: {}, absInput: false }\n }\n const input = args[0]\n if (typeof input !== 'object' || input === null) {\n // throw new Error(\"Invalid get route input: expected object\")\n return { searchInput: {}, paramsInput: {}, absInput: false }\n }\n const { search, abs, ...params } = input\n return { searchInput: search || {}, paramsInput: params, absInput: abs ?? false }\n })()\n\n // validate params\n const neededParamsKeys = this.paramsDefinition ? Object.keys(this.paramsDefinition) : []\n const providedParamsKeys = Object.keys(paramsInput)\n const notProvidedKeys = neededParamsKeys.filter((k) => !providedParamsKeys.includes(k))\n if (notProvidedKeys.length) {\n // throw new Error(`Missing params: not defined keys ${notProvidedKeys.map((k) => `\"${k}\"`).join(\", \")}.`)\n Object.assign(paramsInput, Object.fromEntries(notProvidedKeys.map((k) => [k, 'undefined'])))\n }\n\n // create url\n\n let url = this.pathDefinition as string\n // replace params\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n url = url.replace(/:([A-Za-z0-9_]+)/g, (_m, k) => encodeURIComponent(String(paramsInput?.[k] ?? '')))\n // search params\n const searchInputStringified = Object.fromEntries(Object.entries(searchInput).map(([k, v]) => [k, String(v)]))\n url = [url, new URLSearchParams(searchInputStringified).toString()].filter(Boolean).join('?')\n // dedupe slashes\n url = url.replace(/\\/{2,}/g, '/')\n // absolute\n url = absInput ? Route0._getAbsPath(this.baseUrl, url) : url\n\n return url\n }\n\n // has params\n flat(\n input: OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithParamsInput<TDefinition>>,\n abs?: false,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, PathOnlyRouteValue<TDefinition>>\n flat(\n input: OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithParamsInput<TDefinition, _SearchInput<TDefinition>>>,\n abs?: false,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithSearchRouteValue<TDefinition>>\n flat(\n input: OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithParamsInput<TDefinition>>,\n abs: true,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, AbsolutePathOnlyRouteValue<TDefinition>>\n flat(\n input: OnlyIfHasParams<_ParamsDefinition<TDefinition>, WithParamsInput<TDefinition, _SearchInput<TDefinition>>>,\n abs: true,\n ): OnlyIfHasParams<_ParamsDefinition<TDefinition>, AbsoluteWithSearchRouteValue<TDefinition>>\n\n // no params\n flat(...args: OnlyIfNoParams<_ParamsDefinition<TDefinition>, [], [never]>): PathOnlyRouteValue<TDefinition>\n flat(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, Record<never, never>>,\n abs?: false,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, PathOnlyRouteValue<TDefinition>>\n flat(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, _SearchInput<TDefinition>>,\n abs?: false,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, WithSearchRouteValue<TDefinition>>\n flat(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, Record<never, never>>,\n abs: true,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, AbsolutePathOnlyRouteValue<TDefinition>>\n flat(\n input: OnlyIfNoParams<_ParamsDefinition<TDefinition>, _SearchInput<TDefinition>>,\n abs: true,\n ): OnlyIfNoParams<_ParamsDefinition<TDefinition>, AbsoluteWithSearchRouteValue<TDefinition>>\n\n // implementation\n flat(...args: any[]): string {\n const { searchInput, paramsInput, absInput } = ((): {\n searchInput: Record<string, string | number>\n paramsInput: Record<string, string | number>\n absInput: boolean\n } => {\n if (args.length === 0) {\n return { searchInput: {}, paramsInput: {}, absInput: false }\n }\n const input = args[0]\n if (typeof input !== 'object' || input === null) {\n // throw new Error(\"Invalid get route input: expected object\")\n return { searchInput: {}, paramsInput: {}, absInput: args[1] ?? false }\n }\n const paramsKeys = this.getParamsKeys()\n const paramsInput = paramsKeys.reduce<Record<string, string | number>>((acc, key) => {\n if (input[key] !== undefined) {\n acc[key] = input[key]\n }\n return acc\n }, {})\n const searchKeys = this.getSearchKeys()\n const searchInput = Object.keys(input)\n .filter((k) => {\n if (searchKeys.includes(k)) {\n return true\n }\n if (paramsKeys.includes(k)) {\n return false\n }\n return true\n })\n .reduce<Record<string, string | number>>((acc, key) => {\n acc[key] = input[key]\n return acc\n }, {})\n return { searchInput, paramsInput, absInput: args[1] ?? false }\n })()\n\n return this.get({ ...paramsInput, search: searchInput, abs: absInput } as never)\n }\n\n getParamsKeys(): string[] {\n return Object.keys(this.paramsDefinition || {})\n }\n getSearchKeys(): string[] {\n return Object.keys(this.searchDefinition || {})\n }\n getFlatKeys(): string[] {\n return [...this.getSearchKeys(), ...this.getParamsKeys()]\n }\n\n getDefinition(): string {\n return this.pathDefinition\n }\n\n clone(config?: RouteConfigInput): Route0<TDefinition> {\n return new Route0(this.definition, config)\n }\n\n getRegexString(): string {\n // Normalize the path definition (remove trailing slash except for root)\n const def =\n this.pathDefinition.length > 1 && this.pathDefinition.endsWith('/')\n ? this.pathDefinition.slice(0, -1)\n : this.pathDefinition\n\n // Replace :param with placeholders, escape regex special chars, then restore capture groups\n const pattern = def\n .replace(/:([A-Za-z0-9_]+)/g, '___PARAM___') // temporarily replace params with placeholder\n .replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') // escape regex special chars\n .replace(/___PARAM___/g, '([^/]+)') // replace placeholder with capture group\n\n return pattern\n }\n\n getRegex(): RegExp {\n return new RegExp(`^${this.getRegexString()}$`)\n }\n\n static getRegexString(routes: AnyRoute[] | AnyRoute): string {\n const routesArray = Array.isArray(routes) ? routes : [routes]\n return routesArray.map((route) => route.getRegexString()).join('|')\n }\n static getRegex(routes: AnyRoute[] | AnyRoute): RegExp {\n return new RegExp(`^(${Route0.getRegexString(routes)})$`)\n }\n\n static getLocation(href: `${string}://${string}`): UnknownLocation\n static getLocation(hrefRel: `/${string}`): UnknownLocation\n static getLocation(hrefOrHrefRel: string): UnknownLocation\n static getLocation(location: AnyLocation): UnknownLocation\n static getLocation(url: URL): UnknownLocation\n static getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation\n static getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation {\n if (hrefOrHrefRelOrLocation instanceof URL) {\n return Route0.getLocation(hrefOrHrefRelOrLocation.href)\n }\n if (typeof hrefOrHrefRelOrLocation !== 'string') {\n hrefOrHrefRelOrLocation = hrefOrHrefRelOrLocation.href || hrefOrHrefRelOrLocation.hrefRel\n }\n // Check if it's an absolute URL (starts with scheme://)\n const abs = /^[a-zA-Z][a-zA-Z\\d+\\-.]*:\\/\\//.test(hrefOrHrefRelOrLocation)\n\n // Use dummy base only if relative\n const base = abs ? undefined : 'http://example.com'\n const url = new URL(hrefOrHrefRelOrLocation, base)\n\n // Extract search params\n const searchParams = Object.fromEntries(url.searchParams.entries())\n\n // Normalize pathname (remove trailing slash except for root)\n let pathname = url.pathname\n if (pathname.length > 1 && pathname.endsWith('/')) {\n pathname = pathname.slice(0, -1)\n }\n\n // Common derived values\n const hrefRel = pathname + url.search + url.hash\n\n // Build the location object consistent with _GeneralLocation\n const location: UnknownLocation = {\n pathname,\n search: url.search,\n hash: url.hash,\n origin: abs ? url.origin : undefined,\n href: abs ? url.href : undefined,\n hrefRel,\n abs,\n\n // extra host-related fields (available even for relative with dummy base)\n host: abs ? url.host : undefined,\n hostname: abs ? url.hostname : undefined,\n port: abs ? url.port || undefined : undefined,\n\n // specific to UnknownLocation\n searchParams,\n params: undefined,\n route: undefined,\n exact: false,\n parent: false,\n children: false,\n }\n\n return location\n }\n\n getLocation(href: `${string}://${string}`): KnownLocation<TDefinition>\n getLocation(hrefRel: `/${string}`): KnownLocation<TDefinition>\n getLocation(hrefOrHrefRel: string): KnownLocation<TDefinition>\n getLocation(location: AnyLocation): KnownLocation<TDefinition>\n getLocation(url: AnyLocation): KnownLocation<TDefinition>\n getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): KnownLocation<TDefinition>\n getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): KnownLocation<TDefinition> {\n if (hrefOrHrefRelOrLocation instanceof URL) {\n return this.getLocation(hrefOrHrefRelOrLocation.href)\n }\n if (typeof hrefOrHrefRelOrLocation !== 'string') {\n hrefOrHrefRelOrLocation = hrefOrHrefRelOrLocation.href || hrefOrHrefRelOrLocation.hrefRel\n }\n const location = Route0.getLocation(hrefOrHrefRelOrLocation) as never as KnownLocation<TDefinition>\n location.route = this.definition as Definition<TDefinition>\n location.params = {}\n\n // Normalize pathname (no trailing slash except root)\n const pathname =\n location.pathname.length > 1 && location.pathname.endsWith('/')\n ? location.pathname.slice(0, -1)\n : location.pathname\n\n // Use getRegexString() to get the pattern\n const pattern = this.getRegexString()\n\n // Extract param names from the definition\n const paramNames: string[] = []\n const def =\n this.pathDefinition.length > 1 && this.pathDefinition.endsWith('/')\n ? this.pathDefinition.slice(0, -1)\n : this.pathDefinition\n def.replace(/:([A-Za-z0-9_]+)/g, (_m: string, name: string) => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-conversion\n paramNames.push(String(name))\n return ''\n })\n\n const exactRe = new RegExp(`^${pattern}$`)\n const parentRe = new RegExp(`^${pattern}(?:/.*)?$`) // route matches the beginning of the URL (may have more)\n const exactMatch = pathname.match(exactRe)\n\n // Fill params only for exact match (keeps behavior predictable)\n if (exactMatch) {\n const values = exactMatch.slice(1)\n const params = Object.fromEntries(paramNames.map((n, i) => [n, decodeURIComponent(values[i] ?? '')]))\n location.params = params\n } else {\n location.params = {}\n }\n\n const exact = !!exactMatch\n const parent = !exact && parentRe.test(pathname)\n\n // \"children\": the URL is a prefix of the route definition (params match any single segment)\n const getParts = (path: string) => (path === '/' ? ['/'] : path.split('/').filter(Boolean))\n const defParts = getParts(def)\n const pathParts = getParts(pathname)\n\n let isPrefix = true\n if (pathParts.length > defParts.length) {\n isPrefix = false\n } else {\n for (let i = 0; i < pathParts.length; i++) {\n const defPart = defParts[i]\n const pathPart = pathParts[i]\n if (!defPart) {\n isPrefix = false\n break\n }\n if (defPart.startsWith(':')) continue\n if (defPart !== pathPart) {\n isPrefix = false\n break\n }\n }\n }\n const children = !exact && isPrefix\n\n return {\n ...location,\n exact,\n parent,\n children,\n } as KnownLocation<TDefinition>\n }\n\n isSame(other: Route0<TDefinition>): boolean {\n return (\n this.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__') ===\n other.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__')\n )\n }\n static isSame(a: AnyRoute | string | undefined, b: AnyRoute | string | undefined): boolean {\n if ((!a && b) || (a && !b)) return false\n if (!a || !b) return true\n return Route0.create(a).isSame(Route0.create(b))\n }\n\n isChildren(other: Route0<TDefinition>): boolean {\n return (\n this.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__') ===\n other.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__')\n )\n }\n\n isParent(other: Route0<TDefinition>): boolean {\n return (\n other.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__') ===\n this.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, '__PARAM__')\n )\n }\n\n isConflict(other: Route0<any>): boolean {\n const getParts = (path: string) => {\n if (path === '/') return ['/']\n return path.split('/').filter(Boolean)\n }\n\n const thisParts = getParts(this.pathDefinition)\n const otherParts = getParts(other.pathDefinition)\n\n // Different lengths = no conflict (one is deeper than the other)\n if (thisParts.length !== otherParts.length) {\n return false\n }\n\n // Check if all segments could match\n for (let i = 0; i < thisParts.length; i++) {\n const thisPart = thisParts[i]\n const otherPart = otherParts[i]\n\n // Both params = always match\n if (thisPart.startsWith(':') && otherPart.startsWith(':')) {\n continue\n }\n\n // One is param = can match\n if (thisPart.startsWith(':') || otherPart.startsWith(':')) {\n continue\n }\n\n // Both static = must be same\n if (thisPart !== otherPart) {\n return false\n }\n }\n\n return true\n }\n\n isMoreSpecificThan(other: Route0<any>): boolean {\n // More specific = should come earlier when conflicted\n // Static segments beat param segments at the same position\n const getParts = (path: string) => {\n if (path === '/') return ['/']\n return path.split('/').filter(Boolean)\n }\n\n const thisParts = getParts(this.pathDefinition)\n const otherParts = getParts(other.pathDefinition)\n\n // Compare segment by segment\n for (let i = 0; i < Math.min(thisParts.length, otherParts.length); i++) {\n const thisIsStatic = !thisParts[i].startsWith(':')\n const otherIsStatic = !otherParts[i].startsWith(':')\n\n if (thisIsStatic && !otherIsStatic) return true\n if (!thisIsStatic && otherIsStatic) return false\n }\n\n // All equal, use lexicographic\n return this.pathDefinition < other.pathDefinition\n }\n}\n\nexport class Routes<const T extends RoutesRecord = RoutesRecord> {\n private readonly routes: RoutesRecordHydrated<T>\n private readonly pathsOrdering: string[]\n private readonly keysOrdering: string[]\n private readonly ordered: CallabelRoute[]\n\n _: {\n getLocation: Routes<T>['getLocation']\n override: Routes<T>['override']\n pathsOrdering: Routes<T>['pathsOrdering']\n keysOrdering: Routes<T>['keysOrdering']\n ordered: Routes<T>['ordered']\n }\n\n private constructor({\n routes,\n isHydrated = false,\n pathsOrdering,\n keysOrdering,\n ordered,\n }: {\n routes: RoutesRecordHydrated<T> | T\n isHydrated?: boolean\n pathsOrdering?: string[]\n keysOrdering?: string[]\n ordered?: CallabelRoute[]\n }) {\n this.routes = (isHydrated ? (routes as RoutesRecordHydrated<T>) : Routes.hydrate(routes)) as RoutesRecordHydrated<T>\n if (!pathsOrdering || !keysOrdering || !ordered) {\n const ordering = Routes.makeOrdering(this.routes)\n this.pathsOrdering = ordering.pathsOrdering\n this.keysOrdering = ordering.keysOrdering\n this.ordered = this.keysOrdering.map((key) => this.routes[key])\n } else {\n this.pathsOrdering = pathsOrdering\n this.keysOrdering = keysOrdering\n this.ordered = ordered\n }\n this._ = {\n getLocation: this.getLocation.bind(this),\n override: this.override.bind(this),\n pathsOrdering: this.pathsOrdering,\n keysOrdering: this.keysOrdering,\n ordered: this.ordered,\n }\n }\n\n static create<const T extends RoutesRecord>(routes: T): RoutesPretty<T> {\n const instance = new Routes({ routes })\n return Routes.prettify(instance)\n }\n\n private static prettify<const T extends RoutesRecord>(instance: Routes<T>): RoutesPretty<T> {\n Object.setPrototypeOf(instance, Routes.prototype)\n Object.defineProperty(instance, Symbol.toStringTag, {\n value: 'Routes',\n })\n Object.assign(instance, {\n override: instance.override.bind(instance),\n })\n Object.assign(instance, instance.routes)\n return instance as unknown as RoutesPretty<T>\n }\n\n private static hydrate<const T extends RoutesRecord>(routes: T): RoutesRecordHydrated<T> {\n const result = {} as RoutesRecordHydrated<T>\n for (const key in routes) {\n if (Object.prototype.hasOwnProperty.call(routes, key)) {\n const value = routes[key]\n result[key] = (typeof value === 'string' ? Route0.create(value) : value) as CallabelRoute<T[typeof key]>\n }\n }\n return result\n }\n\n private getLocation(href: `${string}://${string}`): UnknownLocation | ExactLocation\n private getLocation(hrefRel: `/${string}`): UnknownLocation | ExactLocation\n private getLocation(hrefOrHrefRel: string): UnknownLocation | ExactLocation\n private getLocation(location: AnyLocation): UnknownLocation | ExactLocation\n private getLocation(url: URL): UnknownLocation | ExactLocation\n private getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation | ExactLocation\n private getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation | ExactLocation {\n // Find the route that exactly matches the given location\n const input = hrefOrHrefRelOrLocation\n for (const route of this.ordered) {\n const loc = route.getLocation(hrefOrHrefRelOrLocation)\n if (loc.exact) {\n return loc\n }\n }\n // No exact match found, return UnknownLocation\n return typeof input === 'string' ? Route0.getLocation(input) : Route0.getLocation(input)\n }\n\n private static makeOrdering(routes: RoutesRecord): { pathsOrdering: string[]; keysOrdering: string[] } {\n const hydrated = Routes.hydrate(routes)\n const entries = Object.entries(hydrated)\n\n const getParts = (path: string) => {\n if (path === '/') return ['/']\n return path.split('/').filter(Boolean)\n }\n\n // Sort: shorter paths first, then by specificity, then alphabetically\n entries.sort(([_keyA, routeA], [_keyB, routeB]) => {\n const partsA = getParts(routeA.pathDefinition)\n const partsB = getParts(routeB.pathDefinition)\n\n // 1. Shorter paths first (by segment count)\n if (partsA.length !== partsB.length) {\n return partsA.length - partsB.length\n }\n\n // 2. Same length: check if they conflict\n if (routeA.isConflict(routeB)) {\n // Conflicting routes: more specific first\n if (routeA.isMoreSpecificThan(routeB)) return -1\n if (routeB.isMoreSpecificThan(routeA)) return 1\n }\n\n // 3. Same length, not conflicting or equal specificity: alphabetically\n return routeA.pathDefinition.localeCompare(routeB.pathDefinition)\n })\n\n const pathsOrdering = entries.map(([_key, route]) => route.definition)\n const keysOrdering = entries.map(([_key, route]) => _key)\n return { pathsOrdering, keysOrdering }\n }\n\n private override(config: RouteConfigInput): RoutesPretty<T> {\n const newRoutes = {} as RoutesRecordHydrated<T>\n for (const key in this.routes) {\n if (Object.prototype.hasOwnProperty.call(this.routes, key)) {\n newRoutes[key] = this.routes[key].clone(config) as CallabelRoute<T[typeof key]>\n }\n }\n const instance = new Routes({\n routes: newRoutes,\n isHydrated: true,\n pathsOrdering: this.pathsOrdering,\n keysOrdering: this.keysOrdering,\n ordered: this.keysOrdering.map((key) => newRoutes[key]),\n })\n return Routes.prettify(instance)\n }\n\n static _ = {\n prettify: Routes.prettify.bind(Routes),\n hydrate: Routes.hydrate.bind(Routes),\n makeOrdering: Routes.makeOrdering.bind(Routes),\n }\n}\n\n// main\n\nexport type AnyRoute<T extends Route0<string> | string = string> = T extends string ? Route0<T> : T\nexport type CallabelRoute<T extends Route0<string> | string = string> = AnyRoute<T> & AnyRoute<T>['get']\nexport type AnyRouteOrDefinition<T extends string = string> = AnyRoute<T> | CallabelRoute<T> | T\nexport type RouteConfigInput = {\n baseUrl?: string\n}\n\n// collection\n\nexport type RoutesRecord = Record<string, AnyRoute | string>\nexport type RoutesRecordHydrated<TRoutesRecord extends RoutesRecord = RoutesRecord> = {\n [K in keyof TRoutesRecord]: CallabelRoute<TRoutesRecord[K]>\n}\nexport type RoutesPretty<TRoutesRecord extends RoutesRecord = RoutesRecord> = RoutesRecordHydrated<TRoutesRecord> &\n Routes<TRoutesRecord>\nexport type ExtractRoutesKeys<TRoutes extends RoutesPretty | RoutesRecord> = TRoutes extends RoutesPretty\n ? keyof TRoutes['routes']\n : TRoutes extends RoutesRecord\n ? keyof TRoutes\n : never\nexport type ExtractRoute<\n TRoutes extends RoutesPretty | RoutesRecord,\n TKey extends keyof ExtractRoutesKeys<TRoutes>,\n> = TKey extends keyof TRoutes ? TRoutes[TKey] : never\n\n// public utils\n\nexport type Definition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['definition']\n : T extends string\n ? T\n : never\nexport type PathDefinition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['pathDefinition']\n : T extends string\n ? _PathDefinition<T>\n : never\nexport type ParamsDefinition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['paramsDefinition']\n : T extends string\n ? _ParamsDefinition<T>\n : undefined\nexport type SearchDefinition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['searchDefinition']\n : T extends string\n ? _SearchDefinition<T>\n : undefined\n\nexport type Extended<T extends AnyRoute | string | undefined, TSuffixDefinition extends string> = T extends AnyRoute\n ? Route0<PathExtended<T['definition'], TSuffixDefinition>>\n : T extends string\n ? Route0<PathExtended<T, TSuffixDefinition>>\n : T extends undefined\n ? Route0<TSuffixDefinition>\n : never\n\nexport type IsParent<T extends AnyRoute | string, TParent extends AnyRoute | string> = _IsParent<\n PathDefinition<T>,\n PathDefinition<TParent>\n>\nexport type IsChildren<T extends AnyRoute | string, TChildren extends AnyRoute | string> = _IsChildren<\n PathDefinition<T>,\n PathDefinition<TChildren>\n>\nexport type IsSame<T extends AnyRoute | string, TExact extends AnyRoute | string> = _IsSame<\n PathDefinition<T>,\n PathDefinition<TExact>\n>\nexport type IsSameParams<T1 extends AnyRoute | string, T2 extends AnyRoute | string> = _IsSameParams<\n ParamsDefinition<T1>,\n ParamsDefinition<T2>\n>\n\nexport type HasParams<T extends AnyRoute | string> =\n ExtractPathParams<PathDefinition<T>> extends infer U ? ([U] extends [never] ? false : true) : false\nexport type HasSearch<T extends AnyRoute | string> =\n NonEmpty<SearchTailDefinitionWithoutFirstAmp<Definition<T>>> extends infer Tail extends string\n ? AmpSplit<Tail> extends infer U\n ? [U] extends [never]\n ? false\n : true\n : false\n : false\n\nexport type ParamsOutput<T extends AnyRoute | string> = {\n [K in keyof ParamsDefinition<T>]: string\n}\nexport type SearchOutput<T extends AnyRoute | string = string> = Partial<\n {\n [K in keyof SearchDefinition<T>]?: string\n } & Record<string, string | undefined>\n>\nexport type StrictSearchOutput<T extends AnyRoute | string> = Partial<{\n [K in keyof SearchDefinition<T>]?: string | undefined\n}>\nexport type FlatOutput<T extends AnyRoute | string = string> =\n HasParams<Definition<T>> extends true ? ParamsOutput<T> & SearchOutput<T> : SearchOutput<T>\nexport type StrictFlatOutput<T extends AnyRoute | string> =\n HasParams<Definition<T>> extends true ? ParamsOutput<T> & StrictSearchOutput<T> : StrictSearchOutput<T>\nexport type ParamsInput<T extends AnyRoute | string = string> = _ParamsInput<PathDefinition<T>>\nexport type SearchInput<T extends AnyRoute | string = string> = _SearchInput<Definition<T>>\nexport type StrictSearchInput<T extends AnyRoute | string> = _StrictSearchInput<Definition<T>>\nexport type FlatInput<T extends AnyRoute | string> = _FlatInput<Definition<T>>\nexport type StrictFlatInput<T extends AnyRoute | string> = _StrictFlatInput<Definition<T>>\nexport type CanInputBeEmpty<T extends AnyRoute | string> = HasParams<Definition<T>> extends true ? false : true\n\n// location\n\nexport type LocationParams<TDefinition extends string> = {\n [K in keyof _ParamsDefinition<TDefinition>]: string\n}\nexport type LocationSearch<TDefinition extends string = string> = {\n [K in keyof _SearchDefinition<TDefinition>]: string | undefined\n} & Record<string, string | undefined>\n\nexport type _GeneralLocation = {\n pathname: string\n search: string\n hash: string\n origin?: string\n href?: string\n hrefRel: string\n abs: boolean\n port?: string\n host?: string\n hostname?: string\n}\nexport type UnknownLocation = _GeneralLocation & {\n params: undefined\n searchParams: SearchOutput\n route: undefined\n exact: false\n parent: false\n children: false\n}\nexport type UnmatchedLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & {\n params: Record<never, never>\n searchParams: SearchOutput<TRoute>\n route: Definition<TRoute>\n exact: false\n parent: false\n children: false\n}\nexport type ExactLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & {\n params: ParamsOutput<TRoute>\n searchParams: SearchOutput<TRoute>\n route: Definition<TRoute>\n exact: true\n parent: false\n children: false\n}\nexport type ParentLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & {\n params: Partial<ParamsOutput<TRoute>> // in fact maybe there will be whole params object, but does not matter now\n searchParams: SearchOutput<TRoute>\n route: Definition<TRoute>\n exact: false\n parent: true\n children: false\n}\nexport type ChildrenLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & {\n params: ParamsOutput<TRoute>\n searchParams: SearchOutput<TRoute>\n route: Definition<TRoute>\n exact: false\n parent: false\n children: true\n}\nexport type KnownLocation<TRoute extends AnyRoute | string = AnyRoute | string> =\n | UnmatchedLocation<TRoute>\n | ExactLocation<TRoute>\n | ParentLocation<TRoute>\n | ChildrenLocation<TRoute>\nexport type AnyLocation<TRoute extends AnyRoute = AnyRoute> = UnknownLocation | KnownLocation<TRoute>\n\n// internal utils\n\nexport type _PathDefinition<T extends string> = T extends string ? TrimSearchTailDefinition<T> : never\nexport type _ParamsDefinition<TDefinition extends string> =\n ExtractPathParams<PathDefinition<TDefinition>> extends infer U\n ? [U] extends [never]\n ? undefined\n : { [K in Extract<U, string>]: true }\n : undefined\nexport type _SearchDefinition<TDefinition extends string> =\n NonEmpty<SearchTailDefinitionWithoutFirstAmp<TDefinition>> extends infer Tail extends string\n ? AmpSplit<Tail> extends infer U\n ? [U] extends [never]\n ? undefined\n : { [K in Extract<U, string>]: true }\n : undefined\n : undefined\n\nexport type _ParamsInput<TDefinition extends string> =\n _ParamsDefinition<TDefinition> extends undefined\n ? Record<never, never>\n : {\n [K in keyof _ParamsDefinition<TDefinition>]: string | number\n }\nexport type _SearchInput<TDefinition extends string> =\n _SearchDefinition<TDefinition> extends undefined\n ? Record<string, string | number>\n : Partial<{\n [K in keyof _SearchDefinition<TDefinition>]: string | number\n }> &\n Record<string, string | number>\nexport type _StrictSearchInput<TDefinition extends string> = Partial<{\n [K in keyof _SearchDefinition<TDefinition>]: string | number\n}>\nexport type _FlatInput<TDefinition extends string> =\n HasParams<TDefinition> extends true\n ? _ParamsInput<TDefinition> & _SearchInput<TDefinition>\n : _SearchInput<TDefinition>\nexport type _StrictFlatInput<TDefinition extends string> =\n HasParams<TDefinition> extends true\n ? HasSearch<TDefinition> extends true\n ? _StrictSearchInput<TDefinition> & _ParamsInput<TDefinition>\n : _ParamsInput<TDefinition>\n : HasSearch<TDefinition> extends true\n ? _StrictSearchInput<TDefinition>\n : Record<never, never>\n\nexport type TrimSearchTailDefinition<S extends string> = S extends `${infer P}&${string}` ? P : S\nexport type SearchTailDefinitionWithoutFirstAmp<S extends string> = S extends `${string}&${infer T}` ? T : ''\nexport type SearchTailDefinitionWithFirstAmp<S extends string> = S extends `${string}&${infer T}` ? `&${T}` : ''\nexport type AmpSplit<S extends string> = S extends `${infer A}&${infer B}` ? A | AmpSplit<B> : S\n// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\nexport type NonEmpty<T> = [T] extends ['' | never] ? never : T\nexport type ExtractPathParams<S extends string> = S extends `${string}:${infer After}`\n ? After extends `${infer Name}/${infer Rest}`\n ? Name | ExtractPathParams<`/${Rest}`>\n : After\n : never\nexport type ReplacePathParams<S extends string> = S extends `${infer Head}:${infer Tail}`\n ? // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Tail extends `${infer _Param}/${infer Rest}`\n ? ReplacePathParams<`${Head}${string}/${Rest}`>\n : `${Head}${string}`\n : S\nexport type DedupeSlashes<S extends string> = S extends `${infer A}//${infer B}` ? DedupeSlashes<`${A}/${B}`> : S\nexport type EmptyRecord = Record<never, never>\nexport type JoinPath<Parent extends string, Suffix extends string> = DedupeSlashes<\n PathDefinition<Parent> extends infer A extends string\n ? PathDefinition<Suffix> extends infer B extends string\n ? A extends ''\n ? B extends ''\n ? ''\n : B extends `/${string}`\n ? B\n : `/${B}`\n : B extends ''\n ? A\n : A extends `${string}/`\n ? `${A}${B}`\n : B extends `/${string}`\n ? `${A}${B}`\n : `${A}/${B}`\n : never\n : never\n>\n\nexport type OnlyIfNoParams<TParams extends object | undefined, Yes, No = never> = TParams extends undefined ? Yes : No\nexport type OnlyIfHasParams<TParams extends object | undefined, Yes, No = never> = TParams extends undefined ? No : Yes\n\nexport type PathOnlyRouteValue<TDefinition extends string> = `${ReplacePathParams<PathDefinition<TDefinition>>}`\nexport type WithSearchRouteValue<TDefinition extends string> =\n `${ReplacePathParams<PathDefinition<TDefinition>>}?${string}`\nexport type AbsolutePathOnlyRouteValue<TDefinition extends string> =\n PathOnlyRouteValue<TDefinition> extends '/' ? string : `${string}${PathOnlyRouteValue<TDefinition>}`\nexport type AbsoluteWithSearchRouteValue<TDefinition extends string> = `${string}${WithSearchRouteValue<TDefinition>}`\n\nexport type PathExtended<\n TSourcedefinitionDefinition extends string,\n TSuffixdefinitionDefinition extends string,\n> = `${JoinPath<TSourcedefinitionDefinition, TSuffixdefinitionDefinition>}${SearchTailDefinitionWithFirstAmp<TSuffixdefinitionDefinition>}`\n\nexport type WithParamsInput<\n TDefinition extends string,\n T extends\n | {\n search?: _SearchInput<any>\n abs?: boolean\n }\n | undefined = undefined,\n> = _ParamsInput<TDefinition> & (T extends undefined ? Record<never, never> : T)\n\nexport type _IsSameParams<T1 extends object | undefined, T2 extends object | undefined> = T1 extends undefined\n ? T2 extends undefined\n ? true\n : false\n : T2 extends undefined\n ? false\n : T1 extends T2\n ? T2 extends T1\n ? true\n : false\n : false\n\nexport type _IsParent<T extends string, TParent extends string> = T extends TParent\n ? false\n : T extends `${TParent}${string}`\n ? true\n : false\nexport type _IsChildren<T extends string, TChildren extends string> = TChildren extends T\n ? false\n : TChildren extends `${T}${string}`\n ? true\n : false\nexport type _IsSame<T extends string, TExact extends string> = T extends TExact\n ? TExact extends T\n ? true\n : false\n : false\n"],"mappings":"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","names":["paramsInput","searchInput"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devp0nt/route0",
3
- "version": "1.0.0-next.26",
3
+ "version": "1.0.0-next.27",
4
4
  "license": "MIT",
5
5
  "author": {
6
6
  "name": "Sergei Dmitriev",
package/src/index.test.ts CHANGED
@@ -223,7 +223,7 @@ describe('Route0', () => {
223
223
  // r0: route0,
224
224
  // r1: route1,
225
225
  // }
226
- // const routes2 = Route0.overrideMany(routes, { baseUrl: 'https://z.com' })
226
+ // const routes2 = Route0._.overrideMany(routes, { baseUrl: 'https://z.com' })
227
227
  // const path = routes2.r1.get({ abs: true })
228
228
  // expectTypeOf<typeof path>().toEqualTypeOf<`${string}/path/suffix`>()
229
229
  // expect(path).toBe('https://z.com/path/suffix')
@@ -661,7 +661,7 @@ describe('getLocation', () => {
661
661
  userDetail: '/users/:id',
662
662
  })
663
663
 
664
- const loc = routes.getLocation('/users/123')
664
+ const loc = routes._.getLocation('/users/123')
665
665
  expect(loc.exact).toBe(true)
666
666
  expect(loc.parent).toBe(false)
667
667
  expect(loc.children).toBe(false)
@@ -680,7 +680,7 @@ describe('getLocation', () => {
680
680
  })
681
681
 
682
682
  // '/users/123/posts' is not an exact match for any route
683
- const loc = routes.getLocation('/users/123/posts')
683
+ const loc = routes._.getLocation('/users/123/posts')
684
684
  expect(loc.exact).toBe(false)
685
685
  expect(loc.parent).toBe(false)
686
686
  expect(loc.children).toBe(false)
@@ -695,7 +695,7 @@ describe('getLocation', () => {
695
695
  })
696
696
 
697
697
  // '/users/123' is not an exact match for any route
698
- const loc = routes.getLocation('/users/123')
698
+ const loc = routes._.getLocation('/users/123')
699
699
  expect(loc.exact).toBe(false)
700
700
  expect(loc.parent).toBe(false)
701
701
  expect(loc.children).toBe(false)
@@ -708,7 +708,7 @@ describe('getLocation', () => {
708
708
  users: '/users',
709
709
  })
710
710
 
711
- const loc = routes.getLocation('/posts/123')
711
+ const loc = routes._.getLocation('/posts/123')
712
712
  expect(loc.exact).toBe(false)
713
713
  expect(loc.parent).toBe(false)
714
714
  expect(loc.children).toBe(false)
@@ -724,19 +724,19 @@ describe('getLocation', () => {
724
724
  })
725
725
 
726
726
  // Should match /users exactly
727
- const loc1 = routes.getLocation('/users')
727
+ const loc1 = routes._.getLocation('/users')
728
728
  expect(loc1.exact).toBe(true)
729
729
  expect(loc1.pathname).toBe('/users')
730
730
 
731
731
  // Should match /users/:id exactly
732
- const loc2 = routes.getLocation('/users/123')
732
+ const loc2 = routes._.getLocation('/users/123')
733
733
  expect(loc2.exact).toBe(true)
734
734
  if (loc2.exact) {
735
735
  expect(loc2.params).toMatchObject({ id: '123' })
736
736
  }
737
737
 
738
738
  // Should match /users/:id/posts exactly
739
- const loc3 = routes.getLocation('/users/123/posts')
739
+ const loc3 = routes._.getLocation('/users/123/posts')
740
740
  expect(loc3.exact).toBe(true)
741
741
  if (loc3.exact) {
742
742
  expect(loc3.params).toMatchObject({ id: '123' })
@@ -749,7 +749,7 @@ describe('getLocation', () => {
749
749
  users: '/users',
750
750
  })
751
751
 
752
- const loc = routes.getLocation('/search?q=test&filter=all')
752
+ const loc = routes._.getLocation('/search?q=test&filter=all')
753
753
  expect(loc.exact).toBe(true)
754
754
  expect(loc.pathname).toBe('/search')
755
755
  expect(loc.search).toBe('?q=test&filter=all')
@@ -762,7 +762,7 @@ describe('getLocation', () => {
762
762
  users: '/api/v1/users',
763
763
  })
764
764
 
765
- const loc = routes.getLocation('https://example.com/api/v1/users')
765
+ const loc = routes._.getLocation('https://example.com/api/v1/users')
766
766
  expect(loc.exact).toBe(true)
767
767
  expect(loc.abs).toBe(true)
768
768
  expect(loc.origin).toBe('https://example.com')
@@ -775,7 +775,7 @@ describe('getLocation', () => {
775
775
  userDetail: '/users/:id',
776
776
  })
777
777
 
778
- const loc = routes.getLocation('/users/123#profile')
778
+ const loc = routes._.getLocation('/users/123#profile')
779
779
  expect(loc.exact).toBe(true)
780
780
  expect(loc.hash).toBe('#profile')
781
781
  expect(loc.pathname).toBe('/users/123')
@@ -792,7 +792,7 @@ describe('getLocation', () => {
792
792
  userDetail: api.extend('/users/:id'),
793
793
  })
794
794
 
795
- const loc = routes.getLocation('/api/v1/users/456')
795
+ const loc = routes._.getLocation('/api/v1/users/456')
796
796
  expect(loc.exact).toBe(true)
797
797
  if (loc.exact) {
798
798
  expect(loc.params).toMatchObject({ id: '456' })
@@ -805,7 +805,7 @@ describe('getLocation', () => {
805
805
  about: '/about',
806
806
  })
807
807
 
808
- const loc = routes.getLocation('/')
808
+ const loc = routes._.getLocation('/')
809
809
  expect(loc.exact).toBe(true)
810
810
  expect(loc.pathname).toBe('/')
811
811
  })
@@ -816,7 +816,7 @@ describe('getLocation', () => {
816
816
  })
817
817
 
818
818
  const inputLoc = Route0.getLocation('/users/789')
819
- const loc = routes.getLocation(inputLoc)
819
+ const loc = routes._.getLocation(inputLoc)
820
820
  expect(loc.exact).toBe(true)
821
821
  if (loc.exact) {
822
822
  expect(loc.params).toMatchObject({ id: '789' })
@@ -832,7 +832,7 @@ describe('getLocation', () => {
832
832
  userPosts: api.extend('/users/:id/posts&sort&filter'),
833
833
  })
834
834
 
835
- const loc = routes.getLocation('/api/v1/users/42/posts?sort=date&filter=published&extra=value')
835
+ const loc = routes._.getLocation('/api/v1/users/42/posts?sort=date&filter=published&extra=value')
836
836
  expect(loc.exact).toBe(true)
837
837
  expect(loc.pathname).toBe('/api/v1/users/42/posts')
838
838
  expect(loc.searchParams).toMatchObject({
@@ -938,7 +938,7 @@ describe('Routes', () => {
938
938
  about: '/about',
939
939
  })
940
940
 
941
- const overridden = collection.override({ baseUrl: 'https://example.com' })
941
+ const overridden = collection._.override({ baseUrl: 'https://example.com' })
942
942
 
943
943
  const home = overridden.home
944
944
  const about = overridden.about
@@ -955,7 +955,7 @@ describe('Routes', () => {
955
955
  const original = collection.home
956
956
  expect(original.get({ abs: true })).toBe('https://example.com')
957
957
 
958
- const overridden = collection.override({ baseUrl: 'https://newdomain.com' })
958
+ const overridden = collection._.override({ baseUrl: 'https://newdomain.com' })
959
959
  const newRoute = overridden.home
960
960
 
961
961
  expect(original.get({ abs: true })).toBe('https://example.com')
@@ -975,14 +975,14 @@ describe('Routes', () => {
975
975
  expect(collection.api({ abs: true })).toBe('https://api.example.com/api')
976
976
  expect(collection.users.get({ abs: true })).toBe('https://api.example.com/api/users')
977
977
 
978
- const overridden = collection.override({ baseUrl: 'https://new-api.example.com' })
978
+ const overridden = collection._.override({ baseUrl: 'https://new-api.example.com' })
979
979
 
980
980
  expect(overridden.api.get({ abs: true })).toBe('https://new-api.example.com/api')
981
981
  expect(overridden.users.get({ abs: true })).toBe('https://new-api.example.com/api/users')
982
982
  })
983
983
 
984
984
  it('hydrate static method', () => {
985
- const hydrated = Routes._hydrate({
985
+ const hydrated = Routes._.hydrate({
986
986
  home: '/',
987
987
  user: '/user/:id',
988
988
  about: Route0.create('/about'),
@@ -1312,7 +1312,7 @@ describe('ordering', () => {
1312
1312
  catchAll: '/:slug',
1313
1313
  }
1314
1314
 
1315
- const { pathsOrdering: ordering } = Routes._makeOrdering(routes)
1315
+ const { pathsOrdering: ordering } = Routes._.makeOrdering(routes)
1316
1316
 
1317
1317
  // Expected order:
1318
1318
  // Depth 1: / then /users (static) then /:slug (param)
@@ -1329,7 +1329,7 @@ describe('ordering', () => {
1329
1329
  home: '/home',
1330
1330
  }
1331
1331
 
1332
- const { pathsOrdering: ordering } = Routes._makeOrdering(routes)
1332
+ const { pathsOrdering: ordering } = Routes._.makeOrdering(routes)
1333
1333
 
1334
1334
  // All have same depth and don't conflict
1335
1335
  // Ordered alphabetically
@@ -1349,7 +1349,7 @@ describe('ordering', () => {
1349
1349
  catchAll: '/:slug',
1350
1350
  }
1351
1351
 
1352
- const { pathsOrdering: ordering } = Routes._makeOrdering(routes)
1352
+ const { pathsOrdering: ordering } = Routes._.makeOrdering(routes)
1353
1353
 
1354
1354
  // Expected order:
1355
1355
  // Depth 1: / (static), /:slug (param)
@@ -1377,11 +1377,11 @@ describe('ordering', () => {
1377
1377
  userDetail: '/users/:id',
1378
1378
  })
1379
1379
 
1380
- expect(routes.pathsOrdering).toBeDefined()
1381
- expect(Array.isArray(routes.pathsOrdering)).toBe(true)
1380
+ expect(routes._.pathsOrdering).toBeDefined()
1381
+ expect(Array.isArray(routes._.pathsOrdering)).toBe(true)
1382
1382
  // Depth 1: /, /users (alphabetically)
1383
1383
  // Depth 2: /users/:id
1384
- expect(routes.pathsOrdering).toEqual(['/', '/users', '/users/:id'])
1384
+ expect(routes._.pathsOrdering).toEqual(['/', '/users', '/users/:id'])
1385
1385
  })
1386
1386
 
1387
1387
  it('ordering is preserved after override', () => {
@@ -1391,12 +1391,12 @@ describe('ordering', () => {
1391
1391
  userDetail: '/users/:id',
1392
1392
  })
1393
1393
 
1394
- const originalOrdering = routes.pathsOrdering
1394
+ const originalOrdering = routes._.pathsOrdering
1395
1395
 
1396
- const overridden = routes.override({ baseUrl: 'https://example.com' })
1396
+ const overridden = routes._.override({ baseUrl: 'https://example.com' })
1397
1397
 
1398
- expect(overridden.pathsOrdering).toEqual(originalOrdering)
1399
- expect(overridden.pathsOrdering).toEqual(['/', '/users', '/users/:id'])
1398
+ expect(overridden._.pathsOrdering).toEqual(originalOrdering)
1399
+ expect(overridden._.pathsOrdering).toEqual(['/', '/users', '/users/:id'])
1400
1400
  })
1401
1401
 
1402
1402
  it('_makeOrdering: handles single route', () => {
@@ -1404,14 +1404,14 @@ describe('ordering', () => {
1404
1404
  home: '/',
1405
1405
  }
1406
1406
 
1407
- const { pathsOrdering: ordering } = Routes._makeOrdering(routes)
1407
+ const { pathsOrdering: ordering } = Routes._.makeOrdering(routes)
1408
1408
  expect(ordering).toEqual(['/'])
1409
1409
  })
1410
1410
 
1411
1411
  it('_makeOrdering: handles empty object', () => {
1412
1412
  const routes = {}
1413
1413
 
1414
- const { pathsOrdering: ordering } = Routes._makeOrdering(routes)
1414
+ const { pathsOrdering: ordering } = Routes._.makeOrdering(routes)
1415
1415
  expect(ordering).toEqual([])
1416
1416
  })
1417
1417
  })
package/src/index.ts CHANGED
@@ -571,10 +571,18 @@ export class Route0<TDefinition extends string> {
571
571
  }
572
572
 
573
573
  export class Routes<const T extends RoutesRecord = RoutesRecord> {
574
- readonly routes: RoutesRecordHydrated<T>
575
- readonly pathsOrdering: string[]
576
- readonly keysOrdering: string[]
577
- readonly ordered: CallabelRoute[]
574
+ private readonly routes: RoutesRecordHydrated<T>
575
+ private readonly pathsOrdering: string[]
576
+ private readonly keysOrdering: string[]
577
+ private readonly ordered: CallabelRoute[]
578
+
579
+ _: {
580
+ getLocation: Routes<T>['getLocation']
581
+ override: Routes<T>['override']
582
+ pathsOrdering: Routes<T>['pathsOrdering']
583
+ keysOrdering: Routes<T>['keysOrdering']
584
+ ordered: Routes<T>['ordered']
585
+ }
578
586
 
579
587
  private constructor({
580
588
  routes,
@@ -589,11 +597,9 @@ export class Routes<const T extends RoutesRecord = RoutesRecord> {
589
597
  keysOrdering?: string[]
590
598
  ordered?: CallabelRoute[]
591
599
  }) {
592
- this.routes = (
593
- isHydrated ? (routes as RoutesRecordHydrated<T>) : Routes._hydrate(routes)
594
- ) as RoutesRecordHydrated<T>
600
+ this.routes = (isHydrated ? (routes as RoutesRecordHydrated<T>) : Routes.hydrate(routes)) as RoutesRecordHydrated<T>
595
601
  if (!pathsOrdering || !keysOrdering || !ordered) {
596
- const ordering = Routes._makeOrdering(this.routes)
602
+ const ordering = Routes.makeOrdering(this.routes)
597
603
  this.pathsOrdering = ordering.pathsOrdering
598
604
  this.keysOrdering = ordering.keysOrdering
599
605
  this.ordered = this.keysOrdering.map((key) => this.routes[key])
@@ -602,14 +608,21 @@ export class Routes<const T extends RoutesRecord = RoutesRecord> {
602
608
  this.keysOrdering = keysOrdering
603
609
  this.ordered = ordered
604
610
  }
611
+ this._ = {
612
+ getLocation: this.getLocation.bind(this),
613
+ override: this.override.bind(this),
614
+ pathsOrdering: this.pathsOrdering,
615
+ keysOrdering: this.keysOrdering,
616
+ ordered: this.ordered,
617
+ }
605
618
  }
606
619
 
607
620
  static create<const T extends RoutesRecord>(routes: T): RoutesPretty<T> {
608
621
  const instance = new Routes({ routes })
609
- return Routes._prettify(instance)
622
+ return Routes.prettify(instance)
610
623
  }
611
624
 
612
- static _prettify<const T extends RoutesRecord>(instance: Routes<T>): RoutesPretty<T> {
625
+ private static prettify<const T extends RoutesRecord>(instance: Routes<T>): RoutesPretty<T> {
613
626
  Object.setPrototypeOf(instance, Routes.prototype)
614
627
  Object.defineProperty(instance, Symbol.toStringTag, {
615
628
  value: 'Routes',
@@ -621,7 +634,7 @@ export class Routes<const T extends RoutesRecord = RoutesRecord> {
621
634
  return instance as unknown as RoutesPretty<T>
622
635
  }
623
636
 
624
- static _hydrate<const T extends RoutesRecord>(routes: T): RoutesRecordHydrated<T> {
637
+ private static hydrate<const T extends RoutesRecord>(routes: T): RoutesRecordHydrated<T> {
625
638
  const result = {} as RoutesRecordHydrated<T>
626
639
  for (const key in routes) {
627
640
  if (Object.prototype.hasOwnProperty.call(routes, key)) {
@@ -632,13 +645,13 @@ export class Routes<const T extends RoutesRecord = RoutesRecord> {
632
645
  return result
633
646
  }
634
647
 
635
- getLocation(href: `${string}://${string}`): UnknownLocation | ExactLocation
636
- getLocation(hrefRel: `/${string}`): UnknownLocation | ExactLocation
637
- getLocation(hrefOrHrefRel: string): UnknownLocation | ExactLocation
638
- getLocation(location: AnyLocation): UnknownLocation | ExactLocation
639
- getLocation(url: URL): UnknownLocation | ExactLocation
640
- getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation | ExactLocation
641
- getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation | ExactLocation {
648
+ private getLocation(href: `${string}://${string}`): UnknownLocation | ExactLocation
649
+ private getLocation(hrefRel: `/${string}`): UnknownLocation | ExactLocation
650
+ private getLocation(hrefOrHrefRel: string): UnknownLocation | ExactLocation
651
+ private getLocation(location: AnyLocation): UnknownLocation | ExactLocation
652
+ private getLocation(url: URL): UnknownLocation | ExactLocation
653
+ private getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation | ExactLocation
654
+ private getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation | ExactLocation {
642
655
  // Find the route that exactly matches the given location
643
656
  const input = hrefOrHrefRelOrLocation
644
657
  for (const route of this.ordered) {
@@ -651,8 +664,8 @@ export class Routes<const T extends RoutesRecord = RoutesRecord> {
651
664
  return typeof input === 'string' ? Route0.getLocation(input) : Route0.getLocation(input)
652
665
  }
653
666
 
654
- static _makeOrdering(routes: RoutesRecord): { pathsOrdering: string[]; keysOrdering: string[] } {
655
- const hydrated = Routes._hydrate(routes)
667
+ private static makeOrdering(routes: RoutesRecord): { pathsOrdering: string[]; keysOrdering: string[] } {
668
+ const hydrated = Routes.hydrate(routes)
656
669
  const entries = Object.entries(hydrated)
657
670
 
658
671
  const getParts = (path: string) => {
@@ -686,7 +699,7 @@ export class Routes<const T extends RoutesRecord = RoutesRecord> {
686
699
  return { pathsOrdering, keysOrdering }
687
700
  }
688
701
 
689
- override(config: RouteConfigInput): RoutesPretty<T> {
702
+ private override(config: RouteConfigInput): RoutesPretty<T> {
690
703
  const newRoutes = {} as RoutesRecordHydrated<T>
691
704
  for (const key in this.routes) {
692
705
  if (Object.prototype.hasOwnProperty.call(this.routes, key)) {
@@ -700,7 +713,13 @@ export class Routes<const T extends RoutesRecord = RoutesRecord> {
700
713
  keysOrdering: this.keysOrdering,
701
714
  ordered: this.keysOrdering.map((key) => newRoutes[key]),
702
715
  })
703
- return Routes._prettify(instance)
716
+ return Routes.prettify(instance)
717
+ }
718
+
719
+ static _ = {
720
+ prettify: Routes.prettify.bind(Routes),
721
+ hydrate: Routes.hydrate.bind(Routes),
722
+ makeOrdering: Routes.makeOrdering.bind(Routes),
704
723
  }
705
724
  }
706
725