@mintlify/common
Version:
Commonly shared code within Mintlify
59 lines (58 loc) • 2.16 kB
JavaScript
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;
};