UNPKG

@mintlify/common

Version:

Commonly shared code within Mintlify

59 lines (58 loc) 2.16 kB
import { fromHtml } from 'hast-util-from-html'; import rehypeStringify from 'rehype-stringify'; import remarkGfm from 'remark-gfm'; import remarkParse from 'remark-parse'; import remarkRehype from 'remark-rehype'; import { unified } from 'unified'; import { visit } from 'unist-util-visit'; const DANGEROUS_TAGS = ['script', 'iframe', 'object', 'embed', 'style']; const rehypeResolveRelativeUrls = (siteUrl) => { return (tree) => { visit(tree, 'element', (node) => { var _a; for (const attr of ['href', 'src']) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition const value = (_a = node.properties) === null || _a === void 0 ? void 0 : _a[attr]; if (typeof value === 'string' && value.startsWith('/') && !value.startsWith('//')) { node.properties[attr] = `${siteUrl}${value}`; } } }); }; }; const rehypeRaw = () => { return (tree) => { visit(tree, 'raw', (raw, index, parent) => { if ('value' in raw && parent && index !== undefined) { const rawAst = fromHtml(raw.value, { fragment: true }); parent.children.splice(index, 1, ...rawAst.children); } }); }; }; const rehypeSanitizeDangerous = () => { return (tree) => { visit(tree, 'element', (node, index, parent) => { if (parent && typeof index === 'number' && DANGEROUS_TAGS.includes(node.tagName)) { parent.children.splice(index, 1); return ['skip', index]; } }); }; }; export const encodeContentAsHtml = (content, siteUrl) => { let processor = unified() .use(remarkParse) .use(remarkGfm) .use(remarkRehype, { allowDangerousHtml: true }) .use(rehypeRaw) .use(rehypeSanitizeDangerous); if (siteUrl) { processor = processor.use(rehypeResolveRelativeUrls, siteUrl); } const html = processor .use(rehypeStringify, { allowDangerousHtml: true }) .processSync(content) .toString(); return html; };