@gudhub/core 1.0.68 → 1.1.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.
- package/GUDHUB/AppProcessor/AppProcessor.js +12 -0
- package/GUDHUB/GHConstructor/createAngularModuleInstance.js +170 -109
- package/GUDHUB/GHConstructor/createClassInstance.js +44 -4
- package/GUDHUB/GHConstructor/ghconstructor.js +16 -6
- package/GUDHUB/Storage/ModulesList.js +5 -0
- package/GUDHUB/Utils/AppsTemplateService/AppsTemplateService.js +526 -0
- package/GUDHUB/Utils/FIleHelper/FileHelper.js +69 -0
- package/GUDHUB/Utils/MergeFields/MergeFields.js +20 -11
- package/GUDHUB/Utils/Utils.js +20 -0
- package/GUDHUB/gudhub-https-service.js +30 -32
- package/GUDHUB/gudhub.js +1 -7
- package/package.json +1 -1
- package/umd/library.min.js +21 -15
- package/umd/library.min.js.map +1 -1
|
@@ -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
|
|
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
|
|
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
|
-
//
|
|
67
|
-
//
|
|
68
|
-
//
|
|
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
|
-
|
|
73
|
+
/*** TODO ***/
|
|
74
|
+
// Need to make angular modules instances creation similar to pure js classes.
|
|
71
75
|
|
|
72
|
-
|
|
76
|
+
export default async function createAngularModuleInstance(module_id, module_url, angularInjector, nodeWindow) {
|
|
73
77
|
|
|
74
|
-
|
|
75
|
-
await angularInjector.get('$ocLazyLoad').load(module_url);
|
|
76
|
-
}
|
|
78
|
+
try {
|
|
77
79
|
|
|
78
|
-
|
|
80
|
+
let angularModule;
|
|
81
|
+
let importedClass;
|
|
79
82
|
|
|
80
|
-
|
|
81
|
-
// Result of eval will be in factory returns object, with key == module_id
|
|
83
|
+
if (IS_WEB) {
|
|
82
84
|
|
|
83
|
-
|
|
84
|
-
module = module.data;
|
|
85
|
+
// Download module with $ocLazyLoad if module not in injector already.
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
|
|
93
|
-
type: module_id,
|
|
91
|
+
angularModule = await angularInjector.get(module_id);
|
|
94
92
|
|
|
95
|
-
|
|
93
|
+
// Then, dynamically import modules from url.
|
|
96
94
|
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
107
|
+
} else {
|
|
117
108
|
|
|
118
|
-
|
|
119
|
-
|
|
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
|
-
|
|
119
|
+
// Downloading module's code and transform it to data url.
|
|
123
120
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
-
|
|
192
|
+
//*************** GET INTERPRETATION ****************//
|
|
143
193
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
194
|
+
getInterpretation: function (value, interpretation_id, dataType, field, itemId, appId) {
|
|
195
|
+
return new Promise(async (resolve) => {
|
|
196
|
+
let currentDataType = importedClass;
|
|
147
197
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
202
|
+
let result = await data.content()
|
|
153
203
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
-
|
|
212
|
+
//*************** GET INTERPRETATIONS LIST ****************//
|
|
163
213
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
214
|
+
getInterpretationsList: function (field_value, appId, itemId, field) {
|
|
215
|
+
return importedClass.getInterpretation(field_value, appId, itemId, field);
|
|
216
|
+
},
|
|
167
217
|
|
|
168
|
-
|
|
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
|
-
|
|
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
|
-
|
|
235
|
+
if (IS_WEB) {
|
|
183
236
|
|
|
184
|
-
|
|
185
|
-
angularModule.getActionScope(actionScope);
|
|
186
|
-
},
|
|
237
|
+
//*************** EXTEND CONTROLLER ****************//
|
|
187
238
|
|
|
188
|
-
|
|
239
|
+
result.extendController = function (actionScope) {
|
|
240
|
+
angularModule.getActionScope(actionScope);
|
|
241
|
+
}
|
|
189
242
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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
|
-
|
|
259
|
+
//*************** GET WINDOW HTML ****************//
|
|
260
|
+
|
|
261
|
+
result.getWindowHTML = function (scope) {
|
|
262
|
+
return angularModule.getWindowHTML(scope);
|
|
263
|
+
}
|
|
199
264
|
|
|
200
|
-
|
|
201
|
-
return angularModule.getWindowScope(windowScope);
|
|
202
|
-
},
|
|
265
|
+
}
|
|
203
266
|
|
|
204
|
-
|
|
267
|
+
return result;
|
|
205
268
|
|
|
206
|
-
|
|
207
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
//
|
|
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
|
|
13
|
-
// If not, check if module is in cache. If not, create new instance and put loading to modules
|
|
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);
|
|
@@ -518,6 +518,11 @@ export default function generateModulesList(async_modules_path, file_server_url)
|
|
|
518
518
|
js: "https://gudhub.com/modules/Nested-List/dist/main.js",
|
|
519
519
|
css: "https://gudhub.com/modules/Nested-List/dist/style.css",
|
|
520
520
|
type: 'class'
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
name: "countertop_smart_quote",
|
|
524
|
+
url: file_server_url + '/' + async_modules_path + "countertop_smart_quote.js",
|
|
525
|
+
type: 'angular'
|
|
521
526
|
}
|
|
522
527
|
]
|
|
523
528
|
}
|