@ind-rcg/backend 246.1008.0
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/LICENSE.md +37 -0
- package/README.md +7 -0
- package/bin/libsqliteExtension.dll +0 -0
- package/bin/libsqliteExtension.dylib +0 -0
- package/binding.gyp +21 -0
- package/configuration.template.json +24 -0
- package/log4js.json +11 -0
- package/nativeSrc/PriceEngineWrap.cc +157 -0
- package/nativeSrc/PriceEngineWrap.h +24 -0
- package/nativeSrc/common/DBAccess/SimpleDBConnection.cpp +800 -0
- package/nativeSrc/common/DBAccess/SimpleDBConnection.h +54 -0
- package/nativeSrc/common/Libs/cJSON/CHANGELOG.md +428 -0
- package/nativeSrc/common/Libs/cJSON/LICENSE +20 -0
- package/nativeSrc/common/Libs/cJSON/README.md +571 -0
- package/nativeSrc/common/Libs/cJSON/cJSON.c +3110 -0
- package/nativeSrc/common/Libs/cJSON/cJSON.h +293 -0
- package/nativeSrc/common/Libs/sqlcipher/sqlite3.c +241624 -0
- package/nativeSrc/common/Libs/sqlcipher/sqlite3.h +12836 -0
- package/nativeSrc/common/Libs/sqlcipher/sqlite3ext.h +701 -0
- package/nativeSrc/common/LogAdapter/LogAdapter.cpp +25 -0
- package/nativeSrc/common/LogAdapter/LogAdapter.h +20 -0
- package/nativeSrc/common/PriceEngine/PriceEngine.cpp +251 -0
- package/nativeSrc/common/PriceEngine/PriceEngine.h +67 -0
- package/nativeSrc/common/Utils/StringFormat.cpp +905 -0
- package/nativeSrc/common/Utils/StringFormat.h +116 -0
- package/nativeSrc/common/Utils/miniz/timer.cpp +165 -0
- package/nativeSrc/common/Utils/miniz/timer.h +40 -0
- package/nativeSrc/common/stdngm.h +92 -0
- package/nativeSrc/nativeWrapper.cc +15 -0
- package/package.json +70 -0
- package/src/argsParser.js +73 -0
- package/src/bootstrap.js +156 -0
- package/src/fsHelper.js +36 -0
- package/src/globalConfig.js +23 -0
- package/src/local.js +546 -0
- package/src/server.js +64 -0
- package/src/sfAttachmentsHandler.js +283 -0
- package/src/utils.js +91 -0
- package/src/zipHandler.js +153 -0
package/src/local.js
ADDED
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* FILE_HEADER
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
const sqlite3 = require("sqlite3");
|
|
8
|
+
const TransactionDatabase = require("sqlite3-transactions").TransactionDatabase;
|
|
9
|
+
const fs = require("fs");
|
|
10
|
+
const path = require("path");
|
|
11
|
+
|
|
12
|
+
const log = require('log4js').getLogger("local");
|
|
13
|
+
const _ = require('lodash');
|
|
14
|
+
let db;
|
|
15
|
+
const mobileNativeCode = require('bindings')('mobileNativeCode.node');
|
|
16
|
+
const GlobalConfig = require('./globalConfig');
|
|
17
|
+
const os = require('os');
|
|
18
|
+
const SFAttachmentsHandler = require("./sfAttachmentsHandler");
|
|
19
|
+
const ZipHandler = require('./zipHandler');
|
|
20
|
+
const Utils = require("./utils");
|
|
21
|
+
|
|
22
|
+
let priceEngine;
|
|
23
|
+
|
|
24
|
+
const loadExtensionAsync = (distanceDatabaseExtension) => {
|
|
25
|
+
return new Promise(function(resolve, reject) {
|
|
26
|
+
db.loadExtension(distanceDatabaseExtension, function (status) {
|
|
27
|
+
if (_.isNil(status)) {
|
|
28
|
+
resolve();
|
|
29
|
+
} else {
|
|
30
|
+
reject(status);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
let initialize = (webServerConfig) => {
|
|
37
|
+
// get db file (path) from config
|
|
38
|
+
let file = webServerConfig.database;
|
|
39
|
+
priceEngine = new mobileNativeCode.PriceEngineWrap();
|
|
40
|
+
|
|
41
|
+
if (!fs.existsSync(file)) {
|
|
42
|
+
log.error("DB file", file, "does not exist!");
|
|
43
|
+
return Promise.reject(false);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const openDBResponse = priceEngine.openDbConnection(file);
|
|
47
|
+
|
|
48
|
+
//failed to open db connection
|
|
49
|
+
if(!openDBResponse.success) {
|
|
50
|
+
log.error(`We couldn’t complete the openDbConnection operation. Try again or contact Salesforce Support and provide the error details: ${JSON.stringify(openDBResponse?.results?.messages)}`);
|
|
51
|
+
return Promise.reject(false);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// console.log("before " + file);
|
|
55
|
+
db = new sqlite3.Database(file, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE);
|
|
56
|
+
//console.log("after " + file);
|
|
57
|
+
log.info("The local database", file, "started successfully.");
|
|
58
|
+
|
|
59
|
+
//retrieves the path to the node module in each case (sfdx plugin / local development)
|
|
60
|
+
let sqlLiteExtensionModulePath = path.join(path.dirname(__filename), '..', 'bin');
|
|
61
|
+
|
|
62
|
+
let distanceDatabaseExtension = os.type() === "Darwin" ?
|
|
63
|
+
path.join(sqlLiteExtensionModulePath, "libsqliteExtension.dylib"):
|
|
64
|
+
path.join(sqlLiteExtensionModulePath, "libsqliteExtension.dll");
|
|
65
|
+
|
|
66
|
+
if (!fs.existsSync(distanceDatabaseExtension)) {
|
|
67
|
+
log.error("DB extension", distanceDatabaseExtension, "not found. SQL distance() function will not be available.");
|
|
68
|
+
return Promise.resolve(true);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return loadExtensionAsync(distanceDatabaseExtension)
|
|
72
|
+
.then(() => {
|
|
73
|
+
log.info("The database extension loaded successfully. The SQL operator DISTANCE() is ready for use in the server.");
|
|
74
|
+
return Promise.resolve(true);
|
|
75
|
+
})
|
|
76
|
+
.catch((err) => {
|
|
77
|
+
log.error("Couldn't load the database extension. The SQL operator DISTANCE() is unavailable for use in the server. "+
|
|
78
|
+
"Try again or contact Salesforce Support with the status code:", err);
|
|
79
|
+
return Promise.resolve(true);
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
let closeDBConnection = () => {
|
|
86
|
+
//closing the db connection
|
|
87
|
+
const closeDBResponse = priceEngine.closeDbConnection();
|
|
88
|
+
|
|
89
|
+
//failure occurred
|
|
90
|
+
if(!closeDBResponse.success) {
|
|
91
|
+
log.error(`We couldn’t complete the closeDbConnection operation. Try again or contact Salesforce Support and provide the error details: ${JSON.stringify(closeDBResponse?.results?.messages)}`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return closeDBResponse.success;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
let sendResponse = (startTime, resultSet, res) => {
|
|
98
|
+
log.debug("OVERALL EXECUTION TIME:", new Date() - startTime, "ms");
|
|
99
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
100
|
+
res.end(JSON.stringify(resultSet));
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
let execCall = (payload, res) => {
|
|
104
|
+
const queries = payload.workload instanceof Array ? payload.workload : [payload.workload];
|
|
105
|
+
log.debug(`/exec REQUEST WITH ${queries.length} `);
|
|
106
|
+
const startTime = new Date();
|
|
107
|
+
let exec = function (dbRef, queriesRef, execCb) {
|
|
108
|
+
let results = [],
|
|
109
|
+
querysLength = queries.length;
|
|
110
|
+
return queriesRef.forEach(function (queryEle, i) {
|
|
111
|
+
let query = Utils.sanitizeQuery(queryEle);
|
|
112
|
+
let qid;
|
|
113
|
+
let params;
|
|
114
|
+
if (_.isObject(query)) {
|
|
115
|
+
params = query.parameters;
|
|
116
|
+
qid = query.qid;
|
|
117
|
+
query = query.query;
|
|
118
|
+
}
|
|
119
|
+
log.debug("QUERY", i, ":", JSON.stringify(query));
|
|
120
|
+
if (!query) return;
|
|
121
|
+
query = query.trim();
|
|
122
|
+
let cb = function(err){
|
|
123
|
+
let result = {
|
|
124
|
+
"result": true
|
|
125
|
+
};
|
|
126
|
+
if(!_.isUndefined(qid))
|
|
127
|
+
result.qid = qid;
|
|
128
|
+
if(err){
|
|
129
|
+
result.result = false;
|
|
130
|
+
result.rowsAffected = 0;
|
|
131
|
+
}else{
|
|
132
|
+
result.rowsAffected = this.changes;
|
|
133
|
+
}
|
|
134
|
+
if(results.push(result) === querysLength)
|
|
135
|
+
execCb(results);
|
|
136
|
+
};
|
|
137
|
+
if (params) {
|
|
138
|
+
let stmt = dbRef.prepare(query);
|
|
139
|
+
stmt.run(params, cb);
|
|
140
|
+
} else {
|
|
141
|
+
dbRef.run(query, cb);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
};
|
|
145
|
+
if (_.isEmpty(queries)) {
|
|
146
|
+
log.debug("The request is empty. Provide a valid request and try again.");
|
|
147
|
+
sendResponse(startTime, { success: true, results: [] }, res);
|
|
148
|
+
} else if (payload.transaction === "1") {
|
|
149
|
+
log.debug("OPENING A TRANSACTION...");
|
|
150
|
+
let tranDb = new TransactionDatabase(db);
|
|
151
|
+
tranDb.beginTransaction(function (err, T) {
|
|
152
|
+
if (err) log.error("Error opening transaction!", err);
|
|
153
|
+
else {
|
|
154
|
+
exec(T, queries, results => {
|
|
155
|
+
T.commit(function (error) {
|
|
156
|
+
if (error) {
|
|
157
|
+
log.error("Transaction commit failed!", error);
|
|
158
|
+
T.rollback();
|
|
159
|
+
sendResponse(startTime, { success: false, results: error.message }, res);
|
|
160
|
+
return;
|
|
161
|
+
} else {
|
|
162
|
+
log.debug("Transaction committed successfully!");
|
|
163
|
+
sendResponse(startTime, { success: true, results: results }, res);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
} else {
|
|
170
|
+
exec(db, queries, results => {
|
|
171
|
+
sendResponse(startTime, { success: true, results: results }, res);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
let queryCall = (payload, res) => {
|
|
177
|
+
const query = payload.workload;
|
|
178
|
+
if (!query) return;
|
|
179
|
+
|
|
180
|
+
const anchor_id = payload.anchor_id;
|
|
181
|
+
|
|
182
|
+
const result = {
|
|
183
|
+
"anchor_id": anchor_id,
|
|
184
|
+
"success": true
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
log.debug("/query", "REQUEST RECEIVED");
|
|
188
|
+
const startTime = new Date();
|
|
189
|
+
|
|
190
|
+
let getQueryFn = queryRef => {
|
|
191
|
+
if (queryRef.parameters) {
|
|
192
|
+
const params = queryRef.parameters;
|
|
193
|
+
queryRef = queryRef.query.trim();
|
|
194
|
+
|
|
195
|
+
return cb => {
|
|
196
|
+
let stmt = db.prepare(queryRef, (resInner)=>{
|
|
197
|
+
if(resInner !== null){
|
|
198
|
+
//prepare failed
|
|
199
|
+
cb(resInner, []);
|
|
200
|
+
} else {
|
|
201
|
+
stmt.all(params, cb);
|
|
202
|
+
}
|
|
203
|
+
} );
|
|
204
|
+
};
|
|
205
|
+
} else {
|
|
206
|
+
queryRef = queryRef.trim();
|
|
207
|
+
return cb => db.all(queryRef, cb);
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
let fn;
|
|
212
|
+
if (_.isArray(query)) {
|
|
213
|
+
result.results = [];
|
|
214
|
+
const iterator = queryRef => {
|
|
215
|
+
if(queryRef.length > 0){
|
|
216
|
+
let currentQuery = queryRef.shift();
|
|
217
|
+
fn = getQueryFn(currentQuery);
|
|
218
|
+
fn(function (err, rows) {
|
|
219
|
+
log.debug("QUERY:", JSON.stringify(currentQuery));
|
|
220
|
+
if (err) {
|
|
221
|
+
result.success = false;
|
|
222
|
+
log.error("ERROR:", err);
|
|
223
|
+
result.results.push({
|
|
224
|
+
"qid": currentQuery.qid,
|
|
225
|
+
"result": err.message});
|
|
226
|
+
} else {
|
|
227
|
+
log.debug("ROWS RETURNED:", rows.length);
|
|
228
|
+
result.results.push({
|
|
229
|
+
"qid": currentQuery.qid,
|
|
230
|
+
"result": rows});
|
|
231
|
+
}
|
|
232
|
+
iterator(queryRef);
|
|
233
|
+
});
|
|
234
|
+
}else{
|
|
235
|
+
log.debug(JSON.stringify(result));
|
|
236
|
+
sendResponse(startTime, result, res);
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
iterator(query);
|
|
240
|
+
} else {
|
|
241
|
+
fn = getQueryFn(query);
|
|
242
|
+
fn(function (err, rows) {
|
|
243
|
+
log.debug("QUERY:", JSON.stringify(query));
|
|
244
|
+
if (err) {
|
|
245
|
+
result.success = false;
|
|
246
|
+
log.error("ERROR:", err);
|
|
247
|
+
result.results = err.message;
|
|
248
|
+
sendResponse(startTime, result, res);
|
|
249
|
+
} else {
|
|
250
|
+
log.debug("ROWS RETURNED:", rows.length);
|
|
251
|
+
result.results = rows;
|
|
252
|
+
log.debug(JSON.stringify(rows));
|
|
253
|
+
sendResponse(startTime, result, res);
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
let __mimeTypeToExtension = (mimeType) => {
|
|
260
|
+
const knownTypes = {
|
|
261
|
+
"image/png": "png",
|
|
262
|
+
"image/jpeg": "jpg",
|
|
263
|
+
"image/svg+xml": "svg",
|
|
264
|
+
"application/pdf": "pdf",
|
|
265
|
+
"application/zip": "zip"
|
|
266
|
+
|
|
267
|
+
};
|
|
268
|
+
return knownTypes[mimeType];
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
let __composeResponse = (targetFolder, newfileName, content, payload, res) => {
|
|
273
|
+
if (!fs.existsSync(targetFolder)) {
|
|
274
|
+
fs.mkdirSync(targetFolder);
|
|
275
|
+
}
|
|
276
|
+
fs.writeFileSync(path.join(targetFolder, newfileName), content);
|
|
277
|
+
sendResponse(new Date().getTime(), {
|
|
278
|
+
success: true,
|
|
279
|
+
performance: 0,
|
|
280
|
+
anchor_id: payload.anchor_id,
|
|
281
|
+
results: path.join(GlobalConfig.hesaFolder, newfileName)
|
|
282
|
+
}, res);
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
module.exports.performCall = (req, res) => {
|
|
286
|
+
|
|
287
|
+
// Checkmarx False Positive
|
|
288
|
+
// This function is only used on a developer machine to improve implementation speed. The data which will be retrieved by that
|
|
289
|
+
// function can be accessed over the developers file system anyway. This part of the application is only for internal developer
|
|
290
|
+
// purpose and not live outside.
|
|
291
|
+
let payload = req.body;
|
|
292
|
+
|
|
293
|
+
if (req.headers['content-type'] === 'application/octet-stream') {
|
|
294
|
+
payload = JSON.parse(req.body);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
log.debug(`Executing operation : ${payload.operation}`);
|
|
298
|
+
log.debug(`Payload : ${JSON.stringify(payload)}`);
|
|
299
|
+
|
|
300
|
+
if (payload.operation === 'executeBatch' || payload.operation === 'executeParameterized' || payload.operation === 'execute' ) {
|
|
301
|
+
execCall(payload, res);
|
|
302
|
+
} else if (payload.operation === 'select' || payload.operation === 'selectParameterized') {
|
|
303
|
+
queryCall(payload, res);
|
|
304
|
+
} else if (payload.operation === 'savePrintingData') {
|
|
305
|
+
log.debug('saving printing data for print:', payload.workload);
|
|
306
|
+
let printId = payload.workload[0];
|
|
307
|
+
let printData = payload.workload[1];
|
|
308
|
+
let printingDataFolder = 'Printing';
|
|
309
|
+
if (!fs.existsSync(printingDataFolder)) {
|
|
310
|
+
fs.mkdirSync(printingDataFolder);
|
|
311
|
+
}
|
|
312
|
+
let dataFile = path.join(printingDataFolder, (printId + '.json'));
|
|
313
|
+
fs.writeFileSync(dataFile, printData);
|
|
314
|
+
sendResponse(new Date().getTime(), {success: true, anchor_id: payload.anchor_id, results: []}, res);
|
|
315
|
+
} else if(payload.operation === 'saveDatasourceToggles') {
|
|
316
|
+
let toggleData = payload.workload[0];
|
|
317
|
+
let DataSourceGenerationFolder = 'DataSourceGeneration';
|
|
318
|
+
if (!fs.existsSync(DataSourceGenerationFolder)) {
|
|
319
|
+
fs.mkdirSync(DataSourceGenerationFolder);
|
|
320
|
+
}
|
|
321
|
+
let dataFile = path.join(DataSourceGenerationFolder, ('Toggles.json'));
|
|
322
|
+
let hasSucceeded = false;
|
|
323
|
+
try {
|
|
324
|
+
//Reparse to write the data in pretty print format
|
|
325
|
+
let toggleDataJSON = JSON.parse(toggleData);
|
|
326
|
+
fs.writeFileSync(dataFile, JSON.stringify(toggleDataJSON, null, 4));
|
|
327
|
+
hasSucceeded = true;
|
|
328
|
+
} catch (e) {
|
|
329
|
+
log.error("The saveDatasourceToggles operation failed. Review the exception details to fix the issue, or contact Salesforce Support for help.", e);
|
|
330
|
+
}
|
|
331
|
+
sendResponse(new Date().getTime(), {success: hasSucceeded, anchor_id: payload.anchor_id, results: []}, res);
|
|
332
|
+
} else if(payload.operation === 'saveDatasourceParameters') {
|
|
333
|
+
let boName = payload.workload[0];
|
|
334
|
+
let paramsData = payload.workload[1];
|
|
335
|
+
let DataSourceGenerationFolder = 'DataSourceGeneration';
|
|
336
|
+
if (!fs.existsSync(DataSourceGenerationFolder)) {
|
|
337
|
+
fs.mkdirSync(DataSourceGenerationFolder);
|
|
338
|
+
}
|
|
339
|
+
let dataFile = path.join(DataSourceGenerationFolder, (boName + '.json'));
|
|
340
|
+
let hasSucceeded = false;
|
|
341
|
+
try {
|
|
342
|
+
//Reparse to write the data in pretty print format
|
|
343
|
+
let paramsDataJSON = JSON.parse(paramsData);
|
|
344
|
+
fs.writeFileSync(dataFile, JSON.stringify(paramsDataJSON, null, 4));
|
|
345
|
+
hasSucceeded = true;
|
|
346
|
+
} catch (e) {
|
|
347
|
+
log.error("The saveDatasourceParameters operation failed. Review the exception details to fix the issue, or contact Salesforce Support for help.", e);
|
|
348
|
+
}
|
|
349
|
+
sendResponse(new Date().getTime(), {success: hasSucceeded, anchor_id: payload.anchor_id, results: []}, res);
|
|
350
|
+
} else if (payload.operation === 'saveAttachment') {
|
|
351
|
+
const dataUrl = payload.workload[0];
|
|
352
|
+
const blobPKey = payload.workload[2];
|
|
353
|
+
|
|
354
|
+
if (!Utils.isValidParamString(blobPKey) || !Utils.isValidParamString(payload.workload[1]) || !Utils.isValidString(dataUrl)) {
|
|
355
|
+
const invalidParamErrorMessage = "Invalid input parameters for saveAttachment. Check the input parameters and try again.";
|
|
356
|
+
log.error(invalidParamErrorMessage);
|
|
357
|
+
sendResponse(new Date().getTime(), { success: false, performance: 0, anchor_id: payload.anchor_id, results: false, error_message: invalidParamErrorMessage }, res);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const regex = /^data:(\w+\/[\w+]+);base64,(.+)$/;
|
|
361
|
+
const matches = dataUrl.match(regex);
|
|
362
|
+
const extension = __mimeTypeToExtension(matches[1]);
|
|
363
|
+
|
|
364
|
+
if (!Utils.isValidParamString(extension)) {
|
|
365
|
+
const errorMessage = "This isn’t a supported file extension. Specify a valid file extension and try again.";
|
|
366
|
+
log.error(errorMessage);
|
|
367
|
+
sendResponse(new Date().getTime(), { success: false, performance: 0, anchor_id: payload.anchor_id, results: false, error_message: errorMessage }, res);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const tableName = payload.workload[1] + GlobalConfig.BlobFolder;
|
|
371
|
+
const targetFolder = path.join(GlobalConfig.AttachmentsFolder, tableName);
|
|
372
|
+
const data = matches[2];
|
|
373
|
+
const buffer = Buffer.from(data, 'base64');
|
|
374
|
+
|
|
375
|
+
if (!fs.existsSync(targetFolder)) {
|
|
376
|
+
fs.mkdirSync(targetFolder);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
const filename = Utils.getSFFileName(blobPKey, extension);
|
|
380
|
+
fs.writeFileSync(path.join(targetFolder, filename), buffer);
|
|
381
|
+
sendResponse(new Date().getTime(), { success: true, performance: 0, anchor_id: payload.anchor_id, results: true }, res);
|
|
382
|
+
|
|
383
|
+
} else if(payload.operation === 'validateThemeZip') {
|
|
384
|
+
log.debug('validateThemeZip:', payload.workload);
|
|
385
|
+
ZipHandler.extractZipFiles(payload.workload[0])
|
|
386
|
+
.then((zip) => {
|
|
387
|
+
const results = ZipHandler.validateThemeZip(payload.workload[0], zip);
|
|
388
|
+
if (!results.isOk){
|
|
389
|
+
sendResponse(new Date().getTime(), { success: true, anchor_id: payload.anchor_id, results }, res);
|
|
390
|
+
} else {
|
|
391
|
+
sendResponse(new Date().getTime(), { success: true, anchor_id: payload.anchor_id, results }, res);
|
|
392
|
+
}
|
|
393
|
+
}, (details) => {
|
|
394
|
+
sendResponse(new Date().getTime(), {success: true, anchor_id: payload.anchor_id, results: { isOk: false, details }}, res);
|
|
395
|
+
});
|
|
396
|
+
} else if(payload.operation === 'extractThemeZip') {
|
|
397
|
+
log.debug('extractThemeZip:', payload.workload);
|
|
398
|
+
ZipHandler.extractZipFiles(payload.workload[0])
|
|
399
|
+
.then((zip) => {
|
|
400
|
+
ZipHandler.writeZipFilesOnMemory(zip).then(() => {
|
|
401
|
+
sendResponse(new Date().getTime(), {success: true, anchor_id: payload.anchor_id, results: { success: true, fileCache: ZipHandler.serializeZipAsJSON(zip) }}, res);
|
|
402
|
+
});
|
|
403
|
+
}, (details) => {
|
|
404
|
+
sendResponse(new Date().getTime(), {success: true, anchor_id: payload.anchor_id, results: { success: false, details }}, res);
|
|
405
|
+
});
|
|
406
|
+
} else if(payload.operation === 'saveSFFile') {
|
|
407
|
+
if (req && req.body && req.body.workload && req.body.workload.length === 4) {
|
|
408
|
+
SFAttachmentsHandler.saveSFFile(req.body.workload[0], req.body.workload[1], req.body.workload[2], req.body.workload[3])
|
|
409
|
+
.then((result) => {
|
|
410
|
+
sendResponse(new Date().getTime(), {
|
|
411
|
+
success: true,
|
|
412
|
+
performance: 0,
|
|
413
|
+
anchor_id: payload.anchor_id,
|
|
414
|
+
results: result
|
|
415
|
+
}, res);
|
|
416
|
+
})
|
|
417
|
+
.catch((errorMessage) => {
|
|
418
|
+
log.error("error saving SFFile! " + errorMessage);
|
|
419
|
+
sendResponse(new Date().getTime(), {success: false, performance: 0, anchor_id: payload.anchor_id, results: { "error_message": errorMessage}}, res);
|
|
420
|
+
});
|
|
421
|
+
} else {
|
|
422
|
+
const errorMessage = Utils.getParamsMissingErrorMessage(payload.operation);
|
|
423
|
+
log.error(errorMessage);
|
|
424
|
+
sendResponse(new Date().getTime(), {success: false, performance: 0, anchor_id: payload.anchor_id, results: { "error_message": errorMessage }}, res);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
} else if (payload.operation === 'readSFFile') {
|
|
428
|
+
if (req && req.body && req.body.workload && req.body.workload.length >= 2 && req.body.workload.length <= 3) {
|
|
429
|
+
const result = SFAttachmentsHandler.readSFFile(req.body.workload[0], req.body.workload[1], req.body.workload[2] ? req.body.workload[2] : false);
|
|
430
|
+
sendResponse(new Date().getTime(), {
|
|
431
|
+
success: result.success,
|
|
432
|
+
performance: 0,
|
|
433
|
+
anchor_id: payload.anchor_id,
|
|
434
|
+
results: result.results
|
|
435
|
+
}, res);
|
|
436
|
+
} else {
|
|
437
|
+
const errorMessage = Utils.getParamsMissingErrorMessage(payload.operation);
|
|
438
|
+
log.error(errorMessage);
|
|
439
|
+
sendResponse(new Date().getTime(), {success: false, performance: 0, anchor_id: payload.anchor_id, results: { "error_message": errorMessage }}, res);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
} else if (payload.operation === 'renameSFFile') {
|
|
443
|
+
if (req && req.body && req.body.workload && req.body.workload.length >= 3) {
|
|
444
|
+
let oldId = req.body.workload[0];
|
|
445
|
+
let fileType = req.body.workload[1];
|
|
446
|
+
let newId = req.body.workload[2];
|
|
447
|
+
|
|
448
|
+
const result = SFAttachmentsHandler.renameSFFile(oldId, fileType, newId);
|
|
449
|
+
sendResponse(new Date().getTime(), {
|
|
450
|
+
success: result.success,
|
|
451
|
+
performance: 0,
|
|
452
|
+
anchor_id: payload.anchor_id,
|
|
453
|
+
results: result.results
|
|
454
|
+
}, res);
|
|
455
|
+
} else {
|
|
456
|
+
const errorMessage = Utils.getParamsMissingErrorMessage(payload.operation);
|
|
457
|
+
log.error(errorMessage);
|
|
458
|
+
sendResponse(new Date().getTime(), {success: false, performance: 0, anchor_id: payload.anchor_id, results: { "error_message": errorMessage }}, res);
|
|
459
|
+
}
|
|
460
|
+
} else if (payload.operation === 'deleteSFFile') {
|
|
461
|
+
if (req && req.body && req.body.workload && req.body.workload.length >= 2) {
|
|
462
|
+
let id = req.body.workload[0];
|
|
463
|
+
let fileType = req.body.workload[1];
|
|
464
|
+
|
|
465
|
+
const result = SFAttachmentsHandler.deleteSFFile(id, fileType);
|
|
466
|
+
sendResponse(new Date().getTime(), {
|
|
467
|
+
success: result.success,
|
|
468
|
+
performance: 0,
|
|
469
|
+
anchor_id: payload.anchor_id,
|
|
470
|
+
results: result.results
|
|
471
|
+
}, res);
|
|
472
|
+
|
|
473
|
+
} else {
|
|
474
|
+
const errorMessage = Utils.getParamsMissingErrorMessage(payload.operation);
|
|
475
|
+
log.error(errorMessage);
|
|
476
|
+
sendResponse(new Date().getTime(), { success: false, performance: 0, anchor_id: payload.anchor_id, results: { "error_message": errorMessage } }, res);
|
|
477
|
+
}
|
|
478
|
+
} else if (payload.operation === 'conditionSearch') {
|
|
479
|
+
if (req && req.body && req.body.workload) {
|
|
480
|
+
|
|
481
|
+
const workload = req.body.workload;
|
|
482
|
+
if (!Array.isArray(workload)) {
|
|
483
|
+
log.error(`Invalid input parameters for conditionSearch. Check the input parameters and try again.`);
|
|
484
|
+
sendResponse(new Date().getTime(), { success: false, performance: 0, anchor_id: payload.anchor_id, results: { "error_message": Utils.internalServerError } }, res);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
let conditionJSON = JSON.stringify(req.body.workload);
|
|
488
|
+
|
|
489
|
+
//search for conditions
|
|
490
|
+
const response = priceEngine.conditionSearch(conditionJSON);
|
|
491
|
+
|
|
492
|
+
if (!response.success) {
|
|
493
|
+
//failure case
|
|
494
|
+
const errorMessage = response.results.messages.toString();
|
|
495
|
+
log.error(`We couldn’t complete the conditionSearch operation. Try again or contact Salesforce Support and provide the error details: ${errorMessage}`);
|
|
496
|
+
sendResponse(new Date().getTime(), {
|
|
497
|
+
success: false,
|
|
498
|
+
performance: 0,
|
|
499
|
+
anchor_id: payload.anchor_id,
|
|
500
|
+
results: { "error_message": errorMessage }
|
|
501
|
+
}, res);
|
|
502
|
+
} else {
|
|
503
|
+
sendResponse(new Date().getTime(), {
|
|
504
|
+
success: response.success,
|
|
505
|
+
performance: 0,
|
|
506
|
+
anchor_id: payload.anchor_id,
|
|
507
|
+
results: JSON.parse(response.results.conditions)
|
|
508
|
+
}, res);
|
|
509
|
+
}
|
|
510
|
+
} else {
|
|
511
|
+
const errorMessage = Utils.getParamsMissingErrorMessage(payload.operation);
|
|
512
|
+
log.error(errorMessage);
|
|
513
|
+
sendResponse(new Date().getTime(), {success: false, performance: 0, anchor_id: payload.anchor_id, results: { "error_message": errorMessage }}, res);
|
|
514
|
+
}
|
|
515
|
+
} else if (payload.operation === 'saveFile') {
|
|
516
|
+
const data = payload.workload[0];
|
|
517
|
+
const type = payload.workload[1];
|
|
518
|
+
const compress = payload.workload[2];
|
|
519
|
+
|
|
520
|
+
if (!Utils.isValidString(data) || !Utils.isValidParamString(type) || !_.isBoolean(compress)) {
|
|
521
|
+
const errorMessage = "Invalid input parameters for saveFile. Check the input parameters and try again.";
|
|
522
|
+
sendResponse(new Date().getTime(), {
|
|
523
|
+
success: false,
|
|
524
|
+
performance: 0,
|
|
525
|
+
anchor_id: payload.anchor_id,
|
|
526
|
+
results: { "error_message": errorMessage }
|
|
527
|
+
}, res);
|
|
528
|
+
}
|
|
529
|
+
const targetFolder = path.join(GlobalConfig.AttachmentsFolder, GlobalConfig.hesaFolder);
|
|
530
|
+
const filename = Utils.getSFFileName(new Date().getTime().toString(), type);
|
|
531
|
+
if(compress) {
|
|
532
|
+
ZipHandler.createZipFile(filename, data).then(content => {
|
|
533
|
+
let newfileName = filename.substring(0, filename.indexOf(".")) + ".zip";
|
|
534
|
+
__composeResponse(targetFolder, newfileName, content, payload, res);
|
|
535
|
+
});
|
|
536
|
+
} else {
|
|
537
|
+
__composeResponse(targetFolder, filename, data, payload, res);
|
|
538
|
+
}
|
|
539
|
+
} else {
|
|
540
|
+
log.error("Probably UNKNOWN operation detected :: " + payload.operation + " --> " + payload.action);
|
|
541
|
+
sendResponse(new Date().getTime(), { success: true, anchor_id: payload.anchor_id, results: [] }, res);
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
module.exports.initialize = initialize;
|
|
546
|
+
module.exports.closeDBConnection = closeDBConnection;
|
package/src/server.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* FILE_HEADER
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
const log4js = require('log4js');
|
|
8
|
+
|
|
9
|
+
const bootstrap = require('./bootstrap');
|
|
10
|
+
const argsParser = require('./argsParser');
|
|
11
|
+
const fsHelper = require('./fsHelper');
|
|
12
|
+
|
|
13
|
+
let result = argsParser.run(process.argv);
|
|
14
|
+
if (result && result.success) {
|
|
15
|
+
|
|
16
|
+
let settings = result.data;
|
|
17
|
+
|
|
18
|
+
// configure logging
|
|
19
|
+
log4js.configure(settings.loggingConfig);
|
|
20
|
+
const log = log4js.getLogger('server');
|
|
21
|
+
|
|
22
|
+
// load web server configuration file
|
|
23
|
+
let webServerConfig = fsHelper.readJsonFile(settings.webServerConfig);
|
|
24
|
+
if (webServerConfig) {
|
|
25
|
+
|
|
26
|
+
// configure, setup and start web server
|
|
27
|
+
bootstrap.setup(webServerConfig)
|
|
28
|
+
.then((app) => {
|
|
29
|
+
// take port from webServerConfig or take fallback/default port 3000
|
|
30
|
+
let webServerPort = webServerConfig.port || 3000;
|
|
31
|
+
|
|
32
|
+
const server = app.listen(webServerPort, "localhost", function () {
|
|
33
|
+
const port = server.address().port;
|
|
34
|
+
log.info('Backend server has started. Use the URL http://localhost:' +
|
|
35
|
+
port +
|
|
36
|
+
'/framework/index.html?desktop to perform any testing activities. ' +
|
|
37
|
+
'It is recommended to execute the application in incognito window of your browser ' +
|
|
38
|
+
'and take care only one incognito window is opened to avoid influences.');
|
|
39
|
+
log.info('Use CTRL+C to stop the backend server.');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
server.on('close', function () {
|
|
43
|
+
bootstrap.closeConnection();
|
|
44
|
+
log.info('The server closed successfully.');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// listen for SIGINT signal
|
|
48
|
+
process.on('SIGINT', function () {
|
|
49
|
+
server.close();
|
|
50
|
+
});
|
|
51
|
+
})
|
|
52
|
+
.catch(() => {
|
|
53
|
+
log.error("Couldn't start the backend server and the web application setup failed. Verify that the TCP port is available and you have the required permissions to perform this task. If the issue persists, contact Salesforce Support for help.");
|
|
54
|
+
process.exit(1);
|
|
55
|
+
});
|
|
56
|
+
} else {
|
|
57
|
+
log.error("The backend server failed to start and the web server configuration file couldn't be loaded. Make sure the appropriate access permissions are configured and that the configuration file format is valid. If the issue persists, contact Salesforce Support for help.");
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
} else {
|
|
62
|
+
console.error('The backend server failed to start. Review the error details to fix the issue, and if the issue persists, contact Salesforce Support for help:', result.error ? result.error : '');
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|