systemview 1.4.2 → 1.6.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.
@@ -0,0 +1,25 @@
1
+ const http = require("http");
2
+
3
+ module.exports = async function appIsRunning(appUrls) {
4
+ let allAppsRunning = true;
5
+ const pingApps = appUrls.map(
6
+ (url) =>
7
+ new Promise((resolve, reject) => {
8
+ http.get(url, resolve).on("error", reject);
9
+ })
10
+ );
11
+ try {
12
+ const responses = await Promise.all(pingApps);
13
+ responses.forEach((res, index) => {
14
+ if (res.statusCode !== 200) {
15
+ allAppsRunning = false;
16
+ console.log(`App ${index + 1} is not running`);
17
+ }
18
+ });
19
+ } catch (err) {
20
+ console.error("Error pinging apps:", err.message);
21
+ allAppsRunning = false;
22
+ }
23
+
24
+ return allAppsRunning;
25
+ };
package/cli/index.js CHANGED
@@ -10,58 +10,26 @@
10
10
  const init = require("./utils/init");
11
11
  const cli = require("./utils/cli");
12
12
  const log = require("./utils/log");
13
- const { spawn } = require("child_process");
14
- const path = require("path");
15
13
 
16
- const parentDirectory = path.resolve(__dirname, "..");
14
+ const launchApp = require("./launchApp");
15
+ const startLineReader = require("./startLineReader");
16
+ const runTests = require("./runTests");
17
17
 
18
18
  const input = cli.input;
19
19
  const flags = cli.flags;
20
20
  const { clear, debug } = flags;
21
21
 
22
- function startApp() {
23
- // Start React app
24
- const arg = parseInt();
25
- const port = isNaN(arg) ? 3000 : arg;
26
- const env = Object.create(process.env);
27
- env.PORT = port;
28
- log(`Launching SystemView UI @http://localhost:${port}/`);
29
- const AppProcess = spawn("npm", ["start"], {
30
- stdio: ["inherit"],
31
- shell: true,
32
- env,
33
- cwd: parentDirectory,
34
- });
35
-
36
- AppProcess.on("close", (code) => {
37
- console.log(`React app exited with code ${code}`);
38
- });
39
- }
40
-
41
- function startApi() {
42
- log(`Launching SystemView API @http://localhost:${3300}/systemview/api`);
43
-
44
- const AppProcess = spawn("node", ["api"], {
45
- stdio: ["inherit"],
46
- shell: true,
47
- cwd: parentDirectory,
48
- });
49
-
50
- AppProcess.on("close", (code) => {
51
- console.log(`React app exited with code ${code}`);
52
- });
53
- }
54
22
  (async () => {
55
23
  init({ clear });
56
24
  if (input.includes(`help`)) {
57
25
  cli.showHelp(0);
58
- }
59
- if (input[0] === "start") {
60
- startApi();
61
- startApp();
62
26
  } else if (input.includes("test")) {
63
- // Run tests
27
+ if (await launchApp()) await runTests(input[1]);
28
+ } else {
29
+ const shutdown = await launchApp();
30
+ if (typeof shutdown === "function") startLineReader(shutdown);
64
31
  }
65
32
 
33
+ cli.input = [];
66
34
  debug && log(flags);
67
35
  })();
package/cli/launchApp.js CHANGED
@@ -0,0 +1,48 @@
1
+ const log = require("./utils/log");
2
+ const { spawn } = require("child_process");
3
+ const path = require("path");
4
+ const appIsRunning = require("./appIsRunning");
5
+ const parentDirectory = path.resolve(__dirname, "..");
6
+ const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
7
+
8
+ function logConnection(api, app) {
9
+ log("connected!", "success");
10
+ console.log(`SystemView API running @${api}`);
11
+ console.log(`SystemView UI running @${app}`);
12
+ }
13
+ module.exports = async function launchApp(_port) {
14
+ const port = isNaN(_port) ? 3000 : _port;
15
+ const env = Object.create(process.env);
16
+ const api = `http://localhost:${3300}/systemview/api`;
17
+ const app = `http://localhost:${port}/`;
18
+ env.PORT = port;
19
+
20
+ if (await appIsRunning([api, app])) {
21
+ log("SystemView is running from another terminal", "info", "info");
22
+ logConnection(api, app);
23
+ return true;
24
+ } else {
25
+ log("Launching...");
26
+
27
+ const appProcess = spawn("node", ["api & node server"], {
28
+ stdio: ["inherit"],
29
+ shell: true,
30
+ env,
31
+ cwd: parentDirectory,
32
+ });
33
+
34
+ appProcess.on("close", (code) => {
35
+ console.log(`SystemView APP exited with code ${code}`);
36
+ });
37
+ const shutdown = () => {
38
+ if (appProcess) appProcess.kill();
39
+ };
40
+
41
+ await delay(2000);
42
+ const isRunning = await appIsRunning([api, app]);
43
+ if (isRunning) {
44
+ logConnection(api, app);
45
+ return shutdown;
46
+ }
47
+ }
48
+ };
@@ -0,0 +1,99 @@
1
+ const { Client } = require("systemlynx");
2
+ const { initializeSavedTests } = require("../testing-utilities/transformTests");
3
+ const FullTestController = require("../testing-utilities/FullTestController");
4
+ const log = require("./utils/log");
5
+ const validationMessages = require("../testing-utilities/validtionMessages");
6
+ module.exports = async function runTests(project_code) {
7
+ if (!project_code) {
8
+ return log("project_code or service_url are required", "warning", "warning");
9
+ }
10
+ // get connected services from the systemview api
11
+ const connectedServices = await getConnectedServices(project_code);
12
+ //get all the test for each service or the targeted services
13
+ if (!connectedServices.length) {
14
+ return log("No connected services found!", "warning");
15
+ } else {
16
+ connectedServices.forEach(({ serviceId, system }) => {
17
+ log(`connected @${system.connectionData.serviceUrl}`, "success", serviceId);
18
+ });
19
+ }
20
+
21
+ const Tests = await getTests(connectedServices);
22
+ //transform the test from the saved format to the testing format
23
+
24
+ const executeTest = async (savedTests) => {
25
+ const tests = initializeSavedTests(savedTests, connectedServices);
26
+ await runAllTests(tests);
27
+ };
28
+ (
29
+ await new Promise((resolve) => {
30
+ async function recursiveExecuteTest(i = 0) {
31
+ const { serviceId } = connectedServices[i];
32
+ log(`Initializing Tests...`, "info", serviceId);
33
+ if (i === Tests.length) resolve();
34
+ else executeTest(Tests[0]).then(() => recursiveExecuteTest(i + 1));
35
+ }
36
+ recursiveExecuteTest();
37
+ })
38
+ )();
39
+ };
40
+ const Logger = function (trackTime) {
41
+ this.start = (test) => {
42
+ if (trackTime) {
43
+ }
44
+ };
45
+
46
+ this.end = ({ errors }) => {
47
+ errors.forEach((err) => {
48
+ const msg = validationMessages(err);
49
+ log(msg, "error", err.namespace);
50
+ });
51
+ };
52
+ };
53
+ const { runFullTest } = new FullTestController();
54
+ const runAllTests = async (savedTest) => {
55
+ const runTest = async ({ Before, Main, Events, After }) => {
56
+ const fullTest = [Before, Main, Events, After];
57
+ const [B, M, E, A] = await runFullTest(fullTest, new Logger());
58
+ const { title, namespace } = Main[0];
59
+ return { Before: B, Main: M, Events: E, After: A, title, namespace };
60
+ };
61
+
62
+ await new Promise((resolve) => {
63
+ function recursiveRunTest(i = 0) {
64
+ if (i === savedTest.length) resolve();
65
+ else runTest(savedTest[i]).then(() => recursiveRunTest(i + 1));
66
+ }
67
+ recursiveRunTest();
68
+ });
69
+ };
70
+ async function getTests(connectedServices) {
71
+ return await new Promise(async (resolve) => {
72
+ const results = [];
73
+
74
+ return (async function recursiveGetTests(i = 0) {
75
+ if (i < connectedServices.length) {
76
+ const { connectionData } = connectedServices[1].system;
77
+ try {
78
+ results.push(await Client.createService(connectionData).Plugin.getTests());
79
+ } catch (error) {
80
+ console.log(`Failed to retrieve test from:${connectionData.serviceUrl}`);
81
+ }
82
+
83
+ await recursiveGetTests(i + 1);
84
+ } else resolve(results);
85
+ })();
86
+ });
87
+ }
88
+ async function getConnectedServices(project_code) {
89
+ try {
90
+ const { SystemView } = await Client.loadService(
91
+ "http://localhost:3300/systemview/api"
92
+ );
93
+ try {
94
+ return SystemView.getServices(project_code);
95
+ } catch (error) {}
96
+ } catch (error) {
97
+ console.log("Failed to connect to systemview");
98
+ }
99
+ }
@@ -0,0 +1,27 @@
1
+ const runTests = require("./runTests");
2
+ const cli = require("./utils/cli");
3
+
4
+ const readline = require("readline");
5
+
6
+ module.exports = function startLineReader(shutdown) {
7
+ const lineReader = readline.createInterface({
8
+ input: process.stdin,
9
+ output: process.stdout,
10
+ });
11
+ const handleInput = (input = "") => {
12
+ const [command, argument] = input.split(" ").map((s) => s.trim());
13
+ if (["exit", "q"].includes(command)) {
14
+ shutdown();
15
+ lineReader.close();
16
+ } else if (command === "test") {
17
+ runTests(argument);
18
+ } else if (command === "help") {
19
+ cli.showHelp(0);
20
+ }
21
+ lineReader.prompt();
22
+ };
23
+
24
+ lineReader.prompt();
25
+ lineReader.on("line", handleInput);
26
+ lineReader.on("close", shutdown);
27
+ };
package/cli/utils/log.js CHANGED
@@ -1,11 +1,5 @@
1
1
  const alert = require("cli-alerts");
2
2
 
3
- module.exports = (info) => {
4
- alert({
5
- type: `info`,
6
- name: `SystemView`,
7
- msg: ``,
8
- });
9
-
10
- console.log(info);
3
+ module.exports = (msg, type = "info", name = "SystemView") => {
4
+ alert({ type, name, msg });
11
5
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "systemview",
3
3
  "description": "A documentation and testing suite for SystemLynx",
4
- "version": "1.4.2",
4
+ "version": "1.6.2",
5
5
  "license": "UNLICENSED",
6
6
  "bin": {
7
7
  "systemview": "cli/index.js"
@@ -28,6 +28,7 @@
28
28
  "react-router-dom": "^5.2.0",
29
29
  "react-scripts": "^4.0.0",
30
30
  "react-syntax-highlighter": "^15.5.0",
31
+ "readline": "^1.3.0",
31
32
  "remark-gfm": "^3.0.1",
32
33
  "systemlynx": "^1.8.3",
33
34
  "web-vitals": "^0.2.4"
@@ -81,7 +82,6 @@
81
82
  "files": [
82
83
  "cli/",
83
84
  "api/",
84
- "plugin/",
85
85
  "build/",
86
86
  "server.js"
87
87
  ]
package/cli/runTest.js DELETED
File without changes
@@ -1,97 +0,0 @@
1
- const fs = require("fs");
2
- const getAllTests = require("./getAllTest");
3
-
4
- module.exports = (specs, projectCode, serviceId, helperMethods = {}) => {
5
- specs = specs.substr(-1) === "/" ? specs.substr(0, specs.length - 1) : specs;
6
-
7
- return function SystemViewPlugin() {
8
- const { SystemView } = this.useService("SystemView");
9
- Object.assign(this, helperMethods);
10
-
11
- this.saveDoc = ({ documentation, namespace }) => {
12
- const fileName = `${specs}/docs/${getName(namespace)}.md`;
13
- ensureDir(`${specs}/docs/`);
14
- if (documentation) {
15
- fs.writeFileSync(fileName, documentation, "utf8");
16
- } else {
17
- deleteFile(fileName);
18
- }
19
- SystemView.updateSpecList(this.getSpecList(), projectCode, serviceId);
20
- return { documentation, namespace };
21
- };
22
-
23
- this.getDoc = (namespace) => {
24
- const fileName = `${specs}/docs/${getName(namespace)}.md`;
25
- const documentation = getFile(fileName) || "";
26
- return { namespace, documentation };
27
- };
28
-
29
- this.getTests = (namespace = {}) => {
30
- const { moduleName, methodName } = namespace;
31
- if (methodName) {
32
- const fileName = `${specs}/tests/${moduleName}.${methodName}.json`;
33
- const tests = JSON.parse(getFile(fileName) || "[]");
34
- return tests;
35
- } else if (moduleName) {
36
- return getAllTests(`${specs}/tests/`, moduleName);
37
- } else {
38
- return getAllTests(`${specs}/tests/`);
39
- }
40
- };
41
- this.saveTest = (test, index) => {
42
- const fileName = `${specs}/tests/${getName(test.namespace)}.json`;
43
- const tests = JSON.parse(getFile(fileName) || "[]");
44
- if (typeof index === "number") {
45
- tests[index] = test;
46
- } else {
47
- tests.push(test);
48
- }
49
- fs.writeFileSync(fileName, JSON.stringify(tests), "utf8");
50
- SystemView.updateSpecList(this.getSpecList(), projectCode, serviceId);
51
- return index || tests.length - 1;
52
- };
53
- this.deleteTest = (namespace, index) => {
54
- const fileName = `${specs}/tests/${getName(namespace)}.json`;
55
- const tests = JSON.parse(getFile(fileName) || "[]");
56
- tests.splice(index, 1);
57
- console.log(tests.length);
58
- if (tests.length) {
59
- fs.writeFileSync(fileName, JSON.stringify(tests), "utf8");
60
- } else {
61
- deleteFile(fileName);
62
- SystemView.updateSpecList(this.getSpecList(), projectCode, serviceId);
63
- }
64
- };
65
- this.getSpecList = () => ({
66
- docs: fs.readdirSync(`${specs}/docs/`),
67
- tests: fs.readdirSync(`${specs}/tests/`),
68
- });
69
- };
70
-
71
- function deleteFile(fileName) {
72
- try {
73
- console.log(fileName);
74
- fs.unlinkSync(fileName);
75
- } catch (err) {
76
- // console.error(err);
77
- }
78
- }
79
- function getFile(fileName) {
80
- try {
81
- return fs.readFileSync(fileName, "utf8");
82
- } catch (error) {
83
- // console.log(error);
84
- }
85
- }
86
- function ensureDir(dir) {
87
- if (!fs.existsSync(dir)) {
88
- fs.mkdirSync(dir, { recursive: true });
89
- }
90
- }
91
-
92
- function getName({ serviceId, moduleName, methodName }) {
93
- if (methodName) return `${moduleName}.${methodName}`;
94
- else if (moduleName) return moduleName;
95
- else if (serviceId) return serviceId;
96
- }
97
- };
@@ -1,21 +0,0 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
-
4
- module.exports = function getFilesByNamespace(folder, namespace) {
5
- const files = fs.readdirSync(folder); // read the contents of the current directory
6
- const namespacePattern = namespace
7
- ? new RegExp(`^${namespace}\\..+\\.json$`)
8
- : /\.json$/;
9
-
10
- return files
11
- .filter((file) => namespacePattern.test(file))
12
- .reduce((sum, file) => {
13
- const filePath = path.join(folder, file);
14
- const fileContents = fs.readFileSync(filePath, "utf-8");
15
- const parsedData = JSON.parse(fileContents);
16
-
17
- return sum.concat(parsedData);
18
- }, []);
19
- };
20
-
21
- // no namespace passed, return all files
package/plugin/index.js DELETED
@@ -1,40 +0,0 @@
1
- const SystemViewModule = require("./SystemViewModule");
2
- const fs = require("fs");
3
-
4
- function ensureDir(dir) {
5
- if (!fs.existsSync(dir)) {
6
- fs.mkdirSync(dir, { recursive: true });
7
- }
8
- }
9
-
10
- const getSpecList = (specs) => {
11
- ensureDir(`${specs}/docs/`);
12
- ensureDir(`${specs}/tests/`);
13
- return {
14
- docs: fs.readdirSync(`${specs}/docs/`),
15
- tests: fs.readdirSync(`${specs}/tests/`),
16
- };
17
- };
18
- module.exports = function ({
19
- connection = "http://localhost:3300/systemview/api",
20
- specs = "./specs",
21
- projectCode,
22
- serviceId,
23
- helperMethods,
24
- }) {
25
- return function (App) {
26
- App.loadService("SystemView", connection)
27
- .module("Plugin", SystemViewModule(specs, projectCode, serviceId, helperMethods))
28
- .on("ready", async function connectSystemView(system) {
29
- try {
30
- const { SystemView } = this.useService("SystemView");
31
- const specList = getSpecList(specs);
32
- console.log("reconnection");
33
- await SystemView.connect({ system, projectCode, serviceId, specList });
34
- // SystemView.on("reconnect", connectSystemView.bind(this, system));
35
- } catch (error) {
36
- console.log("SystemView connection failed---->", error);
37
- }
38
- });
39
- };
40
- };