@mswjs/interceptors 0.25.1 → 0.25.3
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/lib/browser/Interceptor-8d5fd4c6.d.ts +86 -0
- package/lib/browser/{chunk-ANLPTCZ5.mjs → chunk-AN3YI76R.mjs} +33 -26
- package/lib/browser/{chunk-4CFMDU7Z.js → chunk-CWVY2E3W.js} +20 -134
- package/lib/browser/{chunk-OSIUQA4X.js → chunk-FFBQOFWV.js} +38 -31
- package/lib/browser/{chunk-VMXB5F2J.mjs → chunk-HXJPKJY3.mjs} +25 -15
- package/lib/browser/{chunk-DBFLI5DJ.js → chunk-KITNLK66.js} +30 -20
- package/lib/browser/chunk-KK6APRON.mjs +58 -0
- package/lib/browser/{chunk-GXJLJMOT.mjs → chunk-QPMXOLDO.mjs} +21 -135
- package/lib/browser/chunk-X3NRJIZW.js +58 -0
- package/lib/browser/index.d.ts +7 -3
- package/lib/browser/index.js +24 -5
- package/lib/browser/index.mjs +22 -3
- package/lib/browser/interceptors/XMLHttpRequest/index.d.ts +4 -3
- package/lib/browser/interceptors/XMLHttpRequest/index.js +4 -4
- package/lib/browser/interceptors/XMLHttpRequest/index.mjs +3 -3
- package/lib/browser/interceptors/fetch/index.d.ts +2 -1
- package/lib/browser/interceptors/fetch/index.js +4 -4
- package/lib/browser/interceptors/fetch/index.mjs +3 -3
- package/lib/browser/presets/browser.d.ts +2 -1
- package/lib/browser/presets/browser.js +6 -6
- package/lib/browser/presets/browser.mjs +4 -4
- package/lib/node/{BatchInterceptor-c841b068.d.ts → BatchInterceptor-9785c567.d.ts} +5 -2
- package/lib/node/Interceptor-7a701c1f.d.ts +86 -0
- package/lib/node/RemoteHttpInterceptor.d.ts +3 -2
- package/lib/node/RemoteHttpInterceptor.js +19 -18
- package/lib/node/RemoteHttpInterceptor.mjs +15 -14
- package/lib/node/chunk-3IYIKC3X.mjs +6 -0
- package/lib/node/{chunk-XYZRP5S2.js → chunk-3XFLRXRY.js} +20 -134
- package/lib/node/chunk-5PTPJLB7.js +58 -0
- package/lib/node/{chunk-HSCXCLVT.mjs → chunk-FB53TMYN.mjs} +33 -26
- package/lib/node/{chunk-RGYCLCLK.mjs → chunk-GM3YBSM3.mjs} +21 -135
- package/lib/node/{chunk-E6YC337Q.js → chunk-JCWVLTP7.js} +35 -28
- package/lib/node/{chunk-OL7OR4RL.mjs → chunk-MCO3RLQC.mjs} +48 -26
- package/lib/node/{chunk-3MYUI4B2.js → chunk-NCHFM2TB.js} +50 -28
- package/lib/node/chunk-OGN3ZR35.js +6 -0
- package/lib/node/{chunk-VS3GJPUE.mjs → chunk-UBEFEZXT.mjs} +22 -3
- package/lib/node/{chunk-MVPEJK4V.js → chunk-UF7QIAQ5.js} +23 -4
- package/lib/node/chunk-YQGTMMOZ.mjs +58 -0
- package/lib/node/index.d.ts +3 -2
- package/lib/node/index.js +3 -3
- package/lib/node/index.mjs +2 -2
- package/lib/node/interceptors/ClientRequest/index.d.ts +4 -3
- package/lib/node/interceptors/ClientRequest/index.js +5 -4
- package/lib/node/interceptors/ClientRequest/index.mjs +4 -3
- package/lib/node/interceptors/XMLHttpRequest/index.d.ts +4 -3
- package/lib/node/interceptors/XMLHttpRequest/index.js +5 -4
- package/lib/node/interceptors/XMLHttpRequest/index.mjs +4 -3
- package/lib/node/interceptors/fetch/index.d.ts +2 -1
- package/lib/node/interceptors/fetch/index.js +27 -17
- package/lib/node/interceptors/fetch/index.mjs +25 -15
- package/lib/node/presets/node.d.ts +3 -2
- package/lib/node/presets/node.js +7 -6
- package/lib/node/presets/node.mjs +5 -4
- package/package.json +2 -2
- package/src/BatchInterceptor.test.ts +141 -0
- package/src/BatchInterceptor.ts +38 -4
- package/src/Interceptor.test.ts +46 -0
- package/src/Interceptor.ts +35 -16
- package/src/RemoteHttpInterceptor.ts +11 -9
- package/src/interceptors/ClientRequest/NodeClientRequest.test.ts +10 -10
- package/src/interceptors/ClientRequest/NodeClientRequest.ts +80 -43
- package/src/interceptors/ClientRequest/http.get.ts +3 -1
- package/src/interceptors/ClientRequest/http.request.ts +3 -1
- package/src/interceptors/ClientRequest/index.test.ts +2 -3
- package/src/interceptors/ClientRequest/index.ts +2 -2
- package/src/interceptors/ClientRequest/utils/createRequest.test.ts +2 -2
- package/src/interceptors/ClientRequest/utils/createResponse.test.ts +23 -0
- package/src/interceptors/ClientRequest/utils/createResponse.ts +18 -13
- package/src/interceptors/XMLHttpRequest/XMLHttpRequestProxy.ts +29 -25
- package/src/interceptors/XMLHttpRequest/index.ts +2 -2
- package/src/interceptors/XMLHttpRequest/utils/createResponse.ts +4 -2
- package/src/interceptors/fetch/index.ts +26 -13
- package/src/utils/RequestController.ts +21 -0
- package/src/utils/emitAsync.ts +25 -0
- package/src/utils/responseUtils.ts +5 -0
- package/src/utils/toInteractiveRequest.ts +17 -23
- package/lib/browser/Interceptor-0a020bc4.d.ts +0 -116
- package/lib/browser/chunk-PCFJD76X.js +0 -64
- package/lib/browser/chunk-RT3ATOJH.mjs +0 -64
- package/lib/node/Interceptor-738f79c5.d.ts +0 -116
- package/lib/node/chunk-STA6QBYM.mjs +0 -64
- package/lib/node/chunk-ZJOF5MEZ.js +0 -64
- package/src/utils/AsyncEventEmitter.test.ts +0 -102
- package/src/utils/AsyncEventEmitter.ts +0 -193
- package/src/utils/createLazyCallback.ts +0 -49
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { DeferredPromise } from '@open-draft/deferred-promise';
|
|
2
|
+
import { Logger } from '@open-draft/logger';
|
|
3
|
+
import { Emitter, Listener } from 'strict-event-emitter';
|
|
4
|
+
|
|
5
|
+
declare class RequestController {
|
|
6
|
+
protected request: Request;
|
|
7
|
+
responsePromise: DeferredPromise<Response | undefined>;
|
|
8
|
+
constructor(request: Request);
|
|
9
|
+
respondWith(response?: Response): void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type InteractiveRequest = globalThis.Request & {
|
|
13
|
+
respondWith: RequestController['respondWith'];
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
declare const IS_PATCHED_MODULE: unique symbol;
|
|
17
|
+
type RequestCredentials = 'omit' | 'include' | 'same-origin';
|
|
18
|
+
type HttpRequestEventMap = {
|
|
19
|
+
request: [
|
|
20
|
+
args: {
|
|
21
|
+
request: InteractiveRequest;
|
|
22
|
+
requestId: string;
|
|
23
|
+
}
|
|
24
|
+
];
|
|
25
|
+
response: [
|
|
26
|
+
args: {
|
|
27
|
+
response: Response;
|
|
28
|
+
isMockedResponse: boolean;
|
|
29
|
+
request: Request;
|
|
30
|
+
requestId: string;
|
|
31
|
+
}
|
|
32
|
+
];
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
type InterceptorEventMap = Record<string, any>;
|
|
36
|
+
type InterceptorSubscription = () => void;
|
|
37
|
+
declare function getGlobalSymbol<V>(symbol: Symbol): V | undefined;
|
|
38
|
+
declare function deleteGlobalSymbol(symbol: Symbol): void;
|
|
39
|
+
declare enum InterceptorReadyState {
|
|
40
|
+
INACTIVE = "INACTIVE",
|
|
41
|
+
APPLYING = "APPLYING",
|
|
42
|
+
APPLIED = "APPLIED",
|
|
43
|
+
DISPOSING = "DISPOSING",
|
|
44
|
+
DISPOSED = "DISPOSED"
|
|
45
|
+
}
|
|
46
|
+
type ExtractEventNames<Events extends Record<string, any>> = Events extends Record<infer EventName, any> ? EventName : never;
|
|
47
|
+
declare class Interceptor<Events extends InterceptorEventMap> {
|
|
48
|
+
private readonly symbol;
|
|
49
|
+
protected emitter: Emitter<Events>;
|
|
50
|
+
protected subscriptions: Array<InterceptorSubscription>;
|
|
51
|
+
protected logger: Logger;
|
|
52
|
+
readyState: InterceptorReadyState;
|
|
53
|
+
constructor(symbol: symbol);
|
|
54
|
+
/**
|
|
55
|
+
* Determine if this interceptor can be applied
|
|
56
|
+
* in the current environment.
|
|
57
|
+
*/
|
|
58
|
+
protected checkEnvironment(): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Apply this interceptor to the current process.
|
|
61
|
+
* Returns an already running interceptor instance if it's present.
|
|
62
|
+
*/
|
|
63
|
+
apply(): void;
|
|
64
|
+
/**
|
|
65
|
+
* Setup the module augments and stubs necessary for this interceptor.
|
|
66
|
+
* This method is not run if there's a running interceptor instance
|
|
67
|
+
* to prevent instantiating an interceptor multiple times.
|
|
68
|
+
*/
|
|
69
|
+
protected setup(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Listen to the interceptor's public events.
|
|
72
|
+
*/
|
|
73
|
+
on<EventName extends ExtractEventNames<Events>>(event: EventName, listener: Listener<Events[EventName]>): this;
|
|
74
|
+
once<EventName extends ExtractEventNames<Events>>(event: EventName, listener: Listener<Events[EventName]>): this;
|
|
75
|
+
off<EventName extends ExtractEventNames<Events>>(event: EventName, listener: Listener<Events[EventName]>): this;
|
|
76
|
+
removeAllListeners<EventName extends ExtractEventNames<Events>>(event?: EventName): this;
|
|
77
|
+
/**
|
|
78
|
+
* Disposes of any side-effects this interceptor has introduced.
|
|
79
|
+
*/
|
|
80
|
+
dispose(): void;
|
|
81
|
+
private getInstance;
|
|
82
|
+
private setInstance;
|
|
83
|
+
private clearInstance;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { ExtractEventNames as E, HttpRequestEventMap as H, Interceptor as I, RequestCredentials as R, IS_PATCHED_MODULE as a, InterceptorEventMap as b, InterceptorSubscription as c, deleteGlobalSymbol as d, InterceptorReadyState as e, InteractiveRequest as f, getGlobalSymbol as g };
|
|
@@ -4,13 +4,14 @@ import {
|
|
|
4
4
|
toArrayBuffer
|
|
5
5
|
} from "./chunk-7II4SWKS.mjs";
|
|
6
6
|
import {
|
|
7
|
+
emitAsync,
|
|
7
8
|
toInteractiveRequest,
|
|
8
9
|
uuidv4
|
|
9
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-KK6APRON.mjs";
|
|
10
11
|
import {
|
|
11
12
|
IS_PATCHED_MODULE,
|
|
12
13
|
Interceptor
|
|
13
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-QPMXOLDO.mjs";
|
|
14
15
|
|
|
15
16
|
// src/interceptors/XMLHttpRequest/index.ts
|
|
16
17
|
import { invariant as invariant2 } from "outvariant";
|
|
@@ -201,10 +202,14 @@ function parseJson(data) {
|
|
|
201
202
|
}
|
|
202
203
|
}
|
|
203
204
|
|
|
205
|
+
// src/utils/responseUtils.ts
|
|
206
|
+
var responseStatusCodesWithoutBody = [204, 205, 304];
|
|
207
|
+
|
|
204
208
|
// src/interceptors/XMLHttpRequest/utils/createResponse.ts
|
|
205
|
-
var statusCodesWithoutBody = [204, 205, 304];
|
|
206
209
|
function createResponse(request, body) {
|
|
207
|
-
const responseBodyOrNull =
|
|
210
|
+
const responseBodyOrNull = responseStatusCodesWithoutBody.includes(
|
|
211
|
+
request.status
|
|
212
|
+
) ? null : body;
|
|
208
213
|
return new Response(responseBodyOrNull, {
|
|
209
214
|
status: request.status,
|
|
210
215
|
statusText: request.statusText,
|
|
@@ -652,30 +657,32 @@ function createXMLHttpRequestProxy({
|
|
|
652
657
|
prototypeDescriptors[propertyName]
|
|
653
658
|
);
|
|
654
659
|
}
|
|
655
|
-
const
|
|
660
|
+
const xhrRequestController = new XMLHttpRequestController(
|
|
656
661
|
originalRequest,
|
|
657
662
|
logger
|
|
658
663
|
);
|
|
659
|
-
|
|
660
|
-
const interactiveRequest = toInteractiveRequest(request);
|
|
661
|
-
this.logger.info(
|
|
662
|
-
'emitting the "request" event for %s listener(s)...',
|
|
663
|
-
emitter.listenerCount("request")
|
|
664
|
-
);
|
|
665
|
-
emitter.emit("request", {
|
|
666
|
-
request: interactiveRequest,
|
|
667
|
-
requestId
|
|
668
|
-
});
|
|
664
|
+
xhrRequestController.onRequest = async function({ request, requestId }) {
|
|
665
|
+
const { interactiveRequest, requestController } = toInteractiveRequest(request);
|
|
669
666
|
this.logger.info("awaiting mocked response...");
|
|
667
|
+
emitter.once("request", ({ requestId: pendingRequestId }) => {
|
|
668
|
+
if (pendingRequestId !== requestId) {
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
671
|
+
if (requestController.responsePromise.state === "pending") {
|
|
672
|
+
requestController.respondWith(void 0);
|
|
673
|
+
}
|
|
674
|
+
});
|
|
670
675
|
const resolverResult = await until(async () => {
|
|
671
|
-
|
|
672
|
-
"request",
|
|
673
|
-
(
|
|
674
|
-
return pendingRequestId === requestId;
|
|
675
|
-
}
|
|
676
|
+
this.logger.info(
|
|
677
|
+
'emitting the "request" event for %s listener(s)...',
|
|
678
|
+
emitter.listenerCount("request")
|
|
676
679
|
);
|
|
680
|
+
await emitAsync(emitter, "request", {
|
|
681
|
+
request: interactiveRequest,
|
|
682
|
+
requestId
|
|
683
|
+
});
|
|
677
684
|
this.logger.info('all "request" listeners settled!');
|
|
678
|
-
const
|
|
685
|
+
const mockedResponse2 = await requestController.responsePromise;
|
|
679
686
|
this.logger.info("event.respondWith called with:", mockedResponse2);
|
|
680
687
|
return mockedResponse2;
|
|
681
688
|
});
|
|
@@ -684,7 +691,7 @@ function createXMLHttpRequestProxy({
|
|
|
684
691
|
"request listener threw an exception, aborting request...",
|
|
685
692
|
resolverResult.error
|
|
686
693
|
);
|
|
687
|
-
|
|
694
|
+
xhrRequestController.errorWith(resolverResult.error);
|
|
688
695
|
return;
|
|
689
696
|
}
|
|
690
697
|
const mockedResponse = resolverResult.data;
|
|
@@ -698,16 +705,16 @@ function createXMLHttpRequestProxy({
|
|
|
698
705
|
this.logger.info(
|
|
699
706
|
"received a network error response, rejecting the request promise..."
|
|
700
707
|
);
|
|
701
|
-
|
|
708
|
+
xhrRequestController.errorWith(new TypeError("Network error"));
|
|
702
709
|
return;
|
|
703
710
|
}
|
|
704
|
-
return
|
|
711
|
+
return xhrRequestController.respondWith(mockedResponse);
|
|
705
712
|
}
|
|
706
713
|
this.logger.info(
|
|
707
714
|
"no mocked response received, performing request as-is..."
|
|
708
715
|
);
|
|
709
716
|
};
|
|
710
|
-
|
|
717
|
+
xhrRequestController.onResponse = async function({
|
|
711
718
|
response,
|
|
712
719
|
isMockedResponse,
|
|
713
720
|
request,
|
|
@@ -724,7 +731,7 @@ function createXMLHttpRequestProxy({
|
|
|
724
731
|
requestId
|
|
725
732
|
});
|
|
726
733
|
};
|
|
727
|
-
return
|
|
734
|
+
return xhrRequestController.request;
|
|
728
735
|
}
|
|
729
736
|
});
|
|
730
737
|
return XMLHttpRequestProxy;
|
|
@@ -3,133 +3,7 @@ var IS_PATCHED_MODULE = Symbol("isPatchedModule");
|
|
|
3
3
|
|
|
4
4
|
// src/Interceptor.ts
|
|
5
5
|
var _logger = require('@open-draft/logger');
|
|
6
|
-
|
|
7
|
-
// src/utils/AsyncEventEmitter.ts
|
|
8
|
-
|
|
9
6
|
var _stricteventemitter = require('strict-event-emitter');
|
|
10
|
-
|
|
11
|
-
// src/utils/nextTick.ts
|
|
12
|
-
function nextTick(callback) {
|
|
13
|
-
setTimeout(callback, 0);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// src/utils/AsyncEventEmitter.ts
|
|
17
|
-
var AsyncEventEmitter = class extends _stricteventemitter.Emitter {
|
|
18
|
-
constructor() {
|
|
19
|
-
super();
|
|
20
|
-
this.logger = new (0, _logger.Logger)("async-event-emitter");
|
|
21
|
-
this.queue = /* @__PURE__ */ new Map();
|
|
22
|
-
this.readyState = "ACTIVE" /* ACTIVE */;
|
|
23
|
-
}
|
|
24
|
-
on(eventName, listener) {
|
|
25
|
-
const logger = this.logger.extend("on");
|
|
26
|
-
logger.info('adding "%s" listener...', eventName);
|
|
27
|
-
if (this.readyState === "DEACTIVATED" /* DEACTIVATED */) {
|
|
28
|
-
logger.info("the emitter is destroyed, skipping!");
|
|
29
|
-
return this;
|
|
30
|
-
}
|
|
31
|
-
return super.on(eventName, async (...args) => {
|
|
32
|
-
const queue = this.openListenerQueue(eventName);
|
|
33
|
-
logger.info('awaiting the "%s" listener...', eventName);
|
|
34
|
-
queue.push({
|
|
35
|
-
args,
|
|
36
|
-
done: new Promise(async (resolve, reject) => {
|
|
37
|
-
try {
|
|
38
|
-
await listener(...args);
|
|
39
|
-
resolve();
|
|
40
|
-
logger.info('"%s" listener has resolved!', eventName);
|
|
41
|
-
} catch (error) {
|
|
42
|
-
logger.info('"%s" listener has rejected!', error);
|
|
43
|
-
reject(error);
|
|
44
|
-
}
|
|
45
|
-
})
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
emit(eventName, ...data) {
|
|
50
|
-
const logger = this.logger.extend("emit");
|
|
51
|
-
logger.info('emitting "%s" event...', eventName);
|
|
52
|
-
if (this.readyState === "DEACTIVATED" /* DEACTIVATED */) {
|
|
53
|
-
logger.info("the emitter is destroyed, skipping!");
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
if (this.isInternalEventName(eventName)) {
|
|
57
|
-
return super.emit(eventName, ...data);
|
|
58
|
-
}
|
|
59
|
-
this.openListenerQueue(eventName);
|
|
60
|
-
logger.info('appending a one-time cleanup "%s" listener...', eventName);
|
|
61
|
-
this.once(eventName, () => {
|
|
62
|
-
nextTick(() => {
|
|
63
|
-
this.queue.delete(eventName);
|
|
64
|
-
logger.info('cleaned up "%s" listeners queue!', eventName);
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
return super.emit(eventName, ...data);
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Returns a promise that resolves when all the listeners for the given event
|
|
71
|
-
* has been called. Awaits asynchronous listeners.
|
|
72
|
-
* If the event has no listeners, resolves immediately.
|
|
73
|
-
*/
|
|
74
|
-
async untilIdle(eventName, filter = () => true) {
|
|
75
|
-
const listenersQueue = this.queue.get(eventName) || [];
|
|
76
|
-
await Promise.all(
|
|
77
|
-
listenersQueue.filter(filter).map(({ done }) => done)
|
|
78
|
-
).finally(() => {
|
|
79
|
-
this.queue.delete(eventName);
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
openListenerQueue(eventName) {
|
|
83
|
-
const logger = this.logger.extend("openListenerQueue");
|
|
84
|
-
logger.info('opening "%s" listeners queue...', eventName);
|
|
85
|
-
const queue = this.queue.get(eventName);
|
|
86
|
-
if (!queue) {
|
|
87
|
-
logger.info("no queue found, creating one...");
|
|
88
|
-
this.queue.set(eventName, []);
|
|
89
|
-
return [];
|
|
90
|
-
}
|
|
91
|
-
logger.info("returning an exising queue:", queue);
|
|
92
|
-
return queue;
|
|
93
|
-
}
|
|
94
|
-
removeAllListeners(eventName) {
|
|
95
|
-
const logger = this.logger.extend("removeAllListeners");
|
|
96
|
-
logger.info("event:", eventName);
|
|
97
|
-
if (eventName) {
|
|
98
|
-
this.queue.delete(eventName);
|
|
99
|
-
logger.info(
|
|
100
|
-
'cleared the "%s" listeners queue!',
|
|
101
|
-
eventName,
|
|
102
|
-
this.queue.get(eventName)
|
|
103
|
-
);
|
|
104
|
-
} else {
|
|
105
|
-
this.queue.clear();
|
|
106
|
-
logger.info("cleared the listeners queue!", this.queue);
|
|
107
|
-
}
|
|
108
|
-
return super.removeAllListeners(eventName);
|
|
109
|
-
}
|
|
110
|
-
activate() {
|
|
111
|
-
const logger = this.logger.extend("activate");
|
|
112
|
-
this.readyState = "ACTIVE" /* ACTIVE */;
|
|
113
|
-
logger.info("set state to:", this.readyState);
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Deactivate this event emitter.
|
|
117
|
-
* Deactivated emitter can no longer emit and listen to events
|
|
118
|
-
* and needs to be activated again in order to do so.
|
|
119
|
-
*/
|
|
120
|
-
deactivate() {
|
|
121
|
-
const logger = this.logger.extend("deactivate");
|
|
122
|
-
logger.info("removing all listeners...");
|
|
123
|
-
this.removeAllListeners();
|
|
124
|
-
this.readyState = "DEACTIVATED" /* DEACTIVATED */;
|
|
125
|
-
logger.info("set state to:", this.readyState);
|
|
126
|
-
}
|
|
127
|
-
isInternalEventName(eventName) {
|
|
128
|
-
return eventName === "newListener" || eventName === "removeListener";
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
// src/Interceptor.ts
|
|
133
7
|
function getGlobalSymbol(symbol) {
|
|
134
8
|
return (
|
|
135
9
|
// @ts-ignore https://github.com/Microsoft/TypeScript/issues/24587
|
|
@@ -154,7 +28,7 @@ var Interceptor = class {
|
|
|
154
28
|
constructor(symbol) {
|
|
155
29
|
this.symbol = symbol;
|
|
156
30
|
this.readyState = "INACTIVE" /* INACTIVE */;
|
|
157
|
-
this.emitter = new
|
|
31
|
+
this.emitter = new (0, _stricteventemitter.Emitter)();
|
|
158
32
|
this.subscriptions = [];
|
|
159
33
|
this.logger = new (0, _logger.Logger)(symbol.description);
|
|
160
34
|
this.emitter.setMaxListeners(0);
|
|
@@ -184,8 +58,6 @@ var Interceptor = class {
|
|
|
184
58
|
return;
|
|
185
59
|
}
|
|
186
60
|
this.readyState = "APPLYING" /* APPLYING */;
|
|
187
|
-
this.emitter.activate();
|
|
188
|
-
logger.info("activated the emiter!", this.emitter.readyState);
|
|
189
61
|
const runningInstance = this.getInstance();
|
|
190
62
|
if (runningInstance) {
|
|
191
63
|
logger.info("found a running instance, reusing...");
|
|
@@ -196,6 +68,7 @@ var Interceptor = class {
|
|
|
196
68
|
runningInstance.emitter.removeListener(event, listener);
|
|
197
69
|
logger.info('removed proxied "%s" listener!', event);
|
|
198
70
|
});
|
|
71
|
+
return this;
|
|
199
72
|
};
|
|
200
73
|
this.readyState = "APPLIED" /* APPLIED */;
|
|
201
74
|
return;
|
|
@@ -215,14 +88,27 @@ var Interceptor = class {
|
|
|
215
88
|
/**
|
|
216
89
|
* Listen to the interceptor's public events.
|
|
217
90
|
*/
|
|
218
|
-
on(
|
|
91
|
+
on(event, listener) {
|
|
219
92
|
const logger = this.logger.extend("on");
|
|
220
93
|
if (this.readyState === "DISPOSING" /* DISPOSING */ || this.readyState === "DISPOSED" /* DISPOSED */) {
|
|
221
94
|
logger.info("cannot listen to events, already disposed!");
|
|
222
|
-
return;
|
|
95
|
+
return this;
|
|
223
96
|
}
|
|
224
|
-
logger.info('adding "%s" event listener:',
|
|
225
|
-
this.emitter.on(
|
|
97
|
+
logger.info('adding "%s" event listener:', event, listener.name);
|
|
98
|
+
this.emitter.on(event, listener);
|
|
99
|
+
return this;
|
|
100
|
+
}
|
|
101
|
+
once(event, listener) {
|
|
102
|
+
this.emitter.once(event, listener);
|
|
103
|
+
return this;
|
|
104
|
+
}
|
|
105
|
+
off(event, listener) {
|
|
106
|
+
this.emitter.off(event, listener);
|
|
107
|
+
return this;
|
|
108
|
+
}
|
|
109
|
+
removeAllListeners(event) {
|
|
110
|
+
this.emitter.removeAllListeners(event);
|
|
111
|
+
return this;
|
|
226
112
|
}
|
|
227
113
|
/**
|
|
228
114
|
* Disposes of any side-effects this interceptor has introduced.
|
|
@@ -249,7 +135,7 @@ var Interceptor = class {
|
|
|
249
135
|
this.subscriptions = [];
|
|
250
136
|
logger.info("disposed of all subscriptions!", this.subscriptions.length);
|
|
251
137
|
}
|
|
252
|
-
this.emitter.
|
|
138
|
+
this.emitter.removeAllListeners();
|
|
253
139
|
logger.info("destroyed the listener!");
|
|
254
140
|
this.readyState = "DISPOSED" /* DISPOSED */;
|
|
255
141
|
}
|
|
@@ -6,11 +6,12 @@ var _chunk3LFH2WCFjs = require('./chunk-3LFH2WCF.js');
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
var _chunkPCFJD76Xjs = require('./chunk-PCFJD76X.js');
|
|
10
9
|
|
|
10
|
+
var _chunkX3NRJIZWjs = require('./chunk-X3NRJIZW.js');
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
var _chunkCWVY2E3Wjs = require('./chunk-CWVY2E3W.js');
|
|
14
15
|
|
|
15
16
|
// src/interceptors/XMLHttpRequest/index.ts
|
|
16
17
|
var _outvariant = require('outvariant');
|
|
@@ -201,10 +202,14 @@ function parseJson(data) {
|
|
|
201
202
|
}
|
|
202
203
|
}
|
|
203
204
|
|
|
205
|
+
// src/utils/responseUtils.ts
|
|
206
|
+
var responseStatusCodesWithoutBody = [204, 205, 304];
|
|
207
|
+
|
|
204
208
|
// src/interceptors/XMLHttpRequest/utils/createResponse.ts
|
|
205
|
-
var statusCodesWithoutBody = [204, 205, 304];
|
|
206
209
|
function createResponse(request, body) {
|
|
207
|
-
const responseBodyOrNull =
|
|
210
|
+
const responseBodyOrNull = responseStatusCodesWithoutBody.includes(
|
|
211
|
+
request.status
|
|
212
|
+
) ? null : body;
|
|
208
213
|
return new Response(responseBodyOrNull, {
|
|
209
214
|
status: request.status,
|
|
210
215
|
statusText: request.statusText,
|
|
@@ -237,7 +242,7 @@ var XMLHttpRequestController = class {
|
|
|
237
242
|
this.method = "GET";
|
|
238
243
|
this.url = null;
|
|
239
244
|
this.events = /* @__PURE__ */ new Map();
|
|
240
|
-
this.requestId =
|
|
245
|
+
this.requestId = _chunkX3NRJIZWjs.uuidv4.call(void 0, );
|
|
241
246
|
this.requestHeaders = new Headers();
|
|
242
247
|
this.responseBuffer = new Uint8Array();
|
|
243
248
|
this.request = createProxy(initialRequest, {
|
|
@@ -652,30 +657,32 @@ function createXMLHttpRequestProxy({
|
|
|
652
657
|
prototypeDescriptors[propertyName]
|
|
653
658
|
);
|
|
654
659
|
}
|
|
655
|
-
const
|
|
660
|
+
const xhrRequestController = new XMLHttpRequestController(
|
|
656
661
|
originalRequest,
|
|
657
662
|
logger
|
|
658
663
|
);
|
|
659
|
-
|
|
660
|
-
const interactiveRequest =
|
|
661
|
-
this.logger.info(
|
|
662
|
-
'emitting the "request" event for %s listener(s)...',
|
|
663
|
-
emitter.listenerCount("request")
|
|
664
|
-
);
|
|
665
|
-
emitter.emit("request", {
|
|
666
|
-
request: interactiveRequest,
|
|
667
|
-
requestId
|
|
668
|
-
});
|
|
664
|
+
xhrRequestController.onRequest = async function({ request, requestId }) {
|
|
665
|
+
const { interactiveRequest, requestController } = _chunkX3NRJIZWjs.toInteractiveRequest.call(void 0, request);
|
|
669
666
|
this.logger.info("awaiting mocked response...");
|
|
667
|
+
emitter.once("request", ({ requestId: pendingRequestId }) => {
|
|
668
|
+
if (pendingRequestId !== requestId) {
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
671
|
+
if (requestController.responsePromise.state === "pending") {
|
|
672
|
+
requestController.respondWith(void 0);
|
|
673
|
+
}
|
|
674
|
+
});
|
|
670
675
|
const resolverResult = await _until.until.call(void 0, async () => {
|
|
671
|
-
|
|
672
|
-
"request",
|
|
673
|
-
(
|
|
674
|
-
return pendingRequestId === requestId;
|
|
675
|
-
}
|
|
676
|
+
this.logger.info(
|
|
677
|
+
'emitting the "request" event for %s listener(s)...',
|
|
678
|
+
emitter.listenerCount("request")
|
|
676
679
|
);
|
|
680
|
+
await _chunkX3NRJIZWjs.emitAsync.call(void 0, emitter, "request", {
|
|
681
|
+
request: interactiveRequest,
|
|
682
|
+
requestId
|
|
683
|
+
});
|
|
677
684
|
this.logger.info('all "request" listeners settled!');
|
|
678
|
-
const
|
|
685
|
+
const mockedResponse2 = await requestController.responsePromise;
|
|
679
686
|
this.logger.info("event.respondWith called with:", mockedResponse2);
|
|
680
687
|
return mockedResponse2;
|
|
681
688
|
});
|
|
@@ -684,7 +691,7 @@ function createXMLHttpRequestProxy({
|
|
|
684
691
|
"request listener threw an exception, aborting request...",
|
|
685
692
|
resolverResult.error
|
|
686
693
|
);
|
|
687
|
-
|
|
694
|
+
xhrRequestController.errorWith(resolverResult.error);
|
|
688
695
|
return;
|
|
689
696
|
}
|
|
690
697
|
const mockedResponse = resolverResult.data;
|
|
@@ -698,16 +705,16 @@ function createXMLHttpRequestProxy({
|
|
|
698
705
|
this.logger.info(
|
|
699
706
|
"received a network error response, rejecting the request promise..."
|
|
700
707
|
);
|
|
701
|
-
|
|
708
|
+
xhrRequestController.errorWith(new TypeError("Network error"));
|
|
702
709
|
return;
|
|
703
710
|
}
|
|
704
|
-
return
|
|
711
|
+
return xhrRequestController.respondWith(mockedResponse);
|
|
705
712
|
}
|
|
706
713
|
this.logger.info(
|
|
707
714
|
"no mocked response received, performing request as-is..."
|
|
708
715
|
);
|
|
709
716
|
};
|
|
710
|
-
|
|
717
|
+
xhrRequestController.onResponse = async function({
|
|
711
718
|
response,
|
|
712
719
|
isMockedResponse,
|
|
713
720
|
request,
|
|
@@ -724,14 +731,14 @@ function createXMLHttpRequestProxy({
|
|
|
724
731
|
requestId
|
|
725
732
|
});
|
|
726
733
|
};
|
|
727
|
-
return
|
|
734
|
+
return xhrRequestController.request;
|
|
728
735
|
}
|
|
729
736
|
});
|
|
730
737
|
return XMLHttpRequestProxy;
|
|
731
738
|
}
|
|
732
739
|
|
|
733
740
|
// src/interceptors/XMLHttpRequest/index.ts
|
|
734
|
-
var _XMLHttpRequestInterceptor = class extends
|
|
741
|
+
var _XMLHttpRequestInterceptor = class extends _chunkCWVY2E3Wjs.Interceptor {
|
|
735
742
|
constructor() {
|
|
736
743
|
super(_XMLHttpRequestInterceptor.interceptorSymbol);
|
|
737
744
|
}
|
|
@@ -743,7 +750,7 @@ var _XMLHttpRequestInterceptor = class extends _chunk4CFMDU7Zjs.Interceptor {
|
|
|
743
750
|
logger.info('patching "XMLHttpRequest" module...');
|
|
744
751
|
const PureXMLHttpRequest = globalThis.XMLHttpRequest;
|
|
745
752
|
_outvariant.invariant.call(void 0,
|
|
746
|
-
!PureXMLHttpRequest[
|
|
753
|
+
!PureXMLHttpRequest[_chunkCWVY2E3Wjs.IS_PATCHED_MODULE],
|
|
747
754
|
'Failed to patch the "XMLHttpRequest" module: already patched.'
|
|
748
755
|
);
|
|
749
756
|
globalThis.XMLHttpRequest = createXMLHttpRequestProxy({
|
|
@@ -754,13 +761,13 @@ var _XMLHttpRequestInterceptor = class extends _chunk4CFMDU7Zjs.Interceptor {
|
|
|
754
761
|
'native "XMLHttpRequest" module patched!',
|
|
755
762
|
globalThis.XMLHttpRequest.name
|
|
756
763
|
);
|
|
757
|
-
Object.defineProperty(globalThis.XMLHttpRequest,
|
|
764
|
+
Object.defineProperty(globalThis.XMLHttpRequest, _chunkCWVY2E3Wjs.IS_PATCHED_MODULE, {
|
|
758
765
|
enumerable: true,
|
|
759
766
|
configurable: true,
|
|
760
767
|
value: true
|
|
761
768
|
});
|
|
762
769
|
this.subscriptions.push(() => {
|
|
763
|
-
Object.defineProperty(globalThis.XMLHttpRequest,
|
|
770
|
+
Object.defineProperty(globalThis.XMLHttpRequest, _chunkCWVY2E3Wjs.IS_PATCHED_MODULE, {
|
|
764
771
|
value: void 0
|
|
765
772
|
});
|
|
766
773
|
globalThis.XMLHttpRequest = PureXMLHttpRequest;
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
|
+
emitAsync,
|
|
2
3
|
toInteractiveRequest,
|
|
3
4
|
uuidv4
|
|
4
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-KK6APRON.mjs";
|
|
5
6
|
import {
|
|
6
7
|
IS_PATCHED_MODULE,
|
|
7
8
|
Interceptor
|
|
8
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-QPMXOLDO.mjs";
|
|
9
10
|
|
|
10
11
|
// src/interceptors/fetch/index.ts
|
|
11
|
-
import { DeferredPromise } from "@open-draft/deferred-promise";
|
|
12
12
|
import { invariant } from "outvariant";
|
|
13
|
+
import { DeferredPromise } from "@open-draft/deferred-promise";
|
|
13
14
|
import { until } from "@open-draft/until";
|
|
14
15
|
var _FetchInterceptor = class extends Interceptor {
|
|
15
16
|
constructor() {
|
|
@@ -29,14 +30,18 @@ var _FetchInterceptor = class extends Interceptor {
|
|
|
29
30
|
const requestId = uuidv4();
|
|
30
31
|
const request = new Request(input, init);
|
|
31
32
|
this.logger.info("[%s] %s", request.method, request.url);
|
|
32
|
-
const interactiveRequest = toInteractiveRequest(request);
|
|
33
|
+
const { interactiveRequest, requestController } = toInteractiveRequest(request);
|
|
33
34
|
this.logger.info(
|
|
34
35
|
'emitting the "request" event for %d listener(s)...',
|
|
35
36
|
this.emitter.listenerCount("request")
|
|
36
37
|
);
|
|
37
|
-
this.emitter.
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
this.emitter.once("request", ({ requestId: pendingRequestId }) => {
|
|
39
|
+
if (pendingRequestId !== requestId) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (requestController.responsePromise.state === "pending") {
|
|
43
|
+
requestController.responsePromise.resolve(void 0);
|
|
44
|
+
}
|
|
40
45
|
});
|
|
41
46
|
this.logger.info("awaiting for the mocked response...");
|
|
42
47
|
const signal = interactiveRequest.signal;
|
|
@@ -49,15 +54,20 @@ var _FetchInterceptor = class extends Interceptor {
|
|
|
49
54
|
{ once: true }
|
|
50
55
|
);
|
|
51
56
|
const resolverResult = await until(async () => {
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
const listenersFinished = emitAsync(this.emitter, "request", {
|
|
58
|
+
request: interactiveRequest,
|
|
59
|
+
requestId
|
|
60
|
+
});
|
|
61
|
+
await Promise.race([
|
|
62
|
+
requestAborted,
|
|
63
|
+
// Put the listeners invocation Promise in the same race condition
|
|
64
|
+
// with the request abort Promise because otherwise awaiting the listeners
|
|
65
|
+
// would always yield some response (or undefined).
|
|
66
|
+
listenersFinished,
|
|
67
|
+
requestController.responsePromise
|
|
68
|
+
]);
|
|
59
69
|
this.logger.info("all request listeners have been resolved!");
|
|
60
|
-
const
|
|
70
|
+
const mockedResponse2 = await requestController.responsePromise;
|
|
61
71
|
this.logger.info("event.respondWith called with:", mockedResponse2);
|
|
62
72
|
return mockedResponse2;
|
|
63
73
|
});
|