Home / File/ rehype-apply-frontmatter-export.ts — astro Source File

rehype-apply-frontmatter-export.ts — astro Source File

Architecture documentation for rehype-apply-frontmatter-export.ts, a typescript file in the astro codebase. 6 imports, 0 dependents.

File typescript CoreAstro RoutingSystem 6 imports 2 functions 1 classes

Entity Profile

Dependency Diagram

graph LR
  50f0dfd4_d9b5_8cd5_80a6_3519a94ab6d7["rehype-apply-frontmatter-export.ts"]
  ab5f9b39_abc6_0697_d4ba_c51748add5b2["./utils.js"]
  50f0dfd4_d9b5_8cd5_80a6_3519a94ab6d7 --> ab5f9b39_abc6_0697_d4ba_c51748add5b2
  c52a5f83_66e3_37d7_9ebb_767f7129bc62["node:path"]
  50f0dfd4_d9b5_8cd5_80a6_3519a94ab6d7 --> c52a5f83_66e3_37d7_9ebb_767f7129bc62
  d9a92db9_c95e_9165_13ac_24b3d859d946["node:url"]
  50f0dfd4_d9b5_8cd5_80a6_3519a94ab6d7 --> d9a92db9_c95e_9165_13ac_24b3d859d946
  82f345a2_2234_43f1_c3c4_eea191acdca8["markdown-remark"]
  50f0dfd4_d9b5_8cd5_80a6_3519a94ab6d7 --> 82f345a2_2234_43f1_c3c4_eea191acdca8
  f76e2597_e3e8_c502_d293_a666b44d49ce["hast"]
  50f0dfd4_d9b5_8cd5_80a6_3519a94ab6d7 --> f76e2597_e3e8_c502_d293_a666b44d49ce
  b909a1d2_5b96_acd8_d198_1f106f44e2c3["vfile"]
  50f0dfd4_d9b5_8cd5_80a6_3519a94ab6d7 --> b909a1d2_5b96_acd8_d198_1f106f44e2c3
  style 50f0dfd4_d9b5_8cd5_80a6_3519a94ab6d7 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { isFrontmatterValid } from '@astrojs/markdown-remark';
import type { Root, RootContent } from 'hast';
import type { VFile } from 'vfile';
import { jsToTreeNode } from './utils.js';

// Passed metadata to help determine adding charset utf8 by default
declare module 'vfile' {
	interface DataMap {
		applyFrontmatterExport?: {
			srcDir?: URL;
		};
	}
}

const exportConstPartialTrueRe = /export\s+const\s+partial\s*=\s*true/;

export function rehypeApplyFrontmatterExport() {
	return function (tree: Root, vfile: VFile) {
		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 extraChildren: RootContent[] = [
			jsToTreeNode(`export const frontmatter = ${JSON.stringify(frontmatter)};`),
		];
		if (frontmatter.layout) {
			extraChildren.unshift(
				jsToTreeNode(
					// NOTE: Use `__astro_*` import names to prevent conflicts with user code
					/** @see 'vite-plugin-markdown' for layout props reference */
					`\
import { jsx as __astro_layout_jsx__ } from 'astro/jsx-runtime';
import __astro_layout_component__ from ${JSON.stringify(frontmatter.layout)};

export default function ({ children }) {
	const { layout, ...content } = frontmatter;
	content.file = file;
	content.url = url;
	return __astro_layout_jsx__(__astro_layout_component__, {
		file,
		url,
		content,
		frontmatter: content,
		headings: getHeadings(),
		'server:root': true,
		children,
	});
};`,
				),
			);
		} else if (shouldAddCharset(tree, vfile)) {
			extraChildren.unshift({
				type: 'mdxJsxFlowElement',
				name: 'meta',
				attributes: [
					{
						type: 'mdxJsxAttribute',
						name: 'charset',
						value: 'utf-8',
					},
				],
				children: [],
			});
		}
		tree.children = extraChildren.concat(tree.children);
	};
}

/**
 * If this is a page (e.g. in src/pages), has no layout frontmatter (handled before calling this function),
 * has no leading component that looks like a wrapping layout, and `partial` isn't set to true, we default to
 * adding charset=utf-8 like markdown so that users don't have to worry about it for MDX pages without layouts.
 */
function shouldAddCharset(tree: Root, vfile: VFile) {
	const srcDirUrl = vfile.data.applyFrontmatterExport?.srcDir;
	if (!srcDirUrl) return false;

	const hasConstPartialTrue = tree.children.some(
		(node) => node.type === 'mdxjsEsm' && exportConstPartialTrueRe.test(node.value),
	);
	if (hasConstPartialTrue) return false;

	// NOTE: the pages directory is a non-configurable Astro behaviour
	const pagesDir = path.join(fileURLToPath(srcDirUrl), 'pages').replace(/\\/g, '/');
	// `vfile.path` comes from Vite, which is a normalized path (no backslashes)
	const filePath = vfile.path;
	if (!filePath.startsWith(pagesDir)) return false;

	const hasLeadingUnderscoreInPath = filePath
		.slice(pagesDir.length)
		.replace(/\\/g, '/')
		.split('/')
		.some((part) => part.startsWith('_'));
	if (hasLeadingUnderscoreInPath) return false;

	// Bail if the first content found is a wrapping layout component
	for (const child of tree.children) {
		if (child.type === 'element') break;
		if (child.type === 'mdxJsxFlowElement') {
			// If is fragment or lowercase tag name (html tags), skip and assume there's no layout
			if (child.name == null) break;
			if (child.name[0] === child.name[0].toLowerCase()) break;
			return false;
		}
	}

	return true;
}

Domain

Subdomains

Classes

Types

Dependencies

  • ./utils.js
  • hast
  • markdown-remark
  • node:path
  • node:url
  • vfile

Frequently Asked Questions

What does rehype-apply-frontmatter-export.ts do?
rehype-apply-frontmatter-export.ts is a source file in the astro codebase, written in typescript. It belongs to the CoreAstro domain, RoutingSystem subdomain.
What functions are defined in rehype-apply-frontmatter-export.ts?
rehype-apply-frontmatter-export.ts defines 2 function(s): rehypeApplyFrontmatterExport, shouldAddCharset.
What does rehype-apply-frontmatter-export.ts depend on?
rehype-apply-frontmatter-export.ts imports 6 module(s): ./utils.js, hast, markdown-remark, node:path, node:url, vfile.
Where is rehype-apply-frontmatter-export.ts in the architecture?
rehype-apply-frontmatter-export.ts is located at packages/integrations/mdx/src/rehype-apply-frontmatter-export.ts (domain: CoreAstro, subdomain: RoutingSystem, directory: packages/integrations/mdx/src).

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free