UNPKG

devebot

Version:

Nodejs Microservice Framework

718 lines (713 loc) 28.6 kB
"use strict"; const assert = require("assert"); const lodash = require("lodash"); const util = require("util"); const path = require("path"); const chores = require("../utils/chores"); const constx = require("../utils/constx"); const loader = require("../utils/loader"); const envbox = require("../utils/envbox"); const envcfg = require("../utils/envcfg"); const nodash = require("../utils/nodash"); const LoggingWrapper = require("./logging-wrapper"); const blockRef = chores.getBlockRef(__filename); const _isUpgradeSupported = chores.isUpgradeSupported.bind(chores); const FRAMEWORK_NAMESPACE_UCASE = lodash.toUpper(constx.FRAMEWORK.NAMESPACE); const FRAMEWORK_BRIDGE_LABEL = "bridge"; const FRAMEWORK_PLUGIN_LABEL = "plugin"; const FILE_JS_FILTER_PATTERN = constx.FILE.JS_FILTER_PATTERN; const CONFIG_SUBDIR = "/config"; const CONFIG_VAR_NAMES = ["PROFILE", "SANDBOX", "TEXTURE", "CONFIG_DIR", "CONFIG_ENV"]; const CONFIG_PROFILE_NAME = "profile"; const CONFIG_SANDBOX_NAME = "sandbox"; const CONFIG_TEXTURE_NAME = "texture"; const CONFIG_TYPES = [CONFIG_PROFILE_NAME, CONFIG_SANDBOX_NAME, CONFIG_TEXTURE_NAME]; const CONFIG_METADATA_BLOCK = "__manifest__"; const RELOADING_FORCED = true; function ConfigLoader(params = {}) { const { options, appRef, frameworkRef, pluginRefs, bridgeRefs } = params; const { issueInspector, stateInspector, nameResolver, manifestHandler } = params; const loggingWrapper = new LoggingWrapper(blockRef); const L = loggingWrapper.getLogger(); const T = loggingWrapper.getTracer(); const CTX = { L, T, issueInspector, stateInspector, nameResolver, manifestHandler }; const appName = appRef && appRef.name; const label = chores.stringLabelCase(appName); L && L.has("silly") && L.log("silly", T && T.add({ appName, label }).toMessage({ tags: [blockRef, "constructor-begin"], text: " + Config of application (${appName}) is loaded in name: ${label}" })); this.load = function () { const configObject = loadConfig.bind(null, CTX, appName, options, appRef, frameworkRef, pluginRefs, bridgeRefs).apply(null, CONFIG_VAR_NAMES.map(readVariable.bind(null, CTX, label))); if (_isUpgradeSupported("manifest-refiner")) { if (manifestHandler) { const result = manifestHandler.validateConfig(configObject); issueInspector.collect(result).barrier({ invoker: blockRef, footmark: "metadata-validating" }); } } return configObject; }; L && L.has("silly") && L.log("silly", T && T.toMessage({ tags: [blockRef, "constructor-end"], text: " - constructor has finished" })); } module.exports = ConfigLoader; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ private members function readVariable(ctx, appLabel, varName) { const { L, T } = ctx || this || {}; const labels = [util.format("%s_%s", appLabel, varName), util.format("%s_%s", FRAMEWORK_NAMESPACE_UCASE, varName), util.format("NODE_%s_%s", appLabel, varName), util.format("NODE_%s_%s", FRAMEWORK_NAMESPACE_UCASE, varName)]; for (const label of labels) { const value = envbox.getEnv(label); if (value) { L && L.has("dunce") && L.log("dunce", T && T.add({ label: labels[0], value }).toMessage({ text: " - Final value of ${label}: ${value}" })); return value; } } return undefined; } function loadConfig(ctx, appName, options, appRef, frameworkRef, pluginRefs, bridgeRefs, profileName, sandboxName, textureName, customDir, customEnv) { const { L, T, issueInspector, stateInspector, nameResolver } = ctx || this || {}; assert.ok(nameResolver); assert.ok(issueInspector); assert.ok(stateInspector); const aliasesOf = buildConfigTypeAliases(); L && L.has("silly") && L.log("silly", T && T.add({ aliasesOf }).toMessage({ tags: [blockRef, "config-dir", "aliases-of"], text: " - configType aliases mapping: ${aliasesOf}" })); const config = {}; const tileNames = buildConfigTileNames(ctx, options, profileName, sandboxName, textureName); L && L.has("dunce") && L.log("dunce", T && T.add({ tileNames }).toMessage({ text: " + included names: ${tileNames}" })); loadConfigOfModules(ctx, config, aliasesOf, tileNames, appName, appRef, frameworkRef, pluginRefs, bridgeRefs, customDir, customEnv); fillConfigByEnvVars(ctx, config, appName); lodash.forEach([CONFIG_SANDBOX_NAME, CONFIG_TEXTURE_NAME], function (configType) { if (_isUpgradeSupported("standardizing-config")) { applyAliasMap(ctx, config[configType].initial, nameResolver.getDefaultAliasOf); applyAliasMap(ctx, config[configType].default, nameResolver.getDefaultAliasOf); applyAliasMap(ctx, config[configType].expanse, nameResolver.getDefaultAliasOf); applyAliasMap(ctx, config[configType].mixture, nameResolver.getDefaultAliasOf); if (!_isUpgradeSupported("simplify-name-resolver")) { const { plugin: pluginReverseMap, bridge: bridgeReverseMap } = nameResolver.getRelativeAliasMap(); doAliasMap(ctx, config[configType].initial, pluginReverseMap, bridgeReverseMap); doAliasMap(ctx, config[configType].default, pluginReverseMap, bridgeReverseMap); doAliasMap(ctx, config[configType].expanse, pluginReverseMap, bridgeReverseMap); doAliasMap(ctx, config[configType].mixture, pluginReverseMap, bridgeReverseMap); } stateInspector.collect({ config }); } }); issueInspector.barrier({ invoker: blockRef, footmark: "config-file-loading" }); return config; } function buildConfigTypeAliases() { const ALIASES_OF = {}; ALIASES_OF[CONFIG_PROFILE_NAME] = lodash.clone(envbox.getEnv("CONFIG_PROFILE_ALIASES")); ALIASES_OF[CONFIG_PROFILE_NAME].unshift(CONFIG_PROFILE_NAME); ALIASES_OF[CONFIG_SANDBOX_NAME] = lodash.clone(envbox.getEnv("CONFIG_SANDBOX_ALIASES")); ALIASES_OF[CONFIG_SANDBOX_NAME].unshift(CONFIG_SANDBOX_NAME); ALIASES_OF[CONFIG_TEXTURE_NAME] = lodash.clone(envbox.getEnv("CONFIG_TEXTURE_ALIASES")); ALIASES_OF[CONFIG_TEXTURE_NAME].unshift(CONFIG_TEXTURE_NAME); return ALIASES_OF; } function buildConfigTileNames(ctx, options = {}, profileName, sandboxName, textureName) { const tileNames = {}; tileNames[CONFIG_PROFILE_NAME] = standardizeNames(ctx, profileName); tileNames[CONFIG_SANDBOX_NAME] = standardizeNames(ctx, sandboxName); tileNames[CONFIG_TEXTURE_NAME] = standardizeNames(ctx, textureName); const appProfiles = standardizeNames(ctx, options.privateProfile || options.privateProfiles); tileNames[CONFIG_PROFILE_NAME] = lodash.concat(lodash.difference(tileNames[CONFIG_PROFILE_NAME], appProfiles), appProfiles); const appSandboxes = standardizeNames(ctx, options.privateSandbox || options.privateSandboxes); tileNames[CONFIG_SANDBOX_NAME] = lodash.concat(lodash.difference(tileNames[CONFIG_SANDBOX_NAME], appSandboxes), appSandboxes); const appTextures = standardizeNames(ctx, options.privateTexture || options.privateTextures); tileNames[CONFIG_TEXTURE_NAME] = lodash.concat(lodash.difference(tileNames[CONFIG_TEXTURE_NAME], appTextures), appTextures); return tileNames; } function loadConfigOfModules(ctx, config, aliasesOf, tileNames, appName, appRef, frameworkRef, pluginRefs, bridgeRefs, customDir, customEnv) { const { L, T } = ctx || this || {}; const libRefs = lodash.values(pluginRefs); if (frameworkRef) { libRefs.push(frameworkRef); } const bundleRefs = {}; if (appRef && appRef.path) bundleRefs[appRef.path] = appRef; lodash.assign(bundleRefs, pluginRefs); if (frameworkRef && frameworkRef.path) bundleRefs[frameworkRef.path] = frameworkRef; let bridgeManifests = extractConfigManifest(ctx, bridgeRefs); let pluginManifests = extractConfigManifest(ctx, bundleRefs); if (!_isUpgradeSupported("manifest-refiner")) { bridgeManifests = pluginManifests = undefined; } const appRootDir = appRef && lodash.isString(appRef.path) ? appRef.path : null; const defaultConfigDir = appRootDir ? path.join(appRootDir, CONFIG_SUBDIR) : null; L && L.has("silly") && L.log("silly", T && T.add({ configDir: defaultConfigDir }).toMessage({ tags: [blockRef, "config-dir", "internal-config-dir"], text: " - internal configDir: ${configDir}" })); const externalConfigDir = resolveConfigDir(ctx, appName, appRootDir, customDir, customEnv); L && L.has("silly") && L.log("silly", T && T.add({ configDir: externalConfigDir }).toMessage({ tags: [blockRef, "config-dir", "external-config-dir"], text: " - external configDir: ${configDir}" })); CONFIG_TYPES.forEach(function (configType) { config[configType] = config[configType] || {}; L && L.has("dunce") && L.log("dunce", T && T.toMessage({ text: " + load the default config from plugins & framework" })); lodash.forEach(libRefs, function (libRef) { if (libRef.presets && _isUpgradeSupported("presets")) { L && L.has("dunce") && L.log("dunce", T && T.add(libRef).toMessage({ text: " - Presets of ${type}[${name}]: ${presets}" })); } const libRootDir = libRef.path; for (const i in aliasesOf[configType]) { const defaultFile = path.join(libRootDir, CONFIG_SUBDIR, aliasesOf[configType][i] + ".js"); if (chores.fileExists(defaultFile)) { config[configType]["initial"] = lodash.defaultsDeep(config[configType]["initial"], standardizeConfig(ctx, configType, loadConfigFile(ctx, defaultFile), libRef, bridgeManifests, pluginManifests)); config[configType]["default"] = lodash.cloneDeep(config[configType]["initial"]); break; } } }); config[configType]["names"] = ["default"]; config[configType]["mixture"] = {}; loadAppboxConfig(ctx, config, aliasesOf, tileNames, appRef, bridgeManifests, pluginManifests, configType, defaultConfigDir); if (externalConfigDir != defaultConfigDir) { loadAppboxConfig(ctx, config, aliasesOf, tileNames, appRef, bridgeManifests, pluginManifests, configType, externalConfigDir); } L && L.has("dunce") && L.log("dunce", T && T.toMessage({ text: " - Final config object: " + util.inspect(config[configType], { depth: 8 }) })); }); } function extractConfigManifest(ctx, moduleRefs, configManifest) { const { nameResolver } = ctx || this || {}; assert.ok(nameResolver); configManifest = configManifest || {}; lodash.forOwn(moduleRefs, function (moduleRef) { let moduleName = nameResolver.getOriginalNameOf(moduleRef.name, moduleRef.type); if (!_isUpgradeSupported("refining-name-resolver")) { moduleName = nameResolver.getOriginalName(moduleRef); } configManifest[moduleName] = lodash.pick(moduleRef, ["version", "manifest"]); }); return configManifest; } function fillConfigByEnvVars(ctx, config = {}, appName) { const appLabel = chores.stringLabelCase(appName); const { store, paths } = extractEnvironConfig(ctx, appLabel); const clone = {}; for (const location of paths) { if (!lodash.isArray(location)) { continue; } if (location.length < 2) { continue; } const configType = location[0]; if (CONFIG_TYPES.indexOf(configType) < 0) { continue; } let newVal; const envVal = lodash.get(store, location); const oldVal = lodash.get(config, [configType, "mixture"].concat(location.slice(1))); if (lodash.isNumber(oldVal)) { newVal = Number(envVal); if (Number.isNaN(newVal)) { newVal = null; } } else if (lodash.isBoolean(oldVal)) { newVal = envVal.toLowerCase() == "true" ? true : false; } else if (lodash.isString(oldVal)) { newVal = envVal; } if (!lodash.isNil(newVal)) { lodash.set(clone, location, newVal); } } CONFIG_TYPES.forEach(function (configType) { config[configType] = config[configType] || {}; if (configType in clone && !lodash.isEmpty(clone[configType])) { config[configType]["environ"] = clone[configType]; config[configType]["mixture"] = lodash.merge(config[configType]["mixture"], config[configType]["environ"]); } }); } function extractEnvironConfig(ctx, appLabel) { const prefixes = [util.format("%s_CONFIG_VAL", appLabel), util.format("%s_CONFIG_VAL", FRAMEWORK_NAMESPACE_UCASE), util.format("NODE_%s_CONFIG_VAL", appLabel), util.format("NODE_%s_CONFIG_VAL", FRAMEWORK_NAMESPACE_UCASE)]; let result = {}; for (const prefix of prefixes) { result = envcfg.extractEnv(prefix, result); } return result; } function loadAppboxConfig(ctx, config, aliasesOf, tileNames, appRef, bridgeManifests, pluginManifests, configType, configDir) { const { L, T } = ctx || this || {}; if (configDir) { L && L.has("dunce") && L.log("dunce", T && T.add({ configType, configDir }).toMessage({ text: " + load the '${configType}' configuration in '${configDir}'" })); const configFiles = chores.filterFiles(configDir, FILE_JS_FILTER_PATTERN); const configInfos = lodash.map(configFiles, function (file) { if (constx.LOADING.SPLITTING_FILENAME_BY_REGEXP) { return file.replace(".js", "").split(/_(.+)/).filter(function (sub) { return sub.length > 0; }); } return file.replace(".js", "").replace(/[_]/, "&").split("&"); }); L && L.has("dunce") && L.log("dunce", T && T.add({ configInfos }).toMessage({ text: " - parsing configFiles result: ${configInfos}" })); L && L.has("dunce") && L.log("dunce", T && T.add({ configType }).toMessage({ text: " - load the application default config of '${configType}'" })); for (const i in aliasesOf[configType]) { const defaultFile = path.join(configDir, aliasesOf[configType][i] + ".js"); if (chores.fileExists(defaultFile)) { config[configType]["expanse"] = standardizeConfig(ctx, configType, loadConfigFile(ctx, defaultFile), appRef, bridgeManifests, pluginManifests); break; } } config[configType]["default"] = lodash.defaultsDeep({}, config[configType]["expanse"], config[configType]["default"]); L && L.has("dunce") && L.log("dunce", T && T.add({ configType }).toMessage({ text: " - load the application customized config of '${configType}'" })); const expanseNames = filterConfigBy(ctx, configInfos, tileNames, configType, aliasesOf); L && L.has("dunce") && L.log("dunce", T && T.add({ expanseNames }).toMessage({ text: " + expanded names: ${expanseNames}" })); config[configType]["expanse"] = config[configType]["expanse"] || {}; config[configType]["expanse"] = lodash.reduce(expanseNames, function (accum, expanseItem) { const configFile = path.join(configDir, expanseItem.join("_") + ".js"); const configObj = lodash.defaultsDeep(standardizeConfig(ctx, configType, loadConfigFile(ctx, configFile), appRef, bridgeManifests, pluginManifests), accum); if (configObj.disabled) return accum; config[configType]["names"].push(expanseItem[1]); return configObj; }, config[configType]["expanse"]); config[configType]["mixture"] = config[configType]["mixture"] || {}; config[configType]["mixture"] = lodash.defaultsDeep(config[configType]["expanse"], config[configType]["mixture"], config[configType]["default"]); } } function loadConfigFile(ctx, configFile) { const { L, T, issueInspector } = ctx || this || {}; const opStatus = { type: "CONFIG", file: configFile }; let content; try { L && L.has("dunce") && L.log("dunce", T && T.add({ configFile }).toMessage({ text: " - load config file: '${configFile}'" })); content = loader(configFile, { stopWhenError: true }); L && L.has("dunce") && L.log("dunce", T && T.add({ configFile }).toMessage({ text: " - loading config file: '${configFile}' has done." })); } catch (err) { if (err.code !== "MODULE_NOT_FOUND") { L && L.has("dunce") && L.log("dunce", T && T.add({ configFile }).toMessage({ text: " - config file ${configFile} loading is failed." })); opStatus.hasError = true; opStatus.stack = err.stack; } } issueInspector && issueInspector.collect(opStatus); return RELOADING_FORCED ? lodash.cloneDeep(content) : content; } function filterConfigBy(ctx, configInfos, selectedNames, configType, aliasesOf) { const arr = {}; const idx = {}; selectedNames[configType].forEach(function (name, index) { idx[name] = index; }); lodash.forEach(configInfos, function (item) { const found = item.length === 2 && aliasesOf[configType].indexOf(item[0]) >= 0 && item[1].length > 0; if (found && idx[item[1]] != null) { arr[idx[item[1]]] = item; } }); return lodash.values(arr); } function resolveConfigDir(ctx, appName, appRootDir, configDir, configEnv) { const { L, T, issueInspector } = ctx || this || {}; let dirPath = configDir; if (lodash.isEmpty(dirPath)) { if (["production"].indexOf(process.env.NODE_ENV) >= 0) { dirPath = chores.assertDir(appName); if (dirPath == null) { L && L.has("dunce") && L.log("dunce", T && T.toMessage({ text: "Run in production mode, but config directory not found" })); issueInspector.exit(1); } } else { if (!lodash.isEmpty(appRootDir)) { dirPath = path.join(appRootDir, CONFIG_SUBDIR); } } } if (!lodash.isEmpty(dirPath) && !lodash.isEmpty(configEnv)) { dirPath = path.join(dirPath, configEnv); } return dirPath; } function standardizeNames(ctx, cfgLabels) { if (lodash.isString(cfgLabels) && cfgLabels.length > 0) { cfgLabels = cfgLabels.split(","); } cfgLabels = nodash.arrayify(cfgLabels); cfgLabels = lodash.filter(cfgLabels, lodash.isString); cfgLabels = lodash.map(cfgLabels, lodash.trim); cfgLabels = lodash.filter(cfgLabels, lodash.negate(lodash.isEmpty)); return cfgLabels; } function standardizeConfig(ctx, configType, configStore, crateInfo, bridgeManifests, pluginManifests) { configStore = transformConfig(ctx, configType, configStore, crateInfo); configStore = modernizeConfig(ctx, configType, configStore, crateInfo, bridgeManifests, pluginManifests); return configStore; } function modernizeConfig(ctx, configType, configStore, crateInfo, bridgeManifests, pluginManifests) { if (configType !== CONFIG_SANDBOX_NAME) return configStore; if (lodash.isEmpty(configStore)) return configStore; const { issueInspector } = ctx || this || {}; const collector = new ModernizingResultCollector(); if (!lodash.isEmpty(bridgeManifests)) { for (const bridgeName in configStore.bridges) { const bridgePath = ["bridges"].concat(bridgeName); const bridgeNode = configStore.bridges[bridgeName] || {}; for (const pluginName in bridgeNode) { const pluginPath = bridgePath.concat(pluginName); const pluginNode = bridgeNode[pluginName] || {}; for (const dialectName in pluginNode) { const dialectPath = pluginPath.concat(dialectName); const r = modernizeConfigBlock(ctx, configStore, dialectPath, bridgeManifests[bridgeName], FRAMEWORK_BRIDGE_LABEL); collector.push(r, crateInfo, FRAMEWORK_BRIDGE_LABEL, pluginName, bridgeName, dialectName); } } } } if (!lodash.isEmpty(pluginManifests)) { if (crateInfo.type === "application" && configStore["application"] && pluginManifests["application"]) { const r = modernizeConfigBlock(ctx, configStore, ["application"], pluginManifests["application"], "application"); collector.push(r, crateInfo, "application"); } for (const pluginName in configStore.plugins) { const r = modernizeConfigBlock(ctx, configStore, ["plugins", pluginName], pluginManifests[pluginName], FRAMEWORK_PLUGIN_LABEL); collector.push(r, crateInfo, FRAMEWORK_PLUGIN_LABEL, pluginName); } } issueInspector && issueInspector.collect(collector.toList()); return configStore; } function modernizeConfigBlock(ctx, configStore, configPath, manifestBlock, moduleType) { if (manifestBlock) { const moduleVersion = manifestBlock.version; if (moduleVersion) { const manifestPath = ["manifest", constx.MANIFEST.DEFAULT_ROOT_NAME]; const manifestObject = lodash.get(manifestBlock, manifestPath); return applyManifestMigration(ctx, configStore, configPath, moduleVersion, manifestObject); } } return null; } function applyManifestMigration(ctx, configStore, configPath, moduleVersion, manifest) { if (manifest && manifest.migration && manifest.enabled !== false) { const configNode = lodash.get(configStore, configPath); if (lodash.isObject(configNode)) { const configVersion = lodash.get(configNode, [CONFIG_METADATA_BLOCK, "version"]); if (chores.isVersionLessThan(configVersion, moduleVersion)) { const configMeta = lodash.get(configNode, [CONFIG_METADATA_BLOCK]); const configData = lodash.omit(configNode, [CONFIG_METADATA_BLOCK]); const result = { migrated: false, configVersion, moduleVersion, steps: {} }; for (const ruleName in manifest.migration) { const rule = manifest.migration[ruleName]; if (rule.enabled === false) { result.steps[ruleName] = "disabled"; continue; } if (!lodash.isFunction(rule.transform)) { result.steps[ruleName] = "not_function"; continue; } if (!chores.isVersionSatisfied(configVersion, rule.from)) { result.steps[ruleName] = "unmatched"; continue; } const transformedData = rule.transform(configData); if (lodash.isObject(transformedData)) { lodash.set(configMeta, "version", moduleVersion); lodash.set(transformedData, CONFIG_METADATA_BLOCK, configMeta); lodash.set(configStore, configPath, transformedData); result.migrated = true; result.ruleName = ruleName; result.steps[ruleName] = "ok"; break; } else { result.steps[ruleName] = "empty_output"; } } return result; } } } return null; } function ModernizingResultCollector() { const collection = []; this.push = function (result, crateInfo, moduleType, pluginName, bridgeName, dialectName) { const opStatus = { stage: "config/upgrade" }; opStatus.hasError = result != null && result.migrated !== true; opStatus.type = crateInfo.type; opStatus.name = crateInfo.name; if (opStatus.hasError) { const stackText = []; switch (moduleType) { case FRAMEWORK_BRIDGE_LABEL: { stackText.push(util.format("Converting config block for bridge[%s/%s#%s] from [%s] to [%s] has failed", pluginName, bridgeName, dialectName, result.configVersion, result.moduleVersion)); break; } case FRAMEWORK_PLUGIN_LABEL: { stackText.push(util.format("Converting config block for plugin[%s] from [%s] to [%s] has failed", pluginName, result.configVersion, result.moduleVersion)); break; } } lodash.forOwn(result.steps, function (state, ruleName) { stackText.push(util.format("- rule[%s]: %s", ruleName, state)); }); opStatus.stack = stackText.join("\n "); } collection.push(opStatus); }; this.toList = function () { return collection; }; } function transformConfig(ctx, configType, configStore, crateInfo) { const { nameResolver } = ctx || this || {}; if (configType === CONFIG_PROFILE_NAME) { if (_isUpgradeSupported("profile-config-field-framework")) { configStore = chores.renameJsonFields(configStore, { [constx.LEGACY.PROFILE_CONFIG_FRAMEWORK_FIELD]: "framework" }); } } if (configType === CONFIG_SANDBOX_NAME) { configStore = convertPreciseConfig(ctx, configStore, crateInfo.type, crateInfo.name, crateInfo.presets); configStore = applyAliasMap(ctx, configStore, nameResolver.getOriginalNameOf); if (!_isUpgradeSupported("simplify-name-resolver")) { const { plugin: pluginAliasMap, bridge: bridgeAliasMap } = nameResolver.getAbsoluteAliasMap(); configStore = doAliasMap(ctx, configStore, pluginAliasMap, bridgeAliasMap); } } return configStore; } function convertPreciseConfig(ctx, preciseConfig, moduleType, moduleName, modulePresets) { if (lodash.isEmpty(preciseConfig) || !lodash.isObject(preciseConfig)) { return preciseConfig; } // convert old bridge structures function traverseBackward(cfgBridges, newBridges) { lodash.forOwn(cfgBridges, function (bridgeCfg, cfgName) { if (lodash.isObject(bridgeCfg) && !lodash.isEmpty(bridgeCfg)) { if (moduleType === "application") { newBridges[cfgName] = newBridges[cfgName] || {}; lodash.merge(newBridges[cfgName], bridgeCfg); } else if (moduleType === FRAMEWORK_PLUGIN_LABEL) { moduleName = moduleName || "*"; const bridgeNames = lodash.keys(bridgeCfg); if (bridgeNames.length === 1) { const bridgeName = bridgeNames[0]; newBridges[bridgeName] = newBridges[bridgeName] || {}; newBridges[bridgeName][moduleName] = newBridges[bridgeName][moduleName] || {}; if (lodash.isObject(bridgeCfg[bridgeName])) { newBridges[bridgeName][moduleName][cfgName] = bridgeCfg[bridgeName]; } } } } }); } if (_isUpgradeSupported(["bridge-full-ref", "presets"])) { const tags = nodash.arrayify(lodash.get(modulePresets, ["configTags"], [])); const cfgBridges = preciseConfig.bridges; const loadable = RELOADING_FORCED || !(cfgBridges && cfgBridges.__status__); if (lodash.isObject(cfgBridges) && tags.indexOf("bridge[dialect-bridge]") >= 0 && loadable) { const newBridges = RELOADING_FORCED ? {} : { __status__: true }; traverseBackward(cfgBridges, newBridges); preciseConfig.bridges = newBridges; } } return preciseConfig; } //----------------------------------------------------------------------------- let applyAliasMap = function (ctx, preciseConfig, nameTransformer) { if (_isUpgradeSupported("standardizing-config")) { if (preciseConfig && lodash.isObject(preciseConfig.plugins)) { const oldPlugins = preciseConfig.plugins; const newPlugins = {}; lodash.forOwn(oldPlugins, function (oldPlugin, oldPluginName) { const newPluginName = nameTransformer(oldPluginName, FRAMEWORK_PLUGIN_LABEL); newPlugins[newPluginName] = oldPlugin; }); preciseConfig.plugins = newPlugins; } } if (_isUpgradeSupported(["standardizing-config", "bridge-full-ref"])) { if (preciseConfig && lodash.isObject(preciseConfig.bridges)) { const oldBridges = preciseConfig.bridges; const newBridges = {}; lodash.forOwn(oldBridges, function (oldBridge, oldBridgeName) { const newBridgeName = nameTransformer(oldBridgeName, FRAMEWORK_BRIDGE_LABEL); if (newBridgeName) { if (lodash.isObject(oldBridge)) { newBridges[newBridgeName] = {}; lodash.forOwn(oldBridge, function (oldPlugin, oldPluginName) { const newPluginName = nameTransformer(oldPluginName, FRAMEWORK_PLUGIN_LABEL); newBridges[newBridgeName][newPluginName] = oldPlugin; }); } else { newBridges[newBridgeName] = oldBridge; } } }); preciseConfig.bridges = newBridges; } } return preciseConfig; }; let doAliasMap = null; if (!_isUpgradeSupported("simplify-name-resolver")) { const applyAliasMapRef = applyAliasMap; applyAliasMap = function (ctx, configStore) { return configStore; }; doAliasMap = function (ctx, preciseConfig, pluginAliasMap, bridgeAliasMap) { function nameTransformer(name, type) { switch (type) { case FRAMEWORK_PLUGIN_LABEL: return pluginAliasMap[name] || name; case FRAMEWORK_BRIDGE_LABEL: return bridgeAliasMap[name] || name; } return name; } return applyAliasMapRef(ctx, preciseConfig, nameTransformer); }; }