/** Live fixture capture for hareruya: search-form cardsets + two unisearch_api pages. Usage: pnpm tsx connectors/api/hareruya/_capture.ts */ import { mkdirSync, writeFileSync } from 'node:fs'; import path from 'node:path'; import { fixtureDir, saveFixture } from '@rareindex/connectors/testing'; import { DocSchema, apiUrl, parseCardsets, type HareruyaPayload } from './index.js'; import { HTML_HEADERS, JSON_HEADERS } from '../_g1-cards-eu-jp-lib/index.js'; const SITE = 'https://www.hareruyamtg.com'; const wait = (ms: number) => new Promise((r) => setTimeout(r, ms)); mkdirSync(fixtureDir('hareruya'), { recursive: true }); const form = await (await fetch(`${SITE}/en/products/search`, { headers: HTML_HEADERS })).text(); writeFileSync(path.join(fixtureDir('hareruya'), 'search-form.html'), form); const cardsets = parseCardsets(form); console.log('cardsets', cardsets.length, cardsets.slice(0, 3)); async function page(cardset: { id: string; name: string }, pageNo: number, name: string, note: string, keep = 15) { await wait(4000); const url = apiUrl(cardset.id, pageNo, 60); const json = (await (await fetch(url, { headers: { ...JSON_HEADERS, referer: `${SITE}/en/products/search?cardset=${cardset.id}` } })).json()) as { response: { numFound: number; page: number | string; docs: unknown[] } }; const docs = json.response.docs.map((d) => DocSchema.parse(d)).slice(0, keep); const payload: HareruyaPayload = { cardset, page: pageNo, numFound: json.response.numFound, docs }; saveFixture('hareruya', name, { raw: { url, externalId: `${cardset.id}:p${pageNo}`, kind: 'listing', engine: 'api', fetchedAt: new Date(), payload }, expect: { minCount: Math.min(keep, docs.length), kinds: ['listing'], requiredFields: ['price', 'attributes.name', 'attributes.identifiers.hareruya_product_id'] }, note: `Live capture ${new Date().toISOString().slice(0, 10)} — ${url} (${note}; numFound ${json.response.numFound}, first ${docs.length} docs kept)`, }); console.log(name, cardset, json.response.numFound, docs[0]); return json.response.numFound; } const newest = cardsets[0]!; await page(newest, 1, 'newest-set-page1', `newest card set in the form: ${newest.name}`); // a set with several languages/foils: find one with a large numFound among the first options const big = cardsets.find((c) => /Foundations|Bloomburrow|Duskmourn|Aetherdrift|Tarkir/i.test(c.name)) ?? cardsets[3]!; const n = await page(big, 1, 'multi-language-page1', `set ${big.name} with EN/JP/foil offers`); if (n > 60) await page(big, 2, 'multi-language-page2', `page 2 of ${big.name} (pagination)`, 8);