UNPKG

fumadocs-openapi

Version:

Generate MDX docs for your OpenAPI spec

136 lines (134 loc) 4.57 kB
import { createMethod } from "../utils/schema.js"; import { defaultAdapters } from "../requests/media/adapter.js"; import { Operation } from "./operation/index.js"; import { ApiProviderLazy } from "./contexts/api.lazy.js"; import Slugger from "github-slugger"; import * as JsxRuntime from "react/jsx-runtime"; import { jsx, jsxs } from "react/jsx-runtime"; import { CodeBlock, Pre } from "fumadocs-ui/components/codeblock"; import { highlight } from "fumadocs-core/highlight"; import { Heading } from "fumadocs-ui/components/heading"; import { rehypeCode } from "fumadocs-core/mdx-plugins/rehype-code"; import { remarkGfm } from "fumadocs-core/mdx-plugins/remark-gfm"; import defaultMdxComponents from "fumadocs-ui/mdx"; import { remark } from "remark"; import remarkRehype from "remark-rehype"; import { toJsxRuntime } from "hast-util-to-jsx-runtime"; //#region src/ui/api-page.tsx function createAPIPage(server, options = {}) { let processor; function createMarkdownProcessor() { function rehypeReact() { this.compiler = (tree, file) => { return toJsxRuntime(tree, { development: false, filePath: file.path, ...JsxRuntime, components: defaultMdxComponents }); }; } return remark().use(remarkGfm).use(remarkRehype).use(rehypeCode, { langs: [], lazy: true }).use(rehypeReact); } return async function APIPageWrapper({ document, ...props }) { let processed; if (typeof document === "string") processed = await server.getSchema(document); else processed = await document; const { dereferenced } = processed; const servers = dereferenced.servers && dereferenced.servers.length > 0 ? dereferenced.servers : [{ url: "/" }]; const slugger = new Slugger(); const ctx = { schema: processed, proxyUrl: server.options.proxyUrl, ...options, servers, mediaAdapters: { ...defaultAdapters, ...options.mediaAdapters }, slugger, renderHeading(depth, text, props$1) { const id = slugger.slug(text); return /* @__PURE__ */ jsx(Heading, { id, as: `h${depth}`, ...props$1, children: text }, id); }, async renderMarkdown(text) { processor ??= createMarkdownProcessor(); return (await processor.process({ value: text })).result; }, async renderCodeBlock(lang, code) { return /* @__PURE__ */ jsx(CodeBlock, { className: "my-0", children: await highlight(code, { lang, ...options.shikiOptions, components: { pre: (props$1) => /* @__PURE__ */ jsx(Pre, { ...props$1 }) } }) }); } }; return /* @__PURE__ */ jsx(APIPage, { ...props, ctx }); }; } async function APIPage({ showTitle: hasHead = false, showDescription, operations, webhooks, ctx }) { const { dereferenced } = ctx.schema; let { renderPageLayout } = ctx.content ?? {}; renderPageLayout ??= (slots) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-24 text-sm @container", children: [slots.operations?.map((op) => op.children), slots.webhooks?.map((op) => op.children)] }); const content = await renderPageLayout({ operations: operations?.map((item) => { const pathItem = dereferenced.paths?.[item.path]; if (!pathItem) throw new Error(`[Fumadocs OpenAPI] Path not found in OpenAPI schema: ${item.path}`); const operation = pathItem[item.method]; if (!operation) throw new Error(`[Fumadocs OpenAPI] Method ${item.method} not found in operation: ${item.path}`); return { item, children: /* @__PURE__ */ jsx(Operation, { method: createMethod(item.method, pathItem, operation), path: item.path, ctx, showTitle: hasHead, showDescription }, `${item.path}:${item.method}`) }; }), webhooks: webhooks?.map((item) => { const webhook = dereferenced.webhooks?.[item.name]; if (!webhook) throw new Error(`[Fumadocs OpenAPI] Webhook not found in OpenAPI schema: ${item.name}`); const hook = webhook[item.method]; if (!hook) throw new Error(`[Fumadocs OpenAPI] Method ${item.method} not found in webhook: ${item.name}`); return { item, children: /* @__PURE__ */ jsx(Operation, { type: "webhook", method: createMethod(item.method, webhook, hook), ctx, path: `/${item.name}`, showTitle: hasHead, showDescription }, `${item.name}:${item.method}`) }; }) }, ctx); return /* @__PURE__ */ jsx(ApiProviderLazy, { servers: ctx.servers, shikiOptions: ctx.shikiOptions, client: ctx.client ?? {}, children: content }); } //#endregion export { createAPIPage }; //# sourceMappingURL=api-page.js.map