diff --git a/fixtures/genshin/game8-events-2026-08-14.expected.json b/fixtures/genshin/game8-events-2026-08-14.expected.json index bc6bf1d..f5421c5 100644 --- a/fixtures/genshin/game8-events-2026-08-14.expected.json +++ b/fixtures/genshin/game8-events-2026-08-14.expected.json @@ -4,7 +4,7 @@ "game": "genshin", "title": "To Temper Thyself and Journey Far", "type": "other", - "summary": null, + "summary": "In the To Temper Thyself and Journey Far event, players can complete the Daily and Weekly Training Goals to claim various rewards, including a 5-Star constellation from a character of their choice in the selection pool!", "startsAt": "2026-08-10T00:00:00.000Z", "startPrecision": "day", "endsAt": "2026-11-02T00:00:00.000Z", @@ -25,7 +25,7 @@ "game": "genshin", "title": "Battle Pass - Frostfarer", "type": "other", - "summary": null, + "summary": "Participate in the free Sojourner's Battle Pass and the for-purchase Gnostic Hymn to receive prizes as you increase your BP Level.", "startsAt": "2026-08-12T00:00:00.000Z", "startPrecision": "day", "endsAt": "2026-09-21T00:00:00.000Z", @@ -46,7 +46,7 @@ "game": "genshin", "title": "Character Test Runs", "type": "challenge", - "summary": null, + "summary": "The Character Test Run is available at the same time as the Character Banners in Phase 1 of Version 7.0 from August 12, 2026 to September 1, 2026!", "startsAt": "2026-08-12T00:00:00.000Z", "startPrecision": "day", "endsAt": "2026-09-01T00:00:00.000Z", @@ -67,7 +67,7 @@ "game": "genshin", "title": "Mutual Aid in Bloom: Into the Frostlands", "type": "other", - "summary": null, + "summary": "Take photos and complete objectives in this Snezhnaya exploration event!", "startsAt": "2026-08-12T00:00:00.000Z", "startPrecision": "day", "endsAt": "2026-08-24T00:00:00.000Z", @@ -88,7 +88,7 @@ "game": "genshin", "title": "Snezhnaya Travel Guide Web Event", "type": "other", - "summary": null, + "summary": "Earn rewards from progressing the 7.0 quests, initiating new combat and exploration mechanics, and connecting with other players via invitation codes!", "startsAt": "2026-08-12T00:00:00.000Z", "startPrecision": "day", "endsAt": "2026-08-25T00:00:00.000Z", @@ -109,7 +109,7 @@ "game": "genshin", "title": "Stygian Onslaught", "type": "challenge", - "summary": null, + "summary": "The Stygian Onslaught event is a recurring boss rush event where you must defeat three field bosses in different difficulties, solo or in Co-Op.", "startsAt": "2026-08-19T00:00:00.000Z", "startPrecision": "day", "endsAt": "2026-09-22T00:00:00.000Z", @@ -130,7 +130,7 @@ "game": "genshin", "title": "Great Expeditionist Challenge", "type": "challenge", - "summary": null, + "summary": "Join the Adventurer's Guild Tournament to play minigames and win prizes in the 7.0 flagship event, Great Expeditionist Challenge!", "startsAt": "2026-08-28T00:00:00.000Z", "startPrecision": "day", "endsAt": "2026-09-14T00:00:00.000Z", @@ -151,7 +151,7 @@ "game": "genshin", "title": "Trial of the Bastion", "type": "challenge", - "summary": null, + "summary": "Construct mechanisms and use firearms to defend your stronghold in the base defense event, Trial of the Bastion!", "startsAt": "2026-09-07T00:00:00.000Z", "startPrecision": "day", "endsAt": "2026-09-17T00:00:00.000Z", @@ -172,7 +172,7 @@ "game": "genshin", "title": "Overflowing Abundance Rerun", "type": "rerun", - "summary": null, + "summary": "Get double the Talent Level-Up and Weapon Ascension rewards from domains in the return of the Overflowing Abundance event!", "startsAt": "2026-09-14T00:00:00.000Z", "startPrecision": "day", "endsAt": "2026-09-21T00:00:00.000Z", diff --git a/src/ingest/html.ts b/src/ingest/html.ts index 66e53d4..3826929 100644 --- a/src/ingest/html.ts +++ b/src/ingest/html.ts @@ -51,10 +51,22 @@ export interface TableNode { rows: string[][]; } +export interface ParagraphNode { + kind: "p"; + text: string; + /** + * True when the paragraph is really a call-to-action link rather than prose. + * Game8 wraps its "… Event Guide" buttons in the same paragraph class as body + * copy, so callers need to tell them apart. + */ + isButton: boolean; +} + export type DocNode = | { kind: "h2"; text: string } | { kind: "h3"; text: string } - | TableNode; + | TableNode + | ParagraphNode; /** * Walk a document in source order, yielding h2/h3 headings and tables. @@ -66,16 +78,19 @@ export function scanDocument(rawHtml: string): DocNode[] { const html = rawHtml.replace(//g, "").replace(/\s+/g, " "); const nodes: DocNode[] = []; - const re = /