From e1e31cef2070051175b646ca3b355076d06ef2ed Mon Sep 17 00:00:00 2001 From: mARTin Date: Tue, 24 Mar 2026 22:27:35 +0100 Subject: [PATCH] fix: use updateCalendarObject instead of updateObject for CalDAV updates iCloud returned 501 Not Implemented for updateObject calls. Switch to updateCalendarObject which properly sends CalDAV PUT requests. Fixed in both Apple Calendar and Synology Calendar update + recurring delete paths. v1.71.1 Co-Authored-By: Claude Opus 4.6 --- package.json | 2 +- src/lib/apple-calendar.ts | 47 +++++++++++++----------------------- src/lib/synology-calendar.ts | 23 ++++++++++-------- 3 files changed, 31 insertions(+), 41 deletions(-) diff --git a/package.json b/package.json index d6d03b1..69443f5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "my-weekly-todo-list", - "version": "1.71.0", + "version": "1.71.1", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "main": "index.js", "scripts": { diff --git a/src/lib/apple-calendar.ts b/src/lib/apple-calendar.ts index 2c28fb4..756f4fa 100644 --- a/src/lib/apple-calendar.ts +++ b/src/lib/apple-calendar.ts @@ -818,32 +818,17 @@ export const updateEvent = async ( const updatedIcalString = comp.toString(); console.log('[APPLE CALENDAR] Updating event with iCal:', updatedIcalString); - // tsdav types might be slightly off in the d.ts compared to usage or we need to check the actual signature - // In d.ts: updateCalendarObject(params: { calendarObject: DAVCalendarObject ... }) -> Promise - // But it doesn't seem to take 'data' in the d.ts signature shown earlier? - // Wait, let's look at d.ts again. - // updateCalendarObject: (params: { calendarObject: ..., headers?: ... }) - // It DOES NOT show `data` or `etag` in the params in the d.ts signature shown earlier? - // Let's check line 117 of d.ts: - // updateCalendarObject: (params: { calendarObject: ... }) - // This implies the data must be SET on the calendarObject before calling? - // OR the d.ts is incomplete/wrong. + // Use updateCalendarObject with the modified calendar object + const updateResult = await client.updateCalendarObject({ + calendarObject: { + ...targetObject, + data: updatedIcalString, + }, + }); - // Let's assume we need to update the object locally then call update? - // Or maybe we use the `davRequest` or `updateObject` lower level if `updateCalendarObject` limits us. - // Actually, `updateObject` takes `url`, `data`, `etag`. - - // Let's try using `client.updateObject` directly which is more raw but allows data. - // `targetObject.url` is what we need. - - const updateResult = await client.updateObject({ - url: targetObject.url, - data: updatedIcalString, - etag: targetObject.etag - } as any); // Cast to any to bypass type definition mismatch - - // Log result for debugging - if (updateResult && (updateResult as any).status && (updateResult as any).status >= 400) { + // Check for errors in the response + const status = (updateResult as any)?.status || (updateResult as any)?.ok; + if (updateResult && typeof (updateResult as any).status === 'number' && (updateResult as any).status >= 400) { console.error('[APPLE CALENDAR] Update failed with status:', (updateResult as any).status); throw new Error(`CalDAV update failed with status ${(updateResult as any).status}`); } @@ -1032,11 +1017,13 @@ export const deleteRecurringInstance = async ( // PUT the modified object back const updatedData = comp.toString(); - await client.updateObject({ - url: objectUrl, - data: updatedData, - etag: targetObject.etag, - } as any); + await client.updateCalendarObject({ + calendarObject: { + ...targetObject, + url: objectUrl, + data: updatedData, + }, + }); console.log('[APPLE CALENDAR] Recurring instance delete complete (mode:', deleteMode, ')'); diff --git a/src/lib/synology-calendar.ts b/src/lib/synology-calendar.ts index 5aabc72..76a4ff1 100644 --- a/src/lib/synology-calendar.ts +++ b/src/lib/synology-calendar.ts @@ -820,11 +820,12 @@ export const updateEvent = async ( const updatedIcalString = comp.toString(); console.log('[SYNOLOGY CALENDAR] Updating event with iCal:', updatedIcalString); - await client.updateObject({ - url: targetObject.url, - data: updatedIcalString, - etag: targetObject.etag - } as any); + await client.updateCalendarObject({ + calendarObject: { + ...targetObject, + data: updatedIcalString, + }, + }); return { id: eventId, @@ -994,11 +995,13 @@ export const deleteRecurringInstance = async ( // PUT the modified object back const updatedData = comp.toString(); - await client.updateObject({ - url: objectUrl, - data: updatedData, - etag: targetObject.etag, - } as any); + await client.updateCalendarObject({ + calendarObject: { + ...targetObject, + url: objectUrl, + data: updatedData, + }, + }); console.log('[SYNOLOGY CALENDAR] Recurring instance delete complete (mode:', deleteMode, ')');