text: "use strict";
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.readCommandLineArgs = readCommandLineArgs;
  exports.commandLineOptions = void 0;
  
  var _commandLineArgs = _interopRequireDefault(require("command-line-args"));
  
  var _commandLineUsage = _interopRequireDefault(require("command-line-usage"));
  
  var _path = _interopRequireDefault(require("path"));
  
  var _camelcase = _interopRequireDefault(require("camelcase"));
  
  var _fs = _interopRequireDefault(require("fs"));
  
  var _deepmerge = _interopRequireDefault(require("deepmerge"));
  
  var _utils = require("./utils/utils.js");
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  /* eslint-disable import/no-dynamic-require, global-require */
  const commandLineOptions = [{
    name: 'config',
    alias: 'c',
    type: String,
    description: 'The file to read configuration from (js or json). Config entries are camelCases flags.'
  }, {
    name: 'port',
    alias: 'p',
    type: Number,
    description: 'The port to use. Default: 8080'
  }, {
    name: 'hostname',
    alias: 'h',
    type: String,
    description: 'The hostname to use. Default: localhost'
  }, {
    name: 'open',
    alias: 'o',
    type: String,
    description: 'Opens the browser on app-index, root dir or a custom path.'
  }, {
    name: 'app-index',
    alias: 'a',
    type: String,
    description: "The app's index.html file. When set, serves the index.html for non-file requests. Use this to enable SPA routing."
  }, {
    name: 'root-dir',
    alias: 'r',
    type: String,
    description: 'The root directory to serve files from. Defaults to the current working directory.'
  }, {
    name: 'base-path',
    type: String,
    description: 'Base path the app is served on. This path is only visible in the browser, it is stripped from the request url before resolving files. ' + 'Starts with a / and ends with no/. For example: /my-app, /foo, /foo/bar'
  }, {
    name: 'module-dirs',
    alias: 'm',
    type: String,
    multiple: true,
    description: 'Directories to resolve modules from. Used by node-resolve'
  }, {
    name: 'watch',
    alias: 'w',
    type: Boolean,
    description: 'Reload the browser when files are edited.'
  }, {
    name: 'watch-excludes',
    type: Boolean,
    description: 'Globs to exclude from file watching. Default: node_modules/**'
  }, {
    name: 'http2',
    alias: 't',
    type: Boolean,
    description: 'Serve files over HTTP2. Sets up HTTPS with self-signed certificates or optional custom certificates'
  }, {
    name: 'ssl-key',
    type: String,
    description: 'Path to local .key file for https'
  }, {
    name: 'ssl-cert',
    type: String,
    description: 'Path to local .cert file for https'
  }, {
    name: 'node-resolve',
    alias: 'n',
    type: Boolean,
    description: 'Resolve bare import imports using node resolve.'
  }, {
    name: 'dedupe',
    alias: 'd',
    type: Boolean,
    description: 'Dedupe modules by resolving them always from the root, ensuring only one version of a package is ever resolved.'
  }, {
    name: 'preserve-symlinks',
    type: Boolean,
    description: 'Preserve symlinks when resolving modules. Default false, which is the default node behavior.'
  }, {
    name: 'babel',
    alias: 'b',
    type: Boolean,
    description: 'Transform served code through babel. Requires .babelrc'
  }, {
    name: 'file-extensions',
    type: String,
    multiple: true,
    description: 'Extra file extentions to use when transforming code.'
  }, {
    name: 'babel-exclude',
    type: String,
    multiple: true,
    description: 'Patterns of files to exclude from babel compilation.'
  }, {
    name: 'babel-modern-exclude',
    type: String,
    multiple: true,
    description: 'Patterns of files to exclude from babel compilation on modern browsers.'
  }, {
    name: 'compatibility',
    type: String,
    description: 'Compatibility mode for older browsers. Can be: "auto", "always", "min", "max" or "none". Default "auto"'
  }, {
    name: 'polyfills',
    type: String,
    description: 'Polyfills to load for older browsers. Can be "auto" or "none". Default "auto"'
  }, {
    name: 'debug',
    type: Boolean,
    description: 'Whether to log debug messages'
  }, {
    name: 'help',
    type: Boolean,
    description: 'See all options'
  }];
  /**
   * Reads command line args from arguments array. Defaults to `process.argv`.
   *
   * @param {string[]} [argv]
   * @param {{ defaultConfigDir?: string, defaultConfigName?: string }} config
   * @returns {import('./config.js').Config}
   */
  
  exports.commandLineOptions = commandLineOptions;
  
  function readCommandLineArgs(argv = process.argv, config = {}) {
    const {
      defaultConfigDir = '.',
      defaultConfigName = 'es-dev-server.config.js'
    } = config;
    const dashesArgs = (0, _commandLineArgs.default)(commandLineOptions, {
      argv,
      partial: true
    });
    const openInCommandLineArgs = 'open' in dashesArgs; // convert kebab-case to camelCase
  
    /** @type {object} */
  
    const args = Object.keys(dashesArgs).reduce((acc, key) => {
      acc[(0, _camelcase.default)(key)] = dashesArgs[key];
      return acc;
    }, {});
  
    if (args.debug) {
      (0, _utils.setDebug)(true);
    }
  
    if ('help' in args) {
      /* eslint-disable-next-line no-console */
      console.log((0, _commandLineUsage.default)([{
        header: 'es-dev-server',
        content: `
            A dev server for modern web development workflows.
  
            Usage: \`es-dev-server [options...]\`
          `.trim()
      }, {
        header: 'Global Options',
        optionList: commandLineOptions
      }]));
      process.exit();
    }
  
    let options;
  
    if (args.config) {
      // read config from user provided path
      const configPath = _path.default.join(process.cwd(), args.config);
  
      if (!_fs.default.existsSync(configPath) || !_fs.default.statSync(configPath).isFile()) {
        throw new Error(`Did not find any config file at ${configPath}`);
      }
  
      const fileConfig = require(configPath);
  
      options = (0, _deepmerge.default)(fileConfig, args);
      (0, _utils.logDebug)(`Found a config file at ${configPath}`);
    } else {
      // read default config if present
      const defaultConfigPath = _path.default.join(process.cwd(), defaultConfigDir, defaultConfigName);
  
      if (_fs.default.existsSync(defaultConfigPath) && _fs.default.statSync(defaultConfigPath).isFile()) {
        const fileConfig = require(defaultConfigPath);
  
        options = (0, _deepmerge.default)(fileConfig, args);
        (0, _utils.logDebug)(`Found a default config file at ${defaultConfigPath}`);
      } else {
        // no file config, just command line args
        options = args;
        (0, _utils.logDebug)(`Did not find a default config file at ${defaultConfigPath}`);
      }
    }
  
    let {
      open
    } = options;
  
    if (options.dedupe) {
      options.dedupeModules = options.dedupe;
      delete options.dedupe;
    } // open can be a boolean nor a string. if it's a boolean from command line args,
    // it's passed as null. so if it's not a string or boolean type, we check for the
    // existence of open in the args object, and treat that as true
  
  
    if (typeof open !== 'string' && typeof open !== 'boolean' && openInCommandLineArgs) {
      open = true;
    }
  
    return { ...options,
      open,
      logStartup: true,
      // when used from the command line we log compile errors to the browser,
      // not to the terminal for a better UX
      logCompileErrors: false
    };
  }