feat: add XLSX export functionality and refactor argument parsing in main script
This commit is contained in:
59
src/index.ts
59
src/index.ts
@@ -1,6 +1,10 @@
|
|||||||
import { readProducts } from "./reader.ts";
|
import { readProducts } from "./reader.ts";
|
||||||
import { connectCache, disconnectCache } from "./cache.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 { initDb, closeDb } from "./database.ts";
|
||||||
import {
|
import {
|
||||||
chunkArray,
|
chunkArray,
|
||||||
@@ -40,14 +44,18 @@ function parseArgs(): {
|
|||||||
sellability: SellabilityFilter;
|
sellability: SellabilityFilter;
|
||||||
} {
|
} {
|
||||||
const args = process.argv.slice(2);
|
const args = process.argv.slice(2);
|
||||||
const inputFile = args.find((a) => !a.startsWith("--"));
|
const outputFile = readFlagValue(args, "--out", "--output");
|
||||||
const outIdx = args.indexOf("--out");
|
const inputFile = readInputFileArg(
|
||||||
const outputFile = outIdx !== -1 ? args[outIdx + 1] : undefined;
|
args,
|
||||||
|
"--out",
|
||||||
|
"--output",
|
||||||
|
"--sellability",
|
||||||
|
);
|
||||||
const sellability = parseSellabilityArg(args);
|
const sellability = parseSellabilityArg(args);
|
||||||
|
|
||||||
if (!inputFile) {
|
if (!inputFile) {
|
||||||
console.error(
|
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);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
@@ -55,6 +63,44 @@ function parseArgs(): {
|
|||||||
return { inputFile, outputFile, sellability };
|
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 {
|
function resolveBaseOutputPath(inputFile: string, outputFile?: string): string {
|
||||||
if (outputFile) return outputFile;
|
if (outputFile) return outputFile;
|
||||||
|
|
||||||
@@ -103,7 +149,8 @@ async function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
printResults(allResults);
|
printResults(allResults);
|
||||||
writeResultsToDb(allResults, DB_PATH, inputFile, outputFile);
|
writeResultsWorkbook(allResults, resolvedBaseOutputPath);
|
||||||
|
writeResultsToDb(allResults, DB_PATH, inputFile, resolvedBaseOutputPath);
|
||||||
} finally {
|
} finally {
|
||||||
await disconnectCache();
|
await disconnectCache();
|
||||||
closeDb();
|
closeDb();
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import { getDb } from "./database.ts";
|
import { getDb } from "./database.ts";
|
||||||
import type { AnalysisResult, SupplierAnalysisResult } from "./types.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 = {
|
export type RunCounts = {
|
||||||
totalProducts: number;
|
totalProducts: number;
|
||||||
@@ -93,6 +96,22 @@ export function writeResultsToDb(
|
|||||||
console.log(`Results written to SQLite database for run_id: ${runId}`);
|
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(
|
export function startRunInDb(
|
||||||
dbPath: string,
|
dbPath: string,
|
||||||
inputFile: string,
|
inputFile: string,
|
||||||
|
|||||||
Reference in New Issue
Block a user