@devp0nt/route0 1.0.0-next.81 → 1.0.0-next.82

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.
@@ -524,7 +524,7 @@ class Route0 {
524
524
  route: this.definition,
525
525
  params,
526
526
  exact: true,
527
- ascendant: false,
527
+ ancestor: false,
528
528
  descendant: false,
529
529
  unmatched: false
530
530
  };
@@ -540,11 +540,11 @@ class Route0 {
540
540
  })
541
541
  );
542
542
  return {
543
- type: "ascendant",
543
+ type: "ancestor",
544
544
  route: this.definition,
545
545
  params,
546
546
  exact: false,
547
- ascendant: true,
547
+ ancestor: true,
548
548
  descendant: false,
549
549
  unmatched: false
550
550
  };
@@ -568,7 +568,7 @@ class Route0 {
568
568
  route: this.definition,
569
569
  params,
570
570
  exact: false,
571
- ascendant: false,
571
+ ancestor: false,
572
572
  descendant: true,
573
573
  unmatched: false
574
574
  };
@@ -578,7 +578,7 @@ class Route0 {
578
578
  route: this.definition,
579
579
  params: {},
580
580
  exact: false,
581
- ascendant: false,
581
+ ancestor: false,
582
582
  descendant: false,
583
583
  unmatched: true
584
584
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["import type { StandardSchemaV1 } from '@standard-schema/spec'\nimport { parse as parseSearchQuery, stringify as stringifySearchQuery } from '@devp0nt/flat0'\n\nexport type RouteToken =\n | { kind: 'static'; value: string }\n | { kind: 'param'; name: string; optional: boolean }\n | { kind: 'wildcard'; prefix: string; optional: boolean }\n\nconst escapeRegex = (value: string): string => value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n\nconst collapseDuplicateSlashes = (value: string): string => value.replace(/\\/{2,}/g, '/')\n\n/**\n * Strongly typed route descriptor and URL builder.\n *\n * A route definition uses:\n * - path params: `/users/:id`\n * - named search keys: `/users&tab&sort`\n * - loose search mode: trailing `&`, e.g. `/users&`\n *\n * Instances are callable (same as `.get()`), so `route(input)` and\n * `route.get(input)` are equivalent.\n */\nexport class Route0<TDefinition extends string, TSearchInput extends UnknownSearchInput = UnknownSearchInput> {\n readonly definition: TDefinition\n readonly params: _ParamsDefinition<TDefinition>\n private _origin: string | undefined\n private _callable: CallableRoute<TDefinition, TSearchInput>\n private _routeSegments?: string[]\n private _routeTokens?: RouteToken[]\n private _routePatternCandidates?: string[]\n private _pathParamsDefinition?: Record<string, boolean>\n private _definitionWithoutTrailingWildcard?: string\n private _routeRegexBaseStringRaw?: string\n private _regexBaseString?: string\n private _regexString?: string\n private _regex?: RegExp\n private _regexAncestor?: RegExp\n private _regexDescendantMatchers?: Array<{ regex: RegExp; captureKeys: string[] }>\n private _captureKeys?: string[]\n private _normalizedDefinition?: string\n private _definitionParts?: string[]\n\n static normalizeSlash = (value: string): string => {\n const collapsed = collapseDuplicateSlashes(value)\n if (collapsed === '' || collapsed === '/') return '/'\n const withLeadingSlash = collapsed.startsWith('/') ? collapsed : `/${collapsed}`\n return withLeadingSlash.length > 1 && withLeadingSlash.endsWith('/')\n ? withLeadingSlash.slice(0, -1)\n : withLeadingSlash\n }\n\n private static _getRouteSegments(definition: string): string[] {\n if (definition === '' || definition === '/') return []\n return definition.split('/').filter(Boolean)\n }\n\n private static _validateRouteDefinition(definition: string): void {\n const segments = Route0._getRouteSegments(definition)\n const wildcardSegments = segments.filter((segment) => segment.includes('*'))\n if (wildcardSegments.length === 0) return\n if (wildcardSegments.length > 1) {\n throw new Error(`Invalid route definition \"${definition}\": only one wildcard segment is allowed`)\n }\n const wildcardSegmentIndex = segments.findIndex((segment) => segment.includes('*'))\n const wildcardSegment = segments[wildcardSegmentIndex]\n if (!wildcardSegment.match(/^(?:\\*|\\*\\?|[^*]+\\*|\\S+\\*\\?)$/)) {\n throw new Error(`Invalid route definition \"${definition}\": wildcard must be trailing in its segment`)\n }\n if (wildcardSegmentIndex !== segments.length - 1) {\n throw new Error(`Invalid route definition \"${definition}\": wildcard segment is allowed only at the end`)\n }\n }\n\n Infer: {\n ParamsDefinition: _ParamsDefinition<TDefinition>\n ParamsInput: _ParamsInput<TDefinition>\n ParamsInputStringOnly: _ParamsInputStringOnly<TDefinition>\n ParamsOutput: ParamsOutput<TDefinition>\n SearchInput: TSearchInput\n } = null as never\n\n /** Base URL used when generating absolute URLs (`abs: true`). */\n get origin(): string {\n if (!this._origin) {\n throw new Error(\n 'origin for route ' +\n this.definition +\n ' is not set, please provide it like Route0.create(route, {origin: \"https://example.com\"}) in config or set via clones like routes._.clone({origin: \"https://example.com\"})',\n )\n }\n return this._origin\n }\n set origin(origin: string) {\n this._origin = origin\n }\n\n private constructor(definition: TDefinition, config: RouteConfigInput = {}) {\n const normalizedDefinition = Route0.normalizeSlash(definition) as TDefinition\n Route0._validateRouteDefinition(normalizedDefinition)\n this.definition = normalizedDefinition\n this.params = this.pathParamsDefinition as _ParamsDefinition<TDefinition>\n\n const { origin } = config\n if (origin && typeof origin === 'string' && origin.length) {\n this._origin = origin\n } else {\n const g = globalThis as unknown as { location?: { origin?: string } } | undefined\n if (typeof g?.location?.origin === 'string' && g.location.origin.length > 0) {\n this._origin = g.location.origin\n } else {\n this._origin = undefined\n }\n }\n const callable = this.get.bind(this)\n Object.setPrototypeOf(callable, this)\n Object.defineProperty(callable, Symbol.toStringTag, {\n value: this.definition,\n })\n this._callable = callable as CallableRoute<TDefinition, TSearchInput>\n }\n\n /**\n * Creates a callable route instance.\n *\n * If an existing route/callable route is provided, it is cloned.\n */\n static create<TDefinition extends string>(\n definition: TDefinition | AnyRoute<TDefinition> | CallableRoute<TDefinition>,\n config?: RouteConfigInput,\n ): CallableRoute<NormalizeRouteDefinition<TDefinition>> {\n if (typeof definition === 'function' || typeof definition === 'object') {\n return definition.clone(config) as CallableRoute<NormalizeRouteDefinition<TDefinition>>\n }\n const original = new Route0<NormalizeRouteDefinition<TDefinition>>(\n Route0.normalizeSlash(definition) as NormalizeRouteDefinition<TDefinition>,\n config,\n )\n return original._callable as CallableRoute<NormalizeRouteDefinition<TDefinition>>\n }\n\n /**\n * Normalizes a definition/route into a callable route.\n *\n * Unlike `create`, passing a callable route returns the same instance.\n */\n static from<TDefinition extends string, TSearchInput extends UnknownSearchInput>(\n definition: TDefinition | AnyRoute<TDefinition, TSearchInput> | CallableRoute<TDefinition, TSearchInput>,\n ): CallableRoute<NormalizeRouteDefinition<TDefinition>, TSearchInput> {\n if (typeof definition === 'function') {\n return definition as CallableRoute<NormalizeRouteDefinition<TDefinition>, TSearchInput>\n }\n const original =\n typeof definition === 'object'\n ? definition\n : new Route0<NormalizeRouteDefinition<TDefinition>>(\n Route0.normalizeSlash(definition) as NormalizeRouteDefinition<TDefinition>,\n )\n return original._callable as CallableRoute<NormalizeRouteDefinition<TDefinition>, TSearchInput>\n }\n\n private static _getAbsPath(origin: string, url: string) {\n return new URL(url, origin).toString().replace(/\\/$/, '')\n }\n\n search<TNewSearchInput extends UnknownSearchInput>(): CallableRoute<TDefinition, TNewSearchInput> {\n return this._callable as CallableRoute<TDefinition, TNewSearchInput>\n }\n\n /** Extends the current route definition by appending a suffix route. */\n extend<TSuffixDefinition extends string>(\n suffixDefinition: TSuffixDefinition,\n ): CallableRoute<PathExtended<TDefinition, TSuffixDefinition>, TSearchInput> {\n const definition = Route0.normalizeSlash(`${this.definitionWithoutTrailingWildcard}/${suffixDefinition}`)\n return Route0.create<PathExtended<TDefinition, TSuffixDefinition>>(\n definition as PathExtended<TDefinition, TSuffixDefinition>,\n {\n origin: this._origin,\n },\n ) as CallableRoute<PathExtended<TDefinition, TSuffixDefinition>, TSearchInput>\n }\n\n get(...args: IsParamsOptional<TDefinition> extends true ? [abs: boolean | string | undefined] : never): string\n get(\n ...args: IsParamsOptional<TDefinition> extends true\n ? [input?: GetPathInput<TDefinition, TSearchInput> | undefined, abs?: boolean | string | undefined]\n : [input: GetPathInput<TDefinition, TSearchInput>, abs?: boolean | string | undefined]\n ): string\n\n // implementation\n get(...args: unknown[]): string {\n const { searchInput, paramsInput, absInput, absOriginInput, hashInput } = ((): {\n searchInput: Record<string, unknown>\n paramsInput: Record<string, string | undefined>\n absInput: boolean\n absOriginInput: string | undefined\n hashInput: string | undefined\n } => {\n if (args.length === 0) {\n return {\n searchInput: {},\n paramsInput: {},\n absInput: false,\n absOriginInput: undefined,\n hashInput: undefined,\n }\n }\n const [input, abs] = ((): [Record<string, unknown>, boolean | string | undefined] => {\n if (typeof args[0] === 'object' && args[0] !== null) {\n return [args[0], args[1]] as [Record<string, unknown>, boolean | string | undefined]\n }\n if (typeof args[1] === 'object' && args[1] !== null) {\n return [args[1], args[0]] as [Record<string, unknown>, boolean | string | undefined]\n }\n if (typeof args[0] === 'boolean' || typeof args[0] === 'string') {\n return [{}, args[0]]\n }\n if (typeof args[1] === 'boolean' || typeof args[1] === 'string') {\n return [{}, args[1]]\n }\n return [{}, undefined]\n })()\n let searchInput: Record<string, unknown> = {}\n let hashInput: string | undefined = undefined\n const paramsInput: Record<string, string | undefined> = {}\n for (const [key, value] of Object.entries(input)) {\n if (key === '?' && typeof value === 'object' && value !== null) {\n searchInput = value as Record<string, unknown>\n } else if (key === '#' && (typeof value === 'string' || typeof value === 'number')) {\n hashInput = String(value)\n } else if (key in this.params && (typeof value === 'string' || typeof value === 'number')) {\n Object.assign(paramsInput, { [key]: String(value) })\n }\n }\n const absOriginInput = typeof abs === 'string' && abs.length > 0 ? abs : undefined\n return {\n searchInput,\n paramsInput,\n absInput: absOriginInput !== undefined || abs === true,\n absOriginInput,\n hashInput,\n }\n })()\n\n // create url\n\n let url = this.definition as string\n // optional named params like /:id?\n url = url.replace(/\\/:([A-Za-z0-9_]+)\\?/g, (_m, k) => {\n const value = paramsInput[k]\n if (value === undefined) return ''\n return `/${encodeURIComponent(String(value))}`\n })\n // required named 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] ?? 'undefined')))\n // optional wildcard segment (/*?)\n url = url.replace(/\\/\\*\\?/g, () => {\n const value = paramsInput['*']\n if (value === undefined) return ''\n const stringValue = String(value)\n return stringValue.startsWith('/') ? stringValue : `/${stringValue}`\n })\n // required wildcard segment (/*)\n url = url.replace(/\\/\\*/g, () => {\n const value = String(paramsInput['*'] ?? '')\n return value.startsWith('/') ? value : `/${value}`\n })\n // optional wildcard inline (e.g. /app*?)\n url = url.replace(/\\*\\?/g, () => String(paramsInput['*'] ?? ''))\n // required wildcard inline (e.g. /app*)\n url = url.replace(/\\*/g, () => String(paramsInput['*'] ?? ''))\n // search params\n const searchString = stringifySearchQuery(searchInput, { arrayIndexes: false })\n url = [url, searchString].filter(Boolean).join('?')\n // dedupe slashes\n url = collapseDuplicateSlashes(url)\n // absolute\n url = absInput ? Route0._getAbsPath(absOriginInput || this.origin, url) : url\n // hash\n if (hashInput !== undefined) {\n url = `${url}#${hashInput}`\n }\n\n return url\n }\n\n /** Returns path param keys extracted from route definition. */\n getParamsKeys(): string[] {\n return Object.keys(this.params)\n }\n\n getTokens(): RouteToken[] {\n return this.routeTokens.map((token): RouteToken => ({ ...token }))\n }\n\n /** Clones route with optional config override. */\n clone(config?: RouteConfigInput): CallableRoute<TDefinition> {\n return Route0.create(this.definition, config) as CallableRoute<TDefinition>\n }\n\n get regexBaseString(): string {\n if (this._regexBaseString === undefined) {\n this._regexBaseString = this.routeRegexBaseStringRaw.replace(/\\/+$/, '') + '/?' // remove trailing slashes and add optional slash\n }\n return this._regexBaseString\n }\n\n get regexString(): string {\n if (this._regexString === undefined) {\n this._regexString = `^${this.regexBaseString}$`\n }\n return this._regexString\n }\n\n get regex(): RegExp {\n if (this._regex === undefined) {\n this._regex = new RegExp(this.regexString)\n }\n return this._regex\n }\n\n get regexAncestor(): RegExp {\n if (this._regexAncestor === undefined) {\n this._regexAncestor = new RegExp(`^${this.regexBaseString}(?:/.*)?$`)\n }\n return this._regexAncestor\n }\n\n private get regexDescendantMatchers(): Array<{ regex: RegExp; captureKeys: string[] }> {\n if (this._regexDescendantMatchers === undefined) {\n const matchers: Array<{ regex: RegExp; captureKeys: string[] }> = []\n if (this.definitionParts[0] !== '/') {\n let pattern = ''\n const captureKeys: string[] = []\n for (const part of this.definitionParts) {\n if (part.startsWith(':')) {\n pattern += '/([^/]+)'\n captureKeys.push(part.replace(/^:/, '').replace(/\\?$/, ''))\n } else if (part.includes('*')) {\n const prefix = part.replace(/\\*\\??$/, '')\n pattern += `/${escapeRegex(prefix)}[^/]*`\n captureKeys.push('*')\n } else {\n pattern += `/${escapeRegex(part)}`\n }\n matchers.push({\n regex: new RegExp(`^${pattern}/?$`),\n captureKeys: [...captureKeys],\n })\n }\n }\n this._regexDescendantMatchers = matchers\n }\n return this._regexDescendantMatchers\n }\n\n private get captureKeys(): string[] {\n if (this._captureKeys === undefined) {\n this._captureKeys = this.routeTokens\n .filter((token): token is Extract<RouteToken, { kind: 'param' | 'wildcard' }> => token.kind !== 'static')\n .map((token) => (token.kind === 'param' ? token.name : '*'))\n }\n return this._captureKeys\n }\n\n private get routeSegments(): string[] {\n if (this._routeSegments === undefined) {\n this._routeSegments = Route0._getRouteSegments(this.definition)\n }\n return this._routeSegments\n }\n\n private get routeTokens(): RouteToken[] {\n if (this._routeTokens === undefined) {\n this._routeTokens = this.routeSegments.map((segment): RouteToken => {\n const param = segment.match(/^:([A-Za-z0-9_]+)(\\?)?$/)\n if (param) {\n return { kind: 'param', name: param[1], optional: param[2] === '?' }\n }\n if (segment === '*' || segment === '*?') {\n return { kind: 'wildcard', prefix: '', optional: segment.endsWith('?') }\n }\n const wildcard = segment.match(/^(.*)\\*(\\?)?$/)\n if (wildcard && !segment.includes('\\\\*')) {\n return { kind: 'wildcard', prefix: wildcard[1], optional: wildcard[2] === '?' }\n }\n return { kind: 'static', value: segment }\n })\n }\n return this._routeTokens\n }\n\n private get routePatternCandidates(): string[] {\n if (this._routePatternCandidates === undefined) {\n const values = (token: RouteToken): string[] => {\n if (token.kind === 'static') return [token.value]\n if (token.kind === 'param') return token.optional ? ['', 'x', 'y'] : ['x', 'y']\n if (token.prefix.length > 0)\n return [token.prefix, `${token.prefix}-x`, `${token.prefix}/x`, `${token.prefix}/y/z`]\n return ['', 'x', 'y', 'x/y']\n }\n let acc: string[] = ['']\n for (const token of this.routeTokens) {\n const next: string[] = []\n for (const base of acc) {\n for (const value of values(token)) {\n if (value === '') {\n next.push(base)\n } else if (value.startsWith('/')) {\n next.push(`${base}${value}`)\n } else {\n next.push(`${base}/${value}`)\n }\n }\n }\n // Keep candidate space bounded for large route definitions.\n acc = next.length > 512 ? next.slice(0, 512) : next\n }\n this._routePatternCandidates =\n acc.length === 0 ? ['/'] : Array.from(new Set(acc.map((x) => (x === '' ? '/' : collapseDuplicateSlashes(x)))))\n }\n return this._routePatternCandidates\n }\n\n private get pathParamsDefinition(): Record<string, boolean> {\n if (this._pathParamsDefinition === undefined) {\n const entries = this.routeTokens\n .filter((t) => t.kind !== 'static')\n .map((t): [string, boolean] => (t.kind === 'param' ? [t.name, !t.optional] : ['*', !t.optional]))\n this._pathParamsDefinition = Object.fromEntries(entries)\n }\n return this._pathParamsDefinition\n }\n\n private get definitionWithoutTrailingWildcard(): string {\n if (this._definitionWithoutTrailingWildcard === undefined) {\n this._definitionWithoutTrailingWildcard = this.definition.replace(/\\*\\??$/, '')\n }\n return this._definitionWithoutTrailingWildcard\n }\n\n private get routeRegexBaseStringRaw(): string {\n if (this._routeRegexBaseStringRaw === undefined) {\n if (this.routeTokens.length === 0) {\n this._routeRegexBaseStringRaw = ''\n } else {\n let pattern = ''\n for (const token of this.routeTokens) {\n if (token.kind === 'static') {\n pattern += `/${escapeRegex(token.value)}`\n continue\n }\n if (token.kind === 'param') {\n pattern += token.optional ? '(?:/([^/]+))?' : '/([^/]+)'\n continue\n }\n if (token.prefix.length > 0) {\n pattern += `/${escapeRegex(token.prefix)}(.*)`\n } else {\n // Wouter-compatible splat: /orders/* matches /orders and /orders/...\n pattern += '(?:/(.*))?'\n }\n }\n this._routeRegexBaseStringRaw = pattern\n }\n }\n return this._routeRegexBaseStringRaw\n }\n\n private get normalizedDefinition(): string {\n if (this._normalizedDefinition === undefined) {\n this._normalizedDefinition =\n this.definition.length > 1 && this.definition.endsWith('/') ? this.definition.slice(0, -1) : this.definition\n }\n return this._normalizedDefinition\n }\n\n private get definitionParts(): string[] {\n if (this._definitionParts === undefined) {\n this._definitionParts =\n this.normalizedDefinition === '/' ? ['/'] : this.normalizedDefinition.split('/').filter(Boolean)\n }\n return this._definitionParts\n }\n\n /** Fast pathname exact match check without building a full relation object. */\n isExact(pathname: string, normalize = true): boolean {\n const normalizedPathname = normalize ? Route0.normalizeSlash(pathname) : pathname\n return this.regex.test(normalizedPathname)\n }\n\n /** Fast pathname exact or ancestor match check without building a full relation object. */\n isExactOrAncestor(pathname: string, normalize = true): boolean {\n const normalizedPathname = normalize ? Route0.normalizeSlash(pathname) : pathname\n return this.regex.test(normalizedPathname) || this.regexAncestor.test(normalizedPathname)\n }\n\n /** True when route is ancestor of pathname (pathname is deeper). */\n isAncestor(pathname: string, normalize = true): boolean {\n const normalizedPathname = normalize ? Route0.normalizeSlash(pathname) : pathname\n return !this.regex.test(normalizedPathname) && this.regexAncestor.test(normalizedPathname)\n }\n\n /** True when route is descendant of pathname (pathname is shallower). */\n isDescendant(pathname: string, normalize = true): boolean {\n const normalizedPathname = normalize ? Route0.normalizeSlash(pathname) : pathname\n if (this.regex.test(normalizedPathname) || this.regexAncestor.test(normalizedPathname)) {\n return false\n }\n for (const matcher of this.regexDescendantMatchers) {\n if (normalizedPathname.match(matcher.regex)) {\n return true\n }\n }\n return false\n }\n\n /** Creates a grouped regex pattern string from many routes. */\n static getRegexStringGroup(routes: AnyRoute[]): string {\n const patterns = routes.map((route) => route.regexString).join('|')\n return `(${patterns})`\n }\n\n /** Creates a grouped regex from many routes. */\n static getRegexGroup(routes: AnyRoute[]): RegExp {\n const patterns = Route0.getRegexStringGroup(routes)\n return new RegExp(`^(${patterns})$`)\n }\n\n /** Converts any location shape to relative form (removes host/origin fields). */\n static toRelLocation<TLocation extends AnyLocation>(location: TLocation): TLocation {\n return {\n ...location,\n abs: false,\n origin: undefined,\n href: undefined,\n port: undefined,\n host: undefined,\n hostname: undefined,\n }\n }\n\n /** Converts a location to absolute form using provided origin URL. */\n static toAbsLocation<TLocation extends AnyLocation>(location: TLocation, origin: string): TLocation {\n const relLoc = Route0.toRelLocation(location)\n const url = new URL(relLoc.hrefRel, origin)\n return {\n ...location,\n abs: true,\n origin: url.origin,\n href: url.href,\n port: url.port,\n host: url.host,\n hostname: url.hostname,\n }\n }\n\n /**\n * Parses a URL-like input into raw location object (without route knowledge).\n *\n * Result is always `UnknownLocation` because no route matching is applied.\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 // Common derived values\n const hrefRel = url.pathname + url.search + url.hash\n\n // Build the location object consistent with _GeneralLocation\n let _search: UnknownSearchParsed | undefined\n const location: UnknownLocation = {\n pathname: url.pathname,\n get search() {\n if (_search === undefined) {\n _search = parseSearchQuery(url.search)\n }\n return _search\n },\n searchString: 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 params: undefined,\n route: undefined,\n }\n\n return location\n }\n\n // /**\n // * Parses input and returns location only for exact route matches.\n // */\n // getLocation(href: `${string}://${string}`): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(hrefRel: `/${string}`): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(hrefOrHrefRel: string): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(location: AnyLocation): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(url: AnyLocation): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): ExactLocation<TDefinition> | UnknownLocation {\n // const relation = this.getRelation(hrefOrHrefRelOrLocation)\n // if (!relation.exact) {\n // return Route0.getLocation(hrefOrHrefRelOrLocation)\n // }\n // const location = Route0.getLocation(hrefOrHrefRelOrLocation)\n // return {\n // ...location,\n // route: this.definition as Definition<TDefinition>,\n // params: relation.params as ParamsOutput<TDefinition>,\n // }\n // }\n\n /**\n * Parses input and evaluates pathname relation to this route.\n */\n getRelation(href: `${string}://${string}`): RouteRelation<TDefinition>\n getRelation(hrefRel: `/${string}`): RouteRelation<TDefinition>\n getRelation(hrefOrHrefRel: string): RouteRelation<TDefinition>\n getRelation(location: AnyLocation): RouteRelation<TDefinition>\n getRelation(url: URL): RouteRelation<TDefinition>\n getRelation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): RouteRelation<TDefinition>\n getRelation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): RouteRelation<TDefinition> {\n if (hrefOrHrefRelOrLocation instanceof URL) {\n return this.getRelation(hrefOrHrefRelOrLocation.href)\n }\n if (typeof hrefOrHrefRelOrLocation !== 'string') {\n hrefOrHrefRelOrLocation = hrefOrHrefRelOrLocation.href || hrefOrHrefRelOrLocation.hrefRel\n }\n // Normalize pathname (no trailing slash except root)\n const pathname = Route0.normalizeSlash(new URL(hrefOrHrefRelOrLocation, 'http://example.com').pathname)\n\n const paramNames = this.captureKeys\n const exactRe = this.regex\n const exactMatch = pathname.match(exactRe)\n\n if (exactMatch) {\n const values = exactMatch.slice(1, 1 + paramNames.length)\n const params = Object.fromEntries(\n paramNames.map((n, i) => {\n const value = values[i] as string | undefined\n return [n, value === undefined ? undefined : decodeURIComponent(value)]\n }),\n )\n return {\n type: 'exact',\n route: this.definition as Definition<TDefinition>,\n params: params as ParamsOutput<TDefinition>,\n exact: true,\n ascendant: false,\n descendant: false,\n unmatched: false,\n }\n }\n\n const ancestorRe = this.regexAncestor\n const ancestorMatch = pathname.match(ancestorRe)\n if (ancestorMatch) {\n const values = ancestorMatch.slice(1, 1 + paramNames.length)\n const params = Object.fromEntries(\n paramNames.map((n, i) => {\n const value = values[i] as string | undefined\n return [n, value === undefined ? undefined : decodeURIComponent(value)]\n }),\n )\n return {\n type: 'ascendant',\n route: this.definition as Definition<TDefinition>,\n params: params as ParamsOutput<TDefinition> & { [key: string]: string | undefined },\n exact: false,\n ascendant: true,\n descendant: false,\n unmatched: false,\n }\n }\n\n let descendantMatch: RegExpMatchArray | null = null\n let descendantCaptureKeys: string[] = []\n for (const matcher of this.regexDescendantMatchers) {\n const match = pathname.match(matcher.regex)\n if (!match) continue\n descendantMatch = match\n descendantCaptureKeys = matcher.captureKeys\n break\n }\n\n if (descendantMatch) {\n const values = descendantMatch.slice(1, 1 + descendantCaptureKeys.length)\n const params = Object.fromEntries(\n descendantCaptureKeys.map((key, index) => [key, decodeURIComponent(values[index] as string)]),\n )\n return {\n type: 'descendant',\n route: this.definition as Definition<TDefinition>,\n params: params as Partial<ParamsOutput<TDefinition>>,\n exact: false,\n ascendant: false,\n descendant: true,\n unmatched: false,\n }\n }\n\n return {\n type: 'unmatched',\n route: this.definition as Definition<TDefinition>,\n params: {},\n exact: false,\n ascendant: false,\n descendant: false,\n unmatched: true,\n }\n }\n\n private _validateParamsInput(input: unknown): StandardSchemaV1.Result<ParamsOutput<TDefinition>> {\n const paramsEntries = Object.entries(this.params) as Array<[string, boolean]>\n const paramsMap = this.params as Record<string, boolean>\n const requiredParamsKeys = paramsEntries.filter(([, required]) => required).map(([k]) => k)\n const paramsKeys = paramsEntries.map(([k]) => k)\n if (input === undefined) {\n if (requiredParamsKeys.length) {\n return {\n issues: [\n {\n message: `Missing params: ${requiredParamsKeys.map((k) => `\"${k}\"`).join(', ')}`,\n },\n ],\n }\n }\n input = {}\n }\n if (typeof input !== 'object' || input === null) {\n return {\n issues: [{ message: 'Invalid route params: expected object' }],\n }\n }\n const inputObj = input as Record<string, unknown>\n const inputKeys = Object.keys(inputObj)\n const notDefinedKeys = requiredParamsKeys.filter((k) => !inputKeys.includes(k))\n if (notDefinedKeys.length) {\n return {\n issues: [\n {\n message: `Missing params: ${notDefinedKeys.map((k) => `\"${k}\"`).join(', ')}`,\n },\n ],\n }\n }\n const data: Record<string, string | undefined> = {}\n for (const k of paramsKeys) {\n const v = inputObj[k]\n const required = paramsMap[k]\n if (v === undefined && !required) {\n data[k] = undefined as never\n } else if (typeof v === 'string') {\n data[k] = v\n } else if (typeof v === 'number') {\n data[k] = String(v)\n } else {\n return {\n issues: [{ message: `Invalid route params: expected string, number, got ${typeof v} for \"${k}\"` }],\n }\n }\n }\n return {\n value: data as ParamsOutput<TDefinition>,\n }\n }\n\n private _safeParseSchemaResult<TOutput extends Record<string, unknown>>(\n result: StandardSchemaV1.Result<TOutput>,\n ): _SafeParseInputResult<TOutput> {\n if ('issues' in result) {\n return {\n success: false,\n data: undefined,\n error: new Error(result.issues?.[0]?.message ?? 'Invalid input'),\n }\n }\n return {\n success: true,\n data: result.value,\n error: undefined,\n }\n }\n\n private _parseSchemaResult<TOutput extends Record<string, unknown>>(\n result: StandardSchemaV1.Result<TOutput>,\n ): TOutput {\n const safeResult = this._safeParseSchemaResult(result)\n if (safeResult.error) {\n throw safeResult.error\n }\n return safeResult.data\n }\n\n /** Standard Schema for route params input. */\n readonly schema: SchemaRoute0<ParamsInput<TDefinition>, ParamsOutput<TDefinition>> = {\n '~standard': {\n version: 1,\n vendor: 'route0',\n validate: (value) => this._validateParamsInput(value),\n types: undefined as unknown as StandardSchemaV1.Types<ParamsInput<TDefinition>, ParamsOutput<TDefinition>>,\n },\n parse: (value) => this._parseSchemaResult(this._validateParamsInput(value)),\n safeParse: (value) => this._safeParseSchemaResult(this._validateParamsInput(value)),\n }\n\n // /** True when path structure is equal (param names are ignored). */\n // isSame(other: AnyRoute): boolean {\n // const thisShape = this.routeTokens\n // .map((t) => {\n // if (t.kind === 'static') return `s:${t.value}`\n // if (t.kind === 'param') return `p:${t.optional ? 'o' : 'r'}`\n // return `w:${t.prefix}:${t.optional ? 'o' : 'r'}`\n // })\n // .join('/')\n // const otherRoute = Route0.from(other) as Route0<string, UnknownSearchInput>\n // const otherShape = otherRoute.routeTokens\n // .map((t) => {\n // if (t.kind === 'static') return `s:${t.value}`\n // if (t.kind === 'param') return `p:${t.optional ? 'o' : 'r'}`\n // return `w:${t.prefix}:${t.optional ? 'o' : 'r'}`\n // })\n // .join('/')\n // return thisShape === otherShape\n // }\n // /** Static convenience wrapper for `isSame`. */\n // static isSame(a: AnyRoute | string | undefined, b: AnyRoute | string | undefined): boolean {\n // if (!a) {\n // if (!b) return true\n // return false\n // }\n // if (!b) {\n // return false\n // }\n // return Route0.create(a).isSame(Route0.create(b))\n // }\n\n // /** True when current route is more specific/deeper than `other`. */\n // isDescendant(other: AnyRoute | string | undefined): boolean {\n // if (!other) return false\n // other = Route0.create(other)\n // // this is a descendant of other if:\n // // - paths are not exactly the same\n // // - other's path is a prefix of this path, matching params as wildcards\n // const getParts = (path: string) => (path === '/' ? ['/'] : path.split('/').filter(Boolean))\n // // Root is ancestor of any non-root; thus any non-root is a descendant of root\n // if (other.definition === '/' && this.definition !== '/') {\n // return true\n // }\n // const thisParts = getParts(this.definition)\n // const otherParts = getParts(other.definition)\n\n // // A descendant must be deeper\n // if (thisParts.length <= otherParts.length) return false\n\n // const matchesPatternPart = (patternPart: string, valuePart: string): { match: boolean; wildcard: boolean } => {\n // if (patternPart.startsWith(':')) return { match: true, wildcard: false }\n // const wildcardIndex = patternPart.indexOf('*')\n // if (wildcardIndex >= 0) {\n // const prefix = patternPart.slice(0, wildcardIndex)\n // return { match: prefix.length === 0 || valuePart.startsWith(prefix), wildcard: true }\n // }\n // return { match: patternPart === valuePart, wildcard: false }\n // }\n\n // for (let i = 0; i < otherParts.length; i++) {\n // const otherPart = otherParts[i]\n // const thisPart = thisParts[i]\n // const result = matchesPatternPart(otherPart, thisPart)\n // if (!result.match) return false\n // if (result.wildcard) return true\n // }\n // // Not equal (depth already ensures not equal)\n // return true\n // }\n\n // /** True when current route is broader/shallower than `other`. */\n // isAncestor(other: AnyRoute | string | undefined): boolean {\n // if (!other) return false\n // other = Route0.create(other)\n // // this is an ancestor of other if:\n // // - paths are not exactly the same\n // // - this path is a prefix of other path, matching params as wildcards\n // const getParts = (path: string) => (path === '/' ? ['/'] : path.split('/').filter(Boolean))\n // // Root is ancestor of any non-root path\n // if (this.definition === '/' && other.definition !== '/') {\n // return true\n // }\n // const thisParts = getParts(this.definition)\n // const otherParts = getParts(other.definition)\n\n // // An ancestor must be shallower\n // if (thisParts.length >= otherParts.length) return false\n\n // const matchesPatternPart = (patternPart: string, valuePart: string): { match: boolean; wildcard: boolean } => {\n // if (patternPart.startsWith(':')) return { match: true, wildcard: false }\n // const wildcardIndex = patternPart.indexOf('*')\n // if (wildcardIndex >= 0) {\n // const prefix = patternPart.slice(0, wildcardIndex)\n // return { match: prefix.length === 0 || valuePart.startsWith(prefix), wildcard: true }\n // }\n // return { match: patternPart === valuePart, wildcard: false }\n // }\n\n // for (let i = 0; i < thisParts.length; i++) {\n // const thisPart = thisParts[i]\n // const otherPart = otherParts[i]\n // const result = matchesPatternPart(thisPart, otherPart)\n // if (!result.match) return false\n // if (result.wildcard) return true\n // }\n // // Not equal (depth already ensures not equal)\n // return true\n // }\n\n /** True when two route patterns can match the same concrete URL. */\n isOverlap(other: AnyRoute | string | undefined): boolean {\n if (!other) return false\n const otherRoute = Route0.from(other) as Route0<string, UnknownSearchInput>\n const thisRegex = this.regex\n const otherRegex = otherRoute.regex\n const thisCandidates = this.routePatternCandidates\n const otherCandidates = otherRoute.routePatternCandidates\n if (thisCandidates.some((path) => otherRegex.test(path))) return true\n if (otherCandidates.some((path) => thisRegex.test(path))) return true\n return false\n }\n\n /**\n * True when overlap is not resolvable by route ordering inside one route set.\n *\n * Non-conflicting overlap means one route is a strict subset of another\n * (e.g. `/x/y` is a strict subset of `/x/:id`) and can be safely ordered first.\n */\n isConflict(other: AnyRoute | string | undefined): boolean {\n if (!other) return false\n const otherRoute = Route0.from(other) as Route0<string, UnknownSearchInput>\n if (!this.isOverlap(otherRoute)) return false\n const thisRegex = this.regex\n const otherRegex = otherRoute.regex\n const thisCandidates = this.routePatternCandidates\n const otherCandidates = otherRoute.routePatternCandidates\n const thisExclusive = thisCandidates.some((path) => thisRegex.test(path) && !otherRegex.test(path))\n const otherExclusive = otherCandidates.some((path) => otherRegex.test(path) && !thisRegex.test(path))\n // Exactly one side has exclusive matches => strict subset => resolvable by ordering.\n if (thisExclusive !== otherExclusive) return false\n // Both exclusive (partial overlap) OR none exclusive (equal languages) => real conflict.\n return true\n }\n\n /** Specificity comparator used for deterministic route ordering. */\n isMoreSpecificThan(other: AnyRoute | string | undefined): boolean {\n if (!other) return false\n other = Route0.create(other)\n const getParts = (path: string) => {\n if (path === '/') return ['/']\n return path.split('/').filter(Boolean)\n }\n const rank = (part: string): number => {\n if (part.includes('*')) return -1\n if (part.startsWith(':') && part.endsWith('?')) return 0\n if (part.startsWith(':')) return 1\n return 2\n }\n const thisParts = getParts(this.definition)\n const otherParts = getParts(other.definition)\n for (let i = 0; i < Math.min(thisParts.length, otherParts.length); i++) {\n const thisRank = rank(thisParts[i])\n const otherRank = rank(otherParts[i])\n if (thisRank > otherRank) return true\n if (thisRank < otherRank) return false\n }\n return this.definition < other.definition\n }\n}\n\n/**\n * Typed route collection with deterministic matching order.\n *\n * `Routes.create()` accepts either plain string definitions or route objects\n * and returns a \"pretty\" object with direct route access + helper methods under `._`.\n */\n\nexport class Routes<const T extends RoutesRecord = any> {\n _routes: RoutesRecordHydrated<T>\n _pathsOrdering: string[]\n _keysOrdering: string[]\n _ordered: CallableRoute[]\n\n _: {\n routes: Routes<T>['_routes']\n getLocation: Routes<T>['_getLocation']\n clone: Routes<T>['_clone']\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?: CallableRoute[]\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 this._ = {\n routes: this._routes,\n getLocation: this._getLocation.bind(this),\n clone: this._clone.bind(this),\n pathsOrdering: this._pathsOrdering,\n keysOrdering: this._keysOrdering,\n ordered: this._ordered,\n }\n }\n\n /** Creates and hydrates a typed routes collection. */\n static create<const T extends RoutesRecord>(routes: T, override?: RouteConfigInput): RoutesPretty<T> {\n const result = Routes.prettify(new Routes({ routes }))\n if (!override) {\n return result\n }\n return result._.clone(override)\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 clone: instance._clone.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.hasOwn(routes, key)) {\n const value = routes[key]\n result[key] = (typeof value === 'string' ? Route0.create(value) : value) as CallableRoute<T[typeof key]>\n }\n }\n return result\n }\n\n /**\n * Matches an input URL against collection routes.\n *\n * Returns first exact match according to precomputed ordering,\n * otherwise returns `UnknownLocation`.\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 const input = hrefOrHrefRelOrLocation\n const location = Route0.getLocation(input)\n for (const route of this._ordered) {\n if (route.isExact(location.pathname, false)) {\n const relation = route.getRelation(input)\n return Object.assign(location, {\n route: route.definition,\n params: relation.params,\n }) as ExactLocation\n }\n }\n return location as UnknownLocation\n }\n\n private static makeOrdering(routes: RoutesRecord): {\n pathsOrdering: string[]\n keysOrdering: string[]\n } {\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: overlapping routes by specificity first, otherwise by path depth and alphabetically.\n entries.sort(([_keyA, routeA], [_keyB, routeB]) => {\n const partsA = getParts(routeA.definition)\n const partsB = getParts(routeB.definition)\n\n // 1. Overlapping routes: more specific first\n if (routeA.isOverlap(routeB)) {\n if (routeA.isMoreSpecificThan(routeB)) return -1\n if (routeB.isMoreSpecificThan(routeA)) return 1\n }\n\n // 2. Different non-overlapping depth: shorter first\n if (partsA.length !== partsB.length) {\n return partsA.length - partsB.length\n }\n\n // 3. Fallback: alphabetically for deterministic ordering\n return routeA.definition.localeCompare(routeB.definition)\n })\n\n const pathsOrdering = entries.map(([_key, route]) => route.definition)\n const keysOrdering = entries.map(([_key]) => _key)\n return { pathsOrdering, keysOrdering }\n }\n\n /** Returns a cloned routes collection with config applied to each route. */\n _clone(config: RouteConfigInput): RoutesPretty<T> {\n const newRoutes = {} as RoutesRecordHydrated<T>\n for (const key in this._routes) {\n if (Object.hasOwn(this._routes, key)) {\n newRoutes[key] = this._routes[key].clone(config) as CallableRoute<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\n/** Any route instance shape, preserving literal path type when known. */\nexport type AnyRoute<\n T extends Route0<string> | string = string,\n TSearch extends UnknownSearchInput = UnknownSearchInput,\n> = T extends string ? Route0<T, TSearch> : T\n/** Callable route (`route(input)`) plus route instance methods/properties. */\nexport type CallableRoute<\n T extends Route0<string> | string = string,\n TSearch extends UnknownSearchInput = UnknownSearchInput,\n> = AnyRoute<T, TSearch> & AnyRoute<T, TSearch>['get']\n/** Route input accepted by most APIs: definition string or route object/callable. */\nexport type AnyRouteOrDefinition<T extends string = string> = AnyRoute<T> | CallableRoute<T> | T\n/** Route-level runtime configuration. */\nexport type RouteConfigInput = {\n origin?: string\n}\n\n// collection\n\n/** User-provided routes map (plain definitions or route instances). */\nexport type RoutesRecord = Record<string, AnyRoute | string>\n/** Same as `RoutesRecord` but all values normalized to callable routes. */\nexport type RoutesRecordHydrated<TRoutesRecord extends RoutesRecord = any> = {\n [K in keyof TRoutesRecord]: CallableRoute<TRoutesRecord[K]>\n}\n/** Public shape returned by `Routes.create()`. Default `any` so `satisfies RoutesPretty` accepts any created routes. */\nexport type RoutesPretty<TRoutesRecord extends RoutesRecord = any> = RoutesRecordHydrated<TRoutesRecord> &\n Omit<Routes<TRoutesRecord>, '_routes' | '_getLocation' | '_clone' | '_pathsOrdering' | '_keysOrdering' | '_ordered'>\nexport type ExtractRoutesKeys<TRoutes extends RoutesPretty | RoutesRecord> = TRoutes extends RoutesPretty\n ? Extract<keyof TRoutes['_']['routes'], string>\n : TRoutes extends RoutesRecord\n ? Extract<keyof TRoutes, string>\n : never\nexport type ExtractRoute<\n TRoutes extends RoutesPretty | RoutesRecord,\n TKey extends ExtractRoutesKeys<TRoutes>,\n> = TRoutes extends RoutesPretty ? TRoutes['_']['routes'][TKey] : TRoutes extends RoutesRecord ? 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 ParamsDefinition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['params']\n : T extends string\n ? _ParamsDefinition<T>\n : undefined\nexport type Extended<\n T extends AnyRoute | string | undefined,\n TSuffixDefinition extends string,\n TSearchInput extends UnknownSearchInput = UnknownSearchInput,\n> = T extends AnyRoute\n ? Route0<PathExtended<T['definition'], TSuffixDefinition>, TSearchInput>\n : T extends string\n ? Route0<PathExtended<T, TSuffixDefinition>, TSearchInput>\n : T extends undefined\n ? Route0<TSuffixDefinition, TSearchInput>\n : never\n\n// export type IsAncestor<T extends AnyRoute | string, TAncestor extends AnyRoute | string> = _IsAncestor<\n// Definition<T>,\n// Definition<TAncestor>\n// >\n// export type IsDescendant<T extends AnyRoute | string, TDescendant extends AnyRoute | string> = _IsDescendant<\n// Definition<T>,\n// Definition<TDescendant>\n// >\n// export type IsSame<T extends AnyRoute | string, TExact extends AnyRoute | string> = _IsSame<\n// Definition<T>,\n// Definition<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> = keyof _ParamsDefinition<Definition<T>> extends never ? false : true\nexport type HasWildcard<T extends AnyRoute | string> = Definition<T> extends `${string}*${string}` ? true : false\nexport type HasRequiredParams<T extends AnyRoute | string> =\n _RequiredParamKeys<Definition<T>> extends never ? false : true\n\nexport type ParamsOutput<T extends AnyRoute | string> = {\n [K in keyof ParamsDefinition<T>]: ParamsDefinition<T>[K] extends true ? string : string | undefined\n}\nexport type ParamsInput<T extends AnyRoute | string = string> = _ParamsInput<Definition<T>>\nexport type IsParamsOptional<T extends AnyRoute | string> = HasRequiredParams<Definition<T>> extends true ? false : true\nexport type ParamsInputStringOnly<T extends AnyRoute | string = string> = _ParamsInputStringOnly<Definition<T>>\n\n// location\n\nexport type LocationParams<TDefinition extends string> = {\n [K in keyof _ParamsDefinition<TDefinition>]: _ParamsDefinition<TDefinition>[K] extends true\n ? string\n : string | undefined\n}\n\n/**\n * URL location primitives independent from route-matching state.\n *\n * `hrefRel` is relative href and includes `pathname + search + hash`.\n */\nexport type _GeneralLocation = {\n /**\n * Path without search/hash (normalized for trailing slash).\n *\n * Example:\n * - input: `https://example.com/users/42?tab=posts#section`\n * - pathname: `/users/42`\n */\n pathname: string\n /**\n * Parsed query object.\n *\n * Example:\n * - `{ tab: \"posts\", sort: \"desc\" }`\n */\n search: UnknownSearchParsed\n /**\n * Raw query string with leading `?`, if present, else empty string.\n *\n * Example:\n * - `?tab=posts&sort=desc`\n */\n searchString: string\n /**\n * Raw hash with leading `#`, if present, else empty string.\n *\n * Example:\n * - `#section`\n */\n hash: string\n /**\n * URL origin for absolute inputs.\n *\n * Example:\n * - href: `https://example.com/users/42`\n * - origin: `https://example.com`\n */\n origin: string | undefined\n /**\n * Full absolute href for absolute inputs.\n *\n * Example:\n * - `https://example.com/users/42?tab=posts#section`\n */\n href: string | undefined\n /**\n * Relative href (`pathname + search + hash`).\n *\n * Example:\n * - pathname: `/users/42`\n * - search: `?tab=posts`\n * - hash: `#section`\n * - hrefRel: `/users/42?tab=posts#section`\n */\n hrefRel: string\n /**\n * Whether input was absolute URL.\n *\n * Examples:\n * - `https://example.com/users/42` -> `true`\n * - `/users/42` -> `false`\n */\n abs: boolean\n port: string | undefined\n host: string | undefined\n hostname: string | undefined\n}\n/** Location state before matching against a concrete route. */\nexport type UnknownLocationState = {\n route: undefined\n params: undefined\n}\nexport type UnknownLocation = _GeneralLocation & UnknownLocationState\n\n/** Exact match state for a known route. */\nexport type ExactLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: Definition<TRoute>\n params: ParamsOutput<TRoute>\n}\nexport type ExactLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n ExactLocationState<TRoute>\n\nexport type ExactRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {\n type: 'exact'\n route: Definition<TRoute>\n params: ParamsOutput<TRoute>\n exact: true\n ascendant: false\n descendant: false\n unmatched: false\n}\nexport type AscendantRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {\n type: 'ascendant'\n route: Definition<TRoute>\n params: ParamsOutput<TRoute> & { [key: string]: string | undefined }\n exact: false\n ascendant: true\n descendant: false\n unmatched: false\n}\nexport type DescendantRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {\n type: 'descendant'\n route: Definition<TRoute>\n params: Partial<ParamsOutput<TRoute>>\n exact: false\n ascendant: false\n descendant: true\n unmatched: false\n}\nexport type UnmatchedRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {\n type: 'unmatched'\n route: Definition<TRoute>\n params: Record<never, never>\n exact: false\n ascendant: false\n descendant: false\n unmatched: true\n}\nexport type RouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> =\n | ExactRouteRelation<TRoute>\n | AscendantRouteRelation<TRoute>\n | DescendantRouteRelation<TRoute>\n | UnmatchedRouteRelation<TRoute>\n\nexport type UnknownSearchParsedValue = string | UnknownSearchParsed | Array<UnknownSearchParsedValue>\nexport interface UnknownSearchParsed {\n [key: string]: UnknownSearchParsedValue\n}\n\nexport type UnknownSearchInput = Record<string, unknown>\n\n/** Input URL is a descendant of route definition (route is ancestor). */\nexport type AncestorLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: string\n params: IsAny<TRoute> extends true ? any : ParamsOutput<TRoute> & { [key: string]: string | undefined }\n}\nexport type AncestorLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n AncestorLocationState<TRoute>\n\n/** It is when route not match at all, but params match. */\nexport type WeakAncestorLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: string\n params: IsAny<TRoute> extends true ? any : ParamsOutput<TRoute> & { [key: string]: string | undefined }\n}\nexport type WeakAncestorLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n WeakAncestorLocationState<TRoute>\n\n/** Input URL is an ancestor prefix of route definition (route is descendant). */\nexport type DescendantLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: string\n params: Partial<ParamsOutput<TRoute>>\n}\nexport type DescendantLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n DescendantLocationState<TRoute>\n\n/** It is when route not match at all, but params partially match. */\nexport type WeakDescendantLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: string\n params: Partial<ParamsOutput<TRoute>>\n}\nexport type WeakDescendantLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n WeakDescendantLocationState<TRoute>\nexport type KnownLocation<TRoute extends AnyRoute | string = AnyRoute | string> =\n | ExactLocation<TRoute>\n | AncestorLocation<TRoute>\n | WeakAncestorLocation<TRoute>\n | DescendantLocation<TRoute>\n | WeakDescendantLocation<TRoute>\nexport type AnyLocation<TRoute extends AnyRoute | string = AnyRoute | string> = UnknownLocation | KnownLocation<TRoute>\n\n// internal utils\n\nexport type _ParamsDefinition<TDefinition extends string> = _ExtractParamsDefinitionBySegments<\n _SplitPathSegments<Definition<TDefinition>>\n>\n\nexport type _Simplify<T> = { [K in keyof T]: T[K] } & {}\nexport type _IfNoKeys<T extends object, TYes, TNo> = keyof T extends never ? TYes : TNo\n\nexport type _ParamsInput<TDefinition extends string> =\n _ParamsDefinition<TDefinition> extends infer TDef extends Record<string, boolean>\n ? _IfNoKeys<\n TDef,\n Record<never, never>,\n _Simplify<\n {\n [K in keyof TDef as TDef[K] extends true ? K : never]: string | number\n } & {\n [K in keyof TDef as TDef[K] extends false ? K : never]?: string | number | undefined\n }\n >\n >\n : Record<never, never>\n\nexport type _ParamsInputStringOnly<TDefinition extends string> =\n _ParamsDefinition<TDefinition> extends infer TDef extends Record<string, boolean>\n ? _IfNoKeys<\n TDef,\n Record<never, never>,\n _Simplify<\n {\n [K in keyof TDef as TDef[K] extends true ? K : never]: string\n } & {\n [K in keyof TDef as TDef[K] extends false ? K : never]?: string | undefined\n }\n >\n >\n : Record<never, never>\n\nexport type _SplitPathSegments<TPath extends string> = TPath extends ''\n ? []\n : TPath extends '/'\n ? []\n : TPath extends `/${infer Rest}`\n ? _SplitPathSegments<Rest>\n : TPath extends `${infer Segment}/${infer Rest}`\n ? Segment extends ''\n ? _SplitPathSegments<Rest>\n : [Segment, ..._SplitPathSegments<Rest>]\n : TPath extends ''\n ? []\n : [TPath]\n\nexport type _ParamDefinitionFromSegment<TSegment extends string> = TSegment extends `:${infer Name}?`\n ? { [K in Name]: false }\n : TSegment extends `:${infer Name}`\n ? { [K in Name]: true }\n : TSegment extends `${string}*?`\n ? { '*': false }\n : TSegment extends `${string}*`\n ? { '*': true }\n : Record<never, never>\n\nexport type _MergeParamDefinitions<A extends Record<string, boolean>, B extends Record<string, boolean>> = {\n [K in keyof A | keyof B]: K extends keyof B ? B[K] : K extends keyof A ? A[K] : never\n}\n\nexport type _ExtractParamsDefinitionBySegments<TSegments extends string[]> = TSegments extends [\n infer Segment extends string,\n ...infer Rest extends string[],\n]\n ? _MergeParamDefinitions<_ParamDefinitionFromSegment<Segment>, _ExtractParamsDefinitionBySegments<Rest>>\n : Record<never, never>\n\nexport type _RequiredParamKeys<TDefinition extends string> = {\n [K in keyof _ParamsDefinition<TDefinition>]: _ParamsDefinition<TDefinition>[K] extends true ? K : never\n}[keyof _ParamsDefinition<TDefinition>]\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 EnsureLeadingSlash<S extends string> = S extends '' ? '/' : S extends `/${string}` ? S : `/${S}`\nexport type TrimTrailingSlash<S extends string> = S extends '/'\n ? '/'\n : S extends `${infer V}/`\n ? TrimTrailingSlash<V>\n : S\nexport type NormalizeRouteDefinition<S extends string> = TrimTrailingSlash<EnsureLeadingSlash<DedupeSlashes<S>>>\nexport type EmptyRecord = Record<never, never>\nexport type JoinPath<Parent extends string, Suffix extends string> = NormalizeRouteDefinition<\n Definition<Parent> extends infer A extends string\n ? Definition<Suffix> extends infer B extends string\n ? NormalizeRouteDefinition<A> extends infer ANormalized extends string\n ? NormalizeRouteDefinition<B> extends infer BNormalized extends string\n ? BNormalized extends '/'\n ? ANormalized\n : ANormalized extends '/'\n ? BNormalized\n : `${ANormalized}/${BNormalized}`\n : never\n : never\n : never\n : never\n>\nexport type PathExtended<\n TSourceDefinitionDefinition extends string,\n TSuffixDefinitionDefinition extends string,\n> = `${NormalizeRouteDefinition<JoinPath<StripTrailingWildcard<TSourceDefinitionDefinition>, TSuffixDefinitionDefinition>>}`\n\nexport type StripTrailingWildcard<TDefinition extends string> = TDefinition extends `${infer TPath}*?`\n ? NormalizeRouteDefinition<TPath>\n : TDefinition extends `${infer TPath}*`\n ? NormalizeRouteDefinition<TPath>\n : NormalizeRouteDefinition<TDefinition>\n\nexport type OnlyIfNoParams<TRoute extends AnyRoute | string, Yes, No = never> =\n HasParams<TRoute> extends false ? Yes : No\nexport type OnlyIfHasParams<TRoute extends AnyRoute | string, Yes, No = never> =\n HasParams<TRoute> extends true ? Yes : No\n\nexport type GetPathInput<\n TDefinition extends string,\n TSearchInput extends UnknownSearchInput,\n> = _ParamsInput<TDefinition> & {\n '?'?: TSearchInput\n '#'?: string | number\n}\nexport type GetPathInputByRoute<TRoute extends AnyRoute | CallableRoute | string> =\n TRoute extends AnyRoute<any, infer TSearchInput>\n ? GetPathInput<Definition<TRoute>, TSearchInput>\n : TRoute extends string\n ? GetPathInput<TRoute, UnknownSearchInput>\n : never\n\nexport type IsAny<T> = 0 extends 1 & T ? true : false\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\n// export type _IsAncestor<T extends string, TAncestor extends string> = T extends TAncestor\n// ? false\n// : T extends `${TAncestor}${string}`\n// ? true\n// : false\n// export type _IsDescendant<T extends string, TDescendant extends string> = TDescendant extends T\n// ? false\n// : TDescendant extends `${T}${string}`\n// ? true\n// : false\n// export type _IsSame<T extends string, TExact extends string> = T extends TExact\n// ? TExact extends T\n// ? true\n// : false\n// : false\n\nexport type _SafeParseInputResult<TInputParsed extends Record<string, unknown>> =\n | {\n success: true\n data: TInputParsed\n error: undefined\n }\n | {\n success: false\n data: undefined\n error: Error\n }\n\nexport type SchemaRoute0<\n TInput extends Record<string, unknown>,\n TOutput extends Record<string, unknown>,\n> = StandardSchemaV1<TInput, TOutput> & {\n parse: (input: unknown) => TOutput\n safeParse: (input: unknown) => _SafeParseInputResult<TOutput>\n}\n"],"mappings":"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","names":["searchInput","hashInput","paramsInput","absOriginInput","stringifySearchQuery","parseSearchQuery"]}
1
+ {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["import type { StandardSchemaV1 } from '@standard-schema/spec'\nimport { parse as parseSearchQuery, stringify as stringifySearchQuery } from '@devp0nt/flat0'\n\nexport type RouteToken =\n | { kind: 'static'; value: string }\n | { kind: 'param'; name: string; optional: boolean }\n | { kind: 'wildcard'; prefix: string; optional: boolean }\n\nconst escapeRegex = (value: string): string => value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n\nconst collapseDuplicateSlashes = (value: string): string => value.replace(/\\/{2,}/g, '/')\n\n/**\n * Strongly typed route descriptor and URL builder.\n *\n * A route definition uses:\n * - path params: `/users/:id`\n * - named search keys: `/users&tab&sort`\n * - loose search mode: trailing `&`, e.g. `/users&`\n *\n * Instances are callable (same as `.get()`), so `route(input)` and\n * `route.get(input)` are equivalent.\n */\nexport class Route0<TDefinition extends string, TSearchInput extends UnknownSearchInput = UnknownSearchInput> {\n readonly definition: TDefinition\n readonly params: _ParamsDefinition<TDefinition>\n private _origin: string | undefined\n private _callable: CallableRoute<TDefinition, TSearchInput>\n private _routeSegments?: string[]\n private _routeTokens?: RouteToken[]\n private _routePatternCandidates?: string[]\n private _pathParamsDefinition?: Record<string, boolean>\n private _definitionWithoutTrailingWildcard?: string\n private _routeRegexBaseStringRaw?: string\n private _regexBaseString?: string\n private _regexString?: string\n private _regex?: RegExp\n private _regexAncestor?: RegExp\n private _regexDescendantMatchers?: Array<{ regex: RegExp; captureKeys: string[] }>\n private _captureKeys?: string[]\n private _normalizedDefinition?: string\n private _definitionParts?: string[]\n\n static normalizeSlash = (value: string): string => {\n const collapsed = collapseDuplicateSlashes(value)\n if (collapsed === '' || collapsed === '/') return '/'\n const withLeadingSlash = collapsed.startsWith('/') ? collapsed : `/${collapsed}`\n return withLeadingSlash.length > 1 && withLeadingSlash.endsWith('/')\n ? withLeadingSlash.slice(0, -1)\n : withLeadingSlash\n }\n\n private static _getRouteSegments(definition: string): string[] {\n if (definition === '' || definition === '/') return []\n return definition.split('/').filter(Boolean)\n }\n\n private static _validateRouteDefinition(definition: string): void {\n const segments = Route0._getRouteSegments(definition)\n const wildcardSegments = segments.filter((segment) => segment.includes('*'))\n if (wildcardSegments.length === 0) return\n if (wildcardSegments.length > 1) {\n throw new Error(`Invalid route definition \"${definition}\": only one wildcard segment is allowed`)\n }\n const wildcardSegmentIndex = segments.findIndex((segment) => segment.includes('*'))\n const wildcardSegment = segments[wildcardSegmentIndex]\n if (!wildcardSegment.match(/^(?:\\*|\\*\\?|[^*]+\\*|\\S+\\*\\?)$/)) {\n throw new Error(`Invalid route definition \"${definition}\": wildcard must be trailing in its segment`)\n }\n if (wildcardSegmentIndex !== segments.length - 1) {\n throw new Error(`Invalid route definition \"${definition}\": wildcard segment is allowed only at the end`)\n }\n }\n\n Infer: {\n ParamsDefinition: _ParamsDefinition<TDefinition>\n ParamsInput: _ParamsInput<TDefinition>\n ParamsInputStringOnly: _ParamsInputStringOnly<TDefinition>\n ParamsOutput: ParamsOutput<TDefinition>\n SearchInput: TSearchInput\n } = null as never\n\n /** Base URL used when generating absolute URLs (`abs: true`). */\n get origin(): string {\n if (!this._origin) {\n throw new Error(\n 'origin for route ' +\n this.definition +\n ' is not set, please provide it like Route0.create(route, {origin: \"https://example.com\"}) in config or set via clones like routes._.clone({origin: \"https://example.com\"})',\n )\n }\n return this._origin\n }\n set origin(origin: string) {\n this._origin = origin\n }\n\n private constructor(definition: TDefinition, config: RouteConfigInput = {}) {\n const normalizedDefinition = Route0.normalizeSlash(definition) as TDefinition\n Route0._validateRouteDefinition(normalizedDefinition)\n this.definition = normalizedDefinition\n this.params = this.pathParamsDefinition as _ParamsDefinition<TDefinition>\n\n const { origin } = config\n if (origin && typeof origin === 'string' && origin.length) {\n this._origin = origin\n } else {\n const g = globalThis as unknown as { location?: { origin?: string } } | undefined\n if (typeof g?.location?.origin === 'string' && g.location.origin.length > 0) {\n this._origin = g.location.origin\n } else {\n this._origin = undefined\n }\n }\n const callable = this.get.bind(this)\n Object.setPrototypeOf(callable, this)\n Object.defineProperty(callable, Symbol.toStringTag, {\n value: this.definition,\n })\n this._callable = callable as CallableRoute<TDefinition, TSearchInput>\n }\n\n /**\n * Creates a callable route instance.\n *\n * If an existing route/callable route is provided, it is cloned.\n */\n static create<TDefinition extends string>(\n definition: TDefinition | AnyRoute<TDefinition> | CallableRoute<TDefinition>,\n config?: RouteConfigInput,\n ): CallableRoute<NormalizeRouteDefinition<TDefinition>> {\n if (typeof definition === 'function' || typeof definition === 'object') {\n return definition.clone(config) as CallableRoute<NormalizeRouteDefinition<TDefinition>>\n }\n const original = new Route0<NormalizeRouteDefinition<TDefinition>>(\n Route0.normalizeSlash(definition) as NormalizeRouteDefinition<TDefinition>,\n config,\n )\n return original._callable as CallableRoute<NormalizeRouteDefinition<TDefinition>>\n }\n\n /**\n * Normalizes a definition/route into a callable route.\n *\n * Unlike `create`, passing a callable route returns the same instance.\n */\n static from<TDefinition extends string, TSearchInput extends UnknownSearchInput>(\n definition: TDefinition | AnyRoute<TDefinition, TSearchInput> | CallableRoute<TDefinition, TSearchInput>,\n ): CallableRoute<NormalizeRouteDefinition<TDefinition>, TSearchInput> {\n if (typeof definition === 'function') {\n return definition as CallableRoute<NormalizeRouteDefinition<TDefinition>, TSearchInput>\n }\n const original =\n typeof definition === 'object'\n ? definition\n : new Route0<NormalizeRouteDefinition<TDefinition>>(\n Route0.normalizeSlash(definition) as NormalizeRouteDefinition<TDefinition>,\n )\n return original._callable as CallableRoute<NormalizeRouteDefinition<TDefinition>, TSearchInput>\n }\n\n private static _getAbsPath(origin: string, url: string) {\n return new URL(url, origin).toString().replace(/\\/$/, '')\n }\n\n search<TNewSearchInput extends UnknownSearchInput>(): CallableRoute<TDefinition, TNewSearchInput> {\n return this._callable as CallableRoute<TDefinition, TNewSearchInput>\n }\n\n /** Extends the current route definition by appending a suffix route. */\n extend<TSuffixDefinition extends string>(\n suffixDefinition: TSuffixDefinition,\n ): CallableRoute<PathExtended<TDefinition, TSuffixDefinition>, TSearchInput> {\n const definition = Route0.normalizeSlash(`${this.definitionWithoutTrailingWildcard}/${suffixDefinition}`)\n return Route0.create<PathExtended<TDefinition, TSuffixDefinition>>(\n definition as PathExtended<TDefinition, TSuffixDefinition>,\n {\n origin: this._origin,\n },\n ) as CallableRoute<PathExtended<TDefinition, TSuffixDefinition>, TSearchInput>\n }\n\n get(...args: IsParamsOptional<TDefinition> extends true ? [abs: boolean | string | undefined] : never): string\n get(\n ...args: IsParamsOptional<TDefinition> extends true\n ? [input?: GetPathInput<TDefinition, TSearchInput> | undefined, abs?: boolean | string | undefined]\n : [input: GetPathInput<TDefinition, TSearchInput>, abs?: boolean | string | undefined]\n ): string\n\n // implementation\n get(...args: unknown[]): string {\n const { searchInput, paramsInput, absInput, absOriginInput, hashInput } = ((): {\n searchInput: Record<string, unknown>\n paramsInput: Record<string, string | undefined>\n absInput: boolean\n absOriginInput: string | undefined\n hashInput: string | undefined\n } => {\n if (args.length === 0) {\n return {\n searchInput: {},\n paramsInput: {},\n absInput: false,\n absOriginInput: undefined,\n hashInput: undefined,\n }\n }\n const [input, abs] = ((): [Record<string, unknown>, boolean | string | undefined] => {\n if (typeof args[0] === 'object' && args[0] !== null) {\n return [args[0], args[1]] as [Record<string, unknown>, boolean | string | undefined]\n }\n if (typeof args[1] === 'object' && args[1] !== null) {\n return [args[1], args[0]] as [Record<string, unknown>, boolean | string | undefined]\n }\n if (typeof args[0] === 'boolean' || typeof args[0] === 'string') {\n return [{}, args[0]]\n }\n if (typeof args[1] === 'boolean' || typeof args[1] === 'string') {\n return [{}, args[1]]\n }\n return [{}, undefined]\n })()\n let searchInput: Record<string, unknown> = {}\n let hashInput: string | undefined = undefined\n const paramsInput: Record<string, string | undefined> = {}\n for (const [key, value] of Object.entries(input)) {\n if (key === '?' && typeof value === 'object' && value !== null) {\n searchInput = value as Record<string, unknown>\n } else if (key === '#' && (typeof value === 'string' || typeof value === 'number')) {\n hashInput = String(value)\n } else if (key in this.params && (typeof value === 'string' || typeof value === 'number')) {\n Object.assign(paramsInput, { [key]: String(value) })\n }\n }\n const absOriginInput = typeof abs === 'string' && abs.length > 0 ? abs : undefined\n return {\n searchInput,\n paramsInput,\n absInput: absOriginInput !== undefined || abs === true,\n absOriginInput,\n hashInput,\n }\n })()\n\n // create url\n\n let url = this.definition as string\n // optional named params like /:id?\n url = url.replace(/\\/:([A-Za-z0-9_]+)\\?/g, (_m, k) => {\n const value = paramsInput[k]\n if (value === undefined) return ''\n return `/${encodeURIComponent(String(value))}`\n })\n // required named 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] ?? 'undefined')))\n // optional wildcard segment (/*?)\n url = url.replace(/\\/\\*\\?/g, () => {\n const value = paramsInput['*']\n if (value === undefined) return ''\n const stringValue = String(value)\n return stringValue.startsWith('/') ? stringValue : `/${stringValue}`\n })\n // required wildcard segment (/*)\n url = url.replace(/\\/\\*/g, () => {\n const value = String(paramsInput['*'] ?? '')\n return value.startsWith('/') ? value : `/${value}`\n })\n // optional wildcard inline (e.g. /app*?)\n url = url.replace(/\\*\\?/g, () => String(paramsInput['*'] ?? ''))\n // required wildcard inline (e.g. /app*)\n url = url.replace(/\\*/g, () => String(paramsInput['*'] ?? ''))\n // search params\n const searchString = stringifySearchQuery(searchInput, { arrayIndexes: false })\n url = [url, searchString].filter(Boolean).join('?')\n // dedupe slashes\n url = collapseDuplicateSlashes(url)\n // absolute\n url = absInput ? Route0._getAbsPath(absOriginInput || this.origin, url) : url\n // hash\n if (hashInput !== undefined) {\n url = `${url}#${hashInput}`\n }\n\n return url\n }\n\n /** Returns path param keys extracted from route definition. */\n getParamsKeys(): string[] {\n return Object.keys(this.params)\n }\n\n getTokens(): RouteToken[] {\n return this.routeTokens.map((token): RouteToken => ({ ...token }))\n }\n\n /** Clones route with optional config override. */\n clone(config?: RouteConfigInput): CallableRoute<TDefinition> {\n return Route0.create(this.definition, config) as CallableRoute<TDefinition>\n }\n\n get regexBaseString(): string {\n if (this._regexBaseString === undefined) {\n this._regexBaseString = this.routeRegexBaseStringRaw.replace(/\\/+$/, '') + '/?' // remove trailing slashes and add optional slash\n }\n return this._regexBaseString\n }\n\n get regexString(): string {\n if (this._regexString === undefined) {\n this._regexString = `^${this.regexBaseString}$`\n }\n return this._regexString\n }\n\n get regex(): RegExp {\n if (this._regex === undefined) {\n this._regex = new RegExp(this.regexString)\n }\n return this._regex\n }\n\n get regexAncestor(): RegExp {\n if (this._regexAncestor === undefined) {\n this._regexAncestor = new RegExp(`^${this.regexBaseString}(?:/.*)?$`)\n }\n return this._regexAncestor\n }\n\n private get regexDescendantMatchers(): Array<{ regex: RegExp; captureKeys: string[] }> {\n if (this._regexDescendantMatchers === undefined) {\n const matchers: Array<{ regex: RegExp; captureKeys: string[] }> = []\n if (this.definitionParts[0] !== '/') {\n let pattern = ''\n const captureKeys: string[] = []\n for (const part of this.definitionParts) {\n if (part.startsWith(':')) {\n pattern += '/([^/]+)'\n captureKeys.push(part.replace(/^:/, '').replace(/\\?$/, ''))\n } else if (part.includes('*')) {\n const prefix = part.replace(/\\*\\??$/, '')\n pattern += `/${escapeRegex(prefix)}[^/]*`\n captureKeys.push('*')\n } else {\n pattern += `/${escapeRegex(part)}`\n }\n matchers.push({\n regex: new RegExp(`^${pattern}/?$`),\n captureKeys: [...captureKeys],\n })\n }\n }\n this._regexDescendantMatchers = matchers\n }\n return this._regexDescendantMatchers\n }\n\n private get captureKeys(): string[] {\n if (this._captureKeys === undefined) {\n this._captureKeys = this.routeTokens\n .filter((token): token is Extract<RouteToken, { kind: 'param' | 'wildcard' }> => token.kind !== 'static')\n .map((token) => (token.kind === 'param' ? token.name : '*'))\n }\n return this._captureKeys\n }\n\n private get routeSegments(): string[] {\n if (this._routeSegments === undefined) {\n this._routeSegments = Route0._getRouteSegments(this.definition)\n }\n return this._routeSegments\n }\n\n private get routeTokens(): RouteToken[] {\n if (this._routeTokens === undefined) {\n this._routeTokens = this.routeSegments.map((segment): RouteToken => {\n const param = segment.match(/^:([A-Za-z0-9_]+)(\\?)?$/)\n if (param) {\n return { kind: 'param', name: param[1], optional: param[2] === '?' }\n }\n if (segment === '*' || segment === '*?') {\n return { kind: 'wildcard', prefix: '', optional: segment.endsWith('?') }\n }\n const wildcard = segment.match(/^(.*)\\*(\\?)?$/)\n if (wildcard && !segment.includes('\\\\*')) {\n return { kind: 'wildcard', prefix: wildcard[1], optional: wildcard[2] === '?' }\n }\n return { kind: 'static', value: segment }\n })\n }\n return this._routeTokens\n }\n\n private get routePatternCandidates(): string[] {\n if (this._routePatternCandidates === undefined) {\n const values = (token: RouteToken): string[] => {\n if (token.kind === 'static') return [token.value]\n if (token.kind === 'param') return token.optional ? ['', 'x', 'y'] : ['x', 'y']\n if (token.prefix.length > 0)\n return [token.prefix, `${token.prefix}-x`, `${token.prefix}/x`, `${token.prefix}/y/z`]\n return ['', 'x', 'y', 'x/y']\n }\n let acc: string[] = ['']\n for (const token of this.routeTokens) {\n const next: string[] = []\n for (const base of acc) {\n for (const value of values(token)) {\n if (value === '') {\n next.push(base)\n } else if (value.startsWith('/')) {\n next.push(`${base}${value}`)\n } else {\n next.push(`${base}/${value}`)\n }\n }\n }\n // Keep candidate space bounded for large route definitions.\n acc = next.length > 512 ? next.slice(0, 512) : next\n }\n this._routePatternCandidates =\n acc.length === 0 ? ['/'] : Array.from(new Set(acc.map((x) => (x === '' ? '/' : collapseDuplicateSlashes(x)))))\n }\n return this._routePatternCandidates\n }\n\n private get pathParamsDefinition(): Record<string, boolean> {\n if (this._pathParamsDefinition === undefined) {\n const entries = this.routeTokens\n .filter((t) => t.kind !== 'static')\n .map((t): [string, boolean] => (t.kind === 'param' ? [t.name, !t.optional] : ['*', !t.optional]))\n this._pathParamsDefinition = Object.fromEntries(entries)\n }\n return this._pathParamsDefinition\n }\n\n private get definitionWithoutTrailingWildcard(): string {\n if (this._definitionWithoutTrailingWildcard === undefined) {\n this._definitionWithoutTrailingWildcard = this.definition.replace(/\\*\\??$/, '')\n }\n return this._definitionWithoutTrailingWildcard\n }\n\n private get routeRegexBaseStringRaw(): string {\n if (this._routeRegexBaseStringRaw === undefined) {\n if (this.routeTokens.length === 0) {\n this._routeRegexBaseStringRaw = ''\n } else {\n let pattern = ''\n for (const token of this.routeTokens) {\n if (token.kind === 'static') {\n pattern += `/${escapeRegex(token.value)}`\n continue\n }\n if (token.kind === 'param') {\n pattern += token.optional ? '(?:/([^/]+))?' : '/([^/]+)'\n continue\n }\n if (token.prefix.length > 0) {\n pattern += `/${escapeRegex(token.prefix)}(.*)`\n } else {\n // Wouter-compatible splat: /orders/* matches /orders and /orders/...\n pattern += '(?:/(.*))?'\n }\n }\n this._routeRegexBaseStringRaw = pattern\n }\n }\n return this._routeRegexBaseStringRaw\n }\n\n private get normalizedDefinition(): string {\n if (this._normalizedDefinition === undefined) {\n this._normalizedDefinition =\n this.definition.length > 1 && this.definition.endsWith('/') ? this.definition.slice(0, -1) : this.definition\n }\n return this._normalizedDefinition\n }\n\n private get definitionParts(): string[] {\n if (this._definitionParts === undefined) {\n this._definitionParts =\n this.normalizedDefinition === '/' ? ['/'] : this.normalizedDefinition.split('/').filter(Boolean)\n }\n return this._definitionParts\n }\n\n /** Fast pathname exact match check without building a full relation object. */\n isExact(pathname: string, normalize = true): boolean {\n const normalizedPathname = normalize ? Route0.normalizeSlash(pathname) : pathname\n return this.regex.test(normalizedPathname)\n }\n\n /** Fast pathname exact or ancestor match check without building a full relation object. */\n isExactOrAncestor(pathname: string, normalize = true): boolean {\n const normalizedPathname = normalize ? Route0.normalizeSlash(pathname) : pathname\n return this.regex.test(normalizedPathname) || this.regexAncestor.test(normalizedPathname)\n }\n\n /** True when route is ancestor of pathname (pathname is deeper). */\n isAncestor(pathname: string, normalize = true): boolean {\n const normalizedPathname = normalize ? Route0.normalizeSlash(pathname) : pathname\n return !this.regex.test(normalizedPathname) && this.regexAncestor.test(normalizedPathname)\n }\n\n /** True when route is descendant of pathname (pathname is shallower). */\n isDescendant(pathname: string, normalize = true): boolean {\n const normalizedPathname = normalize ? Route0.normalizeSlash(pathname) : pathname\n if (this.regex.test(normalizedPathname) || this.regexAncestor.test(normalizedPathname)) {\n return false\n }\n for (const matcher of this.regexDescendantMatchers) {\n if (normalizedPathname.match(matcher.regex)) {\n return true\n }\n }\n return false\n }\n\n /** Creates a grouped regex pattern string from many routes. */\n static getRegexStringGroup(routes: AnyRoute[]): string {\n const patterns = routes.map((route) => route.regexString).join('|')\n return `(${patterns})`\n }\n\n /** Creates a grouped regex from many routes. */\n static getRegexGroup(routes: AnyRoute[]): RegExp {\n const patterns = Route0.getRegexStringGroup(routes)\n return new RegExp(`^(${patterns})$`)\n }\n\n /** Converts any location shape to relative form (removes host/origin fields). */\n static toRelLocation<TLocation extends AnyLocation>(location: TLocation): TLocation {\n return {\n ...location,\n abs: false,\n origin: undefined,\n href: undefined,\n port: undefined,\n host: undefined,\n hostname: undefined,\n }\n }\n\n /** Converts a location to absolute form using provided origin URL. */\n static toAbsLocation<TLocation extends AnyLocation>(location: TLocation, origin: string): TLocation {\n const relLoc = Route0.toRelLocation(location)\n const url = new URL(relLoc.hrefRel, origin)\n return {\n ...location,\n abs: true,\n origin: url.origin,\n href: url.href,\n port: url.port,\n host: url.host,\n hostname: url.hostname,\n }\n }\n\n /**\n * Parses a URL-like input into raw location object (without route knowledge).\n *\n * Result is always `UnknownLocation` because no route matching is applied.\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 // Common derived values\n const hrefRel = url.pathname + url.search + url.hash\n\n // Build the location object consistent with _GeneralLocation\n let _search: UnknownSearchParsed | undefined\n const location: UnknownLocation = {\n pathname: url.pathname,\n get search() {\n if (_search === undefined) {\n _search = parseSearchQuery(url.search)\n }\n return _search\n },\n searchString: 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 params: undefined,\n route: undefined,\n }\n\n return location\n }\n\n // /**\n // * Parses input and returns location only for exact route matches.\n // */\n // getLocation(href: `${string}://${string}`): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(hrefRel: `/${string}`): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(hrefOrHrefRel: string): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(location: AnyLocation): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(url: AnyLocation): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): ExactLocation<TDefinition> | UnknownLocation {\n // const relation = this.getRelation(hrefOrHrefRelOrLocation)\n // if (!relation.exact) {\n // return Route0.getLocation(hrefOrHrefRelOrLocation)\n // }\n // const location = Route0.getLocation(hrefOrHrefRelOrLocation)\n // return {\n // ...location,\n // route: this.definition as Definition<TDefinition>,\n // params: relation.params as ParamsOutput<TDefinition>,\n // }\n // }\n\n /**\n * Parses input and evaluates pathname relation to this route.\n */\n getRelation(href: `${string}://${string}`): RouteRelation<TDefinition>\n getRelation(hrefRel: `/${string}`): RouteRelation<TDefinition>\n getRelation(hrefOrHrefRel: string): RouteRelation<TDefinition>\n getRelation(location: AnyLocation): RouteRelation<TDefinition>\n getRelation(url: URL): RouteRelation<TDefinition>\n getRelation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): RouteRelation<TDefinition>\n getRelation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): RouteRelation<TDefinition> {\n if (hrefOrHrefRelOrLocation instanceof URL) {\n return this.getRelation(hrefOrHrefRelOrLocation.href)\n }\n if (typeof hrefOrHrefRelOrLocation !== 'string') {\n hrefOrHrefRelOrLocation = hrefOrHrefRelOrLocation.href || hrefOrHrefRelOrLocation.hrefRel\n }\n // Normalize pathname (no trailing slash except root)\n const pathname = Route0.normalizeSlash(new URL(hrefOrHrefRelOrLocation, 'http://example.com').pathname)\n\n const paramNames = this.captureKeys\n const exactRe = this.regex\n const exactMatch = pathname.match(exactRe)\n\n if (exactMatch) {\n const values = exactMatch.slice(1, 1 + paramNames.length)\n const params = Object.fromEntries(\n paramNames.map((n, i) => {\n const value = values[i] as string | undefined\n return [n, value === undefined ? undefined : decodeURIComponent(value)]\n }),\n )\n return {\n type: 'exact',\n route: this.definition as Definition<TDefinition>,\n params: params as ParamsOutput<TDefinition>,\n exact: true,\n ancestor: false,\n descendant: false,\n unmatched: false,\n }\n }\n\n const ancestorRe = this.regexAncestor\n const ancestorMatch = pathname.match(ancestorRe)\n if (ancestorMatch) {\n const values = ancestorMatch.slice(1, 1 + paramNames.length)\n const params = Object.fromEntries(\n paramNames.map((n, i) => {\n const value = values[i] as string | undefined\n return [n, value === undefined ? undefined : decodeURIComponent(value)]\n }),\n )\n return {\n type: 'ancestor',\n route: this.definition as Definition<TDefinition>,\n params: params as ParamsOutput<TDefinition> & { [key: string]: string | undefined },\n exact: false,\n ancestor: true,\n descendant: false,\n unmatched: false,\n }\n }\n\n let descendantMatch: RegExpMatchArray | null = null\n let descendantCaptureKeys: string[] = []\n for (const matcher of this.regexDescendantMatchers) {\n const match = pathname.match(matcher.regex)\n if (!match) continue\n descendantMatch = match\n descendantCaptureKeys = matcher.captureKeys\n break\n }\n\n if (descendantMatch) {\n const values = descendantMatch.slice(1, 1 + descendantCaptureKeys.length)\n const params = Object.fromEntries(\n descendantCaptureKeys.map((key, index) => [key, decodeURIComponent(values[index] as string)]),\n )\n return {\n type: 'descendant',\n route: this.definition as Definition<TDefinition>,\n params: params as Partial<ParamsOutput<TDefinition>>,\n exact: false,\n ancestor: false,\n descendant: true,\n unmatched: false,\n }\n }\n\n return {\n type: 'unmatched',\n route: this.definition as Definition<TDefinition>,\n params: {},\n exact: false,\n ancestor: false,\n descendant: false,\n unmatched: true,\n }\n }\n\n private _validateParamsInput(input: unknown): StandardSchemaV1.Result<ParamsOutput<TDefinition>> {\n const paramsEntries = Object.entries(this.params) as Array<[string, boolean]>\n const paramsMap = this.params as Record<string, boolean>\n const requiredParamsKeys = paramsEntries.filter(([, required]) => required).map(([k]) => k)\n const paramsKeys = paramsEntries.map(([k]) => k)\n if (input === undefined) {\n if (requiredParamsKeys.length) {\n return {\n issues: [\n {\n message: `Missing params: ${requiredParamsKeys.map((k) => `\"${k}\"`).join(', ')}`,\n },\n ],\n }\n }\n input = {}\n }\n if (typeof input !== 'object' || input === null) {\n return {\n issues: [{ message: 'Invalid route params: expected object' }],\n }\n }\n const inputObj = input as Record<string, unknown>\n const inputKeys = Object.keys(inputObj)\n const notDefinedKeys = requiredParamsKeys.filter((k) => !inputKeys.includes(k))\n if (notDefinedKeys.length) {\n return {\n issues: [\n {\n message: `Missing params: ${notDefinedKeys.map((k) => `\"${k}\"`).join(', ')}`,\n },\n ],\n }\n }\n const data: Record<string, string | undefined> = {}\n for (const k of paramsKeys) {\n const v = inputObj[k]\n const required = paramsMap[k]\n if (v === undefined && !required) {\n data[k] = undefined as never\n } else if (typeof v === 'string') {\n data[k] = v\n } else if (typeof v === 'number') {\n data[k] = String(v)\n } else {\n return {\n issues: [{ message: `Invalid route params: expected string, number, got ${typeof v} for \"${k}\"` }],\n }\n }\n }\n return {\n value: data as ParamsOutput<TDefinition>,\n }\n }\n\n private _safeParseSchemaResult<TOutput extends Record<string, unknown>>(\n result: StandardSchemaV1.Result<TOutput>,\n ): _SafeParseInputResult<TOutput> {\n if ('issues' in result) {\n return {\n success: false,\n data: undefined,\n error: new Error(result.issues?.[0]?.message ?? 'Invalid input'),\n }\n }\n return {\n success: true,\n data: result.value,\n error: undefined,\n }\n }\n\n private _parseSchemaResult<TOutput extends Record<string, unknown>>(\n result: StandardSchemaV1.Result<TOutput>,\n ): TOutput {\n const safeResult = this._safeParseSchemaResult(result)\n if (safeResult.error) {\n throw safeResult.error\n }\n return safeResult.data\n }\n\n /** Standard Schema for route params input. */\n readonly schema: SchemaRoute0<ParamsInput<TDefinition>, ParamsOutput<TDefinition>> = {\n '~standard': {\n version: 1,\n vendor: 'route0',\n validate: (value) => this._validateParamsInput(value),\n types: undefined as unknown as StandardSchemaV1.Types<ParamsInput<TDefinition>, ParamsOutput<TDefinition>>,\n },\n parse: (value) => this._parseSchemaResult(this._validateParamsInput(value)),\n safeParse: (value) => this._safeParseSchemaResult(this._validateParamsInput(value)),\n }\n\n // /** True when path structure is equal (param names are ignored). */\n // isSame(other: AnyRoute): boolean {\n // const thisShape = this.routeTokens\n // .map((t) => {\n // if (t.kind === 'static') return `s:${t.value}`\n // if (t.kind === 'param') return `p:${t.optional ? 'o' : 'r'}`\n // return `w:${t.prefix}:${t.optional ? 'o' : 'r'}`\n // })\n // .join('/')\n // const otherRoute = Route0.from(other) as Route0<string, UnknownSearchInput>\n // const otherShape = otherRoute.routeTokens\n // .map((t) => {\n // if (t.kind === 'static') return `s:${t.value}`\n // if (t.kind === 'param') return `p:${t.optional ? 'o' : 'r'}`\n // return `w:${t.prefix}:${t.optional ? 'o' : 'r'}`\n // })\n // .join('/')\n // return thisShape === otherShape\n // }\n // /** Static convenience wrapper for `isSame`. */\n // static isSame(a: AnyRoute | string | undefined, b: AnyRoute | string | undefined): boolean {\n // if (!a) {\n // if (!b) return true\n // return false\n // }\n // if (!b) {\n // return false\n // }\n // return Route0.create(a).isSame(Route0.create(b))\n // }\n\n // /** True when current route is more specific/deeper than `other`. */\n // isDescendant(other: AnyRoute | string | undefined): boolean {\n // if (!other) return false\n // other = Route0.create(other)\n // // this is a descendant of other if:\n // // - paths are not exactly the same\n // // - other's path is a prefix of this path, matching params as wildcards\n // const getParts = (path: string) => (path === '/' ? ['/'] : path.split('/').filter(Boolean))\n // // Root is ancestor of any non-root; thus any non-root is a descendant of root\n // if (other.definition === '/' && this.definition !== '/') {\n // return true\n // }\n // const thisParts = getParts(this.definition)\n // const otherParts = getParts(other.definition)\n\n // // A descendant must be deeper\n // if (thisParts.length <= otherParts.length) return false\n\n // const matchesPatternPart = (patternPart: string, valuePart: string): { match: boolean; wildcard: boolean } => {\n // if (patternPart.startsWith(':')) return { match: true, wildcard: false }\n // const wildcardIndex = patternPart.indexOf('*')\n // if (wildcardIndex >= 0) {\n // const prefix = patternPart.slice(0, wildcardIndex)\n // return { match: prefix.length === 0 || valuePart.startsWith(prefix), wildcard: true }\n // }\n // return { match: patternPart === valuePart, wildcard: false }\n // }\n\n // for (let i = 0; i < otherParts.length; i++) {\n // const otherPart = otherParts[i]\n // const thisPart = thisParts[i]\n // const result = matchesPatternPart(otherPart, thisPart)\n // if (!result.match) return false\n // if (result.wildcard) return true\n // }\n // // Not equal (depth already ensures not equal)\n // return true\n // }\n\n // /** True when current route is broader/shallower than `other`. */\n // isAncestor(other: AnyRoute | string | undefined): boolean {\n // if (!other) return false\n // other = Route0.create(other)\n // // this is an ancestor of other if:\n // // - paths are not exactly the same\n // // - this path is a prefix of other path, matching params as wildcards\n // const getParts = (path: string) => (path === '/' ? ['/'] : path.split('/').filter(Boolean))\n // // Root is ancestor of any non-root path\n // if (this.definition === '/' && other.definition !== '/') {\n // return true\n // }\n // const thisParts = getParts(this.definition)\n // const otherParts = getParts(other.definition)\n\n // // An ancestor must be shallower\n // if (thisParts.length >= otherParts.length) return false\n\n // const matchesPatternPart = (patternPart: string, valuePart: string): { match: boolean; wildcard: boolean } => {\n // if (patternPart.startsWith(':')) return { match: true, wildcard: false }\n // const wildcardIndex = patternPart.indexOf('*')\n // if (wildcardIndex >= 0) {\n // const prefix = patternPart.slice(0, wildcardIndex)\n // return { match: prefix.length === 0 || valuePart.startsWith(prefix), wildcard: true }\n // }\n // return { match: patternPart === valuePart, wildcard: false }\n // }\n\n // for (let i = 0; i < thisParts.length; i++) {\n // const thisPart = thisParts[i]\n // const otherPart = otherParts[i]\n // const result = matchesPatternPart(thisPart, otherPart)\n // if (!result.match) return false\n // if (result.wildcard) return true\n // }\n // // Not equal (depth already ensures not equal)\n // return true\n // }\n\n /** True when two route patterns can match the same concrete URL. */\n isOverlap(other: AnyRoute | string | undefined): boolean {\n if (!other) return false\n const otherRoute = Route0.from(other) as Route0<string, UnknownSearchInput>\n const thisRegex = this.regex\n const otherRegex = otherRoute.regex\n const thisCandidates = this.routePatternCandidates\n const otherCandidates = otherRoute.routePatternCandidates\n if (thisCandidates.some((path) => otherRegex.test(path))) return true\n if (otherCandidates.some((path) => thisRegex.test(path))) return true\n return false\n }\n\n /**\n * True when overlap is not resolvable by route ordering inside one route set.\n *\n * Non-conflicting overlap means one route is a strict subset of another\n * (e.g. `/x/y` is a strict subset of `/x/:id`) and can be safely ordered first.\n */\n isConflict(other: AnyRoute | string | undefined): boolean {\n if (!other) return false\n const otherRoute = Route0.from(other) as Route0<string, UnknownSearchInput>\n if (!this.isOverlap(otherRoute)) return false\n const thisRegex = this.regex\n const otherRegex = otherRoute.regex\n const thisCandidates = this.routePatternCandidates\n const otherCandidates = otherRoute.routePatternCandidates\n const thisExclusive = thisCandidates.some((path) => thisRegex.test(path) && !otherRegex.test(path))\n const otherExclusive = otherCandidates.some((path) => otherRegex.test(path) && !thisRegex.test(path))\n // Exactly one side has exclusive matches => strict subset => resolvable by ordering.\n if (thisExclusive !== otherExclusive) return false\n // Both exclusive (partial overlap) OR none exclusive (equal languages) => real conflict.\n return true\n }\n\n /** Specificity comparator used for deterministic route ordering. */\n isMoreSpecificThan(other: AnyRoute | string | undefined): boolean {\n if (!other) return false\n other = Route0.create(other)\n const getParts = (path: string) => {\n if (path === '/') return ['/']\n return path.split('/').filter(Boolean)\n }\n const rank = (part: string): number => {\n if (part.includes('*')) return -1\n if (part.startsWith(':') && part.endsWith('?')) return 0\n if (part.startsWith(':')) return 1\n return 2\n }\n const thisParts = getParts(this.definition)\n const otherParts = getParts(other.definition)\n for (let i = 0; i < Math.min(thisParts.length, otherParts.length); i++) {\n const thisRank = rank(thisParts[i])\n const otherRank = rank(otherParts[i])\n if (thisRank > otherRank) return true\n if (thisRank < otherRank) return false\n }\n return this.definition < other.definition\n }\n}\n\n/**\n * Typed route collection with deterministic matching order.\n *\n * `Routes.create()` accepts either plain string definitions or route objects\n * and returns a \"pretty\" object with direct route access + helper methods under `._`.\n */\n\nexport class Routes<const T extends RoutesRecord = any> {\n _routes: RoutesRecordHydrated<T>\n _pathsOrdering: string[]\n _keysOrdering: string[]\n _ordered: CallableRoute[]\n\n _: {\n routes: Routes<T>['_routes']\n getLocation: Routes<T>['_getLocation']\n clone: Routes<T>['_clone']\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?: CallableRoute[]\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 this._ = {\n routes: this._routes,\n getLocation: this._getLocation.bind(this),\n clone: this._clone.bind(this),\n pathsOrdering: this._pathsOrdering,\n keysOrdering: this._keysOrdering,\n ordered: this._ordered,\n }\n }\n\n /** Creates and hydrates a typed routes collection. */\n static create<const T extends RoutesRecord>(routes: T, override?: RouteConfigInput): RoutesPretty<T> {\n const result = Routes.prettify(new Routes({ routes }))\n if (!override) {\n return result\n }\n return result._.clone(override)\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 clone: instance._clone.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.hasOwn(routes, key)) {\n const value = routes[key]\n result[key] = (typeof value === 'string' ? Route0.create(value) : value) as CallableRoute<T[typeof key]>\n }\n }\n return result\n }\n\n /**\n * Matches an input URL against collection routes.\n *\n * Returns first exact match according to precomputed ordering,\n * otherwise returns `UnknownLocation`.\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 const input = hrefOrHrefRelOrLocation\n const location = Route0.getLocation(input)\n for (const route of this._ordered) {\n if (route.isExact(location.pathname, false)) {\n const relation = route.getRelation(input)\n return Object.assign(location, {\n route: route.definition,\n params: relation.params,\n }) as ExactLocation\n }\n }\n return location as UnknownLocation\n }\n\n private static makeOrdering(routes: RoutesRecord): {\n pathsOrdering: string[]\n keysOrdering: string[]\n } {\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: overlapping routes by specificity first, otherwise by path depth and alphabetically.\n entries.sort(([_keyA, routeA], [_keyB, routeB]) => {\n const partsA = getParts(routeA.definition)\n const partsB = getParts(routeB.definition)\n\n // 1. Overlapping routes: more specific first\n if (routeA.isOverlap(routeB)) {\n if (routeA.isMoreSpecificThan(routeB)) return -1\n if (routeB.isMoreSpecificThan(routeA)) return 1\n }\n\n // 2. Different non-overlapping depth: shorter first\n if (partsA.length !== partsB.length) {\n return partsA.length - partsB.length\n }\n\n // 3. Fallback: alphabetically for deterministic ordering\n return routeA.definition.localeCompare(routeB.definition)\n })\n\n const pathsOrdering = entries.map(([_key, route]) => route.definition)\n const keysOrdering = entries.map(([_key]) => _key)\n return { pathsOrdering, keysOrdering }\n }\n\n /** Returns a cloned routes collection with config applied to each route. */\n _clone(config: RouteConfigInput): RoutesPretty<T> {\n const newRoutes = {} as RoutesRecordHydrated<T>\n for (const key in this._routes) {\n if (Object.hasOwn(this._routes, key)) {\n newRoutes[key] = this._routes[key].clone(config) as CallableRoute<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\n/** Any route instance shape, preserving literal path type when known. */\nexport type AnyRoute<\n T extends Route0<string> | string = string,\n TSearch extends UnknownSearchInput = UnknownSearchInput,\n> = T extends string ? Route0<T, TSearch> : T\n/** Callable route (`route(input)`) plus route instance methods/properties. */\nexport type CallableRoute<\n T extends Route0<string> | string = string,\n TSearch extends UnknownSearchInput = UnknownSearchInput,\n> = AnyRoute<T, TSearch> & AnyRoute<T, TSearch>['get']\n/** Route input accepted by most APIs: definition string or route object/callable. */\nexport type AnyRouteOrDefinition<T extends string = string> = AnyRoute<T> | CallableRoute<T> | T\n/** Route-level runtime configuration. */\nexport type RouteConfigInput = {\n origin?: string\n}\n\n// collection\n\n/** User-provided routes map (plain definitions or route instances). */\nexport type RoutesRecord = Record<string, AnyRoute | string>\n/** Same as `RoutesRecord` but all values normalized to callable routes. */\nexport type RoutesRecordHydrated<TRoutesRecord extends RoutesRecord = any> = {\n [K in keyof TRoutesRecord]: CallableRoute<TRoutesRecord[K]>\n}\n/** Public shape returned by `Routes.create()`. Default `any` so `satisfies RoutesPretty` accepts any created routes. */\nexport type RoutesPretty<TRoutesRecord extends RoutesRecord = any> = RoutesRecordHydrated<TRoutesRecord> &\n Omit<Routes<TRoutesRecord>, '_routes' | '_getLocation' | '_clone' | '_pathsOrdering' | '_keysOrdering' | '_ordered'>\nexport type ExtractRoutesKeys<TRoutes extends RoutesPretty | RoutesRecord> = TRoutes extends RoutesPretty\n ? Extract<keyof TRoutes['_']['routes'], string>\n : TRoutes extends RoutesRecord\n ? Extract<keyof TRoutes, string>\n : never\nexport type ExtractRoute<\n TRoutes extends RoutesPretty | RoutesRecord,\n TKey extends ExtractRoutesKeys<TRoutes>,\n> = TRoutes extends RoutesPretty ? TRoutes['_']['routes'][TKey] : TRoutes extends RoutesRecord ? 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 ParamsDefinition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['params']\n : T extends string\n ? _ParamsDefinition<T>\n : undefined\nexport type Extended<\n T extends AnyRoute | string | undefined,\n TSuffixDefinition extends string,\n TSearchInput extends UnknownSearchInput = UnknownSearchInput,\n> = T extends AnyRoute\n ? Route0<PathExtended<T['definition'], TSuffixDefinition>, TSearchInput>\n : T extends string\n ? Route0<PathExtended<T, TSuffixDefinition>, TSearchInput>\n : T extends undefined\n ? Route0<TSuffixDefinition, TSearchInput>\n : never\n\n// export type IsAncestor<T extends AnyRoute | string, TAncestor extends AnyRoute | string> = _IsAncestor<\n// Definition<T>,\n// Definition<TAncestor>\n// >\n// export type IsDescendant<T extends AnyRoute | string, TDescendant extends AnyRoute | string> = _IsDescendant<\n// Definition<T>,\n// Definition<TDescendant>\n// >\n// export type IsSame<T extends AnyRoute | string, TExact extends AnyRoute | string> = _IsSame<\n// Definition<T>,\n// Definition<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> = keyof _ParamsDefinition<Definition<T>> extends never ? false : true\nexport type HasWildcard<T extends AnyRoute | string> = Definition<T> extends `${string}*${string}` ? true : false\nexport type HasRequiredParams<T extends AnyRoute | string> =\n _RequiredParamKeys<Definition<T>> extends never ? false : true\n\nexport type ParamsOutput<T extends AnyRoute | string> = {\n [K in keyof ParamsDefinition<T>]: ParamsDefinition<T>[K] extends true ? string : string | undefined\n}\nexport type ParamsInput<T extends AnyRoute | string = string> = _ParamsInput<Definition<T>>\nexport type IsParamsOptional<T extends AnyRoute | string> = HasRequiredParams<Definition<T>> extends true ? false : true\nexport type ParamsInputStringOnly<T extends AnyRoute | string = string> = _ParamsInputStringOnly<Definition<T>>\n\n// relation\n\nexport type ExactRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {\n type: 'exact'\n route: Definition<TRoute>\n params: ParamsOutput<TRoute>\n exact: true\n ancestor: false\n descendant: false\n unmatched: false\n}\nexport type AncestorRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {\n type: 'ancestor'\n route: Definition<TRoute>\n params: ParamsOutput<TRoute> & { [key: string]: string | undefined }\n exact: false\n ancestor: true\n descendant: false\n unmatched: false\n}\nexport type DescendantRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {\n type: 'descendant'\n route: Definition<TRoute>\n params: Partial<ParamsOutput<TRoute>>\n exact: false\n ancestor: false\n descendant: true\n unmatched: false\n}\nexport type UnmatchedRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {\n type: 'unmatched'\n route: Definition<TRoute>\n params: Record<never, never>\n exact: false\n ancestor: false\n descendant: false\n unmatched: true\n}\nexport type RouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> =\n | ExactRouteRelation<TRoute>\n | AncestorRouteRelation<TRoute>\n | DescendantRouteRelation<TRoute>\n | UnmatchedRouteRelation<TRoute>\n\n// location\n\nexport type LocationParams<TDefinition extends string> = {\n [K in keyof _ParamsDefinition<TDefinition>]: _ParamsDefinition<TDefinition>[K] extends true\n ? string\n : string | undefined\n}\n\n/**\n * URL location primitives independent from route-matching state.\n *\n * `hrefRel` is relative href and includes `pathname + search + hash`.\n */\nexport type _GeneralLocation = {\n /**\n * Path without search/hash (normalized for trailing slash).\n *\n * Example:\n * - input: `https://example.com/users/42?tab=posts#section`\n * - pathname: `/users/42`\n */\n pathname: string\n /**\n * Parsed query object.\n *\n * Example:\n * - `{ tab: \"posts\", sort: \"desc\" }`\n */\n search: UnknownSearchParsed\n /**\n * Raw query string with leading `?`, if present, else empty string.\n *\n * Example:\n * - `?tab=posts&sort=desc`\n */\n searchString: string\n /**\n * Raw hash with leading `#`, if present, else empty string.\n *\n * Example:\n * - `#section`\n */\n hash: string\n /**\n * URL origin for absolute inputs.\n *\n * Example:\n * - href: `https://example.com/users/42`\n * - origin: `https://example.com`\n */\n origin: string | undefined\n /**\n * Full absolute href for absolute inputs.\n *\n * Example:\n * - `https://example.com/users/42?tab=posts#section`\n */\n href: string | undefined\n /**\n * Relative href (`pathname + search + hash`).\n *\n * Example:\n * - pathname: `/users/42`\n * - search: `?tab=posts`\n * - hash: `#section`\n * - hrefRel: `/users/42?tab=posts#section`\n */\n hrefRel: string\n /**\n * Whether input was absolute URL.\n *\n * Examples:\n * - `https://example.com/users/42` -> `true`\n * - `/users/42` -> `false`\n */\n abs: boolean\n port: string | undefined\n host: string | undefined\n hostname: string | undefined\n}\n/** Location state before matching against a concrete route. */\nexport type UnknownLocationState = {\n route: undefined\n params: undefined\n}\nexport type UnknownLocation = _GeneralLocation & UnknownLocationState\n\n/** Exact match state for a known route. */\nexport type ExactLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: Definition<TRoute>\n params: ParamsOutput<TRoute>\n}\nexport type ExactLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n ExactLocationState<TRoute>\n\nexport type UnknownSearchParsedValue = string | UnknownSearchParsed | Array<UnknownSearchParsedValue>\nexport interface UnknownSearchParsed {\n [key: string]: UnknownSearchParsedValue\n}\n\nexport type UnknownSearchInput = Record<string, unknown>\n\n/** Input URL is a descendant of route definition (route is ancestor). */\nexport type AncestorLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: string\n params: IsAny<TRoute> extends true ? any : ParamsOutput<TRoute> & { [key: string]: string | undefined }\n}\nexport type AncestorLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n AncestorLocationState<TRoute>\n\n/** It is when route not match at all, but params match. */\nexport type WeakAncestorLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: string\n params: IsAny<TRoute> extends true ? any : ParamsOutput<TRoute> & { [key: string]: string | undefined }\n}\nexport type WeakAncestorLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n WeakAncestorLocationState<TRoute>\n\n/** Input URL is an ancestor prefix of route definition (route is descendant). */\nexport type DescendantLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: string\n params: Partial<ParamsOutput<TRoute>>\n}\nexport type DescendantLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n DescendantLocationState<TRoute>\n\n/** It is when route not match at all, but params partially match. */\nexport type WeakDescendantLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: string\n params: Partial<ParamsOutput<TRoute>>\n}\nexport type WeakDescendantLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n WeakDescendantLocationState<TRoute>\nexport type KnownLocation<TRoute extends AnyRoute | string = AnyRoute | string> =\n | ExactLocation<TRoute>\n | AncestorLocation<TRoute>\n | WeakAncestorLocation<TRoute>\n | DescendantLocation<TRoute>\n | WeakDescendantLocation<TRoute>\nexport type AnyLocation<TRoute extends AnyRoute | string = AnyRoute | string> = UnknownLocation | KnownLocation<TRoute>\n\n// internal utils\n\nexport type _ParamsDefinition<TDefinition extends string> = _ExtractParamsDefinitionBySegments<\n _SplitPathSegments<Definition<TDefinition>>\n>\n\nexport type _Simplify<T> = { [K in keyof T]: T[K] } & {}\nexport type _IfNoKeys<T extends object, TYes, TNo> = keyof T extends never ? TYes : TNo\n\nexport type _ParamsInput<TDefinition extends string> =\n _ParamsDefinition<TDefinition> extends infer TDef extends Record<string, boolean>\n ? _IfNoKeys<\n TDef,\n Record<never, never>,\n _Simplify<\n {\n [K in keyof TDef as TDef[K] extends true ? K : never]: string | number\n } & {\n [K in keyof TDef as TDef[K] extends false ? K : never]?: string | number | undefined\n }\n >\n >\n : Record<never, never>\n\nexport type _ParamsInputStringOnly<TDefinition extends string> =\n _ParamsDefinition<TDefinition> extends infer TDef extends Record<string, boolean>\n ? _IfNoKeys<\n TDef,\n Record<never, never>,\n _Simplify<\n {\n [K in keyof TDef as TDef[K] extends true ? K : never]: string\n } & {\n [K in keyof TDef as TDef[K] extends false ? K : never]?: string | undefined\n }\n >\n >\n : Record<never, never>\n\nexport type _SplitPathSegments<TPath extends string> = TPath extends ''\n ? []\n : TPath extends '/'\n ? []\n : TPath extends `/${infer Rest}`\n ? _SplitPathSegments<Rest>\n : TPath extends `${infer Segment}/${infer Rest}`\n ? Segment extends ''\n ? _SplitPathSegments<Rest>\n : [Segment, ..._SplitPathSegments<Rest>]\n : TPath extends ''\n ? []\n : [TPath]\n\nexport type _ParamDefinitionFromSegment<TSegment extends string> = TSegment extends `:${infer Name}?`\n ? { [K in Name]: false }\n : TSegment extends `:${infer Name}`\n ? { [K in Name]: true }\n : TSegment extends `${string}*?`\n ? { '*': false }\n : TSegment extends `${string}*`\n ? { '*': true }\n : Record<never, never>\n\nexport type _MergeParamDefinitions<A extends Record<string, boolean>, B extends Record<string, boolean>> = {\n [K in keyof A | keyof B]: K extends keyof B ? B[K] : K extends keyof A ? A[K] : never\n}\n\nexport type _ExtractParamsDefinitionBySegments<TSegments extends string[]> = TSegments extends [\n infer Segment extends string,\n ...infer Rest extends string[],\n]\n ? _MergeParamDefinitions<_ParamDefinitionFromSegment<Segment>, _ExtractParamsDefinitionBySegments<Rest>>\n : Record<never, never>\n\nexport type _RequiredParamKeys<TDefinition extends string> = {\n [K in keyof _ParamsDefinition<TDefinition>]: _ParamsDefinition<TDefinition>[K] extends true ? K : never\n}[keyof _ParamsDefinition<TDefinition>]\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 EnsureLeadingSlash<S extends string> = S extends '' ? '/' : S extends `/${string}` ? S : `/${S}`\nexport type TrimTrailingSlash<S extends string> = S extends '/'\n ? '/'\n : S extends `${infer V}/`\n ? TrimTrailingSlash<V>\n : S\nexport type NormalizeRouteDefinition<S extends string> = TrimTrailingSlash<EnsureLeadingSlash<DedupeSlashes<S>>>\nexport type EmptyRecord = Record<never, never>\nexport type JoinPath<Parent extends string, Suffix extends string> = NormalizeRouteDefinition<\n Definition<Parent> extends infer A extends string\n ? Definition<Suffix> extends infer B extends string\n ? NormalizeRouteDefinition<A> extends infer ANormalized extends string\n ? NormalizeRouteDefinition<B> extends infer BNormalized extends string\n ? BNormalized extends '/'\n ? ANormalized\n : ANormalized extends '/'\n ? BNormalized\n : `${ANormalized}/${BNormalized}`\n : never\n : never\n : never\n : never\n>\nexport type PathExtended<\n TSourceDefinitionDefinition extends string,\n TSuffixDefinitionDefinition extends string,\n> = `${NormalizeRouteDefinition<JoinPath<StripTrailingWildcard<TSourceDefinitionDefinition>, TSuffixDefinitionDefinition>>}`\n\nexport type StripTrailingWildcard<TDefinition extends string> = TDefinition extends `${infer TPath}*?`\n ? NormalizeRouteDefinition<TPath>\n : TDefinition extends `${infer TPath}*`\n ? NormalizeRouteDefinition<TPath>\n : NormalizeRouteDefinition<TDefinition>\n\nexport type OnlyIfNoParams<TRoute extends AnyRoute | string, Yes, No = never> =\n HasParams<TRoute> extends false ? Yes : No\nexport type OnlyIfHasParams<TRoute extends AnyRoute | string, Yes, No = never> =\n HasParams<TRoute> extends true ? Yes : No\n\nexport type GetPathInput<\n TDefinition extends string,\n TSearchInput extends UnknownSearchInput,\n> = _ParamsInput<TDefinition> & {\n '?'?: TSearchInput\n '#'?: string | number\n}\nexport type GetPathInputByRoute<TRoute extends AnyRoute | CallableRoute | string> =\n TRoute extends AnyRoute<any, infer TSearchInput>\n ? GetPathInput<Definition<TRoute>, TSearchInput>\n : TRoute extends string\n ? GetPathInput<TRoute, UnknownSearchInput>\n : never\n\nexport type IsAny<T> = 0 extends 1 & T ? true : false\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\n// export type _IsAncestor<T extends string, TAncestor extends string> = T extends TAncestor\n// ? false\n// : T extends `${TAncestor}${string}`\n// ? true\n// : false\n// export type _IsDescendant<T extends string, TDescendant extends string> = TDescendant extends T\n// ? false\n// : TDescendant extends `${T}${string}`\n// ? true\n// : false\n// export type _IsSame<T extends string, TExact extends string> = T extends TExact\n// ? TExact extends T\n// ? true\n// : false\n// : false\n\nexport type _SafeParseInputResult<TInputParsed extends Record<string, unknown>> =\n | {\n success: true\n data: TInputParsed\n error: undefined\n }\n | {\n success: false\n data: undefined\n error: Error\n }\n\nexport type SchemaRoute0<\n TInput extends Record<string, unknown>,\n TOutput extends Record<string, unknown>,\n> = StandardSchemaV1<TInput, TOutput> & {\n parse: (input: unknown) => TOutput\n safeParse: (input: unknown) => _SafeParseInputResult<TOutput>\n}\n"],"mappings":"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","names":["searchInput","hashInput","paramsInput","absOriginInput","stringifySearchQuery","parseSearchQuery"]}
@@ -224,6 +224,45 @@ type ParamsOutput<T extends AnyRoute | string> = {
224
224
  type ParamsInput<T extends AnyRoute | string = string> = _ParamsInput<Definition<T>>;
225
225
  type IsParamsOptional<T extends AnyRoute | string> = HasRequiredParams<Definition<T>> extends true ? false : true;
226
226
  type ParamsInputStringOnly<T extends AnyRoute | string = string> = _ParamsInputStringOnly<Definition<T>>;
227
+ type ExactRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {
228
+ type: 'exact';
229
+ route: Definition<TRoute>;
230
+ params: ParamsOutput<TRoute>;
231
+ exact: true;
232
+ ancestor: false;
233
+ descendant: false;
234
+ unmatched: false;
235
+ };
236
+ type AncestorRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {
237
+ type: 'ancestor';
238
+ route: Definition<TRoute>;
239
+ params: ParamsOutput<TRoute> & {
240
+ [key: string]: string | undefined;
241
+ };
242
+ exact: false;
243
+ ancestor: true;
244
+ descendant: false;
245
+ unmatched: false;
246
+ };
247
+ type DescendantRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {
248
+ type: 'descendant';
249
+ route: Definition<TRoute>;
250
+ params: Partial<ParamsOutput<TRoute>>;
251
+ exact: false;
252
+ ancestor: false;
253
+ descendant: true;
254
+ unmatched: false;
255
+ };
256
+ type UnmatchedRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {
257
+ type: 'unmatched';
258
+ route: Definition<TRoute>;
259
+ params: Record<never, never>;
260
+ exact: false;
261
+ ancestor: false;
262
+ descendant: false;
263
+ unmatched: true;
264
+ };
265
+ type RouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = ExactRouteRelation<TRoute> | AncestorRouteRelation<TRoute> | DescendantRouteRelation<TRoute> | UnmatchedRouteRelation<TRoute>;
227
266
  type LocationParams<TDefinition extends string> = {
228
267
  [K in keyof _ParamsDefinition<TDefinition>]: _ParamsDefinition<TDefinition>[K] extends true ? string : string | undefined;
229
268
  };
@@ -311,45 +350,6 @@ type ExactLocationState<TRoute extends AnyRoute | string = AnyRoute | string> =
311
350
  params: ParamsOutput<TRoute>;
312
351
  };
313
352
  type ExactLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & ExactLocationState<TRoute>;
314
- type ExactRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {
315
- type: 'exact';
316
- route: Definition<TRoute>;
317
- params: ParamsOutput<TRoute>;
318
- exact: true;
319
- ascendant: false;
320
- descendant: false;
321
- unmatched: false;
322
- };
323
- type AscendantRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {
324
- type: 'ascendant';
325
- route: Definition<TRoute>;
326
- params: ParamsOutput<TRoute> & {
327
- [key: string]: string | undefined;
328
- };
329
- exact: false;
330
- ascendant: true;
331
- descendant: false;
332
- unmatched: false;
333
- };
334
- type DescendantRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {
335
- type: 'descendant';
336
- route: Definition<TRoute>;
337
- params: Partial<ParamsOutput<TRoute>>;
338
- exact: false;
339
- ascendant: false;
340
- descendant: true;
341
- unmatched: false;
342
- };
343
- type UnmatchedRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {
344
- type: 'unmatched';
345
- route: Definition<TRoute>;
346
- params: Record<never, never>;
347
- exact: false;
348
- ascendant: false;
349
- descendant: false;
350
- unmatched: true;
351
- };
352
- type RouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = ExactRouteRelation<TRoute> | AscendantRouteRelation<TRoute> | DescendantRouteRelation<TRoute> | UnmatchedRouteRelation<TRoute>;
353
353
  type UnknownSearchParsedValue = string | UnknownSearchParsed | Array<UnknownSearchParsedValue>;
354
354
  interface UnknownSearchParsed {
355
355
  [key: string]: UnknownSearchParsedValue;
@@ -452,4 +452,4 @@ type SchemaRoute0<TInput extends Record<string, unknown>, TOutput extends Record
452
452
  safeParse: (input: unknown) => _SafeParseInputResult<TOutput>;
453
453
  };
454
454
 
455
- export { type AncestorLocation, type AncestorLocationState, type AnyLocation, type AnyRoute, type AnyRouteOrDefinition, type AscendantRouteRelation, type CallableRoute, type DedupeSlashes, type Definition, type DescendantLocation, type DescendantLocationState, type DescendantRouteRelation, type EmptyRecord, type EnsureLeadingSlash, type ExactLocation, type ExactLocationState, type ExactRouteRelation, type Extended, type ExtractRoute, type ExtractRoutesKeys, type GetPathInput, type GetPathInputByRoute, type HasParams, type HasRequiredParams, type HasWildcard, type IsAny, type IsParamsOptional, type IsSameParams, type JoinPath, type KnownLocation, type LocationParams, type NormalizeRouteDefinition, type OnlyIfHasParams, type OnlyIfNoParams, type ParamsDefinition, type ParamsInput, type ParamsInputStringOnly, type ParamsOutput, type PathExtended, type ReplacePathParams, Route0, type RouteConfigInput, type RouteRelation, type RouteToken, Routes, type RoutesPretty, type RoutesRecord, type RoutesRecordHydrated, type SchemaRoute0, type StripTrailingWildcard, type TrimTrailingSlash, type UnknownLocation, type UnknownLocationState, type UnknownSearchInput, type UnknownSearchParsed, type UnknownSearchParsedValue, type UnmatchedRouteRelation, type WeakAncestorLocation, type WeakAncestorLocationState, type WeakDescendantLocation, type WeakDescendantLocationState, type _ExtractParamsDefinitionBySegments, type _GeneralLocation, type _IfNoKeys, type _IsSameParams, type _MergeParamDefinitions, type _ParamDefinitionFromSegment, type _ParamsDefinition, type _ParamsInput, type _ParamsInputStringOnly, type _RequiredParamKeys, type _SafeParseInputResult, type _Simplify, type _SplitPathSegments };
455
+ export { type AncestorLocation, type AncestorLocationState, type AncestorRouteRelation, type AnyLocation, type AnyRoute, type AnyRouteOrDefinition, type CallableRoute, type DedupeSlashes, type Definition, type DescendantLocation, type DescendantLocationState, type DescendantRouteRelation, type EmptyRecord, type EnsureLeadingSlash, type ExactLocation, type ExactLocationState, type ExactRouteRelation, type Extended, type ExtractRoute, type ExtractRoutesKeys, type GetPathInput, type GetPathInputByRoute, type HasParams, type HasRequiredParams, type HasWildcard, type IsAny, type IsParamsOptional, type IsSameParams, type JoinPath, type KnownLocation, type LocationParams, type NormalizeRouteDefinition, type OnlyIfHasParams, type OnlyIfNoParams, type ParamsDefinition, type ParamsInput, type ParamsInputStringOnly, type ParamsOutput, type PathExtended, type ReplacePathParams, Route0, type RouteConfigInput, type RouteRelation, type RouteToken, Routes, type RoutesPretty, type RoutesRecord, type RoutesRecordHydrated, type SchemaRoute0, type StripTrailingWildcard, type TrimTrailingSlash, type UnknownLocation, type UnknownLocationState, type UnknownSearchInput, type UnknownSearchParsed, type UnknownSearchParsedValue, type UnmatchedRouteRelation, type WeakAncestorLocation, type WeakAncestorLocationState, type WeakDescendantLocation, type WeakDescendantLocationState, type _ExtractParamsDefinitionBySegments, type _GeneralLocation, type _IfNoKeys, type _IsSameParams, type _MergeParamDefinitions, type _ParamDefinitionFromSegment, type _ParamsDefinition, type _ParamsInput, type _ParamsInputStringOnly, type _RequiredParamKeys, type _SafeParseInputResult, type _Simplify, type _SplitPathSegments };
@@ -224,6 +224,45 @@ type ParamsOutput<T extends AnyRoute | string> = {
224
224
  type ParamsInput<T extends AnyRoute | string = string> = _ParamsInput<Definition<T>>;
225
225
  type IsParamsOptional<T extends AnyRoute | string> = HasRequiredParams<Definition<T>> extends true ? false : true;
226
226
  type ParamsInputStringOnly<T extends AnyRoute | string = string> = _ParamsInputStringOnly<Definition<T>>;
227
+ type ExactRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {
228
+ type: 'exact';
229
+ route: Definition<TRoute>;
230
+ params: ParamsOutput<TRoute>;
231
+ exact: true;
232
+ ancestor: false;
233
+ descendant: false;
234
+ unmatched: false;
235
+ };
236
+ type AncestorRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {
237
+ type: 'ancestor';
238
+ route: Definition<TRoute>;
239
+ params: ParamsOutput<TRoute> & {
240
+ [key: string]: string | undefined;
241
+ };
242
+ exact: false;
243
+ ancestor: true;
244
+ descendant: false;
245
+ unmatched: false;
246
+ };
247
+ type DescendantRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {
248
+ type: 'descendant';
249
+ route: Definition<TRoute>;
250
+ params: Partial<ParamsOutput<TRoute>>;
251
+ exact: false;
252
+ ancestor: false;
253
+ descendant: true;
254
+ unmatched: false;
255
+ };
256
+ type UnmatchedRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {
257
+ type: 'unmatched';
258
+ route: Definition<TRoute>;
259
+ params: Record<never, never>;
260
+ exact: false;
261
+ ancestor: false;
262
+ descendant: false;
263
+ unmatched: true;
264
+ };
265
+ type RouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = ExactRouteRelation<TRoute> | AncestorRouteRelation<TRoute> | DescendantRouteRelation<TRoute> | UnmatchedRouteRelation<TRoute>;
227
266
  type LocationParams<TDefinition extends string> = {
228
267
  [K in keyof _ParamsDefinition<TDefinition>]: _ParamsDefinition<TDefinition>[K] extends true ? string : string | undefined;
229
268
  };
@@ -311,45 +350,6 @@ type ExactLocationState<TRoute extends AnyRoute | string = AnyRoute | string> =
311
350
  params: ParamsOutput<TRoute>;
312
351
  };
313
352
  type ExactLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & ExactLocationState<TRoute>;
314
- type ExactRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {
315
- type: 'exact';
316
- route: Definition<TRoute>;
317
- params: ParamsOutput<TRoute>;
318
- exact: true;
319
- ascendant: false;
320
- descendant: false;
321
- unmatched: false;
322
- };
323
- type AscendantRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {
324
- type: 'ascendant';
325
- route: Definition<TRoute>;
326
- params: ParamsOutput<TRoute> & {
327
- [key: string]: string | undefined;
328
- };
329
- exact: false;
330
- ascendant: true;
331
- descendant: false;
332
- unmatched: false;
333
- };
334
- type DescendantRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {
335
- type: 'descendant';
336
- route: Definition<TRoute>;
337
- params: Partial<ParamsOutput<TRoute>>;
338
- exact: false;
339
- ascendant: false;
340
- descendant: true;
341
- unmatched: false;
342
- };
343
- type UnmatchedRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {
344
- type: 'unmatched';
345
- route: Definition<TRoute>;
346
- params: Record<never, never>;
347
- exact: false;
348
- ascendant: false;
349
- descendant: false;
350
- unmatched: true;
351
- };
352
- type RouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = ExactRouteRelation<TRoute> | AscendantRouteRelation<TRoute> | DescendantRouteRelation<TRoute> | UnmatchedRouteRelation<TRoute>;
353
353
  type UnknownSearchParsedValue = string | UnknownSearchParsed | Array<UnknownSearchParsedValue>;
354
354
  interface UnknownSearchParsed {
355
355
  [key: string]: UnknownSearchParsedValue;
@@ -452,4 +452,4 @@ type SchemaRoute0<TInput extends Record<string, unknown>, TOutput extends Record
452
452
  safeParse: (input: unknown) => _SafeParseInputResult<TOutput>;
453
453
  };
454
454
 
455
- export { type AncestorLocation, type AncestorLocationState, type AnyLocation, type AnyRoute, type AnyRouteOrDefinition, type AscendantRouteRelation, type CallableRoute, type DedupeSlashes, type Definition, type DescendantLocation, type DescendantLocationState, type DescendantRouteRelation, type EmptyRecord, type EnsureLeadingSlash, type ExactLocation, type ExactLocationState, type ExactRouteRelation, type Extended, type ExtractRoute, type ExtractRoutesKeys, type GetPathInput, type GetPathInputByRoute, type HasParams, type HasRequiredParams, type HasWildcard, type IsAny, type IsParamsOptional, type IsSameParams, type JoinPath, type KnownLocation, type LocationParams, type NormalizeRouteDefinition, type OnlyIfHasParams, type OnlyIfNoParams, type ParamsDefinition, type ParamsInput, type ParamsInputStringOnly, type ParamsOutput, type PathExtended, type ReplacePathParams, Route0, type RouteConfigInput, type RouteRelation, type RouteToken, Routes, type RoutesPretty, type RoutesRecord, type RoutesRecordHydrated, type SchemaRoute0, type StripTrailingWildcard, type TrimTrailingSlash, type UnknownLocation, type UnknownLocationState, type UnknownSearchInput, type UnknownSearchParsed, type UnknownSearchParsedValue, type UnmatchedRouteRelation, type WeakAncestorLocation, type WeakAncestorLocationState, type WeakDescendantLocation, type WeakDescendantLocationState, type _ExtractParamsDefinitionBySegments, type _GeneralLocation, type _IfNoKeys, type _IsSameParams, type _MergeParamDefinitions, type _ParamDefinitionFromSegment, type _ParamsDefinition, type _ParamsInput, type _ParamsInputStringOnly, type _RequiredParamKeys, type _SafeParseInputResult, type _Simplify, type _SplitPathSegments };
455
+ export { type AncestorLocation, type AncestorLocationState, type AncestorRouteRelation, type AnyLocation, type AnyRoute, type AnyRouteOrDefinition, type CallableRoute, type DedupeSlashes, type Definition, type DescendantLocation, type DescendantLocationState, type DescendantRouteRelation, type EmptyRecord, type EnsureLeadingSlash, type ExactLocation, type ExactLocationState, type ExactRouteRelation, type Extended, type ExtractRoute, type ExtractRoutesKeys, type GetPathInput, type GetPathInputByRoute, type HasParams, type HasRequiredParams, type HasWildcard, type IsAny, type IsParamsOptional, type IsSameParams, type JoinPath, type KnownLocation, type LocationParams, type NormalizeRouteDefinition, type OnlyIfHasParams, type OnlyIfNoParams, type ParamsDefinition, type ParamsInput, type ParamsInputStringOnly, type ParamsOutput, type PathExtended, type ReplacePathParams, Route0, type RouteConfigInput, type RouteRelation, type RouteToken, Routes, type RoutesPretty, type RoutesRecord, type RoutesRecordHydrated, type SchemaRoute0, type StripTrailingWildcard, type TrimTrailingSlash, type UnknownLocation, type UnknownLocationState, type UnknownSearchInput, type UnknownSearchParsed, type UnknownSearchParsedValue, type UnmatchedRouteRelation, type WeakAncestorLocation, type WeakAncestorLocationState, type WeakDescendantLocation, type WeakDescendantLocationState, type _ExtractParamsDefinitionBySegments, type _GeneralLocation, type _IfNoKeys, type _IsSameParams, type _MergeParamDefinitions, type _ParamDefinitionFromSegment, type _ParamsDefinition, type _ParamsInput, type _ParamsInputStringOnly, type _RequiredParamKeys, type _SafeParseInputResult, type _Simplify, type _SplitPathSegments };
package/dist/esm/index.js CHANGED
@@ -500,7 +500,7 @@ class Route0 {
500
500
  route: this.definition,
501
501
  params,
502
502
  exact: true,
503
- ascendant: false,
503
+ ancestor: false,
504
504
  descendant: false,
505
505
  unmatched: false
506
506
  };
@@ -516,11 +516,11 @@ class Route0 {
516
516
  })
517
517
  );
518
518
  return {
519
- type: "ascendant",
519
+ type: "ancestor",
520
520
  route: this.definition,
521
521
  params,
522
522
  exact: false,
523
- ascendant: true,
523
+ ancestor: true,
524
524
  descendant: false,
525
525
  unmatched: false
526
526
  };
@@ -544,7 +544,7 @@ class Route0 {
544
544
  route: this.definition,
545
545
  params,
546
546
  exact: false,
547
- ascendant: false,
547
+ ancestor: false,
548
548
  descendant: true,
549
549
  unmatched: false
550
550
  };
@@ -554,7 +554,7 @@ class Route0 {
554
554
  route: this.definition,
555
555
  params: {},
556
556
  exact: false,
557
- ascendant: false,
557
+ ancestor: false,
558
558
  descendant: false,
559
559
  unmatched: true
560
560
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["import type { StandardSchemaV1 } from '@standard-schema/spec'\nimport { parse as parseSearchQuery, stringify as stringifySearchQuery } from '@devp0nt/flat0'\n\nexport type RouteToken =\n | { kind: 'static'; value: string }\n | { kind: 'param'; name: string; optional: boolean }\n | { kind: 'wildcard'; prefix: string; optional: boolean }\n\nconst escapeRegex = (value: string): string => value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n\nconst collapseDuplicateSlashes = (value: string): string => value.replace(/\\/{2,}/g, '/')\n\n/**\n * Strongly typed route descriptor and URL builder.\n *\n * A route definition uses:\n * - path params: `/users/:id`\n * - named search keys: `/users&tab&sort`\n * - loose search mode: trailing `&`, e.g. `/users&`\n *\n * Instances are callable (same as `.get()`), so `route(input)` and\n * `route.get(input)` are equivalent.\n */\nexport class Route0<TDefinition extends string, TSearchInput extends UnknownSearchInput = UnknownSearchInput> {\n readonly definition: TDefinition\n readonly params: _ParamsDefinition<TDefinition>\n private _origin: string | undefined\n private _callable: CallableRoute<TDefinition, TSearchInput>\n private _routeSegments?: string[]\n private _routeTokens?: RouteToken[]\n private _routePatternCandidates?: string[]\n private _pathParamsDefinition?: Record<string, boolean>\n private _definitionWithoutTrailingWildcard?: string\n private _routeRegexBaseStringRaw?: string\n private _regexBaseString?: string\n private _regexString?: string\n private _regex?: RegExp\n private _regexAncestor?: RegExp\n private _regexDescendantMatchers?: Array<{ regex: RegExp; captureKeys: string[] }>\n private _captureKeys?: string[]\n private _normalizedDefinition?: string\n private _definitionParts?: string[]\n\n static normalizeSlash = (value: string): string => {\n const collapsed = collapseDuplicateSlashes(value)\n if (collapsed === '' || collapsed === '/') return '/'\n const withLeadingSlash = collapsed.startsWith('/') ? collapsed : `/${collapsed}`\n return withLeadingSlash.length > 1 && withLeadingSlash.endsWith('/')\n ? withLeadingSlash.slice(0, -1)\n : withLeadingSlash\n }\n\n private static _getRouteSegments(definition: string): string[] {\n if (definition === '' || definition === '/') return []\n return definition.split('/').filter(Boolean)\n }\n\n private static _validateRouteDefinition(definition: string): void {\n const segments = Route0._getRouteSegments(definition)\n const wildcardSegments = segments.filter((segment) => segment.includes('*'))\n if (wildcardSegments.length === 0) return\n if (wildcardSegments.length > 1) {\n throw new Error(`Invalid route definition \"${definition}\": only one wildcard segment is allowed`)\n }\n const wildcardSegmentIndex = segments.findIndex((segment) => segment.includes('*'))\n const wildcardSegment = segments[wildcardSegmentIndex]\n if (!wildcardSegment.match(/^(?:\\*|\\*\\?|[^*]+\\*|\\S+\\*\\?)$/)) {\n throw new Error(`Invalid route definition \"${definition}\": wildcard must be trailing in its segment`)\n }\n if (wildcardSegmentIndex !== segments.length - 1) {\n throw new Error(`Invalid route definition \"${definition}\": wildcard segment is allowed only at the end`)\n }\n }\n\n Infer: {\n ParamsDefinition: _ParamsDefinition<TDefinition>\n ParamsInput: _ParamsInput<TDefinition>\n ParamsInputStringOnly: _ParamsInputStringOnly<TDefinition>\n ParamsOutput: ParamsOutput<TDefinition>\n SearchInput: TSearchInput\n } = null as never\n\n /** Base URL used when generating absolute URLs (`abs: true`). */\n get origin(): string {\n if (!this._origin) {\n throw new Error(\n 'origin for route ' +\n this.definition +\n ' is not set, please provide it like Route0.create(route, {origin: \"https://example.com\"}) in config or set via clones like routes._.clone({origin: \"https://example.com\"})',\n )\n }\n return this._origin\n }\n set origin(origin: string) {\n this._origin = origin\n }\n\n private constructor(definition: TDefinition, config: RouteConfigInput = {}) {\n const normalizedDefinition = Route0.normalizeSlash(definition) as TDefinition\n Route0._validateRouteDefinition(normalizedDefinition)\n this.definition = normalizedDefinition\n this.params = this.pathParamsDefinition as _ParamsDefinition<TDefinition>\n\n const { origin } = config\n if (origin && typeof origin === 'string' && origin.length) {\n this._origin = origin\n } else {\n const g = globalThis as unknown as { location?: { origin?: string } } | undefined\n if (typeof g?.location?.origin === 'string' && g.location.origin.length > 0) {\n this._origin = g.location.origin\n } else {\n this._origin = undefined\n }\n }\n const callable = this.get.bind(this)\n Object.setPrototypeOf(callable, this)\n Object.defineProperty(callable, Symbol.toStringTag, {\n value: this.definition,\n })\n this._callable = callable as CallableRoute<TDefinition, TSearchInput>\n }\n\n /**\n * Creates a callable route instance.\n *\n * If an existing route/callable route is provided, it is cloned.\n */\n static create<TDefinition extends string>(\n definition: TDefinition | AnyRoute<TDefinition> | CallableRoute<TDefinition>,\n config?: RouteConfigInput,\n ): CallableRoute<NormalizeRouteDefinition<TDefinition>> {\n if (typeof definition === 'function' || typeof definition === 'object') {\n return definition.clone(config) as CallableRoute<NormalizeRouteDefinition<TDefinition>>\n }\n const original = new Route0<NormalizeRouteDefinition<TDefinition>>(\n Route0.normalizeSlash(definition) as NormalizeRouteDefinition<TDefinition>,\n config,\n )\n return original._callable as CallableRoute<NormalizeRouteDefinition<TDefinition>>\n }\n\n /**\n * Normalizes a definition/route into a callable route.\n *\n * Unlike `create`, passing a callable route returns the same instance.\n */\n static from<TDefinition extends string, TSearchInput extends UnknownSearchInput>(\n definition: TDefinition | AnyRoute<TDefinition, TSearchInput> | CallableRoute<TDefinition, TSearchInput>,\n ): CallableRoute<NormalizeRouteDefinition<TDefinition>, TSearchInput> {\n if (typeof definition === 'function') {\n return definition as CallableRoute<NormalizeRouteDefinition<TDefinition>, TSearchInput>\n }\n const original =\n typeof definition === 'object'\n ? definition\n : new Route0<NormalizeRouteDefinition<TDefinition>>(\n Route0.normalizeSlash(definition) as NormalizeRouteDefinition<TDefinition>,\n )\n return original._callable as CallableRoute<NormalizeRouteDefinition<TDefinition>, TSearchInput>\n }\n\n private static _getAbsPath(origin: string, url: string) {\n return new URL(url, origin).toString().replace(/\\/$/, '')\n }\n\n search<TNewSearchInput extends UnknownSearchInput>(): CallableRoute<TDefinition, TNewSearchInput> {\n return this._callable as CallableRoute<TDefinition, TNewSearchInput>\n }\n\n /** Extends the current route definition by appending a suffix route. */\n extend<TSuffixDefinition extends string>(\n suffixDefinition: TSuffixDefinition,\n ): CallableRoute<PathExtended<TDefinition, TSuffixDefinition>, TSearchInput> {\n const definition = Route0.normalizeSlash(`${this.definitionWithoutTrailingWildcard}/${suffixDefinition}`)\n return Route0.create<PathExtended<TDefinition, TSuffixDefinition>>(\n definition as PathExtended<TDefinition, TSuffixDefinition>,\n {\n origin: this._origin,\n },\n ) as CallableRoute<PathExtended<TDefinition, TSuffixDefinition>, TSearchInput>\n }\n\n get(...args: IsParamsOptional<TDefinition> extends true ? [abs: boolean | string | undefined] : never): string\n get(\n ...args: IsParamsOptional<TDefinition> extends true\n ? [input?: GetPathInput<TDefinition, TSearchInput> | undefined, abs?: boolean | string | undefined]\n : [input: GetPathInput<TDefinition, TSearchInput>, abs?: boolean | string | undefined]\n ): string\n\n // implementation\n get(...args: unknown[]): string {\n const { searchInput, paramsInput, absInput, absOriginInput, hashInput } = ((): {\n searchInput: Record<string, unknown>\n paramsInput: Record<string, string | undefined>\n absInput: boolean\n absOriginInput: string | undefined\n hashInput: string | undefined\n } => {\n if (args.length === 0) {\n return {\n searchInput: {},\n paramsInput: {},\n absInput: false,\n absOriginInput: undefined,\n hashInput: undefined,\n }\n }\n const [input, abs] = ((): [Record<string, unknown>, boolean | string | undefined] => {\n if (typeof args[0] === 'object' && args[0] !== null) {\n return [args[0], args[1]] as [Record<string, unknown>, boolean | string | undefined]\n }\n if (typeof args[1] === 'object' && args[1] !== null) {\n return [args[1], args[0]] as [Record<string, unknown>, boolean | string | undefined]\n }\n if (typeof args[0] === 'boolean' || typeof args[0] === 'string') {\n return [{}, args[0]]\n }\n if (typeof args[1] === 'boolean' || typeof args[1] === 'string') {\n return [{}, args[1]]\n }\n return [{}, undefined]\n })()\n let searchInput: Record<string, unknown> = {}\n let hashInput: string | undefined = undefined\n const paramsInput: Record<string, string | undefined> = {}\n for (const [key, value] of Object.entries(input)) {\n if (key === '?' && typeof value === 'object' && value !== null) {\n searchInput = value as Record<string, unknown>\n } else if (key === '#' && (typeof value === 'string' || typeof value === 'number')) {\n hashInput = String(value)\n } else if (key in this.params && (typeof value === 'string' || typeof value === 'number')) {\n Object.assign(paramsInput, { [key]: String(value) })\n }\n }\n const absOriginInput = typeof abs === 'string' && abs.length > 0 ? abs : undefined\n return {\n searchInput,\n paramsInput,\n absInput: absOriginInput !== undefined || abs === true,\n absOriginInput,\n hashInput,\n }\n })()\n\n // create url\n\n let url = this.definition as string\n // optional named params like /:id?\n url = url.replace(/\\/:([A-Za-z0-9_]+)\\?/g, (_m, k) => {\n const value = paramsInput[k]\n if (value === undefined) return ''\n return `/${encodeURIComponent(String(value))}`\n })\n // required named 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] ?? 'undefined')))\n // optional wildcard segment (/*?)\n url = url.replace(/\\/\\*\\?/g, () => {\n const value = paramsInput['*']\n if (value === undefined) return ''\n const stringValue = String(value)\n return stringValue.startsWith('/') ? stringValue : `/${stringValue}`\n })\n // required wildcard segment (/*)\n url = url.replace(/\\/\\*/g, () => {\n const value = String(paramsInput['*'] ?? '')\n return value.startsWith('/') ? value : `/${value}`\n })\n // optional wildcard inline (e.g. /app*?)\n url = url.replace(/\\*\\?/g, () => String(paramsInput['*'] ?? ''))\n // required wildcard inline (e.g. /app*)\n url = url.replace(/\\*/g, () => String(paramsInput['*'] ?? ''))\n // search params\n const searchString = stringifySearchQuery(searchInput, { arrayIndexes: false })\n url = [url, searchString].filter(Boolean).join('?')\n // dedupe slashes\n url = collapseDuplicateSlashes(url)\n // absolute\n url = absInput ? Route0._getAbsPath(absOriginInput || this.origin, url) : url\n // hash\n if (hashInput !== undefined) {\n url = `${url}#${hashInput}`\n }\n\n return url\n }\n\n /** Returns path param keys extracted from route definition. */\n getParamsKeys(): string[] {\n return Object.keys(this.params)\n }\n\n getTokens(): RouteToken[] {\n return this.routeTokens.map((token): RouteToken => ({ ...token }))\n }\n\n /** Clones route with optional config override. */\n clone(config?: RouteConfigInput): CallableRoute<TDefinition> {\n return Route0.create(this.definition, config) as CallableRoute<TDefinition>\n }\n\n get regexBaseString(): string {\n if (this._regexBaseString === undefined) {\n this._regexBaseString = this.routeRegexBaseStringRaw.replace(/\\/+$/, '') + '/?' // remove trailing slashes and add optional slash\n }\n return this._regexBaseString\n }\n\n get regexString(): string {\n if (this._regexString === undefined) {\n this._regexString = `^${this.regexBaseString}$`\n }\n return this._regexString\n }\n\n get regex(): RegExp {\n if (this._regex === undefined) {\n this._regex = new RegExp(this.regexString)\n }\n return this._regex\n }\n\n get regexAncestor(): RegExp {\n if (this._regexAncestor === undefined) {\n this._regexAncestor = new RegExp(`^${this.regexBaseString}(?:/.*)?$`)\n }\n return this._regexAncestor\n }\n\n private get regexDescendantMatchers(): Array<{ regex: RegExp; captureKeys: string[] }> {\n if (this._regexDescendantMatchers === undefined) {\n const matchers: Array<{ regex: RegExp; captureKeys: string[] }> = []\n if (this.definitionParts[0] !== '/') {\n let pattern = ''\n const captureKeys: string[] = []\n for (const part of this.definitionParts) {\n if (part.startsWith(':')) {\n pattern += '/([^/]+)'\n captureKeys.push(part.replace(/^:/, '').replace(/\\?$/, ''))\n } else if (part.includes('*')) {\n const prefix = part.replace(/\\*\\??$/, '')\n pattern += `/${escapeRegex(prefix)}[^/]*`\n captureKeys.push('*')\n } else {\n pattern += `/${escapeRegex(part)}`\n }\n matchers.push({\n regex: new RegExp(`^${pattern}/?$`),\n captureKeys: [...captureKeys],\n })\n }\n }\n this._regexDescendantMatchers = matchers\n }\n return this._regexDescendantMatchers\n }\n\n private get captureKeys(): string[] {\n if (this._captureKeys === undefined) {\n this._captureKeys = this.routeTokens\n .filter((token): token is Extract<RouteToken, { kind: 'param' | 'wildcard' }> => token.kind !== 'static')\n .map((token) => (token.kind === 'param' ? token.name : '*'))\n }\n return this._captureKeys\n }\n\n private get routeSegments(): string[] {\n if (this._routeSegments === undefined) {\n this._routeSegments = Route0._getRouteSegments(this.definition)\n }\n return this._routeSegments\n }\n\n private get routeTokens(): RouteToken[] {\n if (this._routeTokens === undefined) {\n this._routeTokens = this.routeSegments.map((segment): RouteToken => {\n const param = segment.match(/^:([A-Za-z0-9_]+)(\\?)?$/)\n if (param) {\n return { kind: 'param', name: param[1], optional: param[2] === '?' }\n }\n if (segment === '*' || segment === '*?') {\n return { kind: 'wildcard', prefix: '', optional: segment.endsWith('?') }\n }\n const wildcard = segment.match(/^(.*)\\*(\\?)?$/)\n if (wildcard && !segment.includes('\\\\*')) {\n return { kind: 'wildcard', prefix: wildcard[1], optional: wildcard[2] === '?' }\n }\n return { kind: 'static', value: segment }\n })\n }\n return this._routeTokens\n }\n\n private get routePatternCandidates(): string[] {\n if (this._routePatternCandidates === undefined) {\n const values = (token: RouteToken): string[] => {\n if (token.kind === 'static') return [token.value]\n if (token.kind === 'param') return token.optional ? ['', 'x', 'y'] : ['x', 'y']\n if (token.prefix.length > 0)\n return [token.prefix, `${token.prefix}-x`, `${token.prefix}/x`, `${token.prefix}/y/z`]\n return ['', 'x', 'y', 'x/y']\n }\n let acc: string[] = ['']\n for (const token of this.routeTokens) {\n const next: string[] = []\n for (const base of acc) {\n for (const value of values(token)) {\n if (value === '') {\n next.push(base)\n } else if (value.startsWith('/')) {\n next.push(`${base}${value}`)\n } else {\n next.push(`${base}/${value}`)\n }\n }\n }\n // Keep candidate space bounded for large route definitions.\n acc = next.length > 512 ? next.slice(0, 512) : next\n }\n this._routePatternCandidates =\n acc.length === 0 ? ['/'] : Array.from(new Set(acc.map((x) => (x === '' ? '/' : collapseDuplicateSlashes(x)))))\n }\n return this._routePatternCandidates\n }\n\n private get pathParamsDefinition(): Record<string, boolean> {\n if (this._pathParamsDefinition === undefined) {\n const entries = this.routeTokens\n .filter((t) => t.kind !== 'static')\n .map((t): [string, boolean] => (t.kind === 'param' ? [t.name, !t.optional] : ['*', !t.optional]))\n this._pathParamsDefinition = Object.fromEntries(entries)\n }\n return this._pathParamsDefinition\n }\n\n private get definitionWithoutTrailingWildcard(): string {\n if (this._definitionWithoutTrailingWildcard === undefined) {\n this._definitionWithoutTrailingWildcard = this.definition.replace(/\\*\\??$/, '')\n }\n return this._definitionWithoutTrailingWildcard\n }\n\n private get routeRegexBaseStringRaw(): string {\n if (this._routeRegexBaseStringRaw === undefined) {\n if (this.routeTokens.length === 0) {\n this._routeRegexBaseStringRaw = ''\n } else {\n let pattern = ''\n for (const token of this.routeTokens) {\n if (token.kind === 'static') {\n pattern += `/${escapeRegex(token.value)}`\n continue\n }\n if (token.kind === 'param') {\n pattern += token.optional ? '(?:/([^/]+))?' : '/([^/]+)'\n continue\n }\n if (token.prefix.length > 0) {\n pattern += `/${escapeRegex(token.prefix)}(.*)`\n } else {\n // Wouter-compatible splat: /orders/* matches /orders and /orders/...\n pattern += '(?:/(.*))?'\n }\n }\n this._routeRegexBaseStringRaw = pattern\n }\n }\n return this._routeRegexBaseStringRaw\n }\n\n private get normalizedDefinition(): string {\n if (this._normalizedDefinition === undefined) {\n this._normalizedDefinition =\n this.definition.length > 1 && this.definition.endsWith('/') ? this.definition.slice(0, -1) : this.definition\n }\n return this._normalizedDefinition\n }\n\n private get definitionParts(): string[] {\n if (this._definitionParts === undefined) {\n this._definitionParts =\n this.normalizedDefinition === '/' ? ['/'] : this.normalizedDefinition.split('/').filter(Boolean)\n }\n return this._definitionParts\n }\n\n /** Fast pathname exact match check without building a full relation object. */\n isExact(pathname: string, normalize = true): boolean {\n const normalizedPathname = normalize ? Route0.normalizeSlash(pathname) : pathname\n return this.regex.test(normalizedPathname)\n }\n\n /** Fast pathname exact or ancestor match check without building a full relation object. */\n isExactOrAncestor(pathname: string, normalize = true): boolean {\n const normalizedPathname = normalize ? Route0.normalizeSlash(pathname) : pathname\n return this.regex.test(normalizedPathname) || this.regexAncestor.test(normalizedPathname)\n }\n\n /** True when route is ancestor of pathname (pathname is deeper). */\n isAncestor(pathname: string, normalize = true): boolean {\n const normalizedPathname = normalize ? Route0.normalizeSlash(pathname) : pathname\n return !this.regex.test(normalizedPathname) && this.regexAncestor.test(normalizedPathname)\n }\n\n /** True when route is descendant of pathname (pathname is shallower). */\n isDescendant(pathname: string, normalize = true): boolean {\n const normalizedPathname = normalize ? Route0.normalizeSlash(pathname) : pathname\n if (this.regex.test(normalizedPathname) || this.regexAncestor.test(normalizedPathname)) {\n return false\n }\n for (const matcher of this.regexDescendantMatchers) {\n if (normalizedPathname.match(matcher.regex)) {\n return true\n }\n }\n return false\n }\n\n /** Creates a grouped regex pattern string from many routes. */\n static getRegexStringGroup(routes: AnyRoute[]): string {\n const patterns = routes.map((route) => route.regexString).join('|')\n return `(${patterns})`\n }\n\n /** Creates a grouped regex from many routes. */\n static getRegexGroup(routes: AnyRoute[]): RegExp {\n const patterns = Route0.getRegexStringGroup(routes)\n return new RegExp(`^(${patterns})$`)\n }\n\n /** Converts any location shape to relative form (removes host/origin fields). */\n static toRelLocation<TLocation extends AnyLocation>(location: TLocation): TLocation {\n return {\n ...location,\n abs: false,\n origin: undefined,\n href: undefined,\n port: undefined,\n host: undefined,\n hostname: undefined,\n }\n }\n\n /** Converts a location to absolute form using provided origin URL. */\n static toAbsLocation<TLocation extends AnyLocation>(location: TLocation, origin: string): TLocation {\n const relLoc = Route0.toRelLocation(location)\n const url = new URL(relLoc.hrefRel, origin)\n return {\n ...location,\n abs: true,\n origin: url.origin,\n href: url.href,\n port: url.port,\n host: url.host,\n hostname: url.hostname,\n }\n }\n\n /**\n * Parses a URL-like input into raw location object (without route knowledge).\n *\n * Result is always `UnknownLocation` because no route matching is applied.\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 // Common derived values\n const hrefRel = url.pathname + url.search + url.hash\n\n // Build the location object consistent with _GeneralLocation\n let _search: UnknownSearchParsed | undefined\n const location: UnknownLocation = {\n pathname: url.pathname,\n get search() {\n if (_search === undefined) {\n _search = parseSearchQuery(url.search)\n }\n return _search\n },\n searchString: 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 params: undefined,\n route: undefined,\n }\n\n return location\n }\n\n // /**\n // * Parses input and returns location only for exact route matches.\n // */\n // getLocation(href: `${string}://${string}`): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(hrefRel: `/${string}`): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(hrefOrHrefRel: string): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(location: AnyLocation): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(url: AnyLocation): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): ExactLocation<TDefinition> | UnknownLocation {\n // const relation = this.getRelation(hrefOrHrefRelOrLocation)\n // if (!relation.exact) {\n // return Route0.getLocation(hrefOrHrefRelOrLocation)\n // }\n // const location = Route0.getLocation(hrefOrHrefRelOrLocation)\n // return {\n // ...location,\n // route: this.definition as Definition<TDefinition>,\n // params: relation.params as ParamsOutput<TDefinition>,\n // }\n // }\n\n /**\n * Parses input and evaluates pathname relation to this route.\n */\n getRelation(href: `${string}://${string}`): RouteRelation<TDefinition>\n getRelation(hrefRel: `/${string}`): RouteRelation<TDefinition>\n getRelation(hrefOrHrefRel: string): RouteRelation<TDefinition>\n getRelation(location: AnyLocation): RouteRelation<TDefinition>\n getRelation(url: URL): RouteRelation<TDefinition>\n getRelation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): RouteRelation<TDefinition>\n getRelation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): RouteRelation<TDefinition> {\n if (hrefOrHrefRelOrLocation instanceof URL) {\n return this.getRelation(hrefOrHrefRelOrLocation.href)\n }\n if (typeof hrefOrHrefRelOrLocation !== 'string') {\n hrefOrHrefRelOrLocation = hrefOrHrefRelOrLocation.href || hrefOrHrefRelOrLocation.hrefRel\n }\n // Normalize pathname (no trailing slash except root)\n const pathname = Route0.normalizeSlash(new URL(hrefOrHrefRelOrLocation, 'http://example.com').pathname)\n\n const paramNames = this.captureKeys\n const exactRe = this.regex\n const exactMatch = pathname.match(exactRe)\n\n if (exactMatch) {\n const values = exactMatch.slice(1, 1 + paramNames.length)\n const params = Object.fromEntries(\n paramNames.map((n, i) => {\n const value = values[i] as string | undefined\n return [n, value === undefined ? undefined : decodeURIComponent(value)]\n }),\n )\n return {\n type: 'exact',\n route: this.definition as Definition<TDefinition>,\n params: params as ParamsOutput<TDefinition>,\n exact: true,\n ascendant: false,\n descendant: false,\n unmatched: false,\n }\n }\n\n const ancestorRe = this.regexAncestor\n const ancestorMatch = pathname.match(ancestorRe)\n if (ancestorMatch) {\n const values = ancestorMatch.slice(1, 1 + paramNames.length)\n const params = Object.fromEntries(\n paramNames.map((n, i) => {\n const value = values[i] as string | undefined\n return [n, value === undefined ? undefined : decodeURIComponent(value)]\n }),\n )\n return {\n type: 'ascendant',\n route: this.definition as Definition<TDefinition>,\n params: params as ParamsOutput<TDefinition> & { [key: string]: string | undefined },\n exact: false,\n ascendant: true,\n descendant: false,\n unmatched: false,\n }\n }\n\n let descendantMatch: RegExpMatchArray | null = null\n let descendantCaptureKeys: string[] = []\n for (const matcher of this.regexDescendantMatchers) {\n const match = pathname.match(matcher.regex)\n if (!match) continue\n descendantMatch = match\n descendantCaptureKeys = matcher.captureKeys\n break\n }\n\n if (descendantMatch) {\n const values = descendantMatch.slice(1, 1 + descendantCaptureKeys.length)\n const params = Object.fromEntries(\n descendantCaptureKeys.map((key, index) => [key, decodeURIComponent(values[index] as string)]),\n )\n return {\n type: 'descendant',\n route: this.definition as Definition<TDefinition>,\n params: params as Partial<ParamsOutput<TDefinition>>,\n exact: false,\n ascendant: false,\n descendant: true,\n unmatched: false,\n }\n }\n\n return {\n type: 'unmatched',\n route: this.definition as Definition<TDefinition>,\n params: {},\n exact: false,\n ascendant: false,\n descendant: false,\n unmatched: true,\n }\n }\n\n private _validateParamsInput(input: unknown): StandardSchemaV1.Result<ParamsOutput<TDefinition>> {\n const paramsEntries = Object.entries(this.params) as Array<[string, boolean]>\n const paramsMap = this.params as Record<string, boolean>\n const requiredParamsKeys = paramsEntries.filter(([, required]) => required).map(([k]) => k)\n const paramsKeys = paramsEntries.map(([k]) => k)\n if (input === undefined) {\n if (requiredParamsKeys.length) {\n return {\n issues: [\n {\n message: `Missing params: ${requiredParamsKeys.map((k) => `\"${k}\"`).join(', ')}`,\n },\n ],\n }\n }\n input = {}\n }\n if (typeof input !== 'object' || input === null) {\n return {\n issues: [{ message: 'Invalid route params: expected object' }],\n }\n }\n const inputObj = input as Record<string, unknown>\n const inputKeys = Object.keys(inputObj)\n const notDefinedKeys = requiredParamsKeys.filter((k) => !inputKeys.includes(k))\n if (notDefinedKeys.length) {\n return {\n issues: [\n {\n message: `Missing params: ${notDefinedKeys.map((k) => `\"${k}\"`).join(', ')}`,\n },\n ],\n }\n }\n const data: Record<string, string | undefined> = {}\n for (const k of paramsKeys) {\n const v = inputObj[k]\n const required = paramsMap[k]\n if (v === undefined && !required) {\n data[k] = undefined as never\n } else if (typeof v === 'string') {\n data[k] = v\n } else if (typeof v === 'number') {\n data[k] = String(v)\n } else {\n return {\n issues: [{ message: `Invalid route params: expected string, number, got ${typeof v} for \"${k}\"` }],\n }\n }\n }\n return {\n value: data as ParamsOutput<TDefinition>,\n }\n }\n\n private _safeParseSchemaResult<TOutput extends Record<string, unknown>>(\n result: StandardSchemaV1.Result<TOutput>,\n ): _SafeParseInputResult<TOutput> {\n if ('issues' in result) {\n return {\n success: false,\n data: undefined,\n error: new Error(result.issues?.[0]?.message ?? 'Invalid input'),\n }\n }\n return {\n success: true,\n data: result.value,\n error: undefined,\n }\n }\n\n private _parseSchemaResult<TOutput extends Record<string, unknown>>(\n result: StandardSchemaV1.Result<TOutput>,\n ): TOutput {\n const safeResult = this._safeParseSchemaResult(result)\n if (safeResult.error) {\n throw safeResult.error\n }\n return safeResult.data\n }\n\n /** Standard Schema for route params input. */\n readonly schema: SchemaRoute0<ParamsInput<TDefinition>, ParamsOutput<TDefinition>> = {\n '~standard': {\n version: 1,\n vendor: 'route0',\n validate: (value) => this._validateParamsInput(value),\n types: undefined as unknown as StandardSchemaV1.Types<ParamsInput<TDefinition>, ParamsOutput<TDefinition>>,\n },\n parse: (value) => this._parseSchemaResult(this._validateParamsInput(value)),\n safeParse: (value) => this._safeParseSchemaResult(this._validateParamsInput(value)),\n }\n\n // /** True when path structure is equal (param names are ignored). */\n // isSame(other: AnyRoute): boolean {\n // const thisShape = this.routeTokens\n // .map((t) => {\n // if (t.kind === 'static') return `s:${t.value}`\n // if (t.kind === 'param') return `p:${t.optional ? 'o' : 'r'}`\n // return `w:${t.prefix}:${t.optional ? 'o' : 'r'}`\n // })\n // .join('/')\n // const otherRoute = Route0.from(other) as Route0<string, UnknownSearchInput>\n // const otherShape = otherRoute.routeTokens\n // .map((t) => {\n // if (t.kind === 'static') return `s:${t.value}`\n // if (t.kind === 'param') return `p:${t.optional ? 'o' : 'r'}`\n // return `w:${t.prefix}:${t.optional ? 'o' : 'r'}`\n // })\n // .join('/')\n // return thisShape === otherShape\n // }\n // /** Static convenience wrapper for `isSame`. */\n // static isSame(a: AnyRoute | string | undefined, b: AnyRoute | string | undefined): boolean {\n // if (!a) {\n // if (!b) return true\n // return false\n // }\n // if (!b) {\n // return false\n // }\n // return Route0.create(a).isSame(Route0.create(b))\n // }\n\n // /** True when current route is more specific/deeper than `other`. */\n // isDescendant(other: AnyRoute | string | undefined): boolean {\n // if (!other) return false\n // other = Route0.create(other)\n // // this is a descendant of other if:\n // // - paths are not exactly the same\n // // - other's path is a prefix of this path, matching params as wildcards\n // const getParts = (path: string) => (path === '/' ? ['/'] : path.split('/').filter(Boolean))\n // // Root is ancestor of any non-root; thus any non-root is a descendant of root\n // if (other.definition === '/' && this.definition !== '/') {\n // return true\n // }\n // const thisParts = getParts(this.definition)\n // const otherParts = getParts(other.definition)\n\n // // A descendant must be deeper\n // if (thisParts.length <= otherParts.length) return false\n\n // const matchesPatternPart = (patternPart: string, valuePart: string): { match: boolean; wildcard: boolean } => {\n // if (patternPart.startsWith(':')) return { match: true, wildcard: false }\n // const wildcardIndex = patternPart.indexOf('*')\n // if (wildcardIndex >= 0) {\n // const prefix = patternPart.slice(0, wildcardIndex)\n // return { match: prefix.length === 0 || valuePart.startsWith(prefix), wildcard: true }\n // }\n // return { match: patternPart === valuePart, wildcard: false }\n // }\n\n // for (let i = 0; i < otherParts.length; i++) {\n // const otherPart = otherParts[i]\n // const thisPart = thisParts[i]\n // const result = matchesPatternPart(otherPart, thisPart)\n // if (!result.match) return false\n // if (result.wildcard) return true\n // }\n // // Not equal (depth already ensures not equal)\n // return true\n // }\n\n // /** True when current route is broader/shallower than `other`. */\n // isAncestor(other: AnyRoute | string | undefined): boolean {\n // if (!other) return false\n // other = Route0.create(other)\n // // this is an ancestor of other if:\n // // - paths are not exactly the same\n // // - this path is a prefix of other path, matching params as wildcards\n // const getParts = (path: string) => (path === '/' ? ['/'] : path.split('/').filter(Boolean))\n // // Root is ancestor of any non-root path\n // if (this.definition === '/' && other.definition !== '/') {\n // return true\n // }\n // const thisParts = getParts(this.definition)\n // const otherParts = getParts(other.definition)\n\n // // An ancestor must be shallower\n // if (thisParts.length >= otherParts.length) return false\n\n // const matchesPatternPart = (patternPart: string, valuePart: string): { match: boolean; wildcard: boolean } => {\n // if (patternPart.startsWith(':')) return { match: true, wildcard: false }\n // const wildcardIndex = patternPart.indexOf('*')\n // if (wildcardIndex >= 0) {\n // const prefix = patternPart.slice(0, wildcardIndex)\n // return { match: prefix.length === 0 || valuePart.startsWith(prefix), wildcard: true }\n // }\n // return { match: patternPart === valuePart, wildcard: false }\n // }\n\n // for (let i = 0; i < thisParts.length; i++) {\n // const thisPart = thisParts[i]\n // const otherPart = otherParts[i]\n // const result = matchesPatternPart(thisPart, otherPart)\n // if (!result.match) return false\n // if (result.wildcard) return true\n // }\n // // Not equal (depth already ensures not equal)\n // return true\n // }\n\n /** True when two route patterns can match the same concrete URL. */\n isOverlap(other: AnyRoute | string | undefined): boolean {\n if (!other) return false\n const otherRoute = Route0.from(other) as Route0<string, UnknownSearchInput>\n const thisRegex = this.regex\n const otherRegex = otherRoute.regex\n const thisCandidates = this.routePatternCandidates\n const otherCandidates = otherRoute.routePatternCandidates\n if (thisCandidates.some((path) => otherRegex.test(path))) return true\n if (otherCandidates.some((path) => thisRegex.test(path))) return true\n return false\n }\n\n /**\n * True when overlap is not resolvable by route ordering inside one route set.\n *\n * Non-conflicting overlap means one route is a strict subset of another\n * (e.g. `/x/y` is a strict subset of `/x/:id`) and can be safely ordered first.\n */\n isConflict(other: AnyRoute | string | undefined): boolean {\n if (!other) return false\n const otherRoute = Route0.from(other) as Route0<string, UnknownSearchInput>\n if (!this.isOverlap(otherRoute)) return false\n const thisRegex = this.regex\n const otherRegex = otherRoute.regex\n const thisCandidates = this.routePatternCandidates\n const otherCandidates = otherRoute.routePatternCandidates\n const thisExclusive = thisCandidates.some((path) => thisRegex.test(path) && !otherRegex.test(path))\n const otherExclusive = otherCandidates.some((path) => otherRegex.test(path) && !thisRegex.test(path))\n // Exactly one side has exclusive matches => strict subset => resolvable by ordering.\n if (thisExclusive !== otherExclusive) return false\n // Both exclusive (partial overlap) OR none exclusive (equal languages) => real conflict.\n return true\n }\n\n /** Specificity comparator used for deterministic route ordering. */\n isMoreSpecificThan(other: AnyRoute | string | undefined): boolean {\n if (!other) return false\n other = Route0.create(other)\n const getParts = (path: string) => {\n if (path === '/') return ['/']\n return path.split('/').filter(Boolean)\n }\n const rank = (part: string): number => {\n if (part.includes('*')) return -1\n if (part.startsWith(':') && part.endsWith('?')) return 0\n if (part.startsWith(':')) return 1\n return 2\n }\n const thisParts = getParts(this.definition)\n const otherParts = getParts(other.definition)\n for (let i = 0; i < Math.min(thisParts.length, otherParts.length); i++) {\n const thisRank = rank(thisParts[i])\n const otherRank = rank(otherParts[i])\n if (thisRank > otherRank) return true\n if (thisRank < otherRank) return false\n }\n return this.definition < other.definition\n }\n}\n\n/**\n * Typed route collection with deterministic matching order.\n *\n * `Routes.create()` accepts either plain string definitions or route objects\n * and returns a \"pretty\" object with direct route access + helper methods under `._`.\n */\n\nexport class Routes<const T extends RoutesRecord = any> {\n _routes: RoutesRecordHydrated<T>\n _pathsOrdering: string[]\n _keysOrdering: string[]\n _ordered: CallableRoute[]\n\n _: {\n routes: Routes<T>['_routes']\n getLocation: Routes<T>['_getLocation']\n clone: Routes<T>['_clone']\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?: CallableRoute[]\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 this._ = {\n routes: this._routes,\n getLocation: this._getLocation.bind(this),\n clone: this._clone.bind(this),\n pathsOrdering: this._pathsOrdering,\n keysOrdering: this._keysOrdering,\n ordered: this._ordered,\n }\n }\n\n /** Creates and hydrates a typed routes collection. */\n static create<const T extends RoutesRecord>(routes: T, override?: RouteConfigInput): RoutesPretty<T> {\n const result = Routes.prettify(new Routes({ routes }))\n if (!override) {\n return result\n }\n return result._.clone(override)\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 clone: instance._clone.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.hasOwn(routes, key)) {\n const value = routes[key]\n result[key] = (typeof value === 'string' ? Route0.create(value) : value) as CallableRoute<T[typeof key]>\n }\n }\n return result\n }\n\n /**\n * Matches an input URL against collection routes.\n *\n * Returns first exact match according to precomputed ordering,\n * otherwise returns `UnknownLocation`.\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 const input = hrefOrHrefRelOrLocation\n const location = Route0.getLocation(input)\n for (const route of this._ordered) {\n if (route.isExact(location.pathname, false)) {\n const relation = route.getRelation(input)\n return Object.assign(location, {\n route: route.definition,\n params: relation.params,\n }) as ExactLocation\n }\n }\n return location as UnknownLocation\n }\n\n private static makeOrdering(routes: RoutesRecord): {\n pathsOrdering: string[]\n keysOrdering: string[]\n } {\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: overlapping routes by specificity first, otherwise by path depth and alphabetically.\n entries.sort(([_keyA, routeA], [_keyB, routeB]) => {\n const partsA = getParts(routeA.definition)\n const partsB = getParts(routeB.definition)\n\n // 1. Overlapping routes: more specific first\n if (routeA.isOverlap(routeB)) {\n if (routeA.isMoreSpecificThan(routeB)) return -1\n if (routeB.isMoreSpecificThan(routeA)) return 1\n }\n\n // 2. Different non-overlapping depth: shorter first\n if (partsA.length !== partsB.length) {\n return partsA.length - partsB.length\n }\n\n // 3. Fallback: alphabetically for deterministic ordering\n return routeA.definition.localeCompare(routeB.definition)\n })\n\n const pathsOrdering = entries.map(([_key, route]) => route.definition)\n const keysOrdering = entries.map(([_key]) => _key)\n return { pathsOrdering, keysOrdering }\n }\n\n /** Returns a cloned routes collection with config applied to each route. */\n _clone(config: RouteConfigInput): RoutesPretty<T> {\n const newRoutes = {} as RoutesRecordHydrated<T>\n for (const key in this._routes) {\n if (Object.hasOwn(this._routes, key)) {\n newRoutes[key] = this._routes[key].clone(config) as CallableRoute<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\n/** Any route instance shape, preserving literal path type when known. */\nexport type AnyRoute<\n T extends Route0<string> | string = string,\n TSearch extends UnknownSearchInput = UnknownSearchInput,\n> = T extends string ? Route0<T, TSearch> : T\n/** Callable route (`route(input)`) plus route instance methods/properties. */\nexport type CallableRoute<\n T extends Route0<string> | string = string,\n TSearch extends UnknownSearchInput = UnknownSearchInput,\n> = AnyRoute<T, TSearch> & AnyRoute<T, TSearch>['get']\n/** Route input accepted by most APIs: definition string or route object/callable. */\nexport type AnyRouteOrDefinition<T extends string = string> = AnyRoute<T> | CallableRoute<T> | T\n/** Route-level runtime configuration. */\nexport type RouteConfigInput = {\n origin?: string\n}\n\n// collection\n\n/** User-provided routes map (plain definitions or route instances). */\nexport type RoutesRecord = Record<string, AnyRoute | string>\n/** Same as `RoutesRecord` but all values normalized to callable routes. */\nexport type RoutesRecordHydrated<TRoutesRecord extends RoutesRecord = any> = {\n [K in keyof TRoutesRecord]: CallableRoute<TRoutesRecord[K]>\n}\n/** Public shape returned by `Routes.create()`. Default `any` so `satisfies RoutesPretty` accepts any created routes. */\nexport type RoutesPretty<TRoutesRecord extends RoutesRecord = any> = RoutesRecordHydrated<TRoutesRecord> &\n Omit<Routes<TRoutesRecord>, '_routes' | '_getLocation' | '_clone' | '_pathsOrdering' | '_keysOrdering' | '_ordered'>\nexport type ExtractRoutesKeys<TRoutes extends RoutesPretty | RoutesRecord> = TRoutes extends RoutesPretty\n ? Extract<keyof TRoutes['_']['routes'], string>\n : TRoutes extends RoutesRecord\n ? Extract<keyof TRoutes, string>\n : never\nexport type ExtractRoute<\n TRoutes extends RoutesPretty | RoutesRecord,\n TKey extends ExtractRoutesKeys<TRoutes>,\n> = TRoutes extends RoutesPretty ? TRoutes['_']['routes'][TKey] : TRoutes extends RoutesRecord ? 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 ParamsDefinition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['params']\n : T extends string\n ? _ParamsDefinition<T>\n : undefined\nexport type Extended<\n T extends AnyRoute | string | undefined,\n TSuffixDefinition extends string,\n TSearchInput extends UnknownSearchInput = UnknownSearchInput,\n> = T extends AnyRoute\n ? Route0<PathExtended<T['definition'], TSuffixDefinition>, TSearchInput>\n : T extends string\n ? Route0<PathExtended<T, TSuffixDefinition>, TSearchInput>\n : T extends undefined\n ? Route0<TSuffixDefinition, TSearchInput>\n : never\n\n// export type IsAncestor<T extends AnyRoute | string, TAncestor extends AnyRoute | string> = _IsAncestor<\n// Definition<T>,\n// Definition<TAncestor>\n// >\n// export type IsDescendant<T extends AnyRoute | string, TDescendant extends AnyRoute | string> = _IsDescendant<\n// Definition<T>,\n// Definition<TDescendant>\n// >\n// export type IsSame<T extends AnyRoute | string, TExact extends AnyRoute | string> = _IsSame<\n// Definition<T>,\n// Definition<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> = keyof _ParamsDefinition<Definition<T>> extends never ? false : true\nexport type HasWildcard<T extends AnyRoute | string> = Definition<T> extends `${string}*${string}` ? true : false\nexport type HasRequiredParams<T extends AnyRoute | string> =\n _RequiredParamKeys<Definition<T>> extends never ? false : true\n\nexport type ParamsOutput<T extends AnyRoute | string> = {\n [K in keyof ParamsDefinition<T>]: ParamsDefinition<T>[K] extends true ? string : string | undefined\n}\nexport type ParamsInput<T extends AnyRoute | string = string> = _ParamsInput<Definition<T>>\nexport type IsParamsOptional<T extends AnyRoute | string> = HasRequiredParams<Definition<T>> extends true ? false : true\nexport type ParamsInputStringOnly<T extends AnyRoute | string = string> = _ParamsInputStringOnly<Definition<T>>\n\n// location\n\nexport type LocationParams<TDefinition extends string> = {\n [K in keyof _ParamsDefinition<TDefinition>]: _ParamsDefinition<TDefinition>[K] extends true\n ? string\n : string | undefined\n}\n\n/**\n * URL location primitives independent from route-matching state.\n *\n * `hrefRel` is relative href and includes `pathname + search + hash`.\n */\nexport type _GeneralLocation = {\n /**\n * Path without search/hash (normalized for trailing slash).\n *\n * Example:\n * - input: `https://example.com/users/42?tab=posts#section`\n * - pathname: `/users/42`\n */\n pathname: string\n /**\n * Parsed query object.\n *\n * Example:\n * - `{ tab: \"posts\", sort: \"desc\" }`\n */\n search: UnknownSearchParsed\n /**\n * Raw query string with leading `?`, if present, else empty string.\n *\n * Example:\n * - `?tab=posts&sort=desc`\n */\n searchString: string\n /**\n * Raw hash with leading `#`, if present, else empty string.\n *\n * Example:\n * - `#section`\n */\n hash: string\n /**\n * URL origin for absolute inputs.\n *\n * Example:\n * - href: `https://example.com/users/42`\n * - origin: `https://example.com`\n */\n origin: string | undefined\n /**\n * Full absolute href for absolute inputs.\n *\n * Example:\n * - `https://example.com/users/42?tab=posts#section`\n */\n href: string | undefined\n /**\n * Relative href (`pathname + search + hash`).\n *\n * Example:\n * - pathname: `/users/42`\n * - search: `?tab=posts`\n * - hash: `#section`\n * - hrefRel: `/users/42?tab=posts#section`\n */\n hrefRel: string\n /**\n * Whether input was absolute URL.\n *\n * Examples:\n * - `https://example.com/users/42` -> `true`\n * - `/users/42` -> `false`\n */\n abs: boolean\n port: string | undefined\n host: string | undefined\n hostname: string | undefined\n}\n/** Location state before matching against a concrete route. */\nexport type UnknownLocationState = {\n route: undefined\n params: undefined\n}\nexport type UnknownLocation = _GeneralLocation & UnknownLocationState\n\n/** Exact match state for a known route. */\nexport type ExactLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: Definition<TRoute>\n params: ParamsOutput<TRoute>\n}\nexport type ExactLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n ExactLocationState<TRoute>\n\nexport type ExactRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {\n type: 'exact'\n route: Definition<TRoute>\n params: ParamsOutput<TRoute>\n exact: true\n ascendant: false\n descendant: false\n unmatched: false\n}\nexport type AscendantRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {\n type: 'ascendant'\n route: Definition<TRoute>\n params: ParamsOutput<TRoute> & { [key: string]: string | undefined }\n exact: false\n ascendant: true\n descendant: false\n unmatched: false\n}\nexport type DescendantRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {\n type: 'descendant'\n route: Definition<TRoute>\n params: Partial<ParamsOutput<TRoute>>\n exact: false\n ascendant: false\n descendant: true\n unmatched: false\n}\nexport type UnmatchedRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {\n type: 'unmatched'\n route: Definition<TRoute>\n params: Record<never, never>\n exact: false\n ascendant: false\n descendant: false\n unmatched: true\n}\nexport type RouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> =\n | ExactRouteRelation<TRoute>\n | AscendantRouteRelation<TRoute>\n | DescendantRouteRelation<TRoute>\n | UnmatchedRouteRelation<TRoute>\n\nexport type UnknownSearchParsedValue = string | UnknownSearchParsed | Array<UnknownSearchParsedValue>\nexport interface UnknownSearchParsed {\n [key: string]: UnknownSearchParsedValue\n}\n\nexport type UnknownSearchInput = Record<string, unknown>\n\n/** Input URL is a descendant of route definition (route is ancestor). */\nexport type AncestorLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: string\n params: IsAny<TRoute> extends true ? any : ParamsOutput<TRoute> & { [key: string]: string | undefined }\n}\nexport type AncestorLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n AncestorLocationState<TRoute>\n\n/** It is when route not match at all, but params match. */\nexport type WeakAncestorLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: string\n params: IsAny<TRoute> extends true ? any : ParamsOutput<TRoute> & { [key: string]: string | undefined }\n}\nexport type WeakAncestorLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n WeakAncestorLocationState<TRoute>\n\n/** Input URL is an ancestor prefix of route definition (route is descendant). */\nexport type DescendantLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: string\n params: Partial<ParamsOutput<TRoute>>\n}\nexport type DescendantLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n DescendantLocationState<TRoute>\n\n/** It is when route not match at all, but params partially match. */\nexport type WeakDescendantLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: string\n params: Partial<ParamsOutput<TRoute>>\n}\nexport type WeakDescendantLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n WeakDescendantLocationState<TRoute>\nexport type KnownLocation<TRoute extends AnyRoute | string = AnyRoute | string> =\n | ExactLocation<TRoute>\n | AncestorLocation<TRoute>\n | WeakAncestorLocation<TRoute>\n | DescendantLocation<TRoute>\n | WeakDescendantLocation<TRoute>\nexport type AnyLocation<TRoute extends AnyRoute | string = AnyRoute | string> = UnknownLocation | KnownLocation<TRoute>\n\n// internal utils\n\nexport type _ParamsDefinition<TDefinition extends string> = _ExtractParamsDefinitionBySegments<\n _SplitPathSegments<Definition<TDefinition>>\n>\n\nexport type _Simplify<T> = { [K in keyof T]: T[K] } & {}\nexport type _IfNoKeys<T extends object, TYes, TNo> = keyof T extends never ? TYes : TNo\n\nexport type _ParamsInput<TDefinition extends string> =\n _ParamsDefinition<TDefinition> extends infer TDef extends Record<string, boolean>\n ? _IfNoKeys<\n TDef,\n Record<never, never>,\n _Simplify<\n {\n [K in keyof TDef as TDef[K] extends true ? K : never]: string | number\n } & {\n [K in keyof TDef as TDef[K] extends false ? K : never]?: string | number | undefined\n }\n >\n >\n : Record<never, never>\n\nexport type _ParamsInputStringOnly<TDefinition extends string> =\n _ParamsDefinition<TDefinition> extends infer TDef extends Record<string, boolean>\n ? _IfNoKeys<\n TDef,\n Record<never, never>,\n _Simplify<\n {\n [K in keyof TDef as TDef[K] extends true ? K : never]: string\n } & {\n [K in keyof TDef as TDef[K] extends false ? K : never]?: string | undefined\n }\n >\n >\n : Record<never, never>\n\nexport type _SplitPathSegments<TPath extends string> = TPath extends ''\n ? []\n : TPath extends '/'\n ? []\n : TPath extends `/${infer Rest}`\n ? _SplitPathSegments<Rest>\n : TPath extends `${infer Segment}/${infer Rest}`\n ? Segment extends ''\n ? _SplitPathSegments<Rest>\n : [Segment, ..._SplitPathSegments<Rest>]\n : TPath extends ''\n ? []\n : [TPath]\n\nexport type _ParamDefinitionFromSegment<TSegment extends string> = TSegment extends `:${infer Name}?`\n ? { [K in Name]: false }\n : TSegment extends `:${infer Name}`\n ? { [K in Name]: true }\n : TSegment extends `${string}*?`\n ? { '*': false }\n : TSegment extends `${string}*`\n ? { '*': true }\n : Record<never, never>\n\nexport type _MergeParamDefinitions<A extends Record<string, boolean>, B extends Record<string, boolean>> = {\n [K in keyof A | keyof B]: K extends keyof B ? B[K] : K extends keyof A ? A[K] : never\n}\n\nexport type _ExtractParamsDefinitionBySegments<TSegments extends string[]> = TSegments extends [\n infer Segment extends string,\n ...infer Rest extends string[],\n]\n ? _MergeParamDefinitions<_ParamDefinitionFromSegment<Segment>, _ExtractParamsDefinitionBySegments<Rest>>\n : Record<never, never>\n\nexport type _RequiredParamKeys<TDefinition extends string> = {\n [K in keyof _ParamsDefinition<TDefinition>]: _ParamsDefinition<TDefinition>[K] extends true ? K : never\n}[keyof _ParamsDefinition<TDefinition>]\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 EnsureLeadingSlash<S extends string> = S extends '' ? '/' : S extends `/${string}` ? S : `/${S}`\nexport type TrimTrailingSlash<S extends string> = S extends '/'\n ? '/'\n : S extends `${infer V}/`\n ? TrimTrailingSlash<V>\n : S\nexport type NormalizeRouteDefinition<S extends string> = TrimTrailingSlash<EnsureLeadingSlash<DedupeSlashes<S>>>\nexport type EmptyRecord = Record<never, never>\nexport type JoinPath<Parent extends string, Suffix extends string> = NormalizeRouteDefinition<\n Definition<Parent> extends infer A extends string\n ? Definition<Suffix> extends infer B extends string\n ? NormalizeRouteDefinition<A> extends infer ANormalized extends string\n ? NormalizeRouteDefinition<B> extends infer BNormalized extends string\n ? BNormalized extends '/'\n ? ANormalized\n : ANormalized extends '/'\n ? BNormalized\n : `${ANormalized}/${BNormalized}`\n : never\n : never\n : never\n : never\n>\nexport type PathExtended<\n TSourceDefinitionDefinition extends string,\n TSuffixDefinitionDefinition extends string,\n> = `${NormalizeRouteDefinition<JoinPath<StripTrailingWildcard<TSourceDefinitionDefinition>, TSuffixDefinitionDefinition>>}`\n\nexport type StripTrailingWildcard<TDefinition extends string> = TDefinition extends `${infer TPath}*?`\n ? NormalizeRouteDefinition<TPath>\n : TDefinition extends `${infer TPath}*`\n ? NormalizeRouteDefinition<TPath>\n : NormalizeRouteDefinition<TDefinition>\n\nexport type OnlyIfNoParams<TRoute extends AnyRoute | string, Yes, No = never> =\n HasParams<TRoute> extends false ? Yes : No\nexport type OnlyIfHasParams<TRoute extends AnyRoute | string, Yes, No = never> =\n HasParams<TRoute> extends true ? Yes : No\n\nexport type GetPathInput<\n TDefinition extends string,\n TSearchInput extends UnknownSearchInput,\n> = _ParamsInput<TDefinition> & {\n '?'?: TSearchInput\n '#'?: string | number\n}\nexport type GetPathInputByRoute<TRoute extends AnyRoute | CallableRoute | string> =\n TRoute extends AnyRoute<any, infer TSearchInput>\n ? GetPathInput<Definition<TRoute>, TSearchInput>\n : TRoute extends string\n ? GetPathInput<TRoute, UnknownSearchInput>\n : never\n\nexport type IsAny<T> = 0 extends 1 & T ? true : false\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\n// export type _IsAncestor<T extends string, TAncestor extends string> = T extends TAncestor\n// ? false\n// : T extends `${TAncestor}${string}`\n// ? true\n// : false\n// export type _IsDescendant<T extends string, TDescendant extends string> = TDescendant extends T\n// ? false\n// : TDescendant extends `${T}${string}`\n// ? true\n// : false\n// export type _IsSame<T extends string, TExact extends string> = T extends TExact\n// ? TExact extends T\n// ? true\n// : false\n// : false\n\nexport type _SafeParseInputResult<TInputParsed extends Record<string, unknown>> =\n | {\n success: true\n data: TInputParsed\n error: undefined\n }\n | {\n success: false\n data: undefined\n error: Error\n }\n\nexport type SchemaRoute0<\n TInput extends Record<string, unknown>,\n TOutput extends Record<string, unknown>,\n> = StandardSchemaV1<TInput, TOutput> & {\n parse: (input: unknown) => TOutput\n safeParse: (input: unknown) => _SafeParseInputResult<TOutput>\n}\n"],"mappings":"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","names":["searchInput","hashInput","paramsInput","absOriginInput"]}
1
+ {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["import type { StandardSchemaV1 } from '@standard-schema/spec'\nimport { parse as parseSearchQuery, stringify as stringifySearchQuery } from '@devp0nt/flat0'\n\nexport type RouteToken =\n | { kind: 'static'; value: string }\n | { kind: 'param'; name: string; optional: boolean }\n | { kind: 'wildcard'; prefix: string; optional: boolean }\n\nconst escapeRegex = (value: string): string => value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n\nconst collapseDuplicateSlashes = (value: string): string => value.replace(/\\/{2,}/g, '/')\n\n/**\n * Strongly typed route descriptor and URL builder.\n *\n * A route definition uses:\n * - path params: `/users/:id`\n * - named search keys: `/users&tab&sort`\n * - loose search mode: trailing `&`, e.g. `/users&`\n *\n * Instances are callable (same as `.get()`), so `route(input)` and\n * `route.get(input)` are equivalent.\n */\nexport class Route0<TDefinition extends string, TSearchInput extends UnknownSearchInput = UnknownSearchInput> {\n readonly definition: TDefinition\n readonly params: _ParamsDefinition<TDefinition>\n private _origin: string | undefined\n private _callable: CallableRoute<TDefinition, TSearchInput>\n private _routeSegments?: string[]\n private _routeTokens?: RouteToken[]\n private _routePatternCandidates?: string[]\n private _pathParamsDefinition?: Record<string, boolean>\n private _definitionWithoutTrailingWildcard?: string\n private _routeRegexBaseStringRaw?: string\n private _regexBaseString?: string\n private _regexString?: string\n private _regex?: RegExp\n private _regexAncestor?: RegExp\n private _regexDescendantMatchers?: Array<{ regex: RegExp; captureKeys: string[] }>\n private _captureKeys?: string[]\n private _normalizedDefinition?: string\n private _definitionParts?: string[]\n\n static normalizeSlash = (value: string): string => {\n const collapsed = collapseDuplicateSlashes(value)\n if (collapsed === '' || collapsed === '/') return '/'\n const withLeadingSlash = collapsed.startsWith('/') ? collapsed : `/${collapsed}`\n return withLeadingSlash.length > 1 && withLeadingSlash.endsWith('/')\n ? withLeadingSlash.slice(0, -1)\n : withLeadingSlash\n }\n\n private static _getRouteSegments(definition: string): string[] {\n if (definition === '' || definition === '/') return []\n return definition.split('/').filter(Boolean)\n }\n\n private static _validateRouteDefinition(definition: string): void {\n const segments = Route0._getRouteSegments(definition)\n const wildcardSegments = segments.filter((segment) => segment.includes('*'))\n if (wildcardSegments.length === 0) return\n if (wildcardSegments.length > 1) {\n throw new Error(`Invalid route definition \"${definition}\": only one wildcard segment is allowed`)\n }\n const wildcardSegmentIndex = segments.findIndex((segment) => segment.includes('*'))\n const wildcardSegment = segments[wildcardSegmentIndex]\n if (!wildcardSegment.match(/^(?:\\*|\\*\\?|[^*]+\\*|\\S+\\*\\?)$/)) {\n throw new Error(`Invalid route definition \"${definition}\": wildcard must be trailing in its segment`)\n }\n if (wildcardSegmentIndex !== segments.length - 1) {\n throw new Error(`Invalid route definition \"${definition}\": wildcard segment is allowed only at the end`)\n }\n }\n\n Infer: {\n ParamsDefinition: _ParamsDefinition<TDefinition>\n ParamsInput: _ParamsInput<TDefinition>\n ParamsInputStringOnly: _ParamsInputStringOnly<TDefinition>\n ParamsOutput: ParamsOutput<TDefinition>\n SearchInput: TSearchInput\n } = null as never\n\n /** Base URL used when generating absolute URLs (`abs: true`). */\n get origin(): string {\n if (!this._origin) {\n throw new Error(\n 'origin for route ' +\n this.definition +\n ' is not set, please provide it like Route0.create(route, {origin: \"https://example.com\"}) in config or set via clones like routes._.clone({origin: \"https://example.com\"})',\n )\n }\n return this._origin\n }\n set origin(origin: string) {\n this._origin = origin\n }\n\n private constructor(definition: TDefinition, config: RouteConfigInput = {}) {\n const normalizedDefinition = Route0.normalizeSlash(definition) as TDefinition\n Route0._validateRouteDefinition(normalizedDefinition)\n this.definition = normalizedDefinition\n this.params = this.pathParamsDefinition as _ParamsDefinition<TDefinition>\n\n const { origin } = config\n if (origin && typeof origin === 'string' && origin.length) {\n this._origin = origin\n } else {\n const g = globalThis as unknown as { location?: { origin?: string } } | undefined\n if (typeof g?.location?.origin === 'string' && g.location.origin.length > 0) {\n this._origin = g.location.origin\n } else {\n this._origin = undefined\n }\n }\n const callable = this.get.bind(this)\n Object.setPrototypeOf(callable, this)\n Object.defineProperty(callable, Symbol.toStringTag, {\n value: this.definition,\n })\n this._callable = callable as CallableRoute<TDefinition, TSearchInput>\n }\n\n /**\n * Creates a callable route instance.\n *\n * If an existing route/callable route is provided, it is cloned.\n */\n static create<TDefinition extends string>(\n definition: TDefinition | AnyRoute<TDefinition> | CallableRoute<TDefinition>,\n config?: RouteConfigInput,\n ): CallableRoute<NormalizeRouteDefinition<TDefinition>> {\n if (typeof definition === 'function' || typeof definition === 'object') {\n return definition.clone(config) as CallableRoute<NormalizeRouteDefinition<TDefinition>>\n }\n const original = new Route0<NormalizeRouteDefinition<TDefinition>>(\n Route0.normalizeSlash(definition) as NormalizeRouteDefinition<TDefinition>,\n config,\n )\n return original._callable as CallableRoute<NormalizeRouteDefinition<TDefinition>>\n }\n\n /**\n * Normalizes a definition/route into a callable route.\n *\n * Unlike `create`, passing a callable route returns the same instance.\n */\n static from<TDefinition extends string, TSearchInput extends UnknownSearchInput>(\n definition: TDefinition | AnyRoute<TDefinition, TSearchInput> | CallableRoute<TDefinition, TSearchInput>,\n ): CallableRoute<NormalizeRouteDefinition<TDefinition>, TSearchInput> {\n if (typeof definition === 'function') {\n return definition as CallableRoute<NormalizeRouteDefinition<TDefinition>, TSearchInput>\n }\n const original =\n typeof definition === 'object'\n ? definition\n : new Route0<NormalizeRouteDefinition<TDefinition>>(\n Route0.normalizeSlash(definition) as NormalizeRouteDefinition<TDefinition>,\n )\n return original._callable as CallableRoute<NormalizeRouteDefinition<TDefinition>, TSearchInput>\n }\n\n private static _getAbsPath(origin: string, url: string) {\n return new URL(url, origin).toString().replace(/\\/$/, '')\n }\n\n search<TNewSearchInput extends UnknownSearchInput>(): CallableRoute<TDefinition, TNewSearchInput> {\n return this._callable as CallableRoute<TDefinition, TNewSearchInput>\n }\n\n /** Extends the current route definition by appending a suffix route. */\n extend<TSuffixDefinition extends string>(\n suffixDefinition: TSuffixDefinition,\n ): CallableRoute<PathExtended<TDefinition, TSuffixDefinition>, TSearchInput> {\n const definition = Route0.normalizeSlash(`${this.definitionWithoutTrailingWildcard}/${suffixDefinition}`)\n return Route0.create<PathExtended<TDefinition, TSuffixDefinition>>(\n definition as PathExtended<TDefinition, TSuffixDefinition>,\n {\n origin: this._origin,\n },\n ) as CallableRoute<PathExtended<TDefinition, TSuffixDefinition>, TSearchInput>\n }\n\n get(...args: IsParamsOptional<TDefinition> extends true ? [abs: boolean | string | undefined] : never): string\n get(\n ...args: IsParamsOptional<TDefinition> extends true\n ? [input?: GetPathInput<TDefinition, TSearchInput> | undefined, abs?: boolean | string | undefined]\n : [input: GetPathInput<TDefinition, TSearchInput>, abs?: boolean | string | undefined]\n ): string\n\n // implementation\n get(...args: unknown[]): string {\n const { searchInput, paramsInput, absInput, absOriginInput, hashInput } = ((): {\n searchInput: Record<string, unknown>\n paramsInput: Record<string, string | undefined>\n absInput: boolean\n absOriginInput: string | undefined\n hashInput: string | undefined\n } => {\n if (args.length === 0) {\n return {\n searchInput: {},\n paramsInput: {},\n absInput: false,\n absOriginInput: undefined,\n hashInput: undefined,\n }\n }\n const [input, abs] = ((): [Record<string, unknown>, boolean | string | undefined] => {\n if (typeof args[0] === 'object' && args[0] !== null) {\n return [args[0], args[1]] as [Record<string, unknown>, boolean | string | undefined]\n }\n if (typeof args[1] === 'object' && args[1] !== null) {\n return [args[1], args[0]] as [Record<string, unknown>, boolean | string | undefined]\n }\n if (typeof args[0] === 'boolean' || typeof args[0] === 'string') {\n return [{}, args[0]]\n }\n if (typeof args[1] === 'boolean' || typeof args[1] === 'string') {\n return [{}, args[1]]\n }\n return [{}, undefined]\n })()\n let searchInput: Record<string, unknown> = {}\n let hashInput: string | undefined = undefined\n const paramsInput: Record<string, string | undefined> = {}\n for (const [key, value] of Object.entries(input)) {\n if (key === '?' && typeof value === 'object' && value !== null) {\n searchInput = value as Record<string, unknown>\n } else if (key === '#' && (typeof value === 'string' || typeof value === 'number')) {\n hashInput = String(value)\n } else if (key in this.params && (typeof value === 'string' || typeof value === 'number')) {\n Object.assign(paramsInput, { [key]: String(value) })\n }\n }\n const absOriginInput = typeof abs === 'string' && abs.length > 0 ? abs : undefined\n return {\n searchInput,\n paramsInput,\n absInput: absOriginInput !== undefined || abs === true,\n absOriginInput,\n hashInput,\n }\n })()\n\n // create url\n\n let url = this.definition as string\n // optional named params like /:id?\n url = url.replace(/\\/:([A-Za-z0-9_]+)\\?/g, (_m, k) => {\n const value = paramsInput[k]\n if (value === undefined) return ''\n return `/${encodeURIComponent(String(value))}`\n })\n // required named 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] ?? 'undefined')))\n // optional wildcard segment (/*?)\n url = url.replace(/\\/\\*\\?/g, () => {\n const value = paramsInput['*']\n if (value === undefined) return ''\n const stringValue = String(value)\n return stringValue.startsWith('/') ? stringValue : `/${stringValue}`\n })\n // required wildcard segment (/*)\n url = url.replace(/\\/\\*/g, () => {\n const value = String(paramsInput['*'] ?? '')\n return value.startsWith('/') ? value : `/${value}`\n })\n // optional wildcard inline (e.g. /app*?)\n url = url.replace(/\\*\\?/g, () => String(paramsInput['*'] ?? ''))\n // required wildcard inline (e.g. /app*)\n url = url.replace(/\\*/g, () => String(paramsInput['*'] ?? ''))\n // search params\n const searchString = stringifySearchQuery(searchInput, { arrayIndexes: false })\n url = [url, searchString].filter(Boolean).join('?')\n // dedupe slashes\n url = collapseDuplicateSlashes(url)\n // absolute\n url = absInput ? Route0._getAbsPath(absOriginInput || this.origin, url) : url\n // hash\n if (hashInput !== undefined) {\n url = `${url}#${hashInput}`\n }\n\n return url\n }\n\n /** Returns path param keys extracted from route definition. */\n getParamsKeys(): string[] {\n return Object.keys(this.params)\n }\n\n getTokens(): RouteToken[] {\n return this.routeTokens.map((token): RouteToken => ({ ...token }))\n }\n\n /** Clones route with optional config override. */\n clone(config?: RouteConfigInput): CallableRoute<TDefinition> {\n return Route0.create(this.definition, config) as CallableRoute<TDefinition>\n }\n\n get regexBaseString(): string {\n if (this._regexBaseString === undefined) {\n this._regexBaseString = this.routeRegexBaseStringRaw.replace(/\\/+$/, '') + '/?' // remove trailing slashes and add optional slash\n }\n return this._regexBaseString\n }\n\n get regexString(): string {\n if (this._regexString === undefined) {\n this._regexString = `^${this.regexBaseString}$`\n }\n return this._regexString\n }\n\n get regex(): RegExp {\n if (this._regex === undefined) {\n this._regex = new RegExp(this.regexString)\n }\n return this._regex\n }\n\n get regexAncestor(): RegExp {\n if (this._regexAncestor === undefined) {\n this._regexAncestor = new RegExp(`^${this.regexBaseString}(?:/.*)?$`)\n }\n return this._regexAncestor\n }\n\n private get regexDescendantMatchers(): Array<{ regex: RegExp; captureKeys: string[] }> {\n if (this._regexDescendantMatchers === undefined) {\n const matchers: Array<{ regex: RegExp; captureKeys: string[] }> = []\n if (this.definitionParts[0] !== '/') {\n let pattern = ''\n const captureKeys: string[] = []\n for (const part of this.definitionParts) {\n if (part.startsWith(':')) {\n pattern += '/([^/]+)'\n captureKeys.push(part.replace(/^:/, '').replace(/\\?$/, ''))\n } else if (part.includes('*')) {\n const prefix = part.replace(/\\*\\??$/, '')\n pattern += `/${escapeRegex(prefix)}[^/]*`\n captureKeys.push('*')\n } else {\n pattern += `/${escapeRegex(part)}`\n }\n matchers.push({\n regex: new RegExp(`^${pattern}/?$`),\n captureKeys: [...captureKeys],\n })\n }\n }\n this._regexDescendantMatchers = matchers\n }\n return this._regexDescendantMatchers\n }\n\n private get captureKeys(): string[] {\n if (this._captureKeys === undefined) {\n this._captureKeys = this.routeTokens\n .filter((token): token is Extract<RouteToken, { kind: 'param' | 'wildcard' }> => token.kind !== 'static')\n .map((token) => (token.kind === 'param' ? token.name : '*'))\n }\n return this._captureKeys\n }\n\n private get routeSegments(): string[] {\n if (this._routeSegments === undefined) {\n this._routeSegments = Route0._getRouteSegments(this.definition)\n }\n return this._routeSegments\n }\n\n private get routeTokens(): RouteToken[] {\n if (this._routeTokens === undefined) {\n this._routeTokens = this.routeSegments.map((segment): RouteToken => {\n const param = segment.match(/^:([A-Za-z0-9_]+)(\\?)?$/)\n if (param) {\n return { kind: 'param', name: param[1], optional: param[2] === '?' }\n }\n if (segment === '*' || segment === '*?') {\n return { kind: 'wildcard', prefix: '', optional: segment.endsWith('?') }\n }\n const wildcard = segment.match(/^(.*)\\*(\\?)?$/)\n if (wildcard && !segment.includes('\\\\*')) {\n return { kind: 'wildcard', prefix: wildcard[1], optional: wildcard[2] === '?' }\n }\n return { kind: 'static', value: segment }\n })\n }\n return this._routeTokens\n }\n\n private get routePatternCandidates(): string[] {\n if (this._routePatternCandidates === undefined) {\n const values = (token: RouteToken): string[] => {\n if (token.kind === 'static') return [token.value]\n if (token.kind === 'param') return token.optional ? ['', 'x', 'y'] : ['x', 'y']\n if (token.prefix.length > 0)\n return [token.prefix, `${token.prefix}-x`, `${token.prefix}/x`, `${token.prefix}/y/z`]\n return ['', 'x', 'y', 'x/y']\n }\n let acc: string[] = ['']\n for (const token of this.routeTokens) {\n const next: string[] = []\n for (const base of acc) {\n for (const value of values(token)) {\n if (value === '') {\n next.push(base)\n } else if (value.startsWith('/')) {\n next.push(`${base}${value}`)\n } else {\n next.push(`${base}/${value}`)\n }\n }\n }\n // Keep candidate space bounded for large route definitions.\n acc = next.length > 512 ? next.slice(0, 512) : next\n }\n this._routePatternCandidates =\n acc.length === 0 ? ['/'] : Array.from(new Set(acc.map((x) => (x === '' ? '/' : collapseDuplicateSlashes(x)))))\n }\n return this._routePatternCandidates\n }\n\n private get pathParamsDefinition(): Record<string, boolean> {\n if (this._pathParamsDefinition === undefined) {\n const entries = this.routeTokens\n .filter((t) => t.kind !== 'static')\n .map((t): [string, boolean] => (t.kind === 'param' ? [t.name, !t.optional] : ['*', !t.optional]))\n this._pathParamsDefinition = Object.fromEntries(entries)\n }\n return this._pathParamsDefinition\n }\n\n private get definitionWithoutTrailingWildcard(): string {\n if (this._definitionWithoutTrailingWildcard === undefined) {\n this._definitionWithoutTrailingWildcard = this.definition.replace(/\\*\\??$/, '')\n }\n return this._definitionWithoutTrailingWildcard\n }\n\n private get routeRegexBaseStringRaw(): string {\n if (this._routeRegexBaseStringRaw === undefined) {\n if (this.routeTokens.length === 0) {\n this._routeRegexBaseStringRaw = ''\n } else {\n let pattern = ''\n for (const token of this.routeTokens) {\n if (token.kind === 'static') {\n pattern += `/${escapeRegex(token.value)}`\n continue\n }\n if (token.kind === 'param') {\n pattern += token.optional ? '(?:/([^/]+))?' : '/([^/]+)'\n continue\n }\n if (token.prefix.length > 0) {\n pattern += `/${escapeRegex(token.prefix)}(.*)`\n } else {\n // Wouter-compatible splat: /orders/* matches /orders and /orders/...\n pattern += '(?:/(.*))?'\n }\n }\n this._routeRegexBaseStringRaw = pattern\n }\n }\n return this._routeRegexBaseStringRaw\n }\n\n private get normalizedDefinition(): string {\n if (this._normalizedDefinition === undefined) {\n this._normalizedDefinition =\n this.definition.length > 1 && this.definition.endsWith('/') ? this.definition.slice(0, -1) : this.definition\n }\n return this._normalizedDefinition\n }\n\n private get definitionParts(): string[] {\n if (this._definitionParts === undefined) {\n this._definitionParts =\n this.normalizedDefinition === '/' ? ['/'] : this.normalizedDefinition.split('/').filter(Boolean)\n }\n return this._definitionParts\n }\n\n /** Fast pathname exact match check without building a full relation object. */\n isExact(pathname: string, normalize = true): boolean {\n const normalizedPathname = normalize ? Route0.normalizeSlash(pathname) : pathname\n return this.regex.test(normalizedPathname)\n }\n\n /** Fast pathname exact or ancestor match check without building a full relation object. */\n isExactOrAncestor(pathname: string, normalize = true): boolean {\n const normalizedPathname = normalize ? Route0.normalizeSlash(pathname) : pathname\n return this.regex.test(normalizedPathname) || this.regexAncestor.test(normalizedPathname)\n }\n\n /** True when route is ancestor of pathname (pathname is deeper). */\n isAncestor(pathname: string, normalize = true): boolean {\n const normalizedPathname = normalize ? Route0.normalizeSlash(pathname) : pathname\n return !this.regex.test(normalizedPathname) && this.regexAncestor.test(normalizedPathname)\n }\n\n /** True when route is descendant of pathname (pathname is shallower). */\n isDescendant(pathname: string, normalize = true): boolean {\n const normalizedPathname = normalize ? Route0.normalizeSlash(pathname) : pathname\n if (this.regex.test(normalizedPathname) || this.regexAncestor.test(normalizedPathname)) {\n return false\n }\n for (const matcher of this.regexDescendantMatchers) {\n if (normalizedPathname.match(matcher.regex)) {\n return true\n }\n }\n return false\n }\n\n /** Creates a grouped regex pattern string from many routes. */\n static getRegexStringGroup(routes: AnyRoute[]): string {\n const patterns = routes.map((route) => route.regexString).join('|')\n return `(${patterns})`\n }\n\n /** Creates a grouped regex from many routes. */\n static getRegexGroup(routes: AnyRoute[]): RegExp {\n const patterns = Route0.getRegexStringGroup(routes)\n return new RegExp(`^(${patterns})$`)\n }\n\n /** Converts any location shape to relative form (removes host/origin fields). */\n static toRelLocation<TLocation extends AnyLocation>(location: TLocation): TLocation {\n return {\n ...location,\n abs: false,\n origin: undefined,\n href: undefined,\n port: undefined,\n host: undefined,\n hostname: undefined,\n }\n }\n\n /** Converts a location to absolute form using provided origin URL. */\n static toAbsLocation<TLocation extends AnyLocation>(location: TLocation, origin: string): TLocation {\n const relLoc = Route0.toRelLocation(location)\n const url = new URL(relLoc.hrefRel, origin)\n return {\n ...location,\n abs: true,\n origin: url.origin,\n href: url.href,\n port: url.port,\n host: url.host,\n hostname: url.hostname,\n }\n }\n\n /**\n * Parses a URL-like input into raw location object (without route knowledge).\n *\n * Result is always `UnknownLocation` because no route matching is applied.\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 // Common derived values\n const hrefRel = url.pathname + url.search + url.hash\n\n // Build the location object consistent with _GeneralLocation\n let _search: UnknownSearchParsed | undefined\n const location: UnknownLocation = {\n pathname: url.pathname,\n get search() {\n if (_search === undefined) {\n _search = parseSearchQuery(url.search)\n }\n return _search\n },\n searchString: 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 params: undefined,\n route: undefined,\n }\n\n return location\n }\n\n // /**\n // * Parses input and returns location only for exact route matches.\n // */\n // getLocation(href: `${string}://${string}`): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(hrefRel: `/${string}`): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(hrefOrHrefRel: string): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(location: AnyLocation): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(url: AnyLocation): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): ExactLocation<TDefinition> | UnknownLocation\n // getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): ExactLocation<TDefinition> | UnknownLocation {\n // const relation = this.getRelation(hrefOrHrefRelOrLocation)\n // if (!relation.exact) {\n // return Route0.getLocation(hrefOrHrefRelOrLocation)\n // }\n // const location = Route0.getLocation(hrefOrHrefRelOrLocation)\n // return {\n // ...location,\n // route: this.definition as Definition<TDefinition>,\n // params: relation.params as ParamsOutput<TDefinition>,\n // }\n // }\n\n /**\n * Parses input and evaluates pathname relation to this route.\n */\n getRelation(href: `${string}://${string}`): RouteRelation<TDefinition>\n getRelation(hrefRel: `/${string}`): RouteRelation<TDefinition>\n getRelation(hrefOrHrefRel: string): RouteRelation<TDefinition>\n getRelation(location: AnyLocation): RouteRelation<TDefinition>\n getRelation(url: URL): RouteRelation<TDefinition>\n getRelation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): RouteRelation<TDefinition>\n getRelation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): RouteRelation<TDefinition> {\n if (hrefOrHrefRelOrLocation instanceof URL) {\n return this.getRelation(hrefOrHrefRelOrLocation.href)\n }\n if (typeof hrefOrHrefRelOrLocation !== 'string') {\n hrefOrHrefRelOrLocation = hrefOrHrefRelOrLocation.href || hrefOrHrefRelOrLocation.hrefRel\n }\n // Normalize pathname (no trailing slash except root)\n const pathname = Route0.normalizeSlash(new URL(hrefOrHrefRelOrLocation, 'http://example.com').pathname)\n\n const paramNames = this.captureKeys\n const exactRe = this.regex\n const exactMatch = pathname.match(exactRe)\n\n if (exactMatch) {\n const values = exactMatch.slice(1, 1 + paramNames.length)\n const params = Object.fromEntries(\n paramNames.map((n, i) => {\n const value = values[i] as string | undefined\n return [n, value === undefined ? undefined : decodeURIComponent(value)]\n }),\n )\n return {\n type: 'exact',\n route: this.definition as Definition<TDefinition>,\n params: params as ParamsOutput<TDefinition>,\n exact: true,\n ancestor: false,\n descendant: false,\n unmatched: false,\n }\n }\n\n const ancestorRe = this.regexAncestor\n const ancestorMatch = pathname.match(ancestorRe)\n if (ancestorMatch) {\n const values = ancestorMatch.slice(1, 1 + paramNames.length)\n const params = Object.fromEntries(\n paramNames.map((n, i) => {\n const value = values[i] as string | undefined\n return [n, value === undefined ? undefined : decodeURIComponent(value)]\n }),\n )\n return {\n type: 'ancestor',\n route: this.definition as Definition<TDefinition>,\n params: params as ParamsOutput<TDefinition> & { [key: string]: string | undefined },\n exact: false,\n ancestor: true,\n descendant: false,\n unmatched: false,\n }\n }\n\n let descendantMatch: RegExpMatchArray | null = null\n let descendantCaptureKeys: string[] = []\n for (const matcher of this.regexDescendantMatchers) {\n const match = pathname.match(matcher.regex)\n if (!match) continue\n descendantMatch = match\n descendantCaptureKeys = matcher.captureKeys\n break\n }\n\n if (descendantMatch) {\n const values = descendantMatch.slice(1, 1 + descendantCaptureKeys.length)\n const params = Object.fromEntries(\n descendantCaptureKeys.map((key, index) => [key, decodeURIComponent(values[index] as string)]),\n )\n return {\n type: 'descendant',\n route: this.definition as Definition<TDefinition>,\n params: params as Partial<ParamsOutput<TDefinition>>,\n exact: false,\n ancestor: false,\n descendant: true,\n unmatched: false,\n }\n }\n\n return {\n type: 'unmatched',\n route: this.definition as Definition<TDefinition>,\n params: {},\n exact: false,\n ancestor: false,\n descendant: false,\n unmatched: true,\n }\n }\n\n private _validateParamsInput(input: unknown): StandardSchemaV1.Result<ParamsOutput<TDefinition>> {\n const paramsEntries = Object.entries(this.params) as Array<[string, boolean]>\n const paramsMap = this.params as Record<string, boolean>\n const requiredParamsKeys = paramsEntries.filter(([, required]) => required).map(([k]) => k)\n const paramsKeys = paramsEntries.map(([k]) => k)\n if (input === undefined) {\n if (requiredParamsKeys.length) {\n return {\n issues: [\n {\n message: `Missing params: ${requiredParamsKeys.map((k) => `\"${k}\"`).join(', ')}`,\n },\n ],\n }\n }\n input = {}\n }\n if (typeof input !== 'object' || input === null) {\n return {\n issues: [{ message: 'Invalid route params: expected object' }],\n }\n }\n const inputObj = input as Record<string, unknown>\n const inputKeys = Object.keys(inputObj)\n const notDefinedKeys = requiredParamsKeys.filter((k) => !inputKeys.includes(k))\n if (notDefinedKeys.length) {\n return {\n issues: [\n {\n message: `Missing params: ${notDefinedKeys.map((k) => `\"${k}\"`).join(', ')}`,\n },\n ],\n }\n }\n const data: Record<string, string | undefined> = {}\n for (const k of paramsKeys) {\n const v = inputObj[k]\n const required = paramsMap[k]\n if (v === undefined && !required) {\n data[k] = undefined as never\n } else if (typeof v === 'string') {\n data[k] = v\n } else if (typeof v === 'number') {\n data[k] = String(v)\n } else {\n return {\n issues: [{ message: `Invalid route params: expected string, number, got ${typeof v} for \"${k}\"` }],\n }\n }\n }\n return {\n value: data as ParamsOutput<TDefinition>,\n }\n }\n\n private _safeParseSchemaResult<TOutput extends Record<string, unknown>>(\n result: StandardSchemaV1.Result<TOutput>,\n ): _SafeParseInputResult<TOutput> {\n if ('issues' in result) {\n return {\n success: false,\n data: undefined,\n error: new Error(result.issues?.[0]?.message ?? 'Invalid input'),\n }\n }\n return {\n success: true,\n data: result.value,\n error: undefined,\n }\n }\n\n private _parseSchemaResult<TOutput extends Record<string, unknown>>(\n result: StandardSchemaV1.Result<TOutput>,\n ): TOutput {\n const safeResult = this._safeParseSchemaResult(result)\n if (safeResult.error) {\n throw safeResult.error\n }\n return safeResult.data\n }\n\n /** Standard Schema for route params input. */\n readonly schema: SchemaRoute0<ParamsInput<TDefinition>, ParamsOutput<TDefinition>> = {\n '~standard': {\n version: 1,\n vendor: 'route0',\n validate: (value) => this._validateParamsInput(value),\n types: undefined as unknown as StandardSchemaV1.Types<ParamsInput<TDefinition>, ParamsOutput<TDefinition>>,\n },\n parse: (value) => this._parseSchemaResult(this._validateParamsInput(value)),\n safeParse: (value) => this._safeParseSchemaResult(this._validateParamsInput(value)),\n }\n\n // /** True when path structure is equal (param names are ignored). */\n // isSame(other: AnyRoute): boolean {\n // const thisShape = this.routeTokens\n // .map((t) => {\n // if (t.kind === 'static') return `s:${t.value}`\n // if (t.kind === 'param') return `p:${t.optional ? 'o' : 'r'}`\n // return `w:${t.prefix}:${t.optional ? 'o' : 'r'}`\n // })\n // .join('/')\n // const otherRoute = Route0.from(other) as Route0<string, UnknownSearchInput>\n // const otherShape = otherRoute.routeTokens\n // .map((t) => {\n // if (t.kind === 'static') return `s:${t.value}`\n // if (t.kind === 'param') return `p:${t.optional ? 'o' : 'r'}`\n // return `w:${t.prefix}:${t.optional ? 'o' : 'r'}`\n // })\n // .join('/')\n // return thisShape === otherShape\n // }\n // /** Static convenience wrapper for `isSame`. */\n // static isSame(a: AnyRoute | string | undefined, b: AnyRoute | string | undefined): boolean {\n // if (!a) {\n // if (!b) return true\n // return false\n // }\n // if (!b) {\n // return false\n // }\n // return Route0.create(a).isSame(Route0.create(b))\n // }\n\n // /** True when current route is more specific/deeper than `other`. */\n // isDescendant(other: AnyRoute | string | undefined): boolean {\n // if (!other) return false\n // other = Route0.create(other)\n // // this is a descendant of other if:\n // // - paths are not exactly the same\n // // - other's path is a prefix of this path, matching params as wildcards\n // const getParts = (path: string) => (path === '/' ? ['/'] : path.split('/').filter(Boolean))\n // // Root is ancestor of any non-root; thus any non-root is a descendant of root\n // if (other.definition === '/' && this.definition !== '/') {\n // return true\n // }\n // const thisParts = getParts(this.definition)\n // const otherParts = getParts(other.definition)\n\n // // A descendant must be deeper\n // if (thisParts.length <= otherParts.length) return false\n\n // const matchesPatternPart = (patternPart: string, valuePart: string): { match: boolean; wildcard: boolean } => {\n // if (patternPart.startsWith(':')) return { match: true, wildcard: false }\n // const wildcardIndex = patternPart.indexOf('*')\n // if (wildcardIndex >= 0) {\n // const prefix = patternPart.slice(0, wildcardIndex)\n // return { match: prefix.length === 0 || valuePart.startsWith(prefix), wildcard: true }\n // }\n // return { match: patternPart === valuePart, wildcard: false }\n // }\n\n // for (let i = 0; i < otherParts.length; i++) {\n // const otherPart = otherParts[i]\n // const thisPart = thisParts[i]\n // const result = matchesPatternPart(otherPart, thisPart)\n // if (!result.match) return false\n // if (result.wildcard) return true\n // }\n // // Not equal (depth already ensures not equal)\n // return true\n // }\n\n // /** True when current route is broader/shallower than `other`. */\n // isAncestor(other: AnyRoute | string | undefined): boolean {\n // if (!other) return false\n // other = Route0.create(other)\n // // this is an ancestor of other if:\n // // - paths are not exactly the same\n // // - this path is a prefix of other path, matching params as wildcards\n // const getParts = (path: string) => (path === '/' ? ['/'] : path.split('/').filter(Boolean))\n // // Root is ancestor of any non-root path\n // if (this.definition === '/' && other.definition !== '/') {\n // return true\n // }\n // const thisParts = getParts(this.definition)\n // const otherParts = getParts(other.definition)\n\n // // An ancestor must be shallower\n // if (thisParts.length >= otherParts.length) return false\n\n // const matchesPatternPart = (patternPart: string, valuePart: string): { match: boolean; wildcard: boolean } => {\n // if (patternPart.startsWith(':')) return { match: true, wildcard: false }\n // const wildcardIndex = patternPart.indexOf('*')\n // if (wildcardIndex >= 0) {\n // const prefix = patternPart.slice(0, wildcardIndex)\n // return { match: prefix.length === 0 || valuePart.startsWith(prefix), wildcard: true }\n // }\n // return { match: patternPart === valuePart, wildcard: false }\n // }\n\n // for (let i = 0; i < thisParts.length; i++) {\n // const thisPart = thisParts[i]\n // const otherPart = otherParts[i]\n // const result = matchesPatternPart(thisPart, otherPart)\n // if (!result.match) return false\n // if (result.wildcard) return true\n // }\n // // Not equal (depth already ensures not equal)\n // return true\n // }\n\n /** True when two route patterns can match the same concrete URL. */\n isOverlap(other: AnyRoute | string | undefined): boolean {\n if (!other) return false\n const otherRoute = Route0.from(other) as Route0<string, UnknownSearchInput>\n const thisRegex = this.regex\n const otherRegex = otherRoute.regex\n const thisCandidates = this.routePatternCandidates\n const otherCandidates = otherRoute.routePatternCandidates\n if (thisCandidates.some((path) => otherRegex.test(path))) return true\n if (otherCandidates.some((path) => thisRegex.test(path))) return true\n return false\n }\n\n /**\n * True when overlap is not resolvable by route ordering inside one route set.\n *\n * Non-conflicting overlap means one route is a strict subset of another\n * (e.g. `/x/y` is a strict subset of `/x/:id`) and can be safely ordered first.\n */\n isConflict(other: AnyRoute | string | undefined): boolean {\n if (!other) return false\n const otherRoute = Route0.from(other) as Route0<string, UnknownSearchInput>\n if (!this.isOverlap(otherRoute)) return false\n const thisRegex = this.regex\n const otherRegex = otherRoute.regex\n const thisCandidates = this.routePatternCandidates\n const otherCandidates = otherRoute.routePatternCandidates\n const thisExclusive = thisCandidates.some((path) => thisRegex.test(path) && !otherRegex.test(path))\n const otherExclusive = otherCandidates.some((path) => otherRegex.test(path) && !thisRegex.test(path))\n // Exactly one side has exclusive matches => strict subset => resolvable by ordering.\n if (thisExclusive !== otherExclusive) return false\n // Both exclusive (partial overlap) OR none exclusive (equal languages) => real conflict.\n return true\n }\n\n /** Specificity comparator used for deterministic route ordering. */\n isMoreSpecificThan(other: AnyRoute | string | undefined): boolean {\n if (!other) return false\n other = Route0.create(other)\n const getParts = (path: string) => {\n if (path === '/') return ['/']\n return path.split('/').filter(Boolean)\n }\n const rank = (part: string): number => {\n if (part.includes('*')) return -1\n if (part.startsWith(':') && part.endsWith('?')) return 0\n if (part.startsWith(':')) return 1\n return 2\n }\n const thisParts = getParts(this.definition)\n const otherParts = getParts(other.definition)\n for (let i = 0; i < Math.min(thisParts.length, otherParts.length); i++) {\n const thisRank = rank(thisParts[i])\n const otherRank = rank(otherParts[i])\n if (thisRank > otherRank) return true\n if (thisRank < otherRank) return false\n }\n return this.definition < other.definition\n }\n}\n\n/**\n * Typed route collection with deterministic matching order.\n *\n * `Routes.create()` accepts either plain string definitions or route objects\n * and returns a \"pretty\" object with direct route access + helper methods under `._`.\n */\n\nexport class Routes<const T extends RoutesRecord = any> {\n _routes: RoutesRecordHydrated<T>\n _pathsOrdering: string[]\n _keysOrdering: string[]\n _ordered: CallableRoute[]\n\n _: {\n routes: Routes<T>['_routes']\n getLocation: Routes<T>['_getLocation']\n clone: Routes<T>['_clone']\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?: CallableRoute[]\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 this._ = {\n routes: this._routes,\n getLocation: this._getLocation.bind(this),\n clone: this._clone.bind(this),\n pathsOrdering: this._pathsOrdering,\n keysOrdering: this._keysOrdering,\n ordered: this._ordered,\n }\n }\n\n /** Creates and hydrates a typed routes collection. */\n static create<const T extends RoutesRecord>(routes: T, override?: RouteConfigInput): RoutesPretty<T> {\n const result = Routes.prettify(new Routes({ routes }))\n if (!override) {\n return result\n }\n return result._.clone(override)\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 clone: instance._clone.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.hasOwn(routes, key)) {\n const value = routes[key]\n result[key] = (typeof value === 'string' ? Route0.create(value) : value) as CallableRoute<T[typeof key]>\n }\n }\n return result\n }\n\n /**\n * Matches an input URL against collection routes.\n *\n * Returns first exact match according to precomputed ordering,\n * otherwise returns `UnknownLocation`.\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 const input = hrefOrHrefRelOrLocation\n const location = Route0.getLocation(input)\n for (const route of this._ordered) {\n if (route.isExact(location.pathname, false)) {\n const relation = route.getRelation(input)\n return Object.assign(location, {\n route: route.definition,\n params: relation.params,\n }) as ExactLocation\n }\n }\n return location as UnknownLocation\n }\n\n private static makeOrdering(routes: RoutesRecord): {\n pathsOrdering: string[]\n keysOrdering: string[]\n } {\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: overlapping routes by specificity first, otherwise by path depth and alphabetically.\n entries.sort(([_keyA, routeA], [_keyB, routeB]) => {\n const partsA = getParts(routeA.definition)\n const partsB = getParts(routeB.definition)\n\n // 1. Overlapping routes: more specific first\n if (routeA.isOverlap(routeB)) {\n if (routeA.isMoreSpecificThan(routeB)) return -1\n if (routeB.isMoreSpecificThan(routeA)) return 1\n }\n\n // 2. Different non-overlapping depth: shorter first\n if (partsA.length !== partsB.length) {\n return partsA.length - partsB.length\n }\n\n // 3. Fallback: alphabetically for deterministic ordering\n return routeA.definition.localeCompare(routeB.definition)\n })\n\n const pathsOrdering = entries.map(([_key, route]) => route.definition)\n const keysOrdering = entries.map(([_key]) => _key)\n return { pathsOrdering, keysOrdering }\n }\n\n /** Returns a cloned routes collection with config applied to each route. */\n _clone(config: RouteConfigInput): RoutesPretty<T> {\n const newRoutes = {} as RoutesRecordHydrated<T>\n for (const key in this._routes) {\n if (Object.hasOwn(this._routes, key)) {\n newRoutes[key] = this._routes[key].clone(config) as CallableRoute<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\n/** Any route instance shape, preserving literal path type when known. */\nexport type AnyRoute<\n T extends Route0<string> | string = string,\n TSearch extends UnknownSearchInput = UnknownSearchInput,\n> = T extends string ? Route0<T, TSearch> : T\n/** Callable route (`route(input)`) plus route instance methods/properties. */\nexport type CallableRoute<\n T extends Route0<string> | string = string,\n TSearch extends UnknownSearchInput = UnknownSearchInput,\n> = AnyRoute<T, TSearch> & AnyRoute<T, TSearch>['get']\n/** Route input accepted by most APIs: definition string or route object/callable. */\nexport type AnyRouteOrDefinition<T extends string = string> = AnyRoute<T> | CallableRoute<T> | T\n/** Route-level runtime configuration. */\nexport type RouteConfigInput = {\n origin?: string\n}\n\n// collection\n\n/** User-provided routes map (plain definitions or route instances). */\nexport type RoutesRecord = Record<string, AnyRoute | string>\n/** Same as `RoutesRecord` but all values normalized to callable routes. */\nexport type RoutesRecordHydrated<TRoutesRecord extends RoutesRecord = any> = {\n [K in keyof TRoutesRecord]: CallableRoute<TRoutesRecord[K]>\n}\n/** Public shape returned by `Routes.create()`. Default `any` so `satisfies RoutesPretty` accepts any created routes. */\nexport type RoutesPretty<TRoutesRecord extends RoutesRecord = any> = RoutesRecordHydrated<TRoutesRecord> &\n Omit<Routes<TRoutesRecord>, '_routes' | '_getLocation' | '_clone' | '_pathsOrdering' | '_keysOrdering' | '_ordered'>\nexport type ExtractRoutesKeys<TRoutes extends RoutesPretty | RoutesRecord> = TRoutes extends RoutesPretty\n ? Extract<keyof TRoutes['_']['routes'], string>\n : TRoutes extends RoutesRecord\n ? Extract<keyof TRoutes, string>\n : never\nexport type ExtractRoute<\n TRoutes extends RoutesPretty | RoutesRecord,\n TKey extends ExtractRoutesKeys<TRoutes>,\n> = TRoutes extends RoutesPretty ? TRoutes['_']['routes'][TKey] : TRoutes extends RoutesRecord ? 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 ParamsDefinition<T extends AnyRoute | string> = T extends AnyRoute\n ? T['params']\n : T extends string\n ? _ParamsDefinition<T>\n : undefined\nexport type Extended<\n T extends AnyRoute | string | undefined,\n TSuffixDefinition extends string,\n TSearchInput extends UnknownSearchInput = UnknownSearchInput,\n> = T extends AnyRoute\n ? Route0<PathExtended<T['definition'], TSuffixDefinition>, TSearchInput>\n : T extends string\n ? Route0<PathExtended<T, TSuffixDefinition>, TSearchInput>\n : T extends undefined\n ? Route0<TSuffixDefinition, TSearchInput>\n : never\n\n// export type IsAncestor<T extends AnyRoute | string, TAncestor extends AnyRoute | string> = _IsAncestor<\n// Definition<T>,\n// Definition<TAncestor>\n// >\n// export type IsDescendant<T extends AnyRoute | string, TDescendant extends AnyRoute | string> = _IsDescendant<\n// Definition<T>,\n// Definition<TDescendant>\n// >\n// export type IsSame<T extends AnyRoute | string, TExact extends AnyRoute | string> = _IsSame<\n// Definition<T>,\n// Definition<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> = keyof _ParamsDefinition<Definition<T>> extends never ? false : true\nexport type HasWildcard<T extends AnyRoute | string> = Definition<T> extends `${string}*${string}` ? true : false\nexport type HasRequiredParams<T extends AnyRoute | string> =\n _RequiredParamKeys<Definition<T>> extends never ? false : true\n\nexport type ParamsOutput<T extends AnyRoute | string> = {\n [K in keyof ParamsDefinition<T>]: ParamsDefinition<T>[K] extends true ? string : string | undefined\n}\nexport type ParamsInput<T extends AnyRoute | string = string> = _ParamsInput<Definition<T>>\nexport type IsParamsOptional<T extends AnyRoute | string> = HasRequiredParams<Definition<T>> extends true ? false : true\nexport type ParamsInputStringOnly<T extends AnyRoute | string = string> = _ParamsInputStringOnly<Definition<T>>\n\n// relation\n\nexport type ExactRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {\n type: 'exact'\n route: Definition<TRoute>\n params: ParamsOutput<TRoute>\n exact: true\n ancestor: false\n descendant: false\n unmatched: false\n}\nexport type AncestorRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {\n type: 'ancestor'\n route: Definition<TRoute>\n params: ParamsOutput<TRoute> & { [key: string]: string | undefined }\n exact: false\n ancestor: true\n descendant: false\n unmatched: false\n}\nexport type DescendantRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {\n type: 'descendant'\n route: Definition<TRoute>\n params: Partial<ParamsOutput<TRoute>>\n exact: false\n ancestor: false\n descendant: true\n unmatched: false\n}\nexport type UnmatchedRouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> = {\n type: 'unmatched'\n route: Definition<TRoute>\n params: Record<never, never>\n exact: false\n ancestor: false\n descendant: false\n unmatched: true\n}\nexport type RouteRelation<TRoute extends AnyRoute | string = AnyRoute | string> =\n | ExactRouteRelation<TRoute>\n | AncestorRouteRelation<TRoute>\n | DescendantRouteRelation<TRoute>\n | UnmatchedRouteRelation<TRoute>\n\n// location\n\nexport type LocationParams<TDefinition extends string> = {\n [K in keyof _ParamsDefinition<TDefinition>]: _ParamsDefinition<TDefinition>[K] extends true\n ? string\n : string | undefined\n}\n\n/**\n * URL location primitives independent from route-matching state.\n *\n * `hrefRel` is relative href and includes `pathname + search + hash`.\n */\nexport type _GeneralLocation = {\n /**\n * Path without search/hash (normalized for trailing slash).\n *\n * Example:\n * - input: `https://example.com/users/42?tab=posts#section`\n * - pathname: `/users/42`\n */\n pathname: string\n /**\n * Parsed query object.\n *\n * Example:\n * - `{ tab: \"posts\", sort: \"desc\" }`\n */\n search: UnknownSearchParsed\n /**\n * Raw query string with leading `?`, if present, else empty string.\n *\n * Example:\n * - `?tab=posts&sort=desc`\n */\n searchString: string\n /**\n * Raw hash with leading `#`, if present, else empty string.\n *\n * Example:\n * - `#section`\n */\n hash: string\n /**\n * URL origin for absolute inputs.\n *\n * Example:\n * - href: `https://example.com/users/42`\n * - origin: `https://example.com`\n */\n origin: string | undefined\n /**\n * Full absolute href for absolute inputs.\n *\n * Example:\n * - `https://example.com/users/42?tab=posts#section`\n */\n href: string | undefined\n /**\n * Relative href (`pathname + search + hash`).\n *\n * Example:\n * - pathname: `/users/42`\n * - search: `?tab=posts`\n * - hash: `#section`\n * - hrefRel: `/users/42?tab=posts#section`\n */\n hrefRel: string\n /**\n * Whether input was absolute URL.\n *\n * Examples:\n * - `https://example.com/users/42` -> `true`\n * - `/users/42` -> `false`\n */\n abs: boolean\n port: string | undefined\n host: string | undefined\n hostname: string | undefined\n}\n/** Location state before matching against a concrete route. */\nexport type UnknownLocationState = {\n route: undefined\n params: undefined\n}\nexport type UnknownLocation = _GeneralLocation & UnknownLocationState\n\n/** Exact match state for a known route. */\nexport type ExactLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: Definition<TRoute>\n params: ParamsOutput<TRoute>\n}\nexport type ExactLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n ExactLocationState<TRoute>\n\nexport type UnknownSearchParsedValue = string | UnknownSearchParsed | Array<UnknownSearchParsedValue>\nexport interface UnknownSearchParsed {\n [key: string]: UnknownSearchParsedValue\n}\n\nexport type UnknownSearchInput = Record<string, unknown>\n\n/** Input URL is a descendant of route definition (route is ancestor). */\nexport type AncestorLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: string\n params: IsAny<TRoute> extends true ? any : ParamsOutput<TRoute> & { [key: string]: string | undefined }\n}\nexport type AncestorLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n AncestorLocationState<TRoute>\n\n/** It is when route not match at all, but params match. */\nexport type WeakAncestorLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: string\n params: IsAny<TRoute> extends true ? any : ParamsOutput<TRoute> & { [key: string]: string | undefined }\n}\nexport type WeakAncestorLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n WeakAncestorLocationState<TRoute>\n\n/** Input URL is an ancestor prefix of route definition (route is descendant). */\nexport type DescendantLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: string\n params: Partial<ParamsOutput<TRoute>>\n}\nexport type DescendantLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n DescendantLocationState<TRoute>\n\n/** It is when route not match at all, but params partially match. */\nexport type WeakDescendantLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n route: string\n params: Partial<ParamsOutput<TRoute>>\n}\nexport type WeakDescendantLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n WeakDescendantLocationState<TRoute>\nexport type KnownLocation<TRoute extends AnyRoute | string = AnyRoute | string> =\n | ExactLocation<TRoute>\n | AncestorLocation<TRoute>\n | WeakAncestorLocation<TRoute>\n | DescendantLocation<TRoute>\n | WeakDescendantLocation<TRoute>\nexport type AnyLocation<TRoute extends AnyRoute | string = AnyRoute | string> = UnknownLocation | KnownLocation<TRoute>\n\n// internal utils\n\nexport type _ParamsDefinition<TDefinition extends string> = _ExtractParamsDefinitionBySegments<\n _SplitPathSegments<Definition<TDefinition>>\n>\n\nexport type _Simplify<T> = { [K in keyof T]: T[K] } & {}\nexport type _IfNoKeys<T extends object, TYes, TNo> = keyof T extends never ? TYes : TNo\n\nexport type _ParamsInput<TDefinition extends string> =\n _ParamsDefinition<TDefinition> extends infer TDef extends Record<string, boolean>\n ? _IfNoKeys<\n TDef,\n Record<never, never>,\n _Simplify<\n {\n [K in keyof TDef as TDef[K] extends true ? K : never]: string | number\n } & {\n [K in keyof TDef as TDef[K] extends false ? K : never]?: string | number | undefined\n }\n >\n >\n : Record<never, never>\n\nexport type _ParamsInputStringOnly<TDefinition extends string> =\n _ParamsDefinition<TDefinition> extends infer TDef extends Record<string, boolean>\n ? _IfNoKeys<\n TDef,\n Record<never, never>,\n _Simplify<\n {\n [K in keyof TDef as TDef[K] extends true ? K : never]: string\n } & {\n [K in keyof TDef as TDef[K] extends false ? K : never]?: string | undefined\n }\n >\n >\n : Record<never, never>\n\nexport type _SplitPathSegments<TPath extends string> = TPath extends ''\n ? []\n : TPath extends '/'\n ? []\n : TPath extends `/${infer Rest}`\n ? _SplitPathSegments<Rest>\n : TPath extends `${infer Segment}/${infer Rest}`\n ? Segment extends ''\n ? _SplitPathSegments<Rest>\n : [Segment, ..._SplitPathSegments<Rest>]\n : TPath extends ''\n ? []\n : [TPath]\n\nexport type _ParamDefinitionFromSegment<TSegment extends string> = TSegment extends `:${infer Name}?`\n ? { [K in Name]: false }\n : TSegment extends `:${infer Name}`\n ? { [K in Name]: true }\n : TSegment extends `${string}*?`\n ? { '*': false }\n : TSegment extends `${string}*`\n ? { '*': true }\n : Record<never, never>\n\nexport type _MergeParamDefinitions<A extends Record<string, boolean>, B extends Record<string, boolean>> = {\n [K in keyof A | keyof B]: K extends keyof B ? B[K] : K extends keyof A ? A[K] : never\n}\n\nexport type _ExtractParamsDefinitionBySegments<TSegments extends string[]> = TSegments extends [\n infer Segment extends string,\n ...infer Rest extends string[],\n]\n ? _MergeParamDefinitions<_ParamDefinitionFromSegment<Segment>, _ExtractParamsDefinitionBySegments<Rest>>\n : Record<never, never>\n\nexport type _RequiredParamKeys<TDefinition extends string> = {\n [K in keyof _ParamsDefinition<TDefinition>]: _ParamsDefinition<TDefinition>[K] extends true ? K : never\n}[keyof _ParamsDefinition<TDefinition>]\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 EnsureLeadingSlash<S extends string> = S extends '' ? '/' : S extends `/${string}` ? S : `/${S}`\nexport type TrimTrailingSlash<S extends string> = S extends '/'\n ? '/'\n : S extends `${infer V}/`\n ? TrimTrailingSlash<V>\n : S\nexport type NormalizeRouteDefinition<S extends string> = TrimTrailingSlash<EnsureLeadingSlash<DedupeSlashes<S>>>\nexport type EmptyRecord = Record<never, never>\nexport type JoinPath<Parent extends string, Suffix extends string> = NormalizeRouteDefinition<\n Definition<Parent> extends infer A extends string\n ? Definition<Suffix> extends infer B extends string\n ? NormalizeRouteDefinition<A> extends infer ANormalized extends string\n ? NormalizeRouteDefinition<B> extends infer BNormalized extends string\n ? BNormalized extends '/'\n ? ANormalized\n : ANormalized extends '/'\n ? BNormalized\n : `${ANormalized}/${BNormalized}`\n : never\n : never\n : never\n : never\n>\nexport type PathExtended<\n TSourceDefinitionDefinition extends string,\n TSuffixDefinitionDefinition extends string,\n> = `${NormalizeRouteDefinition<JoinPath<StripTrailingWildcard<TSourceDefinitionDefinition>, TSuffixDefinitionDefinition>>}`\n\nexport type StripTrailingWildcard<TDefinition extends string> = TDefinition extends `${infer TPath}*?`\n ? NormalizeRouteDefinition<TPath>\n : TDefinition extends `${infer TPath}*`\n ? NormalizeRouteDefinition<TPath>\n : NormalizeRouteDefinition<TDefinition>\n\nexport type OnlyIfNoParams<TRoute extends AnyRoute | string, Yes, No = never> =\n HasParams<TRoute> extends false ? Yes : No\nexport type OnlyIfHasParams<TRoute extends AnyRoute | string, Yes, No = never> =\n HasParams<TRoute> extends true ? Yes : No\n\nexport type GetPathInput<\n TDefinition extends string,\n TSearchInput extends UnknownSearchInput,\n> = _ParamsInput<TDefinition> & {\n '?'?: TSearchInput\n '#'?: string | number\n}\nexport type GetPathInputByRoute<TRoute extends AnyRoute | CallableRoute | string> =\n TRoute extends AnyRoute<any, infer TSearchInput>\n ? GetPathInput<Definition<TRoute>, TSearchInput>\n : TRoute extends string\n ? GetPathInput<TRoute, UnknownSearchInput>\n : never\n\nexport type IsAny<T> = 0 extends 1 & T ? true : false\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\n// export type _IsAncestor<T extends string, TAncestor extends string> = T extends TAncestor\n// ? false\n// : T extends `${TAncestor}${string}`\n// ? true\n// : false\n// export type _IsDescendant<T extends string, TDescendant extends string> = TDescendant extends T\n// ? false\n// : TDescendant extends `${T}${string}`\n// ? true\n// : false\n// export type _IsSame<T extends string, TExact extends string> = T extends TExact\n// ? TExact extends T\n// ? true\n// : false\n// : false\n\nexport type _SafeParseInputResult<TInputParsed extends Record<string, unknown>> =\n | {\n success: true\n data: TInputParsed\n error: undefined\n }\n | {\n success: false\n data: undefined\n error: Error\n }\n\nexport type SchemaRoute0<\n TInput extends Record<string, unknown>,\n TOutput extends Record<string, unknown>,\n> = StandardSchemaV1<TInput, TOutput> & {\n parse: (input: unknown) => TOutput\n safeParse: (input: unknown) => _SafeParseInputResult<TOutput>\n}\n"],"mappings":"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","names":["searchInput","hashInput","paramsInput","absOriginInput"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devp0nt/route0",
3
- "version": "1.0.0-next.81",
3
+ "version": "1.0.0-next.82",
4
4
  "license": "MIT",
5
5
  "author": {
6
6
  "name": "Sergei Dmitriev",