Files
wwjcloud/tools/gen-controllers.js

75 lines
2.9 KiB
JavaScript
Raw Normal View History

const fs = require('fs');
const path = require('path');
const PROJECT_SRC = path.join(__dirname, '..', 'wwjcloud', 'src', 'common');
const CONTRACT_FILE = path.join(__dirname, 'contracts', 'routes.json');
function toCamelCase(input) {
return input.replace(/[-_]+([a-zA-Z0-9])/g, (_, c) => c.toUpperCase());
}
function toPascalCase(input) {
const camel = toCamelCase(input);
return camel.charAt(0).toUpperCase() + camel.slice(1);
}
function ensureDir(dir) {
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
}
function buildMethodName(method, relPath) {
const cleaned = relPath.replace(/:\w+/g, '').replace(/\/$/, '');
const parts = cleaned.split('/').filter(Boolean);
const base = parts.length ? parts.join('_') : 'root';
return method.toLowerCase() + toPascalCase(base);
}
function controllerTemplate(prefix, className, routes) {
const imports = "import { Controller, Get, Post, Put, Delete, Body, Param, Query, UseGuards } from '@nestjs/common';\n" +
"import { ApiOperation, ApiTags } from '@nestjs/swagger';\n" +
"import { AdminCheckTokenGuard } from '../../../../core/security/adminCheckToken.guard';\n" +
"import { SiteScopeGuard } from '../../../../core/security/siteScopeGuard';\n\n";
const header = `@ApiTags('${prefix}')\n@UseGuards(AdminCheckTokenGuard, SiteScopeGuard)\n@Controller('adminapi/${prefix}')\nexport class ${className} {`;
const methods = routes.map(r => {
const decorator = `@${r.method.charAt(0) + r.method.slice(1).toLowerCase()}('${r.rel}')`;
const summary = `@ApiOperation({ summary: '${r.method} ${r.rel}' })`;
const methodName = buildMethodName(r.method, r.rel);
return ` ${decorator}\n ${summary}\n ${methodName}() {\n return { success: true };\n }`;
}).join('\n\n');
return imports + header + '\n' + methods + '\n}\n';
}
function main() {
const contract = JSON.parse(fs.readFileSync(CONTRACT_FILE, 'utf8'));
// group by first segment after adminapi/
const groups = new Map();
for (const r of contract) {
if (!r.path.startsWith('adminapi/')) continue;
const rest = r.path.slice('adminapi/'.length);
const [prefix, ...restParts] = rest.split('/');
const rel = restParts.join('/');
const arr = groups.get(prefix) || [];
arr.push({ method: r.method, rel });
groups.set(prefix, arr);
}
for (const [prefix, routes] of groups) {
const moduleDir = path.join(PROJECT_SRC, prefix);
const ctrlDir = path.join(moduleDir, 'controllers', 'adminapi');
ensureDir(ctrlDir);
const fileName = `${toCamelCase(prefix)}.controller.ts`;
const filePath = path.join(ctrlDir, fileName);
if (fs.existsSync(filePath)) {
// do not overwrite; skip existing controllers
continue;
}
const className = `${toPascalCase(prefix)}Controller`;
const content = controllerTemplate(prefix, className, routes);
fs.writeFileSync(filePath, content);
console.log('Generated', filePath);
}
}
main();