diff options
author | 2023-01-03 16:31:19 -0500 | |
---|---|---|
committer | 2023-01-03 16:31:19 -0500 | |
commit | e2019be6ffa46fa33d92cfd346f9ecbe51bb7144 (patch) | |
tree | 413c13945ae992c26111e78314a567f5c0136c67 /packages/markdown/remark/src | |
parent | 16c7d0bfd49d2b9bfae45385f506bcd642f9444a (diff) | |
download | astro-e2019be6ffa46fa33d92cfd346f9ecbe51bb7144.tar.gz astro-e2019be6ffa46fa33d92cfd346f9ecbe51bb7144.tar.zst astro-e2019be6ffa46fa33d92cfd346f9ecbe51bb7144.zip |
Change frontmatter injection ordering (#5687)
* feat: make user frontmatter accessible in md
* test: new frontmatter injection
* refactor: move injection utils to remark pkg
* fix: add dist/internal to remark exports
* feat: update frontmater injection in mdx
* tests: new mdx injection
* chore: changeset
* chore: simplify frontmatter destructuring
* fix: remove old _internal references
* refactor: injectedFrontmatter -> remarkPluginFrontmatter
* docs: add content collections change
* chore: changeset heading levels
Diffstat (limited to 'packages/markdown/remark/src')
-rw-r--r-- | packages/markdown/remark/src/frontmatter-injection.ts | 41 | ||||
-rw-r--r-- | packages/markdown/remark/src/index.ts | 5 | ||||
-rw-r--r-- | packages/markdown/remark/src/internal.ts | 5 | ||||
-rw-r--r-- | packages/markdown/remark/src/remark-initialize-astro-data.ts | 9 | ||||
-rw-r--r-- | packages/markdown/remark/src/types.ts | 6 |
5 files changed, 55 insertions, 11 deletions
diff --git a/packages/markdown/remark/src/frontmatter-injection.ts b/packages/markdown/remark/src/frontmatter-injection.ts new file mode 100644 index 000000000..921d01297 --- /dev/null +++ b/packages/markdown/remark/src/frontmatter-injection.ts @@ -0,0 +1,41 @@ +import type { 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 toRemarkInitializeAstroData({ + userFrontmatter, +}: { + userFrontmatter: Record<string, any>; +}) { + return () => + function (tree: any, vfile: VFile) { + if (!vfile.data.astro) { + vfile.data.astro = { frontmatter: userFrontmatter }; + } + }; +} diff --git a/packages/markdown/remark/src/index.ts b/packages/markdown/remark/src/index.ts index 66889108e..480cc9e38 100644 --- a/packages/markdown/remark/src/index.ts +++ b/packages/markdown/remark/src/index.ts @@ -8,7 +8,7 @@ import rehypeIslands from './rehype-islands.js'; import rehypeJsx from './rehype-jsx.js'; import toRemarkContentRelImageError from './remark-content-rel-image-error.js'; import remarkEscape from './remark-escape.js'; -import { remarkInitializeAstroData } from './remark-initialize-astro-data.js'; +import { toRemarkInitializeAstroData } from './frontmatter-injection.js'; import remarkMarkAndUnravel from './remark-mark-and-unravel.js'; import remarkMdxish from './remark-mdxish.js'; import remarkPrism from './remark-prism.js'; @@ -45,13 +45,14 @@ export async function renderMarkdown( isAstroFlavoredMd = false, isExperimentalContentCollections = false, contentDir, + frontmatter: userFrontmatter = {}, } = opts; const input = new VFile({ value: content, path: fileURL }); const scopedClassName = opts.$?.scopedClassName; let parser = unified() .use(markdown) - .use(remarkInitializeAstroData) + .use(toRemarkInitializeAstroData({ userFrontmatter })) .use(isAstroFlavoredMd ? [remarkMdxish, remarkMarkAndUnravel, remarkUnwrap, remarkEscape] : []); if (extendDefaultPlugins || (remarkPlugins.length === 0 && rehypePlugins.length === 0)) { diff --git a/packages/markdown/remark/src/internal.ts b/packages/markdown/remark/src/internal.ts new file mode 100644 index 000000000..0ab7e34bb --- /dev/null +++ b/packages/markdown/remark/src/internal.ts @@ -0,0 +1,5 @@ +export { + InvalidAstroDataError, + safelyGetAstroData, + toRemarkInitializeAstroData, +} from './frontmatter-injection.js'; diff --git a/packages/markdown/remark/src/remark-initialize-astro-data.ts b/packages/markdown/remark/src/remark-initialize-astro-data.ts deleted file mode 100644 index 37af8aeaf..000000000 --- a/packages/markdown/remark/src/remark-initialize-astro-data.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { VFile } from 'vfile'; - -export function remarkInitializeAstroData() { - return function (tree: any, vfile: VFile) { - if (!vfile.data.astro) { - vfile.data.astro = { frontmatter: {} }; - } - }; -} diff --git a/packages/markdown/remark/src/types.ts b/packages/markdown/remark/src/types.ts index 15465d950..f52fd4bf5 100644 --- a/packages/markdown/remark/src/types.ts +++ b/packages/markdown/remark/src/types.ts @@ -11,6 +11,10 @@ import type { VFile } from 'vfile'; export type { Node } from 'unist'; +export type MarkdownAstroData = { + frontmatter: Record<string, any>; +}; + export type RemarkPlugin<PluginParameters extends any[] = any[]> = unified.Plugin< PluginParameters, mdast.Root @@ -58,6 +62,8 @@ export interface MarkdownRenderingOptions extends AstroMarkdownOptions { isExperimentalContentCollections?: boolean; /** Used to prevent relative image imports from `src/content/` */ contentDir: URL; + /** Used for frontmatter injection plugins */ + frontmatter?: Record<string, any>; } export interface MarkdownHeading { |