neex 0.7.20 → 0.7.31
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 +13 -31
- package/dist/bin/neex.d.ts +26 -0
- package/dist/bin/neex.d.ts.map +1 -0
- package/dist/src/build-manager.d.ts +41 -0
- package/dist/src/build-manager.d.ts.map +1 -0
- package/dist/src/build-manager.js +26 -24
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/commands/build-commands.d.ts +5 -0
- package/dist/src/commands/build-commands.d.ts.map +1 -0
- package/dist/src/commands/build-commands.js +2 -2
- package/dist/src/commands/dev-commands.d.ts +5 -0
- package/dist/src/commands/dev-commands.d.ts.map +1 -0
- package/dist/src/commands/dev-commands.js +5 -3
- package/dist/src/commands/index.d.ts +7 -0
- package/dist/src/commands/index.d.ts.map +1 -0
- package/dist/src/commands/init-commands.d.ts +2 -0
- package/dist/src/commands/init-commands.d.ts.map +1 -0
- package/dist/src/commands/init-commands.js +4 -4
- package/dist/src/commands/run-commands.d.ts +3 -0
- package/dist/src/commands/run-commands.d.ts.map +1 -0
- package/dist/src/commands/run-commands.js +26 -26
- package/dist/src/commands/server-commands.d.ts +3 -0
- package/dist/src/commands/server-commands.d.ts.map +1 -0
- package/dist/src/commands/server-commands.js +4 -2
- package/dist/src/commands/start-commands.d.ts +5 -0
- package/dist/src/commands/start-commands.d.ts.map +1 -0
- package/dist/src/commands/start-commands.js +2 -2
- package/dist/src/dev-manager.d.ts +51 -0
- package/dist/src/dev-manager.d.ts.map +1 -0
- package/dist/src/dev-manager.js +29 -21
- package/dist/src/index.d.ts +41 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +15 -16
- package/dist/src/logger-manager.d.ts +4 -0
- package/dist/src/logger-manager.d.ts.map +1 -0
- package/dist/src/logger-manager.js +4 -4
- package/dist/src/logger.d.ts +34 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +21 -15
- package/dist/src/runner.d.ts +21 -0
- package/dist/src/runner.d.ts.map +1 -0
- package/dist/src/runner.js +38 -25
- package/dist/src/start-manager.d.ts +49 -0
- package/dist/src/start-manager.d.ts.map +1 -0
- package/dist/src/start-manager.js +34 -29
- package/dist/src/types.d.ts +41 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/utils.d.ts +2 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/package.json +14 -9
- package/dist/src/cli-init.js +0 -1
- package/dist/src/commands/process-commands.js +0 -759
- package/dist/src/config.js +0 -59
- package/dist/src/dev-runner.js +0 -234
- package/dist/src/logger-process.js +0 -17
- package/dist/src/process-manager.js +0 -669
- package/dist/src/watcher.js +0 -245
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export interface DevOptions {
|
|
2
|
+
file: string;
|
|
3
|
+
watch: string[];
|
|
4
|
+
ignore: string[];
|
|
5
|
+
extensions: string[];
|
|
6
|
+
delay: number;
|
|
7
|
+
color: boolean;
|
|
8
|
+
quiet: boolean;
|
|
9
|
+
verbose: boolean;
|
|
10
|
+
clearConsole: boolean;
|
|
11
|
+
inspect: boolean;
|
|
12
|
+
inspectBrk: boolean;
|
|
13
|
+
envFile: string;
|
|
14
|
+
execCommand?: string;
|
|
15
|
+
tsConfig?: string;
|
|
16
|
+
sourceMaps: boolean;
|
|
17
|
+
transpileOnly: boolean;
|
|
18
|
+
nodeArgs: string[];
|
|
19
|
+
}
|
|
20
|
+
export declare class DevManager {
|
|
21
|
+
private options;
|
|
22
|
+
private process;
|
|
23
|
+
private watcher;
|
|
24
|
+
private isRestarting;
|
|
25
|
+
private restartCount;
|
|
26
|
+
private startTime;
|
|
27
|
+
private debouncedRestart;
|
|
28
|
+
private moduleCache;
|
|
29
|
+
private tsCompilerOptions;
|
|
30
|
+
private tempDir;
|
|
31
|
+
private currentTempFile;
|
|
32
|
+
private isShuttingDown;
|
|
33
|
+
constructor(options: DevOptions);
|
|
34
|
+
private setupTempDir;
|
|
35
|
+
private loadTsConfig;
|
|
36
|
+
private loadEnvFile;
|
|
37
|
+
private createHash;
|
|
38
|
+
private extractDependencies;
|
|
39
|
+
private compileModule;
|
|
40
|
+
private invalidateModuleCache;
|
|
41
|
+
private createExecutableFile;
|
|
42
|
+
private getExecuteCommand;
|
|
43
|
+
private clearConsole;
|
|
44
|
+
private startProcess;
|
|
45
|
+
private stopProcess;
|
|
46
|
+
private restart;
|
|
47
|
+
private setupWatcher;
|
|
48
|
+
start(): Promise<void>;
|
|
49
|
+
stop(): Promise<void>;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=dev-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-manager.d.ts","sourceRoot":"","sources":["../../src/dev-manager.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAUD,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,iBAAiB,CAAqB;IAC9C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,cAAc,CAAS;gBAEnB,OAAO,EAAE,UAAU;IAW/B,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,YAAY;IA2CpB,OAAO,CAAC,WAAW;IAwCnB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,mBAAmB;IA0C3B,OAAO,CAAC,aAAa;IAoDrB,OAAO,CAAC,qBAAqB;IA0B7B,OAAO,CAAC,oBAAoB;YAqCd,iBAAiB;IAoB/B,OAAO,CAAC,YAAY;YAMN,YAAY;YA2DZ,WAAW;YA6BX,OAAO;IAqBrB,OAAO,CAAC,YAAY;IAsEP,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgCtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CA6BnC"}
|
package/dist/src/dev-manager.js
CHANGED
|
@@ -49,15 +49,19 @@ const lodash_1 = require("lodash");
|
|
|
49
49
|
const ts = __importStar(require("typescript"));
|
|
50
50
|
const crypto_1 = __importDefault(require("crypto"));
|
|
51
51
|
class DevManager {
|
|
52
|
+
options;
|
|
53
|
+
process = null;
|
|
54
|
+
watcher = null;
|
|
55
|
+
isRestarting = false;
|
|
56
|
+
restartCount = 0;
|
|
57
|
+
startTime = null;
|
|
58
|
+
debouncedRestart;
|
|
59
|
+
moduleCache = new Map();
|
|
60
|
+
tsCompilerOptions;
|
|
61
|
+
tempDir;
|
|
62
|
+
currentTempFile = null;
|
|
63
|
+
isShuttingDown = false;
|
|
52
64
|
constructor(options) {
|
|
53
|
-
this.process = null;
|
|
54
|
-
this.watcher = null;
|
|
55
|
-
this.isRestarting = false;
|
|
56
|
-
this.restartCount = 0;
|
|
57
|
-
this.startTime = null;
|
|
58
|
-
this.moduleCache = new Map();
|
|
59
|
-
this.currentTempFile = null;
|
|
60
|
-
this.isShuttingDown = false;
|
|
61
65
|
this.options = options;
|
|
62
66
|
this.tempDir = path_1.default.join(process.cwd(), '.neex-temp');
|
|
63
67
|
this.debouncedRestart = (0, lodash_1.debounce)(this.restart.bind(this), Math.max(options.delay, 100));
|
|
@@ -123,7 +127,10 @@ class DevManager {
|
|
|
123
127
|
if (trimmed && !trimmed.startsWith('#')) {
|
|
124
128
|
const [key, ...values] = trimmed.split('=');
|
|
125
129
|
if (key && values.length > 0) {
|
|
126
|
-
process.env[key.trim()] = values
|
|
130
|
+
process.env[key.trim()] = values
|
|
131
|
+
.join('=')
|
|
132
|
+
.trim()
|
|
133
|
+
.replace(/^["']|["']$/g, '');
|
|
127
134
|
count++;
|
|
128
135
|
}
|
|
129
136
|
}
|
|
@@ -192,14 +199,14 @@ class DevManager {
|
|
|
192
199
|
const result = ts.transpileModule(sourceCode, {
|
|
193
200
|
compilerOptions: this.tsCompilerOptions,
|
|
194
201
|
fileName: absolutePath,
|
|
195
|
-
reportDiagnostics: false // Skip diagnostics for speed
|
|
202
|
+
reportDiagnostics: false, // Skip diagnostics for speed
|
|
196
203
|
});
|
|
197
204
|
const moduleInfo = {
|
|
198
205
|
code: result.outputText,
|
|
199
206
|
map: result.sourceMapText,
|
|
200
207
|
hash,
|
|
201
208
|
timestamp: Date.now(),
|
|
202
|
-
dependencies
|
|
209
|
+
dependencies,
|
|
203
210
|
};
|
|
204
211
|
this.moduleCache.set(absolutePath, moduleInfo);
|
|
205
212
|
if (this.options.verbose) {
|
|
@@ -283,7 +290,6 @@ class DevManager {
|
|
|
283
290
|
}
|
|
284
291
|
}
|
|
285
292
|
async startProcess() {
|
|
286
|
-
var _a, _b;
|
|
287
293
|
if (this.process)
|
|
288
294
|
return;
|
|
289
295
|
this.loadEnvFile();
|
|
@@ -297,25 +303,27 @@ class DevManager {
|
|
|
297
303
|
FORCE_COLOR: this.options.color ? '1' : '0',
|
|
298
304
|
NODE_OPTIONS: '--max-old-space-size=4096', // Prevent memory issues
|
|
299
305
|
},
|
|
300
|
-
detached: false // Keep attached for better cleanup
|
|
306
|
+
detached: false, // Keep attached for better cleanup
|
|
301
307
|
});
|
|
302
308
|
this.startTime = new Date();
|
|
303
309
|
this.restartCount++;
|
|
304
310
|
// Handle stdout/stderr
|
|
305
|
-
|
|
311
|
+
this.process.stdout?.on('data', data => {
|
|
306
312
|
process.stdout.write(data);
|
|
307
313
|
});
|
|
308
|
-
|
|
314
|
+
this.process.stderr?.on('data', data => {
|
|
309
315
|
process.stderr.write(data);
|
|
310
316
|
});
|
|
311
|
-
this.process.on('error',
|
|
317
|
+
this.process.on('error', error => {
|
|
312
318
|
logger_manager_js_1.loggerManager.printLine(`Process error: ${error.message}`, 'error');
|
|
313
319
|
});
|
|
314
320
|
this.process.on('exit', (code, signal) => {
|
|
315
321
|
if (this.process) {
|
|
316
322
|
this.process = null;
|
|
317
323
|
if (!this.isRestarting && code !== 0) {
|
|
318
|
-
const duration = this.startTime
|
|
324
|
+
const duration = this.startTime
|
|
325
|
+
? Date.now() - this.startTime.getTime()
|
|
326
|
+
: 0;
|
|
319
327
|
logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red('✖')} Process exited with code ${code} (${duration}ms)`, 'error');
|
|
320
328
|
}
|
|
321
329
|
}
|
|
@@ -329,7 +337,7 @@ class DevManager {
|
|
|
329
337
|
async stopProcess() {
|
|
330
338
|
if (!this.process)
|
|
331
339
|
return;
|
|
332
|
-
return new Promise(
|
|
340
|
+
return new Promise(resolve => {
|
|
333
341
|
const proc = this.process;
|
|
334
342
|
this.process = null;
|
|
335
343
|
const cleanup = () => {
|
|
@@ -379,7 +387,7 @@ class DevManager {
|
|
|
379
387
|
'**/*.d.ts',
|
|
380
388
|
'**/*.map',
|
|
381
389
|
'**/*.tsbuildinfo',
|
|
382
|
-
...this.options.ignore
|
|
390
|
+
...this.options.ignore,
|
|
383
391
|
];
|
|
384
392
|
this.watcher = (0, chokidar_1.watch)(watchPatterns, {
|
|
385
393
|
ignored,
|
|
@@ -389,8 +397,8 @@ class DevManager {
|
|
|
389
397
|
atomic: 50, // Very fast detection
|
|
390
398
|
awaitWriteFinish: {
|
|
391
399
|
stabilityThreshold: 100,
|
|
392
|
-
pollInterval: 50
|
|
393
|
-
}
|
|
400
|
+
pollInterval: 50,
|
|
401
|
+
},
|
|
394
402
|
});
|
|
395
403
|
this.watcher.on('change', (filePath) => {
|
|
396
404
|
this.invalidateModuleCache(filePath);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { RunOptions, RunResult } from './types';
|
|
2
|
+
export { RunOptions, RunResult };
|
|
3
|
+
export interface neexOptions {
|
|
4
|
+
parallel?: boolean;
|
|
5
|
+
maxParallel?: number;
|
|
6
|
+
printOutput?: boolean;
|
|
7
|
+
color?: boolean;
|
|
8
|
+
showTiming?: boolean;
|
|
9
|
+
prefix?: boolean;
|
|
10
|
+
stopOnError?: boolean;
|
|
11
|
+
minimalOutput?: boolean;
|
|
12
|
+
groupOutput?: boolean;
|
|
13
|
+
isServerMode?: boolean;
|
|
14
|
+
retry?: number;
|
|
15
|
+
retryDelay?: number;
|
|
16
|
+
registerCleanup?: (cleanupFn: () => void) => void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Run one or more commands in parallel or sequentially
|
|
20
|
+
*/
|
|
21
|
+
export declare function run(commands: string | string[], options?: neexOptions): Promise<RunResult[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Run multiple commands in parallel
|
|
24
|
+
*/
|
|
25
|
+
export declare function runParallel(commands: string | string[], options?: Omit<neexOptions, 'parallel'>): Promise<RunResult[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Run multiple commands sequentially
|
|
28
|
+
*/
|
|
29
|
+
export declare function runSequential(commands: string | string[], options?: Omit<neexOptions, 'parallel'>): Promise<RunResult[]>;
|
|
30
|
+
/**
|
|
31
|
+
* Run multiple servers with optimized output
|
|
32
|
+
*/
|
|
33
|
+
export declare function runServers(commands: string | string[], options?: Omit<neexOptions, 'parallel' | 'isServerMode'>): Promise<RunResult[]>;
|
|
34
|
+
declare const _default: {
|
|
35
|
+
run: typeof run;
|
|
36
|
+
runParallel: typeof runParallel;
|
|
37
|
+
runSequential: typeof runSequential;
|
|
38
|
+
runServers: typeof runServers;
|
|
39
|
+
};
|
|
40
|
+
export default _default;
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGhD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;AAEjC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;CACnD;AAED;;GAEG;AACH,wBAAsB,GAAG,CACvB,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,EAC3B,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CA+BtB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,EAC3B,OAAO,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,GACtC,OAAO,CAAC,SAAS,EAAE,CAAC,CAEtB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,EAC3B,OAAO,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,GACtC,OAAO,CAAC,SAAS,EAAE,CAAC,CAEtB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,EAC3B,OAAO,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,cAAc,CAAC,GACvD,OAAO,CAAC,SAAS,EAAE,CAAC,CAOtB;;;;;;;AAED,wBAKE"}
|
package/dist/src/index.js
CHANGED
|
@@ -14,24 +14,23 @@ const logger_1 = __importDefault(require("./logger"));
|
|
|
14
14
|
* Run one or more commands in parallel or sequentially
|
|
15
15
|
*/
|
|
16
16
|
async function run(commands, options) {
|
|
17
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
18
17
|
const cmdArray = Array.isArray(commands) ? commands : [commands];
|
|
19
18
|
const runOptions = {
|
|
20
|
-
parallel:
|
|
21
|
-
maxParallel: options
|
|
22
|
-
printOutput:
|
|
23
|
-
color:
|
|
24
|
-
showTiming:
|
|
25
|
-
prefix:
|
|
26
|
-
stopOnError:
|
|
27
|
-
minimalOutput:
|
|
28
|
-
groupOutput:
|
|
29
|
-
isServerMode:
|
|
30
|
-
retry: options
|
|
31
|
-
retryDelay: options
|
|
19
|
+
parallel: options?.parallel ?? false,
|
|
20
|
+
maxParallel: options?.maxParallel,
|
|
21
|
+
printOutput: options?.printOutput ?? true,
|
|
22
|
+
color: options?.color ?? true,
|
|
23
|
+
showTiming: options?.showTiming ?? true,
|
|
24
|
+
prefix: options?.prefix ?? true,
|
|
25
|
+
stopOnError: options?.stopOnError ?? false,
|
|
26
|
+
minimalOutput: options?.minimalOutput ?? false,
|
|
27
|
+
groupOutput: options?.groupOutput ?? false,
|
|
28
|
+
isServerMode: options?.isServerMode ?? false,
|
|
29
|
+
retry: options?.retry,
|
|
30
|
+
retryDelay: options?.retryDelay,
|
|
32
31
|
};
|
|
33
32
|
const runner = new runner_1.Runner(runOptions);
|
|
34
|
-
if (options
|
|
33
|
+
if (options?.registerCleanup) {
|
|
35
34
|
options.registerCleanup(() => runner.cleanup());
|
|
36
35
|
}
|
|
37
36
|
const results = await runner.run(cmdArray);
|
|
@@ -60,12 +59,12 @@ async function runServers(commands, options) {
|
|
|
60
59
|
...options,
|
|
61
60
|
parallel: true,
|
|
62
61
|
isServerMode: true,
|
|
63
|
-
printOutput: true
|
|
62
|
+
printOutput: true,
|
|
64
63
|
});
|
|
65
64
|
}
|
|
66
65
|
exports.default = {
|
|
67
66
|
run,
|
|
68
67
|
runParallel,
|
|
69
68
|
runSequential,
|
|
70
|
-
runServers
|
|
69
|
+
runServers,
|
|
71
70
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger-manager.d.ts","sourceRoot":"","sources":["../../src/logger-manager.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa;yBACH,MAAM,UAAS,MAAM,GAAG,MAAM,GAAG,OAAO;CAS9D,CAAC"}
|
|
@@ -6,11 +6,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.loggerManager = void 0;
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
8
|
exports.loggerManager = {
|
|
9
|
-
printLine: (message, level =
|
|
9
|
+
printLine: (message, level = 'info') => {
|
|
10
10
|
const prefix = {
|
|
11
|
-
info: chalk_1.default.blue(
|
|
12
|
-
warn: chalk_1.default.yellow(
|
|
13
|
-
error: chalk_1.default.red(
|
|
11
|
+
info: chalk_1.default.blue('i'),
|
|
12
|
+
warn: chalk_1.default.yellow('!'),
|
|
13
|
+
error: chalk_1.default.red('x'),
|
|
14
14
|
}[level];
|
|
15
15
|
console.log(`${prefix} ${message}`);
|
|
16
16
|
},
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { CommandOutput, RunResult } from './types';
|
|
2
|
+
declare class Logger {
|
|
3
|
+
private static instance;
|
|
4
|
+
private prefixLength;
|
|
5
|
+
private outputBuffer;
|
|
6
|
+
private commandColors;
|
|
7
|
+
private startTimes;
|
|
8
|
+
private spinnerFrames;
|
|
9
|
+
private spinnerIndex;
|
|
10
|
+
private spinnerIntervals;
|
|
11
|
+
private isSpinnerActive;
|
|
12
|
+
private constructor();
|
|
13
|
+
static getInstance(): Logger;
|
|
14
|
+
private getSpinnerFrame;
|
|
15
|
+
private showBanner;
|
|
16
|
+
setCommands(commands: string[]): void;
|
|
17
|
+
private generateColor;
|
|
18
|
+
formatPrefix(command: string): string;
|
|
19
|
+
bufferOutput(output: CommandOutput): void;
|
|
20
|
+
printBuffer(command: string): void;
|
|
21
|
+
clearBuffer(command: string): void;
|
|
22
|
+
printLine(message: string, level?: 'info' | 'error' | 'warn'): void;
|
|
23
|
+
printStart(command: string): void;
|
|
24
|
+
startSpinner(command: string): void;
|
|
25
|
+
stopSpinner(command: string): void;
|
|
26
|
+
stopAllSpinners(): void;
|
|
27
|
+
printSuccess(result: RunResult): void;
|
|
28
|
+
printError(result: RunResult): void;
|
|
29
|
+
printEnd(result: RunResult, minimalOutput: boolean): void;
|
|
30
|
+
printSummary(results: RunResult[]): void;
|
|
31
|
+
}
|
|
32
|
+
declare const _default: Logger;
|
|
33
|
+
export default _default;
|
|
34
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGnD,cAAM,MAAM;IACV,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAS;IAChC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,YAAY,CAA2C;IAC/D,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,aAAa,CAAsD;IAC3E,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,gBAAgB,CAA0C;IAClE,OAAO,CAAC,eAAe,CAAS;IAEhC,OAAO;IAEP,MAAM,CAAC,WAAW,IAAI,MAAM;IAO5B,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,UAAU;IAMlB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI;IAyBrC,OAAO,CAAC,aAAa;IAyBrB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAMrC,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAMzC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAyClC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIlC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,GAAG,OAAO,GAAG,MAAe,GAAG,IAAI;IAU3E,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAuBjC,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAoBnC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAelC,eAAe,IAAI,IAAI;IAevB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAerC,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAmBnC,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,GAAG,IAAI;IAqCzD,YAAY,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI;CAyDzC;;AAED,wBAAoC"}
|
package/dist/src/logger.js
CHANGED
|
@@ -9,16 +9,16 @@ const figures_1 = __importDefault(require("figures"));
|
|
|
9
9
|
const string_width_1 = __importDefault(require("string-width"));
|
|
10
10
|
const utils_1 = require("./utils");
|
|
11
11
|
class Logger {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
12
|
+
static instance;
|
|
13
|
+
prefixLength = 0;
|
|
14
|
+
outputBuffer = new Map();
|
|
15
|
+
commandColors = new Map();
|
|
16
|
+
startTimes = new Map();
|
|
17
|
+
spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
18
|
+
spinnerIndex = 0;
|
|
19
|
+
spinnerIntervals = new Map();
|
|
20
|
+
isSpinnerActive = false;
|
|
21
|
+
constructor() { }
|
|
22
22
|
static getInstance() {
|
|
23
23
|
if (!Logger.instance) {
|
|
24
24
|
Logger.instance = new Logger();
|
|
@@ -65,7 +65,7 @@ class Logger {
|
|
|
65
65
|
'#0066FF', // Deep Pink
|
|
66
66
|
'#4169E1', // Royal Blue
|
|
67
67
|
'#FFD700', // Gold
|
|
68
|
-
'#8A2BE2' // Blue Violet
|
|
68
|
+
'#8A2BE2', // Blue Violet
|
|
69
69
|
];
|
|
70
70
|
let hash = 0;
|
|
71
71
|
for (let i = 0; i < command.length; i++) {
|
|
@@ -101,7 +101,8 @@ class Logger {
|
|
|
101
101
|
// Show stderr in appropriate colors
|
|
102
102
|
if (output.type === 'stderr') {
|
|
103
103
|
// Not all stderr is an error, check for warning or info patterns
|
|
104
|
-
if (line.toLowerCase().includes('warn') ||
|
|
104
|
+
if (line.toLowerCase().includes('warn') ||
|
|
105
|
+
line.toLowerCase().includes('warning')) {
|
|
105
106
|
console.log(`${prefix} ${chalk_1.default.yellow(line)}`);
|
|
106
107
|
}
|
|
107
108
|
else if (line.toLowerCase().includes('error')) {
|
|
@@ -143,7 +144,8 @@ class Logger {
|
|
|
143
144
|
// Stop any previous spinner for this command (e.g. if retrying)
|
|
144
145
|
this.stopSpinner(command);
|
|
145
146
|
// Clear the line before printing "Starting..."
|
|
146
|
-
if (this.isSpinnerActive) {
|
|
147
|
+
if (this.isSpinnerActive) {
|
|
148
|
+
// Check if any spinner was active to avoid clearing unnecessarily
|
|
147
149
|
process.stdout.write('\r' + ' '.repeat(process.stdout.columns || 80) + '\r');
|
|
148
150
|
}
|
|
149
151
|
console.log(`${prefix} ${color('Starting...')}`);
|
|
@@ -200,7 +202,9 @@ class Logger {
|
|
|
200
202
|
const { command, error, code, duration } = result;
|
|
201
203
|
this.stopSpinner(command);
|
|
202
204
|
const prefix = this.formatPrefix(command);
|
|
203
|
-
const durationStr = duration
|
|
205
|
+
const durationStr = duration
|
|
206
|
+
? ` ${chalk_1.default.dim(`(${(duration / 1000).toFixed(2)}s)`)}`
|
|
207
|
+
: '';
|
|
204
208
|
const errorCode = code !== null ? ` ${chalk_1.default.red(`[code: ${code}]`)}` : '';
|
|
205
209
|
console.error(`${prefix} ${chalk_1.default.red(figures_1.default.cross)} ${chalk_1.default.red('Failed')}${errorCode}${durationStr}`);
|
|
206
210
|
if (error) {
|
|
@@ -240,7 +244,9 @@ class Logger {
|
|
|
240
244
|
const failed = results.length - successful;
|
|
241
245
|
const totalDuration = results.reduce((sum, result) => sum + (result.duration || 0), 0);
|
|
242
246
|
const totalSeconds = (totalDuration / 1000).toFixed(2);
|
|
243
|
-
console.log('\n' +
|
|
247
|
+
console.log('\n' +
|
|
248
|
+
chalk_1.default.bgHex('#0066FF').black(' Execution Summary ') +
|
|
249
|
+
'\n');
|
|
244
250
|
console.log(`${chalk_1.default.green(`${figures_1.default.tick} ${successful} succeeded`)}, ${chalk_1.default.red(`${figures_1.default.cross} ${failed} failed`)}`);
|
|
245
251
|
console.log(`${chalk_1.default.blue(figures_1.default.info)} ${chalk_1.default.dim(`Total execution time: ${totalSeconds}s`)}`);
|
|
246
252
|
if (successful > 0) {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { RunOptions, RunResult } from './types';
|
|
2
|
+
export declare class Runner {
|
|
3
|
+
private options;
|
|
4
|
+
private activeProcesses;
|
|
5
|
+
private serverInfo;
|
|
6
|
+
private portRegex;
|
|
7
|
+
private urlRegex;
|
|
8
|
+
private isCleaningUp;
|
|
9
|
+
constructor(options: RunOptions);
|
|
10
|
+
private setupSignalHandlers;
|
|
11
|
+
private expandWildcardCommands;
|
|
12
|
+
private resolveScriptAndCwd;
|
|
13
|
+
detectServerInfo(command: string, data: string): void;
|
|
14
|
+
runCommand(originalCommand: string, currentRetry?: number): Promise<RunResult>;
|
|
15
|
+
runSequential(commands: string[]): Promise<RunResult[]>;
|
|
16
|
+
runParallel(commands: string[]): Promise<RunResult[]>;
|
|
17
|
+
run(initialCommands: string[]): Promise<RunResult[]>;
|
|
18
|
+
cleanup(signal?: NodeJS.Signals): void;
|
|
19
|
+
private killProcess;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/runner.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,SAAS,EAA6B,MAAM,SAAS,CAAC;AAM3E,qBAAa,MAAM;IACjB,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,eAAe,CAAwC;IAC/D,OAAO,CAAC,UAAU,CAAsC;IACxD,OAAO,CAAC,SAAS,CACyD;IAC1E,OAAO,CAAC,QAAQ,CAAiD;IACjE,OAAO,CAAC,YAAY,CAAS;gBAEjB,OAAO,EAAE,UAAU;IAM/B,OAAO,CAAC,mBAAmB;YAsBb,sBAAsB;YA4CtB,mBAAmB;IAmCjC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAsC/C,UAAU,CACd,eAAe,EAAE,MAAM,EACvB,YAAY,SAAI,GACf,OAAO,CAAC,SAAS,CAAC;IAkKf,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAevD,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAuBrD,GAAG,CAAC,eAAe,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAsBnD,OAAO,CAAC,MAAM,GAAE,MAAM,CAAC,OAAmB,GAAG,IAAI;YAwC1C,WAAW;CAkD1B"}
|
package/dist/src/runner.js
CHANGED
|
@@ -47,19 +47,20 @@ const p_map_1 = __importDefault(require("p-map"));
|
|
|
47
47
|
const npm_run_path_1 = require("npm-run-path");
|
|
48
48
|
const fs = __importStar(require("fs"));
|
|
49
49
|
class Runner {
|
|
50
|
+
options;
|
|
51
|
+
activeProcesses = new Map();
|
|
52
|
+
serverInfo = new Map();
|
|
53
|
+
portRegex = /listening on (?:port |http:\/\/localhost:|https:\/\/localhost:)(\d+)/i;
|
|
54
|
+
urlRegex = /(https?:\/\/localhost:[0-9]+(?:\/[^\s]*)?)/i;
|
|
55
|
+
isCleaningUp = false;
|
|
50
56
|
constructor(options) {
|
|
51
|
-
this.activeProcesses = new Map();
|
|
52
|
-
this.serverInfo = new Map();
|
|
53
|
-
this.portRegex = /listening on (?:port |http:\/\/localhost:|https:\/\/localhost:)(\d+)/i;
|
|
54
|
-
this.urlRegex = /(https?:\/\/localhost:[0-9]+(?:\/[^\s]*)?)/i;
|
|
55
|
-
this.isCleaningUp = false;
|
|
56
57
|
this.options = options;
|
|
57
58
|
this.activeProcesses = new Map();
|
|
58
59
|
this.setupSignalHandlers();
|
|
59
60
|
}
|
|
60
61
|
setupSignalHandlers() {
|
|
61
62
|
const signals = ['SIGINT', 'SIGTERM', 'SIGQUIT'];
|
|
62
|
-
signals.forEach(
|
|
63
|
+
signals.forEach(signal => {
|
|
63
64
|
process.on(signal, () => {
|
|
64
65
|
if (!this.isCleaningUp) {
|
|
65
66
|
this.isCleaningUp = true;
|
|
@@ -123,7 +124,10 @@ class Runner {
|
|
|
123
124
|
const dir = cdMatch[1];
|
|
124
125
|
const commandToExecute = cdMatch[2];
|
|
125
126
|
const targetCwd = path.resolve(baseDir, dir);
|
|
126
|
-
return {
|
|
127
|
+
return {
|
|
128
|
+
executableCommand: commandToExecute,
|
|
129
|
+
executionCwd: targetCwd,
|
|
130
|
+
};
|
|
127
131
|
}
|
|
128
132
|
else {
|
|
129
133
|
return { executableCommand: scriptValue, executionCwd: baseDir };
|
|
@@ -142,7 +146,7 @@ class Runner {
|
|
|
142
146
|
if (!serverInfo) {
|
|
143
147
|
serverInfo = {
|
|
144
148
|
name: command,
|
|
145
|
-
status: 'starting'
|
|
149
|
+
status: 'starting',
|
|
146
150
|
};
|
|
147
151
|
this.serverInfo.set(command, serverInfo);
|
|
148
152
|
}
|
|
@@ -172,25 +176,24 @@ class Runner {
|
|
|
172
176
|
startTime,
|
|
173
177
|
endTime: null,
|
|
174
178
|
output: [],
|
|
175
|
-
stderr: []
|
|
179
|
+
stderr: [],
|
|
176
180
|
};
|
|
177
181
|
if (this.options.printOutput) {
|
|
178
182
|
logger_1.default.printStart(originalCommand);
|
|
179
183
|
}
|
|
180
184
|
return new Promise(async (resolve) => {
|
|
181
|
-
var _a, _b;
|
|
182
185
|
const [cmd, ...args] = command.split(' ');
|
|
183
186
|
const env = {
|
|
184
187
|
...process.env,
|
|
185
188
|
...(0, npm_run_path_1.npmRunPathEnv)(),
|
|
186
|
-
FORCE_COLOR: this.options.color ? '1' : '0'
|
|
189
|
+
FORCE_COLOR: this.options.color ? '1' : '0',
|
|
187
190
|
};
|
|
188
191
|
// Fix: Remove detached and handle process groups properly
|
|
189
192
|
const proc = (0, child_process_1.spawn)(cmd, args, {
|
|
190
193
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
191
194
|
shell: true,
|
|
192
195
|
env,
|
|
193
|
-
cwd
|
|
196
|
+
cwd,
|
|
194
197
|
});
|
|
195
198
|
this.activeProcesses.set(originalCommand, proc);
|
|
196
199
|
if (this.options.isServerMode) {
|
|
@@ -198,15 +201,15 @@ class Runner {
|
|
|
198
201
|
name: originalCommand,
|
|
199
202
|
status: 'starting',
|
|
200
203
|
pid: proc.pid,
|
|
201
|
-
startTime: new Date()
|
|
204
|
+
startTime: new Date(),
|
|
202
205
|
});
|
|
203
206
|
}
|
|
204
|
-
|
|
207
|
+
proc.stdout?.on('data', data => {
|
|
205
208
|
const output = {
|
|
206
209
|
command: originalCommand,
|
|
207
210
|
type: 'stdout',
|
|
208
211
|
data: data.toString(),
|
|
209
|
-
timestamp: new Date()
|
|
212
|
+
timestamp: new Date(),
|
|
210
213
|
};
|
|
211
214
|
if (this.options.isServerMode)
|
|
212
215
|
this.detectServerInfo(originalCommand, data.toString());
|
|
@@ -216,12 +219,12 @@ class Runner {
|
|
|
216
219
|
if (!this.options.groupOutput && this.options.printOutput)
|
|
217
220
|
logger_1.default.printBuffer(originalCommand);
|
|
218
221
|
});
|
|
219
|
-
|
|
222
|
+
proc.stderr?.on('data', data => {
|
|
220
223
|
const output = {
|
|
221
224
|
command: originalCommand,
|
|
222
225
|
type: 'stderr',
|
|
223
226
|
data: data.toString(),
|
|
224
|
-
timestamp: new Date()
|
|
227
|
+
timestamp: new Date(),
|
|
225
228
|
};
|
|
226
229
|
if (result.output)
|
|
227
230
|
result.output.push(output);
|
|
@@ -246,7 +249,9 @@ class Runner {
|
|
|
246
249
|
logger_1.default.printBuffer(originalCommand);
|
|
247
250
|
if (this.options.printOutput)
|
|
248
251
|
logger_1.default.printEnd(result, this.options.minimalOutput);
|
|
249
|
-
if (this.options.retry &&
|
|
252
|
+
if (this.options.retry &&
|
|
253
|
+
this.options.retry > 0 &&
|
|
254
|
+
currentRetry < this.options.retry) {
|
|
250
255
|
logger_1.default.printLine(`Command "${originalCommand}" failed with error. Retrying (${currentRetry + 1}/${this.options.retry})...`, 'warn');
|
|
251
256
|
if (this.options.retryDelay && this.options.retryDelay > 0) {
|
|
252
257
|
await new Promise(res => setTimeout(res, this.options.retryDelay));
|
|
@@ -277,7 +282,10 @@ class Runner {
|
|
|
277
282
|
logger_1.default.printBuffer(originalCommand);
|
|
278
283
|
if (this.options.printOutput)
|
|
279
284
|
logger_1.default.printEnd(result, this.options.minimalOutput);
|
|
280
|
-
if (!result.success &&
|
|
285
|
+
if (!result.success &&
|
|
286
|
+
this.options.retry &&
|
|
287
|
+
this.options.retry > 0 &&
|
|
288
|
+
currentRetry < this.options.retry) {
|
|
281
289
|
logger_1.default.printLine(`Command "${originalCommand}" failed with code ${code}. Retrying (${currentRetry + 1}/${this.options.retry})...`, 'warn');
|
|
282
290
|
if (this.options.retryDelay && this.options.retryDelay > 0) {
|
|
283
291
|
await new Promise(res => setTimeout(res, this.options.retryDelay));
|
|
@@ -310,7 +318,7 @@ class Runner {
|
|
|
310
318
|
try {
|
|
311
319
|
return await (0, p_map_1.default)(commands, mapper, {
|
|
312
320
|
concurrency,
|
|
313
|
-
stopOnError: this.options.stopOnError
|
|
321
|
+
stopOnError: this.options.stopOnError,
|
|
314
322
|
});
|
|
315
323
|
}
|
|
316
324
|
catch (error) {
|
|
@@ -352,22 +360,27 @@ class Runner {
|
|
|
352
360
|
}
|
|
353
361
|
});
|
|
354
362
|
// Wait for all processes to be killed
|
|
355
|
-
Promise.all(promises)
|
|
363
|
+
Promise.all(promises)
|
|
364
|
+
.then(() => {
|
|
356
365
|
this.activeProcesses.clear();
|
|
357
366
|
if (this.options.isServerMode && this.serverInfo.size > 0) {
|
|
358
367
|
logger_1.default.printLine('Server shutdown summary:', 'info');
|
|
359
368
|
this.serverInfo.forEach((info, command) => {
|
|
360
|
-
const statusColor = info.status === 'running'
|
|
361
|
-
|
|
369
|
+
const statusColor = info.status === 'running'
|
|
370
|
+
? chalk_1.default.green
|
|
371
|
+
: info.status === 'error'
|
|
372
|
+
? chalk_1.default.red
|
|
373
|
+
: chalk_1.default.yellow;
|
|
362
374
|
logger_1.default.printLine(` ${command}: ${statusColor(info.status)}`, 'info');
|
|
363
375
|
});
|
|
364
376
|
}
|
|
365
|
-
})
|
|
377
|
+
})
|
|
378
|
+
.catch(error => {
|
|
366
379
|
logger_1.default.printLine(`Error during cleanup: ${error.message}`, 'error');
|
|
367
380
|
});
|
|
368
381
|
}
|
|
369
382
|
async killProcess(proc, command, signal) {
|
|
370
|
-
return new Promise(
|
|
383
|
+
return new Promise(resolve => {
|
|
371
384
|
const timeout = setTimeout(() => {
|
|
372
385
|
if (proc.pid && !proc.killed) {
|
|
373
386
|
try {
|