diff --git a/README.md b/README.md
index 17b2ab32f..ce321cf52 100644
--- a/README.md
+++ b/README.md
@@ -29,6 +29,7 @@ the passed options and sends the request using [fetch](https://developer.mozilla
- [Special cases](#special-cases)
- [The `data` parameter – set request body directly](#the-data-parameter--set-request-body-directly)
- [Set parameters for both the URL/query and the request body](#set-parameters-for-both-the-urlquery-and-the-request-body)
+ - [Set a custom Agent to your requests](#set-a-custom-agent-to-your-requests)
- [LICENSE](#license)
@@ -345,6 +346,17 @@ const { data: app } = await requestWithAuth(
Used for internal logging. Defaults to console
.
+
+
+ options.request.parseSuccessResponseBody
+ |
+
+ boolean
+ |
+
+ If set to false the returned `response` will be passed through from `fetch`. This is useful to stream response.body when downloading files from the GitHub API.
+ |
+
All other options except `options.request.*` will be passed depending on the `method` and `url` options.
@@ -528,6 +540,40 @@ request(
);
```
+### Set a custom Agent to your requests
+
+The way to pass a custom `Agent` to requests is by creating a custom `fetch` function and pass it as `options.request.fetch`. A good example can be [undici's `fetch` implementation](https://undici.nodejs.org/#/?id=undicifetchinput-init-promise).
+
+Example ([See example in CodeSandbox](https://codesandbox.io/p/sandbox/nifty-stitch-wdlwlf))
+
+```js
+import { request } from "@octokit/request";
+import { fetch as undiciFetch, Agent } from "undici";
+
+/** @type {typeof import("undici").fetch} */
+const myFetch = (url, options) => {
+ return undiciFetch(url, {
+ ...options,
+ dispatcher: new Agent({
+ keepAliveTimeout: 10,
+ keepAliveMaxTimeout: 10,
+ }),
+ });
+};
+
+const { data } = await request("GET /users/{username}", {
+ username: "octocat",
+ headers: {
+ "X-GitHub-Api-Version": "2022-11-28",
+ },
+ options: {
+ request: {
+ fetch: myFetch,
+ },
+ },
+});
+```
+
## LICENSE
[MIT](LICENSE)
diff --git a/package-lock.json b/package-lock.json
index 58c8e0223..8e0dca4c0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,7 +11,7 @@
"dependencies": {
"@octokit/endpoint": "^9.0.0",
"@octokit/request-error": "^5.0.0",
- "@octokit/types": "^11.0.0",
+ "@octokit/types": "^11.1.0",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
},
@@ -2013,9 +2013,9 @@
"dev": true
},
"node_modules/@octokit/types": {
- "version": "11.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-11.0.0.tgz",
- "integrity": "sha512-h4iyfMpQUdub1itwTn6y7z2a3EtPuer1paKfsIbZErv0LBbZYGq6haiPUPJys/LetPqgcX3ft33O16XuS03Anw==",
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/@octokit/types/-/types-11.1.0.tgz",
+ "integrity": "sha512-Fz0+7GyLm/bHt8fwEqgvRBWwIV1S6wRRyq+V6exRKLVWaKGsuy6H9QFYeBVDV7rK6fO3XwHgQOPxv+cLj2zpXQ==",
"dependencies": {
"@octokit/openapi-types": "^18.0.0"
}
diff --git a/package.json b/package.json
index 509113dc1..8c43062cd 100644
--- a/package.json
+++ b/package.json
@@ -24,7 +24,7 @@
"dependencies": {
"@octokit/endpoint": "^9.0.0",
"@octokit/request-error": "^5.0.0",
- "@octokit/types": "^11.0.0",
+ "@octokit/types": "^11.1.0",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
},
diff --git a/src/fetch-wrapper.ts b/src/fetch-wrapper.ts
index 0a4f40942..0e6987176 100644
--- a/src/fetch-wrapper.ts
+++ b/src/fetch-wrapper.ts
@@ -11,6 +11,8 @@ export default function fetchWrapper(
requestOptions.request && requestOptions.request.log
? requestOptions.request.log
: console;
+ const parseSuccessResponseBody =
+ requestOptions.request?.parseSuccessResponseBody !== false;
if (
isPlainObject(requestOptions.body) ||
@@ -113,7 +115,9 @@ export default function fetchWrapper(
throw error;
}
- return getResponseData(response);
+ return parseSuccessResponseBody
+ ? await getResponseData(response)
+ : response.body;
})
.then((data) => {
return {
diff --git a/test/request.test.ts b/test/request.test.ts
index 59263941b..86e79bbdb 100644
--- a/test/request.test.ts
+++ b/test/request.test.ts
@@ -1,5 +1,5 @@
import fs from "fs";
-import stream from "stream";
+import stream, { Stream } from "stream";
import { getUserAgent } from "universal-user-agent";
import fetchMock from "fetch-mock";
@@ -1021,4 +1021,35 @@ x//0u+zd/R/QRUzLOw4N72/Hu+UG6MNt5iDZFCtapRaKt6OvSBwy8w==
expect(error.name).toEqual("AbortError");
});
});
+
+ it("request should pass the stream in the response", () => {
+ const mock = fetchMock.sandbox().get(
+ "https://api.github.com/repos/octokit-fixture-org/release-assets/tarball/main",
+ {
+ status: 200,
+ headers: {
+ "content-type": "application/x-gzip",
+ },
+ body: fs.createReadStream(__filename),
+ },
+ {
+ sendAsJson: false,
+ },
+ );
+
+ return request("GET /repos/{owner}/{repo}/tarball/{branch}", {
+ owner: "octokit-fixture-org",
+ repo: "release-assets",
+ branch: "main",
+ request: {
+ parseSuccessResponseBody: false,
+ fetch: mock,
+ },
+ }).then((response) => {
+ expect(response.status).toEqual(200);
+ expect(response.headers["content-type"]).toEqual("application/x-gzip");
+ expect(response.data).toBeInstanceOf(Stream);
+ expect(mock.done()).toBe(true);
+ });
+ });
});