fix: preserve VALUE=DATE in DTSTART for RRULE parsing#432
fix: preserve VALUE=DATE in DTSTART for RRULE parsing#432jens-maus merged 1 commit intojens-maus:masterfrom
Conversation
📝 WalkthroughWalkthroughAdds explicit handling for date-only (VALUE=DATE) VEVENTs in RRULE/DTSTART construction, emitting a local YYYYMMDD DTSTART for date-only events and adjusting RRULE assembly; includes new tests validating DATE-only RRULE parsing, UNTIL handling, and RRULE string generation. Changes
Sequence Diagram(s)(No sequence diagrams generated — changes are internal to RRULE/DTSTART formatting and tests and do not introduce multi-component interaction flows that require visualization.) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@ical.js`:
- Around line 748-758: The code appends ";DTSTART;VALUE=DATE:YYYYMMDD" to the
rule string when curr.start.dateOnly is true, but the later filter that builds
rruleOnly only strips segments starting with "DTSTART", leaving an orphaned
"VALUE=DATE:YYYYMMDD" token and producing an invalid RRULE; fix by either not
injecting DTSTART into the rule string (set a separate dtstart variable and
attach it outside the RRULE) or update the filtering that produces rruleOnly to
also remove any standalone "VALUE=DATE:..." segments (e.g., strip segments
matching /^VALUE=DATE:/ or the combined ";VALUE=DATE:..."/"VALUE=DATE:..."),
referencing rule, rruleOnly, and curr.start.dateOnly to locate the change.
When parsing recurring events with VALUE=DATE (all-day events), preserve the VALUE=DATE parameter in the DTSTART string passed to rrule-temporal. This ensures that rrule-temporal can correctly validate that UNTIL values have the same type as DTSTART. Previously, date-only information was lost when building the RRULE string, causing rrule-temporal to incorrectly assume DTSTART was DATE-TIME and reject valid DATE-only UNTIL values with the error: "UNTIL rule part MUST have the same value type as DTSTART" The fix uses local date components (getFullYear, getMonth, getDate) which is consistent with how dateOnly dates are created in the dateParameter function using new Date(year, month, day). Fixes issue reported in MagicMirrorOrg/MagicMirror#4016 where Google Calendar birthday events with yearly RRULE and DATE-only UNTIL in the past failed to parse. Test coverage: - Yearly recurring DATE events with UNTIL - Monthly recurring DATE events with UNTIL - DATE events with COUNT instead of UNTIL - Edge case: VALUE=DATE with TZID (correctly ignores TZID)
ac46ae6 to
55f8419
Compare
|
coderabbit seems to be satisfied here too 😃 @jens-maus, if you have the time, it would be nice if you have a look. |
|
Thanks @KristjanESPERANTO for the reminder and big thanks for this PR and all your efforts. Will of course merge it immediately. |
…al 1.4.2+ PR jens-maus#432 added initial support for VALUE=DATE preservation, but some edge cases still failed with rrule-temporal 1.4.2+ strict RFC5545 validation. Additional fixes: - Strip time component from UNTIL when DTSTART is DATE-only - Ensure UNTIL has UTC 'Z' suffix for DATE-TIME events - Convert non-UTC UNTIL to UTC when DTSTART has TZID - Embed DTSTART;VALUE=DATE in rruleString for proper validation
…al 1.4.2+ PR jens-maus#432 added initial support for VALUE=DATE preservation, but some edge cases still failed with rrule-temporal 1.4.2+ strict RFC5545 validation. Additional fixes: - Strip time component from UNTIL when DTSTART is DATE-only - Ensure UNTIL has UTC 'Z' suffix for DATE-TIME events - Convert non-UTC UNTIL to UTC when DTSTART has TZID - Embed DTSTART;VALUE=DATE in rruleString for proper validation
…al 1.4.2+ (#433) * chore: update rrule-temporal to v1.4.5 * fix: complete UNTIL/DTSTART value type normalization for rrule-temporal 1.4.2+ PR #432 added initial support for VALUE=DATE preservation, but some edge cases still failed with rrule-temporal 1.4.2+ strict RFC5545 validation. Additional fixes: - Strip time component from UNTIL when DTSTART is DATE-only - Ensure UNTIL has UTC 'Z' suffix for DATE-TIME events - Convert non-UTC UNTIL to UTC when DTSTART has TZID - Embed DTSTART;VALUE=DATE in rruleString for proper validation * chore: filter orphaned TZID segments when extracting RRULE string When the internal rule string contains DTSTART;TZID=..., splitting on semicolons produces an orphaned TZID=... segment. This segment is now filtered out along with DTSTART and VALUE= for cleaner RRULE syntax. Note: rrule-temporal tolerates these extra segments, so this is a code quality improvement rather than a bug fix.
Problem
When parsing recurring all-day events (
VALUE=DATE), the date-only information was never passed to the RRULE library. This became visible whenrrule-temporalyesterday added strict RFC 5545 validation (with v1.4.2), causing it to reject DATE-only UNTIL values:Example: Google Calendar birthday events
Both DTSTART and UNTIL are DATE values (correct per RFC 5545), but node-ical didn't preserve
VALUE=DATEwhen passing to rrule-temporal, causing the validation to fail.Solution
Added check for
curr.start.dateOnlyto preserve the VALUE=DATE parameter.Use local date components (not UTC) to stay consistent with how date-only events are parsed.
Testing
Impact
Fixes: Issue reported in MagicMirrorOrg/MagicMirror#4016
Affected: Users parsing recurring all-day events (birthdays, holidays) from Google Calendar and other CalDAV servers
Breaking Changes: None
Summary by CodeRabbit
Bug Fixes
Tests
✏️ Tip: You can customize this high-level summary in your review settings.