From 96c4b925333fede1a53d19657d15e0052da90780 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Thu, 2 Jan 2025 09:49:20 +0000 Subject: [PATCH] fix: make `reference()` a sync transform (#12781) --- .changeset/fluffy-ants-reflect.md | 5 +++++ packages/astro/src/content/runtime.ts | 17 ++++++++++++++--- .../content-layer/src/content.config.ts | 2 +- 3 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 .changeset/fluffy-ants-reflect.md diff --git a/.changeset/fluffy-ants-reflect.md b/.changeset/fluffy-ants-reflect.md new file mode 100644 index 000000000000..924c7991049c --- /dev/null +++ b/.changeset/fluffy-ants-reflect.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes a regression that caused `default()` to not work with `reference()` diff --git a/packages/astro/src/content/runtime.ts b/packages/astro/src/content/runtime.ts index cf6537609ef1..ea1527106c52 100644 --- a/packages/astro/src/content/runtime.ts +++ b/packages/astro/src/content/runtime.ts @@ -18,7 +18,7 @@ import { unescapeHTML, } from '../runtime/server/index.js'; import { CONTENT_LAYER_TYPE, IMAGE_IMPORT_PREFIX } from './consts.js'; -import { type DataEntry, globalDataStore } from './data-store.js'; +import { type DataEntry, type ImmutableDataStore, globalDataStore } from './data-store.js'; import type { ContentLookupMap } from './utils.js'; type LazyImport = () => Promise; @@ -604,6 +604,10 @@ async function render({ } export function createReference({ lookupMap }: { lookupMap: ContentLookupMap }) { + // We're handling it like this to avoid needing an async schema. Not ideal, but should + // be safe because the store will already have been loaded by the time this is called. + let store: ImmutableDataStore | null = null; + globalDataStore.get().then((s) => (store = s)); return function reference(collection: string) { return z .union([ @@ -618,15 +622,22 @@ export function createReference({ lookupMap }: { lookupMap: ContentLookupMap }) }), ]) .transform( - async ( + ( lookup: | string | { id: string; collection: string } | { slug: string; collection: string }, ctx, ) => { + if (!store) { + ctx.addIssue({ + code: ZodIssueCode.custom, + message: `**${ctx.path.join('.')}:** Reference to ${collection} could not be resolved: store not available.\nThis is an Astro bug, so please file an issue at https://github.com/withastro/astro/issues.`, + }); + return; + } + const flattenedErrorPath = ctx.path.join('.'); - const store = await globalDataStore.get(); const collectionIsInStore = store.hasCollection(collection); if (typeof lookup === 'object') { diff --git a/packages/astro/test/fixtures/content-layer/src/content.config.ts b/packages/astro/test/fixtures/content-layer/src/content.config.ts index b0e97225659f..484d14d528cf 100644 --- a/packages/astro/test/fixtures/content-layer/src/content.config.ts +++ b/packages/astro/test/fixtures/content-layer/src/content.config.ts @@ -152,7 +152,7 @@ const spacecraft = defineCollection({ publishedDate: z.coerce.date(), tags: z.array(z.string()), heroImage: image().optional(), - cat: reference('cats').optional(), + cat: reference('cats').default('siamese'), something: z .string() .optional()