Prevent /undefined catch-all routes in dev (#4873)

This commit is contained in:
Bjorn Lu 2022-09-27 02:03:14 +08:00 committed by GitHub
parent 03e8b750ad
commit 83ed1cc1f2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 66 additions and 9 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Prevent /undefined catch-all routes in dev

View file

@ -108,13 +108,9 @@ export class RouteCache {
export function findPathItemByKey(staticPaths: GetStaticPathsResultKeyed, params: Params) {
const paramsKey = stringifyParams(params);
let matchedStaticPath = staticPaths.keyed.get(paramsKey);
const matchedStaticPath = staticPaths.keyed.get(paramsKey);
if (matchedStaticPath) {
return matchedStaticPath;
}
debug('findPathItemByKey', `Unexpected cache miss looking for ${paramsKey}`);
matchedStaticPath = staticPaths.find(
({ params: _params }) => JSON.stringify(_params) === paramsKey
);
}

View file

@ -32,7 +32,7 @@ export function stringifyParams(params: Params) {
const validatedParams = Object.entries(params).reduce((acc, next) => {
validateGetStaticPathsParameter(next);
const [key, value] = next;
acc[key] = `${value}`;
acc[key] = typeof value === 'undefined' ? undefined : `${value}`;
return acc;
}, {} as Params);

View file

@ -0,0 +1,22 @@
---
export function getStaticPaths() {
return [{
params: { slug: undefined },
}, {
params: { slug: 'potato' },
}]
}
const { slug } = Astro.params
---
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>{slug}</title>
</head>
<body>
<h1>empty-slug/[...slug].astro</h1>
<p>slug: {slug}</p>
</body>
</html>

View file

@ -95,6 +95,17 @@ const routes = [
h1: '[id].astro',
p: 'injected-2',
},
{
description: 'matches /empty-slug to empty-slug/[...slug].astro',
url: '/empty-slug',
h1: 'empty-slug/[...slug].astro',
p: 'slug: ',
},
{
description: 'do not match /empty-slug/undefined to empty-slug/[...slug].astro',
url: '/empty-slug/undefined',
fourOhFour: true,
},
];
function appendForwardSlash(path) {
@ -112,9 +123,16 @@ describe('Routing priority', () => {
await fixture.build();
});
routes.forEach(({ description, url, h1, p }) => {
routes.forEach(({ description, url, fourOhFour, h1, p }) => {
it(description, async () => {
const html = await fixture.readFile(`${appendForwardSlash(url)}index.html`);
const htmlFile = `${appendForwardSlash(url)}index.html`;
if (fourOhFour) {
expect(fixture.pathExists(htmlFile)).to.be.false;
return;
}
const html = await fixture.readFile(htmlFile);
const $ = cheerioLoad(html);
expect($('h1').text()).to.equal(h1);
@ -142,12 +160,17 @@ describe('Routing priority', () => {
await devServer.stop();
});
routes.forEach(({ description, url, h1, p }) => {
routes.forEach(({ description, url, fourOhFour, h1, p }) => {
// checks URLs as written above
it(description, async () => {
const html = await fixture.fetch(url).then((res) => res.text());
const $ = cheerioLoad(html);
if (fourOhFour) {
expect($('title').text()).to.equal('404: Not Found');
return;
}
expect($('h1').text()).to.equal(h1);
if (p) {
@ -160,6 +183,11 @@ describe('Routing priority', () => {
const html = await fixture.fetch(appendForwardSlash(url)).then((res) => res.text());
const $ = cheerioLoad(html);
if (fourOhFour) {
expect($('title').text()).to.equal('404: Not Found');
return;
}
expect($('h1').text()).to.equal(h1);
if (p) {
@ -174,6 +202,11 @@ describe('Routing priority', () => {
.then((res) => res.text());
const $ = cheerioLoad(html);
if (fourOhFour) {
expect($('title').text()).to.equal('404: Not Found');
return;
}
expect($('h1').text()).to.equal(h1);
if (p) {

View file

@ -156,6 +156,7 @@ export async function loadFixture(inlineConfig) {
const previewServer = await preview(settings, { logging, telemetry, ...opts });
return previewServer;
},
pathExists: (p) => fs.existsSync(new URL(p.replace(/^\//, ''), config.outDir)),
readFile: (filePath, encoding) =>
fs.promises.readFile(new URL(filePath.replace(/^\//, ''), config.outDir), encoding ?? 'utf8'),
readdir: (fp) => fs.promises.readdir(new URL(fp.replace(/^\//, ''), config.outDir)),