@tanstack/router-core 1.119.0 → 1.120.4-alpha.1

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 (51) hide show
  1. package/dist/cjs/fileRoute.d.cts +6 -2
  2. package/dist/cjs/index.cjs +4 -0
  3. package/dist/cjs/index.cjs.map +1 -1
  4. package/dist/cjs/index.d.cts +5 -5
  5. package/dist/cjs/link.cjs.map +1 -1
  6. package/dist/cjs/link.d.cts +7 -2
  7. package/dist/cjs/path.cjs +130 -16
  8. package/dist/cjs/path.cjs.map +1 -1
  9. package/dist/cjs/path.d.cts +17 -0
  10. package/dist/cjs/redirect.cjs +19 -14
  11. package/dist/cjs/redirect.cjs.map +1 -1
  12. package/dist/cjs/redirect.d.cts +10 -8
  13. package/dist/cjs/route.cjs +12 -1
  14. package/dist/cjs/route.cjs.map +1 -1
  15. package/dist/cjs/route.d.cts +10 -11
  16. package/dist/cjs/router.cjs +227 -155
  17. package/dist/cjs/router.cjs.map +1 -1
  18. package/dist/cjs/router.d.cts +50 -7
  19. package/dist/cjs/typePrimitives.d.cts +2 -2
  20. package/dist/cjs/utils.cjs.map +1 -1
  21. package/dist/cjs/utils.d.cts +3 -1
  22. package/dist/esm/fileRoute.d.ts +6 -2
  23. package/dist/esm/index.d.ts +5 -5
  24. package/dist/esm/index.js +7 -3
  25. package/dist/esm/link.d.ts +7 -2
  26. package/dist/esm/link.js.map +1 -1
  27. package/dist/esm/path.d.ts +17 -0
  28. package/dist/esm/path.js +130 -16
  29. package/dist/esm/path.js.map +1 -1
  30. package/dist/esm/redirect.d.ts +10 -8
  31. package/dist/esm/redirect.js +20 -15
  32. package/dist/esm/redirect.js.map +1 -1
  33. package/dist/esm/route.d.ts +10 -11
  34. package/dist/esm/route.js +12 -1
  35. package/dist/esm/route.js.map +1 -1
  36. package/dist/esm/router.d.ts +50 -7
  37. package/dist/esm/router.js +230 -158
  38. package/dist/esm/router.js.map +1 -1
  39. package/dist/esm/typePrimitives.d.ts +2 -2
  40. package/dist/esm/utils.d.ts +3 -1
  41. package/dist/esm/utils.js.map +1 -1
  42. package/package.json +2 -2
  43. package/src/fileRoute.ts +90 -1
  44. package/src/index.ts +13 -3
  45. package/src/link.ts +10 -7
  46. package/src/path.ts +181 -16
  47. package/src/redirect.ts +42 -28
  48. package/src/route.ts +96 -23
  49. package/src/router.ts +332 -215
  50. package/src/typePrimitives.ts +2 -2
  51. package/src/utils.ts +20 -6
package/src/redirect.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { NavigateOptions } from './link'
2
- import type { RoutePaths } from './routeInfo'
3
2
  import type { AnyRouter, RegisteredRouter } from './router'
4
- import type { PickAsRequired } from './utils'
3
+
4
+ export const tsrRedirectHeaderKey = 'X-Tanstack-Router-Redirect-Options'
5
5
 
6
6
  export type AnyRedirect = Redirect<any, any, any, any, any>
7
7
 
@@ -10,9 +10,20 @@ export type AnyRedirect = Redirect<any, any, any, any, any>
10
10
  */
11
11
  export type Redirect<
12
12
  TRouter extends AnyRouter = RegisteredRouter,
13
- TFrom extends RoutePaths<TRouter['routeTree']> | string = '/',
14
- TTo extends string | undefined = '.',
15
- TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,
13
+ TFrom extends string = string,
14
+ TTo extends string | undefined = undefined,
15
+ TMaskFrom extends string = TFrom,
16
+ TMaskTo extends string = '.',
17
+ > = Response & {
18
+ options: NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>
19
+ redirectHandled?: boolean
20
+ }
21
+
22
+ export type RedirectOptions<
23
+ TRouter extends AnyRouter = RegisteredRouter,
24
+ TFrom extends string = string,
25
+ TTo extends string | undefined = undefined,
26
+ TMaskFrom extends string = TFrom,
16
27
  TMaskTo extends string = '.',
17
28
  > = {
18
29
  href?: string
@@ -39,16 +50,11 @@ export type Redirect<
39
50
 
40
51
  export type ResolvedRedirect<
41
52
  TRouter extends AnyRouter = RegisteredRouter,
42
- TFrom extends RoutePaths<TRouter['routeTree']> = '/',
53
+ TFrom extends string = string,
43
54
  TTo extends string = '',
44
- TMaskFrom extends RoutePaths<TRouter['routeTree']> = TFrom,
55
+ TMaskFrom extends string = TFrom,
45
56
  TMaskTo extends string = '',
46
- > = PickAsRequired<
47
- Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,
48
- 'code' | 'statusCode' | 'headers'
49
- > & {
50
- href: string
51
- }
57
+ > = Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>
52
58
 
53
59
  export function redirect<
54
60
  TRouter extends AnyRouter = RegisteredRouter,
@@ -57,30 +63,38 @@ export function redirect<
57
63
  const TMaskFrom extends string = TFrom,
58
64
  const TMaskTo extends string = '',
59
65
  >(
60
- opts: Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,
66
+ opts: RedirectOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,
61
67
  ): Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> {
62
- ;(opts as any).isRedirect = true
63
68
  opts.statusCode = opts.statusCode || opts.code || 307
64
- opts.headers = opts.headers || {}
65
- if (!opts.reloadDocument) {
66
- opts.reloadDocument = false
67
- try {
68
- new URL(`${opts.href}`)
69
- opts.reloadDocument = true
70
- } catch {}
71
- }
69
+ const headers = new Headers(opts.headers || {})
70
+
71
+ const response = new Response(null, {
72
+ status: opts.statusCode,
73
+ headers,
74
+ })
75
+
76
+ ;(response as Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>).options =
77
+ opts
72
78
 
73
79
  if (opts.throw) {
74
- throw opts
80
+ throw response
75
81
  }
76
82
 
77
- return opts
83
+ return response as Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>
78
84
  }
79
85
 
80
86
  export function isRedirect(obj: any): obj is AnyRedirect {
81
- return !!obj?.isRedirect
87
+ return obj instanceof Response && !!(obj as any).options
88
+ }
89
+
90
+ export function isResolvedRedirect(obj: any): obj is AnyRedirect {
91
+ return isRedirect(obj) && !!obj.options.href
82
92
  }
83
93
 
84
- export function isResolvedRedirect(obj: any): obj is ResolvedRedirect {
85
- return !!obj?.isRedirect && obj.href
94
+ export function parseRedirect(obj: any) {
95
+ if (typeof obj === 'object' && obj.isSerializedRedirect) {
96
+ return redirect(obj)
97
+ }
98
+
99
+ return undefined
86
100
  }
package/src/route.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import invariant from 'tiny-invariant'
1
2
  import { joinPaths, trimPathLeft } from './path'
2
3
  import { notFound } from './not-found'
3
4
  import { rootRouteId } from './root'
@@ -20,6 +21,8 @@ import type {
20
21
  Constrain,
21
22
  Expand,
22
23
  IntersectAssign,
24
+ LooseAsyncReturnType,
25
+ LooseReturnType,
23
26
  NoInfer,
24
27
  } from './utils'
25
28
  import type {
@@ -270,20 +273,6 @@ export type TrimPathRight<T extends string> = T extends '/'
270
273
  ? TrimPathRight<U>
271
274
  : T
272
275
 
273
- export type LooseReturnType<T> = T extends (
274
- ...args: Array<any>
275
- ) => infer TReturn
276
- ? TReturn
277
- : never
278
-
279
- export type LooseAsyncReturnType<T> = T extends (
280
- ...args: Array<any>
281
- ) => infer TReturn
282
- ? TReturn extends Promise<infer TReturn>
283
- ? TReturn
284
- : TReturn
285
- : never
286
-
287
276
  export type ContextReturnType<TContextFn> = unknown extends TContextFn
288
277
  ? TContextFn
289
278
  : LooseReturnType<TContextFn> extends never
@@ -442,10 +431,13 @@ export type ResolveFullPath<
442
431
  TPrefixed = RoutePrefix<TParentRoute['fullPath'], TPath>,
443
432
  > = TPrefixed extends RootRouteId ? '/' : TPrefixed
444
433
 
445
- export interface RouteExtensions<TId, TFullPath> {}
434
+ export interface RouteExtensions<in out TId, in out TFullPath> {
435
+ id: TId
436
+ fullPath: TFullPath
437
+ }
446
438
 
447
439
  export type RouteLazyFn<TRoute extends AnyRoute> = (
448
- lazyFn: () => Promise<LazyRoute>,
440
+ lazyFn: () => Promise<LazyRoute<TRoute>>,
449
441
  ) => TRoute
450
442
 
451
443
  export type RouteAddChildrenFn<
@@ -564,9 +556,7 @@ export interface Route<
564
556
  in out TChildren,
565
557
  in out TFileRouteTypes,
566
558
  > extends RouteExtensions<TId, TFullPath> {
567
- fullPath: TFullPath
568
559
  path: TPath
569
- id: TId
570
560
  parentRoute: TParentRoute
571
561
  children?: TChildren
572
562
  types: RouteTypes<
@@ -601,7 +591,26 @@ export interface Route<
601
591
  >
602
592
  isRoot: TParentRoute extends AnyRoute ? true : false
603
593
  _componentsPromise?: Promise<Array<void>>
604
- lazyFn?: () => Promise<LazyRoute>
594
+ lazyFn?: () => Promise<
595
+ LazyRoute<
596
+ Route<
597
+ TParentRoute,
598
+ TPath,
599
+ TFullPath,
600
+ TCustomId,
601
+ TId,
602
+ TSearchValidator,
603
+ TParams,
604
+ TRouterContext,
605
+ TRouteContextFn,
606
+ TBeforeLoadFn,
607
+ TLoaderDeps,
608
+ TLoaderFn,
609
+ TChildren,
610
+ TFileRouteTypes
611
+ >
612
+ >
613
+ >
605
614
  _lazyPromise?: Promise<void>
606
615
  rank: number
607
616
  to: TrimPathRight<TFullPath>
@@ -620,7 +629,24 @@ export interface Route<
620
629
  TBeforeLoadFn
621
630
  >,
622
631
  ) => this
623
- lazy: RouteLazyFn<this>
632
+ lazy: RouteLazyFn<
633
+ Route<
634
+ TParentRoute,
635
+ TPath,
636
+ TFullPath,
637
+ TCustomId,
638
+ TId,
639
+ TSearchValidator,
640
+ TParams,
641
+ TRouterContext,
642
+ TRouteContextFn,
643
+ TBeforeLoadFn,
644
+ TLoaderDeps,
645
+ TLoaderFn,
646
+ TChildren,
647
+ TFileRouteTypes
648
+ >
649
+ >
624
650
  addChildren: RouteAddChildrenFn<
625
651
  TParentRoute,
626
652
  TPath,
@@ -1335,7 +1361,26 @@ export class BaseRoute<
1335
1361
  children?: TChildren
1336
1362
  originalIndex?: number
1337
1363
  rank!: number
1338
- lazyFn?: () => Promise<LazyRoute>
1364
+ lazyFn?: () => Promise<
1365
+ LazyRoute<
1366
+ Route<
1367
+ TParentRoute,
1368
+ TPath,
1369
+ TFullPath,
1370
+ TCustomId,
1371
+ TId,
1372
+ TSearchValidator,
1373
+ TParams,
1374
+ TRouterContext,
1375
+ TRouteContextFn,
1376
+ TBeforeLoadFn,
1377
+ TLoaderDeps,
1378
+ TLoaderFn,
1379
+ TChildren,
1380
+ TFileRouteTypes
1381
+ >
1382
+ >
1383
+ >
1339
1384
  _lazyPromise?: Promise<void>
1340
1385
  _componentsPromise?: Promise<Array<void>>
1341
1386
 
@@ -1408,7 +1453,8 @@ export class BaseRoute<
1408
1453
  if (isRoot) {
1409
1454
  this._path = rootRouteId as TPath
1410
1455
  } else if (!this.parentRoute) {
1411
- throw new Error(
1456
+ invariant(
1457
+ false,
1412
1458
  `Child Route instances must pass a 'getParentRoute: () => ParentRoute' option that returns a Route instance.`,
1413
1459
  )
1414
1460
  }
@@ -1448,6 +1494,16 @@ export class BaseRoute<
1448
1494
  this._ssr = options?.ssr ?? opts.defaultSsr ?? true
1449
1495
  }
1450
1496
 
1497
+ clone = (other: typeof this) => {
1498
+ this._path = other._path
1499
+ this._id = other._id
1500
+ this._fullPath = other._fullPath
1501
+ this._to = other._to
1502
+ this._ssr = other._ssr
1503
+ this.options.getParentRoute = other.options.getParentRoute
1504
+ this.children = other.children
1505
+ }
1506
+
1451
1507
  addChildren: RouteAddChildrenFn<
1452
1508
  TParentRoute,
1453
1509
  TPath,
@@ -1561,7 +1617,24 @@ export class BaseRoute<
1561
1617
  return this
1562
1618
  }
1563
1619
 
1564
- lazy: RouteLazyFn<this> = (lazyFn) => {
1620
+ lazy: RouteLazyFn<
1621
+ Route<
1622
+ TParentRoute,
1623
+ TPath,
1624
+ TFullPath,
1625
+ TCustomId,
1626
+ TId,
1627
+ TSearchValidator,
1628
+ TParams,
1629
+ TRouterContext,
1630
+ TRouteContextFn,
1631
+ TBeforeLoadFn,
1632
+ TLoaderDeps,
1633
+ TLoaderFn,
1634
+ TChildren,
1635
+ TFileRouteTypes
1636
+ >
1637
+ > = (lazyFn) => {
1565
1638
  this.lazyFn = lazyFn
1566
1639
  return this
1567
1640
  }