'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _regenerator;

function _load_regenerator() {
  return _regenerator = _interopRequireDefault(require('babel-runtime/regenerator'));
}

var _bluebird;

function _load_bluebird() {
  return _bluebird = require('bluebird');
}

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _fsExtra;

function _load_fsExtra() {
  return _fsExtra = _interopRequireDefault(require('fs-extra'));
}

var _ramdaAdjunct;

function _load_ramdaAdjunct() {
  return _ramdaAdjunct = _interopRequireWildcard(require('ramda-adjunct'));
}

var _path;

function _load_path() {
  return _path = _interopRequireDefault(require('path'));
}

var _componentMap;

function _load_componentMap() {
  return _componentMap = _interopRequireDefault(require('../bit-map/component-map'));
}

var _logger;

function _load_logger() {
  return _logger = _interopRequireDefault(require('../../logger/logger'));
}

var _generalError;

function _load_generalError() {
  return _generalError = _interopRequireDefault(require('../../error/general-error'));
}

var _path2;

function _load_path2() {
  return _path2 = require('../../utils/path');
}

var _constants;

function _load_constants() {
  return _constants = require('../../constants');
}

var _componentNodeModulesPath;

function _load_componentNodeModulesPath() {
  return _componentNodeModulesPath = _interopRequireDefault(require('../../utils/bit/component-node-modules-path'));
}

var _packageJsonUtils;

function _load_packageJsonUtils() {
  return _packageJsonUtils = require('../component/package-json-utils');
}

var _dataToPersist;

function _load_dataToPersist() {
  return _dataToPersist = _interopRequireDefault(require('../component/sources/data-to-persist'));
}

var _removePath;

function _load_removePath() {
  return _removePath = _interopRequireDefault(require('../component/sources/remove-path'));
}

var _bitMap;

function _load_bitMap() {
  return _bitMap = _interopRequireDefault(require('../bit-map/bit-map'));
}

var _configDir;

function _load_configDir() {
  return _configDir = _interopRequireDefault(require('../bit-map/config-dir'));
}

var _envExtension;

function _load_envExtension() {
  return _envExtension = _interopRequireDefault(require('../../extensions/env-extension'));
}

var _componentConfig;

function _load_componentConfig() {
  return _componentConfig = _interopRequireDefault(require('../config/component-config'));
}

var _ejectConf;

function _load_ejectConf() {
  return _ejectConf = require('./eject-conf');
}

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

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

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var ComponentWriter = function () {
  function ComponentWriter(_ref) {
    var component = _ref.component,
        writeToPath = _ref.writeToPath,
        _ref$writeConfig = _ref.writeConfig,
        writeConfig = _ref$writeConfig === undefined ? false : _ref$writeConfig,
        configDir = _ref.configDir,
        _ref$writePackageJson = _ref.writePackageJson,
        writePackageJson = _ref$writePackageJson === undefined ? true : _ref$writePackageJson,
        _ref$override = _ref.override,
        override = _ref$override === undefined ? true : _ref$override,
        _ref$isolated = _ref.isolated,
        isolated = _ref$isolated === undefined ? false : _ref$isolated,
        origin = _ref.origin,
        consumer = _ref.consumer,
        bitMap = _ref.bitMap,
        _ref$writeBitDependen = _ref.writeBitDependencies,
        writeBitDependencies = _ref$writeBitDependen === undefined ? false : _ref$writeBitDependen,
        deleteBitDirContent = _ref.deleteBitDirContent,
        existingComponentMap = _ref.existingComponentMap,
        _ref$excludeRegistryP = _ref.excludeRegistryPrefix,
        excludeRegistryPrefix = _ref$excludeRegistryP === undefined ? false : _ref$excludeRegistryP;

    _classCallCheck(this, ComponentWriter);

    this.component = component;
    this.writeToPath = writeToPath;
    this.writeConfig = writeConfig;
    this.configDir = configDir;
    this.writePackageJson = writePackageJson;
    this.override = override;
    this.isolated = isolated;
    this.origin = origin;
    this.consumer = consumer;
    this.bitMap = bitMap;
    this.writeBitDependencies = writeBitDependencies;
    this.deleteBitDirContent = deleteBitDirContent;
    this.existingComponentMap = existingComponentMap;
    this.excludeRegistryPrefix = excludeRegistryPrefix;
  }

  _createClass(ComponentWriter, [{
    key: 'write',


    /**
     * write the component to the filesystem and update .bitmap with the details.
     *
     * bitMap gets updated before writing the files to the filesystem, because as part of writing the
     * package-json file, the componentMap is needed to be stored with the updated version.
     *
     * when a component is not new, write the files according to the paths in .bitmap.
     */
    value: function () {
      var _ref2 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee() {
        return (_regenerator || _load_regenerator()).default.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                if (this.consumer) {
                  _context.next = 2;
                  break;
                }

                throw new Error('ComponentWriter.write expect to have a consumer');

              case 2:
                _context.next = 4;
                return this.populateComponentsFilesToWrite();

              case 4:
                // $FlowFixMe consumer is set
                this.component.dataToPersist.addBasePath(this.consumer.getPath());
                _context.next = 7;
                return this.component.dataToPersist.persistAllToFS();

              case 7:
                return _context.abrupt('return', this.component);

              case 8:
              case 'end':
                return _context.stop();
            }
          }
        }, _callee, this);
      }));

      function write() {
        return _ref2.apply(this, arguments);
      }

      return write;
    }()
  }, {
    key: 'populateComponentsFilesToWrite',
    value: function () {
      var _ref3 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee2() {
        return (_regenerator || _load_regenerator()).default.wrap(function _callee2$(_context2) {
          while (1) {
            switch (_context2.prev = _context2.next) {
              case 0:
                if (!(!this.component.files || !this.component.files.length)) {
                  _context2.next = 2;
                  break;
                }

                throw new (_generalError || _load_generalError()).default(`Component ${this.component.id.toString()} is invalid as it has no files`);

              case 2:
                this.component.dataToPersist = new (_dataToPersist || _load_dataToPersist()).default();
                this._updateFilesBasePaths();
                this.componentMap = this.existingComponentMap || this.addComponentToBitMap(this.writeToPath);
                this.component.componentMap = this.componentMap;
                this._copyFilesIntoDistsWhenDistsOutsideComponentDir();
                this._determineWhetherToDeleteComponentDirContent();
                _context2.next = 10;
                return this._handlePreviouslyNestedCurrentlyImportedCase();

              case 10:
                this._determineWhetherToWriteConfig();
                this._updateComponentRootPathAccordingToBitMap();
                this._updateBitMapIfNeeded();
                _context2.next = 15;
                return this._updateConsumerConfigIfNeeded();

              case 15:
                this._determineWhetherToWritePackageJson();
                _context2.next = 18;
                return this.populateFilesToWriteToComponentDir();

              case 18:
                return _context2.abrupt('return', this.component);

              case 19:
              case 'end':
                return _context2.stop();
            }
          }
        }, _callee2, this);
      }));

      function populateComponentsFilesToWrite() {
        return _ref3.apply(this, arguments);
      }

      return populateComponentsFilesToWrite;
    }()
  }, {
    key: 'populateFilesToWriteToComponentDir',
    value: function () {
      var _ref4 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee3() {
        var _this = this;

        var dists, resolvedConfigDir, configToWrite, _preparePackageJsonTo, packageJson, distPackageJson, componentConfig;

        return (_regenerator || _load_regenerator()).default.wrap(function _callee3$(_context3) {
          while (1) {
            switch (_context3.prev = _context3.next) {
              case 0:
                if (this.deleteBitDirContent) {
                  this.component.dataToPersist.removePath(new (_removePath || _load_removePath()).default(this.writeToPath));
                }
                this.component.files.forEach(function (file) {
                  return file.override = _this.override;
                });
                this.component.files.map(function (file) {
                  return _this.component.dataToPersist.addFile(file);
                });
                _context3.next = 5;
                return this.component.dists.getDistsToWrite(this.component, this.consumer, false);

              case 5:
                dists = _context3.sent;

                if (dists) this.component.dataToPersist.merge(dists);

                if (!(this.writeConfig && this.consumer)) {
                  _context3.next = 13;
                  break;
                }

                resolvedConfigDir = this.configDir || this.consumer.dirStructure.ejectedEnvsDirStructure;
                _context3.next = 11;
                return this.component.getConfigToWrite(this.consumer, this.bitMap, resolvedConfigDir);

              case 11:
                configToWrite = _context3.sent;

                this.component.dataToPersist.merge(configToWrite.dataToPersist);

              case 13:
                if (!(this.writePackageJson && (this.consumer && this.consumer.isolated || this.writeToPath !== '.'))) {
                  _context3.next = 24;
                  break;
                }

                _preparePackageJsonTo = (0, (_packageJsonUtils || _load_packageJsonUtils()).preparePackageJsonToWrite)(this.consumer, this.component, this.writeToPath, this.override, this.writeBitDependencies, this.excludeRegistryPrefix), packageJson = _preparePackageJsonTo.packageJson, distPackageJson = _preparePackageJsonTo.distPackageJson;
                componentConfig = (_componentConfig || _load_componentConfig()).default.fromComponent(this.component);

                componentConfig.compiler = this.component.compiler ? this.component.compiler.toBitJsonObject('.') : {};
                componentConfig.tester = this.component.tester ? this.component.tester.toBitJsonObject('.') : {};
                packageJson.addOrUpdateProperty('bit', componentConfig.toPlainObject());
                _context3.next = 21;
                return this._populateEnvFilesIfNeeded();

              case 21:
                this.component.dataToPersist.addFile(packageJson.toJSONFile());
                if (distPackageJson) this.component.dataToPersist.addFile(distPackageJson.toJSONFile());
                this.component.packageJsonFile = packageJson;

              case 24:
                if (this.component.license && this.component.license.contents) {
                  this.component.license.updatePaths({ newBase: this.writeToPath });
                  // $FlowFixMe this.component.license is set
                  this.component.license.override = this.override;
                  // $FlowFixMe this.component.license is set
                  this.component.dataToPersist.addFile(this.component.license);
                }

              case 25:
              case 'end':
                return _context3.stop();
            }
          }
        }, _callee3, this);
      }));

      function populateFilesToWriteToComponentDir() {
        return _ref4.apply(this, arguments);
      }

      return populateFilesToWriteToComponentDir;
    }()
  }, {
    key: 'addComponentToBitMap',
    value: function addComponentToBitMap(rootDir) {
      var _this2 = this;

      var filesForBitMap = this.component.files.map(function (file) {
        return { name: file.basename, relativePath: (0, (_path2 || _load_path2()).pathNormalizeToLinux)(file.relative), test: file.test };
      });
      var getConfigDir = function getConfigDir() {
        if (_this2.configDir) return _this2.configDir;
        if (_this2.componentMap) return _this2.componentMap.configDir;
        return undefined;
      };

      return this.bitMap.addComponent({
        componentId: this.component.id,
        files: filesForBitMap,
        mainFile: this.component.mainFile, // $FlowFixMe
        rootDir, // $FlowFixMe
        configDir: getConfigDir(),
        origin: this.origin,
        originallySharedDir: this.component.originallySharedDir,
        wrapDir: this.component.wrapDir
      });
    }
  }, {
    key: '_populateEnvFilesIfNeeded',
    value: function () {
      var _ref5 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee4() {
        var areThereEnvFiles;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee4$(_context4) {
          while (1) {
            switch (_context4.prev = _context4.next) {
              case 0:
                areThereEnvFiles = this.component.compiler && !(_ramdaAdjunct || _load_ramdaAdjunct()).isNilOrEmpty(this.component.compiler.files) || this.component.tester && !(_ramdaAdjunct || _load_ramdaAdjunct()).isNilOrEmpty(this.component.tester.files);

                if (areThereEnvFiles) {
                  _context4.next = 3;
                  break;
                }

                return _context4.abrupt('return');

              case 3:
                if (!this.component.compiler) {
                  _context4.next = 7;
                  break;
                }

                _context4.next = 6;
                return (0, (_ejectConf || _load_ejectConf()).populateEnvFilesToWrite)({
                  configDir: this.writeToPath,
                  env: this.component.compiler,
                  consumer: this.consumer,
                  component: this.component,
                  deleteOldFiles: false,
                  verbose: false
                });

              case 6:
                // $FlowFixMe
                this.component.dataToPersist.merge(this.component.compiler.dataToPersist);

              case 7:
                if (!this.component.tester) {
                  _context4.next = 11;
                  break;
                }

                _context4.next = 10;
                return (0, (_ejectConf || _load_ejectConf()).populateEnvFilesToWrite)({
                  configDir: this.writeToPath,
                  env: this.component.tester,
                  consumer: this.consumer,
                  component: this.component,
                  deleteOldFiles: false,
                  verbose: false
                });

              case 10:
                // $FlowFixMe
                this.component.dataToPersist.merge(this.component.tester.dataToPersist);

              case 11:
                if (!this.writeConfig && !this.configDir && this.component.componentMap) {
                  this.configDir = (_constants || _load_constants()).DEFAULT_EJECTED_ENVS_DIR_PATH;
                  this.component.componentMap.setConfigDir(this.configDir);
                }

              case 12:
              case 'end':
                return _context4.stop();
            }
          }
        }, _callee4, this);
      }));

      function _populateEnvFilesIfNeeded() {
        return _ref5.apply(this, arguments);
      }

      return _populateEnvFilesIfNeeded;
    }()
  }, {
    key: '_copyFilesIntoDistsWhenDistsOutsideComponentDir',
    value: function _copyFilesIntoDistsWhenDistsOutsideComponentDir() {
      if (!this.consumer) return; // not relevant when consumer is not available
      if (!this.consumer.shouldDistsBeInsideTheComponent() && this.component.dists.isEmpty()) {
        // since the dists are set to be outside the components dir, the source files must be saved there
        // otherwise, other components in dists won't be able to link to this component
        this.component.copyFilesIntoDists();
      }
    }
  }, {
    key: '_updateComponentRootPathAccordingToBitMap',
    value: function _updateComponentRootPathAccordingToBitMap() {
      this.writeToPath = this.componentMap.getRootDir();
      this.component.writtenPath = this.writeToPath;
      this._updateFilesBasePaths();
    }

    /**
     * when there is componentMap, this component (with this version or other version) is already part of the project.
     * There are several options as to what was the origin before and what is the origin now and according to this,
     * we update/remove/don't-touch the record in bit.map.
     * 1) current origin is AUTHORED - If the version is the same as before, don't update bit.map. Otherwise, update.
     * 2) current origin is IMPORTED - If the version is the same as before, don't update bit.map. Otherwise, update.
     * one exception is where the origin was NESTED before, in this case, remove the current record and add a new one.
     * this case has been already handled before by this._handlePreviouslyNestedCurrentlyImportedCase();
     * 3) current origin is NESTED - the version can't be the same as before (otherwise it would be ignored before and
     * never reach this function, see @write-components.writeToComponentsDir). Therefore, always add to bit.map.
     */

  }, {
    key: '_updateBitMapIfNeeded',
    value: function _updateBitMapIfNeeded() {
      if (this.isolated) return;
      var componentMapExistWithSameVersion = this.bitMap.isExistWithSameVersion(this.component.id);
      var updateBitMap = !componentMapExistWithSameVersion || this.componentMap.originallySharedDir !== this.component.originallySharedDir;
      if (updateBitMap) {
        if (componentMapExistWithSameVersion) {
          // originallySharedDir has been changed. it affects also the relativePath of the files
          // so it's better to just remove the old record and add a new one
          this.bitMap.removeComponent(this.component.id);
        }
        this.component.componentMap = this.addComponentToBitMap(this.componentMap.rootDir);
      }
    }
  }, {
    key: '_updateConsumerConfigIfNeeded',
    value: function () {
      var _ref6 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee6() {
        var _this3 = this;

        var areEnvsChanged;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee6$(_context6) {
          while (1) {
            switch (_context6.prev = _context6.next) {
              case 0:
                // for authored components there is no bit.json/package.json component specific
                // so if the overrides or envs were changed, it should be written to the consumer-config
                areEnvsChanged = function () {
                  var _ref7 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee5() {
                    var context, compilerFromConsumer, testerFromConsumer, compilerFromComponent, testerFromComponent;
                    return (_regenerator || _load_regenerator()).default.wrap(function _callee5$(_context5) {
                      while (1) {
                        switch (_context5.prev = _context5.next) {
                          case 0:
                            context = { componentDir: _this3.componentMap.getRootDir() };

                            if (!_this3.consumer) {
                              _context5.next = 7;
                              break;
                            }

                            _context5.next = 4;
                            return _this3.consumer.getEnv((_constants || _load_constants()).COMPILER_ENV_TYPE, context);

                          case 4:
                            _context5.t0 = _context5.sent;
                            _context5.next = 8;
                            break;

                          case 7:
                            _context5.t0 = null;

                          case 8:
                            compilerFromConsumer = _context5.t0;

                            if (!_this3.consumer) {
                              _context5.next = 15;
                              break;
                            }

                            _context5.next = 12;
                            return _this3.consumer.getEnv((_constants || _load_constants()).TESTER_ENV_TYPE, context);

                          case 12:
                            _context5.t1 = _context5.sent;
                            _context5.next = 16;
                            break;

                          case 15:
                            _context5.t1 = null;

                          case 16:
                            testerFromConsumer = _context5.t1;
                            compilerFromComponent = _this3.component.compiler ? _this3.component.compiler.toModelObject() : null;
                            testerFromComponent = _this3.component.tester ? _this3.component.tester.toModelObject() : null;
                            return _context5.abrupt('return', (_envExtension || _load_envExtension()).default.areEnvsDifferent(compilerFromConsumer ? compilerFromConsumer.toModelObject() : null, compilerFromComponent) || (_envExtension || _load_envExtension()).default.areEnvsDifferent(testerFromConsumer ? testerFromConsumer.toModelObject() : null, testerFromComponent));

                          case 20:
                          case 'end':
                            return _context5.stop();
                        }
                      }
                    }, _callee5, _this3);
                  }));

                  return function areEnvsChanged() {
                    return _ref7.apply(this, arguments);
                  };
                }();

                if (!(this.componentMap.origin === (_constants || _load_constants()).COMPONENT_ORIGINS.AUTHORED && this.consumer)) {
                  _context6.next = 8;
                  break;
                }

                _context6.t0 = this.consumer.config.overrides;
                _context6.t1 = this.component;
                _context6.next = 6;
                return areEnvsChanged();

              case 6:
                _context6.t2 = _context6.sent;

                _context6.t0.updateOverridesIfChanged.call(_context6.t0, _context6.t1, _context6.t2);

              case 8:
              case 'end':
                return _context6.stop();
            }
          }
        }, _callee6, this);
      }));

      function _updateConsumerConfigIfNeeded() {
        return _ref6.apply(this, arguments);
      }

      return _updateConsumerConfigIfNeeded;
    }()
  }, {
    key: '_determineWhetherToWriteConfig',
    value: function _determineWhetherToWriteConfig() {
      if (this.componentMap.origin === (_constants || _load_constants()).COMPONENT_ORIGINS.AUTHORED) {
        this.writeConfig = false;
      }
    }

    /**
     * don't write the package.json for an authored component, because its dependencies are managed
     * by the root package.json
     */

  }, {
    key: '_determineWhetherToWritePackageJson',
    value: function _determineWhetherToWritePackageJson() {
      this.writePackageJson = this.writePackageJson && this.origin !== (_constants || _load_constants()).COMPONENT_ORIGINS.AUTHORED;
    }

    /**
     * when a user imports a component that was a dependency before, write the component directly
     * into the components directory for an easy access/change. Then, remove the current record from
     * bit.map and add an updated one.
     */

  }, {
    key: '_handlePreviouslyNestedCurrentlyImportedCase',
    value: function () {
      var _ref8 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee7() {
        return (_regenerator || _load_regenerator()).default.wrap(function _callee7$(_context7) {
          while (1) {
            switch (_context7.prev = _context7.next) {
              case 0:
                if (this.consumer) {
                  _context7.next = 2;
                  break;
                }

                return _context7.abrupt('return');

              case 2:
                if (!(this.origin === (_constants || _load_constants()).COMPONENT_ORIGINS.IMPORTED && this.componentMap.origin === (_constants || _load_constants()).COMPONENT_ORIGINS.NESTED)) {
                  _context7.next = 6;
                  break;
                }

                _context7.next = 5;
                return this._cleanOldNestedComponent();

              case 5:
                this.componentMap = this.addComponentToBitMap(this.writeToPath);

              case 6:
              case 'end':
                return _context7.stop();
            }
          }
        }, _callee7, this);
      }));

      function _handlePreviouslyNestedCurrentlyImportedCase() {
        return _ref8.apply(this, arguments);
      }

      return _handlePreviouslyNestedCurrentlyImportedCase;
    }()

    /**
     * For IMPORTED component we have to delete the content of the directory before importing.
     * Otherwise, when the author adds new files outside of the previous originallySharedDir and this user imports them
     * the environment will contain both copies, the old one with the old originallySharedDir and the new one.
     * If a user made changes to the imported component, it will show a warning and stop the process.
     */

  }, {
    key: '_determineWhetherToDeleteComponentDirContent',
    value: function _determineWhetherToDeleteComponentDirContent() {
      if (typeof this.deleteBitDirContent === 'undefined') {
        this.deleteBitDirContent = this.origin === (_constants || _load_constants()).COMPONENT_ORIGINS.IMPORTED;
      }
    }
  }, {
    key: '_updateFilesBasePaths',
    value: function _updateFilesBasePaths() {
      var newBase = this.writeToPath || '.';
      this.component.files.forEach(function (file) {
        return file.updatePaths({ newBase });
      });
      if (!this.component.dists.isEmpty()) {
        this.component.dists.get().forEach(function (dist) {
          return dist.updatePaths({ newBase });
        });
      }
    }
  }, {
    key: '_cleanOldNestedComponent',
    value: function () {
      var _ref9 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee8() {
        var oldLocation;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee8$(_context8) {
          while (1) {
            switch (_context8.prev = _context8.next) {
              case 0:
                if (this.consumer) {
                  _context8.next = 2;
                  break;
                }

                throw new Error('ComponentWriter._cleanOldNestedComponent expect to have a consumer');

              case 2:
                // $FlowFixMe this function gets called when it was previously NESTED, so the rootDir is set
                oldLocation = (_path || _load_path()).default.join(this.consumer.getPath(), this.componentMap.rootDir);

                (_logger || _load_logger()).default.debugAndAddBreadCrumb('component-writer._cleanOldNestedComponent', 'deleting the old directory of a component at {oldLocation}', { oldLocation });
                _context8.next = 6;
                return (_fsExtra || _load_fsExtra()).default.remove(oldLocation);

              case 6:
                _context8.next = 8;
                return this._removeNodeModulesLinksFromDependents();

              case 8:
                this.bitMap.removeComponent(this.component.id);

              case 9:
              case 'end':
                return _context8.stop();
            }
          }
        }, _callee8, this);
      }));

      function _cleanOldNestedComponent() {
        return _ref9.apply(this, arguments);
      }

      return _cleanOldNestedComponent;
    }()
  }, {
    key: '_removeNodeModulesLinksFromDependents',
    value: function () {
      var _ref10 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee9() {
        var _this4 = this;

        var directDependentIds;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee9$(_context9) {
          while (1) {
            switch (_context9.prev = _context9.next) {
              case 0:
                if (this.consumer) {
                  _context9.next = 2;
                  break;
                }

                throw new Error('ComponentWriter._removeNodeModulesLinksFromDependents expect to have a consumer');

              case 2:
                _context9.next = 4;
                return this.consumer.getAuthoredAndImportedDependentsIdsOf([this.component]);

              case 4:
                directDependentIds = _context9.sent;
                _context9.next = 7;
                return Promise.all(directDependentIds.map(function (dependentId) {
                  var dependentComponentMap = _this4.consumer ? _this4.consumer.bitMap.getComponent(dependentId) : null;
                  var relativeLinkPath = _this4.consumer ? (0, (_componentNodeModulesPath || _load_componentNodeModulesPath()).default)(_this4.consumer.config.bindingPrefix, _this4.component.id) : null;
                  var nodeModulesLinkAbs = _this4.consumer && dependentComponentMap && relativeLinkPath ? _this4.consumer.toAbsolutePath((_path || _load_path()).default.join(dependentComponentMap.getRootDir(), relativeLinkPath)) : null;
                  if (nodeModulesLinkAbs) {
                    (_logger || _load_logger()).default.debug(`deleting an obsolete link to node_modules at ${nodeModulesLinkAbs}`);
                  }
                  return nodeModulesLinkAbs ? (_fsExtra || _load_fsExtra()).default.remove(nodeModulesLinkAbs) : Promise.resolve();
                }));

              case 7:
              case 'end':
                return _context9.stop();
            }
          }
        }, _callee9, this);
      }));

      function _removeNodeModulesLinksFromDependents() {
        return _ref10.apply(this, arguments);
      }

      return _removeNodeModulesLinksFromDependents;
    }()
  }, {
    key: '_getConfigDir',
    value: function _getConfigDir() {
      if (this.configDir) return this.configDir;
      if (this.consumer) return this.consumer.dirStructure.ejectedEnvsDirStructure;
      return new (_configDir || _load_configDir()).default((_constants || _load_constants()).DEFAULT_EJECTED_ENVS_DIR_PATH);
    }
  }], [{
    key: 'getInstance',
    value: function getInstance(componentWriterProps) {
      return new ComponentWriter(componentWriterProps);
    }
  }]);

  return ComponentWriter;
}();

exports.default = ComponentWriter;