@gudhub/core 1.0.69 → 1.1.1

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.
@@ -177,6 +177,18 @@ export class AppProcessor {
177
177
  console.log("Apps refreshed: ", JSON.stringify(apps_id));
178
178
  }
179
179
 
180
+ async refreshAppsList() {
181
+ let currentAppsList = this.getAppListFromStorage();
182
+ let appsListFromApi = await this.getAppListApi();
183
+ let mergedAppsList = appsListFromApi.map(apiApp => {
184
+ return { ...apiApp, ...currentAppsList.find(app => app.app_id === apiApp.app_id) }
185
+ })
186
+
187
+ this.updateAppsListInStorage(mergedAppsList);
188
+
189
+ this.pipeService.emit('gh_apps_list_refreshed', {});
190
+ }
191
+
180
192
  async getAppsList() {
181
193
  let app_list = this.getAppListFromStorage();
182
194
  if (!this.applistReceived) {
@@ -1,7 +1,8 @@
1
1
  import axios from 'axios';
2
+ import { IS_WEB } from './../consts.js';
2
3
 
3
4
  /*************** FAKE ANGULAR $Q ***************/
4
- // It's needed when we eval() angular code.
5
+ // It's needed when we import angular code.
5
6
 
6
7
  let $q = {
7
8
  when: function (a) {
@@ -12,7 +13,7 @@ let $q = {
12
13
  }
13
14
 
14
15
  /*************** FAKE ANGULAR ***************/
15
- // It's needed when we eval() angular code.
16
+ // It's needed when we import angular code.
16
17
 
17
18
  let factoryReturns = {};
18
19
 
@@ -63,150 +64,210 @@ let angular = {
63
64
  }
64
65
 
65
66
  /*************** CREATE INSTANCE ***************/
66
- // Get angular module and module's code.
67
- // Then eval() module's code.
68
- // Finally, creating instance of module, using functions from angular module and evaled code.
67
+ // Here we are importing modules using dynamic import.
68
+ // For browser: just do dynamic import with url as parameter.
69
+ // In node environment we can't dynamically import module from url, so we download module's code via axios and transform it to data url.
70
+ // Then creating classes from imported modules.
71
+ // Finally, creating instance of module, using functions from imported classes. If we in browser - also takes methods from angular's injector.
69
72
 
70
- export default async function createAngularModuleInstance(module_id, module_url, angularInjector) {
73
+ /*** TODO ***/
74
+ // Need to make angular modules instances creation similar to pure js classes.
71
75
 
72
- // If $injector don't have module with this id, than loadding this module using $oxLazyLoad
76
+ export default async function createAngularModuleInstance(module_id, module_url, angularInjector, nodeWindow) {
73
77
 
74
- if (!angularInjector.has(module_id)) {
75
- await angularInjector.get('$ocLazyLoad').load(module_url);
76
- }
78
+ try {
77
79
 
78
- let angularModule = await angularInjector.get(module_id);
80
+ let angularModule;
81
+ let importedClass;
79
82
 
80
- // Downloading module's code as text via axios and evaling it
81
- // Result of eval will be in factory returns object, with key == module_id
83
+ if (IS_WEB) {
82
84
 
83
- let module = await axios.get(module_url);
84
- module = module.data;
85
+ // Download module with $ocLazyLoad if module not in injector already.
85
86
 
86
- try {
87
- eval(module);
88
- } catch (error) {
89
- console.error('ERROR WHILE EVAL() IN GHCONSTRUCTOR', error);
90
- }
87
+ if (!angularInjector.has(module_id)) {
88
+ await angularInjector.get('$ocLazyLoad').load(module_url);
89
+ }
91
90
 
92
- let result = {
93
- type: module_id,
91
+ angularModule = await angularInjector.get(module_id);
94
92
 
95
- //*************** GET TEMPLATE ****************//
93
+ // Then, dynamically import modules from url.
96
94
 
97
- getTemplate: function (ref, changeFieldName, displayFieldName, field_model, appId, itemId) {
98
- let displayFieldNameChecked = displayFieldName === 'false' ? false : true;
99
- return angularModule.getTemplate(ref, changeFieldName, displayFieldNameChecked, field_model, appId, itemId);
100
- },
95
+ let module = await axios.get(module_url);
96
+ module = module.data;
101
97
 
102
- //*************** GET DEFAULT VALUE ****************//
98
+ try {
99
+ eval(module);
100
+ } catch (error) {
101
+ console.error(`ERROR WHILE EVAL() IN GHCONSTRUCTOR. MODULE ID: ${module_id}`);
102
+ console.log(error);
103
+ }
103
104
 
104
- getDefaultValue: function (fieldModel, valuesArray, itemsList, currentAppId) {
105
- return new Promise(async (resolve) => {
106
- let getValueFunction = angularModule.getDefaultValue;
107
- if (getValueFunction) {
108
- let value = await getValueFunction(fieldModel, valuesArray, itemsList, currentAppId);
109
- resolve(value);
110
- } else {
111
- resolve(null);
112
- }
113
- });
114
- },
105
+ importedClass = factoryReturns[module_id];
115
106
 
116
- //*************** GET SETTINGS ****************//
107
+ } else {
117
108
 
118
- getSettings: function (scope, settingType, fieldModels) {
119
- return angularModule.getSettings(scope, settingType, fieldModels);
120
- },
109
+ // If node's global object don't have window and it's methods yet - set it.
110
+ if (!global.hasOwnProperty('window')) {
111
+ global.window = nodeWindow;
112
+ global.document = nodeWindow.document;
113
+ global.Element = nodeWindow.Element;
114
+ global.navigator = nodeWindow.navigator;
115
+ global.HTMLElement = nodeWindow.HTMLElement;
116
+ global.angular = angular;
117
+ }
121
118
 
122
- //*************** FILTER****************//
119
+ // Downloading module's code and transform it to data url.
123
120
 
124
- filter: {
125
- getSearchOptions: function (fieldModel) {
126
- let d_type = angularModule;
127
- if (d_type.filter && d_type.filter.getSearchOptions) {
128
- return angularModule.filter.getSearchOptions(fieldModel);
129
- }
130
- return [];
121
+ let response = await axios.get(module_url);
122
+ let code = response.data;
123
+ let encodedCode = encodeURIComponent(code);
124
+ encodedCode = 'data:text/javascript;charset=utf-8,' + encodedCode;
125
+
126
+ let module;
127
+
128
+ // Then, dynamically import modules from data url.
129
+
130
+ try {
131
+ module = await import(/* webpackIgnore: true */encodedCode);
132
+ } catch (err) {
133
+ console.log(`Error while importing module: ${module_id}`);
134
+ }
135
+
136
+ // Modules always exports classes as default, so we create new class instance.
137
+
138
+ importedClass = new module.default();
139
+
140
+ }
141
+
142
+ let result = {
143
+ type: module_id,
144
+
145
+ //*************** GET TEMPLATE ****************//
146
+
147
+ getTemplate: function (ref, changeFieldName, displayFieldName, field_model, appId, itemId) {
148
+ let displayFieldNameChecked = displayFieldName === 'false' ? false : true;
149
+ return importedClass.getTemplate(ref, changeFieldName, displayFieldNameChecked, field_model, appId, itemId);
150
+ },
151
+
152
+ //*************** GET DEFAULT VALUE ****************//
153
+
154
+ getDefaultValue: function (fieldModel, valuesArray, itemsList, currentAppId) {
155
+ return new Promise(async (resolve) => {
156
+ let getValueFunction = importedClass.getDefaultValue;
157
+ if (getValueFunction) {
158
+ let value = await getValueFunction(fieldModel, valuesArray, itemsList, currentAppId);
159
+ resolve(value);
160
+ } else {
161
+ resolve(null);
162
+ }
163
+ });
164
+ },
165
+
166
+ //*************** GET SETTINGS ****************//
167
+
168
+ getSettings: function (scope, settingType, fieldModels) {
169
+ return importedClass.getSettings(scope, settingType, fieldModels);
131
170
  },
132
- getDropdownValues: function () {
133
- let d_type = angularModule;
134
- if (d_type.filter && d_type.filter.getDropdownValues) {
135
- return d_type.filter.getDropdownValues();
136
- } else {
171
+
172
+ //*************** FILTER****************//
173
+
174
+ filter: {
175
+ getSearchOptions: function (fieldModel) {
176
+ let d_type = importedClass;
177
+ if (d_type.filter && d_type.filter.getSearchOptions) {
178
+ return importedClass.filter.getSearchOptions(fieldModel) || null;
179
+ }
137
180
  return [];
181
+ },
182
+ getDropdownValues: function () {
183
+ let d_type = importedClass;
184
+ if (d_type.filter && d_type.filter.getDropdownValues) {
185
+ return d_type.filter.getDropdownValues() || null;
186
+ } else {
187
+ return [];
188
+ }
138
189
  }
139
- }
140
- },
190
+ },
141
191
 
142
- //*************** GET INTERPRETATION ****************//
192
+ //*************** GET INTERPRETATION ****************//
143
193
 
144
- getInterpretation: function (value, interpretation_id, dataType, field, itemId, appId) {
145
- return new Promise(async (resolve) => {
146
- let currentDataType = factoryReturns[module_id];
194
+ getInterpretation: function (value, interpretation_id, dataType, field, itemId, appId) {
195
+ return new Promise(async (resolve) => {
196
+ let currentDataType = importedClass;
147
197
 
148
- try {
149
- let interpr_arr = await currentDataType.getInterpretation(value, appId, itemId, field, dataType);
150
- let data = interpr_arr.find((item) => item.id == interpretation_id) || interpr_arr.find((item) => item.id == 'default');
198
+ try {
199
+ let interpr_arr = await currentDataType.getInterpretation(value, appId, itemId, field, dataType);
200
+ let data = interpr_arr.find((item) => item.id == interpretation_id) || interpr_arr.find((item) => item.id == 'default');
151
201
 
152
- let result = await data.content()
202
+ let result = await data.content()
153
203
 
154
- resolve({ html: result });
155
- } catch (error) {
156
- console.log(`ERROR IN ${module_id}`, error);
157
- resolve({ html: '<span>no interpretation</span>' })
158
- }
159
- });
160
- },
204
+ resolve({ html: result });
205
+ } catch (error) {
206
+ console.log(`ERROR IN ${module_id}`, error);
207
+ resolve({ html: '<span>no interpretation</span>' })
208
+ }
209
+ });
210
+ },
161
211
 
162
- //*************** GET INTERPRETATIONS LIST ****************//
212
+ //*************** GET INTERPRETATIONS LIST ****************//
163
213
 
164
- getInterpretationsList: function (field_value, appId, itemId, field) {
165
- return factoryReturns[module_id].getInterpretation(field_value, appId, itemId, field);
166
- },
214
+ getInterpretationsList: function (field_value, appId, itemId, field) {
215
+ return importedClass.getInterpretation(field_value, appId, itemId, field);
216
+ },
167
217
 
168
- //*************** GET INTERPRETATED VALUE ****************//
218
+ //*************** GET INTERPRETATED VALUE ****************//
219
+
220
+ getInterpretatedValue: function (field_value, field_model, appId, itemId) {
221
+ return new Promise(async (resolve) => {
222
+ let getInterpretatedValueFunction = importedClass.getInterpretatedValue;
223
+ if (getInterpretatedValueFunction) {
224
+ let value = await getInterpretatedValueFunction(field_value, field_model, appId, itemId);
225
+ resolve(value);
226
+ } else {
227
+ resolve(field_value);
228
+ }
229
+ });
230
+ },
231
+ }
169
232
 
170
- getInterpretatedValue: function (field_value, field_model, appId, itemId) {
171
- return new Promise(async (resolve) => {
172
- let getInterpretatedValueFunction = factoryReturns[module_id].getInterpretatedValue;
173
- if (getInterpretatedValueFunction) {
174
- let value = await getInterpretatedValueFunction(field_value, field_model, appId, itemId);
175
- resolve(value);
176
- } else {
177
- resolve(field_value);
178
- }
179
- });
180
- },
233
+ // We need these methods in browser environment only
181
234
 
182
- //*************** EXTEND CONTROLLER ****************//
235
+ if (IS_WEB) {
183
236
 
184
- extendController: function (actionScope) {
185
- angularModule.getActionScope(actionScope);
186
- },
237
+ //*************** EXTEND CONTROLLER ****************//
187
238
 
188
- //*************** RUN ACTION ****************//
239
+ result.extendController = function (actionScope) {
240
+ angularModule.getActionScope(actionScope);
241
+ }
189
242
 
190
- runAction: function (scope) {
191
- try {
192
- angularModule.runAction(scope);
193
- } catch (e) {
243
+ //*************** RUN ACTION ****************//
244
+
245
+ result.runAction = function (scope) {
246
+ try {
247
+ angularModule.runAction(scope);
248
+ } catch (e) {
249
+
250
+ }
251
+ }
252
+
253
+ //*************** GET WINDOW SCOPE ****************//
194
254
 
255
+ result.getWindowScope = function (windowScope) {
256
+ return angularModule.getWindowScope(windowScope);
195
257
  }
196
- },
197
258
 
198
- //*************** GET WINDOW SCOPE ****************//
259
+ //*************** GET WINDOW HTML ****************//
260
+
261
+ result.getWindowHTML = function (scope) {
262
+ return angularModule.getWindowHTML(scope);
263
+ }
199
264
 
200
- getWindowScope: function (windowScope) {
201
- return angularModule.getWindowScope(windowScope);
202
- },
265
+ }
203
266
 
204
- //*************** GET WINDOW HTML ****************//
267
+ return result;
205
268
 
206
- getWindowHTML: function (scope) {
207
- return angularModule.getWindowHTML(scope);
208
- },
269
+ } catch (err) {
270
+ console.log(err);
271
+ console.log(`Failed in createAngularModuleInstance (ghconstructor). Module id: ${module_id}.`);
209
272
  }
210
-
211
- return result;
212
273
  }
@@ -1,4 +1,9 @@
1
- export default async function createClassInstance(module_id, js_url, css_url) {
1
+ import axios from 'axios';
2
+ import { IS_WEB } from './../consts.js';
3
+
4
+ export default async function createClassInstance(module_id, js_url, css_url, nodeWindow) {
5
+
6
+ try {
2
7
 
3
8
  // Check if there is url to javascript file of module
4
9
 
@@ -8,16 +13,46 @@ export default async function createClassInstance(module_id, js_url, css_url) {
8
13
 
9
14
  // Import module using dynamic import
10
15
 
11
- let module = await import(/* webpackIgnore: true */js_url);
16
+ let downloadModule = (url) => {
17
+ if (!IS_WEB && !global.hasOwnProperty('window')) {
18
+ global.window = nodeWindow;
19
+ global.document = nodeWindow.document;
20
+ global.Element = nodeWindow.Element;
21
+ global.navigator = nodeWindow.navigator;
22
+ global.HTMLElement = nodeWindow.HTMLElement;
23
+ }
24
+ return new Promise(async (resolve) => {
25
+ let moduleData = await axios.get(url).catch(err => {
26
+ console.log(`Failed to fetch: ${url} in ghconstructor. Module id: ${module_id}`);
27
+ })
28
+
29
+ let encodedJs = encodeURIComponent(moduleData.data);
30
+
31
+ let dataUri = 'data:text/javascript;charset=utf-8,' + encodedJs;
32
+
33
+ resolve(dataUri);
34
+ })
35
+ }
36
+
37
+ let moduleData = await downloadModule(js_url);
38
+
39
+ let module;
40
+
41
+ try {
42
+ module = await import(/* webpackIgnore: true */moduleData);
43
+ } catch (err) {
44
+ console.log(`Error while importing module: ${module_id}`);
45
+ console.log(err);
46
+ }
12
47
 
13
48
  // Creating class from imported module
14
49
 
15
50
  let importedClass = new module.default(module_id);
16
51
 
17
- // Checl if there is url to css file of module
52
+ // Check if there is url to css file of module
18
53
  // If true, and there is no css for this data type, than create link tag to this css in head
19
54
 
20
- if(css_url) {
55
+ if(css_url && IS_WEB) {
21
56
  const linkTag = document.createElement('link');
22
57
  linkTag.href = css_url;
23
58
  linkTag.setAttribute('data-module', module_id);
@@ -145,4 +180,9 @@ export default async function createClassInstance(module_id, js_url, css_url) {
145
180
  }
146
181
 
147
182
  return result;
183
+
184
+ } catch(err) {
185
+ console.log(err);
186
+ console.log(`Failed in createClassInstance (ghconstructor). Module id: ${module_id}. JS url: ${js_url}`);
187
+ }
148
188
  }
@@ -2,15 +2,17 @@ import createAngularModuleInstance from './createAngularModuleInstance.js';
2
2
  import createClassInstance from './createClassInstance.js';
3
3
 
4
4
  export class GHConstructor {
5
- constructor() {
5
+ constructor(gudhub) {
6
+ this.gudhub = gudhub;
6
7
  this.cache = [];
7
8
  this.modulesQueue = {};
8
9
  this.angularInjector;
10
+ this.nodeWindow;
9
11
  }
10
12
 
11
13
  /*************** GET INSTANCE ***************/
12
- // Firstly, check if module is loading right now in modules query.
13
- // If not, check if module is in cache. If not, create new instance and put loading to modules query.
14
+ // Firstly, check if module is loading right now in modules queue.
15
+ // If not, check if module is in cache. If not, create new instance and put loading to modules queue.
14
16
  // If yes, return module from cache.
15
17
 
16
18
  async getInstance(module_id) {
@@ -52,19 +54,27 @@ export class GHConstructor {
52
54
  this.angularInjector = angularInjector;
53
55
  }
54
56
 
57
+ /*************** INIT JSDOM WINDOW ***************/
58
+ // Saves jsdom's window object to this.window.
59
+ // It's needed to eval browser code on node when library works in node environment.
60
+
61
+ initJsdomWindow(window) {
62
+ this.nodeWindow = window;
63
+ }
64
+
55
65
  /*************** CREATE INSTANCE ***************/
56
66
  // Check if module is "angular" or "class"
57
67
  // Than, creating instance for that type of module
58
68
  // Finally, returns the result (created instance) and puting it to the cache
59
69
 
60
70
  async createInstance(module_id) {
61
- let module = gudhub.storage.getModuleUrl(module_id);
71
+ let module = this.gudhub.storage.getModuleUrl(module_id);
62
72
 
63
73
  let result;
64
74
  if (module.type === 'angular') {
65
- result = await createAngularModuleInstance(module_id, module.url, this.angularInjector);
75
+ result = await createAngularModuleInstance(module_id, module.url, this.angularInjector, this.nodeWindow);
66
76
  } else if(module.type === 'class') {
67
- result = await createClassInstance(module_id, module.js, module.css);
77
+ result = await createClassInstance(module_id, module.js, module.css, this.nodeWindow);
68
78
  }
69
79
 
70
80
  this.pupToCache(result);