🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Book a DemoInstallSign in
Socket

nock

Package Overview
Dependencies
Maintainers
4
Versions
445
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

to
14.0.1

197

lib/recorder.js

@@ -9,3 +9,2 @@ 'use strict'

const { restoreOverriddenClientRequest } = require('./intercept')
const { EventEmitter } = require('stream')
const { gzipSync, brotliCompressSync, deflateSync } = require('zlib')

@@ -229,130 +228,102 @@ const {

fetchRequestInterceptor.apply()
clientRequestInterceptor.on('request', async function ({ request }) {
await recordRequest(request)
})
fetchRequestInterceptor.on('request', async function ({ request }) {
await recordRequest(request)
})
clientRequestInterceptor.on(
'response',
async function ({ request, response }) {
await recordResponse(request, response)
},
)
fetchRequestInterceptor.on(
'response',
async function ({ request, 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()) || []
async function recordRequest(mswRequest) {
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)
}
}
await recordResponse(request, new Response(body, response))
},
)
async function recordResponse(mswRequest, mswResponse) {
const request = mswRequest.clone()
const response = mswResponse.clone()
const { options } = common.normalizeClientRequestArgs(request.url)
options.method = request.method
const proto = options.protocol.slice(0, -1)
if (proto === 'https') {
options.proto = 'https'
}
debug(thisRecordingId, proto, 'intercepted request ended')
// Node 0.11 https.request calls http.request -- don't want to record things
// twice.
/* istanbul ignore if */
if (options._recording) {
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')
}
options._recording = true
const req = new EventEmitter()
req.on('response', function () {
debug(thisRecordingId, 'intercepting', proto, 'request to record')
const headers = Object.fromEntries(response.headers.entries())
const res = {
statusCode: response.status,
headers,
rawHeaders: headers,
}
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 generateFn = outputObjects
? generateRequestAndResponseObject
: generateRequestAndResponse
let out = generateFn({
req: options,
bodyChunks: [Buffer.from(await request.arrayBuffer())],
options,
res,
dataChunks: [Buffer.from(await response.arrayBuffer())],
reqheaders,
})
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)
}
}
debug('out:', out)
await recordResponse(new Response(body, response))
})
// 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
}
// Intercept "res.once('end', ...)"-like event
async function recordResponse(mswResponse) {
const response = mswResponse.clone()
debug(thisRecordingId, proto, 'intercepted request ended')
outputs.push(out)
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')
if (!dontPrint) {
if (useSeparator) {
if (typeof out !== 'string') {
out = JSON.stringify(out, null, 2)
}
const headers = Object.fromEntries(response.headers.entries())
const res = {
statusCode: response.status,
headers,
rawHeaders: headers,
}
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('out:', out)
// 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
}
outputs.push(out)
if (!dontPrint) {
if (useSeparator) {
if (typeof out !== 'string') {
out = JSON.stringify(out, null, 2)
}
logging(SEPARATOR + out + SEPARATOR)
} else {
logging(out)
}
}
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')
debug('finished setting up intercepting')
}

@@ -359,0 +330,0 @@ }

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

],
"version": "14.0.0",
"version": "14.0.1",
"author": "Pedro Teixeira <pedro.teixeira@gmail.com>",

@@ -21,3 +21,3 @@ "repository": {

"engines": {
"node": ">= 18"
"node": ">=18.20.0 <20 || >=20.12.1"
},

@@ -24,0 +24,0 @@ "main": "./index.js",