@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.
Files changed (69) hide show
  1. package/README.md +56 -39
  2. package/lib/node/RemoteHttpInterceptor.d.ts +1 -2
  3. package/lib/node/RemoteHttpInterceptor.js +11 -11
  4. package/lib/node/RemoteHttpInterceptor.mjs +5 -5
  5. package/lib/node/{chunk-LTEXDYJ6.js → chunk-2COJKQQB.js} +3 -3
  6. package/lib/node/chunk-3OJLYEWA.mjs +963 -0
  7. package/lib/node/chunk-3OJLYEWA.mjs.map +1 -0
  8. package/lib/node/chunk-5JMJ55U7.js +963 -0
  9. package/lib/node/chunk-5JMJ55U7.js.map +1 -0
  10. package/lib/node/{chunk-E4AC7YAC.js → chunk-BFLYGQ6D.js} +4 -2
  11. package/lib/node/{chunk-KSHIDGUL.mjs → chunk-DV4PBH4D.mjs} +3 -3
  12. package/lib/node/{chunk-OUWBQF3Z.mjs → chunk-KWV3JXSI.mjs} +14 -14
  13. package/lib/node/chunk-KWV3JXSI.mjs.map +1 -0
  14. package/lib/node/{chunk-6FRASLM3.mjs → chunk-PNWPIDEL.mjs} +2 -2
  15. package/lib/node/{chunk-APT7KA3B.js → chunk-PYD4E2EJ.js} +13 -13
  16. package/lib/node/{chunk-Q7POAM5N.mjs → chunk-TGTPXCLF.mjs} +3 -1
  17. package/lib/node/{chunk-MQJ3JOOK.js → chunk-UXCYRE4F.js} +14 -14
  18. package/lib/node/chunk-UXCYRE4F.js.map +1 -0
  19. package/lib/node/index.js +3 -3
  20. package/lib/node/index.mjs +2 -2
  21. package/lib/node/interceptors/ClientRequest/index.d.ts +83 -14
  22. package/lib/node/interceptors/ClientRequest/index.js +4 -4
  23. package/lib/node/interceptors/ClientRequest/index.mjs +3 -3
  24. package/lib/node/interceptors/XMLHttpRequest/index.js +4 -4
  25. package/lib/node/interceptors/XMLHttpRequest/index.mjs +3 -3
  26. package/lib/node/interceptors/fetch/index.js +10 -10
  27. package/lib/node/interceptors/fetch/index.mjs +2 -2
  28. package/lib/node/presets/node.d.ts +2 -3
  29. package/lib/node/presets/node.js +6 -6
  30. package/lib/node/presets/node.mjs +4 -4
  31. package/package.json +2 -2
  32. package/src/interceptors/ClientRequest/MockHttpSocket.ts +595 -0
  33. package/src/interceptors/ClientRequest/agents.ts +78 -0
  34. package/src/interceptors/ClientRequest/index.test.ts +14 -12
  35. package/src/interceptors/ClientRequest/index.ts +200 -41
  36. package/src/interceptors/ClientRequest/utils/normalizeClientRequestArgs.test.ts +78 -98
  37. package/src/interceptors/ClientRequest/utils/normalizeClientRequestArgs.ts +40 -22
  38. package/src/interceptors/Socket/MockSocket.test.ts +264 -0
  39. package/src/interceptors/Socket/MockSocket.ts +59 -0
  40. package/src/interceptors/Socket/utils/baseUrlFromConnectionOptions.ts +26 -0
  41. package/src/interceptors/Socket/utils/normalizeSocketWriteArgs.test.ts +52 -0
  42. package/src/interceptors/Socket/utils/normalizeSocketWriteArgs.ts +33 -0
  43. package/src/interceptors/Socket/utils/parseRawHeaders.ts +10 -0
  44. package/lib/node/chunk-IS3CIGXU.js +0 -909
  45. package/lib/node/chunk-IS3CIGXU.js.map +0 -1
  46. package/lib/node/chunk-MQJ3JOOK.js.map +0 -1
  47. package/lib/node/chunk-OMOWHUE6.mjs +0 -909
  48. package/lib/node/chunk-OMOWHUE6.mjs.map +0 -1
  49. package/lib/node/chunk-OUWBQF3Z.mjs.map +0 -1
  50. package/src/interceptors/ClientRequest/NodeClientRequest.test.ts +0 -206
  51. package/src/interceptors/ClientRequest/NodeClientRequest.ts +0 -680
  52. package/src/interceptors/ClientRequest/http.get.ts +0 -30
  53. package/src/interceptors/ClientRequest/http.request.ts +0 -27
  54. package/src/interceptors/ClientRequest/utils/cloneIncomingMessage.test.ts +0 -26
  55. package/src/interceptors/ClientRequest/utils/cloneIncomingMessage.ts +0 -74
  56. package/src/interceptors/ClientRequest/utils/createRequest.test.ts +0 -144
  57. package/src/interceptors/ClientRequest/utils/createRequest.ts +0 -51
  58. package/src/interceptors/ClientRequest/utils/createResponse.test.ts +0 -53
  59. package/src/interceptors/ClientRequest/utils/createResponse.ts +0 -55
  60. package/src/interceptors/ClientRequest/utils/normalizeClientRequestEndArgs.test.ts +0 -41
  61. package/src/interceptors/ClientRequest/utils/normalizeClientRequestEndArgs.ts +0 -53
  62. package/src/interceptors/ClientRequest/utils/normalizeClientRequestWriteArgs.test.ts +0 -36
  63. package/src/interceptors/ClientRequest/utils/normalizeClientRequestWriteArgs.ts +0 -39
  64. /package/lib/node/{chunk-LTEXDYJ6.js.map → chunk-2COJKQQB.js.map} +0 -0
  65. /package/lib/node/{chunk-E4AC7YAC.js.map → chunk-BFLYGQ6D.js.map} +0 -0
  66. /package/lib/node/{chunk-KSHIDGUL.mjs.map → chunk-DV4PBH4D.mjs.map} +0 -0
  67. /package/lib/node/{chunk-6FRASLM3.mjs.map → chunk-PNWPIDEL.mjs.map} +0 -0
  68. /package/lib/node/{chunk-APT7KA3B.js.map → chunk-PYD4E2EJ.js.map} +0 -0
  69. /package/lib/node/{chunk-Q7POAM5N.mjs.map → chunk-TGTPXCLF.mjs.map} +0 -0
@@ -1,909 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
2
-
3
-
4
- var _chunkMQJ3JOOKjs = require('./chunk-MQJ3JOOK.js');
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
- var _chunkE4AC7YACjs = require('./chunk-E4AC7YAC.js');
13
-
14
- // src/interceptors/ClientRequest/index.ts
15
- var _http = require('http'); var _http2 = _interopRequireDefault(_http);
16
- var _https = require('https'); var _https2 = _interopRequireDefault(_https);
17
-
18
- // src/interceptors/ClientRequest/NodeClientRequest.ts
19
-
20
- var _until = require('@open-draft/until');
21
- var _deferredpromise = require('@open-draft/deferred-promise');
22
-
23
- // src/interceptors/ClientRequest/utils/normalizeClientRequestEndArgs.ts
24
- var _logger = require('@open-draft/logger');
25
- var logger = new (0, _logger.Logger)("utils getUrlByRequestOptions");
26
- function normalizeClientRequestEndArgs(...args) {
27
- logger.info("arguments", args);
28
- const normalizedArgs = new Array(3).fill(null).map((value, index) => args[index] || value);
29
- normalizedArgs.sort((a, b) => {
30
- if (typeof a === "function") {
31
- return 1;
32
- }
33
- if (typeof b === "function") {
34
- return -1;
35
- }
36
- if (typeof a === "string" && typeof b === "string") {
37
- return normalizedArgs.indexOf(a) - normalizedArgs.indexOf(b);
38
- }
39
- return 0;
40
- });
41
- logger.info("normalized args", normalizedArgs);
42
- return normalizedArgs;
43
- }
44
-
45
- // src/interceptors/ClientRequest/utils/normalizeClientRequestWriteArgs.ts
46
-
47
- var logger2 = new (0, _logger.Logger)("http normalizeWriteArgs");
48
- function normalizeClientRequestWriteArgs(args) {
49
- logger2.info("normalizing ClientRequest.write arguments...", args);
50
- const chunk = args[0];
51
- const encoding = typeof args[1] === "string" ? args[1] : void 0;
52
- const callback = typeof args[1] === "function" ? args[1] : args[2];
53
- const writeArgs = [
54
- chunk,
55
- encoding,
56
- callback
57
- ];
58
- logger2.info(
59
- "successfully normalized ClientRequest.write arguments:",
60
- writeArgs
61
- );
62
- return writeArgs;
63
- }
64
-
65
- // src/interceptors/ClientRequest/utils/cloneIncomingMessage.ts
66
-
67
- var _stream = require('stream');
68
- var IS_CLONE = Symbol("isClone");
69
- function cloneIncomingMessage(message) {
70
- const clone = message.pipe(new (0, _stream.PassThrough)());
71
- inheritProperties(message, clone);
72
- const clonedPrototype = Object.create(_http.IncomingMessage.prototype);
73
- getPrototypes(clone).forEach((prototype) => {
74
- inheritProperties(prototype, clonedPrototype);
75
- });
76
- Object.setPrototypeOf(clone, clonedPrototype);
77
- Object.defineProperty(clone, IS_CLONE, {
78
- enumerable: true,
79
- value: true
80
- });
81
- return clone;
82
- }
83
- function getPrototypes(source) {
84
- const prototypes = [];
85
- let current = source;
86
- while (current = Object.getPrototypeOf(current)) {
87
- prototypes.push(current);
88
- }
89
- return prototypes;
90
- }
91
- function inheritProperties(source, target) {
92
- const properties = [
93
- ...Object.getOwnPropertyNames(source),
94
- ...Object.getOwnPropertySymbols(source)
95
- ];
96
- for (const property of properties) {
97
- if (target.hasOwnProperty(property)) {
98
- continue;
99
- }
100
- const descriptor = Object.getOwnPropertyDescriptor(source, property);
101
- if (!descriptor) {
102
- continue;
103
- }
104
- Object.defineProperty(target, property, descriptor);
105
- }
106
- }
107
-
108
- // src/interceptors/ClientRequest/utils/createResponse.ts
109
- function createResponse(message) {
110
- const responseBodyOrNull = _chunkE4AC7YACjs.isResponseWithoutBody.call(void 0, message.statusCode || 200) ? null : new ReadableStream({
111
- start(controller) {
112
- message.on("data", (chunk) => controller.enqueue(chunk));
113
- message.on("end", () => controller.close());
114
- }
115
- });
116
- return new Response(responseBodyOrNull, {
117
- status: message.statusCode,
118
- statusText: message.statusMessage,
119
- headers: createHeadersFromIncomingHttpHeaders(message.headers)
120
- });
121
- }
122
- function createHeadersFromIncomingHttpHeaders(httpHeaders) {
123
- const headers = new Headers();
124
- for (const headerName in httpHeaders) {
125
- const headerValues = httpHeaders[headerName];
126
- if (typeof headerValues === "undefined") {
127
- continue;
128
- }
129
- if (Array.isArray(headerValues)) {
130
- headerValues.forEach((headerValue) => {
131
- headers.append(headerName, headerValue);
132
- });
133
- continue;
134
- }
135
- headers.set(headerName, headerValues);
136
- }
137
- return headers;
138
- }
139
-
140
- // src/interceptors/ClientRequest/utils/createRequest.ts
141
- function createRequest(clientRequest) {
142
- const headers = new Headers();
143
- const outgoingHeaders = clientRequest.getHeaders();
144
- for (const headerName in outgoingHeaders) {
145
- const headerValue = outgoingHeaders[headerName];
146
- if (typeof headerValue === "undefined") {
147
- continue;
148
- }
149
- const valuesList = Array.prototype.concat([], headerValue);
150
- for (const value of valuesList) {
151
- headers.append(headerName, value.toString());
152
- }
153
- }
154
- if (clientRequest.url.username || clientRequest.url.password) {
155
- const username = decodeURIComponent(clientRequest.url.username || "");
156
- const password = decodeURIComponent(clientRequest.url.password || "");
157
- const auth = `${username}:${password}`;
158
- headers.set("Authorization", `Basic ${btoa(auth)}`);
159
- clientRequest.url.username = "";
160
- clientRequest.url.password = "";
161
- }
162
- const method = clientRequest.method || "GET";
163
- return new Request(clientRequest.url, {
164
- method,
165
- headers,
166
- credentials: "same-origin",
167
- body: method === "HEAD" || method === "GET" ? null : clientRequest.requestBuffer
168
- });
169
- }
170
-
171
- // src/utils/getValueBySymbol.ts
172
- function getValueBySymbol(symbolName, source) {
173
- const ownSymbols = Object.getOwnPropertySymbols(source);
174
- const symbol = ownSymbols.find((symbol2) => {
175
- return symbol2.description === symbolName;
176
- });
177
- if (symbol) {
178
- return Reflect.get(source, symbol);
179
- }
180
- return;
181
- }
182
-
183
- // src/utils/isObject.ts
184
- function isObject(value, loose = false) {
185
- return loose ? Object.prototype.toString.call(value).startsWith("[object ") : Object.prototype.toString.call(value) === "[object Object]";
186
- }
187
-
188
- // src/utils/getRawFetchHeaders.ts
189
- function getRawFetchHeaders(headers) {
190
- const headersList = getValueBySymbol("headers list", headers);
191
- if (!headersList) {
192
- return;
193
- }
194
- const headersMap = getValueBySymbol("headers map", headersList);
195
- if (!headersMap || !isHeadersMapWithRawHeaderNames(headersMap)) {
196
- return;
197
- }
198
- const rawHeaders = /* @__PURE__ */ new Map();
199
- headersMap.forEach(({ name, value }) => {
200
- rawHeaders.set(name, value);
201
- });
202
- return rawHeaders;
203
- }
204
- function isHeadersMapWithRawHeaderNames(headersMap) {
205
- return Array.from(
206
- headersMap.values()
207
- ).every((value) => {
208
- return isObject(value) && "name" in value;
209
- });
210
- }
211
-
212
- // src/utils/isNodeLikeError.ts
213
- function isNodeLikeError(error) {
214
- if (error == null) {
215
- return false;
216
- }
217
- if (!(error instanceof Error)) {
218
- return false;
219
- }
220
- return "code" in error && "errno" in error;
221
- }
222
-
223
- // src/interceptors/ClientRequest/NodeClientRequest.ts
224
- var _NodeClientRequest = class extends _http.ClientRequest {
225
- constructor([url, requestOptions, callback], options) {
226
- super(requestOptions, callback);
227
- this.chunks = [];
228
- this.logger = options.logger.extend(
229
- `request ${requestOptions.method} ${url.href}`
230
- );
231
- this.logger.info("constructing ClientRequest using options:", {
232
- url,
233
- requestOptions,
234
- callback
235
- });
236
- this.state = 0 /* Idle */;
237
- this.url = url;
238
- this.emitter = options.emitter;
239
- this.requestBuffer = null;
240
- this.response = new (0, _http.IncomingMessage)(this.socket);
241
- }
242
- writeRequestBodyChunk(chunk, encoding) {
243
- if (chunk == null) {
244
- return;
245
- }
246
- if (this.requestBuffer == null) {
247
- this.requestBuffer = Buffer.from([]);
248
- }
249
- const resolvedChunk = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, encoding);
250
- this.requestBuffer = Buffer.concat([this.requestBuffer, resolvedChunk]);
251
- }
252
- write(...args) {
253
- var _a;
254
- const [chunk, encoding, callback] = normalizeClientRequestWriteArgs(args);
255
- this.logger.info("write:", { chunk, encoding, callback });
256
- this.chunks.push({ chunk, encoding });
257
- this.writeRequestBodyChunk(chunk, encoding);
258
- this.logger.info(
259
- "chunk successfully stored!",
260
- (_a = this.requestBuffer) == null ? void 0 : _a.byteLength
261
- );
262
- if (!chunk || chunk.length === 0) {
263
- this.logger.info("written chunk is empty, skipping callback...");
264
- } else {
265
- callback == null ? void 0 : callback();
266
- }
267
- return true;
268
- }
269
- end(...args) {
270
- this.logger.info("end", args);
271
- const requestId = _chunkE4AC7YACjs.createRequestId.call(void 0, );
272
- const [chunk, encoding, callback] = normalizeClientRequestEndArgs(...args);
273
- this.logger.info("normalized arguments:", { chunk, encoding, callback });
274
- this.writeRequestBodyChunk(chunk, encoding || void 0);
275
- this.state = 2 /* Sent */;
276
- const capturedRequest = createRequest(this);
277
- const { interactiveRequest, requestController } = _chunkMQJ3JOOKjs.toInteractiveRequest.call(void 0, capturedRequest);
278
- Object.defineProperty(capturedRequest, "respondWith", {
279
- value: requestController.respondWith.bind(requestController)
280
- });
281
- if (this.hasHeader(_chunkE4AC7YACjs.INTERNAL_REQUEST_ID_HEADER_NAME)) {
282
- this.removeHeader(_chunkE4AC7YACjs.INTERNAL_REQUEST_ID_HEADER_NAME);
283
- return this.passthrough(chunk, encoding, callback);
284
- }
285
- this.emitter.once("request", ({ requestId: pendingRequestId }) => {
286
- if (pendingRequestId !== requestId) {
287
- return;
288
- }
289
- if (requestController.responsePromise.state === "pending") {
290
- this.logger.info(
291
- "request has not been handled in listeners, executing fail-safe listener..."
292
- );
293
- requestController.responsePromise.resolve(void 0);
294
- }
295
- });
296
- _until.until.call(void 0, async () => {
297
- this.logger.info(
298
- 'emitting the "request" event for %d listener(s)...',
299
- this.emitter.listenerCount("request")
300
- );
301
- this.state = 3 /* MockLookupStart */;
302
- await _chunkMQJ3JOOKjs.emitAsync.call(void 0, this.emitter, "request", {
303
- request: interactiveRequest,
304
- requestId
305
- });
306
- this.logger.info('all "request" listeners done!');
307
- const mockedResponse = await requestController.responsePromise;
308
- this.logger.info("event.respondWith called with:", mockedResponse);
309
- return mockedResponse;
310
- }).then((resolverResult) => {
311
- this.logger.info("the listeners promise awaited!");
312
- this.state = 4 /* MockLookupEnd */;
313
- if (!this.headersSent) {
314
- for (const [headerName, headerValue] of capturedRequest.headers) {
315
- this.setHeader(headerName, headerValue);
316
- }
317
- }
318
- if (resolverResult.error) {
319
- this.logger.info(
320
- "unhandled resolver exception, coercing to an error response...",
321
- resolverResult.error
322
- );
323
- if (resolverResult.error instanceof Response) {
324
- if (_chunkE4AC7YACjs.isResponseError.call(void 0, resolverResult.error)) {
325
- this.logger.info(
326
- "received network error response, erroring request..."
327
- );
328
- this.errorWith(new TypeError("Network error"));
329
- } else {
330
- this.respondWith(resolverResult.error);
331
- }
332
- return;
333
- }
334
- if (isNodeLikeError(resolverResult.error)) {
335
- this.errorWith(resolverResult.error);
336
- return this;
337
- }
338
- _until.until.call(void 0, async () => {
339
- if (this.emitter.listenerCount("unhandledException") > 0) {
340
- await _chunkMQJ3JOOKjs.emitAsync.call(void 0, this.emitter, "unhandledException", {
341
- error: resolverResult.error,
342
- request: capturedRequest,
343
- requestId,
344
- controller: {
345
- respondWith: this.respondWith.bind(this),
346
- errorWith: this.errorWith.bind(this)
347
- }
348
- });
349
- if (this.writableEnded || this.destroyed) {
350
- return;
351
- }
352
- }
353
- this.respondWith(_chunkE4AC7YACjs.createServerErrorResponse.call(void 0, resolverResult.error));
354
- });
355
- return this;
356
- }
357
- const mockedResponse = resolverResult.data;
358
- if (mockedResponse) {
359
- this.logger.info(
360
- "received mocked response:",
361
- mockedResponse.status,
362
- mockedResponse.statusText
363
- );
364
- this.destroyed = false;
365
- if (_chunkE4AC7YACjs.isResponseError.call(void 0, mockedResponse)) {
366
- this.logger.info(
367
- "received network error response, erroring request..."
368
- );
369
- this.errorWith(new TypeError("Network error"));
370
- return this;
371
- }
372
- const responseClone = mockedResponse.clone();
373
- this.respondWith(mockedResponse);
374
- this.logger.info(
375
- mockedResponse.status,
376
- mockedResponse.statusText,
377
- "(MOCKED)"
378
- );
379
- callback == null ? void 0 : callback();
380
- this.logger.info('emitting the custom "response" event...');
381
- const responseListenersPromise = _chunkMQJ3JOOKjs.emitAsync.call(void 0, this.emitter, "response", {
382
- response: responseClone,
383
- isMockedResponse: true,
384
- request: capturedRequest,
385
- requestId
386
- });
387
- responseListenersPromise.then(() => {
388
- this.logger.info("request (mock) is completed");
389
- });
390
- this.deferResponseEndUntil(responseListenersPromise, this.response);
391
- return this;
392
- }
393
- this.logger.info("no mocked response received!");
394
- this.once(
395
- "response-internal",
396
- (message, originalMessage) => {
397
- this.logger.info(message.statusCode, message.statusMessage);
398
- this.logger.info("original response headers:", message.headers);
399
- this.logger.info('emitting the custom "response" event...');
400
- const responseListenersPromise = _chunkMQJ3JOOKjs.emitAsync.call(void 0, this.emitter, "response", {
401
- response: createResponse(message),
402
- isMockedResponse: false,
403
- request: capturedRequest,
404
- requestId
405
- });
406
- this.deferResponseEndUntil(responseListenersPromise, originalMessage);
407
- }
408
- );
409
- return this.passthrough(chunk, encoding, callback);
410
- });
411
- return this;
412
- }
413
- emit(event, ...data) {
414
- this.logger.info("emit: %s", event);
415
- if (event === "response") {
416
- this.logger.info('found "response" event, cloning the response...');
417
- try {
418
- const response = data[0];
419
- const firstClone = cloneIncomingMessage(response);
420
- const secondClone = cloneIncomingMessage(response);
421
- this.emit("response-internal", secondClone, firstClone);
422
- this.logger.info(
423
- 'response successfully cloned, emitting "response" event...'
424
- );
425
- return super.emit(event, firstClone, ...data.slice(1));
426
- } catch (error) {
427
- this.logger.info("error when cloning response:", error);
428
- return super.emit(event, ...data);
429
- }
430
- }
431
- if (event === "error") {
432
- const error = data[0];
433
- const errorCode = error.code || "";
434
- this.logger.info("error:\n", error);
435
- if (_NodeClientRequest.suppressErrorCodes.includes(errorCode)) {
436
- if (this.state < 4 /* MockLookupEnd */) {
437
- if (!this.capturedError) {
438
- this.capturedError = error;
439
- this.logger.info("captured the first error:", this.capturedError);
440
- }
441
- return false;
442
- }
443
- if (this.state === 5 /* ResponseReceived */ && this.responseType === "mock") {
444
- return false;
445
- }
446
- }
447
- }
448
- return super.emit(event, ...data);
449
- }
450
- /**
451
- * Performs the intercepted request as-is.
452
- * Replays the captured request body chunks,
453
- * still emits the internal events, and wraps
454
- * up the request with `super.end()`.
455
- */
456
- passthrough(chunk, encoding, callback) {
457
- this.state = 5 /* ResponseReceived */;
458
- this.responseType = "passthrough";
459
- if (this.capturedError) {
460
- this.emit("error", this.capturedError);
461
- return this;
462
- }
463
- this.logger.info("writing request chunks...", this.chunks);
464
- for (const { chunk: chunk2, encoding: encoding2 } of this.chunks) {
465
- if (encoding2) {
466
- super.write(chunk2, encoding2);
467
- } else {
468
- super.write(chunk2);
469
- }
470
- }
471
- this.once("error", (error) => {
472
- this.logger.info("original request error:", error);
473
- });
474
- this.once("abort", () => {
475
- this.logger.info("original request aborted!");
476
- });
477
- this.once("response-internal", (message) => {
478
- this.logger.info(message.statusCode, message.statusMessage);
479
- this.logger.info("original response headers:", message.headers);
480
- });
481
- this.logger.info("performing original request...");
482
- return super.end(...[chunk, encoding, callback].filter(Boolean));
483
- }
484
- /**
485
- * Responds to this request instance using a mocked response.
486
- */
487
- respondWith(mockedResponse) {
488
- this.logger.info("responding with a mocked response...", mockedResponse);
489
- this.state = 5 /* ResponseReceived */;
490
- this.responseType = "mock";
491
- Object.defineProperties(this, {
492
- writableFinished: { value: true },
493
- writableEnded: { value: true }
494
- });
495
- this.emit("finish");
496
- const { status, statusText, headers, body } = mockedResponse;
497
- this.response.statusCode = status;
498
- this.response.statusMessage = statusText || _http.STATUS_CODES[status];
499
- const rawHeaders = getRawFetchHeaders(headers) || headers;
500
- if (rawHeaders) {
501
- this.response.headers = {};
502
- rawHeaders.forEach((headerValue, headerName) => {
503
- this.response.rawHeaders.push(headerName, headerValue);
504
- const insensitiveHeaderName = headerName.toLowerCase();
505
- const prevHeaders = this.response.headers[insensitiveHeaderName];
506
- this.response.headers[insensitiveHeaderName] = prevHeaders ? Array.prototype.concat([], prevHeaders, headerValue) : headerValue;
507
- });
508
- }
509
- this.logger.info("mocked response headers ready:", headers);
510
- this.res = this.response;
511
- this.emit("response", this.response);
512
- const isResponseStreamFinished = new (0, _deferredpromise.DeferredPromise)();
513
- const finishResponseStream = () => {
514
- this.logger.info("finished response stream!");
515
- this.response.push(null);
516
- this.response.complete = true;
517
- isResponseStreamFinished.resolve();
518
- };
519
- if (body) {
520
- const bodyReader = body.getReader();
521
- const readNextChunk = async () => {
522
- const { done, value } = await bodyReader.read();
523
- if (done) {
524
- finishResponseStream();
525
- return;
526
- }
527
- this.response.emit("data", value);
528
- return readNextChunk();
529
- };
530
- readNextChunk();
531
- } else {
532
- finishResponseStream();
533
- }
534
- isResponseStreamFinished.then(() => {
535
- this.logger.info("finalizing response...");
536
- this.response.emit("end");
537
- this.terminate();
538
- this.logger.info("request complete!");
539
- });
540
- }
541
- errorWith(error) {
542
- this.destroyed = true;
543
- this.emit("error", error);
544
- this.terminate();
545
- }
546
- /**
547
- * Terminates a pending request.
548
- */
549
- terminate() {
550
- var _a, _b;
551
- (_b = (_a = this.agent) == null ? void 0 : _a.destroy) == null ? void 0 : _b.call(_a);
552
- }
553
- deferResponseEndUntil(promise, response) {
554
- response.emit = new Proxy(response.emit, {
555
- apply: (target, thisArg, args) => {
556
- const [event] = args;
557
- const callEmit = () => Reflect.apply(target, thisArg, args);
558
- if (event === "end") {
559
- promise.finally(() => callEmit());
560
- return this.listenerCount("end") > 0;
561
- }
562
- return callEmit();
563
- }
564
- });
565
- }
566
- };
567
- var NodeClientRequest = _NodeClientRequest;
568
- /**
569
- * The list of internal Node.js errors to suppress while
570
- * using the "mock" response source.
571
- */
572
- NodeClientRequest.suppressErrorCodes = [
573
- "ENOTFOUND",
574
- "ECONNREFUSED",
575
- "ECONNRESET",
576
- "EAI_AGAIN",
577
- "ENETUNREACH",
578
- "EHOSTUNREACH"
579
- ];
580
-
581
- // src/interceptors/ClientRequest/utils/normalizeClientRequestArgs.ts
582
-
583
-
584
-
585
-
586
-
587
-
588
-
589
-
590
- var _url = require('url');
591
-
592
-
593
- // src/utils/getRequestOptionsByUrl.ts
594
- function getRequestOptionsByUrl(url) {
595
- const options = {
596
- method: "GET",
597
- protocol: url.protocol,
598
- hostname: typeof url.hostname === "string" && url.hostname.startsWith("[") ? url.hostname.slice(1, -1) : url.hostname,
599
- host: url.host,
600
- path: `${url.pathname}${url.search || ""}`
601
- };
602
- if (!!url.port) {
603
- options.port = Number(url.port);
604
- }
605
- if (url.username || url.password) {
606
- options.auth = `${url.username}:${url.password}`;
607
- }
608
- return options;
609
- }
610
-
611
- // src/utils/getUrlByRequestOptions.ts
612
-
613
-
614
- var logger3 = new (0, _logger.Logger)("utils getUrlByRequestOptions");
615
- var DEFAULT_PATH = "/";
616
- var DEFAULT_PROTOCOL = "http:";
617
- var DEFAULT_HOSTNAME = "localhost";
618
- var SSL_PORT = 443;
619
- function getAgent(options) {
620
- return options.agent instanceof _http.Agent ? options.agent : void 0;
621
- }
622
- function getProtocolByRequestOptions(options) {
623
- var _a;
624
- if (options.protocol) {
625
- return options.protocol;
626
- }
627
- const agent = getAgent(options);
628
- const agentProtocol = agent == null ? void 0 : agent.protocol;
629
- if (agentProtocol) {
630
- return agentProtocol;
631
- }
632
- const port = getPortByRequestOptions(options);
633
- const isSecureRequest = options.cert || port === SSL_PORT;
634
- return isSecureRequest ? "https:" : ((_a = options.uri) == null ? void 0 : _a.protocol) || DEFAULT_PROTOCOL;
635
- }
636
- function getPortByRequestOptions(options) {
637
- if (options.port) {
638
- return Number(options.port);
639
- }
640
- const agent = getAgent(options);
641
- if (agent == null ? void 0 : agent.options.port) {
642
- return Number(agent.options.port);
643
- }
644
- if (agent == null ? void 0 : agent.defaultPort) {
645
- return Number(agent.defaultPort);
646
- }
647
- return void 0;
648
- }
649
- function getAuthByRequestOptions(options) {
650
- if (options.auth) {
651
- const [username, password] = options.auth.split(":");
652
- return { username, password };
653
- }
654
- }
655
- function isRawIPv6Address(host) {
656
- return host.includes(":") && !host.startsWith("[") && !host.endsWith("]");
657
- }
658
- function getHostname(options) {
659
- let host = options.hostname || options.host;
660
- if (host) {
661
- if (isRawIPv6Address(host)) {
662
- host = `[${host}]`;
663
- }
664
- return new URL(`http://${host}`).hostname;
665
- }
666
- return DEFAULT_HOSTNAME;
667
- }
668
- function getUrlByRequestOptions(options) {
669
- logger3.info("request options", options);
670
- if (options.uri) {
671
- logger3.info(
672
- 'constructing url from explicitly provided "options.uri": %s',
673
- options.uri
674
- );
675
- return new URL(options.uri.href);
676
- }
677
- logger3.info("figuring out url from request options...");
678
- const protocol = getProtocolByRequestOptions(options);
679
- logger3.info("protocol", protocol);
680
- const port = getPortByRequestOptions(options);
681
- logger3.info("port", port);
682
- const hostname = getHostname(options);
683
- logger3.info("hostname", hostname);
684
- const path = options.path || DEFAULT_PATH;
685
- logger3.info("path", path);
686
- const credentials = getAuthByRequestOptions(options);
687
- logger3.info("credentials", credentials);
688
- const authString = credentials ? `${credentials.username}:${credentials.password}@` : "";
689
- logger3.info("auth string:", authString);
690
- const portString = typeof port !== "undefined" ? `:${port}` : "";
691
- const url = new URL(`${protocol}//${hostname}${portString}${path}`);
692
- url.username = (credentials == null ? void 0 : credentials.username) || "";
693
- url.password = (credentials == null ? void 0 : credentials.password) || "";
694
- logger3.info("created url:", url);
695
- return url;
696
- }
697
-
698
- // src/utils/cloneObject.ts
699
-
700
- var logger4 = new (0, _logger.Logger)("cloneObject");
701
- function isPlainObject(obj) {
702
- var _a;
703
- logger4.info("is plain object?", obj);
704
- if (obj == null || !((_a = obj.constructor) == null ? void 0 : _a.name)) {
705
- logger4.info("given object is undefined, not a plain object...");
706
- return false;
707
- }
708
- logger4.info("checking the object constructor:", obj.constructor.name);
709
- return obj.constructor.name === "Object";
710
- }
711
- function cloneObject(obj) {
712
- logger4.info("cloning object:", obj);
713
- const enumerableProperties = Object.entries(obj).reduce(
714
- (acc, [key, value]) => {
715
- logger4.info("analyzing key-value pair:", key, value);
716
- acc[key] = isPlainObject(value) ? cloneObject(value) : value;
717
- return acc;
718
- },
719
- {}
720
- );
721
- return isPlainObject(obj) ? enumerableProperties : Object.assign(Object.getPrototypeOf(obj), enumerableProperties);
722
- }
723
-
724
- // src/interceptors/ClientRequest/utils/normalizeClientRequestArgs.ts
725
- var logger5 = new (0, _logger.Logger)("http normalizeClientRequestArgs");
726
- function resolveRequestOptions(args, url) {
727
- if (typeof args[1] === "undefined" || typeof args[1] === "function") {
728
- logger5.info("request options not provided, deriving from the url", url);
729
- return getRequestOptionsByUrl(url);
730
- }
731
- if (args[1]) {
732
- logger5.info("has custom RequestOptions!", args[1]);
733
- const requestOptionsFromUrl = getRequestOptionsByUrl(url);
734
- logger5.info("derived RequestOptions from the URL:", requestOptionsFromUrl);
735
- logger5.info("cloning RequestOptions...");
736
- const clonedRequestOptions = cloneObject(args[1]);
737
- logger5.info("successfully cloned RequestOptions!", clonedRequestOptions);
738
- return {
739
- ...requestOptionsFromUrl,
740
- ...clonedRequestOptions
741
- };
742
- }
743
- logger5.info("using an empty object as request options");
744
- return {};
745
- }
746
- function overrideUrlByRequestOptions(url, options) {
747
- url.host = options.host || url.host;
748
- url.hostname = options.hostname || url.hostname;
749
- url.port = options.port ? options.port.toString() : url.port;
750
- if (options.path) {
751
- const parsedOptionsPath = _url.parse.call(void 0, options.path, false);
752
- url.pathname = parsedOptionsPath.pathname || "";
753
- url.search = parsedOptionsPath.search || "";
754
- }
755
- return url;
756
- }
757
- function resolveCallback(args) {
758
- return typeof args[1] === "function" ? args[1] : args[2];
759
- }
760
- function normalizeClientRequestArgs(defaultProtocol, ...args) {
761
- let url;
762
- let options;
763
- let callback;
764
- logger5.info("arguments", args);
765
- logger5.info("using default protocol:", defaultProtocol);
766
- if (args.length === 0) {
767
- const url2 = new URL("http://localhost");
768
- const options2 = resolveRequestOptions(args, url2);
769
- return [url2, options2];
770
- }
771
- if (typeof args[0] === "string") {
772
- logger5.info("first argument is a location string:", args[0]);
773
- url = new URL(args[0]);
774
- logger5.info("created a url:", url);
775
- const requestOptionsFromUrl = getRequestOptionsByUrl(url);
776
- logger5.info("request options from url:", requestOptionsFromUrl);
777
- options = resolveRequestOptions(args, url);
778
- logger5.info("resolved request options:", options);
779
- callback = resolveCallback(args);
780
- } else if (args[0] instanceof URL) {
781
- url = args[0];
782
- logger5.info("first argument is a URL:", url);
783
- if (typeof args[1] !== "undefined" && isObject(args[1])) {
784
- url = overrideUrlByRequestOptions(url, args[1]);
785
- }
786
- options = resolveRequestOptions(args, url);
787
- logger5.info("derived request options:", options);
788
- callback = resolveCallback(args);
789
- } else if ("hash" in args[0] && !("method" in args[0])) {
790
- const [legacyUrl] = args;
791
- logger5.info("first argument is a legacy URL:", legacyUrl);
792
- if (legacyUrl.hostname === null) {
793
- logger5.info("given legacy URL is relative (no hostname)");
794
- return isObject(args[1]) ? normalizeClientRequestArgs(
795
- defaultProtocol,
796
- { path: legacyUrl.path, ...args[1] },
797
- args[2]
798
- ) : normalizeClientRequestArgs(
799
- defaultProtocol,
800
- { path: legacyUrl.path },
801
- args[1]
802
- );
803
- }
804
- logger5.info("given legacy url is absolute");
805
- const resolvedUrl = new URL(legacyUrl.href);
806
- return args[1] === void 0 ? normalizeClientRequestArgs(defaultProtocol, resolvedUrl) : typeof args[1] === "function" ? normalizeClientRequestArgs(defaultProtocol, resolvedUrl, args[1]) : normalizeClientRequestArgs(
807
- defaultProtocol,
808
- resolvedUrl,
809
- args[1],
810
- args[2]
811
- );
812
- } else if (isObject(args[0])) {
813
- options = args[0];
814
- logger5.info("first argument is RequestOptions:", options);
815
- options.protocol = options.protocol || defaultProtocol;
816
- logger5.info("normalized request options:", options);
817
- url = getUrlByRequestOptions(options);
818
- logger5.info("created a URL from RequestOptions:", url.href);
819
- callback = resolveCallback(args);
820
- } else {
821
- throw new Error(
822
- `Failed to construct ClientRequest with these parameters: ${args}`
823
- );
824
- }
825
- options.protocol = options.protocol || url.protocol;
826
- options.method = options.method || "GET";
827
- if (typeof options.agent === "undefined") {
828
- const agent = options.protocol === "https:" ? new (0, _https.Agent)({
829
- rejectUnauthorized: options.rejectUnauthorized
830
- }) : new (0, _http.Agent)();
831
- options.agent = agent;
832
- logger5.info("resolved fallback agent:", agent);
833
- }
834
- if (!options._defaultAgent) {
835
- logger5.info(
836
- 'has no default agent, setting the default agent for "%s"',
837
- options.protocol
838
- );
839
- options._defaultAgent = options.protocol === "https:" ? _https.globalAgent : _http.globalAgent;
840
- }
841
- logger5.info("successfully resolved url:", url.href);
842
- logger5.info("successfully resolved options:", options);
843
- logger5.info("successfully resolved callback:", callback);
844
- return [url, options, callback];
845
- }
846
-
847
- // src/interceptors/ClientRequest/http.get.ts
848
- function get(protocol, options) {
849
- return function interceptorsHttpGet(...args) {
850
- const clientRequestArgs = normalizeClientRequestArgs(
851
- `${protocol}:`,
852
- ...args
853
- );
854
- const request2 = new NodeClientRequest(clientRequestArgs, options);
855
- request2.end();
856
- return request2;
857
- };
858
- }
859
-
860
- // src/interceptors/ClientRequest/http.request.ts
861
-
862
- var logger6 = new (0, _logger.Logger)("http request");
863
- function request(protocol, options) {
864
- return function interceptorsHttpRequest(...args) {
865
- logger6.info('request call (protocol "%s"):', protocol, args);
866
- const clientRequestArgs = normalizeClientRequestArgs(
867
- `${protocol}:`,
868
- ...args
869
- );
870
- return new NodeClientRequest(clientRequestArgs, options);
871
- };
872
- }
873
-
874
- // src/interceptors/ClientRequest/index.ts
875
- var _ClientRequestInterceptor = class extends _chunkE4AC7YACjs.Interceptor {
876
- constructor() {
877
- super(_ClientRequestInterceptor.interceptorSymbol);
878
- this.modules = /* @__PURE__ */ new Map();
879
- this.modules.set("http", _http2.default);
880
- this.modules.set("https", _https2.default);
881
- }
882
- setup() {
883
- const logger7 = this.logger.extend("setup");
884
- for (const [protocol, requestModule] of this.modules) {
885
- const { request: pureRequest, get: pureGet } = requestModule;
886
- this.subscriptions.push(() => {
887
- requestModule.request = pureRequest;
888
- requestModule.get = pureGet;
889
- logger7.info('native "%s" module restored!', protocol);
890
- });
891
- const options = {
892
- emitter: this.emitter,
893
- logger: this.logger
894
- };
895
- requestModule.request = // Force a line break.
896
- request(protocol, options);
897
- requestModule.get = // Force a line break.
898
- get(protocol, options);
899
- logger7.info('native "%s" module patched!', protocol);
900
- }
901
- }
902
- };
903
- var ClientRequestInterceptor = _ClientRequestInterceptor;
904
- ClientRequestInterceptor.interceptorSymbol = Symbol("http");
905
-
906
-
907
-
908
- exports.ClientRequestInterceptor = ClientRequestInterceptor;
909
- //# sourceMappingURL=chunk-IS3CIGXU.js.map