mirror of
https://github.com/honojs/hono.git
synced 2024-11-29 17:46:30 +01:00
fix(trie-router): fix the rule for capturing named parameter (#419)
Close #418
This commit is contained in:
parent
34b218ddf6
commit
f6f454ed42
@ -135,9 +135,23 @@ export class Node<T> {
|
||||
const part: string = parts[i]
|
||||
const isLast = i === len - 1
|
||||
const tempNodes: Node<T>[] = []
|
||||
let matched = false
|
||||
|
||||
for (let j = 0, len2 = curNodes.length; j < len2; j++) {
|
||||
const node = curNodes[j]
|
||||
const nextNode = node.children[part]
|
||||
|
||||
if (nextNode) {
|
||||
if (isLast === true) {
|
||||
// '/hello/*' => match '/hello'
|
||||
if (nextNode.children['*']) {
|
||||
handlerSets.push(...this.getHandlerSets(nextNode.children['*'], method, true))
|
||||
}
|
||||
handlerSets.push(...this.getHandlerSets(nextNode, method))
|
||||
matched = true
|
||||
}
|
||||
tempNodes.push(nextNode)
|
||||
}
|
||||
|
||||
for (let k = 0, len3 = node.patterns.length; k < len3; k++) {
|
||||
const pattern = node.patterns[k]
|
||||
@ -165,24 +179,16 @@ export class Node<T> {
|
||||
}
|
||||
tempNodes.push(node.children[key])
|
||||
}
|
||||
if (typeof name === 'string') {
|
||||
|
||||
// '/book/a' => not-slug
|
||||
// '/book/:slug' => slug
|
||||
// GET /book/a ~> no-slug, param['slug'] => undefined
|
||||
// GET /book/foo ~> slug, param['slug'] => foo
|
||||
if (typeof name === 'string' && !matched) {
|
||||
params[name] = part
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const nextNode = node.children[part]
|
||||
|
||||
if (nextNode) {
|
||||
if (isLast === true) {
|
||||
// '/hello/*' => match '/hello'
|
||||
if (nextNode.children['*']) {
|
||||
handlerSets.push(...this.getHandlerSets(nextNode.children['*'], method, true))
|
||||
}
|
||||
handlerSets.push(...this.getHandlerSets(nextNode, method))
|
||||
}
|
||||
tempNodes.push(nextNode)
|
||||
}
|
||||
}
|
||||
|
||||
curNodes = tempNodes
|
||||
|
@ -527,3 +527,21 @@ describe('star', () => {
|
||||
expect(res?.handlers).toEqual(['/*', '*', '/x', '/x/*'])
|
||||
})
|
||||
})
|
||||
|
||||
describe('Routing order With named parameters', () => {
|
||||
const node = new Node()
|
||||
node.insert('get', '/book/a', 'no-slug')
|
||||
node.insert('get', '/book/:slug', 'slug')
|
||||
it('/book/a', () => {
|
||||
const res = node.search('get', '/book/a')
|
||||
expect(res).not.toBeNull()
|
||||
expect(res?.handlers).toEqual(['no-slug', 'slug'])
|
||||
expect(res?.params['slug']).toBeUndefined()
|
||||
})
|
||||
it('/book/foo', () => {
|
||||
const res = node.search('get', '/book/foo')
|
||||
expect(res).not.toBeNull()
|
||||
expect(res?.handlers).toEqual(['slug'])
|
||||
expect(res?.params['slug']).toBe('foo')
|
||||
})
|
||||
})
|
||||
|
@ -135,9 +135,23 @@ export class Node<T> {
|
||||
const part: string = parts[i]
|
||||
const isLast = i === len - 1
|
||||
const tempNodes: Node<T>[] = []
|
||||
let matched = false
|
||||
|
||||
for (let j = 0, len2 = curNodes.length; j < len2; j++) {
|
||||
const node = curNodes[j]
|
||||
const nextNode = node.children[part]
|
||||
|
||||
if (nextNode) {
|
||||
if (isLast === true) {
|
||||
// '/hello/*' => match '/hello'
|
||||
if (nextNode.children['*']) {
|
||||
handlerSets.push(...this.getHandlerSets(nextNode.children['*'], method, true))
|
||||
}
|
||||
handlerSets.push(...this.getHandlerSets(nextNode, method))
|
||||
matched = true
|
||||
}
|
||||
tempNodes.push(nextNode)
|
||||
}
|
||||
|
||||
for (let k = 0, len3 = node.patterns.length; k < len3; k++) {
|
||||
const pattern = node.patterns[k]
|
||||
@ -165,24 +179,16 @@ export class Node<T> {
|
||||
}
|
||||
tempNodes.push(node.children[key])
|
||||
}
|
||||
if (typeof name === 'string') {
|
||||
|
||||
// '/book/a' => not-slug
|
||||
// '/book/:slug' => slug
|
||||
// GET /book/a ~> no-slug, param['slug'] => undefined
|
||||
// GET /book/foo ~> slug, param['slug'] => foo
|
||||
if (typeof name === 'string' && !matched) {
|
||||
params[name] = part
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const nextNode = node.children[part]
|
||||
|
||||
if (nextNode) {
|
||||
if (isLast === true) {
|
||||
// '/hello/*' => match '/hello'
|
||||
if (nextNode.children['*']) {
|
||||
handlerSets.push(...this.getHandlerSets(nextNode.children['*'], method, true))
|
||||
}
|
||||
handlerSets.push(...this.getHandlerSets(nextNode, method))
|
||||
}
|
||||
tempNodes.push(nextNode)
|
||||
}
|
||||
}
|
||||
|
||||
curNodes = tempNodes
|
||||
|
@ -129,3 +129,19 @@ describe('page', () => {
|
||||
expect(res?.handlers).toEqual(['page', 'fallback'])
|
||||
})
|
||||
})
|
||||
|
||||
describe('routing order with named parameters', () => {
|
||||
const router = new TrieRouter<string>()
|
||||
router.add('GET', '/book/a', 'no-slug')
|
||||
router.add('GET', '/book/:slug', 'slug')
|
||||
it('GET /book/a', async () => {
|
||||
const res = router.match('GET', '/book/a')
|
||||
expect(res?.handlers).toEqual(['no-slug', 'slug'])
|
||||
expect(res?.params['slug']).toBeUndefined()
|
||||
})
|
||||
it('GET /book/foo', async () => {
|
||||
const res = router.match('GET', '/book/foo')
|
||||
expect(res?.handlers).toEqual(['slug'])
|
||||
expect(res?.params['slug']).toBe('foo')
|
||||
})
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user