0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-02-17 22:44:24 -05:00

fix(routing): regression on partial dynamic routes (#10355)

* fix(routing): regression on partial dynamic routes

* Update .changeset/eight-spoons-nail.md

Co-authored-by: Bjorn Lu <bjornlu.dev@gmail.com>

---------

Co-authored-by: Bjorn Lu <bjornlu.dev@gmail.com>
This commit is contained in:
Emanuele Stoppa 2024-03-07 14:48:39 +00:00 committed by GitHub
parent 4eab7f4ac3
commit 8ce9fffd44
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 24 additions and 4 deletions

View file

@ -0,0 +1,5 @@
---
"astro": patch
---
Fixes a regression where full dynamic routes were prioritized over partial dynamic routes. Now a route like `food-[name].astro` is matched **before** `[name].astro`.

View file

@ -42,11 +42,14 @@ function countOccurrences(needle: string, haystack: string) {
return count;
}
// Disable eslint as we're not sure how to improve this regex yet
// eslint-disable-next-line regexp/no-super-linear-backtracking
const ROUTE_DYNAMIC_SPLIT = /\[(.+?\(.+?\)|.+?)\]/;
const ROUTE_SPREAD = /^\.{3}.+$/;
function getParts(part: string, file: string) {
const result: RoutePart[] = [];
// Disable eslint as we're not sure how to improve this regex yet
// eslint-disable-next-line regexp/no-super-linear-backtracking
part.split(/\[(.+?\(.+?\)|.+?)\]/).map((str, i) => {
part.split(ROUTE_DYNAMIC_SPLIT).map((str, i) => {
if (!str) return;
const dynamic = i % 2 === 1;
@ -59,7 +62,7 @@ function getParts(part: string, file: string) {
result.push({
content,
dynamic,
spread: dynamic && /^\.{3}.+$/.test(content),
spread: dynamic && ROUTE_SPREAD.test(content),
});
});
@ -218,6 +221,15 @@ function routeComparator(a: RouteData, b: RouteData) {
return aIsStatic ? -1 : 1;
}
const aAllDynamic = aSegment.every((part) => part.dynamic);
const bAllDynamic = bSegment.every((part) => part.dynamic);
// Some route might have partial dynamic segments, e.g. game-[title].astro
// These routes should have higher priority against route that have **only** dynamic segments, e.g. [title].astro
if (aAllDynamic !== bAllDynamic) {
return aAllDynamic ? 1 : -1;
}
const aHasSpread = aSegment.some((part) => part.spread);
const bHasSpread = bSegment.some((part) => part.spread);

View file

@ -122,6 +122,7 @@ describe('routing - createRouteManifest', () => {
'/src/pages/[dynamic].astro': `<h1>test</h1>`,
'/src/pages/[...rest].astro': `<h1>test</h1>`,
'/src/pages/static.astro': `<h1>test</h1>`,
'/src/pages/static-[dynamic].astro': `<h1>test</h1>`,
'/src/pages/index.astro': `<h1>test</h1>`,
},
root
@ -143,6 +144,8 @@ describe('routing - createRouteManifest', () => {
assertRouteRelations(getManifestRoutes(manifest), [
['/', '/[...rest]'],
['/static', '/static-'],
['/static-', '/[dynamic]'],
['/static', '/[dynamic]'],
['/static', '/[...rest]'],
['/[dynamic]', '/[...rest]'],