TypeScript 61.9%
HTML 37.2%
SQL 0.7%
1import { describe, expect, it } from 'vitest';2import { readFileSync } from 'node:fs';3import path from 'node:path';4import { fileURLToPath } from 'node:url';5import { runFixtureSuite } from '@rareindex/connectors/testing';6import { localMeta } from '../_lib/local-meta.js';7import { monthYearDate } from '../_g7-auctions-na-lib/index.js';8import createConnector, { cleanSweepCategory, isBundle, monthKey, parseLotPage, parseMonthPage, parsePastIndex } from './index.js';910const dir = path.dirname(fileURLToPath(import.meta.url));11const meta = localMeta(JSON.parse(readFileSync(path.join(dir, 'meta.json'), 'utf8')));12const connector = createConnector(meta);1314// Real fragments captured live from www.cleansweepauctions.com on 2026-09-08.15const INDEX = `<div class="col-md-3"> <div class="auction-list-item"> <div class="image-container"> <a href="/past-auctions/may-2025"> <img src="http://marketplace.cleansweepauctions.com/images/main/entertainmentlot705986.jpg" alt="May 2025" /> </a> </div> <a href="/past-auctions/may-2025"> May 2025 </a> </div> </div>16<div class="col-md-3"> <div class="auction-list-item"> <div class="image-container"> <a href="/past-auctions/april-2025"> <img src="http://marketplace.cleansweepauctions.com/images/main/flick678144b.jpg" alt="April 2025" /> </a> </div> <a href="/past-auctions/april-2025"> April 2025 </a> </div> </div>17<div class="col-md-3"> <div class="auction-list-item"> <a href="/past-auctions/december-2025"> December 2025 </a> </div> </div>18<div class="col-md-3"> <div class="auction-list-item"> <a href="/past-auctions/april-2008"> April 2008 </a> </div> </div>19<a href="/past-auctions">Past Auctions</a>`;2021const MONTH_PAGE = `<h1 style="font-weight:600;">April 2025</h1>22<div class="row"> <div class="col-md-3"> <div class="auction-list-item"> <div class="image-container"> <img src="http://marketplace.cleansweepauctions.com/images/main/mcclothlin713341.jpg" alt="1971 Topps 556 Jim McClothlin 8 " /> </div> <!-- 🔥 CORRECT ROUTE --> <a href="/past-auctions/april-2025/1971-topps-556-jim-mcclothlin-8"> 1971 Topps 556 Jim McClothlin 8 </a> </div> </div>23<div class="col-md-3"> <div class="auction-list-item"> <div class="image-container"> <img src="http://marketplace.cleansweepauctions.com/images/main/dodgers713283.jpg" alt="1947 Exhibit 294 Dodgers Team 1956 PSA 3.5 " /> </div> <a href="/past-auctions/april-2025/1947-exhibit-294-dodgers-team-1956-psa-35"> 1947 Exhibit 294 Dodgers Team 1956 PSA 3.5 </a> </div> </div> </div>24<div class="pagination" style="text-align:center;"> <a href="?page=1&q=&category=&auction=&sort=" class="active"> 1 </a> <a href="?page=2&q=&category=&auction=&sort=" class=""> 2 </a> <a href="?page=3&q=&category=&auction=&sort=" class=""> 3 </a> <a href="?page=12&q=" class="">Next →</a> </div>`;2526const LOT_PAGE = `<section id="subheader"> <div class="container"> <h1 style="font-weight:600;">1971 Topps 556 Jim McClothlin 8 </h1> <ul class="crumb"> <li><a href="/">Home</a></li> <li class="sep">/</li> <li><a href="april-2025">April 2025</a></li> <li class="sep">/</li> <li>Auction Item Details</li> </ul> </div> </section>27<section> <div class="container"> <div class="row"> <div class="col-md-4"> <div class='card'> <img src='http://marketplace.cleansweepauctions.com/images/main/mcclothlin713341.jpg' /> </div> </div> <div class="col-md-8"> <h2 style="padding-top: 10px;"> 1971 Topps 556 Jim McClothlin 8 </h2> <div> </div> <div> <strong style="display:block; padding-top:10px; color: #993B34;">Winning bid: $70.00</strong> </div> </div> </div> <a href="/past-auctions/april-2025" class="back-to-auction">< Back to April 2025</a> </div> </section>`;2829describe('clean-sweep', () => {30 runFixtureSuite(connector, it, expect);3132 it('parses the past-auction index newest first', () => {33 expect(parsePastIndex(INDEX)).toEqual(['december-2025', 'may-2025', 'april-2025', 'april-2008']);34 expect(monthKey('april-2025')).toBe(202504);35 expect(monthKey('not-a-month')).toBeNull();36 });3738 it('parses a month page (lots + page count)', () => {39 const mp = parseMonthPage(MONTH_PAGE, 'april-2025', 1);40 expect(mp.monthLabel).toBe('April 2025');41 expect(mp.totalPages).toBe(12);42 expect(mp.lots.length).toBe(2);43 expect(mp.lots[0]).toEqual({ slug: '1971-topps-556-jim-mcclothlin-8', url: 'https://www.cleansweepauctions.com/past-auctions/april-2025/1971-topps-556-jim-mcclothlin-8', title: '1971 Topps 556 Jim McClothlin 8', image: 'https://marketplace.cleansweepauctions.com/images/main/mcclothlin713341.jpg' });44 });4546 it('parses the lot page winning bid and month date', () => {47 const p = parseLotPage(LOT_PAGE, 'https://www.cleansweepauctions.com/past-auctions/april-2025/1971-topps-556-jim-mcclothlin-8', 'april-2025', '1971-topps-556-jim-mcclothlin-8', 'https://www.cleansweepauctions.com/past-auctions/april-2025')!;48 expect(p).toMatchObject({ title: '1971 Topps 556 Jim McClothlin 8', winningBidText: '$70.00', price: 70, monthLabel: 'April 2025' });49 expect(p.image).toBe('https://marketplace.cleansweepauctions.com/images/main/mcclothlin713341.jpg');50 expect(monthYearDate('april-2025')?.toISOString()).toBe('2025-04-01T00:00:00.000Z');51 });5253 it('normalises to a hammer sale with month precision and no inferred grader', async () => {54 const p = parseLotPage(LOT_PAGE, 'https://www.cleansweepauctions.com/past-auctions/april-2025/1971-topps-556-jim-mcclothlin-8', 'april-2025', '1971-topps-556-jim-mcclothlin-8', 'https://www.cleansweepauctions.com/past-auctions/april-2025')!;55 const out = await connector.normalize({ url: p.url, externalId: 'april-2025/1971-topps-556-jim-mcclothlin-8', kind: 'sale', engine: 'api', fetchedAt: new Date('2026-09-08T00:00:00Z'), payload: p });56 expect(out.length).toBe(1);57 const s = out[0]!;58 if (s.kind !== 'sale') throw new Error('expected sale');59 expect(s).toMatchObject({ price: 70, currency: 'USD', buyerPremiumIncluded: false, auctionHouse: 'Clean Sweep Auctions', confidence: 0.7, isBundle: false });60 expect(s.saleDate.toISOString()).toBe('2025-04-01T00:00:00.000Z');61 expect(s.attributes.categorySlug).toBe('baseball_cards');62 expect(s.attributes.metadata).toMatchObject({ sale_date_precision: 'month', buyers_premium_pct: 22, hammer_price: 70 });63 expect(s.attributes.identifiers.clean_sweep_lot_slug).toBe('april-2025/1971-topps-556-jim-mcclothlin-8');64 expect(s.grade.grader).toBeNull();65 expect(s.attributes.year).toBe(1971);66 });6768 it('keeps graders when the title names one and flags bundles', async () => {69 const graded = { ...parseLotPage(LOT_PAGE, 'https://www.cleansweepauctions.com/x', 'april-2025', 'x', 'y')!, title: '1947 Exhibit 294 Dodgers Team 1956 PSA 3.5', price: 120 };70 const [s] = await connector.normalize({ url: 'https://www.cleansweepauctions.com/x', externalId: 'x', kind: 'sale', engine: 'api', fetchedAt: new Date('2026-09-08T00:00:00Z'), payload: graded });71 if (!s || s.kind !== 'sale') throw new Error('expected sale');72 expect(s.grade).toMatchObject({ grader: 'psa', grade: '3.5' });73 expect(s.confidence).toBe(0.75);74 expect(isBundle('1970s Reds Signed Dinner Programs w/Bench, Rose (3 pcs) 9')).toBe(true);75 expect(isBundle('1971 Topps 556 Jim McClothlin 8')).toBe(false);76 expect(cleanSweepCategory('2018 Topps Update 285 Ohtani RC Ex')).toBe('baseball_cards');77 expect(cleanSweepCategory('1986 Fleer 57 Michael Jordan RC PSA 7')).toBe('basketball_cards');78 expect(cleanSweepCategory('1970 NLCS At Cincinnati Program NM')).toBe('sports_memorabilia');79 expect(cleanSweepCategory('Big Red Machine Single Signed Ball Lot (27 different) 8')).toBe('sports_memorabilia');80 const unsold = await connector.normalize({ url: 'https://www.cleansweepauctions.com/x', externalId: 'x', kind: 'sale', engine: 'api', fetchedAt: new Date(), payload: { ...graded, price: null, winningBidText: null } });81 expect(unsold).toEqual([]);82 });83});84