nock 13.3.3 → 13.3.5
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/README.md +4 -4
- package/lib/back.js +3 -3
- package/lib/common.js +94 -20
- package/lib/intercept.js +10 -10
- package/lib/intercepted_request_router.js +6 -6
- package/lib/interceptor.js +14 -14
- package/lib/match_body.js +8 -1
- package/lib/playback_interceptor.js +2 -2
- package/lib/recorder.js +3 -3
- package/lib/scope.js +9 -9
- package/lib/socket.js +1 -1
- package/package.json +4 -5
- package/types/index.d.ts +25 -19
package/README.md
CHANGED
|
@@ -1142,7 +1142,7 @@ nock.enableNetConnect(/(amazon|github)\.com/)
|
|
|
1142
1142
|
|
|
1143
1143
|
// Or a Function
|
|
1144
1144
|
nock.enableNetConnect(
|
|
1145
|
-
host => host.includes('amazon.com') || host.includes('github.com')
|
|
1145
|
+
host => host.includes('amazon.com') || host.includes('github.com'),
|
|
1146
1146
|
)
|
|
1147
1147
|
|
|
1148
1148
|
http.get('http://www.amazon.com/')
|
|
@@ -1228,7 +1228,7 @@ The returned call objects have the following properties:
|
|
|
1228
1228
|
- `body` - the body of the call, if any
|
|
1229
1229
|
- `status` - the HTTP status of the reply (e.g. `200`)
|
|
1230
1230
|
- `response` - the body of the reply which can be a JSON, string, hex string representing binary buffers or an array of such hex strings (when handling `content-encoded` in reply header)
|
|
1231
|
-
- `
|
|
1231
|
+
- `rawHeaders` - the headers of the reply which are formatted as a flat array containing header name and header value pairs (e.g. `['accept', 'application/json', 'set-cookie', 'my-cookie=value']`)
|
|
1232
1232
|
- `reqheader` - the headers of the request
|
|
1233
1233
|
|
|
1234
1234
|
If you save this as a JSON file, you can load them directly through `nock.load(path)`. Then you can post-process them before using them in the tests. For example, to add request body filtering (shown here fixing timestamps to match the ones captured during recording):
|
|
@@ -1248,7 +1248,7 @@ nocks.forEach(function (nock) {
|
|
|
1248
1248
|
/(timestamp):([0-9]+)/g,
|
|
1249
1249
|
function (match, key, value) {
|
|
1250
1250
|
return key + ':' + recordedTimestamp
|
|
1251
|
-
}
|
|
1251
|
+
},
|
|
1252
1252
|
)
|
|
1253
1253
|
} else {
|
|
1254
1254
|
return body
|
|
@@ -1467,7 +1467,7 @@ function prepareScope(scope) {
|
|
|
1467
1467
|
const recordedTimestamp = recordedBodyResult[1]
|
|
1468
1468
|
return body.replace(
|
|
1469
1469
|
/(timestamp):([0-9]+)/g,
|
|
1470
|
-
(match, key, value) => `${key}:${recordedTimestamp}
|
|
1470
|
+
(match, key, value) => `${key}:${recordedTimestamp}`,
|
|
1471
1471
|
)
|
|
1472
1472
|
} else {
|
|
1473
1473
|
return body
|
package/lib/back.js
CHANGED
|
@@ -49,7 +49,7 @@ function Back(fixtureName, options, nockedFn) {
|
|
|
49
49
|
throw new Error(
|
|
50
50
|
'Back requires nock.back.fixtures to be set\n' +
|
|
51
51
|
'Ex:\n' +
|
|
52
|
-
"\trequire(nock).back.fixtures = '/path/to/fixtures/'"
|
|
52
|
+
"\trequire(nock).back.fixtures = '/path/to/fixtures/'",
|
|
53
53
|
)
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -300,8 +300,8 @@ function assertScopes(scopes, fixture) {
|
|
|
300
300
|
format(
|
|
301
301
|
'%j was not used, consider removing %s to rerecord fixture',
|
|
302
302
|
[].concat(...pending),
|
|
303
|
-
fixture
|
|
304
|
-
)
|
|
303
|
+
fixture,
|
|
304
|
+
),
|
|
305
305
|
)
|
|
306
306
|
}
|
|
307
307
|
}
|
package/lib/common.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const debug = require('debug')('nock.common')
|
|
4
|
-
const isPlainObject = require('lodash/isPlainObject')
|
|
5
|
-
const set = require('lodash/set')
|
|
6
4
|
const timers = require('timers')
|
|
7
5
|
const url = require('url')
|
|
8
6
|
const util = require('util')
|
|
@@ -81,7 +79,7 @@ function overrideRequests(newRequest) {
|
|
|
81
79
|
|
|
82
80
|
if (requestOverrides[moduleName]) {
|
|
83
81
|
throw new Error(
|
|
84
|
-
`Module's request already overridden for ${moduleName} protocol
|
|
82
|
+
`Module's request already overridden for ${moduleName} protocol.`,
|
|
85
83
|
)
|
|
86
84
|
}
|
|
87
85
|
|
|
@@ -126,7 +124,7 @@ function restoreOverriddenRequests() {
|
|
|
126
124
|
module.request = request
|
|
127
125
|
module.get = get
|
|
128
126
|
debug('- restored request for', proto)
|
|
129
|
-
}
|
|
127
|
+
},
|
|
130
128
|
)
|
|
131
129
|
requestOverrides = {}
|
|
132
130
|
}
|
|
@@ -206,11 +204,11 @@ function headersFieldNamesToLowerCase(headers, throwOnDuplicate) {
|
|
|
206
204
|
if (lowerCaseHeaders[key] !== undefined) {
|
|
207
205
|
if (throwOnDuplicate) {
|
|
208
206
|
throw Error(
|
|
209
|
-
`Failed to convert header keys to lower case due to field name conflict: ${key}
|
|
207
|
+
`Failed to convert header keys to lower case due to field name conflict: ${key}`,
|
|
210
208
|
)
|
|
211
209
|
} else {
|
|
212
210
|
debug(
|
|
213
|
-
`Duplicate header provided in request: ${key}. Only the last value can be matched
|
|
211
|
+
`Duplicate header provided in request: ${key}. Only the last value can be matched.`,
|
|
214
212
|
)
|
|
215
213
|
}
|
|
216
214
|
}
|
|
@@ -244,7 +242,7 @@ function headersInputToRawArray(headers) {
|
|
|
244
242
|
// but throw an error if there aren't an even number of items in the array
|
|
245
243
|
if (headers.length % 2) {
|
|
246
244
|
throw new Error(
|
|
247
|
-
`Raw headers must be provided as an array with an even number of items. [fieldName, value, ...]
|
|
245
|
+
`Raw headers must be provided as an array with an even number of items. [fieldName, value, ...]`,
|
|
248
246
|
)
|
|
249
247
|
}
|
|
250
248
|
return [...headers]
|
|
@@ -260,7 +258,7 @@ function headersInputToRawArray(headers) {
|
|
|
260
258
|
}
|
|
261
259
|
|
|
262
260
|
throw new Error(
|
|
263
|
-
`Headers must be provided as an array of raw values, a Map, or a plain Object. ${headers}
|
|
261
|
+
`Headers must be provided as an array of raw values, a Map, or a plain Object. ${headers}`,
|
|
264
262
|
)
|
|
265
263
|
}
|
|
266
264
|
|
|
@@ -568,17 +566,6 @@ const dataEqual = (expected, actual) => {
|
|
|
568
566
|
return deepEqual(expected, actual)
|
|
569
567
|
}
|
|
570
568
|
|
|
571
|
-
/**
|
|
572
|
-
* Converts flat objects whose keys use JSON path notation to nested objects.
|
|
573
|
-
*
|
|
574
|
-
* The input object is not mutated.
|
|
575
|
-
*
|
|
576
|
-
* @example
|
|
577
|
-
* { 'foo[bar][0]': 'baz' } -> { foo: { bar: [ 'baz' ] } }
|
|
578
|
-
*/
|
|
579
|
-
const expand = input =>
|
|
580
|
-
Object.entries(input).reduce((acc, [k, v]) => set(acc, k, v), {})
|
|
581
|
-
|
|
582
569
|
/**
|
|
583
570
|
* Performs a recursive strict comparison between two values.
|
|
584
571
|
*
|
|
@@ -600,7 +587,7 @@ function deepEqual(expected, actual) {
|
|
|
600
587
|
|
|
601
588
|
if (isPlainObject(expected) && isPlainObject(actual)) {
|
|
602
589
|
const allKeys = Array.from(
|
|
603
|
-
new Set(Object.keys(expected).concat(Object.keys(actual)))
|
|
590
|
+
new Set(Object.keys(expected).concat(Object.keys(actual))),
|
|
604
591
|
)
|
|
605
592
|
|
|
606
593
|
return allKeys.every(key => deepEqual(expected[key], actual[key]))
|
|
@@ -665,10 +652,97 @@ function isRequestDestroyed(req) {
|
|
|
665
652
|
)
|
|
666
653
|
}
|
|
667
654
|
|
|
655
|
+
/**
|
|
656
|
+
* Returns true if the given value is a plain object and not an Array.
|
|
657
|
+
* @param {*} value
|
|
658
|
+
* @returns {boolean}
|
|
659
|
+
*/
|
|
660
|
+
function isPlainObject(value) {
|
|
661
|
+
if (typeof value !== 'object' || value === null) return false
|
|
662
|
+
|
|
663
|
+
if (Object.prototype.toString.call(value) !== '[object Object]') return false
|
|
664
|
+
|
|
665
|
+
const proto = Object.getPrototypeOf(value)
|
|
666
|
+
if (proto === null) return true
|
|
667
|
+
|
|
668
|
+
const Ctor =
|
|
669
|
+
Object.prototype.hasOwnProperty.call(proto, 'constructor') &&
|
|
670
|
+
proto.constructor
|
|
671
|
+
return (
|
|
672
|
+
typeof Ctor === 'function' &&
|
|
673
|
+
Ctor instanceof Ctor &&
|
|
674
|
+
Function.prototype.call(Ctor) === Function.prototype.call(value)
|
|
675
|
+
)
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
const prototypePollutionBlockList = ['__proto__', 'prototype', 'constructor']
|
|
679
|
+
const blocklistFilter = function (part) {
|
|
680
|
+
return prototypePollutionBlockList.indexOf(part) === -1
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/**
|
|
684
|
+
* Converts flat objects whose keys use JSON path notation to nested objects.
|
|
685
|
+
*
|
|
686
|
+
* The input object is not mutated.
|
|
687
|
+
*
|
|
688
|
+
* @example
|
|
689
|
+
* { 'foo[bar][0]': 'baz' } -> { foo: { bar: [ 'baz' ] } }
|
|
690
|
+
*/
|
|
691
|
+
const expand = input => {
|
|
692
|
+
if (input === undefined || input === null) {
|
|
693
|
+
return input
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
const keys = Object.keys(input)
|
|
697
|
+
|
|
698
|
+
const result = {}
|
|
699
|
+
let resultPtr = result
|
|
700
|
+
|
|
701
|
+
for (let path of keys) {
|
|
702
|
+
const originalPath = path
|
|
703
|
+
if (path.indexOf('[') >= 0) {
|
|
704
|
+
path = path.replace(/\[/g, '.').replace(/]/g, '')
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
const parts = path.split('.')
|
|
708
|
+
|
|
709
|
+
const check = parts.filter(blocklistFilter)
|
|
710
|
+
|
|
711
|
+
if (check.length !== parts.length) {
|
|
712
|
+
return undefined
|
|
713
|
+
}
|
|
714
|
+
resultPtr = result
|
|
715
|
+
const lastIndex = parts.length - 1
|
|
716
|
+
|
|
717
|
+
for (let i = 0; i < parts.length; ++i) {
|
|
718
|
+
const part = parts[i]
|
|
719
|
+
if (i === lastIndex) {
|
|
720
|
+
if (Array.isArray(resultPtr)) {
|
|
721
|
+
resultPtr[+part] = input[originalPath]
|
|
722
|
+
} else {
|
|
723
|
+
resultPtr[part] = input[originalPath]
|
|
724
|
+
}
|
|
725
|
+
} else {
|
|
726
|
+
if (resultPtr[part] === undefined || resultPtr[part] === null) {
|
|
727
|
+
const nextPart = parts[i + 1]
|
|
728
|
+
if (/^\d+$/.test(nextPart)) {
|
|
729
|
+
resultPtr[part] = []
|
|
730
|
+
} else {
|
|
731
|
+
resultPtr[part] = {}
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
resultPtr = resultPtr[part]
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
return result
|
|
739
|
+
}
|
|
740
|
+
|
|
668
741
|
module.exports = {
|
|
669
742
|
contentEncoding,
|
|
670
743
|
dataEqual,
|
|
671
744
|
deleteHeadersField,
|
|
745
|
+
expand,
|
|
672
746
|
forEachHeader,
|
|
673
747
|
formatQueryValue,
|
|
674
748
|
headersArrayToObject,
|
package/lib/intercept.js
CHANGED
|
@@ -151,7 +151,7 @@ function interceptorsFor(options) {
|
|
|
151
151
|
|
|
152
152
|
// First try to use filteringScope if any of the interceptors has it defined.
|
|
153
153
|
for (const { key, interceptors, allowUnmocked } of Object.values(
|
|
154
|
-
allInterceptors
|
|
154
|
+
allInterceptors,
|
|
155
155
|
)) {
|
|
156
156
|
for (const interceptor of interceptors) {
|
|
157
157
|
const { filteringScope } = interceptor.__nock_scopeOptions
|
|
@@ -185,7 +185,7 @@ function interceptorsFor(options) {
|
|
|
185
185
|
debug(
|
|
186
186
|
`matched base path (${interceptors.length} interceptor${
|
|
187
187
|
interceptors.length > 1 ? 's' : ''
|
|
188
|
-
})
|
|
188
|
+
})`,
|
|
189
189
|
)
|
|
190
190
|
return interceptors
|
|
191
191
|
}
|
|
@@ -243,7 +243,7 @@ function ErroringClientRequest(error) {
|
|
|
243
243
|
process.nextTick(
|
|
244
244
|
function () {
|
|
245
245
|
this.emit('error', error)
|
|
246
|
-
}.bind(this)
|
|
246
|
+
}.bind(this),
|
|
247
247
|
)
|
|
248
248
|
}
|
|
249
249
|
|
|
@@ -272,7 +272,7 @@ function overrideClientRequest() {
|
|
|
272
272
|
// https://github.com/nock/nock/pull/1386
|
|
273
273
|
// https://github.com/nock/nock/pull/1440
|
|
274
274
|
throw Error(
|
|
275
|
-
'Creating a ClientRequest with empty `options` is not supported in Nock'
|
|
275
|
+
'Creating a ClientRequest with empty `options` is not supported in Nock',
|
|
276
276
|
)
|
|
277
277
|
}
|
|
278
278
|
|
|
@@ -308,10 +308,10 @@ function overrideClientRequest() {
|
|
|
308
308
|
function () {
|
|
309
309
|
const error = new NetConnectNotAllowedError(
|
|
310
310
|
options.host,
|
|
311
|
-
options.path
|
|
311
|
+
options.path,
|
|
312
312
|
)
|
|
313
313
|
this.emit('error', error)
|
|
314
|
-
}.bind(this)
|
|
314
|
+
}.bind(this),
|
|
315
315
|
)
|
|
316
316
|
}
|
|
317
317
|
}
|
|
@@ -348,7 +348,7 @@ function isActive() {
|
|
|
348
348
|
|
|
349
349
|
function interceptorScopes() {
|
|
350
350
|
const nestedInterceptors = Object.values(allInterceptors).map(
|
|
351
|
-
i => i.interceptors
|
|
351
|
+
i => i.interceptors,
|
|
352
352
|
)
|
|
353
353
|
return [].concat(...nestedInterceptors).map(i => i.scope)
|
|
354
354
|
}
|
|
@@ -389,7 +389,7 @@ function activate() {
|
|
|
389
389
|
// https://github.com/nock/nock/pull/1386
|
|
390
390
|
// https://github.com/nock/nock/pull/1440
|
|
391
391
|
throw Error(
|
|
392
|
-
'Making a request with empty `options` is not supported in Nock'
|
|
392
|
+
'Making a request with empty `options` is not supported in Nock',
|
|
393
393
|
)
|
|
394
394
|
}
|
|
395
395
|
|
|
@@ -402,10 +402,10 @@ function activate() {
|
|
|
402
402
|
|
|
403
403
|
if (isOn() && interceptors) {
|
|
404
404
|
const matches = interceptors.some(interceptor =>
|
|
405
|
-
interceptor.matchOrigin(options)
|
|
405
|
+
interceptor.matchOrigin(options),
|
|
406
406
|
)
|
|
407
407
|
const allowUnmocked = interceptors.some(
|
|
408
|
-
interceptor => interceptor.options.allowUnmocked
|
|
408
|
+
interceptor => interceptor.options.allowUnmocked,
|
|
409
409
|
)
|
|
410
410
|
|
|
411
411
|
if (!matches && allowUnmocked) {
|
|
@@ -42,7 +42,7 @@ class InterceptedRequestRouter {
|
|
|
42
42
|
// We use lower-case header field names throughout Nock.
|
|
43
43
|
headers: common.headersFieldNamesToLowerCase(
|
|
44
44
|
options.headers || {},
|
|
45
|
-
false
|
|
45
|
+
false,
|
|
46
46
|
),
|
|
47
47
|
}
|
|
48
48
|
this.interceptors = interceptors
|
|
@@ -89,7 +89,7 @@ class InterceptedRequestRouter {
|
|
|
89
89
|
req.setHeader(
|
|
90
90
|
// We use lower-case header field names throughout Nock.
|
|
91
91
|
'authorization',
|
|
92
|
-
`Basic ${Buffer.from(options.auth).toString('base64')}
|
|
92
|
+
`Basic ${Buffer.from(options.auth).toString('base64')}`,
|
|
93
93
|
)
|
|
94
94
|
}
|
|
95
95
|
|
|
@@ -297,16 +297,16 @@ class InterceptedRequestRouter {
|
|
|
297
297
|
const requestBodyIsUtf8Representable =
|
|
298
298
|
common.isUtf8Representable(requestBodyBuffer)
|
|
299
299
|
const requestBodyString = requestBodyBuffer.toString(
|
|
300
|
-
requestBodyIsUtf8Representable ? 'utf8' : 'hex'
|
|
300
|
+
requestBodyIsUtf8Representable ? 'utf8' : 'hex',
|
|
301
301
|
)
|
|
302
302
|
|
|
303
303
|
const matchedInterceptor = interceptors.find(i =>
|
|
304
|
-
i.match(req, options, requestBodyString)
|
|
304
|
+
i.match(req, options, requestBodyString),
|
|
305
305
|
)
|
|
306
306
|
|
|
307
307
|
if (matchedInterceptor) {
|
|
308
308
|
matchedInterceptor.scope.logger(
|
|
309
|
-
'interceptor identified, starting mocking'
|
|
309
|
+
'interceptor identified, starting mocking',
|
|
310
310
|
)
|
|
311
311
|
|
|
312
312
|
matchedInterceptor.markConsumed()
|
|
@@ -329,7 +329,7 @@ class InterceptedRequestRouter {
|
|
|
329
329
|
|
|
330
330
|
// Try to find a hostname match that allows unmocked.
|
|
331
331
|
const allowUnmocked = interceptors.some(
|
|
332
|
-
i => i.matchHostName(options) && i.options.allowUnmocked
|
|
332
|
+
i => i.matchHostName(options) && i.options.allowUnmocked,
|
|
333
333
|
)
|
|
334
334
|
|
|
335
335
|
if (allowUnmocked && req instanceof ClientRequest) {
|
package/lib/interceptor.js
CHANGED
|
@@ -39,13 +39,13 @@ module.exports = class Interceptor {
|
|
|
39
39
|
!uri.startsWith('*')
|
|
40
40
|
) {
|
|
41
41
|
throw Error(
|
|
42
|
-
`Non-wildcard URL path strings must begin with a slash (otherwise they won't match anything) (got: ${uri})
|
|
42
|
+
`Non-wildcard URL path strings must begin with a slash (otherwise they won't match anything) (got: ${uri})`,
|
|
43
43
|
)
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
if (!method) {
|
|
47
47
|
throw new Error(
|
|
48
|
-
'The "method" parameter is required for an intercept call.'
|
|
48
|
+
'The "method" parameter is required for an intercept call.',
|
|
49
49
|
)
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -67,10 +67,10 @@ module.exports = class Interceptor {
|
|
|
67
67
|
// We use lower-case header field names throughout Nock.
|
|
68
68
|
this.reqheaders = common.headersFieldNamesToLowerCase(
|
|
69
69
|
scope.scopeOptions.reqheaders || {},
|
|
70
|
-
true
|
|
70
|
+
true,
|
|
71
71
|
)
|
|
72
72
|
this.badheaders = common.headersFieldsArrayToLowerCase(
|
|
73
|
-
scope.scopeOptions.badheaders || []
|
|
73
|
+
scope.scopeOptions.badheaders || [],
|
|
74
74
|
)
|
|
75
75
|
|
|
76
76
|
this.delayBodyInMs = 0
|
|
@@ -118,7 +118,7 @@ module.exports = class Interceptor {
|
|
|
118
118
|
// It's not very Javascript-y to throw an error for extra args to a function, but because
|
|
119
119
|
// of legacy behavior, this error was added to reduce confusion for those migrating.
|
|
120
120
|
throw Error(
|
|
121
|
-
'Invalid arguments. When providing a function for the first argument, .reply does not accept other arguments.'
|
|
121
|
+
'Invalid arguments. When providing a function for the first argument, .reply does not accept other arguments.',
|
|
122
122
|
)
|
|
123
123
|
}
|
|
124
124
|
this.statusCode = null
|
|
@@ -152,7 +152,7 @@ module.exports = class Interceptor {
|
|
|
152
152
|
// Including all the default headers is safe for our purposes because of the specific headers we introspect.
|
|
153
153
|
// A more thoughtful process is used to merge the default headers when the response headers are finally computed.
|
|
154
154
|
this.headers = common.headersArrayToObject(
|
|
155
|
-
this.rawHeaders.concat(this.scope._defaultReplyHeaders)
|
|
155
|
+
this.rawHeaders.concat(this.scope._defaultReplyHeaders),
|
|
156
156
|
)
|
|
157
157
|
|
|
158
158
|
// If the content is not encoded we may need to transform the response body.
|
|
@@ -236,7 +236,7 @@ module.exports = class Interceptor {
|
|
|
236
236
|
"request header field doesn't match:",
|
|
237
237
|
key,
|
|
238
238
|
header,
|
|
239
|
-
reqHeader
|
|
239
|
+
reqHeader,
|
|
240
240
|
)
|
|
241
241
|
return false
|
|
242
242
|
}
|
|
@@ -247,7 +247,7 @@ module.exports = class Interceptor {
|
|
|
247
247
|
this.scope.logger(
|
|
248
248
|
'attempting match %s, body = %s',
|
|
249
249
|
stringify(options),
|
|
250
|
-
stringify(body)
|
|
250
|
+
stringify(body),
|
|
251
251
|
)
|
|
252
252
|
}
|
|
253
253
|
|
|
@@ -259,7 +259,7 @@ module.exports = class Interceptor {
|
|
|
259
259
|
|
|
260
260
|
if (this.method !== method) {
|
|
261
261
|
this.scope.logger(
|
|
262
|
-
`Method did not match. Request ${method} Interceptor ${this.method}
|
|
262
|
+
`Method did not match. Request ${method} Interceptor ${this.method}`,
|
|
263
263
|
)
|
|
264
264
|
return false
|
|
265
265
|
}
|
|
@@ -286,7 +286,7 @@ module.exports = class Interceptor {
|
|
|
286
286
|
}
|
|
287
287
|
|
|
288
288
|
const reqHeadersMatch = Object.keys(this.reqheaders).every(key =>
|
|
289
|
-
this.reqheaderMatches(options, key)
|
|
289
|
+
this.reqheaderMatches(options, key),
|
|
290
290
|
)
|
|
291
291
|
|
|
292
292
|
if (!reqHeadersMatch) {
|
|
@@ -299,13 +299,13 @@ module.exports = class Interceptor {
|
|
|
299
299
|
!this.scope.scopeOptions.conditionally()
|
|
300
300
|
) {
|
|
301
301
|
this.scope.logger(
|
|
302
|
-
'matching failed because Scope.conditionally() did not validate'
|
|
302
|
+
'matching failed because Scope.conditionally() did not validate',
|
|
303
303
|
)
|
|
304
304
|
return false
|
|
305
305
|
}
|
|
306
306
|
|
|
307
307
|
const badHeaders = this.badheaders.filter(
|
|
308
|
-
header => header in options.headers
|
|
308
|
+
header => header in options.headers,
|
|
309
309
|
)
|
|
310
310
|
|
|
311
311
|
if (badHeaders.length) {
|
|
@@ -322,7 +322,7 @@ module.exports = class Interceptor {
|
|
|
322
322
|
const matchQueries = this.matchQuery({ search })
|
|
323
323
|
|
|
324
324
|
this.scope.logger(
|
|
325
|
-
matchQueries ? 'query matching succeeded' : 'query matching failed'
|
|
325
|
+
matchQueries ? 'query matching succeeded' : 'query matching failed',
|
|
326
326
|
)
|
|
327
327
|
|
|
328
328
|
if (!matchQueries) {
|
|
@@ -369,7 +369,7 @@ module.exports = class Interceptor {
|
|
|
369
369
|
"bodies don't match: \n",
|
|
370
370
|
this._requestBody,
|
|
371
371
|
'\n',
|
|
372
|
-
body
|
|
372
|
+
body,
|
|
373
373
|
)
|
|
374
374
|
}
|
|
375
375
|
}
|
package/lib/match_body.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const mapValues = require('lodash/mapValues')
|
|
4
3
|
const querystring = require('querystring')
|
|
5
4
|
|
|
6
5
|
const common = require('./common')
|
|
@@ -62,6 +61,14 @@ module.exports = function matchBody(options, spec, body) {
|
|
|
62
61
|
return common.dataEqual(spec, body)
|
|
63
62
|
}
|
|
64
63
|
|
|
64
|
+
function mapValues(object, cb) {
|
|
65
|
+
const keys = Object.keys(object)
|
|
66
|
+
for (const key of keys) {
|
|
67
|
+
object[key] = cb(object[key], key, object)
|
|
68
|
+
}
|
|
69
|
+
return object
|
|
70
|
+
}
|
|
71
|
+
|
|
65
72
|
/**
|
|
66
73
|
* Based on lodash issue discussion
|
|
67
74
|
* https://github.com/lodash/lodash/issues/1244
|
|
@@ -29,7 +29,7 @@ function parseFullReplyResult(response, fullReplyResult) {
|
|
|
29
29
|
|
|
30
30
|
if (fullReplyResult.length > 3) {
|
|
31
31
|
throw Error(
|
|
32
|
-
'The array returned from the .reply callback contains too many values'
|
|
32
|
+
'The array returned from the .reply callback contains too many values',
|
|
33
33
|
)
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -257,7 +257,7 @@ function playbackInterceptor({
|
|
|
257
257
|
}
|
|
258
258
|
|
|
259
259
|
response.rawHeaders.push(
|
|
260
|
-
...selectDefaultHeaders(response.rawHeaders, defaultHeaders)
|
|
260
|
+
...selectDefaultHeaders(response.rawHeaders, defaultHeaders),
|
|
261
261
|
)
|
|
262
262
|
|
|
263
263
|
// Evaluate functional headers.
|
package/lib/recorder.js
CHANGED
|
@@ -68,7 +68,7 @@ function generateRequestAndResponseObject({
|
|
|
68
68
|
}) {
|
|
69
69
|
const { body, isUtf8Representable } = getBodyFromChunks(
|
|
70
70
|
dataChunks,
|
|
71
|
-
res.headers
|
|
71
|
+
res.headers,
|
|
72
72
|
)
|
|
73
73
|
options.path = req.path
|
|
74
74
|
|
|
@@ -120,7 +120,7 @@ function generateRequestAndResponse({
|
|
|
120
120
|
const formattedPair = common.formatQueryValue(
|
|
121
121
|
key,
|
|
122
122
|
queryObj[key],
|
|
123
|
-
common.percentEncode
|
|
123
|
+
common.percentEncode,
|
|
124
124
|
)
|
|
125
125
|
encodedQueryObj[formattedPair[0]] = formattedPair[1]
|
|
126
126
|
}
|
|
@@ -368,7 +368,7 @@ function record(recOptions) {
|
|
|
368
368
|
function restore() {
|
|
369
369
|
debug(
|
|
370
370
|
currentRecordingId,
|
|
371
|
-
'restoring all the overridden http/https properties'
|
|
371
|
+
'restoring all the overridden http/https properties',
|
|
372
372
|
)
|
|
373
373
|
|
|
374
374
|
common.restoreOverriddenRequests()
|
package/lib/scope.js
CHANGED
|
@@ -35,7 +35,7 @@ function normalizeUrl(u) {
|
|
|
35
35
|
|
|
36
36
|
if (!/https?:/.test(u.protocol)) {
|
|
37
37
|
throw new TypeError(
|
|
38
|
-
`Protocol '${u.protocol}' not recognized. This commonly occurs when a hostname and port are included without a protocol, producing a URL that is valid but confusing, and probably not what you want
|
|
38
|
+
`Protocol '${u.protocol}' not recognized. This commonly occurs when a hostname and port are included without a protocol, producing a URL that is valid but confusing, and probably not what you want.`,
|
|
39
39
|
)
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -112,7 +112,7 @@ class Scope extends EventEmitter {
|
|
|
112
112
|
interceptor,
|
|
113
113
|
this,
|
|
114
114
|
this.scopeOptions,
|
|
115
|
-
this.urlParts.hostname
|
|
115
|
+
this.urlParts.hostname,
|
|
116
116
|
)
|
|
117
117
|
}
|
|
118
118
|
|
|
@@ -135,7 +135,7 @@ class Scope extends EventEmitter {
|
|
|
135
135
|
uri,
|
|
136
136
|
method,
|
|
137
137
|
requestBody,
|
|
138
|
-
interceptorOptions
|
|
138
|
+
interceptorOptions,
|
|
139
139
|
)
|
|
140
140
|
|
|
141
141
|
this.interceptors.push(ic)
|
|
@@ -182,7 +182,7 @@ class Scope extends EventEmitter {
|
|
|
182
182
|
this.keyedInterceptors[key].some(({ interceptionCounter, optional }) => {
|
|
183
183
|
const persistedAndUsed = this._persist && interceptionCounter > 0
|
|
184
184
|
return !persistedAndUsed && !optional
|
|
185
|
-
})
|
|
185
|
+
}),
|
|
186
186
|
)
|
|
187
187
|
}
|
|
188
188
|
|
|
@@ -204,7 +204,7 @@ class Scope extends EventEmitter {
|
|
|
204
204
|
done() {
|
|
205
205
|
assert.ok(
|
|
206
206
|
this.isDone(),
|
|
207
|
-
`Mocks not yet satisfied:\n${this.pendingMocks().join('\n')}
|
|
207
|
+
`Mocks not yet satisfied:\n${this.pendingMocks().join('\n')}`,
|
|
208
208
|
)
|
|
209
209
|
}
|
|
210
210
|
|
|
@@ -220,7 +220,7 @@ class Scope extends EventEmitter {
|
|
|
220
220
|
// However the code used to contain a truthiness test of `candidate`.
|
|
221
221
|
// The check is being preserved for now.
|
|
222
222
|
throw Error(
|
|
223
|
-
`Nock internal assertion failed: typeof candidate is ${typeof candidate}. If you encounter this error, please report it as a bug
|
|
223
|
+
`Nock internal assertion failed: typeof candidate is ${typeof candidate}. If you encounter this error, please report it as a bug.`,
|
|
224
224
|
)
|
|
225
225
|
}
|
|
226
226
|
return candidate.replace(filteringArguments[0], filteringArguments[1])
|
|
@@ -234,7 +234,7 @@ class Scope extends EventEmitter {
|
|
|
234
234
|
this.transformPathFunction = this.buildFilter.apply(this, arguments)
|
|
235
235
|
if (!this.transformPathFunction) {
|
|
236
236
|
throw new Error(
|
|
237
|
-
'Invalid arguments: filtering path should be a function or a regular expression'
|
|
237
|
+
'Invalid arguments: filtering path should be a function or a regular expression',
|
|
238
238
|
)
|
|
239
239
|
}
|
|
240
240
|
return this
|
|
@@ -244,7 +244,7 @@ class Scope extends EventEmitter {
|
|
|
244
244
|
this.transformRequestBodyFunction = this.buildFilter.apply(this, arguments)
|
|
245
245
|
if (!this.transformRequestBodyFunction) {
|
|
246
246
|
throw new Error(
|
|
247
|
-
'Invalid arguments: filtering request body should be a function or a regular expression'
|
|
247
|
+
'Invalid arguments: filtering request body should be a function or a regular expression',
|
|
248
248
|
)
|
|
249
249
|
}
|
|
250
250
|
return this
|
|
@@ -326,7 +326,7 @@ function getScopeFromDefinition(nockDef) {
|
|
|
326
326
|
} else {
|
|
327
327
|
if (parseInt(options.port) !== parseInt(nockDef.port)) {
|
|
328
328
|
throw new Error(
|
|
329
|
-
'Mismatched port numbers in scope and port properties of nock definition.'
|
|
329
|
+
'Mismatched port numbers in scope and port properties of nock definition.',
|
|
330
330
|
)
|
|
331
331
|
}
|
|
332
332
|
}
|
package/lib/socket.js
CHANGED
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"testing",
|
|
8
8
|
"isolation"
|
|
9
9
|
],
|
|
10
|
-
"version": "13.3.
|
|
10
|
+
"version": "13.3.5",
|
|
11
11
|
"author": "Pedro Teixeira <pedro.teixeira@gmail.com>",
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"debug": "^4.1.0",
|
|
26
26
|
"json-stringify-safe": "^5.0.1",
|
|
27
|
-
"lodash": "^4.17.21",
|
|
28
27
|
"propagate": "^2.0.0"
|
|
29
28
|
},
|
|
30
29
|
"devDependencies": {
|
|
@@ -34,7 +33,7 @@
|
|
|
34
33
|
"chai": "^4.1.2",
|
|
35
34
|
"dirty-chai": "^2.0.1",
|
|
36
35
|
"eslint": "^8.8.0",
|
|
37
|
-
"eslint-config-prettier": "^
|
|
36
|
+
"eslint-config-prettier": "^9.0.0",
|
|
38
37
|
"eslint-config-standard": "^17.0.0-0",
|
|
39
38
|
"eslint-plugin-import": "^2.16.0",
|
|
40
39
|
"eslint-plugin-mocha": "^10.0.3",
|
|
@@ -45,10 +44,10 @@
|
|
|
45
44
|
"mocha": "^9.1.3",
|
|
46
45
|
"npm-run-all": "^4.1.5",
|
|
47
46
|
"nyc": "^15.0.0",
|
|
48
|
-
"prettier": "
|
|
47
|
+
"prettier": "3.0.3",
|
|
49
48
|
"proxyquire": "^2.1.0",
|
|
50
49
|
"rimraf": "^3.0.0",
|
|
51
|
-
"semantic-release": "^
|
|
50
|
+
"semantic-release": "^22.0.5",
|
|
52
51
|
"sinon": "^15.0.1",
|
|
53
52
|
"sinon-chai": "^3.7.0",
|
|
54
53
|
"typescript": "^5.0.4"
|
package/types/index.d.ts
CHANGED
|
@@ -8,8 +8,8 @@ import { Url, URLSearchParams } from 'url'
|
|
|
8
8
|
export = nock
|
|
9
9
|
|
|
10
10
|
declare function nock(
|
|
11
|
-
basePath: string | RegExp | Url,
|
|
12
|
-
options?: nock.Options
|
|
11
|
+
basePath: string | RegExp | Url | URL,
|
|
12
|
+
options?: nock.Options,
|
|
13
13
|
): nock.Scope
|
|
14
14
|
|
|
15
15
|
declare namespace nock {
|
|
@@ -22,7 +22,7 @@ declare namespace nock {
|
|
|
22
22
|
function removeInterceptor(interceptor: Interceptor | ReqOptions): boolean
|
|
23
23
|
function disableNetConnect(): void
|
|
24
24
|
function enableNetConnect(
|
|
25
|
-
matcher?: string | RegExp | ((host: string) => boolean)
|
|
25
|
+
matcher?: string | RegExp | ((host: string) => boolean),
|
|
26
26
|
): void
|
|
27
27
|
function load(path: string): Scope[]
|
|
28
28
|
function loadDefs(path: string): Definition[]
|
|
@@ -37,7 +37,7 @@ declare namespace nock {
|
|
|
37
37
|
type InterceptFunction = (
|
|
38
38
|
uri: string | RegExp | { (uri: string): boolean },
|
|
39
39
|
requestBody?: RequestBodyMatcher,
|
|
40
|
-
interceptorOptions?: Options
|
|
40
|
+
interceptorOptions?: Options,
|
|
41
41
|
) => Interceptor
|
|
42
42
|
|
|
43
43
|
// Essentially valid, decoded JSON with the addition of possible RegExp. TS doesn't currently have
|
|
@@ -76,7 +76,7 @@ declare namespace nock {
|
|
|
76
76
|
type ReplyHeaderFunction = (
|
|
77
77
|
req: ClientRequest,
|
|
78
78
|
res: IncomingMessage,
|
|
79
|
-
body: string | Buffer
|
|
79
|
+
body: string | Buffer,
|
|
80
80
|
) => string | string[]
|
|
81
81
|
type ReplyHeaderValue = string | string[] | ReplyHeaderFunction
|
|
82
82
|
type ReplyHeaders =
|
|
@@ -110,7 +110,7 @@ declare namespace nock {
|
|
|
110
110
|
uri: string | RegExp | { (uri: string): boolean },
|
|
111
111
|
method: string,
|
|
112
112
|
requestBody?: RequestBodyMatcher,
|
|
113
|
-
options?: Options
|
|
113
|
+
options?: Options,
|
|
114
114
|
) => Interceptor
|
|
115
115
|
|
|
116
116
|
defaultReplyHeaders(headers: ReplyHeaders): this
|
|
@@ -137,7 +137,7 @@ declare namespace nock {
|
|
|
137
137
|
| string
|
|
138
138
|
| DataMatcherMap
|
|
139
139
|
| URLSearchParams
|
|
140
|
-
| { (parsedObj: ParsedUrlQuery): boolean }
|
|
140
|
+
| { (parsedObj: ParsedUrlQuery): boolean },
|
|
141
141
|
): this
|
|
142
142
|
|
|
143
143
|
// tslint (as of 5.16) is under the impression that the callback types can be unified,
|
|
@@ -151,16 +151,16 @@ declare namespace nock {
|
|
|
151
151
|
body: Body,
|
|
152
152
|
callback: (
|
|
153
153
|
err: NodeJS.ErrnoException | null,
|
|
154
|
-
result: ReplyFnResult
|
|
155
|
-
) => void
|
|
156
|
-
) => void
|
|
154
|
+
result: ReplyFnResult,
|
|
155
|
+
) => void,
|
|
156
|
+
) => void,
|
|
157
157
|
): Scope
|
|
158
158
|
reply(
|
|
159
159
|
replyFn: (
|
|
160
160
|
this: ReplyFnContext,
|
|
161
161
|
uri: string,
|
|
162
|
-
body: Body
|
|
163
|
-
) => ReplyFnResult | Promise<ReplyFnResult
|
|
162
|
+
body: Body,
|
|
163
|
+
) => ReplyFnResult | Promise<ReplyFnResult>,
|
|
164
164
|
): Scope
|
|
165
165
|
reply(
|
|
166
166
|
statusCode: StatusCode,
|
|
@@ -168,18 +168,21 @@ declare namespace nock {
|
|
|
168
168
|
this: ReplyFnContext,
|
|
169
169
|
uri: string,
|
|
170
170
|
body: Body,
|
|
171
|
-
callback: (
|
|
171
|
+
callback: (
|
|
172
|
+
err: NodeJS.ErrnoException | null,
|
|
173
|
+
result: ReplyBody,
|
|
174
|
+
) => void,
|
|
172
175
|
) => void,
|
|
173
|
-
headers?: ReplyHeaders
|
|
176
|
+
headers?: ReplyHeaders,
|
|
174
177
|
): Scope
|
|
175
178
|
reply(
|
|
176
179
|
statusCode: StatusCode,
|
|
177
180
|
replyBodyFn: (
|
|
178
181
|
this: ReplyFnContext,
|
|
179
182
|
uri: string,
|
|
180
|
-
body: Body
|
|
183
|
+
body: Body,
|
|
181
184
|
) => ReplyBody | Promise<ReplyBody>,
|
|
182
|
-
headers?: ReplyHeaders
|
|
185
|
+
headers?: ReplyHeaders,
|
|
183
186
|
): Scope
|
|
184
187
|
reply(responseCode?: StatusCode, body?: Body, headers?: ReplyHeaders): Scope
|
|
185
188
|
/* tslint:enable:unified-signatures */
|
|
@@ -188,7 +191,7 @@ declare namespace nock {
|
|
|
188
191
|
replyWithFile(
|
|
189
192
|
statusCode: StatusCode,
|
|
190
193
|
fileName: string,
|
|
191
|
-
headers?: ReplyHeaders
|
|
194
|
+
headers?: ReplyHeaders,
|
|
192
195
|
): Scope
|
|
193
196
|
|
|
194
197
|
matchHeader(name: string, value: RequestHeaderMatcher): this
|
|
@@ -251,9 +254,12 @@ declare namespace nock {
|
|
|
251
254
|
(
|
|
252
255
|
fixtureName: string,
|
|
253
256
|
options: BackOptions,
|
|
254
|
-
nockedFn: (nockDone: () => void) => void
|
|
257
|
+
nockedFn: (nockDone: () => void) => void,
|
|
255
258
|
): void
|
|
256
|
-
(
|
|
259
|
+
(
|
|
260
|
+
fixtureName: string,
|
|
261
|
+
options?: BackOptions,
|
|
262
|
+
): Promise<{
|
|
257
263
|
nockDone: () => void
|
|
258
264
|
context: BackContext
|
|
259
265
|
}>
|