UNPKG

@accounter/scraper-app

Version:
70 lines (61 loc) 2.14 kB
import { addMonths, format, startOfMonth } from 'date-fns'; import type { z } from 'zod'; import { init } from '@accounter/modern-poalim-scraper'; import type { ServerMessage } from '../../shared/ws-protocol.js'; import type { DiscountPayload } from '../payload-schemas/discount.schema.js'; import { validatePayload } from '../validate-payload.js'; import type { DiscountAccountSchema } from '../vault.js'; export type DiscountCreds = z.infer<typeof DiscountAccountSchema>; export type Emitter = (msg: ServerMessage) => void; function buildMonthList(dateFrom: Date, dateTo: Date): Date[] { const months: Date[] = []; let current = startOfMonth(dateFrom); const end = startOfMonth(dateTo); while (current <= end) { months.push(current); current = addMonths(current, 1); } return months; } export async function scrapeDiscount( creds: DiscountCreds, dateFrom: Date, dateTo: Date, emit: Emitter, headless = true, ): Promise<DiscountPayload> { const { discount: discountFn, close } = await init({ headless }); try { const scraper = await discountFn({ ID: creds.ID, password: creds.password, ...(creds.code ? { code: creds.code } : {}), }); const months = buildMonthList(dateFrom, dateTo); const results: DiscountPayload = []; for (const month of months) { const monthStr = format(month, 'yyyy-MM'); emit({ type: 'task-month-fetching', sourceId: creds.id, month: monthStr }); try { const { accountNumber, balance, transactions } = await scraper.getMonthTransactions(month); emit({ type: 'task-month-fetched', sourceId: creds.id, month: monthStr, transactionCount: transactions.length, }); results.push({ accountNumber, month: monthStr, balance, transactions }); } catch (err) { emit({ type: 'task-month-error', sourceId: creds.id, month: monthStr, error: err instanceof Error ? err.message : String(err), }); } } return validatePayload('discount', results); } finally { await close(); } }