@depup/mswjs__interceptors 0.41.3-depup.0
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/ClientRequest/package.json +11 -0
- package/LICENSE.md +9 -0
- package/README.md +31 -0
- package/RemoteHttpInterceptor/package.json +11 -0
- package/WebSocket/package.json +12 -0
- package/XMLHttpRequest/package.json +12 -0
- package/changes.json +10 -0
- package/fetch/package.json +12 -0
- package/lib/browser/Interceptor-Deczogc8.d.cts +65 -0
- package/lib/browser/Interceptor-gqKgs-aF.d.mts +65 -0
- package/lib/browser/XMLHttpRequest-BACqefB-.cjs +761 -0
- package/lib/browser/XMLHttpRequest-BACqefB-.cjs.map +1 -0
- package/lib/browser/XMLHttpRequest-BvxZV0WU.mjs +756 -0
- package/lib/browser/XMLHttpRequest-BvxZV0WU.mjs.map +1 -0
- package/lib/browser/bufferUtils-BiiO6HZv.mjs +20 -0
- package/lib/browser/bufferUtils-BiiO6HZv.mjs.map +1 -0
- package/lib/browser/bufferUtils-Uc0eRItL.cjs +38 -0
- package/lib/browser/bufferUtils-Uc0eRItL.cjs.map +1 -0
- package/lib/browser/createRequestId-Cs4oXfa1.cjs +205 -0
- package/lib/browser/createRequestId-Cs4oXfa1.cjs.map +1 -0
- package/lib/browser/createRequestId-DQcIlohW.mjs +170 -0
- package/lib/browser/createRequestId-DQcIlohW.mjs.map +1 -0
- package/lib/browser/fetch-DdKEdDOR.mjs +248 -0
- package/lib/browser/fetch-DdKEdDOR.mjs.map +1 -0
- package/lib/browser/fetch-U3v3Y4ap.cjs +253 -0
- package/lib/browser/fetch-U3v3Y4ap.cjs.map +1 -0
- package/lib/browser/getRawRequest-BTaNLFr0.mjs +218 -0
- package/lib/browser/getRawRequest-BTaNLFr0.mjs.map +1 -0
- package/lib/browser/getRawRequest-zx8rUJL2.cjs +259 -0
- package/lib/browser/getRawRequest-zx8rUJL2.cjs.map +1 -0
- package/lib/browser/glossary-BdLS4k1H.d.cts +70 -0
- package/lib/browser/glossary-DYwOrogs.d.mts +70 -0
- package/lib/browser/handleRequest-CvX2G-Lz.cjs +189 -0
- package/lib/browser/handleRequest-CvX2G-Lz.cjs.map +1 -0
- package/lib/browser/handleRequest-D7kpTI5U.mjs +178 -0
- package/lib/browser/handleRequest-D7kpTI5U.mjs.map +1 -0
- package/lib/browser/hasConfigurableGlobal-BvCTG97d.cjs +45 -0
- package/lib/browser/hasConfigurableGlobal-BvCTG97d.cjs.map +1 -0
- package/lib/browser/hasConfigurableGlobal-npXitu1-.mjs +33 -0
- package/lib/browser/hasConfigurableGlobal-npXitu1-.mjs.map +1 -0
- package/lib/browser/index.cjs +70 -0
- package/lib/browser/index.cjs.map +1 -0
- package/lib/browser/index.d.cts +96 -0
- package/lib/browser/index.d.mts +96 -0
- package/lib/browser/index.mjs +56 -0
- package/lib/browser/index.mjs.map +1 -0
- package/lib/browser/interceptors/WebSocket/index.cjs +622 -0
- package/lib/browser/interceptors/WebSocket/index.cjs.map +1 -0
- package/lib/browser/interceptors/WebSocket/index.d.cts +277 -0
- package/lib/browser/interceptors/WebSocket/index.d.mts +277 -0
- package/lib/browser/interceptors/WebSocket/index.mjs +615 -0
- package/lib/browser/interceptors/WebSocket/index.mjs.map +1 -0
- package/lib/browser/interceptors/XMLHttpRequest/index.cjs +7 -0
- package/lib/browser/interceptors/XMLHttpRequest/index.d.cts +15 -0
- package/lib/browser/interceptors/XMLHttpRequest/index.d.mts +15 -0
- package/lib/browser/interceptors/XMLHttpRequest/index.mjs +7 -0
- package/lib/browser/interceptors/fetch/index.cjs +6 -0
- package/lib/browser/interceptors/fetch/index.d.cts +13 -0
- package/lib/browser/interceptors/fetch/index.d.mts +13 -0
- package/lib/browser/interceptors/fetch/index.mjs +6 -0
- package/lib/browser/presets/browser.cjs +17 -0
- package/lib/browser/presets/browser.cjs.map +1 -0
- package/lib/browser/presets/browser.d.cts +12 -0
- package/lib/browser/presets/browser.d.mts +14 -0
- package/lib/browser/presets/browser.mjs +17 -0
- package/lib/browser/presets/browser.mjs.map +1 -0
- package/lib/browser/resolveWebSocketUrl-6K6EgqsA.cjs +31 -0
- package/lib/browser/resolveWebSocketUrl-6K6EgqsA.cjs.map +1 -0
- package/lib/browser/resolveWebSocketUrl-C83-x9iE.mjs +25 -0
- package/lib/browser/resolveWebSocketUrl-C83-x9iE.mjs.map +1 -0
- package/lib/node/BatchInterceptor-3LnAnLTx.cjs +49 -0
- package/lib/node/BatchInterceptor-3LnAnLTx.cjs.map +1 -0
- package/lib/node/BatchInterceptor-D7mXzHcQ.d.mts +26 -0
- package/lib/node/BatchInterceptor-DFaBPilf.mjs +44 -0
- package/lib/node/BatchInterceptor-DFaBPilf.mjs.map +1 -0
- package/lib/node/BatchInterceptor-D_YqR8qU.d.cts +26 -0
- package/lib/node/ClientRequest-2rDe54Ui.cjs +1043 -0
- package/lib/node/ClientRequest-2rDe54Ui.cjs.map +1 -0
- package/lib/node/ClientRequest-Ca8Qykuv.mjs +1034 -0
- package/lib/node/ClientRequest-Ca8Qykuv.mjs.map +1 -0
- package/lib/node/Interceptor-DEazpLJd.d.mts +133 -0
- package/lib/node/Interceptor-DJ2akVWI.d.cts +133 -0
- package/lib/node/RemoteHttpInterceptor.cjs +154 -0
- package/lib/node/RemoteHttpInterceptor.cjs.map +1 -0
- package/lib/node/RemoteHttpInterceptor.d.cts +39 -0
- package/lib/node/RemoteHttpInterceptor.d.mts +39 -0
- package/lib/node/RemoteHttpInterceptor.mjs +152 -0
- package/lib/node/RemoteHttpInterceptor.mjs.map +1 -0
- package/lib/node/XMLHttpRequest-B7kJdYYI.cjs +763 -0
- package/lib/node/XMLHttpRequest-B7kJdYYI.cjs.map +1 -0
- package/lib/node/XMLHttpRequest-C8dIZpds.mjs +757 -0
- package/lib/node/XMLHttpRequest-C8dIZpds.mjs.map +1 -0
- package/lib/node/bufferUtils-DiCTqG-7.cjs +38 -0
- package/lib/node/bufferUtils-DiCTqG-7.cjs.map +1 -0
- package/lib/node/bufferUtils-_8XfKIfX.mjs +20 -0
- package/lib/node/bufferUtils-_8XfKIfX.mjs.map +1 -0
- package/lib/node/chunk-CbDLau6x.cjs +34 -0
- package/lib/node/fetch-BmXpK10r.cjs +272 -0
- package/lib/node/fetch-BmXpK10r.cjs.map +1 -0
- package/lib/node/fetch-G1DVwDKG.mjs +265 -0
- package/lib/node/fetch-G1DVwDKG.mjs.map +1 -0
- package/lib/node/fetchUtils-BaY5iWXw.cjs +419 -0
- package/lib/node/fetchUtils-BaY5iWXw.cjs.map +1 -0
- package/lib/node/fetchUtils-CoU35g3M.mjs +359 -0
- package/lib/node/fetchUtils-CoU35g3M.mjs.map +1 -0
- package/lib/node/getRawRequest-BavnMWh_.cjs +36 -0
- package/lib/node/getRawRequest-BavnMWh_.cjs.map +1 -0
- package/lib/node/getRawRequest-DnwmXyOW.mjs +24 -0
- package/lib/node/getRawRequest-DnwmXyOW.mjs.map +1 -0
- package/lib/node/glossary-BLKRyLBd.cjs +12 -0
- package/lib/node/glossary-BLKRyLBd.cjs.map +1 -0
- package/lib/node/glossary-glQBRnVD.mjs +6 -0
- package/lib/node/glossary-glQBRnVD.mjs.map +1 -0
- package/lib/node/handleRequest-Bb7Y-XLw.cjs +220 -0
- package/lib/node/handleRequest-Bb7Y-XLw.cjs.map +1 -0
- package/lib/node/handleRequest-Y97UwBbF.mjs +190 -0
- package/lib/node/handleRequest-Y97UwBbF.mjs.map +1 -0
- package/lib/node/hasConfigurableGlobal-C97fWuaA.cjs +26 -0
- package/lib/node/hasConfigurableGlobal-C97fWuaA.cjs.map +1 -0
- package/lib/node/hasConfigurableGlobal-DBJA0vjm.mjs +20 -0
- package/lib/node/hasConfigurableGlobal-DBJA0vjm.mjs.map +1 -0
- package/lib/node/index-BMbJ8FXL.d.cts +113 -0
- package/lib/node/index-C0YAQ36w.d.mts +113 -0
- package/lib/node/index.cjs +54 -0
- package/lib/node/index.cjs.map +1 -0
- package/lib/node/index.d.cts +75 -0
- package/lib/node/index.d.mts +75 -0
- package/lib/node/index.mjs +40 -0
- package/lib/node/index.mjs.map +1 -0
- package/lib/node/interceptors/ClientRequest/index.cjs +6 -0
- package/lib/node/interceptors/ClientRequest/index.d.cts +2 -0
- package/lib/node/interceptors/ClientRequest/index.d.mts +3 -0
- package/lib/node/interceptors/ClientRequest/index.mjs +6 -0
- package/lib/node/interceptors/XMLHttpRequest/index.cjs +6 -0
- package/lib/node/interceptors/XMLHttpRequest/index.d.cts +14 -0
- package/lib/node/interceptors/XMLHttpRequest/index.d.mts +14 -0
- package/lib/node/interceptors/XMLHttpRequest/index.mjs +6 -0
- package/lib/node/interceptors/fetch/index.cjs +5 -0
- package/lib/node/interceptors/fetch/index.d.cts +12 -0
- package/lib/node/interceptors/fetch/index.d.mts +12 -0
- package/lib/node/interceptors/fetch/index.mjs +5 -0
- package/lib/node/node-DwCc6iuP.mjs +27 -0
- package/lib/node/node-DwCc6iuP.mjs.map +1 -0
- package/lib/node/node-dKdAf3tC.cjs +39 -0
- package/lib/node/node-dKdAf3tC.cjs.map +1 -0
- package/lib/node/presets/node.cjs +22 -0
- package/lib/node/presets/node.cjs.map +1 -0
- package/lib/node/presets/node.d.cts +13 -0
- package/lib/node/presets/node.d.mts +15 -0
- package/lib/node/presets/node.mjs +22 -0
- package/lib/node/presets/node.mjs.map +1 -0
- package/lib/node/utils/node/index.cjs +4 -0
- package/lib/node/utils/node/index.d.cts +16 -0
- package/lib/node/utils/node/index.d.mts +16 -0
- package/lib/node/utils/node/index.mjs +3 -0
- package/package.json +204 -0
- package/presets/browser/package.json +5 -0
- package/presets/node/package.json +11 -0
- package/src/BatchInterceptor.test.ts +255 -0
- package/src/BatchInterceptor.ts +95 -0
- package/src/Interceptor.test.ts +205 -0
- package/src/Interceptor.ts +249 -0
- package/src/InterceptorError.ts +7 -0
- package/src/RemoteHttpInterceptor.ts +251 -0
- package/src/RequestController.test.ts +104 -0
- package/src/RequestController.ts +109 -0
- package/src/createRequestId.test.ts +7 -0
- package/src/createRequestId.ts +9 -0
- package/src/getRawRequest.ts +21 -0
- package/src/glossary.ts +37 -0
- package/src/index.ts +15 -0
- package/src/interceptors/ClientRequest/MockHttpSocket.ts +724 -0
- package/src/interceptors/ClientRequest/agents.ts +110 -0
- package/src/interceptors/ClientRequest/index.test.ts +75 -0
- package/src/interceptors/ClientRequest/index.ts +193 -0
- package/src/interceptors/ClientRequest/utils/getIncomingMessageBody.test.ts +54 -0
- package/src/interceptors/ClientRequest/utils/getIncomingMessageBody.ts +45 -0
- package/src/interceptors/ClientRequest/utils/normalizeClientRequestArgs.test.ts +427 -0
- package/src/interceptors/ClientRequest/utils/normalizeClientRequestArgs.ts +268 -0
- package/src/interceptors/ClientRequest/utils/parserUtils.ts +48 -0
- package/src/interceptors/ClientRequest/utils/recordRawHeaders.test.ts +258 -0
- package/src/interceptors/ClientRequest/utils/recordRawHeaders.ts +262 -0
- package/src/interceptors/Socket/MockSocket.test.ts +264 -0
- package/src/interceptors/Socket/MockSocket.ts +58 -0
- package/src/interceptors/Socket/utils/baseUrlFromConnectionOptions.ts +26 -0
- package/src/interceptors/Socket/utils/normalizeSocketWriteArgs.test.ts +52 -0
- package/src/interceptors/Socket/utils/normalizeSocketWriteArgs.ts +33 -0
- package/src/interceptors/WebSocket/WebSocketClassTransport.ts +116 -0
- package/src/interceptors/WebSocket/WebSocketClientConnection.ts +152 -0
- package/src/interceptors/WebSocket/WebSocketOverride.ts +252 -0
- package/src/interceptors/WebSocket/WebSocketServerConnection.ts +420 -0
- package/src/interceptors/WebSocket/WebSocketTransport.ts +39 -0
- package/src/interceptors/WebSocket/index.ts +191 -0
- package/src/interceptors/WebSocket/utils/bindEvent.test.ts +27 -0
- package/src/interceptors/WebSocket/utils/bindEvent.ts +21 -0
- package/src/interceptors/WebSocket/utils/events.test.ts +101 -0
- package/src/interceptors/WebSocket/utils/events.ts +94 -0
- package/src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts +746 -0
- package/src/interceptors/XMLHttpRequest/XMLHttpRequestProxy.ts +121 -0
- package/src/interceptors/XMLHttpRequest/index.ts +61 -0
- package/src/interceptors/XMLHttpRequest/polyfills/EventPolyfill.ts +51 -0
- package/src/interceptors/XMLHttpRequest/polyfills/ProgressEventPolyfill.ts +17 -0
- package/src/interceptors/XMLHttpRequest/utils/concatArrayBuffer.ts +12 -0
- package/src/interceptors/XMLHttpRequest/utils/concateArrayBuffer.test.ts +12 -0
- package/src/interceptors/XMLHttpRequest/utils/createEvent.test.ts +26 -0
- package/src/interceptors/XMLHttpRequest/utils/createEvent.ts +41 -0
- package/src/interceptors/XMLHttpRequest/utils/createResponse.ts +49 -0
- package/src/interceptors/XMLHttpRequest/utils/getBodyByteLength.test.ts +164 -0
- package/src/interceptors/XMLHttpRequest/utils/getBodyByteLength.ts +16 -0
- package/src/interceptors/XMLHttpRequest/utils/isDomParserSupportedType.ts +14 -0
- package/src/interceptors/fetch/index.ts +214 -0
- package/src/interceptors/fetch/utils/brotli-decompress.browser.ts +14 -0
- package/src/interceptors/fetch/utils/brotli-decompress.ts +31 -0
- package/src/interceptors/fetch/utils/createNetworkError.ts +5 -0
- package/src/interceptors/fetch/utils/decompression.ts +85 -0
- package/src/interceptors/fetch/utils/followRedirect.ts +114 -0
- package/src/presets/browser.ts +11 -0
- package/src/presets/node.ts +13 -0
- package/src/utils/bufferUtils.test.ts +21 -0
- package/src/utils/bufferUtils.ts +22 -0
- package/src/utils/canParseUrl.ts +13 -0
- package/src/utils/cloneObject.test.ts +94 -0
- package/src/utils/cloneObject.ts +36 -0
- package/src/utils/createProxy.test.ts +164 -0
- package/src/utils/createProxy.ts +104 -0
- package/src/utils/emitAsync.ts +25 -0
- package/src/utils/fetchUtils.ts +119 -0
- package/src/utils/findPropertySource.test.ts +27 -0
- package/src/utils/findPropertySource.ts +20 -0
- package/src/utils/getCleanUrl.test.ts +32 -0
- package/src/utils/getCleanUrl.ts +6 -0
- package/src/utils/getUrlByRequestOptions.test.ts +163 -0
- package/src/utils/getUrlByRequestOptions.ts +152 -0
- package/src/utils/getValueBySymbol.test.ts +14 -0
- package/src/utils/getValueBySymbol.ts +19 -0
- package/src/utils/handleRequest.ts +205 -0
- package/src/utils/hasConfigurableGlobal.test.ts +83 -0
- package/src/utils/hasConfigurableGlobal.ts +34 -0
- package/src/utils/isNodeLikeError.ts +13 -0
- package/src/utils/isObject.test.ts +21 -0
- package/src/utils/isObject.ts +8 -0
- package/src/utils/isPropertyAccessible.ts +19 -0
- package/src/utils/nextTick.ts +11 -0
- package/src/utils/node/index.ts +39 -0
- package/src/utils/parseJson.test.ts +10 -0
- package/src/utils/parseJson.ts +12 -0
- package/src/utils/resolveWebSocketUrl.ts +45 -0
- package/src/utils/responseUtils.ts +59 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Socket } from 'node:net'
|
|
2
|
+
import { HTTPParser } from '_http_common'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @see https://github.com/nodejs/node/blob/f3adc11e37b8bfaaa026ea85c1cf22e3a0e29ae9/lib/_http_common.js#L180
|
|
6
|
+
*/
|
|
7
|
+
export function freeParser(parser: HTTPParser<any>, socket?: Socket): void {
|
|
8
|
+
if (parser._consumed) {
|
|
9
|
+
parser.unconsume()
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
parser._headers = []
|
|
13
|
+
parser._url = ''
|
|
14
|
+
parser.socket = null
|
|
15
|
+
parser.incoming = null
|
|
16
|
+
parser.outgoing = null
|
|
17
|
+
parser.maxHeaderPairs = 2000
|
|
18
|
+
parser._consumed = false
|
|
19
|
+
parser.onIncoming = null
|
|
20
|
+
|
|
21
|
+
parser[HTTPParser.kOnHeaders] = null
|
|
22
|
+
parser[HTTPParser.kOnHeadersComplete] = null
|
|
23
|
+
parser[HTTPParser.kOnMessageBegin] = null
|
|
24
|
+
parser[HTTPParser.kOnMessageComplete] = null
|
|
25
|
+
parser[HTTPParser.kOnBody] = null
|
|
26
|
+
parser[HTTPParser.kOnExecute] = null
|
|
27
|
+
parser[HTTPParser.kOnTimeout] = null
|
|
28
|
+
|
|
29
|
+
parser.remove()
|
|
30
|
+
parser.free()
|
|
31
|
+
|
|
32
|
+
if (socket) {
|
|
33
|
+
/**
|
|
34
|
+
* @note Unassigning the socket's parser will fail this assertion
|
|
35
|
+
* if there's still some data being processed on the socket:
|
|
36
|
+
* @see https://github.com/nodejs/node/blob/4e1f39b678b37017ac9baa0971e3aeecd3b67b51/lib/_http_client.js#L613
|
|
37
|
+
*/
|
|
38
|
+
if (socket.destroyed) {
|
|
39
|
+
// @ts-expect-error Node.js internals.
|
|
40
|
+
socket.parser = null
|
|
41
|
+
} else {
|
|
42
|
+
socket.once('end', () => {
|
|
43
|
+
// @ts-expect-error Node.js internals.
|
|
44
|
+
socket.parser = null
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
// @vitest-environment node
|
|
2
|
+
import { it, expect, afterEach } from 'vitest'
|
|
3
|
+
import {
|
|
4
|
+
recordRawFetchHeaders,
|
|
5
|
+
restoreHeadersPrototype,
|
|
6
|
+
getRawFetchHeaders,
|
|
7
|
+
} from './recordRawHeaders'
|
|
8
|
+
|
|
9
|
+
const url = 'http://localhost'
|
|
10
|
+
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
restoreHeadersPrototype()
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('returns an empty list if no headers were set', () => {
|
|
16
|
+
expect(getRawFetchHeaders(new Headers())).toEqual([])
|
|
17
|
+
expect(getRawFetchHeaders(new Headers(undefined))).toEqual([])
|
|
18
|
+
expect(getRawFetchHeaders(new Headers({}))).toEqual([])
|
|
19
|
+
expect(getRawFetchHeaders(new Headers([]))).toEqual([])
|
|
20
|
+
expect(getRawFetchHeaders(new Request(url).headers)).toEqual([])
|
|
21
|
+
expect(getRawFetchHeaders(new Response().headers)).toEqual([])
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('records raw headers (Headers / object as init)', () => {
|
|
25
|
+
recordRawFetchHeaders()
|
|
26
|
+
const headers = new Headers({
|
|
27
|
+
'Content-Type': 'application/json',
|
|
28
|
+
'X-My-Header': '1',
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
expect(getRawFetchHeaders(headers)).toEqual([
|
|
32
|
+
['Content-Type', 'application/json'],
|
|
33
|
+
['X-My-Header', '1'],
|
|
34
|
+
])
|
|
35
|
+
expect(Object.fromEntries(headers)).toEqual({
|
|
36
|
+
'content-type': 'application/json',
|
|
37
|
+
'x-my-header': '1',
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('records raw headers (Headers / array as init)', () => {
|
|
42
|
+
recordRawFetchHeaders()
|
|
43
|
+
const headers = new Headers([['X-My-Header', '1']])
|
|
44
|
+
|
|
45
|
+
expect(getRawFetchHeaders(headers)).toEqual([['X-My-Header', '1']])
|
|
46
|
+
expect(Object.fromEntries(headers)).toEqual({
|
|
47
|
+
'x-my-header': '1',
|
|
48
|
+
})
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('records raw headers (Headers / Headers as init', () => {
|
|
52
|
+
recordRawFetchHeaders()
|
|
53
|
+
const headers = new Headers([['X-My-Header', '1']])
|
|
54
|
+
|
|
55
|
+
expect(getRawFetchHeaders(new Headers(headers))).toEqual([
|
|
56
|
+
['X-My-Header', '1'],
|
|
57
|
+
])
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('records raw headers added via ".set()"', () => {
|
|
61
|
+
recordRawFetchHeaders()
|
|
62
|
+
const headers = new Headers([['X-My-Header', '1']])
|
|
63
|
+
headers.set('X-Another-Header', '2')
|
|
64
|
+
|
|
65
|
+
expect(getRawFetchHeaders(headers)).toEqual([
|
|
66
|
+
['X-My-Header', '1'],
|
|
67
|
+
['X-Another-Header', '2'],
|
|
68
|
+
])
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('records raw headers added via ".append()"', () => {
|
|
72
|
+
recordRawFetchHeaders()
|
|
73
|
+
const headers = new Headers([['X-My-Header', '1']])
|
|
74
|
+
headers.append('X-My-Header', '2')
|
|
75
|
+
|
|
76
|
+
expect(getRawFetchHeaders(headers)).toEqual([
|
|
77
|
+
['X-My-Header', '1'],
|
|
78
|
+
['X-My-Header', '2'],
|
|
79
|
+
])
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('deletes the header when called ".delete()"', () => {
|
|
83
|
+
const headers = new Headers([['X-My-Header', '1']])
|
|
84
|
+
headers.delete('X-My-Header')
|
|
85
|
+
|
|
86
|
+
expect(getRawFetchHeaders(headers)).toEqual([])
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('records raw headers (Request / object as init)', () => {
|
|
90
|
+
recordRawFetchHeaders()
|
|
91
|
+
const request = new Request(url, {
|
|
92
|
+
headers: {
|
|
93
|
+
'Content-Type': 'application/json',
|
|
94
|
+
'X-My-Header': '1',
|
|
95
|
+
},
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
expect(getRawFetchHeaders(request.headers)).toEqual([
|
|
99
|
+
['Content-Type', 'application/json'],
|
|
100
|
+
['X-My-Header', '1'],
|
|
101
|
+
])
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
it('records raw headers (Request / array as init)', () => {
|
|
105
|
+
recordRawFetchHeaders()
|
|
106
|
+
const request = new Request(url, {
|
|
107
|
+
headers: [['X-My-Header', '1']],
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
expect(getRawFetchHeaders(request.headers)).toEqual([['X-My-Header', '1']])
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
it('records raw headers (Request / Headers as init)', () => {
|
|
114
|
+
recordRawFetchHeaders()
|
|
115
|
+
const headers = new Headers([['X-My-Header', '1']])
|
|
116
|
+
const request = new Request(url, { headers })
|
|
117
|
+
|
|
118
|
+
expect(getRawFetchHeaders(request.headers)).toEqual([['X-My-Header', '1']])
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
it('records raw headers (Request / Request as init)', () => {
|
|
122
|
+
recordRawFetchHeaders()
|
|
123
|
+
const init = new Request(url, { headers: [['X-My-Header', '1']] })
|
|
124
|
+
const request = new Request(init)
|
|
125
|
+
|
|
126
|
+
expect(getRawFetchHeaders(request.headers)).toEqual([['X-My-Header', '1']])
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
it('preserves headers instanceof (Request / Request as init)', () => {
|
|
130
|
+
recordRawFetchHeaders()
|
|
131
|
+
const init = new Request(url, { headers: [['X-My-Header', '1']] })
|
|
132
|
+
new Request(init)
|
|
133
|
+
expect(init.headers).toBeInstanceOf(Headers)
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
it('preserves headers instanceof (Request / Request with Headers as init)', () => {
|
|
137
|
+
recordRawFetchHeaders()
|
|
138
|
+
const headers = new Headers([['X-My-Header', '1']])
|
|
139
|
+
const init = new Request(url, { headers })
|
|
140
|
+
new Request(init)
|
|
141
|
+
expect(init.headers).toBeInstanceOf(Headers)
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
it('preserves headers instanceof (Response / Response with Headers as init)', () => {
|
|
145
|
+
recordRawFetchHeaders()
|
|
146
|
+
const init = { headers: new Headers([['X-My-Header', '1']]) }
|
|
147
|
+
new Response(url, init)
|
|
148
|
+
expect(init.headers).toBeInstanceOf(Headers)
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
it('records raw headers (Request / Request+Headers as init)', () => {
|
|
152
|
+
recordRawFetchHeaders()
|
|
153
|
+
const init = new Request(url, { headers: [['X-My-Header', '1']] })
|
|
154
|
+
expect(getRawFetchHeaders(init.headers)).toEqual([['X-My-Header', '1']])
|
|
155
|
+
|
|
156
|
+
const request = new Request(init, {
|
|
157
|
+
headers: new Headers([['X-Another-Header', '2']]),
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
// Must merge the raw headers from the request init
|
|
161
|
+
// and the request instance itself.
|
|
162
|
+
expect(getRawFetchHeaders(request.headers)).toEqual([
|
|
163
|
+
['X-My-Header', '1'],
|
|
164
|
+
['X-Another-Header', '2'],
|
|
165
|
+
])
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
it('records raw headers (Response / object as init)', () => {
|
|
169
|
+
recordRawFetchHeaders()
|
|
170
|
+
const response = new Response(null, {
|
|
171
|
+
headers: {
|
|
172
|
+
'Content-Type': 'application/json',
|
|
173
|
+
'X-My-Header': '1',
|
|
174
|
+
},
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
expect(getRawFetchHeaders(response.headers)).toEqual([
|
|
178
|
+
['Content-Type', 'application/json'],
|
|
179
|
+
['X-My-Header', '1'],
|
|
180
|
+
])
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
it('records raw headers (Response / array as init)', () => {
|
|
184
|
+
recordRawFetchHeaders()
|
|
185
|
+
const response = new Response(null, {
|
|
186
|
+
headers: [['X-My-Header', '1']],
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
expect(getRawFetchHeaders(response.headers)).toEqual([['X-My-Header', '1']])
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
it('records raw headers (Response / Headers as init)', () => {
|
|
193
|
+
recordRawFetchHeaders()
|
|
194
|
+
const headers = new Headers([['X-My-Header', '1']])
|
|
195
|
+
const response = new Response(null, { headers })
|
|
196
|
+
|
|
197
|
+
expect(getRawFetchHeaders(response.headers)).toEqual([['X-My-Header', '1']])
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
it('stops recording once the patches are restored', () => {
|
|
201
|
+
restoreHeadersPrototype()
|
|
202
|
+
|
|
203
|
+
const headers = new Headers({ 'X-My-Header': '1' })
|
|
204
|
+
// Must return the normalized headers (no access to raw headers).
|
|
205
|
+
expect(getRawFetchHeaders(headers)).toEqual([['x-my-header', '1']])
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
it('overrides an existing header when calling ".set()"', () => {
|
|
209
|
+
recordRawFetchHeaders()
|
|
210
|
+
const headers = new Headers([['a', '1']])
|
|
211
|
+
expect(headers.get('a')).toBe('1')
|
|
212
|
+
|
|
213
|
+
headers.set('a', '2')
|
|
214
|
+
expect(headers.get('a')).toBe('2')
|
|
215
|
+
|
|
216
|
+
const headersClone = new Headers(headers)
|
|
217
|
+
expect(headersClone.get('a')).toBe('2')
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
it('overrides an existing multi-value header when calling ".set()"', () => {
|
|
221
|
+
recordRawFetchHeaders()
|
|
222
|
+
const headers = new Headers([
|
|
223
|
+
['a', '1'],
|
|
224
|
+
['a', '2'],
|
|
225
|
+
])
|
|
226
|
+
expect(headers.get('a')).toBe('1, 2')
|
|
227
|
+
|
|
228
|
+
headers.set('a', '3')
|
|
229
|
+
expect(headers.get('a')).toBe('3')
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
it('does not throw on using Headers before recording', () => {
|
|
233
|
+
// If the consumer constructs a Headers instance before
|
|
234
|
+
// the interceptor is enabled, it will have no internal symbol set.
|
|
235
|
+
const headers = new Headers()
|
|
236
|
+
recordRawFetchHeaders()
|
|
237
|
+
const request = new Request(url, { headers })
|
|
238
|
+
|
|
239
|
+
expect(getRawFetchHeaders(request.headers)).toEqual([])
|
|
240
|
+
|
|
241
|
+
request.headers.set('X-My-Header', '1')
|
|
242
|
+
expect(getRawFetchHeaders(request.headers)).toEqual([['X-My-Header', '1']])
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* @see https://github.com/mswjs/interceptors/issues/681
|
|
247
|
+
*/
|
|
248
|
+
it('isolates headers between different headers instances', async () => {
|
|
249
|
+
recordRawFetchHeaders()
|
|
250
|
+
const original = new Headers()
|
|
251
|
+
const firstClone = new Headers(original)
|
|
252
|
+
firstClone.set('Content-Type', 'application/json')
|
|
253
|
+
const secondClone = new Headers(original)
|
|
254
|
+
|
|
255
|
+
expect(original.get('Content-Type')).toBeNull()
|
|
256
|
+
expect(firstClone.get('Content-Type')).toBe('application/json')
|
|
257
|
+
expect(secondClone.get('Content-Type')).toBeNull()
|
|
258
|
+
})
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
type HeaderTuple = [string, string]
|
|
2
|
+
type RawHeaders = Array<HeaderTuple>
|
|
3
|
+
type SetHeaderBehavior = 'set' | 'append'
|
|
4
|
+
|
|
5
|
+
const kRawHeaders = Symbol('kRawHeaders')
|
|
6
|
+
const kRestorePatches = Symbol('kRestorePatches')
|
|
7
|
+
|
|
8
|
+
function recordRawHeader(
|
|
9
|
+
headers: Headers,
|
|
10
|
+
args: HeaderTuple,
|
|
11
|
+
behavior: SetHeaderBehavior
|
|
12
|
+
) {
|
|
13
|
+
ensureRawHeadersSymbol(headers, [])
|
|
14
|
+
const rawHeaders = Reflect.get(headers, kRawHeaders) as RawHeaders
|
|
15
|
+
|
|
16
|
+
if (behavior === 'set') {
|
|
17
|
+
// When recording a set header, ensure we remove any matching existing headers.
|
|
18
|
+
for (let index = rawHeaders.length - 1; index >= 0; index--) {
|
|
19
|
+
if (rawHeaders[index][0].toLowerCase() === args[0].toLowerCase()) {
|
|
20
|
+
rawHeaders.splice(index, 1)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
rawHeaders.push(args)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Define the raw headers symbol on the given `Headers` instance.
|
|
30
|
+
* If the symbol already exists, this function does nothing.
|
|
31
|
+
*/
|
|
32
|
+
function ensureRawHeadersSymbol(
|
|
33
|
+
headers: Headers,
|
|
34
|
+
rawHeaders: RawHeaders
|
|
35
|
+
): void {
|
|
36
|
+
if (Reflect.has(headers, kRawHeaders)) {
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
defineRawHeadersSymbol(headers, rawHeaders)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Define the raw headers symbol on the given `Headers` instance.
|
|
45
|
+
* If the symbol already exists, it gets overridden.
|
|
46
|
+
*/
|
|
47
|
+
function defineRawHeadersSymbol(headers: Headers, rawHeaders: RawHeaders) {
|
|
48
|
+
Object.defineProperty(headers, kRawHeaders, {
|
|
49
|
+
value: rawHeaders,
|
|
50
|
+
enumerable: false,
|
|
51
|
+
// Mark the symbol as configurable so its value can be overridden.
|
|
52
|
+
// Overrides happen when merging raw headers from multiple sources.
|
|
53
|
+
// E.g. new Request(new Request(url, { headers }), { headers })
|
|
54
|
+
configurable: true,
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Patch the global `Headers` class to store raw headers.
|
|
60
|
+
* This is for compatibility with `IncomingMessage.prototype.rawHeaders`.
|
|
61
|
+
*
|
|
62
|
+
* @note Node.js has their own raw headers symbol but it
|
|
63
|
+
* only records the first header name in case of multi-value headers.
|
|
64
|
+
* Any other headers are normalized before comparing. This makes it
|
|
65
|
+
* incompatible with the `rawHeaders` format.
|
|
66
|
+
*
|
|
67
|
+
* let h = new Headers()
|
|
68
|
+
* h.append('X-Custom', 'one')
|
|
69
|
+
* h.append('x-custom', 'two')
|
|
70
|
+
* h[Symbol('headers map')] // Map { 'X-Custom' => 'one, two' }
|
|
71
|
+
*/
|
|
72
|
+
export function recordRawFetchHeaders() {
|
|
73
|
+
// Prevent patching the Headers prototype multiple times.
|
|
74
|
+
if (Reflect.get(Headers, kRestorePatches)) {
|
|
75
|
+
return Reflect.get(Headers, kRestorePatches)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const {
|
|
79
|
+
Headers: OriginalHeaders,
|
|
80
|
+
Request: OriginalRequest,
|
|
81
|
+
Response: OriginalResponse,
|
|
82
|
+
} = globalThis
|
|
83
|
+
const { set, append, delete: headersDeleteMethod } = Headers.prototype
|
|
84
|
+
|
|
85
|
+
Object.defineProperty(Headers, kRestorePatches, {
|
|
86
|
+
value: () => {
|
|
87
|
+
Headers.prototype.set = set
|
|
88
|
+
Headers.prototype.append = append
|
|
89
|
+
Headers.prototype.delete = headersDeleteMethod
|
|
90
|
+
globalThis.Headers = OriginalHeaders
|
|
91
|
+
|
|
92
|
+
globalThis.Request = OriginalRequest
|
|
93
|
+
globalThis.Response = OriginalResponse
|
|
94
|
+
|
|
95
|
+
Reflect.deleteProperty(Headers, kRestorePatches)
|
|
96
|
+
},
|
|
97
|
+
enumerable: false,
|
|
98
|
+
/**
|
|
99
|
+
* @note Mark this property as configurable
|
|
100
|
+
* so we can delete it using `Reflect.delete` during cleanup.
|
|
101
|
+
*/
|
|
102
|
+
configurable: true,
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
Object.defineProperty(globalThis, 'Headers', {
|
|
106
|
+
enumerable: true,
|
|
107
|
+
writable: true,
|
|
108
|
+
value: new Proxy(Headers, {
|
|
109
|
+
construct(target, args, newTarget) {
|
|
110
|
+
const headersInit = args[0] || []
|
|
111
|
+
|
|
112
|
+
if (
|
|
113
|
+
headersInit instanceof Headers &&
|
|
114
|
+
Reflect.has(headersInit, kRawHeaders)
|
|
115
|
+
) {
|
|
116
|
+
const headers = Reflect.construct(
|
|
117
|
+
target,
|
|
118
|
+
[Reflect.get(headersInit, kRawHeaders)],
|
|
119
|
+
newTarget
|
|
120
|
+
)
|
|
121
|
+
ensureRawHeadersSymbol(headers, [
|
|
122
|
+
/**
|
|
123
|
+
* @note Spread the retrieved headers to clone them.
|
|
124
|
+
* This prevents multiple Headers instances from pointing
|
|
125
|
+
* at the same internal "rawHeaders" array.
|
|
126
|
+
*/
|
|
127
|
+
...Reflect.get(headersInit, kRawHeaders),
|
|
128
|
+
])
|
|
129
|
+
return headers
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const headers = Reflect.construct(target, args, newTarget)
|
|
133
|
+
|
|
134
|
+
// Request/Response constructors will set the symbol
|
|
135
|
+
// upon creating a new instance, using the raw developer
|
|
136
|
+
// input as the raw headers. Skip the symbol altogether
|
|
137
|
+
// in those cases because the input to Headers will be normalized.
|
|
138
|
+
if (!Reflect.has(headers, kRawHeaders)) {
|
|
139
|
+
const rawHeadersInit = Array.isArray(headersInit)
|
|
140
|
+
? headersInit
|
|
141
|
+
: Object.entries(headersInit)
|
|
142
|
+
ensureRawHeadersSymbol(headers, rawHeadersInit)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return headers
|
|
146
|
+
},
|
|
147
|
+
}),
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
Headers.prototype.set = new Proxy(Headers.prototype.set, {
|
|
151
|
+
apply(target, thisArg, args: HeaderTuple) {
|
|
152
|
+
recordRawHeader(thisArg, args, 'set')
|
|
153
|
+
return Reflect.apply(target, thisArg, args)
|
|
154
|
+
},
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
Headers.prototype.append = new Proxy(Headers.prototype.append, {
|
|
158
|
+
apply(target, thisArg, args: HeaderTuple) {
|
|
159
|
+
recordRawHeader(thisArg, args, 'append')
|
|
160
|
+
return Reflect.apply(target, thisArg, args)
|
|
161
|
+
},
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
Headers.prototype.delete = new Proxy(Headers.prototype.delete, {
|
|
165
|
+
apply(target, thisArg, args: [string]) {
|
|
166
|
+
const rawHeaders = Reflect.get(thisArg, kRawHeaders) as RawHeaders
|
|
167
|
+
|
|
168
|
+
if (rawHeaders) {
|
|
169
|
+
for (let index = rawHeaders.length - 1; index >= 0; index--) {
|
|
170
|
+
if (rawHeaders[index][0].toLowerCase() === args[0].toLowerCase()) {
|
|
171
|
+
rawHeaders.splice(index, 1)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return Reflect.apply(target, thisArg, args)
|
|
177
|
+
},
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
Object.defineProperty(globalThis, 'Request', {
|
|
181
|
+
enumerable: true,
|
|
182
|
+
writable: true,
|
|
183
|
+
value: new Proxy(Request, {
|
|
184
|
+
construct(target, args, newTarget) {
|
|
185
|
+
const request = Reflect.construct(target, args, newTarget)
|
|
186
|
+
const inferredRawHeaders: RawHeaders = []
|
|
187
|
+
|
|
188
|
+
// Infer raw headers from a `Request` instance used as init.
|
|
189
|
+
if (typeof args[0] === 'object' && args[0].headers != null) {
|
|
190
|
+
inferredRawHeaders.push(...inferRawHeaders(args[0].headers))
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Infer raw headers from the "headers" init argument.
|
|
194
|
+
if (typeof args[1] === 'object' && args[1].headers != null) {
|
|
195
|
+
inferredRawHeaders.push(...inferRawHeaders(args[1].headers))
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (inferredRawHeaders.length > 0) {
|
|
199
|
+
ensureRawHeadersSymbol(request.headers, inferredRawHeaders)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return request
|
|
203
|
+
},
|
|
204
|
+
}),
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
Object.defineProperty(globalThis, 'Response', {
|
|
208
|
+
enumerable: true,
|
|
209
|
+
writable: true,
|
|
210
|
+
value: new Proxy(Response, {
|
|
211
|
+
construct(target, args, newTarget) {
|
|
212
|
+
const response = Reflect.construct(target, args, newTarget)
|
|
213
|
+
|
|
214
|
+
if (typeof args[1] === 'object' && args[1].headers != null) {
|
|
215
|
+
ensureRawHeadersSymbol(
|
|
216
|
+
response.headers,
|
|
217
|
+
inferRawHeaders(args[1].headers)
|
|
218
|
+
)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return response
|
|
222
|
+
},
|
|
223
|
+
}),
|
|
224
|
+
})
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export function restoreHeadersPrototype() {
|
|
228
|
+
if (!Reflect.get(Headers, kRestorePatches)) {
|
|
229
|
+
return
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
Reflect.get(Headers, kRestorePatches)()
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export function getRawFetchHeaders(headers: Headers): RawHeaders {
|
|
236
|
+
// If the raw headers recording failed for some reason,
|
|
237
|
+
// use the normalized header entries instead.
|
|
238
|
+
if (!Reflect.has(headers, kRawHeaders)) {
|
|
239
|
+
return Array.from(headers.entries())
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const rawHeaders = Reflect.get(headers, kRawHeaders) as RawHeaders
|
|
243
|
+
return rawHeaders.length > 0 ? rawHeaders : Array.from(headers.entries())
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Infers the raw headers from the given `HeadersInit` provided
|
|
248
|
+
* to the Request/Response constructor.
|
|
249
|
+
*
|
|
250
|
+
* If the `init.headers` is a Headers instance, use it directly.
|
|
251
|
+
* That means the headers were created standalone and already have
|
|
252
|
+
* the raw headers stored.
|
|
253
|
+
* If the `init.headers` is a HeadersInit, create a new Headers
|
|
254
|
+
* instance out of it.
|
|
255
|
+
*/
|
|
256
|
+
function inferRawHeaders(headers: HeadersInit): RawHeaders {
|
|
257
|
+
if (headers instanceof Headers) {
|
|
258
|
+
return Reflect.get(headers, kRawHeaders) || []
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return Reflect.get(new Headers(headers), kRawHeaders)
|
|
262
|
+
}
|