@devp0nt/route0 1.0.0-next.7 → 1.0.0-next.71

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.
@@ -1,99 +1,447 @@
1
- declare class Route0<TPathOriginalDefinition extends string, TPathDefinition extends Route0._PathDefinition<TPathOriginalDefinition>, TParamsDefinition extends Route0._ParamsDefinition<TPathOriginalDefinition>, TQueryDefinition extends Route0._QueryDefinition<TPathOriginalDefinition>> {
2
- pathOriginalDefinition: TPathOriginalDefinition;
3
- private readonly pathDefinition;
4
- paramsDefinition: TParamsDefinition;
5
- queryDefinition: TQueryDefinition;
6
- baseUrl: string;
1
+ import { StandardSchemaV1 } from '@standard-schema/spec';
2
+
3
+ type PathToken = {
4
+ kind: 'static';
5
+ value: string;
6
+ } | {
7
+ kind: 'param';
8
+ name: string;
9
+ optional: boolean;
10
+ } | {
11
+ kind: 'wildcard';
12
+ prefix: string;
13
+ optional: boolean;
14
+ };
15
+ /**
16
+ * Strongly typed route descriptor and URL builder.
17
+ *
18
+ * A route definition uses:
19
+ * - path params: `/users/:id`
20
+ * - named search keys: `/users&tab&sort`
21
+ * - loose search mode: trailing `&`, e.g. `/users&`
22
+ *
23
+ * Instances are callable (same as `.get()`), so `route(input)` and
24
+ * `route.get(input)` are equivalent.
25
+ */
26
+ declare class Route0<TDefinition extends string, TSearchInput extends UnknownSearchInput = UnknownSearchInput> {
27
+ readonly definition: TDefinition;
28
+ readonly params: _ParamsDefinition<TDefinition>;
29
+ private _origin;
30
+ private _callable;
31
+ Infer: {
32
+ ParamsDefinition: _ParamsDefinition<TDefinition>;
33
+ ParamsInput: _ParamsInput<TDefinition>;
34
+ ParamsInputStringOnly: _ParamsInputStringOnly<TDefinition>;
35
+ ParamsOutput: ParamsOutput<TDefinition>;
36
+ SearchInput: TSearchInput;
37
+ };
38
+ /** Base URL used when generating absolute URLs (`abs: true`). */
39
+ get origin(): string;
40
+ set origin(origin: string);
7
41
  private constructor();
8
- static create<TPathOriginalDefinition extends string, TPathDefinition extends Route0._PathDefinition<TPathOriginalDefinition>, TParamsDefinition extends Route0._ParamsDefinition<TPathOriginalDefinition>, TQueryDefinition extends Route0._QueryDefinition<TPathOriginalDefinition>>(definition: TPathOriginalDefinition, config?: Route0.RouteConfigInput): Route0.Callable<Route0<TPathOriginalDefinition, TPathDefinition, TParamsDefinition, TQueryDefinition>>;
9
- private static _splitPathDefinitionAndQueryTailDefinition;
42
+ /**
43
+ * Creates a callable route instance.
44
+ *
45
+ * If an existing route/callable route is provided, it is cloned.
46
+ */
47
+ static create<TDefinition extends string>(definition: TDefinition | AnyRoute<TDefinition> | CallableRoute<TDefinition>, config?: RouteConfigInput): CallableRoute<TDefinition>;
48
+ /**
49
+ * Normalizes a definition/route into a callable route.
50
+ *
51
+ * Unlike `create`, passing a callable route returns the same instance.
52
+ */
53
+ static from<TDefinition extends string, TSearchInput extends UnknownSearchInput>(definition: TDefinition | AnyRoute<TDefinition, TSearchInput> | CallableRoute<TDefinition, TSearchInput>): CallableRoute<TDefinition, TSearchInput>;
10
54
  private static _getAbsPath;
11
- private static _getPathDefinitionByOriginalDefinition;
12
- private static _getParamsDefinitionByRouteDefinition;
13
- private static _getQueryDefinitionByRouteDefinition;
14
- static overrideMany<T extends Record<string, Route0<any, any, any, any>>>(routes: T, config: Route0.RouteConfigInput): T;
15
- extend<TSuffixDefinition extends string>(suffixDefinition: TSuffixDefinition): Route0.Callable<Route0<Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>, Route0._PathDefinition<Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>>, Route0._ParamsDefinition<Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>>, Route0._QueryDefinition<Route0._RoutePathOriginalDefinitionExtended<TPathOriginalDefinition, TSuffixDefinition>>>>;
16
- get(input: Route0._OnlyIfHasParams<TParamsDefinition, Route0._WithParamsInput<TParamsDefinition, {
17
- query?: undefined;
18
- abs?: false;
19
- }>>): Route0._OnlyIfHasParams<TParamsDefinition, Route0._PathOnlyRouteValue<TPathOriginalDefinition>>;
20
- get(input: Route0._OnlyIfHasParams<TParamsDefinition, Route0._WithParamsInput<TParamsDefinition, {
21
- query: Route0._QueryInput<TQueryDefinition>;
22
- abs?: false;
23
- }>>): Route0._OnlyIfHasParams<TParamsDefinition, Route0._WithQueryRouteValue<TPathOriginalDefinition>>;
24
- get(input: Route0._OnlyIfHasParams<TParamsDefinition, Route0._WithParamsInput<TParamsDefinition, {
25
- query?: undefined;
26
- abs: true;
27
- }>>): Route0._OnlyIfHasParams<TParamsDefinition, Route0._AbsolutePathOnlyRouteValue<TPathOriginalDefinition>>;
28
- get(input: Route0._OnlyIfHasParams<TParamsDefinition, Route0._WithParamsInput<TParamsDefinition, {
29
- query: Route0._QueryInput<TQueryDefinition>;
30
- abs: true;
31
- }>>): Route0._OnlyIfHasParams<TParamsDefinition, Route0._AbsoluteWithQueryRouteValue<TPathOriginalDefinition>>;
32
- get(...args: Route0._OnlyIfNoParams<TParamsDefinition, [], [never]>): Route0._PathOnlyRouteValue<TPathOriginalDefinition>;
33
- get(input: Route0._OnlyIfNoParams<TParamsDefinition, {
34
- query?: undefined;
35
- abs?: false;
36
- }>): Route0._OnlyIfNoParams<TParamsDefinition, Route0._PathOnlyRouteValue<TPathOriginalDefinition>>;
37
- get(input: Route0._OnlyIfNoParams<TParamsDefinition, {
38
- query: Route0._QueryInput<TQueryDefinition>;
39
- abs?: false;
40
- }>): Route0._OnlyIfNoParams<TParamsDefinition, Route0._WithQueryRouteValue<TPathOriginalDefinition>>;
41
- get(input: Route0._OnlyIfNoParams<TParamsDefinition, {
42
- query?: undefined;
43
- abs: true;
44
- }>): Route0._OnlyIfNoParams<TParamsDefinition, Route0._AbsolutePathOnlyRouteValue<TPathOriginalDefinition>>;
45
- get(input: Route0._OnlyIfNoParams<TParamsDefinition, {
46
- query: Route0._QueryInput<TQueryDefinition>;
47
- abs: true;
48
- }>): Route0._OnlyIfNoParams<TParamsDefinition, Route0._AbsoluteWithQueryRouteValue<TPathOriginalDefinition>>;
49
- getDefinition(): TPathDefinition;
50
- clone(config?: Route0.RouteConfigInput): Route0<TPathOriginalDefinition, Route0._TrimQueryTailDefinition<TPathOriginalDefinition>, Route0._ParamsDefinition<TPathOriginalDefinition>, Route0._QueryDefinition<TPathOriginalDefinition>>;
55
+ private static _getParamsDefinitionByDefinition;
56
+ search<TNewSearchInput extends UnknownSearchInput>(): CallableRoute<TDefinition, TNewSearchInput>;
57
+ /** Extends the current route definition by appending a suffix route. */
58
+ extend<TSuffixDefinition extends string>(suffixDefinition: TSuffixDefinition): CallableRoute<PathExtended<TDefinition, TSuffixDefinition>, TSearchInput>;
59
+ get(...args: IsParamsOptional<TDefinition> extends true ? [abs: boolean | string | undefined] : never): string;
60
+ get(...args: IsParamsOptional<TDefinition> extends true ? [
61
+ input?: (_ParamsInput<TDefinition> & {
62
+ '?'?: TSearchInput;
63
+ '#'?: string | number;
64
+ }) | undefined,
65
+ abs?: boolean | string | undefined
66
+ ] : [
67
+ input: _ParamsInput<TDefinition> & {
68
+ '?'?: TSearchInput;
69
+ '#'?: string | number;
70
+ },
71
+ abs?: boolean | string | undefined
72
+ ]): string;
73
+ /** Returns path param keys extracted from route definition. */
74
+ getParamsKeys(): string[];
75
+ getPathTokens(): PathToken[];
76
+ /** Clones route with optional config override. */
77
+ clone(config?: RouteConfigInput): CallableRoute<TDefinition>;
78
+ getRegexBaseStrictString(): string;
79
+ getRegexBaseString(): string;
80
+ getRegexStrictString(): string;
81
+ getRegexString(): string;
82
+ getRegexStrict(): RegExp;
83
+ getRegex(): RegExp;
84
+ /** Creates a grouped strict regex pattern string from many routes. */
85
+ static getRegexStrictStringGroup(routes: AnyRoute[]): string;
86
+ /** Creates a strict grouped regex from many routes. */
87
+ static getRegexStrictGroup(routes: AnyRoute[]): RegExp;
88
+ /** Creates a grouped regex pattern string from many routes. */
89
+ static getRegexStringGroup(routes: AnyRoute[]): string;
90
+ /** Creates a grouped regex from many routes. */
91
+ static getRegexGroup(routes: AnyRoute[]): RegExp;
92
+ /** Converts any location shape to relative form (removes host/origin fields). */
93
+ static toRelLocation<TLocation extends AnyLocation>(location: TLocation): TLocation;
94
+ /** Converts a location to absolute form using provided origin URL. */
95
+ static toAbsLocation<TLocation extends AnyLocation>(location: TLocation, origin: string): TLocation;
96
+ /**
97
+ * Parses a URL-like input into raw location object (without route knowledge).
98
+ *
99
+ * Result is always `UnknownLocation` because no route matching is applied.
100
+ */
101
+ static getLocation(href: `${string}://${string}`): UnknownLocation;
102
+ static getLocation(hrefRel: `/${string}`): UnknownLocation;
103
+ static getLocation(hrefOrHrefRel: string): UnknownLocation;
104
+ static getLocation(location: AnyLocation): UnknownLocation;
105
+ static getLocation(url: URL): UnknownLocation;
106
+ static getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation;
107
+ /**
108
+ * Parses input and matches it against this route definition.
109
+ *
110
+ * Result includes relation flags:
111
+ * - `exact`
112
+ * - `ancestor`
113
+ * - `descendant`
114
+ * - `unmatched`
115
+ */
116
+ getLocation(href: `${string}://${string}`): KnownLocation<TDefinition>;
117
+ getLocation(hrefRel: `/${string}`): KnownLocation<TDefinition>;
118
+ getLocation(hrefOrHrefRel: string): KnownLocation<TDefinition>;
119
+ getLocation(location: AnyLocation): KnownLocation<TDefinition>;
120
+ getLocation(url: AnyLocation): KnownLocation<TDefinition>;
121
+ getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): KnownLocation<TDefinition>;
122
+ private _validateParamsInput;
123
+ private _safeParseSchemaResult;
124
+ private _parseSchemaResult;
125
+ /** Standard Schema for route params input. */
126
+ readonly schema: SchemaRoute0<ParamsInput<TDefinition>, ParamsOutput<TDefinition>>;
127
+ /** True when path structure is equal (param names are ignored). */
128
+ isSame(other: AnyRoute): boolean;
129
+ /** Static convenience wrapper for `isSame`. */
130
+ static isSame(a: AnyRoute | string | undefined, b: AnyRoute | string | undefined): boolean;
131
+ /** True when current route is more specific/deeper than `other`. */
132
+ isDescendant(other: AnyRoute | string | undefined): boolean;
133
+ /** True when current route is broader/shallower than `other`. */
134
+ isAncestor(other: AnyRoute | string | undefined): boolean;
135
+ /** True when two route patterns can match the same concrete URL. */
136
+ isConflict(other: AnyRoute | string | undefined): boolean;
137
+ /** True when paths are same or can overlap when optional parts are omitted. */
138
+ isMayBeSame(other: AnyRoute | string | undefined): boolean;
139
+ /** Specificity comparator used for deterministic route ordering. */
140
+ isMoreSpecificThan(other: AnyRoute | string | undefined): boolean;
51
141
  }
52
- declare namespace Route0 {
53
- type Callable<T extends Route0<any, any, any, any>> = T & T['get'];
54
- type RouteConfigInput = {
55
- baseUrl?: string;
56
- };
57
- type Params<TRoute0 extends Route0<any, any, any, any>> = {
58
- [K in keyof TRoute0['paramsDefinition']]: string;
142
+ /**
143
+ * Typed route collection with deterministic matching order.
144
+ *
145
+ * `Routes.create()` accepts either plain string definitions or route objects
146
+ * and returns a "pretty" object with direct route access + helper methods under `._`.
147
+ */
148
+ declare class Routes<const T extends RoutesRecord = any> {
149
+ _routes: RoutesRecordHydrated<T>;
150
+ _pathsOrdering: string[];
151
+ _keysOrdering: string[];
152
+ _ordered: CallableRoute[];
153
+ _: {
154
+ routes: Routes<T>['_routes'];
155
+ getLocation: Routes<T>['_getLocation'];
156
+ clone: Routes<T>['_clone'];
157
+ pathsOrdering: Routes<T>['_pathsOrdering'];
158
+ keysOrdering: Routes<T>['_keysOrdering'];
159
+ ordered: Routes<T>['_ordered'];
59
160
  };
60
- type Query<TRoute0 extends Route0<any, any, any, any>> = Partial<{
61
- [K in keyof TRoute0['queryDefinition']]: string | undefined;
62
- } & Record<string, string | undefined>>;
63
- type _TrimQueryTailDefinition<S extends string> = S extends `${infer P}&${string}` ? P : S;
64
- type _QueryTailDefinitionWithoutFirstAmp<S extends string> = S extends `${string}&${infer T}` ? T : '';
65
- type _QueryTailDefinitionWithFirstAmp<S extends string> = S extends `${string}&${infer T}` ? `&${T}` : '';
66
- type _AmpSplit<S extends string> = S extends `${infer A}&${infer B}` ? A | _AmpSplit<B> : S;
67
- type _NonEmpty<T> = [T] extends ['' | never] ? never : T;
68
- type _ExtractPathParams<S extends string> = S extends `${string}:${infer After}` ? After extends `${infer Name}/${infer Rest}` ? Name | _ExtractPathParams<`/${Rest}`> : After : never;
69
- type _ReplacePathParams<S extends string> = S extends `${infer Head}:${infer Tail}` ? Tail extends `${infer _Param}/${infer Rest}` ? _ReplacePathParams<`${Head}${string}/${Rest}`> : `${Head}${string}` : S;
70
- type _DedupeSlashes<S extends string> = S extends `${infer A}//${infer B}` ? _DedupeSlashes<`${A}/${B}`> : S;
71
- type _EmptyRecord = Record<never, never>;
72
- type _JoinPath<Parent extends string, Suffix extends string> = _DedupeSlashes<_PathDefinition<Parent> extends infer A extends string ? _PathDefinition<Suffix> extends infer B extends string ? A extends '' ? B extends '' ? '' : B extends `/${string}` ? B : `/${B}` : B extends '' ? A : A extends `${string}/` ? `${A}${B}` : B extends `/${string}` ? `${A}${B}` : `${A}/${B}` : never : never>;
73
- type _OnlyIfNoParams<TParams extends object, Yes, No = never> = keyof TParams extends never ? Yes : No;
74
- type _OnlyIfHasParams<TParams extends object, Yes, No = never> = keyof TParams extends never ? No : Yes;
75
- type _PathDefinition<TPathOriginalDefinition extends string> = _TrimQueryTailDefinition<TPathOriginalDefinition>;
76
- type _ParamsDefinition<TPathOriginalDefinition extends string> = _ExtractPathParams<_PathDefinition<TPathOriginalDefinition>> extends infer U ? [U] extends [never] ? _EmptyRecord : {
77
- [K in Extract<U, string>]: true;
78
- } : _EmptyRecord;
79
- type _QueryDefinition<TPathOriginalDefinition extends string> = _NonEmpty<_QueryTailDefinitionWithoutFirstAmp<TPathOriginalDefinition>> extends infer Tail extends string ? _AmpSplit<Tail> extends infer U ? [U] extends [never] ? _EmptyRecord : {
80
- [K in Extract<U, string>]: true;
81
- } : _EmptyRecord : _EmptyRecord;
82
- type _RoutePathOriginalDefinitionExtended<TSourcePathOriginalDefinition extends string, TSuffixPathOriginalDefinition extends string> = `${_JoinPath<TSourcePathOriginalDefinition, TSuffixPathOriginalDefinition>}${_QueryTailDefinitionWithFirstAmp<TSuffixPathOriginalDefinition>}`;
83
- type _ParamsInput<TParamsDefinition extends object> = {
84
- [K in keyof TParamsDefinition]: string | number;
161
+ private constructor();
162
+ /** Creates and hydrates a typed routes collection. */
163
+ static create<const T extends RoutesRecord>(routes: T, override?: RouteConfigInput): RoutesPretty<T>;
164
+ private static prettify;
165
+ private static hydrate;
166
+ /**
167
+ * Matches an input URL against collection routes.
168
+ *
169
+ * Returns first exact match according to precomputed ordering,
170
+ * otherwise returns `UnknownLocation`.
171
+ */
172
+ _getLocation(href: `${string}://${string}`): UnknownLocation | ExactLocation;
173
+ _getLocation(hrefRel: `/${string}`): UnknownLocation | ExactLocation;
174
+ _getLocation(hrefOrHrefRel: string): UnknownLocation | ExactLocation;
175
+ _getLocation(location: AnyLocation): UnknownLocation | ExactLocation;
176
+ _getLocation(url: URL): UnknownLocation | ExactLocation;
177
+ _getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation | ExactLocation;
178
+ private static makeOrdering;
179
+ /** Returns a cloned routes collection with config applied to each route. */
180
+ _clone(config: RouteConfigInput): RoutesPretty<T>;
181
+ static _: {
182
+ prettify: typeof Routes.prettify;
183
+ hydrate: typeof Routes.hydrate;
184
+ makeOrdering: typeof Routes.makeOrdering;
85
185
  };
86
- type _QueryInput<TQueryDefinition extends object> = Partial<{
87
- [K in keyof TQueryDefinition]: string | number;
88
- }> & Record<string, string | number>;
89
- type _WithParamsInput<TParamsDefinition extends object, T extends {
90
- query?: _QueryInput<any>;
91
- abs?: boolean;
92
- }> = _ParamsInput<TParamsDefinition> & T;
93
- type _PathOnlyRouteValue<TPathOriginalDefinition extends string> = `${_ReplacePathParams<_PathDefinition<TPathOriginalDefinition>>}`;
94
- type _WithQueryRouteValue<TPathOriginalDefinition extends string> = `${_ReplacePathParams<_PathDefinition<TPathOriginalDefinition>>}?${string}`;
95
- type _AbsolutePathOnlyRouteValue<TPathOriginalDefinition extends string> = `${string}${_PathOnlyRouteValue<TPathOriginalDefinition>}`;
96
- type _AbsoluteWithQueryRouteValue<TPathOriginalDefinition extends string> = `${string}${_WithQueryRouteValue<TPathOriginalDefinition>}`;
97
186
  }
187
+ /** Any route instance shape, preserving literal path type when known. */
188
+ type AnyRoute<T extends Route0<string> | string = string, TSearch extends UnknownSearchInput = UnknownSearchInput> = T extends string ? Route0<T, TSearch> : T;
189
+ /** Callable route (`route(input)`) plus route instance methods/properties. */
190
+ type CallableRoute<T extends Route0<string> | string = string, TSearch extends UnknownSearchInput = UnknownSearchInput> = AnyRoute<T, TSearch> & AnyRoute<T, TSearch>['get'];
191
+ /** Route input accepted by most APIs: definition string or route object/callable. */
192
+ type AnyRouteOrDefinition<T extends string = string> = AnyRoute<T> | CallableRoute<T> | T;
193
+ /** Route-level runtime configuration. */
194
+ type RouteConfigInput = {
195
+ origin?: string;
196
+ };
197
+ /** User-provided routes map (plain definitions or route instances). */
198
+ type RoutesRecord = Record<string, AnyRoute | string>;
199
+ /** Same as `RoutesRecord` but all values normalized to callable routes. */
200
+ type RoutesRecordHydrated<TRoutesRecord extends RoutesRecord = any> = {
201
+ [K in keyof TRoutesRecord]: CallableRoute<TRoutesRecord[K]>;
202
+ };
203
+ /** Public shape returned by `Routes.create()`. Default `any` so `satisfies RoutesPretty` accepts any created routes. */
204
+ type RoutesPretty<TRoutesRecord extends RoutesRecord = any> = RoutesRecordHydrated<TRoutesRecord> & Omit<Routes<TRoutesRecord>, '_routes' | '_getLocation' | '_clone' | '_pathsOrdering' | '_keysOrdering' | '_ordered'>;
205
+ type ExtractRoutesKeys<TRoutes extends RoutesPretty | RoutesRecord> = TRoutes extends RoutesPretty ? Extract<keyof TRoutes['_']['routes'], string> : TRoutes extends RoutesRecord ? Extract<keyof TRoutes, string> : never;
206
+ type ExtractRoute<TRoutes extends RoutesPretty | RoutesRecord, TKey extends ExtractRoutesKeys<TRoutes>> = TRoutes extends RoutesPretty ? TRoutes['_']['routes'][TKey] : TRoutes extends RoutesRecord ? TRoutes[TKey] : never;
207
+ type Definition<T extends AnyRoute | string> = T extends AnyRoute ? T['definition'] : T extends string ? T : never;
208
+ type ParamsDefinition<T extends AnyRoute | string> = T extends AnyRoute ? T['params'] : T extends string ? _ParamsDefinition<T> : undefined;
209
+ type Extended<T extends AnyRoute | string | undefined, TSuffixDefinition extends string, TSearchInput extends UnknownSearchInput = UnknownSearchInput> = T extends AnyRoute ? Route0<PathExtended<T['definition'], TSuffixDefinition>, TSearchInput> : T extends string ? Route0<PathExtended<T, TSuffixDefinition>, TSearchInput> : T extends undefined ? Route0<TSuffixDefinition, TSearchInput> : never;
210
+ type IsAncestor<T extends AnyRoute | string, TAncestor extends AnyRoute | string> = _IsAncestor<Definition<T>, Definition<TAncestor>>;
211
+ type IsDescendant<T extends AnyRoute | string, TDescendant extends AnyRoute | string> = _IsDescendant<Definition<T>, Definition<TDescendant>>;
212
+ type IsSame<T extends AnyRoute | string, TExact extends AnyRoute | string> = _IsSame<Definition<T>, Definition<TExact>>;
213
+ type IsSameParams<T1 extends AnyRoute | string, T2 extends AnyRoute | string> = _IsSameParams<ParamsDefinition<T1>, ParamsDefinition<T2>>;
214
+ type HasParams<T extends AnyRoute | string> = keyof _ParamsDefinition<Definition<T>> extends never ? false : true;
215
+ type HasWildcard<T extends AnyRoute | string> = Definition<T> extends `${string}*${string}` ? true : false;
216
+ type HasRequiredParams<T extends AnyRoute | string> = _RequiredParamKeys<Definition<T>> extends never ? false : true;
217
+ type ParamsOutput<T extends AnyRoute | string> = {
218
+ [K in keyof ParamsDefinition<T>]: ParamsDefinition<T>[K] extends true ? string : string | undefined;
219
+ };
220
+ type ParamsInput<T extends AnyRoute | string = string> = _ParamsInput<Definition<T>>;
221
+ type IsParamsOptional<T extends AnyRoute | string> = HasRequiredParams<Definition<T>> extends true ? false : true;
222
+ type ParamsInputStringOnly<T extends AnyRoute | string = string> = _ParamsInputStringOnly<Definition<T>>;
223
+ type LocationParams<TDefinition extends string> = {
224
+ [K in keyof _ParamsDefinition<TDefinition>]: _ParamsDefinition<TDefinition>[K] extends true ? string : string | undefined;
225
+ };
226
+ /**
227
+ * URL location primitives independent from route-matching state.
228
+ *
229
+ * `hrefRel` is relative href and includes `pathname + search + hash`.
230
+ */
231
+ type _GeneralLocation = {
232
+ /**
233
+ * Path without search/hash (normalized for trailing slash).
234
+ *
235
+ * Example:
236
+ * - input: `https://example.com/users/42?tab=posts#section`
237
+ * - pathname: `/users/42`
238
+ */
239
+ pathname: string;
240
+ /**
241
+ * Parsed query object.
242
+ *
243
+ * Example:
244
+ * - `{ tab: "posts", sort: "desc" }`
245
+ */
246
+ search: UnknownSearchParsed;
247
+ /**
248
+ * Raw query string with leading `?`, if present.
249
+ *
250
+ * Example:
251
+ * - `?tab=posts&sort=desc`
252
+ */
253
+ searchString: string;
254
+ /**
255
+ * Raw hash with leading `#`, if present.
256
+ *
257
+ * Example:
258
+ * - `#section`
259
+ */
260
+ hash: string;
261
+ /**
262
+ * URL origin for absolute inputs.
263
+ *
264
+ * Example:
265
+ * - href: `https://example.com/users/42`
266
+ * - origin: `https://example.com`
267
+ */
268
+ origin?: string;
269
+ /**
270
+ * Full absolute href for absolute inputs.
271
+ *
272
+ * Example:
273
+ * - `https://example.com/users/42?tab=posts#section`
274
+ */
275
+ href?: string;
276
+ /**
277
+ * Relative href (`pathname + search + hash`).
278
+ *
279
+ * Example:
280
+ * - pathname: `/users/42`
281
+ * - search: `?tab=posts`
282
+ * - hash: `#section`
283
+ * - hrefRel: `/users/42?tab=posts#section`
284
+ */
285
+ hrefRel: string;
286
+ /**
287
+ * Whether input was absolute URL.
288
+ *
289
+ * Examples:
290
+ * - `https://example.com/users/42` -> `true`
291
+ * - `/users/42` -> `false`
292
+ */
293
+ abs: boolean;
294
+ port?: string;
295
+ host?: string;
296
+ hostname?: string;
297
+ };
298
+ /** Location state before matching against a concrete route. */
299
+ type UnknownLocationState = {
300
+ known: false;
301
+ route: undefined;
302
+ params: undefined;
303
+ exact: false;
304
+ ancestor: false;
305
+ descendant: false;
306
+ unmatched: false;
307
+ };
308
+ type UnknownLocation = _GeneralLocation & UnknownLocationState;
309
+ /** Known route context, but no exact/ancestor/descendant relation matched. */
310
+ type UnmatchedLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {
311
+ known: true;
312
+ route: Definition<TRoute>;
313
+ params: Record<never, never>;
314
+ exact: false;
315
+ ancestor: false;
316
+ descendant: false;
317
+ unmatched: true;
318
+ };
319
+ type UnmatchedLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & UnmatchedLocationState<TRoute>;
320
+ /** Exact match state for a known route. */
321
+ type ExactLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {
322
+ known: true;
323
+ route: Definition<TRoute>;
324
+ params: ParamsOutput<TRoute>;
325
+ exact: true;
326
+ ancestor: false;
327
+ descendant: false;
328
+ unmatched: false;
329
+ };
330
+ type ExactLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & ExactLocationState<TRoute>;
331
+ /** Input URL is a descendant of route definition (route is ancestor). */
332
+ type AncestorLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {
333
+ known: true;
334
+ route: Definition<TRoute>;
335
+ params: ParamsOutput<TRoute>;
336
+ exact: false;
337
+ ancestor: true;
338
+ descendant: false;
339
+ unmatched: false;
340
+ };
341
+ type AncestorLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & AncestorLocationState<TRoute>;
342
+ /** It is when route not match at all, but params match. */
343
+ type WeakAncestorLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {
344
+ known: true;
345
+ route: Definition<TRoute>;
346
+ params: ParamsOutput<TRoute>;
347
+ exact: false;
348
+ ancestor: true;
349
+ descendant: false;
350
+ unmatched: false;
351
+ };
352
+ type WeakAncestorLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & WeakAncestorLocationState<TRoute>;
353
+ /** Input URL is an ancestor prefix of route definition (route is descendant). */
354
+ type DescendantLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {
355
+ known: true;
356
+ route: Definition<TRoute>;
357
+ params: Partial<ParamsOutput<TRoute>>;
358
+ exact: false;
359
+ ancestor: false;
360
+ descendant: true;
361
+ unmatched: false;
362
+ };
363
+ type DescendantLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & DescendantLocationState<TRoute>;
364
+ type UnknownSearchParsedValue = string | UnknownSearchParsed | Array<UnknownSearchParsedValue>;
365
+ interface UnknownSearchParsed {
366
+ [key: string]: UnknownSearchParsedValue;
367
+ }
368
+ type UnknownSearchInputValue = string | number | boolean | undefined | UnknownSearchInput | Array<UnknownSearchInputValue>;
369
+ interface UnknownSearchInput {
370
+ [key: string]: UnknownSearchInputValue;
371
+ }
372
+ /** It is when route not match at all, but params partially match. */
373
+ type WeakDescendantLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {
374
+ known: true;
375
+ route: Definition<TRoute>;
376
+ params: Partial<ParamsOutput<TRoute>>;
377
+ exact: false;
378
+ ancestor: false;
379
+ descendant: true;
380
+ unmatched: false;
381
+ };
382
+ type WeakDescendantLocation<TRoute extends AnyRoute | string = AnyRoute | string> = _GeneralLocation & WeakDescendantLocationState<TRoute>;
383
+ type KnownLocation<TRoute extends AnyRoute | string = AnyRoute | string> = UnmatchedLocation<TRoute> | ExactLocation<TRoute> | AncestorLocation<TRoute> | WeakAncestorLocation<TRoute> | DescendantLocation<TRoute> | WeakDescendantLocation<TRoute>;
384
+ type AnyLocation<TRoute extends AnyRoute | string = AnyRoute | string> = UnknownLocation | KnownLocation<TRoute>;
385
+ type _ParamsDefinition<TDefinition extends string> = _ExtractParamsDefinitionBySegments<_SplitPathSegments<Definition<TDefinition>>>;
386
+ type _Simplify<T> = {
387
+ [K in keyof T]: T[K];
388
+ } & {};
389
+ type _IfNoKeys<T extends object, TYes, TNo> = keyof T extends never ? TYes : TNo;
390
+ type _ParamsInput<TDefinition extends string> = _ParamsDefinition<TDefinition> extends infer TDef extends Record<string, boolean> ? _IfNoKeys<TDef, Record<never, never>, _Simplify<{
391
+ [K in keyof TDef as TDef[K] extends true ? K : never]: string | number;
392
+ } & {
393
+ [K in keyof TDef as TDef[K] extends false ? K : never]?: string | number | undefined;
394
+ }>> : Record<never, never>;
395
+ type _ParamsInputStringOnly<TDefinition extends string> = _ParamsDefinition<TDefinition> extends infer TDef extends Record<string, boolean> ? _IfNoKeys<TDef, Record<never, never>, _Simplify<{
396
+ [K in keyof TDef as TDef[K] extends true ? K : never]: string;
397
+ } & {
398
+ [K in keyof TDef as TDef[K] extends false ? K : never]?: string | undefined;
399
+ }>> : Record<never, never>;
400
+ type _SplitPathSegments<TPath extends string> = TPath extends '' ? [] : TPath extends '/' ? [] : TPath extends `/${infer Rest}` ? _SplitPathSegments<Rest> : TPath extends `${infer Segment}/${infer Rest}` ? Segment extends '' ? _SplitPathSegments<Rest> : [Segment, ..._SplitPathSegments<Rest>] : TPath extends '' ? [] : [TPath];
401
+ type _ParamDefinitionFromSegment<TSegment extends string> = TSegment extends `:${infer Name}?` ? {
402
+ [K in Name]: false;
403
+ } : TSegment extends `:${infer Name}` ? {
404
+ [K in Name]: true;
405
+ } : TSegment extends `${string}*?` ? {
406
+ '*': false;
407
+ } : TSegment extends `${string}*` ? {
408
+ '*': true;
409
+ } : Record<never, never>;
410
+ type _MergeParamDefinitions<A extends Record<string, boolean>, B extends Record<string, boolean>> = {
411
+ [K in keyof A | keyof B]: K extends keyof B ? B[K] : K extends keyof A ? A[K] : never;
412
+ };
413
+ type _ExtractParamsDefinitionBySegments<TSegments extends string[]> = TSegments extends [
414
+ infer Segment extends string,
415
+ ...infer Rest extends string[]
416
+ ] ? _MergeParamDefinitions<_ParamDefinitionFromSegment<Segment>, _ExtractParamsDefinitionBySegments<Rest>> : Record<never, never>;
417
+ type _RequiredParamKeys<TDefinition extends string> = {
418
+ [K in keyof _ParamsDefinition<TDefinition>]: _ParamsDefinition<TDefinition>[K] extends true ? K : never;
419
+ }[keyof _ParamsDefinition<TDefinition>];
420
+ type ReplacePathParams<S extends string> = S extends `${infer Head}:${infer Tail}` ? Tail extends `${infer _Param}/${infer Rest}` ? ReplacePathParams<`${Head}${string}/${Rest}`> : `${Head}${string}` : S;
421
+ type DedupeSlashes<S extends string> = S extends `${infer A}//${infer B}` ? DedupeSlashes<`${A}/${B}`> : S;
422
+ type EmptyRecord = Record<never, never>;
423
+ type JoinPath<Parent extends string, Suffix extends string> = DedupeSlashes<Definition<Parent> extends infer A extends string ? Definition<Suffix> extends infer B extends string ? A extends '' ? B extends '' ? '' : B extends `/${string}` ? B : `/${B}` : B extends '' ? A : A extends `${string}/` ? `${A}${B}` : B extends `/${string}` ? `${A}${B}` : `${A}/${B}` : never : never>;
424
+ type OnlyIfNoParams<TRoute extends AnyRoute | string, Yes, No = never> = HasParams<TRoute> extends false ? Yes : No;
425
+ type OnlyIfHasParams<TRoute extends AnyRoute | string, Yes, No = never> = HasParams<TRoute> extends true ? Yes : No;
426
+ type PathExtended<TSourceDefinitionDefinition extends string, TSuffixDefinitionDefinition extends string> = `${JoinPath<StripTrailingWildcard<TSourceDefinitionDefinition>, TSuffixDefinitionDefinition>}`;
427
+ type StripTrailingWildcard<TDefinition extends string> = TDefinition extends `${infer TPath}*?` ? TPath : TDefinition extends `${infer TPath}*` ? TPath : TDefinition;
428
+ type IsAny<T> = 0 extends 1 & T ? true : false;
429
+ type _IsSameParams<T1 extends object | undefined, T2 extends object | undefined> = T1 extends undefined ? T2 extends undefined ? true : false : T2 extends undefined ? false : T1 extends T2 ? T2 extends T1 ? true : false : false;
430
+ type _IsAncestor<T extends string, TAncestor extends string> = T extends TAncestor ? false : T extends `${TAncestor}${string}` ? true : false;
431
+ type _IsDescendant<T extends string, TDescendant extends string> = TDescendant extends T ? false : TDescendant extends `${T}${string}` ? true : false;
432
+ type _IsSame<T extends string, TExact extends string> = T extends TExact ? TExact extends T ? true : false : false;
433
+ type _SafeParseInputResult<TInputParsed extends Record<string, unknown>> = {
434
+ success: true;
435
+ data: TInputParsed;
436
+ error: undefined;
437
+ } | {
438
+ success: false;
439
+ data: undefined;
440
+ error: Error;
441
+ };
442
+ type SchemaRoute0<TInput extends Record<string, unknown>, TOutput extends Record<string, unknown>> = StandardSchemaV1<TInput, TOutput> & {
443
+ parse: (input: unknown) => TOutput;
444
+ safeParse: (input: unknown) => _SafeParseInputResult<TOutput>;
445
+ };
98
446
 
99
- export { Route0 };
447
+ export { type AncestorLocation, type AncestorLocationState, type AnyLocation, type AnyRoute, type AnyRouteOrDefinition, type CallableRoute, type DedupeSlashes, type Definition, type DescendantLocation, type DescendantLocationState, type EmptyRecord, type ExactLocation, type ExactLocationState, type Extended, type ExtractRoute, type ExtractRoutesKeys, type HasParams, type HasRequiredParams, type HasWildcard, type IsAncestor, type IsAny, type IsDescendant, type IsParamsOptional, type IsSame, type IsSameParams, type JoinPath, type KnownLocation, type LocationParams, type OnlyIfHasParams, type OnlyIfNoParams, type ParamsDefinition, type ParamsInput, type ParamsInputStringOnly, type ParamsOutput, type PathExtended, type PathToken, type ReplacePathParams, Route0, type RouteConfigInput, Routes, type RoutesPretty, type RoutesRecord, type RoutesRecordHydrated, type SchemaRoute0, type StripTrailingWildcard, type UnknownLocation, type UnknownLocationState, type UnknownSearchInput, type UnknownSearchInputValue, type UnknownSearchParsed, type UnknownSearchParsedValue, type UnmatchedLocation, type UnmatchedLocationState, type WeakAncestorLocation, type WeakAncestorLocationState, type WeakDescendantLocation, type WeakDescendantLocationState, type _ExtractParamsDefinitionBySegments, type _GeneralLocation, type _IfNoKeys, type _IsAncestor, type _IsDescendant, type _IsSame, type _IsSameParams, type _MergeParamDefinitions, type _ParamDefinitionFromSegment, type _ParamsDefinition, type _ParamsInput, type _ParamsInputStringOnly, type _RequiredParamKeys, type _SafeParseInputResult, type _Simplify, type _SplitPathSegments };