UNPKG

next-mdx-remote

Version:

utilities for loading mdx from any remote source as data, rather than as a local import

51 lines (50 loc) 2.12 kB
/** * Copyright (c) HashiCorp, Inc. * SPDX-License-Identifier: MPL-2.0 */ import { visit, SKIP } from 'unist-util-visit'; /** * Remark plugin that removes JavaScript expressions from MDX. * This blocks patterns like {variable} or {func()} that enable code execution. * * Safe patterns (preserved): * - JSX: <Component /> * - Markdown: # Heading, **bold**, etc. * * Blocked patterns: * - JS expressions: {variable}, {func()}, {obj.prop} * - JSX attribute expressions: <Component prop={value} /> */ export const removeJavaScriptExpressions = () => { return (tree) => { visit(tree, (node, index, parent) => { // Remove mdxFlowExpression and mdxTextExpression nodes (JS expressions in MDX) if (node.type === 'mdxFlowExpression' || node.type === 'mdxTextExpression') { // Remove this node from parent if (parent && typeof index === 'number') { parent.children.splice(index, 1); return [SKIP, index]; } } // Remove JavaScript expressions from JSX attribute values if (node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement') { if (node.attributes) { node.attributes = node.attributes.filter((attr) => { // Keep literal values, remove expression values if (attr.type === 'mdxJsxAttribute') { // If the value is null (boolean attribute) or a literal string, keep it return (attr.value === null || typeof attr.value === 'string' || (attr.value && attr.value.type !== 'mdxJsxAttributeValueExpression')); } // Remove spread attributes entirely as they're JS expressions return attr.type !== 'mdxJsxExpressionAttribute'; }); } } }); }; };