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();