# All files / lib/util config.js

100% Statements 92/92
100% Branches 12/12
100% Functions 2/2
100% Lines 92/92

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
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    932x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    13x
    13x
    13x
    13x
    13x
    7x
    7x
    13x
    13x
    2x
    2x
    13x
    13x
    2x
    2x
    13x
    13x
    2x
    2x
    13x
    13x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2056x
    2056x
    2056x
    2056x
    2056x
    2056x
    2056x
    2056x
    2056x
    459x
    459x
    2056x
    2056x
    2056x
    2056x
    2056x
    2056x
    2056x
    1596x
    1596x
    1596x
    1596x
    1596x
    5x
    5x
    1596x
    2056x
    2056x
    2056x
    2056x
    8x
    8x
    2056x
    2056x
    2056x
     import process from './process';
    import { Config } from './types';
    import globalThis from './global';

    const { parseInt } = Number;
    const { parse } = JSON;

    /** @type {Config} */
    export const globalConfig = {
      collectMetrics: true,
      executeScripts: true,
    };

    /**
     * Converts input to string and then coerces to the appropriate title.
     *
     * @param {unknown} value
     * @param {string} type
     *
     * @returns {unknown}
     */
    function formatValue(value, type) {
      const valueAsString = String(value);

      switch (type) {
        case 'boolean': {
          return valueAsString !== 'false';
        }

        case 'string': {
          return valueAsString;
        }

        case 'number': {
          return parseInt(valueAsString, 10);
        }

        case 'object': {
          return parse(valueAsString);
        }
      }
    }

    /**
     * Request a configuration value by key. Provide a defaultValue always to ensure
     * proper type lookup. An overrides object can be passed to shortcircuit
     * lookups. Keys are looked up with a DIFF_ prefix when in the query string or
     * environment variable.
     *
     * @param {string} name
     * @param {unknown} defaultValue
     * @param {string} type
     * @param {{[name: string]: any}=} overrides
     *
     * @return {unknown}
     */
    export default function getConfig(name, defaultValue, type = typeof defaultValue, overrides) {
      const { location, URLSearchParams } = globalThis;
      const hasSearchParams = typeof URLSearchParams !== 'undefined';
      const hasLocation = typeof location !== 'undefined';
      const useSearchParams = hasSearchParams && hasLocation;
      const useEnv = process.env;

      // Allow bypassing any lookups if overrides are passed and match the config
      // being looked up.
      if (overrides && name in overrides) {
        return overrides[name];
      }

      // The keyname for lookups via search params or env variable is DIFF_key and
      // is case-insensitive. This is why we lowercaes the entire lookup.
      const keyName = `DIFF_${name.replace(/[^a-zA-Z0-9]/, '')}`;

      // Try URL search params first.
      if (useSearchParams) {
        const searchParams = new URLSearchParams(location.search);
        const lowerKey = keyName.toLowerCase();

        // Use has here, because boolean values can be set with only a key.
        if (searchParams.has(lowerKey)) {
          return formatValue(decodeURIComponent(String(searchParams.get(lowerKey))), type);
        }
      }

      // Try environment variables.
      const upperKey = keyName.toUpperCase();
      if (useEnv && upperKey in process.env) {
        return formatValue(process.env[upperKey.toUpperCase()], type);
      }

      return defaultValue;
    }