nock 15.0.0-beta.12 → 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
|
|
@@ -235,25 +231,6 @@ function activeMocks() {
|
|
|
235
231
|
function activate() {
|
|
236
232
|
if (!_isActive) {
|
|
237
233
|
builtinMock.activate()
|
|
238
|
-
|
|
239
|
-
if (!undiciMock) {
|
|
240
|
-
try {
|
|
241
|
-
undiciMock = _require('./interceptors/undici.js')
|
|
242
|
-
} catch (err ) {
|
|
243
|
-
if (
|
|
244
|
-
err.code !== 'MODULE_NOT_FOUND' &&
|
|
245
|
-
err.code !== 'ERR_MODULE_NOT_FOUND' &&
|
|
246
|
-
err.code !== 'ERR_REQUIRE_ESM'
|
|
247
|
-
) {
|
|
248
|
-
throw err
|
|
249
|
-
}
|
|
250
|
-
debug(
|
|
251
|
-
'Undici mocking is disabled because the undici module is not installed',
|
|
252
|
-
)
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
undiciMock?.activate()
|
|
257
234
|
_isActive = true
|
|
258
235
|
} else {
|
|
259
236
|
throw new Error('Nock already active')
|
|
@@ -263,7 +240,6 @@ function activate() {
|
|
|
263
240
|
function deactivate() {
|
|
264
241
|
if (_isActive) {
|
|
265
242
|
builtinMock.deactivate()
|
|
266
|
-
undiciMock?.deactivate()
|
|
267
243
|
_isActive = false
|
|
268
244
|
}
|
|
269
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 }
|