Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
STAGING_TOKEN=
PROD_TOKEN=
APIDRIFT_HTTP_TIMEOUT_MS=10000
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,12 @@ After `init`, create a `.env` file (or set env vars) so `${STAGING_TOKEN}` / `${
```bash
STAGING_TOKEN=your_token_here
PROD_TOKEN=your_token_here
APIDRIFT_HTTP_TIMEOUT_MS=10000
```

- Add `.env` to `.gitignore`.
- If your `Authorization` header resolves empty (e.g. token missing), apidrift prints a warning before making requests.
- Set `APIDRIFT_HTTP_TIMEOUT_MS` to a positive integer to override the default 10 second HTTP timeout.

---

Expand Down
3 changes: 2 additions & 1 deletion src/core/fetcher.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import axios from "axios";
import { maskSensitiveData } from "./masker.js";
import { getHttpTimeoutMs } from "../utils/httpTimeout.js";

const RETRY_DEFAULTS = {
retries: 3,
Expand Down Expand Up @@ -29,7 +30,7 @@ async function fetchWithRetry(
config = RETRY_DEFAULTS,
) {
try {
return await axios({ ...options, url, timeout: 10000 });
return await axios({ ...options, url, timeout: getHttpTimeoutMs() });
} catch (err) {
if (attempt < config.retries && isRetryable(err)) {
const delay = Math.min(
Expand Down
3 changes: 2 additions & 1 deletion src/discovery/graphql.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import axios from "axios";
import { getHttpTimeoutMs } from "../utils/httpTimeout.js";

const INTROSPECTION_QUERY = {
query: `{ __schema { queryType { fields { name } } mutationType { fields { name } } } }`,
Expand All @@ -10,7 +11,7 @@ export async function discoverGraphQL(baseUrl, headers = {}) {
url: baseUrl,
headers: { "Content-Type": "application/json", ...headers },
data: INTROSPECTION_QUERY,
timeout: 10000,
timeout: getHttpTimeoutMs(),
});

const schema = resp.data?.data?.__schema;
Expand Down
3 changes: 2 additions & 1 deletion src/discovery/openapi.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import axios from "axios";
import { getHttpTimeoutMs } from "../utils/httpTimeout.js";

export async function discoverOpenAPI(
specUrl,
Expand All @@ -9,7 +10,7 @@ export async function discoverOpenAPI(
method: "GET",
url: specUrl,
headers,
timeout: 10000,
timeout: getHttpTimeoutMs(),
});
const spec = resp.data;

Expand Down
18 changes: 18 additions & 0 deletions src/utils/httpTimeout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const DEFAULT_HTTP_TIMEOUT_MS = 10000;

export function getHttpTimeoutMs(env = process.env) {
const rawTimeout = env.APIDRIFT_HTTP_TIMEOUT_MS;

if (rawTimeout === undefined || rawTimeout === "") {
return DEFAULT_HTTP_TIMEOUT_MS;
}

const timeout = Number(rawTimeout);
if (!Number.isInteger(timeout) || timeout <= 0) {
throw new Error(
"APIDRIFT_HTTP_TIMEOUT_MS must be a positive integer number of milliseconds",
);
}

return timeout;
}
20 changes: 20 additions & 0 deletions tests/utils/httpTimeout.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { getHttpTimeoutMs } from "../../src/utils/httpTimeout.js";

describe("getHttpTimeoutMs", () => {
test("uses the default timeout when env var is unset", () => {
expect(getHttpTimeoutMs({})).toBe(10000);
});

test("reads a positive integer timeout from the environment", () => {
expect(getHttpTimeoutMs({ APIDRIFT_HTTP_TIMEOUT_MS: "2500" })).toBe(2500);
});

test.each(["0", "-1", "1.5", "abc"])(
"rejects invalid timeout value %s",
(value) => {
expect(() =>
getHttpTimeoutMs({ APIDRIFT_HTTP_TIMEOUT_MS: value }),
).toThrow("APIDRIFT_HTTP_TIMEOUT_MS must be a positive integer");
},
);
});