2023-12-27 19:33:32 -05:00
|
|
|
import { Operator } from "../functions";
|
2023-11-20 22:12:03 +01:00
|
|
|
import { Action } from "../../declarations/Action";
|
2023-11-20 22:43:09 +01:00
|
|
|
import { getOperatorByName } from "./getOperatorByName";
|
2023-11-20 22:12:03 +01:00
|
|
|
|
2023-11-21 22:27:01 +01:00
|
|
|
/** This function validates the "workflow-json" from the API */
|
2023-11-20 22:12:03 +01:00
|
|
|
export function validateOperations(actions: Action[]): { valid: boolean, reason?: string} {
|
2023-12-21 15:57:51 +01:00
|
|
|
const done: Action[] = [];
|
|
|
|
|
2023-11-21 22:27:01 +01:00
|
|
|
for (const action of actions) {
|
2023-12-21 15:57:51 +01:00
|
|
|
if (action.type === "done") {
|
|
|
|
if(done[action.values.id] !== undefined) {
|
|
|
|
return { valid: false, reason: "There is a duplicate id in the done actions." };
|
2023-11-20 22:43:09 +01:00
|
|
|
}
|
2023-12-21 15:57:51 +01:00
|
|
|
done[action.values.id] = action;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const operator = getOperatorByName(action.type);
|
|
|
|
if(!operator) {
|
|
|
|
return { valid: false, reason: `action.type ${action.type} does not exist` }
|
|
|
|
}
|
2023-12-21 16:42:00 +01:00
|
|
|
const validationResult = operator.schema.validate({values: action.values});
|
2023-11-21 22:27:01 +01:00
|
|
|
|
2023-12-21 16:42:00 +01:00
|
|
|
// TODO: convert everything to joiresult format
|
|
|
|
if(validationResult.error) {
|
|
|
|
return { valid: false, reason: validationResult.error.message};
|
2023-11-21 22:27:01 +01:00
|
|
|
}
|
2023-11-20 22:43:09 +01:00
|
|
|
|
2023-11-21 22:27:01 +01:00
|
|
|
if (action.actions) {
|
2023-12-21 15:57:51 +01:00
|
|
|
// Check io compatibility of the operators
|
|
|
|
for (const childAction of action.actions) {
|
|
|
|
if (childAction.type === "wait") {
|
|
|
|
if(done[childAction.values.id] === undefined) {
|
|
|
|
return { valid: false, reason: "There is a wait action that does not have an associated done action." };
|
|
|
|
}
|
|
|
|
|
2023-12-27 19:33:32 -05:00
|
|
|
for (const afterDoneChild of done[childAction.values.id]?.actions || []) {
|
|
|
|
const receivingOperator = getOperatorByName(afterDoneChild.type);
|
|
|
|
if (!receivingOperator) {
|
|
|
|
return { valid: false, reason: `The receiving operator ${afterDoneChild.type} does not exist.` };
|
|
|
|
} else if (!ioCompatible(operator, receivingOperator)) {
|
2023-12-21 15:57:51 +01:00
|
|
|
return { valid: false, reason: `Ouput of action ${action.type} is not compatible with input of action ${afterDoneChild.type}` };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (action.type === "done") {
|
|
|
|
return { valid: false, reason: `There shouldn't be a done action here.` };
|
|
|
|
}
|
|
|
|
else {
|
2023-12-27 19:33:32 -05:00
|
|
|
const receivingOperator = getOperatorByName(childAction.type);
|
|
|
|
if (!receivingOperator) {
|
|
|
|
return { valid: false, reason: `The receiving operator ${childAction.type} does not exist.` };
|
|
|
|
} else if (!ioCompatible(operator, receivingOperator)) {
|
2023-12-21 15:57:51 +01:00
|
|
|
return { valid: false, reason: `Ouput of action ${action.type} is not compatible with input of action ${childAction.type}` };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-21 22:27:01 +01:00
|
|
|
const validationResult = validateOperations(action.actions);
|
2023-11-20 22:43:09 +01:00
|
|
|
|
2023-11-21 22:27:01 +01:00
|
|
|
if(!validationResult.valid) {
|
|
|
|
return validationResult;
|
2023-11-20 22:43:09 +01:00
|
|
|
}
|
2023-11-20 22:12:03 +01:00
|
|
|
}
|
2023-11-20 22:43:09 +01:00
|
|
|
}
|
2023-11-21 22:27:01 +01:00
|
|
|
return { valid: true };
|
2023-12-21 15:57:51 +01:00
|
|
|
}
|
|
|
|
|
2023-12-27 19:33:32 -05:00
|
|
|
function ioCompatible(outputingOperator: typeof Operator, receivingOperator: typeof Operator): boolean {
|
2023-12-21 15:57:51 +01:00
|
|
|
const outputType = outputingOperator.schema.describe().keys.output.label;
|
2023-12-27 19:33:32 -05:00
|
|
|
const inputType = receivingOperator.schema.describe().keys.input.label;
|
2023-12-21 15:57:51 +01:00
|
|
|
return outputType == inputType;
|
2023-12-27 19:33:32 -05:00
|
|
|
}
|