@mswjs/interceptors 0.19.4 → 0.19.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/BatchInterceptor.d.ts +5 -5
- package/lib/BatchInterceptor.js +14 -59
- package/lib/BatchInterceptor.js.map +1 -1
- package/lib/Interceptor.d.ts +7 -6
- package/lib/Interceptor.js +39 -64
- package/lib/Interceptor.js.map +1 -1
- package/lib/RemoteHttpInterceptor.js +115 -209
- package/lib/RemoteHttpInterceptor.js.map +1 -1
- package/lib/glossary.d.ts +2 -2
- package/lib/interceptors/ClientRequest/NodeClientRequest.js +141 -278
- package/lib/interceptors/ClientRequest/NodeClientRequest.js.map +1 -1
- package/lib/interceptors/ClientRequest/http.get.js +5 -34
- package/lib/interceptors/ClientRequest/http.get.js.map +1 -1
- package/lib/interceptors/ClientRequest/http.request.js +6 -35
- package/lib/interceptors/ClientRequest/http.request.js.map +1 -1
- package/lib/interceptors/ClientRequest/index.js +22 -82
- package/lib/interceptors/ClientRequest/index.js.map +1 -1
- package/lib/interceptors/ClientRequest/utils/cloneIncomingMessage.js +18 -62
- package/lib/interceptors/ClientRequest/utils/cloneIncomingMessage.js.map +1 -1
- package/lib/interceptors/ClientRequest/utils/createRequest.js +10 -32
- package/lib/interceptors/ClientRequest/utils/createRequest.js.map +1 -1
- package/lib/interceptors/ClientRequest/utils/createResponse.js +6 -6
- package/lib/interceptors/ClientRequest/utils/createResponse.js.map +1 -1
- package/lib/interceptors/ClientRequest/utils/getIncomingMessageBody.js +12 -12
- package/lib/interceptors/ClientRequest/utils/getIncomingMessageBody.js.map +1 -1
- package/lib/interceptors/ClientRequest/utils/normalizeClientRequestArgs.js +21 -52
- package/lib/interceptors/ClientRequest/utils/normalizeClientRequestArgs.js.map +1 -1
- package/lib/interceptors/ClientRequest/utils/normalizeClientRequestEndArgs.js +5 -9
- package/lib/interceptors/ClientRequest/utils/normalizeClientRequestEndArgs.js.map +1 -1
- package/lib/interceptors/ClientRequest/utils/normalizeClientRequestWriteArgs.js +6 -6
- package/lib/interceptors/ClientRequest/utils/normalizeClientRequestWriteArgs.js.map +1 -1
- package/lib/interceptors/XMLHttpRequest/XMLHttpRequestOverride.js +213 -338
- package/lib/interceptors/XMLHttpRequest/XMLHttpRequestOverride.js.map +1 -1
- package/lib/interceptors/XMLHttpRequest/index.js +16 -33
- package/lib/interceptors/XMLHttpRequest/index.js.map +1 -1
- package/lib/interceptors/XMLHttpRequest/polyfills/EventPolyfill.js +11 -12
- package/lib/interceptors/XMLHttpRequest/polyfills/EventPolyfill.js.map +1 -1
- package/lib/interceptors/XMLHttpRequest/polyfills/ProgressEventPolyfill.js +9 -27
- package/lib/interceptors/XMLHttpRequest/polyfills/ProgressEventPolyfill.js.map +1 -1
- package/lib/interceptors/XMLHttpRequest/utils/concatArrayBuffer.js +1 -1
- package/lib/interceptors/XMLHttpRequest/utils/concatArrayBuffer.js.map +1 -1
- package/lib/interceptors/XMLHttpRequest/utils/createEvent.js +7 -7
- package/lib/interceptors/XMLHttpRequest/utils/createEvent.js.map +1 -1
- package/lib/interceptors/XMLHttpRequest/utils/createResponse.js +2 -2
- package/lib/interceptors/XMLHttpRequest/utils/createResponse.js.map +1 -1
- package/lib/interceptors/XMLHttpRequest/utils/isDomParserSupportedType.js +2 -2
- package/lib/interceptors/XMLHttpRequest/utils/isDomParserSupportedType.js.map +1 -1
- package/lib/interceptors/fetch/index.js +52 -125
- package/lib/interceptors/fetch/index.js.map +1 -1
- package/lib/presets/browser.js +2 -2
- package/lib/presets/browser.js.map +1 -1
- package/lib/presets/node.js +2 -2
- package/lib/presets/node.js.map +1 -1
- package/lib/utils/AsyncEventEmitter.d.ts +9 -8
- package/lib/utils/AsyncEventEmitter.js +84 -190
- package/lib/utils/AsyncEventEmitter.js.map +1 -1
- package/lib/utils/bufferUtils.js +3 -3
- package/lib/utils/bufferUtils.js.map +1 -1
- package/lib/utils/cloneObject.js +2 -19
- package/lib/utils/cloneObject.js.map +1 -1
- package/lib/utils/createLazyCallback.js +14 -49
- package/lib/utils/createLazyCallback.js.map +1 -1
- package/lib/utils/getCleanUrl.js +1 -2
- package/lib/utils/getCleanUrl.js.map +1 -1
- package/lib/utils/getRequestOptionsByUrl.js +3 -3
- package/lib/utils/getRequestOptionsByUrl.js.map +1 -1
- package/lib/utils/getUrlByRequestOptions.js +23 -39
- package/lib/utils/getUrlByRequestOptions.js.map +1 -1
- package/lib/utils/nextTick.js +2 -2
- package/lib/utils/nextTick.js.map +1 -1
- package/lib/utils/parseJson.js +1 -1
- package/lib/utils/parseJson.js.map +1 -1
- package/lib/utils/toInteractiveRequest.js +3 -3
- package/lib/utils/toInteractiveRequest.js.map +1 -1
- package/lib/utils/uuid.js +2 -2
- package/lib/utils/uuid.js.map +1 -1
- package/package.json +2 -2
- package/src/BatchInterceptor.test.ts +2 -2
- package/src/BatchInterceptor.ts +14 -13
- package/src/Interceptor.ts +12 -11
- package/src/glossary.ts +2 -6
- package/src/utils/AsyncEventEmitter.test.ts +6 -6
- package/src/utils/AsyncEventEmitter.ts +60 -50
|
@@ -8,78 +8,24 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
var __values = (this && this.__values) || function(o) {
|
|
39
|
-
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
40
|
-
if (m) return m.call(o);
|
|
41
|
-
if (o && typeof o.length === "number") return {
|
|
42
|
-
next: function () {
|
|
43
|
-
if (o && i >= o.length) o = void 0;
|
|
44
|
-
return { value: o && o[i++], done: !o };
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
48
|
-
};
|
|
49
|
-
var __read = (this && this.__read) || function (o, n) {
|
|
50
|
-
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
51
|
-
if (!m) return o;
|
|
52
|
-
var i = m.call(o), r, ar = [], e;
|
|
53
|
-
try {
|
|
54
|
-
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
55
|
-
}
|
|
56
|
-
catch (error) { e = { error: error }; }
|
|
57
|
-
finally {
|
|
58
|
-
try {
|
|
59
|
-
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
60
|
-
}
|
|
61
|
-
finally { if (e) throw e.error; }
|
|
62
|
-
}
|
|
63
|
-
return ar;
|
|
64
|
-
};
|
|
65
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
66
12
|
exports.createXMLHttpRequestOverride = void 0;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
13
|
+
const until_1 = require("@open-draft/until");
|
|
14
|
+
const web_fetch_1 = require("@remix-run/web-fetch");
|
|
15
|
+
const headers_polyfill_1 = require("headers-polyfill");
|
|
16
|
+
const parseJson_1 = require("../../utils/parseJson");
|
|
17
|
+
const createEvent_1 = require("./utils/createEvent");
|
|
18
|
+
const bufferUtils_1 = require("../../utils/bufferUtils");
|
|
19
|
+
const createResponse_1 = require("./utils/createResponse");
|
|
20
|
+
const concatArrayBuffer_1 = require("./utils/concatArrayBuffer");
|
|
21
|
+
const toInteractiveRequest_1 = require("../../utils/toInteractiveRequest");
|
|
22
|
+
const uuid_1 = require("../../utils/uuid");
|
|
23
|
+
const isDomParserSupportedType_1 = require("./utils/isDomParserSupportedType");
|
|
24
|
+
const createXMLHttpRequestOverride = (options) => {
|
|
79
25
|
var _a;
|
|
80
|
-
|
|
81
|
-
return _a =
|
|
82
|
-
|
|
26
|
+
const { XMLHttpRequest, emitter, log } = options;
|
|
27
|
+
return _a = class XMLHttpRequestOverride {
|
|
28
|
+
constructor() {
|
|
83
29
|
// Collection of events modified by `addEventListener`/`removeEventListener` calls.
|
|
84
30
|
this._events = [];
|
|
85
31
|
this.log = log;
|
|
@@ -111,7 +57,7 @@ var createXMLHttpRequestOverride = function (options) {
|
|
|
111
57
|
this._responseBuffer = new Uint8Array();
|
|
112
58
|
this._responseHeaders = new headers_polyfill_1.Headers();
|
|
113
59
|
}
|
|
114
|
-
|
|
60
|
+
setReadyState(nextState) {
|
|
115
61
|
if (nextState === this.readyState) {
|
|
116
62
|
return;
|
|
117
63
|
}
|
|
@@ -121,36 +67,25 @@ var createXMLHttpRequestOverride = function (options) {
|
|
|
121
67
|
this.log('triggering readystate change...');
|
|
122
68
|
this.trigger('readystatechange');
|
|
123
69
|
}
|
|
124
|
-
}
|
|
70
|
+
}
|
|
125
71
|
/**
|
|
126
72
|
* Triggers both direct callback and attached event listeners
|
|
127
73
|
* for the given event.
|
|
128
74
|
*/
|
|
129
|
-
|
|
130
|
-
var e_1, _a;
|
|
75
|
+
trigger(eventName, options) {
|
|
131
76
|
this.log('trigger "%s" (%d)', eventName, this.readyState);
|
|
132
77
|
this.log('resolve listener for event "%s"', eventName);
|
|
133
|
-
|
|
78
|
+
const callback = this[`on${eventName}`];
|
|
134
79
|
callback === null || callback === void 0 ? void 0 : callback.call(this, (0, createEvent_1.createEvent)(this, eventName, options));
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
log('calling mock event listener "%s" (%d)', eventName, this.readyState);
|
|
140
|
-
event_1.listener.call(this, (0, createEvent_1.createEvent)(this, eventName, options));
|
|
141
|
-
}
|
|
80
|
+
for (const event of this._events) {
|
|
81
|
+
if (event.name === eventName) {
|
|
82
|
+
log('calling mock event listener "%s" (%d)', eventName, this.readyState);
|
|
83
|
+
event.listener.call(this, (0, createEvent_1.createEvent)(this, eventName, options));
|
|
142
84
|
}
|
|
143
85
|
}
|
|
144
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
145
|
-
finally {
|
|
146
|
-
try {
|
|
147
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
148
|
-
}
|
|
149
|
-
finally { if (e_1) throw e_1.error; }
|
|
150
|
-
}
|
|
151
86
|
return this;
|
|
152
|
-
}
|
|
153
|
-
|
|
87
|
+
}
|
|
88
|
+
reset() {
|
|
154
89
|
this.log('reset');
|
|
155
90
|
this.setReadyState(this.UNSENT);
|
|
156
91
|
this.status = 0;
|
|
@@ -158,35 +93,30 @@ var createXMLHttpRequestOverride = function (options) {
|
|
|
158
93
|
this._responseBuffer = new Uint8Array();
|
|
159
94
|
this._requestHeaders = new headers_polyfill_1.Headers();
|
|
160
95
|
this._responseHeaders = new headers_polyfill_1.Headers();
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
this.
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
this.password = password;
|
|
180
|
-
}
|
|
181
|
-
return [2 /*return*/];
|
|
182
|
-
});
|
|
96
|
+
}
|
|
97
|
+
open(method, url, async = true, user, password) {
|
|
98
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
99
|
+
this.log = this.log.extend(`request ${method} ${url}`);
|
|
100
|
+
this.log('open', { method, url, async, user, password });
|
|
101
|
+
this.reset();
|
|
102
|
+
this.setReadyState(this.OPENED);
|
|
103
|
+
if (typeof url === 'undefined') {
|
|
104
|
+
this.url = method;
|
|
105
|
+
this.method = 'GET';
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
this.url = url;
|
|
109
|
+
this.method = method;
|
|
110
|
+
this.async = async;
|
|
111
|
+
this.user = user;
|
|
112
|
+
this.password = password;
|
|
113
|
+
}
|
|
183
114
|
});
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
var _this = this;
|
|
115
|
+
}
|
|
116
|
+
send(data) {
|
|
187
117
|
this.log('send %s %s', this.method, this.url);
|
|
188
|
-
|
|
189
|
-
|
|
118
|
+
const requestBuffer = typeof data === 'string' ? (0, bufferUtils_1.encodeBuffer)(data) : data;
|
|
119
|
+
let url;
|
|
190
120
|
try {
|
|
191
121
|
url = new URL(this.url);
|
|
192
122
|
}
|
|
@@ -198,176 +128,157 @@ var createXMLHttpRequestOverride = function (options) {
|
|
|
198
128
|
}
|
|
199
129
|
this.log('request headers', this._requestHeaders);
|
|
200
130
|
// Create an intercepted request instance exposed to the request intercepting middleware.
|
|
201
|
-
|
|
202
|
-
|
|
131
|
+
const requestId = (0, uuid_1.uuidv4)();
|
|
132
|
+
const capturedRequest = new web_fetch_1.Request(url, {
|
|
203
133
|
method: this.method,
|
|
204
134
|
headers: this._requestHeaders,
|
|
205
135
|
credentials: this.withCredentials ? 'include' : 'omit',
|
|
206
136
|
body: requestBuffer,
|
|
207
137
|
});
|
|
208
|
-
|
|
138
|
+
const interactiveRequest = (0, toInteractiveRequest_1.toInteractiveRequest)(capturedRequest);
|
|
209
139
|
this.log('emitting the "request" event for %d listener(s)...', emitter.listenerCount('request'));
|
|
210
140
|
emitter.emit('request', interactiveRequest, requestId);
|
|
211
141
|
this.log('awaiting mocked response...');
|
|
212
|
-
Promise.resolve((0, until_1.until)(
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
switch (_b.label) {
|
|
216
|
-
case 0: return [4 /*yield*/, emitter.untilIdle('request', function (_a) {
|
|
217
|
-
var _b = __read(_a.args, 2), pendingRequestId = _b[1];
|
|
218
|
-
return pendingRequestId === requestId;
|
|
219
|
-
})];
|
|
220
|
-
case 1:
|
|
221
|
-
_b.sent();
|
|
222
|
-
this.log('all request listeners have been resolved!');
|
|
223
|
-
return [4 /*yield*/, interactiveRequest.respondWith.invoked()];
|
|
224
|
-
case 2:
|
|
225
|
-
_a = __read.apply(void 0, [_b.sent(), 1]), mockedResponse = _a[0];
|
|
226
|
-
this.log('event.respondWith called with:', mockedResponse);
|
|
227
|
-
return [2 /*return*/, mockedResponse];
|
|
228
|
-
}
|
|
142
|
+
Promise.resolve((0, until_1.until)(() => __awaiter(this, void 0, void 0, function* () {
|
|
143
|
+
yield emitter.untilIdle('request', ({ args: [, pendingRequestId] }) => {
|
|
144
|
+
return pendingRequestId === requestId;
|
|
229
145
|
});
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
146
|
+
this.log('all request listeners have been resolved!');
|
|
147
|
+
const [mockedResponse] = yield interactiveRequest.respondWith.invoked();
|
|
148
|
+
this.log('event.respondWith called with:', mockedResponse);
|
|
149
|
+
return mockedResponse;
|
|
150
|
+
}))).then(([middlewareException, mockedResponse]) => {
|
|
151
|
+
var _a, _b;
|
|
233
152
|
// When the request middleware throws an exception, error the request.
|
|
234
153
|
// This cancels the request and is similar to a network error.
|
|
235
154
|
if (middlewareException) {
|
|
236
|
-
|
|
155
|
+
this.log('middleware function threw an exception!', middlewareException);
|
|
237
156
|
// Mark the request as complete.
|
|
238
|
-
|
|
157
|
+
this.setReadyState(this.DONE);
|
|
239
158
|
// No way to propagate the actual error message.
|
|
240
|
-
|
|
159
|
+
this.trigger('error');
|
|
241
160
|
// Emit the "loadend" event to notify that the request has settled.
|
|
242
161
|
// In this case, there's been an error with the request so
|
|
243
162
|
// we must not emit the "load" event.
|
|
244
|
-
|
|
163
|
+
this.trigger('loadend');
|
|
245
164
|
// Abort must not be called when request fails!
|
|
246
165
|
// this.abort()
|
|
247
166
|
return;
|
|
248
167
|
}
|
|
249
168
|
// Forward request headers modified in the "request" listener.
|
|
250
|
-
|
|
169
|
+
this._requestHeaders = new headers_polyfill_1.Headers(capturedRequest.headers);
|
|
251
170
|
// Return a mocked response, if provided in the middleware.
|
|
252
171
|
if (mockedResponse) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
? Number(
|
|
172
|
+
const responseClone = mockedResponse.clone();
|
|
173
|
+
this.log('received mocked response', mockedResponse);
|
|
174
|
+
this.status = (_a = mockedResponse.status) !== null && _a !== void 0 ? _a : 200;
|
|
175
|
+
this.statusText = mockedResponse.statusText || 'OK';
|
|
176
|
+
this.log('set response status', this.status, this.statusText);
|
|
177
|
+
this._responseHeaders = new headers_polyfill_1.Headers(mockedResponse.headers || {});
|
|
178
|
+
this.log('set response headers', this._responseHeaders);
|
|
179
|
+
this.log('response type', this.responseType);
|
|
180
|
+
this.responseURL = this.url;
|
|
181
|
+
const totalLength = this._responseHeaders.has('Content-Length')
|
|
182
|
+
? Number(this._responseHeaders.get('Content-Length'))
|
|
264
183
|
: undefined;
|
|
265
184
|
// Trigger a loadstart event to indicate the initialization of the fetch.
|
|
266
|
-
|
|
185
|
+
this.trigger('loadstart', { loaded: 0, total: totalLength });
|
|
267
186
|
// Mark that response headers has been received
|
|
268
187
|
// and trigger a ready state event to reflect received headers
|
|
269
188
|
// in a custom "onreadystatechange" callback.
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
189
|
+
this.setReadyState(this.HEADERS_RECEIVED);
|
|
190
|
+
this.setReadyState(this.LOADING);
|
|
191
|
+
const closeResponseStream = () => {
|
|
273
192
|
/**
|
|
274
193
|
* Explicitly mark the request as done so its response never hangs.
|
|
275
194
|
* @see https://github.com/mswjs/interceptors/issues/13
|
|
276
195
|
*/
|
|
277
|
-
|
|
196
|
+
this.setReadyState(this.DONE);
|
|
278
197
|
// Always trigger the "load" event because at this point
|
|
279
198
|
// the request has been performed successfully.
|
|
280
|
-
|
|
281
|
-
loaded:
|
|
282
|
-
total:
|
|
199
|
+
this.trigger('load', {
|
|
200
|
+
loaded: this._responseBuffer.byteLength,
|
|
201
|
+
total: totalLength,
|
|
283
202
|
});
|
|
284
203
|
// Trigger a loadend event to indicate the fetch has completed.
|
|
285
|
-
|
|
286
|
-
loaded:
|
|
287
|
-
total:
|
|
204
|
+
this.trigger('loadend', {
|
|
205
|
+
loaded: this._responseBuffer.byteLength,
|
|
206
|
+
total: totalLength,
|
|
288
207
|
});
|
|
289
|
-
emitter.emit('response',
|
|
208
|
+
emitter.emit('response', responseClone, capturedRequest, requestId);
|
|
290
209
|
};
|
|
291
210
|
if (mockedResponse.body) {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
readNextChunk_1();
|
|
312
|
-
return [2 /*return*/];
|
|
313
|
-
}
|
|
314
|
-
});
|
|
315
|
-
}); };
|
|
316
|
-
readNextChunk_1();
|
|
211
|
+
const reader = mockedResponse.body.getReader();
|
|
212
|
+
const readNextChunk = () => __awaiter(this, void 0, void 0, function* () {
|
|
213
|
+
const { value, done } = yield reader.read();
|
|
214
|
+
if (done) {
|
|
215
|
+
closeResponseStream();
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
if (value) {
|
|
219
|
+
this._responseBuffer = (0, concatArrayBuffer_1.concatArrayBuffer)(this._responseBuffer, value);
|
|
220
|
+
this.trigger('progress', {
|
|
221
|
+
loaded: this._responseBuffer.byteLength,
|
|
222
|
+
total: totalLength,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
readNextChunk();
|
|
226
|
+
});
|
|
227
|
+
readNextChunk();
|
|
317
228
|
}
|
|
318
229
|
else {
|
|
319
|
-
|
|
230
|
+
closeResponseStream();
|
|
320
231
|
}
|
|
321
232
|
}
|
|
322
233
|
else {
|
|
323
|
-
|
|
234
|
+
this.log('no mocked response received!');
|
|
324
235
|
// Perform an original request, when the request middleware returned no mocked response.
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
236
|
+
const originalRequest = new XMLHttpRequest();
|
|
237
|
+
this.log('opening an original request %s %s', this.method, this.url);
|
|
238
|
+
originalRequest.open(this.method, this.url, (_b = this.async) !== null && _b !== void 0 ? _b : true, this.user, this.password);
|
|
239
|
+
originalRequest.addEventListener('readystatechange', () => {
|
|
329
240
|
// Forward the original response headers to the patched instance
|
|
330
241
|
// immediately as they are received.
|
|
331
|
-
if (
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
242
|
+
if (originalRequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
|
|
243
|
+
const responseHeaders = originalRequest.getAllResponseHeaders();
|
|
244
|
+
this.log('original response headers:\n', responseHeaders);
|
|
245
|
+
this._responseHeaders = (0, headers_polyfill_1.stringToHeaders)(responseHeaders);
|
|
246
|
+
this.log('original response headers (normalized)', this._responseHeaders);
|
|
336
247
|
}
|
|
337
248
|
});
|
|
338
|
-
|
|
249
|
+
originalRequest.addEventListener('loadstart', () => {
|
|
339
250
|
// Forward the response type to the patched instance immediately.
|
|
340
251
|
// Response type affects how response reading properties are resolved.
|
|
341
|
-
|
|
252
|
+
this.responseType = originalRequest.responseType;
|
|
342
253
|
});
|
|
343
|
-
|
|
344
|
-
|
|
254
|
+
originalRequest.addEventListener('progress', () => {
|
|
255
|
+
this._responseBuffer = (0, concatArrayBuffer_1.concatArrayBuffer)(this._responseBuffer, (0, bufferUtils_1.encodeBuffer)(originalRequest.responseText));
|
|
345
256
|
});
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
257
|
+
originalRequest.addEventListener('load', () => {
|
|
258
|
+
this.status = originalRequest.status;
|
|
259
|
+
this.statusText = originalRequest.statusText;
|
|
260
|
+
this.responseURL = originalRequest.responseURL;
|
|
261
|
+
this.log('received original response', this.status, this.statusText);
|
|
351
262
|
// Explicitly mark the mocked request instance as done
|
|
352
263
|
// so the response never hangs.
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
264
|
+
this.setReadyState(this.DONE);
|
|
265
|
+
this.log('set mock request readyState to DONE');
|
|
266
|
+
this.log('original response body:', this.response);
|
|
267
|
+
this.log('original response finished!');
|
|
357
268
|
});
|
|
358
269
|
// Update the patched instance on the "loadend" event
|
|
359
270
|
// because it fires when the request settles (succeeds/errors).
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
emitter.emit('response', (0, createResponse_1.createResponse)(
|
|
271
|
+
originalRequest.addEventListener('loadend', () => {
|
|
272
|
+
this.log('original "loadend"');
|
|
273
|
+
emitter.emit('response', (0, createResponse_1.createResponse)(originalRequest, this._responseBuffer), capturedRequest, requestId);
|
|
363
274
|
});
|
|
364
|
-
|
|
275
|
+
this.propagateHeaders(originalRequest, this._requestHeaders);
|
|
365
276
|
// Assign callbacks and event listeners from the intercepted XHR instance
|
|
366
277
|
// to the original XHR instance.
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
if (
|
|
370
|
-
|
|
278
|
+
this.propagateCallbacks(originalRequest);
|
|
279
|
+
this.propagateListeners(originalRequest);
|
|
280
|
+
if (this.async) {
|
|
281
|
+
originalRequest.timeout = this.timeout;
|
|
371
282
|
}
|
|
372
283
|
/**
|
|
373
284
|
* @note Set the intercepted request ID on the original request
|
|
@@ -375,120 +286,107 @@ var createXMLHttpRequestOverride = function (options) {
|
|
|
375
286
|
* to process it once again. This happens when bypassing XMLHttpRequest
|
|
376
287
|
* because it's polyfilled with "http.ClientRequest" in JSDOM.
|
|
377
288
|
*/
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
289
|
+
originalRequest.setRequestHeader('X-Request-Id', requestId);
|
|
290
|
+
this.log('send', data);
|
|
291
|
+
originalRequest.send(data);
|
|
381
292
|
}
|
|
382
293
|
});
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
}
|
|
403
|
-
case 'blob': {
|
|
404
|
-
var mimeType = this.getResponseHeader('content-type') || 'text/plain';
|
|
405
|
-
this.log('resolving response body as blog (%s)', mimeType);
|
|
406
|
-
return new Blob([this.responseText], { type: mimeType });
|
|
407
|
-
}
|
|
408
|
-
case 'document': {
|
|
409
|
-
this.log('resolving response body as XML');
|
|
410
|
-
return this.responseXML;
|
|
411
|
-
}
|
|
412
|
-
default: {
|
|
413
|
-
return this.responseText;
|
|
414
|
-
}
|
|
294
|
+
}
|
|
295
|
+
get responseText() {
|
|
296
|
+
this.log('responseText()');
|
|
297
|
+
return (0, bufferUtils_1.decodeBuffer)(this._responseBuffer);
|
|
298
|
+
}
|
|
299
|
+
get response() {
|
|
300
|
+
switch (this.responseType) {
|
|
301
|
+
case 'json': {
|
|
302
|
+
this.log('resolving response body as JSON');
|
|
303
|
+
return (0, parseJson_1.parseJson)(this.responseText);
|
|
304
|
+
}
|
|
305
|
+
case 'arraybuffer': {
|
|
306
|
+
this.log('resolving response body as ArrayBuffer');
|
|
307
|
+
return (0, bufferUtils_1.toArrayBuffer)(this._responseBuffer);
|
|
308
|
+
}
|
|
309
|
+
case 'blob': {
|
|
310
|
+
const mimeType = this.getResponseHeader('content-type') || 'text/plain';
|
|
311
|
+
this.log('resolving response body as blog (%s)', mimeType);
|
|
312
|
+
return new Blob([this.responseText], { type: mimeType });
|
|
415
313
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
});
|
|
420
|
-
Object.defineProperty(XMLHttpRequestOverride.prototype, "responseXML", {
|
|
421
|
-
get: function () {
|
|
422
|
-
var contentType = this.getResponseHeader('content-type') || '';
|
|
423
|
-
this.log('responseXML() %s', contentType);
|
|
424
|
-
if (typeof DOMParser === 'undefined') {
|
|
425
|
-
console.warn('Cannot retrieve XMLHttpRequest response body as XML: DOMParser is not defined. You are likely using an environment that is not browser or does not polyfill browser globals correctly.');
|
|
426
|
-
return null;
|
|
314
|
+
case 'document': {
|
|
315
|
+
this.log('resolving response body as XML');
|
|
316
|
+
return this.responseXML;
|
|
427
317
|
}
|
|
428
|
-
|
|
429
|
-
this.
|
|
430
|
-
return new DOMParser().parseFromString(this.responseText, contentType);
|
|
318
|
+
default: {
|
|
319
|
+
return this.responseText;
|
|
431
320
|
}
|
|
432
|
-
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
get responseXML() {
|
|
324
|
+
const contentType = this.getResponseHeader('content-type') || '';
|
|
325
|
+
this.log('responseXML() %s', contentType);
|
|
326
|
+
if (typeof DOMParser === 'undefined') {
|
|
327
|
+
console.warn('Cannot retrieve XMLHttpRequest response body as XML: DOMParser is not defined. You are likely using an environment that is not browser or does not polyfill browser globals correctly.');
|
|
433
328
|
return null;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
329
|
+
}
|
|
330
|
+
if ((0, isDomParserSupportedType_1.isDomParserSupportedType)(contentType)) {
|
|
331
|
+
this.log('response content-type is XML, parsing...');
|
|
332
|
+
return new DOMParser().parseFromString(this.responseText, contentType);
|
|
333
|
+
}
|
|
334
|
+
this.log('response content type is not XML, returning null...');
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
abort() {
|
|
439
338
|
this.log('abort()');
|
|
440
339
|
if (this.readyState > this.UNSENT && this.readyState < this.DONE) {
|
|
441
340
|
this.reset();
|
|
442
341
|
this.trigger('abort');
|
|
443
342
|
}
|
|
444
|
-
}
|
|
445
|
-
|
|
343
|
+
}
|
|
344
|
+
dispatchEvent() {
|
|
446
345
|
return false;
|
|
447
|
-
}
|
|
448
|
-
|
|
346
|
+
}
|
|
347
|
+
setRequestHeader(name, value) {
|
|
449
348
|
this.log('setRequestHeader() "%s" to "%s"', name, value);
|
|
450
349
|
this._requestHeaders.append(name, value);
|
|
451
|
-
}
|
|
452
|
-
|
|
350
|
+
}
|
|
351
|
+
getResponseHeader(name) {
|
|
453
352
|
this.log('getResponseHeader() "%s"', name);
|
|
454
353
|
if (this.readyState < this.HEADERS_RECEIVED) {
|
|
455
354
|
this.log('cannot return a header: headers not received (state: %s)', this.readyState);
|
|
456
355
|
return null;
|
|
457
356
|
}
|
|
458
|
-
|
|
357
|
+
const headerValue = this._responseHeaders.get(name);
|
|
459
358
|
this.log('resolved response header "%s" to "%s"', name, headerValue, this._responseHeaders);
|
|
460
359
|
return headerValue;
|
|
461
|
-
}
|
|
462
|
-
|
|
360
|
+
}
|
|
361
|
+
getAllResponseHeaders() {
|
|
463
362
|
this.log('getAllResponseHeaders()');
|
|
464
363
|
if (this.readyState < this.HEADERS_RECEIVED) {
|
|
465
364
|
this.log('cannot return headers: headers not received (state: %s)', this.readyState);
|
|
466
365
|
return '';
|
|
467
366
|
}
|
|
468
367
|
return (0, headers_polyfill_1.headersToString)(this._responseHeaders);
|
|
469
|
-
}
|
|
470
|
-
|
|
368
|
+
}
|
|
369
|
+
addEventListener(event, listener) {
|
|
471
370
|
this.log('addEventListener', event, listener);
|
|
472
371
|
this._events.push({
|
|
473
372
|
name: event,
|
|
474
|
-
listener
|
|
373
|
+
listener,
|
|
475
374
|
});
|
|
476
|
-
}
|
|
477
|
-
|
|
375
|
+
}
|
|
376
|
+
removeEventListener(event, listener) {
|
|
478
377
|
this.log('removeEventListener', name, listener);
|
|
479
|
-
this._events = this._events.filter(
|
|
378
|
+
this._events = this._events.filter((storedEvent) => {
|
|
480
379
|
return storedEvent.name !== event && storedEvent.listener !== listener;
|
|
481
380
|
});
|
|
482
|
-
}
|
|
483
|
-
|
|
381
|
+
}
|
|
382
|
+
overrideMimeType() { }
|
|
484
383
|
/**
|
|
485
384
|
* Propagates mock XMLHttpRequest instance callbacks
|
|
486
385
|
* to the given XMLHttpRequest instance.
|
|
487
386
|
*/
|
|
488
|
-
|
|
489
|
-
var e_2, _a;
|
|
387
|
+
propagateCallbacks(request) {
|
|
490
388
|
this.log('propagating request callbacks to the original request');
|
|
491
|
-
|
|
389
|
+
const callbackNames = [
|
|
492
390
|
'abort',
|
|
493
391
|
'onerror',
|
|
494
392
|
'ontimeout',
|
|
@@ -498,23 +396,13 @@ var createXMLHttpRequestOverride = function (options) {
|
|
|
498
396
|
'onprogress',
|
|
499
397
|
'onreadystatechange',
|
|
500
398
|
];
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
request[callbackName] = this[callbackName];
|
|
507
|
-
this.log('propagated the "%s" callback', callbackName, callback);
|
|
508
|
-
}
|
|
399
|
+
for (const callbackName of callbackNames) {
|
|
400
|
+
const callback = this[callbackName];
|
|
401
|
+
if (callback) {
|
|
402
|
+
request[callbackName] = this[callbackName];
|
|
403
|
+
this.log('propagated the "%s" callback', callbackName, callback);
|
|
509
404
|
}
|
|
510
405
|
}
|
|
511
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
512
|
-
finally {
|
|
513
|
-
try {
|
|
514
|
-
if (callbackNames_1_1 && !callbackNames_1_1.done && (_a = callbackNames_1.return)) _a.call(callbackNames_1);
|
|
515
|
-
}
|
|
516
|
-
finally { if (e_2) throw e_2.error; }
|
|
517
|
-
}
|
|
518
406
|
request.onabort = this.abort;
|
|
519
407
|
request.onerror = this.onerror;
|
|
520
408
|
request.ontimeout = this.ontimeout;
|
|
@@ -523,38 +411,25 @@ var createXMLHttpRequestOverride = function (options) {
|
|
|
523
411
|
request.onloadend = this.onloadend;
|
|
524
412
|
request.onprogress = this.onprogress;
|
|
525
413
|
request.onreadystatechange = this.onreadystatechange;
|
|
526
|
-
}
|
|
414
|
+
}
|
|
527
415
|
/**
|
|
528
416
|
* Propagates the mock XMLHttpRequest instance listeners
|
|
529
417
|
* to the given XMLHttpRequest instance.
|
|
530
418
|
*/
|
|
531
|
-
|
|
419
|
+
propagateListeners(request) {
|
|
532
420
|
this.log('propagating request listeners (%d) to the original request', this._events.length, this._events);
|
|
533
|
-
this._events.forEach(
|
|
534
|
-
var name = _a.name, listener = _a.listener;
|
|
421
|
+
this._events.forEach(({ name, listener }) => {
|
|
535
422
|
request.addEventListener(name, listener);
|
|
536
423
|
});
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
var e_3, _a;
|
|
424
|
+
}
|
|
425
|
+
propagateHeaders(request, headers) {
|
|
540
426
|
this.log('propagating request headers to the original request', headers);
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
this.log('setting "%s" (%s) header on the original request', headerName, headerValue);
|
|
545
|
-
request.setRequestHeader(headerName, headerValue);
|
|
546
|
-
}
|
|
427
|
+
for (const [headerName, headerValue] of headers) {
|
|
428
|
+
this.log('setting "%s" (%s) header on the original request', headerName, headerValue);
|
|
429
|
+
request.setRequestHeader(headerName, headerValue);
|
|
547
430
|
}
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
try {
|
|
551
|
-
if (headers_1_1 && !headers_1_1.done && (_a = headers_1.return)) _a.call(headers_1);
|
|
552
|
-
}
|
|
553
|
-
finally { if (e_3) throw e_3.error; }
|
|
554
|
-
}
|
|
555
|
-
};
|
|
556
|
-
return XMLHttpRequestOverride;
|
|
557
|
-
}()),
|
|
431
|
+
}
|
|
432
|
+
},
|
|
558
433
|
/* Request state */
|
|
559
434
|
_a.UNSENT = 0,
|
|
560
435
|
_a.OPENED = 1,
|