rowpipe 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/README.md +327 -41
  2. package/dist/cli/commands/diff.d.ts +30 -0
  3. package/dist/cli/commands/diff.d.ts.map +1 -0
  4. package/dist/cli/commands/diff.js +143 -0
  5. package/dist/cli/commands/diff.js.map +1 -0
  6. package/dist/cli/commands/files.d.ts +35 -0
  7. package/dist/cli/commands/files.d.ts.map +1 -0
  8. package/dist/cli/commands/files.js +93 -0
  9. package/dist/cli/commands/files.js.map +1 -0
  10. package/dist/cli/index.js +89 -5
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/core/errors.d.ts +23 -0
  13. package/dist/core/errors.d.ts.map +1 -1
  14. package/dist/core/errors.js +38 -0
  15. package/dist/core/errors.js.map +1 -1
  16. package/dist/core/types.d.ts +4 -0
  17. package/dist/core/types.d.ts.map +1 -1
  18. package/dist/diff/comparator.d.ts +17 -0
  19. package/dist/diff/comparator.d.ts.map +1 -0
  20. package/dist/diff/comparator.js +158 -0
  21. package/dist/diff/comparator.js.map +1 -0
  22. package/dist/diff/engine.d.ts +10 -0
  23. package/dist/diff/engine.d.ts.map +1 -0
  24. package/dist/diff/engine.js +333 -0
  25. package/dist/diff/engine.js.map +1 -0
  26. package/dist/diff/hash.d.ts +6 -0
  27. package/dist/diff/hash.d.ts.map +1 -0
  28. package/dist/diff/hash.js +50 -0
  29. package/dist/diff/hash.js.map +1 -0
  30. package/dist/diff/key.d.ts +21 -0
  31. package/dist/diff/key.d.ts.map +1 -0
  32. package/dist/diff/key.js +107 -0
  33. package/dist/diff/key.js.map +1 -0
  34. package/dist/diff/reporter.d.ts +18 -0
  35. package/dist/diff/reporter.d.ts.map +1 -0
  36. package/dist/diff/reporter.js +133 -0
  37. package/dist/diff/reporter.js.map +1 -0
  38. package/dist/diff/schema.d.ts +7 -0
  39. package/dist/diff/schema.d.ts.map +1 -0
  40. package/dist/diff/schema.js +65 -0
  41. package/dist/diff/schema.js.map +1 -0
  42. package/dist/diff/storage/disk-index.d.ts +28 -0
  43. package/dist/diff/storage/disk-index.d.ts.map +1 -0
  44. package/dist/diff/storage/disk-index.js +105 -0
  45. package/dist/diff/storage/disk-index.js.map +1 -0
  46. package/dist/diff/storage/memory-index.d.ts +23 -0
  47. package/dist/diff/storage/memory-index.d.ts.map +1 -0
  48. package/dist/diff/storage/memory-index.js +69 -0
  49. package/dist/diff/storage/memory-index.js.map +1 -0
  50. package/dist/diff/storage/spillable-index.d.ts +30 -0
  51. package/dist/diff/storage/spillable-index.d.ts.map +1 -0
  52. package/dist/diff/storage/spillable-index.js +108 -0
  53. package/dist/diff/storage/spillable-index.js.map +1 -0
  54. package/dist/diff/types.d.ts +127 -0
  55. package/dist/diff/types.d.ts.map +1 -0
  56. package/dist/diff/types.js +2 -0
  57. package/dist/diff/types.js.map +1 -0
  58. package/dist/files/glob.d.ts +21 -0
  59. package/dist/files/glob.d.ts.map +1 -0
  60. package/dist/files/glob.js +132 -0
  61. package/dist/files/glob.js.map +1 -0
  62. package/dist/files/hash.d.ts +10 -0
  63. package/dist/files/hash.d.ts.map +1 -0
  64. package/dist/files/hash.js +67 -0
  65. package/dist/files/hash.js.map +1 -0
  66. package/dist/files/index.d.ts +6 -0
  67. package/dist/files/index.d.ts.map +1 -0
  68. package/dist/files/index.js +6 -0
  69. package/dist/files/index.js.map +1 -0
  70. package/dist/files/mime.d.ts +9 -0
  71. package/dist/files/mime.d.ts.map +1 -0
  72. package/dist/files/mime.js +128 -0
  73. package/dist/files/mime.js.map +1 -0
  74. package/dist/files/reader.d.ts +19 -0
  75. package/dist/files/reader.d.ts.map +1 -0
  76. package/dist/files/reader.js +344 -0
  77. package/dist/files/reader.js.map +1 -0
  78. package/dist/files/types.d.ts +47 -0
  79. package/dist/files/types.d.ts.map +1 -0
  80. package/dist/files/types.js +2 -0
  81. package/dist/files/types.js.map +1 -0
  82. package/dist/index.d.ts +17 -2
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +19 -2
  85. package/dist/index.js.map +1 -1
  86. package/dist/readers/csv.d.ts.map +1 -1
  87. package/dist/readers/csv.js +59 -27
  88. package/dist/readers/csv.js.map +1 -1
  89. package/dist/readers/index.d.ts +2 -0
  90. package/dist/readers/index.d.ts.map +1 -1
  91. package/dist/readers/index.js +57 -3
  92. package/dist/readers/index.js.map +1 -1
  93. package/dist/readers/json.d.ts.map +1 -1
  94. package/dist/readers/json.js +6 -8
  95. package/dist/readers/json.js.map +1 -1
  96. package/dist/readers/jsonl.d.ts.map +1 -1
  97. package/dist/readers/jsonl.js +5 -7
  98. package/dist/readers/jsonl.js.map +1 -1
  99. package/dist/readers/parquet.d.ts +17 -0
  100. package/dist/readers/parquet.d.ts.map +1 -0
  101. package/dist/readers/parquet.js +146 -0
  102. package/dist/readers/parquet.js.map +1 -0
  103. package/dist/transforms/expression.d.ts.map +1 -1
  104. package/dist/transforms/expression.js +73 -7
  105. package/dist/transforms/expression.js.map +1 -1
  106. package/dist/utils/compression.d.ts +30 -6
  107. package/dist/utils/compression.d.ts.map +1 -1
  108. package/dist/utils/compression.js +95 -18
  109. package/dist/utils/compression.js.map +1 -1
  110. package/dist/writers/csv.d.ts.map +1 -1
  111. package/dist/writers/csv.js +29 -17
  112. package/dist/writers/csv.js.map +1 -1
  113. package/dist/writers/index.d.ts +2 -0
  114. package/dist/writers/index.d.ts.map +1 -1
  115. package/dist/writers/index.js +49 -4
  116. package/dist/writers/index.js.map +1 -1
  117. package/dist/writers/json.d.ts +1 -1
  118. package/dist/writers/json.d.ts.map +1 -1
  119. package/dist/writers/json.js +9 -11
  120. package/dist/writers/json.js.map +1 -1
  121. package/dist/writers/jsonl.d.ts +1 -1
  122. package/dist/writers/jsonl.d.ts.map +1 -1
  123. package/dist/writers/jsonl.js +9 -11
  124. package/dist/writers/jsonl.js.map +1 -1
  125. package/dist/writers/markdown.d.ts +21 -0
  126. package/dist/writers/markdown.d.ts.map +1 -0
  127. package/dist/writers/markdown.js +82 -0
  128. package/dist/writers/markdown.js.map +1 -0
  129. package/dist/writers/parquet.d.ts +19 -0
  130. package/dist/writers/parquet.d.ts.map +1 -0
  131. package/dist/writers/parquet.js +129 -0
  132. package/dist/writers/parquet.js.map +1 -0
  133. package/package.json +16 -3
  134. package/skills/rowpipe/SKILL.md +263 -0
  135. package/benchmarks/memory-bench.ts +0 -109
  136. package/src/analytics/reduce.ts +0 -388
  137. package/src/analytics/schema-inference.ts +0 -217
  138. package/src/analytics/semantic-types.ts +0 -36
  139. package/src/analytics/stats.ts +0 -383
  140. package/src/analytics/validator.ts +0 -134
  141. package/src/cli/commands/cast.ts +0 -60
  142. package/src/cli/commands/convert.ts +0 -128
  143. package/src/cli/commands/filter.ts +0 -58
  144. package/src/cli/commands/inspect.ts +0 -193
  145. package/src/cli/commands/map.ts +0 -66
  146. package/src/cli/commands/reduce.ts +0 -74
  147. package/src/cli/commands/rename.ts +0 -59
  148. package/src/cli/commands/sample.ts +0 -61
  149. package/src/cli/commands/schema.ts +0 -86
  150. package/src/cli/commands/select.ts +0 -59
  151. package/src/cli/commands/stats.ts +0 -100
  152. package/src/cli/commands/validate.ts +0 -123
  153. package/src/cli/index.ts +0 -285
  154. package/src/core/batch.ts +0 -81
  155. package/src/core/errors.ts +0 -81
  156. package/src/core/pipeline.ts +0 -150
  157. package/src/core/types.ts +0 -110
  158. package/src/index.ts +0 -52
  159. package/src/readers/csv.ts +0 -302
  160. package/src/readers/index.ts +0 -88
  161. package/src/readers/json.ts +0 -256
  162. package/src/readers/jsonl.ts +0 -126
  163. package/src/readers/xlsx.ts +0 -182
  164. package/src/transforms/cast.ts +0 -212
  165. package/src/transforms/expression.ts +0 -1114
  166. package/src/transforms/filter.ts +0 -38
  167. package/src/transforms/map.ts +0 -99
  168. package/src/transforms/rename.ts +0 -47
  169. package/src/transforms/sample.ts +0 -57
  170. package/src/transforms/select.ts +0 -64
  171. package/src/utils/compression.ts +0 -43
  172. package/src/utils/formatting.ts +0 -75
  173. package/src/utils/progress.ts +0 -37
  174. package/src/writers/csv.ts +0 -106
  175. package/src/writers/index.ts +0 -87
  176. package/src/writers/json.ts +0 -52
  177. package/src/writers/jsonl.ts +0 -49
  178. package/src/writers/xlsx.ts +0 -87
  179. package/tests/analytics.test.ts +0 -119
  180. package/tests/cli-integration.test.ts +0 -187
  181. package/tests/map-reduce.test.ts +0 -223
  182. package/tests/readers-writers.test.ts +0 -189
  183. package/tests/transforms.test.ts +0 -199
  184. package/tsconfig.json +0 -21
  185. package/vitest.config.ts +0 -9
@@ -1,58 +0,0 @@
1
- import { createPipeline } from "../../core/pipeline.js";
2
- import { createReader, inferFormatFromPath as inferReaderFormat } from "../../readers/index.js";
3
- import { createWriter } from "../../writers/index.js";
4
- import { filterRows } from "../../transforms/filter.js";
5
- import { openReadableStream } from "../../utils/compression.js";
6
- import { logMemoryDebug } from "../../utils/formatting.js";
7
- import { ProgressReporter } from "../../utils/progress.js";
8
-
9
- export interface FilterCommandOptions {
10
- from?: string;
11
- to?: string;
12
- sheet?: string;
13
- delimiter?: string;
14
- batchSize?: string | number;
15
- quiet?: boolean;
16
- noProgress?: boolean;
17
- }
18
-
19
- export async function filterCommand(
20
- inputPath = "-",
21
- expression: string,
22
- options: FilterCommandOptions = {}
23
- ): Promise<void> {
24
- const effectiveBatchSize = Number(options.batchSize) || 1000;
25
- const progress = new ProgressReporter(options);
26
-
27
- let fromFormat = options.from?.toLowerCase();
28
- if (!fromFormat && inputPath !== "-") {
29
- fromFormat = inferReaderFormat(inputPath) ?? undefined;
30
- }
31
- if (!fromFormat) {
32
- fromFormat = "csv";
33
- }
34
-
35
- const toFormat = options.to?.toLowerCase() || (fromFormat === "xlsx" ? "csv" : fromFormat);
36
-
37
- const inputStream = openReadableStream(inputPath);
38
- const reader = createReader(inputStream, {
39
- format: fromFormat,
40
- sheet: options.sheet,
41
- delimiter: options.delimiter,
42
- batchSize: effectiveBatchSize,
43
- filePath: inputPath,
44
- });
45
-
46
- const writer = createWriter(process.stdout, {
47
- format: toFormat,
48
- delimiter: options.delimiter,
49
- });
50
-
51
- const pipeline = createPipeline(reader, { batchSize: effectiveBatchSize });
52
- pipeline.pipe(filterRows(expression));
53
- pipeline.onProgress((info) => progress.update(info));
54
-
55
- await pipeline.to(writer);
56
- progress.done();
57
- logMemoryDebug();
58
- }
@@ -1,193 +0,0 @@
1
- import { stat } from "node:fs/promises";
2
- import { DatasetStatsAggregator } from "../../analytics/stats.js";
3
- import { SchemaInferenceAggregator } from "../../analytics/schema-inference.js";
4
- import { InvalidArgumentError } from "../../core/errors.js";
5
- import { createPipeline } from "../../core/pipeline.js";
6
- import { createReader, inferFormatFromPath } from "../../readers/index.js";
7
- import { openReadableStream } from "../../utils/compression.js";
8
- import {
9
- formatBytes,
10
- formatDecimal,
11
- formatNumber,
12
- formatTable,
13
- logMemoryDebug,
14
- } from "../../utils/formatting.js";
15
- import { ProgressReporter } from "../../utils/progress.js";
16
-
17
- export interface InspectCommandOptions {
18
- sheet?: string;
19
- path?: string;
20
- delimiter?: string;
21
- json?: boolean;
22
- quiet?: boolean;
23
- noProgress?: boolean;
24
- }
25
-
26
- export async function inspectCommand(
27
- inputPath = "-",
28
- options: InspectCommandOptions = {}
29
- ): Promise<void> {
30
- const progress = new ProgressReporter(options);
31
-
32
- let fileSize: number | undefined;
33
- if (inputPath !== "-") {
34
- try {
35
- const fileStat = await stat(inputPath);
36
- fileSize = fileStat.size;
37
- } catch {
38
- // Ignore if cannot stat
39
- }
40
- }
41
-
42
- const format =
43
- inputPath !== "-" ? inferFormatFromPath(inputPath) || "CSV" : "CSV";
44
-
45
- const stream = openReadableStream(inputPath);
46
- const reader = createReader(stream, {
47
- format,
48
- sheet: options.sheet,
49
- path: options.path,
50
- delimiter: options.delimiter,
51
- filePath: inputPath,
52
- });
53
-
54
- // If XLSX without a specific --sheet requested, show rich workbook & sheet breakdown
55
- if (format === "xlsx" && !options.sheet && reader.inspect) {
56
- const meta = await reader.inspect();
57
- if (options.json) {
58
- process.stdout.write(
59
- JSON.stringify(
60
- {
61
- file: inputPath === "-" ? "stdin" : inputPath,
62
- format: "XLSX",
63
- sizeBytes: fileSize,
64
- sizeFormatted: fileSize !== undefined ? formatBytes(fileSize) : undefined,
65
- sheetsCount: meta.sheets?.length ?? 0,
66
- sheets: meta.sheets,
67
- },
68
- null,
69
- 2
70
- ) + "\n"
71
- );
72
- logMemoryDebug();
73
- return;
74
- }
75
-
76
- process.stdout.write(`File: ${inputPath === "-" ? "stdin" : inputPath}\n`);
77
- process.stdout.write(`Format: XLSX\n`);
78
- if (fileSize !== undefined) {
79
- process.stdout.write(`Size: ${formatBytes(fileSize)}\n`);
80
- }
81
-
82
- if (meta.sheets && meta.sheets.length > 0) {
83
- process.stdout.write(`Sheets: ${meta.sheets.length}\n\n`);
84
- const sheetRows = meta.sheets.map((s) => {
85
- const previewCols = (s.columns || []).slice(0, 5).join(", ") + (s.columns && s.columns.length > 5 ? ", ..." : "");
86
- return [
87
- s.name,
88
- formatNumber(s.rowCount),
89
- s.columnCount !== undefined ? String(s.columnCount) : "-",
90
- previewCols,
91
- ];
92
- });
93
-
94
- process.stdout.write(
95
- formatTable(
96
- ["SHEET", "ROWS", "COLUMNS", "PREVIEW COLUMNS"],
97
- sheetRows,
98
- ["left", "right", "right", "left"]
99
- ) + "\n\nTip: Run with --sheet <name> to inspect a specific sheet in full detail.\n"
100
- );
101
- }
102
- logMemoryDebug();
103
- return;
104
- }
105
-
106
- // General inspection across stream
107
- const schemaAgg = new SchemaInferenceAggregator();
108
- const statsAgg = new DatasetStatsAggregator();
109
-
110
- const pipeline = createPipeline(reader);
111
- pipeline.onProgress((info) => progress.update(info));
112
-
113
- for await (const row of pipeline.rows()) {
114
- schemaAgg.add(row);
115
- statsAgg.add(row);
116
- }
117
-
118
- progress.done();
119
-
120
- const schemaRes = schemaAgg.result();
121
- const statsRes = statsAgg.result();
122
-
123
- const totalRows = schemaRes.totalRowsScanned;
124
- const columnCount = schemaRes.columns.length;
125
-
126
- const columnDetails = schemaRes.columns.map((col) => {
127
- const nullPct =
128
- col.sampleCount > 0 ? (col.nullCount / col.sampleCount) * 100 : 0;
129
- const colStats = statsRes.columns[col.name];
130
- const distinctCount =
131
- colStats?.numeric?.approxDistinct ?? colStats?.string?.approxDistinct ?? 0;
132
- const uniquePct =
133
- totalRows > 0 ? Math.min(100, (distinctCount / totalRows) * 100) : 0;
134
-
135
- return {
136
- name: col.name,
137
- type: col.type,
138
- nullPct,
139
- uniquePct,
140
- semantic: col.semantic,
141
- };
142
- });
143
-
144
- if (options.json) {
145
- const resultJson = {
146
- file: inputPath === "-" ? "stdin" : inputPath,
147
- format: format.toUpperCase(),
148
- sheet: options.sheet,
149
- sizeBytes: fileSize,
150
- sizeFormatted: fileSize !== undefined ? formatBytes(fileSize) : undefined,
151
- rows: totalRows,
152
- columnsCount: columnCount,
153
- columns: columnDetails.map((c) => ({
154
- name: c.name,
155
- type: c.type,
156
- nullPercentage: Math.round(c.nullPct * 10) / 10,
157
- approxUniquePercentage: Math.round(c.uniquePct * 10) / 10,
158
- semantic: c.semantic,
159
- })),
160
- };
161
- process.stdout.write(JSON.stringify(resultJson, null, 2) + "\n");
162
- } else {
163
- process.stdout.write(`File: ${inputPath === "-" ? "stdin" : inputPath}\n`);
164
- process.stdout.write(`Format: ${format.toUpperCase()}`);
165
- if (options.sheet) {
166
- process.stdout.write(` (Sheet: ${options.sheet})`);
167
- }
168
- process.stdout.write("\n");
169
-
170
- if (fileSize !== undefined) {
171
- process.stdout.write(`Size: ${formatBytes(fileSize)}\n`);
172
- }
173
- process.stdout.write(`Rows: ${formatNumber(totalRows)}\n`);
174
- process.stdout.write(`Columns: ${columnCount}\n\n`);
175
-
176
- const tableRows = columnDetails.map((c) => [
177
- c.name,
178
- c.type,
179
- `${formatDecimal(c.nullPct, 1)}%`,
180
- `${formatDecimal(c.uniquePct, 1)}%`,
181
- ]);
182
-
183
- process.stdout.write(
184
- formatTable(
185
- ["COLUMN", "TYPE", "NULL", "UNIQUE*"],
186
- tableRows,
187
- ["left", "left", "right", "right"]
188
- ) + "\n\n* approximate\n"
189
- );
190
- }
191
-
192
- logMemoryDebug();
193
- }
@@ -1,66 +0,0 @@
1
- import { InvalidArgumentError } from "../../core/errors.js";
2
- import { createPipeline } from "../../core/pipeline.js";
3
- import { createReader, inferFormatFromPath as inferReaderFormat } from "../../readers/index.js";
4
- import { createWriter } from "../../writers/index.js";
5
- import { mapRows, parseMapSpecs } from "../../transforms/map.js";
6
- import { openReadableStream } from "../../utils/compression.js";
7
- import { logMemoryDebug } from "../../utils/formatting.js";
8
- import { ProgressReporter } from "../../utils/progress.js";
9
-
10
- export interface MapCommandOptions {
11
- from?: string;
12
- to?: string;
13
- sheet?: string;
14
- delimiter?: string;
15
- batchSize?: string | number;
16
- quiet?: boolean;
17
- noProgress?: boolean;
18
- }
19
-
20
- export async function mapCommand(
21
- inputPath = "-",
22
- specs: string[],
23
- options: MapCommandOptions = {}
24
- ): Promise<void> {
25
- if (!specs || specs.length === 0) {
26
- throw new InvalidArgumentError(
27
- "At least one map specification is required (e.g. rowpipe map users.csv 'full_name=concat(first, \" \", last)')"
28
- );
29
- }
30
-
31
- const effectiveBatchSize = Number(options.batchSize) || 1000;
32
- const progress = new ProgressReporter(options);
33
- const parsedSpecs = parseMapSpecs(specs);
34
-
35
- let fromFormat = options.from?.toLowerCase();
36
- if (!fromFormat && inputPath !== "-") {
37
- fromFormat = inferReaderFormat(inputPath) ?? undefined;
38
- }
39
- if (!fromFormat) {
40
- fromFormat = "csv";
41
- }
42
-
43
- const toFormat = options.to?.toLowerCase() || (fromFormat === "xlsx" ? "csv" : fromFormat);
44
-
45
- const inputStream = openReadableStream(inputPath);
46
- const reader = createReader(inputStream, {
47
- format: fromFormat,
48
- sheet: options.sheet,
49
- delimiter: options.delimiter,
50
- batchSize: effectiveBatchSize,
51
- filePath: inputPath,
52
- });
53
-
54
- const writer = createWriter(process.stdout, {
55
- format: toFormat,
56
- delimiter: options.delimiter,
57
- });
58
-
59
- const pipeline = createPipeline(reader, { batchSize: effectiveBatchSize });
60
- pipeline.pipe(mapRows(parsedSpecs));
61
- pipeline.onProgress((info) => progress.update(info));
62
-
63
- await pipeline.to(writer);
64
- progress.done();
65
- logMemoryDebug();
66
- }
@@ -1,74 +0,0 @@
1
- import { InvalidArgumentError } from "../../core/errors.js";
2
- import { createPipeline } from "../../core/pipeline.js";
3
- import { createReader, inferFormatFromPath as inferReaderFormat } from "../../readers/index.js";
4
- import { createWriter } from "../../writers/index.js";
5
- import { parseReduceSpecs, reduceRows } from "../../analytics/reduce.js";
6
- import { openReadableStream } from "../../utils/compression.js";
7
- import { logMemoryDebug } from "../../utils/formatting.js";
8
- import { ProgressReporter } from "../../utils/progress.js";
9
-
10
- export interface ReduceCommandOptions {
11
- by?: string;
12
- from?: string;
13
- to?: string;
14
- sheet?: string;
15
- delimiter?: string;
16
- batchSize?: string | number;
17
- quiet?: boolean;
18
- noProgress?: boolean;
19
- }
20
-
21
- export async function reduceCommand(
22
- inputPath = "-",
23
- specs: string[],
24
- options: ReduceCommandOptions = {}
25
- ): Promise<void> {
26
- if (!specs || specs.length === 0) {
27
- throw new InvalidArgumentError(
28
- "At least one aggregation specification is required (e.g. rowpipe reduce sales.csv 'total=sum(revenue)' --by country)"
29
- );
30
- }
31
-
32
- const effectiveBatchSize = Number(options.batchSize) || 1000;
33
- const progress = new ProgressReporter(options);
34
- const parsedSpecs = parseReduceSpecs(specs);
35
-
36
- const byCols = options.by
37
- ? options.by
38
- .split(",")
39
- .map((c) => c.trim())
40
- .filter(Boolean)
41
- : undefined;
42
-
43
- let fromFormat = options.from?.toLowerCase();
44
- if (!fromFormat && inputPath !== "-") {
45
- fromFormat = inferReaderFormat(inputPath) ?? undefined;
46
- }
47
- if (!fromFormat) {
48
- fromFormat = "csv";
49
- }
50
-
51
- const toFormat = options.to?.toLowerCase() || (fromFormat === "xlsx" ? "csv" : fromFormat);
52
-
53
- const inputStream = openReadableStream(inputPath);
54
- const reader = createReader(inputStream, {
55
- format: fromFormat,
56
- sheet: options.sheet,
57
- delimiter: options.delimiter,
58
- batchSize: effectiveBatchSize,
59
- filePath: inputPath,
60
- });
61
-
62
- const writer = createWriter(process.stdout, {
63
- format: toFormat,
64
- delimiter: options.delimiter,
65
- });
66
-
67
- const pipeline = createPipeline(reader, { batchSize: effectiveBatchSize });
68
- pipeline.pipe(reduceRows({ by: byCols, aggregations: parsedSpecs }));
69
- pipeline.onProgress((info) => progress.update(info));
70
-
71
- await pipeline.to(writer);
72
- progress.done();
73
- logMemoryDebug();
74
- }
@@ -1,59 +0,0 @@
1
- import { createPipeline } from "../../core/pipeline.js";
2
- import { createReader, inferFormatFromPath as inferReaderFormat } from "../../readers/index.js";
3
- import { createWriter } from "../../writers/index.js";
4
- import { parseRenameSpecs, renameColumns } from "../../transforms/rename.js";
5
- import { openReadableStream } from "../../utils/compression.js";
6
- import { logMemoryDebug } from "../../utils/formatting.js";
7
- import { ProgressReporter } from "../../utils/progress.js";
8
-
9
- export interface RenameCommandOptions {
10
- from?: string;
11
- to?: string;
12
- sheet?: string;
13
- delimiter?: string;
14
- batchSize?: string | number;
15
- quiet?: boolean;
16
- noProgress?: boolean;
17
- }
18
-
19
- export async function renameCommand(
20
- inputPath = "-",
21
- specs: string[],
22
- options: RenameCommandOptions = {}
23
- ): Promise<void> {
24
- const effectiveBatchSize = Number(options.batchSize) || 1000;
25
- const progress = new ProgressReporter(options);
26
-
27
- let fromFormat = options.from?.toLowerCase();
28
- if (!fromFormat && inputPath !== "-") {
29
- fromFormat = inferReaderFormat(inputPath) ?? undefined;
30
- }
31
- if (!fromFormat) {
32
- fromFormat = "csv";
33
- }
34
-
35
- const toFormat = options.to?.toLowerCase() || (fromFormat === "xlsx" ? "csv" : fromFormat);
36
- const mapping = parseRenameSpecs(specs);
37
-
38
- const inputStream = openReadableStream(inputPath);
39
- const reader = createReader(inputStream, {
40
- format: fromFormat,
41
- sheet: options.sheet,
42
- delimiter: options.delimiter,
43
- batchSize: effectiveBatchSize,
44
- filePath: inputPath,
45
- });
46
-
47
- const writer = createWriter(process.stdout, {
48
- format: toFormat,
49
- delimiter: options.delimiter,
50
- });
51
-
52
- const pipeline = createPipeline(reader, { batchSize: effectiveBatchSize });
53
- pipeline.pipe(renameColumns(mapping));
54
- pipeline.onProgress((info) => progress.update(info));
55
-
56
- await pipeline.to(writer);
57
- progress.done();
58
- logMemoryDebug();
59
- }
@@ -1,61 +0,0 @@
1
- import { createPipeline } from "../../core/pipeline.js";
2
- import { createReader, inferFormatFromPath as inferReaderFormat } from "../../readers/index.js";
3
- import { createWriter } from "../../writers/index.js";
4
- import { sampleRows } from "../../transforms/sample.js";
5
- import { openReadableStream } from "../../utils/compression.js";
6
- import { logMemoryDebug } from "../../utils/formatting.js";
7
- import { ProgressReporter } from "../../utils/progress.js";
8
-
9
- export interface SampleCommandOptions {
10
- rows?: string | number;
11
- seed?: string | number;
12
- from?: string;
13
- to?: string;
14
- sheet?: string;
15
- delimiter?: string;
16
- batchSize?: string | number;
17
- quiet?: boolean;
18
- noProgress?: boolean;
19
- }
20
-
21
- export async function sampleCommand(
22
- inputPath = "-",
23
- options: SampleCommandOptions = {}
24
- ): Promise<void> {
25
- const sampleCount = options.rows !== undefined ? Number(options.rows) : 1000;
26
- const seed = options.seed !== undefined ? Number(options.seed) : undefined;
27
- const effectiveBatchSize = Number(options.batchSize) || 1000;
28
- const progress = new ProgressReporter(options);
29
-
30
- let fromFormat = options.from?.toLowerCase();
31
- if (!fromFormat && inputPath !== "-") {
32
- fromFormat = inferReaderFormat(inputPath) ?? undefined;
33
- }
34
- if (!fromFormat) {
35
- fromFormat = "csv";
36
- }
37
-
38
- const toFormat = options.to?.toLowerCase() || (fromFormat === "xlsx" ? "csv" : fromFormat);
39
-
40
- const inputStream = openReadableStream(inputPath);
41
- const reader = createReader(inputStream, {
42
- format: fromFormat,
43
- sheet: options.sheet,
44
- delimiter: options.delimiter,
45
- batchSize: effectiveBatchSize,
46
- filePath: inputPath,
47
- });
48
-
49
- const writer = createWriter(process.stdout, {
50
- format: toFormat,
51
- delimiter: options.delimiter,
52
- });
53
-
54
- const pipeline = createPipeline(reader, { batchSize: effectiveBatchSize });
55
- pipeline.pipe(sampleRows({ rows: sampleCount, seed }));
56
- pipeline.onProgress((info) => progress.update(info));
57
-
58
- await pipeline.to(writer);
59
- progress.done();
60
- logMemoryDebug();
61
- }
@@ -1,86 +0,0 @@
1
- import { SchemaInferenceAggregator } from "../../analytics/schema-inference.js";
2
- import { createPipeline } from "../../core/pipeline.js";
3
- import { createReader, inferFormatFromPath } from "../../readers/index.js";
4
- import { openReadableStream } from "../../utils/compression.js";
5
- import { formatTable, logMemoryDebug } from "../../utils/formatting.js";
6
- import { ProgressReporter } from "../../utils/progress.js";
7
-
8
- export interface SchemaCommandOptions {
9
- from?: string;
10
- sheet?: string;
11
- path?: string;
12
- delimiter?: string;
13
- sample?: string | number;
14
- full?: boolean;
15
- json?: boolean;
16
- quiet?: boolean;
17
- noProgress?: boolean;
18
- }
19
-
20
- export async function schemaCommand(
21
- inputPath = "-",
22
- options: SchemaCommandOptions = {}
23
- ): Promise<void> {
24
- const progress = new ProgressReporter(options);
25
-
26
- let fromFormat = options.from?.toLowerCase();
27
- if (!fromFormat && inputPath !== "-") {
28
- fromFormat = inferFormatFromPath(inputPath) ?? undefined;
29
- }
30
- if (!fromFormat) {
31
- fromFormat = "csv";
32
- }
33
-
34
- const sampleSize = options.full
35
- ? Number.POSITIVE_INFINITY
36
- : options.sample !== undefined
37
- ? Number(options.sample)
38
- : 10000;
39
-
40
- const inputStream = openReadableStream(inputPath);
41
- const reader = createReader(inputStream, {
42
- format: fromFormat,
43
- sheet: options.sheet,
44
- path: options.path,
45
- delimiter: options.delimiter,
46
- filePath: inputPath,
47
- });
48
-
49
- const schemaAgg = new SchemaInferenceAggregator({ sample: sampleSize });
50
- const pipeline = createPipeline(reader);
51
- pipeline.onProgress((info) => progress.update(info));
52
-
53
- for await (const row of pipeline.rows()) {
54
- schemaAgg.add(row);
55
- }
56
-
57
- progress.done();
58
- const res = schemaAgg.result();
59
-
60
- if (options.json) {
61
- process.stdout.write(JSON.stringify(res, null, 2) + "\n");
62
- } else {
63
- const tableRows = res.columns.map((col) => {
64
- let typeDisplay = col.type as string;
65
- if (col.semantic) {
66
- typeDisplay += ` (${col.semantic})`;
67
- }
68
- return [
69
- col.name,
70
- typeDisplay,
71
- col.nullable ? "true" : "false",
72
- `${col.confidence}%`,
73
- ];
74
- });
75
-
76
- process.stdout.write(
77
- formatTable(
78
- ["COLUMN", "TYPE", "NULLABLE", "CONFIDENCE"],
79
- tableRows,
80
- ["left", "left", "left", "right"]
81
- ) + "\n"
82
- );
83
- }
84
-
85
- logMemoryDebug();
86
- }
@@ -1,59 +0,0 @@
1
- import { createPipeline } from "../../core/pipeline.js";
2
- import { createReader, inferFormatFromPath as inferReaderFormat } from "../../readers/index.js";
3
- import { createWriter } from "../../writers/index.js";
4
- import { selectColumns } from "../../transforms/select.js";
5
- import { openReadableStream } from "../../utils/compression.js";
6
- import { logMemoryDebug } from "../../utils/formatting.js";
7
- import { ProgressReporter } from "../../utils/progress.js";
8
-
9
- export interface SelectCommandOptions {
10
- from?: string;
11
- to?: string;
12
- sheet?: string;
13
- delimiter?: string;
14
- batchSize?: string | number;
15
- quiet?: boolean;
16
- noProgress?: boolean;
17
- }
18
-
19
- export async function selectCommand(
20
- inputPath = "-",
21
- columnsArg: string,
22
- options: SelectCommandOptions = {}
23
- ): Promise<void> {
24
- const effectiveBatchSize = Number(options.batchSize) || 1000;
25
- const progress = new ProgressReporter(options);
26
-
27
- let fromFormat = options.from?.toLowerCase();
28
- if (!fromFormat && inputPath !== "-") {
29
- fromFormat = inferReaderFormat(inputPath) ?? undefined;
30
- }
31
- if (!fromFormat) {
32
- fromFormat = "csv";
33
- }
34
-
35
- const toFormat = options.to?.toLowerCase() || (fromFormat === "xlsx" ? "csv" : fromFormat);
36
- const columns = columnsArg.split(",").map((c) => c.trim());
37
-
38
- const inputStream = openReadableStream(inputPath);
39
- const reader = createReader(inputStream, {
40
- format: fromFormat,
41
- sheet: options.sheet,
42
- delimiter: options.delimiter,
43
- batchSize: effectiveBatchSize,
44
- filePath: inputPath,
45
- });
46
-
47
- const writer = createWriter(process.stdout, {
48
- format: toFormat,
49
- delimiter: options.delimiter,
50
- });
51
-
52
- const pipeline = createPipeline(reader, { batchSize: effectiveBatchSize });
53
- pipeline.pipe(selectColumns(columns));
54
- pipeline.onProgress((info) => progress.update(info));
55
-
56
- await pipeline.to(writer);
57
- progress.done();
58
- logMemoryDebug();
59
- }