msw 2.8.6 → 2.9.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.
@@ -5,7 +5,6 @@
5
5
  * Mock Service Worker.
6
6
  * @see https://github.com/mswjs/msw
7
7
  * - Please do NOT modify this file.
8
- * - Please do NOT serve this file on production.
9
8
  */
10
9
 
11
10
  const PACKAGE_VERSION = '<PACKAGE_VERSION>'
@@ -13,16 +12,16 @@ const INTEGRITY_CHECKSUM = '<INTEGRITY_CHECKSUM>'
13
12
  const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
14
13
  const activeClientIds = new Set()
15
14
 
16
- self.addEventListener('install', function () {
15
+ addEventListener('install', function () {
17
16
  self.skipWaiting()
18
17
  })
19
18
 
20
- self.addEventListener('activate', function (event) {
19
+ addEventListener('activate', function (event) {
21
20
  event.waitUntil(self.clients.claim())
22
21
  })
23
22
 
24
- self.addEventListener('message', async function (event) {
25
- const clientId = event.source.id
23
+ addEventListener('message', async function (event) {
24
+ const clientId = Reflect.get(event.source || {}, 'id')
26
25
 
27
26
  if (!clientId || !self.clients) {
28
27
  return
@@ -94,17 +93,18 @@ self.addEventListener('message', async function (event) {
94
93
  }
95
94
  })
96
95
 
97
- self.addEventListener('fetch', function (event) {
98
- const { request } = event
99
-
96
+ addEventListener('fetch', function (event) {
100
97
  // Bypass navigation requests.
101
- if (request.mode === 'navigate') {
98
+ if (event.request.mode === 'navigate') {
102
99
  return
103
100
  }
104
101
 
105
102
  // Opening the DevTools triggers the "only-if-cached" request
106
103
  // that cannot be handled by the worker. Bypass such requests.
107
- if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
104
+ if (
105
+ event.request.cache === 'only-if-cached' &&
106
+ event.request.mode !== 'same-origin'
107
+ ) {
108
108
  return
109
109
  }
110
110
 
@@ -115,48 +115,62 @@ self.addEventListener('fetch', function (event) {
115
115
  return
116
116
  }
117
117
 
118
- // Generate unique request ID.
119
118
  const requestId = crypto.randomUUID()
120
119
  event.respondWith(handleRequest(event, requestId))
121
120
  })
122
121
 
122
+ /**
123
+ * @param {FetchEvent} event
124
+ * @param {string} requestId
125
+ */
123
126
  async function handleRequest(event, requestId) {
124
127
  const client = await resolveMainClient(event)
128
+ const requestCloneForEvents = event.request.clone()
125
129
  const response = await getResponse(event, client, requestId)
126
130
 
127
131
  // Send back the response clone for the "response:*" life-cycle events.
128
132
  // Ensure MSW is active and ready to handle the message, otherwise
129
133
  // this message will pend indefinitely.
130
134
  if (client && activeClientIds.has(client.id)) {
131
- ;(async function () {
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,
135
+ const serializedRequest = await serializeRequest(requestCloneForEvents)
136
+
137
+ // Clone the response so both the client and the library could consume it.
138
+ const responseClone = response.clone()
139
+
140
+ sendToClient(
141
+ client,
142
+ {
143
+ type: 'RESPONSE',
144
+ payload: {
145
+ isMockedResponse: IS_MOCKED_RESPONSE in response,
146
+ request: {
147
+ id: requestId,
148
+ ...serializedRequest,
149
+ },
150
+ response: {
141
151
  type: responseClone.type,
142
152
  status: responseClone.status,
143
153
  statusText: responseClone.statusText,
144
- body: responseClone.body,
145
154
  headers: Object.fromEntries(responseClone.headers.entries()),
155
+ body: responseClone.body,
146
156
  },
147
157
  },
148
- [responseClone.body],
149
- )
150
- })()
158
+ },
159
+ responseClone.body ? [serializedRequest.body, responseClone.body] : [],
160
+ )
151
161
  }
152
162
 
153
163
  return response
154
164
  }
155
165
 
156
- // Resolve the main client for the given event.
157
- // Client that issues a request doesn't necessarily equal the client
158
- // that registered the worker. It's with the latter the worker should
159
- // communicate with during the response resolving phase.
166
+ /**
167
+ * Resolve the main client for the given event.
168
+ * Client that issues a request doesn't necessarily equal the client
169
+ * that registered the worker. It's with the latter the worker should
170
+ * communicate with during the response resolving phase.
171
+ * @param {FetchEvent} event
172
+ * @returns {Promise<Client | undefined>}
173
+ */
160
174
  async function resolveMainClient(event) {
161
175
  const client = await self.clients.get(event.clientId)
162
176
 
@@ -184,12 +198,16 @@ async function resolveMainClient(event) {
184
198
  })
185
199
  }
186
200
 
201
+ /**
202
+ * @param {FetchEvent} event
203
+ * @param {Client | undefined} client
204
+ * @param {string} requestId
205
+ * @returns {Promise<Response>}
206
+ */
187
207
  async function getResponse(event, client, requestId) {
188
- const { request } = event
189
-
190
208
  // Clone the request because it might've been already used
191
209
  // (i.e. its body has been read and sent to the client).
192
- const requestClone = request.clone()
210
+ const requestClone = event.request.clone()
193
211
 
194
212
  function passthrough() {
195
213
  // Cast the request headers to a new Headers instance
@@ -230,29 +248,17 @@ async function getResponse(event, client, requestId) {
230
248
  }
231
249
 
232
250
  // Notify the client that a request has been intercepted.
233
- const requestBuffer = await request.arrayBuffer()
251
+ const serializedRequest = await serializeRequest(event.request)
234
252
  const clientMessage = await sendToClient(
235
253
  client,
236
254
  {
237
255
  type: 'REQUEST',
238
256
  payload: {
239
257
  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,
258
+ ...serializedRequest,
253
259
  },
254
260
  },
255
- [requestBuffer],
261
+ [serializedRequest.body],
256
262
  )
257
263
 
258
264
  switch (clientMessage.type) {
@@ -268,6 +274,12 @@ async function getResponse(event, client, requestId) {
268
274
  return passthrough()
269
275
  }
270
276
 
277
+ /**
278
+ * @param {Client} client
279
+ * @param {any} message
280
+ * @param {Array<Transferable>} transferrables
281
+ * @returns {Promise<any>}
282
+ */
271
283
  function sendToClient(client, message, transferrables = []) {
272
284
  return new Promise((resolve, reject) => {
273
285
  const channel = new MessageChannel()
@@ -280,14 +292,18 @@ function sendToClient(client, message, transferrables = []) {
280
292
  resolve(event.data)
281
293
  }
282
294
 
283
- client.postMessage(
284
- message,
285
- [channel.port2].concat(transferrables.filter(Boolean)),
286
- )
295
+ client.postMessage(message, [
296
+ channel.port2,
297
+ ...transferrables.filter(Boolean),
298
+ ])
287
299
  })
288
300
  }
289
301
 
290
- async function respondWithMock(response) {
302
+ /**
303
+ * @param {Response} response
304
+ * @returns {Response}
305
+ */
306
+ function respondWithMock(response) {
291
307
  // Setting response status code to 0 is a no-op.
292
308
  // However, when responding with a "Response.error()", the produced Response
293
309
  // instance will have status code set to 0. Since it's not possible to create
@@ -305,3 +321,24 @@ async function respondWithMock(response) {
305
321
 
306
322
  return mockedResponse
307
323
  }
324
+
325
+ /**
326
+ * @param {Request} request
327
+ */
328
+ async function serializeRequest(request) {
329
+ return {
330
+ url: request.url,
331
+ mode: request.mode,
332
+ method: request.method,
333
+ headers: Object.fromEntries(request.headers.entries()),
334
+ cache: request.cache,
335
+ credentials: request.credentials,
336
+ destination: request.destination,
337
+ integrity: request.integrity,
338
+ redirect: request.redirect,
339
+ referrer: request.referrer,
340
+ referrerPolicy: request.referrerPolicy,
341
+ body: await request.arrayBuffer(),
342
+ keepalive: request.keepalive,
343
+ }
344
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "include": ["./mockServiceWorker.js"],
3
+ "compilerOptions": {
4
+ "strict": true,
5
+ "allowJs": true,
6
+ "checkJs": true,
7
+ "noEmit": true,
8
+ "target": "esnext",
9
+ "module": "esnext",
10
+ "lib": ["esnext"],
11
+ "types": ["@types/serviceworker"]
12
+ }
13
+ }