rowpipe 2.2.0 → 2.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (345) hide show
  1. package/README.md +35 -4
  2. package/dist/analytics/abtest.d.ts +39 -0
  3. package/dist/analytics/abtest.d.ts.map +1 -0
  4. package/dist/analytics/abtest.js +266 -0
  5. package/dist/analytics/abtest.js.map +1 -0
  6. package/dist/analytics/cluster.d.ts +25 -0
  7. package/dist/analytics/cluster.d.ts.map +1 -0
  8. package/dist/analytics/cluster.js +212 -0
  9. package/dist/analytics/cluster.js.map +1 -0
  10. package/dist/analytics/cohort.d.ts +22 -0
  11. package/dist/analytics/cohort.d.ts.map +1 -0
  12. package/dist/analytics/cohort.js +170 -0
  13. package/dist/analytics/cohort.js.map +1 -0
  14. package/dist/analytics/correlation.d.ts +15 -0
  15. package/dist/analytics/correlation.d.ts.map +1 -0
  16. package/dist/analytics/correlation.js +116 -0
  17. package/dist/analytics/correlation.js.map +1 -0
  18. package/dist/analytics/crosstab.d.ts +27 -0
  19. package/dist/analytics/crosstab.d.ts.map +1 -0
  20. package/dist/analytics/crosstab.js +90 -0
  21. package/dist/analytics/crosstab.js.map +1 -0
  22. package/dist/analytics/entropy.d.ts +23 -0
  23. package/dist/analytics/entropy.d.ts.map +1 -0
  24. package/dist/analytics/entropy.js +180 -0
  25. package/dist/analytics/entropy.js.map +1 -0
  26. package/dist/analytics/funnel.d.ts +29 -0
  27. package/dist/analytics/funnel.d.ts.map +1 -0
  28. package/dist/analytics/funnel.js +170 -0
  29. package/dist/analytics/funnel.js.map +1 -0
  30. package/dist/analytics/ngrams.d.ts +25 -0
  31. package/dist/analytics/ngrams.d.ts.map +1 -0
  32. package/dist/analytics/ngrams.js +110 -0
  33. package/dist/analytics/ngrams.js.map +1 -0
  34. package/dist/analytics/outliers.d.ts +25 -0
  35. package/dist/analytics/outliers.d.ts.map +1 -0
  36. package/dist/analytics/outliers.js +114 -0
  37. package/dist/analytics/outliers.js.map +1 -0
  38. package/dist/analytics/pareto.d.ts +36 -0
  39. package/dist/analytics/pareto.d.ts.map +1 -0
  40. package/dist/analytics/pareto.js +140 -0
  41. package/dist/analytics/pareto.js.map +1 -0
  42. package/dist/analytics/quantiles.d.ts +18 -0
  43. package/dist/analytics/quantiles.d.ts.map +1 -0
  44. package/dist/analytics/quantiles.js +62 -0
  45. package/dist/analytics/quantiles.js.map +1 -0
  46. package/dist/analytics/regression.d.ts +18 -0
  47. package/dist/analytics/regression.d.ts.map +1 -0
  48. package/dist/analytics/regression.js +79 -0
  49. package/dist/analytics/regression.js.map +1 -0
  50. package/dist/analytics/rfm.d.ts +41 -0
  51. package/dist/analytics/rfm.d.ts.map +1 -0
  52. package/dist/analytics/rfm.js +221 -0
  53. package/dist/analytics/rfm.js.map +1 -0
  54. package/dist/analytics/stats.d.ts.map +1 -1
  55. package/dist/analytics/stats.js +65 -15
  56. package/dist/analytics/stats.js.map +1 -1
  57. package/dist/analytics/technical.d.ts +19 -0
  58. package/dist/analytics/technical.d.ts.map +1 -0
  59. package/dist/analytics/technical.js +365 -0
  60. package/dist/analytics/technical.js.map +1 -0
  61. package/dist/cli/commands/abtest.d.ts +10 -0
  62. package/dist/cli/commands/abtest.d.ts.map +1 -0
  63. package/dist/cli/commands/abtest.js +68 -0
  64. package/dist/cli/commands/abtest.js.map +1 -0
  65. package/dist/cli/commands/cluster.d.ts +9 -0
  66. package/dist/cli/commands/cluster.d.ts.map +1 -0
  67. package/dist/cli/commands/cluster.js +77 -0
  68. package/dist/cli/commands/cluster.js.map +1 -0
  69. package/dist/cli/commands/cohort.d.ts +10 -0
  70. package/dist/cli/commands/cohort.d.ts.map +1 -0
  71. package/dist/cli/commands/cohort.js +66 -0
  72. package/dist/cli/commands/cohort.js.map +1 -0
  73. package/dist/cli/commands/completion.d.ts +5 -0
  74. package/dist/cli/commands/completion.d.ts.map +1 -0
  75. package/dist/cli/commands/completion.js +7 -0
  76. package/dist/cli/commands/completion.js.map +1 -0
  77. package/dist/cli/commands/concat.d.ts +9 -0
  78. package/dist/cli/commands/concat.d.ts.map +1 -0
  79. package/dist/cli/commands/concat.js +62 -0
  80. package/dist/cli/commands/concat.js.map +1 -0
  81. package/dist/cli/commands/convert.d.ts +2 -0
  82. package/dist/cli/commands/convert.d.ts.map +1 -1
  83. package/dist/cli/commands/convert.js.map +1 -1
  84. package/dist/cli/commands/corr.d.ts +7 -0
  85. package/dist/cli/commands/corr.d.ts.map +1 -0
  86. package/dist/cli/commands/corr.js +70 -0
  87. package/dist/cli/commands/corr.js.map +1 -0
  88. package/dist/cli/commands/crosstab.d.ts +11 -0
  89. package/dist/cli/commands/crosstab.d.ts.map +1 -0
  90. package/dist/cli/commands/crosstab.js +71 -0
  91. package/dist/cli/commands/crosstab.js.map +1 -0
  92. package/dist/cli/commands/entropy.d.ts +9 -0
  93. package/dist/cli/commands/entropy.d.ts.map +1 -0
  94. package/dist/cli/commands/entropy.js +71 -0
  95. package/dist/cli/commands/entropy.js.map +1 -0
  96. package/dist/cli/commands/explode.d.ts +8 -0
  97. package/dist/cli/commands/explode.d.ts.map +1 -0
  98. package/dist/cli/commands/explode.js +61 -0
  99. package/dist/cli/commands/explode.js.map +1 -0
  100. package/dist/cli/commands/fetch.d.ts +8 -0
  101. package/dist/cli/commands/fetch.d.ts.map +1 -0
  102. package/dist/cli/commands/fetch.js +41 -0
  103. package/dist/cli/commands/fetch.js.map +1 -0
  104. package/dist/cli/commands/files.d.ts +1 -1
  105. package/dist/cli/commands/files.d.ts.map +1 -1
  106. package/dist/cli/commands/flatten.d.ts +8 -0
  107. package/dist/cli/commands/flatten.d.ts.map +1 -0
  108. package/dist/cli/commands/flatten.js +57 -0
  109. package/dist/cli/commands/flatten.js.map +1 -0
  110. package/dist/cli/commands/freq.d.ts +10 -0
  111. package/dist/cli/commands/freq.d.ts.map +1 -0
  112. package/dist/cli/commands/freq.js +122 -0
  113. package/dist/cli/commands/freq.js.map +1 -0
  114. package/dist/cli/commands/funnel.d.ts +11 -0
  115. package/dist/cli/commands/funnel.d.ts.map +1 -0
  116. package/dist/cli/commands/funnel.js +69 -0
  117. package/dist/cli/commands/funnel.js.map +1 -0
  118. package/dist/cli/commands/fuzzy-join.d.ts +25 -0
  119. package/dist/cli/commands/fuzzy-join.d.ts.map +1 -0
  120. package/dist/cli/commands/fuzzy-join.js +85 -0
  121. package/dist/cli/commands/fuzzy-join.js.map +1 -0
  122. package/dist/cli/commands/generate.d.ts +8 -0
  123. package/dist/cli/commands/generate.d.ts.map +1 -0
  124. package/dist/cli/commands/generate.js +34 -0
  125. package/dist/cli/commands/generate.js.map +1 -0
  126. package/dist/cli/commands/mask.d.ts +6 -0
  127. package/dist/cli/commands/mask.d.ts.map +1 -0
  128. package/dist/cli/commands/mask.js +58 -0
  129. package/dist/cli/commands/mask.js.map +1 -0
  130. package/dist/cli/commands/ngrams.d.ts +11 -0
  131. package/dist/cli/commands/ngrams.d.ts.map +1 -0
  132. package/dist/cli/commands/ngrams.js +70 -0
  133. package/dist/cli/commands/ngrams.js.map +1 -0
  134. package/dist/cli/commands/outliers.d.ts +13 -0
  135. package/dist/cli/commands/outliers.d.ts.map +1 -0
  136. package/dist/cli/commands/outliers.js +58 -0
  137. package/dist/cli/commands/outliers.js.map +1 -0
  138. package/dist/cli/commands/pareto.d.ts +8 -0
  139. package/dist/cli/commands/pareto.d.ts.map +1 -0
  140. package/dist/cli/commands/pareto.js +80 -0
  141. package/dist/cli/commands/pareto.js.map +1 -0
  142. package/dist/cli/commands/partition.d.ts +8 -0
  143. package/dist/cli/commands/partition.d.ts.map +1 -0
  144. package/dist/cli/commands/partition.js +44 -0
  145. package/dist/cli/commands/partition.js.map +1 -0
  146. package/dist/cli/commands/pipeline.d.ts +6 -0
  147. package/dist/cli/commands/pipeline.d.ts.map +1 -1
  148. package/dist/cli/commands/pipeline.js +22 -0
  149. package/dist/cli/commands/pipeline.js.map +1 -1
  150. package/dist/cli/commands/pivot.d.ts +11 -0
  151. package/dist/cli/commands/pivot.d.ts.map +1 -0
  152. package/dist/cli/commands/pivot.js +58 -0
  153. package/dist/cli/commands/pivot.js.map +1 -0
  154. package/dist/cli/commands/plot.d.ts +12 -0
  155. package/dist/cli/commands/plot.d.ts.map +1 -0
  156. package/dist/cli/commands/plot.js +123 -0
  157. package/dist/cli/commands/plot.js.map +1 -0
  158. package/dist/cli/commands/quantiles.d.ts +7 -0
  159. package/dist/cli/commands/quantiles.d.ts.map +1 -0
  160. package/dist/cli/commands/quantiles.js +94 -0
  161. package/dist/cli/commands/quantiles.js.map +1 -0
  162. package/dist/cli/commands/regression.d.ts +7 -0
  163. package/dist/cli/commands/regression.d.ts.map +1 -0
  164. package/dist/cli/commands/regression.js +86 -0
  165. package/dist/cli/commands/regression.js.map +1 -0
  166. package/dist/cli/commands/report.d.ts +8 -0
  167. package/dist/cli/commands/report.d.ts.map +1 -0
  168. package/dist/cli/commands/report.js +36 -0
  169. package/dist/cli/commands/report.js.map +1 -0
  170. package/dist/cli/commands/rfm.d.ts +11 -0
  171. package/dist/cli/commands/rfm.d.ts.map +1 -0
  172. package/dist/cli/commands/rfm.js +78 -0
  173. package/dist/cli/commands/rfm.js.map +1 -0
  174. package/dist/cli/commands/serve.d.ts +7 -0
  175. package/dist/cli/commands/serve.d.ts.map +1 -0
  176. package/dist/cli/commands/serve.js +43 -0
  177. package/dist/cli/commands/serve.js.map +1 -0
  178. package/dist/cli/commands/split.d.ts +8 -0
  179. package/dist/cli/commands/split.d.ts.map +1 -0
  180. package/dist/cli/commands/split.js +43 -0
  181. package/dist/cli/commands/split.js.map +1 -0
  182. package/dist/cli/commands/table.d.ts +9 -0
  183. package/dist/cli/commands/table.d.ts.map +1 -0
  184. package/dist/cli/commands/table.js +9 -0
  185. package/dist/cli/commands/table.js.map +1 -0
  186. package/dist/cli/commands/technical.d.ts +8 -0
  187. package/dist/cli/commands/technical.d.ts.map +1 -0
  188. package/dist/cli/commands/technical.js +54 -0
  189. package/dist/cli/commands/technical.js.map +1 -0
  190. package/dist/cli/commands/test.d.ts +7 -0
  191. package/dist/cli/commands/test.d.ts.map +1 -0
  192. package/dist/cli/commands/test.js +53 -0
  193. package/dist/cli/commands/test.js.map +1 -0
  194. package/dist/cli/commands/timeseries.d.ts +11 -0
  195. package/dist/cli/commands/timeseries.d.ts.map +1 -0
  196. package/dist/cli/commands/timeseries.js +82 -0
  197. package/dist/cli/commands/timeseries.js.map +1 -0
  198. package/dist/cli/commands/unpivot.d.ts +12 -0
  199. package/dist/cli/commands/unpivot.d.ts.map +1 -0
  200. package/dist/cli/commands/unpivot.js +59 -0
  201. package/dist/cli/commands/unpivot.js.map +1 -0
  202. package/dist/cli/completion.d.ts +5 -0
  203. package/dist/cli/completion.d.ts.map +1 -0
  204. package/dist/cli/completion.js +194 -0
  205. package/dist/cli/completion.js.map +1 -0
  206. package/dist/cli/index.js +816 -15
  207. package/dist/cli/index.js.map +1 -1
  208. package/dist/core/error-handler.d.ts +38 -0
  209. package/dist/core/error-handler.d.ts.map +1 -0
  210. package/dist/core/error-handler.js +81 -0
  211. package/dist/core/error-handler.js.map +1 -0
  212. package/dist/core/pipeline.d.ts +10 -0
  213. package/dist/core/pipeline.d.ts.map +1 -1
  214. package/dist/core/pipeline.js +14 -0
  215. package/dist/core/pipeline.js.map +1 -1
  216. package/dist/core/types.d.ts +4 -0
  217. package/dist/core/types.d.ts.map +1 -1
  218. package/dist/dataops/fetch.d.ts +27 -0
  219. package/dist/dataops/fetch.d.ts.map +1 -0
  220. package/dist/dataops/fetch.js +150 -0
  221. package/dist/dataops/fetch.js.map +1 -0
  222. package/dist/dataops/generate.d.ts +16 -0
  223. package/dist/dataops/generate.d.ts.map +1 -0
  224. package/dist/dataops/generate.js +201 -0
  225. package/dist/dataops/generate.js.map +1 -0
  226. package/dist/dataops/mask.d.ts +25 -0
  227. package/dist/dataops/mask.d.ts.map +1 -0
  228. package/dist/dataops/mask.js +133 -0
  229. package/dist/dataops/mask.js.map +1 -0
  230. package/dist/dataops/report.d.ts +7 -0
  231. package/dist/dataops/report.d.ts.map +1 -0
  232. package/dist/dataops/report.js +139 -0
  233. package/dist/dataops/report.js.map +1 -0
  234. package/dist/dataops/server.d.ts +10 -0
  235. package/dist/dataops/server.d.ts.map +1 -0
  236. package/dist/dataops/server.js +137 -0
  237. package/dist/dataops/server.js.map +1 -0
  238. package/dist/dataops/test-runner.d.ts +34 -0
  239. package/dist/dataops/test-runner.d.ts.map +1 -0
  240. package/dist/dataops/test-runner.js +128 -0
  241. package/dist/dataops/test-runner.js.map +1 -0
  242. package/dist/db/adapters/sqlite.d.ts +2 -1
  243. package/dist/db/adapters/sqlite.d.ts.map +1 -1
  244. package/dist/db/adapters/sqlite.js +54 -20
  245. package/dist/db/adapters/sqlite.js.map +1 -1
  246. package/dist/diff/engine.d.ts.map +1 -1
  247. package/dist/diff/engine.js +73 -16
  248. package/dist/diff/engine.js.map +1 -1
  249. package/dist/diff/storage/disk-index.d.ts +10 -1
  250. package/dist/diff/storage/disk-index.d.ts.map +1 -1
  251. package/dist/diff/storage/disk-index.js +95 -13
  252. package/dist/diff/storage/disk-index.js.map +1 -1
  253. package/dist/files/hash.d.ts +9 -2
  254. package/dist/files/hash.d.ts.map +1 -1
  255. package/dist/files/hash.js +9 -10
  256. package/dist/files/hash.js.map +1 -1
  257. package/dist/files/reader.d.ts.map +1 -1
  258. package/dist/files/reader.js +17 -10
  259. package/dist/files/reader.js.map +1 -1
  260. package/dist/files/types.d.ts +2 -1
  261. package/dist/files/types.d.ts.map +1 -1
  262. package/dist/index.d.ts +65 -1
  263. package/dist/index.d.ts.map +1 -1
  264. package/dist/index.js +66 -1
  265. package/dist/index.js.map +1 -1
  266. package/dist/planner/executor.d.ts.map +1 -1
  267. package/dist/planner/executor.js +17 -0
  268. package/dist/planner/executor.js.map +1 -1
  269. package/dist/planner/types.d.ts +11 -0
  270. package/dist/planner/types.d.ts.map +1 -1
  271. package/dist/readers/csv.d.ts.map +1 -1
  272. package/dist/readers/csv.js +206 -164
  273. package/dist/readers/csv.js.map +1 -1
  274. package/dist/readers/json.d.ts.map +1 -1
  275. package/dist/readers/json.js +145 -121
  276. package/dist/readers/json.js.map +1 -1
  277. package/dist/readers/jsonl.d.ts.map +1 -1
  278. package/dist/readers/jsonl.js +51 -31
  279. package/dist/readers/jsonl.js.map +1 -1
  280. package/dist/rowpipe +4 -0
  281. package/dist/transforms/concat.d.ts +26 -0
  282. package/dist/transforms/concat.d.ts.map +1 -0
  283. package/dist/transforms/concat.js +57 -0
  284. package/dist/transforms/concat.js.map +1 -0
  285. package/dist/transforms/explode.d.ts +14 -0
  286. package/dist/transforms/explode.d.ts.map +1 -0
  287. package/dist/transforms/explode.js +81 -0
  288. package/dist/transforms/explode.js.map +1 -0
  289. package/dist/transforms/flatten.d.ts +12 -0
  290. package/dist/transforms/flatten.d.ts.map +1 -0
  291. package/dist/transforms/flatten.js +65 -0
  292. package/dist/transforms/flatten.js.map +1 -0
  293. package/dist/transforms/fuzzy-join.d.ts +53 -0
  294. package/dist/transforms/fuzzy-join.d.ts.map +1 -0
  295. package/dist/transforms/fuzzy-join.js +347 -0
  296. package/dist/transforms/fuzzy-join.js.map +1 -0
  297. package/dist/transforms/jit-compiler.d.ts.map +1 -1
  298. package/dist/transforms/jit-compiler.js +103 -14
  299. package/dist/transforms/jit-compiler.js.map +1 -1
  300. package/dist/transforms/join/index-storage.d.ts +8 -5
  301. package/dist/transforms/join/index-storage.d.ts.map +1 -1
  302. package/dist/transforms/join/index-storage.js +91 -54
  303. package/dist/transforms/join/index-storage.js.map +1 -1
  304. package/dist/transforms/map.d.ts +6 -2
  305. package/dist/transforms/map.d.ts.map +1 -1
  306. package/dist/transforms/map.js +64 -26
  307. package/dist/transforms/map.js.map +1 -1
  308. package/dist/transforms/partition.d.ts +35 -0
  309. package/dist/transforms/partition.d.ts.map +1 -0
  310. package/dist/transforms/partition.js +150 -0
  311. package/dist/transforms/partition.js.map +1 -0
  312. package/dist/transforms/pivot.d.ts +16 -0
  313. package/dist/transforms/pivot.d.ts.map +1 -0
  314. package/dist/transforms/pivot.js +194 -0
  315. package/dist/transforms/pivot.js.map +1 -0
  316. package/dist/transforms/sort/comparator.d.ts.map +1 -1
  317. package/dist/transforms/sort/comparator.js +153 -24
  318. package/dist/transforms/sort/comparator.js.map +1 -1
  319. package/dist/transforms/sort/external-sort.js +1 -1
  320. package/dist/transforms/sort/external-sort.js.map +1 -1
  321. package/dist/transforms/split.d.ts +17 -0
  322. package/dist/transforms/split.d.ts.map +1 -0
  323. package/dist/transforms/split.js +88 -0
  324. package/dist/transforms/split.js.map +1 -0
  325. package/dist/transforms/timeseries.d.ts +42 -0
  326. package/dist/transforms/timeseries.d.ts.map +1 -0
  327. package/dist/transforms/timeseries.js +276 -0
  328. package/dist/transforms/timeseries.js.map +1 -0
  329. package/dist/transforms/unpivot.d.ts +14 -0
  330. package/dist/transforms/unpivot.d.ts.map +1 -0
  331. package/dist/transforms/unpivot.js +56 -0
  332. package/dist/transforms/unpivot.js.map +1 -0
  333. package/dist/ui/chart.d.ts +30 -0
  334. package/dist/ui/chart.d.ts.map +1 -0
  335. package/dist/ui/chart.js +91 -0
  336. package/dist/ui/chart.js.map +1 -0
  337. package/dist/writers/index.d.ts +1 -0
  338. package/dist/writers/index.d.ts.map +1 -1
  339. package/dist/writers/index.js +10 -0
  340. package/dist/writers/index.js.map +1 -1
  341. package/dist/writers/table.d.ts +23 -0
  342. package/dist/writers/table.d.ts.map +1 -0
  343. package/dist/writers/table.js +156 -0
  344. package/dist/writers/table.js.map +1 -0
  345. package/package.json +6 -3
package/dist/cli/index.js CHANGED
@@ -1,4 +1,16 @@
1
1
  #!/usr/bin/env node
2
+ // Suppress internal Node SEA and experimental embedder warnings in production CLI
3
+ const _origEmitWarning = process.emitWarning;
4
+ process.emitWarning = function (warning, ...args) {
5
+ const msg = typeof warning === "string" ? warning : (warning && warning.message) || "";
6
+ if (msg.includes("single-executable") ||
7
+ msg.includes("ExperimentalWarning") ||
8
+ msg.includes("require() provided to the main script embedded")) {
9
+ return;
10
+ }
11
+ return Reflect.apply(_origEmitWarning, process, [warning, ...args]);
12
+ };
13
+ import { existsSync } from "node:fs";
2
14
  import { Command } from "commander";
3
15
  import { RowpipeError } from "../core/errors.js";
4
16
  import { castCommand } from "./commands/cast.js";
@@ -32,6 +44,39 @@ import { uniqueCommand } from "./commands/unique.js";
32
44
  import { validateCommand } from "./commands/validate.js";
33
45
  import { windowCommand } from "./commands/window.js";
34
46
  import { viewCommand } from "./commands/view.js";
47
+ import { explodeCommand } from "./commands/explode.js";
48
+ import { flattenCommand } from "./commands/flatten.js";
49
+ import { freqCommand } from "./commands/freq.js";
50
+ import { plotCommand } from "./commands/plot.js";
51
+ import { tableCommand } from "./commands/table.js";
52
+ import { completionCommand } from "./commands/completion.js";
53
+ import { partitionCommand } from "./commands/partition.js";
54
+ import { splitCommand } from "./commands/split.js";
55
+ import { timeseriesCommand } from "./commands/timeseries.js";
56
+ import { corrCommand } from "./commands/corr.js";
57
+ import { quantilesCommand } from "./commands/quantiles.js";
58
+ import { outliersCommand } from "./commands/outliers.js";
59
+ import { crosstabCommand } from "./commands/crosstab.js";
60
+ import { regressionCommand } from "./commands/regression.js";
61
+ import { rfmCommand } from "./commands/rfm.js";
62
+ import { cohortCommand } from "./commands/cohort.js";
63
+ import { funnelCommand } from "./commands/funnel.js";
64
+ import { abTestCommand } from "./commands/abtest.js";
65
+ import { paretoCommand } from "./commands/pareto.js";
66
+ import { technicalCommand } from "./commands/technical.js";
67
+ import { clusterCommand } from "./commands/cluster.js";
68
+ import { entropyCommand } from "./commands/entropy.js";
69
+ import { ngramsCommand } from "./commands/ngrams.js";
70
+ import { pivotCommand } from "./commands/pivot.js";
71
+ import { unpivotCommand } from "./commands/unpivot.js";
72
+ import { fuzzyJoinCommand } from "./commands/fuzzy-join.js";
73
+ import { concatCommand } from "./commands/concat.js";
74
+ import { generateCommand } from "./commands/generate.js";
75
+ import { maskCommand } from "./commands/mask.js";
76
+ import { testCommand } from "./commands/test.js";
77
+ import { serveCommand } from "./commands/serve.js";
78
+ import { reportCommand } from "./commands/report.js";
79
+ import { fetchCommand } from "./commands/fetch.js";
35
80
  // Handle broken pipe gracefully when piping to head/less
36
81
  process.stdout.on("error", (err) => {
37
82
  if (err.code === "EPIPE") {
@@ -42,7 +87,7 @@ const program = new Command();
42
87
  program
43
88
  .name("rowpipe")
44
89
  .description("Stream-first tabular data toolkit for CSV, TSV, JSON, JSONL, XLSX, Parquet, and Markdown")
45
- .version("2.0.0");
90
+ .version("2.10.0");
46
91
  // Global & Pipeline options on root command
47
92
  program
48
93
  .argument("[input]", "Input dataset file path or '-' for stdin")
@@ -53,6 +98,9 @@ program
53
98
  .option("--map <specs...>", "Derive new columns (col=expr)")
54
99
  .option("--window <specs...>", "Compute sliding window/rolling values (col=fn(...))", (val, prev = []) => [...prev, val])
55
100
  .option("--partition-by <columns>", "Partition window functions by columns (comma-separated)")
101
+ .option("--explode <column>", "Expand delimited or array column into multiple rows", (val, prev = []) => [...prev, val])
102
+ .option("--explode-delimiter <delim>", "Delimiter for string exploding (default: ',')")
103
+ .option("--flatten [sep]", "Flatten nested JSON objects into flat dot-notated columns")
56
104
  .option("--add-filename", "Inject source filename into records as '_file' column")
57
105
  .option("--file-col <name>", "Custom column name for injected filename")
58
106
  .option("--sort <specs>", "Sort stream by columns (--sort country,revenue:desc)")
@@ -98,8 +146,14 @@ program
98
146
  .option("--dry-run", "Print generated DDL/SQL without executing")
99
147
  .option("--quiet", "Suppress non-data output and progress")
100
148
  .option("--no-progress", "Disable real-time progress bar")
149
+ .option("--on-error <strategy>", "Error handling strategy: abort (default), skip, or log", "abort")
150
+ .option("--bad-rows-log <file>", "Write malformed or rejected rows to dead-letter log file")
101
151
  .action(async (input = "-", cmdOptions) => {
102
- // If running root command with flags
152
+ // If running root command with no input file and stdin is an interactive TTY, display help
153
+ if (input === "-" && process.stdin.isTTY) {
154
+ program.outputHelp();
155
+ return;
156
+ }
103
157
  await unifiedPipelineCommand(input, cmdOptions);
104
158
  });
105
159
  // 1. inspect
@@ -130,6 +184,8 @@ program
130
184
  .option("--path <path>", "Nested path for JSON array")
131
185
  .option("--delimiter <delim>", "Custom CSV delimiter")
132
186
  .option("--no-header", "Disable writing or reading headers in CSV")
187
+ .option("--on-error <strategy>", "Error handling strategy: abort (default), skip, or log")
188
+ .option("--bad-rows-log <file>", "Write malformed or rejected rows to dead-letter log file")
133
189
  .action(async (input = "-", output, cmdOptions) => {
134
190
  const opts = { ...program.opts(), ...cmdOptions };
135
191
  await convertCommand(input, output, opts);
@@ -467,33 +523,59 @@ program
467
523
  });
468
524
  // 18. head
469
525
  program
470
- .command("head [input]")
526
+ .command("head [input] [lines]")
471
527
  .description("Emit first N rows of stream (default: 10)")
472
528
  .option("-n, --lines <number>", "Number of rows to emit", "10")
473
529
  .option("--from <format>", "Input format")
474
530
  .option("--to <format>", "Output format")
475
531
  .option("--sheet <sheet>", "Worksheet name for XLSX")
476
532
  .option("--delimiter <delim>", "Custom CSV delimiter")
477
- .action(async (input = "-", cmdOptions) => {
478
- const opts = { ...program.opts(), ...cmdOptions };
533
+ .action(async (inputOrLines, maybeLines, cmdOptions) => {
534
+ let input = "-";
535
+ let lines = cmdOptions.lines;
536
+ if (maybeLines !== undefined) {
537
+ input = inputOrLines || "-";
538
+ lines = maybeLines;
539
+ }
540
+ else if (inputOrLines !== undefined && !Number.isNaN(Number(inputOrLines))) {
541
+ lines = inputOrLines;
542
+ input = "-";
543
+ }
544
+ else if (inputOrLines !== undefined) {
545
+ input = inputOrLines;
546
+ }
547
+ const opts = { ...program.opts(), ...cmdOptions, lines: lines ?? cmdOptions.lines ?? "10" };
479
548
  await headCommand(input, opts);
480
549
  });
481
550
  // 19. tail
482
551
  program
483
- .command("tail [input]")
552
+ .command("tail [input] [lines]")
484
553
  .description("Emit last N rows of stream using bounded memory ring buffer (default: 10)")
485
554
  .option("-n, --lines <number>", "Number of rows to emit", "10")
486
555
  .option("--from <format>", "Input format")
487
556
  .option("--to <format>", "Output format")
488
557
  .option("--sheet <sheet>", "Worksheet name for XLSX")
489
558
  .option("--delimiter <delim>", "Custom CSV delimiter")
490
- .action(async (input = "-", cmdOptions) => {
491
- const opts = { ...program.opts(), ...cmdOptions };
559
+ .action(async (inputOrLines, maybeLines, cmdOptions) => {
560
+ let input = "-";
561
+ let lines = cmdOptions.lines;
562
+ if (maybeLines !== undefined) {
563
+ input = inputOrLines || "-";
564
+ lines = maybeLines;
565
+ }
566
+ else if (inputOrLines !== undefined && !Number.isNaN(Number(inputOrLines))) {
567
+ lines = inputOrLines;
568
+ input = "-";
569
+ }
570
+ else if (inputOrLines !== undefined) {
571
+ input = inputOrLines;
572
+ }
573
+ const opts = { ...program.opts(), ...cmdOptions, lines: lines ?? cmdOptions.lines ?? "10" };
492
574
  await tailCommand(input, opts);
493
575
  });
494
576
  // 20. sort
495
577
  program
496
- .command("sort [input]")
578
+ .command("sort [input] [specs]")
497
579
  .description("Sort stream by columns with typed comparisons and external merge sort on large files")
498
580
  .option("--by <specs>", "Sort columns (e.g. country,revenue:desc or age:desc)")
499
581
  .option("--nulls <placement>", "Null sorting placement: first or last", "last")
@@ -505,15 +587,28 @@ program
505
587
  .option("--to <format>", "Output format")
506
588
  .option("--sheet <sheet>", "Worksheet name for XLSX")
507
589
  .option("--delimiter <delim>", "Custom CSV delimiter")
508
- .action(async (input = "-", cmdOptions) => {
509
- const opts = { ...program.opts(), ...cmdOptions };
590
+ .action(async (inputOrSpecs, maybeSpecs, cmdOptions) => {
591
+ let input = "-";
592
+ let by = cmdOptions.by;
593
+ if (maybeSpecs !== undefined) {
594
+ input = inputOrSpecs || "-";
595
+ by = maybeSpecs;
596
+ }
597
+ else if (inputOrSpecs && (inputOrSpecs.includes(":") || (inputOrSpecs !== "-" && !existsSync(inputOrSpecs)))) {
598
+ by = inputOrSpecs;
599
+ input = "-";
600
+ }
601
+ else {
602
+ input = inputOrSpecs || "-";
603
+ }
604
+ const opts = { ...program.opts(), ...cmdOptions, by: by || cmdOptions.by };
510
605
  await sortCommand(input, opts);
511
606
  });
512
607
  // 21. top
513
608
  program
514
- .command("top [input]")
609
+ .command("top [input] [by] [lines]")
515
610
  .description("Retain top-N rows using bounded-memory binary heap (default: 10)")
516
- .requiredOption("--by <column>", "Sort column for ranking")
611
+ .option("--by <column>", "Sort column for ranking")
517
612
  .option("-n, --lines <number>", "Number of top rows to emit", "10")
518
613
  .option("--order <order>", "Sort order: asc or desc", "desc")
519
614
  .option("--smallest", "Emit smallest N rows (bottom-K) instead of largest")
@@ -524,8 +619,46 @@ program
524
619
  .option("--to <format>", "Output format")
525
620
  .option("--sheet <sheet>", "Worksheet name for XLSX")
526
621
  .option("--delimiter <delim>", "Custom CSV delimiter")
527
- .action(async (input = "-", cmdOptions) => {
528
- const opts = { ...program.opts(), ...cmdOptions };
622
+ .action(async (arg1, arg2, arg3, cmdOptions) => {
623
+ let input = "-";
624
+ let by = cmdOptions.by;
625
+ let lines = cmdOptions.lines;
626
+ if (arg3 !== undefined) {
627
+ input = arg1 || "-";
628
+ by = arg2;
629
+ lines = arg3;
630
+ }
631
+ else if (arg2 !== undefined) {
632
+ if (!Number.isNaN(Number(arg2))) {
633
+ if (arg1 && (arg1 === "-" || existsSync(arg1))) {
634
+ input = arg1;
635
+ lines = arg2;
636
+ }
637
+ else {
638
+ by = arg1;
639
+ lines = arg2;
640
+ }
641
+ }
642
+ else {
643
+ input = arg1 || "-";
644
+ by = arg2;
645
+ }
646
+ }
647
+ else if (arg1 !== undefined) {
648
+ if (!Number.isNaN(Number(arg1))) {
649
+ lines = arg1;
650
+ }
651
+ else if (arg1 === "-" || existsSync(arg1)) {
652
+ input = arg1;
653
+ }
654
+ else {
655
+ by = arg1;
656
+ }
657
+ }
658
+ const opts = { ...program.opts(), ...cmdOptions, by: by || cmdOptions.by, lines: lines || cmdOptions.lines || "10" };
659
+ if (!opts.by) {
660
+ throw new Error("Sort column is required for top command (e.g. rowpipe top netflix.csv revenue 10 or --by revenue)");
661
+ }
529
662
  await topCommand(input, opts);
530
663
  });
531
664
  // 22. unique
@@ -772,7 +905,675 @@ program
772
905
  const opts = { ...program.opts(), ...cmdOptions };
773
906
  await viewCommand(input, opts);
774
907
  });
908
+ // 32. explode
909
+ program
910
+ .command("explode [input] [column]")
911
+ .description("Expand array or delimited string column into multiple rows (1 -> N)")
912
+ .option("--delimiter <delim>", "Delimiter for splitting strings (default: ',')")
913
+ .option("--no-trim", "Do not trim whitespace around split values")
914
+ .option("--preserve-empty", "Preserve empty string elements")
915
+ .option("--from <format>", "Input format")
916
+ .option("--to <format>", "Output format")
917
+ .option("--sheet <sheet>", "Worksheet name for XLSX")
918
+ .option("--output <file>", "Write output to file")
919
+ .option("--json", "Output machine-readable JSON")
920
+ .option("--quiet", "Suppress non-data output")
921
+ .option("--no-progress", "Disable progress bar")
922
+ .action(async (inputOrCol, maybeCol, cmdOptions) => {
923
+ let input = "-";
924
+ let column = "";
925
+ if (maybeCol !== undefined) {
926
+ input = inputOrCol || "-";
927
+ column = maybeCol;
928
+ }
929
+ else {
930
+ column = inputOrCol || "";
931
+ }
932
+ const opts = { ...program.opts(), ...cmdOptions };
933
+ await explodeCommand(input, column, opts);
934
+ });
935
+ // 33. flatten
936
+ program
937
+ .command("flatten [input]")
938
+ .description("Flatten nested JSON objects into dot-notated columns")
939
+ .option("--separator <sep>", "Field separator for nested paths", ".")
940
+ .option("--max-depth <depth>", "Maximum recursion depth", "10")
941
+ .option("--arrays", "Flatten nested array indices as well")
942
+ .option("--from <format>", "Input format")
943
+ .option("--to <format>", "Output format")
944
+ .option("--output <file>", "Write output to file")
945
+ .option("--json", "Output machine-readable JSON")
946
+ .option("--quiet", "Suppress non-data output")
947
+ .option("--no-progress", "Disable progress bar")
948
+ .action(async (input = "-", cmdOptions) => {
949
+ const opts = { ...program.opts(), ...cmdOptions };
950
+ await flattenCommand(input, opts);
951
+ });
952
+ // 34. freq
953
+ program
954
+ .command("freq [input] [column]")
955
+ .description("Compute frequency distribution and value counts for a column")
956
+ .option("-n, --top <number>", "Number of top frequent values to show", "20")
957
+ .option("-c, --chart", "Render horizontal bar chart for frequencies")
958
+ .option("--width <number>", "Maximum bar chart width in characters", "30")
959
+ .option("--asc", "Sort by frequency ascending instead of descending")
960
+ .option("--no-nulls", "Exclude null/empty values from count")
961
+ .option("--json", "Output frequency table as JSON")
962
+ .option("--to <format>", "Output format (csv, json, jsonl, markdown, table)")
963
+ .option("--from <format>", "Input format")
964
+ .option("--output <file>", "Write output to file")
965
+ .action(async (inputOrCol, maybeCol, cmdOptions) => {
966
+ let input = "-";
967
+ let column = "";
968
+ if (maybeCol !== undefined) {
969
+ input = inputOrCol || "-";
970
+ column = maybeCol;
971
+ }
972
+ else {
973
+ column = inputOrCol || "";
974
+ }
975
+ const opts = { ...program.opts(), ...cmdOptions };
976
+ await freqCommand(input, column, opts);
977
+ });
978
+ // 35. plot / chart
979
+ program
980
+ .command("plot [input] [col1] [col2]")
981
+ .alias("chart")
982
+ .description("Render horizontal ASCII/Unicode bar charts and numeric histograms")
983
+ .option("-n, --top <number>", "Number of top categories to show", "20")
984
+ .option("--bins <number>", "Number of bins for numeric histogram", "10")
985
+ .option("--width <number>", "Maximum bar chart width in characters", "30")
986
+ .option("--numeric", "Force numeric histogram rendering")
987
+ .option("--categorical", "Force categorical frequency bar chart")
988
+ .option("--asc", "Sort ascending instead of descending")
989
+ .option("--no-nulls", "Exclude null/empty values")
990
+ .option("--from <format>", "Input format")
991
+ .option("--sheet <sheet>", "Worksheet name for XLSX")
992
+ .option("--delimiter <delim>", "Custom delimiter for CSV/TSV")
993
+ .action(async (inputOrCol1, maybeCol1, maybeCol2, cmdOptions) => {
994
+ let input = "-";
995
+ let col1;
996
+ let col2;
997
+ if (maybeCol2 !== undefined) {
998
+ input = inputOrCol1 || "-";
999
+ col1 = maybeCol1;
1000
+ col2 = maybeCol2;
1001
+ }
1002
+ else if (maybeCol1 !== undefined) {
1003
+ if (existsSync(inputOrCol1) || inputOrCol1.includes("/") || inputOrCol1.includes(".")) {
1004
+ input = inputOrCol1;
1005
+ col1 = maybeCol1;
1006
+ }
1007
+ else {
1008
+ input = "-";
1009
+ col1 = inputOrCol1;
1010
+ col2 = maybeCol1;
1011
+ }
1012
+ }
1013
+ else {
1014
+ input = "-";
1015
+ col1 = inputOrCol1;
1016
+ }
1017
+ const opts = { ...program.opts(), ...cmdOptions };
1018
+ await plotCommand(input, col1, col2, opts);
1019
+ });
1020
+ // 36. table
1021
+ program
1022
+ .command("table [input]")
1023
+ .description("Render dataset as pretty terminal grid table with Unicode/ASCII box drawing")
1024
+ .option("--style <style>", "Box border style (unicode, ascii, compact)", "unicode")
1025
+ .option("--max-width <number>", "Maximum column width before truncation", "40")
1026
+ .option("--max-buffer <number>", "Maximum rows to buffer for alignment", "5000")
1027
+ .option("--filter <expression>", "Filter rows using expression", (val, prev = []) => [...prev, val])
1028
+ .option("--select <columns>", "Project subset of columns")
1029
+ .option("--sort <specs>", "Sort stream by columns")
1030
+ .option("--limit <number>", "Limit number of rows emitted")
1031
+ .option("--offset <number>", "Skip first N rows")
1032
+ .option("--from <format>", "Input format")
1033
+ .option("--sheet <sheet>", "Worksheet name for XLSX")
1034
+ .option("--delimiter <delim>", "Custom delimiter for CSV/TSV")
1035
+ .action(async (input = "-", cmdOptions) => {
1036
+ const opts = { ...program.opts(), ...cmdOptions };
1037
+ await tableCommand(input, opts);
1038
+ });
1039
+ // 37. completion
1040
+ program
1041
+ .command("completion [shell]")
1042
+ .description("Generate shell autocompletion script (zsh, bash, fish)")
1043
+ .action(async (shell = "zsh", cmdOptions) => {
1044
+ const opts = { ...program.opts(), ...cmdOptions };
1045
+ await completionCommand(shell, opts);
1046
+ });
1047
+ // 38. partition
1048
+ program
1049
+ .command("partition [input]")
1050
+ .description("Partition dataset into dynamic files/directories based on column values")
1051
+ .option("--by <columns>", "Partition columns (e.g. country,release_year)")
1052
+ .option("-o, --out-pattern <pattern>", "Output file path template (e.g. 'dist/{country}/{release_year}.csv')")
1053
+ .option("--to <format>", "Output format (csv, json, jsonl, parquet)")
1054
+ .option("--max-open <number>", "Maximum open file descriptors pool", "50")
1055
+ .option("--from <format>", "Input format")
1056
+ .option("--sheet <sheet>", "Worksheet name for XLSX")
1057
+ .option("--delimiter <delim>", "Custom delimiter for CSV/TSV")
1058
+ .option("--quiet", "Suppress summary output")
1059
+ .action(async (input = "-", cmdOptions) => {
1060
+ const opts = { ...program.opts(), ...cmdOptions };
1061
+ await partitionCommand(input, opts);
1062
+ });
1063
+ // 39. split
1064
+ program
1065
+ .command("split [input]")
1066
+ .description("Split stream into sequential chunk files based on row count")
1067
+ .option("-n, --chunk-size <number>", "Number of rows per chunk file", "100000")
1068
+ .option("-o, --out-pattern <pattern>", "Output file path template (e.g. 'parts/chunk_{n:03d}.csv')")
1069
+ .option("--to <format>", "Output format (csv, json, jsonl, parquet)")
1070
+ .option("--from <format>", "Input format")
1071
+ .option("--sheet <sheet>", "Worksheet name for XLSX")
1072
+ .option("--delimiter <delim>", "Custom delimiter for CSV/TSV")
1073
+ .option("--quiet", "Suppress summary output")
1074
+ .action(async (input = "-", cmdOptions) => {
1075
+ const opts = { ...program.opts(), ...cmdOptions };
1076
+ await splitCommand(input, opts);
1077
+ });
1078
+ // 40. timeseries
1079
+ program
1080
+ .command("timeseries [input]")
1081
+ .description("Resample timeseries data into fixed time buckets and fill missing gaps")
1082
+ .option("-t, --time-col <col>", "Time/timestamp column name")
1083
+ .option("-i, --interval <window>", "Time interval window (e.g. 5s, 1m, 15m, 1h, 1d, 1w, 1mo, 1y)", "1m")
1084
+ .option("--agg <specs...>", "Aggregation specifications (e.g. avg(cpu),max(mem))", (val, prev = []) => [...prev, val])
1085
+ .option("--avg <columns>", "Average column values", (val, prev = []) => [...prev, val])
1086
+ .option("--sum <columns>", "Sum column values", (val, prev = []) => [...prev, val])
1087
+ .option("--min <columns>", "Minimum column values", (val, prev = []) => [...prev, val])
1088
+ .option("--max <columns>", "Maximum column values", (val, prev = []) => [...prev, val])
1089
+ .option("--first <columns>", "First column values", (val, prev = []) => [...prev, val])
1090
+ .option("--last <columns>", "Last column values", (val, prev = []) => [...prev, val])
1091
+ .option("--count", "Include count of records per time bucket")
1092
+ .option("--fill-gaps <method>", "Gap filling method: ffill, bfill, zero, null, linear")
1093
+ .option("--time-format <format>", "Output timestamp format: iso, epoch_ms, epoch_s, date_only", "iso")
1094
+ .option("--to <format>", "Output format (csv, json, jsonl, parquet, markdown, table)")
1095
+ .option("--from <format>", "Input format")
1096
+ .option("--output <file>", "Write output to file")
1097
+ .action(async (input = "-", cmdOptions) => {
1098
+ const opts = { ...program.opts(), ...cmdOptions };
1099
+ await timeseriesCommand(input, opts);
1100
+ });
1101
+ // 41. corr
1102
+ program
1103
+ .command("corr [input]")
1104
+ .description("Compute Pearson correlation matrix across numeric columns")
1105
+ .option("--cols <columns>", "Target columns (comma-separated)")
1106
+ .option("--from <format>", "Input format")
1107
+ .option("--to <format>", "Output format (csv, json, jsonl, markdown, table)")
1108
+ .option("--output <file>", "Write output to file")
1109
+ .option("--json", "Output machine-readable JSON")
1110
+ .action(async (input = "-", cmdOptions) => {
1111
+ const opts = { ...program.opts(), ...cmdOptions };
1112
+ await corrCommand(input, opts);
1113
+ });
1114
+ // 42. quantiles / percentiles
1115
+ program
1116
+ .command("quantiles [input] [column]")
1117
+ .alias("percentiles")
1118
+ .description("Compute streaming percentiles (P50, P90, P95, P99, P99.9, IQR, etc.)")
1119
+ .option("-p, --p <percentiles>", "Percentiles to calculate (e.g. 50,90,95,99)", "25,50,75,90,95,99")
1120
+ .option("--from <format>", "Input format")
1121
+ .option("--to <format>", "Output format")
1122
+ .option("--output <file>", "Write output to file")
1123
+ .option("--json", "Output machine-readable JSON")
1124
+ .action(async (inputOrCol, maybeCol, cmdOptions) => {
1125
+ let input = "-";
1126
+ let column = "";
1127
+ if (maybeCol !== undefined) {
1128
+ input = inputOrCol || "-";
1129
+ column = maybeCol;
1130
+ }
1131
+ else {
1132
+ column = inputOrCol || "";
1133
+ }
1134
+ const opts = { ...program.opts(), ...cmdOptions };
1135
+ await quantilesCommand(input, column, opts);
1136
+ });
1137
+ // 43. outliers / anomalies
1138
+ program
1139
+ .command("outliers [input] [column]")
1140
+ .alias("anomalies")
1141
+ .description("Detect and filter statistical outliers and anomalies using Z-Score, IQR, or MAD")
1142
+ .option("-c, --col <column>", "Target column name")
1143
+ .option("-m, --method <method>", "Method: zscore, iqr, mad", "zscore")
1144
+ .option("--threshold <number>", "Statistical threshold (default: 3.0 for zscore/mad, 1.5 for iqr)")
1145
+ .option("--only-outliers", "Filter stream to output only outlier rows")
1146
+ .option("--add-columns", "Append _is_outlier and _outlier_score columns")
1147
+ .option("--invert", "Emit only clean inlier rows")
1148
+ .option("--from <format>", "Input format")
1149
+ .option("--to <format>", "Output format")
1150
+ .option("--output <file>", "Write output to file")
1151
+ .option("--json", "Output machine-readable JSON")
1152
+ .action(async (inputOrCol, maybeCol, cmdOptions) => {
1153
+ let input = "-";
1154
+ let column = "";
1155
+ if (maybeCol !== undefined) {
1156
+ input = inputOrCol || "-";
1157
+ column = maybeCol;
1158
+ }
1159
+ else if (cmdOptions.col || cmdOptions.column) {
1160
+ input = inputOrCol || "-";
1161
+ column = cmdOptions.col || cmdOptions.column;
1162
+ }
1163
+ else {
1164
+ column = inputOrCol || "";
1165
+ }
1166
+ const opts = { ...program.opts(), ...cmdOptions, col: column || cmdOptions.col };
1167
+ await outliersCommand(input, opts);
1168
+ });
1169
+ // 44. crosstab
1170
+ program
1171
+ .command("crosstab [input] [rowCol] [colCol]")
1172
+ .description("Compute 2D contingency table and Chi-Square independence test")
1173
+ .option("-r, --row <col>", "Row dimension column")
1174
+ .option("-c, --col <col>", "Column dimension column")
1175
+ .option("-n, --top <number>", "Limit top categories per dimension", "15")
1176
+ .option("--normalize <method>", "Normalization: row, col, all")
1177
+ .option("--from <format>", "Input format")
1178
+ .option("--to <format>", "Output format")
1179
+ .option("--output <file>", "Write output to file")
1180
+ .option("--json", "Output machine-readable JSON")
1181
+ .action(async (arg1, arg2, arg3, cmdOptions) => {
1182
+ let input = "-";
1183
+ let rowCol = "";
1184
+ let colCol = "";
1185
+ if (arg3 !== undefined) {
1186
+ input = arg1 || "-";
1187
+ rowCol = arg2 || "";
1188
+ colCol = arg3 || "";
1189
+ }
1190
+ else {
1191
+ rowCol = arg1 || "";
1192
+ colCol = arg2 || "";
1193
+ }
1194
+ const opts = { ...program.opts(), ...cmdOptions };
1195
+ await crosstabCommand(input, rowCol, colCol, opts);
1196
+ });
1197
+ // 45. regression / trend
1198
+ program
1199
+ .command("regression [input] [xCol] [yCol]")
1200
+ .alias("trend")
1201
+ .description("Compute Ordinary Least Squares (OLS) Linear Regression model")
1202
+ .option("-x, --x <column>", "Independent variable column (X)")
1203
+ .option("-y, --y <column>", "Dependent variable column (Y)")
1204
+ .option("--from <format>", "Input format")
1205
+ .option("--to <format>", "Output format")
1206
+ .option("--output <file>", "Write output to file")
1207
+ .option("--json", "Output machine-readable JSON")
1208
+ .action(async (arg1, arg2, arg3, cmdOptions) => {
1209
+ let input = "-";
1210
+ let xCol = "";
1211
+ let yCol = "";
1212
+ if (arg3 !== undefined) {
1213
+ input = arg1 || "-";
1214
+ xCol = arg2 || "";
1215
+ yCol = arg3 || "";
1216
+ }
1217
+ else {
1218
+ xCol = arg1 || "";
1219
+ yCol = arg2 || "";
1220
+ }
1221
+ const opts = { ...program.opts(), ...cmdOptions };
1222
+ await regressionCommand(input, xCol, yCol, opts);
1223
+ });
1224
+ // 46. rfm
1225
+ program
1226
+ .command("rfm [input]")
1227
+ .description("Compute RFM (Recency, Frequency, Monetary) customer segmentation and scoring")
1228
+ .option("-c, --customer-id <col>", "Customer / user ID column")
1229
+ .option("-d, --date-col <col>", "Transaction / order date column")
1230
+ .option("-a, --amount-col <col>", "Monetary amount / revenue column")
1231
+ .option("--as-of <date>", "Reference date for recency calculation (default: latest date in stream)")
1232
+ .option("--summary", "Output aggregated segment breakdown and statistics")
1233
+ .option("--from <format>", "Input format")
1234
+ .option("--to <format>", "Output format")
1235
+ .option("--output <file>", "Write output to file")
1236
+ .option("--json", "Output machine-readable JSON")
1237
+ .action(async (input = "-", cmdOptions) => {
1238
+ const opts = { ...program.opts(), ...cmdOptions };
1239
+ await rfmCommand(input, opts);
1240
+ });
1241
+ // 47. cohort
1242
+ program
1243
+ .command("cohort [input]")
1244
+ .description("Compute user retention cohort matrix over time intervals")
1245
+ .option("-u, --user-id <col>", "User / customer ID column")
1246
+ .option("-t, --time-col <col>", "Timestamp / event date column")
1247
+ .option("-i, --interval <interval>", "Cohort interval: 1d, 1w, 1mo, 1y", "1mo")
1248
+ .option("--counts", "Display raw user retention counts instead of percentages")
1249
+ .option("--from <format>", "Input format")
1250
+ .option("--to <format>", "Output format")
1251
+ .option("--output <file>", "Write output to file")
1252
+ .option("--json", "Output machine-readable JSON")
1253
+ .action(async (input = "-", cmdOptions) => {
1254
+ const opts = { ...program.opts(), ...cmdOptions };
1255
+ await cohortCommand(input, opts);
1256
+ });
1257
+ // 48. funnel
1258
+ program
1259
+ .command("funnel [input]")
1260
+ .description("Compute conversion funnel, step drop-off rates, and visual ASCII funnel")
1261
+ .option("-s, --steps <steps>", "Comma-separated list of funnel stages (e.g. 'view,cart,checkout,purchase')")
1262
+ .option("-u, --user-id <col>", "User / session ID column")
1263
+ .option("--step-col <col>", "Step / event name column")
1264
+ .option("-t, --time-col <col>", "Event timestamp column")
1265
+ .option("--strict", "Enforce strict chronological step order per user")
1266
+ .option("--from <format>", "Input format")
1267
+ .option("--to <format>", "Output format")
1268
+ .option("--output <file>", "Write output to file")
1269
+ .option("--json", "Output machine-readable JSON")
1270
+ .action(async (input = "-", cmdOptions) => {
1271
+ const opts = { ...program.opts(), ...cmdOptions };
1272
+ await funnelCommand(input, opts);
1273
+ });
1274
+ // 49. abtest
1275
+ program
1276
+ .command("abtest [input]")
1277
+ .description("Compute A/B test statistical significance (Two-Proportion Z-Test or Welch's T-Test)")
1278
+ .option("-g, --group <col>", "Experiment group / variant column")
1279
+ .option("-m, --metric <col>", "Conversion metric (0/1) or numeric value column")
1280
+ .option("--control <group>", "Control group name (default: auto-detected 'control' or 'A')")
1281
+ .option("--variant <group>", "Variant group name (default: auto-detected 'variant' or 'B')")
1282
+ .option("--type <type>", "Test type: proportion, means, auto", "auto")
1283
+ .option("--confidence-level <level>", "Confidence level (e.g. 0.95, 0.99, 0.90)", "0.95")
1284
+ .option("--from <format>", "Input format")
1285
+ .option("--to <format>", "Output format")
1286
+ .option("--output <file>", "Write output to file")
1287
+ .option("--json", "Output machine-readable JSON")
1288
+ .action(async (input = "-", cmdOptions) => {
1289
+ const opts = { ...program.opts(), ...cmdOptions };
1290
+ await abTestCommand(input, opts);
1291
+ });
1292
+ // 50. pareto
1293
+ program
1294
+ .command("pareto [input]")
1295
+ .description("Compute 80/20 Pareto distribution and ABC inventory/revenue classification")
1296
+ .option("-i, --item <col>", "Item / SKU / category / customer column")
1297
+ .option("-v, --value <col>", "Value / revenue / sales / quantity column")
1298
+ .option("--a-threshold <pct>", "Threshold percentage for Class A (default: 80)", "80")
1299
+ .option("--b-threshold <pct>", "Threshold percentage for Class B (default: 95)", "95")
1300
+ .option("--summary", "Output aggregated ABC class summary breakdown")
1301
+ .option("--from <format>", "Input format")
1302
+ .option("--to <format>", "Output format")
1303
+ .option("--output <file>", "Write output to file")
1304
+ .option("--json", "Output machine-readable JSON")
1305
+ .action(async (input = "-", cmdOptions) => {
1306
+ const opts = { ...program.opts(), ...cmdOptions };
1307
+ await paretoCommand(input, opts);
1308
+ });
1309
+ // 51. technical / indicators
1310
+ program
1311
+ .command("technical [input]")
1312
+ .alias("indicators")
1313
+ .description("Compute financial technical indicators (SMA, EMA, RSI, MACD, Bollinger Bands, VWAP, ATR)")
1314
+ .option("-p, --price <col>", "Price / close price column")
1315
+ .option("-v, --volume <col>", "Volume column")
1316
+ .option("--high <col>", "High price column")
1317
+ .option("--low <col>", "Low price column")
1318
+ .option("--close <col>", "Close price column")
1319
+ .option("-i, --indicators <specs>", "Indicator list (e.g. 'sma(20),rsi(14),macd,bollinger(20,2),vwap')")
1320
+ .option("--from <format>", "Input format")
1321
+ .option("--to <format>", "Output format")
1322
+ .option("--output <file>", "Write output to file")
1323
+ .option("--json", "Output machine-readable JSON")
1324
+ .action(async (input = "-", cmdOptions) => {
1325
+ const opts = { ...program.opts(), ...cmdOptions };
1326
+ await technicalCommand(input, opts);
1327
+ });
1328
+ // 52. cluster / kmeans
1329
+ program
1330
+ .command("cluster [input]")
1331
+ .alias("kmeans")
1332
+ .description("Perform O(1) streaming Mini-Batch K-Means clustering across numeric features")
1333
+ .option("-k, --k <number>", "Number of clusters (default: 3)", "3")
1334
+ .option("-c, --cols <columns>", "Target numeric feature columns (comma-separated)")
1335
+ .option("--summary", "Output cluster centroids summary instead of row assignments")
1336
+ .option("--from <format>", "Input format")
1337
+ .option("--to <format>", "Output format")
1338
+ .option("--output <file>", "Write output to file")
1339
+ .option("--json", "Output machine-readable JSON")
1340
+ .action(async (input = "-", cmdOptions) => {
1341
+ const opts = { ...program.opts(), ...cmdOptions };
1342
+ await clusterCommand(input, opts);
1343
+ });
1344
+ // 53. entropy / importance
1345
+ program
1346
+ .command("entropy [input]")
1347
+ .alias("importance")
1348
+ .description("Compute Shannon entropy, mutual information, and feature importance rankings")
1349
+ .option("-t, --target <col>", "Target / label column name")
1350
+ .option("-c, --cols <columns>", "Feature columns to evaluate (comma-separated)")
1351
+ .option("--bins <number>", "Numeric discretization bins count (default: 10)", "10")
1352
+ .option("--from <format>", "Input format")
1353
+ .option("--to <format>", "Output format")
1354
+ .option("--output <file>", "Write output to file")
1355
+ .option("--json", "Output machine-readable JSON")
1356
+ .action(async (input = "-", cmdOptions) => {
1357
+ const opts = { ...program.opts(), ...cmdOptions };
1358
+ await entropyCommand(input, opts);
1359
+ });
1360
+ // 54. ngrams / tokens
1361
+ program
1362
+ .command("ngrams [input] [column]")
1363
+ .alias("tokens")
1364
+ .description("Extract N-Gram word phrases (unigrams, bigrams, trigrams) and frequency counts")
1365
+ .option("-c, --col <column>", "Target text column name")
1366
+ .option("-n, --n <number>", "N-Gram size: 1 (unigram), 2 (bigram), 3 (trigram)", "2")
1367
+ .option("--top <number>", "Limit top frequent N-Grams (default: 20)", "20")
1368
+ .option("--stopwords", "Filter out common English stopwords")
1369
+ .option("--min-freq <number>", "Minimum frequency threshold", "1")
1370
+ .option("--from <format>", "Input format")
1371
+ .option("--to <format>", "Output format")
1372
+ .option("--output <file>", "Write output to file")
1373
+ .option("--json", "Output machine-readable JSON")
1374
+ .action(async (inputOrCol, maybeCol, cmdOptions) => {
1375
+ let input = "-";
1376
+ let column = "";
1377
+ if (maybeCol !== undefined) {
1378
+ input = inputOrCol || "-";
1379
+ column = maybeCol;
1380
+ }
1381
+ else if (cmdOptions.col) {
1382
+ input = inputOrCol || "-";
1383
+ column = cmdOptions.col;
1384
+ }
1385
+ else {
1386
+ column = inputOrCol || "";
1387
+ }
1388
+ const opts = { ...program.opts(), ...cmdOptions, col: column || cmdOptions.col };
1389
+ await ngramsCommand(input, column, opts);
1390
+ });
1391
+ // 55. pivot / pivot-table / crosstab-pivot
1392
+ program
1393
+ .command("pivot [input]")
1394
+ .aliases(["pivot-table", "crosstab-pivot"])
1395
+ .description("Create multi-dimensional pivot table with aggregated metrics across row and column dimensions")
1396
+ .option("-i, --index <cols>", "Index / row grouping column(s) (comma-separated)")
1397
+ .option("-c, --columns <col>", "Column whose unique values become output columns")
1398
+ .option("-v, --values <col>", "Metric / value column to aggregate")
1399
+ .option("-a, --agg <func>", "Aggregation function: sum, avg, min, max, count, first, last", "sum")
1400
+ .option("--fill <val>", "Fill value for empty cells")
1401
+ .option("--from <format>", "Input format")
1402
+ .option("--to <format>", "Output format")
1403
+ .option("--output <file>", "Write output to file")
1404
+ .option("--json", "Output machine-readable JSON")
1405
+ .action(async (input = "-", cmdOptions) => {
1406
+ const opts = { ...program.opts(), ...cmdOptions };
1407
+ await pivotCommand(input, opts);
1408
+ });
1409
+ // 56. unpivot / melt / wide-to-long
1410
+ program
1411
+ .command("unpivot [input]")
1412
+ .aliases(["melt", "wide-to-long"])
1413
+ .description("Unpivot / melt wide dataset into long key-value format (O(1) memory)")
1414
+ .option("-i, --index <cols>", "Index / identifier column(s) to keep fixed (comma-separated)")
1415
+ .option("-c, --columns <cols>", "Value columns to unpivot (comma-separated, defaults to all non-index columns)")
1416
+ .option("--var-col <name>", "Name for variable / dimension column", "variable")
1417
+ .option("--val-col <name>", "Name for metric / value column", "value")
1418
+ .option("--drop-null", "Drop rows where unpivoted value is null")
1419
+ .option("--from <format>", "Input format")
1420
+ .option("--to <format>", "Output format")
1421
+ .option("--output <file>", "Write output to file")
1422
+ .option("--json", "Output machine-readable JSON")
1423
+ .action(async (input = "-", cmdOptions) => {
1424
+ const opts = { ...program.opts(), ...cmdOptions };
1425
+ await unpivotCommand(input, opts);
1426
+ });
1427
+ // 57. fuzzy-join / fuzzyjoin / fuzzy
1428
+ program
1429
+ .command("fuzzy-join <left> <right>")
1430
+ .aliases(["fuzzyjoin", "fuzzy"])
1431
+ .description("Fuzzy approximate string matching join (Levenshtein, Jaro-Winkler, Jaccard, Soundex)")
1432
+ .option("-o, --on <col>", "Key column name to compare in both datasets")
1433
+ .option("--left-key <col>", "Left dataset key column")
1434
+ .option("--right-key <col>", "Right dataset key column")
1435
+ .option("--type <type>", "Join type: inner, left, right, full", "left")
1436
+ .option("-m, --method <algo>", "Similarity algorithm: levenshtein, jaro-winkler, jaccard, soundex", "levenshtein")
1437
+ .option("-t, --threshold <num>", "Match threshold between 0.0 and 1.0 (default: 0.75)", "0.75")
1438
+ .option("--all-matches", "Keep all matching right records instead of only best match")
1439
+ .option("--score-col <col>", "Add similarity score column (e.g. 'similarity_score')")
1440
+ .option("--from-left <fmt>", "Format of left file")
1441
+ .option("--from-right <fmt>", "Format of right file")
1442
+ .option("--from <format>", "Input format")
1443
+ .option("--to <format>", "Output format")
1444
+ .option("--output <file>", "Write output to file")
1445
+ .option("--json", "Output machine-readable JSON")
1446
+ .action(async (left, right, cmdOptions) => {
1447
+ const opts = { ...program.opts(), ...cmdOptions, bestMatch: !cmdOptions.allMatches };
1448
+ await fuzzyJoinCommand(left, right, opts);
1449
+ });
1450
+ // 58. concat / stack / union-all
1451
+ program
1452
+ .command("concat <files...>")
1453
+ .aliases(["stack", "union-all"])
1454
+ .description("Stream concatenate multiple tabular files sequentially with unified schema")
1455
+ .option("-s, --source-col <name>", "Add source filename / path column to rows")
1456
+ .option("--from <format>", "Input format")
1457
+ .option("--to <format>", "Output format")
1458
+ .option("--output <file>", "Write output to file")
1459
+ .option("--json", "Output machine-readable JSON")
1460
+ .action(async (files, cmdOptions) => {
1461
+ const opts = { ...program.opts(), ...cmdOptions };
1462
+ await concatCommand(files, opts);
1463
+ });
1464
+ // 59. generate / mock / fake / synth
1465
+ program
1466
+ .command("generate [schema]")
1467
+ .aliases(["mock", "fake", "synth"])
1468
+ .description("Stream generate synthetic tabular data based on column generators (seq, uuid, name, email, int, float, date, choice)")
1469
+ .option("-n, --rows <number>", "Number of rows to generate (default: 1000)", "1000")
1470
+ .option("-s, --schema <spec>", "Column schema specifications (e.g. 'id:seq,name:name,email:email,age:int(18,70)')")
1471
+ .option("--to <format>", "Output format")
1472
+ .option("--output <file>", "Write output to file")
1473
+ .option("--json", "Output machine-readable JSON")
1474
+ .action(async (schema, cmdOptions) => {
1475
+ const opts = { ...program.opts(), ...cmdOptions };
1476
+ await generateCommand(schema, opts);
1477
+ });
1478
+ // 60. mask / anonymize / redact
1479
+ program
1480
+ .command("mask [input]")
1481
+ .aliases(["anonymize", "redact"])
1482
+ .description("Redact and mask sensitive PII fields (email, phone, credit card, IP, name, hash)")
1483
+ .option("--email <cols>", "Email columns to mask (e.g. 'j***@domain.com')")
1484
+ .option("--phone <cols>", "Phone columns to mask (e.g. '***-***-1234')")
1485
+ .option("--card <cols>", "Credit card columns to mask (e.g. '**** **** **** 1234')")
1486
+ .option("--ip <cols>", "IP columns to mask (e.g. '192.168.***.***')")
1487
+ .option("--name <cols>", "Name columns to mask (e.g. 'J*** D***')")
1488
+ .option("--hash <cols>", "Columns to tokenize with deterministic SHA-256 hash")
1489
+ .option("--redact <cols>", "Columns to redact completely with [REDACTED]")
1490
+ .option("--salt <salt>", "Salt for HMAC/SHA-256 hashing")
1491
+ .option("--from <format>", "Input format")
1492
+ .option("--to <format>", "Output format")
1493
+ .option("--output <file>", "Write output to file")
1494
+ .option("--json", "Output machine-readable JSON")
1495
+ .action(async (input = "-", cmdOptions) => {
1496
+ const opts = { ...program.opts(), ...cmdOptions };
1497
+ await maskCommand(input, opts);
1498
+ });
1499
+ // 61. test / assert / check
1500
+ program
1501
+ .command("test [input]")
1502
+ .aliases(["assert", "check"])
1503
+ .description("Run streaming data quality assertions and constraints (CI/CD assert runner)")
1504
+ .option("-a, --assert <expressions...>", "Expressions that must evaluate truthy on every row")
1505
+ .option("--not-null <cols>", "Columns that must not contain null/empty values (comma-separated)")
1506
+ .option("--unique <cols>", "Columns that must contain strictly unique values (comma-separated)")
1507
+ .option("--min-rows <number>", "Minimum row count requirement")
1508
+ .option("--max-rows <number>", "Maximum row count limit")
1509
+ .option("--max-errors <number>", "Limit number of sample violation rows reported", "5")
1510
+ .option("--fail-fast", "Stop processing stream on first assertion failure")
1511
+ .option("--from <format>", "Input format")
1512
+ .option("--json", "Output machine-readable test summary JSON")
1513
+ .action(async (input = "-", cmdOptions) => {
1514
+ const opts = { ...program.opts(), ...cmdOptions };
1515
+ await testCommand(input, opts);
1516
+ });
1517
+ // 62. serve / api / http
1518
+ program
1519
+ .command("serve [input]")
1520
+ .aliases(["api", "http"])
1521
+ .description("Instantly serve dataset via zero-dependency streaming HTTP REST API")
1522
+ .option("-p, --port <number>", "Port to bind HTTP server (default: 3000)", "3000")
1523
+ .option("-h, --host <host>", "Host address to bind (default: 0.0.0.0)", "0.0.0.0")
1524
+ .option("--from <format>", "Input format")
1525
+ .action(async (input = "-", cmdOptions) => {
1526
+ const opts = { ...program.opts(), ...cmdOptions };
1527
+ await serveCommand(input, opts);
1528
+ });
1529
+ // 63. report / summary-html
1530
+ program
1531
+ .command("report [input]")
1532
+ .aliases(["summary-html"])
1533
+ .description("Generate modern offline self-contained HTML data health dashboard and report")
1534
+ .option("-t, --title <title>", "Report title")
1535
+ .option("-o, --output <file>", "Output HTML file path")
1536
+ .option("--from <format>", "Input format")
1537
+ .action(async (input = "-", cmdOptions) => {
1538
+ const opts = { ...program.opts(), ...cmdOptions };
1539
+ if (!opts.output) {
1540
+ opts.output = "report.html";
1541
+ }
1542
+ await reportCommand(input, opts);
1543
+ });
1544
+ // 64. fetch / http-get / curl-stream
1545
+ program
1546
+ .command("fetch <url>")
1547
+ .aliases(["http-get", "curl-stream"])
1548
+ .description("Stream tabular data from remote REST API with pagination and data path extraction")
1549
+ .option("-H, --header <key:val...>", "Custom HTTP headers", (val, prev = []) => [...prev, val])
1550
+ .option("--bearer <token>", "Bearer authorization token")
1551
+ .option("--auth <user:pass>", "Basic authorization credentials")
1552
+ .option("--data-path <path>", "Dot-path to extract array from JSON response envelope (e.g. data.items)")
1553
+ .option("--paginate <mode>", "Pagination mode: page, offset, cursor (default: none)", "none")
1554
+ .option("--page-param <param>", "Query parameter for page number (default: page)", "page")
1555
+ .option("--offset-param <param>", "Query parameter for offset (default: offset)", "offset")
1556
+ .option("--limit-param <param>", "Query parameter for page size (default: limit)", "limit")
1557
+ .option("--page-size <number>", "Page size limit per request")
1558
+ .option("--cursor-param <param>", "Query parameter for cursor token", "cursor")
1559
+ .option("--cursor-path <path>", "Dot-path in response JSON containing next cursor token")
1560
+ .option("--max-pages <number>", "Maximum number of pages to fetch (default: 100)", "100")
1561
+ .action(async (url, cmdOptions) => {
1562
+ const opts = { ...program.opts(), ...cmdOptions };
1563
+ if (cmdOptions.header) {
1564
+ opts.headersList = Array.isArray(cmdOptions.header) ? cmdOptions.header : [cmdOptions.header];
1565
+ }
1566
+ if (cmdOptions.pageSize)
1567
+ opts.pageSize = parseInt(cmdOptions.pageSize, 10);
1568
+ if (cmdOptions.maxPages)
1569
+ opts.maxPages = parseInt(cmdOptions.maxPages, 10);
1570
+ await fetchCommand(url, opts);
1571
+ });
775
1572
  async function main() {
1573
+ if (process.argv.length <= 2 && process.stdin.isTTY) {
1574
+ program.outputHelp();
1575
+ return;
1576
+ }
776
1577
  try {
777
1578
  await program.parseAsync(process.argv);
778
1579
  }