fumadocs-openapi 5.5.3 → 5.5.5

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.
package/dist/index.js CHANGED
@@ -286,7 +286,7 @@ async function generateFiles(options) {
286
286
  const metaFiles = new Set();
287
287
  const results = await generateOperations(pathOrUrl, options);
288
288
  await Promise.all(results.map(async (result)=>{
289
- let outPaths = new Array();
289
+ const outPaths = new Array();
290
290
  if (!result.method.operationId) return;
291
291
  const id = result.method.operationId.split('.').at(-1) ?? result.method.operationId;
292
292
  if (groupBy === 'tag' && result.method.tags && result.method.tags.length > 0) {
@@ -294,7 +294,7 @@ async function generateFiles(options) {
294
294
  outPaths.push(join(outputDir, getFilename(tag), `${getFilename(id)}.mdx`));
295
295
  }
296
296
  } else if (groupBy === 'route') {
297
- let outPath = join(outputDir, result.route.summary ? getFilename(result.route.summary) : getFilenameFromRoute(result.route.path), `${getFilename(id)}.mdx`);
297
+ const outPath = join(outputDir, result.route.summary ? getFilename(result.route.summary) : getFilenameFromRoute(result.route.path), `${getFilename(id)}.mdx`);
298
298
  const metaFile = join(dirname(outPath), 'meta.json');
299
299
  if (result.route.summary && !metaFiles.has(metaFile)) {
300
300
  metaFiles.add(metaFile);
@@ -13,7 +13,7 @@ import { Heading } from 'fumadocs-ui/components/heading';
13
13
  import { Tabs, Tab } from 'fumadocs-ui/components/tabs';
14
14
  import { Accordions, Accordion } from 'fumadocs-ui/components/accordion';
15
15
  import * as Base from 'fumadocs-ui/components/codeblock';
16
- import { codeToHast } from 'shiki';
16
+ import { highlight } from 'fumadocs-core/server';
17
17
  import { Root, API, APIInfo, APIExample as APIExample$1, Property, ObjectCollapsible, APIPlayground } from '../ui/index.js';
18
18
  import { cva } from 'class-variance-authority';
19
19
 
@@ -439,27 +439,11 @@ function idToTitle(id) {
439
439
  return result.join('');
440
440
  }
441
441
 
442
- const sharedTransformers = [
443
- {
444
- name: 'fumadocs:pre-process',
445
- line (hast) {
446
- if (hast.children.length === 0) {
447
- // Keep the empty lines when using grid layout
448
- hast.children.push({
449
- type: 'text',
450
- value: ' '
451
- });
452
- }
453
- }
454
- }
455
- ];
456
-
457
442
  const processor = remark().use(remarkGfm).use(remarkImage, {
458
443
  useImport: false
459
444
  }).use(remarkRehype).use(rehypeCode, {
460
445
  langs: [],
461
- lazy: true,
462
- transformers: sharedTransformers
446
+ lazy: true
463
447
  });
464
448
  async function Markdown({ text }) {
465
449
  const nodes = processor.parse({
@@ -1016,21 +1000,9 @@ async function ResponseTabs({ endpoint, operation, ctx: { renderer, generateType
1016
1000
  }
1017
1001
 
1018
1002
  async function CodeBlock({ code, lang, options, ...rest }) {
1019
- const html = await codeToHast(code, {
1003
+ const rendered = await highlight(code, {
1020
1004
  lang,
1021
- defaultColor: false,
1022
- themes: {
1023
- light: 'github-light',
1024
- dark: 'github-dark'
1025
- },
1026
- transformers: sharedTransformers,
1027
- ...options
1028
- });
1029
- const codeblock = toJsxRuntime(html, {
1030
- development: false,
1031
- jsx: jsx,
1032
- jsxs: jsxs,
1033
- Fragment: Fragment$1,
1005
+ ...options,
1034
1006
  components: {
1035
1007
  pre: (props)=>/*#__PURE__*/ jsx(Base.Pre, {
1036
1008
  ...props,
@@ -1040,7 +1012,7 @@ async function CodeBlock({ code, lang, options, ...rest }) {
1040
1012
  });
1041
1013
  return /*#__PURE__*/ jsx(Base.CodeBlock, {
1042
1014
  className: "my-0",
1043
- children: codeblock
1015
+ children: rendered
1044
1016
  });
1045
1017
  }
1046
1018
 
@@ -1143,14 +1115,14 @@ function createOpenAPI(options = {}) {
1143
1115
  };
1144
1116
  }
1145
1117
 
1146
- cva('rounded border px-1.5 py-1 text-xs font-medium leading-[12px]', {
1118
+ cva('rounded-xl border px-1.5 py-1 text-xs font-medium leading-[12px]', {
1147
1119
  variants: {
1148
1120
  color: {
1149
- green: 'border-green-400/50 bg-green-400/20 text-green-600 dark:text-green-400',
1150
- yellow: 'border-yellow-400/50 bg-yellow-400/20 text-yellow-600 dark:text-yellow-400',
1151
- red: 'border-red-400/50 bg-red-400/20 text-red-600 dark:text-red-400',
1152
- blue: 'border-blue-400/50 bg-blue-400/20 text-blue-600 dark:text-blue-400',
1153
- orange: 'border-orange-400/50 bg-orange-400/20 text-orange-600 dark:text-orange-400'
1121
+ green: 'bg-green-400/20 text-green-600 dark:text-green-400',
1122
+ yellow: 'bg-yellow-400/20 text-yellow-600 dark:text-yellow-400',
1123
+ red: 'bg-red-400/20 text-red-600 dark:text-red-400',
1124
+ blue: 'bg-blue-400/20 text-blue-600 dark:text-blue-400',
1125
+ orange: 'bg-orange-400/20 text-orange-600 dark:text-orange-400'
1154
1126
  }
1155
1127
  }
1156
1128
  });
@@ -219,21 +219,6 @@ const Trash2 = createLucideIcon("Trash2", [
219
219
  ]
220
220
  ]);
221
221
 
222
- const sharedTransformers = [
223
- {
224
- name: 'fumadocs:pre-process',
225
- line (hast) {
226
- if (hast.children.length === 0) {
227
- // Keep the empty lines when using grid layout
228
- hast.children.push({
229
- type: 'text',
230
- value: ' '
231
- });
232
- }
233
- }
234
- }
235
- ];
236
-
237
222
  const ApiContext = /*#__PURE__*/ createContext(undefined);
238
223
  function useApiContext() {
239
224
  const ctx = useContext(ApiContext);
@@ -252,19 +237,7 @@ function ApiProvider({ defaultBaseUrl, shikiOptions, children }) {
252
237
  value: useMemo(()=>({
253
238
  baseUrl,
254
239
  setBaseUrl,
255
- highlight: async (lang, code)=>{
256
- const { codeToHast } = await import('shiki/bundle/web');
257
- return codeToHast(code, {
258
- lang,
259
- themes: {
260
- light: 'github-light',
261
- dark: 'github-dark'
262
- },
263
- transformers: sharedTransformers,
264
- defaultColor: false,
265
- ...shikiOptions
266
- });
267
- }
240
+ shikiOptions
268
241
  }), [
269
242
  baseUrl,
270
243
  shikiOptions
@@ -280,7 +253,7 @@ function useSchemaContext() {
280
253
  return ctx;
281
254
  }
282
255
 
283
- const APIPlayground = dynamic(()=>import('./playground-client-CcBhYwDS.js').then((mod)=>mod.APIPlayground));
256
+ const APIPlayground = dynamic(()=>import('./playground-client-jizWhzv7.js').then((mod)=>mod.APIPlayground));
284
257
  function Root({ children, baseUrl, className, shikiOptions, ...props }) {
285
258
  return /*#__PURE__*/ jsx("div", {
286
259
  className: cn('flex flex-col gap-24 text-sm text-fd-muted-foreground', className),
@@ -307,9 +280,9 @@ function CopyRouteButton({ className, route, ...props }) {
307
280
  "aria-label": "Copy route path",
308
281
  ...props,
309
282
  children: checked ? /*#__PURE__*/ jsx(Check, {
310
- className: "size-3"
283
+ className: "size-full"
311
284
  }) : /*#__PURE__*/ jsx(Copy, {
312
- className: "size-3"
285
+ className: "size-full"
313
286
  })
314
287
  });
315
288
  }
@@ -233,7 +233,7 @@ declare function Root({ children, baseUrl, className, shikiOptions, ...props }:
233
233
  declare function APIInfo({ children, className, route, badgeClassname, method, ...props }: APIInfoProps & HTMLAttributes<HTMLDivElement> & {
234
234
  badgeClassname?: string;
235
235
  }): React.ReactElement;
236
- declare function API({ className, children, ...props }: HTMLAttributes<HTMLDivElement>): React.ReactElement;
236
+ declare function API({ children, ...props }: HTMLAttributes<HTMLDivElement>): React.ReactElement;
237
237
  declare function Property({ name, type, required, deprecated, children, }: PropertyProps): React.ReactElement;
238
238
  declare function APIExample(props: HTMLAttributes<HTMLDivElement>): React.ReactElement;
239
239
  declare function ObjectCollapsible(props: {
package/dist/ui/index.js CHANGED
@@ -3,17 +3,17 @@ import { cn } from 'fumadocs-ui/components/api';
3
3
  import { Fragment } from 'react';
4
4
  import { Accordions, Accordion } from 'fumadocs-ui/components/accordion';
5
5
  import { cva } from 'class-variance-authority';
6
- import { f as CopyRouteButton } from './client-client-ByT1LZmz.js';
7
- export { A as APIPlayground, R as Root, u as useSchemaContext } from './client-client-ByT1LZmz.js';
6
+ import { f as CopyRouteButton } from './client-client-mFPFBgXc.js';
7
+ export { A as APIPlayground, R as Root, u as useSchemaContext } from './client-client-mFPFBgXc.js';
8
8
 
9
- const badgeVariants = cva('rounded border px-1.5 py-1 text-xs font-medium leading-[12px]', {
9
+ const badgeVariants = cva('rounded-xl border px-1.5 py-1 text-xs font-medium leading-[12px]', {
10
10
  variants: {
11
11
  color: {
12
- green: 'border-green-400/50 bg-green-400/20 text-green-600 dark:text-green-400',
13
- yellow: 'border-yellow-400/50 bg-yellow-400/20 text-yellow-600 dark:text-yellow-400',
14
- red: 'border-red-400/50 bg-red-400/20 text-red-600 dark:text-red-400',
15
- blue: 'border-blue-400/50 bg-blue-400/20 text-blue-600 dark:text-blue-400',
16
- orange: 'border-orange-400/50 bg-orange-400/20 text-orange-600 dark:text-orange-400'
12
+ green: 'bg-green-400/20 text-green-600 dark:text-green-400',
13
+ yellow: 'bg-yellow-400/20 text-yellow-600 dark:text-yellow-400',
14
+ red: 'bg-red-400/20 text-red-600 dark:text-red-400',
15
+ blue: 'bg-blue-400/20 text-blue-600 dark:text-blue-400',
16
+ orange: 'bg-orange-400/20 text-orange-600 dark:text-orange-400'
17
17
  }
18
18
  }
19
19
  });
@@ -35,7 +35,7 @@ function getBadgeColor(method) {
35
35
  function Route({ route }) {
36
36
  const segments = route.split('/').filter((part)=>part.length > 0);
37
37
  return /*#__PURE__*/ jsx("div", {
38
- className: "flex flex-row flex-wrap items-center gap-1 text-sm",
38
+ className: "not-prose flex flex-row items-center gap-1 overflow-auto text-xs",
39
39
  children: segments.map((part, index)=>/*#__PURE__*/ jsxs(Fragment, {
40
40
  children: [
41
41
  /*#__PURE__*/ jsx("span", {
@@ -43,9 +43,9 @@ function Route({ route }) {
43
43
  children: "/"
44
44
  }),
45
45
  part.startsWith('{') && part.endsWith('}') ? /*#__PURE__*/ jsx("code", {
46
- className: "text-fd-primary",
46
+ className: "bg-fd-primary/10 text-fd-primary",
47
47
  children: part
48
- }) : /*#__PURE__*/ jsx("span", {
48
+ }) : /*#__PURE__*/ jsx("code", {
49
49
  className: "text-fd-foreground",
50
50
  children: part
51
51
  })
@@ -59,10 +59,7 @@ function APIInfo({ children, className, route, badgeClassname, method = 'GET', .
59
59
  ...props,
60
60
  children: [
61
61
  /*#__PURE__*/ jsxs("div", {
62
- className: cn('sticky top-[calc(var(--fd-api-info-top)+36px)] z-20 mb-4 flex flex-row items-center gap-2 rounded-lg border bg-fd-card px-3 py-2 md:top-[var(--fd-api-info-top)]'),
63
- style: {
64
- '--fd-api-info-top': 'calc(var(--fd-nav-height) + var(--fd-banner-height) + 4px)'
65
- },
62
+ className: "sticky top-[var(--fd-api-info-top)] z-[4] mb-4 flex flex-row items-center gap-1.5 border-b border-fd-foreground/10 bg-fd-card/50 px-4 py-1.5 shadow-lg backdrop-blur-lg max-lg:-mx-3 max-md:-mx-4 md:rounded-full md:border md:px-1.5",
66
63
  children: [
67
64
  /*#__PURE__*/ jsx("span", {
68
65
  className: cn(badgeVariants({
@@ -74,7 +71,7 @@ function APIInfo({ children, className, route, badgeClassname, method = 'GET', .
74
71
  route: route
75
72
  }),
76
73
  /*#__PURE__*/ jsx(CopyRouteButton, {
77
- className: "ms-auto size-6 p-1",
74
+ className: "ms-auto size-6 p-1.5",
78
75
  route: route
79
76
  })
80
77
  ]
@@ -86,10 +83,14 @@ function APIInfo({ children, className, route, badgeClassname, method = 'GET', .
86
83
  ]
87
84
  });
88
85
  }
89
- function API({ className, children, ...props }) {
86
+ function API({ children, ...props }) {
90
87
  return /*#__PURE__*/ jsx("div", {
91
- className: cn('flex flex-col gap-x-6 gap-y-4 xl:flex-row xl:items-start', className),
92
88
  ...props,
89
+ className: cn('flex flex-col gap-x-6 gap-y-4 max-lg:[--fd-toc-height:46px] max-md:[--fd-toc-height:36px] xl:flex-row xl:items-start', props.className),
90
+ style: {
91
+ '--fd-api-info-top': 'calc(var(--fd-nav-height) + var(--fd-banner-height) + var(--fd-toc-height, 0.5rem))',
92
+ ...props.style
93
+ },
93
94
  children: children
94
95
  });
95
96
  }
@@ -98,7 +99,7 @@ function Property({ name, type, required, deprecated, children }) {
98
99
  className: "mb-4 rounded-lg border bg-fd-card p-3 prose-no-margin",
99
100
  children: [
100
101
  /*#__PURE__*/ jsxs("h4", {
101
- className: "flex flex-row items-center gap-4",
102
+ className: "flex flex-row flex-wrap items-center gap-4",
102
103
  children: [
103
104
  /*#__PURE__*/ jsx("code", {
104
105
  children: name
@@ -129,10 +130,6 @@ function APIExample(props) {
129
130
  return /*#__PURE__*/ jsx("div", {
130
131
  ...props,
131
132
  className: cn('prose-no-margin md:sticky md:top-[var(--fd-api-info-top)] xl:w-[400px]', props.className),
132
- style: {
133
- '--fd-api-info-top': 'calc(var(--fd-nav-height) + var(--fd-banner-height) + 40px)',
134
- ...props.style
135
- },
136
133
  children: props.children
137
134
  });
138
135
  }
@@ -1,17 +1,17 @@
1
1
  'use client';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import * as React from 'react';
4
- import { forwardRef, useId, createContext, useContext, useState, useCallback, useEffect, Fragment as Fragment$1, useRef, useMemo } from 'react';
4
+ import { forwardRef, useId, createContext, useContext, useState, useCallback, useRef, useEffect, useMemo } from 'react';
5
5
  import { FormProvider, Controller, useFormContext, useFieldArray, useForm, useWatch } from 'react-hook-form';
6
6
  import { Accordions, Accordion } from 'fumadocs-ui/components/accordion';
7
7
  import { cn, buttonVariants } from 'fumadocs-ui/components/api';
8
- import { C as CircleCheck, a as CircleX, b as ChevronDown, c as ChevronUp, d as Check, u as useSchemaContext, T as Trash2, P as Plus, e as useApiContext, S as SchemaContext } from './client-client-ByT1LZmz.js';
8
+ import { C as CircleCheck, a as CircleX, b as ChevronDown, c as ChevronUp, d as Check, u as useSchemaContext, T as Trash2, P as Plus, e as useApiContext, S as SchemaContext } from './client-client-mFPFBgXc.js';
9
9
  import { Slot } from '@radix-ui/react-slot';
10
10
  import { cva } from 'class-variance-authority';
11
11
  import { useOnChange } from 'fumadocs-core/utils/use-on-change';
12
12
  import * as SelectPrimitive from '@radix-ui/react-select';
13
13
  import * as Base from 'fumadocs-ui/components/codeblock';
14
- import { toJsxRuntime } from 'hast-util-to-jsx-runtime';
14
+ import { useShiki } from 'fumadocs-core/utils/use-shiki';
15
15
 
16
16
  const Form = FormProvider;
17
17
  const FormFieldContext = /*#__PURE__*/ createContext({
@@ -811,33 +811,18 @@ function ArrayInput({ fieldName, field, ...props }) {
811
811
  }
812
812
 
813
813
  function CodeBlock({ code, lang = 'json' }) {
814
- const { highlight } = useApiContext();
815
- const [rendered, setRendered] = useState(/*#__PURE__*/ jsx(Base.Pre, {
816
- className: "max-h-[288px]",
817
- children: code
818
- }));
819
- useEffect(()=>{
820
- void highlight(lang, code).then((res)=>{
821
- const output = toJsxRuntime(res, {
822
- jsx,
823
- jsxs,
824
- development: false,
825
- Fragment: Fragment$1,
826
- components: {
827
- pre: (props)=>/*#__PURE__*/ jsx(Base.Pre, {
828
- className: "max-h-[288px]",
829
- ...props,
830
- children: props.children
831
- })
832
- }
833
- });
834
- setRendered(output);
835
- });
836
- }, [
837
- code,
838
- highlight,
839
- lang
840
- ]);
814
+ const { shikiOptions } = useApiContext();
815
+ const rendered = useShiki(code, {
816
+ lang,
817
+ ...shikiOptions,
818
+ components: {
819
+ pre: (props)=>/*#__PURE__*/ jsx(Base.Pre, {
820
+ className: "max-h-[288px]",
821
+ ...props,
822
+ children: props.children
823
+ })
824
+ }
825
+ });
841
826
  return /*#__PURE__*/ jsx(Base.CodeBlock, {
842
827
  className: "my-0",
843
828
  children: rendered
@@ -923,7 +908,7 @@ function APIPlayground({ route, method = 'GET', bodyType, authorization, path =
923
908
  schemas
924
909
  ]),
925
910
  children: /*#__PURE__*/ jsxs("form", {
926
- className: "not-prose flex flex-col gap-5 rounded-lg border bg-fd-card p-3",
911
+ className: "not-prose flex flex-col gap-5 rounded-xl border bg-fd-card p-3",
927
912
  onSubmit: onSubmit,
928
913
  children: [
929
914
  /*#__PURE__*/ jsxs("div", {
@@ -935,7 +920,7 @@ function APIPlayground({ route, method = 'GET', bodyType, authorization, path =
935
920
  /*#__PURE__*/ jsx("button", {
936
921
  type: "submit",
937
922
  className: cn(buttonVariants({
938
- color: 'secondary'
923
+ color: 'outline'
939
924
  })),
940
925
  disabled: testQuery.isLoading,
941
926
  children: "Send"
@@ -945,7 +930,7 @@ function APIPlayground({ route, method = 'GET', bodyType, authorization, path =
945
930
  authorization ? renderCustomField('authorization', authorization, fields.auth) : null,
946
931
  /*#__PURE__*/ jsxs(Accordions, {
947
932
  type: "multiple",
948
- className: cn('-m-3 border-0 text-sm', path.length === 0 && query.length === 0 && header.length === 0 && !body && 'hidden'),
933
+ className: cn('-m-3 border-0 bg-transparent text-sm', path.length === 0 && query.length === 0 && header.length === 0 && !body && 'hidden'),
949
934
  children: [
950
935
  path.length > 0 ? /*#__PURE__*/ jsx(Accordion, {
951
936
  title: "Path",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-openapi",
3
- "version": "5.5.3",
3
+ "version": "5.5.5",
4
4
  "description": "Generate MDX docs for your OpenAPI spec",
5
5
  "keywords": [
6
6
  "NextJs",
@@ -44,16 +44,16 @@
44
44
  "react-hook-form": "^7.53.1",
45
45
  "remark": "^15.0.1",
46
46
  "remark-rehype": "^11.1.1",
47
- "shiki": "^1.22.0",
48
- "fumadocs-core": "14.0.2",
49
- "fumadocs-ui": "14.0.2"
47
+ "shiki": "^1.22.2",
48
+ "fumadocs-core": "14.1.1",
49
+ "fumadocs-ui": "14.1.1"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@types/js-yaml": "^4.0.9",
53
- "@types/node": "22.7.8",
53
+ "@types/node": "22.8.1",
54
54
  "@types/openapi-sampler": "^1.0.3",
55
- "@types/react": "^18.3.11",
56
- "bunchee": "^5.5.1",
55
+ "@types/react": "^18.3.12",
56
+ "bunchee": "^5.6.0",
57
57
  "lucide-react": "^0.453.0",
58
58
  "next": "15.0.1",
59
59
  "openapi-types": "^12.1.3",