/** * Debug a specific park + date to inspect raw API data and parsed output. * * Usage: * npm run debug -- --park greatadventure --date 2026-07-04 * * Output is printed to the terminal and saved to debug/{parkId}_{date}.txt */ import fs from "fs"; import path from "path"; import { openDb, getApiId } from "../lib/db"; import { PARKS } from "../lib/parks"; import { scrapeMonthRaw } from "../lib/scrapers/sixflags"; function arg(flag: string): string | undefined { const i = process.argv.indexOf(flag); return i !== -1 ? process.argv[i + 1] : undefined; } function fmt24(time: string): string { const [h, m] = time.split(":").map(Number); const period = h >= 12 ? "pm" : "am"; const h12 = h % 12 || 12; return m === 0 ? `${h12}${period}` : `${h12}:${String(m).padStart(2, "0")}${period}`; } async function main() { const parkId = arg("--park"); const dateStr = arg("--date"); if (!parkId || !dateStr) { console.error("Usage: npm run debug -- --park --date "); console.error("\nAvailable park IDs:"); for (const p of PARKS) console.error(` ${p.id.padEnd(24)} ${p.name}`); process.exit(1); } const park = PARKS.find((p) => p.id === parkId); if (!park) { console.error(`Unknown park: "${parkId}"`); process.exit(1); } const match = dateStr.match(/^(\d{4})-(\d{2})-(\d{2})$/); if (!match) { console.error(`Invalid date: "${dateStr}" — expected YYYY-MM-DD`); process.exit(1); } const [, yearStr, monthStr, dayStr] = match; const year = parseInt(yearStr); const month = parseInt(monthStr); const day = parseInt(dayStr); const db = openDb(); const apiId = getApiId(db, park.id); db.close(); if (apiId === null) { console.error(`No API ID found for ${park.name} — run: npm run discover`); process.exit(1); } // Collect all output so we can write it to a file as well const lines: string[] = []; const out = (...args: string[]) => { const line = args.join(" "); lines.push(line); console.log(line); }; out(`Park : ${park.name} (${park.id})`); out(`API ID : ${apiId}`); out(`Date : ${dateStr}`); out(`Fetched : ${new Date().toISOString()}`); out(""); out(`Fetching ${year}-${String(month).padStart(2, "0")} from API...`); const raw = await scrapeMonthRaw(apiId, year, month); const targetDate = `${String(month).padStart(2, "0")}/${String(day).padStart(2, "0")}/${year}`; const dayData = raw.dates.find((d) => d.date === targetDate); if (!dayData) { console.error(`Date ${dateStr} not found in API response.`); console.error(`Dates returned by API: ${raw.dates.map((d) => d.date).join(", ")}`); process.exit(1); } // ── Raw API response ─────────────────────────────────────────────────────── out(""); out("── Raw API response ─────────────────────────────────────────"); out(JSON.stringify(dayData, null, 2)); // ── Parsed result ────────────────────────────────────────────────────────── const operating = dayData.operatings?.find((o) => o.operatingTypeName === "Park") ?? dayData.operatings?.[0]; const item = operating?.items?.[0]; const hoursLabel = item?.timeFrom && item?.timeTo ? `${fmt24(item.timeFrom)} – ${fmt24(item.timeTo)}` : undefined; const isOpen = !dayData.isParkClosed && hoursLabel !== undefined; out(""); out("── Parsed result ────────────────────────────────────────────"); out(` isParkClosed : ${dayData.isParkClosed}`); out(` operatings : ${dayData.operatings?.length ?? 0} entr${dayData.operatings?.length === 1 ? "y" : "ies"}`); if (operating) { out(` selected : "${operating.operatingTypeName}" (${operating.items?.length ?? 0} item(s))`); if (item) { out(` timeFrom : ${item.timeFrom} → ${fmt24(item.timeFrom)}`); out(` timeTo : ${item.timeTo} → ${fmt24(item.timeTo)}`); } } out(` hoursLabel : ${hoursLabel ?? "(none)"}`); out(` isOpen : ${isOpen}`); // ── Write to file ────────────────────────────────────────────────────────── const debugDir = path.join(process.cwd(), "debug"); fs.mkdirSync(debugDir, { recursive: true }); const outPath = path.join(debugDir, `${parkId}_${dateStr}.txt`); fs.writeFileSync(outPath, lines.join("\n") + "\n"); console.log(`\nSaved to debug/${parkId}_${dateStr}.txt`); } main().catch((err) => { console.error("Fatal:", err); process.exit(1); });