49 lines
1.8 KiB
TypeScript
49 lines
1.8 KiB
TypeScript
import { InvalidAstroDataError } from '@astrojs/markdown-remark';
|
|
import { safelyGetAstroData } from '@astrojs/markdown-remark/dist/internal.js';
|
|
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)
|
|
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)};`),
|
|
];
|
|
if (frontmatter.layout) {
|
|
// NOTE(bholmesdev) 08-22-2022
|
|
// Using an async layout import (i.e. `const Layout = (await import...)`)
|
|
// Preserves the dev server import cache when globbing a large set of MDX files
|
|
// Full explanation: 'https://github.com/withastro/astro/pull/4428'
|
|
exportNodes.unshift(
|
|
jsToTreeNode(
|
|
/** @see 'vite-plugin-markdown' for layout props reference */
|
|
`import { jsx as layoutJsx } from 'astro/jsx-runtime';
|
|
|
|
export default async function ({ children }) {
|
|
const Layout = (await import(${JSON.stringify(frontmatter.layout)})).default;
|
|
const { layout, ...content } = frontmatter;
|
|
content.file = file;
|
|
content.url = url;
|
|
return layoutJsx(Layout, {
|
|
file,
|
|
url,
|
|
content,
|
|
frontmatter: content,
|
|
headings: getHeadings(),
|
|
'server:root': true,
|
|
children,
|
|
});
|
|
};`
|
|
)
|
|
);
|
|
}
|
|
tree.children = exportNodes.concat(tree.children);
|
|
};
|
|
}
|