All files / src/worker/handlers handleScriptsInjection.ts

90.9% Statements 10/11
50% Branches 1/2
100% Functions 2/2
90.9% Lines 10/11

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55                                            2x     2x   2x 2x 2x   2x     1x   1x                   1x           1x    
import { TypedEnv } from '../types'
import { hasContentType } from '../utils/headers'
import { getScriptUrl } from '../scripts'
import { fetchOrigin } from '../utils/origin'
import { getRoutePrefix } from '../env'
 
type HandleScriptsInjectionParams = {
  request: Request
  env: TypedEnv
}
 
/**
 * Handles the injection of instrumentation scripts into HTML responses.
 * If the response's content type is HTML, the method appends specified scripts to the `<head>` element of the document.
 *
 * @param {Object} params - The parameters for the function.
 * @param {Request} params.request - The incoming HTTP request.
 * @param {Object} params.env - The environment configuration object containing necessary script and resource paths.
 *
 * @return {Promise<Response>} A Promise that resolves to an HTTP Response, potentially modified with injected scripts if the content type is HTML.
 */
export async function handleScriptsInjection({ request, env }: HandleScriptsInjectionParams): Promise<Response> {
  console.info('Injecting instrumentation script for page:', request.url)
 
  // Propagate a request to the origin
  const response = await fetchOrigin(request)
 
  if (hasContentType(response.headers, 'text/html')) {
    try {
      console.info('Received HTML content, injecting agent and instrumentation scripts.')
 
      return new HTMLRewriter()
        .on('head', {
          element(element) {
            console.info('Injecting instrumentation into <head> element.')
 
            element.append(
              `<script defer src="${getScriptUrl('instrumentor.iife.js', getRoutePrefix(env))}"></script>\n`,
              {
                html: true,
              }
            )
          },
        })
        .transform(response)
    } catch (error) {
      console.error('Error injecting instrumentation script:', error)
    }
  } else E{
    console.warn('Received non-HTML content, skipping instrumentation script injection.')
  }
 
  return response
}