fumapress 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,12 @@ import defaultMdxComponents, { createRelativeLink } from "fumadocs-ui/mdx";
3
3
  import { z } from "zod/mini";
4
4
  //#region src/adapters/mdx.ts
5
5
  function fumadocsMdx(options) {
6
- const getMdxComponents = options?.getMdxComponents;
6
+ const getMdxComponents = options?.getMdxComponents ?? async function(page) {
7
+ return {
8
+ ...defaultMdxComponents,
9
+ a: createRelativeLink(await this.getLoader(), page)
10
+ };
11
+ };
7
12
  return {
8
13
  async "core:get-text"(page) {
9
14
  if (isAsyncEntry(page.data) || isSyncEntry(page.data)) return page.data.getText("processed");
@@ -17,10 +22,7 @@ function fumadocsMdx(options) {
17
22
  if (isSyncEntry(page.data)) body = page.data.body;
18
23
  else if (isAsyncEntry(page.data)) body = (await page.data.load()).body;
19
24
  else return;
20
- return createElement(body, getMdxComponents ? await getMdxComponents.call(this, page) : { components: {
21
- ...defaultMdxComponents,
22
- a: createRelativeLink(await this.getLoader(), page)
23
- } });
25
+ return createElement(body, { components: await getMdxComponents.call(this, page) });
24
26
  },
25
27
  async "core:render-toc"(page) {
26
28
  if (isSyncEntry(page.data)) return page.data.toc;
@@ -0,0 +1,15 @@
1
+ import { ConfigContext } from "../config.js";
2
+ import { Adapter } from "../lib/types.js";
3
+ import { FC } from "react";
4
+ import { OpenAPIPageData } from "fumadocs-openapi/server";
5
+ import { ClientApiPageProps } from "fumadocs-openapi/ui/create-client";
6
+
7
+ //#region src/adapters/openapi.d.ts
8
+ interface OpenAPIAdapterOptions {
9
+ ClientAPIPage: FC<ClientApiPageProps>;
10
+ }
11
+ declare function fumadocsOpenAPI<C extends ConfigContext>(options: OpenAPIAdapterOptions): Adapter<C>;
12
+ /** @internal */
13
+ declare function isOpenAPI(data: object): data is OpenAPIPageData;
14
+ //#endregion
15
+ export { OpenAPIAdapterOptions, fumadocsOpenAPI, isOpenAPI };
@@ -0,0 +1,22 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ //#region src/adapters/openapi.tsx
3
+ function fumadocsOpenAPI(options) {
4
+ const { ClientAPIPage } = options;
5
+ return {
6
+ async "core:render-body"(page) {
7
+ if (isOpenAPI(page.data)) return /* @__PURE__ */ jsx(ClientAPIPage, { ...await page.data.getClientAPIPageProps() });
8
+ },
9
+ "core:render-toc"(page) {
10
+ if (isOpenAPI(page.data)) return page.data.toc;
11
+ },
12
+ "core:get-structured-data"(page) {
13
+ if (isOpenAPI(page.data)) return page.data.structuredData;
14
+ }
15
+ };
16
+ }
17
+ /** @internal */
18
+ function isOpenAPI(data) {
19
+ return "getAPIPageProps" in data && typeof data.getAPIPageProps === "function";
20
+ }
21
+ //#endregion
22
+ export { fumadocsOpenAPI, isOpenAPI };
package/dist/config.d.ts CHANGED
@@ -37,8 +37,9 @@ interface Layouts<C extends ConfigContext = ConfigContext> {
37
37
  }>;
38
38
  page: ComponentType<{
39
39
  lang?: string;
40
- ctx: AppContext<C>;
41
40
  slugs: string[];
41
+ ctx: AppContext<C>;
42
+ page: C["loaderConfig"]["page"];
42
43
  }>;
43
44
  notFound: ComponentType<{
44
45
  lang?: string;
@@ -6,7 +6,6 @@ import { BlogPanel, BlogProvider } from "../components/blog-panel.js";
6
6
  import { createHomeLayout } from "./home.js";
7
7
  import { Link } from "waku";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
- import { unstable_notFound } from "waku/router/server";
10
9
  import { TagIcon } from "lucide-react";
11
10
  //#region src/layouts/blog.tsx
12
11
  function createBlogLayout(options) {
@@ -24,9 +23,7 @@ function createBlogLayout(options) {
24
23
  }
25
24
  function createBlogLayoutPage(options = {}) {
26
25
  const { render } = options;
27
- return async function BlogLayoutPage({ slugs, ctx, blog, lang }) {
28
- const page = (await ctx.getLoader()).getPage(slugs, lang);
29
- if (!page) unstable_notFound();
26
+ return async function BlogLayoutPage({ ctx, page, blog, lang }) {
30
27
  const tags = await getTags(ctx, page);
31
28
  const _raw = await render?.call(ctx, page);
32
29
  const result = {
@@ -1,17 +1,14 @@
1
1
  import { baseLayoutProps, createTransformChildren, getGitHubFileUrl, getLastModifiedDate, mergeLayoutConfigs, renderBody, renderPageMeta, renderToc } from "../lib/shared.js";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import { unstable_notFound } from "waku/router/server";
4
3
  import { DocsLayout } from "fumadocs-ui/layouts/docs";
5
4
  import { DocsBody, DocsDescription, DocsPage, DocsTitle, MarkdownCopyButton, PageLastUpdate, ViewOptionsPopover } from "fumadocs-ui/layouts/docs/page";
6
5
  //#region src/layouts/docs.tsx
7
6
  function createDocsLayoutPage({ render } = {}) {
8
7
  const TDocsLayout = createTransformChildren(DocsLayout);
9
8
  const TDocsPage = createTransformChildren(DocsPage);
10
- return async function Layout({ slugs, lang, ctx }) {
9
+ return async function Layout({ lang, page, ctx }) {
11
10
  const { getLoader, layouts, data: { "core:docs-layout": layoutData } } = ctx;
12
11
  const source = await getLoader();
13
- const page = source.getPage(slugs, lang);
14
- if (!page) unstable_notFound();
15
12
  async function getLayoutProps(overrides) {
16
13
  const inherit = await layouts.defaultProps?.call(ctx, { lang });
17
14
  return mergeLayoutConfigs({ tree: source.getPageTree(lang) }, baseLayoutProps(ctx), inherit, overrides);
@@ -1,14 +1,11 @@
1
1
  import { baseLayoutProps, createTransformChildren, mergeLayoutConfigs, renderBody, renderPageMeta } from "../lib/shared.js";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import { unstable_notFound } from "waku/router/server";
4
3
  import { HomeLayout } from "fumadocs-ui/layouts/home";
5
4
  //#region src/layouts/home.tsx
6
5
  function createHomeLayoutPage({ render } = {}) {
7
6
  const THomeLayout = createTransformChildren(HomeLayout);
8
- return async function Layout({ slugs, lang, ctx }) {
9
- const { getLoader, layouts, data: { "core:home-layout": layoutData } } = ctx;
10
- const page = (await getLoader()).getPage(slugs, lang);
11
- if (!page) unstable_notFound();
7
+ return async function Layout({ lang, page, ctx }) {
8
+ const { layouts, data: { "core:home-layout": layoutData } } = ctx;
12
9
  async function getLayoutProps(overrides) {
13
10
  const inherit = await layouts.defaultProps?.call(ctx, { lang });
14
11
  return mergeLayoutConfigs(baseLayoutProps(ctx), inherit, overrides);
@@ -1,17 +1,14 @@
1
1
  import { baseLayoutProps, createTransformChildren, getGitHubFileUrl, getLastModifiedDate, mergeLayoutConfigs, renderBody, renderPageMeta, renderToc } from "../lib/shared.js";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import { unstable_notFound } from "waku/router/server";
4
3
  import { DocsLayout } from "fumadocs-ui/layouts/notebook";
5
4
  import { DocsBody, DocsDescription, DocsPage, DocsTitle, MarkdownCopyButton, PageLastUpdate, ViewOptionsPopover } from "fumadocs-ui/layouts/notebook/page";
6
5
  //#region src/layouts/notebook.tsx
7
6
  function createNotebookLayoutPage({ render } = {}) {
8
7
  const TDocsLayout = createTransformChildren(DocsLayout);
9
8
  const TDocsPage = createTransformChildren(DocsPage);
10
- return async function Layout({ slugs, lang, ctx }) {
9
+ return async function Layout({ lang, page, ctx }) {
11
10
  const { getLoader, layouts, data: { "core:notebook-layout": layoutData } } = ctx;
12
11
  const source = await getLoader();
13
- const page = source.getPage(slugs, lang);
14
- if (!page) unstable_notFound();
15
12
  async function getLayoutProps(overrides) {
16
13
  const inherit = await layouts.defaultProps?.call(ctx, { lang });
17
14
  return mergeLayoutConfigs({ tree: source.getPageTree(lang) }, baseLayoutProps(ctx), inherit, overrides);
@@ -3,9 +3,8 @@ import { unstable_notFound } from "waku/router/server";
3
3
  //#region src/layouts/switch.tsx
4
4
  function createLayoutSwitchAuto(layouts) {
5
5
  return async function(props) {
6
- const { slugs, lang, ctx } = props;
7
- const page = (await ctx.getLoader()).getPage(slugs, lang);
8
- if (!page?.type) unstable_notFound();
6
+ const { page } = props;
7
+ if (!page.type) unstable_notFound();
9
8
  const Layout = layouts[page.type];
10
9
  if (!Layout) unstable_notFound();
11
10
  return /* @__PURE__ */ jsx(Layout, { ...props });
@@ -13,10 +12,7 @@ function createLayoutSwitchAuto(layouts) {
13
12
  }
14
13
  function createLayoutSwitch(detector, layouts) {
15
14
  return async function(props) {
16
- const { slugs, lang, ctx } = props;
17
- const page = (await ctx.getLoader()).getPage(slugs, lang);
18
- if (!page) unstable_notFound();
19
- const Layout = layouts[detector.call(ctx, page)];
15
+ const Layout = layouts[detector.call(props.ctx, props.page)];
20
16
  if (!Layout) unstable_notFound();
21
17
  return /* @__PURE__ */ jsx(Layout, { ...props });
22
18
  };
@@ -23,15 +23,17 @@ interface CreatePagesContext<C extends ConfigContext = ConfigContext> extends Ap
23
23
  }
24
24
  interface ServerPlugin<C extends ConfigContext = ConfigContext> {
25
25
  /** receive & modify context */
26
- init?: (this: AppContext<C>) => void;
26
+ init?: (this: AppContext<C>) => Awaitable<void>;
27
27
  createPages?: (this: CreatePagesContext<C>, fns: RouteFns) => Awaitable<void>;
28
28
  }
29
- interface RouteFns {
29
+ interface BaseRouteFns {
30
30
  createPage: CreatePage;
31
31
  createLayout: CreateLayout;
32
32
  createRoot: CreateRoot;
33
33
  createApi: CreateApi;
34
34
  createSlice: CreateSlice;
35
+ }
36
+ interface RouteFns extends BaseRouteFns {
35
37
  createApiIsomorphic: (config: {
36
38
  render: "static" | "dynamic";
37
39
  path: string;
@@ -37,6 +37,7 @@ interface BlogContext<C extends ConfigContext> {
37
37
  type BlogLayoutPage<C extends ConfigContext = ConfigContext> = ComponentType<{
38
38
  lang?: string;
39
39
  slugs: string[];
40
+ page: C["loaderConfig"]["page"];
40
41
  blog: BlogContext<C>;
41
42
  ctx: AppContext<C>;
42
43
  }>;
@@ -4,6 +4,7 @@ import { groupTags, groupTagsI18n } from "../lib/shared/blog.js";
4
4
  import { createBlogTagPage, createBlogTagsPage } from "../layouts/blog.tags.js";
5
5
  import { createBlogLayout, createBlogLayoutPage } from "../layouts/blog.js";
6
6
  import { jsx } from "react/jsx-runtime";
7
+ import { unstable_notFound } from "waku/router/server";
7
8
  //#region src/plugins/blog.tsx
8
9
  function blogPlugin({ paths = {}, isBlog = (page) => page.type === "blog", layouts = {} } = {}) {
9
10
  const blogCtx = {
@@ -39,11 +40,14 @@ function blogPlugin({ paths = {}, isBlog = (page) => page.type === "blog", layou
39
40
  render: renderMode,
40
41
  path: "/[lang]/(blog)/[...slugs]",
41
42
  staticPaths: blogPages.map((page) => [page.locale, ...page.slugs]),
42
- component: ({ slugs, lang }) => {
43
+ component: async ({ slugs, lang }) => {
44
+ const page = (await this.getLoader()).getPage(slugs, lang);
45
+ if (!page || !isBlog.call(this, page)) unstable_notFound();
43
46
  return /* @__PURE__ */ jsx(Page, {
44
47
  lang,
45
48
  slugs,
46
49
  blog: blogCtx,
50
+ page,
47
51
  ctx: this
48
52
  });
49
53
  }
@@ -111,10 +115,13 @@ function blogPlugin({ paths = {}, isBlog = (page) => page.type === "blog", layou
111
115
  render: renderMode,
112
116
  path: "/(blog)/[...slugs]",
113
117
  staticPaths: blogPages.map((page) => page.slugs),
114
- component: ({ slugs }) => {
118
+ component: async ({ slugs }) => {
119
+ const page = (await this.getLoader()).getPage(slugs);
120
+ if (!page || !isBlog.call(this, page)) unstable_notFound();
115
121
  return /* @__PURE__ */ jsx(Page, {
116
122
  blog: blogCtx,
117
123
  slugs,
124
+ page,
118
125
  ctx: this
119
126
  });
120
127
  }
@@ -151,7 +158,7 @@ function blogPlugin({ paths = {}, isBlog = (page) => page.type === "blog", layou
151
158
  createPage({
152
159
  path: joinPathname("/(blog)", blogCtx.tagsPath, "[tag]"),
153
160
  render: renderMode,
154
- staticPaths: grouped ? Array.from(grouped.keys()) : [],
161
+ staticPaths: Array.from(grouped.keys()),
155
162
  component: ({ tag }) => {
156
163
  return /* @__PURE__ */ jsx(TagPage, {
157
164
  tag,
@@ -4,7 +4,7 @@ import { Awaitable, ServerPlugin } from "../lib/types.js";
4
4
 
5
5
  //#region src/plugins/llms.txt.d.ts
6
6
  interface LLMsOptions<C extends ConfigContext = ConfigContext> {
7
- getLLMText?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => Awaitable<string>;
7
+ getLLMText?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => Awaitable<string | undefined>;
8
8
  }
9
9
  declare function llmsPlugin<C extends ConfigContext = ConfigContext>(options?: LLMsOptions<NoInfer<C>>): ServerPlugin<C>;
10
10
  //#endregion
@@ -7,7 +7,6 @@ function llmsPlugin(options = {}) {
7
7
  const txt = await adapter["core:get-text"]?.call(this, page);
8
8
  if (txt !== void 0) return `# ${page.data.title} (${page.url})\n\n${txt}`;
9
9
  }
10
- throw new Error("[Fumapress] Please specify the `getLLMText()` option in llmsPlugin()");
11
10
  } } = options;
12
11
  return {
13
12
  init() {
@@ -33,9 +32,9 @@ function llmsPlugin(options = {}) {
33
32
  render: defaultRenderMode,
34
33
  path: "/llms-full.txt",
35
34
  handler: async () => {
36
- const scan = (await this.getLoader()).getPages().map(getLLMText);
37
- const scanned = await Promise.all(scan);
38
- return new Response(scanned.join("\n\n"));
35
+ const source = await this.getLoader();
36
+ const scanned = await Promise.all(source.getPages().map(getLLMText));
37
+ return new Response(scanned.filter((item) => item !== void 0).join("\n\n"));
39
38
  }
40
39
  });
41
40
  createApiIsomorphic({
@@ -45,7 +44,8 @@ function llmsPlugin(options = {}) {
45
44
  handler: async (_req, { params }) => {
46
45
  const page = (await this.getLoader()).getPage(markdownPathToSlugs(params.slugs), params.lang);
47
46
  if (!page) unstable_notFound();
48
- return new Response(await getLLMText(page), { headers: { "Content-Type": "text/markdown" } });
47
+ const txt = await getLLMText(page);
48
+ return new Response(txt ?? "", { headers: { "Content-Type": "text/markdown" } });
49
49
  }
50
50
  });
51
51
  }
@@ -0,0 +1,13 @@
1
+ import { ConfigContext } from "../config.js";
2
+ import { ServerPlugin } from "../lib/types.js";
3
+ import { OpenAPIAdapterOptions } from "../adapters/openapi.js";
4
+ import { openapiPlugin as openapiLoaderPlugin } from "fumadocs-openapi/server";
5
+
6
+ //#region src/plugins/openapi.d.ts
7
+ type OpenAPIOptions = OpenAPIAdapterOptions;
8
+ /**
9
+ * this will register the OpenAPI adapter & required layout configs.
10
+ */
11
+ declare function openapiPlugin<C extends ConfigContext>(options: OpenAPIOptions): ServerPlugin<C>;
12
+ //#endregion
13
+ export { OpenAPIOptions, openapiLoaderPlugin, openapiPlugin };
@@ -0,0 +1,21 @@
1
+ import { fumadocsOpenAPI, isOpenAPI } from "../adapters/openapi.js";
2
+ import { openapiPlugin as openapiLoaderPlugin } from "fumadocs-openapi/server";
3
+ //#region src/plugins/openapi.tsx
4
+ /**
5
+ * this will register the OpenAPI adapter & required layout configs.
6
+ */
7
+ function openapiPlugin(options) {
8
+ function initRenderers(data) {
9
+ (data.renderers ??= []).push(function(data) {
10
+ if (isOpenAPI(this.page.data)) data.pageProps.full ??= true;
11
+ return data;
12
+ });
13
+ }
14
+ return { init() {
15
+ this.adapters.push(fumadocsOpenAPI(options));
16
+ initRenderers(this.data["core:docs-layout"] ??= {});
17
+ initRenderers(this.data["core:notebook-layout"] ??= {});
18
+ } };
19
+ }
20
+ //#endregion
21
+ export { openapiLoaderPlugin, openapiPlugin };
package/dist/router.d.ts CHANGED
@@ -1,10 +1,12 @@
1
+ import { AppContext } from "./lib/shared.js";
1
2
  import { Config, ConfigContext } from "./config.js";
3
+ import { Awaitable, RouteFns } from "./lib/types.js";
2
4
  import * as waku from "waku";
3
5
 
4
6
  //#region src/router.d.ts
7
+ type Options = Parameters<typeof waku.createPages>[1];
5
8
  declare function createRouter<C extends ConfigContext>(userConfig: Config<C>): {
6
- extend: typeof waku.createPages;
7
- createPages: () => ReturnType<typeof waku.createPages>;
9
+ createPages: (fn?: (this: AppContext<C>, fns: RouteFns) => Awaitable<void>, options?: Options) => ReturnType<typeof waku.createPages>;
8
10
  };
9
11
  //#endregion
10
12
  export { createRouter };
package/dist/router.js CHANGED
@@ -2,12 +2,12 @@ import { parseConfig } from "./lib/shared.js";
2
2
  import * as waku from "waku";
3
3
  import { Fragment } from "react";
4
4
  import { jsx } from "react/jsx-runtime";
5
- import { unstable_redirect } from "waku/router/server";
5
+ import { unstable_notFound, unstable_redirect } from "waku/router/server";
6
6
  //#region src/router.tsx
7
7
  function createRouter(userConfig) {
8
8
  async function init() {
9
9
  const context = parseConfig(userConfig);
10
- for (const plugin of context.plugins) plugin.init?.call(context);
10
+ for (const plugin of context.plugins) await plugin.init?.call(context);
11
11
  return {
12
12
  context,
13
13
  root: context.layouts.root ?? (await import("./layouts/root.js")).createRootLayout(),
@@ -35,7 +35,7 @@ function createRouter(userConfig) {
35
35
  });
36
36
  }
37
37
  };
38
- await base(fns);
38
+ await base?.call(context, fns);
39
39
  const resolved = /* @__PURE__ */ new Set();
40
40
  const createPagesCtx = {
41
41
  ...context,
@@ -44,7 +44,12 @@ function createRouter(userConfig) {
44
44
  }
45
45
  };
46
46
  for (const plugin of context.plugins) await plugin.createPages?.call(createPagesCtx, fns);
47
- const pendingPages = (await context.getLoader()).getPages().filter((page) => !resolved.has(page));
47
+ const source = await context.getLoader();
48
+ const staticPaths = [];
49
+ for (const page of source.getPages()) {
50
+ if (resolved.has(page)) continue;
51
+ staticPaths.push(page.locale ? [page.locale, ...page.slugs] : page.slugs);
52
+ }
48
53
  const defaultRenderMode = context.mode === "dynamic" ? "dynamic" : "static";
49
54
  if (context.i18nConfig) {
50
55
  fns.createRoot({
@@ -65,11 +70,14 @@ function createRouter(userConfig) {
65
70
  fns.createPage({
66
71
  render: defaultRenderMode,
67
72
  path: "/[lang]/[...slugs]",
68
- staticPaths: pendingPages.map((page) => [page.locale, ...page.slugs]),
69
- component({ slugs, lang }) {
73
+ staticPaths,
74
+ async component({ slugs, lang }) {
75
+ const page = (await context.getLoader()).getPage(slugs, lang);
76
+ if (!page || resolved.has(page)) unstable_notFound();
70
77
  return /* @__PURE__ */ jsx(layouts.page, {
71
78
  lang,
72
79
  slugs,
80
+ page,
73
81
  ctx: context
74
82
  });
75
83
  }
@@ -105,10 +113,13 @@ function createRouter(userConfig) {
105
113
  fns.createPage({
106
114
  render: defaultRenderMode,
107
115
  path: "/[...slugs]",
108
- staticPaths: pendingPages.map((page) => page.slugs),
109
- component({ slugs }) {
116
+ staticPaths,
117
+ async component({ slugs }) {
118
+ const page = (await context.getLoader()).getPage(slugs);
119
+ if (!page || resolved.has(page)) unstable_notFound();
110
120
  return /* @__PURE__ */ jsx(layouts.page, {
111
121
  slugs,
122
+ page,
112
123
  ctx: context
113
124
  });
114
125
  }
@@ -125,12 +136,7 @@ function createRouter(userConfig) {
125
136
  return null;
126
137
  }, createPagesOptions);
127
138
  };
128
- return {
129
- extend: createPages,
130
- createPages() {
131
- return createPages(() => null);
132
- }
133
- };
139
+ return { createPages };
134
140
  }
135
141
  //#endregion
136
142
  export { createRouter };
package/dist/vite.d.ts CHANGED
@@ -1,6 +1,14 @@
1
- import { PluginOption } from "vite";
1
+ import { Plugin } from "vite";
2
2
 
3
3
  //#region src/vite.d.ts
4
- declare function press(): PluginOption;
4
+ interface PluginOptions {
5
+ /**
6
+ * Auto-generate Vite config to handle CJS bundling.
7
+ *
8
+ * @default true
9
+ */
10
+ generateViteConfig?: boolean;
11
+ }
12
+ declare function press(options?: PluginOptions): Plugin;
5
13
  //#endregion
6
- export { press as default };
14
+ export { PluginOptions, press as default };
package/dist/vite.js CHANGED
@@ -1,12 +1,11 @@
1
1
  import { crawlFrameworkPkgs } from "./lib/vitefu.js";
2
2
  //#region src/vite.ts
3
- function press() {
4
- return pressCore();
5
- }
6
- function pressCore() {
3
+ function press(options = {}) {
4
+ const { generateViteConfig = true } = options;
7
5
  return {
8
6
  name: "fumapress:core",
9
7
  async config(_, { command }) {
8
+ if (!generateViteConfig) return;
10
9
  const out = await crawlFrameworkPkgs({
11
10
  root: process.cwd(),
12
11
  isBuild: command === "build",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumapress",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "An opinionated docs framework powered by Fumadocs",
5
5
  "keywords": [
6
6
  "Docs",
@@ -21,6 +21,7 @@
21
21
  ".": "./dist/index.js",
22
22
  "./adapters/mdx": "./dist/adapters/mdx.js",
23
23
  "./adapters/mdx/schema": "./dist/adapters/mdx/schema.js",
24
+ "./adapters/openapi": "./dist/adapters/openapi.js",
24
25
  "./layouts/blog": "./dist/layouts/blog.js",
25
26
  "./layouts/blog.index": "./dist/layouts/blog.index.js",
26
27
  "./layouts/blog.tags": "./dist/layouts/blog.tags.js",
@@ -32,6 +33,7 @@
32
33
  "./plugins/blog": "./dist/plugins/blog.js",
33
34
  "./plugins/flexsearch": "./dist/plugins/flexsearch.js",
34
35
  "./plugins/llms.txt": "./dist/plugins/llms.txt.js",
36
+ "./plugins/openapi": "./dist/plugins/openapi.js",
35
37
  "./plugins/orama-search": "./dist/plugins/orama-search.js",
36
38
  "./plugins/takumi": "./dist/plugins/takumi.js",
37
39
  "./router": "./dist/router.js",
@@ -61,7 +63,8 @@
61
63
  "@types/mdx": "^2.0.13",
62
64
  "@types/node": "^25.8.0",
63
65
  "@types/react": "^19.2.14",
64
- "fumadocs-mdx": "^15.0.5",
66
+ "fumadocs-mdx": "^15.0.6",
67
+ "fumadocs-openapi": "^10.8.5",
65
68
  "react": "^19.2.6",
66
69
  "react-dom": "^19.2.6",
67
70
  "tsdown": "0.22.0",
@@ -72,11 +75,15 @@
72
75
  "@types/mdx": "*",
73
76
  "@types/react": "*",
74
77
  "fumadocs-mdx": "^15.0.0",
78
+ "fumadocs-openapi": "^10.8.0",
75
79
  "react": "^19.2.0",
76
80
  "react-dom": "^19.2.0",
77
81
  "waku": "1.0.0-beta.0"
78
82
  },
79
83
  "peerDependenciesMeta": {
84
+ "fumadocs-openapi": {
85
+ "optional": true
86
+ },
80
87
  "@types/mdx": {
81
88
  "optional": true
82
89
  },