@kumologica/sdk 3.0.0-alpha4
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 +52 -0
- package/bin/kl.js +2 -0
- package/cli/KumologicaError.js +17 -0
- package/cli/cli.js +7 -0
- package/cli/commands/build-commands/aws.js +49 -0
- package/cli/commands/build-commands/azure.js +43 -0
- package/cli/commands/build-commands/kumohub.js +49 -0
- package/cli/commands/build.js +6 -0
- package/cli/commands/create-commands/create-project-iteratively.js +49 -0
- package/cli/commands/create-commands/index.js +5 -0
- package/cli/commands/create.js +66 -0
- package/cli/commands/deploy-commands/kumohub.js +114 -0
- package/cli/commands/deploy.js +6 -0
- package/cli/commands/doc-commands/html.js +60 -0
- package/cli/commands/doc.js +6 -0
- package/cli/commands/export-commands/cloudformation.js +371 -0
- package/cli/commands/export-commands/serverless.js +164 -0
- package/cli/commands/export-commands/terraform-commands/aws.js +193 -0
- package/cli/commands/export-commands/terraform-commands/azure.js +148 -0
- package/cli/commands/export-commands/terraform.js +6 -0
- package/cli/commands/export-commands/utils/validator.js +195 -0
- package/cli/commands/export.js +6 -0
- package/cli/commands/list-templates.js +24 -0
- package/cli/commands/open.js +53 -0
- package/cli/commands/start.js +165 -0
- package/cli/commands/test/TestSuiteRunner.js +76 -0
- package/cli/commands/test.js +123 -0
- package/cli/utils/download-template-from-repo.js +346 -0
- package/cli/utils/download-test.js +12 -0
- package/cli/utils/download.js +119 -0
- package/cli/utils/fs/copy-dir-contents-sync.js +15 -0
- package/cli/utils/fs/create-zip-file.js +39 -0
- package/cli/utils/fs/dir-exists-sync.js +14 -0
- package/cli/utils/fs/dir-exists.js +17 -0
- package/cli/utils/fs/file-exists-sync.js +14 -0
- package/cli/utils/fs/file-exists.js +12 -0
- package/cli/utils/fs/get-tmp-dir-path.js +22 -0
- package/cli/utils/fs/parse.js +40 -0
- package/cli/utils/fs/read-file-sync.js +11 -0
- package/cli/utils/fs/read-file.js +10 -0
- package/cli/utils/fs/safe-move-file.js +58 -0
- package/cli/utils/fs/walk-dir-sync.js +34 -0
- package/cli/utils/fs/write-file-sync.js +31 -0
- package/cli/utils/fs/write-file.js +32 -0
- package/cli/utils/logger.js +26 -0
- package/cli/utils/rename-service.js +49 -0
- package/package.json +72 -0
- package/src/api/core/comms.js +141 -0
- package/src/api/core/context.js +296 -0
- package/src/api/core/flows.js +286 -0
- package/src/api/core/index.js +29 -0
- package/src/api/core/library.js +106 -0
- package/src/api/core/nodes.js +476 -0
- package/src/api/core/projects.js +426 -0
- package/src/api/core/rest/context.js +42 -0
- package/src/api/core/rest/flow.js +53 -0
- package/src/api/core/rest/flows.js +53 -0
- package/src/api/core/rest/index.js +171 -0
- package/src/api/core/rest/nodes.js +164 -0
- package/src/api/core/rest/util.js +53 -0
- package/src/api/core/settings.js +287 -0
- package/src/api/tools/base/DesignerTool.js +108 -0
- package/src/api/tools/core/flow.js +58 -0
- package/src/api/tools/core/index.js +18 -0
- package/src/api/tools/core/node.js +77 -0
- package/src/api/tools/debugger/index.js +193 -0
- package/src/api/tools/filemanager/index.js +127 -0
- package/src/api/tools/git/index.js +103 -0
- package/src/api/tools/index.js +13 -0
- package/src/api/tools/test/index.js +56 -0
- package/src/api/tools/test/lib/TestCaseRunner.js +105 -0
- package/src/api/tools/test/lib/fixtures/example3-flow.json +148 -0
- package/src/api/tools/test/lib/fixtures/package.json +6 -0
- package/src/api/tools/test/lib/fixtures/s3-event.js +43 -0
- package/src/api/tools/test/lib/reporters/index.js +120 -0
- package/src/server/DesignerServer.js +141 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
|
|
2
|
+
class DesignerTool {
|
|
3
|
+
constructor(designServer) {
|
|
4
|
+
this.designServer = designServer;
|
|
5
|
+
this.adminApp = designServer.getAdminServer(); // TODO: remove
|
|
6
|
+
this.flowServer = designServer.getFlowServer();
|
|
7
|
+
|
|
8
|
+
this.runtimeEventEmitter = this.flowServer.events;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
getRuntimePlugin(pluginName) {
|
|
12
|
+
return this.flowServer.runtime.pluginRegistry.getPlugin(pluginName);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
isRuntimePluginInstalled(pluginName) {
|
|
16
|
+
return this.getRuntimePlugin(pluginName) ? true : false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// ================================
|
|
20
|
+
// WebSocket communication with SDK
|
|
21
|
+
// ================================
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* This method will be used by all the tools within the `install` method in order to register a websocket tool
|
|
25
|
+
* that will respond to each `eventType` request.
|
|
26
|
+
* @param {string} eventType
|
|
27
|
+
* @param {function(string): {type: string, payload?: object}} action
|
|
28
|
+
*/
|
|
29
|
+
addEventHandler(eventType, action) {
|
|
30
|
+
this.designServer.registerEvent(eventType, action);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Sends an event over WebSocket back to the client.
|
|
35
|
+
* If you use this method instead of sendResponse, ensure to follow the naming convention used for responses: `{eventType}:response`
|
|
36
|
+
* @param {WebSocket} ws - The WebSocket connection.
|
|
37
|
+
* @param {string} eventType - The type of event to send.
|
|
38
|
+
* @param {object} payload - The payload data to send with the event.
|
|
39
|
+
*/
|
|
40
|
+
sendEvent(ws, eventType, payload) {
|
|
41
|
+
let response = {
|
|
42
|
+
type: eventType,
|
|
43
|
+
payload
|
|
44
|
+
};
|
|
45
|
+
ws.send(JSON.stringify(response));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Sends a response event over WebSocket back to the client
|
|
50
|
+
* @param {WebSocket} ws - The WebSocket connection.
|
|
51
|
+
* @param {string} eventType - The type of event to send as a response.
|
|
52
|
+
* @param {object} payload - The payload data to send with the response.
|
|
53
|
+
*/
|
|
54
|
+
sendResponse(ws, eventType, payload) {
|
|
55
|
+
this.sendEvent(ws, `${eventType}:response`, payload);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Sends an error event over WebSocket back to the client
|
|
60
|
+
* @param {WebSocket} ws - The WebSocket connection.
|
|
61
|
+
* @param {string} eventType - The type of event to send as an error.
|
|
62
|
+
* @param {Error} err - The error object to send with the error event.
|
|
63
|
+
*/
|
|
64
|
+
sendError(ws, eventType, err) {
|
|
65
|
+
this.sendEvent(ws, `${eventType}:error`, { reason: err });
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// ================================
|
|
69
|
+
// Communication with Runtime
|
|
70
|
+
// ================================
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Use these two methods to subscribe to events emitted by a runtime plugin
|
|
74
|
+
* Remember that whenever you subscribe you will have to unsubscribe it when you are done
|
|
75
|
+
* otherwise, events will come duplicated.
|
|
76
|
+
*
|
|
77
|
+
* @param {*} listener
|
|
78
|
+
*/
|
|
79
|
+
subscribeRuntimeListener(listener) {
|
|
80
|
+
this.runtimeEventEmitter.on('runtime-event', listener);
|
|
81
|
+
}
|
|
82
|
+
clearRuntimeListener(listener) {
|
|
83
|
+
this.runtimeEventEmitter.off('runtime-event', listener);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Use this method to invoke a command to a runtime plugin.
|
|
88
|
+
* - Plugin must extends the class `Plugin`
|
|
89
|
+
* - Communication will be done direct call to the object
|
|
90
|
+
*
|
|
91
|
+
* @param {string} pluginName
|
|
92
|
+
* @param {string} command
|
|
93
|
+
* @param {*} params - optional
|
|
94
|
+
*/
|
|
95
|
+
sendCommandToPlugin(pluginName, command, params) {
|
|
96
|
+
let plugin = this.getRuntimePlugin(pluginName);
|
|
97
|
+
if (plugin) {
|
|
98
|
+
plugin.handleCommand(command, params);
|
|
99
|
+
} else {
|
|
100
|
+
throw new Error(`Plugin not found: ${pluginName}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
module.exports = {
|
|
107
|
+
DesignerTool
|
|
108
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const { DesignerTool } = require("../base/DesignerTool");
|
|
2
|
+
|
|
3
|
+
class CoreFlowTool extends DesignerTool {
|
|
4
|
+
constructor(designServer) {
|
|
5
|
+
super(designServer);
|
|
6
|
+
}
|
|
7
|
+
install() {
|
|
8
|
+
/**
|
|
9
|
+
* { type: 'test:run',
|
|
10
|
+
* payload: { testcaseid: '123432.34343'} }
|
|
11
|
+
*/
|
|
12
|
+
this.addEventHandler('flow:getFlow', this.getFlowAction('flow:getFlow'));
|
|
13
|
+
this.addEventHandler('flow:deployFlow', this.deployFlowAction('flow:deployFlow'));
|
|
14
|
+
this.addEventHandler('flow:reloadFlow', this.reloadFlowAction('flow:reloadFlow'));
|
|
15
|
+
|
|
16
|
+
}
|
|
17
|
+
getFlowAction(eventType) {
|
|
18
|
+
return async (ws, payload) => {
|
|
19
|
+
try {
|
|
20
|
+
let response = this.flowServer.runtime._.nodes.getFlows()
|
|
21
|
+
this.sendResponse(ws, eventType, response);
|
|
22
|
+
} catch (err) {
|
|
23
|
+
this.sendError(ws, eventType, err.message);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
deployFlowAction(eventType) {
|
|
29
|
+
return async (ws, payload) => {
|
|
30
|
+
try {
|
|
31
|
+
let response = this.flowServer.runtime._.nodes.setFlows(payload, 'full');
|
|
32
|
+
this.sendResponse(ws, eventType, {});
|
|
33
|
+
|
|
34
|
+
} catch (err) {
|
|
35
|
+
this.sendError(ws, eventType, err.message);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
reloadFlowAction(eventType) {
|
|
41
|
+
return async (ws, payload) => {
|
|
42
|
+
try {
|
|
43
|
+
let response = this.flowServer.runtime._.nodes.loadFlows(true);
|
|
44
|
+
this.sendResponse(ws, eventType, {});
|
|
45
|
+
|
|
46
|
+
} catch (err) {
|
|
47
|
+
this.sendError(ws, eventType, err.message);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
module.exports = {
|
|
57
|
+
CoreFlowTool
|
|
58
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const { DesignerTool } = require("../base/DesignerTool");
|
|
2
|
+
|
|
3
|
+
const { CoreFlowTool } = require('./flow');
|
|
4
|
+
const { CoreNodeTool } = require('./node');
|
|
5
|
+
|
|
6
|
+
class CoreTools extends DesignerTool {
|
|
7
|
+
constructor(designServer) {
|
|
8
|
+
super(designServer);
|
|
9
|
+
}
|
|
10
|
+
install() {
|
|
11
|
+
new CoreFlowTool(this.designServer).install();
|
|
12
|
+
new CoreNodeTool(this.designServer).install();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = {
|
|
17
|
+
CoreTools
|
|
18
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const { DesignerTool } = require("../base/DesignerTool");
|
|
2
|
+
|
|
3
|
+
class CoreNodeTool extends DesignerTool {
|
|
4
|
+
constructor(designServer) {
|
|
5
|
+
super(designServer);
|
|
6
|
+
}
|
|
7
|
+
install() {
|
|
8
|
+
/**
|
|
9
|
+
* { type: 'test:run',
|
|
10
|
+
* payload: { testcaseid: '123432.34343'} }
|
|
11
|
+
*/
|
|
12
|
+
this.addEventHandler('node:getAllNodes', this.getAllNodes('node:getAllNodes'));
|
|
13
|
+
this.addEventHandler('node:getAllInstalledTypes', this.getAllInstalledTypes('node:getAllInstalledTypes'));
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
* @param {*} eventType
|
|
19
|
+
* @returns
|
|
20
|
+
* {
|
|
21
|
+
"type": "node:getAllNodes:response",
|
|
22
|
+
"payload": [
|
|
23
|
+
{
|
|
24
|
+
"id": "kumologica-core/sftp",
|
|
25
|
+
"name": "sftp",
|
|
26
|
+
"types": [
|
|
27
|
+
"SFTP"
|
|
28
|
+
],
|
|
29
|
+
"enabled": true,
|
|
30
|
+
"local": false,
|
|
31
|
+
"module": "kumologica-core",
|
|
32
|
+
"version": "3.2.0-beta6"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"id": "kumologica-core/Rekognition",
|
|
36
|
+
"name": "Rekognition",
|
|
37
|
+
"types": [
|
|
38
|
+
"Rekognition"
|
|
39
|
+
],
|
|
40
|
+
"enabled": true,
|
|
41
|
+
"local": false,
|
|
42
|
+
"module": "kumologica-core",
|
|
43
|
+
"version": "3.2.0-beta6"
|
|
44
|
+
}, ... ]
|
|
45
|
+
*/
|
|
46
|
+
getAllNodes(eventType) {
|
|
47
|
+
return async (ws, payload) => {
|
|
48
|
+
try {
|
|
49
|
+
let response = this.flowServer.runtime._.nodes.getNodeList();
|
|
50
|
+
// console.log(this.flowServer.runtime._.nodes.getNodeConfigs());
|
|
51
|
+
// console.log(this.flowServer.runtime._.nodes.getNodeConfig('kumologica-core/sftp'));
|
|
52
|
+
this.sendResponse(ws, eventType, response);
|
|
53
|
+
} catch (err) {
|
|
54
|
+
this.sendError(ws, eventType, err.message);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
getAllInstalledTypes(eventType) {
|
|
61
|
+
return async (ws, payload) => {
|
|
62
|
+
try {
|
|
63
|
+
let response = this.flowServer.runtime._.nodes.getNodeConfigs();
|
|
64
|
+
this.sendResponse(ws, eventType, response);
|
|
65
|
+
} catch (err) {
|
|
66
|
+
this.sendError(ws, eventType, err.message);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
module.exports = {
|
|
75
|
+
CoreNodeTool
|
|
76
|
+
}
|
|
77
|
+
1
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
const { DesignerTool } = require('../base/DesignerTool');
|
|
2
|
+
const { TestCaseRunner, InMemoryReporter } = require('../test/lib/TestCaseRunner');
|
|
3
|
+
|
|
4
|
+
const DEBUGGER_PLUGIN = 'DebuggerPlugin';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* Commands:
|
|
9
|
+
* { type: 'debugger:start', payload: { testcaseid: '2343.3434', breakpoints: {'123.1231', '1231.123'}}
|
|
10
|
+
* { type: 'debugger:continue' }
|
|
11
|
+
* { type: 'debugger:next' }
|
|
12
|
+
* { type: 'debugger:terminate' }
|
|
13
|
+
*
|
|
14
|
+
* Events:
|
|
15
|
+
* { type: 'debugger:on:trace', payload: { step: 1, type: 'input|output|error', message: {...}, vars: {} }}
|
|
16
|
+
* { type: 'debugger:on:change-state', payload: { step: 2, from: 'running', to: 'paused'}}
|
|
17
|
+
* { type: 'debugger:on:event', { status: "startFlow" });
|
|
18
|
+
*
|
|
19
|
+
* Responses:
|
|
20
|
+
* { type: 'debugger:start:response', "payload": { "testCaseExecutionTimeInMs": 1.7501250505447388, "testCaseID": "e8fb91dc.46c24", "testCaseDescription": "TestCase HelloWorld", "assertions": [... ] } }
|
|
21
|
+
*/
|
|
22
|
+
class DebuggerTool extends DesignerTool {
|
|
23
|
+
constructor(designerServer) {
|
|
24
|
+
super(designerServer);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
install() {
|
|
28
|
+
this.addEventHandler('debugger:start', this.start('debugger:start'));
|
|
29
|
+
this.addEventHandler('debugger:next', this.next('debugger:next'));
|
|
30
|
+
this.addEventHandler('debugger:continue', this.continue('debugger:continue'));
|
|
31
|
+
this.addEventHandler('debugger:terminate', this.terminate('debugger:terminate'));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
start(eventType) {
|
|
36
|
+
return async (ws, payload) => {
|
|
37
|
+
const { testcaseid, breakpoints } = payload;
|
|
38
|
+
// runtime -> tool -> sdk
|
|
39
|
+
let debuggerListener = this.debuggerEventListener(ws);
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
if (!this.isRuntimePluginInstalled(DEBUGGER_PLUGIN)) {
|
|
43
|
+
throw new Error("DebuggerPlugin not installed");
|
|
44
|
+
}
|
|
45
|
+
let pluginCommands = this.getRuntimePlugin(DEBUGGER_PLUGIN).listCommands();
|
|
46
|
+
|
|
47
|
+
// Subscribe to debugger plugin events
|
|
48
|
+
this.subscribeRuntimeListener(debuggerListener);
|
|
49
|
+
|
|
50
|
+
// Send command to get ready the debugger plugin
|
|
51
|
+
this.sendCommandToPlugin(DEBUGGER_PLUGIN, pluginCommands.ENABLE, breakpoints);
|
|
52
|
+
|
|
53
|
+
// Execute the flow as a test
|
|
54
|
+
const reporter = new InMemoryReporter();
|
|
55
|
+
const runner = new TestCaseRunner(this.flowServer, testcaseid, [reporter]);
|
|
56
|
+
await runner.runAsync();
|
|
57
|
+
let response = {
|
|
58
|
+
testCaseExecutionTimeInMs: reporter.executionTimeInMs,
|
|
59
|
+
testCaseID: reporter.testCaseID,
|
|
60
|
+
testCaseDescription: reporter.testCaseDescription,
|
|
61
|
+
assertions: reporter.assertionResults
|
|
62
|
+
}
|
|
63
|
+
this.sendResponse(ws, eventType, response);
|
|
64
|
+
|
|
65
|
+
} catch (err) {
|
|
66
|
+
console.log(err);
|
|
67
|
+
this.sendError(ws, eventType, err.message);
|
|
68
|
+
} finally {
|
|
69
|
+
this.clearRuntimeListener(debuggerListener);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
next(eventType) {
|
|
76
|
+
return async (ws, payload) => {
|
|
77
|
+
try {
|
|
78
|
+
if (!this.isRuntimePluginInstalled(DEBUGGER_PLUGIN)) {
|
|
79
|
+
throw new Error("DebuggerPlugin not installed");
|
|
80
|
+
}
|
|
81
|
+
let pluginCommands = this.getRuntimePlugin(DEBUGGER_PLUGIN).listCommands();
|
|
82
|
+
// Send command to get ready the debugger plugin
|
|
83
|
+
this.sendCommandToPlugin(DEBUGGER_PLUGIN, pluginCommands.NEXT);
|
|
84
|
+
} catch (err) {
|
|
85
|
+
console.log(err);
|
|
86
|
+
this.sendError(ws, eventType, err.message);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
continue(eventType) {
|
|
92
|
+
return async (ws, payload) => {
|
|
93
|
+
try {
|
|
94
|
+
if (!this.isRuntimePluginInstalled(DEBUGGER_PLUGIN)) {
|
|
95
|
+
throw new Error("DebuggerPlugin not installed");
|
|
96
|
+
}
|
|
97
|
+
let pluginCommands = this.getRuntimePlugin(DEBUGGER_PLUGIN).listCommands();
|
|
98
|
+
// Send command to get ready the debugger plugin
|
|
99
|
+
this.sendCommandToPlugin(DEBUGGER_PLUGIN, pluginCommands.CONTINUE);
|
|
100
|
+
} catch (err) {
|
|
101
|
+
console.log(err);
|
|
102
|
+
this.sendError(ws, eventType, err.message);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
terminate(eventType) {
|
|
108
|
+
return async (ws, payload) => {
|
|
109
|
+
try {
|
|
110
|
+
if (!this.isRuntimePluginInstalled(DEBUGGER_PLUGIN)) {
|
|
111
|
+
throw new Error("DebuggerPlugin not installed");
|
|
112
|
+
}
|
|
113
|
+
let pluginCommands = this.getRuntimePlugin(DEBUGGER_PLUGIN).listCommands();
|
|
114
|
+
// Send command to get ready the debugger plugin
|
|
115
|
+
this.sendCommandToPlugin(DEBUGGER_PLUGIN, pluginCommands.TERMINATE);
|
|
116
|
+
} catch (err) {
|
|
117
|
+
console.log(err);
|
|
118
|
+
this.sendError(ws, eventType, err.message);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
debuggerEventListener(ws) {
|
|
124
|
+
return (event) => {
|
|
125
|
+
let payload = event.payload;
|
|
126
|
+
|
|
127
|
+
switch (event.id) {
|
|
128
|
+
case 'runtime-event://debuggerPlugin/startFlow':
|
|
129
|
+
this.sendEvent(ws, 'debugger:on:event', { status: "startFlow" });
|
|
130
|
+
break;
|
|
131
|
+
case 'runtime-event://debuggerPlugin/endFlow':
|
|
132
|
+
this.sendEvent(ws, 'debugger:on:event', { status: "endFlow" });
|
|
133
|
+
break;
|
|
134
|
+
case 'runtime-event://debuggerPlugin/errorFlow':
|
|
135
|
+
this.sendEvent(ws, 'debugger:on:event', { status: "errorFlow" });
|
|
136
|
+
break;
|
|
137
|
+
|
|
138
|
+
case 'runtime-event://debuggerPlugin/startNode':
|
|
139
|
+
case 'runtime-event://debuggerPlugin/endNode':
|
|
140
|
+
case 'runtime-event://debuggerPlugin/errorNode':
|
|
141
|
+
this.sendEvent(ws, 'debugger:on:trace', payload);
|
|
142
|
+
break;
|
|
143
|
+
|
|
144
|
+
case 'runtime-event://debuggerPlugin/changeState':
|
|
145
|
+
this.sendEvent(ws, 'debugger:on:change-state', payload);
|
|
146
|
+
break;
|
|
147
|
+
default:
|
|
148
|
+
// do nothing
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
// NOT NEEDED YET
|
|
155
|
+
// genNextUniqueId(node, testcaseid) {
|
|
156
|
+
// let uniqueExecutionNodeId;
|
|
157
|
+
// let id = node.id;
|
|
158
|
+
// // check if node.id has not yet injected with unique runtime id
|
|
159
|
+
// if (!id.includes('::')){
|
|
160
|
+
// uniqueExecutionNodeId = `${testcaseid}::${node.id}::0`;
|
|
161
|
+
// } else{
|
|
162
|
+
// // Replace the testcase id for current one, if still carries the old one
|
|
163
|
+
// let idTokenized = id.split('::');
|
|
164
|
+
// let prevTestCaseId = idTokenized[0];
|
|
165
|
+
// let prevNodeId = idTokenized[1];
|
|
166
|
+
// let prevExecutionId = idTokenized[2];
|
|
167
|
+
|
|
168
|
+
// if (prevTestCaseId !== testcaseid) {
|
|
169
|
+
// id = `${testcaseid}::${prevNodeId}::${prevExecutionId}`
|
|
170
|
+
// }
|
|
171
|
+
|
|
172
|
+
// // if it has iterate over the executionId (last part of the unique runtime id)
|
|
173
|
+
|
|
174
|
+
// let posExecId = id.lastIndexOf('::');
|
|
175
|
+
// let prefixId = id.substr(0, posExecId);
|
|
176
|
+
// let executionId = parseInt(id.substr(posExecId + 2));
|
|
177
|
+
|
|
178
|
+
// uniqueExecutionNodeId = `${prefixId}::${executionId}`;
|
|
179
|
+
// while (uniqueExecutionNodeId in this._cache) {
|
|
180
|
+
// executionId = executionId + 1;
|
|
181
|
+
// uniqueExecutionNodeId = `${prefixId}::${executionId}`;
|
|
182
|
+
// }
|
|
183
|
+
// }
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
// return uniqueExecutionNodeId;
|
|
187
|
+
// }
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
module.exports = {
|
|
192
|
+
DebuggerTool
|
|
193
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
const { DesignerTool } = require("../base/DesignerTool");
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* FileManagerTool
|
|
5
|
+
* A cloud designer tool responsible to facilitate the sync of files between the frontend and the local filesystem.
|
|
6
|
+
* This tool will support the following operations: rename, update, add and delete files.
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
class FileManagerTool extends DesignerTool {
|
|
10
|
+
constructor(designerServer) {
|
|
11
|
+
super(designerServer);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
install() {
|
|
15
|
+
/**
|
|
16
|
+
* { "type": "filemanager:pull" }
|
|
17
|
+
*/
|
|
18
|
+
this.addEventHandler('filemanager:pull', this.executePull('filemanager:pull'));
|
|
19
|
+
/**
|
|
20
|
+
* { "type": "filemanager:push",
|
|
21
|
+
* "payload": { ... }}
|
|
22
|
+
*/
|
|
23
|
+
this.addEventHandler('filemanager:push', this.executePush('filemanager:push'));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Invoked by the client to get the project structure on the server (localfilesystem).
|
|
28
|
+
* @param {string} - eventType: "filemanager:pull"
|
|
29
|
+
*/
|
|
30
|
+
executePull(eventType) {
|
|
31
|
+
/**
|
|
32
|
+
* @param {ws} - client websocket
|
|
33
|
+
* @returns {Object} - response
|
|
34
|
+
* :: Example
|
|
35
|
+
* {
|
|
36
|
+
* 'flow': '/project-directory/simple-flow.json',
|
|
37
|
+
* 'files': {
|
|
38
|
+
* '/project-directory': {
|
|
39
|
+
* '.kumologica': {
|
|
40
|
+
* 'editor.json': <content>
|
|
41
|
+
* '.kumologica-ignore: "build \n",
|
|
42
|
+
* }
|
|
43
|
+
*
|
|
44
|
+
* 'simple-flow.json': <content>,
|
|
45
|
+
* 'config.json': <content>,
|
|
46
|
+
* 'package.json': <content>
|
|
47
|
+
* }
|
|
48
|
+
* }
|
|
49
|
+
*
|
|
50
|
+
* }
|
|
51
|
+
*/
|
|
52
|
+
return async (ws, payload) => {
|
|
53
|
+
try {
|
|
54
|
+
const response = this.flowServer.runtime.storage.getProjectStructure();
|
|
55
|
+
this.sendResponse(ws, eventType, response);
|
|
56
|
+
} catch (err) {
|
|
57
|
+
console.log(err);
|
|
58
|
+
this.sendError(ws, eventType, "An error ocurred while pulling project directory from the server");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Invoked by the client to send the project structure updates into the server.
|
|
65
|
+
* @param {string} - eventType: "filemanager:push"
|
|
66
|
+
*/
|
|
67
|
+
executePush(eventType) {
|
|
68
|
+
/**
|
|
69
|
+
* @param {ws} - client websocket
|
|
70
|
+
* @param {Object} payload - request's payload
|
|
71
|
+
* @param {}
|
|
72
|
+
* :: Example
|
|
73
|
+
* {[
|
|
74
|
+
* {
|
|
75
|
+
* operation: "add_file",
|
|
76
|
+
* path: "/project-directory",
|
|
77
|
+
* filename: "secret.pem",
|
|
78
|
+
* content: <content>
|
|
79
|
+
* },
|
|
80
|
+
* {
|
|
81
|
+
* operation: "delete_file",
|
|
82
|
+
* path: "/project-directory",
|
|
83
|
+
* filename: "secret.pem"
|
|
84
|
+
* },
|
|
85
|
+
* {
|
|
86
|
+
* operation: "update_file",
|
|
87
|
+
* path: "/project-directory",
|
|
88
|
+
* filename: "secret.pem",
|
|
89
|
+
* content: <content>
|
|
90
|
+
* },
|
|
91
|
+
* {
|
|
92
|
+
* operation: "rename_file",
|
|
93
|
+
* path: "/project-directory",
|
|
94
|
+
* filename: "secret.pem",
|
|
95
|
+
* newFileName: "keys.pem"
|
|
96
|
+
* },
|
|
97
|
+
* {
|
|
98
|
+
* operation: "add_folder",
|
|
99
|
+
* path: "/project-directory/new-folder",
|
|
100
|
+
* },
|
|
101
|
+
* {
|
|
102
|
+
* operation: "remove_folder",
|
|
103
|
+
* path: "/project-directory/old-folder",
|
|
104
|
+
* },
|
|
105
|
+
* {
|
|
106
|
+
* operation: "rename_folder",
|
|
107
|
+
* path: "/project-directory/old-folder",
|
|
108
|
+
* newPath: "/project-directory/new-folder",
|
|
109
|
+
* },
|
|
110
|
+
|
|
111
|
+
* ]}
|
|
112
|
+
*/
|
|
113
|
+
return async (ws, payload) => {
|
|
114
|
+
try {
|
|
115
|
+
const response = await this.flowServer.runtime.storage.fileOperation(payload);
|
|
116
|
+
this.sendResponse(ws, eventType, response);
|
|
117
|
+
} catch (err) {
|
|
118
|
+
console.log(err);
|
|
119
|
+
this.sendError(ws, eventType, err.message);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
module.exports = {
|
|
126
|
+
FileManagerTool
|
|
127
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
const { DesignerTool } = require("../base/DesignerTool");
|
|
2
|
+
const simpleGit = require('simple-git');
|
|
3
|
+
|
|
4
|
+
class GitTool extends DesignerTool {
|
|
5
|
+
constructor(designerServer) {
|
|
6
|
+
super(designerServer);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
install() {
|
|
10
|
+
/**
|
|
11
|
+
* { "type": "git:status"}
|
|
12
|
+
*/
|
|
13
|
+
this.addEventHandler('git:status', this.executeGitStatus('git:status'));
|
|
14
|
+
/**
|
|
15
|
+
* { "type": "git:add-and-commit",
|
|
16
|
+
* "payload": { "commit": "commit message..." }}
|
|
17
|
+
*/
|
|
18
|
+
this.addEventHandler('git:add-and-commit', this.executeAddAndCommit('git:add-and-commit'));
|
|
19
|
+
/**
|
|
20
|
+
* { "type": "git:push-origin"
|
|
21
|
+
* "payload": {
|
|
22
|
+
* proxy: "http://my-annoying-proxy" // optional
|
|
23
|
+
* }
|
|
24
|
+
* }
|
|
25
|
+
*/
|
|
26
|
+
this.addEventHandler('git:push-origin', this.executePushOrigin('git:push-origin'));
|
|
27
|
+
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
gitCommand(options) {
|
|
31
|
+
const { proxy } = options || {};
|
|
32
|
+
|
|
33
|
+
// base options
|
|
34
|
+
let gitOptions = {
|
|
35
|
+
baseDir: this.flowServer.serverSettings.projectDir,
|
|
36
|
+
binary: 'git',
|
|
37
|
+
maxConcurrentProcesses: 6,
|
|
38
|
+
trimmed: false
|
|
39
|
+
}
|
|
40
|
+
// proxy included?
|
|
41
|
+
if (proxy) {
|
|
42
|
+
gitOptions = { ...gitOptions, config: [`http.proxy=${proxy}`] }
|
|
43
|
+
}
|
|
44
|
+
return simpleGit(gitOptions);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
executeGitStatus(eventType) {
|
|
48
|
+
return async (ws, payload) => {
|
|
49
|
+
try {
|
|
50
|
+
const git = this.gitCommand();
|
|
51
|
+
let status = await git.status(); //['-', 'sb'] // newStatus = {ahead, behind, current, tracking};
|
|
52
|
+
this.sendResponse(ws, eventType, { status });
|
|
53
|
+
} catch (err) {
|
|
54
|
+
this.sendError(ws, eventType, "The current project directory is not a Git repository. Please initialize Git in this directory.");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
executeAddAndCommit(eventType) {
|
|
60
|
+
return async (ws, payload) => {
|
|
61
|
+
try {
|
|
62
|
+
const { commit } = payload;
|
|
63
|
+
if (!commit) {
|
|
64
|
+
throw new Error('Commit message cannot be empty')
|
|
65
|
+
}
|
|
66
|
+
const git = this.gitCommand();
|
|
67
|
+
const resp = await git.add('./*').commit(commit);
|
|
68
|
+
this.sendResponse(ws, eventType, { resp });
|
|
69
|
+
} catch (err) {
|
|
70
|
+
this.sendError(ws, eventType, err.message);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
executePushOrigin(eventType) {
|
|
76
|
+
return async (ws, payload) => {
|
|
77
|
+
try {
|
|
78
|
+
const { proxy } = payload;
|
|
79
|
+
const git = this.gitCommand({ proxy });
|
|
80
|
+
let currentBranch = await this.readCurrentBranch();
|
|
81
|
+
const resp = await git.push('origin', currentBranch);
|
|
82
|
+
this.sendResponse(ws, eventType, { resp });
|
|
83
|
+
} catch (e) {
|
|
84
|
+
this.sendError(ws, eventType, err.message);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async readCurrentBranch() {
|
|
90
|
+
try {
|
|
91
|
+
const git = this.gitCommand();
|
|
92
|
+
const localBranches = await git.branchLocal();
|
|
93
|
+
return localBranches.current;
|
|
94
|
+
} catch (err) {
|
|
95
|
+
throw err;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
module.exports = {
|
|
102
|
+
GitTool
|
|
103
|
+
}
|