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  }