From ea1cc6731917ef4e20dc023eaf32b20cf0682835 Mon Sep 17 00:00:00 2001 From: Tobias Bocanegra Date: Thu, 2 Apr 2026 15:35:18 +0200 Subject: [PATCH] feat: serialize array body to JSON in Request and Response Extend the non-spec plain-object JSON auto-serialization to also cover arrays, so that `new Response([1,2,3])` and `new Request(url, { body: [1,2,3] })` automatically set Content-Type: application/json and serialize the body. Fixes #583 Co-Authored-By: Claude Sonnet 4.6 --- src/fetch/request.js | 4 ++-- src/fetch/response.js | 4 ++-- test/fetch/request.test.js | 20 ++++++++++++++++++++ test/fetch/response.test.js | 10 ++++++++++ 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/fetch/request.js b/src/fetch/request.js index c1e61af..785fd06 100644 --- a/src/fetch/request.js +++ b/src/fetch/request.js @@ -64,8 +64,8 @@ class Request extends Body { } if (!headers.has('content-type')) { - if (isPlainObject(body)) { - // non-spec extension: support plain js object body (JSON serialization) + if (isPlainObject(body) || Array.isArray(body)) { + // non-spec extension: support plain js object/array body (JSON serialization) body = JSON.stringify(body); headers.set('content-type', 'application/json'); } else { diff --git a/src/fetch/response.js b/src/fetch/response.js index 9abd0c4..bcc5be2 100644 --- a/src/fetch/response.js +++ b/src/fetch/response.js @@ -49,8 +49,8 @@ class Response extends Body { } if (respBody !== null && !headers.has('content-type')) { - if (isPlainObject(respBody)) { - // non-spec extension: support plain js object body (JSON serialization) + if (isPlainObject(respBody) || Array.isArray(respBody)) { + // non-spec extension: support plain js object/array body (JSON serialization) respBody = JSON.stringify(respBody); headers.set('content-type', 'application/json'); } else { diff --git a/test/fetch/request.test.js b/test/fetch/request.test.js index e763a56..1540620 100644 --- a/test/fetch/request.test.js +++ b/test/fetch/request.test.js @@ -301,6 +301,26 @@ describe('Request Tests', () => { }); }); + it('should serialize plain object body to JSON', () => { + const method = 'POST'; + const body = { foo: 42 }; + const req = new Request(BASE_URL, { method, body }); + expect(req.headers.get('content-type')).to.equal('application/json'); + return req.json().then((result) => { + expect(result).to.deep.equal(body); + }); + }); + + it('should serialize array body to JSON', () => { + const method = 'POST'; + const body = [1, 2, 3]; + const req = new Request(BASE_URL, { method, body }); + expect(req.headers.get('content-type')).to.equal('application/json'); + return req.json().then((result) => { + expect(result).to.deep.equal(body); + }); + }); + it('wrapping requests preserves init options', () => { const method = 'POST'; const body = { foo: 'bar', baz: { count: 313 } }; diff --git a/test/fetch/response.test.js b/test/fetch/response.test.js index 6ddf909..ed9ab83 100644 --- a/test/fetch/response.test.js +++ b/test/fetch/response.test.js @@ -193,6 +193,16 @@ describe('Response Tests', () => { // plain js object body res = new Response({ foo: 42 }); expect(res.headers.get('content-type')).to.equal('application/json'); + // array body + res = new Response([1, 2, 3]); + expect(res.headers.get('content-type')).to.equal('application/json'); + }); + + it('should serialize array body to JSON', () => { + const res = new Response([1, 2, 3]); + return res.json().then((result) => { + expect(result).to.deep.equal([1, 2, 3]); + }); }); it('should not override content-type header', () => {