hono
hono copied to clipboard
Feature Request: Allow Path Capture Groups to trim the Value, or support lookahead/lookbehind
What is the feature you are proposing?
router.get('/test/:test{(\\w+)\\.json$}', c => c.text(c.req.param('test')))
Url: /test/something.json
Expected: something
Actual: something.json
Alternatively, allow matching outside of variable regex
router.get('/test/:test{(\\w+)}.json', c => c.text(c.req.param('test')))
Url: /test/something.json
Expected: something
Actual: 404 not found
Hi @JustinGrote
If there is no performance degradation and the amount of code does not increase too much, we can implement it, but it will be difficult if there is performance degradation.
For TrieRouter, there must be a degration though my implementation might be bad:
diff --git a/src/router/trie-router/node.ts b/src/router/trie-router/node.ts
index 7b120d4..796f6c4 100644
--- a/src/router/trie-router/node.ts
+++ b/src/router/trie-router/node.ts
@@ -163,10 +163,13 @@ export class Node<T> {
// `/js/:filename{[a-z]+.js}` => match /js/chunk/123.js
const restPathString = parts.slice(i).join('/')
- if (matcher instanceof RegExp && matcher.test(restPathString)) {
- params[name] = restPathString
- handlerSets.push(...this.gHSets(child, method, { ...params, ...node.params }))
- continue
+ if (matcher instanceof RegExp) {
+ const matchResult = restPathString.match(matcher)
+ if (matchResult) {
+ params[name] = matchResult[1]
+ handlerSets.push(...this.gHSets(child, method, { ...params, ...node.params }))
+ continue
+ }
}
if (matcher === true || (matcher instanceof RegExp && matcher.test(part))) {
diff --git a/src/utils/url.ts b/src/utils/url.ts
index 29a7d58..63bcf61 100644
--- a/src/utils/url.ts
+++ b/src/utils/url.ts
@@ -56,7 +56,11 @@ export const getPattern = (label: string): Pattern | null => {
if (match) {
if (!patternCache[label]) {
if (match[2]) {
- patternCache[label] = [label, match[1], new RegExp('^' + match[2] + '$')]
+ patternCache[label] = [
+ label,
+ match[1],
+ /\(.+\)/.test(match[2]) ? new RegExp(match[2]) : new RegExp('^(' + match[2] + ')$'),
+ ]
} else {
patternCache[label] = [label, match[1], true]
}
@usualoma
Do you have any thoughts?