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.
@@ -71,20 +71,27 @@ var ExecutionTimeoutError = class extends Error {
71
71
  }
72
72
  };
73
73
 
74
+ // src/error/ErrorWithCause.ts
75
+ var _errorCause;
76
+ var ErrorWithCause = class extends Error {
77
+ constructor(message, options) {
78
+ super(message);
79
+ __privateAdd(this, _errorCause, void 0);
80
+ __privateSet(this, _errorCause, options?.cause);
81
+ }
82
+ get cause() {
83
+ return __privateGet(this, _errorCause);
84
+ }
85
+ };
86
+ _errorCause = new WeakMap();
87
+
74
88
  // src/error/ExecutionError.ts
75
- var _wrappedError;
76
- var ExecutionError = class extends Error {
89
+ var ExecutionError = class extends ErrorWithCause {
77
90
  constructor(caughtError) {
78
- super(`Execution has failed with the following error: ${caughtError.message}`);
79
- __privateAdd(this, _wrappedError, void 0);
91
+ super(`Execution has failed with the following error: ${caughtError.message}`, { cause: caughtError });
80
92
  this.name = "ExecutionError";
81
- __privateSet(this, _wrappedError, caughtError);
82
- }
83
- get getWrappedError() {
84
- return __privateGet(this, _wrappedError);
85
93
  }
86
94
  };
87
- _wrappedError = new WeakMap();
88
95
 
89
96
  // src/util/random.ts
90
97
  function cyrb128(str) {
@@ -123,46 +130,51 @@ function getRandomNumber(min, max, rng = Math.random) {
123
130
  }
124
131
 
125
132
  // src/util/index.ts
133
+ var isBrowserEnvironment = typeof window !== "undefined" && typeof window.document !== "undefined";
126
134
  function isPlainObj(value) {
127
135
  return !!value && Object.getPrototypeOf(value) === Object.prototype;
128
136
  }
129
- function sleep(ms, abortSignal, rootAbortSignal) {
137
+ function sleep(ms, abortSignal) {
130
138
  return new Promise((resolve) => {
131
- if (abortSignal?.aborted || rootAbortSignal?.aborted) {
139
+ if (abortSignal?.aborted) {
132
140
  return resolve();
133
141
  }
134
142
  const onAbort = () => {
135
- abortSignal?.removeEventListener("abort", onAbort);
136
- rootAbortSignal?.removeEventListener("abort", onAbort);
137
143
  clearTimeout(timeout);
138
144
  resolve();
139
145
  };
140
146
  const timeout = setTimeout(() => {
141
147
  abortSignal?.removeEventListener("abort", onAbort);
142
- rootAbortSignal?.removeEventListener("abort", onAbort);
143
148
  resolve();
144
149
  }, ms);
145
- abortSignal?.addEventListener("abort", onAbort);
146
- rootAbortSignal?.addEventListener("abort", onAbort);
150
+ abortSignal?.addEventListener("abort", onAbort, { once: true });
147
151
  });
148
152
  }
149
153
  function byteToHex(byte) {
150
154
  return byte.toString(16).padStart(2, "0");
151
155
  }
156
+ function isRFC3339Timestamp(date) {
157
+ 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]))$/;
158
+ return regex.test(date);
159
+ }
160
+ function stringifyJSONValue(value) {
161
+ return JSON.stringify(value);
162
+ }
152
163
 
153
- // src/stateMachine/JsonPath.ts
164
+ // src/stateMachine/jsonPath/JsonPath.ts
154
165
  var import_jsonpath_plus = require("jsonpath-plus");
155
- function jsonPathQuery(pathExpression, json, context) {
156
- if (pathExpression.startsWith("$$")) {
157
- return (0, import_jsonpath_plus.JSONPath)({ path: pathExpression.slice(1), json: context ?? null, wrap: false });
166
+
167
+ // src/stateMachine/jsonPath/constraints/BaseJsonPathConstraint.ts
168
+ var BaseJSONPathConstraint = class {
169
+ constructor(pathExpression) {
170
+ this.pathExpression = pathExpression;
158
171
  }
159
- return (0, import_jsonpath_plus.JSONPath)({ path: pathExpression, json, wrap: false });
160
- }
172
+ };
161
173
 
162
174
  // src/error/RuntimeError.ts
163
- var RuntimeError = class extends Error {
164
- constructor(message) {
165
- super(message);
175
+ var RuntimeError = class extends ErrorWithCause {
176
+ constructor(message, cause) {
177
+ super(message, { cause });
166
178
  this.name = "RuntimeError";
167
179
  this.retryable = true;
168
180
  this.catchable = true;
@@ -175,14 +187,6 @@ var RuntimeError = class extends Error {
175
187
  }
176
188
  };
177
189
 
178
- // src/error/predefined/StatesResultPathMatchFailureError.ts
179
- var StatesResultPathMatchFailureError = class extends RuntimeError {
180
- constructor() {
181
- super("States.ResultPathMatchFailure");
182
- this.name = "States.ResultPathMatchFailure";
183
- }
184
- };
185
-
186
190
  // src/error/predefined/StatesRuntimeError.ts
187
191
  var StatesRuntimeError = class extends RuntimeError {
188
192
  constructor(message = "States.Runtime") {
@@ -193,6 +197,43 @@ var StatesRuntimeError = class extends RuntimeError {
193
197
  }
194
198
  };
195
199
 
200
+ // src/stateMachine/jsonPath/constraints/DefinedValueConstraint.ts
201
+ var DefinedValueConstraint = class extends BaseJSONPathConstraint {
202
+ test(value) {
203
+ if (typeof value === "undefined") {
204
+ throw new StatesRuntimeError(`Path expression '${this.pathExpression}' does not point to a value`);
205
+ }
206
+ }
207
+ };
208
+
209
+ // src/stateMachine/jsonPath/JsonPath.ts
210
+ function jsonPathQuery(pathExpression, json, context, options) {
211
+ const defaultConstraints = [];
212
+ if (!options?.ignoreDefinedValueConstraint) {
213
+ defaultConstraints.push(DefinedValueConstraint);
214
+ }
215
+ const constraints = [...defaultConstraints, ...options?.constraints ?? []];
216
+ let evaluation;
217
+ if (pathExpression.startsWith("$$")) {
218
+ evaluation = (0, import_jsonpath_plus.JSONPath)({ path: pathExpression.slice(1), json: context ?? null, wrap: false });
219
+ } else {
220
+ evaluation = (0, import_jsonpath_plus.JSONPath)({ path: pathExpression, json, wrap: false });
221
+ }
222
+ for (const Constraint of constraints) {
223
+ const constraintObject = new Constraint(pathExpression);
224
+ constraintObject.test(evaluation);
225
+ }
226
+ return evaluation;
227
+ }
228
+
229
+ // src/error/predefined/StatesResultPathMatchFailureError.ts
230
+ var StatesResultPathMatchFailureError = class extends RuntimeError {
231
+ constructor() {
232
+ super("States.ResultPathMatchFailure");
233
+ this.name = "States.ResultPathMatchFailure";
234
+ }
235
+ };
236
+
196
237
  // src/stateMachine/intrinsicFunctions/ArgumentHandling.ts
197
238
  function validateArgumentType(allowedTypes, argPosition, funcArg, funcName) {
198
239
  let matchesAllowedType = false;
@@ -933,212 +974,300 @@ var StatesNoChoiceMatchedError = class extends RuntimeError {
933
974
  }
934
975
  };
935
976
 
977
+ // src/stateMachine/jsonPath/constraints/StringConstraint.ts
978
+ var StringConstraint = class extends BaseJSONPathConstraint {
979
+ test(value) {
980
+ if (typeof value !== "string") {
981
+ throw new StatesRuntimeError(
982
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(value)}, but expected a string`
983
+ );
984
+ }
985
+ }
986
+ };
987
+
988
+ // src/stateMachine/jsonPath/constraints/NumberConstraint.ts
989
+ var NumberConstraint = class extends BaseJSONPathConstraint {
990
+ test(value) {
991
+ if (typeof value !== "number") {
992
+ throw new StatesRuntimeError(
993
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(value)}, but expected a number`
994
+ );
995
+ }
996
+ }
997
+ };
998
+
999
+ // src/stateMachine/jsonPath/constraints/BooleanConstraint.ts
1000
+ var BooleanConstraint = class extends BaseJSONPathConstraint {
1001
+ test(value) {
1002
+ if (typeof value !== "boolean") {
1003
+ throw new StatesRuntimeError(
1004
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(value)}, but expected a boolean`
1005
+ );
1006
+ }
1007
+ }
1008
+ };
1009
+
1010
+ // src/stateMachine/jsonPath/constraints/RFC3339TimestampConstraint.ts
1011
+ var RFC3339TimestampConstraint = class extends BaseJSONPathConstraint {
1012
+ test(value) {
1013
+ if (typeof value !== "string" || !isRFC3339Timestamp(value)) {
1014
+ throw new StatesRuntimeError(
1015
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(
1016
+ value
1017
+ )}, but expected a timestamp conforming to the RFC3339 profile`
1018
+ );
1019
+ }
1020
+ }
1021
+ };
1022
+
936
1023
  // src/stateMachine/stateActions/ChoiceStateAction.ts
937
1024
  var import_wildcard_match = __toESM(require("wildcard-match"), 1);
938
1025
  var ChoiceStateAction = class extends BaseStateAction {
939
1026
  constructor(stateDefinition, stateName) {
940
1027
  super(stateDefinition, stateName);
941
1028
  }
942
- testChoiceRule(choiceRule, input) {
1029
+ testChoiceRule(choiceRule, input, context) {
943
1030
  if ("And" in choiceRule) {
944
- return choiceRule.And.every((rule) => this.testChoiceRule(rule, input));
1031
+ return choiceRule.And.every((rule) => this.testChoiceRule(rule, input, context));
945
1032
  }
946
1033
  if ("Or" in choiceRule) {
947
- return choiceRule.Or.some((rule) => this.testChoiceRule(rule, input));
1034
+ return choiceRule.Or.some((rule) => this.testChoiceRule(rule, input, context));
948
1035
  }
949
1036
  if ("Not" in choiceRule) {
950
- return !this.testChoiceRule(choiceRule.Not, input);
1037
+ return !this.testChoiceRule(choiceRule.Not, input, context);
951
1038
  }
952
1039
  if ("StringEquals" in choiceRule) {
953
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1040
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
954
1041
  return varValue === choiceRule.StringEquals;
955
1042
  }
956
1043
  if ("StringEqualsPath" in choiceRule) {
957
- const varValue = jsonPathQuery(choiceRule.Variable, input);
958
- const stringValue = jsonPathQuery(choiceRule.StringEqualsPath, input);
1044
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1045
+ const stringValue = jsonPathQuery(choiceRule.StringEqualsPath, input, context, {
1046
+ constraints: [StringConstraint]
1047
+ });
959
1048
  return varValue === stringValue;
960
1049
  }
961
1050
  if ("StringLessThan" in choiceRule) {
962
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1051
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
963
1052
  return varValue < choiceRule.StringLessThan;
964
1053
  }
965
1054
  if ("StringLessThanPath" in choiceRule) {
966
- const varValue = jsonPathQuery(choiceRule.Variable, input);
967
- const stringValue = jsonPathQuery(choiceRule.StringLessThanPath, input);
1055
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1056
+ const stringValue = jsonPathQuery(choiceRule.StringLessThanPath, input, context, {
1057
+ constraints: [StringConstraint]
1058
+ });
968
1059
  return varValue < stringValue;
969
1060
  }
970
1061
  if ("StringGreaterThan" in choiceRule) {
971
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1062
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
972
1063
  return varValue > choiceRule.StringGreaterThan;
973
1064
  }
974
1065
  if ("StringGreaterThanPath" in choiceRule) {
975
- const varValue = jsonPathQuery(choiceRule.Variable, input);
976
- const stringValue = jsonPathQuery(choiceRule.StringGreaterThanPath, input);
1066
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1067
+ const stringValue = jsonPathQuery(choiceRule.StringGreaterThanPath, input, context, {
1068
+ constraints: [StringConstraint]
1069
+ });
977
1070
  return varValue > stringValue;
978
1071
  }
979
1072
  if ("StringLessThanEquals" in choiceRule) {
980
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1073
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
981
1074
  return varValue <= choiceRule.StringLessThanEquals;
982
1075
  }
983
1076
  if ("StringLessThanEqualsPath" in choiceRule) {
984
- const varValue = jsonPathQuery(choiceRule.Variable, input);
985
- const stringValue = jsonPathQuery(choiceRule.StringLessThanEqualsPath, input);
1077
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1078
+ const stringValue = jsonPathQuery(choiceRule.StringLessThanEqualsPath, input, context, {
1079
+ constraints: [StringConstraint]
1080
+ });
986
1081
  return varValue <= stringValue;
987
1082
  }
988
1083
  if ("StringGreaterThanEquals" in choiceRule) {
989
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1084
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
990
1085
  return varValue >= choiceRule.StringGreaterThanEquals;
991
1086
  }
992
1087
  if ("StringGreaterThanEqualsPath" in choiceRule) {
993
- const varValue = jsonPathQuery(choiceRule.Variable, input);
994
- const stringValue = jsonPathQuery(choiceRule.StringGreaterThanEqualsPath, input);
1088
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1089
+ const stringValue = jsonPathQuery(choiceRule.StringGreaterThanEqualsPath, input, context, {
1090
+ constraints: [StringConstraint]
1091
+ });
995
1092
  return varValue >= stringValue;
996
1093
  }
997
1094
  if ("StringMatches" in choiceRule) {
998
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1095
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
999
1096
  const isMatch = (0, import_wildcard_match.default)(choiceRule.StringMatches, { separator: false });
1000
1097
  return isMatch(varValue);
1001
1098
  }
1002
1099
  if ("NumericEquals" in choiceRule) {
1003
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1100
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1004
1101
  return varValue === choiceRule.NumericEquals;
1005
1102
  }
1006
1103
  if ("NumericEqualsPath" in choiceRule) {
1007
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1008
- const numberValue = jsonPathQuery(choiceRule.NumericEqualsPath, input);
1104
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1105
+ const numberValue = jsonPathQuery(choiceRule.NumericEqualsPath, input, context, {
1106
+ constraints: [NumberConstraint]
1107
+ });
1009
1108
  return varValue === numberValue;
1010
1109
  }
1011
1110
  if ("NumericLessThan" in choiceRule) {
1012
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1111
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1013
1112
  return varValue < choiceRule.NumericLessThan;
1014
1113
  }
1015
1114
  if ("NumericLessThanPath" in choiceRule) {
1016
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1017
- const numberValue = jsonPathQuery(choiceRule.NumericLessThanPath, input);
1115
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1116
+ const numberValue = jsonPathQuery(choiceRule.NumericLessThanPath, input, context, {
1117
+ constraints: [NumberConstraint]
1118
+ });
1018
1119
  return varValue < numberValue;
1019
1120
  }
1020
1121
  if ("NumericGreaterThan" in choiceRule) {
1021
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1122
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1022
1123
  return varValue > choiceRule.NumericGreaterThan;
1023
1124
  }
1024
1125
  if ("NumericGreaterThanPath" in choiceRule) {
1025
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1026
- const numberValue = jsonPathQuery(choiceRule.NumericGreaterThanPath, input);
1126
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1127
+ const numberValue = jsonPathQuery(choiceRule.NumericGreaterThanPath, input, context, {
1128
+ constraints: [NumberConstraint]
1129
+ });
1027
1130
  return varValue > numberValue;
1028
1131
  }
1029
1132
  if ("NumericLessThanEquals" in choiceRule) {
1030
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1133
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1031
1134
  return varValue <= choiceRule.NumericLessThanEquals;
1032
1135
  }
1033
1136
  if ("NumericLessThanEqualsPath" in choiceRule) {
1034
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1035
- const numberValue = jsonPathQuery(choiceRule.NumericLessThanEqualsPath, input);
1137
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1138
+ const numberValue = jsonPathQuery(choiceRule.NumericLessThanEqualsPath, input, context, {
1139
+ constraints: [NumberConstraint]
1140
+ });
1036
1141
  return varValue <= numberValue;
1037
1142
  }
1038
1143
  if ("NumericGreaterThanEquals" in choiceRule) {
1039
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1144
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1040
1145
  return varValue >= choiceRule.NumericGreaterThanEquals;
1041
1146
  }
1042
1147
  if ("NumericGreaterThanEqualsPath" in choiceRule) {
1043
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1044
- const numberValue = jsonPathQuery(choiceRule.NumericGreaterThanEqualsPath, input);
1148
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1149
+ const numberValue = jsonPathQuery(choiceRule.NumericGreaterThanEqualsPath, input, context, {
1150
+ constraints: [NumberConstraint]
1151
+ });
1045
1152
  return varValue >= numberValue;
1046
1153
  }
1047
1154
  if ("BooleanEquals" in choiceRule) {
1048
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1155
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1049
1156
  return varValue === choiceRule.BooleanEquals;
1050
1157
  }
1051
1158
  if ("BooleanEqualsPath" in choiceRule) {
1052
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1053
- const booleanValue = jsonPathQuery(choiceRule.BooleanEqualsPath, input);
1159
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1160
+ const booleanValue = jsonPathQuery(choiceRule.BooleanEqualsPath, input, context, {
1161
+ constraints: [BooleanConstraint]
1162
+ });
1054
1163
  return varValue === booleanValue;
1055
1164
  }
1056
1165
  if ("TimestampEquals" in choiceRule) {
1057
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1166
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1058
1167
  const timestampValue = new Date(choiceRule.TimestampEquals);
1059
1168
  return varValue.getTime() === timestampValue.getTime();
1060
1169
  }
1061
1170
  if ("TimestampEqualsPath" in choiceRule) {
1062
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1063
- const timestampValue = new Date(jsonPathQuery(choiceRule.TimestampEqualsPath, input));
1171
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1172
+ const timestampValue = new Date(
1173
+ jsonPathQuery(choiceRule.TimestampEqualsPath, input, context, {
1174
+ constraints: [RFC3339TimestampConstraint]
1175
+ })
1176
+ );
1064
1177
  return varValue.getTime() === timestampValue.getTime();
1065
1178
  }
1066
1179
  if ("TimestampLessThan" in choiceRule) {
1067
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1180
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1068
1181
  const timestampValue = new Date(choiceRule.TimestampLessThan);
1069
1182
  return varValue < timestampValue;
1070
1183
  }
1071
1184
  if ("TimestampLessThanPath" in choiceRule) {
1072
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1073
- const timestampValue = new Date(jsonPathQuery(choiceRule.TimestampLessThanPath, input));
1185
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1186
+ const timestampValue = new Date(
1187
+ jsonPathQuery(choiceRule.TimestampLessThanPath, input, context, {
1188
+ constraints: [RFC3339TimestampConstraint]
1189
+ })
1190
+ );
1074
1191
  return varValue < timestampValue;
1075
1192
  }
1076
1193
  if ("TimestampGreaterThan" in choiceRule) {
1077
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1194
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1078
1195
  const timestampValue = new Date(choiceRule.TimestampGreaterThan);
1079
1196
  return varValue > timestampValue;
1080
1197
  }
1081
1198
  if ("TimestampGreaterThanPath" in choiceRule) {
1082
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1083
- const timestampValue = new Date(jsonPathQuery(choiceRule.TimestampGreaterThanPath, input));
1199
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1200
+ const timestampValue = new Date(
1201
+ jsonPathQuery(choiceRule.TimestampGreaterThanPath, input, context, {
1202
+ constraints: [RFC3339TimestampConstraint]
1203
+ })
1204
+ );
1084
1205
  return varValue > timestampValue;
1085
1206
  }
1086
1207
  if ("TimestampLessThanEquals" in choiceRule) {
1087
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1208
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1088
1209
  const timestampValue = new Date(choiceRule.TimestampLessThanEquals);
1089
1210
  return varValue <= timestampValue;
1090
1211
  }
1091
1212
  if ("TimestampLessThanEqualsPath" in choiceRule) {
1092
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1093
- const timestampValue = new Date(jsonPathQuery(choiceRule.TimestampLessThanEqualsPath, input));
1213
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1214
+ const timestampValue = new Date(
1215
+ jsonPathQuery(choiceRule.TimestampLessThanEqualsPath, input, context, {
1216
+ constraints: [RFC3339TimestampConstraint]
1217
+ })
1218
+ );
1094
1219
  return varValue <= timestampValue;
1095
1220
  }
1096
1221
  if ("TimestampGreaterThanEquals" in choiceRule) {
1097
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1222
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1098
1223
  const timestampValue = new Date(choiceRule.TimestampGreaterThanEquals);
1099
1224
  return varValue >= timestampValue;
1100
1225
  }
1101
1226
  if ("TimestampGreaterThanEqualsPath" in choiceRule) {
1102
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1103
- const timestampValue = new Date(jsonPathQuery(choiceRule.TimestampGreaterThanEqualsPath, input));
1227
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1228
+ const timestampValue = new Date(
1229
+ jsonPathQuery(choiceRule.TimestampGreaterThanEqualsPath, input, context, {
1230
+ constraints: [RFC3339TimestampConstraint]
1231
+ })
1232
+ );
1104
1233
  return varValue >= timestampValue;
1105
1234
  }
1106
1235
  if ("IsNull" in choiceRule) {
1107
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1236
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1108
1237
  const isNullTrue = choiceRule.IsNull;
1109
1238
  return isNullTrue && varValue === null;
1110
1239
  }
1111
1240
  if ("IsPresent" in choiceRule) {
1112
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1241
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context, { ignoreDefinedValueConstraint: true });
1113
1242
  const IsPresentTrue = choiceRule.IsPresent;
1114
1243
  return IsPresentTrue && varValue !== void 0;
1115
1244
  }
1116
1245
  if ("IsNumeric" in choiceRule) {
1117
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1246
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1118
1247
  const IsNumericTrue = choiceRule.IsNumeric;
1119
1248
  return IsNumericTrue && typeof varValue === "number";
1120
1249
  }
1121
1250
  if ("IsString" in choiceRule) {
1122
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1251
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1123
1252
  const IsStringTrue = choiceRule.IsString;
1124
1253
  return IsStringTrue && typeof varValue === "string";
1125
1254
  }
1126
1255
  if ("IsBoolean" in choiceRule) {
1127
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1256
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1128
1257
  const IsBooleanTrue = choiceRule.IsBoolean;
1129
1258
  return IsBooleanTrue && typeof varValue === "boolean";
1130
1259
  }
1131
1260
  if ("IsTimestamp" in choiceRule) {
1132
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1261
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1133
1262
  const IsTimestampTrue = choiceRule.IsTimestamp;
1134
- return IsTimestampTrue && /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|(\+|-)\d{2}:\d{2})/.test(varValue);
1263
+ return IsTimestampTrue && isRFC3339Timestamp(varValue);
1135
1264
  }
1136
1265
  return false;
1137
1266
  }
1138
1267
  async execute(input, context, options) {
1139
1268
  const state = this.stateDefinition;
1140
1269
  for (const choice of state.Choices) {
1141
- const choiceIsMatch = this.testChoiceRule(choice, input);
1270
+ const choiceIsMatch = this.testChoiceRule(choice, input, context);
1142
1271
  if (choiceIsMatch) {
1143
1272
  return { stateResult: input, nextState: choice.Next, isEndState: false };
1144
1273
  }
@@ -1168,6 +1297,17 @@ var FailStateAction = class extends BaseStateAction {
1168
1297
  }
1169
1298
  };
1170
1299
 
1300
+ // src/stateMachine/jsonPath/constraints/ArrayConstraint.ts
1301
+ var ArrayConstraint = class extends BaseJSONPathConstraint {
1302
+ test(value) {
1303
+ if (!Array.isArray(value)) {
1304
+ throw new StatesRuntimeError(
1305
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(value)}, but expected an array`
1306
+ );
1307
+ }
1308
+ }
1309
+ };
1310
+
1171
1311
  // src/stateMachine/stateActions/MapStateAction.ts
1172
1312
  var import_p_limit = __toESM(require("p-limit"), 1);
1173
1313
  var DEFAULT_MAX_CONCURRENCY = 40;
@@ -1195,23 +1335,25 @@ var MapStateAction = class extends BaseStateAction {
1195
1335
  if (state.Parameters) {
1196
1336
  paramValue = processPayloadTemplate(state.Parameters, input, context);
1197
1337
  }
1198
- const execution = stateMachine.run(paramValue ?? item, options?.runOptions);
1338
+ const execution = stateMachine.run(paramValue ?? item, options.runOptions);
1199
1339
  this.executionAbortFuncs.push(execution.abort);
1200
- this.forwardEventsToRootEventLogger(options?.eventLogger, execution.eventLogs, index, options?.rawInput);
1340
+ this.forwardEventsToRootEventLogger(options.eventLogger, execution.eventLogs, index, options.rawInput);
1201
1341
  return execution.result;
1202
1342
  }
1203
1343
  async execute(input, context, options) {
1204
1344
  const state = this.stateDefinition;
1205
1345
  let items = input;
1206
1346
  if (state.ItemsPath) {
1207
- items = jsonPathQuery(state.ItemsPath, input, context);
1347
+ items = jsonPathQuery(state.ItemsPath, input, context, {
1348
+ constraints: [ArrayConstraint]
1349
+ });
1208
1350
  }
1209
1351
  if (!Array.isArray(items)) {
1210
1352
  throw new StatesRuntimeError("Input of Map state must be an array or ItemsPath property must point to an array");
1211
1353
  }
1212
1354
  const iteratorStateMachine = new StateMachine(state.Iterator, {
1213
- ...options?.stateMachineOptions,
1214
- validationOptions: { _noValidate: true }
1355
+ ...options.stateMachineOptions,
1356
+ validationOptions: { noValidate: true }
1215
1357
  });
1216
1358
  const limit = (0, import_p_limit.default)(state.MaxConcurrency || DEFAULT_MAX_CONCURRENCY);
1217
1359
  const processedItemsPromise = items.map(
@@ -1223,7 +1365,7 @@ var MapStateAction = class extends BaseStateAction {
1223
1365
  } catch (error) {
1224
1366
  this.executionAbortFuncs.forEach((abort) => abort());
1225
1367
  if (error instanceof ExecutionError) {
1226
- throw error.getWrappedError;
1368
+ throw error.cause;
1227
1369
  }
1228
1370
  throw error;
1229
1371
  } finally {
@@ -1249,12 +1391,12 @@ var ParallelStateAction = class extends BaseStateAction {
1249
1391
  }
1250
1392
  processBranch(branch, input, context, options) {
1251
1393
  const stateMachine = new StateMachine(branch, {
1252
- ...options?.stateMachineOptions,
1253
- validationOptions: { _noValidate: true }
1394
+ ...options.stateMachineOptions,
1395
+ validationOptions: { noValidate: true }
1254
1396
  });
1255
- const execution = stateMachine.run(input, options?.runOptions);
1397
+ const execution = stateMachine.run(input, options.runOptions);
1256
1398
  this.executionAbortFuncs.push(execution.abort);
1257
- this.forwardEventsToRootEventLogger(options?.eventLogger, execution.eventLogs, options?.rawInput);
1399
+ this.forwardEventsToRootEventLogger(options.eventLogger, execution.eventLogs, options.rawInput);
1258
1400
  return execution.result;
1259
1401
  }
1260
1402
  async execute(input, context, options) {
@@ -1269,7 +1411,7 @@ var ParallelStateAction = class extends BaseStateAction {
1269
1411
  } catch (error) {
1270
1412
  this.executionAbortFuncs.forEach((abort) => abort());
1271
1413
  if (error instanceof ExecutionError) {
1272
- throw error.getWrappedError;
1414
+ throw error.cause;
1273
1415
  }
1274
1416
  throw error;
1275
1417
  }
@@ -1302,13 +1444,28 @@ var SucceedStateAction = class extends BaseStateAction {
1302
1444
  // src/aws/LambdaClient.ts
1303
1445
  var import_client_lambda = require("@aws-sdk/client-lambda");
1304
1446
  var import_credential_providers = require("@aws-sdk/credential-providers");
1447
+
1448
+ // src/error/LambdaInvocationError.ts
1449
+ var LambdaInvocationError = class extends RuntimeError {
1450
+ constructor(name, message, cause) {
1451
+ super(message, cause);
1452
+ this.name = name;
1453
+ }
1454
+ };
1455
+
1456
+ // src/aws/LambdaClient.ts
1305
1457
  var LambdaClient = class {
1306
1458
  constructor(config) {
1307
1459
  this.client = new import_client_lambda.LambdaClient({});
1308
1460
  if (config) {
1309
1461
  if (!config.region) {
1310
1462
  throw new StatesRuntimeError(
1311
- "'awsConfig' option was specified for state machine, but 'region' property is not set"
1463
+ "'awsConfig' option was specified in state machine constructor, but 'region' property is not set."
1464
+ );
1465
+ }
1466
+ if (!config.credentials) {
1467
+ throw new StatesRuntimeError(
1468
+ "'awsConfig' option was specified in state machine constructor, but 'credentials' property is not set."
1312
1469
  );
1313
1470
  }
1314
1471
  if (config.credentials) {
@@ -1331,6 +1488,12 @@ var LambdaClient = class {
1331
1488
  } else if (config.credentials?.accessKeys) {
1332
1489
  this.client = new import_client_lambda.LambdaClient({ region: config.region, credentials: config.credentials.accessKeys });
1333
1490
  }
1491
+ } else {
1492
+ if (isBrowserEnvironment) {
1493
+ throw new StatesRuntimeError(
1494
+ "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."
1495
+ );
1496
+ }
1334
1497
  }
1335
1498
  }
1336
1499
  async invokeFunction(funcNameOrArn, payload) {
@@ -1347,7 +1510,11 @@ var LambdaClient = class {
1347
1510
  }
1348
1511
  if (invocationResult.FunctionError) {
1349
1512
  const errorResult = resultValue;
1350
- throw new FailStateError(errorResult.errorType, `Execution of Lambda function '${funcNameOrArn}' failed`);
1513
+ throw new LambdaInvocationError(
1514
+ errorResult.errorType,
1515
+ `${errorResult.errorType}: ${errorResult.errorMessage}`,
1516
+ errorResult
1517
+ );
1351
1518
  }
1352
1519
  return resultValue;
1353
1520
  }
@@ -1360,16 +1527,41 @@ var TaskStateAction = class extends BaseStateAction {
1360
1527
  }
1361
1528
  async execute(input, context, options) {
1362
1529
  const state = this.stateDefinition;
1363
- if (options?.overrideFn) {
1530
+ if (options.overrideFn) {
1364
1531
  const result2 = await options.overrideFn(input);
1365
1532
  return this.buildExecutionResult(result2);
1366
1533
  }
1367
- const lambdaClient = new LambdaClient(options?.awsConfig);
1534
+ const lambdaClient = new LambdaClient(options.awsConfig);
1368
1535
  const result = await lambdaClient.invokeFunction(state.Resource, input);
1369
1536
  return this.buildExecutionResult(result);
1370
1537
  }
1371
1538
  };
1372
1539
 
1540
+ // src/stateMachine/jsonPath/constraints/IntegerConstraint.ts
1541
+ var IntegerConstraint = class extends BaseJSONPathConstraint {
1542
+ test(value) {
1543
+ if (!Number.isInteger(value)) {
1544
+ throw new StatesRuntimeError(
1545
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(value)}, but expected an integer`
1546
+ );
1547
+ }
1548
+ }
1549
+ static greaterThanOrEqual(n) {
1550
+ return class extends this {
1551
+ test(value) {
1552
+ super.test(value);
1553
+ if (value < n) {
1554
+ throw new StatesRuntimeError(
1555
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(
1556
+ value
1557
+ )}, but expected an integer >= ${n}`
1558
+ );
1559
+ }
1560
+ }
1561
+ };
1562
+ }
1563
+ };
1564
+
1373
1565
  // src/stateMachine/stateActions/WaitStateAction.ts
1374
1566
  var WaitStateAction = class extends BaseStateAction {
1375
1567
  constructor(stateDefinition, stateName) {
@@ -1377,26 +1569,30 @@ var WaitStateAction = class extends BaseStateAction {
1377
1569
  }
1378
1570
  async execute(input, context, options) {
1379
1571
  const state = this.stateDefinition;
1380
- if (options?.waitTimeOverrideOption !== void 0) {
1381
- await sleep(options.waitTimeOverrideOption, options.abortSignal, options.rootAbortSignal);
1572
+ if (options.waitTimeOverrideOption !== void 0) {
1573
+ await sleep(options.waitTimeOverrideOption, options.abortSignal);
1382
1574
  return this.buildExecutionResult(input);
1383
1575
  }
1384
1576
  if (state.Seconds) {
1385
- await sleep(state.Seconds * 1e3, options?.abortSignal, options?.rootAbortSignal);
1577
+ await sleep(state.Seconds * 1e3, options.abortSignal);
1386
1578
  } else if (state.Timestamp) {
1387
1579
  const dateTimestamp = new Date(state.Timestamp);
1388
1580
  const currentTime = Date.now();
1389
1581
  const timeDiff = dateTimestamp.getTime() - currentTime;
1390
- await sleep(timeDiff, options?.abortSignal, options?.rootAbortSignal);
1582
+ await sleep(timeDiff, options.abortSignal);
1391
1583
  } else if (state.SecondsPath) {
1392
- const seconds = jsonPathQuery(state.SecondsPath, input, context);
1393
- await sleep(seconds * 1e3, options?.abortSignal, options?.rootAbortSignal);
1584
+ const seconds = jsonPathQuery(state.SecondsPath, input, context, {
1585
+ constraints: [IntegerConstraint.greaterThanOrEqual(0)]
1586
+ });
1587
+ await sleep(seconds * 1e3, options.abortSignal);
1394
1588
  } else if (state.TimestampPath) {
1395
- const timestamp = jsonPathQuery(state.TimestampPath, input, context);
1589
+ const timestamp = jsonPathQuery(state.TimestampPath, input, context, {
1590
+ constraints: [RFC3339TimestampConstraint]
1591
+ });
1396
1592
  const dateTimestamp = new Date(timestamp);
1397
1593
  const currentTime = Date.now();
1398
1594
  const timeDiff = dateTimestamp.getTime() - currentTime;
1399
- await sleep(timeDiff, options?.abortSignal, options?.rootAbortSignal);
1595
+ await sleep(timeDiff, options.abortSignal);
1400
1596
  }
1401
1597
  return this.buildExecutionResult(input);
1402
1598
  }
@@ -1456,13 +1652,34 @@ var StateExecutor = class {
1456
1652
  const processedResult = this.processResult(currResult, rawInput, context);
1457
1653
  return { stateResult: processedResult, nextState, isEndState };
1458
1654
  } catch (error) {
1459
- const { shouldRetry, waitTimeBeforeRetry } = this.shouldRetry(error);
1460
- if (shouldRetry && waitTimeBeforeRetry) {
1461
- await sleep(waitTimeBeforeRetry, options.abortSignal, options.runOptions?._rootAbortSignal);
1655
+ options.eventLogger.dispatchStateFailedEvent(
1656
+ this.stateName,
1657
+ this.stateDefinition.Type,
1658
+ input,
1659
+ error
1660
+ );
1661
+ const { shouldRetry, waitTimeBeforeRetry, retrierIndex } = this.shouldRetry(error);
1662
+ if (shouldRetry) {
1663
+ const stateDefinition = this.stateDefinition;
1664
+ await sleep(waitTimeBeforeRetry, options.abortSignal);
1665
+ options.eventLogger.dispatchStateRetriedEvent(
1666
+ this.stateName,
1667
+ stateDefinition.Type,
1668
+ input,
1669
+ stateDefinition.Retry[retrierIndex],
1670
+ this.retrierAttempts[retrierIndex]
1671
+ );
1462
1672
  return this.execute(input, context, options);
1463
1673
  }
1464
- const { nextState, errorOutput, resultPath } = this.catchError(error);
1674
+ const { nextState, errorOutput, resultPath, catcherIndex } = this.catchError(error);
1465
1675
  if (nextState && errorOutput) {
1676
+ const stateDefinition = this.stateDefinition;
1677
+ options.eventLogger.dispatchStateCaughtEvent(
1678
+ this.stateName,
1679
+ stateDefinition.Type,
1680
+ input,
1681
+ stateDefinition.Catch[catcherIndex]
1682
+ );
1466
1683
  return { stateResult: processResultPath(resultPath, rawInput, errorOutput), nextState, isEndState: false };
1467
1684
  }
1468
1685
  throw error;
@@ -1520,7 +1737,7 @@ var StateExecutor = class {
1520
1737
  if (this.retrierAttempts[i] >= maxAttempts)
1521
1738
  return { shouldRetry: false };
1522
1739
  this.retrierAttempts[i]++;
1523
- return { shouldRetry: true, waitTimeBeforeRetry };
1740
+ return { shouldRetry: true, waitTimeBeforeRetry, retrierIndex: i };
1524
1741
  }
1525
1742
  }
1526
1743
  }
@@ -1548,7 +1765,7 @@ var StateExecutor = class {
1548
1765
  Cause: error.message
1549
1766
  };
1550
1767
  const resultPath = catcher.ResultPath;
1551
- return { nextState, errorOutput, resultPath };
1768
+ return { nextState, errorOutput, resultPath, catcherIndex: i };
1552
1769
  }
1553
1770
  }
1554
1771
  }
@@ -1622,8 +1839,7 @@ var StateExecutor = class {
1622
1839
  const waitStateAction = new WaitStateAction(stateDefinition, stateName);
1623
1840
  const executionResult = await waitStateAction.execute(input, context, {
1624
1841
  waitTimeOverrideOption,
1625
- abortSignal: options.abortSignal,
1626
- rootAbortSignal: options.runOptions?._rootAbortSignal
1842
+ abortSignal: options.abortSignal
1627
1843
  });
1628
1844
  return executionResult;
1629
1845
  }
@@ -1708,6 +1924,9 @@ var EventLogger = class {
1708
1924
  break;
1709
1925
  case "StateEntered":
1710
1926
  case "StateExited":
1927
+ case "StateFailed":
1928
+ case "StateRetried":
1929
+ case "StateCaught":
1711
1930
  event.index = index;
1712
1931
  this.dispatch(event);
1713
1932
  break;
@@ -1752,7 +1971,12 @@ var EventLogger = class {
1752
1971
  this.close();
1753
1972
  }
1754
1973
  dispatchExecutionFailedEvent(error) {
1755
- this.dispatch({ type: "ExecutionFailed", timestamp: Date.now(), Error: error.name, Cause: error.message });
1974
+ this.dispatch({
1975
+ type: "ExecutionFailed",
1976
+ timestamp: Date.now(),
1977
+ Error: error.name,
1978
+ Cause: error.cause ?? error.message
1979
+ });
1756
1980
  this.close();
1757
1981
  }
1758
1982
  dispatchExecutionAbortedEvent() {
@@ -1777,6 +2001,31 @@ var EventLogger = class {
1777
2001
  state: { name: stateName, type: stateType, input, output }
1778
2002
  });
1779
2003
  }
2004
+ dispatchStateFailedEvent(stateName, stateType, input, error) {
2005
+ this.dispatch({
2006
+ type: "StateFailed",
2007
+ timestamp: Date.now(),
2008
+ state: { name: stateName, type: stateType, input },
2009
+ Error: error.name,
2010
+ Cause: error.cause ?? error.message
2011
+ });
2012
+ }
2013
+ dispatchStateRetriedEvent(stateName, stateType, input, retrier, retryAttempt) {
2014
+ this.dispatch({
2015
+ type: "StateRetried",
2016
+ timestamp: Date.now(),
2017
+ state: { name: stateName, type: stateType, input },
2018
+ retry: { retrier, attempt: retryAttempt }
2019
+ });
2020
+ }
2021
+ dispatchStateCaughtEvent(stateName, stateType, input, catcher) {
2022
+ this.dispatch({
2023
+ type: "StateCaught",
2024
+ timestamp: Date.now(),
2025
+ state: { name: stateName, type: stateType, input },
2026
+ catch: { catcher }
2027
+ });
2028
+ }
1780
2029
  dispatchMapIterationStartedEvent(event, index, mapStateName, mapStateRawInput) {
1781
2030
  this.dispatch({
1782
2031
  ...event,
@@ -1852,7 +2101,7 @@ var StateMachine = class {
1852
2101
  * These options also apply to state machines defined in the `Iterator` field of `Map` states and in the `Branches` field of `Parallel` states.
1853
2102
  */
1854
2103
  constructor(definition, stateMachineOptions) {
1855
- if (!stateMachineOptions?.validationOptions?._noValidate) {
2104
+ if (!stateMachineOptions?.validationOptions?.noValidate) {
1856
2105
  const { isValid, errorsText } = (0, import_asl_validator.default)(definition, {
1857
2106
  checkArn: true,
1858
2107
  checkPaths: true,
@@ -1883,6 +2132,15 @@ var StateMachine = class {
1883
2132
  run(input, options) {
1884
2133
  const abortController = new AbortController();
1885
2134
  const eventLogger = new EventLogger();
2135
+ let rootSignalAbortHandler;
2136
+ if (options?._rootAbortSignal) {
2137
+ rootSignalAbortHandler = () => abortController.abort();
2138
+ if (options._rootAbortSignal.aborted) {
2139
+ rootSignalAbortHandler();
2140
+ } else {
2141
+ options._rootAbortSignal.addEventListener("abort", rootSignalAbortHandler);
2142
+ }
2143
+ }
1886
2144
  let onAbortHandler;
1887
2145
  const settleOnAbort = new Promise((resolve, reject) => {
1888
2146
  if (options?.noThrowOnAbort) {
@@ -1920,6 +2178,7 @@ var StateMachine = class {
1920
2178
  },
1921
2179
  () => {
1922
2180
  abortController.signal.removeEventListener("abort", onAbortHandler);
2181
+ options?._rootAbortSignal?.removeEventListener("abort", rootSignalAbortHandler);
1923
2182
  clearTimeout(timeoutId);
1924
2183
  }
1925
2184
  );