systemview 1.20.0 → 1.21.0
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 +76 -40
- package/api/Connections.js +14 -0
- package/api/connections.json +1 -1
- package/api/index.js +40 -12
- package/build/asset-manifest.json +8 -6
- package/build/index.html +1 -1
- package/build/static/css/main.8e85f0c8.css +15 -0
- package/build/static/css/main.8e85f0c8.css.map +1 -0
- package/build/static/js/422.05c538a9.chunk.js +2 -0
- package/build/static/js/422.05c538a9.chunk.js.map +1 -0
- package/build/static/js/main.6240c0f1.js +3 -0
- package/build/static/js/{main.c3485d98.js.LICENSE.txt → main.6240c0f1.js.LICENSE.txt} +26 -48
- package/build/static/js/main.6240c0f1.js.map +1 -0
- package/cli/connectService.js +147 -55
- package/cli/cookieClient.js +1 -4
- package/cli/index.js +85 -29
- package/cli/launchApp.js +5 -4
- package/cli/listTests.js +15 -19
- package/cli/logs.js +251 -0
- package/cli/manifest.js +97 -0
- package/cli/probe.js +36 -19
- package/cli/runTests.js +35 -40
- package/cli/startLineReader.js +122 -13
- package/cli/utils/cli.js +60 -12
- package/package.json +3 -3
- package/testing-utilities/Test.class.js +2 -1
- package/testing-utilities/transformTests.js +7 -6
- package/build/static/css/main.3396e24d.css +0 -15
- package/build/static/css/main.3396e24d.css.map +0 -1
- package/build/static/js/main.c3485d98.js +0 -3
- package/build/static/js/main.c3485d98.js.map +0 -1
package/cli/connectService.js
CHANGED
|
@@ -1,80 +1,172 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const Client = createCookieClient();
|
|
1
|
+
const { HttpClient, createClient } = require("systemlynx");
|
|
2
|
+
const { createCookieHttpClient } = require("./cookieClient");
|
|
3
|
+
const cookieHttpClient = createCookieHttpClient();
|
|
4
|
+
const Client = createClient(cookieHttpClient);
|
|
6
5
|
const log = require("./logger");
|
|
7
6
|
|
|
8
|
-
async function
|
|
9
|
-
const connectionData = await HttpClient.request({ url });
|
|
10
|
-
if (!connectionData.SystemLynxService) {
|
|
11
|
-
throw new Error(`No SystemLynx service found at ${url}`);
|
|
12
|
-
}
|
|
13
|
-
const client = Client.createService(connectionData);
|
|
14
|
-
const connection = await client.Plugin.getConnection();
|
|
15
|
-
return connection; // { projectCode, serviceId, system, specList }
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function readManifest(manifestFile) {
|
|
19
|
-
if (!fs.existsSync(manifestFile)) return null;
|
|
7
|
+
async function getUiSvc(uiUrl) {
|
|
20
8
|
try {
|
|
21
|
-
|
|
9
|
+
const { SystemView } = await Client.loadService(`${uiUrl}/systemview/api`);
|
|
10
|
+
return SystemView;
|
|
22
11
|
} catch {
|
|
23
12
|
return null;
|
|
24
13
|
}
|
|
25
14
|
}
|
|
26
15
|
|
|
27
|
-
function
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
16
|
+
async function notifyUi(uiSvc, project) {
|
|
17
|
+
if (!uiSvc) return;
|
|
18
|
+
try {
|
|
19
|
+
await uiSvc.connect(project);
|
|
20
|
+
} catch {}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function serviceIdFromRoute(route) {
|
|
24
|
+
const segments = (route || "").split("/").filter(Boolean);
|
|
25
|
+
return [...segments].reverse().find((s) => s.toLowerCase() !== "api") || "Service";
|
|
36
26
|
}
|
|
37
27
|
|
|
38
|
-
|
|
39
|
-
|
|
28
|
+
function printSummary(entries) {
|
|
29
|
+
console.log("");
|
|
30
|
+
entries.forEach(({ projectCode, serviceId, url }) => {
|
|
31
|
+
log.plain(` ${projectCode} › ${serviceId}${url ? " " + url : ""}`);
|
|
32
|
+
});
|
|
33
|
+
console.log("");
|
|
34
|
+
}
|
|
40
35
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
36
|
+
module.exports = async function connectService(target, { useManifest, force, connectedUrls, uiUrl } = {}) {
|
|
37
|
+
const uiSvc = await getUiSvc(uiUrl);
|
|
38
|
+
|
|
39
|
+
// connect (no args) — connect to every service stored in UI
|
|
40
|
+
if (!target) {
|
|
41
|
+
if (!uiSvc) {
|
|
42
|
+
log.warn("SystemView UI not running. Start it first or provide a URL.");
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const projects = await uiSvc.getProjects();
|
|
46
|
+
const all = Object.entries(projects).flatMap(([pc, svcs]) =>
|
|
47
|
+
svcs.map((s) => ({ projectCode: pc, ...s }))
|
|
48
|
+
);
|
|
49
|
+
if (!all.length) {
|
|
50
|
+
log.warn("No services in UI store. Use: systemview connect <url>");
|
|
46
51
|
return;
|
|
47
52
|
}
|
|
48
|
-
log.info(`
|
|
49
|
-
|
|
53
|
+
log.info(`Connecting to ${all.length} stored service(s)...`);
|
|
54
|
+
const summary = [];
|
|
55
|
+
for (const { projectCode, serviceId, connectionData, serviceUrl } of all) {
|
|
56
|
+
const url = serviceUrl || (connectionData && connectionData.serviceUrl);
|
|
57
|
+
if (!url) continue;
|
|
50
58
|
try {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
59
|
+
if (force) {
|
|
60
|
+
await Client.loadService(url);
|
|
61
|
+
} else {
|
|
62
|
+
Client.createService(connectionData);
|
|
63
|
+
}
|
|
64
|
+
connectedUrls.add(url);
|
|
65
|
+
log.success(`${projectCode} › ${serviceId}`);
|
|
66
|
+
summary.push({ projectCode, serviceId, url });
|
|
54
67
|
} catch (err) {
|
|
55
|
-
log.error(`${
|
|
68
|
+
log.error(`${serviceId} failed: ${err.message}`);
|
|
56
69
|
}
|
|
57
70
|
}
|
|
58
|
-
|
|
71
|
+
printSummary(summary);
|
|
59
72
|
return;
|
|
60
73
|
}
|
|
61
74
|
|
|
62
|
-
|
|
75
|
+
const isUrl = /^https?:\/\//i.test(target);
|
|
76
|
+
|
|
77
|
+
// connect <projectCode> — look up from UI store
|
|
78
|
+
if (!isUrl) {
|
|
79
|
+
if (!uiSvc) {
|
|
80
|
+
log.warn("SystemView UI not running. Cannot look up project by code.");
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const services = await uiSvc.getServices(target);
|
|
84
|
+
if (!services || !services.length) {
|
|
85
|
+
log.warn(`No services found for project: ${target}`);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
log.info(`Connecting to ${services.length} service(s) for ${target}...`);
|
|
89
|
+
const summary = [];
|
|
90
|
+
for (const { serviceId, system } of services) {
|
|
91
|
+
const { serviceUrl } = system.connectionData;
|
|
92
|
+
try {
|
|
93
|
+
if (force) {
|
|
94
|
+
await Client.loadService(serviceUrl);
|
|
95
|
+
} else {
|
|
96
|
+
Client.createService(system.connectionData);
|
|
97
|
+
}
|
|
98
|
+
connectedUrls.add(serviceUrl);
|
|
99
|
+
log.success(`${target} › ${serviceId}`);
|
|
100
|
+
summary.push({ projectCode: target, serviceId, url: serviceUrl });
|
|
101
|
+
} catch (err) {
|
|
102
|
+
log.error(`${serviceId} failed: ${err.message}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
printSummary(summary);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// connect <url> [--manifest]
|
|
110
|
+
log.info(`Connecting to ${target}...`);
|
|
63
111
|
try {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
112
|
+
if (useManifest) {
|
|
113
|
+
const svc = await Client.loadService(target);
|
|
114
|
+
let manifest = null;
|
|
115
|
+
try { manifest = await svc.Plugin.getManifest(); } catch {}
|
|
116
|
+
if (manifest && manifest.services && manifest.services.length) {
|
|
117
|
+
log.info(`Plugin manifest found: ${manifest.projectCode} (${manifest.services.length} service(s))`);
|
|
118
|
+
const summary = [];
|
|
119
|
+
for (const service of manifest.services) {
|
|
120
|
+
try {
|
|
121
|
+
Client.createService(service.system.connectionData);
|
|
122
|
+
connectedUrls.add(service.system.connectionData.serviceUrl);
|
|
123
|
+
await notifyUi(uiSvc, {
|
|
124
|
+
system: service.system,
|
|
125
|
+
projectCode: manifest.projectCode,
|
|
126
|
+
serviceId: service.serviceId,
|
|
127
|
+
specList: service.specList || { tests: [], docs: [] },
|
|
128
|
+
});
|
|
129
|
+
log.success(`${manifest.projectCode} › ${service.serviceId}`);
|
|
130
|
+
summary.push({ projectCode: manifest.projectCode, serviceId: service.serviceId, url: service.system.connectionData.serviceUrl });
|
|
131
|
+
} catch (err) {
|
|
132
|
+
log.error(`${service.serviceId} failed: ${err.message}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
printSummary(summary);
|
|
136
|
+
} else {
|
|
137
|
+
log.warn("No plugin manifest found. Storing as connected-services.");
|
|
138
|
+
const connectionData = await HttpClient.request({ url: target });
|
|
139
|
+
const serviceId = serviceIdFromRoute(connectionData.route);
|
|
140
|
+
const project = {
|
|
141
|
+
system: { connectionData },
|
|
142
|
+
projectCode: "connected-services",
|
|
143
|
+
serviceId,
|
|
144
|
+
specList: { tests: [], docs: [] },
|
|
145
|
+
};
|
|
146
|
+
Client.createService(connectionData);
|
|
147
|
+
connectedUrls.add(target);
|
|
148
|
+
await notifyUi(uiSvc, project);
|
|
149
|
+
printSummary([{ projectCode: "connected-services", serviceId, url: target }]);
|
|
150
|
+
}
|
|
151
|
+
} else {
|
|
152
|
+
const connectionData = await HttpClient.request({ url: target });
|
|
153
|
+
if (!connectionData || !connectionData.SystemLynxService) {
|
|
154
|
+
throw new Error("No SystemLynx service found at " + target);
|
|
155
|
+
}
|
|
156
|
+
const serviceId = serviceIdFromRoute(connectionData.route);
|
|
157
|
+
const project = {
|
|
158
|
+
system: { connectionData },
|
|
159
|
+
projectCode: "connected-services",
|
|
160
|
+
serviceId,
|
|
161
|
+
specList: { tests: [], docs: [] },
|
|
162
|
+
};
|
|
163
|
+
Client.createService(connectionData);
|
|
164
|
+
connectedUrls.add(target);
|
|
165
|
+
await notifyUi(uiSvc, project);
|
|
166
|
+
log.success(`connected-services › ${serviceId}`);
|
|
167
|
+
printSummary([{ projectCode: "connected-services", serviceId, url: target }]);
|
|
168
|
+
}
|
|
67
169
|
} catch (err) {
|
|
68
170
|
log.error(`Connection failed: ${err.message}`);
|
|
69
171
|
}
|
|
70
172
|
};
|
|
71
|
-
|
|
72
|
-
function printManifestSummary(manifest) {
|
|
73
|
-
if (!manifest) return;
|
|
74
|
-
log.plain(`\n Project: ${manifest.projectCode}`);
|
|
75
|
-
log.plain(` Services:`);
|
|
76
|
-
(manifest.services || []).forEach(({ serviceId, system }) => {
|
|
77
|
-
log.plain(` - ${serviceId} @ ${system.connectionData.serviceUrl}`);
|
|
78
|
-
});
|
|
79
|
-
log.plain("");
|
|
80
|
-
}
|
package/cli/cookieClient.js
CHANGED
|
@@ -87,7 +87,4 @@ function createCookieHttpClient(extraHeaders = {}) {
|
|
|
87
87
|
};
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
module.exports = {
|
|
91
|
-
createCookieHttpClient,
|
|
92
|
-
createCookieClient: (extraHeaders = {}) => createClient(createCookieHttpClient(extraHeaders)),
|
|
93
|
-
};
|
|
90
|
+
module.exports = { createCookieHttpClient };
|
package/cli/index.js
CHANGED
|
@@ -13,17 +13,39 @@ const listTests = require("./listTests");
|
|
|
13
13
|
const appIsRunning = require("./appIsRunning");
|
|
14
14
|
const openBrowser = require("./openBrowser");
|
|
15
15
|
const connectService = require("./connectService");
|
|
16
|
+
const manifestCommands = require("./manifest");
|
|
16
17
|
const probe = require("./probe");
|
|
17
|
-
const
|
|
18
|
-
const {
|
|
18
|
+
const logsCommand = require("./logs");
|
|
19
|
+
const { HttpClient, createClient } = require("systemlynx");
|
|
20
|
+
const { createCookieHttpClient } = require("./cookieClient");
|
|
21
|
+
const cookieHttpClient = createCookieHttpClient();
|
|
22
|
+
const Client = createClient(cookieHttpClient);
|
|
19
23
|
|
|
20
24
|
const DEFAULT_PORT = 3000;
|
|
21
25
|
const VERSION = require("../package.json").version;
|
|
26
|
+
const UI_URL = `http://localhost:${DEFAULT_PORT}`;
|
|
27
|
+
|
|
28
|
+
const MANIFEST_FILE = flags.manifest || path.join(process.cwd(), "systemview.manifest.json");
|
|
29
|
+
const connectedUrls = new Set();
|
|
30
|
+
|
|
31
|
+
function loadManifest() {
|
|
32
|
+
if (!fs.existsSync(MANIFEST_FILE)) return;
|
|
33
|
+
try {
|
|
34
|
+
const manifest = JSON.parse(fs.readFileSync(MANIFEST_FILE, "utf8"));
|
|
35
|
+
const services = manifest.services || [manifest];
|
|
36
|
+
for (const { system } of services) {
|
|
37
|
+
if (system && system.connectionData) {
|
|
38
|
+
Client.createService(system.connectionData);
|
|
39
|
+
connectedUrls.add(system.connectionData.serviceUrl);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
} catch {}
|
|
43
|
+
}
|
|
22
44
|
|
|
23
45
|
async function startApp() {
|
|
24
46
|
const port = isNaN(input[1]) ? DEFAULT_PORT : Number(input[1]);
|
|
25
47
|
try {
|
|
26
|
-
await launchApp(port, { interactive: true });
|
|
48
|
+
await launchApp(port, { interactive: true, connectedUrls });
|
|
27
49
|
} catch (error) {
|
|
28
50
|
log.error("Launch failed: " + error.message);
|
|
29
51
|
}
|
|
@@ -32,13 +54,11 @@ async function startApp() {
|
|
|
32
54
|
async function startTest() {
|
|
33
55
|
const project_code = input[1];
|
|
34
56
|
const namespace = input[2];
|
|
35
|
-
const url = `http://localhost:${DEFAULT_PORT}`;
|
|
36
57
|
try {
|
|
37
58
|
await launchApp(DEFAULT_PORT);
|
|
38
|
-
const exitCode = await runTests(
|
|
59
|
+
const exitCode = await runTests(UI_URL, project_code, namespace, {
|
|
39
60
|
json: flags.json,
|
|
40
61
|
verbose: flags.verbose,
|
|
41
|
-
manifest: flags.manifest,
|
|
42
62
|
headers: flags.headers,
|
|
43
63
|
bail: flags.bail,
|
|
44
64
|
dryRun: flags.dryRun,
|
|
@@ -56,41 +76,34 @@ async function startTest() {
|
|
|
56
76
|
async function list() {
|
|
57
77
|
const project_code = input[1];
|
|
58
78
|
const namespace = input[2];
|
|
59
|
-
const
|
|
60
|
-
const api = `${url}/systemview/api`;
|
|
79
|
+
const api = `${UI_URL}/systemview/api`;
|
|
61
80
|
if (!(await appIsRunning(api))) {
|
|
62
81
|
await launchApp(DEFAULT_PORT);
|
|
63
82
|
}
|
|
64
|
-
await listTests(
|
|
83
|
+
await listTests(UI_URL, project_code, namespace, {
|
|
84
|
+
connectedUrls,
|
|
85
|
+
verbose: flags.verbose,
|
|
86
|
+
});
|
|
65
87
|
process.exit(0);
|
|
66
88
|
}
|
|
67
89
|
|
|
68
90
|
async function open() {
|
|
69
91
|
const project_code = input[1];
|
|
70
92
|
const namespace = input[2];
|
|
71
|
-
const
|
|
72
|
-
const api = `${ui}/systemview/api`;
|
|
93
|
+
const api = `${UI_URL}/systemview/api`;
|
|
73
94
|
if (!(await appIsRunning(api))) {
|
|
74
95
|
await launchApp(DEFAULT_PORT);
|
|
75
96
|
}
|
|
76
97
|
|
|
77
98
|
let connectedServices = [];
|
|
78
99
|
if (namespace && project_code) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
connectedServices = raw.services ? raw.services : [raw];
|
|
84
|
-
} catch {}
|
|
85
|
-
} else {
|
|
86
|
-
try {
|
|
87
|
-
const { SystemView } = await createCookieClient().loadService(api);
|
|
88
|
-
connectedServices = (await SystemView.getServices(project_code)) || [];
|
|
89
|
-
} catch {}
|
|
90
|
-
}
|
|
100
|
+
try {
|
|
101
|
+
const { SystemView } = await Client.loadService(api);
|
|
102
|
+
connectedServices = (await SystemView.getServices(project_code)) || [];
|
|
103
|
+
} catch {}
|
|
91
104
|
}
|
|
92
105
|
|
|
93
|
-
openBrowser(
|
|
106
|
+
openBrowser(UI_URL, project_code, namespace, connectedServices);
|
|
94
107
|
process.exit(0);
|
|
95
108
|
}
|
|
96
109
|
|
|
@@ -121,13 +134,17 @@ async function quitApp() {
|
|
|
121
134
|
}
|
|
122
135
|
|
|
123
136
|
(async () => {
|
|
137
|
+
if (process.argv.includes("--version") || process.argv.includes("-v")) {
|
|
138
|
+
console.log(VERSION);
|
|
139
|
+
process.exit(0);
|
|
140
|
+
}
|
|
141
|
+
|
|
124
142
|
init();
|
|
143
|
+
loadManifest();
|
|
144
|
+
|
|
125
145
|
const command = input[0];
|
|
126
146
|
|
|
127
|
-
if (
|
|
128
|
-
console.log(VERSION);
|
|
129
|
-
process.exit(0);
|
|
130
|
-
} else if (command === "open") {
|
|
147
|
+
if (command === "open") {
|
|
131
148
|
await open();
|
|
132
149
|
} else if (command === "list") {
|
|
133
150
|
await list();
|
|
@@ -138,15 +155,54 @@ async function quitApp() {
|
|
|
138
155
|
} else if (["exit", "q", "shutdown", "stop"].includes(command)) {
|
|
139
156
|
await quitApp();
|
|
140
157
|
} else if (command === "connect") {
|
|
141
|
-
|
|
158
|
+
const useManifest = process.argv.includes("--manifest");
|
|
159
|
+
await connectService(input[1], {
|
|
160
|
+
useManifest,
|
|
161
|
+
force: flags.force,
|
|
162
|
+
connectedUrls,
|
|
163
|
+
uiUrl: UI_URL,
|
|
164
|
+
});
|
|
165
|
+
process.exit(0);
|
|
166
|
+
} else if (command === "disconnect") {
|
|
167
|
+
await manifestCommands.disconnect(input[1], input[2], {
|
|
168
|
+
connectedUrls,
|
|
169
|
+
uiUrl: UI_URL,
|
|
170
|
+
});
|
|
171
|
+
process.exit(0);
|
|
172
|
+
} else if (command === "manifest") {
|
|
173
|
+
const sub = input[1];
|
|
174
|
+
if (sub === "save") {
|
|
175
|
+
log.warn("manifest save requires an interactive session. Run: systemview start");
|
|
176
|
+
} else if (sub === "clean") {
|
|
177
|
+
await manifestCommands.clean(MANIFEST_FILE);
|
|
178
|
+
} else {
|
|
179
|
+
log.warn("Usage: systemview manifest <save|clean>");
|
|
180
|
+
}
|
|
142
181
|
process.exit(0);
|
|
143
182
|
} else if (command === "probe") {
|
|
183
|
+
await launchApp(DEFAULT_PORT);
|
|
144
184
|
const exitCode = await probe(input[1], input[2], {
|
|
145
185
|
json: flags.json,
|
|
146
186
|
manifest: flags.manifest,
|
|
147
187
|
headers: flags.headers,
|
|
188
|
+
uiUrl: UI_URL,
|
|
148
189
|
});
|
|
149
190
|
process.exit(exitCode || 0);
|
|
191
|
+
} else if (command === "logs") {
|
|
192
|
+
await launchApp(DEFAULT_PORT);
|
|
193
|
+
await logsCommand(input[1], input[2], {
|
|
194
|
+
uiUrl: UI_URL,
|
|
195
|
+
level: flags.level,
|
|
196
|
+
limit: flags.limit,
|
|
197
|
+
clear: flags.clear,
|
|
198
|
+
json: flags.json,
|
|
199
|
+
current: flags.current,
|
|
200
|
+
verbose: flags.verbose,
|
|
201
|
+
filter: flags.filter,
|
|
202
|
+
or: flags.or,
|
|
203
|
+
include: flags.include,
|
|
204
|
+
});
|
|
205
|
+
process.exit(0);
|
|
150
206
|
} else {
|
|
151
207
|
await startApp();
|
|
152
208
|
}
|
package/cli/launchApp.js
CHANGED
|
@@ -3,7 +3,7 @@ const appIsRunning = require("./appIsRunning");
|
|
|
3
3
|
const launchSystemView = require("../api");
|
|
4
4
|
const startLineReader = require("./startLineReader");
|
|
5
5
|
|
|
6
|
-
module.exports = async function launchApp(port, { interactive = false } = {}) {
|
|
6
|
+
module.exports = async function launchApp(port, { interactive = false, connectedUrls = new Set() } = {}) {
|
|
7
7
|
const ui = `http://localhost:${port}`;
|
|
8
8
|
const api = `${ui}/systemview/api`;
|
|
9
9
|
|
|
@@ -15,17 +15,18 @@ module.exports = async function launchApp(port, { interactive = false } = {}) {
|
|
|
15
15
|
|
|
16
16
|
if (await appIsRunning(api)) {
|
|
17
17
|
if (interactive) {
|
|
18
|
-
log.info(
|
|
18
|
+
log.info(`SystemView already running on port ${port} — attaching.`);
|
|
19
19
|
logConnection();
|
|
20
|
+
return startLineReader(ui, { connectedUrls });
|
|
20
21
|
}
|
|
21
22
|
return;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
if (interactive) log.info(
|
|
25
|
+
if (interactive) log.info(`Launching on port ${port}...`);
|
|
25
26
|
await launchSystemView(port);
|
|
26
27
|
logConnection();
|
|
27
28
|
|
|
28
29
|
if (interactive) {
|
|
29
|
-
return startLineReader(ui);
|
|
30
|
+
return startLineReader(ui, { connectedUrls });
|
|
30
31
|
}
|
|
31
32
|
};
|
package/cli/listTests.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
const { createCookieClient } = require("./cookieClient");
|
|
1
|
+
const { createClient } = require("systemlynx");
|
|
2
|
+
const { createCookieHttpClient } = require("./cookieClient");
|
|
4
3
|
const log = require("./logger");
|
|
5
4
|
const chalk = require("chalk");
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
const cookieHttpClient = createCookieHttpClient();
|
|
7
|
+
const Client = createClient(cookieHttpClient);
|
|
8
|
+
|
|
9
|
+
module.exports = async function listTests(url, project_code, namespace, { connectedUrls = new Set(), verbose = false } = {}) {
|
|
8
10
|
const api = `${url}/systemview/api`;
|
|
9
|
-
const Client = createCookieClient();
|
|
10
11
|
|
|
11
12
|
if (!project_code) {
|
|
12
|
-
await listAllProjects(api, Client, verbose);
|
|
13
|
+
await listAllProjects(api, Client, verbose, connectedUrls);
|
|
13
14
|
return;
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
const connectedServices = await loadServices(api, project_code,
|
|
17
|
+
const connectedServices = await loadServices(api, project_code, Client);
|
|
17
18
|
if (!connectedServices.length) {
|
|
18
19
|
log.warn("No connected services found for project: " + project_code);
|
|
19
20
|
return;
|
|
@@ -30,7 +31,7 @@ module.exports = async function listTests(url, project_code, namespace, { manife
|
|
|
30
31
|
|
|
31
32
|
let testList = [];
|
|
32
33
|
try {
|
|
33
|
-
const svc =
|
|
34
|
+
const svc = Client.createService(system.connectionData);
|
|
34
35
|
testList = await svc.Plugin.getTests();
|
|
35
36
|
} catch {
|
|
36
37
|
console.log(`${servicePrefix}${chalk.dim(serviceId)} ${chalk.dim("(could not load tests)")}`);
|
|
@@ -93,7 +94,7 @@ module.exports = async function listTests(url, project_code, namespace, { manife
|
|
|
93
94
|
console.log("");
|
|
94
95
|
};
|
|
95
96
|
|
|
96
|
-
async function listAllProjects(api, Client, verbose = false) {
|
|
97
|
+
async function listAllProjects(api, Client, verbose = false, connectedUrls = new Set()) {
|
|
97
98
|
let projects;
|
|
98
99
|
try {
|
|
99
100
|
const { SystemView } = await Client.loadService(api);
|
|
@@ -120,9 +121,11 @@ async function listAllProjects(api, Client, verbose = false) {
|
|
|
120
121
|
const isLastService = si === services.length - 1;
|
|
121
122
|
const servicePrefix = isLastService ? " └── " : " ├── ";
|
|
122
123
|
const childPad = isLastService ? " " : " │ ";
|
|
124
|
+
const connected = connectedUrls.has(serviceUrl);
|
|
125
|
+
const connectedMark = connected ? chalk.green(" ●") : chalk.dim(" ○");
|
|
123
126
|
|
|
124
127
|
if (verbose && connectionData && connectionData.modules) {
|
|
125
|
-
console.log(`${servicePrefix}${chalk.bold(serviceId)} ${chalk.dim(serviceUrl)}`);
|
|
128
|
+
console.log(`${servicePrefix}${chalk.bold(serviceId)}${connectedMark} ${chalk.dim(serviceUrl)}`);
|
|
126
129
|
const mods = connectionData.modules.filter((m) => m.name !== "Plugin");
|
|
127
130
|
mods.forEach((mod, mi) => {
|
|
128
131
|
const isLastMod = mi === mods.length - 1;
|
|
@@ -137,7 +140,7 @@ async function listAllProjects(api, Client, verbose = false) {
|
|
|
137
140
|
});
|
|
138
141
|
});
|
|
139
142
|
} else {
|
|
140
|
-
console.log(`${servicePrefix}${serviceId} ${chalk.dim(serviceUrl)}`);
|
|
143
|
+
console.log(`${servicePrefix}${serviceId}${connectedMark} ${chalk.dim(serviceUrl)}`);
|
|
141
144
|
}
|
|
142
145
|
});
|
|
143
146
|
if (pi < codes.length - 1) console.log("");
|
|
@@ -145,14 +148,7 @@ async function listAllProjects(api, Client, verbose = false) {
|
|
|
145
148
|
console.log("");
|
|
146
149
|
}
|
|
147
150
|
|
|
148
|
-
async function loadServices(api, project_code,
|
|
149
|
-
const manifestFile = manifestPath || path.join(process.cwd(), "systemview.manifest.json");
|
|
150
|
-
if (fs.existsSync(manifestFile)) {
|
|
151
|
-
try {
|
|
152
|
-
const raw = JSON.parse(fs.readFileSync(manifestFile, "utf8"));
|
|
153
|
-
return raw.services ? raw.services : [raw];
|
|
154
|
-
} catch {}
|
|
155
|
-
}
|
|
151
|
+
async function loadServices(api, project_code, Client) {
|
|
156
152
|
try {
|
|
157
153
|
const { SystemView } = await Client.loadService(api);
|
|
158
154
|
return (await SystemView.getServices(project_code)) || [];
|