@tanstack/react-router 1.64.2 → 1.65.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.
@@ -1 +1 @@
1
- {"version":3,"file":"useNavigate.js","sources":["../../src/useNavigate.tsx"],"sourcesContent":["import * as React from 'react'\nimport { useRouter } from './useRouter'\nimport type { FromPathOption, NavigateOptions } from './link'\nimport type { RoutePaths } from './routeInfo'\nimport type { AnyRouter, RegisteredRouter } from './router'\n\nexport type UseNavigateResult<TDefaultFrom extends string> = <\n TRouter extends RegisteredRouter,\n TTo extends string | undefined,\n TFrom extends string = TDefaultFrom,\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '',\n>({\n from,\n ...rest\n}: NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>) => Promise<void>\n\nexport function useNavigate<\n TRouter extends AnyRouter = RegisteredRouter,\n TDefaultFrom extends string = string,\n>(_defaultOpts?: {\n from?: FromPathOption<TRouter, TDefaultFrom>\n}): UseNavigateResult<TDefaultFrom> {\n const { navigate } = useRouter()\n\n return React.useCallback(\n (options: NavigateOptions) => {\n return navigate({\n ...options,\n })\n },\n [navigate],\n ) as UseNavigateResult<TDefaultFrom>\n}\n\n// NOTE: I don't know of anyone using this. It's undocumented, so let's wait until someone needs it\n// export function typedNavigate<\n// TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n// TDefaultFrom extends RoutePaths<TRouteTree> = '/',\n// >(navigate: (opts: NavigateOptions<any>) => Promise<void>) {\n// return navigate as <\n// TFrom extends RoutePaths<TRouteTree> = TDefaultFrom,\n// TTo extends string = '',\n// TMaskFrom extends RoutePaths<TRouteTree> = '/',\n// TMaskTo extends string = '',\n// >(\n// opts?: NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>,\n// ) => Promise<void>\n// } //\n\nexport function Navigate<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n>(props: NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>): null {\n const { navigate } = useRouter()\n\n React.useEffect(() => {\n navigate({\n ...props,\n } as any)\n }, [])\n\n return null\n}\n"],"names":[],"mappings":";;AAiBO,SAAS,YAGd,cAEkC;AAC5B,QAAA,EAAE,aAAa;AAErB,SAAO,MAAM;AAAA,IACX,CAAC,YAA6B;AAC5B,aAAO,SAAS;AAAA,QACd,GAAG;AAAA,MAAA,CACJ;AAAA,IACH;AAAA,IACA,CAAC,QAAQ;AAAA,EAAA;AAEb;AAiBO,SAAS,SAMd,OAAuE;AACjE,QAAA,EAAE,aAAa;AAErB,QAAM,UAAU,MAAM;AACX,aAAA;AAAA,MACP,GAAG;AAAA,IAAA,CACG;AAAA,EACV,GAAG,CAAE,CAAA;AAEE,SAAA;AACT;"}
1
+ {"version":3,"file":"useNavigate.js","sources":["../../src/useNavigate.tsx"],"sourcesContent":["import * as React from 'react'\nimport { useRouter } from './useRouter'\nimport type { FromPathOption, NavigateOptions } from './link'\nimport type { AnyRouter, RegisteredRouter } from './router'\n\nexport type UseNavigateResult<TDefaultFrom extends string> = <\n TRouter extends RegisteredRouter,\n TTo extends string | undefined,\n TFrom extends string = TDefaultFrom,\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '',\n>({\n from,\n ...rest\n}: NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>) => Promise<void>\n\nexport function useNavigate<\n TRouter extends AnyRouter = RegisteredRouter,\n TDefaultFrom extends string = string,\n>(_defaultOpts?: {\n from?: FromPathOption<TRouter, TDefaultFrom>\n}): UseNavigateResult<TDefaultFrom> {\n const { navigate } = useRouter()\n\n return React.useCallback(\n (options: NavigateOptions) => {\n return navigate({\n ...options,\n })\n },\n [navigate],\n ) as UseNavigateResult<TDefaultFrom>\n}\n\n// NOTE: I don't know of anyone using this. It's undocumented, so let's wait until someone needs it\n// export function typedNavigate<\n// TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n// TDefaultFrom extends RoutePaths<TRouteTree> = '/',\n// >(navigate: (opts: NavigateOptions<any>) => Promise<void>) {\n// return navigate as <\n// TFrom extends RoutePaths<TRouteTree> = TDefaultFrom,\n// TTo extends string = '',\n// TMaskFrom extends RoutePaths<TRouteTree> = '/',\n// TMaskTo extends string = '',\n// >(\n// opts?: NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>,\n// ) => Promise<void>\n// } //\n\nexport function Navigate<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n>(props: NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>): null {\n const { navigate } = useRouter()\n\n React.useEffect(() => {\n navigate({\n ...props,\n } as any)\n }, [])\n\n return null\n}\n"],"names":[],"mappings":";;AAgBO,SAAS,YAGd,cAEkC;AAC5B,QAAA,EAAE,aAAa;AAErB,SAAO,MAAM;AAAA,IACX,CAAC,YAA6B;AAC5B,aAAO,SAAS;AAAA,QACd,GAAG;AAAA,MAAA,CACJ;AAAA,IACH;AAAA,IACA,CAAC,QAAQ;AAAA,EAAA;AAEb;AAiBO,SAAS,SAMd,OAAuE;AACjE,QAAA,EAAE,aAAa;AAErB,QAAM,UAAU,MAAM;AACX,aAAA;AAAA,MACP,GAAG;AAAA,IAAA,CACG;AAAA,EACV,GAAG,CAAE,CAAA;AAEE,SAAA;AACT;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useSearch.js","sources":["../../src/useSearch.tsx"],"sourcesContent":["import { useMatch } from './useMatch'\nimport type { AnyRoute } from './route'\nimport type { FullSearchSchema, RouteById, RouteIds } from './routeInfo'\nimport type { RegisteredRouter } from './router'\nimport type { MakeRouteMatch } from './Matches'\nimport type { Constrain, Expand, StrictOrFrom } from './utils'\n\nexport type UseSearchOptions<\n TFrom,\n TStrict extends boolean,\n TSearch,\n TSelected,\n> = StrictOrFrom<TFrom, TStrict> & {\n select?: (search: TSearch) => TSelected\n}\n\nexport function useSearch<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends string | undefined = undefined,\n TStrict extends boolean = true,\n TSearch = TStrict extends false\n ? FullSearchSchema<TRouteTree>\n : Expand<RouteById<TRouteTree, TFrom>['types']['fullSearchSchema']>,\n TSelected = TSearch,\n>(\n opts: UseSearchOptions<\n Constrain<TFrom, RouteIds<TRouteTree>>,\n TStrict,\n TSearch,\n TSelected\n >,\n): TSelected {\n return useMatch({\n ...opts,\n select: (match) => {\n return opts.select ? opts.select(match.search) : match.search\n },\n })\n}\n"],"names":[],"mappings":";AAgBO,SAAS,UASd,MAMW;AACX,SAAO,SAAS;AAAA,IACd,GAAG;AAAA,IACH,QAAQ,CAAC,UAAU;AACjB,aAAO,KAAK,SAAS,KAAK,OAAO,MAAM,MAAM,IAAI,MAAM;AAAA,IACzD;AAAA,EAAA,CACD;AACH;"}
1
+ {"version":3,"file":"useSearch.js","sources":["../../src/useSearch.tsx"],"sourcesContent":["import { useMatch } from './useMatch'\nimport type { AnyRoute } from './route'\nimport type { FullSearchSchema, RouteById, RouteIds } from './routeInfo'\nimport type { RegisteredRouter } from './router'\nimport type { Constrain, Expand, StrictOrFrom } from './utils'\n\nexport type UseSearchOptions<\n TFrom,\n TStrict extends boolean,\n TSearch,\n TSelected,\n> = StrictOrFrom<TFrom, TStrict> & {\n select?: (search: TSearch) => TSelected\n}\n\nexport function useSearch<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends string | undefined = undefined,\n TStrict extends boolean = true,\n TSearch = TStrict extends false\n ? FullSearchSchema<TRouteTree>\n : Expand<RouteById<TRouteTree, TFrom>['types']['fullSearchSchema']>,\n TSelected = TSearch,\n>(\n opts: UseSearchOptions<\n Constrain<TFrom, RouteIds<TRouteTree>>,\n TStrict,\n TSearch,\n TSelected\n >,\n): TSelected {\n return useMatch({\n ...opts,\n select: (match) => {\n return opts.select ? opts.select(match.search) : match.search\n },\n })\n}\n"],"names":[],"mappings":";AAeO,SAAS,UASd,MAMW;AACX,SAAO,SAAS;AAAA,IACd,GAAG;AAAA,IACH,QAAQ,CAAC,UAAU;AACjB,aAAO,KAAK,SAAS,KAAK,OAAO,MAAM,MAAM,IAAI,MAAM;AAAA,IACzD;AAAA,EAAA,CACD;AACH;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/react-router",
3
- "version": "1.64.2",
3
+ "version": "1.65.0",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -66,7 +66,7 @@
66
66
  "peerDependencies": {
67
67
  "react": ">=18",
68
68
  "react-dom": ">=18",
69
- "@tanstack/router-generator": "1.64.0"
69
+ "@tanstack/router-generator": "1.65.0"
70
70
  },
71
71
  "peerDependenciesMeta": {
72
72
  "@tanstack/router-generator": {
@@ -48,6 +48,7 @@ export type BuildLocationFn = <
48
48
  >(
49
49
  opts: ToOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & {
50
50
  leaveParams?: boolean
51
+ _includeValidateSearch?: boolean
51
52
  },
52
53
  ) => ParsedLocation
53
54
 
package/src/fileRoute.ts CHANGED
@@ -21,7 +21,7 @@ import type {
21
21
  UpdatableRouteOptions,
22
22
  } from './route'
23
23
  import type { MakeRouteMatch } from './Matches'
24
- import type { AnyRouter, RegisteredRouter } from './router'
24
+ import type { RegisteredRouter } from './router'
25
25
  import type { RouteById, RouteIds } from './routeInfo'
26
26
 
27
27
  export interface FileRoutesByPath {
package/src/link.tsx CHANGED
@@ -757,8 +757,9 @@ export function useLinkProps<
757
757
  })
758
758
 
759
759
  // All is well? Navigate!
760
- router.commitLocation({
761
- ...next,
760
+ // N.B. we don't call `router.commitLocation(next) here because we want to run `validateSearch` before committing
761
+ router.buildAndCommitLocation({
762
+ ...options,
762
763
  replace,
763
764
  resetScroll,
764
765
  startTransition,
package/src/route.ts CHANGED
@@ -16,7 +16,7 @@ import type { NavigateOptions, ParsePathParams, ToMaskOptions } from './link'
16
16
  import type { ParsedLocation } from './location'
17
17
  import type { RouteById, RouteIds, RoutePaths } from './routeInfo'
18
18
  import type { AnyRouter, RegisteredRouter, Router } from './router'
19
- import type { Assign, Constrain, Expand, NoInfer, PickRequired } from './utils'
19
+ import type { Assign, Constrain, Expand, NoInfer } from './utils'
20
20
  import type { BuildLocationFn, NavigateFn } from './RouterProvider'
21
21
  import type { NotFoundError } from './not-found'
22
22
  import type { LazyRoute } from './fileRoute'
package/src/router.ts CHANGED
@@ -1460,8 +1460,24 @@ export class Router<
1460
1460
  ? postSearchFilters.reduce((prev, next) => next(prev), destSearch)
1461
1461
  : destSearch
1462
1462
 
1463
- const search = replaceEqualDeep(fromSearch, postFilteredSearch)
1463
+ let search = postFilteredSearch
1464
1464
 
1465
+ if (opts._includeValidateSearch) {
1466
+ matchedRoutesResult?.matchedRoutes.forEach((route) => {
1467
+ try {
1468
+ if (route.options.validateSearch) {
1469
+ const validator =
1470
+ typeof route.options.validateSearch === 'object'
1471
+ ? route.options.validateSearch.parse
1472
+ : route.options.validateSearch
1473
+ search = { ...search, ...validator(search) }
1474
+ }
1475
+ } catch (e) {
1476
+ // ignore errors here because they are already handled in matchRoutes
1477
+ }
1478
+ })
1479
+ }
1480
+ search = replaceEqualDeep(fromSearch, search)
1465
1481
  const searchStr = this.options.stringifySearch(search)
1466
1482
 
1467
1483
  const hash =
@@ -1644,7 +1660,10 @@ export class Router<
1644
1660
  rest.hash = parsed.hash
1645
1661
  }
1646
1662
 
1647
- const location = this.buildLocation(rest as any)
1663
+ const location = this.buildLocation({
1664
+ ...(rest as any),
1665
+ _includeValidateSearch: true,
1666
+ })
1648
1667
  return this.commitLocation({
1649
1668
  ...location,
1650
1669
  viewTransition,
@@ -1,7 +1,6 @@
1
1
  import * as React from 'react'
2
2
  import { useRouter } from './useRouter'
3
3
  import type { FromPathOption, NavigateOptions } from './link'
4
- import type { RoutePaths } from './routeInfo'
5
4
  import type { AnyRouter, RegisteredRouter } from './router'
6
5
 
7
6
  export type UseNavigateResult<TDefaultFrom extends string> = <
package/src/useSearch.tsx CHANGED
@@ -2,7 +2,6 @@ import { useMatch } from './useMatch'
2
2
  import type { AnyRoute } from './route'
3
3
  import type { FullSearchSchema, RouteById, RouteIds } from './routeInfo'
4
4
  import type { RegisteredRouter } from './router'
5
- import type { MakeRouteMatch } from './Matches'
6
5
  import type { Constrain, Expand, StrictOrFrom } from './utils'
7
6
 
8
7
  export type UseSearchOptions<