feat(web): downloadFile.ts enhancements (downloadBlob, fileNameFromUri, isHttpUrl)#1586
Conversation
|
@claude review |
|
Claude finished @cliffhall's task in 53s —— View job Code Review:
|
|
📋 Smoke test & AGENTS.md audit for this PR: #1560 (comment) (posted on the linked issue #1560). |
…ase change; tree unchanged)
Closes #1560
Wave 1 of the #1579 decomposition (re-implementing PR #1510 as scoped issues). Generalizes
clients/web/src/lib/downloadFile.tsbeyond JSON so the Apps host'sui/download-filesupport (a later issue) can download arbitrary embedded resources and open http(s) resource links safely. No UI wiring in this change.What changed
downloadBlob(filename, blob)— the temp-anchor download core, with asetTimeout(..., 0)-deferredURL.revokeObjectURL()so a synchronous revoke can't abort the scheduled download (Firefox/Safari, intermittently Chrome for larger blobs).downloadJsonFile(filename, json)— refactored on top ofdownloadBlob; existing callers (App.tsx) are unchanged.fileNameFromUri(uri)— derives a safe filename from a resource URI's last path segment: strips control/format chars, replaces disallowed filename chars with_, caps at 255 chars, falls back to"download".isHttpUrl(url)— parses and returns theURLonly forhttp:/https:schemes, elsenull(shared allowlist for opening/downloading server-supplied URLs).Tests & coverage
downloadFile.test.ts: deferred-revoke assertions via fake timers, adownloadBlobpassthrough/type case, andfileNameFromUri/isHttpUrlcoverage (backslash splitting, control-char stripping, 255-char truncation, scheme rejection).downloadFile.ts: 100% statements / functions / lines, 92.3% branches — all four dimensions ≥90.cd clients/web && npm run test:coveragepasses (exit 0, 3245 tests); the per-file gate holds.Scope
Only
clients/web/src/lib/downloadFile.ts(+ its test) — no other Wave 1 files touched.🤖 Generated with Claude Code
https://claude.ai/code/session_01S3fTN8H3R8YV4yUGvZjYnX