UNPKG

bit-bin

Version:

<a href="https://opensource.org/licenses/Apache-2.0"><img alt="apache" src="https://img.shields.io/badge/License-Apache%202.0-blue.svg"></a> <a href="https://github.com/teambit/bit/blob/master/CONTRIBUTING.md"><img alt="prs" src="https://img.shields.io/b

500 lines (381 loc) 16.6 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; function _bluebird() { const data = require("bluebird"); _bluebird = function () { return data; }; return data; } function _defineProperty2() { const data = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); _defineProperty2 = function () { return data; }; return data; } function _ramda() { const data = _interopRequireDefault(require("ramda")); _ramda = function () { return data; }; return data; } function _pMapSeries() { const data = _interopRequireDefault(require("p-map-series")); _pMapSeries = function () { return data; }; return data; } function _enrichContextFromGlobal() { const data = _interopRequireDefault(require("../../hooks/utils/enrich-context-from-global")); _enrichContextFromGlobal = function () { return data; }; return data; } function _bitId() { const data = require("../../bit-id"); _bitId = function () { return data; }; return data; } function _versionDependencies() { const data = _interopRequireDefault(require("../version-dependencies")); _versionDependencies = function () { return data; }; return data; } function _logger() { const data = _interopRequireDefault(require("../../logger/logger")); _logger = function () { return data; }; return data; } function _exceptions() { const data = require("../network/exceptions"); _exceptions = function () { return data; }; return data; } function _exceptions2() { const data = require("../exceptions"); _exceptions2 = function () { return data; }; return data; } function _analytics() { const data = require("../../analytics/analytics"); _analytics = function () { return data; }; return data; } function _generalError() { const data = _interopRequireDefault(require("../../error/general-error")); _generalError = function () { return data; }; return data; } function _scopeRemotes() { const data = require("../scope-remotes"); _scopeRemotes = function () { return data; }; return data; } function _utils() { const data = require("../../utils"); _utils = function () { return data; }; return data; } function _showDoctorError() { const data = _interopRequireDefault(require("../../error/show-doctor-error")); _showDoctorError = function () { return data; }; return data; } const removeNils = _ramda().default.reject(_ramda().default.isNil); class ScopeComponentsImporter { constructor(scope) { (0, _defineProperty2().default)(this, "scope", void 0); (0, _defineProperty2().default)(this, "sources", void 0); if (!scope) throw new Error('unable to instantiate ScopeComponentsImporter without Scope'); this.scope = scope; this.sources = scope.sources; } static getInstance(scope) { return new ScopeComponentsImporter(scope); } /** * 1. Local objects, fetch from local. (done by this.sources.getMany method) * 2. Fetch flattened dependencies (done by toVersionDependencies method). If they're not locally, fetch from remote * and save them locally. * 3. External objects, fetch from a remote and save locally. (done by this.getExternalOnes method). */ importMany(ids, cache = true, persist = true) { var _this = this; return (0, _bluebird().coroutine)(function* () { _logger().default.debugAndAddBreadCrumb('ScopeComponentsImporter', 'importMany: {ids}', { ids: ids.toString() }); const idsWithoutNils = removeNils(ids); if (_ramda().default.isEmpty(idsWithoutNils)) return Promise.resolve([]); const [locals, externals] = _ramda().default.partition(id => id.isLocal(_this.scope.name), idsWithoutNils); const localDefs = yield _this.sources.getMany(locals); const versionDeps = yield (0, _pMapSeries().default)(localDefs, def => { if (!def.component) throw new (_exceptions2().ComponentNotFound)(def.id.toString()); return _this.componentToVersionDependencies(def.component, def.id); }); _logger().default.debugAndAddBreadCrumb('ScopeComponentsImporter', 'importMany: successfully fetched local components and their dependencies. Going to fetch externals'); const remotes = yield (0, _scopeRemotes().getScopeRemotes)(_this.scope); const externalDeps = yield _this._getExternalMany(externals, remotes, cache, persist); return versionDeps.concat(externalDeps); })(); } importManyWithoutDependencies(ids, cache = true) { var _this2 = this; return (0, _bluebird().coroutine)(function* () { if (!ids.length) return []; _logger().default.debug(`importManyWithoutDependencies. Ids: ${ids.join(', ')}, cache: ${cache.toString()}`); _analytics().Analytics.addBreadCrumb('importManyWithoutDependencies', `Ids: ${_analytics().Analytics.hashData(ids)}`); const idsWithoutNils = removeNils(ids); if (_ramda().default.isEmpty(idsWithoutNils)) return Promise.resolve([]); const [externals, locals] = (0, _utils().splitBy)(idsWithoutNils, id => id.isLocal(_this2.scope.name)); const localDefs = yield _this2.sources.getMany(locals); const componentVersionArr = yield Promise.all(localDefs.map(def => { if (!def.component) throw new (_exceptions2().ComponentNotFound)(def.id.toString()); // $FlowFixMe it must have a version // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! return def.component.toComponentVersion(def.id.version); })); const remotes = yield (0, _scopeRemotes().getScopeRemotes)(_this2.scope); const externalDeps = yield _this2._getExternalManyWithoutDependencies(externals, remotes, cache); return componentVersionArr.concat(externalDeps); })(); } /** * todo: improve performance by finding all versions needed and fetching them in one request from the server * currently it goes to the server twice. First, it asks for the last version of each id, and then it goes again to * ask for the older versions. */ importManyWithAllVersions(ids, cache = true, allDepsVersions = false // by default, only dependencies of the latest version are imported ) { var _this3 = this; return (0, _bluebird().coroutine)(function* () { _logger().default.debug(`scope.getManyWithAllVersions, Ids: ${ids.join(', ')}`); _analytics().Analytics.addBreadCrumb('getManyWithAllVersions', `scope.getManyWithAllVersions, Ids: ${_analytics().Analytics.hashData(ids)}`); const idsWithoutNils = removeNils(ids); if (_ramda().default.isEmpty(idsWithoutNils)) return Promise.resolve([]); const versionDependenciesArr = yield _this3.importMany(idsWithoutNils, cache); const allIdsWithAllVersions = new (_bitId().BitIds)(); versionDependenciesArr.forEach(versionDependencies => { const versions = versionDependencies.component.component.listVersions(); const idsWithAllVersions = versions.map(version => { if (version === versionDependencies.component.version) return null; // imported already const versionId = versionDependencies.component.id; return versionId.changeVersion(version); }); allIdsWithAllVersions.push(...removeNils(idsWithAllVersions)); }); if (allDepsVersions) { const verDepsOfOlderVersions = yield _this3.importMany(allIdsWithAllVersions, cache); versionDependenciesArr.push(...verDepsOfOlderVersions); const allFlattenDepsIds = versionDependenciesArr.map(v => v.allDependencies.map(d => d.id)); const dependenciesOnly = _ramda().default.flatten(allFlattenDepsIds).filter(id => !ids.hasWithoutVersion(id)); const verDepsOfAllFlattenDeps = yield _this3.importManyWithAllVersions(_bitId().BitIds.uniqFromArray(dependenciesOnly)); versionDependenciesArr.push(...verDepsOfAllFlattenDeps); } else { yield _this3.importManyWithoutDependencies(allIdsWithAllVersions); } return versionDependenciesArr; })(); } importDependencies(dependencies) { return new Promise((resolve, reject) => { return this.importMany(dependencies).then(resolve).catch(e => { _logger().default.error(`importDependencies got an error: ${JSON.stringify(e)}`); if (e instanceof _exceptions().RemoteScopeNotFound || e instanceof _exceptions().PermissionDenied) return reject(e); return reject(new (_exceptions2().DependencyNotFound)(e.id)); }); }); } componentToVersionDependencies(component, id) { var _this4 = this; return (0, _bluebird().coroutine)(function* () { // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! const versionComp = component.toComponentVersion(id.version); // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! const source = id.scope; const version = yield versionComp.getVersion(_this4.scope.objects); if (!version) { _logger().default.debug(`toVersionDependencies, component ${component.id().toString()}, version ${versionComp.version} not found, going to fetch from a remote`); if (component.scope === _this4.scope.name) { // it should have been fetched locally, since it wasn't found, this is an error throw new (_showDoctorError().default)(`Version ${versionComp.version} of ${component.id().toString()} was not found in scope ${_this4.scope.name}`); } return (0, _scopeRemotes().getScopeRemotes)(_this4.scope).then(remotes => { return _this4._getExternal({ id, remotes, localFetch: false }); }); } _logger().default.debug(`toVersionDependencies, component ${component.id().toString()}, version ${versionComp.version} found, going to collect its dependencies`); const dependencies = yield _this4.importManyWithoutDependencies(version.flattenedDependencies); const devDependencies = yield _this4.importManyWithoutDependencies(version.flattenedDevDependencies); const extensionsDependencies = yield _this4.importManyWithoutDependencies(version.extensions.extensionsBitIds); return new (_versionDependencies().default)(versionComp, dependencies, devDependencies, extensionsDependencies, source); })(); } componentsToComponentsObjects(components, clientVersion) { return (0, _pMapSeries().default)(components, component => component.toObjects(this.scope.objects, clientVersion)); } /** * get ConsumerComponent by bitId. if the component was not found locally, import it from a remote scope */ loadRemoteComponent(id) { return this._getComponentVersion(id).then(component => { if (!component) throw new (_exceptions2().ComponentNotFound)(id.toString()); // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! return component.toConsumer(this.scope.objects); }); } loadComponent(id, localOnly = true) { _logger().default.debugAndAddBreadCrumb('ScopeComponentsImporter', 'loadComponent {id}', { id: id.toString() }); if (localOnly && !id.isLocal(this.scope.name)) { throw new (_generalError().default)('cannot load a component from remote scope, please import first'); } return this.loadRemoteComponent(id); } /** * recursive function. * if found locally, use them. Otherwise, fetch from remote and then, save into the model. */ _getExternalMany(ids, remotes, localFetch = true, persist = true, context = {}) { if (!ids.length) return Promise.resolve([]); _logger().default.debugAndAddBreadCrumb('scope.getExternalMan', `planning on fetching from ${localFetch ? 'local' : 'remote'} scope. Ids: {ids}`, { ids: ids.join(', ') }); (0, _enrichContextFromGlobal().default)(Object.assign(context, { requestedBitIds: ids.map(id => id.toString()) })); return this.sources.getMany(ids).then(defs => { const left = defs.filter(def => { if (!localFetch) return true; if (!def.component) return true; return false; }); if (left.length === 0) { _logger().default.debugAndAddBreadCrumb('scope.getExternalMany', 'no more ids left, all found locally, exiting the method'); return (0, _pMapSeries().default)(defs, def => this.componentToVersionDependencies(def.component, def.id)); } _logger().default.debugAndAddBreadCrumb('scope.getExternalMany', `${left.length} left. Fetching them from a remote`); return remotes.fetch(left.map(def => def.id), this.scope, undefined, context).then(componentObjects => { _logger().default.debugAndAddBreadCrumb('scope.getExternalMany', 'writing them to the model'); return this.scope.writeManyComponentsToModel(componentObjects, persist); }).then(() => this._getExternalMany(ids, remotes)); }); } /** * If the component is not in the local scope, fetch it from a remote and save into the local * scope. (objects directory). */ _getExternal({ id, remotes, localFetch = true, context = {} }) { (0, _enrichContextFromGlobal().default)(context); return this.sources.get(id).then(component => { if (component && localFetch) { return this.componentToVersionDependencies(component, id); } return remotes.fetch([id], this.scope, undefined, context).then(([componentObjects]) => { return this.scope.writeComponentToModel(componentObjects); }).then(() => this._getExternal({ id, remotes, localFetch: true })); }); } _getExternalWithoutDependencies({ id, remotes, localFetch = true, context = {} }) { return this.sources.get(id).then(component => { if (component && localFetch) { // $FlowFixMe scope component must have a version // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! return component.toComponentVersion(id.version); } return remotes.fetch([id], this.scope, true, context).then(([componentObjects]) => this.scope.writeComponentToModel(componentObjects)).then(() => this._getExternal({ id, remotes, localFetch: true })).then(versionDependencies => versionDependencies.component); }); } _getExternalManyWithoutDependencies(ids, remotes, localFetch = false, context = {}) { if (!ids.length) return Promise.resolve([]); _logger().default.debugAndAddBreadCrumb('getExternalOnes', `getExternalOnes, ids: {ids}, localFetch: ${localFetch.toString()}`, { ids: ids.join(', ') }); (0, _enrichContextFromGlobal().default)(Object.assign(context, { requestedBitIds: ids.map(id => id.toString()) })); return this.sources.getMany(ids).then(defs => { const left = defs.filter(def => { if (!localFetch) return true; if (!def.component) return true; return false; }); if (left.length === 0) { _logger().default.debugAndAddBreadCrumb('scope.getExternalOnes', 'no more ids left, all found locally, exiting the method'); // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! return Promise.all(defs.map(def => def.component.toComponentVersion(def.id.version))); } _logger().default.debugAndAddBreadCrumb('getExternalOnes', `getExternalOnes: ${left.length} left. Fetching them from a remote`); return remotes.fetch(left.map(def => def.id), this.scope, true, context).then(componentObjects => { return this.scope.writeManyComponentsToModel(componentObjects); }).then(() => this._getExternalManyWithoutDependencies(ids, remotes, true)); }); } _getComponentVersion(id) { var _this5 = this; return (0, _bluebird().coroutine)(function* () { if (!id.isLocal(_this5.scope.name)) { const remotes = yield (0, _scopeRemotes().getScopeRemotes)(_this5.scope); return _this5._getExternalWithoutDependencies({ id, remotes, localFetch: true }); } return _this5.sources.get(id).then(component => { if (!component) throw new (_exceptions2().ComponentNotFound)(id.toString()); // $FlowFixMe version is set // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! return component.toComponentVersion(id.version); }); })(); } } exports.default = ScopeComponentsImporter;