mirror of
https://github.com/withastro/astro.git
synced 2025-03-17 23:11:29 -05:00
Clean up Astro metadata in vfile.data (#11861)
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
This commit is contained in:
parent
2bdde80cd3
commit
3ab3b4efbc
20 changed files with 115 additions and 128 deletions
13
.changeset/clean-donuts-walk.md
Normal file
13
.changeset/clean-donuts-walk.md
Normal file
|
@ -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.
|
5
.changeset/selfish-cats-crash.md
Normal file
5
.changeset/selfish-cats-crash.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@astrojs/markdown-remark': major
|
||||
---
|
||||
|
||||
Removes `InvalidAstroDataError`, `safelyGetAstroData`, and `setVfileFrontmatter` APIs in favour of `isFrontmatterValid`
|
5
.changeset/twelve-comics-march.md
Normal file
5
.changeset/twelve-comics-march.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@astrojs/mdx': patch
|
||||
---
|
||||
|
||||
Updates `@astrojs/markdown-remark` and handle its breaking changes
|
|
@ -32,10 +32,7 @@ export const markdownContentEntryType: ContentEntryType = {
|
|||
});
|
||||
return {
|
||||
html: result.code,
|
||||
metadata: {
|
||||
...result.metadata,
|
||||
imagePaths: Array.from(result.metadata.imagePaths),
|
||||
},
|
||||
metadata: result.metadata,
|
||||
};
|
||||
};
|
||||
},
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)};`),
|
||||
];
|
||||
|
|
|
@ -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)} }`),
|
||||
);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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;
|
||||
}
|
9
packages/markdown/remark/src/frontmatter.ts
Normal file
9
packages/markdown/remark/src/frontmatter.ts
Normal file
|
@ -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;
|
||||
}
|
|
@ -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 ?? {},
|
||||
},
|
||||
};
|
||||
},
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
export { InvalidAstroDataError, safelyGetAstroData } from './frontmatter-injection.js';
|
|
@ -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']];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ describe('collect images', async () => {
|
|||
'<p>Hello <img __ASTRO_IMAGE_="{"src":"./img.png","alt":"inline image url","index":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_="{"src":"./img.webp","alt":"image ref","index":0}"></p>',
|
||||
);
|
||||
|
||||
assert.deepEqual(Array.from(metadata.imagePaths), ['./img.webp']);
|
||||
assert.deepEqual(metadata.imagePaths, ['./img.webp']);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue