feat: Field-based updates for CalDAV/CardDAV #4

Merged
PhilflowIO merged 11 commits from feature/field-based-updates into master 2025-10-25 20:30:10 +00:00
PhilflowIO commented 2025-10-25 18:38:34 +00:00 (Migrated from github.com)

Field-Based Updates for CalDAV/CardDAV

Implements field-based update API for calendar events, todos, and vCards - solving the problem of requiring full iCalendar string generation for simple field updates.

Problem Solved

Previously, updating a calendar event required generating complete 500+ line iCalendar strings with proper timezone definitions, encoding, and structure. This was:

  • Complex and error-prone
  • Created issues with duplicate VTIMEZONE blocks, missing END tags, incorrect line folding
  • Difficult for AI/LLM integrations
  • Unnecessary overhead for simple field changes

Solution

New field-based update functions that handle iCal generation internally:

Calendar Events (VEVENT)

import { updateEventFields } from 'tsdav/util/calendarFieldUpdater';

const result = updateEventFields(calendarObject, {
  SUMMARY: 'Updated Meeting Title',
  DESCRIPTION: 'New detailed description'
});

Todos (VTODO)

import { updateTodoFields } from 'tsdav/util/todoFieldUpdater';

updateTodoFields(calendarObject, {
  SUMMARY: 'Complete documentation',
  DESCRIPTION: 'Write comprehensive API docs'
});

vCards (CardDAV)

import { updateVCardFields } from 'tsdav/util/vCardFieldUpdater';

updateVCardFields(vCard, {
  FN: 'Dr. John Q. Public, Esq.',
  EMAIL: 'john@example.com',
  TEL: '+1-555-555-5555'
});

Features

  • Simple API: Plain JavaScript objects instead of iCal strings
  • RFC Compliant: RFC 5545 (iCalendar), RFC 6350 (vCard)
  • Auto-update: SEQUENCE auto-increment, DTSTAMP/REV timestamp updates
  • Preservation: VTIMEZONE, vendor extensions (X-* properties)
  • Type Safe: TypeScript definitions with strict mode compliance
  • Backwards Compatible: Existing API unchanged, opt-in feature
  • Zero Bundle Impact: Tree-shaking excludes unused code

Tests

  • 156 unit tests (all passing)
  • 96.39% code coverage
  • Integration test with real Baikal CalDAV server

Test Breakdown

  • fieldUpdater.ts: 30 tests (96.34% coverage)
  • calendarFieldUpdater.ts: 45 tests (98.78% coverage)
  • todoFieldUpdater.ts: 47 tests (98.85% coverage)
  • vCardFieldUpdater.ts: 34 tests (92.72% coverage)

Benefits

Before

// ❌ 500+ lines of manual iCal generation
await client.updateCalendarObject({
  calendarObject: {
    url: eventUrl,
    etag: eventEtag,
    data: "BEGIN:VCALENDAR\nVERSION:2.0\n..." // 😱
  }
});

After

// ✅ 3 lines with automatic iCal handling
const result = updateEventFields(event, {
  SUMMARY: 'Updated Title'
});

await client.updateCalendarObject({
  calendarObject: { ...event, data: result.data }
});

Status

Production Ready
156 tests passed, 0 failed
96.39% coverage
TypeScript strict mode (0 errors)
Integration tested with Baikal CalDAV

# Field-Based Updates for CalDAV/CardDAV Implements field-based update API for calendar events, todos, and vCards - solving the problem of requiring full iCalendar string generation for simple field updates. ## Problem Solved Previously, updating a calendar event required generating complete 500+ line iCalendar strings with proper timezone definitions, encoding, and structure. This was: - Complex and error-prone - Created issues with duplicate VTIMEZONE blocks, missing END tags, incorrect line folding - Difficult for AI/LLM integrations - Unnecessary overhead for simple field changes ## Solution New field-based update functions that handle iCal generation internally: ### Calendar Events (VEVENT) ```typescript import { updateEventFields } from 'tsdav/util/calendarFieldUpdater'; const result = updateEventFields(calendarObject, { SUMMARY: 'Updated Meeting Title', DESCRIPTION: 'New detailed description' }); ``` ### Todos (VTODO) ```typescript import { updateTodoFields } from 'tsdav/util/todoFieldUpdater'; updateTodoFields(calendarObject, { SUMMARY: 'Complete documentation', DESCRIPTION: 'Write comprehensive API docs' }); ``` ### vCards (CardDAV) ```typescript import { updateVCardFields } from 'tsdav/util/vCardFieldUpdater'; updateVCardFields(vCard, { FN: 'Dr. John Q. Public, Esq.', EMAIL: 'john@example.com', TEL: '+1-555-555-5555' }); ``` ## Features - ✅ Simple API: Plain JavaScript objects instead of iCal strings - ✅ RFC Compliant: RFC 5545 (iCalendar), RFC 6350 (vCard) - ✅ Auto-update: SEQUENCE auto-increment, DTSTAMP/REV timestamp updates - ✅ Preservation: VTIMEZONE, vendor extensions (X-* properties) - ✅ Type Safe: TypeScript definitions with strict mode compliance - ✅ Backwards Compatible: Existing API unchanged, opt-in feature - ✅ Zero Bundle Impact: Tree-shaking excludes unused code ## Tests - **156 unit tests** (all passing) - **96.39% code coverage** - **Integration test** with real Baikal CalDAV server ### Test Breakdown - fieldUpdater.ts: 30 tests (96.34% coverage) - calendarFieldUpdater.ts: 45 tests (98.78% coverage) - todoFieldUpdater.ts: 47 tests (98.85% coverage) - vCardFieldUpdater.ts: 34 tests (92.72% coverage) ## Benefits ### Before ```javascript // ❌ 500+ lines of manual iCal generation await client.updateCalendarObject({ calendarObject: { url: eventUrl, etag: eventEtag, data: "BEGIN:VCALENDAR\nVERSION:2.0\n..." // 😱 } }); ``` ### After ```javascript // ✅ 3 lines with automatic iCal handling const result = updateEventFields(event, { SUMMARY: 'Updated Title' }); await client.updateCalendarObject({ calendarObject: { ...event, data: result.data } }); ``` ## Status ✅ Production Ready ✅ 156 tests passed, 0 failed ✅ 96.39% coverage ✅ TypeScript strict mode (0 errors) ✅ Integration tested with Baikal CalDAV
Sign in to join this conversation.
No description provided.