fix(carddav): honour fetch override in makeAddressBook - #31
Merged
Conversation
makeAddressBook was the only function in addressBook.ts that neither accepted a `fetch` override nor forwarded one to davRequest, and the only DAVClient method besides the todo family that did not pass this.fetchOverride. Its structural twin makeCalendar does both. createDAVClient has passed `fetch: fetchOverride` to it since the upstream sync, which was a type error (TS2353) and left `pnpm typecheck` red on master. At runtime the property was simply dropped: davRequest fell back to its module-level fetch, so the override was silently dead for this one call. Consumers on a platform that needs a custom fetch -- KaiOS mozSystem, or any environment where the default cross-fetch cannot issue the request -- now get their fetch used when creating an address book, where before the MKCOL quietly went out through the wrong one.
Four tests, each of which fails if its half of the fix is reverted. The addressBook unit tests mock ./request and assert davRequest receives the override, and receives undefined when none is given. The client tests drive a jest.fn() fetch all the way through DAVClient and createDAVClient and assert it was actually called -- the class test fails without the this.fetchOverride wiring, the factory test without the addressBook.ts threading.
This was referenced Aug 14, 2026
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.
Fixes the red
pnpm typecheckon master.The defect
makeAddressBookwas the only function inaddressBook.tsthat neither accepted afetchoverride nor forwarded one todavRequest. I scanned every exported function that takesfetchOptions— it and the six todo functions were the only ones missingfetch?: typeof fetch, and the todo family is untouched here (see follow-ups).Its structural twin
makeCalendardoes both: same params, samedavRequestcall, one MKCALENDAR vs MKCOL. AnddavRequesthas always supported it —const requestFetch = fetchOverride ?? fetch;.Two call sites were affected, and they failed differently:
createDAVClient(client.ts:267) has passedfetch: fetchOverrideto it since the upstream sync. That was the TS2353 error. At runtime the extra property was simply dropped on the floor.DAVClient.makeAddressBook(client.ts:694) never passed it at all — no type error, just silence. The class storesthis.fetchOverrideand forwards it in 28 other methods; this one was skipped.Fixing only the type would have left the class path still broken, so both are fixed. No cast, no ts-ignore —
makeAddressBooknow matchesmakeCalendarexactly.Runtime behaviour change
The override goes from dead to live for
makeAddressBook. Anyone who configures a custom fetch and then creates an address book will see their fetch used where previously the MKCOL went out through the module-level default (nativeglobalThis.fetch, elsecross-fetch).Concretely, for a consumer on KaiOS with
mozSystem, or a Cloudflare Worker, or any environment where the default fetch cannot issue the request:client.makeAddressBook(...)previously bypassed their fetch and the MKCOL typically failed on CORS or privilege. It now succeeds. Anyone not passing a custom fetch is unaffected —fetchOverrideisundefinedanddavRequestfalls back exactly as before, which the second unit test pins down.Verification
Before, on
d411d78:After:
Tests
Four, in the two existing unit suites — no new harness invented. Each was confirmed to fail when its half of the fix is reverted:
addressBook.test.tsmocks../../request(the file's existing pattern) and assertsdavRequestreceives the override, and receivesundefinedwhen none is passed.client.test.tsextends the existing "DAVClient fetch override" describe, driving ajest.fn()fetch through bothDAVClientandcreateDAVClientand asserting it was actually called.Reverting the
addressBook.tsthreading fails the first pair; reverting thethis.fetchOverridewiring fails theDAVClienttest while thecreateDAVClienttest still passes — the two halves are independently guarded.The
dist/diff is generated, and small this time (~64 lines): the repo's pre-commit hook rebuilt and staged it. CI verifies it against a fresh build.Not in this PR
todoQuery,todoMultiGet,fetchTodos,createTodo,updateTodo,deleteTodoall lackfetch?: typeof fetch, and none of the sixDAVClientmethods passthis.fetchOverride. It is not a type error only becauseclient.tsnever tries to pass it, so it is silent rather than red. That is a six-function feature change, not a typecheck fix.pnpm lintis red on master — 10 remaining prettier-only errors inclient.ts,index.ts,todo.tsandaddressBook.ts, all auto-fixable withpnpm lint --fix. All pre-existing: I verified theaddressBook.tsone is present at line 346 on pristine master and merely shifted to 355 by this diff. It went 11 → 10 only because one sat on the line I rewrote. Untouched otherwise to keep this PR single-purpose. It stays red unnoticed becauseci.ymlnever runs (below) andrelease.ymlhas the lint step commented out..husky/pre-commituses the husky v8 preamble; prints DEPRECATED on every commit, will fail on husky v10.ci.ymlonly triggers on PRs tomainwhile the default branch ismaster, sotypecheck/lint/testnever actually run in CI.