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

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

var _semver;

function _load_semver() {
  return _semver = _interopRequireDefault(require('semver'));
}

var _fsExtra;

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

var _ramda;

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

var _pMapSeries;

function _load_pMapSeries() {
  return _pMapSeries = _interopRequireDefault(require('p-map-series'));
}

var _componentObjects;

function _load_componentObjects() {
  return _componentObjects = _interopRequireDefault(require('./component-objects'));
}

var _models;

function _load_models() {
  return _models = require('./models');
}

var _utils;

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

var _constants;

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

var _scopeJson;

function _load_scopeJson() {
  return _scopeJson = require('./scope-json');
}

var _exceptions;

function _load_exceptions() {
  return _exceptions = require('./exceptions');
}

var _repositories;

function _load_repositories() {
  return _repositories = require('./repositories');
}

var _bitId;

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

var _componentVersion;

function _load_componentVersion() {
  return _componentVersion = _interopRequireDefault(require('./component-version'));
}

var _objects;

function _load_objects() {
  return _objects = require('./objects');
}

var _sources;

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

var _loader;

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

var _scopeMigratorManifest;

function _load_scopeMigratorManifest() {
  return _scopeMigratorManifest = _interopRequireDefault(require('./migrations/scope-migrator-manifest'));
}

var _scopeMigrator;

function _load_scopeMigrator() {
  return _scopeMigrator = _interopRequireDefault(require('./migrations/scope-migrator'));
}

var _loaderMessages;

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

var _logger;

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

var _removedComponents;

function _load_removedComponents() {
  return _removedComponents = require('./removed-components');
}

var _graph;

function _load_graph() {
  return _graph = _interopRequireDefault(require('./graph/graph'));
}

var _removeModelComponents;

function _load_removeModelComponents() {
  return _removeModelComponents = _interopRequireDefault(require('./component-ops/remove-model-components'));
}

var _dists;

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

var _specsResults;

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

var _analytics;

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

var _generalError;

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

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 removeNils = (_ramda || _load_ramda()).default.reject((_ramda || _load_ramda()).default.isNil);
var pathHasScope = (0, (_utils || _load_utils()).pathHasAll)([(_constants || _load_constants()).OBJECTS_DIR, (_constants || _load_constants()).SCOPE_JSON]);

var Scope = function () {
  // cache DependencyGraph instance

  function Scope(scopeProps) {
    _classCallCheck(this, Scope);

    this.created = false;

    this.path = scopeProps.path;
    this.scopeJson = scopeProps.scopeJson;
    this.created = scopeProps.created || false;
    this.tmp = scopeProps.tmp || new (_repositories || _load_repositories()).Tmp(this);
    this.sources = scopeProps.sources || new (_sources || _load_sources()).default(this);
    this.objects = scopeProps.objects;
  }

  _createClass(Scope, [{
    key: 'getDependencyGraph',
    value: function () {
      var _ref = (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._dependencyGraph) {
                  _context.next = 4;
                  break;
                }

                _context.next = 3;
                return (_graph || _load_graph()).default.load(this);

              case 3:
                this._dependencyGraph = _context.sent;

              case 4:
                return _context.abrupt('return', this._dependencyGraph);

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

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

      return getDependencyGraph;
    }()
  }, {
    key: 'getPath',
    value: function getPath() {
      return this.path;
    }
  }, {
    key: 'getComponentsPath',
    value: function getComponentsPath() {
      return (_path || _load_path()).join(this.path, Scope.getComponentsRelativePath());
    }

    /**
     * Get the relative components path inside the scope
     * (components such as compilers / testers / extensions)
     * currently components
     */

  }, {
    key: 'getBitPathInComponentsDir',
    value: function getBitPathInComponentsDir(id) {
      return (_path || _load_path()).join(this.getComponentsPath(), id.toFullPath());
    }

    /**
     * Running migration process for scope to update the stores (bit objects) to the current version
     *
     * @param {any} verbose - print debug logs
     * @returns {Object} - wether the process run and wether it successeded
     * @memberof Consumer
     */

  }, {
    key: 'migrate',
    value: function () {
      var _ref2 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee2(verbose) {
        var scopeVersion, upToDateMsg, rawObjects, resultObjects, validateBeforePersist;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee2$(_context2) {
          while (1) {
            switch (_context2.prev = _context2.next) {
              case 0:
                (_logger || _load_logger()).default.debug('scope.migrate, running migration process for scope');
                if (verbose) console.log('running migration process for scope'); // eslint-disable-line
                // We start to use this process after version 0.10.9, so we assume the scope is in the last production version
                scopeVersion = this.scopeJson.get('version') || '0.10.9';

                if (!(_semver || _load_semver()).default.gte(scopeVersion, (_constants || _load_constants()).BIT_VERSION)) {
                  _context2.next = 8;
                  break;
                }

                upToDateMsg = 'scope version is up to date';

                if (verbose) console.log(upToDateMsg); // eslint-disable-line
                (_logger || _load_logger()).default.debug(`scope.migrate, ${upToDateMsg}`);
                return _context2.abrupt('return', {
                  run: false
                });

              case 8:
                (_loader || _load_loader()).default.start((_loaderMessages || _load_loaderMessages()).BEFORE_MIGRATION);
                (_logger || _load_logger()).default.debugAndAddBreadCrumb('scope.migrate', `start scope migration. scope version ${scopeVersion}, bit version ${(_constants || _load_constants()).BIT_VERSION}`);
                _context2.next = 12;
                return this.objects.listRawObjects();

              case 12:
                rawObjects = _context2.sent;
                _context2.next = 15;
                return (0, (_scopeMigrator || _load_scopeMigrator()).default)(scopeVersion, (_scopeMigratorManifest || _load_scopeMigratorManifest()).default, rawObjects, verbose);

              case 15:
                resultObjects = _context2.sent;

                // Add the new / updated objects
                this.objects.addMany(resultObjects.newObjects);
                // Remove old objects
                this.objects.removeManyObjects(resultObjects.refsToRemove);
                // Persists new / remove objects
                validateBeforePersist = false;
                _context2.next = 21;
                return this.objects.persist(validateBeforePersist);

              case 21:
                // Update the scope version
                this.scopeJson.set('version', (_constants || _load_constants()).BIT_VERSION);
                (_logger || _load_logger()).default.debugAndAddBreadCrumb('scope.migrate', `updating scope version to version ${(_constants || _load_constants()).BIT_VERSION}`);
                _context2.next = 25;
                return this.scopeJson.write(this.getPath());

              case 25:
                (_loader || _load_loader()).default.stop();
                return _context2.abrupt('return', {
                  run: true,
                  success: true
                });

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

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

      return migrate;
    }()
  }, {
    key: 'describe',
    value: function describe() {
      return {
        name: this.name
      };
    }
  }, {
    key: 'toConsumerComponents',
    value: function toConsumerComponents(components) {
      var _this = this;

      return Promise.all(components.filter(function (comp) {
        return !(comp instanceof (_models || _load_models()).Symlink);
      }).map(function (c) {
        return c.toConsumerComponent(c.latestExisting(_this.objects).toString(), _this.name, _this.objects);
      }));
    }
  }, {
    key: 'list',
    value: function () {
      var _ref3 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee3() {
        return (_regenerator || _load_regenerator()).default.wrap(function _callee3$(_context3) {
          while (1) {
            switch (_context3.prev = _context3.next) {
              case 0:
                return _context3.abrupt('return', this.objects.listComponents());

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

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

      return list;
    }()
  }, {
    key: 'listIncludesSymlinks',
    value: function () {
      var _ref4 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee4() {
        return (_regenerator || _load_regenerator()).default.wrap(function _callee4$(_context4) {
          while (1) {
            switch (_context4.prev = _context4.next) {
              case 0:
                return _context4.abrupt('return', this.objects.listComponentsIncludeSymlinks());

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

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

      return listIncludesSymlinks;
    }()
  }, {
    key: 'listLocal',
    value: function () {
      var _ref5 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee5() {
        var _this2 = this;

        var listResults;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee5$(_context5) {
          while (1) {
            switch (_context5.prev = _context5.next) {
              case 0:
                _context5.next = 2;
                return this.list();

              case 2:
                listResults = _context5.sent;
                return _context5.abrupt('return', listResults.filter(function (result) {
                  return !result.scope || result.scope === _this2.name;
                }));

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

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

      return listLocal;
    }()
  }, {
    key: 'latestVersions',
    value: function () {
      var _ref6 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee6(componentIds) {
        var throwOnFailure = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
        var components, ids;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee6$(_context6) {
          while (1) {
            switch (_context6.prev = _context6.next) {
              case 0:
                componentIds = componentIds.map(function (componentId) {
                  return componentId.changeVersion(null);
                });
                _context6.next = 3;
                return this.sources.getMany(componentIds);

              case 3:
                components = _context6.sent;
                ids = components.map(function (component) {
                  var getVersion = function getVersion() {
                    if (component.component) {
                      return component.component.latest();
                    }
                    if (throwOnFailure) throw new (_exceptions || _load_exceptions()).ComponentNotFound(component.id.toString());
                    return (_constants || _load_constants()).DEFAULT_BIT_VERSION;
                  };
                  var version = getVersion();
                  return component.id.changeVersion(version);
                });
                return _context6.abrupt('return', (_bitId || _load_bitId()).BitIds.fromArray(ids));

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

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

      return latestVersions;
    }()

    /**
     * Build multiple components sequentially, not in parallel.
     *
     * Two reasons why not running them in parallel:
     * 1) when several components have the same environment, it'll try to install them multiple times.
     * 2) npm throws errors when running 'npm install' from several directories
     */

  }, {
    key: 'buildMultiple',
    value: function () {
      var _ref7 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee8(components, consumer, noCache, verbose) {
        var _this3 = this;

        var build;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee8$(_context8) {
          while (1) {
            switch (_context8.prev = _context8.next) {
              case 0:
                (_logger || _load_logger()).default.debugAndAddBreadCrumb('scope.buildMultiple', 'scope.buildMultiple: sequentially build multiple components');
                // Make sure to not start the loader if there are no components to build
                if (components && components.length) {
                  (_loader || _load_loader()).default.start((_loaderMessages || _load_loaderMessages()).BEFORE_RUNNING_BUILD);
                }

                build = function () {
                  var _ref8 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee7(component) {
                    var buildResults;
                    return (_regenerator || _load_regenerator()).default.wrap(function _callee7$(_context7) {
                      while (1) {
                        switch (_context7.prev = _context7.next) {
                          case 0:
                            _context7.next = 2;
                            return component.build({ scope: _this3, consumer, noCache, verbose });

                          case 2:
                            _context7.next = 4;
                            return component.dists.writeDists(component, consumer);

                          case 4:
                            buildResults = _context7.sent;
                            return _context7.abrupt('return', { component: component.id.toString(), buildResults });

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

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

                return _context8.abrupt('return', (0, (_pMapSeries || _load_pMapSeries()).default)(components, build));

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

      function buildMultiple(_x4, _x5, _x6, _x7) {
        return _ref7.apply(this, arguments);
      }

      return buildMultiple;
    }()

    /**
     * when custom-module-resolution is used, the test process needs to set the custom module
     * directory to the dist directory
     */

  }, {
    key: 'injectNodePathIfNeeded',
    value: function injectNodePathIfNeeded(consumer, components) {
      var nodePathDirDist = (_dists || _load_dists()).default.getNodePathDir(consumer);
      // only author components need this injection. for imported the links are built on node_modules
      var isNodePathNeeded = nodePathDirDist && components.some(function (component) {
        return (component.dependencies.isCustomResolvedUsed() || component.devDependencies.isCustomResolvedUsed() || component.compilerDependencies.isCustomResolvedUsed() || component.testerDependencies.isCustomResolvedUsed()) && component.componentMap && component.componentMap.origin === (_constants || _load_constants()).COMPONENT_ORIGINS.AUTHORED && !component.dists.isEmpty();
      });
      if (isNodePathNeeded) {
        var getCurrentNodePathWithDirDist = function getCurrentNodePathWithDirDist() {
          if (!process.env.NODE_PATH) return nodePathDirDist;
          var separator = process.env.NODE_PATH.endsWith((_constants || _load_constants()).NODE_PATH_SEPARATOR) ? '' : (_constants || _load_constants()).NODE_PATH_SEPARATOR;
          // $FlowFixMe
          return process.env.NODE_PATH + separator + nodePathDirDist;
        };
        process.env.NODE_PATH = getCurrentNodePathWithDirDist();
        // $FlowFixMe
        require('module').Module._initPaths(); // eslint-disable-line
      }
    }

    /**
     * Test multiple components sequentially, not in parallel.
     *
     * See the reason not to run them in parallel at @buildMultiple()
     */

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

        var components = _ref10.components,
            consumer = _ref10.consumer,
            verbose = _ref10.verbose,
            _ref10$rejectOnFailur = _ref10.rejectOnFailure,
            rejectOnFailure = _ref10$rejectOnFailur === undefined ? false : _ref10$rejectOnFailur;
        var test;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee10$(_context10) {
          while (1) {
            switch (_context10.prev = _context10.next) {
              case 0:
                (_logger || _load_logger()).default.debugAndAddBreadCrumb('scope.testMultiple', 'scope.testMultiple: sequentially test multiple components');
                // Make sure not starting the loader when there is nothing to test
                if (components && components.length) {
                  (_loader || _load_loader()).default.start((_loaderMessages || _load_loaderMessages()).BEFORE_RUNNING_SPECS);
                }
                this.injectNodePathIfNeeded(consumer, components);

                test = function () {
                  var _ref11 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee9(component) {
                    var specs, pass;
                    return (_regenerator || _load_regenerator()).default.wrap(function _callee9$(_context9) {
                      while (1) {
                        switch (_context9.prev = _context9.next) {
                          case 0:
                            if (component.tester) {
                              _context9.next = 2;
                              break;
                            }

                            return _context9.abrupt('return', { componentId: component.id, missingTester: true, pass: true });

                          case 2:
                            _context9.next = 4;
                            return component.runSpecs({
                              scope: _this4,
                              rejectOnFailure,
                              consumer,
                              verbose
                            });

                          case 4:
                            specs = _context9.sent;
                            pass = specs ? specs.every(function (spec) {
                              return spec.pass;
                            }) : true;
                            return _context9.abrupt('return', { componentId: component.id, specs, pass });

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

                  return function test(_x10) {
                    return _ref11.apply(this, arguments);
                  };
                }();

                return _context10.abrupt('return', (0, (_pMapSeries || _load_pMapSeries()).default)(components, test));

              case 5:
              case 'end':
                return _context10.stop();
            }
          }
        }, _callee10, this);
      }));

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

      return testMultiple;
    }()

    /**
     * Writes a component as an object into the 'objects' directory
     */

  }, {
    key: 'writeComponentToModel',
    value: function writeComponentToModel(componentObjects) {
      var _this5 = this;

      var objects = componentObjects.toObjects(this.objects);
      (_logger || _load_logger()).default.debugAndAddBreadCrumb('writeComponentToModel', 'writing into the model, Main id: {id}. It might have dependencies which are going to be written too', { id: objects.component.id().toString() });
      return this.sources.merge(objects).then(function () {
        return _this5.objects.persist();
      });
    }

    /**
     * Writes components as objects into the 'objects' directory
     */

  }, {
    key: 'writeManyComponentsToModel',
    value: function () {
      var _ref12 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee11(componentsObjects) {
        var _this6 = this;

        var persist = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
        var manyObjects;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee11$(_context11) {
          while (1) {
            switch (_context11.prev = _context11.next) {
              case 0:
                manyObjects = componentsObjects.map(function (componentObjects) {
                  return componentObjects.toObjects(_this6.objects);
                });

                (_logger || _load_logger()).default.debugAndAddBreadCrumb('scope.writeManyComponentsToModel', 'writing into the model, ids: {ids}. They might have dependencies which are going to be written too', { ids: manyObjects.map(function (objects) {
                    return objects.component.id();
                  }).join(', ') });
                _context11.next = 4;
                return Promise.all(manyObjects.map(function (objects) {
                  return _this6.sources.merge(objects);
                }));

              case 4:
                return _context11.abrupt('return', persist ? this.objects.persist() : Promise.resolve());

              case 5:
              case 'end':
                return _context11.stop();
            }
          }
        }, _callee11, this);
      }));

      function writeManyComponentsToModel(_x11) {
        return _ref12.apply(this, arguments);
      }

      return writeManyComponentsToModel;
    }()
  }, {
    key: 'getObject',
    value: function getObject(hash) {
      return new (_objects || _load_objects()).Ref(hash).load(this.objects);
    }
  }, {
    key: 'getRawObject',
    value: function getRawObject(hash) {
      return this.objects.loadRawObject(new (_objects || _load_objects()).Ref(hash));
    }
  }, {
    key: 'getModelComponentIfExist',
    value: function () {
      var _ref13 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee12(id) {
        return (_regenerator || _load_regenerator()).default.wrap(function _callee12$(_context12) {
          while (1) {
            switch (_context12.prev = _context12.next) {
              case 0:
                return _context12.abrupt('return', this.sources.get(id));

              case 1:
              case 'end':
                return _context12.stop();
            }
          }
        }, _callee12, this);
      }));

      function getModelComponentIfExist(_x13) {
        return _ref13.apply(this, arguments);
      }

      return getModelComponentIfExist;
    }()
  }, {
    key: 'deprecateSingle',
    value: function () {
      var _ref14 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee13(bitId) {
        var component;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee13$(_context13) {
          while (1) {
            switch (_context13.prev = _context13.next) {
              case 0:
                _context13.next = 2;
                return this.getModelComponentIfExist(bitId);

              case 2:
                component = _context13.sent;

                component.deprecated = true;
                this.objects.add(component);
                return _context13.abrupt('return', bitId.toStringWithoutVersion());

              case 6:
              case 'end':
                return _context13.stop();
            }
          }
        }, _callee13, this);
      }));

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

      return deprecateSingle;
    }()

    /**
     * Remove components from scope
     * @force Boolean - remove component from scope even if other components use it
     */

  }, {
    key: 'removeMany',
    value: function () {
      var _ref15 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee14(bitIds, force) {
        var removeSameOrigin = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
        var consumer = arguments[3];
        var removeComponents;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee14$(_context14) {
          while (1) {
            switch (_context14.prev = _context14.next) {
              case 0:
                (_logger || _load_logger()).default.debug(`scope.removeMany ${bitIds.toString()} with force flag: ${force.toString()}`);
                (_analytics || _load_analytics()).Analytics.addBreadCrumb('removeMany', `scope.removeMany ${(_analytics || _load_analytics()).Analytics.hashData(bitIds)} with force flag: ${force.toString()}`);
                removeComponents = new (_removeModelComponents || _load_removeModelComponents()).default(this, bitIds, force, removeSameOrigin, consumer);
                return _context14.abrupt('return', removeComponents.remove());

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

      function removeMany(_x15, _x16) {
        return _ref15.apply(this, arguments);
      }

      return removeMany;
    }()

    /**
     * findDependentBits
     * foreach component in array find the componnet that uses that component
     */

  }, {
    key: 'findDependentBits',
    value: function () {
      var _ref16 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee17(bitIds) {
        var _this7 = this;

        var returnResultsWithVersion = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
        var allComponents, allComponentVersions, allScopeComponents, dependentBits;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee17$(_context17) {
          while (1) {
            switch (_context17.prev = _context17.next) {
              case 0:
                _context17.next = 2;
                return this.list();

              case 2:
                allComponents = _context17.sent;
                _context17.next = 5;
                return Promise.all(allComponents.map(function () {
                  var _ref17 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee16(component) {
                    var loadedVersions;
                    return (_regenerator || _load_regenerator()).default.wrap(function _callee16$(_context16) {
                      while (1) {
                        switch (_context16.prev = _context16.next) {
                          case 0:
                            _context16.next = 2;
                            return Promise.all(Object.keys(component.versions).map(function () {
                              var _ref18 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee15(version) {
                                var componentVersion;
                                return (_regenerator || _load_regenerator()).default.wrap(function _callee15$(_context15) {
                                  while (1) {
                                    switch (_context15.prev = _context15.next) {
                                      case 0:
                                        _context15.next = 2;
                                        return component.loadVersion(version, _this7.objects);

                                      case 2:
                                        componentVersion = _context15.sent;

                                        if (componentVersion) {
                                          _context15.next = 5;
                                          break;
                                        }

                                        return _context15.abrupt('return');

                                      case 5:
                                        componentVersion.id = component.toBitId();
                                        return _context15.abrupt('return', componentVersion);

                                      case 7:
                                      case 'end':
                                        return _context15.stop();
                                    }
                                  }
                                }, _callee15, _this7);
                              }));

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

                          case 2:
                            loadedVersions = _context16.sent;
                            return _context16.abrupt('return', loadedVersions.filter(function (x) {
                              return x;
                            }));

                          case 4:
                          case 'end':
                            return _context16.stop();
                        }
                      }
                    }, _callee16, _this7);
                  }));

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

              case 5:
                allComponentVersions = _context17.sent;
                allScopeComponents = (_ramda || _load_ramda()).default.flatten(allComponentVersions);
                dependentBits = {};

                bitIds.forEach(function (bitId) {
                  var dependencies = [];
                  allScopeComponents.forEach(function (scopeComponents) {
                    scopeComponents.flattenedDependencies.forEach(function (flattenedDependency) {
                      if (flattenedDependency.isEqualWithoutVersion(bitId)) {
                        returnResultsWithVersion ? dependencies.push(scopeComponents.id) : dependencies.push(scopeComponents.id.changeVersion(null));
                      }
                    });
                  });

                  if (!(_ramda || _load_ramda()).default.isEmpty(dependencies)) {
                    dependentBits[bitId.toStringWithoutVersion()] = (_bitId || _load_bitId()).BitIds.uniqFromArray(dependencies);
                  }
                });
                return _context17.abrupt('return', Promise.resolve(dependentBits));

              case 10:
              case 'end':
                return _context17.stop();
            }
          }
        }, _callee17, this);
      }));

      function findDependentBits(_x18) {
        return _ref16.apply(this, arguments);
      }

      return findDependentBits;
    }()

    /**
     * split bit array to found and missing components (incase user misspelled id)
     */

  }, {
    key: 'filterFoundAndMissingComponents',
    value: function () {
      var _ref19 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee19(bitIds) {
        var _this8 = this;

        var missingComponents, foundComponents, resultP;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee19$(_context19) {
          while (1) {
            switch (_context19.prev = _context19.next) {
              case 0:
                missingComponents = new (_bitId || _load_bitId()).BitIds();
                foundComponents = new (_bitId || _load_bitId()).BitIds();
                resultP = bitIds.map(function () {
                  var _ref20 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee18(id) {
                    var component;
                    return (_regenerator || _load_regenerator()).default.wrap(function _callee18$(_context18) {
                      while (1) {
                        switch (_context18.prev = _context18.next) {
                          case 0:
                            _context18.next = 2;
                            return _this8.getModelComponentIfExist(id);

                          case 2:
                            component = _context18.sent;

                            if (!component) missingComponents.push(id);else foundComponents.push(id);

                          case 4:
                          case 'end':
                            return _context18.stop();
                        }
                      }
                    }, _callee18, _this8);
                  }));

                  return function (_x23) {
                    return _ref20.apply(this, arguments);
                  };
                }());
                _context19.next = 5;
                return Promise.all(resultP);

              case 5:
                return _context19.abrupt('return', { missingComponents, foundComponents });

              case 6:
              case 'end':
                return _context19.stop();
            }
          }
        }, _callee19, this);
      }));

      function filterFoundAndMissingComponents(_x22) {
        return _ref19.apply(this, arguments);
      }

      return filterFoundAndMissingComponents;
    }()

    /**
     * deprecate components from scope
     */

  }, {
    key: 'deprecateMany',
    value: function () {
      var _ref21 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee20(bitIds) {
        var _this9 = this;

        var _ref22, missingComponents, foundComponents, deprecatedComponentsP, deprecatedComponents, missingComponentsStrings;

        return (_regenerator || _load_regenerator()).default.wrap(function _callee20$(_context20) {
          while (1) {
            switch (_context20.prev = _context20.next) {
              case 0:
                (_logger || _load_logger()).default.debug(`scope.deprecateMany, ids: ${bitIds.toString()}`);
                _context20.next = 3;
                return this.filterFoundAndMissingComponents(bitIds);

              case 3:
                _ref22 = _context20.sent;
                missingComponents = _ref22.missingComponents;
                foundComponents = _ref22.foundComponents;
                deprecatedComponentsP = foundComponents.map(function (bitId) {
                  return _this9.deprecateSingle(bitId);
                });
                _context20.next = 9;
                return Promise.all(deprecatedComponentsP);

              case 9:
                deprecatedComponents = _context20.sent;
                _context20.next = 12;
                return this.objects.persist();

              case 12:
                missingComponentsStrings = missingComponents.map(function (id) {
                  return id.toStringWithoutVersion();
                });
                return _context20.abrupt('return', { bitIds: deprecatedComponents, missingComponents: missingComponentsStrings });

              case 14:
              case 'end':
                return _context20.stop();
            }
          }
        }, _callee20, this);
      }));

      function deprecateMany(_x24) {
        return _ref21.apply(this, arguments);
      }

      return deprecateMany;
    }()

    /**
     * load components from the model and return them as ComponentVersion array.
     * if a component is not available locally, it'll just ignore it without throwing any error.
     */

  }, {
    key: 'loadLocalComponents',
    value: function () {
      var _ref23 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee21(ids) {
        var componentsObjects, components;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee21$(_context21) {
          while (1) {
            switch (_context21.prev = _context21.next) {
              case 0:
                _context21.next = 2;
                return this.sources.getMany(ids);

              case 2:
                componentsObjects = _context21.sent;
                components = componentsObjects.map(function (componentObject) {
                  var component = componentObject.component;
                  if (!component) return null;
                  var version = componentObject.id.hasVersion() ? componentObject.id.version : component.latest();
                  return component.toComponentVersion(version);
                });
                return _context21.abrupt('return', removeNils(components));

              case 5:
              case 'end':
                return _context21.stop();
            }
          }
        }, _callee21, this);
      }));

      function loadLocalComponents(_x25) {
        return _ref23.apply(this, arguments);
      }

      return loadLocalComponents;
    }()
  }, {
    key: 'loadComponentLogs',
    value: function loadComponentLogs(id) {
      var _this10 = this;

      return this.getModelComponentIfExist(id).then(function (componentModel) {
        if (!componentModel) throw new (_exceptions || _load_exceptions()).ComponentNotFound(id.toString());
        return componentModel.collectLogs(_this10.objects);
      });
    }
  }, {
    key: 'loadAllVersions',
    value: function loadAllVersions(id) {
      var _this11 = this;

      return this.getModelComponentIfExist(id).then(function (componentModel) {
        if (!componentModel) throw new (_exceptions || _load_exceptions()).ComponentNotFound(id.toString());
        return componentModel.collectVersions(_this11.objects);
      });
    }

    /**
     * get ModelComponent instance per bit-id.
     * it throws an error if the component wasn't found.
     * @see getModelComponentIfExist to not throw an error
     * @see getModelComponentIgnoreScope to ignore the scope name
     */

  }, {
    key: 'getModelComponent',
    value: function () {
      var _ref24 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee22(id) {
        var component;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee22$(_context22) {
          while (1) {
            switch (_context22.prev = _context22.next) {
              case 0:
                _context22.next = 2;
                return this.getModelComponentIfExist(id);

              case 2:
                component = _context22.sent;

                if (!component) {
                  _context22.next = 5;
                  break;
                }

                return _context22.abrupt('return', component);

              case 5:
                throw new (_exceptions || _load_exceptions()).ComponentNotFound(id.toString());

              case 6:
              case 'end':
                return _context22.stop();
            }
          }
        }, _callee22, this);
      }));

      function getModelComponent(_x26) {
        return _ref24.apply(this, arguments);
      }

      return getModelComponent;
    }()

    /**
     * the id can be either with or without a scope-name.
     * in case the component is saved in the model only with the scope (imported), it loads all
     * components and search for it.
     * it throws an error if the component wasn't found.
     */

  }, {
    key: 'getModelComponentIgnoreScope',
    value: function () {
      var _ref25 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee23(id) {
        var component, components, foundComponent;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee23$(_context23) {
          while (1) {
            switch (_context23.prev = _context23.next) {
              case 0:
                _context23.next = 2;
                return this.getModelComponentIfExist(id);

              case 2:
                component = _context23.sent;

                if (!component) {
                  _context23.next = 5;
                  break;
                }

                return _context23.abrupt('return', component);

              case 5:
                if (id.scope) {
                  _context23.next = 12;
                  break;
                }

                _context23.next = 8;
                return this.list();

              case 8:
                components = _context23.sent;
                foundComponent = components.filter(function (c) {
                  return c.toBitId().isEqualWithoutScopeAndVersion(id);
                });
                // $FlowFixMe

                if (!foundComponent.length) {
                  _context23.next = 12;
                  break;
                }

                return _context23.abrupt('return', (0, (_utils || _load_utils()).first)(foundComponent));

              case 12:
                throw new (_exceptions || _load_exceptions()).ComponentNotFound(id.toString());

              case 13:
              case 'end':
                return _context23.stop();
            }
          }
        }, _callee23, this);
      }));

      function getModelComponentIgnoreScope(_x27) {
        return _ref25.apply(this, arguments);
      }

      return getModelComponentIgnoreScope;
    }()

    /**
     * throws if component was not found
     */

  }, {
    key: 'getConsumerComponent',
    value: function () {
      var _ref26 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee24(id) {
        var modelComponent, componentVersion;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee24$(_context24) {
          while (1) {
            switch (_context24.prev = _context24.next) {
              case 0:
                _context24.next = 2;
                return this.getModelComponent(id);

              case 2:
                modelComponent = _context24.sent;

                // $FlowFixMe version must be set
                componentVersion = modelComponent.toComponentVersion(id.version);
                return _context24.abrupt('return', componentVersion.toConsumer(this.objects));

              case 5:
              case 'end':
                return _context24.stop();
            }
          }
        }, _callee24, this);
      }));

      function getConsumerComponent(_x28) {
        return _ref26.apply(this, arguments);
      }

      return getConsumerComponent;
    }()
  }, {
    key: 'getVersionInstance',
    value: function () {
      var _ref27 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee25(id) {
        var component;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee25$(_context25) {
          while (1) {
            switch (_context25.prev = _context25.next) {
              case 0:
                if (id.hasVersion()) {
                  _context25.next = 2;
                  break;
                }

                throw new TypeError(`scope.getVersionInstance - id ${id.toString()} is missing the version`);

              case 2:
                _context25.next = 4;
                return this.getModelComponent(id);

              case 4:
                component = _context25.sent;
                return _context25.abrupt('return', component.loadVersion(id.version, this.objects));

              case 6:
              case 'end':
                return _context25.stop();
            }
          }
        }, _callee25, this);
      }));

      function getVersionInstance(_x29) {
        return _ref27.apply(this, arguments);
      }

      return getVersionInstance;
    }()
  }, {
    key: 'getComponentsAndVersions',
    value: function () {
      var _ref28 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee27(ids) {
        var _this12 = this;

        var componentsObjects, componentsAndVersionsP, componentsAndVersions;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee27$(_context27) {
          while (1) {
            switch (_context27.prev = _context27.next) {
              case 0:
                _context27.next = 2;
                return this.sources.getMany(ids);

              case 2:
                componentsObjects = _context27.sent;
                componentsAndVersionsP = componentsObjects.map(function () {
                  var _ref29 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee26(componentObjects) {
                    var component, versionStr, version;
                    return (_regenerator || _load_regenerator()).default.wrap(function _callee26$(_context26) {
                      while (1) {
                        switch (_context26.prev = _context26.next) {
                          case 0:
                            if (componentObjects.component) {
                              _context26.next = 2;
                              break;
                            }

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

                          case 2:
                            component = componentObjects.component;
                            versionStr = componentObjects.id.getVersion().toString();
                            _context26.next = 6;
                            return component.loadVersion(versionStr, _this12.objects);

                          case 6:
                            version = _context26.sent;
                            return _context26.abrupt('return', { component, version, versionStr });

                          case 8:
                          case 'end':
                            return _context26.stop();
                        }
                      }
                    }, _callee26, _this12);
                  }));

                  return function (_x31) {
                    return _ref29.apply(this, arguments);
                  };
                }());
                _context27.next = 6;
                return Promise.all(componentsAndVersionsP);

              case 6:
                componentsAndVersions = _context27.sent;
                return _context27.abrupt('return', removeNils(componentsAndVersions));

              case 8:
              case 'end':
                return _context27.stop();
            }
          }
        }, _callee27, this);
      }));

      function getComponentsAndVersions(_x30) {
        return _ref28.apply(this, arguments);
      }

      return getComponentsAndVersions;
    }()

    /**
     * Creates a symlink object with the local-scope which links to the real-object of the remote-scope
     * This way, local components that have dependencies to the exported component won't break.
     */

  }, {
    key: 'createSymlink',
    value: function createSymlink(id, remote) {
      var symlink = new (_models || _load_models()).Symlink({
        scope: id.scope,
        name: id.name,
        realScope: remote
      });
      return this.objects.add(symlink);
    }
  }, {
    key: 'ensureDir',
    value: function ensureDir() {
      var _this13 = this;

      (_fsExtra || _load_fsExtra()).default.ensureDirSync(this.getComponentsPath());
      return this.tmp.ensureDir().then(function () {
        return _this13.scopeJson.write(_this13.getPath());
      }).then(function () {
        return _this13.objects.ensureDir();
      }).then(function () {
        return _this13;
      });
    }

    /**
     * find the components in componentsPool which one of their dependencies include in potentialDependencies
     */

  }, {
    key: 'findDirectDependentComponents',
    value: function () {
      var _ref30 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee29(componentsPool, potentialDependencies) {
        var _this14 = this;

        var componentsVersions, dependentsP, dependents;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee29$(_context29) {
          while (1) {
            switch (_context29.prev = _context29.next) {
              case 0:
                _context29.next = 2;
                return this.loadLocalComponents(componentsPool);

              case 2:
                componentsVersions = _context29.sent;
                dependentsP = componentsVersions.map(function () {
                  var _ref31 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee28(componentVersion) {
                    var component, found;
                    return (_regenerator || _load_regenerator()).default.wrap(function _callee28$(_context28) {
                      while (1) {
                        switch (_context28.prev = _context28.next) {
                          case 0:
                            _context28.next = 2;
                            return componentVersion.getVersion(_this14.objects);

                          case 2:
                            component = _context28.sent;
                            found = component.getAllDependencies().find(function (dependency) {
                              return potentialDependencies.searchWithoutVersion(dependency.id);
                            });
                            return _context28.abrupt('return', found ? componentVersion : null);

                          case 5:
                          case 'end':
                            return _context28.stop();
                        }
                      }
                    }, _callee28, _this14);
                  }));

                  return function (_x34) {
                    return _ref31.apply(this, arguments);
                  };
                }());
                _context29.next = 6;
                return Promise.all(dependentsP);

              case 6:
                dependents = _context29.sent;
                return _context29.abrupt('return', removeNils(dependents));

              case 8:
              case 'end':
                return _context29.stop();
            }
          }
        }, _callee29, this);
      }));

      function findDirectDependentComponents(_x32, _x33) {
        return _ref30.apply(this, arguments);
      }

      return findDirectDependentComponents;
    }()
  }, {
    key: 'runComponentSpecs',
    value: function () {
      var _ref32 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee30(_ref33) {
        var bitId = _ref33.bitId,
            consumer = _ref33.consumer,
            save = _ref33.save,
            verbose = _ref33.verbose,
            isolated = _ref33.isolated,
            directory = _ref33.directory,
            keep = _ref33.keep;
        var component;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee30$(_context30) {
          while (1) {
            switch (_context30.prev = _context30.next) {
              case 0:
                if (bitId.isLocal(this.name)) {
                  _context30.next = 2;
                  break;
                }

                throw new (_generalError || _load_generalError()).default('cannot run specs on remote component');

              case 2:
                _context30.next = 4;
                return this.getConsumerComponent(bitId);

              case 4:
                component = _context30.sent;
                return _context30.abrupt('return', component.runSpecs({
                  scope: this,
                  consumer,
                  save,
                  verbose,
                  isolated,
                  directory,
                  keep
                }));

              case 6:
              case 'end':
                return _context30.stop();
            }
          }
        }, _callee30, this);
      }));

      function runComponentSpecs(_x35) {
        return _ref32.apply(this, arguments);
      }

      return runComponentSpecs;
    }()
  }, {
    key: 'build',
    value: function () {
      var _ref34 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee31(_ref35) {
        var bitId = _ref35.bitId,
            save = _ref35.save,
            consumer = _ref35.consumer,
            verbose = _ref35.verbose,
            directory = _ref35.directory,
            keep = _ref35.keep;
        var component;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee31$(_context31) {
          while (1) {
            switch (_context31.prev = _context31.next) {
              case 0:
                if (bitId.isLocal(this.name)) {
                  _context31.next = 2;
                  break;
                }

                throw new (_generalError || _load_generalError()).default('cannot run build on remote component');

              case 2:
                _context31.next = 4;
                return this.getConsumerComponent(bitId);

              case 4:
                component = _context31.sent;
                return _context31.abrupt('return', component.build({
                  scope: this,
                  save,
                  consumer,
                  verbose,
                  directory,
                  keep
                }));

              case 6:
              case 'end':
                return _context31.stop();
            }
          }
        }, _callee31, this);
      }));

      function build(_x36) {
        return _ref34.apply(this, arguments);
      }

      return build;
    }()
  }, {
    key: 'loadModelComponentByIdStr',
    value: function () {
      var _ref36 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee32(id) {
        var idWithoutVersion, ref;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee32$(_context32) {
          while (1) {
            switch (_context32.prev = _context32.next) {
              case 0:
                // Remove the version before hashing since hashing with the version number will result a wrong hash
                idWithoutVersion = (_bitId || _load_bitId()).BitId.getStringWithoutVersion(id);
                ref = (_objects || _load_objects()).Ref.from((_objects || _load_objects()).BitObject.makeHash(idWithoutVersion));
                // $FlowFixMe

                return _context32.abrupt('return', this.objects.load(ref));

              case 3:
              case 'end':
                return _context32.stop();
            }
          }
        }, _callee32, this);
      }));

      function loadModelComponentByIdStr(_x37) {
        return _ref36.apply(this, arguments);
      }

      return loadModelComponentByIdStr;
    }()

    /**
     * if it's not in the scope, it's probably new, we assume it doesn't have scope.
     */

  }, {
    key: 'isIdHasScope',
    value: function () {
      var _ref37 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee33(id) {
        var component;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee33$(_context33) {
          while (1) {
            switch (_context33.prev = _context33.next) {
              case 0:
                _context33.next = 2;
                return this.loadModelComponentByIdStr(id);

              case 2:
                component = _context33.sent;
                return _context33.abrupt('return', Boolean(component && component.scope));

              case 4:
              case 'end':
                return _context33.stop();
            }
          }
        }, _callee33, this);
      }));

      function isIdHasScope(_x38) {
        return _ref37.apply(this, arguments);
      }

      return isIdHasScope;
    }()
  }, {
    key: 'getParsedId',
    value: function () {
      var _ref38 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee34(id) {
        var idHasScope;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee34$(_context34) {
          while (1) {
            switch (_context34.prev = _context34.next) {
              case 0:
                _context34.next = 2;
                return this.isIdHasScope(id);

              case 2:
                idHasScope = _context34.sent;
                return _context34.abrupt('return', (_bitId || _load_bitId()).BitId.parse(id, idHasScope));

              case 4:
              case 'end':
                return _context34.stop();
            }
          }
        }, _callee34, this);
      }));

      function getParsedId(_x39) {
        return _ref38.apply(this, arguments);
      }

      return getParsedId;
    }()
  }, {
    key: 'groupName',
    get: function get() {
      if (!this.scopeJson.groupName) return null;
      return this.scopeJson.groupName;
    }
  }, {
    key: 'name',
    get: function get() {
      return this.scopeJson.name;
    }
  }], [{
    key: 'getComponentsRelativePath',
    value: function getComponentsRelativePath() {
      return (_constants || _load_constants()).BITS_DIRNAME;
    }

    /**
     * Get a relative (to scope) path to a specific component such as compiler / tester / extension
     * Support getting the latest installed version
     * @param {BitId} id
     */

  }, {
    key: 'getComponentRelativePath',
    value: function getComponentRelativePath(id, scopePath) {
      if (!id.scope) {
        throw new Error('could not find id.scope');
      }
      var relativePath = (_path || _load_path()).join(id.name, id.scope);
      if (!id.getVersion().latest) {
        if (!id.version) {
          // brought closer because flow can't deduce if it's done in the beginning.
          throw new Error('could not find id.version');
        }
        return (_path || _load_path()).join(relativePath, id.version);
      }
      if (!scopePath) {
        throw new Error(`could not find the latest version of ${id.toString()} without the scope path`);
      }
      var componentFullPath = (_path || _load_path()).join(scopePath, Scope.getComponentsRelativePath(), relativePath);
      if (!(_fsExtra || _load_fsExtra()).default.existsSync(componentFullPath)) return '';
      var versions = (_fsExtra || _load_fsExtra()).default.readdirSync(componentFullPath);
      var latestVersion = (_semver || _load_semver()).default.maxSatisfying(versions, '*');
      return (_path || _load_path()).join(relativePath, latestVersion);
    }
  }, {
    key: 'ensure',
    value: function ensure(path, name, groupName) {
      if (pathHasScope(path)) return this.load(path);
      if (!name) name = (0, (_utils || _load_utils()).currentDirName)();
      var scopeJson = new (_scopeJson || _load_scopeJson()).ScopeJson({ name, groupName, version: (_constants || _load_constants()).BIT_VERSION });
      var repository = (_objects || _load_objects()).Repository.create({ scopePath: path, scopeJson });
      return Promise.resolve(new Scope({ path, created: true, scopeJson, objects: repository }));
    }
  }, {
    key: 'reset',
    value: function () {
      var _ref39 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee35(path, resetHard) {
        return (_regenerator || _load_regenerator()).default.wrap(function _callee35$(_context35) {
          while (1) {
            switch (_context35.prev = _context35.next) {
              case 0:
                _context35.next = 2;
                return (_objects || _load_objects()).Repository.reset(path);

              case 2:
                if (!resetHard) {
                  _context35.next = 6;
                  break;
                }

                (_logger || _load_logger()).default.info(`deleting the whole scope at ${path}`);
                _context35.next = 6;
                return (_fsExtra || _load_fsExtra()).default.emptyDir(path);

              case 6:
              case 'end':
                return _context35.stop();
            }
          }
        }, _callee35, this);
      }));

      function reset(_x40, _x41) {
        return _ref39.apply(this, arguments);
      }

      return reset;
    }()
  }, {
    key: 'load',
    value: function () {
      var _ref40 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee36(absPath) {
        var scopePath, scopeJson, objects;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee36$(_context36) {
          while (1) {
            switch (_context36.prev = _context36.next) {
              case 0:
                scopePath = (0, (_utils || _load_utils()).propogateUntil)(absPath);

                if (scopePath) {
                  _context36.next = 3;
                  break;
                }

                throw new (_exceptions || _load_exceptions()).ScopeNotFound();

              case 3:
                if ((_fsExtra || _load_fsExtra()).default.existsSync((_path || _load_path()).join(scopePath, (_constants || _load_constants()).BIT_HIDDEN_DIR))) {
                  scopePath = (_path || _load_path()).join(scopePath, (_constants || _load_constants()).BIT_HIDDEN_DIR);
                }

                _context36.next = 6;
                return (_scopeJson || _load_scopeJson()).ScopeJson.loadFromFile((0, (_scopeJson || _load_scopeJson()).getPath)(scopePath));

              case 6:
                scopeJson = _context36.sent;
                _context36.next = 9;
                return (_objects || _load_objects()).Repository.load({ scopePath, scopeJson });

              case 9:
                objects = _context36.sent;
                return _context36.abrupt('return', new Scope({ path: scopePath, scopeJson, objects }));

              case 11:
              case 'end':
                return _context36.stop();
            }
          }
        }, _callee36, this);
      }));

      function load(_x42) {
        return _ref40.apply(this, arguments);
      }

      return load;
    }()
  }]);

  return Scope;
}();

exports.default = Scope;