From 5e018ea2ba26be21e9c44b5cd7d626c47c90045d Mon Sep 17 00:00:00 2001 From: Khafra <42794878+KhafraDev@users.noreply.github.com> Date: Tue, 8 Nov 2022 18:07:24 -0500 Subject: [PATCH 1/2] feat: add static Response.json --- @types/index.d.ts | 1 + @types/index.test-d.ts | 5 +++++ src/response.js | 19 +++++++++++++++++++ test/main.js | 19 +++++++++++++++++++ 4 files changed, 44 insertions(+) diff --git a/@types/index.d.ts b/@types/index.d.ts index 2374801f6..f68dd28e2 100644 --- a/@types/index.d.ts +++ b/@types/index.d.ts @@ -196,6 +196,7 @@ export class Response extends BodyMixin { static error(): Response; static redirect(url: string, status?: number): Response; + static json(data: any, init?: ResponseInit): Response; } export class FetchError extends Error { diff --git a/@types/index.test-d.ts b/@types/index.test-d.ts index 627766599..3272a0e7c 100644 --- a/@types/index.test-d.ts +++ b/@types/index.test-d.ts @@ -93,6 +93,11 @@ async function run() { expectType(Response.redirect('https://google.com')); expectType(Response.redirect('https://google.com', 301)); + + expectType(Response.json({foo: 'bar'})); + expectType(Response.json({foo: 'bar'}, { + status: 301 + })); } run().finally(() => { diff --git a/src/response.js b/src/response.js index 63af26711..0dd918c34 100644 --- a/src/response.js +++ b/src/response.js @@ -124,6 +124,25 @@ export default class Response extends Body { return response; } + static json(data = undefined, init = {}) { + const body = JSON.stringify(data); + + if (body === undefined) { + throw new TypeError('data is not JSON serializable'); + } + + return new Response(body, { + ...init, + headers: { + // If body’s type is non-null and response’s header list does not contain + // `Content-Type`, then append (`Content-Type`, body’s type) to response’s + // header list. + 'Content-Type': 'application/json', + ...init.headers + } + }); + } + get [Symbol.toStringTag]() { return 'Response'; } diff --git a/test/main.js b/test/main.js index ec58f8285..c9bc3ba11 100644 --- a/test/main.js +++ b/test/main.js @@ -2281,6 +2281,25 @@ describe('node-fetch', () => { const res = await fetch(url); expect(res.url).to.equal(`${base}m%C3%B6bius`); }); + + it('static Response.json should work', async () => { + const response = Response.json({foo: 'bar'}); + expect(response.status).to.equal(200); + expect(response.headers.get('content-type')).to.equal('application/json'); + expect(await response.text()).to.equal(JSON.stringify({foo: 'bar'})); + + const response1 = Response.json(null, { + status: 301, + statusText: 'node-fetch', + headers: { + 'Content-Type': 'text/plain' + } + }); + + expect(response1.headers.get('content-type')).to.equal('text/plain'); + expect(response1.status).to.equal(301); + expect(response1.statusText).to.equal('node-fetch'); + }); }); describe('node-fetch using IPv6', () => { From 89480fa5c158696932587e0e836588ca7bedf036 Mon Sep 17 00:00:00 2001 From: Khafra <42794878+KhafraDev@users.noreply.github.com> Date: Wed, 9 Nov 2022 10:05:50 -0500 Subject: [PATCH 2/2] fix: set content-type if it doesn't exist properly --- src/response.js | 14 +++++++------- test/main.js | 8 ++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/response.js b/src/response.js index 0dd918c34..9806c0cba 100644 --- a/src/response.js +++ b/src/response.js @@ -131,15 +131,15 @@ export default class Response extends Body { throw new TypeError('data is not JSON serializable'); } + const headers = new Headers(init && init.headers); + + if (!headers.has('content-type')) { + headers.set('content-type', 'application/json'); + } + return new Response(body, { ...init, - headers: { - // If body’s type is non-null and response’s header list does not contain - // `Content-Type`, then append (`Content-Type`, body’s type) to response’s - // header list. - 'Content-Type': 'application/json', - ...init.headers - } + headers }); } diff --git a/test/main.js b/test/main.js index c9bc3ba11..93e0cee19 100644 --- a/test/main.js +++ b/test/main.js @@ -2299,6 +2299,14 @@ describe('node-fetch', () => { expect(response1.headers.get('content-type')).to.equal('text/plain'); expect(response1.status).to.equal(301); expect(response1.statusText).to.equal('node-fetch'); + + const response2 = Response.json(null, { + headers: { + 'CoNtEnT-TypE': 'text/plain' + } + }); + + expect(response2.headers.get('content-type')).to.equal('text/plain'); }); });