@testsmith/api-spector 0.3.0 → 0.3.2
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/out/main/agents.js +24 -35
- package/out/main/chunks/{auth-builder-CRQayp8x.js → auth-builder-CUs9yzOF.js} +4 -3
- package/out/main/chunks/cli-common-CDQY1erJ.js +98 -0
- package/out/main/chunks/handle-C0IQL-Vl.js +164 -0
- package/out/main/chunks/{import-C9qdkBCH.js → import-C5Ngq8hk.js} +2 -1
- package/out/main/chunks/{ipc-validate-CscN4HfG.js → ipc-validate-k6KI8adf.js} +4 -2
- package/out/main/chunks/{request-collection-d2vgYls1.js → request-collection-8TOVNXE0.js} +296 -350
- package/out/main/chunks/{snapshots-CQliv7WB.js → snapshots-UFd3XgSS.js} +366 -26
- package/out/main/chunks/{soap-handler-Cpj-JwyA.js → soap-handler-B9x_YCtj.js} +6 -5
- package/out/main/contract.js +515 -58
- package/out/main/index.js +825 -785
- package/out/main/mock.js +30 -84
- package/out/main/record.js +19 -53
- package/out/main/runner.js +59 -321
- package/out/main/wsdl.js +9 -45
- package/out/preload/index.js +243 -90
- package/out/renderer/assets/{index-v6nKE4G2.js → index-BSWo6Dkt.js} +2801 -2950
- package/out/renderer/assets/index-CjvjKHtF.css +2 -0
- package/out/renderer/index.html +2 -2
- package/package.json +22 -4
- package/out/renderer/assets/index-D4vegaiz.css +0 -2
package/out/main/mock.js
CHANGED
|
@@ -1,74 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
-
const promises = require("fs/promises");
|
|
4
|
-
const path = require("path");
|
|
5
3
|
const mockServer = require("./chunks/mock-server-DSLR2ulH.js");
|
|
4
|
+
const cliCommon = require("./chunks/cli-common-CDQY1erJ.js");
|
|
6
5
|
require("http");
|
|
7
6
|
require("crypto");
|
|
8
7
|
require("vm");
|
|
9
8
|
require("dayjs");
|
|
10
9
|
require("@xmldom/xmldom");
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
bold: "\x1B[1m",
|
|
14
|
-
green: "\x1B[32m",
|
|
15
|
-
red: "\x1B[31m",
|
|
16
|
-
yellow: "\x1B[33m",
|
|
17
|
-
cyan: "\x1B[36m",
|
|
18
|
-
gray: "\x1B[90m",
|
|
19
|
-
white: "\x1B[97m"
|
|
20
|
-
};
|
|
21
|
-
function color(str, ...codes) {
|
|
22
|
-
return process.stdout.isTTY ? codes.join("") + str + C.reset : str;
|
|
23
|
-
}
|
|
24
|
-
function parseArgs(argv) {
|
|
25
|
-
const args = {};
|
|
26
|
-
for (let i = 0; i < argv.length; i++) {
|
|
27
|
-
const arg = argv[i];
|
|
28
|
-
if (!arg.startsWith("--")) continue;
|
|
29
|
-
const key = arg.slice(2);
|
|
30
|
-
const next = argv[i + 1];
|
|
31
|
-
if (!next || next.startsWith("--")) {
|
|
32
|
-
args[key] = true;
|
|
33
|
-
} else {
|
|
34
|
-
if (key === "name") {
|
|
35
|
-
const prev = args[key];
|
|
36
|
-
args[key] = Array.isArray(prev) ? [...prev, next] : [next];
|
|
37
|
-
} else {
|
|
38
|
-
args[key] = next;
|
|
39
|
-
}
|
|
40
|
-
i++;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return args;
|
|
44
|
-
}
|
|
45
|
-
async function resolveWorkspacePath(wsPath) {
|
|
46
|
-
const s = await promises.stat(wsPath);
|
|
47
|
-
if (!s.isDirectory()) return wsPath;
|
|
48
|
-
const entries = await promises.readdir(wsPath);
|
|
49
|
-
const spector = entries.find((e) => e.endsWith(".spector"));
|
|
50
|
-
if (!spector) throw new Error(`No .spector workspace file found in directory: ${wsPath}`);
|
|
51
|
-
return path.join(wsPath, spector);
|
|
52
|
-
}
|
|
53
|
-
async function loadWorkspace(wsPath) {
|
|
54
|
-
const resolved = await resolveWorkspacePath(wsPath);
|
|
55
|
-
const raw = await promises.readFile(resolved, "utf8");
|
|
56
|
-
return { workspace: JSON.parse(raw), dir: path.dirname(path.resolve(resolved)) };
|
|
57
|
-
}
|
|
58
|
-
async function loadMocks(workspace, dir) {
|
|
59
|
-
const mocks = [];
|
|
60
|
-
for (const relPath of workspace.mocks ?? []) {
|
|
61
|
-
try {
|
|
62
|
-
const raw = await promises.readFile(path.join(dir, relPath), "utf8");
|
|
63
|
-
mocks.push(JSON.parse(raw));
|
|
64
|
-
} catch {
|
|
65
|
-
console.warn(color(` [warn] Could not load mock: ${relPath}`, C.yellow));
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return mocks;
|
|
69
|
-
}
|
|
10
|
+
require("fs/promises");
|
|
11
|
+
require("path");
|
|
70
12
|
async function main() {
|
|
71
|
-
const args = parseArgs(process.argv.slice(2));
|
|
13
|
+
const args = cliCommon.parseArgs(process.argv.slice(2), ["name"]);
|
|
72
14
|
if (args.help) {
|
|
73
15
|
console.log(
|
|
74
16
|
"\nUsage:\n api-spector mock --workspace <path> [--name <server-name>] [--log]\n\nOptions:\n --workspace <path> Path to workspace.json (required)\n --name <name> Start only the named server (repeat for multiple)\n --log Print each incoming request (matched and unmatched)\n --help Show this message\n"
|
|
@@ -77,50 +19,54 @@ async function main() {
|
|
|
77
19
|
}
|
|
78
20
|
const wsPath = args.workspace;
|
|
79
21
|
if (!wsPath) {
|
|
80
|
-
console.error(color("Error: --workspace is required", C.red));
|
|
22
|
+
console.error(cliCommon.color("Error: --workspace is required", cliCommon.C.red));
|
|
81
23
|
process.exit(1);
|
|
82
24
|
}
|
|
83
25
|
let workspace, wsDir;
|
|
84
26
|
try {
|
|
85
27
|
;
|
|
86
|
-
({ workspace, dir: wsDir } = await loadWorkspace(wsPath));
|
|
28
|
+
({ workspace, dir: wsDir } = await cliCommon.loadWorkspace(wsPath));
|
|
87
29
|
} catch {
|
|
88
|
-
console.error(color(`Error: could not read workspace: ${wsPath}`, C.red));
|
|
30
|
+
console.error(cliCommon.color(`Error: could not read workspace: ${wsPath}`, cliCommon.C.red));
|
|
89
31
|
process.exit(1);
|
|
90
32
|
}
|
|
91
|
-
const allMocks = await loadMocks(
|
|
33
|
+
const allMocks = await cliCommon.loadMocks(
|
|
34
|
+
workspace,
|
|
35
|
+
wsDir,
|
|
36
|
+
(relPath) => console.warn(cliCommon.color(` [warn] Could not load mock: ${relPath}`, cliCommon.C.yellow))
|
|
37
|
+
);
|
|
92
38
|
if (allMocks.length === 0) {
|
|
93
|
-
console.error(color(" No mock servers defined in this workspace.", C.yellow));
|
|
39
|
+
console.error(cliCommon.color(" No mock servers defined in this workspace.", cliCommon.C.yellow));
|
|
94
40
|
process.exit(0);
|
|
95
41
|
}
|
|
96
42
|
const nameFilter = args.name ? (Array.isArray(args.name) ? args.name : [args.name]).map((n) => n.toLowerCase()) : null;
|
|
97
43
|
const toStart = nameFilter ? allMocks.filter((m) => nameFilter.includes(m.name.toLowerCase())) : allMocks;
|
|
98
44
|
if (toStart.length === 0) {
|
|
99
|
-
console.error(color(` No mock servers matched the given --name filter.`, C.yellow));
|
|
100
|
-
console.log(color(` Available: ${allMocks.map((m) => `"${m.name}"`).join(", ")}`, C.gray));
|
|
45
|
+
console.error(cliCommon.color(` No mock servers matched the given --name filter.`, cliCommon.C.yellow));
|
|
46
|
+
console.log(cliCommon.color(` Available: ${allMocks.map((m) => `"${m.name}"`).join(", ")}`, cliCommon.C.gray));
|
|
101
47
|
process.exit(1);
|
|
102
48
|
}
|
|
103
49
|
console.log("");
|
|
104
|
-
console.log(color(" Mock Servers", C.bold, C.white));
|
|
105
|
-
console.log(color(` Workspace: ${wsPath}`, C.gray));
|
|
50
|
+
console.log(cliCommon.color(" Mock Servers", cliCommon.C.bold, cliCommon.C.white));
|
|
51
|
+
console.log(cliCommon.color(` Workspace: ${wsPath}`, cliCommon.C.gray));
|
|
106
52
|
console.log("");
|
|
107
53
|
let started = 0;
|
|
108
54
|
for (const mock of toStart) {
|
|
109
55
|
try {
|
|
110
56
|
await mockServer.startMock(mock);
|
|
111
57
|
console.log(
|
|
112
|
-
color(" ✓", C.green, C.bold) + ` ${color(mock.name, C.white)} ` + color(`http://127.0.0.1:${mock.port}`, C.cyan) + color(` (${mock.routes.length} route${mock.routes.length !== 1 ? "s" : ""})`, C.gray)
|
|
58
|
+
cliCommon.color(" ✓", cliCommon.C.green, cliCommon.C.bold) + ` ${cliCommon.color(mock.name, cliCommon.C.white)} ` + cliCommon.color(`http://127.0.0.1:${mock.port}`, cliCommon.C.cyan) + cliCommon.color(` (${mock.routes.length} route${mock.routes.length !== 1 ? "s" : ""})`, cliCommon.C.gray)
|
|
113
59
|
);
|
|
114
60
|
for (const route of mock.routes) {
|
|
115
|
-
const delay = route.delay ? color(` ${route.delay}ms`, C.gray) : "";
|
|
61
|
+
const delay = route.delay ? cliCommon.color(` ${route.delay}ms`, cliCommon.C.gray) : "";
|
|
116
62
|
console.log(
|
|
117
|
-
color(` ${route.method.padEnd(7)} ${route.path}`, C.gray) + color(` → ${route.statusCode}`, route.statusCode < 400 ? C.green : C.red) + delay
|
|
63
|
+
cliCommon.color(` ${route.method.padEnd(7)} ${route.path}`, cliCommon.C.gray) + cliCommon.color(` → ${route.statusCode}`, route.statusCode < 400 ? cliCommon.C.green : cliCommon.C.red) + delay
|
|
118
64
|
);
|
|
119
65
|
}
|
|
120
66
|
started++;
|
|
121
67
|
} catch (e) {
|
|
122
68
|
console.error(
|
|
123
|
-
color(" ✗", C.red, C.bold) + ` ${mock.name} ` + color(e instanceof Error ? e.message : String(e), C.red)
|
|
69
|
+
cliCommon.color(" ✗", cliCommon.C.red, cliCommon.C.bold) + ` ${mock.name} ` + cliCommon.color(e instanceof Error ? e.message : String(e), cliCommon.C.red)
|
|
124
70
|
);
|
|
125
71
|
}
|
|
126
72
|
}
|
|
@@ -138,27 +84,27 @@ async function main() {
|
|
|
138
84
|
}
|
|
139
85
|
mockServer.setHitCallback((hit) => {
|
|
140
86
|
const ts = new Date(hit.timestamp).toISOString().slice(11, 23);
|
|
141
|
-
const server = color(serverNames[hit.serverId] ?? hit.serverId, C.white);
|
|
87
|
+
const server = cliCommon.color(serverNames[hit.serverId] ?? hit.serverId, cliCommon.C.white);
|
|
142
88
|
const method = hit.method.padEnd(7);
|
|
143
89
|
const matched = hit.matchedRouteId !== null;
|
|
144
|
-
const status = color(String(hit.status), hit.status < 400 ? C.green : C.red);
|
|
145
|
-
const dur = color(`${hit.durationMs}ms`, C.gray);
|
|
90
|
+
const status = cliCommon.color(String(hit.status), hit.status < 400 ? cliCommon.C.green : cliCommon.C.red);
|
|
91
|
+
const dur = cliCommon.color(`${hit.durationMs}ms`, cliCommon.C.gray);
|
|
146
92
|
if (matched) {
|
|
147
|
-
const route = color(routePaths[hit.matchedRouteId] ?? hit.matchedRouteId, C.gray);
|
|
93
|
+
const route = cliCommon.color(routePaths[hit.matchedRouteId] ?? hit.matchedRouteId, cliCommon.C.gray);
|
|
148
94
|
console.log(
|
|
149
|
-
color(` ${ts}`, C.gray) + ` ${server} ` + color(method, C.cyan) + color(hit.path, C.white) + ` ${status} ${dur}` + color(` → ${route}`, C.gray)
|
|
95
|
+
cliCommon.color(` ${ts}`, cliCommon.C.gray) + ` ${server} ` + cliCommon.color(method, cliCommon.C.cyan) + cliCommon.color(hit.path, cliCommon.C.white) + ` ${status} ${dur}` + cliCommon.color(` → ${route}`, cliCommon.C.gray)
|
|
150
96
|
);
|
|
151
97
|
} else {
|
|
152
98
|
console.log(
|
|
153
|
-
color(` ${ts}`, C.gray) + ` ${server} ` + color(method, C.yellow) + color(hit.path, C.yellow) + ` ${status} ${dur}` + color(" (no match)", C.yellow)
|
|
99
|
+
cliCommon.color(` ${ts}`, cliCommon.C.gray) + ` ${server} ` + cliCommon.color(method, cliCommon.C.yellow) + cliCommon.color(hit.path, cliCommon.C.yellow) + ` ${status} ${dur}` + cliCommon.color(" (no match)", cliCommon.C.yellow)
|
|
154
100
|
);
|
|
155
101
|
}
|
|
156
102
|
});
|
|
157
103
|
}
|
|
158
104
|
console.log("");
|
|
159
|
-
console.log(color(" Press Ctrl+C to stop all servers.\n", C.gray));
|
|
105
|
+
console.log(cliCommon.color(" Press Ctrl+C to stop all servers.\n", cliCommon.C.gray));
|
|
160
106
|
async function shutdown() {
|
|
161
|
-
console.log(color("\n Stopping mock servers…", C.gray));
|
|
107
|
+
console.log(cliCommon.color("\n Stopping mock servers…", cliCommon.C.gray));
|
|
162
108
|
await mockServer.stopAll();
|
|
163
109
|
process.exit(0);
|
|
164
110
|
}
|
|
@@ -168,6 +114,6 @@ async function main() {
|
|
|
168
114
|
}, 1 << 30);
|
|
169
115
|
}
|
|
170
116
|
main().catch((err) => {
|
|
171
|
-
console.error(color(`Fatal: ${err.message}`, C.red));
|
|
117
|
+
console.error(cliCommon.color(`Fatal: ${err.message}`, cliCommon.C.red));
|
|
172
118
|
process.exit(2);
|
|
173
119
|
});
|
package/out/main/record.js
CHANGED
|
@@ -3,51 +3,17 @@
|
|
|
3
3
|
const promises = require("fs/promises");
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const recorder = require("./chunks/recorder-DFxJgn9c.js");
|
|
6
|
+
const cliCommon = require("./chunks/cli-common-CDQY1erJ.js");
|
|
6
7
|
require("http");
|
|
7
8
|
require("crypto");
|
|
8
9
|
require("undici");
|
|
9
|
-
const C = {
|
|
10
|
-
reset: "\x1B[0m",
|
|
11
|
-
bold: "\x1B[1m",
|
|
12
|
-
dim: "\x1B[2m",
|
|
13
|
-
green: "\x1B[32m",
|
|
14
|
-
red: "\x1B[31m",
|
|
15
|
-
yellow: "\x1B[33m",
|
|
16
|
-
cyan: "\x1B[36m",
|
|
17
|
-
gray: "\x1B[90m",
|
|
18
|
-
white: "\x1B[97m"
|
|
19
|
-
};
|
|
20
|
-
function color(str, ...codes) {
|
|
21
|
-
return process.stdout.isTTY ? codes.join("") + str + C.reset : str;
|
|
22
|
-
}
|
|
23
10
|
function methodBadge(method) {
|
|
24
11
|
const m = method.toUpperCase();
|
|
25
|
-
const c = m === "GET" ? C.green : m === "POST" ? C.cyan : m === "PUT" || m === "PATCH" ? C.yellow : m === "DELETE" ? C.red : C.white;
|
|
26
|
-
return color(m.padEnd(7), c, C.bold);
|
|
27
|
-
}
|
|
28
|
-
function parseArgs(argv) {
|
|
29
|
-
const args = {};
|
|
30
|
-
for (let i = 0; i < argv.length; i++) {
|
|
31
|
-
const arg = argv[i];
|
|
32
|
-
if (!arg.startsWith("--")) continue;
|
|
33
|
-
const key = arg.slice(2);
|
|
34
|
-
const next = argv[i + 1];
|
|
35
|
-
if (!next || next.startsWith("--")) {
|
|
36
|
-
args[key] = true;
|
|
37
|
-
} else {
|
|
38
|
-
if (key === "mask" || key === "ignore") {
|
|
39
|
-
const existing = args[key];
|
|
40
|
-
args[key] = Array.isArray(existing) ? [...existing, next] : [next];
|
|
41
|
-
} else {
|
|
42
|
-
args[key] = next;
|
|
43
|
-
}
|
|
44
|
-
i++;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return args;
|
|
12
|
+
const c = m === "GET" ? cliCommon.C.green : m === "POST" ? cliCommon.C.cyan : m === "PUT" || m === "PATCH" ? cliCommon.C.yellow : m === "DELETE" ? cliCommon.C.red : cliCommon.C.white;
|
|
13
|
+
return cliCommon.color(m.padEnd(7), c, cliCommon.C.bold);
|
|
48
14
|
}
|
|
49
15
|
async function main() {
|
|
50
|
-
const args = parseArgs(process.argv.slice(2));
|
|
16
|
+
const args = cliCommon.parseArgs(process.argv.slice(2), ["mask", "ignore"]);
|
|
51
17
|
if (args.help) {
|
|
52
18
|
console.log(
|
|
53
19
|
"\nUsage:\n api-spector record --upstream <url> [options]\n\nOptions:\n --upstream <url> Real API base URL (required)\n --port <n> Local port (default: 4001)\n --output <path> Output directory (default: ./recordings)\n --mask <header> Mask header value with *** (repeatable)\n --ignore <header> Omit header from recordings (repeatable)\n"
|
|
@@ -56,7 +22,7 @@ async function main() {
|
|
|
56
22
|
}
|
|
57
23
|
const upstream = args.upstream?.replace(/\/$/, "");
|
|
58
24
|
if (!upstream) {
|
|
59
|
-
console.error(color("Error: --upstream <url> is required", C.red));
|
|
25
|
+
console.error(cliCommon.color("Error: --upstream <url> is required", cliCommon.C.red));
|
|
60
26
|
process.exit(1);
|
|
61
27
|
}
|
|
62
28
|
const port = parseInt(args.port ?? "4001", 10);
|
|
@@ -66,24 +32,24 @@ async function main() {
|
|
|
66
32
|
recorder.setRecorderHitCallback((entry) => {
|
|
67
33
|
const { method, path: path2 } = entry.request;
|
|
68
34
|
const { status, binary } = entry.response;
|
|
69
|
-
const sc = status < 300 ? C.green : status < 400 ? C.cyan : C.red;
|
|
70
|
-
const st = status > 0 ? color(String(status), sc, C.bold) : color("ERR", C.red, C.bold);
|
|
71
|
-
const bin = binary ? color(" [binary]", C.yellow) : "";
|
|
72
|
-
console.log(` ${methodBadge(method)} ${color(path2, C.white)} ${st} ${color(`${entry.durationMs}ms`, C.gray)}${bin}`);
|
|
35
|
+
const sc = status < 300 ? cliCommon.C.green : status < 400 ? cliCommon.C.cyan : cliCommon.C.red;
|
|
36
|
+
const st = status > 0 ? cliCommon.color(String(status), sc, cliCommon.C.bold) : cliCommon.color("ERR", cliCommon.C.red, cliCommon.C.bold);
|
|
37
|
+
const bin = binary ? cliCommon.color(" [binary]", cliCommon.C.yellow) : "";
|
|
38
|
+
console.log(` ${methodBadge(method)} ${cliCommon.color(path2, cliCommon.C.white)} ${st} ${cliCommon.color(`${entry.durationMs}ms`, cliCommon.C.gray)}${bin}`);
|
|
73
39
|
});
|
|
74
40
|
await recorder.startRecorder({ upstream, port, maskHeaders: extraMask, ignoreHeaders: extraIgnore });
|
|
75
41
|
console.log("");
|
|
76
|
-
console.log(color(" API Spector — Record Proxy", C.bold, C.white));
|
|
77
|
-
console.log(color(` Upstream: ${upstream}`, C.gray));
|
|
78
|
-
console.log(color(` Listening: http://localhost:${port}`, C.cyan));
|
|
79
|
-
console.log(color(` Output: ${outputDir}`, C.gray));
|
|
80
|
-
console.log(color(" Press Ctrl+C to stop and save recordings.\n", C.dim));
|
|
42
|
+
console.log(cliCommon.color(" API Spector — Record Proxy", cliCommon.C.bold, cliCommon.C.white));
|
|
43
|
+
console.log(cliCommon.color(` Upstream: ${upstream}`, cliCommon.C.gray));
|
|
44
|
+
console.log(cliCommon.color(` Listening: http://localhost:${port}`, cliCommon.C.cyan));
|
|
45
|
+
console.log(cliCommon.color(` Output: ${outputDir}`, cliCommon.C.gray));
|
|
46
|
+
console.log(cliCommon.color(" Press Ctrl+C to stop and save recordings.\n", cliCommon.C.dim));
|
|
81
47
|
async function shutdown() {
|
|
82
48
|
console.log("");
|
|
83
49
|
const session = recorder.stopRecorder();
|
|
84
50
|
recorder.setRecorderHitCallback(null);
|
|
85
51
|
if (session.entries.length === 0) {
|
|
86
|
-
console.log(color(" No requests recorded.", C.yellow));
|
|
52
|
+
console.log(cliCommon.color(" No requests recorded.", cliCommon.C.yellow));
|
|
87
53
|
process.exit(0);
|
|
88
54
|
}
|
|
89
55
|
await promises.mkdir(outputDir, { recursive: true });
|
|
@@ -94,9 +60,9 @@ async function main() {
|
|
|
94
60
|
const mockServer = recorder.entriesToMockServer(session.entries, upstream, mockName, port);
|
|
95
61
|
const mockPath = path.join(outputDir, `session-${slug}.mock.json`);
|
|
96
62
|
await promises.writeFile(mockPath, JSON.stringify(mockServer, null, 2), "utf8");
|
|
97
|
-
console.log(color(` Recorded ${session.entries.length} request${session.entries.length !== 1 ? "s" : ""}.`, C.green, C.bold));
|
|
98
|
-
console.log(color(` Session: ${sessionPath}`, C.gray));
|
|
99
|
-
console.log(color(` Mock stubs: ${mockPath}`, C.gray));
|
|
63
|
+
console.log(cliCommon.color(` Recorded ${session.entries.length} request${session.entries.length !== 1 ? "s" : ""}.`, cliCommon.C.green, cliCommon.C.bold));
|
|
64
|
+
console.log(cliCommon.color(` Session: ${sessionPath}`, cliCommon.C.gray));
|
|
65
|
+
console.log(cliCommon.color(` Mock stubs: ${mockPath}`, cliCommon.C.gray));
|
|
100
66
|
console.log("");
|
|
101
67
|
process.exit(0);
|
|
102
68
|
}
|
|
@@ -104,6 +70,6 @@ async function main() {
|
|
|
104
70
|
process.on("SIGTERM", shutdown);
|
|
105
71
|
}
|
|
106
72
|
main().catch((err) => {
|
|
107
|
-
console.error(color(`Fatal: ${err instanceof Error ? err.message : String(err)}`, "\x1B[31m"));
|
|
73
|
+
console.error(cliCommon.color(`Fatal: ${err instanceof Error ? err.message : String(err)}`, "\x1B[31m"));
|
|
108
74
|
process.exit(2);
|
|
109
75
|
});
|