@sasonarik/nextapi-swagger
Version:
CLI tool to generate Next.js API routes and types from Swagger/OpenAPI specs
68 lines (67 loc) • 3.12 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateTypes = generateTypes;
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const helper_1 = require("../helper/helper");
const chalk_1 = __importDefault(require("chalk"));
async function generateTypes(spec, outDir, baseName) {
const outPath = path_1.default.join(outDir, "types", "api.ts");
await fs_extra_1.default.ensureDir(path_1.default.dirname(outPath));
let existingContent = "";
let existingInterfaceNames = new Set();
// Read existing file content
if (await fs_extra_1.default.pathExists(outPath)) {
existingContent = await fs_extra_1.default.readFile(outPath, "utf8");
console.log(chalk_1.default.yellow(`ℹ️ Existing file found at ${outPath}`));
// Extract already defined interface names using regex
const interfaceRegex = /export\s+interface\s+(\w+)/g;
let match;
while ((match = interfaceRegex.exec(existingContent)) !== null) {
existingInterfaceNames.add(match[1]);
}
}
const lines = [];
const seenInterfaces = new Set();
const schemas = spec.components?.schemas ??
spec.definitions ??
{};
if (Object.keys(schemas).length === 0) {
console.log(chalk_1.default.yellowBright(`❌ No schemas found in spec. Check OpenAPI version.`));
const fallbackContent = [`// Auto-generated types for ${baseName}`, ``];
await fs_extra_1.default.writeFile(outPath, fallbackContent.join("\n\n"));
return;
}
// Add ApiResult only if it's not already defined
if (!existingInterfaceNames.has("ApiResult")) {
lines.push(`export interface ApiResult<T> {`, ` status: boolean;`, ` data: T;`, ` message: string;`, `}`, ``);
}
for (const [rawName, schema] of Object.entries(schemas)) {
const name = (0, helper_1.cleanTypeName)(rawName);
if (seenInterfaces.has(name) || existingInterfaceNames.has(name))
continue;
seenInterfaces.add(name);
const props = schema.properties ?? {};
const required = new Set(schema.required ?? []);
const typeLines = Object.entries(props).map(([key, val]) => {
const optional = required.has(key) ? "" : "?";
const type = (0, helper_1.resolveType)(val);
return ` ${key}${optional}: ${type};`;
});
lines.push(`export interface ${name} {`, ...typeLines, `}`);
}
if (lines.length > 0) {
const newContent = lines.join("\n\n");
const fullContent = [existingContent, newContent]
.filter(Boolean)
.join("\n\n");
await fs_extra_1.default.writeFile(outPath, fullContent);
console.log(chalk_1.default.greenBright(`✅ API types written to ${outPath}`));
}
else {
console.log(chalk_1.default.gray(`ℹ️ No new interfaces to write.`));
}
}