mirror of
https://github.com/honojs/hono.git
synced 2024-12-01 11:51:01 +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 part: string = parts[i]
|
||||||
const isLast = i === len - 1
|
const isLast = i === len - 1
|
||||||
const tempNodes: Node<T>[] = []
|
const tempNodes: Node<T>[] = []
|
||||||
|
let matched = false
|
||||||
|
|
||||||
for (let j = 0, len2 = curNodes.length; j < len2; j++) {
|
for (let j = 0, len2 = curNodes.length; j < len2; j++) {
|
||||||
const node = curNodes[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++) {
|
for (let k = 0, len3 = node.patterns.length; k < len3; k++) {
|
||||||
const pattern = node.patterns[k]
|
const pattern = node.patterns[k]
|
||||||
@ -165,24 +179,16 @@ export class Node<T> {
|
|||||||
}
|
}
|
||||||
tempNodes.push(node.children[key])
|
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
|
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
|
curNodes = tempNodes
|
||||||
|
@ -527,3 +527,21 @@ describe('star', () => {
|
|||||||
expect(res?.handlers).toEqual(['/*', '*', '/x', '/x/*'])
|
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 part: string = parts[i]
|
||||||
const isLast = i === len - 1
|
const isLast = i === len - 1
|
||||||
const tempNodes: Node<T>[] = []
|
const tempNodes: Node<T>[] = []
|
||||||
|
let matched = false
|
||||||
|
|
||||||
for (let j = 0, len2 = curNodes.length; j < len2; j++) {
|
for (let j = 0, len2 = curNodes.length; j < len2; j++) {
|
||||||
const node = curNodes[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++) {
|
for (let k = 0, len3 = node.patterns.length; k < len3; k++) {
|
||||||
const pattern = node.patterns[k]
|
const pattern = node.patterns[k]
|
||||||
@ -165,24 +179,16 @@ export class Node<T> {
|
|||||||
}
|
}
|
||||||
tempNodes.push(node.children[key])
|
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
|
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
|
curNodes = tempNodes
|
||||||
|
@ -129,3 +129,19 @@ describe('page', () => {
|
|||||||
expect(res?.handlers).toEqual(['page', 'fallback'])
|
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