From ab05a2979155d11b162bf7ddb405c9d1cb78612b Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Fri, 10 Jan 2025 14:38:14 +0000 Subject: [PATCH] fix: delete old entry when frontmatter slug changed --- .changeset/tiny-papayas-develop.md | 5 +++ packages/astro/src/content/loaders/glob.ts | 10 ++++-- packages/astro/test/content-layer.test.js | 31 +++++++++++++++++++ .../src/content/space/exomars.md | 10 ++++++ .../src/pages/collections.json.js | 5 ++- .../src/pages/spacecraft/index.astro | 17 ++++++++++ 6 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 .changeset/tiny-papayas-develop.md create mode 100644 packages/astro/test/fixtures/content-layer/src/content/space/exomars.md create mode 100644 packages/astro/test/fixtures/content-layer/src/pages/spacecraft/index.astro diff --git a/.changeset/tiny-papayas-develop.md b/.changeset/tiny-papayas-develop.md new file mode 100644 index 000000000000..49da5049d443 --- /dev/null +++ b/.changeset/tiny-papayas-develop.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Ensures old content collection entry is deleted if a markdown frontmatter slug is changed in dev diff --git a/packages/astro/src/content/loaders/glob.ts b/packages/astro/src/content/loaders/glob.ts index 6069ad8386c5..56474b00ee39 100644 --- a/packages/astro/src/content/loaders/glob.ts +++ b/packages/astro/src/content/loaders/glob.ts @@ -93,7 +93,7 @@ export function glob(globOptions: GlobOptions): Loader { const isLegacy = (globOptions as any)._legacy; // If global legacy collection handling flag is *not* enabled then this loader is used to emulate them instead const emulateLegacyCollections = !config.legacy.collections; - async function syncData(entry: string, base: URL, entryType?: ContentEntryType) { + async function syncData(entry: string, base: URL, entryType?: ContentEntryType, oldId?: string) { if (!entryType) { logger.warn(`No entry type found for ${entry}`); return; @@ -115,6 +115,11 @@ export function glob(globOptions: GlobOptions): Loader { }); const id = generateId({ entry, base, data }); + + if(oldId && oldId !== id) { + store.delete(oldId); + } + let legacyId: string | undefined; if (isLegacy) { @@ -320,7 +325,8 @@ export function glob(globOptions: GlobOptions): Loader { } const entryType = configForFile(changedPath); const baseUrl = pathToFileURL(basePath); - await syncData(entry, baseUrl, entryType); + const oldId = fileToIdMap.get(changedPath); + await syncData(entry, baseUrl, entryType, oldId); logger.info(`Reloaded data from ${green(entry)}`); } diff --git a/packages/astro/test/content-layer.test.js b/packages/astro/test/content-layer.test.js index 225025b3069e..10d7790ff79c 100644 --- a/packages/astro/test/content-layer.test.js +++ b/packages/astro/test/content-layer.test.js @@ -467,6 +467,37 @@ describe('Content Layer', () => { await fixture.resetAllFiles(); }); + it('removes old entry when slug is changed', async () => { + const rawJsonResponse = await fixture.fetch('/collections.json'); + const initialJson = devalue.parse(await rawJsonResponse.text()); + + assert.ok(initialJson.spacecraft.includes('exomars')); + assert.ok(!initialJson.spacecraft.includes('rosalind-franklin-rover')); + + await fixture.editFile('/src/content/space/exomars.md', (prev) => { + return prev.replace('# slug', 'slug'); + }); + + await fixture.onNextDataStoreChange(); + const updatedJsonResponse = await fixture.fetch('/collections.json'); + const updated = devalue.parse(await updatedJsonResponse.text()); + assert.ok(!updated.spacecraft.includes('exomars')); + assert.ok(updated.spacecraft.includes('rosalind-franklin-rover')); + + await fixture.editFile('/src/content/space/exomars.md', (prev) => { + return prev.replace('rosalind-franklin-rover', 'rosalind-franklin'); + }) + + await fixture.onNextDataStoreChange(); + const updatedJsonResponse2 = await fixture.fetch('/collections.json'); + const updated2 = devalue.parse(await updatedJsonResponse2.text()); + assert.ok(!updated2.spacecraft.includes('rosalind-franklin-rover')); + assert.ok(updated2.spacecraft.includes('rosalind-franklin')); + + await fixture.resetAllFiles(); + + }); + it('returns an error if we render an undefined entry', async () => { const res = await fixture.fetch('/missing'); const text = await res.text(); diff --git a/packages/astro/test/fixtures/content-layer/src/content/space/exomars.md b/packages/astro/test/fixtures/content-layer/src/content/space/exomars.md new file mode 100644 index 000000000000..ea0ac6023689 --- /dev/null +++ b/packages/astro/test/fixtures/content-layer/src/content/space/exomars.md @@ -0,0 +1,10 @@ +--- +title: Rosalind Franklin Rover +description: 'Learn about the Rosalind Franklin Rover.' +publishedDate: '2022-09-19' +tags: [space, 2020s] +# slug: rosalind-franklin-rover +--- +**Source:** [Wikipedia](https://en.wikipedia.org/wiki/Rosalind_Franklin_(rover)) + +The Rosalind Franklin rover is a planned robotic Mars rover, part of the ExoMars mission led by the European Space Agency and the Russian space agency Roscosmos. The mission is scheduled to launch in September 2022, and the rover is expected to land on Mars in June 2023. The rover is named after the British biophysicist Rosalind Franklin, who made key contributions to the discovery of the structure of DNA. diff --git a/packages/astro/test/fixtures/content-layer/src/pages/collections.json.js b/packages/astro/test/fixtures/content-layer/src/pages/collections.json.js index 968dfc24d3c6..3fa3543e6e0d 100644 --- a/packages/astro/test/fixtures/content-layer/src/pages/collections.json.js +++ b/packages/astro/test/fixtures/content-layer/src/pages/collections.json.js @@ -15,6 +15,8 @@ export async function GET() { const atlantis = await getEntry('spacecraft', 'atlantis'); const referencedEntry = await getEntry(entryWithReference.data.cat); + const spacecraft = await getCollection('spacecraft'); + const entryWithImagePath = await getEntry('spacecraft', 'lunar-module'); const increment = await getEntry('increment', 'value'); @@ -50,7 +52,8 @@ export async function GET() { yamlLoader, tomlLoader, nestedJsonLoader, - atlantis + atlantis, + spacecraft: spacecraft.map(({id}) => id).sort((a, b) => a.localeCompare(b)), }) ); } diff --git a/packages/astro/test/fixtures/content-layer/src/pages/spacecraft/index.astro b/packages/astro/test/fixtures/content-layer/src/pages/spacecraft/index.astro new file mode 100644 index 000000000000..38bbb08f7f66 --- /dev/null +++ b/packages/astro/test/fixtures/content-layer/src/pages/spacecraft/index.astro @@ -0,0 +1,17 @@ +--- +import { getCollection } from "astro:content"; +const collection = await getCollection("spacecraft"); +--- + + + Spacecraft + + +

Spacecraft

+ + +