diff options
Diffstat (limited to 'packages/integrations')
-rw-r--r-- | packages/integrations/markdoc/package.json | 1 | ||||
-rw-r--r-- | packages/integrations/markdoc/src/content-entry-type.ts | 43 | ||||
-rw-r--r-- | packages/integrations/markdoc/test/content-collections.test.js | 6 | ||||
-rw-r--r-- | packages/integrations/mdx/package.json | 1 | ||||
-rw-r--r-- | packages/integrations/mdx/src/index.ts | 12 | ||||
-rw-r--r-- | packages/integrations/mdx/src/utils.ts | 6 | ||||
-rw-r--r-- | packages/integrations/mdx/src/vite-plugin-mdx.ts | 7 |
7 files changed, 32 insertions, 44 deletions
diff --git a/packages/integrations/markdoc/package.json b/packages/integrations/markdoc/package.json index c92b5049d..35deff065 100644 --- a/packages/integrations/markdoc/package.json +++ b/packages/integrations/markdoc/package.json @@ -68,7 +68,6 @@ "@markdoc/markdoc": "^0.4.0", "esbuild": "^0.21.5", "github-slugger": "^2.0.0", - "gray-matter": "^4.0.3", "htmlparser2": "^9.1.0" }, "peerDependencies": { diff --git a/packages/integrations/markdoc/src/content-entry-type.ts b/packages/integrations/markdoc/src/content-entry-type.ts index 303251d66..67a8be531 100644 --- a/packages/integrations/markdoc/src/content-entry-type.ts +++ b/packages/integrations/markdoc/src/content-entry-type.ts @@ -1,11 +1,11 @@ import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; +import { parseFrontmatter } from '@astrojs/markdown-remark'; import type { Config as MarkdocConfig, Node } from '@markdoc/markdoc'; import Markdoc from '@markdoc/markdoc'; import type { AstroConfig, ContentEntryType } from 'astro'; import { emitESMImage } from 'astro/assets/utils'; -import matter from 'gray-matter'; import type { Rollup, ErrorPayload as ViteErrorPayload } from 'vite'; import type { ComponentConfig } from './config.js'; import { htmlTokenTransform } from './html/transform/html-token-transform.js'; @@ -26,12 +26,20 @@ export async function getContentEntryType({ }): Promise<ContentEntryType> { return { extensions: ['.mdoc'], - getEntryInfo, + getEntryInfo({ fileUrl, contents }) { + const parsed = safeParseFrontmatter(contents, fileURLToPath(fileUrl)); + return { + data: parsed.frontmatter, + body: parsed.content.trim(), + slug: parsed.frontmatter.slug, + rawData: parsed.rawFrontmatter, + }; + }, handlePropagation: true, async getRenderModule({ contents, fileUrl, viteId }) { - const entry = getEntryInfo({ contents, fileUrl }); + const parsed = safeParseFrontmatter(contents, fileURLToPath(fileUrl)); const tokenizer = getMarkdocTokenizer(options); - let tokens = tokenizer.tokenize(entry.body); + let tokens = tokenizer.tokenize(parsed.content); if (options?.allowHTML) { tokens = htmlTokenTransform(tokenizer, tokens); @@ -47,7 +55,6 @@ export async function getContentEntryType({ ast, /* Raised generics issue with Markdoc core https://github.com/markdoc/markdoc/discussions/400 */ markdocConfig: markdocConfig as MarkdocConfig, - entry, viteId, astroConfig, filePath, @@ -64,7 +71,6 @@ export async function getContentEntryType({ raiseValidationErrors({ ast: partialAst, markdocConfig: markdocConfig as MarkdocConfig, - entry, viteId, astroConfig, filePath: partialPath, @@ -224,14 +230,12 @@ async function resolvePartials({ function raiseValidationErrors({ ast, markdocConfig, - entry, viteId, astroConfig, filePath, }: { ast: Node; markdocConfig: MarkdocConfig; - entry: ReturnType<typeof getEntryInfo>; viteId: string; astroConfig: AstroConfig; filePath: string; @@ -250,8 +254,6 @@ function raiseValidationErrors({ }); if (validationErrors.length) { - // Heuristic: take number of newlines for `rawData` and add 2 for the `---` fences - const frontmatterBlockOffset = entry.rawData.split('\n').length + 2; const rootRelativePath = path.relative(fileURLToPath(astroConfig.root), filePath); throw new MarkdocError({ message: [ @@ -261,7 +263,7 @@ function raiseValidationErrors({ location: { // Error overlay does not support multi-line or ranges. // Just point to the first line. - line: frontmatterBlockOffset + validationErrors[0].lines[0], + line: validationErrors[0].lines[0], file: viteId, }, }); @@ -282,16 +284,6 @@ function getUsedTags(markdocAst: Node) { return tags; } -function getEntryInfo({ fileUrl, contents }: { fileUrl: URL; contents: string }) { - const parsed = parseFrontmatter(contents, fileURLToPath(fileUrl)); - return { - data: parsed.data, - body: parsed.content, - slug: parsed.data.slug, - rawData: parsed.matter, - }; -} - /** * Emits optimized images, and appends the generated `src` to each AST node * via the `__optimizedSrc` attribute. @@ -410,12 +402,11 @@ function getStringifiedMap( * Match YAML exception handling from Astro core errors * @see 'astro/src/core/errors.ts' */ -function parseFrontmatter(fileContents: string, filePath: string) { +function safeParseFrontmatter(fileContents: string, filePath: string) { try { - // `matter` is empty string on cache results - // clear cache to prevent this - (matter as any).clearCache(); - return matter(fileContents); + // empty with lines to preserve sourcemap location, but not `empty-with-spaces` + // because markdoc struggles with spaces + return parseFrontmatter(fileContents, { frontmatter: 'empty-with-lines' }); } catch (e: any) { if (e.name === 'YAMLException') { const err: Error & ViteErrorPayload['err'] = e; diff --git a/packages/integrations/markdoc/test/content-collections.test.js b/packages/integrations/markdoc/test/content-collections.test.js index 5417f297d..16032ce58 100644 --- a/packages/integrations/markdoc/test/content-collections.test.js +++ b/packages/integrations/markdoc/test/content-collections.test.js @@ -83,7 +83,7 @@ const post1Entry = { schemaWorks: true, title: 'Post 1', }, - body: '\n## Post 1\n\nThis is the contents of post 1.\n', + body: '## Post 1\n\nThis is the contents of post 1.', }; const post2Entry = { @@ -94,7 +94,7 @@ const post2Entry = { schemaWorks: true, title: 'Post 2', }, - body: '\n## Post 2\n\nThis is the contents of post 2.\n', + body: '## Post 2\n\nThis is the contents of post 2.', }; const post3Entry = { @@ -105,5 +105,5 @@ const post3Entry = { schemaWorks: true, title: 'Post 3', }, - body: '\n## Post 3\n\nThis is the contents of post 3.\n', + body: '## Post 3\n\nThis is the contents of post 3.', }; diff --git a/packages/integrations/mdx/package.json b/packages/integrations/mdx/package.json index bcb55ede0..ec02ebf12 100644 --- a/packages/integrations/mdx/package.json +++ b/packages/integrations/mdx/package.json @@ -39,7 +39,6 @@ "acorn": "^8.12.1", "es-module-lexer": "^1.5.4", "estree-util-visit": "^2.0.0", - "gray-matter": "^4.0.3", "hast-util-to-html": "^9.0.2", "kleur": "^4.1.5", "rehype-raw": "^7.0.0", diff --git a/packages/integrations/mdx/src/index.ts b/packages/integrations/mdx/src/index.ts index 3ebfc5f31..dcb13bc62 100644 --- a/packages/integrations/mdx/src/index.ts +++ b/packages/integrations/mdx/src/index.ts @@ -11,7 +11,7 @@ import type { import type { Options as RemarkRehypeOptions } from 'remark-rehype'; import type { PluggableList } from 'unified'; import type { OptimizeOptions } from './rehype-optimize-static.js'; -import { ignoreStringPlugins, parseFrontmatter } from './utils.js'; +import { ignoreStringPlugins, safeParseFrontmatter } from './utils.js'; import { vitePluginMdxPostprocess } from './vite-plugin-mdx-postprocess.js'; import { vitePluginMdx } from './vite-plugin-mdx.js'; @@ -60,12 +60,12 @@ export default function mdx(partialMdxOptions: Partial<MdxOptions> = {}): AstroI addContentEntryType({ extensions: ['.mdx'], async getEntryInfo({ fileUrl, contents }: { fileUrl: URL; contents: string }) { - const parsed = parseFrontmatter(contents, fileURLToPath(fileUrl)); + const parsed = safeParseFrontmatter(contents, fileURLToPath(fileUrl)); return { - data: parsed.data, - body: parsed.content, - slug: parsed.data.slug, - rawData: parsed.matter, + data: parsed.frontmatter, + body: parsed.content.trim(), + slug: parsed.frontmatter.slug, + rawData: parsed.rawFrontmatter, }; }, contentModuleTypes: await fs.readFile( diff --git a/packages/integrations/mdx/src/utils.ts b/packages/integrations/mdx/src/utils.ts index ad98abb9e..7dcd4a14c 100644 --- a/packages/integrations/mdx/src/utils.ts +++ b/packages/integrations/mdx/src/utils.ts @@ -1,7 +1,7 @@ +import { parseFrontmatter } from '@astrojs/markdown-remark'; import type { Options as AcornOpts } from 'acorn'; import { parse } from 'acorn'; import type { AstroConfig, AstroIntegrationLogger, SSRError } from 'astro'; -import matter from 'gray-matter'; import { bold } from 'kleur/colors'; import type { MdxjsEsm } from 'mdast-util-mdx'; import type { PluggableList } from 'unified'; @@ -48,9 +48,9 @@ export function getFileInfo(id: string, config: AstroConfig): FileInfo { * Match YAML exception handling from Astro core errors * @see 'astro/src/core/errors.ts' */ -export function parseFrontmatter(code: string, id: string) { +export function safeParseFrontmatter(code: string, id: string) { try { - return matter(code); + return parseFrontmatter(code, { frontmatter: 'empty-with-spaces' }); } catch (e: any) { if (e.name === 'YAMLException') { const err: SSRError = e; diff --git a/packages/integrations/mdx/src/vite-plugin-mdx.ts b/packages/integrations/mdx/src/vite-plugin-mdx.ts index 238286202..eea530c1c 100644 --- a/packages/integrations/mdx/src/vite-plugin-mdx.ts +++ b/packages/integrations/mdx/src/vite-plugin-mdx.ts @@ -4,7 +4,7 @@ import { VFile } from 'vfile'; import type { Plugin } from 'vite'; import type { MdxOptions } from './index.js'; import { createMdxProcessor } from './plugins.js'; -import { parseFrontmatter } from './utils.js'; +import { safeParseFrontmatter } from './utils.js'; export function vitePluginMdx(mdxOptions: MdxOptions): Plugin { let processor: ReturnType<typeof createMdxProcessor> | undefined; @@ -38,11 +38,10 @@ export function vitePluginMdx(mdxOptions: MdxOptions): Plugin { async transform(code, id) { if (!id.endsWith('.mdx')) return; - const { data: frontmatter, content: pageContent, matter } = parseFrontmatter(code, id); - const frontmatterLines = matter ? matter.match(/\n/g)?.join('') + '\n\n' : ''; + const { frontmatter, content } = safeParseFrontmatter(code, id); const vfile = new VFile({ - value: frontmatterLines + pageContent, + value: content, path: id, data: { astro: { |