@devp0nt/route0 1.0.0-next.8 → 1.0.0-next.80
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.
- package/dist/cjs/index.cjs +918 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.d.cts +467 -91
- package/dist/esm/index.d.ts +467 -91
- package/dist/esm/index.js +856 -97
- package/dist/esm/index.js.map +1 -1
- package/package.json +42 -25
- package/dist/cjs/index.js +0 -158
- package/dist/cjs/index.js.map +0 -1
- package/src/index.test.ts +0 -206
- package/src/index.ts +0 -365
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["// TODO: use splats in param definition \"*\"\n// TODO: ? check extend for query only .extend('&x&z')\n// TODO: .create(route, {useQuery, useParams})\n// TODO: Из пас экзакт, из пасвизквери экзает, из чилдрен, из парент, из экзактОр\n// TODO: isEqual, isChildren, isParent\n// TODO: extractParams, extractQuery\n// TODO: getPathDefinition respecting definitionParamPrefix, definitionQueryPrefix\n// TODO: prepend\n// TODO: Route0.createTree({base:{self: x, children: ...})\n// TODO: overrideTree\n// TODO: .create(route, {baseUrl, useLocation})\n// TODO: ? optional path params as @\n// TODO: prependMany, extendMany, overrideMany, with types\n\n// page0\n// TODO: Сделать чисто фронтовую штуку, которая сама вызывает лоадер, сама вызывает нужные мета и title, и отдаёт в компонент нужные штуки\n\n// ssr0\n// TODO: ССР работает просто поверх любого роутера, который поддерживает асинхронную загрузку страниц\n\nexport class Route0<\n TPathOriginalDefinition extends string,\n TPathDefinition extends Route0._PathDefinition<TPathOriginalDefinition>,\n TParamsDefinition extends Route0._ParamsDefinition<TPathOriginalDefinition>,\n TQueryDefinition extends Route0._QueryDefinition<TPathOriginalDefinition>,\n> {\n pathOriginalDefinition: TPathOriginalDefinition\n private readonly pathDefinition: TPathDefinition\n paramsDefinition: TParamsDefinition\n queryDefinition: TQueryDefinition\n baseUrl: string\n\n private constructor(definition: TPathOriginalDefinition, config: Route0.RouteConfigInput = {}) {\n this.pathOriginalDefinition = definition\n this.pathDefinition = Route0._getPathDefinitionByOriginalDefinition(definition) as TPathDefinition\n this.paramsDefinition = Route0._getParamsDefinitionByRouteDefinition(definition) as TParamsDefinition\n this.queryDefinition = Route0._getQueryDefinitionByRouteDefinition(definition) as TQueryDefinition\n\n const { baseUrl } = config\n if (baseUrl && typeof baseUrl === 'string' && baseUrl.length) {\n this.baseUrl = baseUrl\n } else {\n const g = globalThis as unknown as { location?: { origin?: string } }\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (g?.location?.origin) {\n this.baseUrl = g.location.origin\n } else {\n this.baseUrl = 'https://example.com'\n }\n }\n }\n\n static create<\n TPathOriginalDefinition extends string,\n TPathDefinition extends Route0._PathDefinition<TPathOriginalDefinition>,\n TParamsDefinition extends Route0._ParamsDefinition<TPathOriginalDefinition>,\n TQueryDefinition extends Route0._QueryDefinition<TPathOriginalDefinition>,\n >(\n definition: TPathOriginalDefinition,\n config?: Route0.RouteConfigInput,\n ): Route0.Callable<Route0<TPathOriginalDefinition, TPathDefinition, TParamsDefinition, TQueryDefinition>> {\n const original = new Route0<TPathOriginalDefinition, TPathDefinition, TParamsDefinition, TQueryDefinition>(\n definition,\n config,\n )\n const callable = original.get.bind(original)\n const proxy = new Proxy(callable, {\n get(_target, prop, receiver) {\n const value = (original as any)[prop]\n if (typeof value === 'function') {\n return value.bind(original)\n }\n return value\n },\n set(_target, prop, value, receiver) {\n ;(original as any)[prop] = value\n return true\n },\n has(_target, prop) {\n return prop in original\n },\n })\n Object.setPrototypeOf(proxy, Route0.prototype)\n return proxy as never\n }\n\n private static _splitPathDefinitionAndQueryTailDefinition(pathOriginalDefinition: string) {\n const i = pathOriginalDefinition.indexOf('&')\n if (i === -1) return { pathDefinition: pathOriginalDefinition, queryTailDefinition: '' }\n return {\n pathDefinition: pathOriginalDefinition.slice(0, i),\n queryTailDefinition: pathOriginalDefinition.slice(i),\n }\n }\n\n private static _getAbsPath(baseUrl: string, pathWithQuery: string) {\n return new URL(pathWithQuery, baseUrl).toString().replace(/\\/$/, '')\n }\n\n private static _getPathDefinitionByOriginalDefinition<TPathOriginalDefinition extends string>(\n pathOriginalDefinition: TPathOriginalDefinition,\n ) {\n const { pathDefinition } = Route0._splitPathDefinitionAndQueryTailDefinition(pathOriginalDefinition)\n return pathDefinition as Route0._PathDefinition<TPathOriginalDefinition>\n }\n\n private static _getParamsDefinitionByRouteDefinition<TPathOriginalDefinition extends string>(\n pathOriginalDefinition: TPathOriginalDefinition,\n ) {\n const { pathDefinition } = Route0._splitPathDefinitionAndQueryTailDefinition(pathOriginalDefinition)\n const matches = Array.from(pathDefinition.matchAll(/:([A-Za-z0-9_]+)/g))\n const paramsDefinition = Object.fromEntries(matches.map((m) => [m[1], true]))\n return paramsDefinition as Route0._ParamsDefinition<TPathOriginalDefinition>\n }\n\n private static _getQueryDefinitionByRouteDefinition<TPathOriginalDefinition extends string>(\n pathOriginalDefinition: TPathOriginalDefinition,\n ) {\n const { queryTailDefinition } = Route0._splitPathDefinitionAndQueryTailDefinition(pathOriginalDefinition)\n if (!queryTailDefinition) {\n return {} as Route0._QueryDefinition<TPathOriginalDefinition>\n }\n const keys = queryTailDefinition.split('&').map(Boolean)\n const queryDefinition = Object.fromEntries(keys.map((k) => [k, true]))\n return queryDefinition as Route0._QueryDefinition<TPathOriginalDefinition>\n }\n\n static overrideMany<T extends Record<string, Route0<any, any, any, any>>>(\n routes: T,\n config: Route0.RouteConfigInput,\n ): T {\n const result = {} as T\n for (const [key, value] of Object.entries(routes)) {\n ;(result as any)[key] = value.clone(config)\n }\n return result\n }\n\n extend<TSuffixDefinition extends string>(\n suffixDefinition: TSuffixDefinition,\n ): Route0.Callable<\n Route0<\n Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>,\n Route0._PathDefinition<Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>>,\n Route0._ParamsDefinition<Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>>,\n Route0._QueryDefinition<Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>>\n >\n > {\n const { pathDefinition: parentPathDefinition } = Route0._splitPathDefinitionAndQueryTailDefinition(\n this.pathOriginalDefinition,\n )\n const { pathDefinition: suffixPathDefinition, queryTailDefinition: suffixQueryTailDefinition } =\n Route0._splitPathDefinitionAndQueryTailDefinition(suffixDefinition)\n const pathDefinition = `${parentPathDefinition}/${suffixPathDefinition}`.replace(/\\/{2,}/g, '/')\n const pathOriginalDefinition =\n `${pathDefinition}${suffixQueryTailDefinition}` as Route0._RoutePathOriginalDefinitionExtended<\n TPathOriginalDefinition,\n TSuffixDefinition\n >\n return Route0.create<\n Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>,\n Route0._PathDefinition<Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>>,\n Route0._ParamsDefinition<Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>>,\n Route0._QueryDefinition<Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>>\n >(pathOriginalDefinition, { baseUrl: this.baseUrl })\n }\n\n // has params\n get(\n input: Route0._OnlyIfHasParams<\n TParamsDefinition,\n Route0._WithParamsInput<TParamsDefinition, { query?: undefined; abs?: false }>\n >,\n ): Route0._OnlyIfHasParams<TParamsDefinition, Route0._PathOnlyRouteValue<TPathOriginalDefinition>>\n get(\n input: Route0._OnlyIfHasParams<\n TParamsDefinition,\n Route0._WithParamsInput<TParamsDefinition, { query: Route0._QueryInput<TQueryDefinition>; abs?: false }>\n >,\n ): Route0._OnlyIfHasParams<TParamsDefinition, Route0._WithQueryRouteValue<TPathOriginalDefinition>>\n get(\n input: Route0._OnlyIfHasParams<\n TParamsDefinition,\n Route0._WithParamsInput<TParamsDefinition, { query?: undefined; abs: true }>\n >,\n ): Route0._OnlyIfHasParams<TParamsDefinition, Route0._AbsolutePathOnlyRouteValue<TPathOriginalDefinition>>\n get(\n input: Route0._OnlyIfHasParams<\n TParamsDefinition,\n Route0._WithParamsInput<TParamsDefinition, { query: Route0._QueryInput<TQueryDefinition>; abs: true }>\n >,\n ): Route0._OnlyIfHasParams<TParamsDefinition, Route0._AbsoluteWithQueryRouteValue<TPathOriginalDefinition>>\n\n // no params\n get(\n ...args: Route0._OnlyIfNoParams<TParamsDefinition, [], [never]>\n ): Route0._PathOnlyRouteValue<TPathOriginalDefinition>\n get(\n input: Route0._OnlyIfNoParams<TParamsDefinition, { query?: undefined; abs?: false }>,\n ): Route0._OnlyIfNoParams<TParamsDefinition, Route0._PathOnlyRouteValue<TPathOriginalDefinition>>\n get(\n input: Route0._OnlyIfNoParams<TParamsDefinition, { query: Route0._QueryInput<TQueryDefinition>; abs?: false }>,\n ): Route0._OnlyIfNoParams<TParamsDefinition, Route0._WithQueryRouteValue<TPathOriginalDefinition>>\n get(\n input: Route0._OnlyIfNoParams<TParamsDefinition, { query?: undefined; abs: true }>,\n ): Route0._OnlyIfNoParams<TParamsDefinition, Route0._AbsolutePathOnlyRouteValue<TPathOriginalDefinition>>\n get(\n input: Route0._OnlyIfNoParams<TParamsDefinition, { query: Route0._QueryInput<TQueryDefinition>; abs: true }>,\n ): Route0._OnlyIfNoParams<TParamsDefinition, Route0._AbsoluteWithQueryRouteValue<TPathOriginalDefinition>>\n\n // implementation\n get(...args: any[]): string {\n const { queryInput, paramsInput, absInput } = ((): {\n queryInput: Record<string, string | number>\n paramsInput: Record<string, string | number>\n absInput: boolean\n } => {\n if (args.length === 0) {\n return { queryInput: {}, paramsInput: {}, absInput: false }\n }\n const input = args[0]\n if (typeof input !== 'object' || input === null) {\n // throw new Error(\"Invalid get route input: expected object\")\n return { queryInput: {}, paramsInput: {}, absInput: false }\n }\n const { query, abs, ...params } = input\n return { queryInput: query || {}, paramsInput: params, absInput: abs ?? false }\n })()\n\n // validate params\n const neededParamsKeys = Object.keys(this.paramsDefinition)\n const providedParamsKeys = Object.keys(paramsInput)\n const notProvidedKeys = neededParamsKeys.filter((k) => !providedParamsKeys.includes(k))\n if (notProvidedKeys.length) {\n // throw new Error(`Missing params: not defined keys ${notProvidedKeys.map((k) => `\"${k}\"`).join(\", \")}.`)\n Object.assign(paramsInput, Object.fromEntries(notProvidedKeys.map((k) => [k, 'undefined'])))\n }\n\n // create url\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-conversion\n let url = String(this.pathDefinition)\n // replace params\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n url = url.replace(/:([A-Za-z0-9_]+)/g, (_m, k) => encodeURIComponent(String(paramsInput?.[k] ?? '')))\n // query params\n const queryInputStringified = Object.fromEntries(Object.entries(queryInput).map(([k, v]) => [k, String(v)]))\n url = [url, new URLSearchParams(queryInputStringified).toString()].filter(Boolean).join('?')\n // dedupe slashes\n url = url.replace(/\\/{2,}/g, '/')\n // absolute\n url = absInput ? Route0._getAbsPath(this.baseUrl, url) : url\n\n return url\n }\n\n getDefinition() {\n return this.pathDefinition\n }\n\n clone(config?: Route0.RouteConfigInput) {\n return new Route0(this.pathOriginalDefinition, config)\n }\n}\n\nexport namespace Route0 {\n export type Callable<T extends Route0<any, any, any, any>> = T & T['get']\n export type RouteConfigInput = {\n baseUrl?: string\n }\n export type Params<TRoute0 extends Route0<any, any, any, any>> = {\n [K in keyof TRoute0['paramsDefinition']]: string\n }\n export type Query<TRoute0 extends Route0<any, any, any, any>> = Partial<\n {\n [K in keyof TRoute0['queryDefinition']]: string | undefined\n } & Record<string, string | undefined>\n >\n\n export type _TrimQueryTailDefinition<S extends string> = S extends `${infer P}&${string}` ? P : S\n export type _QueryTailDefinitionWithoutFirstAmp<S extends string> = S extends `${string}&${infer T}` ? T : ''\n export type _QueryTailDefinitionWithFirstAmp<S extends string> = S extends `${string}&${infer T}` ? `&${T}` : ''\n export type _AmpSplit<S extends string> = S extends `${infer A}&${infer B}` ? A | _AmpSplit<B> : S\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n export type _NonEmpty<T> = [T] extends ['' | never] ? never : T\n export type _ExtractPathParams<S extends string> = S extends `${string}:${infer After}`\n ? After extends `${infer Name}/${infer Rest}`\n ? Name | _ExtractPathParams<`/${Rest}`>\n : After\n : never\n export 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\n export type _DedupeSlashes<S extends string> = S extends `${infer A}//${infer B}` ? _DedupeSlashes<`${A}/${B}`> : S\n export type _EmptyRecord = Record<never, never>\n export type _JoinPath<Parent extends string, Suffix extends string> = _DedupeSlashes<\n _PathDefinition<Parent> extends infer A extends string\n ? _PathDefinition<Suffix> extends infer B extends string\n ? A extends ''\n ? B extends ''\n ? ''\n : B extends `/${string}`\n ? B\n : `/${B}`\n : B extends ''\n ? A\n : A extends `${string}/`\n ? `${A}${B}`\n : B extends `/${string}`\n ? `${A}${B}`\n : `${A}/${B}`\n : never\n : never\n >\n\n export type _OnlyIfNoParams<TParams extends object, Yes, No = never> = keyof TParams extends never ? Yes : No\n export type _OnlyIfHasParams<TParams extends object, Yes, No = never> = keyof TParams extends never ? No : Yes\n\n export type _PathDefinition<TPathOriginalDefinition extends string> =\n _TrimQueryTailDefinition<TPathOriginalDefinition>\n export type _ParamsDefinition<TPathOriginalDefinition extends string> =\n _ExtractPathParams<_PathDefinition<TPathOriginalDefinition>> extends infer U\n ? [U] extends [never]\n ? _EmptyRecord\n : { [K in Extract<U, string>]: true }\n : _EmptyRecord\n export type _QueryDefinition<TPathOriginalDefinition extends string> =\n _NonEmpty<_QueryTailDefinitionWithoutFirstAmp<TPathOriginalDefinition>> extends infer Tail extends string\n ? _AmpSplit<Tail> extends infer U\n ? [U] extends [never]\n ? _EmptyRecord\n : { [K in Extract<U, string>]: true }\n : _EmptyRecord\n : _EmptyRecord\n export type _RoutePathOriginalDefinitionExtended<\n TSourcePathOriginalDefinition extends string,\n TSuffixPathOriginalDefinition extends string,\n > = `${_JoinPath<TSourcePathOriginalDefinition, TSuffixPathOriginalDefinition>}${_QueryTailDefinitionWithFirstAmp<TSuffixPathOriginalDefinition>}`\n\n export type _ParamsInput<TParamsDefinition extends object> = {\n [K in keyof TParamsDefinition]: string | number\n }\n export type _QueryInput<TQueryDefinition extends object> = Partial<{\n [K in keyof TQueryDefinition]: string | number\n }> &\n Record<string, string | number>\n export type _WithParamsInput<\n TParamsDefinition extends object,\n T extends {\n query?: _QueryInput<any>\n abs?: boolean\n },\n > = _ParamsInput<TParamsDefinition> & T\n\n export type _PathOnlyRouteValue<TPathOriginalDefinition extends string> =\n `${_ReplacePathParams<_PathDefinition<TPathOriginalDefinition>>}`\n export type _WithQueryRouteValue<TPathOriginalDefinition extends string> =\n `${_ReplacePathParams<_PathDefinition<TPathOriginalDefinition>>}?${string}`\n export type _AbsolutePathOnlyRouteValue<TPathOriginalDefinition extends string> =\n `${string}${_PathOnlyRouteValue<TPathOriginalDefinition>}`\n export type _AbsoluteWithQueryRouteValue<TPathOriginalDefinition extends string> =\n `${string}${_WithQueryRouteValue<TPathOriginalDefinition>}`\n}\n"],"mappings":"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","names":[]}
|
|
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\nconst normalizeSlashPath = (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/**\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 private static _getRouteSegments(definition: string): string[] {\n if (definition === '' || definition === '/') return []\n return definition.split('/').filter(Boolean)\n }\n\n private static _normalizeRouteDefinition(definition: string): string {\n return normalizeSlashPath(definition)\n }\n\n private static _normalizePathname(pathname: string): string {\n return Route0._normalizeRouteDefinition(pathname)\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._normalizeRouteDefinition(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._normalizeRouteDefinition(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._normalizeRouteDefinition(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._normalizeRouteDefinition(`${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)\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 location object. */\n isExactPathnameMatch(pathname: string): boolean {\n return this.regex.test(Route0._normalizePathname(pathname))\n }\n\n /** Fast pathname exact or ancestor match check without building a full location object. */\n isExactOrAncestorPathnameMatch(pathname: string): boolean {\n const normalizedPathname = Route0._normalizePathname(pathname)\n return this.regex.test(normalizedPathname) || this.regexAncestor.test(normalizedPathname)\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 // Parse search query to object form\n const search = parseSearchQuery(url.search)\n\n // Common derived values\n const hrefRel = url.pathname + url.search + url.hash\n\n // Build the location object consistent with _GeneralLocation\n const location: UnknownLocation = {\n pathname: url.pathname,\n search,\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 known: false,\n exact: false,\n ancestor: false,\n descendant: false,\n unmatched: false,\n }\n\n return location\n }\n\n /**\n * Parses input and matches it against this route definition.\n *\n * Result includes relation flags:\n * - `exact`\n * - `ancestor`\n * - `descendant`\n * - `unmatched`\n */\n getLocation(href: `${string}://${string}`): ExactLocation<TDefinition> | UnmatchedLocation<TDefinition>\n getLocation(hrefRel: `/${string}`): ExactLocation<TDefinition> | UnmatchedLocation<TDefinition>\n getLocation(hrefOrHrefRel: string): ExactLocation<TDefinition> | UnmatchedLocation<TDefinition>\n getLocation(location: AnyLocation): ExactLocation<TDefinition> | UnmatchedLocation<TDefinition>\n getLocation(url: AnyLocation): ExactLocation<TDefinition> | UnmatchedLocation<TDefinition>\n getLocation(\n hrefOrHrefRelOrLocation: string | AnyLocation | URL,\n ): ExactLocation<TDefinition> | UnmatchedLocation<TDefinition>\n getLocation(\n hrefOrHrefRelOrLocation: string | AnyLocation | URL,\n ): ExactLocation<TDefinition> | UnmatchedLocation<TDefinition> {\n if (hrefOrHrefRelOrLocation instanceof URL) {\n return this.getLocation(hrefOrHrefRelOrLocation.href)\n }\n if (typeof hrefOrHrefRelOrLocation !== 'string') {\n hrefOrHrefRelOrLocation = hrefOrHrefRelOrLocation.href || hrefOrHrefRelOrLocation.hrefRel\n }\n const location = Route0.getLocation(hrefOrHrefRelOrLocation) as never as\n | ExactLocation<TDefinition>\n | UnmatchedLocation<TDefinition>\n location.route = this.definition as Definition<TDefinition>\n location.params = {}\n\n // Normalize pathname (no trailing slash except root)\n const pathname = Route0._normalizePathname(location.pathname)\n\n const paramNames = this.captureKeys\n const exactRe = this.regex\n const ancestorRe = this.regexAncestor // route matches the beginning of the URL (may have more)\n const exactMatch = pathname.match(exactRe)\n const ancestorMatch = pathname.match(ancestorRe)\n const exact = !!exactMatch\n const ancestor = !exact && !!ancestorMatch\n\n // Parse params for exact and ancestor matches.\n const paramsMatch = exactMatch || (ancestor ? ancestorMatch : null)\n if (paramsMatch) {\n const values = paramsMatch.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 location.params = params\n } else {\n location.params = {}\n }\n\n let descendant = false\n let descendantMatch: RegExpMatchArray | null = null\n let descendantCaptureKeys: string[] = []\n if (!exact && !ancestor) {\n for (const matcher of this.regexDescendantMatchers) {\n const match = pathname.match(matcher.regex)\n if (!match) continue\n descendant = true\n descendantMatch = match\n descendantCaptureKeys = matcher.captureKeys\n break\n }\n }\n const unmatched = !exact && !ancestor && !descendant\n\n if (descendant && descendantMatch) {\n const values = descendantMatch.slice(1, 1 + descendantCaptureKeys.length)\n location.params = Object.fromEntries(\n descendantCaptureKeys.map((key, index) => [key, decodeURIComponent(values[index] as string)]),\n )\n }\n\n return {\n ...location,\n known: true,\n exact,\n ancestor,\n descendant,\n unmatched,\n } as ExactLocation<TDefinition> | UnmatchedLocation<TDefinition>\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 private static _getNormalizedPathnameFromInput(hrefOrHrefRelOrLocation: string | AnyLocation | URL): string {\n if (hrefOrHrefRelOrLocation instanceof URL) {\n return normalizeSlashPath(hrefOrHrefRelOrLocation.pathname)\n }\n if (typeof hrefOrHrefRelOrLocation !== 'string') {\n if (typeof hrefOrHrefRelOrLocation.pathname === 'string') {\n return normalizeSlashPath(hrefOrHrefRelOrLocation.pathname)\n }\n hrefOrHrefRelOrLocation = hrefOrHrefRelOrLocation.href || hrefOrHrefRelOrLocation.hrefRel\n }\n const abs = /^[a-zA-Z][a-zA-Z\\d+\\-.]*:\\/\\//.test(hrefOrHrefRelOrLocation)\n const base = abs ? undefined : 'http://example.com'\n const url = new URL(hrefOrHrefRelOrLocation, base)\n return normalizeSlashPath(url.pathname)\n }\n\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 pathname = Routes._getNormalizedPathnameFromInput(input)\n // Find exact match using a fast pathname pre-check first.\n for (const route of this._ordered) {\n if (!route.isExactPathnameMatch(pathname)) {\n continue\n }\n const loc = route.getLocation(input)\n if (loc.exact) {\n return loc\n }\n }\n // No exact match found, return UnknownLocation\n return typeof input === 'string' ? Route0.getLocation(input) : Route0.getLocation(input)\n }\n\n private static makeOrdering(routes: RoutesRecord): {\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\nexport type IsAncestor<T extends AnyRoute | string, TAncestor extends AnyRoute | string> = _IsAncestor<\n Definition<T>,\n Definition<TAncestor>\n>\nexport type IsDescendant<T extends AnyRoute | string, TDescendant extends AnyRoute | string> = _IsDescendant<\n Definition<T>,\n Definition<TDescendant>\n>\nexport 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.\n *\n * Example:\n * - `?tab=posts&sort=desc`\n */\n searchString: string\n /**\n * Raw hash with leading `#`, if present.\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 known: false\n route: undefined\n params: undefined\n exact: false\n ancestor: false\n descendant: false\n unmatched: false\n}\nexport type UnknownLocation = _GeneralLocation & UnknownLocationState\n\n/** Known route context, but no exact/ancestor/descendant relation matched. */\nexport type UnmatchedLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n known: true\n route: Definition<TRoute>\n params: Record<never, never>\n exact: false\n ancestor: false\n descendant: false\n unmatched: true\n}\nexport type UnmatchedLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n UnmatchedLocationState<TRoute>\n\n/** Exact match state for a known route. */\nexport type ExactLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n known: true\n route: Definition<TRoute>\n params: ParamsOutput<TRoute>\n exact: true\n ancestor: false\n descendant: false\n unmatched: false\n}\nexport type ExactLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n ExactLocationState<TRoute>\n\n/** Input URL is a descendant of route definition (route is ancestor). */\nexport type AncestorLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n known: true\n route: string\n params: IsAny<TRoute> extends true ? any : ParamsOutput<TRoute> & { [key: string]: string | undefined }\n exact: false\n ancestor: true\n descendant: false\n unmatched: false\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 known: true\n route: string\n params: IsAny<TRoute> extends true ? any : ParamsOutput<TRoute> & { [key: string]: string | undefined }\n exact: false\n ancestor: true\n descendant: false\n unmatched: false\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 known: true\n route: Definition<TRoute>\n params: Partial<ParamsOutput<TRoute>>\n exact: false\n ancestor: false\n descendant: true\n unmatched: false\n}\nexport type DescendantLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n DescendantLocationState<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/** It is when route not match at all, but params partially match. */\nexport type WeakDescendantLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {\n known: true\n route: Definition<TRoute>\n params: Partial<ParamsOutput<TRoute>>\n exact: false\n ancestor: false\n descendant: true\n unmatched: false\n}\nexport type WeakDescendantLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation &\n WeakDescendantLocationState<TRoute>\nexport type KnownLocation<TRoute extends AnyRoute | string = AnyRoute | string> =\n | UnmatchedLocation<TRoute>\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\nexport type _IsAncestor<T extends string, TAncestor extends string> = T extends TAncestor\n ? false\n : T extends `${TAncestor}${string}`\n ? true\n : false\nexport type _IsDescendant<T extends string, TDescendant extends string> = TDescendant extends T\n ? false\n : TDescendant extends `${T}${string}`\n ? true\n : false\nexport type _IsSame<T extends string, TExact extends string> = T extends TExact\n ? TExact extends T\n ? true\n : false\n : false\n\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.
|
|
3
|
+
"version": "1.0.0-next.80",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Sergei Dmitriev",
|
|
@@ -15,24 +15,31 @@
|
|
|
15
15
|
"url": "https://github.com/devp0nt/route0/issues"
|
|
16
16
|
},
|
|
17
17
|
"type": "module",
|
|
18
|
-
"main": "./dist/cjs/index.js",
|
|
19
|
-
"module": "./dist/esm/index.js",
|
|
20
18
|
"types": "./dist/esm/index.d.ts",
|
|
19
|
+
"main": "./dist/cjs/index.cjs",
|
|
20
|
+
"module": "./dist/esm/index.js",
|
|
21
21
|
"exports": {
|
|
22
22
|
".": {
|
|
23
23
|
"types": "./dist/esm/index.d.ts",
|
|
24
|
-
"
|
|
25
|
-
"
|
|
24
|
+
"require": "./dist/cjs/index.cjs",
|
|
25
|
+
"import": "./dist/esm/index.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"typesVersions": {
|
|
29
|
+
"*": {
|
|
30
|
+
"": [
|
|
31
|
+
"./dist/esm/index.d.ts"
|
|
32
|
+
]
|
|
26
33
|
}
|
|
27
34
|
},
|
|
28
35
|
"files": [
|
|
29
36
|
"dist/**/*",
|
|
30
|
-
"src/**/*",
|
|
31
37
|
"README.md",
|
|
32
38
|
"LICENSE"
|
|
33
39
|
],
|
|
34
40
|
"scripts": {
|
|
35
|
-
"dev": "tsc-watch --preserveWatchOutput --project tsconfig.build.json
|
|
41
|
+
"dev": "tsc-watch --preserveWatchOutput --project tsconfig.build.json",
|
|
42
|
+
"dev:npm": "tsc-watch --preserveWatchOutput --project tsconfig.build.json --onSuccess 'bun run pack:dist'",
|
|
36
43
|
"build": "tsup",
|
|
37
44
|
"build:test:esm": "tsup --outDir dist-test/esm --tsconfig tsconfig.build.test.json --format esm src",
|
|
38
45
|
"build:test:esm:watch": "bun run build:test:esm --watch",
|
|
@@ -41,14 +48,14 @@
|
|
|
41
48
|
"build:test": "bun run build:test:esm && bun run build:test:cjs",
|
|
42
49
|
"build:test:watch": "bun run build:test:esm:watch & bun run build:test:cjs:watch",
|
|
43
50
|
"build:all": "bun run build && bun run build:test",
|
|
44
|
-
"test": "bun test src",
|
|
45
|
-
"test:us": "bun test src --update-snapshots",
|
|
51
|
+
"test": "bun test ./src",
|
|
52
|
+
"test:us": "bun test ./src --update-snapshots",
|
|
46
53
|
"test:watch": "bun test --watch",
|
|
47
|
-
"test:coverage": "bun test --coverage",
|
|
48
|
-
"test:dist:esm": "bun test dist-test/esm",
|
|
54
|
+
"test:coverage": "bun test ./src --coverage",
|
|
55
|
+
"test:dist:esm": "bun test ./dist-test/esm",
|
|
49
56
|
"test:dist:esm:watch": "bun run test:dist:esm --watch",
|
|
50
57
|
"test:dist:esm:build:watch": "bun build:test:esm:watch --no-clean & bun test:dist:esm:watch",
|
|
51
|
-
"test:dist:cjs": "bun test dist-test/cjs",
|
|
58
|
+
"test:dist:cjs": "bun test ./dist-test/cjs",
|
|
52
59
|
"test:dist:cjs:watch": "bun run test:dist:cjs --watch",
|
|
53
60
|
"test:dist:cjs:build:watch": "bun build:test:cjs:watch --no-clean & bun test:dist:cjs:watch",
|
|
54
61
|
"test:dist": "bun run test:dist:esm && bun run test:dist:cjs",
|
|
@@ -58,19 +65,21 @@
|
|
|
58
65
|
"test:all:watch": "bun run test:watch & bun run test:dist:watch",
|
|
59
66
|
"test:all:build": "bun run build:all && bun run test:all",
|
|
60
67
|
"test:all:build:watch": "bun run build:all:watch & bun run test:all:watch",
|
|
61
|
-
"lint": "bun run lint:
|
|
68
|
+
"lint": "bun run lint:fix .",
|
|
62
69
|
"lint:base": "eslint --cache --cache-location node_modules/.cache/eslint/.eslintcache",
|
|
63
|
-
"lint:fix": "bun run lint --fix",
|
|
64
|
-
"format": "bun run format:
|
|
65
|
-
"format:base": "prettier --cache --cache-location node_modules/.cache/prettier/.prettiercache --ignore-path .gitignore",
|
|
70
|
+
"lint:fix": "bun run lint:base --fix",
|
|
71
|
+
"format": "bun run format:fix .",
|
|
72
|
+
"format:base": "prettier --cache --cache-location node_modules/.cache/prettier/.prettiercache --ignore-path .gitignore --ignore-path .prettierignore",
|
|
66
73
|
"format:fix": "bun run format:base --write",
|
|
67
74
|
"types:build": "tsc --noEmit --project tsconfig.build.json",
|
|
68
75
|
"types:dev": "tsc --noEmit",
|
|
69
76
|
"types": "bun run types:dev",
|
|
77
|
+
"typesgo": "tsgo --noEmit",
|
|
70
78
|
"pack:dry": "npm pack --dry-run",
|
|
71
|
-
"pack:dist": "
|
|
72
|
-
"
|
|
73
|
-
"
|
|
79
|
+
"pack:dist": "mkdir -p dist-npm && npm pack --pack-destination dist-npm --silent && cd dist-npm && tar -xzf *.tgz && cp -r package/* . && rm -rf package && rm *.tgz",
|
|
80
|
+
"pack:dist:hard": "rimraf dist-npm && bun run pack:dist",
|
|
81
|
+
"prepare": "husky || true",
|
|
82
|
+
"clean": "rimraf dist && rimraf dist-test && rimraf dist-npm && rimraf node_modules/.cache"
|
|
74
83
|
},
|
|
75
84
|
"dependencies": {},
|
|
76
85
|
"devDependencies": {
|
|
@@ -78,22 +87,27 @@
|
|
|
78
87
|
"@commitlint/config-conventional": "^19.8.1",
|
|
79
88
|
"@semantic-release/changelog": "^6.0.3",
|
|
80
89
|
"@semantic-release/git": "^10.0.1",
|
|
81
|
-
"@semantic-release/github": "^
|
|
82
|
-
"@semantic-release/npm": "^
|
|
90
|
+
"@semantic-release/github": "^12.0.2",
|
|
91
|
+
"@semantic-release/npm": "^13.1.3",
|
|
92
|
+
"@standard-schema/spec": "^1.1.0",
|
|
83
93
|
"@types/bun": "^1.2.22",
|
|
84
94
|
"@types/node": "^20.0.0",
|
|
95
|
+
"@typescript/native-preview": "^7.0.0-dev.20260219.1",
|
|
85
96
|
"cross-env": "^10.0.0",
|
|
86
|
-
"
|
|
87
|
-
"eslint
|
|
97
|
+
"esbuild-fix-imports-plugin": "^1.0.22",
|
|
98
|
+
"eslint": "^10.0.0",
|
|
88
99
|
"eslint-config-prettier": "^10.1.8",
|
|
100
|
+
"eslint-plugin-no-only-tests": "^3.3.0",
|
|
89
101
|
"husky": "^9.1.7",
|
|
90
102
|
"lint-staged": "^16.2.1",
|
|
91
103
|
"prettier": "^3.6.2",
|
|
92
104
|
"rimraf": "^6.0.1",
|
|
93
|
-
"semantic-release": "^
|
|
105
|
+
"semantic-release": "^25.0.2",
|
|
94
106
|
"tsc-watch": "^7.1.1",
|
|
95
107
|
"tsup": "^8.0.0",
|
|
96
|
-
"typescript": "^5.0.0"
|
|
108
|
+
"typescript": "^5.0.0",
|
|
109
|
+
"typescript-eslint": "^8.56.0",
|
|
110
|
+
"@devp0nt/flat0": "^1.1.1"
|
|
97
111
|
},
|
|
98
112
|
"engines": {
|
|
99
113
|
"node": ">=18.0.0",
|
|
@@ -101,5 +115,8 @@
|
|
|
101
115
|
},
|
|
102
116
|
"publishConfig": {
|
|
103
117
|
"access": "public"
|
|
118
|
+
},
|
|
119
|
+
"peerDependencies": {
|
|
120
|
+
"@devp0nt/flat0": "^1.1.1"
|
|
104
121
|
}
|
|
105
122
|
}
|
package/dist/cjs/index.js
DELETED
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
var index_exports = {};
|
|
20
|
-
__export(index_exports, {
|
|
21
|
-
Route0: () => Route0
|
|
22
|
-
});
|
|
23
|
-
module.exports = __toCommonJS(index_exports);
|
|
24
|
-
class Route0 {
|
|
25
|
-
pathOriginalDefinition;
|
|
26
|
-
pathDefinition;
|
|
27
|
-
paramsDefinition;
|
|
28
|
-
queryDefinition;
|
|
29
|
-
baseUrl;
|
|
30
|
-
constructor(definition, config = {}) {
|
|
31
|
-
this.pathOriginalDefinition = definition;
|
|
32
|
-
this.pathDefinition = Route0._getPathDefinitionByOriginalDefinition(definition);
|
|
33
|
-
this.paramsDefinition = Route0._getParamsDefinitionByRouteDefinition(definition);
|
|
34
|
-
this.queryDefinition = Route0._getQueryDefinitionByRouteDefinition(definition);
|
|
35
|
-
const { baseUrl } = config;
|
|
36
|
-
if (baseUrl && typeof baseUrl === "string" && baseUrl.length) {
|
|
37
|
-
this.baseUrl = baseUrl;
|
|
38
|
-
} else {
|
|
39
|
-
const g = globalThis;
|
|
40
|
-
if (g?.location?.origin) {
|
|
41
|
-
this.baseUrl = g.location.origin;
|
|
42
|
-
} else {
|
|
43
|
-
this.baseUrl = "https://example.com";
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
static create(definition, config) {
|
|
48
|
-
const original = new Route0(
|
|
49
|
-
definition,
|
|
50
|
-
config
|
|
51
|
-
);
|
|
52
|
-
const callable = original.get.bind(original);
|
|
53
|
-
const proxy = new Proxy(callable, {
|
|
54
|
-
get(_target, prop, receiver) {
|
|
55
|
-
const value = original[prop];
|
|
56
|
-
if (typeof value === "function") {
|
|
57
|
-
return value.bind(original);
|
|
58
|
-
}
|
|
59
|
-
return value;
|
|
60
|
-
},
|
|
61
|
-
set(_target, prop, value, receiver) {
|
|
62
|
-
;
|
|
63
|
-
original[prop] = value;
|
|
64
|
-
return true;
|
|
65
|
-
},
|
|
66
|
-
has(_target, prop) {
|
|
67
|
-
return prop in original;
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
Object.setPrototypeOf(proxy, Route0.prototype);
|
|
71
|
-
return proxy;
|
|
72
|
-
}
|
|
73
|
-
static _splitPathDefinitionAndQueryTailDefinition(pathOriginalDefinition) {
|
|
74
|
-
const i = pathOriginalDefinition.indexOf("&");
|
|
75
|
-
if (i === -1) return { pathDefinition: pathOriginalDefinition, queryTailDefinition: "" };
|
|
76
|
-
return {
|
|
77
|
-
pathDefinition: pathOriginalDefinition.slice(0, i),
|
|
78
|
-
queryTailDefinition: pathOriginalDefinition.slice(i)
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
static _getAbsPath(baseUrl, pathWithQuery) {
|
|
82
|
-
return new URL(pathWithQuery, baseUrl).toString().replace(/\/$/, "");
|
|
83
|
-
}
|
|
84
|
-
static _getPathDefinitionByOriginalDefinition(pathOriginalDefinition) {
|
|
85
|
-
const { pathDefinition } = Route0._splitPathDefinitionAndQueryTailDefinition(pathOriginalDefinition);
|
|
86
|
-
return pathDefinition;
|
|
87
|
-
}
|
|
88
|
-
static _getParamsDefinitionByRouteDefinition(pathOriginalDefinition) {
|
|
89
|
-
const { pathDefinition } = Route0._splitPathDefinitionAndQueryTailDefinition(pathOriginalDefinition);
|
|
90
|
-
const matches = Array.from(pathDefinition.matchAll(/:([A-Za-z0-9_]+)/g));
|
|
91
|
-
const paramsDefinition = Object.fromEntries(matches.map((m) => [m[1], true]));
|
|
92
|
-
return paramsDefinition;
|
|
93
|
-
}
|
|
94
|
-
static _getQueryDefinitionByRouteDefinition(pathOriginalDefinition) {
|
|
95
|
-
const { queryTailDefinition } = Route0._splitPathDefinitionAndQueryTailDefinition(pathOriginalDefinition);
|
|
96
|
-
if (!queryTailDefinition) {
|
|
97
|
-
return {};
|
|
98
|
-
}
|
|
99
|
-
const keys = queryTailDefinition.split("&").map(Boolean);
|
|
100
|
-
const queryDefinition = Object.fromEntries(keys.map((k) => [k, true]));
|
|
101
|
-
return queryDefinition;
|
|
102
|
-
}
|
|
103
|
-
static overrideMany(routes, config) {
|
|
104
|
-
const result = {};
|
|
105
|
-
for (const [key, value] of Object.entries(routes)) {
|
|
106
|
-
;
|
|
107
|
-
result[key] = value.clone(config);
|
|
108
|
-
}
|
|
109
|
-
return result;
|
|
110
|
-
}
|
|
111
|
-
extend(suffixDefinition) {
|
|
112
|
-
const { pathDefinition: parentPathDefinition } = Route0._splitPathDefinitionAndQueryTailDefinition(
|
|
113
|
-
this.pathOriginalDefinition
|
|
114
|
-
);
|
|
115
|
-
const { pathDefinition: suffixPathDefinition, queryTailDefinition: suffixQueryTailDefinition } = Route0._splitPathDefinitionAndQueryTailDefinition(suffixDefinition);
|
|
116
|
-
const pathDefinition = `${parentPathDefinition}/${suffixPathDefinition}`.replace(/\/{2,}/g, "/");
|
|
117
|
-
const pathOriginalDefinition = `${pathDefinition}${suffixQueryTailDefinition}`;
|
|
118
|
-
return Route0.create(pathOriginalDefinition, { baseUrl: this.baseUrl });
|
|
119
|
-
}
|
|
120
|
-
// implementation
|
|
121
|
-
get(...args) {
|
|
122
|
-
const { queryInput, paramsInput, absInput } = (() => {
|
|
123
|
-
if (args.length === 0) {
|
|
124
|
-
return { queryInput: {}, paramsInput: {}, absInput: false };
|
|
125
|
-
}
|
|
126
|
-
const input = args[0];
|
|
127
|
-
if (typeof input !== "object" || input === null) {
|
|
128
|
-
return { queryInput: {}, paramsInput: {}, absInput: false };
|
|
129
|
-
}
|
|
130
|
-
const { query, abs, ...params } = input;
|
|
131
|
-
return { queryInput: query || {}, paramsInput: params, absInput: abs ?? false };
|
|
132
|
-
})();
|
|
133
|
-
const neededParamsKeys = Object.keys(this.paramsDefinition);
|
|
134
|
-
const providedParamsKeys = Object.keys(paramsInput);
|
|
135
|
-
const notProvidedKeys = neededParamsKeys.filter((k) => !providedParamsKeys.includes(k));
|
|
136
|
-
if (notProvidedKeys.length) {
|
|
137
|
-
Object.assign(paramsInput, Object.fromEntries(notProvidedKeys.map((k) => [k, "undefined"])));
|
|
138
|
-
}
|
|
139
|
-
let url = String(this.pathDefinition);
|
|
140
|
-
url = url.replace(/:([A-Za-z0-9_]+)/g, (_m, k) => encodeURIComponent(String(paramsInput?.[k] ?? "")));
|
|
141
|
-
const queryInputStringified = Object.fromEntries(Object.entries(queryInput).map(([k, v]) => [k, String(v)]));
|
|
142
|
-
url = [url, new URLSearchParams(queryInputStringified).toString()].filter(Boolean).join("?");
|
|
143
|
-
url = url.replace(/\/{2,}/g, "/");
|
|
144
|
-
url = absInput ? Route0._getAbsPath(this.baseUrl, url) : url;
|
|
145
|
-
return url;
|
|
146
|
-
}
|
|
147
|
-
getDefinition() {
|
|
148
|
-
return this.pathDefinition;
|
|
149
|
-
}
|
|
150
|
-
clone(config) {
|
|
151
|
-
return new Route0(this.pathOriginalDefinition, config);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
155
|
-
0 && (module.exports = {
|
|
156
|
-
Route0
|
|
157
|
-
});
|
|
158
|
-
//# sourceMappingURL=index.js.map
|
package/dist/cjs/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["// TODO: use splats in param definition \"*\"\n// TODO: ? check extend for query only .extend('&x&z')\n// TODO: .create(route, {useQuery, useParams})\n// TODO: Из пас экзакт, из пасвизквери экзает, из чилдрен, из парент, из экзактОр\n// TODO: isEqual, isChildren, isParent\n// TODO: extractParams, extractQuery\n// TODO: getPathDefinition respecting definitionParamPrefix, definitionQueryPrefix\n// TODO: prepend\n// TODO: Route0.createTree({base:{self: x, children: ...})\n// TODO: overrideTree\n// TODO: .create(route, {baseUrl, useLocation})\n// TODO: ? optional path params as @\n// TODO: prependMany, extendMany, overrideMany, with types\n\n// page0\n// TODO: Сделать чисто фронтовую штуку, которая сама вызывает лоадер, сама вызывает нужные мета и title, и отдаёт в компонент нужные штуки\n\n// ssr0\n// TODO: ССР работает просто поверх любого роутера, который поддерживает асинхронную загрузку страниц\n\nexport class Route0<\n TPathOriginalDefinition extends string,\n TPathDefinition extends Route0._PathDefinition<TPathOriginalDefinition>,\n TParamsDefinition extends Route0._ParamsDefinition<TPathOriginalDefinition>,\n TQueryDefinition extends Route0._QueryDefinition<TPathOriginalDefinition>,\n> {\n pathOriginalDefinition: TPathOriginalDefinition\n private readonly pathDefinition: TPathDefinition\n paramsDefinition: TParamsDefinition\n queryDefinition: TQueryDefinition\n baseUrl: string\n\n private constructor(definition: TPathOriginalDefinition, config: Route0.RouteConfigInput = {}) {\n this.pathOriginalDefinition = definition\n this.pathDefinition = Route0._getPathDefinitionByOriginalDefinition(definition) as TPathDefinition\n this.paramsDefinition = Route0._getParamsDefinitionByRouteDefinition(definition) as TParamsDefinition\n this.queryDefinition = Route0._getQueryDefinitionByRouteDefinition(definition) as TQueryDefinition\n\n const { baseUrl } = config\n if (baseUrl && typeof baseUrl === 'string' && baseUrl.length) {\n this.baseUrl = baseUrl\n } else {\n const g = globalThis as unknown as { location?: { origin?: string } }\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (g?.location?.origin) {\n this.baseUrl = g.location.origin\n } else {\n this.baseUrl = 'https://example.com'\n }\n }\n }\n\n static create<\n TPathOriginalDefinition extends string,\n TPathDefinition extends Route0._PathDefinition<TPathOriginalDefinition>,\n TParamsDefinition extends Route0._ParamsDefinition<TPathOriginalDefinition>,\n TQueryDefinition extends Route0._QueryDefinition<TPathOriginalDefinition>,\n >(\n definition: TPathOriginalDefinition,\n config?: Route0.RouteConfigInput,\n ): Route0.Callable<Route0<TPathOriginalDefinition, TPathDefinition, TParamsDefinition, TQueryDefinition>> {\n const original = new Route0<TPathOriginalDefinition, TPathDefinition, TParamsDefinition, TQueryDefinition>(\n definition,\n config,\n )\n const callable = original.get.bind(original)\n const proxy = new Proxy(callable, {\n get(_target, prop, receiver) {\n const value = (original as any)[prop]\n if (typeof value === 'function') {\n return value.bind(original)\n }\n return value\n },\n set(_target, prop, value, receiver) {\n ;(original as any)[prop] = value\n return true\n },\n has(_target, prop) {\n return prop in original\n },\n })\n Object.setPrototypeOf(proxy, Route0.prototype)\n return proxy as never\n }\n\n private static _splitPathDefinitionAndQueryTailDefinition(pathOriginalDefinition: string) {\n const i = pathOriginalDefinition.indexOf('&')\n if (i === -1) return { pathDefinition: pathOriginalDefinition, queryTailDefinition: '' }\n return {\n pathDefinition: pathOriginalDefinition.slice(0, i),\n queryTailDefinition: pathOriginalDefinition.slice(i),\n }\n }\n\n private static _getAbsPath(baseUrl: string, pathWithQuery: string) {\n return new URL(pathWithQuery, baseUrl).toString().replace(/\\/$/, '')\n }\n\n private static _getPathDefinitionByOriginalDefinition<TPathOriginalDefinition extends string>(\n pathOriginalDefinition: TPathOriginalDefinition,\n ) {\n const { pathDefinition } = Route0._splitPathDefinitionAndQueryTailDefinition(pathOriginalDefinition)\n return pathDefinition as Route0._PathDefinition<TPathOriginalDefinition>\n }\n\n private static _getParamsDefinitionByRouteDefinition<TPathOriginalDefinition extends string>(\n pathOriginalDefinition: TPathOriginalDefinition,\n ) {\n const { pathDefinition } = Route0._splitPathDefinitionAndQueryTailDefinition(pathOriginalDefinition)\n const matches = Array.from(pathDefinition.matchAll(/:([A-Za-z0-9_]+)/g))\n const paramsDefinition = Object.fromEntries(matches.map((m) => [m[1], true]))\n return paramsDefinition as Route0._ParamsDefinition<TPathOriginalDefinition>\n }\n\n private static _getQueryDefinitionByRouteDefinition<TPathOriginalDefinition extends string>(\n pathOriginalDefinition: TPathOriginalDefinition,\n ) {\n const { queryTailDefinition } = Route0._splitPathDefinitionAndQueryTailDefinition(pathOriginalDefinition)\n if (!queryTailDefinition) {\n return {} as Route0._QueryDefinition<TPathOriginalDefinition>\n }\n const keys = queryTailDefinition.split('&').map(Boolean)\n const queryDefinition = Object.fromEntries(keys.map((k) => [k, true]))\n return queryDefinition as Route0._QueryDefinition<TPathOriginalDefinition>\n }\n\n static overrideMany<T extends Record<string, Route0<any, any, any, any>>>(\n routes: T,\n config: Route0.RouteConfigInput,\n ): T {\n const result = {} as T\n for (const [key, value] of Object.entries(routes)) {\n ;(result as any)[key] = value.clone(config)\n }\n return result\n }\n\n extend<TSuffixDefinition extends string>(\n suffixDefinition: TSuffixDefinition,\n ): Route0.Callable<\n Route0<\n Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>,\n Route0._PathDefinition<Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>>,\n Route0._ParamsDefinition<Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>>,\n Route0._QueryDefinition<Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>>\n >\n > {\n const { pathDefinition: parentPathDefinition } = Route0._splitPathDefinitionAndQueryTailDefinition(\n this.pathOriginalDefinition,\n )\n const { pathDefinition: suffixPathDefinition, queryTailDefinition: suffixQueryTailDefinition } =\n Route0._splitPathDefinitionAndQueryTailDefinition(suffixDefinition)\n const pathDefinition = `${parentPathDefinition}/${suffixPathDefinition}`.replace(/\\/{2,}/g, '/')\n const pathOriginalDefinition =\n `${pathDefinition}${suffixQueryTailDefinition}` as Route0._RoutePathOriginalDefinitionExtended<\n TPathOriginalDefinition,\n TSuffixDefinition\n >\n return Route0.create<\n Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>,\n Route0._PathDefinition<Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>>,\n Route0._ParamsDefinition<Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>>,\n Route0._QueryDefinition<Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>>\n >(pathOriginalDefinition, { baseUrl: this.baseUrl })\n }\n\n // has params\n get(\n input: Route0._OnlyIfHasParams<\n TParamsDefinition,\n Route0._WithParamsInput<TParamsDefinition, { query?: undefined; abs?: false }>\n >,\n ): Route0._OnlyIfHasParams<TParamsDefinition, Route0._PathOnlyRouteValue<TPathOriginalDefinition>>\n get(\n input: Route0._OnlyIfHasParams<\n TParamsDefinition,\n Route0._WithParamsInput<TParamsDefinition, { query: Route0._QueryInput<TQueryDefinition>; abs?: false }>\n >,\n ): Route0._OnlyIfHasParams<TParamsDefinition, Route0._WithQueryRouteValue<TPathOriginalDefinition>>\n get(\n input: Route0._OnlyIfHasParams<\n TParamsDefinition,\n Route0._WithParamsInput<TParamsDefinition, { query?: undefined; abs: true }>\n >,\n ): Route0._OnlyIfHasParams<TParamsDefinition, Route0._AbsolutePathOnlyRouteValue<TPathOriginalDefinition>>\n get(\n input: Route0._OnlyIfHasParams<\n TParamsDefinition,\n Route0._WithParamsInput<TParamsDefinition, { query: Route0._QueryInput<TQueryDefinition>; abs: true }>\n >,\n ): Route0._OnlyIfHasParams<TParamsDefinition, Route0._AbsoluteWithQueryRouteValue<TPathOriginalDefinition>>\n\n // no params\n get(\n ...args: Route0._OnlyIfNoParams<TParamsDefinition, [], [never]>\n ): Route0._PathOnlyRouteValue<TPathOriginalDefinition>\n get(\n input: Route0._OnlyIfNoParams<TParamsDefinition, { query?: undefined; abs?: false }>,\n ): Route0._OnlyIfNoParams<TParamsDefinition, Route0._PathOnlyRouteValue<TPathOriginalDefinition>>\n get(\n input: Route0._OnlyIfNoParams<TParamsDefinition, { query: Route0._QueryInput<TQueryDefinition>; abs?: false }>,\n ): Route0._OnlyIfNoParams<TParamsDefinition, Route0._WithQueryRouteValue<TPathOriginalDefinition>>\n get(\n input: Route0._OnlyIfNoParams<TParamsDefinition, { query?: undefined; abs: true }>,\n ): Route0._OnlyIfNoParams<TParamsDefinition, Route0._AbsolutePathOnlyRouteValue<TPathOriginalDefinition>>\n get(\n input: Route0._OnlyIfNoParams<TParamsDefinition, { query: Route0._QueryInput<TQueryDefinition>; abs: true }>,\n ): Route0._OnlyIfNoParams<TParamsDefinition, Route0._AbsoluteWithQueryRouteValue<TPathOriginalDefinition>>\n\n // implementation\n get(...args: any[]): string {\n const { queryInput, paramsInput, absInput } = ((): {\n queryInput: Record<string, string | number>\n paramsInput: Record<string, string | number>\n absInput: boolean\n } => {\n if (args.length === 0) {\n return { queryInput: {}, paramsInput: {}, absInput: false }\n }\n const input = args[0]\n if (typeof input !== 'object' || input === null) {\n // throw new Error(\"Invalid get route input: expected object\")\n return { queryInput: {}, paramsInput: {}, absInput: false }\n }\n const { query, abs, ...params } = input\n return { queryInput: query || {}, paramsInput: params, absInput: abs ?? false }\n })()\n\n // validate params\n const neededParamsKeys = Object.keys(this.paramsDefinition)\n const providedParamsKeys = Object.keys(paramsInput)\n const notProvidedKeys = neededParamsKeys.filter((k) => !providedParamsKeys.includes(k))\n if (notProvidedKeys.length) {\n // throw new Error(`Missing params: not defined keys ${notProvidedKeys.map((k) => `\"${k}\"`).join(\", \")}.`)\n Object.assign(paramsInput, Object.fromEntries(notProvidedKeys.map((k) => [k, 'undefined'])))\n }\n\n // create url\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-conversion\n let url = String(this.pathDefinition)\n // replace params\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n url = url.replace(/:([A-Za-z0-9_]+)/g, (_m, k) => encodeURIComponent(String(paramsInput?.[k] ?? '')))\n // query params\n const queryInputStringified = Object.fromEntries(Object.entries(queryInput).map(([k, v]) => [k, String(v)]))\n url = [url, new URLSearchParams(queryInputStringified).toString()].filter(Boolean).join('?')\n // dedupe slashes\n url = url.replace(/\\/{2,}/g, '/')\n // absolute\n url = absInput ? Route0._getAbsPath(this.baseUrl, url) : url\n\n return url\n }\n\n getDefinition() {\n return this.pathDefinition\n }\n\n clone(config?: Route0.RouteConfigInput) {\n return new Route0(this.pathOriginalDefinition, config)\n }\n}\n\nexport namespace Route0 {\n export type Callable<T extends Route0<any, any, any, any>> = T & T['get']\n export type RouteConfigInput = {\n baseUrl?: string\n }\n export type Params<TRoute0 extends Route0<any, any, any, any>> = {\n [K in keyof TRoute0['paramsDefinition']]: string\n }\n export type Query<TRoute0 extends Route0<any, any, any, any>> = Partial<\n {\n [K in keyof TRoute0['queryDefinition']]: string | undefined\n } & Record<string, string | undefined>\n >\n\n export type _TrimQueryTailDefinition<S extends string> = S extends `${infer P}&${string}` ? P : S\n export type _QueryTailDefinitionWithoutFirstAmp<S extends string> = S extends `${string}&${infer T}` ? T : ''\n export type _QueryTailDefinitionWithFirstAmp<S extends string> = S extends `${string}&${infer T}` ? `&${T}` : ''\n export type _AmpSplit<S extends string> = S extends `${infer A}&${infer B}` ? A | _AmpSplit<B> : S\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n export type _NonEmpty<T> = [T] extends ['' | never] ? never : T\n export type _ExtractPathParams<S extends string> = S extends `${string}:${infer After}`\n ? After extends `${infer Name}/${infer Rest}`\n ? Name | _ExtractPathParams<`/${Rest}`>\n : After\n : never\n export 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\n export type _DedupeSlashes<S extends string> = S extends `${infer A}//${infer B}` ? _DedupeSlashes<`${A}/${B}`> : S\n export type _EmptyRecord = Record<never, never>\n export type _JoinPath<Parent extends string, Suffix extends string> = _DedupeSlashes<\n _PathDefinition<Parent> extends infer A extends string\n ? _PathDefinition<Suffix> extends infer B extends string\n ? A extends ''\n ? B extends ''\n ? ''\n : B extends `/${string}`\n ? B\n : `/${B}`\n : B extends ''\n ? A\n : A extends `${string}/`\n ? `${A}${B}`\n : B extends `/${string}`\n ? `${A}${B}`\n : `${A}/${B}`\n : never\n : never\n >\n\n export type _OnlyIfNoParams<TParams extends object, Yes, No = never> = keyof TParams extends never ? Yes : No\n export type _OnlyIfHasParams<TParams extends object, Yes, No = never> = keyof TParams extends never ? No : Yes\n\n export type _PathDefinition<TPathOriginalDefinition extends string> =\n _TrimQueryTailDefinition<TPathOriginalDefinition>\n export type _ParamsDefinition<TPathOriginalDefinition extends string> =\n _ExtractPathParams<_PathDefinition<TPathOriginalDefinition>> extends infer U\n ? [U] extends [never]\n ? _EmptyRecord\n : { [K in Extract<U, string>]: true }\n : _EmptyRecord\n export type _QueryDefinition<TPathOriginalDefinition extends string> =\n _NonEmpty<_QueryTailDefinitionWithoutFirstAmp<TPathOriginalDefinition>> extends infer Tail extends string\n ? _AmpSplit<Tail> extends infer U\n ? [U] extends [never]\n ? _EmptyRecord\n : { [K in Extract<U, string>]: true }\n : _EmptyRecord\n : _EmptyRecord\n export type _RoutePathOriginalDefinitionExtended<\n TSourcePathOriginalDefinition extends string,\n TSuffixPathOriginalDefinition extends string,\n > = `${_JoinPath<TSourcePathOriginalDefinition, TSuffixPathOriginalDefinition>}${_QueryTailDefinitionWithFirstAmp<TSuffixPathOriginalDefinition>}`\n\n export type _ParamsInput<TParamsDefinition extends object> = {\n [K in keyof TParamsDefinition]: string | number\n }\n export type _QueryInput<TQueryDefinition extends object> = Partial<{\n [K in keyof TQueryDefinition]: string | number\n }> &\n Record<string, string | number>\n export type _WithParamsInput<\n TParamsDefinition extends object,\n T extends {\n query?: _QueryInput<any>\n abs?: boolean\n },\n > = _ParamsInput<TParamsDefinition> & T\n\n export type _PathOnlyRouteValue<TPathOriginalDefinition extends string> =\n `${_ReplacePathParams<_PathDefinition<TPathOriginalDefinition>>}`\n export type _WithQueryRouteValue<TPathOriginalDefinition extends string> =\n `${_ReplacePathParams<_PathDefinition<TPathOriginalDefinition>>}?${string}`\n export type _AbsolutePathOnlyRouteValue<TPathOriginalDefinition extends string> =\n `${string}${_PathOnlyRouteValue<TPathOriginalDefinition>}`\n export type _AbsoluteWithQueryRouteValue<TPathOriginalDefinition extends string> =\n `${string}${_WithQueryRouteValue<TPathOriginalDefinition>}`\n}\n"],"mappings":"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","names":[]}
|