@gudhub/core 1.1.90 → 1.1.92

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.
@@ -298,9 +298,6 @@ export class AppProcessor {
298
298
  }
299
299
  }
300
300
  }
301
-
302
- // This code for trash must be changed
303
- // return trash ? app : {...app, items_list: app.items_list.filter(item => !item.trash)};
304
301
  return app;
305
302
  }
306
303
 
@@ -10,6 +10,12 @@ export class Auth {
10
10
  return user;
11
11
  }
12
12
 
13
+ async loginWithToken(token) {
14
+ const user = await this.loginWithTokenApi(token);
15
+ this.storage.updateUser(user);
16
+ return user;
17
+ }
18
+
13
19
  async logout(token) {
14
20
  const response = await this.logoutApi(token);
15
21
  return response;
@@ -58,6 +64,18 @@ export class Auth {
58
64
  }
59
65
  }
60
66
 
67
+ async loginWithTokenApi(token) {
68
+ try {
69
+ const user = await this.req.axiosRequest({
70
+ method: 'POST',
71
+ url: `${this.req.root}/auth/login?accesstoken=${token}`
72
+ });
73
+ return user;
74
+ } catch (error) {
75
+ console.log(error);
76
+ }
77
+ }
78
+
61
79
  async updateTokenApi(auth_key) {
62
80
  try {
63
81
  const user = await this.req.axiosRequest({
@@ -1,4 +1,4 @@
1
- import should from "should";
1
+
2
2
  import {GudHub} from './../gudhub.js';
3
3
 
4
4
  describe("AUTHORIZATION", async function() {
@@ -22,6 +22,16 @@ describe("AUTHORIZATION", async function() {
22
22
  user.fullname.should.equal('Vasya Pupkin');
23
23
  })
24
24
 
25
+ it("Authentication with access token", async function () {
26
+ const gudhub = new GudHub();
27
+
28
+ const token = 'accesstoken';
29
+
30
+ const user = await gudhub.loginWithToken(token);
31
+
32
+ user.hasOwnProperty('fullname').should.equal(true);
33
+ })
34
+
25
35
  it("Signing up user", async function () {
26
36
  const gudhub = new GudHub();
27
37
  let credentials = {
@@ -39,7 +39,7 @@ export class FileManager {
39
39
  }
40
40
  }
41
41
 
42
- async updateFileFromStringApi(data, file_id, file_name, extension, format) {
42
+ async updateFileFromStringApi(data, file_id, file_name, extension, format, alt, title) {
43
43
  try {
44
44
  const fileObj = {
45
45
  file_name,
@@ -47,6 +47,8 @@ export class FileManager {
47
47
  file_id,
48
48
  format,
49
49
  source: data,
50
+ alt,
51
+ title
50
52
  };
51
53
 
52
54
  const file = await this.req.post({
@@ -198,13 +200,15 @@ async getFiles(app_id, filesId = []) {
198
200
  return file;
199
201
  }
200
202
 
201
- async updateFileFromString(data, file_id, file_name, extension, format) {
203
+ async updateFileFromString(data, file_id, file_name, extension, format, alt, title) {
202
204
  const file = await this.updateFileFromStringApi(
203
205
  data,
204
206
  file_id,
205
207
  file_name,
206
208
  extension,
207
- format
209
+ format,
210
+ alt,
211
+ title
208
212
  );
209
213
  this.updateFileInStorage(file_id, file.app_id, file);
210
214
  return file;
@@ -119,25 +119,27 @@ export default async function createAngularModuleInstance(gudhub, module_id, mod
119
119
  }
120
120
 
121
121
  // Modules always exports classes as default, so we create new class instance.
122
-
123
122
  importedClass = factoryReturns[module_id];
124
-
125
123
  }
126
-
127
124
  } else {
128
-
129
125
  const proxy = new Proxy(nodeWindow, {
130
126
  get: (target, property) => {
131
- return target[property]
127
+ const value = target[property];
128
+ if (typeof value === 'symbol') {
129
+ return undefined;
130
+ }
131
+ return value;
132
132
  },
133
133
  set: (target, property, value) => {
134
+ if (typeof value === 'symbol') {
135
+ return false;
136
+ }
134
137
  target[property] = value;
135
138
  global[property] = value;
136
139
  return true;
137
140
  }
138
- })
139
-
140
- // If node's global object don't have window and it's methods yet - set it.
141
+ });
142
+
141
143
  if (!global.hasOwnProperty('window')) {
142
144
  global.window = proxy;
143
145
  global.document = nodeWindow.document;
@@ -153,35 +155,42 @@ export default async function createAngularModuleInstance(gudhub, module_id, mod
153
155
  global.WebSocket = nodeWindow.WebSocket;
154
156
  global.crypto = nodeWindow.crypto;
155
157
  global.DOMParser = nodeWindow.DOMParser;
156
- global.Symbol = nodeWindow.Symbol;
158
+
157
159
  global.document.queryCommandSupported = (command) => {
158
160
  return false;
159
- }
161
+ };
160
162
  global.angular = angular;
161
163
  }
162
-
163
- // Downloading module's code and transform it to data url.
164
-
165
- let response = await axios.get(module_url);
166
- let code = response.data;
167
- let encodedCode = encodeURIComponent(code);
168
- encodedCode = 'data:text/javascript;charset=utf-8,' + encodedCode;
169
-
170
- let module;
171
-
172
- // Then, dynamically import modules from data url.
173
-
164
+
165
+ // Downloading module's code and transforming it to a data URL.
174
166
  try {
175
- module = await import(/* webpackIgnore: true */encodedCode);
176
- } catch (err) {
177
- console.log(`Error while importing module: ${module_id}`);
178
- console.log(err);
167
+ let response = await axios.get(module_url);
168
+ let code = response.data;
169
+
170
+ // Ensure code is properly encoded, excluding any symbols
171
+ let encodedCode = encodeURIComponent(code);
172
+
173
+ // Creating a data URL
174
+ encodedCode = 'data:text/javascript;charset=utf-8,' + encodedCode;
175
+
176
+ let module;
177
+
178
+ // Dynamically import the module from the data URL.
179
+ try {
180
+ module = await import(/* webpackIgnore: true */ encodedCode);
181
+ } catch (err) {
182
+ console.log(`Error while importing module: ${module_id}`);
183
+ console.log(err);
184
+ }
185
+
186
+ if (module && module.default) {
187
+ importedClass = new module.default();
188
+ } else {
189
+ console.error(`Module ${module_id} didn't export a default class`);
190
+ }
191
+ } catch (error) {
192
+ console.error("Error fetching module code:", error);
179
193
  }
180
-
181
- // Modules always exports classes as default, so we create new class instance.
182
-
183
- importedClass = new module.default();
184
-
185
194
  }
186
195
 
187
196
  let result = {
@@ -134,7 +134,7 @@ export class ItemProcessor {
134
134
  }
135
135
 
136
136
  async getItems(app_id, trash = false) {
137
- const app = await this.appProcessor.getApp(app_id, trash);
137
+ const app = await this.appProcessor.getApp(app_id);
138
138
  if(!app) return null;
139
139
  return app.items_list;
140
140
  }
@@ -165,6 +165,15 @@ export class ItemProcessor {
165
165
  );
166
166
  }
167
167
 
168
+ async restoreItems(app_id, itemsIds) {
169
+ const preparedItemsList = itemsIds.map((id) => ({
170
+ item_id: id,
171
+ trash: false
172
+ }));
173
+ const updatedItems = await this.updateItemsApi(app_id, preparedItemsList);
174
+ return await this.updateItemsInStorage(app_id, updatedItems);
175
+ }
176
+
168
177
  itemListeners() {
169
178
  this.pipeService.onRoot("gh_items_get", {}, async (event, data) => {
170
179
  if(data && data.app_id) {
@@ -931,7 +931,7 @@ export default function generateModulesList(async_modules_path, file_server_url,
931
931
  data_type: 'study_journal',
932
932
  name: 'Study Journal',
933
933
  icon: 'timeline',
934
- js: 'https://gudhub.com/modules/Study-Journal/dist/main.js',
934
+ js: 'https://gudhub.com/modules/Study-Journal/dist/main.js?t=1',
935
935
  css: 'https://gudhub.com/modules/Study-Journal/dist/style.css',
936
936
  type: 'gh_element',
937
937
  technology: 'class'
@@ -958,11 +958,44 @@ export default function generateModulesList(async_modules_path, file_server_url,
958
958
  data_type: "text_area",
959
959
  name: "Text Area",
960
960
  icon: "text_icon",
961
- js: "https://gudhub.com/modules/text-area-ghe/dist/main.js?t=1",
961
+ js: "https://gudhub.com/modules/text-area-ghe/dist/main.js?t=3",
962
962
  css: "https://gudhub.com/modules/text-area-ghe/dist/style.css",
963
963
  type: "gh_element",
964
964
  technology: "class",
965
965
  },
966
+ {
967
+ data_type: "resource_calendar",
968
+ name: "Resource Сalendar",
969
+ icon: "calendar",
970
+ url: file_server_url + '/' + async_modules_path + "resource_calendar_data.js",
971
+ type: 'gh_element',
972
+ technology: 'angular'
973
+ },
974
+ {
975
+ data_type: "visualizer_with_control_panel",
976
+ name: "Visualizer With Control Panel",
977
+ icon: 'visualizer',
978
+ url: file_server_url + '/' + async_modules_path + "visualizer_with_control_panel_data.js",
979
+ type: 'gh_element',
980
+ technology: 'angular'
981
+ },
982
+ {
983
+ data_type: "svg_to_pdf",
984
+ name: "SVG To PDF",
985
+ icon: "box",
986
+ js: "https://gudhub.com/modules/SVG-to-PDF-Gh-Element/dist/main.js",
987
+ css: "https://gudhub.com/modules/SVG-to-PDF-Gh-Element/dist/style.css",
988
+ type: "gh_element",
989
+ technology: "class",
990
+ },
991
+ {
992
+ data_type: "recycle_bin",
993
+ name: "Recycle Bin",
994
+ icon: 'recycle_bin',
995
+ url: file_server_url + '/' + async_modules_path + "recycle_bin_data.js",
996
+ type: 'gh_element',
997
+ technology: "angular",
998
+ },
966
999
  /* AUTOMATION MODULES */
967
1000
  /*
968
1001
  We have next types for automations:
@@ -1340,6 +1373,13 @@ export default function generateModulesList(async_modules_path, file_server_url,
1340
1373
  url: file_server_url + '/' + automation_modules_path + 'turbo_sms.js',
1341
1374
  type: 'automation',
1342
1375
  icon: 'email'
1376
+ },
1377
+ {
1378
+ data_type: 'JsCode',
1379
+ name: 'Js Code',
1380
+ url: file_server_url + '/' + automation_modules_path + 'js_code.js',
1381
+ type: 'automation',
1382
+ icon: 'code_editor'
1343
1383
  }
1344
1384
  ]
1345
1385
  }
@@ -195,6 +195,8 @@ export default class AppsTemplateService {
195
195
 
196
196
  documentInstallerHelper(appId, items, elementId) {
197
197
  const self = this;
198
+ const itemsWithClonedDocument = [];
199
+
198
200
  return new Promise(async (resolve) => {
199
201
  for(const item of items) {
200
202
  const itemId = item.item_id;
@@ -216,10 +218,11 @@ export default class AppsTemplateService {
216
218
 
217
219
  field.field_value = newDocument._id;
218
220
 
221
+ itemsWithClonedDocument.push(item);
219
222
  }
220
223
  }
221
224
  }
222
- resolve();
225
+ resolve(itemsWithClonedDocument);
223
226
  });
224
227
  }
225
228
 
@@ -440,7 +443,14 @@ export default class AppsTemplateService {
440
443
  });
441
444
 
442
445
  self.crawling(app.field_list, function (prop, value, parent) {
443
- if (prop.indexOf("field_id") !== -1 || prop.indexOf("FieldId") !== -1 || prop.indexOf("destination_field") !== -1) {
446
+ const fieldProps = ["field_id", "FieldId", "destination_field", "element_id"];
447
+ const appProps = ["app_id", "AppId", "destination_app"];
448
+ const viewProps = ["view_id"];
449
+ const srcProps = ["src"];
450
+
451
+ const hasProp = (prop, propArray) => propArray.some(key => prop.indexOf(key) !== -1);
452
+
453
+ if (hasProp(prop, fieldProps)) {
444
454
  let fieldsArr = String(value).split(','), newFieldsArr = [];
445
455
 
446
456
  appsConnectingMap.fields.forEach(field => {
@@ -456,7 +466,7 @@ export default class AppsTemplateService {
456
466
  }
457
467
  }
458
468
 
459
- if (prop.indexOf("app_id") != -1 || prop.indexOf("AppId") != -1 || prop.indexOf("destination_app") != -1) {
469
+ if (hasProp(prop, appProps)) {
460
470
  appsConnectingMap.apps.forEach(app => {
461
471
  if (value == app.old_app_id) {
462
472
  parent[prop] = app.new_app_id;
@@ -464,7 +474,7 @@ export default class AppsTemplateService {
464
474
  })
465
475
  }
466
476
 
467
- if (prop.indexOf("view_id") !== -1) {
477
+ if (hasProp(prop, viewProps)) {
468
478
  appsConnectingMap.views.forEach(view => {
469
479
  if (value == view.old_view_id) {
470
480
  parent[prop] = view.new_view_id;
@@ -472,7 +482,7 @@ export default class AppsTemplateService {
472
482
  })
473
483
  }
474
484
 
475
- if (prop.indexOf("src") !== -1 && isFinite(value)) {
485
+ if (hasProp(prop, srcProps) && isFinite(value)) {
476
486
  const pron_name = 'container_id';
477
487
  const old_app_id = appsConnectingMap.apps.find(appMap => appMap.new_app_id === app.app_id).old_app_id;
478
488
  const path = self.findPath(source_apps[old_app_id].views_list, pron_name, value);
@@ -480,6 +490,39 @@ export default class AppsTemplateService {
480
490
  parent[prop] = `${self.getValueByPath(app.views_list, path, pron_name)}`;
481
491
  }
482
492
 
493
+ if (prop.indexOf("trigger") !== -1 && value.model && value.model.nodes) {
494
+ const nodes = value.model.nodes;
495
+ const nodeProperties = ["inputs", "outputs"];
496
+
497
+ for (const index in nodes) {
498
+ nodeProperties.forEach((property) => {
499
+ const node = nodes[index];
500
+ const numericProperties = Object.keys(node[property]).filter(prop => prop !== '' && !isNaN(prop)); // field_id as keys
501
+
502
+ numericProperties.forEach((old_field_id) => {
503
+ const correspondFieldOfConnectingMap = appsConnectingMap.fields.filter((field) => field.old_field_id == old_field_id);
504
+
505
+ if (correspondFieldOfConnectingMap.length !== 0 && correspondFieldOfConnectingMap[0].new_field_id) {
506
+ const new_field_id = correspondFieldOfConnectingMap[0].new_field_id.toString();
507
+
508
+ const connectionObjectCopy = node[property][old_field_id];
509
+ connectionObjectCopy.connections.forEach((connection) => {
510
+ if (connection.input == old_field_id) {
511
+ connection.input = new_field_id;
512
+ }
513
+ if (connection.output == old_field_id) {
514
+ connection.output = new_field_id;
515
+ }
516
+ });
517
+
518
+ delete node[property][old_field_id];
519
+
520
+ node[property][new_field_id] = connectionObjectCopy;
521
+ }
522
+ });
523
+ });
524
+ };
525
+ }
483
526
  })
484
527
  })
485
528
 
@@ -53,7 +53,7 @@ describe("GET DATE", function () {
53
53
  day.getDay().should.equal(6);
54
54
  });
55
55
 
56
- it("CHECK IF DATE TODAY", function() {
56
+ it("CHECK RECURRING DATE / today", function() {
57
57
  let today = new Date();
58
58
  let result = gudhub.checkRecurringDate(today, 'day');
59
59
  result.should.equal(true);
@@ -64,7 +64,7 @@ describe("GET DATE", function () {
64
64
  result.should.equal(false);
65
65
  })
66
66
 
67
- it("CHECK IF DATE IN THIS WEEK", function() {
67
+ it("CHECK RECURRING DATE / week", function() {
68
68
  let today = new Date();
69
69
  let result = gudhub.checkRecurringDate(today, 'week');
70
70
  result.should.equal(true);
@@ -75,16 +75,7 @@ describe("GET DATE", function () {
75
75
  result.should.equal(false);
76
76
  });
77
77
 
78
- it('CHECK IF DATE IN THIS WEEK / Compare this wednesday with wednesday two years ago', function(){
79
- let day = gudhub.getDate('this_wednesday');
80
- let dayTwoYearsBefore = subYears(day, 2);
81
-
82
- // console.log(dayTwoYearsBefore);
83
- let result = gudhub.checkRecurringDate(dayTwoYearsBefore, 'week');
84
- result.should.equal(true);
85
- });
86
-
87
- it("CHECK IF DATE IN THIS MONTH", function() {
78
+ it("CHECK RECURRING DATE / month", function() {
88
79
  let today = new Date();
89
80
  let result = gudhub.checkRecurringDate(today, 'month');
90
81
  result.should.equal(true);
@@ -1,52 +1,55 @@
1
- export function makeNestedList(arr, id, parent_id, children_property, priority_property) {
2
- let array = JSON.parse(JSON.stringify(arr));
3
- let children = Boolean(children_property) ? children_property : 'children';
4
- let priority = Boolean(priority_property) ? priority_property : false;
5
- let i;
6
- for (i = 0; i < array.length; i++) {
7
- if (array[i][parent_id] && array[i][parent_id] !== 0) {
8
- array.forEach((parent) => {
9
- if (array[i][parent_id] == parent[id]) {
10
- if (!parent[children]) {
11
- parent[children] = [];
12
- }
13
- parent[children].push(array[i]);
14
- array.splice(i, 1);
15
- i == 0 ? i = 0 : i--;
16
- } else if (parent[children]) {
17
- findIdsOfChildren(parent);
18
- }
19
- });
20
- }
21
- }
22
-
23
- function findIdsOfChildren(parent) {
24
- parent[children].forEach((child) => {
25
- if (child[id] == array[i][parent_id]) {
26
- if (!child[children]) {
27
- child[children] = [];
1
+ export function makeNestedList(
2
+ arr,
3
+ id,
4
+ parent_id,
5
+ children_property = "children",
6
+ priority_property = null
7
+ ) {
8
+ let map = {};
9
+ let roots = [];
10
+
11
+ arr.forEach((item) => {
12
+ map[item[id]] = { ...item, [children_property]: [] };
13
+ });
14
+
15
+ arr.forEach((item) => {
16
+ const parentId = item[parent_id];
17
+ if (parentId && map[parentId]) {
18
+ map[parentId][children_property].push(map[item[id]]);
19
+ } else {
20
+ roots.push(map[item[id]]);
28
21
  }
29
- child[children].push(array[i]);
30
- array.splice(i, 1);
31
- i == 0 ? i = 0 : i--;
32
- } else if (child[children]) {
33
- findIdsOfChildren(child);
34
- }
35
22
  });
36
- }
37
-
38
- function sortChildrensByPriority(unsorted_array) {
39
- unsorted_array.sort( (a, b) => a[priority] - b[priority])
40
- unsorted_array.forEach(element => {
41
- if(element[children]) {
42
- sortChildrensByPriority(element[children])
43
- }
44
- })
45
- }
46
-
47
- if(priority) {
48
- sortChildrensByPriority(array);
49
- }
50
-
51
- return array;
52
- }
23
+
24
+ const sortTreeByPriority = (nodes) => {
25
+ nodes.forEach((node) => {
26
+ if (node[children_property].length > 0) {
27
+ sortTreeByPriority(node[children_property]);
28
+ }
29
+ });
30
+
31
+ if (priority_property) {
32
+ nodes.sort((a, b) => {
33
+ const priorityA = a[priority_property] ?? Infinity;
34
+ const priorityB = b[priority_property] ?? Infinity;
35
+ return priorityA - priorityB;
36
+ });
37
+ }
38
+ };
39
+
40
+ sortTreeByPriority(roots);
41
+
42
+ const cleanEmptyChildren = (nodes) => {
43
+ nodes.forEach((node) => {
44
+ if (node[children_property].length === 0) {
45
+ delete node[children_property];
46
+ } else {
47
+ cleanEmptyChildren(node[children_property]);
48
+ }
49
+ });
50
+ };
51
+
52
+ cleanEmptyChildren(roots);
53
+
54
+ return roots;
55
+ };