-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Context
draft-ietf-calext-jscalendar-icalendar-22 defines two distinct mechanisms for preserving extension properties across the iCalendar↔JSCalendar boundary. Gnomon currently uses a simplified approach (flat x_-prefixed field name mangling) that doesn't match either mechanism and loses information.
Current behaviour
iCalendar import
X-properties like X-CUSTOM-FIELD are translated into flat record fields with name mangling: x_custom_field. Parameters on X-properties are dropped, and the iCalendar VALUE type is inferred but not preserved alongside the field.
iCalendar export
Unrecognized fields are exported as X-properties with the reverse name mangling.
JSCalendar import/export
Vendor properties (e.g. example.com:foo) are preserved as-is in both directions (no mangling needed since JSON keys are used directly).
What the draft specifies
iCalendar → JSCalendar (Section 5.1.1): the iCalendar property
Unknown iCalendar properties and components are preserved in a structured iCalendar property on the JSCalendar object, using jCal format (RFC 7265):
{
"@type": "Event",
"title": "test",
"iCalendar": {
"@type": "ICalComponent",
"name": "vevent",
"properties": [
["x-bar", {}, "unknown", "bam"]
],
"components": [
["x-baz", [["uid", {}, "text", "507A..."]], []]
],
"convertedProperties": {
"title": {
"@type": "ICalProperty",
"name": "summary",
"parameters": { "x-foo": "bar" }
}
}
}
}Key elements:
- Unknown properties →
iCalendar.propertiesas jCal arrays[name, params, type, value] - Unknown components →
iCalendar.componentsas jCal arrays - Unknown parameters on known properties (e.g.
X-FOOonSUMMARY) →iCalendar.convertedProperties, which maps JSCalendar property paths toICalPropertyobjects retaining the original iCalendar property name and parameters
JSCalendar → iCalendar (Section 4.1.2): the JSPROP property
JSCalendar vendor properties are converted to a new iCalendar property JSPROP with a mandatory JSPTR parameter:
JSPROP;JSPTR="example.com:foo":true
JSPROP;JSPTR="example.com:foo":{"bar":1234\,"baz":"bam"}
The value is the JSON-encoded JSCalendar value as TEXT. Multiple JSPROP properties form a PatchObject. JSPTR uses JSON pointer syntax relative to the enclosing JSCalendar object, supporting vendor properties at any nesting depth (inside alerts, links, participants, etc.).
Problems with gnomon's current approach
- Loses type information — the iCalendar VALUE type is not preserved
- Loses parameters — any parameters on X-properties are dropped
- No round-trip fidelity —
x_-mangled names don't survive conversion in either direction (an iCalendar X-property imported and re-exported may not reproduce the original) - Namespace mismatch —
x_custom_fieldis neither a valid JSCalendar vendor property (example.com:customField) nor a faithful iCalendar X-property name (X-CUSTOM-FIELD)
Expected behaviour
iCalendar import
- X-properties and unrecognized IANA properties should be collected into an
iCalendarrecord on the gnomon entry, preserving property name, parameters, and value type per theICalComponentstructure - Unknown parameters on known properties (e.g.
X-FOOonSUMMARY) should be preserved viaconvertedProperties
iCalendar export
- If an entry has an
iCalendar.propertiesfield, those jCal-formatted properties should be emitted as iCalendar properties - JSCalendar vendor properties on gnomon records should be exported as
JSPROP;JSPTR="..."properties convertedPropertiesshould restore unknown parameters onto their corresponding iCalendar properties
JSCalendar import/export
- Vendor properties continue to be preserved as-is (current behaviour is correct here)
- The
iCalendarproperty, if present on a JSCalendar object, should be preserved through import
Scope notes
- This is a breaking change to the import/export format for X-properties
- The
convertedPropertiesmechanism (preserving unknown parameters on known properties) can be deferred to a follow-up if needed — the core value is iniCalendar.propertiesandJSPROP - calico may need upstream changes to expose raw parameters on properties; check what's available before implementing