UNPKG

@pulzar/cli

Version:

Ultimate command-line interface for Pulzar framework - scaffolding, development server, building, testing, code generation, health diagnostics, security auditing, and deployment tools for modern Node.js applications

233 lines 7.71 kB
import { logger } from "../utils/logger"; export async function devCommand(options) { try { logger.info("Starting development server...", { options }); // 1. Check if pulzar.config.ts exists const configPath = await findConfigFile(); if (!configPath) { logger.error("No pulzar.config.ts found. Run 'pulzar init' first."); process.exit(1); } logger.info("Found configuration file", { path: configPath }); // 2. Load configuration const config = await loadConfig(configPath); // 3. Setup environment process.env.NODE_ENV = process.env.NODE_ENV || "development"; // 4. Generate DI container if needed await generateDIContainer(config); // 5. Start development server await startDevServer(config, options); } catch (error) { logger.error("Failed to start development server", { error }); process.exit(1); } } async function findConfigFile() { const possiblePaths = [ "pulzar.config.ts", "pulzar.config.js", "src/pulzar.config.ts", "src/pulzar.config.js", ]; for (const path of possiblePaths) { try { const fs = await import("fs/promises"); await fs.access(path); return path; } catch { continue; } } return null; } async function loadConfig(configPath) { try { const config = await import(process.cwd() + "/" + configPath); return config.default || config; } catch (error) { logger.error("Failed to load configuration", { configPath, error }); return { entry: "src/main.ts", port: 3000, host: "localhost", }; } } async function generateDIContainer(config) { try { const { buildDI } = await import("./build-di"); await buildDI({ sourceDir: config.src || "src", outputFile: config.diOut || "src/generated/di-container.ts", watch: false, }); logger.info("DI container generated for development"); } catch (error) { logger.warn("Failed to generate DI container", { error }); } } async function startDevServer(config, options) { const port = parseInt(options.port) || config.port || 3000; const host = options.host || config.host || "localhost"; // Try to use different development strategies if (await tryTsxDev(config, { ...options, port: port.toString(), host })) { return; } if (await tryTsNodeDev(config, { ...options, port: port.toString(), host })) { return; } // Fallback to nodemon await tryNodemonDev(config, { ...options, port: port.toString(), host }); } async function tryTsxDev(config, options) { try { const { spawn } = await import("child_process"); const path = await import("path"); // Check if tsx is available const tsxPath = path.join(process.cwd(), "node_modules", ".bin", "tsx"); try { const fs = await import("fs/promises"); await fs.access(tsxPath); } catch { return false; } const entryFile = config.entry || "src/main.ts"; const args = ["watch", "--clear-screen=false", entryFile]; logger.info("Starting development server with tsx", { entry: entryFile, port: options.port, host: options.host, }); const child = spawn(tsxPath, args, { stdio: "inherit", env: { ...process.env, PORT: options.port, HOST: options.host, NODE_ENV: "development", }, }); child.on("error", (error) => { logger.error("Development server error", { error }); }); // Graceful shutdown process.on("SIGINT", () => { logger.info("Shutting down development server..."); child.kill("SIGTERM"); process.exit(0); }); logger.info(`🚀 Development server started on http://${options.host}:${options.port}`); return true; } catch (error) { logger.warn("Failed to start with tsx", { error }); return false; } } async function tryTsNodeDev(config, options) { try { const { spawn } = await import("child_process"); const path = await import("path"); // Check if ts-node-dev is available const tsNodeDevPath = path.join(process.cwd(), "node_modules", ".bin", "ts-node-dev"); try { const fs = await import("fs/promises"); await fs.access(tsNodeDevPath); } catch { return false; } const entryFile = config.entry || "src/main.ts"; const args = [ "--respawn", "--transpile-only", "--ignore-watch", "node_modules", "--clear", entryFile, ]; logger.info("Starting development server with ts-node-dev", { entry: entryFile, port: options.port, host: options.host, }); const child = spawn(tsNodeDevPath, args, { stdio: "inherit", env: { ...process.env, PORT: options.port, HOST: options.host, NODE_ENV: "development", }, }); child.on("error", (error) => { logger.error("Development server error", { error }); }); // Graceful shutdown process.on("SIGINT", () => { logger.info("Shutting down development server..."); child.kill("SIGTERM"); process.exit(0); }); logger.info(`🚀 Development server started on http://${options.host}:${options.port}`); return true; } catch (error) { logger.warn("Failed to start with ts-node-dev", { error }); return false; } } async function tryNodemonDev(config, options) { try { const { spawn } = await import("child_process"); const path = await import("path"); // Try nodemon as fallback const nodemonPath = path.join(process.cwd(), "node_modules", ".bin", "nodemon"); const entryFile = config.entry || "src/main.ts"; const args = [ "--exec", "npx tsx", "--watch", path.dirname(entryFile), "--ext", "ts,js,json", "--ignore", "node_modules/", entryFile, ]; logger.info("Starting development server with nodemon + tsx", { entry: entryFile, port: options.port, host: options.host, }); const child = spawn(nodemonPath, args, { stdio: "inherit", env: { ...process.env, PORT: options.port, HOST: options.host, NODE_ENV: "development", }, }); child.on("error", (error) => { logger.error("Development server error", { error }); }); // Graceful shutdown process.on("SIGINT", () => { logger.info("Shutting down development server..."); child.kill("SIGTERM"); process.exit(0); }); logger.info(`🚀 Development server started on http://${options.host}:${options.port}`); } catch (error) { logger.error("Failed to start development server", { error }); throw error; } } //# sourceMappingURL=dev.js.map