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

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

var _fsExtra;

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

var _path;

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

var _lodash;

function _load_lodash() {
  return _lodash = _interopRequireDefault(require('lodash.uniqby'));
}

var _object;

function _load_object() {
  return _object = _interopRequireDefault(require('./object'));
}

var _rawObject;

function _load_rawObject() {
  return _rawObject = _interopRequireDefault(require('./raw-object'));
}

var _ref18;

function _load_ref() {
  return _ref18 = _interopRequireDefault(require('./ref'));
}

var _constants;

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

var _exceptions;

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

var _utils;

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

var _fsRemoveFile;

function _load_fsRemoveFile() {
  return _fsRemoveFile = _interopRequireDefault(require('../../utils/fs-remove-file'));
}

var _scopeMeta;

function _load_scopeMeta() {
  return _scopeMeta = _interopRequireDefault(require('../models/scopeMeta'));
}

var _logger;

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

var _componentsIndex2;

function _load_componentsIndex() {
  return _componentsIndex2 = _interopRequireDefault(require('./components-index'));
}

var _scopeJson;

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

var _objectRegistrar;

function _load_objectRegistrar() {
  return _objectRegistrar = require('../object-registrar');
}

var _models;

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

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 OBJECTS_BACKUP_DIR = `${(_constants || _load_constants()).OBJECTS_DIR}.bak`;

var Repository = function () {
  function Repository(scopePath, scopeJson) {
    var types = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : (_objectRegistrar || _load_objectRegistrar()).typesObj;

    _classCallCheck(this, Repository);

    this.objects = {};
    this.objectsToRemove = [];
    this._cache = {};

    this.scopePath = scopePath;
    this.scopeJson = scopeJson;
    this.types = types;
  }

  _createClass(Repository, [{
    key: 'ensureDir',
    value: function ensureDir() {
      return (0, (_utils || _load_utils()).mkdirp)(this.getPath());
    }
  }, {
    key: 'getPath',
    value: function getPath() {
      return Repository.getPathByScopePath(this.scopePath);
    }
  }, {
    key: 'getBackupPath',
    value: function getBackupPath(dirName) {
      var backupPath = (_path || _load_path()).default.join(this.scopePath, OBJECTS_BACKUP_DIR);
      return dirName ? (_path || _load_path()).default.join(backupPath, dirName) : backupPath;
    }
  }, {
    key: 'getLicense',
    value: function getLicense() {
      return this.scopeJson.getPopulatedLicense();
    }
  }, {
    key: 'getScopeMetaObject',
    value: function getScopeMetaObject() {
      var _this = this;

      return this.getLicense().then(function (license) {
        return (_scopeMeta || _load_scopeMeta()).default.fromObject({ license, name: _this.scopeJson.name }).compress();
      });
    }
  }, {
    key: 'objectPath',
    value: function objectPath(ref) {
      var hash = ref.toString();
      return (_path || _load_path()).default.join(this.getPath(), hash.slice(0, 2), hash.slice(2));
    }
  }, {
    key: 'load',
    value: function load(ref) {
      var _this2 = this;

      var throws = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;

      if (this.getCache(ref)) return Promise.resolve(this.getCache(ref));
      return (_fsExtra || _load_fsExtra()).default.readFile(this.objectPath(ref)).then(function (fileContents) {
        return (_object || _load_object()).default.parseObject(fileContents, _this2.types);
      }).then(function (parsedObject) {
        _this2.setCache(parsedObject);
        return parsedObject;
      }).catch(function (err) {
        if (err.code === 'ENOENT') {
          (_logger || _load_logger()).default.debug(`Failed finding a ref file ${_this2.objectPath(ref)}.`);
        } else {
          (_logger || _load_logger()).default.error(`Failed reading a ref file ${_this2.objectPath(ref)}. Error: ${err.message}`);
        }
        if (throws) throw err;
        return null;
      });
    }
  }, {
    key: 'list',
    value: function () {
      var _ref = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee() {
        var _this3 = this;

        var refs;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                _context.next = 2;
                return this.listRefs();

              case 2:
                refs = _context.sent;
                return _context.abrupt('return', Promise.all(refs.map(function (ref) {
                  return _this3.load(ref);
                })));

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

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

      return list;
    }()
  }, {
    key: 'listRefs',
    value: function () {
      var _ref2 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee2() {
        var matches, refs;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee2$(_context2) {
          while (1) {
            switch (_context2.prev = _context2.next) {
              case 0:
                _context2.next = 2;
                return (0, (_utils || _load_utils()).glob)((_path || _load_path()).default.join('*', '*'), { cwd: this.getPath() });

              case 2:
                matches = _context2.sent;
                refs = matches.map(function (str) {
                  var hash = str.replace((_path || _load_path()).default.sep, '');
                  return new (_ref18 || _load_ref()).default(hash);
                });
                return _context2.abrupt('return', refs);

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

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

      return listRefs;
    }()
  }, {
    key: 'listRawObjects',
    value: function () {
      var _ref3 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee4() {
        var _this4 = this;

        var refs;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee4$(_context4) {
          while (1) {
            switch (_context4.prev = _context4.next) {
              case 0:
                _context4.next = 2;
                return this.listRefs();

              case 2:
                refs = _context4.sent;
                return _context4.abrupt('return', Promise.all(refs.map(function () {
                  var _ref4 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee3(ref) {
                    var buffer, bitRawObject;
                    return (_regenerator || _load_regenerator()).default.wrap(function _callee3$(_context3) {
                      while (1) {
                        switch (_context3.prev = _context3.next) {
                          case 0:
                            _context3.prev = 0;
                            _context3.next = 3;
                            return _this4.loadRaw(ref);

                          case 3:
                            buffer = _context3.sent;
                            _context3.next = 6;
                            return (_rawObject || _load_rawObject()).default.fromDeflatedBuffer(buffer, ref.hash, _this4.types);

                          case 6:
                            bitRawObject = _context3.sent;
                            return _context3.abrupt('return', bitRawObject);

                          case 10:
                            _context3.prev = 10;
                            _context3.t0 = _context3['catch'](0);

                            (_logger || _load_logger()).default.error(`Couldn't load the ref ${ref} this object is probably corrupted and should be delete`);
                            return _context3.abrupt('return', null);

                          case 14:
                          case 'end':
                            return _context3.stop();
                        }
                      }
                    }, _callee3, _this4, [[0, 10]]);
                  }));

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

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

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

      return listRawObjects;
    }()
  }, {
    key: 'listComponentsIncludeSymlinks',
    value: function () {
      var _ref5 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee5() {
        var hashes;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee5$(_context5) {
          while (1) {
            switch (_context5.prev = _context5.next) {
              case 0:
                hashes = this.componentsIndex.getHashesIncludeSymlinks();
                return _context5.abrupt('return', this._getBitObjectsByHashes(hashes));

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

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

      return listComponentsIncludeSymlinks;
    }()
  }, {
    key: 'listComponents',
    value: function () {
      var _ref6 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee6() {
        var hashes;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee6$(_context6) {
          while (1) {
            switch (_context6.prev = _context6.next) {
              case 0:
                hashes = this.componentsIndex.getHashes();
                return _context6.abrupt('return', this._getBitObjectsByHashes(hashes));

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

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

      return listComponents;
    }()
  }, {
    key: '_getBitObjectsByHashes',
    value: function () {
      var _ref7 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee8(hashes) {
        var _this5 = this;

        var bitObjects;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee8$(_context8) {
          while (1) {
            switch (_context8.prev = _context8.next) {
              case 0:
                _context8.next = 2;
                return Promise.all(hashes.map(function () {
                  var _ref8 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee7(hash) {
                    var bitObject, componentId, indexJsonPath;
                    return (_regenerator || _load_regenerator()).default.wrap(function _callee7$(_context7) {
                      while (1) {
                        switch (_context7.prev = _context7.next) {
                          case 0:
                            _context7.next = 2;
                            return _this5.load(new (_ref18 || _load_ref()).default(hash));

                          case 2:
                            bitObject = _context7.sent;

                            if (bitObject) {
                              _context7.next = 10;
                              break;
                            }

                            componentId = _this5.componentsIndex.getIdByHash(hash);
                            indexJsonPath = _this5.componentsIndex.getPath();

                            if (!_this5.componentsIndex.isFileOnBitHub()) {
                              _context7.next = 9;
                              break;
                            }

                            (_logger || _load_logger()).default.error(`repository._getBitObjectsByHashes, indexJson at "${indexJsonPath}" is outdated and needs to be deleted`);
                            return _context7.abrupt('return', null);

                          case 9:
                            throw new (_exceptions || _load_exceptions()).OutdatedIndexJson(componentId, indexJsonPath);

                          case 10:
                            return _context7.abrupt('return', bitObject);

                          case 11:
                          case 'end':
                            return _context7.stop();
                        }
                      }
                    }, _callee7, _this5);
                  }));

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

              case 2:
                bitObjects = _context8.sent;
                return _context8.abrupt('return', bitObjects.filter(function (b) {
                  return b;
                }));

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

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

      return _getBitObjectsByHashes;
    }()
  }, {
    key: 'loadOptionallyCreateComponentsIndex',
    value: function () {
      var _ref9 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee9() {
        var componentsIndex, bitObjects, _componentsIndex;

        return (_regenerator || _load_regenerator()).default.wrap(function _callee9$(_context9) {
          while (1) {
            switch (_context9.prev = _context9.next) {
              case 0:
                _context9.prev = 0;
                _context9.next = 3;
                return (_componentsIndex2 || _load_componentsIndex()).default.load(this.scopePath);

              case 3:
                componentsIndex = _context9.sent;
                return _context9.abrupt('return', componentsIndex);

              case 7:
                _context9.prev = 7;
                _context9.t0 = _context9['catch'](0);

                if (!(_context9.t0.code === 'ENOENT')) {
                  _context9.next = 18;
                  break;
                }

                _context9.next = 12;
                return this.list();

              case 12:
                bitObjects = _context9.sent;
                _componentsIndex = (_componentsIndex2 || _load_componentsIndex()).default.create(this.scopePath);

                _componentsIndex.addMany(bitObjects);
                _context9.next = 17;
                return _componentsIndex.write();

              case 17:
                return _context9.abrupt('return', _componentsIndex);

              case 18:
                throw _context9.t0;

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

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

      return loadOptionallyCreateComponentsIndex;
    }()
  }, {
    key: 'loadRaw',
    value: function loadRaw(ref) {
      return (_fsExtra || _load_fsExtra()).default.readFile(this.objectPath(ref));
    }
  }, {
    key: 'loadRawObject',
    value: function () {
      var _ref10 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee10(ref) {
        var buffer, bitRawObject;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee10$(_context10) {
          while (1) {
            switch (_context10.prev = _context10.next) {
              case 0:
                _context10.next = 2;
                return this.loadRaw(ref);

              case 2:
                buffer = _context10.sent;
                _context10.next = 5;
                return (_rawObject || _load_rawObject()).default.fromDeflatedBuffer(buffer, ref.hash, this.types);

              case 5:
                bitRawObject = _context10.sent;
                return _context10.abrupt('return', bitRawObject);

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

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

      return loadRawObject;
    }()

    /**
     * prefer using `this.load()` for an async version, which also writes to the cache
     */

  }, {
    key: 'loadSync',
    value: function loadSync(ref) {
      var throws = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;

      try {
        var objectFile = (_fsExtra || _load_fsExtra()).default.readFileSync(this.objectPath(ref));
        return (_object || _load_object()).default.parseSync(objectFile, this.types);
      } catch (err) {
        if (throws) {
          throw new (_exceptions || _load_exceptions()).HashNotFound(ref.toString());
        }
        return null;
      }
    }
  }, {
    key: 'setCache',
    value: function setCache(object) {
      this._cache[object.hash().toString()] = object;
      return this;
    }
  }, {
    key: 'getCache',
    value: function getCache(ref) {
      return this._cache[ref.toString()];
    }
  }, {
    key: 'removeFromCache',
    value: function removeFromCache(ref) {
      delete this._cache[ref.toString()];
    }
  }, {
    key: 'backup',
    value: function backup(dirName) {
      var backupDir = this.getBackupPath(dirName);
      var objectsDir = this.getPath();
      (_logger || _load_logger()).default.debug(`making a backup of all objects from ${objectsDir} to ${backupDir}`);
      (_fsExtra || _load_fsExtra()).default.emptyDirSync(backupDir);
      (_fsExtra || _load_fsExtra()).default.copySync(objectsDir, backupDir);
    }
  }, {
    key: 'add',
    value: function add(object) {
      if (!object) return this;
      // leave the following commented log message, it is very useful for debugging but too verbose when not needed.
      // logger.debug(`repository: adding object ${object.hash().toString()} which consist of the following id: ${object.id()}`);
      this.objects[object.hash().toString()] = object;
      this.setCache(object);
      return this;
    }
  }, {
    key: 'addMany',
    value: function addMany(objects) {
      var _this6 = this;

      if (!objects || !objects.length) return this;
      objects.forEach(function (obj) {
        return _this6.add(obj);
      });
      return this;
    }
  }, {
    key: 'removeObject',
    value: function removeObject(ref) {
      this.objectsToRemove.push(ref);
    }
  }, {
    key: 'removeManyObjects',
    value: function removeManyObjects(refs) {
      var _this7 = this;

      if (!refs || !refs.length) return;
      refs.forEach(function (ref) {
        return _this7.removeObject(ref);
      });
    }
  }, {
    key: 'findMany',
    value: function findMany(refs) {
      var _this8 = this;

      return Promise.all(refs.map(function (ref) {
        return _this8.load(ref);
      }));
    }

    /**
     * persist objects changes (added and removed) into the filesystem
     * do not call this function multiple times in parallel, otherwise, it'll damage the index.json file.
     * call this function only once after you added and removed all applicable objects.
     */

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

        var validate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee11$(_context11) {
          while (1) {
            switch (_context11.prev = _context11.next) {
              case 0:
                (_logger || _load_logger()).default.debug(`Repository.persist, validate = ${validate.toString()}`);
                _context11.next = 3;
                return this._deleteMany();

              case 3:
                if (!validate) Object.keys(this.objects).map(function (hash) {
                  return _this9.objects[hash].validateBeforePersist = false;
                });
                _context11.next = 6;
                return this._writeMany();

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

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

      return persist;
    }()
  }, {
    key: '_deleteMany',
    value: function () {
      var _ref12 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee12() {
        var _this10 = this;

        var uniqRefs, removed;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee12$(_context12) {
          while (1) {
            switch (_context12.prev = _context12.next) {
              case 0:
                if (this.objectsToRemove.length) {
                  _context12.next = 2;
                  break;
                }

                return _context12.abrupt('return');

              case 2:
                uniqRefs = (0, (_lodash || _load_lodash()).default)(this.objectsToRemove, 'hash');

                (_logger || _load_logger()).default.debug(`Repository._deleteMany: deleting ${uniqRefs.length} objects`);
                _context12.next = 6;
                return Promise.all(uniqRefs.map(function (ref) {
                  return _this10._deleteOne(ref);
                }));

              case 6:
                removed = this.componentsIndex.removeMany(uniqRefs);

                if (!removed) {
                  _context12.next = 10;
                  break;
                }

                _context12.next = 10;
                return this.componentsIndex.write();

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

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

      return _deleteMany;
    }()
  }, {
    key: '_writeMany',
    value: function () {
      var _ref13 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee13() {
        var _this11 = this;

        var added;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee13$(_context13) {
          while (1) {
            switch (_context13.prev = _context13.next) {
              case 0:
                if (!(_ramda || _load_ramda()).default.isEmpty(this.objects)) {
                  _context13.next = 2;
                  break;
                }

                return _context13.abrupt('return');

              case 2:
                (_logger || _load_logger()).default.debug(`Repository._writeMany: writing ${Object.keys(this.objects).length} objects`);
                // @TODO handle failures
                _context13.next = 5;
                return Promise.all(Object.keys(this.objects).map(function (hash) {
                  return _this11._writeOne(_this11.objects[hash]);
                }));

              case 5:
                added = this.componentsIndex.addMany((_ramda || _load_ramda()).default.values(this.objects));

                if (!added) {
                  _context13.next = 9;
                  break;
                }

                _context13.next = 9;
                return this.componentsIndex.write();

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

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

      return _writeMany;
    }()

    /**
     * do not call this method directly. always call this.removeObject() and once done with all objects,
     * call this.persist()
     */

  }, {
    key: '_deleteOne',
    value: function _deleteOne(ref) {
      this.removeFromCache(ref);
      var pathToDelete = this.objectPath(ref);
      (_logger || _load_logger()).default.debug(`repository._deleteOne: deleting ${pathToDelete}`);
      return (0, (_fsRemoveFile || _load_fsRemoveFile()).default)(pathToDelete, true);
    }

    /**
     * always prefer this.persist().
     * this method doesn't write to componentsIndex. so using this method for ModelComponent or
     * Symlink makes the index outdated.
     */

  }, {
    key: '_writeOne',
    value: function () {
      var _ref14 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee14(object) {
        var contents, options, objectPath;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee14$(_context14) {
          while (1) {
            switch (_context14.prev = _context14.next) {
              case 0:
                _context14.next = 2;
                return object.compress();

              case 2:
                contents = _context14.sent;
                options = {};

                if (this.scopeJson.groupName) options.gid = (0, (_utils || _load_utils()).resolveGroupId)(this.scopeJson.groupName);
                objectPath = this.objectPath(object.hash());

                (_logger || _load_logger()).default.debug(`repository._writeOne: ${objectPath}`);
                return _context14.abrupt('return', (0, (_utils || _load_utils()).writeFile)(objectPath, contents, options));

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

      function _writeOne(_x9) {
        return _ref14.apply(this, arguments);
      }

      return _writeOne;
    }()
  }], [{
    key: 'load',
    value: function () {
      var _ref15 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee15(_ref16) {
        var scopePath = _ref16.scopePath,
            scopeJson = _ref16.scopeJson;
        var repository, componentsIndex;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee15$(_context15) {
          while (1) {
            switch (_context15.prev = _context15.next) {
              case 0:
                repository = new Repository(scopePath, scopeJson, (_objectRegistrar || _load_objectRegistrar()).typesObj);
                _context15.next = 3;
                return repository.loadOptionallyCreateComponentsIndex();

              case 3:
                componentsIndex = _context15.sent;

                repository.componentsIndex = componentsIndex;
                return _context15.abrupt('return', repository);

              case 6:
              case 'end':
                return _context15.stop();
            }
          }
        }, _callee15, this);
      }));

      function load(_x10) {
        return _ref15.apply(this, arguments);
      }

      return load;
    }()
  }, {
    key: 'create',
    value: function create(_ref17) {
      var scopePath = _ref17.scopePath,
          scopeJson = _ref17.scopeJson;

      var repository = new Repository(scopePath, scopeJson, (_objectRegistrar || _load_objectRegistrar()).typesObj);
      var componentsIndex = (_componentsIndex2 || _load_componentsIndex()).default.create(scopePath);
      repository.componentsIndex = componentsIndex;
      return repository;
    }
  }, {
    key: 'reset',
    value: function reset(scopePath) {
      return (_componentsIndex2 || _load_componentsIndex()).default.reset(scopePath);
    }
  }, {
    key: 'getPathByScopePath',
    value: function getPathByScopePath(scopePath) {
      return (_path || _load_path()).default.join(scopePath, (_constants || _load_constants()).OBJECTS_DIR);
    }
  }]);

  return Repository;
}();

exports.default = Repository;