@mesantosrai/pipeline-canvas 1.0.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 (148) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +545 -0
  3. package/dist/_virtual/dynamic-import-helper.mjs +17 -0
  4. package/dist/_virtual/dynamic-import-helper.mjs.map +1 -0
  5. package/dist/components/CustomHandle.d.ts +9 -0
  6. package/dist/components/CustomHandle.d.ts.map +1 -0
  7. package/dist/components/CustomHandle.mjs +18 -0
  8. package/dist/components/CustomHandle.mjs.map +1 -0
  9. package/dist/components/ExecutionLogsPanel.d.ts +3 -0
  10. package/dist/components/ExecutionLogsPanel.d.ts.map +1 -0
  11. package/dist/components/ExecutionLogsPanel.mjs +189 -0
  12. package/dist/components/ExecutionLogsPanel.mjs.map +1 -0
  13. package/dist/components/NodeContextMenu.d.ts +15 -0
  14. package/dist/components/NodeContextMenu.d.ts.map +1 -0
  15. package/dist/components/NodeContextMenu.mjs +110 -0
  16. package/dist/components/NodeContextMenu.mjs.map +1 -0
  17. package/dist/components/PipelineCanvas.d.ts +4 -0
  18. package/dist/components/PipelineCanvas.d.ts.map +1 -0
  19. package/dist/components/PipelineCanvas.mjs +1016 -0
  20. package/dist/components/PipelineCanvas.mjs.map +1 -0
  21. package/dist/components/PipelineCanvasProvider.d.ts +30 -0
  22. package/dist/components/PipelineCanvasProvider.d.ts.map +1 -0
  23. package/dist/components/PipelineCanvasProvider.mjs +7 -0
  24. package/dist/components/PipelineCanvasProvider.mjs.map +1 -0
  25. package/dist/components/PipelineExecution.d.ts +16 -0
  26. package/dist/components/PipelineExecution.d.ts.map +1 -0
  27. package/dist/components/PipelineExecution.mjs +310 -0
  28. package/dist/components/PipelineExecution.mjs.map +1 -0
  29. package/dist/components/PipelineManager.d.ts +8 -0
  30. package/dist/components/PipelineManager.d.ts.map +1 -0
  31. package/dist/components/PipelineManager.mjs +143 -0
  32. package/dist/components/PipelineManager.mjs.map +1 -0
  33. package/dist/components/PipelineNodeConfig.d.ts +11 -0
  34. package/dist/components/PipelineNodeConfig.d.ts.map +1 -0
  35. package/dist/components/PipelineNodeConfig.mjs +1808 -0
  36. package/dist/components/PipelineNodeConfig.mjs.map +1 -0
  37. package/dist/components/PipelineNodePalette.d.ts +3 -0
  38. package/dist/components/PipelineNodePalette.d.ts.map +1 -0
  39. package/dist/components/PipelineNodePalette.mjs +87 -0
  40. package/dist/components/PipelineNodePalette.mjs.map +1 -0
  41. package/dist/components/SavePipelineDialog.d.ts +9 -0
  42. package/dist/components/SavePipelineDialog.d.ts.map +1 -0
  43. package/dist/components/SavePipelineDialog.mjs +140 -0
  44. package/dist/components/SavePipelineDialog.mjs.map +1 -0
  45. package/dist/components/SavedPipelinesList.d.ts +3 -0
  46. package/dist/components/SavedPipelinesList.d.ts.map +1 -0
  47. package/dist/components/SavedPipelinesList.mjs +172 -0
  48. package/dist/components/SavedPipelinesList.mjs.map +1 -0
  49. package/dist/components/index.d.ts +8 -0
  50. package/dist/components/index.d.ts.map +1 -0
  51. package/dist/components/ui/alert.d.ts +9 -0
  52. package/dist/components/ui/alert.d.ts.map +1 -0
  53. package/dist/components/ui/alert.mjs +51 -0
  54. package/dist/components/ui/alert.mjs.map +1 -0
  55. package/dist/components/ui/button.d.ts +12 -0
  56. package/dist/components/ui/button.d.ts.map +1 -0
  57. package/dist/components/ui/button.mjs +45 -0
  58. package/dist/components/ui/button.mjs.map +1 -0
  59. package/dist/components/ui/dialog.d.ts +20 -0
  60. package/dist/components/ui/dialog.d.ts.map +1 -0
  61. package/dist/components/ui/dialog.mjs +99 -0
  62. package/dist/components/ui/dialog.mjs.map +1 -0
  63. package/dist/components/ui/index.d.ts +8 -0
  64. package/dist/components/ui/index.d.ts.map +1 -0
  65. package/dist/components/ui/input.d.ts +6 -0
  66. package/dist/components/ui/input.d.ts.map +1 -0
  67. package/dist/components/ui/input.mjs +22 -0
  68. package/dist/components/ui/input.mjs.map +1 -0
  69. package/dist/components/ui/label.d.ts +6 -0
  70. package/dist/components/ui/label.d.ts.map +1 -0
  71. package/dist/components/ui/label.mjs +20 -0
  72. package/dist/components/ui/label.mjs.map +1 -0
  73. package/dist/components/ui/select.d.ts +14 -0
  74. package/dist/components/ui/select.d.ts.map +1 -0
  75. package/dist/components/ui/select.mjs +121 -0
  76. package/dist/components/ui/select.mjs.map +1 -0
  77. package/dist/components/ui/tooltip.d.ts +8 -0
  78. package/dist/components/ui/tooltip.d.ts.map +1 -0
  79. package/dist/components/ui/tooltip.mjs +24 -0
  80. package/dist/components/ui/tooltip.mjs.map +1 -0
  81. package/dist/context/PipelineContext.d.ts +50 -0
  82. package/dist/context/PipelineContext.d.ts.map +1 -0
  83. package/dist/context/PipelineContext.mjs +36 -0
  84. package/dist/context/PipelineContext.mjs.map +1 -0
  85. package/dist/index.d.ts +12 -0
  86. package/dist/index.d.ts.map +1 -0
  87. package/dist/index.mjs +45 -0
  88. package/dist/index.mjs.map +1 -0
  89. package/dist/lib/utils.d.ts +3 -0
  90. package/dist/lib/utils.d.ts.map +1 -0
  91. package/dist/lib/utils.mjs +9 -0
  92. package/dist/lib/utils.mjs.map +1 -0
  93. package/dist/node_modules/zustand/esm/middleware.mjs +256 -0
  94. package/dist/node_modules/zustand/esm/middleware.mjs.map +1 -0
  95. package/dist/nodes/alphafold_node/node.json.mjs +82 -0
  96. package/dist/nodes/alphafold_node/node.json.mjs.map +1 -0
  97. package/dist/nodes/http_request_node/node.json.mjs +383 -0
  98. package/dist/nodes/http_request_node/node.json.mjs.map +1 -0
  99. package/dist/nodes/input_node/node.json.mjs +51 -0
  100. package/dist/nodes/input_node/node.json.mjs.map +1 -0
  101. package/dist/nodes/message_input_node/node.json.mjs +90 -0
  102. package/dist/nodes/message_input_node/node.json.mjs.map +1 -0
  103. package/dist/nodes/proteinmpnn_node/node.json.mjs +83 -0
  104. package/dist/nodes/proteinmpnn_node/node.json.mjs.map +1 -0
  105. package/dist/nodes/rfdiffusion_node/node.json.mjs +281 -0
  106. package/dist/nodes/rfdiffusion_node/node.json.mjs.map +1 -0
  107. package/dist/store/pipelineStore.d.ts +108 -0
  108. package/dist/store/pipelineStore.d.ts.map +1 -0
  109. package/dist/store/pipelineStore.mjs +633 -0
  110. package/dist/store/pipelineStore.mjs.map +1 -0
  111. package/dist/style.css +1 -0
  112. package/dist/types/dependencies.d.ts +93 -0
  113. package/dist/types/dependencies.d.ts.map +1 -0
  114. package/dist/types/index.d.ts +56 -0
  115. package/dist/types/index.d.ts.map +1 -0
  116. package/dist/types/logger.d.ts +67 -0
  117. package/dist/types/logger.d.ts.map +1 -0
  118. package/dist/types/logger.mjs +22 -0
  119. package/dist/types/logger.mjs.map +1 -0
  120. package/dist/utils/executionEngine.d.ts +27 -0
  121. package/dist/utils/executionEngine.d.ts.map +1 -0
  122. package/dist/utils/executionEngine.mjs +461 -0
  123. package/dist/utils/executionEngine.mjs.map +1 -0
  124. package/dist/utils/index.d.ts +6 -0
  125. package/dist/utils/index.d.ts.map +1 -0
  126. package/dist/utils/logger.d.ts +23 -0
  127. package/dist/utils/logger.d.ts.map +1 -0
  128. package/dist/utils/logger.mjs +29 -0
  129. package/dist/utils/logger.mjs.map +1 -0
  130. package/dist/utils/nodeLoader.d.ts +76 -0
  131. package/dist/utils/nodeLoader.d.ts.map +1 -0
  132. package/dist/utils/nodeLoader.mjs +48 -0
  133. package/dist/utils/nodeLoader.mjs.map +1 -0
  134. package/dist/utils/templateResolver.d.ts +10 -0
  135. package/dist/utils/templateResolver.d.ts.map +1 -0
  136. package/dist/utils/templateResolver.mjs +64 -0
  137. package/dist/utils/templateResolver.mjs.map +1 -0
  138. package/dist/utils/topologicalSort.d.ts +10 -0
  139. package/dist/utils/topologicalSort.d.ts.map +1 -0
  140. package/dist/utils/topologicalSort.mjs +25 -0
  141. package/dist/utils/topologicalSort.mjs.map +1 -0
  142. package/nodes/alphafold_node/node.json +77 -0
  143. package/nodes/http_request_node/node.json +311 -0
  144. package/nodes/input_node/node.json +47 -0
  145. package/nodes/message_input_node/node.json +56 -0
  146. package/nodes/proteinmpnn_node/node.json +78 -0
  147. package/nodes/rfdiffusion_node/node.json +231 -0
  148. package/package.json +94 -0
@@ -0,0 +1,461 @@
1
+ import { loadNodeConfig as Q } from "./nodeLoader.mjs";
2
+ import { resolveTemplates as E } from "./templateResolver.mjs";
3
+ async function oe(i, u, c, d) {
4
+ var R, q, k, P, v, D, A, U, H, J, M, W, F, L, z;
5
+ const f = d.edges.filter(($) => $.target === i);
6
+ if (f.length === 0)
7
+ return null;
8
+ const a = d.nodes.find(($) => $.id === f[0].source);
9
+ if (!a)
10
+ return null;
11
+ if (!(await Q(a.type)).handles.outputs.find(
12
+ ($) => $.dataType === c.dataType
13
+ ) && c.dataType, a.type === "input_node" && (c.dataType === "pdb_file" || !c.dataType))
14
+ return (R = a.result_metadata) != null && R.file_info ? a.result_metadata.file_info : (q = a.result_metadata) != null && q.data ? a.result_metadata.data : {
15
+ type: "pdb_file",
16
+ filename: (k = a.config) == null ? void 0 : k.filename,
17
+ file_id: (P = a.config) == null ? void 0 : P.file_id,
18
+ file_url: (v = a.config) == null ? void 0 : v.file_url,
19
+ chains: (D = a.config) == null ? void 0 : D.chains,
20
+ total_residues: (A = a.config) == null ? void 0 : A.total_residues,
21
+ suggested_contigs: (U = a.config) == null ? void 0 : U.suggested_contigs,
22
+ chain_residue_counts: (H = a.config) == null ? void 0 : H.chain_residue_counts,
23
+ atoms: (J = a.config) == null ? void 0 : J.atoms
24
+ };
25
+ if (a.type === "message_input_node") {
26
+ if (c.dataType === "any" || !c.dataType)
27
+ return a.result_metadata || null;
28
+ if (c.dataType === "message")
29
+ return ((M = a.result_metadata) == null ? void 0 : M.message) || ((W = a.config) == null ? void 0 : W.message) || null;
30
+ }
31
+ return (F = a.result_metadata) != null && F.output_file && c.dataType === "pdb_file" ? a.result_metadata.output_file : (L = a.result_metadata) != null && L.sequence && c.dataType === "sequence" ? a.result_metadata.sequence : (z = a.result_metadata) != null && z.message && c.dataType === "message" ? a.result_metadata.message : a.result_metadata && c.dataType === "any" ? a.result_metadata : a.result_metadata && (a.result_metadata.output_file || a.result_metadata.sequence || a.result_metadata.message || a.result_metadata.data || // For code execution, return the full result
32
+ (Object.keys(a.result_metadata).length > 0 ? a.result_metadata : null)) || null;
33
+ }
34
+ async function ee(i, u, c) {
35
+ const d = {};
36
+ for (const f of u.handles.inputs) {
37
+ const a = await oe(i.id, f.id, f, c);
38
+ a !== null && (d[f.id] = a);
39
+ }
40
+ return d;
41
+ }
42
+ async function de(i, u) {
43
+ var a, b, N, R, q, k, P, v, D, A, U, H, J, M, W, F, L, z, $, X;
44
+ const c = await Q(i.type), d = await ee(i, c, u.pipeline);
45
+ for (const _ of c.handles.inputs)
46
+ if (i.type !== "http_request_node" && !d[_.id] && _.dataType)
47
+ throw new Error(
48
+ `Required input '${_.id}' (${_.dataType}) not found for node ${i.label}`
49
+ );
50
+ const f = c.execution;
51
+ if (!f || !f.type)
52
+ throw new Error(`Node ${i.label} has invalid execution configuration`);
53
+ switch (f.type) {
54
+ case "api_call":
55
+ let _ = f.endpoint;
56
+ if (typeof _ == "string" && _.includes("{{") && (_ = E(_, i, d)), !_ && i.type === "http_request_node") {
57
+ const e = (a = c.defaultConfig) == null ? void 0 : a.url;
58
+ e && (_ = e);
59
+ }
60
+ if (!_)
61
+ throw new Error(`Node ${i.label} has api_call type but no endpoint specified. Please configure the URL in the node settings.`);
62
+ i.type === "http_request_node" && console.log("[HTTP Request] Executing:", {
63
+ nodeId: i.id,
64
+ method: (b = i.config) == null ? void 0 : b.method,
65
+ url: (N = i.config) == null ? void 0 : N.url,
66
+ resolvedEndpoint: _,
67
+ config: i.config
68
+ });
69
+ let h = f.method || "POST";
70
+ typeof h == "string" && h.includes("{{") && (h = E(h, i, d)), !h && i.type === "http_request_node" && (h = ((R = c.defaultConfig) == null ? void 0 : R.method) || "GET"), h = (h || "POST").toUpperCase();
71
+ let x;
72
+ if (f.queryParams) {
73
+ const e = E(f.queryParams, i, d);
74
+ if (typeof e == "string")
75
+ try {
76
+ x = JSON.parse(e);
77
+ } catch {
78
+ x = {};
79
+ }
80
+ else typeof e == "object" && (x = e);
81
+ }
82
+ let m = _;
83
+ if (x && Object.keys(x).length > 0)
84
+ if (_.startsWith("http://") || _.startsWith("https://")) {
85
+ const e = new URL(_);
86
+ Object.entries(x).forEach(([p, t]) => {
87
+ e.searchParams.append(p, String(t));
88
+ }), m = e.toString();
89
+ } else {
90
+ const e = Object.entries(x).map(([p, t]) => `${encodeURIComponent(p)}=${encodeURIComponent(String(t))}`).join("&");
91
+ m = `${_}?${e}`;
92
+ }
93
+ let l = {};
94
+ if (f.headers) {
95
+ const e = E(f.headers, i, d);
96
+ if (e && typeof e == "object") {
97
+ const p = e.__send_headers__, t = e.__custom_headers__, n = e.__auth_type__, w = e.__basic_auth_username__, g = e.__basic_auth_password__, S = e.__bearer_token__, y = e.__custom_auth_header_name__, V = e.__custom_auth_header_value__;
98
+ if (delete e.__send_headers__, delete e.__custom_headers__, delete e.__auth_type__, delete e.__basic_auth_username__, delete e.__basic_auth_password__, delete e.__bearer_token__, delete e.__custom_auth_header_name__, delete e.__custom_auth_header_value__, n === "basic" && w && g) {
99
+ const T = `${String(w)}:${String(g)}`, r = btoa(T);
100
+ l.Authorization = `Basic ${r}`;
101
+ } else n === "bearer" && S ? l.Authorization = `Bearer ${String(S)}` : n === "custom" && y && V && (l[String(y)] = String(V));
102
+ if (t && typeof t == "string")
103
+ try {
104
+ const T = JSON.parse(t);
105
+ l = { ...l, ...T };
106
+ } catch {
107
+ }
108
+ else t && typeof t == "object" && (l = { ...l, ...t });
109
+ if (l = Object.fromEntries(
110
+ Object.entries(l).filter(([T, r]) => r !== "" && r !== null && r !== void 0)
111
+ ), p === !1 || p === "false") {
112
+ const T = {};
113
+ l.Authorization && (T.Authorization = l.Authorization), Object.keys(l).forEach((r) => {
114
+ (r.toLowerCase().includes("auth") || r.toLowerCase().includes("token")) && (T[r] = l[r]);
115
+ }), l = T;
116
+ }
117
+ }
118
+ }
119
+ let o;
120
+ if (f.payload) {
121
+ const e = f.payload.__body_json__;
122
+ let p;
123
+ if (typeof e == "string" && e.trim().startsWith("{{") && e.trim().endsWith("}}")) {
124
+ const w = e.trim().match(/^\{\{config\.(.+)\}\}$/);
125
+ w && (p = (q = i.config) == null ? void 0 : q[w[1]]);
126
+ }
127
+ const t = { ...f.payload };
128
+ p !== void 0 && delete t.__body_json__;
129
+ const n = E(t, i, d);
130
+ if (p !== void 0 && (n.__body_json__ = p), n && typeof n == "object") {
131
+ const w = n.__send_body__, g = n.__body_content_type__, S = n.__body_specify__, y = n.__body_json__, V = n.__body_raw__, T = n.__legacy_payload__;
132
+ if (w !== !1 && w !== "false") {
133
+ if (S === "json" && y)
134
+ try {
135
+ if (typeof y == "string") {
136
+ if (!y.trim())
137
+ throw new Error("body_json is empty");
138
+ let r = y;
139
+ r = r.replace(/("([^"]+)":\s*)(\{\{([^}]+)\}\})(\s*[,}])/g, (s, I, ie, re, te, se) => I.endsWith('"') ? s : `${I}"{{${te}}}"${se}`), o = JSON.parse(r);
140
+ } else
141
+ o = y;
142
+ if (o = E(o, i, d), i.type === "rfdiffusion_node" && o && typeof o == "object") {
143
+ if (typeof o.diffusion_steps == "string")
144
+ if (o.diffusion_steps === "")
145
+ o.diffusion_steps = ((k = i.config) == null ? void 0 : k.diffusion_steps) ?? 15;
146
+ else {
147
+ const r = Number(o.diffusion_steps);
148
+ isNaN(r) || (o.diffusion_steps = r);
149
+ }
150
+ if (typeof o.num_designs == "string")
151
+ if (o.num_designs === "")
152
+ o.num_designs = ((P = i.config) == null ? void 0 : P.num_designs) ?? 1;
153
+ else {
154
+ const r = Number(o.num_designs);
155
+ isNaN(r) || (o.num_designs = r);
156
+ }
157
+ if (typeof o.hotspot_res == "string")
158
+ if (o.hotspot_res.trim() === "")
159
+ delete o.hotspot_res;
160
+ else {
161
+ const r = o.hotspot_res.split(",").map((s) => s.trim()).filter((s) => s);
162
+ r.length > 0 ? o.hotspot_res = r : delete o.hotspot_res;
163
+ }
164
+ else if (Array.isArray(o.hotspot_res)) {
165
+ const r = o.hotspot_res.filter((s) => s && String(s).trim());
166
+ r.length > 0 ? o.hotspot_res = r : delete o.hotspot_res;
167
+ }
168
+ if (i.type === "rfdiffusion_node" && o && typeof o == "object") {
169
+ const r = `rf_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, s = { ...o };
170
+ if (delete s.jobId, delete s.sessionId, s.pdb_file && (typeof s.pdb_file == "object" && s.pdb_file.file_id ? (s.uploadId = s.pdb_file.file_id, delete s.pdb_file) : typeof s.pdb_file == "string" && s.pdb_file.trim() && (s.pdb_file.length > 20 || s.pdb_file.includes("/") || (s.uploadId = s.pdb_file, delete s.pdb_file))), d && d.target) {
171
+ const I = d.target;
172
+ I && typeof I == "object" && I.file_id && (s.uploadId = I.file_id, delete s.pdb_file);
173
+ }
174
+ s.uploadId && (!s.pdb_id || s.pdb_id.trim() === "") && (delete s.pdb_id, console.log("[ExecutionEngine] Removed empty pdb_id since uploadId is present:", s.uploadId)), o = {
175
+ parameters: s,
176
+ jobId: r
177
+ }, u.sessionId ? (o.sessionId = u.sessionId, console.log("[ExecutionEngine] Transformed RFdiffusion payload with jobId:", r, "sessionId:", u.sessionId, "parameters:", Object.keys(s))) : console.log("[ExecutionEngine] Transformed RFdiffusion payload with jobId:", r, "(no sessionId)", "parameters:", Object.keys(s));
178
+ } else if (i.type === "rfdiffusion_node") {
179
+ const r = `rf_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
180
+ o = {
181
+ parameters: o || {},
182
+ jobId: r
183
+ }, u.sessionId && (o.sessionId = u.sessionId);
184
+ }
185
+ }
186
+ } catch (r) {
187
+ const s = r instanceof Error ? r.message : String(r), I = typeof y == "string" ? y.length > 200 ? y.substring(0, 200) + "..." : y : "Not a string";
188
+ throw new Error(`Invalid JSON body: ${s}. JSON preview: ${I}`);
189
+ }
190
+ else if (S === "expression" && y)
191
+ try {
192
+ if (typeof y == "string" ? o = JSON.parse(y) : o = y, o = E(o, i, d), i.type === "rfdiffusion_node" && o && typeof o == "object") {
193
+ const r = `rf_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, s = { ...o };
194
+ delete s.jobId, delete s.sessionId, s.pdb_file && typeof s.pdb_file == "object" && s.pdb_file.file_id && (s.uploadId = s.pdb_file.file_id, delete s.pdb_file), d && d.target && typeof d.target == "object" && d.target.file_id && (s.uploadId = d.target.file_id, delete s.pdb_file), s.uploadId && (!s.pdb_id || s.pdb_id.trim() === "") && delete s.pdb_id, o = {
195
+ parameters: s,
196
+ jobId: r
197
+ }, u.sessionId && (o.sessionId = u.sessionId, console.log("[ExecutionEngine] Transformed RFdiffusion payload (expression) with jobId:", r));
198
+ }
199
+ } catch {
200
+ o = y, typeof o == "string" && (o = E(o, i, d));
201
+ }
202
+ else if (V && (g === "raw" || g === "text" || g === "xml"))
203
+ o = String(V);
204
+ else if (T && (o = T, o = E(o, i, d), i.type === "rfdiffusion_node" && o && typeof o == "object")) {
205
+ const r = `rf_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, s = { ...o };
206
+ delete s.jobId, delete s.sessionId, s.pdb_file && typeof s.pdb_file == "object" && s.pdb_file.file_id && (s.uploadId = s.pdb_file.file_id, delete s.pdb_file), d && d.target && typeof d.target == "object" && d.target.file_id && (s.uploadId = d.target.file_id, delete s.pdb_file), s.uploadId && (!s.pdb_id || s.pdb_id.trim() === "") && delete s.pdb_id, o = {
207
+ parameters: s,
208
+ jobId: r
209
+ }, u.sessionId && (o.sessionId = u.sessionId, console.log("[ExecutionEngine] Transformed RFdiffusion payload (legacy) with jobId:", r));
210
+ }
211
+ g === "json" && !l["Content-Type"] ? l["Content-Type"] = "application/json" : g === "form-data" && !l["Content-Type"] ? l["Content-Type"] = "multipart/form-data" : g === "x-www-form-urlencoded" && !l["Content-Type"] ? l["Content-Type"] = "application/x-www-form-urlencoded" : g === "text" && !l["Content-Type"] ? l["Content-Type"] = "text/plain" : g === "xml" && !l["Content-Type"] ? l["Content-Type"] = "application/xml" : g === "raw" && !l["Content-Type"] && (l["Content-Type"] = "text/plain");
212
+ }
213
+ } else
214
+ o = n;
215
+ }
216
+ const K = Object.keys(l).length > 0 ? { headers: l } : void 0, Y = {
217
+ method: h,
218
+ url: m,
219
+ headers: l,
220
+ queryParams: x,
221
+ body: o
222
+ };
223
+ let j, C = 200, O = "OK", B = {};
224
+ try {
225
+ if (m.startsWith("http://") || m.startsWith("https://")) {
226
+ const t = {
227
+ method: h,
228
+ headers: l
229
+ };
230
+ ["POST", "PUT", "PATCH"].includes(h) && o !== void 0 && (typeof o == "string" ? t.body = o : (t.body = JSON.stringify(o), !l["Content-Type"] && !l["content-type"] && (l["Content-Type"] = "application/json", t.headers = l)));
231
+ const n = await fetch(m, t);
232
+ C = n.status, O = n.statusText, n.headers.forEach((g, S) => {
233
+ B[S] = g;
234
+ });
235
+ const w = n.headers.get("content-type");
236
+ if (w && w.includes("application/json"))
237
+ j = await n.json();
238
+ else {
239
+ const g = await n.text();
240
+ try {
241
+ j = JSON.parse(g);
242
+ } catch {
243
+ j = g;
244
+ }
245
+ }
246
+ if (!n.ok)
247
+ throw new Error(`HTTP ${C}: ${O}`);
248
+ } else
249
+ try {
250
+ console.log("[ExecutionEngine] Making API call:", { method: h, url: m, hasPayload: !!o });
251
+ let t;
252
+ switch (h) {
253
+ case "GET":
254
+ t = await u.apiClient.get(m, K);
255
+ break;
256
+ case "POST":
257
+ t = await u.apiClient.post(m, o, K);
258
+ break;
259
+ case "PUT":
260
+ t = await u.apiClient.post(m, o, { ...K, method: "PUT" });
261
+ break;
262
+ case "PATCH":
263
+ t = await u.apiClient.post(m, o, { ...K, method: "PATCH" });
264
+ break;
265
+ case "DELETE":
266
+ t = await u.apiClient.get(m, K);
267
+ break;
268
+ default:
269
+ throw new Error(`Unsupported HTTP method: ${h}`);
270
+ }
271
+ console.log("[ExecutionEngine] API response received:", {
272
+ hasResponse: !!t,
273
+ responseType: typeof t,
274
+ hasData: t && typeof t == "object" && "data" in t,
275
+ keys: t && typeof t == "object" ? Object.keys(t) : []
276
+ }), t && typeof t == "object" && "data" in t ? (j = t.data, "status" in t && (C = t.status), "statusText" in t && (O = t.statusText), "headers" in t && t.headers && (B = t.headers)) : j = t;
277
+ } catch (t) {
278
+ if (console.error("[ExecutionEngine] Axios error:", {
279
+ message: t.message,
280
+ code: t.code,
281
+ hasResponse: !!t.response,
282
+ hasRequest: !!t.request,
283
+ responseStatus: (v = t.response) == null ? void 0 : v.status,
284
+ responseData: (D = t.response) == null ? void 0 : D.data,
285
+ url: m,
286
+ method: h
287
+ }), t.response) {
288
+ C = t.response.status, O = t.response.statusText || "Error", B = t.response.headers || {}, j = t.response.data;
289
+ const n = new Error(`HTTP ${C}: ${O}`);
290
+ throw n.response = t.response, n;
291
+ } else if (t.request) {
292
+ const n = new Error(`Network Error: ${t.message || "No response from server. Please check your connection and try again."}`);
293
+ throw n.code = t.code || "NETWORK_ERROR", n.request = t.request, n;
294
+ } else
295
+ throw new Error(`Request Error: ${t.message || "Failed to make request"}`);
296
+ }
297
+ return {
298
+ data: j,
299
+ request: Y,
300
+ response: {
301
+ status: C,
302
+ statusText: O,
303
+ headers: B,
304
+ data: j
305
+ }
306
+ };
307
+ } catch (e) {
308
+ const p = ((A = e.message) == null ? void 0 : A.includes("Network Error")) || e.code === "NETWORK_ERROR" || e.code === "ERR_NETWORK", t = e.response && typeof e.response == "object", n = {
309
+ status: t ? e.response.status : p ? 0 : C || 500,
310
+ statusText: t ? e.response.statusText : p ? "Network Error" : O || "Error",
311
+ headers: t ? e.response.headers : B,
312
+ data: t ? e.response.data : p ? { error: e.message, status: "error" } : e.message
313
+ };
314
+ throw e.request = Y, e.response = n, e;
315
+ }
316
+ case "file_check":
317
+ const G = (U = i.config) == null ? void 0 : U.filename;
318
+ if (!G)
319
+ throw new Error("No filename specified for input node");
320
+ const Z = {
321
+ type: "pdb_file",
322
+ filename: G,
323
+ file_id: (H = i.config) == null ? void 0 : H.file_id,
324
+ file_url: (J = i.config) == null ? void 0 : J.file_url,
325
+ chains: (M = i.config) == null ? void 0 : M.chains,
326
+ total_residues: (W = i.config) == null ? void 0 : W.total_residues,
327
+ suggested_contigs: (F = i.config) == null ? void 0 : F.suggested_contigs,
328
+ chain_residue_counts: (L = i.config) == null ? void 0 : L.chain_residue_counts,
329
+ atoms: (z = i.config) == null ? void 0 : z.atoms
330
+ };
331
+ return {
332
+ data: Z,
333
+ request: {
334
+ type: "file_check",
335
+ filename: G
336
+ },
337
+ response: {
338
+ status: 200,
339
+ statusText: "OK",
340
+ data: Z
341
+ }
342
+ };
343
+ case "log":
344
+ try {
345
+ let e = f.message;
346
+ return typeof e == "string" && e.includes("{{") && (e = E(e, i, d)), e == null && (e = (($ = i.config) == null ? void 0 : $.message) || ""), console.log(`[Message Input Node: ${i.label}]`, e), {
347
+ data: {
348
+ message: e || "",
349
+ loggedAt: (/* @__PURE__ */ new Date()).toISOString()
350
+ },
351
+ request: {
352
+ type: "log",
353
+ message: e || ""
354
+ },
355
+ response: {
356
+ status: 200,
357
+ statusText: "Logged",
358
+ data: { message: e || "" }
359
+ }
360
+ };
361
+ } catch (e) {
362
+ throw console.error("[Message Input Node Error]", e), new Error(`Failed to log message: ${e.message || "Unknown error"}`);
363
+ }
364
+ case "code_execution":
365
+ try {
366
+ let e = f.code;
367
+ if (typeof e == "string" && e.includes("{{") && (e = E(e, i, d)), (!e || e.trim() === "") && (e = ((X = i.config) == null ? void 0 : X.code) || ""), !e || e.trim() === "")
368
+ throw new Error("No code provided for code execution node");
369
+ const p = {
370
+ input: d,
371
+ config: i.config || {},
372
+ node: {
373
+ id: i.id,
374
+ type: i.type,
375
+ label: i.label,
376
+ status: i.status
377
+ },
378
+ // Provide console for logging
379
+ console: {
380
+ log: (...n) => {
381
+ console.log(`[Code Execution: ${i.label}]`, ...n);
382
+ },
383
+ error: (...n) => {
384
+ console.error(`[Code Execution: ${i.label}]`, ...n);
385
+ },
386
+ warn: (...n) => {
387
+ console.warn(`[Code Execution: ${i.label}]`, ...n);
388
+ }
389
+ },
390
+ // Provide Date for timestamps
391
+ Date,
392
+ // Provide JSON for serialization
393
+ JSON
394
+ };
395
+ let t;
396
+ try {
397
+ t = new Function(
398
+ "input",
399
+ "config",
400
+ "node",
401
+ "console",
402
+ "Date",
403
+ "JSON",
404
+ `
405
+ ${e}
406
+ `
407
+ )(
408
+ p.input,
409
+ p.config,
410
+ p.node,
411
+ p.console,
412
+ p.Date,
413
+ p.JSON
414
+ ), t === void 0 && (t = { executed: !0, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
415
+ } catch (n) {
416
+ throw console.error(`[Code Execution Error in ${i.label}]`, n), new Error(`Code execution failed: ${n.message || "Unknown error"}`);
417
+ }
418
+ return {
419
+ data: t,
420
+ request: {
421
+ type: "code_execution",
422
+ code: e.substring(0, 200) + (e.length > 200 ? "..." : "")
423
+ // Truncate for logging
424
+ },
425
+ response: {
426
+ status: 200,
427
+ statusText: "Executed",
428
+ data: t
429
+ }
430
+ };
431
+ } catch (e) {
432
+ throw console.error("[Code Execution Node Error]", e), new Error(`Failed to execute code: ${e.message || "Unknown error"}`);
433
+ }
434
+ default:
435
+ throw new Error(`Unknown execution type: ${f.type}`);
436
+ }
437
+ }
438
+ async function le(i, u) {
439
+ var d;
440
+ const c = [];
441
+ try {
442
+ const f = await Q(i.type), a = await ee(i, f, u);
443
+ for (const b of f.handles.inputs)
444
+ !a[b.id] && b.dataType && c.push(
445
+ `Missing required input '${b.id}' (${b.dataType})`
446
+ );
447
+ for (const [b, N] of Object.entries(f.schema))
448
+ N.required && !((d = i.config) != null && d[b]) && c.push(`Missing required config field: ${b}`);
449
+ } catch (f) {
450
+ c.push(f.message || "Validation failed");
451
+ }
452
+ return {
453
+ valid: c.length === 0,
454
+ errors: c
455
+ };
456
+ }
457
+ export {
458
+ de as executeNode,
459
+ le as validateNodeExecution
460
+ };
461
+ //# sourceMappingURL=executionEngine.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executionEngine.mjs","sources":["../../utils/executionEngine.ts"],"sourcesContent":["import { PipelineNode, Pipeline } from '../types/index';\nimport { loadNodeConfig, NodeDefinition, HandleDefinition } from './nodeLoader';\nimport { resolveTemplates } from './templateResolver';\n\ninterface ApiClient {\n post: (endpoint: string, data: any, config?: { headers?: Record<string, string> }) => Promise<any>;\n get: (endpoint: string, config?: { headers?: Record<string, string> }) => Promise<any>;\n}\n\ninterface ExecutionContext {\n pipeline: Pipeline;\n apiClient: ApiClient;\n sessionId?: string | null;\n}\n\n/**\n * Gets input data from connected source nodes based on handle dataType\n */\nasync function getInputData(\n nodeId: string,\n _handleId: string,\n handle: HandleDefinition,\n pipeline: Pipeline\n): Promise<any> {\n const incomingEdges = pipeline.edges.filter((e) => e.target === nodeId);\n if (incomingEdges.length === 0) {\n return null;\n }\n\n // Find the source node\n const sourceNode = pipeline.nodes.find((n) => n.id === incomingEdges[0].source);\n if (!sourceNode) {\n return null;\n }\n\n // Get the output handle from source node that matches the dataType\n const config = await loadNodeConfig(sourceNode.type);\n \n // Find matching output handle by dataType\n const matchingOutput = config.handles.outputs.find(\n (output) => output.dataType === handle.dataType\n );\n\n if (!matchingOutput && handle.dataType) {\n // If no exact match, try to find any output with matching dataType\n // This allows flexibility in connections\n }\n\n // Extract data based on node type and dataType\n if (sourceNode.type === 'input_node') {\n if (handle.dataType === 'pdb_file' || !handle.dataType) {\n // Return full file metadata from result_metadata if available, otherwise from config\n if (sourceNode.result_metadata?.file_info) {\n return sourceNode.result_metadata.file_info;\n } else if (sourceNode.result_metadata?.data) {\n return sourceNode.result_metadata.data;\n } else {\n // Fallback to config data\n return {\n type: 'pdb_file',\n filename: sourceNode.config?.filename,\n file_id: sourceNode.config?.file_id,\n file_url: sourceNode.config?.file_url,\n chains: sourceNode.config?.chains,\n total_residues: sourceNode.config?.total_residues,\n suggested_contigs: sourceNode.config?.suggested_contigs,\n chain_residue_counts: sourceNode.config?.chain_residue_counts,\n atoms: sourceNode.config?.atoms,\n };\n }\n }\n }\n\n if (sourceNode.type === 'message_input_node') {\n // For code execution nodes, return the full result metadata\n if (handle.dataType === 'any' || !handle.dataType) {\n return sourceNode.result_metadata || null;\n }\n if (handle.dataType === 'message') {\n return sourceNode.result_metadata?.message || sourceNode.config?.message || null;\n }\n }\n\n // For nodes that produce output files\n if (sourceNode.result_metadata?.output_file) {\n if (handle.dataType === 'pdb_file') {\n return sourceNode.result_metadata.output_file;\n }\n }\n\n // For sequence outputs\n if (sourceNode.result_metadata?.sequence) {\n if (handle.dataType === 'sequence') {\n return sourceNode.result_metadata.sequence;\n }\n }\n\n // For message outputs\n if (sourceNode.result_metadata?.message) {\n if (handle.dataType === 'message') {\n return sourceNode.result_metadata.message;\n }\n }\n\n // For code execution results (any data type)\n if (sourceNode.result_metadata && handle.dataType === 'any') {\n // Return the entire result metadata for 'any' type\n return sourceNode.result_metadata;\n }\n\n // Fallback: try to get from result_metadata (for backwards compatibility)\n if (sourceNode.result_metadata) {\n // Try common keys\n return (\n sourceNode.result_metadata.output_file ||\n sourceNode.result_metadata.sequence ||\n sourceNode.result_metadata.message ||\n sourceNode.result_metadata.data ||\n // For code execution, return the full result\n (Object.keys(sourceNode.result_metadata).length > 0 ? sourceNode.result_metadata : null) ||\n null\n );\n }\n\n return null;\n}\n\n/**\n * Gets all input data for a node based on its input handles\n */\nasync function getAllInputData(\n node: PipelineNode,\n nodeDefinition: NodeDefinition,\n pipeline: Pipeline\n): Promise<Record<string, any>> {\n const inputData: Record<string, any> = {};\n\n for (const inputHandle of nodeDefinition.handles.inputs) {\n const data = await getInputData(node.id, inputHandle.id, inputHandle, pipeline);\n if (data !== null) {\n inputData[inputHandle.id] = data;\n }\n }\n\n return inputData;\n}\n\n/**\n * Executes a node based on its execution configuration\n */\nexport async function executeNode(\n node: PipelineNode,\n context: ExecutionContext\n): Promise<any> {\n // Load node configuration\n const nodeDefinition = await loadNodeConfig(node.type);\n\n // Get all input data from connected nodes\n const inputData = await getAllInputData(node, nodeDefinition, context.pipeline);\n\n // Validate required inputs\n // Note: HTTP Request nodes can work without inputs (they're optional)\n // Only validate if the node explicitly requires inputs\n for (const inputHandle of nodeDefinition.handles.inputs) {\n // Skip validation for HTTP Request nodes - inputs are optional\n if (node.type === 'http_request_node') {\n continue;\n }\n if (!inputData[inputHandle.id] && inputHandle.dataType) {\n throw new Error(\n `Required input '${inputHandle.id}' (${inputHandle.dataType}) not found for node ${node.label}`\n );\n }\n }\n\n const executionConfig = nodeDefinition.execution;\n\n // Validate execution config exists\n if (!executionConfig || !executionConfig.type) {\n throw new Error(`Node ${node.label} has invalid execution configuration`);\n }\n\n // Execute based on execution type\n switch (executionConfig.type) {\n case 'api_call':\n // Resolve endpoint URL (can be template variable)\n let endpoint = executionConfig.endpoint;\n if (typeof endpoint === 'string' && endpoint.includes('{{')) {\n endpoint = resolveTemplates(endpoint, node, inputData) as string;\n }\n \n // Fallback to defaultConfig if endpoint is empty (for HTTP Request nodes)\n if (!endpoint && node.type === 'http_request_node') {\n const defaultUrl = nodeDefinition.defaultConfig?.url;\n if (defaultUrl) {\n endpoint = defaultUrl;\n }\n }\n \n if (!endpoint) {\n throw new Error(`Node ${node.label} has api_call type but no endpoint specified. Please configure the URL in the node settings.`);\n }\n \n // Debug logging for HTTP Request nodes\n if (node.type === 'http_request_node') {\n console.log('[HTTP Request] Executing:', {\n nodeId: node.id,\n method: node.config?.method,\n url: node.config?.url,\n resolvedEndpoint: endpoint,\n config: node.config\n });\n }\n\n // Resolve HTTP method (can be template variable, defaults to POST)\n let method = executionConfig.method || 'POST';\n if (typeof method === 'string' && method.includes('{{')) {\n method = resolveTemplates(method, node, inputData) as string;\n }\n \n // Fallback to defaultConfig if method is empty (for HTTP Request nodes)\n if (!method && node.type === 'http_request_node') {\n method = nodeDefinition.defaultConfig?.method || 'GET';\n }\n \n method = (method || 'POST').toUpperCase();\n\n // Resolve query parameters (if send_query_params is enabled)\n let queryParams: Record<string, any> | undefined;\n if (executionConfig.queryParams) {\n const queryParamsResolved = resolveTemplates(executionConfig.queryParams, node, inputData);\n if (typeof queryParamsResolved === 'string') {\n try {\n queryParams = JSON.parse(queryParamsResolved);\n } catch {\n // If not valid JSON, treat as empty\n queryParams = {};\n }\n } else if (typeof queryParamsResolved === 'object') {\n queryParams = queryParamsResolved;\n }\n }\n\n // Build URL with query parameters\n let finalUrl = endpoint;\n if (queryParams && Object.keys(queryParams).length > 0) {\n if (endpoint.startsWith('http://') || endpoint.startsWith('https://')) {\n // Absolute URL\n const urlObj = new URL(endpoint);\n Object.entries(queryParams).forEach(([key, value]) => {\n urlObj.searchParams.append(key, String(value));\n });\n finalUrl = urlObj.toString();\n } else {\n // Relative URL - build query string manually\n const queryString = Object.entries(queryParams)\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)\n .join('&');\n finalUrl = `${endpoint}?${queryString}`;\n }\n }\n\n // Resolve template variables in headers (if provided)\n let resolvedHeaders: Record<string, string> = {};\n if (executionConfig.headers) {\n const headersResolved = resolveTemplates(executionConfig.headers, node, inputData);\n \n // Handle special __custom_headers__ and __send_headers__ flags\n if (headersResolved && typeof headersResolved === 'object') {\n const sendHeaders = headersResolved['__send_headers__'];\n const customHeaders = headersResolved['__custom_headers__'];\n const authType = headersResolved['__auth_type__'];\n const basicAuthUsername = headersResolved['__basic_auth_username__'];\n const basicAuthPassword = headersResolved['__basic_auth_password__'];\n const bearerToken = headersResolved['__bearer_token__'];\n const customAuthHeaderName = headersResolved['__custom_auth_header_name__'];\n const customAuthHeaderValue = headersResolved['__custom_auth_header_value__'];\n \n // Remove special flags\n delete headersResolved['__send_headers__'];\n delete headersResolved['__custom_headers__'];\n delete headersResolved['__auth_type__'];\n delete headersResolved['__basic_auth_username__'];\n delete headersResolved['__basic_auth_password__'];\n delete headersResolved['__bearer_token__'];\n delete headersResolved['__custom_auth_header_name__'];\n delete headersResolved['__custom_auth_header_value__'];\n \n // Handle authentication\n if (authType === 'basic' && basicAuthUsername && basicAuthPassword) {\n // Create Basic Auth header\n const credentials = `${String(basicAuthUsername)}:${String(basicAuthPassword)}`;\n const encoded = btoa(credentials);\n resolvedHeaders['Authorization'] = `Basic ${encoded}`;\n } else if (authType === 'bearer' && bearerToken) {\n // Create Bearer token header\n resolvedHeaders['Authorization'] = `Bearer ${String(bearerToken)}`;\n } else if (authType === 'custom' && customAuthHeaderName && customAuthHeaderValue) {\n // Set custom auth header\n resolvedHeaders[String(customAuthHeaderName)] = String(customAuthHeaderValue);\n }\n \n // Merge custom headers if provided\n if (customHeaders && typeof customHeaders === 'string') {\n try {\n const parsedCustom = JSON.parse(customHeaders);\n resolvedHeaders = { ...resolvedHeaders, ...parsedCustom };\n } catch {\n // If parsing fails, keep existing headers\n }\n } else if (customHeaders && typeof customHeaders === 'object') {\n resolvedHeaders = { ...resolvedHeaders, ...customHeaders };\n }\n \n // Filter out empty headers (e.g., empty API keys should not be sent)\n resolvedHeaders = Object.fromEntries(\n Object.entries(resolvedHeaders).filter(([_, value]) => {\n return value !== '' && value !== null && value !== undefined;\n })\n ) as Record<string, string>;\n \n // Only include headers if send_headers is true (but always include auth headers)\n if (sendHeaders === false || sendHeaders === 'false') {\n // Keep only auth headers if send_headers is false\n const authHeaders: Record<string, string> = {};\n if (resolvedHeaders['Authorization']) {\n authHeaders['Authorization'] = resolvedHeaders['Authorization'];\n }\n // Also keep any custom auth headers\n Object.keys(resolvedHeaders).forEach(key => {\n if (key.toLowerCase().includes('auth') || key.toLowerCase().includes('token')) {\n authHeaders[key] = resolvedHeaders[key];\n }\n });\n resolvedHeaders = authHeaders;\n }\n }\n }\n\n // Resolve request body\n let resolvedPayload: any = undefined;\n if (executionConfig.payload) {\n // Extract body_json template BEFORE full resolution to prevent recursive template resolution\n // that could corrupt the JSON string\n const bodyJsonTemplate = executionConfig.payload['__body_json__'];\n let bodyJsonRaw: string | undefined = undefined;\n \n // If body_json is a template variable, extract the config value directly\n if (typeof bodyJsonTemplate === 'string' && bodyJsonTemplate.trim().startsWith('{{') && bodyJsonTemplate.trim().endsWith('}}')) {\n const match = bodyJsonTemplate.trim().match(/^\\{\\{config\\.(.+)\\}\\}$/);\n if (match) {\n // Get the raw JSON string from config without template resolution\n bodyJsonRaw = node.config?.[match[1]] as string | undefined;\n }\n }\n \n // Resolve the rest of the payload (but skip __body_json__ to avoid double processing)\n const payloadToResolve = { ...executionConfig.payload };\n if (bodyJsonRaw !== undefined) {\n // Temporarily remove __body_json__ to prevent recursive resolution\n delete payloadToResolve['__body_json__'];\n }\n const payloadResolved = resolveTemplates(payloadToResolve, node, inputData);\n \n // Restore __body_json__ with the raw value\n if (bodyJsonRaw !== undefined) {\n payloadResolved['__body_json__'] = bodyJsonRaw;\n }\n \n // Handle special body flags\n if (payloadResolved && typeof payloadResolved === 'object') {\n const sendBody = payloadResolved['__send_body__'];\n const bodyContentType = payloadResolved['__body_content_type__'];\n const bodySpecify = payloadResolved['__body_specify__'];\n const bodyJson = payloadResolved['__body_json__'];\n const bodyRaw = payloadResolved['__body_raw__'];\n const legacyPayload = payloadResolved['__legacy_payload__'];\n \n // Only process body if send_body is true\n if (sendBody !== false && sendBody !== 'false') {\n if (bodySpecify === 'json' && bodyJson) {\n // Parse JSON body\n try {\n if (typeof bodyJson === 'string') {\n // Validate JSON string before parsing\n if (!bodyJson.trim()) {\n throw new Error('body_json is empty');\n }\n \n // Fix unquoted template variables in JSON string before parsing\n // Replace patterns like {{config.field}} (unquoted) with \"{{config.field}}\" (quoted)\n // This handles cases where users have old configs with unquoted template variables\n let fixedJson = bodyJson;\n // Match unquoted template variables: \"key\": {{variable}} -> \"key\": \"{{variable}}\"\n // Pattern matches colon, optional whitespace, then {{...}} that's NOT already quoted\n // We detect \"not quoted\" by checking that there's no quote immediately after the colon\n fixedJson = fixedJson.replace(/(\"([^\"]+)\":\\s*)(\\{\\{([^}]+)\\}\\})(\\s*[,}])/g, (match, prefix, _key, _templateVar, content, suffix) => {\n // If prefix ends with a quote, it's already quoted, don't modify\n if (prefix.endsWith('\"')) {\n return match;\n }\n // Otherwise, quote the template variable\n return `${prefix}\"{{${content}}}\"${suffix}`;\n });\n \n // Try to parse the fixed JSON\n resolvedPayload = JSON.parse(fixedJson);\n } else {\n resolvedPayload = bodyJson;\n }\n // CRITICAL: Resolve template variables in the parsed payload\n resolvedPayload = resolveTemplates(resolvedPayload, node, inputData);\n \n // Convert string numbers to actual numbers for numeric fields (RFdiffusion compatibility)\n if (node.type === 'rfdiffusion_node' && resolvedPayload && typeof resolvedPayload === 'object') {\n // Handle diffusion_steps: convert string to number, use default 15 if empty\n if (typeof resolvedPayload.diffusion_steps === 'string') {\n if (resolvedPayload.diffusion_steps === '') {\n resolvedPayload.diffusion_steps = node.config?.diffusion_steps ?? 15;\n } else {\n const steps = Number(resolvedPayload.diffusion_steps);\n if (!isNaN(steps)) resolvedPayload.diffusion_steps = steps;\n }\n }\n // Handle num_designs: convert string to number, use default 1 if empty\n if (typeof resolvedPayload.num_designs === 'string') {\n if (resolvedPayload.num_designs === '') {\n resolvedPayload.num_designs = node.config?.num_designs ?? 1;\n } else {\n const designs = Number(resolvedPayload.num_designs);\n if (!isNaN(designs)) resolvedPayload.num_designs = designs;\n }\n }\n // Handle hotspot_res: convert empty string to empty array, or omit if empty\n if (typeof resolvedPayload.hotspot_res === 'string') {\n if (resolvedPayload.hotspot_res.trim() === '') {\n // Remove empty hotspot_res to avoid API validation errors\n delete resolvedPayload.hotspot_res;\n } else {\n // Parse comma-separated string to array\n const hotspots = resolvedPayload.hotspot_res.split(',').map((h: string) => h.trim()).filter((h: string) => h);\n if (hotspots.length > 0) {\n resolvedPayload.hotspot_res = hotspots;\n } else {\n delete resolvedPayload.hotspot_res;\n }\n }\n } else if (Array.isArray(resolvedPayload.hotspot_res)) {\n // Filter out empty values from array\n const filtered = resolvedPayload.hotspot_res.filter((h: any) => h && String(h).trim());\n if (filtered.length > 0) {\n resolvedPayload.hotspot_res = filtered;\n } else {\n delete resolvedPayload.hotspot_res;\n }\n }\n \n // Transform RFdiffusion payload to match backend API format\n // Backend expects: { parameters: {...}, jobId: \"...\", sessionId: \"...\" }\n if (node.type === 'rfdiffusion_node' && resolvedPayload && typeof resolvedPayload === 'object') {\n // Generate a unique jobId if not already present\n const jobId = `rf_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n \n // Extract parameters (everything except jobId and sessionId)\n const parameters = { ...resolvedPayload };\n delete parameters.jobId;\n delete parameters.sessionId;\n \n // Transform file references: pdb_file can be a file object with file_id\n // Backend expects uploadId (file_id) or pdb_id\n if (parameters.pdb_file) {\n // If pdb_file is an object with file_id, convert to uploadId\n if (typeof parameters.pdb_file === 'object' && parameters.pdb_file.file_id) {\n parameters.uploadId = parameters.pdb_file.file_id;\n delete parameters.pdb_file;\n } else if (typeof parameters.pdb_file === 'string' && parameters.pdb_file.trim()) {\n // If it's a string, it might be a file_id or file path\n // Check if it looks like a file_id (UUID or similar)\n if (parameters.pdb_file.length > 20 || parameters.pdb_file.includes('/')) {\n // Looks like a file path, keep as pdb_file\n } else {\n // Likely a file_id, convert to uploadId\n parameters.uploadId = parameters.pdb_file;\n delete parameters.pdb_file;\n }\n }\n }\n \n // Also check inputData for file references\n if (inputData && inputData.target) {\n const fileData = inputData.target;\n if (fileData && typeof fileData === 'object' && fileData.file_id) {\n // Use file_id as uploadId\n parameters.uploadId = fileData.file_id;\n // Remove pdb_file if it was set incorrectly\n delete parameters.pdb_file;\n }\n }\n \n // If we have an uploadId, remove empty pdb_id to avoid confusion\n // Backend prioritizes uploadId over pdb_id, so empty pdb_id is not needed\n if (parameters.uploadId && (!parameters.pdb_id || parameters.pdb_id.trim() === '')) {\n delete parameters.pdb_id;\n console.log('[ExecutionEngine] Removed empty pdb_id since uploadId is present:', parameters.uploadId);\n }\n \n // Transform to backend format\n resolvedPayload = {\n parameters: parameters,\n jobId: jobId\n };\n \n // Add sessionId if available\n if (context.sessionId) {\n resolvedPayload.sessionId = context.sessionId;\n console.log('[ExecutionEngine] Transformed RFdiffusion payload with jobId:', jobId, 'sessionId:', context.sessionId, 'parameters:', Object.keys(parameters));\n } else {\n console.log('[ExecutionEngine] Transformed RFdiffusion payload with jobId:', jobId, '(no sessionId)', 'parameters:', Object.keys(parameters));\n }\n } else if (node.type === 'rfdiffusion_node') {\n // Fallback: if payload is not an object, create a basic structure\n const jobId = `rf_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n resolvedPayload = {\n parameters: resolvedPayload || {},\n jobId: jobId\n };\n if (context.sessionId) {\n resolvedPayload.sessionId = context.sessionId;\n }\n }\n }\n } catch (e) {\n // Provide more context about the JSON parsing error\n const errorMessage = e instanceof Error ? e.message : String(e);\n const jsonPreview = typeof bodyJson === 'string' \n ? (bodyJson.length > 200 ? bodyJson.substring(0, 200) + '...' : bodyJson)\n : 'Not a string';\n throw new Error(`Invalid JSON body: ${errorMessage}. JSON preview: ${jsonPreview}`);\n }\n } else if (bodySpecify === 'expression' && bodyJson) {\n // Expression-based body (for now, treat as JSON)\n try {\n if (typeof bodyJson === 'string') {\n resolvedPayload = JSON.parse(bodyJson);\n } else {\n resolvedPayload = bodyJson;\n }\n // CRITICAL: Resolve template variables in the parsed payload\n resolvedPayload = resolveTemplates(resolvedPayload, node, inputData);\n \n // Transform RFdiffusion payload to match backend API format (expression mode)\n if (node.type === 'rfdiffusion_node' && resolvedPayload && typeof resolvedPayload === 'object') {\n const jobId = `rf_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n const parameters = { ...resolvedPayload };\n delete parameters.jobId;\n delete parameters.sessionId;\n \n // Transform file references\n if (parameters.pdb_file && typeof parameters.pdb_file === 'object' && parameters.pdb_file.file_id) {\n parameters.uploadId = parameters.pdb_file.file_id;\n delete parameters.pdb_file;\n }\n if (inputData && inputData.target && typeof inputData.target === 'object' && inputData.target.file_id) {\n parameters.uploadId = inputData.target.file_id;\n delete parameters.pdb_file;\n }\n \n // If we have an uploadId, remove empty pdb_id\n if (parameters.uploadId && (!parameters.pdb_id || parameters.pdb_id.trim() === '')) {\n delete parameters.pdb_id;\n }\n \n resolvedPayload = {\n parameters: parameters,\n jobId: jobId\n };\n \n if (context.sessionId) {\n resolvedPayload.sessionId = context.sessionId;\n console.log('[ExecutionEngine] Transformed RFdiffusion payload (expression) with jobId:', jobId);\n }\n }\n } catch (e) {\n resolvedPayload = bodyJson; // Fallback to raw string\n // Even for raw string, try to resolve templates if it's a string\n if (typeof resolvedPayload === 'string') {\n resolvedPayload = resolveTemplates(resolvedPayload, node, inputData);\n }\n }\n } else if (bodyRaw && (bodyContentType === 'raw' || bodyContentType === 'text' || bodyContentType === 'xml')) {\n // Raw body content (text, XML, or raw)\n resolvedPayload = String(bodyRaw);\n } else if (legacyPayload) {\n // Use legacy payload structure\n resolvedPayload = legacyPayload;\n // CRITICAL: Resolve template variables in legacy payload\n resolvedPayload = resolveTemplates(resolvedPayload, node, inputData);\n \n // Transform RFdiffusion payload to match backend API format (legacy mode)\n if (node.type === 'rfdiffusion_node' && resolvedPayload && typeof resolvedPayload === 'object') {\n const jobId = `rf_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n const parameters = { ...resolvedPayload };\n delete parameters.jobId;\n delete parameters.sessionId;\n \n // Transform file references\n if (parameters.pdb_file && typeof parameters.pdb_file === 'object' && parameters.pdb_file.file_id) {\n parameters.uploadId = parameters.pdb_file.file_id;\n delete parameters.pdb_file;\n }\n if (inputData && inputData.target && typeof inputData.target === 'object' && inputData.target.file_id) {\n parameters.uploadId = inputData.target.file_id;\n delete parameters.pdb_file;\n }\n \n // If we have an uploadId, remove empty pdb_id\n if (parameters.uploadId && (!parameters.pdb_id || parameters.pdb_id.trim() === '')) {\n delete parameters.pdb_id;\n }\n \n resolvedPayload = {\n parameters: parameters,\n jobId: jobId\n };\n \n if (context.sessionId) {\n resolvedPayload.sessionId = context.sessionId;\n console.log('[ExecutionEngine] Transformed RFdiffusion payload (legacy) with jobId:', jobId);\n }\n }\n }\n \n // Set Content-Type header based on body_content_type\n if (bodyContentType === 'json' && !resolvedHeaders['Content-Type']) {\n resolvedHeaders['Content-Type'] = 'application/json';\n } else if (bodyContentType === 'form-data' && !resolvedHeaders['Content-Type']) {\n resolvedHeaders['Content-Type'] = 'multipart/form-data';\n } else if (bodyContentType === 'x-www-form-urlencoded' && !resolvedHeaders['Content-Type']) {\n resolvedHeaders['Content-Type'] = 'application/x-www-form-urlencoded';\n } else if (bodyContentType === 'text' && !resolvedHeaders['Content-Type']) {\n resolvedHeaders['Content-Type'] = 'text/plain';\n } else if (bodyContentType === 'xml' && !resolvedHeaders['Content-Type']) {\n resolvedHeaders['Content-Type'] = 'application/xml';\n } else if (bodyContentType === 'raw' && !resolvedHeaders['Content-Type']) {\n resolvedHeaders['Content-Type'] = 'text/plain';\n }\n }\n } else {\n // Fallback: use payload as-is if no special flags\n resolvedPayload = payloadResolved;\n }\n }\n\n // Make API call with optional headers\n const requestConfig = Object.keys(resolvedHeaders).length > 0 \n ? { headers: resolvedHeaders } \n : undefined;\n \n // Capture request details for logging\n const requestDetails = {\n method,\n url: finalUrl,\n headers: resolvedHeaders,\n queryParams: queryParams,\n body: resolvedPayload,\n };\n\n // Execute based on HTTP method and capture response\n let responseData: any;\n let responseStatus: number = 200;\n let responseStatusText: string = 'OK';\n let responseHeaders: Record<string, string> = {};\n \n try {\n // Check if this is an external URL (starts with http:// or https://)\n const isExternalUrl = finalUrl.startsWith('http://') || finalUrl.startsWith('https://');\n \n if (isExternalUrl) {\n // For external URLs, use fetch API\n const fetchOptions: RequestInit = {\n method,\n headers: resolvedHeaders,\n };\n \n // Add body for methods that support it\n if (['POST', 'PUT', 'PATCH'].includes(method) && resolvedPayload !== undefined) {\n if (typeof resolvedPayload === 'string') {\n fetchOptions.body = resolvedPayload;\n } else {\n fetchOptions.body = JSON.stringify(resolvedPayload);\n // Set Content-Type if not already set\n if (!resolvedHeaders['Content-Type'] && !resolvedHeaders['content-type']) {\n resolvedHeaders['Content-Type'] = 'application/json';\n fetchOptions.headers = resolvedHeaders;\n }\n }\n }\n \n const response = await fetch(finalUrl, fetchOptions);\n responseStatus = response.status;\n responseStatusText = response.statusText;\n \n // Extract response headers\n response.headers.forEach((value, key) => {\n responseHeaders[key] = value;\n });\n \n // Parse response body\n const contentType = response.headers.get('content-type');\n if (contentType && contentType.includes('application/json')) {\n responseData = await response.json();\n } else {\n const text = await response.text();\n try {\n // Try to parse as JSON even if content-type doesn't say so\n responseData = JSON.parse(text);\n } catch {\n // If not JSON, return as text\n responseData = text;\n }\n }\n \n // Throw error for non-2xx status codes\n if (!response.ok) {\n throw new Error(`HTTP ${responseStatus}: ${responseStatusText}`);\n }\n } else {\n // For internal API calls, use the apiClient\n try {\n console.log('[ExecutionEngine] Making API call:', { method, url: finalUrl, hasPayload: !!resolvedPayload });\n let axiosResponse: any;\n switch (method) {\n case 'GET':\n axiosResponse = await context.apiClient.get(finalUrl, requestConfig);\n break;\n case 'POST':\n axiosResponse = await context.apiClient.post(finalUrl, resolvedPayload, requestConfig);\n break;\n case 'PUT':\n axiosResponse = await context.apiClient.post(finalUrl, resolvedPayload, { ...requestConfig, method: 'PUT' } as any);\n break;\n case 'PATCH':\n axiosResponse = await context.apiClient.post(finalUrl, resolvedPayload, { ...requestConfig, method: 'PATCH' } as any);\n break;\n case 'DELETE':\n axiosResponse = await context.apiClient.get(finalUrl, requestConfig);\n break;\n default:\n throw new Error(`Unsupported HTTP method: ${method}`);\n }\n \n console.log('[ExecutionEngine] API response received:', { \n hasResponse: !!axiosResponse, \n responseType: typeof axiosResponse,\n hasData: axiosResponse && typeof axiosResponse === 'object' && 'data' in axiosResponse,\n keys: axiosResponse && typeof axiosResponse === 'object' ? Object.keys(axiosResponse) : []\n });\n \n // Axios returns response object with data property\n // Extract data and response metadata\n if (axiosResponse && typeof axiosResponse === 'object') {\n if ('data' in axiosResponse) {\n responseData = axiosResponse.data;\n // Also extract status and headers from axios response\n if ('status' in axiosResponse) {\n responseStatus = axiosResponse.status;\n }\n if ('statusText' in axiosResponse) {\n responseStatusText = axiosResponse.statusText;\n }\n if ('headers' in axiosResponse && axiosResponse.headers) {\n responseHeaders = axiosResponse.headers;\n }\n } else {\n // If no data property, use the whole response\n responseData = axiosResponse;\n }\n } else {\n responseData = axiosResponse;\n }\n } catch (axiosError: any) {\n console.error('[ExecutionEngine] Axios error:', {\n message: axiosError.message,\n code: axiosError.code,\n hasResponse: !!axiosError.response,\n hasRequest: !!axiosError.request,\n responseStatus: axiosError.response?.status,\n responseData: axiosError.response?.data,\n url: finalUrl,\n method\n });\n \n // Handle axios-specific errors\n if (axiosError.response) {\n // Server responded with error status\n responseStatus = axiosError.response.status;\n responseStatusText = axiosError.response.statusText || 'Error';\n responseHeaders = axiosError.response.headers || {};\n responseData = axiosError.response.data;\n // Re-throw with proper error structure\n const httpError = new Error(`HTTP ${responseStatus}: ${responseStatusText}`);\n (httpError as any).response = axiosError.response;\n throw httpError;\n } else if (axiosError.request) {\n // Request was made but no response received (network error)\n const networkError = new Error(`Network Error: ${axiosError.message || 'No response from server. Please check your connection and try again.'}`);\n (networkError as any).code = axiosError.code || 'NETWORK_ERROR';\n (networkError as any).request = axiosError.request;\n throw networkError;\n } else {\n // Error setting up the request\n throw new Error(`Request Error: ${axiosError.message || 'Failed to make request'}`);\n }\n }\n }\n\n // Create response details\n const responseDetails = {\n status: responseStatus,\n statusText: responseStatusText,\n headers: responseHeaders,\n data: responseData,\n };\n\n // Return both data and request/response details for logging\n return {\n data: responseData,\n request: requestDetails,\n response: responseDetails,\n };\n } catch (error: any) {\n // Capture error response details\n // Check if it's an axios error with response\n const isNetworkError = error.message?.includes('Network Error') || error.code === 'NETWORK_ERROR' || error.code === 'ERR_NETWORK';\n const hasResponse = error.response && typeof error.response === 'object';\n \n const errorResponse = {\n status: hasResponse ? error.response.status : (isNetworkError ? 0 : responseStatus || 500),\n statusText: hasResponse ? error.response.statusText : (isNetworkError ? 'Network Error' : responseStatusText || 'Error'),\n headers: hasResponse ? error.response.headers : responseHeaders,\n data: hasResponse ? error.response.data : (isNetworkError ? { error: error.message, status: 'error' } : error.message),\n };\n\n // Attach request/response to error for logging\n (error as any).request = requestDetails;\n (error as any).response = errorResponse;\n throw error;\n }\n\n case 'file_check':\n // For input nodes, just validate the file exists\n const filename = node.config?.filename;\n if (!filename) {\n throw new Error('No filename specified for input node');\n }\n // In a real implementation, you might want to verify the file exists\n // For now, we'll just return success with consistent structure\n const fileData = {\n type: 'pdb_file',\n filename: filename,\n file_id: node.config?.file_id,\n file_url: node.config?.file_url,\n chains: node.config?.chains,\n total_residues: node.config?.total_residues,\n suggested_contigs: node.config?.suggested_contigs,\n chain_residue_counts: node.config?.chain_residue_counts,\n atoms: node.config?.atoms,\n };\n return {\n data: fileData,\n request: {\n type: 'file_check',\n filename: filename,\n },\n response: {\n status: 200,\n statusText: 'OK',\n data: fileData,\n },\n };\n\n case 'log':\n // For message input nodes, log the message\n try {\n let message = (executionConfig as any).message;\n \n // If message is a template string, resolve it\n if (typeof message === 'string' && message.includes('{{')) {\n message = resolveTemplates(message, node, inputData) as string;\n }\n \n // Default to empty string if message is undefined or null\n if (message === undefined || message === null) {\n message = node.config?.message || '';\n }\n \n // Log to console for debugging\n console.log(`[Message Input Node: ${node.label}]`, message);\n \n // Return the message as data so it can be passed to connected nodes\n return {\n data: {\n message: message || '',\n loggedAt: new Date().toISOString(),\n },\n request: {\n type: 'log',\n message: message || '',\n },\n response: {\n status: 200,\n statusText: 'Logged',\n data: { message: message || '' },\n },\n };\n } catch (error: any) {\n console.error('[Message Input Node Error]', error);\n throw new Error(`Failed to log message: ${error.message || 'Unknown error'}`);\n }\n\n case 'code_execution':\n // Execute JavaScript code in a controlled environment\n try {\n let code = (executionConfig as any).code;\n \n // If code is a template string, resolve it\n if (typeof code === 'string' && code.includes('{{')) {\n code = resolveTemplates(code, node, inputData) as string;\n }\n \n // Default to empty string if code is undefined or null\n if (!code || code.trim() === '') {\n code = node.config?.code || '';\n }\n \n if (!code || code.trim() === '') {\n throw new Error('No code provided for code execution node');\n }\n \n // Create a controlled execution environment\n // Provide access to input data, config, and node metadata\n const executionContext = {\n input: inputData,\n config: node.config || {},\n node: {\n id: node.id,\n type: node.type,\n label: node.label,\n status: node.status,\n },\n // Provide console for logging\n console: {\n log: (...args: any[]) => {\n console.log(`[Code Execution: ${node.label}]`, ...args);\n },\n error: (...args: any[]) => {\n console.error(`[Code Execution: ${node.label}]`, ...args);\n },\n warn: (...args: any[]) => {\n console.warn(`[Code Execution: ${node.label}]`, ...args);\n },\n },\n // Provide Date for timestamps\n Date: Date,\n // Provide JSON for serialization\n JSON: JSON,\n };\n \n // Execute code in a controlled function\n // Using Function constructor for better isolation than eval\n let result: any;\n try {\n \n const func = new Function(\n 'input',\n 'config',\n 'node',\n 'console',\n 'Date',\n 'JSON',\n `\n ${code}\n `\n );\n \n result = func(\n executionContext.input,\n executionContext.config,\n executionContext.node,\n executionContext.console,\n executionContext.Date,\n executionContext.JSON\n );\n \n // If no return value, use undefined\n if (result === undefined) {\n result = { executed: true, timestamp: new Date().toISOString() };\n }\n } catch (execError: any) {\n console.error(`[Code Execution Error in ${node.label}]`, execError);\n throw new Error(`Code execution failed: ${execError.message || 'Unknown error'}`);\n }\n \n // Return the execution result\n return {\n data: result,\n request: {\n type: 'code_execution',\n code: code.substring(0, 200) + (code.length > 200 ? '...' : ''), // Truncate for logging\n },\n response: {\n status: 200,\n statusText: 'Executed',\n data: result,\n },\n };\n } catch (error: any) {\n console.error('[Code Execution Node Error]', error);\n throw new Error(`Failed to execute code: ${error.message || 'Unknown error'}`);\n }\n\n default:\n throw new Error(`Unknown execution type: ${executionConfig.type}`);\n }\n}\n\n/**\n * Validates that a node can be executed (has required inputs)\n */\nexport async function validateNodeExecution(\n node: PipelineNode,\n pipeline: Pipeline\n): Promise<{ valid: boolean; errors: string[] }> {\n const errors: string[] = [];\n\n try {\n const nodeDefinition = await loadNodeConfig(node.type);\n const inputData = await getAllInputData(node, nodeDefinition, pipeline);\n\n // Check required inputs\n for (const inputHandle of nodeDefinition.handles.inputs) {\n if (!inputData[inputHandle.id] && inputHandle.dataType) {\n errors.push(\n `Missing required input '${inputHandle.id}' (${inputHandle.dataType})`\n );\n }\n }\n\n // Validate config fields marked as required\n for (const [fieldName, fieldSchema] of Object.entries(nodeDefinition.schema)) {\n if (fieldSchema.required && !node.config?.[fieldName]) {\n errors.push(`Missing required config field: ${fieldName}`);\n }\n }\n } catch (error: any) {\n errors.push(error.message || 'Validation failed');\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n\n"],"names":["getInputData","nodeId","_handleId","handle","pipeline","incomingEdges","e","sourceNode","n","loadNodeConfig","output","_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","_n","_o","getAllInputData","node","nodeDefinition","inputData","inputHandle","data","executeNode","context","executionConfig","endpoint","resolveTemplates","defaultUrl","method","queryParams","queryParamsResolved","finalUrl","urlObj","key","value","queryString","resolvedHeaders","headersResolved","sendHeaders","customHeaders","authType","basicAuthUsername","basicAuthPassword","bearerToken","customAuthHeaderName","customAuthHeaderValue","credentials","encoded","parsedCustom","_","authHeaders","resolvedPayload","bodyJsonTemplate","bodyJsonRaw","match","payloadToResolve","payloadResolved","sendBody","bodyContentType","bodySpecify","bodyJson","bodyRaw","legacyPayload","fixedJson","prefix","_key","_templateVar","content","suffix","steps","designs","hotspots","h","filtered","jobId","parameters","fileData","errorMessage","jsonPreview","requestConfig","requestDetails","responseData","responseStatus","responseStatusText","responseHeaders","fetchOptions","response","contentType","text","axiosResponse","axiosError","httpError","networkError","error","isNetworkError","hasResponse","errorResponse","filename","_p","_q","_r","message","_s","code","_t","executionContext","args","result","execError","validateNodeExecution","errors","fieldName","fieldSchema"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export * from './topologicalSort';
2
+ export * from './nodeLoader';
3
+ export * from './templateResolver';
4
+ export * from './executionEngine';
5
+ export * from './logger';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC"}