Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions packages/router-core/src/new-process-route-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ function parseSegments<TRouteLike extends RouteLike>(
nextNode = next
next.parent = node
next.depth = depth
next.isIndex = true
node.wildcard ??= []
node.wildcard.push(next)
}
Expand Down Expand Up @@ -856,7 +857,6 @@ function getNodeMatch<T extends RouteLike>(
},
]

let wildcardMatch: Frame | null = null
let bestFuzzy: Frame | null = null
let bestMatch: Frame | null = null

Expand Down Expand Up @@ -888,7 +888,7 @@ function getNodeMatch<T extends RouteLike>(
let lowerPart: string

// 5. Try wildcard match
if (node.wildcard && isFrameMoreSpecific(wildcardMatch, frame)) {
if (node.wildcard) {
for (const segment of node.wildcard) {
const { prefix, suffix } = segment
if (prefix) {
Expand All @@ -905,15 +905,15 @@ function getNodeMatch<T extends RouteLike>(
if (casePart !== suffix) continue
}
// the first wildcard match is the highest priority one
wildcardMatch = {
stack.push({
node: segment,
index,
index: partsLength,
skipped,
depth,
depth: depth + 1,
statics,
dynamics,
optionals,
}
})
break
}
}
Expand Down Expand Up @@ -1020,8 +1020,6 @@ function getNodeMatch<T extends RouteLike>(

if (bestMatch) return bestMatch

if (wildcardMatch) return wildcardMatch

if (fuzzy && bestFuzzy) {
let sliceIndex = bestFuzzy.index
for (let i = 0; i < bestFuzzy.index; i++) {
Expand Down
17 changes: 17 additions & 0 deletions packages/router-core/tests/new-process-route-tree.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,23 @@ describe('findRouteMatch', () => {
expect(res?.route.id).toBe('/a/b/$')
expect(res?.params).toEqual({ _splat: 'foo', '*': 'foo' })
})
describe('edge-case #5969: trailing empty wildcard should match', () => {
it('basic', () => {
const tree = makeTree(['/a/$'])
expect(findRouteMatch('/a/', tree)?.route.id).toBe('/a/$')
expect(findRouteMatch('/a', tree)?.route.id).toBe('/a/$')
})
it('with layout route', () => {
const tree = makeTree(['/a', '/a/$'])
expect(findRouteMatch('/a/', tree)?.route.id).toBe('/a/$')
expect(findRouteMatch('/a', tree)?.route.id).toBe('/a/$')
})
it('with index route (should not match)', () => {
const tree = makeTree(['/a/', '/a/$'])
expect(findRouteMatch('/a/', tree)?.route.id).toBe('/a/')
expect(findRouteMatch('/a', tree)?.route.id).toBe('/a/')
})
})
})

describe('nested routes', () => {
Expand Down
Loading