@nordsym/apiclaw 1.7.2 → 1.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/convex/_generated/api.d.ts +115 -0
  2. package/convex/_generated/api.js +23 -0
  3. package/convex/_generated/dataModel.d.ts +60 -0
  4. package/convex/_generated/server.d.ts +143 -0
  5. package/convex/_generated/server.js +93 -0
  6. package/convex/adminActivate.d.ts +3 -0
  7. package/convex/adminActivate.d.ts.map +1 -0
  8. package/convex/adminActivate.js +47 -0
  9. package/convex/adminActivate.js.map +1 -0
  10. package/convex/adminActivate.ts +54 -0
  11. package/convex/adminStats.d.ts +3 -0
  12. package/convex/adminStats.d.ts.map +1 -0
  13. package/convex/adminStats.js +42 -0
  14. package/convex/adminStats.js.map +1 -0
  15. package/convex/adminStats.ts +44 -0
  16. package/convex/agents.d.ts +76 -0
  17. package/convex/agents.d.ts.map +1 -0
  18. package/convex/agents.js +699 -0
  19. package/convex/agents.js.map +1 -0
  20. package/convex/agents.ts +814 -0
  21. package/convex/analytics.d.ts +5 -0
  22. package/convex/analytics.d.ts.map +1 -0
  23. package/convex/analytics.js +166 -0
  24. package/convex/analytics.js.map +1 -0
  25. package/convex/analytics.ts +186 -0
  26. package/convex/billing.d.ts +88 -0
  27. package/convex/billing.d.ts.map +1 -0
  28. package/convex/billing.js +655 -0
  29. package/convex/billing.js.map +1 -0
  30. package/convex/billing.ts +791 -0
  31. package/convex/capabilities.d.ts +9 -0
  32. package/convex/capabilities.d.ts.map +1 -0
  33. package/convex/capabilities.js +145 -0
  34. package/convex/capabilities.js.map +1 -0
  35. package/convex/capabilities.ts +157 -0
  36. package/convex/chains.d.ts +68 -0
  37. package/convex/chains.d.ts.map +1 -0
  38. package/convex/chains.js +1105 -0
  39. package/convex/chains.js.map +1 -0
  40. package/convex/chains.ts +1318 -0
  41. package/convex/credits.d.ts +25 -0
  42. package/convex/credits.d.ts.map +1 -0
  43. package/convex/credits.js +186 -0
  44. package/convex/credits.js.map +1 -0
  45. package/convex/credits.ts +211 -0
  46. package/convex/crons.d.ts +3 -0
  47. package/convex/crons.d.ts.map +1 -0
  48. package/convex/crons.js +17 -0
  49. package/convex/crons.js.map +1 -0
  50. package/convex/crons.ts +28 -0
  51. package/convex/directCall.d.ts +72 -0
  52. package/convex/directCall.d.ts.map +1 -0
  53. package/convex/directCall.js +627 -0
  54. package/convex/directCall.js.map +1 -0
  55. package/convex/directCall.ts +678 -0
  56. package/convex/earnProgress.d.ts +58 -0
  57. package/convex/earnProgress.d.ts.map +1 -0
  58. package/convex/earnProgress.js +649 -0
  59. package/convex/earnProgress.js.map +1 -0
  60. package/convex/earnProgress.ts +753 -0
  61. package/convex/email.d.ts +14 -0
  62. package/convex/email.d.ts.map +1 -0
  63. package/convex/email.js +300 -0
  64. package/convex/email.js.map +1 -0
  65. package/convex/email.ts +329 -0
  66. package/convex/feedback.d.ts +7 -0
  67. package/convex/feedback.d.ts.map +1 -0
  68. package/convex/feedback.js +227 -0
  69. package/convex/feedback.js.map +1 -0
  70. package/convex/feedback.ts +265 -0
  71. package/convex/http.d.ts +3 -0
  72. package/convex/http.d.ts.map +1 -0
  73. package/convex/http.js +1405 -0
  74. package/convex/http.js.map +1 -0
  75. package/convex/http.ts +1577 -0
  76. package/convex/inbound.d.ts +2 -0
  77. package/convex/inbound.d.ts.map +1 -0
  78. package/convex/inbound.js +32 -0
  79. package/convex/inbound.js.map +1 -0
  80. package/convex/inbound.ts +32 -0
  81. package/convex/logs.d.ts +38 -0
  82. package/convex/logs.d.ts.map +1 -0
  83. package/convex/logs.js +487 -0
  84. package/convex/logs.js.map +1 -0
  85. package/convex/logs.ts +550 -0
  86. package/convex/mou.d.ts +6 -0
  87. package/convex/mou.d.ts.map +1 -0
  88. package/convex/mou.js +82 -0
  89. package/convex/mou.js.map +1 -0
  90. package/convex/mou.ts +91 -0
  91. package/convex/providerKeys.d.ts +31 -0
  92. package/convex/providerKeys.d.ts.map +1 -0
  93. package/convex/providerKeys.js +257 -0
  94. package/convex/providerKeys.js.map +1 -0
  95. package/convex/providerKeys.ts +289 -0
  96. package/convex/providers.d.ts +32 -0
  97. package/convex/providers.d.ts.map +1 -0
  98. package/convex/providers.js +814 -0
  99. package/convex/providers.js.map +1 -0
  100. package/convex/providers.ts +909 -0
  101. package/convex/purchases.d.ts +7 -0
  102. package/convex/purchases.d.ts.map +1 -0
  103. package/convex/purchases.js +157 -0
  104. package/convex/purchases.js.map +1 -0
  105. package/convex/purchases.ts +183 -0
  106. package/convex/ratelimit.d.ts +4 -0
  107. package/convex/ratelimit.d.ts.map +1 -0
  108. package/convex/ratelimit.js +91 -0
  109. package/convex/ratelimit.js.map +1 -0
  110. package/convex/ratelimit.ts +104 -0
  111. package/convex/schema.ts +802 -0
  112. package/convex/searchLogs.d.ts +4 -0
  113. package/convex/searchLogs.d.ts.map +1 -0
  114. package/convex/searchLogs.js +129 -0
  115. package/convex/searchLogs.js.map +1 -0
  116. package/convex/searchLogs.ts +146 -0
  117. package/convex/seedAPILayerAPIs.d.ts +7 -0
  118. package/convex/seedAPILayerAPIs.d.ts.map +1 -0
  119. package/convex/seedAPILayerAPIs.js +177 -0
  120. package/convex/seedAPILayerAPIs.js.map +1 -0
  121. package/convex/seedAPILayerAPIs.ts +191 -0
  122. package/convex/seedDirectCallConfigs.d.ts +2 -0
  123. package/convex/seedDirectCallConfigs.d.ts.map +1 -0
  124. package/convex/seedDirectCallConfigs.js +324 -0
  125. package/convex/seedDirectCallConfigs.js.map +1 -0
  126. package/convex/seedDirectCallConfigs.ts +336 -0
  127. package/convex/seedPratham.d.ts +6 -0
  128. package/convex/seedPratham.d.ts.map +1 -0
  129. package/convex/seedPratham.js +150 -0
  130. package/convex/seedPratham.js.map +1 -0
  131. package/convex/seedPratham.ts +161 -0
  132. package/convex/spendAlerts.d.ts +36 -0
  133. package/convex/spendAlerts.d.ts.map +1 -0
  134. package/convex/spendAlerts.js +380 -0
  135. package/convex/spendAlerts.js.map +1 -0
  136. package/convex/spendAlerts.ts +442 -0
  137. package/convex/stripeActions.d.ts +19 -0
  138. package/convex/stripeActions.d.ts.map +1 -0
  139. package/convex/stripeActions.js +411 -0
  140. package/convex/stripeActions.js.map +1 -0
  141. package/convex/stripeActions.ts +512 -0
  142. package/convex/teams.d.ts +21 -0
  143. package/convex/teams.d.ts.map +1 -0
  144. package/convex/teams.js +215 -0
  145. package/convex/teams.js.map +1 -0
  146. package/convex/teams.ts +243 -0
  147. package/convex/telemetry.d.ts +4 -0
  148. package/convex/telemetry.d.ts.map +1 -0
  149. package/convex/telemetry.js +74 -0
  150. package/convex/telemetry.js.map +1 -0
  151. package/convex/telemetry.ts +81 -0
  152. package/convex/tsconfig.json +25 -0
  153. package/convex/updateAPIStatus.d.ts +6 -0
  154. package/convex/updateAPIStatus.d.ts.map +1 -0
  155. package/convex/updateAPIStatus.js +40 -0
  156. package/convex/updateAPIStatus.js.map +1 -0
  157. package/convex/updateAPIStatus.ts +45 -0
  158. package/convex/usage.d.ts +27 -0
  159. package/convex/usage.d.ts.map +1 -0
  160. package/convex/usage.js +229 -0
  161. package/convex/usage.js.map +1 -0
  162. package/convex/usage.ts +260 -0
  163. package/convex/waitlist.d.ts +4 -0
  164. package/convex/waitlist.d.ts.map +1 -0
  165. package/convex/waitlist.js +49 -0
  166. package/convex/waitlist.js.map +1 -0
  167. package/convex/waitlist.ts +55 -0
  168. package/convex/webhooks.d.ts +12 -0
  169. package/convex/webhooks.d.ts.map +1 -0
  170. package/convex/webhooks.js +410 -0
  171. package/convex/webhooks.js.map +1 -0
  172. package/convex/webhooks.ts +494 -0
  173. package/convex/workspaces.d.ts +31 -0
  174. package/convex/workspaces.d.ts.map +1 -0
  175. package/convex/workspaces.js +975 -0
  176. package/convex/workspaces.js.map +1 -0
  177. package/convex/workspaces.ts +1130 -0
  178. package/dist/bin.js +0 -0
  179. package/dist/capability-router.js +1 -1
  180. package/dist/capability-router.js.map +1 -1
  181. package/dist/execute.d.ts +2 -0
  182. package/dist/execute.d.ts.map +1 -1
  183. package/dist/execute.js +18 -4
  184. package/dist/execute.js.map +1 -1
  185. package/dist/http-api.js +1 -1
  186. package/dist/http-api.js.map +1 -1
  187. package/dist/index.js +1 -1
  188. package/dist/index.js.map +1 -1
  189. package/dist/mcp-analytics.d.ts +32 -0
  190. package/dist/mcp-analytics.d.ts.map +1 -0
  191. package/dist/mcp-analytics.js +130 -0
  192. package/dist/mcp-analytics.js.map +1 -0
  193. package/package.json +1 -1
  194. package/dist/chain-types.d.ts +0 -187
  195. package/dist/chain-types.d.ts.map +0 -1
  196. package/dist/chain-types.js +0 -33
  197. package/dist/chain-types.js.map +0 -1
  198. package/dist/registry/apis.json.bak +0 -248811
  199. package/dist/src/bin.js +0 -17
  200. package/dist/src/capability-router.js +0 -240
  201. package/dist/src/chainExecutor.js +0 -451
  202. package/dist/src/chainResolver.js +0 -518
  203. package/dist/src/cli/commands/doctor.js +0 -324
  204. package/dist/src/cli/commands/mcp-install.js +0 -255
  205. package/dist/src/cli/commands/restore.js +0 -259
  206. package/dist/src/cli/commands/setup.js +0 -205
  207. package/dist/src/cli/commands/uninstall.js +0 -188
  208. package/dist/src/cli/index.js +0 -111
  209. package/dist/src/cli.js +0 -302
  210. package/dist/src/confirmation.js +0 -240
  211. package/dist/src/credentials.js +0 -357
  212. package/dist/src/credits.js +0 -260
  213. package/dist/src/crypto.js +0 -66
  214. package/dist/src/discovery.js +0 -504
  215. package/dist/src/enterprise/env.js +0 -123
  216. package/dist/src/enterprise/script-generator.js +0 -460
  217. package/dist/src/execute-dynamic.js +0 -473
  218. package/dist/src/execute.js +0 -1727
  219. package/dist/src/index.js +0 -2062
  220. package/dist/src/metered.js +0 -80
  221. package/dist/src/open-apis.js +0 -276
  222. package/dist/src/proxy.js +0 -28
  223. package/dist/src/session.js +0 -86
  224. package/dist/src/stripe.js +0 -407
  225. package/dist/src/telemetry.js +0 -49
  226. package/dist/src/types.js +0 -2
  227. package/dist/src/utils/backup.js +0 -181
  228. package/dist/src/utils/config.js +0 -220
  229. package/dist/src/utils/os.js +0 -105
  230. package/dist/src/utils/paths.js +0 -159
@@ -1,451 +0,0 @@
1
- /**
2
- * APIClaw Chain Executor
3
- *
4
- * Orchestrates multi-step API chains with:
5
- * - Sequential execution
6
- * - Parallel batches
7
- * - Conditional branching
8
- * - ForEach loops
9
- * - Error handling and retry
10
- * - Full execution trace
11
- */
12
- import { executeAPICall } from './execute.js';
13
- import { resolveReferences, validateReferences, evaluateCondition, } from './chainResolver.js';
14
- // ============================================================================
15
- // MAIN EXECUTOR
16
- // ============================================================================
17
- /**
18
- * Execute a chain of API calls
19
- */
20
- export async function executeChain(chain, credentials, inputs, options = {}) {
21
- const chainId = chain.id || generateChainId();
22
- const startedAt = new Date().toISOString();
23
- const startTime = Date.now();
24
- // Initialize context
25
- const context = {
26
- results: {},
27
- inputs: inputs || {},
28
- currentIndex: 0,
29
- startedAt,
30
- env: process.env,
31
- };
32
- // Initialize result
33
- const result = {
34
- success: false,
35
- chainId,
36
- startedAt,
37
- completedAt: '',
38
- totalLatencyMs: 0,
39
- totalCost: { cents: 0 },
40
- results: {},
41
- completedSteps: [],
42
- trace: [],
43
- canResume: false,
44
- };
45
- try {
46
- // Validate inputs
47
- if (chain.inputs) {
48
- validateInputs(inputs || {}, chain.inputs);
49
- }
50
- // Validate references before execution
51
- const validation = validateReferences(chain.steps);
52
- if (!validation.valid) {
53
- const errorMsg = validation.errors.map(e => `${e.stepId}: ${e.message}`).join('; ');
54
- throw new Error(`Reference validation failed: ${errorMsg}`);
55
- }
56
- // Log warnings
57
- if (options.verbose && validation.warnings.length > 0) {
58
- console.log('[Chain] Warnings:', validation.warnings);
59
- }
60
- // Check limits
61
- if (chain.limits?.maxSteps && chain.steps.length > chain.limits.maxSteps) {
62
- throw new Error(`Chain exceeds maxSteps limit (${chain.steps.length} > ${chain.limits.maxSteps})`);
63
- }
64
- // Execute steps
65
- let lastStepResult;
66
- for (let i = 0; i < chain.steps.length; i++) {
67
- const step = chain.steps[i];
68
- context.currentIndex = i;
69
- // Check timeout
70
- if (chain.timeout && Date.now() - startTime > chain.timeout) {
71
- throw new TimeoutError(`Chain exceeded timeout of ${chain.timeout}ms`);
72
- }
73
- // Execute based on step type
74
- if (isParallelStep(step)) {
75
- lastStepResult = await executeParallelStep(step, context, credentials, options, result);
76
- }
77
- else if (isConditionalStep(step)) {
78
- lastStepResult = await executeConditionalStep(step, context, credentials, options, result);
79
- }
80
- else if (isForEachStep(step)) {
81
- lastStepResult = await executeForEachStep(step, context, credentials, options, result, chain.limits);
82
- }
83
- else {
84
- lastStepResult = await executeSingleStep(step, context, credentials, options, result, chain.errorPolicy);
85
- }
86
- }
87
- // Success!
88
- result.success = true;
89
- result.finalResult = lastStepResult;
90
- result.results = { ...context.results };
91
- }
92
- catch (error) {
93
- // Handle failure
94
- result.success = false;
95
- result.error = {
96
- stepId: result.failedStep?.stepId || 'unknown',
97
- code: error.code || 'CHAIN_ERROR',
98
- message: error.message,
99
- retryAfter: error.retryAfter,
100
- };
101
- result.results = { ...context.results };
102
- // Handle rollback for transactional mode
103
- if (chain.errorPolicy?.mode === 'transactional' && chain.errorPolicy.rollback) {
104
- await executeRollback(chain.errorPolicy.rollback, context, credentials, options, result);
105
- }
106
- // Can resume if we have completed steps
107
- result.canResume = result.completedSteps.length > 0;
108
- if (result.canResume) {
109
- result.resumeToken = `${chainId}_step_${result.completedSteps.length}`;
110
- }
111
- }
112
- // Finalize
113
- result.completedAt = new Date().toISOString();
114
- result.totalLatencyMs = Date.now() - startTime;
115
- return result;
116
- }
117
- // ============================================================================
118
- // STEP TYPE GUARDS
119
- // ============================================================================
120
- function isParallelStep(step) {
121
- return 'parallel' in step;
122
- }
123
- function isConditionalStep(step) {
124
- return 'if' in step;
125
- }
126
- function isForEachStep(step) {
127
- return 'forEach' in step;
128
- }
129
- // ============================================================================
130
- // SINGLE STEP EXECUTION
131
- // ============================================================================
132
- async function executeSingleStep(step, context, credentials, options, result, errorPolicy) {
133
- const stepStart = Date.now();
134
- const stepTrace = {
135
- stepId: step.id,
136
- stepIndex: context.currentIndex,
137
- provider: step.provider,
138
- action: step.action,
139
- startedAt: new Date().toISOString(),
140
- completedAt: '',
141
- latencyMs: 0,
142
- success: false,
143
- input: {},
144
- };
145
- options.onStepStart?.(step.id, context.currentIndex);
146
- try {
147
- // Resolve references in params
148
- const resolvedParams = step.params ? resolveReferences(step.params, context) : {};
149
- stepTrace.input = resolvedParams;
150
- // Execute with retry if configured
151
- const maxRetries = step.onError?.retry?.attempts || 0;
152
- let lastError;
153
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
154
- try {
155
- // Get customer key for this provider
156
- const customerKey = credentials.customerKeys?.[step.provider];
157
- // Execute the API call
158
- const apiResult = await executeAPICall(step.provider, step.action, resolvedParams, credentials.userId, customerKey);
159
- if (!apiResult.success) {
160
- throw new StepError(apiResult.error || 'API call failed', apiResult.code || 'PROVIDER_ERROR');
161
- }
162
- // Success!
163
- stepTrace.success = true;
164
- stepTrace.output = apiResult.data;
165
- stepTrace.cost = apiResult.cost ? { cents: Math.round(apiResult.cost * 100) } : undefined;
166
- // Update context
167
- context.results[step.id] = apiResult.data;
168
- context.prevStepId = step.id;
169
- // Update result
170
- result.completedSteps.push(step.id);
171
- if (stepTrace.cost) {
172
- result.totalCost.cents += stepTrace.cost.cents;
173
- }
174
- return apiResult.data;
175
- }
176
- catch (error) {
177
- lastError = error;
178
- stepTrace.retries = attempt;
179
- if (attempt < maxRetries) {
180
- // Wait before retry
181
- const backoff = step.onError?.retry?.backoff?.[attempt] || 1000 * Math.pow(2, attempt);
182
- await sleep(backoff);
183
- }
184
- }
185
- }
186
- // All retries exhausted
187
- throw lastError;
188
- }
189
- catch (error) {
190
- stepTrace.success = false;
191
- stepTrace.error = error.message;
192
- stepTrace.errorCode = error.code;
193
- // Handle error based on policy
194
- const shouldAbort = step.onError?.abort !== false && errorPolicy?.mode !== 'best-effort';
195
- // Try fallback if configured
196
- if (step.onError?.fallback && !options.dryRun) {
197
- try {
198
- const fallbackResult = await executeSingleStep(step.onError.fallback, context, credentials, options, result, errorPolicy);
199
- // Use fallback result as this step's result
200
- context.results[step.id] = fallbackResult;
201
- context.prevStepId = step.id;
202
- stepTrace.success = true;
203
- stepTrace.output = { fallback: true, result: fallbackResult };
204
- result.completedSteps.push(step.id);
205
- return fallbackResult;
206
- }
207
- catch (fallbackError) {
208
- // Fallback also failed
209
- stepTrace.error = `Original: ${error.message}; Fallback: ${fallbackError.message}`;
210
- }
211
- }
212
- result.failedStep = stepTrace;
213
- if (shouldAbort) {
214
- throw error;
215
- }
216
- // Best-effort mode: continue despite failure
217
- context.results[step.id] = { error: error.message };
218
- context.prevStepId = step.id;
219
- return { error: error.message };
220
- }
221
- finally {
222
- stepTrace.completedAt = new Date().toISOString();
223
- stepTrace.latencyMs = Date.now() - stepStart;
224
- result.trace.push(stepTrace);
225
- options.onStepComplete?.(stepTrace);
226
- }
227
- }
228
- // ============================================================================
229
- // PARALLEL EXECUTION
230
- // ============================================================================
231
- async function executeParallelStep(step, context, credentials, options, result) {
232
- const parallelResults = await Promise.all(step.parallel.map(async (ps, idx) => {
233
- // Create a copy of context for each parallel step
234
- const parallelContext = {
235
- ...context,
236
- currentIndex: context.currentIndex,
237
- };
238
- try {
239
- return await executeSingleStep(ps, parallelContext, credentials, options, result);
240
- }
241
- catch (error) {
242
- // Return error as result for best-effort
243
- return { error: error.message };
244
- }
245
- }));
246
- // Store parallel results
247
- context.parallelResults = parallelResults;
248
- // Copy results from parallel steps to main context
249
- for (let i = 0; i < step.parallel.length; i++) {
250
- const ps = step.parallel[i];
251
- context.results[ps.id] = parallelResults[i];
252
- }
253
- // Last parallel step becomes prev
254
- context.prevStepId = step.parallel[step.parallel.length - 1].id;
255
- return parallelResults;
256
- }
257
- // ============================================================================
258
- // CONDITIONAL EXECUTION
259
- // ============================================================================
260
- async function executeConditionalStep(step, context, credentials, options, result) {
261
- // Evaluate condition
262
- const conditionResult = evaluateCondition(step.if, context);
263
- // Choose branch
264
- const branch = conditionResult ? step.then : step.else;
265
- if (!branch) {
266
- // No else branch and condition is false
267
- return null;
268
- }
269
- // Execute branch (can be single step or array)
270
- const steps = Array.isArray(branch) ? branch : [branch];
271
- let lastResult;
272
- for (const branchStep of steps) {
273
- lastResult = await executeSingleStep(branchStep, context, credentials, options, result);
274
- }
275
- return lastResult;
276
- }
277
- // ============================================================================
278
- // FOREACH EXECUTION
279
- // ============================================================================
280
- async function executeForEachStep(step, context, credentials, options, result, limits) {
281
- // Resolve the array to iterate over
282
- const arrayRef = step.forEach;
283
- let items;
284
- // Handle reference vs direct array
285
- if (arrayRef.startsWith('$')) {
286
- // It's a reference - resolve it
287
- const resolved = resolveReferences({ items: arrayRef }, context);
288
- items = resolved.items;
289
- }
290
- else {
291
- // Try to parse as JSON array
292
- try {
293
- items = JSON.parse(arrayRef);
294
- }
295
- catch {
296
- throw new Error(`forEach value must be a reference or JSON array: ${arrayRef}`);
297
- }
298
- }
299
- if (!Array.isArray(items)) {
300
- throw new Error(`forEach target must resolve to an array, got: ${typeof items}`);
301
- }
302
- // Check max iterations
303
- if (limits?.maxSteps && items.length > limits.maxSteps) {
304
- throw new Error(`forEach exceeds maxSteps limit (${items.length} iterations)`);
305
- }
306
- const forEachResults = [];
307
- for (let i = 0; i < items.length; i++) {
308
- // Set up forEach context
309
- context.forEachItem = items[i];
310
- context.forEachIndex = i;
311
- context.forEachResults = forEachResults;
312
- // Create step with dynamic ID
313
- const dynamicStep = {
314
- ...step.do,
315
- id: step.do.id.replace(/\$index/g, String(i)),
316
- };
317
- const itemResult = await executeSingleStep(dynamicStep, context, credentials, options, result);
318
- forEachResults.push(itemResult);
319
- }
320
- // Clean up forEach context
321
- delete context.forEachItem;
322
- delete context.forEachIndex;
323
- context.forEachResults = forEachResults;
324
- // Store aggregate results
325
- context.results['$forEach'] = { results: forEachResults };
326
- return forEachResults;
327
- }
328
- // ============================================================================
329
- // ROLLBACK EXECUTION
330
- // ============================================================================
331
- async function executeRollback(rollbackSteps, context, credentials, options, result) {
332
- for (const rb of rollbackSteps) {
333
- try {
334
- const shouldRollback = evaluateCondition(rb.if, context);
335
- if (shouldRollback) {
336
- await executeSingleStep(rb.do, context, credentials, { ...options, verbose: false }, result);
337
- }
338
- }
339
- catch (error) {
340
- // Log but don't fail on rollback errors
341
- console.error('[Chain] Rollback failed:', error);
342
- }
343
- }
344
- }
345
- // ============================================================================
346
- // INPUT VALIDATION
347
- // ============================================================================
348
- function validateInputs(inputs, definitions) {
349
- for (const [name, def] of Object.entries(definitions)) {
350
- const value = inputs[name];
351
- // Check required
352
- if (def.required && value === undefined) {
353
- if (def.default !== undefined) {
354
- inputs[name] = def.default;
355
- }
356
- else {
357
- throw new Error(`Missing required input: ${name}`);
358
- }
359
- }
360
- // Apply default
361
- if (value === undefined && def.default !== undefined) {
362
- inputs[name] = def.default;
363
- }
364
- // Type check (if value provided)
365
- if (inputs[name] !== undefined) {
366
- const actualType = Array.isArray(inputs[name]) ? 'array' : typeof inputs[name];
367
- if (actualType !== def.type) {
368
- throw new Error(`Input '${name}' must be ${def.type}, got ${actualType}`);
369
- }
370
- }
371
- }
372
- }
373
- // ============================================================================
374
- // UTILITIES
375
- // ============================================================================
376
- function generateChainId() {
377
- return `chain_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
378
- }
379
- function sleep(ms) {
380
- return new Promise(resolve => setTimeout(resolve, ms));
381
- }
382
- // ============================================================================
383
- // CUSTOM ERRORS
384
- // ============================================================================
385
- export class StepError extends Error {
386
- constructor(message, code, retryAfter) {
387
- super(message);
388
- this.name = 'StepError';
389
- this.code = code;
390
- this.retryAfter = retryAfter;
391
- }
392
- }
393
- export class TimeoutError extends Error {
394
- constructor(message) {
395
- super(message);
396
- this.code = 'TIMEOUT';
397
- this.name = 'TimeoutError';
398
- }
399
- }
400
- // ============================================================================
401
- // CHAIN STATUS & RESUME (Stubs for future implementation)
402
- // ============================================================================
403
- // In-memory store for running chains (would be Redis/DB in production)
404
- const runningChains = new Map();
405
- /**
406
- * Get status of a running or completed chain
407
- */
408
- export async function getChainStatus(chainId) {
409
- const entry = runningChains.get(chainId);
410
- if (!entry) {
411
- return { chainId, status: 'not_found' };
412
- }
413
- return {
414
- chainId,
415
- status: entry.status,
416
- result: entry.result,
417
- };
418
- }
419
- /**
420
- * Resume a failed chain from a resume token
421
- */
422
- export async function resumeChain(resumeToken, chain, credentials, inputs, overrides, options = {}) {
423
- // Parse resume token: chain_xyz_step_N
424
- const match = resumeToken.match(/^(.+)_step_(\d+)$/);
425
- if (!match) {
426
- throw new Error(`Invalid resume token: ${resumeToken}`);
427
- }
428
- const [, chainId, stepIndexStr] = match;
429
- const resumeFromIndex = parseInt(stepIndexStr, 10);
430
- // Create a modified chain starting from the resume point
431
- const resumedChain = {
432
- ...chain,
433
- id: chainId,
434
- steps: chain.steps.slice(resumeFromIndex),
435
- };
436
- // Apply any overrides to the resumed steps
437
- if (overrides) {
438
- for (const step of resumedChain.steps) {
439
- if ('id' in step && overrides[step.id]) {
440
- step.params = { ...step.params, ...overrides[step.id] };
441
- }
442
- }
443
- }
444
- // Execute the resumed chain
445
- // Note: In a real implementation, we'd restore the context from the previous run
446
- return executeChain(resumedChain, credentials, inputs, options);
447
- }
448
- // ============================================================================
449
- // RE-EXPORTS
450
- // ============================================================================
451
- export { resolveReferences, validateReferences, evaluateCondition, } from './chainResolver.js';