mirror of
https://github.com/Dokploy/website.git
synced 2026-06-15 20:25:25 +02:00
- Added logic to unwrap nested OpenAPI specifications from migrated APIs, improving compatibility with various API structures. - Updated the condition for writing the fixed schema to include unwrapped status, ensuring all necessary changes are saved.
109 lines
3.2 KiB
JavaScript
109 lines
3.2 KiB
JavaScript
import { readFileSync, writeFileSync } from "fs";
|
|
import { join } from "path";
|
|
|
|
const openapiPath = join(process.cwd(), "public", "openapi.json");
|
|
|
|
console.log("Fixing OpenAPI schema...");
|
|
|
|
try {
|
|
let openapi = JSON.parse(readFileSync(openapiPath, "utf8"));
|
|
|
|
let unwrapped = false;
|
|
// If the spec is nested (e.g. result.data.json from a migrated/source API), use the inner spec
|
|
if (openapi.result?.data?.json && typeof openapi.result.data.json === "object") {
|
|
openapi = openapi.result.data.json;
|
|
unwrapped = true;
|
|
console.log("✓ Unwrapped nested OpenAPI spec (result.data.json)");
|
|
}
|
|
|
|
let fixed = 0;
|
|
let securityFixed = false;
|
|
|
|
// Remove Authorization security scheme and add x-api-key
|
|
if (!openapi.components) {
|
|
openapi.components = {};
|
|
}
|
|
if (!openapi.components.securitySchemes) {
|
|
openapi.components.securitySchemes = {};
|
|
}
|
|
|
|
// Remove old Authorization scheme
|
|
if (openapi.components.securitySchemes["Authorization"]) {
|
|
delete openapi.components.securitySchemes["Authorization"];
|
|
securityFixed = true;
|
|
}
|
|
|
|
// Add x-api-key scheme
|
|
openapi.components.securitySchemes["x-api-key"] = {
|
|
type: "apiKey",
|
|
in: "header",
|
|
name: "x-api-key",
|
|
description: "API key authentication. Use YOUR-GENERATED-API-KEY",
|
|
"x-default": "your-key",
|
|
};
|
|
securityFixed = true;
|
|
|
|
// Replace global security from Authorization to x-api-key
|
|
if (openapi.security) {
|
|
openapi.security = openapi.security.filter((sec) => !sec["Authorization"]);
|
|
} else {
|
|
openapi.security = [];
|
|
}
|
|
|
|
const hasApiKeySecurity = openapi.security.some((sec) => sec["x-api-key"]);
|
|
if (!hasApiKeySecurity) {
|
|
openapi.security.push({ "x-api-key": [] });
|
|
securityFixed = true;
|
|
}
|
|
|
|
// Replace Authorization with x-api-key in all operation security
|
|
for (const [path, pathItem] of Object.entries(openapi.paths || {})) {
|
|
for (const [method, operation] of Object.entries(pathItem)) {
|
|
if (operation && operation.security) {
|
|
// Replace Authorization with x-api-key
|
|
operation.security = operation.security.map((sec) => {
|
|
if (sec["Authorization"] !== undefined) {
|
|
securityFixed = true;
|
|
return { "x-api-key": [] };
|
|
}
|
|
return sec;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// Fix empty response schemas
|
|
for (const [path, pathItem] of Object.entries(openapi.paths || {})) {
|
|
for (const [method, operation] of Object.entries(pathItem)) {
|
|
if (operation.responses) {
|
|
for (const [status, response] of Object.entries(operation.responses)) {
|
|
if (response.content && response.content["application/json"]) {
|
|
const content = response.content["application/json"];
|
|
// Check if schema is completely empty or missing
|
|
if (Object.keys(content).length === 0 || !content.schema) {
|
|
response.content["application/json"] = {
|
|
schema: {
|
|
type: "object",
|
|
description: "Successful response",
|
|
},
|
|
};
|
|
fixed++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (unwrapped || fixed > 0 || securityFixed) {
|
|
writeFileSync(openapiPath, JSON.stringify(openapi, null, 2));
|
|
if (fixed > 0) console.log(`✓ Fixed ${fixed} empty response schemas`);
|
|
if (securityFixed) console.log("✓ Added x-api-key security scheme");
|
|
} else {
|
|
console.log("✓ No fixes needed");
|
|
}
|
|
} catch (error) {
|
|
console.error("Error fixing OpenAPI schema:", error.message);
|
|
process.exit(1);
|
|
}
|