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

353 lines (272 loc) 11.7 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.nonPackageJsonFields = exports.overridesBitInternalFields = exports.overridesForbiddenFields = 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 _chalk() { const data = _interopRequireDefault(require("chalk")); _chalk = function () { return data; }; return data; } function _ramda() { const data = _interopRequireDefault(require("ramda")); _ramda = function () { return data; }; return data; } function _hasWildcard() { const data = _interopRequireDefault(require("../../utils/string/has-wildcard")); _hasWildcard = function () { return data; }; return data; } function _isBitIdMatchByWildcards() { const data = _interopRequireDefault(require("../../utils/bit/is-bit-id-match-by-wildcards")); _isBitIdMatchByWildcards = function () { return data; }; return data; } function _validateType() { const data = require("../../utils/validate-type"); _validateType = function () { return data; }; return data; } function _generalError() { const data = _interopRequireDefault(require("../../error/general-error")); _generalError = function () { return data; }; return data; } function _abstractConfig() { const data = _interopRequireDefault(require("./abstract-config")); _abstractConfig = function () { return data; }; return data; } function _constants() { const data = require("../../constants"); _constants = function () { return data; }; return data; } function _logger() { const data = _interopRequireDefault(require("../../logger/logger")); _logger = function () { return data; }; return data; } const overridesForbiddenFields = ['name', 'main', 'version', 'bit']; exports.overridesForbiddenFields = overridesForbiddenFields; const overridesBitInternalFields = ['propagate', 'exclude', 'env', 'defaultScope', 'extensions']; exports.overridesBitInternalFields = overridesBitInternalFields; const nonPackageJsonFields = [..._constants().DEPENDENCIES_FIELDS, ...overridesBitInternalFields]; exports.nonPackageJsonFields = nonPackageJsonFields; class ConsumerOverrides { // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! // whether the overrides has been changed (so then it should write them to fs) constructor(overrides) { (0, _defineProperty2().default)(this, "overrides", void 0); (0, _defineProperty2().default)(this, "hasChanged", void 0); this.overrides = overrides; } static load(overrides = {}) { // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! return new ConsumerOverrides(overrides); } getOverrideComponentData(bitId) { const matches = this._getAllRulesMatchedById(bitId); if (!matches.length) { return null; } const overrideValues = matches.map(match => _ramda().default.clone(this.overrides[match])); let stopPropagation = false; return overrideValues.reduce((acc, current) => { if (stopPropagation) return acc; if (!current.propagate) { stopPropagation = true; } this._updateSpecificOverridesWithGeneralOverrides(current, acc); return acc; }, {}); } _updateSpecificOverridesWithGeneralOverrides(generalOverrides, specificOverrides) { const isObjectAndNotArray = val => typeof val === 'object' && !Array.isArray(val); Object.keys(generalOverrides).forEach(field => { switch (field) { case 'env': if (!specificOverrides[field]) specificOverrides[field] = {}; ['compiler', 'tester'].forEach(envField => { // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! if (specificOverrides.env[envField] || !generalOverrides.env[envField]) return; // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! specificOverrides.env[envField] = generalOverrides.env[envField]; }); break; case 'propagate': case 'exclude': // it's a system field, do nothing break; default: if (isObjectAndNotArray(specificOverrides[field]) && isObjectAndNotArray(generalOverrides[field])) { specificOverrides[field] = Object.assign({}, generalOverrides[field], specificOverrides[field]); } else if (!specificOverrides[field]) { specificOverrides[field] = generalOverrides[field]; } // when specificOverrides[field] is set and not an object, do not override it by the general one } }); } _getAllRulesMatchedById(bitId) { const exactMatch = this.findExactMatch(bitId); const matchByGlobPattern = Object.keys(this.overrides).filter(idStr => this._isMatchByWildcard(bitId, idStr)); const nonExcluded = matchByGlobPattern.filter(match => !this._isExcluded(this.overrides[match], bitId)); const allMatches = nonExcluded.sort(ConsumerOverrides.sortWildcards); if (exactMatch) allMatches.unshift(exactMatch); return allMatches; } _isMatchByWildcard(bitId, idWithPossibleWildcard) { if (!(0, _hasWildcard().default)(idWithPossibleWildcard)) return false; return (0, _isBitIdMatchByWildcards().default)(bitId, idWithPossibleWildcard); } _isExcluded(overridesValues, bitId) { // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! if (!overridesValues.exclude || !overridesValues.exclude.length) { return false; } // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! return overridesValues.exclude.some(excludeRule => this._isMatchByWildcard(bitId, excludeRule) || bitId.toStringWithoutVersion() === excludeRule || bitId.toStringWithoutScopeAndVersion() === excludeRule); } /** * sort from the more specific (more namespaces) to the more generic (less namespaces) * e.g. * src/utils/javascript/* * src/utils/javascript/* * src/utils/* * src/* * * more namespaces (slashes) === more specific * more wildcards === less specific * * if both have the same number of namespaces (slashes), the one with less wildcards is first. * if both have the same number of wildcards, the one with more namespaces is first. * * a reminder about compare function: * If the result is negative a is sorted before b. * If the result is positive b is sorted before a. * If the result is 0 no changes is done with the sort order of the two values. */ static sortWildcards(a, b) { const numOfNamespaces = str => (str.match(/\//g) || []).length; const numOfWildcards = str => (str.match(/\*/g) || []).length; const indexOfFirstWildcard = str => str.indexOf('*'); const byNamespaces = numOfNamespaces(b) - numOfNamespaces(a); if (byNamespaces !== 0) return byNamespaces; const byWildcards = numOfWildcards(a) - numOfWildcards(b); if (byWildcards !== 0) return byWildcards; // both have the same number of namespaces and the same number of wildcards // e.g. a component `utils/is-string` matches two rules: `utils/*` and `*/is-string`. // the one with the wildcard more left should be first as it is more specific. return indexOfFirstWildcard(a) - indexOfFirstWildcard(b); } updateOverridesIfChanged(component, areEnvsChanged) { var _this = this; return (0, _bluebird().coroutine)(function* () { const overrides = component.overrides.componentOverridesData; const id = component.id; const existingOverrides = _this.getOverrideComponentData(id); if (!areEnvsChanged && _this.areOverridesObjectsEqual(existingOverrides, overrides)) return false; const exactMatch = _this.findExactMatch(id); const key = exactMatch || id.toStringWithoutVersion(); const env = {}; if (component.compiler) { // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! env.compiler = _abstractConfig().default.convertEnvToStringIfPossible(component.compiler.toBitJsonObject('.')); } if (component.tester) { // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! env.tester = _abstractConfig().default.convertEnvToStringIfPossible(component.tester.toBitJsonObject('.')); } if (!_ramda().default.isEmpty(env)) overrides.env = env; _this.overrides[key] = overrides; _this.hasChanged = true; return true; })(); } areOverridesObjectsEqual(overridesA, overridesB) { // seems like R.equals does a great job here. it compares objects by values (not by reference). // also it disregards the keys order. return _ramda().default.equals(overridesA || {}, overridesB || {}); } findExactMatch(bitId) { return Object.keys(this.overrides).find(idStr => bitId.toStringWithoutVersion() === idStr || bitId.toStringWithoutScopeAndVersion() === idStr); } removeExactMatch(bitId) { const exactMatch = this.findExactMatch(bitId); if (!exactMatch) return false; delete this.overrides[exactMatch]; return true; } static validate(overrides) { if (typeof overrides === 'undefined') return; const message = 'consumer-config (either bit.json or package.json "bit")'; (0, _validateType().validateUserInputType)(message, overrides, 'overrides', 'object'); Object.keys(overrides).forEach(id => validateComponentOverride(id, overrides[id])); function validateComponentOverride(id, override) { (0, _validateType().validateUserInputType)(message, override, `overrides.${id}`, 'object'); Object.keys(override).forEach(field => { if (overridesForbiddenFields.includes(field)) { throw new (_generalError().default)(`${message} found a forbidden field "${field}" inside "overrides.${id}" property. the following fields are not allowed: ${overridesForbiddenFields.join(', ')}.`); } if (_constants().DEPENDENCIES_FIELDS.includes(field)) { validateDependencyField(field, override, id); } else if (field === 'env') { validateEnv(override, id); } else if (field === 'exclude') { (0, _validateType().validateUserInputType)(message, override.exclude, `overrides.${id}.exclude`, 'array'); } }); } function validateDependencyField(field, override, id) { (0, _validateType().validateUserInputType)(message, override[field], `overrides.${id}.${field}`, 'object'); Object.keys(override[field]).forEach(rule => { (0, _validateType().validateUserInputType)(message, override[field][rule], `overrides.${id}.${field}.${rule}`, 'string'); if (rule.startsWith(_constants().OVERRIDE_FILE_PREFIX)) { // @todo: once v15 is out, this warning should be replaced by an error _logger().default.console(_chalk().default.yellow(`warning: file overrides (using "${_constants().OVERRIDE_FILE_PREFIX}") is deprecated and will be removed on the next major version`)); } }); } function validateEnv(override, id) { // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! (0, _validateType().validateUserInputType)(message, override.env, `overrides.${id}.env`, 'object'); } } } exports.default = ConsumerOverrides;