summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Bjorn Lu <bjornlu.dev@gmail.com> 2024-09-02 21:43:34 +0800
committerGravatar GitHub <noreply@github.com> 2024-09-02 21:43:34 +0800
commit3ab3b4efbcdd2aabea5f949deedf51a5acefae59 (patch)
treeb2414df525321c3732b380d27d39316c7d937db9
parent2bdde80cd3107d875e2d77e6e9621001e0e8b38a (diff)
downloadastro-3ab3b4efbcdd2aabea5f949deedf51a5acefae59.tar.gz
astro-3ab3b4efbcdd2aabea5f949deedf51a5acefae59.tar.zst
astro-3ab3b4efbcdd2aabea5f949deedf51a5acefae59.zip
Clean up Astro metadata in vfile.data (#11861)
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
-rw-r--r--.changeset/clean-donuts-walk.md13
-rw-r--r--.changeset/selfish-cats-crash.md5
-rw-r--r--.changeset/twelve-comics-march.md5
-rw-r--r--packages/astro/src/vite-plugin-markdown/content-entry-type.ts5
-rw-r--r--packages/astro/src/vite-plugin-markdown/index.ts27
-rw-r--r--packages/integrations/mdx/src/plugins.ts2
-rw-r--r--packages/integrations/mdx/src/rehype-apply-frontmatter-export.ts8
-rw-r--r--packages/integrations/mdx/src/rehype-collect-headings.ts6
-rw-r--r--packages/integrations/mdx/src/rehype-images-to-component.ts10
-rw-r--r--packages/integrations/mdx/src/vite-plugin-mdx.ts13
-rw-r--r--packages/markdown/remark/package.json3
-rw-r--r--packages/markdown/remark/src/frontmatter-injection.ts34
-rw-r--r--packages/markdown/remark/src/frontmatter.ts9
-rw-r--r--packages/markdown/remark/src/index.ts33
-rw-r--r--packages/markdown/remark/src/internal.ts1
-rw-r--r--packages/markdown/remark/src/rehype-collect-headings.ts28
-rw-r--r--packages/markdown/remark/src/rehype-images.ts6
-rw-r--r--packages/markdown/remark/src/remark-collect-images.ts7
-rw-r--r--packages/markdown/remark/src/types.ts24
-rw-r--r--packages/markdown/remark/test/remark-collect-images.test.js4
20 files changed, 115 insertions, 128 deletions
diff --git a/.changeset/clean-donuts-walk.md b/.changeset/clean-donuts-walk.md
new file mode 100644
index 000000000..1af111a4b
--- /dev/null
+++ b/.changeset/clean-donuts-walk.md
@@ -0,0 +1,13 @@
+---
+'@astrojs/markdown-remark': major
+'astro': major
+---
+
+Cleans up Astro-specfic metadata attached to `vfile.data` in Remark and Rehype plugins. Previously, the metadata was attached in different locations with inconsistent names. The metadata is now renamed as below:
+
+- `vfile.data.__astroHeadings` -> `vfile.data.astro.headings`
+- `vfile.data.imagePaths` -> `vfile.data.astro.imagePaths`
+
+The types of `imagePaths` has also been updated from `Set<string>` to `string[]`. The `vfile.data.astro.frontmatter` metadata is left unchanged.
+
+While we don't consider these APIs public, they can be accessed by Remark and Rehype plugins that want to re-use Astro's metadata. If you are using these APIs, make sure to access them in the new locations.
diff --git a/.changeset/selfish-cats-crash.md b/.changeset/selfish-cats-crash.md
new file mode 100644
index 000000000..a1ec38a47
--- /dev/null
+++ b/.changeset/selfish-cats-crash.md
@@ -0,0 +1,5 @@
+---
+'@astrojs/markdown-remark': major
+---
+
+Removes `InvalidAstroDataError`, `safelyGetAstroData`, and `setVfileFrontmatter` APIs in favour of `isFrontmatterValid`
diff --git a/.changeset/twelve-comics-march.md b/.changeset/twelve-comics-march.md
new file mode 100644
index 000000000..5b455ea09
--- /dev/null
+++ b/.changeset/twelve-comics-march.md
@@ -0,0 +1,5 @@
+---
+'@astrojs/mdx': patch
+---
+
+Updates `@astrojs/markdown-remark` and handle its breaking changes
diff --git a/packages/astro/src/vite-plugin-markdown/content-entry-type.ts b/packages/astro/src/vite-plugin-markdown/content-entry-type.ts
index 48a45294e..841789b22 100644
--- a/packages/astro/src/vite-plugin-markdown/content-entry-type.ts
+++ b/packages/astro/src/vite-plugin-markdown/content-entry-type.ts
@@ -32,10 +32,7 @@ export const markdownContentEntryType: ContentEntryType = {
});
return {
html: result.code,
- metadata: {
- ...result.metadata,
- imagePaths: Array.from(result.metadata.imagePaths),
- },
+ metadata: result.metadata,
};
};
},
diff --git a/packages/astro/src/vite-plugin-markdown/index.ts b/packages/astro/src/vite-plugin-markdown/index.ts
index a85eaff46..1a01f223a 100644
--- a/packages/astro/src/vite-plugin-markdown/index.ts
+++ b/packages/astro/src/vite-plugin-markdown/index.ts
@@ -1,9 +1,9 @@
import fs from 'node:fs';
import { fileURLToPath, pathToFileURL } from 'node:url';
import {
- InvalidAstroDataError,
type MarkdownProcessor,
createMarkdownProcessor,
+ isFrontmatterValid,
} from '@astrojs/markdown-remark';
import type { Plugin } from 'vite';
import { normalizePath } from 'vite';
@@ -69,26 +69,23 @@ export default function markdown({ settings, logger }: AstroPluginOptions): Plug
);
}
- const renderResult = await processor
- .render(raw.content, {
- // @ts-expect-error passing internal prop
- fileURL,
- frontmatter: raw.data,
- })
- .catch((err) => {
- // Improve error message for invalid astro data
- if (err instanceof InvalidAstroDataError) {
- throw new AstroError(AstroErrorData.InvalidFrontmatterInjectionError);
- }
- throw err;
- });
+ const renderResult = await processor.render(raw.content, {
+ // @ts-expect-error passing internal prop
+ fileURL,
+ frontmatter: raw.data,
+ });
+
+ // Improve error message for invalid astro frontmatter
+ if (!isFrontmatterValid(renderResult.metadata.frontmatter)) {
+ throw new AstroError(AstroErrorData.InvalidFrontmatterInjectionError);
+ }
let html = renderResult.code;
const { headings, imagePaths: rawImagePaths, frontmatter } = renderResult.metadata;
// Resolve all the extracted images from the content
const imagePaths: MarkdownImagePath[] = [];
- for (const imagePath of rawImagePaths.values()) {
+ for (const imagePath of rawImagePaths) {
imagePaths.push({
raw: imagePath,
safeName: shorthash(imagePath),
diff --git a/packages/integrations/mdx/src/plugins.ts b/packages/integrations/mdx/src/plugins.ts
index 082e8f6fd..77c76243c 100644
--- a/packages/integrations/mdx/src/plugins.ts
+++ b/packages/integrations/mdx/src/plugins.ts
@@ -83,7 +83,7 @@ function getRehypePlugins(mdxOptions: MdxOptions): PluggableList {
}
rehypePlugins.push(
- // Render info from `vfile.data.astro.data.frontmatter` as JS
+ // Render info from `vfile.data.astro.frontmatter` as JS
rehypeApplyFrontmatterExport,
// Analyze MDX nodes and attach to `vfile.data.__astroMetadata`
rehypeAnalyzeAstroMetadata,
diff --git a/packages/integrations/mdx/src/rehype-apply-frontmatter-export.ts b/packages/integrations/mdx/src/rehype-apply-frontmatter-export.ts
index 1b981a68e..cc1f4d141 100644
--- a/packages/integrations/mdx/src/rehype-apply-frontmatter-export.ts
+++ b/packages/integrations/mdx/src/rehype-apply-frontmatter-export.ts
@@ -1,18 +1,16 @@
-import { InvalidAstroDataError } from '@astrojs/markdown-remark';
-import { safelyGetAstroData } from '@astrojs/markdown-remark/dist/internal.js';
+import { isFrontmatterValid } from '@astrojs/markdown-remark';
import type { VFile } from 'vfile';
import { jsToTreeNode } from './utils.js';
export function rehypeApplyFrontmatterExport() {
return function (tree: any, vfile: VFile) {
- const astroData = safelyGetAstroData(vfile.data);
- if (astroData instanceof InvalidAstroDataError)
+ const frontmatter = vfile.data.astro?.frontmatter;
+ if (!frontmatter || !isFrontmatterValid(frontmatter))
throw new Error(
// Copied from Astro core `errors-data`
// TODO: find way to import error data from core
'[MDX] A remark or rehype plugin attempted to inject invalid frontmatter. Ensure "astro.frontmatter" is set to a valid JSON object that is not `null` or `undefined`.',
);
- const { frontmatter } = astroData;
const exportNodes = [
jsToTreeNode(`export const frontmatter = ${JSON.stringify(frontmatter)};`),
];
diff --git a/packages/integrations/mdx/src/rehype-collect-headings.ts b/packages/integrations/mdx/src/rehype-collect-headings.ts
index fafc59721..a51e8e9f0 100644
--- a/packages/integrations/mdx/src/rehype-collect-headings.ts
+++ b/packages/integrations/mdx/src/rehype-collect-headings.ts
@@ -1,9 +1,9 @@
-import type { MarkdownHeading, MarkdownVFile } from '@astrojs/markdown-remark';
+import type { VFile } from 'vfile';
import { jsToTreeNode } from './utils.js';
export function rehypeInjectHeadingsExport() {
- return function (tree: any, file: MarkdownVFile) {
- const headings: MarkdownHeading[] = file.data.__astroHeadings || [];
+ return function (tree: any, file: VFile) {
+ const headings = file.data.astro?.headings ?? [];
tree.children.unshift(
jsToTreeNode(`export function getHeadings() { return ${JSON.stringify(headings)} }`),
);
diff --git a/packages/integrations/mdx/src/rehype-images-to-component.ts b/packages/integrations/mdx/src/rehype-images-to-component.ts
index 95b500784..da2f25ee5 100644
--- a/packages/integrations/mdx/src/rehype-images-to-component.ts
+++ b/packages/integrations/mdx/src/rehype-images-to-component.ts
@@ -1,8 +1,8 @@
-import type { MarkdownVFile } from '@astrojs/markdown-remark';
import type { Properties, Root } from 'hast';
import type { MdxJsxAttribute, MdxjsEsm } from 'mdast-util-mdx';
import type { MdxJsxFlowElementHast } from 'mdast-util-mdx-jsx';
import { visit } from 'unist-util-visit';
+import type { VFile } from 'vfile';
import { jsToTreeNode } from './utils.js';
export const ASTRO_IMAGE_ELEMENT = 'astro-image';
@@ -72,18 +72,18 @@ function getImageComponentAttributes(props: Properties): MdxJsxAttribute[] {
}
export function rehypeImageToComponent() {
- return function (tree: Root, file: MarkdownVFile) {
- if (!file.data.imagePaths) return;
+ return function (tree: Root, file: VFile) {
+ if (!file.data.astro?.imagePaths) return;
const importsStatements: MdxjsEsm[] = [];
const importedImages = new Map<string, string>();
visit(tree, 'element', (node, index, parent) => {
- if (!file.data.imagePaths || node.tagName !== 'img' || !node.properties.src) return;
+ if (!file.data.astro?.imagePaths || node.tagName !== 'img' || !node.properties.src) return;
const src = decodeURI(String(node.properties.src));
- if (!file.data.imagePaths.has(src)) return;
+ if (!file.data.astro.imagePaths?.includes(src)) return;
let importName = importedImages.get(src);
diff --git a/packages/integrations/mdx/src/vite-plugin-mdx.ts b/packages/integrations/mdx/src/vite-plugin-mdx.ts
index 7b37535d8..e4d4387c3 100644
--- a/packages/integrations/mdx/src/vite-plugin-mdx.ts
+++ b/packages/integrations/mdx/src/vite-plugin-mdx.ts
@@ -1,4 +1,3 @@
-import { setVfileFrontmatter } from '@astrojs/markdown-remark';
import type { SSRError } from 'astro';
import { getAstroMetadata } from 'astro/jsx/rehype.js';
import { VFile } from 'vfile';
@@ -47,9 +46,15 @@ export function vitePluginMdx(mdxOptions: MdxOptions): Plugin {
const { data: frontmatter, content: pageContent, matter } = parseFrontmatter(code, id);
const frontmatterLines = matter ? matter.match(/\n/g)?.join('') + '\n\n' : '';
- const vfile = new VFile({ value: frontmatterLines + pageContent, path: id });
- // Ensure `data.astro` is available to all remark plugins
- setVfileFrontmatter(vfile, frontmatter);
+ const vfile = new VFile({
+ value: frontmatterLines + pageContent,
+ path: id,
+ data: {
+ astro: {
+ frontmatter,
+ },
+ },
+ });
// `processor` is initialized in `configResolved`, and removed in `buildEnd`. `transform`
// should be called in between those two lifecycle, so this error should never happen
diff --git a/packages/markdown/remark/package.json b/packages/markdown/remark/package.json
index aec4b0cfc..4807f6091 100644
--- a/packages/markdown/remark/package.json
+++ b/packages/markdown/remark/package.json
@@ -13,8 +13,7 @@
"homepage": "https://astro.build",
"main": "./dist/index.js",
"exports": {
- ".": "./dist/index.js",
- "./dist/internal.js": "./dist/internal.js"
+ ".": "./dist/index.js"
},
"imports": {
"#import-plugin": {
diff --git a/packages/markdown/remark/src/frontmatter-injection.ts b/packages/markdown/remark/src/frontmatter-injection.ts
deleted file mode 100644
index 91b98ebcb..000000000
--- a/packages/markdown/remark/src/frontmatter-injection.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import type { VFileData as Data, VFile } from 'vfile';
-import type { MarkdownAstroData } from './types.js';
-
-function isValidAstroData(obj: unknown): obj is MarkdownAstroData {
- if (typeof obj === 'object' && obj !== null && obj.hasOwnProperty('frontmatter')) {
- const { frontmatter } = obj as any;
- try {
- // ensure frontmatter is JSON-serializable
- JSON.stringify(frontmatter);
- } catch {
- return false;
- }
- return typeof frontmatter === 'object' && frontmatter !== null;
- }
- return false;
-}
-
-export class InvalidAstroDataError extends TypeError {}
-
-export function safelyGetAstroData(vfileData: Data): MarkdownAstroData | InvalidAstroDataError {
- const { astro } = vfileData;
-
- if (!astro || !isValidAstroData(astro)) {
- return new InvalidAstroDataError();
- }
-
- return astro;
-}
-
-export function setVfileFrontmatter(vfile: VFile, frontmatter: Record<string, any>) {
- vfile.data ??= {};
- vfile.data.astro ??= {};
- (vfile.data.astro as any).frontmatter = frontmatter;
-}
diff --git a/packages/markdown/remark/src/frontmatter.ts b/packages/markdown/remark/src/frontmatter.ts
new file mode 100644
index 000000000..d8828a6fe
--- /dev/null
+++ b/packages/markdown/remark/src/frontmatter.ts
@@ -0,0 +1,9 @@
+export function isFrontmatterValid(frontmatter: Record<string, any>) {
+ try {
+ // ensure frontmatter is JSON-serializable
+ JSON.stringify(frontmatter);
+ } catch {
+ return false;
+ }
+ return typeof frontmatter === 'object' && frontmatter !== null;
+}
diff --git a/packages/markdown/remark/src/index.ts b/packages/markdown/remark/src/index.ts
index 0ed2aaca1..ad52dc16f 100644
--- a/packages/markdown/remark/src/index.ts
+++ b/packages/markdown/remark/src/index.ts
@@ -1,10 +1,5 @@
-import type { AstroMarkdownOptions, MarkdownProcessor, MarkdownVFile } from './types.js';
+import type { AstroMarkdownOptions, MarkdownProcessor } from './types.js';
-import {
- InvalidAstroDataError,
- safelyGetAstroData,
- setVfileFrontmatter,
-} from './frontmatter-injection.js';
import { loadPlugins } from './load-plugins.js';
import { rehypeHeadingIds } from './rehype-collect-headings.js';
import { rehypePrism } from './rehype-prism.js';
@@ -21,11 +16,11 @@ import { unified } from 'unified';
import { VFile } from 'vfile';
import { rehypeImages } from './rehype-images.js';
-export { InvalidAstroDataError, setVfileFrontmatter } from './frontmatter-injection.js';
export { rehypeHeadingIds } from './rehype-collect-headings.js';
export { remarkCollectImages } from './remark-collect-images.js';
export { rehypePrism } from './rehype-prism.js';
export { rehypeShiki } from './rehype-shiki.js';
+export { isFrontmatterValid } from './frontmatter.js';
export {
createShikiHighlighter,
type ShikiHighlighter,
@@ -128,10 +123,17 @@ export async function createMarkdownProcessor(
return {
async render(content, renderOpts) {
- const vfile = new VFile({ value: content, path: renderOpts?.fileURL });
- setVfileFrontmatter(vfile, renderOpts?.frontmatter ?? {});
+ const vfile = new VFile({
+ value: content,
+ path: renderOpts?.fileURL,
+ data: {
+ astro: {
+ frontmatter: renderOpts?.frontmatter ?? {},
+ },
+ },
+ });
- const result: MarkdownVFile = await parser.process(vfile).catch((err) => {
+ const result = await parser.process(vfile).catch((err) => {
// Ensure that the error message contains the input filename
// to make it easier for the user to fix the issue
err = prefixError(err, `Failed to parse Markdown file "${vfile.path}"`);
@@ -140,17 +142,12 @@ export async function createMarkdownProcessor(
throw err;
});
- const astroData = safelyGetAstroData(result.data);
- if (astroData instanceof InvalidAstroDataError) {
- throw astroData;
- }
-
return {
code: String(result.value),
metadata: {
- headings: result.data.__astroHeadings ?? [],
- imagePaths: result.data.imagePaths ?? new Set(),
- frontmatter: astroData.frontmatter ?? {},
+ headings: result.data.astro?.headings ?? [],
+ imagePaths: result.data.astro?.imagePaths ?? [],
+ frontmatter: result.data.astro?.frontmatter ?? {},
},
};
},
diff --git a/packages/markdown/remark/src/internal.ts b/packages/markdown/remark/src/internal.ts
deleted file mode 100644
index 6201ef62f..000000000
--- a/packages/markdown/remark/src/internal.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { InvalidAstroDataError, safelyGetAstroData } from './frontmatter-injection.js';
diff --git a/packages/markdown/remark/src/rehype-collect-headings.ts b/packages/markdown/remark/src/rehype-collect-headings.ts
index 05afae1ba..ab2113f49 100644
--- a/packages/markdown/remark/src/rehype-collect-headings.ts
+++ b/packages/markdown/remark/src/rehype-collect-headings.ts
@@ -3,19 +3,18 @@ import Slugger from 'github-slugger';
import type { MdxTextExpression } from 'mdast-util-mdx-expression';
import type { Node } from 'unist';
import { visit } from 'unist-util-visit';
-
-import { InvalidAstroDataError, safelyGetAstroData } from './frontmatter-injection.js';
-import type { MarkdownAstroData, MarkdownHeading, MarkdownVFile, RehypePlugin } from './types.js';
+import type { VFile } from 'vfile';
+import type { MarkdownHeading, RehypePlugin } from './types.js';
const rawNodeTypes = new Set(['text', 'raw', 'mdxTextExpression']);
const codeTagNames = new Set(['code', 'pre']);
export function rehypeHeadingIds(): ReturnType<RehypePlugin> {
- return function (tree, file: MarkdownVFile) {
+ return function (tree, file) {
const headings: MarkdownHeading[] = [];
+ const frontmatter = file.data.astro?.frontmatter;
const slugger = new Slugger();
const isMDX = isMDXFile(file);
- const astroData = safelyGetAstroData(file.data);
visit(tree, (node) => {
if (node.type !== 'element') return;
const { tagName } = node;
@@ -37,10 +36,13 @@ export function rehypeHeadingIds(): ReturnType<RehypePlugin> {
if (rawNodeTypes.has(child.type)) {
if (isMDX || codeTagNames.has(parent.tagName)) {
let value = child.value;
- if (isMdxTextExpression(child) && !(astroData instanceof InvalidAstroDataError)) {
+ if (isMdxTextExpression(child) && frontmatter) {
const frontmatterPath = getMdxFrontmatterVariablePath(child);
if (Array.isArray(frontmatterPath) && frontmatterPath.length > 0) {
- const frontmatterValue = getMdxFrontmatterVariableValue(astroData, frontmatterPath);
+ const frontmatterValue = getMdxFrontmatterVariableValue(
+ frontmatter,
+ frontmatterPath,
+ );
if (typeof frontmatterValue === 'string') {
value = frontmatterValue;
}
@@ -65,11 +67,12 @@ export function rehypeHeadingIds(): ReturnType<RehypePlugin> {
headings.push({ depth, slug: node.properties.id, text });
});
- file.data.__astroHeadings = headings;
+ file.data.astro ??= {};
+ file.data.astro.headings = headings;
};
}
-function isMDXFile(file: MarkdownVFile) {
+function isMDXFile(file: VFile) {
return Boolean(file.history[0]?.endsWith('.mdx'));
}
@@ -109,8 +112,8 @@ function getMdxFrontmatterVariablePath(node: MdxTextExpression): string[] | Erro
return expressionPath.reverse();
}
-function getMdxFrontmatterVariableValue(astroData: MarkdownAstroData, path: string[]) {
- let value: MdxFrontmatterVariableValue = astroData.frontmatter;
+function getMdxFrontmatterVariableValue(frontmatter: Record<string, any>, path: string[]) {
+ let value = frontmatter;
for (const key of path) {
if (!value[key]) return undefined;
@@ -124,6 +127,3 @@ function getMdxFrontmatterVariableValue(astroData: MarkdownAstroData, path: stri
function isMdxTextExpression(node: Node): node is MdxTextExpression {
return node.type === 'mdxTextExpression';
}
-
-type MdxFrontmatterVariableValue =
- MarkdownAstroData['frontmatter'][keyof MarkdownAstroData['frontmatter']];
diff --git a/packages/markdown/remark/src/rehype-images.ts b/packages/markdown/remark/src/rehype-images.ts
index 01e5aa6d6..11d33df9c 100644
--- a/packages/markdown/remark/src/rehype-images.ts
+++ b/packages/markdown/remark/src/rehype-images.ts
@@ -1,9 +1,9 @@
import { visit } from 'unist-util-visit';
-import type { MarkdownVFile } from './types.js';
+import type { VFile } from 'vfile';
export function rehypeImages() {
return () =>
- function (tree: any, file: MarkdownVFile) {
+ function (tree: any, file: VFile) {
const imageOccurrenceMap = new Map();
visit(tree, (node) => {
@@ -13,7 +13,7 @@ export function rehypeImages() {
if (node.properties?.src) {
node.properties.src = decodeURI(node.properties.src);
- if (file.data.imagePaths?.has(node.properties.src)) {
+ if (file.data.astro?.imagePaths?.includes(node.properties.src)) {
const { ...props } = node.properties;
// Initialize or increment occurrence count for this image
diff --git a/packages/markdown/remark/src/remark-collect-images.ts b/packages/markdown/remark/src/remark-collect-images.ts
index 22774d5f1..f09f1c580 100644
--- a/packages/markdown/remark/src/remark-collect-images.ts
+++ b/packages/markdown/remark/src/remark-collect-images.ts
@@ -1,10 +1,10 @@
import type { Image, ImageReference } from 'mdast';
import { definitions } from 'mdast-util-definitions';
import { visit } from 'unist-util-visit';
-import type { MarkdownVFile } from './types.js';
+import type { VFile } from 'vfile';
export function remarkCollectImages() {
- return function (tree: any, vfile: MarkdownVFile) {
+ return function (tree: any, vfile: VFile) {
if (typeof vfile?.path !== 'string') return;
const definition = definitions(tree);
@@ -22,7 +22,8 @@ export function remarkCollectImages() {
}
});
- vfile.data.imagePaths = imagePaths;
+ vfile.data.astro ??= {};
+ vfile.data.astro.imagePaths = Array.from(imagePaths);
};
}
diff --git a/packages/markdown/remark/src/types.ts b/packages/markdown/remark/src/types.ts
index 4a1263e50..6134bdf8a 100644
--- a/packages/markdown/remark/src/types.ts
+++ b/packages/markdown/remark/src/types.ts
@@ -3,14 +3,19 @@ import type * as mdast from 'mdast';
import type { Options as RemarkRehypeOptions } from 'remark-rehype';
import type { BuiltinTheme } from 'shiki';
import type * as unified from 'unified';
-import type { DataMap, VFile } from 'vfile';
import type { CreateShikiHighlighterOptions, ShikiHighlighterHighlightOptions } from './shiki.js';
export type { Node } from 'unist';
-export type MarkdownAstroData = {
- frontmatter: Record<string, any>;
-};
+declare module 'vfile' {
+ interface DataMap {
+ astro: {
+ headings?: MarkdownHeading[];
+ imagePaths?: string[];
+ frontmatter?: Record<string, any>;
+ };
+ }
+}
export type RemarkPlugin<PluginParameters extends any[] = any[]> = unified.Plugin<
PluginParameters,
@@ -62,7 +67,7 @@ export interface MarkdownProcessorRenderResult {
code: string;
metadata: {
headings: MarkdownHeading[];
- imagePaths: Set<string>;
+ imagePaths: string[];
frontmatter: Record<string, any>;
};
}
@@ -72,12 +77,3 @@ export interface MarkdownHeading {
slug: string;
text: string;
}
-
-// TODO: Remove `MarkdownVFile` and move all additional properties to `DataMap` instead
-export interface MarkdownVFile extends VFile {
- data: Record<string, unknown> &
- Partial<DataMap> & {
- __astroHeadings?: MarkdownHeading[];
- imagePaths?: Set<string>;
- };
-}
diff --git a/packages/markdown/remark/test/remark-collect-images.test.js b/packages/markdown/remark/test/remark-collect-images.test.js
index 025d909aa..669bee595 100644
--- a/packages/markdown/remark/test/remark-collect-images.test.js
+++ b/packages/markdown/remark/test/remark-collect-images.test.js
@@ -23,7 +23,7 @@ describe('collect images', async () => {
'<p>Hello <img __ASTRO_IMAGE_="{&#x22;src&#x22;:&#x22;./img.png&#x22;,&#x22;alt&#x22;:&#x22;inline image url&#x22;,&#x22;index&#x22;:0}"></p>',
);
- assert.deepEqual(Array.from(imagePaths), ['./img.png']);
+ assert.deepEqual(imagePaths, ['./img.png']);
});
it('should add image paths from definition', async () => {
@@ -37,6 +37,6 @@ describe('collect images', async () => {
'<p>Hello <img __ASTRO_IMAGE_="{&#x22;src&#x22;:&#x22;./img.webp&#x22;,&#x22;alt&#x22;:&#x22;image ref&#x22;,&#x22;index&#x22;:0}"></p>',
);
- assert.deepEqual(Array.from(metadata.imagePaths), ['./img.webp']);
+ assert.deepEqual(metadata.imagePaths, ['./img.webp']);
});
});