From b14b8188fe47ccbf6318ce3265953151a61e51cf Mon Sep 17 00:00:00 2001 From: Uwe Schuster Date: Tue, 21 Apr 2026 22:33:01 +0200 Subject: [PATCH] v0.3.5: readBody tries .json() without clone() first MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some test mocks expose .json() but not .clone() — cloning throws on object mocks. Try .json() directly, fall back to .text(). Real Response objects are unaffected (calling .json() twice would throw, but we only call it once since we're on the error path). --- package.json | 2 +- src/core-fetch.ts | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 159bbd2..501265a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@uschuster/webapp-scaffold", - "version": "0.3.4", + "version": "0.3.5", "description": "Shared build scripts + Vite config factories for webapp-template-derived projects.", "type": "module", "bin": { diff --git a/src/core-fetch.ts b/src/core-fetch.ts index a165531..f7c9da8 100644 --- a/src/core-fetch.ts +++ b/src/core-fetch.ts @@ -191,12 +191,18 @@ function safeJson(text: string): unknown | null { * JSON (may be null when the body isn't parseable). */ async function readBody(r: Response): Promise<[string, unknown | null]> { + // Some mocks expose .json() but not .clone() (e.g. vitest object mocks). + // Try .json() directly; if it throws, fall back to .text(). try { - const j = await r.clone().json(); + const j = await r.json(); return [JSON.stringify(j), j]; } catch { - const text = await r.text().catch(() => ''); - return [text, safeJson(text)]; + try { + const text = await r.text(); + return [text, safeJson(text)]; + } catch { + return ['', null]; + } } }