@fsai-flow/core 0.0.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.
Files changed (113) hide show
  1. package/README.md +11 -0
  2. package/dist/README.md +11 -0
  3. package/dist/package.json +44 -0
  4. package/dist/src/index.d.ts +15 -0
  5. package/dist/src/index.js +29 -0
  6. package/dist/src/index.js.map +1 -0
  7. package/dist/src/lib/ActiveWebhooks.d.ts +59 -0
  8. package/dist/src/lib/ActiveWebhooks.js +184 -0
  9. package/dist/src/lib/ActiveWebhooks.js.map +1 -0
  10. package/dist/src/lib/ActiveWorkflows.d.ts +58 -0
  11. package/dist/src/lib/ActiveWorkflows.js +244 -0
  12. package/dist/src/lib/ActiveWorkflows.js.map +1 -0
  13. package/dist/src/lib/BinaryDataManager/FileSystem.d.ts +26 -0
  14. package/dist/src/lib/BinaryDataManager/FileSystem.js +179 -0
  15. package/dist/src/lib/BinaryDataManager/FileSystem.js.map +1 -0
  16. package/dist/src/lib/BinaryDataManager/index.d.ts +21 -0
  17. package/dist/src/lib/BinaryDataManager/index.js +146 -0
  18. package/dist/src/lib/BinaryDataManager/index.js.map +1 -0
  19. package/dist/src/lib/ChangeCase.d.ts +9 -0
  20. package/dist/src/lib/ChangeCase.js +43 -0
  21. package/dist/src/lib/ChangeCase.js.map +1 -0
  22. package/dist/src/lib/Constants.d.ts +14 -0
  23. package/dist/src/lib/Constants.js +19 -0
  24. package/dist/src/lib/Constants.js.map +1 -0
  25. package/dist/src/lib/Credentials.d.ts +27 -0
  26. package/dist/src/lib/Credentials.js +89 -0
  27. package/dist/src/lib/Credentials.js.map +1 -0
  28. package/dist/src/lib/FileSystem.d.ts +26 -0
  29. package/dist/src/lib/FileSystem.js +179 -0
  30. package/dist/src/lib/FileSystem.js.map +1 -0
  31. package/dist/src/lib/InputConnectionDataLegacy.d.ts +2 -0
  32. package/dist/src/lib/InputConnectionDataLegacy.js +79 -0
  33. package/dist/src/lib/InputConnectionDataLegacy.js.map +1 -0
  34. package/dist/src/lib/Interfaces.d.ts +148 -0
  35. package/dist/src/lib/Interfaces.js +3 -0
  36. package/dist/src/lib/Interfaces.js.map +1 -0
  37. package/dist/src/lib/LoadNodeParameterOptions.d.ts +39 -0
  38. package/dist/src/lib/LoadNodeParameterOptions.js +150 -0
  39. package/dist/src/lib/LoadNodeParameterOptions.js.map +1 -0
  40. package/dist/src/lib/NodeExecuteFunctions.d.ts +226 -0
  41. package/dist/src/lib/NodeExecuteFunctions.js +2483 -0
  42. package/dist/src/lib/NodeExecuteFunctions.js.map +1 -0
  43. package/dist/src/lib/NodesLoader/constants.d.ts +5 -0
  44. package/dist/src/lib/NodesLoader/constants.js +106 -0
  45. package/dist/src/lib/NodesLoader/constants.js.map +1 -0
  46. package/dist/src/lib/NodesLoader/custom-directory-loader.d.ts +9 -0
  47. package/dist/src/lib/NodesLoader/custom-directory-loader.js +36 -0
  48. package/dist/src/lib/NodesLoader/custom-directory-loader.js.map +1 -0
  49. package/dist/src/lib/NodesLoader/directory-loader.d.ts +66 -0
  50. package/dist/src/lib/NodesLoader/directory-loader.js +325 -0
  51. package/dist/src/lib/NodesLoader/directory-loader.js.map +1 -0
  52. package/dist/src/lib/NodesLoader/index.d.ts +5 -0
  53. package/dist/src/lib/NodesLoader/index.js +12 -0
  54. package/dist/src/lib/NodesLoader/index.js.map +1 -0
  55. package/dist/src/lib/NodesLoader/lazy-package-directory-loader.d.ts +7 -0
  56. package/dist/src/lib/NodesLoader/lazy-package-directory-loader.js +52 -0
  57. package/dist/src/lib/NodesLoader/lazy-package-directory-loader.js.map +1 -0
  58. package/dist/src/lib/NodesLoader/load-class-in-isolation.d.ts +1 -0
  59. package/dist/src/lib/NodesLoader/load-class-in-isolation.js +22 -0
  60. package/dist/src/lib/NodesLoader/load-class-in-isolation.js.map +1 -0
  61. package/dist/src/lib/NodesLoader/package-directory-loader.d.ts +17 -0
  62. package/dist/src/lib/NodesLoader/package-directory-loader.js +100 -0
  63. package/dist/src/lib/NodesLoader/package-directory-loader.js.map +1 -0
  64. package/dist/src/lib/NodesLoader/types.d.ts +14 -0
  65. package/dist/src/lib/NodesLoader/types.js +3 -0
  66. package/dist/src/lib/NodesLoader/types.js.map +1 -0
  67. package/dist/src/lib/UserSettings.d.ts +80 -0
  68. package/dist/src/lib/UserSettings.js +261 -0
  69. package/dist/src/lib/UserSettings.js.map +1 -0
  70. package/dist/src/lib/WorkflowExecute.d.ts +53 -0
  71. package/dist/src/lib/WorkflowExecute.js +835 -0
  72. package/dist/src/lib/WorkflowExecute.js.map +1 -0
  73. package/dist/src/lib/index.d.ts +21 -0
  74. package/dist/src/lib/index.js +146 -0
  75. package/dist/src/lib/index.js.map +1 -0
  76. package/dist/src/utils/crypto.d.ts +1 -0
  77. package/dist/src/utils/crypto.js +8 -0
  78. package/dist/src/utils/crypto.js.map +1 -0
  79. package/eslint.config.js +19 -0
  80. package/jest.config.ts +10 -0
  81. package/package.json +44 -0
  82. package/project.json +19 -0
  83. package/src/index.ts +27 -0
  84. package/src/lib/ActiveWebhooks.ts +245 -0
  85. package/src/lib/ActiveWorkflows.ts +304 -0
  86. package/src/lib/BinaryDataManager/FileSystem.ts +214 -0
  87. package/src/lib/BinaryDataManager/index.ts +187 -0
  88. package/src/lib/ChangeCase.ts +45 -0
  89. package/src/lib/Constants.ts +16 -0
  90. package/src/lib/Credentials.ts +108 -0
  91. package/src/lib/FileSystem.ts +214 -0
  92. package/src/lib/InputConnectionDataLegacy.ts +123 -0
  93. package/src/lib/Interfaces.ts +338 -0
  94. package/src/lib/LoadNodeParameterOptions.ts +235 -0
  95. package/src/lib/NodeExecuteFunctions.ts +3704 -0
  96. package/src/lib/NodesLoader/constants.ts +112 -0
  97. package/src/lib/NodesLoader/custom-directory-loader.ts +31 -0
  98. package/src/lib/NodesLoader/directory-loader.ts +458 -0
  99. package/src/lib/NodesLoader/index.ts +5 -0
  100. package/src/lib/NodesLoader/lazy-package-directory-loader.ts +55 -0
  101. package/src/lib/NodesLoader/load-class-in-isolation.ts +19 -0
  102. package/src/lib/NodesLoader/package-directory-loader.ts +107 -0
  103. package/src/lib/NodesLoader/types.ts +14 -0
  104. package/src/lib/UserSettings.ts +292 -0
  105. package/src/lib/WorkflowExecute.ts +1108 -0
  106. package/src/lib/index.ts +187 -0
  107. package/src/utils/crypto.ts +5 -0
  108. package/tests/Credentials.test.ts +88 -0
  109. package/tests/Helpers.ts +808 -0
  110. package/tests/WorkflowExecute.test.ts +1242 -0
  111. package/tsconfig.json +42 -0
  112. package/tsconfig.lib.json +10 -0
  113. package/tsconfig.spec.json +14 -0
@@ -0,0 +1,2483 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getBinaryDataBuffer = getBinaryDataBuffer;
4
+ exports.prepareBinaryData = prepareBinaryData;
5
+ exports.getCurrentOAuth2AccessToken = getCurrentOAuth2AccessToken;
6
+ exports.requestOAuth2 = requestOAuth2;
7
+ exports.requestOAuth1 = requestOAuth1;
8
+ exports.httpRequestWithAuthentication = httpRequestWithAuthentication;
9
+ exports.returnJsonArray = returnJsonArray;
10
+ exports.normalizeItems = normalizeItems;
11
+ exports.requestWithAuthentication = requestWithAuthentication;
12
+ exports.getAdditionalKeys = getAdditionalKeys;
13
+ exports.getCredentials = getCredentials;
14
+ exports.getNode = getNode;
15
+ exports.getNodeParameter = getNodeParameter;
16
+ exports.continueOnFail = continueOnFail;
17
+ exports.getNodeWebhookUrl = getNodeWebhookUrl;
18
+ exports.getTimezone = getTimezone;
19
+ exports.getWebhookDescription = getWebhookDescription;
20
+ exports.getWorkflowMetadata = getWorkflowMetadata;
21
+ exports.getExecutePollFunctions = getExecutePollFunctions;
22
+ exports.getExecuteTriggerFunctions = getExecuteTriggerFunctions;
23
+ exports.getExecuteFunctions = getExecuteFunctions;
24
+ exports.getExecuteSingleFunctions = getExecuteSingleFunctions;
25
+ exports.getCredentialTestFunctions = getCredentialTestFunctions;
26
+ exports.getLoadOptionsFunctions = getLoadOptionsFunctions;
27
+ exports.getExecuteHookFunctions = getExecuteHookFunctions;
28
+ exports.getExecuteWebhookFunctions = getExecuteWebhookFunctions;
29
+ exports.getSupplyDataFunctions = getSupplyDataFunctions;
30
+ exports.getInputConnectionData = getInputConnectionData;
31
+ const tslib_1 = require("tslib");
32
+ const workflow_1 = require("@fsai-flow/workflow");
33
+ const https_1 = require("https");
34
+ const qs_1 = require("qs");
35
+ const clientOAuth1 = require('oauth-1.0a');
36
+ const simple_oauth2_1 = require("simple-oauth2");
37
+ const crypto = tslib_1.__importStar(require("crypto"));
38
+ const url = tslib_1.__importStar(require("url"));
39
+ const lodash_1 = require("lodash");
40
+ const FormData = require('form-data');
41
+ const path = tslib_1.__importStar(require("path"));
42
+ const crypto_1 = require("crypto");
43
+ const file_type_1 = require("file-type");
44
+ const mime_types_1 = require("mime-types");
45
+ const axios_1 = tslib_1.__importDefault(require("axios"));
46
+ const url_1 = require("url");
47
+ const BinaryDataManager_1 = require("./BinaryDataManager");
48
+ const src_1 = require("../../src");
49
+ const fs_1 = require("fs");
50
+ axios_1.default.defaults.timeout = 900000;
51
+ // Prevent axios from adding x-form-www-urlencoded headers by default
52
+ axios_1.default.defaults.headers.post = {};
53
+ axios_1.default.defaults.headers.put = {};
54
+ axios_1.default.defaults.headers.patch = {};
55
+ axios_1.default.defaults.paramsSerializer = (params) => {
56
+ if (params instanceof url_1.URLSearchParams) {
57
+ return params.toString();
58
+ }
59
+ return (0, qs_1.stringify)(params, { arrayFormat: 'indices' });
60
+ };
61
+ const pushFormDataValue = (form, key, value) => {
62
+ // eslint-disable-next-line no-prototype-builtins
63
+ if ((value === null || value === void 0 ? void 0 : value.hasOwnProperty('value')) && Object.prototype.hasOwnProperty.call(value, 'options')) {
64
+ // @ts-ignore
65
+ form.append(key, value.value, value.options);
66
+ }
67
+ else {
68
+ form.append(key, value);
69
+ }
70
+ };
71
+ const createFormDataObject = (data) => {
72
+ const formData = new FormData();
73
+ const keys = Object.keys(data);
74
+ keys.forEach((key) => {
75
+ // @ts-ignore
76
+ const formField = data[key];
77
+ if (formField instanceof Array) {
78
+ formField.forEach((item) => {
79
+ pushFormDataValue(formData, key, item);
80
+ });
81
+ }
82
+ else {
83
+ pushFormDataValue(formData, key, formField);
84
+ }
85
+ });
86
+ return formData;
87
+ };
88
+ function searchForHeader(headers, headerName) {
89
+ if (headers === undefined) {
90
+ return undefined;
91
+ }
92
+ const headerNames = Object.keys(headers);
93
+ headerName = headerName.toLowerCase();
94
+ return headerNames.find((thisHeader) => thisHeader.toLowerCase() === headerName);
95
+ }
96
+ function generateContentLengthHeader(formData, headers) {
97
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
98
+ if (!formData || !formData.getLength) {
99
+ return;
100
+ }
101
+ try {
102
+ const length = yield new Promise((res, rej) => {
103
+ formData.getLength((error, length) => {
104
+ if (error) {
105
+ rej(error);
106
+ return;
107
+ }
108
+ res(length);
109
+ });
110
+ });
111
+ headers = Object.assign(headers, {
112
+ 'content-length': length,
113
+ });
114
+ }
115
+ catch (error) {
116
+ workflow_1.LoggerProxy.error('Unable to calculate form data length', { error });
117
+ }
118
+ });
119
+ }
120
+ function parseRequestObject(requestObject) {
121
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
122
+ var _a, _b, _c, _d, _e;
123
+ // This function is a temporary implementation
124
+ // That translates all http requests done via
125
+ // the request library to axios directly
126
+ // We are not using n8n's interface as it would
127
+ // an unnecessary step, considering the `request`
128
+ // helper can be deprecated and removed.
129
+ const axiosConfig = {};
130
+ if (typeof requestObject['headers'] === 'object' && requestObject['headers'] !== null) {
131
+ axiosConfig.headers = requestObject['headers'];
132
+ }
133
+ // Let's start parsing the hardest part, which is the request body.
134
+ // The process here is as following?
135
+ // - Check if we have a `content-type` header. If this was set,
136
+ // we will follow
137
+ // - Check if the `form` property was set. If yes, then it's x-www-form-urlencoded
138
+ // - Check if the `formData` property exists. If yes, then it's multipart/form-data
139
+ // - Lastly, we should have a regular `body` that is probably a JSON.
140
+ const contentTypeHeaderKeyName = axiosConfig.headers &&
141
+ Object.keys(axiosConfig.headers).find((headerName) => headerName.toLowerCase() === 'content-type');
142
+ const contentType = contentTypeHeaderKeyName &&
143
+ axiosConfig.headers &&
144
+ axiosConfig.headers[contentTypeHeaderKeyName];
145
+ if (contentType === 'application/x-www-form-urlencoded' && requestObject['formData'] === undefined) {
146
+ // there are nodes incorrectly created, informing the content type header
147
+ // and also using formData. Request lib takes precedence for the formData.
148
+ // We will do the same.
149
+ // Merge body and form properties.
150
+ if (typeof requestObject['body'] === 'string') {
151
+ axiosConfig.data = requestObject['body'];
152
+ }
153
+ else {
154
+ const allData = Object.assign(requestObject['body'] || {}, requestObject['form'] || {});
155
+ if (requestObject['useQuerystring'] === true) {
156
+ axiosConfig.data = (0, qs_1.stringify)(allData, { arrayFormat: 'repeat' });
157
+ }
158
+ else {
159
+ axiosConfig.data = (0, qs_1.stringify)(allData);
160
+ }
161
+ }
162
+ }
163
+ else if (contentType && contentType.includes('multipart/form-data') !== false) {
164
+ if (requestObject['formData'] !== undefined && requestObject['formData'] instanceof FormData) {
165
+ axiosConfig.data = requestObject['formData'];
166
+ }
167
+ else {
168
+ const allData = Object.assign(Object.assign({}, requestObject['body']), requestObject['formData']);
169
+ axiosConfig.data = createFormDataObject(allData);
170
+ }
171
+ // replace the existing header with a new one that
172
+ // contains the boundary property.
173
+ // @ts-ignore
174
+ delete axiosConfig.headers[contentTypeHeaderKeyName];
175
+ const headers = axiosConfig.data.getHeaders();
176
+ axiosConfig.headers = Object.assign(axiosConfig.headers || {}, headers);
177
+ if (!axiosConfig.headers) {
178
+ axiosConfig.headers = {};
179
+ }
180
+ yield generateContentLengthHeader(axiosConfig.data, axiosConfig.headers);
181
+ }
182
+ else {
183
+ // When using the `form` property it means the content should be x-www-form-urlencoded.
184
+ if (requestObject['form'] !== undefined && requestObject['body'] === undefined) {
185
+ // If we have only form
186
+ axiosConfig.data =
187
+ typeof requestObject['form'] === 'string'
188
+ ? (0, qs_1.stringify)(requestObject['form'], { format: 'RFC3986' })
189
+ : (0, qs_1.stringify)(requestObject['form']).toString();
190
+ if (axiosConfig.headers !== undefined) {
191
+ const headerName = searchForHeader(axiosConfig.headers, 'content-type');
192
+ if (headerName) {
193
+ delete axiosConfig.headers[headerName];
194
+ }
195
+ axiosConfig.headers['Content-Type'] = 'application/x-www-form-urlencoded';
196
+ }
197
+ else {
198
+ axiosConfig.headers = {
199
+ 'Content-Type': 'application/x-www-form-urlencoded',
200
+ };
201
+ }
202
+ }
203
+ else if (requestObject['formData'] !== undefined) {
204
+ // remove any "content-type" that might exist.
205
+ if (axiosConfig.headers !== undefined) {
206
+ const headers = Object.keys(axiosConfig.headers);
207
+ headers.forEach((header) => header.toLowerCase() === 'content-type' && axiosConfig.headers ? delete axiosConfig.headers[header] : null);
208
+ }
209
+ if (requestObject['formData'] instanceof FormData) {
210
+ axiosConfig.data = requestObject['formData'];
211
+ }
212
+ else {
213
+ axiosConfig.data = createFormDataObject(requestObject['formData']);
214
+ }
215
+ // Mix in headers as FormData creates the boundary.
216
+ const headers = axiosConfig.data.getHeaders();
217
+ axiosConfig.headers = Object.assign(axiosConfig.headers || {}, headers);
218
+ yield generateContentLengthHeader(axiosConfig.data, axiosConfig.headers);
219
+ }
220
+ else if (requestObject['body'] !== undefined) {
221
+ // If we have body and possibly form
222
+ if (requestObject['form'] !== undefined) {
223
+ // merge both objects when exist.
224
+ if (requestObject['body'] && requestObject['form']) {
225
+ requestObject['body'] = Object.assign(requestObject['body'], requestObject['form']);
226
+ }
227
+ }
228
+ axiosConfig.data = requestObject['body'];
229
+ }
230
+ }
231
+ if (requestObject['uri'] !== undefined) {
232
+ axiosConfig.url = (_a = requestObject['uri']) === null || _a === void 0 ? void 0 : _a.toString();
233
+ }
234
+ if (requestObject['url'] !== undefined) {
235
+ axiosConfig.url = (_b = requestObject['url']) === null || _b === void 0 ? void 0 : _b.toString();
236
+ }
237
+ if (requestObject['baseURL'] !== undefined) {
238
+ axiosConfig.baseURL = (_c = requestObject['baseURL']) === null || _c === void 0 ? void 0 : _c.toString();
239
+ }
240
+ if (requestObject['method'] !== undefined) {
241
+ axiosConfig.method = requestObject['method'];
242
+ }
243
+ if (requestObject['qs'] !== undefined && Object.keys(requestObject['qs']).length > 0) {
244
+ axiosConfig.params = requestObject['qs'];
245
+ }
246
+ if (requestObject['useQuerystring'] === true ||
247
+ // @ts-ignore
248
+ ((_d = requestObject.qsStringifyOptions) === null || _d === void 0 ? void 0 : _d.arrayFormat) === 'repeat') {
249
+ axiosConfig.paramsSerializer = (params) => {
250
+ return (0, qs_1.stringify)(params, { arrayFormat: 'repeat' });
251
+ };
252
+ }
253
+ else if (requestObject['useQuerystring'] === false) {
254
+ axiosConfig.paramsSerializer = (params) => {
255
+ return (0, qs_1.stringify)(params, { arrayFormat: 'indices' });
256
+ };
257
+ }
258
+ // @ts-ignore
259
+ if (((_e = requestObject.qsStringifyOptions) === null || _e === void 0 ? void 0 : _e.arrayFormat) === 'brackets') {
260
+ axiosConfig.paramsSerializer = (params) => {
261
+ return (0, qs_1.stringify)(params, { arrayFormat: 'brackets' });
262
+ };
263
+ }
264
+ if (requestObject['auth'] !== undefined) {
265
+ // Check support for sendImmediately
266
+ if (requestObject['auth']['bearer'] !== undefined) {
267
+ axiosConfig.headers = Object.assign(axiosConfig.headers || {}, {
268
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
269
+ Authorization: `Bearer ${requestObject['auth']['bearer']}`,
270
+ });
271
+ }
272
+ else {
273
+ const authObj = requestObject['auth'];
274
+ // Request accepts both user/username and pass/password
275
+ axiosConfig.auth = {
276
+ username: (authObj['user'] || authObj['username']),
277
+ password: (authObj['password'] || authObj['pass']),
278
+ };
279
+ }
280
+ }
281
+ // Only set header if we have a body, otherwise it may fail
282
+ if (requestObject['json'] === true) {
283
+ // Add application/json headers - do not set charset as it breaks a lot of stuff
284
+ // only add if no other accept headers was sent.
285
+ const acceptHeaderExists = axiosConfig.headers === undefined
286
+ ? false
287
+ : Object.keys(axiosConfig.headers)
288
+ .map((headerKey) => headerKey.toLowerCase())
289
+ .includes('accept');
290
+ if (!acceptHeaderExists) {
291
+ axiosConfig.headers = Object.assign(axiosConfig.headers || {}, {
292
+ Accept: 'application/json',
293
+ });
294
+ }
295
+ }
296
+ if (requestObject['json'] === false || requestObject['json'] === undefined) {
297
+ // Prevent json parsing
298
+ axiosConfig.transformResponse = (res) => res;
299
+ }
300
+ // Axios will follow redirects by default, so we simply tell it otherwise if needed.
301
+ if (requestObject['followRedirect'] === false &&
302
+ (requestObject['method'] || 'get').toLowerCase() === 'get') {
303
+ axiosConfig.maxRedirects = 0;
304
+ }
305
+ if (requestObject['followAllRedirects'] === false &&
306
+ (requestObject['method'] || 'get').toLowerCase() !== 'get') {
307
+ axiosConfig.maxRedirects = 0;
308
+ }
309
+ if (requestObject['rejectUnauthorized'] === false) {
310
+ axiosConfig.httpsAgent = new https_1.Agent({
311
+ rejectUnauthorized: false,
312
+ });
313
+ }
314
+ if (requestObject['timeout'] !== undefined) {
315
+ axiosConfig.timeout = requestObject['timeout'];
316
+ }
317
+ if (requestObject['proxy'] !== undefined) {
318
+ // try our best to parse the url provided.
319
+ if (typeof requestObject['proxy'] === 'string') {
320
+ try {
321
+ const url = new url_1.URL(requestObject['proxy']);
322
+ axiosConfig.proxy = {
323
+ host: url.hostname,
324
+ port: parseInt(url.port, 10),
325
+ protocol: url.protocol,
326
+ };
327
+ if (!url.port) {
328
+ // Sets port to a default if not informed
329
+ if (url.protocol === 'http') {
330
+ axiosConfig.proxy.port = 80;
331
+ }
332
+ else if (url.protocol === 'https') {
333
+ axiosConfig.proxy.port = 443;
334
+ }
335
+ }
336
+ if (url.username || url.password) {
337
+ axiosConfig.proxy.auth = {
338
+ username: url.username,
339
+ password: url.password,
340
+ };
341
+ }
342
+ }
343
+ catch (error) {
344
+ // Not a valid URL. We will try to simply parse stuff
345
+ // such as user:pass@host:port without protocol (we'll assume http)
346
+ if (requestObject['proxy'].includes('@')) {
347
+ const [userpass, hostport] = requestObject['proxy'].split('@');
348
+ const [username, password] = userpass.split(':');
349
+ const [hostname, port] = hostport.split(':');
350
+ axiosConfig.proxy = {
351
+ host: hostname,
352
+ port: parseInt(port, 10),
353
+ protocol: 'http',
354
+ auth: {
355
+ username,
356
+ password,
357
+ },
358
+ };
359
+ }
360
+ else if (requestObject['proxy'].includes(':')) {
361
+ const [hostname, port] = requestObject['proxy'].split(':');
362
+ axiosConfig.proxy = {
363
+ host: hostname,
364
+ port: parseInt(port, 10),
365
+ protocol: 'http',
366
+ };
367
+ }
368
+ else {
369
+ axiosConfig.proxy = {
370
+ host: requestObject['proxy'],
371
+ port: 80,
372
+ protocol: 'http',
373
+ };
374
+ }
375
+ }
376
+ }
377
+ else {
378
+ axiosConfig.proxy = requestObject['proxy'];
379
+ }
380
+ }
381
+ if (requestObject['encoding'] === null) {
382
+ // When downloading files, return an arrayBuffer.
383
+ axiosConfig.responseType = 'arraybuffer';
384
+ }
385
+ // If we don't set an accept header
386
+ // Axios forces "application/json, text/plan, */*"
387
+ // Which causes some nodes like NextCloud to break
388
+ // as the service returns XML unless requested otherwise.
389
+ const allHeaders = axiosConfig.headers ? Object.keys(axiosConfig.headers) : [];
390
+ if (!allHeaders.some((headerKey) => headerKey.toLowerCase() === 'accept')) {
391
+ axiosConfig.headers = Object.assign(axiosConfig.headers || {}, { accept: '*/*' });
392
+ }
393
+ if (requestObject['json'] !== false &&
394
+ axiosConfig.data !== undefined &&
395
+ axiosConfig.data !== '' &&
396
+ !(axiosConfig.data instanceof Buffer) &&
397
+ !allHeaders.some((headerKey) => headerKey.toLowerCase() === 'content-type')) {
398
+ // Use default header for application/json
399
+ // If we don't specify this here, axios will add
400
+ // application/json; charset=utf-8
401
+ // and this breaks a lot of stuff
402
+ axiosConfig.headers = Object.assign(axiosConfig.headers || {}, {
403
+ 'content-type': 'application/json',
404
+ });
405
+ }
406
+ /**
407
+ * Missing properties:
408
+ * encoding (need testing)
409
+ * gzip (ignored - default already works)
410
+ * resolveWithFullResponse (implemented elsewhere)
411
+ * simple (???)
412
+ */
413
+ return axiosConfig;
414
+ });
415
+ }
416
+ function digestAuthAxiosConfig(axiosConfig, response, auth) {
417
+ var _a;
418
+ const authDetails = response.headers['www-authenticate']
419
+ .split(',')
420
+ .map((v) => v.split('='));
421
+ if (authDetails) {
422
+ const nonceCount = `000000001`;
423
+ const cnonce = crypto.randomBytes(24).toString('hex');
424
+ const realm = authDetails
425
+ .find((el) => el[0].toLowerCase().indexOf('realm') > -1)[1]
426
+ .replace(/"/g, '');
427
+ const opaque = authDetails
428
+ .find((el) => el[0].toLowerCase().indexOf('opaque') > -1)[1]
429
+ .replace(/"/g, '');
430
+ const nonce = authDetails
431
+ .find((el) => el[0].toLowerCase().indexOf('nonce') > -1)[1]
432
+ .replace(/"/g, '');
433
+ const ha1 = crypto
434
+ .createHash('md5')
435
+ .update(`${auth === null || auth === void 0 ? void 0 : auth.username}:${realm}:${auth === null || auth === void 0 ? void 0 : auth.password}`)
436
+ .digest('hex');
437
+ const path = new url.URL(axiosConfig.url).pathname;
438
+ const ha2 = crypto
439
+ .createHash('md5')
440
+ .update(`${(_a = axiosConfig.method) !== null && _a !== void 0 ? _a : 'GET'}:${path}`)
441
+ .digest('hex');
442
+ const response = crypto
443
+ .createHash('md5')
444
+ .update(`${ha1}:${nonce}:${nonceCount}:${cnonce}:auth:${ha2}`)
445
+ .digest('hex');
446
+ const authorization = `Digest username="${auth === null || auth === void 0 ? void 0 : auth.username}",realm="${realm}",` +
447
+ `nonce="${nonce}",uri="${path}",qop="auth",algorithm="MD5",` +
448
+ `response="${response}",nc="${nonceCount}",cnonce="${cnonce}",opaque="${opaque}"`;
449
+ if (axiosConfig.headers) {
450
+ axiosConfig.headers['authorization'] = authorization;
451
+ }
452
+ else {
453
+ axiosConfig.headers = { authorization };
454
+ }
455
+ }
456
+ return axiosConfig;
457
+ }
458
+ function proxyRequestToAxios(uriOrObject, options) {
459
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
460
+ // tslint:disable-line:no-any
461
+ var _a;
462
+ let axiosConfig = {};
463
+ let axiosPromise;
464
+ let configObject;
465
+ if (uriOrObject !== undefined && typeof uriOrObject === 'string') {
466
+ axiosConfig.url = uriOrObject;
467
+ }
468
+ if (uriOrObject !== undefined && typeof uriOrObject === 'object') {
469
+ configObject = uriOrObject;
470
+ }
471
+ else {
472
+ configObject = options || {};
473
+ }
474
+ axiosConfig = Object.assign(axiosConfig, yield parseRequestObject(configObject));
475
+ workflow_1.LoggerProxy.debug('Proxying request to axios');
476
+ if (((_a = configObject.auth) === null || _a === void 0 ? void 0 : _a.sendImmediately) === false) {
477
+ // for digest-auth
478
+ const { auth } = axiosConfig;
479
+ delete axiosConfig.auth;
480
+ // eslint-disable-next-line no-async-promise-executor
481
+ axiosPromise = new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
482
+ var _a;
483
+ try {
484
+ const result = yield (0, axios_1.default)(axiosConfig);
485
+ resolve(result);
486
+ }
487
+ catch (resp) {
488
+ if (resp.response === undefined ||
489
+ resp.response.status !== 401 ||
490
+ !((_a = resp.response.headers['www-authenticate']) === null || _a === void 0 ? void 0 : _a.includes('nonce'))) {
491
+ reject(resp);
492
+ }
493
+ axiosConfig = digestAuthAxiosConfig(axiosConfig, resp.response, auth);
494
+ resolve((0, axios_1.default)(axiosConfig));
495
+ }
496
+ }));
497
+ }
498
+ else {
499
+ axiosPromise = (0, axios_1.default)(axiosConfig);
500
+ }
501
+ return new Promise((resolve, reject) => {
502
+ axiosPromise
503
+ .then((response) => {
504
+ if (configObject.resolveWithFullResponse === true) {
505
+ let body = response.data;
506
+ if (response.data === '') {
507
+ if (axiosConfig.responseType === 'arraybuffer') {
508
+ body = Buffer.alloc(0);
509
+ }
510
+ else {
511
+ body = undefined;
512
+ }
513
+ }
514
+ resolve({
515
+ body,
516
+ headers: response.headers,
517
+ statusCode: response.status,
518
+ statusMessage: response.statusText,
519
+ request: response.request,
520
+ });
521
+ }
522
+ else {
523
+ let body = response.data;
524
+ if (response.data === '') {
525
+ if (axiosConfig.responseType === 'arraybuffer') {
526
+ body = Buffer.alloc(0);
527
+ }
528
+ else {
529
+ body = undefined;
530
+ }
531
+ }
532
+ resolve(body);
533
+ }
534
+ })
535
+ .catch((error) => {
536
+ var _a, _b;
537
+ if (configObject.simple === false && error.response) {
538
+ if (configObject.resolveWithFullResponse) {
539
+ resolve({
540
+ body: error.response.data,
541
+ headers: error.response.headers,
542
+ statusCode: error.response.status,
543
+ statusMessage: error.response.statusText,
544
+ });
545
+ }
546
+ else {
547
+ resolve(error.response.data);
548
+ }
549
+ return;
550
+ }
551
+ workflow_1.LoggerProxy.debug('Request proxied to Axios failed', { error });
552
+ // Axios hydrates the original error with more data. We extract them.
553
+ // https://github.com/axios/axios/blob/master/lib/core/enhanceError.js
554
+ // Note: `code` is ignored as it's an expected part of the errorData.
555
+ const { request, response, isAxiosError, toJSON, config } = error, errorData = tslib_1.__rest(error, ["request", "response", "isAxiosError", "toJSON", "config"]);
556
+ if (response) {
557
+ error.message = `${response.status} - ${JSON.stringify(response.data)}`;
558
+ }
559
+ error.cause = errorData;
560
+ error.error = ((_a = error.response) === null || _a === void 0 ? void 0 : _a.data) || errorData;
561
+ error.statusCode = (_b = error.response) === null || _b === void 0 ? void 0 : _b.status;
562
+ error.options = config || {};
563
+ // Remove not needed data and so also remove circular references
564
+ error.request = undefined;
565
+ error.config = undefined;
566
+ error.options.adapter = undefined;
567
+ error.options.httpsAgent = undefined;
568
+ error.options.paramsSerializer = undefined;
569
+ error.options.transformRequest = undefined;
570
+ error.options.transformResponse = undefined;
571
+ error.options.validateStatus = undefined;
572
+ reject(error);
573
+ });
574
+ });
575
+ });
576
+ }
577
+ function convertN8nRequestToAxios(n8nRequest) {
578
+ // Destructure properties with the same name first.
579
+ const { headers, method, timeout, auth, proxy, url } = n8nRequest;
580
+ const axiosRequest = {
581
+ headers: headers !== null && headers !== void 0 ? headers : {},
582
+ method,
583
+ timeout,
584
+ auth,
585
+ proxy,
586
+ url,
587
+ };
588
+ axiosRequest.params = n8nRequest.qs;
589
+ if (n8nRequest.baseURL !== undefined) {
590
+ axiosRequest.baseURL = n8nRequest.baseURL;
591
+ }
592
+ if (n8nRequest.disableFollowRedirect === true) {
593
+ axiosRequest.maxRedirects = 0;
594
+ }
595
+ if (n8nRequest.encoding !== undefined) {
596
+ axiosRequest.responseType = n8nRequest.encoding;
597
+ }
598
+ if (n8nRequest.skipSslCertificateValidation === true) {
599
+ axiosRequest.httpsAgent = new https_1.Agent({
600
+ rejectUnauthorized: false,
601
+ });
602
+ }
603
+ if (n8nRequest.arrayFormat !== undefined) {
604
+ axiosRequest.paramsSerializer = (params) => {
605
+ return (0, qs_1.stringify)(params, { arrayFormat: n8nRequest.arrayFormat });
606
+ };
607
+ }
608
+ if (n8nRequest.body) {
609
+ axiosRequest.data = n8nRequest.body;
610
+ // Let's add some useful header standards here.
611
+ const existingContentTypeHeaderKey = axiosRequest.headers ? searchForHeader(axiosRequest.headers, 'content-type') : undefined;
612
+ if (existingContentTypeHeaderKey === undefined) {
613
+ // We are only setting content type headers if the user did
614
+ // not set it already manually. We're not overriding, even if it's wrong.
615
+ if (axiosRequest.data instanceof FormData) {
616
+ axiosRequest.headers = axiosRequest.headers || {};
617
+ axiosRequest.headers['Content-Type'] = 'multipart/form-data';
618
+ }
619
+ else if (axiosRequest.data instanceof url_1.URLSearchParams) {
620
+ axiosRequest.headers = axiosRequest.headers || {};
621
+ axiosRequest.headers['Content-Type'] = 'application/x-www-form-urlencoded';
622
+ }
623
+ }
624
+ }
625
+ if (n8nRequest.json) {
626
+ const key = axiosRequest.headers ? searchForHeader(axiosRequest.headers, 'accept') : undefined;
627
+ // If key exists, then the user has set both accept
628
+ // header and the json flag. Header should take precedence.
629
+ if (!key) {
630
+ axiosRequest.headers = axiosRequest.headers || {};
631
+ axiosRequest.headers.Accept = 'application/json';
632
+ }
633
+ }
634
+ const userAgentHeader = axiosRequest.headers ? searchForHeader(axiosRequest.headers, 'user-agent') : undefined;
635
+ // If key exists, then the user has set both accept
636
+ // header and the json flag. Header should take precedence.
637
+ if (!userAgentHeader) {
638
+ axiosRequest.headers = axiosRequest.headers || {};
639
+ axiosRequest.headers['User-Agent'] = 'n8n';
640
+ }
641
+ if (n8nRequest.ignoreHttpStatusErrors) {
642
+ axiosRequest.validateStatus = () => true;
643
+ }
644
+ return axiosRequest;
645
+ }
646
+ function httpRequest(requestOptions) {
647
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
648
+ const axiosRequest = convertN8nRequestToAxios(requestOptions);
649
+ const result = yield (0, axios_1.default)(axiosRequest);
650
+ if (requestOptions.returnFullResponse) {
651
+ return {
652
+ body: result.data,
653
+ headers: result.headers,
654
+ statusCode: result.status,
655
+ statusMessage: result.statusText,
656
+ };
657
+ }
658
+ return result.data;
659
+ });
660
+ }
661
+ /**
662
+ * Returns binary data buffer for given item index and property name.
663
+ *
664
+ * @export
665
+ * @param {ITaskDataConnections} inputData
666
+ * @param {number} itemIndex
667
+ * @param {string} propertyName
668
+ * @param {number} inputIndex
669
+ * @returns {Promise<Buffer>}
670
+ */
671
+ function getBinaryDataBuffer(inputData, itemIndex, propertyName, inputIndex) {
672
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
673
+ const binaryData = inputData['main'][inputIndex][itemIndex].binary[propertyName];
674
+ return BinaryDataManager_1.BinaryDataManager.getInstance().retrieveBinaryData(binaryData);
675
+ });
676
+ }
677
+ /**
678
+ * Takes a buffer and converts it into the format n8n uses. It encodes the binary data as
679
+ * base64 and adds metadata.
680
+ *
681
+ * @export
682
+ * @param {Buffer} binaryData
683
+ * @param {string} [filePath]
684
+ * @param {string} [mimeType]
685
+ * @returns {Promise<IBinaryData>}
686
+ */
687
+ function prepareBinaryData(binaryData, executionId, filePath, mimeType) {
688
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
689
+ if (!mimeType) {
690
+ // If no mime type is given figure it out
691
+ if (filePath) {
692
+ // Use file path to guess mime type
693
+ const mimeTypeLookup = (0, mime_types_1.lookup)(filePath);
694
+ if (mimeTypeLookup) {
695
+ mimeType = mimeTypeLookup;
696
+ }
697
+ }
698
+ if (!mimeType) {
699
+ // Use buffer to guess mime type
700
+ const fileTypeData = yield (0, file_type_1.fromBuffer)(binaryData);
701
+ if (fileTypeData) {
702
+ mimeType = fileTypeData.mime;
703
+ }
704
+ }
705
+ if (!mimeType) {
706
+ // Fall back to text
707
+ mimeType = 'text/plain';
708
+ }
709
+ }
710
+ const returnData = {
711
+ mimeType,
712
+ data: '',
713
+ };
714
+ if (filePath) {
715
+ if (filePath.includes('?')) {
716
+ // Remove maybe present query parameters
717
+ filePath = filePath.split('?').shift();
718
+ }
719
+ const filePathParts = path.parse(filePath);
720
+ if (filePathParts.dir !== '') {
721
+ returnData.directory = filePathParts.dir;
722
+ }
723
+ returnData.fileName = filePathParts.base;
724
+ // Remove the dot
725
+ const fileExtension = filePathParts.ext.slice(1);
726
+ if (fileExtension) {
727
+ returnData.fileExtension = fileExtension;
728
+ }
729
+ }
730
+ return BinaryDataManager_1.BinaryDataManager.getInstance().storeBinaryData(returnData, binaryData, executionId);
731
+ });
732
+ }
733
+ function getCurrentOAuth2AccessToken(credentialsType, node, additionalData, oAuth2Options) {
734
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
735
+ var _a, _b, _c, _d, _e, _f;
736
+ const credentials = yield this.getCredentials(credentialsType);
737
+ if (!credentials) {
738
+ throw new workflow_1.NodeOperationError(node, `No credentials of type "${credentialsType}" were returned!`, { description: 'Credentials not found' });
739
+ }
740
+ const clientId = credentials['clientId'];
741
+ const clientSecret = credentials['clientSecret'];
742
+ const scope = credentials['scope'];
743
+ const grantType = credentials['grantType'];
744
+ const authUrl = credentials['authUrl'];
745
+ const accessTokenUrl = credentials['accessTokenUrl'];
746
+ const httpAgent = credentials['httpAgent'];
747
+ const oauthTokenData = ((_a = credentials['oauthTokenData']) !== null && _a !== void 0 ? _a : {});
748
+ let accessToken = ((_b = oauthTokenData === null || oauthTokenData === void 0 ? void 0 : oauthTokenData['accessToken']) !== null && _b !== void 0 ? _b : "");
749
+ let refreshToken = ((_c = oauthTokenData === null || oauthTokenData === void 0 ? void 0 : oauthTokenData['refreshToken']) !== null && _c !== void 0 ? _c : "");
750
+ let expiresAt = ((_d = oauthTokenData === null || oauthTokenData === void 0 ? void 0 : oauthTokenData['expiresAt']) !== null && _d !== void 0 ? _d : "");
751
+ let expiresIn = ((_e = oauthTokenData === null || oauthTokenData === void 0 ? void 0 : oauthTokenData['expiresIn']) !== null && _e !== void 0 ? _e : 0);
752
+ let tokenType = ((_f = oauthTokenData === null || oauthTokenData === void 0 ? void 0 : oauthTokenData['tokenType']) !== null && _f !== void 0 ? _f : "");
753
+ const isExpired = !accessToken || !expiresAt || new Date(expiresAt).getTime() <= Date.now();
754
+ if (isExpired) {
755
+ workflow_1.LoggerProxy.debug(`Node "${node.name}" is using credential "${credentialsType}", however the access token has expired. This will now be refreshed using the "${grantType}" flow.`);
756
+ if (!authUrl) {
757
+ throw new workflow_1.NodeOperationError(node, `The "authUrl" property is required for the "${grantType}" flow. Please check your credentials configuration.`, { description: 'Missing authUrl' });
758
+ }
759
+ const config = {
760
+ client: { id: clientId, secret: clientSecret },
761
+ auth: { tokenHost: authUrl, tokenPath: accessTokenUrl },
762
+ http: { agent: httpAgent },
763
+ options: { authorizationMethod: 'body' },
764
+ };
765
+ if (grantType === 'authorizationCode') {
766
+ const client = new simple_oauth2_1.AuthorizationCode(config);
767
+ let token = client.createToken({
768
+ access_token: (0, lodash_1.get)(oauthTokenData, oAuth2Options === null || oAuth2Options === void 0 ? void 0 : oAuth2Options.property) || accessToken,
769
+ refresh_token: refreshToken,
770
+ token_type: (oAuth2Options === null || oAuth2Options === void 0 ? void 0 : oAuth2Options.tokenType) || tokenType || 'Bearer',
771
+ expires_at: expiresAt,
772
+ expires_in: expiresIn,
773
+ });
774
+ const refreshOptions = (oAuth2Options === null || oAuth2Options === void 0 ? void 0 : oAuth2Options.includeCredentialsOnRefreshOnBody) ? {
775
+ body: {
776
+ client_id: clientId,
777
+ client_secret: clientSecret,
778
+ },
779
+ headers: {
780
+ Authorization: '', // override default basic auth
781
+ },
782
+ } : {};
783
+ token = yield token.refresh(refreshOptions);
784
+ accessToken = token.token['access_token'];
785
+ refreshToken = token.token['refresh_token'] || refreshToken;
786
+ expiresAt = token.token['expires_at'];
787
+ expiresIn = token.token['expires_in'];
788
+ tokenType = token.token['token_type'] || 'Bearer';
789
+ }
790
+ else if (grantType === 'clientCredentials') {
791
+ const client = new simple_oauth2_1.ClientCredentials(config);
792
+ const token = yield client.getToken({ scope });
793
+ accessToken = token.token['access_token'];
794
+ refreshToken = token.token['refresh_token'] || refreshToken;
795
+ expiresAt = token.token['expires_at'];
796
+ expiresIn = token.token['expires_in'];
797
+ tokenType = token.token['token_type'] || 'Bearer';
798
+ }
799
+ else {
800
+ throw new Error(`Unsupported grant type "${grantType}" for Microsoft Graph API`);
801
+ }
802
+ oauthTokenData["accessToken"] = accessToken;
803
+ oauthTokenData["refreshToken"] = refreshToken;
804
+ oauthTokenData["expiresAt"] = expiresAt;
805
+ oauthTokenData["expiresIn"] = expiresIn;
806
+ oauthTokenData["tokenType"] = tokenType;
807
+ if (!node.credentials || !node.credentials[credentialsType]) {
808
+ throw new Error(`Node "${node.name}" has no credentials of type "${credentialsType}"`);
809
+ }
810
+ yield additionalData.credentialsHelper.updateCredentials(node.credentials[credentialsType], credentialsType, credentials);
811
+ workflow_1.LoggerProxy.debug(`Access token for credential "${credentialsType}" has been refreshed.`);
812
+ }
813
+ return accessToken;
814
+ });
815
+ }
816
+ function requestOAuth2(credentialsType_1, requestOptions_1, node_1, additionalData_1, oAuth2Options_1) {
817
+ return tslib_1.__awaiter(this, arguments, void 0, function* (credentialsType, requestOptions, node, additionalData, oAuth2Options, isN8nRequest = false) {
818
+ var _a;
819
+ const credentials = (yield this.getCredentials(credentialsType));
820
+ if (!credentials) {
821
+ throw new Error('No credentials were returned!');
822
+ }
823
+ const oauthTokenData = credentials['oauthTokenData'];
824
+ if (!oauthTokenData) {
825
+ throw new Error('OAuth credentials not connected!');
826
+ }
827
+ const config = {
828
+ client: {
829
+ id: credentials['clientId'],
830
+ secret: credentials['clientSecret'],
831
+ },
832
+ auth: {
833
+ tokenHost: credentials['authUrl'],
834
+ tokenPath: credentials['accessTokenUrl'],
835
+ },
836
+ http: {
837
+ agent: credentials['httpAgent'],
838
+ },
839
+ options: {
840
+ authorizationMethod: 'body',
841
+ },
842
+ };
843
+ const client = new simple_oauth2_1.AuthorizationCode(config);
844
+ // Construct token from saved data
845
+ const tokenObject = client.createToken({
846
+ access_token: (0, lodash_1.get)(oauthTokenData, oAuth2Options === null || oAuth2Options === void 0 ? void 0 : oAuth2Options.property) || oauthTokenData['accessToken'],
847
+ refresh_token: oauthTokenData['refreshToken'],
848
+ token_type: (oAuth2Options === null || oAuth2Options === void 0 ? void 0 : oAuth2Options.tokenType) || oauthTokenData['tokenType'] || 'Bearer',
849
+ expires_at: oauthTokenData['expiresAt'],
850
+ expires_in: oauthTokenData['expiresIn'],
851
+ });
852
+ const currentToken = tokenObject;
853
+ const signedOptions = Object.assign(Object.assign({}, requestOptions), { headers: Object.assign(Object.assign({}, (requestOptions.headers || {})), { Authorization: `${currentToken.token["token_type"]} ${currentToken.token["access_token"]}` }) });
854
+ // Remove 'Bearer' if `keepBearer` is false
855
+ if ((oAuth2Options === null || oAuth2Options === void 0 ? void 0 : oAuth2Options.keepBearer) === false && signedOptions.headers.Authorization) {
856
+ signedOptions.headers.Authorization = signedOptions.headers.Authorization.split(' ')[1];
857
+ }
858
+ try {
859
+ return yield this.helpers['request'](signedOptions);
860
+ }
861
+ catch (error) {
862
+ const statusCodeReturned = (_a = oAuth2Options === null || oAuth2Options === void 0 ? void 0 : oAuth2Options.tokenExpiredStatusCode) !== null && _a !== void 0 ? _a : 401;
863
+ if (error.statusCode === statusCodeReturned && currentToken.expired()) {
864
+ // Refresh token
865
+ workflow_1.LoggerProxy.debug(`OAuth2 token for "${credentialsType}" used by node "${node.name}" expired. Refreshing...`);
866
+ workflow_1.LoggerProxy.info(`OAuth2 token for "${credentialsType}" used by node "${node.name}" expired. Refreshing...`);
867
+ const refreshOptions = {};
868
+ if (oAuth2Options === null || oAuth2Options === void 0 ? void 0 : oAuth2Options.includeCredentialsOnRefreshOnBody) {
869
+ refreshOptions.body = {
870
+ client_id: credentials['clientId'],
871
+ client_secret: credentials['clientSecret'],
872
+ };
873
+ refreshOptions.headers = {
874
+ Authorization: '', // override default basic auth
875
+ };
876
+ }
877
+ let refreshedToken;
878
+ try {
879
+ refreshedToken = yield currentToken.refresh(refreshOptions);
880
+ }
881
+ catch (error) {
882
+ throw new Error("Failed to refresh token: " + error.message);
883
+ }
884
+ credentials['oauthTokenData'] = {
885
+ accessToken: refreshedToken.token["access_token"],
886
+ refreshToken: refreshedToken.token["refresh_token"] || currentToken.token["refresh_token"],
887
+ expiresAt: refreshedToken.token["expires_at"],
888
+ expiresIn: refreshedToken.token["expires_in"],
889
+ tokenType: refreshedToken.token["token_type"],
890
+ };
891
+ // Persist new token
892
+ if (!node.credentials || !node.credentials[credentialsType]) {
893
+ throw new Error(`Node "${node.name}" has no credentials of type "${credentialsType}"`);
894
+ }
895
+ yield additionalData.credentialsHelper.updateCredentials(node.credentials[credentialsType], credentialsType, credentials);
896
+ workflow_1.LoggerProxy.debug(`OAuth2 token for "${credentialsType}" used by node "${node.name}" has been renewed.`);
897
+ workflow_1.LoggerProxy.info(`OAuth2 token for "${credentialsType}" used by node "${node.name}" has been renewed.`);
898
+ // Retry the original request with the new token
899
+ const retryOptions = Object.assign(Object.assign({}, requestOptions), { headers: Object.assign(Object.assign({}, (requestOptions.headers || {})), { Authorization: `${refreshedToken.token["token_type"]} ${refreshedToken.token["access_token"]}` }) });
900
+ if ((oAuth2Options === null || oAuth2Options === void 0 ? void 0 : oAuth2Options.keepBearer) === false && retryOptions.headers.Authorization) {
901
+ retryOptions.headers.Authorization = retryOptions.headers.Authorization.split(' ')[1];
902
+ }
903
+ return isN8nRequest
904
+ ? this.helpers.httpRequest(retryOptions)
905
+ : this.helpers['request'](retryOptions);
906
+ }
907
+ throw error;
908
+ }
909
+ });
910
+ }
911
+ /* Makes a request using OAuth1 data for authentication
912
+ *
913
+ * @export
914
+ * @param {IAllExecuteFunctions} this
915
+ * @param {string} credentialsType
916
+ * @param {(OptionsWithUrl | requestPromise.RequestPromiseOptions)} requestOptionså
917
+ * @returns
918
+ */
919
+ function requestOAuth1(credentialsType_1, requestOptions_1) {
920
+ return tslib_1.__awaiter(this, arguments, void 0, function* (credentialsType, requestOptions, isN8nRequest = false) {
921
+ const credentials = (yield this.getCredentials(credentialsType));
922
+ if (credentials === undefined) {
923
+ throw new Error('No credentials were returned!');
924
+ }
925
+ if (credentials['oauthTokenData'] === undefined) {
926
+ throw new Error('OAuth credentials not connected!');
927
+ }
928
+ const oauth = new clientOAuth1({
929
+ consumer: {
930
+ key: credentials['consumerKey'],
931
+ secret: credentials['consumerSecret'],
932
+ },
933
+ signature_method: credentials['signatureMethod'],
934
+ hash_function(base, key) {
935
+ const algorithm = credentials['signatureMethod'] === 'HMAC-SHA1' ? 'sha1' : 'sha256';
936
+ return (0, crypto_1.createHmac)(algorithm, key).update(base).digest('base64');
937
+ },
938
+ });
939
+ const oauthTokenData = credentials['oauthTokenData'];
940
+ const token = {
941
+ key: oauthTokenData['oauth_token'],
942
+ secret: oauthTokenData['oauth_token_secret'],
943
+ };
944
+ // @ts-ignore
945
+ requestOptions.data = Object.assign(Object.assign({}, requestOptions.qs), requestOptions.form);
946
+ // Fixes issue that OAuth1 library only works with "url" property and not with "uri"
947
+ // @ts-ignore
948
+ if (requestOptions.uri && !requestOptions.url) {
949
+ // @ts-ignore
950
+ requestOptions.url = requestOptions.uri;
951
+ // @ts-ignore
952
+ delete requestOptions.uri;
953
+ }
954
+ // @ts-ignore
955
+ requestOptions.headers = oauth.toHeader(oauth.authorize(requestOptions, token));
956
+ if (isN8nRequest) {
957
+ return this.helpers.httpRequest(requestOptions);
958
+ }
959
+ return this.helpers['request'](requestOptions).catch((error) => tslib_1.__awaiter(this, void 0, void 0, function* () {
960
+ // Unknown error so simply throw it
961
+ throw error;
962
+ }));
963
+ });
964
+ }
965
+ function httpRequestWithAuthentication(credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions) {
966
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
967
+ try {
968
+ const parentTypes = additionalData.credentialsHelper.getParentTypes(credentialsType);
969
+ if (parentTypes.includes('oAuth1Api')) {
970
+ return yield requestOAuth1.call(this, credentialsType, requestOptions, true);
971
+ }
972
+ if (parentTypes.includes('oAuth2Api')) {
973
+ return yield requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, additionalCredentialOptions === null || additionalCredentialOptions === void 0 ? void 0 : additionalCredentialOptions.oauth2, true);
974
+ }
975
+ let credentialsDecrypted;
976
+ if (additionalCredentialOptions === null || additionalCredentialOptions === void 0 ? void 0 : additionalCredentialOptions.credentialsDecrypted) {
977
+ credentialsDecrypted = additionalCredentialOptions.credentialsDecrypted.data;
978
+ }
979
+ else {
980
+ credentialsDecrypted = yield this.getCredentials(credentialsType);
981
+ }
982
+ if (credentialsDecrypted === undefined) {
983
+ throw new workflow_1.NodeOperationError(node, `Node "${node.name}" does not have any credentials of type "${credentialsType}" set!`);
984
+ }
985
+ requestOptions = yield additionalData.credentialsHelper.authenticate(credentialsDecrypted, credentialsType, requestOptions, workflow, node);
986
+ return yield httpRequest(requestOptions);
987
+ }
988
+ catch (error) {
989
+ throw new workflow_1.NodeApiError(this.getNode(), error);
990
+ }
991
+ });
992
+ }
993
+ /**
994
+ * Takes generic input data and brings it into the json format n8n uses.
995
+ *
996
+ * @export
997
+ * @param {(IDataObject | IDataObject[])} jsonData
998
+ * @returns {INodeExecutionData[]}
999
+ */
1000
+ function returnJsonArray(jsonData) {
1001
+ const returnData = [];
1002
+ if (!Array.isArray(jsonData)) {
1003
+ jsonData = [jsonData];
1004
+ }
1005
+ jsonData.forEach((data) => {
1006
+ returnData.push({ json: data });
1007
+ });
1008
+ return returnData;
1009
+ }
1010
+ /**
1011
+ * Automatically put the objects under a 'json' key and don't error,
1012
+ * if some objects contain json/binary keys and others don't, throws error 'Inconsistent item format'
1013
+ *
1014
+ * @export
1015
+ * @param {INodeExecutionData | INodeExecutionData[]} executionData
1016
+ * @returns {INodeExecutionData[]}
1017
+ */
1018
+ function normalizeItems(executionData) {
1019
+ if (typeof executionData === 'object' && !Array.isArray(executionData))
1020
+ executionData = [{ json: executionData }];
1021
+ if (executionData.every((item) => typeof item === 'object' && 'json' in item))
1022
+ return executionData;
1023
+ if (executionData.some((item) => typeof item === 'object' && 'json' in item)) {
1024
+ throw new Error('Inconsistent item format');
1025
+ }
1026
+ if (executionData.every((item) => typeof item === 'object' && 'binary' in item)) {
1027
+ const normalizedItems = [];
1028
+ executionData.forEach((item) => {
1029
+ const json = Object.keys(item).reduce((acc, key) => {
1030
+ if (key === 'binary')
1031
+ return acc;
1032
+ return Object.assign(Object.assign({}, acc), { [key]: item[key] });
1033
+ }, {});
1034
+ normalizedItems.push({
1035
+ json,
1036
+ binary: item.binary,
1037
+ });
1038
+ });
1039
+ return normalizedItems;
1040
+ }
1041
+ if (executionData.some((item) => typeof item === 'object' && 'binary' in item)) {
1042
+ throw new Error('Inconsistent item format');
1043
+ }
1044
+ return executionData.map((item) => {
1045
+ return { json: item };
1046
+ });
1047
+ }
1048
+ // TODO: Move up later
1049
+ function requestWithAuthentication(credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions) {
1050
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1051
+ try {
1052
+ const parentTypes = additionalData.credentialsHelper.getParentTypes(credentialsType);
1053
+ if (parentTypes.includes('oAuth1Api')) {
1054
+ return yield requestOAuth1.call(this, credentialsType, requestOptions, false);
1055
+ }
1056
+ if (parentTypes.includes('oAuth2Api')) {
1057
+ return yield requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, additionalCredentialOptions === null || additionalCredentialOptions === void 0 ? void 0 : additionalCredentialOptions.oauth2, false);
1058
+ }
1059
+ let credentialsDecrypted;
1060
+ if (additionalCredentialOptions === null || additionalCredentialOptions === void 0 ? void 0 : additionalCredentialOptions.credentialsDecrypted) {
1061
+ credentialsDecrypted = additionalCredentialOptions.credentialsDecrypted.data;
1062
+ }
1063
+ else {
1064
+ credentialsDecrypted = yield this.getCredentials(credentialsType);
1065
+ }
1066
+ if (credentialsDecrypted === undefined) {
1067
+ throw new workflow_1.NodeOperationError(node, `Node "${node.name}" does not have any credentials of type "${credentialsType}" set!`);
1068
+ }
1069
+ requestOptions = yield additionalData.credentialsHelper.authenticate(credentialsDecrypted, credentialsType, requestOptions, workflow, node);
1070
+ return yield proxyRequestToAxios(requestOptions);
1071
+ }
1072
+ catch (error) {
1073
+ throw new workflow_1.NodeApiError(this.getNode(), error);
1074
+ }
1075
+ });
1076
+ }
1077
+ /**
1078
+ * Returns the additional keys for Expressions and Function-Nodes
1079
+ *
1080
+ * @export
1081
+ * @param {IWorkflowExecuteAdditionalData} additionalData
1082
+ * @returns {(IWorkflowDataProxyAdditionalKeys)}
1083
+ */
1084
+ function getAdditionalKeys(additionalData) {
1085
+ const executionId = additionalData.executionId || src_1.PLACEHOLDER_EMPTY_EXECUTION_ID;
1086
+ return {
1087
+ $executionId: executionId,
1088
+ $resumeWebhookUrl: `${additionalData.webhookWaitingBaseUrl}/${executionId}`,
1089
+ };
1090
+ }
1091
+ /**
1092
+ * Returns the requested decrypted credentials if the node has access to them.
1093
+ *
1094
+ * @export
1095
+ * @param {Workflow} workflow Workflow which requests the data
1096
+ * @param {INode} node Node which request the data
1097
+ * @param {string} type The credential type to return
1098
+ * @param {IWorkflowExecuteAdditionalData} additionalData
1099
+ * @returns {(ICredentialDataDecryptedObject | undefined)}
1100
+ */
1101
+ function getCredentials(workflow, node, type, additionalData, mode, runExecutionData, runIndex, connectionInputData, itemIndex) {
1102
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1103
+ // Get the NodeType as it has the information if the credentials are required
1104
+ const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
1105
+ if (nodeType === undefined) {
1106
+ throw new workflow_1.NodeOperationError(node, `Node type "${node.type}" is not known so can not get credentials!`);
1107
+ }
1108
+ // Hardcode for now for security reasons that only a single node can access
1109
+ // all credentials
1110
+ const fullAccess = ['n8n-nodes-base.httpRequest'].includes(node.type);
1111
+ let nodeCredentialDescription;
1112
+ if (!fullAccess) {
1113
+ if (nodeType.description.credentials === undefined) {
1114
+ throw new workflow_1.NodeOperationError(node, `Node type "${node.type}" does not have any credentials defined!`);
1115
+ }
1116
+ nodeCredentialDescription = nodeType.description.credentials.find((credentialTypeDescription) => credentialTypeDescription.name === type);
1117
+ if (nodeCredentialDescription === undefined) {
1118
+ throw new workflow_1.NodeOperationError(node, `Node type "${node.type}" does not have any credentials of type "${type}" defined!`);
1119
+ }
1120
+ if (!workflow_1.NodeHelpers.displayParameter(additionalData.currentNodeParameters || node.parameters, nodeCredentialDescription, node.parameters)) {
1121
+ // Credentials should not be displayed so return undefined even if they would be defined
1122
+ return undefined;
1123
+ }
1124
+ }
1125
+ // Check if node has any credentials defined
1126
+ if (!fullAccess && (!node.credentials || !node.credentials[type])) {
1127
+ // If none are defined check if the credentials are required or not
1128
+ if ((nodeCredentialDescription === null || nodeCredentialDescription === void 0 ? void 0 : nodeCredentialDescription.required) === true) {
1129
+ // Credentials are required so error
1130
+ if (!node.credentials) {
1131
+ throw new workflow_1.NodeOperationError(node, 'Node does not have any credentials set!');
1132
+ }
1133
+ if (!node.credentials[type]) {
1134
+ throw new workflow_1.NodeOperationError(node, `Node does not have any credentials set for "${type}"!`);
1135
+ }
1136
+ }
1137
+ else {
1138
+ // Credentials are not required so resolve with undefined
1139
+ return undefined;
1140
+ }
1141
+ }
1142
+ if (fullAccess && (!node.credentials || !node.credentials[type])) {
1143
+ // Make sure that fullAccess nodes still behave like before that if they
1144
+ // request access to credentials that are currently not set it returns undefined
1145
+ return undefined;
1146
+ }
1147
+ let expressionResolveValues;
1148
+ if (connectionInputData && runExecutionData && runIndex !== undefined) {
1149
+ expressionResolveValues = {
1150
+ connectionInputData,
1151
+ itemIndex: itemIndex || 0,
1152
+ node,
1153
+ runExecutionData,
1154
+ runIndex,
1155
+ workflow,
1156
+ };
1157
+ }
1158
+ const nodeCredentials = node.credentials
1159
+ ? node.credentials[type]
1160
+ : {};
1161
+ // TODO: solve using credentials via expression
1162
+ // if (name.charAt(0) === '=') {
1163
+ // // If the credential name is an expression resolve it
1164
+ // const additionalKeys = getAdditionalKeys(additionalData);
1165
+ // name = workflow.expression.getParameterValue(
1166
+ // name,
1167
+ // runExecutionData || null,
1168
+ // runIndex || 0,
1169
+ // itemIndex || 0,
1170
+ // node.name,
1171
+ // connectionInputData || [],
1172
+ // mode,
1173
+ // additionalKeys,
1174
+ // ) as string;
1175
+ // }
1176
+ const decryptedDataObject = yield additionalData.credentialsHelper.getDecrypted(nodeCredentials, type, mode, false, expressionResolveValues);
1177
+ return decryptedDataObject;
1178
+ });
1179
+ }
1180
+ /**
1181
+ * Returns a copy of the node
1182
+ *
1183
+ * @export
1184
+ * @param {INode} node
1185
+ * @returns {INode}
1186
+ */
1187
+ function getNode(node) {
1188
+ return JSON.parse(JSON.stringify(node));
1189
+ }
1190
+ /**
1191
+ * Returns the requested resolved (all expressions replaced) node parameters.
1192
+ *
1193
+ * @export
1194
+ * @param {Workflow} workflow
1195
+ * @param {(IRunExecutionData | null)} runExecutionData
1196
+ * @param {number} runIndex
1197
+ * @param {INodeExecutionData[]} connectionInputData
1198
+ * @param {INode} node
1199
+ * @param {string} parameterName
1200
+ * @param {number} itemIndex
1201
+ * @param {*} [fallbackValue]
1202
+ * @returns {(NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object)}
1203
+ */
1204
+ function getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, mode, additionalKeys, fallbackValue) {
1205
+ const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
1206
+ if (nodeType === undefined) {
1207
+ throw new Error(`Node type "${node.type}" is not known so can not return paramter value!`);
1208
+ }
1209
+ const value = (0, lodash_1.get)(node.parameters, parameterName, fallbackValue);
1210
+ if (value === undefined) {
1211
+ throw new Error(`Could not get parameter "${parameterName}"!`);
1212
+ }
1213
+ let returnData;
1214
+ try {
1215
+ returnData = workflow.expression.getParameterValue(value, runExecutionData, runIndex, itemIndex, node.name, connectionInputData, mode, additionalKeys);
1216
+ }
1217
+ catch (e) {
1218
+ e.message += ` [Error in parameter: "${parameterName}"]`;
1219
+ throw e;
1220
+ }
1221
+ return returnData;
1222
+ }
1223
+ /**
1224
+ * Returns if execution should be continued even if there was an error.
1225
+ *
1226
+ * @export
1227
+ * @param {INode} node
1228
+ * @returns {boolean}
1229
+ */
1230
+ function continueOnFail(node) {
1231
+ return (0, lodash_1.get)(node, 'continueOnFail', false);
1232
+ }
1233
+ /**
1234
+ * Returns the webhook URL of the webhook with the given name
1235
+ *
1236
+ * @export
1237
+ * @param {string} name
1238
+ * @param {Workflow} workflow
1239
+ * @param {INode} node
1240
+ * @param {IWorkflowExecuteAdditionalData} additionalData
1241
+ * @param {boolean} [isTest]
1242
+ * @returns {(string | undefined)}
1243
+ */
1244
+ function getNodeWebhookUrl(name, workflow, node, additionalData, mode, additionalKeys, isTest) {
1245
+ let baseUrl = additionalData.webhookBaseUrl;
1246
+ if (isTest === true) {
1247
+ baseUrl = additionalData.webhookTestBaseUrl;
1248
+ }
1249
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
1250
+ const webhookDescription = getWebhookDescription(name, workflow, node);
1251
+ if (webhookDescription === undefined) {
1252
+ return undefined;
1253
+ }
1254
+ const path = workflow.expression.getSimpleParameterValue(node, webhookDescription.path, mode, additionalKeys);
1255
+ if (path === undefined) {
1256
+ return undefined;
1257
+ }
1258
+ const isFullPath = workflow.expression.getSimpleParameterValue(node, webhookDescription.isFullPath, mode, additionalKeys, false);
1259
+ return workflow_1.NodeHelpers.getNodeWebhookUrl(baseUrl, workflow.id, node, path.toString(), isFullPath);
1260
+ }
1261
+ /**
1262
+ * Returns the timezone for the workflow
1263
+ *
1264
+ * @export
1265
+ * @param {Workflow} workflow
1266
+ * @param {IWorkflowExecuteAdditionalData} additionalData
1267
+ * @returns {string}
1268
+ */
1269
+ function getTimezone(workflow, additionalData) {
1270
+ // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
1271
+ if (workflow.settings !== undefined && workflow.settings['timezone'] !== undefined) {
1272
+ return workflow.settings.timezone;
1273
+ }
1274
+ return additionalData.timezone;
1275
+ }
1276
+ /**
1277
+ * Returns the full webhook description of the webhook with the given name
1278
+ *
1279
+ * @export
1280
+ * @param {string} name
1281
+ * @param {Workflow} workflow
1282
+ * @param {INode} node
1283
+ * @returns {(IWebhookDescription | undefined)}
1284
+ */
1285
+ function getWebhookDescription(name, workflow, node) {
1286
+ const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
1287
+ if (nodeType.description.webhooks === undefined) {
1288
+ // Node does not have any webhooks so return
1289
+ return undefined;
1290
+ }
1291
+ // eslint-disable-next-line no-restricted-syntax
1292
+ for (const webhookDescription of nodeType.description.webhooks) {
1293
+ if (webhookDescription.name === name) {
1294
+ return webhookDescription;
1295
+ }
1296
+ }
1297
+ return undefined;
1298
+ }
1299
+ /**
1300
+ * Returns the workflow metadata
1301
+ *
1302
+ * @export
1303
+ * @param {Workflow} workflow
1304
+ * @returns {IWorkflowMetadata}
1305
+ */
1306
+ function getWorkflowMetadata(workflow) {
1307
+ return {
1308
+ id: workflow.id,
1309
+ name: workflow.name,
1310
+ active: workflow.active,
1311
+ };
1312
+ }
1313
+ /**
1314
+ * Returns the execute functions the poll nodes have access to.
1315
+ *
1316
+ * @export
1317
+ * @param {Workflow} workflow
1318
+ * @param {INode} node
1319
+ * @param {IWorkflowExecuteAdditionalData} additionalData
1320
+ * @param {WorkflowExecuteMode} mode
1321
+ * @returns {ITriggerFunctions}
1322
+ */
1323
+ // TODO: Check if I can get rid of: additionalData, and so then maybe also at ActiveWorkflowRunner.add
1324
+ function getExecutePollFunctions(workflow, node, additionalData, mode, activation) {
1325
+ return ((workflow, node) => {
1326
+ return {
1327
+ __emit: (data) => {
1328
+ throw new Error('Overwrite NodeExecuteFunctions.getExecutePullFunctions.__emit function!');
1329
+ },
1330
+ getCredentials(type) {
1331
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1332
+ return getCredentials(workflow, node, type, additionalData, mode);
1333
+ });
1334
+ },
1335
+ getMode: () => {
1336
+ return mode;
1337
+ },
1338
+ getActivationMode: () => {
1339
+ return activation;
1340
+ },
1341
+ getNode: () => {
1342
+ return getNode(node);
1343
+ },
1344
+ getNodeParameter: (parameterName, fallbackValue) => {
1345
+ const runExecutionData = null;
1346
+ const itemIndex = 0;
1347
+ const runIndex = 0;
1348
+ const connectionInputData = [];
1349
+ return getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, mode, getAdditionalKeys(additionalData), fallbackValue);
1350
+ },
1351
+ getRestApiUrl: () => {
1352
+ return additionalData.restApiUrl;
1353
+ },
1354
+ getTimezone: () => {
1355
+ return getTimezone(workflow, additionalData);
1356
+ },
1357
+ getWorkflow: () => {
1358
+ return getWorkflowMetadata(workflow);
1359
+ },
1360
+ getWorkflowStaticData(type) {
1361
+ return workflow.getStaticData(type, node);
1362
+ },
1363
+ helpers: {
1364
+ httpRequest,
1365
+ prepareBinaryData(binaryData, filePath, mimeType) {
1366
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1367
+ return prepareBinaryData.call(this, binaryData, additionalData.executionId, filePath, mimeType);
1368
+ });
1369
+ },
1370
+ request: proxyRequestToAxios,
1371
+ requestWithAuthentication(credentialsType, requestOptions, additionalCredentialOptions) {
1372
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1373
+ return requestWithAuthentication.call(this, credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions);
1374
+ });
1375
+ },
1376
+ requestOAuth2(credentialsType, requestOptions, oAuth2Options) {
1377
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1378
+ return requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, oAuth2Options);
1379
+ });
1380
+ },
1381
+ getCurrentOAuth2AccessToken(credentialsType, oAuth2Options) {
1382
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1383
+ return getCurrentOAuth2AccessToken.call(this, credentialsType, node, additionalData, oAuth2Options);
1384
+ });
1385
+ },
1386
+ requestOAuth1(credentialsType, requestOptions) {
1387
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1388
+ return requestOAuth1.call(this, credentialsType, requestOptions);
1389
+ });
1390
+ },
1391
+ httpRequestWithAuthentication(credentialsType, requestOptions, additionalCredentialOptions) {
1392
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1393
+ return httpRequestWithAuthentication.call(this, credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions);
1394
+ });
1395
+ },
1396
+ returnJsonArray,
1397
+ },
1398
+ };
1399
+ })(workflow, node);
1400
+ }
1401
+ /**
1402
+ * Returns the execute functions the trigger nodes have access to.
1403
+ *
1404
+ * @export
1405
+ * @param {Workflow} workflow
1406
+ * @param {INode} node
1407
+ * @param {IWorkflowExecuteAdditionalData} additionalData
1408
+ * @param {WorkflowExecuteMode} mode
1409
+ * @returns {ITriggerFunctions}
1410
+ */
1411
+ // TODO: Check if I can get rid of: additionalData, and so then maybe also at ActiveWorkflowRunner.add
1412
+ function getExecuteTriggerFunctions(workflow, node, additionalData, mode, activation) {
1413
+ return ((workflow, node) => {
1414
+ return {
1415
+ emit: (data) => {
1416
+ throw new Error('Overwrite NodeExecuteFunctions.getExecuteTriggerFunctions.emit function!');
1417
+ },
1418
+ getCredentials(type) {
1419
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1420
+ return getCredentials(workflow, node, type, additionalData, mode);
1421
+ });
1422
+ },
1423
+ getNode: () => {
1424
+ return getNode(node);
1425
+ },
1426
+ getMode: () => {
1427
+ return mode;
1428
+ },
1429
+ getActivationMode: () => {
1430
+ return activation;
1431
+ },
1432
+ getNodeParameter: (parameterName, fallbackValue) => {
1433
+ const runExecutionData = null;
1434
+ const itemIndex = 0;
1435
+ const runIndex = 0;
1436
+ const connectionInputData = [];
1437
+ return getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, mode, getAdditionalKeys(additionalData), fallbackValue);
1438
+ },
1439
+ getRestApiUrl: () => {
1440
+ return additionalData.restApiUrl;
1441
+ },
1442
+ getTimezone: () => {
1443
+ return getTimezone(workflow, additionalData);
1444
+ },
1445
+ getWorkflow: () => {
1446
+ return getWorkflowMetadata(workflow);
1447
+ },
1448
+ getWorkflowStaticData(type) {
1449
+ return workflow.getStaticData(type, node);
1450
+ },
1451
+ helpers: {
1452
+ httpRequest,
1453
+ requestWithAuthentication(credentialsType, requestOptions, additionalCredentialOptions) {
1454
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1455
+ return requestWithAuthentication.call(this, credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions);
1456
+ });
1457
+ },
1458
+ prepareBinaryData(binaryData, filePath, mimeType) {
1459
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1460
+ return prepareBinaryData.call(this, binaryData, additionalData.executionId, filePath, mimeType);
1461
+ });
1462
+ },
1463
+ request: proxyRequestToAxios,
1464
+ requestOAuth2(credentialsType, requestOptions, oAuth2Options) {
1465
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1466
+ return requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, oAuth2Options);
1467
+ });
1468
+ },
1469
+ requestOAuth1(credentialsType, requestOptions) {
1470
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1471
+ return requestOAuth1.call(this, credentialsType, requestOptions);
1472
+ });
1473
+ },
1474
+ httpRequestWithAuthentication(credentialsType, requestOptions, additionalCredentialOptions) {
1475
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1476
+ return httpRequestWithAuthentication.call(this, credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions);
1477
+ });
1478
+ },
1479
+ returnJsonArray,
1480
+ },
1481
+ };
1482
+ })(workflow, node);
1483
+ }
1484
+ /**
1485
+ * Returns the execute functions regular nodes have access to.
1486
+ *
1487
+ * @export
1488
+ * @param {Workflow} workflow
1489
+ * @param {IRunExecutionData} runExecutionData
1490
+ * @param {number} runIndex
1491
+ * @param {INodeExecutionData[]} connectionInputData
1492
+ * @param {ITaskDataConnections} inputData
1493
+ * @param {INode} node
1494
+ * @param {IWorkflowExecuteAdditionalData} additionalData
1495
+ * @param {WorkflowExecuteMode} mode
1496
+ * @returns {IExecuteFunctions}
1497
+ */
1498
+ function getExecuteFunctions(workflow, runExecutionData, runIndex, connectionInputData, inputData, node, additionalData, mode, nodeTypeData, closeFunctions) {
1499
+ return ((workflow, runExecutionData, connectionInputData, inputData, node, nodeTypeData, closeFunctions) => {
1500
+ return {
1501
+ continueOnFail: () => {
1502
+ return continueOnFail(node);
1503
+ },
1504
+ evaluateExpression: (expression, itemIndex) => {
1505
+ return workflow.expression.resolveSimpleParameterValue(`=${expression}`, {}, runExecutionData, runIndex, itemIndex, node.name, connectionInputData, mode, getAdditionalKeys(additionalData));
1506
+ },
1507
+ executeWorkflow(workflowInfo, inputData) {
1508
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1509
+ return additionalData
1510
+ .executeWorkflow(workflowInfo, additionalData, inputData)
1511
+ .then((result) => tslib_1.__awaiter(this, void 0, void 0, function* () {
1512
+ return BinaryDataManager_1.BinaryDataManager.getInstance().duplicateBinaryData(result, additionalData.executionId);
1513
+ }));
1514
+ });
1515
+ },
1516
+ getContext(type) {
1517
+ return workflow_1.NodeHelpers.getContext(runExecutionData, type, node);
1518
+ },
1519
+ getCredentials(type, itemIndex) {
1520
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1521
+ return getCredentials(workflow, node, type, additionalData, mode, runExecutionData, runIndex, connectionInputData, itemIndex);
1522
+ });
1523
+ },
1524
+ getExecutionId: () => {
1525
+ return additionalData.executionId;
1526
+ },
1527
+ getInputData: (inputIndex = 0, inputName = 'main') => {
1528
+ if (!Object.prototype.hasOwnProperty.call(inputData, inputName)) {
1529
+ // Return empty array because else it would throw error when nothing is connected to input
1530
+ return [];
1531
+ }
1532
+ // TODO: Check if nodeType has input with that index defined
1533
+ if (inputData[inputName].length < inputIndex) {
1534
+ throw new Error(`Could not get input index "${inputIndex}" of input "${inputName}"!`);
1535
+ }
1536
+ if (inputData[inputName][inputIndex] === null) {
1537
+ // return [];
1538
+ throw new Error(`Value "${inputIndex}" of input "${inputName}" did not get set!`);
1539
+ }
1540
+ return inputData[inputName][inputIndex];
1541
+ },
1542
+ getNodeParameter: (parameterName, itemIndex, fallbackValue) => {
1543
+ return getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, mode, getAdditionalKeys(additionalData), fallbackValue);
1544
+ },
1545
+ getMode: () => {
1546
+ return mode;
1547
+ },
1548
+ getNode: () => {
1549
+ return getNode(node);
1550
+ },
1551
+ getRestApiUrl: () => {
1552
+ return additionalData.restApiUrl;
1553
+ },
1554
+ getTimezone: () => {
1555
+ return getTimezone(workflow, additionalData);
1556
+ },
1557
+ getWorkflow: () => {
1558
+ return getWorkflowMetadata(workflow);
1559
+ },
1560
+ getWorkflowDataProxy: (itemIndex) => {
1561
+ const dataProxy = new workflow_1.WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, node.name, connectionInputData, {}, mode, getAdditionalKeys(additionalData));
1562
+ return dataProxy.getDataProxy();
1563
+ },
1564
+ getWorkflowStaticData(type) {
1565
+ return workflow.getStaticData(type, node);
1566
+ },
1567
+ prepareOutputData: workflow_1.NodeHelpers.prepareOutputData,
1568
+ putExecutionToWait(waitTill) {
1569
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1570
+ runExecutionData.waitTill = waitTill;
1571
+ });
1572
+ },
1573
+ sendMessageToUI(...args) {
1574
+ if (mode !== 'manual') {
1575
+ return;
1576
+ }
1577
+ try {
1578
+ if (additionalData.sendMessageToUI) {
1579
+ additionalData.sendMessageToUI(node.name, args);
1580
+ }
1581
+ }
1582
+ catch (error) {
1583
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
1584
+ workflow_1.LoggerProxy.warn(`There was a problem sending messsage to UI: ${error.message}`);
1585
+ }
1586
+ },
1587
+ sendResponse(response) {
1588
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1589
+ var _a;
1590
+ yield ((_a = additionalData.hooks) === null || _a === void 0 ? void 0 : _a.executeHookFunctions('sendResponse', [response]));
1591
+ });
1592
+ },
1593
+ helpers: {
1594
+ httpRequest,
1595
+ requestWithAuthentication(credentialsType, requestOptions, additionalCredentialOptions) {
1596
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1597
+ return requestWithAuthentication.call(this, credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions);
1598
+ });
1599
+ },
1600
+ assertBinaryData(itemIndex, propertyName, inputIndex = 0) {
1601
+ const binaryKeyData = inputData['main'][inputIndex][itemIndex].binary;
1602
+ if (binaryKeyData === undefined) {
1603
+ throw new workflow_1.NodeOperationError(node, `This operation expects the node's input data to contain a binary file '${propertyName}', but none was found [item ${itemIndex}]`, {
1604
+ itemIndex,
1605
+ description: 'Make sure that the previous node outputs a binary file',
1606
+ });
1607
+ }
1608
+ const binaryPropertyData = binaryKeyData[propertyName];
1609
+ if (binaryPropertyData === undefined) {
1610
+ throw new workflow_1.NodeOperationError(node, `The item has no binary field '${propertyName}' [item ${itemIndex}]`, {
1611
+ itemIndex,
1612
+ description: 'Check that the parameter where you specified the input binary field name is correct, and that it matches a field in the binary input',
1613
+ });
1614
+ }
1615
+ return binaryPropertyData;
1616
+ },
1617
+ prepareBinaryData(binaryData, filePath, mimeType) {
1618
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1619
+ return prepareBinaryData.call(this, binaryData, additionalData.executionId, filePath, mimeType);
1620
+ });
1621
+ },
1622
+ getBinaryDataBuffer(itemIndex_1, propertyName_1) {
1623
+ return tslib_1.__awaiter(this, arguments, void 0, function* (itemIndex, propertyName, inputIndex = 0) {
1624
+ return getBinaryDataBuffer.call(this, inputData, itemIndex, propertyName, inputIndex);
1625
+ });
1626
+ },
1627
+ request: proxyRequestToAxios,
1628
+ requestOAuth2(credentialsType, requestOptions, oAuth2Options) {
1629
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1630
+ return requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, oAuth2Options);
1631
+ });
1632
+ },
1633
+ requestOAuth1(credentialsType, requestOptions) {
1634
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1635
+ return requestOAuth1.call(this, credentialsType, requestOptions);
1636
+ });
1637
+ },
1638
+ httpRequestWithAuthentication(credentialsType, requestOptions, additionalCredentialOptions) {
1639
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1640
+ return httpRequestWithAuthentication.call(this, credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions);
1641
+ });
1642
+ },
1643
+ returnJsonArray,
1644
+ normalizeItems,
1645
+ },
1646
+ getInstanceId: () => {
1647
+ // Return the node's instance ID if available, otherwise return an empty string
1648
+ return node.id || '';
1649
+ },
1650
+ getInputConnectionData(connectionType, itemIndex) {
1651
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1652
+ return yield getInputConnectionData.call(this, workflow, runExecutionData, runIndex, connectionInputData, inputData, additionalData, connectionType, mode, itemIndex, nodeTypeData, closeFunctions);
1653
+ });
1654
+ },
1655
+ addInputData(data, node) {
1656
+ const nodeName = node.name;
1657
+ let currentNodeRunIndex = 0;
1658
+ runExecutionData = {
1659
+ startData: {
1660
+ destinationNode: nodeName,
1661
+ },
1662
+ resultData: {
1663
+ runData: {
1664
+ [nodeName]: [JSON.parse(JSON.stringify(data))]
1665
+ },
1666
+ lastNodeExecuted: nodeName,
1667
+ },
1668
+ };
1669
+ return { index: currentNodeRunIndex, inputExecutionData: runExecutionData };
1670
+ },
1671
+ addOutputData(data, node) {
1672
+ const nodeName = node.name;
1673
+ const outputExecutionData = {
1674
+ startData: {
1675
+ destinationNode: nodeName,
1676
+ },
1677
+ resultData: {
1678
+ error: typeof data === 'object' && 'error' in data ? data.error : undefined,
1679
+ runData: {
1680
+ [nodeName]: [JSON.parse(JSON.stringify(data))]
1681
+ },
1682
+ lastNodeExecuted: nodeName,
1683
+ },
1684
+ };
1685
+ return { outputExecutionData };
1686
+ },
1687
+ getExecutionCancelSignal: () => {
1688
+ return undefined;
1689
+ },
1690
+ };
1691
+ })(workflow, runExecutionData, connectionInputData, inputData, node, nodeTypeData, closeFunctions);
1692
+ }
1693
+ /**
1694
+ * Returns the execute functions regular nodes have access to when single-function is defined.
1695
+ *
1696
+ * @export
1697
+ * @param {Workflow} workflow
1698
+ * @param {IRunExecutionData} runExecutionData
1699
+ * @param {number} runIndex
1700
+ * @param {INodeExecutionData[]} connectionInputData
1701
+ * @param {ITaskDataConnections} inputData
1702
+ * @param {INode} node
1703
+ * @param {number} itemIndex
1704
+ * @param {IWorkflowExecuteAdditionalData} additionalData
1705
+ * @param {WorkflowExecuteMode} mode
1706
+ * @returns {IExecuteSingleFunctions}
1707
+ */
1708
+ function getExecuteSingleFunctions(workflow, runExecutionData, runIndex, connectionInputData, inputData, node, itemIndex, additionalData, mode) {
1709
+ return ((workflow, runExecutionData, connectionInputData, inputData, node, itemIndex) => {
1710
+ return {
1711
+ continueOnFail: () => {
1712
+ return continueOnFail(node);
1713
+ },
1714
+ evaluateExpression: (expression, evaluateItemIndex) => {
1715
+ evaluateItemIndex = evaluateItemIndex === undefined ? itemIndex : evaluateItemIndex;
1716
+ return workflow.expression.resolveSimpleParameterValue(`=${expression}`, {}, runExecutionData, runIndex, evaluateItemIndex, node.name, connectionInputData, mode, getAdditionalKeys(additionalData));
1717
+ },
1718
+ getContext(type) {
1719
+ return workflow_1.NodeHelpers.getContext(runExecutionData, type, node);
1720
+ },
1721
+ getCredentials(type) {
1722
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1723
+ return getCredentials(workflow, node, type, additionalData, mode, runExecutionData, runIndex, connectionInputData, itemIndex);
1724
+ });
1725
+ },
1726
+ getInputData: (inputIndex = 0, inputName = 'main') => {
1727
+ if (!Object.prototype.hasOwnProperty.call(inputData, inputName)) {
1728
+ // Return empty array because else it would throw error when nothing is connected to input
1729
+ return { json: {} };
1730
+ }
1731
+ // TODO: Check if nodeType has input with that index defined
1732
+ if (inputData[inputName].length < inputIndex) {
1733
+ throw new Error(`Could not get input index "${inputIndex}" of input "${inputName}"!`);
1734
+ }
1735
+ const allItems = inputData[inputName][inputIndex];
1736
+ if (allItems === null) {
1737
+ // return [];
1738
+ throw new Error(`Value "${inputIndex}" of input "${inputName}" did not get set!`);
1739
+ }
1740
+ if (allItems[itemIndex] === null) {
1741
+ // return [];
1742
+ throw new Error(`Value "${inputIndex}" of input "${inputName}" with itemIndex "${itemIndex}" did not get set!`);
1743
+ }
1744
+ return allItems[itemIndex];
1745
+ },
1746
+ getMode: () => {
1747
+ return mode;
1748
+ },
1749
+ getNode: () => {
1750
+ return getNode(node);
1751
+ },
1752
+ getRestApiUrl: () => {
1753
+ return additionalData.restApiUrl;
1754
+ },
1755
+ getTimezone: () => {
1756
+ return getTimezone(workflow, additionalData);
1757
+ },
1758
+ getNodeParameter: (parameterName, fallbackValue) => {
1759
+ return getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, mode, getAdditionalKeys(additionalData), fallbackValue);
1760
+ },
1761
+ getWorkflow: () => {
1762
+ return getWorkflowMetadata(workflow);
1763
+ },
1764
+ getWorkflowDataProxy: () => {
1765
+ const dataProxy = new workflow_1.WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, node.name, connectionInputData, {}, mode, getAdditionalKeys(additionalData));
1766
+ return dataProxy.getDataProxy();
1767
+ },
1768
+ getWorkflowStaticData(type) {
1769
+ return workflow.getStaticData(type, node);
1770
+ },
1771
+ helpers: {
1772
+ httpRequest,
1773
+ requestWithAuthentication(credentialsType, requestOptions, additionalCredentialOptions) {
1774
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1775
+ return requestWithAuthentication.call(this, credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions);
1776
+ });
1777
+ },
1778
+ prepareBinaryData(binaryData, filePath, mimeType) {
1779
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1780
+ return prepareBinaryData.call(this, binaryData, additionalData.executionId, filePath, mimeType);
1781
+ });
1782
+ },
1783
+ request: proxyRequestToAxios,
1784
+ requestOAuth2(credentialsType, requestOptions, oAuth2Options) {
1785
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1786
+ return requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, oAuth2Options);
1787
+ });
1788
+ },
1789
+ requestOAuth1(credentialsType, requestOptions) {
1790
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1791
+ return requestOAuth1.call(this, credentialsType, requestOptions);
1792
+ });
1793
+ },
1794
+ httpRequestWithAuthentication(credentialsType, requestOptions, additionalCredentialOptions) {
1795
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1796
+ return httpRequestWithAuthentication.call(this, credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions);
1797
+ });
1798
+ },
1799
+ },
1800
+ getInstanceId: () => {
1801
+ // Return the node's instance ID if available, otherwise return an empty string
1802
+ return node.id || '';
1803
+ },
1804
+ };
1805
+ })(workflow, runExecutionData, connectionInputData, inputData, node, itemIndex);
1806
+ }
1807
+ function getCredentialTestFunctions() {
1808
+ return {
1809
+ helpers: {
1810
+ request: proxyRequestToAxios,
1811
+ },
1812
+ };
1813
+ }
1814
+ /**
1815
+ * Returns the execute functions regular nodes have access to in load-options-function.
1816
+ *
1817
+ * @export
1818
+ * @param {Workflow} workflow
1819
+ * @param {INode} node
1820
+ * @param {IWorkflowExecuteAdditionalData} additionalData
1821
+ * @returns {ILoadOptionsFunctions}
1822
+ */
1823
+ function getLoadOptionsFunctions(workflow, node, path, additionalData) {
1824
+ return ((workflow, node, path) => {
1825
+ const that = {
1826
+ getCredentials(type) {
1827
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1828
+ return getCredentials(workflow, node, type, additionalData, 'internal');
1829
+ });
1830
+ },
1831
+ getCurrentNodeParameter: (parameterPath) => {
1832
+ const nodeParameters = additionalData.currentNodeParameters;
1833
+ if (parameterPath.charAt(0) === '&') {
1834
+ parameterPath = `${path.split('.').slice(1, -1).join('.')}.${parameterPath.slice(1)}`;
1835
+ }
1836
+ return (0, lodash_1.get)(nodeParameters, parameterPath);
1837
+ },
1838
+ getCurrentNodeParameters: () => {
1839
+ return additionalData.currentNodeParameters;
1840
+ },
1841
+ getNode: () => {
1842
+ return getNode(node);
1843
+ },
1844
+ getNodeParameter: (parameterName, fallbackValue) => {
1845
+ const runExecutionData = null;
1846
+ const itemIndex = 0;
1847
+ const runIndex = 0;
1848
+ const connectionInputData = [];
1849
+ return getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, 'internal', getAdditionalKeys(additionalData), fallbackValue);
1850
+ },
1851
+ getTimezone: () => {
1852
+ return getTimezone(workflow, additionalData);
1853
+ },
1854
+ getRestApiUrl: () => {
1855
+ return additionalData.restApiUrl;
1856
+ },
1857
+ helpers: {
1858
+ httpRequest,
1859
+ requestWithAuthentication(credentialsType, requestOptions, additionalCredentialOptions) {
1860
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1861
+ return requestWithAuthentication.call(this, credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions);
1862
+ });
1863
+ },
1864
+ request: proxyRequestToAxios,
1865
+ requestOAuth2(credentialsType, requestOptions, oAuth2Options) {
1866
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1867
+ return requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, oAuth2Options);
1868
+ });
1869
+ },
1870
+ requestOAuth1(credentialsType, requestOptions) {
1871
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1872
+ return requestOAuth1.call(this, credentialsType, requestOptions);
1873
+ });
1874
+ },
1875
+ httpRequestWithAuthentication(credentialsType, requestOptions, additionalCredentialOptions) {
1876
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1877
+ return httpRequestWithAuthentication.call(this, credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions);
1878
+ });
1879
+ },
1880
+ },
1881
+ getInstanceId: () => {
1882
+ // Return the node's instance ID if available, otherwise return an empty string
1883
+ return node.id || '';
1884
+ },
1885
+ };
1886
+ return that;
1887
+ })(workflow, node, path);
1888
+ }
1889
+ /**
1890
+ * Returns the execute functions regular nodes have access to in hook-function.
1891
+ *
1892
+ * @export
1893
+ * @param {Workflow} workflow
1894
+ * @param {INode} node
1895
+ * @param {IWorkflowExecuteAdditionalData} additionalData
1896
+ * @param {WorkflowExecuteMode} mode
1897
+ * @returns {IHookFunctions}
1898
+ */
1899
+ function getExecuteHookFunctions(workflow, node, additionalData, mode, activation, isTest, webhookData) {
1900
+ return ((workflow, node) => {
1901
+ const that = {
1902
+ getCredentials(type) {
1903
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1904
+ return getCredentials(workflow, node, type, additionalData, mode);
1905
+ });
1906
+ },
1907
+ getMode: () => {
1908
+ return mode;
1909
+ },
1910
+ getActivationMode: () => {
1911
+ return activation;
1912
+ },
1913
+ getNode: () => {
1914
+ return getNode(node);
1915
+ },
1916
+ getNodeParameter: (parameterName, fallbackValue) => {
1917
+ const runExecutionData = null;
1918
+ const itemIndex = 0;
1919
+ const runIndex = 0;
1920
+ const connectionInputData = [];
1921
+ return getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, mode, getAdditionalKeys(additionalData), fallbackValue);
1922
+ },
1923
+ getNodeWebhookUrl: (name) => {
1924
+ return getNodeWebhookUrl(name, workflow, node, additionalData, mode, getAdditionalKeys(additionalData), isTest);
1925
+ },
1926
+ getTimezone: () => {
1927
+ return getTimezone(workflow, additionalData);
1928
+ },
1929
+ getWebhookName() {
1930
+ if (webhookData === undefined) {
1931
+ throw new Error('Is only supported in webhook functions!');
1932
+ }
1933
+ return webhookData.webhookDescription.name;
1934
+ },
1935
+ getWebhookDescription(name) {
1936
+ return getWebhookDescription(name, workflow, node);
1937
+ },
1938
+ getWorkflow: () => {
1939
+ return getWorkflowMetadata(workflow);
1940
+ },
1941
+ getWorkflowStaticData(type) {
1942
+ return workflow.getStaticData(type, node);
1943
+ },
1944
+ helpers: {
1945
+ httpRequest,
1946
+ requestWithAuthentication(credentialsType, requestOptions, additionalCredentialOptions) {
1947
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1948
+ return requestWithAuthentication.call(this, credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions);
1949
+ });
1950
+ },
1951
+ request: proxyRequestToAxios,
1952
+ requestOAuth2(credentialsType, requestOptions, oAuth2Options) {
1953
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1954
+ return requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, oAuth2Options);
1955
+ });
1956
+ },
1957
+ requestOAuth1(credentialsType, requestOptions) {
1958
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1959
+ return requestOAuth1.call(this, credentialsType, requestOptions);
1960
+ });
1961
+ },
1962
+ httpRequestWithAuthentication(credentialsType, requestOptions, additionalCredentialOptions) {
1963
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1964
+ return httpRequestWithAuthentication.call(this, credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions);
1965
+ });
1966
+ },
1967
+ },
1968
+ getInstanceId: () => {
1969
+ // Return the node's instance ID if available, otherwise return an empty string
1970
+ return node.id || '';
1971
+ },
1972
+ };
1973
+ return that;
1974
+ })(workflow, node);
1975
+ }
1976
+ /**
1977
+ * Returns the execute functions regular nodes have access to when webhook-function is defined.
1978
+ *
1979
+ * @export
1980
+ * @param {Workflow} workflow
1981
+ * @param {IRunExecutionData} runExecutionData
1982
+ * @param {INode} node
1983
+ * @param {IWorkflowExecuteAdditionalData} additionalData
1984
+ * @param {WorkflowExecuteMode} mode
1985
+ * @returns {IWebhookFunctions}
1986
+ */
1987
+ function getExecuteWebhookFunctions(workflow, node, additionalData, mode, webhookData, runExecutionData) {
1988
+ return ((workflow, node) => {
1989
+ return {
1990
+ logger: workflow_1.LoggerProxy,
1991
+ evaluateExpression: (expression, itemIndex) => {
1992
+ //TODO: Implement this EVALUATE EXPRESSION in get webhook execute function
1993
+ return {};
1994
+ },
1995
+ getChildNodes: (nodeName, options) => {
1996
+ return [];
1997
+ },
1998
+ getParentNodes: (nodeName) => {
1999
+ return [];
2000
+ },
2001
+ getBodyData() {
2002
+ if (additionalData.httpRequest === undefined) {
2003
+ throw new Error('Request is missing!');
2004
+ }
2005
+ return additionalData.httpRequest.body;
2006
+ },
2007
+ getCredentials(type) {
2008
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
2009
+ return getCredentials(workflow, node, type, additionalData, mode);
2010
+ });
2011
+ },
2012
+ nodeHelpers: {
2013
+ copyBinaryFile: (filePath, fileName, mimeType) => tslib_1.__awaiter(this, void 0, void 0, function* () {
2014
+ // Use fs.promises.readFile instead of fsReadFileAsync
2015
+ const buffer = yield fs_1.promises.readFile(filePath);
2016
+ return prepareBinaryData(buffer, workflow.id || '', filePath, mimeType);
2017
+ }),
2018
+ },
2019
+ getHeaderData() {
2020
+ if (additionalData.httpRequest === undefined) {
2021
+ throw new Error('Request is missing!');
2022
+ }
2023
+ return additionalData.httpRequest.headers;
2024
+ },
2025
+ getMode: () => {
2026
+ return mode;
2027
+ },
2028
+ getNode: () => {
2029
+ return getNode(node);
2030
+ },
2031
+ getNodeParameter: (parameterName, fallbackValue, options) => {
2032
+ var _a;
2033
+ const itemIndex = 0;
2034
+ const runIndex = 0;
2035
+ let connectionInputData = [];
2036
+ let executionData;
2037
+ if ((runExecutionData === null || runExecutionData === void 0 ? void 0 : runExecutionData.executionData) !== undefined) {
2038
+ executionData = runExecutionData.executionData.nodeExecutionStack[0];
2039
+ if (executionData !== undefined) {
2040
+ connectionInputData = ((_a = executionData.data['main']) === null || _a === void 0 ? void 0 : _a[0]) || [];
2041
+ }
2042
+ }
2043
+ return getNodeParameter(workflow, runExecutionData || null, runIndex, connectionInputData, node, parameterName, itemIndex, mode, getAdditionalKeys(additionalData), fallbackValue);
2044
+ },
2045
+ getParamsData() {
2046
+ if (additionalData.httpRequest === undefined) {
2047
+ throw new Error('Request is missing!');
2048
+ }
2049
+ return additionalData.httpRequest.params;
2050
+ },
2051
+ getQueryData() {
2052
+ if (additionalData.httpRequest === undefined) {
2053
+ throw new Error('Request is missing!');
2054
+ }
2055
+ return additionalData.httpRequest.query;
2056
+ },
2057
+ getRequestObject() {
2058
+ if (additionalData.httpRequest === undefined) {
2059
+ throw new Error('Request is missing!');
2060
+ }
2061
+ return additionalData.httpRequest;
2062
+ },
2063
+ getResponseObject() {
2064
+ if (additionalData.httpResponse === undefined) {
2065
+ throw new Error('Response is missing!');
2066
+ }
2067
+ return additionalData.httpResponse;
2068
+ },
2069
+ getNodeWebhookUrl: (name) => {
2070
+ return getNodeWebhookUrl(name, workflow, node, additionalData, mode, getAdditionalKeys(additionalData));
2071
+ },
2072
+ getTimezone: () => {
2073
+ return getTimezone(workflow, additionalData);
2074
+ },
2075
+ getWorkflow: () => {
2076
+ return getWorkflowMetadata(workflow);
2077
+ },
2078
+ getWorkflowStaticData(type) {
2079
+ return workflow.getStaticData(type, node);
2080
+ },
2081
+ getWebhookName() {
2082
+ return webhookData.webhookDescription.name;
2083
+ },
2084
+ addInputData(data, node) {
2085
+ const nodeName = node.name;
2086
+ let currentNodeRunIndex = 0;
2087
+ runExecutionData = {
2088
+ startData: {
2089
+ destinationNode: nodeName,
2090
+ },
2091
+ resultData: {
2092
+ error: undefined,
2093
+ runData: {
2094
+ [nodeName]: [JSON.parse(JSON.stringify(data))]
2095
+ },
2096
+ lastNodeExecuted: nodeName,
2097
+ },
2098
+ executionData: {
2099
+ contextData: {},
2100
+ nodeExecutionStack: [],
2101
+ waitingExecution: {},
2102
+ },
2103
+ waitTill: undefined,
2104
+ };
2105
+ return { index: currentNodeRunIndex, inputExecutionData: runExecutionData };
2106
+ },
2107
+ addOutputData(data, node) {
2108
+ const nodeName = node.name;
2109
+ const outputExecutionData = {
2110
+ startData: {
2111
+ destinationNode: nodeName,
2112
+ },
2113
+ resultData: {
2114
+ error: undefined,
2115
+ runData: {
2116
+ [nodeName]: [JSON.parse(JSON.stringify(data))]
2117
+ },
2118
+ lastNodeExecuted: nodeName,
2119
+ },
2120
+ executionData: {
2121
+ contextData: {},
2122
+ nodeExecutionStack: [],
2123
+ waitingExecution: {},
2124
+ },
2125
+ waitTill: undefined,
2126
+ };
2127
+ return { outputExecutionData };
2128
+ },
2129
+ logAiEvent: (event, data) => {
2130
+ // Simple implementation for logAiEvent in webhook functions
2131
+ return;
2132
+ },
2133
+ prepareOutputData: workflow_1.NodeHelpers.prepareOutputData,
2134
+ helpers: {
2135
+ httpRequest,
2136
+ requestWithAuthentication(credentialsType, requestOptions, additionalCredentialOptions) {
2137
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
2138
+ return requestWithAuthentication.call(this, credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions);
2139
+ });
2140
+ },
2141
+ prepareBinaryData(binaryData, filePath, mimeType) {
2142
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
2143
+ return prepareBinaryData.call(this, binaryData, additionalData.executionId, filePath, mimeType);
2144
+ });
2145
+ },
2146
+ request: proxyRequestToAxios,
2147
+ requestOAuth2(credentialsType, requestOptions, oAuth2Options) {
2148
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
2149
+ return requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, oAuth2Options);
2150
+ });
2151
+ },
2152
+ requestOAuth1(credentialsType, requestOptions) {
2153
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
2154
+ return requestOAuth1.call(this, credentialsType, requestOptions);
2155
+ });
2156
+ },
2157
+ httpRequestWithAuthentication(credentialsType, requestOptions, additionalCredentialOptions) {
2158
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
2159
+ return httpRequestWithAuthentication.call(this, credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions);
2160
+ });
2161
+ },
2162
+ returnJsonArray,
2163
+ },
2164
+ getInstanceId: () => {
2165
+ // Return the node's instance ID if available, otherwise return an empty string
2166
+ return node.id || '';
2167
+ },
2168
+ };
2169
+ })(workflow, node);
2170
+ }
2171
+ function getSupplyDataFunctions(workflow, runExecutionData, runIndex, connectionInputData, inputData, node, additionalData, mode, nodeTypeData, closeFunctions) {
2172
+ return ((workflow, runExecutionData, connectionInputData, inputData, node, nodeTypeData, closeFunctions) => {
2173
+ return {
2174
+ logger: workflow_1.LoggerProxy,
2175
+ continueOnFail: () => {
2176
+ return continueOnFail(node);
2177
+ },
2178
+ evaluateExpression: (expression, itemIndex) => {
2179
+ return workflow.expression.resolveSimpleParameterValue(`=${expression}`, {}, runExecutionData, runIndex, itemIndex, node.name, connectionInputData, mode, getAdditionalKeys(additionalData));
2180
+ },
2181
+ executeWorkflow(workflowInfo, inputData) {
2182
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
2183
+ return additionalData
2184
+ .executeWorkflow(workflowInfo, additionalData, inputData)
2185
+ .then((result) => tslib_1.__awaiter(this, void 0, void 0, function* () {
2186
+ return BinaryDataManager_1.BinaryDataManager.getInstance().duplicateBinaryData(result, additionalData.executionId);
2187
+ }));
2188
+ });
2189
+ },
2190
+ getContext(type) {
2191
+ return workflow_1.NodeHelpers.getContext(runExecutionData, type, node);
2192
+ },
2193
+ getCredentials(type, itemIndex) {
2194
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
2195
+ return getCredentials(workflow, node, type, additionalData, mode, runExecutionData, runIndex, connectionInputData, itemIndex);
2196
+ });
2197
+ },
2198
+ getExecutionId: () => {
2199
+ return additionalData.executionId;
2200
+ },
2201
+ getInputData: (inputIndex = 0, inputName = 'main') => {
2202
+ if (!Object.prototype.hasOwnProperty.call(inputData, inputName)) {
2203
+ // Return empty array because else it would throw error when nothing is connected to input
2204
+ return [];
2205
+ }
2206
+ // TODO: Check if nodeType has input with that index defined
2207
+ if (inputData[inputName].length < inputIndex) {
2208
+ throw new Error(`Could not get input index "${inputIndex}" of input "${inputName}"!`);
2209
+ }
2210
+ if (inputData[inputName][inputIndex] === null) {
2211
+ // return [];
2212
+ throw new Error(`Value "${inputIndex}" of input "${inputName}" did not get set!`);
2213
+ }
2214
+ return inputData[inputName][inputIndex];
2215
+ },
2216
+ getNodeParameter: (parameterName, itemIndex, fallbackValue) => {
2217
+ return getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, mode, getAdditionalKeys(additionalData), fallbackValue);
2218
+ },
2219
+ getMode: () => {
2220
+ return mode;
2221
+ },
2222
+ getNode: () => {
2223
+ return getNode(node);
2224
+ },
2225
+ getRestApiUrl: () => {
2226
+ return additionalData.restApiUrl;
2227
+ },
2228
+ getTimezone: () => {
2229
+ return getTimezone(workflow, additionalData);
2230
+ },
2231
+ getWorkflow: () => {
2232
+ return getWorkflowMetadata(workflow);
2233
+ },
2234
+ getWorkflowDataProxy: (itemIndex) => {
2235
+ const dataProxy = new workflow_1.WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, node.name, connectionInputData, {}, mode, getAdditionalKeys(additionalData));
2236
+ return dataProxy.getDataProxy();
2237
+ },
2238
+ getWorkflowStaticData(type) {
2239
+ return workflow.getStaticData(type, node);
2240
+ },
2241
+ prepareOutputData: workflow_1.NodeHelpers.prepareOutputData,
2242
+ putExecutionToWait(waitTill) {
2243
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
2244
+ runExecutionData.waitTill = waitTill;
2245
+ });
2246
+ },
2247
+ sendMessageToUI(...args) {
2248
+ if (mode !== 'manual') {
2249
+ return;
2250
+ }
2251
+ try {
2252
+ if (additionalData.sendMessageToUI) {
2253
+ additionalData.sendMessageToUI(node.name, args);
2254
+ }
2255
+ }
2256
+ catch (error) {
2257
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
2258
+ workflow_1.LoggerProxy.warn(`There was a problem sending messsage to UI: ${error.message}`);
2259
+ }
2260
+ },
2261
+ sendResponse(response) {
2262
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
2263
+ var _a;
2264
+ yield ((_a = additionalData.hooks) === null || _a === void 0 ? void 0 : _a.executeHookFunctions('sendResponse', [response]));
2265
+ });
2266
+ },
2267
+ helpers: {
2268
+ httpRequest,
2269
+ requestWithAuthentication(credentialsType, requestOptions, additionalCredentialOptions) {
2270
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
2271
+ return requestWithAuthentication.call(this, credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions);
2272
+ });
2273
+ },
2274
+ assertBinaryData(itemIndex, propertyName, inputIndex = 0) {
2275
+ const binaryKeyData = inputData['main'][inputIndex][itemIndex].binary;
2276
+ if (binaryKeyData === undefined) {
2277
+ throw new workflow_1.NodeOperationError(node, `This operation expects the node's input data to contain a binary file '${propertyName}', but none was found [item ${itemIndex}]`, {
2278
+ itemIndex,
2279
+ description: 'Make sure that the previous node outputs a binary file',
2280
+ });
2281
+ }
2282
+ const binaryPropertyData = binaryKeyData[propertyName];
2283
+ if (binaryPropertyData === undefined) {
2284
+ throw new workflow_1.NodeOperationError(node, `The item has no binary field '${propertyName}' [item ${itemIndex}]`, {
2285
+ itemIndex,
2286
+ description: 'Check that the parameter where you specified the input binary field name is correct, and that it matches a field in the binary input',
2287
+ });
2288
+ }
2289
+ return binaryPropertyData;
2290
+ },
2291
+ prepareBinaryData(binaryData, filePath, mimeType) {
2292
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
2293
+ return prepareBinaryData.call(this, binaryData, additionalData.executionId, filePath, mimeType);
2294
+ });
2295
+ },
2296
+ getBinaryDataBuffer(itemIndex_1, propertyName_1) {
2297
+ return tslib_1.__awaiter(this, arguments, void 0, function* (itemIndex, propertyName, inputIndex = 0) {
2298
+ return getBinaryDataBuffer.call(this, inputData, itemIndex, propertyName, inputIndex);
2299
+ });
2300
+ },
2301
+ request: proxyRequestToAxios,
2302
+ requestOAuth2(credentialsType, requestOptions, oAuth2Options) {
2303
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
2304
+ return requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, oAuth2Options);
2305
+ });
2306
+ },
2307
+ requestOAuth1(credentialsType, requestOptions) {
2308
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
2309
+ return requestOAuth1.call(this, credentialsType, requestOptions);
2310
+ });
2311
+ },
2312
+ httpRequestWithAuthentication(credentialsType, requestOptions, additionalCredentialOptions) {
2313
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
2314
+ return httpRequestWithAuthentication.call(this, credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions);
2315
+ });
2316
+ },
2317
+ returnJsonArray,
2318
+ normalizeItems,
2319
+ },
2320
+ getInstanceId: () => {
2321
+ // Return the node's instance ID if available, otherwise return an empty string
2322
+ return node.id || '';
2323
+ },
2324
+ addInputData(data, node) {
2325
+ const nodeName = node.name;
2326
+ let currentNodeRunIndex = 0;
2327
+ runExecutionData = {
2328
+ startData: {
2329
+ destinationNode: nodeName,
2330
+ },
2331
+ resultData: {
2332
+ error: undefined,
2333
+ runData: {
2334
+ [nodeName]: [JSON.parse(JSON.stringify(data))]
2335
+ },
2336
+ lastNodeExecuted: nodeName,
2337
+ },
2338
+ executionData: {
2339
+ contextData: {},
2340
+ nodeExecutionStack: [],
2341
+ waitingExecution: {},
2342
+ },
2343
+ waitTill: undefined,
2344
+ };
2345
+ return { index: currentNodeRunIndex, inputExecutionData: runExecutionData };
2346
+ },
2347
+ addOutputData(data, node) {
2348
+ const nodeName = node.name;
2349
+ const outputExecutionData = {
2350
+ startData: {
2351
+ destinationNode: nodeName,
2352
+ },
2353
+ resultData: {
2354
+ error: undefined,
2355
+ runData: {
2356
+ [nodeName]: [JSON.parse(JSON.stringify(data))]
2357
+ },
2358
+ lastNodeExecuted: nodeName,
2359
+ },
2360
+ executionData: {
2361
+ contextData: {},
2362
+ nodeExecutionStack: [],
2363
+ waitingExecution: {},
2364
+ },
2365
+ waitTill: undefined,
2366
+ };
2367
+ return { outputExecutionData };
2368
+ },
2369
+ getInputConnectionData(connectionType, itemIndex) {
2370
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
2371
+ return yield getInputConnectionData.call(this, workflow, runExecutionData, runIndex, connectionInputData, inputData, additionalData, connectionType, mode, itemIndex, nodeTypeData, closeFunctions);
2372
+ });
2373
+ },
2374
+ };
2375
+ })(workflow, runExecutionData, connectionInputData, inputData, node, nodeTypeData, closeFunctions);
2376
+ }
2377
+ function getInputConnectionData(workflow, runExecutionData, runIndex, connectionInputData, inputData, additionalData, connectionType, mode, itemIndex, nodeTypeData, closeFunctions) {
2378
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
2379
+ var _a, _b, _c, _d, _e, _f, _g;
2380
+ const parentNode = this.getNode();
2381
+ const startTime = Date.now();
2382
+ const nodeInputs = getNodeInputs(workflow, parentNode, nodeTypeData.description).map((input) => (typeof input === 'string' ? { type: input } : input));
2383
+ const inputConfiguration = nodeInputs.find((input) => input.type === connectionType);
2384
+ if (inputConfiguration === undefined) {
2385
+ throw new workflow_1.NodeOperationError(parentNode, `Node does not have input of type`, {
2386
+ description: `Node ${parentNode.name} does not have input of type ${connectionType}`,
2387
+ });
2388
+ }
2389
+ const connectedNodes = getConnectedNodes(workflow, parentNode, connectionType);
2390
+ if (connectedNodes.length === 0) {
2391
+ if (inputConfiguration.required) {
2392
+ throw new workflow_1.NodeOperationError(parentNode, `A ${(_a = inputConfiguration === null || inputConfiguration === void 0 ? void 0 : inputConfiguration.displayName) !== null && _a !== void 0 ? _a : connectionType} sub-node must be connected and enabled`);
2393
+ }
2394
+ return inputConfiguration.maxConnections === 1 ? undefined : [];
2395
+ }
2396
+ if (inputConfiguration.maxConnections !== undefined &&
2397
+ connectedNodes.length > inputConfiguration.maxConnections) {
2398
+ throw new workflow_1.NodeOperationError(parentNode, `Only ${inputConfiguration.maxConnections} ${connectionType} sub-nodes are/is allowed to be connected`);
2399
+ }
2400
+ const nodes = [];
2401
+ for (const connectedNode of connectedNodes) {
2402
+ const connectedNodeType = workflow.nodeTypes.getByNameAndVersion(connectedNode.type, connectedNode.typeVersion);
2403
+ if (!connectedNodeType) {
2404
+ continue;
2405
+ }
2406
+ if (connectedNodeType && !connectedNodeType.supplyData) {
2407
+ throw new workflow_1.NodeOperationError(connectedNode, 'Node does not have a `supplyData` method defined', {
2408
+ itemIndex,
2409
+ });
2410
+ }
2411
+ else {
2412
+ try {
2413
+ yield ((_b = additionalData.hooks) === null || _b === void 0 ? void 0 : _b.executeHookFunctions('nodeExecuteBefore', [connectedNode.name, {
2414
+ startTime: startTime,
2415
+ executionTime: new Date().getTime() - startTime
2416
+ }]));
2417
+ const context = getSupplyDataFunctions(workflow, runExecutionData, runIndex, connectionInputData, inputData, connectedNode, additionalData, mode, nodeTypeData, closeFunctions);
2418
+ const supplyData = yield ((_c = connectedNodeType.supplyData) === null || _c === void 0 ? void 0 : _c.call(context, itemIndex));
2419
+ if (supplyData) {
2420
+ nodes.push(supplyData);
2421
+ if (supplyData.closeFunction) {
2422
+ closeFunctions.push(supplyData.closeFunction);
2423
+ }
2424
+ const taskData = {
2425
+ startTime: startTime,
2426
+ executionTime: new Date().getTime() - startTime
2427
+ };
2428
+ if (!Object.prototype.hasOwnProperty.call(runExecutionData.resultData.runData, connectedNode.name)) {
2429
+ runExecutionData.resultData.runData[connectedNode.name] = [];
2430
+ }
2431
+ runExecutionData.resultData.runData[connectedNode.name][runIndex] = taskData;
2432
+ yield ((_d = additionalData.hooks) === null || _d === void 0 ? void 0 : _d.executeHookFunctions('nodeExecuteAfter', [
2433
+ connectedNode.name,
2434
+ taskData,
2435
+ runExecutionData
2436
+ ]));
2437
+ }
2438
+ }
2439
+ catch (error) {
2440
+ const taskData = {
2441
+ startTime: startTime,
2442
+ executionTime: new Date().getTime() - startTime,
2443
+ error: error
2444
+ };
2445
+ runExecutionData.resultData.runData[connectedNode.name][runIndex] = taskData;
2446
+ yield ((_e = additionalData.hooks) === null || _e === void 0 ? void 0 : _e.executeHookFunctions('nodeExecuteAfter', [
2447
+ connectedNode.name,
2448
+ taskData,
2449
+ runExecutionData
2450
+ ]));
2451
+ throw new workflow_1.NodeOperationError(connectedNode, `Error in sub-node ${connectedNode.name}`, {
2452
+ itemIndex,
2453
+ description: (_f = error === null || error === void 0 ? void 0 : error.message) !== null && _f !== void 0 ? _f : 'Unknown error',
2454
+ });
2455
+ }
2456
+ }
2457
+ }
2458
+ return inputConfiguration.maxConnections === 1
2459
+ ? (_g = (nodes || [])[0]) === null || _g === void 0 ? void 0 : _g.response
2460
+ : nodes.map((node) => node.response);
2461
+ });
2462
+ }
2463
+ function getNodeInputs(workflow, node, nodeTypeData) {
2464
+ if (Array.isArray(nodeTypeData === null || nodeTypeData === void 0 ? void 0 : nodeTypeData.inputs)) {
2465
+ return nodeTypeData.inputs;
2466
+ }
2467
+ // Calculate the outputs dynamically
2468
+ try {
2469
+ return (workflow.expression.getSimpleParameterValue(node, nodeTypeData.inputs, 'internal', {}) || []);
2470
+ }
2471
+ catch (e) {
2472
+ console.warn('Could not calculate inputs dynamically for node: ', node.name);
2473
+ return [];
2474
+ }
2475
+ }
2476
+ function getConnectedNodes(workflow, node, connectionType) {
2477
+ return workflow
2478
+ .getParentNodes(node.name, connectionType, 1)
2479
+ .map((nodeName) => workflow.getNode(nodeName))
2480
+ .filter((node) => !!node)
2481
+ .filter((node) => node.disabled !== true);
2482
+ }
2483
+ //# sourceMappingURL=NodeExecuteFunctions.js.map