neex 0.2.7 → 0.2.9

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.
Files changed (50) hide show
  1. package/README.md +3 -1
  2. package/bun.lock +118 -518
  3. package/dist/cli.d.ts +1 -0
  4. package/dist/cli.js +199 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/build.d.ts +3 -0
  7. package/dist/commands/build.js +41 -0
  8. package/dist/commands/build.js.map +1 -0
  9. package/dist/commands/cache.d.ts +3 -0
  10. package/dist/commands/cache.js +34 -0
  11. package/dist/commands/cache.js.map +1 -0
  12. package/dist/commands/dev.d.ts +3 -0
  13. package/dist/commands/dev.js +51 -0
  14. package/dist/commands/dev.js.map +1 -0
  15. package/dist/commands/process.d.ts +2 -0
  16. package/dist/commands/process.js +216 -0
  17. package/dist/commands/process.js.map +1 -0
  18. package/dist/commands/run.d.ts +2 -0
  19. package/dist/commands/run.js +81 -0
  20. package/dist/commands/run.js.map +1 -0
  21. package/dist/commands/start.d.ts +3 -0
  22. package/dist/commands/start.js +45 -0
  23. package/dist/commands/start.js.map +1 -0
  24. package/dist/dev-manager.d.ts +34 -0
  25. package/dist/dev-manager.js +172 -0
  26. package/dist/dev-manager.js.map +1 -0
  27. package/dist/index.d.ts +38 -0
  28. package/dist/index.js +69 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/logger.d.ts +31 -0
  31. package/dist/logger.js +238 -0
  32. package/dist/logger.js.map +1 -0
  33. package/dist/process-manager.d.ts +51 -0
  34. package/dist/process-manager.js +258 -0
  35. package/dist/process-manager.js.map +1 -0
  36. package/dist/project-manager.d.ts +50 -0
  37. package/dist/project-manager.js +241 -0
  38. package/dist/project-manager.js.map +1 -0
  39. package/dist/runner.d.ts +16 -0
  40. package/dist/runner.js +331 -0
  41. package/dist/runner.js.map +1 -0
  42. package/dist/src/cli.js +186 -157
  43. package/dist/src/process-manager.js +110 -60
  44. package/dist/types.d.ts +37 -0
  45. package/dist/types.js +3 -0
  46. package/dist/types.js.map +1 -0
  47. package/dist/typescript-runner.d.ts +12 -0
  48. package/dist/typescript-runner.js +161 -0
  49. package/dist/typescript-runner.js.map +1 -0
  50. package/package.json +7 -2
package/dist/src/cli.js CHANGED
@@ -26,10 +26,12 @@ function cli() {
26
26
  .command('dev <entry>')
27
27
  .description('Run Express.js project in development mode with TypeScript support')
28
28
  .option('-p, --port <number>', 'Port to run the server on', '3000')
29
- .option('-w, --watch <path>', 'Path to watch for changes', 'src')
29
+ .option('-w, --watch <paths...>', 'Paths to watch for changes', ['src'])
30
+ .option('-i, --ignore <paths...>', 'Paths to ignore', ['node_modules', 'dist', '.git'])
31
+ .option('-e, --ext <extensions...>', 'File extensions to watch', ['ts', 'js', 'json'])
32
+ .option('-d, --delay <number>', 'Delay before restarting in milliseconds', '1000')
30
33
  .option('-c, --no-color', 'Disable colored output')
31
- .option('-t, --transpile-only', 'Use transpileOnly mode for faster compilation', false)
32
- .option('-i, --ignore <patterns>', 'Ignore patterns for file watching', 'node_modules,.git')
34
+ .option('--no-clear', 'Disable screen clearing on restart')
33
35
  .action(async (entry, options) => {
34
36
  try {
35
37
  const entryPath = (0, path_1.resolve)(process.cwd(), entry);
@@ -37,31 +39,87 @@ function cli() {
37
39
  throw new Error(`Entry file ${entry} not found`);
38
40
  }
39
41
  console.log(chalk_1.default.blue(`${figures_1.default.info} Starting development server...`));
40
- const tsNodeDevArgs = [
41
- '--respawn',
42
- '--transpile-only',
43
- '--ignore-watch', options.ignore,
44
- '--watch', options.watch,
45
- '-r', 'tsconfig-paths/register',
46
- entryPath
47
- ];
48
- if (options.transpileOnly) {
49
- tsNodeDevArgs.push('--transpile-only');
50
- }
51
- const server = (0, child_process_1.spawn)('ts-node-dev', tsNodeDevArgs, {
52
- stdio: 'inherit',
53
- env: {
54
- ...process.env,
55
- PORT: options.port,
56
- NODE_ENV: 'development'
42
+ let server = null;
43
+ let isRestarting = false;
44
+ let restartTimer = null;
45
+ const startServer = () => {
46
+ if (server) {
47
+ server.kill();
48
+ }
49
+ server = (0, child_process_1.spawn)('ts-node', [
50
+ '-r', 'tsconfig-paths/register',
51
+ entryPath
52
+ ], {
53
+ stdio: 'inherit',
54
+ env: {
55
+ ...process.env,
56
+ PORT: options.port,
57
+ NODE_ENV: 'development'
58
+ }
59
+ });
60
+ server.on('error', (err) => {
61
+ console.error(chalk_1.default.red(`${figures_1.default.cross} Server error: ${err.message}`));
62
+ });
63
+ server.on('exit', (code) => {
64
+ if (code !== 0 && !isRestarting) {
65
+ console.error(chalk_1.default.red(`${figures_1.default.cross} Server crashed with code ${code}`));
66
+ }
67
+ });
68
+ };
69
+ // Initial server start
70
+ startServer();
71
+ // Setup file watching with chokidar
72
+ const watcher = (0, chokidar_1.watch)(options.watch, {
73
+ ignored: [
74
+ ...options.ignore,
75
+ /(^|[\/\\])\../,
76
+ '**/*.map' // Ignore source maps
77
+ ],
78
+ persistent: true,
79
+ ignoreInitial: true,
80
+ awaitWriteFinish: {
81
+ stabilityThreshold: 300,
82
+ pollInterval: 100
83
+ }
84
+ });
85
+ // Handle file changes
86
+ watcher.on('change', (path) => {
87
+ var _a;
88
+ const ext = (_a = path.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
89
+ if (!ext || !options.ext.includes(ext)) {
90
+ return;
91
+ }
92
+ if (restartTimer) {
93
+ clearTimeout(restartTimer);
57
94
  }
95
+ isRestarting = true;
96
+ restartTimer = setTimeout(() => {
97
+ if (options.clear) {
98
+ process.stdout.write('\x1Bc'); // Clear screen
99
+ }
100
+ console.log(chalk_1.default.yellow(`${figures_1.default.info} File ${path} changed. Restarting...`));
101
+ startServer();
102
+ isRestarting = false;
103
+ }, parseInt(options.delay));
58
104
  });
105
+ // Handle cleanup
59
106
  cleanupRunner = () => {
60
- server.kill();
107
+ if (server) {
108
+ server.kill();
109
+ }
110
+ if (restartTimer) {
111
+ clearTimeout(restartTimer);
112
+ }
113
+ watcher.close();
61
114
  };
62
- server.on('error', (err) => {
63
- console.error(chalk_1.default.red(`${figures_1.default.cross} Server error: ${err.message}`));
64
- process.exit(1);
115
+ // Handle process signals
116
+ process.on('SIGINT', () => {
117
+ cleanupRunner === null || cleanupRunner === void 0 ? void 0 : cleanupRunner();
118
+ process.exit(0);
119
+ });
120
+ process.on('SIGTERM', () => {
121
+ cleanupRunner === null || cleanupRunner === void 0 ? void 0 : cleanupRunner();
122
+ process.exit(0);
65
123
  });
66
124
  }
67
125
  catch (error) {
@@ -109,47 +167,56 @@ function cli() {
109
167
  });
110
168
  // Start command for production
111
169
  program
112
- .command('start <entry>')
113
- .description('Start Express.js project in production mode')
170
+ .command('start')
171
+ .description('Start the built application in production mode')
114
172
  .option('-p, --port <number>', 'Port to run the server on', '3000')
115
- .option('-e, --env <env>', 'Environment to run in', 'production')
116
- .option('-m, --max-memory <size>', 'Maximum memory size (e.g., 512M, 1G)', '512M')
117
- .option('-c, --cluster <number>', 'Number of cluster workers', '1')
118
- .action(async (entry, options) => {
173
+ .option('-o, --outDir <dir>', 'Output directory', 'dist')
174
+ .option('-e, --entry <file>', 'Entry file name', 'index.js')
175
+ .action(async (options) => {
119
176
  try {
120
- const entryPath = (0, path_1.resolve)(process.cwd(), entry);
177
+ const outDir = options.outDir;
178
+ const entryFile = options.entry;
179
+ const entryPath = (0, path_1.resolve)(process.cwd(), outDir, entryFile);
121
180
  if (!(0, fs_1.existsSync)(entryPath)) {
122
- throw new Error(`Entry file ${entry} not found`);
181
+ console.log(chalk_1.default.yellow(`${figures_1.default.warning} Build not found. Building project first...`));
182
+ // Run build command first
183
+ const build = (0, child_process_1.spawn)('tsc', [
184
+ '--outDir', outDir
185
+ ], {
186
+ stdio: 'inherit'
187
+ });
188
+ build.on('close', (code) => {
189
+ if (code === 0) {
190
+ console.log(chalk_1.default.green(`${figures_1.default.tick} Build completed successfully`));
191
+ startServer();
192
+ }
193
+ else {
194
+ console.error(chalk_1.default.red(`${figures_1.default.cross} Build failed with code ${code}`));
195
+ process.exit(code !== null && code !== void 0 ? code : 1);
196
+ }
197
+ });
123
198
  }
124
- console.log(chalk_1.default.blue(`${figures_1.default.info} Starting production server...`));
125
- // Check if the entry file is TypeScript
126
- const isTypeScript = entryPath.endsWith('.ts');
127
- const executable = isTypeScript ? 'ts-node' : 'node';
128
- const args = isTypeScript
129
- ? ['-r', 'tsconfig-paths/register', entryPath]
130
- : [entryPath];
131
- // Add cluster support if specified
132
- if (parseInt(options.cluster) > 1) {
133
- args.unshift('--max-old-space-size=' + options.maxMemory);
134
- args.unshift('--max-memory=' + options.maxMemory);
135
- args.unshift('--cluster=' + options.cluster);
199
+ else {
200
+ startServer();
201
+ }
202
+ function startServer() {
203
+ console.log(chalk_1.default.blue(`${figures_1.default.info} Starting production server...`));
204
+ const server = (0, child_process_1.spawn)('node', [entryPath], {
205
+ stdio: 'inherit',
206
+ env: {
207
+ ...process.env,
208
+ PORT: options.port,
209
+ NODE_ENV: 'production'
210
+ }
211
+ });
212
+ cleanupRunner = () => {
213
+ server.kill();
214
+ };
215
+ server.on('error', (err) => {
216
+ console.error(chalk_1.default.red(`${figures_1.default.cross} Server error: ${err.message}`));
217
+ process.exit(1);
218
+ });
136
219
  }
137
- const server = (0, child_process_1.spawn)(executable, args, {
138
- stdio: 'inherit',
139
- env: {
140
- ...process.env,
141
- PORT: options.port,
142
- NODE_ENV: options.env,
143
- MAX_MEMORY: options.maxMemory
144
- }
145
- });
146
- cleanupRunner = () => {
147
- server.kill();
148
- };
149
- server.on('error', (err) => {
150
- console.error(chalk_1.default.red(`${figures_1.default.cross} Server error: ${err.message}`));
151
- process.exit(1);
152
- });
153
220
  }
154
221
  catch (error) {
155
222
  if (error instanceof Error) {
@@ -234,24 +301,26 @@ function cli() {
234
301
  });
235
302
  // Process Management Commands
236
303
  program
237
- .command('startx <path>')
304
+ .command('startx <command>')
238
305
  .description('Start a process with monitoring and auto-restart')
239
306
  .option('-n, --name <name>', 'Process name')
240
307
  .option('-w, --watch', 'Watch for file changes and auto-restart')
241
308
  .option('-r, --max-restarts <number>', 'Maximum number of restart attempts', '5')
242
309
  .option('-d, --restart-delay <number>', 'Delay between restarts in milliseconds', '1000')
243
- .action(async (path, options) => {
310
+ .option('-c, --cwd <path>', 'Working directory for the process')
311
+ .action(async (command, options) => {
244
312
  try {
245
- const process = await process_manager_js_1.processManager.startx(path, {
313
+ const process = await process_manager_js_1.processManager.startx(command, {
246
314
  name: options.name,
247
315
  watch: options.watch,
248
316
  maxRestarts: parseInt(options.maxRestarts),
249
- restartDelay: parseInt(options.restartDelay)
317
+ restartDelay: parseInt(options.restartDelay),
318
+ cwd: options.cwd
250
319
  });
251
320
  console.log(chalk_1.default.green(`${figures_1.default.tick} Process started successfully`));
252
- console.log(chalk_1.default.blue(`ID: ${process.id}`));
253
321
  console.log(chalk_1.default.blue(`Name: ${process.name}`));
254
322
  console.log(chalk_1.default.blue(`PID: ${process.pid}`));
323
+ console.log(chalk_1.default.blue(`Command: ${process.command}`));
255
324
  console.log(chalk_1.default.blue(`Max Restarts: ${process.maxRestarts}`));
256
325
  console.log(chalk_1.default.blue(`Restart Delay: ${process.restartDelay}ms`));
257
326
  }
@@ -266,12 +335,12 @@ function cli() {
266
335
  }
267
336
  });
268
337
  program
269
- .command('stopx <id>')
338
+ .command('stopx <name>')
270
339
  .description('Stop a running process')
271
340
  .option('-f, --force', 'Force stop the process')
272
- .action(async (id, options) => {
341
+ .action(async (name, options) => {
273
342
  try {
274
- await process_manager_js_1.processManager.stopx(id);
343
+ await process_manager_js_1.processManager.stopx(name);
275
344
  console.log(chalk_1.default.green(`${figures_1.default.tick} Process stopped successfully`));
276
345
  }
277
346
  catch (error) {
@@ -290,81 +359,42 @@ function cli() {
290
359
  .option('-a, --all', 'Show all processes including stopped ones')
291
360
  .option('-j, --json', 'Output in JSON format')
292
361
  .action((options) => {
293
- const processes = process_manager_js_1.processManager.list();
294
- const filteredProcesses = options.all ? processes : processes.filter(p => p.status === 'running');
295
- if (filteredProcesses.length === 0) {
296
- console.log(chalk_1.default.yellow(`${figures_1.default.info} No processes running`));
297
- return;
298
- }
299
- if (options.json) {
300
- console.log(JSON.stringify(filteredProcesses, null, 2));
301
- return;
362
+ try {
363
+ if (options.json) {
364
+ const processes = Array.from(process_manager_js_1.processManager.list());
365
+ console.log(JSON.stringify(processes, null, 2));
366
+ return;
367
+ }
368
+ console.log(process_manager_js_1.processManager.list());
302
369
  }
303
- console.log(chalk_1.default.blue(`${figures_1.default.info} Running Processes:`));
304
- filteredProcesses.forEach(process => {
305
- const statusColor = process.status === 'running' ? 'green' :
306
- process.status === 'error' ? 'red' :
307
- process.status === 'restarting' ? 'yellow' : 'gray';
308
- console.log(chalk_1.default.blue(`\nID: ${process.id}`));
309
- console.log(`Name: ${process.name}`);
310
- console.log(`Status: ${chalk_1.default[statusColor](process.status)}`);
311
- console.log(`PID: ${process.pid}`);
312
- console.log(`Uptime: ${Math.floor(process.uptime)}s`);
313
- console.log(`Memory: ${process.memory.toFixed(2)}MB`);
314
- console.log(`Restarts: ${process.restarts}/${process.maxRestarts}`);
315
- if (process.lastError) {
316
- console.log(`Last Error: ${chalk_1.default.red(process.lastError)}`);
370
+ catch (error) {
371
+ if (error instanceof Error) {
372
+ console.error(chalk_1.default.red(`${figures_1.default.cross} Error: ${error.message}`));
373
+ }
374
+ else {
375
+ console.error(chalk_1.default.red(`${figures_1.default.cross} An unknown error occurred`));
317
376
  }
318
- });
377
+ process.exit(1);
378
+ }
319
379
  });
320
380
  program
321
- .command('monit <id>')
322
- .description('Monitor a specific process')
381
+ .command('monit <name>')
382
+ .description('Monitor a process in real-time')
323
383
  .option('-i, --interval <number>', 'Update interval in milliseconds', '1000')
324
- .action((id, options) => {
384
+ .action((name, options) => {
325
385
  try {
326
- const processInfo = process_manager_js_1.processManager.monit(id);
327
- console.log(chalk_1.default.blue(`${figures_1.default.info} Process Monitor:`));
328
- console.log(chalk_1.default.blue(`\nID: ${processInfo.id}`));
329
- console.log(`Name: ${processInfo.name}`);
330
- console.log(`Status: ${processInfo.status}`);
331
- console.log(`PID: ${processInfo.pid}`);
332
- console.log(`Uptime: ${Math.floor(processInfo.uptime)}s`);
333
- console.log(`Memory: ${processInfo.memory.toFixed(2)}MB`);
334
- console.log(`Restarts: ${processInfo.restarts}/${processInfo.maxRestarts}`);
335
- if (processInfo.lastError) {
336
- console.log(`Last Error: ${chalk_1.default.red(processInfo.lastError)}`);
386
+ const interval = parseInt(options.interval);
387
+ if (isNaN(interval) || interval < 100) {
388
+ throw new Error('Interval must be a number greater than 100ms');
337
389
  }
338
- console.log(chalk_1.default.blue(`\nRecent Logs:`));
339
- processInfo.logs.forEach(log => {
340
- if (log.includes('error') || log.includes('Error')) {
341
- console.log(chalk_1.default.red(log));
342
- }
343
- else if (log.includes('warn') || log.includes('Warn')) {
344
- console.log(chalk_1.default.yellow(log));
345
- }
346
- else {
347
- console.log(log);
348
- }
349
- });
350
390
  // Start real-time monitoring
351
- const interval = setInterval(() => {
391
+ const updateDisplay = () => {
352
392
  try {
353
- const updatedProcess = process_manager_js_1.processManager.monit(id);
393
+ const { table, logs } = process_manager_js_1.processManager.monit(name);
354
394
  process.stdout.write('\x1Bc'); // Clear screen
355
- console.log(chalk_1.default.blue(`${figures_1.default.info} Process Monitor (Live):`));
356
- console.log(chalk_1.default.blue(`\nID: ${updatedProcess.id}`));
357
- console.log(`Name: ${updatedProcess.name}`);
358
- console.log(`Status: ${updatedProcess.status}`);
359
- console.log(`PID: ${updatedProcess.pid}`);
360
- console.log(`Uptime: ${Math.floor(updatedProcess.uptime)}s`);
361
- console.log(`Memory: ${updatedProcess.memory.toFixed(2)}MB`);
362
- console.log(`Restarts: ${updatedProcess.restarts}/${updatedProcess.maxRestarts}`);
363
- if (updatedProcess.lastError) {
364
- console.log(`Last Error: ${chalk_1.default.red(updatedProcess.lastError)}`);
365
- }
366
- console.log(chalk_1.default.blue(`\nRecent Logs:`));
367
- updatedProcess.logs.forEach(log => {
395
+ console.log(table);
396
+ console.log(chalk_1.default.blue('\nRecent Logs:'));
397
+ logs.forEach(log => {
368
398
  if (log.includes('error') || log.includes('Error')) {
369
399
  console.log(chalk_1.default.red(log));
370
400
  }
@@ -377,14 +407,15 @@ function cli() {
377
407
  });
378
408
  }
379
409
  catch (error) {
380
- clearInterval(interval);
410
+ clearInterval(monitorInterval);
381
411
  console.error(chalk_1.default.red(`${figures_1.default.cross} Error monitoring process: ${error}`));
382
412
  process.exit(1);
383
413
  }
384
- }, parseInt(options.interval));
385
- // Handle cleanup
414
+ };
415
+ const monitorInterval = setInterval(updateDisplay, interval);
416
+ updateDisplay(); // Initial display
386
417
  process.on('SIGINT', () => {
387
- clearInterval(interval);
418
+ clearInterval(monitorInterval);
388
419
  process.exit(0);
389
420
  });
390
421
  }
@@ -399,31 +430,29 @@ function cli() {
399
430
  }
400
431
  });
401
432
  program
402
- .command('log <id>')
433
+ .command('log <name>')
403
434
  .description('View process logs')
404
- .option('-l, --lines <number>', 'Number of lines to show', '100')
405
435
  .option('-f, --follow', 'Follow log output')
406
- .option('-e, --error', 'Show only error logs')
407
- .option('-w, --warn', 'Show only warning logs')
408
- .action((id, options) => {
436
+ .option('-e, --errors', 'Show only errors')
437
+ .option('-w, --warnings', 'Show only warnings')
438
+ .option('-l, --lines <number>', 'Number of lines to show', '100')
439
+ .action((name, options) => {
409
440
  try {
410
- const logs = process_manager_js_1.processManager.log(id, parseInt(options.lines));
411
- if (options.error) {
412
- const errorLogs = logs.filter(log => log.toLowerCase().includes('error') ||
441
+ const lines = parseInt(options.lines);
442
+ if (isNaN(lines) || lines < 1) {
443
+ throw new Error('Lines must be a positive number');
444
+ }
445
+ const logs = process_manager_js_1.processManager.log(name, lines);
446
+ let filteredLogs = logs;
447
+ if (options.errors) {
448
+ filteredLogs = logs.filter(log => log.toLowerCase().includes('error') ||
413
449
  log.toLowerCase().includes('exception'));
414
- console.log(chalk_1.default.blue(`${figures_1.default.info} Error Logs:`));
415
- errorLogs.forEach(log => console.log(chalk_1.default.red(log)));
416
- return;
417
450
  }
418
- if (options.warn) {
419
- const warnLogs = logs.filter(log => log.toLowerCase().includes('warn') ||
451
+ else if (options.warnings) {
452
+ filteredLogs = logs.filter(log => log.toLowerCase().includes('warn') ||
420
453
  log.toLowerCase().includes('warning'));
421
- console.log(chalk_1.default.blue(`${figures_1.default.info} Warning Logs:`));
422
- warnLogs.forEach(log => console.log(chalk_1.default.yellow(log)));
423
- return;
424
454
  }
425
- console.log(chalk_1.default.blue(`${figures_1.default.info} Process Logs:`));
426
- logs.forEach(log => {
455
+ filteredLogs.forEach(log => {
427
456
  if (log.includes('error') || log.includes('Error')) {
428
457
  console.log(chalk_1.default.red(log));
429
458
  }
@@ -435,11 +464,11 @@ function cli() {
435
464
  }
436
465
  });
437
466
  if (options.follow) {
438
- const watcher = (0, chokidar_1.watch)(process_manager_js_1.processManager.getLogPath(id), {
467
+ const watcher = (0, chokidar_1.watch)(process_manager_js_1.processManager.getLogPath(name), {
439
468
  persistent: true
440
469
  });
441
470
  watcher.on('change', () => {
442
- const newLogs = process_manager_js_1.processManager.log(id, 1);
471
+ const newLogs = process_manager_js_1.processManager.log(name, 1);
443
472
  if (newLogs.length > 0) {
444
473
  const log = newLogs[0];
445
474
  if (log.includes('error') || log.includes('Error')) {