Update checked-in dependencies
This commit is contained in:
parent
7fdbca3ba3
commit
357e0ceaa9
360 changed files with 25673 additions and 917 deletions
244
node_modules/@mswjs/interceptors/src/RemoteHttpInterceptor.ts
generated
vendored
Normal file
244
node_modules/@mswjs/interceptors/src/RemoteHttpInterceptor.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
import { ChildProcess } from 'child_process'
|
||||
import { HttpRequestEventMap } from './glossary'
|
||||
import { Interceptor } from './Interceptor'
|
||||
import { BatchInterceptor } from './BatchInterceptor'
|
||||
import { ClientRequestInterceptor } from './interceptors/ClientRequest'
|
||||
import { XMLHttpRequestInterceptor } from './interceptors/XMLHttpRequest'
|
||||
import { handleRequest } from './utils/handleRequest'
|
||||
import { RequestController } from './RequestController'
|
||||
import { FetchResponse } from './utils/fetchUtils'
|
||||
|
||||
export interface SerializedRequest {
|
||||
id: string
|
||||
url: string
|
||||
method: string
|
||||
headers: Array<[string, string]>
|
||||
credentials: RequestCredentials
|
||||
body: string
|
||||
}
|
||||
|
||||
interface RevivedRequest extends Omit<SerializedRequest, 'url' | 'headers'> {
|
||||
url: URL
|
||||
headers: Headers
|
||||
}
|
||||
|
||||
export interface SerializedResponse {
|
||||
status: number
|
||||
statusText: string
|
||||
headers: Array<[string, string]>
|
||||
body: string
|
||||
}
|
||||
|
||||
export class RemoteHttpInterceptor extends BatchInterceptor<
|
||||
[ClientRequestInterceptor, XMLHttpRequestInterceptor]
|
||||
> {
|
||||
constructor() {
|
||||
super({
|
||||
name: 'remote-interceptor',
|
||||
interceptors: [
|
||||
new ClientRequestInterceptor(),
|
||||
new XMLHttpRequestInterceptor(),
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
protected setup() {
|
||||
super.setup()
|
||||
|
||||
let handleParentMessage: NodeJS.MessageListener
|
||||
|
||||
this.on('request', async ({ request, requestId, controller }) => {
|
||||
// Send the stringified intercepted request to
|
||||
// the parent process where the remote resolver is established.
|
||||
const serializedRequest = JSON.stringify({
|
||||
id: requestId,
|
||||
method: request.method,
|
||||
url: request.url,
|
||||
headers: Array.from(request.headers.entries()),
|
||||
credentials: request.credentials,
|
||||
body: ['GET', 'HEAD'].includes(request.method)
|
||||
? null
|
||||
: await request.text(),
|
||||
} as SerializedRequest)
|
||||
|
||||
this.logger.info(
|
||||
'sent serialized request to the child:',
|
||||
serializedRequest
|
||||
)
|
||||
|
||||
process.send?.(`request:${serializedRequest}`)
|
||||
|
||||
const responsePromise = new Promise<void>((resolve) => {
|
||||
handleParentMessage = (message) => {
|
||||
if (typeof message !== 'string') {
|
||||
return resolve()
|
||||
}
|
||||
|
||||
if (message.startsWith(`response:${requestId}`)) {
|
||||
const [, serializedResponse] =
|
||||
message.match(/^response:.+?:(.+)$/) || []
|
||||
|
||||
if (!serializedResponse) {
|
||||
return resolve()
|
||||
}
|
||||
|
||||
const responseInit = JSON.parse(
|
||||
serializedResponse
|
||||
) as SerializedResponse
|
||||
|
||||
const mockedResponse = new FetchResponse(responseInit.body, {
|
||||
url: request.url,
|
||||
status: responseInit.status,
|
||||
statusText: responseInit.statusText,
|
||||
headers: responseInit.headers,
|
||||
})
|
||||
|
||||
/**
|
||||
* @todo Support "errorWith" as well.
|
||||
* This response handling from the child is incomplete.
|
||||
*/
|
||||
|
||||
controller.respondWith(mockedResponse)
|
||||
return resolve()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Listen for the mocked response message from the parent.
|
||||
this.logger.info(
|
||||
'add "message" listener to the parent process',
|
||||
handleParentMessage
|
||||
)
|
||||
process.addListener('message', handleParentMessage)
|
||||
|
||||
return responsePromise
|
||||
})
|
||||
|
||||
this.subscriptions.push(() => {
|
||||
process.removeListener('message', handleParentMessage)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function requestReviver(key: string, value: any) {
|
||||
switch (key) {
|
||||
case 'url':
|
||||
return new URL(value)
|
||||
|
||||
case 'headers':
|
||||
return new Headers(value)
|
||||
|
||||
default:
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
export interface RemoveResolverOptions {
|
||||
process: ChildProcess
|
||||
}
|
||||
|
||||
export class RemoteHttpResolver extends Interceptor<HttpRequestEventMap> {
|
||||
static symbol = Symbol('remote-resolver')
|
||||
private process: ChildProcess
|
||||
|
||||
constructor(options: RemoveResolverOptions) {
|
||||
super(RemoteHttpResolver.symbol)
|
||||
this.process = options.process
|
||||
}
|
||||
|
||||
protected setup() {
|
||||
const logger = this.logger.extend('setup')
|
||||
|
||||
const handleChildMessage: NodeJS.MessageListener = async (message) => {
|
||||
logger.info('received message from child!', message)
|
||||
|
||||
if (typeof message !== 'string' || !message.startsWith('request:')) {
|
||||
logger.info('unknown message, ignoring...')
|
||||
return
|
||||
}
|
||||
|
||||
const [, serializedRequest] = message.match(/^request:(.+)$/) || []
|
||||
if (!serializedRequest) {
|
||||
return
|
||||
}
|
||||
|
||||
const requestJson = JSON.parse(
|
||||
serializedRequest,
|
||||
requestReviver
|
||||
) as RevivedRequest
|
||||
|
||||
logger.info('parsed intercepted request', requestJson)
|
||||
|
||||
const request = new Request(requestJson.url, {
|
||||
method: requestJson.method,
|
||||
headers: new Headers(requestJson.headers),
|
||||
credentials: requestJson.credentials,
|
||||
body: requestJson.body,
|
||||
})
|
||||
|
||||
const controller = new RequestController(request)
|
||||
await handleRequest({
|
||||
request,
|
||||
requestId: requestJson.id,
|
||||
controller,
|
||||
emitter: this.emitter,
|
||||
onResponse: async (response) => {
|
||||
this.logger.info('received mocked response!', { response })
|
||||
|
||||
const responseClone = response.clone()
|
||||
const responseText = await responseClone.text()
|
||||
|
||||
// // Send the mocked response to the child process.
|
||||
const serializedResponse = JSON.stringify({
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
headers: Array.from(response.headers.entries()),
|
||||
body: responseText,
|
||||
} as SerializedResponse)
|
||||
|
||||
this.process.send(
|
||||
`response:${requestJson.id}:${serializedResponse}`,
|
||||
(error) => {
|
||||
if (error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Emit an optimistic "response" event at this point,
|
||||
// not to rely on the back-and-forth signaling for the sake of the event.
|
||||
this.emitter.emit('response', {
|
||||
request,
|
||||
requestId: requestJson.id,
|
||||
response: responseClone,
|
||||
isMockedResponse: true,
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
logger.info(
|
||||
'sent serialized mocked response to the parent:',
|
||||
serializedResponse
|
||||
)
|
||||
},
|
||||
onRequestError: (response) => {
|
||||
this.logger.info('received a network error!', { response })
|
||||
throw new Error('Not implemented')
|
||||
},
|
||||
onError: (error) => {
|
||||
this.logger.info('request has errored!', { error })
|
||||
throw new Error('Not implemented')
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
this.subscriptions.push(() => {
|
||||
this.process.removeListener('message', handleChildMessage)
|
||||
logger.info('removed the "message" listener from the child process!')
|
||||
})
|
||||
|
||||
logger.info('adding a "message" listener to the child process')
|
||||
this.process.addListener('message', handleChildMessage)
|
||||
|
||||
this.process.once('error', () => this.dispose())
|
||||
this.process.once('exit', () => this.dispose())
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue