import type { ConnectorMeta } from '@rareindex/connectors'; import { CertLookupConnector, type PageStatus, type ParsedCert } from '../_g2-grading-lib/cert-base.js'; import { ccgClassify, ccgParse, ccgTrim, pick } from '../_g2-grading-lib/ccg.js'; import { clean, comicsCategorySlug, parseCardGrade, parseDate, yearOf } from '../_g2-grading-lib/text.js'; /** * CGC Comics certificate verification — https://www.cgccomics.com/certlookup// (public; the CGC * census / population report proper is login-gated and never fetched). Same CCG AngularJS template as * NGC/PMG/CGC Cards; behind a Cloudflare managed challenge, rendered by Firecrawl. */ const PARSER_VERSION = '1.0.0'; const PATTERNS = [/^https?:\/\/(?:www\.)?cgccomics\.com\/(?:certlookup\/)?(\d{6,12})\/?(?:[?#].*)?$/i]; export function certUrl(cert: string): string { return `https://www.cgccomics.com/certlookup/${clean(cert).replace(/\D/g, '')}/`; } export function certFromUrl(url: string): string | null { const m = url.match(PATTERNS[0]!); return m ? m[1]! : null; } export class CgcCertConnector extends CertLookupConnector { readonly version = '1.0.0'; readonly parserVersion = PARSER_VERSION; readonly grader = 'cgc'; readonly idKey = 'cgc_cert'; readonly format = 'html' as const; override readonly urlPatterns = PATTERNS; certUrl(cert: string): string { return certUrl(cert); } certFromUrl(url: string): string | null { return certFromUrl(url); } classify(doc: string): PageStatus { return ccgClassify(doc); } trim(doc: string): string { return ccgTrim(doc); } parse(snapshot: string, info: { cert: string; url: string }): ParsedCert | null { const page = ccgParse(snapshot); const f = page.fields; const cert = pick(f, 'CGC Cert #', 'Cert #', 'Cert') ?? info.cert; const title = pick(f, 'Title'); if (!title) return null; const issue = pick(f, 'Issue'); const publisher = pick(f, 'Publisher'); const issueDate = pick(f, 'Issue Date'); const gradeRaw = pick(f, 'Grade'); const g = parseCardGrade(gradeRaw); const label = pick(f, 'Label Category'); const labelQualifier = label && !/^universal$/i.test(label) ? label : null; const qualifier = [g.qualifier, labelQualifier].filter(Boolean).join(' ') || null; const year = yearOf(pick(f, 'Issue Year')) ?? parseDate(issueDate)?.getUTCFullYear() ?? null; const keyComments = page.lines['Key Comments'] ?? []; const variant = pick(f, 'Variant', 'Variant Description', 'Edition') ?? null; const rawTitle = `${title}${issue ? ` #${issue}` : ''}${publisher || issueDate ? ` (${[publisher, issueDate].filter(Boolean).join(', ')})` : ''}${gradeRaw ? ` CGC ${gradeRaw}` : ''}${labelQualifier ? ` ${labelQualifier}` : ''}`; return { title: rawTitle, attributes: { categorySlug: comicsCategorySlug(publisher), brand: publisher, series: title, name: `${title}${issue ? ` #${issue}` : ''}`, number: issue, year, variant, identifiers: {}, metadata: { cgc_cert: cert, issue_date: issueDate, page_quality: pick(f, 'Page Quality'), grade_date: pick(f, 'Grade Date'), label_category: label, art_comments: page.lines['Art Comments'] ?? null, key_comments: keyComments.length ? keyComments : null, grader_notes: page.lines['Grader Notes'] ?? null, population_url: page.populationUrl, fields: f, }, }, grade: g.grade, qualifier, gradeLabel: g.label || null, description: keyComments.length ? keyComments.join(' ') : null, images: page.images, population: page.atGrade !== null ? { gradeKey: g.grade ?? page.popGradeKey ?? g.label, atGrade: page.atGrade, higher: page.higher, url: page.populationUrl } : null, confidence: 0.92, }; } } export default (meta: ConnectorMeta) => new CgcCertConnector(meta);