@tanstack/router-core 1.128.6 → 1.128.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/router-core",
3
- "version": "1.128.6",
3
+ "version": "1.128.7",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
package/src/path.ts CHANGED
@@ -578,9 +578,6 @@ function isMatch(
578
578
  const baseSegment = baseSegments[baseIndex]
579
579
  const routeSegment = routeSegments[routeIndex]
580
580
 
581
- const isLastBaseSegment = baseIndex >= baseSegments.length - 1
582
- const isLastRouteSegment = routeIndex >= routeSegments.length - 1
583
-
584
581
  if (routeSegment) {
585
582
  if (routeSegment.type === SEGMENT_TYPE_WILDCARD) {
586
583
  // Capture all remaining segments for a wildcard
@@ -805,16 +802,12 @@ function isMatch(
805
802
  }
806
803
  }
807
804
 
808
- if (!isLastBaseSegment && isLastRouteSegment) {
805
+ // If we have base segments left but no route segments, it's a fuzzy match
806
+ if (baseIndex < baseSegments.length && routeIndex >= routeSegments.length) {
809
807
  params['**'] = joinPaths(
810
- baseSegments.slice(baseIndex + 1).map((d) => d.value),
808
+ baseSegments.slice(baseIndex).map((d) => d.value),
811
809
  )
812
- return !!fuzzy && routeSegment?.value !== '/'
813
- }
814
-
815
- // If we have base segments left but no route segments, it's not a match
816
- if (baseIndex < baseSegments.length && routeIndex >= routeSegments.length) {
817
- return false
810
+ return !!fuzzy && routeSegments[routeSegments.length - 1]?.value !== '/'
818
811
  }
819
812
 
820
813
  // If we have route segments left but no base segments, check if remaining are optional
package/src/router.ts CHANGED
@@ -3393,7 +3393,8 @@ export function getMatchedRoutes<TRouteLike extends RouteLike>({
3393
3393
  const result = matchPathname(basepath, trimmedPath, {
3394
3394
  to: route.fullPath,
3395
3395
  caseSensitive: route.options?.caseSensitive ?? caseSensitive,
3396
- fuzzy: false,
3396
+ // we need fuzzy matching for `notFoundMode: 'fuzzy'`
3397
+ fuzzy: true,
3397
3398
  })
3398
3399
  return result
3399
3400
  }
@@ -3403,16 +3404,34 @@ export function getMatchedRoutes<TRouteLike extends RouteLike>({
3403
3404
  if (foundRoute) {
3404
3405
  routeParams = getMatchedParams(foundRoute)!
3405
3406
  } else {
3406
- foundRoute = flatRoutes.find((route) => {
3407
+ // iterate over flatRoutes to find the best match
3408
+ // if we find a fuzzy matching route, keep looking for a perfect fit
3409
+ let fuzzyMatch:
3410
+ | { foundRoute: TRouteLike; routeParams: Record<string, string> }
3411
+ | undefined = undefined
3412
+ for (const route of flatRoutes) {
3407
3413
  const matchedParams = getMatchedParams(route)
3408
3414
 
3409
3415
  if (matchedParams) {
3410
- routeParams = matchedParams
3411
- return true
3416
+ if (
3417
+ route.path !== '/' &&
3418
+ (matchedParams as Record<string, string>)['**']
3419
+ ) {
3420
+ if (!fuzzyMatch) {
3421
+ fuzzyMatch = { foundRoute: route, routeParams: matchedParams }
3422
+ }
3423
+ } else {
3424
+ foundRoute = route
3425
+ routeParams = matchedParams
3426
+ break
3427
+ }
3412
3428
  }
3413
-
3414
- return false
3415
- })
3429
+ }
3430
+ // did not find a perfect fit, so take the fuzzy matching route if it exists
3431
+ if (!foundRoute && fuzzyMatch) {
3432
+ foundRoute = fuzzyMatch.foundRoute
3433
+ routeParams = fuzzyMatch.routeParams
3434
+ }
3416
3435
  }
3417
3436
 
3418
3437
  let routeCursor: TRouteLike = foundRoute || routesById[rootRouteId]!