@continuedev/fetch 1.0.13 → 1.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/util.test.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { afterEach, expect, test, vi } from "vitest";
2
- import { getProxyFromEnv, shouldBypassProxy } from "./util.js";
2
+ import { getProxyFromEnv, patternMatchesHostname, shouldBypassProxy, } from "./util.js";
3
3
  // Reset environment variables after each test
4
4
  afterEach(() => {
5
5
  vi.resetModules();
@@ -42,44 +42,118 @@ test("getProxyFromEnv prefers HTTPS_PROXY over other env vars for https protocol
42
42
  process.env.http_proxy = "http://notused3.example.com";
43
43
  expect(getProxyFromEnv("https:")).toBe("https://preferred.example.com");
44
44
  });
45
+ // Tests for patternMatchesHostname
46
+ test("patternMatchesHostname with exact hostname match", () => {
47
+ expect(patternMatchesHostname("example.com", "example.com")).toBe(true);
48
+ expect(patternMatchesHostname("example.com", "different.com")).toBe(false);
49
+ });
50
+ test("patternMatchesHostname with wildcard domains", () => {
51
+ expect(patternMatchesHostname("sub.example.com", "*.example.com")).toBe(true);
52
+ expect(patternMatchesHostname("sub.sub.example.com", "*.example.com")).toBe(true);
53
+ expect(patternMatchesHostname("example.com", "*.example.com")).toBe(false);
54
+ expect(patternMatchesHostname("sub.different.com", "*.example.com")).toBe(false);
55
+ });
56
+ test("patternMatchesHostname with domain suffix", () => {
57
+ expect(patternMatchesHostname("sub.example.com", ".example.com")).toBe(true);
58
+ expect(patternMatchesHostname("example.com", ".example.com")).toBe(true);
59
+ expect(patternMatchesHostname("different.com", ".example.com")).toBe(false);
60
+ });
61
+ test("patternMatchesHostname with case insensitivity", () => {
62
+ expect(patternMatchesHostname("EXAMPLE.com", "example.COM")).toBe(true);
63
+ expect(patternMatchesHostname("sub.EXAMPLE.com", "*.example.COM")).toBe(true);
64
+ });
65
+ // Port handling tests
66
+ test("patternMatchesHostname with exact port match", () => {
67
+ expect(patternMatchesHostname("example.com:8080", "example.com:8080")).toBe(true);
68
+ expect(patternMatchesHostname("example.com:8080", "example.com:9090")).toBe(false);
69
+ });
70
+ test("patternMatchesHostname with port in pattern but not in hostname", () => {
71
+ expect(patternMatchesHostname("example.com", "example.com:8080")).toBe(false);
72
+ });
73
+ test("patternMatchesHostname with port in hostname but not in pattern", () => {
74
+ expect(patternMatchesHostname("example.com:8080", "example.com")).toBe(true);
75
+ });
76
+ test("patternMatchesHostname with wildcard domains and ports", () => {
77
+ expect(patternMatchesHostname("sub.example.com:8080", "*.example.com:8080")).toBe(true);
78
+ expect(patternMatchesHostname("sub.example.com:9090", "*.example.com:8080")).toBe(false);
79
+ expect(patternMatchesHostname("sub.example.com", "*.example.com:8080")).toBe(false);
80
+ });
81
+ test("patternMatchesHostname with domain suffix and ports", () => {
82
+ expect(patternMatchesHostname("sub.example.com:8080", ".example.com:8080")).toBe(true);
83
+ expect(patternMatchesHostname("example.com:8080", ".example.com:8080")).toBe(true);
84
+ expect(patternMatchesHostname("sub.example.com:9090", ".example.com:8080")).toBe(false);
85
+ });
45
86
  // Tests for shouldBypassProxy
46
87
  test("shouldBypassProxy returns false when NO_PROXY is not set", () => {
47
- expect(shouldBypassProxy("example.com")).toBe(false);
88
+ expect(shouldBypassProxy("example.com", undefined)).toBe(false);
48
89
  });
49
90
  test("shouldBypassProxy returns true for exact hostname match", () => {
50
91
  process.env.NO_PROXY = "example.com,another.com";
51
- expect(shouldBypassProxy("example.com")).toBe(true);
92
+ expect(shouldBypassProxy("example.com", undefined)).toBe(true);
52
93
  });
53
94
  test("shouldBypassProxy returns false when hostname doesn't match any NO_PROXY entry", () => {
54
95
  process.env.NO_PROXY = "example.com,another.com";
55
- expect(shouldBypassProxy("different.com")).toBe(false);
96
+ expect(shouldBypassProxy("different.com", undefined)).toBe(false);
56
97
  });
57
98
  test("shouldBypassProxy handles lowercase no_proxy", () => {
58
99
  process.env.no_proxy = "example.com";
59
- expect(shouldBypassProxy("example.com")).toBe(true);
100
+ expect(shouldBypassProxy("example.com", undefined)).toBe(true);
60
101
  });
61
102
  test("shouldBypassProxy works with wildcard domains", () => {
62
103
  process.env.NO_PROXY = "*.example.com";
63
- expect(shouldBypassProxy("sub.example.com")).toBe(true);
64
- expect(shouldBypassProxy("example.com")).toBe(false);
65
- expect(shouldBypassProxy("different.com")).toBe(false);
104
+ expect(shouldBypassProxy("sub.example.com", undefined)).toBe(true);
105
+ expect(shouldBypassProxy("example.com", undefined)).toBe(false);
106
+ expect(shouldBypassProxy("different.com", undefined)).toBe(false);
66
107
  });
67
108
  test("shouldBypassProxy works with domain suffix", () => {
68
109
  process.env.NO_PROXY = ".example.com";
69
- expect(shouldBypassProxy("sub.example.com")).toBe(true);
70
- expect(shouldBypassProxy("example.com")).toBe(true);
71
- expect(shouldBypassProxy("different.com")).toBe(false);
110
+ expect(shouldBypassProxy("sub.example.com", undefined)).toBe(true);
111
+ expect(shouldBypassProxy("example.com", undefined)).toBe(true);
112
+ expect(shouldBypassProxy("different.com", undefined)).toBe(false);
72
113
  });
73
114
  test("shouldBypassProxy handles multiple entries with different patterns", () => {
74
115
  process.env.NO_PROXY = "internal.local,*.example.com,.test.com";
75
- expect(shouldBypassProxy("internal.local")).toBe(true);
76
- expect(shouldBypassProxy("sub.example.com")).toBe(true);
77
- expect(shouldBypassProxy("sub.test.com")).toBe(true);
78
- expect(shouldBypassProxy("test.com")).toBe(true);
79
- expect(shouldBypassProxy("example.org")).toBe(false);
116
+ expect(shouldBypassProxy("internal.local", undefined)).toBe(true);
117
+ expect(shouldBypassProxy("sub.example.com", undefined)).toBe(true);
118
+ expect(shouldBypassProxy("sub.test.com", undefined)).toBe(true);
119
+ expect(shouldBypassProxy("test.com", undefined)).toBe(true);
120
+ expect(shouldBypassProxy("example.org", undefined)).toBe(false);
80
121
  });
81
122
  test("shouldBypassProxy ignores whitespace in NO_PROXY", () => {
82
123
  process.env.NO_PROXY = " example.com , *.test.org ";
83
- expect(shouldBypassProxy("example.com")).toBe(true);
84
- expect(shouldBypassProxy("subdomain.test.org")).toBe(true);
124
+ expect(shouldBypassProxy("example.com", undefined)).toBe(true);
125
+ expect(shouldBypassProxy("subdomain.test.org", undefined)).toBe(true);
126
+ });
127
+ test("shouldBypassProxy with ports in NO_PROXY", () => {
128
+ process.env.NO_PROXY = "example.com:8080,*.test.org:443,.internal.net:8443";
129
+ expect(shouldBypassProxy("example.com:8080", undefined)).toBe(true);
130
+ expect(shouldBypassProxy("example.com:9090", undefined)).toBe(false);
131
+ expect(shouldBypassProxy("sub.test.org:443", undefined)).toBe(true);
132
+ expect(shouldBypassProxy("sub.internal.net:8443", undefined)).toBe(true);
133
+ expect(shouldBypassProxy("internal.net:8443", undefined)).toBe(true);
134
+ });
135
+ test("shouldBypassProxy accepts options with noProxy patterns", () => {
136
+ const options = { noProxy: ["example.com:8080", "*.internal.net"] };
137
+ expect(shouldBypassProxy("example.com:8080", options)).toBe(true);
138
+ expect(shouldBypassProxy("example.com", options)).toBe(false);
139
+ expect(shouldBypassProxy("server.internal.net", options)).toBe(true);
140
+ });
141
+ test("shouldBypassProxy combines environment and options noProxy patterns", () => {
142
+ process.env.NO_PROXY = "example.org,*.test.com";
143
+ const options = { noProxy: ["example.com:8080", "*.internal.net"] };
144
+ expect(shouldBypassProxy("example.org", options)).toBe(true);
145
+ expect(shouldBypassProxy("sub.test.com", options)).toBe(true);
146
+ expect(shouldBypassProxy("example.com:8080", options)).toBe(true);
147
+ expect(shouldBypassProxy("server.internal.net", options)).toBe(true);
148
+ expect(shouldBypassProxy("other.domain", options)).toBe(false);
149
+ });
150
+ test("shouldBypassProxy handles empty noProxy array in options", () => {
151
+ process.env.NO_PROXY = "example.org";
152
+ const options = { noProxy: [] };
153
+ expect(shouldBypassProxy("example.org", options)).toBe(true);
154
+ expect(shouldBypassProxy("different.com", options)).toBe(false);
155
+ });
156
+ test("shouldBypassProxy handles undefined options", () => {
157
+ process.env.NO_PROXY = "example.org";
158
+ expect(shouldBypassProxy("example.org", undefined)).toBe(true);
85
159
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@continuedev/fetch",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -0,0 +1,3 @@
1
+ import createReleaseConfig from "../shared-release.config.js";
2
+
3
+ export default createReleaseConfig("fetch");
@@ -0,0 +1,187 @@
1
+ import * as fs from "node:fs";
2
+ import { beforeEach, expect, test, vi } from "vitest";
3
+ import { CertsCache, getCertificateContent } from "./certs.js";
4
+
5
+ // Mock fs module
6
+ vi.mock("node:fs", () => ({
7
+ readFileSync: vi.fn(),
8
+ }));
9
+
10
+ const mockReadFileSync = vi.mocked(fs.readFileSync);
11
+
12
+ beforeEach(() => {
13
+ vi.clearAllMocks();
14
+ });
15
+
16
+ test("getCertificateContent should decode base64 data URI correctly", () => {
17
+ const testCert =
18
+ "-----BEGIN CERTIFICATE-----\nMIIC...\n-----END CERTIFICATE-----";
19
+ const base64Data = Buffer.from(testCert, "utf8").toString("base64");
20
+ const dataUri = `data:application/x-pem-file;base64,${base64Data}`;
21
+
22
+ const result = getCertificateContent(dataUri);
23
+
24
+ expect(result).toBe(testCert);
25
+ });
26
+
27
+ test("getCertificateContent should decode URL-encoded data URI correctly", () => {
28
+ const testCert =
29
+ "-----BEGIN CERTIFICATE-----\nMIIC...\n-----END CERTIFICATE-----";
30
+ const encodedData = encodeURIComponent(testCert);
31
+ const dataUri = `data:text/plain,${encodedData}`;
32
+
33
+ const result = getCertificateContent(dataUri);
34
+
35
+ expect(result).toBe(testCert);
36
+ });
37
+
38
+ test("getCertificateContent should handle plain text data URI correctly", () => {
39
+ const testCert = "simple-cert-content";
40
+ const dataUri = `data:text/plain,${testCert}`;
41
+
42
+ const result = getCertificateContent(dataUri);
43
+
44
+ expect(result).toBe(testCert);
45
+ });
46
+
47
+ test("getCertificateContent should read file when input is a file path", () => {
48
+ const filePath = "/path/to/cert.pem";
49
+ const expectedContent =
50
+ "-----BEGIN CERTIFICATE-----\nfile content\n-----END CERTIFICATE-----";
51
+
52
+ mockReadFileSync.mockReturnValue(expectedContent);
53
+
54
+ const result = getCertificateContent(filePath);
55
+
56
+ expect(mockReadFileSync).toHaveBeenCalledWith(filePath, "utf8");
57
+ expect(result).toBe(expectedContent);
58
+ });
59
+
60
+ test("getCertificateContent should handle data URI with different media types", () => {
61
+ const testData = "certificate-data";
62
+ const base64Data = Buffer.from(testData, "utf8").toString("base64");
63
+ const dataUri = `data:application/x-x509-ca-cert;base64,${base64Data}`;
64
+
65
+ const result = getCertificateContent(dataUri);
66
+
67
+ expect(result).toBe(testData);
68
+ });
69
+
70
+ test("getCertificateContent should handle data URI without media type", () => {
71
+ const testData = "simple-data";
72
+ const base64Data = Buffer.from(testData, "utf8").toString("base64");
73
+ const dataUri = `data:;base64,${base64Data}`;
74
+
75
+ const result = getCertificateContent(dataUri);
76
+
77
+ expect(result).toBe(testData);
78
+ });
79
+
80
+ test("getCertificateContent should handle data URI without media type or encoding", () => {
81
+ const testData = "simple-data";
82
+ const base64Data = Buffer.from(testData, "utf8").toString("base64");
83
+ const dataUri = `data:;base64,${base64Data}`;
84
+
85
+ const result = getCertificateContent(dataUri);
86
+
87
+ expect(result).toBe(testData);
88
+ });
89
+
90
+ test("getCertificateContent should handle relative file paths", () => {
91
+ const filePath = "./certs/ca.pem";
92
+ const expectedContent = "certificate from relative path";
93
+
94
+ mockReadFileSync.mockReturnValue(expectedContent);
95
+
96
+ const result = getCertificateContent(filePath);
97
+
98
+ expect(mockReadFileSync).toHaveBeenCalledWith(filePath, "utf8");
99
+ expect(result).toBe(expectedContent);
100
+ });
101
+
102
+ test("getCertificateContent should handle data URI with special characters in URL encoding", () => {
103
+ const testCert = "cert with spaces and special chars: !@#$%";
104
+ const encodedData = encodeURIComponent(testCert);
105
+ const dataUri = `data:text/plain,${encodedData}`;
106
+
107
+ const result = getCertificateContent(dataUri);
108
+
109
+ expect(result).toBe(testCert);
110
+ });
111
+
112
+ test("CertsCache.getCachedCustomCert should cache and return certificate content", async () => {
113
+ const certsCache = CertsCache.getInstance();
114
+ const filePath = "/path/to/custom/cert.pem";
115
+ const expectedContent = "custom cert content";
116
+
117
+ mockReadFileSync.mockReturnValue(expectedContent);
118
+
119
+ const cert1 = await certsCache.getCachedCustomCert(filePath);
120
+ expect(cert1).toBe(expectedContent);
121
+ expect(mockReadFileSync).toHaveBeenCalledTimes(1);
122
+ expect(mockReadFileSync).toHaveBeenCalledWith(filePath, "utf8");
123
+
124
+ // Call again to check if it's cached
125
+ const cert2 = await certsCache.getCachedCustomCert(filePath);
126
+ expect(cert2).toBe(expectedContent);
127
+ // readFileSync should not be called again
128
+ expect(mockReadFileSync).toHaveBeenCalledTimes(1);
129
+ });
130
+
131
+ test("CertsCache.getAllCachedCustomCerts should return all cached custom certs", async () => {
132
+ const certsCache = CertsCache.getInstance();
133
+ const filePaths = ["/path/to/cert1.pem", "/path/to/cert2.pem"];
134
+ const expectedContent1 = "content of cert1";
135
+ const expectedContent2 = "content of cert2";
136
+
137
+ mockReadFileSync.mockReturnValueOnce(expectedContent1);
138
+ mockReadFileSync.mockReturnValueOnce(expectedContent2);
139
+
140
+ const certs = await certsCache.getAllCachedCustomCerts(filePaths);
141
+ expect(certs).toEqual([expectedContent1, expectedContent2]);
142
+ expect(mockReadFileSync).toHaveBeenCalledTimes(2);
143
+ });
144
+
145
+ test("CertsCache.getCa should return combined CA when caBundlePath is provided", async () => {
146
+ const certsCache = CertsCache.getInstance();
147
+ const fixedCa = ["fixed CA cert"];
148
+ const customCertPath = "/path/to/custom/cert.pem";
149
+ const customCertContent = "custom cert content";
150
+
151
+ // Directly set _fixedCa to avoid initializing it with real data
152
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
153
+ // @ts-ignore
154
+ certsCache._fixedCa = fixedCa;
155
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
156
+ // @ts-ignore
157
+ certsCache._initialized = true;
158
+ mockReadFileSync.mockReturnValue(customCertContent);
159
+
160
+ const ca = await certsCache.getCa(customCertPath);
161
+ expect(ca).toEqual([...fixedCa, customCertContent]);
162
+ });
163
+
164
+ test("CertsCache.clear should clear custom certs and reset initialized flag", () => {
165
+ const certsCache = CertsCache.getInstance();
166
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
167
+ // @ts-ignore
168
+ certsCache._customCerts.set("key", "value");
169
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
170
+ // @ts-ignore
171
+ certsCache._initialized = true;
172
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
173
+ // @ts-ignore
174
+ certsCache._fixedCa = ["test"];
175
+
176
+ certsCache.clear();
177
+
178
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
179
+ // @ts-ignore
180
+ expect(certsCache._customCerts.size).toBe(0);
181
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
182
+ // @ts-ignore
183
+ expect(certsCache._initialized).toBe(false);
184
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
185
+ // @ts-ignore
186
+ expect(certsCache._fixedCa).toEqual([]);
187
+ });
package/src/certs.ts ADDED
@@ -0,0 +1,129 @@
1
+ import { globalAgent } from "https";
2
+ import * as fs from "node:fs";
3
+ import tls from "node:tls";
4
+
5
+ /**
6
+ * Extracts content from either a file path or data URI
7
+ */
8
+ export function getCertificateContent(input: string): string {
9
+ if (input.startsWith("data:")) {
10
+ // Parse data URI: data:[<mediatype>][;base64],<data>
11
+ const [header, data] = input.split(",");
12
+ if (header.includes("base64")) {
13
+ return Buffer.from(data, "base64").toString("utf8");
14
+ } else {
15
+ return decodeURIComponent(data);
16
+ }
17
+ } else {
18
+ // Assume it's a file path
19
+ return fs.readFileSync(input, "utf8");
20
+ }
21
+ }
22
+
23
+ export class CertsCache {
24
+ private static instance: CertsCache;
25
+ private _fixedCa: string[] = [];
26
+ private _initialized: boolean = false;
27
+ private _customCerts: Map<string, string> = new Map();
28
+
29
+ private constructor() {}
30
+
31
+ public static getInstance(): CertsCache {
32
+ if (!CertsCache.instance) {
33
+ CertsCache.instance = new CertsCache();
34
+ }
35
+ return CertsCache.instance;
36
+ }
37
+
38
+ get fixedCa(): string[] {
39
+ if (this._initialized) {
40
+ return this._fixedCa;
41
+ }
42
+
43
+ const globalCerts: string[] = [];
44
+ if (Boolean(process.env.IS_BINARY)) {
45
+ if (Array.isArray(globalAgent.options.ca)) {
46
+ globalCerts.push(
47
+ ...globalAgent.options.ca.map((cert) => cert.toString()),
48
+ );
49
+ } else if (typeof globalAgent.options.ca !== "undefined") {
50
+ globalCerts.push(globalAgent.options.ca.toString());
51
+ }
52
+ }
53
+
54
+ const extraCerts: string[] = [];
55
+ if (process.env.NODE_EXTRA_CA_CERTS) {
56
+ try {
57
+ const content = fs.readFileSync(
58
+ process.env.NODE_EXTRA_CA_CERTS,
59
+ "utf8",
60
+ );
61
+ extraCerts.push(content);
62
+ } catch (error) {
63
+ if (process.env.VERBOSE_FETCH) {
64
+ console.error(
65
+ `Error reading NODE_EXTRA_CA_CERTS file: ${process.env.NODE_EXTRA_CA_CERTS}`,
66
+ error,
67
+ );
68
+ }
69
+ }
70
+ }
71
+
72
+ this._fixedCa = Array.from(
73
+ new Set([...tls.rootCertificates, ...globalCerts, ...extraCerts]),
74
+ );
75
+ this._initialized = true;
76
+ return this._fixedCa;
77
+ }
78
+
79
+ async getCachedCustomCert(path: string): Promise<string | undefined> {
80
+ if (this._customCerts.has(path)) {
81
+ return this._customCerts.get(path);
82
+ }
83
+ const certContent = getCertificateContent(path);
84
+ this._customCerts.set(path, certContent);
85
+ return certContent;
86
+ }
87
+
88
+ async getAllCachedCustomCerts(
89
+ caBundlePath: string[] | string,
90
+ ): Promise<string[]> {
91
+ const paths = Array.isArray(caBundlePath) ? caBundlePath : [caBundlePath];
92
+ const certs: string[] = [];
93
+ await Promise.all(
94
+ paths.map(async (path) => {
95
+ try {
96
+ const certContent = await this.getCachedCustomCert(path);
97
+ if (certContent) {
98
+ certs.push(certContent);
99
+ } else if (process.env.VERBOSE_FETCH) {
100
+ console.warn(`Empty certificate found at ${path}`);
101
+ }
102
+ } catch (error) {
103
+ if (process.env.VERBOSE_FETCH) {
104
+ console.error(
105
+ `Error loading custom certificate from ${path}:`,
106
+ error,
107
+ );
108
+ }
109
+ }
110
+ }),
111
+ );
112
+ return certs;
113
+ }
114
+
115
+ async getCa(caBundlePath: undefined | string | string[]): Promise<string[]> {
116
+ if (!caBundlePath) {
117
+ return this.fixedCa;
118
+ }
119
+
120
+ const customCerts = await this.getAllCachedCustomCerts(caBundlePath);
121
+ return [...this.fixedCa, ...customCerts];
122
+ }
123
+
124
+ async clear(): Promise<void> {
125
+ this._customCerts.clear();
126
+ this._initialized = false;
127
+ this._fixedCa = [];
128
+ }
129
+ }
package/src/fetch.ts CHANGED
@@ -2,9 +2,10 @@ import { RequestOptions } from "@continuedev/config-types";
2
2
  import * as followRedirects from "follow-redirects";
3
3
  import { HttpProxyAgent } from "http-proxy-agent";
4
4
  import { HttpsProxyAgent } from "https-proxy-agent";
5
- import fetch, { BodyInit, RequestInit, Response } from "node-fetch";
5
+ import { BodyInit, RequestInit, Response } from "node-fetch";
6
6
  import { getAgentOptions } from "./getAgentOptions.js";
7
- import { getProxyFromEnv, shouldBypassProxy } from "./util.js";
7
+ import patchedFetch from "./node-fetch-patch.js";
8
+ import { getProxy, shouldBypassProxy } from "./util.js";
8
9
 
9
10
  const { http, https } = (followRedirects as any).default;
10
11
 
@@ -88,18 +89,13 @@ export async function fetchwithRequestOptions(
88
89
  url.host = "127.0.0.1";
89
90
  }
90
91
 
91
- const agentOptions = getAgentOptions(requestOptions);
92
+ const agentOptions = await getAgentOptions(requestOptions);
92
93
 
93
94
  // Get proxy from options or environment variables
94
- let proxy = requestOptions?.proxy;
95
- if (!proxy) {
96
- proxy = getProxyFromEnv(url.protocol);
97
- }
95
+ const proxy = getProxy(url.protocol, requestOptions);
98
96
 
99
97
  // Check if should bypass proxy based on requestOptions or NO_PROXY env var
100
- const shouldBypass =
101
- requestOptions?.noProxy?.includes(url.hostname) ||
102
- shouldBypassProxy(url.hostname);
98
+ const shouldBypass = shouldBypassProxy(url.hostname, requestOptions);
103
99
 
104
100
  // Create agent
105
101
  const protocol = url.protocol === "https:" ? https : http;
@@ -148,7 +144,7 @@ export async function fetchwithRequestOptions(
148
144
 
149
145
  // fetch the request with the provided options
150
146
  try {
151
- const resp = await fetch(url, {
147
+ const resp = await patchedFetch(url, {
152
148
  ...init,
153
149
  body: finalBody,
154
150
  headers: headers,