From 9ea6f7961e1aaaf9010a8ec1190ebc50d51d325c Mon Sep 17 00:00:00 2001 From: sstent Date: Fri, 20 Feb 2026 13:21:15 -0800 Subject: [PATCH] fix(icalendar): Correctly map verbose RRULE keys to standard iCal keys --- icalendar.ts | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/icalendar.ts b/icalendar.ts index 05f5f12..7729fd6 100644 --- a/icalendar.ts +++ b/icalendar.ts @@ -8,6 +8,27 @@ const CACHE_KEY = "icalendar:lastSync"; console.log(`[iCalendar] Plug script executing at top level (Version ${VERSION})`); +/** + * Mapping of verbose RRULE object keys to standard iCalendar shortened keys. + */ +const RRULE_KEY_MAP: Record = { + "frequency": "FREQ", + "until": "UNTIL", + "count": "COUNT", + "interval": "INTERVAL", + "bysecond": "BYSECOND", + "byminute": "BYMINUTE", + "byhour": "BYHOUR", + "byday": "BYDAY", + "bymonthday": "BYMONTHDAY", + "byyearday": "BYYEARDAY", + "byweekno": "BYWEEKNO", + "bymonth": "BYMONTH", + "bysetpos": "BYSETPOS", + "wkst": "WKST", + "freq": "FREQ", // Just in case +}; + // ============================================================================ // Utility Functions // ============================================================================ @@ -163,7 +184,10 @@ export function expandRecurrences(icsEvent: any, windowDays = 365): any[] { } else if (typeof rruleStr === "object" && rruleStr !== null) { // Handle object rrule (e.g. from ts-ics) by converting back to string cleanRule = Object.entries(rruleStr) - .map(([k, v]) => `${k.toUpperCase()}=${v}`) + .map(([k, v]) => { + const standardKey = RRULE_KEY_MAP[k.toLowerCase()] || k.toUpperCase(); + return `${standardKey}=${v}`; + }) .join(";"); } else { console.warn(`[iCalendar] Invalid rrule type (${typeof rruleStr}) for event "${icsEvent.summary || "Untitled"}". Treating as non-recurring.`);