/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
* @format
*/
"use strict";
function _toConsumableArray(arr) {
return (
_arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread()
);
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance");
}
function _iterableToArray(iter) {
if (
Symbol.iterator in Object(iter) ||
Object.prototype.toString.call(iter) === "[object Arguments]"
)
return Array.from(iter);
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++)
arr2[i] = arr[i];
return arr2;
}
}
function _objectSpread(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === "function") {
ownKeys = ownKeys.concat(
Object.getOwnPropertySymbols(source).filter(function(sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
})
);
}
ownKeys.forEach(function(key) {
_defineProperty(target, key, source[key]);
});
}
return target;
}
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _asyncToGenerator(fn) {
return function() {
var self = this,
args = arguments;
return new Promise(function(resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(undefined);
});
};
}
const cosmiconfig = require("cosmiconfig");
const getDefaultConfig = require("./defaults");
const _require = require("path"),
dirname = _require.dirname,
resolve = _require.resolve,
join = _require.join;
/**
* Takes the last argument if multiple of the same argument are given
*/
function overrideArgument(arg) {
if (arg == null) {
return arg;
}
if (Array.isArray(arg)) {
return arg[arg.length - 1];
}
return arg;
}
const explorer = cosmiconfig("metro", {
searchPlaces: [
"metro.config.js",
"metro.config.json",
"package.json",
"rn-cli.config.js"
],
loaders: {
".json": cosmiconfig.loadJson,
".yaml": cosmiconfig.loadYaml,
".yml": cosmiconfig.loadYaml,
".js": cosmiconfig.loadJs,
".es6": cosmiconfig.loadJs,
noExt: cosmiconfig.loadYaml
}
});
function resolveConfig(_x, _x2) {
return _resolveConfig.apply(this, arguments);
}
function _resolveConfig() {
_resolveConfig = _asyncToGenerator(function*(path, cwd) {
if (path) {
return explorer.load(path);
}
const result = yield explorer.search(cwd);
if (result == null) {
// No config file found, return a default
return {
isEmpty: true,
filepath: join(cwd || process.cwd(), "metro.config.stub.js"),
config: {}
};
}
return result;
});
return _resolveConfig.apply(this, arguments);
}
function mergeConfig(defaultConfig) {
for (
var _len = arguments.length,
configs = new Array(_len > 1 ? _len - 1 : 0),
_key = 1;
_key < _len;
_key++
) {
configs[_key - 1] = arguments[_key];
}
// If the file is a plain object we merge the file with the default config,
// for the function we don't do this since that's the responsibility of the user
return configs.reduce(
(totalConfig, nextConfig) =>
_objectSpread({}, totalConfig, nextConfig, {
resolver: _objectSpread(
{},
totalConfig.resolver,
nextConfig.resolver || {}
),
serializer: _objectSpread(
{},
totalConfig.serializer,
nextConfig.serializer || {}
),
transformer: _objectSpread(
{},
totalConfig.transformer,
nextConfig.transformer || {}
),
server: _objectSpread({}, totalConfig.server, nextConfig.server || {})
}),
defaultConfig
);
}
function loadMetroConfigFromDisk(_x3, _x4, _x5) {
return _loadMetroConfigFromDisk.apply(this, arguments);
}
function _loadMetroConfigFromDisk() {
_loadMetroConfigFromDisk = _asyncToGenerator(function*(
path,
cwd,
defaultConfigOverrides
) {
const resolvedConfigResults = yield resolveConfig(path, cwd);
const configModule = resolvedConfigResults.config,
filepath = resolvedConfigResults.filepath;
const rootPath = dirname(filepath);
const defaultConfig = yield getDefaultConfig(rootPath);
if (typeof configModule === "function") {
// Get a default configuration based on what we know, which we in turn can pass
// to the function.
const resultedConfig = yield configModule(defaultConfig);
return resultedConfig;
}
return mergeConfig(defaultConfig, defaultConfigOverrides, configModule);
});
return _loadMetroConfigFromDisk.apply(this, arguments);
}
function overrideConfigWithArguments(config, argv) {
// We override some config arguments here with the argv
const output = {
resolver: {},
serializer: {},
server: {},
transformer: {}
};
if (argv.port != null) {
output.server.port = Number(argv.port);
}
if (argv.projectRoot != null) {
output.projectRoot = argv.projectRoot;
}
if (argv.watchFolders != null) {
output.watchFolders = argv.watchFolders;
}
if (argv.assetExts != null) {
output.resolver.assetExts = argv.assetExts;
}
if (argv.sourceExts != null) {
output.resolver.sourceExts = argv.sourceExts;
}
if (argv.platforms != null) {
output.resolver.platforms = argv.platforms;
}
if (argv.providesModuleNodeModules != null) {
output.resolver.providesModuleNodeModules = argv.providesModuleNodeModules;
}
if (argv["max-workers"] != null || argv.maxWorkers != null) {
output.maxWorkers = Number(argv["max-workers"] || argv.maxWorkers);
}
if (argv.transformer != null) {
output.transformer.babelTransformerPath = resolve(argv.transformer);
}
if (argv["reset-cache"] != null) {
output.resetCache = argv["reset-cache"];
}
if (argv.resetCache != null) {
output.resetCache = argv.resetCache;
}
if (argv.verbose === false) {
output.reporter = {
update: () => {}
}; // TODO: Ask if this is the way to go
}
return mergeConfig(config, output);
}
/**
* Load the metro configuration from disk
* @param {object} argv Arguments coming from the CLI, can be empty
* @param {object} defaultConfigOverrides A configuration that can override the default config
* @return {object} Configuration returned
*/
function loadConfig() {
return _loadConfig.apply(this, arguments);
}
function _loadConfig() {
_loadConfig = _asyncToGenerator(function*() {
let argv =
arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
let defaultConfigOverrides =
arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
argv.config = overrideArgument(argv.config);
const configuration = yield loadMetroConfigFromDisk(
argv.config,
argv.cwd,
defaultConfigOverrides
); // Override the configuration with cli parameters
const configWithArgs = overrideConfigWithArguments(configuration, argv);
const overriddenConfig = {}; // The resolver breaks if "json" is missing from `resolver.sourceExts`
const sourceExts = configWithArgs.resolver.sourceExts;
if (!configWithArgs.resolver.sourceExts.includes("json")) {
overriddenConfig.resolver = {
sourceExts: _toConsumableArray(sourceExts).concat(["json"])
};
}
overriddenConfig.watchFolders = [configWithArgs.projectRoot].concat(
_toConsumableArray(configWithArgs.watchFolders)
); // Set the watchfolders to include the projectRoot, as Metro assumes that is
// the case
return mergeConfig(configWithArgs, overriddenConfig);
});
return _loadConfig.apply(this, arguments);
}
module.exports = {
loadConfig,
resolveConfig,
mergeConfig
};