From ec22782c756e5f9105aa6f103a177c2b98befc30 Mon Sep 17 00:00:00 2001 From: Ryan Christian Date: Sat, 19 Oct 2024 18:46:59 -0500 Subject: [PATCH 1/2] fix: Wildcard splat matches --- src/router.js | 2 +- test/node/router-match.test.js | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/router.js b/src/router.js index b999cce..8026b96 100644 --- a/src/router.js +++ b/src/router.js @@ -65,7 +65,7 @@ export const exec = (url, route, matches) => { if (!m || (!val && flag != '?' && flag != '*')) return; rest = flag == '+' || flag == '*'; // rest (+/*) match: - if (rest) val = url.slice(i).map(decodeURIComponent).join('/'); + if (rest) val = url.slice(i).map(decodeURIComponent).join('/') || undefined; // normal/optional field: else if (val) val = decodeURIComponent(val); matches.params[param] = val; diff --git a/test/node/router-match.test.js b/test/node/router-match.test.js index d3bc09b..100377c 100644 --- a/test/node/router-match.test.js +++ b/test/node/router-match.test.js @@ -58,10 +58,26 @@ test('Optional param route', () => { }); test('Optional rest param route "/:x*"', () => { - const accurateResult = execPath('/user', '/user/:id?'); - assert.equal(accurateResult, { path: '/user', params: { id: undefined }, id: undefined, query: {} }); + const matchedResult = execPath('/user', '/user/:id*'); + assert.equal(matchedResult, { path: '/user', params: { id: undefined }, id: undefined, query: {} }); - const inaccurateResult = execPath('/', '/user/:id?'); + const matchedResultWithSlash = execPath('/user/foo/bar', '/user/:id*'); + assert.equal(matchedResultWithSlash, { + path: '/user/foo/bar', + params: { id: 'foo/bar' }, + id: 'foo/bar', + query: {} + }); + + const emptyResult = execPath('/user', '/user/:id*'); + assert.equal(emptyResult, { + path: '/user', + params: { id: undefined }, + id: undefined, + query: {} + }); + + const inaccurateResult = execPath('/', '/user/:id*'); assert.equal(inaccurateResult, undefined); }); From 0ca5d63ac3b4371e8472fa91aaa806a34dd07109 Mon Sep 17 00:00:00 2001 From: Ryan Christian Date: Sat, 19 Oct 2024 19:19:54 -0500 Subject: [PATCH 2/2] docs: Add docs for spat/rest param routes --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 7070778..fbacbd3 100644 --- a/README.md +++ b/README.md @@ -170,6 +170,8 @@ Paths are matched using a simple string matching algorithm. The following featur - `:param` - Matches any URL segment, binding the value to the label (can later extract this value from `useRoute()`) - `/profile/:id` will match `/profile/123` and `/profile/abc` - `/profile/:id?` will match `/profile` and `/profile/123` + - `/profile/:id*` will match `/profile`, `/profile/123`, and `/profile/123/abc` + - `/profile/:id+` will match `/profile/123`, `/profile/123/abc` - `*` - Matches one or more URL segments - `/profile/*` will match `/profile/123`, `/profile/123/abc`, etc. @@ -177,6 +179,13 @@ These can then be composed to create more complex routes: - `/profile/:id/*` will match `/profile/123/abc`, `/profile/123/abc/def`, etc. +The difference between `/:id*` and `/:id/*` is that in the former, the `id` param will include the entire path after it, while in the latter, the `id` is just the single path segment. + +- `/profile/:id*`, with `/profile/123/abc` + - `id` is `123/abc` +- `/profile/:id/*`, with `/profile/123/abc` + - `id` is `123` + ### `useLocation` A hook to work with the `LocationProvider` to access location context.