From 6051cf596a738dd04709fb5a7c36aa656f40599c Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Wed, 25 May 2022 15:35:34 -0600 Subject: [PATCH 1/5] feat: add Response.json static method Signed-off-by: Logan McAnsh --- packages/fetch/src/response.js | 21 +++++++++++++++++++-- packages/fetch/test/response.js | 15 +++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/packages/fetch/src/response.js b/packages/fetch/src/response.js index ebeba7c2..917efc0a 100644 --- a/packages/fetch/src/response.js +++ b/packages/fetch/src/response.js @@ -12,13 +12,13 @@ const INTERNALS = Symbol('Response internals'); /** * Response class - * + * * @typedef {Object} Ext * @property {number} [size] * @property {string} [url] * @property {number} [counter] * @property {number} [highWaterMark] - * + * * @implements {globalThis.Response} */ export default class Response extends Body { @@ -126,6 +126,23 @@ export default class Response extends Body { }); } + /** + * @param {any} data The URL that the new response is to originate from. + * @param {ResponseInit} [responseInit] An optional status code for the response (e.g., 302.) + * @returns {Response} A Response object. + */ + static json(data, responseInit = {}) { + let headers = new Headers(responseInit.headers); + if (!headers.has("Content-Type")) { + headers.set("Content-Type", "application/json; charset=utf-8"); + } + + return new Response(JSON.stringify(data), { + ...responseInit, + headers, + }); + } + get [Symbol.toStringTag]() { return 'Response'; } diff --git a/packages/fetch/test/response.js b/packages/fetch/test/response.js index b4c2957d..8074587a 100644 --- a/packages/fetch/test/response.js +++ b/packages/fetch/test/response.js @@ -220,6 +220,21 @@ describe('Response', () => { const res = new Response(); expect(res.url).to.equal(''); }); + + it('should support json static method', () => { + const res = Response.json({a: 1}); + return res.json().then(result => { + expect(result.a).to.equal(1); + }); + }) + + it('should support json static method with added responseInit', () => { + const res = Response.json({a: 1}, { headers: { "x-foo": "bar" } }); + expect(res.headers.get('x-foo')).to.equal('bar'); + return res.json().then(result => { + expect(result.a).to.equal(1); + }); + }) }); const streamFromString = text => new ReadableStream({ From e120b80ed013e4402b1b32db3d3e6f3f30908ecb Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Wed, 25 May 2022 15:38:30 -0600 Subject: [PATCH 2/5] chore: add changeset Signed-off-by: Logan McAnsh --- .changeset/big-hounds-sniff.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/big-hounds-sniff.md diff --git a/.changeset/big-hounds-sniff.md b/.changeset/big-hounds-sniff.md new file mode 100644 index 00000000..87400f36 --- /dev/null +++ b/.changeset/big-hounds-sniff.md @@ -0,0 +1,5 @@ +--- +"@remix-run/web-fetch": patch +--- + +add Response.json static method From 5e52964b9fd0d4a96b052fc434d6d0ddeb4c2fb9 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Mon, 6 Nov 2023 18:06:58 -0500 Subject: [PATCH 3/5] chore: make Response.json generic Signed-off-by: Logan McAnsh --- packages/fetch/src/response.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/fetch/src/response.js b/packages/fetch/src/response.js index 917efc0a..ff8aa1e7 100644 --- a/packages/fetch/src/response.js +++ b/packages/fetch/src/response.js @@ -127,9 +127,10 @@ export default class Response extends Body { } /** - * @param {any} data The URL that the new response is to originate from. + * @template {unknown} Data + * @param {Data} data The URL that the new response is to originate from. * @param {ResponseInit} [responseInit] An optional status code for the response (e.g., 302.) - * @returns {Response} A Response object. + * @returns {Promise} A Response object. */ static json(data, responseInit = {}) { let headers = new Headers(responseInit.headers); From 2f724270a9f7b87ceabdc90d6b254a3967078a48 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Mon, 6 Nov 2023 18:24:45 -0500 Subject: [PATCH 4/5] chore: add TypedResponse generic Signed-off-by: Logan McAnsh --- packages/fetch/src/response.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/fetch/src/response.js b/packages/fetch/src/response.js index ff8aa1e7..94e35edc 100644 --- a/packages/fetch/src/response.js +++ b/packages/fetch/src/response.js @@ -128,9 +128,9 @@ export default class Response extends Body { /** * @template {unknown} Data - * @param {Data} data The URL that the new response is to originate from. + * @param {Data} data The data to be converted into a JSON string. * @param {ResponseInit} [responseInit] An optional status code for the response (e.g., 302.) - * @returns {Promise} A Response object. + * @returns {TypedResponse} A Response object. */ static json(data, responseInit = {}) { let headers = new Headers(responseInit.headers); @@ -159,3 +159,9 @@ Object.defineProperties(Response.prototype, { clone: {enumerable: true} }); +/** + * @typedef {Omit & { + * json(): Promise; + * }} TypedResponse + * @template T + */ From 857eec95c7127e42dba641a6ac05d73df8378769 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Mon, 6 Nov 2023 18:37:17 -0500 Subject: [PATCH 5/5] chore: move typedef [skip ci] Signed-off-by: Logan McAnsh --- packages/fetch/src/response.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/fetch/src/response.js b/packages/fetch/src/response.js index 94e35edc..4ca72fd5 100644 --- a/packages/fetch/src/response.js +++ b/packages/fetch/src/response.js @@ -19,6 +19,11 @@ const INTERNALS = Symbol('Response internals'); * @property {number} [counter] * @property {number} [highWaterMark] * + * @typedef {Omit & { + * json(): Promise; + * }} TypedResponse + * @template T + * * @implements {globalThis.Response} */ export default class Response extends Body { @@ -158,10 +163,3 @@ Object.defineProperties(Response.prototype, { headers: {enumerable: true}, clone: {enumerable: true} }); - -/** - * @typedef {Omit & { - * json(): Promise; - * }} TypedResponse - * @template T - */