@deliverr/serverless-offline-step-functions
Version:
Serverless Offline Plugin to Support Step Functions for Local Development
134 lines (133 loc) • 5.64 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ChoiceExecutor = void 0;
const jsonpath_plus_1 = require("jsonpath-plus");
const StateProcessor_1 = require("../../StateProcessor");
const StateTypeExecutor_1 = require("../StateTypeExecutor");
class ChoiceExecutor extends StateTypeExecutor_1.StateTypeExecutor {
async execute(context, definition, json) {
const input = this.processInput(json, definition);
this.logger.debug('* * * Choice Input * * *');
this.logger.debug(input);
let nextState = undefined;
for (const choice of definition.Choices) {
let evaluationPassed = false;
if (choice.Not) {
const comparator = this.getComparatorFromChoice(choice.Not);
evaluationPassed = !this.evaluateChoice(comparator, choice.Not, input);
}
else if (choice.And && choice.And.length > 0) {
evaluationPassed = choice.And.every((choiceAnd) => {
const comparator = this.getComparatorFromChoice(choiceAnd);
return this.evaluateChoice(comparator, choiceAnd, input);
});
}
else if (choice.Or && choice.Or.length > 0) {
evaluationPassed = choice.Or.some((choiceAnd) => {
const comparator = this.getComparatorFromChoice(choiceAnd);
return this.evaluateChoice(comparator, choiceAnd, input);
});
}
else {
const comparator = this.getComparatorFromChoice(choice);
evaluationPassed = this.evaluateChoice(comparator, choice, input);
}
this.logger.debug(`* * * Evaluation Passed?: ${evaluationPassed}`);
if (evaluationPassed) {
nextState = choice.Next;
this.logger.debug(`* * * Next state is : ${nextState}`);
break;
}
}
if (!nextState && definition.Default) {
nextState = definition.Default;
}
else if (!nextState && !definition.Default) {
throw new Error('No NextState or Default');
}
return {
json: this.processOutput(input, definition),
Next: nextState,
End: false,
};
}
processInput(json, stateDefinition) {
const proccessedInputJson = StateProcessor_1.StateProcessor.processInputPath(json, stateDefinition.InputPath);
return proccessedInputJson;
}
processOutput(outputJson, stateDefinition) {
const proccessedOutputJson = StateProcessor_1.StateProcessor.processOutputPath(outputJson, stateDefinition.OutputPath);
return proccessedOutputJson;
}
evaluateChoice(comparator, choice, json) {
if (!choice.Variable) {
throw new Error('no "Variable" attribute found in Choice rule');
}
this.logger.debug('* * * Choice Variable * * *');
this.logger.debug(choice.Variable);
const pathResult = jsonpath_plus_1.JSONPath({
path: choice.Variable,
json: JSON.parse(json),
});
if (!pathResult || pathResult.length === 0) {
throw new Error('');
}
let inputValue = pathResult[0];
this.logger.debug(`Input Value Choice: ${inputValue}`);
let choiceValue = choice[comparator];
if (comparator.includes('Timestamp')) {
inputValue = new Date(inputValue).getTime();
choiceValue = new Date(choiceValue).getTime();
}
switch (comparator) {
case 'IsPresent':
return choiceValue ? inputValue !== undefined : inputValue === undefined;
case 'BooleanEquals':
case 'NumericEquals':
case 'StringEquals':
case 'TimestampEquals':
return this.checkEquals(inputValue, choiceValue);
case 'NumericGreaterThan':
case 'StringGreaterThan':
case 'TimestampGreaterThan':
return this.checkGreaterThan(inputValue, choiceValue);
case 'NumericGreaterThanEquals':
case 'StringGreaterThanEquals':
case 'TimestampGreaterThanEquals':
return this.checkGreaterThanEquals(inputValue, choiceValue);
case 'NumericLessThan':
case 'StringLessThan':
case 'TimestampLessThan':
return this.checkLowerThan(inputValue, choiceValue);
case 'NumericLessThanEquals':
case 'StringLessThanEquals':
case 'TimestampLessThanEquals':
return this.checkLowerThanEquals(inputValue, choiceValue);
default:
throw new Error(`Comparator ${comparator} not implemented`);
}
}
checkEquals(inputValue, choiceValue) {
return inputValue === choiceValue;
}
checkGreaterThan(inputValue, choiceValue) {
return inputValue > choiceValue;
}
checkGreaterThanEquals(inputValue, choiceValue) {
return inputValue >= choiceValue;
}
checkLowerThan(inputValue, choiceValue) {
return inputValue < choiceValue;
}
checkLowerThanEquals(inputValue, choiceValue) {
return inputValue <= choiceValue;
}
getComparatorFromChoice(choice) {
const comparators = Object.keys(choice).filter((key) => key !== 'Variable' && key !== 'Next');
if (comparators.length > 1 || !comparators[0]) {
throw Error();
}
return comparators[0];
}
}
exports.ChoiceExecutor = ChoiceExecutor;