diff options
6 files changed, 53 insertions, 12 deletions
| diff --git a/.changeset/stupid-suns-beg.md b/.changeset/stupid-suns-beg.md new file mode 100644 index 000000000..ef398d290 --- /dev/null +++ b/.changeset/stupid-suns-beg.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Update frontmatter assets to be relative to the current file instead of `src/assets` diff --git a/packages/astro/src/content/runtime-assets.ts b/packages/astro/src/content/runtime-assets.ts index f6448b10c..6aa0c71fd 100644 --- a/packages/astro/src/content/runtime-assets.ts +++ b/packages/astro/src/content/runtime-assets.ts @@ -1,3 +1,4 @@ +import { pathToFileURL } from 'url';  import { z } from 'zod';  import { imageMetadata, type Metadata } from '../assets/utils/metadata.js'; @@ -7,9 +8,8 @@ export function createImage(options: { assetsDir: string; relAssetsDir: string }  			throw new Error('Enable `experimental.assets` in your Astro config to use image()');  		} -		return z.string().transform(async (imagePath) => { -			const fullPath = new URL(imagePath, options.assetsDir); -			return await getImageMetadata(fullPath); +		return z.string({ description: '__image' }).transform(async (imagePath) => { +			return await getImageMetadata(pathToFileURL(imagePath));  		});  	};  } diff --git a/packages/astro/src/content/utils.ts b/packages/astro/src/content/utils.ts index e162ff735..d2ba5207e 100644 --- a/packages/astro/src/content/utils.ts +++ b/packages/astro/src/content/utils.ts @@ -3,8 +3,8 @@ import matter from 'gray-matter';  import fsMod from 'node:fs';  import path from 'node:path';  import { fileURLToPath, pathToFileURL } from 'node:url'; -import type { EmitFile } from 'rollup'; -import { normalizePath, type ErrorPayload as ViteErrorPayload, type ViteDevServer } from 'vite'; +import type { EmitFile, PluginContext } from 'rollup'; +import { normalizePath, type ViteDevServer, type ErrorPayload as ViteErrorPayload } from 'vite';  import { z } from 'zod';  import type { AstroConfig, AstroSettings } from '../@types/astro.js';  import { emitESMImage } from '../assets/utils/emitAsset.js'; @@ -88,7 +88,8 @@ export function getEntrySlug({  export async function getEntryData(  	entry: EntryInfo & { unvalidatedData: Record<string, unknown>; _internal: EntryInternal }, -	collectionConfig: CollectionConfig +	collectionConfig: CollectionConfig, +	resolver: (idToResolve: string) => ReturnType<PluginContext['resolve']>  ) {  	// Remove reserved `slug` field before parsing data  	let { slug, ...data } = entry.unvalidatedData; @@ -117,6 +118,37 @@ export async function getEntryData(  				message: AstroErrorData.ContentSchemaContainsSlugError.message(entry.collection),  			});  		} + +		/** +		 * Resolve all the images referred to in the frontmatter from the file requesting them +		 */ +		async function preprocessAssetPaths(object: Record<string, any>) { +			if (typeof object !== 'object' || object === null) return; + +			for (let [schemaName, schema] of Object.entries<any>(object)) { +				if (schema._def.description === '__image') { +					object[schemaName] = z.preprocess( +						async (value: unknown) => { +							if (!value || typeof value !== 'string') return value; +							return (await resolver(value))?.id; +						}, +						schema, +						{ description: undefined } +					); +				} else if ('shape' in schema) { +					await preprocessAssetPaths(schema.shape); +				} else if ('unwrap' in schema) { +					const unwrapped = schema.unwrap().shape; + +					if (unwrapped) { +						await preprocessAssetPaths(unwrapped); +					} +				} +			} +		} + +		await preprocessAssetPaths(collectionConfig.schema.shape); +  		// Use `safeParseAsync` to allow async transforms  		const parsed = await collectionConfig.schema.safeParseAsync(entry.unvalidatedData, {  			errorMap, diff --git a/packages/astro/src/content/vite-plugin-content-imports.ts b/packages/astro/src/content/vite-plugin-content-imports.ts index cc1d38565..6790a9b95 100644 --- a/packages/astro/src/content/vite-plugin-content-imports.ts +++ b/packages/astro/src/content/vite-plugin-content-imports.ts @@ -10,6 +10,7 @@ import { AstroError } from '../core/errors/errors.js';  import { escapeViteEnvReferences, getFileInfo } from '../vite-plugin-utils/index.js';  import { CONTENT_FLAG } from './consts.js';  import { +	NoCollectionError,  	getContentEntryExts,  	getContentPaths,  	getEntryData, @@ -17,7 +18,6 @@ import {  	getEntrySlug,  	getEntryType,  	globalContentConfigObserver, -	NoCollectionError,  	patchAssets,  	type ContentConfig,  } from './utils.js'; @@ -232,7 +232,11 @@ export const _internal = {  		const collectionConfig = contentConfig?.collections[collection];  		let data = collectionConfig -			? await getEntryData({ id, collection, slug, _internal, unvalidatedData }, collectionConfig) +			? await getEntryData( +					{ id, collection, slug, _internal, unvalidatedData }, +					collectionConfig, +					(idToResolve: string) => pluginContext.resolve(idToResolve, fileId) +			  )  			: unvalidatedData;  		await patchAssets(data, pluginContext.meta.watchMode, pluginContext.emitFile, settings); diff --git a/packages/astro/test/fixtures/core-image-ssg/src/content/blog/one.md b/packages/astro/test/fixtures/core-image-ssg/src/content/blog/one.md index 88a210b75..59a5b77ba 100644 --- a/packages/astro/test/fixtures/core-image-ssg/src/content/blog/one.md +++ b/packages/astro/test/fixtures/core-image-ssg/src/content/blog/one.md @@ -1,8 +1,8 @@  ---  title: One -image: penguin2.jpg +image: ~/assets/penguin2.jpg  cover: -  image: penguin1.jpg +  image: ../../assets/penguin1.jpg  ---  # A post diff --git a/packages/astro/test/fixtures/core-image/src/content/blog/one.md b/packages/astro/test/fixtures/core-image/src/content/blog/one.md index 88a210b75..59a5b77ba 100644 --- a/packages/astro/test/fixtures/core-image/src/content/blog/one.md +++ b/packages/astro/test/fixtures/core-image/src/content/blog/one.md @@ -1,8 +1,8 @@  ---  title: One -image: penguin2.jpg +image: ~/assets/penguin2.jpg  cover: -  image: penguin1.jpg +  image: ../../assets/penguin1.jpg  ---  # A post | 
