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 diff --git a/packages/fetch/src/response.js b/packages/fetch/src/response.js index ebeba7c2..4ca72fd5 100644 --- a/packages/fetch/src/response.js +++ b/packages/fetch/src/response.js @@ -12,13 +12,18 @@ const INTERNALS = Symbol('Response internals'); /** * Response class - * + * * @typedef {Object} Ext * @property {number} [size] * @property {string} [url] * @property {number} [counter] * @property {number} [highWaterMark] - * + * + * @typedef {Omit & { + * json(): Promise; + * }} TypedResponse + * @template T + * * @implements {globalThis.Response} */ export default class Response extends Body { @@ -126,6 +131,24 @@ export default class Response extends Body { }); } + /** + * @template {unknown} Data + * @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 {TypedResponse} 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'; } @@ -140,4 +163,3 @@ Object.defineProperties(Response.prototype, { headers: {enumerable: true}, clone: {enumerable: true} }); - 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({