Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

nock

Package Overview
Dependencies
Maintainers
4
Versions
435
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nock - npm Package Compare versions

Comparing version 14.0.0-beta.17 to 14.0.0-beta.18

222

lib/recorder.js

@@ -9,8 +9,7 @@ 'use strict'

const { restoreOverriddenClientRequest } = require('./intercept')
const { BatchInterceptor } = require('@mswjs/interceptors')
const { EventEmitter } = require('stream')
const { gzipSync, brotliCompressSync, deflateSync } = require('zlib')
const {
default: nodeInterceptors,
} = require('@mswjs/interceptors/presets/node')
const { EventEmitter } = require('stream')
const SEPARATOR = '\n<<<<<<-- cut here -->>>>>>\n'

@@ -20,7 +19,5 @@ let recordingInProgress = false

// TODO: Consider use one BatchInterceptor (and not one for intercept and one for record)
const interceptor = new BatchInterceptor({
name: 'nock-interceptor',
interceptors: nodeInterceptors,
})
// TODO: don't reuse the nodeInterceptors, create new ones.
const clientRequestInterceptor = nodeInterceptors[0]
const fetchRequestInterceptor = nodeInterceptors[2]

@@ -231,105 +228,133 @@ function getScope(options) {

// We override the requests so that we can save information on them before executing.
interceptor.apply()
interceptor.on(
'request',
async function ({ request: mswRequest, requestId }) {
const request = mswRequest.clone()
const { options } = common.normalizeClientRequestArgs(request.url)
options.method = request.method
const proto = options.protocol.slice(0, -1)
clientRequestInterceptor.apply()
fetchRequestInterceptor.apply()
clientRequestInterceptor.on('request', async function ({ request }) {
await recordRequest(request)
})
fetchRequestInterceptor.on('request', async function ({ request }) {
await recordRequest(request)
})
// Node 0.11 https.request calls http.request -- don't want to record things
// twice.
/* istanbul ignore if */
if (options._recording) {
return
}
options._recording = true
async function recordRequest(mswRequest) {
const request = mswRequest.clone()
const { options } = common.normalizeClientRequestArgs(request.url)
options.method = request.method
const proto = options.protocol.slice(0, -1)
const req = new EventEmitter()
req.on('response', function () {
debug(thisRecordingId, 'intercepting', proto, 'request to record')
// Node 0.11 https.request calls http.request -- don't want to record things
// twice.
/* istanbul ignore if */
if (options._recording) {
return
}
options._recording = true
// Intercept "res.once('end', ...)"-like event
interceptor.once(
'response',
async function ({ response: mswResponse }) {
const response = mswResponse.clone()
debug(thisRecordingId, proto, 'intercepted request ended')
const req = new EventEmitter()
req.on('response', function () {
debug(thisRecordingId, 'intercepting', proto, 'request to record')
let reqheaders
// Ignore request headers completely unless it was explicitly enabled by the user (see README)
if (enableReqHeadersRecording) {
// We never record user-agent headers as they are worse than useless -
// they actually make testing more difficult without providing any benefit (see README)
reqheaders = Object.fromEntries(request.headers.entries())
common.deleteHeadersField(reqheaders, 'user-agent')
}
clientRequestInterceptor.once('response', async function ({ response }) {
await recordResponse(response)
})
fetchRequestInterceptor.once('response', async function ({ response }) {
// fetch decompresses the body automatically, so we need to recompress it
const codings =
response.headers
.get('content-encoding')
?.toLowerCase()
.split(',')
.map(c => c.trim()) || []
const headers = Object.fromEntries(response.headers.entries())
const res = {
statusCode: response.status,
headers,
rawHeaders: headers,
}
let body = await response.arrayBuffer()
for (const coding of codings) {
if (coding === 'gzip') {
body = gzipSync(body)
} else if (coding === 'deflate') {
body = deflateSync(body)
} else if (coding === 'br') {
body = brotliCompressSync(body)
}
}
const generateFn = outputObjects
? generateRequestAndResponseObject
: generateRequestAndResponse
let out = generateFn({
req: options,
bodyChunks: [Buffer.from(await request.arrayBuffer())],
options,
res,
dataChunks: [Buffer.from(await response.arrayBuffer())],
reqheaders,
})
await recordResponse(new Response(body, response))
})
debug('out:', out)
// Intercept "res.once('end', ...)"-like event
async function recordResponse(mswResponse) {
const response = mswResponse.clone()
debug(thisRecordingId, proto, 'intercepted request ended')
// Check that the request was made during the current recording.
// If it hasn't then skip it. There is no other simple way to handle
// this as it depends on the timing of requests and responses. Throwing
// will make some recordings/unit tests fail randomly depending on how
// fast/slow the response arrived.
// If you are seeing this error then you need to make sure that all
// the requests made during a single recording session finish before
// ending the same recording session.
if (thisRecordingId !== currentRecordingId) {
debug('skipping recording of an out-of-order request', out)
return
}
let reqheaders
// Ignore request headers completely unless it was explicitly enabled by the user (see README)
if (enableReqHeadersRecording) {
// We never record user-agent headers as they are worse than useless -
// they actually make testing more difficult without providing any benefit (see README)
reqheaders = Object.fromEntries(request.headers.entries())
common.deleteHeadersField(reqheaders, 'user-agent')
}
outputs.push(out)
const headers = Object.fromEntries(response.headers.entries())
const res = {
statusCode: response.status,
headers,
rawHeaders: headers,
}
if (!dontPrint) {
if (useSeparator) {
if (typeof out !== 'string') {
out = JSON.stringify(out, null, 2)
}
logging(SEPARATOR + out + SEPARATOR)
} else {
logging(out)
}
}
},
)
const generateFn = outputObjects
? generateRequestAndResponseObject
: generateRequestAndResponse
let out = generateFn({
req: options,
bodyChunks: [Buffer.from(await request.arrayBuffer())],
options,
res,
dataChunks: [Buffer.from(await response.arrayBuffer())],
reqheaders,
})
debug('finished setting up intercepting')
debug('out:', out)
// We override both the http and the https modules; when we are
// serializing the request, we need to know which was called.
// By stuffing the state, we can make sure that nock records
// the intended protocol.
if (proto === 'https') {
options.proto = 'https'
// Check that the request was made during the current recording.
// If it hasn't then skip it. There is no other simple way to handle
// this as it depends on the timing of requests and responses. Throwing
// will make some recordings/unit tests fail randomly depending on how
// fast/slow the response arrived.
// If you are seeing this error then you need to make sure that all
// the requests made during a single recording session finish before
// ending the same recording session.
if (thisRecordingId !== currentRecordingId) {
debug('skipping recording of an out-of-order request', out)
return
}
})
// This is a massive change, we are trying to change minimum code, so we emit end event here
// because mswjs take care for these events
// TODO: refactor the recorder, we no longer need all the listeners and can just record the request we get from MSW
req.emit('response')
},
)
outputs.push(out)
if (!dontPrint) {
if (useSeparator) {
if (typeof out !== 'string') {
out = JSON.stringify(out, null, 2)
}
logging(SEPARATOR + out + SEPARATOR)
} else {
logging(out)
}
}
}
debug('finished setting up intercepting')
// We override both the http and the https modules; when we are
// serializing the request, we need to know which was called.
// By stuffing the state, we can make sure that nock records
// the intended protocol.
if (proto === 'https') {
options.proto = 'https'
}
})
// This is a massive change, we are trying to change minimum code, so we emit end event here
// because mswjs take care for these events
// TODO: refactor the recorder, we no longer need all the listeners and can just record the request we get from MSW
req.emit('response')
}
}

@@ -344,3 +369,4 @@

interceptor.dispose()
clientRequestInterceptor.dispose()
fetchRequestInterceptor.dispose()
restoreOverriddenClientRequest()

@@ -347,0 +373,0 @@ recordingInProgress = false

@@ -10,3 +10,3 @@ {

],
"version": "14.0.0-beta.17",
"version": "14.0.0-beta.18",
"author": "Pedro Teixeira <pedro.teixeira@gmail.com>",

@@ -13,0 +13,0 @@ "repository": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc