@mswjs/interceptors 0.24.0 → 0.25.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/lib/browser/{chunk-B74BGPYH.mjs → chunk-ANLPTCZ5.mjs} +10 -1
- package/lib/browser/{chunk-2TENISKM.js → chunk-DBFLI5DJ.js} +27 -5
- package/lib/browser/{chunk-UGP4JOAM.js → chunk-OSIUQA4X.js} +10 -1
- package/lib/browser/{chunk-LHYX2GOM.mjs → chunk-VMXB5F2J.mjs} +27 -5
- package/lib/browser/interceptors/XMLHttpRequest/index.js +2 -2
- package/lib/browser/interceptors/XMLHttpRequest/index.mjs +1 -1
- package/lib/browser/interceptors/fetch/index.js +2 -2
- package/lib/browser/interceptors/fetch/index.mjs +1 -1
- package/lib/browser/presets/browser.js +4 -4
- package/lib/browser/presets/browser.mjs +2 -2
- package/lib/node/RemoteHttpInterceptor.js +4 -4
- package/lib/node/RemoteHttpInterceptor.mjs +2 -2
- package/lib/node/{chunk-OOSIWXHX.js → chunk-3MYUI4B2.js} +9 -1
- package/lib/node/{chunk-YCEMBJEM.js → chunk-E6YC337Q.js} +10 -1
- package/lib/node/{chunk-UWSK5F3S.mjs → chunk-HSCXCLVT.mjs} +10 -1
- package/lib/node/{chunk-PSIO3L7D.mjs → chunk-OL7OR4RL.mjs} +9 -1
- package/lib/node/interceptors/ClientRequest/index.js +2 -2
- package/lib/node/interceptors/ClientRequest/index.mjs +1 -1
- package/lib/node/interceptors/XMLHttpRequest/index.js +2 -2
- package/lib/node/interceptors/XMLHttpRequest/index.mjs +1 -1
- package/lib/node/interceptors/fetch/index.js +27 -5
- package/lib/node/interceptors/fetch/index.mjs +27 -5
- package/lib/node/presets/node.js +4 -4
- package/lib/node/presets/node.mjs +2 -2
- package/package.json +6 -6
- package/src/interceptors/ClientRequest/NodeClientRequest.ts +18 -1
- package/src/interceptors/ClientRequest/index.test.ts +28 -0
- package/src/interceptors/XMLHttpRequest/XMLHttpRequestProxy.ts +9 -0
- package/src/interceptors/XMLHttpRequest/utils/createResponse.ts +15 -1
- package/src/interceptors/fetch/index.ts +45 -5
|
@@ -202,8 +202,10 @@ function parseJson(data) {
|
|
|
202
202
|
}
|
|
203
203
|
|
|
204
204
|
// src/interceptors/XMLHttpRequest/utils/createResponse.ts
|
|
205
|
+
var statusCodesWithoutBody = [204, 205, 304];
|
|
205
206
|
function createResponse(request, body) {
|
|
206
|
-
|
|
207
|
+
const responseBodyOrNull = statusCodesWithoutBody.includes(request.status) ? null : body;
|
|
208
|
+
return new Response(responseBodyOrNull, {
|
|
207
209
|
status: request.status,
|
|
208
210
|
statusText: request.statusText,
|
|
209
211
|
headers: createHeadersFromXMLHttpReqestHeaders(
|
|
@@ -692,6 +694,13 @@ function createXMLHttpRequestProxy({
|
|
|
692
694
|
mockedResponse.status,
|
|
693
695
|
mockedResponse.statusText
|
|
694
696
|
);
|
|
697
|
+
if (mockedResponse.type === "error") {
|
|
698
|
+
this.logger.info(
|
|
699
|
+
"received a network error response, rejecting the request promise..."
|
|
700
|
+
);
|
|
701
|
+
requestController.errorWith(new TypeError("Network error"));
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
695
704
|
return requestController.respondWith(mockedResponse);
|
|
696
705
|
}
|
|
697
706
|
this.logger.info(
|
|
@@ -8,6 +8,7 @@ var _chunkPCFJD76Xjs = require('./chunk-PCFJD76X.js');
|
|
|
8
8
|
var _chunk4CFMDU7Zjs = require('./chunk-4CFMDU7Z.js');
|
|
9
9
|
|
|
10
10
|
// src/interceptors/fetch/index.ts
|
|
11
|
+
var _deferredpromise = require('@open-draft/deferred-promise');
|
|
11
12
|
var _outvariant = require('outvariant');
|
|
12
13
|
var _until = require('@open-draft/until');
|
|
13
14
|
var _FetchInterceptor = class extends _chunk4CFMDU7Zjs.Interceptor {
|
|
@@ -38,27 +39,43 @@ var _FetchInterceptor = class extends _chunk4CFMDU7Zjs.Interceptor {
|
|
|
38
39
|
requestId
|
|
39
40
|
});
|
|
40
41
|
this.logger.info("awaiting for the mocked response...");
|
|
42
|
+
const signal = interactiveRequest.signal;
|
|
43
|
+
const requestAborted = new (0, _deferredpromise.DeferredPromise)();
|
|
44
|
+
signal.addEventListener(
|
|
45
|
+
"abort",
|
|
46
|
+
() => {
|
|
47
|
+
requestAborted.reject(signal.reason);
|
|
48
|
+
},
|
|
49
|
+
{ once: true }
|
|
50
|
+
);
|
|
41
51
|
const resolverResult = await _until.until.call(void 0, async () => {
|
|
42
|
-
|
|
52
|
+
const allListenersResolved = this.emitter.untilIdle(
|
|
43
53
|
"request",
|
|
44
54
|
({ args: [{ requestId: pendingRequestId }] }) => {
|
|
45
55
|
return pendingRequestId === requestId;
|
|
46
56
|
}
|
|
47
57
|
);
|
|
58
|
+
await Promise.race([requestAborted, allListenersResolved]);
|
|
48
59
|
this.logger.info("all request listeners have been resolved!");
|
|
49
60
|
const [mockedResponse2] = await interactiveRequest.respondWith.invoked();
|
|
50
61
|
this.logger.info("event.respondWith called with:", mockedResponse2);
|
|
51
62
|
return mockedResponse2;
|
|
52
63
|
});
|
|
64
|
+
if (requestAborted.state === "rejected") {
|
|
65
|
+
return Promise.reject(requestAborted.rejectionReason);
|
|
66
|
+
}
|
|
53
67
|
if (resolverResult.error) {
|
|
54
|
-
|
|
55
|
-
cause: resolverResult.error
|
|
56
|
-
});
|
|
57
|
-
return Promise.reject(error);
|
|
68
|
+
return Promise.reject(createNetworkError(resolverResult.error));
|
|
58
69
|
}
|
|
59
70
|
const mockedResponse = resolverResult.data;
|
|
60
71
|
if (mockedResponse && !((_a = request.signal) == null ? void 0 : _a.aborted)) {
|
|
61
72
|
this.logger.info("received mocked response:", mockedResponse);
|
|
73
|
+
if (mockedResponse.type === "error") {
|
|
74
|
+
this.logger.info(
|
|
75
|
+
"received a network error response, rejecting the request promise..."
|
|
76
|
+
);
|
|
77
|
+
return Promise.reject(createNetworkError(mockedResponse));
|
|
78
|
+
}
|
|
62
79
|
const responseClone = mockedResponse.clone();
|
|
63
80
|
this.emitter.emit("response", {
|
|
64
81
|
response: responseClone,
|
|
@@ -107,6 +124,11 @@ var _FetchInterceptor = class extends _chunk4CFMDU7Zjs.Interceptor {
|
|
|
107
124
|
};
|
|
108
125
|
var FetchInterceptor = _FetchInterceptor;
|
|
109
126
|
FetchInterceptor.symbol = Symbol("fetch");
|
|
127
|
+
function createNetworkError(cause) {
|
|
128
|
+
return Object.assign(new TypeError("Failed to fetch"), {
|
|
129
|
+
cause
|
|
130
|
+
});
|
|
131
|
+
}
|
|
110
132
|
|
|
111
133
|
|
|
112
134
|
|
|
@@ -202,8 +202,10 @@ function parseJson(data) {
|
|
|
202
202
|
}
|
|
203
203
|
|
|
204
204
|
// src/interceptors/XMLHttpRequest/utils/createResponse.ts
|
|
205
|
+
var statusCodesWithoutBody = [204, 205, 304];
|
|
205
206
|
function createResponse(request, body) {
|
|
206
|
-
|
|
207
|
+
const responseBodyOrNull = statusCodesWithoutBody.includes(request.status) ? null : body;
|
|
208
|
+
return new Response(responseBodyOrNull, {
|
|
207
209
|
status: request.status,
|
|
208
210
|
statusText: request.statusText,
|
|
209
211
|
headers: createHeadersFromXMLHttpReqestHeaders(
|
|
@@ -692,6 +694,13 @@ function createXMLHttpRequestProxy({
|
|
|
692
694
|
mockedResponse.status,
|
|
693
695
|
mockedResponse.statusText
|
|
694
696
|
);
|
|
697
|
+
if (mockedResponse.type === "error") {
|
|
698
|
+
this.logger.info(
|
|
699
|
+
"received a network error response, rejecting the request promise..."
|
|
700
|
+
);
|
|
701
|
+
requestController.errorWith(new TypeError("Network error"));
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
695
704
|
return requestController.respondWith(mockedResponse);
|
|
696
705
|
}
|
|
697
706
|
this.logger.info(
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
} from "./chunk-GXJLJMOT.mjs";
|
|
9
9
|
|
|
10
10
|
// src/interceptors/fetch/index.ts
|
|
11
|
+
import { DeferredPromise } from "@open-draft/deferred-promise";
|
|
11
12
|
import { invariant } from "outvariant";
|
|
12
13
|
import { until } from "@open-draft/until";
|
|
13
14
|
var _FetchInterceptor = class extends Interceptor {
|
|
@@ -38,27 +39,43 @@ var _FetchInterceptor = class extends Interceptor {
|
|
|
38
39
|
requestId
|
|
39
40
|
});
|
|
40
41
|
this.logger.info("awaiting for the mocked response...");
|
|
42
|
+
const signal = interactiveRequest.signal;
|
|
43
|
+
const requestAborted = new DeferredPromise();
|
|
44
|
+
signal.addEventListener(
|
|
45
|
+
"abort",
|
|
46
|
+
() => {
|
|
47
|
+
requestAborted.reject(signal.reason);
|
|
48
|
+
},
|
|
49
|
+
{ once: true }
|
|
50
|
+
);
|
|
41
51
|
const resolverResult = await until(async () => {
|
|
42
|
-
|
|
52
|
+
const allListenersResolved = this.emitter.untilIdle(
|
|
43
53
|
"request",
|
|
44
54
|
({ args: [{ requestId: pendingRequestId }] }) => {
|
|
45
55
|
return pendingRequestId === requestId;
|
|
46
56
|
}
|
|
47
57
|
);
|
|
58
|
+
await Promise.race([requestAborted, allListenersResolved]);
|
|
48
59
|
this.logger.info("all request listeners have been resolved!");
|
|
49
60
|
const [mockedResponse2] = await interactiveRequest.respondWith.invoked();
|
|
50
61
|
this.logger.info("event.respondWith called with:", mockedResponse2);
|
|
51
62
|
return mockedResponse2;
|
|
52
63
|
});
|
|
64
|
+
if (requestAborted.state === "rejected") {
|
|
65
|
+
return Promise.reject(requestAborted.rejectionReason);
|
|
66
|
+
}
|
|
53
67
|
if (resolverResult.error) {
|
|
54
|
-
|
|
55
|
-
cause: resolverResult.error
|
|
56
|
-
});
|
|
57
|
-
return Promise.reject(error);
|
|
68
|
+
return Promise.reject(createNetworkError(resolverResult.error));
|
|
58
69
|
}
|
|
59
70
|
const mockedResponse = resolverResult.data;
|
|
60
71
|
if (mockedResponse && !((_a = request.signal) == null ? void 0 : _a.aborted)) {
|
|
61
72
|
this.logger.info("received mocked response:", mockedResponse);
|
|
73
|
+
if (mockedResponse.type === "error") {
|
|
74
|
+
this.logger.info(
|
|
75
|
+
"received a network error response, rejecting the request promise..."
|
|
76
|
+
);
|
|
77
|
+
return Promise.reject(createNetworkError(mockedResponse));
|
|
78
|
+
}
|
|
62
79
|
const responseClone = mockedResponse.clone();
|
|
63
80
|
this.emitter.emit("response", {
|
|
64
81
|
response: responseClone,
|
|
@@ -107,6 +124,11 @@ var _FetchInterceptor = class extends Interceptor {
|
|
|
107
124
|
};
|
|
108
125
|
var FetchInterceptor = _FetchInterceptor;
|
|
109
126
|
FetchInterceptor.symbol = Symbol("fetch");
|
|
127
|
+
function createNetworkError(cause) {
|
|
128
|
+
return Object.assign(new TypeError("Failed to fetch"), {
|
|
129
|
+
cause
|
|
130
|
+
});
|
|
131
|
+
}
|
|
110
132
|
|
|
111
133
|
export {
|
|
112
134
|
FetchInterceptor
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkOSIUQA4Xjs = require('../../chunk-OSIUQA4X.js');
|
|
4
4
|
require('../../chunk-3LFH2WCF.js');
|
|
5
5
|
require('../../chunk-PCFJD76X.js');
|
|
6
6
|
require('../../chunk-4CFMDU7Z.js');
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
exports.XMLHttpRequestInterceptor =
|
|
9
|
+
exports.XMLHttpRequestInterceptor = _chunkOSIUQA4Xjs.XMLHttpRequestInterceptor;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkDBFLI5DJjs = require('../../chunk-DBFLI5DJ.js');
|
|
4
4
|
require('../../chunk-PCFJD76X.js');
|
|
5
5
|
require('../../chunk-4CFMDU7Z.js');
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
exports.FetchInterceptor =
|
|
8
|
+
exports.FetchInterceptor = _chunkDBFLI5DJjs.FetchInterceptor;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkOSIUQA4Xjs = require('../chunk-OSIUQA4X.js');
|
|
4
4
|
require('../chunk-3LFH2WCF.js');
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _chunkDBFLI5DJjs = require('../chunk-DBFLI5DJ.js');
|
|
8
8
|
require('../chunk-PCFJD76X.js');
|
|
9
9
|
require('../chunk-4CFMDU7Z.js');
|
|
10
10
|
|
|
11
11
|
// src/presets/browser.ts
|
|
12
12
|
var browser_default = [
|
|
13
|
-
new (0,
|
|
14
|
-
new (0,
|
|
13
|
+
new (0, _chunkDBFLI5DJjs.FetchInterceptor)(),
|
|
14
|
+
new (0, _chunkOSIUQA4Xjs.XMLHttpRequestInterceptor)()
|
|
15
15
|
];
|
|
16
16
|
|
|
17
17
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
XMLHttpRequestInterceptor
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-ANLPTCZ5.mjs";
|
|
4
4
|
import "../chunk-7II4SWKS.mjs";
|
|
5
5
|
import {
|
|
6
6
|
FetchInterceptor
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-VMXB5F2J.mjs";
|
|
8
8
|
import "../chunk-RT3ATOJH.mjs";
|
|
9
9
|
import "../chunk-GXJLJMOT.mjs";
|
|
10
10
|
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
var _chunkMVPEJK4Vjs = require('./chunk-MVPEJK4V.js');
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunk3MYUI4B2js = require('./chunk-3MYUI4B2.js');
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
var
|
|
9
|
+
var _chunkE6YC337Qjs = require('./chunk-E6YC337Q.js');
|
|
10
10
|
require('./chunk-3LFH2WCF.js');
|
|
11
11
|
require('./chunk-VQ4DZOBB.js');
|
|
12
12
|
|
|
@@ -22,8 +22,8 @@ var RemoteHttpInterceptor = class extends _chunkMVPEJK4Vjs.BatchInterceptor {
|
|
|
22
22
|
super({
|
|
23
23
|
name: "remote-interceptor",
|
|
24
24
|
interceptors: [
|
|
25
|
-
new (0,
|
|
26
|
-
new (0,
|
|
25
|
+
new (0, _chunk3MYUI4B2js.ClientRequestInterceptor)(),
|
|
26
|
+
new (0, _chunkE6YC337Qjs.XMLHttpRequestInterceptor)()
|
|
27
27
|
]
|
|
28
28
|
});
|
|
29
29
|
}
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
} from "./chunk-VS3GJPUE.mjs";
|
|
4
4
|
import {
|
|
5
5
|
ClientRequestInterceptor
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-OL7OR4RL.mjs";
|
|
7
7
|
import {
|
|
8
8
|
XMLHttpRequestInterceptor
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-HSCXCLVT.mjs";
|
|
10
10
|
import "./chunk-7II4SWKS.mjs";
|
|
11
11
|
import "./chunk-GFH37L5D.mjs";
|
|
12
12
|
import {
|
|
@@ -249,8 +249,16 @@ var _NodeClientRequest = class extends _http.ClientRequest {
|
|
|
249
249
|
}
|
|
250
250
|
const mockedResponse = resolverResult.data;
|
|
251
251
|
if (mockedResponse) {
|
|
252
|
-
const responseClone = mockedResponse.clone();
|
|
253
252
|
this.logger.info("received mocked response:", mockedResponse);
|
|
253
|
+
if (mockedResponse.type === "error") {
|
|
254
|
+
this.logger.info(
|
|
255
|
+
"received network error response, aborting request..."
|
|
256
|
+
);
|
|
257
|
+
this.emit("error", new TypeError("Network error"));
|
|
258
|
+
this.terminate();
|
|
259
|
+
return this;
|
|
260
|
+
}
|
|
261
|
+
const responseClone = mockedResponse.clone();
|
|
254
262
|
this.responseSource = "mock";
|
|
255
263
|
this.respondWith(mockedResponse);
|
|
256
264
|
this.logger.info(
|
|
@@ -204,8 +204,10 @@ function parseJson(data) {
|
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
// src/interceptors/XMLHttpRequest/utils/createResponse.ts
|
|
207
|
+
var statusCodesWithoutBody = [204, 205, 304];
|
|
207
208
|
function createResponse(request, body) {
|
|
208
|
-
|
|
209
|
+
const responseBodyOrNull = statusCodesWithoutBody.includes(request.status) ? null : body;
|
|
210
|
+
return new Response(responseBodyOrNull, {
|
|
209
211
|
status: request.status,
|
|
210
212
|
statusText: request.statusText,
|
|
211
213
|
headers: createHeadersFromXMLHttpReqestHeaders(
|
|
@@ -694,6 +696,13 @@ function createXMLHttpRequestProxy({
|
|
|
694
696
|
mockedResponse.status,
|
|
695
697
|
mockedResponse.statusText
|
|
696
698
|
);
|
|
699
|
+
if (mockedResponse.type === "error") {
|
|
700
|
+
this.logger.info(
|
|
701
|
+
"received a network error response, rejecting the request promise..."
|
|
702
|
+
);
|
|
703
|
+
requestController.errorWith(new TypeError("Network error"));
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
697
706
|
return requestController.respondWith(mockedResponse);
|
|
698
707
|
}
|
|
699
708
|
this.logger.info(
|
|
@@ -204,8 +204,10 @@ function parseJson(data) {
|
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
// src/interceptors/XMLHttpRequest/utils/createResponse.ts
|
|
207
|
+
var statusCodesWithoutBody = [204, 205, 304];
|
|
207
208
|
function createResponse(request, body) {
|
|
208
|
-
|
|
209
|
+
const responseBodyOrNull = statusCodesWithoutBody.includes(request.status) ? null : body;
|
|
210
|
+
return new Response(responseBodyOrNull, {
|
|
209
211
|
status: request.status,
|
|
210
212
|
statusText: request.statusText,
|
|
211
213
|
headers: createHeadersFromXMLHttpReqestHeaders(
|
|
@@ -694,6 +696,13 @@ function createXMLHttpRequestProxy({
|
|
|
694
696
|
mockedResponse.status,
|
|
695
697
|
mockedResponse.statusText
|
|
696
698
|
);
|
|
699
|
+
if (mockedResponse.type === "error") {
|
|
700
|
+
this.logger.info(
|
|
701
|
+
"received a network error response, rejecting the request promise..."
|
|
702
|
+
);
|
|
703
|
+
requestController.errorWith(new TypeError("Network error"));
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
697
706
|
return requestController.respondWith(mockedResponse);
|
|
698
707
|
}
|
|
699
708
|
this.logger.info(
|
|
@@ -249,8 +249,16 @@ var _NodeClientRequest = class extends ClientRequest {
|
|
|
249
249
|
}
|
|
250
250
|
const mockedResponse = resolverResult.data;
|
|
251
251
|
if (mockedResponse) {
|
|
252
|
-
const responseClone = mockedResponse.clone();
|
|
253
252
|
this.logger.info("received mocked response:", mockedResponse);
|
|
253
|
+
if (mockedResponse.type === "error") {
|
|
254
|
+
this.logger.info(
|
|
255
|
+
"received network error response, aborting request..."
|
|
256
|
+
);
|
|
257
|
+
this.emit("error", new TypeError("Network error"));
|
|
258
|
+
this.terminate();
|
|
259
|
+
return this;
|
|
260
|
+
}
|
|
261
|
+
const responseClone = mockedResponse.clone();
|
|
254
262
|
this.responseSource = "mock";
|
|
255
263
|
this.respondWith(mockedResponse);
|
|
256
264
|
this.logger.info(
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunk3MYUI4B2js = require('../../chunk-3MYUI4B2.js');
|
|
4
4
|
require('../../chunk-ZJOF5MEZ.js');
|
|
5
5
|
require('../../chunk-XYZRP5S2.js');
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
exports.ClientRequestInterceptor =
|
|
8
|
+
exports.ClientRequestInterceptor = _chunk3MYUI4B2js.ClientRequestInterceptor;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkE6YC337Qjs = require('../../chunk-E6YC337Q.js');
|
|
4
4
|
require('../../chunk-3LFH2WCF.js');
|
|
5
5
|
require('../../chunk-VQ4DZOBB.js');
|
|
6
6
|
require('../../chunk-ZJOF5MEZ.js');
|
|
7
7
|
require('../../chunk-XYZRP5S2.js');
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
exports.XMLHttpRequestInterceptor =
|
|
10
|
+
exports.XMLHttpRequestInterceptor = _chunkE6YC337Qjs.XMLHttpRequestInterceptor;
|
|
@@ -10,6 +10,7 @@ var _chunkZJOF5MEZjs = require('../../chunk-ZJOF5MEZ.js');
|
|
|
10
10
|
var _chunkXYZRP5S2js = require('../../chunk-XYZRP5S2.js');
|
|
11
11
|
|
|
12
12
|
// src/interceptors/fetch/index.ts
|
|
13
|
+
var _deferredpromise = require('@open-draft/deferred-promise');
|
|
13
14
|
var _outvariant = require('outvariant');
|
|
14
15
|
var _until = require('@open-draft/until');
|
|
15
16
|
var _FetchInterceptor = class extends _chunkXYZRP5S2js.Interceptor {
|
|
@@ -40,27 +41,43 @@ var _FetchInterceptor = class extends _chunkXYZRP5S2js.Interceptor {
|
|
|
40
41
|
requestId
|
|
41
42
|
});
|
|
42
43
|
this.logger.info("awaiting for the mocked response...");
|
|
44
|
+
const signal = interactiveRequest.signal;
|
|
45
|
+
const requestAborted = new (0, _deferredpromise.DeferredPromise)();
|
|
46
|
+
signal.addEventListener(
|
|
47
|
+
"abort",
|
|
48
|
+
() => {
|
|
49
|
+
requestAborted.reject(signal.reason);
|
|
50
|
+
},
|
|
51
|
+
{ once: true }
|
|
52
|
+
);
|
|
43
53
|
const resolverResult = await _until.until.call(void 0, async () => {
|
|
44
|
-
|
|
54
|
+
const allListenersResolved = this.emitter.untilIdle(
|
|
45
55
|
"request",
|
|
46
56
|
({ args: [{ requestId: pendingRequestId }] }) => {
|
|
47
57
|
return pendingRequestId === requestId;
|
|
48
58
|
}
|
|
49
59
|
);
|
|
60
|
+
await Promise.race([requestAborted, allListenersResolved]);
|
|
50
61
|
this.logger.info("all request listeners have been resolved!");
|
|
51
62
|
const [mockedResponse2] = await interactiveRequest.respondWith.invoked();
|
|
52
63
|
this.logger.info("event.respondWith called with:", mockedResponse2);
|
|
53
64
|
return mockedResponse2;
|
|
54
65
|
});
|
|
66
|
+
if (requestAborted.state === "rejected") {
|
|
67
|
+
return Promise.reject(requestAborted.rejectionReason);
|
|
68
|
+
}
|
|
55
69
|
if (resolverResult.error) {
|
|
56
|
-
|
|
57
|
-
cause: resolverResult.error
|
|
58
|
-
});
|
|
59
|
-
return Promise.reject(error);
|
|
70
|
+
return Promise.reject(createNetworkError(resolverResult.error));
|
|
60
71
|
}
|
|
61
72
|
const mockedResponse = resolverResult.data;
|
|
62
73
|
if (mockedResponse && !((_a = request.signal) == null ? void 0 : _a.aborted)) {
|
|
63
74
|
this.logger.info("received mocked response:", mockedResponse);
|
|
75
|
+
if (mockedResponse.type === "error") {
|
|
76
|
+
this.logger.info(
|
|
77
|
+
"received a network error response, rejecting the request promise..."
|
|
78
|
+
);
|
|
79
|
+
return Promise.reject(createNetworkError(mockedResponse));
|
|
80
|
+
}
|
|
64
81
|
const responseClone = mockedResponse.clone();
|
|
65
82
|
this.emitter.emit("response", {
|
|
66
83
|
response: responseClone,
|
|
@@ -109,6 +126,11 @@ var _FetchInterceptor = class extends _chunkXYZRP5S2js.Interceptor {
|
|
|
109
126
|
};
|
|
110
127
|
var FetchInterceptor = _FetchInterceptor;
|
|
111
128
|
FetchInterceptor.symbol = Symbol("fetch");
|
|
129
|
+
function createNetworkError(cause) {
|
|
130
|
+
return Object.assign(new TypeError("Failed to fetch"), {
|
|
131
|
+
cause
|
|
132
|
+
});
|
|
133
|
+
}
|
|
112
134
|
|
|
113
135
|
|
|
114
136
|
exports.FetchInterceptor = FetchInterceptor;
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
} from "../../chunk-RGYCLCLK.mjs";
|
|
11
11
|
|
|
12
12
|
// src/interceptors/fetch/index.ts
|
|
13
|
+
import { DeferredPromise } from "@open-draft/deferred-promise";
|
|
13
14
|
import { invariant } from "outvariant";
|
|
14
15
|
import { until } from "@open-draft/until";
|
|
15
16
|
var _FetchInterceptor = class extends Interceptor {
|
|
@@ -40,27 +41,43 @@ var _FetchInterceptor = class extends Interceptor {
|
|
|
40
41
|
requestId
|
|
41
42
|
});
|
|
42
43
|
this.logger.info("awaiting for the mocked response...");
|
|
44
|
+
const signal = interactiveRequest.signal;
|
|
45
|
+
const requestAborted = new DeferredPromise();
|
|
46
|
+
signal.addEventListener(
|
|
47
|
+
"abort",
|
|
48
|
+
() => {
|
|
49
|
+
requestAborted.reject(signal.reason);
|
|
50
|
+
},
|
|
51
|
+
{ once: true }
|
|
52
|
+
);
|
|
43
53
|
const resolverResult = await until(async () => {
|
|
44
|
-
|
|
54
|
+
const allListenersResolved = this.emitter.untilIdle(
|
|
45
55
|
"request",
|
|
46
56
|
({ args: [{ requestId: pendingRequestId }] }) => {
|
|
47
57
|
return pendingRequestId === requestId;
|
|
48
58
|
}
|
|
49
59
|
);
|
|
60
|
+
await Promise.race([requestAborted, allListenersResolved]);
|
|
50
61
|
this.logger.info("all request listeners have been resolved!");
|
|
51
62
|
const [mockedResponse2] = await interactiveRequest.respondWith.invoked();
|
|
52
63
|
this.logger.info("event.respondWith called with:", mockedResponse2);
|
|
53
64
|
return mockedResponse2;
|
|
54
65
|
});
|
|
66
|
+
if (requestAborted.state === "rejected") {
|
|
67
|
+
return Promise.reject(requestAborted.rejectionReason);
|
|
68
|
+
}
|
|
55
69
|
if (resolverResult.error) {
|
|
56
|
-
|
|
57
|
-
cause: resolverResult.error
|
|
58
|
-
});
|
|
59
|
-
return Promise.reject(error);
|
|
70
|
+
return Promise.reject(createNetworkError(resolverResult.error));
|
|
60
71
|
}
|
|
61
72
|
const mockedResponse = resolverResult.data;
|
|
62
73
|
if (mockedResponse && !((_a = request.signal) == null ? void 0 : _a.aborted)) {
|
|
63
74
|
this.logger.info("received mocked response:", mockedResponse);
|
|
75
|
+
if (mockedResponse.type === "error") {
|
|
76
|
+
this.logger.info(
|
|
77
|
+
"received a network error response, rejecting the request promise..."
|
|
78
|
+
);
|
|
79
|
+
return Promise.reject(createNetworkError(mockedResponse));
|
|
80
|
+
}
|
|
64
81
|
const responseClone = mockedResponse.clone();
|
|
65
82
|
this.emitter.emit("response", {
|
|
66
83
|
response: responseClone,
|
|
@@ -109,6 +126,11 @@ var _FetchInterceptor = class extends Interceptor {
|
|
|
109
126
|
};
|
|
110
127
|
var FetchInterceptor = _FetchInterceptor;
|
|
111
128
|
FetchInterceptor.symbol = Symbol("fetch");
|
|
129
|
+
function createNetworkError(cause) {
|
|
130
|
+
return Object.assign(new TypeError("Failed to fetch"), {
|
|
131
|
+
cause
|
|
132
|
+
});
|
|
133
|
+
}
|
|
112
134
|
export {
|
|
113
135
|
FetchInterceptor
|
|
114
136
|
};
|
package/lib/node/presets/node.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunk3MYUI4B2js = require('../chunk-3MYUI4B2.js');
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkE6YC337Qjs = require('../chunk-E6YC337Q.js');
|
|
7
7
|
require('../chunk-3LFH2WCF.js');
|
|
8
8
|
require('../chunk-VQ4DZOBB.js');
|
|
9
9
|
require('../chunk-ZJOF5MEZ.js');
|
|
@@ -11,8 +11,8 @@ require('../chunk-XYZRP5S2.js');
|
|
|
11
11
|
|
|
12
12
|
// src/presets/node.ts
|
|
13
13
|
var node_default = [
|
|
14
|
-
new (0,
|
|
15
|
-
new (0,
|
|
14
|
+
new (0, _chunk3MYUI4B2js.ClientRequestInterceptor)(),
|
|
15
|
+
new (0, _chunkE6YC337Qjs.XMLHttpRequestInterceptor)()
|
|
16
16
|
];
|
|
17
17
|
|
|
18
18
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ClientRequestInterceptor
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-OL7OR4RL.mjs";
|
|
4
4
|
import {
|
|
5
5
|
XMLHttpRequestInterceptor
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-HSCXCLVT.mjs";
|
|
7
7
|
import "../chunk-7II4SWKS.mjs";
|
|
8
8
|
import "../chunk-GFH37L5D.mjs";
|
|
9
9
|
import "../chunk-STA6QBYM.mjs";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mswjs/interceptors",
|
|
3
3
|
"description": "Low-level HTTP/HTTPS/XHR/fetch request interception library.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.25.0",
|
|
5
5
|
"main": "./lib/node/index.js",
|
|
6
6
|
"module": "./lib/node/index.mjs",
|
|
7
7
|
"types": "./lib/node/index.d.ts",
|
|
@@ -45,10 +45,10 @@
|
|
|
45
45
|
},
|
|
46
46
|
"./RemoteHttpInterceptor": {
|
|
47
47
|
"browser": null,
|
|
48
|
-
"types": "./lib/node/
|
|
49
|
-
"require": "./lib/node/
|
|
50
|
-
"import": "./lib/node/
|
|
51
|
-
"default": "./lib/node/
|
|
48
|
+
"types": "./lib/node/RemoteHttpInterceptor.d.ts",
|
|
49
|
+
"require": "./lib/node/RemoteHttpInterceptor.js",
|
|
50
|
+
"import": "./lib/node/RemoteHttpInterceptor.mjs",
|
|
51
|
+
"default": "./lib/node/RemoteHttpInterceptor.js"
|
|
52
52
|
},
|
|
53
53
|
"./presets/node": {
|
|
54
54
|
"browser": null,
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"@commitlint/cli": "^16.0.2",
|
|
89
89
|
"@commitlint/config-conventional": "^16.0.0",
|
|
90
90
|
"@open-draft/test-server": "^0.5.1",
|
|
91
|
-
"@ossjs/release": "^0.
|
|
91
|
+
"@ossjs/release": "^0.7.2",
|
|
92
92
|
"@playwright/test": "^1.37.1",
|
|
93
93
|
"@types/cors": "^2.8.12",
|
|
94
94
|
"@types/express": "^4.17.13",
|
|
@@ -212,9 +212,26 @@ export class NodeClientRequest extends ClientRequest {
|
|
|
212
212
|
const mockedResponse = resolverResult.data
|
|
213
213
|
|
|
214
214
|
if (mockedResponse) {
|
|
215
|
+
this.logger.info('received mocked response:', mockedResponse)
|
|
216
|
+
|
|
217
|
+
// Handle mocked "Response.error" network error responses.
|
|
218
|
+
if (mockedResponse.type === 'error') {
|
|
219
|
+
this.logger.info(
|
|
220
|
+
'received network error response, aborting request...'
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* There is no standardized error format for network errors
|
|
225
|
+
* in Node.js. Instead, emit a generic TypeError.
|
|
226
|
+
*/
|
|
227
|
+
this.emit('error', new TypeError('Network error'))
|
|
228
|
+
this.terminate()
|
|
229
|
+
|
|
230
|
+
return this
|
|
231
|
+
}
|
|
232
|
+
|
|
215
233
|
const responseClone = mockedResponse.clone()
|
|
216
234
|
|
|
217
|
-
this.logger.info('received mocked response:', mockedResponse)
|
|
218
235
|
this.responseSource = 'mock'
|
|
219
236
|
|
|
220
237
|
this.respondWith(mockedResponse)
|
|
@@ -3,6 +3,7 @@ import http from 'http'
|
|
|
3
3
|
import { HttpServer } from '@open-draft/test-server/http'
|
|
4
4
|
import { DeferredPromise } from '@open-draft/deferred-promise'
|
|
5
5
|
import { ClientRequestInterceptor } from '.'
|
|
6
|
+
import { sleep } from '../../../test/helpers'
|
|
6
7
|
|
|
7
8
|
const httpServer = new HttpServer((app) => {
|
|
8
9
|
app.get('/', (_req, res) => {
|
|
@@ -55,3 +56,30 @@ it('forbids calling "respondWith" multiple times for the same request', async ()
|
|
|
55
56
|
expect(response.statusCode).toBe(200)
|
|
56
57
|
expect(response.statusMessage).toBe('')
|
|
57
58
|
})
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
it('abort the request if the abort signal is emitted', async () => {
|
|
62
|
+
const requestUrl = httpServer.http.url('/')
|
|
63
|
+
|
|
64
|
+
const requestEmitted = new DeferredPromise<void>()
|
|
65
|
+
interceptor.on('request', async function delayedResponse({ request }) {
|
|
66
|
+
requestEmitted.resolve()
|
|
67
|
+
await sleep(10000)
|
|
68
|
+
request.respondWith(new Response())
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
const abortController = new AbortController()
|
|
72
|
+
const request = http.get(requestUrl, { signal: abortController.signal })
|
|
73
|
+
|
|
74
|
+
await requestEmitted
|
|
75
|
+
|
|
76
|
+
abortController.abort()
|
|
77
|
+
|
|
78
|
+
const requestAborted = new DeferredPromise<void>()
|
|
79
|
+
request.on('error', function(err) {
|
|
80
|
+
expect(err.name).toEqual('AbortError')
|
|
81
|
+
requestAborted.resolve()
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
await requestAborted
|
|
85
|
+
})
|
|
@@ -104,6 +104,15 @@ export function createXMLHttpRequestProxy({
|
|
|
104
104
|
mockedResponse.statusText
|
|
105
105
|
)
|
|
106
106
|
|
|
107
|
+
if (mockedResponse.type === 'error') {
|
|
108
|
+
this.logger.info(
|
|
109
|
+
'received a network error response, rejecting the request promise...'
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
requestController.errorWith(new TypeError('Network error'))
|
|
113
|
+
return
|
|
114
|
+
}
|
|
115
|
+
|
|
107
116
|
return requestController.respondWith(mockedResponse)
|
|
108
117
|
}
|
|
109
118
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const statusCodesWithoutBody = [204, 205, 304]
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Creates a Fetch API `Response` instance from the given
|
|
3
5
|
* `XMLHttpRequest` instance and a response body.
|
|
@@ -6,7 +8,19 @@ export function createResponse(
|
|
|
6
8
|
request: XMLHttpRequest,
|
|
7
9
|
body: BodyInit | null
|
|
8
10
|
): Response {
|
|
9
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Handle XMLHttpRequest responses that must have null as the
|
|
13
|
+
* response body when represented using Fetch API Response.
|
|
14
|
+
* XMLHttpRequest response will always have an empty string
|
|
15
|
+
* as the "request.response" in those cases, resulting in an error
|
|
16
|
+
* when constructing a Response instance.
|
|
17
|
+
* @see https://github.com/mswjs/interceptors/issues/379
|
|
18
|
+
*/
|
|
19
|
+
const responseBodyOrNull = statusCodesWithoutBody.includes(request.status)
|
|
20
|
+
? null
|
|
21
|
+
: body
|
|
22
|
+
|
|
23
|
+
return new Response(responseBodyOrNull, {
|
|
10
24
|
status: request.status,
|
|
11
25
|
statusText: request.statusText,
|
|
12
26
|
headers: createHeadersFromXMLHttpReqestHeaders(
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DeferredPromise } from '@open-draft/deferred-promise'
|
|
1
2
|
import { invariant } from 'outvariant'
|
|
2
3
|
import { until } from '@open-draft/until'
|
|
3
4
|
import { HttpRequestEventMap, IS_PATCHED_MODULE } from '../../glossary'
|
|
@@ -46,13 +47,27 @@ export class FetchInterceptor extends Interceptor<HttpRequestEventMap> {
|
|
|
46
47
|
|
|
47
48
|
this.logger.info('awaiting for the mocked response...')
|
|
48
49
|
|
|
50
|
+
const signal = interactiveRequest.signal
|
|
51
|
+
const requestAborted = new DeferredPromise()
|
|
52
|
+
|
|
53
|
+
signal.addEventListener(
|
|
54
|
+
'abort',
|
|
55
|
+
() => {
|
|
56
|
+
requestAborted.reject(signal.reason)
|
|
57
|
+
},
|
|
58
|
+
{ once: true }
|
|
59
|
+
)
|
|
60
|
+
|
|
49
61
|
const resolverResult = await until(async () => {
|
|
50
|
-
|
|
62
|
+
const allListenersResolved = this.emitter.untilIdle(
|
|
51
63
|
'request',
|
|
52
64
|
({ args: [{ requestId: pendingRequestId }] }) => {
|
|
53
65
|
return pendingRequestId === requestId
|
|
54
66
|
}
|
|
55
67
|
)
|
|
68
|
+
|
|
69
|
+
await Promise.race([requestAborted, allListenersResolved])
|
|
70
|
+
|
|
56
71
|
this.logger.info('all request listeners have been resolved!')
|
|
57
72
|
|
|
58
73
|
const [mockedResponse] = await interactiveRequest.respondWith.invoked()
|
|
@@ -61,17 +76,36 @@ export class FetchInterceptor extends Interceptor<HttpRequestEventMap> {
|
|
|
61
76
|
return mockedResponse
|
|
62
77
|
})
|
|
63
78
|
|
|
79
|
+
if (requestAborted.state === 'rejected') {
|
|
80
|
+
return Promise.reject(requestAborted.rejectionReason)
|
|
81
|
+
}
|
|
82
|
+
|
|
64
83
|
if (resolverResult.error) {
|
|
65
|
-
|
|
66
|
-
cause: resolverResult.error,
|
|
67
|
-
})
|
|
68
|
-
return Promise.reject(error)
|
|
84
|
+
return Promise.reject(createNetworkError(resolverResult.error))
|
|
69
85
|
}
|
|
70
86
|
|
|
71
87
|
const mockedResponse = resolverResult.data
|
|
72
88
|
|
|
73
89
|
if (mockedResponse && !request.signal?.aborted) {
|
|
74
90
|
this.logger.info('received mocked response:', mockedResponse)
|
|
91
|
+
|
|
92
|
+
// Reject the request Promise on mocked "Response.error" responses.
|
|
93
|
+
if (mockedResponse.type === 'error') {
|
|
94
|
+
this.logger.info(
|
|
95
|
+
'received a network error response, rejecting the request promise...'
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Set the cause of the request promise rejection to the
|
|
100
|
+
* network error Response instance. This different from Undici.
|
|
101
|
+
* Undici will forward the "response.error" custom property
|
|
102
|
+
* as the rejection reason but for "Response.error()" static method
|
|
103
|
+
* "response.error" will equal to undefined, making "cause" an empty Error.
|
|
104
|
+
* @see https://github.com/nodejs/undici/blob/83cb522ae0157a19d149d72c7d03d46e34510d0a/lib/fetch/response.js#L344
|
|
105
|
+
*/
|
|
106
|
+
return Promise.reject(createNetworkError(mockedResponse))
|
|
107
|
+
}
|
|
108
|
+
|
|
75
109
|
const responseClone = mockedResponse.clone()
|
|
76
110
|
|
|
77
111
|
this.emitter.emit('response', {
|
|
@@ -131,3 +165,9 @@ export class FetchInterceptor extends Interceptor<HttpRequestEventMap> {
|
|
|
131
165
|
})
|
|
132
166
|
}
|
|
133
167
|
}
|
|
168
|
+
|
|
169
|
+
function createNetworkError(cause: unknown) {
|
|
170
|
+
return Object.assign(new TypeError('Failed to fetch'), {
|
|
171
|
+
cause,
|
|
172
|
+
})
|
|
173
|
+
}
|