cdx-chores 0.0.8 → 0.0.9-canary.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/dist/cjs/index.cjs +226 -111
- package/dist/esm/bin.mjs +225 -110
- package/dist/esm/bin.mjs.map +1 -1
- package/dist/esm/index.d.mts +1 -1
- package/dist/esm/index.mjs +226 -111
- package/package.json +1 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -974,6 +974,14 @@ function normalizeOptionalPositiveInteger(value, context) {
|
|
|
974
974
|
exitCode: 2
|
|
975
975
|
});
|
|
976
976
|
}
|
|
977
|
+
function normalizeOptionalBoolean(value, context) {
|
|
978
|
+
if (value === void 0 || value === null || value === "") return;
|
|
979
|
+
if (typeof value === "boolean") return value;
|
|
980
|
+
throw new CliError(`Invalid header mapping artifact: ${context} must be a boolean.`, {
|
|
981
|
+
code: "INVALID_INPUT",
|
|
982
|
+
exitCode: 2
|
|
983
|
+
});
|
|
984
|
+
}
|
|
977
985
|
function throwUnsupportedHeaderMappingVersion(version, options = {}) {
|
|
978
986
|
const suffix = options.rewriting ? " Cannot preserve it safely while rewriting." : "";
|
|
979
987
|
throw new CliError(`Unsupported header mapping artifact version: ${String(version)}.${suffix}`, {
|
|
@@ -993,6 +1001,7 @@ function createHeaderMappingInputReference(options) {
|
|
|
993
1001
|
...options.shape?.bodyStartRow !== void 0 ? { bodyStartRow: options.shape.bodyStartRow } : {},
|
|
994
1002
|
format: options.format,
|
|
995
1003
|
...options.shape?.headerRow !== void 0 ? { headerRow: options.shape.headerRow } : {},
|
|
1004
|
+
...options.shape?.noHeader ? { noHeader: true } : {},
|
|
996
1005
|
path: normalizedRelativePath,
|
|
997
1006
|
...options.shape?.range ? { range: options.shape.range } : {},
|
|
998
1007
|
...options.shape?.source ? { source: options.shape.source } : {}
|
|
@@ -1206,10 +1215,12 @@ function parseDataHeaderMappingArtifact(parsed, options = {}) {
|
|
|
1206
1215
|
};
|
|
1207
1216
|
const bodyStartRow = normalizeOptionalPositiveInteger(input.bodyStartRow, "input.bodyStartRow");
|
|
1208
1217
|
const headerRow = normalizeOptionalPositiveInteger(input.headerRow, "input.headerRow");
|
|
1218
|
+
const noHeader = normalizeOptionalBoolean(input.noHeader, "input.noHeader");
|
|
1209
1219
|
const source = normalizeOptionalString(input.source);
|
|
1210
1220
|
const range = normalizeOptionalString(input.range);
|
|
1211
1221
|
if (bodyStartRow !== void 0) normalizedInput.bodyStartRow = bodyStartRow;
|
|
1212
1222
|
if (headerRow !== void 0) normalizedInput.headerRow = headerRow;
|
|
1223
|
+
if (noHeader) normalizedInput.noHeader = true;
|
|
1213
1224
|
if (source) normalizedInput.source = source;
|
|
1214
1225
|
if (range) normalizedInput.range = range;
|
|
1215
1226
|
if (!Array.isArray(parsed.mappings)) throw new CliError("Invalid header mapping artifact: mappings must be an array.", {
|
|
@@ -1317,7 +1328,7 @@ async function writeDataHeaderMappingArtifact(path, artifact, options = {}) {
|
|
|
1317
1328
|
function resolveReusableHeaderMappings(options) {
|
|
1318
1329
|
const expected = options.currentInput;
|
|
1319
1330
|
const actual = options.artifact.input;
|
|
1320
|
-
if (!(actual.bodyStartRow === expected.bodyStartRow && actual.path === expected.path && actual.format === expected.format && actual.headerRow === expected.headerRow && actual.source === expected.source && actual.range === expected.range)) throw new CliError("Header mapping artifact does not match the current input context exactly.", {
|
|
1331
|
+
if (!(actual.bodyStartRow === expected.bodyStartRow && actual.path === expected.path && actual.format === expected.format && actual.headerRow === expected.headerRow && actual.noHeader === expected.noHeader && actual.source === expected.source && actual.range === expected.range)) throw new CliError("Header mapping artifact does not match the current input context exactly.", {
|
|
1321
1332
|
code: "INVALID_INPUT",
|
|
1322
1333
|
exitCode: 2
|
|
1323
1334
|
});
|
|
@@ -1340,8 +1351,9 @@ function isGeneratedQueryPlaceholderSequence(names) {
|
|
|
1340
1351
|
return Number.isInteger(detectedIndex) && detectedIndex === index;
|
|
1341
1352
|
});
|
|
1342
1353
|
}
|
|
1343
|
-
async function shouldNormalizeGeneratedQueryColumnNames(connection, inputPath, format, columnNames) {
|
|
1354
|
+
async function shouldNormalizeGeneratedQueryColumnNames(connection, inputPath, format, columnNames, options = {}) {
|
|
1344
1355
|
if (format !== "csv" && format !== "tsv" || !isGeneratedQueryPlaceholderSequence(columnNames)) return false;
|
|
1356
|
+
if (options.noHeader) return true;
|
|
1345
1357
|
try {
|
|
1346
1358
|
const delimiter = format === "tsv" ? " " : ",";
|
|
1347
1359
|
return (await connection.runAndReadAll(`select HasHeader from sniff_csv(${escapeSqlStringLiteral(inputPath)}, delim = ${escapeSqlStringLiteral(delimiter)})`)).getRowObjectsJson()[0]?.HasHeader === false;
|
|
@@ -1353,7 +1365,7 @@ async function collectQueryRelationColumns(connection, relationName, options) {
|
|
|
1353
1365
|
const reader = await connection.runAndReadAll(`select * from ${quoteSqlIdentifier$1(relationName)} limit 0`);
|
|
1354
1366
|
const columnNames = reader.deduplicatedColumnNames();
|
|
1355
1367
|
const columnTypes = reader.columnTypes();
|
|
1356
|
-
const shouldNormalizeGeneratedColumns = await shouldNormalizeGeneratedQueryColumnNames(connection, options.inputPath, options.format, columnNames);
|
|
1368
|
+
const shouldNormalizeGeneratedColumns = await shouldNormalizeGeneratedQueryColumnNames(connection, options.inputPath, options.format, columnNames, { noHeader: options.noHeader });
|
|
1357
1369
|
return columnNames.map((name, index) => ({
|
|
1358
1370
|
name: shouldNormalizeGeneratedColumns ? normalizeGeneratedQueryColumnName(name) : name,
|
|
1359
1371
|
sourceName: name,
|
|
@@ -1365,8 +1377,16 @@ async function collectQueryRelationColumns(connection, relationName, options) {
|
|
|
1365
1377
|
function buildRelationSql(inputPath, format, shape = {}, options = {}) {
|
|
1366
1378
|
const escapedInput = escapeSqlStringLiteral(inputPath);
|
|
1367
1379
|
switch (format) {
|
|
1368
|
-
case "csv": return `select * from read_csv_auto(${
|
|
1369
|
-
|
|
1380
|
+
case "csv": return `select * from read_csv_auto(${[
|
|
1381
|
+
escapedInput,
|
|
1382
|
+
"delim = ','",
|
|
1383
|
+
...shape.noHeader ? ["header = false"] : []
|
|
1384
|
+
].join(", ")})`;
|
|
1385
|
+
case "tsv": return `select * from read_csv_auto(${[
|
|
1386
|
+
escapedInput,
|
|
1387
|
+
"delim = ' '",
|
|
1388
|
+
...shape.noHeader ? ["header = false"] : []
|
|
1389
|
+
].join(", ")})`;
|
|
1370
1390
|
case "parquet": return `select * from read_parquet(${escapedInput})`;
|
|
1371
1391
|
case "sqlite": return `select * from sqlite_scan(${escapedInput}, ${escapeSqlStringLiteral(shape.source ?? "")})`;
|
|
1372
1392
|
case "excel": return `select * from read_xlsx(${[
|
|
@@ -1525,8 +1545,13 @@ async function prepareDataQuerySource(connection, inputPath, format, shape = {},
|
|
|
1525
1545
|
const selectedBodyStartRow = shape.bodyStartRow !== void 0 ? normalizeExcelBodyStartRow(shape.bodyStartRow) : void 0;
|
|
1526
1546
|
const selectedRange = shape.range?.trim() ? normalizeExcelRange(shape.range) : void 0;
|
|
1527
1547
|
const selectedHeaderRow = shape.headerRow !== void 0 ? normalizeExcelHeaderRow(shape.headerRow) : void 0;
|
|
1548
|
+
const noHeader = shape.noHeader === true;
|
|
1528
1549
|
let effectiveRange = selectedRange;
|
|
1529
1550
|
let boundaryRangeParts;
|
|
1551
|
+
if (noHeader && format !== "csv" && format !== "tsv") throw new CliError("--no-header is only valid for CSV and TSV query inputs.", {
|
|
1552
|
+
code: "INVALID_INPUT",
|
|
1553
|
+
exitCode: 2
|
|
1554
|
+
});
|
|
1530
1555
|
if (format === "sqlite") {
|
|
1531
1556
|
if (selectedRange) throw new CliError("--range is only valid for Excel query inputs.", {
|
|
1532
1557
|
code: "INVALID_INPUT",
|
|
@@ -1594,7 +1619,8 @@ async function prepareDataQuerySource(connection, inputPath, format, shape = {},
|
|
|
1594
1619
|
});
|
|
1595
1620
|
const relationColumns = await collectQueryRelationColumns(connection, "file_source", {
|
|
1596
1621
|
format,
|
|
1597
|
-
inputPath
|
|
1622
|
+
inputPath,
|
|
1623
|
+
noHeader
|
|
1598
1624
|
});
|
|
1599
1625
|
const appliedHeaderMappings = normalizeAndValidateAcceptedHeaderMappings({
|
|
1600
1626
|
availableColumns: relationColumns.map((column) => column.name),
|
|
@@ -1618,6 +1644,7 @@ async function prepareDataQuerySource(connection, inputPath, format, shape = {},
|
|
|
1618
1644
|
const excelImportMode = excelImportModes[index] ?? "default";
|
|
1619
1645
|
try {
|
|
1620
1646
|
await connection.run(`create or replace temp view file_source as ${buildRelationSql(inputPath, format, {
|
|
1647
|
+
noHeader,
|
|
1621
1648
|
range: effectiveRange,
|
|
1622
1649
|
source: selectedSource
|
|
1623
1650
|
}, {
|
|
@@ -1626,7 +1653,8 @@ async function prepareDataQuerySource(connection, inputPath, format, shape = {},
|
|
|
1626
1653
|
})}`);
|
|
1627
1654
|
const relationColumns = await collectQueryRelationColumns(connection, "file_source", {
|
|
1628
1655
|
format,
|
|
1629
|
-
inputPath
|
|
1656
|
+
inputPath,
|
|
1657
|
+
noHeader
|
|
1630
1658
|
});
|
|
1631
1659
|
const appliedHeaderMappings = normalizeAndValidateAcceptedHeaderMappings({
|
|
1632
1660
|
availableColumns: relationColumns.map((column) => column.name),
|
|
@@ -2646,6 +2674,86 @@ async function actionDataDuckDbExtensionInstall(runtime, options) {
|
|
|
2646
2674
|
}
|
|
2647
2675
|
}
|
|
2648
2676
|
//#endregion
|
|
2677
|
+
//#region src/cli/interactive/analyzer-status.ts
|
|
2678
|
+
const ANALYZER_WAITING_FRAMES = [
|
|
2679
|
+
". ",
|
|
2680
|
+
".. ",
|
|
2681
|
+
"...",
|
|
2682
|
+
".. ",
|
|
2683
|
+
". "
|
|
2684
|
+
];
|
|
2685
|
+
const ANALYZER_WAITING_INTERVAL_MS = 360;
|
|
2686
|
+
function clearStatusLine(stream) {
|
|
2687
|
+
stream.write("\r\x1B[2K");
|
|
2688
|
+
}
|
|
2689
|
+
function normalizeAnalyzerStatusMessage(message) {
|
|
2690
|
+
if (message.includes("Sampling filenames")) return "sampling";
|
|
2691
|
+
if (message.includes("Grouping filename patterns")) return "grouping";
|
|
2692
|
+
if (message.includes("Waiting for Codex cleanup suggestions")) return "waiting";
|
|
2693
|
+
return message;
|
|
2694
|
+
}
|
|
2695
|
+
function renderStatusLine(stream, message, colorEnabled) {
|
|
2696
|
+
const pc = (0, import_picocolors.createColors)(colorEnabled);
|
|
2697
|
+
const normalizedMessage = normalizeAnalyzerStatusMessage(message);
|
|
2698
|
+
const content = ` ${pc.dim("Codex")} ${pc.white("Thinking...")} ${pc.dim(normalizedMessage)} `;
|
|
2699
|
+
stream.write(`\r\x1b[2K${pc.bgBlack(content)}`);
|
|
2700
|
+
}
|
|
2701
|
+
function renderWaitingStatusLine(stream, message, tick, colorEnabled) {
|
|
2702
|
+
const pc = (0, import_picocolors.createColors)(colorEnabled);
|
|
2703
|
+
const normalizedMessage = normalizeAnalyzerStatusMessage(message);
|
|
2704
|
+
const dots = ANALYZER_WAITING_FRAMES[tick % ANALYZER_WAITING_FRAMES.length] ?? "...";
|
|
2705
|
+
const content = ` ${pc.dim("Codex")} ${pc.white("Thinking")} ${pc.dim(normalizedMessage)} ${pc.gray(dots)} `;
|
|
2706
|
+
stream.write(`\r\x1b[2K${pc.bgBlack(content)}`);
|
|
2707
|
+
}
|
|
2708
|
+
function createInteractiveAnalyzerStatus(stream, colorEnabled = true) {
|
|
2709
|
+
if (!stream.isTTY) return {
|
|
2710
|
+
start(message) {
|
|
2711
|
+
printLine(stream, message);
|
|
2712
|
+
},
|
|
2713
|
+
update(message) {
|
|
2714
|
+
printLine(stream, message);
|
|
2715
|
+
},
|
|
2716
|
+
wait(message) {
|
|
2717
|
+
printLine(stream, message);
|
|
2718
|
+
},
|
|
2719
|
+
stop() {}
|
|
2720
|
+
};
|
|
2721
|
+
let currentMessage = "";
|
|
2722
|
+
let timer;
|
|
2723
|
+
let tick = 0;
|
|
2724
|
+
const stopTimer = () => {
|
|
2725
|
+
if (!timer) return;
|
|
2726
|
+
clearInterval(timer);
|
|
2727
|
+
timer = void 0;
|
|
2728
|
+
};
|
|
2729
|
+
return {
|
|
2730
|
+
start(message) {
|
|
2731
|
+
stopTimer();
|
|
2732
|
+
currentMessage = message;
|
|
2733
|
+
renderStatusLine(stream, currentMessage, colorEnabled);
|
|
2734
|
+
},
|
|
2735
|
+
update(message) {
|
|
2736
|
+
stopTimer();
|
|
2737
|
+
currentMessage = message;
|
|
2738
|
+
renderStatusLine(stream, currentMessage, colorEnabled);
|
|
2739
|
+
},
|
|
2740
|
+
wait(message) {
|
|
2741
|
+
stopTimer();
|
|
2742
|
+
currentMessage = message;
|
|
2743
|
+
tick = 0;
|
|
2744
|
+
renderWaitingStatusLine(stream, currentMessage, tick, colorEnabled);
|
|
2745
|
+
timer = setInterval(() => {
|
|
2746
|
+
tick += 1;
|
|
2747
|
+
renderWaitingStatusLine(stream, currentMessage, tick, colorEnabled);
|
|
2748
|
+
}, ANALYZER_WAITING_INTERVAL_MS);
|
|
2749
|
+
},
|
|
2750
|
+
stop() {
|
|
2751
|
+
stopTimer();
|
|
2752
|
+
clearStatusLine(stream);
|
|
2753
|
+
}
|
|
2754
|
+
};
|
|
2755
|
+
}
|
|
2756
|
+
//#endregion
|
|
2649
2757
|
//#region src/cli/data-workflows/header-mapping-flow.ts
|
|
2650
2758
|
function classifyHeaderSuggestionFailure(message, options) {
|
|
2651
2759
|
if (/codex exec exited/i.test(message) || /missing optional dependency/i.test(message) || /spawn/i.test(message) || /enoent/i.test(message) || /auth/i.test(message) || /sign in/i.test(message) || /api key/i.test(message)) return {
|
|
@@ -2682,6 +2790,7 @@ function buildHeaderSuggestionFollowUpCommand(options) {
|
|
|
2682
2790
|
options.format,
|
|
2683
2791
|
...options.shape.source ? ["--source", JSON.stringify(options.shape.source)] : [],
|
|
2684
2792
|
...options.shape.range ? ["--range", options.shape.range] : [],
|
|
2793
|
+
...options.shape.noHeader ? ["--no-header"] : [],
|
|
2685
2794
|
...options.shape.bodyStartRow !== void 0 ? ["--body-start-row", String(options.shape.bodyStartRow)] : [],
|
|
2686
2795
|
...options.shape.headerRow !== void 0 ? ["--header-row", String(options.shape.headerRow)] : [],
|
|
2687
2796
|
"--header-mapping",
|
|
@@ -2702,13 +2811,21 @@ async function resolveReusableHeaderMappingsForDataFlow(options) {
|
|
|
2702
2811
|
}
|
|
2703
2812
|
async function runCodexHeaderSuggestionFlow(options) {
|
|
2704
2813
|
const artifactPath = options.writeHeaderMapping?.trim() ? resolveFromCwd(options.runtime, options.writeHeaderMapping.trim()) : (0, node_path.join)(options.runtime.cwd, generateDataHeaderMappingFileName());
|
|
2705
|
-
const
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2814
|
+
const status = createInteractiveAnalyzerStatus(options.runtime.stdout, options.runtime.colorEnabled);
|
|
2815
|
+
let suggestionResult;
|
|
2816
|
+
try {
|
|
2817
|
+
status.start("Inspecting shaped source");
|
|
2818
|
+
const introspection = await options.collectIntrospection();
|
|
2819
|
+
status.wait("Waiting for Codex header suggestions");
|
|
2820
|
+
suggestionResult = await suggestDataHeaderMappingsWithCodex({
|
|
2821
|
+
format: options.format,
|
|
2822
|
+
introspection,
|
|
2823
|
+
runner: options.headerSuggestionRunner,
|
|
2824
|
+
workingDirectory: options.runtime.cwd
|
|
2825
|
+
});
|
|
2826
|
+
} finally {
|
|
2827
|
+
status.stop();
|
|
2828
|
+
}
|
|
2712
2829
|
if (suggestionResult.errorMessage) {
|
|
2713
2830
|
const failure = classifyHeaderSuggestionFailure(suggestionResult.errorMessage, {
|
|
2714
2831
|
failureCode: options.failureCode,
|
|
@@ -2999,7 +3116,7 @@ function buildSourceShapeHeaderSuggestionFollowUpCommand(options) {
|
|
|
2999
3116
|
].join(" ");
|
|
3000
3117
|
}
|
|
3001
3118
|
async function resolveReusableSourceShapeForDataFlow(options) {
|
|
3002
|
-
if (!isSourceShapeFormat(options.format)) throw new CliError(
|
|
3119
|
+
if (!isSourceShapeFormat(options.format)) throw new CliError(`--source-shape is only valid for Excel ${options.commandName} inputs.`, {
|
|
3003
3120
|
code: "INVALID_INPUT",
|
|
3004
3121
|
exitCode: 2
|
|
3005
3122
|
});
|
|
@@ -3166,14 +3283,18 @@ async function runCodexSourceShapeSuggestionFlow(runtime, options) {
|
|
|
3166
3283
|
});
|
|
3167
3284
|
const selectedSource = assertNonEmpty(options.source, "Source");
|
|
3168
3285
|
const artifactPath = options.writeSourceShape?.trim() ? resolveFromCwd(runtime, options.writeSourceShape.trim()) : (0, node_path.join)(runtime.cwd, generateDataSourceShapeFileName());
|
|
3286
|
+
const status = createInteractiveAnalyzerStatus(runtime.stdout, runtime.colorEnabled);
|
|
3169
3287
|
let connection;
|
|
3170
3288
|
try {
|
|
3171
3289
|
connection = await createDuckDbConnection$1();
|
|
3290
|
+
status.start("Inspecting worksheet structure");
|
|
3172
3291
|
const currentIntrospection = await collectDataQuerySourceIntrospection(connection, options.inputPath, options.format, { source: selectedSource }, 5);
|
|
3292
|
+
const sheetSnapshot = await collectXlsxSheetSnapshot(options.inputPath, selectedSource, { maxRows: 24 });
|
|
3293
|
+
status.wait("Waiting for Codex source-shape suggestions");
|
|
3173
3294
|
const suggestionResult = await suggestDataSourceShapeWithCodex({
|
|
3174
3295
|
context: {
|
|
3175
3296
|
currentIntrospection,
|
|
3176
|
-
sheetSnapshot
|
|
3297
|
+
sheetSnapshot
|
|
3177
3298
|
},
|
|
3178
3299
|
currentBodyStartRow: currentIntrospection.selectedBodyStartRow,
|
|
3179
3300
|
currentHeaderRow: currentIntrospection.selectedHeaderRow,
|
|
@@ -3181,6 +3302,7 @@ async function runCodexSourceShapeSuggestionFlow(runtime, options) {
|
|
|
3181
3302
|
runner: options.sourceShapeSuggestionRunner,
|
|
3182
3303
|
workingDirectory: runtime.cwd
|
|
3183
3304
|
});
|
|
3305
|
+
status.stop();
|
|
3184
3306
|
if (suggestionResult.errorMessage || !suggestionResult.shape || !suggestionResult.reasoningSummary) {
|
|
3185
3307
|
const failure = classifySourceShapeSuggestionFailure(suggestionResult.errorMessage ?? "Codex did not return a valid source-shape suggestion.");
|
|
3186
3308
|
throw new CliError(`${failure.prefix}: ${suggestionResult.errorMessage ?? "Codex did not return a valid source-shape suggestion."}`, {
|
|
@@ -3220,6 +3342,7 @@ async function runCodexSourceShapeSuggestionFlow(runtime, options) {
|
|
|
3220
3342
|
runtime
|
|
3221
3343
|
}));
|
|
3222
3344
|
} finally {
|
|
3345
|
+
status.stop();
|
|
3223
3346
|
connection?.closeSync();
|
|
3224
3347
|
}
|
|
3225
3348
|
}
|
|
@@ -3295,6 +3418,11 @@ async function actionDataExtract(runtime, options) {
|
|
|
3295
3418
|
const format = detectDataQueryInputFormat(inputPath, options.inputFormat);
|
|
3296
3419
|
const bodyStartRow = options.bodyStartRow;
|
|
3297
3420
|
const headerRow = options.headerRow;
|
|
3421
|
+
const noHeader = options.noHeader === true;
|
|
3422
|
+
if (noHeader && format !== "csv" && format !== "tsv") throw new CliError("--no-header is only valid for CSV and TSV extract inputs.", {
|
|
3423
|
+
code: "INVALID_INPUT",
|
|
3424
|
+
exitCode: 2
|
|
3425
|
+
});
|
|
3298
3426
|
const explicitRange = options.range?.trim() || void 0;
|
|
3299
3427
|
const explicitSource = options.source?.trim() || void 0;
|
|
3300
3428
|
if (options.codexSuggestShape) {
|
|
@@ -3309,6 +3437,7 @@ async function actionDataExtract(runtime, options) {
|
|
|
3309
3437
|
return;
|
|
3310
3438
|
}
|
|
3311
3439
|
const resolvedSourceShape = options.sourceShape?.trim() ? await resolveReusableSourceShapeForDataFlow({
|
|
3440
|
+
commandName: "extract",
|
|
3312
3441
|
format,
|
|
3313
3442
|
inputPath,
|
|
3314
3443
|
runtime,
|
|
@@ -3329,6 +3458,7 @@ async function actionDataExtract(runtime, options) {
|
|
|
3329
3458
|
shape: {
|
|
3330
3459
|
bodyStartRow: effectiveBodyStartRow,
|
|
3331
3460
|
headerRow: effectiveHeaderRow,
|
|
3461
|
+
noHeader,
|
|
3332
3462
|
range,
|
|
3333
3463
|
source
|
|
3334
3464
|
},
|
|
@@ -3338,6 +3468,7 @@ async function actionDataExtract(runtime, options) {
|
|
|
3338
3468
|
collectIntrospection: async () => await collectDataQuerySourceIntrospection(connection, inputPath, format, {
|
|
3339
3469
|
bodyStartRow: effectiveBodyStartRow,
|
|
3340
3470
|
headerRow: effectiveHeaderRow,
|
|
3471
|
+
noHeader,
|
|
3341
3472
|
range,
|
|
3342
3473
|
source
|
|
3343
3474
|
}, 5),
|
|
@@ -3360,6 +3491,7 @@ async function actionDataExtract(runtime, options) {
|
|
|
3360
3491
|
shape: {
|
|
3361
3492
|
...effectiveBodyStartRow !== void 0 ? { bodyStartRow: effectiveBodyStartRow } : {},
|
|
3362
3493
|
...effectiveHeaderRow !== void 0 ? { headerRow: effectiveHeaderRow } : {},
|
|
3494
|
+
...noHeader ? { noHeader: true } : {},
|
|
3363
3495
|
range,
|
|
3364
3496
|
source
|
|
3365
3497
|
}
|
|
@@ -3371,6 +3503,7 @@ async function actionDataExtract(runtime, options) {
|
|
|
3371
3503
|
bodyStartRow: effectiveBodyStartRow,
|
|
3372
3504
|
headerMappings: resolvedHeaderMappings,
|
|
3373
3505
|
headerRow: effectiveHeaderRow,
|
|
3506
|
+
noHeader,
|
|
3374
3507
|
range,
|
|
3375
3508
|
source
|
|
3376
3509
|
});
|
|
@@ -3522,6 +3655,22 @@ function validateDataQueryOptions(options) {
|
|
|
3522
3655
|
code: "INVALID_INPUT",
|
|
3523
3656
|
exitCode: 2
|
|
3524
3657
|
});
|
|
3658
|
+
if (options.sourceShape?.trim() && options.source?.trim()) throw new CliError("--source-shape cannot be used together with --source in the current replay flow.", {
|
|
3659
|
+
code: "INVALID_INPUT",
|
|
3660
|
+
exitCode: 2
|
|
3661
|
+
});
|
|
3662
|
+
if (options.sourceShape?.trim() && options.range?.trim()) throw new CliError("--source-shape cannot be used together with --range in the current replay flow.", {
|
|
3663
|
+
code: "INVALID_INPUT",
|
|
3664
|
+
exitCode: 2
|
|
3665
|
+
});
|
|
3666
|
+
if (options.sourceShape?.trim() && options.headerRow !== void 0) throw new CliError("--source-shape cannot be used together with --header-row in the current replay flow.", {
|
|
3667
|
+
code: "INVALID_INPUT",
|
|
3668
|
+
exitCode: 2
|
|
3669
|
+
});
|
|
3670
|
+
if (options.sourceShape?.trim() && options.bodyStartRow !== void 0) throw new CliError("--source-shape cannot be used together with --body-start-row in the current replay flow.", {
|
|
3671
|
+
code: "INVALID_INPUT",
|
|
3672
|
+
exitCode: 2
|
|
3673
|
+
});
|
|
3525
3674
|
}
|
|
3526
3675
|
function isDuckDbBuiltInQueryFormat(format) {
|
|
3527
3676
|
return format === "csv" || format === "tsv" || format === "parquet";
|
|
@@ -3545,12 +3694,29 @@ async function actionDataQuery(runtime, options) {
|
|
|
3545
3694
|
const format = detectDataQueryInputFormat(inputPath, options.inputFormat);
|
|
3546
3695
|
const bodyStartRow = options.bodyStartRow;
|
|
3547
3696
|
const headerRow = options.headerRow;
|
|
3697
|
+
const noHeader = options.noHeader === true;
|
|
3698
|
+
if (noHeader && format !== "csv" && format !== "tsv") throw new CliError("--no-header is only valid for CSV and TSV query inputs.", {
|
|
3699
|
+
code: "INVALID_INPUT",
|
|
3700
|
+
exitCode: 2
|
|
3701
|
+
});
|
|
3548
3702
|
if (options.installMissingExtension && isDuckDbBuiltInQueryFormat(format)) throw new CliError("--install-missing-extension is only valid for extension-backed query formats (sqlite, excel).", {
|
|
3549
3703
|
code: "INVALID_INPUT",
|
|
3550
3704
|
exitCode: 2
|
|
3551
3705
|
});
|
|
3552
|
-
const
|
|
3553
|
-
const
|
|
3706
|
+
const explicitRange = options.range?.trim() || void 0;
|
|
3707
|
+
const explicitSource = options.source?.trim() || void 0;
|
|
3708
|
+
const resolvedSourceShape = options.sourceShape?.trim() ? await resolveReusableSourceShapeForDataFlow({
|
|
3709
|
+
commandName: "query",
|
|
3710
|
+
format,
|
|
3711
|
+
inputPath,
|
|
3712
|
+
runtime,
|
|
3713
|
+
source: explicitSource,
|
|
3714
|
+
sourceShapePath: resolveFromCwd(runtime, options.sourceShape.trim())
|
|
3715
|
+
}) : void 0;
|
|
3716
|
+
const range = resolvedSourceShape?.range ?? explicitRange;
|
|
3717
|
+
const source = resolvedSourceShape?.source ?? explicitSource;
|
|
3718
|
+
const effectiveBodyStartRow = resolvedSourceShape?.bodyStartRow ?? bodyStartRow;
|
|
3719
|
+
const effectiveHeaderRow = resolvedSourceShape?.headerRow ?? headerRow;
|
|
3554
3720
|
const rowCount = options.rows ?? DEFAULT_QUERY_ROWS;
|
|
3555
3721
|
if (options.codexSuggestHeaders) {
|
|
3556
3722
|
const collectSourceIntrospection = options.sourceIntrospectionCollector ?? collectDataQuerySourceIntrospection;
|
|
@@ -3561,18 +3727,20 @@ async function actionDataQuery(runtime, options) {
|
|
|
3561
3727
|
format,
|
|
3562
3728
|
inputPath,
|
|
3563
3729
|
shape: {
|
|
3564
|
-
bodyStartRow,
|
|
3730
|
+
bodyStartRow: effectiveBodyStartRow,
|
|
3565
3731
|
range,
|
|
3566
|
-
headerRow,
|
|
3732
|
+
headerRow: effectiveHeaderRow,
|
|
3733
|
+
noHeader,
|
|
3567
3734
|
source
|
|
3568
3735
|
},
|
|
3569
3736
|
overwrite: options.overwrite,
|
|
3570
3737
|
writeHeaderMapping: options.writeHeaderMapping,
|
|
3571
3738
|
headerSuggestionRunner: options.headerSuggestionRunner,
|
|
3572
3739
|
collectIntrospection: async () => await collectSourceIntrospection(connection, inputPath, format, {
|
|
3573
|
-
bodyStartRow,
|
|
3740
|
+
bodyStartRow: effectiveBodyStartRow,
|
|
3574
3741
|
range,
|
|
3575
|
-
headerRow,
|
|
3742
|
+
headerRow: effectiveHeaderRow,
|
|
3743
|
+
noHeader,
|
|
3576
3744
|
source
|
|
3577
3745
|
}, DATA_QUERY_HEADER_SUGGESTION_SAMPLE_ROWS, {
|
|
3578
3746
|
installMissingExtension: options.installMissingExtension,
|
|
@@ -3595,9 +3763,10 @@ async function actionDataQuery(runtime, options) {
|
|
|
3595
3763
|
inputPath,
|
|
3596
3764
|
runtime,
|
|
3597
3765
|
shape: {
|
|
3598
|
-
bodyStartRow,
|
|
3766
|
+
...effectiveBodyStartRow !== void 0 ? { bodyStartRow: effectiveBodyStartRow } : {},
|
|
3599
3767
|
range,
|
|
3600
|
-
headerRow,
|
|
3768
|
+
...effectiveHeaderRow !== void 0 ? { headerRow: effectiveHeaderRow } : {},
|
|
3769
|
+
noHeader,
|
|
3601
3770
|
source
|
|
3602
3771
|
}
|
|
3603
3772
|
}) : void 0;
|
|
@@ -3606,9 +3775,10 @@ async function actionDataQuery(runtime, options) {
|
|
|
3606
3775
|
try {
|
|
3607
3776
|
connection = await createDuckDbConnection$1();
|
|
3608
3777
|
const preparedSource = await prepareDataQuerySource(connection, inputPath, format, {
|
|
3609
|
-
bodyStartRow,
|
|
3778
|
+
bodyStartRow: effectiveBodyStartRow,
|
|
3610
3779
|
headerMappings: resolvedHeaderMappings,
|
|
3611
|
-
headerRow,
|
|
3780
|
+
headerRow: effectiveHeaderRow,
|
|
3781
|
+
noHeader,
|
|
3612
3782
|
range,
|
|
3613
3783
|
source
|
|
3614
3784
|
}, {
|
|
@@ -3651,86 +3821,6 @@ async function actionDataQuery(runtime, options) {
|
|
|
3651
3821
|
}
|
|
3652
3822
|
}
|
|
3653
3823
|
//#endregion
|
|
3654
|
-
//#region src/cli/interactive/analyzer-status.ts
|
|
3655
|
-
const ANALYZER_WAITING_FRAMES = [
|
|
3656
|
-
". ",
|
|
3657
|
-
".. ",
|
|
3658
|
-
"...",
|
|
3659
|
-
".. ",
|
|
3660
|
-
". "
|
|
3661
|
-
];
|
|
3662
|
-
const ANALYZER_WAITING_INTERVAL_MS = 360;
|
|
3663
|
-
function clearStatusLine(stream) {
|
|
3664
|
-
stream.write("\r\x1B[2K");
|
|
3665
|
-
}
|
|
3666
|
-
function normalizeAnalyzerStatusMessage(message) {
|
|
3667
|
-
if (message.includes("Sampling filenames")) return "sampling";
|
|
3668
|
-
if (message.includes("Grouping filename patterns")) return "grouping";
|
|
3669
|
-
if (message.includes("Waiting for Codex cleanup suggestions")) return "waiting";
|
|
3670
|
-
return message;
|
|
3671
|
-
}
|
|
3672
|
-
function renderStatusLine(stream, message, colorEnabled) {
|
|
3673
|
-
const pc = (0, import_picocolors.createColors)(colorEnabled);
|
|
3674
|
-
const normalizedMessage = normalizeAnalyzerStatusMessage(message);
|
|
3675
|
-
const content = ` ${pc.dim("Codex")} ${pc.white("Thinking...")} ${pc.dim(normalizedMessage)} `;
|
|
3676
|
-
stream.write(`\r\x1b[2K${pc.bgBlack(content)}`);
|
|
3677
|
-
}
|
|
3678
|
-
function renderWaitingStatusLine(stream, message, tick, colorEnabled) {
|
|
3679
|
-
const pc = (0, import_picocolors.createColors)(colorEnabled);
|
|
3680
|
-
const normalizedMessage = normalizeAnalyzerStatusMessage(message);
|
|
3681
|
-
const dots = ANALYZER_WAITING_FRAMES[tick % ANALYZER_WAITING_FRAMES.length] ?? "...";
|
|
3682
|
-
const content = ` ${pc.dim("Codex")} ${pc.white("Thinking")} ${pc.dim(normalizedMessage)} ${pc.gray(dots)} `;
|
|
3683
|
-
stream.write(`\r\x1b[2K${pc.bgBlack(content)}`);
|
|
3684
|
-
}
|
|
3685
|
-
function createInteractiveAnalyzerStatus(stream, colorEnabled = true) {
|
|
3686
|
-
if (!stream.isTTY) return {
|
|
3687
|
-
start(message) {
|
|
3688
|
-
printLine(stream, message);
|
|
3689
|
-
},
|
|
3690
|
-
update(message) {
|
|
3691
|
-
printLine(stream, message);
|
|
3692
|
-
},
|
|
3693
|
-
wait(message) {
|
|
3694
|
-
printLine(stream, message);
|
|
3695
|
-
},
|
|
3696
|
-
stop() {}
|
|
3697
|
-
};
|
|
3698
|
-
let currentMessage = "";
|
|
3699
|
-
let timer;
|
|
3700
|
-
let tick = 0;
|
|
3701
|
-
const stopTimer = () => {
|
|
3702
|
-
if (!timer) return;
|
|
3703
|
-
clearInterval(timer);
|
|
3704
|
-
timer = void 0;
|
|
3705
|
-
};
|
|
3706
|
-
return {
|
|
3707
|
-
start(message) {
|
|
3708
|
-
stopTimer();
|
|
3709
|
-
currentMessage = message;
|
|
3710
|
-
renderStatusLine(stream, currentMessage, colorEnabled);
|
|
3711
|
-
},
|
|
3712
|
-
update(message) {
|
|
3713
|
-
stopTimer();
|
|
3714
|
-
currentMessage = message;
|
|
3715
|
-
renderStatusLine(stream, currentMessage, colorEnabled);
|
|
3716
|
-
},
|
|
3717
|
-
wait(message) {
|
|
3718
|
-
stopTimer();
|
|
3719
|
-
currentMessage = message;
|
|
3720
|
-
tick = 0;
|
|
3721
|
-
renderWaitingStatusLine(stream, currentMessage, tick, colorEnabled);
|
|
3722
|
-
timer = setInterval(() => {
|
|
3723
|
-
tick += 1;
|
|
3724
|
-
renderWaitingStatusLine(stream, currentMessage, tick, colorEnabled);
|
|
3725
|
-
}, ANALYZER_WAITING_INTERVAL_MS);
|
|
3726
|
-
},
|
|
3727
|
-
stop() {
|
|
3728
|
-
stopTimer();
|
|
3729
|
-
clearStatusLine(stream);
|
|
3730
|
-
}
|
|
3731
|
-
};
|
|
3732
|
-
}
|
|
3733
|
-
//#endregion
|
|
3734
3824
|
//#region src/cli/data-query/codex.ts
|
|
3735
3825
|
const DATA_QUERY_CODEX_OUTPUT_SCHEMA = {
|
|
3736
3826
|
type: "object",
|
|
@@ -9626,6 +9716,13 @@ async function promptOptionalSourceSelection(format, sources) {
|
|
|
9626
9716
|
}))
|
|
9627
9717
|
});
|
|
9628
9718
|
}
|
|
9719
|
+
async function promptDelimitedHeaderMode(format) {
|
|
9720
|
+
if (format !== "csv" && format !== "tsv") return;
|
|
9721
|
+
return await (0, _inquirer_prompts.confirm)({
|
|
9722
|
+
message: "Treat CSV/TSV input as headerless?",
|
|
9723
|
+
default: false
|
|
9724
|
+
});
|
|
9725
|
+
}
|
|
9629
9726
|
//#endregion
|
|
9630
9727
|
//#region src/cli/interactive/data-query/types.ts
|
|
9631
9728
|
const QUERY_CONTINUATION_LABELS = {
|
|
@@ -9749,7 +9846,7 @@ function renderIntrospectionSummary(runtime, options) {
|
|
|
9749
9846
|
}
|
|
9750
9847
|
async function collectInteractiveIntrospection(options) {
|
|
9751
9848
|
const labels = options.labels ?? QUERY_CONTINUATION_LABELS;
|
|
9752
|
-
let sourceShape = {};
|
|
9849
|
+
let sourceShape = options.initialNoHeader ? { selectedNoHeader: true } : {};
|
|
9753
9850
|
let cachedSheetSnapshot;
|
|
9754
9851
|
const getSheetSnapshot = async () => {
|
|
9755
9852
|
const selectedSource = options.selectedSource?.trim();
|
|
@@ -9767,6 +9864,7 @@ async function collectInteractiveIntrospection(options) {
|
|
|
9767
9864
|
const introspection = await collectDataQuerySourceIntrospection(options.connection, options.inputPath, options.format, {
|
|
9768
9865
|
bodyStartRow: sourceShape.selectedBodyStartRow,
|
|
9769
9866
|
headerRow: sourceShape.selectedHeaderRow,
|
|
9867
|
+
noHeader: sourceShape.selectedNoHeader,
|
|
9770
9868
|
range: sourceShape.selectedRange,
|
|
9771
9869
|
source: options.selectedSource
|
|
9772
9870
|
}, DATA_QUERY_INTERACTIVE_SAMPLE_ROWS$1);
|
|
@@ -9992,6 +10090,7 @@ async function reviewInteractiveHeaderMappings(options) {
|
|
|
9992
10090
|
bodyStartRow: options.selectedBodyStartRow,
|
|
9993
10091
|
headerMappings: acceptedMappings,
|
|
9994
10092
|
headerRow: options.selectedHeaderRow,
|
|
10093
|
+
noHeader: options.selectedNoHeader,
|
|
9995
10094
|
range: options.selectedRange,
|
|
9996
10095
|
source: options.selectedSource
|
|
9997
10096
|
}, DATA_QUERY_INTERACTIVE_SAMPLE_ROWS);
|
|
@@ -10121,6 +10220,7 @@ async function executeInteractiveCandidate(runtime, pathPromptContext, options)
|
|
|
10121
10220
|
...options.headerMappings ? { headerMappings: options.headerMappings } : {},
|
|
10122
10221
|
...options.selectedBodyStartRow !== void 0 ? { bodyStartRow: options.selectedBodyStartRow } : {},
|
|
10123
10222
|
...options.selectedHeaderRow !== void 0 ? { headerRow: options.selectedHeaderRow } : {},
|
|
10223
|
+
...options.selectedNoHeader ? { noHeader: true } : {},
|
|
10124
10224
|
...options.selectedRange ? { range: options.selectedRange } : {},
|
|
10125
10225
|
...options.selectedSource ? { source: options.selectedSource } : {},
|
|
10126
10226
|
sql: options.sql
|
|
@@ -10200,6 +10300,7 @@ async function runCodexInteractiveQuery(runtime, pathPromptContext, options) {
|
|
|
10200
10300
|
input: options.input,
|
|
10201
10301
|
selectedBodyStartRow: options.selectedBodyStartRow,
|
|
10202
10302
|
selectedHeaderRow: options.selectedHeaderRow,
|
|
10303
|
+
selectedNoHeader: options.selectedNoHeader,
|
|
10203
10304
|
selectedRange: options.selectedRange,
|
|
10204
10305
|
selectedSource: options.selectedSource,
|
|
10205
10306
|
sql: draftResult.draft.sql
|
|
@@ -10446,6 +10547,7 @@ async function runFormalGuideInteractiveQuery(runtime, pathPromptContext, option
|
|
|
10446
10547
|
input: options.input,
|
|
10447
10548
|
selectedBodyStartRow: options.selectedBodyStartRow,
|
|
10448
10549
|
selectedHeaderRow: options.selectedHeaderRow,
|
|
10550
|
+
selectedNoHeader: options.selectedNoHeader,
|
|
10449
10551
|
selectedRange: options.selectedRange,
|
|
10450
10552
|
selectedSource: options.selectedSource,
|
|
10451
10553
|
sql
|
|
@@ -10477,6 +10579,7 @@ async function runInteractiveDataQuery(runtime, pathPromptContext) {
|
|
|
10477
10579
|
});
|
|
10478
10580
|
const inputPath = resolveFromCwd(runtime, input);
|
|
10479
10581
|
const format = await promptInteractiveInputFormat(runtime, inputPath);
|
|
10582
|
+
const noHeader = await promptDelimitedHeaderMode(format);
|
|
10480
10583
|
let connection;
|
|
10481
10584
|
try {
|
|
10482
10585
|
connection = await createDuckDbConnection$1();
|
|
@@ -10484,6 +10587,7 @@ async function runInteractiveDataQuery(runtime, pathPromptContext) {
|
|
|
10484
10587
|
const { introspection, sourceShape } = await collectInteractiveIntrospection({
|
|
10485
10588
|
connection,
|
|
10486
10589
|
format,
|
|
10590
|
+
initialNoHeader: noHeader,
|
|
10487
10591
|
inputPath,
|
|
10488
10592
|
labels: QUERY_CONTINUATION_LABELS,
|
|
10489
10593
|
runtime,
|
|
@@ -10498,6 +10602,7 @@ async function runInteractiveDataQuery(runtime, pathPromptContext) {
|
|
|
10498
10602
|
runtime,
|
|
10499
10603
|
selectedBodyStartRow: sourceShape.selectedBodyStartRow,
|
|
10500
10604
|
selectedHeaderRow: sourceShape.selectedHeaderRow,
|
|
10605
|
+
selectedNoHeader: sourceShape.selectedNoHeader,
|
|
10501
10606
|
selectedRange: sourceShape.selectedRange,
|
|
10502
10607
|
selectedSource
|
|
10503
10608
|
});
|
|
@@ -10525,6 +10630,7 @@ async function runInteractiveDataQuery(runtime, pathPromptContext) {
|
|
|
10525
10630
|
input,
|
|
10526
10631
|
selectedBodyStartRow: sourceShape.selectedBodyStartRow,
|
|
10527
10632
|
selectedHeaderRow: sourceShape.selectedHeaderRow,
|
|
10633
|
+
selectedNoHeader: sourceShape.selectedNoHeader,
|
|
10528
10634
|
selectedRange: sourceShape.selectedRange,
|
|
10529
10635
|
selectedSource
|
|
10530
10636
|
});
|
|
@@ -10538,6 +10644,7 @@ async function runInteractiveDataQuery(runtime, pathPromptContext) {
|
|
|
10538
10644
|
headerMappings: reviewedHeaders.headerMappings,
|
|
10539
10645
|
selectedBodyStartRow: sourceShape.selectedBodyStartRow,
|
|
10540
10646
|
selectedHeaderRow: sourceShape.selectedHeaderRow,
|
|
10647
|
+
selectedNoHeader: sourceShape.selectedNoHeader,
|
|
10541
10648
|
selectedRange: sourceShape.selectedRange,
|
|
10542
10649
|
selectedSource
|
|
10543
10650
|
});
|
|
@@ -10550,6 +10657,7 @@ async function runInteractiveDataQuery(runtime, pathPromptContext) {
|
|
|
10550
10657
|
headerMappings: reviewedHeaders.headerMappings,
|
|
10551
10658
|
selectedBodyStartRow: sourceShape.selectedBodyStartRow,
|
|
10552
10659
|
selectedHeaderRow: sourceShape.selectedHeaderRow,
|
|
10660
|
+
selectedNoHeader: sourceShape.selectedNoHeader,
|
|
10553
10661
|
selectedRange: sourceShape.selectedRange,
|
|
10554
10662
|
selectedSource
|
|
10555
10663
|
});
|
|
@@ -10653,6 +10761,7 @@ async function runInteractiveDataExtract(runtime, pathPromptContext) {
|
|
|
10653
10761
|
});
|
|
10654
10762
|
const inputPath = resolveFromCwd(runtime, input);
|
|
10655
10763
|
const format = await promptInteractiveInputFormat(runtime, inputPath);
|
|
10764
|
+
const noHeader = await promptDelimitedHeaderMode(format);
|
|
10656
10765
|
let connection;
|
|
10657
10766
|
try {
|
|
10658
10767
|
connection = await createDuckDbConnection$1();
|
|
@@ -10660,6 +10769,7 @@ async function runInteractiveDataExtract(runtime, pathPromptContext) {
|
|
|
10660
10769
|
const { introspection, sourceShape } = await collectInteractiveIntrospection({
|
|
10661
10770
|
connection,
|
|
10662
10771
|
format,
|
|
10772
|
+
initialNoHeader: noHeader,
|
|
10663
10773
|
inputPath,
|
|
10664
10774
|
labels: EXTRACT_CONTINUATION_LABELS,
|
|
10665
10775
|
runtime,
|
|
@@ -10674,6 +10784,7 @@ async function runInteractiveDataExtract(runtime, pathPromptContext) {
|
|
|
10674
10784
|
runtime,
|
|
10675
10785
|
selectedBodyStartRow: sourceShape.selectedBodyStartRow,
|
|
10676
10786
|
selectedHeaderRow: sourceShape.selectedHeaderRow,
|
|
10787
|
+
selectedNoHeader: sourceShape.selectedNoHeader,
|
|
10677
10788
|
selectedRange: sourceShape.selectedRange,
|
|
10678
10789
|
selectedSource
|
|
10679
10790
|
});
|
|
@@ -10690,6 +10801,7 @@ async function runInteractiveDataExtract(runtime, pathPromptContext) {
|
|
|
10690
10801
|
...reviewedHeaders.headerMappings ? { headerMappings: reviewedHeaders.headerMappings } : {},
|
|
10691
10802
|
input,
|
|
10692
10803
|
inputFormat: format,
|
|
10804
|
+
...sourceShape.selectedNoHeader ? { noHeader: true } : {},
|
|
10693
10805
|
output: outputOptions.output,
|
|
10694
10806
|
overwrite: outputOptions.overwrite,
|
|
10695
10807
|
...sourceShape.selectedBodyStartRow !== void 0 ? { bodyStartRow: sourceShape.selectedBodyStartRow } : {},
|
|
@@ -12362,7 +12474,7 @@ function registerDataDuckDbCommands(dataCommand, runtime) {
|
|
|
12362
12474
|
//#endregion
|
|
12363
12475
|
//#region src/cli/commands/data/extract.ts
|
|
12364
12476
|
function registerDataExtractCommand(dataCommand, runtime) {
|
|
12365
|
-
dataCommand.command("extract").description("Materialize one shaped table from one input file").argument("<input>", "Input data file").option("--input-format <format>", `Override detected input format (${DATA_QUERY_INPUT_FORMAT_VALUES.join(", ")})`, parseDataQueryInputFormatOption).option("--source <name>", "Source object name for SQLite tables/views or Excel sheets").option("--range <A1:Z99>", "Excel cell range within the selected sheet").option("--body-start-row <value>", "Excel worksheet row number where logical body rows begin", (value) => parsePositiveIntegerOption(value, "--body-start-row")).option("--header-row <value>", "Excel worksheet row number to treat as the header row", (value) => parsePositiveIntegerOption(value, "--header-row")).option("--source-shape <path>", "Reuse an accepted JSON source-shape artifact").option("--codex-suggest-shape", "Ask Codex to suggest an explicit Excel source shape and stop after writing the review artifact", false).option("--write-source-shape <path>", "Write the suggested source-shape artifact to an explicit path").option("--header-mapping <path>", "Reuse an accepted JSON header-mapping artifact").option("--codex-suggest-headers", "Ask Codex to suggest semantic header mappings and stop after writing the review artifact", false).option("--write-header-mapping <path>", "Write the suggested header-mapping artifact to an explicit path").option("-o, --output <path>", "Write the shaped table to a .csv, .tsv, or .json file").option("--overwrite", "Overwrite output file if it already exists", false).action(async (input, options) => {
|
|
12477
|
+
dataCommand.command("extract").description("Materialize one shaped table from one input file").argument("<input>", "Input data file").option("--input-format <format>", `Override detected input format (${DATA_QUERY_INPUT_FORMAT_VALUES.join(", ")})`, parseDataQueryInputFormatOption).option("--source <name>", "Source object name for SQLite tables/views or Excel sheets").option("--range <A1:Z99>", "Excel cell range within the selected sheet").option("--no-header", "Treat CSV or TSV input as headerless and generate column_n names").option("--body-start-row <value>", "Excel worksheet row number where logical body rows begin", (value) => parsePositiveIntegerOption(value, "--body-start-row")).option("--header-row <value>", "Excel worksheet row number to treat as the header row", (value) => parsePositiveIntegerOption(value, "--header-row")).option("--source-shape <path>", "Reuse an accepted JSON source-shape artifact").option("--codex-suggest-shape", "Ask Codex to suggest an explicit Excel source shape and stop after writing the review artifact", false).option("--write-source-shape <path>", "Write the suggested source-shape artifact to an explicit path").option("--header-mapping <path>", "Reuse an accepted JSON header-mapping artifact").option("--codex-suggest-headers", "Ask Codex to suggest semantic header mappings and stop after writing the review artifact", false).option("--write-header-mapping <path>", "Write the suggested header-mapping artifact to an explicit path").option("-o, --output <path>", "Write the shaped table to a .csv, .tsv, or .json file").option("--overwrite", "Overwrite output file if it already exists", false).action(async (input, options) => {
|
|
12366
12478
|
await actionDataExtract(runtime, {
|
|
12367
12479
|
bodyStartRow: options.bodyStartRow,
|
|
12368
12480
|
codexSuggestShape: options.codexSuggestShape,
|
|
@@ -12371,6 +12483,7 @@ function registerDataExtractCommand(dataCommand, runtime) {
|
|
|
12371
12483
|
headerRow: options.headerRow,
|
|
12372
12484
|
input,
|
|
12373
12485
|
inputFormat: options.inputFormat,
|
|
12486
|
+
noHeader: options.noHeader ?? options.header === false,
|
|
12374
12487
|
output: options.output,
|
|
12375
12488
|
overwrite: options.overwrite,
|
|
12376
12489
|
range: options.range,
|
|
@@ -12406,7 +12519,7 @@ function registerDataPreviewCommands(dataCommand, runtime) {
|
|
|
12406
12519
|
//#endregion
|
|
12407
12520
|
//#region src/cli/commands/data/query.ts
|
|
12408
12521
|
function registerDataQueryCommands(dataCommand, runtime) {
|
|
12409
|
-
dataCommand.command("query").description("Run a DuckDB-backed SQL query against one input file").argument("<input>", "Input data file").option("--sql <query>", "SQL query to execute against logical table `file`").option("--input-format <format>", `Override detected input format (${DATA_QUERY_INPUT_FORMAT_VALUES.join(", ")})`, parseDataQueryInputFormatOption).option("--source <name>", "Source object name for SQLite tables/views or Excel sheets").option("--range <A1:Z99>", "Excel cell range within the selected sheet").option("--body-start-row <value>", "Excel worksheet row number where logical body rows begin", (value) => parsePositiveIntegerOption(value, "--body-start-row")).option("--header-row <value>", "Excel worksheet row number to treat as the header row", (value) => parsePositiveIntegerOption(value, "--header-row")).option("--header-mapping <path>", "Reuse an accepted JSON header-mapping artifact").option("--codex-suggest-headers", "Ask Codex to suggest semantic header mappings and stop after writing the review artifact", false).option("--write-header-mapping <path>", "Write the suggested header-mapping artifact to an explicit path").option("--install-missing-extension", "Attempt one DuckDB extension install-and-retry for sqlite/excel inputs", false).option("--rows <value>", "Number of rows to show in bounded table output", (value) => parsePositiveIntegerOption(value, "--rows")).option("--json", "Write full query results as JSON to stdout", false).option("--pretty", "Pretty-print JSON stdout or .json file output", false).option("-o, --output <path>", "Write full query results to a .json or .csv file").option("--overwrite", "Overwrite output file if it already exists", false).action(async (input, options) => {
|
|
12522
|
+
dataCommand.command("query").description("Run a DuckDB-backed SQL query against one input file").argument("<input>", "Input data file").option("--sql <query>", "SQL query to execute against logical table `file`").option("--input-format <format>", `Override detected input format (${DATA_QUERY_INPUT_FORMAT_VALUES.join(", ")})`, parseDataQueryInputFormatOption).option("--source <name>", "Source object name for SQLite tables/views or Excel sheets").option("--range <A1:Z99>", "Excel cell range within the selected sheet").option("--source-shape <path>", "Reuse an accepted JSON source-shape artifact for Excel query replay").option("--no-header", "Treat CSV or TSV input as headerless and generate column_n names").option("--body-start-row <value>", "Excel worksheet row number where logical body rows begin", (value) => parsePositiveIntegerOption(value, "--body-start-row")).option("--header-row <value>", "Excel worksheet row number to treat as the header row", (value) => parsePositiveIntegerOption(value, "--header-row")).option("--header-mapping <path>", "Reuse an accepted JSON header-mapping artifact").option("--codex-suggest-headers", "Ask Codex to suggest semantic header mappings and stop after writing the review artifact", false).option("--write-header-mapping <path>", "Write the suggested header-mapping artifact to an explicit path").option("--install-missing-extension", "Attempt one DuckDB extension install-and-retry for sqlite/excel inputs", false).option("--rows <value>", "Number of rows to show in bounded table output", (value) => parsePositiveIntegerOption(value, "--rows")).option("--json", "Write full query results as JSON to stdout", false).option("--pretty", "Pretty-print JSON stdout or .json file output", false).option("-o, --output <path>", "Write full query results to a .json or .csv file").option("--overwrite", "Overwrite output file if it already exists", false).action(async (input, options) => {
|
|
12410
12523
|
await actionDataQuery(runtime, {
|
|
12411
12524
|
bodyStartRow: options.bodyStartRow,
|
|
12412
12525
|
codexSuggestHeaders: options.codexSuggestHeaders,
|
|
@@ -12416,11 +12529,13 @@ function registerDataQueryCommands(dataCommand, runtime) {
|
|
|
12416
12529
|
inputFormat: options.inputFormat,
|
|
12417
12530
|
installMissingExtension: options.installMissingExtension,
|
|
12418
12531
|
json: options.json,
|
|
12532
|
+
noHeader: options.noHeader ?? options.header === false,
|
|
12419
12533
|
output: options.output,
|
|
12420
12534
|
overwrite: options.overwrite,
|
|
12421
12535
|
pretty: options.pretty,
|
|
12422
12536
|
range: options.range,
|
|
12423
12537
|
rows: options.rows,
|
|
12538
|
+
sourceShape: options.sourceShape,
|
|
12424
12539
|
source: options.source,
|
|
12425
12540
|
sql: options.sql,
|
|
12426
12541
|
writeHeaderMapping: options.writeHeaderMapping
|
|
@@ -12587,7 +12702,7 @@ function registerCliCommands(program, runtime) {
|
|
|
12587
12702
|
}
|
|
12588
12703
|
//#endregion
|
|
12589
12704
|
//#region src/cli/program/version-embedded.ts
|
|
12590
|
-
const EMBEDDED_PACKAGE_VERSION = "0.0.
|
|
12705
|
+
const EMBEDDED_PACKAGE_VERSION = "0.0.9-canary.2";
|
|
12591
12706
|
//#endregion
|
|
12592
12707
|
//#region src/cli/program/version.ts
|
|
12593
12708
|
function* candidateSearchRoots() {
|
|
@@ -12620,7 +12735,7 @@ function normalizeVersion(value) {
|
|
|
12620
12735
|
return trimmed;
|
|
12621
12736
|
}
|
|
12622
12737
|
function resolvePackageVersion(options = {}) {
|
|
12623
|
-
const embeddedVersion = normalizeVersion(options.embeddedVersion ?? "0.0.
|
|
12738
|
+
const embeddedVersion = normalizeVersion(options.embeddedVersion ?? "0.0.9-canary.2");
|
|
12624
12739
|
if (embeddedVersion) return embeddedVersion;
|
|
12625
12740
|
const maxLevels = options.maxLevels ?? 8;
|
|
12626
12741
|
const resolveFromPath = options.resolveFromPath ?? resolveVersionFromPath;
|