224 lines
8.9 KiB
JavaScript
224 lines
8.9 KiB
JavaScript
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.assertInternalProjectRoot = assertInternalProjectRoot;
|
|
exports.moduleNameIsDirectFileReference = moduleNameIsDirectFileReference;
|
|
exports.moduleNameIsPackageReference = moduleNameIsPackageReference;
|
|
exports.normalizeStaticPlugin = normalizeStaticPlugin;
|
|
exports.pluginFileName = void 0;
|
|
exports.resolveConfigPluginExport = resolveConfigPluginExport;
|
|
exports.resolveConfigPluginFunction = resolveConfigPluginFunction;
|
|
exports.resolveConfigPluginFunctionWithInfo = resolveConfigPluginFunctionWithInfo;
|
|
exports.resolvePluginForModule = resolvePluginForModule;
|
|
function _assert() {
|
|
const data = _interopRequireDefault(require("assert"));
|
|
_assert = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function path() {
|
|
const data = _interopRequireWildcard(require("path"));
|
|
path = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _resolveFrom() {
|
|
const data = _interopRequireDefault(require("resolve-from"));
|
|
_resolveFrom = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _errors() {
|
|
const data = require("./errors");
|
|
_errors = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _modules() {
|
|
const data = require("./modules");
|
|
_modules = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
// Default plugin entry file name.
|
|
const pluginFileName = exports.pluginFileName = 'app.plugin.js';
|
|
|
|
/**
|
|
* Resolve the config plugin from a node module or package.
|
|
* If the module or package does not include a config plugin, this function throws a `PluginError`.
|
|
* The resolution is done in following order:
|
|
* 1. Is the reference a relative file path or an import specifier with file path? e.g. `./file.js`, `pkg/file.js` or `@org/pkg/file.js`?
|
|
* - Resolve the config plugin as-is
|
|
* 2. If the reference a module? e.g. `expo-font`
|
|
* - Resolve the root `app.plugin.js` file within the module, e.g. `expo-font/app.plugin.js`
|
|
* 3. Does the module have a valid config plugin in the `main` field?
|
|
* - Resolve the `main` entry point as config plugin
|
|
*/
|
|
function resolvePluginForModule(projectRoot, pluginReference) {
|
|
if (moduleNameIsDirectFileReference(pluginReference)) {
|
|
// Only resolve `./file.js`, `package/file.js`, `@org/package/file.js`
|
|
const pluginScriptFile = _resolveFrom().default.silent(projectRoot, pluginReference);
|
|
if (pluginScriptFile) {
|
|
return {
|
|
// NOTE(cedric): `path.sep` is required here, we are resolving the absolute path, not the plugin reference
|
|
isPluginFile: pluginScriptFile.endsWith(path().sep + pluginFileName),
|
|
filePath: pluginScriptFile
|
|
};
|
|
}
|
|
} else if (moduleNameIsPackageReference(pluginReference)) {
|
|
// Only resolve `package -> package/app.plugin.js`, `@org/package -> @org/package/app.plugin.js`
|
|
const pluginPackageFile = _resolveFrom().default.silent(projectRoot, `${pluginReference}/${pluginFileName}`);
|
|
if (pluginPackageFile && (0, _modules().fileExists)(pluginPackageFile)) {
|
|
return {
|
|
isPluginFile: true,
|
|
filePath: pluginPackageFile
|
|
};
|
|
}
|
|
// Try to resole the `main` entry as config plugin
|
|
const packageMainEntry = _resolveFrom().default.silent(projectRoot, pluginReference);
|
|
if (packageMainEntry) {
|
|
return {
|
|
isPluginFile: false,
|
|
filePath: packageMainEntry
|
|
};
|
|
}
|
|
}
|
|
throw new (_errors().PluginError)(`Failed to resolve plugin for module "${pluginReference}" relative to "${projectRoot}". Do you have node modules installed?`, 'PLUGIN_NOT_FOUND');
|
|
}
|
|
|
|
// TODO: Test windows
|
|
function pathIsFilePath(name) {
|
|
// Matches lines starting with: . / ~/
|
|
return !!name.match(/^(\.|~\/|\/)/g);
|
|
}
|
|
function moduleNameIsDirectFileReference(name) {
|
|
if (pathIsFilePath(name)) {
|
|
return true;
|
|
}
|
|
const slashCount = name.split('/')?.length;
|
|
// Orgs (like @expo/config ) should have more than one slash to be a direct file.
|
|
if (name.startsWith('@')) {
|
|
return slashCount > 2;
|
|
}
|
|
|
|
// Regular packages should be considered direct reference if they have more than one slash.
|
|
return slashCount > 1;
|
|
}
|
|
function moduleNameIsPackageReference(name) {
|
|
const slashCount = name.split('/')?.length;
|
|
return name.startsWith('@') ? slashCount === 2 : slashCount === 1;
|
|
}
|
|
function normalizeStaticPlugin(plugin) {
|
|
if (Array.isArray(plugin)) {
|
|
(0, _assert().default)(plugin.length > 0 && plugin.length < 3, `Wrong number of arguments provided for static config plugin, expected either 1 or 2, got ${plugin.length}`);
|
|
return plugin;
|
|
}
|
|
return [plugin, undefined];
|
|
}
|
|
function assertInternalProjectRoot(projectRoot) {
|
|
(0, _assert().default)(projectRoot, `Unexpected: Config \`_internal.projectRoot\` isn't defined by expo-cli, this is a bug.`);
|
|
}
|
|
|
|
// Resolve the module function and assert type
|
|
function resolveConfigPluginFunction(projectRoot, pluginReference) {
|
|
const {
|
|
plugin
|
|
} = resolveConfigPluginFunctionWithInfo(projectRoot, pluginReference);
|
|
return plugin;
|
|
}
|
|
|
|
// Resolve the module function and assert type
|
|
function resolveConfigPluginFunctionWithInfo(projectRoot, pluginReference) {
|
|
const {
|
|
filePath: pluginFile,
|
|
isPluginFile
|
|
} = resolvePluginForModule(projectRoot, pluginReference);
|
|
let result;
|
|
try {
|
|
result = requirePluginFile(pluginFile);
|
|
} catch (error) {
|
|
const learnMoreLink = 'Learn more: https://docs.expo.dev/guides/config-plugins/';
|
|
let underlyingError;
|
|
let stack;
|
|
if (error instanceof Error) {
|
|
const errorWithCode = error;
|
|
underlyingError = `${errorWithCode.message} ${errorWithCode.code ?? ''}`;
|
|
stack = errorWithCode.stack;
|
|
} else {
|
|
underlyingError = String(error);
|
|
}
|
|
let errorMessage = `Unable to resolve a valid config plugin for ${pluginReference}.\n`;
|
|
if (!isPluginFile) {
|
|
errorMessage += `• No "${pluginFileName}" file found in ${pluginReference}: config plugins are typically exported from an "${pluginFileName}" file in the package root.\n`;
|
|
}
|
|
errorMessage += `• main export of ${pluginReference} does not appear to be a config plugin: the following error was thrown when importing ${pluginFile}: ${underlyingError}\n`;
|
|
errorMessage += `Verify that ${pluginReference} includes a config plugin. If it does not, then remove the entry from plugins in your app config file. ${learnMoreLink}`;
|
|
const pluginError = new (_errors().PluginError)(errorMessage, 'INVALID_PLUGIN_IMPORT');
|
|
if (stack) {
|
|
pluginError.stack = stack;
|
|
}
|
|
throw pluginError;
|
|
}
|
|
const plugin = resolveConfigPluginExport({
|
|
plugin: result,
|
|
pluginFile,
|
|
pluginReference,
|
|
isPluginFile
|
|
});
|
|
return {
|
|
plugin,
|
|
pluginFile,
|
|
pluginReference,
|
|
isPluginFile
|
|
};
|
|
}
|
|
|
|
/**
|
|
* - Resolve the exported contents of an Expo config (be it default or module.exports)
|
|
* - Assert no promise exports
|
|
* - Return config type
|
|
* - Serialize config
|
|
*
|
|
* @param props.plugin plugin results
|
|
* @param props.pluginFile plugin file path
|
|
* @param props.pluginReference the string used to reference the plugin
|
|
* @param props.isPluginFile is file path from the app.plugin.js module root
|
|
*/
|
|
function resolveConfigPluginExport({
|
|
plugin,
|
|
pluginFile,
|
|
pluginReference,
|
|
isPluginFile
|
|
}) {
|
|
if (plugin.default != null) {
|
|
plugin = plugin.default;
|
|
}
|
|
if (typeof plugin !== 'function') {
|
|
const learnMoreLink = `Learn more: https://docs.expo.dev/guides/config-plugins/`;
|
|
// If the plugin reference is a node module, and that node module does not export a function then it probably doesn't have a config plugin.
|
|
if (!isPluginFile && !moduleNameIsDirectFileReference(pluginReference)) {
|
|
throw new (_errors().PluginError)(`Package "${pluginReference}" does not contain a valid config plugin. Module must export a function from file: ${pluginFile}\n${learnMoreLink}`, 'INVALID_PLUGIN_TYPE');
|
|
}
|
|
throw new (_errors().PluginError)(`Plugin "${pluginReference}" must export a function from file: ${pluginFile}. ${learnMoreLink}`, 'INVALID_PLUGIN_TYPE');
|
|
}
|
|
return plugin;
|
|
}
|
|
function requirePluginFile(filePath) {
|
|
try {
|
|
return require(filePath);
|
|
} catch (error) {
|
|
// TODO: Improve error messages
|
|
throw error;
|
|
}
|
|
}
|
|
//# sourceMappingURL=plugin-resolver.js.map
|