1082815dcSEvan Bacon"use strict"; 2082815dcSEvan Bacon 3082815dcSEvan BaconObject.defineProperty(exports, "__esModule", { 4082815dcSEvan Bacon value: true 5082815dcSEvan Bacon}); 6082815dcSEvan Baconexports.withBaseMod = withBaseMod; 7082815dcSEvan Baconexports.withMod = withMod; 8082815dcSEvan Baconfunction _chalk() { 9082815dcSEvan Bacon const data = _interopRequireDefault(require("chalk")); 10082815dcSEvan Bacon _chalk = function () { 11082815dcSEvan Bacon return data; 12082815dcSEvan Bacon }; 13082815dcSEvan Bacon return data; 14082815dcSEvan Bacon} 15082815dcSEvan Baconfunction _getenv() { 16082815dcSEvan Bacon const data = require("getenv"); 17082815dcSEvan Bacon _getenv = function () { 18082815dcSEvan Bacon return data; 19082815dcSEvan Bacon }; 20082815dcSEvan Bacon return data; 21082815dcSEvan Bacon} 22082815dcSEvan Baconfunction _errors() { 23082815dcSEvan Bacon const data = require("../utils/errors"); 24082815dcSEvan Bacon _errors = function () { 25082815dcSEvan Bacon return data; 26082815dcSEvan Bacon }; 27082815dcSEvan Bacon return data; 28082815dcSEvan Bacon} 29082815dcSEvan Baconfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 30082815dcSEvan Baconconst EXPO_DEBUG = (0, _getenv().boolish)('EXPO_DEBUG', false); 31082815dcSEvan Bacon/** 32082815dcSEvan Bacon * Plugin to intercept execution of a given `mod` with the given `action`. 33082815dcSEvan Bacon * If an action was already set on the given `config` config for `mod`, then it 34082815dcSEvan Bacon * will be provided to the `action` as `nextMod` when it's evaluated, otherwise 35082815dcSEvan Bacon * `nextMod` will be an identity function. 36082815dcSEvan Bacon * 37082815dcSEvan Bacon * @param config exported config 38082815dcSEvan Bacon * @param platform platform to target (ios or android) 39082815dcSEvan Bacon * @param mod name of the platform function to intercept 40082815dcSEvan Bacon * @param skipEmptyMod should skip running the action if there is no existing mod to intercept 41082815dcSEvan Bacon * @param saveToInternal should save the results to `_internal.modResults`, only enable this when the results are pure JSON. 42082815dcSEvan Bacon * @param isProvider should provide data up to the other mods. 43082815dcSEvan Bacon * @param action method to run on the mod when the config is compiled 44082815dcSEvan Bacon */ 45082815dcSEvan Baconfunction withBaseMod(config, { 46082815dcSEvan Bacon platform, 47082815dcSEvan Bacon mod, 48082815dcSEvan Bacon action, 49082815dcSEvan Bacon skipEmptyMod, 50082815dcSEvan Bacon isProvider, 51082815dcSEvan Bacon isIntrospective, 52082815dcSEvan Bacon saveToInternal 53082815dcSEvan Bacon}) { 54082815dcSEvan Bacon var _config$_internal$isD, _config$_internal; 55082815dcSEvan Bacon if (!config.mods) { 56082815dcSEvan Bacon config.mods = {}; 57082815dcSEvan Bacon } 58082815dcSEvan Bacon if (!config.mods[platform]) { 59082815dcSEvan Bacon config.mods[platform] = {}; 60082815dcSEvan Bacon } 61*ee216927STomasz Sapeta let interceptedMod = config.mods[platform][mod]; 62082815dcSEvan Bacon 63*ee216927STomasz Sapeta // No existing mod to intercept 64082815dcSEvan Bacon if (!interceptedMod) { 65082815dcSEvan Bacon if (skipEmptyMod) { 66082815dcSEvan Bacon // Skip running the action 67082815dcSEvan Bacon return config; 68*ee216927STomasz Sapeta } 69*ee216927STomasz Sapeta // Use a noop mod and continue 70082815dcSEvan Bacon const noopMod = config => config; 71082815dcSEvan Bacon interceptedMod = noopMod; 72*ee216927STomasz Sapeta } 73082815dcSEvan Bacon 74*ee216927STomasz Sapeta // Create a stack trace for debugging ahead of time 75*ee216927STomasz Sapeta let debugTrace = ''; 76*ee216927STomasz Sapeta // Use the possibly user defined value. Otherwise fallback to the env variable. 77082815dcSEvan Bacon // We support the env variable because user mods won't have _internal defined in time. 78082815dcSEvan Bacon const isDebug = (_config$_internal$isD = (_config$_internal = config._internal) === null || _config$_internal === void 0 ? void 0 : _config$_internal.isDebug) !== null && _config$_internal$isD !== void 0 ? _config$_internal$isD : EXPO_DEBUG; 79082815dcSEvan Bacon if (isDebug) { 80082815dcSEvan Bacon // Get a stack trace via the Error API 81*ee216927STomasz Sapeta const stack = new Error().stack; 82*ee216927STomasz Sapeta // Format the stack trace to create the debug log 83082815dcSEvan Bacon debugTrace = getDebugPluginStackFromStackTrace(stack); 84082815dcSEvan Bacon const modStack = _chalk().default.bold(`${platform}.${mod}`); 85082815dcSEvan Bacon debugTrace = `${modStack}: ${debugTrace}`; 86*ee216927STomasz Sapeta } 87*ee216927STomasz Sapeta 88*ee216927STomasz Sapeta // Prevent adding multiple providers to a mod. 89082815dcSEvan Bacon // Base mods that provide files ignore any incoming modResults and therefore shouldn't have provider mods as parents. 90082815dcSEvan Bacon if (interceptedMod.isProvider) { 91082815dcSEvan Bacon if (isProvider) { 92082815dcSEvan Bacon throw new (_errors().PluginError)(`Cannot set provider mod for "${platform}.${mod}" because another is already being used.`, 'CONFLICTING_PROVIDER'); 93082815dcSEvan Bacon } else { 94082815dcSEvan Bacon throw new (_errors().PluginError)(`Cannot add mod to "${platform}.${mod}" because the provider has already been added. Provider must be the last mod added.`, 'INVALID_MOD_ORDER'); 95082815dcSEvan Bacon } 96082815dcSEvan Bacon } 97082815dcSEvan Bacon async function interceptingMod({ 98082815dcSEvan Bacon modRequest, 99082815dcSEvan Bacon ...config 100082815dcSEvan Bacon }) { 101082815dcSEvan Bacon if (isDebug) { 102082815dcSEvan Bacon // In debug mod, log the plugin stack in the order which they were invoked 103082815dcSEvan Bacon console.log(debugTrace); 104082815dcSEvan Bacon } 105*ee216927STomasz Sapeta const results = await action({ 106*ee216927STomasz Sapeta ...config, 107*ee216927STomasz Sapeta modRequest: { 108*ee216927STomasz Sapeta ...modRequest, 109082815dcSEvan Bacon nextMod: interceptedMod 110082815dcSEvan Bacon } 111082815dcSEvan Bacon }); 112082815dcSEvan Bacon if (saveToInternal) { 113082815dcSEvan Bacon saveToInternalObject(results, platform, mod, results.modResults); 114082815dcSEvan Bacon } 115082815dcSEvan Bacon return results; 116*ee216927STomasz Sapeta } 117082815dcSEvan Bacon 118*ee216927STomasz Sapeta // Ensure this base mod is registered as the provider. 119082815dcSEvan Bacon interceptingMod.isProvider = isProvider; 120082815dcSEvan Bacon if (isIntrospective) { 121082815dcSEvan Bacon // Register the mode as idempotent so introspection doesn't remove it. 122082815dcSEvan Bacon interceptingMod.isIntrospective = isIntrospective; 123082815dcSEvan Bacon } 124082815dcSEvan Bacon config.mods[platform][mod] = interceptingMod; 125082815dcSEvan Bacon return config; 126082815dcSEvan Bacon} 127082815dcSEvan Baconfunction saveToInternalObject(config, platformName, modName, results) { 128082815dcSEvan Bacon if (!config._internal) config._internal = {}; 129082815dcSEvan Bacon if (!config._internal.modResults) config._internal.modResults = {}; 130082815dcSEvan Bacon if (!config._internal.modResults[platformName]) config._internal.modResults[platformName] = {}; 131082815dcSEvan Bacon config._internal.modResults[platformName][modName] = results; 132082815dcSEvan Bacon} 133082815dcSEvan Baconfunction getDebugPluginStackFromStackTrace(stacktrace) { 134082815dcSEvan Bacon if (!stacktrace) { 135082815dcSEvan Bacon return ''; 136082815dcSEvan Bacon } 137082815dcSEvan Bacon const treeStackLines = []; 138082815dcSEvan Bacon for (const line of stacktrace.split('\n')) { 139082815dcSEvan Bacon const [first, second] = line.trim().split(' '); 140082815dcSEvan Bacon if (first === 'at') { 141082815dcSEvan Bacon treeStackLines.push(second); 142082815dcSEvan Bacon } 143082815dcSEvan Bacon } 144082815dcSEvan Bacon const plugins = treeStackLines.map(first => { 145082815dcSEvan Bacon var _ref, _first$match$1$trim, _first$match, _first$match$, _first$match2, _first$match2$; 146082815dcSEvan Bacon // Match the first part of the stack trace against the plugin naming convention 147082815dcSEvan Bacon // "with" followed by a capital letter. 148082815dcSEvan Bacon return (_ref = (_first$match$1$trim = first === null || first === void 0 ? void 0 : (_first$match = first.match(/^(\bwith[A-Z].*?\b)/)) === null || _first$match === void 0 ? void 0 : (_first$match$ = _first$match[1]) === null || _first$match$ === void 0 ? void 0 : _first$match$.trim()) !== null && _first$match$1$trim !== void 0 ? _first$match$1$trim : first === null || first === void 0 ? void 0 : (_first$match2 = first.match(/\.(\bwith[A-Z].*?\b)/)) === null || _first$match2 === void 0 ? void 0 : (_first$match2$ = _first$match2[1]) === null || _first$match2$ === void 0 ? void 0 : _first$match2$.trim()) !== null && _ref !== void 0 ? _ref : null; 149082815dcSEvan Bacon }).filter(Boolean).filter(plugin => { 150082815dcSEvan Bacon // redundant as all debug logs are captured in withBaseMod 151082815dcSEvan Bacon return !['withMod', 'withBaseMod', 'withExtendedMod'].includes(plugin); 152082815dcSEvan Bacon }); 153082815dcSEvan Bacon const commonPlugins = ['withPlugins', 'withRunOnce', 'withStaticPlugin']; 154082815dcSEvan Bacon return plugins.reverse().map((pluginName, index) => { 155082815dcSEvan Bacon // Base mods indicate a logical section. 156082815dcSEvan Bacon if (pluginName.includes('BaseMod')) { 157082815dcSEvan Bacon pluginName = _chalk().default.bold(pluginName); 158*ee216927STomasz Sapeta } 159*ee216927STomasz Sapeta // highlight dangerous mods 160082815dcSEvan Bacon if (pluginName.toLowerCase().includes('dangerous')) { 161082815dcSEvan Bacon pluginName = _chalk().default.red(pluginName); 162082815dcSEvan Bacon } 163082815dcSEvan Bacon if (index === 0) { 164082815dcSEvan Bacon return _chalk().default.blue(pluginName); 165082815dcSEvan Bacon } else if (commonPlugins.includes(pluginName)) { 166082815dcSEvan Bacon // Common mod names often clutter up the logs, dim them out 167082815dcSEvan Bacon return _chalk().default.dim(pluginName); 168082815dcSEvan Bacon } 169082815dcSEvan Bacon return pluginName; 170*ee216927STomasz Sapeta }) 171*ee216927STomasz Sapeta // Join the results: 172082815dcSEvan Bacon // withAndroidExpoPlugins ➜ withPlugins ➜ withIcons ➜ withDangerousMod ➜ withMod 173082815dcSEvan Bacon .join(' ➜ '); 174082815dcSEvan Bacon} 175*ee216927STomasz Sapeta 176082815dcSEvan Bacon/** 177082815dcSEvan Bacon * Plugin to extend a mod function in the plugins config. 178082815dcSEvan Bacon * 179082815dcSEvan Bacon * @param config exported config 180082815dcSEvan Bacon * @param platform platform to target (ios or android) 181082815dcSEvan Bacon * @param mod name of the platform function to extend 182082815dcSEvan Bacon * @param action method to run on the mod when the config is compiled 183082815dcSEvan Bacon */ 184082815dcSEvan Baconfunction withMod(config, { 185082815dcSEvan Bacon platform, 186082815dcSEvan Bacon mod, 187082815dcSEvan Bacon action 188082815dcSEvan Bacon}) { 189082815dcSEvan Bacon return withBaseMod(config, { 190082815dcSEvan Bacon platform, 191082815dcSEvan Bacon mod, 192082815dcSEvan Bacon isProvider: false, 193082815dcSEvan Bacon async action({ 194082815dcSEvan Bacon modRequest: { 195082815dcSEvan Bacon nextMod, 196082815dcSEvan Bacon ...modRequest 197082815dcSEvan Bacon }, 198082815dcSEvan Bacon modResults, 199082815dcSEvan Bacon ...config 200082815dcSEvan Bacon }) { 201082815dcSEvan Bacon const results = await action({ 202082815dcSEvan Bacon modRequest, 203082815dcSEvan Bacon modResults: modResults, 204082815dcSEvan Bacon ...config 205082815dcSEvan Bacon }); 206082815dcSEvan Bacon return nextMod(results); 207082815dcSEvan Bacon } 208082815dcSEvan Bacon }); 209082815dcSEvan Bacon} 210082815dcSEvan Bacon//# sourceMappingURL=withMod.js.map