@kumologica/sdk 3.4.0 → 3.5.0-beta2

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.
Files changed (51) hide show
  1. package/cli/commands/create-commands/openapi.js +42 -0
  2. package/cli/commands/create.js +17 -8
  3. package/cli/commands/login.js +87 -0
  4. package/package.json +18 -7
  5. package/src/app/lib/ai/layout.js +75 -0
  6. package/src/app/lib/ai/openai.js +108 -0
  7. package/src/app/lib/ai/prompt.txt +583 -0
  8. package/src/app/lib/aws/ca-cloudwatch-api.js +2 -10
  9. package/src/app/lib/aws/ca-dynamodb-api.js +6 -10
  10. package/src/app/lib/aws/ca-elb-api.js +4 -24
  11. package/src/app/lib/aws/ca-events-api.js +5 -12
  12. package/src/app/lib/aws/ca-iot-api.js +3 -87
  13. package/src/app/lib/aws/ca-s3-api.js +17 -62
  14. package/src/app/lib/aws/ca-sns-api.js +6 -15
  15. package/src/app/lib/aws/ca-sqs-api.js +9 -6
  16. package/src/app/lib/aws/index.js +70 -86
  17. package/src/app/lib/aws/kl-apigw-api.js +40 -0
  18. package/src/app/lib/aws/kl-iam-api.js +5 -5
  19. package/src/app/lib/github/index.js +0 -17
  20. package/src/app/lib/serverless/index.js +1 -1
  21. package/src/app/lib/stores/settings-cloud-store.js +35 -2
  22. package/src/app/main.js +34 -32
  23. package/src/app/preload.js +36 -28
  24. package/src/app/ui/editor-client/public/red/red.js +924 -458
  25. package/src/app/ui/editor-client/public/red/red.min.js +2 -2
  26. package/src/app/ui/editor-client/public/red/style.min.css +1 -1
  27. package/src/app/ui/editor-client/src/js/nodes.js +19 -18
  28. package/src/app/ui/editor-client/src/js/red.js +6 -3
  29. package/src/app/ui/editor-client/src/js/ui/editor.js +70 -70
  30. package/src/app/ui/editor-client/src/js/ui/footer.js +143 -0
  31. package/src/app/ui/editor-client/src/js/ui/search.js +43 -34
  32. package/src/app/ui/editor-client/src/js/ui/sidebar.js +26 -24
  33. package/src/app/ui/editor-client/src/js/ui/signup.js +56 -0
  34. package/src/app/ui/editor-client/src/js/ui/tab-ai.js +210 -0
  35. package/src/app/ui/editor-client/src/js/ui/tab-awsDeploy.js +30 -5
  36. package/src/app/ui/editor-client/src/js/ui/tab-test.js +120 -99
  37. package/src/app/ui/editor-client/src/js/ui/update-panel.js +0 -1
  38. package/src/app/ui/editor-client/src/js/ui/view.js +201 -202
  39. package/src/app/ui/editor-client/src/sass/editor.scss +715 -645
  40. package/src/app/ui/editor-client/src/sass/sidebar.scss +21 -12
  41. package/src/app/ui/editor-client/src/sass/style.scss +101 -0
  42. package/src/app/ui/editor-client/src/sass/tab-ai.scss +68 -0
  43. package/src/app/ui/editor-client/src/sass/workspace.scss +12 -2
  44. package/src/app/ui/editor-client/templates/index.mst +41 -7
  45. package/src/server/DesignerServer.js +2 -1
  46. package/cli/.DS_Store +0 -0
  47. package/fixtures/.DS_Store +0 -0
  48. package/src/app/lib/aws/ca-apigw-api.js +0 -216
  49. package/src/app/lib/aws/ca-codecommit-api.js +0 -63
  50. package/src/app/lib/aws/kl-rekognition-api.js +0 -66
  51. package/src/app/lib/aws/kl-ssm-api.js +0 -24
@@ -0,0 +1,42 @@
1
+ const pathlib = require('path');
2
+ const { prompt, Select } = require('enquirer');
3
+ const { logNotice, logError } = require('../../utils/logger');
4
+ const { downloadTemplateFromRepo, listAvailableTemplates } = require('../../utils/download-template-from-repo');
5
+
6
+ async function createProjectIteratively(){
7
+ const availableTemplates = await listAvailableTemplates();
8
+ // Project name
9
+ const projectNameResponse = await prompt({
10
+ type: 'input',
11
+ name: 'projectName',
12
+ message: 'Enter the name for the project'
13
+ });
14
+ let aProjectName = projectNameResponse.projectName;
15
+
16
+ // Target Path
17
+ const directoryResponse = await prompt({
18
+ type: 'input',
19
+ name: 'directory',
20
+ message: 'Enter the path where the project will be created '
21
+ });
22
+ let aProjectPath = directoryResponse.directory;
23
+
24
+ // Template name
25
+ const promptTemplate = new Select({
26
+ name: 'template',
27
+ message: 'Pick one of the available templates',
28
+ choices: availableTemplates
29
+ });
30
+
31
+ let aTemplateName = await promptTemplate.run();
32
+
33
+ try{
34
+ await downloadTemplateFromRepo(undefined, aTemplateName, aProjectPath, aProjectName);
35
+ logNotice(`Successfully created project: ${pathlib.join(aProjectPath, aProjectName)}`)
36
+ } catch (err){
37
+ logError(`Error found while creating project due to: ${err.message}`)
38
+ }
39
+ }
40
+
41
+
42
+ module.exports = createProjectIteratively;
@@ -20,32 +20,41 @@ exports.builder = (yargs) => {
20
20
  alias: 't',
21
21
  nargs: 1
22
22
  })
23
+ yargs.option(`api`, {
24
+ describe: `OpenApi/Swagger definition of the api`,
25
+ type: 'string',
26
+ alias: 'a',
27
+ nargs: 1
28
+ })
23
29
  }
24
30
 
25
31
 
26
32
  exports.desc = 'Create a kumologica project. Do not pass any options to create iteratively.'
27
- exports.handler = async ({ path, template }) => {
33
+ exports.handler = async ({ path, template, api }) => {
28
34
  const { version } = require('../../package.json');
29
35
 
30
- if (!path && !template) {
36
+ if (!path && !template && !api) {
31
37
  await createProjectIteratively();
38
+
32
39
  } else if (!path && template) {
33
- try{
40
+ try {
34
41
  await downloadTemplateFromRepo(undefined, template, process.cwd(), template);
35
- logNotice(`Successfully created project: ${ pathlib.join(process.cwd(), template)}`);
36
- }catch(e){
42
+ logNotice(`Successfully created project: ${ pathlib.join(process.cwd(), template)}`);
43
+ } catch(e) {
37
44
  logError(e.message);
38
45
  }
46
+
39
47
  } else if (path && !template){
40
- try{
48
+ try {
41
49
  codegen.generateBoilerplateProject({
42
50
  basePath :process.cwd(),
43
51
  projectName: path,
44
52
  runtimeVersion: version });
45
53
  logNotice(`Successfully created project: ${ pathlib.join(process.cwd(), path)}`);
46
- }catch(e){
54
+ } catch(e) {
47
55
  logError(e.message);
48
56
  }
57
+
49
58
  } else if (path && template) {
50
59
  path = pathlib.resolve(path);
51
60
  let projectPath = pathlib.dirname(path);
@@ -57,7 +66,7 @@ exports.handler = async ({ path, template }) => {
57
66
  await downloadTemplateFromRepo(undefined, template, projectPath, projectName);
58
67
  }
59
68
  logNotice(`Successfully created project: ${path}`);
60
- }catch(e){
69
+ } catch(e) {
61
70
  logError(e.message);
62
71
  }
63
72
  }
@@ -0,0 +1,87 @@
1
+
2
+ const { prompt, Select } = require('enquirer');
3
+
4
+ exports.command = 'login';
5
+ exports.desc = `Login to kumologica.dev`;
6
+
7
+ exports.builder = {
8
+
9
+ "email": {
10
+ describe: "Valid email address for login",
11
+ type: 'string',
12
+ alias: 'e',
13
+ nargs: 1
14
+ },
15
+ "password": {
16
+ describe: "Password for login.",
17
+ type: 'string',
18
+ alias: 'p',
19
+ nargs: 1
20
+ }
21
+ }
22
+
23
+ async function login(email, password) {
24
+ const { CognitoIdentityProviderClient, InitiateAuthCommand } = require("@aws-sdk/client-cognito-identity-provider");
25
+ const client = new CognitoIdentityProviderClient();
26
+
27
+ const input = {
28
+ AuthFlow: "USER_PASSWORD_AUTH",
29
+ AuthParameters: {
30
+ PASSWORD: password,
31
+ USERNAME: email
32
+ },
33
+ ClientId: "5qm756mn3otap8o8f2vf6vqj96"
34
+ };
35
+ const command = new InitiateAuthCommand(input);
36
+ const response = await client.send(command);
37
+ console.log(JSON.stringify(response, null, 2));
38
+
39
+
40
+ };
41
+
42
+
43
+ exports.handler = async function (argv) {
44
+
45
+ const chalk = require('chalk');
46
+
47
+ try {
48
+ let email;
49
+
50
+ if (argv.email) {
51
+ email = argv.email;
52
+ } else {
53
+ const emailPrompt = await prompt({
54
+ type: 'input',
55
+ name: 'email',
56
+ message: 'Enter valid email address to be used for login'
57
+ });
58
+ email = emailPrompt.email;
59
+ }
60
+
61
+ console.log(`\Logging in to komologica.dev using email: ${email}\n`);
62
+
63
+ let pwd;
64
+
65
+ if (argv.password) {
66
+ pwd = argv.password;
67
+ } else {
68
+ const pwdPrompt = await prompt({
69
+ type: 'input',
70
+ name: 'password',
71
+ message: 'Enter password.'
72
+ });
73
+ pwd = pwdPrompt.password;
74
+ }
75
+
76
+ await login(email, pwd);
77
+
78
+
79
+ console.log(chalk.greenBright('Login successful.'));
80
+
81
+ process.exit(0);
82
+ } catch (e) {
83
+
84
+ console.log(`${chalk.redBright(e.message)}`);
85
+ process.exit(1);
86
+ }
87
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kumologica/sdk",
3
- "version": "3.4.0",
3
+ "version": "3.5.0-beta2",
4
4
  "productName": "Kumologica Designer",
5
5
  "copyright": "Copyright 2020 Kumologica Pty Ltd, All Rights Reserved.",
6
6
  "author": "Kumologica Pty Ltd <contact@kumologica.com>",
@@ -63,14 +63,24 @@
63
63
  },
64
64
  "license": "Proprietary",
65
65
  "dependencies": {
66
+ "@aws-sdk/client-api-gateway": "^3.556.0",
67
+ "@aws-sdk/client-cloudformation": "^3.556.0",
68
+ "@aws-sdk/client-cloudwatch-events": "^3.556.0",
69
+ "@aws-sdk/client-dynamodb-streams": "^3.556.0",
70
+ "@aws-sdk/client-elastic-load-balancing-v2": "^3.556.0",
71
+ "@aws-sdk/client-iam": "^3.556.0",
72
+ "@aws-sdk/client-iot": "^3.556.0",
73
+ "@aws-sdk/client-s3": "^3.556.0",
74
+ "@aws-sdk/client-sns": "^3.556.0",
75
+ "@aws-sdk/client-sqs": "^3.556.0",
76
+ "@aws-sdk/credential-providers": "^3.556.0",
66
77
  "@electron/remote": "^2.0.8",
67
- "@kumologica/builder": "3.4.0",
68
- "@kumologica/devkit": "3.4.0",
69
- "@kumologica/runtime": "3.4.0",
78
+ "@kumologica/builder": "3.5.0-beta2",
79
+ "@kumologica/devkit": "3.5.0-beta2",
80
+ "@kumologica/runtime": "3.5.0-beta2",
70
81
  "adm-zip": "0.4.13",
71
82
  "ajv": "8.10.0",
72
83
  "archive-type": "^4.0.0",
73
- "aws-sdk": "2.513.0",
74
84
  "basic-auth": "2.0.1",
75
85
  "bcryptjs": "2.4.3",
76
86
  "bluebird": "^3.7.2",
@@ -111,6 +121,7 @@
111
121
  "mime": "2.4.4",
112
122
  "mustache": "3.0.1",
113
123
  "oauth2orize": "1.11.0",
124
+ "openai": "^4.28.4",
114
125
  "os": "0.1.1",
115
126
  "p-event": "^5.0.1",
116
127
  "passport": "0.4.0",
@@ -164,9 +175,9 @@
164
175
  "typescript": "^3.5.3"
165
176
  },
166
177
  "engines": {
167
- "node": ">=8"
178
+ "node": ">=18"
168
179
  },
169
180
  "kumologica": {
170
- "dev": false
181
+ "dev": true
171
182
  }
172
183
  }
@@ -0,0 +1,75 @@
1
+ const dagre = require('dagre');
2
+
3
+ const NODE_SIZE = 45;
4
+ const NODE_SEP = 50;
5
+ const MARGIN_X = 50;
6
+ const MARGIN_Y = 50;
7
+
8
+ function applyLayout(nodes) {
9
+ let layarizedFlow = [];
10
+
11
+ let tabs = nodes.filter(n => n.type === 'tab');
12
+ // No tab, most likely a single nod
13
+ if (tabs.length === 0) {
14
+ let tabIds = [...new Set(nodes.map(item => item.z))];
15
+ tabIds.map(tabId => {
16
+ layarizedFlow.push(...applyTabLayout(nodes, tabId));
17
+ })
18
+ } else {
19
+ tabs.map(tab => {
20
+ layarizedFlow.push(tab);
21
+ layarizedFlow.push(...applyTabLayout(nodes, tab.id));
22
+ })
23
+ }
24
+
25
+ return layarizedFlow;
26
+ }
27
+
28
+ function applyTabLayout(nodes, tabId) {
29
+ let nodesOnTab = nodes.filter(n => n.z === tabId) || [];
30
+
31
+ // Prepare the graph
32
+ let g = new dagre.graphlib.Graph();
33
+
34
+ // Set an object for the graph label
35
+ g.setGraph({
36
+ rankdir: "LR",
37
+ nodesep: NODE_SEP,
38
+ marginx: MARGIN_X,
39
+ marginy: MARGIN_Y
40
+ });
41
+
42
+ // Default to assigning a new object as a label for each new edge.
43
+ g.setDefaultEdgeLabel(function () { return {}; });
44
+
45
+ // Create nodes for the graph
46
+ nodesOnTab.forEach(n => {
47
+ g.setNode(n.id, { label: n.name, width: NODE_SIZE, height: NODE_SIZE })
48
+
49
+ // TODO - Check the wires here and create the edge
50
+ if (n.wires && Array.isArray(n.wires) && n.wires.length > 0) {
51
+ n.wires.forEach(wire => {
52
+ g.setEdge(n.id, wire)
53
+ })
54
+ }
55
+ });
56
+
57
+ dagre.layout(g);
58
+
59
+ // Apply the coordinates
60
+ g.nodes().forEach(nid => {
61
+ if (nid) {
62
+ let node = nodesOnTab.find(n => n.id === nid);
63
+ if (node) {
64
+ node.x = g.node(nid).x;
65
+ node.y = Number.isNaN(g.node(nid).y) ? 0 : g.node(nid).y;
66
+ }
67
+ }
68
+ });
69
+
70
+ return nodesOnTab;
71
+ }
72
+
73
+ module.exports = {
74
+ applyLayout
75
+ }
@@ -0,0 +1,108 @@
1
+ const OpenAI = require('openai');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const { applyLayout } = require('./layout');
5
+
6
+
7
+ require('dotenv').config()
8
+
9
+ // utils
10
+ function unescapeObject(obj) {
11
+ // Check if the input is an object
12
+ if (typeof obj !== 'object' || obj === null) {
13
+ return obj; // Return as is if not an object
14
+ }
15
+
16
+ // Iterate over each property of the object
17
+ for (let key in obj) {
18
+ if (obj.hasOwnProperty(key)) {
19
+ // If the property is a string, unescape it
20
+ if (typeof obj[key] === 'string') {
21
+ obj[key] = unescapeString(obj[key]);
22
+ }
23
+ // If the property is an object, recursively unescape its properties
24
+ else if (typeof obj[key] === 'object') {
25
+ obj[key] = unescapeObject(obj[key]);
26
+ }
27
+ }
28
+ }
29
+
30
+ return obj;
31
+ }
32
+
33
+ // Function to unescape a string
34
+ function unescapeString(str) {
35
+ // Remove all occurrences of "\n
36
+ str = str.replace(/\\n\s*|\\n/g, '');
37
+
38
+
39
+ return str.replace(/\\(.)/g, function (_, char) {
40
+ switch (char) {
41
+ case 'n': return '\n'; // Replace '\n' with newline character
42
+ case 't': return '\t'; // Replace '\t' with tab character
43
+ case 'r': return '\r'; // Replace '\r' with carriage return character
44
+ case 'b': return '\b'; // Replace '\b' with backspace character
45
+ case 'f': return '\f'; // Replace '\f' with form feed character
46
+ case '\\': return '\\'; // Replace '\\' with backslash character
47
+ case '"': return '"'; // Replace '\"' with double quote character
48
+ case "'": return "'"; // Replace "\'" with single quote character
49
+ default: return char; // Return the character as is if not an escape sequence
50
+ }
51
+ });
52
+ }
53
+
54
+
55
+ class OpenAIClient {
56
+ // attributes
57
+ openai = null;
58
+ version = null;
59
+
60
+ constructor(props) {
61
+ this.openai = new OpenAI({
62
+ apiKey: props.key || process.env.OPENAI_API_KEY || '***',
63
+ dangerouslyAllowBrowser: true
64
+ });
65
+ this.version = props.version || 'gpt-3.5-turbo';
66
+ }
67
+
68
+ getSystemPrompt() {
69
+ if (!this.systemPrompt) {
70
+ try {
71
+ this.systemPrompt = fs.readFileSync(path.join(__dirname, 'prompt.txt'), 'utf-8');
72
+ } catch (err) {
73
+ throw err;
74
+ }
75
+ }
76
+ return this.systemPrompt;
77
+ }
78
+
79
+ async t2c(userTask) {
80
+ let userMessage = `
81
+ Generate kumologica flow. Do not include any extra explanation, just the json document. For the following user description:
82
+ ${userTask}`;
83
+ try {
84
+ let spec = this.getSystemPrompt();
85
+ const chatCompletion = await this.openai.chat.completions.create({
86
+ model: this.version,
87
+ messages: [
88
+ { role: 'system', content: spec },
89
+ { role: 'user', content: userMessage }
90
+ ]
91
+ });
92
+
93
+ const resp = chatCompletion.choices[0].message.content;
94
+ console.log('[openai] Resp=', resp);
95
+ const respo = JSON.parse(resp);
96
+ console.log('[openai] Resp.flow=', JSON.parse(respo.flow));
97
+ console.log('[openai] Unscaped - Resp.flow', unescapeObject(JSON.parse(respo.flow)));
98
+ return applyLayout(unescapeObject(JSON.parse(respo.flow)));
99
+ } catch (err) {
100
+ console.log(err);
101
+ throw new Error(err.toString());
102
+ }
103
+ }
104
+ }
105
+
106
+ module.exports = {
107
+ OpenAIClient
108
+ }