fumadocs-openapi 9.0.16 → 9.0.18

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.
@@ -67,6 +67,12 @@ interface BaseConfig extends GenerateOptions {
67
67
  * Output directory
68
68
  */
69
69
  output: string;
70
+ /**
71
+ * Custom function to convert names into file names.
72
+ *
73
+ * By default, it only escapes whitespaces and upper case (English) characters
74
+ */
75
+ slugify?: (name: string) => string;
70
76
  }
71
77
  export declare function generateFiles(options: Config): Promise<void>;
72
78
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"generate-file.d.ts","sourceRoot":"","sources":["../src/generate-file.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,kBAAkB,EAEvB,KAAK,iBAAiB,EAEvB,MAAM,YAAY,CAAC;AACpB,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAElC,UAAU,kBAAkB;IAC1B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,eAAgB,SAAQ,UAAU;IAC1C;;OAEG;IACH,GAAG,CAAC,EAAE,WAAW,CAAC;IAElB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC;IAEnC;;OAEG;IACH,IAAI,CAAC,EACD,CAAC,CACC,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,iBAAiB,CAAC,UAAU,CAAC,KACpC,MAAM,CAAC,GACZ,QAAQ,CAAC;CACd;AAED,UAAU,SAAU,SAAQ,UAAU;IACpC;;OAEG;IACH,GAAG,EAAE,KAAK,CAAC;IAEX;;OAEG;IACH,IAAI,CAAC,EACD,CAAC,CACC,MAAM,EAAE,iBAAiB,EACzB,QAAQ,EAAE,iBAAiB,CAAC,UAAU,CAAC,KACpC,MAAM,CAAC,GACZ,QAAQ,CAAC;CACd;AAED,UAAU,UAAW,SAAQ,UAAU;IACrC;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,IAAI,CAAC,EACD,CAAC,CACC,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,iBAAiB,CAAC,UAAU,CAAC,KACpC,MAAM,CAAC,GACZ,QAAQ,CAAC;CACd;AAED,MAAM,MAAM,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,eAAe,CAAC;AAE9D,UAAU,QAAQ;IAChB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACzB;AAED,UAAU,UAAW,SAAQ,eAAe;IAC1C;;OAEG;IACH,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAEzB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BlE"}
1
+ {"version":3,"file":"generate-file.d.ts","sourceRoot":"","sources":["../src/generate-file.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,kBAAkB,EAEvB,KAAK,iBAAiB,EAEvB,MAAM,YAAY,CAAC;AACpB,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAElC,UAAU,kBAAkB;IAC1B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,eAAgB,SAAQ,UAAU;IAC1C;;OAEG;IACH,GAAG,CAAC,EAAE,WAAW,CAAC;IAElB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC;IAEnC;;OAEG;IACH,IAAI,CAAC,EACD,CAAC,CACC,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,iBAAiB,CAAC,UAAU,CAAC,KACpC,MAAM,CAAC,GACZ,QAAQ,CAAC;CACd;AAED,UAAU,SAAU,SAAQ,UAAU;IACpC;;OAEG;IACH,GAAG,EAAE,KAAK,CAAC;IAEX;;OAEG;IACH,IAAI,CAAC,EACD,CAAC,CACC,MAAM,EAAE,iBAAiB,EACzB,QAAQ,EAAE,iBAAiB,CAAC,UAAU,CAAC,KACpC,MAAM,CAAC,GACZ,QAAQ,CAAC;CACd;AAED,UAAU,UAAW,SAAQ,UAAU;IACrC;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,IAAI,CAAC,EACD,CAAC,CACC,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,iBAAiB,CAAC,UAAU,CAAC,KACpC,MAAM,CAAC,GACZ,QAAQ,CAAC;CACd;AAED,MAAM,MAAM,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,eAAe,CAAC;AAE9D,UAAU,QAAQ;IAChB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACzB;AAED,UAAU,UAAW,SAAQ,eAAe;IAC1C;;OAEG;IACH,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAEzB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACpC;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BlE"}
@@ -26,14 +26,14 @@ export async function generateFiles(options) {
26
26
  await Promise.all(resolvedInputs.map((input) => generateFromDocument(input, options)));
27
27
  }
28
28
  async function generateFromDocument(pathOrUrl, options) {
29
- const { output, cwd = process.cwd() } = options;
29
+ const { output, cwd = process.cwd(), slugify = defaultSlugify } = options;
30
30
  let nameFn;
31
31
  if (!options.name || typeof options.name !== 'function') {
32
32
  const { algorithm = 'v2' } = options.name ?? {};
33
33
  nameFn = (output, document) => {
34
34
  if (options.per === 'tag') {
35
35
  const result = output;
36
- return getFilename(result.tag);
36
+ return slugify(result.tag);
37
37
  }
38
38
  if (options.per === 'file') {
39
39
  return isUrl(pathOrUrl)
@@ -52,7 +52,7 @@ async function generateFromDocument(pathOrUrl, options) {
52
52
  if (algorithm === 'v2' && hook.operationId) {
53
53
  return hook.operationId;
54
54
  }
55
- return getFilename(result.item.name);
55
+ return slugify(result.item.name);
56
56
  };
57
57
  }
58
58
  else {
@@ -81,7 +81,7 @@ async function generateFromDocument(pathOrUrl, options) {
81
81
  console.warn('When `groupBy` is set to `tag`, make sure a `tags` is defined for every operation schema.');
82
82
  tags = ['unknown'];
83
83
  }
84
- return tags.map((tag) => path.join(getFilename(tag), `${file}.mdx`));
84
+ return tags.map((tag) => path.join(slugify(tag), `${file}.mdx`));
85
85
  }
86
86
  return [`${file}.mdx`];
87
87
  }
@@ -142,7 +142,7 @@ function getOutputPathFromRoute(path) {
142
142
  })
143
143
  .join('/') ?? '');
144
144
  }
145
- function getFilename(s) {
145
+ function defaultSlugify(s) {
146
146
  return s.replace(/\s+/g, '-').toLowerCase();
147
147
  }
148
148
  async function dereference(pathOrDocument, options) {
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/render/renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAiBtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGtE,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IAEd,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IAEb,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,SAAS,CAAC;QACxB,KAAK,EAAE,MAAM,CAAC;KACf,EAAE,CAAC;CACL;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,aAAa,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAC/B,GAAG,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAC5C,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACrC,UAAU,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAEnD,SAAS,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC;IACzC,QAAQ,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IACvC,mBAAmB,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACjD,QAAQ,EAAE,aAAa,CAAC;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAClE,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACrC,aAAa,EAAE,aAAa,CAAC;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAC7E,YAAY,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAE/C;;OAEG;IACH,iBAAiB,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAC;IACzD,QAAQ,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IACvC,aAAa,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;CAClD;AAED,wBAAgB,aAAa,IAAI,QAAQ,CA4CxC"}
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/render/renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAiBtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAStE,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IAEd,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IAEb,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,SAAS,CAAC;QACxB,KAAK,EAAE,MAAM,CAAC;KACf,EAAE,CAAC;CACL;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,aAAa,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAC/B,GAAG,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAC5C,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACrC,UAAU,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAEnD,SAAS,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC;IACzC,QAAQ,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IACvC,mBAAmB,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACjD,QAAQ,EAAE,aAAa,CAAC;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAClE,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACrC,aAAa,EAAE,aAAa,CAAC;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAC7E,YAAY,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAE/C;;OAEG;IACH,iBAAiB,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAC;IACzD,QAAQ,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IACvC,aAAa,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;CAClD;AAED,wBAAgB,aAAa,IAAI,QAAQ,CA0DxC"}
@@ -4,6 +4,7 @@ import { AccordionContent, AccordionHeader, AccordionItem, Accordions, Accordion
4
4
  import { API, APIExample, APIInfo, ObjectCollapsible, Property, Root, } from '../ui/index.js';
5
5
  import { APIPlayground } from '../playground/index.js';
6
6
  import { CodeExampleSelector } from '../ui/lazy.js';
7
+ import { CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, } from 'fumadocs-ui/components/codeblock';
7
8
  export function createRenders() {
8
9
  return {
9
10
  Root,
@@ -16,9 +17,9 @@ export function createRenders() {
16
17
  ResponseType: (props) => (_jsxs(AccordionItem, { value: props.label, children: [_jsx(AccordionHeader, { children: _jsx(AccordionTrigger, { children: props.label }) }), _jsx(AccordionContent, { className: "prose-no-margin", children: props.children })] })),
17
18
  Property,
18
19
  ObjectCollapsible,
19
- Requests: (props) => (_jsx(Tabs, { groupId: "fumadocs_openapi_requests", ...props })),
20
+ Requests: ({ items, children }) => (_jsxs(CodeBlockTabs, { groupId: "fumadocs_openapi_requests", defaultValue: items[0], children: [_jsx(CodeBlockTabsList, { children: items.map((item) => (_jsx(CodeBlockTabsTrigger, { value: item, children: item }, item))) }), children] })),
20
21
  CodeExampleSelector,
21
- Request: (props) => _jsx(Tab, { value: props.name, children: props.children }),
22
+ Request: (props) => (_jsx(CodeBlockTab, { value: props.name, children: props.children })),
22
23
  APIPlayground,
23
24
  };
24
25
  }
@@ -1,7 +1,7 @@
1
1
  import { type ReactNode } from 'react';
2
2
  import type { ResolvedSchema } from '../utils/schema.js';
3
3
  import type { RenderContext } from '../types.js';
4
- export declare function Schema({ name, schema, required, readOnly, writeOnly, as, ctx: { renderer }, }: {
4
+ export declare function Schema({ name, schema, required, readOnly, writeOnly, as, ctx: renderContext, }: {
5
5
  name: string;
6
6
  required?: boolean;
7
7
  schema: ResolvedSchema;
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/render/schema.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAe7C,wBAAgB,MAAM,CAAC,EACrB,IAAI,EACJ,MAAM,EACN,QAAgB,EAChB,QAAgB,EAChB,SAAiB,EACjB,EAAe,EACf,GAAG,EAAE,EAAE,QAAQ,EAAE,GAClB,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,cAAc,CAAC;IACvB,EAAE,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAEzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,GAAG,EAAE,aAAa,CAAC;CACpB,GAAG,SAAS,CAoTZ"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/render/schema.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAe7C,wBAAgB,MAAM,CAAC,EACrB,IAAI,EACJ,MAAM,EACN,QAAgB,EAChB,QAAgB,EAChB,SAAiB,EACjB,EAAe,EACf,GAAG,EAAE,aAAa,GACnB,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,cAAc,CAAC;IACvB,EAAE,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAEzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,GAAG,EAAE,aAAa,CAAC;CACpB,GAAG,SAAS,CAoTZ"}
@@ -4,7 +4,8 @@ import { combineSchema } from '../utils/combine-schema.js';
4
4
  import { Markdown } from './markdown.js';
5
5
  import { schemaToString } from '../utils/schema-to-string.js';
6
6
  import { Tabs, TabsContent, TabsList, TabsTrigger, } from 'fumadocs-ui/components/tabs';
7
- export function Schema({ name, schema, required = false, readOnly = false, writeOnly = false, as = 'property', ctx: { renderer }, }) {
7
+ export function Schema({ name, schema, required = false, readOnly = false, writeOnly = false, as = 'property', ctx: renderContext, }) {
8
+ const { renderer } = renderContext;
8
9
  function propertyBody(schema, renderPrimitive, ctx) {
9
10
  if (Array.isArray(schema.type)) {
10
11
  const items = schema.type.flatMap((type) => {
@@ -20,7 +21,7 @@ export function Schema({ name, schema, required = false, readOnly = false, write
20
21
  return;
21
22
  if (items.length === 1)
22
23
  return propertyBody(items[0], renderPrimitive, ctx);
23
- return (_jsxs(Tabs, { defaultValue: items[0].type, children: [_jsx(TabsList, { children: items.map((item) => (_jsx(TabsTrigger, { value: item.type, children: schemaToString(item) }, item.type))) }), items.map((item) => (_jsxs(TabsContent, { value: item.type, children: [item.description && _jsx(Markdown, { text: item.description }), propertyInfo(item), renderPrimitive(item, ctx)] }, item.type)))] }));
24
+ return (_jsxs(Tabs, { defaultValue: items[0].type, children: [_jsx(TabsList, { children: items.map((item) => (_jsx(TabsTrigger, { value: item.type, children: schemaToString(item, renderContext.schema) }, item.type))) }), items.map((item) => (_jsxs(TabsContent, { value: item.type, children: [item.description && _jsx(Markdown, { text: item.description }), propertyInfo(item), renderPrimitive(item, ctx)] }, item.type)))] }));
24
25
  }
25
26
  if (schema.oneOf) {
26
27
  const oneOf = schema.oneOf.filter((item) => isComplexType(item));
@@ -29,7 +30,7 @@ export function Schema({ name, schema, required = false, readOnly = false, write
29
30
  if (oneOf.length === 1) {
30
31
  return propertyBody(oneOf[0], renderPrimitive, ctx);
31
32
  }
32
- return (_jsxs(Tabs, { defaultValue: "0", children: [_jsx(TabsList, { children: oneOf.map((item, i) => (_jsx(TabsTrigger, { value: i.toString(), children: schemaToString(item) }, i))) }), oneOf.map((item, i) => (_jsxs(TabsContent, { value: i.toString(), children: [item.description && _jsx(Markdown, { text: item.description }), propertyInfo(item), propertyBody(item, (child, ctx) => primitiveBody(child, ctx, false, true), ctx)] }, i)))] }));
33
+ return (_jsxs(Tabs, { defaultValue: "0", children: [_jsx(TabsList, { children: oneOf.map((item, i) => (_jsx(TabsTrigger, { value: i.toString(), children: schemaToString(item, renderContext.schema) }, i))) }), oneOf.map((item, i) => (_jsxs(TabsContent, { value: i.toString(), children: [item.description && _jsx(Markdown, { text: item.description }), propertyInfo(item), propertyBody(item, (child, ctx) => primitiveBody(child, ctx, false, true), ctx)] }, i)))] }));
33
34
  }
34
35
  const of = schema.allOf ?? schema.anyOf;
35
36
  if (of) {
@@ -45,7 +46,7 @@ export function Schema({ name, schema, required = false, readOnly = false, write
45
46
  }
46
47
  function propertyInfo(schema) {
47
48
  const fields = [];
48
- if (schema.default) {
49
+ if (schema.default !== undefined) {
49
50
  fields.push({
50
51
  key: 'Default',
51
52
  value: JSON.stringify(schema.default),
@@ -122,12 +123,12 @@ export function Schema({ name, schema, required = false, readOnly = false, write
122
123
  }
123
124
  if (schema.type === 'array') {
124
125
  const items = schema.items;
125
- if (!items || !isComplexType(items) || ctx.stack.has(items))
126
+ if (!items || typeof items === 'boolean' || ctx.stack.has(items))
126
127
  return;
127
- return (_jsxs(_Fragment, { children: [items.description && (_jsx(Markdown, { text: 'Item: ' + items.description })), _jsx(renderer.ObjectCollapsible, { name: "Array Item", children: propertyBody(items, (child, ctx) => primitiveBody(child, ctx, false, true), {
128
- ...ctx,
129
- stack: ctx.stack.next(schema),
130
- }) })] }));
128
+ return (_jsxs(renderer.ObjectCollapsible, { name: "Array Item", children: [_jsxs("div", { className: "text-sm border-t p-3 border-x prose-no-margin bg-fd-card last:rounded-b-xl first:rounded-tr-xl last:border-b empty:hidden", children: [_jsx(Markdown, { text: items.description ?? 'No Description' }), propertyInfo(items)] }), propertyBody(items, (child, ctx) => primitiveBody(child, ctx, false, true), {
129
+ ...ctx,
130
+ stack: ctx.stack.next(schema),
131
+ })] }));
131
132
  }
132
133
  }
133
134
  function property(key, schema, ctx, props) {
@@ -139,7 +140,7 @@ export function Schema({ name, schema, required = false, readOnly = false, write
139
140
  }
140
141
  if ((schema.readOnly && !readOnly) || (schema.writeOnly && !writeOnly))
141
142
  return;
142
- return (_jsxs(renderer.Property, { name: key, type: schemaToString(schema), deprecated: schema.deprecated, ...props, children: [schema.description && _jsx(Markdown, { text: schema.description }), propertyInfo(schema), propertyBody(schema, (child, ctx) => primitiveBody(child, ctx, true, true), ctx)] }));
143
+ return (_jsxs(renderer.Property, { name: key, type: schemaToString(schema, renderContext.schema), deprecated: schema.deprecated, ...props, children: [schema.description && _jsx(Markdown, { text: schema.description }), propertyInfo(schema), propertyBody(schema, (child, ctx) => primitiveBody(child, ctx, true, true), ctx)] }));
143
144
  }
144
145
  const context = {
145
146
  stack: schemaStack(),
@@ -189,23 +190,21 @@ function isComplexType(schema) {
189
190
  if (arr && arr.some(isComplexType))
190
191
  return true;
191
192
  return (schema.type === 'object' ||
192
- (schema.type === 'array' &&
193
- schema.items != null &&
194
- isComplexType(schema.items)));
193
+ (schema.type === 'array' && schema.items != null));
195
194
  }
196
195
  function getRange(value, min, exclusiveMin, max, exclusiveMax) {
197
196
  const out = [];
198
- if (min) {
197
+ if (min !== undefined) {
199
198
  out.push(`${min} <=`);
200
199
  }
201
- else if (exclusiveMin) {
200
+ else if (exclusiveMin !== undefined) {
202
201
  out.push(`${exclusiveMin} <`);
203
202
  }
204
203
  out.push(value);
205
- if (max) {
204
+ if (max !== undefined) {
206
205
  out.push(`<= ${max}`);
207
206
  }
208
- else if (exclusiveMax) {
207
+ else if (exclusiveMax !== undefined) {
209
208
  out.push(`< ${exclusiveMax}`);
210
209
  }
211
210
  if (out.length > 1)
@@ -1 +1 @@
1
- {"version":3,"file":"accordion.d.ts","sourceRoot":"","sources":["../../../src/ui/components/accordion.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,SAAS,MAAM,2BAA2B,CAAC;AAEvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C,wBAAgB,UAAU,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,SAAS,CAAC,IAAI,CAAC,2CAUtE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,SAAS,CAAC,IAAI,CAAC,2CAMzE;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,cAAc,CAAC,OAAO,SAAS,CAAC,OAAO,CAAC,2CAahD;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,cAAc,CAAC,OAAO,SAAS,CAAC,MAAM,CAAC,2CAa/C;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,cAAc,CAAC,OAAO,SAAS,CAAC,OAAO,CAAC,2CAchD"}
1
+ {"version":3,"file":"accordion.d.ts","sourceRoot":"","sources":["../../../src/ui/components/accordion.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,SAAS,MAAM,2BAA2B,CAAC;AAEvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C,wBAAgB,UAAU,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,SAAS,CAAC,IAAI,CAAC,2CAOtE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,SAAS,CAAC,IAAI,CAAC,2CAMzE;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,cAAc,CAAC,OAAO,SAAS,CAAC,OAAO,CAAC,2CAahD;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,cAAc,CAAC,OAAO,SAAS,CAAC,MAAM,CAAC,2CAa/C;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,cAAc,CAAC,OAAO,SAAS,CAAC,OAAO,CAAC,2CAchD"}
@@ -4,7 +4,7 @@ import * as Primitive from '@radix-ui/react-accordion';
4
4
  import { ChevronRight } from '../../icons.js';
5
5
  import { cn } from 'fumadocs-ui/utils/cn';
6
6
  export function Accordions(props) {
7
- return (_jsx(Primitive.Root, { ...props, className: cn('divide-y divide-fd-border overflow-hidden', props.className) }));
7
+ return (_jsx(Primitive.Root, { ...props, className: cn('divide-y divide-fd-border', props.className) }));
8
8
  }
9
9
  export function AccordionItem(props) {
10
10
  return (_jsx(Primitive.Item, { ...props, className: cn('scroll-m-20', props.className), children: props.children }));
@@ -1 +1 @@
1
- {"version":3,"file":"get-typescript-schema.d.ts","sourceRoot":"","sources":["../../src/utils/get-typescript-schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,cAAc,GAC7B,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAS7B"}
1
+ {"version":3,"file":"get-typescript-schema.d.ts","sourceRoot":"","sources":["../../src/utils/get-typescript-schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,cAAc,GAC7B,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAa7B"}
@@ -1,11 +1,16 @@
1
1
  import { compile } from '@fumari/json-schema-to-typescript';
2
2
  export async function getTypescriptSchema(schema, dereferenceMap) {
3
- const cloned = structuredClone({ schema, dereferenceMap });
4
- return compile(cloned.schema, 'Response', {
5
- $refOptions: false,
6
- schemaToId: cloned.dereferenceMap,
7
- bannerComment: '',
8
- additionalProperties: false,
9
- enableConstEnums: false,
10
- });
3
+ try {
4
+ const cloned = structuredClone({ schema, dereferenceMap });
5
+ return await compile(cloned.schema, 'Response', {
6
+ $refOptions: false,
7
+ schemaToId: cloned.dereferenceMap,
8
+ bannerComment: '',
9
+ additionalProperties: false,
10
+ enableConstEnums: false,
11
+ });
12
+ }
13
+ catch (e) {
14
+ console.warn('Failed to generate typescript schema:', e);
15
+ }
11
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"process-document.d.ts","sourceRoot":"","sources":["../../src/utils/process-document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAK5D,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,WAAW,CAAC,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC;AAE/E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,UAAU,EAAE,QAAQ,CAAC;CACtB,CAAC;AAIF;;GAEG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,aAAa,EACpB,YAAY,UAAQ,GACnB,OAAO,CAAC,iBAAiB,CAAC,CAoC5B"}
1
+ {"version":3,"file":"process-document.d.ts","sourceRoot":"","sources":["../../src/utils/process-document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAI5D,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,WAAW,CAAC,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC;AAE/E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,UAAU,EAAE,QAAQ,CAAC;CACtB,CAAC;AAIF;;GAEG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,aAAa,EACpB,YAAY,UAAQ,GACnB,OAAO,CAAC,iBAAiB,CAAC,CA+B5B"}
@@ -1,6 +1,5 @@
1
- import { dereference, load, upgrade } from '@scalar/openapi-parser';
2
- import { fetchUrls } from '@scalar/openapi-parser/plugins/fetch-urls';
3
- import { readFiles } from '@scalar/openapi-parser/plugins/read-files';
1
+ import { bundle, dereference, upgrade } from '@scalar/openapi-parser';
2
+ import { fetchUrls, readFiles } from '@scalar/openapi-parser/plugins';
4
3
  const cache = new Map();
5
4
  /**
6
5
  * process & reference input document to a Fumadocs OpenAPI compatible format
@@ -10,15 +9,13 @@ export async function processDocument(input, disableCache = false) {
10
9
  if (cached)
11
10
  return cached;
12
11
  const dereferenceMap = new Map();
13
- const loaded = await load(input, {
14
- plugins: [readFiles(), fetchUrls()],
12
+ let document = await bundle(input, {
13
+ plugins: [fetchUrls(), readFiles()],
14
+ treeShake: false,
15
15
  });
16
- if (loaded.errors && loaded.errors.length > 0) {
17
- throw new Error(loaded.errors.map((err) => `${err.code}: ${err.message}`).join('\n'));
18
- }
19
16
  // upgrade
20
- loaded.specification = upgrade(loaded.specification).specification;
21
- const { schema: dereferenced } = await dereference(loaded.filesystem, {
17
+ document = upgrade(document).specification;
18
+ const { schema: dereferenced } = await dereference(document, {
22
19
  onDereference({ ref, schema }) {
23
20
  dereferenceMap.set(schema, ref);
24
21
  },
@@ -26,7 +23,7 @@ export async function processDocument(input, disableCache = false) {
26
23
  const processed = {
27
24
  document: dereferenced,
28
25
  dereferenceMap,
29
- downloaded: loaded.specification,
26
+ downloaded: document,
30
27
  };
31
28
  if (!disableCache && typeof input === 'string') {
32
29
  cache.set(input, processed);
@@ -1,3 +1,4 @@
1
1
  import { type ResolvedSchema } from '../utils/schema.js';
2
- export declare function schemaToString(schema: ResolvedSchema, isRoot?: boolean): string;
2
+ import type { ProcessedDocument } from '../utils/process-document.js';
3
+ export declare function schemaToString(value: ResolvedSchema, ctx?: ProcessedDocument): string;
3
4
  //# sourceMappingURL=schema-to-string.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema-to-string.d.ts","sourceRoot":"","sources":["../../src/utils/schema-to-string.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAExE,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,UAAO,GAAG,MAAM,CA0D5E"}
1
+ {"version":3,"file":"schema-to-string.d.ts","sourceRoot":"","sources":["../../src/utils/schema-to-string.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,wBAAgB,cAAc,CAC5B,KAAK,EAAE,cAAc,EACrB,GAAG,CAAC,EAAE,iBAAiB,GACtB,MAAM,CA8DR"}
@@ -1,50 +1,58 @@
1
- export function schemaToString(schema, isRoot = true) {
2
- if (schema === true)
3
- return 'any';
4
- else if (schema === false)
5
- return 'never';
6
- if (isNullable(schema) && isRoot) {
7
- const type = schemaToString(schema, false);
8
- // null if schema only contains `nullable`
9
- return type === 'unknown' ? 'null' : `${type} | null`;
1
+ export function schemaToString(value, ctx) {
2
+ function run(schema, isRoot) {
3
+ if (schema === true)
4
+ return 'any';
5
+ else if (schema === false)
6
+ return 'never';
7
+ if (isNullable(schema) && isRoot) {
8
+ const type = run(schema, false);
9
+ // null if schema only contains `nullable`
10
+ return type === 'unknown' ? 'null' : `${type} | null`;
11
+ }
12
+ if (schema.title)
13
+ return schema.title;
14
+ const referenceName = ctx?.dereferenceMap.get(schema);
15
+ if (referenceName)
16
+ return referenceName.split('/').at(-1);
17
+ if (Array.isArray(schema.type)) {
18
+ return schema.type
19
+ .map((type, _, originalType) => {
20
+ schema.type = type;
21
+ const str = run(schema, false);
22
+ schema.type = originalType;
23
+ return str;
24
+ })
25
+ .filter((v) => v !== 'unknown' && v !== 'null')
26
+ .join(' | ');
27
+ }
28
+ if (schema.type === 'array')
29
+ return `array<${schema.items ? run(schema.items, true) : 'unknown'}>`;
30
+ if (schema.oneOf) {
31
+ return schema.oneOf
32
+ .map((one) => run(one, false))
33
+ .filter((v) => v !== 'unknown' && v !== 'null')
34
+ .join(' | ');
35
+ }
36
+ const combinedOf = schema.anyOf ?? schema.allOf;
37
+ if (combinedOf) {
38
+ return combinedOf
39
+ .map((one) => run(one, false))
40
+ .filter((v) => v !== 'unknown' && v !== 'null')
41
+ .join(' & ');
42
+ }
43
+ if (schema.not)
44
+ return `not ${run(schema.not, false)}`;
45
+ if (schema.type === 'string' && schema.format === 'binary')
46
+ return 'file';
47
+ if (schema.type && Array.isArray(schema.type)) {
48
+ return schema.type.filter((v) => v !== 'null').join(' | ');
49
+ }
50
+ if (schema.type) {
51
+ return schema.type;
52
+ }
53
+ return 'unknown';
10
54
  }
11
- if (schema.title)
12
- return schema.title;
13
- if (Array.isArray(schema.type)) {
14
- return schema.type
15
- .map((type) => schemaToString({
16
- ...schema,
17
- type,
18
- }, false))
19
- .filter((v) => v !== 'unknown' && v !== 'null')
20
- .join(' | ');
21
- }
22
- if (schema.type === 'array')
23
- return `array<${schema.items ? schemaToString(schema.items) : 'unknown'}>`;
24
- if (schema.oneOf) {
25
- return schema.oneOf
26
- .map((one) => schemaToString(one, false))
27
- .filter((v) => v !== 'unknown' && v !== 'null')
28
- .join(' | ');
29
- }
30
- const combinedOf = schema.anyOf ?? schema.allOf;
31
- if (combinedOf) {
32
- return combinedOf
33
- .map((one) => schemaToString(one, false))
34
- .filter((v) => v !== 'unknown' && v !== 'null')
35
- .join(' & ');
36
- }
37
- if (schema.not)
38
- return `not ${schemaToString(schema.not, false)}`;
39
- if (schema.type === 'string' && schema.format === 'binary')
40
- return 'file';
41
- if (schema.type && Array.isArray(schema.type)) {
42
- return schema.type.filter((v) => v !== 'null').join(' | ');
43
- }
44
- if (schema.type) {
45
- return schema.type;
46
- }
47
- return 'unknown';
55
+ return run(value, true);
48
56
  }
49
57
  function isNullable(schema) {
50
58
  if (typeof schema === 'boolean')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-openapi",
3
- "version": "9.0.16",
3
+ "version": "9.0.18",
4
4
  "description": "Generate MDX docs for your OpenAPI spec",
5
5
  "keywords": [
6
6
  "NextJs",