rowpipe 2.2.1 → 2.10.2
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.
- package/README.md +34 -4
- package/dist/analytics/abtest.d.ts +39 -0
- package/dist/analytics/abtest.d.ts.map +1 -0
- package/dist/analytics/abtest.js +266 -0
- package/dist/analytics/abtest.js.map +1 -0
- package/dist/analytics/cluster.d.ts +25 -0
- package/dist/analytics/cluster.d.ts.map +1 -0
- package/dist/analytics/cluster.js +212 -0
- package/dist/analytics/cluster.js.map +1 -0
- package/dist/analytics/cohort.d.ts +22 -0
- package/dist/analytics/cohort.d.ts.map +1 -0
- package/dist/analytics/cohort.js +170 -0
- package/dist/analytics/cohort.js.map +1 -0
- package/dist/analytics/correlation.d.ts +15 -0
- package/dist/analytics/correlation.d.ts.map +1 -0
- package/dist/analytics/correlation.js +116 -0
- package/dist/analytics/correlation.js.map +1 -0
- package/dist/analytics/crosstab.d.ts +27 -0
- package/dist/analytics/crosstab.d.ts.map +1 -0
- package/dist/analytics/crosstab.js +90 -0
- package/dist/analytics/crosstab.js.map +1 -0
- package/dist/analytics/entropy.d.ts +23 -0
- package/dist/analytics/entropy.d.ts.map +1 -0
- package/dist/analytics/entropy.js +180 -0
- package/dist/analytics/entropy.js.map +1 -0
- package/dist/analytics/funnel.d.ts +29 -0
- package/dist/analytics/funnel.d.ts.map +1 -0
- package/dist/analytics/funnel.js +170 -0
- package/dist/analytics/funnel.js.map +1 -0
- package/dist/analytics/ngrams.d.ts +25 -0
- package/dist/analytics/ngrams.d.ts.map +1 -0
- package/dist/analytics/ngrams.js +110 -0
- package/dist/analytics/ngrams.js.map +1 -0
- package/dist/analytics/outliers.d.ts +25 -0
- package/dist/analytics/outliers.d.ts.map +1 -0
- package/dist/analytics/outliers.js +114 -0
- package/dist/analytics/outliers.js.map +1 -0
- package/dist/analytics/pareto.d.ts +36 -0
- package/dist/analytics/pareto.d.ts.map +1 -0
- package/dist/analytics/pareto.js +140 -0
- package/dist/analytics/pareto.js.map +1 -0
- package/dist/analytics/quantiles.d.ts +18 -0
- package/dist/analytics/quantiles.d.ts.map +1 -0
- package/dist/analytics/quantiles.js +62 -0
- package/dist/analytics/quantiles.js.map +1 -0
- package/dist/analytics/regression.d.ts +18 -0
- package/dist/analytics/regression.d.ts.map +1 -0
- package/dist/analytics/regression.js +79 -0
- package/dist/analytics/regression.js.map +1 -0
- package/dist/analytics/rfm.d.ts +41 -0
- package/dist/analytics/rfm.d.ts.map +1 -0
- package/dist/analytics/rfm.js +221 -0
- package/dist/analytics/rfm.js.map +1 -0
- package/dist/analytics/stats.d.ts.map +1 -1
- package/dist/analytics/stats.js +65 -15
- package/dist/analytics/stats.js.map +1 -1
- package/dist/analytics/technical.d.ts +19 -0
- package/dist/analytics/technical.d.ts.map +1 -0
- package/dist/analytics/technical.js +365 -0
- package/dist/analytics/technical.js.map +1 -0
- package/dist/cli/commands/abtest.d.ts +10 -0
- package/dist/cli/commands/abtest.d.ts.map +1 -0
- package/dist/cli/commands/abtest.js +68 -0
- package/dist/cli/commands/abtest.js.map +1 -0
- package/dist/cli/commands/cluster.d.ts +9 -0
- package/dist/cli/commands/cluster.d.ts.map +1 -0
- package/dist/cli/commands/cluster.js +77 -0
- package/dist/cli/commands/cluster.js.map +1 -0
- package/dist/cli/commands/cohort.d.ts +10 -0
- package/dist/cli/commands/cohort.d.ts.map +1 -0
- package/dist/cli/commands/cohort.js +66 -0
- package/dist/cli/commands/cohort.js.map +1 -0
- package/dist/cli/commands/completion.d.ts +5 -0
- package/dist/cli/commands/completion.d.ts.map +1 -0
- package/dist/cli/commands/completion.js +7 -0
- package/dist/cli/commands/completion.js.map +1 -0
- package/dist/cli/commands/concat.d.ts +9 -0
- package/dist/cli/commands/concat.d.ts.map +1 -0
- package/dist/cli/commands/concat.js +62 -0
- package/dist/cli/commands/concat.js.map +1 -0
- package/dist/cli/commands/convert.d.ts +2 -0
- package/dist/cli/commands/convert.d.ts.map +1 -1
- package/dist/cli/commands/convert.js.map +1 -1
- package/dist/cli/commands/corr.d.ts +7 -0
- package/dist/cli/commands/corr.d.ts.map +1 -0
- package/dist/cli/commands/corr.js +70 -0
- package/dist/cli/commands/corr.js.map +1 -0
- package/dist/cli/commands/crosstab.d.ts +11 -0
- package/dist/cli/commands/crosstab.d.ts.map +1 -0
- package/dist/cli/commands/crosstab.js +71 -0
- package/dist/cli/commands/crosstab.js.map +1 -0
- package/dist/cli/commands/entropy.d.ts +9 -0
- package/dist/cli/commands/entropy.d.ts.map +1 -0
- package/dist/cli/commands/entropy.js +71 -0
- package/dist/cli/commands/entropy.js.map +1 -0
- package/dist/cli/commands/explode.d.ts +8 -0
- package/dist/cli/commands/explode.d.ts.map +1 -0
- package/dist/cli/commands/explode.js +61 -0
- package/dist/cli/commands/explode.js.map +1 -0
- package/dist/cli/commands/fetch.d.ts +8 -0
- package/dist/cli/commands/fetch.d.ts.map +1 -0
- package/dist/cli/commands/fetch.js +41 -0
- package/dist/cli/commands/fetch.js.map +1 -0
- package/dist/cli/commands/files.d.ts +1 -1
- package/dist/cli/commands/files.d.ts.map +1 -1
- package/dist/cli/commands/flatten.d.ts +8 -0
- package/dist/cli/commands/flatten.d.ts.map +1 -0
- package/dist/cli/commands/flatten.js +57 -0
- package/dist/cli/commands/flatten.js.map +1 -0
- package/dist/cli/commands/freq.d.ts +10 -0
- package/dist/cli/commands/freq.d.ts.map +1 -0
- package/dist/cli/commands/freq.js +122 -0
- package/dist/cli/commands/freq.js.map +1 -0
- package/dist/cli/commands/funnel.d.ts +11 -0
- package/dist/cli/commands/funnel.d.ts.map +1 -0
- package/dist/cli/commands/funnel.js +69 -0
- package/dist/cli/commands/funnel.js.map +1 -0
- package/dist/cli/commands/fuzzy-join.d.ts +25 -0
- package/dist/cli/commands/fuzzy-join.d.ts.map +1 -0
- package/dist/cli/commands/fuzzy-join.js +85 -0
- package/dist/cli/commands/fuzzy-join.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +8 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +34 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/mask.d.ts +6 -0
- package/dist/cli/commands/mask.d.ts.map +1 -0
- package/dist/cli/commands/mask.js +58 -0
- package/dist/cli/commands/mask.js.map +1 -0
- package/dist/cli/commands/ngrams.d.ts +11 -0
- package/dist/cli/commands/ngrams.d.ts.map +1 -0
- package/dist/cli/commands/ngrams.js +70 -0
- package/dist/cli/commands/ngrams.js.map +1 -0
- package/dist/cli/commands/outliers.d.ts +13 -0
- package/dist/cli/commands/outliers.d.ts.map +1 -0
- package/dist/cli/commands/outliers.js +58 -0
- package/dist/cli/commands/outliers.js.map +1 -0
- package/dist/cli/commands/pareto.d.ts +8 -0
- package/dist/cli/commands/pareto.d.ts.map +1 -0
- package/dist/cli/commands/pareto.js +80 -0
- package/dist/cli/commands/pareto.js.map +1 -0
- package/dist/cli/commands/partition.d.ts +8 -0
- package/dist/cli/commands/partition.d.ts.map +1 -0
- package/dist/cli/commands/partition.js +44 -0
- package/dist/cli/commands/partition.js.map +1 -0
- package/dist/cli/commands/pipeline.d.ts +6 -0
- package/dist/cli/commands/pipeline.d.ts.map +1 -1
- package/dist/cli/commands/pipeline.js +22 -0
- package/dist/cli/commands/pipeline.js.map +1 -1
- package/dist/cli/commands/pivot.d.ts +11 -0
- package/dist/cli/commands/pivot.d.ts.map +1 -0
- package/dist/cli/commands/pivot.js +58 -0
- package/dist/cli/commands/pivot.js.map +1 -0
- package/dist/cli/commands/plot.d.ts +12 -0
- package/dist/cli/commands/plot.d.ts.map +1 -0
- package/dist/cli/commands/plot.js +123 -0
- package/dist/cli/commands/plot.js.map +1 -0
- package/dist/cli/commands/quantiles.d.ts +7 -0
- package/dist/cli/commands/quantiles.d.ts.map +1 -0
- package/dist/cli/commands/quantiles.js +94 -0
- package/dist/cli/commands/quantiles.js.map +1 -0
- package/dist/cli/commands/regression.d.ts +7 -0
- package/dist/cli/commands/regression.d.ts.map +1 -0
- package/dist/cli/commands/regression.js +86 -0
- package/dist/cli/commands/regression.js.map +1 -0
- package/dist/cli/commands/report.d.ts +8 -0
- package/dist/cli/commands/report.d.ts.map +1 -0
- package/dist/cli/commands/report.js +36 -0
- package/dist/cli/commands/report.js.map +1 -0
- package/dist/cli/commands/rfm.d.ts +11 -0
- package/dist/cli/commands/rfm.d.ts.map +1 -0
- package/dist/cli/commands/rfm.js +78 -0
- package/dist/cli/commands/rfm.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +7 -0
- package/dist/cli/commands/serve.d.ts.map +1 -0
- package/dist/cli/commands/serve.js +43 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/split.d.ts +8 -0
- package/dist/cli/commands/split.d.ts.map +1 -0
- package/dist/cli/commands/split.js +43 -0
- package/dist/cli/commands/split.js.map +1 -0
- package/dist/cli/commands/table.d.ts +9 -0
- package/dist/cli/commands/table.d.ts.map +1 -0
- package/dist/cli/commands/table.js +9 -0
- package/dist/cli/commands/table.js.map +1 -0
- package/dist/cli/commands/technical.d.ts +8 -0
- package/dist/cli/commands/technical.d.ts.map +1 -0
- package/dist/cli/commands/technical.js +54 -0
- package/dist/cli/commands/technical.js.map +1 -0
- package/dist/cli/commands/test.d.ts +7 -0
- package/dist/cli/commands/test.d.ts.map +1 -0
- package/dist/cli/commands/test.js +53 -0
- package/dist/cli/commands/test.js.map +1 -0
- package/dist/cli/commands/timeseries.d.ts +11 -0
- package/dist/cli/commands/timeseries.d.ts.map +1 -0
- package/dist/cli/commands/timeseries.js +82 -0
- package/dist/cli/commands/timeseries.js.map +1 -0
- package/dist/cli/commands/unpivot.d.ts +12 -0
- package/dist/cli/commands/unpivot.d.ts.map +1 -0
- package/dist/cli/commands/unpivot.js +59 -0
- package/dist/cli/commands/unpivot.js.map +1 -0
- package/dist/cli/completion.d.ts +5 -0
- package/dist/cli/completion.d.ts.map +1 -0
- package/dist/cli/completion.js +194 -0
- package/dist/cli/completion.js.map +1 -0
- package/dist/cli/index.js +816 -15
- package/dist/cli/index.js.map +1 -1
- package/dist/core/error-handler.d.ts +38 -0
- package/dist/core/error-handler.d.ts.map +1 -0
- package/dist/core/error-handler.js +81 -0
- package/dist/core/error-handler.js.map +1 -0
- package/dist/core/pipeline.d.ts +10 -0
- package/dist/core/pipeline.d.ts.map +1 -1
- package/dist/core/pipeline.js +14 -0
- package/dist/core/pipeline.js.map +1 -1
- package/dist/core/types.d.ts +4 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/dataops/fetch.d.ts +27 -0
- package/dist/dataops/fetch.d.ts.map +1 -0
- package/dist/dataops/fetch.js +150 -0
- package/dist/dataops/fetch.js.map +1 -0
- package/dist/dataops/generate.d.ts +16 -0
- package/dist/dataops/generate.d.ts.map +1 -0
- package/dist/dataops/generate.js +201 -0
- package/dist/dataops/generate.js.map +1 -0
- package/dist/dataops/mask.d.ts +25 -0
- package/dist/dataops/mask.d.ts.map +1 -0
- package/dist/dataops/mask.js +133 -0
- package/dist/dataops/mask.js.map +1 -0
- package/dist/dataops/report.d.ts +7 -0
- package/dist/dataops/report.d.ts.map +1 -0
- package/dist/dataops/report.js +139 -0
- package/dist/dataops/report.js.map +1 -0
- package/dist/dataops/server.d.ts +10 -0
- package/dist/dataops/server.d.ts.map +1 -0
- package/dist/dataops/server.js +137 -0
- package/dist/dataops/server.js.map +1 -0
- package/dist/dataops/test-runner.d.ts +34 -0
- package/dist/dataops/test-runner.d.ts.map +1 -0
- package/dist/dataops/test-runner.js +128 -0
- package/dist/dataops/test-runner.js.map +1 -0
- package/dist/db/adapters/sqlite.d.ts.map +1 -1
- package/dist/db/adapters/sqlite.js +4 -1
- package/dist/db/adapters/sqlite.js.map +1 -1
- package/dist/diff/engine.d.ts.map +1 -1
- package/dist/diff/engine.js +73 -16
- package/dist/diff/engine.js.map +1 -1
- package/dist/diff/storage/disk-index.d.ts +10 -1
- package/dist/diff/storage/disk-index.d.ts.map +1 -1
- package/dist/diff/storage/disk-index.js +95 -13
- package/dist/diff/storage/disk-index.js.map +1 -1
- package/dist/files/hash.d.ts +9 -2
- package/dist/files/hash.d.ts.map +1 -1
- package/dist/files/hash.js +9 -10
- package/dist/files/hash.js.map +1 -1
- package/dist/files/reader.d.ts.map +1 -1
- package/dist/files/reader.js +17 -10
- package/dist/files/reader.js.map +1 -1
- package/dist/files/types.d.ts +2 -1
- package/dist/files/types.d.ts.map +1 -1
- package/dist/index.d.ts +65 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +66 -1
- package/dist/index.js.map +1 -1
- package/dist/planner/executor.d.ts.map +1 -1
- package/dist/planner/executor.js +17 -0
- package/dist/planner/executor.js.map +1 -1
- package/dist/planner/types.d.ts +11 -0
- package/dist/planner/types.d.ts.map +1 -1
- package/dist/readers/csv.d.ts.map +1 -1
- package/dist/readers/csv.js +206 -164
- package/dist/readers/csv.js.map +1 -1
- package/dist/readers/json.d.ts.map +1 -1
- package/dist/readers/json.js +145 -121
- package/dist/readers/json.js.map +1 -1
- package/dist/readers/jsonl.d.ts.map +1 -1
- package/dist/readers/jsonl.js +51 -31
- package/dist/readers/jsonl.js.map +1 -1
- package/dist/transforms/concat.d.ts +26 -0
- package/dist/transforms/concat.d.ts.map +1 -0
- package/dist/transforms/concat.js +57 -0
- package/dist/transforms/concat.js.map +1 -0
- package/dist/transforms/explode.d.ts +14 -0
- package/dist/transforms/explode.d.ts.map +1 -0
- package/dist/transforms/explode.js +81 -0
- package/dist/transforms/explode.js.map +1 -0
- package/dist/transforms/flatten.d.ts +12 -0
- package/dist/transforms/flatten.d.ts.map +1 -0
- package/dist/transforms/flatten.js +65 -0
- package/dist/transforms/flatten.js.map +1 -0
- package/dist/transforms/fuzzy-join.d.ts +53 -0
- package/dist/transforms/fuzzy-join.d.ts.map +1 -0
- package/dist/transforms/fuzzy-join.js +347 -0
- package/dist/transforms/fuzzy-join.js.map +1 -0
- package/dist/transforms/jit-compiler.d.ts.map +1 -1
- package/dist/transforms/jit-compiler.js +103 -14
- package/dist/transforms/jit-compiler.js.map +1 -1
- package/dist/transforms/map.d.ts +6 -2
- package/dist/transforms/map.d.ts.map +1 -1
- package/dist/transforms/map.js +64 -26
- package/dist/transforms/map.js.map +1 -1
- package/dist/transforms/partition.d.ts +35 -0
- package/dist/transforms/partition.d.ts.map +1 -0
- package/dist/transforms/partition.js +150 -0
- package/dist/transforms/partition.js.map +1 -0
- package/dist/transforms/pivot.d.ts +16 -0
- package/dist/transforms/pivot.d.ts.map +1 -0
- package/dist/transforms/pivot.js +194 -0
- package/dist/transforms/pivot.js.map +1 -0
- package/dist/transforms/sort/comparator.d.ts.map +1 -1
- package/dist/transforms/sort/comparator.js +153 -24
- package/dist/transforms/sort/comparator.js.map +1 -1
- package/dist/transforms/sort/external-sort.js +1 -1
- package/dist/transforms/sort/external-sort.js.map +1 -1
- package/dist/transforms/split.d.ts +17 -0
- package/dist/transforms/split.d.ts.map +1 -0
- package/dist/transforms/split.js +88 -0
- package/dist/transforms/split.js.map +1 -0
- package/dist/transforms/timeseries.d.ts +42 -0
- package/dist/transforms/timeseries.d.ts.map +1 -0
- package/dist/transforms/timeseries.js +276 -0
- package/dist/transforms/timeseries.js.map +1 -0
- package/dist/transforms/unpivot.d.ts +14 -0
- package/dist/transforms/unpivot.d.ts.map +1 -0
- package/dist/transforms/unpivot.js +56 -0
- package/dist/transforms/unpivot.js.map +1 -0
- package/dist/ui/chart.d.ts +30 -0
- package/dist/ui/chart.d.ts.map +1 -0
- package/dist/ui/chart.js +91 -0
- package/dist/ui/chart.js.map +1 -0
- package/dist/writers/index.d.ts +1 -0
- package/dist/writers/index.d.ts.map +1 -1
- package/dist/writers/index.js +10 -0
- package/dist/writers/index.js.map +1 -1
- package/dist/writers/table.d.ts +23 -0
- package/dist/writers/table.d.ts.map +1 -0
- package/dist/writers/table.js +156 -0
- package/dist/writers/table.js.map +1 -0
- 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.
|
|
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
|
|
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 (
|
|
478
|
-
|
|
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 (
|
|
491
|
-
|
|
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 (
|
|
509
|
-
|
|
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
|
-
.
|
|
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 (
|
|
528
|
-
|
|
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
|
}
|