UNPKG

mockey-patcher-cli

Version:

Global CLI tool for managing Mockey Patcher backend services with Docker Compose - API mocking and request redirection made simple

403 lines (360 loc) • 12.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.setupCommand = setupCommand; const fs = __importStar(require("fs-extra")); const path = __importStar(require("path")); const inquirer_1 = __importDefault(require("inquirer")); const logger_1 = require("../utils/logger"); const config_1 = require("../utils/config"); async function setupCommand(options) { try { logger_1.Logger.header("Mockey Patcher Setup"); const currentPath = process.cwd(); let projectName = options.projectName; let projectPath; // Get project name if not provided if (!projectName && options.interactive !== false) { const answers = await inquirer_1.default.prompt([ { type: "input", name: "projectName", message: "Enter project name:", default: "my-mockey-patcher", validate: (input) => { if (!input.trim()) { return "Project name cannot be empty"; } if (!/^[a-zA-Z0-9-_]+$/.test(input)) { return "Project name can only contain letters, numbers, hyphens, and underscores"; } return true; }, }, ]); projectName = answers.projectName; } // Use default if still not provided if (!projectName) { projectName = "my-mockey-patcher"; } // Create project path projectPath = path.join(currentPath, projectName); // Check if project directory already exists if (fs.existsSync(projectPath)) { if (!options.force) { if (options.interactive !== false) { const { overwrite } = await inquirer_1.default.prompt([ { type: "confirm", name: "overwrite", message: `Directory '${projectName}' already exists. Continue anyway?`, default: false, }, ]); if (!overwrite) { logger_1.Logger.info("Setup cancelled"); return; } } else { logger_1.Logger.error(`Directory '${projectName}' already exists. Use --force to overwrite.`); return; } } } // Create project directory await fs.ensureDir(projectPath); logger_1.Logger.info(`Created project directory: ${projectPath}`); // Change to project directory for configuration process.chdir(projectPath); // Initialize configuration let config; const configPath = path.join(projectPath, ".redirector.json"); if (fs.existsSync(configPath) && !options.force) { config = await config_1.ConfigManager.loadConfig(projectPath); logger_1.Logger.info("Loaded existing configuration"); } else { config = { backendPort: options.port || 3000, postgresPort: options.postgresPort || 5432, dockerUsername: options.dockerUsername || "shivarajbakale", projectName: projectName, environment: "production", }; } // Interactive configuration if enabled if (options.interactive !== false) { const answers = await inquirer_1.default.prompt([ { type: "number", name: "backendPort", message: "Backend API port:", default: config.backendPort, validate: (input) => { if (input < 1 || input > 65535) { return "Port must be between 1 and 65535"; } return true; }, }, { type: "number", name: "postgresPort", message: "PostgreSQL port:", default: config.postgresPort, validate: (input) => { if (input < 1 || input > 65535) { return "Port must be between 1 and 65535"; } return true; }, }, { type: "input", name: "dockerUsername", message: "Docker Hub username:", default: config.dockerUsername, }, ]); config = { ...config, ...answers }; } // Override with CLI options if (options.port) config.backendPort = options.port; if (options.postgresPort) config.postgresPort = options.postgresPort; if (options.dockerUsername) config.dockerUsername = options.dockerUsername; // Save configuration await config_1.ConfigManager.saveConfig(config, projectPath); logger_1.Logger.success("Configuration saved"); // Generate project files await generateProjectFiles(config, projectPath); logger_1.Logger.success(`\nšŸŽ‰ Mockey Patcher project '${projectName}' initialized successfully!`); logger_1.Logger.info(`\nNext steps:`); logger_1.Logger.info(` cd ${projectName}`); logger_1.Logger.info(` mockey-patcher start`); logger_1.Logger.info(`\nAPI will be available at: http://localhost:${config.backendPort}`); logger_1.Logger.info(`Health check: http://localhost:${config.backendPort}/health`); // Change back to original directory process.chdir(currentPath); } catch (error) { logger_1.Logger.error(`Setup failed: ${error}`); throw error; } } async function generateProjectFiles(config, projectPath) { try { logger_1.Logger.info("Generating project files..."); // Generate docker-compose.yml await fs.writeFile(path.join(projectPath, "docker-compose.yml"), generateDockerComposeTemplate(config)); logger_1.Logger.info("āœ“ Generated docker-compose.yml"); // Generate .env file await config_1.ConfigManager.createEnvFile(config, projectPath); logger_1.Logger.info("āœ“ Generated .env"); // Generate .gitignore await fs.writeFile(path.join(projectPath, ".gitignore"), generateGitignoreTemplate()); logger_1.Logger.info("āœ“ Generated .gitignore"); // Generate README.md await fs.writeFile(path.join(projectPath, "README.md"), generateReadmeTemplate(config)); logger_1.Logger.info("āœ“ Generated README.md"); // Create data directory await fs.ensureDir(path.join(projectPath, "data")); logger_1.Logger.success("All project files generated successfully"); } catch (error) { logger_1.Logger.error(`Failed to generate project files: ${error}`); throw error; } } function generateDockerComposeTemplate(config) { return `services: postgres: image: postgres:15 environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: redirector ports: - "\${POSTGRES_PORT:-${config.postgresPort}}:5432" volumes: - postgres_data:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -d redirector"] interval: 10s timeout: 5s retries: 5 start_period: 30s backend: image: \${DOCKER_USERNAME:-${config.dockerUsername}}/redirector-backend:latest ports: - "\${BACKEND_PORT:-${config.backendPort}}:3000" depends_on: postgres: condition: service_healthy environment: - NODE_ENV=${config.environment} - DATABASE_URL=postgresql://postgres:postgres@postgres:5432/redirector restart: unless-stopped healthcheck: test: [ "CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1", ] interval: 30s timeout: 10s retries: 3 start_period: 40s volumes: postgres_data: `; } function generateGitignoreTemplate() { return `# Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* # Runtime data pids *.pid *.seed *.pid.lock # Directory for instrumented libs generated by jscoverage/JSCover lib-cov # Coverage directory used by tools like istanbul coverage # nyc test coverage .nyc_output # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) .grunt # Bower dependency directory (https://bower.io/) bower_components # node-files dependency directory (https://github.com/pledbrook/node-files) node_modules/ # TypeScript v1 declaration files typings/ # Optional npm cache directory .npm # Optional eslint cache .eslintcache # Microbundle cache .rpt2_cache/ .rts2_cache_cjs/ .rts2_cache_es/ .rts2_cache_umd/ # Optional REPL history .node_repl_history # Output of 'npm pack' *.tgz # Yarn Integrity file .yarn-integrity # dotenv environment variables file .env .env.test .env.local .env.production # parcel-bundler cache (https://parceljs.org/) .cache .parcel-cache # next.js build output .next # nuxt.js build output .nuxt # vuepress build output .vuepress/dist # Serverless directories .serverless/ # FuseBox cache .fusebox/ # DynamoDB Local files .dynamodb/ # TernJS port file .tern-port # Docker volumes data/ # Mockey Patcher specific .redirector.json `; } function generateReadmeTemplate(config) { return `# Mockey Patcher Backend This project was initialized with \`mockey-patcher-cli\`. ## Quick Start \`\`\`bash # Start services mockey-patcher start # Check status mockey-patcher status # View logs mockey-patcher logs # Stop services mockey-patcher stop \`\`\` ## Available Commands - \`mockey-patcher setup\` - Initialize project configuration - \`mockey-patcher start\` - Start all services - \`mockey-patcher stop\` - Stop all services - \`mockey-patcher restart\` - Restart all services - \`mockey-patcher reset\` - Reset all data and volumes - \`mockey-patcher status\` - Show service status - \`mockey-patcher logs [service]\` - View service logs ## Configuration The project uses environment variables for configuration: - \`BACKEND_PORT\` - Backend API port (default: ${config.backendPort}) - \`POSTGRES_PORT\` - PostgreSQL port (default: ${config.postgresPort}) - \`DOCKER_USERNAME\` - Docker Hub username (default: ${config.dockerUsername}) ## Services - **Backend API**: Available at http://localhost:${config.backendPort} - **PostgreSQL**: Available at localhost:${config.postgresPort} - **Health Check**: http://localhost:${config.backendPort}/health ## API Endpoints - \`GET /health\` - Health check - \`GET /groups\` - List groups - \`POST /groups/create\` - Create group - \`GET /requests\` - List requests For more information, visit: https://github.com/shivarajbakale/redirector-app `; } //# sourceMappingURL=setup.js.map