"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.action = action;
exports.default = void 0;

function _fs() {
  const data = _interopRequireDefault(require("fs"));

  _fs = function () {
    return data;
  };

  return data;
}

function _path() {
  const data = _interopRequireDefault(require("path"));

  _path = function () {
    return data;
  };

  return data;
}

function _chalk() {
  const data = _interopRequireDefault(require("chalk"));

  _chalk = function () {
    return data;
  };

  return data;
}

function _simpleSpinner() {
  const data = _interopRequireDefault(require("@expo/simple-spinner"));

  _simpleSpinner = function () {
    return data;
  };

  return data;
}

function _xdl() {
  const data = require("@expo/xdl");

  _xdl = function () {
    return data;
  };

  return data;
}

function _log() {
  const data = _interopRequireDefault(require("../log"));

  _log = function () {
    return data;
  };

  return data;
}

function _sendTo() {
  const data = _interopRequireDefault(require("../sendTo"));

  _sendTo = function () {
    return data;
  };

  return data;
}

function _exit() {
  const data = require("../exit");

  _exit = function () {
    return data;
  };

  return data;
}

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

async function action(projectDir, options = {}) {
  let channelRe = new RegExp(/^[a-z\d][a-z\d._-]*$/);

  if (options.releaseChannel && !channelRe.test(options.releaseChannel)) {
    _log().default.error('Release channel name can only contain lowercase letters, numbers and special characters . _ and -');

    process.exit(1);
  }

  const hasOptimized = _fs().default.existsSync(_path().default.join(projectDir, '/.expo-shared/assets.json'));

  const nonInteractive = options.parent && options.parent.nonInteractive;

  if (!hasOptimized && !nonInteractive) {
    _log().default.warn('Warning: Your project may contain unoptimized image assets. Smaller image sizes can improve app performance.');

    _log().default.warn(`To compress the images in your project, abort publishing and run ${_chalk().default.bold('expo optimize')}.`);
  }

  const status = await _xdl().Project.currentStatus(projectDir);
  let startedOurOwn = false;

  if (status !== 'running') {
    (0, _log().default)('Unable to find an existing Expo CLI instance for this directory, starting a new one...');
    (0, _exit().installExitHooks)(projectDir);
    const startOpts = {
      reset: options.clear,
      nonPersistent: true
    };

    if (options.maxWorkers) {
      startOpts.maxWorkers = options.maxWorkers;
    }

    await _xdl().Project.startAsync(projectDir, startOpts, !options.quiet);
    startedOurOwn = true;
  }

  let recipient = await _sendTo().default.getRecipient(options.sendTo);
  (0, _log().default)(`Publishing to channel '${options.releaseChannel}'...`);
  const {
    args: {
      sdkVersion
    }
  } = await _xdl().Exp.getPublishInfoAsync(projectDir);
  const buildStatus = await _xdl().Project.buildAsync(projectDir, {
    mode: 'status',
    platform: 'all',
    current: true,
    releaseChannel: options.releaseChannel,
    sdkVersion
  });
  const {
    exp
  } = await _xdl().ProjectUtils.readConfigJsonAsync(projectDir);

  if (buildStatus.userHasBuiltExperienceBefore && !buildStatus.userHasBuiltAppBefore && !options.duringBuild && !exp.isDetached) {
    _log().default.warn('We noticed that you have not built a standalone app with this SDK version and release channel before. ' + 'Remember that OTA updates will only work for builds with matching SDK versions and release channels. ' + 'Read more here: https://docs.expo.io/versions/latest/workflow/publishing/#limitations');
  }

  if (options.quiet) {
    _simpleSpinner().default.start();
  }

  let result;

  try {
    result = await _xdl().Project.publishAsync(projectDir, {
      releaseChannel: options.releaseChannel
    });
    let url = result.url;

    if (options.quiet) {
      _simpleSpinner().default.stop();
    }

    (0, _log().default)('Published');
    (0, _log().default)('Your URL is\n\n' + _chalk().default.underline(url) + '\n');

    _log().default.raw(url);

    if (recipient) {
      await _sendTo().default.sendUrlAsync(url, recipient);
    }
  } finally {
    if (startedOurOwn) {
      await _xdl().Project.stopAsync(projectDir);
    }
  }

  return result;
}

var _default = program => {
  program.command('publish [project-dir]').alias('p').description('Publishes your project to exp.host').option('-q, --quiet', 'Suppress verbose output from the React Native packager.').option('-s, --send-to [dest]', 'A phone number or email address to send a link to').option('-c, --clear', 'Clear the React Native packager cache') // TODO(anp) set a default for this dynamically based on whether we're inside a container?
  .option('--max-workers [num]', 'Maximum number of tasks to allow Metro to spawn.').option('--release-channel <release channel>', "The release channel to publish to. Default is 'default'.", 'default').asyncActionProjectDir(action, true);
};

exports.default = _default;
//# sourceMappingURL=../__sourcemaps__/commands/publish.js.map