@mswjs/interceptors 0.22.4 → 0.22.5

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 (72) hide show
  1. package/README.md +3 -3
  2. package/lib/browser/{Interceptor-959f650e.d.ts → Interceptor-c794917d.d.ts} +2 -2
  3. package/lib/browser/{chunk-IIY3SHU3.js → chunk-2EIH6L6D.js} +25 -25
  4. package/lib/browser/{chunk-BQYA7ER5.mjs → chunk-2GVXYEMC.mjs} +5 -5
  5. package/lib/browser/chunk-2Z7B3HL5.js +106 -0
  6. package/lib/browser/{chunk-5B525MKF.mjs → chunk-65HGG3CV.mjs} +1 -1
  7. package/lib/browser/chunk-CNZUUPXM.mjs +682 -0
  8. package/lib/browser/chunk-GL6Y4E24.mjs +106 -0
  9. package/lib/browser/chunk-KDXWM46S.js +682 -0
  10. package/lib/browser/{chunk-QWL3EOEY.js → chunk-OK5YCL7L.js} +7 -7
  11. package/lib/browser/{chunk-ZJOF5MEZ.js → chunk-PCFJD76X.js} +11 -11
  12. package/lib/browser/{chunk-STA6QBYM.mjs → chunk-RT3ATOJH.mjs} +11 -11
  13. package/lib/browser/index.d.ts +6 -6
  14. package/lib/browser/index.js +4 -4
  15. package/lib/browser/index.mjs +2 -2
  16. package/lib/browser/interceptors/XMLHttpRequest/index.d.ts +3 -3
  17. package/lib/browser/interceptors/XMLHttpRequest/index.js +5 -677
  18. package/lib/browser/interceptors/XMLHttpRequest/index.mjs +5 -677
  19. package/lib/browser/interceptors/fetch/index.d.ts +2 -2
  20. package/lib/browser/interceptors/fetch/index.js +4 -101
  21. package/lib/browser/interceptors/fetch/index.mjs +4 -101
  22. package/lib/browser/presets/browser.d.ts +13 -0
  23. package/lib/browser/presets/browser.js +18 -0
  24. package/lib/browser/presets/browser.mjs +18 -0
  25. package/lib/node/{BatchInterceptor-a7261b26.d.ts → BatchInterceptor-5c1e5de3.d.ts} +5 -5
  26. package/lib/node/{Interceptor-997045eb.d.ts → Interceptor-b3a4098c.d.ts} +2 -2
  27. package/lib/node/RemoteHttpInterceptor.d.ts +3 -3
  28. package/lib/node/RemoteHttpInterceptor.js +9 -9
  29. package/lib/node/RemoteHttpInterceptor.mjs +5 -5
  30. package/lib/node/{chunk-FGPCRIW6.mjs → chunk-53LM4S3X.mjs} +59 -62
  31. package/lib/node/{chunk-WWHITCCI.js → chunk-62KFIM4W.js} +9 -8
  32. package/lib/node/{chunk-37CATPNG.mjs → chunk-6CRMKMDL.mjs} +6 -5
  33. package/lib/node/{chunk-XLZJAPVS.js → chunk-D7MOETL2.js} +59 -62
  34. package/lib/node/{chunk-P7NKDCFD.mjs → chunk-HGKO2BOA.mjs} +4 -4
  35. package/lib/node/{chunk-RVLLS44W.js → chunk-HTLVOEKP.js} +8 -8
  36. package/lib/node/{chunk-KZEQH4YW.mjs → chunk-IC6Y7RGW.mjs} +1 -1
  37. package/lib/node/{chunk-SNNL2EXF.js → chunk-MUUQLKVJ.js} +3 -3
  38. package/lib/node/{chunk-G6ZTHYZQ.mjs → chunk-RFVEKRYP.mjs} +1 -1
  39. package/lib/node/{chunk-Q56TMOP5.js → chunk-SFLY7F52.js} +2 -2
  40. package/lib/node/index.d.ts +3 -3
  41. package/lib/node/index.js +4 -4
  42. package/lib/node/index.mjs +3 -3
  43. package/lib/node/interceptors/ClientRequest/index.d.ts +3 -3
  44. package/lib/node/interceptors/ClientRequest/index.js +3 -3
  45. package/lib/node/interceptors/ClientRequest/index.mjs +2 -2
  46. package/lib/node/interceptors/XMLHttpRequest/index.d.ts +3 -3
  47. package/lib/node/interceptors/XMLHttpRequest/index.js +4 -4
  48. package/lib/node/interceptors/XMLHttpRequest/index.mjs +3 -3
  49. package/lib/node/interceptors/fetch/index.d.ts +2 -2
  50. package/lib/node/interceptors/fetch/index.js +2 -2
  51. package/lib/node/interceptors/fetch/index.mjs +1 -1
  52. package/lib/node/presets/node.d.ts +15 -0
  53. package/lib/node/presets/node.js +19 -0
  54. package/lib/node/presets/node.mjs +19 -0
  55. package/package.json +16 -1
  56. package/src/BatchInterceptor.ts +5 -5
  57. package/src/Interceptor.ts +2 -2
  58. package/src/interceptors/ClientRequest/NodeClientRequest.test.ts +1 -1
  59. package/src/interceptors/ClientRequest/http.request.ts +1 -1
  60. package/src/interceptors/ClientRequest/index.ts +2 -2
  61. package/src/interceptors/ClientRequest/utils/createRequest.test.ts +1 -1
  62. package/src/interceptors/ClientRequest/utils/getIncomingMessageBody.ts +1 -1
  63. package/src/interceptors/ClientRequest/utils/normalizeClientRequestArgs.ts +1 -1
  64. package/src/interceptors/ClientRequest/utils/normalizeClientRequestEndArgs.ts +5 -3
  65. package/src/interceptors/ClientRequest/utils/normalizeClientRequestWriteArgs.ts +1 -1
  66. package/src/interceptors/XMLHttpRequest/index.ts +2 -2
  67. package/src/presets/browser.ts +4 -1
  68. package/src/presets/node.ts +4 -1
  69. package/src/utils/AsyncEventEmitter.ts +1 -1
  70. package/src/utils/cloneObject.ts +8 -6
  71. package/src/utils/debug.ts +4 -0
  72. package/src/utils/getUrlByRequestOptions.ts +13 -12
@@ -0,0 +1,682 @@
1
+ import {
2
+ decodeBuffer,
3
+ encodeBuffer,
4
+ toArrayBuffer
5
+ } from "./chunk-65HGG3CV.mjs";
6
+ import {
7
+ toInteractiveRequest,
8
+ uuidv4
9
+ } from "./chunk-RT3ATOJH.mjs";
10
+ import {
11
+ IS_PATCHED_MODULE,
12
+ Interceptor
13
+ } from "./chunk-2GVXYEMC.mjs";
14
+
15
+ // src/interceptors/XMLHttpRequest/index.ts
16
+ import { invariant as invariant2 } from "outvariant";
17
+
18
+ // src/interceptors/XMLHttpRequest/XMLHttpRequestProxy.ts
19
+ import { until } from "@open-draft/until";
20
+
21
+ // src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts
22
+ import { headersToString } from "headers-polyfill";
23
+
24
+ // src/interceptors/XMLHttpRequest/utils/concatArrayBuffer.ts
25
+ function concatArrayBuffer(left, right) {
26
+ const result = new Uint8Array(left.byteLength + right.byteLength);
27
+ result.set(left, 0);
28
+ result.set(right, left.byteLength);
29
+ return result;
30
+ }
31
+
32
+ // src/interceptors/XMLHttpRequest/polyfills/EventPolyfill.ts
33
+ var EventPolyfill = class {
34
+ constructor(type, options) {
35
+ this.AT_TARGET = 0;
36
+ this.BUBBLING_PHASE = 0;
37
+ this.CAPTURING_PHASE = 0;
38
+ this.NONE = 0;
39
+ this.type = "";
40
+ this.srcElement = null;
41
+ this.currentTarget = null;
42
+ this.eventPhase = 0;
43
+ this.isTrusted = true;
44
+ this.composed = false;
45
+ this.cancelable = true;
46
+ this.defaultPrevented = false;
47
+ this.bubbles = true;
48
+ this.lengthComputable = true;
49
+ this.loaded = 0;
50
+ this.total = 0;
51
+ this.cancelBubble = false;
52
+ this.returnValue = true;
53
+ this.type = type;
54
+ this.target = (options == null ? void 0 : options.target) || null;
55
+ this.currentTarget = (options == null ? void 0 : options.currentTarget) || null;
56
+ this.timeStamp = Date.now();
57
+ }
58
+ composedPath() {
59
+ return [];
60
+ }
61
+ initEvent(type, bubbles, cancelable) {
62
+ this.type = type;
63
+ this.bubbles = !!bubbles;
64
+ this.cancelable = !!cancelable;
65
+ }
66
+ preventDefault() {
67
+ this.defaultPrevented = true;
68
+ }
69
+ stopPropagation() {
70
+ }
71
+ stopImmediatePropagation() {
72
+ }
73
+ };
74
+
75
+ // src/interceptors/XMLHttpRequest/polyfills/ProgressEventPolyfill.ts
76
+ var ProgressEventPolyfill = class extends EventPolyfill {
77
+ constructor(type, init) {
78
+ super(type);
79
+ this.lengthComputable = (init == null ? void 0 : init.lengthComputable) || false;
80
+ this.composed = (init == null ? void 0 : init.composed) || false;
81
+ this.loaded = (init == null ? void 0 : init.loaded) || 0;
82
+ this.total = (init == null ? void 0 : init.total) || 0;
83
+ }
84
+ };
85
+
86
+ // src/interceptors/XMLHttpRequest/utils/createEvent.ts
87
+ var SUPPORTS_PROGRESS_EVENT = typeof ProgressEvent !== "undefined";
88
+ function createEvent(target, type, init) {
89
+ const progressEvents = [
90
+ "error",
91
+ "progress",
92
+ "loadstart",
93
+ "loadend",
94
+ "load",
95
+ "timeout",
96
+ "abort"
97
+ ];
98
+ const ProgressEventClass = SUPPORTS_PROGRESS_EVENT ? ProgressEvent : ProgressEventPolyfill;
99
+ const event = progressEvents.includes(type) ? new ProgressEventClass(type, {
100
+ lengthComputable: true,
101
+ loaded: (init == null ? void 0 : init.loaded) || 0,
102
+ total: (init == null ? void 0 : init.total) || 0
103
+ }) : new EventPolyfill(type, {
104
+ target,
105
+ currentTarget: target
106
+ });
107
+ return event;
108
+ }
109
+
110
+ // src/utils/createProxy.ts
111
+ function createProxy(target, options) {
112
+ const proxy = new Proxy(target, optionsToProxyHandler(options));
113
+ return proxy;
114
+ }
115
+ function optionsToProxyHandler(options) {
116
+ const { constructorCall, methodCall, getProperty, setProperty } = options;
117
+ const handler = {};
118
+ if (typeof constructorCall !== "undefined") {
119
+ handler.construct = function(target, args, newTarget) {
120
+ const next = Reflect.construct.bind(null, target, args, newTarget);
121
+ return constructorCall.call(newTarget, args, next);
122
+ };
123
+ }
124
+ handler.set = function(target, propertyName, nextValue, receiver) {
125
+ const next = () => {
126
+ const ownDescriptors = Reflect.getOwnPropertyDescriptor(
127
+ target,
128
+ propertyName
129
+ );
130
+ if (typeof (ownDescriptors == null ? void 0 : ownDescriptors.set) !== "undefined") {
131
+ ownDescriptors.set.apply(target, [nextValue]);
132
+ return true;
133
+ }
134
+ return Reflect.defineProperty(target, propertyName, {
135
+ writable: true,
136
+ enumerable: true,
137
+ configurable: true,
138
+ value: nextValue
139
+ });
140
+ };
141
+ if (typeof setProperty !== "undefined") {
142
+ return setProperty.call(target, [propertyName, nextValue], next);
143
+ }
144
+ return next();
145
+ };
146
+ handler.get = function(target, propertyName, receiver) {
147
+ const next = () => target[propertyName];
148
+ const value = typeof getProperty !== "undefined" ? getProperty.call(target, [propertyName, receiver], next) : next();
149
+ if (typeof value === "function") {
150
+ return (...args) => {
151
+ const next2 = value.bind(target, ...args);
152
+ if (typeof methodCall !== "undefined") {
153
+ return methodCall.call(target, [propertyName, args], next2);
154
+ }
155
+ return next2();
156
+ };
157
+ }
158
+ return value;
159
+ };
160
+ return handler;
161
+ }
162
+
163
+ // src/interceptors/XMLHttpRequest/utils/isDomParserSupportedType.ts
164
+ function isDomParserSupportedType(type) {
165
+ const supportedTypes = [
166
+ "application/xhtml+xml",
167
+ "application/xml",
168
+ "image/svg+xml",
169
+ "text/html",
170
+ "text/xml"
171
+ ];
172
+ return supportedTypes.some((supportedType) => {
173
+ return type.startsWith(supportedType);
174
+ });
175
+ }
176
+
177
+ // src/utils/parseJson.ts
178
+ function parseJson(data) {
179
+ try {
180
+ const json = JSON.parse(data);
181
+ return json;
182
+ } catch (_) {
183
+ return null;
184
+ }
185
+ }
186
+
187
+ // src/interceptors/XMLHttpRequest/utils/createResponse.ts
188
+ import { stringToHeaders } from "headers-polyfill";
189
+ function createResponse(request, responseBody) {
190
+ return new Response(responseBody, {
191
+ status: request.status,
192
+ statusText: request.statusText,
193
+ headers: stringToHeaders(request.getAllResponseHeaders())
194
+ });
195
+ }
196
+
197
+ // src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts
198
+ import { invariant } from "outvariant";
199
+ var XMLHttpRequestController = class {
200
+ constructor(initialRequest, log) {
201
+ this.initialRequest = initialRequest;
202
+ this.log = log;
203
+ this.method = "GET";
204
+ this.url = null;
205
+ this.events = /* @__PURE__ */ new Map();
206
+ this.requestHeaders = new Headers();
207
+ this.responseBuffer = new Uint8Array();
208
+ this.request = createProxy(initialRequest, {
209
+ setProperty: ([propertyName, nextValue], invoke) => {
210
+ switch (propertyName) {
211
+ case "onabort":
212
+ case "onerror":
213
+ case "onload":
214
+ case "onloadend":
215
+ case "onloadstart":
216
+ case "onprogress":
217
+ case "ontimeout":
218
+ case "onreadystatechange": {
219
+ const eventName = propertyName.slice(
220
+ 2
221
+ );
222
+ this.request.addEventListener(eventName, nextValue);
223
+ return invoke();
224
+ }
225
+ default: {
226
+ return invoke();
227
+ }
228
+ }
229
+ },
230
+ methodCall: ([methodName, args], invoke) => {
231
+ var _a;
232
+ switch (methodName) {
233
+ case "open": {
234
+ const [method, url] = args;
235
+ this.requestId = uuidv4();
236
+ if (typeof url === "undefined") {
237
+ this.method = "GET";
238
+ this.url = toAbsoluteUrl(method);
239
+ } else {
240
+ this.method = method;
241
+ this.url = toAbsoluteUrl(url);
242
+ }
243
+ this.log = this.log.extend(`${this.method} ${this.url.href}`);
244
+ this.log("open", this.method, this.url.href);
245
+ return invoke();
246
+ }
247
+ case "addEventListener": {
248
+ const [eventName, listener] = args;
249
+ this.registerEvent(eventName, listener);
250
+ this.log("addEventListener", eventName, listener.name);
251
+ return invoke();
252
+ }
253
+ case "setRequestHeader": {
254
+ const [name, value] = args;
255
+ this.requestHeaders.set(name, value);
256
+ this.log("setRequestHeader", name, value);
257
+ return invoke();
258
+ }
259
+ case "send": {
260
+ const [body] = args;
261
+ if (body != null) {
262
+ this.requestBody = typeof body === "string" ? encodeBuffer(body) : body;
263
+ }
264
+ this.request.addEventListener("load", () => {
265
+ if (typeof this.onResponse !== "undefined") {
266
+ const fetchResponse = createResponse(
267
+ this.request,
268
+ this.request.response
269
+ );
270
+ this.onResponse.call(
271
+ this,
272
+ fetchResponse,
273
+ fetchRequest,
274
+ this.requestId
275
+ );
276
+ }
277
+ });
278
+ const fetchRequest = this.toFetchApiRequest();
279
+ const onceRequestSettled = ((_a = this.onRequest) == null ? void 0 : _a.call(this, fetchRequest, this.requestId)) || Promise.resolve();
280
+ onceRequestSettled.finally(() => {
281
+ if (this.request.readyState < this.request.LOADING) {
282
+ this.log(
283
+ "request callback settled but request has not been handled (readystate %d), performing as-is...",
284
+ this.request.readyState
285
+ );
286
+ this.request.setRequestHeader("X-Request-Id", this.requestId);
287
+ return invoke();
288
+ }
289
+ });
290
+ break;
291
+ }
292
+ default: {
293
+ return invoke();
294
+ }
295
+ }
296
+ }
297
+ });
298
+ }
299
+ registerEvent(eventName, listener) {
300
+ const prevEvents = this.events.get(eventName) || [];
301
+ const nextEvents = prevEvents.concat(listener);
302
+ this.events.set(eventName, nextEvents);
303
+ this.log('registered event "%s"', eventName, listener.name);
304
+ }
305
+ respondWith(response) {
306
+ this.log(
307
+ "responding with a mocked response: %d %s",
308
+ response.status,
309
+ response.statusText
310
+ );
311
+ define(this.request, "status", response.status);
312
+ define(this.request, "statusText", response.statusText);
313
+ define(this.request, "responseURL", this.url.href);
314
+ this.request.getResponseHeader = new Proxy(this.request.getResponseHeader, {
315
+ apply: (_, __, args) => {
316
+ this.log("getResponseHeader", args[0]);
317
+ if (this.request.readyState < this.request.HEADERS_RECEIVED) {
318
+ this.log("headers not received yet, returning null");
319
+ return null;
320
+ }
321
+ const headerValue = response.headers.get(args[0]);
322
+ this.log('resolved response header "%s" to', args[0], headerValue);
323
+ return headerValue;
324
+ }
325
+ });
326
+ this.request.getAllResponseHeaders = new Proxy(
327
+ this.request.getAllResponseHeaders,
328
+ {
329
+ apply: () => {
330
+ this.log("getAllResponseHeaders");
331
+ if (this.request.readyState < this.request.HEADERS_RECEIVED) {
332
+ this.log("headers not received yet, returning empty string");
333
+ return "";
334
+ }
335
+ const allHeaders = headersToString(response.headers);
336
+ this.log("resolved all response headers to", allHeaders);
337
+ return allHeaders;
338
+ }
339
+ }
340
+ );
341
+ Object.defineProperties(this.request, {
342
+ response: {
343
+ enumerable: true,
344
+ configurable: false,
345
+ get: () => this.response
346
+ },
347
+ responseText: {
348
+ enumerable: true,
349
+ configurable: false,
350
+ get: () => this.responseText
351
+ },
352
+ responseXML: {
353
+ enumerable: true,
354
+ configurable: false,
355
+ get: () => this.responseXML
356
+ }
357
+ });
358
+ const totalResponseBodyLength = response.headers.has("Content-Length") ? Number(response.headers.get("Content-Length")) : void 0;
359
+ this.log("calculated response body length", totalResponseBodyLength);
360
+ this.trigger("loadstart", {
361
+ loaded: 0,
362
+ total: totalResponseBodyLength
363
+ });
364
+ this.setReadyState(this.request.HEADERS_RECEIVED);
365
+ this.setReadyState(this.request.LOADING);
366
+ const finalizeResponse = () => {
367
+ this.log("finalizing the mocked response...");
368
+ this.setReadyState(this.request.DONE);
369
+ this.trigger("load", {
370
+ loaded: this.responseBuffer.byteLength,
371
+ total: totalResponseBodyLength
372
+ });
373
+ this.trigger("loadend", {
374
+ loaded: this.responseBuffer.byteLength,
375
+ total: totalResponseBodyLength
376
+ });
377
+ };
378
+ if (response.body) {
379
+ this.log("mocked response has body, streaming...");
380
+ const reader = response.body.getReader();
381
+ const readNextResponseBodyChunk = async () => {
382
+ const { value, done } = await reader.read();
383
+ if (done) {
384
+ this.log("response body stream done!");
385
+ finalizeResponse();
386
+ return;
387
+ }
388
+ if (value) {
389
+ this.log("read response body chunk:", value);
390
+ this.responseBuffer = concatArrayBuffer(this.responseBuffer, value);
391
+ this.trigger("progress", {
392
+ loaded: this.responseBuffer.byteLength,
393
+ total: totalResponseBodyLength
394
+ });
395
+ }
396
+ readNextResponseBodyChunk();
397
+ };
398
+ readNextResponseBodyChunk();
399
+ } else {
400
+ finalizeResponse();
401
+ }
402
+ }
403
+ responseBufferToText() {
404
+ return decodeBuffer(this.responseBuffer);
405
+ }
406
+ get response() {
407
+ this.log("getResponse (responseType: %s)", this.request.responseType);
408
+ if (this.request.readyState !== this.request.DONE) {
409
+ return null;
410
+ }
411
+ switch (this.request.responseType) {
412
+ case "json": {
413
+ const responseJson = parseJson(this.responseBufferToText());
414
+ this.log("resolved response JSON", responseJson);
415
+ return responseJson;
416
+ }
417
+ case "arraybuffer": {
418
+ const arrayBuffer = toArrayBuffer(this.responseBuffer);
419
+ this.log("resolved response ArrayBuffer", arrayBuffer);
420
+ return arrayBuffer;
421
+ }
422
+ case "blob": {
423
+ const mimeType = this.request.getResponseHeader("Content-Type") || "text/plain";
424
+ const responseBlob = new Blob([this.responseBufferToText()], {
425
+ type: mimeType
426
+ });
427
+ this.log(
428
+ "resolved response Blob (mime type: %s)",
429
+ responseBlob,
430
+ mimeType
431
+ );
432
+ return responseBlob;
433
+ }
434
+ default: {
435
+ const responseText = this.responseBufferToText();
436
+ this.log(
437
+ 'resolving "%s" response type as text',
438
+ this.request.responseType,
439
+ responseText
440
+ );
441
+ return responseText;
442
+ }
443
+ }
444
+ }
445
+ get responseText() {
446
+ invariant(
447
+ this.request.responseType === "" || this.request.responseType === "text",
448
+ "InvalidStateError: The object is in invalid state."
449
+ );
450
+ if (this.request.readyState !== this.request.LOADING && this.request.readyState !== this.request.DONE) {
451
+ return "";
452
+ }
453
+ const responseText = this.responseBufferToText();
454
+ this.log('getResponseText: "%s"', responseText);
455
+ return responseText;
456
+ }
457
+ get responseXML() {
458
+ invariant(
459
+ this.request.responseType === "" || this.request.responseType === "document",
460
+ "InvalidStateError: The object is in invalid state."
461
+ );
462
+ if (this.request.readyState !== this.request.DONE) {
463
+ return null;
464
+ }
465
+ const contentType = this.request.getResponseHeader("Content-Type") || "";
466
+ if (typeof DOMParser === "undefined") {
467
+ console.warn(
468
+ "Cannot retrieve XMLHttpRequest response body as XML: DOMParser is not defined. You are likely using an environment that is not browser or does not polyfill browser globals correctly."
469
+ );
470
+ return null;
471
+ }
472
+ if (isDomParserSupportedType(contentType)) {
473
+ return new DOMParser().parseFromString(
474
+ this.responseBufferToText(),
475
+ contentType
476
+ );
477
+ }
478
+ return null;
479
+ }
480
+ errorWith(error) {
481
+ this.log("responding with an error");
482
+ this.setReadyState(this.request.DONE);
483
+ this.trigger("error");
484
+ this.trigger("loadend");
485
+ }
486
+ setReadyState(nextReadyState) {
487
+ this.log("setReadyState: %d -> %d", this.request.readyState, nextReadyState);
488
+ if (this.request.readyState === nextReadyState) {
489
+ this.log("ready state identical, skipping transition...");
490
+ return;
491
+ }
492
+ define(this.request, "readyState", nextReadyState);
493
+ this.log("set readyState to: %d", nextReadyState);
494
+ if (nextReadyState !== this.request.UNSENT) {
495
+ this.log('triggerring "readystatechange" event...');
496
+ this.trigger("readystatechange");
497
+ }
498
+ }
499
+ trigger(eventName, options) {
500
+ const callback = this.request[`on${eventName}`];
501
+ const event = createEvent(this.request, eventName, options);
502
+ this.log('trigger "%s"', eventName, options || "");
503
+ if (typeof callback === "function") {
504
+ this.log('found a direct "%s" callback, calling...', eventName);
505
+ callback.call(this.request, event);
506
+ }
507
+ for (const [registeredEventName, listeners] of this.events) {
508
+ if (registeredEventName === eventName) {
509
+ this.log(
510
+ 'found %d listener(s) for "%s" event, calling...',
511
+ listeners.length,
512
+ eventName
513
+ );
514
+ listeners.forEach((listener) => listener.call(this.request, event));
515
+ }
516
+ }
517
+ }
518
+ toFetchApiRequest() {
519
+ this.log("converting request to a Fetch API Request...");
520
+ const fetchRequest = new Request(this.url.href, {
521
+ method: this.method,
522
+ headers: this.requestHeaders,
523
+ credentials: this.request.withCredentials ? "include" : "same-origin",
524
+ body: this.requestBody
525
+ });
526
+ const proxyHeaders = createProxy(fetchRequest.headers, {
527
+ methodCall: ([methodName, args], invoke) => {
528
+ switch (methodName) {
529
+ case "append":
530
+ case "set": {
531
+ const [headerName, headerValue] = args;
532
+ this.request.setRequestHeader(headerName, headerValue);
533
+ break;
534
+ }
535
+ case "delete": {
536
+ const [headerName] = args;
537
+ console.warn(
538
+ `XMLHttpRequest: Cannot remove a "${headerName}" header from the Fetch API representation of the "${fetchRequest.method} ${fetchRequest.url}" request. XMLHttpRequest headers cannot be removed.`
539
+ );
540
+ break;
541
+ }
542
+ }
543
+ return invoke();
544
+ }
545
+ });
546
+ define(fetchRequest, "headers", proxyHeaders);
547
+ this.log("converted request to a Fetch API Request!", fetchRequest);
548
+ return fetchRequest;
549
+ }
550
+ };
551
+ function toAbsoluteUrl(url) {
552
+ return new URL(url.toString(), location.href);
553
+ }
554
+ function define(target, property, value) {
555
+ Reflect.defineProperty(target, property, {
556
+ writable: true,
557
+ enumerable: true,
558
+ value
559
+ });
560
+ }
561
+
562
+ // src/interceptors/XMLHttpRequest/XMLHttpRequestProxy.ts
563
+ function createXMLHttpRequestProxy({
564
+ emitter,
565
+ log
566
+ }) {
567
+ const XMLHttpRequestProxy = new Proxy(globalThis.XMLHttpRequest, {
568
+ construct(target, args, newTarget) {
569
+ log("constructed new XMLHttpRequest");
570
+ const originalRequest = Reflect.construct(target, args, newTarget);
571
+ const prototypeDescriptors = Object.getOwnPropertyDescriptors(
572
+ target.prototype
573
+ );
574
+ for (const propertyName in prototypeDescriptors) {
575
+ Reflect.defineProperty(
576
+ originalRequest,
577
+ propertyName,
578
+ prototypeDescriptors[propertyName]
579
+ );
580
+ }
581
+ const requestController = new XMLHttpRequestController(
582
+ originalRequest,
583
+ log
584
+ );
585
+ requestController.onRequest = async function(request, requestId) {
586
+ const interactiveRequest = toInteractiveRequest(request);
587
+ this.log(
588
+ 'emitting the "request" event for %s listener(s)...',
589
+ emitter.listenerCount("request")
590
+ );
591
+ emitter.emit("request", interactiveRequest, requestId);
592
+ this.log("awaiting mocked response...");
593
+ const [middlewareException, mockedResponse] = await until(async () => {
594
+ await emitter.untilIdle(
595
+ "request",
596
+ ({ args: [, pendingRequestId] }) => {
597
+ return pendingRequestId === requestId;
598
+ }
599
+ );
600
+ this.log('all "request" listeners settled!');
601
+ const [mockedResponse2] = await interactiveRequest.respondWith.invoked();
602
+ this.log("event.respondWith called with:", mockedResponse2);
603
+ return mockedResponse2;
604
+ });
605
+ if (middlewareException) {
606
+ this.log(
607
+ "request listener threw an exception, aborting request...",
608
+ middlewareException
609
+ );
610
+ requestController.errorWith(middlewareException);
611
+ return;
612
+ }
613
+ if (typeof mockedResponse !== "undefined") {
614
+ this.log(
615
+ "received mocked response: %d %s",
616
+ mockedResponse.status,
617
+ mockedResponse.statusText
618
+ );
619
+ return requestController.respondWith(mockedResponse);
620
+ }
621
+ this.log("no mocked response received, performing request as-is...");
622
+ };
623
+ requestController.onResponse = async function(response, request, requestId) {
624
+ this.log(
625
+ 'emitting the "response" event for %s listener(s)...',
626
+ emitter.listenerCount("response")
627
+ );
628
+ emitter.emit("response", response, request, requestId);
629
+ };
630
+ return requestController.request;
631
+ }
632
+ });
633
+ return XMLHttpRequestProxy;
634
+ }
635
+
636
+ // src/interceptors/XMLHttpRequest/index.ts
637
+ var _XMLHttpRequestInterceptor = class extends Interceptor {
638
+ constructor() {
639
+ super(_XMLHttpRequestInterceptor.interceptorSymbol);
640
+ }
641
+ checkEnvironment() {
642
+ return typeof globalThis.XMLHttpRequest !== "undefined";
643
+ }
644
+ setup() {
645
+ const log = this.log.extend("setup");
646
+ log('patching "XMLHttpRequest" module...');
647
+ const PureXMLHttpRequest = globalThis.XMLHttpRequest;
648
+ invariant2(
649
+ !PureXMLHttpRequest[IS_PATCHED_MODULE],
650
+ 'Failed to patch the "XMLHttpRequest" module: already patched.'
651
+ );
652
+ globalThis.XMLHttpRequest = createXMLHttpRequestProxy({
653
+ emitter: this.emitter,
654
+ log: this.log
655
+ });
656
+ log(
657
+ 'native "XMLHttpRequest" module patched!',
658
+ globalThis.XMLHttpRequest.name
659
+ );
660
+ Object.defineProperty(globalThis.XMLHttpRequest, IS_PATCHED_MODULE, {
661
+ enumerable: true,
662
+ configurable: true,
663
+ value: true
664
+ });
665
+ this.subscriptions.push(() => {
666
+ Object.defineProperty(globalThis.XMLHttpRequest, IS_PATCHED_MODULE, {
667
+ value: void 0
668
+ });
669
+ globalThis.XMLHttpRequest = PureXMLHttpRequest;
670
+ log(
671
+ 'native "XMLHttpRequest" module restored!',
672
+ globalThis.XMLHttpRequest.name
673
+ );
674
+ });
675
+ }
676
+ };
677
+ var XMLHttpRequestInterceptor = _XMLHttpRequestInterceptor;
678
+ XMLHttpRequestInterceptor.interceptorSymbol = Symbol("xhr");
679
+
680
+ export {
681
+ XMLHttpRequestInterceptor
682
+ };