nock 13.5.1 → 14.0.0-beta.2

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/common.js CHANGED
@@ -735,6 +735,24 @@ const expand = input => {
735
735
  return result
736
736
  }
737
737
 
738
+ /**
739
+ * @param {Request} request
740
+ */
741
+ function convertFetchRequestToOptions(request) {
742
+ const url = new URL(request.url)
743
+ const options = {
744
+ ...urlToOptions(url),
745
+ method: request.method,
746
+ host: url.hostname,
747
+ port: url.port || (url.protocol === 'https:' ? 443 : 80),
748
+ path: url.pathname + url.search,
749
+ proto: url.protocol.slice(0, -1),
750
+ headers: Object.fromEntries(request.headers.entries()),
751
+ }
752
+
753
+ return options
754
+ }
755
+
738
756
  module.exports = {
739
757
  contentEncoding,
740
758
  dataEqual,
@@ -765,4 +783,5 @@ module.exports = {
765
783
  setInterval,
766
784
  setTimeout,
767
785
  stringifyRequest,
786
+ convertFetchRequestToClientRequest: convertFetchRequestToOptions,
768
787
  }
@@ -0,0 +1,45 @@
1
+ 'use strict'
2
+
3
+ const { headersArrayToObject } = require('./common')
4
+
5
+ /**
6
+ * Creates a Fetch API `Response` instance from the given
7
+ * `http.IncomingMessage` instance.
8
+ * Inspired by: https://github.com/mswjs/interceptors/blob/04152ed914f8041272b6e92ed374216b8177e1b2/src/interceptors/ClientRequest/utils/createResponse.ts#L8
9
+ */
10
+
11
+ /**
12
+ * Response status codes for responses that cannot have body.
13
+ * @see https://fetch.spec.whatwg.org/#statuses
14
+ */
15
+ const responseStatusCodesWithoutBody = [204, 205, 304]
16
+
17
+ /**
18
+ * @param {IncomingMessage} message
19
+ */
20
+ function createResponse(message) {
21
+ const responseBodyOrNull = responseStatusCodesWithoutBody.includes(
22
+ message.statusCode,
23
+ )
24
+ ? null
25
+ : new ReadableStream({
26
+ start(controller) {
27
+ message.on('data', chunk => controller.enqueue(chunk))
28
+ message.on('end', () => controller.close())
29
+
30
+ /**
31
+ * @todo Should also listen to the "error" on the message
32
+ * and forward it to the controller. Otherwise the stream
33
+ * will pend indefinitely.
34
+ */
35
+ },
36
+ })
37
+
38
+ return new Response(responseBodyOrNull, {
39
+ status: message.statusCode,
40
+ statusText: message.statusMessage,
41
+ headers: headersArrayToObject(message.rawHeaders),
42
+ })
43
+ }
44
+
45
+ module.exports = { createResponse }
package/lib/intercept.js CHANGED
@@ -10,6 +10,7 @@ const { inherits } = require('util')
10
10
  const http = require('http')
11
11
  const debug = require('debug')('nock.intercept')
12
12
  const globalEmitter = require('./global_emitter')
13
+ const { createResponse } = require('./create_response')
13
14
 
14
15
  /**
15
16
  * @name NetConnectNotAllowedError
@@ -237,6 +238,8 @@ function removeInterceptor(options) {
237
238
  // Variable where we keep the ClientRequest we have overridden
238
239
  // (which might or might not be node's original http.ClientRequest)
239
240
  let originalClientRequest
241
+ // Variable where we keep the fetch we have overridden
242
+ let originalFetch
240
243
 
241
244
  function ErroringClientRequest(error) {
242
245
  http.OutgoingMessage.call(this)
@@ -302,7 +305,9 @@ function overrideClientRequest() {
302
305
 
303
306
  // Fallback to original ClientRequest if nock is off or the net connection is enabled.
304
307
  if (isOff() || isEnabledForNetConnect(options)) {
305
- originalClientRequest.apply(this, arguments)
308
+ if (options.isFetchRequest === undefined) {
309
+ originalClientRequest.apply(this, arguments)
310
+ }
306
311
  } else {
307
312
  common.setImmediate(
308
313
  function () {
@@ -336,6 +341,9 @@ function restoreOverriddenClientRequest() {
336
341
  http.ClientRequest = originalClientRequest
337
342
  originalClientRequest = undefined
338
343
 
344
+ global.fetch = originalFetch
345
+ originalFetch = undefined
346
+
339
347
  debug('- ClientRequest restored')
340
348
  }
341
349
  }
@@ -434,6 +442,28 @@ function activate() {
434
442
  }
435
443
  })
436
444
 
445
+ originalFetch = global.fetch
446
+ global.fetch = async (input, init = undefined) => {
447
+ const request = new Request(input, init)
448
+ const options = common.convertFetchRequestToClientRequest(request)
449
+ options.isFetchRequest = true
450
+ const body = await request.arrayBuffer()
451
+ const clientRequest = new http.ClientRequest(options)
452
+
453
+ // If mock found
454
+ if (clientRequest.interceptors) {
455
+ return new Promise((resolve, reject) => {
456
+ clientRequest.on('response', response => {
457
+ resolve(createResponse(response))
458
+ })
459
+ clientRequest.on('error', reject)
460
+ clientRequest.end(body)
461
+ })
462
+ } else {
463
+ return originalFetch(input, init)
464
+ }
465
+ }
466
+
437
467
  overrideClientRequest()
438
468
  }
439
469
 
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "testing",
8
8
  "isolation"
9
9
  ],
10
- "version": "13.5.1",
10
+ "version": "14.0.0-beta.2",
11
11
  "author": "Pedro Teixeira <pedro.teixeira@gmail.com>",
12
12
  "repository": {
13
13
  "type": "git",