Merge branches 'main' and 'main' of https://github.com/nvictorme/asin-check

This commit is contained in:
Victor Noguera
2026-04-12 23:51:16 -04:00
5 changed files with 550 additions and 369 deletions

View File

@@ -3,8 +3,10 @@ import { fetchKeepaDataBatch } from "./keepa.ts";
import { fetchSellabilityBatch, fetchSpApiPricingAndFees } from "./sp-api.ts";
import { connectCache, getCache, setCache, disconnectCache } from "./cache.ts";
import { analyzeProducts } from "./llm.ts";
import { printResults, writeResultsCsv } from "./writer.ts";
import path from "node:path";
import { printResults, writeResultsToDb } from "./writer.ts";
import { initDb, closeDb } from "./database.ts";
const DB_PATH = "./results.db";
import type {
EnrichedProduct,
AnalysisResult,
@@ -32,38 +34,26 @@ function parseArgs(): { inputFile: string; outputFile?: string } {
return { inputFile, outputFile };
}
function chunkArray<T>(items: T[], chunkSize: number): T[][] {
const chunks: T[][] = [];
for (let i = 0; i < items.length; i += chunkSize) {
chunks.push(items.slice(i, i + chunkSize));
async function main() {
const { inputFile, outputFile } = parseArgs();
console.log("Connecting to Redis...");
await connectCache();
// Initialize SQLite DB
console.log("Initializing SQLite database...");
initDb(DB_PATH);
// Phase 1: Read input file
console.log(`\nReading ${inputFile}...`);
const products = readProducts(inputFile);
if (products.length === 0) {
console.error("No valid products found in input file.");
process.exit(1);
}
return chunks;
}
function resolveBaseOutputPath(inputFile: string, outputFile?: string): string {
if (outputFile) return outputFile;
const parsedInput = path.parse(inputFile);
return path.join(parsedInput.dir, `${parsedInput.name}_results.xlsx`);
}
function buildChunkOutputPath(
baseOutputPath: string,
chunkIndex: number,
): string {
const parsed = path.parse(baseOutputPath);
const extension = parsed.ext || ".xlsx";
const chunkSuffix = String(chunkIndex + 1).padStart(3, "0");
return path.join(
parsed.dir,
`${parsed.name}_part_${chunkSuffix}${extension}`,
);
}
async function processProductChunk(
products: ProductRecord[],
): Promise<AnalysisResult[]> {
// Phase 2: Check cache for all ASINs in chunk
// Phase 2: Check cache for all ASINs
console.log(`\nChecking cache for ${products.length} products...`);
const cached = new Map<string, EnrichedProduct>();
const excludedCachedAsins = new Set<string>();
@@ -331,12 +321,10 @@ async function main() {
printResults(allResults);
if (!hasMultipleChunks && outputFile) {
writeResultsCsv(allResults, outputFile);
}
} finally {
await disconnectCache();
}
writeResultsToDb(allResults, DB_PATH, inputFile, outputFile);
await disconnectCache();
closeDb();
}
main().catch((err) => {