Skip to content

Commit 908263e

Browse files
authored
fix: allow clone of request and responses will null body (#20)
1 parent 6d9cd44 commit 908263e

File tree

4 files changed

+63
-2
lines changed

4 files changed

+63
-2
lines changed

.changeset/tasty-peas-mate.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@remix-run/web-fetch": patch
3+
---
4+
5+
allow clone of request and responses will null body

packages/fetch/src/body.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ async function consumeBody(data) {
273273
* Clone body given Res/Req instance
274274
*
275275
* @param {Body} instance Response or Request instance
276-
* @return {ReadableStream<Uint8Array>}
276+
* @return {ReadableStream<Uint8Array> | null}
277277
*/
278278
export const clone = instance => {
279279
const {body} = instance;
@@ -283,7 +283,10 @@ export const clone = instance => {
283283
throw new Error('cannot clone body after it is used');
284284
}
285285

286-
// @ts-expect-error - could be null
286+
if (!body) {
287+
return null;
288+
}
289+
287290
const [left, right] = body.tee();
288291
instance[INTERNALS].body = left;
289292
return right;

packages/fetch/test/request.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,37 @@ describe('Request', () => {
258258
});
259259
});
260260

261+
it('should support clone() method with null body', () => {
262+
const url = base;
263+
264+
const agent = new http.Agent();
265+
const {signal} = new AbortController();
266+
const request = new Request(url, {
267+
method: 'POST',
268+
redirect: 'manual',
269+
headers: {
270+
b: '2'
271+
},
272+
follow: 3,
273+
compress: false,
274+
agent,
275+
signal
276+
});
277+
const cl = request.clone();
278+
expect(cl.url).to.equal(url);
279+
expect(cl.method).to.equal('POST');
280+
expect(cl.redirect).to.equal('manual');
281+
expect(cl.headers.get('b')).to.equal('2');
282+
expect(cl.follow).to.equal(3);
283+
expect(cl.compress).to.equal(false);
284+
expect(cl.method).to.equal('POST');
285+
expect(cl.counter).to.equal(0);
286+
expect(cl.agent).to.equal(agent);
287+
expect(cl.signal).to.equal(signal);
288+
// Clone body should be null
289+
expect(cl.body).to.equal(null);
290+
});
291+
261292
it('should support ArrayBuffer as body', () => {
262293
const encoder = new TextEncoder();
263294
const request = new Request(base, {

packages/fetch/test/response.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,28 @@ describe('Response', () => {
129129
});
130130
});
131131

132+
it('should support clone() method with null body', () => {
133+
const res = new Response(null, {
134+
headers: {
135+
a: '1'
136+
},
137+
url: base,
138+
status: 346,
139+
statusText: 'production'
140+
});
141+
const cl = res.clone();
142+
expect(cl.headers.get('a')).to.equal('1');
143+
expect(cl.url).to.equal(base);
144+
expect(cl.status).to.equal(346);
145+
expect(cl.statusText).to.equal('production');
146+
expect(cl.ok).to.be.false;
147+
// Clone body should also be null
148+
expect(cl.body).to.equal(null);
149+
return cl.text().then(result => {
150+
expect(result).to.equal('');
151+
});
152+
});
153+
132154
it('should support stream as body', () => {
133155
const body = streamFromString('a=1');
134156
const res = new Response(body);

0 commit comments

Comments
 (0)