diff --git a/icalendar.ts b/icalendar.ts index 3f3560f..f54a2c9 100644 --- a/icalendar.ts +++ b/icalendar.ts @@ -30,15 +30,25 @@ const RRULE_KEY_MAP: Record = { }; /** - * Formats an RRULE value for the string representation. - * Specifically handles Date objects and nested date objects from ts-ics. + * Robustly formats an RRULE value for its string representation. + * Handles: + * - Arrays: joins elements with commas (recursive) + * - Date objects: formats as YYYYMMDDTHHMMSSZ + * - Objects: extracts .date, .day, or .value properties (recursive) + * - Primitives: stringifies directly */ function formatRRuleValue(v: any): string { + if (Array.isArray(v)) { + return v.map((item) => formatRRuleValue(item)).join(","); + } if (v instanceof Date) { return v.toISOString().replace(/[-:]/g, "").split(".")[0] + "Z"; } - if (typeof v === "object" && v !== null && v.date instanceof Date) { - return v.date.toISOString().replace(/[-:]/g, "").split(".")[0] + "Z"; + if (typeof v === "object" && v !== null) { + const val = v.date || v.day || v.value; + if (val !== undefined) { + return formatRRuleValue(val); + } } return String(v); } diff --git a/icalendar_test.ts b/icalendar_test.ts index 5707e11..cec9c10 100644 --- a/icalendar_test.ts +++ b/icalendar_test.ts @@ -226,7 +226,7 @@ Deno.test("expandRecurrences - object rrule with until", () => { }); -Deno.test("expandRecurrences - object rrule with byday (Reproduction)", () => { +Deno.test("expandRecurrences - object rrule with byday", () => { const now = new Date(); const start = new Date(now.getTime() - 10 * 86400000); const startStr = localDateString(start); @@ -237,22 +237,9 @@ Deno.test("expandRecurrences - object rrule with byday (Reproduction)", () => { rrule: { frequency: "WEEKLY", byday: [{ day: "MO" }, { day: "WE" }] } }; - // Spy on console.error - let errorLogged = false; - const originalConsoleError = console.error; - console.error = (...args) => { - if (args[0].includes("Error expanding recurrence for Object RRULE BYDAY Event") && - args[1].message.includes("Invalid weekday string: [object Object]")) { - errorLogged = true; - } - }; - - try { - expandRecurrences(icsEvent, 30); - } finally { - console.error = originalConsoleError; - } - - assert(errorLogged, "Should have logged an error for invalid BYDAY object values"); + const results = expandRecurrences(icsEvent, 30); + // Should now return multiple occurrences + assert(results.length > 1, `Expected > 1 occurrences, got ${results.length}`); + assertEquals(results[0].recurrent, true); });