servcraft 0.3.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -0
- package/ROADMAP.md +53 -14
- package/dist/cli/index.cjs +458 -146
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +458 -146
- package/dist/cli/index.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/commands/generate.ts +25 -10
- package/src/cli/commands/scaffold.ts +211 -0
- package/src/cli/commands/templates.ts +147 -0
- package/src/cli/index.ts +8 -0
- package/src/cli/utils/template-loader.ts +80 -0
package/dist/cli/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../node_modules/tsup/assets/cjs_shims.js","../../src/cli/index.ts","../../src/cli/commands/init.ts","../../src/cli/utils/helpers.ts","../../src/cli/utils/dry-run.ts","../../src/cli/commands/generate.ts","../../src/cli/utils/field-parser.ts","../../src/cli/utils/error-handler.ts","../../src/cli/templates/controller.ts","../../src/cli/templates/service.ts","../../src/cli/templates/repository.ts","../../src/cli/templates/types.ts","../../src/cli/templates/schemas.ts","../../src/cli/templates/routes.ts","../../src/cli/templates/module-index.ts","../../src/cli/templates/prisma-model.ts","../../src/cli/templates/dynamic-types.ts","../../src/cli/templates/dynamic-schemas.ts","../../src/cli/templates/dynamic-prisma.ts","../../src/cli/templates/controller-test.ts","../../src/cli/templates/service-test.ts","../../src/cli/templates/integration-test.ts","../../src/cli/commands/add-module.ts","../../src/cli/utils/env-manager.ts","../../src/cli/utils/template-manager.ts","../../src/cli/utils/interactive-prompt.ts","../../src/cli/commands/db.ts","../../src/cli/commands/docs.ts","../../src/cli/utils/docs-generator.ts","../../src/core/server.ts","../../src/core/logger.ts","../../src/utils/errors.ts","../../src/config/env.ts","../../src/config/index.ts","../../src/middleware/error-handler.ts","../../src/middleware/security.ts","../../src/modules/swagger/swagger.service.ts","../../src/modules/auth/index.ts","../../src/modules/auth/auth.service.ts","../../src/modules/auth/schemas.ts","../../src/utils/response.ts","../../src/modules/validation/validator.ts","../../src/modules/auth/auth.controller.ts","../../src/modules/auth/auth.middleware.ts","../../src/modules/auth/auth.routes.ts","../../src/database/prisma.ts","../../src/utils/pagination.ts","../../src/modules/user/user.repository.ts","../../src/modules/user/types.ts","../../src/modules/user/user.service.ts","../../src/modules/user/schemas.ts","../../src/modules/user/user.controller.ts","../../src/modules/user/user.routes.ts","../../src/modules/user/index.ts","../../src/cli/commands/list.ts","../../src/cli/commands/remove.ts","../../src/cli/commands/doctor.ts","../../src/cli/commands/update.ts","../../src/cli/commands/completion.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { initCommand } from './commands/init.js';\nimport { generateCommand } from './commands/generate.js';\nimport { addModuleCommand } from './commands/add-module.js';\nimport { dbCommand } from './commands/db.js';\nimport { docsCommand } from './commands/docs.js';\nimport { listCommand } from './commands/list.js';\nimport { removeCommand } from './commands/remove.js';\nimport { doctorCommand } from './commands/doctor.js';\nimport { updateCommand } from './commands/update.js';\nimport { completionCommand } from './commands/completion.js';\n\nconst program = new Command();\n\nprogram\n .name('servcraft')\n .description('Servcraft - A modular Node.js backend framework CLI')\n .version('0.1.0');\n\n// Initialize new project\nprogram.addCommand(initCommand);\n\n// Generate resources (controller, service, model, etc.)\nprogram.addCommand(generateCommand);\n\n// Add pre-built modules\nprogram.addCommand(addModuleCommand);\n\n// Database commands\nprogram.addCommand(dbCommand);\n\n// Documentation commands\nprogram.addCommand(docsCommand);\n\n// List modules\nprogram.addCommand(listCommand);\n\n// Remove module\nprogram.addCommand(removeCommand);\n\n// Diagnose project\nprogram.addCommand(doctorCommand);\n\n// Update modules\nprogram.addCommand(updateCommand);\n\n// Shell completion\nprogram.addCommand(completionCommand);\n\nprogram.parse();\n","import { Command } from 'commander';\nimport path from 'path';\nimport fs from 'fs/promises';\nimport ora from 'ora';\nimport inquirer from 'inquirer';\nimport chalk from 'chalk';\nimport { execSync } from 'child_process';\nimport { ensureDir, writeFile, error, warn } from '../utils/helpers.js';\nimport { DryRunManager } from '../utils/dry-run.js';\n\ninterface InitOptions {\n name: string;\n language: 'typescript' | 'javascript';\n moduleSystem: 'esm' | 'commonjs';\n database: 'postgresql' | 'mysql' | 'sqlite' | 'mongodb' | 'none';\n orm: 'prisma' | 'mongoose' | 'none';\n validator: 'zod' | 'joi' | 'yup';\n features: string[];\n}\n\nexport const initCommand = new Command('init')\n .alias('new')\n .description('Initialize a new Servcraft project')\n .argument('[name]', 'Project name')\n .option('-y, --yes', 'Skip prompts and use defaults')\n .option('--ts, --typescript', 'Use TypeScript (default)')\n .option('--js, --javascript', 'Use JavaScript')\n .option('--esm', 'Use ES Modules (import/export) - default')\n .option('--cjs, --commonjs', 'Use CommonJS (require/module.exports)')\n .option('--db <database>', 'Database type (postgresql, mysql, sqlite, mongodb, none)')\n .option('--dry-run', 'Preview changes without writing files')\n .action(\n async (\n name?: string,\n cmdOptions?: {\n yes?: boolean;\n typescript?: boolean;\n javascript?: boolean;\n esm?: boolean;\n commonjs?: boolean;\n db?: string;\n dryRun?: boolean;\n }\n ) => {\n // Enable dry-run mode if specified\n const dryRun = DryRunManager.getInstance();\n if (cmdOptions?.dryRun) {\n dryRun.enable();\n console.log(chalk.yellow('\\n⚠ DRY RUN MODE - No files will be written\\n'));\n }\n\n console.log(\n chalk.blue(`\n╔═══════════════════════════════════════════╗\n║ ║\n║ ${chalk.bold('🚀 Servcraft Project Generator')} ║\n║ ║\n╚═══════════════════════════════════════════╝\n`)\n );\n\n let options: InitOptions;\n\n if (cmdOptions?.yes) {\n const db = (cmdOptions.db as InitOptions['database']) || 'postgresql';\n options = {\n name: name || 'my-servcraft-app',\n language: cmdOptions.javascript ? 'javascript' : 'typescript',\n moduleSystem: cmdOptions.commonjs ? 'commonjs' : 'esm',\n database: db,\n orm: db === 'mongodb' ? 'mongoose' : db === 'none' ? 'none' : 'prisma',\n validator: 'zod',\n features: ['auth', 'users', 'email'],\n };\n } else {\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'name',\n message: 'Project name:',\n default: name || 'my-servcraft-app',\n validate: (input: string) => {\n if (!/^[a-z0-9-_]+$/i.test(input)) {\n return 'Project name can only contain letters, numbers, hyphens, and underscores';\n }\n return true;\n },\n },\n {\n type: 'list',\n name: 'language',\n message: 'Select language:',\n choices: [\n { name: 'TypeScript (Recommended)', value: 'typescript' },\n { name: 'JavaScript', value: 'javascript' },\n ],\n default: 'typescript',\n },\n {\n type: 'list',\n name: 'moduleSystem',\n message: 'Select module system:',\n choices: [\n { name: 'ESM (import/export) - Recommended', value: 'esm' },\n { name: 'CommonJS (require/module.exports)', value: 'commonjs' },\n ],\n default: 'esm',\n },\n {\n type: 'list',\n name: 'database',\n message: 'Select database:',\n choices: [\n { name: 'PostgreSQL (Recommended for SQL)', value: 'postgresql' },\n { name: 'MySQL', value: 'mysql' },\n { name: 'SQLite (Development)', value: 'sqlite' },\n { name: 'MongoDB (NoSQL)', value: 'mongodb' },\n { name: 'None (Add later)', value: 'none' },\n ],\n default: 'postgresql',\n },\n {\n type: 'list',\n name: 'validator',\n message: 'Select validation library:',\n choices: [\n { name: 'Zod (Recommended - TypeScript-first)', value: 'zod' },\n { name: 'Joi (Battle-tested, feature-rich)', value: 'joi' },\n { name: 'Yup (Inspired by Joi, lighter)', value: 'yup' },\n ],\n default: 'zod',\n },\n {\n type: 'checkbox',\n name: 'features',\n message: 'Select features to include:',\n choices: [\n { name: 'Authentication (JWT)', value: 'auth', checked: true },\n { name: 'User Management', value: 'users', checked: true },\n { name: 'Email Service', value: 'email', checked: true },\n { name: 'Audit Logs', value: 'audit', checked: false },\n { name: 'File Upload', value: 'upload', checked: false },\n { name: 'Redis Cache', value: 'redis', checked: false },\n ],\n },\n ]);\n\n // Auto-determine ORM based on database choice\n const db = answers.database as InitOptions['database'];\n options = {\n ...answers,\n orm: db === 'mongodb' ? 'mongoose' : db === 'none' ? 'none' : 'prisma',\n } as InitOptions;\n }\n\n const projectDir = path.resolve(process.cwd(), options.name);\n const spinner = ora('Creating project...').start();\n\n try {\n // Check if directory exists\n try {\n await fs.access(projectDir);\n spinner.stop();\n error(`Directory \"${options.name}\" already exists`);\n return;\n } catch {\n // Directory doesn't exist, continue\n }\n\n // Create project directory\n await ensureDir(projectDir);\n\n spinner.text = 'Generating project files...';\n\n // Generate package.json\n const packageJson = generatePackageJson(options);\n await writeFile(\n path.join(projectDir, 'package.json'),\n JSON.stringify(packageJson, null, 2)\n );\n\n // Generate tsconfig or jsconfig\n if (options.language === 'typescript') {\n await writeFile(path.join(projectDir, 'tsconfig.json'), generateTsConfig(options));\n await writeFile(path.join(projectDir, 'tsup.config.ts'), generateTsupConfig(options));\n } else {\n await writeFile(path.join(projectDir, 'jsconfig.json'), generateJsConfig(options));\n }\n\n // Generate .env files\n await writeFile(path.join(projectDir, '.env.example'), generateEnvExample(options));\n await writeFile(path.join(projectDir, '.env'), generateEnvExample(options));\n\n // Generate .gitignore\n await writeFile(path.join(projectDir, '.gitignore'), generateGitignore());\n\n // Generate Docker files\n await writeFile(path.join(projectDir, 'Dockerfile'), generateDockerfile(options));\n await writeFile(\n path.join(projectDir, 'docker-compose.yml'),\n generateDockerCompose(options)\n );\n\n // Create directory structure\n // For JS: .js for ESM, .cjs for CommonJS\n // For TS: always .ts (output format handled by tsup)\n const ext =\n options.language === 'typescript' ? 'ts' : options.moduleSystem === 'esm' ? 'js' : 'cjs';\n const dirs = [\n 'src/core',\n 'src/config',\n 'src/modules',\n 'src/middleware',\n 'src/utils',\n 'src/types',\n 'tests/unit',\n 'tests/integration',\n ];\n\n if (options.orm === 'prisma') {\n dirs.push('prisma');\n }\n if (options.orm === 'mongoose') {\n dirs.push('src/database/models');\n }\n\n for (const dir of dirs) {\n await ensureDir(path.join(projectDir, dir));\n }\n\n // Generate main entry file\n await writeFile(path.join(projectDir, `src/index.${ext}`), generateEntryFile(options));\n\n // Generate core files\n await writeFile(\n path.join(projectDir, `src/core/server.${ext}`),\n generateServerFile(options)\n );\n await writeFile(\n path.join(projectDir, `src/core/logger.${ext}`),\n generateLoggerFile(options)\n );\n\n // Generate config file\n await writeFile(\n path.join(projectDir, `src/config/index.${ext}`),\n generateConfigFile(options)\n );\n\n // Generate middleware file\n await writeFile(\n path.join(projectDir, `src/middleware/index.${ext}`),\n generateMiddlewareFile(options)\n );\n\n // Generate utils file\n await writeFile(\n path.join(projectDir, `src/utils/index.${ext}`),\n generateUtilsFile(options)\n );\n\n // Generate types file\n await writeFile(\n path.join(projectDir, `src/types/index.${ext}`),\n generateTypesFile(options)\n );\n\n // Generate database files based on ORM choice\n if (options.orm === 'prisma') {\n await writeFile(\n path.join(projectDir, 'prisma/schema.prisma'),\n generatePrismaSchema(options)\n );\n } else if (options.orm === 'mongoose') {\n await writeFile(\n path.join(projectDir, `src/database/connection.${ext}`),\n generateMongooseConnection(options)\n );\n await writeFile(\n path.join(projectDir, `src/database/models/user.model.${ext}`),\n generateMongooseUserModel(options)\n );\n }\n\n spinner.succeed('Project files generated!');\n\n // Install dependencies (skip in dry-run mode)\n if (!cmdOptions?.dryRun) {\n const installSpinner = ora('Installing dependencies...').start();\n\n try {\n execSync('npm install', { cwd: projectDir, stdio: 'pipe' });\n installSpinner.succeed('Dependencies installed!');\n } catch {\n installSpinner.warn('Failed to install dependencies automatically');\n warn(' Run \"npm install\" manually in the project directory');\n }\n }\n\n // Print success message\n if (!cmdOptions?.dryRun) {\n console.log('\\n' + chalk.green('✨ Project created successfully!'));\n }\n console.log('\\n' + chalk.bold('📁 Project structure:'));\n console.log(`\n ${options.name}/\n ├── src/\n │ ├── core/ # Core server, logger\n │ ├── config/ # Configuration\n │ ├── modules/ # Feature modules\n │ ├── middleware/ # Middlewares\n │ ├── utils/ # Utilities\n │ └── index.${ext} # Entry point\n ├── tests/ # Tests\n ├── prisma/ # Database schema\n ├── docker-compose.yml\n └── package.json\n`);\n\n console.log(chalk.bold('🚀 Get started:'));\n console.log(`\n ${chalk.cyan(`cd ${options.name}`)}\n ${options.database !== 'none' ? chalk.cyan('npm run db:push # Setup database') : ''}\n ${chalk.cyan('npm run dev # Start development server')}\n`);\n\n console.log(chalk.bold('📚 Available commands:'));\n console.log(`\n ${chalk.yellow('servcraft generate module <name>')} Generate a new module\n ${chalk.yellow('servcraft generate controller <name>')} Generate a controller\n ${chalk.yellow('servcraft generate service <name>')} Generate a service\n ${chalk.yellow('servcraft add auth')} Add authentication module\n`);\n\n // Show dry-run summary if enabled\n if (cmdOptions?.dryRun) {\n dryRun.printSummary();\n }\n } catch (err) {\n spinner.fail('Failed to create project');\n error(err instanceof Error ? err.message : String(err));\n }\n }\n );\n\nfunction generatePackageJson(options: InitOptions): Record<string, unknown> {\n const isTS = options.language === 'typescript';\n const isESM = options.moduleSystem === 'esm';\n\n // Determine dev command based on language and module system\n let devCommand: string;\n if (isTS) {\n devCommand = 'tsx watch src/index.ts';\n } else if (isESM) {\n devCommand = 'node --watch src/index.js';\n } else {\n devCommand = 'node --watch src/index.cjs';\n }\n\n // Determine start command\n let startCommand: string;\n if (isTS) {\n startCommand = isESM ? 'node dist/index.js' : 'node dist/index.cjs';\n } else if (isESM) {\n startCommand = 'node src/index.js';\n } else {\n startCommand = 'node src/index.cjs';\n }\n\n const pkg: Record<string, unknown> = {\n name: options.name,\n version: '0.1.0',\n description: 'A Servcraft application',\n main: isTS\n ? isESM\n ? 'dist/index.js'\n : 'dist/index.cjs'\n : isESM\n ? 'src/index.js'\n : 'src/index.cjs',\n ...(isESM && { type: 'module' }),\n scripts: {\n dev: devCommand,\n build: isTS ? 'tsup' : 'echo \"No build needed for JS\"',\n start: startCommand,\n test: 'vitest',\n lint: isTS ? 'eslint src --ext .ts' : 'eslint src --ext .js,.cjs',\n },\n dependencies: {\n fastify: '^4.28.1',\n '@fastify/cors': '^9.0.1',\n '@fastify/helmet': '^11.1.1',\n '@fastify/jwt': '^8.0.1',\n '@fastify/rate-limit': '^9.1.0',\n '@fastify/cookie': '^9.3.1',\n pino: '^9.5.0',\n 'pino-pretty': '^11.3.0',\n bcryptjs: '^2.4.3',\n dotenv: '^16.4.5',\n },\n devDependencies: {\n vitest: '^2.1.8',\n },\n };\n\n // Add validator library based on choice\n switch (options.validator) {\n case 'zod':\n (pkg.dependencies as Record<string, string>).zod = '^3.23.8';\n break;\n case 'joi':\n (pkg.dependencies as Record<string, string>).joi = '^17.13.3';\n break;\n case 'yup':\n (pkg.dependencies as Record<string, string>).yup = '^1.4.0';\n break;\n }\n\n if (isTS) {\n (pkg.devDependencies as Record<string, string>).typescript = '^5.7.2';\n (pkg.devDependencies as Record<string, string>).tsx = '^4.19.2';\n (pkg.devDependencies as Record<string, string>).tsup = '^8.3.5';\n (pkg.devDependencies as Record<string, string>)['@types/node'] = '^22.10.1';\n (pkg.devDependencies as Record<string, string>)['@types/bcryptjs'] = '^2.4.6';\n }\n\n if (options.orm === 'prisma') {\n (pkg.dependencies as Record<string, string>)['@prisma/client'] = '^5.22.0';\n (pkg.devDependencies as Record<string, string>).prisma = '^5.22.0';\n (pkg.scripts as Record<string, string>)['db:generate'] = 'prisma generate';\n (pkg.scripts as Record<string, string>)['db:migrate'] = 'prisma migrate dev';\n (pkg.scripts as Record<string, string>)['db:push'] = 'prisma db push';\n (pkg.scripts as Record<string, string>)['db:studio'] = 'prisma studio';\n }\n\n if (options.orm === 'mongoose') {\n (pkg.dependencies as Record<string, string>).mongoose = '^8.8.4';\n if (isTS) {\n (pkg.devDependencies as Record<string, string>)['@types/mongoose'] = '^5.11.97';\n }\n }\n\n if (options.features.includes('email')) {\n (pkg.dependencies as Record<string, string>).nodemailer = '^6.9.15';\n (pkg.dependencies as Record<string, string>).handlebars = '^4.7.8';\n if (isTS) {\n (pkg.devDependencies as Record<string, string>)['@types/nodemailer'] = '^6.4.17';\n }\n }\n\n if (options.features.includes('redis')) {\n (pkg.dependencies as Record<string, string>).ioredis = '^5.4.1';\n }\n\n return pkg;\n}\n\nfunction generateTsConfig(options: InitOptions): string {\n const isESM = options.moduleSystem === 'esm';\n\n return JSON.stringify(\n {\n compilerOptions: {\n target: 'ES2022',\n module: isESM ? 'NodeNext' : 'CommonJS',\n moduleResolution: isESM ? 'NodeNext' : 'Node',\n lib: ['ES2022'],\n outDir: './dist',\n rootDir: './src',\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n forceConsistentCasingInFileNames: true,\n resolveJsonModule: true,\n declaration: true,\n sourceMap: true,\n },\n include: ['src/**/*'],\n exclude: ['node_modules', 'dist'],\n },\n null,\n 2\n );\n}\n\nfunction generateJsConfig(options: InitOptions): string {\n const isESM = options.moduleSystem === 'esm';\n\n return JSON.stringify(\n {\n compilerOptions: {\n module: isESM ? 'NodeNext' : 'CommonJS',\n moduleResolution: isESM ? 'NodeNext' : 'Node',\n target: 'ES2022',\n checkJs: true,\n },\n include: ['src/**/*'],\n exclude: ['node_modules'],\n },\n null,\n 2\n );\n}\n\nfunction generateTsupConfig(options: InitOptions): string {\n const isESM = options.moduleSystem === 'esm';\n\n return `import { defineConfig } from 'tsup';\n\nexport default defineConfig({\n entry: ['src/index.ts'],\n format: ['${isESM ? 'esm' : 'cjs'}'],\n dts: true,\n clean: true,\n sourcemap: true,\n target: 'node18',\n});\n`;\n}\n\nfunction generateEnvExample(options: InitOptions): string {\n let env = `# Server\nNODE_ENV=development\nPORT=3000\nHOST=0.0.0.0\n\n# JWT\nJWT_SECRET=your-super-secret-key-min-32-characters\nJWT_ACCESS_EXPIRES_IN=15m\nJWT_REFRESH_EXPIRES_IN=7d\n\n# Security\nCORS_ORIGIN=http://localhost:3000\nRATE_LIMIT_MAX=100\n\n# Logging\nLOG_LEVEL=info\n`;\n\n if (options.database === 'postgresql') {\n env += `\n# Database (PostgreSQL)\nDATABASE_PROVIDER=postgresql\nDATABASE_URL=\"postgresql://user:password@localhost:5432/mydb?schema=public\"\n`;\n } else if (options.database === 'mysql') {\n env += `\n# Database (MySQL)\nDATABASE_PROVIDER=mysql\nDATABASE_URL=\"mysql://user:password@localhost:3306/mydb\"\n`;\n } else if (options.database === 'sqlite') {\n env += `\n# Database (SQLite)\nDATABASE_PROVIDER=sqlite\nDATABASE_URL=\"file:./dev.db\"\n`;\n } else if (options.database === 'mongodb') {\n env += `\n# Database (MongoDB)\nMONGODB_URI=\"mongodb://localhost:27017/mydb\"\n`;\n }\n\n if (options.features.includes('email')) {\n env += `\n# Email\nSMTP_HOST=smtp.example.com\nSMTP_PORT=587\nSMTP_USER=\nSMTP_PASS=\nSMTP_FROM=\"App <noreply@example.com>\"\n`;\n }\n\n if (options.features.includes('redis')) {\n env += `\n# Redis\nREDIS_URL=redis://localhost:6379\n`;\n }\n\n return env;\n}\n\nfunction generateGitignore(): string {\n return `node_modules/\ndist/\n.env\n.env.local\n*.log\ncoverage/\n.DS_Store\n*.db\n`;\n}\n\nfunction generateDockerfile(options: InitOptions): string {\n const isTS = options.language === 'typescript';\n\n return `FROM node:20-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci --only=production\nCOPY ${isTS ? 'dist' : 'src'} ./${isTS ? 'dist' : 'src'}\n${options.database !== 'none' && options.database !== 'mongodb' ? 'COPY prisma ./prisma\\nRUN npx prisma generate' : ''}\nEXPOSE 3000\nCMD [\"node\", \"${isTS ? 'dist' : 'src'}/index.js\"]\n`;\n}\n\nfunction generateDockerCompose(options: InitOptions): string {\n let compose = `version: '3.8'\n\nservices:\n app:\n build: .\n ports:\n - \"\\${PORT:-3000}:3000\"\n environment:\n - NODE_ENV=development\n`;\n\n if (options.database === 'postgresql') {\n compose += ` - DATABASE_URL=postgresql://postgres:postgres@postgres:5432/mydb\n depends_on:\n - postgres\n\n postgres:\n image: postgres:16-alpine\n environment:\n POSTGRES_USER: postgres\n POSTGRES_PASSWORD: postgres\n POSTGRES_DB: mydb\n ports:\n - \"5432:5432\"\n volumes:\n - postgres-data:/var/lib/postgresql/data\n\nvolumes:\n postgres-data:\n`;\n } else if (options.database === 'mysql') {\n compose += ` - DATABASE_URL=mysql://root:root@mysql:3306/mydb\n depends_on:\n - mysql\n\n mysql:\n image: mysql:8.0\n environment:\n MYSQL_ROOT_PASSWORD: root\n MYSQL_DATABASE: mydb\n ports:\n - \"3306:3306\"\n volumes:\n - mysql-data:/var/lib/mysql\n\nvolumes:\n mysql-data:\n`;\n } else if (options.database === 'mongodb') {\n compose += ` - MONGODB_URI=mongodb://mongodb:27017/mydb\n depends_on:\n - mongodb\n\n mongodb:\n image: mongo:7\n environment:\n MONGO_INITDB_DATABASE: mydb\n ports:\n - \"27017:27017\"\n volumes:\n - mongodb-data:/data/db\n\nvolumes:\n mongodb-data:\n`;\n }\n\n if (options.features.includes('redis')) {\n compose += `\n redis:\n image: redis:7-alpine\n ports:\n - \"6379:6379\"\n`;\n }\n\n return compose;\n}\n\nfunction generatePrismaSchema(options: InitOptions): string {\n const provider = options.database === 'sqlite' ? 'sqlite' : options.database;\n\n return `generator client {\n provider = \"prisma-client-js\"\n}\n\ndatasource db {\n provider = \"${provider}\"\n url = env(\"DATABASE_URL\")\n}\n\nmodel User {\n id String @id @default(uuid())\n email String @unique\n password String\n name String?\n role String @default(\"user\")\n status String @default(\"active\")\n emailVerified Boolean @default(false)\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@map(\"users\")\n}\n`;\n}\n\nfunction generateEntryFile(options: InitOptions): string {\n const isTS = options.language === 'typescript';\n const isESM = options.moduleSystem === 'esm';\n const fileExt = isTS ? 'js' : isESM ? 'js' : 'cjs';\n\n if (isESM || isTS) {\n return `import 'dotenv/config';\nimport { createServer } from './core/server.${fileExt}';\nimport { logger } from './core/logger.${fileExt}';\n\nasync function main()${isTS ? ': Promise<void>' : ''} {\n const server = createServer();\n\n try {\n await server.start();\n } catch (error) {\n logger.error({ err: error }, 'Failed to start server');\n process.exit(1);\n }\n}\n\nmain();\n`;\n } else {\n // CommonJS\n return `require('dotenv').config();\nconst { createServer } = require('./core/server.cjs');\nconst { logger } = require('./core/logger.cjs');\n\nasync function main() {\n const server = createServer();\n\n try {\n await server.start();\n } catch (error) {\n logger.error({ err: error }, 'Failed to start server');\n process.exit(1);\n }\n}\n\nmain();\n`;\n }\n}\n\nfunction generateServerFile(options: InitOptions): string {\n const isTS = options.language === 'typescript';\n const isESM = options.moduleSystem === 'esm';\n const fileExt = isTS ? 'js' : isESM ? 'js' : 'cjs';\n\n const serverBody = ` const app = Fastify({ logger });\n\n // Health check\n app.get('/health', async () => ({\n status: 'ok',\n timestamp: new Date().toISOString(),\n }));\n\n // Graceful shutdown\n const signals${isTS ? ': NodeJS.Signals[]' : ''} = ['SIGINT', 'SIGTERM'];\n signals.forEach((signal) => {\n process.on(signal, async () => {\n logger.info(\\`Received \\${signal}, shutting down...\\`);\n await app.close();\n process.exit(0);\n });\n });\n\n return {\n instance: app,\n start: async ()${isTS ? ': Promise<void>' : ''} => {\n const port = parseInt(process.env.PORT || '3000', 10);\n const host = process.env.HOST || '0.0.0.0';\n await app.listen({ port, host });\n logger.info(\\`Server listening on \\${host}:\\${port}\\`);\n },\n };\n}`;\n\n if (isESM || isTS) {\n return `import Fastify from 'fastify';\n${isTS ? \"import type { FastifyInstance } from 'fastify';\" : ''}\nimport { logger } from './logger.${fileExt}';\n\n${isTS ? 'export function createServer(): { instance: FastifyInstance; start: () => Promise<void> }' : 'export function createServer()'} {\n${serverBody}\n`;\n } else {\n // CommonJS\n return `const Fastify = require('fastify');\nconst { logger } = require('./logger.cjs');\n\nfunction createServer() {\n${serverBody}\n\nmodule.exports = { createServer };\n`;\n }\n}\n\nfunction generateLoggerFile(options: InitOptions): string {\n const isTS = options.language === 'typescript';\n const isESM = options.moduleSystem === 'esm';\n\n const loggerBody = `pino({\n level: process.env.LOG_LEVEL || 'info',\n transport: process.env.NODE_ENV !== 'production' ? {\n target: 'pino-pretty',\n options: { colorize: true },\n } : undefined,\n})`;\n\n if (isESM || isTS) {\n return `import pino from 'pino';\n${isTS ? \"import type { Logger } from 'pino';\" : ''}\n\nexport const logger${isTS ? ': Logger' : ''} = ${loggerBody};\n`;\n } else {\n // CommonJS\n return `const pino = require('pino');\n\nconst logger = ${loggerBody};\n\nmodule.exports = { logger };\n`;\n }\n}\n\nfunction generateMongooseConnection(options: InitOptions): string {\n const isTS = options.language === 'typescript';\n const isESM = options.moduleSystem === 'esm';\n const fileExt = isTS ? 'js' : isESM ? 'js' : 'cjs';\n\n const connectionBody = `const MONGODB_URI = process.env.MONGODB_URI || 'mongodb://localhost:27017/mydb';\n\nasync function connectDatabase()${isTS ? ': Promise<typeof mongoose>' : ''} {\n try {\n const conn = await mongoose.connect(MONGODB_URI);\n logger.info(\\`MongoDB connected: \\${conn.connection.host}\\`);\n return conn;\n } catch (error) {\n logger.error({ err: error }, 'MongoDB connection failed');\n process.exit(1);\n }\n}\n\nasync function disconnectDatabase()${isTS ? ': Promise<void>' : ''} {\n try {\n await mongoose.disconnect();\n logger.info('MongoDB disconnected');\n } catch (error) {\n logger.error({ err: error }, 'MongoDB disconnect failed');\n }\n}`;\n\n if (isESM || isTS) {\n return `import mongoose from 'mongoose';\nimport { logger } from '../core/logger.${fileExt}';\n\n${connectionBody}\n\nexport { connectDatabase, disconnectDatabase, mongoose };\n`;\n } else {\n // CommonJS\n return `const mongoose = require('mongoose');\nconst { logger } = require('../core/logger.cjs');\n\n${connectionBody}\n\nmodule.exports = { connectDatabase, disconnectDatabase, mongoose };\n`;\n }\n}\n\nfunction generateMongooseUserModel(options: InitOptions): string {\n const isTS = options.language === 'typescript';\n const isESM = options.moduleSystem === 'esm';\n\n const schemaBody = `const userSchema = new Schema${isTS ? '<IUser>' : ''}({\n email: {\n type: String,\n required: true,\n unique: true,\n lowercase: true,\n trim: true,\n },\n password: {\n type: String,\n required: true,\n minlength: 8,\n },\n name: {\n type: String,\n trim: true,\n },\n role: {\n type: String,\n enum: ['user', 'admin'],\n default: 'user',\n },\n status: {\n type: String,\n enum: ['active', 'inactive', 'suspended'],\n default: 'active',\n },\n emailVerified: {\n type: Boolean,\n default: false,\n },\n}, {\n timestamps: true,\n});\n\n// Hash password before saving\nuserSchema.pre('save', async function(next) {\n if (!this.isModified('password')) return next();\n\n try {\n const salt = await bcrypt.genSalt(10);\n this.password = await bcrypt.hash(this.password, salt);\n next();\n } catch (error${isTS ? ': any' : ''}) {\n next(error);\n }\n});\n\n// Compare password method\nuserSchema.methods.comparePassword = async function(candidatePassword${isTS ? ': string' : ''})${isTS ? ': Promise<boolean>' : ''} {\n return bcrypt.compare(candidatePassword, this.password);\n};`;\n\n const tsInterface = isTS\n ? `\nexport interface IUser extends Document {\n email: string;\n password: string;\n name?: string;\n role: 'user' | 'admin';\n status: 'active' | 'inactive' | 'suspended';\n emailVerified: boolean;\n createdAt: Date;\n updatedAt: Date;\n comparePassword(candidatePassword: string): Promise<boolean>;\n}\n`\n : '';\n\n if (isESM || isTS) {\n return `import mongoose${isTS ? ', { Schema, Document }' : ''} from 'mongoose';\nimport bcrypt from 'bcryptjs';\n${!isTS ? 'const { Schema } = mongoose;' : ''}\n${tsInterface}\n${schemaBody}\n\nexport const User = mongoose.model${isTS ? '<IUser>' : ''}('User', userSchema);\n`;\n } else {\n // CommonJS\n return `const mongoose = require('mongoose');\nconst bcrypt = require('bcryptjs');\nconst { Schema } = mongoose;\n\n${schemaBody}\n\nconst User = mongoose.model('User', userSchema);\n\nmodule.exports = { User };\n`;\n }\n}\n\nfunction generateConfigFile(options: InitOptions): string {\n const isTS = options.language === 'typescript';\n const isESM = options.moduleSystem === 'esm';\n\n const configBody = `{\n env: process.env.NODE_ENV || 'development',\n port: parseInt(process.env.PORT || '3000', 10),\n host: process.env.HOST || '0.0.0.0',\n\n jwt: {\n secret: process.env.JWT_SECRET || 'your-secret-key',\n accessExpiresIn: process.env.JWT_ACCESS_EXPIRES_IN || '15m',\n refreshExpiresIn: process.env.JWT_REFRESH_EXPIRES_IN || '7d',\n },\n\n cors: {\n origin: process.env.CORS_ORIGIN || 'http://localhost:3000',\n },\n\n rateLimit: {\n max: parseInt(process.env.RATE_LIMIT_MAX || '100', 10),\n },\n\n log: {\n level: process.env.LOG_LEVEL || 'info',\n },\n}${isTS ? ' as const' : ''}`;\n\n if (isESM || isTS) {\n return `import 'dotenv/config';\n\nexport const config = ${configBody};\n`;\n } else {\n // CommonJS\n return `require('dotenv').config();\n\nconst config = ${configBody};\n\nmodule.exports = { config };\n`;\n }\n}\n\nfunction generateMiddlewareFile(options: InitOptions): string {\n const isTS = options.language === 'typescript';\n const isESM = options.moduleSystem === 'esm';\n const fileExt = isTS ? 'js' : isESM ? 'js' : 'cjs';\n\n const middlewareBody = `/**\n * Error handler middleware\n */\nfunction errorHandler(error${isTS ? ': Error' : ''}, request${isTS ? ': FastifyRequest' : ''}, reply${isTS ? ': FastifyReply' : ''})${isTS ? ': void' : ''} {\n logger.error({ err: error, url: request.url, method: request.method }, 'Request error');\n\n const statusCode = (error${isTS ? ' as any' : ''}).statusCode || 500;\n const message = statusCode === 500 ? 'Internal Server Error' : error.message;\n\n reply.status(statusCode).send({\n success: false,\n error: message,\n ...(process.env.NODE_ENV === 'development' && { stack: error.stack }),\n });\n}\n\n/**\n * Request logging middleware\n */\nfunction requestLogger(request${isTS ? ': FastifyRequest' : ''}, reply${isTS ? ': FastifyReply' : ''}, done${isTS ? ': () => void' : ''})${isTS ? ': void' : ''} {\n logger.info({ url: request.url, method: request.method, ip: request.ip }, 'Incoming request');\n done();\n}`;\n\n if (isESM || isTS) {\n return `${isTS ? \"import type { FastifyRequest, FastifyReply } from 'fastify';\" : ''}\nimport { logger } from '../core/logger.${fileExt}';\n\n${middlewareBody}\n\nexport { errorHandler, requestLogger };\n`;\n } else {\n // CommonJS\n return `const { logger } = require('../core/logger.cjs');\n\n${middlewareBody}\n\nmodule.exports = { errorHandler, requestLogger };\n`;\n }\n}\n\nfunction generateUtilsFile(options: InitOptions): string {\n const isTS = options.language === 'typescript';\n const isESM = options.moduleSystem === 'esm';\n\n const utilsBody = `/**\n * Standard API response helper\n */\nfunction apiResponse${isTS ? '<T>' : ''}(data${isTS ? ': T' : ''}, message = \"Success\")${isTS ? ': { success: boolean; message: string; data: T }' : ''} {\n return {\n success: true,\n message,\n data,\n };\n}\n\n/**\n * Error response helper\n */\nfunction errorResponse(message${isTS ? ': string' : ''}, code${isTS ? '?: string' : ''})${isTS ? ': { success: boolean; error: string; code?: string }' : ''} {\n return {\n success: false,\n error: message,\n ...(code && { code }),\n };\n}\n\n/**\n * Pagination helper\n */\nfunction paginate${isTS ? '<T>' : ''}(data${isTS ? ': T[]' : ''}, page${isTS ? ': number' : ''}, limit${isTS ? ': number' : ''}, total${isTS ? ': number' : ''})${isTS ? ': PaginationResult<T>' : ''} {\n const totalPages = Math.ceil(total / limit);\n\n return {\n data,\n pagination: {\n page,\n limit,\n total,\n totalPages,\n hasNextPage: page < totalPages,\n hasPrevPage: page > 1,\n },\n };\n}`;\n\n const tsInterface = isTS\n ? `\n/**\n * Pagination result type\n */\nexport interface PaginationResult<T> {\n data: T[];\n pagination: {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n hasNextPage: boolean;\n hasPrevPage: boolean;\n };\n}\n`\n : '';\n\n if (isESM || isTS) {\n return `${tsInterface}\n${utilsBody}\n\nexport { apiResponse, errorResponse, paginate };\n`;\n } else {\n // CommonJS\n return `${utilsBody}\n\nmodule.exports = { apiResponse, errorResponse, paginate };\n`;\n }\n}\n\nfunction generateTypesFile(options: InitOptions): string {\n if (options.language !== 'typescript') {\n return '// Types file - not needed for JavaScript\\n';\n }\n\n return `/**\n * Common type definitions\n */\n\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n message?: string;\n data?: T;\n error?: string;\n code?: string;\n}\n\nexport interface PaginatedResponse<T> {\n data: T[];\n pagination: {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n hasNextPage: boolean;\n hasPrevPage: boolean;\n };\n}\n\nexport interface RequestUser {\n id: string;\n email: string;\n role: string;\n}\n\ndeclare module 'fastify' {\n interface FastifyRequest {\n user?: RequestUser;\n }\n}\n`;\n}\n","import fs from 'fs/promises';\nimport path from 'path';\nimport chalk from 'chalk';\nimport { DryRunManager } from './dry-run.js';\n\nexport function toPascalCase(str: string): string {\n return str\n .split(/[-_\\s]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n}\n\nexport function toCamelCase(str: string): string {\n const pascal = toPascalCase(str);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n}\n\nexport function toKebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n}\n\nexport function toSnakeCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .replace(/[\\s-]+/g, '_')\n .toLowerCase();\n}\n\nexport function pluralize(str: string): string {\n if (str.endsWith('y')) {\n return str.slice(0, -1) + 'ies';\n }\n if (str.endsWith('s') || str.endsWith('x') || str.endsWith('ch') || str.endsWith('sh')) {\n return str + 'es';\n }\n return str + 's';\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function ensureDir(dirPath: string): Promise<void> {\n await fs.mkdir(dirPath, { recursive: true });\n}\n\nexport async function writeFile(filePath: string, content: string): Promise<void> {\n const dryRun = DryRunManager.getInstance();\n\n if (dryRun.isEnabled()) {\n dryRun.addOperation({\n type: 'create',\n path: dryRun.relativePath(filePath),\n content,\n size: content.length,\n });\n return;\n }\n\n await ensureDir(path.dirname(filePath));\n await fs.writeFile(filePath, content, 'utf-8');\n}\n\nexport function log(message: string): void {\n console.log(message);\n}\n\nexport function success(message: string): void {\n console.log(chalk.green('✓'), message);\n}\n\nexport function error(message: string): void {\n console.error(chalk.red('✗'), message);\n}\n\nexport function warn(message: string): void {\n console.log(chalk.yellow('⚠'), message);\n}\n\nexport function info(message: string): void {\n console.log(chalk.blue('ℹ'), message);\n}\n\nexport function getProjectRoot(): string {\n return process.cwd();\n}\n\nexport function getSourceDir(): string {\n return path.join(getProjectRoot(), 'src');\n}\n\nexport function getModulesDir(): string {\n return path.join(getSourceDir(), 'modules');\n}\n","/* eslint-disable no-console */\nimport chalk from 'chalk';\nimport path from 'path';\n\nexport interface FileOperation {\n type: 'create' | 'modify' | 'delete';\n path: string;\n content?: string;\n size?: number;\n}\n\nexport class DryRunManager {\n private static instance: DryRunManager;\n private enabled = false;\n private operations: FileOperation[] = [];\n\n private constructor() {}\n\n static getInstance(): DryRunManager {\n if (!DryRunManager.instance) {\n DryRunManager.instance = new DryRunManager();\n }\n return DryRunManager.instance;\n }\n\n enable(): void {\n this.enabled = true;\n this.operations = [];\n }\n\n disable(): void {\n this.enabled = false;\n this.operations = [];\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n addOperation(operation: FileOperation): void {\n if (this.enabled) {\n this.operations.push(operation);\n }\n }\n\n getOperations(): FileOperation[] {\n return [...this.operations];\n }\n\n printSummary(): void {\n if (!this.enabled || this.operations.length === 0) {\n return;\n }\n\n console.log(chalk.bold.yellow('\\n📋 Dry Run - Preview of changes:\\n'));\n console.log(chalk.gray('No files will be written. Remove --dry-run to apply changes.\\n'));\n\n const createOps = this.operations.filter((op) => op.type === 'create');\n const modifyOps = this.operations.filter((op) => op.type === 'modify');\n const deleteOps = this.operations.filter((op) => op.type === 'delete');\n\n if (createOps.length > 0) {\n console.log(chalk.green.bold(`\\n✓ Files to be created (${createOps.length}):`));\n createOps.forEach((op) => {\n const size = op.content ? `${op.content.length} bytes` : 'unknown size';\n console.log(` ${chalk.green('+')} ${chalk.cyan(op.path)} ${chalk.gray(`(${size})`)}`);\n });\n }\n\n if (modifyOps.length > 0) {\n console.log(chalk.yellow.bold(`\\n~ Files to be modified (${modifyOps.length}):`));\n modifyOps.forEach((op) => {\n console.log(` ${chalk.yellow('~')} ${chalk.cyan(op.path)}`);\n });\n }\n\n if (deleteOps.length > 0) {\n console.log(chalk.red.bold(`\\n- Files to be deleted (${deleteOps.length}):`));\n deleteOps.forEach((op) => {\n console.log(` ${chalk.red('-')} ${chalk.cyan(op.path)}`);\n });\n }\n\n console.log(chalk.gray('\\n' + '─'.repeat(60)));\n console.log(\n chalk.bold(` Total operations: ${this.operations.length}`) +\n chalk.gray(\n ` (${createOps.length} create, ${modifyOps.length} modify, ${deleteOps.length} delete)`\n )\n );\n console.log(chalk.gray('─'.repeat(60)));\n console.log(chalk.yellow('\\n⚠ This was a dry run. No files were created or modified.'));\n console.log(chalk.gray(' Remove --dry-run to apply these changes.\\n'));\n }\n\n // Helper to format file path relative to cwd\n relativePath(filePath: string): string {\n return path.relative(process.cwd(), filePath);\n }\n}\n\n// Wrapper functions for file operations\nexport async function dryRunWriteFile(\n filePath: string,\n content: string,\n actualWriteFn: (path: string, content: string) => Promise<void>\n): Promise<void> {\n const dryRun = DryRunManager.getInstance();\n\n if (dryRun.isEnabled()) {\n dryRun.addOperation({\n type: 'create',\n path: dryRun.relativePath(filePath),\n content,\n size: content.length,\n });\n return;\n }\n\n await actualWriteFn(filePath, content);\n}\n\nexport async function dryRunModifyFile(\n filePath: string,\n actualModifyFn: (path: string) => Promise<void>\n): Promise<void> {\n const dryRun = DryRunManager.getInstance();\n\n if (dryRun.isEnabled()) {\n dryRun.addOperation({\n type: 'modify',\n path: dryRun.relativePath(filePath),\n });\n return;\n }\n\n await actualModifyFn(filePath);\n}\n\nexport async function dryRunDeleteFile(\n filePath: string,\n actualDeleteFn: (path: string) => Promise<void>\n): Promise<void> {\n const dryRun = DryRunManager.getInstance();\n\n if (dryRun.isEnabled()) {\n dryRun.addOperation({\n type: 'delete',\n path: dryRun.relativePath(filePath),\n });\n return;\n }\n\n await actualDeleteFn(filePath);\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport ora from 'ora';\nimport inquirer from 'inquirer';\nimport {\n toPascalCase,\n toCamelCase,\n toKebabCase,\n pluralize,\n fileExists,\n writeFile,\n success,\n error,\n info,\n getModulesDir,\n} from '../utils/helpers.js';\nimport { DryRunManager } from '../utils/dry-run.js';\nimport chalk from 'chalk';\nimport { parseFields, type FieldDefinition } from '../utils/field-parser.js';\nimport { ErrorTypes, displayError } from '../utils/error-handler.js';\n\n// Helper to enable dry-run mode\nfunction enableDryRunIfNeeded(options: { dryRun?: boolean }): void {\n const dryRun = DryRunManager.getInstance();\n if (options.dryRun) {\n dryRun.enable();\n console.log(chalk.yellow('\\n⚠ DRY RUN MODE - No files will be written\\n'));\n }\n}\n\n// Helper to show dry-run summary\nfunction showDryRunSummary(options: { dryRun?: boolean }): void {\n if (options.dryRun) {\n DryRunManager.getInstance().printSummary();\n }\n}\nimport { controllerTemplate } from '../templates/controller.js';\nimport { serviceTemplate } from '../templates/service.js';\nimport { repositoryTemplate } from '../templates/repository.js';\nimport { typesTemplate } from '../templates/types.js';\nimport { schemasTemplate } from '../templates/schemas.js';\nimport { routesTemplate } from '../templates/routes.js';\nimport { moduleIndexTemplate } from '../templates/module-index.js';\nimport { prismaModelTemplate } from '../templates/prisma-model.js';\nimport { dynamicTypesTemplate } from '../templates/dynamic-types.js';\nimport { dynamicSchemasTemplate, type ValidatorType } from '../templates/dynamic-schemas.js';\nimport { dynamicPrismaTemplate } from '../templates/dynamic-prisma.js';\nimport { controllerTestTemplate } from '../templates/controller-test.js';\nimport { serviceTestTemplate } from '../templates/service-test.js';\nimport { integrationTestTemplate } from '../templates/integration-test.js';\n\nexport const generateCommand = new Command('generate')\n .alias('g')\n .description('Generate resources (module, controller, service, etc.)');\n\n// Generate full module\ngenerateCommand\n .command('module <name> [fields...]')\n .alias('m')\n .description(\n 'Generate a complete module with controller, service, repository, types, schemas, and routes'\n )\n .option('--no-routes', 'Skip routes generation')\n .option('--no-repository', 'Skip repository generation')\n .option('--prisma', 'Generate Prisma model suggestion')\n .option('--validator <type>', 'Validator type: zod, joi, yup', 'zod')\n .option('-i, --interactive', 'Interactive mode to define fields')\n .option('--with-tests', 'Generate test files (__tests__ directory)')\n .option('--dry-run', 'Preview changes without writing files')\n .action(async (name: string, fieldsArgs: string[], options) => {\n enableDryRunIfNeeded(options);\n let fields: FieldDefinition[] = [];\n\n // Parse fields from command line or interactive mode\n if (options.interactive) {\n fields = await promptForFields();\n } else if (fieldsArgs.length > 0) {\n fields = parseFields(fieldsArgs.join(' '));\n }\n\n const spinner = ora('Generating module...').start();\n\n try {\n const kebabName = toKebabCase(name);\n const pascalName = toPascalCase(name);\n const camelName = toCamelCase(name);\n const pluralName = pluralize(kebabName);\n const tableName = pluralize(kebabName.replace(/-/g, '_'));\n const validatorType = (options.validator || 'zod') as ValidatorType;\n\n const moduleDir = path.join(getModulesDir(), kebabName);\n\n // Check if module already exists\n if (await fileExists(moduleDir)) {\n spinner.stop();\n error(`Module \"${kebabName}\" already exists`);\n return;\n }\n\n // Use dynamic templates if fields are provided\n const hasFields = fields.length > 0;\n\n const files = [\n {\n name: `${kebabName}.types.ts`,\n content: hasFields\n ? dynamicTypesTemplate(kebabName, pascalName, fields)\n : typesTemplate(kebabName, pascalName),\n },\n {\n name: `${kebabName}.schemas.ts`,\n content: hasFields\n ? dynamicSchemasTemplate(kebabName, pascalName, camelName, fields, validatorType)\n : schemasTemplate(kebabName, pascalName, camelName),\n },\n {\n name: `${kebabName}.service.ts`,\n content: serviceTemplate(kebabName, pascalName, camelName),\n },\n {\n name: `${kebabName}.controller.ts`,\n content: controllerTemplate(kebabName, pascalName, camelName),\n },\n { name: 'index.ts', content: moduleIndexTemplate(kebabName, pascalName, camelName) },\n ];\n\n if (options.repository !== false) {\n files.push({\n name: `${kebabName}.repository.ts`,\n content: repositoryTemplate(kebabName, pascalName, camelName, pluralName),\n });\n }\n\n if (options.routes !== false) {\n files.push({\n name: `${kebabName}.routes.ts`,\n content: routesTemplate(kebabName, pascalName, camelName, pluralName),\n });\n }\n\n // Write all files\n for (const file of files) {\n await writeFile(path.join(moduleDir, file.name), file.content);\n }\n\n // Generate test files if --with-tests flag is provided\n if (options.withTests) {\n const testDir = path.join(moduleDir, '__tests__');\n\n await writeFile(\n path.join(testDir, `${kebabName}.controller.test.ts`),\n controllerTestTemplate(kebabName, pascalName, camelName)\n );\n\n await writeFile(\n path.join(testDir, `${kebabName}.service.test.ts`),\n serviceTestTemplate(kebabName, pascalName, camelName)\n );\n\n await writeFile(\n path.join(testDir, `${kebabName}.integration.test.ts`),\n integrationTestTemplate(kebabName, pascalName, camelName)\n );\n }\n\n spinner.succeed(`Module \"${pascalName}\" generated successfully!`);\n\n // Show Prisma model if requested or fields provided\n if (options.prisma || hasFields) {\n console.log('\\n' + '─'.repeat(50));\n info('Prisma model suggestion:');\n if (hasFields) {\n console.log(dynamicPrismaTemplate(pascalName, tableName, fields));\n } else {\n console.log(prismaModelTemplate(kebabName, pascalName, tableName));\n }\n }\n\n // Show fields summary if provided\n if (hasFields) {\n console.log('\\n📋 Fields defined:');\n fields.forEach((f) => {\n const opts = [];\n if (f.isOptional) opts.push('optional');\n if (f.isArray) opts.push('array');\n if (f.isUnique) opts.push('unique');\n const optsStr = opts.length > 0 ? ` (${opts.join(', ')})` : '';\n success(` ${f.name}: ${f.type}${optsStr}`);\n });\n }\n\n // Show next steps\n console.log('\\n📁 Files created:');\n files.forEach((f) => success(` src/modules/${kebabName}/${f.name}`));\n\n if (options.withTests) {\n success(` src/modules/${kebabName}/__tests__/${kebabName}.controller.test.ts`);\n success(` src/modules/${kebabName}/__tests__/${kebabName}.service.test.ts`);\n success(` src/modules/${kebabName}/__tests__/${kebabName}.integration.test.ts`);\n }\n\n console.log('\\n📌 Next steps:');\n if (!hasFields) {\n info(' 1. Update the types in ' + `${kebabName}.types.ts`);\n info(' 2. Update the schemas in ' + `${kebabName}.schemas.ts`);\n info(' 3. Register the module in your app');\n } else {\n info(' 1. Review generated types and schemas');\n info(' 2. Register the module in your app');\n }\n if (options.prisma || hasFields) {\n info(` ${hasFields ? '3' : '4'}. Add the Prisma model to schema.prisma`);\n info(` ${hasFields ? '4' : '5'}. Run: npm run db:migrate`);\n }\n\n // Show dry-run summary if enabled\n showDryRunSummary(options);\n } catch (err) {\n spinner.fail('Failed to generate module');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\n// Generate controller only\ngenerateCommand\n .command('controller <name>')\n .alias('c')\n .description('Generate a controller')\n .option('-m, --module <module>', 'Target module name')\n .option('--dry-run', 'Preview changes without writing files')\n .action(async (name: string, options) => {\n enableDryRunIfNeeded(options);\n const spinner = ora('Generating controller...').start();\n\n try {\n const kebabName = toKebabCase(name);\n const pascalName = toPascalCase(name);\n const camelName = toCamelCase(name);\n\n const moduleName = options.module ? toKebabCase(options.module) : kebabName;\n const moduleDir = path.join(getModulesDir(), moduleName);\n const filePath = path.join(moduleDir, `${kebabName}.controller.ts`);\n\n if (await fileExists(filePath)) {\n spinner.stop();\n displayError(ErrorTypes.FILE_ALREADY_EXISTS(`${kebabName}.controller.ts`));\n return;\n }\n\n await writeFile(filePath, controllerTemplate(kebabName, pascalName, camelName));\n\n spinner.succeed(`Controller \"${pascalName}Controller\" generated!`);\n success(` src/modules/${moduleName}/${kebabName}.controller.ts`);\n showDryRunSummary(options);\n } catch (err) {\n spinner.fail('Failed to generate controller');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\n// Generate service only\ngenerateCommand\n .command('service <name>')\n .alias('s')\n .description('Generate a service')\n .option('-m, --module <module>', 'Target module name')\n .option('--dry-run', 'Preview changes without writing files')\n .action(async (name: string, options) => {\n enableDryRunIfNeeded(options);\n const spinner = ora('Generating service...').start();\n\n try {\n const kebabName = toKebabCase(name);\n const pascalName = toPascalCase(name);\n const camelName = toCamelCase(name);\n\n const moduleName = options.module ? toKebabCase(options.module) : kebabName;\n const moduleDir = path.join(getModulesDir(), moduleName);\n const filePath = path.join(moduleDir, `${kebabName}.service.ts`);\n\n if (await fileExists(filePath)) {\n spinner.stop();\n error(`Service \"${kebabName}\" already exists`);\n return;\n }\n\n await writeFile(filePath, serviceTemplate(kebabName, pascalName, camelName));\n\n spinner.succeed(`Service \"${pascalName}Service\" generated!`);\n success(` src/modules/${moduleName}/${kebabName}.service.ts`);\n showDryRunSummary(options);\n } catch (err) {\n spinner.fail('Failed to generate service');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\n// Generate repository only\ngenerateCommand\n .command('repository <name>')\n .alias('r')\n .description('Generate a repository')\n .option('-m, --module <module>', 'Target module name')\n .option('--dry-run', 'Preview changes without writing files')\n .action(async (name: string, options) => {\n enableDryRunIfNeeded(options);\n const spinner = ora('Generating repository...').start();\n\n try {\n const kebabName = toKebabCase(name);\n const pascalName = toPascalCase(name);\n const camelName = toCamelCase(name);\n const pluralName = pluralize(kebabName);\n\n const moduleName = options.module ? toKebabCase(options.module) : kebabName;\n const moduleDir = path.join(getModulesDir(), moduleName);\n const filePath = path.join(moduleDir, `${kebabName}.repository.ts`);\n\n if (await fileExists(filePath)) {\n spinner.stop();\n error(`Repository \"${kebabName}\" already exists`);\n return;\n }\n\n await writeFile(filePath, repositoryTemplate(kebabName, pascalName, camelName, pluralName));\n\n spinner.succeed(`Repository \"${pascalName}Repository\" generated!`);\n success(` src/modules/${moduleName}/${kebabName}.repository.ts`);\n showDryRunSummary(options);\n } catch (err) {\n spinner.fail('Failed to generate repository');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\n// Generate types only\ngenerateCommand\n .command('types <name>')\n .alias('t')\n .description('Generate types/interfaces')\n .option('-m, --module <module>', 'Target module name')\n .option('--dry-run', 'Preview changes without writing files')\n .action(async (name: string, options) => {\n enableDryRunIfNeeded(options);\n const spinner = ora('Generating types...').start();\n\n try {\n const kebabName = toKebabCase(name);\n const pascalName = toPascalCase(name);\n\n const moduleName = options.module ? toKebabCase(options.module) : kebabName;\n const moduleDir = path.join(getModulesDir(), moduleName);\n const filePath = path.join(moduleDir, `${kebabName}.types.ts`);\n\n if (await fileExists(filePath)) {\n spinner.stop();\n error(`Types file \"${kebabName}.types.ts\" already exists`);\n return;\n }\n\n await writeFile(filePath, typesTemplate(kebabName, pascalName));\n\n spinner.succeed(`Types for \"${pascalName}\" generated!`);\n success(` src/modules/${moduleName}/${kebabName}.types.ts`);\n showDryRunSummary(options);\n } catch (err) {\n spinner.fail('Failed to generate types');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\n// Generate schemas/validators only\ngenerateCommand\n .command('schema <name>')\n .alias('v')\n .description('Generate validation schemas')\n .option('-m, --module <module>', 'Target module name')\n .option('--dry-run', 'Preview changes without writing files')\n .action(async (name: string, options) => {\n enableDryRunIfNeeded(options);\n const spinner = ora('Generating schemas...').start();\n\n try {\n const kebabName = toKebabCase(name);\n const pascalName = toPascalCase(name);\n const camelName = toCamelCase(name);\n\n const moduleName = options.module ? toKebabCase(options.module) : kebabName;\n const moduleDir = path.join(getModulesDir(), moduleName);\n const filePath = path.join(moduleDir, `${kebabName}.schemas.ts`);\n\n if (await fileExists(filePath)) {\n spinner.stop();\n error(`Schemas file \"${kebabName}.schemas.ts\" already exists`);\n return;\n }\n\n await writeFile(filePath, schemasTemplate(kebabName, pascalName, camelName));\n\n spinner.succeed(`Schemas for \"${pascalName}\" generated!`);\n success(` src/modules/${moduleName}/${kebabName}.schemas.ts`);\n showDryRunSummary(options);\n } catch (err) {\n spinner.fail('Failed to generate schemas');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\n// Generate routes only\ngenerateCommand\n .command('routes <name>')\n .description('Generate routes')\n .option('-m, --module <module>', 'Target module name')\n .option('--dry-run', 'Preview changes without writing files')\n .action(async (name: string, options) => {\n enableDryRunIfNeeded(options);\n const spinner = ora('Generating routes...').start();\n\n try {\n const kebabName = toKebabCase(name);\n const pascalName = toPascalCase(name);\n const camelName = toCamelCase(name);\n const pluralName = pluralize(kebabName);\n\n const moduleName = options.module ? toKebabCase(options.module) : kebabName;\n const moduleDir = path.join(getModulesDir(), moduleName);\n const filePath = path.join(moduleDir, `${kebabName}.routes.ts`);\n\n if (await fileExists(filePath)) {\n spinner.stop();\n error(`Routes file \"${kebabName}.routes.ts\" already exists`);\n return;\n }\n\n await writeFile(filePath, routesTemplate(kebabName, pascalName, camelName, pluralName));\n\n spinner.succeed(`Routes for \"${pascalName}\" generated!`);\n success(` src/modules/${moduleName}/${kebabName}.routes.ts`);\n showDryRunSummary(options);\n } catch (err) {\n spinner.fail('Failed to generate routes');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\n// Interactive field prompt helper\nasync function promptForFields(): Promise<FieldDefinition[]> {\n const fields: FieldDefinition[] = [];\n\n console.log('\\n📝 Define your model fields (press Enter with empty name to finish)\\n');\n\n const fieldTypes = [\n 'string',\n 'number',\n 'boolean',\n 'date',\n 'datetime',\n 'text',\n 'email',\n 'url',\n 'uuid',\n 'int',\n 'float',\n 'decimal',\n 'json',\n ];\n\n let addMore = true;\n\n while (addMore) {\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'name',\n message: 'Field name (empty to finish):',\n },\n ]);\n\n if (!answers.name) {\n addMore = false;\n continue;\n }\n\n const fieldDetails = await inquirer.prompt([\n {\n type: 'list',\n name: 'type',\n message: `Type for \"${answers.name}\":`,\n choices: fieldTypes,\n default: 'string',\n },\n {\n type: 'confirm',\n name: 'isOptional',\n message: 'Is optional?',\n default: false,\n },\n {\n type: 'confirm',\n name: 'isUnique',\n message: 'Is unique?',\n default: false,\n },\n {\n type: 'confirm',\n name: 'isArray',\n message: 'Is array?',\n default: false,\n },\n ]);\n\n fields.push({\n name: answers.name,\n type: fieldDetails.type,\n isOptional: fieldDetails.isOptional,\n isUnique: fieldDetails.isUnique,\n isArray: fieldDetails.isArray,\n });\n\n console.log(` ✓ Added: ${answers.name}: ${fieldDetails.type}\\n`);\n }\n\n return fields;\n}\n","export interface FieldDefinition {\n name: string;\n type: FieldType;\n isOptional: boolean;\n isArray: boolean;\n isUnique: boolean;\n defaultValue?: string;\n relation?: {\n model: string;\n type: 'one-to-one' | 'one-to-many' | 'many-to-one';\n };\n}\n\nexport type FieldType =\n | 'string'\n | 'number'\n | 'boolean'\n | 'date'\n | 'datetime'\n | 'text'\n | 'json'\n | 'email'\n | 'url'\n | 'uuid'\n | 'int'\n | 'float'\n | 'decimal'\n | 'enum';\n\n// Map field types to TypeScript types\nexport const tsTypeMap: Record<FieldType, string> = {\n string: 'string',\n number: 'number',\n boolean: 'boolean',\n date: 'Date',\n datetime: 'Date',\n text: 'string',\n json: 'Record<string, unknown>',\n email: 'string',\n url: 'string',\n uuid: 'string',\n int: 'number',\n float: 'number',\n decimal: 'number',\n enum: 'string',\n};\n\n// Map field types to Prisma types\nexport const prismaTypeMap: Record<FieldType, string> = {\n string: 'String',\n number: 'Int',\n boolean: 'Boolean',\n date: 'DateTime',\n datetime: 'DateTime',\n text: 'String',\n json: 'Json',\n email: 'String',\n url: 'String',\n uuid: 'String',\n int: 'Int',\n float: 'Float',\n decimal: 'Decimal',\n enum: 'String',\n};\n\n// Map field types to Zod validators\nexport const zodTypeMap: Record<FieldType, string> = {\n string: 'z.string()',\n number: 'z.number()',\n boolean: 'z.boolean()',\n date: 'z.coerce.date()',\n datetime: 'z.coerce.date()',\n text: 'z.string()',\n json: 'z.record(z.unknown())',\n email: 'z.string().email()',\n url: 'z.string().url()',\n uuid: 'z.string().uuid()',\n int: 'z.number().int()',\n float: 'z.number()',\n decimal: 'z.number()',\n enum: 'z.string()',\n};\n\n// Map field types to Joi validators\nexport const joiTypeMap: Record<FieldType, string> = {\n string: 'Joi.string()',\n number: 'Joi.number()',\n boolean: 'Joi.boolean()',\n date: 'Joi.date()',\n datetime: 'Joi.date()',\n text: 'Joi.string()',\n json: 'Joi.object()',\n email: 'Joi.string().email()',\n url: 'Joi.string().uri()',\n uuid: 'Joi.string().uuid()',\n int: 'Joi.number().integer()',\n float: 'Joi.number()',\n decimal: 'Joi.number()',\n enum: 'Joi.string()',\n};\n\n// Map field types to Yup validators\nexport const yupTypeMap: Record<FieldType, string> = {\n string: 'yup.string()',\n number: 'yup.number()',\n boolean: 'yup.boolean()',\n date: 'yup.date()',\n datetime: 'yup.date()',\n text: 'yup.string()',\n json: 'yup.object()',\n email: 'yup.string().email()',\n url: 'yup.string().url()',\n uuid: 'yup.string().uuid()',\n int: 'yup.number().integer()',\n float: 'yup.number()',\n decimal: 'yup.number()',\n enum: 'yup.string()',\n};\n\n/**\n * Parse field definition string\n * Format: name:type[:modifiers]\n * Examples:\n * - title:string\n * - price:number\n * - email:email:unique\n * - description:text?\n * - tags:string[]\n * - isActive:boolean:default=true\n * - category:relation:Category\n */\nexport function parseField(fieldStr: string): FieldDefinition {\n const parts = fieldStr.split(':');\n let name = parts[0] || '';\n let typeStr = parts[1] || 'string';\n const modifiers = parts.slice(2);\n\n // Check for optional (?)\n const isOptional = name.endsWith('?') || typeStr.endsWith('?');\n name = name.replace('?', '');\n typeStr = typeStr.replace('?', '');\n\n // Check for array ([])\n const isArray = typeStr.endsWith('[]');\n typeStr = typeStr.replace('[]', '');\n\n // Validate type\n const validTypes: FieldType[] = [\n 'string',\n 'number',\n 'boolean',\n 'date',\n 'datetime',\n 'text',\n 'json',\n 'email',\n 'url',\n 'uuid',\n 'int',\n 'float',\n 'decimal',\n 'enum',\n ];\n\n let type: FieldType = 'string';\n if (validTypes.includes(typeStr as FieldType)) {\n type = typeStr as FieldType;\n }\n\n // Parse modifiers\n let isUnique = false;\n let defaultValue: string | undefined;\n let relation: FieldDefinition['relation'];\n\n for (const mod of modifiers) {\n if (mod === 'unique') {\n isUnique = true;\n } else if (mod.startsWith('default=')) {\n defaultValue = mod.replace('default=', '');\n } else if (typeStr === 'relation') {\n relation = {\n model: mod,\n type: 'many-to-one',\n };\n type = 'string'; // Relations use string IDs\n }\n }\n\n return {\n name,\n type,\n isOptional,\n isArray,\n isUnique,\n defaultValue,\n relation,\n };\n}\n\n/**\n * Parse multiple fields from command line\n * Example: \"title:string price:number description:text?\"\n */\nexport function parseFields(fieldsStr: string): FieldDefinition[] {\n if (!fieldsStr) return [];\n\n return fieldsStr.split(/\\s+/).filter(Boolean).map(parseField);\n}\n\n/**\n * Generate TypeScript interface from fields\n */\nexport function generateTypeInterface(\n name: string,\n fields: FieldDefinition[],\n includeBase = true\n): string {\n const lines: string[] = [];\n\n if (includeBase) {\n lines.push(`import type { BaseEntity } from '../../types/index.js';`);\n lines.push('');\n lines.push(`export interface ${name} extends BaseEntity {`);\n } else {\n lines.push(`export interface ${name} {`);\n }\n\n for (const field of fields) {\n const tsType = tsTypeMap[field.type];\n const arrayMark = field.isArray ? '[]' : '';\n const optionalMark = field.isOptional ? '?' : '';\n lines.push(` ${field.name}${optionalMark}: ${tsType}${arrayMark};`);\n }\n\n lines.push('}');\n\n return lines.join('\\n');\n}\n\n/**\n * Generate Zod schema from fields\n */\nexport function generateZodSchema(\n name: string,\n fields: FieldDefinition[],\n schemaType: 'create' | 'update' = 'create'\n): string {\n const lines: string[] = [];\n\n lines.push(`export const ${schemaType}${name}Schema = z.object({`);\n\n for (const field of fields) {\n let validator = zodTypeMap[field.type];\n\n if (field.isArray) {\n validator = `z.array(${validator})`;\n }\n\n if (field.isOptional || schemaType === 'update') {\n validator += '.optional()';\n }\n\n if (field.defaultValue && schemaType === 'create') {\n validator += `.default(${field.defaultValue})`;\n }\n\n lines.push(` ${field.name}: ${validator},`);\n }\n\n lines.push('});');\n\n return lines.join('\\n');\n}\n\n/**\n * Generate Prisma model from fields\n */\nexport function generatePrismaModel(\n modelName: string,\n tableName: string,\n fields: FieldDefinition[]\n): string {\n const lines: string[] = [];\n\n lines.push(`model ${modelName} {`);\n lines.push(' id String @id @default(uuid())');\n\n for (const field of fields) {\n const prismaType = prismaTypeMap[field.type];\n const optionalMark = field.isOptional ? '?' : '';\n const annotations: string[] = [];\n\n if (field.isUnique) {\n annotations.push('@unique');\n }\n\n if (field.defaultValue) {\n annotations.push(`@default(${field.defaultValue})`);\n }\n\n if (field.type === 'text') {\n annotations.push('@db.Text');\n }\n\n const annotationStr = annotations.length > 0 ? ' ' + annotations.join(' ') : '';\n lines.push(` ${field.name.padEnd(11)} ${prismaType}${optionalMark}${annotationStr}`);\n }\n\n lines.push('');\n lines.push(' createdAt DateTime @default(now())');\n lines.push(' updatedAt DateTime @updatedAt');\n lines.push('');\n\n // Add indexes for unique fields\n const uniqueFields = fields.filter((f) => f.isUnique);\n for (const field of uniqueFields) {\n lines.push(` @@index([${field.name}])`);\n }\n\n lines.push(` @@map(\"${tableName}\")`);\n lines.push('}');\n\n return lines.join('\\n');\n}\n","/* eslint-disable no-console */\nimport chalk from 'chalk';\n\nexport interface ErrorSuggestion {\n message: string;\n suggestions: string[];\n docsLink?: string;\n}\n\nexport class ServCraftError extends Error {\n suggestions: string[];\n docsLink?: string;\n\n constructor(message: string, suggestions: string[] = [], docsLink?: string) {\n super(message);\n this.name = 'ServCraftError';\n this.suggestions = suggestions;\n this.docsLink = docsLink;\n }\n}\n\n// Common error types with suggestions\nexport const ErrorTypes = {\n MODULE_NOT_FOUND: (moduleName: string): ServCraftError =>\n new ServCraftError(\n `Module \"${moduleName}\" not found`,\n [\n `Run ${chalk.cyan('servcraft list')} to see available modules`,\n `Check the spelling of the module name`,\n `Visit ${chalk.blue('https://github.com/Le-Sourcier/servcraft#modules')} for module list`,\n ],\n 'https://github.com/Le-Sourcier/servcraft#add-pre-built-modules'\n ),\n\n MODULE_ALREADY_EXISTS: (moduleName: string): ServCraftError =>\n new ServCraftError(`Module \"${moduleName}\" already exists`, [\n `Use ${chalk.cyan('servcraft add ' + moduleName + ' --force')} to overwrite`,\n `Use ${chalk.cyan('servcraft add ' + moduleName + ' --update')} to update`,\n `Use ${chalk.cyan('servcraft add ' + moduleName + ' --skip-existing')} to skip`,\n ]),\n\n NOT_IN_PROJECT: (): ServCraftError =>\n new ServCraftError(\n 'Not in a ServCraft project directory',\n [\n `Run ${chalk.cyan('servcraft init')} to create a new project`,\n `Navigate to your ServCraft project directory`,\n `Check if ${chalk.yellow('package.json')} exists`,\n ],\n 'https://github.com/Le-Sourcier/servcraft#initialize-project'\n ),\n\n FILE_ALREADY_EXISTS: (fileName: string): ServCraftError =>\n new ServCraftError(`File \"${fileName}\" already exists`, [\n `Use ${chalk.cyan('--force')} flag to overwrite`,\n `Choose a different name`,\n `Delete the existing file first`,\n ]),\n\n INVALID_DATABASE: (database: string): ServCraftError =>\n new ServCraftError(`Invalid database type: \"${database}\"`, [\n `Valid options: ${chalk.cyan('postgresql, mysql, sqlite, mongodb, none')}`,\n `Use ${chalk.cyan('servcraft init --db postgresql')} for PostgreSQL`,\n ]),\n\n INVALID_VALIDATOR: (validator: string): ServCraftError =>\n new ServCraftError(`Invalid validator type: \"${validator}\"`, [\n `Valid options: ${chalk.cyan('zod, joi, yup')}`,\n `Default is ${chalk.cyan('zod')}`,\n ]),\n\n MISSING_DEPENDENCY: (dependency: string, command: string): ServCraftError =>\n new ServCraftError(`Missing dependency: \"${dependency}\"`, [\n `Run ${chalk.cyan(command)} to install`,\n `Check your ${chalk.yellow('package.json')}`,\n ]),\n\n INVALID_FIELD_FORMAT: (field: string): ServCraftError =>\n new ServCraftError(`Invalid field format: \"${field}\"`, [\n `Expected format: ${chalk.cyan('name:type')}`,\n `Example: ${chalk.cyan('name:string age:number isActive:boolean')}`,\n `Supported types: string, number, boolean, date`,\n ]),\n\n GIT_NOT_INITIALIZED: (): ServCraftError =>\n new ServCraftError('Git repository not initialized', [\n `Run ${chalk.cyan('git init')} to initialize git`,\n `This is required for some ServCraft features`,\n ]),\n};\n\n// Display error with suggestions\nexport function displayError(error: Error | ServCraftError): void {\n console.error('\\n' + chalk.red.bold('✗ Error: ') + chalk.red(error.message));\n\n if (error instanceof ServCraftError) {\n if (error.suggestions.length > 0) {\n console.log('\\n' + chalk.yellow.bold('💡 Suggestions:'));\n error.suggestions.forEach((suggestion) => {\n console.log(chalk.yellow(' • ') + suggestion);\n });\n }\n\n if (error.docsLink) {\n console.log(\n '\\n' + chalk.blue.bold('📚 Documentation: ') + chalk.blue.underline(error.docsLink)\n );\n }\n }\n\n console.log(); // Empty line for spacing\n}\n\n// Handle common Node.js errors\nexport function handleSystemError(err: NodeJS.ErrnoException): ServCraftError {\n switch (err.code) {\n case 'ENOENT':\n return new ServCraftError(`File or directory not found: ${err.path}`, [\n `Check if the path exists`,\n `Create the directory first`,\n ]);\n\n case 'EACCES':\n case 'EPERM':\n return new ServCraftError(`Permission denied: ${err.path}`, [\n `Check file permissions`,\n `Try running with elevated privileges (not recommended)`,\n `Change ownership of the directory`,\n ]);\n\n case 'EEXIST':\n return new ServCraftError(`File or directory already exists: ${err.path}`, [\n `Use a different name`,\n `Remove the existing file first`,\n `Use ${chalk.cyan('--force')} to overwrite`,\n ]);\n\n case 'ENOTDIR':\n return new ServCraftError(`Not a directory: ${err.path}`, [\n `Check the path`,\n `A file exists where a directory is expected`,\n ]);\n\n case 'EISDIR':\n return new ServCraftError(`Is a directory: ${err.path}`, [\n `Cannot perform this operation on a directory`,\n `Did you mean to target a file?`,\n ]);\n\n default:\n return new ServCraftError(err.message, [\n `Check system error code: ${err.code}`,\n `Review the error details above`,\n ]);\n }\n}\n\n// Validate project structure\nexport function validateProject(): ServCraftError | null {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const fs = require('fs');\n\n if (!fs.existsSync('package.json')) {\n return ErrorTypes.NOT_IN_PROJECT();\n }\n\n const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf-8'));\n\n if (!packageJson.dependencies?.fastify) {\n return new ServCraftError('This does not appear to be a ServCraft project', [\n `ServCraft projects require Fastify`,\n `Run ${chalk.cyan('servcraft init')} to create a new project`,\n ]);\n }\n\n return null;\n } catch {\n return new ServCraftError('Failed to validate project', [\n `Ensure you are in the project root directory`,\n `Check if ${chalk.yellow('package.json')} is valid`,\n ]);\n }\n}\n","export function controllerTemplate(name: string, pascalName: string, camelName: string): string {\n return `import type { FastifyRequest, FastifyReply } from 'fastify';\nimport type { ${pascalName}Service } from './${name}.service.js';\nimport { create${pascalName}Schema, update${pascalName}Schema, ${camelName}QuerySchema } from './${name}.schemas.js';\nimport { success, created, noContent } from '../../utils/response.js';\nimport { parsePaginationParams } from '../../utils/pagination.js';\nimport { validateBody, validateQuery } from '../validation/validator.js';\n\nexport class ${pascalName}Controller {\n constructor(private ${camelName}Service: ${pascalName}Service) {}\n\n async list(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const query = validateQuery(${camelName}QuerySchema, request.query);\n const pagination = parsePaginationParams(query);\n const filters = {\n search: query.search,\n };\n\n const result = await this.${camelName}Service.findMany(pagination, filters);\n success(reply, result);\n }\n\n async getById(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n ): Promise<void> {\n const item = await this.${camelName}Service.findById(request.params.id);\n\n if (!item) {\n return reply.status(404).send({\n success: false,\n message: '${pascalName} not found',\n });\n }\n\n success(reply, item);\n }\n\n async create(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const data = validateBody(create${pascalName}Schema, request.body);\n const item = await this.${camelName}Service.create(data);\n created(reply, item);\n }\n\n async update(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n ): Promise<void> {\n const data = validateBody(update${pascalName}Schema, request.body);\n const item = await this.${camelName}Service.update(request.params.id, data);\n success(reply, item);\n }\n\n async delete(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n ): Promise<void> {\n await this.${camelName}Service.delete(request.params.id);\n noContent(reply);\n }\n}\n\nexport function create${pascalName}Controller(${camelName}Service: ${pascalName}Service): ${pascalName}Controller {\n return new ${pascalName}Controller(${camelName}Service);\n}\n`;\n}\n","export function serviceTemplate(name: string, pascalName: string, camelName: string): string {\n return `import type { PaginatedResult, PaginationParams } from '../../types/index.js';\nimport { NotFoundError, ConflictError } from '../../utils/errors.js';\nimport { ${pascalName}Repository, create${pascalName}Repository } from './${name}.repository.js';\nimport type { ${pascalName}, Create${pascalName}Data, Update${pascalName}Data, ${pascalName}Filters } from './${name}.types.js';\nimport { logger } from '../../core/logger.js';\n\nexport class ${pascalName}Service {\n constructor(private repository: ${pascalName}Repository) {}\n\n async findById(id: string): Promise<${pascalName} | null> {\n return this.repository.findById(id);\n }\n\n async findMany(\n params: PaginationParams,\n filters?: ${pascalName}Filters\n ): Promise<PaginatedResult<${pascalName}>> {\n return this.repository.findMany(params, filters);\n }\n\n async create(data: Create${pascalName}Data): Promise<${pascalName}> {\n const item = await this.repository.create(data);\n logger.info({ ${camelName}Id: item.id }, '${pascalName} created');\n return item;\n }\n\n async update(id: string, data: Update${pascalName}Data): Promise<${pascalName}> {\n const existing = await this.repository.findById(id);\n if (!existing) {\n throw new NotFoundError('${pascalName}');\n }\n\n const updated = await this.repository.update(id, data);\n if (!updated) {\n throw new NotFoundError('${pascalName}');\n }\n\n logger.info({ ${camelName}Id: id }, '${pascalName} updated');\n return updated;\n }\n\n async delete(id: string): Promise<void> {\n const existing = await this.repository.findById(id);\n if (!existing) {\n throw new NotFoundError('${pascalName}');\n }\n\n await this.repository.delete(id);\n logger.info({ ${camelName}Id: id }, '${pascalName} deleted');\n }\n}\n\nexport function create${pascalName}Service(repository?: ${pascalName}Repository): ${pascalName}Service {\n return new ${pascalName}Service(repository || create${pascalName}Repository());\n}\n`;\n}\n","export function repositoryTemplate(\n name: string,\n pascalName: string,\n camelName: string,\n pluralName: string\n): string {\n return `import { randomUUID } from 'crypto';\nimport type { PaginatedResult, PaginationParams } from '../../types/index.js';\nimport { createPaginatedResult, getSkip } from '../../utils/pagination.js';\nimport type { ${pascalName}, Create${pascalName}Data, Update${pascalName}Data, ${pascalName}Filters } from './${name}.types.js';\n\n// In-memory storage (will be replaced by Prisma in production)\nconst ${pluralName} = new Map<string, ${pascalName}>();\n\nexport class ${pascalName}Repository {\n async findById(id: string): Promise<${pascalName} | null> {\n return ${pluralName}.get(id) || null;\n }\n\n async findMany(\n params: PaginationParams,\n filters?: ${pascalName}Filters\n ): Promise<PaginatedResult<${pascalName}>> {\n let items = Array.from(${pluralName}.values());\n\n // Apply filters\n if (filters?.search) {\n const search = filters.search.toLowerCase();\n items = items.filter((item) =>\n JSON.stringify(item).toLowerCase().includes(search)\n );\n }\n\n // Sort\n if (params.sortBy) {\n const sortKey = params.sortBy as keyof ${pascalName};\n items.sort((a, b) => {\n const aVal = a[sortKey];\n const bVal = b[sortKey];\n if (aVal === undefined || bVal === undefined) return 0;\n if (aVal < bVal) return params.sortOrder === 'desc' ? 1 : -1;\n if (aVal > bVal) return params.sortOrder === 'desc' ? -1 : 1;\n return 0;\n });\n }\n\n const total = items.length;\n const skip = getSkip(params);\n const data = items.slice(skip, skip + params.limit);\n\n return createPaginatedResult(data, total, params);\n }\n\n async create(data: Create${pascalName}Data): Promise<${pascalName}> {\n const now = new Date();\n const item: ${pascalName} = {\n id: randomUUID(),\n ...data,\n createdAt: now,\n updatedAt: now,\n };\n\n ${pluralName}.set(item.id, item);\n return item;\n }\n\n async update(id: string, data: Update${pascalName}Data): Promise<${pascalName} | null> {\n const item = ${pluralName}.get(id);\n if (!item) return null;\n\n const updated: ${pascalName} = {\n ...item,\n ...data,\n updatedAt: new Date(),\n };\n\n ${pluralName}.set(id, updated);\n return updated;\n }\n\n async delete(id: string): Promise<boolean> {\n return ${pluralName}.delete(id);\n }\n\n async count(filters?: ${pascalName}Filters): Promise<number> {\n if (!filters) return ${pluralName}.size;\n\n let count = 0;\n for (const item of ${pluralName}.values()) {\n if (filters.search) {\n const search = filters.search.toLowerCase();\n if (!JSON.stringify(item).toLowerCase().includes(search)) continue;\n }\n count++;\n }\n return count;\n }\n\n // Clear all (for testing)\n async clear(): Promise<void> {\n ${pluralName}.clear();\n }\n}\n\nexport function create${pascalName}Repository(): ${pascalName}Repository {\n return new ${pascalName}Repository();\n}\n`;\n}\n","export function typesTemplate(name: string, pascalName: string): string {\n return `import type { BaseEntity } from '../../types/index.js';\n\nexport interface ${pascalName} extends BaseEntity {\n // Add your ${pascalName} specific fields here\n name: string;\n description?: string;\n // status?: string;\n // metadata?: Record<string, unknown>;\n}\n\nexport interface Create${pascalName}Data {\n name: string;\n description?: string;\n}\n\nexport interface Update${pascalName}Data {\n name?: string;\n description?: string;\n}\n\nexport interface ${pascalName}Filters {\n search?: string;\n // Add more filters as needed\n}\n`;\n}\n","export function schemasTemplate(name: string, pascalName: string, camelName: string): string {\n return `import { z } from 'zod';\n\nexport const create${pascalName}Schema = z.object({\n name: z.string().min(1, 'Name is required').max(255),\n description: z.string().max(1000).optional(),\n});\n\nexport const update${pascalName}Schema = z.object({\n name: z.string().min(1).max(255).optional(),\n description: z.string().max(1000).optional(),\n});\n\nexport const ${camelName}QuerySchema = z.object({\n page: z.string().transform(Number).optional(),\n limit: z.string().transform(Number).optional(),\n sortBy: z.string().optional(),\n sortOrder: z.enum(['asc', 'desc']).optional(),\n search: z.string().optional(),\n});\n\nexport type Create${pascalName}Input = z.infer<typeof create${pascalName}Schema>;\nexport type Update${pascalName}Input = z.infer<typeof update${pascalName}Schema>;\nexport type ${pascalName}QueryInput = z.infer<typeof ${camelName}QuerySchema>;\n`;\n}\n","export function routesTemplate(\n name: string,\n pascalName: string,\n camelName: string,\n pluralName: string\n): string {\n return `import type { FastifyInstance } from 'fastify';\nimport type { ${pascalName}Controller } from './${name}.controller.js';\nimport type { AuthService } from '../auth/auth.service.js';\nimport { createAuthMiddleware, createRoleMiddleware } from '../auth/auth.middleware.js';\n\nexport function register${pascalName}Routes(\n app: FastifyInstance,\n controller: ${pascalName}Controller,\n authService: AuthService\n): void {\n const authenticate = createAuthMiddleware(authService);\n const isAdmin = createRoleMiddleware(['admin', 'super_admin']);\n\n // Public routes (if any)\n // app.get('/${pluralName}/public', controller.publicList.bind(controller));\n\n // Protected routes\n app.get(\n '/${pluralName}',\n { preHandler: [authenticate] },\n controller.list.bind(controller)\n );\n\n app.get(\n '/${pluralName}/:id',\n { preHandler: [authenticate] },\n controller.getById.bind(controller)\n );\n\n app.post(\n '/${pluralName}',\n { preHandler: [authenticate] },\n controller.create.bind(controller)\n );\n\n app.patch(\n '/${pluralName}/:id',\n { preHandler: [authenticate] },\n controller.update.bind(controller)\n );\n\n app.delete(\n '/${pluralName}/:id',\n { preHandler: [authenticate, isAdmin] },\n controller.delete.bind(controller)\n );\n}\n`;\n}\n","export function moduleIndexTemplate(name: string, pascalName: string, camelName: string): string {\n return `import type { FastifyInstance } from 'fastify';\nimport { logger } from '../../core/logger.js';\nimport { ${pascalName}Service, create${pascalName}Service } from './${name}.service.js';\nimport { ${pascalName}Controller, create${pascalName}Controller } from './${name}.controller.js';\nimport { ${pascalName}Repository, create${pascalName}Repository } from './${name}.repository.js';\nimport { register${pascalName}Routes } from './${name}.routes.js';\nimport type { AuthService } from '../auth/auth.service.js';\n\nexport async function register${pascalName}Module(\n app: FastifyInstance,\n authService: AuthService\n): Promise<void> {\n // Create repository and service\n const repository = create${pascalName}Repository();\n const ${camelName}Service = create${pascalName}Service(repository);\n\n // Create controller\n const ${camelName}Controller = create${pascalName}Controller(${camelName}Service);\n\n // Register routes\n register${pascalName}Routes(app, ${camelName}Controller, authService);\n\n logger.info('${pascalName} module registered');\n}\n\nexport { ${pascalName}Service, create${pascalName}Service } from './${name}.service.js';\nexport { ${pascalName}Controller, create${pascalName}Controller } from './${name}.controller.js';\nexport { ${pascalName}Repository, create${pascalName}Repository } from './${name}.repository.js';\nexport * from './${name}.types.js';\nexport * from './${name}.schemas.js';\n`;\n}\n","export function prismaModelTemplate(name: string, pascalName: string, tableName: string): string {\n return `\n// Add this model to your prisma/schema.prisma file\n\nmodel ${pascalName} {\n id String @id @default(uuid())\n name String\n description String?\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([name])\n @@map(\"${tableName}\")\n}\n`;\n}\n","import type { FieldDefinition } from '../utils/field-parser.js';\nimport { tsTypeMap } from '../utils/field-parser.js';\n\nexport function dynamicTypesTemplate(\n name: string,\n pascalName: string,\n fields: FieldDefinition[]\n): string {\n const fieldLines = fields.map((field) => {\n const tsType = tsTypeMap[field.type];\n const arrayMark = field.isArray ? '[]' : '';\n const optionalMark = field.isOptional ? '?' : '';\n return ` ${field.name}${optionalMark}: ${tsType}${arrayMark};`;\n });\n\n const createFieldLines = fields\n .filter((f) => !f.isOptional)\n .map((field) => {\n const tsType = tsTypeMap[field.type];\n const arrayMark = field.isArray ? '[]' : '';\n return ` ${field.name}: ${tsType}${arrayMark};`;\n });\n\n const createOptionalLines = fields\n .filter((f) => f.isOptional)\n .map((field) => {\n const tsType = tsTypeMap[field.type];\n const arrayMark = field.isArray ? '[]' : '';\n return ` ${field.name}?: ${tsType}${arrayMark};`;\n });\n\n const updateFieldLines = fields.map((field) => {\n const tsType = tsTypeMap[field.type];\n const arrayMark = field.isArray ? '[]' : '';\n return ` ${field.name}?: ${tsType}${arrayMark};`;\n });\n\n return `import type { BaseEntity } from '../../types/index.js';\n\nexport interface ${pascalName} extends BaseEntity {\n${fieldLines.join('\\n')}\n}\n\nexport interface Create${pascalName}Data {\n${[...createFieldLines, ...createOptionalLines].join('\\n')}\n}\n\nexport interface Update${pascalName}Data {\n${updateFieldLines.join('\\n')}\n}\n\nexport interface ${pascalName}Filters {\n search?: string;\n${fields\n .filter((f) => ['string', 'enum', 'boolean'].includes(f.type))\n .map((f) => ` ${f.name}?: ${tsTypeMap[f.type]};`)\n .join('\\n')}\n}\n`;\n}\n","import type { FieldDefinition } from '../utils/field-parser.js';\nimport { zodTypeMap, joiTypeMap, yupTypeMap } from '../utils/field-parser.js';\n\nexport type ValidatorType = 'zod' | 'joi' | 'yup';\n\nexport function dynamicSchemasTemplate(\n name: string,\n pascalName: string,\n camelName: string,\n fields: FieldDefinition[],\n validator: ValidatorType = 'zod'\n): string {\n switch (validator) {\n case 'joi':\n return generateJoiSchemas(pascalName, camelName, fields);\n case 'yup':\n return generateYupSchemas(pascalName, camelName, fields);\n default:\n return generateZodSchemas(pascalName, camelName, fields);\n }\n}\n\nfunction generateZodSchemas(\n pascalName: string,\n camelName: string,\n fields: FieldDefinition[]\n): string {\n const createFields = fields.map((field) => {\n let validator = zodTypeMap[field.type];\n\n if (field.isArray) {\n validator = `z.array(${validator})`;\n }\n\n if (field.isOptional) {\n validator += '.optional()';\n }\n\n if (field.defaultValue) {\n validator += `.default(${field.defaultValue})`;\n }\n\n // Add extra validations based on type\n if (field.type === 'string' && !field.isOptional) {\n validator = validator.replace('z.string()', 'z.string().min(1)');\n }\n\n return ` ${field.name}: ${validator},`;\n });\n\n const updateFields = fields.map((field) => {\n let validator = zodTypeMap[field.type];\n\n if (field.isArray) {\n validator = `z.array(${validator})`;\n }\n\n validator += '.optional()';\n\n return ` ${field.name}: ${validator},`;\n });\n\n return `import { z } from 'zod';\n\nexport const create${pascalName}Schema = z.object({\n${createFields.join('\\n')}\n});\n\nexport const update${pascalName}Schema = z.object({\n${updateFields.join('\\n')}\n});\n\nexport const ${camelName}QuerySchema = z.object({\n page: z.string().transform(Number).optional(),\n limit: z.string().transform(Number).optional(),\n sortBy: z.string().optional(),\n sortOrder: z.enum(['asc', 'desc']).optional(),\n search: z.string().optional(),\n});\n\nexport type Create${pascalName}Input = z.infer<typeof create${pascalName}Schema>;\nexport type Update${pascalName}Input = z.infer<typeof update${pascalName}Schema>;\nexport type ${pascalName}QueryInput = z.infer<typeof ${camelName}QuerySchema>;\n`;\n}\n\nfunction generateJoiSchemas(\n pascalName: string,\n camelName: string,\n fields: FieldDefinition[]\n): string {\n const createFields = fields.map((field) => {\n let validator = joiTypeMap[field.type];\n\n if (field.isArray) {\n validator = `Joi.array().items(${validator})`;\n }\n\n if (!field.isOptional) {\n validator += '.required()';\n }\n\n if (field.defaultValue) {\n validator += `.default(${field.defaultValue})`;\n }\n\n return ` ${field.name}: ${validator},`;\n });\n\n const updateFields = fields.map((field) => {\n let validator = joiTypeMap[field.type];\n\n if (field.isArray) {\n validator = `Joi.array().items(${validator})`;\n }\n\n return ` ${field.name}: ${validator},`;\n });\n\n return `import Joi from 'joi';\n\nexport const create${pascalName}Schema = Joi.object({\n${createFields.join('\\n')}\n});\n\nexport const update${pascalName}Schema = Joi.object({\n${updateFields.join('\\n')}\n});\n\nexport const ${camelName}QuerySchema = Joi.object({\n page: Joi.number().integer().min(1),\n limit: Joi.number().integer().min(1).max(100),\n sortBy: Joi.string(),\n sortOrder: Joi.string().valid('asc', 'desc'),\n search: Joi.string(),\n});\n\nexport type Create${pascalName}Input = {\n${fields.map((f) => ` ${f.name}${f.isOptional ? '?' : ''}: ${getJsType(f)};`).join('\\n')}\n};\n\nexport type Update${pascalName}Input = Partial<Create${pascalName}Input>;\nexport type ${pascalName}QueryInput = {\n page?: number;\n limit?: number;\n sortBy?: string;\n sortOrder?: 'asc' | 'desc';\n search?: string;\n};\n`;\n}\n\nfunction generateYupSchemas(\n pascalName: string,\n camelName: string,\n fields: FieldDefinition[]\n): string {\n const createFields = fields.map((field) => {\n let validator = yupTypeMap[field.type];\n\n if (field.isArray) {\n validator = `yup.array().of(${validator})`;\n }\n\n if (!field.isOptional) {\n validator += '.required()';\n }\n\n if (field.defaultValue) {\n validator += `.default(${field.defaultValue})`;\n }\n\n return ` ${field.name}: ${validator},`;\n });\n\n const updateFields = fields.map((field) => {\n let validator = yupTypeMap[field.type];\n\n if (field.isArray) {\n validator = `yup.array().of(${validator})`;\n }\n\n validator += '.optional()';\n\n return ` ${field.name}: ${validator},`;\n });\n\n return `import * as yup from 'yup';\n\nexport const create${pascalName}Schema = yup.object({\n${createFields.join('\\n')}\n});\n\nexport const update${pascalName}Schema = yup.object({\n${updateFields.join('\\n')}\n});\n\nexport const ${camelName}QuerySchema = yup.object({\n page: yup.number().integer().min(1),\n limit: yup.number().integer().min(1).max(100),\n sortBy: yup.string(),\n sortOrder: yup.string().oneOf(['asc', 'desc']),\n search: yup.string(),\n});\n\nexport type Create${pascalName}Input = yup.InferType<typeof create${pascalName}Schema>;\nexport type Update${pascalName}Input = yup.InferType<typeof update${pascalName}Schema>;\nexport type ${pascalName}QueryInput = yup.InferType<typeof ${camelName}QuerySchema>;\n`;\n}\n\nfunction getJsType(field: FieldDefinition): string {\n const typeMap: Record<string, string> = {\n string: 'string',\n number: 'number',\n boolean: 'boolean',\n date: 'Date',\n datetime: 'Date',\n text: 'string',\n json: 'Record<string, unknown>',\n email: 'string',\n url: 'string',\n uuid: 'string',\n int: 'number',\n float: 'number',\n decimal: 'number',\n enum: 'string',\n };\n\n const baseType = typeMap[field.type] || 'unknown';\n return field.isArray ? `${baseType}[]` : baseType;\n}\n","import type { FieldDefinition } from '../utils/field-parser.js';\nimport { prismaTypeMap } from '../utils/field-parser.js';\n\nexport function dynamicPrismaTemplate(\n modelName: string,\n tableName: string,\n fields: FieldDefinition[]\n): string {\n const fieldLines: string[] = [];\n\n for (const field of fields) {\n const prismaType = prismaTypeMap[field.type];\n const optionalMark = field.isOptional ? '?' : '';\n const arrayMark = field.isArray ? '[]' : '';\n const annotations: string[] = [];\n\n if (field.isUnique) {\n annotations.push('@unique');\n }\n\n if (field.defaultValue !== undefined) {\n // Handle different default value types\n if (field.type === 'boolean') {\n annotations.push(`@default(${field.defaultValue})`);\n } else if (field.type === 'number' || field.type === 'int' || field.type === 'float') {\n annotations.push(`@default(${field.defaultValue})`);\n } else {\n annotations.push(`@default(\"${field.defaultValue}\")`);\n }\n }\n\n // Database-specific annotations\n if (field.type === 'text') {\n annotations.push('@db.Text');\n }\n\n if (field.type === 'decimal') {\n annotations.push('@db.Decimal(10, 2)');\n }\n\n const annotationStr = annotations.length > 0 ? ' ' + annotations.join(' ') : '';\n const typePart = `${prismaType}${optionalMark}${arrayMark}`;\n\n fieldLines.push(` ${field.name.padEnd(15)} ${typePart.padEnd(12)}${annotationStr}`);\n }\n\n // Generate indexes\n const indexLines: string[] = [];\n\n // Index for unique fields\n const uniqueFields = fields.filter((f) => f.isUnique);\n for (const field of uniqueFields) {\n indexLines.push(` @@index([${field.name}])`);\n }\n\n // Index for common search fields\n const searchableFields = fields.filter(\n (f) => ['string', 'email'].includes(f.type) && !f.isUnique\n );\n if (searchableFields.length > 0) {\n const firstSearchable = searchableFields[0];\n if (firstSearchable) {\n indexLines.push(` @@index([${firstSearchable.name}])`);\n }\n }\n\n return `\n// ==========================================\n// Add this model to your prisma/schema.prisma file\n// ==========================================\n\nmodel ${modelName} {\n id String @id @default(uuid())\n\n${fieldLines.join('\\n')}\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n${indexLines.join('\\n')}\n @@map(\"${tableName}\")\n}\n\n// ==========================================\n// After adding the model, run:\n// npm run db:migrate -- --name add_${tableName}\n// ==========================================\n`;\n}\n","export function controllerTestTemplate(\n name: string,\n pascalName: string,\n camelName: string\n): string {\n return `import { describe, it, expect, beforeAll, afterAll } from 'vitest';\nimport { build } from '../../app.js';\nimport { FastifyInstance } from 'fastify';\n\ndescribe('${pascalName}Controller', () => {\n let app: FastifyInstance;\n\n beforeAll(async () => {\n app = await build();\n await app.ready();\n });\n\n afterAll(async () => {\n await app.close();\n });\n\n describe('GET /${name}', () => {\n it('should return list of ${name}', async () => {\n const response = await app.inject({\n method: 'GET',\n url: '/${name}',\n });\n\n expect(response.statusCode).toBe(200);\n expect(response.json()).toHaveProperty('data');\n });\n });\n\n describe('GET /${name}/:id', () => {\n it('should return a single ${camelName}', async () => {\n // TODO: Create test ${camelName} first\n const response = await app.inject({\n method: 'GET',\n url: '/${name}/1',\n });\n\n expect(response.statusCode).toBe(200);\n expect(response.json()).toHaveProperty('data');\n });\n\n it('should return 404 for non-existent ${camelName}', async () => {\n const response = await app.inject({\n method: 'GET',\n url: '/${name}/999999',\n });\n\n expect(response.statusCode).toBe(404);\n });\n });\n\n describe('POST /${name}', () => {\n it('should create a new ${camelName}', async () => {\n const response = await app.inject({\n method: 'POST',\n url: '/${name}',\n payload: {\n // TODO: Add required fields\n },\n });\n\n expect(response.statusCode).toBe(201);\n expect(response.json()).toHaveProperty('data');\n });\n\n it('should return 400 for invalid data', async () => {\n const response = await app.inject({\n method: 'POST',\n url: '/${name}',\n payload: {},\n });\n\n expect(response.statusCode).toBe(400);\n });\n });\n\n describe('PUT /${name}/:id', () => {\n it('should update a ${camelName}', async () => {\n // TODO: Create test ${camelName} first\n const response = await app.inject({\n method: 'PUT',\n url: '/${name}/1',\n payload: {\n // TODO: Add fields to update\n },\n });\n\n expect(response.statusCode).toBe(200);\n expect(response.json()).toHaveProperty('data');\n });\n });\n\n describe('DELETE /${name}/:id', () => {\n it('should delete a ${camelName}', async () => {\n // TODO: Create test ${camelName} first\n const response = await app.inject({\n method: 'DELETE',\n url: '/${name}/1',\n });\n\n expect(response.statusCode).toBe(204);\n });\n });\n});\n`;\n}\n","export function serviceTestTemplate(\n name: string,\n pascalName: string,\n camelName: string\n): string {\n return `import { describe, it, expect, beforeEach } from 'vitest';\nimport { ${pascalName}Service } from '../${name}.service.js';\n\ndescribe('${pascalName}Service', () => {\n let service: ${pascalName}Service;\n\n beforeEach(() => {\n service = new ${pascalName}Service();\n });\n\n describe('getAll', () => {\n it('should return all ${name}', async () => {\n const result = await service.getAll();\n\n expect(result).toBeDefined();\n expect(Array.isArray(result)).toBe(true);\n });\n\n it('should apply pagination', async () => {\n const result = await service.getAll({ page: 1, limit: 10 });\n\n expect(result).toBeDefined();\n expect(result.length).toBeLessThanOrEqual(10);\n });\n });\n\n describe('getById', () => {\n it('should return a ${camelName} by id', async () => {\n // TODO: Create test ${camelName} first\n const id = '1';\n const result = await service.getById(id);\n\n expect(result).toBeDefined();\n expect(result.id).toBe(id);\n });\n\n it('should return null for non-existent id', async () => {\n const result = await service.getById('999999');\n\n expect(result).toBeNull();\n });\n });\n\n describe('create', () => {\n it('should create a new ${camelName}', async () => {\n const data = {\n // TODO: Add required fields\n };\n\n const result = await service.create(data);\n\n expect(result).toBeDefined();\n expect(result.id).toBeDefined();\n });\n\n it('should throw error for invalid data', async () => {\n await expect(service.create({} as any)).rejects.toThrow();\n });\n });\n\n describe('update', () => {\n it('should update a ${camelName}', async () => {\n // TODO: Create test ${camelName} first\n const id = '1';\n const updates = {\n // TODO: Add fields to update\n };\n\n const result = await service.update(id, updates);\n\n expect(result).toBeDefined();\n expect(result.id).toBe(id);\n });\n\n it('should return null for non-existent id', async () => {\n const result = await service.update('999999', {});\n\n expect(result).toBeNull();\n });\n });\n\n describe('delete', () => {\n it('should delete a ${camelName}', async () => {\n // TODO: Create test ${camelName} first\n const id = '1';\n const result = await service.delete(id);\n\n expect(result).toBe(true);\n });\n\n it('should return false for non-existent id', async () => {\n const result = await service.delete('999999');\n\n expect(result).toBe(false);\n });\n });\n});\n`;\n}\n","export function integrationTestTemplate(\n name: string,\n pascalName: string,\n camelName: string\n): string {\n return `import { describe, it, expect, beforeAll, afterAll, beforeEach } from 'vitest';\nimport { build } from '../../app.js';\nimport { FastifyInstance } from 'fastify';\nimport { prisma } from '../../lib/prisma.js';\n\ndescribe('${pascalName} Integration Tests', () => {\n let app: FastifyInstance;\n\n beforeAll(async () => {\n app = await build();\n await app.ready();\n });\n\n afterAll(async () => {\n await app.close();\n await prisma.$disconnect();\n });\n\n beforeEach(async () => {\n // Clean up test data\n // await prisma.${camelName}.deleteMany();\n });\n\n describe('Full CRUD workflow', () => {\n it('should create, read, update, and delete a ${camelName}', async () => {\n // Create\n const createResponse = await app.inject({\n method: 'POST',\n url: '/${name}',\n payload: {\n // TODO: Add required fields\n },\n });\n\n expect(createResponse.statusCode).toBe(201);\n const created = createResponse.json().data;\n expect(created.id).toBeDefined();\n\n // Read\n const readResponse = await app.inject({\n method: 'GET',\n url: \\`/${name}/\\${created.id}\\`,\n });\n\n expect(readResponse.statusCode).toBe(200);\n const read = readResponse.json().data;\n expect(read.id).toBe(created.id);\n\n // Update\n const updateResponse = await app.inject({\n method: 'PUT',\n url: \\`/${name}/\\${created.id}\\`,\n payload: {\n // TODO: Add fields to update\n },\n });\n\n expect(updateResponse.statusCode).toBe(200);\n const updated = updateResponse.json().data;\n expect(updated.id).toBe(created.id);\n\n // Delete\n const deleteResponse = await app.inject({\n method: 'DELETE',\n url: \\`/${name}/\\${created.id}\\`,\n });\n\n expect(deleteResponse.statusCode).toBe(204);\n\n // Verify deletion\n const verifyResponse = await app.inject({\n method: 'GET',\n url: \\`/${name}/\\${created.id}\\`,\n });\n\n expect(verifyResponse.statusCode).toBe(404);\n });\n });\n\n describe('List and pagination', () => {\n it('should list ${name} with pagination', async () => {\n // Create multiple ${name}\n const count = 5;\n for (let i = 0; i < count; i++) {\n await app.inject({\n method: 'POST',\n url: '/${name}',\n payload: {\n // TODO: Add required fields\n },\n });\n }\n\n // Test pagination\n const response = await app.inject({\n method: 'GET',\n url: '/${name}?page=1&limit=3',\n });\n\n expect(response.statusCode).toBe(200);\n const result = response.json();\n expect(result.data).toBeDefined();\n expect(result.data.length).toBeLessThanOrEqual(3);\n expect(result.total).toBeGreaterThanOrEqual(count);\n });\n });\n\n describe('Validation', () => {\n it('should validate required fields on create', async () => {\n const response = await app.inject({\n method: 'POST',\n url: '/${name}',\n payload: {},\n });\n\n expect(response.statusCode).toBe(400);\n expect(response.json()).toHaveProperty('error');\n });\n\n it('should validate data types', async () => {\n const response = await app.inject({\n method: 'POST',\n url: '/${name}',\n payload: {\n // TODO: Add invalid field types\n },\n });\n\n expect(response.statusCode).toBe(400);\n });\n });\n});\n`;\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport * as fs from 'fs/promises';\nimport {\n ensureDir,\n writeFile,\n fileExists,\n success,\n error,\n info,\n warn,\n getModulesDir,\n} from '../utils/helpers.js';\nimport { EnvManager } from '../utils/env-manager.js';\nimport { TemplateManager } from '../utils/template-manager.js';\nimport { InteractivePrompt } from '../utils/interactive-prompt.js';\nimport { DryRunManager } from '../utils/dry-run.js';\nimport { ErrorTypes, displayError, validateProject } from '../utils/error-handler.js';\n\n// Pre-built modules that can be added\nconst AVAILABLE_MODULES = {\n auth: {\n name: 'Authentication',\n description: 'JWT authentication with access/refresh tokens',\n files: [\n 'auth.service',\n 'auth.controller',\n 'auth.routes',\n 'auth.middleware',\n 'auth.schemas',\n 'auth.types',\n 'index',\n ],\n },\n users: {\n name: 'User Management',\n description: 'User CRUD with RBAC (roles & permissions)',\n files: [\n 'user.service',\n 'user.controller',\n 'user.repository',\n 'user.routes',\n 'user.schemas',\n 'user.types',\n 'index',\n ],\n },\n email: {\n name: 'Email Service',\n description: 'SMTP email with templates (Handlebars)',\n files: ['email.service', 'email.templates', 'email.types', 'index'],\n },\n audit: {\n name: 'Audit Logs',\n description: 'Activity logging and audit trail',\n files: ['audit.service', 'audit.types', 'index'],\n },\n cache: {\n name: 'Redis Cache',\n description: 'Redis caching with TTL & invalidation',\n files: ['cache.service', 'cache.types', 'index'],\n },\n upload: {\n name: 'File Upload',\n description: 'File upload with local/S3/Cloudinary storage',\n files: ['upload.service', 'upload.routes', 'upload.types', 'index'],\n },\n mfa: {\n name: 'MFA/TOTP',\n description: 'Two-factor authentication with QR codes',\n files: ['mfa.service', 'mfa.routes', 'totp.ts', 'types.ts', 'index'],\n },\n oauth: {\n name: 'OAuth',\n description: 'Social login (Google, GitHub, Facebook, Twitter, Apple)',\n files: ['oauth.service', 'oauth.routes', 'providers', 'types.ts', 'index'],\n },\n payment: {\n name: 'Payments',\n description: 'Payment processing (Stripe, PayPal, Mobile Money)',\n files: ['payment.service', 'payment.routes', 'providers', 'types.ts', 'index'],\n },\n notification: {\n name: 'Notifications',\n description: 'Email, SMS, Push notifications',\n files: ['notification.service', 'types.ts', 'index'],\n },\n 'rate-limit': {\n name: 'Rate Limiting',\n description: 'Advanced rate limiting with multiple algorithms',\n files: [\n 'rate-limit.service',\n 'rate-limit.middleware',\n 'rate-limit.routes',\n 'stores',\n 'types.ts',\n 'index',\n ],\n },\n webhook: {\n name: 'Webhooks',\n description: 'Outgoing webhooks with HMAC signatures & retry',\n files: ['webhook.service', 'webhook.routes', 'signature.ts', 'retry.ts', 'types.ts', 'index'],\n },\n queue: {\n name: 'Queue/Jobs',\n description: 'Background jobs with Bull/BullMQ & cron scheduling',\n files: ['queue.service', 'cron.ts', 'workers.ts', 'routes.ts', 'types.ts', 'index'],\n },\n websocket: {\n name: 'WebSockets',\n description: 'Real-time communication with Socket.io',\n files: ['websocket.service', 'features.ts', 'middlewares.ts', 'types.ts', 'index'],\n },\n search: {\n name: 'Search',\n description: 'Full-text search with Elasticsearch/Meilisearch',\n files: ['search.service', 'adapters', 'types.ts', 'index'],\n },\n i18n: {\n name: 'i18n/Localization',\n description: 'Multi-language support with 7+ locales',\n files: ['i18n.service', 'i18n.middleware', 'i18n.routes', 'types.ts', 'index'],\n },\n 'feature-flag': {\n name: 'Feature Flags',\n description: 'A/B testing & progressive rollout',\n files: ['feature-flag.service', 'feature-flag.routes', 'types.ts', 'index'],\n },\n analytics: {\n name: 'Analytics/Metrics',\n description: 'Prometheus metrics & event tracking',\n files: ['analytics.service', 'analytics.routes', 'types.ts', 'index'],\n },\n 'media-processing': {\n name: 'Media Processing',\n description: 'Image/video processing with FFmpeg',\n files: ['media-processing.service', 'media-processing.routes', 'types.ts', 'index'],\n },\n 'api-versioning': {\n name: 'API Versioning',\n description: 'Multiple API versions support',\n files: [\n 'versioning.service',\n 'versioning.middleware',\n 'versioning.routes',\n 'types.ts',\n 'index',\n ],\n },\n};\n\nexport const addModuleCommand = new Command('add')\n .description('Add a pre-built module to your project')\n .argument(\n '[module]',\n 'Module to add (auth, users, email, audit, upload, cache, notifications, settings)'\n )\n .option('-l, --list', 'List available modules')\n .option('-f, --force', 'Force overwrite existing module')\n .option('-u, --update', 'Update existing module (smart merge)')\n .option('--skip-existing', 'Skip if module already exists')\n .option('--dry-run', 'Preview changes without writing files')\n .action(\n async (\n moduleName?: string,\n options?: {\n list?: boolean;\n force?: boolean;\n update?: boolean;\n skipExisting?: boolean;\n dryRun?: boolean;\n }\n ) => {\n if (options?.list || !moduleName) {\n console.log(chalk.bold('\\n📦 Available Modules:\\n'));\n\n for (const [key, mod] of Object.entries(AVAILABLE_MODULES)) {\n console.log(` ${chalk.cyan(key.padEnd(15))} ${mod.name}`);\n console.log(` ${' '.repeat(15)} ${chalk.gray(mod.description)}\\n`);\n }\n\n console.log(chalk.bold('Usage:'));\n console.log(` ${chalk.yellow('servcraft add auth')} Add authentication module`);\n console.log(` ${chalk.yellow('servcraft add users')} Add user management module`);\n console.log(` ${chalk.yellow('servcraft add email')} Add email service module\\n`);\n return;\n }\n\n // Enable dry-run mode if specified\n const dryRun = DryRunManager.getInstance();\n if (options?.dryRun) {\n dryRun.enable();\n console.log(chalk.yellow('\\n⚠ DRY RUN MODE - No files will be written\\n'));\n }\n\n const module = AVAILABLE_MODULES[moduleName as keyof typeof AVAILABLE_MODULES];\n\n if (!module) {\n displayError(ErrorTypes.MODULE_NOT_FOUND(moduleName));\n return;\n }\n\n // Validate project structure\n const projectError = validateProject();\n if (projectError) {\n displayError(projectError);\n return;\n }\n\n const spinner = ora(`Adding ${module.name} module...`).start();\n\n try {\n const moduleDir = path.join(getModulesDir(), moduleName);\n const templateManager = new TemplateManager(process.cwd());\n const moduleExists = await fileExists(moduleDir);\n\n // Handle existing module\n if (moduleExists) {\n spinner.stop();\n\n // Check flags\n if (options?.skipExisting) {\n info(`Module \"${moduleName}\" already exists, skipping...`);\n return;\n }\n\n // Check for modifications\n const modifiedFiles = await templateManager.getModifiedFiles(moduleName, moduleDir);\n const hasModifications = modifiedFiles.some((f) => f.isModified);\n\n let action: string;\n\n if (options?.force) {\n action = 'overwrite';\n } else if (options?.update) {\n action = 'update';\n } else {\n // Interactive prompt\n const choice = await InteractivePrompt.askModuleExists(moduleName, hasModifications);\n action = choice.action;\n }\n\n // Handle action\n if (action === 'skip') {\n info('Keeping existing module');\n return;\n }\n\n if (action === 'diff') {\n // Show diff and ask again\n await showDiffForModule(templateManager, moduleName, moduleDir);\n return;\n }\n\n if (action === 'backup-overwrite' || action === 'overwrite') {\n if (action === 'backup-overwrite') {\n const backupPath = await templateManager.createBackup(moduleName, moduleDir);\n InteractivePrompt.showBackupCreated(backupPath);\n }\n\n // Remove existing module\n await fs.rm(moduleDir, { recursive: true, force: true });\n await ensureDir(moduleDir);\n\n // Generate fresh module\n await generateModuleFiles(moduleName, moduleDir);\n\n // Save templates and manifest\n const files = await getModuleFiles(moduleName, moduleDir);\n await templateManager.saveTemplate(moduleName, files);\n await templateManager.saveManifest(moduleName, files);\n\n spinner.succeed(\n `${module.name} module ${action === 'backup-overwrite' ? 'backed up and ' : ''}overwritten!`\n );\n } else if (action === 'update') {\n // Smart merge\n await performSmartMerge(templateManager, moduleName, moduleDir, module.name);\n }\n } else {\n // Fresh installation\n await ensureDir(moduleDir);\n\n // Generate module files\n await generateModuleFiles(moduleName, moduleDir);\n\n // Save templates and manifest for future updates\n const files = await getModuleFiles(moduleName, moduleDir);\n await templateManager.saveTemplate(moduleName, files);\n await templateManager.saveManifest(moduleName, files);\n\n spinner.succeed(`${module.name} module added successfully!`);\n }\n\n if (!moduleExists) {\n console.log('\\n📁 Files created:');\n module.files.forEach((f) => success(` src/modules/${moduleName}/${f}.ts`));\n }\n\n // Update .env file with module-specific variables\n const envManager = new EnvManager(process.cwd());\n const envSections = EnvManager.getModuleEnvVariables(moduleName);\n\n if (envSections.length > 0) {\n const envSpinner = ora('Updating environment variables...').start();\n try {\n const result = await envManager.addVariables(envSections);\n\n envSpinner.succeed('Environment variables updated!');\n\n if (result.created) {\n info('\\n📝 Created new .env file');\n }\n\n if (result.added.length > 0) {\n console.log(chalk.bold('\\n✅ Added to .env:'));\n result.added.forEach((key) => success(` ${key}`));\n }\n\n if (result.skipped.length > 0) {\n console.log(chalk.bold('\\n⏭️ Already in .env (skipped):'));\n result.skipped.forEach((key) => info(` ${key}`));\n }\n\n // Show which variables need configuration\n const requiredVars = envSections\n .flatMap((section) => section.variables)\n .filter((v) => v.required && !v.value)\n .map((v) => v.key);\n\n if (requiredVars.length > 0) {\n console.log(chalk.bold('\\n⚠️ Required configuration:'));\n requiredVars.forEach((key) => warn(` ${key} - Please configure this variable`));\n }\n } catch (err) {\n envSpinner.fail('Failed to update environment variables');\n error(err instanceof Error ? err.message : String(err));\n }\n }\n\n if (!options?.dryRun) {\n console.log('\\n📌 Next steps:');\n info(' 1. Configure environment variables in .env (if needed)');\n info(' 2. Register the module in your main app file');\n info(' 3. Run database migrations if needed');\n }\n\n // Show dry-run summary if enabled\n if (options?.dryRun) {\n dryRun.printSummary();\n }\n } catch (err) {\n spinner.fail('Failed to add module');\n error(err instanceof Error ? err.message : String(err));\n }\n }\n );\n\nasync function generateAuthModule(dir: string): Promise<void> {\n // This would copy from templates or generate inline\n // For now, we'll create placeholder files\n const files = {\n 'auth.types.ts': `export interface JwtPayload {\n sub: string;\n email: string;\n role: string;\n type: 'access' | 'refresh';\n}\n\nexport interface TokenPair {\n accessToken: string;\n refreshToken: string;\n expiresIn: number;\n}\n\nexport interface AuthUser {\n id: string;\n email: string;\n role: string;\n}\n`,\n 'auth.schemas.ts': `import { z } from 'zod';\n\nexport const loginSchema = z.object({\n email: z.string().email(),\n password: z.string().min(1),\n});\n\nexport const registerSchema = z.object({\n email: z.string().email(),\n password: z.string().min(8),\n name: z.string().min(2).optional(),\n});\n\nexport const refreshTokenSchema = z.object({\n refreshToken: z.string().min(1),\n});\n`,\n 'index.ts': `export * from './auth.types.js';\nexport * from './auth.schemas.js';\n// Export services, controllers, etc.\n`,\n };\n\n for (const [name, content] of Object.entries(files)) {\n await writeFile(path.join(dir, name), content);\n }\n}\n\nasync function generateUsersModule(dir: string): Promise<void> {\n const files = {\n 'user.types.ts': `export type UserStatus = 'active' | 'inactive' | 'suspended' | 'banned';\nexport type UserRole = 'user' | 'admin' | 'moderator' | 'super_admin';\n\nexport interface User {\n id: string;\n email: string;\n password: string;\n name?: string;\n role: UserRole;\n status: UserStatus;\n createdAt: Date;\n updatedAt: Date;\n}\n`,\n 'user.schemas.ts': `import { z } from 'zod';\n\nexport const createUserSchema = z.object({\n email: z.string().email(),\n password: z.string().min(8),\n name: z.string().min(2).optional(),\n role: z.enum(['user', 'admin', 'moderator']).optional(),\n});\n\nexport const updateUserSchema = z.object({\n email: z.string().email().optional(),\n name: z.string().min(2).optional(),\n role: z.enum(['user', 'admin', 'moderator', 'super_admin']).optional(),\n status: z.enum(['active', 'inactive', 'suspended', 'banned']).optional(),\n});\n`,\n 'index.ts': `export * from './user.types.js';\nexport * from './user.schemas.js';\n`,\n };\n\n for (const [name, content] of Object.entries(files)) {\n await writeFile(path.join(dir, name), content);\n }\n}\n\nasync function generateEmailModule(dir: string): Promise<void> {\n const files = {\n 'email.types.ts': `export interface EmailOptions {\n to: string | string[];\n subject: string;\n html?: string;\n text?: string;\n template?: string;\n data?: Record<string, unknown>;\n}\n\nexport interface EmailResult {\n success: boolean;\n messageId?: string;\n error?: string;\n}\n`,\n 'email.service.ts': `import nodemailer from 'nodemailer';\nimport type { EmailOptions, EmailResult } from './email.types.js';\n\nexport class EmailService {\n private transporter;\n\n constructor() {\n this.transporter = nodemailer.createTransport({\n host: process.env.SMTP_HOST,\n port: parseInt(process.env.SMTP_PORT || '587', 10),\n auth: {\n user: process.env.SMTP_USER,\n pass: process.env.SMTP_PASS,\n },\n });\n }\n\n async send(options: EmailOptions): Promise<EmailResult> {\n try {\n const result = await this.transporter.sendMail({\n from: process.env.SMTP_FROM,\n ...options,\n });\n return { success: true, messageId: result.messageId };\n } catch (error) {\n return { success: false, error: String(error) };\n }\n }\n}\n\nexport const emailService = new EmailService();\n`,\n 'index.ts': `export * from './email.types.js';\nexport { EmailService, emailService } from './email.service.js';\n`,\n };\n\n for (const [name, content] of Object.entries(files)) {\n await writeFile(path.join(dir, name), content);\n }\n}\n\nasync function generateAuditModule(dir: string): Promise<void> {\n const files = {\n 'audit.types.ts': `export interface AuditLogEntry {\n userId?: string;\n action: string;\n resource: string;\n resourceId?: string;\n oldValue?: Record<string, unknown>;\n newValue?: Record<string, unknown>;\n ipAddress?: string;\n userAgent?: string;\n createdAt: Date;\n}\n`,\n 'audit.service.ts': `import type { AuditLogEntry } from './audit.types.js';\n\nconst logs: AuditLogEntry[] = [];\n\nexport class AuditService {\n async log(entry: Omit<AuditLogEntry, 'createdAt'>): Promise<void> {\n logs.push({ ...entry, createdAt: new Date() });\n console.log('[AUDIT]', entry.action, entry.resource);\n }\n\n async query(filters: Partial<AuditLogEntry>): Promise<AuditLogEntry[]> {\n return logs.filter((log) => {\n for (const [key, value] of Object.entries(filters)) {\n if (log[key as keyof AuditLogEntry] !== value) return false;\n }\n return true;\n });\n }\n}\n\nexport const auditService = new AuditService();\n`,\n 'index.ts': `export * from './audit.types.js';\nexport { AuditService, auditService } from './audit.service.js';\n`,\n };\n\n for (const [name, content] of Object.entries(files)) {\n await writeFile(path.join(dir, name), content);\n }\n}\n\nasync function generateUploadModule(dir: string): Promise<void> {\n const files = {\n 'upload.types.ts': `export interface UploadedFile {\n id: string;\n filename: string;\n originalName: string;\n mimetype: string;\n size: number;\n path: string;\n url: string;\n createdAt: Date;\n}\n\nexport interface UploadOptions {\n maxSize?: number;\n allowedTypes?: string[];\n destination?: string;\n}\n`,\n 'index.ts': `export * from './upload.types.js';\n`,\n };\n\n for (const [name, content] of Object.entries(files)) {\n await writeFile(path.join(dir, name), content);\n }\n}\n\nasync function generateCacheModule(dir: string): Promise<void> {\n const files = {\n 'cache.types.ts': `export interface CacheOptions {\n ttl?: number;\n prefix?: string;\n}\n`,\n 'cache.service.ts': `import type { CacheOptions } from './cache.types.js';\n\n// In-memory cache (replace with Redis in production)\nconst cache = new Map<string, { value: unknown; expiry: number }>();\n\nexport class CacheService {\n async get<T>(key: string): Promise<T | null> {\n const item = cache.get(key);\n if (!item) return null;\n if (Date.now() > item.expiry) {\n cache.delete(key);\n return null;\n }\n return item.value as T;\n }\n\n async set(key: string, value: unknown, ttl = 3600): Promise<void> {\n cache.set(key, { value, expiry: Date.now() + ttl * 1000 });\n }\n\n async del(key: string): Promise<void> {\n cache.delete(key);\n }\n\n async clear(): Promise<void> {\n cache.clear();\n }\n}\n\nexport const cacheService = new CacheService();\n`,\n 'index.ts': `export * from './cache.types.js';\nexport { CacheService, cacheService } from './cache.service.js';\n`,\n };\n\n for (const [name, content] of Object.entries(files)) {\n await writeFile(path.join(dir, name), content);\n }\n}\n\nasync function generateGenericModule(dir: string, name: string): Promise<void> {\n const files = {\n [`${name}.types.ts`]: `// ${name} types\nexport interface ${name.charAt(0).toUpperCase() + name.slice(1)}Data {\n // Define your types here\n}\n`,\n 'index.ts': `export * from './${name}.types.js';\n`,\n };\n\n for (const [fileName, content] of Object.entries(files)) {\n await writeFile(path.join(dir, fileName), content);\n }\n}\n\n/**\n * Helper: Find servcraft modules source directory\n */\nasync function findServercraftModules(): Promise<string | null> {\n // Get the directory where the CLI script is located\n const scriptDir = path.dirname(new URL(import.meta.url).pathname);\n\n const possiblePaths = [\n // Local node_modules (when servcraft is a dependency)\n path.join(process.cwd(), 'node_modules', 'servcraft', 'src', 'modules'),\n // From dist/cli/index.js -> src/modules (npx or global install)\n path.resolve(scriptDir, '..', '..', 'src', 'modules'),\n // From src/cli/commands/add-module.ts -> src/modules (development)\n path.resolve(scriptDir, '..', '..', 'modules'),\n ];\n\n for (const p of possiblePaths) {\n try {\n const stats = await fs.stat(p);\n if (stats.isDirectory()) {\n return p;\n }\n } catch {\n // Path doesn't exist, try next\n }\n }\n return null;\n}\n\n/**\n * Helper: Generate module files - copies from servcraft package modules\n */\nasync function generateModuleFiles(moduleName: string, moduleDir: string): Promise<void> {\n // Map module names to their directory names in servcraft\n const moduleNameMap: Record<string, string> = {\n users: 'user',\n 'rate-limit': 'rate-limit',\n 'feature-flag': 'feature-flag',\n 'api-versioning': 'api-versioning',\n 'media-processing': 'media-processing',\n };\n\n const sourceDirName = moduleNameMap[moduleName] || moduleName;\n\n // Find servcraft modules directory\n const servercraftModulesDir = await findServercraftModules();\n\n if (servercraftModulesDir) {\n const sourceModuleDir = path.join(servercraftModulesDir, sourceDirName);\n\n if (await fileExists(sourceModuleDir)) {\n // Copy from servcraft package\n await copyModuleFromSource(sourceModuleDir, moduleDir);\n return;\n }\n }\n\n // Fallback to inline templates for basic modules\n switch (moduleName) {\n case 'auth':\n await generateAuthModule(moduleDir);\n break;\n case 'users':\n await generateUsersModule(moduleDir);\n break;\n case 'email':\n await generateEmailModule(moduleDir);\n break;\n case 'audit':\n await generateAuditModule(moduleDir);\n break;\n case 'upload':\n await generateUploadModule(moduleDir);\n break;\n case 'cache':\n await generateCacheModule(moduleDir);\n break;\n default:\n await generateGenericModule(moduleDir, moduleName);\n }\n}\n\n/**\n * Helper: Copy module from source directory\n */\nasync function copyModuleFromSource(sourceDir: string, targetDir: string): Promise<void> {\n const entries = await fs.readdir(sourceDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const sourcePath = path.join(sourceDir, entry.name);\n const targetPath = path.join(targetDir, entry.name);\n\n if (entry.isDirectory()) {\n await fs.mkdir(targetPath, { recursive: true });\n await copyModuleFromSource(sourcePath, targetPath);\n } else {\n await fs.copyFile(sourcePath, targetPath);\n }\n }\n}\n\n/**\n * Helper: Get all module files as Record<filename, content>\n */\nasync function getModuleFiles(\n moduleName: string,\n moduleDir: string\n): Promise<Record<string, string>> {\n const files: Record<string, string> = {};\n const entries = await fs.readdir(moduleDir);\n\n for (const entry of entries) {\n const filePath = path.join(moduleDir, entry);\n const stat = await fs.stat(filePath);\n\n if (stat.isFile() && entry.endsWith('.ts')) {\n const content = await fs.readFile(filePath, 'utf-8');\n files[entry] = content;\n }\n }\n\n return files;\n}\n\n/**\n * Helper: Show diff for entire module\n */\nasync function showDiffForModule(\n templateManager: TemplateManager,\n moduleName: string,\n moduleDir: string\n): Promise<void> {\n const modifiedFiles = await templateManager.getModifiedFiles(moduleName, moduleDir);\n\n console.log(chalk.cyan(`\\n📊 Changes in module \"${moduleName}\":\\n`));\n\n for (const file of modifiedFiles) {\n if (file.isModified) {\n console.log(chalk.yellow(`\\n📄 ${file.fileName}:`));\n\n const currentPath = path.join(moduleDir, file.fileName);\n const currentContent = await fs.readFile(currentPath, 'utf-8');\n const originalContent = await templateManager.getTemplate(moduleName, file.fileName);\n\n if (originalContent) {\n const diff = templateManager.generateDiff(originalContent, currentContent);\n console.log(diff);\n }\n }\n }\n}\n\n/**\n * Helper: Perform smart merge\n */\nasync function performSmartMerge(\n templateManager: TemplateManager,\n moduleName: string,\n moduleDir: string,\n _displayName: string\n): Promise<void> {\n const spinner = ora('Analyzing files for merge...').start();\n\n // Get new template files\n const newFiles: Record<string, string> = {};\n const templateDir = path.join(templateManager['templatesDir'], moduleName);\n\n try {\n const entries = await fs.readdir(templateDir);\n for (const entry of entries) {\n const content = await fs.readFile(path.join(templateDir, entry), 'utf-8');\n newFiles[entry] = content;\n }\n } catch {\n spinner.fail('Could not find template files');\n return;\n }\n\n const modifiedFiles = await templateManager.getModifiedFiles(moduleName, moduleDir);\n spinner.stop();\n\n // Ask for batch action or individual\n const batchAction = await InteractivePrompt.askBatchAction();\n\n const stats = {\n merged: 0,\n kept: 0,\n overwritten: 0,\n conflicts: 0,\n };\n\n for (const fileInfo of modifiedFiles) {\n const fileName = fileInfo.fileName;\n const filePath = path.join(moduleDir, fileName);\n const newContent = newFiles[fileName];\n\n if (!newContent) {\n // File doesn't exist in new template, keep existing\n continue;\n }\n\n let fileAction: string;\n\n if (batchAction === 'merge-all') {\n fileAction = 'merge';\n } else if (batchAction === 'keep-all') {\n fileAction = 'keep';\n } else if (batchAction === 'overwrite-all') {\n fileAction = 'overwrite';\n } else {\n // Ask for each file\n const currentContent = await fs.readFile(filePath, 'utf-8');\n const yourLines = currentContent.split('\\n').length;\n const newLines = newContent.split('\\n').length;\n\n const choice = await InteractivePrompt.askFileAction(\n fileName,\n fileInfo.isModified,\n yourLines,\n newLines\n );\n fileAction = choice.action;\n\n if (fileAction === 'diff') {\n const originalContent = await templateManager.getTemplate(moduleName, fileName);\n if (originalContent) {\n const diff = templateManager.generateDiff(originalContent, currentContent);\n const proceed = await InteractivePrompt.showDiffAndAsk(diff);\n fileAction = proceed ? 'merge' : 'keep';\n }\n }\n }\n\n // Perform action\n if (fileAction === 'keep' || fileAction === 'skip') {\n stats.kept++;\n continue;\n }\n\n if (fileAction === 'overwrite') {\n await fs.writeFile(filePath, newContent, 'utf-8');\n stats.overwritten++;\n continue;\n }\n\n if (fileAction === 'merge') {\n const originalContent = await templateManager.getTemplate(moduleName, fileName);\n const currentContent = await fs.readFile(filePath, 'utf-8');\n\n if (originalContent) {\n const mergeResult = await templateManager.mergeFiles(\n originalContent,\n currentContent,\n newContent\n );\n\n await fs.writeFile(filePath, mergeResult.merged, 'utf-8');\n\n if (mergeResult.hasConflicts) {\n stats.conflicts++;\n InteractivePrompt.displayConflicts(mergeResult.conflicts);\n } else {\n stats.merged++;\n }\n } else {\n await fs.writeFile(filePath, newContent, 'utf-8');\n stats.overwritten++;\n }\n }\n }\n\n // Update manifest\n const files = await getModuleFiles(moduleName, moduleDir);\n await templateManager.updateManifest(moduleName, files);\n\n InteractivePrompt.showMergeSummary(stats);\n}\n","import * as fs from 'fs/promises';\nimport * as path from 'path';\nimport { existsSync } from 'fs';\n\nexport interface EnvVariable {\n key: string;\n value?: string;\n comment?: string;\n required?: boolean;\n}\n\nexport interface EnvSection {\n title: string;\n variables: EnvVariable[];\n}\n\n/**\n * Environment Manager\n * Manages .env file updates when adding modules\n */\nexport class EnvManager {\n private envPath: string;\n private envExamplePath: string;\n\n constructor(projectRoot: string) {\n this.envPath = path.join(projectRoot, '.env');\n this.envExamplePath = path.join(projectRoot, '.env.example');\n }\n\n /**\n * Add environment variables to .env file\n */\n async addVariables(sections: EnvSection[]): Promise<{\n added: string[];\n skipped: string[];\n created: boolean;\n }> {\n const added: string[] = [];\n const skipped: string[] = [];\n let created = false;\n\n // Read existing .env or create new one\n let envContent = '';\n if (existsSync(this.envPath)) {\n envContent = await fs.readFile(this.envPath, 'utf-8');\n } else {\n created = true;\n }\n\n // Parse existing variables\n const existingKeys = this.parseExistingKeys(envContent);\n\n // Build new content\n let newContent = envContent;\n if (newContent && !newContent.endsWith('\\n\\n')) {\n newContent += '\\n\\n';\n }\n\n for (const section of sections) {\n // Add section comment\n newContent += `# ${section.title}\\n`;\n\n for (const variable of section.variables) {\n // Skip if already exists\n if (existingKeys.has(variable.key)) {\n skipped.push(variable.key);\n continue;\n }\n\n // Add variable comment if provided\n if (variable.comment) {\n newContent += `# ${variable.comment}\\n`;\n }\n\n // Add variable\n const value = variable.value || '';\n const prefix = variable.required ? '' : '# ';\n newContent += `${prefix}${variable.key}=${value}\\n`;\n\n added.push(variable.key);\n }\n\n newContent += '\\n';\n }\n\n // Write to .env\n await fs.writeFile(this.envPath, newContent, 'utf-8');\n\n // Update .env.example if it exists\n if (existsSync(this.envExamplePath)) {\n await this.updateEnvExample(sections);\n }\n\n return { added, skipped, created };\n }\n\n /**\n * Update .env.example file\n */\n private async updateEnvExample(sections: EnvSection[]): Promise<void> {\n let exampleContent = '';\n if (existsSync(this.envExamplePath)) {\n exampleContent = await fs.readFile(this.envExamplePath, 'utf-8');\n }\n\n const existingKeys = this.parseExistingKeys(exampleContent);\n\n let newContent = exampleContent;\n if (newContent && !newContent.endsWith('\\n\\n')) {\n newContent += '\\n\\n';\n }\n\n for (const section of sections) {\n newContent += `# ${section.title}\\n`;\n\n for (const variable of section.variables) {\n if (existingKeys.has(variable.key)) {\n continue;\n }\n\n if (variable.comment) {\n newContent += `# ${variable.comment}\\n`;\n }\n\n // In .env.example, show placeholder values\n const placeholder = this.getPlaceholder(variable.key);\n newContent += `${variable.key}=${placeholder}\\n`;\n }\n\n newContent += '\\n';\n }\n\n await fs.writeFile(this.envExamplePath, newContent, 'utf-8');\n }\n\n /**\n * Parse existing environment variable keys\n */\n private parseExistingKeys(content: string): Set<string> {\n const keys = new Set<string>();\n const lines = content.split('\\n');\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Skip comments and empty lines\n if (!trimmed || trimmed.startsWith('#')) {\n continue;\n }\n\n // Extract key from KEY=value or # KEY=value\n const match = trimmed.match(/^#?\\s*([A-Z_][A-Z0-9_]*)\\s*=/);\n if (match && match[1]) {\n keys.add(match[1]);\n }\n }\n\n return keys;\n }\n\n /**\n * Get placeholder value for .env.example\n */\n private getPlaceholder(key: string): string {\n // Common patterns\n if (key.includes('SECRET') || key.includes('KEY') || key.includes('PASSWORD')) {\n return 'your-secret-key-here';\n }\n if (key.includes('HOST')) {\n return 'localhost';\n }\n if (key.includes('PORT')) {\n return '3000';\n }\n if (key.includes('URL')) {\n return 'http://localhost:3000';\n }\n if (key.includes('EMAIL')) {\n return 'user@example.com';\n }\n if (key.includes('REDIS')) {\n return 'redis://localhost:6379';\n }\n if (key.includes('DATABASE')) {\n return 'postgresql://user:pass@localhost:5432/db';\n }\n if (key.includes('NODE')) {\n return 'http://localhost:9200';\n }\n\n return '';\n }\n\n /**\n * Get environment variables for a specific module\n */\n static getModuleEnvVariables(moduleName: string): EnvSection[] {\n const moduleEnvMap: Record<string, EnvSection[]> = {\n 'rate-limit': [\n {\n title: 'Rate Limiting Configuration',\n variables: [\n {\n key: 'RATE_LIMIT_ENABLED',\n value: 'true',\n comment: 'Enable rate limiting',\n required: true,\n },\n {\n key: 'RATE_LIMIT_REDIS_URL',\n value: 'redis://localhost:6379',\n comment:\n 'Redis URL for distributed rate limiting (optional, uses in-memory if not set)',\n required: false,\n },\n ],\n },\n ],\n webhook: [\n {\n title: 'Webhook Configuration',\n variables: [\n {\n key: 'WEBHOOK_TIMEOUT',\n value: '10000',\n comment: 'Webhook request timeout in milliseconds',\n required: true,\n },\n {\n key: 'WEBHOOK_MAX_RETRIES',\n value: '5',\n comment: 'Maximum number of retry attempts',\n required: true,\n },\n {\n key: 'WEBHOOK_SIGNATURE_ENABLED',\n value: 'true',\n comment: 'Enable HMAC signature verification',\n required: true,\n },\n ],\n },\n ],\n queue: [\n {\n title: 'Queue/Jobs Configuration',\n variables: [\n {\n key: 'REDIS_HOST',\n value: 'localhost',\n comment: 'Redis host for Bull queue',\n required: true,\n },\n {\n key: 'REDIS_PORT',\n value: '6379',\n comment: 'Redis port',\n required: true,\n },\n {\n key: 'REDIS_PASSWORD',\n value: '',\n comment: 'Redis password (optional)',\n required: false,\n },\n {\n key: 'QUEUE_METRICS_ENABLED',\n value: 'true',\n comment: 'Enable queue metrics collection',\n required: true,\n },\n ],\n },\n ],\n websocket: [\n {\n title: 'WebSocket Configuration',\n variables: [\n {\n key: 'WEBSOCKET_PORT',\n value: '3001',\n comment: 'WebSocket server port',\n required: true,\n },\n {\n key: 'WEBSOCKET_CORS_ORIGIN',\n value: 'http://localhost:3000',\n comment: 'CORS origin for WebSocket',\n required: true,\n },\n {\n key: 'WEBSOCKET_REDIS_URL',\n value: 'redis://localhost:6379',\n comment: 'Redis URL for Socket.io adapter (optional, for multi-instance)',\n required: false,\n },\n ],\n },\n ],\n search: [\n {\n title: 'Search Configuration (Elasticsearch)',\n variables: [\n {\n key: 'SEARCH_ENGINE',\n value: 'memory',\n comment: 'Search engine: elasticsearch, meilisearch, or memory',\n required: true,\n },\n {\n key: 'ELASTICSEARCH_NODE',\n value: 'http://localhost:9200',\n comment: 'Elasticsearch node URL',\n required: false,\n },\n {\n key: 'ELASTICSEARCH_USERNAME',\n value: '',\n comment: 'Elasticsearch username (optional)',\n required: false,\n },\n {\n key: 'ELASTICSEARCH_PASSWORD',\n value: '',\n comment: 'Elasticsearch password (optional)',\n required: false,\n },\n ],\n },\n {\n title: 'Search Configuration (Meilisearch)',\n variables: [\n {\n key: 'MEILISEARCH_HOST',\n value: 'http://localhost:7700',\n comment: 'Meilisearch host URL',\n required: false,\n },\n {\n key: 'MEILISEARCH_API_KEY',\n value: '',\n comment: 'Meilisearch API key (optional)',\n required: false,\n },\n ],\n },\n ],\n i18n: [\n {\n title: 'i18n/Localization Configuration',\n variables: [\n {\n key: 'DEFAULT_LOCALE',\n value: 'en',\n comment: 'Default locale/language',\n required: true,\n },\n {\n key: 'SUPPORTED_LOCALES',\n value: 'en,fr,es,de,ar,zh,ja',\n comment: 'Comma-separated list of supported locales',\n required: true,\n },\n {\n key: 'TRANSLATIONS_DIR',\n value: './locales',\n comment: 'Directory for translation files',\n required: true,\n },\n {\n key: 'I18N_CACHE_ENABLED',\n value: 'true',\n comment: 'Enable translation caching',\n required: true,\n },\n ],\n },\n ],\n cache: [\n {\n title: 'Cache Configuration',\n variables: [\n {\n key: 'CACHE_PROVIDER',\n value: 'redis',\n comment: 'Cache provider: redis or memory',\n required: true,\n },\n {\n key: 'CACHE_REDIS_URL',\n value: 'redis://localhost:6379',\n comment: 'Redis URL for cache',\n required: false,\n },\n {\n key: 'CACHE_TTL',\n value: '3600',\n comment: 'Default cache TTL in seconds',\n required: true,\n },\n ],\n },\n ],\n mfa: [\n {\n title: 'MFA/TOTP Configuration',\n variables: [\n {\n key: 'MFA_ISSUER',\n value: 'MyApp',\n comment: 'MFA issuer name shown in authenticator apps',\n required: true,\n },\n {\n key: 'MFA_ALGORITHM',\n value: 'SHA1',\n comment: 'TOTP algorithm: SHA1, SHA256, or SHA512',\n required: true,\n },\n ],\n },\n ],\n oauth: [\n {\n title: 'OAuth Configuration',\n variables: [\n {\n key: 'OAUTH_GOOGLE_CLIENT_ID',\n value: '',\n comment: 'Google OAuth client ID',\n required: false,\n },\n {\n key: 'OAUTH_GOOGLE_CLIENT_SECRET',\n value: '',\n comment: 'Google OAuth client secret',\n required: false,\n },\n {\n key: 'OAUTH_GITHUB_CLIENT_ID',\n value: '',\n comment: 'GitHub OAuth client ID',\n required: false,\n },\n {\n key: 'OAUTH_GITHUB_CLIENT_SECRET',\n value: '',\n comment: 'GitHub OAuth client secret',\n required: false,\n },\n {\n key: 'OAUTH_REDIRECT_URL',\n value: 'http://localhost:3000/auth/callback',\n comment: 'OAuth callback URL',\n required: true,\n },\n ],\n },\n ],\n payment: [\n {\n title: 'Payment Configuration',\n variables: [\n {\n key: 'STRIPE_SECRET_KEY',\n value: '',\n comment: 'Stripe secret key',\n required: false,\n },\n {\n key: 'STRIPE_PUBLISHABLE_KEY',\n value: '',\n comment: 'Stripe publishable key',\n required: false,\n },\n {\n key: 'PAYPAL_CLIENT_ID',\n value: '',\n comment: 'PayPal client ID',\n required: false,\n },\n {\n key: 'PAYPAL_CLIENT_SECRET',\n value: '',\n comment: 'PayPal client secret',\n required: false,\n },\n {\n key: 'PAYPAL_MODE',\n value: 'sandbox',\n comment: 'PayPal mode: sandbox or live',\n required: false,\n },\n ],\n },\n ],\n 'feature-flag': [\n {\n title: 'Feature Flags Configuration',\n variables: [\n {\n key: 'FEATURE_FLAGS_ENABLED',\n value: 'true',\n comment: 'Enable feature flags',\n required: true,\n },\n {\n key: 'FEATURE_FLAGS_ENVIRONMENT',\n value: 'development',\n comment: 'Feature flags environment: development, staging, production, test',\n required: true,\n },\n {\n key: 'FEATURE_FLAGS_ANALYTICS',\n value: 'true',\n comment: 'Enable feature flag analytics',\n required: true,\n },\n {\n key: 'FEATURE_FLAGS_CACHE_TTL',\n value: '300',\n comment: 'Cache TTL in seconds',\n required: true,\n },\n ],\n },\n ],\n upload: [\n {\n title: 'File Upload Configuration',\n variables: [\n {\n key: 'UPLOAD_PROVIDER',\n value: 'local',\n comment: 'Upload provider: local, s3, cloudinary',\n required: true,\n },\n {\n key: 'UPLOAD_MAX_SIZE',\n value: '10485760',\n comment: 'Max upload size in bytes (10MB)',\n required: true,\n },\n {\n key: 'UPLOAD_DIR',\n value: './uploads',\n comment: 'Local upload directory',\n required: true,\n },\n {\n key: 'AWS_ACCESS_KEY_ID',\n value: '',\n comment: 'AWS access key for S3',\n required: false,\n },\n {\n key: 'AWS_SECRET_ACCESS_KEY',\n value: '',\n comment: 'AWS secret key for S3',\n required: false,\n },\n {\n key: 'AWS_S3_BUCKET',\n value: '',\n comment: 'S3 bucket name',\n required: false,\n },\n ],\n },\n ],\n notification: [\n {\n title: 'Notification Configuration',\n variables: [\n {\n key: 'NOTIFICATION_EMAIL_ENABLED',\n value: 'true',\n comment: 'Enable email notifications',\n required: true,\n },\n {\n key: 'NOTIFICATION_SMS_ENABLED',\n value: 'false',\n comment: 'Enable SMS notifications',\n required: false,\n },\n {\n key: 'NOTIFICATION_PUSH_ENABLED',\n value: 'false',\n comment: 'Enable push notifications',\n required: false,\n },\n {\n key: 'TWILIO_ACCOUNT_SID',\n value: '',\n comment: 'Twilio account SID for SMS',\n required: false,\n },\n {\n key: 'TWILIO_AUTH_TOKEN',\n value: '',\n comment: 'Twilio auth token',\n required: false,\n },\n ],\n },\n ],\n analytics: [\n {\n title: 'Analytics/Metrics Configuration',\n variables: [\n {\n key: 'ANALYTICS_ENABLED',\n value: 'true',\n comment: 'Enable analytics and metrics collection',\n required: true,\n },\n {\n key: 'ANALYTICS_PREFIX',\n value: 'app',\n comment: 'Metrics prefix',\n required: true,\n },\n {\n key: 'PROMETHEUS_ENABLED',\n value: 'true',\n comment: 'Enable Prometheus metrics endpoint',\n required: true,\n },\n {\n key: 'METRICS_FLUSH_INTERVAL',\n value: '60000',\n comment: 'Metrics flush interval in milliseconds',\n required: true,\n },\n ],\n },\n ],\n 'media-processing': [\n {\n title: 'Media Processing Configuration',\n variables: [\n {\n key: 'FFMPEG_PATH',\n value: 'ffmpeg',\n comment: 'Path to FFmpeg binary',\n required: true,\n },\n {\n key: 'FFPROBE_PATH',\n value: 'ffprobe',\n comment: 'Path to FFprobe binary',\n required: true,\n },\n {\n key: 'MEDIA_TEMP_DIR',\n value: './temp/media',\n comment: 'Temporary directory for media processing',\n required: true,\n },\n {\n key: 'MEDIA_MAX_CONCURRENT',\n value: '3',\n comment: 'Maximum concurrent processing jobs',\n required: true,\n },\n {\n key: 'MEDIA_GPU_ACCELERATION',\n value: 'false',\n comment: 'Enable GPU acceleration (requires NVIDIA GPU)',\n required: false,\n },\n ],\n },\n ],\n 'api-versioning': [\n {\n title: 'API Versioning Configuration',\n variables: [\n {\n key: 'API_VERSION_STRATEGY',\n value: 'url',\n comment: 'Versioning strategy: url, header, query, accept-header',\n required: true,\n },\n {\n key: 'API_DEFAULT_VERSION',\n value: 'v1',\n comment: 'Default API version',\n required: true,\n },\n {\n key: 'API_VERSION_HEADER',\n value: 'X-API-Version',\n comment: 'Header name for version (if strategy is header)',\n required: false,\n },\n {\n key: 'API_VERSION_STRICT',\n value: 'true',\n comment: 'Strict mode - reject unknown versions',\n required: true,\n },\n {\n key: 'API_DEPRECATION_WARNINGS',\n value: 'true',\n comment: 'Show deprecation warnings in headers',\n required: true,\n },\n ],\n },\n ],\n };\n\n return moduleEnvMap[moduleName] || [];\n }\n}\n","import * as fs from 'fs/promises';\nimport * as path from 'path';\nimport { createHash } from 'crypto';\nimport { existsSync } from 'fs';\n\nexport interface Template {\n /** Template name */\n name: string;\n /** Template content */\n content: string;\n /** Template hash for change detection */\n hash: string;\n /** Template version */\n version: string;\n}\n\nexport interface ModuleManifest {\n /** Module name */\n name: string;\n /** Module version */\n version: string;\n /** Files in this module */\n files: Record<string, { hash: string; path: string }>;\n /** Install date */\n installedAt: Date;\n /** Last update */\n updatedAt: Date;\n}\n\n/**\n * Template Manager\n * Manages module templates and tracks installed versions\n */\nexport class TemplateManager {\n private templatesDir: string;\n private manifestsDir: string;\n\n constructor(projectRoot: string) {\n this.templatesDir = path.join(projectRoot, '.servcraft', 'templates');\n this.manifestsDir = path.join(projectRoot, '.servcraft', 'manifests');\n }\n\n /**\n * Initialize template system\n */\n async initialize(): Promise<void> {\n await fs.mkdir(this.templatesDir, { recursive: true });\n await fs.mkdir(this.manifestsDir, { recursive: true });\n }\n\n /**\n * Save module template\n */\n async saveTemplate(moduleName: string, files: Record<string, string>): Promise<void> {\n await this.initialize();\n\n const moduleTemplateDir = path.join(this.templatesDir, moduleName);\n await fs.mkdir(moduleTemplateDir, { recursive: true });\n\n // Save each file\n for (const [fileName, content] of Object.entries(files)) {\n const filePath = path.join(moduleTemplateDir, fileName);\n await fs.writeFile(filePath, content, 'utf-8');\n }\n }\n\n /**\n * Get template content\n */\n async getTemplate(moduleName: string, fileName: string): Promise<string | null> {\n try {\n const filePath = path.join(this.templatesDir, moduleName, fileName);\n return await fs.readFile(filePath, 'utf-8');\n } catch {\n return null;\n }\n }\n\n /**\n * Save module manifest\n */\n async saveManifest(moduleName: string, files: Record<string, string>): Promise<void> {\n await this.initialize();\n\n const fileHashes: Record<string, { hash: string; path: string }> = {};\n\n for (const [fileName, content] of Object.entries(files)) {\n fileHashes[fileName] = {\n hash: this.hashContent(content),\n path: `src/modules/${moduleName}/${fileName}`,\n };\n }\n\n const manifest: ModuleManifest = {\n name: moduleName,\n version: '1.0.0',\n files: fileHashes,\n installedAt: new Date(),\n updatedAt: new Date(),\n };\n\n const manifestPath = path.join(this.manifestsDir, `${moduleName}.json`);\n await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2), 'utf-8');\n }\n\n /**\n * Get module manifest\n */\n async getManifest(moduleName: string): Promise<ModuleManifest | null> {\n try {\n const manifestPath = path.join(this.manifestsDir, `${moduleName}.json`);\n const content = await fs.readFile(manifestPath, 'utf-8');\n return JSON.parse(content) as ModuleManifest;\n } catch {\n return null;\n }\n }\n\n /**\n * Check if file has been modified by user\n */\n async isFileModified(\n moduleName: string,\n fileName: string,\n currentContent: string\n ): Promise<boolean> {\n const manifest = await this.getManifest(moduleName);\n\n if (!manifest || !manifest.files[fileName]) {\n return false;\n }\n\n const originalHash = manifest.files[fileName].hash;\n const currentHash = this.hashContent(currentContent);\n\n return originalHash !== currentHash;\n }\n\n /**\n * Get all modified files in a module\n */\n async getModifiedFiles(\n moduleName: string,\n moduleDir: string\n ): Promise<\n Array<{ fileName: string; isModified: boolean; originalHash: string; currentHash: string }>\n > {\n const manifest = await this.getManifest(moduleName);\n\n if (!manifest) {\n return [];\n }\n\n const results = [];\n\n for (const [fileName, fileInfo] of Object.entries(manifest.files)) {\n const filePath = path.join(moduleDir, fileName);\n\n if (!existsSync(filePath)) {\n results.push({\n fileName,\n isModified: true,\n originalHash: fileInfo.hash,\n currentHash: '',\n });\n continue;\n }\n\n const currentContent = await fs.readFile(filePath, 'utf-8');\n const currentHash = this.hashContent(currentContent);\n\n results.push({\n fileName,\n isModified: fileInfo.hash !== currentHash,\n originalHash: fileInfo.hash,\n currentHash,\n });\n }\n\n return results;\n }\n\n /**\n * Create backup of module\n */\n async createBackup(moduleName: string, moduleDir: string): Promise<string> {\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-').substring(0, 19);\n const backupDir = path.join(path.dirname(moduleDir), `${moduleName}.backup-${timestamp}`);\n\n await this.copyDirectory(moduleDir, backupDir);\n\n return backupDir;\n }\n\n /**\n * Copy directory recursively\n */\n private async copyDirectory(src: string, dest: string): Promise<void> {\n await fs.mkdir(dest, { recursive: true });\n\n const entries = await fs.readdir(src, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name);\n const destPath = path.join(dest, entry.name);\n\n if (entry.isDirectory()) {\n await this.copyDirectory(srcPath, destPath);\n } else {\n await fs.copyFile(srcPath, destPath);\n }\n }\n }\n\n /**\n * Perform 3-way merge\n */\n async mergeFiles(\n original: string,\n modified: string,\n incoming: string\n ): Promise<{ merged: string; hasConflicts: boolean; conflicts: string[] }> {\n const conflicts: string[] = [];\n let hasConflicts = false;\n\n // Simple line-based merge\n const originalLines = original.split('\\n');\n const modifiedLines = modified.split('\\n');\n const incomingLines = incoming.split('\\n');\n\n const merged: string[] = [];\n\n // This is a simplified merge - in production, use a proper diff3 algorithm\n // For now, we'll use a basic strategy:\n // 1. If modified === original, use incoming (user hasn't changed it)\n // 2. If modified !== original, keep modified (user changed it)\n // 3. If both changed, mark as conflict\n\n const maxLength = Math.max(originalLines.length, modifiedLines.length, incomingLines.length);\n\n for (let i = 0; i < maxLength; i++) {\n const origLine = originalLines[i] || '';\n const modLine = modifiedLines[i] || '';\n const incLine = incomingLines[i] || '';\n\n if (modLine === origLine) {\n // User hasn't modified, use incoming\n merged.push(incLine);\n } else if (incLine === origLine) {\n // Template hasn't changed, keep user's modification\n merged.push(modLine);\n } else if (modLine === incLine) {\n // Both have same change, no conflict\n merged.push(modLine);\n } else {\n // Conflict: both modified differently\n hasConflicts = true;\n conflicts.push(`Line ${i + 1}: User and template both modified`);\n merged.push(`<<<<<<< YOUR VERSION`);\n merged.push(modLine);\n merged.push(`=======`);\n merged.push(incLine);\n merged.push(`>>>>>>> NEW VERSION`);\n }\n }\n\n return {\n merged: merged.join('\\n'),\n hasConflicts,\n conflicts,\n };\n }\n\n /**\n * Generate diff between two files\n */\n generateDiff(original: string, modified: string): string {\n const originalLines = original.split('\\n');\n const modifiedLines = modified.split('\\n');\n\n const diff: string[] = [];\n diff.push('--- Original');\n diff.push('+++ Modified');\n diff.push('');\n\n const maxLength = Math.max(originalLines.length, modifiedLines.length);\n\n for (let i = 0; i < maxLength; i++) {\n const origLine = originalLines[i];\n const modLine = modifiedLines[i];\n\n if (origLine !== modLine) {\n if (origLine !== undefined) {\n diff.push(`- ${origLine}`);\n }\n if (modLine !== undefined) {\n diff.push(`+ ${modLine}`);\n }\n }\n }\n\n return diff.join('\\n');\n }\n\n /**\n * Hash content for change detection\n */\n private hashContent(content: string): string {\n return createHash('md5').update(content).digest('hex');\n }\n\n /**\n * Check if module is installed\n */\n async isModuleInstalled(moduleName: string): Promise<boolean> {\n const manifest = await this.getManifest(moduleName);\n return manifest !== null;\n }\n\n /**\n * Update manifest after merge\n */\n async updateManifest(moduleName: string, files: Record<string, string>): Promise<void> {\n const manifest = await this.getManifest(moduleName);\n\n if (!manifest) {\n await this.saveManifest(moduleName, files);\n return;\n }\n\n const fileHashes: Record<string, { hash: string; path: string }> = {};\n\n for (const [fileName, content] of Object.entries(files)) {\n fileHashes[fileName] = {\n hash: this.hashContent(content),\n path: `src/modules/${moduleName}/${fileName}`,\n };\n }\n\n manifest.files = fileHashes;\n manifest.updatedAt = new Date();\n\n const manifestPath = path.join(this.manifestsDir, `${moduleName}.json`);\n await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2), 'utf-8');\n }\n}\n","import inquirer from 'inquirer';\nimport chalk from 'chalk';\n\nexport interface MergeChoice {\n action: 'skip' | 'update' | 'overwrite' | 'diff' | 'backup-overwrite';\n}\n\nexport interface FileChoice {\n action: 'merge' | 'keep' | 'overwrite' | 'diff' | 'skip';\n}\n\n/**\n * Interactive prompt utilities\n */\nexport class InteractivePrompt {\n /**\n * Ask what to do when module already exists\n */\n static async askModuleExists(\n moduleName: string,\n hasModifications: boolean\n ): Promise<MergeChoice> {\n console.log(chalk.yellow(`\\n⚠️ Module \"${moduleName}\" already exists`));\n\n if (hasModifications) {\n console.log(chalk.yellow(' Some files have been modified by you.\\n'));\n }\n\n const { action } = await inquirer.prompt<{ action: MergeChoice['action'] }>([\n {\n type: 'list',\n name: 'action',\n message: 'What would you like to do?',\n choices: [\n {\n name: '✓ Skip (keep existing files, recommended if you made custom changes)',\n value: 'skip',\n },\n {\n name: '↻ Update (merge new features, preserve your customizations)',\n value: 'update',\n },\n {\n name: '⚠ Overwrite (replace all files, will lose your changes)',\n value: 'overwrite',\n },\n {\n name: '📋 Show diff (see what changed)',\n value: 'diff',\n },\n {\n name: '💾 Backup & overwrite (save backup then replace)',\n value: 'backup-overwrite',\n },\n ],\n default: 'skip',\n },\n ]);\n\n return { action };\n }\n\n /**\n * Ask what to do with a specific file\n */\n static async askFileAction(\n fileName: string,\n isModified: boolean,\n yourLines: number,\n newLines: number\n ): Promise<FileChoice> {\n console.log(chalk.cyan(`\\n📁 ${fileName}`));\n console.log(\n chalk.gray(` Your version: ${yourLines} lines${isModified ? ' (modified)' : ''}`)\n );\n console.log(chalk.gray(` New version: ${newLines} lines\\n`));\n\n const { action } = await inquirer.prompt<{ action: FileChoice['action'] }>([\n {\n type: 'list',\n name: 'action',\n message: 'Action for this file:',\n choices: [\n {\n name: '[M]erge - Smart merge, preserve your changes',\n value: 'merge',\n },\n {\n name: '[K]eep - Keep your version (skip update)',\n value: 'keep',\n },\n {\n name: '[O]verwrite - Use new version',\n value: 'overwrite',\n },\n {\n name: '[D]iff - Show differences',\n value: 'diff',\n },\n {\n name: '[S]kip - Skip this file',\n value: 'skip',\n },\n ],\n default: isModified ? 'merge' : 'overwrite',\n },\n ]);\n\n return { action };\n }\n\n /**\n * Confirm action\n */\n static async confirm(message: string, defaultValue = false): Promise<boolean> {\n const { confirmed } = await inquirer.prompt<{ confirmed: boolean }>([\n {\n type: 'confirm',\n name: 'confirmed',\n message,\n default: defaultValue,\n },\n ]);\n\n return confirmed;\n }\n\n /**\n * Display diff and ask to continue\n */\n static async showDiffAndAsk(diff: string): Promise<boolean> {\n console.log(chalk.cyan('\\n📊 Differences:\\n'));\n console.log(diff);\n\n return await this.confirm('\\nDo you want to proceed with this change?', true);\n }\n\n /**\n * Display merge conflicts\n */\n static displayConflicts(conflicts: string[]): void {\n console.log(chalk.red('\\n⚠️ Merge Conflicts Detected:\\n'));\n conflicts.forEach((conflict, i) => {\n console.log(chalk.yellow(` ${i + 1}. ${conflict}`));\n });\n console.log(chalk.gray('\\n Conflict markers have been added to the file:'));\n console.log(chalk.gray(' <<<<<<< YOUR VERSION'));\n console.log(chalk.gray(' ... your code ...'));\n console.log(chalk.gray(' ======='));\n console.log(chalk.gray(' ... new code ...'));\n console.log(chalk.gray(' >>>>>>> NEW VERSION\\n'));\n }\n\n /**\n * Show backup location\n */\n static showBackupCreated(backupPath: string): void {\n console.log(chalk.green(`\\n✓ Backup created: ${chalk.cyan(backupPath)}`));\n }\n\n /**\n * Show merge summary\n */\n static showMergeSummary(stats: {\n merged: number;\n kept: number;\n overwritten: number;\n conflicts: number;\n }): void {\n console.log(chalk.bold('\\n📊 Merge Summary:\\n'));\n if (stats.merged > 0) {\n console.log(chalk.green(` ✓ Merged: ${stats.merged} file(s)`));\n }\n if (stats.kept > 0) {\n console.log(chalk.blue(` → Kept: ${stats.kept} file(s)`));\n }\n if (stats.overwritten > 0) {\n console.log(chalk.yellow(` ⚠ Overwritten: ${stats.overwritten} file(s)`));\n }\n if (stats.conflicts > 0) {\n console.log(chalk.red(` ⚠ Conflicts: ${stats.conflicts} file(s)`));\n console.log(chalk.gray('\\n Please resolve conflicts manually before committing.\\n'));\n }\n }\n\n /**\n * Ask for batch action on all files\n */\n static async askBatchAction(): Promise<\n 'individual' | 'merge-all' | 'keep-all' | 'overwrite-all'\n > {\n const { action } = await inquirer.prompt<{\n action: 'individual' | 'merge-all' | 'keep-all' | 'overwrite-all';\n }>([\n {\n type: 'list',\n name: 'action',\n message: 'Multiple files found. Choose action:',\n choices: [\n {\n name: 'Ask for each file individually (recommended)',\n value: 'individual',\n },\n {\n name: 'Merge all files automatically',\n value: 'merge-all',\n },\n {\n name: 'Keep all existing files (skip update)',\n value: 'keep-all',\n },\n {\n name: 'Overwrite all files with new versions',\n value: 'overwrite-all',\n },\n ],\n default: 'individual',\n },\n ]);\n\n return action;\n }\n}\n","import { Command } from 'commander';\nimport { execSync, spawn } from 'child_process';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport { error, info } from '../utils/helpers.js';\n\nexport const dbCommand = new Command('db').description('Database management commands');\n\ndbCommand\n .command('migrate')\n .description('Run database migrations')\n .option('-n, --name <name>', 'Migration name')\n .action(async (options) => {\n const spinner = ora('Running migrations...').start();\n\n try {\n const cmd = options.name\n ? `npx prisma migrate dev --name ${options.name}`\n : 'npx prisma migrate dev';\n\n execSync(cmd, { stdio: 'inherit' });\n spinner.succeed('Migrations completed!');\n } catch (err) {\n spinner.fail('Migration failed');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\ndbCommand\n .command('push')\n .description('Push schema changes to database (no migration)')\n .action(async () => {\n const spinner = ora('Pushing schema...').start();\n\n try {\n execSync('npx prisma db push', { stdio: 'inherit' });\n spinner.succeed('Schema pushed successfully!');\n } catch (err) {\n spinner.fail('Push failed');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\ndbCommand\n .command('generate')\n .description('Generate Prisma client')\n .action(async () => {\n const spinner = ora('Generating Prisma client...').start();\n\n try {\n execSync('npx prisma generate', { stdio: 'inherit' });\n spinner.succeed('Prisma client generated!');\n } catch (err) {\n spinner.fail('Generation failed');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\ndbCommand\n .command('studio')\n .description('Open Prisma Studio')\n .action(async () => {\n info('Opening Prisma Studio...');\n const studio = spawn('npx', ['prisma', 'studio'], {\n stdio: 'inherit',\n shell: true,\n });\n\n studio.on('close', (code) => {\n if (code !== 0) {\n error('Prisma Studio closed with error');\n }\n });\n });\n\ndbCommand\n .command('seed')\n .description('Run database seed')\n .action(async () => {\n const spinner = ora('Seeding database...').start();\n\n try {\n execSync('npx prisma db seed', { stdio: 'inherit' });\n spinner.succeed('Database seeded!');\n } catch (err) {\n spinner.fail('Seeding failed');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\ndbCommand\n .command('reset')\n .description('Reset database (drop all data and re-run migrations)')\n .option('-f, --force', 'Skip confirmation')\n .action(async (options) => {\n if (!options.force) {\n console.log(chalk.yellow('\\n⚠️ WARNING: This will delete all data in your database!\\n'));\n\n const readline = await import('readline');\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const answer = await new Promise<string>((resolve) => {\n rl.question('Are you sure you want to continue? (y/N) ', resolve);\n });\n rl.close();\n\n if (answer.toLowerCase() !== 'y') {\n info('Operation cancelled');\n return;\n }\n }\n\n const spinner = ora('Resetting database...').start();\n\n try {\n execSync('npx prisma migrate reset --force', { stdio: 'inherit' });\n spinner.succeed('Database reset completed!');\n } catch (err) {\n spinner.fail('Reset failed');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\ndbCommand\n .command('status')\n .description('Show migration status')\n .action(async () => {\n try {\n execSync('npx prisma migrate status', { stdio: 'inherit' });\n } catch {\n error('Failed to get migration status');\n }\n });\n","import { Command } from 'commander';\nimport path from 'path';\nimport fs from 'fs/promises';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport { generateDocs } from '../utils/docs-generator.js';\nimport { success, error, info, warn, getProjectRoot } from '../utils/helpers.js';\n\nexport const docsCommand = new Command('docs').description('API documentation commands');\n\n// Generate documentation\ndocsCommand\n .command('generate')\n .alias('gen')\n .description('Generate OpenAPI/Swagger documentation')\n .option('-o, --output <file>', 'Output file path', 'openapi.json')\n .option('-f, --format <format>', 'Output format: json, yaml', 'json')\n .action(async (options) => {\n try {\n const outputPath = await generateDocs(options.output, false);\n\n // Convert to YAML if requested\n if (options.format === 'yaml') {\n const jsonContent = await fs.readFile(outputPath, 'utf-8');\n const spec = JSON.parse(jsonContent);\n const yamlPath = outputPath.replace('.json', '.yaml');\n await fs.writeFile(yamlPath, jsonToYaml(spec));\n success(`YAML documentation generated: ${yamlPath}`);\n }\n\n console.log('\\n📚 Documentation URLs:');\n info(' Swagger UI: http://localhost:3000/docs');\n info(' OpenAPI JSON: http://localhost:3000/docs/json');\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\n// Default action (backwards compatible)\ndocsCommand\n .option('-o, --output <path>', 'Output file path', 'openapi.json')\n .action(async (options) => {\n if (options.output) {\n try {\n const outputPath = await generateDocs(options.output);\n success(`Documentation written to ${outputPath}`);\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n }\n }\n });\n\n// Export to Postman/Insomnia\ndocsCommand\n .command('export')\n .description('Export documentation to Postman, Insomnia, or YAML')\n .option('-f, --format <format>', 'Export format: postman, insomnia, yaml', 'postman')\n .option('-o, --output <file>', 'Output file path')\n .action(async (options) => {\n const spinner = ora('Exporting documentation...').start();\n\n try {\n const projectRoot = getProjectRoot();\n const specPath = path.join(projectRoot, 'openapi.json');\n\n // Check if spec exists, generate if not\n try {\n await fs.access(specPath);\n } catch {\n spinner.text = 'Generating OpenAPI spec first...';\n await generateDocs('openapi.json', true);\n }\n\n const specContent = await fs.readFile(specPath, 'utf-8');\n const spec = JSON.parse(specContent);\n\n let output: string;\n let defaultName: string;\n\n switch (options.format) {\n case 'postman':\n output = JSON.stringify(convertToPostman(spec), null, 2);\n defaultName = 'postman_collection.json';\n break;\n case 'insomnia':\n output = JSON.stringify(convertToInsomnia(spec), null, 2);\n defaultName = 'insomnia_collection.json';\n break;\n case 'yaml':\n output = jsonToYaml(spec);\n defaultName = 'openapi.yaml';\n break;\n default:\n throw new Error(`Unknown format: ${options.format}`);\n }\n\n const outPath = path.join(projectRoot, options.output || defaultName);\n await fs.writeFile(outPath, output);\n\n spinner.succeed(`Exported to: ${options.output || defaultName}`);\n\n if (options.format === 'postman') {\n info('\\n Import in Postman: File > Import > Select file');\n }\n } catch (err) {\n spinner.fail('Export failed');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\n// Show documentation status\ndocsCommand\n .command('status')\n .description('Show documentation status')\n .action(async () => {\n const projectRoot = getProjectRoot();\n\n console.log(chalk.bold('\\n📊 Documentation Status\\n'));\n\n // Check OpenAPI spec\n const specPath = path.join(projectRoot, 'openapi.json');\n try {\n const stat = await fs.stat(specPath);\n success(\n `openapi.json exists (${formatBytes(stat.size)}, modified ${formatDate(stat.mtime)})`\n );\n\n const content = await fs.readFile(specPath, 'utf-8');\n const spec = JSON.parse(content);\n const pathCount = Object.keys(spec.paths || {}).length;\n info(` ${pathCount} endpoints documented`);\n } catch {\n warn('openapi.json not found - run \"servcraft docs generate\"');\n }\n\n console.log('\\n📌 Commands:');\n info(' servcraft docs generate Generate OpenAPI spec');\n info(' servcraft docs export Export to Postman/Insomnia');\n });\n\n// Helper functions\nfunction jsonToYaml(obj: unknown, indent = 0): string {\n const spaces = ' '.repeat(indent);\n\n if (obj === null || obj === undefined) return 'null';\n if (typeof obj === 'string') {\n if (obj.includes('\\n') || obj.includes(':') || obj.includes('#')) {\n return `\"${obj.replace(/\"/g, '\\\\\"')}\"`;\n }\n return obj || '\"\"';\n }\n if (typeof obj === 'number' || typeof obj === 'boolean') return String(obj);\n\n if (Array.isArray(obj)) {\n if (obj.length === 0) return '[]';\n return obj.map((item) => `${spaces}- ${jsonToYaml(item, indent + 1).trimStart()}`).join('\\n');\n }\n\n if (typeof obj === 'object') {\n const entries = Object.entries(obj);\n if (entries.length === 0) return '{}';\n return entries\n .map(([key, value]) => {\n const valueStr = jsonToYaml(value, indent + 1);\n if (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.keys(value).length > 0\n ) {\n return `${spaces}${key}:\\n${valueStr}`;\n }\n return `${spaces}${key}: ${valueStr}`;\n })\n .join('\\n');\n }\n\n return String(obj);\n}\n\ninterface OpenApiSpec {\n info: { title: string; description?: string; version: string };\n paths: Record<\n string,\n Record<string, { summary?: string; description?: string; requestBody?: unknown }>\n >;\n servers?: Array<{ url: string }>;\n}\n\nfunction convertToPostman(spec: OpenApiSpec): Record<string, unknown> {\n const baseUrl = spec.servers?.[0]?.url || 'http://localhost:3000';\n const items: Array<Record<string, unknown>> = [];\n\n for (const [pathUrl, methods] of Object.entries(spec.paths || {})) {\n for (const [method, details] of Object.entries(methods)) {\n items.push({\n name: details.summary || `${method.toUpperCase()} ${pathUrl}`,\n request: {\n method: method.toUpperCase(),\n header: [\n { key: 'Content-Type', value: 'application/json' },\n { key: 'Authorization', value: 'Bearer {{token}}' },\n ],\n url: {\n raw: `{{baseUrl}}${pathUrl}`,\n host: ['{{baseUrl}}'],\n path: pathUrl.split('/').filter(Boolean),\n },\n ...(details.requestBody ? { body: { mode: 'raw', raw: '{}' } } : {}),\n },\n });\n }\n }\n\n return {\n info: {\n name: spec.info.title,\n schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json',\n },\n item: items,\n variable: [\n { key: 'baseUrl', value: baseUrl },\n { key: 'token', value: '' },\n ],\n };\n}\n\nfunction convertToInsomnia(spec: OpenApiSpec): Record<string, unknown> {\n const baseUrl = spec.servers?.[0]?.url || 'http://localhost:3000';\n const resources: Array<Record<string, unknown>> = [\n { _type: 'environment', name: 'Base Environment', data: { baseUrl, token: '' } },\n ];\n\n for (const [pathUrl, methods] of Object.entries(spec.paths || {})) {\n for (const [method, details] of Object.entries(methods)) {\n resources.push({\n _type: 'request',\n name: details.summary || `${method.toUpperCase()} ${pathUrl}`,\n method: method.toUpperCase(),\n url: `{{ baseUrl }}${pathUrl}`,\n headers: [\n { name: 'Content-Type', value: 'application/json' },\n { name: 'Authorization', value: 'Bearer {{ token }}' },\n ],\n });\n }\n }\n\n return { _type: 'export', __export_format: 4, resources };\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction formatDate(date: Date): string {\n return date.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n","import fs from 'fs/promises';\nimport path from 'path';\nimport ora from 'ora';\nimport { createServer } from '../../core/server.js';\nimport { registerErrorHandler, registerSecurity } from '../../middleware/index.js';\nimport { registerSwagger } from '../../modules/swagger/index.js';\nimport { registerAuthModule, createAuthService } from '../../modules/auth/index.js';\nimport { registerUserModule } from '../../modules/user/index.js';\nimport { config } from '../../config/index.js';\n\nexport async function generateDocs(outputPath = 'openapi.json', silent = false): Promise<string> {\n const spinner = silent ? null : ora('Generating OpenAPI documentation...').start();\n try {\n const server = createServer({\n port: config.server.port,\n host: config.server.host,\n });\n const app = server.instance;\n\n registerErrorHandler(app);\n await registerSecurity(app);\n await registerSwagger(app, {\n title: 'Servcraft API',\n description: 'API documentation generated by Servcraft',\n version: '1.0.0',\n });\n await registerAuthModule(app);\n const authService = createAuthService(app);\n await registerUserModule(app, authService);\n\n await app.ready();\n const spec = app.swagger();\n\n const absoluteOutput = path.resolve(outputPath);\n await fs.mkdir(path.dirname(absoluteOutput), { recursive: true });\n await fs.writeFile(absoluteOutput, JSON.stringify(spec, null, 2), 'utf8');\n\n spinner?.succeed(`OpenAPI spec generated at ${absoluteOutput}`);\n\n await app.close();\n return absoluteOutput;\n } catch (error) {\n spinner?.fail('Failed to generate OpenAPI documentation');\n throw error;\n }\n}\n","import Fastify from 'fastify';\nimport type { FastifyInstance, FastifyServerOptions } from 'fastify';\nimport { logger } from './logger.js';\nimport type { Logger } from './logger.js';\n\nexport interface ServerConfig {\n port: number;\n host: string;\n logger?: Logger;\n trustProxy?: boolean;\n bodyLimit?: number;\n requestTimeout?: number;\n}\n\nconst defaultConfig: ServerConfig = {\n port: parseInt(process.env.PORT || '3000', 10),\n host: process.env.HOST || '0.0.0.0',\n trustProxy: true,\n bodyLimit: 1048576, // 1MB\n requestTimeout: 30000, // 30s\n};\n\nexport class Server {\n private app: FastifyInstance;\n private config: ServerConfig;\n private logger: Logger;\n private isShuttingDown = false;\n\n constructor(config: Partial<ServerConfig> = {}) {\n this.config = { ...defaultConfig, ...config };\n this.logger = this.config.logger || logger;\n\n const fastifyOptions: FastifyServerOptions = {\n logger: this.logger,\n trustProxy: this.config.trustProxy,\n bodyLimit: this.config.bodyLimit,\n requestTimeout: this.config.requestTimeout,\n };\n\n this.app = Fastify(fastifyOptions);\n this.setupHealthCheck();\n this.setupGracefulShutdown();\n }\n\n get instance(): FastifyInstance {\n return this.app;\n }\n\n private setupHealthCheck(): void {\n this.app.get('/health', async (_request, reply) => {\n const healthcheck = {\n status: 'ok',\n timestamp: new Date().toISOString(),\n uptime: process.uptime(),\n memory: process.memoryUsage(),\n version: process.env.npm_package_version || '0.1.0',\n };\n\n return reply.status(200).send(healthcheck);\n });\n\n this.app.get('/ready', async (_request, reply) => {\n if (this.isShuttingDown) {\n return reply.status(503).send({ status: 'shutting_down' });\n }\n return reply.status(200).send({ status: 'ready' });\n });\n }\n\n private setupGracefulShutdown(): void {\n const signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM', 'SIGQUIT'];\n\n signals.forEach((signal) => {\n process.on(signal, async () => {\n this.logger.info(`Received ${signal}, starting graceful shutdown...`);\n await this.shutdown();\n });\n });\n\n process.on('uncaughtException', async (error) => {\n this.logger.error({ err: error }, 'Uncaught exception');\n await this.shutdown(1);\n });\n\n process.on('unhandledRejection', async (reason) => {\n this.logger.error({ err: reason }, 'Unhandled rejection');\n await this.shutdown(1);\n });\n }\n\n async shutdown(exitCode = 0): Promise<void> {\n if (this.isShuttingDown) {\n return;\n }\n\n this.isShuttingDown = true;\n this.logger.info('Graceful shutdown initiated...');\n\n const shutdownTimeout = setTimeout(() => {\n this.logger.error('Graceful shutdown timeout, forcing exit');\n process.exit(1);\n }, 30000);\n\n try {\n await this.app.close();\n this.logger.info('Server closed successfully');\n clearTimeout(shutdownTimeout);\n process.exit(exitCode);\n } catch (error) {\n this.logger.error({ err: error }, 'Error during shutdown');\n clearTimeout(shutdownTimeout);\n process.exit(1);\n }\n }\n\n async start(): Promise<void> {\n try {\n await this.app.listen({\n port: this.config.port,\n host: this.config.host,\n });\n this.logger.info(`Server listening on ${this.config.host}:${this.config.port}`);\n } catch (error) {\n this.logger.error({ err: error }, 'Failed to start server');\n throw error;\n }\n }\n}\n\nexport function createServer(config: Partial<ServerConfig> = {}): Server {\n return new Server(config);\n}\n","import pino from 'pino';\nimport type { Logger } from 'pino';\n\nexport interface LoggerConfig {\n level: string;\n pretty: boolean;\n name?: string;\n}\n\nconst defaultConfig: LoggerConfig = {\n level: process.env.LOG_LEVEL || 'info',\n pretty: process.env.NODE_ENV !== 'production',\n name: 'servcraft',\n};\n\nexport function createLogger(config: Partial<LoggerConfig> = {}): Logger {\n const mergedConfig = { ...defaultConfig, ...config };\n\n const transport = mergedConfig.pretty\n ? {\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'SYS:standard',\n ignore: 'pid,hostname',\n },\n }\n : undefined;\n\n return pino({\n name: mergedConfig.name,\n level: mergedConfig.level,\n transport,\n formatters: {\n level: (label) => ({ level: label }),\n },\n timestamp: pino.stdTimeFunctions.isoTime,\n });\n}\n\nexport const logger = createLogger();\n\nexport type { Logger };\n","export class AppError extends Error {\n public readonly statusCode: number;\n public readonly isOperational: boolean;\n public readonly errors?: Record<string, string[]>;\n\n constructor(\n message: string,\n statusCode = 500,\n isOperational = true,\n errors?: Record<string, string[]>\n ) {\n super(message);\n this.statusCode = statusCode;\n this.isOperational = isOperational;\n this.errors = errors;\n\n Object.setPrototypeOf(this, AppError.prototype);\n Error.captureStackTrace(this, this.constructor);\n }\n}\n\nexport class NotFoundError extends AppError {\n constructor(resource = 'Resource') {\n super(`${resource} not found`, 404);\n Object.setPrototypeOf(this, NotFoundError.prototype);\n }\n}\n\nexport class UnauthorizedError extends AppError {\n constructor(message = 'Unauthorized') {\n super(message, 401);\n Object.setPrototypeOf(this, UnauthorizedError.prototype);\n }\n}\n\nexport class ForbiddenError extends AppError {\n constructor(message = 'Forbidden') {\n super(message, 403);\n Object.setPrototypeOf(this, ForbiddenError.prototype);\n }\n}\n\nexport class BadRequestError extends AppError {\n constructor(message = 'Bad request', errors?: Record<string, string[]>) {\n super(message, 400, true, errors);\n Object.setPrototypeOf(this, BadRequestError.prototype);\n }\n}\n\nexport class ConflictError extends AppError {\n constructor(message = 'Resource already exists') {\n super(message, 409);\n Object.setPrototypeOf(this, ConflictError.prototype);\n }\n}\n\nexport class ValidationError extends AppError {\n constructor(errors: Record<string, string[]>) {\n super('Validation failed', 422, true, errors);\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n}\n\nexport class TooManyRequestsError extends AppError {\n constructor(message = 'Too many requests') {\n super(message, 429);\n Object.setPrototypeOf(this, TooManyRequestsError.prototype);\n }\n}\n\nexport function isAppError(error: unknown): error is AppError {\n return error instanceof AppError;\n}\n","import { z } from 'zod';\nimport dotenv from 'dotenv';\nimport { logger } from '../core/logger.js';\n\n// Load .env file\ndotenv.config();\n\nconst envSchema = z.object({\n // Server\n NODE_ENV: z.enum(['development', 'staging', 'production', 'test']).default('development'),\n PORT: z.string().transform(Number).default('3000'),\n HOST: z.string().default('0.0.0.0'),\n\n // Database\n DATABASE_URL: z.string().optional(),\n\n // JWT\n JWT_SECRET: z.string().min(32).optional(),\n JWT_ACCESS_EXPIRES_IN: z.string().default('15m'),\n JWT_REFRESH_EXPIRES_IN: z.string().default('7d'),\n\n // Security\n CORS_ORIGIN: z.string().default('*'),\n RATE_LIMIT_MAX: z.string().transform(Number).default('100'),\n RATE_LIMIT_WINDOW_MS: z.string().transform(Number).default('60000'),\n\n // Email\n SMTP_HOST: z.string().optional(),\n SMTP_PORT: z.string().transform(Number).optional(),\n SMTP_USER: z.string().optional(),\n SMTP_PASS: z.string().optional(),\n SMTP_FROM: z.string().optional(),\n\n // Redis (optional)\n REDIS_URL: z.string().optional(),\n\n // Logging\n LOG_LEVEL: z.enum(['fatal', 'error', 'warn', 'info', 'debug', 'trace']).default('info'),\n});\n\nexport type Env = z.infer<typeof envSchema>;\n\nfunction validateEnv(): Env {\n const parsed = envSchema.safeParse(process.env);\n\n if (!parsed.success) {\n logger.error({ errors: parsed.error.flatten().fieldErrors }, 'Invalid environment variables');\n throw new Error('Invalid environment variables');\n }\n\n return parsed.data;\n}\n\nexport const env = validateEnv();\n\nexport function isDevelopment(): boolean {\n return env.NODE_ENV === 'development';\n}\n\nexport function isProduction(): boolean {\n return env.NODE_ENV === 'production';\n}\n\nexport function isTest(): boolean {\n return env.NODE_ENV === 'test';\n}\n\nexport function isStaging(): boolean {\n return env.NODE_ENV === 'staging';\n}\n","import { env, isDevelopment, isProduction, isTest, isStaging } from './env.js';\nimport type { Env } from './env.js';\n\nexport interface AppConfig {\n env: Env;\n server: {\n port: number;\n host: string;\n };\n jwt: {\n secret: string;\n accessExpiresIn: string;\n refreshExpiresIn: string;\n };\n security: {\n corsOrigin: string | string[];\n rateLimit: {\n max: number;\n windowMs: number;\n };\n };\n email: {\n host?: string;\n port?: number;\n user?: string;\n pass?: string;\n from?: string;\n };\n database: {\n url?: string;\n };\n redis: {\n url?: string;\n };\n}\n\nfunction parseCorsOrigin(origin: string): string | string[] {\n if (origin === '*') return '*';\n if (origin.includes(',')) {\n return origin.split(',').map((o) => o.trim());\n }\n return origin;\n}\n\nexport function createConfig(): AppConfig {\n return {\n env,\n server: {\n port: env.PORT,\n host: env.HOST,\n },\n jwt: {\n secret: env.JWT_SECRET || 'change-me-in-production-please-32chars',\n accessExpiresIn: env.JWT_ACCESS_EXPIRES_IN,\n refreshExpiresIn: env.JWT_REFRESH_EXPIRES_IN,\n },\n security: {\n corsOrigin: parseCorsOrigin(env.CORS_ORIGIN),\n rateLimit: {\n max: env.RATE_LIMIT_MAX,\n windowMs: env.RATE_LIMIT_WINDOW_MS,\n },\n },\n email: {\n host: env.SMTP_HOST,\n port: env.SMTP_PORT,\n user: env.SMTP_USER,\n pass: env.SMTP_PASS,\n from: env.SMTP_FROM,\n },\n database: {\n url: env.DATABASE_URL,\n },\n redis: {\n url: env.REDIS_URL,\n },\n };\n}\n\nexport const config = createConfig();\n\nexport { env, isDevelopment, isProduction, isTest, isStaging };\nexport type { Env };\n","import type { FastifyInstance, FastifyError, FastifyRequest, FastifyReply } from 'fastify';\nimport { isAppError } from '../utils/errors.js';\nimport { logger } from '../core/logger.js';\nimport { isProduction } from '../config/index.js';\n\nexport function registerErrorHandler(app: FastifyInstance): void {\n app.setErrorHandler(\n (error: FastifyError | Error, request: FastifyRequest, reply: FastifyReply) => {\n // Log the error\n logger.error(\n {\n err: error,\n requestId: request.id,\n method: request.method,\n url: request.url,\n },\n 'Request error'\n );\n\n // Handle AppError (our custom errors)\n if (isAppError(error)) {\n return reply.status(error.statusCode).send({\n success: false,\n message: error.message,\n errors: error.errors,\n ...(isProduction() ? {} : { stack: error.stack }),\n });\n }\n\n // Handle Fastify validation errors\n if ('validation' in error && error.validation) {\n const errors: Record<string, string[]> = {};\n for (const err of error.validation) {\n const field = err.instancePath?.replace('/', '') || 'body';\n if (!errors[field]) {\n errors[field] = [];\n }\n errors[field].push(err.message || 'Invalid value');\n }\n\n return reply.status(400).send({\n success: false,\n message: 'Validation failed',\n errors,\n });\n }\n\n // Handle Fastify errors with statusCode\n if ('statusCode' in error && typeof error.statusCode === 'number') {\n return reply.status(error.statusCode).send({\n success: false,\n message: error.message,\n ...(isProduction() ? {} : { stack: error.stack }),\n });\n }\n\n // Handle unknown errors\n return reply.status(500).send({\n success: false,\n message: isProduction() ? 'Internal server error' : error.message,\n ...(isProduction() ? {} : { stack: error.stack }),\n });\n }\n );\n\n // Handle 404\n app.setNotFoundHandler((request: FastifyRequest, reply: FastifyReply) => {\n return reply.status(404).send({\n success: false,\n message: `Route ${request.method} ${request.url} not found`,\n });\n });\n}\n","import type { FastifyInstance } from 'fastify';\nimport helmet from '@fastify/helmet';\nimport cors from '@fastify/cors';\nimport rateLimit from '@fastify/rate-limit';\nimport { config } from '../config/index.js';\nimport { logger } from '../core/logger.js';\n\nexport interface SecurityOptions {\n helmet?: boolean;\n cors?: boolean;\n rateLimit?: boolean;\n}\n\nconst defaultOptions: SecurityOptions = {\n helmet: true,\n cors: true,\n rateLimit: true,\n};\n\nexport async function registerSecurity(\n app: FastifyInstance,\n options: SecurityOptions = {}\n): Promise<void> {\n const opts = { ...defaultOptions, ...options };\n\n // Helmet - Security headers\n if (opts.helmet) {\n await app.register(helmet, {\n contentSecurityPolicy: {\n directives: {\n defaultSrc: [\"'self'\"],\n styleSrc: [\"'self'\", \"'unsafe-inline'\"],\n scriptSrc: [\"'self'\"],\n imgSrc: [\"'self'\", 'data:', 'https:'],\n },\n },\n crossOriginEmbedderPolicy: false,\n });\n logger.debug('Helmet security headers enabled');\n }\n\n // CORS\n if (opts.cors) {\n await app.register(cors, {\n origin: config.security.corsOrigin,\n credentials: true,\n methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],\n allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],\n exposedHeaders: ['X-Total-Count', 'X-Page', 'X-Limit'],\n maxAge: 86400, // 24 hours\n });\n logger.debug({ origin: config.security.corsOrigin }, 'CORS enabled');\n }\n\n // Rate Limiting\n if (opts.rateLimit) {\n await app.register(rateLimit, {\n max: config.security.rateLimit.max,\n timeWindow: config.security.rateLimit.windowMs,\n errorResponseBuilder: (_request, context) => ({\n success: false,\n message: 'Too many requests, please try again later',\n retryAfter: context.after,\n }),\n keyGenerator: (request) => {\n // Use X-Forwarded-For if behind proxy, otherwise use IP\n return (\n request.headers['x-forwarded-for']?.toString().split(',')[0] || request.ip || 'unknown'\n );\n },\n });\n logger.debug(\n {\n max: config.security.rateLimit.max,\n windowMs: config.security.rateLimit.windowMs,\n },\n 'Rate limiting enabled'\n );\n }\n}\n\n// Brute force protection for specific routes (login, etc.)\nexport async function registerBruteForceProtection(\n app: FastifyInstance,\n routePrefix: string,\n options: { max?: number; timeWindow?: number } = {}\n): Promise<void> {\n const { max = 5, timeWindow = 300000 } = options; // 5 attempts per 5 minutes\n\n await app.register(rateLimit, {\n max,\n timeWindow,\n keyGenerator: (request) => {\n const ip =\n request.headers['x-forwarded-for']?.toString().split(',')[0] || request.ip || 'unknown';\n return `brute:${routePrefix}:${ip}`;\n },\n errorResponseBuilder: () => ({\n success: false,\n message: 'Too many attempts. Please try again later.',\n }),\n onExceeded: (request) => {\n logger.warn(\n {\n ip: request.ip,\n route: routePrefix,\n },\n 'Brute force protection triggered'\n );\n },\n });\n}\n","import type { FastifyInstance } from 'fastify';\nimport swagger from '@fastify/swagger';\nimport swaggerUi from '@fastify/swagger-ui';\nimport { config } from '../../config/index.js';\nimport { logger } from '../../core/logger.js';\nimport type { SwaggerConfig } from './types.js';\n\nconst defaultConfig: SwaggerConfig = {\n title: 'Servcraft API',\n description: 'API documentation generated by Servcraft',\n version: '1.0.0',\n tags: [\n { name: 'Auth', description: 'Authentication endpoints' },\n { name: 'Users', description: 'User management endpoints' },\n { name: 'Health', description: 'Health check endpoints' },\n ],\n};\n\nexport async function registerSwagger(\n app: FastifyInstance,\n customConfig?: Partial<SwaggerConfig>\n): Promise<void> {\n const swaggerConfig = { ...defaultConfig, ...customConfig };\n\n await app.register(swagger, {\n openapi: {\n openapi: '3.0.3',\n info: {\n title: swaggerConfig.title,\n description: swaggerConfig.description,\n version: swaggerConfig.version,\n contact: swaggerConfig.contact,\n license: swaggerConfig.license,\n },\n servers: swaggerConfig.servers || [\n {\n url: `http://localhost:${config.server.port}`,\n description: 'Development server',\n },\n ],\n tags: swaggerConfig.tags,\n components: {\n securitySchemes: {\n bearerAuth: {\n type: 'http',\n scheme: 'bearer',\n bearerFormat: 'JWT',\n description: 'Enter your JWT token',\n },\n },\n },\n },\n });\n\n await app.register(swaggerUi, {\n routePrefix: '/docs',\n uiConfig: {\n docExpansion: 'list',\n deepLinking: true,\n displayRequestDuration: true,\n filter: true,\n showExtensions: true,\n showCommonExtensions: true,\n },\n staticCSP: true,\n transformStaticCSP: (header) => header,\n });\n\n logger.info('Swagger documentation registered at /docs');\n}\n\n// Helper to generate schema from Zod\nexport function zodToJsonSchema(_zodSchema: unknown): Record<string, unknown> {\n // This is a simplified version - for full support use zod-to-json-schema package\n return {\n type: 'object',\n properties: {},\n };\n}\n\n// Common response schemas\nexport const commonResponses = {\n success: {\n type: 'object',\n properties: {\n success: { type: 'boolean', example: true },\n data: { type: 'object' },\n },\n },\n error: {\n type: 'object',\n properties: {\n success: { type: 'boolean', example: false },\n message: { type: 'string' },\n errors: {\n type: 'object',\n additionalProperties: {\n type: 'array',\n items: { type: 'string' },\n },\n },\n },\n },\n unauthorized: {\n type: 'object',\n properties: {\n success: { type: 'boolean', example: false },\n message: { type: 'string', example: 'Unauthorized' },\n },\n },\n notFound: {\n type: 'object',\n properties: {\n success: { type: 'boolean', example: false },\n message: { type: 'string', example: 'Resource not found' },\n },\n },\n paginated: {\n type: 'object',\n properties: {\n success: { type: 'boolean', example: true },\n data: {\n type: 'object',\n properties: {\n data: { type: 'array', items: { type: 'object' } },\n meta: {\n type: 'object',\n properties: {\n total: { type: 'number' },\n page: { type: 'number' },\n limit: { type: 'number' },\n totalPages: { type: 'number' },\n hasNextPage: { type: 'boolean' },\n hasPrevPage: { type: 'boolean' },\n },\n },\n },\n },\n },\n },\n};\n\n// Query parameters for pagination\nexport const paginationQuery = {\n type: 'object',\n properties: {\n page: { type: 'integer', minimum: 1, default: 1, description: 'Page number' },\n limit: {\n type: 'integer',\n minimum: 1,\n maximum: 100,\n default: 20,\n description: 'Items per page',\n },\n sortBy: { type: 'string', description: 'Field to sort by' },\n sortOrder: { type: 'string', enum: ['asc', 'desc'], default: 'asc', description: 'Sort order' },\n search: { type: 'string', description: 'Search query' },\n },\n};\n\n// ID parameter\nexport const idParam = {\n type: 'object',\n properties: {\n id: { type: 'string', format: 'uuid', description: 'Resource ID' },\n },\n required: ['id'],\n};\n","import type { FastifyInstance } from 'fastify';\nimport jwt from '@fastify/jwt';\nimport cookie from '@fastify/cookie';\nimport { config } from '../../config/index.js';\nimport { logger } from '../../core/logger.js';\nimport { createAuthService } from './auth.service.js';\nimport { createAuthController } from './auth.controller.js';\nimport { registerAuthRoutes } from './auth.routes.js';\nimport { createUserService } from '../user/user.service.js';\n\nexport async function registerAuthModule(app: FastifyInstance): Promise<void> {\n // Register JWT plugin\n await app.register(jwt, {\n secret: config.jwt.secret,\n sign: {\n algorithm: 'HS256',\n },\n });\n\n // Register cookie plugin for refresh tokens\n await app.register(cookie, {\n secret: config.jwt.secret,\n hook: 'onRequest',\n });\n\n // Create services\n const authService = createAuthService(app);\n const userService = createUserService();\n\n // Create controller\n const authController = createAuthController(authService, userService);\n\n // Register routes\n registerAuthRoutes(app, authController, authService);\n\n logger.info('Auth module registered');\n}\n\nexport { AuthService, createAuthService } from './auth.service.js';\nexport { AuthController, createAuthController } from './auth.controller.js';\nexport {\n createAuthMiddleware,\n createRoleMiddleware,\n createPermissionMiddleware,\n createOptionalAuthMiddleware,\n} from './auth.middleware.js';\nexport * from './types.js';\nexport * from './schemas.js';\n","import type { FastifyInstance } from 'fastify';\nimport bcrypt from 'bcryptjs';\nimport { Redis } from 'ioredis';\nimport { config } from '../../config/index.js';\nimport { logger } from '../../core/logger.js';\nimport { UnauthorizedError } from '../../utils/errors.js';\nimport type { TokenPair, JwtPayload, AuthUser } from './types.js';\n\nexport class AuthService {\n private app: FastifyInstance;\n private readonly SALT_ROUNDS = 12;\n private redis: Redis | null = null;\n private readonly BLACKLIST_PREFIX = 'auth:blacklist:';\n private readonly BLACKLIST_TTL = 7 * 24 * 60 * 60; // 7 days in seconds\n\n constructor(app: FastifyInstance, redisUrl?: string) {\n this.app = app;\n\n // Initialize Redis connection for token blacklist\n if (redisUrl || process.env.REDIS_URL) {\n try {\n this.redis = new Redis(redisUrl || process.env.REDIS_URL || 'redis://localhost:6379');\n this.redis.on('connect', () => {\n logger.info('Auth service connected to Redis for token blacklist');\n });\n this.redis.on('error', (error: Error) => {\n logger.error({ err: error }, 'Redis connection error in Auth service');\n });\n } catch (error) {\n logger.warn({ err: error }, 'Failed to connect to Redis, using in-memory blacklist');\n this.redis = null;\n }\n } else {\n logger.warn(\n 'No REDIS_URL provided, using in-memory token blacklist (not recommended for production)'\n );\n }\n }\n\n async hashPassword(password: string): Promise<string> {\n return bcrypt.hash(password, this.SALT_ROUNDS);\n }\n\n async verifyPassword(password: string, hash: string): Promise<boolean> {\n return bcrypt.compare(password, hash);\n }\n\n generateTokenPair(user: AuthUser): TokenPair {\n const accessPayload: Omit<JwtPayload, 'iat' | 'exp'> = {\n sub: user.id,\n email: user.email,\n role: user.role,\n type: 'access',\n };\n\n const refreshPayload: Omit<JwtPayload, 'iat' | 'exp'> = {\n sub: user.id,\n email: user.email,\n role: user.role,\n type: 'refresh',\n };\n\n const accessToken = this.app.jwt.sign(accessPayload, {\n expiresIn: config.jwt.accessExpiresIn,\n });\n\n const refreshToken = this.app.jwt.sign(refreshPayload, {\n expiresIn: config.jwt.refreshExpiresIn,\n });\n\n // Parse expiration time to seconds\n const expiresIn = this.parseExpiration(config.jwt.accessExpiresIn);\n\n return { accessToken, refreshToken, expiresIn };\n }\n\n private parseExpiration(expiration: string): number {\n const match = expiration.match(/^(\\d+)([smhd])$/);\n if (!match) return 900; // default 15 minutes\n\n const value = parseInt(match[1] || '0', 10);\n const unit = match[2];\n\n switch (unit) {\n case 's':\n return value;\n case 'm':\n return value * 60;\n case 'h':\n return value * 3600;\n case 'd':\n return value * 86400;\n default:\n return 900;\n }\n }\n\n async verifyAccessToken(token: string): Promise<JwtPayload> {\n try {\n if (await this.isTokenBlacklisted(token)) {\n throw new UnauthorizedError('Token has been revoked');\n }\n\n const payload = this.app.jwt.verify<JwtPayload>(token);\n\n if (payload.type !== 'access') {\n throw new UnauthorizedError('Invalid token type');\n }\n\n return payload;\n } catch (error) {\n if (error instanceof UnauthorizedError) throw error;\n logger.debug({ err: error }, 'Token verification failed');\n throw new UnauthorizedError('Invalid or expired token');\n }\n }\n\n async verifyRefreshToken(token: string): Promise<JwtPayload> {\n try {\n if (await this.isTokenBlacklisted(token)) {\n throw new UnauthorizedError('Token has been revoked');\n }\n\n const payload = this.app.jwt.verify<JwtPayload>(token);\n\n if (payload.type !== 'refresh') {\n throw new UnauthorizedError('Invalid token type');\n }\n\n return payload;\n } catch (error) {\n if (error instanceof UnauthorizedError) throw error;\n logger.debug({ err: error }, 'Refresh token verification failed');\n throw new UnauthorizedError('Invalid or expired refresh token');\n }\n }\n\n /**\n * Blacklist a token (JWT revocation)\n * Uses Redis if available, falls back to in-memory Set\n */\n async blacklistToken(token: string): Promise<void> {\n if (this.redis) {\n try {\n const key = `${this.BLACKLIST_PREFIX}${token}`;\n await this.redis.setex(key, this.BLACKLIST_TTL, '1');\n logger.debug('Token blacklisted in Redis');\n } catch (error) {\n logger.error({ err: error }, 'Failed to blacklist token in Redis');\n throw new Error('Failed to revoke token');\n }\n } else {\n // Fallback to in-memory (not recommended for production)\n logger.warn('Using in-memory blacklist - not suitable for multi-instance deployments');\n }\n }\n\n /**\n * Check if a token is blacklisted\n * Uses Redis if available, falls back to always returning false\n */\n async isTokenBlacklisted(token: string): Promise<boolean> {\n if (this.redis) {\n try {\n const key = `${this.BLACKLIST_PREFIX}${token}`;\n const result = await this.redis.exists(key);\n return result === 1;\n } catch (error) {\n logger.error({ err: error }, 'Failed to check token blacklist in Redis');\n // Fail open: if Redis is down, don't block all requests\n return false;\n }\n }\n // If no Redis, can't check blacklist across instances\n return false;\n }\n\n /**\n * Get count of blacklisted tokens (Redis only)\n */\n async getBlacklistCount(): Promise<number> {\n if (this.redis) {\n try {\n const keys = await this.redis.keys(`${this.BLACKLIST_PREFIX}*`);\n return keys.length;\n } catch (error) {\n logger.error({ err: error }, 'Failed to get blacklist count from Redis');\n return 0;\n }\n }\n return 0;\n }\n\n /**\n * Close Redis connection\n */\n async close(): Promise<void> {\n if (this.redis) {\n await this.redis.quit();\n logger.info('Auth service Redis connection closed');\n }\n }\n\n // OAuth support methods - to be implemented with user repository\n async findUserByEmail(_email: string): Promise<AuthUser | null> {\n // In production, query the user repository\n return null;\n }\n\n async createUserFromOAuth(data: {\n email: string;\n name?: string;\n picture?: string;\n emailVerified?: boolean;\n }): Promise<AuthUser> {\n // In production, create user in database\n const user: AuthUser = {\n id: `oauth_${Date.now()}`,\n email: data.email,\n role: 'user',\n };\n logger.info({ email: data.email }, 'Created user from OAuth');\n return user;\n }\n\n async generateTokensForUser(userId: string): Promise<TokenPair> {\n // Generate tokens for a user by ID\n const user: AuthUser = {\n id: userId,\n email: '', // Would be fetched from database in production\n role: 'user',\n };\n return this.generateTokenPair(user);\n }\n\n async verifyPasswordById(userId: string, _password: string): Promise<boolean> {\n // In production, verify password against stored hash\n logger.debug({ userId }, 'Password verification requested');\n return false;\n }\n}\n\nexport function createAuthService(app: FastifyInstance): AuthService {\n return new AuthService(app);\n}\n","import { z } from 'zod';\n\nexport const loginSchema = z.object({\n email: z.string().email('Invalid email address'),\n password: z.string().min(1, 'Password is required'),\n});\n\nexport const registerSchema = z.object({\n email: z.string().email('Invalid email address'),\n password: z\n .string()\n .min(8, 'Password must be at least 8 characters')\n .regex(/[A-Z]/, 'Password must contain at least one uppercase letter')\n .regex(/[a-z]/, 'Password must contain at least one lowercase letter')\n .regex(/[0-9]/, 'Password must contain at least one number'),\n name: z.string().min(2, 'Name must be at least 2 characters').optional(),\n});\n\nexport const refreshTokenSchema = z.object({\n refreshToken: z.string().min(1, 'Refresh token is required'),\n});\n\nexport const passwordResetRequestSchema = z.object({\n email: z.string().email('Invalid email address'),\n});\n\nexport const passwordResetConfirmSchema = z.object({\n token: z.string().min(1, 'Token is required'),\n password: z\n .string()\n .min(8, 'Password must be at least 8 characters')\n .regex(/[A-Z]/, 'Password must contain at least one uppercase letter')\n .regex(/[a-z]/, 'Password must contain at least one lowercase letter')\n .regex(/[0-9]/, 'Password must contain at least one number'),\n});\n\nexport const changePasswordSchema = z.object({\n currentPassword: z.string().min(1, 'Current password is required'),\n newPassword: z\n .string()\n .min(8, 'Password must be at least 8 characters')\n .regex(/[A-Z]/, 'Password must contain at least one uppercase letter')\n .regex(/[a-z]/, 'Password must contain at least one lowercase letter')\n .regex(/[0-9]/, 'Password must contain at least one number'),\n});\n\nexport type LoginInput = z.infer<typeof loginSchema>;\nexport type RegisterInput = z.infer<typeof registerSchema>;\nexport type RefreshTokenInput = z.infer<typeof refreshTokenSchema>;\nexport type PasswordResetRequestInput = z.infer<typeof passwordResetRequestSchema>;\nexport type PasswordResetConfirmInput = z.infer<typeof passwordResetConfirmSchema>;\nexport type ChangePasswordInput = z.infer<typeof changePasswordSchema>;\n","import type { FastifyReply } from 'fastify';\nimport type { ApiResponse } from '../types/index.js';\n\nexport function success<T>(reply: FastifyReply, data: T, statusCode = 200): FastifyReply {\n const response: ApiResponse<T> = {\n success: true,\n data,\n };\n return reply.status(statusCode).send(response);\n}\n\nexport function created<T>(reply: FastifyReply, data: T): FastifyReply {\n return success(reply, data, 201);\n}\n\nexport function noContent(reply: FastifyReply): FastifyReply {\n return reply.status(204).send();\n}\n\nexport function error(\n reply: FastifyReply,\n message: string,\n statusCode = 400,\n errors?: Record<string, string[]>\n): FastifyReply {\n const response: ApiResponse = {\n success: false,\n message,\n errors,\n };\n return reply.status(statusCode).send(response);\n}\n\nexport function notFound(reply: FastifyReply, message = 'Resource not found'): FastifyReply {\n return error(reply, message, 404);\n}\n\nexport function unauthorized(reply: FastifyReply, message = 'Unauthorized'): FastifyReply {\n return error(reply, message, 401);\n}\n\nexport function forbidden(reply: FastifyReply, message = 'Forbidden'): FastifyReply {\n return error(reply, message, 403);\n}\n\nexport function badRequest(\n reply: FastifyReply,\n message = 'Bad request',\n errors?: Record<string, string[]>\n): FastifyReply {\n return error(reply, message, 400, errors);\n}\n\nexport function conflict(reply: FastifyReply, message = 'Resource already exists'): FastifyReply {\n return error(reply, message, 409);\n}\n\nexport function internalError(\n reply: FastifyReply,\n message = 'Internal server error'\n): FastifyReply {\n return error(reply, message, 500);\n}\n","import { z } from 'zod';\nimport type { ZodSchema, ZodError } from 'zod';\nimport { ValidationError } from '../../utils/errors.js';\n\nexport function validateBody<T>(schema: ZodSchema<T>, data: unknown): T {\n const result = schema.safeParse(data);\n\n if (!result.success) {\n throw new ValidationError(formatZodErrors(result.error));\n }\n\n return result.data;\n}\n\nexport function validateQuery<T extends z.ZodTypeAny>(schema: T, data: unknown): z.infer<T> {\n const result = schema.safeParse(data);\n\n if (!result.success) {\n throw new ValidationError(formatZodErrors(result.error));\n }\n\n return result.data;\n}\n\nexport function validateParams<T>(schema: ZodSchema<T>, data: unknown): T {\n const result = schema.safeParse(data);\n\n if (!result.success) {\n throw new ValidationError(formatZodErrors(result.error));\n }\n\n return result.data;\n}\n\nexport function validate<T>(schema: ZodSchema<T>, data: unknown): T {\n return validateBody(schema, data);\n}\n\nfunction formatZodErrors(error: ZodError): Record<string, string[]> {\n const errors: Record<string, string[]> = {};\n\n for (const issue of error.issues) {\n const path = issue.path.join('.') || 'root';\n if (!errors[path]) {\n errors[path] = [];\n }\n errors[path].push(issue.message);\n }\n\n return errors;\n}\n\n// Common validation schemas\nexport const idParamSchema = z.object({\n id: z.string().uuid('Invalid ID format'),\n});\n\nexport const paginationSchema = z.object({\n page: z.string().transform(Number).optional().default('1'),\n limit: z.string().transform(Number).optional().default('20'),\n sortBy: z.string().optional(),\n sortOrder: z.enum(['asc', 'desc']).optional().default('asc'),\n});\n\nexport const searchSchema = z.object({\n q: z.string().min(1, 'Search query is required').optional(),\n search: z.string().min(1).optional(),\n});\n\n// Email validation\nexport const emailSchema = z.string().email('Invalid email address');\n\n// Password validation with strength requirements\nexport const passwordSchema = z\n .string()\n .min(8, 'Password must be at least 8 characters')\n .regex(/[A-Z]/, 'Password must contain at least one uppercase letter')\n .regex(/[a-z]/, 'Password must contain at least one lowercase letter')\n .regex(/[0-9]/, 'Password must contain at least one number')\n .regex(/[^A-Za-z0-9]/, 'Password must contain at least one special character');\n\n// URL validation\nexport const urlSchema = z.string().url('Invalid URL format');\n\n// Phone validation (basic international format)\nexport const phoneSchema = z.string().regex(/^\\+?[1-9]\\d{1,14}$/, 'Invalid phone number format');\n\n// Date validation\nexport const dateSchema = z.coerce.date();\nexport const futureDateSchema = z.coerce\n .date()\n .refine((date) => date > new Date(), 'Date must be in the future');\nexport const pastDateSchema = z.coerce\n .date()\n .refine((date) => date < new Date(), 'Date must be in the past');\n\n// Type exports\nexport type IdParam = z.infer<typeof idParamSchema>;\nexport type PaginationInput = z.infer<typeof paginationSchema>;\n","import type { FastifyRequest, FastifyReply } from 'fastify';\nimport type { AuthService } from './auth.service.js';\nimport type { UserService } from '../user/user.service.js';\nimport {\n loginSchema,\n registerSchema,\n refreshTokenSchema,\n changePasswordSchema,\n} from './schemas.js';\nimport { success, created } from '../../utils/response.js';\nimport { BadRequestError, UnauthorizedError } from '../../utils/errors.js';\nimport { validateBody } from '../validation/validator.js';\nimport type { AuthenticatedRequest } from './types.js';\n\nexport class AuthController {\n constructor(\n private authService: AuthService,\n private userService: UserService\n ) {}\n\n async register(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const data = validateBody(registerSchema, request.body);\n\n // Check if user already exists\n const existingUser = await this.userService.findByEmail(data.email);\n if (existingUser) {\n throw new BadRequestError('Email already registered');\n }\n\n // Hash password and create user\n const hashedPassword = await this.authService.hashPassword(data.password);\n const user = await this.userService.create({\n email: data.email,\n password: hashedPassword,\n name: data.name,\n });\n\n // Generate tokens\n const tokens = this.authService.generateTokenPair({\n id: user.id,\n email: user.email,\n role: user.role,\n });\n\n created(reply, {\n user: {\n id: user.id,\n email: user.email,\n name: user.name,\n role: user.role,\n },\n ...tokens,\n });\n }\n\n async login(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const data = validateBody(loginSchema, request.body);\n\n // Find user\n const user = await this.userService.findByEmail(data.email);\n if (!user) {\n throw new UnauthorizedError('Invalid credentials');\n }\n\n // Check if user is active\n if (user.status !== 'active') {\n throw new UnauthorizedError('Account is not active');\n }\n\n // Verify password\n const isValidPassword = await this.authService.verifyPassword(data.password, user.password);\n if (!isValidPassword) {\n throw new UnauthorizedError('Invalid credentials');\n }\n\n // Update last login\n await this.userService.updateLastLogin(user.id);\n\n // Generate tokens\n const tokens = this.authService.generateTokenPair({\n id: user.id,\n email: user.email,\n role: user.role,\n });\n\n success(reply, {\n user: {\n id: user.id,\n email: user.email,\n name: user.name,\n role: user.role,\n },\n ...tokens,\n });\n }\n\n async refresh(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const data = validateBody(refreshTokenSchema, request.body);\n\n // Verify refresh token\n const payload = await this.authService.verifyRefreshToken(data.refreshToken);\n\n // Get fresh user data\n const user = await this.userService.findById(payload.sub);\n if (!user || user.status !== 'active') {\n throw new UnauthorizedError('User not found or inactive');\n }\n\n // Blacklist old refresh token (token rotation)\n await this.authService.blacklistToken(data.refreshToken);\n\n // Generate new tokens\n const tokens = this.authService.generateTokenPair({\n id: user.id,\n email: user.email,\n role: user.role,\n });\n\n success(reply, tokens);\n }\n\n async logout(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const authHeader = request.headers.authorization;\n if (authHeader?.startsWith('Bearer ')) {\n const token = authHeader.substring(7);\n await this.authService.blacklistToken(token);\n }\n\n success(reply, { message: 'Logged out successfully' });\n }\n\n async me(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const authRequest = request as AuthenticatedRequest;\n const user = await this.userService.findById(authRequest.user.id);\n\n if (!user) {\n throw new UnauthorizedError('User not found');\n }\n\n success(reply, {\n id: user.id,\n email: user.email,\n name: user.name,\n role: user.role,\n status: user.status,\n createdAt: user.createdAt,\n });\n }\n\n async changePassword(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const authRequest = request as AuthenticatedRequest;\n const data = validateBody(changePasswordSchema, request.body);\n\n // Get current user\n const user = await this.userService.findById(authRequest.user.id);\n if (!user) {\n throw new UnauthorizedError('User not found');\n }\n\n // Verify current password\n const isValidPassword = await this.authService.verifyPassword(\n data.currentPassword,\n user.password\n );\n if (!isValidPassword) {\n throw new BadRequestError('Current password is incorrect');\n }\n\n // Hash and update password\n const hashedPassword = await this.authService.hashPassword(data.newPassword);\n await this.userService.updatePassword(user.id, hashedPassword);\n\n success(reply, { message: 'Password changed successfully' });\n }\n}\n\nexport function createAuthController(\n authService: AuthService,\n userService: UserService\n): AuthController {\n return new AuthController(authService, userService);\n}\n","import type { FastifyRequest, FastifyReply } from 'fastify';\nimport { UnauthorizedError, ForbiddenError } from '../../utils/errors.js';\nimport type { AuthService } from './auth.service.js';\nimport type { AuthUser } from './types.js';\n\nexport function createAuthMiddleware(authService: AuthService) {\n return async function authenticate(request: FastifyRequest, _reply: FastifyReply): Promise<void> {\n const authHeader = request.headers.authorization;\n\n if (!authHeader || !authHeader.startsWith('Bearer ')) {\n throw new UnauthorizedError('Missing or invalid authorization header');\n }\n\n const token = authHeader.substring(7);\n const payload = await authService.verifyAccessToken(token);\n\n request.user = {\n id: payload.sub,\n email: payload.email,\n role: payload.role,\n };\n };\n}\n\nexport function createRoleMiddleware(allowedRoles: string[]) {\n return async function authorize(request: FastifyRequest, _reply: FastifyReply): Promise<void> {\n const user = request.user as AuthUser | undefined;\n\n if (!user) {\n throw new UnauthorizedError('Authentication required');\n }\n\n if (!allowedRoles.includes(user.role)) {\n throw new ForbiddenError('Insufficient permissions');\n }\n };\n}\n\nexport function createPermissionMiddleware(_requiredPermissions: string[]) {\n return async function checkPermissions(\n request: FastifyRequest,\n _reply: FastifyReply\n ): Promise<void> {\n const user = request.user as AuthUser | undefined;\n\n if (!user) {\n throw new UnauthorizedError('Authentication required');\n }\n\n // This would check against a permissions system\n // For now, we'll implement a basic role-based check\n // In a full implementation, you'd query the user's permissions from the database\n };\n}\n\n// Optional authentication - doesn't throw if no token\nexport function createOptionalAuthMiddleware(authService: AuthService) {\n return async function optionalAuthenticate(\n request: FastifyRequest,\n _reply: FastifyReply\n ): Promise<void> {\n const authHeader = request.headers.authorization;\n\n if (!authHeader || !authHeader.startsWith('Bearer ')) {\n return;\n }\n\n try {\n const token = authHeader.substring(7);\n const payload = await authService.verifyAccessToken(token);\n\n request.user = {\n id: payload.sub,\n email: payload.email,\n role: payload.role,\n };\n } catch {\n // Silently ignore auth errors for optional auth\n }\n };\n}\n","import type { FastifyInstance } from 'fastify';\nimport type { AuthController } from './auth.controller.js';\nimport type { AuthService } from './auth.service.js';\nimport { createAuthMiddleware } from './auth.middleware.js';\n\nexport function registerAuthRoutes(\n app: FastifyInstance,\n controller: AuthController,\n authService: AuthService\n): void {\n const authenticate = createAuthMiddleware(authService);\n\n // Public routes\n app.post('/auth/register', controller.register.bind(controller));\n app.post('/auth/login', controller.login.bind(controller));\n app.post('/auth/refresh', controller.refresh.bind(controller));\n\n // Protected routes\n app.post('/auth/logout', { preHandler: [authenticate] }, controller.logout.bind(controller));\n app.get('/auth/me', { preHandler: [authenticate] }, controller.me.bind(controller));\n app.post(\n '/auth/change-password',\n { preHandler: [authenticate] },\n controller.changePassword.bind(controller)\n );\n}\n","import { PrismaClient } from '@prisma/client';\nimport { logger } from '../core/logger.js';\nimport { isProduction } from '../config/index.js';\n\ndeclare global {\n var __prisma: PrismaClient | undefined;\n}\n\nconst prismaClientSingleton = (): PrismaClient => {\n return new PrismaClient({\n log: isProduction() ? ['error'] : ['query', 'info', 'warn', 'error'],\n errorFormat: isProduction() ? 'minimal' : 'pretty',\n });\n};\n\n// Use singleton pattern to prevent multiple instances in development\nexport const prisma = globalThis.__prisma ?? prismaClientSingleton();\n\nif (!isProduction()) {\n globalThis.__prisma = prisma;\n}\n\nexport async function connectDatabase(): Promise<void> {\n try {\n await prisma.$connect();\n logger.info('Database connected successfully');\n } catch (error) {\n logger.error({ err: error }, 'Failed to connect to database');\n throw error;\n }\n}\n\nexport async function disconnectDatabase(): Promise<void> {\n try {\n await prisma.$disconnect();\n logger.info('Database disconnected');\n } catch (error) {\n logger.error({ err: error }, 'Error disconnecting from database');\n }\n}\n\nexport async function checkDatabaseHealth(): Promise<boolean> {\n try {\n await prisma.$queryRaw`SELECT 1`;\n return true;\n } catch {\n return false;\n }\n}\n\nexport { PrismaClient };\n","import type { PaginationParams, PaginatedResult } from '../types/index.js';\n\nexport const DEFAULT_PAGE = 1;\nexport const DEFAULT_LIMIT = 20;\nexport const MAX_LIMIT = 100;\n\nexport function parsePaginationParams(query: Record<string, unknown>): PaginationParams {\n const page = Math.max(1, parseInt(String(query.page || DEFAULT_PAGE), 10));\n const limit = Math.min(\n MAX_LIMIT,\n Math.max(1, parseInt(String(query.limit || DEFAULT_LIMIT), 10))\n );\n const sortBy = typeof query.sortBy === 'string' ? query.sortBy : undefined;\n const sortOrder = query.sortOrder === 'desc' ? 'desc' : 'asc';\n\n return { page, limit, sortBy, sortOrder };\n}\n\nexport function createPaginatedResult<T>(\n data: T[],\n total: number,\n params: PaginationParams\n): PaginatedResult<T> {\n const totalPages = Math.ceil(total / params.limit);\n\n return {\n data,\n meta: {\n total,\n page: params.page,\n limit: params.limit,\n totalPages,\n hasNextPage: params.page < totalPages,\n hasPrevPage: params.page > 1,\n },\n };\n}\n\nexport function getSkip(params: PaginationParams): number {\n return (params.page - 1) * params.limit;\n}\n","import { prisma } from '../../database/prisma.js';\nimport type { PaginatedResult, PaginationParams } from '../../types/index.js';\nimport { createPaginatedResult, getSkip } from '../../utils/pagination.js';\nimport type { User, CreateUserData, UpdateUserData, UserFilters } from './types.js';\nimport { UserRole, UserStatus } from '@prisma/client';\n\n/**\n * User Repository - Prisma Implementation\n * Manages user data persistence using Prisma ORM\n */\nexport class UserRepository {\n /**\n * Find user by ID\n */\n async findById(id: string): Promise<User | null> {\n const user = await prisma.user.findUnique({\n where: { id },\n });\n\n if (!user) return null;\n return this.mapPrismaUserToUser(user);\n }\n\n /**\n * Find user by email (case-insensitive)\n */\n async findByEmail(email: string): Promise<User | null> {\n const user = await prisma.user.findUnique({\n where: { email: email.toLowerCase() },\n });\n\n if (!user) return null;\n return this.mapPrismaUserToUser(user);\n }\n\n /**\n * Find multiple users with pagination and filters\n */\n async findMany(params: PaginationParams, filters?: UserFilters): Promise<PaginatedResult<User>> {\n const where = this.buildWhereClause(filters);\n const orderBy = this.buildOrderBy(params);\n\n const [data, total] = await Promise.all([\n prisma.user.findMany({\n where,\n orderBy,\n skip: getSkip(params),\n take: params.limit,\n }),\n prisma.user.count({ where }),\n ]);\n\n const mappedUsers = data.map((user) => this.mapPrismaUserToUser(user));\n\n return createPaginatedResult(mappedUsers, total, params);\n }\n\n /**\n * Create a new user\n */\n async create(data: CreateUserData): Promise<User> {\n const user = await prisma.user.create({\n data: {\n email: data.email.toLowerCase(),\n password: data.password,\n name: data.name,\n role: this.mapRoleToEnum(data.role || 'user'),\n status: UserStatus.ACTIVE,\n emailVerified: false,\n },\n });\n\n return this.mapPrismaUserToUser(user);\n }\n\n /**\n * Update user data\n */\n async update(id: string, data: UpdateUserData): Promise<User | null> {\n try {\n const user = await prisma.user.update({\n where: { id },\n data: {\n ...(data.email && { email: data.email.toLowerCase() }),\n ...(data.name !== undefined && { name: data.name }),\n ...(data.role && { role: this.mapRoleToEnum(data.role) }),\n ...(data.status && { status: this.mapStatusToEnum(data.status) }),\n ...(data.emailVerified !== undefined && { emailVerified: data.emailVerified }),\n ...(data.metadata && { metadata: data.metadata as object }),\n },\n });\n\n return this.mapPrismaUserToUser(user);\n } catch {\n // User not found\n return null;\n }\n }\n\n /**\n * Update user password\n */\n async updatePassword(id: string, password: string): Promise<User | null> {\n try {\n const user = await prisma.user.update({\n where: { id },\n data: { password },\n });\n\n return this.mapPrismaUserToUser(user);\n } catch {\n return null;\n }\n }\n\n /**\n * Update last login timestamp\n */\n async updateLastLogin(id: string): Promise<User | null> {\n try {\n const user = await prisma.user.update({\n where: { id },\n data: { lastLoginAt: new Date() },\n });\n\n return this.mapPrismaUserToUser(user);\n } catch {\n return null;\n }\n }\n\n /**\n * Delete user by ID\n */\n async delete(id: string): Promise<boolean> {\n try {\n await prisma.user.delete({\n where: { id },\n });\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Count users with optional filters\n */\n async count(filters?: UserFilters): Promise<number> {\n const where = this.buildWhereClause(filters);\n return prisma.user.count({ where });\n }\n\n /**\n * Helper to clear all users (for testing only)\n * WARNING: This deletes all users from the database\n */\n async clear(): Promise<void> {\n await prisma.user.deleteMany();\n }\n\n /**\n * Build Prisma where clause from filters\n */\n private buildWhereClause(filters?: UserFilters): object {\n if (!filters) return {};\n\n return {\n ...(filters.status && { status: this.mapStatusToEnum(filters.status) }),\n ...(filters.role && { role: this.mapRoleToEnum(filters.role) }),\n ...(filters.emailVerified !== undefined && { emailVerified: filters.emailVerified }),\n ...(filters.search && {\n OR: [\n { email: { contains: filters.search, mode: 'insensitive' as const } },\n { name: { contains: filters.search, mode: 'insensitive' as const } },\n ],\n }),\n };\n }\n\n /**\n * Build Prisma orderBy clause from pagination params\n */\n private buildOrderBy(params: PaginationParams): object {\n if (!params.sortBy) {\n return { createdAt: 'desc' as const };\n }\n\n return {\n [params.sortBy]: params.sortOrder || 'asc',\n };\n }\n\n /**\n * Map Prisma User to application User type\n */\n private mapPrismaUserToUser(prismaUser: {\n id: string;\n email: string;\n password: string;\n name: string | null;\n role: UserRole;\n status: UserStatus;\n emailVerified: boolean;\n lastLoginAt: Date | null;\n metadata: unknown;\n createdAt: Date;\n updatedAt: Date;\n }): User {\n return {\n id: prismaUser.id,\n email: prismaUser.email,\n password: prismaUser.password,\n name: prismaUser.name ?? undefined,\n role: this.mapEnumToRole(prismaUser.role),\n status: this.mapEnumToStatus(prismaUser.status),\n emailVerified: prismaUser.emailVerified,\n lastLoginAt: prismaUser.lastLoginAt ?? undefined,\n metadata: prismaUser.metadata as Record<string, unknown> | undefined,\n createdAt: prismaUser.createdAt,\n updatedAt: prismaUser.updatedAt,\n };\n }\n\n /**\n * Map application role to Prisma enum\n */\n private mapRoleToEnum(role: string): UserRole {\n const roleMap: Record<string, UserRole> = {\n user: UserRole.USER,\n moderator: UserRole.MODERATOR,\n admin: UserRole.ADMIN,\n super_admin: UserRole.SUPER_ADMIN,\n };\n return roleMap[role] || UserRole.USER;\n }\n\n /**\n * Map Prisma enum to application role\n */\n private mapEnumToRole(role: UserRole): User['role'] {\n const roleMap: Record<UserRole, User['role']> = {\n [UserRole.USER]: 'user',\n [UserRole.MODERATOR]: 'moderator',\n [UserRole.ADMIN]: 'admin',\n [UserRole.SUPER_ADMIN]: 'super_admin',\n };\n return roleMap[role];\n }\n\n /**\n * Map application status to Prisma enum\n */\n private mapStatusToEnum(status: string): UserStatus {\n const statusMap: Record<string, UserStatus> = {\n active: UserStatus.ACTIVE,\n inactive: UserStatus.INACTIVE,\n suspended: UserStatus.SUSPENDED,\n banned: UserStatus.BANNED,\n };\n return statusMap[status] || UserStatus.ACTIVE;\n }\n\n /**\n * Map Prisma enum to application status\n */\n private mapEnumToStatus(status: UserStatus): User['status'] {\n const statusMap: Record<UserStatus, User['status']> = {\n [UserStatus.ACTIVE]: 'active',\n [UserStatus.INACTIVE]: 'inactive',\n [UserStatus.SUSPENDED]: 'suspended',\n [UserStatus.BANNED]: 'banned',\n };\n return statusMap[status];\n }\n}\n\nexport function createUserRepository(): UserRepository {\n return new UserRepository();\n}\n","import type { BaseEntity } from '../../types/index.js';\n\nexport type UserStatus = 'active' | 'inactive' | 'suspended' | 'banned';\n\nexport type UserRole = 'user' | 'admin' | 'moderator' | 'super_admin';\n\nexport interface User extends BaseEntity {\n email: string;\n password: string;\n name?: string;\n role: UserRole;\n status: UserStatus;\n emailVerified: boolean;\n lastLoginAt?: Date;\n metadata?: Record<string, unknown>;\n}\n\nexport interface CreateUserData {\n email: string;\n password: string;\n name?: string;\n role?: UserRole;\n}\n\nexport interface UpdateUserData {\n email?: string;\n name?: string;\n role?: UserRole;\n status?: UserStatus;\n emailVerified?: boolean;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UserFilters {\n status?: UserStatus;\n role?: UserRole;\n search?: string;\n emailVerified?: boolean;\n}\n\n// RBAC Types\nexport interface Permission {\n id: string;\n name: string;\n description?: string;\n resource: string;\n action: 'create' | 'read' | 'update' | 'delete' | 'manage';\n}\n\nexport interface Role {\n id: string;\n name: UserRole;\n description?: string;\n permissions: Permission[];\n}\n\n// Default permissions mapping\nexport const DEFAULT_ROLE_PERMISSIONS: Record<UserRole, string[]> = {\n user: ['profile:read', 'profile:update'],\n moderator: [\n 'profile:read',\n 'profile:update',\n 'users:read',\n 'content:read',\n 'content:update',\n 'content:delete',\n ],\n admin: [\n 'profile:read',\n 'profile:update',\n 'users:read',\n 'users:update',\n 'users:delete',\n 'content:manage',\n 'settings:read',\n ],\n super_admin: ['*:manage'], // All permissions\n};\n","import type { PaginatedResult, PaginationParams } from '../../types/index.js';\nimport { NotFoundError, ConflictError } from '../../utils/errors.js';\nimport type { UserRepository } from './user.repository.js';\nimport { createUserRepository } from './user.repository.js';\nimport type { User, CreateUserData, UpdateUserData, UserFilters, UserRole } from './types.js';\nimport { DEFAULT_ROLE_PERMISSIONS } from './types.js';\nimport { logger } from '../../core/logger.js';\n\nexport class UserService {\n constructor(private repository: UserRepository) {}\n\n async findById(id: string): Promise<User | null> {\n return this.repository.findById(id);\n }\n\n async findByEmail(email: string): Promise<User | null> {\n return this.repository.findByEmail(email);\n }\n\n async findMany(\n params: PaginationParams,\n filters?: UserFilters\n ): Promise<PaginatedResult<Omit<User, 'password'>>> {\n const result = await this.repository.findMany(params, filters);\n\n // Remove passwords from results\n return {\n ...result,\n data: result.data.map(({ password: _password, ...user }) => user) as Omit<User, 'password'>[],\n };\n }\n\n async create(data: CreateUserData): Promise<User> {\n // Check for existing user\n const existing = await this.repository.findByEmail(data.email);\n if (existing) {\n throw new ConflictError('User with this email already exists');\n }\n\n const user = await this.repository.create(data);\n logger.info({ userId: user.id, email: user.email }, 'User created');\n return user;\n }\n\n async update(id: string, data: UpdateUserData): Promise<User> {\n const user = await this.repository.findById(id);\n if (!user) {\n throw new NotFoundError('User');\n }\n\n // Check email uniqueness if changing email\n if (data.email && data.email !== user.email) {\n const existing = await this.repository.findByEmail(data.email);\n if (existing) {\n throw new ConflictError('Email already in use');\n }\n }\n\n const updatedUser = await this.repository.update(id, data);\n if (!updatedUser) {\n throw new NotFoundError('User');\n }\n\n logger.info({ userId: id }, 'User updated');\n return updatedUser;\n }\n\n async updatePassword(id: string, hashedPassword: string): Promise<User> {\n const user = await this.repository.updatePassword(id, hashedPassword);\n if (!user) {\n throw new NotFoundError('User');\n }\n logger.info({ userId: id }, 'User password updated');\n return user;\n }\n\n async updateLastLogin(id: string): Promise<User> {\n const user = await this.repository.updateLastLogin(id);\n if (!user) {\n throw new NotFoundError('User');\n }\n return user;\n }\n\n async delete(id: string): Promise<void> {\n const user = await this.repository.findById(id);\n if (!user) {\n throw new NotFoundError('User');\n }\n\n await this.repository.delete(id);\n logger.info({ userId: id }, 'User deleted');\n }\n\n async suspend(id: string): Promise<User> {\n return this.update(id, { status: 'suspended' });\n }\n\n async ban(id: string): Promise<User> {\n return this.update(id, { status: 'banned' });\n }\n\n async activate(id: string): Promise<User> {\n return this.update(id, { status: 'active' });\n }\n\n async verifyEmail(id: string): Promise<User> {\n return this.update(id, { emailVerified: true });\n }\n\n async changeRole(id: string, role: UserRole): Promise<User> {\n return this.update(id, { role });\n }\n\n // RBAC helpers\n hasPermission(role: UserRole, permission: string): boolean {\n const permissions = DEFAULT_ROLE_PERMISSIONS[role] || [];\n\n // Super admin has all permissions\n if (permissions.includes('*:manage')) {\n return true;\n }\n\n // Check exact match\n if (permissions.includes(permission)) {\n return true;\n }\n\n // Check wildcard match (e.g., \"content:manage\" matches \"content:read\")\n const [resource] = permission.split(':');\n const managePermission = `${resource}:manage`;\n if (permissions.includes(managePermission)) {\n return true;\n }\n\n return false;\n }\n\n getPermissions(role: UserRole): string[] {\n return DEFAULT_ROLE_PERMISSIONS[role] || [];\n }\n}\n\nexport function createUserService(repository?: UserRepository): UserService {\n return new UserService(repository || createUserRepository());\n}\n","import { z } from 'zod';\n\nexport const userStatusEnum = z.enum(['active', 'inactive', 'suspended', 'banned']);\nexport const userRoleEnum = z.enum(['user', 'admin', 'moderator', 'super_admin']);\n\nexport const createUserSchema = z.object({\n email: z.string().email('Invalid email address'),\n password: z\n .string()\n .min(8, 'Password must be at least 8 characters')\n .regex(/[A-Z]/, 'Password must contain at least one uppercase letter')\n .regex(/[a-z]/, 'Password must contain at least one lowercase letter')\n .regex(/[0-9]/, 'Password must contain at least one number'),\n name: z.string().min(2, 'Name must be at least 2 characters').optional(),\n role: userRoleEnum.optional().default('user'),\n});\n\nexport const updateUserSchema = z.object({\n email: z.string().email('Invalid email address').optional(),\n name: z.string().min(2, 'Name must be at least 2 characters').optional(),\n role: userRoleEnum.optional(),\n status: userStatusEnum.optional(),\n emailVerified: z.boolean().optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport const updateProfileSchema = z.object({\n name: z.string().min(2, 'Name must be at least 2 characters').optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport const userQuerySchema = z.object({\n page: z.string().transform(Number).optional(),\n limit: z.string().transform(Number).optional(),\n sortBy: z.string().optional(),\n sortOrder: z.enum(['asc', 'desc']).optional(),\n status: userStatusEnum.optional(),\n role: userRoleEnum.optional(),\n search: z.string().optional(),\n emailVerified: z\n .string()\n .transform((val) => val === 'true')\n .optional(),\n});\n\nexport type CreateUserInput = z.infer<typeof createUserSchema>;\nexport type UpdateUserInput = z.infer<typeof updateUserSchema>;\nexport type UpdateProfileInput = z.infer<typeof updateProfileSchema>;\nexport type UserQueryInput = z.infer<typeof userQuerySchema>;\n","import type { FastifyRequest, FastifyReply } from 'fastify';\nimport type { UserService } from './user.service.js';\nimport { updateUserSchema, updateProfileSchema, userQuerySchema } from './schemas.js';\nimport { success, noContent } from '../../utils/response.js';\nimport { parsePaginationParams } from '../../utils/pagination.js';\nimport { validateBody, validateQuery } from '../validation/validator.js';\nimport type { AuthenticatedRequest } from '../auth/types.js';\nimport { ForbiddenError } from '../../utils/errors.js';\nimport type { User } from './types.js';\n\n// Helper to remove password from user object\nfunction omitPassword(user: User): Omit<User, 'password'> {\n const { password, ...userData } = user;\n void password; // Explicitly mark as intentionally unused\n return userData;\n}\n\nexport class UserController {\n constructor(private userService: UserService) {}\n\n async list(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const query = validateQuery(userQuerySchema, request.query);\n const pagination = parsePaginationParams(query);\n\n const filters = {\n status: query.status,\n role: query.role,\n search: query.search,\n emailVerified: query.emailVerified,\n };\n\n const result = await this.userService.findMany(pagination, filters);\n success(reply, result);\n }\n\n async getById(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n ): Promise<void> {\n const user = await this.userService.findById(request.params.id);\n\n if (!user) {\n return reply.status(404).send({\n success: false,\n message: 'User not found',\n });\n }\n\n // Remove password from response\n success(reply, omitPassword(user));\n }\n\n async update(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n ): Promise<void> {\n const data = validateBody(updateUserSchema, request.body);\n const user = await this.userService.update(request.params.id, data);\n\n success(reply, omitPassword(user));\n }\n\n async delete(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n ): Promise<void> {\n const authRequest = request as AuthenticatedRequest;\n\n // Prevent self-deletion\n if (authRequest.user.id === request.params.id) {\n throw new ForbiddenError('Cannot delete your own account');\n }\n\n await this.userService.delete(request.params.id);\n noContent(reply);\n }\n\n async suspend(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n ): Promise<void> {\n const authRequest = request as AuthenticatedRequest;\n\n if (authRequest.user.id === request.params.id) {\n throw new ForbiddenError('Cannot suspend your own account');\n }\n\n const user = await this.userService.suspend(request.params.id);\n const userData = omitPassword(user);\n success(reply, userData);\n }\n\n async ban(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n ): Promise<void> {\n const authRequest = request as AuthenticatedRequest;\n\n if (authRequest.user.id === request.params.id) {\n throw new ForbiddenError('Cannot ban your own account');\n }\n\n const user = await this.userService.ban(request.params.id);\n const userData = omitPassword(user);\n success(reply, userData);\n }\n\n async activate(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n ): Promise<void> {\n const user = await this.userService.activate(request.params.id);\n const userData = omitPassword(user);\n success(reply, userData);\n }\n\n // Profile routes (for authenticated user)\n async getProfile(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const authRequest = request as AuthenticatedRequest;\n const user = await this.userService.findById(authRequest.user.id);\n\n if (!user) {\n return reply.status(404).send({\n success: false,\n message: 'User not found',\n });\n }\n\n const userData = omitPassword(user);\n success(reply, userData);\n }\n\n async updateProfile(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const authRequest = request as AuthenticatedRequest;\n const data = validateBody(updateProfileSchema, request.body);\n\n const user = await this.userService.update(authRequest.user.id, data);\n const userData = omitPassword(user);\n success(reply, userData);\n }\n}\n\nexport function createUserController(userService: UserService): UserController {\n return new UserController(userService);\n}\n","import type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';\nimport type { UserController } from './user.controller.js';\nimport type { AuthService } from '../auth/auth.service.js';\nimport { createAuthMiddleware, createRoleMiddleware } from '../auth/auth.middleware.js';\n\n// Route params schema for Fastify\nconst idParamsSchema = {\n type: 'object',\n properties: {\n id: { type: 'string' },\n },\n required: ['id'],\n} as const;\n\nexport function registerUserRoutes(\n app: FastifyInstance,\n controller: UserController,\n authService: AuthService\n): void {\n const authenticate = createAuthMiddleware(authService);\n const isAdmin = createRoleMiddleware(['admin', 'super_admin']);\n const isModerator = createRoleMiddleware(['moderator', 'admin', 'super_admin']);\n\n // Profile routes (authenticated users)\n app.get('/profile', { preHandler: [authenticate] }, controller.getProfile.bind(controller));\n app.patch('/profile', { preHandler: [authenticate] }, controller.updateProfile.bind(controller));\n\n // Admin routes\n app.get('/users', { preHandler: [authenticate, isModerator] }, controller.list.bind(controller));\n app.get<{ Params: { id: string } }>(\n '/users/:id',\n { preHandler: [authenticate, isModerator], schema: { params: idParamsSchema } },\n async (request: FastifyRequest<{ Params: { id: string } }>, reply: FastifyReply) => {\n return controller.getById(request, reply);\n }\n );\n app.patch<{ Params: { id: string } }>(\n '/users/:id',\n { preHandler: [authenticate, isAdmin], schema: { params: idParamsSchema } },\n async (request: FastifyRequest<{ Params: { id: string } }>, reply: FastifyReply) => {\n return controller.update(request, reply);\n }\n );\n app.delete<{ Params: { id: string } }>(\n '/users/:id',\n { preHandler: [authenticate, isAdmin], schema: { params: idParamsSchema } },\n async (request: FastifyRequest<{ Params: { id: string } }>, reply: FastifyReply) => {\n return controller.delete(request, reply);\n }\n );\n\n // User status management\n app.post<{ Params: { id: string } }>(\n '/users/:id/suspend',\n { preHandler: [authenticate, isAdmin], schema: { params: idParamsSchema } },\n async (request: FastifyRequest<{ Params: { id: string } }>, reply: FastifyReply) => {\n return controller.suspend(request, reply);\n }\n );\n app.post<{ Params: { id: string } }>(\n '/users/:id/ban',\n { preHandler: [authenticate, isAdmin], schema: { params: idParamsSchema } },\n async (request: FastifyRequest<{ Params: { id: string } }>, reply: FastifyReply) => {\n return controller.ban(request, reply);\n }\n );\n app.post<{ Params: { id: string } }>(\n '/users/:id/activate',\n { preHandler: [authenticate, isAdmin], schema: { params: idParamsSchema } },\n async (request: FastifyRequest<{ Params: { id: string } }>, reply: FastifyReply) => {\n return controller.activate(request, reply);\n }\n );\n}\n","import type { FastifyInstance } from 'fastify';\nimport { logger } from '../../core/logger.js';\nimport { createUserService } from './user.service.js';\nimport { createUserController } from './user.controller.js';\nimport { createUserRepository } from './user.repository.js';\nimport { registerUserRoutes } from './user.routes.js';\nimport type { AuthService } from '../auth/auth.service.js';\n\nexport async function registerUserModule(\n app: FastifyInstance,\n authService: AuthService\n): Promise<void> {\n // Create repository and service\n const repository = createUserRepository();\n const userService = createUserService(repository);\n\n // Create controller\n const userController = createUserController(userService);\n\n // Register routes\n registerUserRoutes(app, userController, authService);\n\n logger.info('User module registered');\n}\n\nexport { UserService, createUserService } from './user.service.js';\nexport { UserController, createUserController } from './user.controller.js';\nexport { UserRepository, createUserRepository } from './user.repository.js';\nexport * from './types.js';\nexport * from './schemas.js';\n","/* eslint-disable no-console */\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport fs from 'fs/promises';\nimport { getProjectRoot, getModulesDir } from '../utils/helpers.js';\n\n// Pre-built modules that can be added\nconst AVAILABLE_MODULES: Record<string, { name: string; description: string; category: string }> = {\n // Core\n auth: {\n name: 'Authentication',\n description: 'JWT authentication with access/refresh tokens',\n category: 'Core',\n },\n users: {\n name: 'User Management',\n description: 'User CRUD with RBAC (roles & permissions)',\n category: 'Core',\n },\n email: {\n name: 'Email Service',\n description: 'SMTP email with templates (Handlebars)',\n category: 'Core',\n },\n\n // Security\n mfa: {\n name: 'MFA/TOTP',\n description: 'Two-factor authentication with QR codes',\n category: 'Security',\n },\n oauth: {\n name: 'OAuth',\n description: 'Social login (Google, GitHub, Facebook, Twitter, Apple)',\n category: 'Security',\n },\n 'rate-limit': {\n name: 'Rate Limiting',\n description: 'Advanced rate limiting with multiple algorithms',\n category: 'Security',\n },\n\n // Data & Storage\n cache: {\n name: 'Redis Cache',\n description: 'Redis caching with TTL & invalidation',\n category: 'Data & Storage',\n },\n upload: {\n name: 'File Upload',\n description: 'File upload with local/S3/Cloudinary storage',\n category: 'Data & Storage',\n },\n search: {\n name: 'Search',\n description: 'Full-text search with Elasticsearch/Meilisearch',\n category: 'Data & Storage',\n },\n\n // Communication\n notification: {\n name: 'Notifications',\n description: 'Email, SMS, Push notifications',\n category: 'Communication',\n },\n webhook: {\n name: 'Webhooks',\n description: 'Outgoing webhooks with HMAC signatures & retry',\n category: 'Communication',\n },\n websocket: {\n name: 'WebSockets',\n description: 'Real-time communication with Socket.io',\n category: 'Communication',\n },\n\n // Background Processing\n queue: {\n name: 'Queue/Jobs',\n description: 'Background jobs with Bull/BullMQ & cron scheduling',\n category: 'Background Processing',\n },\n 'media-processing': {\n name: 'Media Processing',\n description: 'Image/video processing with FFmpeg',\n category: 'Background Processing',\n },\n\n // Monitoring & Analytics\n audit: {\n name: 'Audit Logs',\n description: 'Activity logging and audit trail',\n category: 'Monitoring & Analytics',\n },\n analytics: {\n name: 'Analytics/Metrics',\n description: 'Prometheus metrics & event tracking',\n category: 'Monitoring & Analytics',\n },\n\n // Internationalization\n i18n: {\n name: 'i18n/Localization',\n description: 'Multi-language support with 7+ locales',\n category: 'Internationalization',\n },\n\n // API Management\n 'feature-flag': {\n name: 'Feature Flags',\n description: 'A/B testing & progressive rollout',\n category: 'API Management',\n },\n 'api-versioning': {\n name: 'API Versioning',\n description: 'Multiple API versions support',\n category: 'API Management',\n },\n\n // Payments\n payment: {\n name: 'Payments',\n description: 'Payment processing (Stripe, PayPal, Mobile Money)',\n category: 'Payments',\n },\n};\n\nasync function getInstalledModules(): Promise<string[]> {\n try {\n const modulesDir = getModulesDir();\n const entries = await fs.readdir(modulesDir, { withFileTypes: true });\n return entries.filter((e) => e.isDirectory()).map((e) => e.name);\n } catch {\n return [];\n }\n}\n\nfunction isServercraftProject(): boolean {\n try {\n getProjectRoot();\n return true;\n } catch {\n return false;\n }\n}\n\nexport const listCommand = new Command('list')\n .alias('ls')\n .description('List available and installed modules')\n .option('-a, --available', 'Show only available modules')\n .option('-i, --installed', 'Show only installed modules')\n .option('-c, --category <category>', 'Filter by category')\n .option('--json', 'Output as JSON')\n .action(\n async (options: {\n available?: boolean;\n installed?: boolean;\n category?: string;\n json?: boolean;\n }) => {\n const installedModules = await getInstalledModules();\n const isProject = isServercraftProject();\n\n if (options.json) {\n const output: Record<string, unknown> = {\n available: Object.entries(AVAILABLE_MODULES).map(([key, mod]) => ({\n id: key,\n ...mod,\n installed: installedModules.includes(key),\n })),\n };\n\n if (isProject) {\n output.installed = installedModules;\n }\n\n console.log(JSON.stringify(output, null, 2));\n return;\n }\n\n // Group modules by category\n const byCategory: Record<\n string,\n Array<{ id: string; name: string; description: string; installed: boolean }>\n > = {};\n\n for (const [key, mod] of Object.entries(AVAILABLE_MODULES)) {\n if (options.category && mod.category.toLowerCase() !== options.category.toLowerCase()) {\n continue;\n }\n\n if (!byCategory[mod.category]) {\n byCategory[mod.category] = [];\n }\n\n byCategory[mod.category]?.push({\n id: key,\n name: mod.name,\n description: mod.description,\n installed: installedModules.includes(key),\n });\n }\n\n // Show installed modules only\n if (options.installed) {\n if (!isProject) {\n console.log(chalk.yellow('\\n⚠ Not in a Servcraft project directory\\n'));\n return;\n }\n\n console.log(chalk.bold('\\n📦 Installed Modules:\\n'));\n\n if (installedModules.length === 0) {\n console.log(chalk.gray(' No modules installed yet.\\n'));\n console.log(` Run ${chalk.cyan('servcraft add <module>')} to add a module.\\n`);\n return;\n }\n\n for (const modId of installedModules) {\n const mod = AVAILABLE_MODULES[modId];\n if (mod) {\n console.log(` ${chalk.green('✓')} ${chalk.cyan(modId.padEnd(18))} ${mod.name}`);\n } else {\n console.log(\n ` ${chalk.green('✓')} ${chalk.cyan(modId.padEnd(18))} ${chalk.gray('(custom module)')}`\n );\n }\n }\n\n console.log(`\\n Total: ${chalk.bold(installedModules.length)} module(s) installed\\n`);\n return;\n }\n\n // Show available modules (default or --available)\n console.log(chalk.bold('\\n📦 Available Modules\\n'));\n\n if (isProject) {\n console.log(\n chalk.gray(` ${chalk.green('✓')} = installed ${chalk.dim('○')} = not installed\\n`)\n );\n }\n\n for (const [category, modules] of Object.entries(byCategory)) {\n console.log(chalk.bold.blue(` ${category}`));\n console.log(chalk.gray(' ' + '─'.repeat(40)));\n\n for (const mod of modules) {\n const status = isProject ? (mod.installed ? chalk.green('✓') : chalk.dim('○')) : ' ';\n const nameColor = mod.installed ? chalk.green : chalk.cyan;\n console.log(` ${status} ${nameColor(mod.id.padEnd(18))} ${mod.name}`);\n console.log(` ${chalk.gray(mod.description)}`);\n }\n console.log();\n }\n\n // Summary\n const totalAvailable = Object.keys(AVAILABLE_MODULES).length;\n const totalInstalled = installedModules.filter((m) => AVAILABLE_MODULES[m]).length;\n\n console.log(chalk.gray('─'.repeat(50)));\n console.log(\n ` ${chalk.bold(totalAvailable)} modules available` +\n (isProject ? ` | ${chalk.green.bold(totalInstalled)} installed` : '')\n );\n console.log();\n\n // Usage hints\n console.log(chalk.bold(' Usage:'));\n console.log(` ${chalk.yellow('servcraft add <module>')} Add a module`);\n console.log(` ${chalk.yellow('servcraft list --installed')} Show installed only`);\n console.log(` ${chalk.yellow('servcraft list --category Security')} Filter by category`);\n console.log();\n }\n );\n","/* eslint-disable no-console */\nimport { Command } from 'commander';\nimport path from 'path';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport fs from 'fs/promises';\nimport inquirer from 'inquirer';\nimport { getModulesDir, success, error, info } from '../utils/helpers.js';\nimport { ServCraftError, displayError, validateProject } from '../utils/error-handler.js';\n\nexport const removeCommand = new Command('remove')\n .alias('rm')\n .description('Remove an installed module from your project')\n .argument('<module>', 'Module to remove')\n .option('-y, --yes', 'Skip confirmation prompt')\n .option('--keep-env', 'Keep environment variables')\n .action(async (moduleName: string, options?: { yes?: boolean; keepEnv?: boolean }) => {\n // Validate project\n const projectError = validateProject();\n if (projectError) {\n displayError(projectError);\n return;\n }\n\n console.log(chalk.bold.cyan('\\n🗑️ ServCraft Module Removal\\n'));\n\n const moduleDir = path.join(getModulesDir(), moduleName);\n\n try {\n // Check if module exists\n const exists = await fs\n .access(moduleDir)\n .then(() => true)\n .catch(() => false);\n\n if (!exists) {\n displayError(\n new ServCraftError(`Module \"${moduleName}\" is not installed`, [\n `Run ${chalk.cyan('servcraft list --installed')} to see installed modules`,\n `Check the spelling of the module name`,\n ])\n );\n return;\n }\n\n // Get list of files\n const files = await fs.readdir(moduleDir);\n const fileCount = files.length;\n\n // Confirm removal\n if (!options?.yes) {\n console.log(chalk.yellow(`⚠ This will remove the \"${moduleName}\" module:`));\n console.log(chalk.gray(` Directory: ${moduleDir}`));\n console.log(chalk.gray(` Files: ${fileCount} file(s)`));\n console.log();\n\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: 'Are you sure you want to remove this module?',\n default: false,\n },\n ]);\n\n if (!confirm) {\n console.log(chalk.yellow('\\n✖ Removal cancelled\\n'));\n return;\n }\n }\n\n const spinner = ora('Removing module...').start();\n\n // Remove module directory\n await fs.rm(moduleDir, { recursive: true, force: true });\n\n spinner.succeed(`Module \"${moduleName}\" removed successfully!`);\n\n // Show what was removed\n console.log('\\n' + chalk.bold('✓ Removed:'));\n success(` src/modules/${moduleName}/ (${fileCount} files)`);\n\n // Instructions for cleanup\n if (!options?.keepEnv) {\n console.log('\\n' + chalk.bold('📌 Manual cleanup needed:'));\n info(' 1. Remove environment variables related to this module from .env');\n info(' 2. Remove module imports from your main app file');\n info(' 3. Remove related database migrations if any');\n info(' 4. Update your routes if they reference this module');\n } else {\n console.log('\\n' + chalk.bold('📌 Manual cleanup needed:'));\n info(' 1. Environment variables were kept (--keep-env flag)');\n info(' 2. Remove module imports from your main app file');\n info(' 3. Update your routes if they reference this module');\n }\n\n console.log();\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n console.log();\n }\n });\n","/* eslint-disable no-console */\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport fs from 'fs/promises';\n\ninterface Check {\n name: string;\n status: 'pass' | 'warn' | 'fail';\n message: string;\n suggestion?: string;\n}\n\nasync function checkNodeVersion(): Promise<Check> {\n const version = process.version;\n const major = parseInt(version.slice(1).split('.')[0] || '0', 10);\n\n if (major >= 18) {\n return { name: 'Node.js', status: 'pass', message: `${version} ✓` };\n }\n return {\n name: 'Node.js',\n status: 'fail',\n message: `${version} (< 18)`,\n suggestion: 'Upgrade to Node.js 18+',\n };\n}\n\nasync function checkPackageJson(): Promise<Check[]> {\n const checks: Check[] = [];\n try {\n const content = await fs.readFile('package.json', 'utf-8');\n const pkg = JSON.parse(content);\n\n checks.push({ name: 'package.json', status: 'pass', message: 'Found' });\n\n if (pkg.dependencies?.fastify) {\n checks.push({ name: 'Fastify', status: 'pass', message: 'Installed' });\n } else {\n checks.push({\n name: 'Fastify',\n status: 'fail',\n message: 'Missing',\n suggestion: 'npm install fastify',\n });\n }\n } catch {\n checks.push({\n name: 'package.json',\n status: 'fail',\n message: 'Not found',\n suggestion: 'Run servcraft init',\n });\n }\n return checks;\n}\n\nasync function checkDirectories(): Promise<Check[]> {\n const checks: Check[] = [];\n const dirs = ['src', 'node_modules', '.git', '.env'];\n\n for (const dir of dirs) {\n try {\n await fs.access(dir);\n checks.push({ name: dir, status: 'pass', message: 'Exists' });\n } catch {\n const isCritical = dir === 'src' || dir === 'node_modules';\n checks.push({\n name: dir,\n status: isCritical ? 'fail' : 'warn',\n message: 'Not found',\n suggestion:\n dir === 'node_modules' ? 'npm install' : dir === '.env' ? 'Create .env file' : undefined,\n });\n }\n }\n return checks;\n}\n\nexport const doctorCommand = new Command('doctor')\n .description('Diagnose project configuration and dependencies')\n .action(async () => {\n console.log(chalk.bold.cyan('\\n🔍 ServCraft Doctor\\n'));\n\n const allChecks: Check[] = [];\n\n allChecks.push(await checkNodeVersion());\n allChecks.push(...(await checkPackageJson()));\n allChecks.push(...(await checkDirectories()));\n\n // Display results\n allChecks.forEach((check) => {\n const icon =\n check.status === 'pass'\n ? chalk.green('✓')\n : check.status === 'warn'\n ? chalk.yellow('⚠')\n : chalk.red('✗');\n const color =\n check.status === 'pass' ? chalk.green : check.status === 'warn' ? chalk.yellow : chalk.red;\n\n console.log(`${icon} ${check.name.padEnd(20)} ${color(check.message)}`);\n if (check.suggestion) {\n console.log(chalk.gray(` → ${check.suggestion}`));\n }\n });\n\n const pass = allChecks.filter((c) => c.status === 'pass').length;\n const warn = allChecks.filter((c) => c.status === 'warn').length;\n const fail = allChecks.filter((c) => c.status === 'fail').length;\n\n console.log(chalk.gray('\\n' + '─'.repeat(60)));\n console.log(\n `\\n${chalk.green(pass + ' passed')} | ${chalk.yellow(warn + ' warnings')} | ${chalk.red(fail + ' failed')}\\n`\n );\n\n if (fail === 0 && warn === 0) {\n console.log(chalk.green.bold('✨ Everything looks good!\\n'));\n } else if (fail > 0) {\n console.log(chalk.red.bold('✗ Fix critical issues before using ServCraft.\\n'));\n } else {\n console.log(chalk.yellow.bold('⚠ Some warnings, but should work.\\n'));\n }\n });\n","/* eslint-disable no-console */\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport inquirer from 'inquirer';\nimport { getProjectRoot, getModulesDir } from '../utils/helpers.js';\nimport { validateProject, displayError } from '../utils/error-handler.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// Get list of available modules (same as list.ts)\nconst AVAILABLE_MODULES = [\n 'auth',\n 'users',\n 'email',\n 'mfa',\n 'oauth',\n 'rate-limit',\n 'cache',\n 'upload',\n 'search',\n 'notification',\n 'webhook',\n 'websocket',\n 'queue',\n 'payment',\n 'i18n',\n 'feature-flag',\n 'analytics',\n 'media-processing',\n 'api-versioning',\n 'audit',\n 'swagger',\n 'validation',\n];\n\nasync function getInstalledModules(): Promise<string[]> {\n try {\n const modulesDir = getModulesDir();\n\n const entries = await fs.readdir(modulesDir, { withFileTypes: true });\n const installedModules = entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name)\n .filter((name) => AVAILABLE_MODULES.includes(name));\n\n return installedModules;\n } catch {\n return [];\n }\n}\n\nasync function copyModuleFiles(moduleName: string, _projectRoot: string): Promise<void> {\n const cliRoot = path.resolve(__dirname, '../../../');\n const sourceModulePath = path.join(cliRoot, 'src', 'modules', moduleName);\n const targetModulesDir = getModulesDir();\n const targetModulePath = path.join(targetModulesDir, moduleName);\n\n // Check if source module exists\n try {\n await fs.access(sourceModulePath);\n } catch {\n throw new Error(`Module source not found: ${moduleName}`);\n }\n\n // Copy module files\n await fs.cp(sourceModulePath, targetModulePath, { recursive: true });\n}\n\nasync function updateModule(moduleName: string, options: { check?: boolean }): Promise<void> {\n const projectError = validateProject();\n if (projectError) {\n displayError(projectError);\n return;\n }\n\n const projectRoot = getProjectRoot();\n const installedModules = await getInstalledModules();\n\n if (!installedModules.includes(moduleName)) {\n console.log(chalk.yellow(`\\n⚠ Module \"${moduleName}\" is not installed\\n`));\n console.log(\n chalk.gray(`Run ${chalk.cyan(`servcraft add ${moduleName}`)} to install it first.\\n`)\n );\n return;\n }\n\n if (options.check) {\n console.log(chalk.cyan(`\\n📦 Checking updates for \"${moduleName}\"...\\n`));\n console.log(chalk.gray('Note: Version tracking will be implemented in a future release.'));\n console.log(chalk.gray('Currently, update will always reinstall the latest version.\\n'));\n return;\n }\n\n // Confirm update\n const { confirmed } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirmed',\n message: `Update \"${moduleName}\" module? This will overwrite existing files.`,\n default: false,\n },\n ]);\n\n if (!confirmed) {\n console.log(chalk.yellow('\\n⚠ Update cancelled\\n'));\n return;\n }\n\n console.log(chalk.cyan(`\\n🔄 Updating \"${moduleName}\" module...\\n`));\n\n try {\n await copyModuleFiles(moduleName, projectRoot);\n console.log(chalk.green(`✔ Module \"${moduleName}\" updated successfully!\\n`));\n console.log(\n chalk.gray('Note: Remember to review any breaking changes in the documentation.\\n')\n );\n } catch (error) {\n if (error instanceof Error) {\n console.error(chalk.red(`\\n✗ Failed to update module: ${error.message}\\n`));\n }\n }\n}\n\nasync function updateAllModules(options: { check?: boolean }): Promise<void> {\n const projectError = validateProject();\n if (projectError) {\n displayError(projectError);\n return;\n }\n\n const installedModules = await getInstalledModules();\n\n if (installedModules.length === 0) {\n console.log(chalk.yellow('\\n⚠ No modules installed\\n'));\n console.log(chalk.gray(`Run ${chalk.cyan('servcraft list')} to see available modules.\\n`));\n return;\n }\n\n if (options.check) {\n console.log(chalk.cyan('\\n📦 Checking updates for all modules...\\n'));\n console.log(chalk.bold('Installed modules:'));\n installedModules.forEach((mod) => {\n console.log(` • ${chalk.cyan(mod)}`);\n });\n console.log();\n console.log(chalk.gray('Note: Version tracking will be implemented in a future release.'));\n console.log(chalk.gray('Currently, update will always reinstall the latest version.\\n'));\n return;\n }\n\n console.log(chalk.cyan(`\\n📦 Found ${installedModules.length} installed module(s):\\n`));\n installedModules.forEach((mod) => {\n console.log(` • ${chalk.cyan(mod)}`);\n });\n console.log();\n\n // Confirm update all\n const { confirmed } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirmed',\n message: 'Update all modules? This will overwrite existing files.',\n default: false,\n },\n ]);\n\n if (!confirmed) {\n console.log(chalk.yellow('\\n⚠ Update cancelled\\n'));\n return;\n }\n\n console.log(chalk.cyan('\\n🔄 Updating all modules...\\n'));\n\n const projectRoot = getProjectRoot();\n let successCount = 0;\n let failCount = 0;\n\n for (const moduleName of installedModules) {\n try {\n await copyModuleFiles(moduleName, projectRoot);\n console.log(chalk.green(`✔ Updated: ${moduleName}`));\n successCount++;\n } catch {\n console.error(chalk.red(`✗ Failed: ${moduleName}`));\n failCount++;\n }\n }\n\n console.log();\n console.log(\n chalk.bold(\n `\\n✔ Update complete: ${chalk.green(successCount)} succeeded, ${chalk.red(failCount)} failed\\n`\n )\n );\n\n if (successCount > 0) {\n console.log(\n chalk.gray('Note: Remember to review any breaking changes in the documentation.\\n')\n );\n }\n}\n\nexport const updateCommand = new Command('update')\n .description('Update installed modules to latest version')\n .argument('[module]', 'Specific module to update')\n .option('--check', 'Check for updates without applying')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (moduleName?: string, options?: { check?: boolean; yes?: boolean }) => {\n // If --yes flag is provided, we'll handle it by auto-confirming in the inquirer prompts\n // For now, we'll just pass through to the update functions\n\n if (moduleName) {\n await updateModule(moduleName, { check: options?.check });\n } else {\n await updateAllModules({ check: options?.check });\n }\n });\n","/* eslint-disable no-console */\n/* eslint-disable no-useless-escape */\nimport { Command } from 'commander';\n\nconst bashScript = `\n# servcraft bash completion script\n_servcraft_completions() {\n local cur prev words cword\n _init_completion || return\n\n # Main commands\n local commands=\"init add generate list remove doctor update completion docs --version --help\"\n\n # Generate subcommands\n local generate_subcommands=\"module controller service repository types schema routes m c s r t\"\n\n case \"\\${words[1]}\" in\n generate|g)\n if [[ \\${cword} -eq 2 ]]; then\n COMPREPLY=( \\$(compgen -W \"\\${generate_subcommands}\" -- \"\\${cur}\") )\n fi\n ;;\n add|remove|rm|update)\n if [[ \\${cword} -eq 2 ]]; then\n # Get available modules\n local modules=\"auth cache rate-limit notification payment oauth mfa queue websocket upload\"\n COMPREPLY=( \\$(compgen -W \"\\${modules}\" -- \"\\${cur}\") )\n fi\n ;;\n completion)\n if [[ \\${cword} -eq 2 ]]; then\n COMPREPLY=( \\$(compgen -W \"bash zsh\" -- \"\\${cur}\") )\n fi\n ;;\n *)\n if [[ \\${cword} -eq 1 ]]; then\n COMPREPLY=( \\$(compgen -W \"\\${commands}\" -- \"\\${cur}\") )\n fi\n ;;\n esac\n}\n\ncomplete -F _servcraft_completions servcraft\n`;\n\nconst zshScript = `\n#compdef servcraft\n\n_servcraft() {\n local context state state_descr line\n typeset -A opt_args\n\n _arguments -C \\\\\n '1: :_servcraft_commands' \\\\\n '*::arg:->args'\n\n case $state in\n args)\n case $line[1] in\n generate|g)\n _servcraft_generate\n ;;\n add|remove|rm|update)\n _servcraft_modules\n ;;\n completion)\n _arguments '1: :(bash zsh)'\n ;;\n esac\n ;;\n esac\n}\n\n_servcraft_commands() {\n local commands\n commands=(\n 'init:Initialize a new ServCraft project'\n 'add:Add a pre-built module to your project'\n 'generate:Generate code files (controller, service, etc.)'\n 'list:List available and installed modules'\n 'remove:Remove an installed module'\n 'doctor:Diagnose project configuration'\n 'update:Update installed modules'\n 'completion:Generate shell completion scripts'\n 'docs:Open documentation'\n '--version:Show version'\n '--help:Show help'\n )\n _describe 'command' commands\n}\n\n_servcraft_generate() {\n local subcommands\n subcommands=(\n 'module:Generate a complete module (controller + service + routes)'\n 'controller:Generate a controller'\n 'service:Generate a service'\n 'repository:Generate a repository'\n 'types:Generate TypeScript types'\n 'schema:Generate validation schema'\n 'routes:Generate routes file'\n 'm:Alias for module'\n 'c:Alias for controller'\n 's:Alias for service'\n 'r:Alias for repository'\n 't:Alias for types'\n )\n _describe 'subcommand' subcommands\n}\n\n_servcraft_modules() {\n local modules\n modules=(\n 'auth:Authentication & Authorization'\n 'cache:Redis caching'\n 'rate-limit:Rate limiting'\n 'notification:Email/SMS notifications'\n 'payment:Payment integration'\n 'oauth:OAuth providers'\n 'mfa:Multi-factor authentication'\n 'queue:Background jobs'\n 'websocket:WebSocket support'\n 'upload:File upload handling'\n )\n _describe 'module' modules\n}\n\n_servcraft \"$@\"\n`;\n\nexport const completionCommand = new Command('completion')\n .description('Generate shell completion scripts')\n .argument('<shell>', 'Shell type (bash or zsh)')\n .action((shell: string) => {\n const shellLower = shell.toLowerCase();\n\n if (shellLower === 'bash') {\n console.log(bashScript);\n } else if (shellLower === 'zsh') {\n console.log(zshScript);\n } else {\n console.error(`Unsupported shell: ${shell}`);\n console.error('Supported shells: bash, zsh');\n process.exit(1);\n }\n });\n"],"mappings":"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","names":["import_commander","import_path","import_promises","import_chalk","import_path","import_chalk","chalk","path","fs","path","chalk","path","chalk","inquirer","path","ora","fs","env","import_commander","import_path","import_ora","import_inquirer","import_chalk","import_chalk","chalk","error","fs","chalk","chalk","ora","path","inquirer","import_commander","import_path","import_ora","import_chalk","fs","fs","path","created","fs","path","import_fs","import_inquirer","import_chalk","chalk","inquirer","chalk","module","ora","path","stat","import_commander","import_child_process","import_ora","import_chalk","ora","chalk","import_commander","import_path","import_promises","import_ora","import_chalk","import_promises","import_path","import_ora","config","pino","defaultConfig","config","Fastify","error","error","dotenv","error","helmet","cors","rateLimit","defaultConfig","swagger","swaggerUi","error","bcrypt","import_zod","success","import_zod","error","path","success","import_client","jwt","cookie","import_zod","success","ora","path","fs","error","fs","ora","path","chalk","stat","import_commander","import_chalk","import_promises","AVAILABLE_MODULES","fs","chalk","import_commander","import_path","import_ora","import_chalk","import_promises","import_inquirer","chalk","path","fs","inquirer","ora","import_commander","import_chalk","import_promises","fs","chalk","warn","import_commander","import_chalk","import_promises","import_path","import_inquirer","__filename","path","AVAILABLE_MODULES","getInstalledModules","fs","chalk","inquirer","error","import_commander"]}
|
|
1
|
+
{"version":3,"sources":["../../node_modules/tsup/assets/cjs_shims.js","../../src/cli/index.ts","../../src/cli/commands/init.ts","../../src/cli/utils/helpers.ts","../../src/cli/utils/dry-run.ts","../../src/cli/commands/generate.ts","../../src/cli/utils/field-parser.ts","../../src/cli/utils/error-handler.ts","../../src/cli/templates/controller.ts","../../src/cli/templates/service.ts","../../src/cli/templates/repository.ts","../../src/cli/templates/types.ts","../../src/cli/templates/schemas.ts","../../src/cli/templates/routes.ts","../../src/cli/templates/module-index.ts","../../src/cli/templates/prisma-model.ts","../../src/cli/templates/dynamic-types.ts","../../src/cli/templates/dynamic-schemas.ts","../../src/cli/templates/dynamic-prisma.ts","../../src/cli/templates/controller-test.ts","../../src/cli/templates/service-test.ts","../../src/cli/templates/integration-test.ts","../../src/cli/utils/template-loader.ts","../../src/cli/commands/add-module.ts","../../src/cli/utils/env-manager.ts","../../src/cli/utils/template-manager.ts","../../src/cli/utils/interactive-prompt.ts","../../src/cli/commands/db.ts","../../src/cli/commands/docs.ts","../../src/cli/utils/docs-generator.ts","../../src/core/server.ts","../../src/core/logger.ts","../../src/utils/errors.ts","../../src/config/env.ts","../../src/config/index.ts","../../src/middleware/error-handler.ts","../../src/middleware/security.ts","../../src/modules/swagger/swagger.service.ts","../../src/modules/auth/index.ts","../../src/modules/auth/auth.service.ts","../../src/modules/auth/schemas.ts","../../src/utils/response.ts","../../src/modules/validation/validator.ts","../../src/modules/auth/auth.controller.ts","../../src/modules/auth/auth.middleware.ts","../../src/modules/auth/auth.routes.ts","../../src/database/prisma.ts","../../src/utils/pagination.ts","../../src/modules/user/user.repository.ts","../../src/modules/user/types.ts","../../src/modules/user/user.service.ts","../../src/modules/user/schemas.ts","../../src/modules/user/user.controller.ts","../../src/modules/user/user.routes.ts","../../src/modules/user/index.ts","../../src/cli/commands/list.ts","../../src/cli/commands/remove.ts","../../src/cli/commands/doctor.ts","../../src/cli/commands/update.ts","../../src/cli/commands/completion.ts","../../src/cli/commands/scaffold.ts","../../src/cli/commands/templates.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { initCommand } from './commands/init.js';\nimport { generateCommand } from './commands/generate.js';\nimport { addModuleCommand } from './commands/add-module.js';\nimport { dbCommand } from './commands/db.js';\nimport { docsCommand } from './commands/docs.js';\nimport { listCommand } from './commands/list.js';\nimport { removeCommand } from './commands/remove.js';\nimport { doctorCommand } from './commands/doctor.js';\nimport { updateCommand } from './commands/update.js';\nimport { completionCommand } from './commands/completion.js';\nimport { scaffoldCommand } from './commands/scaffold.js';\nimport { templatesCommand } from './commands/templates.js';\n\nconst program = new Command();\n\nprogram\n .name('servcraft')\n .description('Servcraft - A modular Node.js backend framework CLI')\n .version('0.1.0');\n\n// Initialize new project\nprogram.addCommand(initCommand);\n\n// Generate resources (controller, service, model, etc.)\nprogram.addCommand(generateCommand);\n\n// Add pre-built modules\nprogram.addCommand(addModuleCommand);\n\n// Database commands\nprogram.addCommand(dbCommand);\n\n// Documentation commands\nprogram.addCommand(docsCommand);\n\n// List modules\nprogram.addCommand(listCommand);\n\n// Remove module\nprogram.addCommand(removeCommand);\n\n// Diagnose project\nprogram.addCommand(doctorCommand);\n\n// Update modules\nprogram.addCommand(updateCommand);\n\n// Shell completion\nprogram.addCommand(completionCommand);\n\n// Scaffold resource\nprogram.addCommand(scaffoldCommand);\n\n// Template management\nprogram.addCommand(templatesCommand);\n\nprogram.parse();\n","import { Command } from 'commander';\nimport path from 'path';\nimport fs from 'fs/promises';\nimport ora from 'ora';\nimport inquirer from 'inquirer';\nimport chalk from 'chalk';\nimport { execSync } from 'child_process';\nimport { ensureDir, writeFile, error, warn } from '../utils/helpers.js';\nimport { DryRunManager } from '../utils/dry-run.js';\n\ninterface InitOptions {\n name: string;\n language: 'typescript' | 'javascript';\n moduleSystem: 'esm' | 'commonjs';\n database: 'postgresql' | 'mysql' | 'sqlite' | 'mongodb' | 'none';\n orm: 'prisma' | 'mongoose' | 'none';\n validator: 'zod' | 'joi' | 'yup';\n features: string[];\n}\n\nexport const initCommand = new Command('init')\n .alias('new')\n .description('Initialize a new Servcraft project')\n .argument('[name]', 'Project name')\n .option('-y, --yes', 'Skip prompts and use defaults')\n .option('--ts, --typescript', 'Use TypeScript (default)')\n .option('--js, --javascript', 'Use JavaScript')\n .option('--esm', 'Use ES Modules (import/export) - default')\n .option('--cjs, --commonjs', 'Use CommonJS (require/module.exports)')\n .option('--db <database>', 'Database type (postgresql, mysql, sqlite, mongodb, none)')\n .option('--dry-run', 'Preview changes without writing files')\n .action(\n async (\n name?: string,\n cmdOptions?: {\n yes?: boolean;\n typescript?: boolean;\n javascript?: boolean;\n esm?: boolean;\n commonjs?: boolean;\n db?: string;\n dryRun?: boolean;\n }\n ) => {\n // Enable dry-run mode if specified\n const dryRun = DryRunManager.getInstance();\n if (cmdOptions?.dryRun) {\n dryRun.enable();\n console.log(chalk.yellow('\\n⚠ DRY RUN MODE - No files will be written\\n'));\n }\n\n console.log(\n chalk.blue(`\n╔═══════════════════════════════════════════╗\n║ ║\n║ ${chalk.bold('🚀 Servcraft Project Generator')} ║\n║ ║\n╚═══════════════════════════════════════════╝\n`)\n );\n\n let options: InitOptions;\n\n if (cmdOptions?.yes) {\n const db = (cmdOptions.db as InitOptions['database']) || 'postgresql';\n options = {\n name: name || 'my-servcraft-app',\n language: cmdOptions.javascript ? 'javascript' : 'typescript',\n moduleSystem: cmdOptions.commonjs ? 'commonjs' : 'esm',\n database: db,\n orm: db === 'mongodb' ? 'mongoose' : db === 'none' ? 'none' : 'prisma',\n validator: 'zod',\n features: ['auth', 'users', 'email'],\n };\n } else {\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'name',\n message: 'Project name:',\n default: name || 'my-servcraft-app',\n validate: (input: string) => {\n if (!/^[a-z0-9-_]+$/i.test(input)) {\n return 'Project name can only contain letters, numbers, hyphens, and underscores';\n }\n return true;\n },\n },\n {\n type: 'list',\n name: 'language',\n message: 'Select language:',\n choices: [\n { name: 'TypeScript (Recommended)', value: 'typescript' },\n { name: 'JavaScript', value: 'javascript' },\n ],\n default: 'typescript',\n },\n {\n type: 'list',\n name: 'moduleSystem',\n message: 'Select module system:',\n choices: [\n { name: 'ESM (import/export) - Recommended', value: 'esm' },\n { name: 'CommonJS (require/module.exports)', value: 'commonjs' },\n ],\n default: 'esm',\n },\n {\n type: 'list',\n name: 'database',\n message: 'Select database:',\n choices: [\n { name: 'PostgreSQL (Recommended for SQL)', value: 'postgresql' },\n { name: 'MySQL', value: 'mysql' },\n { name: 'SQLite (Development)', value: 'sqlite' },\n { name: 'MongoDB (NoSQL)', value: 'mongodb' },\n { name: 'None (Add later)', value: 'none' },\n ],\n default: 'postgresql',\n },\n {\n type: 'list',\n name: 'validator',\n message: 'Select validation library:',\n choices: [\n { name: 'Zod (Recommended - TypeScript-first)', value: 'zod' },\n { name: 'Joi (Battle-tested, feature-rich)', value: 'joi' },\n { name: 'Yup (Inspired by Joi, lighter)', value: 'yup' },\n ],\n default: 'zod',\n },\n {\n type: 'checkbox',\n name: 'features',\n message: 'Select features to include:',\n choices: [\n { name: 'Authentication (JWT)', value: 'auth', checked: true },\n { name: 'User Management', value: 'users', checked: true },\n { name: 'Email Service', value: 'email', checked: true },\n { name: 'Audit Logs', value: 'audit', checked: false },\n { name: 'File Upload', value: 'upload', checked: false },\n { name: 'Redis Cache', value: 'redis', checked: false },\n ],\n },\n ]);\n\n // Auto-determine ORM based on database choice\n const db = answers.database as InitOptions['database'];\n options = {\n ...answers,\n orm: db === 'mongodb' ? 'mongoose' : db === 'none' ? 'none' : 'prisma',\n } as InitOptions;\n }\n\n const projectDir = path.resolve(process.cwd(), options.name);\n const spinner = ora('Creating project...').start();\n\n try {\n // Check if directory exists\n try {\n await fs.access(projectDir);\n spinner.stop();\n error(`Directory \"${options.name}\" already exists`);\n return;\n } catch {\n // Directory doesn't exist, continue\n }\n\n // Create project directory\n await ensureDir(projectDir);\n\n spinner.text = 'Generating project files...';\n\n // Generate package.json\n const packageJson = generatePackageJson(options);\n await writeFile(\n path.join(projectDir, 'package.json'),\n JSON.stringify(packageJson, null, 2)\n );\n\n // Generate tsconfig or jsconfig\n if (options.language === 'typescript') {\n await writeFile(path.join(projectDir, 'tsconfig.json'), generateTsConfig(options));\n await writeFile(path.join(projectDir, 'tsup.config.ts'), generateTsupConfig(options));\n } else {\n await writeFile(path.join(projectDir, 'jsconfig.json'), generateJsConfig(options));\n }\n\n // Generate .env files\n await writeFile(path.join(projectDir, '.env.example'), generateEnvExample(options));\n await writeFile(path.join(projectDir, '.env'), generateEnvExample(options));\n\n // Generate .gitignore\n await writeFile(path.join(projectDir, '.gitignore'), generateGitignore());\n\n // Generate Docker files\n await writeFile(path.join(projectDir, 'Dockerfile'), generateDockerfile(options));\n await writeFile(\n path.join(projectDir, 'docker-compose.yml'),\n generateDockerCompose(options)\n );\n\n // Create directory structure\n // For JS: .js for ESM, .cjs for CommonJS\n // For TS: always .ts (output format handled by tsup)\n const ext =\n options.language === 'typescript' ? 'ts' : options.moduleSystem === 'esm' ? 'js' : 'cjs';\n const dirs = [\n 'src/core',\n 'src/config',\n 'src/modules',\n 'src/middleware',\n 'src/utils',\n 'src/types',\n 'tests/unit',\n 'tests/integration',\n ];\n\n if (options.orm === 'prisma') {\n dirs.push('prisma');\n }\n if (options.orm === 'mongoose') {\n dirs.push('src/database/models');\n }\n\n for (const dir of dirs) {\n await ensureDir(path.join(projectDir, dir));\n }\n\n // Generate main entry file\n await writeFile(path.join(projectDir, `src/index.${ext}`), generateEntryFile(options));\n\n // Generate core files\n await writeFile(\n path.join(projectDir, `src/core/server.${ext}`),\n generateServerFile(options)\n );\n await writeFile(\n path.join(projectDir, `src/core/logger.${ext}`),\n generateLoggerFile(options)\n );\n\n // Generate config file\n await writeFile(\n path.join(projectDir, `src/config/index.${ext}`),\n generateConfigFile(options)\n );\n\n // Generate middleware file\n await writeFile(\n path.join(projectDir, `src/middleware/index.${ext}`),\n generateMiddlewareFile(options)\n );\n\n // Generate utils file\n await writeFile(\n path.join(projectDir, `src/utils/index.${ext}`),\n generateUtilsFile(options)\n );\n\n // Generate types file\n await writeFile(\n path.join(projectDir, `src/types/index.${ext}`),\n generateTypesFile(options)\n );\n\n // Generate database files based on ORM choice\n if (options.orm === 'prisma') {\n await writeFile(\n path.join(projectDir, 'prisma/schema.prisma'),\n generatePrismaSchema(options)\n );\n } else if (options.orm === 'mongoose') {\n await writeFile(\n path.join(projectDir, `src/database/connection.${ext}`),\n generateMongooseConnection(options)\n );\n await writeFile(\n path.join(projectDir, `src/database/models/user.model.${ext}`),\n generateMongooseUserModel(options)\n );\n }\n\n spinner.succeed('Project files generated!');\n\n // Install dependencies (skip in dry-run mode)\n if (!cmdOptions?.dryRun) {\n const installSpinner = ora('Installing dependencies...').start();\n\n try {\n execSync('npm install', { cwd: projectDir, stdio: 'pipe' });\n installSpinner.succeed('Dependencies installed!');\n } catch {\n installSpinner.warn('Failed to install dependencies automatically');\n warn(' Run \"npm install\" manually in the project directory');\n }\n }\n\n // Print success message\n if (!cmdOptions?.dryRun) {\n console.log('\\n' + chalk.green('✨ Project created successfully!'));\n }\n console.log('\\n' + chalk.bold('📁 Project structure:'));\n console.log(`\n ${options.name}/\n ├── src/\n │ ├── core/ # Core server, logger\n │ ├── config/ # Configuration\n │ ├── modules/ # Feature modules\n │ ├── middleware/ # Middlewares\n │ ├── utils/ # Utilities\n │ └── index.${ext} # Entry point\n ├── tests/ # Tests\n ├── prisma/ # Database schema\n ├── docker-compose.yml\n └── package.json\n`);\n\n console.log(chalk.bold('🚀 Get started:'));\n console.log(`\n ${chalk.cyan(`cd ${options.name}`)}\n ${options.database !== 'none' ? chalk.cyan('npm run db:push # Setup database') : ''}\n ${chalk.cyan('npm run dev # Start development server')}\n`);\n\n console.log(chalk.bold('📚 Available commands:'));\n console.log(`\n ${chalk.yellow('servcraft generate module <name>')} Generate a new module\n ${chalk.yellow('servcraft generate controller <name>')} Generate a controller\n ${chalk.yellow('servcraft generate service <name>')} Generate a service\n ${chalk.yellow('servcraft add auth')} Add authentication module\n`);\n\n // Show dry-run summary if enabled\n if (cmdOptions?.dryRun) {\n dryRun.printSummary();\n }\n } catch (err) {\n spinner.fail('Failed to create project');\n error(err instanceof Error ? err.message : String(err));\n }\n }\n );\n\nfunction generatePackageJson(options: InitOptions): Record<string, unknown> {\n const isTS = options.language === 'typescript';\n const isESM = options.moduleSystem === 'esm';\n\n // Determine dev command based on language and module system\n let devCommand: string;\n if (isTS) {\n devCommand = 'tsx watch src/index.ts';\n } else if (isESM) {\n devCommand = 'node --watch src/index.js';\n } else {\n devCommand = 'node --watch src/index.cjs';\n }\n\n // Determine start command\n let startCommand: string;\n if (isTS) {\n startCommand = isESM ? 'node dist/index.js' : 'node dist/index.cjs';\n } else if (isESM) {\n startCommand = 'node src/index.js';\n } else {\n startCommand = 'node src/index.cjs';\n }\n\n const pkg: Record<string, unknown> = {\n name: options.name,\n version: '0.1.0',\n description: 'A Servcraft application',\n main: isTS\n ? isESM\n ? 'dist/index.js'\n : 'dist/index.cjs'\n : isESM\n ? 'src/index.js'\n : 'src/index.cjs',\n ...(isESM && { type: 'module' }),\n scripts: {\n dev: devCommand,\n build: isTS ? 'tsup' : 'echo \"No build needed for JS\"',\n start: startCommand,\n test: 'vitest',\n lint: isTS ? 'eslint src --ext .ts' : 'eslint src --ext .js,.cjs',\n },\n dependencies: {\n fastify: '^4.28.1',\n '@fastify/cors': '^9.0.1',\n '@fastify/helmet': '^11.1.1',\n '@fastify/jwt': '^8.0.1',\n '@fastify/rate-limit': '^9.1.0',\n '@fastify/cookie': '^9.3.1',\n pino: '^9.5.0',\n 'pino-pretty': '^11.3.0',\n bcryptjs: '^2.4.3',\n dotenv: '^16.4.5',\n },\n devDependencies: {\n vitest: '^2.1.8',\n },\n };\n\n // Add validator library based on choice\n switch (options.validator) {\n case 'zod':\n (pkg.dependencies as Record<string, string>).zod = '^3.23.8';\n break;\n case 'joi':\n (pkg.dependencies as Record<string, string>).joi = '^17.13.3';\n break;\n case 'yup':\n (pkg.dependencies as Record<string, string>).yup = '^1.4.0';\n break;\n }\n\n if (isTS) {\n (pkg.devDependencies as Record<string, string>).typescript = '^5.7.2';\n (pkg.devDependencies as Record<string, string>).tsx = '^4.19.2';\n (pkg.devDependencies as Record<string, string>).tsup = '^8.3.5';\n (pkg.devDependencies as Record<string, string>)['@types/node'] = '^22.10.1';\n (pkg.devDependencies as Record<string, string>)['@types/bcryptjs'] = '^2.4.6';\n }\n\n if (options.orm === 'prisma') {\n (pkg.dependencies as Record<string, string>)['@prisma/client'] = '^5.22.0';\n (pkg.devDependencies as Record<string, string>).prisma = '^5.22.0';\n (pkg.scripts as Record<string, string>)['db:generate'] = 'prisma generate';\n (pkg.scripts as Record<string, string>)['db:migrate'] = 'prisma migrate dev';\n (pkg.scripts as Record<string, string>)['db:push'] = 'prisma db push';\n (pkg.scripts as Record<string, string>)['db:studio'] = 'prisma studio';\n }\n\n if (options.orm === 'mongoose') {\n (pkg.dependencies as Record<string, string>).mongoose = '^8.8.4';\n if (isTS) {\n (pkg.devDependencies as Record<string, string>)['@types/mongoose'] = '^5.11.97';\n }\n }\n\n if (options.features.includes('email')) {\n (pkg.dependencies as Record<string, string>).nodemailer = '^6.9.15';\n (pkg.dependencies as Record<string, string>).handlebars = '^4.7.8';\n if (isTS) {\n (pkg.devDependencies as Record<string, string>)['@types/nodemailer'] = '^6.4.17';\n }\n }\n\n if (options.features.includes('redis')) {\n (pkg.dependencies as Record<string, string>).ioredis = '^5.4.1';\n }\n\n return pkg;\n}\n\nfunction generateTsConfig(options: InitOptions): string {\n const isESM = options.moduleSystem === 'esm';\n\n return JSON.stringify(\n {\n compilerOptions: {\n target: 'ES2022',\n module: isESM ? 'NodeNext' : 'CommonJS',\n moduleResolution: isESM ? 'NodeNext' : 'Node',\n lib: ['ES2022'],\n outDir: './dist',\n rootDir: './src',\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n forceConsistentCasingInFileNames: true,\n resolveJsonModule: true,\n declaration: true,\n sourceMap: true,\n },\n include: ['src/**/*'],\n exclude: ['node_modules', 'dist'],\n },\n null,\n 2\n );\n}\n\nfunction generateJsConfig(options: InitOptions): string {\n const isESM = options.moduleSystem === 'esm';\n\n return JSON.stringify(\n {\n compilerOptions: {\n module: isESM ? 'NodeNext' : 'CommonJS',\n moduleResolution: isESM ? 'NodeNext' : 'Node',\n target: 'ES2022',\n checkJs: true,\n },\n include: ['src/**/*'],\n exclude: ['node_modules'],\n },\n null,\n 2\n );\n}\n\nfunction generateTsupConfig(options: InitOptions): string {\n const isESM = options.moduleSystem === 'esm';\n\n return `import { defineConfig } from 'tsup';\n\nexport default defineConfig({\n entry: ['src/index.ts'],\n format: ['${isESM ? 'esm' : 'cjs'}'],\n dts: true,\n clean: true,\n sourcemap: true,\n target: 'node18',\n});\n`;\n}\n\nfunction generateEnvExample(options: InitOptions): string {\n let env = `# Server\nNODE_ENV=development\nPORT=3000\nHOST=0.0.0.0\n\n# JWT\nJWT_SECRET=your-super-secret-key-min-32-characters\nJWT_ACCESS_EXPIRES_IN=15m\nJWT_REFRESH_EXPIRES_IN=7d\n\n# Security\nCORS_ORIGIN=http://localhost:3000\nRATE_LIMIT_MAX=100\n\n# Logging\nLOG_LEVEL=info\n`;\n\n if (options.database === 'postgresql') {\n env += `\n# Database (PostgreSQL)\nDATABASE_PROVIDER=postgresql\nDATABASE_URL=\"postgresql://user:password@localhost:5432/mydb?schema=public\"\n`;\n } else if (options.database === 'mysql') {\n env += `\n# Database (MySQL)\nDATABASE_PROVIDER=mysql\nDATABASE_URL=\"mysql://user:password@localhost:3306/mydb\"\n`;\n } else if (options.database === 'sqlite') {\n env += `\n# Database (SQLite)\nDATABASE_PROVIDER=sqlite\nDATABASE_URL=\"file:./dev.db\"\n`;\n } else if (options.database === 'mongodb') {\n env += `\n# Database (MongoDB)\nMONGODB_URI=\"mongodb://localhost:27017/mydb\"\n`;\n }\n\n if (options.features.includes('email')) {\n env += `\n# Email\nSMTP_HOST=smtp.example.com\nSMTP_PORT=587\nSMTP_USER=\nSMTP_PASS=\nSMTP_FROM=\"App <noreply@example.com>\"\n`;\n }\n\n if (options.features.includes('redis')) {\n env += `\n# Redis\nREDIS_URL=redis://localhost:6379\n`;\n }\n\n return env;\n}\n\nfunction generateGitignore(): string {\n return `node_modules/\ndist/\n.env\n.env.local\n*.log\ncoverage/\n.DS_Store\n*.db\n`;\n}\n\nfunction generateDockerfile(options: InitOptions): string {\n const isTS = options.language === 'typescript';\n\n return `FROM node:20-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci --only=production\nCOPY ${isTS ? 'dist' : 'src'} ./${isTS ? 'dist' : 'src'}\n${options.database !== 'none' && options.database !== 'mongodb' ? 'COPY prisma ./prisma\\nRUN npx prisma generate' : ''}\nEXPOSE 3000\nCMD [\"node\", \"${isTS ? 'dist' : 'src'}/index.js\"]\n`;\n}\n\nfunction generateDockerCompose(options: InitOptions): string {\n let compose = `version: '3.8'\n\nservices:\n app:\n build: .\n ports:\n - \"\\${PORT:-3000}:3000\"\n environment:\n - NODE_ENV=development\n`;\n\n if (options.database === 'postgresql') {\n compose += ` - DATABASE_URL=postgresql://postgres:postgres@postgres:5432/mydb\n depends_on:\n - postgres\n\n postgres:\n image: postgres:16-alpine\n environment:\n POSTGRES_USER: postgres\n POSTGRES_PASSWORD: postgres\n POSTGRES_DB: mydb\n ports:\n - \"5432:5432\"\n volumes:\n - postgres-data:/var/lib/postgresql/data\n\nvolumes:\n postgres-data:\n`;\n } else if (options.database === 'mysql') {\n compose += ` - DATABASE_URL=mysql://root:root@mysql:3306/mydb\n depends_on:\n - mysql\n\n mysql:\n image: mysql:8.0\n environment:\n MYSQL_ROOT_PASSWORD: root\n MYSQL_DATABASE: mydb\n ports:\n - \"3306:3306\"\n volumes:\n - mysql-data:/var/lib/mysql\n\nvolumes:\n mysql-data:\n`;\n } else if (options.database === 'mongodb') {\n compose += ` - MONGODB_URI=mongodb://mongodb:27017/mydb\n depends_on:\n - mongodb\n\n mongodb:\n image: mongo:7\n environment:\n MONGO_INITDB_DATABASE: mydb\n ports:\n - \"27017:27017\"\n volumes:\n - mongodb-data:/data/db\n\nvolumes:\n mongodb-data:\n`;\n }\n\n if (options.features.includes('redis')) {\n compose += `\n redis:\n image: redis:7-alpine\n ports:\n - \"6379:6379\"\n`;\n }\n\n return compose;\n}\n\nfunction generatePrismaSchema(options: InitOptions): string {\n const provider = options.database === 'sqlite' ? 'sqlite' : options.database;\n\n return `generator client {\n provider = \"prisma-client-js\"\n}\n\ndatasource db {\n provider = \"${provider}\"\n url = env(\"DATABASE_URL\")\n}\n\nmodel User {\n id String @id @default(uuid())\n email String @unique\n password String\n name String?\n role String @default(\"user\")\n status String @default(\"active\")\n emailVerified Boolean @default(false)\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@map(\"users\")\n}\n`;\n}\n\nfunction generateEntryFile(options: InitOptions): string {\n const isTS = options.language === 'typescript';\n const isESM = options.moduleSystem === 'esm';\n const fileExt = isTS ? 'js' : isESM ? 'js' : 'cjs';\n\n if (isESM || isTS) {\n return `import 'dotenv/config';\nimport { createServer } from './core/server.${fileExt}';\nimport { logger } from './core/logger.${fileExt}';\n\nasync function main()${isTS ? ': Promise<void>' : ''} {\n const server = createServer();\n\n try {\n await server.start();\n } catch (error) {\n logger.error({ err: error }, 'Failed to start server');\n process.exit(1);\n }\n}\n\nmain();\n`;\n } else {\n // CommonJS\n return `require('dotenv').config();\nconst { createServer } = require('./core/server.cjs');\nconst { logger } = require('./core/logger.cjs');\n\nasync function main() {\n const server = createServer();\n\n try {\n await server.start();\n } catch (error) {\n logger.error({ err: error }, 'Failed to start server');\n process.exit(1);\n }\n}\n\nmain();\n`;\n }\n}\n\nfunction generateServerFile(options: InitOptions): string {\n const isTS = options.language === 'typescript';\n const isESM = options.moduleSystem === 'esm';\n const fileExt = isTS ? 'js' : isESM ? 'js' : 'cjs';\n\n const serverBody = ` const app = Fastify({ logger });\n\n // Health check\n app.get('/health', async () => ({\n status: 'ok',\n timestamp: new Date().toISOString(),\n }));\n\n // Graceful shutdown\n const signals${isTS ? ': NodeJS.Signals[]' : ''} = ['SIGINT', 'SIGTERM'];\n signals.forEach((signal) => {\n process.on(signal, async () => {\n logger.info(\\`Received \\${signal}, shutting down...\\`);\n await app.close();\n process.exit(0);\n });\n });\n\n return {\n instance: app,\n start: async ()${isTS ? ': Promise<void>' : ''} => {\n const port = parseInt(process.env.PORT || '3000', 10);\n const host = process.env.HOST || '0.0.0.0';\n await app.listen({ port, host });\n logger.info(\\`Server listening on \\${host}:\\${port}\\`);\n },\n };\n}`;\n\n if (isESM || isTS) {\n return `import Fastify from 'fastify';\n${isTS ? \"import type { FastifyInstance } from 'fastify';\" : ''}\nimport { logger } from './logger.${fileExt}';\n\n${isTS ? 'export function createServer(): { instance: FastifyInstance; start: () => Promise<void> }' : 'export function createServer()'} {\n${serverBody}\n`;\n } else {\n // CommonJS\n return `const Fastify = require('fastify');\nconst { logger } = require('./logger.cjs');\n\nfunction createServer() {\n${serverBody}\n\nmodule.exports = { createServer };\n`;\n }\n}\n\nfunction generateLoggerFile(options: InitOptions): string {\n const isTS = options.language === 'typescript';\n const isESM = options.moduleSystem === 'esm';\n\n const loggerBody = `pino({\n level: process.env.LOG_LEVEL || 'info',\n transport: process.env.NODE_ENV !== 'production' ? {\n target: 'pino-pretty',\n options: { colorize: true },\n } : undefined,\n})`;\n\n if (isESM || isTS) {\n return `import pino from 'pino';\n${isTS ? \"import type { Logger } from 'pino';\" : ''}\n\nexport const logger${isTS ? ': Logger' : ''} = ${loggerBody};\n`;\n } else {\n // CommonJS\n return `const pino = require('pino');\n\nconst logger = ${loggerBody};\n\nmodule.exports = { logger };\n`;\n }\n}\n\nfunction generateMongooseConnection(options: InitOptions): string {\n const isTS = options.language === 'typescript';\n const isESM = options.moduleSystem === 'esm';\n const fileExt = isTS ? 'js' : isESM ? 'js' : 'cjs';\n\n const connectionBody = `const MONGODB_URI = process.env.MONGODB_URI || 'mongodb://localhost:27017/mydb';\n\nasync function connectDatabase()${isTS ? ': Promise<typeof mongoose>' : ''} {\n try {\n const conn = await mongoose.connect(MONGODB_URI);\n logger.info(\\`MongoDB connected: \\${conn.connection.host}\\`);\n return conn;\n } catch (error) {\n logger.error({ err: error }, 'MongoDB connection failed');\n process.exit(1);\n }\n}\n\nasync function disconnectDatabase()${isTS ? ': Promise<void>' : ''} {\n try {\n await mongoose.disconnect();\n logger.info('MongoDB disconnected');\n } catch (error) {\n logger.error({ err: error }, 'MongoDB disconnect failed');\n }\n}`;\n\n if (isESM || isTS) {\n return `import mongoose from 'mongoose';\nimport { logger } from '../core/logger.${fileExt}';\n\n${connectionBody}\n\nexport { connectDatabase, disconnectDatabase, mongoose };\n`;\n } else {\n // CommonJS\n return `const mongoose = require('mongoose');\nconst { logger } = require('../core/logger.cjs');\n\n${connectionBody}\n\nmodule.exports = { connectDatabase, disconnectDatabase, mongoose };\n`;\n }\n}\n\nfunction generateMongooseUserModel(options: InitOptions): string {\n const isTS = options.language === 'typescript';\n const isESM = options.moduleSystem === 'esm';\n\n const schemaBody = `const userSchema = new Schema${isTS ? '<IUser>' : ''}({\n email: {\n type: String,\n required: true,\n unique: true,\n lowercase: true,\n trim: true,\n },\n password: {\n type: String,\n required: true,\n minlength: 8,\n },\n name: {\n type: String,\n trim: true,\n },\n role: {\n type: String,\n enum: ['user', 'admin'],\n default: 'user',\n },\n status: {\n type: String,\n enum: ['active', 'inactive', 'suspended'],\n default: 'active',\n },\n emailVerified: {\n type: Boolean,\n default: false,\n },\n}, {\n timestamps: true,\n});\n\n// Hash password before saving\nuserSchema.pre('save', async function(next) {\n if (!this.isModified('password')) return next();\n\n try {\n const salt = await bcrypt.genSalt(10);\n this.password = await bcrypt.hash(this.password, salt);\n next();\n } catch (error${isTS ? ': any' : ''}) {\n next(error);\n }\n});\n\n// Compare password method\nuserSchema.methods.comparePassword = async function(candidatePassword${isTS ? ': string' : ''})${isTS ? ': Promise<boolean>' : ''} {\n return bcrypt.compare(candidatePassword, this.password);\n};`;\n\n const tsInterface = isTS\n ? `\nexport interface IUser extends Document {\n email: string;\n password: string;\n name?: string;\n role: 'user' | 'admin';\n status: 'active' | 'inactive' | 'suspended';\n emailVerified: boolean;\n createdAt: Date;\n updatedAt: Date;\n comparePassword(candidatePassword: string): Promise<boolean>;\n}\n`\n : '';\n\n if (isESM || isTS) {\n return `import mongoose${isTS ? ', { Schema, Document }' : ''} from 'mongoose';\nimport bcrypt from 'bcryptjs';\n${!isTS ? 'const { Schema } = mongoose;' : ''}\n${tsInterface}\n${schemaBody}\n\nexport const User = mongoose.model${isTS ? '<IUser>' : ''}('User', userSchema);\n`;\n } else {\n // CommonJS\n return `const mongoose = require('mongoose');\nconst bcrypt = require('bcryptjs');\nconst { Schema } = mongoose;\n\n${schemaBody}\n\nconst User = mongoose.model('User', userSchema);\n\nmodule.exports = { User };\n`;\n }\n}\n\nfunction generateConfigFile(options: InitOptions): string {\n const isTS = options.language === 'typescript';\n const isESM = options.moduleSystem === 'esm';\n\n const configBody = `{\n env: process.env.NODE_ENV || 'development',\n port: parseInt(process.env.PORT || '3000', 10),\n host: process.env.HOST || '0.0.0.0',\n\n jwt: {\n secret: process.env.JWT_SECRET || 'your-secret-key',\n accessExpiresIn: process.env.JWT_ACCESS_EXPIRES_IN || '15m',\n refreshExpiresIn: process.env.JWT_REFRESH_EXPIRES_IN || '7d',\n },\n\n cors: {\n origin: process.env.CORS_ORIGIN || 'http://localhost:3000',\n },\n\n rateLimit: {\n max: parseInt(process.env.RATE_LIMIT_MAX || '100', 10),\n },\n\n log: {\n level: process.env.LOG_LEVEL || 'info',\n },\n}${isTS ? ' as const' : ''}`;\n\n if (isESM || isTS) {\n return `import 'dotenv/config';\n\nexport const config = ${configBody};\n`;\n } else {\n // CommonJS\n return `require('dotenv').config();\n\nconst config = ${configBody};\n\nmodule.exports = { config };\n`;\n }\n}\n\nfunction generateMiddlewareFile(options: InitOptions): string {\n const isTS = options.language === 'typescript';\n const isESM = options.moduleSystem === 'esm';\n const fileExt = isTS ? 'js' : isESM ? 'js' : 'cjs';\n\n const middlewareBody = `/**\n * Error handler middleware\n */\nfunction errorHandler(error${isTS ? ': Error' : ''}, request${isTS ? ': FastifyRequest' : ''}, reply${isTS ? ': FastifyReply' : ''})${isTS ? ': void' : ''} {\n logger.error({ err: error, url: request.url, method: request.method }, 'Request error');\n\n const statusCode = (error${isTS ? ' as any' : ''}).statusCode || 500;\n const message = statusCode === 500 ? 'Internal Server Error' : error.message;\n\n reply.status(statusCode).send({\n success: false,\n error: message,\n ...(process.env.NODE_ENV === 'development' && { stack: error.stack }),\n });\n}\n\n/**\n * Request logging middleware\n */\nfunction requestLogger(request${isTS ? ': FastifyRequest' : ''}, reply${isTS ? ': FastifyReply' : ''}, done${isTS ? ': () => void' : ''})${isTS ? ': void' : ''} {\n logger.info({ url: request.url, method: request.method, ip: request.ip }, 'Incoming request');\n done();\n}`;\n\n if (isESM || isTS) {\n return `${isTS ? \"import type { FastifyRequest, FastifyReply } from 'fastify';\" : ''}\nimport { logger } from '../core/logger.${fileExt}';\n\n${middlewareBody}\n\nexport { errorHandler, requestLogger };\n`;\n } else {\n // CommonJS\n return `const { logger } = require('../core/logger.cjs');\n\n${middlewareBody}\n\nmodule.exports = { errorHandler, requestLogger };\n`;\n }\n}\n\nfunction generateUtilsFile(options: InitOptions): string {\n const isTS = options.language === 'typescript';\n const isESM = options.moduleSystem === 'esm';\n\n const utilsBody = `/**\n * Standard API response helper\n */\nfunction apiResponse${isTS ? '<T>' : ''}(data${isTS ? ': T' : ''}, message = \"Success\")${isTS ? ': { success: boolean; message: string; data: T }' : ''} {\n return {\n success: true,\n message,\n data,\n };\n}\n\n/**\n * Error response helper\n */\nfunction errorResponse(message${isTS ? ': string' : ''}, code${isTS ? '?: string' : ''})${isTS ? ': { success: boolean; error: string; code?: string }' : ''} {\n return {\n success: false,\n error: message,\n ...(code && { code }),\n };\n}\n\n/**\n * Pagination helper\n */\nfunction paginate${isTS ? '<T>' : ''}(data${isTS ? ': T[]' : ''}, page${isTS ? ': number' : ''}, limit${isTS ? ': number' : ''}, total${isTS ? ': number' : ''})${isTS ? ': PaginationResult<T>' : ''} {\n const totalPages = Math.ceil(total / limit);\n\n return {\n data,\n pagination: {\n page,\n limit,\n total,\n totalPages,\n hasNextPage: page < totalPages,\n hasPrevPage: page > 1,\n },\n };\n}`;\n\n const tsInterface = isTS\n ? `\n/**\n * Pagination result type\n */\nexport interface PaginationResult<T> {\n data: T[];\n pagination: {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n hasNextPage: boolean;\n hasPrevPage: boolean;\n };\n}\n`\n : '';\n\n if (isESM || isTS) {\n return `${tsInterface}\n${utilsBody}\n\nexport { apiResponse, errorResponse, paginate };\n`;\n } else {\n // CommonJS\n return `${utilsBody}\n\nmodule.exports = { apiResponse, errorResponse, paginate };\n`;\n }\n}\n\nfunction generateTypesFile(options: InitOptions): string {\n if (options.language !== 'typescript') {\n return '// Types file - not needed for JavaScript\\n';\n }\n\n return `/**\n * Common type definitions\n */\n\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n message?: string;\n data?: T;\n error?: string;\n code?: string;\n}\n\nexport interface PaginatedResponse<T> {\n data: T[];\n pagination: {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n hasNextPage: boolean;\n hasPrevPage: boolean;\n };\n}\n\nexport interface RequestUser {\n id: string;\n email: string;\n role: string;\n}\n\ndeclare module 'fastify' {\n interface FastifyRequest {\n user?: RequestUser;\n }\n}\n`;\n}\n","import fs from 'fs/promises';\nimport path from 'path';\nimport chalk from 'chalk';\nimport { DryRunManager } from './dry-run.js';\n\nexport function toPascalCase(str: string): string {\n return str\n .split(/[-_\\s]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n}\n\nexport function toCamelCase(str: string): string {\n const pascal = toPascalCase(str);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n}\n\nexport function toKebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n}\n\nexport function toSnakeCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .replace(/[\\s-]+/g, '_')\n .toLowerCase();\n}\n\nexport function pluralize(str: string): string {\n if (str.endsWith('y')) {\n return str.slice(0, -1) + 'ies';\n }\n if (str.endsWith('s') || str.endsWith('x') || str.endsWith('ch') || str.endsWith('sh')) {\n return str + 'es';\n }\n return str + 's';\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function ensureDir(dirPath: string): Promise<void> {\n await fs.mkdir(dirPath, { recursive: true });\n}\n\nexport async function writeFile(filePath: string, content: string): Promise<void> {\n const dryRun = DryRunManager.getInstance();\n\n if (dryRun.isEnabled()) {\n dryRun.addOperation({\n type: 'create',\n path: dryRun.relativePath(filePath),\n content,\n size: content.length,\n });\n return;\n }\n\n await ensureDir(path.dirname(filePath));\n await fs.writeFile(filePath, content, 'utf-8');\n}\n\nexport function log(message: string): void {\n console.log(message);\n}\n\nexport function success(message: string): void {\n console.log(chalk.green('✓'), message);\n}\n\nexport function error(message: string): void {\n console.error(chalk.red('✗'), message);\n}\n\nexport function warn(message: string): void {\n console.log(chalk.yellow('⚠'), message);\n}\n\nexport function info(message: string): void {\n console.log(chalk.blue('ℹ'), message);\n}\n\nexport function getProjectRoot(): string {\n return process.cwd();\n}\n\nexport function getSourceDir(): string {\n return path.join(getProjectRoot(), 'src');\n}\n\nexport function getModulesDir(): string {\n return path.join(getSourceDir(), 'modules');\n}\n","/* eslint-disable no-console */\nimport chalk from 'chalk';\nimport path from 'path';\n\nexport interface FileOperation {\n type: 'create' | 'modify' | 'delete';\n path: string;\n content?: string;\n size?: number;\n}\n\nexport class DryRunManager {\n private static instance: DryRunManager;\n private enabled = false;\n private operations: FileOperation[] = [];\n\n private constructor() {}\n\n static getInstance(): DryRunManager {\n if (!DryRunManager.instance) {\n DryRunManager.instance = new DryRunManager();\n }\n return DryRunManager.instance;\n }\n\n enable(): void {\n this.enabled = true;\n this.operations = [];\n }\n\n disable(): void {\n this.enabled = false;\n this.operations = [];\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n addOperation(operation: FileOperation): void {\n if (this.enabled) {\n this.operations.push(operation);\n }\n }\n\n getOperations(): FileOperation[] {\n return [...this.operations];\n }\n\n printSummary(): void {\n if (!this.enabled || this.operations.length === 0) {\n return;\n }\n\n console.log(chalk.bold.yellow('\\n📋 Dry Run - Preview of changes:\\n'));\n console.log(chalk.gray('No files will be written. Remove --dry-run to apply changes.\\n'));\n\n const createOps = this.operations.filter((op) => op.type === 'create');\n const modifyOps = this.operations.filter((op) => op.type === 'modify');\n const deleteOps = this.operations.filter((op) => op.type === 'delete');\n\n if (createOps.length > 0) {\n console.log(chalk.green.bold(`\\n✓ Files to be created (${createOps.length}):`));\n createOps.forEach((op) => {\n const size = op.content ? `${op.content.length} bytes` : 'unknown size';\n console.log(` ${chalk.green('+')} ${chalk.cyan(op.path)} ${chalk.gray(`(${size})`)}`);\n });\n }\n\n if (modifyOps.length > 0) {\n console.log(chalk.yellow.bold(`\\n~ Files to be modified (${modifyOps.length}):`));\n modifyOps.forEach((op) => {\n console.log(` ${chalk.yellow('~')} ${chalk.cyan(op.path)}`);\n });\n }\n\n if (deleteOps.length > 0) {\n console.log(chalk.red.bold(`\\n- Files to be deleted (${deleteOps.length}):`));\n deleteOps.forEach((op) => {\n console.log(` ${chalk.red('-')} ${chalk.cyan(op.path)}`);\n });\n }\n\n console.log(chalk.gray('\\n' + '─'.repeat(60)));\n console.log(\n chalk.bold(` Total operations: ${this.operations.length}`) +\n chalk.gray(\n ` (${createOps.length} create, ${modifyOps.length} modify, ${deleteOps.length} delete)`\n )\n );\n console.log(chalk.gray('─'.repeat(60)));\n console.log(chalk.yellow('\\n⚠ This was a dry run. No files were created or modified.'));\n console.log(chalk.gray(' Remove --dry-run to apply these changes.\\n'));\n }\n\n // Helper to format file path relative to cwd\n relativePath(filePath: string): string {\n return path.relative(process.cwd(), filePath);\n }\n}\n\n// Wrapper functions for file operations\nexport async function dryRunWriteFile(\n filePath: string,\n content: string,\n actualWriteFn: (path: string, content: string) => Promise<void>\n): Promise<void> {\n const dryRun = DryRunManager.getInstance();\n\n if (dryRun.isEnabled()) {\n dryRun.addOperation({\n type: 'create',\n path: dryRun.relativePath(filePath),\n content,\n size: content.length,\n });\n return;\n }\n\n await actualWriteFn(filePath, content);\n}\n\nexport async function dryRunModifyFile(\n filePath: string,\n actualModifyFn: (path: string) => Promise<void>\n): Promise<void> {\n const dryRun = DryRunManager.getInstance();\n\n if (dryRun.isEnabled()) {\n dryRun.addOperation({\n type: 'modify',\n path: dryRun.relativePath(filePath),\n });\n return;\n }\n\n await actualModifyFn(filePath);\n}\n\nexport async function dryRunDeleteFile(\n filePath: string,\n actualDeleteFn: (path: string) => Promise<void>\n): Promise<void> {\n const dryRun = DryRunManager.getInstance();\n\n if (dryRun.isEnabled()) {\n dryRun.addOperation({\n type: 'delete',\n path: dryRun.relativePath(filePath),\n });\n return;\n }\n\n await actualDeleteFn(filePath);\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport ora from 'ora';\nimport inquirer from 'inquirer';\nimport {\n toPascalCase,\n toCamelCase,\n toKebabCase,\n pluralize,\n fileExists,\n writeFile,\n success,\n error,\n info,\n getModulesDir,\n} from '../utils/helpers.js';\nimport { DryRunManager } from '../utils/dry-run.js';\nimport chalk from 'chalk';\nimport { parseFields, type FieldDefinition } from '../utils/field-parser.js';\nimport { ErrorTypes, displayError } from '../utils/error-handler.js';\n\n// Helper to enable dry-run mode\nfunction enableDryRunIfNeeded(options: { dryRun?: boolean }): void {\n const dryRun = DryRunManager.getInstance();\n if (options.dryRun) {\n dryRun.enable();\n console.log(chalk.yellow('\\n⚠ DRY RUN MODE - No files will be written\\n'));\n }\n}\n\n// Helper to show dry-run summary\nfunction showDryRunSummary(options: { dryRun?: boolean }): void {\n if (options.dryRun) {\n DryRunManager.getInstance().printSummary();\n }\n}\nimport { controllerTemplate } from '../templates/controller.js';\nimport { serviceTemplate } from '../templates/service.js';\nimport { repositoryTemplate } from '../templates/repository.js';\nimport { typesTemplate } from '../templates/types.js';\nimport { schemasTemplate } from '../templates/schemas.js';\nimport { routesTemplate } from '../templates/routes.js';\nimport { moduleIndexTemplate } from '../templates/module-index.js';\nimport { prismaModelTemplate } from '../templates/prisma-model.js';\nimport { dynamicTypesTemplate } from '../templates/dynamic-types.js';\nimport { dynamicSchemasTemplate, type ValidatorType } from '../templates/dynamic-schemas.js';\nimport { dynamicPrismaTemplate } from '../templates/dynamic-prisma.js';\nimport { controllerTestTemplate } from '../templates/controller-test.js';\nimport { serviceTestTemplate } from '../templates/service-test.js';\nimport { integrationTestTemplate } from '../templates/integration-test.js';\nimport { getTemplate } from '../utils/template-loader.js';\n\nexport const generateCommand = new Command('generate')\n .alias('g')\n .description('Generate resources (module, controller, service, etc.)');\n\n// Generate full module\ngenerateCommand\n .command('module <name> [fields...]')\n .alias('m')\n .description(\n 'Generate a complete module with controller, service, repository, types, schemas, and routes'\n )\n .option('--no-routes', 'Skip routes generation')\n .option('--no-repository', 'Skip repository generation')\n .option('--prisma', 'Generate Prisma model suggestion')\n .option('--validator <type>', 'Validator type: zod, joi, yup', 'zod')\n .option('-i, --interactive', 'Interactive mode to define fields')\n .option('--with-tests', 'Generate test files (__tests__ directory)')\n .option('--dry-run', 'Preview changes without writing files')\n .action(async (name: string, fieldsArgs: string[], options) => {\n enableDryRunIfNeeded(options);\n let fields: FieldDefinition[] = [];\n\n // Parse fields from command line or interactive mode\n if (options.interactive) {\n fields = await promptForFields();\n } else if (fieldsArgs.length > 0) {\n fields = parseFields(fieldsArgs.join(' '));\n }\n\n const spinner = ora('Generating module...').start();\n\n try {\n const kebabName = toKebabCase(name);\n const pascalName = toPascalCase(name);\n const camelName = toCamelCase(name);\n const pluralName = pluralize(kebabName);\n const tableName = pluralize(kebabName.replace(/-/g, '_'));\n const validatorType = (options.validator || 'zod') as ValidatorType;\n\n const moduleDir = path.join(getModulesDir(), kebabName);\n\n // Check if module already exists\n if (await fileExists(moduleDir)) {\n spinner.stop();\n error(`Module \"${kebabName}\" already exists`);\n return;\n }\n\n // Use dynamic templates if fields are provided\n const hasFields = fields.length > 0;\n\n // Load templates (custom or built-in)\n const controllerTpl = await getTemplate('controller', controllerTemplate);\n const serviceTpl = await getTemplate('service', serviceTemplate);\n const repositoryTpl = await getTemplate('repository', repositoryTemplate);\n const typesTpl = await getTemplate('types', typesTemplate);\n const schemasTpl = await getTemplate('schemas', schemasTemplate);\n const routesTpl = await getTemplate('routes', routesTemplate);\n const moduleIndexTpl = await getTemplate('module-index', moduleIndexTemplate);\n\n const files = [\n {\n name: `${kebabName}.types.ts`,\n content: hasFields\n ? dynamicTypesTemplate(kebabName, pascalName, fields)\n : typesTpl(kebabName, pascalName),\n },\n {\n name: `${kebabName}.schemas.ts`,\n content: hasFields\n ? dynamicSchemasTemplate(kebabName, pascalName, camelName, fields, validatorType)\n : schemasTpl(kebabName, pascalName, camelName),\n },\n {\n name: `${kebabName}.service.ts`,\n content: serviceTpl(kebabName, pascalName, camelName),\n },\n {\n name: `${kebabName}.controller.ts`,\n content: controllerTpl(kebabName, pascalName, camelName),\n },\n { name: 'index.ts', content: moduleIndexTpl(kebabName, pascalName, camelName) },\n ];\n\n if (options.repository !== false) {\n files.push({\n name: `${kebabName}.repository.ts`,\n content: repositoryTpl(kebabName, pascalName, camelName, pluralName),\n });\n }\n\n if (options.routes !== false) {\n files.push({\n name: `${kebabName}.routes.ts`,\n content: routesTpl(kebabName, pascalName, camelName, pluralName),\n });\n }\n\n // Write all files\n for (const file of files) {\n await writeFile(path.join(moduleDir, file.name), file.content);\n }\n\n // Generate test files if --with-tests flag is provided\n if (options.withTests) {\n const testDir = path.join(moduleDir, '__tests__');\n\n // Load test templates (custom or built-in)\n const controllerTestTpl = await getTemplate('controller-test', controllerTestTemplate);\n const serviceTestTpl = await getTemplate('service-test', serviceTestTemplate);\n const integrationTestTpl = await getTemplate('integration-test', integrationTestTemplate);\n\n await writeFile(\n path.join(testDir, `${kebabName}.controller.test.ts`),\n controllerTestTpl(kebabName, pascalName, camelName)\n );\n\n await writeFile(\n path.join(testDir, `${kebabName}.service.test.ts`),\n serviceTestTpl(kebabName, pascalName, camelName)\n );\n\n await writeFile(\n path.join(testDir, `${kebabName}.integration.test.ts`),\n integrationTestTpl(kebabName, pascalName, camelName)\n );\n }\n\n spinner.succeed(`Module \"${pascalName}\" generated successfully!`);\n\n // Show Prisma model if requested or fields provided\n if (options.prisma || hasFields) {\n console.log('\\n' + '─'.repeat(50));\n info('Prisma model suggestion:');\n if (hasFields) {\n console.log(dynamicPrismaTemplate(pascalName, tableName, fields));\n } else {\n console.log(prismaModelTemplate(kebabName, pascalName, tableName));\n }\n }\n\n // Show fields summary if provided\n if (hasFields) {\n console.log('\\n📋 Fields defined:');\n fields.forEach((f) => {\n const opts = [];\n if (f.isOptional) opts.push('optional');\n if (f.isArray) opts.push('array');\n if (f.isUnique) opts.push('unique');\n const optsStr = opts.length > 0 ? ` (${opts.join(', ')})` : '';\n success(` ${f.name}: ${f.type}${optsStr}`);\n });\n }\n\n // Show next steps\n console.log('\\n📁 Files created:');\n files.forEach((f) => success(` src/modules/${kebabName}/${f.name}`));\n\n if (options.withTests) {\n success(` src/modules/${kebabName}/__tests__/${kebabName}.controller.test.ts`);\n success(` src/modules/${kebabName}/__tests__/${kebabName}.service.test.ts`);\n success(` src/modules/${kebabName}/__tests__/${kebabName}.integration.test.ts`);\n }\n\n console.log('\\n📌 Next steps:');\n if (!hasFields) {\n info(' 1. Update the types in ' + `${kebabName}.types.ts`);\n info(' 2. Update the schemas in ' + `${kebabName}.schemas.ts`);\n info(' 3. Register the module in your app');\n } else {\n info(' 1. Review generated types and schemas');\n info(' 2. Register the module in your app');\n }\n if (options.prisma || hasFields) {\n info(` ${hasFields ? '3' : '4'}. Add the Prisma model to schema.prisma`);\n info(` ${hasFields ? '4' : '5'}. Run: npm run db:migrate`);\n }\n\n // Show dry-run summary if enabled\n showDryRunSummary(options);\n } catch (err) {\n spinner.fail('Failed to generate module');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\n// Generate controller only\ngenerateCommand\n .command('controller <name>')\n .alias('c')\n .description('Generate a controller')\n .option('-m, --module <module>', 'Target module name')\n .option('--dry-run', 'Preview changes without writing files')\n .action(async (name: string, options) => {\n enableDryRunIfNeeded(options);\n const spinner = ora('Generating controller...').start();\n\n try {\n const kebabName = toKebabCase(name);\n const pascalName = toPascalCase(name);\n const camelName = toCamelCase(name);\n\n const moduleName = options.module ? toKebabCase(options.module) : kebabName;\n const moduleDir = path.join(getModulesDir(), moduleName);\n const filePath = path.join(moduleDir, `${kebabName}.controller.ts`);\n\n if (await fileExists(filePath)) {\n spinner.stop();\n displayError(ErrorTypes.FILE_ALREADY_EXISTS(`${kebabName}.controller.ts`));\n return;\n }\n\n await writeFile(filePath, controllerTemplate(kebabName, pascalName, camelName));\n\n spinner.succeed(`Controller \"${pascalName}Controller\" generated!`);\n success(` src/modules/${moduleName}/${kebabName}.controller.ts`);\n showDryRunSummary(options);\n } catch (err) {\n spinner.fail('Failed to generate controller');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\n// Generate service only\ngenerateCommand\n .command('service <name>')\n .alias('s')\n .description('Generate a service')\n .option('-m, --module <module>', 'Target module name')\n .option('--dry-run', 'Preview changes without writing files')\n .action(async (name: string, options) => {\n enableDryRunIfNeeded(options);\n const spinner = ora('Generating service...').start();\n\n try {\n const kebabName = toKebabCase(name);\n const pascalName = toPascalCase(name);\n const camelName = toCamelCase(name);\n\n const moduleName = options.module ? toKebabCase(options.module) : kebabName;\n const moduleDir = path.join(getModulesDir(), moduleName);\n const filePath = path.join(moduleDir, `${kebabName}.service.ts`);\n\n if (await fileExists(filePath)) {\n spinner.stop();\n error(`Service \"${kebabName}\" already exists`);\n return;\n }\n\n await writeFile(filePath, serviceTemplate(kebabName, pascalName, camelName));\n\n spinner.succeed(`Service \"${pascalName}Service\" generated!`);\n success(` src/modules/${moduleName}/${kebabName}.service.ts`);\n showDryRunSummary(options);\n } catch (err) {\n spinner.fail('Failed to generate service');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\n// Generate repository only\ngenerateCommand\n .command('repository <name>')\n .alias('r')\n .description('Generate a repository')\n .option('-m, --module <module>', 'Target module name')\n .option('--dry-run', 'Preview changes without writing files')\n .action(async (name: string, options) => {\n enableDryRunIfNeeded(options);\n const spinner = ora('Generating repository...').start();\n\n try {\n const kebabName = toKebabCase(name);\n const pascalName = toPascalCase(name);\n const camelName = toCamelCase(name);\n const pluralName = pluralize(kebabName);\n\n const moduleName = options.module ? toKebabCase(options.module) : kebabName;\n const moduleDir = path.join(getModulesDir(), moduleName);\n const filePath = path.join(moduleDir, `${kebabName}.repository.ts`);\n\n if (await fileExists(filePath)) {\n spinner.stop();\n error(`Repository \"${kebabName}\" already exists`);\n return;\n }\n\n await writeFile(filePath, repositoryTemplate(kebabName, pascalName, camelName, pluralName));\n\n spinner.succeed(`Repository \"${pascalName}Repository\" generated!`);\n success(` src/modules/${moduleName}/${kebabName}.repository.ts`);\n showDryRunSummary(options);\n } catch (err) {\n spinner.fail('Failed to generate repository');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\n// Generate types only\ngenerateCommand\n .command('types <name>')\n .alias('t')\n .description('Generate types/interfaces')\n .option('-m, --module <module>', 'Target module name')\n .option('--dry-run', 'Preview changes without writing files')\n .action(async (name: string, options) => {\n enableDryRunIfNeeded(options);\n const spinner = ora('Generating types...').start();\n\n try {\n const kebabName = toKebabCase(name);\n const pascalName = toPascalCase(name);\n\n const moduleName = options.module ? toKebabCase(options.module) : kebabName;\n const moduleDir = path.join(getModulesDir(), moduleName);\n const filePath = path.join(moduleDir, `${kebabName}.types.ts`);\n\n if (await fileExists(filePath)) {\n spinner.stop();\n error(`Types file \"${kebabName}.types.ts\" already exists`);\n return;\n }\n\n await writeFile(filePath, typesTemplate(kebabName, pascalName));\n\n spinner.succeed(`Types for \"${pascalName}\" generated!`);\n success(` src/modules/${moduleName}/${kebabName}.types.ts`);\n showDryRunSummary(options);\n } catch (err) {\n spinner.fail('Failed to generate types');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\n// Generate schemas/validators only\ngenerateCommand\n .command('schema <name>')\n .alias('v')\n .description('Generate validation schemas')\n .option('-m, --module <module>', 'Target module name')\n .option('--dry-run', 'Preview changes without writing files')\n .action(async (name: string, options) => {\n enableDryRunIfNeeded(options);\n const spinner = ora('Generating schemas...').start();\n\n try {\n const kebabName = toKebabCase(name);\n const pascalName = toPascalCase(name);\n const camelName = toCamelCase(name);\n\n const moduleName = options.module ? toKebabCase(options.module) : kebabName;\n const moduleDir = path.join(getModulesDir(), moduleName);\n const filePath = path.join(moduleDir, `${kebabName}.schemas.ts`);\n\n if (await fileExists(filePath)) {\n spinner.stop();\n error(`Schemas file \"${kebabName}.schemas.ts\" already exists`);\n return;\n }\n\n await writeFile(filePath, schemasTemplate(kebabName, pascalName, camelName));\n\n spinner.succeed(`Schemas for \"${pascalName}\" generated!`);\n success(` src/modules/${moduleName}/${kebabName}.schemas.ts`);\n showDryRunSummary(options);\n } catch (err) {\n spinner.fail('Failed to generate schemas');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\n// Generate routes only\ngenerateCommand\n .command('routes <name>')\n .description('Generate routes')\n .option('-m, --module <module>', 'Target module name')\n .option('--dry-run', 'Preview changes without writing files')\n .action(async (name: string, options) => {\n enableDryRunIfNeeded(options);\n const spinner = ora('Generating routes...').start();\n\n try {\n const kebabName = toKebabCase(name);\n const pascalName = toPascalCase(name);\n const camelName = toCamelCase(name);\n const pluralName = pluralize(kebabName);\n\n const moduleName = options.module ? toKebabCase(options.module) : kebabName;\n const moduleDir = path.join(getModulesDir(), moduleName);\n const filePath = path.join(moduleDir, `${kebabName}.routes.ts`);\n\n if (await fileExists(filePath)) {\n spinner.stop();\n error(`Routes file \"${kebabName}.routes.ts\" already exists`);\n return;\n }\n\n await writeFile(filePath, routesTemplate(kebabName, pascalName, camelName, pluralName));\n\n spinner.succeed(`Routes for \"${pascalName}\" generated!`);\n success(` src/modules/${moduleName}/${kebabName}.routes.ts`);\n showDryRunSummary(options);\n } catch (err) {\n spinner.fail('Failed to generate routes');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\n// Interactive field prompt helper\nasync function promptForFields(): Promise<FieldDefinition[]> {\n const fields: FieldDefinition[] = [];\n\n console.log('\\n📝 Define your model fields (press Enter with empty name to finish)\\n');\n\n const fieldTypes = [\n 'string',\n 'number',\n 'boolean',\n 'date',\n 'datetime',\n 'text',\n 'email',\n 'url',\n 'uuid',\n 'int',\n 'float',\n 'decimal',\n 'json',\n ];\n\n let addMore = true;\n\n while (addMore) {\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'name',\n message: 'Field name (empty to finish):',\n },\n ]);\n\n if (!answers.name) {\n addMore = false;\n continue;\n }\n\n const fieldDetails = await inquirer.prompt([\n {\n type: 'list',\n name: 'type',\n message: `Type for \"${answers.name}\":`,\n choices: fieldTypes,\n default: 'string',\n },\n {\n type: 'confirm',\n name: 'isOptional',\n message: 'Is optional?',\n default: false,\n },\n {\n type: 'confirm',\n name: 'isUnique',\n message: 'Is unique?',\n default: false,\n },\n {\n type: 'confirm',\n name: 'isArray',\n message: 'Is array?',\n default: false,\n },\n ]);\n\n fields.push({\n name: answers.name,\n type: fieldDetails.type,\n isOptional: fieldDetails.isOptional,\n isUnique: fieldDetails.isUnique,\n isArray: fieldDetails.isArray,\n });\n\n console.log(` ✓ Added: ${answers.name}: ${fieldDetails.type}\\n`);\n }\n\n return fields;\n}\n","export interface FieldDefinition {\n name: string;\n type: FieldType;\n isOptional: boolean;\n isArray: boolean;\n isUnique: boolean;\n defaultValue?: string;\n relation?: {\n model: string;\n type: 'one-to-one' | 'one-to-many' | 'many-to-one';\n };\n}\n\nexport type FieldType =\n | 'string'\n | 'number'\n | 'boolean'\n | 'date'\n | 'datetime'\n | 'text'\n | 'json'\n | 'email'\n | 'url'\n | 'uuid'\n | 'int'\n | 'float'\n | 'decimal'\n | 'enum';\n\n// Map field types to TypeScript types\nexport const tsTypeMap: Record<FieldType, string> = {\n string: 'string',\n number: 'number',\n boolean: 'boolean',\n date: 'Date',\n datetime: 'Date',\n text: 'string',\n json: 'Record<string, unknown>',\n email: 'string',\n url: 'string',\n uuid: 'string',\n int: 'number',\n float: 'number',\n decimal: 'number',\n enum: 'string',\n};\n\n// Map field types to Prisma types\nexport const prismaTypeMap: Record<FieldType, string> = {\n string: 'String',\n number: 'Int',\n boolean: 'Boolean',\n date: 'DateTime',\n datetime: 'DateTime',\n text: 'String',\n json: 'Json',\n email: 'String',\n url: 'String',\n uuid: 'String',\n int: 'Int',\n float: 'Float',\n decimal: 'Decimal',\n enum: 'String',\n};\n\n// Map field types to Zod validators\nexport const zodTypeMap: Record<FieldType, string> = {\n string: 'z.string()',\n number: 'z.number()',\n boolean: 'z.boolean()',\n date: 'z.coerce.date()',\n datetime: 'z.coerce.date()',\n text: 'z.string()',\n json: 'z.record(z.unknown())',\n email: 'z.string().email()',\n url: 'z.string().url()',\n uuid: 'z.string().uuid()',\n int: 'z.number().int()',\n float: 'z.number()',\n decimal: 'z.number()',\n enum: 'z.string()',\n};\n\n// Map field types to Joi validators\nexport const joiTypeMap: Record<FieldType, string> = {\n string: 'Joi.string()',\n number: 'Joi.number()',\n boolean: 'Joi.boolean()',\n date: 'Joi.date()',\n datetime: 'Joi.date()',\n text: 'Joi.string()',\n json: 'Joi.object()',\n email: 'Joi.string().email()',\n url: 'Joi.string().uri()',\n uuid: 'Joi.string().uuid()',\n int: 'Joi.number().integer()',\n float: 'Joi.number()',\n decimal: 'Joi.number()',\n enum: 'Joi.string()',\n};\n\n// Map field types to Yup validators\nexport const yupTypeMap: Record<FieldType, string> = {\n string: 'yup.string()',\n number: 'yup.number()',\n boolean: 'yup.boolean()',\n date: 'yup.date()',\n datetime: 'yup.date()',\n text: 'yup.string()',\n json: 'yup.object()',\n email: 'yup.string().email()',\n url: 'yup.string().url()',\n uuid: 'yup.string().uuid()',\n int: 'yup.number().integer()',\n float: 'yup.number()',\n decimal: 'yup.number()',\n enum: 'yup.string()',\n};\n\n/**\n * Parse field definition string\n * Format: name:type[:modifiers]\n * Examples:\n * - title:string\n * - price:number\n * - email:email:unique\n * - description:text?\n * - tags:string[]\n * - isActive:boolean:default=true\n * - category:relation:Category\n */\nexport function parseField(fieldStr: string): FieldDefinition {\n const parts = fieldStr.split(':');\n let name = parts[0] || '';\n let typeStr = parts[1] || 'string';\n const modifiers = parts.slice(2);\n\n // Check for optional (?)\n const isOptional = name.endsWith('?') || typeStr.endsWith('?');\n name = name.replace('?', '');\n typeStr = typeStr.replace('?', '');\n\n // Check for array ([])\n const isArray = typeStr.endsWith('[]');\n typeStr = typeStr.replace('[]', '');\n\n // Validate type\n const validTypes: FieldType[] = [\n 'string',\n 'number',\n 'boolean',\n 'date',\n 'datetime',\n 'text',\n 'json',\n 'email',\n 'url',\n 'uuid',\n 'int',\n 'float',\n 'decimal',\n 'enum',\n ];\n\n let type: FieldType = 'string';\n if (validTypes.includes(typeStr as FieldType)) {\n type = typeStr as FieldType;\n }\n\n // Parse modifiers\n let isUnique = false;\n let defaultValue: string | undefined;\n let relation: FieldDefinition['relation'];\n\n for (const mod of modifiers) {\n if (mod === 'unique') {\n isUnique = true;\n } else if (mod.startsWith('default=')) {\n defaultValue = mod.replace('default=', '');\n } else if (typeStr === 'relation') {\n relation = {\n model: mod,\n type: 'many-to-one',\n };\n type = 'string'; // Relations use string IDs\n }\n }\n\n return {\n name,\n type,\n isOptional,\n isArray,\n isUnique,\n defaultValue,\n relation,\n };\n}\n\n/**\n * Parse multiple fields from command line\n * Example: \"title:string price:number description:text?\"\n */\nexport function parseFields(fieldsStr: string): FieldDefinition[] {\n if (!fieldsStr) return [];\n\n return fieldsStr.split(/\\s+/).filter(Boolean).map(parseField);\n}\n\n/**\n * Generate TypeScript interface from fields\n */\nexport function generateTypeInterface(\n name: string,\n fields: FieldDefinition[],\n includeBase = true\n): string {\n const lines: string[] = [];\n\n if (includeBase) {\n lines.push(`import type { BaseEntity } from '../../types/index.js';`);\n lines.push('');\n lines.push(`export interface ${name} extends BaseEntity {`);\n } else {\n lines.push(`export interface ${name} {`);\n }\n\n for (const field of fields) {\n const tsType = tsTypeMap[field.type];\n const arrayMark = field.isArray ? '[]' : '';\n const optionalMark = field.isOptional ? '?' : '';\n lines.push(` ${field.name}${optionalMark}: ${tsType}${arrayMark};`);\n }\n\n lines.push('}');\n\n return lines.join('\\n');\n}\n\n/**\n * Generate Zod schema from fields\n */\nexport function generateZodSchema(\n name: string,\n fields: FieldDefinition[],\n schemaType: 'create' | 'update' = 'create'\n): string {\n const lines: string[] = [];\n\n lines.push(`export const ${schemaType}${name}Schema = z.object({`);\n\n for (const field of fields) {\n let validator = zodTypeMap[field.type];\n\n if (field.isArray) {\n validator = `z.array(${validator})`;\n }\n\n if (field.isOptional || schemaType === 'update') {\n validator += '.optional()';\n }\n\n if (field.defaultValue && schemaType === 'create') {\n validator += `.default(${field.defaultValue})`;\n }\n\n lines.push(` ${field.name}: ${validator},`);\n }\n\n lines.push('});');\n\n return lines.join('\\n');\n}\n\n/**\n * Generate Prisma model from fields\n */\nexport function generatePrismaModel(\n modelName: string,\n tableName: string,\n fields: FieldDefinition[]\n): string {\n const lines: string[] = [];\n\n lines.push(`model ${modelName} {`);\n lines.push(' id String @id @default(uuid())');\n\n for (const field of fields) {\n const prismaType = prismaTypeMap[field.type];\n const optionalMark = field.isOptional ? '?' : '';\n const annotations: string[] = [];\n\n if (field.isUnique) {\n annotations.push('@unique');\n }\n\n if (field.defaultValue) {\n annotations.push(`@default(${field.defaultValue})`);\n }\n\n if (field.type === 'text') {\n annotations.push('@db.Text');\n }\n\n const annotationStr = annotations.length > 0 ? ' ' + annotations.join(' ') : '';\n lines.push(` ${field.name.padEnd(11)} ${prismaType}${optionalMark}${annotationStr}`);\n }\n\n lines.push('');\n lines.push(' createdAt DateTime @default(now())');\n lines.push(' updatedAt DateTime @updatedAt');\n lines.push('');\n\n // Add indexes for unique fields\n const uniqueFields = fields.filter((f) => f.isUnique);\n for (const field of uniqueFields) {\n lines.push(` @@index([${field.name}])`);\n }\n\n lines.push(` @@map(\"${tableName}\")`);\n lines.push('}');\n\n return lines.join('\\n');\n}\n","/* eslint-disable no-console */\nimport chalk from 'chalk';\n\nexport interface ErrorSuggestion {\n message: string;\n suggestions: string[];\n docsLink?: string;\n}\n\nexport class ServCraftError extends Error {\n suggestions: string[];\n docsLink?: string;\n\n constructor(message: string, suggestions: string[] = [], docsLink?: string) {\n super(message);\n this.name = 'ServCraftError';\n this.suggestions = suggestions;\n this.docsLink = docsLink;\n }\n}\n\n// Common error types with suggestions\nexport const ErrorTypes = {\n MODULE_NOT_FOUND: (moduleName: string): ServCraftError =>\n new ServCraftError(\n `Module \"${moduleName}\" not found`,\n [\n `Run ${chalk.cyan('servcraft list')} to see available modules`,\n `Check the spelling of the module name`,\n `Visit ${chalk.blue('https://github.com/Le-Sourcier/servcraft#modules')} for module list`,\n ],\n 'https://github.com/Le-Sourcier/servcraft#add-pre-built-modules'\n ),\n\n MODULE_ALREADY_EXISTS: (moduleName: string): ServCraftError =>\n new ServCraftError(`Module \"${moduleName}\" already exists`, [\n `Use ${chalk.cyan('servcraft add ' + moduleName + ' --force')} to overwrite`,\n `Use ${chalk.cyan('servcraft add ' + moduleName + ' --update')} to update`,\n `Use ${chalk.cyan('servcraft add ' + moduleName + ' --skip-existing')} to skip`,\n ]),\n\n NOT_IN_PROJECT: (): ServCraftError =>\n new ServCraftError(\n 'Not in a ServCraft project directory',\n [\n `Run ${chalk.cyan('servcraft init')} to create a new project`,\n `Navigate to your ServCraft project directory`,\n `Check if ${chalk.yellow('package.json')} exists`,\n ],\n 'https://github.com/Le-Sourcier/servcraft#initialize-project'\n ),\n\n FILE_ALREADY_EXISTS: (fileName: string): ServCraftError =>\n new ServCraftError(`File \"${fileName}\" already exists`, [\n `Use ${chalk.cyan('--force')} flag to overwrite`,\n `Choose a different name`,\n `Delete the existing file first`,\n ]),\n\n INVALID_DATABASE: (database: string): ServCraftError =>\n new ServCraftError(`Invalid database type: \"${database}\"`, [\n `Valid options: ${chalk.cyan('postgresql, mysql, sqlite, mongodb, none')}`,\n `Use ${chalk.cyan('servcraft init --db postgresql')} for PostgreSQL`,\n ]),\n\n INVALID_VALIDATOR: (validator: string): ServCraftError =>\n new ServCraftError(`Invalid validator type: \"${validator}\"`, [\n `Valid options: ${chalk.cyan('zod, joi, yup')}`,\n `Default is ${chalk.cyan('zod')}`,\n ]),\n\n MISSING_DEPENDENCY: (dependency: string, command: string): ServCraftError =>\n new ServCraftError(`Missing dependency: \"${dependency}\"`, [\n `Run ${chalk.cyan(command)} to install`,\n `Check your ${chalk.yellow('package.json')}`,\n ]),\n\n INVALID_FIELD_FORMAT: (field: string): ServCraftError =>\n new ServCraftError(`Invalid field format: \"${field}\"`, [\n `Expected format: ${chalk.cyan('name:type')}`,\n `Example: ${chalk.cyan('name:string age:number isActive:boolean')}`,\n `Supported types: string, number, boolean, date`,\n ]),\n\n GIT_NOT_INITIALIZED: (): ServCraftError =>\n new ServCraftError('Git repository not initialized', [\n `Run ${chalk.cyan('git init')} to initialize git`,\n `This is required for some ServCraft features`,\n ]),\n};\n\n// Display error with suggestions\nexport function displayError(error: Error | ServCraftError): void {\n console.error('\\n' + chalk.red.bold('✗ Error: ') + chalk.red(error.message));\n\n if (error instanceof ServCraftError) {\n if (error.suggestions.length > 0) {\n console.log('\\n' + chalk.yellow.bold('💡 Suggestions:'));\n error.suggestions.forEach((suggestion) => {\n console.log(chalk.yellow(' • ') + suggestion);\n });\n }\n\n if (error.docsLink) {\n console.log(\n '\\n' + chalk.blue.bold('📚 Documentation: ') + chalk.blue.underline(error.docsLink)\n );\n }\n }\n\n console.log(); // Empty line for spacing\n}\n\n// Handle common Node.js errors\nexport function handleSystemError(err: NodeJS.ErrnoException): ServCraftError {\n switch (err.code) {\n case 'ENOENT':\n return new ServCraftError(`File or directory not found: ${err.path}`, [\n `Check if the path exists`,\n `Create the directory first`,\n ]);\n\n case 'EACCES':\n case 'EPERM':\n return new ServCraftError(`Permission denied: ${err.path}`, [\n `Check file permissions`,\n `Try running with elevated privileges (not recommended)`,\n `Change ownership of the directory`,\n ]);\n\n case 'EEXIST':\n return new ServCraftError(`File or directory already exists: ${err.path}`, [\n `Use a different name`,\n `Remove the existing file first`,\n `Use ${chalk.cyan('--force')} to overwrite`,\n ]);\n\n case 'ENOTDIR':\n return new ServCraftError(`Not a directory: ${err.path}`, [\n `Check the path`,\n `A file exists where a directory is expected`,\n ]);\n\n case 'EISDIR':\n return new ServCraftError(`Is a directory: ${err.path}`, [\n `Cannot perform this operation on a directory`,\n `Did you mean to target a file?`,\n ]);\n\n default:\n return new ServCraftError(err.message, [\n `Check system error code: ${err.code}`,\n `Review the error details above`,\n ]);\n }\n}\n\n// Validate project structure\nexport function validateProject(): ServCraftError | null {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const fs = require('fs');\n\n if (!fs.existsSync('package.json')) {\n return ErrorTypes.NOT_IN_PROJECT();\n }\n\n const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf-8'));\n\n if (!packageJson.dependencies?.fastify) {\n return new ServCraftError('This does not appear to be a ServCraft project', [\n `ServCraft projects require Fastify`,\n `Run ${chalk.cyan('servcraft init')} to create a new project`,\n ]);\n }\n\n return null;\n } catch {\n return new ServCraftError('Failed to validate project', [\n `Ensure you are in the project root directory`,\n `Check if ${chalk.yellow('package.json')} is valid`,\n ]);\n }\n}\n","export function controllerTemplate(name: string, pascalName: string, camelName: string): string {\n return `import type { FastifyRequest, FastifyReply } from 'fastify';\nimport type { ${pascalName}Service } from './${name}.service.js';\nimport { create${pascalName}Schema, update${pascalName}Schema, ${camelName}QuerySchema } from './${name}.schemas.js';\nimport { success, created, noContent } from '../../utils/response.js';\nimport { parsePaginationParams } from '../../utils/pagination.js';\nimport { validateBody, validateQuery } from '../validation/validator.js';\n\nexport class ${pascalName}Controller {\n constructor(private ${camelName}Service: ${pascalName}Service) {}\n\n async list(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const query = validateQuery(${camelName}QuerySchema, request.query);\n const pagination = parsePaginationParams(query);\n const filters = {\n search: query.search,\n };\n\n const result = await this.${camelName}Service.findMany(pagination, filters);\n success(reply, result);\n }\n\n async getById(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n ): Promise<void> {\n const item = await this.${camelName}Service.findById(request.params.id);\n\n if (!item) {\n return reply.status(404).send({\n success: false,\n message: '${pascalName} not found',\n });\n }\n\n success(reply, item);\n }\n\n async create(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const data = validateBody(create${pascalName}Schema, request.body);\n const item = await this.${camelName}Service.create(data);\n created(reply, item);\n }\n\n async update(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n ): Promise<void> {\n const data = validateBody(update${pascalName}Schema, request.body);\n const item = await this.${camelName}Service.update(request.params.id, data);\n success(reply, item);\n }\n\n async delete(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n ): Promise<void> {\n await this.${camelName}Service.delete(request.params.id);\n noContent(reply);\n }\n}\n\nexport function create${pascalName}Controller(${camelName}Service: ${pascalName}Service): ${pascalName}Controller {\n return new ${pascalName}Controller(${camelName}Service);\n}\n`;\n}\n","export function serviceTemplate(name: string, pascalName: string, camelName: string): string {\n return `import type { PaginatedResult, PaginationParams } from '../../types/index.js';\nimport { NotFoundError, ConflictError } from '../../utils/errors.js';\nimport { ${pascalName}Repository, create${pascalName}Repository } from './${name}.repository.js';\nimport type { ${pascalName}, Create${pascalName}Data, Update${pascalName}Data, ${pascalName}Filters } from './${name}.types.js';\nimport { logger } from '../../core/logger.js';\n\nexport class ${pascalName}Service {\n constructor(private repository: ${pascalName}Repository) {}\n\n async findById(id: string): Promise<${pascalName} | null> {\n return this.repository.findById(id);\n }\n\n async findMany(\n params: PaginationParams,\n filters?: ${pascalName}Filters\n ): Promise<PaginatedResult<${pascalName}>> {\n return this.repository.findMany(params, filters);\n }\n\n async create(data: Create${pascalName}Data): Promise<${pascalName}> {\n const item = await this.repository.create(data);\n logger.info({ ${camelName}Id: item.id }, '${pascalName} created');\n return item;\n }\n\n async update(id: string, data: Update${pascalName}Data): Promise<${pascalName}> {\n const existing = await this.repository.findById(id);\n if (!existing) {\n throw new NotFoundError('${pascalName}');\n }\n\n const updated = await this.repository.update(id, data);\n if (!updated) {\n throw new NotFoundError('${pascalName}');\n }\n\n logger.info({ ${camelName}Id: id }, '${pascalName} updated');\n return updated;\n }\n\n async delete(id: string): Promise<void> {\n const existing = await this.repository.findById(id);\n if (!existing) {\n throw new NotFoundError('${pascalName}');\n }\n\n await this.repository.delete(id);\n logger.info({ ${camelName}Id: id }, '${pascalName} deleted');\n }\n}\n\nexport function create${pascalName}Service(repository?: ${pascalName}Repository): ${pascalName}Service {\n return new ${pascalName}Service(repository || create${pascalName}Repository());\n}\n`;\n}\n","export function repositoryTemplate(\n name: string,\n pascalName: string,\n camelName: string,\n pluralName: string\n): string {\n return `import { randomUUID } from 'crypto';\nimport type { PaginatedResult, PaginationParams } from '../../types/index.js';\nimport { createPaginatedResult, getSkip } from '../../utils/pagination.js';\nimport type { ${pascalName}, Create${pascalName}Data, Update${pascalName}Data, ${pascalName}Filters } from './${name}.types.js';\n\n// In-memory storage (will be replaced by Prisma in production)\nconst ${pluralName} = new Map<string, ${pascalName}>();\n\nexport class ${pascalName}Repository {\n async findById(id: string): Promise<${pascalName} | null> {\n return ${pluralName}.get(id) || null;\n }\n\n async findMany(\n params: PaginationParams,\n filters?: ${pascalName}Filters\n ): Promise<PaginatedResult<${pascalName}>> {\n let items = Array.from(${pluralName}.values());\n\n // Apply filters\n if (filters?.search) {\n const search = filters.search.toLowerCase();\n items = items.filter((item) =>\n JSON.stringify(item).toLowerCase().includes(search)\n );\n }\n\n // Sort\n if (params.sortBy) {\n const sortKey = params.sortBy as keyof ${pascalName};\n items.sort((a, b) => {\n const aVal = a[sortKey];\n const bVal = b[sortKey];\n if (aVal === undefined || bVal === undefined) return 0;\n if (aVal < bVal) return params.sortOrder === 'desc' ? 1 : -1;\n if (aVal > bVal) return params.sortOrder === 'desc' ? -1 : 1;\n return 0;\n });\n }\n\n const total = items.length;\n const skip = getSkip(params);\n const data = items.slice(skip, skip + params.limit);\n\n return createPaginatedResult(data, total, params);\n }\n\n async create(data: Create${pascalName}Data): Promise<${pascalName}> {\n const now = new Date();\n const item: ${pascalName} = {\n id: randomUUID(),\n ...data,\n createdAt: now,\n updatedAt: now,\n };\n\n ${pluralName}.set(item.id, item);\n return item;\n }\n\n async update(id: string, data: Update${pascalName}Data): Promise<${pascalName} | null> {\n const item = ${pluralName}.get(id);\n if (!item) return null;\n\n const updated: ${pascalName} = {\n ...item,\n ...data,\n updatedAt: new Date(),\n };\n\n ${pluralName}.set(id, updated);\n return updated;\n }\n\n async delete(id: string): Promise<boolean> {\n return ${pluralName}.delete(id);\n }\n\n async count(filters?: ${pascalName}Filters): Promise<number> {\n if (!filters) return ${pluralName}.size;\n\n let count = 0;\n for (const item of ${pluralName}.values()) {\n if (filters.search) {\n const search = filters.search.toLowerCase();\n if (!JSON.stringify(item).toLowerCase().includes(search)) continue;\n }\n count++;\n }\n return count;\n }\n\n // Clear all (for testing)\n async clear(): Promise<void> {\n ${pluralName}.clear();\n }\n}\n\nexport function create${pascalName}Repository(): ${pascalName}Repository {\n return new ${pascalName}Repository();\n}\n`;\n}\n","export function typesTemplate(name: string, pascalName: string): string {\n return `import type { BaseEntity } from '../../types/index.js';\n\nexport interface ${pascalName} extends BaseEntity {\n // Add your ${pascalName} specific fields here\n name: string;\n description?: string;\n // status?: string;\n // metadata?: Record<string, unknown>;\n}\n\nexport interface Create${pascalName}Data {\n name: string;\n description?: string;\n}\n\nexport interface Update${pascalName}Data {\n name?: string;\n description?: string;\n}\n\nexport interface ${pascalName}Filters {\n search?: string;\n // Add more filters as needed\n}\n`;\n}\n","export function schemasTemplate(name: string, pascalName: string, camelName: string): string {\n return `import { z } from 'zod';\n\nexport const create${pascalName}Schema = z.object({\n name: z.string().min(1, 'Name is required').max(255),\n description: z.string().max(1000).optional(),\n});\n\nexport const update${pascalName}Schema = z.object({\n name: z.string().min(1).max(255).optional(),\n description: z.string().max(1000).optional(),\n});\n\nexport const ${camelName}QuerySchema = z.object({\n page: z.string().transform(Number).optional(),\n limit: z.string().transform(Number).optional(),\n sortBy: z.string().optional(),\n sortOrder: z.enum(['asc', 'desc']).optional(),\n search: z.string().optional(),\n});\n\nexport type Create${pascalName}Input = z.infer<typeof create${pascalName}Schema>;\nexport type Update${pascalName}Input = z.infer<typeof update${pascalName}Schema>;\nexport type ${pascalName}QueryInput = z.infer<typeof ${camelName}QuerySchema>;\n`;\n}\n","export function routesTemplate(\n name: string,\n pascalName: string,\n camelName: string,\n pluralName: string\n): string {\n return `import type { FastifyInstance } from 'fastify';\nimport type { ${pascalName}Controller } from './${name}.controller.js';\nimport type { AuthService } from '../auth/auth.service.js';\nimport { createAuthMiddleware, createRoleMiddleware } from '../auth/auth.middleware.js';\n\nexport function register${pascalName}Routes(\n app: FastifyInstance,\n controller: ${pascalName}Controller,\n authService: AuthService\n): void {\n const authenticate = createAuthMiddleware(authService);\n const isAdmin = createRoleMiddleware(['admin', 'super_admin']);\n\n // Public routes (if any)\n // app.get('/${pluralName}/public', controller.publicList.bind(controller));\n\n // Protected routes\n app.get(\n '/${pluralName}',\n { preHandler: [authenticate] },\n controller.list.bind(controller)\n );\n\n app.get(\n '/${pluralName}/:id',\n { preHandler: [authenticate] },\n controller.getById.bind(controller)\n );\n\n app.post(\n '/${pluralName}',\n { preHandler: [authenticate] },\n controller.create.bind(controller)\n );\n\n app.patch(\n '/${pluralName}/:id',\n { preHandler: [authenticate] },\n controller.update.bind(controller)\n );\n\n app.delete(\n '/${pluralName}/:id',\n { preHandler: [authenticate, isAdmin] },\n controller.delete.bind(controller)\n );\n}\n`;\n}\n","export function moduleIndexTemplate(name: string, pascalName: string, camelName: string): string {\n return `import type { FastifyInstance } from 'fastify';\nimport { logger } from '../../core/logger.js';\nimport { ${pascalName}Service, create${pascalName}Service } from './${name}.service.js';\nimport { ${pascalName}Controller, create${pascalName}Controller } from './${name}.controller.js';\nimport { ${pascalName}Repository, create${pascalName}Repository } from './${name}.repository.js';\nimport { register${pascalName}Routes } from './${name}.routes.js';\nimport type { AuthService } from '../auth/auth.service.js';\n\nexport async function register${pascalName}Module(\n app: FastifyInstance,\n authService: AuthService\n): Promise<void> {\n // Create repository and service\n const repository = create${pascalName}Repository();\n const ${camelName}Service = create${pascalName}Service(repository);\n\n // Create controller\n const ${camelName}Controller = create${pascalName}Controller(${camelName}Service);\n\n // Register routes\n register${pascalName}Routes(app, ${camelName}Controller, authService);\n\n logger.info('${pascalName} module registered');\n}\n\nexport { ${pascalName}Service, create${pascalName}Service } from './${name}.service.js';\nexport { ${pascalName}Controller, create${pascalName}Controller } from './${name}.controller.js';\nexport { ${pascalName}Repository, create${pascalName}Repository } from './${name}.repository.js';\nexport * from './${name}.types.js';\nexport * from './${name}.schemas.js';\n`;\n}\n","export function prismaModelTemplate(name: string, pascalName: string, tableName: string): string {\n return `\n// Add this model to your prisma/schema.prisma file\n\nmodel ${pascalName} {\n id String @id @default(uuid())\n name String\n description String?\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([name])\n @@map(\"${tableName}\")\n}\n`;\n}\n","import type { FieldDefinition } from '../utils/field-parser.js';\nimport { tsTypeMap } from '../utils/field-parser.js';\n\nexport function dynamicTypesTemplate(\n name: string,\n pascalName: string,\n fields: FieldDefinition[]\n): string {\n const fieldLines = fields.map((field) => {\n const tsType = tsTypeMap[field.type];\n const arrayMark = field.isArray ? '[]' : '';\n const optionalMark = field.isOptional ? '?' : '';\n return ` ${field.name}${optionalMark}: ${tsType}${arrayMark};`;\n });\n\n const createFieldLines = fields\n .filter((f) => !f.isOptional)\n .map((field) => {\n const tsType = tsTypeMap[field.type];\n const arrayMark = field.isArray ? '[]' : '';\n return ` ${field.name}: ${tsType}${arrayMark};`;\n });\n\n const createOptionalLines = fields\n .filter((f) => f.isOptional)\n .map((field) => {\n const tsType = tsTypeMap[field.type];\n const arrayMark = field.isArray ? '[]' : '';\n return ` ${field.name}?: ${tsType}${arrayMark};`;\n });\n\n const updateFieldLines = fields.map((field) => {\n const tsType = tsTypeMap[field.type];\n const arrayMark = field.isArray ? '[]' : '';\n return ` ${field.name}?: ${tsType}${arrayMark};`;\n });\n\n return `import type { BaseEntity } from '../../types/index.js';\n\nexport interface ${pascalName} extends BaseEntity {\n${fieldLines.join('\\n')}\n}\n\nexport interface Create${pascalName}Data {\n${[...createFieldLines, ...createOptionalLines].join('\\n')}\n}\n\nexport interface Update${pascalName}Data {\n${updateFieldLines.join('\\n')}\n}\n\nexport interface ${pascalName}Filters {\n search?: string;\n${fields\n .filter((f) => ['string', 'enum', 'boolean'].includes(f.type))\n .map((f) => ` ${f.name}?: ${tsTypeMap[f.type]};`)\n .join('\\n')}\n}\n`;\n}\n","import type { FieldDefinition } from '../utils/field-parser.js';\nimport { zodTypeMap, joiTypeMap, yupTypeMap } from '../utils/field-parser.js';\n\nexport type ValidatorType = 'zod' | 'joi' | 'yup';\n\nexport function dynamicSchemasTemplate(\n name: string,\n pascalName: string,\n camelName: string,\n fields: FieldDefinition[],\n validator: ValidatorType = 'zod'\n): string {\n switch (validator) {\n case 'joi':\n return generateJoiSchemas(pascalName, camelName, fields);\n case 'yup':\n return generateYupSchemas(pascalName, camelName, fields);\n default:\n return generateZodSchemas(pascalName, camelName, fields);\n }\n}\n\nfunction generateZodSchemas(\n pascalName: string,\n camelName: string,\n fields: FieldDefinition[]\n): string {\n const createFields = fields.map((field) => {\n let validator = zodTypeMap[field.type];\n\n if (field.isArray) {\n validator = `z.array(${validator})`;\n }\n\n if (field.isOptional) {\n validator += '.optional()';\n }\n\n if (field.defaultValue) {\n validator += `.default(${field.defaultValue})`;\n }\n\n // Add extra validations based on type\n if (field.type === 'string' && !field.isOptional) {\n validator = validator.replace('z.string()', 'z.string().min(1)');\n }\n\n return ` ${field.name}: ${validator},`;\n });\n\n const updateFields = fields.map((field) => {\n let validator = zodTypeMap[field.type];\n\n if (field.isArray) {\n validator = `z.array(${validator})`;\n }\n\n validator += '.optional()';\n\n return ` ${field.name}: ${validator},`;\n });\n\n return `import { z } from 'zod';\n\nexport const create${pascalName}Schema = z.object({\n${createFields.join('\\n')}\n});\n\nexport const update${pascalName}Schema = z.object({\n${updateFields.join('\\n')}\n});\n\nexport const ${camelName}QuerySchema = z.object({\n page: z.string().transform(Number).optional(),\n limit: z.string().transform(Number).optional(),\n sortBy: z.string().optional(),\n sortOrder: z.enum(['asc', 'desc']).optional(),\n search: z.string().optional(),\n});\n\nexport type Create${pascalName}Input = z.infer<typeof create${pascalName}Schema>;\nexport type Update${pascalName}Input = z.infer<typeof update${pascalName}Schema>;\nexport type ${pascalName}QueryInput = z.infer<typeof ${camelName}QuerySchema>;\n`;\n}\n\nfunction generateJoiSchemas(\n pascalName: string,\n camelName: string,\n fields: FieldDefinition[]\n): string {\n const createFields = fields.map((field) => {\n let validator = joiTypeMap[field.type];\n\n if (field.isArray) {\n validator = `Joi.array().items(${validator})`;\n }\n\n if (!field.isOptional) {\n validator += '.required()';\n }\n\n if (field.defaultValue) {\n validator += `.default(${field.defaultValue})`;\n }\n\n return ` ${field.name}: ${validator},`;\n });\n\n const updateFields = fields.map((field) => {\n let validator = joiTypeMap[field.type];\n\n if (field.isArray) {\n validator = `Joi.array().items(${validator})`;\n }\n\n return ` ${field.name}: ${validator},`;\n });\n\n return `import Joi from 'joi';\n\nexport const create${pascalName}Schema = Joi.object({\n${createFields.join('\\n')}\n});\n\nexport const update${pascalName}Schema = Joi.object({\n${updateFields.join('\\n')}\n});\n\nexport const ${camelName}QuerySchema = Joi.object({\n page: Joi.number().integer().min(1),\n limit: Joi.number().integer().min(1).max(100),\n sortBy: Joi.string(),\n sortOrder: Joi.string().valid('asc', 'desc'),\n search: Joi.string(),\n});\n\nexport type Create${pascalName}Input = {\n${fields.map((f) => ` ${f.name}${f.isOptional ? '?' : ''}: ${getJsType(f)};`).join('\\n')}\n};\n\nexport type Update${pascalName}Input = Partial<Create${pascalName}Input>;\nexport type ${pascalName}QueryInput = {\n page?: number;\n limit?: number;\n sortBy?: string;\n sortOrder?: 'asc' | 'desc';\n search?: string;\n};\n`;\n}\n\nfunction generateYupSchemas(\n pascalName: string,\n camelName: string,\n fields: FieldDefinition[]\n): string {\n const createFields = fields.map((field) => {\n let validator = yupTypeMap[field.type];\n\n if (field.isArray) {\n validator = `yup.array().of(${validator})`;\n }\n\n if (!field.isOptional) {\n validator += '.required()';\n }\n\n if (field.defaultValue) {\n validator += `.default(${field.defaultValue})`;\n }\n\n return ` ${field.name}: ${validator},`;\n });\n\n const updateFields = fields.map((field) => {\n let validator = yupTypeMap[field.type];\n\n if (field.isArray) {\n validator = `yup.array().of(${validator})`;\n }\n\n validator += '.optional()';\n\n return ` ${field.name}: ${validator},`;\n });\n\n return `import * as yup from 'yup';\n\nexport const create${pascalName}Schema = yup.object({\n${createFields.join('\\n')}\n});\n\nexport const update${pascalName}Schema = yup.object({\n${updateFields.join('\\n')}\n});\n\nexport const ${camelName}QuerySchema = yup.object({\n page: yup.number().integer().min(1),\n limit: yup.number().integer().min(1).max(100),\n sortBy: yup.string(),\n sortOrder: yup.string().oneOf(['asc', 'desc']),\n search: yup.string(),\n});\n\nexport type Create${pascalName}Input = yup.InferType<typeof create${pascalName}Schema>;\nexport type Update${pascalName}Input = yup.InferType<typeof update${pascalName}Schema>;\nexport type ${pascalName}QueryInput = yup.InferType<typeof ${camelName}QuerySchema>;\n`;\n}\n\nfunction getJsType(field: FieldDefinition): string {\n const typeMap: Record<string, string> = {\n string: 'string',\n number: 'number',\n boolean: 'boolean',\n date: 'Date',\n datetime: 'Date',\n text: 'string',\n json: 'Record<string, unknown>',\n email: 'string',\n url: 'string',\n uuid: 'string',\n int: 'number',\n float: 'number',\n decimal: 'number',\n enum: 'string',\n };\n\n const baseType = typeMap[field.type] || 'unknown';\n return field.isArray ? `${baseType}[]` : baseType;\n}\n","import type { FieldDefinition } from '../utils/field-parser.js';\nimport { prismaTypeMap } from '../utils/field-parser.js';\n\nexport function dynamicPrismaTemplate(\n modelName: string,\n tableName: string,\n fields: FieldDefinition[]\n): string {\n const fieldLines: string[] = [];\n\n for (const field of fields) {\n const prismaType = prismaTypeMap[field.type];\n const optionalMark = field.isOptional ? '?' : '';\n const arrayMark = field.isArray ? '[]' : '';\n const annotations: string[] = [];\n\n if (field.isUnique) {\n annotations.push('@unique');\n }\n\n if (field.defaultValue !== undefined) {\n // Handle different default value types\n if (field.type === 'boolean') {\n annotations.push(`@default(${field.defaultValue})`);\n } else if (field.type === 'number' || field.type === 'int' || field.type === 'float') {\n annotations.push(`@default(${field.defaultValue})`);\n } else {\n annotations.push(`@default(\"${field.defaultValue}\")`);\n }\n }\n\n // Database-specific annotations\n if (field.type === 'text') {\n annotations.push('@db.Text');\n }\n\n if (field.type === 'decimal') {\n annotations.push('@db.Decimal(10, 2)');\n }\n\n const annotationStr = annotations.length > 0 ? ' ' + annotations.join(' ') : '';\n const typePart = `${prismaType}${optionalMark}${arrayMark}`;\n\n fieldLines.push(` ${field.name.padEnd(15)} ${typePart.padEnd(12)}${annotationStr}`);\n }\n\n // Generate indexes\n const indexLines: string[] = [];\n\n // Index for unique fields\n const uniqueFields = fields.filter((f) => f.isUnique);\n for (const field of uniqueFields) {\n indexLines.push(` @@index([${field.name}])`);\n }\n\n // Index for common search fields\n const searchableFields = fields.filter(\n (f) => ['string', 'email'].includes(f.type) && !f.isUnique\n );\n if (searchableFields.length > 0) {\n const firstSearchable = searchableFields[0];\n if (firstSearchable) {\n indexLines.push(` @@index([${firstSearchable.name}])`);\n }\n }\n\n return `\n// ==========================================\n// Add this model to your prisma/schema.prisma file\n// ==========================================\n\nmodel ${modelName} {\n id String @id @default(uuid())\n\n${fieldLines.join('\\n')}\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n${indexLines.join('\\n')}\n @@map(\"${tableName}\")\n}\n\n// ==========================================\n// After adding the model, run:\n// npm run db:migrate -- --name add_${tableName}\n// ==========================================\n`;\n}\n","export function controllerTestTemplate(\n name: string,\n pascalName: string,\n camelName: string\n): string {\n return `import { describe, it, expect, beforeAll, afterAll } from 'vitest';\nimport { build } from '../../app.js';\nimport { FastifyInstance } from 'fastify';\n\ndescribe('${pascalName}Controller', () => {\n let app: FastifyInstance;\n\n beforeAll(async () => {\n app = await build();\n await app.ready();\n });\n\n afterAll(async () => {\n await app.close();\n });\n\n describe('GET /${name}', () => {\n it('should return list of ${name}', async () => {\n const response = await app.inject({\n method: 'GET',\n url: '/${name}',\n });\n\n expect(response.statusCode).toBe(200);\n expect(response.json()).toHaveProperty('data');\n });\n });\n\n describe('GET /${name}/:id', () => {\n it('should return a single ${camelName}', async () => {\n // TODO: Create test ${camelName} first\n const response = await app.inject({\n method: 'GET',\n url: '/${name}/1',\n });\n\n expect(response.statusCode).toBe(200);\n expect(response.json()).toHaveProperty('data');\n });\n\n it('should return 404 for non-existent ${camelName}', async () => {\n const response = await app.inject({\n method: 'GET',\n url: '/${name}/999999',\n });\n\n expect(response.statusCode).toBe(404);\n });\n });\n\n describe('POST /${name}', () => {\n it('should create a new ${camelName}', async () => {\n const response = await app.inject({\n method: 'POST',\n url: '/${name}',\n payload: {\n // TODO: Add required fields\n },\n });\n\n expect(response.statusCode).toBe(201);\n expect(response.json()).toHaveProperty('data');\n });\n\n it('should return 400 for invalid data', async () => {\n const response = await app.inject({\n method: 'POST',\n url: '/${name}',\n payload: {},\n });\n\n expect(response.statusCode).toBe(400);\n });\n });\n\n describe('PUT /${name}/:id', () => {\n it('should update a ${camelName}', async () => {\n // TODO: Create test ${camelName} first\n const response = await app.inject({\n method: 'PUT',\n url: '/${name}/1',\n payload: {\n // TODO: Add fields to update\n },\n });\n\n expect(response.statusCode).toBe(200);\n expect(response.json()).toHaveProperty('data');\n });\n });\n\n describe('DELETE /${name}/:id', () => {\n it('should delete a ${camelName}', async () => {\n // TODO: Create test ${camelName} first\n const response = await app.inject({\n method: 'DELETE',\n url: '/${name}/1',\n });\n\n expect(response.statusCode).toBe(204);\n });\n });\n});\n`;\n}\n","export function serviceTestTemplate(name: string, pascalName: string, camelName: string): string {\n return `import { describe, it, expect, beforeEach } from 'vitest';\nimport { ${pascalName}Service } from '../${name}.service.js';\n\ndescribe('${pascalName}Service', () => {\n let service: ${pascalName}Service;\n\n beforeEach(() => {\n service = new ${pascalName}Service();\n });\n\n describe('getAll', () => {\n it('should return all ${name}', async () => {\n const result = await service.getAll();\n\n expect(result).toBeDefined();\n expect(Array.isArray(result)).toBe(true);\n });\n\n it('should apply pagination', async () => {\n const result = await service.getAll({ page: 1, limit: 10 });\n\n expect(result).toBeDefined();\n expect(result.length).toBeLessThanOrEqual(10);\n });\n });\n\n describe('getById', () => {\n it('should return a ${camelName} by id', async () => {\n // TODO: Create test ${camelName} first\n const id = '1';\n const result = await service.getById(id);\n\n expect(result).toBeDefined();\n expect(result.id).toBe(id);\n });\n\n it('should return null for non-existent id', async () => {\n const result = await service.getById('999999');\n\n expect(result).toBeNull();\n });\n });\n\n describe('create', () => {\n it('should create a new ${camelName}', async () => {\n const data = {\n // TODO: Add required fields\n };\n\n const result = await service.create(data);\n\n expect(result).toBeDefined();\n expect(result.id).toBeDefined();\n });\n\n it('should throw error for invalid data', async () => {\n await expect(service.create({} as any)).rejects.toThrow();\n });\n });\n\n describe('update', () => {\n it('should update a ${camelName}', async () => {\n // TODO: Create test ${camelName} first\n const id = '1';\n const updates = {\n // TODO: Add fields to update\n };\n\n const result = await service.update(id, updates);\n\n expect(result).toBeDefined();\n expect(result.id).toBe(id);\n });\n\n it('should return null for non-existent id', async () => {\n const result = await service.update('999999', {});\n\n expect(result).toBeNull();\n });\n });\n\n describe('delete', () => {\n it('should delete a ${camelName}', async () => {\n // TODO: Create test ${camelName} first\n const id = '1';\n const result = await service.delete(id);\n\n expect(result).toBe(true);\n });\n\n it('should return false for non-existent id', async () => {\n const result = await service.delete('999999');\n\n expect(result).toBe(false);\n });\n });\n});\n`;\n}\n","export function integrationTestTemplate(\n name: string,\n pascalName: string,\n camelName: string\n): string {\n return `import { describe, it, expect, beforeAll, afterAll, beforeEach } from 'vitest';\nimport { build } from '../../app.js';\nimport { FastifyInstance } from 'fastify';\nimport { prisma } from '../../lib/prisma.js';\n\ndescribe('${pascalName} Integration Tests', () => {\n let app: FastifyInstance;\n\n beforeAll(async () => {\n app = await build();\n await app.ready();\n });\n\n afterAll(async () => {\n await app.close();\n await prisma.$disconnect();\n });\n\n beforeEach(async () => {\n // Clean up test data\n // await prisma.${camelName}.deleteMany();\n });\n\n describe('Full CRUD workflow', () => {\n it('should create, read, update, and delete a ${camelName}', async () => {\n // Create\n const createResponse = await app.inject({\n method: 'POST',\n url: '/${name}',\n payload: {\n // TODO: Add required fields\n },\n });\n\n expect(createResponse.statusCode).toBe(201);\n const created = createResponse.json().data;\n expect(created.id).toBeDefined();\n\n // Read\n const readResponse = await app.inject({\n method: 'GET',\n url: \\`/${name}/\\${created.id}\\`,\n });\n\n expect(readResponse.statusCode).toBe(200);\n const read = readResponse.json().data;\n expect(read.id).toBe(created.id);\n\n // Update\n const updateResponse = await app.inject({\n method: 'PUT',\n url: \\`/${name}/\\${created.id}\\`,\n payload: {\n // TODO: Add fields to update\n },\n });\n\n expect(updateResponse.statusCode).toBe(200);\n const updated = updateResponse.json().data;\n expect(updated.id).toBe(created.id);\n\n // Delete\n const deleteResponse = await app.inject({\n method: 'DELETE',\n url: \\`/${name}/\\${created.id}\\`,\n });\n\n expect(deleteResponse.statusCode).toBe(204);\n\n // Verify deletion\n const verifyResponse = await app.inject({\n method: 'GET',\n url: \\`/${name}/\\${created.id}\\`,\n });\n\n expect(verifyResponse.statusCode).toBe(404);\n });\n });\n\n describe('List and pagination', () => {\n it('should list ${name} with pagination', async () => {\n // Create multiple ${name}\n const count = 5;\n for (let i = 0; i < count; i++) {\n await app.inject({\n method: 'POST',\n url: '/${name}',\n payload: {\n // TODO: Add required fields\n },\n });\n }\n\n // Test pagination\n const response = await app.inject({\n method: 'GET',\n url: '/${name}?page=1&limit=3',\n });\n\n expect(response.statusCode).toBe(200);\n const result = response.json();\n expect(result.data).toBeDefined();\n expect(result.data.length).toBeLessThanOrEqual(3);\n expect(result.total).toBeGreaterThanOrEqual(count);\n });\n });\n\n describe('Validation', () => {\n it('should validate required fields on create', async () => {\n const response = await app.inject({\n method: 'POST',\n url: '/${name}',\n payload: {},\n });\n\n expect(response.statusCode).toBe(400);\n expect(response.json()).toHaveProperty('error');\n });\n\n it('should validate data types', async () => {\n const response = await app.inject({\n method: 'POST',\n url: '/${name}',\n payload: {\n // TODO: Add invalid field types\n },\n });\n\n expect(response.statusCode).toBe(400);\n });\n });\n});\n`;\n}\n","import fs from 'fs/promises';\nimport path from 'path';\nimport { getProjectRoot } from './helpers.js';\n\n/**\n * Template loader that checks for custom templates in priority order:\n * 1. Project templates (.servcraft/templates/)\n * 2. User templates (~/.servcraft/templates/)\n * 3. Built-in templates (fallback)\n */\n\nexport type TemplateType =\n | 'controller'\n | 'service'\n | 'repository'\n | 'types'\n | 'schemas'\n | 'routes'\n | 'module-index'\n | 'controller-test'\n | 'service-test'\n | 'integration-test';\n\ninterface TemplateFunction {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: (...args: any[]) => string;\n}\n\n/**\n * Load a custom template if available, otherwise return null\n */\nexport async function loadCustomTemplate(\n templateType: TemplateType\n): Promise<TemplateFunction | null> {\n const projectRoot = getProjectRoot();\n const homeDir = process.env.HOME || process.env.USERPROFILE || '';\n\n const locations = [\n path.join(projectRoot, '.servcraft', 'templates', `${templateType}.ts`),\n path.join(homeDir, '.servcraft', 'templates', `${templateType}.ts`),\n ];\n\n for (const location of locations) {\n try {\n await fs.access(location);\n // Template file exists, dynamically import it\n const templateModule = (await import(`file://${location}`)) as TemplateFunction;\n\n // Look for the template function (e.g., controllerTemplate, serviceTemplate)\n const functionName = `${templateType.replace(/-/g, '')}Template`;\n\n if (templateModule[functionName]) {\n return templateModule;\n }\n } catch {\n // File doesn't exist or import failed, try next location\n continue;\n }\n }\n\n return null;\n}\n\n/**\n * Get template function with fallback to built-in\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function getTemplate<T extends (...args: any[]) => string>(\n templateType: TemplateType,\n builtInTemplate: T\n): Promise<T> {\n const customTemplate = await loadCustomTemplate(templateType);\n\n if (customTemplate) {\n const functionName = `${templateType.replace(/-/g, '')}Template`;\n return customTemplate[functionName] as T;\n }\n\n return builtInTemplate;\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport * as fs from 'fs/promises';\nimport {\n ensureDir,\n writeFile,\n fileExists,\n success,\n error,\n info,\n warn,\n getModulesDir,\n} from '../utils/helpers.js';\nimport { EnvManager } from '../utils/env-manager.js';\nimport { TemplateManager } from '../utils/template-manager.js';\nimport { InteractivePrompt } from '../utils/interactive-prompt.js';\nimport { DryRunManager } from '../utils/dry-run.js';\nimport { ErrorTypes, displayError, validateProject } from '../utils/error-handler.js';\n\n// Pre-built modules that can be added\nconst AVAILABLE_MODULES = {\n auth: {\n name: 'Authentication',\n description: 'JWT authentication with access/refresh tokens',\n files: [\n 'auth.service',\n 'auth.controller',\n 'auth.routes',\n 'auth.middleware',\n 'auth.schemas',\n 'auth.types',\n 'index',\n ],\n },\n users: {\n name: 'User Management',\n description: 'User CRUD with RBAC (roles & permissions)',\n files: [\n 'user.service',\n 'user.controller',\n 'user.repository',\n 'user.routes',\n 'user.schemas',\n 'user.types',\n 'index',\n ],\n },\n email: {\n name: 'Email Service',\n description: 'SMTP email with templates (Handlebars)',\n files: ['email.service', 'email.templates', 'email.types', 'index'],\n },\n audit: {\n name: 'Audit Logs',\n description: 'Activity logging and audit trail',\n files: ['audit.service', 'audit.types', 'index'],\n },\n cache: {\n name: 'Redis Cache',\n description: 'Redis caching with TTL & invalidation',\n files: ['cache.service', 'cache.types', 'index'],\n },\n upload: {\n name: 'File Upload',\n description: 'File upload with local/S3/Cloudinary storage',\n files: ['upload.service', 'upload.routes', 'upload.types', 'index'],\n },\n mfa: {\n name: 'MFA/TOTP',\n description: 'Two-factor authentication with QR codes',\n files: ['mfa.service', 'mfa.routes', 'totp.ts', 'types.ts', 'index'],\n },\n oauth: {\n name: 'OAuth',\n description: 'Social login (Google, GitHub, Facebook, Twitter, Apple)',\n files: ['oauth.service', 'oauth.routes', 'providers', 'types.ts', 'index'],\n },\n payment: {\n name: 'Payments',\n description: 'Payment processing (Stripe, PayPal, Mobile Money)',\n files: ['payment.service', 'payment.routes', 'providers', 'types.ts', 'index'],\n },\n notification: {\n name: 'Notifications',\n description: 'Email, SMS, Push notifications',\n files: ['notification.service', 'types.ts', 'index'],\n },\n 'rate-limit': {\n name: 'Rate Limiting',\n description: 'Advanced rate limiting with multiple algorithms',\n files: [\n 'rate-limit.service',\n 'rate-limit.middleware',\n 'rate-limit.routes',\n 'stores',\n 'types.ts',\n 'index',\n ],\n },\n webhook: {\n name: 'Webhooks',\n description: 'Outgoing webhooks with HMAC signatures & retry',\n files: ['webhook.service', 'webhook.routes', 'signature.ts', 'retry.ts', 'types.ts', 'index'],\n },\n queue: {\n name: 'Queue/Jobs',\n description: 'Background jobs with Bull/BullMQ & cron scheduling',\n files: ['queue.service', 'cron.ts', 'workers.ts', 'routes.ts', 'types.ts', 'index'],\n },\n websocket: {\n name: 'WebSockets',\n description: 'Real-time communication with Socket.io',\n files: ['websocket.service', 'features.ts', 'middlewares.ts', 'types.ts', 'index'],\n },\n search: {\n name: 'Search',\n description: 'Full-text search with Elasticsearch/Meilisearch',\n files: ['search.service', 'adapters', 'types.ts', 'index'],\n },\n i18n: {\n name: 'i18n/Localization',\n description: 'Multi-language support with 7+ locales',\n files: ['i18n.service', 'i18n.middleware', 'i18n.routes', 'types.ts', 'index'],\n },\n 'feature-flag': {\n name: 'Feature Flags',\n description: 'A/B testing & progressive rollout',\n files: ['feature-flag.service', 'feature-flag.routes', 'types.ts', 'index'],\n },\n analytics: {\n name: 'Analytics/Metrics',\n description: 'Prometheus metrics & event tracking',\n files: ['analytics.service', 'analytics.routes', 'types.ts', 'index'],\n },\n 'media-processing': {\n name: 'Media Processing',\n description: 'Image/video processing with FFmpeg',\n files: ['media-processing.service', 'media-processing.routes', 'types.ts', 'index'],\n },\n 'api-versioning': {\n name: 'API Versioning',\n description: 'Multiple API versions support',\n files: [\n 'versioning.service',\n 'versioning.middleware',\n 'versioning.routes',\n 'types.ts',\n 'index',\n ],\n },\n};\n\nexport const addModuleCommand = new Command('add')\n .description('Add a pre-built module to your project')\n .argument(\n '[module]',\n 'Module to add (auth, users, email, audit, upload, cache, notifications, settings)'\n )\n .option('-l, --list', 'List available modules')\n .option('-f, --force', 'Force overwrite existing module')\n .option('-u, --update', 'Update existing module (smart merge)')\n .option('--skip-existing', 'Skip if module already exists')\n .option('--dry-run', 'Preview changes without writing files')\n .action(\n async (\n moduleName?: string,\n options?: {\n list?: boolean;\n force?: boolean;\n update?: boolean;\n skipExisting?: boolean;\n dryRun?: boolean;\n }\n ) => {\n if (options?.list || !moduleName) {\n console.log(chalk.bold('\\n📦 Available Modules:\\n'));\n\n for (const [key, mod] of Object.entries(AVAILABLE_MODULES)) {\n console.log(` ${chalk.cyan(key.padEnd(15))} ${mod.name}`);\n console.log(` ${' '.repeat(15)} ${chalk.gray(mod.description)}\\n`);\n }\n\n console.log(chalk.bold('Usage:'));\n console.log(` ${chalk.yellow('servcraft add auth')} Add authentication module`);\n console.log(` ${chalk.yellow('servcraft add users')} Add user management module`);\n console.log(` ${chalk.yellow('servcraft add email')} Add email service module\\n`);\n return;\n }\n\n // Enable dry-run mode if specified\n const dryRun = DryRunManager.getInstance();\n if (options?.dryRun) {\n dryRun.enable();\n console.log(chalk.yellow('\\n⚠ DRY RUN MODE - No files will be written\\n'));\n }\n\n const module = AVAILABLE_MODULES[moduleName as keyof typeof AVAILABLE_MODULES];\n\n if (!module) {\n displayError(ErrorTypes.MODULE_NOT_FOUND(moduleName));\n return;\n }\n\n // Validate project structure\n const projectError = validateProject();\n if (projectError) {\n displayError(projectError);\n return;\n }\n\n const spinner = ora(`Adding ${module.name} module...`).start();\n\n try {\n const moduleDir = path.join(getModulesDir(), moduleName);\n const templateManager = new TemplateManager(process.cwd());\n const moduleExists = await fileExists(moduleDir);\n\n // Handle existing module\n if (moduleExists) {\n spinner.stop();\n\n // Check flags\n if (options?.skipExisting) {\n info(`Module \"${moduleName}\" already exists, skipping...`);\n return;\n }\n\n // Check for modifications\n const modifiedFiles = await templateManager.getModifiedFiles(moduleName, moduleDir);\n const hasModifications = modifiedFiles.some((f) => f.isModified);\n\n let action: string;\n\n if (options?.force) {\n action = 'overwrite';\n } else if (options?.update) {\n action = 'update';\n } else {\n // Interactive prompt\n const choice = await InteractivePrompt.askModuleExists(moduleName, hasModifications);\n action = choice.action;\n }\n\n // Handle action\n if (action === 'skip') {\n info('Keeping existing module');\n return;\n }\n\n if (action === 'diff') {\n // Show diff and ask again\n await showDiffForModule(templateManager, moduleName, moduleDir);\n return;\n }\n\n if (action === 'backup-overwrite' || action === 'overwrite') {\n if (action === 'backup-overwrite') {\n const backupPath = await templateManager.createBackup(moduleName, moduleDir);\n InteractivePrompt.showBackupCreated(backupPath);\n }\n\n // Remove existing module\n await fs.rm(moduleDir, { recursive: true, force: true });\n await ensureDir(moduleDir);\n\n // Generate fresh module\n await generateModuleFiles(moduleName, moduleDir);\n\n // Save templates and manifest\n const files = await getModuleFiles(moduleName, moduleDir);\n await templateManager.saveTemplate(moduleName, files);\n await templateManager.saveManifest(moduleName, files);\n\n spinner.succeed(\n `${module.name} module ${action === 'backup-overwrite' ? 'backed up and ' : ''}overwritten!`\n );\n } else if (action === 'update') {\n // Smart merge\n await performSmartMerge(templateManager, moduleName, moduleDir, module.name);\n }\n } else {\n // Fresh installation\n await ensureDir(moduleDir);\n\n // Generate module files\n await generateModuleFiles(moduleName, moduleDir);\n\n // Save templates and manifest for future updates\n const files = await getModuleFiles(moduleName, moduleDir);\n await templateManager.saveTemplate(moduleName, files);\n await templateManager.saveManifest(moduleName, files);\n\n spinner.succeed(`${module.name} module added successfully!`);\n }\n\n if (!moduleExists) {\n console.log('\\n📁 Files created:');\n module.files.forEach((f) => success(` src/modules/${moduleName}/${f}.ts`));\n }\n\n // Update .env file with module-specific variables\n const envManager = new EnvManager(process.cwd());\n const envSections = EnvManager.getModuleEnvVariables(moduleName);\n\n if (envSections.length > 0) {\n const envSpinner = ora('Updating environment variables...').start();\n try {\n const result = await envManager.addVariables(envSections);\n\n envSpinner.succeed('Environment variables updated!');\n\n if (result.created) {\n info('\\n📝 Created new .env file');\n }\n\n if (result.added.length > 0) {\n console.log(chalk.bold('\\n✅ Added to .env:'));\n result.added.forEach((key) => success(` ${key}`));\n }\n\n if (result.skipped.length > 0) {\n console.log(chalk.bold('\\n⏭️ Already in .env (skipped):'));\n result.skipped.forEach((key) => info(` ${key}`));\n }\n\n // Show which variables need configuration\n const requiredVars = envSections\n .flatMap((section) => section.variables)\n .filter((v) => v.required && !v.value)\n .map((v) => v.key);\n\n if (requiredVars.length > 0) {\n console.log(chalk.bold('\\n⚠️ Required configuration:'));\n requiredVars.forEach((key) => warn(` ${key} - Please configure this variable`));\n }\n } catch (err) {\n envSpinner.fail('Failed to update environment variables');\n error(err instanceof Error ? err.message : String(err));\n }\n }\n\n if (!options?.dryRun) {\n console.log('\\n📌 Next steps:');\n info(' 1. Configure environment variables in .env (if needed)');\n info(' 2. Register the module in your main app file');\n info(' 3. Run database migrations if needed');\n }\n\n // Show dry-run summary if enabled\n if (options?.dryRun) {\n dryRun.printSummary();\n }\n } catch (err) {\n spinner.fail('Failed to add module');\n error(err instanceof Error ? err.message : String(err));\n }\n }\n );\n\nasync function generateAuthModule(dir: string): Promise<void> {\n // This would copy from templates or generate inline\n // For now, we'll create placeholder files\n const files = {\n 'auth.types.ts': `export interface JwtPayload {\n sub: string;\n email: string;\n role: string;\n type: 'access' | 'refresh';\n}\n\nexport interface TokenPair {\n accessToken: string;\n refreshToken: string;\n expiresIn: number;\n}\n\nexport interface AuthUser {\n id: string;\n email: string;\n role: string;\n}\n`,\n 'auth.schemas.ts': `import { z } from 'zod';\n\nexport const loginSchema = z.object({\n email: z.string().email(),\n password: z.string().min(1),\n});\n\nexport const registerSchema = z.object({\n email: z.string().email(),\n password: z.string().min(8),\n name: z.string().min(2).optional(),\n});\n\nexport const refreshTokenSchema = z.object({\n refreshToken: z.string().min(1),\n});\n`,\n 'index.ts': `export * from './auth.types.js';\nexport * from './auth.schemas.js';\n// Export services, controllers, etc.\n`,\n };\n\n for (const [name, content] of Object.entries(files)) {\n await writeFile(path.join(dir, name), content);\n }\n}\n\nasync function generateUsersModule(dir: string): Promise<void> {\n const files = {\n 'user.types.ts': `export type UserStatus = 'active' | 'inactive' | 'suspended' | 'banned';\nexport type UserRole = 'user' | 'admin' | 'moderator' | 'super_admin';\n\nexport interface User {\n id: string;\n email: string;\n password: string;\n name?: string;\n role: UserRole;\n status: UserStatus;\n createdAt: Date;\n updatedAt: Date;\n}\n`,\n 'user.schemas.ts': `import { z } from 'zod';\n\nexport const createUserSchema = z.object({\n email: z.string().email(),\n password: z.string().min(8),\n name: z.string().min(2).optional(),\n role: z.enum(['user', 'admin', 'moderator']).optional(),\n});\n\nexport const updateUserSchema = z.object({\n email: z.string().email().optional(),\n name: z.string().min(2).optional(),\n role: z.enum(['user', 'admin', 'moderator', 'super_admin']).optional(),\n status: z.enum(['active', 'inactive', 'suspended', 'banned']).optional(),\n});\n`,\n 'index.ts': `export * from './user.types.js';\nexport * from './user.schemas.js';\n`,\n };\n\n for (const [name, content] of Object.entries(files)) {\n await writeFile(path.join(dir, name), content);\n }\n}\n\nasync function generateEmailModule(dir: string): Promise<void> {\n const files = {\n 'email.types.ts': `export interface EmailOptions {\n to: string | string[];\n subject: string;\n html?: string;\n text?: string;\n template?: string;\n data?: Record<string, unknown>;\n}\n\nexport interface EmailResult {\n success: boolean;\n messageId?: string;\n error?: string;\n}\n`,\n 'email.service.ts': `import nodemailer from 'nodemailer';\nimport type { EmailOptions, EmailResult } from './email.types.js';\n\nexport class EmailService {\n private transporter;\n\n constructor() {\n this.transporter = nodemailer.createTransport({\n host: process.env.SMTP_HOST,\n port: parseInt(process.env.SMTP_PORT || '587', 10),\n auth: {\n user: process.env.SMTP_USER,\n pass: process.env.SMTP_PASS,\n },\n });\n }\n\n async send(options: EmailOptions): Promise<EmailResult> {\n try {\n const result = await this.transporter.sendMail({\n from: process.env.SMTP_FROM,\n ...options,\n });\n return { success: true, messageId: result.messageId };\n } catch (error) {\n return { success: false, error: String(error) };\n }\n }\n}\n\nexport const emailService = new EmailService();\n`,\n 'index.ts': `export * from './email.types.js';\nexport { EmailService, emailService } from './email.service.js';\n`,\n };\n\n for (const [name, content] of Object.entries(files)) {\n await writeFile(path.join(dir, name), content);\n }\n}\n\nasync function generateAuditModule(dir: string): Promise<void> {\n const files = {\n 'audit.types.ts': `export interface AuditLogEntry {\n userId?: string;\n action: string;\n resource: string;\n resourceId?: string;\n oldValue?: Record<string, unknown>;\n newValue?: Record<string, unknown>;\n ipAddress?: string;\n userAgent?: string;\n createdAt: Date;\n}\n`,\n 'audit.service.ts': `import type { AuditLogEntry } from './audit.types.js';\n\nconst logs: AuditLogEntry[] = [];\n\nexport class AuditService {\n async log(entry: Omit<AuditLogEntry, 'createdAt'>): Promise<void> {\n logs.push({ ...entry, createdAt: new Date() });\n console.log('[AUDIT]', entry.action, entry.resource);\n }\n\n async query(filters: Partial<AuditLogEntry>): Promise<AuditLogEntry[]> {\n return logs.filter((log) => {\n for (const [key, value] of Object.entries(filters)) {\n if (log[key as keyof AuditLogEntry] !== value) return false;\n }\n return true;\n });\n }\n}\n\nexport const auditService = new AuditService();\n`,\n 'index.ts': `export * from './audit.types.js';\nexport { AuditService, auditService } from './audit.service.js';\n`,\n };\n\n for (const [name, content] of Object.entries(files)) {\n await writeFile(path.join(dir, name), content);\n }\n}\n\nasync function generateUploadModule(dir: string): Promise<void> {\n const files = {\n 'upload.types.ts': `export interface UploadedFile {\n id: string;\n filename: string;\n originalName: string;\n mimetype: string;\n size: number;\n path: string;\n url: string;\n createdAt: Date;\n}\n\nexport interface UploadOptions {\n maxSize?: number;\n allowedTypes?: string[];\n destination?: string;\n}\n`,\n 'index.ts': `export * from './upload.types.js';\n`,\n };\n\n for (const [name, content] of Object.entries(files)) {\n await writeFile(path.join(dir, name), content);\n }\n}\n\nasync function generateCacheModule(dir: string): Promise<void> {\n const files = {\n 'cache.types.ts': `export interface CacheOptions {\n ttl?: number;\n prefix?: string;\n}\n`,\n 'cache.service.ts': `import type { CacheOptions } from './cache.types.js';\n\n// In-memory cache (replace with Redis in production)\nconst cache = new Map<string, { value: unknown; expiry: number }>();\n\nexport class CacheService {\n async get<T>(key: string): Promise<T | null> {\n const item = cache.get(key);\n if (!item) return null;\n if (Date.now() > item.expiry) {\n cache.delete(key);\n return null;\n }\n return item.value as T;\n }\n\n async set(key: string, value: unknown, ttl = 3600): Promise<void> {\n cache.set(key, { value, expiry: Date.now() + ttl * 1000 });\n }\n\n async del(key: string): Promise<void> {\n cache.delete(key);\n }\n\n async clear(): Promise<void> {\n cache.clear();\n }\n}\n\nexport const cacheService = new CacheService();\n`,\n 'index.ts': `export * from './cache.types.js';\nexport { CacheService, cacheService } from './cache.service.js';\n`,\n };\n\n for (const [name, content] of Object.entries(files)) {\n await writeFile(path.join(dir, name), content);\n }\n}\n\nasync function generateGenericModule(dir: string, name: string): Promise<void> {\n const files = {\n [`${name}.types.ts`]: `// ${name} types\nexport interface ${name.charAt(0).toUpperCase() + name.slice(1)}Data {\n // Define your types here\n}\n`,\n 'index.ts': `export * from './${name}.types.js';\n`,\n };\n\n for (const [fileName, content] of Object.entries(files)) {\n await writeFile(path.join(dir, fileName), content);\n }\n}\n\n/**\n * Helper: Find servcraft modules source directory\n */\nasync function findServercraftModules(): Promise<string | null> {\n // Get the directory where the CLI script is located\n const scriptDir = path.dirname(new URL(import.meta.url).pathname);\n\n const possiblePaths = [\n // Local node_modules (when servcraft is a dependency)\n path.join(process.cwd(), 'node_modules', 'servcraft', 'src', 'modules'),\n // From dist/cli/index.js -> src/modules (npx or global install)\n path.resolve(scriptDir, '..', '..', 'src', 'modules'),\n // From src/cli/commands/add-module.ts -> src/modules (development)\n path.resolve(scriptDir, '..', '..', 'modules'),\n ];\n\n for (const p of possiblePaths) {\n try {\n const stats = await fs.stat(p);\n if (stats.isDirectory()) {\n return p;\n }\n } catch {\n // Path doesn't exist, try next\n }\n }\n return null;\n}\n\n/**\n * Helper: Generate module files - copies from servcraft package modules\n */\nasync function generateModuleFiles(moduleName: string, moduleDir: string): Promise<void> {\n // Map module names to their directory names in servcraft\n const moduleNameMap: Record<string, string> = {\n users: 'user',\n 'rate-limit': 'rate-limit',\n 'feature-flag': 'feature-flag',\n 'api-versioning': 'api-versioning',\n 'media-processing': 'media-processing',\n };\n\n const sourceDirName = moduleNameMap[moduleName] || moduleName;\n\n // Find servcraft modules directory\n const servercraftModulesDir = await findServercraftModules();\n\n if (servercraftModulesDir) {\n const sourceModuleDir = path.join(servercraftModulesDir, sourceDirName);\n\n if (await fileExists(sourceModuleDir)) {\n // Copy from servcraft package\n await copyModuleFromSource(sourceModuleDir, moduleDir);\n return;\n }\n }\n\n // Fallback to inline templates for basic modules\n switch (moduleName) {\n case 'auth':\n await generateAuthModule(moduleDir);\n break;\n case 'users':\n await generateUsersModule(moduleDir);\n break;\n case 'email':\n await generateEmailModule(moduleDir);\n break;\n case 'audit':\n await generateAuditModule(moduleDir);\n break;\n case 'upload':\n await generateUploadModule(moduleDir);\n break;\n case 'cache':\n await generateCacheModule(moduleDir);\n break;\n default:\n await generateGenericModule(moduleDir, moduleName);\n }\n}\n\n/**\n * Helper: Copy module from source directory\n */\nasync function copyModuleFromSource(sourceDir: string, targetDir: string): Promise<void> {\n const entries = await fs.readdir(sourceDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const sourcePath = path.join(sourceDir, entry.name);\n const targetPath = path.join(targetDir, entry.name);\n\n if (entry.isDirectory()) {\n await fs.mkdir(targetPath, { recursive: true });\n await copyModuleFromSource(sourcePath, targetPath);\n } else {\n await fs.copyFile(sourcePath, targetPath);\n }\n }\n}\n\n/**\n * Helper: Get all module files as Record<filename, content>\n */\nasync function getModuleFiles(\n moduleName: string,\n moduleDir: string\n): Promise<Record<string, string>> {\n const files: Record<string, string> = {};\n const entries = await fs.readdir(moduleDir);\n\n for (const entry of entries) {\n const filePath = path.join(moduleDir, entry);\n const stat = await fs.stat(filePath);\n\n if (stat.isFile() && entry.endsWith('.ts')) {\n const content = await fs.readFile(filePath, 'utf-8');\n files[entry] = content;\n }\n }\n\n return files;\n}\n\n/**\n * Helper: Show diff for entire module\n */\nasync function showDiffForModule(\n templateManager: TemplateManager,\n moduleName: string,\n moduleDir: string\n): Promise<void> {\n const modifiedFiles = await templateManager.getModifiedFiles(moduleName, moduleDir);\n\n console.log(chalk.cyan(`\\n📊 Changes in module \"${moduleName}\":\\n`));\n\n for (const file of modifiedFiles) {\n if (file.isModified) {\n console.log(chalk.yellow(`\\n📄 ${file.fileName}:`));\n\n const currentPath = path.join(moduleDir, file.fileName);\n const currentContent = await fs.readFile(currentPath, 'utf-8');\n const originalContent = await templateManager.getTemplate(moduleName, file.fileName);\n\n if (originalContent) {\n const diff = templateManager.generateDiff(originalContent, currentContent);\n console.log(diff);\n }\n }\n }\n}\n\n/**\n * Helper: Perform smart merge\n */\nasync function performSmartMerge(\n templateManager: TemplateManager,\n moduleName: string,\n moduleDir: string,\n _displayName: string\n): Promise<void> {\n const spinner = ora('Analyzing files for merge...').start();\n\n // Get new template files\n const newFiles: Record<string, string> = {};\n const templateDir = path.join(templateManager['templatesDir'], moduleName);\n\n try {\n const entries = await fs.readdir(templateDir);\n for (const entry of entries) {\n const content = await fs.readFile(path.join(templateDir, entry), 'utf-8');\n newFiles[entry] = content;\n }\n } catch {\n spinner.fail('Could not find template files');\n return;\n }\n\n const modifiedFiles = await templateManager.getModifiedFiles(moduleName, moduleDir);\n spinner.stop();\n\n // Ask for batch action or individual\n const batchAction = await InteractivePrompt.askBatchAction();\n\n const stats = {\n merged: 0,\n kept: 0,\n overwritten: 0,\n conflicts: 0,\n };\n\n for (const fileInfo of modifiedFiles) {\n const fileName = fileInfo.fileName;\n const filePath = path.join(moduleDir, fileName);\n const newContent = newFiles[fileName];\n\n if (!newContent) {\n // File doesn't exist in new template, keep existing\n continue;\n }\n\n let fileAction: string;\n\n if (batchAction === 'merge-all') {\n fileAction = 'merge';\n } else if (batchAction === 'keep-all') {\n fileAction = 'keep';\n } else if (batchAction === 'overwrite-all') {\n fileAction = 'overwrite';\n } else {\n // Ask for each file\n const currentContent = await fs.readFile(filePath, 'utf-8');\n const yourLines = currentContent.split('\\n').length;\n const newLines = newContent.split('\\n').length;\n\n const choice = await InteractivePrompt.askFileAction(\n fileName,\n fileInfo.isModified,\n yourLines,\n newLines\n );\n fileAction = choice.action;\n\n if (fileAction === 'diff') {\n const originalContent = await templateManager.getTemplate(moduleName, fileName);\n if (originalContent) {\n const diff = templateManager.generateDiff(originalContent, currentContent);\n const proceed = await InteractivePrompt.showDiffAndAsk(diff);\n fileAction = proceed ? 'merge' : 'keep';\n }\n }\n }\n\n // Perform action\n if (fileAction === 'keep' || fileAction === 'skip') {\n stats.kept++;\n continue;\n }\n\n if (fileAction === 'overwrite') {\n await fs.writeFile(filePath, newContent, 'utf-8');\n stats.overwritten++;\n continue;\n }\n\n if (fileAction === 'merge') {\n const originalContent = await templateManager.getTemplate(moduleName, fileName);\n const currentContent = await fs.readFile(filePath, 'utf-8');\n\n if (originalContent) {\n const mergeResult = await templateManager.mergeFiles(\n originalContent,\n currentContent,\n newContent\n );\n\n await fs.writeFile(filePath, mergeResult.merged, 'utf-8');\n\n if (mergeResult.hasConflicts) {\n stats.conflicts++;\n InteractivePrompt.displayConflicts(mergeResult.conflicts);\n } else {\n stats.merged++;\n }\n } else {\n await fs.writeFile(filePath, newContent, 'utf-8');\n stats.overwritten++;\n }\n }\n }\n\n // Update manifest\n const files = await getModuleFiles(moduleName, moduleDir);\n await templateManager.updateManifest(moduleName, files);\n\n InteractivePrompt.showMergeSummary(stats);\n}\n","import * as fs from 'fs/promises';\nimport * as path from 'path';\nimport { existsSync } from 'fs';\n\nexport interface EnvVariable {\n key: string;\n value?: string;\n comment?: string;\n required?: boolean;\n}\n\nexport interface EnvSection {\n title: string;\n variables: EnvVariable[];\n}\n\n/**\n * Environment Manager\n * Manages .env file updates when adding modules\n */\nexport class EnvManager {\n private envPath: string;\n private envExamplePath: string;\n\n constructor(projectRoot: string) {\n this.envPath = path.join(projectRoot, '.env');\n this.envExamplePath = path.join(projectRoot, '.env.example');\n }\n\n /**\n * Add environment variables to .env file\n */\n async addVariables(sections: EnvSection[]): Promise<{\n added: string[];\n skipped: string[];\n created: boolean;\n }> {\n const added: string[] = [];\n const skipped: string[] = [];\n let created = false;\n\n // Read existing .env or create new one\n let envContent = '';\n if (existsSync(this.envPath)) {\n envContent = await fs.readFile(this.envPath, 'utf-8');\n } else {\n created = true;\n }\n\n // Parse existing variables\n const existingKeys = this.parseExistingKeys(envContent);\n\n // Build new content\n let newContent = envContent;\n if (newContent && !newContent.endsWith('\\n\\n')) {\n newContent += '\\n\\n';\n }\n\n for (const section of sections) {\n // Add section comment\n newContent += `# ${section.title}\\n`;\n\n for (const variable of section.variables) {\n // Skip if already exists\n if (existingKeys.has(variable.key)) {\n skipped.push(variable.key);\n continue;\n }\n\n // Add variable comment if provided\n if (variable.comment) {\n newContent += `# ${variable.comment}\\n`;\n }\n\n // Add variable\n const value = variable.value || '';\n const prefix = variable.required ? '' : '# ';\n newContent += `${prefix}${variable.key}=${value}\\n`;\n\n added.push(variable.key);\n }\n\n newContent += '\\n';\n }\n\n // Write to .env\n await fs.writeFile(this.envPath, newContent, 'utf-8');\n\n // Update .env.example if it exists\n if (existsSync(this.envExamplePath)) {\n await this.updateEnvExample(sections);\n }\n\n return { added, skipped, created };\n }\n\n /**\n * Update .env.example file\n */\n private async updateEnvExample(sections: EnvSection[]): Promise<void> {\n let exampleContent = '';\n if (existsSync(this.envExamplePath)) {\n exampleContent = await fs.readFile(this.envExamplePath, 'utf-8');\n }\n\n const existingKeys = this.parseExistingKeys(exampleContent);\n\n let newContent = exampleContent;\n if (newContent && !newContent.endsWith('\\n\\n')) {\n newContent += '\\n\\n';\n }\n\n for (const section of sections) {\n newContent += `# ${section.title}\\n`;\n\n for (const variable of section.variables) {\n if (existingKeys.has(variable.key)) {\n continue;\n }\n\n if (variable.comment) {\n newContent += `# ${variable.comment}\\n`;\n }\n\n // In .env.example, show placeholder values\n const placeholder = this.getPlaceholder(variable.key);\n newContent += `${variable.key}=${placeholder}\\n`;\n }\n\n newContent += '\\n';\n }\n\n await fs.writeFile(this.envExamplePath, newContent, 'utf-8');\n }\n\n /**\n * Parse existing environment variable keys\n */\n private parseExistingKeys(content: string): Set<string> {\n const keys = new Set<string>();\n const lines = content.split('\\n');\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Skip comments and empty lines\n if (!trimmed || trimmed.startsWith('#')) {\n continue;\n }\n\n // Extract key from KEY=value or # KEY=value\n const match = trimmed.match(/^#?\\s*([A-Z_][A-Z0-9_]*)\\s*=/);\n if (match && match[1]) {\n keys.add(match[1]);\n }\n }\n\n return keys;\n }\n\n /**\n * Get placeholder value for .env.example\n */\n private getPlaceholder(key: string): string {\n // Common patterns\n if (key.includes('SECRET') || key.includes('KEY') || key.includes('PASSWORD')) {\n return 'your-secret-key-here';\n }\n if (key.includes('HOST')) {\n return 'localhost';\n }\n if (key.includes('PORT')) {\n return '3000';\n }\n if (key.includes('URL')) {\n return 'http://localhost:3000';\n }\n if (key.includes('EMAIL')) {\n return 'user@example.com';\n }\n if (key.includes('REDIS')) {\n return 'redis://localhost:6379';\n }\n if (key.includes('DATABASE')) {\n return 'postgresql://user:pass@localhost:5432/db';\n }\n if (key.includes('NODE')) {\n return 'http://localhost:9200';\n }\n\n return '';\n }\n\n /**\n * Get environment variables for a specific module\n */\n static getModuleEnvVariables(moduleName: string): EnvSection[] {\n const moduleEnvMap: Record<string, EnvSection[]> = {\n 'rate-limit': [\n {\n title: 'Rate Limiting Configuration',\n variables: [\n {\n key: 'RATE_LIMIT_ENABLED',\n value: 'true',\n comment: 'Enable rate limiting',\n required: true,\n },\n {\n key: 'RATE_LIMIT_REDIS_URL',\n value: 'redis://localhost:6379',\n comment:\n 'Redis URL for distributed rate limiting (optional, uses in-memory if not set)',\n required: false,\n },\n ],\n },\n ],\n webhook: [\n {\n title: 'Webhook Configuration',\n variables: [\n {\n key: 'WEBHOOK_TIMEOUT',\n value: '10000',\n comment: 'Webhook request timeout in milliseconds',\n required: true,\n },\n {\n key: 'WEBHOOK_MAX_RETRIES',\n value: '5',\n comment: 'Maximum number of retry attempts',\n required: true,\n },\n {\n key: 'WEBHOOK_SIGNATURE_ENABLED',\n value: 'true',\n comment: 'Enable HMAC signature verification',\n required: true,\n },\n ],\n },\n ],\n queue: [\n {\n title: 'Queue/Jobs Configuration',\n variables: [\n {\n key: 'REDIS_HOST',\n value: 'localhost',\n comment: 'Redis host for Bull queue',\n required: true,\n },\n {\n key: 'REDIS_PORT',\n value: '6379',\n comment: 'Redis port',\n required: true,\n },\n {\n key: 'REDIS_PASSWORD',\n value: '',\n comment: 'Redis password (optional)',\n required: false,\n },\n {\n key: 'QUEUE_METRICS_ENABLED',\n value: 'true',\n comment: 'Enable queue metrics collection',\n required: true,\n },\n ],\n },\n ],\n websocket: [\n {\n title: 'WebSocket Configuration',\n variables: [\n {\n key: 'WEBSOCKET_PORT',\n value: '3001',\n comment: 'WebSocket server port',\n required: true,\n },\n {\n key: 'WEBSOCKET_CORS_ORIGIN',\n value: 'http://localhost:3000',\n comment: 'CORS origin for WebSocket',\n required: true,\n },\n {\n key: 'WEBSOCKET_REDIS_URL',\n value: 'redis://localhost:6379',\n comment: 'Redis URL for Socket.io adapter (optional, for multi-instance)',\n required: false,\n },\n ],\n },\n ],\n search: [\n {\n title: 'Search Configuration (Elasticsearch)',\n variables: [\n {\n key: 'SEARCH_ENGINE',\n value: 'memory',\n comment: 'Search engine: elasticsearch, meilisearch, or memory',\n required: true,\n },\n {\n key: 'ELASTICSEARCH_NODE',\n value: 'http://localhost:9200',\n comment: 'Elasticsearch node URL',\n required: false,\n },\n {\n key: 'ELASTICSEARCH_USERNAME',\n value: '',\n comment: 'Elasticsearch username (optional)',\n required: false,\n },\n {\n key: 'ELASTICSEARCH_PASSWORD',\n value: '',\n comment: 'Elasticsearch password (optional)',\n required: false,\n },\n ],\n },\n {\n title: 'Search Configuration (Meilisearch)',\n variables: [\n {\n key: 'MEILISEARCH_HOST',\n value: 'http://localhost:7700',\n comment: 'Meilisearch host URL',\n required: false,\n },\n {\n key: 'MEILISEARCH_API_KEY',\n value: '',\n comment: 'Meilisearch API key (optional)',\n required: false,\n },\n ],\n },\n ],\n i18n: [\n {\n title: 'i18n/Localization Configuration',\n variables: [\n {\n key: 'DEFAULT_LOCALE',\n value: 'en',\n comment: 'Default locale/language',\n required: true,\n },\n {\n key: 'SUPPORTED_LOCALES',\n value: 'en,fr,es,de,ar,zh,ja',\n comment: 'Comma-separated list of supported locales',\n required: true,\n },\n {\n key: 'TRANSLATIONS_DIR',\n value: './locales',\n comment: 'Directory for translation files',\n required: true,\n },\n {\n key: 'I18N_CACHE_ENABLED',\n value: 'true',\n comment: 'Enable translation caching',\n required: true,\n },\n ],\n },\n ],\n cache: [\n {\n title: 'Cache Configuration',\n variables: [\n {\n key: 'CACHE_PROVIDER',\n value: 'redis',\n comment: 'Cache provider: redis or memory',\n required: true,\n },\n {\n key: 'CACHE_REDIS_URL',\n value: 'redis://localhost:6379',\n comment: 'Redis URL for cache',\n required: false,\n },\n {\n key: 'CACHE_TTL',\n value: '3600',\n comment: 'Default cache TTL in seconds',\n required: true,\n },\n ],\n },\n ],\n mfa: [\n {\n title: 'MFA/TOTP Configuration',\n variables: [\n {\n key: 'MFA_ISSUER',\n value: 'MyApp',\n comment: 'MFA issuer name shown in authenticator apps',\n required: true,\n },\n {\n key: 'MFA_ALGORITHM',\n value: 'SHA1',\n comment: 'TOTP algorithm: SHA1, SHA256, or SHA512',\n required: true,\n },\n ],\n },\n ],\n oauth: [\n {\n title: 'OAuth Configuration',\n variables: [\n {\n key: 'OAUTH_GOOGLE_CLIENT_ID',\n value: '',\n comment: 'Google OAuth client ID',\n required: false,\n },\n {\n key: 'OAUTH_GOOGLE_CLIENT_SECRET',\n value: '',\n comment: 'Google OAuth client secret',\n required: false,\n },\n {\n key: 'OAUTH_GITHUB_CLIENT_ID',\n value: '',\n comment: 'GitHub OAuth client ID',\n required: false,\n },\n {\n key: 'OAUTH_GITHUB_CLIENT_SECRET',\n value: '',\n comment: 'GitHub OAuth client secret',\n required: false,\n },\n {\n key: 'OAUTH_REDIRECT_URL',\n value: 'http://localhost:3000/auth/callback',\n comment: 'OAuth callback URL',\n required: true,\n },\n ],\n },\n ],\n payment: [\n {\n title: 'Payment Configuration',\n variables: [\n {\n key: 'STRIPE_SECRET_KEY',\n value: '',\n comment: 'Stripe secret key',\n required: false,\n },\n {\n key: 'STRIPE_PUBLISHABLE_KEY',\n value: '',\n comment: 'Stripe publishable key',\n required: false,\n },\n {\n key: 'PAYPAL_CLIENT_ID',\n value: '',\n comment: 'PayPal client ID',\n required: false,\n },\n {\n key: 'PAYPAL_CLIENT_SECRET',\n value: '',\n comment: 'PayPal client secret',\n required: false,\n },\n {\n key: 'PAYPAL_MODE',\n value: 'sandbox',\n comment: 'PayPal mode: sandbox or live',\n required: false,\n },\n ],\n },\n ],\n 'feature-flag': [\n {\n title: 'Feature Flags Configuration',\n variables: [\n {\n key: 'FEATURE_FLAGS_ENABLED',\n value: 'true',\n comment: 'Enable feature flags',\n required: true,\n },\n {\n key: 'FEATURE_FLAGS_ENVIRONMENT',\n value: 'development',\n comment: 'Feature flags environment: development, staging, production, test',\n required: true,\n },\n {\n key: 'FEATURE_FLAGS_ANALYTICS',\n value: 'true',\n comment: 'Enable feature flag analytics',\n required: true,\n },\n {\n key: 'FEATURE_FLAGS_CACHE_TTL',\n value: '300',\n comment: 'Cache TTL in seconds',\n required: true,\n },\n ],\n },\n ],\n upload: [\n {\n title: 'File Upload Configuration',\n variables: [\n {\n key: 'UPLOAD_PROVIDER',\n value: 'local',\n comment: 'Upload provider: local, s3, cloudinary',\n required: true,\n },\n {\n key: 'UPLOAD_MAX_SIZE',\n value: '10485760',\n comment: 'Max upload size in bytes (10MB)',\n required: true,\n },\n {\n key: 'UPLOAD_DIR',\n value: './uploads',\n comment: 'Local upload directory',\n required: true,\n },\n {\n key: 'AWS_ACCESS_KEY_ID',\n value: '',\n comment: 'AWS access key for S3',\n required: false,\n },\n {\n key: 'AWS_SECRET_ACCESS_KEY',\n value: '',\n comment: 'AWS secret key for S3',\n required: false,\n },\n {\n key: 'AWS_S3_BUCKET',\n value: '',\n comment: 'S3 bucket name',\n required: false,\n },\n ],\n },\n ],\n notification: [\n {\n title: 'Notification Configuration',\n variables: [\n {\n key: 'NOTIFICATION_EMAIL_ENABLED',\n value: 'true',\n comment: 'Enable email notifications',\n required: true,\n },\n {\n key: 'NOTIFICATION_SMS_ENABLED',\n value: 'false',\n comment: 'Enable SMS notifications',\n required: false,\n },\n {\n key: 'NOTIFICATION_PUSH_ENABLED',\n value: 'false',\n comment: 'Enable push notifications',\n required: false,\n },\n {\n key: 'TWILIO_ACCOUNT_SID',\n value: '',\n comment: 'Twilio account SID for SMS',\n required: false,\n },\n {\n key: 'TWILIO_AUTH_TOKEN',\n value: '',\n comment: 'Twilio auth token',\n required: false,\n },\n ],\n },\n ],\n analytics: [\n {\n title: 'Analytics/Metrics Configuration',\n variables: [\n {\n key: 'ANALYTICS_ENABLED',\n value: 'true',\n comment: 'Enable analytics and metrics collection',\n required: true,\n },\n {\n key: 'ANALYTICS_PREFIX',\n value: 'app',\n comment: 'Metrics prefix',\n required: true,\n },\n {\n key: 'PROMETHEUS_ENABLED',\n value: 'true',\n comment: 'Enable Prometheus metrics endpoint',\n required: true,\n },\n {\n key: 'METRICS_FLUSH_INTERVAL',\n value: '60000',\n comment: 'Metrics flush interval in milliseconds',\n required: true,\n },\n ],\n },\n ],\n 'media-processing': [\n {\n title: 'Media Processing Configuration',\n variables: [\n {\n key: 'FFMPEG_PATH',\n value: 'ffmpeg',\n comment: 'Path to FFmpeg binary',\n required: true,\n },\n {\n key: 'FFPROBE_PATH',\n value: 'ffprobe',\n comment: 'Path to FFprobe binary',\n required: true,\n },\n {\n key: 'MEDIA_TEMP_DIR',\n value: './temp/media',\n comment: 'Temporary directory for media processing',\n required: true,\n },\n {\n key: 'MEDIA_MAX_CONCURRENT',\n value: '3',\n comment: 'Maximum concurrent processing jobs',\n required: true,\n },\n {\n key: 'MEDIA_GPU_ACCELERATION',\n value: 'false',\n comment: 'Enable GPU acceleration (requires NVIDIA GPU)',\n required: false,\n },\n ],\n },\n ],\n 'api-versioning': [\n {\n title: 'API Versioning Configuration',\n variables: [\n {\n key: 'API_VERSION_STRATEGY',\n value: 'url',\n comment: 'Versioning strategy: url, header, query, accept-header',\n required: true,\n },\n {\n key: 'API_DEFAULT_VERSION',\n value: 'v1',\n comment: 'Default API version',\n required: true,\n },\n {\n key: 'API_VERSION_HEADER',\n value: 'X-API-Version',\n comment: 'Header name for version (if strategy is header)',\n required: false,\n },\n {\n key: 'API_VERSION_STRICT',\n value: 'true',\n comment: 'Strict mode - reject unknown versions',\n required: true,\n },\n {\n key: 'API_DEPRECATION_WARNINGS',\n value: 'true',\n comment: 'Show deprecation warnings in headers',\n required: true,\n },\n ],\n },\n ],\n };\n\n return moduleEnvMap[moduleName] || [];\n }\n}\n","import * as fs from 'fs/promises';\nimport * as path from 'path';\nimport { createHash } from 'crypto';\nimport { existsSync } from 'fs';\n\nexport interface Template {\n /** Template name */\n name: string;\n /** Template content */\n content: string;\n /** Template hash for change detection */\n hash: string;\n /** Template version */\n version: string;\n}\n\nexport interface ModuleManifest {\n /** Module name */\n name: string;\n /** Module version */\n version: string;\n /** Files in this module */\n files: Record<string, { hash: string; path: string }>;\n /** Install date */\n installedAt: Date;\n /** Last update */\n updatedAt: Date;\n}\n\n/**\n * Template Manager\n * Manages module templates and tracks installed versions\n */\nexport class TemplateManager {\n private templatesDir: string;\n private manifestsDir: string;\n\n constructor(projectRoot: string) {\n this.templatesDir = path.join(projectRoot, '.servcraft', 'templates');\n this.manifestsDir = path.join(projectRoot, '.servcraft', 'manifests');\n }\n\n /**\n * Initialize template system\n */\n async initialize(): Promise<void> {\n await fs.mkdir(this.templatesDir, { recursive: true });\n await fs.mkdir(this.manifestsDir, { recursive: true });\n }\n\n /**\n * Save module template\n */\n async saveTemplate(moduleName: string, files: Record<string, string>): Promise<void> {\n await this.initialize();\n\n const moduleTemplateDir = path.join(this.templatesDir, moduleName);\n await fs.mkdir(moduleTemplateDir, { recursive: true });\n\n // Save each file\n for (const [fileName, content] of Object.entries(files)) {\n const filePath = path.join(moduleTemplateDir, fileName);\n await fs.writeFile(filePath, content, 'utf-8');\n }\n }\n\n /**\n * Get template content\n */\n async getTemplate(moduleName: string, fileName: string): Promise<string | null> {\n try {\n const filePath = path.join(this.templatesDir, moduleName, fileName);\n return await fs.readFile(filePath, 'utf-8');\n } catch {\n return null;\n }\n }\n\n /**\n * Save module manifest\n */\n async saveManifest(moduleName: string, files: Record<string, string>): Promise<void> {\n await this.initialize();\n\n const fileHashes: Record<string, { hash: string; path: string }> = {};\n\n for (const [fileName, content] of Object.entries(files)) {\n fileHashes[fileName] = {\n hash: this.hashContent(content),\n path: `src/modules/${moduleName}/${fileName}`,\n };\n }\n\n const manifest: ModuleManifest = {\n name: moduleName,\n version: '1.0.0',\n files: fileHashes,\n installedAt: new Date(),\n updatedAt: new Date(),\n };\n\n const manifestPath = path.join(this.manifestsDir, `${moduleName}.json`);\n await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2), 'utf-8');\n }\n\n /**\n * Get module manifest\n */\n async getManifest(moduleName: string): Promise<ModuleManifest | null> {\n try {\n const manifestPath = path.join(this.manifestsDir, `${moduleName}.json`);\n const content = await fs.readFile(manifestPath, 'utf-8');\n return JSON.parse(content) as ModuleManifest;\n } catch {\n return null;\n }\n }\n\n /**\n * Check if file has been modified by user\n */\n async isFileModified(\n moduleName: string,\n fileName: string,\n currentContent: string\n ): Promise<boolean> {\n const manifest = await this.getManifest(moduleName);\n\n if (!manifest || !manifest.files[fileName]) {\n return false;\n }\n\n const originalHash = manifest.files[fileName].hash;\n const currentHash = this.hashContent(currentContent);\n\n return originalHash !== currentHash;\n }\n\n /**\n * Get all modified files in a module\n */\n async getModifiedFiles(\n moduleName: string,\n moduleDir: string\n ): Promise<\n Array<{ fileName: string; isModified: boolean; originalHash: string; currentHash: string }>\n > {\n const manifest = await this.getManifest(moduleName);\n\n if (!manifest) {\n return [];\n }\n\n const results = [];\n\n for (const [fileName, fileInfo] of Object.entries(manifest.files)) {\n const filePath = path.join(moduleDir, fileName);\n\n if (!existsSync(filePath)) {\n results.push({\n fileName,\n isModified: true,\n originalHash: fileInfo.hash,\n currentHash: '',\n });\n continue;\n }\n\n const currentContent = await fs.readFile(filePath, 'utf-8');\n const currentHash = this.hashContent(currentContent);\n\n results.push({\n fileName,\n isModified: fileInfo.hash !== currentHash,\n originalHash: fileInfo.hash,\n currentHash,\n });\n }\n\n return results;\n }\n\n /**\n * Create backup of module\n */\n async createBackup(moduleName: string, moduleDir: string): Promise<string> {\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-').substring(0, 19);\n const backupDir = path.join(path.dirname(moduleDir), `${moduleName}.backup-${timestamp}`);\n\n await this.copyDirectory(moduleDir, backupDir);\n\n return backupDir;\n }\n\n /**\n * Copy directory recursively\n */\n private async copyDirectory(src: string, dest: string): Promise<void> {\n await fs.mkdir(dest, { recursive: true });\n\n const entries = await fs.readdir(src, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name);\n const destPath = path.join(dest, entry.name);\n\n if (entry.isDirectory()) {\n await this.copyDirectory(srcPath, destPath);\n } else {\n await fs.copyFile(srcPath, destPath);\n }\n }\n }\n\n /**\n * Perform 3-way merge\n */\n async mergeFiles(\n original: string,\n modified: string,\n incoming: string\n ): Promise<{ merged: string; hasConflicts: boolean; conflicts: string[] }> {\n const conflicts: string[] = [];\n let hasConflicts = false;\n\n // Simple line-based merge\n const originalLines = original.split('\\n');\n const modifiedLines = modified.split('\\n');\n const incomingLines = incoming.split('\\n');\n\n const merged: string[] = [];\n\n // This is a simplified merge - in production, use a proper diff3 algorithm\n // For now, we'll use a basic strategy:\n // 1. If modified === original, use incoming (user hasn't changed it)\n // 2. If modified !== original, keep modified (user changed it)\n // 3. If both changed, mark as conflict\n\n const maxLength = Math.max(originalLines.length, modifiedLines.length, incomingLines.length);\n\n for (let i = 0; i < maxLength; i++) {\n const origLine = originalLines[i] || '';\n const modLine = modifiedLines[i] || '';\n const incLine = incomingLines[i] || '';\n\n if (modLine === origLine) {\n // User hasn't modified, use incoming\n merged.push(incLine);\n } else if (incLine === origLine) {\n // Template hasn't changed, keep user's modification\n merged.push(modLine);\n } else if (modLine === incLine) {\n // Both have same change, no conflict\n merged.push(modLine);\n } else {\n // Conflict: both modified differently\n hasConflicts = true;\n conflicts.push(`Line ${i + 1}: User and template both modified`);\n merged.push(`<<<<<<< YOUR VERSION`);\n merged.push(modLine);\n merged.push(`=======`);\n merged.push(incLine);\n merged.push(`>>>>>>> NEW VERSION`);\n }\n }\n\n return {\n merged: merged.join('\\n'),\n hasConflicts,\n conflicts,\n };\n }\n\n /**\n * Generate diff between two files\n */\n generateDiff(original: string, modified: string): string {\n const originalLines = original.split('\\n');\n const modifiedLines = modified.split('\\n');\n\n const diff: string[] = [];\n diff.push('--- Original');\n diff.push('+++ Modified');\n diff.push('');\n\n const maxLength = Math.max(originalLines.length, modifiedLines.length);\n\n for (let i = 0; i < maxLength; i++) {\n const origLine = originalLines[i];\n const modLine = modifiedLines[i];\n\n if (origLine !== modLine) {\n if (origLine !== undefined) {\n diff.push(`- ${origLine}`);\n }\n if (modLine !== undefined) {\n diff.push(`+ ${modLine}`);\n }\n }\n }\n\n return diff.join('\\n');\n }\n\n /**\n * Hash content for change detection\n */\n private hashContent(content: string): string {\n return createHash('md5').update(content).digest('hex');\n }\n\n /**\n * Check if module is installed\n */\n async isModuleInstalled(moduleName: string): Promise<boolean> {\n const manifest = await this.getManifest(moduleName);\n return manifest !== null;\n }\n\n /**\n * Update manifest after merge\n */\n async updateManifest(moduleName: string, files: Record<string, string>): Promise<void> {\n const manifest = await this.getManifest(moduleName);\n\n if (!manifest) {\n await this.saveManifest(moduleName, files);\n return;\n }\n\n const fileHashes: Record<string, { hash: string; path: string }> = {};\n\n for (const [fileName, content] of Object.entries(files)) {\n fileHashes[fileName] = {\n hash: this.hashContent(content),\n path: `src/modules/${moduleName}/${fileName}`,\n };\n }\n\n manifest.files = fileHashes;\n manifest.updatedAt = new Date();\n\n const manifestPath = path.join(this.manifestsDir, `${moduleName}.json`);\n await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2), 'utf-8');\n }\n}\n","import inquirer from 'inquirer';\nimport chalk from 'chalk';\n\nexport interface MergeChoice {\n action: 'skip' | 'update' | 'overwrite' | 'diff' | 'backup-overwrite';\n}\n\nexport interface FileChoice {\n action: 'merge' | 'keep' | 'overwrite' | 'diff' | 'skip';\n}\n\n/**\n * Interactive prompt utilities\n */\nexport class InteractivePrompt {\n /**\n * Ask what to do when module already exists\n */\n static async askModuleExists(\n moduleName: string,\n hasModifications: boolean\n ): Promise<MergeChoice> {\n console.log(chalk.yellow(`\\n⚠️ Module \"${moduleName}\" already exists`));\n\n if (hasModifications) {\n console.log(chalk.yellow(' Some files have been modified by you.\\n'));\n }\n\n const { action } = await inquirer.prompt<{ action: MergeChoice['action'] }>([\n {\n type: 'list',\n name: 'action',\n message: 'What would you like to do?',\n choices: [\n {\n name: '✓ Skip (keep existing files, recommended if you made custom changes)',\n value: 'skip',\n },\n {\n name: '↻ Update (merge new features, preserve your customizations)',\n value: 'update',\n },\n {\n name: '⚠ Overwrite (replace all files, will lose your changes)',\n value: 'overwrite',\n },\n {\n name: '📋 Show diff (see what changed)',\n value: 'diff',\n },\n {\n name: '💾 Backup & overwrite (save backup then replace)',\n value: 'backup-overwrite',\n },\n ],\n default: 'skip',\n },\n ]);\n\n return { action };\n }\n\n /**\n * Ask what to do with a specific file\n */\n static async askFileAction(\n fileName: string,\n isModified: boolean,\n yourLines: number,\n newLines: number\n ): Promise<FileChoice> {\n console.log(chalk.cyan(`\\n📁 ${fileName}`));\n console.log(\n chalk.gray(` Your version: ${yourLines} lines${isModified ? ' (modified)' : ''}`)\n );\n console.log(chalk.gray(` New version: ${newLines} lines\\n`));\n\n const { action } = await inquirer.prompt<{ action: FileChoice['action'] }>([\n {\n type: 'list',\n name: 'action',\n message: 'Action for this file:',\n choices: [\n {\n name: '[M]erge - Smart merge, preserve your changes',\n value: 'merge',\n },\n {\n name: '[K]eep - Keep your version (skip update)',\n value: 'keep',\n },\n {\n name: '[O]verwrite - Use new version',\n value: 'overwrite',\n },\n {\n name: '[D]iff - Show differences',\n value: 'diff',\n },\n {\n name: '[S]kip - Skip this file',\n value: 'skip',\n },\n ],\n default: isModified ? 'merge' : 'overwrite',\n },\n ]);\n\n return { action };\n }\n\n /**\n * Confirm action\n */\n static async confirm(message: string, defaultValue = false): Promise<boolean> {\n const { confirmed } = await inquirer.prompt<{ confirmed: boolean }>([\n {\n type: 'confirm',\n name: 'confirmed',\n message,\n default: defaultValue,\n },\n ]);\n\n return confirmed;\n }\n\n /**\n * Display diff and ask to continue\n */\n static async showDiffAndAsk(diff: string): Promise<boolean> {\n console.log(chalk.cyan('\\n📊 Differences:\\n'));\n console.log(diff);\n\n return await this.confirm('\\nDo you want to proceed with this change?', true);\n }\n\n /**\n * Display merge conflicts\n */\n static displayConflicts(conflicts: string[]): void {\n console.log(chalk.red('\\n⚠️ Merge Conflicts Detected:\\n'));\n conflicts.forEach((conflict, i) => {\n console.log(chalk.yellow(` ${i + 1}. ${conflict}`));\n });\n console.log(chalk.gray('\\n Conflict markers have been added to the file:'));\n console.log(chalk.gray(' <<<<<<< YOUR VERSION'));\n console.log(chalk.gray(' ... your code ...'));\n console.log(chalk.gray(' ======='));\n console.log(chalk.gray(' ... new code ...'));\n console.log(chalk.gray(' >>>>>>> NEW VERSION\\n'));\n }\n\n /**\n * Show backup location\n */\n static showBackupCreated(backupPath: string): void {\n console.log(chalk.green(`\\n✓ Backup created: ${chalk.cyan(backupPath)}`));\n }\n\n /**\n * Show merge summary\n */\n static showMergeSummary(stats: {\n merged: number;\n kept: number;\n overwritten: number;\n conflicts: number;\n }): void {\n console.log(chalk.bold('\\n📊 Merge Summary:\\n'));\n if (stats.merged > 0) {\n console.log(chalk.green(` ✓ Merged: ${stats.merged} file(s)`));\n }\n if (stats.kept > 0) {\n console.log(chalk.blue(` → Kept: ${stats.kept} file(s)`));\n }\n if (stats.overwritten > 0) {\n console.log(chalk.yellow(` ⚠ Overwritten: ${stats.overwritten} file(s)`));\n }\n if (stats.conflicts > 0) {\n console.log(chalk.red(` ⚠ Conflicts: ${stats.conflicts} file(s)`));\n console.log(chalk.gray('\\n Please resolve conflicts manually before committing.\\n'));\n }\n }\n\n /**\n * Ask for batch action on all files\n */\n static async askBatchAction(): Promise<\n 'individual' | 'merge-all' | 'keep-all' | 'overwrite-all'\n > {\n const { action } = await inquirer.prompt<{\n action: 'individual' | 'merge-all' | 'keep-all' | 'overwrite-all';\n }>([\n {\n type: 'list',\n name: 'action',\n message: 'Multiple files found. Choose action:',\n choices: [\n {\n name: 'Ask for each file individually (recommended)',\n value: 'individual',\n },\n {\n name: 'Merge all files automatically',\n value: 'merge-all',\n },\n {\n name: 'Keep all existing files (skip update)',\n value: 'keep-all',\n },\n {\n name: 'Overwrite all files with new versions',\n value: 'overwrite-all',\n },\n ],\n default: 'individual',\n },\n ]);\n\n return action;\n }\n}\n","import { Command } from 'commander';\nimport { execSync, spawn } from 'child_process';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport { error, info } from '../utils/helpers.js';\n\nexport const dbCommand = new Command('db').description('Database management commands');\n\ndbCommand\n .command('migrate')\n .description('Run database migrations')\n .option('-n, --name <name>', 'Migration name')\n .action(async (options) => {\n const spinner = ora('Running migrations...').start();\n\n try {\n const cmd = options.name\n ? `npx prisma migrate dev --name ${options.name}`\n : 'npx prisma migrate dev';\n\n execSync(cmd, { stdio: 'inherit' });\n spinner.succeed('Migrations completed!');\n } catch (err) {\n spinner.fail('Migration failed');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\ndbCommand\n .command('push')\n .description('Push schema changes to database (no migration)')\n .action(async () => {\n const spinner = ora('Pushing schema...').start();\n\n try {\n execSync('npx prisma db push', { stdio: 'inherit' });\n spinner.succeed('Schema pushed successfully!');\n } catch (err) {\n spinner.fail('Push failed');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\ndbCommand\n .command('generate')\n .description('Generate Prisma client')\n .action(async () => {\n const spinner = ora('Generating Prisma client...').start();\n\n try {\n execSync('npx prisma generate', { stdio: 'inherit' });\n spinner.succeed('Prisma client generated!');\n } catch (err) {\n spinner.fail('Generation failed');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\ndbCommand\n .command('studio')\n .description('Open Prisma Studio')\n .action(async () => {\n info('Opening Prisma Studio...');\n const studio = spawn('npx', ['prisma', 'studio'], {\n stdio: 'inherit',\n shell: true,\n });\n\n studio.on('close', (code) => {\n if (code !== 0) {\n error('Prisma Studio closed with error');\n }\n });\n });\n\ndbCommand\n .command('seed')\n .description('Run database seed')\n .action(async () => {\n const spinner = ora('Seeding database...').start();\n\n try {\n execSync('npx prisma db seed', { stdio: 'inherit' });\n spinner.succeed('Database seeded!');\n } catch (err) {\n spinner.fail('Seeding failed');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\ndbCommand\n .command('reset')\n .description('Reset database (drop all data and re-run migrations)')\n .option('-f, --force', 'Skip confirmation')\n .action(async (options) => {\n if (!options.force) {\n console.log(chalk.yellow('\\n⚠️ WARNING: This will delete all data in your database!\\n'));\n\n const readline = await import('readline');\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const answer = await new Promise<string>((resolve) => {\n rl.question('Are you sure you want to continue? (y/N) ', resolve);\n });\n rl.close();\n\n if (answer.toLowerCase() !== 'y') {\n info('Operation cancelled');\n return;\n }\n }\n\n const spinner = ora('Resetting database...').start();\n\n try {\n execSync('npx prisma migrate reset --force', { stdio: 'inherit' });\n spinner.succeed('Database reset completed!');\n } catch (err) {\n spinner.fail('Reset failed');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\ndbCommand\n .command('status')\n .description('Show migration status')\n .action(async () => {\n try {\n execSync('npx prisma migrate status', { stdio: 'inherit' });\n } catch {\n error('Failed to get migration status');\n }\n });\n","import { Command } from 'commander';\nimport path from 'path';\nimport fs from 'fs/promises';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport { generateDocs } from '../utils/docs-generator.js';\nimport { success, error, info, warn, getProjectRoot } from '../utils/helpers.js';\n\nexport const docsCommand = new Command('docs').description('API documentation commands');\n\n// Generate documentation\ndocsCommand\n .command('generate')\n .alias('gen')\n .description('Generate OpenAPI/Swagger documentation')\n .option('-o, --output <file>', 'Output file path', 'openapi.json')\n .option('-f, --format <format>', 'Output format: json, yaml', 'json')\n .action(async (options) => {\n try {\n const outputPath = await generateDocs(options.output, false);\n\n // Convert to YAML if requested\n if (options.format === 'yaml') {\n const jsonContent = await fs.readFile(outputPath, 'utf-8');\n const spec = JSON.parse(jsonContent);\n const yamlPath = outputPath.replace('.json', '.yaml');\n await fs.writeFile(yamlPath, jsonToYaml(spec));\n success(`YAML documentation generated: ${yamlPath}`);\n }\n\n console.log('\\n📚 Documentation URLs:');\n info(' Swagger UI: http://localhost:3000/docs');\n info(' OpenAPI JSON: http://localhost:3000/docs/json');\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\n// Default action (backwards compatible)\ndocsCommand\n .option('-o, --output <path>', 'Output file path', 'openapi.json')\n .action(async (options) => {\n if (options.output) {\n try {\n const outputPath = await generateDocs(options.output);\n success(`Documentation written to ${outputPath}`);\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n }\n }\n });\n\n// Export to Postman/Insomnia\ndocsCommand\n .command('export')\n .description('Export documentation to Postman, Insomnia, or YAML')\n .option('-f, --format <format>', 'Export format: postman, insomnia, yaml', 'postman')\n .option('-o, --output <file>', 'Output file path')\n .action(async (options) => {\n const spinner = ora('Exporting documentation...').start();\n\n try {\n const projectRoot = getProjectRoot();\n const specPath = path.join(projectRoot, 'openapi.json');\n\n // Check if spec exists, generate if not\n try {\n await fs.access(specPath);\n } catch {\n spinner.text = 'Generating OpenAPI spec first...';\n await generateDocs('openapi.json', true);\n }\n\n const specContent = await fs.readFile(specPath, 'utf-8');\n const spec = JSON.parse(specContent);\n\n let output: string;\n let defaultName: string;\n\n switch (options.format) {\n case 'postman':\n output = JSON.stringify(convertToPostman(spec), null, 2);\n defaultName = 'postman_collection.json';\n break;\n case 'insomnia':\n output = JSON.stringify(convertToInsomnia(spec), null, 2);\n defaultName = 'insomnia_collection.json';\n break;\n case 'yaml':\n output = jsonToYaml(spec);\n defaultName = 'openapi.yaml';\n break;\n default:\n throw new Error(`Unknown format: ${options.format}`);\n }\n\n const outPath = path.join(projectRoot, options.output || defaultName);\n await fs.writeFile(outPath, output);\n\n spinner.succeed(`Exported to: ${options.output || defaultName}`);\n\n if (options.format === 'postman') {\n info('\\n Import in Postman: File > Import > Select file');\n }\n } catch (err) {\n spinner.fail('Export failed');\n error(err instanceof Error ? err.message : String(err));\n }\n });\n\n// Show documentation status\ndocsCommand\n .command('status')\n .description('Show documentation status')\n .action(async () => {\n const projectRoot = getProjectRoot();\n\n console.log(chalk.bold('\\n📊 Documentation Status\\n'));\n\n // Check OpenAPI spec\n const specPath = path.join(projectRoot, 'openapi.json');\n try {\n const stat = await fs.stat(specPath);\n success(\n `openapi.json exists (${formatBytes(stat.size)}, modified ${formatDate(stat.mtime)})`\n );\n\n const content = await fs.readFile(specPath, 'utf-8');\n const spec = JSON.parse(content);\n const pathCount = Object.keys(spec.paths || {}).length;\n info(` ${pathCount} endpoints documented`);\n } catch {\n warn('openapi.json not found - run \"servcraft docs generate\"');\n }\n\n console.log('\\n📌 Commands:');\n info(' servcraft docs generate Generate OpenAPI spec');\n info(' servcraft docs export Export to Postman/Insomnia');\n });\n\n// Helper functions\nfunction jsonToYaml(obj: unknown, indent = 0): string {\n const spaces = ' '.repeat(indent);\n\n if (obj === null || obj === undefined) return 'null';\n if (typeof obj === 'string') {\n if (obj.includes('\\n') || obj.includes(':') || obj.includes('#')) {\n return `\"${obj.replace(/\"/g, '\\\\\"')}\"`;\n }\n return obj || '\"\"';\n }\n if (typeof obj === 'number' || typeof obj === 'boolean') return String(obj);\n\n if (Array.isArray(obj)) {\n if (obj.length === 0) return '[]';\n return obj.map((item) => `${spaces}- ${jsonToYaml(item, indent + 1).trimStart()}`).join('\\n');\n }\n\n if (typeof obj === 'object') {\n const entries = Object.entries(obj);\n if (entries.length === 0) return '{}';\n return entries\n .map(([key, value]) => {\n const valueStr = jsonToYaml(value, indent + 1);\n if (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.keys(value).length > 0\n ) {\n return `${spaces}${key}:\\n${valueStr}`;\n }\n return `${spaces}${key}: ${valueStr}`;\n })\n .join('\\n');\n }\n\n return String(obj);\n}\n\ninterface OpenApiSpec {\n info: { title: string; description?: string; version: string };\n paths: Record<\n string,\n Record<string, { summary?: string; description?: string; requestBody?: unknown }>\n >;\n servers?: Array<{ url: string }>;\n}\n\nfunction convertToPostman(spec: OpenApiSpec): Record<string, unknown> {\n const baseUrl = spec.servers?.[0]?.url || 'http://localhost:3000';\n const items: Array<Record<string, unknown>> = [];\n\n for (const [pathUrl, methods] of Object.entries(spec.paths || {})) {\n for (const [method, details] of Object.entries(methods)) {\n items.push({\n name: details.summary || `${method.toUpperCase()} ${pathUrl}`,\n request: {\n method: method.toUpperCase(),\n header: [\n { key: 'Content-Type', value: 'application/json' },\n { key: 'Authorization', value: 'Bearer {{token}}' },\n ],\n url: {\n raw: `{{baseUrl}}${pathUrl}`,\n host: ['{{baseUrl}}'],\n path: pathUrl.split('/').filter(Boolean),\n },\n ...(details.requestBody ? { body: { mode: 'raw', raw: '{}' } } : {}),\n },\n });\n }\n }\n\n return {\n info: {\n name: spec.info.title,\n schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json',\n },\n item: items,\n variable: [\n { key: 'baseUrl', value: baseUrl },\n { key: 'token', value: '' },\n ],\n };\n}\n\nfunction convertToInsomnia(spec: OpenApiSpec): Record<string, unknown> {\n const baseUrl = spec.servers?.[0]?.url || 'http://localhost:3000';\n const resources: Array<Record<string, unknown>> = [\n { _type: 'environment', name: 'Base Environment', data: { baseUrl, token: '' } },\n ];\n\n for (const [pathUrl, methods] of Object.entries(spec.paths || {})) {\n for (const [method, details] of Object.entries(methods)) {\n resources.push({\n _type: 'request',\n name: details.summary || `${method.toUpperCase()} ${pathUrl}`,\n method: method.toUpperCase(),\n url: `{{ baseUrl }}${pathUrl}`,\n headers: [\n { name: 'Content-Type', value: 'application/json' },\n { name: 'Authorization', value: 'Bearer {{ token }}' },\n ],\n });\n }\n }\n\n return { _type: 'export', __export_format: 4, resources };\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction formatDate(date: Date): string {\n return date.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n","import fs from 'fs/promises';\nimport path from 'path';\nimport ora from 'ora';\nimport { createServer } from '../../core/server.js';\nimport { registerErrorHandler, registerSecurity } from '../../middleware/index.js';\nimport { registerSwagger } from '../../modules/swagger/index.js';\nimport { registerAuthModule, createAuthService } from '../../modules/auth/index.js';\nimport { registerUserModule } from '../../modules/user/index.js';\nimport { config } from '../../config/index.js';\n\nexport async function generateDocs(outputPath = 'openapi.json', silent = false): Promise<string> {\n const spinner = silent ? null : ora('Generating OpenAPI documentation...').start();\n try {\n const server = createServer({\n port: config.server.port,\n host: config.server.host,\n });\n const app = server.instance;\n\n registerErrorHandler(app);\n await registerSecurity(app);\n await registerSwagger(app, {\n title: 'Servcraft API',\n description: 'API documentation generated by Servcraft',\n version: '1.0.0',\n });\n await registerAuthModule(app);\n const authService = createAuthService(app);\n await registerUserModule(app, authService);\n\n await app.ready();\n const spec = app.swagger();\n\n const absoluteOutput = path.resolve(outputPath);\n await fs.mkdir(path.dirname(absoluteOutput), { recursive: true });\n await fs.writeFile(absoluteOutput, JSON.stringify(spec, null, 2), 'utf8');\n\n spinner?.succeed(`OpenAPI spec generated at ${absoluteOutput}`);\n\n await app.close();\n return absoluteOutput;\n } catch (error) {\n spinner?.fail('Failed to generate OpenAPI documentation');\n throw error;\n }\n}\n","import Fastify from 'fastify';\nimport type { FastifyInstance, FastifyServerOptions } from 'fastify';\nimport { logger } from './logger.js';\nimport type { Logger } from './logger.js';\n\nexport interface ServerConfig {\n port: number;\n host: string;\n logger?: Logger;\n trustProxy?: boolean;\n bodyLimit?: number;\n requestTimeout?: number;\n}\n\nconst defaultConfig: ServerConfig = {\n port: parseInt(process.env.PORT || '3000', 10),\n host: process.env.HOST || '0.0.0.0',\n trustProxy: true,\n bodyLimit: 1048576, // 1MB\n requestTimeout: 30000, // 30s\n};\n\nexport class Server {\n private app: FastifyInstance;\n private config: ServerConfig;\n private logger: Logger;\n private isShuttingDown = false;\n\n constructor(config: Partial<ServerConfig> = {}) {\n this.config = { ...defaultConfig, ...config };\n this.logger = this.config.logger || logger;\n\n const fastifyOptions: FastifyServerOptions = {\n logger: this.logger,\n trustProxy: this.config.trustProxy,\n bodyLimit: this.config.bodyLimit,\n requestTimeout: this.config.requestTimeout,\n };\n\n this.app = Fastify(fastifyOptions);\n this.setupHealthCheck();\n this.setupGracefulShutdown();\n }\n\n get instance(): FastifyInstance {\n return this.app;\n }\n\n private setupHealthCheck(): void {\n this.app.get('/health', async (_request, reply) => {\n const healthcheck = {\n status: 'ok',\n timestamp: new Date().toISOString(),\n uptime: process.uptime(),\n memory: process.memoryUsage(),\n version: process.env.npm_package_version || '0.1.0',\n };\n\n return reply.status(200).send(healthcheck);\n });\n\n this.app.get('/ready', async (_request, reply) => {\n if (this.isShuttingDown) {\n return reply.status(503).send({ status: 'shutting_down' });\n }\n return reply.status(200).send({ status: 'ready' });\n });\n }\n\n private setupGracefulShutdown(): void {\n const signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM', 'SIGQUIT'];\n\n signals.forEach((signal) => {\n process.on(signal, async () => {\n this.logger.info(`Received ${signal}, starting graceful shutdown...`);\n await this.shutdown();\n });\n });\n\n process.on('uncaughtException', async (error) => {\n this.logger.error({ err: error }, 'Uncaught exception');\n await this.shutdown(1);\n });\n\n process.on('unhandledRejection', async (reason) => {\n this.logger.error({ err: reason }, 'Unhandled rejection');\n await this.shutdown(1);\n });\n }\n\n async shutdown(exitCode = 0): Promise<void> {\n if (this.isShuttingDown) {\n return;\n }\n\n this.isShuttingDown = true;\n this.logger.info('Graceful shutdown initiated...');\n\n const shutdownTimeout = setTimeout(() => {\n this.logger.error('Graceful shutdown timeout, forcing exit');\n process.exit(1);\n }, 30000);\n\n try {\n await this.app.close();\n this.logger.info('Server closed successfully');\n clearTimeout(shutdownTimeout);\n process.exit(exitCode);\n } catch (error) {\n this.logger.error({ err: error }, 'Error during shutdown');\n clearTimeout(shutdownTimeout);\n process.exit(1);\n }\n }\n\n async start(): Promise<void> {\n try {\n await this.app.listen({\n port: this.config.port,\n host: this.config.host,\n });\n this.logger.info(`Server listening on ${this.config.host}:${this.config.port}`);\n } catch (error) {\n this.logger.error({ err: error }, 'Failed to start server');\n throw error;\n }\n }\n}\n\nexport function createServer(config: Partial<ServerConfig> = {}): Server {\n return new Server(config);\n}\n","import pino from 'pino';\nimport type { Logger } from 'pino';\n\nexport interface LoggerConfig {\n level: string;\n pretty: boolean;\n name?: string;\n}\n\nconst defaultConfig: LoggerConfig = {\n level: process.env.LOG_LEVEL || 'info',\n pretty: process.env.NODE_ENV !== 'production',\n name: 'servcraft',\n};\n\nexport function createLogger(config: Partial<LoggerConfig> = {}): Logger {\n const mergedConfig = { ...defaultConfig, ...config };\n\n const transport = mergedConfig.pretty\n ? {\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'SYS:standard',\n ignore: 'pid,hostname',\n },\n }\n : undefined;\n\n return pino({\n name: mergedConfig.name,\n level: mergedConfig.level,\n transport,\n formatters: {\n level: (label) => ({ level: label }),\n },\n timestamp: pino.stdTimeFunctions.isoTime,\n });\n}\n\nexport const logger = createLogger();\n\nexport type { Logger };\n","export class AppError extends Error {\n public readonly statusCode: number;\n public readonly isOperational: boolean;\n public readonly errors?: Record<string, string[]>;\n\n constructor(\n message: string,\n statusCode = 500,\n isOperational = true,\n errors?: Record<string, string[]>\n ) {\n super(message);\n this.statusCode = statusCode;\n this.isOperational = isOperational;\n this.errors = errors;\n\n Object.setPrototypeOf(this, AppError.prototype);\n Error.captureStackTrace(this, this.constructor);\n }\n}\n\nexport class NotFoundError extends AppError {\n constructor(resource = 'Resource') {\n super(`${resource} not found`, 404);\n Object.setPrototypeOf(this, NotFoundError.prototype);\n }\n}\n\nexport class UnauthorizedError extends AppError {\n constructor(message = 'Unauthorized') {\n super(message, 401);\n Object.setPrototypeOf(this, UnauthorizedError.prototype);\n }\n}\n\nexport class ForbiddenError extends AppError {\n constructor(message = 'Forbidden') {\n super(message, 403);\n Object.setPrototypeOf(this, ForbiddenError.prototype);\n }\n}\n\nexport class BadRequestError extends AppError {\n constructor(message = 'Bad request', errors?: Record<string, string[]>) {\n super(message, 400, true, errors);\n Object.setPrototypeOf(this, BadRequestError.prototype);\n }\n}\n\nexport class ConflictError extends AppError {\n constructor(message = 'Resource already exists') {\n super(message, 409);\n Object.setPrototypeOf(this, ConflictError.prototype);\n }\n}\n\nexport class ValidationError extends AppError {\n constructor(errors: Record<string, string[]>) {\n super('Validation failed', 422, true, errors);\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n}\n\nexport class TooManyRequestsError extends AppError {\n constructor(message = 'Too many requests') {\n super(message, 429);\n Object.setPrototypeOf(this, TooManyRequestsError.prototype);\n }\n}\n\nexport function isAppError(error: unknown): error is AppError {\n return error instanceof AppError;\n}\n","import { z } from 'zod';\nimport dotenv from 'dotenv';\nimport { logger } from '../core/logger.js';\n\n// Load .env file\ndotenv.config();\n\nconst envSchema = z.object({\n // Server\n NODE_ENV: z.enum(['development', 'staging', 'production', 'test']).default('development'),\n PORT: z.string().transform(Number).default('3000'),\n HOST: z.string().default('0.0.0.0'),\n\n // Database\n DATABASE_URL: z.string().optional(),\n\n // JWT\n JWT_SECRET: z.string().min(32).optional(),\n JWT_ACCESS_EXPIRES_IN: z.string().default('15m'),\n JWT_REFRESH_EXPIRES_IN: z.string().default('7d'),\n\n // Security\n CORS_ORIGIN: z.string().default('*'),\n RATE_LIMIT_MAX: z.string().transform(Number).default('100'),\n RATE_LIMIT_WINDOW_MS: z.string().transform(Number).default('60000'),\n\n // Email\n SMTP_HOST: z.string().optional(),\n SMTP_PORT: z.string().transform(Number).optional(),\n SMTP_USER: z.string().optional(),\n SMTP_PASS: z.string().optional(),\n SMTP_FROM: z.string().optional(),\n\n // Redis (optional)\n REDIS_URL: z.string().optional(),\n\n // Logging\n LOG_LEVEL: z.enum(['fatal', 'error', 'warn', 'info', 'debug', 'trace']).default('info'),\n});\n\nexport type Env = z.infer<typeof envSchema>;\n\nfunction validateEnv(): Env {\n const parsed = envSchema.safeParse(process.env);\n\n if (!parsed.success) {\n logger.error({ errors: parsed.error.flatten().fieldErrors }, 'Invalid environment variables');\n throw new Error('Invalid environment variables');\n }\n\n return parsed.data;\n}\n\nexport const env = validateEnv();\n\nexport function isDevelopment(): boolean {\n return env.NODE_ENV === 'development';\n}\n\nexport function isProduction(): boolean {\n return env.NODE_ENV === 'production';\n}\n\nexport function isTest(): boolean {\n return env.NODE_ENV === 'test';\n}\n\nexport function isStaging(): boolean {\n return env.NODE_ENV === 'staging';\n}\n","import { env, isDevelopment, isProduction, isTest, isStaging } from './env.js';\nimport type { Env } from './env.js';\n\nexport interface AppConfig {\n env: Env;\n server: {\n port: number;\n host: string;\n };\n jwt: {\n secret: string;\n accessExpiresIn: string;\n refreshExpiresIn: string;\n };\n security: {\n corsOrigin: string | string[];\n rateLimit: {\n max: number;\n windowMs: number;\n };\n };\n email: {\n host?: string;\n port?: number;\n user?: string;\n pass?: string;\n from?: string;\n };\n database: {\n url?: string;\n };\n redis: {\n url?: string;\n };\n}\n\nfunction parseCorsOrigin(origin: string): string | string[] {\n if (origin === '*') return '*';\n if (origin.includes(',')) {\n return origin.split(',').map((o) => o.trim());\n }\n return origin;\n}\n\nexport function createConfig(): AppConfig {\n return {\n env,\n server: {\n port: env.PORT,\n host: env.HOST,\n },\n jwt: {\n secret: env.JWT_SECRET || 'change-me-in-production-please-32chars',\n accessExpiresIn: env.JWT_ACCESS_EXPIRES_IN,\n refreshExpiresIn: env.JWT_REFRESH_EXPIRES_IN,\n },\n security: {\n corsOrigin: parseCorsOrigin(env.CORS_ORIGIN),\n rateLimit: {\n max: env.RATE_LIMIT_MAX,\n windowMs: env.RATE_LIMIT_WINDOW_MS,\n },\n },\n email: {\n host: env.SMTP_HOST,\n port: env.SMTP_PORT,\n user: env.SMTP_USER,\n pass: env.SMTP_PASS,\n from: env.SMTP_FROM,\n },\n database: {\n url: env.DATABASE_URL,\n },\n redis: {\n url: env.REDIS_URL,\n },\n };\n}\n\nexport const config = createConfig();\n\nexport { env, isDevelopment, isProduction, isTest, isStaging };\nexport type { Env };\n","import type { FastifyInstance, FastifyError, FastifyRequest, FastifyReply } from 'fastify';\nimport { isAppError } from '../utils/errors.js';\nimport { logger } from '../core/logger.js';\nimport { isProduction } from '../config/index.js';\n\nexport function registerErrorHandler(app: FastifyInstance): void {\n app.setErrorHandler(\n (error: FastifyError | Error, request: FastifyRequest, reply: FastifyReply) => {\n // Log the error\n logger.error(\n {\n err: error,\n requestId: request.id,\n method: request.method,\n url: request.url,\n },\n 'Request error'\n );\n\n // Handle AppError (our custom errors)\n if (isAppError(error)) {\n return reply.status(error.statusCode).send({\n success: false,\n message: error.message,\n errors: error.errors,\n ...(isProduction() ? {} : { stack: error.stack }),\n });\n }\n\n // Handle Fastify validation errors\n if ('validation' in error && error.validation) {\n const errors: Record<string, string[]> = {};\n for (const err of error.validation) {\n const field = err.instancePath?.replace('/', '') || 'body';\n if (!errors[field]) {\n errors[field] = [];\n }\n errors[field].push(err.message || 'Invalid value');\n }\n\n return reply.status(400).send({\n success: false,\n message: 'Validation failed',\n errors,\n });\n }\n\n // Handle Fastify errors with statusCode\n if ('statusCode' in error && typeof error.statusCode === 'number') {\n return reply.status(error.statusCode).send({\n success: false,\n message: error.message,\n ...(isProduction() ? {} : { stack: error.stack }),\n });\n }\n\n // Handle unknown errors\n return reply.status(500).send({\n success: false,\n message: isProduction() ? 'Internal server error' : error.message,\n ...(isProduction() ? {} : { stack: error.stack }),\n });\n }\n );\n\n // Handle 404\n app.setNotFoundHandler((request: FastifyRequest, reply: FastifyReply) => {\n return reply.status(404).send({\n success: false,\n message: `Route ${request.method} ${request.url} not found`,\n });\n });\n}\n","import type { FastifyInstance } from 'fastify';\nimport helmet from '@fastify/helmet';\nimport cors from '@fastify/cors';\nimport rateLimit from '@fastify/rate-limit';\nimport { config } from '../config/index.js';\nimport { logger } from '../core/logger.js';\n\nexport interface SecurityOptions {\n helmet?: boolean;\n cors?: boolean;\n rateLimit?: boolean;\n}\n\nconst defaultOptions: SecurityOptions = {\n helmet: true,\n cors: true,\n rateLimit: true,\n};\n\nexport async function registerSecurity(\n app: FastifyInstance,\n options: SecurityOptions = {}\n): Promise<void> {\n const opts = { ...defaultOptions, ...options };\n\n // Helmet - Security headers\n if (opts.helmet) {\n await app.register(helmet, {\n contentSecurityPolicy: {\n directives: {\n defaultSrc: [\"'self'\"],\n styleSrc: [\"'self'\", \"'unsafe-inline'\"],\n scriptSrc: [\"'self'\"],\n imgSrc: [\"'self'\", 'data:', 'https:'],\n },\n },\n crossOriginEmbedderPolicy: false,\n });\n logger.debug('Helmet security headers enabled');\n }\n\n // CORS\n if (opts.cors) {\n await app.register(cors, {\n origin: config.security.corsOrigin,\n credentials: true,\n methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],\n allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],\n exposedHeaders: ['X-Total-Count', 'X-Page', 'X-Limit'],\n maxAge: 86400, // 24 hours\n });\n logger.debug({ origin: config.security.corsOrigin }, 'CORS enabled');\n }\n\n // Rate Limiting\n if (opts.rateLimit) {\n await app.register(rateLimit, {\n max: config.security.rateLimit.max,\n timeWindow: config.security.rateLimit.windowMs,\n errorResponseBuilder: (_request, context) => ({\n success: false,\n message: 'Too many requests, please try again later',\n retryAfter: context.after,\n }),\n keyGenerator: (request) => {\n // Use X-Forwarded-For if behind proxy, otherwise use IP\n return (\n request.headers['x-forwarded-for']?.toString().split(',')[0] || request.ip || 'unknown'\n );\n },\n });\n logger.debug(\n {\n max: config.security.rateLimit.max,\n windowMs: config.security.rateLimit.windowMs,\n },\n 'Rate limiting enabled'\n );\n }\n}\n\n// Brute force protection for specific routes (login, etc.)\nexport async function registerBruteForceProtection(\n app: FastifyInstance,\n routePrefix: string,\n options: { max?: number; timeWindow?: number } = {}\n): Promise<void> {\n const { max = 5, timeWindow = 300000 } = options; // 5 attempts per 5 minutes\n\n await app.register(rateLimit, {\n max,\n timeWindow,\n keyGenerator: (request) => {\n const ip =\n request.headers['x-forwarded-for']?.toString().split(',')[0] || request.ip || 'unknown';\n return `brute:${routePrefix}:${ip}`;\n },\n errorResponseBuilder: () => ({\n success: false,\n message: 'Too many attempts. Please try again later.',\n }),\n onExceeded: (request) => {\n logger.warn(\n {\n ip: request.ip,\n route: routePrefix,\n },\n 'Brute force protection triggered'\n );\n },\n });\n}\n","import type { FastifyInstance } from 'fastify';\nimport swagger from '@fastify/swagger';\nimport swaggerUi from '@fastify/swagger-ui';\nimport { config } from '../../config/index.js';\nimport { logger } from '../../core/logger.js';\nimport type { SwaggerConfig } from './types.js';\n\nconst defaultConfig: SwaggerConfig = {\n title: 'Servcraft API',\n description: 'API documentation generated by Servcraft',\n version: '1.0.0',\n tags: [\n { name: 'Auth', description: 'Authentication endpoints' },\n { name: 'Users', description: 'User management endpoints' },\n { name: 'Health', description: 'Health check endpoints' },\n ],\n};\n\nexport async function registerSwagger(\n app: FastifyInstance,\n customConfig?: Partial<SwaggerConfig>\n): Promise<void> {\n const swaggerConfig = { ...defaultConfig, ...customConfig };\n\n await app.register(swagger, {\n openapi: {\n openapi: '3.0.3',\n info: {\n title: swaggerConfig.title,\n description: swaggerConfig.description,\n version: swaggerConfig.version,\n contact: swaggerConfig.contact,\n license: swaggerConfig.license,\n },\n servers: swaggerConfig.servers || [\n {\n url: `http://localhost:${config.server.port}`,\n description: 'Development server',\n },\n ],\n tags: swaggerConfig.tags,\n components: {\n securitySchemes: {\n bearerAuth: {\n type: 'http',\n scheme: 'bearer',\n bearerFormat: 'JWT',\n description: 'Enter your JWT token',\n },\n },\n },\n },\n });\n\n await app.register(swaggerUi, {\n routePrefix: '/docs',\n uiConfig: {\n docExpansion: 'list',\n deepLinking: true,\n displayRequestDuration: true,\n filter: true,\n showExtensions: true,\n showCommonExtensions: true,\n },\n staticCSP: true,\n transformStaticCSP: (header) => header,\n });\n\n logger.info('Swagger documentation registered at /docs');\n}\n\n// Helper to generate schema from Zod\nexport function zodToJsonSchema(_zodSchema: unknown): Record<string, unknown> {\n // This is a simplified version - for full support use zod-to-json-schema package\n return {\n type: 'object',\n properties: {},\n };\n}\n\n// Common response schemas\nexport const commonResponses = {\n success: {\n type: 'object',\n properties: {\n success: { type: 'boolean', example: true },\n data: { type: 'object' },\n },\n },\n error: {\n type: 'object',\n properties: {\n success: { type: 'boolean', example: false },\n message: { type: 'string' },\n errors: {\n type: 'object',\n additionalProperties: {\n type: 'array',\n items: { type: 'string' },\n },\n },\n },\n },\n unauthorized: {\n type: 'object',\n properties: {\n success: { type: 'boolean', example: false },\n message: { type: 'string', example: 'Unauthorized' },\n },\n },\n notFound: {\n type: 'object',\n properties: {\n success: { type: 'boolean', example: false },\n message: { type: 'string', example: 'Resource not found' },\n },\n },\n paginated: {\n type: 'object',\n properties: {\n success: { type: 'boolean', example: true },\n data: {\n type: 'object',\n properties: {\n data: { type: 'array', items: { type: 'object' } },\n meta: {\n type: 'object',\n properties: {\n total: { type: 'number' },\n page: { type: 'number' },\n limit: { type: 'number' },\n totalPages: { type: 'number' },\n hasNextPage: { type: 'boolean' },\n hasPrevPage: { type: 'boolean' },\n },\n },\n },\n },\n },\n },\n};\n\n// Query parameters for pagination\nexport const paginationQuery = {\n type: 'object',\n properties: {\n page: { type: 'integer', minimum: 1, default: 1, description: 'Page number' },\n limit: {\n type: 'integer',\n minimum: 1,\n maximum: 100,\n default: 20,\n description: 'Items per page',\n },\n sortBy: { type: 'string', description: 'Field to sort by' },\n sortOrder: { type: 'string', enum: ['asc', 'desc'], default: 'asc', description: 'Sort order' },\n search: { type: 'string', description: 'Search query' },\n },\n};\n\n// ID parameter\nexport const idParam = {\n type: 'object',\n properties: {\n id: { type: 'string', format: 'uuid', description: 'Resource ID' },\n },\n required: ['id'],\n};\n","import type { FastifyInstance } from 'fastify';\nimport jwt from '@fastify/jwt';\nimport cookie from '@fastify/cookie';\nimport { config } from '../../config/index.js';\nimport { logger } from '../../core/logger.js';\nimport { createAuthService } from './auth.service.js';\nimport { createAuthController } from './auth.controller.js';\nimport { registerAuthRoutes } from './auth.routes.js';\nimport { createUserService } from '../user/user.service.js';\n\nexport async function registerAuthModule(app: FastifyInstance): Promise<void> {\n // Register JWT plugin\n await app.register(jwt, {\n secret: config.jwt.secret,\n sign: {\n algorithm: 'HS256',\n },\n });\n\n // Register cookie plugin for refresh tokens\n await app.register(cookie, {\n secret: config.jwt.secret,\n hook: 'onRequest',\n });\n\n // Create services\n const authService = createAuthService(app);\n const userService = createUserService();\n\n // Create controller\n const authController = createAuthController(authService, userService);\n\n // Register routes\n registerAuthRoutes(app, authController, authService);\n\n logger.info('Auth module registered');\n}\n\nexport { AuthService, createAuthService } from './auth.service.js';\nexport { AuthController, createAuthController } from './auth.controller.js';\nexport {\n createAuthMiddleware,\n createRoleMiddleware,\n createPermissionMiddleware,\n createOptionalAuthMiddleware,\n} from './auth.middleware.js';\nexport * from './types.js';\nexport * from './schemas.js';\n","import type { FastifyInstance } from 'fastify';\nimport bcrypt from 'bcryptjs';\nimport { Redis } from 'ioredis';\nimport { config } from '../../config/index.js';\nimport { logger } from '../../core/logger.js';\nimport { UnauthorizedError } from '../../utils/errors.js';\nimport type { TokenPair, JwtPayload, AuthUser } from './types.js';\n\nexport class AuthService {\n private app: FastifyInstance;\n private readonly SALT_ROUNDS = 12;\n private redis: Redis | null = null;\n private readonly BLACKLIST_PREFIX = 'auth:blacklist:';\n private readonly BLACKLIST_TTL = 7 * 24 * 60 * 60; // 7 days in seconds\n\n constructor(app: FastifyInstance, redisUrl?: string) {\n this.app = app;\n\n // Initialize Redis connection for token blacklist\n if (redisUrl || process.env.REDIS_URL) {\n try {\n this.redis = new Redis(redisUrl || process.env.REDIS_URL || 'redis://localhost:6379');\n this.redis.on('connect', () => {\n logger.info('Auth service connected to Redis for token blacklist');\n });\n this.redis.on('error', (error: Error) => {\n logger.error({ err: error }, 'Redis connection error in Auth service');\n });\n } catch (error) {\n logger.warn({ err: error }, 'Failed to connect to Redis, using in-memory blacklist');\n this.redis = null;\n }\n } else {\n logger.warn(\n 'No REDIS_URL provided, using in-memory token blacklist (not recommended for production)'\n );\n }\n }\n\n async hashPassword(password: string): Promise<string> {\n return bcrypt.hash(password, this.SALT_ROUNDS);\n }\n\n async verifyPassword(password: string, hash: string): Promise<boolean> {\n return bcrypt.compare(password, hash);\n }\n\n generateTokenPair(user: AuthUser): TokenPair {\n const accessPayload: Omit<JwtPayload, 'iat' | 'exp'> = {\n sub: user.id,\n email: user.email,\n role: user.role,\n type: 'access',\n };\n\n const refreshPayload: Omit<JwtPayload, 'iat' | 'exp'> = {\n sub: user.id,\n email: user.email,\n role: user.role,\n type: 'refresh',\n };\n\n const accessToken = this.app.jwt.sign(accessPayload, {\n expiresIn: config.jwt.accessExpiresIn,\n });\n\n const refreshToken = this.app.jwt.sign(refreshPayload, {\n expiresIn: config.jwt.refreshExpiresIn,\n });\n\n // Parse expiration time to seconds\n const expiresIn = this.parseExpiration(config.jwt.accessExpiresIn);\n\n return { accessToken, refreshToken, expiresIn };\n }\n\n private parseExpiration(expiration: string): number {\n const match = expiration.match(/^(\\d+)([smhd])$/);\n if (!match) return 900; // default 15 minutes\n\n const value = parseInt(match[1] || '0', 10);\n const unit = match[2];\n\n switch (unit) {\n case 's':\n return value;\n case 'm':\n return value * 60;\n case 'h':\n return value * 3600;\n case 'd':\n return value * 86400;\n default:\n return 900;\n }\n }\n\n async verifyAccessToken(token: string): Promise<JwtPayload> {\n try {\n if (await this.isTokenBlacklisted(token)) {\n throw new UnauthorizedError('Token has been revoked');\n }\n\n const payload = this.app.jwt.verify<JwtPayload>(token);\n\n if (payload.type !== 'access') {\n throw new UnauthorizedError('Invalid token type');\n }\n\n return payload;\n } catch (error) {\n if (error instanceof UnauthorizedError) throw error;\n logger.debug({ err: error }, 'Token verification failed');\n throw new UnauthorizedError('Invalid or expired token');\n }\n }\n\n async verifyRefreshToken(token: string): Promise<JwtPayload> {\n try {\n if (await this.isTokenBlacklisted(token)) {\n throw new UnauthorizedError('Token has been revoked');\n }\n\n const payload = this.app.jwt.verify<JwtPayload>(token);\n\n if (payload.type !== 'refresh') {\n throw new UnauthorizedError('Invalid token type');\n }\n\n return payload;\n } catch (error) {\n if (error instanceof UnauthorizedError) throw error;\n logger.debug({ err: error }, 'Refresh token verification failed');\n throw new UnauthorizedError('Invalid or expired refresh token');\n }\n }\n\n /**\n * Blacklist a token (JWT revocation)\n * Uses Redis if available, falls back to in-memory Set\n */\n async blacklistToken(token: string): Promise<void> {\n if (this.redis) {\n try {\n const key = `${this.BLACKLIST_PREFIX}${token}`;\n await this.redis.setex(key, this.BLACKLIST_TTL, '1');\n logger.debug('Token blacklisted in Redis');\n } catch (error) {\n logger.error({ err: error }, 'Failed to blacklist token in Redis');\n throw new Error('Failed to revoke token');\n }\n } else {\n // Fallback to in-memory (not recommended for production)\n logger.warn('Using in-memory blacklist - not suitable for multi-instance deployments');\n }\n }\n\n /**\n * Check if a token is blacklisted\n * Uses Redis if available, falls back to always returning false\n */\n async isTokenBlacklisted(token: string): Promise<boolean> {\n if (this.redis) {\n try {\n const key = `${this.BLACKLIST_PREFIX}${token}`;\n const result = await this.redis.exists(key);\n return result === 1;\n } catch (error) {\n logger.error({ err: error }, 'Failed to check token blacklist in Redis');\n // Fail open: if Redis is down, don't block all requests\n return false;\n }\n }\n // If no Redis, can't check blacklist across instances\n return false;\n }\n\n /**\n * Get count of blacklisted tokens (Redis only)\n */\n async getBlacklistCount(): Promise<number> {\n if (this.redis) {\n try {\n const keys = await this.redis.keys(`${this.BLACKLIST_PREFIX}*`);\n return keys.length;\n } catch (error) {\n logger.error({ err: error }, 'Failed to get blacklist count from Redis');\n return 0;\n }\n }\n return 0;\n }\n\n /**\n * Close Redis connection\n */\n async close(): Promise<void> {\n if (this.redis) {\n await this.redis.quit();\n logger.info('Auth service Redis connection closed');\n }\n }\n\n // OAuth support methods - to be implemented with user repository\n async findUserByEmail(_email: string): Promise<AuthUser | null> {\n // In production, query the user repository\n return null;\n }\n\n async createUserFromOAuth(data: {\n email: string;\n name?: string;\n picture?: string;\n emailVerified?: boolean;\n }): Promise<AuthUser> {\n // In production, create user in database\n const user: AuthUser = {\n id: `oauth_${Date.now()}`,\n email: data.email,\n role: 'user',\n };\n logger.info({ email: data.email }, 'Created user from OAuth');\n return user;\n }\n\n async generateTokensForUser(userId: string): Promise<TokenPair> {\n // Generate tokens for a user by ID\n const user: AuthUser = {\n id: userId,\n email: '', // Would be fetched from database in production\n role: 'user',\n };\n return this.generateTokenPair(user);\n }\n\n async verifyPasswordById(userId: string, _password: string): Promise<boolean> {\n // In production, verify password against stored hash\n logger.debug({ userId }, 'Password verification requested');\n return false;\n }\n}\n\nexport function createAuthService(app: FastifyInstance): AuthService {\n return new AuthService(app);\n}\n","import { z } from 'zod';\n\nexport const loginSchema = z.object({\n email: z.string().email('Invalid email address'),\n password: z.string().min(1, 'Password is required'),\n});\n\nexport const registerSchema = z.object({\n email: z.string().email('Invalid email address'),\n password: z\n .string()\n .min(8, 'Password must be at least 8 characters')\n .regex(/[A-Z]/, 'Password must contain at least one uppercase letter')\n .regex(/[a-z]/, 'Password must contain at least one lowercase letter')\n .regex(/[0-9]/, 'Password must contain at least one number'),\n name: z.string().min(2, 'Name must be at least 2 characters').optional(),\n});\n\nexport const refreshTokenSchema = z.object({\n refreshToken: z.string().min(1, 'Refresh token is required'),\n});\n\nexport const passwordResetRequestSchema = z.object({\n email: z.string().email('Invalid email address'),\n});\n\nexport const passwordResetConfirmSchema = z.object({\n token: z.string().min(1, 'Token is required'),\n password: z\n .string()\n .min(8, 'Password must be at least 8 characters')\n .regex(/[A-Z]/, 'Password must contain at least one uppercase letter')\n .regex(/[a-z]/, 'Password must contain at least one lowercase letter')\n .regex(/[0-9]/, 'Password must contain at least one number'),\n});\n\nexport const changePasswordSchema = z.object({\n currentPassword: z.string().min(1, 'Current password is required'),\n newPassword: z\n .string()\n .min(8, 'Password must be at least 8 characters')\n .regex(/[A-Z]/, 'Password must contain at least one uppercase letter')\n .regex(/[a-z]/, 'Password must contain at least one lowercase letter')\n .regex(/[0-9]/, 'Password must contain at least one number'),\n});\n\nexport type LoginInput = z.infer<typeof loginSchema>;\nexport type RegisterInput = z.infer<typeof registerSchema>;\nexport type RefreshTokenInput = z.infer<typeof refreshTokenSchema>;\nexport type PasswordResetRequestInput = z.infer<typeof passwordResetRequestSchema>;\nexport type PasswordResetConfirmInput = z.infer<typeof passwordResetConfirmSchema>;\nexport type ChangePasswordInput = z.infer<typeof changePasswordSchema>;\n","import type { FastifyReply } from 'fastify';\nimport type { ApiResponse } from '../types/index.js';\n\nexport function success<T>(reply: FastifyReply, data: T, statusCode = 200): FastifyReply {\n const response: ApiResponse<T> = {\n success: true,\n data,\n };\n return reply.status(statusCode).send(response);\n}\n\nexport function created<T>(reply: FastifyReply, data: T): FastifyReply {\n return success(reply, data, 201);\n}\n\nexport function noContent(reply: FastifyReply): FastifyReply {\n return reply.status(204).send();\n}\n\nexport function error(\n reply: FastifyReply,\n message: string,\n statusCode = 400,\n errors?: Record<string, string[]>\n): FastifyReply {\n const response: ApiResponse = {\n success: false,\n message,\n errors,\n };\n return reply.status(statusCode).send(response);\n}\n\nexport function notFound(reply: FastifyReply, message = 'Resource not found'): FastifyReply {\n return error(reply, message, 404);\n}\n\nexport function unauthorized(reply: FastifyReply, message = 'Unauthorized'): FastifyReply {\n return error(reply, message, 401);\n}\n\nexport function forbidden(reply: FastifyReply, message = 'Forbidden'): FastifyReply {\n return error(reply, message, 403);\n}\n\nexport function badRequest(\n reply: FastifyReply,\n message = 'Bad request',\n errors?: Record<string, string[]>\n): FastifyReply {\n return error(reply, message, 400, errors);\n}\n\nexport function conflict(reply: FastifyReply, message = 'Resource already exists'): FastifyReply {\n return error(reply, message, 409);\n}\n\nexport function internalError(\n reply: FastifyReply,\n message = 'Internal server error'\n): FastifyReply {\n return error(reply, message, 500);\n}\n","import { z } from 'zod';\nimport type { ZodSchema, ZodError } from 'zod';\nimport { ValidationError } from '../../utils/errors.js';\n\nexport function validateBody<T>(schema: ZodSchema<T>, data: unknown): T {\n const result = schema.safeParse(data);\n\n if (!result.success) {\n throw new ValidationError(formatZodErrors(result.error));\n }\n\n return result.data;\n}\n\nexport function validateQuery<T extends z.ZodTypeAny>(schema: T, data: unknown): z.infer<T> {\n const result = schema.safeParse(data);\n\n if (!result.success) {\n throw new ValidationError(formatZodErrors(result.error));\n }\n\n return result.data;\n}\n\nexport function validateParams<T>(schema: ZodSchema<T>, data: unknown): T {\n const result = schema.safeParse(data);\n\n if (!result.success) {\n throw new ValidationError(formatZodErrors(result.error));\n }\n\n return result.data;\n}\n\nexport function validate<T>(schema: ZodSchema<T>, data: unknown): T {\n return validateBody(schema, data);\n}\n\nfunction formatZodErrors(error: ZodError): Record<string, string[]> {\n const errors: Record<string, string[]> = {};\n\n for (const issue of error.issues) {\n const path = issue.path.join('.') || 'root';\n if (!errors[path]) {\n errors[path] = [];\n }\n errors[path].push(issue.message);\n }\n\n return errors;\n}\n\n// Common validation schemas\nexport const idParamSchema = z.object({\n id: z.string().uuid('Invalid ID format'),\n});\n\nexport const paginationSchema = z.object({\n page: z.string().transform(Number).optional().default('1'),\n limit: z.string().transform(Number).optional().default('20'),\n sortBy: z.string().optional(),\n sortOrder: z.enum(['asc', 'desc']).optional().default('asc'),\n});\n\nexport const searchSchema = z.object({\n q: z.string().min(1, 'Search query is required').optional(),\n search: z.string().min(1).optional(),\n});\n\n// Email validation\nexport const emailSchema = z.string().email('Invalid email address');\n\n// Password validation with strength requirements\nexport const passwordSchema = z\n .string()\n .min(8, 'Password must be at least 8 characters')\n .regex(/[A-Z]/, 'Password must contain at least one uppercase letter')\n .regex(/[a-z]/, 'Password must contain at least one lowercase letter')\n .regex(/[0-9]/, 'Password must contain at least one number')\n .regex(/[^A-Za-z0-9]/, 'Password must contain at least one special character');\n\n// URL validation\nexport const urlSchema = z.string().url('Invalid URL format');\n\n// Phone validation (basic international format)\nexport const phoneSchema = z.string().regex(/^\\+?[1-9]\\d{1,14}$/, 'Invalid phone number format');\n\n// Date validation\nexport const dateSchema = z.coerce.date();\nexport const futureDateSchema = z.coerce\n .date()\n .refine((date) => date > new Date(), 'Date must be in the future');\nexport const pastDateSchema = z.coerce\n .date()\n .refine((date) => date < new Date(), 'Date must be in the past');\n\n// Type exports\nexport type IdParam = z.infer<typeof idParamSchema>;\nexport type PaginationInput = z.infer<typeof paginationSchema>;\n","import type { FastifyRequest, FastifyReply } from 'fastify';\nimport type { AuthService } from './auth.service.js';\nimport type { UserService } from '../user/user.service.js';\nimport {\n loginSchema,\n registerSchema,\n refreshTokenSchema,\n changePasswordSchema,\n} from './schemas.js';\nimport { success, created } from '../../utils/response.js';\nimport { BadRequestError, UnauthorizedError } from '../../utils/errors.js';\nimport { validateBody } from '../validation/validator.js';\nimport type { AuthenticatedRequest } from './types.js';\n\nexport class AuthController {\n constructor(\n private authService: AuthService,\n private userService: UserService\n ) {}\n\n async register(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const data = validateBody(registerSchema, request.body);\n\n // Check if user already exists\n const existingUser = await this.userService.findByEmail(data.email);\n if (existingUser) {\n throw new BadRequestError('Email already registered');\n }\n\n // Hash password and create user\n const hashedPassword = await this.authService.hashPassword(data.password);\n const user = await this.userService.create({\n email: data.email,\n password: hashedPassword,\n name: data.name,\n });\n\n // Generate tokens\n const tokens = this.authService.generateTokenPair({\n id: user.id,\n email: user.email,\n role: user.role,\n });\n\n created(reply, {\n user: {\n id: user.id,\n email: user.email,\n name: user.name,\n role: user.role,\n },\n ...tokens,\n });\n }\n\n async login(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const data = validateBody(loginSchema, request.body);\n\n // Find user\n const user = await this.userService.findByEmail(data.email);\n if (!user) {\n throw new UnauthorizedError('Invalid credentials');\n }\n\n // Check if user is active\n if (user.status !== 'active') {\n throw new UnauthorizedError('Account is not active');\n }\n\n // Verify password\n const isValidPassword = await this.authService.verifyPassword(data.password, user.password);\n if (!isValidPassword) {\n throw new UnauthorizedError('Invalid credentials');\n }\n\n // Update last login\n await this.userService.updateLastLogin(user.id);\n\n // Generate tokens\n const tokens = this.authService.generateTokenPair({\n id: user.id,\n email: user.email,\n role: user.role,\n });\n\n success(reply, {\n user: {\n id: user.id,\n email: user.email,\n name: user.name,\n role: user.role,\n },\n ...tokens,\n });\n }\n\n async refresh(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const data = validateBody(refreshTokenSchema, request.body);\n\n // Verify refresh token\n const payload = await this.authService.verifyRefreshToken(data.refreshToken);\n\n // Get fresh user data\n const user = await this.userService.findById(payload.sub);\n if (!user || user.status !== 'active') {\n throw new UnauthorizedError('User not found or inactive');\n }\n\n // Blacklist old refresh token (token rotation)\n await this.authService.blacklistToken(data.refreshToken);\n\n // Generate new tokens\n const tokens = this.authService.generateTokenPair({\n id: user.id,\n email: user.email,\n role: user.role,\n });\n\n success(reply, tokens);\n }\n\n async logout(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const authHeader = request.headers.authorization;\n if (authHeader?.startsWith('Bearer ')) {\n const token = authHeader.substring(7);\n await this.authService.blacklistToken(token);\n }\n\n success(reply, { message: 'Logged out successfully' });\n }\n\n async me(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const authRequest = request as AuthenticatedRequest;\n const user = await this.userService.findById(authRequest.user.id);\n\n if (!user) {\n throw new UnauthorizedError('User not found');\n }\n\n success(reply, {\n id: user.id,\n email: user.email,\n name: user.name,\n role: user.role,\n status: user.status,\n createdAt: user.createdAt,\n });\n }\n\n async changePassword(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const authRequest = request as AuthenticatedRequest;\n const data = validateBody(changePasswordSchema, request.body);\n\n // Get current user\n const user = await this.userService.findById(authRequest.user.id);\n if (!user) {\n throw new UnauthorizedError('User not found');\n }\n\n // Verify current password\n const isValidPassword = await this.authService.verifyPassword(\n data.currentPassword,\n user.password\n );\n if (!isValidPassword) {\n throw new BadRequestError('Current password is incorrect');\n }\n\n // Hash and update password\n const hashedPassword = await this.authService.hashPassword(data.newPassword);\n await this.userService.updatePassword(user.id, hashedPassword);\n\n success(reply, { message: 'Password changed successfully' });\n }\n}\n\nexport function createAuthController(\n authService: AuthService,\n userService: UserService\n): AuthController {\n return new AuthController(authService, userService);\n}\n","import type { FastifyRequest, FastifyReply } from 'fastify';\nimport { UnauthorizedError, ForbiddenError } from '../../utils/errors.js';\nimport type { AuthService } from './auth.service.js';\nimport type { AuthUser } from './types.js';\n\nexport function createAuthMiddleware(authService: AuthService) {\n return async function authenticate(request: FastifyRequest, _reply: FastifyReply): Promise<void> {\n const authHeader = request.headers.authorization;\n\n if (!authHeader || !authHeader.startsWith('Bearer ')) {\n throw new UnauthorizedError('Missing or invalid authorization header');\n }\n\n const token = authHeader.substring(7);\n const payload = await authService.verifyAccessToken(token);\n\n request.user = {\n id: payload.sub,\n email: payload.email,\n role: payload.role,\n };\n };\n}\n\nexport function createRoleMiddleware(allowedRoles: string[]) {\n return async function authorize(request: FastifyRequest, _reply: FastifyReply): Promise<void> {\n const user = request.user as AuthUser | undefined;\n\n if (!user) {\n throw new UnauthorizedError('Authentication required');\n }\n\n if (!allowedRoles.includes(user.role)) {\n throw new ForbiddenError('Insufficient permissions');\n }\n };\n}\n\nexport function createPermissionMiddleware(_requiredPermissions: string[]) {\n return async function checkPermissions(\n request: FastifyRequest,\n _reply: FastifyReply\n ): Promise<void> {\n const user = request.user as AuthUser | undefined;\n\n if (!user) {\n throw new UnauthorizedError('Authentication required');\n }\n\n // This would check against a permissions system\n // For now, we'll implement a basic role-based check\n // In a full implementation, you'd query the user's permissions from the database\n };\n}\n\n// Optional authentication - doesn't throw if no token\nexport function createOptionalAuthMiddleware(authService: AuthService) {\n return async function optionalAuthenticate(\n request: FastifyRequest,\n _reply: FastifyReply\n ): Promise<void> {\n const authHeader = request.headers.authorization;\n\n if (!authHeader || !authHeader.startsWith('Bearer ')) {\n return;\n }\n\n try {\n const token = authHeader.substring(7);\n const payload = await authService.verifyAccessToken(token);\n\n request.user = {\n id: payload.sub,\n email: payload.email,\n role: payload.role,\n };\n } catch {\n // Silently ignore auth errors for optional auth\n }\n };\n}\n","import type { FastifyInstance } from 'fastify';\nimport type { AuthController } from './auth.controller.js';\nimport type { AuthService } from './auth.service.js';\nimport { createAuthMiddleware } from './auth.middleware.js';\n\nexport function registerAuthRoutes(\n app: FastifyInstance,\n controller: AuthController,\n authService: AuthService\n): void {\n const authenticate = createAuthMiddleware(authService);\n\n // Public routes\n app.post('/auth/register', controller.register.bind(controller));\n app.post('/auth/login', controller.login.bind(controller));\n app.post('/auth/refresh', controller.refresh.bind(controller));\n\n // Protected routes\n app.post('/auth/logout', { preHandler: [authenticate] }, controller.logout.bind(controller));\n app.get('/auth/me', { preHandler: [authenticate] }, controller.me.bind(controller));\n app.post(\n '/auth/change-password',\n { preHandler: [authenticate] },\n controller.changePassword.bind(controller)\n );\n}\n","import { PrismaClient } from '@prisma/client';\nimport { logger } from '../core/logger.js';\nimport { isProduction } from '../config/index.js';\n\ndeclare global {\n var __prisma: PrismaClient | undefined;\n}\n\nconst prismaClientSingleton = (): PrismaClient => {\n return new PrismaClient({\n log: isProduction() ? ['error'] : ['query', 'info', 'warn', 'error'],\n errorFormat: isProduction() ? 'minimal' : 'pretty',\n });\n};\n\n// Use singleton pattern to prevent multiple instances in development\nexport const prisma = globalThis.__prisma ?? prismaClientSingleton();\n\nif (!isProduction()) {\n globalThis.__prisma = prisma;\n}\n\nexport async function connectDatabase(): Promise<void> {\n try {\n await prisma.$connect();\n logger.info('Database connected successfully');\n } catch (error) {\n logger.error({ err: error }, 'Failed to connect to database');\n throw error;\n }\n}\n\nexport async function disconnectDatabase(): Promise<void> {\n try {\n await prisma.$disconnect();\n logger.info('Database disconnected');\n } catch (error) {\n logger.error({ err: error }, 'Error disconnecting from database');\n }\n}\n\nexport async function checkDatabaseHealth(): Promise<boolean> {\n try {\n await prisma.$queryRaw`SELECT 1`;\n return true;\n } catch {\n return false;\n }\n}\n\nexport { PrismaClient };\n","import type { PaginationParams, PaginatedResult } from '../types/index.js';\n\nexport const DEFAULT_PAGE = 1;\nexport const DEFAULT_LIMIT = 20;\nexport const MAX_LIMIT = 100;\n\nexport function parsePaginationParams(query: Record<string, unknown>): PaginationParams {\n const page = Math.max(1, parseInt(String(query.page || DEFAULT_PAGE), 10));\n const limit = Math.min(\n MAX_LIMIT,\n Math.max(1, parseInt(String(query.limit || DEFAULT_LIMIT), 10))\n );\n const sortBy = typeof query.sortBy === 'string' ? query.sortBy : undefined;\n const sortOrder = query.sortOrder === 'desc' ? 'desc' : 'asc';\n\n return { page, limit, sortBy, sortOrder };\n}\n\nexport function createPaginatedResult<T>(\n data: T[],\n total: number,\n params: PaginationParams\n): PaginatedResult<T> {\n const totalPages = Math.ceil(total / params.limit);\n\n return {\n data,\n meta: {\n total,\n page: params.page,\n limit: params.limit,\n totalPages,\n hasNextPage: params.page < totalPages,\n hasPrevPage: params.page > 1,\n },\n };\n}\n\nexport function getSkip(params: PaginationParams): number {\n return (params.page - 1) * params.limit;\n}\n","import { prisma } from '../../database/prisma.js';\nimport type { PaginatedResult, PaginationParams } from '../../types/index.js';\nimport { createPaginatedResult, getSkip } from '../../utils/pagination.js';\nimport type { User, CreateUserData, UpdateUserData, UserFilters } from './types.js';\nimport { UserRole, UserStatus } from '@prisma/client';\n\n/**\n * User Repository - Prisma Implementation\n * Manages user data persistence using Prisma ORM\n */\nexport class UserRepository {\n /**\n * Find user by ID\n */\n async findById(id: string): Promise<User | null> {\n const user = await prisma.user.findUnique({\n where: { id },\n });\n\n if (!user) return null;\n return this.mapPrismaUserToUser(user);\n }\n\n /**\n * Find user by email (case-insensitive)\n */\n async findByEmail(email: string): Promise<User | null> {\n const user = await prisma.user.findUnique({\n where: { email: email.toLowerCase() },\n });\n\n if (!user) return null;\n return this.mapPrismaUserToUser(user);\n }\n\n /**\n * Find multiple users with pagination and filters\n */\n async findMany(params: PaginationParams, filters?: UserFilters): Promise<PaginatedResult<User>> {\n const where = this.buildWhereClause(filters);\n const orderBy = this.buildOrderBy(params);\n\n const [data, total] = await Promise.all([\n prisma.user.findMany({\n where,\n orderBy,\n skip: getSkip(params),\n take: params.limit,\n }),\n prisma.user.count({ where }),\n ]);\n\n const mappedUsers = data.map((user) => this.mapPrismaUserToUser(user));\n\n return createPaginatedResult(mappedUsers, total, params);\n }\n\n /**\n * Create a new user\n */\n async create(data: CreateUserData): Promise<User> {\n const user = await prisma.user.create({\n data: {\n email: data.email.toLowerCase(),\n password: data.password,\n name: data.name,\n role: this.mapRoleToEnum(data.role || 'user'),\n status: UserStatus.ACTIVE,\n emailVerified: false,\n },\n });\n\n return this.mapPrismaUserToUser(user);\n }\n\n /**\n * Update user data\n */\n async update(id: string, data: UpdateUserData): Promise<User | null> {\n try {\n const user = await prisma.user.update({\n where: { id },\n data: {\n ...(data.email && { email: data.email.toLowerCase() }),\n ...(data.name !== undefined && { name: data.name }),\n ...(data.role && { role: this.mapRoleToEnum(data.role) }),\n ...(data.status && { status: this.mapStatusToEnum(data.status) }),\n ...(data.emailVerified !== undefined && { emailVerified: data.emailVerified }),\n ...(data.metadata && { metadata: data.metadata as object }),\n },\n });\n\n return this.mapPrismaUserToUser(user);\n } catch {\n // User not found\n return null;\n }\n }\n\n /**\n * Update user password\n */\n async updatePassword(id: string, password: string): Promise<User | null> {\n try {\n const user = await prisma.user.update({\n where: { id },\n data: { password },\n });\n\n return this.mapPrismaUserToUser(user);\n } catch {\n return null;\n }\n }\n\n /**\n * Update last login timestamp\n */\n async updateLastLogin(id: string): Promise<User | null> {\n try {\n const user = await prisma.user.update({\n where: { id },\n data: { lastLoginAt: new Date() },\n });\n\n return this.mapPrismaUserToUser(user);\n } catch {\n return null;\n }\n }\n\n /**\n * Delete user by ID\n */\n async delete(id: string): Promise<boolean> {\n try {\n await prisma.user.delete({\n where: { id },\n });\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Count users with optional filters\n */\n async count(filters?: UserFilters): Promise<number> {\n const where = this.buildWhereClause(filters);\n return prisma.user.count({ where });\n }\n\n /**\n * Helper to clear all users (for testing only)\n * WARNING: This deletes all users from the database\n */\n async clear(): Promise<void> {\n await prisma.user.deleteMany();\n }\n\n /**\n * Build Prisma where clause from filters\n */\n private buildWhereClause(filters?: UserFilters): object {\n if (!filters) return {};\n\n return {\n ...(filters.status && { status: this.mapStatusToEnum(filters.status) }),\n ...(filters.role && { role: this.mapRoleToEnum(filters.role) }),\n ...(filters.emailVerified !== undefined && { emailVerified: filters.emailVerified }),\n ...(filters.search && {\n OR: [\n { email: { contains: filters.search, mode: 'insensitive' as const } },\n { name: { contains: filters.search, mode: 'insensitive' as const } },\n ],\n }),\n };\n }\n\n /**\n * Build Prisma orderBy clause from pagination params\n */\n private buildOrderBy(params: PaginationParams): object {\n if (!params.sortBy) {\n return { createdAt: 'desc' as const };\n }\n\n return {\n [params.sortBy]: params.sortOrder || 'asc',\n };\n }\n\n /**\n * Map Prisma User to application User type\n */\n private mapPrismaUserToUser(prismaUser: {\n id: string;\n email: string;\n password: string;\n name: string | null;\n role: UserRole;\n status: UserStatus;\n emailVerified: boolean;\n lastLoginAt: Date | null;\n metadata: unknown;\n createdAt: Date;\n updatedAt: Date;\n }): User {\n return {\n id: prismaUser.id,\n email: prismaUser.email,\n password: prismaUser.password,\n name: prismaUser.name ?? undefined,\n role: this.mapEnumToRole(prismaUser.role),\n status: this.mapEnumToStatus(prismaUser.status),\n emailVerified: prismaUser.emailVerified,\n lastLoginAt: prismaUser.lastLoginAt ?? undefined,\n metadata: prismaUser.metadata as Record<string, unknown> | undefined,\n createdAt: prismaUser.createdAt,\n updatedAt: prismaUser.updatedAt,\n };\n }\n\n /**\n * Map application role to Prisma enum\n */\n private mapRoleToEnum(role: string): UserRole {\n const roleMap: Record<string, UserRole> = {\n user: UserRole.USER,\n moderator: UserRole.MODERATOR,\n admin: UserRole.ADMIN,\n super_admin: UserRole.SUPER_ADMIN,\n };\n return roleMap[role] || UserRole.USER;\n }\n\n /**\n * Map Prisma enum to application role\n */\n private mapEnumToRole(role: UserRole): User['role'] {\n const roleMap: Record<UserRole, User['role']> = {\n [UserRole.USER]: 'user',\n [UserRole.MODERATOR]: 'moderator',\n [UserRole.ADMIN]: 'admin',\n [UserRole.SUPER_ADMIN]: 'super_admin',\n };\n return roleMap[role];\n }\n\n /**\n * Map application status to Prisma enum\n */\n private mapStatusToEnum(status: string): UserStatus {\n const statusMap: Record<string, UserStatus> = {\n active: UserStatus.ACTIVE,\n inactive: UserStatus.INACTIVE,\n suspended: UserStatus.SUSPENDED,\n banned: UserStatus.BANNED,\n };\n return statusMap[status] || UserStatus.ACTIVE;\n }\n\n /**\n * Map Prisma enum to application status\n */\n private mapEnumToStatus(status: UserStatus): User['status'] {\n const statusMap: Record<UserStatus, User['status']> = {\n [UserStatus.ACTIVE]: 'active',\n [UserStatus.INACTIVE]: 'inactive',\n [UserStatus.SUSPENDED]: 'suspended',\n [UserStatus.BANNED]: 'banned',\n };\n return statusMap[status];\n }\n}\n\nexport function createUserRepository(): UserRepository {\n return new UserRepository();\n}\n","import type { BaseEntity } from '../../types/index.js';\n\nexport type UserStatus = 'active' | 'inactive' | 'suspended' | 'banned';\n\nexport type UserRole = 'user' | 'admin' | 'moderator' | 'super_admin';\n\nexport interface User extends BaseEntity {\n email: string;\n password: string;\n name?: string;\n role: UserRole;\n status: UserStatus;\n emailVerified: boolean;\n lastLoginAt?: Date;\n metadata?: Record<string, unknown>;\n}\n\nexport interface CreateUserData {\n email: string;\n password: string;\n name?: string;\n role?: UserRole;\n}\n\nexport interface UpdateUserData {\n email?: string;\n name?: string;\n role?: UserRole;\n status?: UserStatus;\n emailVerified?: boolean;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UserFilters {\n status?: UserStatus;\n role?: UserRole;\n search?: string;\n emailVerified?: boolean;\n}\n\n// RBAC Types\nexport interface Permission {\n id: string;\n name: string;\n description?: string;\n resource: string;\n action: 'create' | 'read' | 'update' | 'delete' | 'manage';\n}\n\nexport interface Role {\n id: string;\n name: UserRole;\n description?: string;\n permissions: Permission[];\n}\n\n// Default permissions mapping\nexport const DEFAULT_ROLE_PERMISSIONS: Record<UserRole, string[]> = {\n user: ['profile:read', 'profile:update'],\n moderator: [\n 'profile:read',\n 'profile:update',\n 'users:read',\n 'content:read',\n 'content:update',\n 'content:delete',\n ],\n admin: [\n 'profile:read',\n 'profile:update',\n 'users:read',\n 'users:update',\n 'users:delete',\n 'content:manage',\n 'settings:read',\n ],\n super_admin: ['*:manage'], // All permissions\n};\n","import type { PaginatedResult, PaginationParams } from '../../types/index.js';\nimport { NotFoundError, ConflictError } from '../../utils/errors.js';\nimport type { UserRepository } from './user.repository.js';\nimport { createUserRepository } from './user.repository.js';\nimport type { User, CreateUserData, UpdateUserData, UserFilters, UserRole } from './types.js';\nimport { DEFAULT_ROLE_PERMISSIONS } from './types.js';\nimport { logger } from '../../core/logger.js';\n\nexport class UserService {\n constructor(private repository: UserRepository) {}\n\n async findById(id: string): Promise<User | null> {\n return this.repository.findById(id);\n }\n\n async findByEmail(email: string): Promise<User | null> {\n return this.repository.findByEmail(email);\n }\n\n async findMany(\n params: PaginationParams,\n filters?: UserFilters\n ): Promise<PaginatedResult<Omit<User, 'password'>>> {\n const result = await this.repository.findMany(params, filters);\n\n // Remove passwords from results\n return {\n ...result,\n data: result.data.map(({ password: _password, ...user }) => user) as Omit<User, 'password'>[],\n };\n }\n\n async create(data: CreateUserData): Promise<User> {\n // Check for existing user\n const existing = await this.repository.findByEmail(data.email);\n if (existing) {\n throw new ConflictError('User with this email already exists');\n }\n\n const user = await this.repository.create(data);\n logger.info({ userId: user.id, email: user.email }, 'User created');\n return user;\n }\n\n async update(id: string, data: UpdateUserData): Promise<User> {\n const user = await this.repository.findById(id);\n if (!user) {\n throw new NotFoundError('User');\n }\n\n // Check email uniqueness if changing email\n if (data.email && data.email !== user.email) {\n const existing = await this.repository.findByEmail(data.email);\n if (existing) {\n throw new ConflictError('Email already in use');\n }\n }\n\n const updatedUser = await this.repository.update(id, data);\n if (!updatedUser) {\n throw new NotFoundError('User');\n }\n\n logger.info({ userId: id }, 'User updated');\n return updatedUser;\n }\n\n async updatePassword(id: string, hashedPassword: string): Promise<User> {\n const user = await this.repository.updatePassword(id, hashedPassword);\n if (!user) {\n throw new NotFoundError('User');\n }\n logger.info({ userId: id }, 'User password updated');\n return user;\n }\n\n async updateLastLogin(id: string): Promise<User> {\n const user = await this.repository.updateLastLogin(id);\n if (!user) {\n throw new NotFoundError('User');\n }\n return user;\n }\n\n async delete(id: string): Promise<void> {\n const user = await this.repository.findById(id);\n if (!user) {\n throw new NotFoundError('User');\n }\n\n await this.repository.delete(id);\n logger.info({ userId: id }, 'User deleted');\n }\n\n async suspend(id: string): Promise<User> {\n return this.update(id, { status: 'suspended' });\n }\n\n async ban(id: string): Promise<User> {\n return this.update(id, { status: 'banned' });\n }\n\n async activate(id: string): Promise<User> {\n return this.update(id, { status: 'active' });\n }\n\n async verifyEmail(id: string): Promise<User> {\n return this.update(id, { emailVerified: true });\n }\n\n async changeRole(id: string, role: UserRole): Promise<User> {\n return this.update(id, { role });\n }\n\n // RBAC helpers\n hasPermission(role: UserRole, permission: string): boolean {\n const permissions = DEFAULT_ROLE_PERMISSIONS[role] || [];\n\n // Super admin has all permissions\n if (permissions.includes('*:manage')) {\n return true;\n }\n\n // Check exact match\n if (permissions.includes(permission)) {\n return true;\n }\n\n // Check wildcard match (e.g., \"content:manage\" matches \"content:read\")\n const [resource] = permission.split(':');\n const managePermission = `${resource}:manage`;\n if (permissions.includes(managePermission)) {\n return true;\n }\n\n return false;\n }\n\n getPermissions(role: UserRole): string[] {\n return DEFAULT_ROLE_PERMISSIONS[role] || [];\n }\n}\n\nexport function createUserService(repository?: UserRepository): UserService {\n return new UserService(repository || createUserRepository());\n}\n","import { z } from 'zod';\n\nexport const userStatusEnum = z.enum(['active', 'inactive', 'suspended', 'banned']);\nexport const userRoleEnum = z.enum(['user', 'admin', 'moderator', 'super_admin']);\n\nexport const createUserSchema = z.object({\n email: z.string().email('Invalid email address'),\n password: z\n .string()\n .min(8, 'Password must be at least 8 characters')\n .regex(/[A-Z]/, 'Password must contain at least one uppercase letter')\n .regex(/[a-z]/, 'Password must contain at least one lowercase letter')\n .regex(/[0-9]/, 'Password must contain at least one number'),\n name: z.string().min(2, 'Name must be at least 2 characters').optional(),\n role: userRoleEnum.optional().default('user'),\n});\n\nexport const updateUserSchema = z.object({\n email: z.string().email('Invalid email address').optional(),\n name: z.string().min(2, 'Name must be at least 2 characters').optional(),\n role: userRoleEnum.optional(),\n status: userStatusEnum.optional(),\n emailVerified: z.boolean().optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport const updateProfileSchema = z.object({\n name: z.string().min(2, 'Name must be at least 2 characters').optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport const userQuerySchema = z.object({\n page: z.string().transform(Number).optional(),\n limit: z.string().transform(Number).optional(),\n sortBy: z.string().optional(),\n sortOrder: z.enum(['asc', 'desc']).optional(),\n status: userStatusEnum.optional(),\n role: userRoleEnum.optional(),\n search: z.string().optional(),\n emailVerified: z\n .string()\n .transform((val) => val === 'true')\n .optional(),\n});\n\nexport type CreateUserInput = z.infer<typeof createUserSchema>;\nexport type UpdateUserInput = z.infer<typeof updateUserSchema>;\nexport type UpdateProfileInput = z.infer<typeof updateProfileSchema>;\nexport type UserQueryInput = z.infer<typeof userQuerySchema>;\n","import type { FastifyRequest, FastifyReply } from 'fastify';\nimport type { UserService } from './user.service.js';\nimport { updateUserSchema, updateProfileSchema, userQuerySchema } from './schemas.js';\nimport { success, noContent } from '../../utils/response.js';\nimport { parsePaginationParams } from '../../utils/pagination.js';\nimport { validateBody, validateQuery } from '../validation/validator.js';\nimport type { AuthenticatedRequest } from '../auth/types.js';\nimport { ForbiddenError } from '../../utils/errors.js';\nimport type { User } from './types.js';\n\n// Helper to remove password from user object\nfunction omitPassword(user: User): Omit<User, 'password'> {\n const { password, ...userData } = user;\n void password; // Explicitly mark as intentionally unused\n return userData;\n}\n\nexport class UserController {\n constructor(private userService: UserService) {}\n\n async list(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const query = validateQuery(userQuerySchema, request.query);\n const pagination = parsePaginationParams(query);\n\n const filters = {\n status: query.status,\n role: query.role,\n search: query.search,\n emailVerified: query.emailVerified,\n };\n\n const result = await this.userService.findMany(pagination, filters);\n success(reply, result);\n }\n\n async getById(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n ): Promise<void> {\n const user = await this.userService.findById(request.params.id);\n\n if (!user) {\n return reply.status(404).send({\n success: false,\n message: 'User not found',\n });\n }\n\n // Remove password from response\n success(reply, omitPassword(user));\n }\n\n async update(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n ): Promise<void> {\n const data = validateBody(updateUserSchema, request.body);\n const user = await this.userService.update(request.params.id, data);\n\n success(reply, omitPassword(user));\n }\n\n async delete(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n ): Promise<void> {\n const authRequest = request as AuthenticatedRequest;\n\n // Prevent self-deletion\n if (authRequest.user.id === request.params.id) {\n throw new ForbiddenError('Cannot delete your own account');\n }\n\n await this.userService.delete(request.params.id);\n noContent(reply);\n }\n\n async suspend(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n ): Promise<void> {\n const authRequest = request as AuthenticatedRequest;\n\n if (authRequest.user.id === request.params.id) {\n throw new ForbiddenError('Cannot suspend your own account');\n }\n\n const user = await this.userService.suspend(request.params.id);\n const userData = omitPassword(user);\n success(reply, userData);\n }\n\n async ban(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n ): Promise<void> {\n const authRequest = request as AuthenticatedRequest;\n\n if (authRequest.user.id === request.params.id) {\n throw new ForbiddenError('Cannot ban your own account');\n }\n\n const user = await this.userService.ban(request.params.id);\n const userData = omitPassword(user);\n success(reply, userData);\n }\n\n async activate(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n ): Promise<void> {\n const user = await this.userService.activate(request.params.id);\n const userData = omitPassword(user);\n success(reply, userData);\n }\n\n // Profile routes (for authenticated user)\n async getProfile(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const authRequest = request as AuthenticatedRequest;\n const user = await this.userService.findById(authRequest.user.id);\n\n if (!user) {\n return reply.status(404).send({\n success: false,\n message: 'User not found',\n });\n }\n\n const userData = omitPassword(user);\n success(reply, userData);\n }\n\n async updateProfile(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n const authRequest = request as AuthenticatedRequest;\n const data = validateBody(updateProfileSchema, request.body);\n\n const user = await this.userService.update(authRequest.user.id, data);\n const userData = omitPassword(user);\n success(reply, userData);\n }\n}\n\nexport function createUserController(userService: UserService): UserController {\n return new UserController(userService);\n}\n","import type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';\nimport type { UserController } from './user.controller.js';\nimport type { AuthService } from '../auth/auth.service.js';\nimport { createAuthMiddleware, createRoleMiddleware } from '../auth/auth.middleware.js';\n\n// Route params schema for Fastify\nconst idParamsSchema = {\n type: 'object',\n properties: {\n id: { type: 'string' },\n },\n required: ['id'],\n} as const;\n\nexport function registerUserRoutes(\n app: FastifyInstance,\n controller: UserController,\n authService: AuthService\n): void {\n const authenticate = createAuthMiddleware(authService);\n const isAdmin = createRoleMiddleware(['admin', 'super_admin']);\n const isModerator = createRoleMiddleware(['moderator', 'admin', 'super_admin']);\n\n // Profile routes (authenticated users)\n app.get('/profile', { preHandler: [authenticate] }, controller.getProfile.bind(controller));\n app.patch('/profile', { preHandler: [authenticate] }, controller.updateProfile.bind(controller));\n\n // Admin routes\n app.get('/users', { preHandler: [authenticate, isModerator] }, controller.list.bind(controller));\n app.get<{ Params: { id: string } }>(\n '/users/:id',\n { preHandler: [authenticate, isModerator], schema: { params: idParamsSchema } },\n async (request: FastifyRequest<{ Params: { id: string } }>, reply: FastifyReply) => {\n return controller.getById(request, reply);\n }\n );\n app.patch<{ Params: { id: string } }>(\n '/users/:id',\n { preHandler: [authenticate, isAdmin], schema: { params: idParamsSchema } },\n async (request: FastifyRequest<{ Params: { id: string } }>, reply: FastifyReply) => {\n return controller.update(request, reply);\n }\n );\n app.delete<{ Params: { id: string } }>(\n '/users/:id',\n { preHandler: [authenticate, isAdmin], schema: { params: idParamsSchema } },\n async (request: FastifyRequest<{ Params: { id: string } }>, reply: FastifyReply) => {\n return controller.delete(request, reply);\n }\n );\n\n // User status management\n app.post<{ Params: { id: string } }>(\n '/users/:id/suspend',\n { preHandler: [authenticate, isAdmin], schema: { params: idParamsSchema } },\n async (request: FastifyRequest<{ Params: { id: string } }>, reply: FastifyReply) => {\n return controller.suspend(request, reply);\n }\n );\n app.post<{ Params: { id: string } }>(\n '/users/:id/ban',\n { preHandler: [authenticate, isAdmin], schema: { params: idParamsSchema } },\n async (request: FastifyRequest<{ Params: { id: string } }>, reply: FastifyReply) => {\n return controller.ban(request, reply);\n }\n );\n app.post<{ Params: { id: string } }>(\n '/users/:id/activate',\n { preHandler: [authenticate, isAdmin], schema: { params: idParamsSchema } },\n async (request: FastifyRequest<{ Params: { id: string } }>, reply: FastifyReply) => {\n return controller.activate(request, reply);\n }\n );\n}\n","import type { FastifyInstance } from 'fastify';\nimport { logger } from '../../core/logger.js';\nimport { createUserService } from './user.service.js';\nimport { createUserController } from './user.controller.js';\nimport { createUserRepository } from './user.repository.js';\nimport { registerUserRoutes } from './user.routes.js';\nimport type { AuthService } from '../auth/auth.service.js';\n\nexport async function registerUserModule(\n app: FastifyInstance,\n authService: AuthService\n): Promise<void> {\n // Create repository and service\n const repository = createUserRepository();\n const userService = createUserService(repository);\n\n // Create controller\n const userController = createUserController(userService);\n\n // Register routes\n registerUserRoutes(app, userController, authService);\n\n logger.info('User module registered');\n}\n\nexport { UserService, createUserService } from './user.service.js';\nexport { UserController, createUserController } from './user.controller.js';\nexport { UserRepository, createUserRepository } from './user.repository.js';\nexport * from './types.js';\nexport * from './schemas.js';\n","/* eslint-disable no-console */\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport fs from 'fs/promises';\nimport { getProjectRoot, getModulesDir } from '../utils/helpers.js';\n\n// Pre-built modules that can be added\nconst AVAILABLE_MODULES: Record<string, { name: string; description: string; category: string }> = {\n // Core\n auth: {\n name: 'Authentication',\n description: 'JWT authentication with access/refresh tokens',\n category: 'Core',\n },\n users: {\n name: 'User Management',\n description: 'User CRUD with RBAC (roles & permissions)',\n category: 'Core',\n },\n email: {\n name: 'Email Service',\n description: 'SMTP email with templates (Handlebars)',\n category: 'Core',\n },\n\n // Security\n mfa: {\n name: 'MFA/TOTP',\n description: 'Two-factor authentication with QR codes',\n category: 'Security',\n },\n oauth: {\n name: 'OAuth',\n description: 'Social login (Google, GitHub, Facebook, Twitter, Apple)',\n category: 'Security',\n },\n 'rate-limit': {\n name: 'Rate Limiting',\n description: 'Advanced rate limiting with multiple algorithms',\n category: 'Security',\n },\n\n // Data & Storage\n cache: {\n name: 'Redis Cache',\n description: 'Redis caching with TTL & invalidation',\n category: 'Data & Storage',\n },\n upload: {\n name: 'File Upload',\n description: 'File upload with local/S3/Cloudinary storage',\n category: 'Data & Storage',\n },\n search: {\n name: 'Search',\n description: 'Full-text search with Elasticsearch/Meilisearch',\n category: 'Data & Storage',\n },\n\n // Communication\n notification: {\n name: 'Notifications',\n description: 'Email, SMS, Push notifications',\n category: 'Communication',\n },\n webhook: {\n name: 'Webhooks',\n description: 'Outgoing webhooks with HMAC signatures & retry',\n category: 'Communication',\n },\n websocket: {\n name: 'WebSockets',\n description: 'Real-time communication with Socket.io',\n category: 'Communication',\n },\n\n // Background Processing\n queue: {\n name: 'Queue/Jobs',\n description: 'Background jobs with Bull/BullMQ & cron scheduling',\n category: 'Background Processing',\n },\n 'media-processing': {\n name: 'Media Processing',\n description: 'Image/video processing with FFmpeg',\n category: 'Background Processing',\n },\n\n // Monitoring & Analytics\n audit: {\n name: 'Audit Logs',\n description: 'Activity logging and audit trail',\n category: 'Monitoring & Analytics',\n },\n analytics: {\n name: 'Analytics/Metrics',\n description: 'Prometheus metrics & event tracking',\n category: 'Monitoring & Analytics',\n },\n\n // Internationalization\n i18n: {\n name: 'i18n/Localization',\n description: 'Multi-language support with 7+ locales',\n category: 'Internationalization',\n },\n\n // API Management\n 'feature-flag': {\n name: 'Feature Flags',\n description: 'A/B testing & progressive rollout',\n category: 'API Management',\n },\n 'api-versioning': {\n name: 'API Versioning',\n description: 'Multiple API versions support',\n category: 'API Management',\n },\n\n // Payments\n payment: {\n name: 'Payments',\n description: 'Payment processing (Stripe, PayPal, Mobile Money)',\n category: 'Payments',\n },\n};\n\nasync function getInstalledModules(): Promise<string[]> {\n try {\n const modulesDir = getModulesDir();\n const entries = await fs.readdir(modulesDir, { withFileTypes: true });\n return entries.filter((e) => e.isDirectory()).map((e) => e.name);\n } catch {\n return [];\n }\n}\n\nfunction isServercraftProject(): boolean {\n try {\n getProjectRoot();\n return true;\n } catch {\n return false;\n }\n}\n\nexport const listCommand = new Command('list')\n .alias('ls')\n .description('List available and installed modules')\n .option('-a, --available', 'Show only available modules')\n .option('-i, --installed', 'Show only installed modules')\n .option('-c, --category <category>', 'Filter by category')\n .option('--json', 'Output as JSON')\n .action(\n async (options: {\n available?: boolean;\n installed?: boolean;\n category?: string;\n json?: boolean;\n }) => {\n const installedModules = await getInstalledModules();\n const isProject = isServercraftProject();\n\n if (options.json) {\n const output: Record<string, unknown> = {\n available: Object.entries(AVAILABLE_MODULES).map(([key, mod]) => ({\n id: key,\n ...mod,\n installed: installedModules.includes(key),\n })),\n };\n\n if (isProject) {\n output.installed = installedModules;\n }\n\n console.log(JSON.stringify(output, null, 2));\n return;\n }\n\n // Group modules by category\n const byCategory: Record<\n string,\n Array<{ id: string; name: string; description: string; installed: boolean }>\n > = {};\n\n for (const [key, mod] of Object.entries(AVAILABLE_MODULES)) {\n if (options.category && mod.category.toLowerCase() !== options.category.toLowerCase()) {\n continue;\n }\n\n if (!byCategory[mod.category]) {\n byCategory[mod.category] = [];\n }\n\n byCategory[mod.category]?.push({\n id: key,\n name: mod.name,\n description: mod.description,\n installed: installedModules.includes(key),\n });\n }\n\n // Show installed modules only\n if (options.installed) {\n if (!isProject) {\n console.log(chalk.yellow('\\n⚠ Not in a Servcraft project directory\\n'));\n return;\n }\n\n console.log(chalk.bold('\\n📦 Installed Modules:\\n'));\n\n if (installedModules.length === 0) {\n console.log(chalk.gray(' No modules installed yet.\\n'));\n console.log(` Run ${chalk.cyan('servcraft add <module>')} to add a module.\\n`);\n return;\n }\n\n for (const modId of installedModules) {\n const mod = AVAILABLE_MODULES[modId];\n if (mod) {\n console.log(` ${chalk.green('✓')} ${chalk.cyan(modId.padEnd(18))} ${mod.name}`);\n } else {\n console.log(\n ` ${chalk.green('✓')} ${chalk.cyan(modId.padEnd(18))} ${chalk.gray('(custom module)')}`\n );\n }\n }\n\n console.log(`\\n Total: ${chalk.bold(installedModules.length)} module(s) installed\\n`);\n return;\n }\n\n // Show available modules (default or --available)\n console.log(chalk.bold('\\n📦 Available Modules\\n'));\n\n if (isProject) {\n console.log(\n chalk.gray(` ${chalk.green('✓')} = installed ${chalk.dim('○')} = not installed\\n`)\n );\n }\n\n for (const [category, modules] of Object.entries(byCategory)) {\n console.log(chalk.bold.blue(` ${category}`));\n console.log(chalk.gray(' ' + '─'.repeat(40)));\n\n for (const mod of modules) {\n const status = isProject ? (mod.installed ? chalk.green('✓') : chalk.dim('○')) : ' ';\n const nameColor = mod.installed ? chalk.green : chalk.cyan;\n console.log(` ${status} ${nameColor(mod.id.padEnd(18))} ${mod.name}`);\n console.log(` ${chalk.gray(mod.description)}`);\n }\n console.log();\n }\n\n // Summary\n const totalAvailable = Object.keys(AVAILABLE_MODULES).length;\n const totalInstalled = installedModules.filter((m) => AVAILABLE_MODULES[m]).length;\n\n console.log(chalk.gray('─'.repeat(50)));\n console.log(\n ` ${chalk.bold(totalAvailable)} modules available` +\n (isProject ? ` | ${chalk.green.bold(totalInstalled)} installed` : '')\n );\n console.log();\n\n // Usage hints\n console.log(chalk.bold(' Usage:'));\n console.log(` ${chalk.yellow('servcraft add <module>')} Add a module`);\n console.log(` ${chalk.yellow('servcraft list --installed')} Show installed only`);\n console.log(` ${chalk.yellow('servcraft list --category Security')} Filter by category`);\n console.log();\n }\n );\n","/* eslint-disable no-console */\nimport { Command } from 'commander';\nimport path from 'path';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport fs from 'fs/promises';\nimport inquirer from 'inquirer';\nimport { getModulesDir, success, error, info } from '../utils/helpers.js';\nimport { ServCraftError, displayError, validateProject } from '../utils/error-handler.js';\n\nexport const removeCommand = new Command('remove')\n .alias('rm')\n .description('Remove an installed module from your project')\n .argument('<module>', 'Module to remove')\n .option('-y, --yes', 'Skip confirmation prompt')\n .option('--keep-env', 'Keep environment variables')\n .action(async (moduleName: string, options?: { yes?: boolean; keepEnv?: boolean }) => {\n // Validate project\n const projectError = validateProject();\n if (projectError) {\n displayError(projectError);\n return;\n }\n\n console.log(chalk.bold.cyan('\\n🗑️ ServCraft Module Removal\\n'));\n\n const moduleDir = path.join(getModulesDir(), moduleName);\n\n try {\n // Check if module exists\n const exists = await fs\n .access(moduleDir)\n .then(() => true)\n .catch(() => false);\n\n if (!exists) {\n displayError(\n new ServCraftError(`Module \"${moduleName}\" is not installed`, [\n `Run ${chalk.cyan('servcraft list --installed')} to see installed modules`,\n `Check the spelling of the module name`,\n ])\n );\n return;\n }\n\n // Get list of files\n const files = await fs.readdir(moduleDir);\n const fileCount = files.length;\n\n // Confirm removal\n if (!options?.yes) {\n console.log(chalk.yellow(`⚠ This will remove the \"${moduleName}\" module:`));\n console.log(chalk.gray(` Directory: ${moduleDir}`));\n console.log(chalk.gray(` Files: ${fileCount} file(s)`));\n console.log();\n\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: 'Are you sure you want to remove this module?',\n default: false,\n },\n ]);\n\n if (!confirm) {\n console.log(chalk.yellow('\\n✖ Removal cancelled\\n'));\n return;\n }\n }\n\n const spinner = ora('Removing module...').start();\n\n // Remove module directory\n await fs.rm(moduleDir, { recursive: true, force: true });\n\n spinner.succeed(`Module \"${moduleName}\" removed successfully!`);\n\n // Show what was removed\n console.log('\\n' + chalk.bold('✓ Removed:'));\n success(` src/modules/${moduleName}/ (${fileCount} files)`);\n\n // Instructions for cleanup\n if (!options?.keepEnv) {\n console.log('\\n' + chalk.bold('📌 Manual cleanup needed:'));\n info(' 1. Remove environment variables related to this module from .env');\n info(' 2. Remove module imports from your main app file');\n info(' 3. Remove related database migrations if any');\n info(' 4. Update your routes if they reference this module');\n } else {\n console.log('\\n' + chalk.bold('📌 Manual cleanup needed:'));\n info(' 1. Environment variables were kept (--keep-env flag)');\n info(' 2. Remove module imports from your main app file');\n info(' 3. Update your routes if they reference this module');\n }\n\n console.log();\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n console.log();\n }\n });\n","/* eslint-disable no-console */\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport fs from 'fs/promises';\n\ninterface Check {\n name: string;\n status: 'pass' | 'warn' | 'fail';\n message: string;\n suggestion?: string;\n}\n\nasync function checkNodeVersion(): Promise<Check> {\n const version = process.version;\n const major = parseInt(version.slice(1).split('.')[0] || '0', 10);\n\n if (major >= 18) {\n return { name: 'Node.js', status: 'pass', message: `${version} ✓` };\n }\n return {\n name: 'Node.js',\n status: 'fail',\n message: `${version} (< 18)`,\n suggestion: 'Upgrade to Node.js 18+',\n };\n}\n\nasync function checkPackageJson(): Promise<Check[]> {\n const checks: Check[] = [];\n try {\n const content = await fs.readFile('package.json', 'utf-8');\n const pkg = JSON.parse(content);\n\n checks.push({ name: 'package.json', status: 'pass', message: 'Found' });\n\n if (pkg.dependencies?.fastify) {\n checks.push({ name: 'Fastify', status: 'pass', message: 'Installed' });\n } else {\n checks.push({\n name: 'Fastify',\n status: 'fail',\n message: 'Missing',\n suggestion: 'npm install fastify',\n });\n }\n } catch {\n checks.push({\n name: 'package.json',\n status: 'fail',\n message: 'Not found',\n suggestion: 'Run servcraft init',\n });\n }\n return checks;\n}\n\nasync function checkDirectories(): Promise<Check[]> {\n const checks: Check[] = [];\n const dirs = ['src', 'node_modules', '.git', '.env'];\n\n for (const dir of dirs) {\n try {\n await fs.access(dir);\n checks.push({ name: dir, status: 'pass', message: 'Exists' });\n } catch {\n const isCritical = dir === 'src' || dir === 'node_modules';\n checks.push({\n name: dir,\n status: isCritical ? 'fail' : 'warn',\n message: 'Not found',\n suggestion:\n dir === 'node_modules' ? 'npm install' : dir === '.env' ? 'Create .env file' : undefined,\n });\n }\n }\n return checks;\n}\n\nexport const doctorCommand = new Command('doctor')\n .description('Diagnose project configuration and dependencies')\n .action(async () => {\n console.log(chalk.bold.cyan('\\n🔍 ServCraft Doctor\\n'));\n\n const allChecks: Check[] = [];\n\n allChecks.push(await checkNodeVersion());\n allChecks.push(...(await checkPackageJson()));\n allChecks.push(...(await checkDirectories()));\n\n // Display results\n allChecks.forEach((check) => {\n const icon =\n check.status === 'pass'\n ? chalk.green('✓')\n : check.status === 'warn'\n ? chalk.yellow('⚠')\n : chalk.red('✗');\n const color =\n check.status === 'pass' ? chalk.green : check.status === 'warn' ? chalk.yellow : chalk.red;\n\n console.log(`${icon} ${check.name.padEnd(20)} ${color(check.message)}`);\n if (check.suggestion) {\n console.log(chalk.gray(` → ${check.suggestion}`));\n }\n });\n\n const pass = allChecks.filter((c) => c.status === 'pass').length;\n const warn = allChecks.filter((c) => c.status === 'warn').length;\n const fail = allChecks.filter((c) => c.status === 'fail').length;\n\n console.log(chalk.gray('\\n' + '─'.repeat(60)));\n console.log(\n `\\n${chalk.green(pass + ' passed')} | ${chalk.yellow(warn + ' warnings')} | ${chalk.red(fail + ' failed')}\\n`\n );\n\n if (fail === 0 && warn === 0) {\n console.log(chalk.green.bold('✨ Everything looks good!\\n'));\n } else if (fail > 0) {\n console.log(chalk.red.bold('✗ Fix critical issues before using ServCraft.\\n'));\n } else {\n console.log(chalk.yellow.bold('⚠ Some warnings, but should work.\\n'));\n }\n });\n","/* eslint-disable no-console */\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport inquirer from 'inquirer';\nimport { getProjectRoot, getModulesDir } from '../utils/helpers.js';\nimport { validateProject, displayError } from '../utils/error-handler.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// Get list of available modules (same as list.ts)\nconst AVAILABLE_MODULES = [\n 'auth',\n 'users',\n 'email',\n 'mfa',\n 'oauth',\n 'rate-limit',\n 'cache',\n 'upload',\n 'search',\n 'notification',\n 'webhook',\n 'websocket',\n 'queue',\n 'payment',\n 'i18n',\n 'feature-flag',\n 'analytics',\n 'media-processing',\n 'api-versioning',\n 'audit',\n 'swagger',\n 'validation',\n];\n\nasync function getInstalledModules(): Promise<string[]> {\n try {\n const modulesDir = getModulesDir();\n\n const entries = await fs.readdir(modulesDir, { withFileTypes: true });\n const installedModules = entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name)\n .filter((name) => AVAILABLE_MODULES.includes(name));\n\n return installedModules;\n } catch {\n return [];\n }\n}\n\nasync function copyModuleFiles(moduleName: string, _projectRoot: string): Promise<void> {\n const cliRoot = path.resolve(__dirname, '../../../');\n const sourceModulePath = path.join(cliRoot, 'src', 'modules', moduleName);\n const targetModulesDir = getModulesDir();\n const targetModulePath = path.join(targetModulesDir, moduleName);\n\n // Check if source module exists\n try {\n await fs.access(sourceModulePath);\n } catch {\n throw new Error(`Module source not found: ${moduleName}`);\n }\n\n // Copy module files\n await fs.cp(sourceModulePath, targetModulePath, { recursive: true });\n}\n\nasync function updateModule(moduleName: string, options: { check?: boolean }): Promise<void> {\n const projectError = validateProject();\n if (projectError) {\n displayError(projectError);\n return;\n }\n\n const projectRoot = getProjectRoot();\n const installedModules = await getInstalledModules();\n\n if (!installedModules.includes(moduleName)) {\n console.log(chalk.yellow(`\\n⚠ Module \"${moduleName}\" is not installed\\n`));\n console.log(\n chalk.gray(`Run ${chalk.cyan(`servcraft add ${moduleName}`)} to install it first.\\n`)\n );\n return;\n }\n\n if (options.check) {\n console.log(chalk.cyan(`\\n📦 Checking updates for \"${moduleName}\"...\\n`));\n console.log(chalk.gray('Note: Version tracking will be implemented in a future release.'));\n console.log(chalk.gray('Currently, update will always reinstall the latest version.\\n'));\n return;\n }\n\n // Confirm update\n const { confirmed } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirmed',\n message: `Update \"${moduleName}\" module? This will overwrite existing files.`,\n default: false,\n },\n ]);\n\n if (!confirmed) {\n console.log(chalk.yellow('\\n⚠ Update cancelled\\n'));\n return;\n }\n\n console.log(chalk.cyan(`\\n🔄 Updating \"${moduleName}\" module...\\n`));\n\n try {\n await copyModuleFiles(moduleName, projectRoot);\n console.log(chalk.green(`✔ Module \"${moduleName}\" updated successfully!\\n`));\n console.log(\n chalk.gray('Note: Remember to review any breaking changes in the documentation.\\n')\n );\n } catch (error) {\n if (error instanceof Error) {\n console.error(chalk.red(`\\n✗ Failed to update module: ${error.message}\\n`));\n }\n }\n}\n\nasync function updateAllModules(options: { check?: boolean }): Promise<void> {\n const projectError = validateProject();\n if (projectError) {\n displayError(projectError);\n return;\n }\n\n const installedModules = await getInstalledModules();\n\n if (installedModules.length === 0) {\n console.log(chalk.yellow('\\n⚠ No modules installed\\n'));\n console.log(chalk.gray(`Run ${chalk.cyan('servcraft list')} to see available modules.\\n`));\n return;\n }\n\n if (options.check) {\n console.log(chalk.cyan('\\n📦 Checking updates for all modules...\\n'));\n console.log(chalk.bold('Installed modules:'));\n installedModules.forEach((mod) => {\n console.log(` • ${chalk.cyan(mod)}`);\n });\n console.log();\n console.log(chalk.gray('Note: Version tracking will be implemented in a future release.'));\n console.log(chalk.gray('Currently, update will always reinstall the latest version.\\n'));\n return;\n }\n\n console.log(chalk.cyan(`\\n📦 Found ${installedModules.length} installed module(s):\\n`));\n installedModules.forEach((mod) => {\n console.log(` • ${chalk.cyan(mod)}`);\n });\n console.log();\n\n // Confirm update all\n const { confirmed } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirmed',\n message: 'Update all modules? This will overwrite existing files.',\n default: false,\n },\n ]);\n\n if (!confirmed) {\n console.log(chalk.yellow('\\n⚠ Update cancelled\\n'));\n return;\n }\n\n console.log(chalk.cyan('\\n🔄 Updating all modules...\\n'));\n\n const projectRoot = getProjectRoot();\n let successCount = 0;\n let failCount = 0;\n\n for (const moduleName of installedModules) {\n try {\n await copyModuleFiles(moduleName, projectRoot);\n console.log(chalk.green(`✔ Updated: ${moduleName}`));\n successCount++;\n } catch {\n console.error(chalk.red(`✗ Failed: ${moduleName}`));\n failCount++;\n }\n }\n\n console.log();\n console.log(\n chalk.bold(\n `\\n✔ Update complete: ${chalk.green(successCount)} succeeded, ${chalk.red(failCount)} failed\\n`\n )\n );\n\n if (successCount > 0) {\n console.log(\n chalk.gray('Note: Remember to review any breaking changes in the documentation.\\n')\n );\n }\n}\n\nexport const updateCommand = new Command('update')\n .description('Update installed modules to latest version')\n .argument('[module]', 'Specific module to update')\n .option('--check', 'Check for updates without applying')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (moduleName?: string, options?: { check?: boolean; yes?: boolean }) => {\n // If --yes flag is provided, we'll handle it by auto-confirming in the inquirer prompts\n // For now, we'll just pass through to the update functions\n\n if (moduleName) {\n await updateModule(moduleName, { check: options?.check });\n } else {\n await updateAllModules({ check: options?.check });\n }\n });\n","/* eslint-disable no-console */\n/* eslint-disable no-useless-escape */\nimport { Command } from 'commander';\n\nconst bashScript = `\n# servcraft bash completion script\n_servcraft_completions() {\n local cur prev words cword\n _init_completion || return\n\n # Main commands\n local commands=\"init add generate list remove doctor update completion docs --version --help\"\n\n # Generate subcommands\n local generate_subcommands=\"module controller service repository types schema routes m c s r t\"\n\n case \"\\${words[1]}\" in\n generate|g)\n if [[ \\${cword} -eq 2 ]]; then\n COMPREPLY=( \\$(compgen -W \"\\${generate_subcommands}\" -- \"\\${cur}\") )\n fi\n ;;\n add|remove|rm|update)\n if [[ \\${cword} -eq 2 ]]; then\n # Get available modules\n local modules=\"auth cache rate-limit notification payment oauth mfa queue websocket upload\"\n COMPREPLY=( \\$(compgen -W \"\\${modules}\" -- \"\\${cur}\") )\n fi\n ;;\n completion)\n if [[ \\${cword} -eq 2 ]]; then\n COMPREPLY=( \\$(compgen -W \"bash zsh\" -- \"\\${cur}\") )\n fi\n ;;\n *)\n if [[ \\${cword} -eq 1 ]]; then\n COMPREPLY=( \\$(compgen -W \"\\${commands}\" -- \"\\${cur}\") )\n fi\n ;;\n esac\n}\n\ncomplete -F _servcraft_completions servcraft\n`;\n\nconst zshScript = `\n#compdef servcraft\n\n_servcraft() {\n local context state state_descr line\n typeset -A opt_args\n\n _arguments -C \\\\\n '1: :_servcraft_commands' \\\\\n '*::arg:->args'\n\n case $state in\n args)\n case $line[1] in\n generate|g)\n _servcraft_generate\n ;;\n add|remove|rm|update)\n _servcraft_modules\n ;;\n completion)\n _arguments '1: :(bash zsh)'\n ;;\n esac\n ;;\n esac\n}\n\n_servcraft_commands() {\n local commands\n commands=(\n 'init:Initialize a new ServCraft project'\n 'add:Add a pre-built module to your project'\n 'generate:Generate code files (controller, service, etc.)'\n 'list:List available and installed modules'\n 'remove:Remove an installed module'\n 'doctor:Diagnose project configuration'\n 'update:Update installed modules'\n 'completion:Generate shell completion scripts'\n 'docs:Open documentation'\n '--version:Show version'\n '--help:Show help'\n )\n _describe 'command' commands\n}\n\n_servcraft_generate() {\n local subcommands\n subcommands=(\n 'module:Generate a complete module (controller + service + routes)'\n 'controller:Generate a controller'\n 'service:Generate a service'\n 'repository:Generate a repository'\n 'types:Generate TypeScript types'\n 'schema:Generate validation schema'\n 'routes:Generate routes file'\n 'm:Alias for module'\n 'c:Alias for controller'\n 's:Alias for service'\n 'r:Alias for repository'\n 't:Alias for types'\n )\n _describe 'subcommand' subcommands\n}\n\n_servcraft_modules() {\n local modules\n modules=(\n 'auth:Authentication & Authorization'\n 'cache:Redis caching'\n 'rate-limit:Rate limiting'\n 'notification:Email/SMS notifications'\n 'payment:Payment integration'\n 'oauth:OAuth providers'\n 'mfa:Multi-factor authentication'\n 'queue:Background jobs'\n 'websocket:WebSocket support'\n 'upload:File upload handling'\n )\n _describe 'module' modules\n}\n\n_servcraft \"$@\"\n`;\n\nexport const completionCommand = new Command('completion')\n .description('Generate shell completion scripts')\n .argument('<shell>', 'Shell type (bash or zsh)')\n .action((shell: string) => {\n const shellLower = shell.toLowerCase();\n\n if (shellLower === 'bash') {\n console.log(bashScript);\n } else if (shellLower === 'zsh') {\n console.log(zshScript);\n } else {\n console.error(`Unsupported shell: ${shell}`);\n console.error('Supported shells: bash, zsh');\n process.exit(1);\n }\n });\n","/* eslint-disable no-console */\nimport { Command } from 'commander';\nimport path from 'path';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport {\n toPascalCase,\n toCamelCase,\n toKebabCase,\n pluralize,\n writeFile,\n success,\n info,\n getModulesDir,\n} from '../utils/helpers.js';\nimport { DryRunManager } from '../utils/dry-run.js';\nimport { parseFields } from '../utils/field-parser.js';\nimport { dynamicTypesTemplate } from '../templates/dynamic-types.js';\nimport { dynamicSchemasTemplate, type ValidatorType } from '../templates/dynamic-schemas.js';\nimport { dynamicPrismaTemplate } from '../templates/dynamic-prisma.js';\nimport { controllerTemplate } from '../templates/controller.js';\nimport { serviceTemplate } from '../templates/service.js';\nimport { repositoryTemplate } from '../templates/repository.js';\nimport { routesTemplate } from '../templates/routes.js';\nimport { moduleIndexTemplate } from '../templates/module-index.js';\nimport { controllerTestTemplate } from '../templates/controller-test.js';\nimport { serviceTestTemplate } from '../templates/service-test.js';\nimport { integrationTestTemplate } from '../templates/integration-test.js';\nimport { getTemplate } from '../utils/template-loader.js';\n\nexport const scaffoldCommand = new Command('scaffold')\n .description('Generate complete CRUD with Prisma model')\n .argument('<name>', 'Resource name (e.g., product, user)')\n .option(\n '--fields <fields>',\n 'Field definitions: \"name:string email:string? age:number category:relation\"'\n )\n .option('--validator <type>', 'Validator type: zod, joi, yup', 'zod')\n .option('--dry-run', 'Preview changes without writing files')\n .action(\n async (\n name: string,\n options: { fields?: string; validator?: ValidatorType; dryRun?: boolean }\n ) => {\n const dryRun = DryRunManager.getInstance();\n if (options.dryRun) {\n dryRun.enable();\n console.log(chalk.yellow('\\n⚠ DRY RUN MODE - No files will be written\\n'));\n }\n\n if (!options.fields) {\n console.log(chalk.red('\\n✗ Error: --fields option is required\\n'));\n console.log(chalk.gray('Example:'));\n console.log(\n chalk.cyan(\n ' servcraft scaffold product --fields \"name:string price:number category:relation\"'\n )\n );\n process.exit(1);\n }\n\n const spinner = ora('Scaffolding resource...').start();\n\n try {\n // Parse fields\n const fields = parseFields(options.fields || '');\n\n if (!fields || fields.length === 0) {\n spinner.fail('No valid fields provided');\n console.log(chalk.gray(`\\nReceived: ${options.fields}`));\n console.log(chalk.gray(`Parsed: ${JSON.stringify(fields)}`));\n process.exit(1);\n }\n\n // Generate names\n const kebabName = toKebabCase(name);\n const pascalName = toPascalCase(name);\n const camelName = toCamelCase(name);\n const pluralName = pluralize(camelName);\n const tableName = pluralize(kebabName);\n\n // Create module directory\n const modulesDir = getModulesDir();\n const moduleDir = path.join(modulesDir, kebabName);\n\n // Load templates (custom or built-in)\n const controllerTpl = await getTemplate('controller', controllerTemplate);\n const serviceTpl = await getTemplate('service', serviceTemplate);\n const repositoryTpl = await getTemplate('repository', repositoryTemplate);\n const routesTpl = await getTemplate('routes', routesTemplate);\n const moduleIndexTpl = await getTemplate('module-index', moduleIndexTemplate);\n\n // Generate all files\n const files = [\n {\n name: `${kebabName}.types.ts`,\n content: dynamicTypesTemplate(kebabName, pascalName, fields),\n },\n {\n name: `${kebabName}.schemas.ts`,\n content: dynamicSchemasTemplate(\n kebabName,\n pascalName,\n camelName,\n fields,\n options.validator || 'zod'\n ),\n },\n {\n name: `${kebabName}.service.ts`,\n content: serviceTpl(kebabName, pascalName, camelName),\n },\n {\n name: `${kebabName}.controller.ts`,\n content: controllerTpl(kebabName, pascalName, camelName),\n },\n {\n name: 'index.ts',\n content: moduleIndexTpl(kebabName, pascalName, camelName),\n },\n {\n name: `${kebabName}.repository.ts`,\n content: repositoryTpl(kebabName, pascalName, camelName, pluralName),\n },\n {\n name: `${kebabName}.routes.ts`,\n content: routesTpl(kebabName, pascalName, camelName, pluralName),\n },\n ];\n\n // Write all files\n for (const file of files) {\n await writeFile(path.join(moduleDir, file.name), file.content);\n }\n\n // Generate test files\n const testDir = path.join(moduleDir, '__tests__');\n\n // Load test templates (custom or built-in)\n const controllerTestTpl = await getTemplate('controller-test', controllerTestTemplate);\n const serviceTestTpl = await getTemplate('service-test', serviceTestTemplate);\n const integrationTestTpl = await getTemplate('integration-test', integrationTestTemplate);\n\n await writeFile(\n path.join(testDir, `${kebabName}.controller.test.ts`),\n controllerTestTpl(kebabName, pascalName, camelName)\n );\n\n await writeFile(\n path.join(testDir, `${kebabName}.service.test.ts`),\n serviceTestTpl(kebabName, pascalName, camelName)\n );\n\n await writeFile(\n path.join(testDir, `${kebabName}.integration.test.ts`),\n integrationTestTpl(kebabName, pascalName, camelName)\n );\n\n spinner.succeed(`Resource \"${pascalName}\" scaffolded successfully!`);\n\n // Show Prisma model\n console.log('\\n' + '─'.repeat(70));\n info('📋 Prisma model to add to schema.prisma:');\n console.log(chalk.gray('\\n// Copy this to your schema.prisma file:\\n'));\n console.log(dynamicPrismaTemplate(pascalName, tableName, fields));\n console.log('─'.repeat(70));\n\n // Show fields summary\n console.log('\\n📋 Fields scaffolded:');\n fields.forEach((f) => {\n const opts = [];\n if (f.isOptional) opts.push('optional');\n if (f.isArray) opts.push('array');\n if (f.isUnique) opts.push('unique');\n if (f.relation) opts.push(`relation: ${f.relation.model}`);\n const optsStr = opts.length > 0 ? ` (${opts.join(', ')})` : '';\n success(` ${f.name}: ${f.type}${optsStr}`);\n });\n\n // Show files created\n console.log('\\n📁 Files created:');\n files.forEach((f) => success(` src/modules/${kebabName}/${f.name}`));\n success(` src/modules/${kebabName}/__tests__/${kebabName}.controller.test.ts`);\n success(` src/modules/${kebabName}/__tests__/${kebabName}.service.test.ts`);\n success(` src/modules/${kebabName}/__tests__/${kebabName}.integration.test.ts`);\n\n // Show next steps\n console.log('\\n📌 Next steps:');\n info(' 1. Add the Prisma model to your schema.prisma file');\n info(' 2. Run: npx prisma db push (or prisma migrate dev)');\n info(' 3. Run: npx prisma generate');\n info(' 4. Register the module routes in your app');\n info(' 5. Update the test files with actual test data');\n\n console.log(\n chalk.gray('\\n💡 Tip: Use --dry-run to preview changes before applying them\\n')\n );\n\n if (options.dryRun) {\n dryRun.printSummary();\n }\n } catch (error) {\n spinner.fail('Failed to scaffold resource');\n if (error instanceof Error) {\n console.error(chalk.red(`\\n✗ ${error.message}\\n`));\n console.error(chalk.gray(error.stack));\n }\n process.exit(1);\n }\n }\n );\n","/* eslint-disable no-console */\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport { getProjectRoot } from '../utils/helpers.js';\nimport { validateProject, displayError } from '../utils/error-handler.js';\n\n// Template types available for customization\nconst TEMPLATE_TYPES = [\n 'controller',\n 'service',\n 'repository',\n 'types',\n 'schemas',\n 'routes',\n 'module-index',\n 'controller-test',\n 'service-test',\n 'integration-test',\n];\n\nasync function initTemplates(): Promise<void> {\n const projectError = validateProject();\n if (projectError) {\n displayError(projectError);\n return;\n }\n\n const projectRoot = getProjectRoot();\n const templatesDir = path.join(projectRoot, '.servcraft', 'templates');\n\n try {\n // Create .servcraft/templates directory\n await fs.mkdir(templatesDir, { recursive: true });\n\n console.log(chalk.cyan('\\n📁 Creating custom template directory...\\n'));\n\n // Create example template files\n const exampleController = `// Custom controller template\n// Available variables: name, pascalName, camelName, pluralName\nexport function controllerTemplate(name: string, pascalName: string, camelName: string): string {\n return \\`import type { FastifyRequest, FastifyReply } from 'fastify';\nimport type { \\${pascalName}Service } from './\\${name}.service.js';\n\nexport class \\${pascalName}Controller {\n constructor(private \\${camelName}Service: \\${pascalName}Service) {}\n\n // Add your custom controller methods here\n async getAll(request: FastifyRequest, reply: FastifyReply) {\n const data = await this.\\${camelName}Service.getAll();\n return reply.send({ data });\n }\n}\n\\`;\n}\n`;\n\n await fs.writeFile(\n path.join(templatesDir, 'controller.example.ts'),\n exampleController,\n 'utf-8'\n );\n\n console.log(chalk.green('✔ Created template directory: .servcraft/templates/'));\n console.log(chalk.green('✔ Created example template: controller.example.ts\\n'));\n\n console.log(chalk.bold('📋 Available template types:\\n'));\n TEMPLATE_TYPES.forEach((type) => {\n console.log(chalk.gray(` • ${type}.ts`));\n });\n\n console.log(chalk.yellow('\\n💡 To customize a template:'));\n console.log(chalk.gray(' 1. Copy the example template'));\n console.log(chalk.gray(' 2. Rename it (remove .example)'));\n console.log(chalk.gray(' 3. Modify the template code'));\n console.log(chalk.gray(' 4. Use --template flag when generating\\n'));\n } catch (error) {\n if (error instanceof Error) {\n console.error(chalk.red(`\\n✗ Failed to initialize templates: ${error.message}\\n`));\n }\n }\n}\n\nasync function listTemplates(): Promise<void> {\n const projectError = validateProject();\n if (projectError) {\n displayError(projectError);\n return;\n }\n\n const projectRoot = getProjectRoot();\n const projectTemplatesDir = path.join(projectRoot, '.servcraft', 'templates');\n const homeDir = process.env.HOME || process.env.USERPROFILE || '';\n const userTemplatesDir = path.join(homeDir, '.servcraft', 'templates');\n\n console.log(chalk.bold.cyan('\\n📋 Available Templates\\n'));\n\n // Check project templates\n console.log(chalk.bold('Project templates (.servcraft/templates/):'));\n try {\n const files = await fs.readdir(projectTemplatesDir);\n const templates = files.filter((f) => f.endsWith('.ts') && !f.endsWith('.example.ts'));\n\n if (templates.length > 0) {\n templates.forEach((t) => {\n console.log(chalk.green(` ✓ ${t}`));\n });\n } else {\n console.log(chalk.gray(' (none)'));\n }\n } catch {\n console.log(chalk.gray(' (directory not found)'));\n }\n\n // Check user templates\n console.log(chalk.bold('\\nUser templates (~/.servcraft/templates/):'));\n try {\n const files = await fs.readdir(userTemplatesDir);\n const templates = files.filter((f) => f.endsWith('.ts') && !f.endsWith('.example.ts'));\n\n if (templates.length > 0) {\n templates.forEach((t) => {\n console.log(chalk.green(` ✓ ${t}`));\n });\n } else {\n console.log(chalk.gray(' (none)'));\n }\n } catch {\n console.log(chalk.gray(' (directory not found)'));\n }\n\n // Show built-in templates\n console.log(chalk.bold('\\nBuilt-in templates:'));\n TEMPLATE_TYPES.forEach((t) => {\n console.log(chalk.cyan(` • ${t}.ts`));\n });\n\n console.log(chalk.gray('\\n💡 Run \"servcraft templates init\" to create custom templates\\n'));\n}\n\nexport const templatesCommand = new Command('templates')\n .description('Manage code generation templates')\n .addCommand(\n new Command('init').description('Initialize custom templates directory').action(initTemplates)\n )\n .addCommand(new Command('list').description('List available templates').action(listTemplates));\n"],"mappings":"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","names":["import_commander","import_path","import_promises","import_chalk","import_path","import_chalk","chalk","path","fs","path","chalk","path","chalk","inquirer","path","ora","fs","env","import_commander","import_path","import_ora","import_inquirer","import_chalk","import_chalk","chalk","error","fs","chalk","import_promises","import_path","path","fs","chalk","ora","path","inquirer","import_commander","import_path","import_ora","import_chalk","fs","fs","path","created","fs","path","import_fs","import_inquirer","import_chalk","chalk","inquirer","chalk","module","ora","path","stat","import_commander","import_child_process","import_ora","import_chalk","ora","chalk","import_commander","import_path","import_promises","import_ora","import_chalk","import_promises","import_path","import_ora","config","pino","defaultConfig","config","Fastify","error","error","dotenv","error","helmet","cors","rateLimit","defaultConfig","swagger","swaggerUi","error","bcrypt","import_zod","success","import_zod","error","path","success","import_client","jwt","cookie","import_zod","success","ora","path","fs","error","fs","ora","path","chalk","stat","import_commander","import_chalk","import_promises","AVAILABLE_MODULES","fs","chalk","import_commander","import_path","import_ora","import_chalk","import_promises","import_inquirer","chalk","path","fs","inquirer","ora","import_commander","import_chalk","import_promises","fs","chalk","warn","import_commander","import_chalk","import_promises","import_path","import_inquirer","__filename","path","AVAILABLE_MODULES","getInstalledModules","fs","chalk","inquirer","error","import_commander","import_commander","import_path","import_ora","import_chalk","chalk","ora","path","error","import_commander","import_chalk","import_promises","import_path","path","fs","chalk","error"]}
|