export function applyConfigToArgv()

in src/config.js [38:140]


export function applyConfigToArgv({
  argv,
  argvFromCLI,
  configObject,
  options,
  configFileName,
}) {
  let newArgv = { ...argv };

  for (const option of Object.keys(configObject)) {
    if (camelCase(option) !== option) {
      throw new UsageError(
        `The config option "${option}" must be ` +
          `specified in camel case: "${camelCase(option)}"`,
      );
    }

    // A config option cannot be a sub-command config
    // object if it is an array.
    if (
      !Array.isArray(configObject[option]) &&
      typeof options[option] === 'object' &&
      typeof configObject[option] === 'object'
    ) {
      // Descend into the nested configuration for a sub-command.
      newArgv = applyConfigToArgv({
        argv: newArgv,
        argvFromCLI,
        configObject: configObject[option],
        options: options[option],
        configFileName,
      });
      continue;
    }

    const decamelizedOptName = decamelize(option, { separator: '-' });

    if (typeof options[decamelizedOptName] !== 'object') {
      throw new UsageError(
        `The config file at ${configFileName} specified ` +
          `an unknown option: "${option}"`,
      );
    }
    if (options[decamelizedOptName].type === undefined) {
      // This means yargs option type wasn't not defined correctly
      throw new WebExtError(`Option: ${option} was defined without a type.`);
    }

    const expectedType =
      options[decamelizedOptName].type === 'count'
        ? 'number'
        : options[decamelizedOptName].type;

    const optionType = Array.isArray(configObject[option])
      ? 'array'
      : typeof configObject[option];

    if (optionType !== expectedType) {
      throw new UsageError(
        `The config file at ${configFileName} specified ` +
          `the type of "${option}" incorrectly as "${optionType}"` +
          ` (expected type "${expectedType}")`,
      );
    }

    let defaultValue;
    if (options[decamelizedOptName]) {
      if (options[decamelizedOptName].default !== undefined) {
        defaultValue = options[decamelizedOptName].default;
      } else if (expectedType === 'boolean') {
        defaultValue = false;
      }
    }

    // This is our best effort (without patching yargs) to detect
    // if a value was set on the CLI instead of in the config.
    // It looks for a default value and if the argv value is
    // different, it assumes that the value was configured on the CLI.

    const wasValueSetOnCLI =
      typeof argvFromCLI[option] !== 'undefined' &&
      argvFromCLI[option] !== defaultValue;
    if (wasValueSetOnCLI) {
      log.debug(
        `Favoring CLI: ${option}=${argvFromCLI[option]} over ` +
          `configuration: ${option}=${configObject[option]}`,
      );
      newArgv[option] = argvFromCLI[option];
      continue;
    }

    newArgv[option] = configObject[option];

    const coerce = options[decamelizedOptName].coerce;
    if (coerce) {
      log.debug(`Calling coerce() on configured value for ${option}`);
      newArgv[option] = coerce(newArgv[option]);
    }

    newArgv[decamelizedOptName] = newArgv[option];
  }
  return newArgv;
}