UNPKG

@deliverr/serverless-offline-step-functions

Version:

Serverless Offline Plugin to Support Step Functions for Local Development

134 lines (133 loc) 5.64 kB
"use strict"; 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;