feat: 完成PHP到NestJS的100%功能迁移
- 迁移25个模块,包含95个控制器和160个服务 - 新增验证码管理、登录配置、云编译等模块 - 完善认证授权、会员管理、支付系统等核心功能 - 实现完整的队列系统、配置管理、监控体系 - 确保100%功能对齐和命名一致性 - 支持生产环境部署
This commit is contained in:
88
scripts/export-routes.js
Normal file
88
scripts/export-routes.js
Normal file
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const repoRoot = path.resolve(__dirname, '..');
|
||||
const srcRoot = path.join(repoRoot, 'wwjcloud', 'src');
|
||||
|
||||
function isTypescriptFile(filePath) {
|
||||
return filePath.endsWith('.ts') && !filePath.endsWith('.d.ts') && !filePath.endsWith('.spec.ts');
|
||||
}
|
||||
|
||||
function walk(dir, collected = []) {
|
||||
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
||||
for (const entry of entries) {
|
||||
const fullPath = path.join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
walk(fullPath, collected);
|
||||
} else if (entry.isFile() && isTypescriptFile(fullPath)) {
|
||||
collected.push(fullPath);
|
||||
}
|
||||
}
|
||||
return collected;
|
||||
}
|
||||
|
||||
function isControllerFile(filePath) {
|
||||
return filePath.includes(path.join('controllers', 'adminapi') + path.sep) || filePath.includes(path.join('controllers', 'api') + path.sep);
|
||||
}
|
||||
|
||||
function getBasePath(fileContent) {
|
||||
const controllerMatch = fileContent.match(/@Controller\(([^)]*)\)/);
|
||||
if (!controllerMatch) return '';
|
||||
const arg = controllerMatch[1];
|
||||
const strMatch = arg && arg.match(/['"`]([^'"`]*)['"`]/);
|
||||
return strMatch ? strMatch[1] : '';
|
||||
}
|
||||
|
||||
function extractRoutes(fileContent) {
|
||||
const routes = [];
|
||||
const methodDecorators = ['Get', 'Post', 'Put', 'Patch', 'Delete', 'Options', 'Head', 'All'];
|
||||
for (const m of methodDecorators) {
|
||||
const regex = new RegExp(`@${m}\\(([^)]*)\\)`, 'g');
|
||||
let match;
|
||||
while ((match = regex.exec(fileContent)) !== null) {
|
||||
const arg = match[1] || '';
|
||||
let subPath = '';
|
||||
const strMatch = arg.match(/['"`]([^'"`]*)['"`]/);
|
||||
if (strMatch) subPath = strMatch[1];
|
||||
routes.push({ method: m.toUpperCase(), subPath });
|
||||
}
|
||||
}
|
||||
return routes;
|
||||
}
|
||||
|
||||
function main() {
|
||||
if (!fs.existsSync(srcRoot)) {
|
||||
console.error(`src root not found: ${srcRoot}`);
|
||||
process.exit(1);
|
||||
}
|
||||
const allTs = walk(srcRoot);
|
||||
const controllerFiles = allTs.filter(isControllerFile);
|
||||
|
||||
const rows = [];
|
||||
for (const filePath of controllerFiles) {
|
||||
const content = fs.readFileSync(filePath, 'utf8');
|
||||
if (!/@Controller\(/.test(content)) continue;
|
||||
const base = getBasePath(content);
|
||||
const routes = extractRoutes(content);
|
||||
const rel = path.relative(repoRoot, filePath);
|
||||
for (const r of routes) {
|
||||
rows.push({ file: rel, base, method: r.method, sub: r.subPath });
|
||||
}
|
||||
}
|
||||
|
||||
console.log('file,basePath,method,subPath');
|
||||
for (const row of rows) {
|
||||
console.log(`${row.file},${row.base},${row.method},${row.sub}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
try {
|
||||
main();
|
||||
} catch (err) {
|
||||
console.error('export-routes failed:', err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user