"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.bin = void 0;
Object.defineProperty(exports, "loadConfig", {
  enumerable: true,
  get: function () {
    return _cliConfig().default;
  }
});
exports.run = run;
function _chalk() {
  const data = _interopRequireDefault(require("chalk"));
  _chalk = function () {
    return data;
  };
  return data;
}
function _child_process() {
  const data = _interopRequireDefault(require("child_process"));
  _child_process = function () {
    return data;
  };
  return data;
}
function _commander() {
  const data = require("commander");
  _commander = function () {
    return data;
  };
  return data;
}
function _path() {
  const data = _interopRequireDefault(require("path"));
  _path = function () {
    return data;
  };
  return data;
}
function _cliTools() {
  const data = require("@react-native-community/cli-tools");
  _cliTools = function () {
    return data;
  };
  return data;
}
var _commands = require("./commands");
function _cliConfig() {
  const data = _interopRequireDefault(require("@react-native-community/cli-config"));
  _cliConfig = function () {
    return data;
  };
  return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const pkgJson = require('../package.json');
const program = new (_commander().Command)().usage('[command] [options]').version(pkgJson.version, '-v', 'Output the current version').option('--verbose', 'Increase logging verbosity');
const handleError = err => {
  _cliTools().logger.enable();
  if (program.opts().verbose) {
    _cliTools().logger.error(err.message);
  } else {
    // Some error messages (esp. custom ones) might have `.` at the end already.
    const message = err.message.replace(/\.$/, '');
    _cliTools().logger.error(`${message}.`);
  }
  if (err.stack) {
    _cliTools().logger.log(err.stack);
  }
  if (!program.opts().verbose) {
    _cliTools().logger.info(_chalk().default.dim(`Run CLI with ${_chalk().default.reset('--verbose')} ${_chalk().default.dim('flag for more details.')}`));
  }
  process.exit(1);
};
function printExamples(examples) {
  let output = [];
  if (examples && examples.length > 0) {
    const formattedUsage = examples.map(example => `  ${example.desc}: \n  ${_chalk().default.cyan(example.cmd)}`).join('\n\n');
    output = output.concat([_chalk().default.bold('\nExample usage:'), formattedUsage]);
  }
  return output.join('\n').concat('\n');
}

/**
 * Custom type assertion needed for the `makeCommand` conditional
 * types to be properly resolved.
 */
const isDetachedCommand = command => {
  return command.detached === true;
};

/**
 * Attaches a new command onto global `commander` instance.
 *
 * Note that this function takes additional argument of `Config` type in case
 * passed `command` needs it for its execution.
 */
function attachCommand(command, ...rest) {
  const cmd = program.command(command.name).action(async function handleAction(...args) {
    const passedOptions = this.opts();
    const argv = Array.from(args).slice(0, -1);
    try {
      if (isDetachedCommand(command)) {
        await command.func(argv, passedOptions);
      } else {
        await command.func(argv, rest[0], passedOptions);
      }
    } catch (error) {
      handleError(error);
    }
  });
  if (command.description) {
    cmd.description(command.description);
  }
  cmd.addHelpText('after', printExamples(command.examples));
  for (const opt of command.options || []) {
    cmd.option(opt.name, opt.description ?? '', opt.parse || (val => val), typeof opt.default === 'function' ? opt.default(rest[0]) : opt.default);
  }
}
async function run() {
  try {
    await setupAndRun();
  } catch (e) {
    handleError(e);
  }
}
async function setupAndRun() {
  // Commander is not available yet

  // when we run `config`, we don't want to output anything to the console. We
  // expect it to return valid JSON
  if (process.argv.includes('config')) {
    _cliTools().logger.disable();
  }
  _cliTools().logger.setVerbose(process.argv.includes('--verbose'));

  // We only have a setup script for UNIX envs currently
  if (process.platform !== 'win32') {
    const scriptName = 'setup_env.sh';
    const absolutePath = _path().default.join(__dirname, '..', scriptName);
    try {
      _child_process().default.execFileSync(absolutePath, {
        stdio: 'pipe'
      });
    } catch (error) {
      _cliTools().logger.warn(`Failed to run environment setup script "${scriptName}"\n\n${_chalk().default.red(error)}`);
      _cliTools().logger.info(`React Native CLI will continue to run if your local environment matches what React Native expects. If it does fail, check out "${absolutePath}" and adjust your environment to match it.`);
    }
  }
  for (const command of _commands.detachedCommands) {
    attachCommand(command);
  }
  try {
    const config = (0, _cliConfig().default)();
    _cliTools().logger.enable();
    for (const command of [..._commands.projectCommands, ...config.commands]) {
      attachCommand(command, config);
    }
  } catch (error) {
    /**
     * When there is no `package.json` found, the CLI will enter `detached` mode and a subset
     * of commands will be available. That's why we don't throw on such kind of error.
     */
    if (error.message.includes("We couldn't find a package.json")) {
      _cliTools().logger.debug(error.message);
      _cliTools().logger.debug('Failed to load configuration of your project. Only a subset of commands will be available.');
    } else {
      throw new (_cliTools().CLIError)('Failed to load configuration of your project.', error);
    }
  }
  program.parse(process.argv);
}
const bin = require.resolve('./bin');
exports.bin = bin;

//# sourceMappingURL=index.js.map