#!/usr/bin/env node const fs = require('fs'); const path = require('path'); /** * 基础生成器类 * 提供通用的 dry-run、文件操作、日志等功能 */ class BaseGenerator { constructor(generatorName = 'Generator') { this.generatorName = generatorName; // 从环境变量或参数读取配置 this.dryRun = process.env.DRY_RUN === 'true' || process.argv.includes('--dry-run'); this.verbose = process.env.VERBOSE === 'true' || process.argv.includes('--verbose'); this.stats = { filesCreated: 0, filesUpdated: 0, filesSkipped: 0, errors: 0 }; } /** * 安全写入文件(支持 dry-run) */ writeFile(filePath, content, description = '') { try { if (this.dryRun) { console.log(` [DRY-RUN] Would create/update: ${filePath}`); if (this.verbose && description) { console.log(` Description: ${description}`); } this.stats.filesCreated++; return true; } // 确保目录存在 this.ensureDir(path.dirname(filePath)); // 写入文件 fs.writeFileSync(filePath, content, 'utf8'); const action = fs.existsSync(filePath) ? 'Updated' : 'Created'; console.log(` ✅ ${action}: ${filePath}`); if (action === 'Created') { this.stats.filesCreated++; } else { this.stats.filesUpdated++; } return true; } catch (error) { console.error(` ❌ Failed to write ${filePath}:`, error.message); this.stats.errors++; return false; } } /** * 确保目录存在 */ ensureDir(dirPath) { if (this.dryRun) { return; } if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); } } /** * 读取文件(安全) */ readFile(filePath) { try { if (!fs.existsSync(filePath)) { return null; } return fs.readFileSync(filePath, 'utf8'); } catch (error) { console.error(` ❌ Failed to read ${filePath}:`, error.message); return null; } } /** * 检查文件是否存在 */ fileExists(filePath) { return fs.existsSync(filePath); } /** * 日志输出 */ log(message, level = 'info') { const prefix = { 'info': ' ℹ️ ', 'success': ' ✅', 'warning': ' ⚠️ ', 'error': ' ❌', 'debug': ' 🔍' }; if (level === 'debug' && !this.verbose) { return; } console.log(`${prefix[level] || ' '}${message}`); } /** * 输出统计信息 */ printStats(additionalStats = {}) { console.log('\n📊 Generation Statistics'); console.log('=================================================='); if (this.dryRun) { console.log(' 🔍 DRY-RUN MODE - No files were actually modified'); } console.log(` 📁 Files Created: ${this.stats.filesCreated}`); console.log(` 🔄 Files Updated: ${this.stats.filesUpdated}`); console.log(` ⏭️ Files Skipped: ${this.stats.filesSkipped}`); console.log(` ❌ Errors: ${this.stats.errors}`); // 输出额外的统计信息 for (const [key, value] of Object.entries(additionalStats)) { console.log(` 📈 ${key}: ${value}`); } const total = this.stats.filesCreated + this.stats.filesUpdated; const successRate = total > 0 ? ((total / (total + this.stats.errors)) * 100).toFixed(2) : '0.00'; console.log(` 📊 Success Rate: ${successRate}%`); console.log('=================================================='); } /** * kebab-case 转换 */ toKebabCase(str) { return String(str) .replace(/([a-z0-9])([A-Z])/g, '$1-$2') .replace(/_/g, '-') .toLowerCase(); } /** * PascalCase 转换 */ toPascalCase(str) { return String(str) .split(/[-_]/) .map(word => word.charAt(0).toUpperCase() + word.slice(1)) .join(''); } /** * camelCase 转换 */ toCamelCase(str) { const pascal = this.toPascalCase(str); return pascal.charAt(0).toLowerCase() + pascal.slice(1); } /** * snake_case 转换 */ toSnakeCase(str) { return str.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, ''); } } module.exports = BaseGenerator;