github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/ui/public/mockServiceWorker.js (about) 1 /* eslint-disable */ 2 /* tslint:disable */ 3 4 /** 5 * Mock Service Worker (0.36.3). 6 * @see https://github.com/mswjs/msw 7 * - Please do NOT modify this file. 8 * - Please do NOT serve this file on production. 9 */ 10 11 const INTEGRITY_CHECKSUM = '02f4ad4a2797f85668baf196e553d929' 12 const bypassHeaderName = 'x-msw-bypass' 13 const activeClientIds = new Set() 14 15 self.addEventListener('install', function () { 16 return self.skipWaiting() 17 }) 18 19 self.addEventListener('activate', async function (event) { 20 return self.clients.claim() 21 }) 22 23 self.addEventListener('message', async function (event) { 24 const clientId = event.source.id 25 26 if (!clientId || !self.clients) { 27 return 28 } 29 30 const client = await self.clients.get(clientId) 31 32 if (!client) { 33 return 34 } 35 36 const allClients = await self.clients.matchAll() 37 38 switch (event.data) { 39 case 'KEEPALIVE_REQUEST': { 40 sendToClient(client, { 41 type: 'KEEPALIVE_RESPONSE', 42 }) 43 break 44 } 45 46 case 'INTEGRITY_CHECK_REQUEST': { 47 sendToClient(client, { 48 type: 'INTEGRITY_CHECK_RESPONSE', 49 payload: INTEGRITY_CHECKSUM, 50 }) 51 break 52 } 53 54 case 'MOCK_ACTIVATE': { 55 activeClientIds.add(clientId) 56 57 sendToClient(client, { 58 type: 'MOCKING_ENABLED', 59 payload: true, 60 }) 61 break 62 } 63 64 case 'MOCK_DEACTIVATE': { 65 activeClientIds.delete(clientId) 66 break 67 } 68 69 case 'CLIENT_CLOSED': { 70 activeClientIds.delete(clientId) 71 72 const remainingClients = allClients.filter(client => { 73 return client.id !== clientId 74 }) 75 76 // Unregister itself when there are no more clients 77 if (remainingClients.length === 0) { 78 self.registration.unregister() 79 } 80 81 break 82 } 83 } 84 }) 85 86 // Resolve the "main" client for the given event. 87 // Client that issues a request doesn't necessarily equal the client 88 // that registered the worker. It's with the latter the worker should 89 // communicate with during the response resolving phase. 90 async function resolveMainClient(event) { 91 const client = await self.clients.get(event.clientId) 92 93 if (client.frameType === 'top-level') { 94 return client 95 } 96 97 const allClients = await self.clients.matchAll() 98 99 return allClients 100 .filter(client => { 101 // Get only those clients that are currently visible. 102 return client.visibilityState === 'visible' 103 }) 104 .find(client => { 105 // Find the client ID that's recorded in the 106 // set of clients that have registered the worker. 107 return activeClientIds.has(client.id) 108 }) 109 } 110 111 async function handleRequest(event, requestId) { 112 const client = await resolveMainClient(event) 113 const response = await getResponse(event, client, requestId) 114 115 // Send back the response clone for the "response:*" life-cycle events. 116 // Ensure MSW is active and ready to handle the message, otherwise 117 // this message will pend indefinitely. 118 if (client && activeClientIds.has(client.id)) { 119 ;(async function () { 120 const clonedResponse = response.clone() 121 sendToClient(client, { 122 type: 'RESPONSE', 123 payload: { 124 requestId, 125 type: clonedResponse.type, 126 ok: clonedResponse.ok, 127 status: clonedResponse.status, 128 statusText: clonedResponse.statusText, 129 body: 130 clonedResponse.body === null ? null : await clonedResponse.text(), 131 headers: serializeHeaders(clonedResponse.headers), 132 redirected: clonedResponse.redirected, 133 }, 134 }) 135 })() 136 } 137 138 return response 139 } 140 141 async function getResponse(event, client, requestId) { 142 const { request } = event 143 const requestClone = request.clone() 144 const getOriginalResponse = () => fetch(requestClone) 145 146 // Bypass mocking when the request client is not active. 147 if (!client) { 148 return getOriginalResponse() 149 } 150 151 // Bypass initial page load requests (i.e. static assets). 152 // The absence of the immediate/parent client in the map of the active clients 153 // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet 154 // and is not ready to handle requests. 155 if (!activeClientIds.has(client.id)) { 156 return await getOriginalResponse() 157 } 158 159 // Bypass requests with the explicit bypass header 160 if (requestClone.headers.get(bypassHeaderName) === 'true') { 161 const cleanRequestHeaders = serializeHeaders(requestClone.headers) 162 163 // Remove the bypass header to comply with the CORS preflight check. 164 delete cleanRequestHeaders[bypassHeaderName] 165 166 const originalRequest = new Request(requestClone, { 167 headers: new Headers(cleanRequestHeaders), 168 }) 169 170 return fetch(originalRequest) 171 } 172 173 // Send the request to the client-side MSW. 174 const reqHeaders = serializeHeaders(request.headers) 175 const body = await request.text() 176 177 const clientMessage = await sendToClient(client, { 178 type: 'REQUEST', 179 payload: { 180 id: requestId, 181 url: request.url, 182 method: request.method, 183 headers: reqHeaders, 184 cache: request.cache, 185 mode: request.mode, 186 credentials: request.credentials, 187 destination: request.destination, 188 integrity: request.integrity, 189 redirect: request.redirect, 190 referrer: request.referrer, 191 referrerPolicy: request.referrerPolicy, 192 body, 193 bodyUsed: request.bodyUsed, 194 keepalive: request.keepalive, 195 }, 196 }) 197 198 switch (clientMessage.type) { 199 case 'MOCK_SUCCESS': { 200 return delayPromise( 201 () => respondWithMock(clientMessage), 202 clientMessage.payload.delay 203 ) 204 } 205 206 case 'MOCK_NOT_FOUND': { 207 return getOriginalResponse() 208 } 209 210 case 'NETWORK_ERROR': { 211 const { name, message } = clientMessage.payload 212 const networkError = new Error(message) 213 networkError.name = name 214 215 // Rejecting a request Promise emulates a network error. 216 throw networkError 217 } 218 219 case 'INTERNAL_ERROR': { 220 const parsedBody = JSON.parse(clientMessage.payload.body) 221 222 console.error( 223 `\ 224 [MSW] Uncaught exception in the request handler for "%s %s": 225 226 ${parsedBody.location} 227 228 This exception has been gracefully handled as a 500 response, however, it's strongly recommended to resolve this error, as it indicates a mistake in your code. If you wish to mock an error response, please see this guide: https://mswjs.io/docs/recipes/mocking-error-responses\ 229 `, 230 request.method, 231 request.url 232 ) 233 234 return respondWithMock(clientMessage) 235 } 236 } 237 238 return getOriginalResponse() 239 } 240 241 self.addEventListener('fetch', function (event) { 242 const { request } = event 243 const accept = request.headers.get('accept') || '' 244 245 // Bypass server-sent events. 246 if (accept.includes('text/event-stream')) { 247 return 248 } 249 250 // Bypass navigation requests. 251 if (request.mode === 'navigate') { 252 return 253 } 254 255 // Opening the DevTools triggers the "only-if-cached" request 256 // that cannot be handled by the worker. Bypass such requests. 257 if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { 258 return 259 } 260 261 // Bypass all requests when there are no active clients. 262 // Prevents the self-unregistered worked from handling requests 263 // after it's been deleted (still remains active until the next reload). 264 if (activeClientIds.size === 0) { 265 return 266 } 267 268 const requestId = uuidv4() 269 270 return event.respondWith( 271 handleRequest(event, requestId).catch(error => { 272 if (error.name === 'NetworkError') { 273 console.warn( 274 '[MSW] Successfully emulated a network error for the "%s %s" request.', 275 request.method, 276 request.url 277 ) 278 return 279 } 280 281 // At this point, any exception indicates an issue with the original request/response. 282 console.error( 283 `\ 284 [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.`, 285 request.method, 286 request.url, 287 `${error.name}: ${error.message}` 288 ) 289 }) 290 ) 291 }) 292 293 function serializeHeaders(headers) { 294 const reqHeaders = {} 295 headers.forEach((value, name) => { 296 reqHeaders[name] = reqHeaders[name] 297 ? [].concat(reqHeaders[name]).concat(value) 298 : value 299 }) 300 return reqHeaders 301 } 302 303 function sendToClient(client, message) { 304 return new Promise((resolve, reject) => { 305 const channel = new MessageChannel() 306 307 channel.port1.onmessage = event => { 308 if (event.data && event.data.error) { 309 return reject(event.data.error) 310 } 311 312 resolve(event.data) 313 } 314 315 client.postMessage(JSON.stringify(message), [channel.port2]) 316 }) 317 } 318 319 function delayPromise(cb, duration) { 320 return new Promise(resolve => { 321 setTimeout(() => resolve(cb()), duration) 322 }) 323 } 324 325 function respondWithMock(clientMessage) { 326 return new Response(clientMessage.payload.body, { 327 ...clientMessage.payload, 328 headers: clientMessage.payload.headers, 329 }) 330 } 331 332 function uuidv4() { 333 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 334 const r = (Math.random() * 16) | 0 335 const v = c == 'x' ? r : (r & 0x3) | 0x8 336 return v.toString(16) 337 }) 338 }