@mswjs/interceptors 0.22.16 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -11
- package/lib/browser/{Interceptor-c8fc448a.d.ts → Interceptor-0a020bc4.d.ts} +14 -2
- package/lib/browser/{chunk-OQKDMHBL.js → chunk-2TENISKM.js} +21 -18
- package/lib/{node/chunk-IHW3ERPT.js → browser/chunk-3LFH2WCF.js} +1 -9
- package/lib/{node/chunk-MPFSBY4S.js → browser/chunk-4CFMDU7Z.js} +36 -9
- package/lib/{node/chunk-LTX5IGCQ.mjs → browser/chunk-7II4SWKS.mjs} +0 -8
- package/lib/browser/{chunk-CCRODCJY.mjs → chunk-B74BGPYH.mjs} +89 -24
- package/lib/browser/{chunk-MW6NCDWE.mjs → chunk-GXJLJMOT.mjs} +33 -7
- package/lib/browser/{chunk-G2NATYCY.mjs → chunk-LHYX2GOM.mjs} +17 -14
- package/lib/browser/{chunk-RODLGD6G.js → chunk-UGP4JOAM.js} +96 -31
- package/lib/browser/index.d.ts +3 -3
- package/lib/browser/index.js +4 -4
- package/lib/browser/index.mjs +2 -2
- package/lib/browser/interceptors/XMLHttpRequest/index.d.ts +5 -2
- 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 +1 -1
- package/lib/browser/interceptors/fetch/index.js +3 -3
- package/lib/browser/interceptors/fetch/index.mjs +2 -2
- package/lib/browser/presets/browser.d.ts +1 -1
- package/lib/browser/presets/browser.js +6 -6
- package/lib/browser/presets/browser.mjs +4 -4
- package/lib/node/{BatchInterceptor-fe69020d.d.ts → BatchInterceptor-c841b068.d.ts} +1 -1
- package/lib/node/{Interceptor-f9dfe016.d.ts → Interceptor-738f79c5.d.ts} +14 -2
- package/lib/node/RemoteHttpInterceptor.d.ts +4 -5
- package/lib/node/RemoteHttpInterceptor.js +27 -25
- package/lib/node/RemoteHttpInterceptor.mjs +21 -19
- package/lib/node/chunk-3LFH2WCF.js +21 -0
- package/lib/node/chunk-7II4SWKS.mjs +21 -0
- package/lib/node/{chunk-VJDB3MIV.js → chunk-MVPEJK4V.js} +2 -2
- package/lib/node/{chunk-QRCYLMPE.js → chunk-OOSIWXHX.js} +57 -16
- package/lib/node/{chunk-R6MTHW6S.mjs → chunk-PSIO3L7D.mjs} +55 -14
- package/lib/node/{chunk-Y5QA6OEZ.mjs → chunk-RGYCLCLK.mjs} +33 -10
- package/lib/node/{chunk-IAIFDHPP.mjs → chunk-UWSK5F3S.mjs} +89 -24
- package/lib/node/{chunk-NUSH7ACE.mjs → chunk-VS3GJPUE.mjs} +1 -1
- package/lib/{browser/chunk-7VJMJSIJ.js → node/chunk-XYZRP5S2.js} +35 -13
- package/lib/node/{chunk-YFXBOTHW.js → chunk-YCEMBJEM.js} +93 -28
- package/lib/node/index.d.ts +2 -2
- package/lib/node/index.js +4 -4
- package/lib/node/index.mjs +3 -3
- package/lib/node/interceptors/ClientRequest/index.d.ts +1 -1
- package/lib/node/interceptors/ClientRequest/index.js +3 -3
- package/lib/node/interceptors/ClientRequest/index.mjs +2 -2
- package/lib/node/interceptors/XMLHttpRequest/index.d.ts +5 -2
- package/lib/node/interceptors/XMLHttpRequest/index.js +4 -4
- package/lib/node/interceptors/XMLHttpRequest/index.mjs +3 -3
- package/lib/node/interceptors/fetch/index.d.ts +1 -1
- package/lib/node/interceptors/fetch/index.js +18 -15
- package/lib/node/interceptors/fetch/index.mjs +17 -14
- package/lib/node/presets/node.d.ts +1 -1
- package/lib/node/presets/node.js +6 -6
- package/lib/node/presets/node.mjs +4 -4
- package/package.json +15 -18
- package/src/RemoteHttpInterceptor.ts +19 -16
- package/src/glossary.ts +14 -2
- package/src/interceptors/ClientRequest/NodeClientRequest.test.ts +5 -5
- package/src/interceptors/ClientRequest/NodeClientRequest.ts +17 -9
- package/src/interceptors/ClientRequest/index.test.ts +2 -2
- package/src/interceptors/ClientRequest/utils/createRequest.ts +0 -1
- package/src/interceptors/ClientRequest/utils/createResponse.ts +34 -3
- package/src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts +53 -23
- package/src/interceptors/XMLHttpRequest/XMLHttpRequestProxy.ts +16 -7
- package/src/interceptors/XMLHttpRequest/index.ts +3 -3
- package/src/interceptors/XMLHttpRequest/utils/createResponse.ts +27 -5
- package/src/interceptors/fetch/index.ts +18 -15
- package/src/utils/bufferUtils.ts +0 -2
- package/lib/browser/chunk-MQA5WAD4.mjs +0 -2139
- package/lib/browser/chunk-QAZ3SPQZ.js +0 -2139
- package/src/shims/webEncoding.ts +0 -9
package/README.md
CHANGED
|
@@ -116,15 +116,18 @@ interceptor.apply()
|
|
|
116
116
|
|
|
117
117
|
// Listen to any "http.ClientRequest" being dispatched,
|
|
118
118
|
// and log its method and full URL.
|
|
119
|
-
interceptor.on('request', (request, requestId) => {
|
|
119
|
+
interceptor.on('request', ({ request, requestId }) => {
|
|
120
120
|
console.log(request.method, request.url)
|
|
121
121
|
})
|
|
122
122
|
|
|
123
123
|
// Listen to any responses sent to "http.ClientRequest".
|
|
124
124
|
// Note that this listener is read-only and cannot affect responses.
|
|
125
|
-
interceptor.on(
|
|
126
|
-
|
|
127
|
-
})
|
|
125
|
+
interceptor.on(
|
|
126
|
+
'response',
|
|
127
|
+
({ response, isMockedResponse, request, requestId }) => {
|
|
128
|
+
console.log('response to %s %s was:', request.method, request.url, response)
|
|
129
|
+
}
|
|
130
|
+
)
|
|
128
131
|
```
|
|
129
132
|
|
|
130
133
|
All HTTP request interceptors implement the same events:
|
|
@@ -203,7 +206,7 @@ All HTTP request interceptors emit a "request" event. In the listener to this ev
|
|
|
203
206
|
> There are many ways to describe a request in Node.js but this library coerces different request definitions to a single specification-compliant `Request` instance to make the handling consistent.
|
|
204
207
|
|
|
205
208
|
```js
|
|
206
|
-
interceptor.on('
|
|
209
|
+
interceptor.on('request', ({ request, requestId }) => {
|
|
207
210
|
console.log(request.method, request.url)
|
|
208
211
|
})
|
|
209
212
|
```
|
|
@@ -211,7 +214,7 @@ interceptor.on('reqest', (request, requestId) => {
|
|
|
211
214
|
Since the exposed `request` instance implements the Fetch API specification, you can operate with it just as you do with the regular browser request. For example, this is how you would read the request body as JSON:
|
|
212
215
|
|
|
213
216
|
```js
|
|
214
|
-
interceptor.on('request', async (request, requestId) => {
|
|
217
|
+
interceptor.on('request', async ({ request, requestId }) => {
|
|
215
218
|
const json = await request.clone().json()
|
|
216
219
|
})
|
|
217
220
|
```
|
|
@@ -223,7 +226,7 @@ interceptor.on('request', async (request, requestId) => {
|
|
|
223
226
|
Request representations are readonly. You can, however, mutate the intercepted request's headers in the "request" listener:
|
|
224
227
|
|
|
225
228
|
```js
|
|
226
|
-
interceptor.on('request', (request) => {
|
|
229
|
+
interceptor.on('request', ({ request }) => {
|
|
227
230
|
request.headers.set('X-My-Header', 'true')
|
|
228
231
|
})
|
|
229
232
|
```
|
|
@@ -237,7 +240,7 @@ Although this library can be used purely for request introspection purposes, you
|
|
|
237
240
|
Use the `request.respondWith()` method to respond to a request with a mocked response:
|
|
238
241
|
|
|
239
242
|
```js
|
|
240
|
-
interceptor.on('request', (request, requestId) => {
|
|
243
|
+
interceptor.on('request', ({ request, requestId }) => {
|
|
241
244
|
request.respondWith(
|
|
242
245
|
new Response(
|
|
243
246
|
JSON.stringify({
|
|
@@ -267,12 +270,27 @@ Requests must be responded to within the same tick as the request listener. This
|
|
|
267
270
|
```js
|
|
268
271
|
// Respond to all requests with a 500 response
|
|
269
272
|
// delayed by 500ms.
|
|
270
|
-
interceptor.on('request', async (request, requestId) => {
|
|
273
|
+
interceptor.on('request', async ({ request, requestId }) => {
|
|
271
274
|
await sleep(500)
|
|
272
275
|
request.respondWith(new Response(null, { status: 500 }))
|
|
273
276
|
})
|
|
274
277
|
```
|
|
275
278
|
|
|
279
|
+
## Observing responses
|
|
280
|
+
|
|
281
|
+
You can use the "response" event to transparently observe any incoming responses in your Node.js process.
|
|
282
|
+
|
|
283
|
+
```js
|
|
284
|
+
interceptor.on(
|
|
285
|
+
'response',
|
|
286
|
+
({ response, isMockedResponse, request, requestId }) => {
|
|
287
|
+
// react to the incoming response...
|
|
288
|
+
}
|
|
289
|
+
)
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
> Note that the `isMockedResponse` property will only be set to `true` if you resolved this request in the "request" event listener using the `request.respondWith()` method and providing a mocked `Response` instance.
|
|
293
|
+
|
|
276
294
|
## API
|
|
277
295
|
|
|
278
296
|
### `Interceptor`
|
|
@@ -312,7 +330,7 @@ const interceptor = new BatchInterceptor({
|
|
|
312
330
|
|
|
313
331
|
interceptor.apply()
|
|
314
332
|
|
|
315
|
-
interceptor.on('request', (request, requestId) => {
|
|
333
|
+
interceptor.on('request', ({ request, requestId }) => {
|
|
316
334
|
// Inspect the intercepted "request".
|
|
317
335
|
// Optionally, return a mocked response.
|
|
318
336
|
})
|
|
@@ -360,7 +378,7 @@ const resolver = new RemoteHttpResolver({
|
|
|
360
378
|
process: appProcess,
|
|
361
379
|
})
|
|
362
380
|
|
|
363
|
-
resolver.on('request', (request, requestId) => {
|
|
381
|
+
resolver.on('request', ({ request, requestId }) => {
|
|
364
382
|
// Optionally, return a mocked response
|
|
365
383
|
// for a request that occurred in the "appProcess".
|
|
366
384
|
})
|
|
@@ -16,8 +16,20 @@ type InteractiveRequest = globalThis.Request & {
|
|
|
16
16
|
declare const IS_PATCHED_MODULE: unique symbol;
|
|
17
17
|
type RequestCredentials = 'omit' | 'include' | 'same-origin';
|
|
18
18
|
type HttpRequestEventMap = {
|
|
19
|
-
request: [
|
|
20
|
-
|
|
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
|
+
];
|
|
21
33
|
};
|
|
22
34
|
|
|
23
35
|
interface QueueItem<Args extends Array<unknown>> {
|
|
@@ -5,12 +5,12 @@ var _chunkPCFJD76Xjs = require('./chunk-PCFJD76X.js');
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
var
|
|
8
|
+
var _chunk4CFMDU7Zjs = require('./chunk-4CFMDU7Z.js');
|
|
9
9
|
|
|
10
10
|
// src/interceptors/fetch/index.ts
|
|
11
11
|
var _outvariant = require('outvariant');
|
|
12
12
|
var _until = require('@open-draft/until');
|
|
13
|
-
var _FetchInterceptor = class extends
|
|
13
|
+
var _FetchInterceptor = class extends _chunk4CFMDU7Zjs.Interceptor {
|
|
14
14
|
constructor() {
|
|
15
15
|
super(_FetchInterceptor.symbol);
|
|
16
16
|
}
|
|
@@ -20,7 +20,7 @@ var _FetchInterceptor = class extends _chunk7VJMJSIJjs.Interceptor {
|
|
|
20
20
|
setup() {
|
|
21
21
|
const pureFetch = globalThis.fetch;
|
|
22
22
|
_outvariant.invariant.call(void 0,
|
|
23
|
-
!pureFetch[
|
|
23
|
+
!pureFetch[_chunk4CFMDU7Zjs.IS_PATCHED_MODULE],
|
|
24
24
|
'Failed to patch the "fetch" module: already patched.'
|
|
25
25
|
);
|
|
26
26
|
globalThis.fetch = async (input, init) => {
|
|
@@ -33,12 +33,15 @@ var _FetchInterceptor = class extends _chunk7VJMJSIJjs.Interceptor {
|
|
|
33
33
|
'emitting the "request" event for %d listener(s)...',
|
|
34
34
|
this.emitter.listenerCount("request")
|
|
35
35
|
);
|
|
36
|
-
this.emitter.emit("request",
|
|
36
|
+
this.emitter.emit("request", {
|
|
37
|
+
request: interactiveRequest,
|
|
38
|
+
requestId
|
|
39
|
+
});
|
|
37
40
|
this.logger.info("awaiting for the mocked response...");
|
|
38
41
|
const resolverResult = await _until.until.call(void 0, async () => {
|
|
39
42
|
await this.emitter.untilIdle(
|
|
40
43
|
"request",
|
|
41
|
-
({ args: [
|
|
44
|
+
({ args: [{ requestId: pendingRequestId }] }) => {
|
|
42
45
|
return pendingRequestId === requestId;
|
|
43
46
|
}
|
|
44
47
|
);
|
|
@@ -56,13 +59,13 @@ var _FetchInterceptor = class extends _chunk7VJMJSIJjs.Interceptor {
|
|
|
56
59
|
const mockedResponse = resolverResult.data;
|
|
57
60
|
if (mockedResponse && !((_a = request.signal) == null ? void 0 : _a.aborted)) {
|
|
58
61
|
this.logger.info("received mocked response:", mockedResponse);
|
|
59
|
-
const
|
|
60
|
-
this.emitter.emit(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
interactiveRequest,
|
|
62
|
+
const responseClone = mockedResponse.clone();
|
|
63
|
+
this.emitter.emit("response", {
|
|
64
|
+
response: responseClone,
|
|
65
|
+
isMockedResponse: true,
|
|
66
|
+
request: interactiveRequest,
|
|
64
67
|
requestId
|
|
65
|
-
);
|
|
68
|
+
});
|
|
66
69
|
const response = new Response(mockedResponse.body, mockedResponse);
|
|
67
70
|
Object.defineProperty(response, "url", {
|
|
68
71
|
writable: false,
|
|
@@ -76,22 +79,22 @@ var _FetchInterceptor = class extends _chunk7VJMJSIJjs.Interceptor {
|
|
|
76
79
|
return pureFetch(request).then((response) => {
|
|
77
80
|
const responseClone = response.clone();
|
|
78
81
|
this.logger.info("original fetch performed", responseClone);
|
|
79
|
-
this.emitter.emit(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
interactiveRequest,
|
|
82
|
+
this.emitter.emit("response", {
|
|
83
|
+
response: responseClone,
|
|
84
|
+
isMockedResponse: false,
|
|
85
|
+
request: interactiveRequest,
|
|
83
86
|
requestId
|
|
84
|
-
);
|
|
87
|
+
});
|
|
85
88
|
return response;
|
|
86
89
|
});
|
|
87
90
|
};
|
|
88
|
-
Object.defineProperty(globalThis.fetch,
|
|
91
|
+
Object.defineProperty(globalThis.fetch, _chunk4CFMDU7Zjs.IS_PATCHED_MODULE, {
|
|
89
92
|
enumerable: true,
|
|
90
93
|
configurable: true,
|
|
91
94
|
value: true
|
|
92
95
|
});
|
|
93
96
|
this.subscriptions.push(() => {
|
|
94
|
-
Object.defineProperty(globalThis.fetch,
|
|
97
|
+
Object.defineProperty(globalThis.fetch, _chunk4CFMDU7Zjs.IS_PATCHED_MODULE, {
|
|
95
98
|
value: void 0
|
|
96
99
|
});
|
|
97
100
|
globalThis.fetch = pureFetch;
|
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true})
|
|
2
|
-
|
|
3
|
-
var _chunkMPFSBY4Sjs = require('./chunk-MPFSBY4S.js');
|
|
4
|
-
|
|
5
|
-
// src/shims/webEncoding.ts
|
|
6
|
-
var TextEncoder = typeof globalThis.TextEncoder === "undefined" ? _chunkMPFSBY4Sjs.__require.call(void 0, "util").TextEncoder : globalThis.TextEncoder;
|
|
7
|
-
var TextDecoder = typeof globalThis.TextDecoder === "undefined" ? _chunkMPFSBY4Sjs.__require.call(void 0, "util").TextDecoder : globalThis.TextDecoder;
|
|
8
|
-
|
|
9
|
-
// src/utils/bufferUtils.ts
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/utils/bufferUtils.ts
|
|
10
2
|
var encoder = new TextEncoder();
|
|
11
3
|
function encodeBuffer(text) {
|
|
12
4
|
return encoder.encode(text);
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true})
|
|
2
|
-
|
|
3
|
-
}) : x)(function(x) {
|
|
4
|
-
if (typeof require !== "undefined")
|
|
5
|
-
return require.apply(this, arguments);
|
|
6
|
-
throw new Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
-
});
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/glossary.ts
|
|
2
|
+
var IS_PATCHED_MODULE = Symbol("isPatchedModule");
|
|
8
3
|
|
|
9
4
|
// src/Interceptor.ts
|
|
10
5
|
var _logger = require('@open-draft/logger');
|
|
@@ -71,6 +66,11 @@ var AsyncEventEmitter = class extends _stricteventemitter.Emitter {
|
|
|
71
66
|
});
|
|
72
67
|
return super.emit(eventName, ...data);
|
|
73
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
74
|
async untilIdle(eventName, filter = () => true) {
|
|
75
75
|
const listenersQueue = this.queue.get(eventName) || [];
|
|
76
76
|
await Promise.all(
|
|
@@ -112,6 +112,11 @@ var AsyncEventEmitter = class extends _stricteventemitter.Emitter {
|
|
|
112
112
|
this.readyState = "ACTIVE" /* ACTIVE */;
|
|
113
113
|
logger.info("set state to:", this.readyState);
|
|
114
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
|
+
*/
|
|
115
120
|
deactivate() {
|
|
116
121
|
const logger = this.logger.extend("deactivate");
|
|
117
122
|
logger.info("removing all listeners...");
|
|
@@ -126,7 +131,10 @@ var AsyncEventEmitter = class extends _stricteventemitter.Emitter {
|
|
|
126
131
|
|
|
127
132
|
// src/Interceptor.ts
|
|
128
133
|
function getGlobalSymbol(symbol) {
|
|
129
|
-
return
|
|
134
|
+
return (
|
|
135
|
+
// @ts-ignore https://github.com/Microsoft/TypeScript/issues/24587
|
|
136
|
+
globalThis[symbol] || void 0
|
|
137
|
+
);
|
|
130
138
|
}
|
|
131
139
|
function setGlobalSymbol(symbol, value) {
|
|
132
140
|
globalThis[symbol] = value;
|
|
@@ -152,9 +160,17 @@ var Interceptor = class {
|
|
|
152
160
|
this.emitter.setMaxListeners(0);
|
|
153
161
|
this.logger.info("constructing the interceptor...");
|
|
154
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Determine if this interceptor can be applied
|
|
165
|
+
* in the current environment.
|
|
166
|
+
*/
|
|
155
167
|
checkEnvironment() {
|
|
156
168
|
return true;
|
|
157
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* Apply this interceptor to the current process.
|
|
172
|
+
* Returns an already running interceptor instance if it's present.
|
|
173
|
+
*/
|
|
158
174
|
apply() {
|
|
159
175
|
const logger = this.logger.extend("apply");
|
|
160
176
|
logger.info("applying the interceptor...");
|
|
@@ -189,8 +205,16 @@ var Interceptor = class {
|
|
|
189
205
|
this.setInstance();
|
|
190
206
|
this.readyState = "APPLIED" /* APPLIED */;
|
|
191
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Setup the module augments and stubs necessary for this interceptor.
|
|
210
|
+
* This method is not run if there's a running interceptor instance
|
|
211
|
+
* to prevent instantiating an interceptor multiple times.
|
|
212
|
+
*/
|
|
192
213
|
setup() {
|
|
193
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Listen to the interceptor's public events.
|
|
217
|
+
*/
|
|
194
218
|
on(eventName, listener) {
|
|
195
219
|
const logger = this.logger.extend("on");
|
|
196
220
|
if (this.readyState === "DISPOSING" /* DISPOSING */ || this.readyState === "DISPOSED" /* DISPOSED */) {
|
|
@@ -200,6 +224,9 @@ var Interceptor = class {
|
|
|
200
224
|
logger.info('adding "%s" event listener:', eventName, listener.name);
|
|
201
225
|
this.emitter.on(eventName, listener);
|
|
202
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Disposes of any side-effects this interceptor has introduced.
|
|
229
|
+
*/
|
|
203
230
|
dispose() {
|
|
204
231
|
const logger = this.logger.extend("dispose");
|
|
205
232
|
if (this.readyState === "DISPOSED" /* DISPOSED */) {
|
|
@@ -248,4 +275,4 @@ var Interceptor = class {
|
|
|
248
275
|
|
|
249
276
|
|
|
250
277
|
|
|
251
|
-
exports.
|
|
278
|
+
exports.IS_PATCHED_MODULE = IS_PATCHED_MODULE; exports.getGlobalSymbol = getGlobalSymbol; exports.deleteGlobalSymbol = deleteGlobalSymbol; exports.InterceptorReadyState = InterceptorReadyState; exports.Interceptor = Interceptor;
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
__require
|
|
3
|
-
} from "./chunk-Y5QA6OEZ.mjs";
|
|
4
|
-
|
|
5
|
-
// src/shims/webEncoding.ts
|
|
6
|
-
var TextEncoder = typeof globalThis.TextEncoder === "undefined" ? __require("util").TextEncoder : globalThis.TextEncoder;
|
|
7
|
-
var TextDecoder = typeof globalThis.TextDecoder === "undefined" ? __require("util").TextDecoder : globalThis.TextDecoder;
|
|
8
|
-
|
|
9
1
|
// src/utils/bufferUtils.ts
|
|
10
2
|
var encoder = new TextEncoder();
|
|
11
3
|
function encodeBuffer(text) {
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
decodeBuffer,
|
|
3
3
|
encodeBuffer,
|
|
4
4
|
toArrayBuffer
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-7II4SWKS.mjs";
|
|
6
6
|
import {
|
|
7
7
|
toInteractiveRequest,
|
|
8
8
|
uuidv4
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
IS_PATCHED_MODULE,
|
|
12
12
|
Interceptor
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-GXJLJMOT.mjs";
|
|
14
14
|
|
|
15
15
|
// src/interceptors/XMLHttpRequest/index.ts
|
|
16
16
|
import { invariant as invariant2 } from "outvariant";
|
|
@@ -19,7 +19,8 @@ import { invariant as invariant2 } from "outvariant";
|
|
|
19
19
|
import { until } from "@open-draft/until";
|
|
20
20
|
|
|
21
21
|
// src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts
|
|
22
|
-
import {
|
|
22
|
+
import { invariant } from "outvariant";
|
|
23
|
+
import { isNodeProcess } from "is-node-process";
|
|
23
24
|
|
|
24
25
|
// src/interceptors/XMLHttpRequest/utils/concatArrayBuffer.ts
|
|
25
26
|
function concatArrayBuffer(left, right) {
|
|
@@ -201,17 +202,32 @@ function parseJson(data) {
|
|
|
201
202
|
}
|
|
202
203
|
|
|
203
204
|
// src/interceptors/XMLHttpRequest/utils/createResponse.ts
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
return new Response(responseBody, {
|
|
205
|
+
function createResponse(request, body) {
|
|
206
|
+
return new Response(body, {
|
|
207
207
|
status: request.status,
|
|
208
208
|
statusText: request.statusText,
|
|
209
|
-
headers:
|
|
209
|
+
headers: createHeadersFromXMLHttpReqestHeaders(
|
|
210
|
+
request.getAllResponseHeaders()
|
|
211
|
+
)
|
|
210
212
|
});
|
|
211
213
|
}
|
|
214
|
+
function createHeadersFromXMLHttpReqestHeaders(headersString) {
|
|
215
|
+
const headers = new Headers();
|
|
216
|
+
const lines = headersString.split(/[\r\n]+/);
|
|
217
|
+
for (const line of lines) {
|
|
218
|
+
if (line.trim() === "") {
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
const [name, ...parts] = line.split(": ");
|
|
222
|
+
const value = parts.join(": ");
|
|
223
|
+
headers.append(name, value);
|
|
224
|
+
}
|
|
225
|
+
return headers;
|
|
226
|
+
}
|
|
212
227
|
|
|
213
228
|
// src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts
|
|
214
|
-
|
|
229
|
+
var IS_MOCKED_RESPONSE = Symbol("isMockedResponse");
|
|
230
|
+
var IS_NODE = isNodeProcess();
|
|
215
231
|
var XMLHttpRequestController = class {
|
|
216
232
|
constructor(initialRequest, logger) {
|
|
217
233
|
this.initialRequest = initialRequest;
|
|
@@ -219,6 +235,7 @@ var XMLHttpRequestController = class {
|
|
|
219
235
|
this.method = "GET";
|
|
220
236
|
this.url = null;
|
|
221
237
|
this.events = /* @__PURE__ */ new Map();
|
|
238
|
+
this.requestId = uuidv4();
|
|
222
239
|
this.requestHeaders = new Headers();
|
|
223
240
|
this.responseBuffer = new Uint8Array();
|
|
224
241
|
this.request = createProxy(initialRequest, {
|
|
@@ -241,7 +258,6 @@ var XMLHttpRequestController = class {
|
|
|
241
258
|
switch (methodName) {
|
|
242
259
|
case "open": {
|
|
243
260
|
const [method, url] = args;
|
|
244
|
-
this.requestId = uuidv4();
|
|
245
261
|
if (typeof url === "undefined") {
|
|
246
262
|
this.method = "GET";
|
|
247
263
|
this.url = toAbsoluteUrl(method);
|
|
@@ -274,25 +290,35 @@ var XMLHttpRequestController = class {
|
|
|
274
290
|
if (typeof this.onResponse !== "undefined") {
|
|
275
291
|
const fetchResponse = createResponse(
|
|
276
292
|
this.request,
|
|
293
|
+
/**
|
|
294
|
+
* The `response` property is the right way to read
|
|
295
|
+
* the ambiguous response body, as the request's "responseType" may differ.
|
|
296
|
+
* @see https://xhr.spec.whatwg.org/#the-response-attribute
|
|
297
|
+
*/
|
|
277
298
|
this.request.response
|
|
278
299
|
);
|
|
279
|
-
this.onResponse.call(
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
fetchRequest,
|
|
283
|
-
this.requestId
|
|
284
|
-
);
|
|
300
|
+
this.onResponse.call(this, {
|
|
301
|
+
response: fetchResponse,
|
|
302
|
+
isMockedResponse: IS_MOCKED_RESPONSE in this.request,
|
|
303
|
+
request: fetchRequest,
|
|
304
|
+
requestId: this.requestId
|
|
305
|
+
});
|
|
285
306
|
}
|
|
286
307
|
});
|
|
287
308
|
const fetchRequest = this.toFetchApiRequest();
|
|
288
|
-
const onceRequestSettled = ((_a = this.onRequest) == null ? void 0 : _a.call(this,
|
|
309
|
+
const onceRequestSettled = ((_a = this.onRequest) == null ? void 0 : _a.call(this, {
|
|
310
|
+
request: fetchRequest,
|
|
311
|
+
requestId: this.requestId
|
|
312
|
+
})) || Promise.resolve();
|
|
289
313
|
onceRequestSettled.finally(() => {
|
|
290
314
|
if (this.request.readyState < this.request.LOADING) {
|
|
291
315
|
this.logger.info(
|
|
292
316
|
"request callback settled but request has not been handled (readystate %d), performing as-is...",
|
|
293
317
|
this.request.readyState
|
|
294
318
|
);
|
|
295
|
-
|
|
319
|
+
if (IS_NODE) {
|
|
320
|
+
this.request.setRequestHeader("X-Request-Id", this.requestId);
|
|
321
|
+
}
|
|
296
322
|
return invoke();
|
|
297
323
|
}
|
|
298
324
|
});
|
|
@@ -311,12 +337,17 @@ var XMLHttpRequestController = class {
|
|
|
311
337
|
this.events.set(eventName, nextEvents);
|
|
312
338
|
this.logger.info('registered event "%s"', eventName, listener.name);
|
|
313
339
|
}
|
|
340
|
+
/**
|
|
341
|
+
* Responds to the current request with the given
|
|
342
|
+
* Fetch API `Response` instance.
|
|
343
|
+
*/
|
|
314
344
|
respondWith(response) {
|
|
315
345
|
this.logger.info(
|
|
316
346
|
"responding with a mocked response: %d %s",
|
|
317
347
|
response.status,
|
|
318
348
|
response.statusText
|
|
319
349
|
);
|
|
350
|
+
define(this.request, IS_MOCKED_RESPONSE, true);
|
|
320
351
|
define(this.request, "status", response.status);
|
|
321
352
|
define(this.request, "statusText", response.statusText);
|
|
322
353
|
define(this.request, "responseURL", this.url.href);
|
|
@@ -345,7 +376,10 @@ var XMLHttpRequestController = class {
|
|
|
345
376
|
this.logger.info("headers not received yet, returning empty string");
|
|
346
377
|
return "";
|
|
347
378
|
}
|
|
348
|
-
const
|
|
379
|
+
const headersList = Array.from(response.headers.entries());
|
|
380
|
+
const allHeaders = headersList.map(([headerName, headerValue]) => {
|
|
381
|
+
return `${headerName}: ${headerValue}`;
|
|
382
|
+
}).join("\r\n");
|
|
349
383
|
this.logger.info("resolved all response headers to", allHeaders);
|
|
350
384
|
return allHeaders;
|
|
351
385
|
}
|
|
@@ -368,7 +402,12 @@ var XMLHttpRequestController = class {
|
|
|
368
402
|
get: () => this.responseXML
|
|
369
403
|
}
|
|
370
404
|
});
|
|
371
|
-
const totalResponseBodyLength = response.headers.has("Content-Length") ? Number(response.headers.get("Content-Length")) :
|
|
405
|
+
const totalResponseBodyLength = response.headers.has("Content-Length") ? Number(response.headers.get("Content-Length")) : (
|
|
406
|
+
/**
|
|
407
|
+
* @todo Infer the response body length from the response body.
|
|
408
|
+
*/
|
|
409
|
+
void 0
|
|
410
|
+
);
|
|
372
411
|
this.logger.info("calculated response body length", totalResponseBodyLength);
|
|
373
412
|
this.trigger("loadstart", {
|
|
374
413
|
loaded: 0,
|
|
@@ -499,6 +538,9 @@ var XMLHttpRequestController = class {
|
|
|
499
538
|
this.trigger("error");
|
|
500
539
|
this.trigger("loadend");
|
|
501
540
|
}
|
|
541
|
+
/**
|
|
542
|
+
* Transitions this request's `readyState` to the given one.
|
|
543
|
+
*/
|
|
502
544
|
setReadyState(nextReadyState) {
|
|
503
545
|
this.logger.info(
|
|
504
546
|
"setReadyState: %d -> %d",
|
|
@@ -516,6 +558,9 @@ var XMLHttpRequestController = class {
|
|
|
516
558
|
this.trigger("readystatechange");
|
|
517
559
|
}
|
|
518
560
|
}
|
|
561
|
+
/**
|
|
562
|
+
* Triggers given event on the `XMLHttpRequest` instance.
|
|
563
|
+
*/
|
|
519
564
|
trigger(eventName, options) {
|
|
520
565
|
const callback = this.request[`on${eventName}`];
|
|
521
566
|
const event = createEvent(this.request, eventName, options);
|
|
@@ -535,11 +580,17 @@ var XMLHttpRequestController = class {
|
|
|
535
580
|
}
|
|
536
581
|
}
|
|
537
582
|
}
|
|
583
|
+
/**
|
|
584
|
+
* Converts this `XMLHttpRequest` instance into a Fetch API `Request` instance.
|
|
585
|
+
*/
|
|
538
586
|
toFetchApiRequest() {
|
|
539
587
|
this.logger.info("converting request to a Fetch API Request...");
|
|
540
588
|
const fetchRequest = new Request(this.url.href, {
|
|
541
589
|
method: this.method,
|
|
542
590
|
headers: this.requestHeaders,
|
|
591
|
+
/**
|
|
592
|
+
* @see https://xhr.spec.whatwg.org/#cross-origin-credentials
|
|
593
|
+
*/
|
|
543
594
|
credentials: this.request.withCredentials ? "include" : "same-origin",
|
|
544
595
|
body: ["GET", "HEAD"].includes(this.method) ? null : this.requestBody
|
|
545
596
|
});
|
|
@@ -573,6 +624,7 @@ function toAbsoluteUrl(url) {
|
|
|
573
624
|
}
|
|
574
625
|
function define(target, property, value) {
|
|
575
626
|
Reflect.defineProperty(target, property, {
|
|
627
|
+
// Ensure writable properties to allow redefining readonly properties.
|
|
576
628
|
writable: true,
|
|
577
629
|
enumerable: true,
|
|
578
630
|
value
|
|
@@ -602,18 +654,21 @@ function createXMLHttpRequestProxy({
|
|
|
602
654
|
originalRequest,
|
|
603
655
|
logger
|
|
604
656
|
);
|
|
605
|
-
requestController.onRequest = async function(request, requestId) {
|
|
657
|
+
requestController.onRequest = async function({ request, requestId }) {
|
|
606
658
|
const interactiveRequest = toInteractiveRequest(request);
|
|
607
659
|
this.logger.info(
|
|
608
660
|
'emitting the "request" event for %s listener(s)...',
|
|
609
661
|
emitter.listenerCount("request")
|
|
610
662
|
);
|
|
611
|
-
emitter.emit("request",
|
|
663
|
+
emitter.emit("request", {
|
|
664
|
+
request: interactiveRequest,
|
|
665
|
+
requestId
|
|
666
|
+
});
|
|
612
667
|
this.logger.info("awaiting mocked response...");
|
|
613
668
|
const resolverResult = await until(async () => {
|
|
614
669
|
await emitter.untilIdle(
|
|
615
670
|
"request",
|
|
616
|
-
({ args: [
|
|
671
|
+
({ args: [{ requestId: pendingRequestId }] }) => {
|
|
617
672
|
return pendingRequestId === requestId;
|
|
618
673
|
}
|
|
619
674
|
);
|
|
@@ -643,12 +698,22 @@ function createXMLHttpRequestProxy({
|
|
|
643
698
|
"no mocked response received, performing request as-is..."
|
|
644
699
|
);
|
|
645
700
|
};
|
|
646
|
-
requestController.onResponse = async function(
|
|
701
|
+
requestController.onResponse = async function({
|
|
702
|
+
response,
|
|
703
|
+
isMockedResponse,
|
|
704
|
+
request,
|
|
705
|
+
requestId
|
|
706
|
+
}) {
|
|
647
707
|
this.logger.info(
|
|
648
708
|
'emitting the "response" event for %s listener(s)...',
|
|
649
709
|
emitter.listenerCount("response")
|
|
650
710
|
);
|
|
651
|
-
emitter.emit("response",
|
|
711
|
+
emitter.emit("response", {
|
|
712
|
+
response,
|
|
713
|
+
isMockedResponse,
|
|
714
|
+
request,
|
|
715
|
+
requestId
|
|
716
|
+
});
|
|
652
717
|
};
|
|
653
718
|
return requestController.request;
|
|
654
719
|
}
|