@nodetool-ai/base-nodes 0.7.0-rc.11

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 (353) hide show
  1. package/dist/index.d.ts +72 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +270 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/lib/audio-wav.d.ts +66 -0
  6. package/dist/lib/audio-wav.d.ts.map +1 -0
  7. package/dist/lib/audio-wav.js +215 -0
  8. package/dist/lib/audio-wav.js.map +1 -0
  9. package/dist/nodes/agents.d.ts +253 -0
  10. package/dist/nodes/agents.d.ts.map +1 -0
  11. package/dist/nodes/agents.js +2784 -0
  12. package/dist/nodes/agents.js.map +1 -0
  13. package/dist/nodes/anthropic.d.ts +26 -0
  14. package/dist/nodes/anthropic.d.ts.map +1 -0
  15. package/dist/nodes/anthropic.js +133 -0
  16. package/dist/nodes/anthropic.js.map +1 -0
  17. package/dist/nodes/apify.d.ts +120 -0
  18. package/dist/nodes/apify.d.ts.map +1 -0
  19. package/dist/nodes/apify.js +618 -0
  20. package/dist/nodes/apify.js.map +1 -0
  21. package/dist/nodes/audio.d.ts +301 -0
  22. package/dist/nodes/audio.d.ts.map +1 -0
  23. package/dist/nodes/audio.js +1274 -0
  24. package/dist/nodes/audio.js.map +1 -0
  25. package/dist/nodes/code-node.d.ts +34 -0
  26. package/dist/nodes/code-node.d.ts.map +1 -0
  27. package/dist/nodes/code-node.js +343 -0
  28. package/dist/nodes/code-node.js.map +1 -0
  29. package/dist/nodes/code.d.ts +301 -0
  30. package/dist/nodes/code.d.ts.map +1 -0
  31. package/dist/nodes/code.js +850 -0
  32. package/dist/nodes/code.js.map +1 -0
  33. package/dist/nodes/compare.d.ts +18 -0
  34. package/dist/nodes/compare.d.ts.map +1 -0
  35. package/dist/nodes/compare.js +122 -0
  36. package/dist/nodes/compare.js.map +1 -0
  37. package/dist/nodes/constant.d.ts +315 -0
  38. package/dist/nodes/constant.d.ts.map +1 -0
  39. package/dist/nodes/constant.js +715 -0
  40. package/dist/nodes/constant.js.map +1 -0
  41. package/dist/nodes/control.d.ts +83 -0
  42. package/dist/nodes/control.d.ts.map +1 -0
  43. package/dist/nodes/control.js +212 -0
  44. package/dist/nodes/control.js.map +1 -0
  45. package/dist/nodes/data.d.ts +369 -0
  46. package/dist/nodes/data.d.ts.map +1 -0
  47. package/dist/nodes/data.js +1590 -0
  48. package/dist/nodes/data.js.map +1 -0
  49. package/dist/nodes/document.d.ts +134 -0
  50. package/dist/nodes/document.d.ts.map +1 -0
  51. package/dist/nodes/document.js +984 -0
  52. package/dist/nodes/document.js.map +1 -0
  53. package/dist/nodes/extended-placeholders.d.ts +6 -0
  54. package/dist/nodes/extended-placeholders.d.ts.map +1 -0
  55. package/dist/nodes/extended-placeholders.js +19 -0
  56. package/dist/nodes/extended-placeholders.js.map +1 -0
  57. package/dist/nodes/gemini.d.ts +109 -0
  58. package/dist/nodes/gemini.d.ts.map +1 -0
  59. package/dist/nodes/gemini.js +861 -0
  60. package/dist/nodes/gemini.js.map +1 -0
  61. package/dist/nodes/generators.d.ts +84 -0
  62. package/dist/nodes/generators.d.ts.map +1 -0
  63. package/dist/nodes/generators.js +937 -0
  64. package/dist/nodes/generators.js.map +1 -0
  65. package/dist/nodes/image.d.ts +232 -0
  66. package/dist/nodes/image.d.ts.map +1 -0
  67. package/dist/nodes/image.js +1395 -0
  68. package/dist/nodes/image.js.map +1 -0
  69. package/dist/nodes/input.d.ts +445 -0
  70. package/dist/nodes/input.d.ts.map +1 -0
  71. package/dist/nodes/input.js +1459 -0
  72. package/dist/nodes/input.js.map +1 -0
  73. package/dist/nodes/kie-dynamic.d.ts +31 -0
  74. package/dist/nodes/kie-dynamic.d.ts.map +1 -0
  75. package/dist/nodes/kie-dynamic.js +270 -0
  76. package/dist/nodes/kie-dynamic.js.map +1 -0
  77. package/dist/nodes/lib-audio-dsp.d.ts +85 -0
  78. package/dist/nodes/lib-audio-dsp.d.ts.map +1 -0
  79. package/dist/nodes/lib-audio-dsp.js +450 -0
  80. package/dist/nodes/lib-audio-dsp.js.map +1 -0
  81. package/dist/nodes/lib-audio-effects.d.ts +116 -0
  82. package/dist/nodes/lib-audio-effects.d.ts.map +1 -0
  83. package/dist/nodes/lib-audio-effects.js +905 -0
  84. package/dist/nodes/lib-audio-effects.js.map +1 -0
  85. package/dist/nodes/lib-browser.d.ts +99 -0
  86. package/dist/nodes/lib-browser.d.ts.map +1 -0
  87. package/dist/nodes/lib-browser.js +692 -0
  88. package/dist/nodes/lib-browser.js.map +1 -0
  89. package/dist/nodes/lib-charts.d.ts +20 -0
  90. package/dist/nodes/lib-charts.d.ts.map +1 -0
  91. package/dist/nodes/lib-charts.js +245 -0
  92. package/dist/nodes/lib-charts.js.map +1 -0
  93. package/dist/nodes/lib-datetime.d.ts +108 -0
  94. package/dist/nodes/lib-datetime.d.ts.map +1 -0
  95. package/dist/nodes/lib-datetime.js +421 -0
  96. package/dist/nodes/lib-datetime.js.map +1 -0
  97. package/dist/nodes/lib-doc-convert.d.ts +19 -0
  98. package/dist/nodes/lib-doc-convert.d.ts.map +1 -0
  99. package/dist/nodes/lib-doc-convert.js +257 -0
  100. package/dist/nodes/lib-doc-convert.js.map +1 -0
  101. package/dist/nodes/lib-doc-transform.d.ts +39 -0
  102. package/dist/nodes/lib-doc-transform.d.ts.map +1 -0
  103. package/dist/nodes/lib-doc-transform.js +335 -0
  104. package/dist/nodes/lib-doc-transform.js.map +1 -0
  105. package/dist/nodes/lib-docx.d.ts +106 -0
  106. package/dist/nodes/lib-docx.d.ts.map +1 -0
  107. package/dist/nodes/lib-docx.js +595 -0
  108. package/dist/nodes/lib-docx.js.map +1 -0
  109. package/dist/nodes/lib-epub.d.ts +55 -0
  110. package/dist/nodes/lib-epub.d.ts.map +1 -0
  111. package/dist/nodes/lib-epub.js +220 -0
  112. package/dist/nodes/lib-epub.js.map +1 -0
  113. package/dist/nodes/lib-excel.d.ts +74 -0
  114. package/dist/nodes/lib-excel.d.ts.map +1 -0
  115. package/dist/nodes/lib-excel.js +448 -0
  116. package/dist/nodes/lib-excel.js.map +1 -0
  117. package/dist/nodes/lib-graphql.d.ts +66 -0
  118. package/dist/nodes/lib-graphql.d.ts.map +1 -0
  119. package/dist/nodes/lib-graphql.js +333 -0
  120. package/dist/nodes/lib-graphql.js.map +1 -0
  121. package/dist/nodes/lib-grid.d.ts +27 -0
  122. package/dist/nodes/lib-grid.d.ts.map +1 -0
  123. package/dist/nodes/lib-grid.js +172 -0
  124. package/dist/nodes/lib-grid.js.map +1 -0
  125. package/dist/nodes/lib-html-parse.d.ts +108 -0
  126. package/dist/nodes/lib-html-parse.d.ts.map +1 -0
  127. package/dist/nodes/lib-html-parse.js +365 -0
  128. package/dist/nodes/lib-html-parse.js.map +1 -0
  129. package/dist/nodes/lib-http.d.ts +98 -0
  130. package/dist/nodes/lib-http.d.ts.map +1 -0
  131. package/dist/nodes/lib-http.js +267 -0
  132. package/dist/nodes/lib-http.js.map +1 -0
  133. package/dist/nodes/lib-image-color-grading.d.ts +3 -0
  134. package/dist/nodes/lib-image-color-grading.d.ts.map +1 -0
  135. package/dist/nodes/lib-image-color-grading.js +1386 -0
  136. package/dist/nodes/lib-image-color-grading.js.map +1 -0
  137. package/dist/nodes/lib-image-draw.d.ts +3 -0
  138. package/dist/nodes/lib-image-draw.d.ts.map +1 -0
  139. package/dist/nodes/lib-image-draw.js +470 -0
  140. package/dist/nodes/lib-image-draw.js.map +1 -0
  141. package/dist/nodes/lib-image-enhance.d.ts +3 -0
  142. package/dist/nodes/lib-image-enhance.d.ts.map +1 -0
  143. package/dist/nodes/lib-image-enhance.js +731 -0
  144. package/dist/nodes/lib-image-enhance.js.map +1 -0
  145. package/dist/nodes/lib-image-filter.d.ts +3 -0
  146. package/dist/nodes/lib-image-filter.d.ts.map +1 -0
  147. package/dist/nodes/lib-image-filter.js +684 -0
  148. package/dist/nodes/lib-image-filter.js.map +1 -0
  149. package/dist/nodes/lib-image-utils.d.ts +24 -0
  150. package/dist/nodes/lib-image-utils.d.ts.map +1 -0
  151. package/dist/nodes/lib-image-utils.js +150 -0
  152. package/dist/nodes/lib-image-utils.js.map +1 -0
  153. package/dist/nodes/lib-mail.d.ts +74 -0
  154. package/dist/nodes/lib-mail.d.ts.map +1 -0
  155. package/dist/nodes/lib-mail.js +452 -0
  156. package/dist/nodes/lib-mail.js.map +1 -0
  157. package/dist/nodes/lib-markdown.d.ts +70 -0
  158. package/dist/nodes/lib-markdown.d.ts.map +1 -0
  159. package/dist/nodes/lib-markdown.js +236 -0
  160. package/dist/nodes/lib-markdown.js.map +1 -0
  161. package/dist/nodes/lib-nlp.d.ts +98 -0
  162. package/dist/nodes/lib-nlp.d.ts.map +1 -0
  163. package/dist/nodes/lib-nlp.js +374 -0
  164. package/dist/nodes/lib-nlp.js.map +1 -0
  165. package/dist/nodes/lib-notion.d.ts +99 -0
  166. package/dist/nodes/lib-notion.d.ts.map +1 -0
  167. package/dist/nodes/lib-notion.js +601 -0
  168. package/dist/nodes/lib-notion.js.map +1 -0
  169. package/dist/nodes/lib-ocr.d.ts +31 -0
  170. package/dist/nodes/lib-ocr.d.ts.map +1 -0
  171. package/dist/nodes/lib-ocr.js +143 -0
  172. package/dist/nodes/lib-ocr.js.map +1 -0
  173. package/dist/nodes/lib-os.d.ts +312 -0
  174. package/dist/nodes/lib-os.d.ts.map +1 -0
  175. package/dist/nodes/lib-os.js +909 -0
  176. package/dist/nodes/lib-os.js.map +1 -0
  177. package/dist/nodes/lib-pdf.d.ts +142 -0
  178. package/dist/nodes/lib-pdf.d.ts.map +1 -0
  179. package/dist/nodes/lib-pdf.js +871 -0
  180. package/dist/nodes/lib-pdf.js.map +1 -0
  181. package/dist/nodes/lib-pptx.d.ts +29 -0
  182. package/dist/nodes/lib-pptx.d.ts.map +1 -0
  183. package/dist/nodes/lib-pptx.js +122 -0
  184. package/dist/nodes/lib-pptx.js.map +1 -0
  185. package/dist/nodes/lib-rss.d.ts +31 -0
  186. package/dist/nodes/lib-rss.d.ts.map +1 -0
  187. package/dist/nodes/lib-rss.js +163 -0
  188. package/dist/nodes/lib-rss.js.map +1 -0
  189. package/dist/nodes/lib-s3.d.ts +112 -0
  190. package/dist/nodes/lib-s3.d.ts.map +1 -0
  191. package/dist/nodes/lib-s3.js +521 -0
  192. package/dist/nodes/lib-s3.js.map +1 -0
  193. package/dist/nodes/lib-secret.d.ts +15 -0
  194. package/dist/nodes/lib-secret.d.ts.map +1 -0
  195. package/dist/nodes/lib-secret.js +42 -0
  196. package/dist/nodes/lib-secret.js.map +1 -0
  197. package/dist/nodes/lib-sqlite.d.ts +102 -0
  198. package/dist/nodes/lib-sqlite.d.ts.map +1 -0
  199. package/dist/nodes/lib-sqlite.js +532 -0
  200. package/dist/nodes/lib-sqlite.js.map +1 -0
  201. package/dist/nodes/lib-supabase.d.ts +86 -0
  202. package/dist/nodes/lib-supabase.d.ts.map +1 -0
  203. package/dist/nodes/lib-supabase.js +425 -0
  204. package/dist/nodes/lib-supabase.js.map +1 -0
  205. package/dist/nodes/lib-svg.d.ts +199 -0
  206. package/dist/nodes/lib-svg.d.ts.map +1 -0
  207. package/dist/nodes/lib-svg.js +1027 -0
  208. package/dist/nodes/lib-svg.js.map +1 -0
  209. package/dist/nodes/lib-tensorflow.d.ts +71 -0
  210. package/dist/nodes/lib-tensorflow.d.ts.map +1 -0
  211. package/dist/nodes/lib-tensorflow.js +351 -0
  212. package/dist/nodes/lib-tensorflow.js.map +1 -0
  213. package/dist/nodes/lib-twilio.d.ts +71 -0
  214. package/dist/nodes/lib-twilio.d.ts.map +1 -0
  215. package/dist/nodes/lib-twilio.js +469 -0
  216. package/dist/nodes/lib-twilio.js.map +1 -0
  217. package/dist/nodes/lib-validate.d.ts +84 -0
  218. package/dist/nodes/lib-validate.d.ts.map +1 -0
  219. package/dist/nodes/lib-validate.js +215 -0
  220. package/dist/nodes/lib-validate.js.map +1 -0
  221. package/dist/nodes/lib-video-download.d.ts +26 -0
  222. package/dist/nodes/lib-video-download.d.ts.map +1 -0
  223. package/dist/nodes/lib-video-download.js +299 -0
  224. package/dist/nodes/lib-video-download.js.map +1 -0
  225. package/dist/nodes/messaging.d.ts +88 -0
  226. package/dist/nodes/messaging.d.ts.map +1 -0
  227. package/dist/nodes/messaging.js +418 -0
  228. package/dist/nodes/messaging.js.map +1 -0
  229. package/dist/nodes/mistral.d.ts +83 -0
  230. package/dist/nodes/mistral.d.ts.map +1 -0
  231. package/dist/nodes/mistral.js +450 -0
  232. package/dist/nodes/mistral.js.map +1 -0
  233. package/dist/nodes/model3d/analysis.d.ts +13 -0
  234. package/dist/nodes/model3d/analysis.d.ts.map +1 -0
  235. package/dist/nodes/model3d/analysis.js +36 -0
  236. package/dist/nodes/model3d/analysis.js.map +1 -0
  237. package/dist/nodes/model3d/base.d.ts +11 -0
  238. package/dist/nodes/model3d/base.d.ts.map +1 -0
  239. package/dist/nodes/model3d/base.js +20 -0
  240. package/dist/nodes/model3d/base.js.map +1 -0
  241. package/dist/nodes/model3d/boolean-ops.d.ts +2 -0
  242. package/dist/nodes/model3d/boolean-ops.d.ts.map +1 -0
  243. package/dist/nodes/model3d/boolean-ops.js +172 -0
  244. package/dist/nodes/model3d/boolean-ops.js.map +1 -0
  245. package/dist/nodes/model3d/cleanup.d.ts +47 -0
  246. package/dist/nodes/model3d/cleanup.d.ts.map +1 -0
  247. package/dist/nodes/model3d/cleanup.js +136 -0
  248. package/dist/nodes/model3d/cleanup.js.map +1 -0
  249. package/dist/nodes/model3d/convert.d.ts +14 -0
  250. package/dist/nodes/model3d/convert.d.ts.map +1 -0
  251. package/dist/nodes/model3d/convert.js +64 -0
  252. package/dist/nodes/model3d/convert.js.map +1 -0
  253. package/dist/nodes/model3d/defaults.d.ts +34 -0
  254. package/dist/nodes/model3d/defaults.d.ts.map +1 -0
  255. package/dist/nodes/model3d/defaults.js +28 -0
  256. package/dist/nodes/model3d/defaults.js.map +1 -0
  257. package/dist/nodes/model3d/document-ops.d.ts +4 -0
  258. package/dist/nodes/model3d/document-ops.d.ts.map +1 -0
  259. package/dist/nodes/model3d/document-ops.js +40 -0
  260. package/dist/nodes/model3d/document-ops.js.map +1 -0
  261. package/dist/nodes/model3d/generation.d.ts +39 -0
  262. package/dist/nodes/model3d/generation.d.ts.map +1 -0
  263. package/dist/nodes/model3d/generation.js +179 -0
  264. package/dist/nodes/model3d/generation.js.map +1 -0
  265. package/dist/nodes/model3d/glb.d.ts +29 -0
  266. package/dist/nodes/model3d/glb.d.ts.map +1 -0
  267. package/dist/nodes/model3d/glb.js +255 -0
  268. package/dist/nodes/model3d/glb.js.map +1 -0
  269. package/dist/nodes/model3d/index.d.ts +20 -0
  270. package/dist/nodes/model3d/index.d.ts.map +1 -0
  271. package/dist/nodes/model3d/index.js +38 -0
  272. package/dist/nodes/model3d/index.js.map +1 -0
  273. package/dist/nodes/model3d/io.d.ts +38 -0
  274. package/dist/nodes/model3d/io.d.ts.map +1 -0
  275. package/dist/nodes/model3d/io.js +162 -0
  276. package/dist/nodes/model3d/io.js.map +1 -0
  277. package/dist/nodes/model3d/mesh-ops.d.ts +40 -0
  278. package/dist/nodes/model3d/mesh-ops.d.ts.map +1 -0
  279. package/dist/nodes/model3d/mesh-ops.js +775 -0
  280. package/dist/nodes/model3d/mesh-ops.js.map +1 -0
  281. package/dist/nodes/model3d/nodes.d.ts +2 -0
  282. package/dist/nodes/model3d/nodes.d.ts.map +1 -0
  283. package/dist/nodes/model3d/nodes.js +2 -0
  284. package/dist/nodes/model3d/nodes.js.map +1 -0
  285. package/dist/nodes/model3d/ops.d.ts +37 -0
  286. package/dist/nodes/model3d/ops.d.ts.map +1 -0
  287. package/dist/nodes/model3d/ops.js +137 -0
  288. package/dist/nodes/model3d/ops.js.map +1 -0
  289. package/dist/nodes/model3d/transforms.d.ts +49 -0
  290. package/dist/nodes/model3d/transforms.d.ts.map +1 -0
  291. package/dist/nodes/model3d/transforms.js +142 -0
  292. package/dist/nodes/model3d/transforms.js.map +1 -0
  293. package/dist/nodes/model3d/types.d.ts +81 -0
  294. package/dist/nodes/model3d/types.d.ts.map +1 -0
  295. package/dist/nodes/model3d/types.js +2 -0
  296. package/dist/nodes/model3d/types.js.map +1 -0
  297. package/dist/nodes/model3d/utils.d.ts +34 -0
  298. package/dist/nodes/model3d/utils.d.ts.map +1 -0
  299. package/dist/nodes/model3d/utils.js +185 -0
  300. package/dist/nodes/model3d/utils.js.map +1 -0
  301. package/dist/nodes/model3d.d.ts +2 -0
  302. package/dist/nodes/model3d.d.ts.map +1 -0
  303. package/dist/nodes/model3d.js +2 -0
  304. package/dist/nodes/model3d.js.map +1 -0
  305. package/dist/nodes/openai.d.ts +172 -0
  306. package/dist/nodes/openai.d.ts.map +1 -0
  307. package/dist/nodes/openai.js +1294 -0
  308. package/dist/nodes/openai.js.map +1 -0
  309. package/dist/nodes/output.d.ts +29 -0
  310. package/dist/nodes/output.d.ts.map +1 -0
  311. package/dist/nodes/output.js +87 -0
  312. package/dist/nodes/output.js.map +1 -0
  313. package/dist/nodes/sandbox.d.ts +67 -0
  314. package/dist/nodes/sandbox.d.ts.map +1 -0
  315. package/dist/nodes/sandbox.js +681 -0
  316. package/dist/nodes/sandbox.js.map +1 -0
  317. package/dist/nodes/search.d.ts +117 -0
  318. package/dist/nodes/search.d.ts.map +1 -0
  319. package/dist/nodes/search.js +607 -0
  320. package/dist/nodes/search.js.map +1 -0
  321. package/dist/nodes/team.d.ts +74 -0
  322. package/dist/nodes/team.d.ts.map +1 -0
  323. package/dist/nodes/team.js +304 -0
  324. package/dist/nodes/team.js.map +1 -0
  325. package/dist/nodes/text-extra.d.ts +633 -0
  326. package/dist/nodes/text-extra.d.ts.map +1 -0
  327. package/dist/nodes/text-extra.js +2226 -0
  328. package/dist/nodes/text-extra.js.map +1 -0
  329. package/dist/nodes/tool-agents.d.ts +334 -0
  330. package/dist/nodes/tool-agents.d.ts.map +1 -0
  331. package/dist/nodes/tool-agents.js +1861 -0
  332. package/dist/nodes/tool-agents.js.map +1 -0
  333. package/dist/nodes/triggers.d.ts +107 -0
  334. package/dist/nodes/triggers.d.ts.map +1 -0
  335. package/dist/nodes/triggers.js +706 -0
  336. package/dist/nodes/triggers.js.map +1 -0
  337. package/dist/nodes/vector.d.ts +168 -0
  338. package/dist/nodes/vector.d.ts.map +1 -0
  339. package/dist/nodes/vector.js +1121 -0
  340. package/dist/nodes/vector.js.map +1 -0
  341. package/dist/nodes/video.d.ts +387 -0
  342. package/dist/nodes/video.d.ts.map +1 -0
  343. package/dist/nodes/video.js +2361 -0
  344. package/dist/nodes/video.js.map +1 -0
  345. package/dist/nodes/workflow.d.ts +24 -0
  346. package/dist/nodes/workflow.d.ts.map +1 -0
  347. package/dist/nodes/workflow.js +146 -0
  348. package/dist/nodes/workflow.js.map +1 -0
  349. package/dist/nodes/workspace.d.ts +203 -0
  350. package/dist/nodes/workspace.d.ts.map +1 -0
  351. package/dist/nodes/workspace.js +795 -0
  352. package/dist/nodes/workspace.js.map +1 -0
  353. package/package.json +103 -0
@@ -0,0 +1,1590 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { BaseNode, prop } from "@nodetool-ai/node-sdk";
8
+ import { promises as fs } from "node:fs";
9
+ import path from "node:path";
10
+ import Papa from "papaparse";
11
+ function asRows(value) {
12
+ if (Array.isArray(value)) {
13
+ return value
14
+ .filter((x) => !!x && typeof x === "object" && !Array.isArray(x))
15
+ .map((x) => ({ ...x }));
16
+ }
17
+ if (value && typeof value === "object") {
18
+ const obj = value;
19
+ if (Array.isArray(obj.rows))
20
+ return asRows(obj.rows);
21
+ if (Array.isArray(obj.data))
22
+ return asRows(obj.data);
23
+ }
24
+ return [];
25
+ }
26
+ function toDataframe(rows) {
27
+ return { rows };
28
+ }
29
+ function parseCsv(csv) {
30
+ if (!csv)
31
+ return [];
32
+ const result = Papa.parse(csv, {
33
+ header: true,
34
+ dynamicTyping: true,
35
+ skipEmptyLines: true,
36
+ transformHeader: (h) => h.trim()
37
+ });
38
+ return (result.data ?? []).filter((row) => !!row && typeof row === "object");
39
+ }
40
+ function toCsv(rows) {
41
+ if (rows.length === 0)
42
+ return "";
43
+ const headers = [...new Set(rows.flatMap((r) => Object.keys(r)))];
44
+ return Papa.unparse(rows, { columns: headers, newline: "\n" });
45
+ }
46
+ function parseConditionExpr(condition) {
47
+ return condition
48
+ .replace(/\band\b/g, "&&")
49
+ .replace(/\bor\b/g, "||")
50
+ .replace(/\bnot\b/g, "!");
51
+ }
52
+ function applyFilter(rows, condition) {
53
+ const trimmed = condition.trim();
54
+ if (!trimmed)
55
+ return rows;
56
+ const expr = parseConditionExpr(trimmed);
57
+ return rows.filter((row) => {
58
+ try {
59
+ const fn = new Function("row", `with (row) { return Boolean(${expr}); }`);
60
+ return Boolean(fn(row));
61
+ }
62
+ catch {
63
+ return false;
64
+ }
65
+ });
66
+ }
67
+ function uniqueRows(rows) {
68
+ const seen = new Set();
69
+ const out = [];
70
+ for (const row of rows) {
71
+ const key = JSON.stringify(row, Object.keys(row).sort());
72
+ if (!seen.has(key)) {
73
+ seen.add(key);
74
+ out.push(row);
75
+ }
76
+ }
77
+ return out;
78
+ }
79
+ function toNumber(value) {
80
+ if (value == null || value === "")
81
+ return NaN;
82
+ const n = typeof value === "number" ? value : Number(value);
83
+ return Number.isFinite(n) ? n : NaN;
84
+ }
85
+ function sum(values) {
86
+ return values.reduce((a, b) => a + b, 0);
87
+ }
88
+ function mean(values) {
89
+ return values.length === 0 ? NaN : sum(values) / values.length;
90
+ }
91
+ function median(values) {
92
+ if (values.length === 0)
93
+ return NaN;
94
+ const sorted = [...values].sort((a, b) => a - b);
95
+ const mid = Math.floor(sorted.length / 2);
96
+ if (sorted.length % 2 === 0)
97
+ return (sorted[mid - 1] + sorted[mid]) / 2;
98
+ return sorted[mid];
99
+ }
100
+ function dateName(name) {
101
+ const now = new Date();
102
+ const pad = (v) => String(v).padStart(2, "0");
103
+ return name
104
+ .replaceAll("%Y", String(now.getFullYear()))
105
+ .replaceAll("%m", pad(now.getMonth() + 1))
106
+ .replaceAll("%d", pad(now.getDate()))
107
+ .replaceAll("%H", pad(now.getHours()))
108
+ .replaceAll("%M", pad(now.getMinutes()))
109
+ .replaceAll("%S", pad(now.getSeconds()));
110
+ }
111
+ export class SchemaNode extends BaseNode {
112
+ static nodeType = "nodetool.data.Schema";
113
+ static title = "Schema";
114
+ static description = "Define a schema for a dataframe.\n schema, dataframe, create";
115
+ static metadataOutputTypes = {
116
+ output: "record_type"
117
+ };
118
+ async process() {
119
+ return { output: this.columns ?? {} };
120
+ }
121
+ }
122
+ __decorate([
123
+ prop({
124
+ type: "record_type",
125
+ default: {
126
+ type: "record_type",
127
+ columns: []
128
+ },
129
+ title: "Columns",
130
+ description: "The columns to use in the dataframe."
131
+ })
132
+ ], SchemaNode.prototype, "columns", void 0);
133
+ export class FilterDataframeNode extends BaseNode {
134
+ static nodeType = "nodetool.data.Filter";
135
+ static title = "Filter";
136
+ static description = "Filter dataframe based on condition.\n filter, query, condition\n\n Example conditions:\n age > 30\n age > 30 and salary < 50000\n name == 'John Doe'\n 100 <= price <= 200\n status in ['Active', 'Pending']\n not (age < 18)\n\n Use cases:\n - Extract subset of data meeting specific criteria\n - Remove outliers or invalid data points\n - Focus analysis on relevant data segments";
137
+ static metadataOutputTypes = {
138
+ output: "dataframe"
139
+ };
140
+ static exposeAsTool = true;
141
+ async process() {
142
+ const rows = asRows(this.df ?? this.df);
143
+ const condition = String(this.condition ?? this.condition ?? "");
144
+ return { output: toDataframe(applyFilter(rows, condition)) };
145
+ }
146
+ }
147
+ __decorate([
148
+ prop({
149
+ type: "dataframe",
150
+ default: {
151
+ type: "dataframe",
152
+ uri: "",
153
+ asset_id: null,
154
+ data: null,
155
+ metadata: null,
156
+ columns: null
157
+ },
158
+ title: "Df",
159
+ description: "The DataFrame to filter."
160
+ })
161
+ ], FilterDataframeNode.prototype, "df", void 0);
162
+ __decorate([
163
+ prop({
164
+ type: "str",
165
+ default: "",
166
+ title: "Condition",
167
+ description: "The filtering condition to be applied to the DataFrame, e.g. column_name > 5."
168
+ })
169
+ ], FilterDataframeNode.prototype, "condition", void 0);
170
+ export class SliceDataframeNode extends BaseNode {
171
+ static nodeType = "nodetool.data.Slice";
172
+ static title = "Slice";
173
+ static description = "Slice a dataframe by rows using start and end indices.\n slice, subset, rows\n\n Use cases:\n - Extract a specific range of rows from a large dataset\n - Create training and testing subsets for machine learning\n - Analyze data in smaller chunks";
174
+ static metadataOutputTypes = {
175
+ output: "dataframe"
176
+ };
177
+ static exposeAsTool = true;
178
+ async process() {
179
+ const rows = asRows(this.dataframe ?? this.dataframe);
180
+ const start = Number(this.start_index ?? this.start_index ?? 0);
181
+ let end = Number(this.end_index ?? this.end_index ?? -1);
182
+ if (end < 0)
183
+ end = rows.length;
184
+ return { output: toDataframe(rows.slice(start, end)) };
185
+ }
186
+ }
187
+ __decorate([
188
+ prop({
189
+ type: "dataframe",
190
+ default: {
191
+ type: "dataframe",
192
+ uri: "",
193
+ asset_id: null,
194
+ data: null,
195
+ metadata: null,
196
+ columns: null
197
+ },
198
+ title: "Dataframe",
199
+ description: "The input dataframe to be sliced."
200
+ })
201
+ ], SliceDataframeNode.prototype, "dataframe", void 0);
202
+ __decorate([
203
+ prop({
204
+ type: "int",
205
+ default: 0,
206
+ title: "Start Index",
207
+ description: "The starting index of the slice (inclusive)."
208
+ })
209
+ ], SliceDataframeNode.prototype, "start_index", void 0);
210
+ __decorate([
211
+ prop({
212
+ type: "int",
213
+ default: -1,
214
+ title: "End Index",
215
+ description: "The ending index of the slice (exclusive). Use -1 for the last row."
216
+ })
217
+ ], SliceDataframeNode.prototype, "end_index", void 0);
218
+ export class SaveDataframeNode extends BaseNode {
219
+ static nodeType = "nodetool.data.SaveDataframe";
220
+ static title = "Save Dataframe";
221
+ static description = "Save dataframe in specified folder.\n csv, folder, save\n\n Use cases:\n - Export processed data for external use\n - Create backups of dataframes";
222
+ static metadataOutputTypes = {
223
+ output: "dataframe"
224
+ };
225
+ static exposeAsTool = true;
226
+ async process() {
227
+ const rows = asRows(this.df ?? this.df);
228
+ const folder = String(this.folder ?? this.folder ?? ".");
229
+ const filename = dateName(String(this.name ?? this.name ?? "output.csv"));
230
+ const full = path.resolve(folder, filename);
231
+ await fs.mkdir(path.dirname(full), { recursive: true });
232
+ await fs.writeFile(full, toCsv(rows), "utf8");
233
+ return { output: toDataframe(rows), path: full };
234
+ }
235
+ }
236
+ __decorate([
237
+ prop({
238
+ type: "dataframe",
239
+ default: {
240
+ type: "dataframe",
241
+ uri: "",
242
+ asset_id: null,
243
+ data: null,
244
+ metadata: null,
245
+ columns: null
246
+ },
247
+ title: "Df"
248
+ })
249
+ ], SaveDataframeNode.prototype, "df", void 0);
250
+ __decorate([
251
+ prop({
252
+ type: "folder",
253
+ default: {
254
+ type: "folder",
255
+ uri: "",
256
+ asset_id: null,
257
+ data: null,
258
+ metadata: null
259
+ },
260
+ title: "Folder",
261
+ description: "Name of the output folder."
262
+ })
263
+ ], SaveDataframeNode.prototype, "folder", void 0);
264
+ __decorate([
265
+ prop({
266
+ type: "str",
267
+ default: "output.csv",
268
+ title: "Name",
269
+ description: "\n Name of the output file.\n You can use time and date variables to create unique names:\n %Y - Year\n %m - Month\n %d - Day\n %H - Hour\n %M - Minute\n %S - Second\n "
270
+ })
271
+ ], SaveDataframeNode.prototype, "name", void 0);
272
+ export class ImportCSVNode extends BaseNode {
273
+ static nodeType = "nodetool.data.ImportCSV";
274
+ static title = "Import CSV";
275
+ static description = "Convert CSV string to dataframe.\n csv, dataframe, import\n\n Use cases:\n - Import CSV data from string input\n - Convert CSV responses from APIs to dataframe";
276
+ static metadataOutputTypes = {
277
+ output: "dataframe"
278
+ };
279
+ static exposeAsTool = true;
280
+ async process() {
281
+ const csv = String(this.csv_data ?? this.csv_data ?? "");
282
+ return { output: toDataframe(parseCsv(csv)) };
283
+ }
284
+ }
285
+ __decorate([
286
+ prop({
287
+ type: "str",
288
+ default: "",
289
+ title: "CSV Data",
290
+ description: "String input of CSV formatted text."
291
+ })
292
+ ], ImportCSVNode.prototype, "csv_data", void 0);
293
+ export class LoadCSVURLNode extends BaseNode {
294
+ static nodeType = "nodetool.data.LoadCSVURL";
295
+ static title = "Load CSVURL";
296
+ static description = "Load CSV file from URL.\n csv, dataframe, import";
297
+ static metadataOutputTypes = {
298
+ output: "dataframe"
299
+ };
300
+ static exposeAsTool = true;
301
+ async process() {
302
+ const url = String(this.url ?? this.url ?? "");
303
+ const response = await fetch(url);
304
+ if (!response.ok) {
305
+ throw new Error(`Failed to fetch CSV URL: ${response.status}`);
306
+ }
307
+ const csv = await response.text();
308
+ return { output: toDataframe(parseCsv(csv)) };
309
+ }
310
+ }
311
+ __decorate([
312
+ prop({
313
+ type: "str",
314
+ default: "",
315
+ title: "Url",
316
+ description: "The URL of the CSV file to load."
317
+ })
318
+ ], LoadCSVURLNode.prototype, "url", void 0);
319
+ export class LoadCSVFileDataNode extends BaseNode {
320
+ static nodeType = "nodetool.data.LoadCSVFile";
321
+ static title = "Load CSVFile";
322
+ static description = "Load CSV file from file path.\n csv, dataframe, import";
323
+ static metadataOutputTypes = {
324
+ output: "dataframe"
325
+ };
326
+ static exposeAsTool = true;
327
+ async process() {
328
+ const file = String(this.file_path ?? this.file_path ?? "");
329
+ if (!file)
330
+ throw new Error("file_path cannot be empty");
331
+ const csv = await fs.readFile(file, "utf8");
332
+ return { output: toDataframe(parseCsv(csv)) };
333
+ }
334
+ }
335
+ __decorate([
336
+ prop({
337
+ type: "str",
338
+ default: "",
339
+ title: "File Path",
340
+ description: "The path to the CSV file to load."
341
+ })
342
+ ], LoadCSVFileDataNode.prototype, "file_path", void 0);
343
+ export class FromListNode extends BaseNode {
344
+ static nodeType = "nodetool.data.FromList";
345
+ static title = "From List";
346
+ static description = "Convert list of dicts to dataframe.\n list, dataframe, convert\n\n Use cases:\n - Transform list data into structured dataframe\n - Prepare list data for analysis or visualization\n - Convert API responses to dataframe format";
347
+ static metadataOutputTypes = {
348
+ output: "dataframe"
349
+ };
350
+ static exposeAsTool = true;
351
+ async process() {
352
+ const values = Array.isArray(this.values ?? this.values)
353
+ ? (this.values ?? this.values)
354
+ : [];
355
+ const rows = [];
356
+ for (const item of values) {
357
+ if (!item || typeof item !== "object" || Array.isArray(item)) {
358
+ throw new Error("List must contain dicts.");
359
+ }
360
+ const row = {};
361
+ for (const [k, v] of Object.entries(item)) {
362
+ if (v &&
363
+ typeof v === "object" &&
364
+ !Array.isArray(v) &&
365
+ "value" in v) {
366
+ row[k] = v.value;
367
+ }
368
+ else if (typeof v === "number" ||
369
+ typeof v === "string" ||
370
+ typeof v === "boolean" ||
371
+ v == null) {
372
+ row[k] = v;
373
+ }
374
+ else {
375
+ row[k] = String(v);
376
+ }
377
+ }
378
+ rows.push(row);
379
+ }
380
+ return { output: toDataframe(rows) };
381
+ }
382
+ }
383
+ __decorate([
384
+ prop({
385
+ type: "list[any]",
386
+ default: [],
387
+ title: "Values",
388
+ description: "List of values to be converted, each value will be a row."
389
+ })
390
+ ], FromListNode.prototype, "values", void 0);
391
+ export class JSONToDataframeNode extends BaseNode {
392
+ static nodeType = "nodetool.data.JSONToDataframe";
393
+ static title = "Convert JSON to DataFrame";
394
+ static description = "Transforms a JSON string into a pandas DataFrame.\n json, dataframe, conversion\n\n Use cases:\n - Converting API responses to tabular format\n - Preparing JSON data for analysis or visualization\n - Structuring unstructured JSON data for further processing";
395
+ static metadataOutputTypes = {
396
+ output: "dataframe"
397
+ };
398
+ static exposeAsTool = true;
399
+ async process() {
400
+ const text = String(this.text ?? this.text ?? "[]");
401
+ const parsed = JSON.parse(text);
402
+ return { output: toDataframe(asRows(parsed)) };
403
+ }
404
+ }
405
+ __decorate([
406
+ prop({ type: "str", default: "", title: "JSON" })
407
+ ], JSONToDataframeNode.prototype, "text", void 0);
408
+ export class ToListNode extends BaseNode {
409
+ static nodeType = "nodetool.data.ToList";
410
+ static title = "To List";
411
+ static description = "Convert dataframe to list of dictionaries.\n dataframe, list, convert\n\n Use cases:\n - Convert dataframe data for API consumption\n - Transform data for JSON serialization\n - Prepare data for document-based storage";
412
+ static metadataOutputTypes = {
413
+ output: "list[dict]"
414
+ };
415
+ static exposeAsTool = true;
416
+ async process() {
417
+ return { output: asRows(this.dataframe ?? this.dataframe) };
418
+ }
419
+ }
420
+ __decorate([
421
+ prop({
422
+ type: "dataframe",
423
+ default: {
424
+ type: "dataframe",
425
+ uri: "",
426
+ asset_id: null,
427
+ data: null,
428
+ metadata: null,
429
+ columns: null
430
+ },
431
+ title: "Dataframe",
432
+ description: "The input dataframe to convert."
433
+ })
434
+ ], ToListNode.prototype, "dataframe", void 0);
435
+ export class SelectColumnNode extends BaseNode {
436
+ static nodeType = "nodetool.data.SelectColumn";
437
+ static title = "Select Column";
438
+ static description = "Select specific columns from dataframe.\n dataframe, columns, filter\n\n Use cases:\n - Extract relevant features for analysis\n - Reduce dataframe size by removing unnecessary columns\n - Prepare data for specific visualizations or models";
439
+ static metadataOutputTypes = {
440
+ output: "dataframe"
441
+ };
442
+ static exposeAsTool = true;
443
+ async process() {
444
+ const rows = asRows(this.dataframe ?? this.dataframe);
445
+ const cols = String(this.columns ?? this.columns ?? "")
446
+ .split(",")
447
+ .map((c) => c.trim())
448
+ .filter(Boolean);
449
+ if (cols.length === 0)
450
+ return { output: toDataframe(rows) };
451
+ return {
452
+ output: toDataframe(rows.map((row) => Object.fromEntries(cols.map((c) => [c, row[c]]))))
453
+ };
454
+ }
455
+ }
456
+ __decorate([
457
+ prop({
458
+ type: "dataframe",
459
+ default: {
460
+ type: "dataframe",
461
+ uri: "",
462
+ asset_id: null,
463
+ data: null,
464
+ metadata: null,
465
+ columns: null
466
+ },
467
+ title: "Dataframe",
468
+ description: "a dataframe from which columns are to be selected"
469
+ })
470
+ ], SelectColumnNode.prototype, "dataframe", void 0);
471
+ __decorate([
472
+ prop({
473
+ type: "str",
474
+ default: "",
475
+ title: "Columns",
476
+ description: "comma separated list of column names"
477
+ })
478
+ ], SelectColumnNode.prototype, "columns", void 0);
479
+ export class ExtractColumnNode extends BaseNode {
480
+ static nodeType = "nodetool.data.ExtractColumn";
481
+ static title = "Extract Column";
482
+ static description = "Convert dataframe column to list.\n dataframe, column, list\n\n Use cases:\n - Extract data for use in other processing steps\n - Prepare column data for plotting or analysis\n - Convert categorical data to list for encoding";
483
+ static metadataOutputTypes = {
484
+ output: "list[any]"
485
+ };
486
+ static exposeAsTool = true;
487
+ async process() {
488
+ const rows = asRows(this.dataframe ?? this.dataframe);
489
+ const column = String(this.column_name ?? this.column_name ?? "");
490
+ return { output: rows.map((row) => row[column]) };
491
+ }
492
+ }
493
+ __decorate([
494
+ prop({
495
+ type: "dataframe",
496
+ default: {
497
+ type: "dataframe",
498
+ uri: "",
499
+ asset_id: null,
500
+ data: null,
501
+ metadata: null,
502
+ columns: null
503
+ },
504
+ title: "Dataframe",
505
+ description: "The input dataframe."
506
+ })
507
+ ], ExtractColumnNode.prototype, "dataframe", void 0);
508
+ __decorate([
509
+ prop({
510
+ type: "str",
511
+ default: "",
512
+ title: "Column Name",
513
+ description: "The name of the column to be converted to a list."
514
+ })
515
+ ], ExtractColumnNode.prototype, "column_name", void 0);
516
+ export class AddColumnNode extends BaseNode {
517
+ static nodeType = "nodetool.data.AddColumn";
518
+ static title = "Add Column";
519
+ static description = "Add list of values as new column to dataframe.\n dataframe, column, list\n\n Use cases:\n - Incorporate external data into existing dataframe\n - Add calculated results as new column\n - Augment dataframe with additional features";
520
+ static metadataOutputTypes = {
521
+ output: "dataframe"
522
+ };
523
+ static exposeAsTool = true;
524
+ async process() {
525
+ const rows = asRows(this.dataframe ?? this.dataframe);
526
+ const column = String(this.column_name ?? this.column_name ?? "");
527
+ const values = Array.isArray(this.values ?? this.values)
528
+ ? (this.values ?? this.values)
529
+ : [];
530
+ return {
531
+ output: toDataframe(rows.map((row, i) => ({
532
+ ...row,
533
+ [column]: values[i]
534
+ })))
535
+ };
536
+ }
537
+ }
538
+ __decorate([
539
+ prop({
540
+ type: "dataframe",
541
+ default: {
542
+ type: "dataframe",
543
+ uri: "",
544
+ asset_id: null,
545
+ data: null,
546
+ metadata: null,
547
+ columns: null
548
+ },
549
+ title: "Dataframe",
550
+ description: "Dataframe object to add a new column to."
551
+ })
552
+ ], AddColumnNode.prototype, "dataframe", void 0);
553
+ __decorate([
554
+ prop({
555
+ type: "str",
556
+ default: "",
557
+ title: "Column Name",
558
+ description: "The name of the new column to be added to the dataframe."
559
+ })
560
+ ], AddColumnNode.prototype, "column_name", void 0);
561
+ __decorate([
562
+ prop({
563
+ type: "list[any]",
564
+ default: [],
565
+ title: "Values",
566
+ description: "A list of any type of elements which will be the new column's values."
567
+ })
568
+ ], AddColumnNode.prototype, "values", void 0);
569
+ export class MergeDataframeNode extends BaseNode {
570
+ static nodeType = "nodetool.data.Merge";
571
+ static title = "Merge";
572
+ static description = "Merge two dataframes along columns.\n merge, concat, columns\n\n Use cases:\n - Combine data from multiple sources\n - Add new features to existing dataframe\n - Merge time series data from different periods";
573
+ static metadataOutputTypes = {
574
+ output: "dataframe"
575
+ };
576
+ static exposeAsTool = true;
577
+ async process() {
578
+ const a = asRows(this.dataframe_a ?? this.dataframe_a);
579
+ const b = asRows(this.dataframe_b ?? this.dataframe_b);
580
+ const len = Math.max(a.length, b.length);
581
+ const out = [];
582
+ for (let i = 0; i < len; i += 1) {
583
+ out.push({ ...(a[i] ?? {}), ...(b[i] ?? {}) });
584
+ }
585
+ return { output: toDataframe(out) };
586
+ }
587
+ }
588
+ __decorate([
589
+ prop({
590
+ type: "dataframe",
591
+ default: {
592
+ type: "dataframe",
593
+ uri: "",
594
+ asset_id: null,
595
+ data: null,
596
+ metadata: null,
597
+ columns: null
598
+ },
599
+ title: "Dataframe A",
600
+ description: "First DataFrame to be merged."
601
+ })
602
+ ], MergeDataframeNode.prototype, "dataframe_a", void 0);
603
+ __decorate([
604
+ prop({
605
+ type: "dataframe",
606
+ default: {
607
+ type: "dataframe",
608
+ uri: "",
609
+ asset_id: null,
610
+ data: null,
611
+ metadata: null,
612
+ columns: null
613
+ },
614
+ title: "Dataframe B",
615
+ description: "Second DataFrame to be merged."
616
+ })
617
+ ], MergeDataframeNode.prototype, "dataframe_b", void 0);
618
+ export class AppendDataframeNode extends BaseNode {
619
+ static nodeType = "nodetool.data.Append";
620
+ static title = "Append";
621
+ static description = "Append two dataframes along rows.\n append, concat, rows\n\n Use cases:\n - Combine data from multiple time periods\n - Merge datasets with same structure\n - Aggregate data from different sources";
622
+ static metadataOutputTypes = {
623
+ output: "dataframe"
624
+ };
625
+ static exposeAsTool = true;
626
+ async process() {
627
+ const a = asRows(this.dataframe_a ?? this.dataframe_a);
628
+ const b = asRows(this.dataframe_b ?? this.dataframe_b);
629
+ if (a.length === 0)
630
+ return { output: toDataframe(b) };
631
+ if (b.length === 0)
632
+ return { output: toDataframe(a) };
633
+ const aCols = Object.keys(a[0]).sort().join(",");
634
+ const bCols = Object.keys(b[0]).sort().join(",");
635
+ if (aCols !== bCols) {
636
+ throw new Error("Columns in dataframe A do not match columns in dataframe B");
637
+ }
638
+ return { output: toDataframe([...a, ...b]) };
639
+ }
640
+ }
641
+ __decorate([
642
+ prop({
643
+ type: "dataframe",
644
+ default: {
645
+ type: "dataframe",
646
+ uri: "",
647
+ asset_id: null,
648
+ data: null,
649
+ metadata: null,
650
+ columns: null
651
+ },
652
+ title: "Dataframe A",
653
+ description: "First DataFrame to be appended."
654
+ })
655
+ ], AppendDataframeNode.prototype, "dataframe_a", void 0);
656
+ __decorate([
657
+ prop({
658
+ type: "dataframe",
659
+ default: {
660
+ type: "dataframe",
661
+ uri: "",
662
+ asset_id: null,
663
+ data: null,
664
+ metadata: null,
665
+ columns: null
666
+ },
667
+ title: "Dataframe B",
668
+ description: "Second DataFrame to be appended."
669
+ })
670
+ ], AppendDataframeNode.prototype, "dataframe_b", void 0);
671
+ export class JoinDataframeNode extends BaseNode {
672
+ static nodeType = "nodetool.data.Join";
673
+ static title = "Join";
674
+ static description = "Join two dataframes on specified column.\n join, merge, column\n\n Use cases:\n - Combine data from related tables\n - Enrich dataset with additional information\n - Link data based on common identifiers";
675
+ static metadataOutputTypes = {
676
+ output: "dataframe"
677
+ };
678
+ static exposeAsTool = true;
679
+ async process(context) {
680
+ const a = asRows(this.dataframe_a ?? this.dataframe_a);
681
+ const b = asRows(this.dataframe_b ?? this.dataframe_b);
682
+ const joinOn = String(this.join_on ?? this.join_on ?? "");
683
+ // Validate join column exists in both dataframes
684
+ const colsA = a.length > 0 ? Object.keys(a[0]) : [];
685
+ const colsB = b.length > 0 ? Object.keys(b[0]) : [];
686
+ if (joinOn && a.length > 0 && !colsA.includes(joinOn)) {
687
+ throw new Error(`Join column '${joinOn}' not found in dataframe A. Available columns: ${colsA.join(", ")}`);
688
+ }
689
+ if (joinOn && b.length > 0 && !colsB.includes(joinOn)) {
690
+ throw new Error(`Join column '${joinOn}' not found in dataframe B. Available columns: ${colsB.join(", ")}`);
691
+ }
692
+ // Warn about column collisions (excluding the join column)
693
+ const colsASet = new Set(colsA.filter((c) => c !== joinOn));
694
+ const colsBSet = new Set(colsB.filter((c) => c !== joinOn));
695
+ const collisions = [...colsASet].filter((c) => colsBSet.has(c));
696
+ if (collisions.length > 0 && context && typeof context.emit === "function") {
697
+ const nodeId = String(this.__node_id ??
698
+ this.name ??
699
+ "");
700
+ context.emit({
701
+ type: "node_progress",
702
+ node_id: nodeId,
703
+ progress: 0,
704
+ total: 0
705
+ });
706
+ console.warn(`Join: columns [${collisions.join(", ")}] exist in both dataframes and will be overwritten by dataframe B values.`);
707
+ }
708
+ const mapB = new Map();
709
+ for (const row of b) {
710
+ const key = row[joinOn];
711
+ if (!mapB.has(key))
712
+ mapB.set(key, []);
713
+ mapB.get(key).push(row);
714
+ }
715
+ const out = [];
716
+ for (const row of a) {
717
+ const matches = mapB.get(row[joinOn]) ?? [];
718
+ for (const m of matches) {
719
+ out.push({ ...row, ...m });
720
+ }
721
+ }
722
+ return { output: toDataframe(out) };
723
+ }
724
+ }
725
+ __decorate([
726
+ prop({
727
+ type: "dataframe",
728
+ default: {
729
+ type: "dataframe",
730
+ uri: "",
731
+ asset_id: null,
732
+ data: null,
733
+ metadata: null,
734
+ columns: null
735
+ },
736
+ title: "Dataframe A",
737
+ description: "First DataFrame to be merged."
738
+ })
739
+ ], JoinDataframeNode.prototype, "dataframe_a", void 0);
740
+ __decorate([
741
+ prop({
742
+ type: "dataframe",
743
+ default: {
744
+ type: "dataframe",
745
+ uri: "",
746
+ asset_id: null,
747
+ data: null,
748
+ metadata: null,
749
+ columns: null
750
+ },
751
+ title: "Dataframe B",
752
+ description: "Second DataFrame to be merged."
753
+ })
754
+ ], JoinDataframeNode.prototype, "dataframe_b", void 0);
755
+ __decorate([
756
+ prop({
757
+ type: "str",
758
+ default: "",
759
+ title: "Join On",
760
+ description: "The column name on which to join the two dataframes."
761
+ })
762
+ ], JoinDataframeNode.prototype, "join_on", void 0);
763
+ export class RowIteratorNode extends BaseNode {
764
+ static nodeType = "nodetool.data.RowIterator";
765
+ static title = "Row Iterator";
766
+ static description = "Iterate over rows of a dataframe.";
767
+ static metadataOutputTypes = {
768
+ dict: "dict",
769
+ index: "any"
770
+ };
771
+ static isStreamingOutput = true;
772
+ async process() {
773
+ return {};
774
+ }
775
+ async *genProcess() {
776
+ const rows = asRows(this.dataframe ?? this.dataframe);
777
+ for (const [index, row] of rows.entries()) {
778
+ yield { dict: row, index };
779
+ }
780
+ }
781
+ }
782
+ __decorate([
783
+ prop({
784
+ type: "dataframe",
785
+ default: {
786
+ type: "dataframe",
787
+ uri: "",
788
+ asset_id: null,
789
+ data: null,
790
+ metadata: null,
791
+ columns: null
792
+ },
793
+ title: "Dataframe",
794
+ description: "The input dataframe."
795
+ })
796
+ ], RowIteratorNode.prototype, "dataframe", void 0);
797
+ export class FindRowNode extends BaseNode {
798
+ static nodeType = "nodetool.data.FindRow";
799
+ static title = "Find Row";
800
+ static description = "Find the first row in a dataframe that matches a given condition.\n filter, query, condition, single row\n\n Example conditions:\n age > 30\n age > 30 and salary < 50000\n name == 'John Doe'\n 100 <= price <= 200\n status in ['Active', 'Pending']\n not (age < 18)\n\n Use cases:\n - Retrieve specific record based on criteria\n - Find first occurrence of a particular condition\n - Extract single data point for further analysis";
801
+ static metadataOutputTypes = {
802
+ output: "dataframe"
803
+ };
804
+ static exposeAsTool = true;
805
+ async process() {
806
+ const rows = asRows(this.df ?? this.df);
807
+ const condition = String(this.condition ?? this.condition ?? "");
808
+ const filtered = applyFilter(rows, condition).slice(0, 1);
809
+ return { output: toDataframe(filtered) };
810
+ }
811
+ }
812
+ __decorate([
813
+ prop({
814
+ type: "dataframe",
815
+ default: {
816
+ type: "dataframe",
817
+ uri: "",
818
+ asset_id: null,
819
+ data: null,
820
+ metadata: null,
821
+ columns: null
822
+ },
823
+ title: "Df",
824
+ description: "The DataFrame to search."
825
+ })
826
+ ], FindRowNode.prototype, "df", void 0);
827
+ __decorate([
828
+ prop({
829
+ type: "str",
830
+ default: "",
831
+ title: "Condition",
832
+ description: "The condition to filter the DataFrame, e.g. 'column_name == value'."
833
+ })
834
+ ], FindRowNode.prototype, "condition", void 0);
835
+ export class SortByColumnNode extends BaseNode {
836
+ static nodeType = "nodetool.data.SortByColumn";
837
+ static title = "Sort By Column";
838
+ static description = "Sort dataframe by specified column.\n sort, order, column\n\n Use cases:\n - Arrange data in ascending or descending order\n - Identify top or bottom values in dataset\n - Prepare data for rank-based analysis";
839
+ static metadataOutputTypes = {
840
+ output: "dataframe"
841
+ };
842
+ async process() {
843
+ const rows = asRows(this.df ?? this.df);
844
+ const col = String(this.column ?? this.column ?? "");
845
+ const sorted = [...rows].sort((a, b) => {
846
+ const left = a[col];
847
+ const right = b[col];
848
+ const leftNum = toNumber(left);
849
+ const rightNum = toNumber(right);
850
+ if (Number.isFinite(leftNum) && Number.isFinite(rightNum)) {
851
+ return leftNum - rightNum;
852
+ }
853
+ return String(left ?? "").localeCompare(String(right ?? ""));
854
+ });
855
+ return { output: toDataframe(sorted) };
856
+ }
857
+ }
858
+ __decorate([
859
+ prop({
860
+ type: "dataframe",
861
+ default: {
862
+ type: "dataframe",
863
+ uri: "",
864
+ asset_id: null,
865
+ data: null,
866
+ metadata: null,
867
+ columns: null
868
+ },
869
+ title: "Df"
870
+ })
871
+ ], SortByColumnNode.prototype, "df", void 0);
872
+ __decorate([
873
+ prop({
874
+ type: "str",
875
+ default: "",
876
+ title: "Column",
877
+ description: "The column to sort the DataFrame by."
878
+ })
879
+ ], SortByColumnNode.prototype, "column", void 0);
880
+ export class DropDuplicatesNode extends BaseNode {
881
+ static nodeType = "nodetool.data.DropDuplicates";
882
+ static title = "Drop Duplicates";
883
+ static description = "Remove duplicate rows from dataframe.\n duplicates, unique, clean\n\n Use cases:\n - Clean dataset by removing redundant entries\n - Ensure data integrity in analysis\n - Prepare data for unique value operations";
884
+ static metadataOutputTypes = {
885
+ output: "dataframe"
886
+ };
887
+ static exposeAsTool = true;
888
+ async process() {
889
+ const rows = asRows(this.df ?? this.df);
890
+ return { output: toDataframe(uniqueRows(rows)) };
891
+ }
892
+ }
893
+ __decorate([
894
+ prop({
895
+ type: "dataframe",
896
+ default: {
897
+ type: "dataframe",
898
+ uri: "",
899
+ asset_id: null,
900
+ data: null,
901
+ metadata: null,
902
+ columns: null
903
+ },
904
+ title: "Df",
905
+ description: "The input DataFrame."
906
+ })
907
+ ], DropDuplicatesNode.prototype, "df", void 0);
908
+ export class DropNANode extends BaseNode {
909
+ static nodeType = "nodetool.data.DropNA";
910
+ static title = "Drop NA";
911
+ static description = "Remove rows with NA values from dataframe.\n na, missing, clean\n\n Use cases:\n - Clean dataset by removing incomplete entries\n - Prepare data for analysis requiring complete cases\n - Improve data quality for modeling";
912
+ static metadataOutputTypes = {
913
+ output: "dataframe"
914
+ };
915
+ static exposeAsTool = true;
916
+ async process() {
917
+ const rows = asRows(this.df ?? this.df);
918
+ const out = rows.filter((row) => Object.values(row).every((v) => v !== null && v !== undefined && !Number.isNaN(v)));
919
+ return { output: toDataframe(out) };
920
+ }
921
+ }
922
+ __decorate([
923
+ prop({
924
+ type: "dataframe",
925
+ default: {
926
+ type: "dataframe",
927
+ uri: "",
928
+ asset_id: null,
929
+ data: null,
930
+ metadata: null,
931
+ columns: null
932
+ },
933
+ title: "Df",
934
+ description: "The input DataFrame."
935
+ })
936
+ ], DropNANode.prototype, "df", void 0);
937
+ export class ForEachRowNode extends BaseNode {
938
+ static nodeType = "nodetool.data.ForEachRow";
939
+ static title = "For Each Row";
940
+ static description = "Iterate over rows of a dataframe.\n iterator, loop, dataframe, sequence, rows\n\n Use cases:\n - Process each row of a dataframe individually\n - Trigger actions for every record in a dataset";
941
+ static metadataOutputTypes = {
942
+ row: "dict",
943
+ index: "any"
944
+ };
945
+ static exposeAsTool = true;
946
+ static isStreamingOutput = true;
947
+ async process() {
948
+ return {};
949
+ }
950
+ async *genProcess() {
951
+ const rows = asRows(this.dataframe ?? this.dataframe);
952
+ for (const [index, row] of rows.entries()) {
953
+ yield { row, index };
954
+ }
955
+ }
956
+ }
957
+ __decorate([
958
+ prop({
959
+ type: "dataframe",
960
+ default: {
961
+ type: "dataframe",
962
+ uri: "",
963
+ asset_id: null,
964
+ data: null,
965
+ metadata: null,
966
+ columns: null
967
+ },
968
+ title: "Dataframe",
969
+ description: "The input dataframe."
970
+ })
971
+ ], ForEachRowNode.prototype, "dataframe", void 0);
972
+ export class LoadCSVAssetsNode extends BaseNode {
973
+ static nodeType = "nodetool.data.LoadCSVAssets";
974
+ static title = "Load CSV Assets";
975
+ static description = "Load dataframes from an asset folder.\n load, dataframe, file, import\n\n Use cases:\n - Load multiple dataframes from a folder\n - Process multiple datasets in sequence\n - Batch import of data files";
976
+ static metadataOutputTypes = {
977
+ dataframe: "dataframe",
978
+ name: "str",
979
+ dataframes: "list",
980
+ names: "list"
981
+ };
982
+ static exposeAsTool = true;
983
+ static isStreamingOutput = true;
984
+ async process() {
985
+ const allDataframes = [];
986
+ const allNames = [];
987
+ for await (const item of this._collectItems()) {
988
+ allDataframes.push(item.dataframe);
989
+ allNames.push(item.name);
990
+ }
991
+ return {
992
+ dataframe: allDataframes[0] ?? toDataframe([]),
993
+ name: allNames[0] ?? "",
994
+ dataframes: allDataframes,
995
+ names: allNames
996
+ };
997
+ }
998
+ async *_collectItems() {
999
+ const folder = String(this.folder ?? this.folder ?? ".");
1000
+ const entries = await fs.readdir(folder, { withFileTypes: true });
1001
+ for (const entry of entries) {
1002
+ if (!entry.isFile() || !entry.name.toLowerCase().endsWith(".csv"))
1003
+ continue;
1004
+ const full = path.join(folder, entry.name);
1005
+ const csv = await fs.readFile(full, "utf8");
1006
+ yield { name: entry.name, dataframe: toDataframe(parseCsv(csv)) };
1007
+ }
1008
+ }
1009
+ async *genProcess() {
1010
+ const allDataframes = [];
1011
+ const allNames = [];
1012
+ for await (const item of this._collectItems()) {
1013
+ allDataframes.push(item.dataframe);
1014
+ allNames.push(item.name);
1015
+ yield { name: item.name, dataframe: item.dataframe };
1016
+ }
1017
+ // Emit collected lists as final output
1018
+ yield { dataframes: allDataframes, names: allNames };
1019
+ }
1020
+ }
1021
+ __decorate([
1022
+ prop({
1023
+ type: "folder",
1024
+ default: {
1025
+ type: "folder",
1026
+ uri: "",
1027
+ asset_id: null,
1028
+ data: null,
1029
+ metadata: null
1030
+ },
1031
+ title: "Folder",
1032
+ description: "The asset folder to load the dataframes from."
1033
+ })
1034
+ ], LoadCSVAssetsNode.prototype, "folder", void 0);
1035
+ export class AggregateNode extends BaseNode {
1036
+ static nodeType = "nodetool.data.Aggregate";
1037
+ static title = "Aggregate";
1038
+ static description = "Aggregate dataframe by one or more columns.\n aggregate, groupby, group, sum, mean, count, min, max, std, var, median, first, last\n\n Use cases:\n - Prepare data for aggregation operations\n - Analyze data by categories\n - Create summary statistics by groups";
1039
+ static metadataOutputTypes = {
1040
+ output: "dataframe"
1041
+ };
1042
+ static exposeAsTool = true;
1043
+ async process() {
1044
+ const rows = asRows(this.dataframe ?? this.dataframe);
1045
+ const groupCols = String(this.columns ?? this.columns ?? "")
1046
+ .split(",")
1047
+ .map((c) => c.trim())
1048
+ .filter(Boolean);
1049
+ const agg = String(this.aggregation ?? this.aggregation ?? "sum");
1050
+ const groups = new Map();
1051
+ for (const row of rows) {
1052
+ const keyObj = Object.fromEntries(groupCols.map((c) => [c, row[c]]));
1053
+ const key = JSON.stringify(keyObj);
1054
+ if (!groups.has(key))
1055
+ groups.set(key, []);
1056
+ groups.get(key).push(row);
1057
+ }
1058
+ const output = [];
1059
+ for (const [key, items] of groups) {
1060
+ const base = JSON.parse(key);
1061
+ const numericCols = [...new Set(items.flatMap((r) => Object.keys(r)))]
1062
+ .filter((c) => !groupCols.includes(c))
1063
+ .filter((c) => items.some((r) => Number.isFinite(toNumber(r[c]))));
1064
+ for (const col of numericCols) {
1065
+ const values = items
1066
+ .map((r) => toNumber(r[col]))
1067
+ .filter((n) => Number.isFinite(n));
1068
+ if (values.length === 0)
1069
+ continue;
1070
+ if (agg === "sum")
1071
+ base[col] = sum(values);
1072
+ else if (agg === "mean")
1073
+ base[col] = mean(values);
1074
+ else if (agg === "count")
1075
+ base[col] = values.length;
1076
+ else if (agg === "min")
1077
+ base[col] = Math.min(...values);
1078
+ else if (agg === "max")
1079
+ base[col] = Math.max(...values);
1080
+ else if (agg === "std") {
1081
+ const m = mean(values);
1082
+ const variance = values.length > 1
1083
+ ? values.reduce((s, v) => s + (v - m) ** 2, 0) /
1084
+ (values.length - 1)
1085
+ : 0;
1086
+ base[col] = Math.sqrt(variance);
1087
+ }
1088
+ else if (agg === "var") {
1089
+ const m = mean(values);
1090
+ base[col] =
1091
+ values.length > 1
1092
+ ? values.reduce((s, v) => s + (v - m) ** 2, 0) /
1093
+ (values.length - 1)
1094
+ : 0;
1095
+ }
1096
+ else if (agg === "median")
1097
+ base[col] = median(values);
1098
+ else if (agg === "first")
1099
+ base[col] = values[0];
1100
+ else if (agg === "last")
1101
+ base[col] = values[values.length - 1];
1102
+ else
1103
+ throw new Error(`Unknown aggregation function: ${agg}`);
1104
+ }
1105
+ output.push(base);
1106
+ }
1107
+ return { output: toDataframe(output) };
1108
+ }
1109
+ }
1110
+ __decorate([
1111
+ prop({
1112
+ type: "dataframe",
1113
+ default: {
1114
+ type: "dataframe",
1115
+ uri: "",
1116
+ asset_id: null,
1117
+ data: null,
1118
+ metadata: null,
1119
+ columns: null
1120
+ },
1121
+ title: "Dataframe",
1122
+ description: "The DataFrame to group."
1123
+ })
1124
+ ], AggregateNode.prototype, "dataframe", void 0);
1125
+ __decorate([
1126
+ prop({
1127
+ type: "str",
1128
+ default: "",
1129
+ title: "Columns",
1130
+ description: "Comma-separated column names to group by."
1131
+ })
1132
+ ], AggregateNode.prototype, "columns", void 0);
1133
+ __decorate([
1134
+ prop({
1135
+ type: "str",
1136
+ default: "sum",
1137
+ title: "Aggregation",
1138
+ description: "Aggregation function: sum, mean, count, min, max, std, var, median, first, last"
1139
+ })
1140
+ ], AggregateNode.prototype, "aggregation", void 0);
1141
+ export class PivotNode extends BaseNode {
1142
+ static nodeType = "nodetool.data.Pivot";
1143
+ static title = "Pivot";
1144
+ static description = "Pivot dataframe to reshape data.\n pivot, reshape, transform\n\n Use cases:\n - Transform long data to wide format\n - Create cross-tabulation tables\n - Reorganize data for visualization";
1145
+ static metadataOutputTypes = {
1146
+ output: "dataframe"
1147
+ };
1148
+ static exposeAsTool = true;
1149
+ async process() {
1150
+ const rows = asRows(this.dataframe ?? this.dataframe);
1151
+ const indexCol = String(this.index ?? this.index ?? "");
1152
+ const colCol = String(this.columns ?? this.columns ?? "");
1153
+ const valCol = String(this.values ?? this.values ?? "");
1154
+ const agg = String(this.aggfunc ?? this.aggfunc ?? "sum");
1155
+ const groups = new Map();
1156
+ for (const row of rows) {
1157
+ const idx = row[indexCol];
1158
+ const col = row[colCol];
1159
+ const val = toNumber(row[valCol]);
1160
+ if (!Number.isFinite(val))
1161
+ continue;
1162
+ if (!groups.has(idx))
1163
+ groups.set(idx, new Map());
1164
+ const sub = groups.get(idx);
1165
+ if (!sub.has(col))
1166
+ sub.set(col, []);
1167
+ sub.get(col).push(val);
1168
+ }
1169
+ const out = [];
1170
+ for (const [idx, cols] of groups) {
1171
+ const row = { [indexCol]: idx };
1172
+ for (const [col, values] of cols) {
1173
+ if (agg === "sum")
1174
+ row[String(col)] = sum(values);
1175
+ else if (agg === "mean")
1176
+ row[String(col)] = mean(values);
1177
+ else if (agg === "count")
1178
+ row[String(col)] = values.length;
1179
+ else if (agg === "min")
1180
+ row[String(col)] = Math.min(...values);
1181
+ else if (agg === "max")
1182
+ row[String(col)] = Math.max(...values);
1183
+ else if (agg === "first")
1184
+ row[String(col)] = values[0];
1185
+ else if (agg === "last")
1186
+ row[String(col)] = values[values.length - 1];
1187
+ else
1188
+ throw new Error(`Unknown aggregation function: ${agg}`);
1189
+ }
1190
+ out.push(row);
1191
+ }
1192
+ return { output: toDataframe(out) };
1193
+ }
1194
+ }
1195
+ __decorate([
1196
+ prop({
1197
+ type: "dataframe",
1198
+ default: {
1199
+ type: "dataframe",
1200
+ uri: "",
1201
+ asset_id: null,
1202
+ data: null,
1203
+ metadata: null,
1204
+ columns: null
1205
+ },
1206
+ title: "Dataframe",
1207
+ description: "The DataFrame to pivot."
1208
+ })
1209
+ ], PivotNode.prototype, "dataframe", void 0);
1210
+ __decorate([
1211
+ prop({
1212
+ type: "str",
1213
+ default: "",
1214
+ title: "Index",
1215
+ description: "Column name to use as index (rows)."
1216
+ })
1217
+ ], PivotNode.prototype, "index", void 0);
1218
+ __decorate([
1219
+ prop({
1220
+ type: "str",
1221
+ default: "",
1222
+ title: "Columns",
1223
+ description: "Column name to use as columns."
1224
+ })
1225
+ ], PivotNode.prototype, "columns", void 0);
1226
+ __decorate([
1227
+ prop({
1228
+ type: "str",
1229
+ default: "",
1230
+ title: "Values",
1231
+ description: "Column name to use as values."
1232
+ })
1233
+ ], PivotNode.prototype, "values", void 0);
1234
+ __decorate([
1235
+ prop({
1236
+ type: "str",
1237
+ default: "sum",
1238
+ title: "Aggfunc",
1239
+ description: "Aggregation function: sum, mean, count, min, max, first, last"
1240
+ })
1241
+ ], PivotNode.prototype, "aggfunc", void 0);
1242
+ export class RenameNode extends BaseNode {
1243
+ static nodeType = "nodetool.data.Rename";
1244
+ static title = "Rename";
1245
+ static description = "Rename columns in dataframe.\n rename, columns, names\n\n Use cases:\n - Standardize column names\n - Make column names more descriptive\n - Prepare data for specific requirements";
1246
+ static metadataOutputTypes = {
1247
+ output: "dataframe"
1248
+ };
1249
+ static exposeAsTool = true;
1250
+ async process() {
1251
+ const rows = asRows(this.dataframe ?? this.dataframe);
1252
+ const mapString = String(this.rename_map ?? this.rename_map ?? "");
1253
+ const rename = new Map();
1254
+ for (const pair of mapString.split(",")) {
1255
+ if (!pair.includes(":"))
1256
+ continue;
1257
+ const [a, b] = pair.split(":", 2).map((s) => s.trim());
1258
+ if (a)
1259
+ rename.set(a, b);
1260
+ }
1261
+ const out = rows.map((row) => Object.fromEntries(Object.entries(row).map(([k, v]) => [rename.get(k) ?? k, v])));
1262
+ return { output: toDataframe(out) };
1263
+ }
1264
+ }
1265
+ __decorate([
1266
+ prop({
1267
+ type: "dataframe",
1268
+ default: {
1269
+ type: "dataframe",
1270
+ uri: "",
1271
+ asset_id: null,
1272
+ data: null,
1273
+ metadata: null,
1274
+ columns: null
1275
+ },
1276
+ title: "Dataframe",
1277
+ description: "The DataFrame to rename columns."
1278
+ })
1279
+ ], RenameNode.prototype, "dataframe", void 0);
1280
+ __decorate([
1281
+ prop({
1282
+ type: "str",
1283
+ default: "",
1284
+ title: "Rename Map",
1285
+ description: "Column rename mapping in format: old1:new1,old2:new2"
1286
+ })
1287
+ ], RenameNode.prototype, "rename_map", void 0);
1288
+ export class FillNANode extends BaseNode {
1289
+ static nodeType = "nodetool.data.FillNA";
1290
+ static title = "Fill NA";
1291
+ static description = "Fill missing values in dataframe.\n fillna, missing, impute\n\n Use cases:\n - Handle missing data\n - Prepare data for analysis\n - Improve data quality";
1292
+ static metadataOutputTypes = {
1293
+ output: "dataframe"
1294
+ };
1295
+ static exposeAsTool = true;
1296
+ async process() {
1297
+ const rows = asRows(this.dataframe ?? this.dataframe);
1298
+ const value = this.value ?? this.value ?? 0;
1299
+ const method = String(this.method ?? this.method ?? "value");
1300
+ const colsRaw = String(this.columns ?? this.columns ?? "");
1301
+ const allCols = [...new Set(rows.flatMap((r) => Object.keys(r)))];
1302
+ const cols = colsRaw
1303
+ ? colsRaw
1304
+ .split(",")
1305
+ .map((c) => c.trim())
1306
+ .filter(Boolean)
1307
+ : allCols;
1308
+ const out = rows.map((r) => ({ ...r }));
1309
+ if (method === "value") {
1310
+ for (const row of out) {
1311
+ for (const col of cols) {
1312
+ if (row[col] == null || row[col] === "")
1313
+ row[col] = value;
1314
+ }
1315
+ }
1316
+ return { output: toDataframe(out) };
1317
+ }
1318
+ if (method === "forward" || method === "backward") {
1319
+ for (const col of cols) {
1320
+ if (method === "forward") {
1321
+ let last = null;
1322
+ for (const row of out) {
1323
+ if (row[col] == null || row[col] === "")
1324
+ row[col] = last;
1325
+ else
1326
+ last = row[col];
1327
+ }
1328
+ }
1329
+ else {
1330
+ let next = null;
1331
+ for (let i = out.length - 1; i >= 0; i -= 1) {
1332
+ const row = out[i];
1333
+ if (row[col] == null || row[col] === "")
1334
+ row[col] = next;
1335
+ else
1336
+ next = row[col];
1337
+ }
1338
+ }
1339
+ }
1340
+ return { output: toDataframe(out) };
1341
+ }
1342
+ if (method === "mean" || method === "median") {
1343
+ for (const col of cols) {
1344
+ const nums = out
1345
+ .map((r) => toNumber(r[col]))
1346
+ .filter((n) => Number.isFinite(n));
1347
+ const fill = method === "mean" ? mean(nums) : median(nums);
1348
+ if (!Number.isFinite(fill))
1349
+ continue;
1350
+ for (const row of out) {
1351
+ if (row[col] == null || row[col] === "")
1352
+ row[col] = fill;
1353
+ }
1354
+ }
1355
+ return { output: toDataframe(out) };
1356
+ }
1357
+ throw new Error(`Unknown fill method: ${method}`);
1358
+ }
1359
+ }
1360
+ __decorate([
1361
+ prop({
1362
+ type: "dataframe",
1363
+ default: {
1364
+ type: "dataframe",
1365
+ uri: "",
1366
+ asset_id: null,
1367
+ data: null,
1368
+ metadata: null,
1369
+ columns: null
1370
+ },
1371
+ title: "Dataframe",
1372
+ description: "The DataFrame with missing values."
1373
+ })
1374
+ ], FillNANode.prototype, "dataframe", void 0);
1375
+ __decorate([
1376
+ prop({
1377
+ type: "any",
1378
+ default: 0,
1379
+ title: "Value",
1380
+ description: "Value to use for filling missing values."
1381
+ })
1382
+ ], FillNANode.prototype, "value", void 0);
1383
+ __decorate([
1384
+ prop({
1385
+ type: "str",
1386
+ default: "value",
1387
+ title: "Method",
1388
+ description: "Method for filling: value, forward, backward, mean, median"
1389
+ })
1390
+ ], FillNANode.prototype, "method", void 0);
1391
+ __decorate([
1392
+ prop({
1393
+ type: "str",
1394
+ default: "",
1395
+ title: "Columns",
1396
+ description: "Comma-separated column names to fill. Leave empty for all columns."
1397
+ })
1398
+ ], FillNANode.prototype, "columns", void 0);
1399
+ export class SaveCSVDataframeFileNode extends BaseNode {
1400
+ static nodeType = "nodetool.data.SaveCSVDataframeFile";
1401
+ static title = "Save CSVDataframe File";
1402
+ static description = "Write a pandas DataFrame to a CSV file.\n files, csv, write, output, save, file\n\n The filename can include time and date variables:\n %Y - Year, %m - Month, %d - Day\n %H - Hour, %M - Minute, %S - Second";
1403
+ static metadataOutputTypes = {
1404
+ output: "dataframe"
1405
+ };
1406
+ async process() {
1407
+ const rows = asRows(this.dataframe ?? this.dataframe);
1408
+ const folder = String(this.folder ?? this.folder ?? "");
1409
+ const filenameRaw = String(this.filename ?? this.filename ?? "");
1410
+ if (!folder)
1411
+ throw new Error("folder cannot be empty");
1412
+ if (!filenameRaw)
1413
+ throw new Error("filename cannot be empty");
1414
+ const filename = dateName(filenameRaw);
1415
+ const full = path.resolve(folder, filename);
1416
+ await fs.mkdir(path.dirname(full), { recursive: true });
1417
+ await fs.writeFile(full, toCsv(rows), "utf8");
1418
+ return { output: toDataframe(rows), path: full };
1419
+ }
1420
+ }
1421
+ __decorate([
1422
+ prop({
1423
+ type: "dataframe",
1424
+ default: {
1425
+ type: "dataframe",
1426
+ uri: "",
1427
+ asset_id: null,
1428
+ data: null,
1429
+ metadata: null,
1430
+ columns: null
1431
+ },
1432
+ title: "Dataframe",
1433
+ description: "DataFrame to write to CSV"
1434
+ })
1435
+ ], SaveCSVDataframeFileNode.prototype, "dataframe", void 0);
1436
+ __decorate([
1437
+ prop({
1438
+ type: "str",
1439
+ default: "",
1440
+ title: "Folder",
1441
+ description: "Folder where the file will be saved"
1442
+ })
1443
+ ], SaveCSVDataframeFileNode.prototype, "folder", void 0);
1444
+ __decorate([
1445
+ prop({
1446
+ type: "str",
1447
+ default: "",
1448
+ title: "Filename",
1449
+ description: "Name of the CSV file to save. Supports strftime format codes."
1450
+ })
1451
+ ], SaveCSVDataframeFileNode.prototype, "filename", void 0);
1452
+ export class FilterNoneNode extends BaseNode {
1453
+ static nodeType = "nodetool.data.FilterNone";
1454
+ static title = "Filter None";
1455
+ static description = "Filters out None values from a stream.\n filter, none, null, stream\n\n Use cases:\n - Clean data by removing null values\n - Get only valid entries\n - Remove placeholder values";
1456
+ static metadataOutputTypes = {
1457
+ output: "any"
1458
+ };
1459
+ static isStreamingInput = true;
1460
+ static isStreamingOutput = true;
1461
+ async process() {
1462
+ const value = this.value ?? this.value ?? null;
1463
+ if (value == null) {
1464
+ return {};
1465
+ }
1466
+ return { output: value };
1467
+ }
1468
+ }
1469
+ __decorate([
1470
+ prop({
1471
+ type: "any",
1472
+ default: [],
1473
+ title: "Value",
1474
+ description: "Input stream"
1475
+ })
1476
+ ], FilterNoneNode.prototype, "value", void 0);
1477
+ export class DescribeNode extends BaseNode {
1478
+ static nodeType = "nodetool.data.Describe";
1479
+ static title = "Describe";
1480
+ static description = "Compute summary statistics for each numeric column: count, mean, std, min, 25%, 50%, 75%, max.\n dataframe, statistics, describe, summary, stats, mean, std, min, max, quartile";
1481
+ static metadataOutputTypes = {
1482
+ output: "dataframe"
1483
+ };
1484
+ async process() {
1485
+ const rows = asRows(this.dataframe);
1486
+ if (rows.length === 0)
1487
+ return { output: toDataframe([]) };
1488
+ const allKeys = [...new Set(rows.flatMap((r) => Object.keys(r)))];
1489
+ const numericCols = allKeys.filter((key) => {
1490
+ const vals = rows.map((r) => r[key]).filter((v) => v != null && v !== "");
1491
+ return vals.length > 0 && vals.every((v) => !Number.isNaN(Number(v)));
1492
+ });
1493
+ const statNames = ["count", "mean", "std", "min", "25%", "50%", "75%", "max"];
1494
+ const result = statNames.map((stat) => {
1495
+ const row = { stat };
1496
+ for (const col of numericCols) {
1497
+ const values = rows
1498
+ .map((r) => Number(r[col]))
1499
+ .filter((n) => Number.isFinite(n))
1500
+ .sort((a, b) => a - b);
1501
+ const n = values.length;
1502
+ const s = sum(values);
1503
+ const m = n > 0 ? s / n : 0;
1504
+ const variance = n > 1 ? values.reduce((acc, v) => acc + (v - m) ** 2, 0) / (n - 1) : 0;
1505
+ const percentile = (p) => {
1506
+ if (n === 0)
1507
+ return 0;
1508
+ if (n === 1)
1509
+ return values[0];
1510
+ const idx = (p / 100) * (n - 1);
1511
+ const lo = Math.floor(idx);
1512
+ const hi = Math.ceil(idx);
1513
+ if (lo === hi)
1514
+ return values[lo];
1515
+ return values[lo] + (values[hi] - values[lo]) * (idx - lo);
1516
+ };
1517
+ const round4 = (v) => Math.round(v * 10000) / 10000;
1518
+ switch (stat) {
1519
+ case "count":
1520
+ row[col] = n;
1521
+ break;
1522
+ case "mean":
1523
+ row[col] = round4(m);
1524
+ break;
1525
+ case "std":
1526
+ row[col] = round4(Math.sqrt(variance));
1527
+ break;
1528
+ case "min":
1529
+ row[col] = n > 0 ? values[0] : 0;
1530
+ break;
1531
+ case "25%":
1532
+ row[col] = round4(percentile(25));
1533
+ break;
1534
+ case "50%":
1535
+ row[col] = round4(percentile(50));
1536
+ break;
1537
+ case "75%":
1538
+ row[col] = round4(percentile(75));
1539
+ break;
1540
+ case "max":
1541
+ row[col] = n > 0 ? values[n - 1] : 0;
1542
+ break;
1543
+ }
1544
+ }
1545
+ return row;
1546
+ });
1547
+ return { output: toDataframe(result) };
1548
+ }
1549
+ }
1550
+ __decorate([
1551
+ prop({
1552
+ type: "dataframe",
1553
+ default: { rows: [] },
1554
+ title: "Dataframe",
1555
+ description: "The dataframe to describe."
1556
+ })
1557
+ ], DescribeNode.prototype, "dataframe", void 0);
1558
+ export const DATA_NODES = [
1559
+ SchemaNode,
1560
+ FilterDataframeNode,
1561
+ SliceDataframeNode,
1562
+ SaveDataframeNode,
1563
+ ImportCSVNode,
1564
+ LoadCSVURLNode,
1565
+ LoadCSVFileDataNode,
1566
+ FromListNode,
1567
+ JSONToDataframeNode,
1568
+ ToListNode,
1569
+ SelectColumnNode,
1570
+ ExtractColumnNode,
1571
+ AddColumnNode,
1572
+ MergeDataframeNode,
1573
+ AppendDataframeNode,
1574
+ JoinDataframeNode,
1575
+ RowIteratorNode,
1576
+ FindRowNode,
1577
+ SortByColumnNode,
1578
+ DropDuplicatesNode,
1579
+ DropNANode,
1580
+ ForEachRowNode,
1581
+ LoadCSVAssetsNode,
1582
+ AggregateNode,
1583
+ PivotNode,
1584
+ RenameNode,
1585
+ FillNANode,
1586
+ SaveCSVDataframeFileNode,
1587
+ FilterNoneNode,
1588
+ DescribeNode
1589
+ ];
1590
+ //# sourceMappingURL=data.js.map