frappe_docker/frappe-bench/node_modules/babel-preset-babili/lib/options-manager.js
2017-07-31 15:51:51 +05:30

310 lines
No EOL
8.1 KiB
JavaScript

"use strict";
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
var isPlainObject = require("lodash.isplainobject");
/**
* Options Manager
*
* Input Options: Object
* Output: Array of plugins enabled with their options
*
* Handles multiple types of input option keys
*
* 1. boolean and object values
* { mangle: true } // should enable mangler
* { mangle: { blacklist: ["foo"] } } // should enabled mangler
* // and pass obj to mangle plugin
*
* 2. group
* { unsafe: true } // should enable all plugins under unsafe
* { unsafe: { flip: false } } // should disable flip-comparisons plugin
* // and other plugins should take their defaults
* { unsafe: { simplify: {multipass: true}}} // should pass obj to simplify
* // other plugins take defaults
*
* 3. same option passed on to multiple plugins
* { keepFnames: false } // should be passed on to mangle & dce
* // without disturbing their own options
*/
module.exports = {
option,
proxy,
group,
generate,
resolveOptions,
generateResult
};
/**
* Generate the plugin list from option tree and inputOpts
*/
function generate(optionTree, inputOpts) {
return generateResult(resolveOptions(optionTree, inputOpts));
}
/**
* Generate plugin list from the resolvedOptionTree
* where resolvedOptionTree = for every node, node.resolved = true;
*/
function generateResult(resolvedOpts) {
var options = resolvedOpts.children;
var result = [];
for (var i = 0; i < options.length; i++) {
var _option = options[i];
switch (_option.type) {
case "option":
if (_option.resolvedValue) {
result.push(_option.resolvedValue);
}
break;
case "group":
result.push.apply(result, _toConsumableArray(generateResult(_option)));
break;
}
}
return result;
}
/**
* Traverses input @param{optionTree} and adds resolvedValue
* calculated from @param{inputOpts} for each Node in the tree
*/
function resolveOptions(optionTree) {
var inputOpts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var options = optionTree.children;
// a queue to resolve proxies at the end after all options groups are resolved
var proxiesToResolve = [];
for (var i = 0; i < options.length; i++) {
var _option2 = options[i];
switch (_option2.type) {
case "option":
resolveTypeOption(_option2, inputOpts);
break;
case "group":
resolveTypeGroup(_option2, inputOpts);
break;
case "proxy":
if (!hop(inputOpts, _option2.name)) {
break;
}
proxiesToResolve.push(_option2);
break;
default:
throw new TypeError("Option type not supported - " + _option2.type);
}
}
// resolve proxies
for (var _i = 0; _i < proxiesToResolve.length; _i++) {
var _proxy = proxiesToResolve[_i];
for (var j = 0; j < _proxy.to.length; j++) {
var _option3 = _proxy.to[j];
switch (_option3.type) {
case "option":
resolveTypeProxyToOption(_proxy, _option3, inputOpts);
break;
case "group":
case "proxy":
throw new Error(`proxy option cannot proxy to group/proxy. ${_proxy.name} proxied to ${_option3.name}`);
default:
throw new Error("Unsupported option type ${option.name}");
}
}
}
// return the same tree after modifications
return optionTree;
}
/**
* Resolve the type - simple option using the @param{inputOpts}
*/
function resolveTypeOption(option, inputOpts) {
option.resolved = true;
// option does NOT exist in inputOpts
if (!hop(inputOpts, option.name)) {
// default value
option.resolvedValue = option.defaultValue ? option.resolvingValue : null;
return;
}
// Object
// { mangle: { blacklist: ["foo", "bar"] } }
if (isPlainObject(inputOpts[option.name])) {
option.resolvedValue = [option.resolvingValue, inputOpts[option.name]];
return;
}
// any other truthy value, just enables the plugin
// { mangle: true }
if (inputOpts[option.name]) {
option.resolvedValue = option.resolvingValue;
return;
}
// disabled
option.resolvedValue = null;
}
/**
* Resolve the group using @param{inputOpts}
*/
function resolveTypeGroup(option, inputOpts) {
option.resolved = true;
// option does NOT exist in inputOpts
if (!hop(inputOpts, option.name)) {
var _newInputOpts = option.children.filter(function (opt) {
return opt.type !== "proxy";
}).reduce(function (acc, cur) {
var value = void 0;
switch (option.defaultValue) {
case "all":
value = true;break;
case "some":
value = cur.defaultValue;break;
case "none":
value = false;break;
default:
throw new Error(`Unsupported defaultValue - ${option.defaultValue} for option ${option.name}`);
}
return Object.assign({}, acc, {
[cur.name]: value
});
}, {});
// recurse
resolveOptions(option, _newInputOpts);
return;
}
// has individual options for items in group
// { unsafe: { flipComparisons: true } }
if (isPlainObject(inputOpts[option.name])) {
resolveOptions(option, inputOpts[option.name]);
return;
}
// else
// { unsafe: <true | false> }
var newInputOpts = option.children.filter(function (opt) {
return opt.type !== "proxy";
}).reduce(function (acc, cur) {
return Object.assign({}, acc, {
// if the input is truthy, enable all, else disable all
[cur.name]: !!inputOpts[option.name]
});
}, {});
resolveOptions(option, newInputOpts);
}
/**
* Resolve proxies and update the already resolved Options
*/
function resolveTypeProxyToOption(proxy, option, inputOpts) {
if (!option.resolved) {
throw new Error("Proxies cannot be applied before the original option is resolved");
}
// option is disabled
if (!option.resolvedValue) {
return;
}
// option doesn't contain any option on its own
if (option.resolvedValue === option.resolvingValue) {
option.resolvedValue = [option.resolvedValue, {
[proxy.name]: inputOpts[proxy.name]
}];
}
// option already has its own set of options to be passed to plugins
else if (Array.isArray(option.resolvedValue) && option.resolvedValue.length === 2) {
// proxies should not override
if (!hop(option.resolvedValue[1], proxy.name)) {
option.resolvedValue = [option.resolvingValue, Object.assign({}, option.resolvedValue[1], {
[proxy.name]: inputOpts[proxy.name]
})];
}
}
// plugin is invalid
else {
throw new Error(`Invalid resolved value for option ${option.name}`);
}
}
// create an option of type simple option
function option(name, resolvingValue) {
var defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
assertName(name);
if (!resolvingValue) {
// as plugins are truthy values
throw new Error("Only truthy resolving values are supported");
}
return {
type: "option",
name,
resolvingValue,
defaultValue
};
}
// create an option of type proxy
function proxy(name, to) {
assertName(name);
assertArray(name, "to", to);
return {
type: "proxy",
name,
to
};
}
// create an option of type - group of options
function group(name, children) {
var defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "some";
assertName(name);
assertArray(name, "children", children);
return {
type: "group",
name,
children: children.filter(function (x) {
return !!x;
}),
defaultValue
};
}
function hop(o, key) {
return Object.hasOwnProperty.call(o, key);
}
function assertArray(name, prop, arr) {
if (!Array.isArray(arr)) {
throw new Error(`Expected ${prop} to be an array in option ${name}`);
}
}
function assertName(name) {
if (!name) {
throw new Error("Invalid option name " + name);
}
}