neex 0.6.3 → 0.6.5
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.
- package/README.md +1 -1
- package/dist/src/commands/dev-commands.js +61 -39
- package/dist/src/dev-runner.js +62 -63
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ async function fileExists(filePath) {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
// Helper function to determine the best command to run the file
|
|
46
|
-
async function getBestCommand(filePath, showInfo
|
|
46
|
+
async function getBestCommand(filePath, showInfo) {
|
|
47
47
|
const ext = path.extname(filePath).toLowerCase();
|
|
48
48
|
const absolutePath = path.resolve(process.cwd(), filePath);
|
|
49
49
|
// Check if file exists
|
|
@@ -94,12 +94,12 @@ function addDevCommands(program) {
|
|
|
94
94
|
.option('-d, --delay <ms>', 'Delay before restart in milliseconds', parseInt)
|
|
95
95
|
.option('--clear', 'Clear console on restart')
|
|
96
96
|
.option('--verbose', 'Verbose output')
|
|
97
|
-
.option('--info', 'Show detailed information
|
|
97
|
+
.option('--info', 'Show detailed information during startup')
|
|
98
98
|
.option('--signal <signal>', 'Signal to send to processes on restart', 'SIGTERM')
|
|
99
99
|
.action(async (file, options) => {
|
|
100
100
|
try {
|
|
101
|
-
|
|
102
|
-
if (
|
|
101
|
+
const showInfo = options.info || false;
|
|
102
|
+
if (showInfo) {
|
|
103
103
|
console.log(chalk_1.default.blue(`${figures_1.default.info} neex dev: Starting enhanced development server...`));
|
|
104
104
|
console.log(chalk_1.default.blue(`${figures_1.default.info} neex dev: Target file: ${chalk_1.default.cyan(file)}`));
|
|
105
105
|
}
|
|
@@ -114,61 +114,83 @@ function addDevCommands(program) {
|
|
|
114
114
|
let commandToExecute;
|
|
115
115
|
let fileExtension;
|
|
116
116
|
try {
|
|
117
|
-
commandToExecute = await getBestCommand(file,
|
|
117
|
+
commandToExecute = await getBestCommand(file, showInfo);
|
|
118
118
|
fileExtension = path.extname(file).toLowerCase();
|
|
119
119
|
}
|
|
120
120
|
catch (error) {
|
|
121
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} neex dev: Error
|
|
121
|
+
console.error(chalk_1.default.red(`${figures_1.default.cross} neex dev: ${error instanceof Error ? error.message : 'Unknown error occurred'}`));
|
|
122
122
|
process.exit(1);
|
|
123
123
|
}
|
|
124
|
-
//
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
// Setup watch configuration
|
|
125
|
+
const watchPaths = options.watch ? [...options.watch, './'] : ['./'];
|
|
126
|
+
const ignorePatterns = options.ignore || [
|
|
127
|
+
'node_modules/**',
|
|
128
|
+
'.git/**',
|
|
129
|
+
'*.log',
|
|
130
|
+
'dist/**',
|
|
131
|
+
'build/**',
|
|
132
|
+
'coverage/**',
|
|
133
|
+
'.nyc_output/**',
|
|
134
|
+
'*.tmp',
|
|
135
|
+
'*.temp',
|
|
136
|
+
'.DS_Store',
|
|
137
|
+
'Thumbs.db'
|
|
138
|
+
];
|
|
139
|
+
const extensions = options.ext || ['js', 'mjs', 'json', 'ts', 'tsx', 'jsx', 'vue', 'svelte'];
|
|
140
|
+
// Log configuration only if --info flag is set
|
|
141
|
+
if (showInfo) {
|
|
127
142
|
console.log(chalk_1.default.blue(`${figures_1.default.info} neex dev: Configuration:`));
|
|
128
|
-
console.log(`
|
|
129
|
-
console.log(`
|
|
130
|
-
console.log(`
|
|
131
|
-
console.log(`
|
|
132
|
-
console.log(`
|
|
133
|
-
console.log(`
|
|
143
|
+
console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} Target: ${chalk_1.default.cyan(file)}`));
|
|
144
|
+
console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} Runtime: ${chalk_1.default.cyan(fileExtension === '.ts' || fileExtension === '.mts' || fileExtension === '.cts' ? 'TypeScript' : 'JavaScript')}`));
|
|
145
|
+
console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} Watch paths: ${chalk_1.default.cyan(watchPaths.join(', '))}`));
|
|
146
|
+
console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} Extensions: ${chalk_1.default.cyan(extensions.join(', '))}`));
|
|
147
|
+
console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} Restart delay: ${chalk_1.default.cyan(options.delay || 1000)}ms`));
|
|
148
|
+
console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} Clear console: ${chalk_1.default.cyan(options.clear ? 'Yes' : 'No')}`));
|
|
149
|
+
if (options.verbose) {
|
|
150
|
+
console.log(chalk_1.default.blue(`${figures_1.default.info} neex dev: Verbose mode enabled - showing detailed logs`));
|
|
151
|
+
}
|
|
152
|
+
console.log(chalk_1.default.green(`${figures_1.default.tick} neex dev: Starting file watcher and process manager...`));
|
|
153
|
+
console.log(chalk_1.default.green(`${figures_1.default.tick} neex dev: Launching ${chalk_1.default.cyan(path.basename(file))} with auto-restart capability...`));
|
|
154
|
+
console.log(chalk_1.default.blue(`${figures_1.default.info} neex dev: Press Ctrl+C to stop the development server`));
|
|
155
|
+
console.log(chalk_1.default.gray(`${'='.repeat(60)}`));
|
|
134
156
|
}
|
|
135
|
-
console.log(chalk_1.default.green(`${figures_1.default.tick} neex dev: Starting file watcher and process manager...`));
|
|
136
157
|
// Create DevRunner instance
|
|
137
158
|
devRunner = new dev_runner_js_1.DevRunner({
|
|
138
159
|
runnerName: 'neex dev',
|
|
139
160
|
parallel: false,
|
|
140
|
-
color:
|
|
141
|
-
showTiming:
|
|
142
|
-
prefix:
|
|
161
|
+
color: options.color,
|
|
162
|
+
showTiming: options.timing,
|
|
163
|
+
prefix: options.prefix,
|
|
143
164
|
stopOnError: options.stopOnError,
|
|
165
|
+
printOutput: options.output,
|
|
144
166
|
minimalOutput: options.minimal,
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
clearConsole: options.clear,
|
|
149
|
-
signal: options.signal,
|
|
150
|
-
watch: options.watch || ['./'],
|
|
151
|
-
ignore: options.ignore || [
|
|
152
|
-
'node_modules/**',
|
|
153
|
-
'.git/**',
|
|
154
|
-
'*.log',
|
|
155
|
-
'dist/**',
|
|
156
|
-
'build/**',
|
|
157
|
-
'coverage/**',
|
|
158
|
-
'.nyc_output/**',
|
|
159
|
-
'*.tmp',
|
|
160
|
-
'*.temp'
|
|
161
|
-
],
|
|
162
|
-
ext: options.ext || ['js', 'mjs', 'json', 'ts', 'tsx', 'jsx', 'vue', 'svelte'],
|
|
167
|
+
watch: watchPaths,
|
|
168
|
+
ignore: ignorePatterns,
|
|
169
|
+
ext: extensions,
|
|
163
170
|
delay: options.delay || 1000,
|
|
171
|
+
clearConsole: options.clear,
|
|
164
172
|
verbose: options.verbose,
|
|
165
|
-
|
|
173
|
+
showInfo: showInfo,
|
|
174
|
+
signal: options.signal,
|
|
175
|
+
restartOnChange: true,
|
|
176
|
+
groupOutput: false,
|
|
177
|
+
isServerMode: false
|
|
166
178
|
});
|
|
167
179
|
// Start the development server
|
|
168
180
|
await devRunner.start([commandToExecute]);
|
|
169
181
|
}
|
|
170
182
|
catch (error) {
|
|
171
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} neex dev:
|
|
183
|
+
console.error(chalk_1.default.red(`${figures_1.default.cross} neex dev: Fatal error occurred`));
|
|
184
|
+
if (error instanceof Error) {
|
|
185
|
+
console.error(chalk_1.default.red(`${figures_1.default.cross} Details: ${error.message}`));
|
|
186
|
+
if (options.verbose && error.stack) {
|
|
187
|
+
console.error(chalk_1.default.gray(`Stack trace:\n${error.stack}`));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
console.error(chalk_1.default.red(`${figures_1.default.cross} Unknown error occurred`));
|
|
192
|
+
}
|
|
193
|
+
console.error(chalk_1.default.yellow(`${figures_1.default.pointer} Try running with --verbose flag for more details`));
|
|
172
194
|
process.exit(1);
|
|
173
195
|
}
|
|
174
196
|
});
|
package/dist/src/dev-runner.js
CHANGED
|
@@ -16,9 +16,6 @@ class DevRunner {
|
|
|
16
16
|
this.isRunning = false;
|
|
17
17
|
this.restartCount = 0;
|
|
18
18
|
this.startTime = new Date();
|
|
19
|
-
this.serverInfo = new Map();
|
|
20
|
-
this.portRegex = /\bport\s+(\d+)\b/;
|
|
21
|
-
this.urlRegex = /\burl:\s*(https?:\/\/[^\s]+)/;
|
|
22
19
|
const defaultOptions = {
|
|
23
20
|
parallel: false,
|
|
24
21
|
printOutput: true,
|
|
@@ -47,7 +44,8 @@ class DevRunner {
|
|
|
47
44
|
ext: ['js', 'mjs', 'json', 'ts', 'tsx', 'jsx'],
|
|
48
45
|
delay: 1000,
|
|
49
46
|
verbose: false,
|
|
50
|
-
|
|
47
|
+
showInfo: false,
|
|
48
|
+
runnerName: 'neex dev',
|
|
51
49
|
};
|
|
52
50
|
this.options = {
|
|
53
51
|
...defaultOptions,
|
|
@@ -60,7 +58,7 @@ class DevRunner {
|
|
|
60
58
|
ignore: this.options.ignore,
|
|
61
59
|
ext: this.options.ext,
|
|
62
60
|
delay: this.options.delay,
|
|
63
|
-
verbose: this.options.verbose
|
|
61
|
+
verbose: this.options.verbose && this.options.showInfo // Only show verbose watcher logs if both verbose and showInfo are true
|
|
64
62
|
};
|
|
65
63
|
this.fileWatcher = new watcher_1.FileWatcher(watchOptions);
|
|
66
64
|
this.fileWatcher.on('change', (event) => {
|
|
@@ -71,7 +69,9 @@ class DevRunner {
|
|
|
71
69
|
}
|
|
72
70
|
async handleFileChange(event) {
|
|
73
71
|
const prefix = chalk_1.default.cyan(`[${this.options.runnerName}]`);
|
|
74
|
-
|
|
72
|
+
if (this.options.showInfo) {
|
|
73
|
+
logger_1.default.printLine(`${prefix} File changed: ${chalk_1.default.yellow(event.relativePath)}`, 'info');
|
|
74
|
+
}
|
|
75
75
|
if (this.options.clearConsole) {
|
|
76
76
|
console.clear();
|
|
77
77
|
}
|
|
@@ -81,64 +81,49 @@ class DevRunner {
|
|
|
81
81
|
if (this.commands.length === 0) {
|
|
82
82
|
return [];
|
|
83
83
|
}
|
|
84
|
-
|
|
84
|
+
// Create a modified options object for the runner to clean up output
|
|
85
|
+
const runnerOptions = {
|
|
86
|
+
...this.options,
|
|
87
|
+
// Override prefix behavior to show clean command name
|
|
88
|
+
customPrefix: (command) => {
|
|
89
|
+
// Extract just the filename from the command
|
|
90
|
+
const match = command.match(/(?:npx ts-node|node)\s+(.+)/);
|
|
91
|
+
if (match) {
|
|
92
|
+
const filePath = match[1];
|
|
93
|
+
const fileName = filePath.split('/').pop() || filePath;
|
|
94
|
+
return `${fileName}`;
|
|
95
|
+
}
|
|
96
|
+
return command;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
this.runner = new runner_1.Runner(runnerOptions);
|
|
85
100
|
try {
|
|
86
101
|
const results = await this.runner.run(this.commands);
|
|
87
|
-
results.forEach((result, index) => {
|
|
88
|
-
if (result.output) {
|
|
89
|
-
result.output.forEach(output => {
|
|
90
|
-
this.detectServerInfo(this.commands[index], output.data);
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
102
|
return results;
|
|
95
103
|
}
|
|
96
104
|
catch (error) {
|
|
97
|
-
|
|
105
|
+
if (this.options.showInfo) {
|
|
106
|
+
logger_1.default.printLine(`Execution failed: ${error.message}`, 'error');
|
|
107
|
+
}
|
|
98
108
|
return [];
|
|
99
109
|
}
|
|
100
110
|
}
|
|
101
|
-
detectServerInfo(command, data) {
|
|
102
|
-
if (!this.options.isServerMode)
|
|
103
|
-
return;
|
|
104
|
-
// Get or create server info
|
|
105
|
-
let serverInfo = this.serverInfo.get(command);
|
|
106
|
-
if (!serverInfo) {
|
|
107
|
-
serverInfo = {
|
|
108
|
-
name: command,
|
|
109
|
-
status: 'starting'
|
|
110
|
-
};
|
|
111
|
-
this.serverInfo.set(command, serverInfo);
|
|
112
|
-
}
|
|
113
|
-
// Try to detect port from output
|
|
114
|
-
const portMatch = data.match(this.portRegex);
|
|
115
|
-
if (portMatch && portMatch[1]) {
|
|
116
|
-
serverInfo.port = parseInt(portMatch[1], 10);
|
|
117
|
-
serverInfo.status = 'running';
|
|
118
|
-
}
|
|
119
|
-
// Try to detect full URL from output
|
|
120
|
-
const urlMatch = data.match(this.urlRegex);
|
|
121
|
-
if (urlMatch && urlMatch[1]) {
|
|
122
|
-
serverInfo.url = urlMatch[1];
|
|
123
|
-
serverInfo.status = 'running';
|
|
124
|
-
}
|
|
125
|
-
// Update server info
|
|
126
|
-
this.serverInfo.set(command, serverInfo);
|
|
127
|
-
}
|
|
128
111
|
printDevBanner() {
|
|
129
|
-
var _a, _b;
|
|
112
|
+
var _a, _b, _c;
|
|
113
|
+
if (!this.options.showInfo) {
|
|
114
|
+
return; // Don't show banner if showInfo is false
|
|
115
|
+
}
|
|
130
116
|
const prefix = chalk_1.default.cyan(`[${this.options.runnerName}]`);
|
|
131
117
|
const uptime = Math.floor((Date.now() - this.startTime.getTime()) / 1000);
|
|
132
118
|
const uptimeStr = this.formatUptime(uptime);
|
|
133
|
-
if (this.options.
|
|
134
|
-
console.log(
|
|
119
|
+
if (this.options.showInfo) {
|
|
120
|
+
console.log(chalk_1.default.blue(`${prefix} ${figures_1.default.info} Starting file watcher...`));
|
|
121
|
+
console.log(chalk_1.default.blue(`${prefix} ${figures_1.default.info} File watcher started. Monitoring ${((_a = this.options.watch) === null || _a === void 0 ? void 0 : _a.length) || 1} locations`));
|
|
122
|
+
console.log(chalk_1.default.blue(`${prefix} ${figures_1.default.info} Watching extensions: ${((_b = this.options.ext) === null || _b === void 0 ? void 0 : _b.join(', ')) || 'js, mjs, json, ts, tsx, jsx, vue, svelte'}`));
|
|
123
|
+
console.log(chalk_1.default.blue(`${prefix} ${figures_1.default.info} Uptime: ${uptimeStr}`));
|
|
124
|
+
console.log(chalk_1.default.blue(`${prefix} ${figures_1.default.info} Watching: ${((_c = this.options.watch) === null || _c === void 0 ? void 0 : _c.join(', ')) || 'current directory'}`));
|
|
135
125
|
if (this.restartCount > 0) {
|
|
136
|
-
console.log(`${prefix} ${
|
|
137
|
-
}
|
|
138
|
-
console.log(`${prefix} ${chalk_1.default.blue(`${figures_1.default.info} Uptime: ${uptimeStr}`)}`);
|
|
139
|
-
console.log(`${prefix} ${chalk_1.default.blue(`${figures_1.default.info} Watching: ${((_b = this.options.watch) === null || _b === void 0 ? void 0 : _b.join(', ')) || 'current directory'}`)}`);
|
|
140
|
-
if (this.options.ext && this.options.ext.length > 0) {
|
|
141
|
-
console.log(`${prefix} ${chalk_1.default.blue(`${figures_1.default.info} Extensions: ${this.options.ext.join(', ')}`)}`);
|
|
126
|
+
console.log(chalk_1.default.blue(`${prefix} ${figures_1.default.info} Restarted ${this.restartCount} times`));
|
|
142
127
|
}
|
|
143
128
|
console.log('');
|
|
144
129
|
}
|
|
@@ -164,7 +149,7 @@ class DevRunner {
|
|
|
164
149
|
this.startTime = new Date();
|
|
165
150
|
// Setup file watcher
|
|
166
151
|
this.setupFileWatcher();
|
|
167
|
-
// Print development banner
|
|
152
|
+
// Print development banner only if showInfo is true
|
|
168
153
|
this.printDevBanner();
|
|
169
154
|
// Start file watcher
|
|
170
155
|
if (this.fileWatcher) {
|
|
@@ -172,19 +157,25 @@ class DevRunner {
|
|
|
172
157
|
}
|
|
173
158
|
// Run initial commands
|
|
174
159
|
const prefix = chalk_1.default.cyan(`[${this.options.runnerName}]`);
|
|
175
|
-
|
|
160
|
+
if (this.options.showInfo) {
|
|
161
|
+
logger_1.default.printLine(`${prefix} Starting development server...`, 'info');
|
|
162
|
+
}
|
|
176
163
|
await this.runCommands();
|
|
177
164
|
// Set up graceful shutdown
|
|
178
165
|
this.setupGracefulShutdown();
|
|
179
|
-
|
|
180
|
-
|
|
166
|
+
if (this.options.showInfo) {
|
|
167
|
+
logger_1.default.printLine(`${prefix} Development server started. Watching for changes...`, 'info');
|
|
168
|
+
logger_1.default.printLine(`${prefix} Press ${chalk_1.default.cyan('Ctrl+C')} to stop`, 'info');
|
|
169
|
+
}
|
|
181
170
|
}
|
|
182
171
|
async restart() {
|
|
183
172
|
const prefix = chalk_1.default.cyan(`[${this.options.runnerName}]`);
|
|
184
173
|
if (!this.isRunning) {
|
|
185
174
|
return;
|
|
186
175
|
}
|
|
187
|
-
|
|
176
|
+
if (this.options.showInfo) {
|
|
177
|
+
logger_1.default.printLine(`${prefix} Restarting due to file changes...`, 'info');
|
|
178
|
+
}
|
|
188
179
|
this.restartCount++;
|
|
189
180
|
// Stop current processes
|
|
190
181
|
if (this.runner) {
|
|
@@ -192,18 +183,22 @@ class DevRunner {
|
|
|
192
183
|
}
|
|
193
184
|
// Wait a moment before restarting
|
|
194
185
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
195
|
-
// Print restart banner
|
|
186
|
+
// Print restart banner only if showInfo is true
|
|
196
187
|
this.printDevBanner();
|
|
197
188
|
// Run commands again
|
|
198
189
|
await this.runCommands();
|
|
199
|
-
|
|
190
|
+
if (this.options.showInfo) {
|
|
191
|
+
logger_1.default.printLine(`${prefix} Restart completed. Watching for changes...`, 'info');
|
|
192
|
+
}
|
|
200
193
|
}
|
|
201
194
|
async stop() {
|
|
202
195
|
const prefix = chalk_1.default.cyan(`[${this.options.runnerName}]`);
|
|
203
196
|
if (!this.isRunning) {
|
|
204
197
|
return;
|
|
205
198
|
}
|
|
206
|
-
|
|
199
|
+
if (this.options.showInfo) {
|
|
200
|
+
logger_1.default.printLine(`${prefix} Stopping development server...`, 'info');
|
|
201
|
+
}
|
|
207
202
|
this.isRunning = false;
|
|
208
203
|
// Stop file watcher
|
|
209
204
|
if (this.fileWatcher) {
|
|
@@ -215,14 +210,18 @@ class DevRunner {
|
|
|
215
210
|
}
|
|
216
211
|
const uptime = Math.floor((Date.now() - this.startTime.getTime()) / 1000);
|
|
217
212
|
const uptimeStr = this.formatUptime(uptime);
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
213
|
+
if (this.options.showInfo) {
|
|
214
|
+
logger_1.default.printLine(`${prefix} ${this.options.runnerName} development server stopped after ${uptimeStr}`, 'info');
|
|
215
|
+
if (this.restartCount > 0) {
|
|
216
|
+
logger_1.default.printLine(`${prefix} Total restarts: ${this.restartCount}`, 'info');
|
|
217
|
+
}
|
|
221
218
|
}
|
|
222
219
|
}
|
|
223
220
|
setupGracefulShutdown() {
|
|
224
221
|
const handleSignal = (signal) => {
|
|
225
|
-
|
|
222
|
+
if (this.options.showInfo) {
|
|
223
|
+
console.log(`\n${chalk_1.default.yellow(`${figures_1.default.warning} Received ${signal}. Shutting down development server...`)}`);
|
|
224
|
+
}
|
|
226
225
|
this.stop().then(() => {
|
|
227
226
|
process.exit(0);
|
|
228
227
|
});
|