nock 15.0.0-beta.11 → 15.0.0-beta.13
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/dist/lib/intercept.js
CHANGED
|
@@ -3,10 +3,6 @@
|
|
|
3
3
|
import * as common from './common.js'
|
|
4
4
|
import { intercept as debug } from './debug.js'
|
|
5
5
|
import * as builtinMock from './interceptors/builtin.js'
|
|
6
|
-
import { createRequire } from 'node:module'
|
|
7
|
-
|
|
8
|
-
const _require = createRequire(import.meta.url)
|
|
9
|
-
let undiciMock
|
|
10
6
|
|
|
11
7
|
let allInterceptors = {}
|
|
12
8
|
let allowNetConnect
|
|
@@ -190,6 +186,10 @@ function removeInterceptor(
|
|
|
190
186
|
) {
|
|
191
187
|
allInterceptors[baseUrl].interceptors.splice(i, 1)
|
|
192
188
|
interceptor.scope.remove(key, interceptor)
|
|
189
|
+
const scopeIndex = interceptor.scope.interceptors.indexOf(interceptor)
|
|
190
|
+
if (scopeIndex !== -1) {
|
|
191
|
+
interceptor.scope.interceptors.splice(scopeIndex, 1)
|
|
192
|
+
}
|
|
193
193
|
break
|
|
194
194
|
}
|
|
195
195
|
}
|
|
@@ -231,25 +231,6 @@ function activeMocks() {
|
|
|
231
231
|
function activate() {
|
|
232
232
|
if (!_isActive) {
|
|
233
233
|
builtinMock.activate()
|
|
234
|
-
|
|
235
|
-
if (!undiciMock) {
|
|
236
|
-
try {
|
|
237
|
-
undiciMock = _require('./interceptors/undici.js')
|
|
238
|
-
} catch (err ) {
|
|
239
|
-
if (
|
|
240
|
-
err.code !== 'MODULE_NOT_FOUND' &&
|
|
241
|
-
err.code !== 'ERR_MODULE_NOT_FOUND' &&
|
|
242
|
-
err.code !== 'ERR_REQUIRE_ESM'
|
|
243
|
-
) {
|
|
244
|
-
throw err
|
|
245
|
-
}
|
|
246
|
-
debug(
|
|
247
|
-
'Undici mocking is disabled because the undici module is not installed',
|
|
248
|
-
)
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
undiciMock?.activate()
|
|
253
234
|
_isActive = true
|
|
254
235
|
} else {
|
|
255
236
|
throw new Error('Nock already active')
|
|
@@ -259,7 +240,6 @@ function activate() {
|
|
|
259
240
|
function deactivate() {
|
|
260
241
|
if (_isActive) {
|
|
261
242
|
builtinMock.deactivate()
|
|
262
|
-
undiciMock?.deactivate()
|
|
263
243
|
_isActive = false
|
|
264
244
|
}
|
|
265
245
|
}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import http from 'node:http'
|
|
2
|
-
import { getRawRequest, BatchInterceptor } from '@mswjs/interceptors'
|
|
3
|
-
import nodeInterceptors from '@mswjs/interceptors/presets/node'
|
|
4
1
|
import * as common from '../common.js'
|
|
5
2
|
import handleRequest from '../handle-request.js'
|
|
6
|
-
import { arrayBuffer } from 'node:stream/consumers'
|
|
7
|
-
import { getClientRequestBodyStream } from '@mswjs/interceptors/utils/node'
|
|
8
3
|
import { setGetRequestBody } from '../utils/node/index.js'
|
|
4
|
+
import { BatchInterceptor } from '@mswjs/interceptors'
|
|
5
|
+
import { FetchInterceptor } from '@mswjs/interceptors/fetch'
|
|
6
|
+
import { HttpRequestInterceptor } from '@mswjs/interceptors/http'
|
|
9
7
|
|
|
10
8
|
const interceptor = new BatchInterceptor({
|
|
11
|
-
name: '
|
|
12
|
-
interceptors:
|
|
9
|
+
name: 'intercept',
|
|
10
|
+
interceptors: [new HttpRequestInterceptor(), new FetchInterceptor()],
|
|
13
11
|
})
|
|
14
12
|
|
|
15
13
|
function activate() {
|
|
@@ -19,38 +17,36 @@ function activate() {
|
|
|
19
17
|
interceptor.on('unhandledException', ({ controller, error } ) => {
|
|
20
18
|
controller.errorWith(error)
|
|
21
19
|
})
|
|
22
|
-
interceptor.on(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
request.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
})
|
|
20
|
+
interceptor.on(
|
|
21
|
+
'request',
|
|
22
|
+
async function ({ request, controller, initiator }) {
|
|
23
|
+
if (request.headers.get('expect') === '100-continue') {
|
|
24
|
+
// We currently do not support mocking 100-continue responses, so they are passed through for now.
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// If this is GET request with body, we need to read the body from the socket because Fetch API doesn't support this.
|
|
29
|
+
const requestBodyBuffer = common.decompressRequestBody(
|
|
30
|
+
await request.clone().arrayBuffer(),
|
|
31
|
+
request.headers.get('content-encoding') || '',
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
const decompressedRequest = new Request(request, {
|
|
35
|
+
body:
|
|
36
|
+
requestBodyBuffer.byteLength > 0 && request.method !== 'GET'
|
|
37
|
+
? requestBodyBuffer
|
|
38
|
+
: undefined,
|
|
39
|
+
})
|
|
40
|
+
if (requestBodyBuffer.byteLength > 0 && request.method === 'GET') {
|
|
41
|
+
setGetRequestBody(decompressedRequest, requestBodyBuffer)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const response = await handleRequest(decompressedRequest)
|
|
45
|
+
if (response) {
|
|
46
|
+
controller.respondWith(response)
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
)
|
|
54
50
|
}
|
|
55
51
|
|
|
56
52
|
function deactivate() {
|
package/dist/lib/recorder.js
CHANGED
|
@@ -14,15 +14,18 @@ import { inspect } from 'node:util'
|
|
|
14
14
|
|
|
15
15
|
import * as common from './common.js'
|
|
16
16
|
import { restoreOverriddenClientRequest } from './intercept.js'
|
|
17
|
-
import {
|
|
18
|
-
import
|
|
17
|
+
import { BatchInterceptor } from '@mswjs/interceptors'
|
|
18
|
+
import { ClientRequestInterceptor } from '@mswjs/interceptors/ClientRequest'
|
|
19
|
+
import { FetchInterceptor } from '@mswjs/interceptors/fetch'
|
|
20
|
+
|
|
19
21
|
const SEPARATOR = '\n<<<<<<-- cut here -->>>>>>\n'
|
|
20
22
|
let recordingInProgress = false
|
|
21
23
|
let _outputs = []
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
const interceptor = new BatchInterceptor({
|
|
26
|
+
name: 'intercept',
|
|
27
|
+
interceptors: [new ClientRequestInterceptor(), new FetchInterceptor()],
|
|
28
|
+
})
|
|
26
29
|
|
|
27
30
|
function getScope(url ) {
|
|
28
31
|
return common.normalizeOrigin(url)
|
|
@@ -219,39 +222,10 @@ function record(recOptions ) {
|
|
|
219
222
|
restoreOverriddenClientRequest()
|
|
220
223
|
|
|
221
224
|
// We override the requests so that we can save information on them before executing.
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
async function ({ request, response } ) {
|
|
227
|
-
await recordResponse(request, response)
|
|
228
|
-
},
|
|
229
|
-
)
|
|
230
|
-
fetchRequestInterceptor.on(
|
|
231
|
-
'response',
|
|
232
|
-
async function ({ request, response } ) {
|
|
233
|
-
// fetch decompresses the body automatically, so we need to recompress it
|
|
234
|
-
const codings =
|
|
235
|
-
response.headers
|
|
236
|
-
.get('content-encoding')
|
|
237
|
-
?.toLowerCase()
|
|
238
|
-
.split(',')
|
|
239
|
-
.map((c ) => c.trim()) || []
|
|
240
|
-
|
|
241
|
-
let body = await response.arrayBuffer()
|
|
242
|
-
for (const coding of codings) {
|
|
243
|
-
if (coding === 'gzip') {
|
|
244
|
-
body = gzipSync(body)
|
|
245
|
-
} else if (coding === 'deflate') {
|
|
246
|
-
body = deflateSync(body)
|
|
247
|
-
} else if (coding === 'br') {
|
|
248
|
-
body = brotliCompressSync(body)
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
await recordResponse(request, new Response(body, response))
|
|
253
|
-
},
|
|
254
|
-
)
|
|
225
|
+
interceptor.apply()
|
|
226
|
+
interceptor.on('response', async function ({ request, response }) {
|
|
227
|
+
await recordResponse(request, response)
|
|
228
|
+
})
|
|
255
229
|
|
|
256
230
|
async function recordResponse(mswRequest , mswResponse ) {
|
|
257
231
|
const request = mswRequest.clone()
|
|
@@ -319,8 +293,7 @@ function restore() {
|
|
|
319
293
|
'restoring all the overridden http/https properties',
|
|
320
294
|
)
|
|
321
295
|
|
|
322
|
-
|
|
323
|
-
fetchRequestInterceptor.dispose()
|
|
296
|
+
interceptor.dispose()
|
|
324
297
|
restoreOverriddenClientRequest()
|
|
325
298
|
recordingInProgress = false
|
|
326
299
|
}
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"testing",
|
|
8
8
|
"isolation"
|
|
9
9
|
],
|
|
10
|
-
"version": "15.0.0-beta.
|
|
10
|
+
"version": "15.0.0-beta.13",
|
|
11
11
|
"author": "Pedro Teixeira <pedro.teixeira@gmail.com>",
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@mswjs/interceptors": "^0.
|
|
32
|
+
"@mswjs/interceptors": "^0.42.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@eslint/js": "^9.27.0",
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
// This file is loaded lazily after confirming undici is installed
|
|
2
|
-
|
|
3
|
-
import undici from 'undici'
|
|
4
|
-
import handleRequest from '../handle-request.js'
|
|
5
|
-
import { URL } from 'node:url'
|
|
6
|
-
import { convertHeadersToRaw } from '../common.js'
|
|
7
|
-
|
|
8
|
-
class NockClient extends undici.Client {
|
|
9
|
-
constructor(origin , options ) {
|
|
10
|
-
super(origin, options)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
dispatch(options , handler ) {
|
|
14
|
-
const url = new URL(options.path, options.origin)
|
|
15
|
-
if (options.query) {
|
|
16
|
-
url.search = new URLSearchParams(options.query).toString()
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const decompressedRequest = new Request(url, {
|
|
20
|
-
method: options.method,
|
|
21
|
-
headers: options.headers,
|
|
22
|
-
body: options.body,
|
|
23
|
-
duplex: options.body ? 'half' : undefined,
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
handleRequest(decompressedRequest)
|
|
27
|
-
.then(async (response ) => {
|
|
28
|
-
if (response) {
|
|
29
|
-
handler.onConnect?.((err ) => handler.onError(err), null)
|
|
30
|
-
handler.onHeaders?.(
|
|
31
|
-
response.status,
|
|
32
|
-
convertHeadersToRaw(response.headers),
|
|
33
|
-
() => {},
|
|
34
|
-
response.statusText,
|
|
35
|
-
)
|
|
36
|
-
handler.onData?.(Buffer.from(await response.arrayBuffer()))
|
|
37
|
-
handler.onComplete?.([]) // responseTrailers
|
|
38
|
-
} else {
|
|
39
|
-
const dispatcher = options.dispatcher || {
|
|
40
|
-
dispatch: super.dispatch.bind(this),
|
|
41
|
-
}
|
|
42
|
-
dispatcher.dispatch(options, handler)
|
|
43
|
-
}
|
|
44
|
-
})
|
|
45
|
-
.catch((err ) => {
|
|
46
|
-
handler.onError?.(err)
|
|
47
|
-
})
|
|
48
|
-
return true
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
class NockAgent extends undici.Dispatcher {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
constructor(options ) {
|
|
57
|
-
super()
|
|
58
|
-
|
|
59
|
-
this.agent = new undici.Agent({ factory: this.factory.bind(this) })
|
|
60
|
-
this.originalOptions = options
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
dispatch(options , handler ) {
|
|
64
|
-
return this.agent.dispatch(options, handler)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
factory(origin ) {
|
|
68
|
-
const mockOptions = { ...this.originalOptions, agent: this }
|
|
69
|
-
return new NockClient(origin, mockOptions)
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function activate() {
|
|
74
|
-
undici.setGlobalDispatcher(new NockAgent())
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function deactivate() {
|
|
78
|
-
undici.setGlobalDispatcher(new undici.Agent())
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export { activate, deactivate }
|