UNPKG

@misterzik/espressojs

Version:

EspressoJS Introducing Espresso.JS, your ultimate Express configuration starting point and boilerplate. With its simplicity and lack of opinionation, EspressoJS offers plug-and-play configurations built on top of Express.

211 lines (188 loc) 6.63 kB
/* * _| _| _| _| _|_|_| * _| _| _|_| _|_| _| _| * _| _| _| _| _| _| _| * _| _| _| _| _| _| * _| _| _| _|_|_| * EspressoJS - CLI */ const { exec, spawn } = require("child_process"); const { string, number, boolean } = require("yargs"); const yargs = require("yargs"); const fs = require("fs"); const path = require("path"); const { readConfigFile, writeConfigFile, vmdLogo, getDefaultConfig } = require("./config.utils"); const cfgB = readConfigFile(); function showCommand() { console.log("\n╔═══════════════════════════════════════════════════════╗"); console.log("║ ESPRESSO.JS CONFIGURATION ║"); console.log("╚═══════════════════════════════════════════════════════╝\n"); console.log(JSON.stringify(cfgB, null, 2)); console.log("\n"); } function runCommand() { if (cfgB !== undefined) { console.log('\n╔═══════════════════════════════════════════════════════╗'); console.log('║ ESPRESSO.JS CLI ║'); console.log('╚═══════════════════════════════════════════════════════╝\n'); console.log('🚀 Starting server...\n'); console.log(`📋 Configuration:`); console.log(` Environment: ${cfgB.instance}`); console.log(` Port: ${cfgB.port}`); console.log(` URL: http://localhost:${cfgB.port}`); console.log(` MongoDB: ${cfgB.mongoDB?.enabled ? '✓ Enabled' : '✗ Disabled'}`); console.log(` API: ${cfgB.api?.enabled ? '✓ Enabled' : '✗ Disabled'}`); const apiCount = Object.keys(cfgB).filter(key => key.match(/^api\d*$/)).length; if (apiCount > 1) { console.log(` API Endpoints: ${apiCount} configured`); } console.log('\n💡 Press CTRL+C to stop the server\n'); console.log('─'.repeat(55) + '\n'); const child = spawn( "node", ["index.js"], { stdio: "inherit", shell: false, env: { ...process.env, NODE_ENV: cfgB.instance, PORT: cfgB.port.toString() } } ); child.on("error", (error) => { console.error(`Error starting server: ${error.message}`); process.exit(1); }); child.on("exit", (code, signal) => { if (signal) { console.log(`Server process killed with signal ${signal}`); } else if (code !== 0) { console.error(`Server process exited with code ${code}`); } else { console.log(`Server process exited cleanly`); } process.exit(code || 0); }); // Keep the CLI process alive by handling signals process.on('SIGINT', () => { console.log('\nShutting down server...'); child.kill('SIGINT'); }); process.on('SIGTERM', () => { child.kill('SIGTERM'); }); // Prevent the process from exiting by keeping stdin open // This ensures the CLI stays alive as long as the child process is running process.stdin.resume(); } } function envCommand(argv) { try { if (argv.instance !== undefined) { cfgB.instance = argv.instance; console.log(`✓ Instance set to: ${argv.instance}`); } if (argv.port !== undefined && cfgB.port !== argv.port) { cfgB.port = argv.port; console.log(`✓ Port set to: ${argv.port}`); } writeConfigFile(cfgB); console.log("✓ Configuration saved successfully"); } catch (error) { console.error(`✗ Error saving configuration: ${error.message}`); process.exit(1); } } function initCommand(argv) { const configPath = path.join(process.cwd(), "config.json"); if (fs.existsSync(configPath) && !argv.force) { console.error("✗ config.json already exists. Use --force to overwrite."); process.exit(1); } const defaultConfig = getDefaultConfig(); writeConfigFile(defaultConfig); console.log("✓ config.json created successfully"); console.log("\nDefault configuration:"); console.log(JSON.stringify(defaultConfig, null, 2)); } function validateCommand() { try { const configPath = path.join(process.cwd(), "config.json"); if (!fs.existsSync(configPath)) { console.error("✗ config.json not found"); process.exit(1); } readConfigFile(); console.log("✓ Configuration is valid"); } catch (error) { console.error(`✗ Configuration validation failed: ${error.message}`); process.exit(1); } } function versionCommand() { const packagePath = path.join(__dirname, "../../package.json"); const pkg = JSON.parse(fs.readFileSync(packagePath, "utf8")); console.log(`\nEspressoJS v${pkg.version}`); console.log(`Node ${process.version}`); console.log(`Platform: ${process.platform}\n`); } yargs .scriptName("espresso") .usage("$0 <command> [options]") .command({ command: "show", describe: "Show current configuration", handler: showCommand, }) .command({ command: "run", describe: "Run the Express server with current configuration", handler: runCommand, }) .command({ command: "env", describe: "Update environment configuration", builder: { instance: { describe: "Instance to run: development, production, or global", demandOption: false, type: string, choices: ["development", "production", "global"], }, port: { describe: "Port number for the server", demandOption: false, type: number, }, }, handler: envCommand, }) .command({ command: "init", describe: "Initialize a new config.json file", builder: { force: { describe: "Overwrite existing config.json", type: boolean, default: false, }, }, handler: initCommand, }) .command({ command: "validate", describe: "Validate the current configuration", handler: validateCommand, }) .command({ command: "version", describe: "Show version information", handler: versionCommand, }) .demandCommand(1, "You need to specify a command") .help() .alias("h", "help") .alias("v", "version") .parse();