0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-01-06 22:10:10 -05:00

Fix getStaticPaths regression (#11993)

* Revert "Remove dependency on path-to-regexp (#11983)"

This reverts commit 633eeaa9d8.

* Add test for regression

* Add a changeset

* Pin path-to-regexp
This commit is contained in:
Matthew Phillips 2024-09-13 15:39:51 -04:00 committed by GitHub
parent 2d016d4aba
commit ffba5d716e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 99 additions and 31 deletions

View file

@ -0,0 +1,7 @@
---
'astro': patch
---
Fix getStaticPaths regression
This reverts a previous change meant to remove a dependency, to fix a regression with multiple nested spread routes.

View file

@ -168,6 +168,7 @@
"ora": "^8.1.0",
"p-limit": "^6.1.0",
"p-queue": "^8.0.1",
"path-to-regexp": "6.2.2",
"preferred-pm": "^4.0.0",
"prompts": "^2.4.2",
"rehype": "^13.0.1",

View file

@ -1,5 +1,7 @@
import type { AstroConfig, RoutePart } from '../../../@types/astro.js';
import { compile } from 'path-to-regexp';
/**
* Sanitizes the parameters object by normalizing string values and replacing certain characters with their URL-encoded equivalents.
* @param {Record<string, string | number | undefined>} params - The parameters object to be sanitized.
@ -22,40 +24,45 @@ export function getRouteGenerator(
segments: RoutePart[][],
addTrailingSlash: AstroConfig['trailingSlash'],
) {
const template = segments
.map((segment) => {
return (
'/' +
segment
.map((part) => {
if (part.spread) {
return `:${part.content.slice(3)}(.*)?`;
} else if (part.dynamic) {
return `:${part.content}`;
} else {
return part.content
.normalize()
.replace(/\?/g, '%3F')
.replace(/#/g, '%23')
.replace(/%5B/g, '[')
.replace(/%5D/g, ']')
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
})
.join('')
);
})
.join('');
// Unless trailingSlash config is set to 'always', don't automatically append it.
let trailing: '/' | '' = '';
if (addTrailingSlash === 'always' && segments.length) {
trailing = '/';
}
const toPath = compile(template + trailing);
return (params: Record<string, string | number | undefined>): string => {
const sanitizedParams = sanitizeParams(params);
const path = toPath(sanitizedParams);
// Unless trailingSlash config is set to 'always', don't automatically append it.
let trailing: '/' | '' = '';
if (addTrailingSlash === 'always' && segments.length) {
trailing = '/';
}
const path =
segments
.map((segment) => {
return (
'/' +
segment
.map((part) => {
if (part.spread) {
return `${sanitizedParams[part.content.slice(3)] || ''}`;
} else if (part.dynamic) {
return `${sanitizedParams[part.content] || ''}`;
} else {
return part.content
.normalize()
.replace(/\?/g, '%3F')
.replace(/#/g, '%23')
.replace(/%5B/g, '[')
.replace(/%5D/g, ']');
}
})
.join('')
);
})
.join('') + trailing;
// When generating an index from a rest parameter route, `path-to-regexp` will return an
// empty string instead "/". This causes an inconsistency with static indexes that may result
// in the incorrect routes being rendered.
// To fix this, we return "/" when the path is empty.
return path || '/';
};
}

View file

@ -0,0 +1,37 @@
---
export async function getStaticPaths({ paginate }) {
const paths = [
{
slug: 'news/july-2024',
items: ['item 1', 'item 2', 'item 3', 'item 4', 'item 5', 'item 6'],
contentType: 'news',
monthYear: 'july-2024',
}
];
return paths.flatMap((path) => {
return paginate(path.items, {
params: { slug: path.slug },
props: {
contentType: path.contentType,
monthYear: path.monthYear,
},
pageSize: 2,
});
});
}
const { slug, page } = Astro.params;
---
<html>
<head>
<title>Testing</title>
</head>
<body>
<h1>Testing</h1>
<p id="slug">{slug}</p>
<p id="page">{page}</p>
</body>
</html>

View file

@ -25,4 +25,12 @@ describe('getStaticPaths with trailingSlash: ignore', () => {
let $ = cheerio.load(html);
assert.equal($('h1').text(), 'Page 2');
});
// for regression: https://github.com/withastro/astro/issues/11990
it('nested static paths generate', async () => {
let html = await fixture.readFile('/archive/news/july-2024/2/index.html');
let $ = cheerio.load(html);
assert.equal($('#slug').text(), 'news');
assert.equal($('#page').text(), 'july-2024/2');
})
});

View file

@ -693,6 +693,9 @@ importers:
p-queue:
specifier: ^8.0.1
version: 8.0.1
path-to-regexp:
specifier: 6.2.2
version: 6.2.2
preferred-pm:
specifier: ^4.0.0
version: 4.0.0
@ -9543,6 +9546,9 @@ packages:
resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==}
engines: {node: '>=16 || 14 >=14.17'}
path-to-regexp@6.2.2:
resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==}
path-type@4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
@ -15576,6 +15582,8 @@ snapshots:
lru-cache: 10.2.0
minipass: 7.1.2
path-to-regexp@6.2.2: {}
path-type@4.0.0: {}
path-type@5.0.0: {}