@tanstack/router-core 1.120.7 → 1.121.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/fileRoute.d.cts +6 -2
- package/dist/cjs/index.cjs +3 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +7 -7
- package/dist/cjs/link.cjs.map +1 -1
- package/dist/cjs/link.d.cts +18 -1
- package/dist/cjs/path.cjs +130 -16
- package/dist/cjs/path.cjs.map +1 -1
- package/dist/cjs/path.d.cts +17 -0
- package/dist/cjs/redirect.cjs +17 -7
- package/dist/cjs/redirect.cjs.map +1 -1
- package/dist/cjs/redirect.d.cts +13 -7
- package/dist/cjs/route.cjs +12 -1
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/route.d.cts +18 -27
- package/dist/cjs/router.cjs +395 -335
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +48 -8
- package/dist/cjs/typePrimitives.d.cts +2 -2
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +3 -0
- package/dist/esm/fileRoute.d.ts +6 -2
- package/dist/esm/index.d.ts +7 -7
- package/dist/esm/index.js +5 -2
- package/dist/esm/link.d.ts +18 -1
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/path.d.ts +17 -0
- package/dist/esm/path.js +130 -16
- package/dist/esm/path.js.map +1 -1
- package/dist/esm/redirect.d.ts +13 -7
- package/dist/esm/redirect.js +17 -7
- package/dist/esm/redirect.js.map +1 -1
- package/dist/esm/route.d.ts +18 -27
- package/dist/esm/route.js +12 -1
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/router.d.ts +48 -8
- package/dist/esm/router.js +398 -338
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/typePrimitives.d.ts +2 -2
- package/dist/esm/utils.d.ts +3 -0
- package/dist/esm/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/fileRoute.ts +90 -1
- package/src/index.ts +14 -8
- package/src/link.ts +97 -11
- package/src/path.ts +181 -16
- package/src/redirect.ts +39 -16
- package/src/route.ts +91 -64
- package/src/router.ts +569 -434
- package/src/typePrimitives.ts +2 -2
- package/src/utils.ts +15 -0
package/src/path.ts
CHANGED
|
@@ -5,6 +5,9 @@ import type { AnyPathParams } from './route'
|
|
|
5
5
|
export interface Segment {
|
|
6
6
|
type: 'pathname' | 'param' | 'wildcard'
|
|
7
7
|
value: string
|
|
8
|
+
// Add a new property to store the static segment if present
|
|
9
|
+
prefixSegment?: string
|
|
10
|
+
suffixSegment?: string
|
|
8
11
|
}
|
|
9
12
|
|
|
10
13
|
export function joinPaths(paths: Array<string | undefined>) {
|
|
@@ -137,10 +140,52 @@ export function resolvePath({
|
|
|
137
140
|
}
|
|
138
141
|
}
|
|
139
142
|
|
|
140
|
-
const
|
|
143
|
+
const segmentValues = baseSegments.map((segment) => {
|
|
144
|
+
if (segment.type === 'param') {
|
|
145
|
+
const param = segment.value.substring(1)
|
|
146
|
+
if (segment.prefixSegment && segment.suffixSegment) {
|
|
147
|
+
return `${segment.prefixSegment}{$${param}}${segment.suffixSegment}`
|
|
148
|
+
} else if (segment.prefixSegment) {
|
|
149
|
+
return `${segment.prefixSegment}{$${param}}`
|
|
150
|
+
} else if (segment.suffixSegment) {
|
|
151
|
+
return `{$${param}}${segment.suffixSegment}`
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (segment.type === 'wildcard') {
|
|
155
|
+
if (segment.prefixSegment && segment.suffixSegment) {
|
|
156
|
+
return `${segment.prefixSegment}{$}${segment.suffixSegment}`
|
|
157
|
+
} else if (segment.prefixSegment) {
|
|
158
|
+
return `${segment.prefixSegment}{$}`
|
|
159
|
+
} else if (segment.suffixSegment) {
|
|
160
|
+
return `{$}${segment.suffixSegment}`
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return segment.value
|
|
164
|
+
})
|
|
165
|
+
const joined = joinPaths([basepath, ...segmentValues])
|
|
141
166
|
return cleanPath(joined)
|
|
142
167
|
}
|
|
143
168
|
|
|
169
|
+
const PARAM_RE = /^\$.{1,}$/ // $paramName
|
|
170
|
+
const PARAM_W_CURLY_BRACES_RE = /^(.*?)\{(\$[a-zA-Z_$][a-zA-Z0-9_$]*)\}(.*)$/ // prefix{$paramName}suffix
|
|
171
|
+
const WILDCARD_RE = /^\$$/ // $
|
|
172
|
+
const WILDCARD_W_CURLY_BRACES_RE = /^(.*?)\{\$\}(.*)$/ // prefix{$}suffix
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Required: `/foo/$bar` ✅
|
|
176
|
+
* Prefix and Suffix: `/foo/prefix${bar}suffix` ✅
|
|
177
|
+
* Wildcard: `/foo/$` ✅
|
|
178
|
+
* Wildcard with Prefix and Suffix: `/foo/prefix{$}suffix` ✅
|
|
179
|
+
*
|
|
180
|
+
* Future:
|
|
181
|
+
* Optional: `/foo/{-bar}`
|
|
182
|
+
* Optional named segment: `/foo/{bar}`
|
|
183
|
+
* Optional named segment with Prefix and Suffix: `/foo/prefix{-bar}suffix`
|
|
184
|
+
* Escape special characters:
|
|
185
|
+
* - `/foo/[$]` - Static route
|
|
186
|
+
* - `/foo/[$]{$foo} - Dynamic route with a static prefix of `$`
|
|
187
|
+
* - `/foo/{$foo}[$]` - Dynamic route with a static suffix of `$`
|
|
188
|
+
*/
|
|
144
189
|
export function parsePathname(pathname?: string): Array<Segment> {
|
|
145
190
|
if (!pathname) {
|
|
146
191
|
return []
|
|
@@ -167,20 +212,55 @@ export function parsePathname(pathname?: string): Array<Segment> {
|
|
|
167
212
|
|
|
168
213
|
segments.push(
|
|
169
214
|
...split.map((part): Segment => {
|
|
170
|
-
|
|
215
|
+
// Check for wildcard with curly braces: prefix{$}suffix
|
|
216
|
+
const wildcardBracesMatch = part.match(WILDCARD_W_CURLY_BRACES_RE)
|
|
217
|
+
if (wildcardBracesMatch) {
|
|
218
|
+
const prefix = wildcardBracesMatch[1]
|
|
219
|
+
const suffix = wildcardBracesMatch[2]
|
|
171
220
|
return {
|
|
172
221
|
type: 'wildcard',
|
|
173
|
-
value:
|
|
222
|
+
value: '$',
|
|
223
|
+
prefixSegment: prefix || undefined,
|
|
224
|
+
suffixSegment: suffix || undefined,
|
|
174
225
|
}
|
|
175
226
|
}
|
|
176
227
|
|
|
177
|
-
|
|
228
|
+
// Check for the new parameter format: prefix{$paramName}suffix
|
|
229
|
+
const paramBracesMatch = part.match(PARAM_W_CURLY_BRACES_RE)
|
|
230
|
+
if (paramBracesMatch) {
|
|
231
|
+
const prefix = paramBracesMatch[1]
|
|
232
|
+
const paramName = paramBracesMatch[2]
|
|
233
|
+
const suffix = paramBracesMatch[3]
|
|
178
234
|
return {
|
|
179
235
|
type: 'param',
|
|
180
|
-
value:
|
|
236
|
+
value: '' + paramName,
|
|
237
|
+
prefixSegment: prefix || undefined,
|
|
238
|
+
suffixSegment: suffix || undefined,
|
|
181
239
|
}
|
|
182
240
|
}
|
|
183
241
|
|
|
242
|
+
// Check for bare parameter format: $paramName (without curly braces)
|
|
243
|
+
if (PARAM_RE.test(part)) {
|
|
244
|
+
const paramName = part.substring(1)
|
|
245
|
+
return {
|
|
246
|
+
type: 'param',
|
|
247
|
+
value: '$' + paramName,
|
|
248
|
+
prefixSegment: undefined,
|
|
249
|
+
suffixSegment: undefined,
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Check for bare wildcard: $ (without curly braces)
|
|
254
|
+
if (WILDCARD_RE.test(part)) {
|
|
255
|
+
return {
|
|
256
|
+
type: 'wildcard',
|
|
257
|
+
value: '$',
|
|
258
|
+
prefixSegment: undefined,
|
|
259
|
+
suffixSegment: undefined,
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Handle regular pathname segment
|
|
184
264
|
return {
|
|
185
265
|
type: 'pathname',
|
|
186
266
|
value: part.includes('%25')
|
|
@@ -248,9 +328,13 @@ export function interpolatePath({
|
|
|
248
328
|
interpolatedPathSegments.map((segment) => {
|
|
249
329
|
if (segment.type === 'wildcard') {
|
|
250
330
|
usedParams._splat = params._splat
|
|
331
|
+
const segmentPrefix = segment.prefixSegment || ''
|
|
332
|
+
const segmentSuffix = segment.suffixSegment || ''
|
|
251
333
|
const value = encodeParam('_splat')
|
|
252
|
-
if (leaveWildcards)
|
|
253
|
-
|
|
334
|
+
if (leaveWildcards) {
|
|
335
|
+
return `${segmentPrefix}${segment.value}${value ?? ''}${segmentSuffix}`
|
|
336
|
+
}
|
|
337
|
+
return `${segmentPrefix}${value}${segmentSuffix}`
|
|
254
338
|
}
|
|
255
339
|
|
|
256
340
|
if (segment.type === 'param') {
|
|
@@ -259,11 +343,14 @@ export function interpolatePath({
|
|
|
259
343
|
isMissingParams = true
|
|
260
344
|
}
|
|
261
345
|
usedParams[key] = params[key]
|
|
346
|
+
|
|
347
|
+
const segmentPrefix = segment.prefixSegment || ''
|
|
348
|
+
const segmentSuffix = segment.suffixSegment || ''
|
|
262
349
|
if (leaveParams) {
|
|
263
350
|
const value = encodeParam(segment.value)
|
|
264
|
-
return `${segment.value}${value ?? ''}`
|
|
351
|
+
return `${segmentPrefix}${segment.value}${value ?? ''}${segmentSuffix}`
|
|
265
352
|
}
|
|
266
|
-
return encodeParam(key) ?? 'undefined'
|
|
353
|
+
return `${segmentPrefix}${encodeParam(key) ?? 'undefined'}${segmentSuffix}`
|
|
267
354
|
}
|
|
268
355
|
|
|
269
356
|
return segment.value
|
|
@@ -390,9 +477,57 @@ export function matchByPath(
|
|
|
390
477
|
|
|
391
478
|
if (routeSegment) {
|
|
392
479
|
if (routeSegment.type === 'wildcard') {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
480
|
+
// Capture all remaining segments for a wildcard
|
|
481
|
+
const remainingBaseSegments = baseSegments.slice(i)
|
|
482
|
+
|
|
483
|
+
let _splat: string
|
|
484
|
+
|
|
485
|
+
// If this is a wildcard with prefix/suffix, we need to handle the first segment specially
|
|
486
|
+
if (routeSegment.prefixSegment || routeSegment.suffixSegment) {
|
|
487
|
+
if (!baseSegment) return false
|
|
488
|
+
|
|
489
|
+
const prefix = routeSegment.prefixSegment || ''
|
|
490
|
+
const suffix = routeSegment.suffixSegment || ''
|
|
491
|
+
|
|
492
|
+
// Check if the base segment starts with prefix and ends with suffix
|
|
493
|
+
const baseValue = baseSegment.value
|
|
494
|
+
if ('prefixSegment' in routeSegment) {
|
|
495
|
+
if (!baseValue.startsWith(prefix)) {
|
|
496
|
+
return false
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
if ('suffixSegment' in routeSegment) {
|
|
500
|
+
if (
|
|
501
|
+
!baseSegments[baseSegments.length - 1]?.value.endsWith(suffix)
|
|
502
|
+
) {
|
|
503
|
+
return false
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
let rejoinedSplat = decodeURI(
|
|
508
|
+
joinPaths(remainingBaseSegments.map((d) => d.value)),
|
|
509
|
+
)
|
|
510
|
+
|
|
511
|
+
// Remove the prefix and suffix from the rejoined splat
|
|
512
|
+
if (prefix && rejoinedSplat.startsWith(prefix)) {
|
|
513
|
+
rejoinedSplat = rejoinedSplat.slice(prefix.length)
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
if (suffix && rejoinedSplat.endsWith(suffix)) {
|
|
517
|
+
rejoinedSplat = rejoinedSplat.slice(
|
|
518
|
+
0,
|
|
519
|
+
rejoinedSplat.length - suffix.length,
|
|
520
|
+
)
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
_splat = rejoinedSplat
|
|
524
|
+
} else {
|
|
525
|
+
// If no prefix/suffix, just rejoin the remaining segments
|
|
526
|
+
_splat = decodeURI(
|
|
527
|
+
joinPaths(remainingBaseSegments.map((d) => d.value)),
|
|
528
|
+
)
|
|
529
|
+
}
|
|
530
|
+
|
|
396
531
|
// TODO: Deprecate *
|
|
397
532
|
params['*'] = _splat
|
|
398
533
|
params['_splat'] = _splat
|
|
@@ -426,11 +561,41 @@ export function matchByPath(
|
|
|
426
561
|
if (baseSegment.value === '/') {
|
|
427
562
|
return false
|
|
428
563
|
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
564
|
+
|
|
565
|
+
let _paramValue: string
|
|
566
|
+
|
|
567
|
+
// If this param has prefix/suffix, we need to extract the actual parameter value
|
|
568
|
+
if (routeSegment.prefixSegment || routeSegment.suffixSegment) {
|
|
569
|
+
const prefix = routeSegment.prefixSegment || ''
|
|
570
|
+
const suffix = routeSegment.suffixSegment || ''
|
|
571
|
+
|
|
572
|
+
// Check if the base segment starts with prefix and ends with suffix
|
|
573
|
+
const baseValue = baseSegment.value
|
|
574
|
+
if (prefix && !baseValue.startsWith(prefix)) {
|
|
575
|
+
return false
|
|
576
|
+
}
|
|
577
|
+
if (suffix && !baseValue.endsWith(suffix)) {
|
|
578
|
+
return false
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
let paramValue = baseValue
|
|
582
|
+
if (prefix && paramValue.startsWith(prefix)) {
|
|
583
|
+
paramValue = paramValue.slice(prefix.length)
|
|
584
|
+
}
|
|
585
|
+
if (suffix && paramValue.endsWith(suffix)) {
|
|
586
|
+
paramValue = paramValue.slice(
|
|
587
|
+
0,
|
|
588
|
+
paramValue.length - suffix.length,
|
|
589
|
+
)
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
_paramValue = decodeURIComponent(paramValue)
|
|
593
|
+
} else {
|
|
594
|
+
// If no prefix/suffix, just decode the base segment value
|
|
595
|
+
_paramValue = decodeURIComponent(baseSegment.value)
|
|
433
596
|
}
|
|
597
|
+
|
|
598
|
+
params[routeSegment.value.substring(1)] = _paramValue
|
|
434
599
|
}
|
|
435
600
|
}
|
|
436
601
|
|
package/src/redirect.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { NavigateOptions } from './link'
|
|
2
2
|
import type { AnyRouter, RegisteredRouter } from './router'
|
|
3
|
-
import type { PickAsRequired } from './utils'
|
|
4
3
|
|
|
5
4
|
export type AnyRedirect = Redirect<any, any, any, any, any>
|
|
6
5
|
|
|
@@ -13,6 +12,17 @@ export type Redirect<
|
|
|
13
12
|
TTo extends string | undefined = undefined,
|
|
14
13
|
TMaskFrom extends string = TFrom,
|
|
15
14
|
TMaskTo extends string = '.',
|
|
15
|
+
> = Response & {
|
|
16
|
+
options: NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>
|
|
17
|
+
redirectHandled?: boolean
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type RedirectOptions<
|
|
21
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
22
|
+
TFrom extends string = string,
|
|
23
|
+
TTo extends string | undefined = undefined,
|
|
24
|
+
TMaskFrom extends string = TFrom,
|
|
25
|
+
TMaskTo extends string = '.',
|
|
16
26
|
> = {
|
|
17
27
|
href?: string
|
|
18
28
|
/**
|
|
@@ -42,12 +52,7 @@ export type ResolvedRedirect<
|
|
|
42
52
|
TTo extends string = '',
|
|
43
53
|
TMaskFrom extends string = TFrom,
|
|
44
54
|
TMaskTo extends string = '',
|
|
45
|
-
> =
|
|
46
|
-
Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,
|
|
47
|
-
'code' | 'statusCode' | 'headers'
|
|
48
|
-
> & {
|
|
49
|
-
href: string
|
|
50
|
-
}
|
|
55
|
+
> = Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>
|
|
51
56
|
|
|
52
57
|
export function redirect<
|
|
53
58
|
TRouter extends AnyRouter = RegisteredRouter,
|
|
@@ -56,30 +61,48 @@ export function redirect<
|
|
|
56
61
|
const TMaskFrom extends string = TFrom,
|
|
57
62
|
const TMaskTo extends string = '',
|
|
58
63
|
>(
|
|
59
|
-
opts:
|
|
64
|
+
opts: RedirectOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,
|
|
60
65
|
): Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> {
|
|
61
|
-
;(opts as any).isRedirect = true
|
|
62
66
|
opts.statusCode = opts.statusCode || opts.code || 307
|
|
63
|
-
|
|
67
|
+
|
|
64
68
|
if (!opts.reloadDocument) {
|
|
65
|
-
opts.reloadDocument = false
|
|
66
69
|
try {
|
|
67
70
|
new URL(`${opts.href}`)
|
|
68
71
|
opts.reloadDocument = true
|
|
69
72
|
} catch {}
|
|
70
73
|
}
|
|
71
74
|
|
|
75
|
+
const headers = new Headers(opts.headers || {})
|
|
76
|
+
|
|
77
|
+
const response = new Response(null, {
|
|
78
|
+
status: opts.statusCode,
|
|
79
|
+
headers,
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
;(response as Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>).options =
|
|
83
|
+
opts
|
|
84
|
+
|
|
72
85
|
if (opts.throw) {
|
|
73
|
-
throw
|
|
86
|
+
throw response
|
|
74
87
|
}
|
|
75
88
|
|
|
76
|
-
return
|
|
89
|
+
return response as Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>
|
|
77
90
|
}
|
|
78
91
|
|
|
79
92
|
export function isRedirect(obj: any): obj is AnyRedirect {
|
|
80
|
-
return !!obj
|
|
93
|
+
return obj instanceof Response && !!(obj as any).options
|
|
81
94
|
}
|
|
82
95
|
|
|
83
|
-
export function isResolvedRedirect(
|
|
84
|
-
|
|
96
|
+
export function isResolvedRedirect(
|
|
97
|
+
obj: any,
|
|
98
|
+
): obj is AnyRedirect & { options: { href: string } } {
|
|
99
|
+
return isRedirect(obj) && !!obj.options.href
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function parseRedirect(obj: any) {
|
|
103
|
+
if (typeof obj === 'object' && obj.isSerializedRedirect) {
|
|
104
|
+
return redirect(obj)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return undefined
|
|
85
108
|
}
|
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'
|
|
@@ -17,9 +18,12 @@ import type { AnyRouter, RegisteredRouter } from './router'
|
|
|
17
18
|
import type { BuildLocationFn, NavigateFn } from './RouterProvider'
|
|
18
19
|
import type {
|
|
19
20
|
Assign,
|
|
21
|
+
Awaitable,
|
|
20
22
|
Constrain,
|
|
21
23
|
Expand,
|
|
22
24
|
IntersectAssign,
|
|
25
|
+
LooseAsyncReturnType,
|
|
26
|
+
LooseReturnType,
|
|
23
27
|
NoInfer,
|
|
24
28
|
} from './utils'
|
|
25
29
|
import type {
|
|
@@ -150,27 +154,24 @@ export type ResolveSearchSchema<TSearchValidator> =
|
|
|
150
154
|
? ResolveSearchSchemaFn<TSearchValidator['parse']>
|
|
151
155
|
: ResolveSearchSchemaFn<TSearchValidator>
|
|
152
156
|
|
|
153
|
-
export type
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
? never
|
|
157
|
-
: '_splat'
|
|
158
|
-
: '_splat'
|
|
157
|
+
export type ResolveRequiredParams<TPath extends string, T> = {
|
|
158
|
+
[K in ParsePathParams<TPath>['required']]: T
|
|
159
|
+
}
|
|
159
160
|
|
|
160
|
-
export
|
|
161
|
-
|
|
161
|
+
export type ResolveOptionalParams<TPath extends string, T> = {
|
|
162
|
+
[K in ParsePathParams<TPath>['optional']]?: T
|
|
162
163
|
}
|
|
163
164
|
|
|
164
|
-
export type ResolveParams<
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
165
|
+
export type ResolveParams<
|
|
166
|
+
TPath extends string,
|
|
167
|
+
T = string,
|
|
168
|
+
> = ResolveRequiredParams<TPath, T> & ResolveOptionalParams<TPath, T>
|
|
168
169
|
|
|
169
170
|
export type ParseParamsFn<in out TPath extends string, in out TParams> = (
|
|
170
|
-
rawParams: ResolveParams<TPath
|
|
171
|
-
) => TParams extends
|
|
171
|
+
rawParams: Expand<ResolveParams<TPath>>,
|
|
172
|
+
) => TParams extends ResolveParams<TPath, any>
|
|
172
173
|
? TParams
|
|
173
|
-
:
|
|
174
|
+
: ResolveParams<TPath, any>
|
|
174
175
|
|
|
175
176
|
export type StringifyParamsFn<in out TPath extends string, in out TParams> = (
|
|
176
177
|
params: TParams,
|
|
@@ -270,20 +271,6 @@ export type TrimPathRight<T extends string> = T extends '/'
|
|
|
270
271
|
? TrimPathRight<U>
|
|
271
272
|
: T
|
|
272
273
|
|
|
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
274
|
export type ContextReturnType<TContextFn> = unknown extends TContextFn
|
|
288
275
|
? TContextFn
|
|
289
276
|
: LooseReturnType<TContextFn> extends never
|
|
@@ -448,7 +435,7 @@ export interface RouteExtensions<in out TId, in out TFullPath> {
|
|
|
448
435
|
}
|
|
449
436
|
|
|
450
437
|
export type RouteLazyFn<TRoute extends AnyRoute> = (
|
|
451
|
-
lazyFn: () => Promise<LazyRoute
|
|
438
|
+
lazyFn: () => Promise<LazyRoute<TRoute>>,
|
|
452
439
|
) => TRoute
|
|
453
440
|
|
|
454
441
|
export type RouteAddChildrenFn<
|
|
@@ -602,7 +589,26 @@ export interface Route<
|
|
|
602
589
|
>
|
|
603
590
|
isRoot: TParentRoute extends AnyRoute ? true : false
|
|
604
591
|
_componentsPromise?: Promise<Array<void>>
|
|
605
|
-
lazyFn?: () => Promise<
|
|
592
|
+
lazyFn?: () => Promise<
|
|
593
|
+
LazyRoute<
|
|
594
|
+
Route<
|
|
595
|
+
TParentRoute,
|
|
596
|
+
TPath,
|
|
597
|
+
TFullPath,
|
|
598
|
+
TCustomId,
|
|
599
|
+
TId,
|
|
600
|
+
TSearchValidator,
|
|
601
|
+
TParams,
|
|
602
|
+
TRouterContext,
|
|
603
|
+
TRouteContextFn,
|
|
604
|
+
TBeforeLoadFn,
|
|
605
|
+
TLoaderDeps,
|
|
606
|
+
TLoaderFn,
|
|
607
|
+
TChildren,
|
|
608
|
+
TFileRouteTypes
|
|
609
|
+
>
|
|
610
|
+
>
|
|
611
|
+
>
|
|
606
612
|
_lazyPromise?: Promise<void>
|
|
607
613
|
rank: number
|
|
608
614
|
to: TrimPathRight<TFullPath>
|
|
@@ -1100,7 +1106,7 @@ export interface UpdatableRouteOptions<
|
|
|
1100
1106
|
TBeforeLoadFn,
|
|
1101
1107
|
TLoaderDeps
|
|
1102
1108
|
>,
|
|
1103
|
-
) => Record<string, string
|
|
1109
|
+
) => Awaitable<Record<string, string>>
|
|
1104
1110
|
head?: (
|
|
1105
1111
|
ctx: AssetFnContextOptions<
|
|
1106
1112
|
TRouteId,
|
|
@@ -1114,11 +1120,11 @@ export interface UpdatableRouteOptions<
|
|
|
1114
1120
|
TBeforeLoadFn,
|
|
1115
1121
|
TLoaderDeps
|
|
1116
1122
|
>,
|
|
1117
|
-
) => {
|
|
1123
|
+
) => Awaitable<{
|
|
1118
1124
|
links?: AnyRouteMatch['links']
|
|
1119
1125
|
scripts?: AnyRouteMatch['headScripts']
|
|
1120
1126
|
meta?: AnyRouteMatch['meta']
|
|
1121
|
-
}
|
|
1127
|
+
}>
|
|
1122
1128
|
scripts?: (
|
|
1123
1129
|
ctx: AssetFnContextOptions<
|
|
1124
1130
|
TRouteId,
|
|
@@ -1132,7 +1138,7 @@ export interface UpdatableRouteOptions<
|
|
|
1132
1138
|
TBeforeLoadFn,
|
|
1133
1139
|
TLoaderDeps
|
|
1134
1140
|
>,
|
|
1135
|
-
) => AnyRouteMatch['scripts']
|
|
1141
|
+
) => Awaitable<AnyRouteMatch['scripts']>
|
|
1136
1142
|
ssr?: boolean
|
|
1137
1143
|
codeSplitGroupings?: Array<
|
|
1138
1144
|
Array<
|
|
@@ -1298,7 +1304,24 @@ export class BaseRoute<
|
|
|
1298
1304
|
in out TLoaderFn = undefined,
|
|
1299
1305
|
in out TChildren = unknown,
|
|
1300
1306
|
in out TFileRouteTypes = unknown,
|
|
1301
|
-
>
|
|
1307
|
+
> implements
|
|
1308
|
+
Route<
|
|
1309
|
+
TParentRoute,
|
|
1310
|
+
TPath,
|
|
1311
|
+
TFullPath,
|
|
1312
|
+
TCustomId,
|
|
1313
|
+
TId,
|
|
1314
|
+
TSearchValidator,
|
|
1315
|
+
TParams,
|
|
1316
|
+
TRouterContext,
|
|
1317
|
+
TRouteContextFn,
|
|
1318
|
+
TBeforeLoadFn,
|
|
1319
|
+
TLoaderDeps,
|
|
1320
|
+
TLoaderFn,
|
|
1321
|
+
TChildren,
|
|
1322
|
+
TFileRouteTypes
|
|
1323
|
+
>
|
|
1324
|
+
{
|
|
1302
1325
|
isRoot: TParentRoute extends AnyRoute ? true : false
|
|
1303
1326
|
options: RouteOptions<
|
|
1304
1327
|
TParentRoute,
|
|
@@ -1347,7 +1370,26 @@ export class BaseRoute<
|
|
|
1347
1370
|
children?: TChildren
|
|
1348
1371
|
originalIndex?: number
|
|
1349
1372
|
rank!: number
|
|
1350
|
-
lazyFn?: () => Promise<
|
|
1373
|
+
lazyFn?: () => Promise<
|
|
1374
|
+
LazyRoute<
|
|
1375
|
+
Route<
|
|
1376
|
+
TParentRoute,
|
|
1377
|
+
TPath,
|
|
1378
|
+
TFullPath,
|
|
1379
|
+
TCustomId,
|
|
1380
|
+
TId,
|
|
1381
|
+
TSearchValidator,
|
|
1382
|
+
TParams,
|
|
1383
|
+
TRouterContext,
|
|
1384
|
+
TRouteContextFn,
|
|
1385
|
+
TBeforeLoadFn,
|
|
1386
|
+
TLoaderDeps,
|
|
1387
|
+
TLoaderFn,
|
|
1388
|
+
TChildren,
|
|
1389
|
+
TFileRouteTypes
|
|
1390
|
+
>
|
|
1391
|
+
>
|
|
1392
|
+
>
|
|
1351
1393
|
_lazyPromise?: Promise<void>
|
|
1352
1394
|
_componentsPromise?: Promise<Array<void>>
|
|
1353
1395
|
|
|
@@ -1420,7 +1462,8 @@ export class BaseRoute<
|
|
|
1420
1462
|
if (isRoot) {
|
|
1421
1463
|
this._path = rootRouteId as TPath
|
|
1422
1464
|
} else if (!this.parentRoute) {
|
|
1423
|
-
|
|
1465
|
+
invariant(
|
|
1466
|
+
false,
|
|
1424
1467
|
`Child Route instances must pass a 'getParentRoute: () => ParentRoute' option that returns a Route instance.`,
|
|
1425
1468
|
)
|
|
1426
1469
|
}
|
|
@@ -1460,6 +1503,16 @@ export class BaseRoute<
|
|
|
1460
1503
|
this._ssr = options?.ssr ?? opts.defaultSsr ?? true
|
|
1461
1504
|
}
|
|
1462
1505
|
|
|
1506
|
+
clone = (other: typeof this) => {
|
|
1507
|
+
this._path = other._path
|
|
1508
|
+
this._id = other._id
|
|
1509
|
+
this._fullPath = other._fullPath
|
|
1510
|
+
this._to = other._to
|
|
1511
|
+
this._ssr = other._ssr
|
|
1512
|
+
this.options.getParentRoute = other.options.getParentRoute
|
|
1513
|
+
this.children = other.children
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1463
1516
|
addChildren: RouteAddChildrenFn<
|
|
1464
1517
|
TParentRoute,
|
|
1465
1518
|
TPath,
|
|
@@ -1608,32 +1661,6 @@ export class BaseRouteApi<TId, TRouter extends AnyRouter = RegisteredRouter> {
|
|
|
1608
1661
|
}
|
|
1609
1662
|
}
|
|
1610
1663
|
|
|
1611
|
-
export interface RootRoute<
|
|
1612
|
-
in out TSearchValidator = undefined,
|
|
1613
|
-
in out TRouterContext = {},
|
|
1614
|
-
in out TRouteContextFn = AnyContext,
|
|
1615
|
-
in out TBeforeLoadFn = AnyContext,
|
|
1616
|
-
in out TLoaderDeps extends Record<string, any> = {},
|
|
1617
|
-
in out TLoaderFn = undefined,
|
|
1618
|
-
in out TChildren = unknown,
|
|
1619
|
-
in out TFileRouteTypes = unknown,
|
|
1620
|
-
> extends Route<
|
|
1621
|
-
any, // TParentRoute
|
|
1622
|
-
'/', // TPath
|
|
1623
|
-
'/', // TFullPath
|
|
1624
|
-
string, // TCustomId
|
|
1625
|
-
RootRouteId, // TId
|
|
1626
|
-
TSearchValidator, // TSearchValidator
|
|
1627
|
-
{}, // TParams
|
|
1628
|
-
TRouterContext,
|
|
1629
|
-
TRouteContextFn,
|
|
1630
|
-
TBeforeLoadFn,
|
|
1631
|
-
TLoaderDeps,
|
|
1632
|
-
TLoaderFn,
|
|
1633
|
-
TChildren, // TChildren
|
|
1634
|
-
TFileRouteTypes
|
|
1635
|
-
> {}
|
|
1636
|
-
|
|
1637
1664
|
export class BaseRootRoute<
|
|
1638
1665
|
in out TSearchValidator = undefined,
|
|
1639
1666
|
in out TRouterContext = {},
|