'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 _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();

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 _path;

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

var _fsExtra;

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

var _ramda;

function _load_ramda() {
  return _ramda = _interopRequireDefault(require('ramda'));
}

var _chalk;

function _load_chalk() {
  return _chalk = _interopRequireDefault(require('chalk'));
}

var _utils;

function _load_utils() {
  return _utils = require('../../utils');
}

var _createSymlinkOrCopy;

function _load_createSymlinkOrCopy() {
  return _createSymlinkOrCopy = _interopRequireDefault(require('../../utils/fs/create-symlink-or-copy'));
}

var _config;

function _load_config() {
  return _config = _interopRequireDefault(require('../config'));
}

var _sources;

function _load_sources() {
  return _sources = require('../component/sources');
}

var _bitId;

function _load_bitId() {
  return _bitId = _interopRequireDefault(require('../../bit-id/bit-id'));
}

var _bitIds;

function _load_bitIds() {
  return _bitIds = _interopRequireDefault(require('../../bit-id/bit-ids'));
}

var _parser;

function _load_parser() {
  return _parser = _interopRequireDefault(require('../../jsdoc/parser'));
}

var _specsResults;

function _load_specsResults() {
  return _specsResults = _interopRequireDefault(require('../specs-results'));
}

var _ejectConf;

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

var _injectConf;

function _load_injectConf() {
  return _injectConf = _interopRequireDefault(require('../component-ops/inject-conf'));
}

var _componentSpecsFailed;

function _load_componentSpecsFailed() {
  return _componentSpecsFailed = _interopRequireDefault(require('../exceptions/component-specs-failed'));
}

var _missingFilesFromComponent;

function _load_missingFilesFromComponent() {
  return _missingFilesFromComponent = _interopRequireDefault(require('./exceptions/missing-files-from-component'));
}

var _componentNotFoundInPath;

function _load_componentNotFoundInPath() {
  return _componentNotFoundInPath = _interopRequireDefault(require('./exceptions/component-not-found-in-path'));
}

var _environment;

function _load_environment() {
  return _environment = _interopRequireDefault(require('../../environment'));
}

var _environment2;

function _load_environment2() {
  return _environment2 = require('../../environment');
}

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 _loader;

function _load_loader() {
  return _loader = _interopRequireDefault(require('../../cli/loader'));
}

var _compilerExtension;

function _load_compilerExtension() {
  return _compilerExtension = _interopRequireDefault(require('../../extensions/compiler-extension'));
}

var _testerExtension;

function _load_testerExtension() {
  return _testerExtension = _interopRequireDefault(require('../../extensions/tester-extension'));
}

var _driver;

function _load_driver() {
  return _driver = require('../../driver');
}

var _loaderMessages;

function _load_loaderMessages() {
  return _loaderMessages = require('../../cli/loader/loader-messages');
}

var _fileSourceNotFound;

function _load_fileSourceNotFound() {
  return _fileSourceNotFound = _interopRequireDefault(require('./exceptions/file-source-not-found'));
}

var _constants;

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

var _componentDependencies;

function _load_componentDependencies() {
  return _componentDependencies = _interopRequireDefault(require('../../scope/component-dependencies'));
}

var _dependencies;

function _load_dependencies() {
  return _dependencies = require('./dependencies');
}

var _dists;

function _load_dists() {
  return _dists = _interopRequireDefault(require('./sources/dists'));
}

var _chalkBox;

function _load_chalkBox() {
  return _chalkBox = require('../../cli/chalk-box');
}

var _externalTestErrors;

function _load_externalTestErrors() {
  return _externalTestErrors = _interopRequireDefault(require('./exceptions/external-test-errors'));
}

var _generalError;

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

var _analytics;

function _load_analytics() {
  return _analytics = require('../../analytics/analytics');
}

var _componentIssuesTemplate;

function _load_componentIssuesTemplate() {
  return _componentIssuesTemplate = require('../../cli/templates/component-issues-template');
}

var _mainFileRemoved;

function _load_mainFileRemoved() {
  return _mainFileRemoved = _interopRequireDefault(require('./exceptions/main-file-removed'));
}

var _envExtension;

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

var _ejectToWorkspace;

function _load_ejectToWorkspace() {
  return _ejectToWorkspace = _interopRequireDefault(require('./exceptions/eject-to-workspace'));
}

var _ejectBoundToWorkspace;

function _load_ejectBoundToWorkspace() {
  return _ejectBoundToWorkspace = _interopRequireDefault(require('./exceptions/eject-bound-to-workspace'));
}

var _version;

function _load_version() {
  return _version = _interopRequireDefault(require('../../version'));
}

var _injectNonEjected;

function _load_injectNonEjected() {
  return _injectNonEjected = _interopRequireDefault(require('./exceptions/inject-non-ejected'));
}

var _configDir;

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

var _buildComponent;

function _load_buildComponent() {
  return _buildComponent = _interopRequireDefault(require('../component-ops/build-component'));
}

var _extensionFileNotFound;

function _load_extensionFileNotFound() {
  return _extensionFileNotFound = _interopRequireDefault(require('../../extensions/exceptions/extension-file-not-found'));
}

var _dataToPersist;

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

var _componentOutOfSync;

function _load_componentOutOfSync() {
  return _componentOutOfSync = _interopRequireDefault(require('../exceptions/component-out-of-sync'));
}

var _componentOverrides;

function _load_componentOverrides() {
  return _componentOverrides = _interopRequireDefault(require('../config/component-overrides'));
}

var _envFactory;

function _load_envFactory() {
  return _envFactory = _interopRequireDefault(require('../../extensions/env-factory'));
}

var _packageJsonFile;

function _load_packageJsonFile() {
  return _packageJsonFile = _interopRequireDefault(require('./package-json-file'));
}

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

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

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

var Component = function () {
  _createClass(Component, [{
    key: 'id',
    // whether a component was loaded from the filesystem or converted from the model
    // always populated when the loadedFromFileSystem is true
    // populated when loadedFromFileSystem is true and it exists in the model
    // used when in the same component, one file requires another file using custom-resolve
    // used by listScope functionality
    // used during tagging process. It's the version that going to be saved or saved already in the model
    // needed for generate links
    get: function get() {
      return new (_bitId || _load_bitId()).default({
        scope: this.scope,
        name: this.name,
        version: this.version
      });
    } // needed when a user adds a package.json file to the component root
    // otherwise they're saved as npm packages.
    // needed to reduce a potentially long path that was used by the author
    // whether stripOriginallySharedDir() method had been called, we don't want to strip it twice

  }, {
    key: 'docs',
    get: function get() {
      if (!this._docs) {
        this._docs = (_ramda || _load_ramda()).default.flatten(this.files.map(function (file) {
          return file.test ? [] : (0, (_parser || _load_parser()).default)(file.contents.toString(), file.relative);
        }));
      }
      return this._docs;
    }
  }, {
    key: 'driver',
    get: function get() {
      if (!this._driver) {
        this._driver = (_driver || _load_driver()).Driver.load(this.lang);
      }
      return this._driver;
    }
  }]);

  function Component(_ref) {
    var name = _ref.name,
        version = _ref.version,
        scope = _ref.scope,
        files = _ref.files,
        lang = _ref.lang,
        bindingPrefix = _ref.bindingPrefix,
        mainFile = _ref.mainFile,
        compiler = _ref.compiler,
        tester = _ref.tester,
        bitJson = _ref.bitJson,
        dependencies = _ref.dependencies,
        devDependencies = _ref.devDependencies,
        compilerDependencies = _ref.compilerDependencies,
        testerDependencies = _ref.testerDependencies,
        flattenedDependencies = _ref.flattenedDependencies,
        flattenedDevDependencies = _ref.flattenedDevDependencies,
        flattenedCompilerDependencies = _ref.flattenedCompilerDependencies,
        flattenedTesterDependencies = _ref.flattenedTesterDependencies,
        packageDependencies = _ref.packageDependencies,
        devPackageDependencies = _ref.devPackageDependencies,
        peerPackageDependencies = _ref.peerPackageDependencies,
        compilerPackageDependencies = _ref.compilerPackageDependencies,
        testerPackageDependencies = _ref.testerPackageDependencies,
        overrides = _ref.overrides,
        docs = _ref.docs,
        dists = _ref.dists,
        mainDistFile = _ref.mainDistFile,
        specsResults = _ref.specsResults,
        license = _ref.license,
        log = _ref.log,
        deprecated = _ref.deprecated,
        origin = _ref.origin,
        customResolvedPaths = _ref.customResolvedPaths;

    _classCallCheck(this, Component);

    this.manuallyRemovedDependencies = {};
    this.manuallyAddedDependencies = {};
    this.dependenciesSavedAsComponents = true;
    this.loadedFromFileSystem = false;

    this.name = name;
    this.version = version;
    this.scope = scope;
    this.files = files;
    this.lang = lang || (_constants || _load_constants()).DEFAULT_LANGUAGE;
    this.bindingPrefix = bindingPrefix || (_constants || _load_constants()).DEFAULT_BINDINGS_PREFIX;
    this.mainFile = (_path || _load_path()).default.normalize(mainFile);
    this.compiler = compiler;
    this.tester = tester;
    this.bitJson = bitJson;
    this.setDependencies(dependencies);
    this.setDevDependencies(devDependencies);
    this.setCompilerDependencies(compilerDependencies);
    this.setTesterDependencies(testerDependencies);
    this.flattenedDependencies = flattenedDependencies || new (_bitIds || _load_bitIds()).default();
    this.flattenedDevDependencies = flattenedDevDependencies || new (_bitIds || _load_bitIds()).default();
    this.flattenedCompilerDependencies = flattenedCompilerDependencies || new (_bitIds || _load_bitIds()).default();
    this.flattenedTesterDependencies = flattenedTesterDependencies || new (_bitIds || _load_bitIds()).default();
    this.packageDependencies = packageDependencies || {};
    this.devPackageDependencies = devPackageDependencies || {};
    this.peerPackageDependencies = peerPackageDependencies || {};
    this.compilerPackageDependencies = compilerPackageDependencies || {};
    this.testerPackageDependencies = testerPackageDependencies || {};
    this.overrides = overrides;
    this._docs = docs;
    this.setDists(dists, mainDistFile ? (_path || _load_path()).default.normalize(mainDistFile) : null);
    this.specsResults = specsResults;
    this.license = license;
    this.log = log;
    this.deprecated = deprecated || false;
    this.origin = origin;
    this.customResolvedPaths = customResolvedPaths || [];
    this.validateComponent();
  }

  _createClass(Component, [{
    key: 'validateComponent',
    value: function validateComponent() {
      var _this = this;

      var nonEmptyFields = ['name', 'mainFile'];
      nonEmptyFields.forEach(function (field) {
        if (!_this[field]) {
          throw new (_generalError || _load_generalError()).default(`failed loading a component ${_this.id}, the field "${field}" can't be empty`);
        }
      });
    }

    /**
     * Warning: this method does not return a deep copy for objects properties except dependencies and devDependencies
     * Implement deep copy of other properties if needed
     */

  }, {
    key: 'clone',
    value: function clone() {
      // $FlowFixMe
      var newInstance = Object.assign(Object.create(Object.getPrototypeOf(this)), this);
      newInstance.setDependencies(this.dependencies.getClone());
      newInstance.setDevDependencies(this.devDependencies.getClone());
      newInstance.setCompilerDependencies(this.compilerDependencies.getClone());
      newInstance.setTesterDependencies(this.testerDependencies.getClone());
      newInstance.overrides = this.overrides.clone();
      return newInstance;
    }
  }, {
    key: 'getTmpFolder',
    value: function getTmpFolder() {
      var workspacePrefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';

      var folder = (_path || _load_path()).default.join(workspacePrefix, (_constants || _load_constants()).BIT_WORKSPACE_TMP_DIRNAME, this.id.name);
      if (this.componentMap) {
        var componentDir = this.componentMap.getComponentDir();
        if (componentDir) {
          folder = (_path || _load_path()).default.join(workspacePrefix, componentDir, (_constants || _load_constants()).BIT_WORKSPACE_TMP_DIRNAME);
        }
      }
      // Isolated components (for ci-update for example)
      if (this.isolatedEnvironment && this.writtenPath) {
        // Do not join the workspacePrefix since the written path is already a full path
        folder = (_path || _load_path()).default.join(this.writtenPath, (_constants || _load_constants()).BIT_WORKSPACE_TMP_DIRNAME);
      }
      return folder;
    }
  }, {
    key: 'setDependencies',
    value: function setDependencies(dependencies) {
      this.dependencies = new (_dependencies || _load_dependencies()).Dependencies(dependencies);
    }
  }, {
    key: 'setDevDependencies',
    value: function setDevDependencies(devDependencies) {
      this.devDependencies = new (_dependencies || _load_dependencies()).Dependencies(devDependencies);
    }
  }, {
    key: 'setCompilerDependencies',
    value: function setCompilerDependencies(compilerDependencies) {
      this.compilerDependencies = new (_dependencies || _load_dependencies()).Dependencies(compilerDependencies);
    }
  }, {
    key: 'setTesterDependencies',
    value: function setTesterDependencies(testerDependencies) {
      this.testerDependencies = new (_dependencies || _load_dependencies()).Dependencies(testerDependencies);
    }
  }, {
    key: 'setDists',
    value: function setDists(dists, mainDistFile) {
      this.dists = new (_dists || _load_dists()).default(dists, mainDistFile);
    }
  }, {
    key: 'getFileExtension',
    value: function getFileExtension() {
      switch (this.lang) {
        case (_constants || _load_constants()).DEFAULT_LANGUAGE:
        default:
          return 'js';
      }
    }
  }, {
    key: 'getDetachedCompiler',
    value: function () {
      var _ref2 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee(consumer) {
        return (_regenerator || _load_regenerator()).default.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                return _context.abrupt('return', this._isEnvDetach(consumer, (_constants || _load_constants()).COMPILER_ENV_TYPE));

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

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

      return getDetachedCompiler;
    }()
  }, {
    key: 'getDetachedTester',
    value: function () {
      var _ref3 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee2(consumer) {
        return (_regenerator || _load_regenerator()).default.wrap(function _callee2$(_context2) {
          while (1) {
            switch (_context2.prev = _context2.next) {
              case 0:
                return _context2.abrupt('return', this._isEnvDetach(consumer, (_constants || _load_constants()).TESTER_ENV_TYPE));

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

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

      return getDetachedTester;
    }()
  }, {
    key: '_isEnvDetach',
    value: function () {
      var _ref4 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee3(consumer, envType) {
        var context, fromConsumer, fromComponent;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee3$(_context3) {
          while (1) {
            switch (_context3.prev = _context3.next) {
              case 0:
                if (!(this.origin !== (_constants || _load_constants()).COMPONENT_ORIGINS.AUTHORED || !consumer)) {
                  _context3.next = 2;
                  break;
                }

                return _context3.abrupt('return', true);

              case 2:
                context = { workspaceDir: consumer.getPath() };
                _context3.next = 5;
                return consumer.getEnv(envType, context);

              case 5:
                fromConsumer = _context3.sent;
                fromComponent = this[envType] ? this[envType].toModelObject() : null;
                return _context3.abrupt('return', (_envExtension || _load_envExtension()).default.areEnvsDifferent(fromConsumer ? fromConsumer.toModelObject() : null, fromComponent));

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

      function _isEnvDetach(_x4, _x5) {
        return _ref4.apply(this, arguments);
      }

      return _isEnvDetach;
    }()
  }, {
    key: '_getHomepage',
    value: function _getHomepage() {
      // TODO: Validate somehow that this scope is really on bitsrc (maybe check if it contains . ?)
      var homepage = this.scope ? `https://${(_constants || _load_constants()).BASE_WEB_DOMAIN}/${this.scope.replace('.', '/')}/${this.name}` : undefined;
      return homepage;
    }
  }, {
    key: 'writeConfig',
    value: function () {
      var _ref5 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee4(consumer, configDir) {
        var ejectConfData;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee4$(_context4) {
          while (1) {
            switch (_context4.prev = _context4.next) {
              case 0:
                _context4.next = 2;
                return this.getConfigToWrite(consumer, consumer.bitMap, configDir);

              case 2:
                ejectConfData = _context4.sent;

                if (consumer) ejectConfData.dataToPersist.addBasePath(consumer.getPath());
                _context4.next = 6;
                return ejectConfData.dataToPersist.persistAllToFS();

              case 6:
                return _context4.abrupt('return', ejectConfData);

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

      function writeConfig(_x6, _x7) {
        return _ref5.apply(this, arguments);
      }

      return writeConfig;
    }()
  }, {
    key: 'getConfigToWrite',
    value: function () {
      var _ref6 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee5(consumer, bitMap, configDir) {
        var componentMap, configDirInstance, isCompilerDetached, isTesterDetached, res;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee5$(_context5) {
          while (1) {
            switch (_context5.prev = _context5.next) {
              case 0:
                this.componentMap = this.componentMap || bitMap.getComponentIfExist(this.id);
                componentMap = this.componentMap;

                if (componentMap) {
                  _context5.next = 4;
                  break;
                }

                throw new (_generalError || _load_generalError()).default('could not find component in the .bitmap file');

              case 4:
                configDirInstance = typeof configDir === 'string' ? new (_configDir || _load_configDir()).default(configDir) : configDir.clone();

                if (!configDirInstance.isWorkspaceRoot) {
                  _context5.next = 7;
                  break;
                }

                throw new (_ejectToWorkspace || _load_ejectToWorkspace()).default();

              case 7:
                if (!(componentMap.origin === (_constants || _load_constants()).COMPONENT_ORIGINS.AUTHORED)) {
                  _context5.next = 16;
                  break;
                }

                _context5.next = 10;
                return this.getDetachedCompiler(consumer);

              case 10:
                isCompilerDetached = _context5.sent;
                _context5.next = 13;
                return this.getDetachedTester(consumer);

              case 13:
                isTesterDetached = _context5.sent;

                if (!(!isCompilerDetached && !isTesterDetached)) {
                  _context5.next = 16;
                  break;
                }

                throw new (_ejectBoundToWorkspace || _load_ejectBoundToWorkspace()).default();

              case 16:
                _context5.next = 18;
                return (0, (_ejectConf || _load_ejectConf()).getEjectConfDataToPersist)(this, consumer, consumer.bitMap, configDirInstance);

              case 18:
                res = _context5.sent;

                if (this.componentMap) {
                  this.componentMap.setConfigDir(res.ejectedPath);
                }
                return _context5.abrupt('return', res);

              case 21:
              case 'end':
                return _context5.stop();
            }
          }
        }, _callee5, this);
      }));

      function getConfigToWrite(_x8, _x9, _x10) {
        return _ref6.apply(this, arguments);
      }

      return getConfigToWrite;
    }()
  }, {
    key: 'injectConfig',
    value: function () {
      var _ref7 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee6(consumerPath, bitMap) {
        var force = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
        var componentMap, configDir, res;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee6$(_context6) {
          while (1) {
            switch (_context6.prev = _context6.next) {
              case 0:
                this.componentMap = this.componentMap || bitMap.getComponentIfExist(this.id);
                componentMap = this.componentMap;

                if (componentMap) {
                  _context6.next = 4;
                  break;
                }

                throw new (_generalError || _load_generalError()).default('could not find component in the .bitmap file');

              case 4:
                configDir = componentMap.configDir;

                if (configDir) {
                  _context6.next = 7;
                  break;
                }

                throw new (_injectNonEjected || _load_injectNonEjected()).default();

              case 7:
                _context6.next = 9;
                return (0, (_injectConf || _load_injectConf()).default)(this, consumerPath, bitMap, configDir, force);

              case 9:
                res = _context6.sent;

                if (this.componentMap) {
                  this.componentMap.setConfigDir();
                }
                return _context6.abrupt('return', res);

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

      function injectConfig(_x11, _x12) {
        return _ref7.apply(this, arguments);
      }

      return injectConfig;
    }()
  }, {
    key: 'flattenedDependencies',
    value: function flattenedDependencies() {
      return (_bitIds || _load_bitIds()).default.fromObject(this.flattenedDependencies);
    }
  }, {
    key: 'flattenedDevDependencies',
    value: function flattenedDevDependencies() {
      return (_bitIds || _load_bitIds()).default.fromObject(this.flattenedDevDependencies);
    }
  }, {
    key: 'flattenedCompilerDependencies',
    value: function flattenedCompilerDependencies() {
      return (_bitIds || _load_bitIds()).default.fromObject(this.flattenedCompilerDependencies);
    }
  }, {
    key: 'flattenedTesterDependencies',
    value: function flattenedTesterDependencies() {
      return (_bitIds || _load_bitIds()).default.fromObject(this.flattenedTesterDependencies);
    }
  }, {
    key: 'getAllDependencies',
    value: function getAllDependencies() {
      return [].concat(_toConsumableArray(this.dependencies.dependencies), _toConsumableArray(this.devDependencies.dependencies), _toConsumableArray(this.compilerDependencies.dependencies), _toConsumableArray(this.testerDependencies.dependencies));
    }
  }, {
    key: 'getAllDependenciesCloned',
    value: function getAllDependenciesCloned() {
      var dependencies = [].concat(_toConsumableArray(this.dependencies.getClone()), _toConsumableArray(this.devDependencies.getClone()), _toConsumableArray(this.compilerDependencies.getClone()), _toConsumableArray(this.testerDependencies.getClone()));
      return new (_dependencies || _load_dependencies()).Dependencies(dependencies);
    }
  }, {
    key: 'getAllNonEnvsDependencies',
    value: function getAllNonEnvsDependencies() {
      return [].concat(_toConsumableArray(this.dependencies.dependencies), _toConsumableArray(this.devDependencies.dependencies));
    }
  }, {
    key: 'getAllDependenciesIds',
    value: function getAllDependenciesIds() {
      var allDependencies = this.getAllDependencies();
      return (_bitIds || _load_bitIds()).default.fromArray(allDependencies.map(function (dependency) {
        return dependency.id;
      }));
    }
  }, {
    key: 'hasDependencies',
    value: function hasDependencies() {
      var allDependencies = this.getAllDependencies();
      return Boolean(allDependencies.length);
    }
  }, {
    key: 'getAllFlattenedDependencies',
    value: function getAllFlattenedDependencies() {
      return [].concat(_toConsumableArray(this.flattenedDependencies), _toConsumableArray(this.flattenedDevDependencies), _toConsumableArray(this.flattenedCompilerDependencies), _toConsumableArray(this.flattenedTesterDependencies));
    }
  }, {
    key: 'getAllNonEnvsFlattenedDependencies',
    value: function getAllNonEnvsFlattenedDependencies() {
      return [].concat(_toConsumableArray(this.flattenedDependencies), _toConsumableArray(this.flattenedDevDependencies));
    }

    /**
     * Before writing the files into the file-system, remove the path-prefix that is shared among the main component files
     * and its dependencies. It helps to avoid large file-system paths.
     *
     * This is relevant for IMPORTED components only as the author may have long paths that are not needed for whoever
     * imports it. NESTED and AUTHORED components are written as is.
     *
     * @see sources.consumerComponentToVersion() for the opposite action. meaning, adding back the sharedDir.
     */

  }, {
    key: 'stripOriginallySharedDir',
    value: function stripOriginallySharedDir(manipulateDirData) {
      if (this._wasOriginallySharedDirStripped) return;
      this.setOriginallySharedDir(manipulateDirData);
      var originallySharedDir = this.originallySharedDir;
      if (originallySharedDir) {
        (_logger || _load_logger()).default.debug(`stripping originallySharedDir "${originallySharedDir}" from ${this.id}`);
      }
      var pathWithoutSharedDir = function pathWithoutSharedDir(pathStr, sharedDir) {
        if (!sharedDir) return pathStr;
        var partToRemove = (_path || _load_path()).default.normalize(sharedDir) + (_path || _load_path()).default.sep;
        return pathStr.replace(partToRemove, '');
      };
      this.files.forEach(function (file) {
        var newRelative = pathWithoutSharedDir(file.relative, originallySharedDir);
        file.updatePaths({ newBase: file.base, newRelative });
      });
      this.dists.stripOriginallySharedDir(originallySharedDir, pathWithoutSharedDir);
      this.mainFile = pathWithoutSharedDir(this.mainFile, originallySharedDir);
      this.dependencies.stripOriginallySharedDir(manipulateDirData, originallySharedDir);
      this.devDependencies.stripOriginallySharedDir(manipulateDirData, originallySharedDir);
      this.compilerDependencies.stripOriginallySharedDir(manipulateDirData, originallySharedDir);
      this.testerDependencies.stripOriginallySharedDir(manipulateDirData, originallySharedDir);
      this.customResolvedPaths.forEach(function (customPath) {
        customPath.destinationPath = (0, (_utils || _load_utils()).pathNormalizeToLinux)(pathWithoutSharedDir((_path || _load_path()).default.normalize(customPath.destinationPath), originallySharedDir));
      });
      this.overrides.stripOriginallySharedDir(originallySharedDir);
      this._wasOriginallySharedDirStripped = true;
    }
  }, {
    key: 'addWrapperDir',
    value: function addWrapperDir(manipulateDirData) {
      var _this2 = this;

      var manipulateDirItem = manipulateDirData.find(function (m) {
        return m.id.isEqual(_this2.id);
      });
      if (!manipulateDirItem || !manipulateDirItem.wrapDir) return;
      this.wrapDir = manipulateDirItem.wrapDir;

      var pathWithWrapDir = function pathWithWrapDir(pathStr) {
        return (_path || _load_path()).default.join(_this2.wrapDir, pathStr);
      };
      this.files.forEach(function (file) {
        var newRelative = pathWithWrapDir(file.relative);
        file.updatePaths({ newBase: file.base, newRelative });
      });
      // @todo: for dist also.
      this.mainFile = pathWithWrapDir(this.mainFile);
      var allDependencies = new (_dependencies || _load_dependencies()).Dependencies(this.getAllDependencies());
      allDependencies.addWrapDir(manipulateDirData, this.wrapDir);
      this.customResolvedPaths.forEach(function (customPath) {
        customPath.destinationPath = (0, (_utils || _load_utils()).pathNormalizeToLinux)(pathWithWrapDir((_path || _load_path()).default.normalize(customPath.destinationPath)));
      });
    }
  }, {
    key: 'build',
    value: function () {
      var _ref8 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee7(_ref9) {
        var scope = _ref9.scope,
            save = _ref9.save,
            consumer = _ref9.consumer,
            noCache = _ref9.noCache,
            verbose = _ref9.verbose,
            keep = _ref9.keep;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee7$(_context7) {
          while (1) {
            switch (_context7.prev = _context7.next) {
              case 0:
                return _context7.abrupt('return', (0, (_buildComponent || _load_buildComponent()).default)({
                  component: this,
                  scope,
                  save,
                  consumer,
                  noCache,
                  verbose,
                  keep
                }));

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

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

      return build;
    }()
  }, {
    key: 'runSpecs',
    value: function () {
      var _ref10 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee10(_ref11) {
        var _this3 = this;

        var scope = _ref11.scope,
            _ref11$rejectOnFailur = _ref11.rejectOnFailure,
            rejectOnFailure = _ref11$rejectOnFailur === undefined ? false : _ref11$rejectOnFailur,
            consumer = _ref11.consumer,
            save = _ref11.save,
            verbose = _ref11.verbose,
            isolated = _ref11.isolated,
            directory = _ref11.directory,
            keep = _ref11.keep;
        var testFiles, consumerPath, tester, componentDir, context, testerFilePath, run, isolatedEnvironment, isolateOpts, localTesterPath, componentWithDependencies, component, specDistWrite, results;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee10$(_context11) {
          while (1) {
            switch (_context11.prev = _context11.next) {
              case 0:
                testFiles = this.files.filter(function (file) {
                  return file.test;
                });
                consumerPath = consumer ? consumer.getPath() : '';

                if (!(!this.tester || !testFiles || (_ramda || _load_ramda()).default.isEmpty(testFiles))) {
                  _context11.next = 4;
                  break;
                }

                return _context11.abrupt('return', null);

              case 4:

                (_logger || _load_logger()).default.debug('tester found, start running tests');
                (_analytics || _load_analytics()).Analytics.addBreadCrumb('runSpecs', 'tester found, start running tests');
                tester = this.tester;

                if (tester.loaded) {
                  _context11.next = 14;
                  break;
                }

                componentDir = this.componentMap ? this.componentMap.getComponentDir() : undefined;
                context = { dependentId: this.id, workspaceDir: consumerPath, componentDir };

                (_analytics || _load_analytics()).Analytics.addBreadCrumb('runSpecs', 'installing missing tester');
                _context11.next = 13;
                return tester.install(scope, { verbose }, context);

              case 13:
                (_logger || _load_logger()).default.debug('Environment components are installed');

              case 14:
                testerFilePath = tester.filePath;

                run = function () {
                  var _ref12 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee9(component, cwd) {
                    var testFilesList, specsResults, tmpFolderFullPath, contextPaths, isTesterDetached, shouldWriteConfig, _context8, actionParams, oneFileSpecResult, specsResultsP, errors, err, specsResultsPretty, componentIdPretty, specsResultsAndIdPretty;

                    return (_regenerator || _load_regenerator()).default.wrap(function _callee9$(_context10) {
                      while (1) {
                        switch (_context10.prev = _context10.next) {
                          case 0:
                            if (cwd) {
                              (_logger || _load_logger()).default.debug(`changing process cwd to ${cwd}`);
                              (_analytics || _load_analytics()).Analytics.addBreadCrumb('runSpecs.run', 'changing process cwd');
                              process.chdir(cwd);
                            }
                            (_loader || _load_loader()).default.start((_loaderMessages || _load_loaderMessages()).BEFORE_RUNNING_SPECS);
                            testFilesList = !component.dists.isEmpty() ? component.dists.get().filter(function (dist) {
                              return dist.test;
                            }) : component.files.filter(function (file) {
                              return file.test;
                            });
                            specsResults = void 0;
                            tmpFolderFullPath = void 0;
                            contextPaths = {};

                            if (_this3.tester && _this3.tester.context) {
                              contextPaths = _this3.tester.context;
                            } else if (consumer && consumer.bitMap) {
                              contextPaths = {
                                workspaceDir: consumer.bitMap.projectRoot
                              };
                            }
                            if (!contextPaths.componentDir && component.writtenPath) {
                              contextPaths.componentDir = component.writtenPath;
                            }
                            _context10.prev = 8;

                            if (!(tester && tester.action)) {
                              _context10.next = 34;
                              break;
                            }

                            (_logger || _load_logger()).default.debug('running tests using new format');
                            (_analytics || _load_analytics()).Analytics.addBreadCrumb('runSpecs.run', 'running tests using new format');
                            _context10.next = 14;
                            return component.getDetachedTester(consumer);

                          case 14:
                            isTesterDetached = _context10.sent;
                            shouldWriteConfig = tester.writeConfigFilesOnAction && isTesterDetached;

                            if (!shouldWriteConfig) {
                              _context10.next = 21;
                              break;
                            }

                            tmpFolderFullPath = component.getTmpFolder(consumerPath);
                            if (verbose) {
                              console.log(`\nwriting config files to ${tmpFolderFullPath}`); // eslint-disable-line no-console
                            }
                            _context10.next = 21;
                            return (0, (_ejectConf || _load_ejectConf()).writeEnvFiles)({
                              configDir: component.getTmpFolder(),
                              env: tester,
                              consumer,
                              component,
                              deleteOldFiles: false,
                              verbose: !!verbose
                            });

                          case 21:
                            _context8 = {
                              componentObject: component.toObject()
                            };


                            contextPaths && Object.assign(_context8, contextPaths);

                            actionParams = {
                              testFiles: testFilesList,
                              rawConfig: tester.rawConfig,
                              dynamicConfig: tester.dynamicConfig,
                              configFiles: tester.files,
                              api: tester.api,
                              context: _context8
                            };
                            _context10.next = 26;
                            return tester.action(actionParams);

                          case 26:
                            specsResults = _context10.sent;

                            if (!tmpFolderFullPath) {
                              _context10.next = 32;
                              break;
                            }

                            if (verbose) {
                              console.log(`deleting tmp directory ${tmpFolderFullPath}`); // eslint-disable-line no-console
                            }
                            (_logger || _load_logger()).default.info(`consumer-component.runSpecs, deleting ${tmpFolderFullPath}`);
                            _context10.next = 32;
                            return (_fsExtra || _load_fsExtra()).default.remove(tmpFolderFullPath);

                          case 32:
                            _context10.next = 41;
                            break;

                          case 34:
                            (_logger || _load_logger()).default.debug('running tests using old format');
                            (_analytics || _load_analytics()).Analytics.addBreadCrumb('runSpecs.run', 'running tests using old format');

                            oneFileSpecResult = function () {
                              var _ref13 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee8(testFile) {
                                var testFilePath, results, failures, _results;

                                return (_regenerator || _load_regenerator()).default.wrap(function _callee8$(_context9) {
                                  while (1) {
                                    switch (_context9.prev = _context9.next) {
                                      case 0:
                                        testFilePath = testFile.path;
                                        _context9.prev = 1;
                                        _context9.next = 4;
                                        return tester.oldAction(testFilePath);

                                      case 4:
                                        results = _context9.sent;

                                        results.specPath = testFile.relative;
                                        return _context9.abrupt('return', results);

                                      case 9:
                                        _context9.prev = 9;
                                        _context9.t0 = _context9['catch'](1);
                                        failures = [{
                                          title: _context9.t0.message,
                                          err: _context9.t0
                                        }];
                                        _results = {
                                          specPath: testFile.relative,
                                          pass: false,
                                          tests: [],
                                          failures
                                        };
                                        return _context9.abrupt('return', _results);

                                      case 14:
                                      case 'end':
                                        return _context9.stop();
                                    }
                                  }
                                }, _callee8, _this3, [[1, 9]]);
                              }));

                              return function oneFileSpecResult(_x18) {
                                return _ref13.apply(this, arguments);
                              };
                            }();

                            specsResultsP = testFilesList.map(oneFileSpecResult);
                            _context10.next = 40;
                            return Promise.all(specsResultsP);

                          case 40:
                            specsResults = _context10.sent;

                          case 41:
                            _context10.next = 49;
                            break;

                          case 43:
                            _context10.prev = 43;
                            _context10.t0 = _context10['catch'](8);

                            if (tmpFolderFullPath) {
                              (_logger || _load_logger()).default.info(`consumer-component.runSpecs, deleting ${tmpFolderFullPath}`);
                              (_fsExtra || _load_fsExtra()).default.removeSync(tmpFolderFullPath);
                            }
                            errors = _context10.t0.errors || [_context10.t0];
                            err = new (_externalTestErrors || _load_externalTestErrors()).default(component.id.toString(), errors);
                            throw err;

                          case 49:

                            _this3.specsResults = specsResults.map(function (specRes) {
                              return (_specsResults || _load_specsResults()).default.createFromRaw(specRes);
                            });

                            if (!(rejectOnFailure && !_this3.specsResults.every(function (element) {
                              return element.pass;
                            }))) {
                              _context10.next = 58;
                              break;
                            }

                            // some or all the tests were failed.
                            (_loader || _load_loader()).default.stop();

                            if (!verbose) {
                              _context10.next = 57;
                              break;
                            }

                            // $FlowFixMe this.specsResults is not null at this point
                            specsResultsPretty = (0, (_chalkBox || _load_chalkBox()).paintSpecsResults)(_this3.specsResults).join('\n');
                            componentIdPretty = (_chalk || _load_chalk()).default.bold.white(_this3.id.toString());
                            specsResultsAndIdPretty = `${componentIdPretty}${specsResultsPretty}\n`;
                            return _context10.abrupt('return', Promise.reject(new (_componentSpecsFailed || _load_componentSpecsFailed()).default(specsResultsAndIdPretty)));

                          case 57:
                            return _context10.abrupt('return', Promise.reject(new (_componentSpecsFailed || _load_componentSpecsFailed()).default()));

                          case 58:
                            if (!save) {
                              _context10.next = 61;
                              break;
                            }

                            _context10.next = 61;
                            return scope.sources.modifySpecsResults({
                              source: _this3,
                              specsResults: _this3.specsResults
                            });

                          case 61:
                            return _context10.abrupt('return', _this3.specsResults);

                          case 62:
                          case 'end':
                            return _context10.stop();
                        }
                      }
                    }, _callee9, _this3, [[8, 43]]);
                  }));

                  return function run(_x16, _x17) {
                    return _ref12.apply(this, arguments);
                  };
                }();

                if (!(!isolated && consumer)) {
                  _context11.next = 18;
                  break;
                }

                return _context11.abrupt('return', run(this, consumer.getPath()));

              case 18:
                isolatedEnvironment = new (_environment || _load_environment()).default(scope, directory);
                _context11.prev = 19;
                _context11.next = 22;
                return isolatedEnvironment.create();

              case 22:
                isolateOpts = {
                  verbose,
                  dist: true,
                  installPackages: true,
                  installPeerDependencies: true,
                  noPackageJson: false
                };
                localTesterPath = (_path || _load_path()).default.join(isolatedEnvironment.getPath(), 'tester');
                _context11.next = 26;
                return isolatedEnvironment.isolateComponent(this.id, isolateOpts);

              case 26:
                componentWithDependencies = _context11.sent;


                (0, (_createSymlinkOrCopy || _load_createSymlinkOrCopy()).default)(testerFilePath, localTesterPath);
                component = componentWithDependencies.component;

                component.isolatedEnvironment = isolatedEnvironment;
                (_logger || _load_logger()).default.debug(`the component ${this.id.toString()} has been imported successfully into an isolated environment`);

                _context11.next = 33;
                return component.build({ scope, verbose });

              case 33:
                if (component.dists.isEmpty()) {
                  _context11.next = 37;
                  break;
                }

                specDistWrite = component.dists.get().map(function (file) {
                  return file.write();
                });
                _context11.next = 37;
                return Promise.all(specDistWrite);

              case 37:
                _context11.next = 39;
                return run(component);

              case 39:
                results = _context11.sent;

                if (keep) {
                  _context11.next = 43;
                  break;
                }

                _context11.next = 43;
                return isolatedEnvironment.destroy();

              case 43:
                return _context11.abrupt('return', results);

              case 46:
                _context11.prev = 46;
                _context11.t0 = _context11['catch'](19);

                if (keep) {
                  _context11.next = 51;
                  break;
                }

                _context11.next = 51;
                return isolatedEnvironment.destroy();

              case 51:
                return _context11.abrupt('return', Promise.reject(_context11.t0));

              case 52:
              case 'end':
                return _context11.stop();
            }
          }
        }, _callee10, this, [[19, 46]]);
      }));

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

      return runSpecs;
    }()
  }, {
    key: 'isolate',
    value: function () {
      var _ref14 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee11(scope, opts) {
        var isolatedEnvironment;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee11$(_context12) {
          while (1) {
            switch (_context12.prev = _context12.next) {
              case 0:
                isolatedEnvironment = new (_environment || _load_environment()).default(scope, opts.writeToPath);
                _context12.prev = 1;
                _context12.next = 4;
                return isolatedEnvironment.create();

              case 4:
                _context12.next = 6;
                return isolatedEnvironment.isolateComponent(this.id, opts);

              case 6:
                return _context12.abrupt('return', isolatedEnvironment.path);

              case 9:
                _context12.prev = 9;
                _context12.t0 = _context12['catch'](1);
                _context12.next = 13;
                return isolatedEnvironment.destroy();

              case 13:
                throw new (_generalError || _load_generalError()).default(_context12.t0);

              case 14:
              case 'end':
                return _context12.stop();
            }
          }
        }, _callee11, this, [[1, 9]]);
      }));

      function isolate(_x19, _x20) {
        return _ref14.apply(this, arguments);
      }

      return isolate;
    }()
  }, {
    key: 'toObject',
    value: function toObject() {
      return {
        name: this.name,
        version: this.version,
        mainFile: this.mainFile,
        scope: this.scope,
        lang: this.lang,
        bindingPrefix: this.bindingPrefix,
        compiler: this.compiler ? this.compiler.toObject() : null,
        tester: this.tester ? this.tester.toObject() : null,
        dependencies: this.dependencies.serialize(),
        devDependencies: this.devDependencies.serialize(),
        compilerDependencies: this.compilerDependencies.serialize(),
        testerDependencies: this.testerDependencies.serialize(),
        packageDependencies: this.packageDependencies,
        devPackageDependencies: this.devPackageDependencies,
        peerPackageDependencies: this.peerPackageDependencies,
        compilerPackageDependencies: this.compilerPackageDependencies,
        testerPackageDependencies: this.testerPackageDependencies,
        manuallyRemovedDependencies: this.manuallyRemovedDependencies,
        manuallyAddedDependencies: this.manuallyAddedDependencies,
        overrides: this.overrides.componentOverridesData,
        files: this.files,
        docs: this.docs,
        dists: this.dists,
        specsResults: this.specsResults ? this.specsResults.map(function (res) {
          return res.serialize();
        }) : null,
        license: this.license ? this.license.serialize() : null,
        log: this.log,
        deprecated: this.deprecated
      };
    }
  }, {
    key: 'toString',
    value: function toString() {
      return JSON.stringify(this.toObject());
    }
  }, {
    key: 'copyFilesIntoDists',
    value: function copyFilesIntoDists() {
      var dists = this.files.map(function (file) {
        return new (_sources || _load_sources()).Dist({ base: file.base, path: file.path, contents: file.contents });
      });
      this.setDists(dists);
    }
  }, {
    key: 'setOriginallySharedDir',
    value: function setOriginallySharedDir(manipulateDirData) {
      var _this4 = this;

      var manipulateDirItem = manipulateDirData.find(function (m) {
        return m.id.isEqual(_this4.id);
      });
      if (manipulateDirItem) {
        this.originallySharedDir = manipulateDirItem.originallySharedDir;
      }
    }
  }, {
    key: 'toComponentWithDependencies',
    value: function () {
      var _ref15 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee12(consumer) {
        var _this5 = this;

        var getFlatten, getDependenciesComponents, dependencies, devDependencies, compilerDependencies, testerDependencies;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee12$(_context13) {
          while (1) {
            switch (_context13.prev = _context13.next) {
              case 0:
                getFlatten = function getFlatten(field) {
                  // when loaded from filesystem, it doesn't have the flatten, fetch them from model.
                  return _this5.loadedFromFileSystem ? _this5.componentFromModel[field] : _this5[field];
                };

                getDependenciesComponents = function getDependenciesComponents(ids) {
                  return Promise.all(ids.map(function (dependencyId) {
                    if (consumer.bitMap.isExistWithSameVersion(dependencyId)) {
                      return consumer.loadComponent(dependencyId);
                    }
                    // when dependencies are imported as npm packages, they are not in bit.map
                    _this5.dependenciesSavedAsComponents = false;
                    return consumer.loadComponentFromModel(dependencyId);
                  }));
                };

                _context13.next = 4;
                return getDependenciesComponents(getFlatten('flattenedDependencies'));

              case 4:
                dependencies = _context13.sent;
                _context13.next = 7;
                return getDependenciesComponents(getFlatten('flattenedDevDependencies'));

              case 7:
                devDependencies = _context13.sent;
                _context13.next = 10;
                return getDependenciesComponents(getFlatten('flattenedCompilerDependencies'));

              case 10:
                compilerDependencies = _context13.sent;
                _context13.next = 13;
                return getDependenciesComponents(getFlatten('flattenedTesterDependencies'));

              case 13:
                testerDependencies = _context13.sent;
                return _context13.abrupt('return', new (_componentDependencies || _load_componentDependencies()).default({
                  component: this,
                  dependencies,
                  devDependencies,
                  compilerDependencies,
                  testerDependencies
                }));

              case 15:
              case 'end':
                return _context13.stop();
            }
          }
        }, _callee12, this);
      }));

      function toComponentWithDependencies(_x21) {
        return _ref15.apply(this, arguments);
      }

      return toComponentWithDependencies;
    }()
  }, {
    key: 'copyDependenciesFromModel',
    value: function copyDependenciesFromModel(ids) {
      var _this6 = this;

      var componentFromModel = this.componentFromModel;
      if (!componentFromModel) throw new Error('copyDependenciesFromModel: component is missing from the model');
      ids.forEach(function (id) {
        var addDependency = function addDependency(modelDependencies, dependencies) {
          var dependency = modelDependencies.getByIdStr(id);
          if (dependency) dependencies.add(dependency);
          return Boolean(dependency);
        };
        var addedDep = addDependency(componentFromModel.dependencies, _this6.dependencies);
        if (addedDep) return;
        var addedDevDep = addDependency(componentFromModel.devDependencies, _this6.devDependencies);
        if (addedDevDep) return;
        var addedCompilerDep = addDependency(componentFromModel.compilerDependencies, _this6.compilerDependencies);
        if (addedCompilerDep) return;
        var addedTesterDep = addDependency(componentFromModel.testerDependencies, _this6.testerDependencies);
        if (addedTesterDep) return;
        throw new Error(`copyDependenciesFromModel unable to find dependency ${id} in the model`);
      });
    }
  }], [{
    key: 'isComponentInvalidByErrorType',
    value: function isComponentInvalidByErrorType(err) {
      var invalidComponentErrors = [(_mainFileRemoved || _load_mainFileRemoved()).default, (_missingFilesFromComponent || _load_missingFilesFromComponent()).default, (_componentNotFoundInPath || _load_componentNotFoundInPath()).default, (_componentOutOfSync || _load_componentOutOfSync()).default, (_extensionFileNotFound || _load_extensionFileNotFound()).default];
      return invalidComponentErrors.some(function (errorType) {
        return err instanceof errorType;
      });
    }
  }, {
    key: 'fromObject',
    value: function () {
      var _ref16 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee13(object) {
        var name, box, version, scope, lang, bindingPrefix, compiler, tester, dependencies, devDependencies, compilerDependencies, testerDependencies, packageDependencies, devPackageDependencies, peerPackageDependencies, compilerPackageDependencies, testerPackageDependencies, docs, mainFile, dists, files, specsResults, license, overrides, deprecated, compilerProps, compilerInstance, testerProps, testerInstance;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee13$(_context14) {
          while (1) {
            switch (_context14.prev = _context14.next) {
              case 0:
                name = object.name, box = object.box, version = object.version, scope = object.scope, lang = object.lang, bindingPrefix = object.bindingPrefix, compiler = object.compiler, tester = object.tester, dependencies = object.dependencies, devDependencies = object.devDependencies, compilerDependencies = object.compilerDependencies, testerDependencies = object.testerDependencies, packageDependencies = object.packageDependencies, devPackageDependencies = object.devPackageDependencies, peerPackageDependencies = object.peerPackageDependencies, compilerPackageDependencies = object.compilerPackageDependencies, testerPackageDependencies = object.testerPackageDependencies, docs = object.docs, mainFile = object.mainFile, dists = object.dists, files = object.files, specsResults = object.specsResults, license = object.license, overrides = object.overrides, deprecated = object.deprecated;

                if (!compiler) {
                  _context14.next = 7;
                  break;
                }

                _context14.next = 4;
                return (_compilerExtension || _load_compilerExtension()).default.loadFromSerializedModelObject(compiler);

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

              case 7:
                _context14.t0 = null;

              case 8:
                compilerProps = _context14.t0;

                if (!compilerProps) {
                  _context14.next = 15;
                  break;
                }

                _context14.next = 12;
                return (0, (_envFactory || _load_envFactory()).default)((_constants || _load_constants()).COMPILER_ENV_TYPE, compilerProps);

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

              case 15:
                _context14.t1 = null;

              case 16:
                compilerInstance = _context14.t1;

                if (!tester) {
                  _context14.next = 23;
                  break;
                }

                _context14.next = 20;
                return (_testerExtension || _load_testerExtension()).default.loadFromSerializedModelObject(tester);

              case 20:
                _context14.t2 = _context14.sent;
                _context14.next = 24;
                break;

              case 23:
                _context14.t2 = null;

              case 24:
                testerProps = _context14.t2;

                if (!testerProps) {
                  _context14.next = 31;
                  break;
                }

                _context14.next = 28;
                return (0, (_envFactory || _load_envFactory()).default)((_constants || _load_constants()).TESTER_ENV_TYPE, testerProps);

              case 28:
                _context14.t3 = _context14.sent;
                _context14.next = 32;
                break;

              case 31:
                _context14.t3 = null;

              case 32:
                testerInstance = _context14.t3;
                return _context14.abrupt('return', new Component({
                  name: box ? `${box}/${name}` : name,
                  version,
                  scope,
                  lang,
                  bindingPrefix,
                  compiler: compilerInstance,
                  tester: testerInstance,
                  dependencies,
                  devDependencies,
                  compilerDependencies,
                  testerDependencies,
                  packageDependencies,
                  devPackageDependencies,
                  peerPackageDependencies,
                  compilerPackageDependencies,
                  testerPackageDependencies,
                  mainFile,
                  files,
                  docs,
                  dists,
                  specsResults: specsResults ? (_specsResults || _load_specsResults()).default.deserialize(specsResults) : null,
                  license: license ? (_sources || _load_sources()).License.deserialize(license) : null,
                  overrides: new (_componentOverrides || _load_componentOverrides()).default(overrides),
                  deprecated: deprecated || false
                }));

              case 34:
              case 'end':
                return _context14.stop();
            }
          }
        }, _callee13, this);
      }));

      function fromObject(_x22) {
        return _ref16.apply(this, arguments);
      }

      return fromObject;
    }()
  }, {
    key: 'fromString',
    value: function () {
      var _ref17 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee14(str) {
        var object;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee14$(_context15) {
          while (1) {
            switch (_context15.prev = _context15.next) {
              case 0:
                object = JSON.parse(str);

                object.files = (_sources || _load_sources()).SourceFile.loadFromParsedStringArray(object.files);

                // added if statement to support new and old version of remote ls
                // old version of bit returns from server array of dists  and new version return object
                if (object.dists && Array.isArray(object.dists)) {
                  object.dists = (_sources || _load_sources()).Dist.loadFromParsedStringArray(object.dists);
                } else if (object.dists && object.dists.dists) {
                  object.dists = (_sources || _load_sources()).Dist.loadFromParsedStringArray(object.dists.dists);
                }
                return _context15.abrupt('return', this.fromObject(object));

              case 4:
              case 'end':
                return _context15.stop();
            }
          }
        }, _callee14, this);
      }));

      function fromString(_x23) {
        return _ref17.apply(this, arguments);
      }

      return fromString;
    }()
  }, {
    key: 'loadFromFileSystem',
    value: function () {
      var _ref18 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee16(_ref19) {
        var _this7 = this;

        var bitDir = _ref19.bitDir,
            componentMap = _ref19.componentMap,
            id = _ref19.id,
            consumer = _ref19.consumer,
            componentFromModel = _ref19.componentFromModel;

        var consumerPath, workspaceConfig, bitMap, deprecated, componentDir, dists, mainDistFile, getLoadedFiles, configDir, resolvedBaseConfigDir, componentConfig, componentPkgJsonDir, bitJson, envsContext, isAuthor, overridesFromConsumer, propsToLoadEnvs, compilerP, testerP, _ref21, _ref22, compiler, tester, compilerDynamicPackageDependencies, testerDynamicPackageDependencies, modelCompilerPackageDependencies, modelTesterPackageDependencies, compilerPackageDependencies, testerPackageDependencies, overridesFromModel, overrides;

        return (_regenerator || _load_regenerator()).default.wrap(function _callee16$(_context17) {
          while (1) {
            switch (_context17.prev = _context17.next) {
              case 0:
                consumerPath = consumer.getPath();
                workspaceConfig = consumer.config;
                bitMap = consumer.bitMap;
                deprecated = componentFromModel ? componentFromModel.deprecated : false;
                componentDir = componentMap.getComponentDir();
                dists = componentFromModel ? componentFromModel.dists.get() : undefined;
                mainDistFile = componentFromModel ? componentFromModel.dists.getMainDistFile() : undefined;

                getLoadedFiles = function () {
                  var _ref20 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee15() {
                    var sourceFiles, filesToDelete;
                    return (_regenerator || _load_regenerator()).default.wrap(function _callee15$(_context16) {
                      while (1) {
                        switch (_context16.prev = _context16.next) {
                          case 0:
                            sourceFiles = [];
                            _context16.next = 3;
                            return componentMap.trackDirectoryChanges(consumer, id);

                          case 3:
                            filesToDelete = [];

                            componentMap.files.forEach(function (file) {
                              var filePath = (_path || _load_path()).default.join(bitDir, file.relativePath);
                              try {
                                var sourceFile = (_sources || _load_sources()).SourceFile.load(filePath, workspaceConfig.distTarget, bitDir, consumerPath, {
                                  test: file.test
                                });
                                sourceFiles.push(sourceFile);
                              } catch (err) {
                                if (!(err instanceof (_fileSourceNotFound || _load_fileSourceNotFound()).default)) throw err;
                                (_logger || _load_logger()).default.warn(`a file ${filePath} will be deleted from bit.map as it does not exist on the file system`);
                                filesToDelete.push(file);
                              }
                            });

                            if (!filesToDelete.length) {
                              _context16.next = 11;
                              break;
                            }

                            if (sourceFiles.length) {
                              _context16.next = 8;
                              break;
                            }

                            throw new (_missingFilesFromComponent || _load_missingFilesFromComponent()).default(id.toString());

                          case 8:
                            filesToDelete.forEach(function (fileToDelete) {
                              if (fileToDelete.relativePath === componentMap.mainFile) {
                                throw new (_mainFileRemoved || _load_mainFileRemoved()).default(componentMap.mainFile, id.toString());
                              }
                            });
                            componentMap.removeFiles(filesToDelete);
                            bitMap.hasChanged = true;

                          case 11:
                            return _context16.abrupt('return', sourceFiles);

                          case 12:
                          case 'end':
                            return _context16.stop();
                        }
                      }
                    }, _callee15, _this7);
                  }));

                  return function getLoadedFiles() {
                    return _ref20.apply(this, arguments);
                  };
                }();

                if ((_fsExtra || _load_fsExtra()).default.existsSync(bitDir)) {
                  _context17.next = 10;
                  break;
                }

                throw new (_componentNotFoundInPath || _load_componentNotFoundInPath()).default(bitDir);

              case 10:
                configDir = componentDir ? (_path || _load_path()).default.join(consumerPath, componentDir) : consumerPath;

                if (!componentMap.configDir) {
                  _context17.next = 16;
                  break;
                }

                _context17.next = 14;
                return componentMap.deleteConfigDirIfNotExists();

              case 14:
                resolvedBaseConfigDir = componentMap.getBaseConfigDir();

                if (resolvedBaseConfigDir) {
                  configDir = (_path || _load_path()).default.join(consumerPath, resolvedBaseConfigDir);
                }

              case 16:
                // Load the base entry from the root dir in map file in case it was imported using -path
                // Or created using bit create so we don't want all the path but only the relative one
                // Check that bitDir isn't the same as consumer path to make sure we are not loading global stuff into component
                componentConfig = void 0;

                if (!(configDir !== consumerPath)) {
                  _context17.next = 23;
                  break;
                }

                componentPkgJsonDir = componentMap.rootDir ? consumer.toAbsolutePath(componentMap.rootDir) : null;
                // $FlowFixMe unclear error

                _context17.next = 21;
                return (_config || _load_config()).default.load(componentPkgJsonDir, configDir, workspaceConfig);

              case 21:
                componentConfig = _context17.sent;

                // by default, imported components are not written with bit.json file.
                // use the component from the model to get their bit.json values
                if (componentFromModel) {
                  componentConfig.mergeWithComponentData(componentFromModel);
                }

              case 23:
                // for authored componentConfig is normally undefined
                bitJson = componentConfig || workspaceConfig;

                // Remove dists if compiler has been deleted

                if (dists && !bitJson.hasCompiler()) {
                  dists = undefined;
                }

                envsContext = {
                  componentDir: bitDir,
                  workspaceDir: consumerPath
                };
                isAuthor = componentMap.origin === (_constants || _load_constants()).COMPONENT_ORIGINS.AUTHORED;
                // overrides from consumer-config is not relevant and should not affect imported

                overridesFromConsumer = isAuthor ? workspaceConfig.overrides.getOverrideComponentData(id) : null;
                propsToLoadEnvs = {
                  consumerPath,
                  envType: (_constants || _load_constants()).COMPILER_ENV_TYPE,
                  scopePath: consumer.scope.getPath(),
                  componentOrigin: componentMap.origin,
                  componentFromModel,
                  overridesFromConsumer,
                  workspaceConfig,
                  componentConfig,
                  context: envsContext
                };
                compilerP = (_envExtension || _load_envExtension()).default.loadFromCorrectSource(propsToLoadEnvs);

                propsToLoadEnvs.envType = (_constants || _load_constants()).TESTER_ENV_TYPE;
                testerP = (_envExtension || _load_envExtension()).default.loadFromCorrectSource(propsToLoadEnvs);
                _context17.next = 34;
                return Promise.all([compilerP, testerP]);

              case 34:
                _ref21 = _context17.sent;
                _ref22 = _slicedToArray(_ref21, 2);
                compiler = _ref22[0];
                tester = _ref22[1];


                // Load the compilerPackageDependencies/testerPackageDependencies from the actual compiler / tester or from the model
                // if they are not loaded (aka not installed)
                // We load it from model to prevent case when component is modified becasue changes in envsPackageDependencies
                // That occur as a result that we import component but didn't import its envs so we can't
                // calculate the envsPackageDependencies (without install the env, which we don't want)
                compilerDynamicPackageDependencies = compiler && compiler.loaded ? compiler.dynamicPackageDependencies : {};
                testerDynamicPackageDependencies = tester && tester.loaded ? tester.dynamicPackageDependencies : {};
                modelCompilerPackageDependencies = componentFromModel ? componentFromModel.compilerPackageDependencies || {} : {};
                modelTesterPackageDependencies = componentFromModel ? componentFromModel.testerPackageDependencies || {} : {};
                compilerPackageDependencies = _extends({}, modelCompilerPackageDependencies, compilerDynamicPackageDependencies);
                testerPackageDependencies = _extends({}, modelTesterPackageDependencies, testerDynamicPackageDependencies);
                overridesFromModel = componentFromModel ? componentFromModel.overrides.componentOverridesData : null;
                overrides = (_componentOverrides || _load_componentOverrides()).default.loadFromConsumer(overridesFromConsumer, overridesFromModel, componentConfig, isAuthor);
                _context17.t0 = Component;
                _context17.t1 = id.name;
                _context17.t2 = id.scope;
                _context17.t3 = id.version;
                _context17.t4 = bitJson.lang;
                _context17.t5 = bitJson.bindingPrefix || (_constants || _load_constants()).DEFAULT_BINDINGS_PREFIX;
                _context17.t6 = compiler;
                _context17.t7 = tester;
                _context17.t8 = componentConfig;
                _context17.t9 = componentMap.mainFile;
                _context17.next = 58;
                return getLoadedFiles();

              case 58:
                _context17.t10 = _context17.sent;
                _context17.t11 = componentMap;
                _context17.t12 = dists;
                _context17.t13 = mainDistFile ? (_path || _load_path()).default.normalize(mainDistFile) : null;
                _context17.t14 = compilerPackageDependencies;
                _context17.t15 = testerPackageDependencies;
                _context17.t16 = deprecated;
                _context17.t17 = componentMap.origin;
                _context17.t18 = overrides;
                _context17.t19 = {
                  name: _context17.t1,
                  scope: _context17.t2,
                  version: _context17.t3,
                  lang: _context17.t4,
                  bindingPrefix: _context17.t5,
                  compiler: _context17.t6,
                  tester: _context17.t7,
                  bitJson: _context17.t8,
                  mainFile: _context17.t9,
                  files: _context17.t10,
                  loadedFromFileSystem: true,
                  componentMap: _context17.t11,
                  dists: _context17.t12,
                  mainDistFile: _context17.t13,
                  compilerPackageDependencies: _context17.t14,
                  testerPackageDependencies: _context17.t15,
                  deprecated: _context17.t16,
                  origin: _context17.t17,
                  overrides: _context17.t18
                };
                return _context17.abrupt('return', new _context17.t0(_context17.t19));

              case 69:
              case 'end':
                return _context17.stop();
            }
          }
        }, _callee16, this);
      }));

      function loadFromFileSystem(_x24) {
        return _ref18.apply(this, arguments);
      }

      return loadFromFileSystem;
    }()
  }]);

  return Component;
}();

exports.default = Component;