You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
245 lines
7.5 KiB
245 lines
7.5 KiB
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.withBaseMod = withBaseMod;
|
|
exports.withMod = withMod;
|
|
|
|
function _chalk() {
|
|
const data = _interopRequireDefault(require("chalk"));
|
|
|
|
_chalk = function () {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _getenv() {
|
|
const data = require("getenv");
|
|
|
|
_getenv = function () {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _errors() {
|
|
const data = require("../utils/errors");
|
|
|
|
_errors = function () {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
const EXPO_DEBUG = (0, _getenv().boolish)('EXPO_DEBUG', false);
|
|
|
|
/**
|
|
* Plugin to intercept execution of a given `mod` with the given `action`.
|
|
* If an action was already set on the given `config` config for `mod`, then it
|
|
* will be provided to the `action` as `nextMod` when it's evaluated, otherwise
|
|
* `nextMod` will be an identity function.
|
|
*
|
|
* @param config exported config
|
|
* @param platform platform to target (ios or android)
|
|
* @param mod name of the platform function to intercept
|
|
* @param skipEmptyMod should skip running the action if there is no existing mod to intercept
|
|
* @param saveToInternal should save the results to `_internal.modResults`, only enable this when the results are pure JSON.
|
|
* @param isProvider should provide data up to the other mods.
|
|
* @param action method to run on the mod when the config is compiled
|
|
*/
|
|
function withBaseMod(config, {
|
|
platform,
|
|
mod,
|
|
action,
|
|
skipEmptyMod,
|
|
isProvider,
|
|
isIntrospective,
|
|
saveToInternal
|
|
}) {
|
|
var _config$_internal$isD, _config$_internal;
|
|
|
|
if (!config.mods) {
|
|
config.mods = {};
|
|
}
|
|
|
|
if (!config.mods[platform]) {
|
|
config.mods[platform] = {};
|
|
}
|
|
|
|
let interceptedMod = config.mods[platform][mod]; // No existing mod to intercept
|
|
|
|
if (!interceptedMod) {
|
|
if (skipEmptyMod) {
|
|
// Skip running the action
|
|
return config;
|
|
} // Use a noop mod and continue
|
|
|
|
|
|
const noopMod = config => config;
|
|
|
|
interceptedMod = noopMod;
|
|
} // Create a stack trace for debugging ahead of time
|
|
|
|
|
|
let debugTrace = ''; // Use the possibly user defined value. Otherwise fallback to the env variable.
|
|
// We support the env variable because user mods won't have _internal defined in time.
|
|
|
|
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;
|
|
|
|
if (isDebug) {
|
|
// Get a stack trace via the Error API
|
|
const stack = new Error().stack; // Format the stack trace to create the debug log
|
|
|
|
debugTrace = getDebugPluginStackFromStackTrace(stack);
|
|
|
|
const modStack = _chalk().default.bold(`${platform}.${mod}`);
|
|
|
|
debugTrace = `${modStack}: ${debugTrace}`;
|
|
} // Prevent adding multiple providers to a mod.
|
|
// Base mods that provide files ignore any incoming modResults and therefore shouldn't have provider mods as parents.
|
|
|
|
|
|
if (interceptedMod.isProvider) {
|
|
if (isProvider) {
|
|
throw new (_errors().PluginError)(`Cannot set provider mod for "${platform}.${mod}" because another is already being used.`, 'CONFLICTING_PROVIDER');
|
|
} else {
|
|
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');
|
|
}
|
|
}
|
|
|
|
async function interceptingMod({
|
|
modRequest,
|
|
...config
|
|
}) {
|
|
if (isDebug) {
|
|
// In debug mod, log the plugin stack in the order which they were invoked
|
|
console.log(debugTrace);
|
|
}
|
|
|
|
const results = await action({ ...config,
|
|
modRequest: { ...modRequest,
|
|
nextMod: interceptedMod
|
|
}
|
|
});
|
|
|
|
if (saveToInternal) {
|
|
saveToInternalObject(results, platform, mod, results.modResults);
|
|
}
|
|
|
|
return results;
|
|
} // Ensure this base mod is registered as the provider.
|
|
|
|
|
|
interceptingMod.isProvider = isProvider;
|
|
|
|
if (isIntrospective) {
|
|
// Register the mode as idempotent so introspection doesn't remove it.
|
|
interceptingMod.isIntrospective = isIntrospective;
|
|
}
|
|
|
|
config.mods[platform][mod] = interceptingMod;
|
|
return config;
|
|
}
|
|
|
|
function saveToInternalObject(config, platformName, modName, results) {
|
|
if (!config._internal) config._internal = {};
|
|
if (!config._internal.modResults) config._internal.modResults = {};
|
|
if (!config._internal.modResults[platformName]) config._internal.modResults[platformName] = {};
|
|
config._internal.modResults[platformName][modName] = results;
|
|
}
|
|
|
|
function getDebugPluginStackFromStackTrace(stacktrace) {
|
|
if (!stacktrace) {
|
|
return '';
|
|
}
|
|
|
|
const treeStackLines = [];
|
|
|
|
for (const line of stacktrace.split('\n')) {
|
|
const [first, second] = line.trim().split(' ');
|
|
|
|
if (first === 'at') {
|
|
treeStackLines.push(second);
|
|
}
|
|
}
|
|
|
|
const plugins = treeStackLines.map(first => {
|
|
var _ref, _first$match$1$trim, _first$match, _first$match$, _first$match2, _first$match2$;
|
|
|
|
// Match the first part of the stack trace against the plugin naming convention
|
|
// "with" followed by a capital letter.
|
|
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;
|
|
}).filter(Boolean).filter(plugin => {
|
|
// redundant as all debug logs are captured in withBaseMod
|
|
return !['withMod', 'withBaseMod', 'withExtendedMod'].includes(plugin);
|
|
});
|
|
const commonPlugins = ['withPlugins', 'withRunOnce', 'withStaticPlugin'];
|
|
return plugins.reverse().map((pluginName, index) => {
|
|
// Base mods indicate a logical section.
|
|
if (pluginName.includes('BaseMod')) {
|
|
pluginName = _chalk().default.bold(pluginName);
|
|
} // highlight dangerous mods
|
|
|
|
|
|
if (pluginName.toLowerCase().includes('dangerous')) {
|
|
pluginName = _chalk().default.red(pluginName);
|
|
}
|
|
|
|
if (index === 0) {
|
|
return _chalk().default.blue(pluginName);
|
|
} else if (commonPlugins.includes(pluginName)) {
|
|
// Common mod names often clutter up the logs, dim them out
|
|
return _chalk().default.dim(pluginName);
|
|
}
|
|
|
|
return pluginName;
|
|
}) // Join the results:
|
|
// withAndroidExpoPlugins ➜ withPlugins ➜ withIcons ➜ withDangerousMod ➜ withMod
|
|
.join(' ➜ ');
|
|
}
|
|
/**
|
|
* Plugin to extend a mod function in the plugins config.
|
|
*
|
|
* @param config exported config
|
|
* @param platform platform to target (ios or android)
|
|
* @param mod name of the platform function to extend
|
|
* @param action method to run on the mod when the config is compiled
|
|
*/
|
|
|
|
|
|
function withMod(config, {
|
|
platform,
|
|
mod,
|
|
action
|
|
}) {
|
|
return withBaseMod(config, {
|
|
platform,
|
|
mod,
|
|
isProvider: false,
|
|
|
|
async action({
|
|
modRequest: {
|
|
nextMod,
|
|
...modRequest
|
|
},
|
|
modResults,
|
|
...config
|
|
}) {
|
|
const results = await action({
|
|
modRequest,
|
|
modResults: modResults,
|
|
...config
|
|
});
|
|
return nextMod(results);
|
|
}
|
|
|
|
});
|
|
}
|
|
//# sourceMappingURL=withMod.js.map
|