diff --git a/packages/manager/src/auth/PrismicAuthManager.ts b/packages/manager/src/auth/PrismicAuthManager.ts index 04b2163e31..c06620bffe 100644 --- a/packages/manager/src/auth/PrismicAuthManager.ts +++ b/packages/manager/src/auth/PrismicAuthManager.ts @@ -5,7 +5,7 @@ import * as os from "node:os"; import * as http from "node:http"; import * as h3 from "h3"; -import fetch from "node-fetch"; +import fetch from "../lib/fetch"; import cookie from "cookie"; import cors from "cors"; import getPort from "get-port"; diff --git a/packages/manager/src/lib/checkIsURLAccessible.ts b/packages/manager/src/lib/checkIsURLAccessible.ts index 7e0a6988a0..aaf577cc13 100644 --- a/packages/manager/src/lib/checkIsURLAccessible.ts +++ b/packages/manager/src/lib/checkIsURLAccessible.ts @@ -1,4 +1,4 @@ -import fetch from "node-fetch"; +import fetch from "./fetch"; export const checkIsURLAccessible = async (url: string): Promise => { const res = await fetch(url); diff --git a/packages/manager/src/lib/fetch.ts b/packages/manager/src/lib/fetch.ts new file mode 100644 index 0000000000..091ee8e66f --- /dev/null +++ b/packages/manager/src/lib/fetch.ts @@ -0,0 +1,46 @@ +// This temporary wrapper around `node-fetch` fixes an issue where quick +// consecutive network requests cause failed requests. +// +// See https://github.com/node-fetch/node-fetch/issues/1735 for more details. +// +// TODO: Remove this wrapper and replace all imports with `node-fetch` if https://github.com/node-fetch/node-fetch/pull/1736 is merged. + +import * as http from "node:http"; +import * as https from "node:https"; +import baseFetch from "node-fetch"; + +export * from "node-fetch"; + +/** + * The default HTTP Agent with `keepAlive: true` used in `fetch()` requests. + */ +const DEFAULT_HTTP_AGENT = new http.Agent({ keepAlive: true }); + +/** + * The default HTTPS Agent with `keepAlive: true` used in `fetch()` requests. + */ +const DEFAULT_HTTPS_AGENT = new https.Agent({ keepAlive: true }); + +/** + * Patched `fetch()` from `node-fetch` that fixes a bug where quick consecutive + * network requests cause failed requests. + * + * Use this `fetch()` in place of `node-fetch`'s `fetch()`. + * + * @remarks + * `fetch()` is patched by setting an HTTP/HTTPS Agent with `keepAlive: true`. + * If you need to assign an Agent, be sure to retain the `keepAlive: true` + * option. + */ +const fetch: typeof baseFetch = (url, init) => { + return baseFetch(url, { + agent: (parsedURL) => { + return parsedURL.protocol === "http:" + ? DEFAULT_HTTP_AGENT + : DEFAULT_HTTPS_AGENT; + }, + ...init, + }); +}; + +export default fetch; diff --git a/packages/manager/src/lib/fetchGitHubReleaseBodyForRelease.ts b/packages/manager/src/lib/fetchGitHubReleaseBodyForRelease.ts index d39549e468..14383c20bc 100644 --- a/packages/manager/src/lib/fetchGitHubReleaseBodyForRelease.ts +++ b/packages/manager/src/lib/fetchGitHubReleaseBodyForRelease.ts @@ -1,5 +1,5 @@ import * as t from "io-ts"; -import fetch from "node-fetch"; +import fetch from "./fetch"; import pLimit from "p-limit"; import { decode } from "./decode"; diff --git a/packages/manager/src/lib/fetchNPMPackageVersions.ts b/packages/manager/src/lib/fetchNPMPackageVersions.ts index b719279032..78383ef95e 100644 --- a/packages/manager/src/lib/fetchNPMPackageVersions.ts +++ b/packages/manager/src/lib/fetchNPMPackageVersions.ts @@ -1,5 +1,5 @@ import * as t from "io-ts"; -import fetch from "node-fetch"; +import fetch from "./fetch"; import { decode } from "./decode"; diff --git a/packages/manager/src/managers/customTypes/CustomTypesManager.ts b/packages/manager/src/managers/customTypes/CustomTypesManager.ts index 49e6ed8059..37bae1b9bf 100644 --- a/packages/manager/src/managers/customTypes/CustomTypesManager.ts +++ b/packages/manager/src/managers/customTypes/CustomTypesManager.ts @@ -1,5 +1,5 @@ import * as t from "io-ts"; -import fetch from "node-fetch"; +import fetch from "../../lib/fetch"; import * as prismicCustomTypesClient from "@prismicio/custom-types-client"; import { CustomType } from "@prismicio/types-internal/lib/customtypes"; import { diff --git a/packages/manager/src/managers/prismicRepository/PrismicRepositoryManager.ts b/packages/manager/src/managers/prismicRepository/PrismicRepositoryManager.ts index 8d6c06dff7..0c29d21e20 100644 --- a/packages/manager/src/managers/prismicRepository/PrismicRepositoryManager.ts +++ b/packages/manager/src/managers/prismicRepository/PrismicRepositoryManager.ts @@ -1,5 +1,5 @@ import * as t from "io-ts"; -import fetch, { Response } from "node-fetch"; +import fetch, { Response } from "../../lib/fetch"; import { fold } from "fp-ts/Either"; import { decode } from "../../lib/decode"; diff --git a/packages/manager/src/managers/screenshots/ScreenshotsManager.ts b/packages/manager/src/managers/screenshots/ScreenshotsManager.ts index a238045fb5..ab62a69d06 100644 --- a/packages/manager/src/managers/screenshots/ScreenshotsManager.ts +++ b/packages/manager/src/managers/screenshots/ScreenshotsManager.ts @@ -1,6 +1,6 @@ import * as t from "io-ts"; import { fileTypeFromBuffer } from "file-type"; -import fetch, { FormData, Blob, Response } from "node-fetch"; +import fetch, { FormData, Blob, Response } from "../../lib/fetch"; // puppeteer is lazy-loaded in captureSliceSimulatorScreenshot import type { BrowserContext, Viewport } from "puppeteer"; diff --git a/packages/manager/src/managers/simulator/SimulatorManager.ts b/packages/manager/src/managers/simulator/SimulatorManager.ts index 239d9d28d0..318daddcd6 100644 --- a/packages/manager/src/managers/simulator/SimulatorManager.ts +++ b/packages/manager/src/managers/simulator/SimulatorManager.ts @@ -1,6 +1,6 @@ import * as t from "io-ts"; import { HookError } from "@slicemachine/plugin-kit"; -import fetch from "node-fetch"; +import fetch from "../../lib/fetch"; import { DecodeError } from "../../lib/DecodeError"; import { assertPluginsInitialized } from "../../lib/assertPluginsInitialized"; diff --git a/packages/manager/src/managers/slices/SlicesManager.ts b/packages/manager/src/managers/slices/SlicesManager.ts index be6db98a61..fbe5e46bf1 100644 --- a/packages/manager/src/managers/slices/SlicesManager.ts +++ b/packages/manager/src/managers/slices/SlicesManager.ts @@ -1,5 +1,5 @@ import * as t from "io-ts"; -import fetch from "node-fetch"; +import fetch from "../../lib/fetch"; import * as prismicCustomTypesClient from "@prismicio/custom-types-client"; import { SharedSliceContent } from "@prismicio/types-internal/lib/content"; import {