jsonstat-io 0.1.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.
- package/LICENSE +201 -0
- package/README.md +200 -0
- package/dist/arrow/index.cjs +60 -0
- package/dist/arrow/index.cjs.map +1 -0
- package/dist/arrow/index.d.cts +125 -0
- package/dist/arrow/index.d.ts +125 -0
- package/dist/arrow/index.js +3 -0
- package/dist/arrow/index.js.map +1 -0
- package/dist/arrowToCube-BdRWZ5oG.d.cts +29 -0
- package/dist/arrowToCube-Mjr79ZHM.d.ts +29 -0
- package/dist/chunk-2HY7NRKX.js +259 -0
- package/dist/chunk-2HY7NRKX.js.map +1 -0
- package/dist/chunk-62NIY7ML.js +191 -0
- package/dist/chunk-62NIY7ML.js.map +1 -0
- package/dist/chunk-AXUZF6O5.cjs +352 -0
- package/dist/chunk-AXUZF6O5.cjs.map +1 -0
- package/dist/chunk-EFRDFQOT.js +335 -0
- package/dist/chunk-EFRDFQOT.js.map +1 -0
- package/dist/chunk-GDKDYLZ4.cjs +263 -0
- package/dist/chunk-GDKDYLZ4.cjs.map +1 -0
- package/dist/chunk-IDTQZG4B.js +432 -0
- package/dist/chunk-IDTQZG4B.js.map +1 -0
- package/dist/chunk-KFIKGBIJ.cjs +200 -0
- package/dist/chunk-KFIKGBIJ.cjs.map +1 -0
- package/dist/chunk-L65CRXTV.js +64 -0
- package/dist/chunk-L65CRXTV.js.map +1 -0
- package/dist/chunk-PHLCWTHB.cjs +446 -0
- package/dist/chunk-PHLCWTHB.cjs.map +1 -0
- package/dist/chunk-VQCS4LVD.cjs +166 -0
- package/dist/chunk-VQCS4LVD.cjs.map +1 -0
- package/dist/chunk-VYS7DPB3.js +162 -0
- package/dist/chunk-VYS7DPB3.js.map +1 -0
- package/dist/chunk-ZEDTWRDN.cjs +70 -0
- package/dist/chunk-ZEDTWRDN.cjs.map +1 -0
- package/dist/cli/index.cjs +337 -0
- package/dist/cli/index.cjs.map +1 -0
- package/dist/cli/index.d.cts +90 -0
- package/dist/cli/index.d.ts +90 -0
- package/dist/cli/index.js +333 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cubeBuilder-BEGA4C5Y.js +4 -0
- package/dist/cubeBuilder-BEGA4C5Y.js.map +1 -0
- package/dist/cubeBuilder-ZU76VVEX.cjs +25 -0
- package/dist/cubeBuilder-ZU76VVEX.cjs.map +1 -0
- package/dist/cubeReader-7QVUF3TI.js +4 -0
- package/dist/cubeReader-7QVUF3TI.js.map +1 -0
- package/dist/cubeReader-UN2BHQWK.cjs +21 -0
- package/dist/cubeReader-UN2BHQWK.cjs.map +1 -0
- package/dist/index.cjs +172 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +445 -0
- package/dist/index.d.ts +445 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/ir-BArfNxo-.d.cts +143 -0
- package/dist/ir-Jae2ymov.d.ts +143 -0
- package/dist/jsonstat-BX4mBLci.d.cts +179 -0
- package/dist/jsonstat-BX4mBLci.d.ts +179 -0
- package/dist/sources/csv.cjs +40 -0
- package/dist/sources/csv.cjs.map +1 -0
- package/dist/sources/csv.d.cts +112 -0
- package/dist/sources/csv.d.ts +112 -0
- package/dist/sources/csv.js +3 -0
- package/dist/sources/csv.js.map +1 -0
- package/dist/sources/csvw.cjs +236 -0
- package/dist/sources/csvw.cjs.map +1 -0
- package/dist/sources/csvw.d.cts +143 -0
- package/dist/sources/csvw.d.ts +143 -0
- package/dist/sources/csvw.js +230 -0
- package/dist/sources/csvw.js.map +1 -0
- package/dist/sources/duckdb.cjs +121 -0
- package/dist/sources/duckdb.cjs.map +1 -0
- package/dist/sources/duckdb.d.cts +111 -0
- package/dist/sources/duckdb.d.ts +111 -0
- package/dist/sources/duckdb.js +115 -0
- package/dist/sources/duckdb.js.map +1 -0
- package/dist/sources/parquet.cjs +117 -0
- package/dist/sources/parquet.cjs.map +1 -0
- package/dist/sources/parquet.d.cts +83 -0
- package/dist/sources/parquet.d.ts +83 -0
- package/dist/sources/parquet.js +111 -0
- package/dist/sources/parquet.js.map +1 -0
- package/dist/sources/polars.cjs +94 -0
- package/dist/sources/polars.cjs.map +1 -0
- package/dist/sources/polars.d.cts +91 -0
- package/dist/sources/polars.d.ts +91 -0
- package/dist/sources/polars.js +87 -0
- package/dist/sources/polars.js.map +1 -0
- package/docs/api.md +322 -0
- package/docs/architecture.md +140 -0
- package/docs/cli.md +159 -0
- package/docs/formats/arrow.md +111 -0
- package/docs/formats/csv.md +115 -0
- package/docs/formats/csvw.md +152 -0
- package/docs/formats/duckdb.md +151 -0
- package/docs/formats/parquet.md +132 -0
- package/docs/formats/polars.md +111 -0
- package/docs/mapping.md +136 -0
- package/package.json +119 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var chunkAXUZF6O5_cjs = require('../chunk-AXUZF6O5.cjs');
|
|
5
|
+
require('../chunk-GDKDYLZ4.cjs');
|
|
6
|
+
require('../chunk-VQCS4LVD.cjs');
|
|
7
|
+
require('../chunk-ZEDTWRDN.cjs');
|
|
8
|
+
require('../chunk-PHLCWTHB.cjs');
|
|
9
|
+
var commander = require('commander');
|
|
10
|
+
var apacheArrow = require('apache-arrow');
|
|
11
|
+
var url = require('url');
|
|
12
|
+
|
|
13
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
14
|
+
// src/cli/args.ts
|
|
15
|
+
var ALLOWED_FROM = /* @__PURE__ */ new Set([
|
|
16
|
+
"auto",
|
|
17
|
+
"parquet",
|
|
18
|
+
"arrow",
|
|
19
|
+
"csv",
|
|
20
|
+
"csvw",
|
|
21
|
+
"jsonstat",
|
|
22
|
+
"json"
|
|
23
|
+
]);
|
|
24
|
+
var ALLOWED_TO = /* @__PURE__ */ new Set([
|
|
25
|
+
"jsonstat",
|
|
26
|
+
"arrow",
|
|
27
|
+
"parquet",
|
|
28
|
+
"csv",
|
|
29
|
+
"csvw"
|
|
30
|
+
]);
|
|
31
|
+
var ALLOWED_STATUS_FORM = /* @__PURE__ */ new Set([
|
|
32
|
+
"auto",
|
|
33
|
+
"array",
|
|
34
|
+
"string",
|
|
35
|
+
"object",
|
|
36
|
+
"none"
|
|
37
|
+
]);
|
|
38
|
+
function parseRoleFlag(raw) {
|
|
39
|
+
if (!raw) return void 0;
|
|
40
|
+
const roles = {};
|
|
41
|
+
for (const pair of raw.split(",")) {
|
|
42
|
+
const eq = pair.indexOf("=");
|
|
43
|
+
if (eq < 0) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
`Invalid --role entry "${pair}". Expected "<role>=<column>" (e.g. time=year).`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
const role = pair.slice(0, eq).trim();
|
|
49
|
+
const col = pair.slice(eq + 1).trim();
|
|
50
|
+
if (role !== "time" && role !== "geo" && role !== "metric") {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`Invalid --role "${role}". Must be one of: time, geo, metric.`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
if (!col) {
|
|
56
|
+
throw new Error(`--role "${role}=" is missing a column name.`);
|
|
57
|
+
}
|
|
58
|
+
(roles[role] ?? (roles[role] = [])).push(col);
|
|
59
|
+
}
|
|
60
|
+
return roles;
|
|
61
|
+
}
|
|
62
|
+
function parseDimensionsFlag(raw) {
|
|
63
|
+
if (!raw) return void 0;
|
|
64
|
+
const dims = raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
65
|
+
if (dims.length === 0) {
|
|
66
|
+
throw new Error("--dimensions requires at least one column name.");
|
|
67
|
+
}
|
|
68
|
+
return dims;
|
|
69
|
+
}
|
|
70
|
+
function parseThreshold(raw) {
|
|
71
|
+
if (raw === void 0) return void 0;
|
|
72
|
+
const n = Number.parseFloat(raw);
|
|
73
|
+
if (Number.isNaN(n) || n < 0 || n > 1) {
|
|
74
|
+
throw new Error(`--threshold must be a number between 0 and 1, got "${raw}".`);
|
|
75
|
+
}
|
|
76
|
+
return n;
|
|
77
|
+
}
|
|
78
|
+
function resolveValueForm(raw) {
|
|
79
|
+
if (raw.sparse) return "sparse";
|
|
80
|
+
if (raw.dense) return "dense";
|
|
81
|
+
return "auto";
|
|
82
|
+
}
|
|
83
|
+
function parseCliOptions(raw) {
|
|
84
|
+
if (raw.from !== void 0 && !ALLOWED_FROM.has(raw.from)) {
|
|
85
|
+
throw new Error(
|
|
86
|
+
`--from "${raw.from}" is not supported. Use one of: ${[...ALLOWED_FROM].join(", ")}.`
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
const to = raw.to ?? "jsonstat";
|
|
90
|
+
if (!ALLOWED_TO.has(to)) {
|
|
91
|
+
throw new Error(
|
|
92
|
+
`--to "${to}" is not supported. Use one of: ${[...ALLOWED_TO].join(", ")}.`
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
if (raw.statusForm !== void 0 && !ALLOWED_STATUS_FORM.has(raw.statusForm)) {
|
|
96
|
+
throw new Error(
|
|
97
|
+
`--status-form "${raw.statusForm}" is invalid. Use one of: ${[...ALLOWED_STATUS_FORM].join(", ")}.`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
const meta = {};
|
|
101
|
+
if (raw.label) meta.label = raw.label;
|
|
102
|
+
if (raw.source) meta.source = raw.source;
|
|
103
|
+
if (raw.updated) meta.updated = raw.updated;
|
|
104
|
+
const buildOptions = {
|
|
105
|
+
valueForm: resolveValueForm(raw),
|
|
106
|
+
sparseThreshold: parseThreshold(raw.threshold),
|
|
107
|
+
statusForm: raw.statusForm,
|
|
108
|
+
meta: Object.keys(meta).length > 0 ? meta : void 0
|
|
109
|
+
};
|
|
110
|
+
const importOptions = {
|
|
111
|
+
from: raw.from ?? "auto",
|
|
112
|
+
measure: raw.measure,
|
|
113
|
+
dimensions: parseDimensionsFlag(raw.dimensions),
|
|
114
|
+
status: raw.status,
|
|
115
|
+
roles: parseRoleFlag(raw.role),
|
|
116
|
+
build: buildOptions,
|
|
117
|
+
delimiter: raw.delimiter,
|
|
118
|
+
csvwMetadata: raw.csvwMetadata ? safeJsonParse(raw.csvwMetadata, "--csvw-metadata") : void 0
|
|
119
|
+
};
|
|
120
|
+
return {
|
|
121
|
+
to,
|
|
122
|
+
importOptions,
|
|
123
|
+
buildOptions,
|
|
124
|
+
validate: raw.validate === true,
|
|
125
|
+
output: raw.output,
|
|
126
|
+
pretty: raw.noPretty ? false : raw.pretty ?? true,
|
|
127
|
+
canonicalKeys: raw.noCanonicalKeys ? false : raw.canonicalKeys ?? true
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function safeJsonParse(text, flagName) {
|
|
131
|
+
try {
|
|
132
|
+
return JSON.parse(text);
|
|
133
|
+
} catch (e) {
|
|
134
|
+
throw new Error(
|
|
135
|
+
`${flagName} must be valid JSON: ${e.message}`
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// src/cli/index.ts
|
|
141
|
+
async function writeOutput(text, output) {
|
|
142
|
+
if (!output || output === "-") {
|
|
143
|
+
const { stdout } = await import('process');
|
|
144
|
+
stdout.write(text);
|
|
145
|
+
if (!text.endsWith("\n")) stdout.write("\n");
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const { writeFile } = await import('fs/promises');
|
|
149
|
+
await writeFile(output, text, "utf8");
|
|
150
|
+
}
|
|
151
|
+
async function writeBinaryOutput(bytes, output) {
|
|
152
|
+
if (!output || output === "-") {
|
|
153
|
+
const { stdout } = await import('process');
|
|
154
|
+
stdout.write(Buffer.from(bytes));
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const { writeFile } = await import('fs/promises');
|
|
158
|
+
await writeFile(output, bytes);
|
|
159
|
+
}
|
|
160
|
+
async function validateDataset(dataset) {
|
|
161
|
+
try {
|
|
162
|
+
const spec = "jsonstat-validator";
|
|
163
|
+
const mod = await import(
|
|
164
|
+
/* @vite-ignore */
|
|
165
|
+
spec
|
|
166
|
+
);
|
|
167
|
+
const validator = mod?.validate ?? mod?.default?.validate ?? mod?.default?.default?.validate;
|
|
168
|
+
if (typeof validator !== "function") {
|
|
169
|
+
return ["jsonstat-validator is installed but has no validate() export."];
|
|
170
|
+
}
|
|
171
|
+
const result = validator(dataset);
|
|
172
|
+
return result.valid ? [] : result.errors;
|
|
173
|
+
} catch {
|
|
174
|
+
return [
|
|
175
|
+
"jsonstat-validator is not installed. Install it with: npm i -D jsonstat-validator"
|
|
176
|
+
];
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
var VERSION = "0.1.0";
|
|
180
|
+
function createProgram() {
|
|
181
|
+
const program = new commander.Command();
|
|
182
|
+
program.name("jsonstat-io").description(
|
|
183
|
+
"Bidirectional bridge between JSON-stat 2.0 and the columnar stack (Arrow, Parquet, DuckDB, Polars, CSVW, CSV)."
|
|
184
|
+
).version(VERSION).argument(
|
|
185
|
+
"[input]",
|
|
186
|
+
'Input file path, URL, or "-" for stdin (default). Supports .parquet, .arrow/.ipc, .csv, .csvw, .json/.jsonstat.',
|
|
187
|
+
"-"
|
|
188
|
+
).option(
|
|
189
|
+
"-f, --from <format>",
|
|
190
|
+
"Source format: auto (default), parquet, arrow, csv, csvw, jsonstat, json"
|
|
191
|
+
).option(
|
|
192
|
+
"-t, --to <format>",
|
|
193
|
+
"Output format: jsonstat (default) = import; arrow, parquet, csv, csvw = export.",
|
|
194
|
+
"jsonstat"
|
|
195
|
+
).option("--measure <column>", "Name of the measure column (overrides detection)").option("--dimensions <a,b,c>", "Comma-separated dimension column names, in order").option(
|
|
196
|
+
"--role <assigns>",
|
|
197
|
+
"Role assignments: time=<col>,geo=<col>,metric=<col> (comma-separated)"
|
|
198
|
+
).option("--status <column>", "Name of the status column").option("--sparse", "Force sparse (object) value form").option("--dense", "Force dense (array) value form").option("--auto", "Auto-detect value form (default)").option("--threshold <n>", "Sparse threshold: null ratio 0\u20131 (default 0.5)").option(
|
|
199
|
+
"--status-form <form>",
|
|
200
|
+
"Status emission: auto (default), array, string, object, none"
|
|
201
|
+
).option("--label <text>", "Dataset label").option("--source <text>", "Dataset source").option("--updated <date>", "Dataset last-updated date (ISO 8601)").option("--validate", "Validate output with jsonstat-validator (if installed)").option("-o, --output <file>", "Output file path (default: stdout)").option("--pretty", "Pretty-print JSON (default: true)").option("--no-pretty", "Compact JSON output").option("--canonical-keys", "Reorder top-level keys canonically (default: true)").option("--no-canonical-keys", "Preserve source key order").option("--csvw-metadata <json>", "Inline CSVW metadata as a JSON string").option("--delimiter <char>", 'CSV delimiter (default: ",")').action(async (input, opts) => {
|
|
202
|
+
await run(input, opts);
|
|
203
|
+
});
|
|
204
|
+
return program;
|
|
205
|
+
}
|
|
206
|
+
async function run(input, rawOpts) {
|
|
207
|
+
let parsed;
|
|
208
|
+
try {
|
|
209
|
+
parsed = parseCliOptions(rawOpts);
|
|
210
|
+
} catch (e) {
|
|
211
|
+
console.error(`Error: ${e.message}`);
|
|
212
|
+
process.exitCode = 2;
|
|
213
|
+
throw e;
|
|
214
|
+
}
|
|
215
|
+
const source = input && input !== "-" ? input : "-";
|
|
216
|
+
if (parsed.to !== "jsonstat") {
|
|
217
|
+
return runExport(source, parsed);
|
|
218
|
+
}
|
|
219
|
+
let dataset;
|
|
220
|
+
try {
|
|
221
|
+
dataset = await chunkAXUZF6O5_cjs.importToDataset(source, parsed.importOptions);
|
|
222
|
+
} catch (e) {
|
|
223
|
+
if (e instanceof chunkAXUZF6O5_cjs.ImporterError) {
|
|
224
|
+
console.error(`Error: ${e.message}`);
|
|
225
|
+
} else {
|
|
226
|
+
console.error(`Import failed: ${e.message}`);
|
|
227
|
+
}
|
|
228
|
+
process.exitCode = 1;
|
|
229
|
+
throw e;
|
|
230
|
+
}
|
|
231
|
+
let validationErrors = [];
|
|
232
|
+
if (parsed.validate) {
|
|
233
|
+
validationErrors = await validateDataset(dataset);
|
|
234
|
+
if (validationErrors.length > 0) {
|
|
235
|
+
console.error("Validation failed:");
|
|
236
|
+
for (const err of validationErrors) {
|
|
237
|
+
console.error(` - ${err}`);
|
|
238
|
+
}
|
|
239
|
+
process.exitCode = 1;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
const json = chunkAXUZF6O5_cjs.serialize(dataset, {
|
|
243
|
+
pretty: parsed.pretty,
|
|
244
|
+
canonicalKeys: parsed.canonicalKeys
|
|
245
|
+
});
|
|
246
|
+
try {
|
|
247
|
+
await writeOutput(json, parsed.output);
|
|
248
|
+
} catch (e) {
|
|
249
|
+
console.error(`Error writing output: ${e.message}`);
|
|
250
|
+
process.exitCode = 1;
|
|
251
|
+
throw e;
|
|
252
|
+
}
|
|
253
|
+
return { direction: "import", dataset, json, validationErrors };
|
|
254
|
+
}
|
|
255
|
+
async function runExport(source, parsed) {
|
|
256
|
+
let dataset;
|
|
257
|
+
try {
|
|
258
|
+
dataset = await chunkAXUZF6O5_cjs.importToDataset(source, {
|
|
259
|
+
...parsed.importOptions,
|
|
260
|
+
from: parsed.importOptions.from ?? "jsonstat"
|
|
261
|
+
});
|
|
262
|
+
} catch (e) {
|
|
263
|
+
if (e instanceof chunkAXUZF6O5_cjs.ImporterError) {
|
|
264
|
+
console.error(`Error: ${e.message}`);
|
|
265
|
+
} else {
|
|
266
|
+
console.error(`Import failed: ${e.message}`);
|
|
267
|
+
}
|
|
268
|
+
process.exitCode = 1;
|
|
269
|
+
throw e;
|
|
270
|
+
}
|
|
271
|
+
const to = parsed.to;
|
|
272
|
+
try {
|
|
273
|
+
const result = await chunkAXUZF6O5_cjs.exportDataset(dataset, { to });
|
|
274
|
+
if (to === "csv") {
|
|
275
|
+
const text = result;
|
|
276
|
+
await writeOutput(text, parsed.output);
|
|
277
|
+
return { direction: "export", dataset, to, text, validationErrors: [] };
|
|
278
|
+
}
|
|
279
|
+
if (to === "csvw") {
|
|
280
|
+
const { csv, metadata } = result;
|
|
281
|
+
await writeOutput(csv, parsed.output);
|
|
282
|
+
if (parsed.output && parsed.output !== "-") {
|
|
283
|
+
const metaPath = csvwMetadataSibling(parsed.output);
|
|
284
|
+
await writeOutput(
|
|
285
|
+
JSON.stringify(metadata, null, 2),
|
|
286
|
+
metaPath
|
|
287
|
+
);
|
|
288
|
+
} else {
|
|
289
|
+
const { stdout } = await import('process');
|
|
290
|
+
stdout.write("\n--- metadata.json ---\n");
|
|
291
|
+
stdout.write(JSON.stringify(metadata, null, 2));
|
|
292
|
+
stdout.write("\n");
|
|
293
|
+
}
|
|
294
|
+
return { direction: "export", dataset, to, text: csv, validationErrors: [] };
|
|
295
|
+
}
|
|
296
|
+
if (to === "parquet") {
|
|
297
|
+
const bytes2 = result;
|
|
298
|
+
await writeBinaryOutput(bytes2, parsed.output);
|
|
299
|
+
return { direction: "export", dataset, to, bytes: bytes2, validationErrors: [] };
|
|
300
|
+
}
|
|
301
|
+
const table = result;
|
|
302
|
+
const bytes = apacheArrow.tableToIPC(table, "stream");
|
|
303
|
+
await writeBinaryOutput(new Uint8Array(bytes), parsed.output);
|
|
304
|
+
return { direction: "export", dataset, to, bytes: new Uint8Array(bytes), validationErrors: [] };
|
|
305
|
+
} catch (e) {
|
|
306
|
+
if (e instanceof chunkAXUZF6O5_cjs.ImporterError) {
|
|
307
|
+
console.error(`Error: ${e.message}`);
|
|
308
|
+
} else {
|
|
309
|
+
console.error(`Export failed: ${e.message}`);
|
|
310
|
+
}
|
|
311
|
+
process.exitCode = 1;
|
|
312
|
+
throw e;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function csvwMetadataSibling(csvPath) {
|
|
316
|
+
const dot = csvPath.lastIndexOf(".");
|
|
317
|
+
const base = dot > 0 ? csvPath.slice(0, dot) : csvPath;
|
|
318
|
+
return `${base}-metadata.json`;
|
|
319
|
+
}
|
|
320
|
+
var isMain = (() => {
|
|
321
|
+
try {
|
|
322
|
+
return process.argv[1] === url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
|
|
323
|
+
} catch {
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
})();
|
|
327
|
+
if (isMain) {
|
|
328
|
+
createProgram().parseAsync(process.argv).catch((e) => {
|
|
329
|
+
console.error(e);
|
|
330
|
+
process.exitCode = 1;
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
exports.createProgram = createProgram;
|
|
335
|
+
exports.run = run;
|
|
336
|
+
//# sourceMappingURL=index.cjs.map
|
|
337
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/args.ts","../../src/cli/index.ts"],"names":["Command","importToDataset","ImporterError","serialize","exportDataset","bytes","tableToIPC","fileURLToPath"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * CLI argument parsing helpers — translates the string flags captured by\n * commander into the typed [`ImportOptions`](../index.ts) +\n * [`BuildOptions`](../core/cubeBuilder.ts) the library expects.\n *\n * Kept separate from [`index.ts`](./index.ts) so the parsing logic is unit-\n * testable without spinning up a commander Program.\n */\n\nimport type { BuildOptions } from \"../core/cubeBuilder\";\nimport type { DatasetMeta } from \"../model/ir\";\nimport type { ImportOptions } from \"../index\";\nimport type { SourceFormat } from \"../util/detect\";\n\n/** The raw option bag that commander collects from argv. */\nexport interface RawCliOptions {\n from?: string;\n to?: string;\n measure?: string;\n dimensions?: string;\n role?: string;\n status?: string;\n sparse?: boolean;\n dense?: boolean;\n auto?: boolean;\n threshold?: string;\n statusForm?: string;\n label?: string;\n source?: string;\n updated?: string;\n validate?: boolean;\n output?: string;\n pretty?: boolean;\n noPretty?: boolean;\n canonicalKeys?: boolean;\n noCanonicalKeys?: boolean;\n csvwMetadata?: string;\n delimiter?: string;\n}\n\n/** Parsed CLI options, ready to feed into `importToDataset` + `serialize`. */\nexport interface ParsedCliOptions {\n /** Output target: `jsonstat` = import (default); `arrow|parquet|csv|csvw` = export. */\n to: string;\n importOptions: ImportOptions;\n buildOptions: BuildOptions;\n /** `--validate` flag. */\n validate: boolean;\n /** Output file path (`-o` / `--output`), or undefined for stdout. */\n output?: string;\n /** Pretty-print the JSON output (default true). */\n pretty: boolean;\n /** Reorder top-level keys canonically (default true). */\n canonicalKeys: boolean;\n}\n\nconst ALLOWED_FROM: ReadonlySet<string> = new Set([\n \"auto\",\n \"parquet\",\n \"arrow\",\n \"csv\",\n \"csvw\",\n \"jsonstat\",\n \"json\",\n]);\n\nconst ALLOWED_TO: ReadonlySet<string> = new Set([\n \"jsonstat\",\n \"arrow\",\n \"parquet\",\n \"csv\",\n \"csvw\",\n]);\n\nconst ALLOWED_STATUS_FORM: ReadonlySet<string> = new Set([\n \"auto\",\n \"array\",\n \"string\",\n \"object\",\n \"none\",\n]);\n\n/**\n * Parse the `--role` flag: `time=year,geo=country,metric=value` → a\n * [`RoleMap`](../model/ir.ts).\n */\nexport function parseRoleFlag(raw: string | undefined): {\n time?: string[];\n geo?: string[];\n metric?: string[];\n} | undefined {\n if (!raw) return undefined;\n const roles: { time?: string[]; geo?: string[]; metric?: string[] } = {};\n for (const pair of raw.split(\",\")) {\n const eq = pair.indexOf(\"=\");\n if (eq < 0) {\n throw new Error(\n `Invalid --role entry \"${pair}\". Expected \"<role>=<column>\" (e.g. time=year).`,\n );\n }\n const role = pair.slice(0, eq).trim();\n const col = pair.slice(eq + 1).trim();\n if (role !== \"time\" && role !== \"geo\" && role !== \"metric\") {\n throw new Error(\n `Invalid --role \"${role}\". Must be one of: time, geo, metric.`,\n );\n }\n if (!col) {\n throw new Error(`--role \"${role}=\" is missing a column name.`);\n }\n // A role can map to multiple columns (comma-separated within the value\n // is already split above, so each pair is a single column). Accumulate.\n (roles[role] ??= []).push(col);\n }\n return roles;\n}\n\n/**\n * Parse the `--dimensions` flag: `a,b,c` → `[\"a\",\"b\",\"c\"]`.\n */\nexport function parseDimensionsFlag(\n raw: string | undefined,\n): string[] | undefined {\n if (!raw) return undefined;\n const dims = raw\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n if (dims.length === 0) {\n throw new Error(\"--dimensions requires at least one column name.\");\n }\n return dims;\n}\n\n/**\n * Parse a `--threshold` value (0–1) with a friendly error.\n */\nexport function parseThreshold(raw: string | undefined): number | undefined {\n if (raw === undefined) return undefined;\n const n = Number.parseFloat(raw);\n if (Number.isNaN(n) || n < 0 || n > 1) {\n throw new Error(`--threshold must be a number between 0 and 1, got \"${raw}\".`);\n }\n return n;\n}\n\n/**\n * Resolve the `--sparse` / `--dense` / `--auto` trio into a `valueForm`.\n * `--sparse` wins over `--dense` if both are set (defensive).\n */\nexport function resolveValueForm(raw: RawCliOptions): \"auto\" | \"dense\" | \"sparse\" {\n if (raw.sparse) return \"sparse\";\n if (raw.dense) return \"dense\";\n return \"auto\";\n}\n\n/**\n * Convert the raw commander option bag into typed library options.\n *\n * @throws Error with a user-friendly message if any flag is invalid.\n */\nexport function parseCliOptions(raw: RawCliOptions): ParsedCliOptions {\n // --- --from -----------------------------------------------------------\n if (raw.from !== undefined && !ALLOWED_FROM.has(raw.from)) {\n throw new Error(\n `--from \"${raw.from}\" is not supported. Use one of: ${[...ALLOWED_FROM].join(\", \")}.`,\n );\n }\n\n // --- --to (drives direction: jsonstat = import, else export) ----------\n const to = raw.to ?? \"jsonstat\";\n if (!ALLOWED_TO.has(to)) {\n throw new Error(\n `--to \"${to}\" is not supported. Use one of: ${[...ALLOWED_TO].join(\", \")}.`,\n );\n }\n\n // --- --status-form ----------------------------------------------------\n if (raw.statusForm !== undefined && !ALLOWED_STATUS_FORM.has(raw.statusForm)) {\n throw new Error(\n `--status-form \"${raw.statusForm}\" is invalid. Use one of: ${[...ALLOWED_STATUS_FORM].join(\", \")}.`,\n );\n }\n\n // --- Dataset metadata -------------------------------------------------\n const meta: DatasetMeta = {};\n if (raw.label) meta.label = raw.label;\n if (raw.source) meta.source = raw.source;\n if (raw.updated) meta.updated = raw.updated;\n\n // --- Build options ----------------------------------------------------\n const buildOptions: BuildOptions = {\n valueForm: resolveValueForm(raw),\n sparseThreshold: parseThreshold(raw.threshold),\n statusForm: raw.statusForm as BuildOptions[\"statusForm\"],\n meta: Object.keys(meta).length > 0 ? meta : undefined,\n };\n\n // --- Import options ---------------------------------------------------\n const importOptions: ImportOptions = {\n from: (raw.from ?? \"auto\") as SourceFormat | \"auto\",\n measure: raw.measure,\n dimensions: parseDimensionsFlag(raw.dimensions),\n status: raw.status,\n roles: parseRoleFlag(raw.role),\n build: buildOptions,\n delimiter: raw.delimiter,\n csvwMetadata: raw.csvwMetadata\n ? safeJsonParse(raw.csvwMetadata, \"--csvw-metadata\")\n : undefined,\n };\n\n return {\n to,\n importOptions,\n buildOptions,\n validate: raw.validate === true,\n output: raw.output,\n pretty: raw.noPretty ? false : (raw.pretty ?? true),\n canonicalKeys: raw.noCanonicalKeys ? false : (raw.canonicalKeys ?? true),\n };\n}\n\nfunction safeJsonParse(text: string, flagName: string): unknown {\n try {\n return JSON.parse(text);\n } catch (e) {\n throw new Error(\n `${flagName} must be valid JSON: ${(e as Error).message}`,\n );\n }\n}\n","#!/usr/bin/env node\n/**\n * jsonstat-io CLI entry point.\n *\n * `--to` drives direction:\n * - `--to jsonstat` (default): import a columnar source → JSON-stat (Phase 1).\n * - `--to arrow|parquet|csv|csvw`: export a JSON-stat dataset → columnar (Phase 2).\n *\n * Usage:\n *\n * ```sh\n * npx jsonstat-io <input> [options]\n * npx jsonstat-io ./sales.parquet -o sales.jsonstat.json\n * cat data.csv | npx jsonstat-io - --measure amount --role time=year\n * npx jsonstat-io https://example.com/data.arrow --sparse --label \"Sales 2024\"\n * npx jsonstat-io ./census.jsonstat.json --to parquet -o census.parquet\n * ```\n *\n * See [docs/cli.md](../../docs/cli.md) for the full reference.\n *\n * @module\n */\n\nimport { Command } from \"commander\";\nimport { tableToIPC } from \"apache-arrow\";\nimport type { Table } from \"apache-arrow\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n importToDataset,\n exportDataset,\n serialize,\n ImporterError,\n} from \"../index\";\nimport type { ExportTarget } from \"../index\";\nimport type { JsonStatDataset } from \"../model/jsonstat\";\nimport { parseCliOptions } from \"./args\";\nimport type { RawCliOptions } from \"./args\";\n\n// ---------------------------------------------------------------------------\n// File writing (Node only) — kept inline to avoid pulling node:fs in browser\n// builds of the library proper.\n// ---------------------------------------------------------------------------\nasync function writeOutput(\n text: string,\n output: string | undefined,\n): Promise<void> {\n if (!output || output === \"-\") {\n // stdout\n const { stdout } = await import(\"node:process\");\n stdout.write(text);\n if (!text.endsWith(\"\\n\")) stdout.write(\"\\n\");\n return;\n }\n const { writeFile } = await import(\"node:fs/promises\");\n await writeFile(output, text, \"utf8\");\n}\n\n/**\n * Write binary output (Parquet / Arrow IPC bytes) to stdout or a file. For\n * stdout we write the raw bytes (no trailing newline), since the content is\n * not text.\n */\nasync function writeBinaryOutput(\n bytes: Uint8Array,\n output: string | undefined,\n): Promise<void> {\n if (!output || output === \"-\") {\n const { stdout } = await import(\"node:process\");\n // process.stdout.write accepts a Buffer (raw bytes, no text encoding).\n stdout.write(Buffer.from(bytes));\n return;\n }\n const { writeFile } = await import(\"node:fs/promises\");\n await writeFile(output, bytes);\n}\n\n// ---------------------------------------------------------------------------\n// Optional validation via jsonstat-validator (lazy, peer).\n// ---------------------------------------------------------------------------\nasync function validateDataset(dataset: JsonStatDataset): Promise<string[]> {\n try {\n // jsonstat-validator is an optional peer dependency that may not be\n // installed. Using a non-literal specifier so TypeScript skips static\n // module resolution; the try/catch handles runtime absence.\n const spec = \"jsonstat-validator\";\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod: any = await import(/* @vite-ignore */ spec);\n const validator =\n mod?.validate ??\n mod?.default?.validate ??\n mod?.default?.default?.validate;\n if (typeof validator !== \"function\") {\n return [\"jsonstat-validator is installed but has no validate() export.\"];\n }\n const result = validator(dataset);\n return result.valid ? [] : result.errors;\n } catch {\n return [\n \"jsonstat-validator is not installed. Install it with: npm i -D jsonstat-validator\",\n ];\n }\n}\n\n// ---------------------------------------------------------------------------\n// Program definition\n// ---------------------------------------------------------------------------\nconst VERSION = \"0.1.0\";\n\nfunction createProgram(): Command {\n const program = new Command();\n\n program\n .name(\"jsonstat-io\")\n .description(\n \"Bidirectional bridge between JSON-stat 2.0 and the columnar stack (Arrow, Parquet, DuckDB, Polars, CSVW, CSV).\",\n )\n .version(VERSION)\n .argument(\n \"[input]\",\n 'Input file path, URL, or \"-\" for stdin (default). Supports .parquet, .arrow/.ipc, .csv, .csvw, .json/.jsonstat.',\n \"-\",\n )\n .option(\n \"-f, --from <format>\",\n \"Source format: auto (default), parquet, arrow, csv, csvw, jsonstat, json\",\n )\n .option(\n \"-t, --to <format>\",\n \"Output format: jsonstat (default) = import; arrow, parquet, csv, csvw = export.\",\n \"jsonstat\",\n )\n .option(\"--measure <column>\", \"Name of the measure column (overrides detection)\")\n .option(\"--dimensions <a,b,c>\", \"Comma-separated dimension column names, in order\")\n .option(\n \"--role <assigns>\",\n 'Role assignments: time=<col>,geo=<col>,metric=<col> (comma-separated)',\n )\n .option(\"--status <column>\", \"Name of the status column\")\n .option(\"--sparse\", \"Force sparse (object) value form\")\n .option(\"--dense\", \"Force dense (array) value form\")\n .option(\"--auto\", \"Auto-detect value form (default)\")\n .option(\"--threshold <n>\", \"Sparse threshold: null ratio 0–1 (default 0.5)\")\n .option(\n \"--status-form <form>\",\n \"Status emission: auto (default), array, string, object, none\",\n )\n .option(\"--label <text>\", \"Dataset label\")\n .option(\"--source <text>\", \"Dataset source\")\n .option(\"--updated <date>\", \"Dataset last-updated date (ISO 8601)\")\n .option(\"--validate\", \"Validate output with jsonstat-validator (if installed)\")\n .option(\"-o, --output <file>\", \"Output file path (default: stdout)\")\n .option(\"--pretty\", \"Pretty-print JSON (default: true)\")\n .option(\"--no-pretty\", \"Compact JSON output\")\n .option(\"--canonical-keys\", \"Reorder top-level keys canonically (default: true)\")\n .option(\"--no-canonical-keys\", \"Preserve source key order\")\n .option(\"--csvw-metadata <json>\", \"Inline CSVW metadata as a JSON string\")\n .option(\"--delimiter <char>\", 'CSV delimiter (default: \",\")')\n .action(async (input: string, opts: RawCliOptions) => {\n await run(input, opts);\n });\n\n return program;\n}\n\n// ---------------------------------------------------------------------------\n// Core run logic (separated for testability)\n// ---------------------------------------------------------------------------\n\n/** Result of a CLI run — exposed for unit tests. */\nexport interface CliRunResult {\n /** Direction taken: \"import\" (→ jsonstat) or \"export\" (→ columnar). */\n direction: \"import\" | \"export\";\n /** The input dataset (always JSON-stat). Present for import runs. */\n dataset: JsonStatDataset;\n /** Serialized JSON-stat text (import path only). */\n json?: string;\n /** The export target, when `direction === \"export\"`. */\n to?: string;\n /** Exported text (csv) or metadata (csvw), when applicable. */\n text?: string;\n /** Exported bytes (parquet / arrow), when applicable. */\n bytes?: Uint8Array;\n /** Validation errors, import path only. */\n validationErrors: string[];\n}\n\n/**\n * Run the CLI programmatically. Exposed so tests can invoke the full pipeline\n * without spawning a child process.\n *\n * `--to` drives direction: `jsonstat` (default) = import a columnar source and\n * serialize JSON-stat; `arrow|parquet|csv|csvw` = import a JSON-stat source\n * and export it to the requested columnar format.\n */\nexport async function run(\n input: string,\n rawOpts: RawCliOptions,\n): Promise<CliRunResult> {\n let parsed;\n try {\n parsed = parseCliOptions(rawOpts);\n } catch (e) {\n console.error(`Error: ${(e as Error).message}`);\n process.exitCode = 2;\n throw e;\n }\n\n const source = input && input !== \"-\" ? input : \"-\";\n\n // --- Export path (--to arrow|parquet|csv|csvw) --------------------------\n // The source must be JSON-stat; we import it as a dataset, then export.\n if (parsed.to !== \"jsonstat\") {\n return runExport(source, parsed);\n }\n\n // --- Import path (--to jsonstat) ----------------------------------------\n let dataset: JsonStatDataset;\n try {\n dataset = await importToDataset(source, parsed.importOptions);\n } catch (e) {\n if (e instanceof ImporterError) {\n console.error(`Error: ${e.message}`);\n } else {\n console.error(`Import failed: ${(e as Error).message}`);\n }\n process.exitCode = 1;\n throw e;\n }\n\n // Optional validation\n let validationErrors: string[] = [];\n if (parsed.validate) {\n validationErrors = await validateDataset(dataset);\n if (validationErrors.length > 0) {\n console.error(\"Validation failed:\");\n for (const err of validationErrors) {\n console.error(` - ${err}`);\n }\n process.exitCode = 1;\n }\n }\n\n const json = serialize(dataset, {\n pretty: parsed.pretty,\n canonicalKeys: parsed.canonicalKeys,\n });\n\n try {\n await writeOutput(json, parsed.output);\n } catch (e) {\n console.error(`Error writing output: ${(e as Error).message}`);\n process.exitCode = 1;\n throw e;\n }\n\n return { direction: \"import\", dataset, json, validationErrors };\n}\n\n/**\n * Import a JSON-stat source as a dataset, then export it via\n * [`exportDataset`](../index.ts) and write the result. Handles the four\n * `--to` targets: `arrow`, `parquet`, `csv`, `csvw`.\n */\nasync function runExport(\n source: string,\n parsed: ReturnType<typeof parseCliOptions>,\n): Promise<CliRunResult> {\n // Import the JSON-stat source into a dataset first.\n let dataset: JsonStatDataset;\n try {\n // Force the import path to treat the input as JSON-stat.\n dataset = await importToDataset(source, {\n ...parsed.importOptions,\n from: parsed.importOptions.from ?? \"jsonstat\",\n });\n } catch (e) {\n if (e instanceof ImporterError) {\n console.error(`Error: ${e.message}`);\n } else {\n console.error(`Import failed: ${(e as Error).message}`);\n }\n process.exitCode = 1;\n throw e;\n }\n\n const to = parsed.to as ExportTarget;\n try {\n const result = await exportDataset(dataset, { to });\n\n if (to === \"csv\") {\n const text = result as string;\n await writeOutput(text, parsed.output);\n return { direction: \"export\", dataset, to, text, validationErrors: [] };\n }\n if (to === \"csvw\") {\n const { csv, metadata } = result as {\n csv: string;\n metadata: unknown;\n };\n // Write the CSV to -o (or stdout); write the metadata next to it.\n await writeOutput(csv, parsed.output);\n if (parsed.output && parsed.output !== \"-\") {\n const metaPath = csvwMetadataSibling(parsed.output);\n await writeOutput(\n JSON.stringify(metadata, null, 2),\n metaPath,\n );\n } else {\n // stdout: emit a separator and the metadata for visibility.\n const { stdout } = await import(\"node:process\");\n stdout.write(\"\\n--- metadata.json ---\\n\");\n stdout.write(JSON.stringify(metadata, null, 2));\n stdout.write(\"\\n\");\n }\n return { direction: \"export\", dataset, to, text: csv, validationErrors: [] };\n }\n if (to === \"parquet\") {\n const bytes = result as Uint8Array;\n await writeBinaryOutput(bytes, parsed.output);\n return { direction: \"export\", dataset, to, bytes, validationErrors: [] };\n }\n // arrow → serialize the Table to IPC stream bytes.\n const table = result as Table;\n const bytes = tableToIPC(table, \"stream\");\n await writeBinaryOutput(new Uint8Array(bytes), parsed.output);\n return { direction: \"export\", dataset, to, bytes: new Uint8Array(bytes), validationErrors: [] };\n } catch (e) {\n if (e instanceof ImporterError) {\n console.error(`Error: ${e.message}`);\n } else {\n console.error(`Export failed: ${(e as Error).message}`);\n }\n process.exitCode = 1;\n throw e;\n }\n}\n\n/** Derive the CSVW metadata sibling path from a CSV output path. */\nfunction csvwMetadataSibling(csvPath: string): string {\n const dot = csvPath.lastIndexOf(\".\");\n const base = dot > 0 ? csvPath.slice(0, dot) : csvPath;\n return `${base}-metadata.json`;\n}\n\n// ---------------------------------------------------------------------------\n// Entrypoint\n// ---------------------------------------------------------------------------\n\n// Only run when invoked directly (not when imported by tests).\n// ESM-safe: compare the resolved entry path against this module's URL.\nconst isMain = (() => {\n try {\n return process.argv[1] === fileURLToPath(import.meta.url);\n } catch {\n return false;\n }\n})();\n\nif (isMain) {\n createProgram().parseAsync(process.argv).catch((e: unknown) => {\n console.error(e);\n process.exitCode = 1;\n });\n}\n\nexport { createProgram };\n"]}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { J as JsonStatDataset } from '../jsonstat-BX4mBLci.cjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* CLI argument parsing helpers — translates the string flags captured by
|
|
7
|
+
* commander into the typed [`ImportOptions`](../index.ts) +
|
|
8
|
+
* [`BuildOptions`](../core/cubeBuilder.ts) the library expects.
|
|
9
|
+
*
|
|
10
|
+
* Kept separate from [`index.ts`](./index.ts) so the parsing logic is unit-
|
|
11
|
+
* testable without spinning up a commander Program.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** The raw option bag that commander collects from argv. */
|
|
15
|
+
interface RawCliOptions {
|
|
16
|
+
from?: string;
|
|
17
|
+
to?: string;
|
|
18
|
+
measure?: string;
|
|
19
|
+
dimensions?: string;
|
|
20
|
+
role?: string;
|
|
21
|
+
status?: string;
|
|
22
|
+
sparse?: boolean;
|
|
23
|
+
dense?: boolean;
|
|
24
|
+
auto?: boolean;
|
|
25
|
+
threshold?: string;
|
|
26
|
+
statusForm?: string;
|
|
27
|
+
label?: string;
|
|
28
|
+
source?: string;
|
|
29
|
+
updated?: string;
|
|
30
|
+
validate?: boolean;
|
|
31
|
+
output?: string;
|
|
32
|
+
pretty?: boolean;
|
|
33
|
+
noPretty?: boolean;
|
|
34
|
+
canonicalKeys?: boolean;
|
|
35
|
+
noCanonicalKeys?: boolean;
|
|
36
|
+
csvwMetadata?: string;
|
|
37
|
+
delimiter?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* jsonstat-io CLI entry point.
|
|
42
|
+
*
|
|
43
|
+
* `--to` drives direction:
|
|
44
|
+
* - `--to jsonstat` (default): import a columnar source → JSON-stat (Phase 1).
|
|
45
|
+
* - `--to arrow|parquet|csv|csvw`: export a JSON-stat dataset → columnar (Phase 2).
|
|
46
|
+
*
|
|
47
|
+
* Usage:
|
|
48
|
+
*
|
|
49
|
+
* ```sh
|
|
50
|
+
* npx jsonstat-io <input> [options]
|
|
51
|
+
* npx jsonstat-io ./sales.parquet -o sales.jsonstat.json
|
|
52
|
+
* cat data.csv | npx jsonstat-io - --measure amount --role time=year
|
|
53
|
+
* npx jsonstat-io https://example.com/data.arrow --sparse --label "Sales 2024"
|
|
54
|
+
* npx jsonstat-io ./census.jsonstat.json --to parquet -o census.parquet
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* See [docs/cli.md](../../docs/cli.md) for the full reference.
|
|
58
|
+
*
|
|
59
|
+
* @module
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
declare function createProgram(): Command;
|
|
63
|
+
/** Result of a CLI run — exposed for unit tests. */
|
|
64
|
+
interface CliRunResult {
|
|
65
|
+
/** Direction taken: "import" (→ jsonstat) or "export" (→ columnar). */
|
|
66
|
+
direction: "import" | "export";
|
|
67
|
+
/** The input dataset (always JSON-stat). Present for import runs. */
|
|
68
|
+
dataset: JsonStatDataset;
|
|
69
|
+
/** Serialized JSON-stat text (import path only). */
|
|
70
|
+
json?: string;
|
|
71
|
+
/** The export target, when `direction === "export"`. */
|
|
72
|
+
to?: string;
|
|
73
|
+
/** Exported text (csv) or metadata (csvw), when applicable. */
|
|
74
|
+
text?: string;
|
|
75
|
+
/** Exported bytes (parquet / arrow), when applicable. */
|
|
76
|
+
bytes?: Uint8Array;
|
|
77
|
+
/** Validation errors, import path only. */
|
|
78
|
+
validationErrors: string[];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Run the CLI programmatically. Exposed so tests can invoke the full pipeline
|
|
82
|
+
* without spawning a child process.
|
|
83
|
+
*
|
|
84
|
+
* `--to` drives direction: `jsonstat` (default) = import a columnar source and
|
|
85
|
+
* serialize JSON-stat; `arrow|parquet|csv|csvw` = import a JSON-stat source
|
|
86
|
+
* and export it to the requested columnar format.
|
|
87
|
+
*/
|
|
88
|
+
declare function run(input: string, rawOpts: RawCliOptions): Promise<CliRunResult>;
|
|
89
|
+
|
|
90
|
+
export { type CliRunResult, createProgram, run };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { J as JsonStatDataset } from '../jsonstat-BX4mBLci.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* CLI argument parsing helpers — translates the string flags captured by
|
|
7
|
+
* commander into the typed [`ImportOptions`](../index.ts) +
|
|
8
|
+
* [`BuildOptions`](../core/cubeBuilder.ts) the library expects.
|
|
9
|
+
*
|
|
10
|
+
* Kept separate from [`index.ts`](./index.ts) so the parsing logic is unit-
|
|
11
|
+
* testable without spinning up a commander Program.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** The raw option bag that commander collects from argv. */
|
|
15
|
+
interface RawCliOptions {
|
|
16
|
+
from?: string;
|
|
17
|
+
to?: string;
|
|
18
|
+
measure?: string;
|
|
19
|
+
dimensions?: string;
|
|
20
|
+
role?: string;
|
|
21
|
+
status?: string;
|
|
22
|
+
sparse?: boolean;
|
|
23
|
+
dense?: boolean;
|
|
24
|
+
auto?: boolean;
|
|
25
|
+
threshold?: string;
|
|
26
|
+
statusForm?: string;
|
|
27
|
+
label?: string;
|
|
28
|
+
source?: string;
|
|
29
|
+
updated?: string;
|
|
30
|
+
validate?: boolean;
|
|
31
|
+
output?: string;
|
|
32
|
+
pretty?: boolean;
|
|
33
|
+
noPretty?: boolean;
|
|
34
|
+
canonicalKeys?: boolean;
|
|
35
|
+
noCanonicalKeys?: boolean;
|
|
36
|
+
csvwMetadata?: string;
|
|
37
|
+
delimiter?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* jsonstat-io CLI entry point.
|
|
42
|
+
*
|
|
43
|
+
* `--to` drives direction:
|
|
44
|
+
* - `--to jsonstat` (default): import a columnar source → JSON-stat (Phase 1).
|
|
45
|
+
* - `--to arrow|parquet|csv|csvw`: export a JSON-stat dataset → columnar (Phase 2).
|
|
46
|
+
*
|
|
47
|
+
* Usage:
|
|
48
|
+
*
|
|
49
|
+
* ```sh
|
|
50
|
+
* npx jsonstat-io <input> [options]
|
|
51
|
+
* npx jsonstat-io ./sales.parquet -o sales.jsonstat.json
|
|
52
|
+
* cat data.csv | npx jsonstat-io - --measure amount --role time=year
|
|
53
|
+
* npx jsonstat-io https://example.com/data.arrow --sparse --label "Sales 2024"
|
|
54
|
+
* npx jsonstat-io ./census.jsonstat.json --to parquet -o census.parquet
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* See [docs/cli.md](../../docs/cli.md) for the full reference.
|
|
58
|
+
*
|
|
59
|
+
* @module
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
declare function createProgram(): Command;
|
|
63
|
+
/** Result of a CLI run — exposed for unit tests. */
|
|
64
|
+
interface CliRunResult {
|
|
65
|
+
/** Direction taken: "import" (→ jsonstat) or "export" (→ columnar). */
|
|
66
|
+
direction: "import" | "export";
|
|
67
|
+
/** The input dataset (always JSON-stat). Present for import runs. */
|
|
68
|
+
dataset: JsonStatDataset;
|
|
69
|
+
/** Serialized JSON-stat text (import path only). */
|
|
70
|
+
json?: string;
|
|
71
|
+
/** The export target, when `direction === "export"`. */
|
|
72
|
+
to?: string;
|
|
73
|
+
/** Exported text (csv) or metadata (csvw), when applicable. */
|
|
74
|
+
text?: string;
|
|
75
|
+
/** Exported bytes (parquet / arrow), when applicable. */
|
|
76
|
+
bytes?: Uint8Array;
|
|
77
|
+
/** Validation errors, import path only. */
|
|
78
|
+
validationErrors: string[];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Run the CLI programmatically. Exposed so tests can invoke the full pipeline
|
|
82
|
+
* without spawning a child process.
|
|
83
|
+
*
|
|
84
|
+
* `--to` drives direction: `jsonstat` (default) = import a columnar source and
|
|
85
|
+
* serialize JSON-stat; `arrow|parquet|csv|csvw` = import a JSON-stat source
|
|
86
|
+
* and export it to the requested columnar format.
|
|
87
|
+
*/
|
|
88
|
+
declare function run(input: string, rawOpts: RawCliOptions): Promise<CliRunResult>;
|
|
89
|
+
|
|
90
|
+
export { type CliRunResult, createProgram, run };
|