From 15b84ccb9859b070e30030015fca0de090a7b079 Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Fri, 10 Nov 2023 13:49:27 +0000 Subject: [PATCH] fix: regression when calculating params and pattern (#9051) * fix: regression when calculating params and pattern * changeset --- .changeset/grumpy-cobras-attend.md | 5 +++ packages/astro/src/core/render/route-cache.ts | 39 +++++++++---------- .../astro/src/core/routing/manifest/create.ts | 17 ++++---- .../test/fixtures/static/astro.config.mjs | 6 +-- .../static/src/pages/[lang]/manifest.ts | 15 +++++++ .../sitemap/test/staticPaths.test.js | 6 +++ 6 files changed, 58 insertions(+), 30 deletions(-) create mode 100644 .changeset/grumpy-cobras-attend.md create mode 100644 packages/integrations/sitemap/test/fixtures/static/src/pages/[lang]/manifest.ts diff --git a/.changeset/grumpy-cobras-attend.md b/.changeset/grumpy-cobras-attend.md new file mode 100644 index 0000000000..8b5e6afef3 --- /dev/null +++ b/.changeset/grumpy-cobras-attend.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fix a regression where endpoints were incorrectly processed during SSG build when `trailingSlash: "always"` diff --git a/packages/astro/src/core/render/route-cache.ts b/packages/astro/src/core/render/route-cache.ts index 5b22518dee..c318b8c443 100644 --- a/packages/astro/src/core/render/route-cache.ts +++ b/packages/astro/src/core/render/route-cache.ts @@ -31,11 +31,14 @@ export async function callGetStaticPaths({ ssr, }: CallGetStaticPathsOptions): Promise { const cached = routeCache.get(route); - if (cached?.staticPaths) return cached.staticPaths; - - if (mod) { - validateDynamicRouteModule(mod, { ssr, route }); + if (!mod) { + throw new Error('This is an error caused by Astro and not your code. Please file an issue.'); } + if (cached?.staticPaths) { + return cached.staticPaths; + } + + validateDynamicRouteModule(mod, { ssr, route }); // No static paths in SSR mode. Return an empty RouteCacheEntry. if (ssr && !route.prerender) { @@ -47,24 +50,20 @@ export async function callGetStaticPaths({ let staticPaths: GetStaticPathsResult = []; // Add a check here to make TypeScript happy. // This is already checked in validateDynamicRouteModule(). - if (mod) { - if (!mod.getStaticPaths) { - throw new Error('Unexpected Error.'); - } - - if (mod) { - // Calculate your static paths. - staticPaths = await mod.getStaticPaths({ - // Q: Why the cast? - // A: So users downstream can have nicer typings, we have to make some sacrifice in our internal typings, which necessitate a cast here - paginate: generatePaginateFunction(route) as PaginateFunction, - rss() { - throw new AstroError(AstroErrorData.GetStaticPathsRemovedRSSHelper); - }, - }); - } + if (!mod.getStaticPaths) { + throw new Error('Unexpected Error.'); } + // Calculate your static paths. + staticPaths = await mod.getStaticPaths({ + // Q: Why the cast? + // A: So users downstream can have nicer typings, we have to make some sacrifice in our internal typings, which necessitate a cast here + paginate: generatePaginateFunction(route) as PaginateFunction, + rss() { + throw new AstroError(AstroErrorData.GetStaticPathsRemovedRSSHelper); + }, + }); + validateGetStaticPathsResult(staticPaths, logger, route); const keyedStaticPaths = staticPaths as GetStaticPathsResultKeyed; diff --git a/packages/astro/src/core/routing/manifest/create.ts b/packages/astro/src/core/routing/manifest/create.ts index f5b6e0ccdd..6a57972e07 100644 --- a/packages/astro/src/core/routing/manifest/create.ts +++ b/packages/astro/src/core/routing/manifest/create.ts @@ -60,9 +60,12 @@ function getParts(part: string, file: string) { return result; } -function getPattern(segments: RoutePart[][], config: AstroConfig) { +function getPattern( + segments: RoutePart[][], + config: AstroConfig, + addTrailingSlash: AstroConfig['trailingSlash'] +) { const base = config.base; - const addTrailingSlash = config.trailingSlash; const pathname = segments .map((segment) => { if (segment.length === 1 && segment[0].spread) { @@ -325,7 +328,7 @@ export function createRouteManifest( components.push(item.file); const component = item.file; const trailingSlash = item.isPage ? settings.config.trailingSlash : 'never'; - const pattern = getPattern(segments, settings.config); + const pattern = getPattern(segments, settings.config, trailingSlash); const generate = getRouteGenerator(segments, trailingSlash); const pathname = segments.every((segment) => segment.length === 1 && !segment[0].dynamic) ? `/${segments.map((segment) => segment[0].content).join('/')}` @@ -386,7 +389,7 @@ export function createRouteManifest( const isPage = type === 'page'; const trailingSlash = isPage ? config.trailingSlash : 'never'; - const pattern = getPattern(segments, settings.config); + const pattern = getPattern(segments, settings.config, trailingSlash); const generate = getRouteGenerator(segments, trailingSlash); const pathname = segments.every((segment) => segment.length === 1 && !segment[0].dynamic) ? `/${segments.map((segment) => segment[0].content).join('/')}` @@ -433,7 +436,7 @@ export function createRouteManifest( return getParts(s, from); }); - const pattern = getPattern(segments, settings.config); + const pattern = getPattern(segments, settings.config, trailingSlash); const generate = getRouteGenerator(segments, trailingSlash); const pathname = segments.every((segment) => segment.length === 1 && !segment[0].dynamic) ? `/${segments.map((segment) => segment[0].content).join('/')}` @@ -551,7 +554,7 @@ export function createRouteManifest( pathname, route, segments, - pattern: getPattern(segments, config), + pattern: getPattern(segments, config, config.trailingSlash), type: 'fallback', }); } @@ -624,7 +627,7 @@ export function createRouteManifest( pathname, route, segments, - pattern: getPattern(segments, config), + pattern: getPattern(segments, config, config.trailingSlash), type: 'fallback', }); } diff --git a/packages/integrations/sitemap/test/fixtures/static/astro.config.mjs b/packages/integrations/sitemap/test/fixtures/static/astro.config.mjs index 1b53c53a8c..f0288b6dd7 100644 --- a/packages/integrations/sitemap/test/fixtures/static/astro.config.mjs +++ b/packages/integrations/sitemap/test/fixtures/static/astro.config.mjs @@ -4,7 +4,7 @@ import sitemap from '@astrojs/sitemap'; export default defineConfig({ integrations: [sitemap()], site: 'http://example.com', - redirects: { - '/redirect': '/' - }, + redirects: { + '/redirect': '/' + }, }) diff --git a/packages/integrations/sitemap/test/fixtures/static/src/pages/[lang]/manifest.ts b/packages/integrations/sitemap/test/fixtures/static/src/pages/[lang]/manifest.ts new file mode 100644 index 0000000000..907b94a217 --- /dev/null +++ b/packages/integrations/sitemap/test/fixtures/static/src/pages/[lang]/manifest.ts @@ -0,0 +1,15 @@ +export const GET: APIRoute = async ({ params }) => { + const { lang } = params; + + return new Response(`I'm a route in the "${lang}" language.`); +}; + +export async function getStaticPaths() { + return ['it', 'en'].map((language) => { + return { + params: { + lang: language, + }, + }; + }); +} diff --git a/packages/integrations/sitemap/test/staticPaths.test.js b/packages/integrations/sitemap/test/staticPaths.test.js index d5d95b2d3a..603af163d1 100644 --- a/packages/integrations/sitemap/test/staticPaths.test.js +++ b/packages/integrations/sitemap/test/staticPaths.test.js @@ -10,6 +10,7 @@ describe('getStaticPaths support', () => { before(async () => { fixture = await loadFixture({ root: './fixtures/static/', + trailingSlash: 'always', }); await fixture.build(); @@ -33,4 +34,9 @@ describe('getStaticPaths support', () => { it('includes numerical pages', () => { expect(urls).to.include('http://example.com/123/'); }); + + it('should render the endpoint', async () => { + const page = await fixture.readFile('./it/manifest'); + expect(page).to.contain('I\'m a route in the "it" language.'); + }); });