UNPKG

fumadocs-docgen

Version:

Useful remark utilities and plugins

229 lines (223 loc) 6.5 kB
import { __async } from "./chunk-4AFQP74Z.js"; // src/remark-docgen.ts import { visit } from "unist-util-visit"; var metaRegex = new RegExp("doc-gen:(?<name>.+)"); function remarkDocGen({ generators = [] }) { return (tree, file) => __async(null, null, function* () { generators.forEach((gen) => { var _a; return (_a = gen.onFile) == null ? void 0 : _a.call(gen, tree, file); }); const queue = []; visit(tree, "code", (code, _, parent) => { if (code.lang !== "json" || !code.meta || !parent) return; const matches = metaRegex.exec(code.meta); if (!matches) return; const name = matches[1]; const gen = generators.find((g) => g.name === name); const run = () => __async(null, null, function* () { const result = yield gen == null ? void 0 : gen.run(JSON.parse(code.value), { cwd: file.cwd, path: file.path, node: code }); const index = parent.children.findIndex((c) => c === code); if (result && index !== -1) { const items = Array.isArray(result) ? result : [result]; parent.children.splice(index, 1, ...items); } }); queue.push(run()); }); yield Promise.all(queue); }); } // src/utils.ts function createElement(name, attributes, children) { const element = { type: "mdxJsxFlowElement", name, attributes }; if (children) element.children = children; return element; } function expressionToAttribute(key, value) { return { type: "mdxJsxAttribute", name: key, value: { type: "mdxJsxAttributeValueExpression", value: "", data: { estree: { type: "Program", body: [ { type: "ExpressionStatement", expression: value } ] } } } }; } // src/file-generator.ts import * as fs from "fs/promises"; import * as path from "path"; import { z } from "zod"; var fileGeneratorSchema = z.object({ file: z.string(), /** * Turn file content into a code block * * @defaultValue false */ codeblock: z.union([ z.object({ lang: z.string().optional(), meta: z.string().optional() }), z.boolean() ]).default(false) }); function fileGenerator({ relative = false, trim = true } = {}) { return { name: "file", run(input, ctx) { return __async(this, null, function* () { var _a2; const { file, codeblock = false } = fileGeneratorSchema.parse(input); const dest = relative ? path.resolve(ctx.cwd, path.dirname(ctx.path), file) : path.resolve(ctx.cwd, file); let value = yield fs.readFile(dest).then((res) => res.toString()); if (trim) value = value.trim(); if (codeblock === false) { return { type: "paragraph", children: [{ type: "text", value }] }; } const codeOptions = codeblock === true ? {} : codeblock; return { type: "code", lang: (_a2 = codeOptions.lang) != null ? _a2 : path.extname(dest).slice(1), meta: codeOptions.meta, value }; }); } }; } // src/remark-install.ts import { visit as visit2 } from "unist-util-visit"; import convert from "npm-to-yarn"; function remarkInstall({ Tab = "Tab", Tabs = "Tabs", persist = false, packageManagers = [ { command: (cmd) => convert(cmd, "npm"), name: "npm" }, { command: (cmd) => convert(cmd, "pnpm"), name: "pnpm" }, { command: (cmd) => convert(cmd, "yarn"), name: "yarn" }, { command: (cmd) => convert(cmd, "bun"), name: "bun" } ] } = {}) { return (tree) => { visit2(tree, "code", (node) => { if (node.lang !== "package-install") return "skip"; const value = node.value.startsWith("npm") || node.value.startsWith("npx") ? node.value : `npm install ${node.value}`; const insert = createElement( Tabs, [ ...typeof persist === "object" ? [ { type: "mdxJsxAttribute", name: "groupId", value: persist.id }, { type: "mdxJsxAttribute", name: "persist", value: null } ] : [], expressionToAttribute("items", { type: "ArrayExpression", elements: packageManagers.map(({ name }) => ({ type: "Literal", value: name })) }) ], packageManagers.map(({ command, name }) => ({ type: "mdxJsxFlowElement", name: Tab, attributes: [{ type: "mdxJsxAttribute", name: "value", value: name }], children: [ { type: "code", lang: "bash", meta: node.meta, value: command(value) } ] })) ); Object.assign(node, insert); }); }; } // src/remark-show.ts import { visit as visit3 } from "unist-util-visit"; function remarkShow(options) { var _a; const variables = (_a = options == null ? void 0 : options.variables) != null ? _a : {}; return (tree, file) => __async(null, null, function* () { const { toJs } = yield import("estree-util-to-js"); const tasks = []; visit3(tree, "mdxJsxFlowElement", (node) => { var _a2; if (node.name !== "show") return; for (const attr of node.attributes) { if (attr.type !== "mdxJsxAttribute" || attr.name !== "on") continue; if (!attr.value || typeof attr.value !== "object" || !((_a2 = attr.value.data) == null ? void 0 : _a2.estree)) return "skip"; const js = toJs(attr.value.data.estree); const callback = new Function( ...Object.keys(variables), `return ${js.value}` )(...Object.values(variables)); tasks.push( (() => __async(null, null, function* () { const value = typeof callback === "function" ? yield callback(file) : callback; Object.assign(node, { type: "mdxJsxFlowElement", name: null, attributes: [], children: value === true ? node.children : [] }); }))() ); return "skip"; } }); yield Promise.all(tasks); }); } export { createElement, expressionToAttribute, fileGenerator, fileGeneratorSchema, remarkDocGen, remarkInstall, remarkShow };