UNPKG

vibe-cli-tool

Version:

VibeCLI v1.9 - 模板商店生态,智能部署生成,多语言支持,交互式学习系统,企业级Web全栈应用CLI工具

210 lines 8.64 kB
import fs from 'fs-extra'; import path from 'path'; import mustache from 'mustache'; export class ProjectGenerator { constructor(projectName, projectPath, config) { this.projectName = projectName; this.projectPath = projectPath; this.config = config; } async generate() { // 创建项目目录 await fs.ensureDir(this.projectPath); // 生成基础项目结构 await this.generateBaseProject(); // 生成配置文件 await this.generateConfigFiles(); // 生成数据库模式 await this.generateDatabaseSchema(); // 生成功能模块 await this.generateFeatures(); // 生成页面和组件 await this.generatePages(); // 复制静态文件 await this.copyStaticFiles(); } async generateBaseProject() { const templatePath = path.join(__dirname, '../templates/base'); // 生成package.json const packageTemplate = await fs.readFile(path.join(templatePath, 'package.json.mustache'), 'utf-8'); const packageJson = mustache.render(packageTemplate, { projectName: this.projectName, hasAuth: this.config.auth, hasUpload: this.config.upload, hasEmail: this.config.email, hasPayment: this.config.payment, hasRealtime: this.config.realtime, database: this.config.database, uiFramework: this.config.uiFramework }); await fs.writeFile(path.join(this.projectPath, 'package.json'), packageJson); // 生成Next.js配置 const nextConfigTemplate = await fs.readFile(path.join(templatePath, 'next.config.js.mustache'), 'utf-8'); const nextConfig = mustache.render(nextConfigTemplate, this.config); await fs.writeFile(path.join(this.projectPath, 'next.config.js'), nextConfig); // 生成TypeScript配置 await fs.copy(path.join(templatePath, 'tsconfig.json'), path.join(this.projectPath, 'tsconfig.json')); // 生成Tailwind配置 if (this.config.uiFramework === 'tailwind-radix') { await fs.copy(path.join(templatePath, 'tailwind.config.js'), path.join(this.projectPath, 'tailwind.config.js')); } } async generateConfigFiles() { const templatePath = path.join(__dirname, '../templates/config'); // 环境变量模板 const envTemplate = await fs.readFile(path.join(templatePath, '.env.example.mustache'), 'utf-8'); const envContent = mustache.render(envTemplate, { database: this.config.database, hasAuth: this.config.auth, hasEmail: this.config.email, hasPayment: this.config.payment, hasUpload: this.config.upload }); await fs.writeFile(path.join(this.projectPath, '.env.example'), envContent); // ESLint配置 await fs.copy(path.join(templatePath, '.eslintrc.json'), path.join(this.projectPath, '.eslintrc.json')); // Prettier配置 await fs.copy(path.join(templatePath, '.prettierrc'), path.join(this.projectPath, '.prettierrc')); // GitIgnore await fs.copy(path.join(templatePath, '.gitignore'), path.join(this.projectPath, '.gitignore')); } async generateDatabaseSchema() { const templatePath = path.join(__dirname, '../templates/database'); // 创建prisma目录 const prismaDir = path.join(this.projectPath, 'prisma'); await fs.ensureDir(prismaDir); // 生成schema.prisma const schemaTemplate = await fs.readFile(path.join(templatePath, 'schema.prisma.mustache'), 'utf-8'); const schemaContent = mustache.render(schemaTemplate, { database: this.config.database, hasAuth: this.config.auth, hasUpload: this.config.upload, template: this.config.template }); await fs.writeFile(path.join(prismaDir, 'schema.prisma'), schemaContent); // 生成种子文件 if (this.config.auth || this.config.template !== 'default') { const seedTemplate = await fs.readFile(path.join(templatePath, 'seed.ts.mustache'), 'utf-8'); const seedContent = mustache.render(seedTemplate, this.config); await fs.writeFile(path.join(prismaDir, 'seed.ts'), seedContent); } } async generateFeatures() { const featuresPath = path.join(this.projectPath, 'lib'); await fs.ensureDir(featuresPath); // 生成认证功能 if (this.config.auth) { await this.generateAuthFeature(); } // 生成文件上传功能 if (this.config.upload) { await this.generateUploadFeature(); } // 生成邮件功能 if (this.config.email) { await this.generateEmailFeature(); } // 生成支付功能 if (this.config.payment) { await this.generatePaymentFeature(); } // 生成实时功能 if (this.config.realtime) { await this.generateRealtimeFeature(); } } async generateAuthFeature() { const authPath = path.join(this.projectPath, 'lib/auth'); await fs.ensureDir(authPath); const templatePath = path.join(__dirname, '../templates/features/auth'); // 复制认证相关文件 const files = [ 'auth.ts', 'jwt.ts', 'middleware.ts', 'validation.ts' ]; for (const file of files) { await fs.copy(path.join(templatePath, file), path.join(authPath, file)); } // 生成API路由 const apiPath = path.join(this.projectPath, 'pages/api/auth'); await fs.ensureDir(apiPath); const apiFiles = [ 'login.ts', 'register.ts', 'logout.ts', 'refresh.ts', 'profile.ts' ]; for (const file of apiFiles) { await fs.copy(path.join(templatePath, 'api', file), path.join(apiPath, file)); } } async generateUploadFeature() { // 实现文件上传功能生成 } async generateEmailFeature() { // 实现邮件功能生成 } async generatePaymentFeature() { // 实现支付功能生成 } async generateRealtimeFeature() { // 实现实时功能生成 } async generatePages() { const pagesPath = path.join(this.projectPath, 'pages'); await fs.ensureDir(pagesPath); const templatePath = path.join(__dirname, '../templates/pages'); // 基础页面 const basePages = ['_app.tsx', '_document.tsx', 'index.tsx']; for (const page of basePages) { const pageTemplate = await fs.readFile(path.join(templatePath, `${page}.mustache`), 'utf-8'); const pageContent = mustache.render(pageTemplate, this.config); await fs.writeFile(path.join(pagesPath, page), pageContent); } // 认证页面 if (this.config.auth) { const authPages = ['login.tsx', 'register.tsx']; for (const page of authPages) { await fs.copy(path.join(templatePath, 'auth', page), path.join(pagesPath, page)); } } // 管理页面 if (this.config.admin) { const adminPath = path.join(pagesPath, 'admin'); await fs.ensureDir(adminPath); await fs.copy(path.join(templatePath, 'admin'), adminPath); } } async copyStaticFiles() { const staticPath = path.join(__dirname, '../templates/static'); const publicPath = path.join(this.projectPath, 'public'); await fs.copy(staticPath, publicPath); // 创建其他必要目录 const dirs = [ 'components/ui', 'components/layout', 'components/forms', 'lib/services', 'lib/hooks', 'lib/stores', 'lib/utils', 'lib/validations', 'types', 'styles' ]; for (const dir of dirs) { await fs.ensureDir(path.join(this.projectPath, dir)); } // 生成README const readmeTemplate = await fs.readFile(path.join(__dirname, '../templates/README.md.mustache'), 'utf-8'); const readmeContent = mustache.render(readmeTemplate, { projectName: this.projectName, ...this.config }); await fs.writeFile(path.join(this.projectPath, 'README.md'), readmeContent); } } //# sourceMappingURL=generator.js.map