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

460 lines (371 loc) 14.2 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 _pMapSeries() { const data = _interopRequireDefault(require("p-map-series")); _pMapSeries = function () { return data; }; return data; } function _ramda() { const data = _interopRequireDefault(require("ramda")); _ramda = function () { return data; }; return data; } function _abstractConfig() { const data = _interopRequireDefault(require("./abstract-config")); _abstractConfig = function () { return data; }; return data; } function _logger() { const data = _interopRequireDefault(require("../../logger/logger")); _logger = function () { return data; }; return data; } function _filterObject() { const data = _interopRequireDefault(require("../../utils/filter-object")); _filterObject = function () { return data; }; return data; } function _packageJsonFile() { const data = _interopRequireDefault(require("../component/package-json-file")); _packageJsonFile = function () { return data; }; return data; } function _showDoctorError() { const data = _interopRequireDefault(require("../../error/show-doctor-error")); _showDoctorError = function () { return data; }; return data; } function _extensionData() { const data = require("./extension-data"); _extensionData = function () { return data; }; return data; } function _constants() { const data = require("../../constants"); _constants = function () { return data; }; return data; } class ComponentConfig extends _abstractConfig().default { // whether a component has bit.json written to FS or package.json written with 'bit' property static registerOnComponentConfigLoading(extId, func) { this.componentConfigLoadingRegistry[extId] = func; } static registerAddConfigAction(extId, func) { this.addConfigRegistry[extId] = func; } constructor({ compiler, tester, lang, bindingPrefix, extensions, overrides }) { super({ compiler, tester, lang, bindingPrefix, extensions }); (0, _defineProperty2().default)(this, "overrides", void 0); (0, _defineProperty2().default)(this, "componentHasWrittenConfig", false); (0, _defineProperty2().default)(this, "packageJsonFile", void 0); (0, _defineProperty2().default)(this, "extensionsAddedConfig", void 0); this.overrides = overrides; this.writeToBitJson = true; // will be changed later to work similar to workspace-config } toPlainObject() { const superObject = super.toPlainObject(); const componentObject = _ramda().default.merge(superObject, { overrides: this.overrides }); const isPropDefaultOrEmpty = (val, key) => { if (key === 'overrides') return !_ramda().default.isEmpty(val); return true; }; return (0, _filterObject().default)(componentObject, isPropDefaultOrEmpty); } validate(bitJsonPath) { if (typeof this.compiler !== 'object' || typeof this.tester !== 'object' || // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! this.extensions() && typeof this.extensions() !== 'object') { throw new (_showDoctorError().default)(`bit.json at "${bitJsonPath}" is invalid, re-import the component with "--conf" flag to recreate it`); } } /** * Return the extensions as ExtensionDataList * * @returns {ExtensionDataList} * @memberof ComponentConfig */ parseExtensions() { return _extensionData().ExtensionDataList.fromArray(this.extensions); } static fromPlainObject(object) { const { env, lang, bindingPrefix, extensions, overrides } = object; return new ComponentConfig({ compiler: env ? _ramda().default.prop('compiler', env) : undefined, tester: env ? _ramda().default.prop('tester', env) : undefined, extensions, lang, bindingPrefix, overrides }); // TODO: run runOnLoadEvent } static fromComponent(component) { return new ComponentConfig({ version: component.version, scope: component.scope, lang: component.lang, bindingPrefix: component.bindingPrefix, // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! compiler: component.compiler || {}, // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! tester: component.tester || {}, overrides: component.overrides.componentOverridesData }); // TODO: run runOnLoadEvent } mergeWithComponentData(component) { this.bindingPrefix = this.bindingPrefix || component.bindingPrefix; this.lang = this.lang || component.lang; this.extensions = this.extensions.length ? this.extensions : component.extensions; } /** * Use the workspaceConfig as a base. Override values if exist in componentConfig * This only used for legacy props that were defined in the root like compiler / tester */ static mergeWithWorkspaceRootConfigs(consumer, componentId, componentConfig, workspaceConfig) { const plainWorkspaceConfig = workspaceConfig ? workspaceConfig._legacyPlainObject() : undefined; let legacyWorkspaceConfigToMerge = {}; if (plainWorkspaceConfig) { legacyWorkspaceConfigToMerge = (0, _filterObject().default)(plainWorkspaceConfig, (val, key) => key !== 'overrides'); } const componentConfigFromWorkspaceToMerge = (workspaceConfig === null || workspaceConfig === void 0 ? void 0 : workspaceConfig.getComponentConfig(componentId)) || {}; const defaultOwner = workspaceConfig === null || workspaceConfig === void 0 ? void 0 : workspaceConfig.defaultOwner; if (defaultOwner && defaultOwner !== _constants().DEFAULT_REGISTRY_DOMAIN_PREFIX) { componentConfigFromWorkspaceToMerge.bindingPrefix = defaultOwner.startsWith('@') ? defaultOwner : `@${defaultOwner}`; } const mergedObject = _ramda().default.mergeAll([legacyWorkspaceConfigToMerge, componentConfigFromWorkspaceToMerge, componentConfig]); mergedObject.extensions = _extensionData().ExtensionDataList.fromObject(mergedObject.extensions, consumer); // Do not try to load extension for itself (usually happen when using '*' pattern) mergedObject.extensions = mergedObject.extensions.remove(componentId); return ComponentConfig.fromPlainObject(mergedObject); } /** * component config is written by default to package.json inside "bit" property. * in case "eject-conf" was running or the component was imported with "--conf" flag, the * bit.json is written as well. * * @param {*} componentDir root component directory, needed for loading package.json file. * in case a component is authored, leave this param empty to not load the project package.json * @param {*} workspaceConfig */ static loadConfigFromFolder({ componentDir, workspaceDir }) { return (0, _bluebird().coroutine)(function* () { let bitJsonPath; let componentHasWrittenConfig = false; let packageJsonFile; if (componentDir) { bitJsonPath = _abstractConfig().default.composeBitJsonPath(componentDir); } const loadBitJson = /*#__PURE__*/function () { var _ref = (0, _bluebird().coroutine)(function* () { if (!bitJsonPath) { return {}; } try { const file = yield _abstractConfig().default.loadJsonFileIfExist(bitJsonPath); if (file) { componentHasWrittenConfig = true; return file; } return {}; } catch (e) { throw new (_showDoctorError().default)(`bit.json at "${bitJsonPath}" is not a valid JSON file, re-import the component with "--conf" flag to recreate it`); } }); return function loadBitJson() { return _ref.apply(this, arguments); }; }(); const loadPackageJson = /*#__PURE__*/function () { var _ref2 = (0, _bluebird().coroutine)(function* () { if (!componentDir) return {}; try { const file = yield _packageJsonFile().default.load(workspaceDir, componentDir); packageJsonFile = file; const packageJsonObject = file.fileExist ? file.packageJsonObject : undefined; const packageJsonHasConfig = Boolean(packageJsonObject && packageJsonObject.bit); if (packageJsonHasConfig) { const packageJsonConfig = packageJsonObject === null || packageJsonObject === void 0 ? void 0 : packageJsonObject.bit; componentHasWrittenConfig = true; return packageJsonConfig; } return {}; } catch (e) { throw new (_showDoctorError().default)(`package.json at ${_abstractConfig().default.composePackageJsonPath(componentDir)} is not a valid JSON file, consider to re-import the file to re-generate the file`); } }); return function loadPackageJson() { return _ref2.apply(this, arguments); }; }(); const [bitJsonConfig, packageJsonConfig] = yield Promise.all([loadBitJson(), loadPackageJson()]); // in case of conflicts, bit.json wins package.json const config = Object.assign(packageJsonConfig, bitJsonConfig); return { config, bitJsonPath, packageJsonFile, componentHasWrittenConfig }; })(); } /** * component config is written by default to package.json inside "bit" property. * in case "eject-conf" was running or the component was imported with "--conf" flag, the * bit.json is written as well. * * @param {*} componentDir root component directory, needed for loading package.json file. * in case a component is authored, leave this param empty to not load the project package.json * @param {*} workspaceConfig */ static load({ consumer, componentId, componentDir, workspaceDir, workspaceConfig }) { var _this = this; return (0, _bluebird().coroutine)(function* () { const { config, bitJsonPath, packageJsonFile, componentHasWrittenConfig } = yield _this.loadConfigFromFolder({ componentDir, workspaceDir }); const componentConfig = ComponentConfig.mergeWithWorkspaceRootConfigs(consumer, componentId, config, workspaceConfig); componentConfig.path = bitJsonPath; yield _this.runOnLoadEvent(_this.componentConfigLoadingRegistry, componentId, componentConfig); const extensionsAddedConfig = yield runOnAddConfigEvent(_this.addConfigRegistry, componentConfig.parseExtensions()); componentConfig.extensionsAddedConfig = extensionsAddedConfig; componentConfig.componentHasWrittenConfig = componentHasWrittenConfig; // @ts-ignore seems to be a bug in ts v3.7.x, it doesn't recognize Promise.all array correctly componentConfig.packageJsonFile = packageJsonFile; return componentConfig; })(); } /** * Run all subscribers to the component config load event * * @static * @param {ConfigLoadRegistry} componentConfigLoadingRegistry * @param {BitId} id * @param {*} config * @memberof ComponentConfig */ static runOnLoadEvent(componentConfigLoadingRegistry, id, config) { return (0, _bluebird().coroutine)(function* () { try { yield (0, _pMapSeries().default)(Object.keys(componentConfigLoadingRegistry), /*#__PURE__*/function () { var _ref3 = (0, _bluebird().coroutine)(function* (extId) { const func = componentConfigLoadingRegistry[extId]; return func(id, config); }); return function (_x) { return _ref3.apply(this, arguments); }; }()); } catch (err) { // TODO: improve texts _logger().default.console(`\nfailed loading an extension for component ${id.toString()}, error is:`, 'warn', 'yellow'); // TODO: this show an ugly error, we should somehow show a proper errors _logger().default.console(err, 'warn', 'yellow'); _logger().default.console('the error has been ignored', 'warn', 'yellow'); _logger().default.warn('extension on load event throw an error', err); } })(); } } /** * Runs all the functions from the registry and merged their results * * @param {AddConfigRegistry} configsRegistry * @returns {Promise<any>} A merge results of the added config by all the extensions */ exports.default = ComponentConfig; (0, _defineProperty2().default)(ComponentConfig, "componentConfigLoadingRegistry", {}); (0, _defineProperty2().default)(ComponentConfig, "addConfigRegistry", {}); function runOnAddConfigEvent(_x2, _x3) { return _runOnAddConfigEvent.apply(this, arguments); } /** * Merge added configs from many extensions * * @param {any[]} configs * @returns A merge results of all config */ function _runOnAddConfigEvent() { _runOnAddConfigEvent = (0, _bluebird().coroutine)(function* (configsRegistry, extensions) { const extensionsConfigModificationsP = Object.keys(configsRegistry).map(extId => { // TODO: only running func for relevant extensions const func = configsRegistry[extId]; return func(extensions); }); const extensionsConfigModifications = yield Promise.all(extensionsConfigModificationsP); const extensionsConfigModificationsObject = mergeExtensionsConfig(extensionsConfigModifications); return extensionsConfigModificationsObject; }); return _runOnAddConfigEvent.apply(this, arguments); } function mergeExtensionsConfig(configs) { return configs.reduce((prev, curr) => { return _ramda().default.mergeDeepLeft(prev, curr); }, {}); }