fumadocs-openapi 5.2.1 → 5.3.0
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
|
@@ -5,10 +5,21 @@ import Slugger from 'github-slugger';
|
|
|
5
5
|
import { mkdir, writeFile } from 'node:fs/promises';
|
|
6
6
|
import fg from 'fast-glob';
|
|
7
7
|
|
|
8
|
-
function
|
|
8
|
+
function noRef(v) {
|
|
9
|
+
return v;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Summarize method endpoint information
|
|
14
|
+
*/ function createMethod(method, path, operation) {
|
|
9
15
|
return {
|
|
16
|
+
description: path.description,
|
|
17
|
+
summary: path.summary,
|
|
10
18
|
...operation,
|
|
11
|
-
parameters:
|
|
19
|
+
parameters: [
|
|
20
|
+
...noRef(operation.parameters ?? []),
|
|
21
|
+
...noRef(path.parameters ?? [])
|
|
22
|
+
],
|
|
12
23
|
method: method.toUpperCase()
|
|
13
24
|
};
|
|
14
25
|
}
|
|
@@ -25,13 +36,13 @@ const methodKeys = [
|
|
|
25
36
|
* Build the route information of tags, use `.get('all')` to get all entries
|
|
26
37
|
*/ function buildRoutes(document) {
|
|
27
38
|
const map = new Map();
|
|
28
|
-
for (const [path,
|
|
29
|
-
if (!
|
|
39
|
+
for (const [path, pathItem] of Object.entries(document.paths)){
|
|
40
|
+
if (!pathItem) continue;
|
|
30
41
|
const methodMap = new Map();
|
|
31
42
|
for (const methodKey of methodKeys){
|
|
32
|
-
const operation =
|
|
43
|
+
const operation = pathItem[methodKey];
|
|
33
44
|
if (!operation) continue;
|
|
34
|
-
const info = createMethod(methodKey, operation);
|
|
45
|
+
const info = createMethod(methodKey, pathItem, operation);
|
|
35
46
|
const tags = operation.tags ?? [];
|
|
36
47
|
for (const tag of [
|
|
37
48
|
...tags,
|
|
@@ -45,7 +56,7 @@ const methodKeys = [
|
|
|
45
56
|
for (const [tag, methods] of methodMap.entries()){
|
|
46
57
|
const list = map.get(tag) ?? [];
|
|
47
58
|
list.push({
|
|
48
|
-
...
|
|
59
|
+
...pathItem,
|
|
49
60
|
path,
|
|
50
61
|
methods
|
|
51
62
|
});
|
package/dist/server/index.js
CHANGED
|
@@ -134,7 +134,7 @@ function generateBody(method, schema) {
|
|
|
134
134
|
});
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
function getSampleRequest$
|
|
137
|
+
function getSampleRequest$3(endpoint) {
|
|
138
138
|
const s = [];
|
|
139
139
|
s.push(`curl -X ${endpoint.method} "${endpoint.url}"`);
|
|
140
140
|
for (const param of endpoint.parameters){
|
|
@@ -161,7 +161,7 @@ function getSampleRequest$2(endpoint) {
|
|
|
161
161
|
return s.flatMap((v, i)=>v.split('\n').map((line)=>i > 0 ? ` ${line}` : line).join('\n')).join(' \\\n');
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
function getSampleRequest$
|
|
164
|
+
function getSampleRequest$2(endpoint) {
|
|
165
165
|
const s = [];
|
|
166
166
|
const options = new Map();
|
|
167
167
|
const headers = new Map();
|
|
@@ -192,7 +192,7 @@ function getSampleRequest$1(endpoint) {
|
|
|
192
192
|
return s.join('\n\n');
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
function getSampleRequest(endpoint) {
|
|
195
|
+
function getSampleRequest$1(endpoint) {
|
|
196
196
|
const imports = [
|
|
197
197
|
'fmt',
|
|
198
198
|
'net/http',
|
|
@@ -244,6 +244,32 @@ ${Array.from(variables.entries()).map(([k, v])=>` ${k} := ${v}`).join('\n')}
|
|
|
244
244
|
}`;
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
+
function getSampleRequest(endpoint) {
|
|
248
|
+
const headers = new Map();
|
|
249
|
+
const cookies = new Map();
|
|
250
|
+
const variables = new Map();
|
|
251
|
+
for (const param of endpoint.parameters){
|
|
252
|
+
if (param.in === 'header') headers.set(param.name, param.sample);
|
|
253
|
+
if (param.in === 'cookie') cookies.set(param.name, param.sample);
|
|
254
|
+
}
|
|
255
|
+
if (headers.size > 0) {
|
|
256
|
+
variables.set('headers', JSON.stringify(Object.fromEntries(headers.entries()), null, 2));
|
|
257
|
+
}
|
|
258
|
+
if (cookies.size > 0) {
|
|
259
|
+
variables.set('cookies', JSON.stringify(Object.fromEntries(cookies.entries()), null, 2));
|
|
260
|
+
}
|
|
261
|
+
if (endpoint.body) {
|
|
262
|
+
variables.set(endpoint.body.mediaType === 'multipart/form-data' ? 'data' : 'json', JSON.stringify(endpoint.body.sample, null, 2));
|
|
263
|
+
}
|
|
264
|
+
return `import requests
|
|
265
|
+
|
|
266
|
+
url = ${JSON.stringify(endpoint.url)}
|
|
267
|
+
${Array.from(variables.entries()).map(([k, v])=>`${k} = ${v}`).join('\n')}
|
|
268
|
+
response = requests.request("${endpoint.method}", url${variables.size > 0 ? `, ${Array.from(variables.keys()).map((k)=>`${k}=${k}`).join(', ')}` : ''})
|
|
269
|
+
|
|
270
|
+
print(response.text)`;
|
|
271
|
+
}
|
|
272
|
+
|
|
247
273
|
async function getTypescriptSchema(endpoint, code) {
|
|
248
274
|
if (code in endpoint.responses) {
|
|
249
275
|
return compile(endpoint.responses[code].schema, 'Response', {
|
|
@@ -443,7 +469,6 @@ function heading(depth, child, ctx) {
|
|
|
443
469
|
}
|
|
444
470
|
|
|
445
471
|
const keys = {
|
|
446
|
-
example: 'Example',
|
|
447
472
|
default: 'Default',
|
|
448
473
|
minimum: 'Minimum',
|
|
449
474
|
maximum: 'Maximum',
|
|
@@ -461,17 +486,6 @@ function Schema({ name, schema, ctx }) {
|
|
|
461
486
|
const stack = ctx.stack ?? [];
|
|
462
487
|
const { renderer } = ctx.render;
|
|
463
488
|
const child = [];
|
|
464
|
-
function field(key, value) {
|
|
465
|
-
child.push(/*#__PURE__*/ jsxs("span", {
|
|
466
|
-
children: [
|
|
467
|
-
key,
|
|
468
|
-
": ",
|
|
469
|
-
/*#__PURE__*/ jsx("code", {
|
|
470
|
-
children: value
|
|
471
|
-
})
|
|
472
|
-
]
|
|
473
|
-
}, key));
|
|
474
|
-
}
|
|
475
489
|
// object type
|
|
476
490
|
if (isObject(schema) && parseObject) {
|
|
477
491
|
const { additionalProperties, properties } = schema;
|
|
@@ -510,15 +524,32 @@ function Schema({ name, schema, ctx }) {
|
|
|
510
524
|
if (schema.description) child.push(/*#__PURE__*/ jsx(Markdown, {
|
|
511
525
|
text: schema.description
|
|
512
526
|
}, "description"));
|
|
527
|
+
const fields = [];
|
|
513
528
|
for (const [key, value] of Object.entries(keys)){
|
|
514
529
|
if (key in schema) {
|
|
515
|
-
|
|
530
|
+
fields.push({
|
|
531
|
+
key: value,
|
|
532
|
+
value: JSON.stringify(schema[key])
|
|
533
|
+
});
|
|
516
534
|
}
|
|
517
535
|
}
|
|
518
|
-
// enum types
|
|
519
536
|
if (schema.enum) {
|
|
520
|
-
|
|
537
|
+
fields.push({
|
|
538
|
+
key: 'Value in',
|
|
539
|
+
value: schema.enum.map((value)=>JSON.stringify(value)).join(' | ')
|
|
540
|
+
});
|
|
521
541
|
}
|
|
542
|
+
if (fields.length > 0) child.push(/*#__PURE__*/ jsx("p", {
|
|
543
|
+
children: fields.map((field)=>/*#__PURE__*/ jsxs("span", {
|
|
544
|
+
children: [
|
|
545
|
+
field.key,
|
|
546
|
+
": ",
|
|
547
|
+
/*#__PURE__*/ jsx("code", {
|
|
548
|
+
children: field.value
|
|
549
|
+
})
|
|
550
|
+
]
|
|
551
|
+
}, field.key))
|
|
552
|
+
}, "fields"));
|
|
522
553
|
if (isObject(schema) && !parseObject) {
|
|
523
554
|
child.push(/*#__PURE__*/ jsx(renderer.ObjectCollapsible, {
|
|
524
555
|
name: "Attributes",
|
|
@@ -537,7 +568,7 @@ function Schema({ name, schema, ctx }) {
|
|
|
537
568
|
name: name,
|
|
538
569
|
children: /*#__PURE__*/ jsx(Schema, {
|
|
539
570
|
name: name,
|
|
540
|
-
schema: combineSchema(schema.allOf
|
|
571
|
+
schema: combineSchema(noRef(schema.allOf)),
|
|
541
572
|
ctx: {
|
|
542
573
|
...ctx,
|
|
543
574
|
parseObject: true,
|
|
@@ -578,6 +609,7 @@ function Schema({ name, schema, ctx }) {
|
|
|
578
609
|
return /*#__PURE__*/ jsx(renderer.Property, {
|
|
579
610
|
name: name,
|
|
580
611
|
type: getSchemaType(schema, ctx),
|
|
612
|
+
required: ctx.required,
|
|
581
613
|
deprecated: schema.deprecated,
|
|
582
614
|
children: child
|
|
583
615
|
});
|
|
@@ -601,7 +633,7 @@ function Schema({ name, schema, ctx }) {
|
|
|
601
633
|
Object.assign(result.additionalProperties, s.additionalProperties);
|
|
602
634
|
}
|
|
603
635
|
if (s.allOf) {
|
|
604
|
-
add(combineSchema(s.allOf
|
|
636
|
+
add(combineSchema(noRef(s.allOf)));
|
|
605
637
|
}
|
|
606
638
|
}
|
|
607
639
|
schema.forEach(add);
|
|
@@ -750,19 +782,24 @@ async function APIExample({ method, endpoint, ctx }) {
|
|
|
750
782
|
const samples = dedupe([
|
|
751
783
|
{
|
|
752
784
|
label: 'cURL',
|
|
753
|
-
source: getSampleRequest$
|
|
785
|
+
source: getSampleRequest$3(endpoint),
|
|
754
786
|
lang: 'bash'
|
|
755
787
|
},
|
|
756
788
|
{
|
|
757
789
|
label: 'JavaScript',
|
|
758
|
-
source: getSampleRequest$
|
|
790
|
+
source: getSampleRequest$2(endpoint),
|
|
759
791
|
lang: 'js'
|
|
760
792
|
},
|
|
761
793
|
{
|
|
762
794
|
label: 'Go',
|
|
763
|
-
source: getSampleRequest(endpoint),
|
|
795
|
+
source: getSampleRequest$1(endpoint),
|
|
764
796
|
lang: 'go'
|
|
765
797
|
},
|
|
798
|
+
{
|
|
799
|
+
label: 'Python',
|
|
800
|
+
source: getSampleRequest(endpoint),
|
|
801
|
+
lang: 'python'
|
|
802
|
+
},
|
|
766
803
|
...ctx.generateCodeSamples ? await ctx.generateCodeSamples(endpoint) : [],
|
|
767
804
|
...method['x-codeSamples'] ?? []
|
|
768
805
|
]).filter((item)=>item.source !== undefined);
|
|
@@ -931,14 +968,36 @@ async function ResponseTabs({ endpoint, operation, ctx: { renderer, generateType
|
|
|
931
968
|
});
|
|
932
969
|
}
|
|
933
970
|
|
|
934
|
-
|
|
971
|
+
/**
|
|
972
|
+
* Summarize method endpoint information
|
|
973
|
+
*/ function createMethod(method, path, operation) {
|
|
935
974
|
return {
|
|
975
|
+
description: path.description,
|
|
976
|
+
summary: path.summary,
|
|
936
977
|
...operation,
|
|
937
|
-
parameters:
|
|
978
|
+
parameters: [
|
|
979
|
+
...noRef(operation.parameters ?? []),
|
|
980
|
+
...noRef(path.parameters ?? [])
|
|
981
|
+
],
|
|
938
982
|
method: method.toUpperCase()
|
|
939
983
|
};
|
|
940
984
|
}
|
|
941
985
|
|
|
986
|
+
const sharedTransformers = [
|
|
987
|
+
{
|
|
988
|
+
name: 'fumadocs:pre-process',
|
|
989
|
+
line (hast) {
|
|
990
|
+
if (hast.children.length === 0) {
|
|
991
|
+
// Keep the empty lines when using grid layout
|
|
992
|
+
hast.children.push({
|
|
993
|
+
type: 'text',
|
|
994
|
+
value: ' '
|
|
995
|
+
});
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
];
|
|
1000
|
+
|
|
942
1001
|
const highlighter = await createHighlighter({
|
|
943
1002
|
themes: Object.values(bundledThemes),
|
|
944
1003
|
langs: Object.values(bundledLanguages)
|
|
@@ -951,7 +1010,8 @@ function CodeBlock({ code, lang, ...props }) {
|
|
|
951
1010
|
themes: {
|
|
952
1011
|
light: 'github-light',
|
|
953
1012
|
dark: 'github-dark'
|
|
954
|
-
}
|
|
1013
|
+
},
|
|
1014
|
+
transformers: sharedTransformers
|
|
955
1015
|
});
|
|
956
1016
|
}, [
|
|
957
1017
|
code,
|
|
@@ -1016,9 +1076,11 @@ async function APIPage(props) {
|
|
|
1016
1076
|
return /*#__PURE__*/ jsx(ctx.renderer.Root, {
|
|
1017
1077
|
baseUrl: ctx.baseUrl,
|
|
1018
1078
|
children: operations.map((item)=>{
|
|
1019
|
-
const
|
|
1079
|
+
const pathItem = document.paths[item.path];
|
|
1080
|
+
if (!pathItem) return null;
|
|
1081
|
+
const operation = pathItem[item.method];
|
|
1020
1082
|
if (!operation) return null;
|
|
1021
|
-
const method = createMethod(item.method, operation);
|
|
1083
|
+
const method = createMethod(item.method, pathItem, operation);
|
|
1022
1084
|
return /*#__PURE__*/ jsx(Operation, {
|
|
1023
1085
|
method: method,
|
|
1024
1086
|
path: item.path,
|
|
@@ -64,7 +64,7 @@ function useSchemaContext() {
|
|
|
64
64
|
return ctx;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
const APIPlayground = dynamic(()=>import('./playground-client-
|
|
67
|
+
const APIPlayground = dynamic(()=>import('./playground-client-CthJtmMz.js').then((mod)=>mod.APIPlayground));
|
|
68
68
|
function Root({ children, baseUrl, className, ...props }) {
|
|
69
69
|
return /*#__PURE__*/ jsx("div", {
|
|
70
70
|
className: cn('flex flex-col gap-24 text-sm text-fd-muted-foreground', className),
|
package/dist/ui/index.js
CHANGED
|
@@ -3,8 +3,8 @@ 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 { C as CopyRouteButton } from './client-client-
|
|
7
|
-
export { A as APIPlayground, R as Root, u as useSchemaContext } from './client-client-
|
|
6
|
+
import { C as CopyRouteButton } from './client-client-CgPBB3ii.js';
|
|
7
|
+
export { A as APIPlayground, R as Root, u as useSchemaContext } from './client-client-CgPBB3ii.js';
|
|
8
8
|
|
|
9
9
|
const badgeVariants = cva('rounded border px-1.5 py-1 text-xs font-medium leading-[12px]', {
|
|
10
10
|
variants: {
|
|
@@ -6,7 +6,7 @@ import { FormProvider, Controller, useFormContext, useFieldArray, useForm, useWa
|
|
|
6
6
|
import useSWRImmutable from 'swr/immutable';
|
|
7
7
|
import { Accordions, Accordion } from 'fumadocs-ui/components/accordion';
|
|
8
8
|
import { cn, buttonVariants } from 'fumadocs-ui/components/api';
|
|
9
|
-
import { u as useSchemaContext, a as useApiContext, S as SchemaContext } from './client-client-
|
|
9
|
+
import { u as useSchemaContext, a as useApiContext, S as SchemaContext } from './client-client-CgPBB3ii.js';
|
|
10
10
|
import { Slot } from '@radix-ui/react-slot';
|
|
11
11
|
import { cva } from 'class-variance-authority';
|
|
12
12
|
import { CircleCheckIcon, CircleXIcon, ChevronDown, ChevronUp, Check, Trash2, Plus } from 'lucide-react';
|
|
@@ -809,6 +809,21 @@ function ArrayInput({ fieldName, field, ...props }) {
|
|
|
809
809
|
});
|
|
810
810
|
}
|
|
811
811
|
|
|
812
|
+
const sharedTransformers = [
|
|
813
|
+
{
|
|
814
|
+
name: 'fumadocs:pre-process',
|
|
815
|
+
line (hast) {
|
|
816
|
+
if (hast.children.length === 0) {
|
|
817
|
+
// Keep the empty lines when using grid layout
|
|
818
|
+
hast.children.push({
|
|
819
|
+
type: 'text',
|
|
820
|
+
value: ' '
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
];
|
|
826
|
+
|
|
812
827
|
function CodeBlock({ code, lang = 'json', ...props }) {
|
|
813
828
|
const { highlighter } = useApiContext();
|
|
814
829
|
const [html, setHtml] = useState('');
|
|
@@ -820,7 +835,8 @@ function CodeBlock({ code, lang = 'json', ...props }) {
|
|
|
820
835
|
themes: {
|
|
821
836
|
light: 'github-light',
|
|
822
837
|
dark: 'github-dark'
|
|
823
|
-
}
|
|
838
|
+
},
|
|
839
|
+
transformers: sharedTransformers
|
|
824
840
|
});
|
|
825
841
|
setHtml(themedHtml);
|
|
826
842
|
}, [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fumadocs-openapi",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"description": "Generate MDX docs for your OpenAPI spec",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"NextJs",
|
|
@@ -60,8 +60,8 @@
|
|
|
60
60
|
"remark": "^15.0.0",
|
|
61
61
|
"shiki": "^1.13.0",
|
|
62
62
|
"swr": "^2.2.5",
|
|
63
|
-
"fumadocs-core": "13.3.
|
|
64
|
-
"fumadocs-ui": "13.3.
|
|
63
|
+
"fumadocs-core": "13.3.2",
|
|
64
|
+
"fumadocs-ui": "13.3.2"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
67
|
"@types/js-yaml": "^4.0.9",
|