@mswjs/interceptors 0.22.11 → 0.22.13

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.
@@ -3,7 +3,7 @@
3
3
  var _chunkRJMXHEGJjs = require('./chunk-RJMXHEGJ.js');
4
4
 
5
5
 
6
- var _chunk7XU7Q63Wjs = require('./chunk-7XU7Q63W.js');
6
+ var _chunkBGW7OOI4js = require('./chunk-BGW7OOI4.js');
7
7
 
8
8
 
9
9
  var _chunk2OJRZCGSjs = require('./chunk-2OJRZCGS.js');
@@ -23,7 +23,7 @@ var RemoteHttpInterceptor = class extends _chunkRJMXHEGJjs.BatchInterceptor {
23
23
  super({
24
24
  name: "remote-interceptor",
25
25
  interceptors: [
26
- new (0, _chunk7XU7Q63Wjs.ClientRequestInterceptor)(),
26
+ new (0, _chunkBGW7OOI4js.ClientRequestInterceptor)(),
27
27
  new (0, _chunk2OJRZCGSjs.XMLHttpRequestInterceptor)()
28
28
  ]
29
29
  });
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-SBAVVQIW.mjs";
4
4
  import {
5
5
  ClientRequestInterceptor
6
- } from "./chunk-XVHIXGXD.mjs";
6
+ } from "./chunk-JRKMZWAD.mjs";
7
7
  import {
8
8
  XMLHttpRequestInterceptor
9
9
  } from "./chunk-RL5IV5PL.mjs";
@@ -323,6 +323,11 @@ var _NodeClientRequest = class extends _http.ClientRequest {
323
323
  }
324
324
  respondWith(mockedResponse) {
325
325
  this.logger.info("responding with a mocked response...", mockedResponse);
326
+ Object.defineProperties(this, {
327
+ writableFinished: { value: true },
328
+ writableEnded: { value: true }
329
+ });
330
+ this.emit("finish");
326
331
  const { status, statusText, headers, body } = mockedResponse;
327
332
  this.response.statusCode = status;
328
333
  this.response.statusMessage = statusText;
@@ -336,37 +341,33 @@ var _NodeClientRequest = class extends _http.ClientRequest {
336
341
  });
337
342
  }
338
343
  this.logger.info("mocked response headers ready:", headers);
339
- const isResponseStreamRead = new (0, _deferredpromise.DeferredPromise)();
340
- const closeResponseStream = () => {
341
- this.logger.info("closing response stream...");
342
- this.response.push(null);
343
- this.response.complete = true;
344
- isResponseStreamRead.resolve();
345
- this.logger.info("closed response stream!");
344
+ const isResponseStreamFinished = new (0, _deferredpromise.DeferredPromise)();
345
+ const finishResponseStream = () => {
346
+ this.logger.info("finished response stream!");
347
+ isResponseStreamFinished.resolve();
346
348
  };
347
349
  if (body) {
348
350
  const bodyReader = body.getReader();
349
351
  const readNextChunk = async () => {
350
352
  const { done, value } = await bodyReader.read();
351
353
  if (done) {
352
- closeResponseStream();
354
+ finishResponseStream();
353
355
  return;
354
356
  }
355
- this.response.push(value);
357
+ this.response.emit("data", value);
356
358
  return readNextChunk();
357
359
  };
358
360
  readNextChunk();
359
361
  } else {
360
- closeResponseStream();
362
+ finishResponseStream();
361
363
  }
362
- isResponseStreamRead.then(() => {
363
- this.res = this.response;
364
- this.finished = true;
365
- Object.defineProperty(this, "writableEnded", {
366
- value: true
367
- });
368
- this.emit("finish");
369
- this.emit("response", this.response);
364
+ this.res = this.response;
365
+ this.emit("response", this.response);
366
+ isResponseStreamFinished.then(() => {
367
+ this.logger.info("finalizing response...");
368
+ this.response.push(null);
369
+ this.response.complete = true;
370
+ this.response.emit("end");
370
371
  this.terminate();
371
372
  });
372
373
  }
@@ -323,6 +323,11 @@ var _NodeClientRequest = class extends ClientRequest {
323
323
  }
324
324
  respondWith(mockedResponse) {
325
325
  this.logger.info("responding with a mocked response...", mockedResponse);
326
+ Object.defineProperties(this, {
327
+ writableFinished: { value: true },
328
+ writableEnded: { value: true }
329
+ });
330
+ this.emit("finish");
326
331
  const { status, statusText, headers, body } = mockedResponse;
327
332
  this.response.statusCode = status;
328
333
  this.response.statusMessage = statusText;
@@ -336,37 +341,33 @@ var _NodeClientRequest = class extends ClientRequest {
336
341
  });
337
342
  }
338
343
  this.logger.info("mocked response headers ready:", headers);
339
- const isResponseStreamRead = new DeferredPromise();
340
- const closeResponseStream = () => {
341
- this.logger.info("closing response stream...");
342
- this.response.push(null);
343
- this.response.complete = true;
344
- isResponseStreamRead.resolve();
345
- this.logger.info("closed response stream!");
344
+ const isResponseStreamFinished = new DeferredPromise();
345
+ const finishResponseStream = () => {
346
+ this.logger.info("finished response stream!");
347
+ isResponseStreamFinished.resolve();
346
348
  };
347
349
  if (body) {
348
350
  const bodyReader = body.getReader();
349
351
  const readNextChunk = async () => {
350
352
  const { done, value } = await bodyReader.read();
351
353
  if (done) {
352
- closeResponseStream();
354
+ finishResponseStream();
353
355
  return;
354
356
  }
355
- this.response.push(value);
357
+ this.response.emit("data", value);
356
358
  return readNextChunk();
357
359
  };
358
360
  readNextChunk();
359
361
  } else {
360
- closeResponseStream();
362
+ finishResponseStream();
361
363
  }
362
- isResponseStreamRead.then(() => {
363
- this.res = this.response;
364
- this.finished = true;
365
- Object.defineProperty(this, "writableEnded", {
366
- value: true
367
- });
368
- this.emit("finish");
369
- this.emit("response", this.response);
364
+ this.res = this.response;
365
+ this.emit("response", this.response);
366
+ isResponseStreamFinished.then(() => {
367
+ this.logger.info("finalizing response...");
368
+ this.response.push(null);
369
+ this.response.complete = true;
370
+ this.response.emit("end");
370
371
  this.terminate();
371
372
  });
372
373
  }
@@ -1,8 +1,8 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunk7XU7Q63Wjs = require('../../chunk-7XU7Q63W.js');
3
+ var _chunkBGW7OOI4js = require('../../chunk-BGW7OOI4.js');
4
4
  require('../../chunk-ZJOF5MEZ.js');
5
5
  require('../../chunk-6KJ5M2VR.js');
6
6
 
7
7
 
8
- exports.ClientRequestInterceptor = _chunk7XU7Q63Wjs.ClientRequestInterceptor;
8
+ exports.ClientRequestInterceptor = _chunkBGW7OOI4js.ClientRequestInterceptor;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ClientRequestInterceptor
3
- } from "../../chunk-XVHIXGXD.mjs";
3
+ } from "../../chunk-JRKMZWAD.mjs";
4
4
  import "../../chunk-STA6QBYM.mjs";
5
5
  import "../../chunk-3V5OWTY7.mjs";
6
6
  export {
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunk7XU7Q63Wjs = require('../chunk-7XU7Q63W.js');
3
+ var _chunkBGW7OOI4js = require('../chunk-BGW7OOI4.js');
4
4
 
5
5
 
6
6
  var _chunk2OJRZCGSjs = require('../chunk-2OJRZCGS.js');
@@ -11,7 +11,7 @@ require('../chunk-6KJ5M2VR.js');
11
11
 
12
12
  // src/presets/node.ts
13
13
  var node_default = [
14
- new (0, _chunk7XU7Q63Wjs.ClientRequestInterceptor)(),
14
+ new (0, _chunkBGW7OOI4js.ClientRequestInterceptor)(),
15
15
  new (0, _chunk2OJRZCGSjs.XMLHttpRequestInterceptor)()
16
16
  ];
17
17
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ClientRequestInterceptor
3
- } from "../chunk-XVHIXGXD.mjs";
3
+ } from "../chunk-JRKMZWAD.mjs";
4
4
  import {
5
5
  XMLHttpRequestInterceptor
6
6
  } from "../chunk-RL5IV5PL.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.22.11",
4
+ "version": "0.22.13",
5
5
  "main": "./lib/node/index.js",
6
6
  "module": "./lib/node/index.mjs",
7
7
  "types": "./lib/node/index.d.ts",
@@ -138,7 +138,7 @@
138
138
  },
139
139
  "dependencies": {
140
140
  "@open-draft/deferred-promise": "^2.1.0",
141
- "@open-draft/logger": "^0.2.0",
141
+ "@open-draft/logger": "^0.3.0",
142
142
  "@open-draft/until": "^2.0.0",
143
143
  "headers-polyfill": "^3.1.0",
144
144
  "outvariant": "^1.2.1",
@@ -62,22 +62,29 @@ it('gracefully finishes the request when it has a mocked response', async () =>
62
62
  request.end()
63
63
 
64
64
  const responseReceived = new DeferredPromise<IncomingMessage>()
65
+
65
66
  request.on('response', async (response) => {
66
67
  responseReceived.resolve(response)
67
68
  })
68
69
  const response = await responseReceived
69
70
 
70
- // Request must be marked as finished.
71
- expect(request.finished).toEqual(true)
72
- expect(request.writableEnded).toEqual(true)
73
- expect(request.writableFinished).toEqual(true)
74
- expect(request.writableCorked).toEqual(0)
75
-
76
- expect(response.statusCode).toEqual(301)
77
- expect(response.headers).toHaveProperty('x-custom-header', 'yes')
71
+ // Request must be marked as finished as soon as it's sent.
72
+ expect(request.writableEnded).toBe(true)
73
+ expect(request.writableFinished).toBe(true)
74
+ expect(request.writableCorked).toBe(0)
78
75
 
76
+ /**
77
+ * Consume the response body, which will handle the "data" and "end"
78
+ * events of the incoming message. After this point, the response is finished.
79
+ */
79
80
  const text = await getIncomingMessageBody(response)
80
- expect(text).toEqual('mocked-response')
81
+
82
+ // Response must be marked as finished as soon as its done.
83
+ expect(request['response'].complete).toBe(true)
84
+
85
+ expect(response.statusCode).toBe(301)
86
+ expect(response.headers).toHaveProperty('x-custom-header', 'yes')
87
+ expect(text).toBe('mocked-response')
81
88
  })
82
89
 
83
90
  it('responds with a mocked response when requesting an existing hostname', async () => {
@@ -102,10 +109,10 @@ it('responds with a mocked response when requesting an existing hostname', async
102
109
  })
103
110
  const response = await responseReceived
104
111
 
105
- expect(response.statusCode).toEqual(201)
112
+ expect(response.statusCode).toBe(201)
106
113
 
107
114
  const text = await getIncomingMessageBody(response)
108
- expect(text).toEqual('mocked-response')
115
+ expect(text).toBe('mocked-response')
109
116
  })
110
117
 
111
118
  it('performs the request as-is given resolver returned no mocked response', async () => {
@@ -128,15 +135,15 @@ it('performs the request as-is given resolver returned no mocked response', asyn
128
135
  })
129
136
  const response = await responseReceived
130
137
 
131
- expect(request.finished).toEqual(true)
132
- expect(request.writableEnded).toEqual(true)
138
+ expect(request.finished).toBe(true)
139
+ expect(request.writableEnded).toBe(true)
133
140
 
134
- expect(response.statusCode).toEqual(200)
135
- expect(response.statusMessage).toEqual('OK')
141
+ expect(response.statusCode).toBe(200)
142
+ expect(response.statusMessage).toBe('OK')
136
143
  expect(response.headers).toHaveProperty('x-powered-by', 'Express')
137
144
 
138
145
  const text = await getIncomingMessageBody(response)
139
- expect(text).toEqual('original-response')
146
+ expect(text).toBe('original-response')
140
147
  })
141
148
 
142
149
  it('emits the ENOTFOUND error connecting to a non-existing hostname given no mocked response', async () => {
@@ -153,8 +160,8 @@ it('emits the ENOTFOUND error connecting to a non-existing hostname given no moc
153
160
  })
154
161
  const error = await errorReceived
155
162
 
156
- expect(error.code).toEqual('ENOTFOUND')
157
- expect(error.syscall).toEqual('getaddrinfo')
163
+ expect(error.code).toBe('ENOTFOUND')
164
+ expect(error.syscall).toBe('getaddrinfo')
158
165
  })
159
166
 
160
167
  it('emits the ECONNREFUSED error connecting to an inactive server given no mocked response', async () => {
@@ -177,10 +184,10 @@ it('emits the ECONNREFUSED error connecting to an inactive server given no mocke
177
184
 
178
185
  const error = await errorReceived
179
186
 
180
- expect(error.code).toEqual('ECONNREFUSED')
181
- expect(error.syscall).toEqual('connect')
182
- expect(error.address).toEqual('127.0.0.1')
183
- expect(error.port).toEqual(12345)
187
+ expect(error.code).toBe('ECONNREFUSED')
188
+ expect(error.syscall).toBe('connect')
189
+ expect(error.address).toBe('127.0.0.1')
190
+ expect(error.port).toBe(12345)
184
191
  })
185
192
 
186
193
  it('does not emit ENOTFOUND error connecting to an inactive server given mocked response', async () => {
@@ -209,8 +216,8 @@ it('does not emit ENOTFOUND error connecting to an inactive server given mocked
209
216
  const response = await responseReceived
210
217
 
211
218
  expect(handleError).not.toHaveBeenCalled()
212
- expect(response.statusCode).toEqual(200)
213
- expect(response.statusMessage).toEqual('Works')
219
+ expect(response.statusCode).toBe(200)
220
+ expect(response.statusMessage).toBe('Works')
214
221
  })
215
222
 
216
223
  it('does not emit ECONNREFUSED error connecting to an inactive server given mocked response', async () => {
@@ -241,8 +248,8 @@ it('does not emit ECONNREFUSED error connecting to an inactive server given mock
241
248
  const response = await responseReceived
242
249
 
243
250
  expect(handleError).not.toHaveBeenCalled()
244
- expect(response.statusCode).toEqual(200)
245
- expect(response.statusMessage).toEqual('Works')
251
+ expect(response.statusCode).toBe(200)
252
+ expect(response.statusMessage).toBe('Works')
246
253
  })
247
254
 
248
255
  it('sends the request body to the server given no mocked response', async () => {
@@ -270,10 +277,10 @@ it('sends the request body to the server given no mocked response', async () =>
270
277
  })
271
278
  const response = await responseReceived
272
279
 
273
- expect(response.statusCode).toEqual(200)
280
+ expect(response.statusCode).toBe(200)
274
281
 
275
282
  const text = await getIncomingMessageBody(response)
276
- expect(text).toEqual('onetwothree')
283
+ expect(text).toBe('onetwothree')
277
284
  })
278
285
 
279
286
  it('does not send request body to the original server given mocked response', async () => {
@@ -303,8 +310,8 @@ it('does not send request body to the original server given mocked response', as
303
310
  })
304
311
  const response = await responseReceived
305
312
 
306
- expect(response.statusCode).toEqual(301)
313
+ expect(response.statusCode).toBe(301)
307
314
 
308
315
  const text = await getIncomingMessageBody(response)
309
- expect(text).toEqual('mock created!')
316
+ expect(text).toBe('mock created!')
310
317
  })
@@ -370,6 +370,20 @@ export class NodeClientRequest extends ClientRequest {
370
370
  private respondWith(mockedResponse: Response): void {
371
371
  this.logger.info('responding with a mocked response...', mockedResponse)
372
372
 
373
+ /**
374
+ * Mark the request as finished right before streaming back the response.
375
+ * This is not entirely conventional but this will allow the consumer to
376
+ * modify the outoging request in the interceptor.
377
+ *
378
+ * The request is finished when its headers and bodies have been sent.
379
+ * @see https://nodejs.org/api/http.html#event-finish
380
+ */
381
+ Object.defineProperties(this, {
382
+ writableFinished: { value: true },
383
+ writableEnded: { value: true },
384
+ })
385
+ this.emit('finish')
386
+
373
387
  const { status, statusText, headers, body } = mockedResponse
374
388
  this.response.statusCode = status
375
389
  this.response.statusMessage = statusText
@@ -392,18 +406,11 @@ export class NodeClientRequest extends ClientRequest {
392
406
  }
393
407
  this.logger.info('mocked response headers ready:', headers)
394
408
 
395
- const isResponseStreamRead = new DeferredPromise<void>()
396
-
397
- const closeResponseStream = () => {
398
- this.logger.info('closing response stream...')
399
-
400
- // Push "null" to indicate that the response body is complete
401
- // and shouldn't be written to anymore.
402
- this.response.push(null)
403
- this.response.complete = true
409
+ const isResponseStreamFinished = new DeferredPromise<void>()
404
410
 
405
- isResponseStreamRead.resolve()
406
- this.logger.info('closed response stream!')
411
+ const finishResponseStream = () => {
412
+ this.logger.info('finished response stream!')
413
+ isResponseStreamFinished.resolve()
407
414
  }
408
415
 
409
416
  if (body) {
@@ -412,38 +419,41 @@ export class NodeClientRequest extends ClientRequest {
412
419
  const { done, value } = await bodyReader.read()
413
420
 
414
421
  if (done) {
415
- closeResponseStream()
422
+ finishResponseStream()
416
423
  return
417
424
  }
418
425
 
419
- // this.response.push(Buffer.from(body))
420
- this.response.push(value)
426
+ this.response.emit('data', value)
421
427
 
422
428
  return readNextChunk()
423
429
  }
424
430
 
425
431
  readNextChunk()
426
432
  } else {
427
- closeResponseStream()
433
+ finishResponseStream()
428
434
  }
429
435
 
430
- isResponseStreamRead.then(() => {
431
- /**
432
- * Set the internal "res" property to the mocked "OutgoingMessage"
433
- * to make the "ClientRequest" instance think there's data received
434
- * from the socket.
435
- * @see https://github.com/nodejs/node/blob/9c405f2591f5833d0247ed0fafdcd68c5b14ce7a/lib/_http_client.js#L501
436
- */
437
- // @ts-ignore
438
- this.res = this.response
436
+ /**
437
+ * Set the internal "res" property to the mocked "OutgoingMessage"
438
+ * to make the "ClientRequest" instance think there's data received
439
+ * from the socket.
440
+ * @see https://github.com/nodejs/node/blob/9c405f2591f5833d0247ed0fafdcd68c5b14ce7a/lib/_http_client.js#L501
441
+ *
442
+ * Set the response immediately so the interceptor could stream data
443
+ * chunks to the request client as they come in.
444
+ */
445
+ // @ts-ignore
446
+ this.res = this.response
447
+ this.emit('response', this.response)
439
448
 
440
- this.finished = true
441
- Object.defineProperty(this, 'writableEnded', {
442
- value: true,
443
- })
449
+ isResponseStreamFinished.then(() => {
450
+ this.logger.info('finalizing response...')
444
451
 
445
- this.emit('finish')
446
- this.emit('response', this.response)
452
+ // Push "null" to indicate that the response body is complete
453
+ // and shouldn't be written to anymore.
454
+ this.response.push(null)
455
+ this.response.complete = true
456
+ this.response.emit('end')
447
457
 
448
458
  this.terminate()
449
459
  })