fumadocs-openapi
Version:
Generate MDX docs for your OpenAPI spec
92 lines (90 loc) • 3.41 kB
JavaScript
import { generateDocument, toText } from "./utils/pages/to-text.js";
import { createAutoPreset } from "./utils/pages/preset-auto.js";
import { fromSchema } from "./utils/pages/builder.js";
import { mkdir, writeFile } from "node:fs/promises";
import * as path from "node:path";
import { createGetUrl, getSlugs } from "fumadocs-core/source";
//#region src/generate-file.ts
async function generateFiles(options) {
const files = await generateFilesOnly(options);
const { output } = options;
await Promise.all(files.map(async (file) => {
const filePath = path.join(output, file.path);
await mkdir(path.dirname(filePath), { recursive: true });
await writeFile(filePath, file.content);
console.log(`Generated: ${filePath}`);
}));
}
async function generateFilesOnly(options) {
const schemas = await options.input.getSchemas();
const files = [];
const generated = {};
const generatedEntries = {};
const entries = Object.entries(schemas);
if (entries.length === 0) throw new Error("No input files found.");
const preset = createAutoPreset(options);
for (const [id, schema] of entries) {
const entries$1 = fromSchema(id, schema, preset);
const schemaFiles = generated[id] ??= [];
generatedEntries[id] = entries$1;
for (const entry of entries$1) {
const file = {
path: entry.path,
content: toText(entry, schema, options)
};
schemaFiles.push(file);
files.push(file);
}
}
const context = {
generated,
generatedEntries,
documents: schemas
};
if (options.index) writeIndexFiles(files, context, options);
await options.beforeWrite?.call(context, files);
return files;
}
function writeIndexFiles(files, context, options) {
const { generatedEntries } = context;
const { items, url } = options.index;
let urlFn;
if (typeof url === "object") {
const getUrl = createGetUrl(url.baseUrl);
urlFn = (file) => getUrl(getSlugs(path.relative(url.contentDir, file)));
} else urlFn = url;
function findEntryByPath(path$1) {
for (const entries of Object.values(generatedEntries)) {
const match = entries.find((entry) => entry.path === path$1);
if (match) return match;
}
}
function fileContent(index) {
const content = [];
content.push("<Cards>");
const pathToEntry = /* @__PURE__ */ new Map();
const only = index.only ?? Object.keys(context.generated);
for (const item of only) if (generatedEntries[item]) for (const entry of generatedEntries[item]) pathToEntry.set(entry.path, entry);
else {
const match = findEntryByPath(item);
if (!match) throw new Error(`${item} does not exist on "input", available: ${Object.keys(generatedEntries).join(", ")}.`);
pathToEntry.set(match.path, match);
}
for (const file of pathToEntry.values()) {
const descriptionAttr = file.info.description ? `description=${JSON.stringify(file.info.description)} ` : "";
content.push(`<Card href="${urlFn(file.path)}" title=${JSON.stringify(file.info.title)} ${descriptionAttr}/>`);
}
content.push("</Cards>");
return generateDocument({
title: index.title ?? "Overview",
description: index.description
}, content.join("\n"), options);
}
for (const item of typeof items === "function" ? items(context) : items) files.push({
path: path.extname(item.path).length === 0 ? `${item.path}.mdx` : item.path,
content: fileContent(item)
});
}
//#endregion
export { generateFiles, generateFilesOnly };
//# sourceMappingURL=generate-file.js.map