aws-local-stepfunctions 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -33,20 +33,27 @@ var ExecutionTimeoutError = class extends Error {
33
33
  }
34
34
  };
35
35
 
36
+ // src/error/ErrorWithCause.ts
37
+ var _errorCause;
38
+ var ErrorWithCause = class extends Error {
39
+ constructor(message, options) {
40
+ super(message);
41
+ __privateAdd(this, _errorCause, void 0);
42
+ __privateSet(this, _errorCause, options?.cause);
43
+ }
44
+ get cause() {
45
+ return __privateGet(this, _errorCause);
46
+ }
47
+ };
48
+ _errorCause = new WeakMap();
49
+
36
50
  // src/error/ExecutionError.ts
37
- var _wrappedError;
38
- var ExecutionError = class extends Error {
51
+ var ExecutionError = class extends ErrorWithCause {
39
52
  constructor(caughtError) {
40
- super(`Execution has failed with the following error: ${caughtError.message}`);
41
- __privateAdd(this, _wrappedError, void 0);
53
+ super(`Execution has failed with the following error: ${caughtError.message}`, { cause: caughtError });
42
54
  this.name = "ExecutionError";
43
- __privateSet(this, _wrappedError, caughtError);
44
- }
45
- get getWrappedError() {
46
- return __privateGet(this, _wrappedError);
47
55
  }
48
56
  };
49
- _wrappedError = new WeakMap();
50
57
 
51
58
  // src/util/random.ts
52
59
  function cyrb128(str) {
@@ -85,46 +92,51 @@ function getRandomNumber(min, max, rng = Math.random) {
85
92
  }
86
93
 
87
94
  // src/util/index.ts
95
+ var isBrowserEnvironment = typeof window !== "undefined" && typeof window.document !== "undefined";
88
96
  function isPlainObj(value) {
89
97
  return !!value && Object.getPrototypeOf(value) === Object.prototype;
90
98
  }
91
- function sleep(ms, abortSignal, rootAbortSignal) {
99
+ function sleep(ms, abortSignal) {
92
100
  return new Promise((resolve) => {
93
- if (abortSignal?.aborted || rootAbortSignal?.aborted) {
101
+ if (abortSignal?.aborted) {
94
102
  return resolve();
95
103
  }
96
104
  const onAbort = () => {
97
- abortSignal?.removeEventListener("abort", onAbort);
98
- rootAbortSignal?.removeEventListener("abort", onAbort);
99
105
  clearTimeout(timeout);
100
106
  resolve();
101
107
  };
102
108
  const timeout = setTimeout(() => {
103
109
  abortSignal?.removeEventListener("abort", onAbort);
104
- rootAbortSignal?.removeEventListener("abort", onAbort);
105
110
  resolve();
106
111
  }, ms);
107
- abortSignal?.addEventListener("abort", onAbort);
108
- rootAbortSignal?.addEventListener("abort", onAbort);
112
+ abortSignal?.addEventListener("abort", onAbort, { once: true });
109
113
  });
110
114
  }
111
115
  function byteToHex(byte) {
112
116
  return byte.toString(16).padStart(2, "0");
113
117
  }
118
+ function isRFC3339Timestamp(date) {
119
+ const regex = /^\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(\.\d+)?(Z|(\+|-)([01][0-9]|2[0-3]):([0-5][0-9]))$/;
120
+ return regex.test(date);
121
+ }
122
+ function stringifyJSONValue(value) {
123
+ return JSON.stringify(value);
124
+ }
114
125
 
115
- // src/stateMachine/JsonPath.ts
126
+ // src/stateMachine/jsonPath/JsonPath.ts
116
127
  import { JSONPath as jp } from "jsonpath-plus";
117
- function jsonPathQuery(pathExpression, json, context) {
118
- if (pathExpression.startsWith("$$")) {
119
- return jp({ path: pathExpression.slice(1), json: context ?? null, wrap: false });
128
+
129
+ // src/stateMachine/jsonPath/constraints/BaseJsonPathConstraint.ts
130
+ var BaseJSONPathConstraint = class {
131
+ constructor(pathExpression) {
132
+ this.pathExpression = pathExpression;
120
133
  }
121
- return jp({ path: pathExpression, json, wrap: false });
122
- }
134
+ };
123
135
 
124
136
  // src/error/RuntimeError.ts
125
- var RuntimeError = class extends Error {
126
- constructor(message) {
127
- super(message);
137
+ var RuntimeError = class extends ErrorWithCause {
138
+ constructor(message, cause) {
139
+ super(message, { cause });
128
140
  this.name = "RuntimeError";
129
141
  this.retryable = true;
130
142
  this.catchable = true;
@@ -137,14 +149,6 @@ var RuntimeError = class extends Error {
137
149
  }
138
150
  };
139
151
 
140
- // src/error/predefined/StatesResultPathMatchFailureError.ts
141
- var StatesResultPathMatchFailureError = class extends RuntimeError {
142
- constructor() {
143
- super("States.ResultPathMatchFailure");
144
- this.name = "States.ResultPathMatchFailure";
145
- }
146
- };
147
-
148
152
  // src/error/predefined/StatesRuntimeError.ts
149
153
  var StatesRuntimeError = class extends RuntimeError {
150
154
  constructor(message = "States.Runtime") {
@@ -155,6 +159,43 @@ var StatesRuntimeError = class extends RuntimeError {
155
159
  }
156
160
  };
157
161
 
162
+ // src/stateMachine/jsonPath/constraints/DefinedValueConstraint.ts
163
+ var DefinedValueConstraint = class extends BaseJSONPathConstraint {
164
+ test(value) {
165
+ if (typeof value === "undefined") {
166
+ throw new StatesRuntimeError(`Path expression '${this.pathExpression}' does not point to a value`);
167
+ }
168
+ }
169
+ };
170
+
171
+ // src/stateMachine/jsonPath/JsonPath.ts
172
+ function jsonPathQuery(pathExpression, json, context, options) {
173
+ const defaultConstraints = [];
174
+ if (!options?.ignoreDefinedValueConstraint) {
175
+ defaultConstraints.push(DefinedValueConstraint);
176
+ }
177
+ const constraints = [...defaultConstraints, ...options?.constraints ?? []];
178
+ let evaluation;
179
+ if (pathExpression.startsWith("$$")) {
180
+ evaluation = jp({ path: pathExpression.slice(1), json: context ?? null, wrap: false });
181
+ } else {
182
+ evaluation = jp({ path: pathExpression, json, wrap: false });
183
+ }
184
+ for (const Constraint of constraints) {
185
+ const constraintObject = new Constraint(pathExpression);
186
+ constraintObject.test(evaluation);
187
+ }
188
+ return evaluation;
189
+ }
190
+
191
+ // src/error/predefined/StatesResultPathMatchFailureError.ts
192
+ var StatesResultPathMatchFailureError = class extends RuntimeError {
193
+ constructor() {
194
+ super("States.ResultPathMatchFailure");
195
+ this.name = "States.ResultPathMatchFailure";
196
+ }
197
+ };
198
+
158
199
  // src/stateMachine/intrinsicFunctions/ArgumentHandling.ts
159
200
  function validateArgumentType(allowedTypes, argPosition, funcArg, funcName) {
160
201
  let matchesAllowedType = false;
@@ -895,212 +936,300 @@ var StatesNoChoiceMatchedError = class extends RuntimeError {
895
936
  }
896
937
  };
897
938
 
939
+ // src/stateMachine/jsonPath/constraints/StringConstraint.ts
940
+ var StringConstraint = class extends BaseJSONPathConstraint {
941
+ test(value) {
942
+ if (typeof value !== "string") {
943
+ throw new StatesRuntimeError(
944
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(value)}, but expected a string`
945
+ );
946
+ }
947
+ }
948
+ };
949
+
950
+ // src/stateMachine/jsonPath/constraints/NumberConstraint.ts
951
+ var NumberConstraint = class extends BaseJSONPathConstraint {
952
+ test(value) {
953
+ if (typeof value !== "number") {
954
+ throw new StatesRuntimeError(
955
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(value)}, but expected a number`
956
+ );
957
+ }
958
+ }
959
+ };
960
+
961
+ // src/stateMachine/jsonPath/constraints/BooleanConstraint.ts
962
+ var BooleanConstraint = class extends BaseJSONPathConstraint {
963
+ test(value) {
964
+ if (typeof value !== "boolean") {
965
+ throw new StatesRuntimeError(
966
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(value)}, but expected a boolean`
967
+ );
968
+ }
969
+ }
970
+ };
971
+
972
+ // src/stateMachine/jsonPath/constraints/RFC3339TimestampConstraint.ts
973
+ var RFC3339TimestampConstraint = class extends BaseJSONPathConstraint {
974
+ test(value) {
975
+ if (typeof value !== "string" || !isRFC3339Timestamp(value)) {
976
+ throw new StatesRuntimeError(
977
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(
978
+ value
979
+ )}, but expected a timestamp conforming to the RFC3339 profile`
980
+ );
981
+ }
982
+ }
983
+ };
984
+
898
985
  // src/stateMachine/stateActions/ChoiceStateAction.ts
899
986
  import wcmatch from "wildcard-match";
900
987
  var ChoiceStateAction = class extends BaseStateAction {
901
988
  constructor(stateDefinition, stateName) {
902
989
  super(stateDefinition, stateName);
903
990
  }
904
- testChoiceRule(choiceRule, input) {
991
+ testChoiceRule(choiceRule, input, context) {
905
992
  if ("And" in choiceRule) {
906
- return choiceRule.And.every((rule) => this.testChoiceRule(rule, input));
993
+ return choiceRule.And.every((rule) => this.testChoiceRule(rule, input, context));
907
994
  }
908
995
  if ("Or" in choiceRule) {
909
- return choiceRule.Or.some((rule) => this.testChoiceRule(rule, input));
996
+ return choiceRule.Or.some((rule) => this.testChoiceRule(rule, input, context));
910
997
  }
911
998
  if ("Not" in choiceRule) {
912
- return !this.testChoiceRule(choiceRule.Not, input);
999
+ return !this.testChoiceRule(choiceRule.Not, input, context);
913
1000
  }
914
1001
  if ("StringEquals" in choiceRule) {
915
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1002
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
916
1003
  return varValue === choiceRule.StringEquals;
917
1004
  }
918
1005
  if ("StringEqualsPath" in choiceRule) {
919
- const varValue = jsonPathQuery(choiceRule.Variable, input);
920
- const stringValue = jsonPathQuery(choiceRule.StringEqualsPath, input);
1006
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1007
+ const stringValue = jsonPathQuery(choiceRule.StringEqualsPath, input, context, {
1008
+ constraints: [StringConstraint]
1009
+ });
921
1010
  return varValue === stringValue;
922
1011
  }
923
1012
  if ("StringLessThan" in choiceRule) {
924
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1013
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
925
1014
  return varValue < choiceRule.StringLessThan;
926
1015
  }
927
1016
  if ("StringLessThanPath" in choiceRule) {
928
- const varValue = jsonPathQuery(choiceRule.Variable, input);
929
- const stringValue = jsonPathQuery(choiceRule.StringLessThanPath, input);
1017
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1018
+ const stringValue = jsonPathQuery(choiceRule.StringLessThanPath, input, context, {
1019
+ constraints: [StringConstraint]
1020
+ });
930
1021
  return varValue < stringValue;
931
1022
  }
932
1023
  if ("StringGreaterThan" in choiceRule) {
933
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1024
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
934
1025
  return varValue > choiceRule.StringGreaterThan;
935
1026
  }
936
1027
  if ("StringGreaterThanPath" in choiceRule) {
937
- const varValue = jsonPathQuery(choiceRule.Variable, input);
938
- const stringValue = jsonPathQuery(choiceRule.StringGreaterThanPath, input);
1028
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1029
+ const stringValue = jsonPathQuery(choiceRule.StringGreaterThanPath, input, context, {
1030
+ constraints: [StringConstraint]
1031
+ });
939
1032
  return varValue > stringValue;
940
1033
  }
941
1034
  if ("StringLessThanEquals" in choiceRule) {
942
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1035
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
943
1036
  return varValue <= choiceRule.StringLessThanEquals;
944
1037
  }
945
1038
  if ("StringLessThanEqualsPath" in choiceRule) {
946
- const varValue = jsonPathQuery(choiceRule.Variable, input);
947
- const stringValue = jsonPathQuery(choiceRule.StringLessThanEqualsPath, input);
1039
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1040
+ const stringValue = jsonPathQuery(choiceRule.StringLessThanEqualsPath, input, context, {
1041
+ constraints: [StringConstraint]
1042
+ });
948
1043
  return varValue <= stringValue;
949
1044
  }
950
1045
  if ("StringGreaterThanEquals" in choiceRule) {
951
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1046
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
952
1047
  return varValue >= choiceRule.StringGreaterThanEquals;
953
1048
  }
954
1049
  if ("StringGreaterThanEqualsPath" in choiceRule) {
955
- const varValue = jsonPathQuery(choiceRule.Variable, input);
956
- const stringValue = jsonPathQuery(choiceRule.StringGreaterThanEqualsPath, input);
1050
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1051
+ const stringValue = jsonPathQuery(choiceRule.StringGreaterThanEqualsPath, input, context, {
1052
+ constraints: [StringConstraint]
1053
+ });
957
1054
  return varValue >= stringValue;
958
1055
  }
959
1056
  if ("StringMatches" in choiceRule) {
960
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1057
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
961
1058
  const isMatch = wcmatch(choiceRule.StringMatches, { separator: false });
962
1059
  return isMatch(varValue);
963
1060
  }
964
1061
  if ("NumericEquals" in choiceRule) {
965
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1062
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
966
1063
  return varValue === choiceRule.NumericEquals;
967
1064
  }
968
1065
  if ("NumericEqualsPath" in choiceRule) {
969
- const varValue = jsonPathQuery(choiceRule.Variable, input);
970
- const numberValue = jsonPathQuery(choiceRule.NumericEqualsPath, input);
1066
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1067
+ const numberValue = jsonPathQuery(choiceRule.NumericEqualsPath, input, context, {
1068
+ constraints: [NumberConstraint]
1069
+ });
971
1070
  return varValue === numberValue;
972
1071
  }
973
1072
  if ("NumericLessThan" in choiceRule) {
974
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1073
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
975
1074
  return varValue < choiceRule.NumericLessThan;
976
1075
  }
977
1076
  if ("NumericLessThanPath" in choiceRule) {
978
- const varValue = jsonPathQuery(choiceRule.Variable, input);
979
- const numberValue = jsonPathQuery(choiceRule.NumericLessThanPath, input);
1077
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1078
+ const numberValue = jsonPathQuery(choiceRule.NumericLessThanPath, input, context, {
1079
+ constraints: [NumberConstraint]
1080
+ });
980
1081
  return varValue < numberValue;
981
1082
  }
982
1083
  if ("NumericGreaterThan" in choiceRule) {
983
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1084
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
984
1085
  return varValue > choiceRule.NumericGreaterThan;
985
1086
  }
986
1087
  if ("NumericGreaterThanPath" in choiceRule) {
987
- const varValue = jsonPathQuery(choiceRule.Variable, input);
988
- const numberValue = jsonPathQuery(choiceRule.NumericGreaterThanPath, input);
1088
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1089
+ const numberValue = jsonPathQuery(choiceRule.NumericGreaterThanPath, input, context, {
1090
+ constraints: [NumberConstraint]
1091
+ });
989
1092
  return varValue > numberValue;
990
1093
  }
991
1094
  if ("NumericLessThanEquals" in choiceRule) {
992
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1095
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
993
1096
  return varValue <= choiceRule.NumericLessThanEquals;
994
1097
  }
995
1098
  if ("NumericLessThanEqualsPath" in choiceRule) {
996
- const varValue = jsonPathQuery(choiceRule.Variable, input);
997
- const numberValue = jsonPathQuery(choiceRule.NumericLessThanEqualsPath, input);
1099
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1100
+ const numberValue = jsonPathQuery(choiceRule.NumericLessThanEqualsPath, input, context, {
1101
+ constraints: [NumberConstraint]
1102
+ });
998
1103
  return varValue <= numberValue;
999
1104
  }
1000
1105
  if ("NumericGreaterThanEquals" in choiceRule) {
1001
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1106
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1002
1107
  return varValue >= choiceRule.NumericGreaterThanEquals;
1003
1108
  }
1004
1109
  if ("NumericGreaterThanEqualsPath" in choiceRule) {
1005
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1006
- const numberValue = jsonPathQuery(choiceRule.NumericGreaterThanEqualsPath, input);
1110
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1111
+ const numberValue = jsonPathQuery(choiceRule.NumericGreaterThanEqualsPath, input, context, {
1112
+ constraints: [NumberConstraint]
1113
+ });
1007
1114
  return varValue >= numberValue;
1008
1115
  }
1009
1116
  if ("BooleanEquals" in choiceRule) {
1010
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1117
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1011
1118
  return varValue === choiceRule.BooleanEquals;
1012
1119
  }
1013
1120
  if ("BooleanEqualsPath" in choiceRule) {
1014
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1015
- const booleanValue = jsonPathQuery(choiceRule.BooleanEqualsPath, input);
1121
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1122
+ const booleanValue = jsonPathQuery(choiceRule.BooleanEqualsPath, input, context, {
1123
+ constraints: [BooleanConstraint]
1124
+ });
1016
1125
  return varValue === booleanValue;
1017
1126
  }
1018
1127
  if ("TimestampEquals" in choiceRule) {
1019
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1128
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1020
1129
  const timestampValue = new Date(choiceRule.TimestampEquals);
1021
1130
  return varValue.getTime() === timestampValue.getTime();
1022
1131
  }
1023
1132
  if ("TimestampEqualsPath" in choiceRule) {
1024
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1025
- const timestampValue = new Date(jsonPathQuery(choiceRule.TimestampEqualsPath, input));
1133
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1134
+ const timestampValue = new Date(
1135
+ jsonPathQuery(choiceRule.TimestampEqualsPath, input, context, {
1136
+ constraints: [RFC3339TimestampConstraint]
1137
+ })
1138
+ );
1026
1139
  return varValue.getTime() === timestampValue.getTime();
1027
1140
  }
1028
1141
  if ("TimestampLessThan" in choiceRule) {
1029
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1142
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1030
1143
  const timestampValue = new Date(choiceRule.TimestampLessThan);
1031
1144
  return varValue < timestampValue;
1032
1145
  }
1033
1146
  if ("TimestampLessThanPath" in choiceRule) {
1034
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1035
- const timestampValue = new Date(jsonPathQuery(choiceRule.TimestampLessThanPath, input));
1147
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1148
+ const timestampValue = new Date(
1149
+ jsonPathQuery(choiceRule.TimestampLessThanPath, input, context, {
1150
+ constraints: [RFC3339TimestampConstraint]
1151
+ })
1152
+ );
1036
1153
  return varValue < timestampValue;
1037
1154
  }
1038
1155
  if ("TimestampGreaterThan" in choiceRule) {
1039
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1156
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1040
1157
  const timestampValue = new Date(choiceRule.TimestampGreaterThan);
1041
1158
  return varValue > timestampValue;
1042
1159
  }
1043
1160
  if ("TimestampGreaterThanPath" in choiceRule) {
1044
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1045
- const timestampValue = new Date(jsonPathQuery(choiceRule.TimestampGreaterThanPath, input));
1161
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1162
+ const timestampValue = new Date(
1163
+ jsonPathQuery(choiceRule.TimestampGreaterThanPath, input, context, {
1164
+ constraints: [RFC3339TimestampConstraint]
1165
+ })
1166
+ );
1046
1167
  return varValue > timestampValue;
1047
1168
  }
1048
1169
  if ("TimestampLessThanEquals" in choiceRule) {
1049
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1170
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1050
1171
  const timestampValue = new Date(choiceRule.TimestampLessThanEquals);
1051
1172
  return varValue <= timestampValue;
1052
1173
  }
1053
1174
  if ("TimestampLessThanEqualsPath" in choiceRule) {
1054
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1055
- const timestampValue = new Date(jsonPathQuery(choiceRule.TimestampLessThanEqualsPath, input));
1175
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1176
+ const timestampValue = new Date(
1177
+ jsonPathQuery(choiceRule.TimestampLessThanEqualsPath, input, context, {
1178
+ constraints: [RFC3339TimestampConstraint]
1179
+ })
1180
+ );
1056
1181
  return varValue <= timestampValue;
1057
1182
  }
1058
1183
  if ("TimestampGreaterThanEquals" in choiceRule) {
1059
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1184
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1060
1185
  const timestampValue = new Date(choiceRule.TimestampGreaterThanEquals);
1061
1186
  return varValue >= timestampValue;
1062
1187
  }
1063
1188
  if ("TimestampGreaterThanEqualsPath" in choiceRule) {
1064
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1065
- const timestampValue = new Date(jsonPathQuery(choiceRule.TimestampGreaterThanEqualsPath, input));
1189
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1190
+ const timestampValue = new Date(
1191
+ jsonPathQuery(choiceRule.TimestampGreaterThanEqualsPath, input, context, {
1192
+ constraints: [RFC3339TimestampConstraint]
1193
+ })
1194
+ );
1066
1195
  return varValue >= timestampValue;
1067
1196
  }
1068
1197
  if ("IsNull" in choiceRule) {
1069
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1198
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1070
1199
  const isNullTrue = choiceRule.IsNull;
1071
1200
  return isNullTrue && varValue === null;
1072
1201
  }
1073
1202
  if ("IsPresent" in choiceRule) {
1074
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1203
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context, { ignoreDefinedValueConstraint: true });
1075
1204
  const IsPresentTrue = choiceRule.IsPresent;
1076
1205
  return IsPresentTrue && varValue !== void 0;
1077
1206
  }
1078
1207
  if ("IsNumeric" in choiceRule) {
1079
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1208
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1080
1209
  const IsNumericTrue = choiceRule.IsNumeric;
1081
1210
  return IsNumericTrue && typeof varValue === "number";
1082
1211
  }
1083
1212
  if ("IsString" in choiceRule) {
1084
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1213
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1085
1214
  const IsStringTrue = choiceRule.IsString;
1086
1215
  return IsStringTrue && typeof varValue === "string";
1087
1216
  }
1088
1217
  if ("IsBoolean" in choiceRule) {
1089
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1218
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1090
1219
  const IsBooleanTrue = choiceRule.IsBoolean;
1091
1220
  return IsBooleanTrue && typeof varValue === "boolean";
1092
1221
  }
1093
1222
  if ("IsTimestamp" in choiceRule) {
1094
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1223
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1095
1224
  const IsTimestampTrue = choiceRule.IsTimestamp;
1096
- return IsTimestampTrue && /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|(\+|-)\d{2}:\d{2})/.test(varValue);
1225
+ return IsTimestampTrue && isRFC3339Timestamp(varValue);
1097
1226
  }
1098
1227
  return false;
1099
1228
  }
1100
1229
  async execute(input, context, options) {
1101
1230
  const state = this.stateDefinition;
1102
1231
  for (const choice of state.Choices) {
1103
- const choiceIsMatch = this.testChoiceRule(choice, input);
1232
+ const choiceIsMatch = this.testChoiceRule(choice, input, context);
1104
1233
  if (choiceIsMatch) {
1105
1234
  return { stateResult: input, nextState: choice.Next, isEndState: false };
1106
1235
  }
@@ -1130,6 +1259,17 @@ var FailStateAction = class extends BaseStateAction {
1130
1259
  }
1131
1260
  };
1132
1261
 
1262
+ // src/stateMachine/jsonPath/constraints/ArrayConstraint.ts
1263
+ var ArrayConstraint = class extends BaseJSONPathConstraint {
1264
+ test(value) {
1265
+ if (!Array.isArray(value)) {
1266
+ throw new StatesRuntimeError(
1267
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(value)}, but expected an array`
1268
+ );
1269
+ }
1270
+ }
1271
+ };
1272
+
1133
1273
  // src/stateMachine/stateActions/MapStateAction.ts
1134
1274
  import pLimit from "p-limit";
1135
1275
  var DEFAULT_MAX_CONCURRENCY = 40;
@@ -1157,23 +1297,25 @@ var MapStateAction = class extends BaseStateAction {
1157
1297
  if (state.Parameters) {
1158
1298
  paramValue = processPayloadTemplate(state.Parameters, input, context);
1159
1299
  }
1160
- const execution = stateMachine.run(paramValue ?? item, options?.runOptions);
1300
+ const execution = stateMachine.run(paramValue ?? item, options.runOptions);
1161
1301
  this.executionAbortFuncs.push(execution.abort);
1162
- this.forwardEventsToRootEventLogger(options?.eventLogger, execution.eventLogs, index, options?.rawInput);
1302
+ this.forwardEventsToRootEventLogger(options.eventLogger, execution.eventLogs, index, options.rawInput);
1163
1303
  return execution.result;
1164
1304
  }
1165
1305
  async execute(input, context, options) {
1166
1306
  const state = this.stateDefinition;
1167
1307
  let items = input;
1168
1308
  if (state.ItemsPath) {
1169
- items = jsonPathQuery(state.ItemsPath, input, context);
1309
+ items = jsonPathQuery(state.ItemsPath, input, context, {
1310
+ constraints: [ArrayConstraint]
1311
+ });
1170
1312
  }
1171
1313
  if (!Array.isArray(items)) {
1172
1314
  throw new StatesRuntimeError("Input of Map state must be an array or ItemsPath property must point to an array");
1173
1315
  }
1174
1316
  const iteratorStateMachine = new StateMachine(state.Iterator, {
1175
- ...options?.stateMachineOptions,
1176
- validationOptions: { _noValidate: true }
1317
+ ...options.stateMachineOptions,
1318
+ validationOptions: { noValidate: true }
1177
1319
  });
1178
1320
  const limit = pLimit(state.MaxConcurrency || DEFAULT_MAX_CONCURRENCY);
1179
1321
  const processedItemsPromise = items.map(
@@ -1185,7 +1327,7 @@ var MapStateAction = class extends BaseStateAction {
1185
1327
  } catch (error) {
1186
1328
  this.executionAbortFuncs.forEach((abort) => abort());
1187
1329
  if (error instanceof ExecutionError) {
1188
- throw error.getWrappedError;
1330
+ throw error.cause;
1189
1331
  }
1190
1332
  throw error;
1191
1333
  } finally {
@@ -1211,12 +1353,12 @@ var ParallelStateAction = class extends BaseStateAction {
1211
1353
  }
1212
1354
  processBranch(branch, input, context, options) {
1213
1355
  const stateMachine = new StateMachine(branch, {
1214
- ...options?.stateMachineOptions,
1215
- validationOptions: { _noValidate: true }
1356
+ ...options.stateMachineOptions,
1357
+ validationOptions: { noValidate: true }
1216
1358
  });
1217
- const execution = stateMachine.run(input, options?.runOptions);
1359
+ const execution = stateMachine.run(input, options.runOptions);
1218
1360
  this.executionAbortFuncs.push(execution.abort);
1219
- this.forwardEventsToRootEventLogger(options?.eventLogger, execution.eventLogs, options?.rawInput);
1361
+ this.forwardEventsToRootEventLogger(options.eventLogger, execution.eventLogs, options.rawInput);
1220
1362
  return execution.result;
1221
1363
  }
1222
1364
  async execute(input, context, options) {
@@ -1231,7 +1373,7 @@ var ParallelStateAction = class extends BaseStateAction {
1231
1373
  } catch (error) {
1232
1374
  this.executionAbortFuncs.forEach((abort) => abort());
1233
1375
  if (error instanceof ExecutionError) {
1234
- throw error.getWrappedError;
1376
+ throw error.cause;
1235
1377
  }
1236
1378
  throw error;
1237
1379
  }
@@ -1264,13 +1406,28 @@ var SucceedStateAction = class extends BaseStateAction {
1264
1406
  // src/aws/LambdaClient.ts
1265
1407
  import { LambdaClient as AWSLambdaClient, InvokeCommand } from "@aws-sdk/client-lambda";
1266
1408
  import { fromCognitoIdentityPool } from "@aws-sdk/credential-providers";
1409
+
1410
+ // src/error/LambdaInvocationError.ts
1411
+ var LambdaInvocationError = class extends RuntimeError {
1412
+ constructor(name, message, cause) {
1413
+ super(message, cause);
1414
+ this.name = name;
1415
+ }
1416
+ };
1417
+
1418
+ // src/aws/LambdaClient.ts
1267
1419
  var LambdaClient = class {
1268
1420
  constructor(config) {
1269
1421
  this.client = new AWSLambdaClient({});
1270
1422
  if (config) {
1271
1423
  if (!config.region) {
1272
1424
  throw new StatesRuntimeError(
1273
- "'awsConfig' option was specified for state machine, but 'region' property is not set"
1425
+ "'awsConfig' option was specified in state machine constructor, but 'region' property is not set."
1426
+ );
1427
+ }
1428
+ if (!config.credentials) {
1429
+ throw new StatesRuntimeError(
1430
+ "'awsConfig' option was specified in state machine constructor, but 'credentials' property is not set."
1274
1431
  );
1275
1432
  }
1276
1433
  if (config.credentials) {
@@ -1293,6 +1450,12 @@ var LambdaClient = class {
1293
1450
  } else if (config.credentials?.accessKeys) {
1294
1451
  this.client = new AWSLambdaClient({ region: config.region, credentials: config.credentials.accessKeys });
1295
1452
  }
1453
+ } else {
1454
+ if (isBrowserEnvironment) {
1455
+ throw new StatesRuntimeError(
1456
+ "aws-local-stepfunctions is running in a browser environment and your state machine definition contains a state of type 'Task'. In order to invoke the Lambda function, you must provide an AWS region and credentials in the state machine constructor by passing the 'awsConfig' option."
1457
+ );
1458
+ }
1296
1459
  }
1297
1460
  }
1298
1461
  async invokeFunction(funcNameOrArn, payload) {
@@ -1309,7 +1472,11 @@ var LambdaClient = class {
1309
1472
  }
1310
1473
  if (invocationResult.FunctionError) {
1311
1474
  const errorResult = resultValue;
1312
- throw new FailStateError(errorResult.errorType, `Execution of Lambda function '${funcNameOrArn}' failed`);
1475
+ throw new LambdaInvocationError(
1476
+ errorResult.errorType,
1477
+ `${errorResult.errorType}: ${errorResult.errorMessage}`,
1478
+ errorResult
1479
+ );
1313
1480
  }
1314
1481
  return resultValue;
1315
1482
  }
@@ -1322,16 +1489,41 @@ var TaskStateAction = class extends BaseStateAction {
1322
1489
  }
1323
1490
  async execute(input, context, options) {
1324
1491
  const state = this.stateDefinition;
1325
- if (options?.overrideFn) {
1492
+ if (options.overrideFn) {
1326
1493
  const result2 = await options.overrideFn(input);
1327
1494
  return this.buildExecutionResult(result2);
1328
1495
  }
1329
- const lambdaClient = new LambdaClient(options?.awsConfig);
1496
+ const lambdaClient = new LambdaClient(options.awsConfig);
1330
1497
  const result = await lambdaClient.invokeFunction(state.Resource, input);
1331
1498
  return this.buildExecutionResult(result);
1332
1499
  }
1333
1500
  };
1334
1501
 
1502
+ // src/stateMachine/jsonPath/constraints/IntegerConstraint.ts
1503
+ var IntegerConstraint = class extends BaseJSONPathConstraint {
1504
+ test(value) {
1505
+ if (!Number.isInteger(value)) {
1506
+ throw new StatesRuntimeError(
1507
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(value)}, but expected an integer`
1508
+ );
1509
+ }
1510
+ }
1511
+ static greaterThanOrEqual(n) {
1512
+ return class extends this {
1513
+ test(value) {
1514
+ super.test(value);
1515
+ if (value < n) {
1516
+ throw new StatesRuntimeError(
1517
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(
1518
+ value
1519
+ )}, but expected an integer >= ${n}`
1520
+ );
1521
+ }
1522
+ }
1523
+ };
1524
+ }
1525
+ };
1526
+
1335
1527
  // src/stateMachine/stateActions/WaitStateAction.ts
1336
1528
  var WaitStateAction = class extends BaseStateAction {
1337
1529
  constructor(stateDefinition, stateName) {
@@ -1339,26 +1531,30 @@ var WaitStateAction = class extends BaseStateAction {
1339
1531
  }
1340
1532
  async execute(input, context, options) {
1341
1533
  const state = this.stateDefinition;
1342
- if (options?.waitTimeOverrideOption !== void 0) {
1343
- await sleep(options.waitTimeOverrideOption, options.abortSignal, options.rootAbortSignal);
1534
+ if (options.waitTimeOverrideOption !== void 0) {
1535
+ await sleep(options.waitTimeOverrideOption, options.abortSignal);
1344
1536
  return this.buildExecutionResult(input);
1345
1537
  }
1346
1538
  if (state.Seconds) {
1347
- await sleep(state.Seconds * 1e3, options?.abortSignal, options?.rootAbortSignal);
1539
+ await sleep(state.Seconds * 1e3, options.abortSignal);
1348
1540
  } else if (state.Timestamp) {
1349
1541
  const dateTimestamp = new Date(state.Timestamp);
1350
1542
  const currentTime = Date.now();
1351
1543
  const timeDiff = dateTimestamp.getTime() - currentTime;
1352
- await sleep(timeDiff, options?.abortSignal, options?.rootAbortSignal);
1544
+ await sleep(timeDiff, options.abortSignal);
1353
1545
  } else if (state.SecondsPath) {
1354
- const seconds = jsonPathQuery(state.SecondsPath, input, context);
1355
- await sleep(seconds * 1e3, options?.abortSignal, options?.rootAbortSignal);
1546
+ const seconds = jsonPathQuery(state.SecondsPath, input, context, {
1547
+ constraints: [IntegerConstraint.greaterThanOrEqual(0)]
1548
+ });
1549
+ await sleep(seconds * 1e3, options.abortSignal);
1356
1550
  } else if (state.TimestampPath) {
1357
- const timestamp = jsonPathQuery(state.TimestampPath, input, context);
1551
+ const timestamp = jsonPathQuery(state.TimestampPath, input, context, {
1552
+ constraints: [RFC3339TimestampConstraint]
1553
+ });
1358
1554
  const dateTimestamp = new Date(timestamp);
1359
1555
  const currentTime = Date.now();
1360
1556
  const timeDiff = dateTimestamp.getTime() - currentTime;
1361
- await sleep(timeDiff, options?.abortSignal, options?.rootAbortSignal);
1557
+ await sleep(timeDiff, options.abortSignal);
1362
1558
  }
1363
1559
  return this.buildExecutionResult(input);
1364
1560
  }
@@ -1418,13 +1614,34 @@ var StateExecutor = class {
1418
1614
  const processedResult = this.processResult(currResult, rawInput, context);
1419
1615
  return { stateResult: processedResult, nextState, isEndState };
1420
1616
  } catch (error) {
1421
- const { shouldRetry, waitTimeBeforeRetry } = this.shouldRetry(error);
1422
- if (shouldRetry && waitTimeBeforeRetry) {
1423
- await sleep(waitTimeBeforeRetry, options.abortSignal, options.runOptions?._rootAbortSignal);
1617
+ options.eventLogger.dispatchStateFailedEvent(
1618
+ this.stateName,
1619
+ this.stateDefinition.Type,
1620
+ input,
1621
+ error
1622
+ );
1623
+ const { shouldRetry, waitTimeBeforeRetry, retrierIndex } = this.shouldRetry(error);
1624
+ if (shouldRetry) {
1625
+ const stateDefinition = this.stateDefinition;
1626
+ await sleep(waitTimeBeforeRetry, options.abortSignal);
1627
+ options.eventLogger.dispatchStateRetriedEvent(
1628
+ this.stateName,
1629
+ stateDefinition.Type,
1630
+ input,
1631
+ stateDefinition.Retry[retrierIndex],
1632
+ this.retrierAttempts[retrierIndex]
1633
+ );
1424
1634
  return this.execute(input, context, options);
1425
1635
  }
1426
- const { nextState, errorOutput, resultPath } = this.catchError(error);
1636
+ const { nextState, errorOutput, resultPath, catcherIndex } = this.catchError(error);
1427
1637
  if (nextState && errorOutput) {
1638
+ const stateDefinition = this.stateDefinition;
1639
+ options.eventLogger.dispatchStateCaughtEvent(
1640
+ this.stateName,
1641
+ stateDefinition.Type,
1642
+ input,
1643
+ stateDefinition.Catch[catcherIndex]
1644
+ );
1428
1645
  return { stateResult: processResultPath(resultPath, rawInput, errorOutput), nextState, isEndState: false };
1429
1646
  }
1430
1647
  throw error;
@@ -1482,7 +1699,7 @@ var StateExecutor = class {
1482
1699
  if (this.retrierAttempts[i] >= maxAttempts)
1483
1700
  return { shouldRetry: false };
1484
1701
  this.retrierAttempts[i]++;
1485
- return { shouldRetry: true, waitTimeBeforeRetry };
1702
+ return { shouldRetry: true, waitTimeBeforeRetry, retrierIndex: i };
1486
1703
  }
1487
1704
  }
1488
1705
  }
@@ -1510,7 +1727,7 @@ var StateExecutor = class {
1510
1727
  Cause: error.message
1511
1728
  };
1512
1729
  const resultPath = catcher.ResultPath;
1513
- return { nextState, errorOutput, resultPath };
1730
+ return { nextState, errorOutput, resultPath, catcherIndex: i };
1514
1731
  }
1515
1732
  }
1516
1733
  }
@@ -1584,8 +1801,7 @@ var StateExecutor = class {
1584
1801
  const waitStateAction = new WaitStateAction(stateDefinition, stateName);
1585
1802
  const executionResult = await waitStateAction.execute(input, context, {
1586
1803
  waitTimeOverrideOption,
1587
- abortSignal: options.abortSignal,
1588
- rootAbortSignal: options.runOptions?._rootAbortSignal
1804
+ abortSignal: options.abortSignal
1589
1805
  });
1590
1806
  return executionResult;
1591
1807
  }
@@ -1670,6 +1886,9 @@ var EventLogger = class {
1670
1886
  break;
1671
1887
  case "StateEntered":
1672
1888
  case "StateExited":
1889
+ case "StateFailed":
1890
+ case "StateRetried":
1891
+ case "StateCaught":
1673
1892
  event.index = index;
1674
1893
  this.dispatch(event);
1675
1894
  break;
@@ -1714,7 +1933,12 @@ var EventLogger = class {
1714
1933
  this.close();
1715
1934
  }
1716
1935
  dispatchExecutionFailedEvent(error) {
1717
- this.dispatch({ type: "ExecutionFailed", timestamp: Date.now(), Error: error.name, Cause: error.message });
1936
+ this.dispatch({
1937
+ type: "ExecutionFailed",
1938
+ timestamp: Date.now(),
1939
+ Error: error.name,
1940
+ Cause: error.cause ?? error.message
1941
+ });
1718
1942
  this.close();
1719
1943
  }
1720
1944
  dispatchExecutionAbortedEvent() {
@@ -1739,6 +1963,31 @@ var EventLogger = class {
1739
1963
  state: { name: stateName, type: stateType, input, output }
1740
1964
  });
1741
1965
  }
1966
+ dispatchStateFailedEvent(stateName, stateType, input, error) {
1967
+ this.dispatch({
1968
+ type: "StateFailed",
1969
+ timestamp: Date.now(),
1970
+ state: { name: stateName, type: stateType, input },
1971
+ Error: error.name,
1972
+ Cause: error.cause ?? error.message
1973
+ });
1974
+ }
1975
+ dispatchStateRetriedEvent(stateName, stateType, input, retrier, retryAttempt) {
1976
+ this.dispatch({
1977
+ type: "StateRetried",
1978
+ timestamp: Date.now(),
1979
+ state: { name: stateName, type: stateType, input },
1980
+ retry: { retrier, attempt: retryAttempt }
1981
+ });
1982
+ }
1983
+ dispatchStateCaughtEvent(stateName, stateType, input, catcher) {
1984
+ this.dispatch({
1985
+ type: "StateCaught",
1986
+ timestamp: Date.now(),
1987
+ state: { name: stateName, type: stateType, input },
1988
+ catch: { catcher }
1989
+ });
1990
+ }
1742
1991
  dispatchMapIterationStartedEvent(event, index, mapStateName, mapStateRawInput) {
1743
1992
  this.dispatch({
1744
1993
  ...event,
@@ -1814,7 +2063,7 @@ var StateMachine = class {
1814
2063
  * These options also apply to state machines defined in the `Iterator` field of `Map` states and in the `Branches` field of `Parallel` states.
1815
2064
  */
1816
2065
  constructor(definition, stateMachineOptions) {
1817
- if (!stateMachineOptions?.validationOptions?._noValidate) {
2066
+ if (!stateMachineOptions?.validationOptions?.noValidate) {
1818
2067
  const { isValid, errorsText } = aslValidator(definition, {
1819
2068
  checkArn: true,
1820
2069
  checkPaths: true,
@@ -1845,6 +2094,15 @@ var StateMachine = class {
1845
2094
  run(input, options) {
1846
2095
  const abortController = new AbortController();
1847
2096
  const eventLogger = new EventLogger();
2097
+ let rootSignalAbortHandler;
2098
+ if (options?._rootAbortSignal) {
2099
+ rootSignalAbortHandler = () => abortController.abort();
2100
+ if (options._rootAbortSignal.aborted) {
2101
+ rootSignalAbortHandler();
2102
+ } else {
2103
+ options._rootAbortSignal.addEventListener("abort", rootSignalAbortHandler);
2104
+ }
2105
+ }
1848
2106
  let onAbortHandler;
1849
2107
  const settleOnAbort = new Promise((resolve, reject) => {
1850
2108
  if (options?.noThrowOnAbort) {
@@ -1882,6 +2140,7 @@ var StateMachine = class {
1882
2140
  },
1883
2141
  () => {
1884
2142
  abortController.signal.removeEventListener("abort", onAbortHandler);
2143
+ options?._rootAbortSignal?.removeEventListener("abort", rootSignalAbortHandler);
1885
2144
  clearTimeout(timeoutId);
1886
2145
  }
1887
2146
  );