feat: add XLSX export functionality and refactor argument parsing in main script

This commit is contained in:
Victor Noguera
2026-05-20 16:18:12 -04:00
parent 0c2e59771c
commit f8bc05685e
2 changed files with 72 additions and 6 deletions

View File

@@ -1,6 +1,10 @@
import { readProducts } from "./reader.ts";
import { connectCache, disconnectCache } from "./cache.ts";
import { printResults, writeResultsToDb } from "./writer.ts";
import {
printResults,
writeResultsToDb,
writeResultsWorkbook,
} from "./writer.ts";
import { initDb, closeDb } from "./database.ts";
import {
chunkArray,
@@ -40,14 +44,18 @@ function parseArgs(): {
sellability: SellabilityFilter;
} {
const args = process.argv.slice(2);
const inputFile = args.find((a) => !a.startsWith("--"));
const outIdx = args.indexOf("--out");
const outputFile = outIdx !== -1 ? args[outIdx + 1] : undefined;
const outputFile = readFlagValue(args, "--out", "--output");
const inputFile = readInputFileArg(
args,
"--out",
"--output",
"--sellability",
);
const sellability = parseSellabilityArg(args);
if (!inputFile) {
console.error(
"Usage: bun run src/index.ts <input.csv|xlsx> [--out results.csv] [--sellability available|all]",
"Usage: bun run src/index.ts <input.csv|xlsx> [--out results.xlsx|--output results.xlsx] [--sellability available|all]",
);
process.exit(1);
}
@@ -55,6 +63,44 @@ function parseArgs(): {
return { inputFile, outputFile, sellability };
}
function readFlagValue(args: string[], ...flags: string[]): string | undefined {
for (const flag of flags) {
const equalsArg = args.find((arg) => arg.startsWith(`${flag}=`));
if (equalsArg) {
const value = equalsArg.slice(flag.length + 1);
if (value) return value;
}
const flagIdx = args.indexOf(flag);
if (flagIdx !== -1) {
return args[flagIdx + 1];
}
}
return undefined;
}
function readInputFileArg(
args: string[],
...flagsWithValues: string[]
): string | undefined {
for (let i = 0; i < args.length; i++) {
const arg = args[i]!;
if (flagsWithValues.includes(arg)) {
i++;
continue;
}
if (flagsWithValues.some((flag) => arg.startsWith(`${flag}=`))) {
continue;
}
if (!arg.startsWith("--")) {
return arg;
}
}
return undefined;
}
function resolveBaseOutputPath(inputFile: string, outputFile?: string): string {
if (outputFile) return outputFile;
@@ -103,7 +149,8 @@ async function main() {
}
printResults(allResults);
writeResultsToDb(allResults, DB_PATH, inputFile, outputFile);
writeResultsWorkbook(allResults, resolvedBaseOutputPath);
writeResultsToDb(allResults, DB_PATH, inputFile, resolvedBaseOutputPath);
} finally {
await disconnectCache();
closeDb();

View File

@@ -1,5 +1,8 @@
import { getDb } from "./database.ts";
import type { AnalysisResult, SupplierAnalysisResult } from "./types.ts";
import { mkdirSync } from "node:fs";
import path from "node:path";
import * as XLSX from "xlsx";
export type RunCounts = {
totalProducts: number;
@@ -93,6 +96,22 @@ export function writeResultsToDb(
console.log(`Results written to SQLite database for run_id: ${runId}`);
}
export function writeResultsWorkbook(
results: AnalysisResult[],
outputFile: string,
): void {
const outputDir = path.dirname(outputFile);
if (outputDir && outputDir !== ".") {
mkdirSync(outputDir, { recursive: true });
}
const workbook = XLSX.utils.book_new();
const worksheet = XLSX.utils.json_to_sheet(results.map(buildRow));
XLSX.utils.book_append_sheet(workbook, worksheet, "Results");
XLSX.writeFile(workbook, outputFile);
console.log(`Results workbook written: ${outputFile}`);
}
export function startRunInDb(
dbPath: string,
inputFile: string,