@mswjs/interceptors 0.15.2 → 0.15.3
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 +49 -68
- package/lib/createInterceptor.d.ts +54 -0
- package/lib/createInterceptor.js +27 -0
- package/lib/createInterceptor.js.map +1 -0
- package/lib/index.d.ts +2 -2
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/interceptors/ClientRequest/NodeClientRequest.d.ts +5 -5
- package/lib/interceptors/ClientRequest/NodeClientRequest.js +15 -56
- package/lib/interceptors/ClientRequest/NodeClientRequest.js.map +1 -1
- package/lib/interceptors/ClientRequest/http.get.d.ts +3 -2
- package/lib/interceptors/ClientRequest/http.get.js +5 -2
- package/lib/interceptors/ClientRequest/http.get.js.map +1 -1
- package/lib/interceptors/ClientRequest/http.request.d.ts +3 -2
- package/lib/interceptors/ClientRequest/http.request.js +6 -3
- package/lib/interceptors/ClientRequest/http.request.js.map +1 -1
- package/lib/interceptors/ClientRequest/index.d.ts +4 -14
- package/lib/interceptors/ClientRequest/index.js +46 -59
- package/lib/interceptors/ClientRequest/index.js.map +1 -1
- package/lib/interceptors/ClientRequest/utils/getIncomingMessageBody.js +2 -7
- package/lib/interceptors/ClientRequest/utils/getIncomingMessageBody.js.map +1 -1
- package/lib/interceptors/XMLHttpRequest/XMLHttpRequestOverride.d.ts +4 -11
- package/lib/interceptors/XMLHttpRequest/XMLHttpRequestOverride.js +58 -110
- package/lib/interceptors/XMLHttpRequest/XMLHttpRequestOverride.js.map +1 -1
- package/lib/interceptors/XMLHttpRequest/index.d.ts +5 -11
- package/lib/interceptors/XMLHttpRequest/index.js +25 -43
- package/lib/interceptors/XMLHttpRequest/index.js.map +1 -1
- package/lib/interceptors/fetch/index.d.ts +2 -8
- package/lib/interceptors/fetch/index.js +68 -120
- package/lib/interceptors/fetch/index.js.map +1 -1
- package/lib/presets/browser.d.ts +1 -3
- package/lib/presets/browser.js +2 -2
- package/lib/presets/browser.js.map +1 -1
- package/lib/presets/node.d.ts +1 -3
- package/lib/presets/node.js +1 -1
- package/lib/presets/node.js.map +1 -1
- package/lib/remote.d.ts +21 -0
- package/lib/remote.js +178 -0
- package/lib/remote.js.map +1 -0
- package/lib/utils/toIsoResponse.d.ts +1 -1
- package/package.json +6 -6
- package/src/createInterceptor.ts +100 -0
- package/src/index.ts +2 -2
- package/src/interceptors/ClientRequest/NodeClientRequest.test.ts +70 -87
- package/src/interceptors/ClientRequest/NodeClientRequest.ts +100 -139
- package/src/interceptors/ClientRequest/http.get.ts +11 -7
- package/src/interceptors/ClientRequest/http.request.ts +12 -8
- package/src/interceptors/ClientRequest/index.ts +46 -46
- package/src/interceptors/ClientRequest/utils/getIncomingMessageBody.test.ts +0 -9
- package/src/interceptors/ClientRequest/utils/getIncomingMessageBody.ts +2 -9
- package/src/interceptors/XMLHttpRequest/XMLHttpRequestOverride.ts +159 -215
- package/src/interceptors/XMLHttpRequest/index.ts +23 -41
- package/src/interceptors/fetch/index.ts +55 -81
- package/src/presets/browser.ts +3 -3
- package/src/presets/node.ts +3 -3
- package/src/remote.ts +174 -0
- package/src/utils/.DS_Store +0 -0
- package/src/utils/toIsoResponse.ts +1 -1
- package/LICENSE.md +0 -9
- package/lib/BatchInterceptor.d.ts +0 -18
- package/lib/BatchInterceptor.js +0 -79
- package/lib/BatchInterceptor.js.map +0 -1
- package/lib/Interceptor.d.ts +0 -49
- package/lib/Interceptor.js +0 -197
- package/lib/Interceptor.js.map +0 -1
- package/lib/RemoteInterceptor.d.ts +0 -24
- package/lib/RemoteInterceptor.js +0 -216
- package/lib/RemoteInterceptor.js.map +0 -1
- package/lib/glossary.d.ts +0 -32
- package/lib/glossary.js +0 -3
- package/lib/glossary.js.map +0 -1
- package/lib/utils/AsyncEventEmitter.d.ts +0 -29
- package/lib/utils/AsyncEventEmitter.js +0 -241
- package/lib/utils/AsyncEventEmitter.js.map +0 -1
- package/lib/utils/createLazyCallback.d.ts +0 -11
- package/lib/utils/createLazyCallback.js +0 -75
- package/lib/utils/createLazyCallback.js.map +0 -1
- package/lib/utils/nextTick.d.ts +0 -2
- package/lib/utils/nextTick.js +0 -16
- package/lib/utils/nextTick.js.map +0 -1
- package/src/BatchInterceptor.test.ts +0 -113
- package/src/BatchInterceptor.ts +0 -60
- package/src/Interceptor.test.ts +0 -166
- package/src/Interceptor.ts +0 -226
- package/src/RemoteInterceptor.ts +0 -176
- package/src/glossary.ts +0 -42
- package/src/interceptors/ClientRequest/index.test.ts +0 -43
- package/src/utils/AsyncEventEmitter.test.ts +0 -68
- package/src/utils/AsyncEventEmitter.ts +0 -171
- package/src/utils/createLazyCallback.ts +0 -49
- package/src/utils/nextTick.ts +0 -11
|
@@ -1,106 +1,80 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Headers,
|
|
3
|
-
flattenHeadersObject,
|
|
4
|
-
objectToHeaders,
|
|
5
3
|
headersToObject,
|
|
4
|
+
objectToHeaders,
|
|
5
|
+
flattenHeadersObject,
|
|
6
6
|
} from 'headers-polyfill'
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
import {
|
|
8
|
+
Interceptor,
|
|
9
|
+
IsomorphicRequest,
|
|
10
10
|
IsomorphicResponse,
|
|
11
|
-
} from '../../
|
|
12
|
-
import { Interceptor } from '../../Interceptor'
|
|
13
|
-
import { createLazyCallback } from '../../utils/createLazyCallback'
|
|
11
|
+
} from '../../createInterceptor'
|
|
14
12
|
import { toIsoResponse } from '../../utils/toIsoResponse'
|
|
15
13
|
import { uuidv4 } from '../../utils/uuid'
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
static symbol = Symbol('fetch')
|
|
19
|
-
|
|
20
|
-
constructor() {
|
|
21
|
-
super(FetchInterceptor.symbol)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
protected checkEnvironment() {
|
|
25
|
-
return (
|
|
26
|
-
typeof globalThis !== 'undefined' &&
|
|
27
|
-
typeof globalThis.fetch !== 'undefined'
|
|
28
|
-
)
|
|
29
|
-
}
|
|
15
|
+
const debug = require('debug')('fetch')
|
|
30
16
|
|
|
31
|
-
|
|
32
|
-
|
|
17
|
+
export const interceptFetch: Interceptor = (observer, resolver) => {
|
|
18
|
+
const pureFetch = window.fetch
|
|
33
19
|
|
|
34
|
-
|
|
35
|
-
const request = new Request(input, init)
|
|
36
|
-
const url = typeof input === 'string' ? input : input.url
|
|
37
|
-
const method = request.method
|
|
20
|
+
debug('replacing "window.fetch"...')
|
|
38
21
|
|
|
39
|
-
|
|
22
|
+
window.fetch = async (input, init) => {
|
|
23
|
+
const request = new Request(input, init)
|
|
24
|
+
const url = typeof input === 'string' ? input : input.url
|
|
25
|
+
const method = request.method
|
|
40
26
|
|
|
41
|
-
|
|
42
|
-
id: uuidv4(),
|
|
43
|
-
url: new URL(url, location.origin),
|
|
44
|
-
method: method,
|
|
45
|
-
headers: new Headers(request.headers),
|
|
46
|
-
credentials: request.credentials,
|
|
47
|
-
body: await request.clone().text(),
|
|
48
|
-
respondWith: createLazyCallback(),
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
this.log('isomorphic request', isomorphicRequest)
|
|
52
|
-
|
|
53
|
-
this.log(
|
|
54
|
-
'emitting the "request" event for %d listener(s)...',
|
|
55
|
-
this.emitter.listenerCount('request')
|
|
56
|
-
)
|
|
57
|
-
this.emitter.emit('request', isomorphicRequest)
|
|
27
|
+
debug('[%s] %s', method, url)
|
|
58
28
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const isomorphicResponse = toIsoResponse(mockedResponse)
|
|
71
|
-
this.log('derived isomorphic response:', isomorphicResponse)
|
|
72
|
-
|
|
73
|
-
this.emitter.emit('response', isomorphicRequest, isomorphicResponse)
|
|
29
|
+
const isoRequest: IsomorphicRequest = {
|
|
30
|
+
id: uuidv4(),
|
|
31
|
+
url: new URL(url, location.origin),
|
|
32
|
+
method: method,
|
|
33
|
+
headers: new Headers(request.headers),
|
|
34
|
+
credentials: request.credentials,
|
|
35
|
+
body: await request.clone().text(),
|
|
36
|
+
}
|
|
37
|
+
debug('isomorphic request', isoRequest)
|
|
38
|
+
observer.emit('request', isoRequest)
|
|
74
39
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
// Apparently, it halts if the `Headers` class contains unknown properties
|
|
79
|
-
// (i.e. the internal `Headers.map`).
|
|
80
|
-
headers: flattenHeadersObject(mockedResponse.headers || {}),
|
|
81
|
-
})
|
|
82
|
-
}
|
|
40
|
+
debug('awaiting for the mocked response...')
|
|
41
|
+
const response = await resolver(isoRequest, request)
|
|
42
|
+
debug('mocked response', response)
|
|
83
43
|
|
|
84
|
-
|
|
44
|
+
if (response) {
|
|
45
|
+
const isomorphicResponse = toIsoResponse(response)
|
|
46
|
+
debug('derived isomorphic response', isomorphicResponse)
|
|
85
47
|
|
|
86
|
-
|
|
87
|
-
const cloneResponse = response.clone()
|
|
88
|
-
this.log('original fetch performed', cloneResponse)
|
|
48
|
+
observer.emit('response', isoRequest, isomorphicResponse)
|
|
89
49
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
)
|
|
95
|
-
|
|
50
|
+
return new Response(response.body, {
|
|
51
|
+
...isomorphicResponse,
|
|
52
|
+
// `Response.headers` cannot be instantiated with the `Headers` polyfill.
|
|
53
|
+
// Apparently, it halts if the `Headers` class contains unknown properties
|
|
54
|
+
// (i.e. the internal `Headers.map`).
|
|
55
|
+
headers: flattenHeadersObject(response.headers || {}),
|
|
96
56
|
})
|
|
97
57
|
}
|
|
98
58
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
59
|
+
debug('no mocked response found, bypassing...')
|
|
60
|
+
|
|
61
|
+
return pureFetch(request).then(async (response) => {
|
|
62
|
+
const cloneResponse = response.clone()
|
|
63
|
+
debug('original fetch performed', cloneResponse)
|
|
64
|
+
|
|
65
|
+
observer.emit(
|
|
66
|
+
'response',
|
|
67
|
+
isoRequest,
|
|
68
|
+
await normalizeFetchResponse(cloneResponse)
|
|
69
|
+
)
|
|
70
|
+
return response
|
|
102
71
|
})
|
|
103
72
|
}
|
|
73
|
+
|
|
74
|
+
return () => {
|
|
75
|
+
debug('restoring modules...')
|
|
76
|
+
window.fetch = pureFetch
|
|
77
|
+
}
|
|
104
78
|
}
|
|
105
79
|
|
|
106
80
|
async function normalizeFetchResponse(
|
package/src/presets/browser.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { interceptXMLHttpRequest } from '../interceptors/XMLHttpRequest'
|
|
2
|
+
import { interceptFetch } from '../interceptors/fetch'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* The default preset provisions the interception of requests
|
|
6
6
|
* regardless of their type (fetch/XMLHttpRequest).
|
|
7
7
|
*/
|
|
8
|
-
export default [
|
|
8
|
+
export default [interceptXMLHttpRequest, interceptFetch]
|
package/src/presets/node.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { interceptClientRequest } from '../interceptors/ClientRequest'
|
|
2
|
+
import { interceptXMLHttpRequest } from '../interceptors/XMLHttpRequest'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* The default preset provisions the interception of requests
|
|
6
6
|
* regardless of their type (http/https/XMLHttpRequest).
|
|
7
7
|
*/
|
|
8
|
-
export default [
|
|
8
|
+
export default [interceptClientRequest, interceptXMLHttpRequest]
|
package/src/remote.ts
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { ChildProcess } from 'child_process'
|
|
2
|
+
import { Headers } from 'headers-polyfill'
|
|
3
|
+
import { invariant } from 'outvariant'
|
|
4
|
+
import { StrictEventEmitter } from 'strict-event-emitter'
|
|
5
|
+
import {
|
|
6
|
+
createInterceptor,
|
|
7
|
+
InterceptorApi,
|
|
8
|
+
InterceptorEventsMap,
|
|
9
|
+
InterceptorOptions,
|
|
10
|
+
IsomorphicRequest,
|
|
11
|
+
Resolver,
|
|
12
|
+
} from './createInterceptor'
|
|
13
|
+
import { toIsoResponse } from './utils/toIsoResponse'
|
|
14
|
+
|
|
15
|
+
export type CreateRemoteInterceptorOptions = Omit<
|
|
16
|
+
InterceptorOptions,
|
|
17
|
+
'resolver'
|
|
18
|
+
>
|
|
19
|
+
|
|
20
|
+
export type RemoteResolverApi = Pick<InterceptorApi, 'on'>
|
|
21
|
+
|
|
22
|
+
export interface CreateRemoteResolverOptions {
|
|
23
|
+
process: ChildProcess
|
|
24
|
+
resolver: Resolver
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function requestReviver(key: string, value: any) {
|
|
28
|
+
switch (key) {
|
|
29
|
+
case 'url':
|
|
30
|
+
return new URL(value)
|
|
31
|
+
|
|
32
|
+
case 'headers':
|
|
33
|
+
return new Headers(value)
|
|
34
|
+
|
|
35
|
+
default:
|
|
36
|
+
return value
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Creates a remote request interceptor that delegates
|
|
42
|
+
* the mocked response resolution to the parent process.
|
|
43
|
+
* The parent process must establish a remote resolver
|
|
44
|
+
* by calling `createRemoteResolver` function.
|
|
45
|
+
*/
|
|
46
|
+
export function createRemoteInterceptor(
|
|
47
|
+
options: CreateRemoteInterceptorOptions
|
|
48
|
+
): InterceptorApi {
|
|
49
|
+
invariant(
|
|
50
|
+
process.connected,
|
|
51
|
+
`Failed to create a remote interceptor: the current process (%s) does not have a parent. Please make sure you're spawning this process as a child process in order to use remote request interception.`,
|
|
52
|
+
process.pid
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
if (typeof process.send === 'undefined') {
|
|
56
|
+
throw new Error(
|
|
57
|
+
`\
|
|
58
|
+
Failed to create a remote interceptor: the current process (${process.pid}) does not have the IPC enabled. Please make sure you're spawning this process with the "ipc" stdio value set:
|
|
59
|
+
|
|
60
|
+
spawn('node', ['module.js'], { stdio: ['ipc'] })\
|
|
61
|
+
`
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let handleParentMessage: NodeJS.MessageListener
|
|
66
|
+
|
|
67
|
+
const interceptor = createInterceptor({
|
|
68
|
+
...options,
|
|
69
|
+
resolver(request) {
|
|
70
|
+
const serializedRequest = JSON.stringify(request)
|
|
71
|
+
process.send?.(`request:${serializedRequest}`)
|
|
72
|
+
|
|
73
|
+
return new Promise((resolve) => {
|
|
74
|
+
handleParentMessage = (message) => {
|
|
75
|
+
if (typeof message !== 'string') {
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (message.startsWith(`response:${request.id}`)) {
|
|
80
|
+
const [, responseString] =
|
|
81
|
+
message.match(/^response:.+?:(.+)$/) || []
|
|
82
|
+
|
|
83
|
+
if (!responseString) {
|
|
84
|
+
return resolve()
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const mockedResponse = JSON.parse(responseString)
|
|
88
|
+
|
|
89
|
+
return resolve(mockedResponse)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
process.addListener('message', handleParentMessage)
|
|
94
|
+
})
|
|
95
|
+
},
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
...interceptor,
|
|
100
|
+
restore() {
|
|
101
|
+
interceptor.restore()
|
|
102
|
+
process.removeListener('message', handleParentMessage)
|
|
103
|
+
},
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Creates a response resolver function attached to the given `ChildProcess`.
|
|
109
|
+
* The child process must establish a remote interceptor by calling `createRemoteInterceptor` function.
|
|
110
|
+
*/
|
|
111
|
+
export function createRemoteResolver(
|
|
112
|
+
options: CreateRemoteResolverOptions
|
|
113
|
+
): RemoteResolverApi {
|
|
114
|
+
const observer = new StrictEventEmitter<InterceptorEventsMap>()
|
|
115
|
+
|
|
116
|
+
const handleChildMessage: NodeJS.MessageListener = async (message) => {
|
|
117
|
+
if (typeof message !== 'string') {
|
|
118
|
+
return
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (message.startsWith('request:')) {
|
|
122
|
+
const [, requestString] = message.match(/^request:(.+)$/) || []
|
|
123
|
+
|
|
124
|
+
if (!requestString) {
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const isoRequest: IsomorphicRequest = JSON.parse(
|
|
129
|
+
requestString,
|
|
130
|
+
requestReviver
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
observer.emit('request', isoRequest)
|
|
134
|
+
|
|
135
|
+
// Retrieve the mocked response.
|
|
136
|
+
const mockedResponse = await options.resolver(
|
|
137
|
+
isoRequest,
|
|
138
|
+
undefined as any
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
// Send the mocked response to the child process.
|
|
142
|
+
const serializedResponse = JSON.stringify(mockedResponse)
|
|
143
|
+
options.process.send(
|
|
144
|
+
`response:${isoRequest.id}:${serializedResponse}`,
|
|
145
|
+
(error) => {
|
|
146
|
+
if (error) {
|
|
147
|
+
return
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (mockedResponse) {
|
|
151
|
+
// Emit an optimisting "response" event at this point,
|
|
152
|
+
// not to rely on the back-and-forth signaling for the sake of the event.
|
|
153
|
+
observer.emit('response', isoRequest, toIsoResponse(mockedResponse))
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const cleanup = () => {
|
|
161
|
+
options.process.removeListener('message', handleChildMessage)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
options.process.addListener('message', handleChildMessage)
|
|
165
|
+
options.process.addListener('disconnect', cleanup)
|
|
166
|
+
options.process.addListener('error', cleanup)
|
|
167
|
+
options.process.addListener('exit', cleanup)
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
on(event, listener) {
|
|
171
|
+
observer.addListener(event, listener)
|
|
172
|
+
},
|
|
173
|
+
}
|
|
174
|
+
}
|
|
Binary file
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { objectToHeaders } from 'headers-polyfill'
|
|
2
|
-
import { IsomorphicResponse, MockedResponse } from '../
|
|
2
|
+
import { IsomorphicResponse, MockedResponse } from '../createInterceptor'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Converts a given mocked response object into an isomorphic response.
|
package/LICENSE.md
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2018–present Artem Zakharchenko
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
-
|
|
7
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
-
|
|
9
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { EventMapType } from 'strict-event-emitter';
|
|
2
|
-
import { ExtractEventNames, Interceptor } from './Interceptor';
|
|
3
|
-
export interface BatchInterceptorOptions<InterceptorList extends Interceptor<any>[]> {
|
|
4
|
-
name: string;
|
|
5
|
-
interceptors: InterceptorList;
|
|
6
|
-
}
|
|
7
|
-
export declare type ExtractEventMapType<InterceptorList extends Interceptor<any>[]> = InterceptorList extends Array<infer InterceptorType> ? InterceptorType extends Interceptor<infer EventMap> ? EventMap : never : never;
|
|
8
|
-
/**
|
|
9
|
-
* A batch interceptor that exposes a single interface
|
|
10
|
-
* to apply and operate with multiple interceptors at once.
|
|
11
|
-
*/
|
|
12
|
-
export declare class BatchInterceptor<InterceptorList extends Interceptor<any>[], EventMap extends EventMapType = ExtractEventMapType<InterceptorList>> extends Interceptor<EventMap> {
|
|
13
|
-
static symbol: Symbol;
|
|
14
|
-
private interceptors;
|
|
15
|
-
constructor(options: BatchInterceptorOptions<InterceptorList>);
|
|
16
|
-
protected setup(): void;
|
|
17
|
-
on<Event extends ExtractEventNames<EventMap>>(event: Event, listener: EventMap[Event]): void;
|
|
18
|
-
}
|
package/lib/BatchInterceptor.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __extends = (this && this.__extends) || (function () {
|
|
3
|
-
var extendStatics = function (d, b) {
|
|
4
|
-
extendStatics = Object.setPrototypeOf ||
|
|
5
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
if (typeof b !== "function" && b !== null)
|
|
11
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
-
extendStatics(d, b);
|
|
13
|
-
function __() { this.constructor = d; }
|
|
14
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
-
};
|
|
16
|
-
})();
|
|
17
|
-
var __values = (this && this.__values) || function(o) {
|
|
18
|
-
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
19
|
-
if (m) return m.call(o);
|
|
20
|
-
if (o && typeof o.length === "number") return {
|
|
21
|
-
next: function () {
|
|
22
|
-
if (o && i >= o.length) o = void 0;
|
|
23
|
-
return { value: o && o[i++], done: !o };
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
27
|
-
};
|
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.BatchInterceptor = void 0;
|
|
30
|
-
var Interceptor_1 = require("./Interceptor");
|
|
31
|
-
/**
|
|
32
|
-
* A batch interceptor that exposes a single interface
|
|
33
|
-
* to apply and operate with multiple interceptors at once.
|
|
34
|
-
*/
|
|
35
|
-
var BatchInterceptor = /** @class */ (function (_super) {
|
|
36
|
-
__extends(BatchInterceptor, _super);
|
|
37
|
-
function BatchInterceptor(options) {
|
|
38
|
-
var _this = this;
|
|
39
|
-
BatchInterceptor.symbol = Symbol(options.name);
|
|
40
|
-
_this = _super.call(this, BatchInterceptor.symbol) || this;
|
|
41
|
-
_this.interceptors = options.interceptors;
|
|
42
|
-
return _this;
|
|
43
|
-
}
|
|
44
|
-
BatchInterceptor.prototype.setup = function () {
|
|
45
|
-
var e_1, _a;
|
|
46
|
-
var log = this.log.extend('setup');
|
|
47
|
-
log('applying all %d interceptors...', this.interceptors.length);
|
|
48
|
-
var _loop_1 = function (interceptor) {
|
|
49
|
-
log('applying "%s" interceptor...', interceptor.constructor.name);
|
|
50
|
-
interceptor.apply();
|
|
51
|
-
log('adding interceptor dispose subscription');
|
|
52
|
-
this_1.subscriptions.push(function () { return interceptor.dispose(); });
|
|
53
|
-
};
|
|
54
|
-
var this_1 = this;
|
|
55
|
-
try {
|
|
56
|
-
for (var _b = __values(this.interceptors), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
57
|
-
var interceptor = _c.value;
|
|
58
|
-
_loop_1(interceptor);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
62
|
-
finally {
|
|
63
|
-
try {
|
|
64
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
65
|
-
}
|
|
66
|
-
finally { if (e_1) throw e_1.error; }
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
BatchInterceptor.prototype.on = function (event, listener) {
|
|
70
|
-
// Instead of adding a listener to the batch interceptor,
|
|
71
|
-
// propagate the listener to each of the individual interceptors.
|
|
72
|
-
this.interceptors.forEach(function (interceptor) {
|
|
73
|
-
interceptor.on(event, listener);
|
|
74
|
-
});
|
|
75
|
-
};
|
|
76
|
-
return BatchInterceptor;
|
|
77
|
-
}(Interceptor_1.Interceptor));
|
|
78
|
-
exports.BatchInterceptor = BatchInterceptor;
|
|
79
|
-
//# sourceMappingURL=BatchInterceptor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BatchInterceptor.js","sourceRoot":"","sources":["../src/BatchInterceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,6CAA8D;AAgB9D;;;GAGG;AACH;IAGU,oCAAqB;IAK7B,0BAAY,OAAiD;QAA7D,iBAIC;QAHC,gBAAgB,CAAC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAC9C,QAAA,kBAAM,gBAAgB,CAAC,MAAM,CAAC,SAAA;QAC9B,KAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAA;;IAC1C,CAAC;IAES,gCAAK,GAAf;;QACE,IAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QAEpC,GAAG,CAAC,iCAAiC,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;gCAErD,WAAW;YACpB,GAAG,CAAC,8BAA8B,EAAE,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;YACjE,WAAW,CAAC,KAAK,EAAE,CAAA;YAEnB,GAAG,CAAC,yCAAyC,CAAC,CAAA;YAC9C,OAAK,aAAa,CAAC,IAAI,CAAC,cAAM,OAAA,WAAW,CAAC,OAAO,EAAE,EAArB,CAAqB,CAAC,CAAA;;;;YALtD,KAA0B,IAAA,KAAA,SAAA,IAAI,CAAC,YAAY,CAAA,gBAAA;gBAAtC,IAAM,WAAW,WAAA;wBAAX,WAAW;aAMrB;;;;;;;;;IACH,CAAC;IAEM,6BAAE,GAAT,UACE,KAAY,EACZ,QAAyB;QAEzB,yDAAyD;QACzD,iEAAiE;QACjE,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,UAAC,WAAW;YACpC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;QACjC,CAAC,CAAC,CAAA;IACJ,CAAC;IACH,uBAAC;AAAD,CAAC,AAtCD,CAGU,yBAAW,GAmCpB;AAtCY,4CAAgB"}
|
package/lib/Interceptor.d.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { Debugger } from 'debug';
|
|
2
|
-
import { AsyncEventEmitter } from './utils/AsyncEventEmitter';
|
|
3
|
-
export declare type InterceptorEventMap = Record<string, (...args: any[]) => void>;
|
|
4
|
-
export declare type InterceptorSubscription = () => void;
|
|
5
|
-
export declare function getGlobalSymbol<V>(symbol: Symbol): V | undefined;
|
|
6
|
-
export declare function deleteGlobalSymbol(symbol: Symbol): void;
|
|
7
|
-
export declare enum InterceptorReadyState {
|
|
8
|
-
IDLE = "IDLE",
|
|
9
|
-
APPLYING = "APPLYING",
|
|
10
|
-
APPLIED = "APPLIED",
|
|
11
|
-
DISPOSING = "DISPOSING",
|
|
12
|
-
DISPOSED = "DISPOSED"
|
|
13
|
-
}
|
|
14
|
-
export declare type ExtractEventNames<EventMap extends Record<string, any>> = EventMap extends Record<infer EventName, any> ? EventName : never;
|
|
15
|
-
export declare class Interceptor<EventMap extends InterceptorEventMap> {
|
|
16
|
-
private readonly symbol;
|
|
17
|
-
protected emitter: AsyncEventEmitter<EventMap>;
|
|
18
|
-
protected subscriptions: InterceptorSubscription[];
|
|
19
|
-
protected log: Debugger;
|
|
20
|
-
readyState: InterceptorReadyState;
|
|
21
|
-
constructor(symbol: Symbol);
|
|
22
|
-
/**
|
|
23
|
-
* Determine if this interceptor can be applied
|
|
24
|
-
* in the current environment.
|
|
25
|
-
*/
|
|
26
|
-
protected checkEnvironment(): boolean;
|
|
27
|
-
/**
|
|
28
|
-
* Apply this interceptor to the current process.
|
|
29
|
-
* Returns an already running interceptor instance if it's present.
|
|
30
|
-
*/
|
|
31
|
-
apply(): void;
|
|
32
|
-
/**
|
|
33
|
-
* Setup the module augments and stubs necessary for this interceptor.
|
|
34
|
-
* This method is not run if there's a running interceptor instance
|
|
35
|
-
* to prevent instantiating an interceptor multiple times.
|
|
36
|
-
*/
|
|
37
|
-
protected setup(): void;
|
|
38
|
-
/**
|
|
39
|
-
* Listen to the interceptor's public events.
|
|
40
|
-
*/
|
|
41
|
-
on<Event extends ExtractEventNames<EventMap>>(event: Event, listener: EventMap[Event]): void;
|
|
42
|
-
/**
|
|
43
|
-
* Disposes of any side-effects this interceptor has introduced.
|
|
44
|
-
*/
|
|
45
|
-
dispose(): void;
|
|
46
|
-
private getInstance;
|
|
47
|
-
private setInstance;
|
|
48
|
-
private clearInstance;
|
|
49
|
-
}
|