fa-mcp-sdk 0.2.87 → 0.2.95
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/bin/fa-mcp.js +46 -7
- package/cli-template/.env.example +0 -2
- package/cli-template/config/_local.yaml +4 -2
- package/cli-template/config/custom-environment-variables.yaml +1 -0
- package/cli-template/config/default.yaml +19 -8
- package/cli-template/deploy/{mcp-template.com.conf → NGINX/sites-enabled/mcp-template.com.conf} +1 -1
- package/cli-template/deploy/NGINX/snippets/ssl-params.conf +18 -0
- package/cli-template/deploy/NGINX/snippets/ssl-wildcard.conf +3 -0
- package/cli-template/deploy/srv.cjs +450 -0
- package/cli-template/deploy/srv.sh.readme.md +122 -259
- package/cli-template/update.cjs +638 -642
- package/dist/core/_types_/types.d.ts +1 -0
- package/dist/core/_types_/types.d.ts.map +1 -1
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js +7 -3
- package/dist/core/logger.js.map +1 -1
- package/package.json +6 -6
- package/cli-template/deploy/srv.sh +0 -359
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* srv.cjs - Unified systemd service management script (Node.js version)
|
|
5
|
+
* Analog of deploy/srv.sh
|
|
6
|
+
* Can be run from project root or from deploy/ directory
|
|
7
|
+
*/
|
|
8
|
+
const version = '2025-11-26-08:46';
|
|
9
|
+
|
|
10
|
+
/* Colors for output */
|
|
11
|
+
const c = '\x1b[1;36m', lc = '\x1b[0;36m';
|
|
12
|
+
const g = '\x1b[1;32m', lg = '\x1b[0;32m';
|
|
13
|
+
const m = '\x1b[1;35m', lm = '\x1b[0;35m';
|
|
14
|
+
const r = '\x1b[1;31m', lr = '\x1b[0;31m';
|
|
15
|
+
const y = '\x1b[1;33m', ly = '\x1b[0;33m';
|
|
16
|
+
const c0 = '\x1b[0m';
|
|
17
|
+
|
|
18
|
+
const fs = require('fs');
|
|
19
|
+
const path = require('path');
|
|
20
|
+
const os = require('os');
|
|
21
|
+
const { execSync, spawn, spawnSync } = require('child_process');
|
|
22
|
+
|
|
23
|
+
/* Script configuration */
|
|
24
|
+
const SCRIPT_DIR = __dirname; // deploy/
|
|
25
|
+
const PROJECT_ROOT = path.resolve(SCRIPT_DIR, '..'); // Project root
|
|
26
|
+
process.chdir(PROJECT_ROOT);
|
|
27
|
+
|
|
28
|
+
let SERVICE_NAME = '';
|
|
29
|
+
let NODE_VERSION = '';
|
|
30
|
+
let PORT = '';
|
|
31
|
+
let COMMAND = '';
|
|
32
|
+
|
|
33
|
+
const trim = (v) => String(v || '').trim();
|
|
34
|
+
|
|
35
|
+
/* Helpers */
|
|
36
|
+
function log (...args) { console.log(...args); }
|
|
37
|
+
|
|
38
|
+
function err (...args) { console.error(...args); }
|
|
39
|
+
|
|
40
|
+
function sh (cmd, opts = {}) {
|
|
41
|
+
try {
|
|
42
|
+
return execSync(cmd, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], ...opts }).trim();
|
|
43
|
+
} catch (e) {
|
|
44
|
+
// Attach stderr to error message for easier diagnosis
|
|
45
|
+
const stderr = e.stderr ? e.stderr.toString() : '';
|
|
46
|
+
const stdout = e.stdout ? e.stdout.toString() : '';
|
|
47
|
+
const msg = stderr || stdout || e.message;
|
|
48
|
+
const errObj = new Error(msg);
|
|
49
|
+
errObj.code = e.status;
|
|
50
|
+
throw errObj;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function showUsage () {
|
|
55
|
+
const usage = `
|
|
56
|
+
Usage:
|
|
57
|
+
${process.argv[1]} i|install [-n <service_name>] [-v <node_version>]
|
|
58
|
+
${process.argv[1]} d|delete [-n <service_name>] [-p <port>]
|
|
59
|
+
${process.argv[1]} r|reinstall [-n <service_name>] [-p <port>] [-v <node_version>]
|
|
60
|
+
|
|
61
|
+
Commands:
|
|
62
|
+
i, install - Install and start systemd service
|
|
63
|
+
d, delete - Stop and remove systemd service
|
|
64
|
+
r, reinstall - Reinstall service (delete + install)
|
|
65
|
+
|
|
66
|
+
Options:
|
|
67
|
+
-n <name> - Alternative service name (default: from package.json)
|
|
68
|
+
-v <version> - Node.js version (default: auto-detected)
|
|
69
|
+
-p <port> - Port number for service cleanup (default: auto-detected)
|
|
70
|
+
|
|
71
|
+
Working directories:
|
|
72
|
+
Script location: ${SCRIPT_DIR}
|
|
73
|
+
Project root: ${PROJECT_ROOT}
|
|
74
|
+
`.trim();
|
|
75
|
+
log(usage);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function serviceExists (name) {
|
|
79
|
+
try {
|
|
80
|
+
const cmd = `systemctl list-units --all -t service --full --no-legend ${name}.service`;
|
|
81
|
+
const out = sh(cmd, { shell: '/bin/bash' });
|
|
82
|
+
const re = new RegExp(`\\b${name}\\.service\\b`);
|
|
83
|
+
return re.test(out);
|
|
84
|
+
} catch {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function readFileSafe (p) {
|
|
90
|
+
try { return fs.readFileSync(p, 'utf8'); } catch { return ''; }
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function detectNodeVersion () {
|
|
94
|
+
let version = '';
|
|
95
|
+
if (NODE_VERSION) {
|
|
96
|
+
version = NODE_VERSION;
|
|
97
|
+
err(`${c}**** Using provided Node.js version: ${g}${version}${c} ****${c0}`);
|
|
98
|
+
} else {
|
|
99
|
+
const envrc = path.join(PROJECT_ROOT, '.envrc');
|
|
100
|
+
if (fs.existsSync(envrc)) {
|
|
101
|
+
const content = readFileSafe(envrc);
|
|
102
|
+
const m = content.match(/^\s*nvm\s+use\s+([0-9]+\.[0-9]+\.[0-9]+)/m);
|
|
103
|
+
if (m) {
|
|
104
|
+
version = m[1];
|
|
105
|
+
err(`${c}**** Found Node.js version in .envrc: ${g}${version}${c} ****${c0}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (!version) {
|
|
110
|
+
try {
|
|
111
|
+
const v = sh('node -v 2>/dev/null', { shell: '/bin/bash' });
|
|
112
|
+
version = v.replace(/^v/, '');
|
|
113
|
+
if (version) {
|
|
114
|
+
err(`${c}**** Using current Node.js version: ${g}${version}${c} ****${c0}`);
|
|
115
|
+
}
|
|
116
|
+
} catch {
|
|
117
|
+
// ignore
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (!version) {
|
|
121
|
+
err(`${r}**** Error: Could not detect Node.js version ****${c0}`);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
return version;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function findNodePath (version) {
|
|
128
|
+
// Try NVM path first
|
|
129
|
+
const nvmPath = path.join(os.homedir(), '.nvm', 'versions', 'node', `v${version}`, 'bin', 'node');
|
|
130
|
+
if (fs.existsSync(nvmPath)) {
|
|
131
|
+
err(`${c}**** Found Node.js at NVM path: ${g}${nvmPath}${c} ****${c0}`);
|
|
132
|
+
return nvmPath;
|
|
133
|
+
}
|
|
134
|
+
// Try system node
|
|
135
|
+
try {
|
|
136
|
+
const whichNode = sh('which node 2>/dev/null', { shell: '/bin/bash' });
|
|
137
|
+
if (whichNode) {
|
|
138
|
+
let currentVersion = '';
|
|
139
|
+
try { currentVersion = sh('node -v 2>/dev/null', { shell: '/bin/bash' }).replace(/^v/, ''); } catch {}
|
|
140
|
+
if (currentVersion === version) {
|
|
141
|
+
err(`${c}**** Found Node.js at system path: ${g}${whichNode}${c} ****${c0}`);
|
|
142
|
+
} else {
|
|
143
|
+
const warn = `
|
|
144
|
+
${y}**** Warning: System Node.js version (${currentVersion}) differs from target (${version}) ****${c0}
|
|
145
|
+
${c}**** Using system path anyway: ${g}${whichNode}${c} ****${c0}
|
|
146
|
+
`.trim();
|
|
147
|
+
err(warn);
|
|
148
|
+
}
|
|
149
|
+
return whichNode;
|
|
150
|
+
}
|
|
151
|
+
} catch {
|
|
152
|
+
// ignore
|
|
153
|
+
}
|
|
154
|
+
err(`${r}**** Error: Could not find Node.js binary ****${c0}`);
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function parsePackageJson (field) {
|
|
159
|
+
const packageFile = path.join(PROJECT_ROOT, 'package.json');
|
|
160
|
+
if (!fs.existsSync(packageFile)) {
|
|
161
|
+
err(`${r}**** Error: package.json not found at ${packageFile} ****${c0}`);
|
|
162
|
+
process.exit(1);
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
const pkg = JSON.parse(fs.readFileSync(packageFile, 'utf8'));
|
|
166
|
+
const value = pkg[field] || '';
|
|
167
|
+
if (!value) throw new Error('empty');
|
|
168
|
+
return value;
|
|
169
|
+
} catch {
|
|
170
|
+
err(`${r}**** Error: Could not parse ${field} from package.json ****${c0}`);
|
|
171
|
+
process.exit(1);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Parse .env in project root to extract variables
|
|
176
|
+
function parseDotEnvVars () {
|
|
177
|
+
const envPath = path.join(PROJECT_ROOT, '.env');
|
|
178
|
+
const result = {};
|
|
179
|
+
if (!fs.existsSync(envPath)) return result;
|
|
180
|
+
try {
|
|
181
|
+
const content = fs.readFileSync(envPath, 'utf8');
|
|
182
|
+
// Simple line parser, ignores comments and empty lines
|
|
183
|
+
for (const line of content.split(/\r?\n/)) {
|
|
184
|
+
if (!line || /^\s*#/.test(line)) continue;
|
|
185
|
+
const m = line.match(/^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)\s*$/);
|
|
186
|
+
if (!m) continue;
|
|
187
|
+
const key = m[1];
|
|
188
|
+
// remove surrounding quotes if present
|
|
189
|
+
let val = m[2];
|
|
190
|
+
const q = val[0];
|
|
191
|
+
if ((q === '"' || q === '\'') && val[val.length - 1] === q) {
|
|
192
|
+
val = val.slice(1, -1);
|
|
193
|
+
}
|
|
194
|
+
result[key] = val;
|
|
195
|
+
}
|
|
196
|
+
} catch {}
|
|
197
|
+
return result;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Return full service name aligned with update.cjs logic: base name plus optional "--<instance>"
|
|
201
|
+
function getServiceName () {
|
|
202
|
+
// Highest priority: CLI parameter (-n)
|
|
203
|
+
let baseName = trim(SERVICE_NAME);
|
|
204
|
+
if (baseName) {
|
|
205
|
+
return baseName;
|
|
206
|
+
}
|
|
207
|
+
let instance = '';
|
|
208
|
+
|
|
209
|
+
const envVars = parseDotEnvVars();
|
|
210
|
+
|
|
211
|
+
// If base name not provided via CLI, try from .env, then from package.json
|
|
212
|
+
if (!baseName) {
|
|
213
|
+
baseName = trim(envVars.SERVICE_NAME);
|
|
214
|
+
}
|
|
215
|
+
if (!baseName) {
|
|
216
|
+
baseName = parsePackageJson('name');
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Instance suffix from .env if present
|
|
220
|
+
const rawInstance = trim(envVars.SERVICE_INSTANCE);
|
|
221
|
+
if (rawInstance) {
|
|
222
|
+
instance = `--${rawInstance}`;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return `${baseName}${instance}`;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
async function detectPort () {
|
|
229
|
+
if (PORT) return PORT;
|
|
230
|
+
// Try to load config from project root
|
|
231
|
+
try {
|
|
232
|
+
// Ensure module resolution relative to project root
|
|
233
|
+
const createRequire = require('module').createRequire;
|
|
234
|
+
const projectRequire = createRequire(path.join(PROJECT_ROOT, 'package.json'));
|
|
235
|
+
let cfg;
|
|
236
|
+
try {
|
|
237
|
+
cfg = projectRequire('config');
|
|
238
|
+
} catch (e) {
|
|
239
|
+
// Try dynamic import
|
|
240
|
+
cfg = await new Function('p', 'return import(p)')('config');
|
|
241
|
+
cfg = cfg.default || cfg;
|
|
242
|
+
}
|
|
243
|
+
const port = cfg?.webServer?.port || cfg?.server?.port;
|
|
244
|
+
if (port && String(port).match(/^[0-9]{2,5}$/)) return String(port);
|
|
245
|
+
} catch (e) {
|
|
246
|
+
// ignore, will fail below
|
|
247
|
+
}
|
|
248
|
+
err(`${r}**** Error: Could not detect port from config ****${c0}`);
|
|
249
|
+
process.exit(1);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function generateUnitFile (serviceName, nodePath, mainFile) {
|
|
253
|
+
const workingDir = PROJECT_ROOT;
|
|
254
|
+
const serviceFile = `/etc/systemd/system/${serviceName}.service`;
|
|
255
|
+
const content = `
|
|
256
|
+
[Unit]
|
|
257
|
+
Description=${serviceName}
|
|
258
|
+
After=network.target
|
|
259
|
+
# https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#StartLimitIntervalSec=interval
|
|
260
|
+
StartLimitIntervalSec=0
|
|
261
|
+
|
|
262
|
+
[Service]
|
|
263
|
+
User=root
|
|
264
|
+
WorkingDirectory=${workingDir}
|
|
265
|
+
EnvironmentFile=${workingDir}/.env
|
|
266
|
+
ExecStart=${nodePath} ${mainFile}
|
|
267
|
+
Restart=always
|
|
268
|
+
RestartSec=3
|
|
269
|
+
|
|
270
|
+
[Install]
|
|
271
|
+
WantedBy=multi-user.target
|
|
272
|
+
`.trimStart();
|
|
273
|
+
fs.writeFileSync(serviceFile, content, 'utf8');
|
|
274
|
+
const info = `
|
|
275
|
+
${c}**** Generated unit file for ${g}${serviceName}${c} ****${c0}
|
|
276
|
+
${lc} WorkingDirectory: ${g}${workingDir}${c0}
|
|
277
|
+
${lc} ExecStart: ${g}${nodePath} ${mainFile}${c0}
|
|
278
|
+
${lc} View Service file: ${g}cat ${serviceFile}${c0}
|
|
279
|
+
`.trim();
|
|
280
|
+
err(info);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function systemctl (args, inherit = false) {
|
|
284
|
+
if (inherit) {
|
|
285
|
+
const p = spawn('systemctl', args.split(/\s+/).filter(Boolean), { stdio: 'inherit' });
|
|
286
|
+
return new Promise((resolve, reject) => {
|
|
287
|
+
p.on('exit', code => code === 0 ? resolve() : reject(new Error(`systemctl ${args} exited with ${code}`)));
|
|
288
|
+
});
|
|
289
|
+
} else {
|
|
290
|
+
sh(`systemctl ${args}`);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
async function installService () {
|
|
295
|
+
log(`${c}**** Installing service ****${c0}`);
|
|
296
|
+
const nodeVersion = detectNodeVersion();
|
|
297
|
+
const nodePath = findNodePath(nodeVersion);
|
|
298
|
+
const mainFile = parsePackageJson('main');
|
|
299
|
+
const serviceName = getServiceName();
|
|
300
|
+
|
|
301
|
+
const cfgInfo = `
|
|
302
|
+
${c}**** Service configuration ****${c0}
|
|
303
|
+
${lc} Service name: ${g}${serviceName}${c0}
|
|
304
|
+
${lc} Node.js version: ${g}${nodeVersion}${c0}
|
|
305
|
+
${lc} Node.js path: ${g}${nodePath}${c0}
|
|
306
|
+
${lc} Main file: ${g}${mainFile}${c0}
|
|
307
|
+
${lc} Project root: ${g}${PROJECT_ROOT}${c0}
|
|
308
|
+
`.trim();
|
|
309
|
+
err(cfgInfo);
|
|
310
|
+
|
|
311
|
+
if (serviceExists(serviceName)) {
|
|
312
|
+
err(`${c}**** Service ${g}${serviceName}${c} already installed ****${c0}`);
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
generateUnitFile(serviceName, nodePath, mainFile);
|
|
317
|
+
|
|
318
|
+
// Reload systemd and enable service
|
|
319
|
+
sh('systemctl daemon-reload');
|
|
320
|
+
try {
|
|
321
|
+
sh(`systemctl enable --now ${serviceName}`);
|
|
322
|
+
} catch (e) {
|
|
323
|
+
const msg = `
|
|
324
|
+
${r}**** Error: Failed to install service ${serviceName} ****${c0}
|
|
325
|
+
${e.message || String(e)}
|
|
326
|
+
`.trim();
|
|
327
|
+
err(msg);
|
|
328
|
+
process.exit(1);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const post = `
|
|
332
|
+
${c}**** Service ${g}${serviceName}${c} installed and started ****${c0}
|
|
333
|
+
|
|
334
|
+
${m}View status: ${y}systemctl -l status ${serviceName}${c0}
|
|
335
|
+
${m}View logs: ${y}journalctl -o cat -xefu ${serviceName}${c0}
|
|
336
|
+
`.trim();
|
|
337
|
+
log(post);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
async function deleteService () {
|
|
341
|
+
const serviceName = getServiceName();
|
|
342
|
+
const port = await detectPort();
|
|
343
|
+
log(`${c}**** Removing service ${g}${serviceName}${c} listening on port ${g}${port}${c} ****${c0}`);
|
|
344
|
+
|
|
345
|
+
if (!serviceExists(serviceName)) {
|
|
346
|
+
log(`${c}**** Service ${g}${serviceName}${c} not found ****${c0}`);
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
try { sh(`systemctl stop ${serviceName}`); } catch {}
|
|
351
|
+
try { sh(`systemctl disable ${serviceName}`); } catch {}
|
|
352
|
+
|
|
353
|
+
try { fs.unlinkSync(`/etc/systemd/system/${serviceName}.service`); } catch {}
|
|
354
|
+
|
|
355
|
+
// Kill any remaining process on the port
|
|
356
|
+
try {
|
|
357
|
+
const out = sh(`lsof -i tcp:${port} 2>/dev/null | grep ${port} | awk '{print $2}' | head -1`, { shell: '/bin/bash' });
|
|
358
|
+
if (out) {
|
|
359
|
+
log(`${c}**** Killing process ${g}${out}${c} on port ${g}${port}${c} ****${c0}`);
|
|
360
|
+
try { sh(`kill -9 ${out}`); } catch {}
|
|
361
|
+
}
|
|
362
|
+
} catch {}
|
|
363
|
+
|
|
364
|
+
try { sh('systemctl daemon-reload'); } catch {}
|
|
365
|
+
log(`${c}**** Service ${g}${serviceName}${c} removed ****${c0}`);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
async function reinstallService () {
|
|
369
|
+
log(`${c}**** Reinstalling service ****${c0}`);
|
|
370
|
+
await deleteService();
|
|
371
|
+
await installService();
|
|
372
|
+
const serviceName = getServiceName();
|
|
373
|
+
log(`${c}**** Service ${g}${serviceName}${c} reinstalled ****${c0}`);
|
|
374
|
+
|
|
375
|
+
try {
|
|
376
|
+
await systemctl(`status ${serviceName}`, true);
|
|
377
|
+
} catch {}
|
|
378
|
+
log(`\n${m}Following logs (Ctrl+C to exit): ${y}journalctl -o cat -xefu ${serviceName}${c0}`);
|
|
379
|
+
// Follow logs until user interrupts
|
|
380
|
+
const p = spawn('journalctl', ['-o', 'cat', '-xefu', serviceName], { stdio: 'inherit' });
|
|
381
|
+
await new Promise(resolve => p.on('exit', resolve));
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/* Argument parsing */
|
|
385
|
+
async function main () {
|
|
386
|
+
if (process.argv.length <= 2) {
|
|
387
|
+
showUsage();
|
|
388
|
+
process.exit(1);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
const args = process.argv.slice(2);
|
|
392
|
+
const cmd = args.shift();
|
|
393
|
+
switch (cmd) {
|
|
394
|
+
case 'i':
|
|
395
|
+
case 'install':
|
|
396
|
+
COMMAND = 'install';
|
|
397
|
+
break;
|
|
398
|
+
case 'd':
|
|
399
|
+
case 'delete':
|
|
400
|
+
COMMAND = 'delete';
|
|
401
|
+
break;
|
|
402
|
+
case 'r':
|
|
403
|
+
case 'reinstall':
|
|
404
|
+
COMMAND = 'reinstall';
|
|
405
|
+
break;
|
|
406
|
+
default:
|
|
407
|
+
err(`${r}**** Error: Unknown command '${cmd}' ****${c0}`);
|
|
408
|
+
showUsage();
|
|
409
|
+
process.exit(1);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Parse options
|
|
413
|
+
while (args.length > 0) {
|
|
414
|
+
const a = args.shift();
|
|
415
|
+
switch (a) {
|
|
416
|
+
case '-n':
|
|
417
|
+
SERVICE_NAME = args.shift() || '';
|
|
418
|
+
break;
|
|
419
|
+
case '-v':
|
|
420
|
+
NODE_VERSION = args.shift() || '';
|
|
421
|
+
break;
|
|
422
|
+
case '-p':
|
|
423
|
+
PORT = args.shift() || '';
|
|
424
|
+
break;
|
|
425
|
+
default:
|
|
426
|
+
err(`${r}**** Error: Unknown option '${a}' ****${c0}`);
|
|
427
|
+
showUsage();
|
|
428
|
+
process.exit(1);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
switch (COMMAND) {
|
|
433
|
+
case 'install':
|
|
434
|
+
await installService();
|
|
435
|
+
break;
|
|
436
|
+
case 'delete':
|
|
437
|
+
await deleteService();
|
|
438
|
+
break;
|
|
439
|
+
case 'reinstall':
|
|
440
|
+
await reinstallService();
|
|
441
|
+
break;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
main().then(() => {
|
|
446
|
+
process.exit(0);
|
|
447
|
+
}).catch(e => {
|
|
448
|
+
err(String(e && e.message ? e.message : e));
|
|
449
|
+
process.exit(1);
|
|
450
|
+
});
|