Skip to content

fix(caldav): honour fetch override in todo API - #32

Merged
PhilflowIO merged 2 commits into
masterfrom
fix/todo-fetch-override
Aug 14, 2026
Merged

fix(caldav): honour fetch override in todo API#32
PhilflowIO merged 2 commits into
masterfrom
fix/todo-fetch-override

Conversation

@PhilflowIO

Copy link
Copy Markdown
Owner

The follow-up identified in #31. This closes the last fetch-override gap in the codebase.

The defect

The todo module was modelled on the calendar one but predates the fetch override and never gained it. All six functions lacked fetch?: typeof fetch, and neither wiring surface forwarded an override to any of them:

  • createDAVClient wired all six as defaultParam(rawTodoQuery, { headers: authHeaders }) — no fetch, unlike every calendar equivalent.
  • DAVClient forwarded this.fetchOverride in 29 methods but in none of the six todo ones.

Unlike makeAddressBook, this was never a type error, because client.ts never attempted to pass fetch. It was silent in both directions — which is why a green typecheck did not surface it.

Matching the calendar reference

Each function now mirrors its counterpart exactly rather than improvising:

todo reference notes
todoQuery calendarQuery collectionQuery
todoMultiGet calendarMultiGet collectionQuery
fetchTodos fetchCalendarObjects override threaded through all three internal calls (initial query, expand query, multiget)
createTodo createCalendarObject createObject
updateTodo updateCalendarObject updateObject
deleteTodo deleteCalendarObject deleteObject

fetchTodos was the one needing care: like fetchCalendarObjects, it calls todoQuery/todoMultiGet internally, so the override has to be passed down or the outer signature is decorative. All three internal call sites now pass it.

The JSDoc gains a @param params.fetch line per function, matching this file's own convention (calendar.ts carries no JSDoc at all).

Both wiring surfaces are done too: six fetch: fetchOverride in createDAVClient, six fetch: this.fetchOverride in the class, written in the same multi-line shape the calendar entries already use.

Verification

A scan for every exported function that takes fetchOptions but not fetch?: typeof fetch is now empty across account, addressBook, calendar, collection, request and todo — it previously returned these six. Likewise every defaultParam in createDAVClient forwards fetchOverride, and every class method forwards this.fetchOverride.

$ pnpm typecheck
> tsc --noEmit
(clean)

$ pnpm test
Test Suites: 10 passed, 10 total
Tests:       42 passed, 42 total

Runtime behaviour change

The override goes from dead to live across the whole todo surface. Consumers who configure a custom fetch previously had every todo request bypass it and go out through the module-level default (native globalThis.fetch, else cross-fetch).

Concretely: on KaiOS with mozSystem, in a Cloudflare Worker, or anywhere the default fetch cannot serve the request, the todo API was entirely unusable — reads and writes both — while calendars and contacts worked, since those already honoured the override. Those consumers can now use VTODOs at all. Anyone not passing a custom fetch is unaffected: fetchOverride is undefined and the request helpers fall back exactly as before, which one test pins down explicitly.

Tests

Ten, and each of the three halves was confirmed to fail on its own when that half is reverted:

  • todo.test.ts (new file, but the existing calendar.test.ts harness — mock ./request only and let the real collectionQuery run through to davRequest): one test per function plus an undefined case. Reverting the todo.ts threading fails 6 of 7; the undefined case still passes.
  • client.test.ts extends the existing "DAVClient fetch override" describe with fetchTodos (which also exercises the internal todoQuery threading) and createTodo. Reverting the class wiring fails the two DAVClient cases while the createDAVClient one still passes; reverting the factory wiring fails only the createDAVClient one.

Side effect worth flagging

pnpm lint drops from 10 pre-existing errors to 4, without --fix being run: six of the ten sat on the exact DAVClient todo lines this PR rewrote into the multi-line form. No new lint errors. The remaining 4 are addressBook.ts:355, client.ts:709, index.ts:63, todo.ts:205 — all pre-existing and untouched here; they belong to the hygiene PR.

The todo module was modelled on the calendar one but predates the fetch
override, and never gained it. All six functions lacked
`fetch?: typeof fetch`, and neither createDAVClient nor the DAVClient
class forwarded an override to any of them -- the only remaining gap
after makeAddressBook, and silent rather than red because client.ts
never attempted to pass it.

Each function now matches its calendar counterpart exactly: todoQuery
and todoMultiGet mirror calendarQuery and calendarMultiGet, fetchTodos
mirrors fetchCalendarObjects including threading the override through
its internal query and multiget calls, and the write trio mirrors
create/update/deleteCalendarObject.

Consumers on a platform that needs a custom fetch -- KaiOS mozSystem, a
Cloudflare Worker, any environment the default cross-fetch cannot serve
-- can now read and write VTODOs at all. Before, every todo request
bypassed their fetch, so the whole todo surface was unusable there while
calendars and contacts worked.
Ten tests across three independently reverted halves.

todo.test.ts follows calendar.test.ts: mock ./request only, let the real
collectionQuery run through to davRequest, and assert each of the six
functions forwards the override -- plus that it stays undefined when
none is given. Reverting the todo.ts threading fails six of the seven.

client.test.ts extends the existing fetch-override describe with
fetchTodos and createTodo. Reverting the class wiring fails the two
DAVClient cases while the createDAVClient one still passes; reverting
the factory wiring fails only the createDAVClient one.
@PhilflowIO
PhilflowIO merged commit 2ab5372 into master Aug 14, 2026
1 check passed
@PhilflowIO
PhilflowIO deleted the fix/todo-fetch-override branch August 14, 2026 20:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant