Last 12 weeks · 21 commits
2 of 6 standards met
Summary The stale-if-error cache expiry check in was inverted, causing stale-if-error caches to \\never expire\\ — they would indefinitely serve stale content regardless of how much time passed. Bug The condition compared: This evaluates to for any positive because is always in the future. The cache entry time is always less than a future timestamp, so stale content is served forever. Fix Changed the comparison (in both and ) to: This correctly checks whether has exceeded the cache entry time plus the stale-if-error window — only serving stale content when the window has not yet elapsed. Test Added a regression test: after advancing time past the stale-if-error window (11s past a 10s ), a network-fault fetch should throw — not serve stale content. The test fails before the fix and passes after.
Summary Multipart uploads fail for files larger than 80 GiB because the part size is hardcoded to 8 MiB, and the Vercel Blob API enforces a maximum of 10,000 parts per upload (8 MiB × 10,000 = 80 GiB). This contradicts the advertised 5 TB support for multipart uploads. The fix scales the part size up for bodies with a known size above 80 GiB so the part count always stays at or under 10,000, e.g. a 100 GiB body now uploads with ~10.2 MiB parts instead of failing at part 10,001. Changes Added : returns the 8 MiB default for bodies at or under 80 GiB, otherwise . now derives the part size from instead of the module-level constant. Decoupled the read-ahead memory bound () from the part size. It previously scaled with the part size (2 parts × concurrency), which would buffer gigabytes for the larger part sizes now used on big uploads; it stays at the previous 128 MiB ceiling. — new tests: keeps 8 MiB at/under the 80 GiB ceiling. Part size scales above 80 GiB and keeps the part count ≤ 10,000 (including for a 5 TiB body). An upload above 80 GiB produces one scaled part instead of many 8 MiB parts. Small bodies still split into 8 MiB parts (no regression). Bodies with an unknown size (streams) keep the 8 MiB default, since the total length isn't known upfront. Tests — 6 suites, 176 tests, 20 snapshots ✅ — 1 suite, 1 test, 2 snapshots ✅ — 3 suites, 19 tests, 3 snapshots ✅ Fixes #1067
Summary Raises the dependency floor for from to . The previous range () still resolves versions affected by CVE-2026-12151 (GHSA-vxpw-j846-p89q), a request-smuggling vulnerability in undici. Pinning the floor to guarantees any install of pulls a patched undici, without forcing a breaking major upgrade. Changes : → : synced via — now resolves (undici-only diff) Tests All three test environments pass on : — 6 suites, 172 tests, 20 snapshots ✅ — 1 suite, 1 test, 2 snapshots ✅ — 3 suites, 19 tests, 3 snapshots ✅ Fixes #1090
Problem Image optimization currently has two split SDK surfaces: an option on (body sources) and a separate function (URL sources). Callers have to pick the right one for their source kind, and the CLI's new command (vercel/vercel-internal#184) mirrors that split internally. Solution Add a single method: The source can be the image content itself (string, File, Blob, Buffer or Stream) or a instance pointing at a public http(s) image, which is fetched server-side ( picks the path; strings are always body content, and non-http(s) URLs are rejected). Only the optimized output is stored. Options are shared with — , , , , , auth options — but not : the stored content type always comes from the optimizer output and the source format is detected from the bytes, so it is excluded from the type entirely (a Blob/File .type still fails fast for non-image sources) — plus the required parameters (, , ), mirroring . is intentionally not part of the surface (optimization cannot use it). is guarded at runtime so an untyped caller omitting it fails loudly instead of falling through to a regular unoptimized put. Deprecates the option on and the function via JSDoc pointing at ; both keep working unchanged. is a standalone implementation: it talks to and directly through the shared low-level helpers (, , , ) and has no dependency on the deprecated function or 's branch. Tests assert the exact request paths, headers, and bodies, so wire behavior is identical to the current surfaces. 🤖 Generated with Claude Code
What SDK support for storing optimized images: → (body streamed through the optimizer, optimized output stored) → (optimizer fetches the source URL server-side) Notes : — short format names map to MIME types on the wire. Options are validated client-side (width integer 1–3840, quality integer 1–100, format enum), mirroring the server limits so bad values fail fast with a descriptive instead of a billed round trip. Clearly non-image sources are rejected client-side when a signal exists ( option or a / ); otherwise the server detects the format from the bytes. OIDC-only (the API rejects other token types with a clear 403). + throws. Stored comes from the optimizer output — and the stored pathname extension is rewritten server-side to match it (vercel/api#83451). Requires the corresponding Blob API support to be deployed first; do not merge until it is. Tests cover both new paths (), including validation errors, content-type rejection, forwarding, and the multipart conflict. 🤖 Generated with Claude Code
Repository: vercel/storage. Description: Vercel Storage - Blob and Edge Config Stars: 594, Forks: 99. Primary language: TypeScript. Languages: TypeScript (99.1%), JavaScript (0.8%), CSS (0.2%). License: Apache-2.0. Homepage: https://vercel.com/docs/storage Topics: blob, config, edge, edge-config, serverless. Latest release: @vercel/blob@2.8.0 (4h ago). Open PRs: 22, open issues: 44. Last activity: 4h ago. Community health: 50%. Top contributors: renovate[bot], github-actions[bot], vvo, dferber90, luismeyer, correttojs, AndyBitz, falcoagustin, elliott-with-the-longest-name-on-github, lukahartwig and others.