neex
Version:
Neex - Modern Fullstack Framework Built on Express and Next.js. Fast to Start, Easy to Build, Ready to Deploy
197 lines (196 loc) • 10.5 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.addDevCommands = addDevCommands;
const dev_manager_js_1 = require("../dev-manager.js");
const logger_manager_js_1 = require("../logger-manager.js");
const chalk_1 = __importDefault(require("chalk"));
const figures_1 = __importDefault(require("figures"));
function addDevCommands(program) {
let devManager = null;
// Ultra-fast dev command optimized for speed
program
.command('dev [file]')
.description('Start ultra-fast TypeScript development server (like tsx)')
.option('-w, --watch <patterns>', 'Watch patterns (comma-separated)', 'src/**/*')
.option('-i, --ignore <patterns>', 'Ignore patterns (comma-separated)', 'node_modules,dist,build,.git')
.option('-e, --ext <extensions>', 'File extensions to watch', 'ts,tsx,js,jsx')
.option('-d, --delay <ms>', 'Restart delay in milliseconds', parseInt, 100)
.option('--fast', 'Ultra-fast mode (50ms delay)')
.option('--no-clear', 'Don\'t clear console on restart')
.option('--no-color', 'Disable colored output')
.option('-q, --quiet', 'Minimal output')
.option('-v, --verbose', 'Verbose logging')
.option('--inspect', 'Enable Node.js inspector')
.option('--inspect-brk', 'Enable Node.js inspector with breakpoint')
.option('--env <file>', 'Environment file to load', '.env')
.option('--exec <command>', 'Custom command to execute')
.option('--tsconfig <path>', 'TypeScript config file path')
.option('--no-source-maps', 'Disable source map generation')
.option('--transpile-only', 'Skip type checking (faster)')
.option('--node-args <args>', 'Node.js arguments (comma-separated)', '')
.action(async (file, options) => {
try {
const targetFile = file || 'src/index.ts';
const delay = options.fast ? 50 : options.delay;
if (!options.quiet) {
console.log(''); // Empty line for better visual separation
logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green(figures_1.default.play)} Starting ${chalk_1.default.cyan('neex dev')} for ${chalk_1.default.cyan(targetFile)}`, 'info');
}
devManager = new dev_manager_js_1.DevManager({
file: targetFile,
watch: options.watch.split(',').map((p) => p.trim()),
ignore: options.ignore.split(',').map((p) => p.trim()),
extensions: options.ext.split(',').map((e) => e.trim()),
delay: delay,
color: options.color,
quiet: options.quiet,
verbose: options.verbose,
clearConsole: options.clear,
inspect: options.inspect,
inspectBrk: options.inspectBrk,
envFile: options.env,
execCommand: options.exec,
tsConfig: options.tsconfig,
sourceMaps: options.sourceMaps,
transpileOnly: options.transpileOnly,
nodeArgs: options.nodeArgs ? options.nodeArgs.split(',').map((arg) => arg.trim()) : []
});
// --- Signal Handlers for Dev ---
let isShuttingDown = false;
const cleanupAndExit = () => {
if (isShuttingDown)
return;
isShuttingDown = true;
if (devManager) {
logger_manager_js_1.loggerManager.printLine(`\n${chalk_1.default.yellow('⏹')} Received SIGINT, shutting down...`, 'info');
devManager.stop().then(() => process.exit(0));
}
};
const sigintHandler = () => cleanupAndExit();
const sigtermHandler = () => cleanupAndExit();
process.on('SIGINT', sigintHandler);
process.on('SIGTERM', sigtermHandler);
await devManager.start();
}
catch (error) {
if (error instanceof Error) {
logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red('✖')} ${error.message}`, 'error');
}
else {
logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red('✖')} Unknown error occurred`, 'error');
}
process.exit(1);
}
});
// Clean cache command
program
.command('dev:clean')
.description('Clean development cache and temp files')
.action(() => {
const path = require('path');
const fs = require('fs');
const tempDir = path.join(process.cwd(), '.neex-temp');
const nodeModulesCache = path.join(process.cwd(), 'node_modules/.cache');
let cleaned = false;
if (fs.existsSync(tempDir)) {
fs.rmSync(tempDir, { recursive: true, force: true });
cleaned = true;
}
if (fs.existsSync(nodeModulesCache)) {
try {
fs.rmSync(nodeModulesCache, { recursive: true, force: true });
cleaned = true;
}
catch (error) {
// Ignore cache cleanup errors
}
}
if (cleaned) {
logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green('✓')} Cache cleaned successfully`, 'info');
}
else {
logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue('ℹ')} No cache to clean`, 'info');
}
});
// TypeScript config check
program
.command('dev:check')
.description('Check TypeScript configuration')
.option('--tsconfig <path>', 'TypeScript config file path')
.action((options) => {
const path = require('path');
const fs = require('fs');
const configPath = options.tsconfig || 'tsconfig.json';
if (!fs.existsSync(configPath)) {
logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red('✖')} TypeScript config not found: ${configPath}`, 'error');
process.exit(1);
}
try {
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green('✓')} TypeScript config is valid`, 'info');
if (config.compilerOptions && !options.quiet) {
const opts = config.compilerOptions;
logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Configuration:')}`, 'info');
logger_manager_js_1.loggerManager.printLine(` Target: ${opts.target || 'ES5'}`, 'info');
logger_manager_js_1.loggerManager.printLine(` Module: ${opts.module || 'CommonJS'}`, 'info');
logger_manager_js_1.loggerManager.printLine(` Strict: ${opts.strict || false}`, 'info');
logger_manager_js_1.loggerManager.printLine(` Source Maps: ${opts.sourceMap || false}`, 'info');
logger_manager_js_1.loggerManager.printLine(` Skip Lib Check: ${opts.skipLibCheck || false}`, 'info');
}
}
catch (error) {
logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red('✖')} Invalid TypeScript config: ${error.message}`, 'error');
process.exit(1);
}
});
// Performance info command
program
.command('dev:info')
.description('Show development server information')
.action(() => {
const path = require('path');
const fs = require('fs');
const os = require('os');
console.log('');
logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue('⚡')} ${chalk_1.default.bold('neex dev')} - Development Server Info`, 'info');
console.log('');
logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('System:')}`, 'info');
logger_manager_js_1.loggerManager.printLine(` Platform: ${os.platform()} ${os.arch()}`, 'info');
logger_manager_js_1.loggerManager.printLine(` Node.js: ${process.version}`, 'info');
logger_manager_js_1.loggerManager.printLine(` Memory: ${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)}MB used`, 'info');
console.log('');
logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Features:')}`, 'info');
logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Ultra-fast TypeScript compilation`, 'info');
logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Intelligent module caching`, 'info');
logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Hot reload with dependency tracking`, 'info');
logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Source map support`, 'info');
logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Memory-optimized processing`, 'info');
const tsConfigExists = fs.existsSync('tsconfig.json');
const packageJsonExists = fs.existsSync('package.json');
console.log('');
logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Project:')}`, 'info');
logger_manager_js_1.loggerManager.printLine(` TypeScript Config: ${tsConfigExists ? chalk_1.default.green('✓') : chalk_1.default.red('✖')}`, 'info');
logger_manager_js_1.loggerManager.printLine(` Package.json: ${packageJsonExists ? chalk_1.default.green('✓') : chalk_1.default.red('✖')}`, 'info');
if (packageJsonExists) {
try {
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
if (pkg.name) {
logger_manager_js_1.loggerManager.printLine(` Name: ${pkg.name}`, 'info');
}
if (pkg.version) {
logger_manager_js_1.loggerManager.printLine(` Version: ${pkg.version}`, 'info');
}
}
catch (error) {
// Ignore package.json parsing errors
}
}
console.log('');
});
// Cleanup function is no longer needed here as it's handled within the command
const cleanupDev = () => { };
return { cleanupDev };
}