import 'dotenv/config'; import { db, ClosePool } from '../src/db/index.ts'; import chalk from 'chalk'; import fs from "fs"; //import path from "node:path"; import { parse, stringify, transform } from 'csv'; import { client } from '../src/db/typesense.ts'; async function PricesFromCSV() { const inputFilePath = 'scripts/test.tcgcollector.csv'; const outputFilePath = 'scripts/output.csv'; // Create read and write streams const inputStream = fs.createReadStream(inputFilePath, 'utf8'); const outputStream = fs.createWriteStream(outputFilePath); // Define the transformation logic const transformer = transform({ parallel: 1 }, async function(this: any, row: any, callback: any) { try { // Specific query bsaed on tcgcollector CSV const query = String(Object.values(row)[1]); const setname = String(Object.values(row)[4]).replace(/Wizards of the coast promos/ig,'WoTC Promo'); const cardNumber = String(Object.values(row)[7]); console.log(`${query} ${cardNumber} : ${setname}`); // Use Typesense to find the card because we can easily use the combined fields let cards = await client.collections('cards').documents().search({ q: query, query_by: 'productName', filter_by: `setName:\`${setname}\` && number:${cardNumber}` }); if (cards.hits?.length === 0) { // Try without card number cards = await client.collections('cards').documents().search({ q: query, query_by: 'productName', filter_by: `setName:\`${setname}\`` }); } if (cards.hits?.length === 0) { // Try without set name cards = await client.collections('cards').documents().search({ q: query, query_by: 'productName', filter_by: `number:${cardNumber}` }); } if (cards.hits?.length === 0) { // I give up, just output the values from the csv console.log(chalk.red(' - not found')); const newRow = { ...row }; newRow.Variant = ''; newRow.marketPrice = ''; this.push(newRow); } else { for (const card of cards.hits?.map((hit: any) => hit.document) ?? []) { console.log(chalk.blue(` - ${card.cardId} : ${card.productName} : ${card.number}`), chalk.yellow(`${card.setName}`), chalk.green(`${card.variant}`)); const variant = await db.query.cards.findFirst({ with: { prices: true, tcgdata: true }, where: { cardId: card.cardId } }); const newRow = { ...row }; newRow.Variant = variant?.variant; newRow.marketPrice = variant?.prices.find(p => p.condition === 'Near Mint')?.marketPrice; this.push(newRow); } } callback(); } catch (error) { callback(error); } }); // Pipe the streams: Read -> Parse -> Transform -> Stringify -> Write inputStream .on('error', (error) => console.error('Input stream error:', error)) .pipe(parse({ columns: true, trim: true })) .on('error', (error) => console.error('Parse error:', error)) .pipe(transformer) .on('error', (error) => console.error('Transform error:', error)) .pipe(stringify({ header: true })) .on('error', (error) => console.error('Stringify error:', error)) .pipe(outputStream); outputStream.on('finish', () => { console.log(`Successfully written to ${outputFilePath}`); ClosePool(); }); outputStream.on('error', (error) => { console.error('An error occurred in the process:', error); ClosePool(); }); } await PricesFromCSV();