Comparing version
@@ -80,3 +80,2 @@ 'use strict' | ||
debug('context:', context) | ||
// If nockedFn is a function then invoke it, otherwise return a promise resolving to nockDone. | ||
@@ -83,0 +82,0 @@ if (typeof nockedFn === 'function') { |
@@ -7,2 +7,3 @@ 'use strict' | ||
const util = require('util') | ||
const http = require('http') | ||
@@ -54,79 +55,3 @@ /** | ||
// Array where all information about all the overridden requests are held. | ||
let requestOverrides = {} | ||
/** | ||
* Overrides the current `request` function of `http` and `https` modules with | ||
* our own version which intercepts issues HTTP/HTTPS requests and forwards them | ||
* to the given `newRequest` function. | ||
* | ||
* @param {Function} newRequest - a function handling requests; it accepts four arguments: | ||
* - proto - a string with the overridden module's protocol name (either `http` or `https`) | ||
* - overriddenRequest - the overridden module's request function already bound to module's object | ||
* - options - the options of the issued request | ||
* - callback - the callback of the issued request | ||
*/ | ||
function overrideRequests(newRequest) { | ||
debug('overriding requests') | ||
;['http', 'https'].forEach(function (proto) { | ||
debug('- overriding request for', proto) | ||
const moduleName = proto // 1 to 1 match of protocol and module is fortunate :) | ||
const module = require(proto) | ||
const overriddenRequest = module.request | ||
const overriddenGet = module.get | ||
if (requestOverrides[moduleName]) { | ||
throw new Error( | ||
`Module's request already overridden for ${moduleName} protocol.`, | ||
) | ||
} | ||
// Store the properties of the overridden request so that it can be restored later on. | ||
requestOverrides[moduleName] = { | ||
module, | ||
request: overriddenRequest, | ||
get: overriddenGet, | ||
} | ||
// https://nodejs.org/api/http.html#http_http_request_url_options_callback | ||
module.request = function (input, options, callback) { | ||
return newRequest(proto, overriddenRequest.bind(module), [ | ||
input, | ||
options, | ||
callback, | ||
]) | ||
} | ||
// https://nodejs.org/api/http.html#http_http_get_options_callback | ||
module.get = function (input, options, callback) { | ||
const req = newRequest(proto, overriddenGet.bind(module), [ | ||
input, | ||
options, | ||
callback, | ||
]) | ||
req.end() | ||
return req | ||
} | ||
debug('- overridden request for', proto) | ||
}) | ||
} | ||
/** | ||
* Restores `request` function of `http` and `https` modules to values they | ||
* held before they were overridden by us. | ||
*/ | ||
function restoreOverriddenRequests() { | ||
debug('restoring requests') | ||
Object.entries(requestOverrides).forEach( | ||
([proto, { module, request, get }]) => { | ||
debug('- restoring request for', proto) | ||
module.request = request | ||
module.get = get | ||
debug('- restored request for', proto) | ||
}, | ||
) | ||
requestOverrides = {} | ||
} | ||
/** | ||
* In WHATWG URL vernacular, this returns the origin portion of a URL. | ||
@@ -621,2 +546,3 @@ * However, the port is not included if it's standard and not already present on the host. | ||
function removeAllTimers() { | ||
debug('remove all timers') | ||
clearTimer(clearTimeout, timeouts) | ||
@@ -656,2 +582,27 @@ clearTimer(clearInterval, intervals) | ||
/** | ||
* @param {Request} request | ||
*/ | ||
function convertFetchRequestToClientRequest(request) { | ||
const url = new URL(request.url); | ||
const options = { | ||
...urlToOptions(url), | ||
method: request.method, | ||
host: url.hostname, | ||
port: url.port || (url.protocol === 'https:' ? 443 : 80), | ||
path: url.pathname + url.search, | ||
proto: url.protocol.slice(0, -1), | ||
headers: Object.fromEntries(request.headers.entries()) | ||
}; | ||
// By default, Node adds a host header, but for maximum backward compatibility, we are now removing it. | ||
// However, we need to consider leaving the header and fixing the tests. | ||
if (options.headers.host === options.host) { | ||
const { host, ...restHeaders } = options.headers | ||
options.headers = restHeaders | ||
} | ||
return new http.ClientRequest(options); | ||
} | ||
/** | ||
* Returns true if the given value is a plain object and not an Array. | ||
@@ -742,20 +693,2 @@ * @param {*} value | ||
/** | ||
* @param {Request} request | ||
*/ | ||
function convertFetchRequestToOptions(request) { | ||
const url = new URL(request.url) | ||
const options = { | ||
...urlToOptions(url), | ||
method: request.method, | ||
host: url.hostname, | ||
port: url.port || (url.protocol === 'https:' ? 443 : 80), | ||
path: url.pathname + url.search, | ||
proto: url.protocol.slice(0, -1), | ||
headers: Object.fromEntries(request.headers.entries()), | ||
} | ||
return options | ||
} | ||
module.exports = { | ||
@@ -782,7 +715,5 @@ contentEncoding, | ||
normalizeRequestOptions, | ||
overrideRequests, | ||
percentDecode, | ||
percentEncode, | ||
removeAllTimers, | ||
restoreOverriddenRequests, | ||
setImmediate, | ||
@@ -792,3 +723,3 @@ setInterval, | ||
stringifyRequest, | ||
convertFetchRequestToClientRequest: convertFetchRequestToOptions, | ||
convertFetchRequestToClientRequest, | ||
} |
'use strict' | ||
const zlib = require('node:zlib') | ||
const { headersArrayToObject } = require('./common') | ||
const { STATUS_CODES } = require('http') | ||
const { pipeline, Readable } = require('node:stream') | ||
@@ -21,77 +18,35 @@ /** | ||
/** | ||
* @param {import('node:http').IncomingMessage} message | ||
* @param {import('http').IncomingMessage} message | ||
*/ | ||
function createResponse(message) { | ||
// https://github.com/Uzlopak/undici/blob/main/lib/fetch/index.js#L2031 | ||
const decoders = [] | ||
const codings = | ||
message.headers['content-encoding'] | ||
?.toLowerCase() | ||
.split(',') | ||
.map(x => x.trim()) | ||
.reverse() || [] | ||
for (const coding of codings) { | ||
if (coding === 'gzip' || coding === 'x-gzip') { | ||
decoders.push( | ||
zlib.createGunzip({ | ||
flush: zlib.constants.Z_SYNC_FLUSH, | ||
finishFlush: zlib.constants.Z_SYNC_FLUSH, | ||
}), | ||
) | ||
} else if (coding === 'deflate') { | ||
decoders.push(zlib.createInflate()) | ||
} else if (coding === 'br') { | ||
decoders.push(zlib.createBrotliDecompress()) | ||
} else { | ||
decoders.length = 0 | ||
break | ||
} | ||
} | ||
let isCanceled = false | ||
const chunks = [] | ||
const responseBodyOrNull = responseStatusCodesWithoutBody.includes( | ||
message.statusCode, | ||
message.statusCode || 200 | ||
) | ||
? null | ||
: new ReadableStream({ | ||
start(controller) { | ||
message.on('data', chunk => chunks.push(chunk)) | ||
message.on('end', () => { | ||
pipeline( | ||
Readable.from(chunks), | ||
...decoders, | ||
async function* (source) { | ||
for await (const chunk of source) { | ||
yield controller.enqueue(chunk) | ||
} | ||
}, | ||
error => { | ||
if (error) { | ||
controller.error(error) | ||
} else if (!isCanceled) { | ||
controller.close() | ||
} | ||
}, | ||
) | ||
}) | ||
start(controller) { | ||
message.on('data', (chunk) => controller.enqueue(chunk)) | ||
message.on('end', () => controller.close()) | ||
message.on('error', (error) => controller.error(error)) | ||
}, | ||
cancel() { | ||
message.destroy() | ||
}, | ||
}) | ||
/** | ||
* @todo Should also listen to the "error" on the message | ||
* and forward it to the controller. Otherwise the stream | ||
* will pend indefinitely. | ||
*/ | ||
}, | ||
cancel() { | ||
isCanceled = true | ||
}, | ||
}) | ||
const rawHeaders = new Headers() | ||
for (let i = 0; i < message.rawHeaders.length; i += 2) { | ||
rawHeaders.append(message.rawHeaders[i], message.rawHeaders[i + 1]) | ||
} | ||
return new Response(responseBodyOrNull, { | ||
// @mswjs/interceptors supports rawHeaders. https://github.com/mswjs/interceptors/pull/598 | ||
const response = new Response(responseBodyOrNull, { | ||
status: message.statusCode, | ||
statusText: STATUS_CODES[message.statusCode], | ||
headers: headersArrayToObject(message.rawHeaders), | ||
statusText: message.statusMessage || STATUS_CODES[message.statusCode], | ||
headers: rawHeaders, | ||
}) | ||
return response | ||
} | ||
module.exports = { createResponse } |
@@ -13,4 +13,14 @@ 'use strict' | ||
const globalEmitter = require('./global_emitter') | ||
const { BatchInterceptor } = require('@mswjs/interceptors') | ||
const { FetchInterceptor } = require('@mswjs/interceptors/fetch') | ||
const { default: nodeInterceptors } = require('@mswjs/interceptors/presets/node') | ||
const { createResponse } = require('./create_response') | ||
const { once } = require('events') | ||
const interceptor = new BatchInterceptor({ | ||
name: 'nock-interceptor', | ||
interceptors: [...nodeInterceptors, new FetchInterceptor()], | ||
}) | ||
let isNockActive = false | ||
/** | ||
@@ -188,4 +198,3 @@ * @name NetConnectNotAllowedError | ||
debug( | ||
`matched base path (${interceptors.length} interceptor${ | ||
interceptors.length > 1 ? 's' : '' | ||
`matched base path (${interceptors.length} interceptor${interceptors.length > 1 ? 's' : '' | ||
})`, | ||
@@ -243,16 +252,3 @@ ) | ||
let originalClientRequest | ||
// Variable where we keep the fetch we have overridden | ||
let originalFetch | ||
function ErroringClientRequest(error) { | ||
http.OutgoingMessage.call(this) | ||
process.nextTick( | ||
function () { | ||
this.emit('error', error) | ||
}.bind(this), | ||
) | ||
} | ||
inherits(ErroringClientRequest, http.ClientRequest) | ||
function overrideClientRequest() { | ||
@@ -311,5 +307,3 @@ // Here's some background discussion about overriding ClientRequest: | ||
if (isOff() || isEnabledForNetConnect(options)) { | ||
if (options.isFetchRequest === undefined) { | ||
originalClientRequest.apply(this, arguments) | ||
} | ||
originalClientRequest.apply(this, arguments) | ||
} else { | ||
@@ -345,8 +339,7 @@ common.setImmediate( | ||
} else { | ||
isNockActive = false; | ||
interceptor.dispose() | ||
http.ClientRequest = originalClientRequest | ||
originalClientRequest = undefined | ||
global.fetch = originalFetch | ||
originalFetch = undefined | ||
debug('- ClientRequest restored') | ||
@@ -357,5 +350,3 @@ } | ||
function isActive() { | ||
// If ClientRequest has been overwritten by Nock then originalClientRequest is not undefined. | ||
// This means that Nock has been activated. | ||
return originalClientRequest !== undefined | ||
return isNockActive | ||
} | ||
@@ -367,3 +358,4 @@ | ||
) | ||
return [].concat(...nestedInterceptors).map(i => i.scope) | ||
const scopes = new Set([].concat(...nestedInterceptors).map(i => i.scope)) | ||
return [...scopes] | ||
} | ||
@@ -384,93 +376,60 @@ | ||
function activate() { | ||
if (originalClientRequest) { | ||
if (isNockActive) { | ||
throw new Error('Nock already active') | ||
} | ||
// ----- Overriding http.request and https.request: | ||
common.overrideRequests(function (proto, overriddenRequest, args) { | ||
// NOTE: overriddenRequest is already bound to its module. | ||
const { options, callback } = common.normalizeClientRequestArgs(...args) | ||
if (Object.keys(options).length === 0) { | ||
// As weird as it is, it's possible to call `http.request` without | ||
// options, and it makes a request to localhost or somesuch. We should | ||
// support it too, for parity. However it doesn't work today, and fixing | ||
// it seems low priority. Giving an explicit error is nicer than | ||
// crashing with a weird stack trace. `new ClientRequest()`, nock's | ||
// other client-facing entry point, makes a similar check. | ||
// https://github.com/nock/nock/pull/1386 | ||
// https://github.com/nock/nock/pull/1440 | ||
throw Error( | ||
'Making a request with empty `options` is not supported in Nock', | ||
) | ||
} | ||
// The option per the docs is `protocol`. Its unclear if this line is meant to override that and is misspelled or if | ||
// the intend is to explicitly keep track of which module was called using a separate name. | ||
// Either way, `proto` is used as the source of truth from here on out. | ||
options.proto = proto | ||
overrideClientRequest() | ||
interceptor.apply(); | ||
// Force msw to forward Nock's error instead of coerce it into 500 error | ||
interceptor.on('unhandledException', ({ controller, error }) => { | ||
controller.errorWith(error) | ||
}) | ||
interceptor.on('request', async function ({ request: mswRequest, controller }) { | ||
const request = mswRequest.clone() | ||
const { options } = common.normalizeClientRequestArgs(request.url) | ||
options.proto = options.protocol.slice(0, -1) | ||
options.method = request.method | ||
const interceptors = interceptorsFor(options) | ||
if (isOn() && interceptors) { | ||
const matches = interceptors.some(interceptor => | ||
interceptor.matchOrigin(options), | ||
interceptor.matchOrigin(options) | ||
) | ||
const allowUnmocked = interceptors.some( | ||
interceptor => interceptor.options.allowUnmocked, | ||
interceptor => interceptor.options.allowUnmocked | ||
) | ||
const nockRequest = common.convertFetchRequestToClientRequest(request); | ||
if (!matches && allowUnmocked) { | ||
let req | ||
if (proto === 'https') { | ||
const { ClientRequest } = http | ||
http.ClientRequest = originalClientRequest | ||
req = overriddenRequest(options, callback) | ||
http.ClientRequest = ClientRequest | ||
} else { | ||
req = overriddenRequest(options, callback) | ||
} | ||
globalEmitter.emit('no match', req) | ||
return req | ||
globalEmitter.emit('no match', nockRequest) | ||
} else { | ||
nockRequest.on('response', nockResponse => { | ||
// TODO: Consider put empty headers object as default when create the ClientRequest | ||
if (nockResponse.req.headers) { | ||
// forward Nock request headers to the MSW request | ||
Object.entries(nockResponse.req.headers).map(([k, v]) => mswRequest.headers.set(k, v)) | ||
} | ||
const response = createResponse(nockResponse) | ||
controller.respondWith(response) | ||
}) | ||
const promise = Promise.race([ | ||
// TODO: temp hacky way to handle allowUnmocked in startPlayback | ||
once(nockRequest, 'real-request'), | ||
once(nockRequest, 'error'), | ||
once(nockRequest, 'response'), | ||
]) | ||
const buffer = await request.arrayBuffer() | ||
nockRequest.write(buffer) | ||
nockRequest.end() | ||
await promise | ||
} | ||
// NOTE: Since we already overrode the http.ClientRequest we are in fact constructing | ||
// our own OverriddenClientRequest. | ||
return new http.ClientRequest(options, callback) | ||
} else { | ||
globalEmitter.emit('no match', options) | ||
if (isOff() || isEnabledForNetConnect(options)) { | ||
return overriddenRequest(options, callback) | ||
} else { | ||
const error = new NetConnectNotAllowedError(options.host, options.path) | ||
return new ErroringClientRequest(error) | ||
if (!(isOff() || isEnabledForNetConnect(options))) { | ||
throw new NetConnectNotAllowedError(options.host, options.path) | ||
} | ||
} | ||
}) | ||
originalFetch = global.fetch | ||
global.fetch = async (input, init = undefined) => { | ||
const request = new Request(input, init) | ||
const options = common.convertFetchRequestToClientRequest(request) | ||
options.isFetchRequest = true | ||
const body = await request.arrayBuffer() | ||
const clientRequest = new http.ClientRequest(options) | ||
// If mock found | ||
if (clientRequest.interceptors) { | ||
return new Promise((resolve, reject) => { | ||
clientRequest.on('response', response => { | ||
resolve(createResponse(response)) | ||
}) | ||
clientRequest.on('error', reject) | ||
clientRequest.end(body) | ||
}) | ||
} else { | ||
return originalFetch(input, init) | ||
} | ||
} | ||
overrideClientRequest() | ||
isNockActive = true | ||
} | ||
@@ -477,0 +436,0 @@ |
@@ -7,5 +7,3 @@ 'use strict' | ||
ClientRequest, | ||
request: originalHttpRequest, | ||
} = require('http') | ||
const { request: originalHttpsRequest } = require('https') | ||
const propagate = require('propagate') | ||
@@ -337,10 +335,3 @@ const common = require('./common') | ||
if (allowUnmocked && req instanceof ClientRequest) { | ||
const newReq = | ||
options.proto === 'https' | ||
? originalHttpsRequest(options) | ||
: originalHttpRequest(options) | ||
propagate(newReq, req) | ||
// We send the raw buffer as we received it, not as we interpreted it. | ||
newReq.end(requestBodyBuffer) | ||
req.emit('real-request') | ||
} else { | ||
@@ -347,0 +338,0 @@ const reqStr = common.stringifyRequest(options, requestBodyString) |
@@ -201,6 +201,12 @@ 'use strict' | ||
} | ||
const readStream = fs.createReadStream(filePath) | ||
readStream.pause() | ||
this.filePath = filePath | ||
return this.reply(statusCode, readStream, headers) | ||
return this.reply( | ||
statusCode, | ||
() => { | ||
const readStream = fs.createReadStream(filePath) | ||
readStream.pause() | ||
return readStream | ||
}, | ||
headers, | ||
) | ||
} | ||
@@ -450,11 +456,2 @@ | ||
if ( | ||
(this.scope.shouldPersist() || this.counter > 0) && | ||
this.interceptionCounter > 1 && | ||
this.filePath | ||
) { | ||
this.body = fs.createReadStream(this.filePath) | ||
this.body.pause() | ||
} | ||
remove(this) | ||
@@ -508,3 +505,3 @@ | ||
if (queries instanceof URLSearchParams) { | ||
if (queries instanceof URLSearchParams || typeof queries === 'string') { | ||
// Normalize the data into the shape that is matched against. | ||
@@ -511,0 +508,0 @@ // Duplicate keys are handled by combining the values into an array. |
@@ -9,2 +9,6 @@ 'use strict' | ||
const { restoreOverriddenClientRequest } = require('./intercept') | ||
const { BatchInterceptor } = require('@mswjs/interceptors') | ||
const { FetchInterceptor } = require('@mswjs/interceptors/fetch') | ||
const { default: nodeInterceptors } = require('@mswjs/interceptors/presets/node') | ||
const { EventEmitter } = require('stream') | ||
@@ -15,2 +19,8 @@ const SEPARATOR = '\n<<<<<<-- cut here -->>>>>>\n' | ||
// TODO: Consider use one BatchInterceptor (and not one for intercept and one for record) | ||
const interceptor = new BatchInterceptor({ | ||
name: 'nock-interceptor', | ||
interceptors: [...nodeInterceptors, new FetchInterceptor()], | ||
}) | ||
function getScope(options) { | ||
@@ -215,3 +225,3 @@ const { proto, host, port } = common.normalizeRequestOptions(options) | ||
// behavior in the face of other modules also overriding ClientRequest. | ||
common.restoreOverriddenRequests() | ||
// common.restoreOverriddenRequests() | ||
// We restore ClientRequest as it messes with recording of modules that also override ClientRequest (e.g. xhr2) | ||
@@ -221,5 +231,8 @@ restoreOverriddenClientRequest() | ||
// We override the requests so that we can save information on them before executing. | ||
common.overrideRequests(function (proto, overriddenRequest, rawArgs) { | ||
const { options, callback } = common.normalizeClientRequestArgs(...rawArgs) | ||
const bodyChunks = [] | ||
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) | ||
@@ -230,11 +243,13 @@ // Node 0.11 https.request calls http.request -- don't want to record things | ||
if (options._recording) { | ||
return overriddenRequest(options, callback) | ||
return | ||
} | ||
options._recording = true | ||
const req = overriddenRequest(options, function (res) { | ||
const req = new EventEmitter(); | ||
req.on('response', function () { | ||
debug(thisRecordingId, 'intercepting', proto, 'request to record') | ||
// We put our 'end' listener to the front of the listener array. | ||
res.once('end', function () { | ||
// Intercept "res.once('end', ...)"-like event | ||
interceptor.once('response', async function ({ response: mswResponse }) { | ||
const response = mswResponse.clone() | ||
debug(thisRecordingId, proto, 'intercepted request ended') | ||
@@ -247,6 +262,13 @@ | ||
// they actually make testing more difficult without providing any benefit (see README) | ||
reqheaders = req.getHeaders() | ||
reqheaders = Object.fromEntries(request.headers.entries()) | ||
common.deleteHeadersField(reqheaders, 'user-agent') | ||
} | ||
const headers = Object.fromEntries(response.headers.entries()) | ||
const res = { | ||
statusCode: response.status, | ||
headers, | ||
rawHeaders: headers, | ||
} | ||
const generateFn = outputObjects | ||
@@ -256,7 +278,7 @@ ? generateRequestAndResponseObject | ||
let out = generateFn({ | ||
req, | ||
bodyChunks, | ||
req: options, | ||
bodyChunks: [Buffer.from(await request.arrayBuffer())], | ||
options, | ||
res, | ||
dataChunks, | ||
dataChunks: [Buffer.from(await response.arrayBuffer())], | ||
reqheaders, | ||
@@ -294,29 +316,2 @@ }) | ||
let encoding | ||
// We need to be aware of changes to the stream's encoding so that we | ||
// don't accidentally mangle the data. | ||
const { setEncoding } = res | ||
res.setEncoding = function (newEncoding) { | ||
encoding = newEncoding | ||
return setEncoding.apply(this, arguments) | ||
} | ||
const dataChunks = [] | ||
// Replace res.push with our own implementation that stores chunks | ||
const origResPush = res.push | ||
res.push = function (data) { | ||
if (data) { | ||
if (encoding) { | ||
data = Buffer.from(data, encoding) | ||
} | ||
dataChunks.push(data) | ||
} | ||
return origResPush.call(res, data) | ||
} | ||
if (callback) { | ||
callback(res, options, callback) | ||
} | ||
debug('finished setting up intercepting') | ||
@@ -333,41 +328,6 @@ | ||
const recordChunk = (chunk, encoding) => { | ||
debug(thisRecordingId, 'new', proto, 'body chunk') | ||
if (!Buffer.isBuffer(chunk)) { | ||
chunk = Buffer.from(chunk, encoding) | ||
} | ||
bodyChunks.push(chunk) | ||
} | ||
const oldWrite = req.write | ||
req.write = function (chunk, encoding) { | ||
if (typeof chunk !== 'undefined') { | ||
recordChunk(chunk, encoding) | ||
oldWrite.apply(req, arguments) | ||
} else { | ||
throw new Error('Data was undefined.') | ||
} | ||
} | ||
// Starting in Node 8, `OutgoingMessage.end()` directly calls an internal | ||
// `write_` function instead of proxying to the public | ||
// `OutgoingMessage.write()` method, so we have to wrap `end` too. | ||
const oldEnd = req.end | ||
req.end = function (chunk, encoding, callback) { | ||
debug('req.end') | ||
if (typeof chunk === 'function') { | ||
callback = chunk | ||
chunk = null | ||
} else if (typeof encoding === 'function') { | ||
callback = encoding | ||
encoding = null | ||
} | ||
if (chunk) { | ||
recordChunk(chunk, encoding) | ||
} | ||
oldEnd.call(req, chunk, encoding, callback) | ||
} | ||
return req | ||
// 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') | ||
}) | ||
@@ -383,3 +343,3 @@ } | ||
common.restoreOverriddenRequests() | ||
interceptor.dispose() | ||
restoreOverriddenClientRequest() | ||
@@ -386,0 +346,0 @@ recordingInProgress = false |
@@ -10,3 +10,3 @@ { | ||
], | ||
"version": "14.0.0-beta.7", | ||
"version": "14.0.0-beta.8", | ||
"author": "Pedro Teixeira <pedro.teixeira@gmail.com>", | ||
@@ -26,2 +26,3 @@ "repository": { | ||
"dependencies": { | ||
"@mswjs/interceptors": "^0.33.1", | ||
"json-stringify-safe": "^5.0.1", | ||
@@ -49,3 +50,3 @@ "propagate": "^2.0.0" | ||
"nyc": "^15.0.0", | ||
"prettier": "3.1.0", | ||
"prettier": "3.2.5", | ||
"proxyquire": "^2.1.0", | ||
@@ -52,0 +53,0 @@ "rimraf": "^3.0.0", |
@@ -259,3 +259,3 @@ // TypeScript Version: 3.5 | ||
options: BackOptions, | ||
nockedFn: (nockDone: () => void) => void, | ||
nockedFn: (nockDone: () => Promise<void>) => void, | ||
): void | ||
@@ -266,3 +266,3 @@ ( | ||
): Promise<{ | ||
nockDone: () => void | ||
nockDone: () => Promise<void> | ||
context: BackContext | ||
@@ -269,0 +269,0 @@ }> |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
6
-14.29%185625
-3.03%3
50%3566
-4.88%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added