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

352 lines (274 loc) 13.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.componentOverridesForbiddenFields = 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 _constants() { const data = require("../../constants"); _constants = function () { return data; }; return data; } function _consumerOverrides() { const data = require("./consumer-overrides"); _consumerOverrides = function () { return data; }; return data; } function _utils() { const data = require("../../utils"); _utils = function () { return data; }; return data; } // consumer internal fields should not be used in component overrides, otherwise, they might conflict upon import const componentOverridesForbiddenFields = [..._consumerOverrides().overridesForbiddenFields, ..._consumerOverrides().overridesBitInternalFields]; exports.componentOverridesForbiddenFields = componentOverridesForbiddenFields; class ComponentOverrides { constructor(overrides) { (0, _defineProperty2().default)(this, "overrides", void 0); this.overrides = overrides || {}; } static registerOnComponentOverridesLoading(extId, func) { this.componentOverridesLoadingRegistry[extId] = func; } /** * overrides of component can be determined by three different sources. * 1. component-config. (bit.json/package.json of the component itself). * authored normally don't have it, most imported have it, unless they choose not to write package.json/bit.json. * 2. consumer-config. (bit.json/package.json of the consumer when it has overrides of the component). * 3. model. (when the component is tagged, the overrides data is saved into the model). * * the strategy of loading them is as follows: * a) find the component config. (if exists) * b) find the overrides of workspace config matching this component. (if exists) * c) merge between the two. in case of conflict, the component config wins. * * the following steps are needed to find the component config * a) if the component config is written to the filesystem, use it * b) if the component config is not written, it can be for two reasons: * 1) it's imported and the user chose not to write package.json nor bit.json. in this case, use * component from the model. * 2) it's author. by default, the config is written into consumer-config (if not exist) on import. * which, in this case, use only consumer-config. * an exception is when an author runs `eject-conf` command to explicitly write the config, then, * use the component-config. */ static loadFromConsumer(componentId, workspaceConfig, overridesFromModel, componentConfig, origin) { var _this = this; return (0, _bluebird().coroutine)(function* () { const isAuthor = origin === _constants().COMPONENT_ORIGINS.AUTHORED; const isNotNested = origin !== _constants().COMPONENT_ORIGINS.NESTED; // overrides from consumer-config is not relevant and should not affect imported let legacyOverridesFromConsumer = isNotNested ? workspaceConfig === null || workspaceConfig === void 0 ? void 0 : workspaceConfig.getComponentConfig(componentId) : null; if (isAuthor) { const plainLegacy = workspaceConfig === null || workspaceConfig === void 0 ? void 0 : workspaceConfig._legacyPlainObject(); if (plainLegacy && plainLegacy.env) { legacyOverridesFromConsumer = legacyOverridesFromConsumer || {}; legacyOverridesFromConsumer.env = {}; legacyOverridesFromConsumer.env.compiler = plainLegacy.env.compiler; legacyOverridesFromConsumer.env.tester = plainLegacy.env.tester; } } const getFromComponent = () => { if (componentConfig && componentConfig.componentHasWrittenConfig) { return componentConfig.overrides; } return isAuthor ? null : overridesFromModel; }; const extensionsAddedOverrides = yield runOnLoadOverridesEvent(_this.componentOverridesLoadingRegistry, componentConfig.parseExtensions()); const mergedLegacyConsumerOverridesWithExtensions = mergeOverrides(legacyOverridesFromConsumer || {}, extensionsAddedOverrides); const fromComponent = getFromComponent(); if (!fromComponent) { return new ComponentOverrides(mergedLegacyConsumerOverridesWithExtensions); } const mergedOverrides = mergedLegacyConsumerOverridesWithExtensions ? mergeOverrides(fromComponent, mergedLegacyConsumerOverridesWithExtensions) : fromComponent; return new ComponentOverrides(mergedOverrides); })(); } static loadFromScope(overridesFromModel = {}) { // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! return new ComponentOverrides(_ramda().default.clone(overridesFromModel), {}); } get componentOverridesData() { const isNotSystemField = (val, field) => !_consumerOverrides().overridesBitInternalFields.includes(field); return _ramda().default.pickBy(isNotSystemField, this.overrides); } get componentOverridesPackageJsonData() { const isPackageJsonField = (val, field) => !_consumerOverrides().nonPackageJsonFields.includes(field); return _ramda().default.pickBy(isPackageJsonField, this.overrides); } getEnvByType(envType) { return _ramda().default.path(['env', envType], this.overrides); } getComponentDependenciesWithVersion() { const allDeps = Object.assign({}, this.overrides.dependencies, this.overrides.devDependencies, this.overrides.peerDependencies); return this._filterForComponentWithValidVersion(allDeps); } get defaultScope() { return this.overrides.defaultScope; } _filterForComponentWithValidVersion(deps) { return Object.keys(deps).reduce((acc, current) => { if (this._isValidVersion(deps[current]) && current.startsWith(_constants().OVERRIDE_COMPONENT_PREFIX)) { const component = current.replace(_constants().OVERRIDE_COMPONENT_PREFIX, ''); acc[component] = deps[current]; } return acc; }, {}); } _isValidVersion(ver) { return ver !== _constants().MANUALLY_ADD_DEPENDENCY && ver !== _constants().MANUALLY_REMOVE_DEPENDENCY; } getIgnored(field) { return _ramda().default.keys(_ramda().default.filter(dep => dep === _constants().MANUALLY_REMOVE_DEPENDENCY, this.overrides[field] || {})); } getIgnoredFiles(field) { const ignoredRules = this.getIgnored(field); return ignoredRules.filter(rule => rule.startsWith(_constants().OVERRIDE_FILE_PREFIX)).map(rule => rule.replace(_constants().OVERRIDE_FILE_PREFIX, '')); } getIgnoredComponents(field) { const ignoredRules = this.getIgnored(field); return _ramda().default.flatten(ignoredRules.filter(rule => rule.startsWith(_constants().OVERRIDE_COMPONENT_PREFIX)).map(rule => rule.replace(_constants().OVERRIDE_COMPONENT_PREFIX, '')).map(idStr => [idStr, ...this._getComponentNamesFromPackages(idStr)])); } // TODO: This strategy should be stopped using since harmony, because a package name // TODO: might be completely different than a component id // TODO: instead we should go to the package.json and check the component name there // TODO: Like we do in build-tree.resolveNodePackage // TODO: or use some index that store it (doesn't exist at the moment) /** * it is possible that a user added the component into the overrides as a package. * e.g. `@bit/david.utils.is-string` instead of `@bit/david.utils/is-string` * or, if not using bit.dev, `@bit/utils.is-string` instead of `@bit/utils/is-string` */ _getComponentNamesFromPackages(idStr) { const idSplitByDot = idStr.split('.'); const numberOfDots = idSplitByDot.length - 1; if (numberOfDots === 0) return []; // nothing to do. it wasn't entered as a package const localScopeComponent = idSplitByDot.join('/'); // convert all dots to slashes if (numberOfDots === 1) { // it can't be from bit.dev, it must be locally return [localScopeComponent]; } // there are two dots or more. it can be from bit.dev and it can be locally // for a remoteScopeComponent, leave the first dot and convert only the rest to a slash const remoteScopeComponent = `${_ramda().default.head(idSplitByDot)}.${_ramda().default.tail(idSplitByDot).join('/')}`; return [localScopeComponent, remoteScopeComponent]; } getIgnoredPackages(field) { const ignoredRules = this.getIgnored(field); return ignoredRules.filter(rule => !rule.startsWith(_constants().OVERRIDE_FILE_PREFIX) && !rule.startsWith(_constants().OVERRIDE_COMPONENT_PREFIX)); } stripOriginallySharedDir(sharedDir) { if (!sharedDir) return; _constants().DEPENDENCIES_FIELDS.forEach(field => { if (!this.overrides[field]) return; Object.keys(this.overrides[field]).forEach(rule => { if (!rule.startsWith(_constants().OVERRIDE_FILE_PREFIX)) return; const fileWithSharedDir = rule.replace(_constants().OVERRIDE_FILE_PREFIX, ''); const fileWithoutSharedDir = fileWithSharedDir.replace(`${sharedDir}/`, ''); const value = this.overrides[field][rule]; delete this.overrides[field][rule]; this.overrides[field][`${_constants().OVERRIDE_FILE_PREFIX}${fileWithoutSharedDir}`] = value; }); }); } addOriginallySharedDir(sharedDir) { if (!sharedDir) return; _constants().DEPENDENCIES_FIELDS.forEach(field => { if (!this.overrides[field]) return; Object.keys(this.overrides[field]).forEach(rule => { if (!rule.startsWith(_constants().OVERRIDE_FILE_PREFIX)) return; const fileWithoutSharedDir = rule.replace(_constants().OVERRIDE_FILE_PREFIX, ''); const fileWithSharedDir = `${sharedDir}/${fileWithoutSharedDir}`; const value = this.overrides[field][rule]; delete this.overrides[field][rule]; this.overrides[field][`${_constants().OVERRIDE_FILE_PREFIX}${fileWithSharedDir}`] = value; }); }); } static getAllFilesPaths(overrides) { if (!overrides) return []; const allDeps = Object.assign({}, overrides.dependencies, overrides.devDependencies, overrides.peerDependencies); return Object.keys(allDeps).filter(rule => rule.startsWith(_constants().OVERRIDE_FILE_PREFIX)).map(rule => rule.replace(_constants().OVERRIDE_FILE_PREFIX, '')); } clone() { return new ComponentOverrides(_ramda().default.clone(this.overrides)); } } exports.default = ComponentOverrides; (0, _defineProperty2().default)(ComponentOverrides, "componentOverridesLoadingRegistry", {}); function mergeOverrides(overrides1, overrides2) { // Make sure to not mutate the original object const result = _ramda().default.clone(overrides1); const isObjectAndNotArray = val => typeof val === 'object' && !Array.isArray(val); Object.keys(overrides2 || {}).forEach(field => { // Do not merge internal fields if (_consumerOverrides().overridesBitInternalFields.includes(field)) { return; // do nothing } if (isObjectAndNotArray(overrides1[field]) && isObjectAndNotArray(overrides2[field])) { result[field] = Object.assign({}, overrides2[field], overrides1[field]); } else if (!result[field]) { result[field] = overrides2[field]; } // when overrides1[field] is set and not an object, do not override it by overrides2 }); return result; } /** * Merge added overrides from many extensions * * @param {any[]} configs * @returns A merge results of all config */ function mergeExtensionsOverrides(configs) { return configs.reduce((prev, curr) => { return _ramda().default.mergeDeepLeft(prev, curr); }, {}); } /** * Runs all the functions from the registry and merged their results * * @param {OverridesLoadRegistry} configsRegistry * @returns {Promise<ComponentOverridesData>} A merge results of the added overrides by all the extensions */ function runOnLoadOverridesEvent(_x, _x2) { return _runOnLoadOverridesEvent.apply(this, arguments); } function _runOnLoadOverridesEvent() { _runOnLoadOverridesEvent = (0, _bluebird().coroutine)(function* (configsRegistry, extensions) { const extensionsAddedOverridesP = Object.keys(configsRegistry).map(extId => { // TODO: only running func for relevant extensions const func = configsRegistry[extId]; return func(extensions); }); const extensionsAddedOverrides = yield Promise.all(extensionsAddedOverridesP); let extensionsConfigModificationsObject = mergeExtensionsOverrides(extensionsAddedOverrides); const filterFunc = val => !_ramda().default.isEmpty(val); extensionsConfigModificationsObject = (0, _utils().filterObject)(extensionsConfigModificationsObject, filterFunc); return extensionsConfigModificationsObject; }); return _runOnLoadOverridesEvent.apply(this, arguments); }