Repository navigation
fix(calendar): read CDATA timezone and description - #45
Merged
Merged
Conversation
fetchCalendars kept calendar-timezone and calendar-description only
when xml-js returned a plain string. Servers that wrap the value in
CDATA produce { _cdata } (or { _text }), so the timezone was silently
returned as "". Use getDAVText, which displayName, ctag and syncToken
already use, so every text shape is read the same way.
Closes #44
PhilflowIO
added a commit
to PhilflowIO/dav-mcp
that referenced
this pull request
Oct 9, 2026
Review of #135 found that the calendar-timezone property was read as if it were always present, small and well-formed, and that some writes could be stored an hour off without saying so. Reading: every value goes through one reader (calendar-zone.js), whatever form tsdav hands it in. tsdav up to 2.4 drops a CDATA calendar-timezone from `timezone` (fixed in PhilflowIO/tsdav#45), so fetchCalendars now projects the raw property and the listing tools, create_event and the update_calendar read-back read the same value the PROPFIND paths do. The value is capped at 64 KB (4.5 MB of RDATE lines took 4.5 s), parsed through the parameter guard of ical-parse.js, and its parse is cached by text, like the zones built from it. A VTIMEZONE without rules is read by its IANA name instead of as UTC. Failures: a lookup that fails (no answer, an error status, an unreadable value) is no longer a silent fallback. A read goes ahead in dav-mcp's zone and says so in a note; a write that needs the zone is refused, since a floating series moved with Z, or a time without a zone, would otherwise land on dav-mcp's clock unsaid. A calendar without the property, or a 404, still simply has no zone. DST: a write that the zone's clock change makes impossible or ambiguous is refused with what to give instead: a local time the spring change skips, one the autumn change shows twice given without an offset, and an instant in the second pass of that hour for an event stored without a zone (it would read back as the first, or the event shorter). Also: every IANA zone can be set; Africa/Monrovia, on local mean time until 1972, made generateVtimezone throw an internal error, so its VTIMEZONE starts at the first year that can be written (all 418 zones Intl knows checked once). update_calendar reports a calendar missing from the listing as not found. The "no occurrence falls inside" note could no longer be reached since the tools filter ranges themselves, so it goes. Refs #78, #117, #128 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…-cdata # Conflicts: # dist/tsdav.min.cjs # dist/tsdav.min.js # dist/tsdav.min.mjs
Merged
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
fetchCalendarsnow readscalendar-timezoneandcalendar-descriptionthroughgetDAVText, the same helper already used fordisplayName,ctagandsyncToken.Why
Both values were kept only when xml-js returned a plain string. A server that sends the VCALENDAR inside CDATA (
<c:calendar-timezone><![CDATA[BEGIN:VCALENDAR...]]></c:calendar-timezone>) produces{ _cdata: "..." }, so the timezone came back as""without any error. Missing or empty values still return"".Tests
New unit tests in
src/__tests__/unit/calendar.test.tscover plain text, CDATA,_textand missing values. The CDATA and_textcases failed before the fix.pnpm test(430 passed),pnpm typecheckandpnpm lintare green.Closes #44