UNPKG

asl-validator

Version:
197 lines (196 loc) 8.89 kB
"use strict"; var json_schema_errors_1 = require("./checks/json-schema-errors"); var missing_transition_target_errors_1 = require("./checks/missing-transition-target-errors"); var state_transitions_errors_1 = require("./checks/state-transitions-errors"); var duplicate_state_names_errors_1 = require("./checks/duplicate-state-names-errors"); var missing_terminal_state_errors_1 = require("./checks/missing-terminal-state-errors"); var types_1 = require("./types"); var duplicate_payload_template_fields_1 = require("./checks/duplicate-payload-template-fields"); var state_checks_1 = require("./checks/state-checks"); var DefaultOptions = { checkPaths: true, checkArn: true, }; module.exports = function validator(definition, opts) { var _a; // A state machine's query language defaults to JSONPath. // The interpreter MUST support JSONPath and JSONata, and // MAY support others. var defaultQueryLanguage = (_a = definition.QueryLanguage) !== null && _a !== void 0 ? _a : "JSONPath"; var IsJsonPath = function (_a) { var _b; var state = _a.state; var queryLanguage = (_b = state.QueryLanguage) !== null && _b !== void 0 ? _b : defaultQueryLanguage; return queryLanguage === "JSONPath"; }; var IsJsonNata = function (_a) { var _b; var state = _a.state; var queryLanguage = (_b = state.QueryLanguage) !== null && _b !== void 0 ? _b : defaultQueryLanguage; return queryLanguage === "JSONata"; }; var options = opts !== null && opts !== void 0 ? opts : DefaultOptions; var errors = (0, json_schema_errors_1.jsonSchemaErrors)(definition, options); if (errors.length === 0) { errors.push.apply(errors, (0, missing_transition_target_errors_1.missingTransitionTargetErrors)(definition, options)); errors.push.apply(errors, (0, state_transitions_errors_1.stateTransitionsErrors)(definition, options)); errors.push.apply(errors, (0, duplicate_state_names_errors_1.duplicateStateNames)(definition, options)); errors.push.apply(errors, (0, missing_terminal_state_errors_1.missingTerminalStateErrors)(definition, options)); errors.push.apply(errors, (0, duplicate_payload_template_fields_1.mustNotHaveDuplicateFieldNamesAfterEvaluation)(definition, options)); errors.push.apply(errors, (0, state_checks_1.stateChecks)(definition, options, [ { filter: state_checks_1.IsTask, checker: (0, state_checks_1.AtMostOne)({ props: ["TimeoutSeconds", "TimeoutSecondsPath"], errorCode: types_1.StateMachineErrorCode.TaskTimeoutError, }), }, { filter: state_checks_1.IsTask, checker: (0, state_checks_1.AtMostOne)({ props: ["HeartbeatSeconds", "HeartbeatSecondsPath"], errorCode: types_1.StateMachineErrorCode.TaskHeartbeatError, }), }, { filter: state_checks_1.IsMap, checker: (0, state_checks_1.ExactlyOne)({ props: ["ItemProcessor", "Iterator"], errorCode: types_1.StateMachineErrorCode.MapItemProcessorError, }), }, { filter: state_checks_1.IsMap, checker: (0, state_checks_1.AtMostOne)({ props: ["ItemSelector", "Parameters"], errorCode: types_1.StateMachineErrorCode.MapItemSelectorError, }), }, { filter: state_checks_1.IsWait, checker: (0, state_checks_1.ExactlyOne)({ props: ["Seconds", "SecondsPath", "Timestamp", "TimestampPath"], errorCode: types_1.StateMachineErrorCode.WaitDurationError, }), }, { // performs the check that non-Terminal states do not contain a `Next` field. // This replaces the following schema snippet: // "oneOf": [{ // "required": ["Next"] // }, { // "required": ["End"] // }], filter: function (entry) { return !((0, state_checks_1.IsSucceed)(entry) || (0, state_checks_1.IsFail)(entry) || (0, state_checks_1.IsChoice)(entry)); }, checker: (0, state_checks_1.ExactlyOne)({ props: ["End", "Next"], errorCode: types_1.StateMachineErrorCode.TerminalStateWithNextError, }), }, { filter: state_checks_1.IsMap, checker: (0, state_checks_1.AtMostOne)({ props: ["ToleratedFailureCount", "ToleratedFailureCountPath"], errorCode: types_1.StateMachineErrorCode.MapToleratedFailureError, }), }, { filter: state_checks_1.IsMap, checker: (0, state_checks_1.AtMostOne)({ props: [ "ToleratedFailurePercentage", "ToleratedFailurePercentagePath", ], errorCode: types_1.StateMachineErrorCode.MapToleratedFailureError, }), }, { filter: state_checks_1.IsMap, checker: (0, state_checks_1.AtMostOne)({ props: ["MaxConcurrency", "MaxConcurrencyPath"], errorCode: types_1.StateMachineErrorCode.MapMaxConcurrencyError, }), }, { filter: state_checks_1.IsMap, checker: (0, state_checks_1.AtMostOne)({ props: ["MaxItems", "MaxItemsPath"], path: "$.ItemReader.ReaderConfig", errorCode: types_1.StateMachineErrorCode.MapItemReaderMaxItemsError, }), }, { filter: state_checks_1.IsMap, checker: (0, state_checks_1.AtMostOne)({ props: ["MaxItemsPerBatch", "MaxItemsPerBatchPath"], path: "$.ItemBatcher", errorCode: types_1.StateMachineErrorCode.MapItemBatcherError, }), }, { filter: state_checks_1.IsMap, checker: (0, state_checks_1.AtMostOne)({ props: ["MaxInputBytesPerBatch", "MaxInputBytesPerBatchPath"], path: "$.ItemBatcher", errorCode: types_1.StateMachineErrorCode.MapItemBatcherError, }), }, { filter: state_checks_1.IsFail, checker: (0, state_checks_1.AtMostOne)({ props: ["Cause", "CausePath"], errorCode: types_1.StateMachineErrorCode.FailCauseProperty, }), }, { filter: state_checks_1.IsFail, checker: (0, state_checks_1.AtMostOne)({ props: ["Error", "ErrorPath"], errorCode: types_1.StateMachineErrorCode.FailErrorProperty, }), }, { filter: IsJsonNata, checker: (0, state_checks_1.None)({ props: [ "InputPath", "OutputPath", "ResultPath", "Parameters", "ResultSelector", ], errorCode: types_1.StateMachineErrorCode.QueryLanguageFieldError, }), }, { filter: IsJsonPath, checker: (0, state_checks_1.None)({ props: ["Arguments", "Output"], errorCode: types_1.StateMachineErrorCode.QueryLanguageFieldError, }), }, { filter: function (entry) { return (0, state_checks_1.IsMap)(entry) && IsJsonPath(entry); }, checker: (0, state_checks_1.None)({ props: ["Arguments"], path: "$.ItemReader", errorCode: types_1.StateMachineErrorCode.QueryLanguageFieldError, }), }, ])); } return { isValid: errors.length === 0, errors: errors, errorsText: function (separator) { if (separator === void 0) { separator = "\n"; } return errors .map(function (error) { return "".concat(error["Error code"], ": ").concat(error.Message); }) .join(separator); }, }; };