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.
- package/README.md +1 -1
- package/cli/init.js +1 -1
- package/lib/browser/index.js +14 -18
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/index.mjs +14 -18
- package/lib/browser/index.mjs.map +1 -1
- package/lib/core/handlers/HttpHandler.js +1 -1
- package/lib/core/handlers/HttpHandler.js.map +1 -1
- package/lib/core/handlers/HttpHandler.mjs +1 -1
- package/lib/core/handlers/HttpHandler.mjs.map +1 -1
- package/lib/core/utils/request/onUnhandledRequest.js +1 -1
- package/lib/core/utils/request/onUnhandledRequest.js.map +1 -1
- package/lib/core/utils/request/onUnhandledRequest.mjs +1 -1
- package/lib/core/utils/request/onUnhandledRequest.mjs.map +1 -1
- package/lib/iife/index.js +16 -20
- package/lib/iife/index.js.map +1 -1
- package/lib/mockServiceWorker.js +91 -54
- package/package.json +3 -2
- package/src/browser/setupWorker/glossary.ts +7 -7
- package/src/browser/setupWorker/setupWorker.ts +0 -1
- package/src/browser/setupWorker/start/createRequestListener.ts +4 -5
- package/src/browser/setupWorker/start/createResponseListener.ts +8 -12
- package/src/browser/utils/{parseWorkerRequest.ts → deserializeRequest.ts} +5 -5
- package/src/core/handlers/HttpHandler.ts +1 -1
- package/src/core/utils/request/onUnhandledRequest.test.ts +3 -3
- package/src/core/utils/request/onUnhandledRequest.ts +1 -1
- package/src/mockServiceWorker.js +89 -52
- package/src/tsconfig.worker.json +13 -0
package/src/mockServiceWorker.js
CHANGED
|
@@ -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
|
-
|
|
15
|
+
addEventListener('install', function () {
|
|
17
16
|
self.skipWaiting()
|
|
18
17
|
})
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
addEventListener('activate', function (event) {
|
|
21
20
|
event.waitUntil(self.clients.claim())
|
|
22
21
|
})
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
const clientId = event.source
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
-
|
|
149
|
-
|
|
150
|
-
|
|
158
|
+
},
|
|
159
|
+
responseClone.body ? [serializedRequest.body, responseClone.body] : [],
|
|
160
|
+
)
|
|
151
161
|
}
|
|
152
162
|
|
|
153
163
|
return response
|
|
154
164
|
}
|
|
155
165
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
[
|
|
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
|
-
|
|
285
|
-
|
|
286
|
-
)
|
|
295
|
+
client.postMessage(message, [
|
|
296
|
+
channel.port2,
|
|
297
|
+
...transferrables.filter(Boolean),
|
|
298
|
+
])
|
|
287
299
|
})
|
|
288
300
|
}
|
|
289
301
|
|
|
290
|
-
|
|
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
|
+
}
|