fumadocs-openapi 3.1.0 → 3.1.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.
- package/dist/index.d.ts +7 -2
- package/dist/index.js +54 -6
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -64,7 +64,12 @@ interface GenerateTagOutput {
|
|
|
64
64
|
tag: string;
|
|
65
65
|
content: string;
|
|
66
66
|
}
|
|
67
|
+
interface GenerateOperationOutput {
|
|
68
|
+
id: string;
|
|
69
|
+
content: string;
|
|
70
|
+
}
|
|
67
71
|
declare function generate(pathOrDocument: string | OpenAPIV3.Document, options?: GenerateOptions): Promise<string>;
|
|
72
|
+
declare function generateOperations(pathOrDocument: string | OpenAPIV3.Document, options?: GenerateOptions): Promise<GenerateOperationOutput[]>;
|
|
68
73
|
declare function generateTags(pathOrDocument: string | OpenAPIV3.Document, options?: GenerateOptions): Promise<GenerateTagOutput[]>;
|
|
69
74
|
|
|
70
75
|
interface Config extends GenerateOptions {
|
|
@@ -83,7 +88,7 @@ interface Config extends GenerateOptions {
|
|
|
83
88
|
*
|
|
84
89
|
* @defaultValue file
|
|
85
90
|
*/
|
|
86
|
-
per?: 'tag' | 'file';
|
|
91
|
+
per?: 'tag' | 'file' | 'operation';
|
|
87
92
|
/**
|
|
88
93
|
* Specify name for output file
|
|
89
94
|
*/
|
|
@@ -110,4 +115,4 @@ interface RenderContext {
|
|
|
110
115
|
|
|
111
116
|
declare function createElement(name: string, props: object, ...child: string[]): string;
|
|
112
117
|
|
|
113
|
-
export { type APIInfoProps, type Config, type GenerateOptions, type GenerateTagOutput, type MethodInformation, type ObjectCollapsibleProps, type PropertyProps, type RenderContext, type Renderer, type RequestProps, type ResponseProps, type ResponsesProps, type RouteInformation, createElement, defaultRenderer, generate, generateFiles, generateTags };
|
|
118
|
+
export { type APIInfoProps, type Config, type GenerateOperationOutput, type GenerateOptions, type GenerateTagOutput, type MethodInformation, type ObjectCollapsibleProps, type PropertyProps, type RenderContext, type Renderer, type RequestProps, type ResponseProps, type ResponsesProps, type RouteInformation, createElement, defaultRenderer, generate, generateFiles, generateOperations, generateTags };
|
package/dist/index.js
CHANGED
|
@@ -72,6 +72,9 @@ function codeblock({ language, title }, child) {
|
|
|
72
72
|
"```"
|
|
73
73
|
].join("\n");
|
|
74
74
|
}
|
|
75
|
+
function heading(depth, child) {
|
|
76
|
+
return `${"#".repeat(depth)} ${child.trim()}`;
|
|
77
|
+
}
|
|
75
78
|
|
|
76
79
|
// src/render/renderer.ts
|
|
77
80
|
var defaultRenderer = {
|
|
@@ -375,23 +378,24 @@ function getSchemaType(schema) {
|
|
|
375
378
|
}
|
|
376
379
|
|
|
377
380
|
// src/render/operation.ts
|
|
378
|
-
async function renderOperation(path, method, ctx) {
|
|
381
|
+
async function renderOperation(path, method, ctx, noTitle = false) {
|
|
382
|
+
let level = 2;
|
|
379
383
|
const body = noRef(method.requestBody);
|
|
380
384
|
const security = method.security ?? ctx.document.security;
|
|
381
385
|
const info = [];
|
|
382
386
|
const example = [];
|
|
383
387
|
const title = method.summary ?? method.operationId;
|
|
384
|
-
if (title) info.push(
|
|
388
|
+
if (title && !noTitle) info.push(heading(level++, title));
|
|
385
389
|
if (method.description) info.push(p(method.description));
|
|
386
390
|
if (security) {
|
|
387
|
-
info.push("
|
|
391
|
+
info.push(heading(level, "Authorization"));
|
|
388
392
|
info.push(getAuthSection(security, ctx));
|
|
389
393
|
}
|
|
390
394
|
if (body) {
|
|
391
395
|
const bodySchema = getPreferredMedia(body.content)?.schema;
|
|
392
396
|
if (!bodySchema) throw new Error();
|
|
393
397
|
info.push(
|
|
394
|
-
|
|
398
|
+
heading(level, `Request Body ${!body.required ? "(Optional)" : ""}`),
|
|
395
399
|
p(body.description),
|
|
396
400
|
schemaElement("body", noRef(bodySchema), {
|
|
397
401
|
parseObject: true,
|
|
@@ -435,7 +439,7 @@ async function renderOperation(path, method, ctx) {
|
|
|
435
439
|
parameterGroups.set(groupName, group);
|
|
436
440
|
}
|
|
437
441
|
for (const [group, parameters] of Array.from(parameterGroups.entries())) {
|
|
438
|
-
info.push(
|
|
442
|
+
info.push(heading(level, group), ...parameters);
|
|
439
443
|
}
|
|
440
444
|
info.push(getResponseTable(method));
|
|
441
445
|
example.push(
|
|
@@ -584,6 +588,29 @@ async function generate(pathOrDocument, options = {}) {
|
|
|
584
588
|
options
|
|
585
589
|
);
|
|
586
590
|
}
|
|
591
|
+
async function generateOperations(pathOrDocument, options = {}) {
|
|
592
|
+
const document = await Parser.dereference(pathOrDocument);
|
|
593
|
+
const routes = buildRoutes(document).get("all") ?? [];
|
|
594
|
+
const ctx = getContext(document, options);
|
|
595
|
+
return await Promise.all(
|
|
596
|
+
routes.flatMap((route) => {
|
|
597
|
+
return route.methods.map(async (method) => {
|
|
598
|
+
const content = renderPage(
|
|
599
|
+
method.summary ?? method.method,
|
|
600
|
+
method.description,
|
|
601
|
+
[await renderOperation(route.path, method, ctx, true)],
|
|
602
|
+
options
|
|
603
|
+
);
|
|
604
|
+
if (!method.operationId)
|
|
605
|
+
throw new Error("Operation ID is required for generating docs.");
|
|
606
|
+
return {
|
|
607
|
+
id: method.operationId,
|
|
608
|
+
content
|
|
609
|
+
};
|
|
610
|
+
});
|
|
611
|
+
})
|
|
612
|
+
);
|
|
613
|
+
}
|
|
587
614
|
async function generateTags(pathOrDocument, options = {}) {
|
|
588
615
|
const document = await Parser.dereference(pathOrDocument);
|
|
589
616
|
const tags = Array.from(buildRoutes(document).entries());
|
|
@@ -640,10 +667,24 @@ async function generateFiles({
|
|
|
640
667
|
console.log(`Generated: ${outPath}`);
|
|
641
668
|
return;
|
|
642
669
|
}
|
|
670
|
+
if (per === "operation") {
|
|
671
|
+
const results2 = await generateOperations(path, options);
|
|
672
|
+
await Promise.all(
|
|
673
|
+
results2.map(async (result) => {
|
|
674
|
+
const outPath = join(
|
|
675
|
+
outputDir,
|
|
676
|
+
filename,
|
|
677
|
+
`${getName(result.id)}.mdx`
|
|
678
|
+
);
|
|
679
|
+
await write(outPath, result.content);
|
|
680
|
+
console.log(`Generated: ${outPath}`);
|
|
681
|
+
})
|
|
682
|
+
);
|
|
683
|
+
}
|
|
643
684
|
const results = await generateTags(path, options);
|
|
644
685
|
for (const result of results) {
|
|
645
686
|
let tagName = result.tag;
|
|
646
|
-
tagName = nameFn?.("tag", tagName) ?? tagName
|
|
687
|
+
tagName = nameFn?.("tag", tagName) ?? getName(tagName);
|
|
647
688
|
const outPath = join(outputDir, filename, `${tagName}.mdx`);
|
|
648
689
|
await write(outPath, result.content);
|
|
649
690
|
console.log(`Generated: ${outPath}`);
|
|
@@ -651,6 +692,12 @@ async function generateFiles({
|
|
|
651
692
|
})
|
|
652
693
|
);
|
|
653
694
|
}
|
|
695
|
+
function getName(s) {
|
|
696
|
+
return s.replace(
|
|
697
|
+
/[A-Z]/g,
|
|
698
|
+
(match, idx) => idx === 0 ? match : `-${match.toLowerCase()}`
|
|
699
|
+
).replace(/\s+/g, "-").toLowerCase();
|
|
700
|
+
}
|
|
654
701
|
async function write(path, content) {
|
|
655
702
|
await mkdir(dirname(path), { recursive: true });
|
|
656
703
|
await writeFile(path, content);
|
|
@@ -660,5 +707,6 @@ export {
|
|
|
660
707
|
defaultRenderer,
|
|
661
708
|
generate,
|
|
662
709
|
generateFiles,
|
|
710
|
+
generateOperations,
|
|
663
711
|
generateTags
|
|
664
712
|
};
|