A tiny web framework for Gleam targeting all JavaScript runtimes
0

Configure Feed

Select the types of activity you want to include in your feed.

:bug: fix cloudflare workers multipart bodies

+17 -2
+4
CHANGELOG.md
··· 1 1 # Changelog 2 2 3 + ## [v2.2.1] - 2026-06-29 4 + 5 + - Added a fallback for Cloudflare workers `writeFile` compatibility. 6 + 3 7 ## [v2.2.0] - 2026-06-28 4 8 5 9 ### Added
+1 -1
gleam.toml
··· 1 1 name = "smol" 2 - version = "2.2.0" 2 + version = "2.2.1" 3 3 target = "javascript" 4 4 gleam = ">= 1.16.0" 5 5
+12 -1
src/smol.ffi.mjs
··· 62 62 } else if (typeof globalThis.Deno !== "undefined") { 63 63 runtimeResult = Result$Ok(Runtime$Deno()); 64 64 } else if (globalThis.process?.versions?.node) { 65 + // TODO: Cloudflare Workers with nodejs_compat are detected here as Node. 65 66 runtimeResult = Result$Ok(Runtime$Node()); 66 67 } else { 67 68 runtimeResult = Result$Error(undefined); ··· 157 158 // -- BODY --------------------------------------------------------------------- 158 159 159 160 const bodyTooLarge = Symbol("smolBodyTooLarge"); 161 + const isCloudflareWorkers = 162 + globalThis.navigator?.userAgent === "Cloudflare-Workers"; 160 163 161 164 export async function read(request, max_body_limit) { 162 165 try { ··· 196 199 197 200 uploadDir ??= await mkdtemp(join(tmpdir(), "smol-upload-")); 198 201 const path = join(uploadDir, `upload-${files.length}`); 199 - await writeFile(path, value.stream()); 202 + await writeUploadedBlob(path, value); 200 203 files.push([name, UploadedFile$UploadedFile(value.name ?? "", path)]); 201 204 } 202 205 } ··· 208 211 if (uploadDir) { 209 212 await rm(uploadDir, { recursive: true, force: true }).catch((_) => {}); 210 213 } 214 + } 215 + } 216 + 217 + async function writeUploadedBlob(path, value) { 218 + if (isCloudflareWorkers) { 219 + await writeFile(path, await value.bytes()); 220 + } else { 221 + await writeFile(path, value.stream()); 211 222 } 212 223 } 213 224