SPB Git forge

spb/rareindex

Public
54commits 1branches 0releases
7.1 MBsize
maindefault branch
10 days agolast push
TypeScript 61.9% HTML 37.2% SQL 0.7%
3.2 KB · 58 lines typescript
Raw Blame History
1/**2 * Live smoke + fixture capture for the auction-house connectors.3 * Usage: pnpm tsx connectors/api/_auction-lib/smoke.ts <connectorId> [--limit N] [--seed URL]... [--category slug]... [--capture name]4 * Requires FIRECRAWL_API_KEY / SCRAPFLY_API_KEY in the environment for the engines the connector uses.5 */6import { createCrawlContext, createRouter, getConnectorMeta, loadConnector } from '@rareindex/connectors';7import { saveFixture } from '@rareindex/connectors/testing';8import { childLogger } from '@rareindex/shared';910const [id, ...rest] = process.argv.slice(2);11if (!id) throw new Error('usage: smoke.ts <connectorId> [--limit N] [--seed URL] [--category slug] [--capture name]');12const opt = { limit: 12, seeds: [] as string[], categories: [] as string[], capture: null as string | null };13for (let i = 0; i < rest.length; i++) {14  const a = rest[i]!;15  if (a === '--limit') opt.limit = Number(rest[++i]);16  else if (a === '--seed') opt.seeds.push(rest[++i]!);17  else if (a === '--category') opt.categories.push(rest[++i]!);18  else if (a === '--capture') opt.capture = rest[++i]!;19}2021const meta = getConnectorMeta(id);22const connector = await loadConnector(id);23const router = createRouter({ firecrawlApiKey: process.env.FIRECRAWL_API_KEY, scrapflyApiKey: process.env.SCRAPFLY_API_KEY });24const ctx = createCrawlContext({25  router,26  meta,27  options: { mode: 'probe', limit: opt.limit, ...(opt.seeds.length ? { seeds: opt.seeds } : {}), ...(opt.categories.length ? { categories: opt.categories } : {}) },28  log: childLogger({ connector: id, smoke: true }),29});3031let rawCount = 0;32let total = 0;33const kinds: Record<string, number> = {};34let captured = 0;35for await (const raw of connector.crawl(ctx)) {36  rawCount++;37  const rawLike = { ...raw, externalId: raw.externalId ?? null, fetchedAt: raw.fetchedAt ?? new Date() };38  const records = await connector.normalize(rawLike);39  total += records.length;40  for (const r of records) kinds[r.kind] = (kinds[r.kind] ?? 0) + 1;41  const p = raw.payload as { lots?: unknown[]; kind?: string };42  console.log(`raw#${rawCount} ${raw.kind} ${raw.url} → payload.${p.kind} lots=${p.lots?.length ?? '-'} → ${records.length} records`);43  for (const r of records.slice(0, 2)) console.log(JSON.stringify(r, null, 1).slice(0, 1800));44  if (opt.capture && captured < 3 && records.length) {45    const name = `${opt.capture}-${captured + 1}`;46    const first = records[0]!;47    saveFixture(id, name, {48      raw: { ...rawLike, payload: JSON.parse(JSON.stringify(rawLike.payload)) },49      expect: { minCount: 1, kinds: [...new Set(records.map((r) => r.kind))], first: { kind: first.kind, ...('auctionHouse' in first ? { auctionHouse: (first as { auctionHouse: string }).auctionHouse } : {}), ...('currency' in first && first.currency ? { currency: first.currency } : {}) } },50      note: `Captured live by connectors/api/_auction-lib/smoke.ts on ${new Date().toISOString().slice(0, 10)} (${records.length} records from this raw page).`,51    });52    captured++;53    console.log(`  saved fixture data/fixtures/${id}/${name}.json`);54  }55  if (rawCount >= 6) break;56}57console.log(JSON.stringify({ rawCount, totalNormalized: total, kinds, engineStats: ctx.engineStats, anomalies: ctx.anomalies }, null, 1));58