UNPKG

asl-validator

Version:
88 lines (87 loc) 4.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.stateTransitionsErrors = void 0; var jsonpath_plus_1 = require("jsonpath-plus"); var types_1 = require("../types"); var stateTransitionsErrors = function (definition) { var errorMessages = []; // given a nested state machine, this function will examine // each state and record its `Next` or `Default` values // to see what states are reachable. // Avoids traversing into Map or Parallel states since the // states defined within those containers are not valid // targets for states outside the containers. var nextAndDefaultTargets = function (nestedStateMachine) { var states = []; Object.keys(nestedStateMachine.States).forEach(function (stateName) { var nestedState = nestedStateMachine.States[stateName]; var isContainer = ["Map", "Parallel"].indexOf(nestedState.Type) >= 0; if (isContainer) { states.push.apply(states, (0, jsonpath_plus_1.JSONPath)({ json: nestedState, path: "$.Next", })); states.push.apply(states, (0, jsonpath_plus_1.JSONPath)({ json: nestedState, path: "$.Default", })); } else { states.push.apply(states, (0, jsonpath_plus_1.JSONPath)({ json: nestedState, path: "$..[Next,Default]", })); } }); return states; }; // reports an error for each state that is found to be an invalid // transition var validateNestedStateMachine = function (nestedStateMachine) { var availStateNames = []; // don't traverse into any nested states. We only want to record the States // that are immediately under the Branch. // These are the only valid states to link to from within the branch (0, jsonpath_plus_1.JSONPath)({ json: nestedStateMachine, path: "$.States", }).forEach(function (branchStates) { availStateNames = availStateNames.concat(Object.keys(branchStates)); }); // check that there are no transitions outside this branch var targetedStates = nextAndDefaultTargets(nestedStateMachine); return targetedStates.filter(function (state) { return availStateNames.indexOf(state) === -1; }); }; // we know the step function is schema valid // we know that every `Parallel` state has its expected `Branches` field // we need to visit each Branch within a Parallel to ensure that it doesn't // link outside its branch. (0, jsonpath_plus_1.JSONPath)({ json: definition, path: "$..Branches", }).forEach(function (parallelBranches) { parallelBranches.forEach(function (nestedStateMachine) { var errs = validateNestedStateMachine(nestedStateMachine).map(function (state) { return ({ "Error code": types_1.StateMachineErrorCode.BranchOutboundTransitionTarget, Message: "Parallel branch state cannot transition to target: ".concat(state), }); }); errorMessages.push.apply(errorMessages, errs); }); }); // we know the step function is schema valid // we know that every `Map` state has its expected `Iterator` field // we need to visit the Iterator within a Map to ensure that it doesn't // link outside its container. (0, jsonpath_plus_1.JSONPath)({ json: definition, path: "$..Iterator", }).forEach(function (nestedStateMachine) { var errs = validateNestedStateMachine(nestedStateMachine).map(function (state) { return ({ "Error code": types_1.StateMachineErrorCode.MapOutboundTransitionTarget, Message: "Map branch state cannot transition to target: ".concat(state), }); }); errorMessages.push.apply(errorMessages, errs); }); return errorMessages; }; exports.stateTransitionsErrors = stateTransitionsErrors;