diff --git a/.changeset/spicy-suns-marry.md b/.changeset/spicy-suns-marry.md new file mode 100644 index 00000000000..97c12331998 --- /dev/null +++ b/.changeset/spicy-suns-marry.md @@ -0,0 +1,5 @@ +--- +'@astrojs/starlight': patch +--- + +Fixes an issue with frontmatter schemas containing collection references used with the `` component and an Astro version greater than `4.14.0`. diff --git a/packages/starlight/utils/error-map.ts b/packages/starlight/utils/error-map.ts index 0b2d2c5c73c..667a91af365 100644 --- a/packages/starlight/utils/error-map.ts +++ b/packages/starlight/utils/error-map.ts @@ -25,11 +25,31 @@ export function parseWithFriendlyErrors( input: z.input, message: string ): z.output { - const parsedConfig = schema.safeParse(input, { errorMap }); - if (!parsedConfig.success) { - throw new AstroError(message, parsedConfig.error.issues.map((i) => i.message).join('\n')); + return processParsedData(schema.safeParse(input, { errorMap }), message); +} + +/** + * Asynchronously parse data with a Zod schema that contains asynchronous refinements or transforms + * and throw a nicely formatted error if it is invalid. + * + * @param schema The Zod schema to use to parse the input. + * @param input Input data that should match the schema. + * @param message Error message preamble to use if the input fails to parse. + * @returns Validated data parsed by Zod. + */ +export async function parseAsyncWithFriendlyErrors( + schema: T, + input: z.input, + message: string +): Promise> { + return processParsedData(await schema.safeParseAsync(input, { errorMap }), message); +} + +function processParsedData(parsedData: z.SafeParseReturnType, message: string) { + if (!parsedData.success) { + throw new AstroError(message, parsedData.error.issues.map((i) => i.message).join('\n')); } - return parsedConfig.data; + return parsedData.data; } const errorMap: z.ZodErrorMap = (baseError, ctx) => { diff --git a/packages/starlight/utils/starlight-page.ts b/packages/starlight/utils/starlight-page.ts index 2777431c923..b45d088ff8d 100644 --- a/packages/starlight/utils/starlight-page.ts +++ b/packages/starlight/utils/starlight-page.ts @@ -1,7 +1,7 @@ import { z } from 'astro/zod'; import { type ContentConfig, type SchemaContext } from 'astro:content'; import config from 'virtual:starlight/user-config'; -import { parseWithFriendlyErrors } from './error-map'; +import { parseWithFriendlyErrors, parseAsyncWithFriendlyErrors } from './error-map'; import { stripLeadingAndTrailingSlashes } from './path'; import { getSiteTitle, @@ -198,7 +198,9 @@ async function getStarlightPageFrontmatter(frontmatter: StarlightPageFrontmatter }), }); - return parseWithFriendlyErrors( + // Starting with Astro 4.14.0, a frontmatter schema that contains collection references will + // contain an async transform. + return parseAsyncWithFriendlyErrors( schema, frontmatter, 'Invalid frontmatter props passed to the `` component.'