2
2
/* tslint:disable */
3
3
4
4
/**
5
- * Mock Service Worker (1.2.1) .
5
+ * Mock Service Worker.
6
6
* @see https://github.com/mswjs/msw
7
7
* - Please do NOT modify this file.
8
8
* - Please do NOT serve this file on production.
9
9
*/
10
10
11
- const INTEGRITY_CHECKSUM = '3d6b9f06410d179a7f7404d4bf4c3c70'
11
+ const PACKAGE_VERSION = '2.7.3'
12
+ const INTEGRITY_CHECKSUM = '00729d72e3b82faf54ca8b9621dbb96f'
13
+ const IS_MOCKED_RESPONSE = Symbol ( 'isMockedResponse' )
12
14
const activeClientIds = new Set ( )
13
15
14
16
self . addEventListener ( 'install' , function ( ) {
@@ -47,7 +49,10 @@ self.addEventListener('message', async function (event) {
47
49
case 'INTEGRITY_CHECK_REQUEST' : {
48
50
sendToClient ( client , {
49
51
type : 'INTEGRITY_CHECK_RESPONSE' ,
50
- payload : INTEGRITY_CHECKSUM ,
52
+ payload : {
53
+ packageVersion : PACKAGE_VERSION ,
54
+ checksum : INTEGRITY_CHECKSUM ,
55
+ } ,
51
56
} )
52
57
break
53
58
}
@@ -57,7 +62,12 @@ self.addEventListener('message', async function (event) {
57
62
58
63
sendToClient ( client , {
59
64
type : 'MOCKING_ENABLED' ,
60
- payload : true ,
65
+ payload : {
66
+ client : {
67
+ id : client . id ,
68
+ frameType : client . frameType ,
69
+ } ,
70
+ } ,
61
71
} )
62
72
break
63
73
}
@@ -86,12 +96,6 @@ self.addEventListener('message', async function (event) {
86
96
87
97
self . addEventListener ( 'fetch' , function ( event ) {
88
98
const { request } = event
89
- const accept = request . headers . get ( 'accept' ) || ''
90
-
91
- // Bypass server-sent events.
92
- if ( accept . includes ( 'text/event-stream' ) ) {
93
- return
94
- }
95
99
96
100
// Bypass navigation requests.
97
101
if ( request . mode === 'navigate' ) {
@@ -112,29 +116,8 @@ self.addEventListener('fetch', function (event) {
112
116
}
113
117
114
118
// Generate unique request ID.
115
- const requestId = Math . random ( ) . toString ( 16 ) . slice ( 2 )
116
-
117
- event . respondWith (
118
- handleRequest ( event , requestId ) . catch ( ( error ) => {
119
- if ( error . name === 'NetworkError' ) {
120
- console . warn (
121
- '[MSW] Successfully emulated a network error for the "%s %s" request.' ,
122
- request . method ,
123
- request . url ,
124
- )
125
- return
126
- }
127
-
128
- // At this point, any exception indicates an issue with the original request/response.
129
- console . error (
130
- `\
131
- [MSW] Caught an exception from the "%s %s" request (%s). This is probably not a problem with Mock Service Worker. There is likely an additional logging output above.` ,
132
- request . method ,
133
- request . url ,
134
- `${ error . name } : ${ error . message } ` ,
135
- )
136
- } ) ,
137
- )
119
+ const requestId = crypto . randomUUID ( )
120
+ event . respondWith ( handleRequest ( event , requestId ) )
138
121
} )
139
122
140
123
async function handleRequest ( event , requestId ) {
@@ -146,21 +129,24 @@ async function handleRequest(event, requestId) {
146
129
// this message will pend indefinitely.
147
130
if ( client && activeClientIds . has ( client . id ) ) {
148
131
; ( async function ( ) {
149
- const clonedResponse = response . clone ( )
150
- sendToClient ( client , {
151
- type : 'RESPONSE' ,
152
- payload : {
153
- requestId,
154
- type : clonedResponse . type ,
155
- ok : clonedResponse . ok ,
156
- status : clonedResponse . status ,
157
- statusText : clonedResponse . statusText ,
158
- body :
159
- clonedResponse . body === null ? null : await clonedResponse . text ( ) ,
160
- headers : Object . fromEntries ( clonedResponse . headers . entries ( ) ) ,
161
- redirected : clonedResponse . redirected ,
132
+ const responseClone = response . clone ( )
133
+
134
+ sendToClient (
135
+ client ,
136
+ {
137
+ type : 'RESPONSE' ,
138
+ payload : {
139
+ requestId,
140
+ isMockedResponse : IS_MOCKED_RESPONSE in response ,
141
+ type : responseClone . type ,
142
+ status : responseClone . status ,
143
+ statusText : responseClone . statusText ,
144
+ body : responseClone . body ,
145
+ headers : Object . fromEntries ( responseClone . headers . entries ( ) ) ,
146
+ } ,
162
147
} ,
163
- } )
148
+ [ responseClone . body ] ,
149
+ )
164
150
} ) ( )
165
151
}
166
152
@@ -174,6 +160,10 @@ async function handleRequest(event, requestId) {
174
160
async function resolveMainClient ( event ) {
175
161
const client = await self . clients . get ( event . clientId )
176
162
163
+ if ( activeClientIds . has ( event . clientId ) ) {
164
+ return client
165
+ }
166
+
177
167
if ( client ?. frameType === 'top-level' ) {
178
168
return client
179
169
}
@@ -196,20 +186,34 @@ async function resolveMainClient(event) {
196
186
197
187
async function getResponse ( event , client , requestId ) {
198
188
const { request } = event
199
- const clonedRequest = request . clone ( )
189
+
190
+ // Clone the request because it might've been already used
191
+ // (i.e. its body has been read and sent to the client).
192
+ const requestClone = request . clone ( )
200
193
201
194
function passthrough ( ) {
202
- // Clone the request because it might've been already used
203
- // (i.e. its body has been read and sent to the client).
204
- const headers = Object . fromEntries ( clonedRequest . headers . entries ( ) )
195
+ // Cast the request headers to a new Headers instance
196
+ // so the headers can be manipulated with.
197
+ const headers = new Headers ( requestClone . headers )
198
+
199
+ // Remove the "accept" header value that marked this request as passthrough.
200
+ // This prevents request alteration and also keeps it compliant with the
201
+ // user-defined CORS policies.
202
+ const acceptHeader = headers . get ( 'accept' )
203
+ if ( acceptHeader ) {
204
+ const values = acceptHeader . split ( ',' ) . map ( ( value ) => value . trim ( ) )
205
+ const filteredValues = values . filter (
206
+ ( value ) => value !== 'msw/passthrough' ,
207
+ )
205
208
206
- // Remove MSW-specific request headers so the bypassed requests
207
- // comply with the server's CORS preflight check.
208
- // Operate with the headers as an object because request "Headers"
209
- // are immutable.
210
- delete headers [ 'x-msw-bypass' ]
209
+ if ( filteredValues . length > 0 ) {
210
+ headers . set ( 'accept' , filteredValues . join ( ', ' ) )
211
+ } else {
212
+ headers . delete ( 'accept' )
213
+ }
214
+ }
211
215
212
- return fetch ( clonedRequest , { headers } )
216
+ return fetch ( requestClone , { headers } )
213
217
}
214
218
215
219
// Bypass mocking when the client is not active.
@@ -225,57 +229,46 @@ async function getResponse(event, client, requestId) {
225
229
return passthrough ( )
226
230
}
227
231
228
- // Bypass requests with the explicit bypass header.
229
- // Such requests can be issued by "ctx.fetch()".
230
- if ( request . headers . get ( 'x-msw-bypass' ) === 'true' ) {
231
- return passthrough ( )
232
- }
233
-
234
232
// Notify the client that a request has been intercepted.
235
- const clientMessage = await sendToClient ( client , {
236
- type : 'REQUEST' ,
237
- payload : {
238
- id : requestId ,
239
- url : request . url ,
240
- method : request . method ,
241
- headers : Object . fromEntries ( request . headers . entries ( ) ) ,
242
- cache : request . cache ,
243
- mode : request . mode ,
244
- credentials : request . credentials ,
245
- destination : request . destination ,
246
- integrity : request . integrity ,
247
- redirect : request . redirect ,
248
- referrer : request . referrer ,
249
- referrerPolicy : request . referrerPolicy ,
250
- body : await request . text ( ) ,
251
- bodyUsed : request . bodyUsed ,
252
- keepalive : request . keepalive ,
233
+ const requestBuffer = await request . arrayBuffer ( )
234
+ const clientMessage = await sendToClient (
235
+ client ,
236
+ {
237
+ type : 'REQUEST' ,
238
+ payload : {
239
+ id : requestId ,
240
+ url : request . url ,
241
+ mode : request . mode ,
242
+ method : request . method ,
243
+ headers : Object . fromEntries ( request . headers . entries ( ) ) ,
244
+ cache : request . cache ,
245
+ credentials : request . credentials ,
246
+ destination : request . destination ,
247
+ integrity : request . integrity ,
248
+ redirect : request . redirect ,
249
+ referrer : request . referrer ,
250
+ referrerPolicy : request . referrerPolicy ,
251
+ body : requestBuffer ,
252
+ keepalive : request . keepalive ,
253
+ } ,
253
254
} ,
254
- } )
255
+ [ requestBuffer ] ,
256
+ )
255
257
256
258
switch ( clientMessage . type ) {
257
259
case 'MOCK_RESPONSE' : {
258
260
return respondWithMock ( clientMessage . data )
259
261
}
260
262
261
- case 'MOCK_NOT_FOUND ' : {
263
+ case 'PASSTHROUGH ' : {
262
264
return passthrough ( )
263
265
}
264
-
265
- case 'NETWORK_ERROR' : {
266
- const { name, message } = clientMessage . data
267
- const networkError = new Error ( message )
268
- networkError . name = name
269
-
270
- // Rejecting a "respondWith" promise emulates a network error.
271
- throw networkError
272
- }
273
266
}
274
267
275
268
return passthrough ( )
276
269
}
277
270
278
- function sendToClient ( client , message ) {
271
+ function sendToClient ( client , message , transferrables = [ ] ) {
279
272
return new Promise ( ( resolve , reject ) => {
280
273
const channel = new MessageChannel ( )
281
274
@@ -287,17 +280,28 @@ function sendToClient(client, message) {
287
280
resolve ( event . data )
288
281
}
289
282
290
- client . postMessage ( message , [ channel . port2 ] )
283
+ client . postMessage (
284
+ message ,
285
+ [ channel . port2 ] . concat ( transferrables . filter ( Boolean ) ) ,
286
+ )
291
287
} )
292
288
}
293
289
294
- function sleep ( timeMs ) {
295
- return new Promise ( ( resolve ) => {
296
- setTimeout ( resolve , timeMs )
290
+ async function respondWithMock ( response ) {
291
+ // Setting response status code to 0 is a no-op.
292
+ // However, when responding with a "Response.error()", the produced Response
293
+ // instance will have status code set to 0. Since it's not possible to create
294
+ // a Response instance with status code 0, handle that use-case separately.
295
+ if ( response . status === 0 ) {
296
+ return Response . error ( )
297
+ }
298
+
299
+ const mockedResponse = new Response ( response . body , response )
300
+
301
+ Reflect . defineProperty ( mockedResponse , IS_MOCKED_RESPONSE , {
302
+ value : true ,
303
+ enumerable : true ,
297
304
} )
298
- }
299
305
300
- async function respondWithMock ( response ) {
301
- await sleep ( response . delay )
302
- return new Response ( response . body , response )
306
+ return mockedResponse
303
307
}
0 commit comments