<commit_before>const R = require('ramda');
const { EventEmitter } = require('events');
const logger = require('../logger');
const getProxySettings = require('../getProxySettings');
const applyLoggingOptions = require('./applyLoggingOptions');
const validateConfig = require('./validateConfig');
const { normalizeConfig } = require('./normalizeConfig');

const defaultConfig = {
  http: {},
  server: null,
  // emitter: new EventEmitter(), // TODO Merge + preserve prototype?
  custom: {
    cwd: process.cwd(),
  },
  path: [],
  apiDescriptions: [],
  'dry-run': false,
  reporter: null,
  output: null,
  header: null,
  user: null,
  'inline-errors': false,
  details: false,
  method: [],
  only: [],
  color: true,
  loglevel: 'warn',
  sorted: false,
  names: false,
  hookfiles: [],
  language: 'nodejs',
  'hooks-worker-timeout': 5000,
  'hooks-worker-connect-timeout': 1500,
  'hooks-worker-connect-retry': 500,
  'hooks-worker-after-connect-wait': 100,
  'hooks-worker-term-timeout': 5000,
  'hooks-worker-term-retry': 500,
  'hooks-worker-handler-host': '127.0.0.1',
  'hooks-worker-handler-port': 61321,
};

/**
 * Flattens giving configuration Object, removing nested "options" key.
 * This makes it possible to use nested "options" key without introducing
 * a breaking change to the library's public API.
 * TODO Remove this method after "options" key is removed in the next
 * major version. Document the removal of "options" in the Dredd docs.
 */
function flattenConfig(config) {
  const nestedOptions = R.prop('options', config);
  const rootOptions = R.omit(['options'], config);

  if (nestedOptions) {
    logger.warn('Deprecated usage of `options` in Dredd configuration.');
  }

  return R.mergeDeepLeft(nestedOptions || {}, rootOptions);
}

function resolveConfig(config) {
  const inConfig = R.compose(
    // Set "emitter" property explicitly to preserve its prototype.
    // During deep merge Ramda omits prototypes, breaking emitter.
    R.assoc('emitter', R.propOr(new EventEmitter(), 'emitter', config)),
    R.mergeDeepRight(defaultConfig),
    flattenConfig
  )(config);

  // Validate Dredd configuration
  const { warnings, errors } = validateConfig(inConfig);
  warnings.forEach(message => logger.warn(message));
  errors.forEach(message => logger.error(message));

  // Fail fast upon any Dredd configuration errors
  if (errors.length > 0) {
    throw new Error('Could not configure Dredd');
  }

  return {
    config: normalizeConfig(inConfig),
    warnings,
    errors,
  };
}

function applyConfiguration(config) {
  const { config: resolvedConfig } = resolveConfig(config);

  applyLoggingOptions(resolvedConfig);

  // Log information about the HTTP proxy settings
  const proxySettings = getProxySettings(process.env);
  if (proxySettings.length) {
    logger.warn(
      `HTTP(S) proxy specified by environment variables: ${proxySettings.join(', ')}. `
      + 'Please read documentation on how Dredd works with proxies: '
      + 'https://dredd.org/en/latest/how-it-works/#using-https-proxy'
    );
  }

  return resolvedConfig;
}

module.exports = {
  applyConfiguration,
  resolveConfig,
  _utils: {
    defaultConfig,
  },
};
<commit_msg>refactor: add explanatory comment upon configuration emitter<commit_after>const R = require('ramda');
const { EventEmitter } = require('events');

const logger = require('../logger');
const getProxySettings = require('../getProxySettings');
const applyLoggingOptions = require('./applyLoggingOptions');
const validateConfig = require('./validateConfig');
const { normalizeConfig } = require('./normalizeConfig');

const DEFAULT_CONFIG = {
  http: {},
  server: null,
  // TODO Find a way to deep merge default and custom configs
  // while presering prototypes.
  // When the next line is uncommented, "emitter" property will be processed
  // during "R.mergeDeepX" call, resulting into EventEmitter's instance prototype
  // not being copied. This breaks event emitter.
  // emitter: new EventEmitter(),
  custom: {
    cwd: process.cwd(),
  },
  path: [],
  apiDescriptions: [],
  'dry-run': false,
  reporter: null,
  output: null,
  header: null,
  user: null,
  'inline-errors': false,
  details: false,
  method: [],
  only: [],
  color: true,
  loglevel: 'warn',
  sorted: false,
  names: false,
  hookfiles: [],
  language: 'nodejs',
  'hooks-worker-timeout': 5000,
  'hooks-worker-connect-timeout': 1500,
  'hooks-worker-connect-retry': 500,
  'hooks-worker-after-connect-wait': 100,
  'hooks-worker-term-timeout': 5000,
  'hooks-worker-term-retry': 500,
  'hooks-worker-handler-host': '127.0.0.1',
  'hooks-worker-handler-port': 61321,
};

/**
 * Flattens given configuration Object, removing nested "options" key.
 * This makes it possible to use nested "options" key without introducing
 * a breaking change to the library's public API.
 * TODO Remove this method after "options" key is removed in the next
 * major version. Document the removal of "options" in the Dredd docs.
 */
function flattenConfig(config) {
  const nestedOptions = R.prop('options', config);
  const rootOptions = R.omit(['options'], config);

  if (nestedOptions) {
    logger.warn('Deprecated usage of `options` in Dredd configuration.');
  }

  return R.mergeDeepLeft(nestedOptions || {}, rootOptions);
}

function resolveConfig(config) {
  const inConfig = R.compose(
    // Set "emitter" property explicitly to preserve its prototype.
    // During deep merge Ramda omits prototypes, breaking emitter.
    R.assoc('emitter', R.propOr(new EventEmitter(), 'emitter', config)),
    R.mergeDeepRight(DEFAULT_CONFIG),
    flattenConfig
  )(config);

  // Validate Dredd configuration
  const { warnings, errors } = validateConfig(inConfig);
  warnings.forEach(message => logger.warn(message));
  errors.forEach(message => logger.error(message));

  // Fail fast upon any Dredd configuration errors
  if (errors.length > 0) {
    throw new Error('Could not configure Dredd');
  }

  return {
    config: normalizeConfig(inConfig),
    warnings,
    errors,
  };
}

function applyConfiguration(config) {
  const { config: resolvedConfig } = resolveConfig(config);

  applyLoggingOptions(resolvedConfig);

  // Log information about the HTTP proxy settings
  const proxySettings = getProxySettings(process.env);
  if (proxySettings.length) {
    logger.warn(
      `HTTP(S) proxy specified by environment variables: ${proxySettings.join(', ')}. `
      + 'Please read documentation on how Dredd works with proxies: '
      + 'https://dredd.org/en/latest/how-it-works/#using-https-proxy'
    );
  }

  return resolvedConfig;
}

module.exports = {
  applyConfiguration,
  resolveConfig,
  _utils: {
    DEFAULT_CONFIG,
  },
};

{'fraction_non_alphanumeric': 0.13406987160346373, 'fraction_numerical': 0.009853687667960586, 'mean_word_length': 3.9880863737900225, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5436578', 'n_tokens_mistral': 2052, 'n_tokens_neox': 1986, 'n_words': 558}