diff --git a/.changeset/chilled-ducks-grin.md b/.changeset/chilled-ducks-grin.md new file mode 100644 index 0000000000..b63b1f29c2 --- /dev/null +++ b/.changeset/chilled-ducks-grin.md @@ -0,0 +1,5 @@ +--- +'astro': major +--- + +Removed automatic flattening of `getStaticPaths` result. `.flatMap` and `.flat` should now be used to ensure that you're returning a flat array. diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index 6bcb011bb2..b6f45d0375 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -1530,10 +1530,7 @@ export type GetStaticPathsResultKeyed = GetStaticPathsResult & { */ export type GetStaticPaths = ( options: GetStaticPathsOptions -) => - | Promise - | GetStaticPathsResult - | GetStaticPathsResult[]; +) => Promise | GetStaticPathsResult; /** * Infers the shape of the `params` property returned by `getStaticPaths()`. diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index 7082952963..fbc88d0e48 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -300,7 +300,6 @@ async function getPathsForRoute( mod, route, routeCache: opts.routeCache, - isValidate: false, logging: opts.logging, ssr: isServerLikeOutput(opts.settings.config), }).catch((err) => { diff --git a/packages/astro/src/core/render/params-and-props.ts b/packages/astro/src/core/render/params-and-props.ts index a5e4fa222c..fc08c495e7 100644 --- a/packages/astro/src/core/render/params-and-props.ts +++ b/packages/astro/src/core/render/params-and-props.ts @@ -33,7 +33,6 @@ export async function getParamsAndProps(opts: GetParamsAndPropsOptions): Promise mod, route, routeCache, - isValidate: true, logging, ssr, }); diff --git a/packages/astro/src/core/render/route-cache.ts b/packages/astro/src/core/render/route-cache.ts index 7ad247ef8d..804f091838 100644 --- a/packages/astro/src/core/render/route-cache.ts +++ b/packages/astro/src/core/render/route-cache.ts @@ -18,7 +18,6 @@ interface CallGetStaticPathsOptions { mod: ComponentInstance; route: RouteData; routeCache: RouteCache; - isValidate: boolean; logging: LogOptions; ssr: boolean; } @@ -27,7 +26,6 @@ export async function callGetStaticPaths({ mod, route, routeCache, - isValidate, logging, ssr, }: CallGetStaticPathsOptions): Promise { @@ -58,14 +56,7 @@ export async function callGetStaticPaths({ }, }); - // Flatten the array before validating the content, otherwise users using `.map` will run into errors - if (Array.isArray(staticPaths)) { - staticPaths = staticPaths.flat(); - } - - if (isValidate) { - validateGetStaticPathsResult(staticPaths, logging, route); - } + validateGetStaticPathsResult(staticPaths, logging, route); const keyedStaticPaths = staticPaths as GetStaticPathsResultKeyed; keyedStaticPaths.keyed = new Map(); diff --git a/packages/astro/src/core/routing/validation.ts b/packages/astro/src/core/routing/validation.ts index 9a562c044a..b5c29b16e1 100644 --- a/packages/astro/src/core/routing/validation.ts +++ b/packages/astro/src/core/routing/validation.ts @@ -54,6 +54,15 @@ export function validateGetStaticPathsResult( } result.forEach((pathObject) => { + if ((typeof pathObject === 'object' && Array.isArray(pathObject)) || pathObject === null) { + throw new AstroError({ + ...AstroErrorData.InvalidGetStaticPathsEntry, + message: AstroErrorData.InvalidGetStaticPathsEntry.message( + Array.isArray(pathObject) ? 'array' : typeof pathObject + ), + }); + } + if ( pathObject.params === undefined || pathObject.params === null || @@ -67,16 +76,6 @@ export function validateGetStaticPathsResult( }); } - if (typeof pathObject.params !== 'object') { - throw new AstroError({ - ...AstroErrorData.InvalidGetStaticPathParam, - message: AstroErrorData.InvalidGetStaticPathParam.message(typeof pathObject.params), - location: { - file: route.component, - }, - }); - } - // TODO: Replace those with errors? They technically don't crash the build, but users might miss the warning. - erika, 2022-11-07 for (const [key, val] of Object.entries(pathObject.params)) { if (!(typeof val === 'undefined' || typeof val === 'string' || typeof val === 'number')) { diff --git a/packages/astro/test/astro-get-static-paths.test.js b/packages/astro/test/astro-get-static-paths.test.js index 784ff17186..66aa5b94d0 100644 --- a/packages/astro/test/astro-get-static-paths.test.js +++ b/packages/astro/test/astro-get-static-paths.test.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { loadFixture } from './test-utils.js'; import * as cheerio from 'cheerio'; +import { loadFixture } from './test-utils.js'; describe('getStaticPaths - build calls', () => { /** @type {import('./test-utils').Fixture} */ @@ -92,11 +92,6 @@ describe('getStaticPaths - dev calls', () => { }); describe('route params type validation', () => { - it('resolves 200 on nested array parameters', async () => { - const res = await fixture.fetch('/nested-arrays/slug1'); - expect(res.status).to.equal(200); - }); - it('resolves 200 on matching static path - string params', async () => { // route provided with { params: { year: "2022", slug: "post-2" }} const res = await fixture.fetch('/blog/2022/post-1'); diff --git a/packages/astro/test/fixtures/astro-get-static-paths/src/pages/nested-arrays/[slug].astro b/packages/astro/test/fixtures/astro-get-static-paths/src/pages/nested-arrays/[slug].astro deleted file mode 100644 index 9bd7b4f41a..0000000000 --- a/packages/astro/test/fixtures/astro-get-static-paths/src/pages/nested-arrays/[slug].astro +++ /dev/null @@ -1,8 +0,0 @@ ---- - export function getStaticPaths() { - return [ - [ { params: {slug: "slug1"} } ], - [ { params: {slug: "slug2"} } ], - ] - } ---- diff --git a/packages/astro/test/fixtures/astro-pagination/src/pages/posts/[slug]/[page].astro b/packages/astro/test/fixtures/astro-pagination/src/pages/posts/[slug]/[page].astro index c4cc397390..33df98cf59 100644 --- a/packages/astro/test/fixtures/astro-pagination/src/pages/posts/[slug]/[page].astro +++ b/packages/astro/test/fixtures/astro-pagination/src/pages/posts/[slug]/[page].astro @@ -1,7 +1,7 @@ --- export async function getStaticPaths({paginate}) { const allPosts = await Astro.glob('../../post/*.md'); - return ['red', 'blue'].map((filter) => { + return ['red', 'blue'].flatMap((filter) => { const filteredPosts = allPosts.filter((post) => post.frontmatter.tag === filter); return paginate(filteredPosts, { params: { slug: filter }, diff --git a/packages/astro/test/fixtures/ssr-prerender-get-static-paths/src/pages/nested-arrays/[slug].astro b/packages/astro/test/fixtures/ssr-prerender-get-static-paths/src/pages/nested-arrays/[slug].astro deleted file mode 100644 index 25d1bfff4e..0000000000 --- a/packages/astro/test/fixtures/ssr-prerender-get-static-paths/src/pages/nested-arrays/[slug].astro +++ /dev/null @@ -1,10 +0,0 @@ ---- - export function getStaticPaths() { - return [ - [ { params: {slug: "slug1"} } ], - [ { params: {slug: "slug2"} } ], - ] - } - - export const prerender = true; ---- diff --git a/packages/astro/test/ssr-prerender-get-static-paths.test.js b/packages/astro/test/ssr-prerender-get-static-paths.test.js index 391e7485dd..3fe2950cb8 100644 --- a/packages/astro/test/ssr-prerender-get-static-paths.test.js +++ b/packages/astro/test/ssr-prerender-get-static-paths.test.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import { loadFixture } from './test-utils.js'; import * as cheerio from 'cheerio'; import testAdapter from './test-adapter.js'; +import { loadFixture } from './test-utils.js'; describe('Prerender', () => { /** @type {import('./test-utils').Fixture} */ @@ -102,11 +102,6 @@ describe('Prerender', () => { }); describe('route params type validation', () => { - it('resolves 200 on nested array parameters', async () => { - const res = await fixture.fetch('/blog/nested-arrays/slug1'); - expect(res.status).to.equal(200); - }); - it('resolves 200 on matching static path - string params', async () => { // route provided with { params: { year: "2022", slug: "post-2" }} const res = await fixture.fetch('/blog/blog/2022/post-1'); @@ -234,11 +229,6 @@ describe('Prerender', () => { }); describe('route params type validation', () => { - it('resolves 200 on nested array parameters', async () => { - const res = await fixture.fetch('/blog/nested-arrays/slug1'); - expect(res.status).to.equal(200); - }); - it('resolves 200 on matching static path - string params', async () => { // route provided with { params: { year: "2022", slug: "post-2" }} const res = await fixture.fetch('/blog/blog/2022/post-1');