Formally disallow flowcontrol operations from being used in bake recipes

This commit is contained in:
d98762625 2020-06-05 14:42:20 +01:00
parent 939208903a
commit 53e69835ff
4 changed files with 81 additions and 74 deletions

View file

@ -28,16 +28,22 @@ class NodeRecipe {
* @param {String | Function | Object} ing
*/
_validateIngredient(ing) {
// CASE operation name given. Find operation and validate
if (typeof ing === "string") {
const op = operations.find((op) => {
return sanitise(op.opName) === sanitise(ing);
});
if (op) {
return op;
return this._validateIngredient(op);
} else {
throw new TypeError(`Couldn't find an operation with name '${ing}'.`);
}
// CASE operation given. Check its a chef operation and check its not flowcontrol
} else if (typeof ing === "function") {
if (ing.flowControl) {
throw new TypeError(`flowControl operations like ${ing.opName} are not currently allowed in recipes for chef.bake`);
}
if (operations.includes(ing)) {
return ing;
} else {

View file

@ -177,6 +177,7 @@ export function _wrap(OpClass) {
// Check to see if class's run function is async.
const opInstance = new OpClass();
const isAsync = opInstance.run.constructor.name === "AsyncFunction";
const isFlowControl = opInstance.flowControl;
let wrapped;
@ -192,8 +193,9 @@ export function _wrap(OpClass) {
wrapped = async (input, args=null) => {
const {transformedInput, transformedArgs} = prepareOp(opInstance, input, args);
// SPECIAL CASE for Magic.
if (opInstance.flowControl) {
// SPECIAL CASE for Magic. Other flowControl operations will
// not work because the opList is not passed through.
if (isFlowControl) {
opInstance.ingValues = transformedArgs;
const state = {
@ -241,6 +243,8 @@ export function _wrap(OpClass) {
// used in chef.help
wrapped.opName = OpClass.name;
wrapped.args = createArgInfo(opInstance);
// Used in NodeRecipe to check for flowControl ops
wrapped.flowControl = isFlowControl;
return wrapped;
}
@ -315,25 +319,18 @@ export function help(input) {
/**
* bake [Wrapped] - Perform an array of operations on some input.
* @returns {Function}
* bake
*
* @param {*} input - some input for a recipe.
* @param {String | Function | String[] | Function[] | [String | Function]} recipeConfig -
* An operation, operation name, or an array of either.
* @returns {NodeDish} of the result
* @throws {TypeError} if invalid recipe given.
*/
export function bake() {
/**
* bake
*
* @param {*} input - some input for a recipe.
* @param {String | Function | String[] | Function[] | [String | Function]} recipeConfig -
* An operation, operation name, or an array of either.
* @returns {SyncDish} of the result
* @throws {TypeError} if invalid recipe given.
*/
return function(input, recipeConfig) {
const recipe = new NodeRecipe(recipeConfig);
const dish = ensureIsDish(input);
return recipe.execute(dish);
};
export function bake(input, recipeConfig) {
const recipe = new NodeRecipe(recipeConfig);
const dish = ensureIsDish(input);
return recipe.execute(dish);
}

View file

@ -100,8 +100,7 @@ Object.keys(operations).forEach((op) => {
code += `];
const prebaked = bake(operations);
chef.bake = prebaked;
chef.bake = bake;
export default chef;
// Operations as top level exports.
@ -114,7 +113,7 @@ Object.keys(operations).forEach((op) => {
});
code += " NodeDish as Dish,\n";
code += " prebaked as bake,\n";
code += " bake,\n";
code += " help,\n";
code += " OperationError,\n";
code += " ExcludedOperationError,\n";