UNPKG

fumadocs-mdx

Version:

The built-in source for Fumadocs

212 lines (209 loc) 6.63 kB
import { n as ident } from "./codegen-DleOVLNr.js"; import fs from "node:fs/promises"; import path from "node:path"; //#region src/utils/validation.ts var ValidationError = class extends Error { constructor(message, issues) { super(`${message}:\n${issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`); this.title = message; this.issues = issues; } async toStringFormatted() { const picocolorsModule = await import("picocolors"); const picocolors = picocolorsModule.default ?? picocolorsModule; return [picocolors.bold(`[MDX] ${this.title}:`), ...this.issues.map((issue) => picocolors.redBright(`- ${picocolors.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`))].join("\n"); } }; async function validate(schema, data, context, errorMessage) { if (typeof schema === "function" && !("~standard" in schema)) schema = schema(context); if ("~standard" in schema) { const result = await schema["~standard"].validate(data); if (result.issues) throw new ValidationError(errorMessage, result.issues); return result.value; } return data; } //#endregion //#region src/core.ts const _Defaults = { configPath: "source.config.ts", outDir: ".source" }; async function getPlugins(pluginOptions) { const plugins = []; for await (const option of pluginOptions) { if (!option) continue; if (Array.isArray(option)) plugins.push(...await getPlugins(option)); else plugins.push(option); } return plugins; } function createCore(options) { let config; let plugins; const workspaces = /* @__PURE__ */ new Map(); async function transformMetadata({ collection, filePath, source }, data) { if (collection.schema) data = await validate(collection.schema, data, { path: filePath, source }, collection.type === "doc" ? `invalid frontmatter in ${filePath}` : `invalid data in ${filePath}`); return data; } return { cache: /* @__PURE__ */ new Map(), async init({ config: newConfig }) { config = await newConfig; this.cache.clear(); workspaces.clear(); plugins = await getPlugins([ postprocessPlugin(), options.plugins, config.global.plugins ]); for (const plugin of plugins) { const out = await plugin.config?.call(this.getPluginContext(), config); if (out) config = out; } if (!options.workspace) await Promise.all(Object.entries(config.workspaces).map(async ([name, workspace]) => { const core = createCore({ ...options, outDir: path.join(options.outDir, name), workspace: { name, parent: this, dir: workspace.dir } }); await core.init({ config: workspace.config }); workspaces.set(name, core); })); }, getWorkspaces() { return workspaces; }, getOptions() { return options; }, getConfig() { return config; }, getCompiledConfigPath() { return path.join(options.outDir, "source.config.mjs"); }, getPlugins() { return plugins; }, getCollections() { return Array.from(config.collections.values()); }, getCollection(name) { return config.collections.get(name); }, getPluginContext() { return { core: this }; }, async initServer(server) { const ctx = this.getPluginContext(); for (const plugin of plugins) await plugin.configureServer?.call(ctx, server); for (const workspace of workspaces.values()) await workspace.initServer(server); }, async emit(emitOptions = {}) { const { filterPlugin, filterWorkspace, write = false } = emitOptions; const start = performance.now(); const ctx = this.getPluginContext(); const added = /* @__PURE__ */ new Set(); const out = { entries: [], workspaces: {} }; for (const li of await Promise.all(plugins.map((plugin) => { if (filterPlugin && !filterPlugin(plugin) || !plugin.emit) return; return plugin.emit.call(ctx); }))) { if (!li) continue; for (const item of li) { if (added.has(item.path)) continue; out.entries.push(item); added.add(item.path); } } if (write) { await Promise.all(out.entries.map(async (entry) => { const file = path.join(options.outDir, entry.path); await fs.mkdir(path.dirname(file), { recursive: true }); await fs.writeFile(file, entry.content); })); console.log(options.workspace ? `[MDX: ${options.workspace.name}] generated files in ${performance.now() - start}ms` : `[MDX] generated files in ${performance.now() - start}ms`); } for (const [name, workspace] of workspaces) { if (filterWorkspace && !filterWorkspace(name)) continue; out.workspaces[name] = (await workspace.emit(emitOptions)).entries; } return out; }, async transformMeta(options$1, data) { const ctx = { ...this.getPluginContext(), ...options$1 }; data = await transformMetadata(options$1, data); for (const plugin of plugins) if (plugin.meta?.transform) data = await plugin.meta.transform.call(ctx, data) ?? data; return data; }, async transformFrontmatter(options$1, data) { const ctx = { ...this.getPluginContext(), ...options$1 }; data = await transformMetadata(options$1, data); for (const plugin of plugins) if (plugin.doc?.frontmatter) data = await plugin.doc.frontmatter.call(ctx, data) ?? data; return data; }, async transformVFile(options$1, file) { const ctx = { ...this.getPluginContext(), ...options$1 }; for (const plugin of plugins) if (plugin.doc?.vfile) file = await plugin.doc.vfile.call(ctx, file) ?? file; return file; } }; } function postprocessPlugin() { const LinkReferenceTypes = `{ /** * extracted references (e.g. hrefs, paths), useful for analyzing relationships between pages. */ extractedReferences: import("fumadocs-mdx").ExtractedReference[]; }`; return { "index-file": { generateTypeConfig() { const lines = []; lines.push("{"); lines.push(" DocData: {"); for (const collection of this.core.getCollections()) { let postprocessOptions; switch (collection.type) { case "doc": postprocessOptions = collection.postprocess; break; case "docs": postprocessOptions = collection.docs.postprocess; break; } if (postprocessOptions?.extractLinkReferences) lines.push(ident(`${collection.name}: ${LinkReferenceTypes},`, 2)); } lines.push(" }"); lines.push("}"); return lines.join("\n"); }, serverOptions(options) { options.doc ??= {}; options.doc.passthroughs ??= []; options.doc.passthroughs.push("extractedReferences"); } } }; } //#endregion export { createCore as n, ValidationError as r, _Defaults as t }; //# sourceMappingURL=core-DjldE3H9.js.map