import 'reflect-metadata'; import { config as setupEnv } from 'dotenv-flow'; import { AggregateProduct } from '@/entities'; import { TypeormDataLoader } from '@/entities/utils'; import logger from '@/logger'; import { syncProductsToAlgolia } from '@/utils'; import connect from '../src/config/db'; setupEnv({ silent: true }); /** * To run this script in development, you'll need to: * 1. cd api * 2. Add algolia api keys in api/.env.local * 3. Start the api: yarn docker:compose * 4. Reset the schema in a new terminal tab: yarn docker:schema:reset * 5. Once the db schema is reset, make sure to ctrl+c the api tab. * 6. Change the value of TYPEORM_HOST from database to localhost in * api/.env.development * 7. Run NODE_ENV='development' yarn tsnode scripts/sync-products-to-algolia.ts */ const main = async () => { await connect(); let unIndexedProducts = new Array(); let indexedProductCount = 0; const dbDataLoader = new TypeormDataLoader(); const indexProducts = async () => { const unIndexedProductIds = unIndexedProducts.map(({ id }) => id); await syncProductsToAlgolia(unIndexedProductIds, dbDataLoader); indexedProductCount = indexedProductCount + unIndexedProducts.length; logger.info(`indexed ${indexedProductCount} products`); unIndexedProducts = []; }; const stream = await AggregateProduct.createQueryBuilder( 'AggregateProduct' ).stream(); await new Promise((resolve, reject) => { stream.on('data', (pgProduct: Record) => { const product = AggregateProduct.create( Object.entries(pgProduct).reduce((prev, [key, value]) => { return { ...prev, [key.startsWith('AggregateProduct_') ? key.slice(17) : key]: value, }; }, {}) ); unIndexedProducts.push(product); if (unIndexedProducts.length >= 100) { stream.pause(); indexProducts() .then(() => { stream.resume(); }) .catch((error) => { stream.destroy(error); reject(error); }); } }); stream.on('end', async () => { resolve(undefined); if (unIndexedProducts.length >= 0) { try { indexProducts().then(resolve); } catch (error) { stream.destroy(); reject(error); throw error; } } }); }); }; if (require.main === module) { console.time('sync-products-to-algolia'); main() .then(() => { console.timeEnd('sync-products-to-algolia'); }) .catch((error) => { logger.error(error); process.exit(1); }); }