@yousolution/node-red-contrib-you-sap-service-layer 0.2.2 → 0.2.4

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 (50) hide show
  1. package/.prettierrc +6 -6
  2. package/.vscode/launch.json +23 -23
  3. package/CHANGELOG.md +61 -52
  4. package/README.md +126 -126
  5. package/docker-compose.yml +14 -14
  6. package/examples/example.json +625 -625
  7. package/nodes/SQLQuery.html +179 -179
  8. package/nodes/SQLQuery.js +46 -46
  9. package/nodes/authenticateSap.html +146 -146
  10. package/nodes/authenticateSap.js +129 -129
  11. package/nodes/closeSap.html +128 -97
  12. package/nodes/closeSap.js +36 -36
  13. package/nodes/createSQLQuery.html +165 -165
  14. package/nodes/createSQLQuery.js +70 -70
  15. package/nodes/createSap.html +391 -391
  16. package/nodes/createSap.js +40 -40
  17. package/nodes/crossJoinSap.html +394 -394
  18. package/nodes/crossJoinSap.js +37 -37
  19. package/nodes/deleteSap.html +406 -406
  20. package/nodes/deleteSap.js +35 -35
  21. package/nodes/getSap.html +427 -427
  22. package/nodes/getSap.js +34 -34
  23. package/nodes/listSap.html +402 -402
  24. package/nodes/listSap.js +37 -37
  25. package/nodes/manageErrors.js +38 -38
  26. package/nodes/manipulateEntitySap.html +176 -176
  27. package/nodes/manipulateEntitySap.js +46 -46
  28. package/nodes/nextLink.html +100 -100
  29. package/nodes/nextLink.js +18 -18
  30. package/nodes/patchSap.html +424 -424
  31. package/nodes/patchSap.js +40 -40
  32. package/nodes/serviceSap.html +160 -206
  33. package/nodes/serviceSap.js +39 -39
  34. package/nodes/support.js +363 -363
  35. package/package.json +65 -65
  36. package/resources/entities.json +59 -59
  37. package/resources/services.json +343 -343
  38. package/test/authenticateSap.spec.js +307 -307
  39. package/test/closeSap.spec.js +156 -156
  40. package/test/createSQLQuery.spec.js +174 -174
  41. package/test/createSap.spec.js +183 -183
  42. package/test/crossJoinSap.spec.js +156 -156
  43. package/test/deleteSap.spec.js +156 -156
  44. package/test/getSap.spec.js +156 -156
  45. package/test/listSap.spec.js +156 -156
  46. package/test/manipulateEntitySap.spec.js +191 -191
  47. package/test/patchSap.spec.js +184 -184
  48. package/test/serviceSap.spec.js +170 -170
  49. package/test/support.spec.js +1419 -1419
  50. package/data/.gitkeep +0 -0
package/nodes/support.js CHANGED
@@ -1,363 +1,363 @@
1
- process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
2
- const axiosLibrary = require('axios');
3
- const buildQuery = require('odata-query').default;
4
-
5
- const thickIdApi = [
6
- 'AccrualTypes',
7
- 'AssetClasses',
8
- 'AssetDepreciationGroups',
9
- 'AssetGroups',
10
- 'AlternateCatNum',
11
- 'BankChargesAllocationCodes',
12
- 'BusinessPartners',
13
- 'CampaignResponseType',
14
- 'CashDiscounts',
15
- 'ChartOfAccounts',
16
- 'ChooseFromList',
17
- 'ContractTemplates',
18
- 'CostCenterTypes',
19
- 'CostElements',
20
- 'Countries',
21
- 'CreditCardPayments',
22
- 'Currencies',
23
- 'CustomsDeclaration',
24
- 'CycleCountDeterminations',
25
- 'DeductionTaxSubGroups',
26
- 'DepreciationAreas',
27
- 'DepreciationTypePools',
28
- 'DepreciationTypes',
29
- 'DistributionRules',
30
- 'DunningTerms',
31
- 'EmailGroups',
32
- 'EmployeeIDType',
33
- 'FAAccountDeterminations',
34
- 'FactoringIndicators',
35
- 'FiscalPrinter',
36
- 'ItemImages',
37
- 'Items',
38
- 'JournalEntryDocumentTypes',
39
- 'KPIs',
40
- 'LandedCostsCodes',
41
- 'LocalEra',
42
- 'MobileAddOnSetting',
43
- 'NFModels',
44
- 'ProductTrees',
45
- 'ProfitCenters',
46
- 'Projects',
47
- 'Queue',
48
- 'ReportTypes',
49
- 'Resources',
50
- 'SalesTaxCodes',
51
- 'TargetGroups',
52
- 'TaxInvoiceReport',
53
- 'TransactionCodes',
54
- 'UserDefaultGroups',
55
- 'UserObjectsMD',
56
- 'UserPermissionTree',
57
- 'UserTablesMD',
58
- 'VatGroups',
59
- 'Warehouses',
60
- 'WithholdingTaxCodes',
61
- 'WizardPaymentMethods',
62
- 'UDT',
63
- ];
64
-
65
- async function login(node, idAuth) {
66
- const globalContext = node.context().global;
67
-
68
- const host = globalContext.get(`_YOU_SapServiceLayer_${idAuth}.host`);
69
- const port = globalContext.get(`_YOU_SapServiceLayer_${idAuth}.port`);
70
- const version = globalContext.get(`_YOU_SapServiceLayer_${idAuth}.version`);
71
-
72
- const url = `https://${host}:${port}/b1s/${version}/Login`;
73
-
74
- const credentials = globalContext.get(`_YOU_SapServiceLayer_${idAuth}.credentials`);
75
- const dataString = JSON.stringify(credentials);
76
-
77
- const options = {
78
- method: 'POST',
79
- url: url,
80
- rejectUnauthorized: false,
81
- data: credentials,
82
- headers: {
83
- 'Content-Type': 'application/json',
84
- 'Content-Length': dataString.length,
85
- },
86
- };
87
- return await axiosLibrary(options);
88
- }
89
-
90
- async function sendRequest({ node, msg, config, axios, login, options }) {
91
- if (!node || !msg || !config || !axios || !login) {
92
- const missingParams = [];
93
- node ? null : missingParams.push('node');
94
- msg ? null : missingParams.push('msg');
95
- config ? null : missingParams.push('config');
96
- axios ? null : missingParams.push('axios');
97
- login ? null : missingParams.push('login');
98
- throw new Error(`Missing mandatory params: ${missingParams.join(',')}.`);
99
- }
100
- let requestOptions = generateRequest(node, msg, config, options);
101
- try {
102
- return await axios(requestOptions.axiosOptions);
103
- } catch (error) {
104
- // Refresh headers re-login
105
- if (error.response && (error.response.status == 401 || error.response.status == 301)) {
106
- const globalCotext = node.context().global;
107
- // try {
108
- // update cookies for session timeout
109
- const result = await login(node, requestOptions.idAuthNode);
110
- globalCotext.set(`_YOU_SapServiceLayer_${requestOptions.idAuthNode}.headers`, result.headers['set-cookie']);
111
-
112
- try {
113
- const headers = globalCotext.get(`_YOU_SapServiceLayer_${requestOptions.idAuthNode}.headers`).join(';');
114
-
115
- requestOptions.axiosOptions.headers.Cookie = headers;
116
-
117
- return await axios(requestOptions.axiosOptions);
118
- } catch (error) {
119
- if (error.response && error.response.data) {
120
- msg.statusCode = error.response.status;
121
- msg.payload = error.response.data;
122
- msg.requestUrl = requestOptions.axiosOptions.url;
123
- //node.send(msg);
124
- node.error(JSON.stringify(error.response.data), msg);
125
- //throw new Error(JSON.stringify(error.response.data));
126
- }
127
- else {
128
- throw error;
129
- }
130
- }
131
- // }
132
- }
133
- if (error.response && error.response.data) {
134
- msg.statusCode = error.response.status;
135
- msg.payload = error.response.data;
136
- msg.requestUrl = requestOptions.axiosOptions.url;
137
- //node.send(msg);
138
- node.error(JSON.stringify(error.response.data), msg)
139
- // throw new Error(JSON.stringify(error.response.data));
140
- }
141
- else {
142
- throw error;
143
- }
144
-
145
- }
146
- }
147
-
148
- function generateRequest(node, msg, config, options) {
149
- options = options || {
150
- hasRawQuery: false,
151
- hasEntityId: false,
152
- isClose: false,
153
- isCrossJoin: false,
154
- service: null,
155
- manipulateMethod: null,
156
- method: 'GET',
157
- data: null,
158
- };
159
- // if (!options.typeOfNode) {
160
- // throw new Error('Missing type of node');
161
- // }
162
- options.hasRawQuery = options.hasRawQuery || false;
163
- options.method = options.method || 'GET';
164
- options.data = options.data || null;
165
- options.hasEntityId = options.hasEntityId || false;
166
- options.isClose = options.isClose || false;
167
- options.isCrossJoin = options.isCrossJoin || false;
168
- options.isManipulate = options.isManipulate || false;
169
- options.isService = options.isService || false;
170
- options.isCreateSQLQuery = options.isCreateSQLQuery || false;
171
- options.service = options.service || null;
172
- options.manipulateMethod = options.manipulateMethod || null;
173
-
174
- const { idAuthNode, host, port, version, cookies } = getSapParams(node, msg, config);
175
-
176
- let rawQuery = null;
177
- let url;
178
-
179
- if (options.hasRawQuery) {
180
- try {
181
- rawQuery = eval(config.query);
182
- } catch (error) {
183
- throw new Error('Query editor error');
184
- }
185
- }
186
-
187
- let entity = config.entity;
188
- if (!entity && !options.isService && !options.isCreateSQLQuery && !options.isSQLQuery) {
189
- throw new Error('Missing entity');
190
- }
191
-
192
- if (options.isService) {
193
- if (!config.service) {
194
- throw new Error('Missing service');
195
- }
196
- }
197
-
198
- if (entity == 'UDO') {
199
- entity = config.udo;
200
- }
201
-
202
- if (entity == 'UDT') {
203
- entity = config.udt;
204
- }
205
-
206
- if (entity == 'script') {
207
- const partnerName = config.partnerName;
208
- const scriptName = config.scriptName;
209
- url = `https://${host}:${port}/b1s/${version}/${entity}/${partnerName}/${scriptName}`;
210
- }
211
-
212
- const odataNextLink = msg[config.nextLink];
213
-
214
- if (!odataNextLink) {
215
- url = `https://${host}:${port}/b1s/${version}/${entity}`;
216
- }
217
-
218
- if (options.isCrossJoin) {
219
- url = `https://${host}:${port}/b1s/${version}/$crossjoin(${entity})`;
220
- }
221
-
222
- if (options.isSQLQuery) {
223
- if (!config.sqlCode) {
224
- throw new Error('Missing sqlCode');
225
- }
226
- url = `https://${host}:${port}/b1s/${version}/SQLQueries('${msg[config.sqlCode]}')/List`;
227
- }
228
-
229
- if (odataNextLink) {
230
- url = `https://${host}:${port}/b1s/${version}/${odataNextLink}`;
231
- }
232
- if (options.isClose && !options.hasEntityId) {
233
- throw new Error(`The options are not correct. If 'isClose' is true then 'hasEntityId' must be true.`);
234
- }
235
-
236
- if (options.hasEntityId) {
237
- let entityId = msg[config.entityId];
238
- if (!entityId && config.entity != 'UDO' && config.entity != 'UDT') {
239
- throw new Error('Missing entityId');
240
- }
241
- const docEntry = msg[config.docEntry];
242
- if (config.entity == 'UDO') {
243
- if (!docEntry) {
244
- throw new Error('Missing docEntry');
245
- }
246
- entityId = docEntry;
247
- }
248
-
249
- const code = msg[config.code];
250
- if (config.entity == 'UDT') {
251
- if (!code) {
252
- throw new Error('Missing Code');
253
- }
254
- entityId = code;
255
- }
256
-
257
- if (thickIdApi.includes(entity) || config.entity === 'UDT') {
258
- if(Number.isInteger(entityId)){
259
- url = `https://${host}:${port}/b1s/${version}/${entity}(${entityId})`;
260
- }
261
- else {
262
- url = `https://${host}:${port}/b1s/${version}/${entity}('${entityId}')`;
263
- }
264
-
265
- } else {
266
- url = `https://${host}:${port}/b1s/${version}/${entity}(${entityId})`;
267
- }
268
-
269
- if (options.isClose) {
270
- url += `/Close`;
271
- }
272
-
273
- if (options.isManipulate) {
274
- if (!config.manipulateMethod) {
275
- throw new Error('Missing method');
276
- }
277
- if (thickIdApi.includes(entity)) {
278
- url = `https://${host}:${port}/b1s/${version}/${entity}('${entityId}')/${config.manipulateMethod}`;
279
- } else {
280
- url = `https://${host}:${port}/b1s/${version}/${entity}(${entityId})/${config.manipulateMethod}`;
281
- }
282
- }
283
- }
284
-
285
- if (config.service) {
286
- url = `https://${host}:${port}/b1s/${version}/${config.service}`;
287
- }
288
-
289
- if (options.isCreateSQLQuery) {
290
- if (!config.sqlCode) {
291
- throw new Error('Missing sqlCode');
292
- }
293
- if (!config.sqlName) {
294
- throw new Error('Missing sqlName');
295
- }
296
- if (!config.sqlText) {
297
- throw new Error('Missing sqlText');
298
- }
299
- url = `https://${host}:${port}/b1s/${version}/SQLQueries`;
300
- }
301
-
302
- if (rawQuery && !odataNextLink) {
303
- const urlOdata = buildQuery(rawQuery);
304
- msg.odata = urlOdata;
305
- url = `${url}${urlOdata}`;
306
- }
307
-
308
- // const cookies = flowContext.get(`_YOU_SapServiceLayer_${idAuthNode}.headers`).join(';');
309
- const headers = { ...msg[config.headers], Cookie: cookies };
310
-
311
- let axiosOptions = {
312
- method: options.method,
313
- url: url,
314
- rejectUnauthorized: false,
315
- withCredentials: true,
316
- headers: headers,
317
- };
318
-
319
- if (options.data) {
320
- axiosOptions = { ...axiosOptions, ...{ data: options.data } };
321
- }
322
-
323
- return {
324
- axiosOptions: axiosOptions,
325
- idAuthNode: idAuthNode,
326
- };
327
- }
328
-
329
- function getSapParams(node, msg) {
330
- try {
331
- const globalContext = node.context().global;
332
-
333
- const idAuthNode = msg._YOU_SapServiceLayer.idAuth;
334
- const host = globalContext.get(`_YOU_SapServiceLayer_${idAuthNode}.host`);
335
- const port = globalContext.get(`_YOU_SapServiceLayer_${idAuthNode}.port`);
336
- const version = globalContext.get(`_YOU_SapServiceLayer_${idAuthNode}.version`);
337
-
338
- // if (!flowContext.get(`_YOU_SapServiceLayer_${idAuthNode}.headers`)) {
339
- // throw new Error('Authentication failed');
340
- // }
341
- const cookies = globalContext.get(`_YOU_SapServiceLayer_${idAuthNode}.headers`).join(';');
342
-
343
- return { idAuthNode: idAuthNode, host: host, port: port, version: version, cookies: cookies };
344
- } catch (error) {
345
- throw new Error('Authentication failed');
346
- }
347
- }
348
-
349
- module.exports = {
350
- login: login,
351
- generateRequest: generateRequest,
352
- sendRequest: sendRequest,
353
- thickIdApi: thickIdApi,
354
- };
355
- // if (process.env.NODE_ENV === 'test') {
356
- // console.log('TEST');
357
- // module.exports = {
358
- // login: login,
359
- // generateRequest: generateRequest,
360
- // sendRequest: sendRequest,
361
- // thickIdApi: thickIdApi,
362
- // };
363
- // }
1
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
2
+ const axiosLibrary = require('axios');
3
+ const buildQuery = require('odata-query').default;
4
+
5
+ const thickIdApi = [
6
+ 'AccrualTypes',
7
+ 'AssetClasses',
8
+ 'AssetDepreciationGroups',
9
+ 'AssetGroups',
10
+ 'AlternateCatNum',
11
+ 'BankChargesAllocationCodes',
12
+ 'BusinessPartners',
13
+ 'CampaignResponseType',
14
+ 'CashDiscounts',
15
+ 'ChartOfAccounts',
16
+ 'ChooseFromList',
17
+ 'ContractTemplates',
18
+ 'CostCenterTypes',
19
+ 'CostElements',
20
+ 'Countries',
21
+ 'CreditCardPayments',
22
+ 'Currencies',
23
+ 'CustomsDeclaration',
24
+ 'CycleCountDeterminations',
25
+ 'DeductionTaxSubGroups',
26
+ 'DepreciationAreas',
27
+ 'DepreciationTypePools',
28
+ 'DepreciationTypes',
29
+ 'DistributionRules',
30
+ 'DunningTerms',
31
+ 'EmailGroups',
32
+ 'EmployeeIDType',
33
+ 'FAAccountDeterminations',
34
+ 'FactoringIndicators',
35
+ 'FiscalPrinter',
36
+ 'ItemImages',
37
+ 'Items',
38
+ 'JournalEntryDocumentTypes',
39
+ 'KPIs',
40
+ 'LandedCostsCodes',
41
+ 'LocalEra',
42
+ 'MobileAddOnSetting',
43
+ 'NFModels',
44
+ 'ProductTrees',
45
+ 'ProfitCenters',
46
+ 'Projects',
47
+ 'Queue',
48
+ 'ReportTypes',
49
+ 'Resources',
50
+ 'SalesTaxCodes',
51
+ 'TargetGroups',
52
+ 'TaxInvoiceReport',
53
+ 'TransactionCodes',
54
+ 'UserDefaultGroups',
55
+ 'UserObjectsMD',
56
+ 'UserPermissionTree',
57
+ 'UserTablesMD',
58
+ 'VatGroups',
59
+ 'Warehouses',
60
+ 'WithholdingTaxCodes',
61
+ 'WizardPaymentMethods',
62
+ 'UDT',
63
+ ];
64
+
65
+ async function login(node, idAuth) {
66
+ const globalContext = node.context().global;
67
+
68
+ const host = globalContext.get(`_YOU_SapServiceLayer_${idAuth}.host`);
69
+ const port = globalContext.get(`_YOU_SapServiceLayer_${idAuth}.port`);
70
+ const version = globalContext.get(`_YOU_SapServiceLayer_${idAuth}.version`);
71
+
72
+ const url = `https://${host}:${port}/b1s/${version}/Login`;
73
+
74
+ const credentials = globalContext.get(`_YOU_SapServiceLayer_${idAuth}.credentials`);
75
+ const dataString = JSON.stringify(credentials);
76
+
77
+ const options = {
78
+ method: 'POST',
79
+ url: url,
80
+ rejectUnauthorized: false,
81
+ data: credentials,
82
+ headers: {
83
+ 'Content-Type': 'application/json',
84
+ 'Content-Length': dataString.length,
85
+ },
86
+ };
87
+ return await axiosLibrary(options);
88
+ }
89
+
90
+ async function sendRequest({ node, msg, config, axios, login, options }) {
91
+ if (!node || !msg || !config || !axios || !login) {
92
+ const missingParams = [];
93
+ node ? null : missingParams.push('node');
94
+ msg ? null : missingParams.push('msg');
95
+ config ? null : missingParams.push('config');
96
+ axios ? null : missingParams.push('axios');
97
+ login ? null : missingParams.push('login');
98
+ throw new Error(`Missing mandatory params: ${missingParams.join(',')}.`);
99
+ }
100
+ let requestOptions = generateRequest(node, msg, config, options);
101
+ try {
102
+ return await axios(requestOptions.axiosOptions);
103
+ } catch (error) {
104
+ // Refresh headers re-login
105
+ if (error.response && (error.response.status == 401 || error.response.status == 301)) {
106
+ const globalCotext = node.context().global;
107
+ // try {
108
+ // update cookies for session timeout
109
+ const result = await login(node, requestOptions.idAuthNode);
110
+ globalCotext.set(`_YOU_SapServiceLayer_${requestOptions.idAuthNode}.headers`, result.headers['set-cookie']);
111
+
112
+ try {
113
+ const headers = globalCotext.get(`_YOU_SapServiceLayer_${requestOptions.idAuthNode}.headers`).join(';');
114
+
115
+ requestOptions.axiosOptions.headers.Cookie = headers;
116
+
117
+ return await axios(requestOptions.axiosOptions);
118
+ } catch (error) {
119
+ if (error.response && error.response.data) {
120
+ msg.statusCode = error.response.status;
121
+ msg.payload = error.response.data;
122
+ msg.requestUrl = requestOptions.axiosOptions.url;
123
+ //node.send(msg);
124
+ node.error(JSON.stringify(error.response.data), msg);
125
+ //throw new Error(JSON.stringify(error.response.data));
126
+ }
127
+ else {
128
+ throw error;
129
+ }
130
+ }
131
+ // }
132
+ }
133
+ if (error.response && error.response.data) {
134
+ msg.statusCode = error.response.status;
135
+ msg.payload = error.response.data;
136
+ msg.requestUrl = requestOptions.axiosOptions.url;
137
+ //node.send(msg);
138
+ node.error(JSON.stringify(error.response.data), msg)
139
+ // throw new Error(JSON.stringify(error.response.data));
140
+ }
141
+ else {
142
+ throw error;
143
+ }
144
+
145
+ }
146
+ }
147
+
148
+ function generateRequest(node, msg, config, options) {
149
+ options = options || {
150
+ hasRawQuery: false,
151
+ hasEntityId: false,
152
+ isClose: false,
153
+ isCrossJoin: false,
154
+ service: null,
155
+ manipulateMethod: null,
156
+ method: 'GET',
157
+ data: null,
158
+ };
159
+ // if (!options.typeOfNode) {
160
+ // throw new Error('Missing type of node');
161
+ // }
162
+ options.hasRawQuery = options.hasRawQuery || false;
163
+ options.method = options.method || 'GET';
164
+ options.data = options.data || null;
165
+ options.hasEntityId = options.hasEntityId || false;
166
+ options.isClose = options.isClose || false;
167
+ options.isCrossJoin = options.isCrossJoin || false;
168
+ options.isManipulate = options.isManipulate || false;
169
+ options.isService = options.isService || false;
170
+ options.isCreateSQLQuery = options.isCreateSQLQuery || false;
171
+ options.service = options.service || null;
172
+ options.manipulateMethod = options.manipulateMethod || null;
173
+
174
+ const { idAuthNode, host, port, version, cookies } = getSapParams(node, msg, config);
175
+
176
+ let rawQuery = null;
177
+ let url;
178
+
179
+ if (options.hasRawQuery) {
180
+ try {
181
+ rawQuery = eval(config.query);
182
+ } catch (error) {
183
+ throw new Error('Query editor error');
184
+ }
185
+ }
186
+
187
+ let entity = config.entity;
188
+ if (!entity && !options.isService && !options.isCreateSQLQuery && !options.isSQLQuery) {
189
+ throw new Error('Missing entity');
190
+ }
191
+
192
+ if (options.isService) {
193
+ if (!config.service) {
194
+ throw new Error('Missing service');
195
+ }
196
+ }
197
+
198
+ if (entity == 'UDO') {
199
+ entity = config.udo;
200
+ }
201
+
202
+ if (entity == 'UDT') {
203
+ entity = config.udt;
204
+ }
205
+
206
+ if (entity == 'script') {
207
+ const partnerName = config.partnerName;
208
+ const scriptName = config.scriptName;
209
+ url = `https://${host}:${port}/b1s/${version}/${entity}/${partnerName}/${scriptName}`;
210
+ }
211
+
212
+ const odataNextLink = msg[config.nextLink];
213
+
214
+ if (!odataNextLink) {
215
+ url = `https://${host}:${port}/b1s/${version}/${entity}`;
216
+ }
217
+
218
+ if (options.isCrossJoin) {
219
+ url = `https://${host}:${port}/b1s/${version}/$crossjoin(${entity})`;
220
+ }
221
+
222
+ if (options.isSQLQuery) {
223
+ if (!config.sqlCode) {
224
+ throw new Error('Missing sqlCode');
225
+ }
226
+ url = `https://${host}:${port}/b1s/${version}/SQLQueries('${msg[config.sqlCode]}')/List`;
227
+ }
228
+
229
+ if (odataNextLink) {
230
+ url = `https://${host}:${port}/b1s/${version}/${odataNextLink}`;
231
+ }
232
+ if (options.isClose && !options.hasEntityId) {
233
+ throw new Error(`The options are not correct. If 'isClose' is true then 'hasEntityId' must be true.`);
234
+ }
235
+
236
+ if (options.hasEntityId) {
237
+ let entityId = msg[config.entityId];
238
+ if (!entityId && config.entity != 'UDO' && config.entity != 'UDT') {
239
+ throw new Error('Missing entityId');
240
+ }
241
+ const docEntry = msg[config.docEntry];
242
+ if (config.entity == 'UDO') {
243
+ if (!docEntry) {
244
+ throw new Error('Missing docEntry');
245
+ }
246
+ entityId = docEntry;
247
+ }
248
+
249
+ const code = msg[config.code];
250
+ if (config.entity == 'UDT') {
251
+ if (!code) {
252
+ throw new Error('Missing Code');
253
+ }
254
+ entityId = code;
255
+ }
256
+
257
+ if (thickIdApi.includes(entity) || config.entity === 'UDT') {
258
+ if(Number.isInteger(entityId)){
259
+ url = `https://${host}:${port}/b1s/${version}/${entity}(${entityId})`;
260
+ }
261
+ else {
262
+ url = `https://${host}:${port}/b1s/${version}/${entity}('${entityId}')`;
263
+ }
264
+
265
+ } else {
266
+ url = `https://${host}:${port}/b1s/${version}/${entity}(${entityId})`;
267
+ }
268
+
269
+ if (options.isClose) {
270
+ url += `/Close`;
271
+ }
272
+
273
+ if (options.isManipulate) {
274
+ if (!config.manipulateMethod) {
275
+ throw new Error('Missing method');
276
+ }
277
+ if (thickIdApi.includes(entity)) {
278
+ url = `https://${host}:${port}/b1s/${version}/${entity}('${entityId}')/${config.manipulateMethod}`;
279
+ } else {
280
+ url = `https://${host}:${port}/b1s/${version}/${entity}(${entityId})/${config.manipulateMethod}`;
281
+ }
282
+ }
283
+ }
284
+
285
+ if (config.service) {
286
+ url = `https://${host}:${port}/b1s/${version}/${config.service}`;
287
+ }
288
+
289
+ if (options.isCreateSQLQuery) {
290
+ if (!config.sqlCode) {
291
+ throw new Error('Missing sqlCode');
292
+ }
293
+ if (!config.sqlName) {
294
+ throw new Error('Missing sqlName');
295
+ }
296
+ if (!config.sqlText) {
297
+ throw new Error('Missing sqlText');
298
+ }
299
+ url = `https://${host}:${port}/b1s/${version}/SQLQueries`;
300
+ }
301
+
302
+ if (rawQuery && !odataNextLink) {
303
+ const urlOdata = buildQuery(rawQuery);
304
+ msg.odata = urlOdata;
305
+ url = `${url}${urlOdata}`;
306
+ }
307
+
308
+ // const cookies = flowContext.get(`_YOU_SapServiceLayer_${idAuthNode}.headers`).join(';');
309
+ const headers = { ...msg[config.headers], Cookie: cookies };
310
+
311
+ let axiosOptions = {
312
+ method: options.method,
313
+ url: url,
314
+ rejectUnauthorized: false,
315
+ withCredentials: true,
316
+ headers: headers,
317
+ };
318
+
319
+ if (options.data) {
320
+ axiosOptions = { ...axiosOptions, ...{ data: options.data } };
321
+ }
322
+
323
+ return {
324
+ axiosOptions: axiosOptions,
325
+ idAuthNode: idAuthNode,
326
+ };
327
+ }
328
+
329
+ function getSapParams(node, msg) {
330
+ try {
331
+ const globalContext = node.context().global;
332
+
333
+ const idAuthNode = msg._YOU_SapServiceLayer.idAuth;
334
+ const host = globalContext.get(`_YOU_SapServiceLayer_${idAuthNode}.host`);
335
+ const port = globalContext.get(`_YOU_SapServiceLayer_${idAuthNode}.port`);
336
+ const version = globalContext.get(`_YOU_SapServiceLayer_${idAuthNode}.version`);
337
+
338
+ // if (!flowContext.get(`_YOU_SapServiceLayer_${idAuthNode}.headers`)) {
339
+ // throw new Error('Authentication failed');
340
+ // }
341
+ const cookies = globalContext.get(`_YOU_SapServiceLayer_${idAuthNode}.headers`).join(';');
342
+
343
+ return { idAuthNode: idAuthNode, host: host, port: port, version: version, cookies: cookies };
344
+ } catch (error) {
345
+ throw new Error('Authentication failed');
346
+ }
347
+ }
348
+
349
+ module.exports = {
350
+ login: login,
351
+ generateRequest: generateRequest,
352
+ sendRequest: sendRequest,
353
+ thickIdApi: thickIdApi,
354
+ };
355
+ // if (process.env.NODE_ENV === 'test') {
356
+ // console.log('TEST');
357
+ // module.exports = {
358
+ // login: login,
359
+ // generateRequest: generateRequest,
360
+ // sendRequest: sendRequest,
361
+ // thickIdApi: thickIdApi,
362
+ // };
363
+ // }