Add comments to generated files indicating they were generated (#1512)

* feat: auto-gen comment

* Add addGeneratedComment option to OpenAPI.generateFiles

* adding back previous GenerateOptions, mistakenly removed

* ran prettier

* use mdx style format below the frontmatter

* minimizing changes to the existing codebase

* minimizing changes to the existing codebase

* run prettier

* fixing format of comment within example docs

* fixing issue with prettier removing formatting from JSX style comment within a MDX codeblock

* fix duplicated types

---------

Co-authored-by: Fuma Nama <[email protected]>
This commit is contained in:
Andrew Mikofalvy
2025-03-03 19:09:14 +08:00
committed by GitHub
co-authored by Fuma Nama
parent 2035cb18df
commit 70d715d190
9 changed files with 81 additions and 23 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'fumadocs-openapi': minor
---
Added auto-generated comments to top of generated openapi docs files
@@ -138,6 +138,27 @@ void generateFiles({
});
```
### Add Generated Comment
Add a comment to the top of generated files indicating they are auto-generated.
```ts
import { generateFiles } from 'fumadocs-openapi';
void generateFiles({
input: ['./petstore.yaml'],
output: './content/docs',
// Add default comment
addGeneratedComment: true,
// Or provide a custom comment
addGeneratedComment: 'Custom auto-generated comment',
// Or disable comments
addGeneratedComment: false,
});
```
### Tag Display Name
Adding `x-displayName` to OpenAPI Schema can control the display name of your tags.
+14 -20
View File
@@ -115,15 +115,22 @@ export async function generateFiles(options: Config): Promise<void> {
: join(outputDir, 'webhooks', `${file}.mdx`),
);
}
}
if (groupBy === 'route' || groupBy === 'none') {
} else {
outPaths.push(join(outputDir, `${file}.mdx`));
}
return outPaths;
}
const metaFiles = new Set<string>();
async function writeMetafile(file: string, data: object) {
if (metaFiles.has(file)) return;
metaFiles.add(file);
await write(file, JSON.stringify(data, null, 2));
console.log(`Generated Meta: ${file}`);
}
async function generateFromDocument(pathOrUrl: string) {
if (per === 'file') {
let filename = isUrl(pathOrUrl) ? 'index' : parse(pathOrUrl).name;
@@ -137,30 +144,17 @@ export async function generateFiles(options: Config): Promise<void> {
}
if (per === 'operation') {
const metaFiles = new Set<string>();
const results = await generatePages(pathOrUrl, options);
for (const result of results) {
const meta = JSON.stringify(
{
title: result.pathItem.summary,
},
null,
2,
);
for (const outPath of getOutputPaths(result)) {
await write(outPath, result.content);
console.log(`Generated: ${outPath}`);
if (groupBy === 'route') {
const metaFile = join(dirname(outPath), 'meta.json');
if (!result.pathItem.summary || metaFiles.has(metaFile)) continue;
metaFiles.add(metaFile);
await write(metaFile, meta);
console.log(`Generated Meta: ${metaFile}`);
if (groupBy === 'route' && result.pathItem.summary) {
await writeMetafile(join(dirname(outPath), 'meta.json'), {
title: result.pathItem.summary,
});
}
}
}
+10
View File
@@ -37,6 +37,16 @@ export interface GenerateOptions {
*/
includeDescription?: boolean;
/**
* Add a comment to the top of generated files indicating they are auto-generated.
* - `true`: Adds a standardized comment
* - `false`: No comment is added
* - `string`: Adds the provided custom comment
*
* @defaultValue true
*/
addGeneratedComment?: boolean | string;
cwd?: string;
}
@@ -1,7 +1,7 @@
import { dump } from 'js-yaml';
import Slugger from 'github-slugger';
import { type TableOfContents } from 'fumadocs-core/server';
import { type StructuredData } from 'fumadocs-core/mdx-plugins';
import type { TableOfContents } from 'fumadocs-core/server';
import type { StructuredData } from 'fumadocs-core/mdx-plugins';
import type {
ApiPageProps,
OperationItem,
@@ -38,7 +38,11 @@ export function generateDocument(
context: DocumentContext;
},
): string {
const { frontmatter, includeDescription = false } = options;
const {
frontmatter,
includeDescription = false,
addGeneratedComment = true,
} = options;
const out: string[] = [];
const extend = frontmatter?.(
options.title,
@@ -71,6 +75,18 @@ export function generateDocument(
}).trim();
if (banner.length > 0) out.push(`---\n${banner}\n---`);
if (addGeneratedComment !== false) {
let commentContent =
'This file was generated by Fumadocs.\nDo not edit this file directly. Any changes should be made by running the generation command again.';
if (typeof addGeneratedComment === 'string') {
commentContent = addGeneratedComment;
}
commentContent = commentContent.replaceAll('/', '\\/');
out.push(`{/* ${commentContent} */}`);
}
const imports = options.imports
?.map(
(item) =>
@@ -46,4 +46,7 @@ _openapi:
heading: delete-special-event
---
{/* This file was generated by Fumadocs.
Do not edit this file directly. Any changes should be made by running the generation command again. */}
<APIPage document={"./fixtures/museum.yaml"} operations={[{"path":"/special-events","method":"get"},{"path":"/special-events","method":"post"},{"path":"/special-events/{eventId}","method":"get"},{"path":"/special-events/{eventId}","method":"patch"},{"path":"/special-events/{eventId}","method":"delete"}]} webhooks={[]} hasHead={true} />
@@ -18,4 +18,7 @@ _openapi:
heading: get-museum-hours
---
{/* This file was generated by Fumadocs.
Do not edit this file directly. Any changes should be made by running the generation command again. */}
<APIPage document={"./fixtures/museum.yaml"} operations={[{"path":"/museum-hours","method":"get"}]} webhooks={[]} hasHead={true} />
@@ -25,4 +25,7 @@ _openapi:
heading: get-ticket-qr-code
---
{/* This file was generated by Fumadocs.
Do not edit this file directly. Any changes should be made by running the generation command again. */}
<APIPage document={"./fixtures/museum.yaml"} operations={[{"path":"/tickets","method":"post"},{"path":"/tickets/{ticketId}/qr","method":"get"}]} webhooks={[]} hasHead={true} />
+3
View File
@@ -23,4 +23,7 @@ _openapi:
contents: []
---
{/* This file was generated by Fumadocs.
Do not edit this file directly. Any changes should be made by running the generation command again. */}
<APIPage document={"./fixtures/petstore.yaml"} operations={[{"path":"/pets","method":"get"},{"path":"/pets","method":"post"},{"path":"/pets/{petId}","method":"get"}]} webhooks={[]} hasHead={true} />