neex 0.7.20 → 0.7.32
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
|
@@ -1,759 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.addProcessCommands = void 0;
|
|
30
|
-
const process_manager_js_1 = require("../process-manager.js");
|
|
31
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
32
|
-
const figures_1 = __importDefault(require("figures"));
|
|
33
|
-
const path = __importStar(require("path"));
|
|
34
|
-
const fs = __importStar(require("fs"));
|
|
35
|
-
const fs_1 = require("fs");
|
|
36
|
-
// Helper function to format uptime
|
|
37
|
-
function formatUptime(seconds) {
|
|
38
|
-
if (seconds < 60) {
|
|
39
|
-
return `${seconds}s`;
|
|
40
|
-
}
|
|
41
|
-
else if (seconds < 3600) {
|
|
42
|
-
const minutes = Math.floor(seconds / 60);
|
|
43
|
-
const remainingSeconds = seconds % 60;
|
|
44
|
-
return `${minutes}m ${remainingSeconds}s`;
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
const hours = Math.floor(seconds / 3600);
|
|
48
|
-
const minutes = Math.floor((seconds % 3600) / 60);
|
|
49
|
-
return `${hours}h ${minutes}m`;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
// Helper function to format memory
|
|
53
|
-
function formatMemory(bytes) {
|
|
54
|
-
if (bytes === 0)
|
|
55
|
-
return '0B';
|
|
56
|
-
const k = 1024;
|
|
57
|
-
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
58
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
59
|
-
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + sizes[i];
|
|
60
|
-
}
|
|
61
|
-
// Helper function to format CPU
|
|
62
|
-
function formatCpu(cpu) {
|
|
63
|
-
return `${cpu.toFixed(1)}%`;
|
|
64
|
-
}
|
|
65
|
-
function addProcessCommands(program) {
|
|
66
|
-
let processManager = null;
|
|
67
|
-
const getOrCreateProcessManager = async () => {
|
|
68
|
-
if (!processManager) {
|
|
69
|
-
processManager = new process_manager_js_1.ProcessManager();
|
|
70
|
-
await processManager.load();
|
|
71
|
-
}
|
|
72
|
-
return processManager;
|
|
73
|
-
};
|
|
74
|
-
// Start command - اجرای برنامه
|
|
75
|
-
program
|
|
76
|
-
.command('start <script>')
|
|
77
|
-
.description('Start a new process')
|
|
78
|
-
.option('-n, --name <name>', 'Process name')
|
|
79
|
-
.option('-i, --instances <number>', 'Number of instances', parseInt)
|
|
80
|
-
.option('--cwd <path>', 'Working directory')
|
|
81
|
-
.option('--env <env>', 'Environment variables (JSON string)')
|
|
82
|
-
.option('--no-autorestart', 'Disable auto-restart')
|
|
83
|
-
.option('--max-restarts <number>', 'Maximum restarts', parseInt)
|
|
84
|
-
.option('--restart-delay <ms>', 'Restart delay in ms', parseInt)
|
|
85
|
-
.option('--watch', 'Enable file watching')
|
|
86
|
-
.option('--ignore-watch <patterns...>', 'Patterns to ignore when watching')
|
|
87
|
-
.option('--max-memory <size>', 'Max memory before restart (e.g., 1G, 500M)')
|
|
88
|
-
.option('--interpreter <interpreter>', 'Interpreter to use (node, ts-node, etc.)')
|
|
89
|
-
.option('--interpreter-args <args>', 'Interpreter arguments')
|
|
90
|
-
.option('--log <path>', 'Log file path')
|
|
91
|
-
.option('--error <path>', 'Error log file path')
|
|
92
|
-
.option('--time', 'Prefix logs with timestamp')
|
|
93
|
-
.option('--merge-logs', 'Merge logs and errors')
|
|
94
|
-
.option('--typescript', 'Script is TypeScript (will use ts-node)')
|
|
95
|
-
.option('--build-dir <dir>', 'Build directory for TypeScript projects', 'dist')
|
|
96
|
-
.action(async (script, options) => {
|
|
97
|
-
try {
|
|
98
|
-
const pm = await getOrCreateProcessManager();
|
|
99
|
-
// Resolve script path
|
|
100
|
-
const scriptPath = path.resolve(script);
|
|
101
|
-
if (!fs.existsSync(scriptPath)) {
|
|
102
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Script file not found: ${scriptPath}`));
|
|
103
|
-
process.exit(1);
|
|
104
|
-
}
|
|
105
|
-
// If TypeScript flag is set, use ts-node
|
|
106
|
-
const interpreter = options.typescript ? 'ts-node' : options.interpreter || 'node';
|
|
107
|
-
const interpreterArgs = options.typescript ? ['--project', 'tsconfig.json'] : options.interpreterArgs ? options.interpreterArgs.split(' ') : undefined;
|
|
108
|
-
const config = {
|
|
109
|
-
id: '',
|
|
110
|
-
name: options.name || path.basename(script, path.extname(script)),
|
|
111
|
-
script: scriptPath,
|
|
112
|
-
cwd: options.cwd ? path.resolve(options.cwd) : process.cwd(),
|
|
113
|
-
env: options.env ? JSON.parse(options.env) : undefined,
|
|
114
|
-
instances: options.instances || 1,
|
|
115
|
-
autorestart: options.autorestart !== false,
|
|
116
|
-
max_restarts: options.maxRestarts || 10,
|
|
117
|
-
restart_delay: options.restartDelay || 1000,
|
|
118
|
-
watch: options.watch || false,
|
|
119
|
-
ignore_watch: options.ignoreWatch,
|
|
120
|
-
max_memory_restart: options.maxMemory,
|
|
121
|
-
interpreter,
|
|
122
|
-
interpreter_args: interpreterArgs,
|
|
123
|
-
log_file: options.log,
|
|
124
|
-
error_file: options.error,
|
|
125
|
-
out_file: options.log,
|
|
126
|
-
time: options.time || false,
|
|
127
|
-
merge_logs: options.mergeLogs || false
|
|
128
|
-
};
|
|
129
|
-
const id = await pm.start(config);
|
|
130
|
-
console.log(chalk_1.default.green(`${figures_1.default.tick} Process started successfully`));
|
|
131
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Process ID: ${id}`));
|
|
132
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Process Name: ${config.name}`));
|
|
133
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Script: ${scriptPath}`));
|
|
134
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Interpreter: ${interpreter}`));
|
|
135
|
-
}
|
|
136
|
-
catch (error) {
|
|
137
|
-
if (error instanceof Error) {
|
|
138
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Start Error: ${error.message}`));
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} An unknown start error occurred`));
|
|
142
|
-
}
|
|
143
|
-
process.exit(1);
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
// Stop command - توقف برنامه
|
|
147
|
-
program
|
|
148
|
-
.command('stop <id>')
|
|
149
|
-
.description('Stop a process (use "all" to stop all processes)')
|
|
150
|
-
.action(async (id) => {
|
|
151
|
-
try {
|
|
152
|
-
const pm = await getOrCreateProcessManager();
|
|
153
|
-
if (id === 'all') {
|
|
154
|
-
await pm.stopAll();
|
|
155
|
-
console.log(chalk_1.default.green(`${figures_1.default.tick} All processes stopped`));
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
await pm.stop(id);
|
|
159
|
-
console.log(chalk_1.default.green(`${figures_1.default.tick} Process ${id} stopped`));
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
catch (error) {
|
|
163
|
-
if (error instanceof Error) {
|
|
164
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Stop Error: ${error.message}`));
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} An unknown stop error occurred`));
|
|
168
|
-
}
|
|
169
|
-
process.exit(1);
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
// Restart command - راهاندازی مجدد
|
|
173
|
-
program
|
|
174
|
-
.command('restart <id>')
|
|
175
|
-
.description('Restart a process (use "all" to restart all processes)')
|
|
176
|
-
.action(async (id) => {
|
|
177
|
-
try {
|
|
178
|
-
const pm = await getOrCreateProcessManager();
|
|
179
|
-
if (id === 'all') {
|
|
180
|
-
await pm.restartAll();
|
|
181
|
-
console.log(chalk_1.default.green(`${figures_1.default.tick} All processes restarted`));
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
await pm.restart(id);
|
|
185
|
-
console.log(chalk_1.default.green(`${figures_1.default.tick} Process ${id} restarted`));
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
catch (error) {
|
|
189
|
-
if (error instanceof Error) {
|
|
190
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Restart Error: ${error.message}`));
|
|
191
|
-
}
|
|
192
|
-
else {
|
|
193
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} An unknown restart error occurred`));
|
|
194
|
-
}
|
|
195
|
-
process.exit(1);
|
|
196
|
-
}
|
|
197
|
-
});
|
|
198
|
-
// Delete command - حذف برنامه
|
|
199
|
-
program
|
|
200
|
-
.command('delete <id>')
|
|
201
|
-
.alias('del')
|
|
202
|
-
.description('Delete a process (use "all" to delete all processes)')
|
|
203
|
-
.action(async (id) => {
|
|
204
|
-
try {
|
|
205
|
-
const pm = await getOrCreateProcessManager();
|
|
206
|
-
if (id === 'all') {
|
|
207
|
-
await pm.deleteAll();
|
|
208
|
-
console.log(chalk_1.default.green(`${figures_1.default.tick} All processes deleted`));
|
|
209
|
-
}
|
|
210
|
-
else {
|
|
211
|
-
await pm.delete(id);
|
|
212
|
-
console.log(chalk_1.default.green(`${figures_1.default.tick} Process ${id} deleted`));
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
catch (error) {
|
|
216
|
-
if (error instanceof Error) {
|
|
217
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Delete Error: ${error.message}`));
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} An unknown delete error occurred`));
|
|
221
|
-
}
|
|
222
|
-
process.exit(1);
|
|
223
|
-
}
|
|
224
|
-
});
|
|
225
|
-
// List/Status command - نمایش وضعیت
|
|
226
|
-
program
|
|
227
|
-
.command('list')
|
|
228
|
-
.alias('status')
|
|
229
|
-
.alias('ls')
|
|
230
|
-
.description('List all processes with detailed information')
|
|
231
|
-
.action(async () => {
|
|
232
|
-
try {
|
|
233
|
-
const pm = await getOrCreateProcessManager();
|
|
234
|
-
const processes = await pm.list();
|
|
235
|
-
if (processes.length === 0) {
|
|
236
|
-
console.log(chalk_1.default.yellow(`${figures_1.default.info} No processes found`));
|
|
237
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Use 'neex start <script>' to start a new process`));
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
// Print enhanced table
|
|
241
|
-
console.log('\n' + chalk_1.default.bold.cyan('Neex Process Monitor'));
|
|
242
|
-
console.log(chalk_1.default.gray('─'.repeat(100)));
|
|
243
|
-
const header = `${chalk_1.default.bold('ID'.padEnd(12))} ${chalk_1.default.bold('Name'.padEnd(15))} ${chalk_1.default.bold('Status'.padEnd(10))} ${chalk_1.default.bold('PID'.padEnd(8))} ${chalk_1.default.bold('Uptime'.padEnd(10))} ${chalk_1.default.bold('Restarts'.padEnd(8))} ${chalk_1.default.bold('CPU'.padEnd(8))} ${chalk_1.default.bold('Memory'.padEnd(10))}`;
|
|
244
|
-
console.log(header);
|
|
245
|
-
console.log(chalk_1.default.gray('─'.repeat(100)));
|
|
246
|
-
// Print process information
|
|
247
|
-
processes.forEach(proc => {
|
|
248
|
-
const statusColor = proc.status === 'online' ? chalk_1.default.green :
|
|
249
|
-
proc.status === 'stopped' ? chalk_1.default.gray :
|
|
250
|
-
proc.status === 'errored' ? chalk_1.default.red :
|
|
251
|
-
proc.status === 'launching' ? chalk_1.default.yellow : chalk_1.default.blue;
|
|
252
|
-
const uptime = formatUptime(proc.uptime);
|
|
253
|
-
const pid = proc.pid ? proc.pid.toString() : 'N/A';
|
|
254
|
-
const cpu = proc.status === 'online' ? formatCpu(proc.cpu) : 'N/A';
|
|
255
|
-
const memory = proc.status === 'online' ? formatMemory(proc.memory) : 'N/A';
|
|
256
|
-
const row = `${proc.id.padEnd(12)} ${proc.name.padEnd(15)} ${statusColor(proc.status.padEnd(10))} ${pid.padEnd(8)} ${uptime.padEnd(10)} ${proc.restarts.toString().padEnd(8)} ${cpu.padEnd(8)} ${memory.padEnd(10)}`;
|
|
257
|
-
console.log(row);
|
|
258
|
-
});
|
|
259
|
-
console.log(chalk_1.default.gray('─'.repeat(100)));
|
|
260
|
-
const online = processes.filter(p => p.status === 'online').length;
|
|
261
|
-
const stopped = processes.filter(p => p.status === 'stopped').length;
|
|
262
|
-
const errored = processes.filter(p => p.status === 'errored').length;
|
|
263
|
-
console.log(`\n${chalk_1.default.blue(`${figures_1.default.info} Total: ${processes.length} processes`)} | ${chalk_1.default.green(`Online: ${online}`)} | ${chalk_1.default.gray(`Stopped: ${stopped}`)} | ${chalk_1.default.red(`Errored: ${errored}`)}`);
|
|
264
|
-
}
|
|
265
|
-
catch (error) {
|
|
266
|
-
if (error instanceof Error) {
|
|
267
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} List Error: ${error.message}`));
|
|
268
|
-
}
|
|
269
|
-
else {
|
|
270
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} An unknown list error occurred`));
|
|
271
|
-
}
|
|
272
|
-
process.exit(1);
|
|
273
|
-
}
|
|
274
|
-
});
|
|
275
|
-
// Logs command - نمایش لاگها
|
|
276
|
-
program
|
|
277
|
-
.command('logs <id>')
|
|
278
|
-
.alias('log')
|
|
279
|
-
.description('Show process logs')
|
|
280
|
-
.option('-l, --lines <number>', 'Number of lines to show', parseInt, 15)
|
|
281
|
-
.option('-f, --follow', 'Follow log output')
|
|
282
|
-
.action(async (id, options) => {
|
|
283
|
-
try {
|
|
284
|
-
const pm = await getOrCreateProcessManager();
|
|
285
|
-
const processInfo = pm.getProcess(id);
|
|
286
|
-
if (!processInfo) {
|
|
287
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Process ${id} not found`));
|
|
288
|
-
process.exit(1);
|
|
289
|
-
}
|
|
290
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Showing logs for process: ${processInfo.name} (${id})`));
|
|
291
|
-
console.log(chalk_1.default.gray('─'.repeat(60)));
|
|
292
|
-
if (options.follow) {
|
|
293
|
-
// Follow logs
|
|
294
|
-
const logFollower = pm.followLogs(id, (logLine) => {
|
|
295
|
-
console.log(logLine);
|
|
296
|
-
});
|
|
297
|
-
if (!logFollower) {
|
|
298
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Failed to follow logs for process ${id}`));
|
|
299
|
-
process.exit(1);
|
|
300
|
-
}
|
|
301
|
-
// Handle Ctrl+C to stop following
|
|
302
|
-
process.on('SIGINT', () => {
|
|
303
|
-
console.log(chalk_1.default.yellow(`\n${figures_1.default.info} Stopping log follow...`));
|
|
304
|
-
logFollower.stop();
|
|
305
|
-
process.exit(0);
|
|
306
|
-
});
|
|
307
|
-
console.log(chalk_1.default.green(`${figures_1.default.tick} Following logs... Press Ctrl+C to stop`));
|
|
308
|
-
}
|
|
309
|
-
else {
|
|
310
|
-
// Show recent logs
|
|
311
|
-
const logs = await pm.logs(id, options.lines);
|
|
312
|
-
if (logs.length === 0) {
|
|
313
|
-
console.log(chalk_1.default.yellow(`${figures_1.default.info} No logs found for process ${id}`));
|
|
314
|
-
}
|
|
315
|
-
else {
|
|
316
|
-
logs.forEach(log => console.log(log));
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
catch (error) {
|
|
321
|
-
if (error instanceof Error) {
|
|
322
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Logs Error: ${error.message}`));
|
|
323
|
-
}
|
|
324
|
-
else {
|
|
325
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} An unknown logs error occurred`));
|
|
326
|
-
}
|
|
327
|
-
process.exit(1);
|
|
328
|
-
}
|
|
329
|
-
});
|
|
330
|
-
// Save command - ذخیره وضعیت
|
|
331
|
-
program
|
|
332
|
-
.command('save')
|
|
333
|
-
.description('Save current process configuration')
|
|
334
|
-
.action(async () => {
|
|
335
|
-
try {
|
|
336
|
-
const pm = await getOrCreateProcessManager();
|
|
337
|
-
await pm.save();
|
|
338
|
-
console.log(chalk_1.default.green(`${figures_1.default.tick} Process configuration saved successfully`));
|
|
339
|
-
}
|
|
340
|
-
catch (error) {
|
|
341
|
-
if (error instanceof Error) {
|
|
342
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Save Error: ${error.message}`));
|
|
343
|
-
}
|
|
344
|
-
else {
|
|
345
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} An unknown save error occurred`));
|
|
346
|
-
}
|
|
347
|
-
process.exit(1);
|
|
348
|
-
}
|
|
349
|
-
});
|
|
350
|
-
// Resurrect command - بازیابی برنامهها
|
|
351
|
-
program
|
|
352
|
-
.command('resurrect')
|
|
353
|
-
.description('Resurrect previously saved processes')
|
|
354
|
-
.action(async () => {
|
|
355
|
-
try {
|
|
356
|
-
const pm = await getOrCreateProcessManager();
|
|
357
|
-
await pm.load();
|
|
358
|
-
const processes = await pm.list();
|
|
359
|
-
const stoppedProcesses = processes.filter(p => p.status === 'stopped');
|
|
360
|
-
if (stoppedProcesses.length === 0) {
|
|
361
|
-
console.log(chalk_1.default.yellow(`${figures_1.default.info} No stopped processes to resurrect`));
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
364
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Resurrecting ${stoppedProcesses.length} processes...`));
|
|
365
|
-
for (const proc of stoppedProcesses) {
|
|
366
|
-
try {
|
|
367
|
-
await pm.restart(proc.id);
|
|
368
|
-
console.log(chalk_1.default.green(`${figures_1.default.tick} Resurrected: ${proc.name} (${proc.id})`));
|
|
369
|
-
}
|
|
370
|
-
catch (error) {
|
|
371
|
-
console.log(chalk_1.default.red(`${figures_1.default.cross} Failed to resurrect: ${proc.name} (${proc.id})`));
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
catch (error) {
|
|
376
|
-
if (error instanceof Error) {
|
|
377
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Resurrect Error: ${error.message}`));
|
|
378
|
-
}
|
|
379
|
-
else {
|
|
380
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} An unknown resurrect error occurred`));
|
|
381
|
-
}
|
|
382
|
-
process.exit(1);
|
|
383
|
-
}
|
|
384
|
-
});
|
|
385
|
-
// Info command - اطلاعات دقیق برنامه
|
|
386
|
-
program
|
|
387
|
-
.command('info <id>')
|
|
388
|
-
.alias('show')
|
|
389
|
-
.description('Show detailed information about a process')
|
|
390
|
-
.action(async (id) => {
|
|
391
|
-
try {
|
|
392
|
-
const pm = await getOrCreateProcessManager();
|
|
393
|
-
const processInfo = pm.getProcess(id);
|
|
394
|
-
if (!processInfo) {
|
|
395
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Process ${id} not found`));
|
|
396
|
-
process.exit(1);
|
|
397
|
-
}
|
|
398
|
-
console.log('\n' + chalk_1.default.bold.cyan(`Process Information: ${processInfo.name}`));
|
|
399
|
-
console.log(chalk_1.default.gray('─'.repeat(50)));
|
|
400
|
-
console.log(`${chalk_1.default.bold('ID:')} ${processInfo.id}`);
|
|
401
|
-
console.log(`${chalk_1.default.bold('Name:')} ${processInfo.name}`);
|
|
402
|
-
console.log(`${chalk_1.default.bold('Status:')} ${processInfo.status === 'online' ? chalk_1.default.green(processInfo.status) : chalk_1.default.red(processInfo.status)}`);
|
|
403
|
-
console.log(`${chalk_1.default.bold('PID:')} ${processInfo.pid || 'N/A'}`);
|
|
404
|
-
console.log(`${chalk_1.default.bold('Uptime:')} ${formatUptime(processInfo.uptime)}`);
|
|
405
|
-
console.log(`${chalk_1.default.bold('Restarts:')} ${processInfo.restarts}`);
|
|
406
|
-
console.log(`${chalk_1.default.bold('CPU:')} ${formatCpu(processInfo.cpu)}`);
|
|
407
|
-
console.log(`${chalk_1.default.bold('Memory:')} ${formatMemory(processInfo.memory)}`);
|
|
408
|
-
console.log(`${chalk_1.default.bold('Script:')} ${processInfo.config.script}`);
|
|
409
|
-
console.log(`${chalk_1.default.bold('Working Directory:')} ${processInfo.config.cwd || process.cwd()}`);
|
|
410
|
-
console.log(`${chalk_1.default.bold('Auto Restart:')} ${processInfo.config.autorestart ? 'Yes' : 'No'}`);
|
|
411
|
-
console.log(`${chalk_1.default.bold('Max Restarts:')} ${processInfo.config.max_restarts}`);
|
|
412
|
-
console.log(`${chalk_1.default.bold('Created At:')} ${processInfo.created_at.toISOString()}`);
|
|
413
|
-
if (processInfo.started_at) {
|
|
414
|
-
console.log(`${chalk_1.default.bold('Started At:')} ${processInfo.started_at.toISOString()}`);
|
|
415
|
-
}
|
|
416
|
-
if (processInfo.last_restart) {
|
|
417
|
-
console.log(`${chalk_1.default.bold('Last Restart:')} ${processInfo.last_restart.toISOString()}`);
|
|
418
|
-
}
|
|
419
|
-
if (processInfo.config.env) {
|
|
420
|
-
console.log(`${chalk_1.default.bold('Environment Variables:')}`);
|
|
421
|
-
Object.entries(processInfo.config.env).forEach(([key, value]) => {
|
|
422
|
-
console.log(` ${key}: ${value}`);
|
|
423
|
-
});
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
catch (error) {
|
|
427
|
-
if (error instanceof Error) {
|
|
428
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Info Error: ${error.message}`));
|
|
429
|
-
}
|
|
430
|
-
else {
|
|
431
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} An unknown info error occurred`));
|
|
432
|
-
}
|
|
433
|
-
process.exit(1);
|
|
434
|
-
}
|
|
435
|
-
});
|
|
436
|
-
// Monitor command - مانیتور زنده
|
|
437
|
-
program
|
|
438
|
-
.command('monitor')
|
|
439
|
-
.alias('monit')
|
|
440
|
-
.description('Launch process monitor dashboard')
|
|
441
|
-
.action(async () => {
|
|
442
|
-
try {
|
|
443
|
-
const pm = await getOrCreateProcessManager();
|
|
444
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Starting Neex Process Monitor...`));
|
|
445
|
-
console.log(chalk_1.default.gray('Press Ctrl+C to exit'));
|
|
446
|
-
const displayMonitor = async () => {
|
|
447
|
-
// Clear screen
|
|
448
|
-
process.stdout.write('\x1Bc');
|
|
449
|
-
const processes = await pm.list();
|
|
450
|
-
console.log(chalk_1.default.bold.cyan('Neex Process Monitor'));
|
|
451
|
-
console.log(chalk_1.default.gray('─'.repeat(80)));
|
|
452
|
-
if (processes.length === 0) {
|
|
453
|
-
console.log(chalk_1.default.yellow(`${figures_1.default.info} No processes running`));
|
|
454
|
-
}
|
|
455
|
-
else {
|
|
456
|
-
processes.forEach(proc => {
|
|
457
|
-
const statusIcon = proc.status === 'online' ? chalk_1.default.green('●') :
|
|
458
|
-
proc.status === 'stopped' ? chalk_1.default.gray('○') :
|
|
459
|
-
proc.status === 'errored' ? chalk_1.default.red('●') : chalk_1.default.yellow('●');
|
|
460
|
-
const uptime = formatUptime(proc.uptime);
|
|
461
|
-
const pid = proc.pid ? `PID: ${proc.pid}` : 'PID: N/A';
|
|
462
|
-
const memory = proc.status === 'online' ? formatMemory(proc.memory) : 'N/A';
|
|
463
|
-
const cpu = proc.status === 'online' ? formatCpu(proc.cpu) : 'N/A';
|
|
464
|
-
console.log(`${statusIcon} ${chalk_1.default.bold(proc.name)} (${proc.id}) - ${proc.status}`);
|
|
465
|
-
console.log(` ${pid} | Uptime: ${uptime} | Restarts: ${proc.restarts} | CPU: ${cpu} | Memory: ${memory}`);
|
|
466
|
-
console.log('');
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
console.log(chalk_1.default.gray('─'.repeat(80)));
|
|
470
|
-
console.log(`Last updated: ${new Date().toLocaleTimeString()}`);
|
|
471
|
-
};
|
|
472
|
-
// Initial display
|
|
473
|
-
await displayMonitor();
|
|
474
|
-
// Update every 2 seconds
|
|
475
|
-
const monitorInterval = setInterval(displayMonitor, 2000);
|
|
476
|
-
// Handle Ctrl+C
|
|
477
|
-
process.on('SIGINT', () => {
|
|
478
|
-
clearInterval(monitorInterval);
|
|
479
|
-
console.log(chalk_1.default.yellow(`\n${figures_1.default.info} Monitor stopped`));
|
|
480
|
-
process.exit(0);
|
|
481
|
-
});
|
|
482
|
-
}
|
|
483
|
-
catch (error) {
|
|
484
|
-
if (error instanceof Error) {
|
|
485
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Monitor Error: ${error.message}`));
|
|
486
|
-
}
|
|
487
|
-
else {
|
|
488
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} An unknown monitor error occurred`));
|
|
489
|
-
}
|
|
490
|
-
process.exit(1);
|
|
491
|
-
}
|
|
492
|
-
});
|
|
493
|
-
// StartX command - اجرای بهینه برای پروداکشن
|
|
494
|
-
program
|
|
495
|
-
.command('startx <script>')
|
|
496
|
-
.description('Start process optimized for production (auto-restart, clustering, monitoring)')
|
|
497
|
-
.option('-n, --name <name>', 'Process name')
|
|
498
|
-
.option('-i, --instances <number>', 'Number of instances (default: CPU cores)', parseInt)
|
|
499
|
-
.option('--max-memory <size>', 'Max memory before restart (default: 1G)')
|
|
500
|
-
.option('--cwd <path>', 'Working directory')
|
|
501
|
-
.option('--env <env>', 'Environment variables (JSON string)')
|
|
502
|
-
.action(async (script, options) => {
|
|
503
|
-
try {
|
|
504
|
-
const pm = await getOrCreateProcessManager();
|
|
505
|
-
const os = require('os');
|
|
506
|
-
// Resolve script path
|
|
507
|
-
const scriptPath = path.resolve(script);
|
|
508
|
-
if (!fs.existsSync(scriptPath)) {
|
|
509
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Script file not found: ${scriptPath}`));
|
|
510
|
-
process.exit(1);
|
|
511
|
-
}
|
|
512
|
-
const instances = options.instances || os.cpus().length;
|
|
513
|
-
const processName = options.name || path.basename(script, path.extname(script));
|
|
514
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Starting production-optimized process...`));
|
|
515
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Script: ${scriptPath}`));
|
|
516
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Instances: ${instances}`));
|
|
517
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Max Memory: ${options.maxMemory || '1G'}`));
|
|
518
|
-
const baseConfig = {
|
|
519
|
-
id: '',
|
|
520
|
-
name: processName,
|
|
521
|
-
script: scriptPath,
|
|
522
|
-
cwd: options.cwd ? path.resolve(options.cwd) : process.cwd(),
|
|
523
|
-
env: {
|
|
524
|
-
NODE_ENV: 'production',
|
|
525
|
-
...(options.env ? JSON.parse(options.env) : {})
|
|
526
|
-
},
|
|
527
|
-
instances: 1,
|
|
528
|
-
autorestart: true,
|
|
529
|
-
max_restarts: 50,
|
|
530
|
-
restart_delay: 1000,
|
|
531
|
-
watch: false,
|
|
532
|
-
max_memory_restart: options.maxMemory || '1G',
|
|
533
|
-
time: true,
|
|
534
|
-
merge_logs: false
|
|
535
|
-
};
|
|
536
|
-
const startedProcesses = [];
|
|
537
|
-
// Start multiple instances
|
|
538
|
-
for (let i = 0; i < instances; i++) {
|
|
539
|
-
const config = {
|
|
540
|
-
...baseConfig,
|
|
541
|
-
name: instances > 1 ? `${processName}-${i}` : processName
|
|
542
|
-
};
|
|
543
|
-
try {
|
|
544
|
-
const id = await pm.start(config);
|
|
545
|
-
startedProcesses.push(id);
|
|
546
|
-
console.log(chalk_1.default.green(`${figures_1.default.tick} Instance ${i + 1}/${instances} started (ID: ${id})`));
|
|
547
|
-
// Small delay between starts
|
|
548
|
-
if (i < instances - 1) {
|
|
549
|
-
await new Promise(resolve => setTimeout(resolve, 500));
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
catch (error) {
|
|
553
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Failed to start instance ${i + 1}: ${error.message}`));
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
if (startedProcesses.length > 0) {
|
|
557
|
-
// Auto-save configuration
|
|
558
|
-
await pm.save();
|
|
559
|
-
console.log(chalk_1.default.green(`\n${figures_1.default.tick} Production deployment completed!`));
|
|
560
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Started ${startedProcesses.length}/${instances} instances`));
|
|
561
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Configuration saved automatically`));
|
|
562
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Use 'neex monitor' to watch processes`));
|
|
563
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Use 'neex logs <id>' to view logs`));
|
|
564
|
-
}
|
|
565
|
-
else {
|
|
566
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Failed to start any instances`));
|
|
567
|
-
process.exit(1);
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
catch (error) {
|
|
571
|
-
if (error instanceof Error) {
|
|
572
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} StartX Error: ${error.message}`));
|
|
573
|
-
}
|
|
574
|
-
else {
|
|
575
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} An unknown startx error occurred`));
|
|
576
|
-
}
|
|
577
|
-
process.exit(1);
|
|
578
|
-
}
|
|
579
|
-
});
|
|
580
|
-
//stopx command - توقف بهینه برای پروداکشن
|
|
581
|
-
program
|
|
582
|
-
.command('stopx <name>')
|
|
583
|
-
.description('Stop all instances of a production-optimized process by name')
|
|
584
|
-
.action(async (name) => {
|
|
585
|
-
try {
|
|
586
|
-
const pm = await getOrCreateProcessManager();
|
|
587
|
-
const processes = await pm.list(); // دریافت لیست تمام فرایندها
|
|
588
|
-
// پیدا کردن تمام فرایندهایی که با نام اصلی (نه با ایندکس) شروع میشوند
|
|
589
|
-
const processesToStop = processes.filter(p => p.name === name || p.name.startsWith(`${name}-`));
|
|
590
|
-
if (processesToStop.length === 0) {
|
|
591
|
-
console.log(chalk_1.default.yellow(`${figures_1.default.warning} No production process instances found for name "${name}".`));
|
|
592
|
-
return;
|
|
593
|
-
}
|
|
594
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Stopping ${processesToStop.length} instances of "${name}"...`));
|
|
595
|
-
const stopPromises = processesToStop.map(async (p) => {
|
|
596
|
-
try {
|
|
597
|
-
await pm.stop(p.id);
|
|
598
|
-
console.log(chalk_1.default.green(`${figures_1.default.tick} Stopped instance ${p.name} (ID: ${p.id})`));
|
|
599
|
-
}
|
|
600
|
-
catch (error) {
|
|
601
|
-
if (error instanceof Error) {
|
|
602
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Failed to stop instance ${p.name} (ID: ${p.id}): ${error.message}`));
|
|
603
|
-
}
|
|
604
|
-
else {
|
|
605
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} An unknown error occurred while stopping instance ${p.name} (ID: ${p.id})`));
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
});
|
|
609
|
-
await Promise.all(stopPromises); // اجرای موازی توقفها
|
|
610
|
-
console.log(chalk_1.default.green(`\n${figures_1.default.tick} All specified production process instances have been processed.`));
|
|
611
|
-
await pm.save(); // ذخیره تغییرات (حذف فرایندهای متوقف شده)
|
|
612
|
-
}
|
|
613
|
-
catch (error) {
|
|
614
|
-
if (error instanceof Error) {
|
|
615
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} StopX Error: ${error.message}`));
|
|
616
|
-
}
|
|
617
|
-
else {
|
|
618
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} An unknown stopx error occurred`));
|
|
619
|
-
}
|
|
620
|
-
process.exit(1);
|
|
621
|
-
}
|
|
622
|
-
});
|
|
623
|
-
// Build command - Compile TypeScript project
|
|
624
|
-
program
|
|
625
|
-
.command('build <entry>')
|
|
626
|
-
.description('Build TypeScript project from entry point')
|
|
627
|
-
.option('-o, --out <dir>', 'Output directory', 'dist')
|
|
628
|
-
.option('--tsconfig <path>', 'Path to tsconfig.json', 'tsconfig.json')
|
|
629
|
-
.option('--watch', 'Watch for changes and rebuild')
|
|
630
|
-
.action(async (entry, options) => {
|
|
631
|
-
try {
|
|
632
|
-
const entryPath = path.resolve(entry);
|
|
633
|
-
const tsConfigPath = path.resolve(options.tsconfig);
|
|
634
|
-
const outDir = path.resolve(options.out);
|
|
635
|
-
// Check if entry file exists
|
|
636
|
-
if (!fs.existsSync(entryPath)) {
|
|
637
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Entry point not found: ${entryPath}`));
|
|
638
|
-
process.exit(1);
|
|
639
|
-
}
|
|
640
|
-
// Check if tsconfig exists
|
|
641
|
-
if (!fs.existsSync(tsConfigPath)) {
|
|
642
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} tsconfig.json not found at: ${tsConfigPath}`));
|
|
643
|
-
process.exit(1);
|
|
644
|
-
}
|
|
645
|
-
// Create output directory if it doesn't exist
|
|
646
|
-
if (!fs.existsSync(outDir)) {
|
|
647
|
-
fs.mkdirSync(outDir, { recursive: true });
|
|
648
|
-
}
|
|
649
|
-
// Read tsconfig
|
|
650
|
-
const tsConfig = JSON.parse(await fs_1.promises.readFile(tsConfigPath, 'utf8'));
|
|
651
|
-
// Update tsconfig with entry point
|
|
652
|
-
tsConfig.files = [entryPath];
|
|
653
|
-
// Write temporary tsconfig
|
|
654
|
-
const tempTsConfigPath = path.join(process.cwd(), '.neex.tsconfig.json');
|
|
655
|
-
await fs_1.promises.writeFile(tempTsConfigPath, JSON.stringify(tsConfig, null, 2));
|
|
656
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Building TypeScript project...`));
|
|
657
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Entry Point: ${entryPath}`));
|
|
658
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Output: ${outDir}`));
|
|
659
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Using tsconfig: ${tempTsConfigPath}`));
|
|
660
|
-
// Run tsc command
|
|
661
|
-
const { spawn } = require('child_process');
|
|
662
|
-
const tsc = spawn('tsc', [
|
|
663
|
-
'--build',
|
|
664
|
-
'--project', tempTsConfigPath,
|
|
665
|
-
...(options.watch ? ['--watch'] : [])
|
|
666
|
-
], {
|
|
667
|
-
stdio: 'inherit',
|
|
668
|
-
cwd: process.cwd()
|
|
669
|
-
});
|
|
670
|
-
tsc.on('close', (code) => {
|
|
671
|
-
// Clean up temporary tsconfig
|
|
672
|
-
fs.unlink(tempTsConfigPath, (err) => {
|
|
673
|
-
if (err)
|
|
674
|
-
console.error('Error cleaning up temporary tsconfig:', err);
|
|
675
|
-
});
|
|
676
|
-
if (code === 0) {
|
|
677
|
-
console.log(chalk_1.default.green(`${figures_1.default.tick} Build completed successfully!`));
|
|
678
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Output files in: ${outDir}`));
|
|
679
|
-
}
|
|
680
|
-
else {
|
|
681
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Build failed with code ${code}`));
|
|
682
|
-
process.exit(1);
|
|
683
|
-
}
|
|
684
|
-
});
|
|
685
|
-
}
|
|
686
|
-
catch (error) {
|
|
687
|
-
if (error instanceof Error) {
|
|
688
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Build Error: ${error.message}`));
|
|
689
|
-
}
|
|
690
|
-
else {
|
|
691
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} An unknown build error occurred`));
|
|
692
|
-
}
|
|
693
|
-
process.exit(1);
|
|
694
|
-
}
|
|
695
|
-
});
|
|
696
|
-
// Startup command - راهاندازی خودکار هنگام بوت
|
|
697
|
-
program
|
|
698
|
-
.command('startup')
|
|
699
|
-
.description('Generate startup script for system boot')
|
|
700
|
-
.option('--user <user>', 'User to run processes as')
|
|
701
|
-
.action(async (options) => {
|
|
702
|
-
try {
|
|
703
|
-
const user = options.user || require('os').userInfo().username;
|
|
704
|
-
const homeDir = require('os').homedir();
|
|
705
|
-
const neexPath = process.argv[1]; // Path to neex executable
|
|
706
|
-
const systemdService = `[Unit]
|
|
707
|
-
Description=Neex Process Manager
|
|
708
|
-
After=network.target
|
|
709
|
-
|
|
710
|
-
[Service]
|
|
711
|
-
Type=forking
|
|
712
|
-
User=${user}
|
|
713
|
-
WorkingDirectory=${homeDir}
|
|
714
|
-
ExecStart=${neexPath} resurrect
|
|
715
|
-
ExecReload=${neexPath} restart all
|
|
716
|
-
ExecStop=${neexPath} stop all
|
|
717
|
-
Restart=on-failure
|
|
718
|
-
RestartSec=5
|
|
719
|
-
|
|
720
|
-
[Install]
|
|
721
|
-
WantedBy=multi-user.target`;
|
|
722
|
-
const servicePath = '/etc/systemd/system/neex.service';
|
|
723
|
-
console.log(chalk_1.default.blue(`${figures_1.default.info} Generating startup configuration...`));
|
|
724
|
-
console.log(chalk_1.default.yellow(`${figures_1.default.warning} This requires sudo privileges`));
|
|
725
|
-
console.log('\nSystemd service file content:');
|
|
726
|
-
console.log(chalk_1.default.gray('─'.repeat(40)));
|
|
727
|
-
console.log(systemdService);
|
|
728
|
-
console.log(chalk_1.default.gray('─'.repeat(40)));
|
|
729
|
-
console.log(`\n${chalk_1.default.bold('To enable startup on boot, run:')}`);
|
|
730
|
-
console.log(chalk_1.default.cyan(`sudo tee ${servicePath} << 'EOF'`));
|
|
731
|
-
console.log(systemdService);
|
|
732
|
-
console.log(chalk_1.default.cyan('EOF'));
|
|
733
|
-
console.log(chalk_1.default.cyan('sudo systemctl daemon-reload'));
|
|
734
|
-
console.log(chalk_1.default.cyan('sudo systemctl enable neex'));
|
|
735
|
-
console.log(chalk_1.default.cyan('sudo systemctl start neex'));
|
|
736
|
-
console.log(`\n${chalk_1.default.bold('To check status:')}`);
|
|
737
|
-
console.log(chalk_1.default.cyan('sudo systemctl status neex'));
|
|
738
|
-
}
|
|
739
|
-
catch (error) {
|
|
740
|
-
if (error instanceof Error) {
|
|
741
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} Startup Error: ${error.message}`));
|
|
742
|
-
}
|
|
743
|
-
else {
|
|
744
|
-
console.error(chalk_1.default.red(`${figures_1.default.cross} An unknown startup error occurred`));
|
|
745
|
-
}
|
|
746
|
-
process.exit(1);
|
|
747
|
-
}
|
|
748
|
-
});
|
|
749
|
-
// Return cleanup function for process manager
|
|
750
|
-
return {
|
|
751
|
-
getProcessManager: () => processManager,
|
|
752
|
-
cleanupProcess: async () => {
|
|
753
|
-
if (processManager) {
|
|
754
|
-
await processManager.dispose();
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
};
|
|
758
|
-
}
|
|
759
|
-
exports.addProcessCommands = addProcessCommands;
|