Skip to content

Commit f6ff0d9

Browse files
authored
fix: clone request object on fetch based adapter (#37)
* test: add test specs * fix: clone request object on fetch based adapter * chore: bump package
1 parent 03d215d commit f6ff0d9

File tree

6 files changed

+85
-3
lines changed

6 files changed

+85
-3
lines changed

.changeset/flat-students-hear.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"plantae": patch
3+
---
4+
5+
fix: clone request object on fetch based adapter

packages/plantae/src/createMiddleware.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,15 @@ export function createResponseMiddleware<T, U>({
4444
extendClientRequest,
4545
convertToAdapterResponse,
4646
extendClientResponse,
47+
cloneClientRequest,
4748
retry,
4849
}: {
4950
plugins: Plugin[];
5051
convertToAdapterRequest: ConvertToAdapterRequest<T>;
5152
extendClientRequest: ExtendClientRequest<T>;
5253
convertToAdapterResponse: ConvertToAdapterResponse<U>;
5354
extendClientResponse: ExtendClientResponse<U>;
55+
cloneClientRequest?: (req: T) => T;
5456
retry: Retryer<T, U>;
5557
}) {
5658
return async (clientResponse: U, clientRequest: T) => {
@@ -64,12 +66,17 @@ export function createResponseMiddleware<T, U>({
6466
convertToAdapterRequest(clientRequest),
6567
// eslint-disable-next-line @typescript-eslint/no-loop-func
6668
async (adapterRequest) => {
67-
clientRequest = await extendClientRequest(
69+
const extendedClientRequest = await extendClientRequest(
6870
clientRequest,
6971
adapterRequest
7072
);
73+
const clonedClientRequest = cloneClientRequest
74+
? cloneClientRequest(extendedClientRequest)
75+
: extendedClientRequest;
7176

72-
clientResponse = await retry(clientRequest);
77+
clientResponse = await retry(extendedClientRequest);
78+
79+
clientRequest = clonedClientRequest;
7380

7481
return convertToAdapterResponse(clientResponse);
7582
}
@@ -86,6 +93,7 @@ export default function createMiddleware<Req, Res>({
8693
extendClientRequest,
8794
convertToAdapterResponse,
8895
extendClientResponse,
96+
cloneClientRequest,
8997
plugins,
9098
retry,
9199
}: {
@@ -94,6 +102,7 @@ export default function createMiddleware<Req, Res>({
94102
extendClientRequest: ExtendClientRequest<Req>;
95103
convertToAdapterResponse: ConvertToAdapterResponse<Res>;
96104
extendClientResponse: ExtendClientResponse<Res>;
105+
cloneClientRequest?: (req: Req) => Req;
97106
retry: Retryer<Req, Res>;
98107
}) {
99108
return {
@@ -108,6 +117,7 @@ export default function createMiddleware<Req, Res>({
108117
extendClientRequest,
109118
convertToAdapterResponse,
110119
extendClientResponse,
120+
cloneClientRequest,
111121
retry,
112122
}),
113123
};

packages/plantae/src/fetch/createFetch.spec.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,4 +424,33 @@ describe("createFetch", () => {
424424

425425
expect(await res.text()).toBe("retried");
426426
});
427+
428+
it("should pass unused request to afterResponse hook", async () => {
429+
server.use(http.post(base("/"), () => new Response()));
430+
431+
const fetch = createFetch({
432+
plugins: [
433+
{
434+
name: "plugin-clone-request",
435+
hooks: {
436+
beforeRequest: (req) => {
437+
return new Request(req, {
438+
method: "POST",
439+
body: "modified",
440+
});
441+
},
442+
afterResponse: (_, req, retry) => {
443+
expect(req.bodyUsed).toBe(false);
444+
445+
return retry(req);
446+
},
447+
},
448+
},
449+
],
450+
});
451+
452+
await fetch(base("/"));
453+
454+
expect.assertions(1);
455+
});
427456
});

packages/plantae/src/fetch/createFetch.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,17 @@ const createFetch = ({
2323
convertToAdapterResponse: (res) => res,
2424
extendClientRequest: (_, req) => req as Request,
2525
extendClientResponse: (_, res) => res as Response,
26+
cloneClientRequest: (req) => req.clone(),
2627
plugins,
2728
retry: client,
2829
});
2930

3031
const request = await requestMiddleware(initialRequest);
32+
const clonedClientRequest = request.clone();
3133

3234
const initialResponse = await client(request);
3335

34-
return responseMiddleware(initialResponse, request);
36+
return responseMiddleware(initialResponse, clonedClientRequest);
3537
};
3638
};
3739

packages/plantae/src/ky/createKyHooks.spec.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,4 +505,39 @@ describe("createKyHooks", () => {
505505

506506
expect(await res.text()).toBe("retried");
507507
});
508+
509+
it("should pass unused request to afterResponse hook", async () => {
510+
server.use(http.post(base("/"), () => new Response()));
511+
512+
const hooks = createKyHooks({
513+
client: Ky,
514+
plugins: [
515+
{
516+
name: "plugin-clone-request",
517+
hooks: {
518+
beforeRequest: (req) => {
519+
return new Request(req, {
520+
method: "POST",
521+
body: "modified",
522+
});
523+
},
524+
afterResponse: (_, req, retry) => {
525+
expect(req.bodyUsed).toBe(false);
526+
527+
return retry(req);
528+
},
529+
},
530+
},
531+
],
532+
});
533+
534+
const ky = Ky.create({
535+
prefixUrl: baseURL,
536+
hooks,
537+
});
538+
539+
await ky.get("");
540+
541+
expect.assertions(1);
542+
});
508543
});

packages/plantae/src/ky/createKyHooks.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const createKyHooks = ({
2424
convertToAdapterResponse: (res) => res,
2525
extendClientRequest: (_, req) => req as Request,
2626
extendClientResponse: (_, res) => res as Response,
27+
cloneClientRequest: (req) => req.clone(),
2728
plugins,
2829
retry: client,
2930
});

0 commit comments

Comments
 (0)