chore(backend): align OpenAPI output with Mintlify and mirror specs to docs-mintlify.

- Normalize empty route path to / for valid OpenAPI path keys
- Drop invalid OAS3 top-level type on header parameters
- Write client/server/admin/webhooks JSON to docs-mintlify/openapi on codegen
This commit is contained in:
Madison 2026-04-08 16:29:05 -05:00
parent 8857dbaa48
commit 63296fd3e0
2 changed files with 20 additions and 4 deletions

View File

@ -14,12 +14,17 @@ async function main() {
// Create openapi directory in Fumadocs project
const fumaDocsOpenApiDir = path.resolve("../../docs/openapi");
const mintlifyOpenApiDir = path.resolve("../../docs-mintlify/openapi");
// Ensure the openapi directory exists
if (!fs.existsSync(fumaDocsOpenApiDir)) {
console.log('Creating OpenAPI directory...');
fs.mkdirSync(fumaDocsOpenApiDir, { recursive: true });
}
if (!fs.existsSync(mintlifyOpenApiDir)) {
console.log('Creating Mintlify OpenAPI directory...');
fs.mkdirSync(mintlifyOpenApiDir, { recursive: true });
}
// Generate OpenAPI specs for each audience (let parseOpenAPI handle the filtering)
const filePathPrefix = path.resolve(process.platform === "win32" ? "apps/src/app/api/latest" : "src/app/api/latest");
@ -33,7 +38,9 @@ async function main() {
const suffix = filePath.slice(filePathPrefix.length);
const midfix = suffix.slice(0, suffix.lastIndexOf("/route."));
const importPath = `${importPathPrefix}${suffix}`;
const urlPath = midfix.replaceAll("[", "{").replaceAll("]", "}").replaceAll(/\/\(.*\)/g, "");
const urlPathRaw = midfix.replaceAll("[", "{").replaceAll("]", "}").replaceAll(/\/\(.*\)/g, "");
// OpenAPI path keys must not be empty (Mintlify and other tooling reject `""`).
const urlPath = urlPathRaw === "" ? "/" : urlPathRaw;
const myModule = await import(importPath);
const handlersByMethod = new Map(
typedKeys(HTTP_METHODS).map(method => [method, myModule[method]] as const)
@ -59,10 +66,15 @@ async function main() {
console.log(`Generated ${Object.keys(openApiSchemaObject.paths || {}).length} endpoints for ${audience} audience`);
const audienceJson = JSON.stringify(openApiSchemaObject, null, 2);
// Write JSON files for Fumadocs (they prefer JSON over YAML)
writeFileSyncIfChanged(
path.join(fumaDocsOpenApiDir, `${audience}.json`),
JSON.stringify(openApiSchemaObject, null, 2)
audienceJson
);
writeFileSyncIfChanged(
path.join(mintlifyOpenApiDir, `${audience}.json`),
audienceJson
);
}
@ -71,9 +83,14 @@ async function main() {
webhooks: webhookEvents,
});
const webhooksJson = JSON.stringify(webhookOpenAPISchema, null, 2);
writeFileSyncIfChanged(
path.join(fumaDocsOpenApiDir, 'webhooks.json'),
JSON.stringify(webhookOpenAPISchema, null, 2)
webhooksJson
);
writeFileSyncIfChanged(
path.join(mintlifyOpenApiDir, 'webhooks.json'),
webhooksJson
);
console.log("Successfully updated Fumadocs OpenAPI schemas with proper audience filtering");

View File

@ -274,7 +274,6 @@ function toHeaderParameters(description: yup.SchemaFieldDescription, crudOperati
return {
name: key,
in: 'header',
type: 'string',
schema,
description: meta?.openapiField?.description,
example: meta?.openapiField?.exampleValue,