Skip to content

Commit

Permalink
fix(dep): migrate from lodash.set to lodash. (#2306)
Browse files Browse the repository at this point in the history
Listing `lodash` as a prod dependency has a few advantages over the single func dep we were using.
Primarily, when a security vulnerability is patched in LoDash, those changes don't get published to individual function libs anymore.
The most recent example being the prototype pollution that was patched in 4.17.16.
That particular vulnerability didn't effect Nock because of our usage, however, Nock does show up as having a vulnerability because of it which is a pain for consumers. It also creates a future problem where the next patch could affect Nock more directly.
#2279

It should be noted that LoDash itself discourages the use of these single function libs: https://lodash.com/per-method-packages

This changes also removes the vendor-izing of two LoDash functions in favor of using the lib directly (`isPlainObject` and `mapValues`).
  • Loading branch information
mastermatt committed Jun 3, 2022
1 parent 8a82b50 commit e4b0331
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 67 deletions.
49 changes: 2 additions & 47 deletions lib/common.js
@@ -1,7 +1,8 @@
'use strict'

const debug = require('debug')('nock.common')
const set = require('lodash.set')
const isPlainObject = require('lodash/isPlainObject')
const set = require('lodash/set')
const timers = require('timers')
const url = require('url')
const util = require('util')
Expand Down Expand Up @@ -608,51 +609,6 @@ function deepEqual(expected, actual) {
return expected === actual
}

/**
* Checks if `value` is a plain object, that is, an object created by the
* `Object` constructor or one with a `[[Prototype]]` of `null`.
* https://github.com/lodash/lodash/blob/588bf3e20db0ae039a822a14a8fa238c5b298e65/isPlainObject.js
*
* @param {*} value The value to check.
* @return {boolean}
*/
function isPlainObject(value) {
const isObjectLike = typeof value === 'object' && value !== null
const tag = Object.prototype.toString.call(value)
if (!isObjectLike || tag !== '[object Object]') {
return false
}
if (Object.getPrototypeOf(value) === null) {
return true
}
let proto = value
while (Object.getPrototypeOf(proto) !== null) {
proto = Object.getPrototypeOf(proto)
}
return Object.getPrototypeOf(value) === proto
}

/**
* Creates an object with the same keys as `object` and values generated
* by running each own enumerable string keyed property of `object` thru
* `iteratee`. (iteration order is not guaranteed)
* The iteratee is invoked with three arguments: (value, key, object).
* https://github.com/lodash/lodash/blob/588bf3e20db0ae039a822a14a8fa238c5b298e65/mapValue.js
*
* @param {Object} object The object to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Object} Returns the new mapped object.
*/
function mapValue(object, iteratee) {
object = Object(object)
const result = {}

Object.keys(object).forEach(key => {
result[key] = iteratee(object[key], key, object)
})
return result
}

const timeouts = []
const intervals = []
const immediates = []
Expand Down Expand Up @@ -725,7 +681,6 @@ module.exports = {
isRequestDestroyed,
isStream,
isUtf8Representable,
mapValue,
matchStringOrRegexp,
normalizeClientRequestArgs,
normalizeOrigin,
Expand Down
9 changes: 5 additions & 4 deletions lib/match_body.js
@@ -1,5 +1,6 @@
'use strict'

const mapValues = require('lodash/mapValues')
const querystring = require('querystring')

const common = require('./common')
Expand Down Expand Up @@ -43,7 +44,7 @@ module.exports = function matchBody(options, spec, body) {
}

// strip line endings from both so that we get a match no matter what OS we are running on
// if Content-Type does not contains 'multipart'
// if Content-Type does not contain 'multipart'
if (!isMultipart && typeof body === 'string') {
body = body.replace(/\r?\n|\r/g, '')
}
Expand All @@ -52,8 +53,8 @@ module.exports = function matchBody(options, spec, body) {
spec = spec.replace(/\r?\n|\r/g, '')
}

// Because the nature of URL encoding, all the values in the body have been cast to strings.
// dataEqual does strict checking so we we have to cast the non-regexp values in the spec too.
// Because the nature of URL encoding, all the values in the body must be cast to strings.
// dataEqual does strict checking, so we have to cast the non-regexp values in the spec too.
if (isUrlencoded) {
spec = mapValuesDeep(spec, val => (val instanceof RegExp ? val : `${val}`))
}
Expand All @@ -70,7 +71,7 @@ function mapValuesDeep(obj, cb) {
return obj.map(v => mapValuesDeep(v, cb))
}
if (common.isPlainObject(obj)) {
return common.mapValue(obj, v => mapValuesDeep(v, cb))
return mapValues(obj, v => mapValuesDeep(v, cb))
}
return cb(obj)
}
18 changes: 3 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -24,7 +24,7 @@
"dependencies": {
"debug": "^4.1.0",
"json-stringify-safe": "^5.0.1",
"lodash.set": "^4.3.2",
"lodash": "^4.17.21",
"propagate": "^2.0.0"
},
"devDependencies": {
Expand Down

0 comments on commit e4b0331

Please sign in to comment.