@fsai-flow/core 0.0.4 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/dist/index.d.ts +17 -0
  2. package/dist/index.js +61 -0
  3. package/dist/{src/lib → lib}/ActiveWebhooks.d.ts +1 -1
  4. package/dist/lib/ActiveWebhooks.js +177 -0
  5. package/dist/{src/lib → lib}/ActiveWorkflows.d.ts +3 -3
  6. package/dist/lib/ActiveWorkflows.js +465 -0
  7. package/dist/{src/lib → lib}/BinaryDataManager/FileSystem.d.ts +1 -1
  8. package/dist/lib/BinaryDataManager/FileSystem.js +180 -0
  9. package/dist/{src/lib → lib}/BinaryDataManager/index.d.ts +2 -2
  10. package/dist/lib/BinaryDataManager/index.js +129 -0
  11. package/dist/{src/lib → lib}/ChangeCase.js +11 -11
  12. package/dist/lib/Constants.js +18 -0
  13. package/dist/{src/lib → lib}/Credentials.d.ts +1 -1
  14. package/dist/{src/lib → lib}/Credentials.js +7 -8
  15. package/dist/{src/lib → lib}/FileSystem.d.ts +1 -1
  16. package/dist/lib/FileSystem.js +180 -0
  17. package/dist/{src/lib → lib}/InputConnectionDataLegacy.d.ts +1 -1
  18. package/dist/lib/InputConnectionDataLegacy.js +72 -0
  19. package/dist/{src/lib → lib}/Interfaces.d.ts +47 -48
  20. package/dist/{src/lib → lib}/Interfaces.js +0 -1
  21. package/dist/{src/lib → lib}/LoadNodeParameterOptions.d.ts +1 -1
  22. package/dist/lib/LoadNodeParameterOptions.js +152 -0
  23. package/dist/{src/lib → lib}/NodeExecuteFunctions.d.ts +9 -10
  24. package/dist/lib/NodeExecuteFunctions.js +2467 -0
  25. package/dist/{src/lib → lib}/NodesLoader/constants.d.ts +1 -1
  26. package/dist/lib/NodesLoader/constants.js +105 -0
  27. package/dist/{src/lib → lib}/NodesLoader/custom-directory-loader.d.ts +1 -1
  28. package/dist/lib/NodesLoader/custom-directory-loader.js +35 -0
  29. package/dist/{src/lib → lib}/NodesLoader/directory-loader.d.ts +1 -1
  30. package/dist/{src/lib → lib}/NodesLoader/directory-loader.js +80 -38
  31. package/dist/lib/NodesLoader/index.d.ts +5 -0
  32. package/dist/{src/lib → lib}/NodesLoader/index.js +5 -6
  33. package/dist/{src/lib → lib}/NodesLoader/lazy-package-directory-loader.d.ts +1 -1
  34. package/dist/lib/NodesLoader/lazy-package-directory-loader.js +44 -0
  35. package/dist/{src/lib → lib}/NodesLoader/load-class-in-isolation.js +6 -11
  36. package/dist/{src/lib → lib}/NodesLoader/package-directory-loader.d.ts +2 -2
  37. package/dist/{src/lib → lib}/NodesLoader/package-directory-loader.js +28 -36
  38. package/dist/{src/lib → lib}/NodesLoader/types.js +0 -1
  39. package/dist/{src/lib → lib}/RedisLeaderElectionManager.d.ts +1 -1
  40. package/dist/lib/RedisLeaderElectionManager.js +279 -0
  41. package/dist/lib/RequestTypes.d.ts +58 -0
  42. package/dist/lib/RequestTypes.js +8 -0
  43. package/dist/{src/lib → lib}/UserSettings.d.ts +1 -1
  44. package/dist/lib/UserSettings.js +269 -0
  45. package/dist/{src/lib → lib}/WorkflowExecute.d.ts +4 -4
  46. package/dist/{src/lib → lib}/WorkflowExecute.js +230 -178
  47. package/dist/{src/lib → lib}/index.d.ts +2 -2
  48. package/dist/lib/index.js +129 -0
  49. package/dist/{src/utils → utils}/crypto.js +2 -3
  50. package/package.json +59 -52
  51. package/dist/README.md +0 -31
  52. package/dist/package.json +0 -54
  53. package/dist/src/index.d.ts +0 -16
  54. package/dist/src/index.js +0 -30
  55. package/dist/src/index.js.map +0 -1
  56. package/dist/src/lib/ActiveWebhooks.js +0 -184
  57. package/dist/src/lib/ActiveWebhooks.js.map +0 -1
  58. package/dist/src/lib/ActiveWorkflows.js +0 -456
  59. package/dist/src/lib/ActiveWorkflows.js.map +0 -1
  60. package/dist/src/lib/BinaryDataManager/FileSystem.js +0 -179
  61. package/dist/src/lib/BinaryDataManager/FileSystem.js.map +0 -1
  62. package/dist/src/lib/BinaryDataManager/index.js +0 -146
  63. package/dist/src/lib/BinaryDataManager/index.js.map +0 -1
  64. package/dist/src/lib/ChangeCase.js.map +0 -1
  65. package/dist/src/lib/Constants.js +0 -19
  66. package/dist/src/lib/Constants.js.map +0 -1
  67. package/dist/src/lib/Credentials.js.map +0 -1
  68. package/dist/src/lib/FileSystem.js +0 -179
  69. package/dist/src/lib/FileSystem.js.map +0 -1
  70. package/dist/src/lib/InputConnectionDataLegacy.js +0 -79
  71. package/dist/src/lib/InputConnectionDataLegacy.js.map +0 -1
  72. package/dist/src/lib/Interfaces.js.map +0 -1
  73. package/dist/src/lib/LoadNodeParameterOptions.js +0 -150
  74. package/dist/src/lib/LoadNodeParameterOptions.js.map +0 -1
  75. package/dist/src/lib/NodeExecuteFunctions.js +0 -2479
  76. package/dist/src/lib/NodeExecuteFunctions.js.map +0 -1
  77. package/dist/src/lib/NodesLoader/constants.js +0 -106
  78. package/dist/src/lib/NodesLoader/constants.js.map +0 -1
  79. package/dist/src/lib/NodesLoader/custom-directory-loader.js +0 -36
  80. package/dist/src/lib/NodesLoader/custom-directory-loader.js.map +0 -1
  81. package/dist/src/lib/NodesLoader/directory-loader.js.map +0 -1
  82. package/dist/src/lib/NodesLoader/index.d.ts +0 -5
  83. package/dist/src/lib/NodesLoader/index.js.map +0 -1
  84. package/dist/src/lib/NodesLoader/lazy-package-directory-loader.js +0 -52
  85. package/dist/src/lib/NodesLoader/lazy-package-directory-loader.js.map +0 -1
  86. package/dist/src/lib/NodesLoader/load-class-in-isolation.js.map +0 -1
  87. package/dist/src/lib/NodesLoader/package-directory-loader.js.map +0 -1
  88. package/dist/src/lib/NodesLoader/types.js.map +0 -1
  89. package/dist/src/lib/RedisLeaderElectionManager.js +0 -294
  90. package/dist/src/lib/RedisLeaderElectionManager.js.map +0 -1
  91. package/dist/src/lib/UserSettings.js +0 -261
  92. package/dist/src/lib/UserSettings.js.map +0 -1
  93. package/dist/src/lib/WorkflowExecute.js.map +0 -1
  94. package/dist/src/lib/index.js +0 -146
  95. package/dist/src/lib/index.js.map +0 -1
  96. package/dist/src/utils/crypto.js.map +0 -1
  97. package/eslint.config.js +0 -19
  98. package/jest.config.ts +0 -10
  99. package/project.json +0 -19
  100. package/src/index.ts +0 -28
  101. package/src/lib/ActiveWebhooks.ts +0 -245
  102. package/src/lib/ActiveWorkflows.ts +0 -575
  103. package/src/lib/BinaryDataManager/FileSystem.ts +0 -214
  104. package/src/lib/BinaryDataManager/index.ts +0 -187
  105. package/src/lib/ChangeCase.ts +0 -45
  106. package/src/lib/Constants.ts +0 -16
  107. package/src/lib/Credentials.ts +0 -108
  108. package/src/lib/FileSystem.ts +0 -214
  109. package/src/lib/InputConnectionDataLegacy.ts +0 -123
  110. package/src/lib/Interfaces.ts +0 -338
  111. package/src/lib/LoadNodeParameterOptions.ts +0 -235
  112. package/src/lib/NodeExecuteFunctions.ts +0 -3700
  113. package/src/lib/NodesLoader/constants.ts +0 -112
  114. package/src/lib/NodesLoader/custom-directory-loader.ts +0 -31
  115. package/src/lib/NodesLoader/directory-loader.ts +0 -458
  116. package/src/lib/NodesLoader/index.ts +0 -5
  117. package/src/lib/NodesLoader/lazy-package-directory-loader.ts +0 -55
  118. package/src/lib/NodesLoader/load-class-in-isolation.ts +0 -19
  119. package/src/lib/NodesLoader/package-directory-loader.ts +0 -107
  120. package/src/lib/NodesLoader/types.ts +0 -14
  121. package/src/lib/RedisLeaderElectionManager.ts +0 -334
  122. package/src/lib/UserSettings.ts +0 -292
  123. package/src/lib/WorkflowExecute.ts +0 -1128
  124. package/src/lib/index.ts +0 -187
  125. package/src/utils/crypto.ts +0 -5
  126. package/tests/Credentials.test.ts +0 -88
  127. package/tests/Helpers.ts +0 -808
  128. package/tests/WorkflowExecute.test.ts +0 -1242
  129. package/tsconfig.json +0 -41
  130. package/tsconfig.lib.json +0 -10
  131. package/tsconfig.spec.json +0 -14
  132. /package/dist/{src/lib → lib}/ChangeCase.d.ts +0 -0
  133. /package/dist/{src/lib → lib}/Constants.d.ts +0 -0
  134. /package/dist/{src/lib → lib}/NodesLoader/load-class-in-isolation.d.ts +0 -0
  135. /package/dist/{src/lib → lib}/NodesLoader/types.d.ts +0 -0
  136. /package/dist/{src/utils → utils}/crypto.d.ts +0 -0
@@ -1,3 +1,2 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=types.js.map
@@ -1,4 +1,4 @@
1
- import { RedisOptions } from 'ioredis';
1
+ import { type RedisOptions } from "ioredis";
2
2
  export interface RedisLeaderElectionCallbacks {
3
3
  onStartedLeading: () => void;
4
4
  onStoppedLeading: () => void;
@@ -0,0 +1,279 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.RedisLeaderElectionManager = void 0;
7
+ const workflow_1 = require("@fsai-flow/workflow");
8
+ const ioredis_1 = __importDefault(require("ioredis"));
9
+ class RedisLeaderElectionManager {
10
+ constructor(lockKey, redisConfig, callbacks) {
11
+ this.isLeader = false;
12
+ this.lockTTL = 30000; // 30 seconds in milliseconds
13
+ this.renewalInterval = 10000; // 10 seconds in milliseconds
14
+ this.lockKey = `leader:${lockKey}`;
15
+ this.nodeId = this.generateNodeId();
16
+ this.callbacks = callbacks;
17
+ // Initialize Redis connection
18
+ if (typeof redisConfig === "string") {
19
+ this.redis = new ioredis_1.default(redisConfig);
20
+ }
21
+ else {
22
+ this.redis = new ioredis_1.default(redisConfig);
23
+ }
24
+ // Handle Redis connection events
25
+ this.redis.on("connect", () => {
26
+ workflow_1.LoggerProxy.info(`Redis connected for leader election: ${this.lockKey}`);
27
+ });
28
+ this.redis.on("ready", () => {
29
+ workflow_1.LoggerProxy.info(`Redis ready for leader election: ${this.lockKey}`);
30
+ });
31
+ this.redis.on("error", (error) => {
32
+ workflow_1.LoggerProxy.error(`Redis connection error for leader election: ${error instanceof Error ? error.message : String(error)}`);
33
+ });
34
+ }
35
+ /**
36
+ * Wait for Redis connection to be ready
37
+ */
38
+ async waitForRedisConnection() {
39
+ return new Promise((resolve, reject) => {
40
+ if (this.redis.status === "ready") {
41
+ workflow_1.LoggerProxy.debug(`Redis already ready for ${this.lockKey}`);
42
+ resolve();
43
+ return;
44
+ }
45
+ let isSettled = false;
46
+ let timeoutId = null;
47
+ // Cleanup function to prevent memory leaks
48
+ const cleanup = () => {
49
+ if (isSettled)
50
+ return; // Already cleaned up
51
+ isSettled = true;
52
+ // Clear timeout safely
53
+ if (timeoutId !== null) {
54
+ clearTimeout(timeoutId);
55
+ timeoutId = null;
56
+ }
57
+ // Remove event listeners safely
58
+ try {
59
+ this.redis.off("ready", onReady);
60
+ this.redis.off("error", onError);
61
+ }
62
+ catch (error) {
63
+ // Ignore cleanup errors - Redis connection might be destroyed
64
+ workflow_1.LoggerProxy.debug(`Cleanup warning for ${this.lockKey}: ${error}`);
65
+ }
66
+ };
67
+ const onReady = () => {
68
+ cleanup();
69
+ workflow_1.LoggerProxy.debug(`Redis connection established for ${this.lockKey}`);
70
+ resolve();
71
+ };
72
+ const onError = (error) => {
73
+ cleanup();
74
+ workflow_1.LoggerProxy.error(`Redis connection failed for ${this.lockKey}: ${error.message}`);
75
+ reject(error);
76
+ };
77
+ const onTimeout = () => {
78
+ cleanup();
79
+ reject(new Error(`Redis connection timeout after 10 seconds for ${this.lockKey}`));
80
+ };
81
+ // Set up timeout
82
+ timeoutId = setTimeout(onTimeout, 10000); // 10 second timeout
83
+ // Set up event listeners
84
+ this.redis.once("ready", onReady);
85
+ this.redis.once("error", onError);
86
+ });
87
+ }
88
+ /**
89
+ * Start the leader election process
90
+ */
91
+ async start() {
92
+ workflow_1.LoggerProxy.info(`🚀 Starting Redis leader election for ${this.nodeId} on key ${this.lockKey}`);
93
+ workflow_1.LoggerProxy.info(`🔧 Leader election config: TTL=${this.lockTTL}ms, RenewalInterval=${this.renewalInterval}ms`);
94
+ // Wait for Redis connection to be ready
95
+ workflow_1.LoggerProxy.info(`⏳ ${this.nodeId} waiting for Redis connection...`);
96
+ await this.waitForRedisConnection();
97
+ workflow_1.LoggerProxy.info(`✅ Redis connection ready for ${this.nodeId}`);
98
+ // Try to acquire leadership immediately
99
+ workflow_1.LoggerProxy.info(`🎯 ${this.nodeId} making initial leadership attempt...`);
100
+ await this.tryAcquireLeadership();
101
+ // Start the renewal/retry loop
102
+ this.startRenewalLoop();
103
+ workflow_1.LoggerProxy.info(`✅ Leader election process started for ${this.nodeId}`);
104
+ }
105
+ /**
106
+ * Stop the leader election process
107
+ */
108
+ async stop() {
109
+ workflow_1.LoggerProxy.info(`🛑 Stopping Redis leader election for ${this.nodeId}`);
110
+ // Stop renewal timer
111
+ if (this.renewalTimer) {
112
+ workflow_1.LoggerProxy.debug(`⏹️ Stopping leadership monitoring loop for ${this.nodeId}`);
113
+ clearInterval(this.renewalTimer);
114
+ this.renewalTimer = undefined;
115
+ }
116
+ // Release leadership if we have it
117
+ if (this.isLeader) {
118
+ workflow_1.LoggerProxy.info(`👋 ${this.nodeId} releasing leadership voluntarily for ${this.lockKey}`);
119
+ await this.releaseLock();
120
+ }
121
+ // Close Redis connection
122
+ workflow_1.LoggerProxy.debug(`🔌 Disconnecting Redis for ${this.nodeId}`);
123
+ this.redis.disconnect();
124
+ workflow_1.LoggerProxy.info(`✅ Leader election stopped for ${this.nodeId}`);
125
+ }
126
+ /**
127
+ * Check if this node is currently the leader
128
+ */
129
+ getIsLeader() {
130
+ return this.isLeader;
131
+ }
132
+ /**
133
+ * Try to acquire leadership
134
+ */
135
+ async tryAcquireLeadership() {
136
+ try {
137
+ // Check if Redis connection is ready before attempting operations
138
+ if (this.redis.status !== "ready") {
139
+ workflow_1.LoggerProxy.warn(`Redis not ready for ${this.nodeId}, current status: ${this.redis.status}`);
140
+ return false;
141
+ }
142
+ workflow_1.LoggerProxy.debug(`Node ${this.nodeId} attempting to acquire leadership for ${this.lockKey}`);
143
+ // Use SET with NX (not exists) and PX (expire in milliseconds)
144
+ const result = await this.redis.set(this.lockKey, this.nodeId, "PX", this.lockTTL, "NX");
145
+ if (result === "OK") {
146
+ // Successfully acquired leadership
147
+ if (!this.isLeader) {
148
+ this.isLeader = true;
149
+ workflow_1.LoggerProxy.info(`🏆 Node ${this.nodeId} ACQUIRED LEADERSHIP for ${this.lockKey} (TTL: ${this.lockTTL}ms)`);
150
+ this.callbacks.onStartedLeading();
151
+ }
152
+ else {
153
+ workflow_1.LoggerProxy.debug(`Node ${this.nodeId} renewed leadership lock for ${this.lockKey}`);
154
+ }
155
+ return true;
156
+ }
157
+ // Failed to acquire leadership - check who is the current leader
158
+ const currentLeader = await this.redis.get(this.lockKey);
159
+ const lockTTL = await this.redis.pttl(this.lockKey);
160
+ if (currentLeader) {
161
+ if (currentLeader !== this.nodeId) {
162
+ workflow_1.LoggerProxy.debug(`👑 Node ${this.nodeId} sees ${currentLeader} is the current leader for ${this.lockKey} (TTL: ${lockTTL}ms)`);
163
+ if (this.callbacks.onNewLeader) {
164
+ this.callbacks.onNewLeader(currentLeader);
165
+ }
166
+ }
167
+ }
168
+ else {
169
+ workflow_1.LoggerProxy.debug(`Node ${this.nodeId} found no current leader for ${this.lockKey}, but failed to acquire lock`);
170
+ }
171
+ // Lost leadership if we previously had it
172
+ if (this.isLeader) {
173
+ this.isLeader = false;
174
+ workflow_1.LoggerProxy.info(`📉 Node ${this.nodeId} LOST LEADERSHIP for ${this.lockKey}`);
175
+ this.callbacks.onStoppedLeading();
176
+ }
177
+ return false;
178
+ }
179
+ catch (error) {
180
+ workflow_1.LoggerProxy.error(`❌ Error during leader election for ${this.nodeId}: ${error instanceof Error ? error.message : String(error)}`);
181
+ // If we had leadership and there's an error, assume we lost it
182
+ if (this.isLeader) {
183
+ this.isLeader = false;
184
+ workflow_1.LoggerProxy.info(`💥 Node ${this.nodeId} LOST LEADERSHIP due to error: ${this.lockKey}`);
185
+ this.callbacks.onStoppedLeading();
186
+ }
187
+ return false;
188
+ }
189
+ }
190
+ /**
191
+ * Renew the leadership lock
192
+ */
193
+ async renewLock() {
194
+ try {
195
+ // Check if Redis connection is ready before attempting operations
196
+ if (this.redis.status !== "ready") {
197
+ workflow_1.LoggerProxy.warn(`Redis not ready for ${this.nodeId} renewal, current status: ${this.redis.status}`);
198
+ return false;
199
+ }
200
+ workflow_1.LoggerProxy.debug(`🔄 Node ${this.nodeId} attempting to renew leadership for ${this.lockKey}`);
201
+ // Use Lua script to atomically check ownership and renew
202
+ const script = `
203
+ if redis.call("get", KEYS[1]) == ARGV[1] then
204
+ return redis.call("pexpire", KEYS[1], ARGV[2])
205
+ else
206
+ return 0
207
+ end
208
+ `;
209
+ const result = await this.redis.eval(script, 1, this.lockKey, this.nodeId, this.lockTTL.toString());
210
+ if (result === 1) {
211
+ workflow_1.LoggerProxy.debug(`✅ Node ${this.nodeId} successfully renewed leadership for ${this.lockKey} (TTL: ${this.lockTTL}ms)`);
212
+ return true;
213
+ }
214
+ workflow_1.LoggerProxy.warn(`⚠️ Node ${this.nodeId} failed to renew leadership for ${this.lockKey} - lock no longer owned by this node`);
215
+ return false;
216
+ }
217
+ catch (error) {
218
+ workflow_1.LoggerProxy.error(`❌ Error renewing leadership lock for ${this.nodeId}: ${error instanceof Error ? error.message : String(error)}`);
219
+ return false;
220
+ }
221
+ }
222
+ /**
223
+ * Release the leadership lock
224
+ */
225
+ async releaseLock() {
226
+ try {
227
+ // Use Lua script to atomically check ownership and delete
228
+ const script = `
229
+ if redis.call("get", KEYS[1]) == ARGV[1] then
230
+ return redis.call("del", KEYS[1])
231
+ else
232
+ return 0
233
+ end
234
+ `;
235
+ await this.redis.eval(script, 1, this.lockKey, this.nodeId);
236
+ workflow_1.LoggerProxy.info(`Node ${this.nodeId} released leadership lock for ${this.lockKey}`);
237
+ }
238
+ catch (error) {
239
+ workflow_1.LoggerProxy.error(`Error releasing lock for ${this.nodeId}: ${error instanceof Error ? error.message : String(error)}`);
240
+ }
241
+ }
242
+ /**
243
+ * Start the renewal/retry loop
244
+ */
245
+ startRenewalLoop() {
246
+ workflow_1.LoggerProxy.info(`Starting leadership monitoring loop for ${this.nodeId} (check every ${this.renewalInterval}ms)`);
247
+ this.renewalTimer = setInterval(async () => {
248
+ if (this.isLeader) {
249
+ // Leader: Try to renew the lock
250
+ workflow_1.LoggerProxy.debug(`⏰ [LEADER] Node ${this.nodeId} periodic leadership renewal check`);
251
+ const renewed = await this.renewLock();
252
+ if (!renewed) {
253
+ // Failed to renew - we lost leadership
254
+ this.isLeader = false;
255
+ workflow_1.LoggerProxy.info(`💔 [LEADER] Node ${this.nodeId} LOST LEADERSHIP (failed to renew) for ${this.lockKey}`);
256
+ this.callbacks.onStoppedLeading();
257
+ }
258
+ else {
259
+ // Successfully renewed - keeping leadership
260
+ //Logger.info(`🔒 [LEADER] Node ${this.nodeId} RENEWED LEADERSHIP - staying active for ${this.lockKey}`);
261
+ }
262
+ }
263
+ else {
264
+ // Follower: Try to acquire leadership
265
+ workflow_1.LoggerProxy.debug(`⏰ [FOLLOWER] Node ${this.nodeId} checking for available leadership`);
266
+ await this.tryAcquireLeadership();
267
+ }
268
+ }, this.renewalInterval);
269
+ }
270
+ /**
271
+ * Generate a unique node identifier
272
+ */
273
+ generateNodeId() {
274
+ return (process.env["POD_NAME"] ||
275
+ process.env["HOSTNAME"] ||
276
+ `node-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`);
277
+ }
278
+ }
279
+ exports.RedisLeaderElectionManager = RedisLeaderElectionManager;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Local replacement types for the deprecated `request` and `request-promise-native` packages.
3
+ *
4
+ * These interfaces provide type compatibility for function signatures that previously
5
+ * referenced types from those packages. The actual HTTP implementation uses axios.
6
+ */
7
+ import type * as http from "node:http";
8
+ import type * as url from "node:url";
9
+ export interface RequestOptions {
10
+ uri?: string | url.Url;
11
+ url?: string | url.Url;
12
+ method?: string;
13
+ headers?: Record<string, unknown>;
14
+ body?: unknown;
15
+ json?: unknown;
16
+ qs?: Record<string, unknown>;
17
+ form?: Record<string, unknown>;
18
+ formData?: Record<string, unknown>;
19
+ encoding?: string | null;
20
+ timeout?: number;
21
+ followRedirect?: boolean;
22
+ followAllRedirects?: boolean;
23
+ maxRedirects?: number;
24
+ proxy?: string | {
25
+ host: string;
26
+ port: number;
27
+ auth?: {
28
+ username: string;
29
+ password: string;
30
+ };
31
+ protocol?: string;
32
+ };
33
+ auth?: {
34
+ user?: string;
35
+ username?: string;
36
+ pass?: string;
37
+ password?: string;
38
+ bearer?: string;
39
+ };
40
+ agent?: http.Agent;
41
+ agentOptions?: Record<string, unknown>;
42
+ rejectUnauthorized?: boolean;
43
+ strictSSL?: boolean;
44
+ gzip?: boolean;
45
+ [key: string]: unknown;
46
+ }
47
+ export interface OptionsWithUri extends RequestOptions {
48
+ uri: string | url.Url;
49
+ }
50
+ export interface OptionsWithUrl extends RequestOptions {
51
+ url: string | url.Url;
52
+ }
53
+ export interface RequestPromiseOptions extends RequestOptions {
54
+ simple?: boolean;
55
+ resolveWithFullResponse?: boolean;
56
+ transform?: (body: unknown, response: unknown, resolveWithFullResponse?: boolean) => unknown;
57
+ transform2xxOnly?: boolean;
58
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ /**
3
+ * Local replacement types for the deprecated `request` and `request-promise-native` packages.
4
+ *
5
+ * These interfaces provide type compatibility for function signatures that previously
6
+ * referenced types from those packages. The actual HTTP implementation uses axios.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,4 +1,4 @@
1
- import { IUserSettings } from '..';
1
+ import { type IUserSettings } from "..";
2
2
  /**
3
3
  * Creates the user settings if they do not exist yet
4
4
  *
@@ -0,0 +1,269 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.prepareUserSettings = prepareUserSettings;
37
+ exports.getEncryptionKey = getEncryptionKey;
38
+ exports.getInstanceId = getInstanceId;
39
+ exports.addToUserSettings = addToUserSettings;
40
+ exports.writeUserSettings = writeUserSettings;
41
+ exports.getUserSettings = getUserSettings;
42
+ exports.getUserSettingsPath = getUserSettingsPath;
43
+ exports.getUserN8nFolderPath = getUserN8nFolderPath;
44
+ exports.getUserN8nFolderCustomExtensionPath = getUserN8nFolderCustomExtensionPath;
45
+ exports.getUserHome = getUserHome;
46
+ const node_crypto_1 = require("node:crypto");
47
+ /* eslint-disable no-param-reassign */
48
+ /* eslint-disable @typescript-eslint/no-use-before-define */
49
+ /* eslint-disable @typescript-eslint/no-unsafe-call */
50
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
51
+ const fs = __importStar(require("node:fs"));
52
+ const path = __importStar(require("node:path"));
53
+ const node_util_1 = require("node:util");
54
+ // eslint-disable-next-line import/no-cycle
55
+ const __1 = require("..");
56
+ const fsAccess = (0, node_util_1.promisify)(fs.access);
57
+ const fsReadFile = (0, node_util_1.promisify)(fs.readFile);
58
+ const fsMkdir = (0, node_util_1.promisify)(fs.mkdir);
59
+ const fsWriteFile = (0, node_util_1.promisify)(fs.writeFile);
60
+ let settingsCache;
61
+ /**
62
+ * Creates the user settings if they do not exist yet
63
+ *
64
+ * @export
65
+ */
66
+ async function prepareUserSettings() {
67
+ const settingsPath = getUserSettingsPath();
68
+ let userSettings = await getUserSettings(settingsPath);
69
+ if (userSettings !== undefined) {
70
+ // Settings already exist, check if they contain the encryptionKey
71
+ if (userSettings.encryptionKey !== undefined) {
72
+ // Key already exists
73
+ if (userSettings.instanceId === undefined) {
74
+ userSettings.instanceId = await generateInstanceId(userSettings.encryptionKey);
75
+ settingsCache = userSettings;
76
+ }
77
+ return userSettings;
78
+ }
79
+ }
80
+ else {
81
+ userSettings = {};
82
+ }
83
+ if (process.env[__1.ENCRYPTION_KEY_ENV_OVERWRITE] !== undefined) {
84
+ // Use the encryption key which got set via environment
85
+ userSettings.encryptionKey = process.env[__1.ENCRYPTION_KEY_ENV_OVERWRITE];
86
+ }
87
+ else {
88
+ // Generate a new encryption key
89
+ userSettings.encryptionKey = (0, node_crypto_1.randomBytes)(24).toString("base64");
90
+ }
91
+ userSettings.instanceId = await generateInstanceId(userSettings.encryptionKey);
92
+ // eslint-disable-next-line no-console
93
+ console.log(`UserSettings were generated and saved to: ${settingsPath}`);
94
+ return writeUserSettings(userSettings, settingsPath);
95
+ }
96
+ /**
97
+ * Returns the encryption key which is used to encrypt
98
+ * the credentials.
99
+ *
100
+ * @export
101
+ * @returns
102
+ */
103
+ async function getEncryptionKey() {
104
+ if (process.env[__1.ENCRYPTION_KEY_ENV_OVERWRITE] !== undefined) {
105
+ return process.env[__1.ENCRYPTION_KEY_ENV_OVERWRITE];
106
+ }
107
+ const userSettings = await getUserSettings();
108
+ if (userSettings === undefined) {
109
+ return undefined;
110
+ }
111
+ if (userSettings.encryptionKey === undefined) {
112
+ return undefined;
113
+ }
114
+ return userSettings.encryptionKey;
115
+ }
116
+ /**
117
+ * Returns the instance ID
118
+ *
119
+ * @export
120
+ * @returns
121
+ */
122
+ async function getInstanceId() {
123
+ const userSettings = await getUserSettings();
124
+ if (userSettings === undefined) {
125
+ return "";
126
+ }
127
+ if (userSettings.instanceId === undefined) {
128
+ return "";
129
+ }
130
+ return userSettings.instanceId;
131
+ }
132
+ async function generateInstanceId(key) {
133
+ const hash = key
134
+ ? (0, node_crypto_1.createHash)("sha256")
135
+ .update(key.slice(Math.round(key.length / 2)))
136
+ .digest("hex")
137
+ : undefined;
138
+ return hash;
139
+ }
140
+ /**
141
+ * Adds/Overwrite the given settings in the currently
142
+ * saved user settings
143
+ *
144
+ * @export
145
+ * @param {IUserSettings} addSettings The settings to add/overwrite
146
+ * @param {string} [settingsPath] Optional settings file path
147
+ * @returns {Promise<IUserSettings>}
148
+ */
149
+ async function addToUserSettings(addSettings, settingsPath) {
150
+ const resolvedSettingsPath = settingsPath ?? getUserSettingsPath();
151
+ let userSettings = await getUserSettings(resolvedSettingsPath);
152
+ if (userSettings === undefined) {
153
+ userSettings = {};
154
+ }
155
+ // Add the settings
156
+ Object.assign(userSettings, addSettings);
157
+ return writeUserSettings(userSettings, resolvedSettingsPath);
158
+ }
159
+ /**
160
+ * Writes a user settings file
161
+ *
162
+ * @export
163
+ * @param {IUserSettings} userSettings The settings to write
164
+ * @param {string} [settingsPath] Optional settings file path
165
+ * @returns {Promise<IUserSettings>}
166
+ */
167
+ async function writeUserSettings(userSettings, settingsPath) {
168
+ const resolvedSettingsPath = settingsPath ?? getUserSettingsPath();
169
+ const resolvedUserSettings = userSettings ?? {};
170
+ // Check if parent folder exists if not create it.
171
+ try {
172
+ await fsAccess(path.dirname(resolvedSettingsPath));
173
+ }
174
+ catch (_error) {
175
+ // Parent folder does not exist so create
176
+ await fsMkdir(path.dirname(resolvedSettingsPath));
177
+ }
178
+ const settingsToWrite = { ...resolvedUserSettings };
179
+ if (settingsToWrite.instanceId !== undefined) {
180
+ settingsToWrite.instanceId = undefined;
181
+ }
182
+ await fsWriteFile(resolvedSettingsPath, JSON.stringify(settingsToWrite, null, "\t"));
183
+ settingsCache = JSON.parse(JSON.stringify(resolvedUserSettings));
184
+ return resolvedUserSettings;
185
+ }
186
+ /**
187
+ * Returns the content of the user settings
188
+ *
189
+ * @export
190
+ * @returns {UserSettings}
191
+ */
192
+ async function getUserSettings(settingsPath, ignoreCache) {
193
+ if (settingsCache !== undefined && ignoreCache !== true) {
194
+ return settingsCache;
195
+ }
196
+ const resolvedSettingsPath = settingsPath ?? getUserSettingsPath();
197
+ try {
198
+ await fsAccess(resolvedSettingsPath);
199
+ }
200
+ catch (_error) {
201
+ // The file does not exist
202
+ return undefined;
203
+ }
204
+ const settingsFile = await fsReadFile(resolvedSettingsPath, "utf8");
205
+ try {
206
+ settingsCache = JSON.parse(settingsFile);
207
+ }
208
+ catch (_error) {
209
+ throw new Error(`Error parsing n8n-config file "${resolvedSettingsPath}". It does not seem to be valid JSON.`);
210
+ }
211
+ return settingsCache;
212
+ }
213
+ /**
214
+ * Returns the path to the user settings
215
+ *
216
+ * @export
217
+ * @returns {string}
218
+ */
219
+ function getUserSettingsPath() {
220
+ const n8nFolder = getUserN8nFolderPath();
221
+ return path.join(n8nFolder, __1.USER_SETTINGS_FILE_NAME);
222
+ }
223
+ /**
224
+ * Retruns the path to the n8n folder in which all n8n
225
+ * related data gets saved
226
+ *
227
+ * @export
228
+ * @returns {string}
229
+ */
230
+ function getUserN8nFolderPath() {
231
+ let userFolder;
232
+ if (process.env[__1.USER_FOLDER_ENV_OVERWRITE] !== undefined) {
233
+ userFolder = process.env[__1.USER_FOLDER_ENV_OVERWRITE];
234
+ }
235
+ else {
236
+ userFolder = getUserHome();
237
+ }
238
+ return path.join(userFolder, __1.USER_SETTINGS_SUBFOLDER);
239
+ }
240
+ /**
241
+ * Returns the path to the n8n user folder with the custom
242
+ * extensions like nodes and credentials
243
+ *
244
+ * @export
245
+ * @returns {string}
246
+ */
247
+ function getUserN8nFolderCustomExtensionPath() {
248
+ return path.join(getUserN8nFolderPath(), __1.EXTENSIONS_SUBDIRECTORY);
249
+ }
250
+ /**
251
+ * Returns the home folder path of the user if
252
+ * none can be found it falls back to the current
253
+ * working directory
254
+ *
255
+ * @export
256
+ * @returns {string}
257
+ */
258
+ function getUserHome() {
259
+ let variableName = "HOME";
260
+ if (process.platform === "win32") {
261
+ variableName = "USERPROFILE";
262
+ }
263
+ if (process.env[variableName] === undefined) {
264
+ // If for some reason the variable does not exist
265
+ // fall back to current folder
266
+ return process.cwd();
267
+ }
268
+ return process.env[variableName];
269
+ }
@@ -1,5 +1,5 @@
1
- import PCancelable = require('p-cancelable');
2
- import { ExecutionError, IConnection, INode, INodeExecutionData, IRun, IRunData, IRunExecutionData, IWorkflowExecuteAdditionalData, Workflow, WorkflowExecuteMode } from '@fsai-flow/workflow';
1
+ import { type ExecutionError, type IConnection, type INode, type INodeExecutionData, type IRun, type IRunData, type IRunExecutionData, type IWorkflowExecuteAdditionalData, type Workflow, type WorkflowExecuteMode } from "@fsai-flow/workflow";
2
+ import PCancelable from "p-cancelable";
3
3
  export declare class WorkflowExecute {
4
4
  runExecutionData: IRunExecutionData;
5
5
  private additionalData;
@@ -30,11 +30,11 @@ export declare class WorkflowExecute {
30
30
  * Executes the hook with the given name
31
31
  *
32
32
  * @param {string} hookName
33
- * @param {any[]} parameters
33
+ * @param {unknown[]} parameters
34
34
  * @returns {Promise<IRun>}
35
35
  * @memberof WorkflowExecute
36
36
  */
37
- executeHook(hookName: string, parameters: any[]): Promise<void>;
37
+ executeHook(hookName: string, parameters: unknown[]): Promise<void>;
38
38
  /**
39
39
  * Checks the incoming connection does not receive any data
40
40
  */