nock 14.0.0 → 14.0.2
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/lib/recorder.js +86 -115
- package/package.json +3 -3
package/lib/recorder.js
CHANGED
|
@@ -6,7 +6,6 @@ const { inspect } = require('util')
|
|
|
6
6
|
|
|
7
7
|
const common = require('./common')
|
|
8
8
|
const { restoreOverriddenClientRequest } = require('./intercept')
|
|
9
|
-
const { EventEmitter } = require('stream')
|
|
10
9
|
const { gzipSync, brotliCompressSync, deflateSync } = require('zlib')
|
|
11
10
|
const {
|
|
12
11
|
default: nodeInterceptors,
|
|
@@ -225,134 +224,106 @@ function record(recOptions) {
|
|
|
225
224
|
// We override the requests so that we can save information on them before executing.
|
|
226
225
|
clientRequestInterceptor.apply()
|
|
227
226
|
fetchRequestInterceptor.apply()
|
|
228
|
-
clientRequestInterceptor.on(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
227
|
+
clientRequestInterceptor.on(
|
|
228
|
+
'response',
|
|
229
|
+
async function ({ request, response }) {
|
|
230
|
+
await recordResponse(request, response)
|
|
231
|
+
},
|
|
232
|
+
)
|
|
233
|
+
fetchRequestInterceptor.on(
|
|
234
|
+
'response',
|
|
235
|
+
async function ({ request, response }) {
|
|
236
|
+
// fetch decompresses the body automatically, so we need to recompress it
|
|
237
|
+
const codings =
|
|
238
|
+
response.headers
|
|
239
|
+
.get('content-encoding')
|
|
240
|
+
?.toLowerCase()
|
|
241
|
+
.split(',')
|
|
242
|
+
.map(c => c.trim()) || []
|
|
243
|
+
|
|
244
|
+
let body = await response.arrayBuffer()
|
|
245
|
+
for (const coding of codings) {
|
|
246
|
+
if (coding === 'gzip') {
|
|
247
|
+
body = gzipSync(body)
|
|
248
|
+
} else if (coding === 'deflate') {
|
|
249
|
+
body = deflateSync(body)
|
|
250
|
+
} else if (coding === 'br') {
|
|
251
|
+
body = brotliCompressSync(body)
|
|
252
|
+
}
|
|
253
|
+
}
|
|
234
254
|
|
|
235
|
-
|
|
255
|
+
await recordResponse(request, new Response(body, response))
|
|
256
|
+
},
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
async function recordResponse(mswRequest, mswResponse) {
|
|
236
260
|
const request = mswRequest.clone()
|
|
261
|
+
const response = mswResponse.clone()
|
|
237
262
|
const { options } = common.normalizeClientRequestArgs(request.url)
|
|
238
263
|
options.method = request.method
|
|
239
264
|
const proto = options.protocol.slice(0, -1)
|
|
265
|
+
if (proto === 'https') {
|
|
266
|
+
options.proto = 'https'
|
|
267
|
+
}
|
|
268
|
+
debug(thisRecordingId, proto, 'intercepted request ended')
|
|
269
|
+
|
|
270
|
+
let reqheaders
|
|
271
|
+
// Ignore request headers completely unless it was explicitly enabled by the user (see README)
|
|
272
|
+
if (enableReqHeadersRecording) {
|
|
273
|
+
// We never record user-agent headers as they are worse than useless -
|
|
274
|
+
// they actually make testing more difficult without providing any benefit (see README)
|
|
275
|
+
reqheaders = Object.fromEntries(request.headers.entries())
|
|
276
|
+
common.deleteHeadersField(reqheaders, 'user-agent')
|
|
277
|
+
}
|
|
240
278
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
279
|
+
const headers = Object.fromEntries(response.headers.entries())
|
|
280
|
+
const res = {
|
|
281
|
+
statusCode: response.status,
|
|
282
|
+
headers,
|
|
283
|
+
rawHeaders: headers,
|
|
246
284
|
}
|
|
247
|
-
options._recording = true
|
|
248
|
-
|
|
249
|
-
const req = new EventEmitter()
|
|
250
|
-
req.on('response', function () {
|
|
251
|
-
debug(thisRecordingId, 'intercepting', proto, 'request to record')
|
|
252
|
-
|
|
253
|
-
clientRequestInterceptor.once('response', async function ({ response }) {
|
|
254
|
-
await recordResponse(response)
|
|
255
|
-
})
|
|
256
|
-
fetchRequestInterceptor.once('response', async function ({ response }) {
|
|
257
|
-
// fetch decompresses the body automatically, so we need to recompress it
|
|
258
|
-
const codings =
|
|
259
|
-
response.headers
|
|
260
|
-
.get('content-encoding')
|
|
261
|
-
?.toLowerCase()
|
|
262
|
-
.split(',')
|
|
263
|
-
.map(c => c.trim()) || []
|
|
264
|
-
|
|
265
|
-
let body = await response.arrayBuffer()
|
|
266
|
-
for (const coding of codings) {
|
|
267
|
-
if (coding === 'gzip') {
|
|
268
|
-
body = gzipSync(body)
|
|
269
|
-
} else if (coding === 'deflate') {
|
|
270
|
-
body = deflateSync(body)
|
|
271
|
-
} else if (coding === 'br') {
|
|
272
|
-
body = brotliCompressSync(body)
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
285
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
// We never record user-agent headers as they are worse than useless -
|
|
288
|
-
// they actually make testing more difficult without providing any benefit (see README)
|
|
289
|
-
reqheaders = Object.fromEntries(request.headers.entries())
|
|
290
|
-
common.deleteHeadersField(reqheaders, 'user-agent')
|
|
291
|
-
}
|
|
286
|
+
const generateFn = outputObjects
|
|
287
|
+
? generateRequestAndResponseObject
|
|
288
|
+
: generateRequestAndResponse
|
|
289
|
+
let out = generateFn({
|
|
290
|
+
req: options,
|
|
291
|
+
bodyChunks: [Buffer.from(await request.arrayBuffer())],
|
|
292
|
+
options,
|
|
293
|
+
res,
|
|
294
|
+
dataChunks: [Buffer.from(await response.arrayBuffer())],
|
|
295
|
+
reqheaders,
|
|
296
|
+
})
|
|
292
297
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
298
|
+
debug('out:', out)
|
|
299
|
+
|
|
300
|
+
// Check that the request was made during the current recording.
|
|
301
|
+
// If it hasn't then skip it. There is no other simple way to handle
|
|
302
|
+
// this as it depends on the timing of requests and responses. Throwing
|
|
303
|
+
// will make some recordings/unit tests fail randomly depending on how
|
|
304
|
+
// fast/slow the response arrived.
|
|
305
|
+
// If you are seeing this error then you need to make sure that all
|
|
306
|
+
// the requests made during a single recording session finish before
|
|
307
|
+
// ending the same recording session.
|
|
308
|
+
if (thisRecordingId !== currentRecordingId) {
|
|
309
|
+
debug('skipping recording of an out-of-order request', out)
|
|
310
|
+
return
|
|
311
|
+
}
|
|
299
312
|
|
|
300
|
-
|
|
301
|
-
? generateRequestAndResponseObject
|
|
302
|
-
: generateRequestAndResponse
|
|
303
|
-
let out = generateFn({
|
|
304
|
-
req: options,
|
|
305
|
-
bodyChunks: [Buffer.from(await request.arrayBuffer())],
|
|
306
|
-
options,
|
|
307
|
-
res,
|
|
308
|
-
dataChunks: [Buffer.from(await response.arrayBuffer())],
|
|
309
|
-
reqheaders,
|
|
310
|
-
})
|
|
311
|
-
|
|
312
|
-
debug('out:', out)
|
|
313
|
-
|
|
314
|
-
// Check that the request was made during the current recording.
|
|
315
|
-
// If it hasn't then skip it. There is no other simple way to handle
|
|
316
|
-
// this as it depends on the timing of requests and responses. Throwing
|
|
317
|
-
// will make some recordings/unit tests fail randomly depending on how
|
|
318
|
-
// fast/slow the response arrived.
|
|
319
|
-
// If you are seeing this error then you need to make sure that all
|
|
320
|
-
// the requests made during a single recording session finish before
|
|
321
|
-
// ending the same recording session.
|
|
322
|
-
if (thisRecordingId !== currentRecordingId) {
|
|
323
|
-
debug('skipping recording of an out-of-order request', out)
|
|
324
|
-
return
|
|
325
|
-
}
|
|
313
|
+
outputs.push(out)
|
|
326
314
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
if (
|
|
330
|
-
|
|
331
|
-
if (typeof out !== 'string') {
|
|
332
|
-
out = JSON.stringify(out, null, 2)
|
|
333
|
-
}
|
|
334
|
-
logging(SEPARATOR + out + SEPARATOR)
|
|
335
|
-
} else {
|
|
336
|
-
logging(out)
|
|
337
|
-
}
|
|
315
|
+
if (!dontPrint) {
|
|
316
|
+
if (useSeparator) {
|
|
317
|
+
if (typeof out !== 'string') {
|
|
318
|
+
out = JSON.stringify(out, null, 2)
|
|
338
319
|
}
|
|
320
|
+
logging(SEPARATOR + out + SEPARATOR)
|
|
321
|
+
} else {
|
|
322
|
+
logging(out)
|
|
339
323
|
}
|
|
324
|
+
}
|
|
340
325
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
// We override both the http and the https modules; when we are
|
|
344
|
-
// serializing the request, we need to know which was called.
|
|
345
|
-
// By stuffing the state, we can make sure that nock records
|
|
346
|
-
// the intended protocol.
|
|
347
|
-
if (proto === 'https') {
|
|
348
|
-
options.proto = 'https'
|
|
349
|
-
}
|
|
350
|
-
})
|
|
351
|
-
|
|
352
|
-
// This is a massive change, we are trying to change minimum code, so we emit end event here
|
|
353
|
-
// because mswjs take care for these events
|
|
354
|
-
// TODO: refactor the recorder, we no longer need all the listeners and can just record the request we get from MSW
|
|
355
|
-
req.emit('response')
|
|
326
|
+
debug('finished setting up intercepting')
|
|
356
327
|
}
|
|
357
328
|
}
|
|
358
329
|
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"testing",
|
|
8
8
|
"isolation"
|
|
9
9
|
],
|
|
10
|
-
"version": "14.0.
|
|
10
|
+
"version": "14.0.2",
|
|
11
11
|
"author": "Pedro Teixeira <pedro.teixeira@gmail.com>",
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
"url": "https://github.com/nock/nock/issues"
|
|
18
18
|
},
|
|
19
19
|
"engines": {
|
|
20
|
-
"node": ">=
|
|
20
|
+
"node": ">=18.20.0 <20 || >=20.12.1"
|
|
21
21
|
},
|
|
22
22
|
"main": "./index.js",
|
|
23
23
|
"types": "types",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@mswjs/interceptors": "^0.
|
|
25
|
+
"@mswjs/interceptors": "^0.38.0",
|
|
26
26
|
"json-stringify-safe": "^5.0.1",
|
|
27
27
|
"propagate": "^2.0.0"
|
|
28
28
|
},
|