@tanstack/router-core 1.121.0-alpha.3 → 1.121.0-alpha.5
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/index.d.cts +1 -1
- package/dist/cjs/link.cjs.map +1 -1
- package/dist/cjs/link.d.cts +1 -1
- package/dist/cjs/redirect.cjs +7 -0
- package/dist/cjs/redirect.cjs.map +1 -1
- package/dist/cjs/router.cjs +133 -148
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +0 -4
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/link.d.ts +1 -1
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/redirect.js +7 -0
- package/dist/esm/redirect.js.map +1 -1
- package/dist/esm/router.d.ts +0 -4
- package/dist/esm/router.js +133 -148
- package/dist/esm/router.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +0 -1
- package/src/link.ts +1 -1
- package/src/redirect.ts +8 -0
- package/src/router.ts +198 -190
package/package.json
CHANGED
package/src/index.ts
CHANGED
package/src/link.ts
CHANGED
|
@@ -424,7 +424,7 @@ export type ToSubOptionsProps<
|
|
|
424
424
|
hash?: true | Updater<string>
|
|
425
425
|
state?: true | NonNullableUpdater<ParsedHistoryState, HistoryState>
|
|
426
426
|
from?: FromPathOption<TRouter, TFrom> & {}
|
|
427
|
-
|
|
427
|
+
unsafeRelative?: 'route' | 'path'
|
|
428
428
|
}
|
|
429
429
|
|
|
430
430
|
export type ParamsReducerFn<
|
package/src/redirect.ts
CHANGED
|
@@ -64,6 +64,14 @@ export function redirect<
|
|
|
64
64
|
opts: RedirectOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,
|
|
65
65
|
): Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> {
|
|
66
66
|
opts.statusCode = opts.statusCode || opts.code || 307
|
|
67
|
+
|
|
68
|
+
if (!opts.reloadDocument) {
|
|
69
|
+
try {
|
|
70
|
+
new URL(`${opts.href}`)
|
|
71
|
+
opts.reloadDocument = true
|
|
72
|
+
} catch {}
|
|
73
|
+
}
|
|
74
|
+
|
|
67
75
|
const headers = new Headers(opts.headers || {})
|
|
68
76
|
|
|
69
77
|
const response = new Response(null, {
|
package/src/router.ts
CHANGED
|
@@ -521,11 +521,6 @@ export interface RouterErrorSerializer<TSerializedError> {
|
|
|
521
521
|
deserialize: (err: TSerializedError) => unknown
|
|
522
522
|
}
|
|
523
523
|
|
|
524
|
-
export interface MatchedRoutesResult {
|
|
525
|
-
matchedRoutes: Array<AnyRoute>
|
|
526
|
-
routeParams: Record<string, string>
|
|
527
|
-
}
|
|
528
|
-
|
|
529
524
|
export type PreloadRouteFn<
|
|
530
525
|
TRouteTree extends AnyRoute,
|
|
531
526
|
TTrailingSlashOption extends TrailingSlashOption,
|
|
@@ -1071,9 +1066,9 @@ export class RouterCore<
|
|
|
1071
1066
|
} as ParsedLocation,
|
|
1072
1067
|
opts,
|
|
1073
1068
|
)
|
|
1074
|
-
} else {
|
|
1075
|
-
return this.matchRoutesInternal(pathnameOrNext, locationSearchOrOpts)
|
|
1076
1069
|
}
|
|
1070
|
+
|
|
1071
|
+
return this.matchRoutesInternal(pathnameOrNext, locationSearchOrOpts)
|
|
1077
1072
|
}
|
|
1078
1073
|
|
|
1079
1074
|
private matchRoutesInternal(
|
|
@@ -1334,7 +1329,8 @@ export class RouterCore<
|
|
|
1334
1329
|
const route = this.looseRoutesById[match.routeId]!
|
|
1335
1330
|
const existingMatch = this.getMatch(match.id)
|
|
1336
1331
|
|
|
1337
|
-
// only execute `context` if we are not
|
|
1332
|
+
// only execute `context` if we are not calling from router.buildLocation
|
|
1333
|
+
|
|
1338
1334
|
if (!existingMatch && opts?._buildLocation !== true) {
|
|
1339
1335
|
const parentMatch = matches[index - 1]
|
|
1340
1336
|
const parentContext = getParentContext(parentMatch)
|
|
@@ -1403,75 +1399,64 @@ export class RouterCore<
|
|
|
1403
1399
|
dest: BuildNextOptions & {
|
|
1404
1400
|
unmaskOnReload?: boolean
|
|
1405
1401
|
} = {},
|
|
1406
|
-
matchedRoutesResult?: MatchedRoutesResult,
|
|
1407
1402
|
): ParsedLocation => {
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
: this.state.matches
|
|
1411
|
-
|
|
1412
|
-
const fromMatch =
|
|
1413
|
-
dest.from != null
|
|
1414
|
-
? fromMatches.find((d) =>
|
|
1415
|
-
matchPathname(this.basepath, trimPathRight(d.pathname), {
|
|
1416
|
-
to: dest.from,
|
|
1417
|
-
caseSensitive: false,
|
|
1418
|
-
fuzzy: false,
|
|
1419
|
-
}),
|
|
1420
|
-
)
|
|
1421
|
-
: undefined
|
|
1403
|
+
// We allow the caller to override the current location
|
|
1404
|
+
const currentLocation = dest._fromLocation || this.latestLocation
|
|
1422
1405
|
|
|
1423
|
-
const
|
|
1406
|
+
const allFromMatches = this.matchRoutes(currentLocation, {
|
|
1407
|
+
_buildLocation: true,
|
|
1408
|
+
})
|
|
1424
1409
|
|
|
1425
|
-
|
|
1426
|
-
dest.from == null || fromMatch != null,
|
|
1427
|
-
'Could not find match for from: ' + dest.from,
|
|
1428
|
-
)
|
|
1410
|
+
const lastMatch = last(allFromMatches)!
|
|
1429
1411
|
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1412
|
+
// First let's find the starting pathname
|
|
1413
|
+
// By default, start with the current location
|
|
1414
|
+
let fromId = lastMatch.fullPath
|
|
1433
1415
|
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
)
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
this.routesById[
|
|
1447
|
-
stayingMatches?.find((route) => {
|
|
1448
|
-
const interpolatedPath = interpolatePath({
|
|
1449
|
-
path: route.fullPath,
|
|
1450
|
-
params: matchedRoutesResult?.routeParams ?? {},
|
|
1451
|
-
decodeCharMap: this.pathParamsDecodeCharMap,
|
|
1452
|
-
}).interpolatedPath
|
|
1453
|
-
const pathname = joinPaths([this.basepath, interpolatedPath])
|
|
1454
|
-
return pathname === fromPath
|
|
1455
|
-
})?.id as keyof this['routesById']
|
|
1456
|
-
]
|
|
1457
|
-
pathname = this.resolvePathWithBase(
|
|
1458
|
-
fromPath,
|
|
1459
|
-
fromRouteByFromPathRouteId?.to ?? fromPath,
|
|
1460
|
-
)
|
|
1416
|
+
// If there is a to, it means we are changing the path in some way
|
|
1417
|
+
// So we need to find the relative fromPath
|
|
1418
|
+
if (dest.to && dest.from) {
|
|
1419
|
+
fromId = dest.from
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
const existingFrom = [...allFromMatches].reverse().find((d) => {
|
|
1423
|
+
return d.fullPath === fromId || d.fullPath === joinPaths([fromId, '/'])
|
|
1424
|
+
})
|
|
1425
|
+
|
|
1426
|
+
if (!existingFrom) {
|
|
1427
|
+
console.warn(`Could not find match for from: ${dest.from}`)
|
|
1461
1428
|
}
|
|
1462
1429
|
|
|
1463
|
-
|
|
1430
|
+
// From search should always use the current location
|
|
1431
|
+
const fromSearch = lastMatch.search
|
|
1432
|
+
// Same with params. It can't hurt to provide as many as possible
|
|
1433
|
+
const fromParams = { ...lastMatch.params }
|
|
1434
|
+
|
|
1435
|
+
// Resolve the next to
|
|
1436
|
+
const nextTo = dest.to
|
|
1437
|
+
? this.resolvePathWithBase(fromId, `${dest.to}`)
|
|
1438
|
+
: fromId
|
|
1464
1439
|
|
|
1440
|
+
// Resolve the next params
|
|
1465
1441
|
let nextParams =
|
|
1466
1442
|
(dest.params ?? true) === true
|
|
1467
|
-
?
|
|
1443
|
+
? fromParams
|
|
1468
1444
|
: {
|
|
1469
|
-
...
|
|
1470
|
-
...functionalUpdate(dest.params as any,
|
|
1445
|
+
...fromParams,
|
|
1446
|
+
...functionalUpdate(dest.params as any, fromParams),
|
|
1471
1447
|
}
|
|
1472
1448
|
|
|
1449
|
+
const destRoutes = this.matchRoutes(
|
|
1450
|
+
nextTo,
|
|
1451
|
+
{},
|
|
1452
|
+
{
|
|
1453
|
+
_buildLocation: true,
|
|
1454
|
+
},
|
|
1455
|
+
).map((d) => this.looseRoutesById[d.routeId]!)
|
|
1456
|
+
|
|
1457
|
+
// If there are any params, we need to stringify them
|
|
1473
1458
|
if (Object.keys(nextParams).length > 0) {
|
|
1474
|
-
|
|
1459
|
+
destRoutes
|
|
1475
1460
|
.map((route) => {
|
|
1476
1461
|
return (
|
|
1477
1462
|
route.options.params?.stringify ?? route.options.stringifyParams
|
|
@@ -1483,25 +1468,27 @@ export class RouterCore<
|
|
|
1483
1468
|
})
|
|
1484
1469
|
}
|
|
1485
1470
|
|
|
1486
|
-
|
|
1487
|
-
|
|
1471
|
+
// Interpolate the next to into the next pathname
|
|
1472
|
+
const nextPathname = interpolatePath({
|
|
1473
|
+
path: nextTo,
|
|
1488
1474
|
params: nextParams ?? {},
|
|
1489
1475
|
leaveWildcards: false,
|
|
1490
1476
|
leaveParams: opts.leaveParams,
|
|
1491
1477
|
decodeCharMap: this.pathParamsDecodeCharMap,
|
|
1492
1478
|
}).interpolatedPath
|
|
1493
1479
|
|
|
1494
|
-
|
|
1480
|
+
// Resolve the next search
|
|
1481
|
+
let nextSearch = fromSearch
|
|
1495
1482
|
if (opts._includeValidateSearch && this.options.search?.strict) {
|
|
1496
1483
|
let validatedSearch = {}
|
|
1497
|
-
|
|
1484
|
+
destRoutes.forEach((route) => {
|
|
1498
1485
|
try {
|
|
1499
1486
|
if (route.options.validateSearch) {
|
|
1500
1487
|
validatedSearch = {
|
|
1501
1488
|
...validatedSearch,
|
|
1502
1489
|
...(validateSearch(route.options.validateSearch, {
|
|
1503
1490
|
...validatedSearch,
|
|
1504
|
-
...
|
|
1491
|
+
...nextSearch,
|
|
1505
1492
|
}) ?? {}),
|
|
1506
1493
|
}
|
|
1507
1494
|
}
|
|
@@ -1509,137 +1496,52 @@ export class RouterCore<
|
|
|
1509
1496
|
// ignore errors here because they are already handled in matchRoutes
|
|
1510
1497
|
}
|
|
1511
1498
|
})
|
|
1512
|
-
|
|
1499
|
+
nextSearch = validatedSearch
|
|
1513
1500
|
}
|
|
1514
1501
|
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
if (route.options.search?.middlewares) {
|
|
1522
|
-
middlewares.push(...route.options.search.middlewares)
|
|
1523
|
-
}
|
|
1524
|
-
}
|
|
1525
|
-
// TODO remove preSearchFilters and postSearchFilters in v2
|
|
1526
|
-
else if (
|
|
1527
|
-
route.options.preSearchFilters ||
|
|
1528
|
-
route.options.postSearchFilters
|
|
1529
|
-
) {
|
|
1530
|
-
const legacyMiddleware: SearchMiddleware<any> = ({
|
|
1531
|
-
search,
|
|
1532
|
-
next,
|
|
1533
|
-
}) => {
|
|
1534
|
-
let nextSearch = search
|
|
1535
|
-
if (
|
|
1536
|
-
'preSearchFilters' in route.options &&
|
|
1537
|
-
route.options.preSearchFilters
|
|
1538
|
-
) {
|
|
1539
|
-
nextSearch = route.options.preSearchFilters.reduce(
|
|
1540
|
-
(prev, next) => next(prev),
|
|
1541
|
-
search,
|
|
1542
|
-
)
|
|
1543
|
-
}
|
|
1544
|
-
const result = next(nextSearch)
|
|
1545
|
-
if (
|
|
1546
|
-
'postSearchFilters' in route.options &&
|
|
1547
|
-
route.options.postSearchFilters
|
|
1548
|
-
) {
|
|
1549
|
-
return route.options.postSearchFilters.reduce(
|
|
1550
|
-
(prev, next) => next(prev),
|
|
1551
|
-
result,
|
|
1552
|
-
)
|
|
1553
|
-
}
|
|
1554
|
-
return result
|
|
1555
|
-
}
|
|
1556
|
-
middlewares.push(legacyMiddleware)
|
|
1557
|
-
}
|
|
1558
|
-
if (opts._includeValidateSearch && route.options.validateSearch) {
|
|
1559
|
-
const validate: SearchMiddleware<any> = ({ search, next }) => {
|
|
1560
|
-
const result = next(search)
|
|
1561
|
-
try {
|
|
1562
|
-
const validatedSearch = {
|
|
1563
|
-
...result,
|
|
1564
|
-
...(validateSearch(
|
|
1565
|
-
route.options.validateSearch,
|
|
1566
|
-
result,
|
|
1567
|
-
) ?? {}),
|
|
1568
|
-
}
|
|
1569
|
-
return validatedSearch
|
|
1570
|
-
} catch {
|
|
1571
|
-
// ignore errors here because they are already handled in matchRoutes
|
|
1572
|
-
return result
|
|
1573
|
-
}
|
|
1574
|
-
}
|
|
1575
|
-
middlewares.push(validate)
|
|
1576
|
-
}
|
|
1577
|
-
return acc.concat(middlewares)
|
|
1578
|
-
},
|
|
1579
|
-
[] as Array<SearchMiddleware<any>>,
|
|
1580
|
-
) ?? []
|
|
1581
|
-
|
|
1582
|
-
// the chain ends here since `next` is not called
|
|
1583
|
-
const final: SearchMiddleware<any> = ({ search }) => {
|
|
1584
|
-
if (!dest.search) {
|
|
1585
|
-
return {}
|
|
1586
|
-
}
|
|
1587
|
-
if (dest.search === true) {
|
|
1588
|
-
return search
|
|
1589
|
-
}
|
|
1590
|
-
return functionalUpdate(dest.search, search)
|
|
1591
|
-
}
|
|
1592
|
-
allMiddlewares.push(final)
|
|
1593
|
-
|
|
1594
|
-
const applyNext = (index: number, currentSearch: any): any => {
|
|
1595
|
-
// no more middlewares left, return the current search
|
|
1596
|
-
if (index >= allMiddlewares.length) {
|
|
1597
|
-
return currentSearch
|
|
1598
|
-
}
|
|
1599
|
-
|
|
1600
|
-
const middleware = allMiddlewares[index]!
|
|
1601
|
-
|
|
1602
|
-
const next = (newSearch: any): any => {
|
|
1603
|
-
return applyNext(index + 1, newSearch)
|
|
1604
|
-
}
|
|
1605
|
-
|
|
1606
|
-
return middleware({ search: currentSearch, next })
|
|
1607
|
-
}
|
|
1608
|
-
|
|
1609
|
-
// Start applying middlewares
|
|
1610
|
-
return applyNext(0, search)
|
|
1611
|
-
}
|
|
1502
|
+
nextSearch = applySearchMiddleware({
|
|
1503
|
+
search: nextSearch,
|
|
1504
|
+
dest,
|
|
1505
|
+
destRoutes,
|
|
1506
|
+
_includeValidateSearch: opts._includeValidateSearch,
|
|
1507
|
+
})
|
|
1612
1508
|
|
|
1613
|
-
|
|
1509
|
+
// Replace the equal deep
|
|
1510
|
+
nextSearch = replaceEqualDeep(fromSearch, nextSearch)
|
|
1614
1511
|
|
|
1615
|
-
|
|
1616
|
-
const searchStr = this.options.stringifySearch(
|
|
1512
|
+
// Stringify the next search
|
|
1513
|
+
const searchStr = this.options.stringifySearch(nextSearch)
|
|
1617
1514
|
|
|
1515
|
+
// Resolve the next hash
|
|
1618
1516
|
const hash =
|
|
1619
1517
|
dest.hash === true
|
|
1620
|
-
?
|
|
1518
|
+
? currentLocation.hash
|
|
1621
1519
|
: dest.hash
|
|
1622
|
-
? functionalUpdate(dest.hash,
|
|
1520
|
+
? functionalUpdate(dest.hash, currentLocation.hash)
|
|
1623
1521
|
: undefined
|
|
1624
1522
|
|
|
1523
|
+
// Resolve the next hash string
|
|
1625
1524
|
const hashStr = hash ? `#${hash}` : ''
|
|
1626
1525
|
|
|
1526
|
+
// Resolve the next state
|
|
1627
1527
|
let nextState =
|
|
1628
1528
|
dest.state === true
|
|
1629
|
-
?
|
|
1529
|
+
? currentLocation.state
|
|
1630
1530
|
: dest.state
|
|
1631
|
-
? functionalUpdate(dest.state,
|
|
1531
|
+
? functionalUpdate(dest.state, currentLocation.state)
|
|
1632
1532
|
: {}
|
|
1633
1533
|
|
|
1634
|
-
|
|
1534
|
+
// Replace the equal deep
|
|
1535
|
+
nextState = replaceEqualDeep(currentLocation.state, nextState)
|
|
1635
1536
|
|
|
1537
|
+
// Return the next location
|
|
1636
1538
|
return {
|
|
1637
|
-
pathname,
|
|
1638
|
-
search,
|
|
1539
|
+
pathname: nextPathname,
|
|
1540
|
+
search: nextSearch,
|
|
1639
1541
|
searchStr,
|
|
1640
1542
|
state: nextState as any,
|
|
1641
1543
|
hash: hash ?? '',
|
|
1642
|
-
href: `${
|
|
1544
|
+
href: `${nextPathname}${searchStr}${hashStr}`,
|
|
1643
1545
|
unmaskOnReload: dest.unmaskOnReload,
|
|
1644
1546
|
}
|
|
1645
1547
|
}
|
|
@@ -1649,6 +1551,7 @@ export class RouterCore<
|
|
|
1649
1551
|
maskedDest?: BuildNextOptions,
|
|
1650
1552
|
) => {
|
|
1651
1553
|
const next = build(dest)
|
|
1554
|
+
|
|
1652
1555
|
let maskedNext = maskedDest ? build(maskedDest) : undefined
|
|
1653
1556
|
|
|
1654
1557
|
if (!maskedNext) {
|
|
@@ -1680,22 +1583,12 @@ export class RouterCore<
|
|
|
1680
1583
|
}
|
|
1681
1584
|
}
|
|
1682
1585
|
|
|
1683
|
-
const nextMatches = this.getMatchedRoutes(
|
|
1684
|
-
next.pathname,
|
|
1685
|
-
dest.to as string,
|
|
1686
|
-
)
|
|
1687
|
-
const final = build(dest, nextMatches)
|
|
1688
|
-
|
|
1689
1586
|
if (maskedNext) {
|
|
1690
|
-
const
|
|
1691
|
-
|
|
1692
|
-
maskedDest?.to as string,
|
|
1693
|
-
)
|
|
1694
|
-
const maskedFinal = build(maskedDest, maskedMatches)
|
|
1695
|
-
final.maskedLocation = maskedFinal
|
|
1587
|
+
const maskedFinal = build(maskedDest)
|
|
1588
|
+
next.maskedLocation = maskedFinal
|
|
1696
1589
|
}
|
|
1697
1590
|
|
|
1698
|
-
return
|
|
1591
|
+
return next
|
|
1699
1592
|
}
|
|
1700
1593
|
|
|
1701
1594
|
if (opts.mask) {
|
|
@@ -2873,6 +2766,7 @@ export class RouterCore<
|
|
|
2873
2766
|
if (err.options.reloadDocument) {
|
|
2874
2767
|
return undefined
|
|
2875
2768
|
}
|
|
2769
|
+
|
|
2876
2770
|
return await this.preloadRoute({
|
|
2877
2771
|
...err.options,
|
|
2878
2772
|
_fromLocation: next,
|
|
@@ -3329,3 +3223,117 @@ export function getMatchedRoutes<TRouteLike extends RouteLike>({
|
|
|
3329
3223
|
|
|
3330
3224
|
return { matchedRoutes, routeParams, foundRoute }
|
|
3331
3225
|
}
|
|
3226
|
+
|
|
3227
|
+
function applySearchMiddleware({
|
|
3228
|
+
search,
|
|
3229
|
+
dest,
|
|
3230
|
+
destRoutes,
|
|
3231
|
+
_includeValidateSearch,
|
|
3232
|
+
}: {
|
|
3233
|
+
search: any
|
|
3234
|
+
dest: BuildNextOptions
|
|
3235
|
+
destRoutes: Array<AnyRoute>
|
|
3236
|
+
_includeValidateSearch: boolean | undefined
|
|
3237
|
+
}) {
|
|
3238
|
+
const allMiddlewares =
|
|
3239
|
+
destRoutes.reduce(
|
|
3240
|
+
(acc, route) => {
|
|
3241
|
+
const middlewares: Array<SearchMiddleware<any>> = []
|
|
3242
|
+
|
|
3243
|
+
if ('search' in route.options) {
|
|
3244
|
+
if (route.options.search?.middlewares) {
|
|
3245
|
+
middlewares.push(...route.options.search.middlewares)
|
|
3246
|
+
}
|
|
3247
|
+
}
|
|
3248
|
+
// TODO remove preSearchFilters and postSearchFilters in v2
|
|
3249
|
+
else if (
|
|
3250
|
+
route.options.preSearchFilters ||
|
|
3251
|
+
route.options.postSearchFilters
|
|
3252
|
+
) {
|
|
3253
|
+
const legacyMiddleware: SearchMiddleware<any> = ({
|
|
3254
|
+
search,
|
|
3255
|
+
next,
|
|
3256
|
+
}) => {
|
|
3257
|
+
let nextSearch = search
|
|
3258
|
+
|
|
3259
|
+
if (
|
|
3260
|
+
'preSearchFilters' in route.options &&
|
|
3261
|
+
route.options.preSearchFilters
|
|
3262
|
+
) {
|
|
3263
|
+
nextSearch = route.options.preSearchFilters.reduce(
|
|
3264
|
+
(prev, next) => next(prev),
|
|
3265
|
+
search,
|
|
3266
|
+
)
|
|
3267
|
+
}
|
|
3268
|
+
|
|
3269
|
+
const result = next(nextSearch)
|
|
3270
|
+
|
|
3271
|
+
if (
|
|
3272
|
+
'postSearchFilters' in route.options &&
|
|
3273
|
+
route.options.postSearchFilters
|
|
3274
|
+
) {
|
|
3275
|
+
return route.options.postSearchFilters.reduce(
|
|
3276
|
+
(prev, next) => next(prev),
|
|
3277
|
+
result,
|
|
3278
|
+
)
|
|
3279
|
+
}
|
|
3280
|
+
|
|
3281
|
+
return result
|
|
3282
|
+
}
|
|
3283
|
+
middlewares.push(legacyMiddleware)
|
|
3284
|
+
}
|
|
3285
|
+
|
|
3286
|
+
if (_includeValidateSearch && route.options.validateSearch) {
|
|
3287
|
+
const validate: SearchMiddleware<any> = ({ search, next }) => {
|
|
3288
|
+
const result = next(search)
|
|
3289
|
+
try {
|
|
3290
|
+
const validatedSearch = {
|
|
3291
|
+
...result,
|
|
3292
|
+
...(validateSearch(route.options.validateSearch, result) ?? {}),
|
|
3293
|
+
}
|
|
3294
|
+
return validatedSearch
|
|
3295
|
+
} catch {
|
|
3296
|
+
// ignore errors here because they are already handled in matchRoutes
|
|
3297
|
+
return result
|
|
3298
|
+
}
|
|
3299
|
+
}
|
|
3300
|
+
|
|
3301
|
+
middlewares.push(validate)
|
|
3302
|
+
}
|
|
3303
|
+
|
|
3304
|
+
return acc.concat(middlewares)
|
|
3305
|
+
},
|
|
3306
|
+
[] as Array<SearchMiddleware<any>>,
|
|
3307
|
+
) ?? []
|
|
3308
|
+
|
|
3309
|
+
// the chain ends here since `next` is not called
|
|
3310
|
+
const final: SearchMiddleware<any> = ({ search }) => {
|
|
3311
|
+
if (!dest.search) {
|
|
3312
|
+
return {}
|
|
3313
|
+
}
|
|
3314
|
+
if (dest.search === true) {
|
|
3315
|
+
return search
|
|
3316
|
+
}
|
|
3317
|
+
return functionalUpdate(dest.search, search)
|
|
3318
|
+
}
|
|
3319
|
+
|
|
3320
|
+
allMiddlewares.push(final)
|
|
3321
|
+
|
|
3322
|
+
const applyNext = (index: number, currentSearch: any): any => {
|
|
3323
|
+
// no more middlewares left, return the current search
|
|
3324
|
+
if (index >= allMiddlewares.length) {
|
|
3325
|
+
return currentSearch
|
|
3326
|
+
}
|
|
3327
|
+
|
|
3328
|
+
const middleware = allMiddlewares[index]!
|
|
3329
|
+
|
|
3330
|
+
const next = (newSearch: any): any => {
|
|
3331
|
+
return applyNext(index + 1, newSearch)
|
|
3332
|
+
}
|
|
3333
|
+
|
|
3334
|
+
return middleware({ search: currentSearch, next })
|
|
3335
|
+
}
|
|
3336
|
+
|
|
3337
|
+
// Start applying middlewares
|
|
3338
|
+
return applyNext(0, search)
|
|
3339
|
+
}
|