@mswjs/interceptors 0.31.1 → 0.32.1
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/README.md +56 -39
- package/lib/node/RemoteHttpInterceptor.d.ts +1 -2
- package/lib/node/RemoteHttpInterceptor.js +11 -11
- package/lib/node/RemoteHttpInterceptor.mjs +5 -5
- package/lib/node/{chunk-LTEXDYJ6.js → chunk-2COJKQQB.js} +3 -3
- package/lib/node/chunk-3OJLYEWA.mjs +963 -0
- package/lib/node/chunk-3OJLYEWA.mjs.map +1 -0
- package/lib/node/chunk-5JMJ55U7.js +963 -0
- package/lib/node/chunk-5JMJ55U7.js.map +1 -0
- package/lib/node/{chunk-E4AC7YAC.js → chunk-BFLYGQ6D.js} +4 -2
- package/lib/node/{chunk-KSHIDGUL.mjs → chunk-DV4PBH4D.mjs} +3 -3
- package/lib/node/{chunk-OUWBQF3Z.mjs → chunk-KWV3JXSI.mjs} +14 -14
- package/lib/node/chunk-KWV3JXSI.mjs.map +1 -0
- package/lib/node/{chunk-6FRASLM3.mjs → chunk-PNWPIDEL.mjs} +2 -2
- package/lib/node/{chunk-APT7KA3B.js → chunk-PYD4E2EJ.js} +13 -13
- package/lib/node/{chunk-Q7POAM5N.mjs → chunk-TGTPXCLF.mjs} +3 -1
- package/lib/node/{chunk-MQJ3JOOK.js → chunk-UXCYRE4F.js} +14 -14
- package/lib/node/chunk-UXCYRE4F.js.map +1 -0
- package/lib/node/index.js +3 -3
- package/lib/node/index.mjs +2 -2
- package/lib/node/interceptors/ClientRequest/index.d.ts +83 -14
- package/lib/node/interceptors/ClientRequest/index.js +4 -4
- package/lib/node/interceptors/ClientRequest/index.mjs +3 -3
- package/lib/node/interceptors/XMLHttpRequest/index.js +4 -4
- package/lib/node/interceptors/XMLHttpRequest/index.mjs +3 -3
- package/lib/node/interceptors/fetch/index.js +10 -10
- package/lib/node/interceptors/fetch/index.mjs +2 -2
- package/lib/node/presets/node.d.ts +2 -3
- package/lib/node/presets/node.js +6 -6
- package/lib/node/presets/node.mjs +4 -4
- package/package.json +2 -2
- package/src/interceptors/ClientRequest/MockHttpSocket.ts +595 -0
- package/src/interceptors/ClientRequest/agents.ts +78 -0
- package/src/interceptors/ClientRequest/index.test.ts +14 -12
- package/src/interceptors/ClientRequest/index.ts +200 -41
- package/src/interceptors/ClientRequest/utils/normalizeClientRequestArgs.test.ts +78 -98
- package/src/interceptors/ClientRequest/utils/normalizeClientRequestArgs.ts +40 -22
- package/src/interceptors/Socket/MockSocket.test.ts +264 -0
- package/src/interceptors/Socket/MockSocket.ts +59 -0
- package/src/interceptors/Socket/utils/baseUrlFromConnectionOptions.ts +26 -0
- package/src/interceptors/Socket/utils/normalizeSocketWriteArgs.test.ts +52 -0
- package/src/interceptors/Socket/utils/normalizeSocketWriteArgs.ts +33 -0
- package/src/interceptors/Socket/utils/parseRawHeaders.ts +10 -0
- package/lib/node/chunk-IS3CIGXU.js +0 -909
- package/lib/node/chunk-IS3CIGXU.js.map +0 -1
- package/lib/node/chunk-MQJ3JOOK.js.map +0 -1
- package/lib/node/chunk-OMOWHUE6.mjs +0 -909
- package/lib/node/chunk-OMOWHUE6.mjs.map +0 -1
- package/lib/node/chunk-OUWBQF3Z.mjs.map +0 -1
- package/src/interceptors/ClientRequest/NodeClientRequest.test.ts +0 -206
- package/src/interceptors/ClientRequest/NodeClientRequest.ts +0 -680
- package/src/interceptors/ClientRequest/http.get.ts +0 -30
- package/src/interceptors/ClientRequest/http.request.ts +0 -27
- package/src/interceptors/ClientRequest/utils/cloneIncomingMessage.test.ts +0 -26
- package/src/interceptors/ClientRequest/utils/cloneIncomingMessage.ts +0 -74
- package/src/interceptors/ClientRequest/utils/createRequest.test.ts +0 -144
- package/src/interceptors/ClientRequest/utils/createRequest.ts +0 -51
- package/src/interceptors/ClientRequest/utils/createResponse.test.ts +0 -53
- package/src/interceptors/ClientRequest/utils/createResponse.ts +0 -55
- package/src/interceptors/ClientRequest/utils/normalizeClientRequestEndArgs.test.ts +0 -41
- package/src/interceptors/ClientRequest/utils/normalizeClientRequestEndArgs.ts +0 -53
- package/src/interceptors/ClientRequest/utils/normalizeClientRequestWriteArgs.test.ts +0 -36
- package/src/interceptors/ClientRequest/utils/normalizeClientRequestWriteArgs.ts +0 -39
- /package/lib/node/{chunk-LTEXDYJ6.js.map → chunk-2COJKQQB.js.map} +0 -0
- /package/lib/node/{chunk-E4AC7YAC.js.map → chunk-BFLYGQ6D.js.map} +0 -0
- /package/lib/node/{chunk-KSHIDGUL.mjs.map → chunk-DV4PBH4D.mjs.map} +0 -0
- /package/lib/node/{chunk-6FRASLM3.mjs.map → chunk-PNWPIDEL.mjs.map} +0 -0
- /package/lib/node/{chunk-APT7KA3B.js.map → chunk-PYD4E2EJ.js.map} +0 -0
- /package/lib/node/{chunk-Q7POAM5N.mjs.map → chunk-TGTPXCLF.mjs.map} +0 -0
|
@@ -6,11 +6,10 @@ import { getUrlByRequestOptions } from '../../../utils/getUrlByRequestOptions'
|
|
|
6
6
|
import { normalizeClientRequestArgs } from './normalizeClientRequestArgs'
|
|
7
7
|
|
|
8
8
|
it('handles [string, callback] input', () => {
|
|
9
|
-
const [url, options, callback] = normalizeClientRequestArgs(
|
|
10
|
-
'https:',
|
|
9
|
+
const [url, options, callback] = normalizeClientRequestArgs('https:', [
|
|
11
10
|
'https://mswjs.io/resource',
|
|
12
|
-
function cb() {}
|
|
13
|
-
)
|
|
11
|
+
function cb() {},
|
|
12
|
+
])
|
|
14
13
|
|
|
15
14
|
// URL string must be converted to a URL instance.
|
|
16
15
|
expect(url.href).toEqual('https://mswjs.io/resource')
|
|
@@ -31,12 +30,11 @@ it('handles [string, RequestOptions, callback] input', () => {
|
|
|
31
30
|
'Content-Type': 'text/plain',
|
|
32
31
|
},
|
|
33
32
|
}
|
|
34
|
-
const [url, options, callback] = normalizeClientRequestArgs(
|
|
35
|
-
'https:',
|
|
33
|
+
const [url, options, callback] = normalizeClientRequestArgs('https:', [
|
|
36
34
|
'https://mswjs.io/resource',
|
|
37
35
|
initialOptions,
|
|
38
|
-
function cb() {}
|
|
39
|
-
)
|
|
36
|
+
function cb() {},
|
|
37
|
+
])
|
|
40
38
|
|
|
41
39
|
// URL must be created from the string.
|
|
42
40
|
expect(url.href).toEqual('https://mswjs.io/resource')
|
|
@@ -49,11 +47,10 @@ it('handles [string, RequestOptions, callback] input', () => {
|
|
|
49
47
|
})
|
|
50
48
|
|
|
51
49
|
it('handles [URL, callback] input', () => {
|
|
52
|
-
const [url, options, callback] = normalizeClientRequestArgs(
|
|
53
|
-
'https:',
|
|
50
|
+
const [url, options, callback] = normalizeClientRequestArgs('https:', [
|
|
54
51
|
new URL('https://mswjs.io/resource'),
|
|
55
|
-
function cb() {}
|
|
56
|
-
)
|
|
52
|
+
function cb() {},
|
|
53
|
+
])
|
|
57
54
|
|
|
58
55
|
// URL must be preserved.
|
|
59
56
|
expect(url.href).toEqual('https://mswjs.io/resource')
|
|
@@ -69,11 +66,10 @@ it('handles [URL, callback] input', () => {
|
|
|
69
66
|
})
|
|
70
67
|
|
|
71
68
|
it('handles [Absolute Legacy URL, callback] input', () => {
|
|
72
|
-
const [url, options, callback] = normalizeClientRequestArgs(
|
|
73
|
-
'https:',
|
|
69
|
+
const [url, options, callback] = normalizeClientRequestArgs('https:', [
|
|
74
70
|
parse('https://cherry:durian@mswjs.io:12345/resource?apple=banana'),
|
|
75
|
-
function cb() {}
|
|
76
|
-
)
|
|
71
|
+
function cb() {},
|
|
72
|
+
])
|
|
77
73
|
|
|
78
74
|
// URL must be preserved.
|
|
79
75
|
expect(url.toJSON()).toEqual(
|
|
@@ -95,12 +91,11 @@ it('handles [Absolute Legacy URL, callback] input', () => {
|
|
|
95
91
|
})
|
|
96
92
|
|
|
97
93
|
it('handles [Relative Legacy URL, RequestOptions without path set, callback] input', () => {
|
|
98
|
-
const [url, options, callback] = normalizeClientRequestArgs(
|
|
99
|
-
'http:',
|
|
94
|
+
const [url, options, callback] = normalizeClientRequestArgs('http:', [
|
|
100
95
|
parse('/resource?apple=banana'),
|
|
101
96
|
{ host: 'mswjs.io' },
|
|
102
|
-
function cb() {}
|
|
103
|
-
)
|
|
97
|
+
function cb() {},
|
|
98
|
+
])
|
|
104
99
|
|
|
105
100
|
// Correct WHATWG URL generated.
|
|
106
101
|
expect(url.toJSON()).toEqual(
|
|
@@ -117,12 +112,11 @@ it('handles [Relative Legacy URL, RequestOptions without path set, callback] inp
|
|
|
117
112
|
})
|
|
118
113
|
|
|
119
114
|
it('handles [Relative Legacy URL, RequestOptions with path set, callback] input', () => {
|
|
120
|
-
const [url, options, callback] = normalizeClientRequestArgs(
|
|
121
|
-
'http:',
|
|
115
|
+
const [url, options, callback] = normalizeClientRequestArgs('http:', [
|
|
122
116
|
parse('/resource?apple=banana'),
|
|
123
117
|
{ host: 'mswjs.io', path: '/other?cherry=durian' },
|
|
124
|
-
function cb() {}
|
|
125
|
-
)
|
|
118
|
+
function cb() {},
|
|
119
|
+
])
|
|
126
120
|
|
|
127
121
|
// Correct WHATWG URL generated.
|
|
128
122
|
expect(url.toJSON()).toEqual(
|
|
@@ -139,11 +133,10 @@ it('handles [Relative Legacy URL, RequestOptions with path set, callback] input'
|
|
|
139
133
|
})
|
|
140
134
|
|
|
141
135
|
it('handles [Relative Legacy URL, callback] input', () => {
|
|
142
|
-
const [url, options, callback] = normalizeClientRequestArgs(
|
|
143
|
-
'http:',
|
|
136
|
+
const [url, options, callback] = normalizeClientRequestArgs('http:', [
|
|
144
137
|
parse('/resource?apple=banana'),
|
|
145
|
-
function cb() {}
|
|
146
|
-
)
|
|
138
|
+
function cb() {},
|
|
139
|
+
])
|
|
147
140
|
|
|
148
141
|
// Correct WHATWG URL generated.
|
|
149
142
|
expect(url.toJSON()).toMatch(
|
|
@@ -155,14 +148,14 @@ it('handles [Relative Legacy URL, callback] input', () => {
|
|
|
155
148
|
expect(options.path).toEqual('/resource?apple=banana')
|
|
156
149
|
|
|
157
150
|
// Callback must be preserved.
|
|
151
|
+
expect(callback).toBeTypeOf('function')
|
|
158
152
|
expect(callback?.name).toEqual('cb')
|
|
159
153
|
})
|
|
160
154
|
|
|
161
155
|
it('handles [Relative Legacy URL] input', () => {
|
|
162
|
-
const [url, options, callback] = normalizeClientRequestArgs(
|
|
163
|
-
'
|
|
164
|
-
|
|
165
|
-
)
|
|
156
|
+
const [url, options, callback] = normalizeClientRequestArgs('http:', [
|
|
157
|
+
parse('/resource?apple=banana'),
|
|
158
|
+
])
|
|
166
159
|
|
|
167
160
|
// Correct WHATWG URL generated.
|
|
168
161
|
expect(url.toJSON()).toMatch(
|
|
@@ -178,8 +171,7 @@ it('handles [Relative Legacy URL] input', () => {
|
|
|
178
171
|
})
|
|
179
172
|
|
|
180
173
|
it('handles [URL, RequestOptions, callback] input', () => {
|
|
181
|
-
const [url, options, callback] = normalizeClientRequestArgs(
|
|
182
|
-
'https:',
|
|
174
|
+
const [url, options, callback] = normalizeClientRequestArgs('https:', [
|
|
183
175
|
new URL('https://mswjs.io/resource'),
|
|
184
176
|
{
|
|
185
177
|
agent: false,
|
|
@@ -187,8 +179,8 @@ it('handles [URL, RequestOptions, callback] input', () => {
|
|
|
187
179
|
'Content-Type': 'text/plain',
|
|
188
180
|
},
|
|
189
181
|
},
|
|
190
|
-
function cb() {}
|
|
191
|
-
)
|
|
182
|
+
function cb() {},
|
|
183
|
+
])
|
|
192
184
|
|
|
193
185
|
// URL must be preserved.
|
|
194
186
|
expect(url.href).toEqual('https://mswjs.io/resource')
|
|
@@ -209,17 +201,17 @@ it('handles [URL, RequestOptions, callback] input', () => {
|
|
|
209
201
|
})
|
|
210
202
|
|
|
211
203
|
// Callback must be preserved.
|
|
204
|
+
expect(callback).toBeTypeOf('function')
|
|
212
205
|
expect(callback?.name).toEqual('cb')
|
|
213
206
|
})
|
|
214
207
|
|
|
215
208
|
it('handles [URL, RequestOptions] where options have custom "hostname"', () => {
|
|
216
|
-
const [url, options] = normalizeClientRequestArgs(
|
|
217
|
-
'http:',
|
|
209
|
+
const [url, options] = normalizeClientRequestArgs('http:', [
|
|
218
210
|
new URL('http://example.com/path-from-url'),
|
|
219
211
|
{
|
|
220
212
|
hostname: 'host-from-options.com',
|
|
221
|
-
}
|
|
222
|
-
)
|
|
213
|
+
},
|
|
214
|
+
])
|
|
223
215
|
expect(url.href).toBe('http://host-from-options.com/path-from-url')
|
|
224
216
|
expect(options).toMatchObject({
|
|
225
217
|
host: 'host-from-options.com',
|
|
@@ -228,15 +220,14 @@ it('handles [URL, RequestOptions] where options have custom "hostname"', () => {
|
|
|
228
220
|
})
|
|
229
221
|
|
|
230
222
|
it('handles [URL, RequestOptions] where options contain "host" and "path" and "port"', () => {
|
|
231
|
-
const [url, options] = normalizeClientRequestArgs(
|
|
232
|
-
'http:',
|
|
223
|
+
const [url, options] = normalizeClientRequestArgs('http:', [
|
|
233
224
|
new URL('http://example.com/path-from-url?a=b&c=d'),
|
|
234
225
|
{
|
|
235
226
|
hostname: 'host-from-options.com',
|
|
236
227
|
path: '/path-from-options',
|
|
237
228
|
port: 1234,
|
|
238
|
-
}
|
|
239
|
-
)
|
|
229
|
+
},
|
|
230
|
+
])
|
|
240
231
|
// Must remove the query string since it's not specified in "options.path"
|
|
241
232
|
expect(url.href).toBe('http://host-from-options.com:1234/path-from-options')
|
|
242
233
|
expect(options).toMatchObject({
|
|
@@ -247,13 +238,12 @@ it('handles [URL, RequestOptions] where options contain "host" and "path" and "p
|
|
|
247
238
|
})
|
|
248
239
|
|
|
249
240
|
it('handles [URL, RequestOptions] where options contain "path" with query string', () => {
|
|
250
|
-
const [url, options] = normalizeClientRequestArgs(
|
|
251
|
-
'http:',
|
|
241
|
+
const [url, options] = normalizeClientRequestArgs('http:', [
|
|
252
242
|
new URL('http://example.com/path-from-url?a=b&c=d'),
|
|
253
243
|
{
|
|
254
244
|
path: '/path-from-options?foo=bar&baz=xyz',
|
|
255
|
-
}
|
|
256
|
-
)
|
|
245
|
+
},
|
|
246
|
+
])
|
|
257
247
|
expect(url.href).toBe('http://example.com/path-from-options?foo=bar&baz=xyz')
|
|
258
248
|
expect(options).toMatchObject({
|
|
259
249
|
host: 'example.com',
|
|
@@ -275,28 +265,27 @@ it('handles [RequestOptions, callback] input', () => {
|
|
|
275
265
|
'Content-Type': 'text/plain',
|
|
276
266
|
},
|
|
277
267
|
}
|
|
278
|
-
const [url, options, callback] = normalizeClientRequestArgs(
|
|
279
|
-
'https:',
|
|
268
|
+
const [url, options, callback] = normalizeClientRequestArgs('https:', [
|
|
280
269
|
initialOptions,
|
|
281
|
-
function cb() {}
|
|
282
|
-
)
|
|
270
|
+
function cb() {},
|
|
271
|
+
])
|
|
283
272
|
|
|
284
273
|
// URL must be derived from request options.
|
|
285
274
|
expect(url.href).toEqual('https://mswjs.io/resource')
|
|
286
275
|
|
|
287
276
|
// Request options must be preserved.
|
|
288
|
-
expect(options).
|
|
277
|
+
expect(options).toMatchObject(initialOptions)
|
|
289
278
|
|
|
290
279
|
// Callback must be preserved.
|
|
280
|
+
expect(callback).toBeTypeOf('function')
|
|
291
281
|
expect(callback?.name).toEqual('cb')
|
|
292
282
|
})
|
|
293
283
|
|
|
294
284
|
it('handles [Empty RequestOptions, callback] input', () => {
|
|
295
|
-
const [_, options, callback] = normalizeClientRequestArgs(
|
|
296
|
-
'https:',
|
|
285
|
+
const [_, options, callback] = normalizeClientRequestArgs('https:', [
|
|
297
286
|
{},
|
|
298
|
-
function cb() {}
|
|
299
|
-
)
|
|
287
|
+
function cb() {},
|
|
288
|
+
])
|
|
300
289
|
|
|
301
290
|
expect(options.protocol).toEqual('https:')
|
|
302
291
|
|
|
@@ -320,11 +309,10 @@ it('handles [PartialRequestOptions, callback] input', () => {
|
|
|
320
309
|
passphrase: undefined,
|
|
321
310
|
agent: false,
|
|
322
311
|
}
|
|
323
|
-
const [url, options, callback] = normalizeClientRequestArgs(
|
|
324
|
-
'https:',
|
|
312
|
+
const [url, options, callback] = normalizeClientRequestArgs('https:', [
|
|
325
313
|
initialOptions,
|
|
326
|
-
function cb() {}
|
|
327
|
-
)
|
|
314
|
+
function cb() {},
|
|
315
|
+
])
|
|
328
316
|
|
|
329
317
|
// URL must be derived from request options.
|
|
330
318
|
expect(url.toJSON()).toEqual(
|
|
@@ -332,20 +320,20 @@ it('handles [PartialRequestOptions, callback] input', () => {
|
|
|
332
320
|
)
|
|
333
321
|
|
|
334
322
|
// Request options must be preserved.
|
|
335
|
-
expect(options).
|
|
323
|
+
expect(options).toMatchObject(initialOptions)
|
|
336
324
|
|
|
337
325
|
// Options protocol must be inferred from the request issuing module.
|
|
338
326
|
expect(options.protocol).toEqual('https:')
|
|
339
327
|
|
|
340
328
|
// Callback must be preserved.
|
|
329
|
+
expect(callback).toBeTypeOf('function')
|
|
341
330
|
expect(callback?.name).toEqual('cb')
|
|
342
331
|
})
|
|
343
332
|
|
|
344
333
|
it('sets fallback Agent based on the URL protocol', () => {
|
|
345
|
-
const [url, options] = normalizeClientRequestArgs(
|
|
346
|
-
'https
|
|
347
|
-
|
|
348
|
-
)
|
|
334
|
+
const [url, options] = normalizeClientRequestArgs('https:', [
|
|
335
|
+
'https://github.com',
|
|
336
|
+
])
|
|
349
337
|
const agent = options.agent as HttpsAgent
|
|
350
338
|
|
|
351
339
|
expect(agent).toBeInstanceOf(HttpsAgent)
|
|
@@ -354,59 +342,54 @@ it('sets fallback Agent based on the URL protocol', () => {
|
|
|
354
342
|
})
|
|
355
343
|
|
|
356
344
|
it('does not set any fallback Agent given "agent: false" option', () => {
|
|
357
|
-
const [, options] = normalizeClientRequestArgs(
|
|
358
|
-
'https:',
|
|
345
|
+
const [, options] = normalizeClientRequestArgs('https:', [
|
|
359
346
|
'https://github.com',
|
|
360
|
-
{ agent: false }
|
|
361
|
-
)
|
|
347
|
+
{ agent: false },
|
|
348
|
+
])
|
|
362
349
|
|
|
363
350
|
expect(options.agent).toEqual(false)
|
|
364
351
|
})
|
|
365
352
|
|
|
366
353
|
it('sets the default Agent for HTTP request', () => {
|
|
367
|
-
const [, options] = normalizeClientRequestArgs(
|
|
368
|
-
'http:',
|
|
354
|
+
const [, options] = normalizeClientRequestArgs('http:', [
|
|
369
355
|
'http://github.com',
|
|
370
|
-
{}
|
|
371
|
-
)
|
|
356
|
+
{},
|
|
357
|
+
])
|
|
372
358
|
|
|
373
359
|
expect(options._defaultAgent).toEqual(httpGlobalAgent)
|
|
374
360
|
})
|
|
375
361
|
|
|
376
362
|
it('sets the default Agent for HTTPS request', () => {
|
|
377
|
-
const [, options] = normalizeClientRequestArgs(
|
|
378
|
-
'https:',
|
|
363
|
+
const [, options] = normalizeClientRequestArgs('https:', [
|
|
379
364
|
'https://github.com',
|
|
380
|
-
{}
|
|
381
|
-
)
|
|
365
|
+
{},
|
|
366
|
+
])
|
|
382
367
|
|
|
383
368
|
expect(options._defaultAgent).toEqual(httpsGlobalAgent)
|
|
384
369
|
})
|
|
385
370
|
|
|
386
371
|
it('preserves a custom default Agent when set', () => {
|
|
387
|
-
const [, options] = normalizeClientRequestArgs(
|
|
388
|
-
'https:',
|
|
372
|
+
const [, options] = normalizeClientRequestArgs('https:', [
|
|
389
373
|
'https://github.com',
|
|
390
374
|
{
|
|
391
375
|
/**
|
|
392
376
|
* @note Intentionally incorrect Agent for HTTPS request.
|
|
393
377
|
*/
|
|
394
378
|
_defaultAgent: httpGlobalAgent,
|
|
395
|
-
}
|
|
396
|
-
)
|
|
379
|
+
},
|
|
380
|
+
])
|
|
397
381
|
|
|
398
382
|
expect(options._defaultAgent).toEqual(httpGlobalAgent)
|
|
399
383
|
})
|
|
400
384
|
|
|
401
385
|
it('merges URL-based RequestOptions with the custom RequestOptions', () => {
|
|
402
|
-
const [url, options] = normalizeClientRequestArgs(
|
|
403
|
-
'https:',
|
|
386
|
+
const [url, options] = normalizeClientRequestArgs('https:', [
|
|
404
387
|
'https://github.com/graphql',
|
|
405
388
|
{
|
|
406
389
|
method: 'GET',
|
|
407
390
|
pfx: 'PFX_KEY',
|
|
408
|
-
}
|
|
409
|
-
)
|
|
391
|
+
},
|
|
392
|
+
])
|
|
410
393
|
|
|
411
394
|
expect(url.href).toEqual('https://github.com/graphql')
|
|
412
395
|
|
|
@@ -422,13 +405,12 @@ it('merges URL-based RequestOptions with the custom RequestOptions', () => {
|
|
|
422
405
|
})
|
|
423
406
|
|
|
424
407
|
it('respects custom "options.path" over URL path', () => {
|
|
425
|
-
const [url, options] = normalizeClientRequestArgs(
|
|
426
|
-
'http:',
|
|
408
|
+
const [url, options] = normalizeClientRequestArgs('http:', [
|
|
427
409
|
new URL('http://example.com/path-from-url'),
|
|
428
410
|
{
|
|
429
411
|
path: '/path-from-options',
|
|
430
|
-
}
|
|
431
|
-
)
|
|
412
|
+
},
|
|
413
|
+
])
|
|
432
414
|
|
|
433
415
|
expect(url.href).toBe('http://example.com/path-from-options')
|
|
434
416
|
expect(options.protocol).toBe('http:')
|
|
@@ -438,13 +420,12 @@ it('respects custom "options.path" over URL path', () => {
|
|
|
438
420
|
})
|
|
439
421
|
|
|
440
422
|
it('respects custom "options.path" over URL path with query string', () => {
|
|
441
|
-
const [url, options] = normalizeClientRequestArgs(
|
|
442
|
-
'http:',
|
|
423
|
+
const [url, options] = normalizeClientRequestArgs('http:', [
|
|
443
424
|
new URL('http://example.com/path-from-url?a=b&c=d'),
|
|
444
425
|
{
|
|
445
426
|
path: '/path-from-options',
|
|
446
|
-
}
|
|
447
|
-
)
|
|
427
|
+
},
|
|
428
|
+
])
|
|
448
429
|
|
|
449
430
|
// Must replace both the path and the query string.
|
|
450
431
|
expect(url.href).toBe('http://example.com/path-from-options')
|
|
@@ -455,10 +436,9 @@ it('respects custom "options.path" over URL path with query string', () => {
|
|
|
455
436
|
})
|
|
456
437
|
|
|
457
438
|
it('preserves URL query string', () => {
|
|
458
|
-
const [url, options] = normalizeClientRequestArgs(
|
|
459
|
-
'http
|
|
460
|
-
|
|
461
|
-
)
|
|
439
|
+
const [url, options] = normalizeClientRequestArgs('http:', [
|
|
440
|
+
new URL('http://example.com/resource?a=b&c=d'),
|
|
441
|
+
])
|
|
462
442
|
|
|
463
443
|
expect(url.href).toBe('http://example.com/resource?a=b&c=d')
|
|
464
444
|
expect(options.protocol).toBe('http:')
|
|
@@ -2,13 +2,23 @@ import {
|
|
|
2
2
|
Agent as HttpAgent,
|
|
3
3
|
globalAgent as httpGlobalAgent,
|
|
4
4
|
IncomingMessage,
|
|
5
|
-
} from 'http'
|
|
5
|
+
} from 'node:http'
|
|
6
6
|
import {
|
|
7
7
|
RequestOptions,
|
|
8
8
|
Agent as HttpsAgent,
|
|
9
9
|
globalAgent as httpsGlobalAgent,
|
|
10
|
-
} from 'https'
|
|
11
|
-
import {
|
|
10
|
+
} from 'node:https'
|
|
11
|
+
import {
|
|
12
|
+
/**
|
|
13
|
+
* @note Use the Node.js URL instead of the global URL
|
|
14
|
+
* because environments like JSDOM may override the global,
|
|
15
|
+
* breaking the compatibility with Node.js.
|
|
16
|
+
* @see https://github.com/node-fetch/node-fetch/issues/1376#issuecomment-966435555
|
|
17
|
+
*/
|
|
18
|
+
URL,
|
|
19
|
+
Url as LegacyURL,
|
|
20
|
+
parse as parseUrl,
|
|
21
|
+
} from 'node:url'
|
|
12
22
|
import { Logger } from '@open-draft/logger'
|
|
13
23
|
import { getRequestOptionsByUrl } from '../../../utils/getRequestOptionsByUrl'
|
|
14
24
|
import {
|
|
@@ -93,7 +103,7 @@ function resolveCallback(
|
|
|
93
103
|
export type NormalizedClientRequestArgs = [
|
|
94
104
|
url: URL,
|
|
95
105
|
options: ResolvedRequestOptions,
|
|
96
|
-
callback?: HttpRequestCallback
|
|
106
|
+
callback?: HttpRequestCallback,
|
|
97
107
|
]
|
|
98
108
|
|
|
99
109
|
/**
|
|
@@ -102,7 +112,7 @@ export type NormalizedClientRequestArgs = [
|
|
|
102
112
|
*/
|
|
103
113
|
export function normalizeClientRequestArgs(
|
|
104
114
|
defaultProtocol: string,
|
|
105
|
-
|
|
115
|
+
args: ClientRequestArgs
|
|
106
116
|
): NormalizedClientRequestArgs {
|
|
107
117
|
let url: URL
|
|
108
118
|
let options: ResolvedRequestOptions
|
|
@@ -172,16 +182,14 @@ export function normalizeClientRequestArgs(
|
|
|
172
182
|
logger.info('given legacy URL is relative (no hostname)')
|
|
173
183
|
|
|
174
184
|
return isObject(args[1])
|
|
175
|
-
? normalizeClientRequestArgs(
|
|
176
|
-
defaultProtocol,
|
|
185
|
+
? normalizeClientRequestArgs(defaultProtocol, [
|
|
177
186
|
{ path: legacyUrl.path, ...args[1] },
|
|
178
|
-
args[2]
|
|
179
|
-
)
|
|
180
|
-
: normalizeClientRequestArgs(
|
|
181
|
-
defaultProtocol,
|
|
187
|
+
args[2],
|
|
188
|
+
])
|
|
189
|
+
: normalizeClientRequestArgs(defaultProtocol, [
|
|
182
190
|
{ path: legacyUrl.path },
|
|
183
|
-
args[1] as HttpRequestCallback
|
|
184
|
-
)
|
|
191
|
+
args[1] as HttpRequestCallback,
|
|
192
|
+
])
|
|
185
193
|
}
|
|
186
194
|
|
|
187
195
|
logger.info('given legacy url is absolute')
|
|
@@ -190,20 +198,19 @@ export function normalizeClientRequestArgs(
|
|
|
190
198
|
const resolvedUrl = new URL(legacyUrl.href)
|
|
191
199
|
|
|
192
200
|
return args[1] === undefined
|
|
193
|
-
? normalizeClientRequestArgs(defaultProtocol, resolvedUrl)
|
|
201
|
+
? normalizeClientRequestArgs(defaultProtocol, [resolvedUrl])
|
|
194
202
|
: typeof args[1] === 'function'
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
)
|
|
203
|
+
? normalizeClientRequestArgs(defaultProtocol, [resolvedUrl, args[1]])
|
|
204
|
+
: normalizeClientRequestArgs(defaultProtocol, [
|
|
205
|
+
resolvedUrl,
|
|
206
|
+
args[1],
|
|
207
|
+
args[2],
|
|
208
|
+
])
|
|
202
209
|
}
|
|
203
210
|
// Handle a given "RequestOptions" object as-is
|
|
204
211
|
// and derive the URL instance from it.
|
|
205
212
|
else if (isObject(args[0])) {
|
|
206
|
-
options = args[0] as any
|
|
213
|
+
options = { ... args[0] as any }
|
|
207
214
|
logger.info('first argument is RequestOptions:', options)
|
|
208
215
|
|
|
209
216
|
// When handling a "RequestOptions" object without an explicit "protocol",
|
|
@@ -266,5 +273,16 @@ export function normalizeClientRequestArgs(
|
|
|
266
273
|
logger.info('successfully resolved options:', options)
|
|
267
274
|
logger.info('successfully resolved callback:', callback)
|
|
268
275
|
|
|
276
|
+
/**
|
|
277
|
+
* @note If the user-provided URL is not a valid URL in Node.js,
|
|
278
|
+
* (e.g. the one provided by the JSDOM polyfills), case it to
|
|
279
|
+
* string. Otherwise, this throws on Node.js incompatibility
|
|
280
|
+
* (`ERR_INVALID_ARG_TYPE` on the connection listener)
|
|
281
|
+
* @see https://github.com/node-fetch/node-fetch/issues/1376#issuecomment-966435555
|
|
282
|
+
*/
|
|
283
|
+
if (!(url instanceof URL)) {
|
|
284
|
+
url = (url as any).toString()
|
|
285
|
+
}
|
|
286
|
+
|
|
269
287
|
return [url, options, callback]
|
|
270
288
|
}
|