Skip to content

Commit f1d9272

Browse files
fix(fetch): allow clone of Request & Response with null body (#79)
* fix: allow clone of request and responses will null body * chore: fix changeset --------- Co-authored-by: Jacob Ebey <[email protected]>
1 parent 08b270f commit f1d9272

File tree

4 files changed

+63
-2
lines changed

4 files changed

+63
-2
lines changed

.changeset/tasty-peas-mate.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@web-std/fetch": patch
3+
---
4+
5+
allow clone of request and responses will `null` body

packages/fetch/src/body.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ async function consumeBody(data) {
274274
* Clone body given Res/Req instance
275275
*
276276
* @param {Body} instance Response or Request instance
277-
* @return {ReadableStream<Uint8Array>}
277+
* @return {ReadableStream<Uint8Array> | null}
278278
*/
279279
export const clone = instance => {
280280
const {body} = instance;
@@ -284,7 +284,10 @@ export const clone = instance => {
284284
throw new Error('cannot clone body after it is used');
285285
}
286286

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

packages/fetch/test/request.js

+31
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,37 @@ describe('Request', () => {
300300
});
301301
});
302302

303+
it('should support clone() method with null body', () => {
304+
const url = base;
305+
306+
const agent = new http.Agent();
307+
const {signal} = new AbortController();
308+
const request = new Request(url, {
309+
method: 'POST',
310+
redirect: 'manual',
311+
headers: {
312+
b: '2'
313+
},
314+
follow: 3,
315+
compress: false,
316+
agent,
317+
signal
318+
});
319+
const cl = request.clone();
320+
expect(cl.url).to.equal(url);
321+
expect(cl.method).to.equal('POST');
322+
expect(cl.redirect).to.equal('manual');
323+
expect(cl.headers.get('b')).to.equal('2');
324+
expect(cl.follow).to.equal(3);
325+
expect(cl.compress).to.equal(false);
326+
expect(cl.method).to.equal('POST');
327+
expect(cl.counter).to.equal(0);
328+
expect(cl.agent).to.equal(agent);
329+
expect(cl.signal).to.equal(signal);
330+
// Clone body should be null
331+
expect(cl.body).to.equal(null);
332+
});
333+
303334
it('should support ArrayBuffer as body', () => {
304335
const encoder = new TextEncoder();
305336
const request = new Request(base, {

packages/fetch/test/response.js

+22
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)