diff --git a/packages/astro/src/content/types-generator.ts b/packages/astro/src/content/types-generator.ts index b50c597fd..bd07f0476 100644 --- a/packages/astro/src/content/types-generator.ts +++ b/packages/astro/src/content/types-generator.ts @@ -30,7 +30,7 @@ type RawContentEvent = { name: ChokidarEvent; entry: string }; type ContentEvent = { name: ChokidarEvent; entry: URL }; type DataEntryMetadata = Record; -type ContentEntryMetadata = { slug: string }; +type ContentEntryMetadata = { slug: string, path: string }; type CollectionEntryMap = { [collection: string]: | { @@ -276,7 +276,7 @@ export async function createContentTypesGenerator({ if (!(entryKey in collectionEntryMap[collectionKey].entries)) { collectionEntryMap[collectionKey] = { type: 'content', - entries: { ...collectionInfo.entries, [entryKey]: { slug: addedSlug } }, + entries: { ...collectionInfo.entries, [entryKey]: { slug: addedSlug, path: event.entry.toString() } }, }; } return { shouldGenerateTypes: true }; @@ -453,7 +453,15 @@ async function writeContentFiles({ )}] }`; const slugType = JSON.stringify(entryMetadata.slug); - contentTypesStr += `${entryKey}: {\n id: ${entryKey};\n slug: ${slugType};\n body: string;\n collection: ${collectionKey};\n data: ${dataType}\n} & ${renderType};\n`; + contentTypesStr += [ + `${entryKey}: {`, + ` id: ${entryKey};`, + ` slug: ${slugType};`, + ` path: ${JSON.stringify(entryMetadata.path)};`, + ` body: string;`, + ` collection: ${collectionKey};`, + ` data: ${dataType}`, + `} & ${renderType};`].join("\n"); } contentTypesStr += `};\n`; break; diff --git a/packages/integrations/mdx/src/index.ts b/packages/integrations/mdx/src/index.ts index fd330625e..4af8bcceb 100644 --- a/packages/integrations/mdx/src/index.ts +++ b/packages/integrations/mdx/src/index.ts @@ -116,14 +116,14 @@ export default function mdx(partialMdxOptions: Partial = {}): AstroI if (!id.endsWith('.mdx')) return; // Read code from file manually to prevent Vite from parsing `import.meta.env` expressions - const { fileId } = getFileInfo(id, config); + const { fileId, fileUrl } = getFileInfo(id, config); const code = await fs.readFile(fileId, 'utf-8'); const { data: frontmatter, content: pageContent } = parseFrontmatter(code, id); const vfile = new VFile({ value: pageContent, path: id }); // Ensure `data.astro` is available to all remark plugins - setVfileFrontmatter(vfile, frontmatter); + setVfileFrontmatter(vfile, frontmatter, { fileURL: new URL(fileUrl) }); try { const compiled = await processor.process(vfile); diff --git a/packages/markdown/remark/src/frontmatter-injection.ts b/packages/markdown/remark/src/frontmatter-injection.ts index 4828873fd..9ebfc374a 100644 --- a/packages/markdown/remark/src/frontmatter-injection.ts +++ b/packages/markdown/remark/src/frontmatter-injection.ts @@ -1,5 +1,5 @@ import type { VFileData as Data, VFile } from 'vfile'; -import type { MarkdownAstroData } from './types.js'; +import type { MarkdownAstroData, MarkdownProcessorRenderOptions } from './types.js'; function isValidAstroData(obj: unknown): obj is MarkdownAstroData { if (typeof obj === 'object' && obj !== null && obj.hasOwnProperty('frontmatter')) { @@ -27,10 +27,15 @@ export function safelyGetAstroData(vfileData: Data): MarkdownAstroData | Invalid return astro; } -export function setVfileFrontmatter(vfile: VFile, frontmatter: Record) { +export function setVfileFrontmatter( + vfile: VFile, + frontmatter: Record, + renderOpts: MarkdownProcessorRenderOptions | undefined +) { vfile.data ??= {}; vfile.data.astro ??= {}; (vfile.data.astro as any).frontmatter = frontmatter; + (vfile.data.astro as any).fileURL = renderOpts?.fileURL; } /** diff --git a/packages/markdown/remark/src/index.ts b/packages/markdown/remark/src/index.ts index 89c9ca8bd..a2fb85b49 100644 --- a/packages/markdown/remark/src/index.ts +++ b/packages/markdown/remark/src/index.ts @@ -124,8 +124,9 @@ export async function createMarkdownProcessor( return { async render(content, renderOpts) { + console.log('url', renderOpts?.fileURL); const vfile = new VFile({ value: content, path: renderOpts?.fileURL }); - setVfileFrontmatter(vfile, renderOpts?.frontmatter ?? {}); + setVfileFrontmatter(vfile, renderOpts?.frontmatter ?? {}, renderOpts); const result: MarkdownVFile = await parser.process(vfile).catch((err) => { // Ensure that the error message contains the input filename