"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

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

function _bluebird() {
  const data = require("bluebird");

  _bluebird = function () {
    return data;
  };

  return data;
}

function _ramda() {
  const data = _interopRequireDefault(require("ramda"));

  _ramda = function () {
    return data;
  };

  return data;
}

function _consumer() {
  const data = require("../../../consumer");

  _consumer = function () {
    return data;
  };

  return data;
}

function _componentsList() {
  const data = _interopRequireDefault(require("../../../consumer/component/components-list"));

  _componentsList = function () {
    return data;
  };

  return data;
}

function _loader() {
  const data = _interopRequireDefault(require("../../../cli/loader"));

  _loader = function () {
    return data;
  };

  return data;
}

function _loaderMessages() {
  const data = require("../../../cli/loader/loader-messages");

  _loaderMessages = function () {
    return data;
  };

  return data;
}

function _bitId() {
  const data = require("../../../bit-id");

  _bitId = function () {
    return data;
  };

  return data;
}

function _idExportedAlready() {
  const data = _interopRequireDefault(require("./exceptions/id-exported-already"));

  _idExportedAlready = function () {
    return data;
  };

  return data;
}

function _logger() {
  const data = _interopRequireDefault(require("../../../logger/logger"));

  _logger = function () {
    return data;
  };

  return data;
}

function _analytics() {
  const data = require("../../../analytics/analytics");

  _analytics = function () {
    return data;
  };

  return data;
}

function _ejectComponents() {
  const data = _interopRequireDefault(require("../../../consumer/component-ops/eject-components"));

  _ejectComponents = function () {
    return data;
  };

  return data;
}

function _hasWildcard() {
  const data = _interopRequireDefault(require("../../../utils/string/has-wildcard"));

  _hasWildcard = function () {
    return data;
  };

  return data;
}

function _exportScopeComponents() {
  const data = require("../../../scope/component-ops/export-scope-components");

  _exportScopeComponents = function () {
    return data;
  };

  return data;
}

function _links() {
  const data = require("../../../links");

  _links = function () {
    return data;
  };

  return data;
}

function _bitMap() {
  const data = _interopRequireDefault(require("../../../consumer/bit-map/bit-map"));

  _bitMap = function () {
    return data;
  };

  return data;
}

var _default =
/*#__PURE__*/
function () {
  var _exportAction = (0, _bluebird().coroutine)(function* (ids, remote, eject) {
    const {
      updatedIds: componentsIds,
      nonExistOnBitMap
    } = yield exportComponents(ids, remote);
    let ejectResults;
    if (eject) ejectResults = yield ejectExportedComponents(componentsIds);
    return {
      componentsIds,
      nonExistOnBitMap,
      ejectResults
    };
  });

  function exportAction(_x, _x2, _x3) {
    return _exportAction.apply(this, arguments);
  }

  return exportAction;
}();

exports.default = _default;

function exportComponents(_x4, _x5) {
  return _exportComponents.apply(this, arguments);
}

function _exportComponents() {
  _exportComponents = (0, _bluebird().coroutine)(function* (ids, remote) {
    const consumer = yield (0, _consumer().loadConsumer)();
    const idsToExport = yield getComponentsToExport(ids, consumer, remote); // todo: what happens when some failed? we might consider avoid Promise.all
    // in case we don't have anything to export

    if (_ramda().default.isEmpty(idsToExport)) return {
      updatedIds: [],
      nonExistOnBitMap: []
    };
    const componentsIds = yield (0, _exportScopeComponents().exportMany)(consumer.scope, idsToExport, remote, undefined);

    const {
      updatedIds,
      nonExistOnBitMap
    } = _updateIdsOnBitMap(consumer.bitMap, componentsIds);

    yield linkComponents(updatedIds, consumer);

    _analytics().Analytics.setExtraData('num_components', componentsIds.length); // it is important to have consumer.onDestroy() before running the eject operation, we want the
    // export and eject operations to function independently. we don't want to lose the changes to
    // .bitmap file done by the export action in case the eject action has failed.


    yield consumer.onDestroy();
    return {
      updatedIds,
      nonExistOnBitMap
    };
  });
  return _exportComponents.apply(this, arguments);
}

function _updateIdsOnBitMap(bitMap, componentsIds) {
  const updatedIds = [];
  const nonExistOnBitMap = [];
  componentsIds.forEach(componentsId => {
    const resultId = bitMap.updateComponentId(componentsId, true);
    if (resultId.hasVersion()) updatedIds.push(resultId);else nonExistOnBitMap.push(resultId);
  });
  return {
    updatedIds,
    nonExistOnBitMap
  };
}

function getComponentsToExport(_x6, _x7, _x8) {
  return _getComponentsToExport.apply(this, arguments);
}

function _getComponentsToExport() {
  _getComponentsToExport = (0, _bluebird().coroutine)(function* (ids, consumer, remote) {
    const componentsList = new (_componentsList().default)(consumer);
    const idsHaveWildcard = (0, _hasWildcard().default)(ids);

    if (!ids || !ids.length || idsHaveWildcard) {
      _loader().default.start(_loaderMessages().BEFORE_LOADING_COMPONENTS);

      const exportPendingComponents = yield componentsList.listExportPendingComponentsIds();
      const componentsToExport = idsHaveWildcard // $FlowFixMe ids are set at this point
      ? _componentsList().default.filterComponentsByWildcard(exportPendingComponents, ids) : exportPendingComponents;
      const loaderMsg = componentsToExport.length > 1 ? _loaderMessages().BEFORE_EXPORTS : _loaderMessages().BEFORE_EXPORT;

      _loader().default.start(loaderMsg);

      return componentsToExport;
    }

    const idsToExportP = ids.map(
    /*#__PURE__*/
    function () {
      var _ref = (0, _bluebird().coroutine)(function* (id) {
        const parsedId = yield getParsedId(consumer, id);
        const status = yield consumer.getComponentStatusById(parsedId); // don't allow to re-export an exported component unless it's being exported to another scope

        if (!status.staged && parsedId.scope === remote) {
          throw new (_idExportedAlready().default)(parsedId.toString(), remote);
        }

        return parsedId;
      });

      return function (_x14) {
        return _ref.apply(this, arguments);
      };
    }());

    _loader().default.start(_loaderMessages().BEFORE_EXPORT); // show single export


    const idsToExport = yield Promise.all(idsToExportP);
    return _bitId().BitIds.fromArray(idsToExport);
  });
  return _getComponentsToExport.apply(this, arguments);
}

function getParsedId(_x9, _x10) {
  return _getParsedId.apply(this, arguments);
}

function _getParsedId() {
  _getParsedId = (0, _bluebird().coroutine)(function* (consumer, id) {
    // reason why not calling `consumer.getParsedId()` first is because a component might not be on
    // .bitmap and only in the scope. we support this case and enable to export
    const parsedId = yield consumer.scope.getParsedId(id);
    if (parsedId.hasScope()) return parsedId; // parsing id from the scope, doesn't provide the scope-name in case it's missing, in this case
    // get the id including the scope from the consumer.

    try {
      return consumer.getParsedId(id);
    } catch (err) {
      // not in the consumer, just return the one parsed without the scope name
      return parsedId;
    }
  });
  return _getParsedId.apply(this, arguments);
}

function linkComponents(_x11, _x12) {
  return _linkComponents.apply(this, arguments);
}

function _linkComponents() {
  _linkComponents = (0, _bluebird().coroutine)(function* (ids, consumer) {
    // we don't have much of a choice here, we have to load all the exported components in order to link them
    // some of the components might be authored, some might be imported.
    // when a component has dists, we need the consumer-component object to retrieve the dists info.
    const components = yield Promise.all(ids.map(id => consumer.loadComponentFromModel(id)));
    const nodeModuleLinker = new (_links().NodeModuleLinker)(components, consumer, consumer.bitMap);
    yield nodeModuleLinker.link();
  });
  return _linkComponents.apply(this, arguments);
}

function ejectExportedComponents(_x13) {
  return _ejectExportedComponents.apply(this, arguments);
}

function _ejectExportedComponents() {
  _ejectExportedComponents = (0, _bluebird().coroutine)(function* (componentsIds) {
    const consumer = yield (0, _consumer().loadConsumer)(undefined, true);
    let ejectResults;

    try {
      const ejectComponents = new (_ejectComponents().default)(consumer, componentsIds);
      ejectResults = yield ejectComponents.eject();
    } catch (err) {
      _logger().default.error(err);

      const ejectErr = `The components ${componentsIds.map(c => c.toString()).join(', ')} were exported successfully.
    However, the eject operation has failed due to an error: ${err.msg || err}`;
      throw new Error(ejectErr);
    } // run the consumer.onDestroy() again, to write the changes done by the eject action to .bitmap


    yield consumer.onDestroy();
    return ejectResults;
  });
  return _ejectExportedComponents.apply(this, arguments);
}