@tanstack/react-router 1.29.2 → 1.31.0

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.
Files changed (63) hide show
  1. package/dist/cjs/Matches.cjs.map +1 -1
  2. package/dist/cjs/Matches.d.cts +9 -9
  3. package/dist/cjs/RouterProvider.cjs.map +1 -1
  4. package/dist/cjs/RouterProvider.d.cts +7 -7
  5. package/dist/cjs/fileRoute.d.cts +1 -1
  6. package/dist/cjs/link.cjs.map +1 -1
  7. package/dist/cjs/link.d.cts +42 -42
  8. package/dist/cjs/path.cjs +1 -1
  9. package/dist/cjs/path.cjs.map +1 -1
  10. package/dist/cjs/redirects.cjs.map +1 -1
  11. package/dist/cjs/redirects.d.cts +5 -6
  12. package/dist/cjs/route.cjs.map +1 -1
  13. package/dist/cjs/route.d.cts +6 -6
  14. package/dist/cjs/routeInfo.d.cts +19 -2
  15. package/dist/cjs/router.cjs +5 -1
  16. package/dist/cjs/router.cjs.map +1 -1
  17. package/dist/cjs/router.d.cts +13 -12
  18. package/dist/cjs/routerContext.cjs.map +1 -1
  19. package/dist/cjs/routerContext.d.cts +1 -1
  20. package/dist/cjs/useNavigate.cjs.map +1 -1
  21. package/dist/cjs/useNavigate.d.cts +3 -4
  22. package/dist/cjs/useRouter.cjs.map +1 -1
  23. package/dist/cjs/useRouter.d.cts +3 -4
  24. package/dist/cjs/useRouterState.cjs.map +1 -1
  25. package/dist/cjs/useRouterState.d.cts +3 -4
  26. package/dist/esm/Matches.d.ts +9 -9
  27. package/dist/esm/Matches.js.map +1 -1
  28. package/dist/esm/RouterProvider.d.ts +7 -7
  29. package/dist/esm/RouterProvider.js.map +1 -1
  30. package/dist/esm/fileRoute.d.ts +1 -1
  31. package/dist/esm/link.d.ts +42 -42
  32. package/dist/esm/link.js.map +1 -1
  33. package/dist/esm/path.js +1 -1
  34. package/dist/esm/path.js.map +1 -1
  35. package/dist/esm/redirects.d.ts +5 -6
  36. package/dist/esm/redirects.js.map +1 -1
  37. package/dist/esm/route.d.ts +6 -6
  38. package/dist/esm/route.js.map +1 -1
  39. package/dist/esm/routeInfo.d.ts +19 -2
  40. package/dist/esm/router.d.ts +13 -12
  41. package/dist/esm/router.js +5 -1
  42. package/dist/esm/router.js.map +1 -1
  43. package/dist/esm/routerContext.d.ts +1 -1
  44. package/dist/esm/routerContext.js.map +1 -1
  45. package/dist/esm/useNavigate.d.ts +3 -4
  46. package/dist/esm/useNavigate.js.map +1 -1
  47. package/dist/esm/useRouter.d.ts +3 -4
  48. package/dist/esm/useRouter.js.map +1 -1
  49. package/dist/esm/useRouterState.d.ts +3 -4
  50. package/dist/esm/useRouterState.js.map +1 -1
  51. package/package.json +1 -1
  52. package/src/Matches.tsx +39 -21
  53. package/src/RouterProvider.tsx +34 -11
  54. package/src/link.tsx +124 -139
  55. package/src/path.ts +1 -1
  56. package/src/redirects.ts +14 -14
  57. package/src/route.ts +3 -3
  58. package/src/routeInfo.ts +72 -4
  59. package/src/router.ts +59 -13
  60. package/src/routerContext.tsx +1 -1
  61. package/src/useNavigate.tsx +9 -10
  62. package/src/useRouter.tsx +4 -5
  63. package/src/useRouterState.tsx +5 -6
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react';
2
- import type { ParsedLocation } from '.';
2
+ import type { AnyRouter, ParsedLocation } from '.';
3
3
  import type { HistoryState } from '@tanstack/history';
4
4
  import type { Trim } from './fileRoute.js';
5
5
  import type { AnyRoute, RootSearchSchema } from './route.js';
6
- import type { RouteByPath, RouteLeaves, RoutePaths, RoutePathsAutoComplete } from './routeInfo.js';
6
+ import type { RouteByPath, RouteByToPath, RoutePaths, RoutePathsAutoComplete, RouteToPath } from './routeInfo.js';
7
7
  import type { RegisteredRouter } from './router.js';
8
8
  import type { Expand, MakeDifferenceOptional, NoInfer, NonNullableUpdater, PickRequired, Updater, WithoutEmpty } from './utils.js';
9
9
  export type CleanPath<T extends string> = T extends `${infer L}//${infer R}` ? CleanPath<`${CleanPath<L>}/${CleanPath<R>}`> : T extends `${infer L}//` ? `${CleanPath<L>}/` : T extends `//${infer L}` ? `/${CleanPath<L>}` : T;
@@ -16,83 +16,83 @@ export type Join<T, TDelimiter extends string = '/'> = T extends [] ? '' : T ext
16
16
  ...infer Tail extends [...Array<string>]
17
17
  ] ? CleanPath<`${L}${TDelimiter}${Join<Tail>}`> : never;
18
18
  export type Last<T extends Array<any>> = T extends [...infer _, infer L] ? L : never;
19
- export type RemoveTrailingSlashes<T> = T extends `${infer R}/` ? RemoveTrailingSlashes<R> : T;
20
- export type RemoveLeadingSlashes<T> = T extends `/${infer R}` ? RemoveLeadingSlashes<R> : T;
21
- export type ResolvePaths<TRouteTree extends AnyRoute, TSearchPath> = RouteByPath<TRouteTree, RemoveTrailingSlashes<TSearchPath>> extends never ? RouteLeaves<TRouteTree> : RouteLeaves<RouteByPath<TRouteTree, RemoveTrailingSlashes<TSearchPath>>>;
22
- export type SearchPaths<TRouteTree extends AnyRoute, TSearchPath extends string, TPaths = ResolvePaths<TRouteTree, TSearchPath>> = TPaths extends `${RemoveTrailingSlashes<TSearchPath>}/${infer TRest}` ? TRest : never;
23
- export type SearchRelativePathAutoComplete<TRouteTree extends AnyRoute, TTo extends string, TSearchPath extends string> = `${TTo}/${SearchPaths<TRouteTree, TSearchPath>}`;
24
- export type RelativeToParentPathAutoComplete<TRouteTree extends AnyRoute, TFrom extends string, TTo extends string, TResolvedPath extends string = RemoveTrailingSlashes<ResolveRelativePath<TFrom, TTo>>> = SearchRelativePathAutoComplete<TRouteTree, TTo, TResolvedPath> | (TResolvedPath extends '' ? never : `${TTo}/../`);
25
- export type RelativeToCurrentPathAutoComplete<TRouteTree extends AnyRoute, TFrom extends string, TTo extends string, TRestTo extends string, TResolvedPath extends string = RemoveTrailingSlashes<`${RemoveTrailingSlashes<TFrom>}/${RemoveLeadingSlashes<TRestTo>}`>> = SearchRelativePathAutoComplete<TRouteTree, TTo, TResolvedPath>;
26
- export type AbsolutePathAutoComplete<TRouteTree extends AnyRoute, TFrom extends string> = (string extends TFrom ? './' : TFrom extends `/` ? never : SearchPaths<TRouteTree, TFrom> extends '' ? never : './') | (string extends TFrom ? '../' : TFrom extends `/` ? never : '../') | RouteLeaves<TRouteTree> | (TFrom extends '/' ? never : SearchPaths<TRouteTree, TFrom>);
27
- export type RelativeToPathAutoComplete<TRouteTree extends AnyRoute, TFrom extends string, TTo extends string> = TTo extends `..${string}` ? RelativeToParentPathAutoComplete<TRouteTree, TFrom, RemoveTrailingSlashes<TTo>> : TTo extends `./${infer TRestTTo}` ? RelativeToCurrentPathAutoComplete<TRouteTree, TFrom, RemoveTrailingSlashes<TTo>, TRestTTo> : AbsolutePathAutoComplete<TRouteTree, TFrom>;
28
- export type NavigateOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''> = ToOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {
19
+ export type RemoveTrailingSlashes<T> = T extends `${infer R}/` ? R : T;
20
+ export type RemoveLeadingSlashes<T> = T extends `/${infer R}` ? R : T;
21
+ export type ResolvePaths<TRouter extends AnyRouter, TSearchPath> = RouteByPath<TRouter['routeTree'], RemoveTrailingSlashes<TSearchPath>> extends never ? RouteToPath<TRouter, TRouter['routeTree']> : RouteToPath<TRouter, RouteByPath<TRouter['routeTree'], RemoveTrailingSlashes<TSearchPath>>>;
22
+ export type SearchPaths<TRouter extends AnyRouter, TSearchPath extends string, TPaths = ResolvePaths<TRouter, TSearchPath>> = TPaths extends `${RemoveTrailingSlashes<TSearchPath>}${infer TRest}` ? TRest : never;
23
+ export type SearchRelativePathAutoComplete<TRouter extends AnyRouter, TTo extends string, TSearchPath extends string> = `${TTo}/${RemoveLeadingSlashes<SearchPaths<TRouter, TSearchPath>>}`;
24
+ export type RelativeToParentPathAutoComplete<TRouter extends AnyRouter, TFrom extends string, TTo extends string, TResolvedPath extends string = RemoveTrailingSlashes<ResolveRelativePath<TFrom, TTo>>> = SearchRelativePathAutoComplete<TRouter, TTo, TResolvedPath> | (TResolvedPath extends '' ? never : `${TTo}/../`);
25
+ export type RelativeToCurrentPathAutoComplete<TRouter extends AnyRouter, TFrom extends string, TTo extends string, TRestTo extends string, TResolvedPath extends string = RemoveTrailingSlashes<`${RemoveTrailingSlashes<TFrom>}/${RemoveLeadingSlashes<TRestTo>}`>> = SearchRelativePathAutoComplete<TRouter, TTo, TResolvedPath>;
26
+ export type AbsolutePathAutoComplete<TRouter extends AnyRouter, TFrom extends string> = (string extends TFrom ? './' : TFrom extends `/` ? never : SearchPaths<TRouter, TFrom> extends '' ? never : './') | (string extends TFrom ? '../' : TFrom extends `/` ? never : '../') | RouteToPath<TRouter, TRouter['routeTree']> | (TFrom extends '/' ? never : string extends TFrom ? RemoveLeadingSlashes<RouteToPath<TRouter, TRouter['routeTree']>> : RemoveLeadingSlashes<SearchPaths<TRouter, TFrom>>);
27
+ export type RelativeToPathAutoComplete<TRouter extends AnyRouter, TFrom extends string, TTo extends string> = TTo extends `..${string}` ? RelativeToParentPathAutoComplete<TRouter, TFrom, RemoveTrailingSlashes<TTo>> : TTo extends `./${infer TRestTTo}` ? RelativeToCurrentPathAutoComplete<TRouter, TFrom, RemoveTrailingSlashes<TTo>, TRestTTo> : AbsolutePathAutoComplete<TRouter, TFrom>;
28
+ export type NavigateOptions<TRouter extends AnyRouter = RegisteredRouter, TFrom extends RoutePaths<TRouter['routeTree']> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom, TMaskTo extends string = ''> = ToOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & {
29
29
  replace?: boolean;
30
30
  resetScroll?: boolean;
31
31
  /** @deprecated All navigations now use startTransition under the hood */
32
32
  startTransition?: boolean;
33
33
  viewTransition?: boolean;
34
34
  };
35
- export type ToOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''> = ToSubOptions<TRouteTree, TFrom, TTo> & {
35
+ export type ToOptions<TRouter extends AnyRouter = RegisteredRouter, TFrom extends RoutePaths<TRouter['routeTree']> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom, TMaskTo extends string = ''> = ToSubOptions<TRouter, TFrom, TTo> & {
36
36
  _fromLocation?: ParsedLocation;
37
- mask?: ToMaskOptions<TRouteTree, TMaskFrom, TMaskTo>;
37
+ mask?: ToMaskOptions<TRouter, TMaskFrom, TMaskTo>;
38
38
  };
39
- export type ToMaskOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TMaskFrom extends RoutePaths<TRouteTree> | string = string, TMaskTo extends string = ''> = ToSubOptions<TRouteTree, TMaskFrom, TMaskTo> & {
39
+ export type ToMaskOptions<TRouteTree extends AnyRouter = RegisteredRouter, TMaskFrom extends RoutePaths<TRouteTree['routeTree']> | string = string, TMaskTo extends string = ''> = ToSubOptions<TRouteTree, TMaskFrom, TMaskTo> & {
40
40
  unmaskOnReload?: boolean;
41
41
  };
42
- export type ToSubOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string = ''> = {
43
- to?: ToPathOption<TRouteTree, TFrom, TTo> & {};
42
+ export type ToSubOptions<TRouter extends AnyRouter = RegisteredRouter, TFrom extends RoutePaths<TRouter['routeTree']> | string = string, TTo extends string = ''> = {
43
+ to?: ToPathOption<TRouter, TFrom, TTo> & {};
44
44
  hash?: true | Updater<string>;
45
45
  state?: true | NonNullableUpdater<HistoryState>;
46
- from?: RoutePathsAutoComplete<TRouteTree, TFrom> & {};
47
- } & SearchParamOptions<TRouteTree, TFrom, TTo> & PathParamOptions<TRouteTree, TFrom, TTo>;
46
+ from?: RoutePathsAutoComplete<TRouter['routeTree'], TFrom> & {};
47
+ } & SearchParamOptions<TRouter, TFrom, TTo> & PathParamOptions<TRouter, TFrom, TTo>;
48
48
  type ParamsReducer<TFrom, TTo> = TTo | ((current: TFrom) => TTo);
49
49
  type ParamVariant = 'PATH' | 'SEARCH';
50
50
  type ExcludeRootSearchSchema<T, TExcluded = Exclude<T, RootSearchSchema>> = [
51
51
  TExcluded
52
52
  ] extends [never] ? {} : TExcluded;
53
- export type ResolveRoute<TRouteTree extends AnyRoute, TFrom, TTo, TPath = RemoveTrailingSlashes<string extends TFrom ? TTo : string extends TTo ? TFrom : ResolveRelativePath<TFrom, TTo>>> = TPath extends string ? RouteByPath<TRouteTree, `${TPath}/`> extends never ? RouteByPath<TRouteTree, TPath> : RouteByPath<TRouteTree, `${TPath}/`> : never;
53
+ export type ResolveRoute<TRouter extends AnyRouter, TFrom, TTo, TPath = string extends TFrom ? TTo : string extends TTo ? TFrom : ResolveRelativePath<TFrom, TTo>> = TPath extends string ? string extends TTo ? RouteByPath<TRouter['routeTree'], TPath> : RouteByToPath<TRouter, TPath> : never;
54
54
  type PostProcessParams<T, TParamVariant extends ParamVariant> = TParamVariant extends 'SEARCH' ? ExcludeRootSearchSchema<T> : T;
55
- type ResolveFromParams<TRouteTree extends AnyRoute, TParamVariant extends ParamVariant, TFrom, TFromRouteType extends 'allParams' | 'fullSearchSchema' = TParamVariant extends 'PATH' ? 'allParams' : 'fullSearchSchema'> = PostProcessParams<RouteByPath<TRouteTree, TFrom>['types'][TFromRouteType], TParamVariant>;
56
- type ResolveToParams<TRouteTree extends AnyRoute, TParamVariant extends ParamVariant, TFrom, TTo, TRoute extends AnyRoute = ResolveRoute<TRouteTree, TFrom, TTo>> = PostProcessParams<TRoute['types'][TParamVariant extends 'PATH' ? 'allParams' : 'fullSearchSchemaInput'], TParamVariant>;
57
- type ResolveRelativeToParams<TRouteTree extends AnyRoute, TParamVariant extends ParamVariant, TFrom, TTo, TToParams = ResolveToParams<TRouteTree, TParamVariant, TFrom, TTo>> = TParamVariant extends 'SEARCH' ? TToParams : string extends TFrom ? TToParams : MakeDifferenceOptional<ResolveFromParams<TRouteTree, TParamVariant, TFrom>, TToParams>;
58
- type MakeOptionalParams<TRouteTree extends AnyRoute, TParamVariant extends ParamVariant, TFrom, TTo> = TParamVariant extends 'SEARCH' ? {
59
- search?: true | (ParamsReducer<Expand<ResolveFromParams<TRouteTree, TParamVariant, TFrom>>, Expand<ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>>> & {});
55
+ type ResolveFromParams<TRouter extends AnyRouter, TParamVariant extends ParamVariant, TFrom> = PostProcessParams<RouteByPath<TRouter['routeTree'], TFrom>['types'][TParamVariant extends 'PATH' ? 'allParams' : 'fullSearchSchema'], TParamVariant>;
56
+ type ResolveToParams<TRouter extends AnyRouter, TParamVariant extends ParamVariant, TFrom, TTo, TRoute extends AnyRoute = ResolveRoute<TRouter, TFrom, TTo>> = PostProcessParams<TRoute['types'][TParamVariant extends 'PATH' ? 'allParams' : 'fullSearchSchemaInput'], TParamVariant>;
57
+ type ResolveRelativeToParams<TRouter extends AnyRouter, TParamVariant extends ParamVariant, TFrom, TTo, TToParams = ResolveToParams<TRouter, TParamVariant, TFrom, TTo>> = TParamVariant extends 'SEARCH' ? TToParams : string extends TFrom ? TToParams : MakeDifferenceOptional<ResolveFromParams<TRouter, TParamVariant, TFrom>, TToParams>;
58
+ type MakeOptionalParams<TRouter extends AnyRouter, TParamVariant extends ParamVariant, TFrom, TTo> = TParamVariant extends 'SEARCH' ? {
59
+ search?: true | (ParamsReducer<Expand<ResolveFromParams<TRouter, TParamVariant, TFrom>>, Expand<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>>> & {});
60
60
  } : {
61
- params?: true | (ParamsReducer<Expand<ResolveFromParams<TRouteTree, TParamVariant, TFrom>>, Expand<ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>>> & {});
61
+ params?: true | (ParamsReducer<Expand<ResolveFromParams<TRouter, TParamVariant, TFrom>>, Expand<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>>> & {});
62
62
  };
63
- type MakeRequiredParamsReducer<TRouteTree extends AnyRoute, TParamVariant extends ParamVariant, TFrom, TToParams, TFromParams = ResolveFromParams<TRouteTree, TParamVariant, TFrom>> = ([TFromParams] extends [WithoutEmpty<PickRequired<TToParams>>] ? true : never) | ParamsReducer<Expand<TFromParams>, TToParams>;
64
- export type MakeRequiredParams<TRouteTree extends AnyRoute, TParamVariant extends ParamVariant, TFrom, TTo> = TParamVariant extends 'SEARCH' ? {
65
- search: Expand<MakeRequiredParamsReducer<TRouteTree, TParamVariant, TFrom, Expand<ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>>>> & {};
63
+ type MakeRequiredParamsReducer<TRouter extends AnyRouter, TParamVariant extends ParamVariant, TFrom, TToParams, TFromParams = ResolveFromParams<TRouter, TParamVariant, TFrom>> = ([TFromParams] extends [WithoutEmpty<PickRequired<TToParams>>] ? true : never) | ParamsReducer<Expand<TFromParams>, TToParams>;
64
+ export type MakeRequiredParams<TRouter extends AnyRouter, TParamVariant extends ParamVariant, TFrom, TTo> = TParamVariant extends 'SEARCH' ? {
65
+ search: Expand<MakeRequiredParamsReducer<TRouter, TParamVariant, TFrom, Expand<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>>>> & {};
66
66
  } : {
67
- params: Expand<MakeRequiredParamsReducer<TRouteTree, TParamVariant, TFrom, Expand<ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>>>> & {};
67
+ params: Expand<MakeRequiredParamsReducer<TRouter, TParamVariant, TFrom, Expand<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>>>> & {};
68
68
  };
69
69
  export type IsRequiredParams<TParams> = keyof TParams extends infer K extends keyof TParams ? K extends any ? undefined extends TParams[K] ? never : true : never : never;
70
- export type IsRequired<TRouteTree extends AnyRoute, TParamVariant extends ParamVariant, TFrom, TTo> = string extends TTo ? string extends TFrom ? never : IsRequiredParams<ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>> : IsRequiredParams<ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>>;
71
- export type ParamOptions<TRouteTree extends AnyRoute, TFrom, TTo extends string, TParamVariant extends ParamVariant> = IsRequired<TRouteTree, TParamVariant, TFrom, TTo> extends never ? MakeOptionalParams<TRouteTree, TParamVariant, TFrom, TTo> : MakeRequiredParams<TRouteTree, TParamVariant, TFrom, TTo>;
72
- export type SearchParamOptions<TRouteTree extends AnyRoute, TFrom, TTo extends string> = ParamOptions<TRouteTree, TFrom, TTo, 'SEARCH'>;
73
- export type PathParamOptions<TRouteTree extends AnyRoute, TFrom, TTo extends string> = ParamOptions<TRouteTree, TFrom, TTo, 'PATH'>;
74
- export type ToPathOption<TRouteTree extends AnyRoute = AnyRoute, TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string = string> = CheckPath<TRouteTree, TTo, never, TFrom, TTo> | RelativeToPathAutoComplete<TRouteTree, NoInfer<TFrom> extends string ? NoInfer<TFrom> : '', NoInfer<TTo> & string>;
70
+ export type IsRequired<TRouter extends AnyRouter, TParamVariant extends ParamVariant, TFrom, TTo> = string extends TTo ? string extends TFrom ? never : IsRequiredParams<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>> : IsRequiredParams<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>>;
71
+ export type ParamOptions<TRouter extends AnyRouter, TFrom, TTo extends string, TParamVariant extends ParamVariant> = IsRequired<TRouter, TParamVariant, TFrom, TTo> extends never ? MakeOptionalParams<TRouter, TParamVariant, TFrom, TTo> : MakeRequiredParams<TRouter, TParamVariant, TFrom, TTo>;
72
+ export type SearchParamOptions<TRouter extends AnyRouter, TFrom, TTo extends string> = ParamOptions<TRouter, TFrom, TTo, 'SEARCH'>;
73
+ export type PathParamOptions<TRouter extends AnyRouter, TFrom, TTo extends string> = ParamOptions<TRouter, TFrom, TTo, 'PATH'>;
74
+ export type ToPathOption<TRouter extends AnyRouter = AnyRouter, TFrom extends RoutePaths<TRouter['routeTree']> | string = string, TTo extends string = string> = CheckPath<TRouter, TTo, never, TFrom, TTo> | RelativeToPathAutoComplete<TRouter, NoInfer<TFrom> extends string ? NoInfer<TFrom> : '', NoInfer<TTo> & string>;
75
75
  export interface ActiveOptions {
76
76
  exact?: boolean;
77
77
  includeHash?: boolean;
78
78
  includeSearch?: boolean;
79
79
  }
80
- export type LinkOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''> = NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {
80
+ export type LinkOptions<TRouter extends AnyRouter = RegisteredRouter, TFrom extends RoutePaths<TRouter['routeTree']> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom, TMaskTo extends string = ''> = NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & {
81
81
  target?: HTMLAnchorElement['target'];
82
82
  activeOptions?: ActiveOptions;
83
83
  preload?: false | 'intent';
84
84
  preloadDelay?: number;
85
85
  disabled?: boolean;
86
86
  };
87
- export type CheckPath<TRouteTree extends AnyRoute, TPass, TFail, TFrom, TTo> = ResolveRoute<TRouteTree, TFrom, TTo> extends infer TRoute extends AnyRoute ? [TRoute] extends [never] ? TFail : string extends TTo ? TPass : unknown extends TRoute['children'] ? TPass : TFail : TFail;
87
+ export type CheckPath<TRouter extends AnyRouter, TPass, TFail, TFrom, TTo> = ResolveRoute<TRouter, TFrom, TTo> extends never ? TFail : TPass;
88
88
  export type ResolveRelativePath<TFrom, TTo = '.'> = TFrom extends string ? TTo extends string ? TTo extends '.' ? TFrom : TTo extends `./` ? Join<[TFrom, '/']> : TTo extends `./${infer TRest}` ? ResolveRelativePath<TFrom, TRest> : TTo extends `/${infer TRest}` ? TTo : Split<TTo> extends ['..', ...infer ToRest] ? Split<TFrom> extends [...infer FromRest, infer FromTail] ? ToRest extends ['/'] ? Join<['/', ...FromRest, '/']> : ResolveRelativePath<Join<FromRest>, Join<ToRest>> : never : Split<TTo> extends ['.', ...infer ToRest] ? ToRest extends ['/'] ? Join<[TFrom, '/']> : ResolveRelativePath<TFrom, Join<ToRest>> : CleanPath<Join<['/', ...Split<TFrom>, ...Split<TTo>]>> : never : never;
89
- export declare function useLinkProps<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''>(options: UseLinkPropsOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>): React.AnchorHTMLAttributes<HTMLAnchorElement>;
90
- export type UseLinkPropsOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''> = ActiveLinkOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & React.AnchorHTMLAttributes<HTMLAnchorElement>;
91
- export type ActiveLinkOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''> = LinkOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {
89
+ export declare function useLinkProps<TRouter extends AnyRouter = RegisteredRouter, TFrom extends RoutePaths<TRouter['routeTree']> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom, TMaskTo extends string = ''>(options: UseLinkPropsOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>): React.AnchorHTMLAttributes<HTMLAnchorElement>;
90
+ export type UseLinkPropsOptions<TRouter extends AnyRouter = RegisteredRouter, TFrom extends RoutePaths<TRouter['routeTree']> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom, TMaskTo extends string = ''> = ActiveLinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & React.AnchorHTMLAttributes<HTMLAnchorElement>;
91
+ export type ActiveLinkOptions<TRouter extends AnyRouter = RegisteredRouter, TFrom extends RoutePaths<TRouter['routeTree']> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom, TMaskTo extends string = ''> = LinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & {
92
92
  activeProps?: React.AnchorHTMLAttributes<HTMLAnchorElement> | (() => React.AnchorHTMLAttributes<HTMLAnchorElement>);
93
93
  inactiveProps?: React.AnchorHTMLAttributes<HTMLAnchorElement> | (() => React.AnchorHTMLAttributes<HTMLAnchorElement>);
94
94
  };
95
- export type LinkProps<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string = string, TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''> = ActiveLinkOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {
95
+ export type LinkProps<TRouter extends AnyRouter = RegisteredRouter, TFrom extends RoutePaths<TRouter['routeTree']> | string = string, TTo extends string = string, TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom, TMaskTo extends string = ''> = ActiveLinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & {
96
96
  children?: React.ReactNode | ((state: {
97
97
  isActive: boolean;
98
98
  isTransitioning: boolean;
@@ -103,7 +103,7 @@ type LinkComponentProps<TComp> = React.PropsWithoutRef<TComp extends React.FC<in
103
103
  }> | React.Component<{
104
104
  ref: infer TRef;
105
105
  }> ? TRef : TComp extends keyof JSX.IntrinsicElements ? React.ComponentRef<TComp> : never>;
106
- export type LinkComponent<TComp> = <TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''>(props: LinkProps<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & LinkComponentProps<TComp>) => React.ReactElement;
106
+ export type LinkComponent<TComp> = <TRouter extends AnyRouter = RegisteredRouter, TFrom extends RoutePaths<TRouter['routeTree']> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom, TMaskTo extends string = ''>(props: LinkProps<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & LinkComponentProps<TComp>) => React.ReactElement;
107
107
  export declare function createLink<const TComp>(Comp: TComp): LinkComponent<TComp>;
108
108
  export declare const Link: LinkComponent<'a'>;
109
109
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"link.js","sources":["../../src/link.tsx"],"sourcesContent":["import * as React from 'react'\nimport { flushSync } from 'react-dom'\nimport { useMatch } from './Matches'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\nimport { deepEqual, exactPathTest, functionalUpdate } from './utils'\nimport type { ParsedLocation } from '.'\nimport type { HistoryState } from '@tanstack/history'\nimport type { Trim } from './fileRoute'\nimport type { AnyRoute, RootSearchSchema } from './route'\nimport type {\n RouteByPath,\n RouteLeaves,\n RoutePaths,\n RoutePathsAutoComplete,\n} from './routeInfo'\nimport type { RegisteredRouter } from './router'\nimport type {\n Expand,\n IsUnion,\n MakeDifferenceOptional,\n NoInfer,\n NonNullableUpdater,\n PickRequired,\n Updater,\n WithoutEmpty,\n} from './utils'\n\nexport type CleanPath<T extends string> = T extends `${infer L}//${infer R}`\n ? CleanPath<`${CleanPath<L>}/${CleanPath<R>}`>\n : T extends `${infer L}//`\n ? `${CleanPath<L>}/`\n : T extends `//${infer L}`\n ? `/${CleanPath<L>}`\n : T\n\nexport type Split<TValue, TIncludeTrailingSlash = true> = TValue extends unknown\n ? string extends TValue\n ? Array<string>\n : TValue extends string\n ? CleanPath<TValue> extends ''\n ? []\n : TIncludeTrailingSlash extends true\n ? CleanPath<TValue> extends `${infer T}/`\n ? [...Split<T>, '/']\n : CleanPath<TValue> extends `/${infer U}`\n ? Split<U>\n : CleanPath<TValue> extends `${infer T}/${infer U}`\n ? [...Split<T>, ...Split<U>]\n : [TValue]\n : CleanPath<TValue> extends `${infer T}/${infer U}`\n ? [...Split<T>, ...Split<U>]\n : TValue extends string\n ? [TValue]\n : never\n : never\n : never\n\nexport type ParsePathParams<T extends string> = keyof {\n [K in Trim<Split<T>[number], '_'> as K extends `$${infer L}`\n ? L extends ''\n ? '_splat'\n : L\n : never]: K\n}\n\nexport type Join<T, TDelimiter extends string = '/'> = T extends []\n ? ''\n : T extends [infer L extends string]\n ? L\n : T extends [\n infer L extends string,\n ...infer Tail extends [...Array<string>],\n ]\n ? CleanPath<`${L}${TDelimiter}${Join<Tail>}`>\n : never\n\nexport type Last<T extends Array<any>> = T extends [...infer _, infer L]\n ? L\n : never\n\nexport type RemoveTrailingSlashes<T> = T extends `${infer R}/`\n ? RemoveTrailingSlashes<R>\n : T\n\nexport type RemoveLeadingSlashes<T> = T extends `/${infer R}`\n ? RemoveLeadingSlashes<R>\n : T\n\nexport type ResolvePaths<TRouteTree extends AnyRoute, TSearchPath> =\n RouteByPath<TRouteTree, RemoveTrailingSlashes<TSearchPath>> extends never\n ? RouteLeaves<TRouteTree>\n : RouteLeaves<RouteByPath<TRouteTree, RemoveTrailingSlashes<TSearchPath>>>\n\nexport type SearchPaths<\n TRouteTree extends AnyRoute,\n TSearchPath extends string,\n TPaths = ResolvePaths<TRouteTree, TSearchPath>,\n> = TPaths extends `${RemoveTrailingSlashes<TSearchPath>}/${infer TRest}`\n ? TRest\n : never\n\nexport type SearchRelativePathAutoComplete<\n TRouteTree extends AnyRoute,\n TTo extends string,\n TSearchPath extends string,\n> = `${TTo}/${SearchPaths<TRouteTree, TSearchPath>}`\n\nexport type RelativeToParentPathAutoComplete<\n TRouteTree extends AnyRoute,\n TFrom extends string,\n TTo extends string,\n TResolvedPath extends string = RemoveTrailingSlashes<\n ResolveRelativePath<TFrom, TTo>\n >,\n> =\n | SearchRelativePathAutoComplete<TRouteTree, TTo, TResolvedPath>\n | (TResolvedPath extends '' ? never : `${TTo}/../`)\n\nexport type RelativeToCurrentPathAutoComplete<\n TRouteTree extends AnyRoute,\n TFrom extends string,\n TTo extends string,\n TRestTo extends string,\n TResolvedPath extends\n string = RemoveTrailingSlashes<`${RemoveTrailingSlashes<TFrom>}/${RemoveLeadingSlashes<TRestTo>}`>,\n> = SearchRelativePathAutoComplete<TRouteTree, TTo, TResolvedPath>\n\nexport type AbsolutePathAutoComplete<\n TRouteTree extends AnyRoute,\n TFrom extends string,\n> =\n | (string extends TFrom\n ? './'\n : TFrom extends `/`\n ? never\n : SearchPaths<TRouteTree, TFrom> extends ''\n ? never\n : './')\n | (string extends TFrom ? '../' : TFrom extends `/` ? never : '../')\n | RouteLeaves<TRouteTree>\n | (TFrom extends '/' ? never : SearchPaths<TRouteTree, TFrom>)\n\nexport type RelativeToPathAutoComplete<\n TRouteTree extends AnyRoute,\n TFrom extends string,\n TTo extends string,\n> = TTo extends `..${string}`\n ? RelativeToParentPathAutoComplete<\n TRouteTree,\n TFrom,\n RemoveTrailingSlashes<TTo>\n >\n : TTo extends `./${infer TRestTTo}`\n ? RelativeToCurrentPathAutoComplete<\n TRouteTree,\n TFrom,\n RemoveTrailingSlashes<TTo>,\n TRestTTo\n >\n : AbsolutePathAutoComplete<TRouteTree, TFrom>\n\nexport type NavigateOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n> = ToOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {\n // `replace` is a boolean that determines whether the navigation should replace the current history entry or push a new one.\n replace?: boolean\n resetScroll?: boolean\n /** @deprecated All navigations now use startTransition under the hood */\n startTransition?: boolean\n // if set to `true`, the router will wrap the resulting navigation in a document.startViewTransition() call.\n viewTransition?: boolean\n}\n\nexport type ToOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n> = ToSubOptions<TRouteTree, TFrom, TTo> & {\n _fromLocation?: ParsedLocation\n mask?: ToMaskOptions<TRouteTree, TMaskFrom, TMaskTo>\n}\n\nexport type ToMaskOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TMaskFrom extends RoutePaths<TRouteTree> | string = string,\n TMaskTo extends string = '',\n> = ToSubOptions<TRouteTree, TMaskFrom, TMaskTo> & {\n unmaskOnReload?: boolean\n}\n\nexport type ToSubOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n> = {\n to?: ToPathOption<TRouteTree, TFrom, TTo> & {}\n hash?: true | Updater<string>\n state?: true | NonNullableUpdater<HistoryState>\n // The source route path. This is automatically set when using route-level APIs, but for type-safe relative routing on the router itself, this is required\n from?: RoutePathsAutoComplete<TRouteTree, TFrom> & {}\n // // When using relative route paths, this option forces resolution from the current path, instead of the route API's path or `from` path\n} & SearchParamOptions<TRouteTree, TFrom, TTo> &\n PathParamOptions<TRouteTree, TFrom, TTo>\n\ntype ParamsReducer<TFrom, TTo> = TTo | ((current: TFrom) => TTo)\n\ntype ParamVariant = 'PATH' | 'SEARCH'\n\ntype ExcludeRootSearchSchema<T, TExcluded = Exclude<T, RootSearchSchema>> = [\n TExcluded,\n] extends [never]\n ? {}\n : TExcluded\n\nexport type ResolveRoute<\n TRouteTree extends AnyRoute,\n TFrom,\n TTo,\n TPath = RemoveTrailingSlashes<\n string extends TFrom\n ? TTo\n : string extends TTo\n ? TFrom\n : ResolveRelativePath<TFrom, TTo>\n >,\n> = TPath extends string\n ? RouteByPath<TRouteTree, `${TPath}/`> extends never\n ? RouteByPath<TRouteTree, TPath>\n : RouteByPath<TRouteTree, `${TPath}/`>\n : never\n\ntype PostProcessParams<\n T,\n TParamVariant extends ParamVariant,\n> = TParamVariant extends 'SEARCH' ? ExcludeRootSearchSchema<T> : T\n\ntype ResolveFromParams<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TFromRouteType extends\n | 'allParams'\n | 'fullSearchSchema' = TParamVariant extends 'PATH'\n ? 'allParams'\n : 'fullSearchSchema',\n> = PostProcessParams<\n RouteByPath<TRouteTree, TFrom>['types'][TFromRouteType],\n TParamVariant\n>\n\ntype ResolveToParams<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n TRoute extends AnyRoute = ResolveRoute<TRouteTree, TFrom, TTo>,\n> = PostProcessParams<\n TRoute['types'][TParamVariant extends 'PATH'\n ? 'allParams'\n : 'fullSearchSchemaInput'],\n TParamVariant\n>\n\ntype ResolveRelativeToParams<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n TToParams = ResolveToParams<TRouteTree, TParamVariant, TFrom, TTo>,\n> = TParamVariant extends 'SEARCH'\n ? TToParams\n : string extends TFrom\n ? TToParams\n : MakeDifferenceOptional<\n ResolveFromParams<TRouteTree, TParamVariant, TFrom>,\n TToParams\n >\n\ntype MakeOptionalParams<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> = TParamVariant extends 'SEARCH'\n ? {\n search?:\n | true\n | (ParamsReducer<\n Expand<ResolveFromParams<TRouteTree, TParamVariant, TFrom>>,\n Expand<\n ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>\n >\n > & {})\n }\n : {\n params?:\n | true\n | (ParamsReducer<\n Expand<ResolveFromParams<TRouteTree, TParamVariant, TFrom>>,\n Expand<\n ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>\n >\n > & {})\n }\n\ntype MakeRequiredParamsReducer<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TToParams,\n TFromParams = ResolveFromParams<TRouteTree, TParamVariant, TFrom>,\n> =\n | ([TFromParams] extends [WithoutEmpty<PickRequired<TToParams>>]\n ? true\n : never)\n | ParamsReducer<Expand<TFromParams>, TToParams>\n\nexport type MakeRequiredParams<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> = TParamVariant extends 'SEARCH'\n ? {\n search: Expand<\n MakeRequiredParamsReducer<\n TRouteTree,\n TParamVariant,\n TFrom,\n Expand<ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>>\n >\n > & {}\n }\n : {\n params: Expand<\n MakeRequiredParamsReducer<\n TRouteTree,\n TParamVariant,\n TFrom,\n Expand<ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>>\n >\n > & {}\n }\n\nexport type IsRequiredParams<TParams> = keyof TParams extends infer K extends\n keyof TParams\n ? K extends any\n ? undefined extends TParams[K]\n ? never\n : true\n : never\n : never\n\nexport type IsRequired<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> = string extends TTo\n ? string extends TFrom\n ? never\n : IsRequiredParams<\n ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>\n >\n : IsRequiredParams<\n ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>\n >\n\nexport type ParamOptions<\n TRouteTree extends AnyRoute,\n TFrom,\n TTo extends string,\n TParamVariant extends ParamVariant,\n> =\n IsRequired<TRouteTree, TParamVariant, TFrom, TTo> extends never\n ? MakeOptionalParams<TRouteTree, TParamVariant, TFrom, TTo>\n : MakeRequiredParams<TRouteTree, TParamVariant, TFrom, TTo>\n\nexport type SearchParamOptions<\n TRouteTree extends AnyRoute,\n TFrom,\n TTo extends string,\n> = ParamOptions<TRouteTree, TFrom, TTo, 'SEARCH'>\n\nexport type PathParamOptions<\n TRouteTree extends AnyRoute,\n TFrom,\n TTo extends string,\n> = ParamOptions<TRouteTree, TFrom, TTo, 'PATH'>\n\nexport type ToPathOption<\n TRouteTree extends AnyRoute = AnyRoute,\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = string,\n> =\n | CheckPath<TRouteTree, TTo, never, TFrom, TTo>\n | RelativeToPathAutoComplete<\n TRouteTree,\n NoInfer<TFrom> extends string ? NoInfer<TFrom> : '',\n NoInfer<TTo> & string\n >\n\nexport interface ActiveOptions {\n exact?: boolean\n includeHash?: boolean\n includeSearch?: boolean\n}\n\nexport type LinkOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n> = NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {\n // The standard anchor tag target attribute\n target?: HTMLAnchorElement['target']\n // Defaults to `{ exact: false, includeHash: false }`\n activeOptions?: ActiveOptions\n // If set, will preload the linked route on hover and cache it for this many milliseconds in hopes that the user will eventually navigate there.\n preload?: false | 'intent'\n // Delay intent preloading by this many milliseconds. If the intent exits before this delay, the preload will be cancelled.\n preloadDelay?: number\n // If true, will render the link without the href attribute\n disabled?: boolean\n}\n\nexport type CheckPath<TRouteTree extends AnyRoute, TPass, TFail, TFrom, TTo> =\n ResolveRoute<TRouteTree, TFrom, TTo> extends infer TRoute extends AnyRoute\n ? [TRoute] extends [never]\n ? TFail\n : string extends TTo\n ? TPass\n : unknown extends TRoute['children']\n ? TPass\n : TFail\n : TFail\n\nexport type ResolveRelativePath<TFrom, TTo = '.'> = TFrom extends string\n ? TTo extends string\n ? TTo extends '.'\n ? TFrom\n : TTo extends `./`\n ? Join<[TFrom, '/']>\n : TTo extends `./${infer TRest}`\n ? ResolveRelativePath<TFrom, TRest>\n : TTo extends `/${infer TRest}`\n ? TTo\n : Split<TTo> extends ['..', ...infer ToRest]\n ? Split<TFrom> extends [...infer FromRest, infer FromTail]\n ? ToRest extends ['/']\n ? Join<['/', ...FromRest, '/']>\n : ResolveRelativePath<Join<FromRest>, Join<ToRest>>\n : never\n : Split<TTo> extends ['.', ...infer ToRest]\n ? ToRest extends ['/']\n ? Join<[TFrom, '/']>\n : ResolveRelativePath<TFrom, Join<ToRest>>\n : CleanPath<Join<['/', ...Split<TFrom>, ...Split<TTo>]>>\n : never\n : never\n\n// type Test1 = ResolveRelativePath<'/', '/posts'>\n// // ^?\n// type Test4 = ResolveRelativePath<'/posts/1/comments', '../..'>\n// // ^?\n// type Test5 = ResolveRelativePath<'/posts/1/comments', '../../..'>\n// // ^?\n// type Test6 = ResolveRelativePath<'/posts/1/comments', './1'>\n// // ^?\n// type Test7 = ResolveRelativePath<'/posts/1/comments', './1/2'>\n// // ^?\n// type Test8 = ResolveRelativePath<'/posts/1/comments', '../edit'>\n// // ^?\n// type Test9 = ResolveRelativePath<'/posts/1/comments', '1'>\n// // ^?\n// type Test10 = ResolveRelativePath<'/posts/1/comments', './1'>\n// // ^?\n// type Test11 = ResolveRelativePath<'/posts/1/comments', './1/2'>\n// // ^?\n\ntype LinkCurrentTargetElement = {\n preloadTimeout?: null | ReturnType<typeof setTimeout>\n}\n\nconst preloadWarning = 'Error preloading route! ☝️'\n\nexport function useLinkProps<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n>(\n options: UseLinkPropsOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>,\n): React.AnchorHTMLAttributes<HTMLAnchorElement> {\n const router = useRouter()\n const matchPathname = useMatch({\n strict: false,\n select: (s) => s.pathname,\n })\n const [isTransitioning, setIsTransitioning] = React.useState(false)\n\n const {\n // custom props\n activeProps = () => ({ className: 'active' }),\n inactiveProps = () => ({}),\n activeOptions,\n hash,\n search,\n params,\n to,\n state,\n mask,\n preload: userPreload,\n preloadDelay: userPreloadDelay,\n replace,\n startTransition,\n resetScroll,\n viewTransition,\n // element props\n children,\n target,\n disabled,\n style,\n className,\n onClick,\n onFocus,\n onMouseEnter,\n onMouseLeave,\n onTouchStart,\n ...rest\n } = options\n\n // If this link simply reloads the current route,\n // make sure it has a new key so it will trigger a data refresh\n\n // If this `to` is a valid external URL, return\n // null for LinkUtils\n\n const dest = {\n ...(options.to && { from: matchPathname }),\n ...options,\n }\n\n let type: 'internal' | 'external' = 'internal'\n\n try {\n new URL(`${to}`)\n type = 'external'\n } catch {}\n\n const next = router.buildLocation(dest as any)\n const preload = userPreload ?? router.options.defaultPreload\n const preloadDelay =\n userPreloadDelay ?? router.options.defaultPreloadDelay ?? 0\n\n const isActive = useRouterState({\n select: (s) => {\n // Compare path/hash for matches\n const currentPathSplit = s.location.pathname.split('/')\n const nextPathSplit = next.pathname.split('/')\n const pathIsFuzzyEqual = nextPathSplit.every(\n (d, i) => d === currentPathSplit[i],\n )\n // Combine the matches based on user router.options\n const pathTest = activeOptions?.exact\n ? exactPathTest(s.location.pathname, next.pathname)\n : pathIsFuzzyEqual\n const hashTest = activeOptions?.includeHash\n ? s.location.hash === next.hash\n : true\n const searchTest =\n activeOptions?.includeSearch ?? true\n ? deepEqual(s.location.search, next.search, !activeOptions?.exact)\n : true\n\n // The final \"active\" test\n return pathTest && hashTest && searchTest\n },\n })\n\n if (type === 'external') {\n return {\n ...rest,\n type,\n href: to,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n ...(onClick && { onClick }),\n ...(onFocus && { onFocus }),\n ...(onMouseEnter && { onMouseEnter }),\n ...(onMouseLeave && { onMouseLeave }),\n ...(onTouchStart && { onTouchStart }),\n }\n }\n\n // The click handler\n const handleClick = (e: MouseEvent) => {\n if (\n !disabled &&\n !isCtrlEvent(e) &&\n !e.defaultPrevented &&\n (!target || target === '_self') &&\n e.button === 0\n ) {\n e.preventDefault()\n\n flushSync(() => {\n setIsTransitioning(true)\n })\n\n const unsub = router.subscribe('onResolved', () => {\n unsub()\n setIsTransitioning(false)\n })\n\n // All is well? Navigate!\n router.commitLocation({\n ...next,\n replace,\n resetScroll,\n startTransition,\n viewTransition,\n })\n }\n }\n\n const doPreload = () => {\n router.preloadRoute(dest as any).catch((err) => {\n console.warn(err)\n console.warn(preloadWarning)\n })\n }\n\n // The click handler\n const handleFocus = (e: MouseEvent) => {\n if (disabled) return\n if (preload) {\n doPreload()\n }\n }\n\n const handleTouchStart = handleFocus\n\n const handleEnter = (e: MouseEvent) => {\n if (disabled) return\n const eventTarget = (e.target || {}) as LinkCurrentTargetElement\n\n if (preload) {\n if (eventTarget.preloadTimeout) {\n return\n }\n\n eventTarget.preloadTimeout = setTimeout(() => {\n eventTarget.preloadTimeout = null\n doPreload()\n }, preloadDelay)\n }\n }\n\n const handleLeave = (e: MouseEvent) => {\n if (disabled) return\n const eventTarget = (e.target || {}) as LinkCurrentTargetElement\n\n if (eventTarget.preloadTimeout) {\n clearTimeout(eventTarget.preloadTimeout)\n eventTarget.preloadTimeout = null\n }\n }\n\n const composeHandlers =\n (handlers: Array<undefined | ((e: any) => void)>) =>\n (e: { persist?: () => void; defaultPrevented: boolean }) => {\n e.persist?.()\n handlers.filter(Boolean).forEach((handler) => {\n if (e.defaultPrevented) return\n handler!(e)\n })\n }\n\n // Get the active props\n const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> = isActive\n ? functionalUpdate(activeProps as any, {}) ?? {}\n : {}\n\n // Get the inactive props\n const resolvedInactiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive ? {} : functionalUpdate(inactiveProps, {})\n\n const resolvedClassName = [\n className,\n resolvedActiveProps.className,\n resolvedInactiveProps.className,\n ]\n .filter(Boolean)\n .join(' ')\n\n const resolvedStyle = {\n ...style,\n ...resolvedActiveProps.style,\n ...resolvedInactiveProps.style,\n }\n\n return {\n ...resolvedActiveProps,\n ...resolvedInactiveProps,\n ...rest,\n href: disabled\n ? undefined\n : next.maskedLocation\n ? router.history.createHref(next.maskedLocation.href)\n : router.history.createHref(next.href),\n onClick: composeHandlers([onClick, handleClick]),\n onFocus: composeHandlers([onFocus, handleFocus]),\n onMouseEnter: composeHandlers([onMouseEnter, handleEnter]),\n onMouseLeave: composeHandlers([onMouseLeave, handleLeave]),\n onTouchStart: composeHandlers([onTouchStart, handleTouchStart]),\n target,\n ...(Object.keys(resolvedStyle).length && { style: resolvedStyle }),\n ...(resolvedClassName && { className: resolvedClassName }),\n ...(disabled && {\n role: 'link',\n 'aria-disabled': true,\n }),\n ...(isActive && { 'data-status': 'active', 'aria-current': 'page' }),\n ...(isTransitioning && { 'data-transitioning': 'transitioning' }),\n }\n}\n\nexport type UseLinkPropsOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n> = ActiveLinkOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> &\n React.AnchorHTMLAttributes<HTMLAnchorElement>\n\nexport type ActiveLinkOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n> = LinkOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {\n // A function that returns additional props for the `active` state of this link. These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)\n activeProps?:\n | React.AnchorHTMLAttributes<HTMLAnchorElement>\n | (() => React.AnchorHTMLAttributes<HTMLAnchorElement>)\n // A function that returns additional props for the `inactive` state of this link. These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)\n inactiveProps?:\n | React.AnchorHTMLAttributes<HTMLAnchorElement>\n | (() => React.AnchorHTMLAttributes<HTMLAnchorElement>)\n}\n\nexport type LinkProps<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = string,\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n> = ActiveLinkOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {\n // If a function is passed as a child, it will be given the `isActive` boolean to aid in further styling on the element it returns\n children?:\n | React.ReactNode\n | ((state: {\n isActive: boolean\n isTransitioning: boolean\n }) => React.ReactNode)\n}\n\ntype LinkComponentProps<TComp> = React.PropsWithoutRef<\n TComp extends React.FC<infer TProps> | React.Component<infer TProps>\n ? TProps\n : TComp extends keyof JSX.IntrinsicElements\n ? Omit<React.HTMLProps<TComp>, 'children' | 'preload'>\n : never\n> &\n React.RefAttributes<\n TComp extends\n | React.FC<{ ref: infer TRef }>\n | React.Component<{ ref: infer TRef }>\n ? TRef\n : TComp extends keyof JSX.IntrinsicElements\n ? React.ComponentRef<TComp>\n : never\n >\n\nexport type LinkComponent<TComp> = <\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n>(\n props: LinkProps<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> &\n LinkComponentProps<TComp>,\n) => React.ReactElement\n\nexport function createLink<const TComp>(Comp: TComp): LinkComponent<TComp> {\n return React.forwardRef(function CreatedLink(props, ref) {\n return <Link {...(props as any)} _asChild={Comp} ref={ref} />\n }) as any\n}\n\nexport const Link: LinkComponent<'a'> = React.forwardRef((props: any, ref) => {\n const { _asChild, ...rest } = props\n const { type, ...linkProps } = useLinkProps(rest)\n\n const children =\n typeof rest.children === 'function'\n ? rest.children({\n isActive: (linkProps as any)['data-status'] === 'active',\n })\n : rest.children\n\n return React.createElement(\n _asChild ? _asChild : 'a',\n {\n ...linkProps,\n ref,\n },\n children,\n )\n}) as any\n\nfunction isCtrlEvent(e: MouseEvent) {\n return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)\n}\n"],"names":[],"mappings":";;;;;;;AA4eA,MAAM,iBAAiB;AAEhB,SAAS,aAOd,SAC+C;AAC/C,QAAM,SAAS;AACf,QAAM,gBAAgB,SAAS;AAAA,IAC7B,QAAQ;AAAA,IACR,QAAQ,CAAC,MAAM,EAAE;AAAA,EAAA,CAClB;AACD,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,MAAM,SAAS,KAAK;AAE5D,QAAA;AAAA;AAAA,IAEJ,cAAc,OAAO,EAAE,WAAW;IAClC,gBAAgB,OAAO,CAAA;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACD,IAAA;AAQJ,QAAM,OAAO;AAAA,IACX,GAAI,QAAQ,MAAM,EAAE,MAAM,cAAc;AAAA,IACxC,GAAG;AAAA,EAAA;AAGL,MAAI,OAAgC;AAEhC,MAAA;AACE,QAAA,IAAI,GAAG,EAAE,EAAE;AACR,WAAA;AAAA,EAAA,QACD;AAAA,EAAC;AAEH,QAAA,OAAO,OAAO,cAAc,IAAW;AACvC,QAAA,UAAU,eAAe,OAAO,QAAQ;AAC9C,QAAM,eACJ,oBAAoB,OAAO,QAAQ,uBAAuB;AAE5D,QAAM,WAAW,eAAe;AAAA,IAC9B,QAAQ,CAAC,MAAM;AAEb,YAAM,mBAAmB,EAAE,SAAS,SAAS,MAAM,GAAG;AACtD,YAAM,gBAAgB,KAAK,SAAS,MAAM,GAAG;AAC7C,YAAM,mBAAmB,cAAc;AAAA,QACrC,CAAC,GAAG,MAAM,MAAM,iBAAiB,CAAC;AAAA,MAAA;AAG9B,YAAA,YAAW,+CAAe,SAC5B,cAAc,EAAE,SAAS,UAAU,KAAK,QAAQ,IAChD;AACJ,YAAM,YAAW,+CAAe,eAC5B,EAAE,SAAS,SAAS,KAAK,OACzB;AACJ,YAAM,cACJ,+CAAe,kBAAiB,OAC5B,UAAU,EAAE,SAAS,QAAQ,KAAK,QAAQ,EAAC,+CAAe,MAAK,IAC/D;AAGN,aAAO,YAAY,YAAY;AAAA,IACjC;AAAA,EAAA,CACD;AAED,MAAI,SAAS,YAAY;AAChB,WAAA;AAAA,MACL,GAAG;AAAA,MACH;AAAA,MACA,MAAM;AAAA,MACN,GAAI,YAAY,EAAE,SAAS;AAAA,MAC3B,GAAI,UAAU,EAAE,OAAO;AAAA,MACvB,GAAI,YAAY,EAAE,SAAS;AAAA,MAC3B,GAAI,SAAS,EAAE,MAAM;AAAA,MACrB,GAAI,aAAa,EAAE,UAAU;AAAA,MAC7B,GAAI,WAAW,EAAE,QAAQ;AAAA,MACzB,GAAI,WAAW,EAAE,QAAQ;AAAA,MACzB,GAAI,gBAAgB,EAAE,aAAa;AAAA,MACnC,GAAI,gBAAgB,EAAE,aAAa;AAAA,MACnC,GAAI,gBAAgB,EAAE,aAAa;AAAA,IAAA;AAAA,EAEvC;AAGM,QAAA,cAAc,CAAC,MAAkB;AACrC,QACE,CAAC,YACD,CAAC,YAAY,CAAC,KACd,CAAC,EAAE,qBACF,CAAC,UAAU,WAAW,YACvB,EAAE,WAAW,GACb;AACA,QAAE,eAAe;AAEjB,gBAAU,MAAM;AACd,2BAAmB,IAAI;AAAA,MAAA,CACxB;AAED,YAAM,QAAQ,OAAO,UAAU,cAAc,MAAM;AAC3C;AACN,2BAAmB,KAAK;AAAA,MAAA,CACzB;AAGD,aAAO,eAAe;AAAA,QACpB,GAAG;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACD;AAAA,IACH;AAAA,EAAA;AAGF,QAAM,YAAY,MAAM;AACtB,WAAO,aAAa,IAAW,EAAE,MAAM,CAAC,QAAQ;AAC9C,cAAQ,KAAK,GAAG;AAChB,cAAQ,KAAK,cAAc;AAAA,IAAA,CAC5B;AAAA,EAAA;AAIG,QAAA,cAAc,CAAC,MAAkB;AACjC,QAAA;AAAU;AACd,QAAI,SAAS;AACD;IACZ;AAAA,EAAA;AAGF,QAAM,mBAAmB;AAEnB,QAAA,cAAc,CAAC,MAAkB;AACjC,QAAA;AAAU;AACR,UAAA,cAAe,EAAE,UAAU;AAEjC,QAAI,SAAS;AACX,UAAI,YAAY,gBAAgB;AAC9B;AAAA,MACF;AAEY,kBAAA,iBAAiB,WAAW,MAAM;AAC5C,oBAAY,iBAAiB;AACnB;SACT,YAAY;AAAA,IACjB;AAAA,EAAA;AAGI,QAAA,cAAc,CAAC,MAAkB;AACjC,QAAA;AAAU;AACR,UAAA,cAAe,EAAE,UAAU;AAEjC,QAAI,YAAY,gBAAgB;AAC9B,mBAAa,YAAY,cAAc;AACvC,kBAAY,iBAAiB;AAAA,IAC/B;AAAA,EAAA;AAGF,QAAM,kBACJ,CAAC,aACD,CAAC,MAA2D;;AAC1D,YAAE,YAAF;AACA,aAAS,OAAO,OAAO,EAAE,QAAQ,CAAC,YAAY;AAC5C,UAAI,EAAE;AAAkB;AACxB,cAAS,CAAC;AAAA,IAAA,CACX;AAAA,EAAA;AAIC,QAAA,sBAA+D,WACjE,iBAAiB,aAAoB,EAAE,KAAK,CAAC,IAC7C;AAGJ,QAAM,wBACJ,WAAW,CAAA,IAAK,iBAAiB,eAAe,CAAA,CAAE;AAEpD,QAAM,oBAAoB;AAAA,IACxB;AAAA,IACA,oBAAoB;AAAA,IACpB,sBAAsB;AAAA,EAErB,EAAA,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,QAAM,gBAAgB;AAAA,IACpB,GAAG;AAAA,IACH,GAAG,oBAAoB;AAAA,IACvB,GAAG,sBAAsB;AAAA,EAAA;AAGpB,SAAA;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,MAAM,WACF,SACA,KAAK,iBACH,OAAO,QAAQ,WAAW,KAAK,eAAe,IAAI,IAClD,OAAO,QAAQ,WAAW,KAAK,IAAI;AAAA,IACzC,SAAS,gBAAgB,CAAC,SAAS,WAAW,CAAC;AAAA,IAC/C,SAAS,gBAAgB,CAAC,SAAS,WAAW,CAAC;AAAA,IAC/C,cAAc,gBAAgB,CAAC,cAAc,WAAW,CAAC;AAAA,IACzD,cAAc,gBAAgB,CAAC,cAAc,WAAW,CAAC;AAAA,IACzD,cAAc,gBAAgB,CAAC,cAAc,gBAAgB,CAAC;AAAA,IAC9D;AAAA,IACA,GAAI,OAAO,KAAK,aAAa,EAAE,UAAU,EAAE,OAAO,cAAc;AAAA,IAChE,GAAI,qBAAqB,EAAE,WAAW,kBAAkB;AAAA,IACxD,GAAI,YAAY;AAAA,MACd,MAAM;AAAA,MACN,iBAAiB;AAAA,IACnB;AAAA,IACA,GAAI,YAAY,EAAE,eAAe,UAAU,gBAAgB,OAAO;AAAA,IAClE,GAAI,mBAAmB,EAAE,sBAAsB,gBAAgB;AAAA,EAAA;AAEnE;AAwEO,SAAS,WAAwB,MAAmC;AACzE,SAAO,MAAM,WAAW,SAAS,YAAY,OAAO,KAAK;AACvD,+BAAQ,MAAM,EAAA,GAAI,OAAe,UAAU,MAAM,IAAU,CAAA;AAAA,EAAA,CAC5D;AACH;AAEO,MAAM,OAA2B,MAAM,WAAW,CAAC,OAAY,QAAQ;AAC5E,QAAM,EAAE,UAAU,GAAG,KAAA,IAAS;AAC9B,QAAM,EAAE,MAAM,GAAG,UAAU,IAAI,aAAa,IAAI;AAEhD,QAAM,WACJ,OAAO,KAAK,aAAa,aACrB,KAAK,SAAS;AAAA,IACZ,UAAW,UAAkB,aAAa,MAAM;AAAA,EAAA,CACjD,IACD,KAAK;AAEX,SAAO,MAAM;AAAA,IACX,WAAW,WAAW;AAAA,IACtB;AAAA,MACE,GAAG;AAAA,MACH;AAAA,IACF;AAAA,IACA;AAAA,EAAA;AAEJ,CAAC;AAED,SAAS,YAAY,GAAe;AAC3B,SAAA,CAAC,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE;AACpD;"}
1
+ {"version":3,"file":"link.js","sources":["../../src/link.tsx"],"sourcesContent":["import * as React from 'react'\nimport { flushSync } from 'react-dom'\nimport { useMatch } from './Matches'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\nimport { deepEqual, exactPathTest, functionalUpdate } from './utils'\nimport type { AnyRouter, ParsedLocation } from '.'\nimport type { HistoryState } from '@tanstack/history'\nimport type { Trim } from './fileRoute'\nimport type { AnyRoute, RootSearchSchema } from './route'\nimport type {\n RouteByPath,\n RouteByToPath,\n RoutePaths,\n RoutePathsAutoComplete,\n RouteToPath,\n} from './routeInfo'\nimport type { RegisteredRouter } from './router'\nimport type {\n Expand,\n MakeDifferenceOptional,\n NoInfer,\n NonNullableUpdater,\n PickRequired,\n Updater,\n WithoutEmpty,\n} from './utils'\n\nexport type CleanPath<T extends string> = T extends `${infer L}//${infer R}`\n ? CleanPath<`${CleanPath<L>}/${CleanPath<R>}`>\n : T extends `${infer L}//`\n ? `${CleanPath<L>}/`\n : T extends `//${infer L}`\n ? `/${CleanPath<L>}`\n : T\n\nexport type Split<TValue, TIncludeTrailingSlash = true> = TValue extends unknown\n ? string extends TValue\n ? Array<string>\n : TValue extends string\n ? CleanPath<TValue> extends ''\n ? []\n : TIncludeTrailingSlash extends true\n ? CleanPath<TValue> extends `${infer T}/`\n ? [...Split<T>, '/']\n : CleanPath<TValue> extends `/${infer U}`\n ? Split<U>\n : CleanPath<TValue> extends `${infer T}/${infer U}`\n ? [...Split<T>, ...Split<U>]\n : [TValue]\n : CleanPath<TValue> extends `${infer T}/${infer U}`\n ? [...Split<T>, ...Split<U>]\n : TValue extends string\n ? [TValue]\n : never\n : never\n : never\n\nexport type ParsePathParams<T extends string> = keyof {\n [K in Trim<Split<T>[number], '_'> as K extends `$${infer L}`\n ? L extends ''\n ? '_splat'\n : L\n : never]: K\n}\n\nexport type Join<T, TDelimiter extends string = '/'> = T extends []\n ? ''\n : T extends [infer L extends string]\n ? L\n : T extends [\n infer L extends string,\n ...infer Tail extends [...Array<string>],\n ]\n ? CleanPath<`${L}${TDelimiter}${Join<Tail>}`>\n : never\n\nexport type Last<T extends Array<any>> = T extends [...infer _, infer L]\n ? L\n : never\n\nexport type RemoveTrailingSlashes<T> = T extends `${infer R}/` ? R : T\n\nexport type RemoveLeadingSlashes<T> = T extends `/${infer R}` ? R : T\n\nexport type ResolvePaths<TRouter extends AnyRouter, TSearchPath> =\n RouteByPath<\n TRouter['routeTree'],\n RemoveTrailingSlashes<TSearchPath>\n > extends never\n ? RouteToPath<TRouter, TRouter['routeTree']>\n : RouteToPath<\n TRouter,\n RouteByPath<TRouter['routeTree'], RemoveTrailingSlashes<TSearchPath>>\n >\n\nexport type SearchPaths<\n TRouter extends AnyRouter,\n TSearchPath extends string,\n TPaths = ResolvePaths<TRouter, TSearchPath>,\n> = TPaths extends `${RemoveTrailingSlashes<TSearchPath>}${infer TRest}`\n ? TRest\n : never\n\nexport type SearchRelativePathAutoComplete<\n TRouter extends AnyRouter,\n TTo extends string,\n TSearchPath extends string,\n> = `${TTo}/${RemoveLeadingSlashes<SearchPaths<TRouter, TSearchPath>>}`\n\nexport type RelativeToParentPathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n TTo extends string,\n TResolvedPath extends string = RemoveTrailingSlashes<\n ResolveRelativePath<TFrom, TTo>\n >,\n> =\n | SearchRelativePathAutoComplete<TRouter, TTo, TResolvedPath>\n | (TResolvedPath extends '' ? never : `${TTo}/../`)\n\nexport type RelativeToCurrentPathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n TTo extends string,\n TRestTo extends string,\n TResolvedPath extends\n string = RemoveTrailingSlashes<`${RemoveTrailingSlashes<TFrom>}/${RemoveLeadingSlashes<TRestTo>}`>,\n> = SearchRelativePathAutoComplete<TRouter, TTo, TResolvedPath>\n\nexport type AbsolutePathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n> =\n | (string extends TFrom\n ? './'\n : TFrom extends `/`\n ? never\n : SearchPaths<TRouter, TFrom> extends ''\n ? never\n : './')\n | (string extends TFrom ? '../' : TFrom extends `/` ? never : '../')\n | RouteToPath<TRouter, TRouter['routeTree']>\n | (TFrom extends '/'\n ? never\n : string extends TFrom\n ? RemoveLeadingSlashes<RouteToPath<TRouter, TRouter['routeTree']>>\n : RemoveLeadingSlashes<SearchPaths<TRouter, TFrom>>)\n\nexport type RelativeToPathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n TTo extends string,\n> = TTo extends `..${string}`\n ? RelativeToParentPathAutoComplete<TRouter, TFrom, RemoveTrailingSlashes<TTo>>\n : TTo extends `./${infer TRestTTo}`\n ? RelativeToCurrentPathAutoComplete<\n TRouter,\n TFrom,\n RemoveTrailingSlashes<TTo>,\n TRestTTo\n >\n : AbsolutePathAutoComplete<TRouter, TFrom>\n\nexport type NavigateOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '',\n> = ToOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & {\n // `replace` is a boolean that determines whether the navigation should replace the current history entry or push a new one.\n replace?: boolean\n resetScroll?: boolean\n /** @deprecated All navigations now use startTransition under the hood */\n startTransition?: boolean\n // if set to `true`, the router will wrap the resulting navigation in a document.startViewTransition() call.\n viewTransition?: boolean\n}\n\nexport type ToOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '',\n> = ToSubOptions<TRouter, TFrom, TTo> & {\n _fromLocation?: ParsedLocation\n mask?: ToMaskOptions<TRouter, TMaskFrom, TMaskTo>\n}\n\nexport type ToMaskOptions<\n TRouteTree extends AnyRouter = RegisteredRouter,\n TMaskFrom extends RoutePaths<TRouteTree['routeTree']> | string = string,\n TMaskTo extends string = '',\n> = ToSubOptions<TRouteTree, TMaskFrom, TMaskTo> & {\n unmaskOnReload?: boolean\n}\n\nexport type ToSubOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string = '',\n> = {\n to?: ToPathOption<TRouter, TFrom, TTo> & {}\n hash?: true | Updater<string>\n state?: true | NonNullableUpdater<HistoryState>\n // The source route path. This is automatically set when using route-level APIs, but for type-safe relative routing on the router itself, this is required\n from?: RoutePathsAutoComplete<TRouter['routeTree'], TFrom> & {}\n // // When using relative route paths, this option forces resolution from the current path, instead of the route API's path or `from` path\n} & SearchParamOptions<TRouter, TFrom, TTo> &\n PathParamOptions<TRouter, TFrom, TTo>\n\ntype ParamsReducer<TFrom, TTo> = TTo | ((current: TFrom) => TTo)\n\ntype ParamVariant = 'PATH' | 'SEARCH'\n\ntype ExcludeRootSearchSchema<T, TExcluded = Exclude<T, RootSearchSchema>> = [\n TExcluded,\n] extends [never]\n ? {}\n : TExcluded\n\nexport type ResolveRoute<\n TRouter extends AnyRouter,\n TFrom,\n TTo,\n TPath = string extends TFrom\n ? TTo\n : string extends TTo\n ? TFrom\n : ResolveRelativePath<TFrom, TTo>,\n> = TPath extends string\n ? string extends TTo\n ? RouteByPath<TRouter['routeTree'], TPath>\n : RouteByToPath<TRouter, TPath>\n : never\n\ntype PostProcessParams<\n T,\n TParamVariant extends ParamVariant,\n> = TParamVariant extends 'SEARCH' ? ExcludeRootSearchSchema<T> : T\n\ntype ResolveFromParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n> = PostProcessParams<\n RouteByPath<TRouter['routeTree'], TFrom>['types'][TParamVariant extends 'PATH'\n ? 'allParams'\n : 'fullSearchSchema'],\n TParamVariant\n>\n\ntype ResolveToParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n TRoute extends AnyRoute = ResolveRoute<TRouter, TFrom, TTo>,\n> = PostProcessParams<\n TRoute['types'][TParamVariant extends 'PATH'\n ? 'allParams'\n : 'fullSearchSchemaInput'],\n TParamVariant\n>\n\ntype ResolveRelativeToParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n TToParams = ResolveToParams<TRouter, TParamVariant, TFrom, TTo>,\n> = TParamVariant extends 'SEARCH'\n ? TToParams\n : string extends TFrom\n ? TToParams\n : MakeDifferenceOptional<\n ResolveFromParams<TRouter, TParamVariant, TFrom>,\n TToParams\n >\n\ntype MakeOptionalParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> = TParamVariant extends 'SEARCH'\n ? {\n search?:\n | true\n | (ParamsReducer<\n Expand<ResolveFromParams<TRouter, TParamVariant, TFrom>>,\n Expand<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>>\n > & {})\n }\n : {\n params?:\n | true\n | (ParamsReducer<\n Expand<ResolveFromParams<TRouter, TParamVariant, TFrom>>,\n Expand<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>>\n > & {})\n }\n\ntype MakeRequiredParamsReducer<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TToParams,\n TFromParams = ResolveFromParams<TRouter, TParamVariant, TFrom>,\n> =\n | ([TFromParams] extends [WithoutEmpty<PickRequired<TToParams>>]\n ? true\n : never)\n | ParamsReducer<Expand<TFromParams>, TToParams>\n\nexport type MakeRequiredParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> = TParamVariant extends 'SEARCH'\n ? {\n search: Expand<\n MakeRequiredParamsReducer<\n TRouter,\n TParamVariant,\n TFrom,\n Expand<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>>\n >\n > & {}\n }\n : {\n params: Expand<\n MakeRequiredParamsReducer<\n TRouter,\n TParamVariant,\n TFrom,\n Expand<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>>\n >\n > & {}\n }\n\nexport type IsRequiredParams<TParams> = keyof TParams extends infer K extends\n keyof TParams\n ? K extends any\n ? undefined extends TParams[K]\n ? never\n : true\n : never\n : never\n\nexport type IsRequired<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> = string extends TTo\n ? string extends TFrom\n ? never\n : IsRequiredParams<\n ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>\n >\n : IsRequiredParams<\n ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>\n >\n\nexport type ParamOptions<\n TRouter extends AnyRouter,\n TFrom,\n TTo extends string,\n TParamVariant extends ParamVariant,\n> =\n IsRequired<TRouter, TParamVariant, TFrom, TTo> extends never\n ? MakeOptionalParams<TRouter, TParamVariant, TFrom, TTo>\n : MakeRequiredParams<TRouter, TParamVariant, TFrom, TTo>\n\nexport type SearchParamOptions<\n TRouter extends AnyRouter,\n TFrom,\n TTo extends string,\n> = ParamOptions<TRouter, TFrom, TTo, 'SEARCH'>\n\nexport type PathParamOptions<\n TRouter extends AnyRouter,\n TFrom,\n TTo extends string,\n> = ParamOptions<TRouter, TFrom, TTo, 'PATH'>\n\nexport type ToPathOption<\n TRouter extends AnyRouter = AnyRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string = string,\n> =\n | CheckPath<TRouter, TTo, never, TFrom, TTo>\n | RelativeToPathAutoComplete<\n TRouter,\n NoInfer<TFrom> extends string ? NoInfer<TFrom> : '',\n NoInfer<TTo> & string\n >\n\nexport interface ActiveOptions {\n exact?: boolean\n includeHash?: boolean\n includeSearch?: boolean\n}\n\nexport type LinkOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '',\n> = NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & {\n // The standard anchor tag target attribute\n target?: HTMLAnchorElement['target']\n // Defaults to `{ exact: false, includeHash: false }`\n activeOptions?: ActiveOptions\n // If set, will preload the linked route on hover and cache it for this many milliseconds in hopes that the user will eventually navigate there.\n preload?: false | 'intent'\n // Delay intent preloading by this many milliseconds. If the intent exits before this delay, the preload will be cancelled.\n preloadDelay?: number\n // If true, will render the link without the href attribute\n disabled?: boolean\n}\n\nexport type CheckPath<TRouter extends AnyRouter, TPass, TFail, TFrom, TTo> =\n ResolveRoute<TRouter, TFrom, TTo> extends never ? TFail : TPass\n\nexport type ResolveRelativePath<TFrom, TTo = '.'> = TFrom extends string\n ? TTo extends string\n ? TTo extends '.'\n ? TFrom\n : TTo extends `./`\n ? Join<[TFrom, '/']>\n : TTo extends `./${infer TRest}`\n ? ResolveRelativePath<TFrom, TRest>\n : TTo extends `/${infer TRest}`\n ? TTo\n : Split<TTo> extends ['..', ...infer ToRest]\n ? Split<TFrom> extends [...infer FromRest, infer FromTail]\n ? ToRest extends ['/']\n ? Join<['/', ...FromRest, '/']>\n : ResolveRelativePath<Join<FromRest>, Join<ToRest>>\n : never\n : Split<TTo> extends ['.', ...infer ToRest]\n ? ToRest extends ['/']\n ? Join<[TFrom, '/']>\n : ResolveRelativePath<TFrom, Join<ToRest>>\n : CleanPath<Join<['/', ...Split<TFrom>, ...Split<TTo>]>>\n : never\n : never\n\n// type Test1 = ResolveRelativePath<'/', '/posts'>\n// // ^?\n// type Test4 = ResolveRelativePath<'/posts/1/comments', '../..'>\n// // ^?\n// type Test5 = ResolveRelativePath<'/posts/1/comments', '../../..'>\n// // ^?\n// type Test6 = ResolveRelativePath<'/posts/1/comments', './1'>\n// // ^?\n// type Test7 = ResolveRelativePath<'/posts/1/comments', './1/2'>\n// // ^?\n// type Test8 = ResolveRelativePath<'/posts/1/comments', '../edit'>\n// // ^?\n// type Test9 = ResolveRelativePath<'/posts/1/comments', '1'>\n// // ^?\n// type Test10 = ResolveRelativePath<'/posts/1/comments', './1'>\n// // ^?\n// type Test11 = ResolveRelativePath<'/posts/1/comments', './1/2'>\n// // ^?\n\ntype LinkCurrentTargetElement = {\n preloadTimeout?: null | ReturnType<typeof setTimeout>\n}\n\nconst preloadWarning = 'Error preloading route! ☝️'\n\nexport function useLinkProps<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '',\n>(\n options: UseLinkPropsOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n): React.AnchorHTMLAttributes<HTMLAnchorElement> {\n const router = useRouter()\n const matchPathname = useMatch({\n strict: false,\n select: (s) => s.pathname,\n })\n const [isTransitioning, setIsTransitioning] = React.useState(false)\n\n const {\n // custom props\n activeProps = () => ({ className: 'active' }),\n inactiveProps = () => ({}),\n activeOptions,\n hash,\n search,\n params,\n to,\n state,\n mask,\n preload: userPreload,\n preloadDelay: userPreloadDelay,\n replace,\n startTransition,\n resetScroll,\n viewTransition,\n // element props\n children,\n target,\n disabled,\n style,\n className,\n onClick,\n onFocus,\n onMouseEnter,\n onMouseLeave,\n onTouchStart,\n ...rest\n } = options\n\n // If this link simply reloads the current route,\n // make sure it has a new key so it will trigger a data refresh\n\n // If this `to` is a valid external URL, return\n // null for LinkUtils\n\n const dest = {\n ...(options.to && { from: matchPathname }),\n ...options,\n }\n\n let type: 'internal' | 'external' = 'internal'\n\n try {\n new URL(`${to}`)\n type = 'external'\n } catch {}\n\n const next = router.buildLocation(dest as any)\n const preload = userPreload ?? router.options.defaultPreload\n const preloadDelay =\n userPreloadDelay ?? router.options.defaultPreloadDelay ?? 0\n\n const isActive = useRouterState({\n select: (s) => {\n // Compare path/hash for matches\n const currentPathSplit = s.location.pathname.split('/')\n const nextPathSplit = next.pathname.split('/')\n const pathIsFuzzyEqual = nextPathSplit.every(\n (d, i) => d === currentPathSplit[i],\n )\n // Combine the matches based on user router.options\n const pathTest = activeOptions?.exact\n ? exactPathTest(s.location.pathname, next.pathname)\n : pathIsFuzzyEqual\n const hashTest = activeOptions?.includeHash\n ? s.location.hash === next.hash\n : true\n const searchTest =\n activeOptions?.includeSearch ?? true\n ? deepEqual(s.location.search, next.search, !activeOptions?.exact)\n : true\n\n // The final \"active\" test\n return pathTest && hashTest && searchTest\n },\n })\n\n if (type === 'external') {\n return {\n ...rest,\n type,\n href: to,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n ...(onClick && { onClick }),\n ...(onFocus && { onFocus }),\n ...(onMouseEnter && { onMouseEnter }),\n ...(onMouseLeave && { onMouseLeave }),\n ...(onTouchStart && { onTouchStart }),\n }\n }\n\n // The click handler\n const handleClick = (e: MouseEvent) => {\n if (\n !disabled &&\n !isCtrlEvent(e) &&\n !e.defaultPrevented &&\n (!target || target === '_self') &&\n e.button === 0\n ) {\n e.preventDefault()\n\n flushSync(() => {\n setIsTransitioning(true)\n })\n\n const unsub = router.subscribe('onResolved', () => {\n unsub()\n setIsTransitioning(false)\n })\n\n // All is well? Navigate!\n router.commitLocation({\n ...next,\n replace,\n resetScroll,\n startTransition,\n viewTransition,\n })\n }\n }\n\n const doPreload = () => {\n router.preloadRoute(dest as any).catch((err) => {\n console.warn(err)\n console.warn(preloadWarning)\n })\n }\n\n // The click handler\n const handleFocus = (e: MouseEvent) => {\n if (disabled) return\n if (preload) {\n doPreload()\n }\n }\n\n const handleTouchStart = handleFocus\n\n const handleEnter = (e: MouseEvent) => {\n if (disabled) return\n const eventTarget = (e.target || {}) as LinkCurrentTargetElement\n\n if (preload) {\n if (eventTarget.preloadTimeout) {\n return\n }\n\n eventTarget.preloadTimeout = setTimeout(() => {\n eventTarget.preloadTimeout = null\n doPreload()\n }, preloadDelay)\n }\n }\n\n const handleLeave = (e: MouseEvent) => {\n if (disabled) return\n const eventTarget = (e.target || {}) as LinkCurrentTargetElement\n\n if (eventTarget.preloadTimeout) {\n clearTimeout(eventTarget.preloadTimeout)\n eventTarget.preloadTimeout = null\n }\n }\n\n const composeHandlers =\n (handlers: Array<undefined | ((e: any) => void)>) =>\n (e: { persist?: () => void; defaultPrevented: boolean }) => {\n e.persist?.()\n handlers.filter(Boolean).forEach((handler) => {\n if (e.defaultPrevented) return\n handler!(e)\n })\n }\n\n // Get the active props\n const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> = isActive\n ? functionalUpdate(activeProps as any, {}) ?? {}\n : {}\n\n // Get the inactive props\n const resolvedInactiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive ? {} : functionalUpdate(inactiveProps, {})\n\n const resolvedClassName = [\n className,\n resolvedActiveProps.className,\n resolvedInactiveProps.className,\n ]\n .filter(Boolean)\n .join(' ')\n\n const resolvedStyle = {\n ...style,\n ...resolvedActiveProps.style,\n ...resolvedInactiveProps.style,\n }\n\n return {\n ...resolvedActiveProps,\n ...resolvedInactiveProps,\n ...rest,\n href: disabled\n ? undefined\n : next.maskedLocation\n ? router.history.createHref(next.maskedLocation.href)\n : router.history.createHref(next.href),\n onClick: composeHandlers([onClick, handleClick]),\n onFocus: composeHandlers([onFocus, handleFocus]),\n onMouseEnter: composeHandlers([onMouseEnter, handleEnter]),\n onMouseLeave: composeHandlers([onMouseLeave, handleLeave]),\n onTouchStart: composeHandlers([onTouchStart, handleTouchStart]),\n target,\n ...(Object.keys(resolvedStyle).length && { style: resolvedStyle }),\n ...(resolvedClassName && { className: resolvedClassName }),\n ...(disabled && {\n role: 'link',\n 'aria-disabled': true,\n }),\n ...(isActive && { 'data-status': 'active', 'aria-current': 'page' }),\n ...(isTransitioning && { 'data-transitioning': 'transitioning' }),\n }\n}\n\nexport type UseLinkPropsOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '',\n> = ActiveLinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n React.AnchorHTMLAttributes<HTMLAnchorElement>\n\nexport type ActiveLinkOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '',\n> = LinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & {\n // A function that returns additional props for the `active` state of this link. These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)\n activeProps?:\n | React.AnchorHTMLAttributes<HTMLAnchorElement>\n | (() => React.AnchorHTMLAttributes<HTMLAnchorElement>)\n // A function that returns additional props for the `inactive` state of this link. These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)\n inactiveProps?:\n | React.AnchorHTMLAttributes<HTMLAnchorElement>\n | (() => React.AnchorHTMLAttributes<HTMLAnchorElement>)\n}\n\nexport type LinkProps<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string = string,\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '',\n> = ActiveLinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & {\n // If a function is passed as a child, it will be given the `isActive` boolean to aid in further styling on the element it returns\n children?:\n | React.ReactNode\n | ((state: {\n isActive: boolean\n isTransitioning: boolean\n }) => React.ReactNode)\n}\n\ntype LinkComponentProps<TComp> = React.PropsWithoutRef<\n TComp extends React.FC<infer TProps> | React.Component<infer TProps>\n ? TProps\n : TComp extends keyof JSX.IntrinsicElements\n ? Omit<React.HTMLProps<TComp>, 'children' | 'preload'>\n : never\n> &\n React.RefAttributes<\n TComp extends\n | React.FC<{ ref: infer TRef }>\n | React.Component<{ ref: infer TRef }>\n ? TRef\n : TComp extends keyof JSX.IntrinsicElements\n ? React.ComponentRef<TComp>\n : never\n >\n\nexport type LinkComponent<TComp> = <\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '',\n>(\n props: LinkProps<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n LinkComponentProps<TComp>,\n) => React.ReactElement\n\nexport function createLink<const TComp>(Comp: TComp): LinkComponent<TComp> {\n return React.forwardRef(function CreatedLink(props, ref) {\n return <Link {...(props as any)} _asChild={Comp} ref={ref} />\n }) as any\n}\n\nexport const Link: LinkComponent<'a'> = React.forwardRef((props: any, ref) => {\n const { _asChild, ...rest } = props\n const { type, ...linkProps } = useLinkProps(rest)\n\n const children =\n typeof rest.children === 'function'\n ? rest.children({\n isActive: (linkProps as any)['data-status'] === 'active',\n })\n : rest.children\n\n return React.createElement(\n _asChild ? _asChild : 'a',\n {\n ...linkProps,\n ref,\n },\n children,\n )\n}) as any\n\nfunction isCtrlEvent(e: MouseEvent) {\n return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)\n}\n"],"names":[],"mappings":"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"}
package/dist/esm/path.js CHANGED
@@ -196,7 +196,7 @@ function matchByPath(basepath, from, matchLocation) {
196
196
  return false;
197
197
  }
198
198
  if (baseSegment.value.charAt(0) !== "$") {
199
- params[routeSegment.value.substring(1)] = decodeURI(
199
+ params[routeSegment.value.substring(1)] = decodeURIComponent(
200
200
  baseSegment.value
201
201
  );
202
202
  }
@@ -1 +1 @@
1
- {"version":3,"file":"path.js","sources":["../../src/path.ts"],"sourcesContent":["import { last } from './utils'\nimport type { MatchLocation } from './RouterProvider'\nimport type { AnyPathParams } from './route'\n\nexport interface Segment {\n type: 'pathname' | 'param' | 'wildcard'\n value: string\n}\n\nexport function joinPaths(paths: Array<string | undefined>) {\n return cleanPath(paths.filter(Boolean).join('/'))\n}\n\nexport function cleanPath(path: string) {\n // remove double slashes\n return path.replace(/\\/{2,}/g, '/')\n}\n\nexport function trimPathLeft(path: string) {\n return path === '/' ? path : path.replace(/^\\/{1,}/, '')\n}\n\nexport function trimPathRight(path: string) {\n return path === '/' ? path : path.replace(/\\/{1,}$/, '')\n}\n\nexport function trimPath(path: string) {\n return trimPathRight(trimPathLeft(path))\n}\n\n// When resolving relative paths, we treat all paths as if they are trailing slash\n// documents. All trailing slashes are removed after the path is resolved.\n// Here are a few examples:\n//\n// /a/b/c + ./d = /a/b/c/d\n// /a/b/c + ../d = /a/b/d\n// /a/b/c + ./d/ = /a/b/c/d\n// /a/b/c + ../d/ = /a/b/d\n// /a/b/c + ./ = /a/b/c\n//\n// Absolute paths that start with `/` short circuit the resolution process to the root\n// path.\n//\n// Here are some examples:\n//\n// /a/b/c + /d = /d\n// /a/b/c + /d/ = /d\n// /a/b/c + / = /\n//\n// Non-.-prefixed paths are still treated as relative paths, resolved like `./`\n//\n// Here are some examples:\n//\n// /a/b/c + d = /a/b/c/d\n// /a/b/c + d/ = /a/b/c/d\n// /a/b/c + d/e = /a/b/c/d/e\ninterface ResolvePathOptions {\n basepath: string\n base: string\n to: string\n trailingSlash?: 'always' | 'never' | 'preserve'\n}\nexport function resolvePath({\n basepath,\n base,\n to,\n trailingSlash = 'never',\n}: ResolvePathOptions) {\n base = base.replace(new RegExp(`^${basepath}`), '/')\n to = to.replace(new RegExp(`^${basepath}`), '/')\n\n let baseSegments = parsePathname(base)\n const toSegments = parsePathname(to)\n\n if (baseSegments.length > 1 && last(baseSegments)?.value === '/') {\n baseSegments.pop()\n }\n\n toSegments.forEach((toSegment, index) => {\n if (toSegment.value === '/') {\n if (!index) {\n // Leading slash\n baseSegments = [toSegment]\n } else if (index === toSegments.length - 1) {\n // Trailing Slash\n baseSegments.push(toSegment)\n } else {\n // ignore inter-slashes\n }\n } else if (toSegment.value === '..') {\n baseSegments.pop()\n } else if (toSegment.value === '.') {\n // ignore\n } else {\n baseSegments.push(toSegment)\n }\n })\n\n if (baseSegments.length > 1) {\n if (last(baseSegments)?.value === '/') {\n if (trailingSlash === 'never') {\n baseSegments.pop()\n }\n } else if (trailingSlash === 'always') {\n baseSegments.push({ type: 'pathname', value: '/' })\n }\n }\n\n const joined = joinPaths([basepath, ...baseSegments.map((d) => d.value)])\n return cleanPath(joined)\n}\n\nexport function parsePathname(pathname?: string): Array<Segment> {\n if (!pathname) {\n return []\n }\n\n pathname = cleanPath(pathname)\n\n const segments: Array<Segment> = []\n\n if (pathname.slice(0, 1) === '/') {\n pathname = pathname.substring(1)\n segments.push({\n type: 'pathname',\n value: '/',\n })\n }\n\n if (!pathname) {\n return segments\n }\n\n // Remove empty segments and '.' segments\n const split = pathname.split('/').filter(Boolean)\n\n segments.push(\n ...split.map((part): Segment => {\n if (part === '$' || part === '*') {\n return {\n type: 'wildcard',\n value: part,\n }\n }\n\n if (part.charAt(0) === '$') {\n return {\n type: 'param',\n value: part,\n }\n }\n\n return {\n type: 'pathname',\n value: part,\n }\n }),\n )\n\n if (pathname.slice(-1) === '/') {\n pathname = pathname.substring(1)\n segments.push({\n type: 'pathname',\n value: '/',\n })\n }\n\n return segments\n}\n\ninterface InterpolatePathOptions {\n path?: string\n params: any\n leaveWildcards?: boolean\n leaveParams?: boolean\n}\nexport function interpolatePath({\n path,\n params,\n leaveWildcards,\n leaveParams,\n}: InterpolatePathOptions) {\n const interpolatedPathSegments = parsePathname(path)\n\n return joinPaths(\n interpolatedPathSegments.map((segment) => {\n if (segment.type === 'wildcard') {\n const value = params._splat\n if (leaveWildcards) return `${segment.value}${value ?? ''}`\n return value\n }\n\n if (segment.type === 'param') {\n if (leaveParams) {\n const value = params[segment.value]\n return `${segment.value}${value ?? ''}`\n }\n return params![segment.value.substring(1)] ?? 'undefined'\n }\n\n return segment.value\n }),\n )\n}\n\nexport function matchPathname(\n basepath: string,\n currentPathname: string,\n matchLocation: Pick<MatchLocation, 'to' | 'fuzzy' | 'caseSensitive'>,\n): AnyPathParams | undefined {\n const pathParams = matchByPath(basepath, currentPathname, matchLocation)\n // const searchMatched = matchBySearch(location.search, matchLocation)\n\n if (matchLocation.to && !pathParams) {\n return\n }\n\n return pathParams ?? {}\n}\n\nexport function removeBasepath(basepath: string, pathname: string) {\n return basepath != '/' ? pathname.replace(basepath, '') : pathname\n}\n\nexport function matchByPath(\n basepath: string,\n from: string,\n matchLocation: Pick<MatchLocation, 'to' | 'caseSensitive' | 'fuzzy'>,\n): Record<string, string> | undefined {\n // Remove the base path from the pathname\n from = removeBasepath(basepath, from)\n // Default to to $ (wildcard)\n const to = removeBasepath(basepath, `${matchLocation.to ?? '$'}`)\n\n // Parse the from and to\n const baseSegments = parsePathname(from)\n const routeSegments = parsePathname(to)\n\n if (!from.startsWith('/')) {\n baseSegments.unshift({\n type: 'pathname',\n value: '/',\n })\n }\n\n if (!to.startsWith('/')) {\n routeSegments.unshift({\n type: 'pathname',\n value: '/',\n })\n }\n\n const params: Record<string, string> = {}\n\n const isMatch = (() => {\n for (\n let i = 0;\n i < Math.max(baseSegments.length, routeSegments.length);\n i++\n ) {\n const baseSegment = baseSegments[i]\n const routeSegment = routeSegments[i]\n\n const isLastBaseSegment = i >= baseSegments.length - 1\n const isLastRouteSegment = i >= routeSegments.length - 1\n\n if (routeSegment) {\n if (routeSegment.type === 'wildcard') {\n if (baseSegment?.value) {\n const _splat = decodeURI(\n joinPaths(baseSegments.slice(i).map((d) => d.value)),\n )\n // TODO: Deprecate *\n params['*'] = _splat\n params['_splat'] = _splat\n return true\n }\n return false\n }\n\n if (routeSegment.type === 'pathname') {\n if (routeSegment.value === '/' && !baseSegment?.value) {\n return true\n }\n\n if (baseSegment) {\n if (matchLocation.caseSensitive) {\n if (routeSegment.value !== baseSegment.value) {\n return false\n }\n } else if (\n routeSegment.value.toLowerCase() !==\n baseSegment.value.toLowerCase()\n ) {\n return false\n }\n }\n }\n\n if (!baseSegment) {\n return false\n }\n\n if (routeSegment.type === 'param') {\n if (baseSegment.value === '/') {\n return false\n }\n if (baseSegment.value.charAt(0) !== '$') {\n params[routeSegment.value.substring(1)] = decodeURI(\n baseSegment.value,\n )\n }\n }\n }\n\n if (!isLastBaseSegment && isLastRouteSegment) {\n params['**'] = joinPaths(baseSegments.slice(i + 1).map((d) => d.value))\n return !!matchLocation.fuzzy && routeSegment?.value !== '/'\n }\n }\n\n return true\n })()\n\n return isMatch ? params : undefined\n}\n"],"names":[],"mappings":";AASO,SAAS,UAAU,OAAkC;AAC1D,SAAO,UAAU,MAAM,OAAO,OAAO,EAAE,KAAK,GAAG,CAAC;AAClD;AAEO,SAAS,UAAU,MAAc;AAE/B,SAAA,KAAK,QAAQ,WAAW,GAAG;AACpC;AAEO,SAAS,aAAa,MAAc;AACzC,SAAO,SAAS,MAAM,OAAO,KAAK,QAAQ,WAAW,EAAE;AACzD;AAEO,SAAS,cAAc,MAAc;AAC1C,SAAO,SAAS,MAAM,OAAO,KAAK,QAAQ,WAAW,EAAE;AACzD;AAEO,SAAS,SAAS,MAAc;AAC9B,SAAA,cAAc,aAAa,IAAI,CAAC;AACzC;AAkCO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB;AAClB,GAAuB;;AACd,SAAA,KAAK,QAAQ,IAAI,OAAO,IAAI,QAAQ,EAAE,GAAG,GAAG;AAC9C,OAAA,GAAG,QAAQ,IAAI,OAAO,IAAI,QAAQ,EAAE,GAAG,GAAG;AAE3C,MAAA,eAAe,cAAc,IAAI;AAC/B,QAAA,aAAa,cAAc,EAAE;AAEnC,MAAI,aAAa,SAAS,OAAK,UAAK,YAAY,MAAjB,mBAAoB,WAAU,KAAK;AAChE,iBAAa,IAAI;AAAA,EACnB;AAEW,aAAA,QAAQ,CAAC,WAAW,UAAU;AACnC,QAAA,UAAU,UAAU,KAAK;AAC3B,UAAI,CAAC,OAAO;AAEV,uBAAe,CAAC,SAAS;AAAA,MAChB,WAAA,UAAU,WAAW,SAAS,GAAG;AAE1C,qBAAa,KAAK,SAAS;AAAA,MAAA;AACtB;AAAA,IAEP,WACS,UAAU,UAAU,MAAM;AACnC,mBAAa,IAAI;AAAA,IACnB,WAAW,UAAU,UAAU;AAAK;AAAA,SAE7B;AACL,mBAAa,KAAK,SAAS;AAAA,IAC7B;AAAA,EAAA,CACD;AAEG,MAAA,aAAa,SAAS,GAAG;AAC3B,UAAI,UAAK,YAAY,MAAjB,mBAAoB,WAAU,KAAK;AACrC,UAAI,kBAAkB,SAAS;AAC7B,qBAAa,IAAI;AAAA,MACnB;AAAA,IAAA,WACS,kBAAkB,UAAU;AACrC,mBAAa,KAAK,EAAE,MAAM,YAAY,OAAO,KAAK;AAAA,IACpD;AAAA,EACF;AAEA,QAAM,SAAS,UAAU,CAAC,UAAU,GAAG,aAAa,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACxE,SAAO,UAAU,MAAM;AACzB;AAEO,SAAS,cAAc,UAAmC;AAC/D,MAAI,CAAC,UAAU;AACb,WAAO;EACT;AAEA,aAAW,UAAU,QAAQ;AAE7B,QAAM,WAA2B,CAAA;AAEjC,MAAI,SAAS,MAAM,GAAG,CAAC,MAAM,KAAK;AACrB,eAAA,SAAS,UAAU,CAAC;AAC/B,aAAS,KAAK;AAAA,MACZ,MAAM;AAAA,MACN,OAAO;AAAA,IAAA,CACR;AAAA,EACH;AAEA,MAAI,CAAC,UAAU;AACN,WAAA;AAAA,EACT;AAGA,QAAM,QAAQ,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AAEvC,WAAA;AAAA,IACP,GAAG,MAAM,IAAI,CAAC,SAAkB;AAC1B,UAAA,SAAS,OAAO,SAAS,KAAK;AACzB,eAAA;AAAA,UACL,MAAM;AAAA,UACN,OAAO;AAAA,QAAA;AAAA,MAEX;AAEA,UAAI,KAAK,OAAO,CAAC,MAAM,KAAK;AACnB,eAAA;AAAA,UACL,MAAM;AAAA,UACN,OAAO;AAAA,QAAA;AAAA,MAEX;AAEO,aAAA;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,MAAA;AAAA,IACT,CACD;AAAA,EAAA;AAGH,MAAI,SAAS,MAAM,EAAE,MAAM,KAAK;AACnB,eAAA,SAAS,UAAU,CAAC;AAC/B,aAAS,KAAK;AAAA,MACZ,MAAM;AAAA,MACN,OAAO;AAAA,IAAA,CACR;AAAA,EACH;AAEO,SAAA;AACT;AAQO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA2B;AACnB,QAAA,2BAA2B,cAAc,IAAI;AAE5C,SAAA;AAAA,IACL,yBAAyB,IAAI,CAAC,YAAY;AACpC,UAAA,QAAQ,SAAS,YAAY;AAC/B,cAAM,QAAQ,OAAO;AACjB,YAAA;AAAgB,iBAAO,GAAG,QAAQ,KAAK,GAAG,SAAS,EAAE;AAClD,eAAA;AAAA,MACT;AAEI,UAAA,QAAQ,SAAS,SAAS;AAC5B,YAAI,aAAa;AACT,gBAAA,QAAQ,OAAO,QAAQ,KAAK;AAClC,iBAAO,GAAG,QAAQ,KAAK,GAAG,SAAS,EAAE;AAAA,QACvC;AACA,eAAO,OAAQ,QAAQ,MAAM,UAAU,CAAC,CAAC,KAAK;AAAA,MAChD;AAEA,aAAO,QAAQ;AAAA,IAAA,CAChB;AAAA,EAAA;AAEL;AAEgB,SAAA,cACd,UACA,iBACA,eAC2B;AAC3B,QAAM,aAAa,YAAY,UAAU,iBAAiB,aAAa;AAGnE,MAAA,cAAc,MAAM,CAAC,YAAY;AACnC;AAAA,EACF;AAEA,SAAO,cAAc,CAAA;AACvB;AAEgB,SAAA,eAAe,UAAkB,UAAkB;AACjE,SAAO,YAAY,MAAM,SAAS,QAAQ,UAAU,EAAE,IAAI;AAC5D;AAEgB,SAAA,YACd,UACA,MACA,eACoC;AAE7B,SAAA,eAAe,UAAU,IAAI;AAEpC,QAAM,KAAK,eAAe,UAAU,GAAG,cAAc,MAAM,GAAG,EAAE;AAG1D,QAAA,eAAe,cAAc,IAAI;AACjC,QAAA,gBAAgB,cAAc,EAAE;AAEtC,MAAI,CAAC,KAAK,WAAW,GAAG,GAAG;AACzB,iBAAa,QAAQ;AAAA,MACnB,MAAM;AAAA,MACN,OAAO;AAAA,IAAA,CACR;AAAA,EACH;AAEA,MAAI,CAAC,GAAG,WAAW,GAAG,GAAG;AACvB,kBAAc,QAAQ;AAAA,MACpB,MAAM;AAAA,MACN,OAAO;AAAA,IAAA,CACR;AAAA,EACH;AAEA,QAAM,SAAiC,CAAA;AAEvC,QAAM,WAAW,MAAM;AAEf,aAAA,IAAI,GACR,IAAI,KAAK,IAAI,aAAa,QAAQ,cAAc,MAAM,GACtD,KACA;AACM,YAAA,cAAc,aAAa,CAAC;AAC5B,YAAA,eAAe,cAAc,CAAC;AAE9B,YAAA,oBAAoB,KAAK,aAAa,SAAS;AAC/C,YAAA,qBAAqB,KAAK,cAAc,SAAS;AAEvD,UAAI,cAAc;AACZ,YAAA,aAAa,SAAS,YAAY;AACpC,cAAI,2CAAa,OAAO;AACtB,kBAAM,SAAS;AAAA,cACb,UAAU,aAAa,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAAA,YAAA;AAGrD,mBAAO,GAAG,IAAI;AACd,mBAAO,QAAQ,IAAI;AACZ,mBAAA;AAAA,UACT;AACO,iBAAA;AAAA,QACT;AAEI,YAAA,aAAa,SAAS,YAAY;AACpC,cAAI,aAAa,UAAU,OAAO,EAAC,2CAAa,QAAO;AAC9C,mBAAA;AAAA,UACT;AAEA,cAAI,aAAa;AACf,gBAAI,cAAc,eAAe;AAC3B,kBAAA,aAAa,UAAU,YAAY,OAAO;AACrC,uBAAA;AAAA,cACT;AAAA,YAAA,WAEA,aAAa,MAAM,kBACnB,YAAY,MAAM,eAClB;AACO,qBAAA;AAAA,YACT;AAAA,UACF;AAAA,QACF;AAEA,YAAI,CAAC,aAAa;AACT,iBAAA;AAAA,QACT;AAEI,YAAA,aAAa,SAAS,SAAS;AAC7B,cAAA,YAAY,UAAU,KAAK;AACtB,mBAAA;AAAA,UACT;AACA,cAAI,YAAY,MAAM,OAAO,CAAC,MAAM,KAAK;AACvC,mBAAO,aAAa,MAAM,UAAU,CAAC,CAAC,IAAI;AAAA,cACxC,YAAY;AAAA,YAAA;AAAA,UAEhB;AAAA,QACF;AAAA,MACF;AAEI,UAAA,CAAC,qBAAqB,oBAAoB;AAC5C,eAAO,IAAI,IAAI,UAAU,aAAa,MAAM,IAAI,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACtE,eAAO,CAAC,CAAC,cAAc,UAAS,6CAAc,WAAU;AAAA,MAC1D;AAAA,IACF;AAEO,WAAA;AAAA,EAAA;AAGT,SAAO,UAAU,SAAS;AAC5B;"}
1
+ {"version":3,"file":"path.js","sources":["../../src/path.ts"],"sourcesContent":["import { last } from './utils'\nimport type { MatchLocation } from './RouterProvider'\nimport type { AnyPathParams } from './route'\n\nexport interface Segment {\n type: 'pathname' | 'param' | 'wildcard'\n value: string\n}\n\nexport function joinPaths(paths: Array<string | undefined>) {\n return cleanPath(paths.filter(Boolean).join('/'))\n}\n\nexport function cleanPath(path: string) {\n // remove double slashes\n return path.replace(/\\/{2,}/g, '/')\n}\n\nexport function trimPathLeft(path: string) {\n return path === '/' ? path : path.replace(/^\\/{1,}/, '')\n}\n\nexport function trimPathRight(path: string) {\n return path === '/' ? path : path.replace(/\\/{1,}$/, '')\n}\n\nexport function trimPath(path: string) {\n return trimPathRight(trimPathLeft(path))\n}\n\n// When resolving relative paths, we treat all paths as if they are trailing slash\n// documents. All trailing slashes are removed after the path is resolved.\n// Here are a few examples:\n//\n// /a/b/c + ./d = /a/b/c/d\n// /a/b/c + ../d = /a/b/d\n// /a/b/c + ./d/ = /a/b/c/d\n// /a/b/c + ../d/ = /a/b/d\n// /a/b/c + ./ = /a/b/c\n//\n// Absolute paths that start with `/` short circuit the resolution process to the root\n// path.\n//\n// Here are some examples:\n//\n// /a/b/c + /d = /d\n// /a/b/c + /d/ = /d\n// /a/b/c + / = /\n//\n// Non-.-prefixed paths are still treated as relative paths, resolved like `./`\n//\n// Here are some examples:\n//\n// /a/b/c + d = /a/b/c/d\n// /a/b/c + d/ = /a/b/c/d\n// /a/b/c + d/e = /a/b/c/d/e\ninterface ResolvePathOptions {\n basepath: string\n base: string\n to: string\n trailingSlash?: 'always' | 'never' | 'preserve'\n}\nexport function resolvePath({\n basepath,\n base,\n to,\n trailingSlash = 'never',\n}: ResolvePathOptions) {\n base = base.replace(new RegExp(`^${basepath}`), '/')\n to = to.replace(new RegExp(`^${basepath}`), '/')\n\n let baseSegments = parsePathname(base)\n const toSegments = parsePathname(to)\n\n if (baseSegments.length > 1 && last(baseSegments)?.value === '/') {\n baseSegments.pop()\n }\n\n toSegments.forEach((toSegment, index) => {\n if (toSegment.value === '/') {\n if (!index) {\n // Leading slash\n baseSegments = [toSegment]\n } else if (index === toSegments.length - 1) {\n // Trailing Slash\n baseSegments.push(toSegment)\n } else {\n // ignore inter-slashes\n }\n } else if (toSegment.value === '..') {\n baseSegments.pop()\n } else if (toSegment.value === '.') {\n // ignore\n } else {\n baseSegments.push(toSegment)\n }\n })\n\n if (baseSegments.length > 1) {\n if (last(baseSegments)?.value === '/') {\n if (trailingSlash === 'never') {\n baseSegments.pop()\n }\n } else if (trailingSlash === 'always') {\n baseSegments.push({ type: 'pathname', value: '/' })\n }\n }\n\n const joined = joinPaths([basepath, ...baseSegments.map((d) => d.value)])\n return cleanPath(joined)\n}\n\nexport function parsePathname(pathname?: string): Array<Segment> {\n if (!pathname) {\n return []\n }\n\n pathname = cleanPath(pathname)\n\n const segments: Array<Segment> = []\n\n if (pathname.slice(0, 1) === '/') {\n pathname = pathname.substring(1)\n segments.push({\n type: 'pathname',\n value: '/',\n })\n }\n\n if (!pathname) {\n return segments\n }\n\n // Remove empty segments and '.' segments\n const split = pathname.split('/').filter(Boolean)\n\n segments.push(\n ...split.map((part): Segment => {\n if (part === '$' || part === '*') {\n return {\n type: 'wildcard',\n value: part,\n }\n }\n\n if (part.charAt(0) === '$') {\n return {\n type: 'param',\n value: part,\n }\n }\n\n return {\n type: 'pathname',\n value: part,\n }\n }),\n )\n\n if (pathname.slice(-1) === '/') {\n pathname = pathname.substring(1)\n segments.push({\n type: 'pathname',\n value: '/',\n })\n }\n\n return segments\n}\n\ninterface InterpolatePathOptions {\n path?: string\n params: any\n leaveWildcards?: boolean\n leaveParams?: boolean\n}\nexport function interpolatePath({\n path,\n params,\n leaveWildcards,\n leaveParams,\n}: InterpolatePathOptions) {\n const interpolatedPathSegments = parsePathname(path)\n\n return joinPaths(\n interpolatedPathSegments.map((segment) => {\n if (segment.type === 'wildcard') {\n const value = params._splat\n if (leaveWildcards) return `${segment.value}${value ?? ''}`\n return value\n }\n\n if (segment.type === 'param') {\n if (leaveParams) {\n const value = params[segment.value]\n return `${segment.value}${value ?? ''}`\n }\n return params![segment.value.substring(1)] ?? 'undefined'\n }\n\n return segment.value\n }),\n )\n}\n\nexport function matchPathname(\n basepath: string,\n currentPathname: string,\n matchLocation: Pick<MatchLocation, 'to' | 'fuzzy' | 'caseSensitive'>,\n): AnyPathParams | undefined {\n const pathParams = matchByPath(basepath, currentPathname, matchLocation)\n // const searchMatched = matchBySearch(location.search, matchLocation)\n\n if (matchLocation.to && !pathParams) {\n return\n }\n\n return pathParams ?? {}\n}\n\nexport function removeBasepath(basepath: string, pathname: string) {\n return basepath != '/' ? pathname.replace(basepath, '') : pathname\n}\n\nexport function matchByPath(\n basepath: string,\n from: string,\n matchLocation: Pick<MatchLocation, 'to' | 'caseSensitive' | 'fuzzy'>,\n): Record<string, string> | undefined {\n // Remove the base path from the pathname\n from = removeBasepath(basepath, from)\n // Default to to $ (wildcard)\n const to = removeBasepath(basepath, `${matchLocation.to ?? '$'}`)\n\n // Parse the from and to\n const baseSegments = parsePathname(from)\n const routeSegments = parsePathname(to)\n\n if (!from.startsWith('/')) {\n baseSegments.unshift({\n type: 'pathname',\n value: '/',\n })\n }\n\n if (!to.startsWith('/')) {\n routeSegments.unshift({\n type: 'pathname',\n value: '/',\n })\n }\n\n const params: Record<string, string> = {}\n\n const isMatch = (() => {\n for (\n let i = 0;\n i < Math.max(baseSegments.length, routeSegments.length);\n i++\n ) {\n const baseSegment = baseSegments[i]\n const routeSegment = routeSegments[i]\n\n const isLastBaseSegment = i >= baseSegments.length - 1\n const isLastRouteSegment = i >= routeSegments.length - 1\n\n if (routeSegment) {\n if (routeSegment.type === 'wildcard') {\n if (baseSegment?.value) {\n const _splat = decodeURI(\n joinPaths(baseSegments.slice(i).map((d) => d.value)),\n )\n // TODO: Deprecate *\n params['*'] = _splat\n params['_splat'] = _splat\n return true\n }\n return false\n }\n\n if (routeSegment.type === 'pathname') {\n if (routeSegment.value === '/' && !baseSegment?.value) {\n return true\n }\n\n if (baseSegment) {\n if (matchLocation.caseSensitive) {\n if (routeSegment.value !== baseSegment.value) {\n return false\n }\n } else if (\n routeSegment.value.toLowerCase() !==\n baseSegment.value.toLowerCase()\n ) {\n return false\n }\n }\n }\n\n if (!baseSegment) {\n return false\n }\n\n if (routeSegment.type === 'param') {\n if (baseSegment.value === '/') {\n return false\n }\n if (baseSegment.value.charAt(0) !== '$') {\n params[routeSegment.value.substring(1)] = decodeURIComponent(\n baseSegment.value,\n )\n }\n }\n }\n\n if (!isLastBaseSegment && isLastRouteSegment) {\n params['**'] = joinPaths(baseSegments.slice(i + 1).map((d) => d.value))\n return !!matchLocation.fuzzy && routeSegment?.value !== '/'\n }\n }\n\n return true\n })()\n\n return isMatch ? params : undefined\n}\n"],"names":[],"mappings":"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"}
@@ -1,10 +1,9 @@
1
1
  import type { NavigateOptions } from './link.js';
2
- import type { AnyRoute } from './route.js';
3
2
  import type { RoutePaths } from './routeInfo.js';
4
- import type { RegisteredRouter } from './router.js';
3
+ import type { AnyRouter, RegisteredRouter } from './router.js';
5
4
  import type { PickAsRequired } from './utils.js';
6
5
  export type AnyRedirect = Redirect<any, any, any, any, any>;
7
- export type Redirect<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> = '/', TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> = TFrom, TMaskTo extends string = ''> = {
6
+ export type Redirect<TRouter extends AnyRouter = RegisteredRouter, TFrom extends RoutePaths<TRouter['routeTree']> = '/', TTo extends string = '', TMaskFrom extends RoutePaths<TRouter['routeTree']> = TFrom, TMaskTo extends string = ''> = {
8
7
  /**
9
8
  * @deprecated Use `statusCode` instead
10
9
  **/
@@ -13,9 +12,9 @@ export type Redirect<TRouteTree extends AnyRoute = RegisteredRouter['routeTree']
13
12
  statusCode?: number;
14
13
  throw?: any;
15
14
  headers?: HeadersInit;
16
- } & NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>;
17
- export type ResolvedRedirect<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> = '/', TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> = TFrom, TMaskTo extends string = ''> = PickAsRequired<Redirect<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>, 'code' | 'statusCode' | 'headers'> & {
15
+ } & NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>;
16
+ export type ResolvedRedirect<TRouter extends AnyRouter = RegisteredRouter, TFrom extends RoutePaths<TRouter['routeTree']> = '/', TTo extends string = '', TMaskFrom extends RoutePaths<TRouter['routeTree']> = TFrom, TMaskTo extends string = ''> = PickAsRequired<Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>, 'code' | 'statusCode' | 'headers'> & {
18
17
  href: string;
19
18
  };
20
- export declare function redirect<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> = '/', TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> = TFrom, TMaskTo extends string = ''>(opts: Redirect<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>): Redirect<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>;
19
+ export declare function redirect<TRouter extends AnyRouter = RegisteredRouter, TFrom extends RoutePaths<TRouter['routeTree']> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom, TMaskTo extends string = ''>(opts: Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>): Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>;
21
20
  export declare function isRedirect(obj: any): obj is AnyRedirect;
@@ -1 +1 @@
1
- {"version":3,"file":"redirects.js","sources":["../../src/redirects.ts"],"sourcesContent":["import type { NavigateOptions } from './link'\nimport type { AnyRoute } from './route'\nimport type { RoutePaths } from './routeInfo'\nimport type { RegisteredRouter } from './router'\nimport type { PickAsRequired } from './utils'\n\nexport type AnyRedirect = Redirect<any, any, any, any, any>\n\nexport type Redirect<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> = '/',\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> = TFrom,\n TMaskTo extends string = '',\n> = {\n /**\n * @deprecated Use `statusCode` instead\n **/\n href?: string\n code?: number\n statusCode?: number\n throw?: any\n headers?: HeadersInit\n} & NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>\n\nexport type ResolvedRedirect<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> = '/',\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> = TFrom,\n TMaskTo extends string = '',\n> = PickAsRequired<\n Redirect<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>,\n 'code' | 'statusCode' | 'headers'\n> & {\n href: string\n}\n\nexport function redirect<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> = '/',\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> = TFrom,\n TMaskTo extends string = '',\n>(\n opts: Redirect<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>,\n): Redirect<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> {\n ;(opts as any).isRedirect = true\n opts.statusCode = opts.statusCode || opts.code || 301\n opts.headers = opts.headers || {}\n if (opts.throw) {\n throw opts\n }\n\n return opts\n}\n\nexport function isRedirect(obj: any): obj is AnyRedirect {\n return !!obj?.isRedirect\n}\n"],"names":[],"mappings":"AAsCO,SAAS,SAOd,MACsD;AACpD,OAAa,aAAa;AAC5B,OAAK,aAAa,KAAK,cAAc,KAAK,QAAQ;AAC7C,OAAA,UAAU,KAAK,WAAW,CAAA;AAC/B,MAAI,KAAK,OAAO;AACR,UAAA;AAAA,EACR;AAEO,SAAA;AACT;AAEO,SAAS,WAAW,KAA8B;AAChD,SAAA,CAAC,EAAC,2BAAK;AAChB;"}
1
+ {"version":3,"file":"redirects.js","sources":["../../src/redirects.ts"],"sourcesContent":["import type { NavigateOptions } from './link'\nimport type { AnyRoute } from './route'\nimport type { RoutePaths } from './routeInfo'\nimport type { AnyRouter, RegisteredRouter } from './router'\nimport type { PickAsRequired } from './utils'\n\nexport type AnyRedirect = Redirect<any, any, any, any, any>\n\nexport type Redirect<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> = '/',\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> = TFrom,\n TMaskTo extends string = '',\n> = {\n /**\n * @deprecated Use `statusCode` instead\n **/\n href?: string\n code?: number\n statusCode?: number\n throw?: any\n headers?: HeadersInit\n} & NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>\n\nexport type ResolvedRedirect<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> = '/',\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> = TFrom,\n TMaskTo extends string = '',\n> = PickAsRequired<\n Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n 'code' | 'statusCode' | 'headers'\n> & {\n href: string\n}\n\nexport function redirect<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '',\n>(\n opts: Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n): Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> {\n ;(opts as any).isRedirect = true\n opts.statusCode = opts.statusCode || opts.code || 301\n opts.headers = opts.headers || {}\n if (opts.throw) {\n throw opts\n }\n\n return opts\n}\n\nexport function isRedirect(obj: any): obj is AnyRedirect {\n return !!obj?.isRedirect\n}\n"],"names":[],"mappings":"AAsCO,SAAS,SAOd,MACmD;AACjD,OAAa,aAAa;AAC5B,OAAK,aAAa,KAAK,cAAc,KAAK,QAAQ;AAC7C,OAAA,UAAU,KAAK,WAAW,CAAA;AAC/B,MAAI,KAAK,OAAO;AACR,UAAA;AAAA,EACR;AAEO,SAAA;AACT;AAEO,SAAS,WAAW,KAA8B;AAChD,SAAA,CAAC,EAAC,2BAAK;AAChB;"}
@@ -4,7 +4,7 @@ import type { MakeRouteMatch, RouteMatch } from './Matches.js';
4
4
  import type { NavigateOptions, ParsePathParams, ToSubOptions } from './link.js';
5
5
  import type { ParsedLocation } from './location.js';
6
6
  import type { RouteById, RouteIds, RoutePaths } from './routeInfo.js';
7
- import type { AnyRouter, RegisteredRouter } from './router.js';
7
+ import type { AnyRouter, RegisteredRouter, Router } from './router.js';
8
8
  import type { Assign, Expand, IsAny, NoInfer, PickRequired, UnionToIntersection } from './utils.js';
9
9
  import type { BuildLocationFn, NavigateFn } from './RouterProvider.js';
10
10
  import type { NotFoundError } from './not-found.js';
@@ -144,7 +144,7 @@ export interface LoaderFnContext<in out TAllParams = {}, in out TLoaderDeps = {}
144
144
  /**
145
145
  * @deprecated Use `throw redirect({ to: '/somewhere' })` instead
146
146
  **/
147
- navigate: (opts: NavigateOptions<AnyRoute>) => Promise<void>;
147
+ navigate: (opts: NavigateOptions<AnyRouter>) => Promise<void>;
148
148
  parentMatchPromise?: Promise<void>;
149
149
  cause: 'preload' | 'enter' | 'stay';
150
150
  route: Route;
@@ -195,7 +195,7 @@ export declare class RouteApi<TId extends RouteIds<RegisteredRouter['routeTree']
195
195
  constructor({ id }: {
196
196
  id: TId;
197
197
  });
198
- useMatch: <TRouteTree extends AnyRoute = AnyRoute, TRouteMatch = MakeRouteMatch<TRouteTree, TId>, TSelected = TRouteMatch>(opts?: {
198
+ useMatch: <TRouteTree extends AnyRoute = any, TRouteMatch = MakeRouteMatch<TRouteTree, TId>, TSelected = TRouteMatch>(opts?: {
199
199
  select?: ((match: TRouteMatch) => TSelected) | undefined;
200
200
  } | undefined) => TSelected;
201
201
  useRouteContext: <TSelected = Expand<TAllContext>>(opts?: {
@@ -263,7 +263,7 @@ export declare class Route<in out TParentRoute extends RouteConstraints['TParent
263
263
  }) => Route<TParentRoute, TPath, TFullPath, TCustomId, TId, TSearchSchemaInput, TSearchSchema, TSearchSchemaUsed, TFullSearchSchemaInput, TFullSearchSchema, TParams, TAllParams, TRouteContextReturn, TRouteContext, TAllContext, TRouterContext, TLoaderDeps, TNewLoaderData, TChildren, unknown>;
264
264
  update: (options: UpdatableRouteOptions<TCustomId, TAllParams, TFullSearchSchema, TLoaderData, TAllContext, TRouteContext, TLoaderDeps>) => this;
265
265
  lazy: (lazyFn: () => Promise<LazyRoute<any>>) => this;
266
- useMatch: <TRouteTree extends AnyRoute = AnyRoute, TRouteMatch = MakeRouteMatch<TRouteTree, TId>, TSelected = TRouteMatch>(opts?: {
266
+ useMatch: <TRouteTree extends AnyRoute = any, TRouteMatch = MakeRouteMatch<TRouteTree, TId>, TSelected = TRouteMatch>(opts?: {
267
267
  select?: ((match: TRouteMatch) => TSelected) | undefined;
268
268
  } | undefined) => TSelected;
269
269
  useRouteContext: <TSelected = Expand<TAllContext>>(opts?: {
@@ -285,7 +285,7 @@ export declare class Route<in out TParentRoute extends RouteConstraints['TParent
285
285
  }
286
286
  export declare function createRoute<TParentRoute extends RouteConstraints['TParentRoute'] = AnyRoute, TPath extends RouteConstraints['TPath'] = '/', TFullPath extends RouteConstraints['TFullPath'] = ResolveFullPath<TParentRoute, TPath>, TCustomId extends RouteConstraints['TCustomId'] = string, TId extends RouteConstraints['TId'] = ResolveId<TParentRoute, TCustomId, TPath>, TSearchSchemaInput extends RouteConstraints['TSearchSchema'] = {}, TSearchSchema extends RouteConstraints['TSearchSchema'] = {}, TSearchSchemaUsed = TSearchSchemaInput extends SearchSchemaInput ? Omit<TSearchSchemaInput, keyof SearchSchemaInput> : TSearchSchema, TFullSearchSchemaInput = ResolveFullSearchSchemaInput<TParentRoute, TSearchSchemaUsed>, TFullSearchSchema = ResolveFullSearchSchema<TParentRoute, TSearchSchema>, TParams = Record<ParsePathParams<TPath>, string>, TAllParams = ResolveAllParams<TParentRoute, TParams>, TRouteContextReturn extends RouteConstraints['TRouteContext'] = RouteContext, TRouteContext = [TRouteContextReturn] extends [never] ? RouteContext : TRouteContextReturn, TAllContext = Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>, TRouterContext extends RouteConstraints['TRouterContext'] = AnyContext, TLoaderDeps extends Record<string, any> = {}, TLoaderDataReturn = unknown, TLoaderData = [TLoaderDataReturn] extends [never] ? undefined : TLoaderDataReturn, TChildren extends RouteConstraints['TChildren'] = unknown>(options: RouteOptions<TParentRoute, TCustomId, TPath, TSearchSchemaInput, TSearchSchema, TSearchSchemaUsed, TFullSearchSchemaInput, TFullSearchSchema, TParams, TAllParams, TRouteContextReturn, TRouteContext, TRouterContext, TAllContext, TLoaderDeps, TLoaderDataReturn, TLoaderData>): Route<TParentRoute, TPath, TFullPath, TCustomId, TId, TSearchSchemaInput, TSearchSchema, TSearchSchemaUsed, TFullSearchSchemaInput, TFullSearchSchema, TParams, TAllParams, TRouteContextReturn, TRouteContext, TAllContext, TRouterContext, TLoaderDeps, TLoaderDataReturn, TLoaderData, TChildren>;
287
287
  export type AnyRootRoute = RootRoute<any, any, any, any, any, any, any, any>;
288
- export declare function createRootRouteWithContext<TRouterContext extends {}>(): <TSearchSchemaInput extends Record<string, any> = RootSearchSchema, TSearchSchema extends Record<string, any> = RootSearchSchema, TSearchSchemaUsed extends Record<string, any> = RootSearchSchema, TRouteContextReturn extends RouteContext = RouteContext, TRouteContext extends RouteContext = [TRouteContextReturn] extends [never] ? RouteContext : TRouteContextReturn, TLoaderDeps extends Record<string, any> = {}, TLoaderDataReturn = unknown, TLoaderData = [TLoaderDataReturn] extends [never] ? undefined : TLoaderDataReturn>(options?: Omit<RouteOptions<any, "__root__", "", TSearchSchemaInput, TSearchSchema, TSearchSchemaUsed, TSearchSchemaUsed, TSearchSchema, {}, {}, TRouteContextReturn, TRouteContext, TRouterContext, Assign<TRouterContext, TRouteContext>, TLoaderDeps, TLoaderDataReturn, TLoaderData>, "path" | "id" | "stringifyParams" | "parseParams" | "getParentRoute" | "caseSensitive"> | undefined) => RootRoute<TSearchSchemaInput, TSearchSchema, TSearchSchemaUsed, TRouteContextReturn, TRouteContext, TRouterContext, TLoaderDeps, TLoaderData, [TLoaderData] extends [never] ? undefined : TLoaderData>;
288
+ export declare function createRootRouteWithContext<TRouterContext extends {}>(): <TSearchSchemaInput extends Record<string, any> = RootSearchSchema, TSearchSchema extends Record<string, any> = RootSearchSchema, TSearchSchemaUsed extends Record<string, any> = RootSearchSchema, TRouteContextReturn extends RouteContext = RouteContext, TRouteContext extends RouteContext = [TRouteContextReturn] extends [never] ? RouteContext : TRouteContextReturn, TLoaderDeps extends Record<string, any> = {}, TLoaderDataReturn = unknown, TLoaderData = [TLoaderDataReturn] extends [never] ? undefined : TLoaderDataReturn>(options?: Omit<RouteOptions<any, "__root__", "", TSearchSchemaInput, TSearchSchema, TSearchSchemaUsed, TSearchSchemaUsed, TSearchSchema, {}, {}, TRouteContextReturn, TRouteContext, TRouterContext, Assign<TRouterContext, TRouteContext>, TLoaderDeps, TLoaderDataReturn, TLoaderData>, "path" | "id" | "caseSensitive" | "stringifyParams" | "parseParams" | "getParentRoute"> | undefined) => RootRoute<TSearchSchemaInput, TSearchSchema, TSearchSchemaUsed, TRouteContextReturn, TRouteContext, TRouterContext, TLoaderDeps, TLoaderData, [TLoaderData] extends [never] ? undefined : TLoaderData>;
289
289
  /**
290
290
  * @deprecated Use the `createRootRouteWithContext` function instead.
291
291
  */
@@ -358,7 +358,7 @@ export type RouteMask<TRouteTree extends AnyRoute> = {
358
358
  };
359
359
  export declare function createRouteMask<TRouteTree extends AnyRoute, TFrom extends RoutePaths<TRouteTree>, TTo extends string>(opts: {
360
360
  routeTree: TRouteTree;
361
- } & ToSubOptions<TRouteTree, TFrom, TTo>): RouteMask<TRouteTree>;
361
+ } & ToSubOptions<Router<TRouteTree, 'never'>, TFrom, TTo>): RouteMask<TRouteTree>;
362
362
  /**
363
363
  * @deprecated Use `ErrorComponentProps` instead.
364
364
  */