aws-local-stepfunctions 1.2.0 → 1.3.1
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.
- package/README.md +60 -1
- package/bin/CLI.cjs +18 -3
- package/build/main.browser.esm.js +526 -331
- package/build/main.d.ts +20 -4
- package/build/main.node.cjs +36 -6
- package/build/main.node.esm.js +36 -6
- package/package.json +7 -7
package/build/main.d.ts
CHANGED
|
@@ -15,15 +15,15 @@ type JSONObject = {
|
|
|
15
15
|
};
|
|
16
16
|
type JSONValue = JSONPrimitiveValue | JSONObject | JSONArray;
|
|
17
17
|
|
|
18
|
-
type PayloadTemplate = JSONObject;
|
|
18
|
+
type PayloadTemplate = JSONObject | JSONArray;
|
|
19
19
|
interface CanHaveInputPath {
|
|
20
20
|
InputPath?: string | null;
|
|
21
21
|
}
|
|
22
22
|
interface CanHaveParameters {
|
|
23
|
-
Parameters?:
|
|
23
|
+
Parameters?: JSONValue;
|
|
24
24
|
}
|
|
25
25
|
interface CanHaveResultSelector {
|
|
26
|
-
ResultSelector?:
|
|
26
|
+
ResultSelector?: JSONValue;
|
|
27
27
|
}
|
|
28
28
|
interface CanHaveResultPath {
|
|
29
29
|
ResultPath?: string | null;
|
|
@@ -189,7 +189,15 @@ interface StateMachineDefinition {
|
|
|
189
189
|
TimeoutSeconds?: number;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
type
|
|
192
|
+
type ContextExecution = {
|
|
193
|
+
Input?: JSONValue;
|
|
194
|
+
StartTime?: string;
|
|
195
|
+
[other: string]: unknown;
|
|
196
|
+
};
|
|
197
|
+
type Context = {
|
|
198
|
+
Execution?: ContextExecution;
|
|
199
|
+
[other: string]: unknown;
|
|
200
|
+
};
|
|
193
201
|
|
|
194
202
|
declare class ErrorWithCause extends Error {
|
|
195
203
|
#private;
|
|
@@ -332,6 +340,9 @@ type TaskStateResourceLocalHandler = {
|
|
|
332
340
|
type WaitStateTimeOverride = {
|
|
333
341
|
[waitStateName: string]: number;
|
|
334
342
|
};
|
|
343
|
+
type RetryIntervalOverrides = {
|
|
344
|
+
[retryableStateName: string]: number | number[];
|
|
345
|
+
};
|
|
335
346
|
interface Overrides {
|
|
336
347
|
/**
|
|
337
348
|
* Pass an object to this option to override a `Task` state to run a local function,
|
|
@@ -343,6 +354,11 @@ interface Overrides {
|
|
|
343
354
|
* instead of pausing for the duration specified by the `Seconds`, `Timestamp`, `SecondsPath`, or `TimestampPath` fields.
|
|
344
355
|
*/
|
|
345
356
|
waitTimeOverrides?: WaitStateTimeOverride;
|
|
357
|
+
/**
|
|
358
|
+
* Pass an object to this option to override the duration in milliseconds a retrier in a `Retry` field waits before retrying the state,
|
|
359
|
+
* instead of pausing for the duration calculated by the `IntervalSeconds`, `BackoffRate`, `MaxDelaySeconds`, and `JitterStrategy` fields.
|
|
360
|
+
*/
|
|
361
|
+
retryIntervalOverrides?: RetryIntervalOverrides;
|
|
346
362
|
}
|
|
347
363
|
interface ValidationOptions {
|
|
348
364
|
/**
|
package/build/main.node.cjs
CHANGED
|
@@ -135,6 +135,8 @@ function isPlainObj(value) {
|
|
|
135
135
|
return !!value && Object.getPrototypeOf(value) === Object.prototype;
|
|
136
136
|
}
|
|
137
137
|
function sleep(ms, abortSignal) {
|
|
138
|
+
if (ms === 0)
|
|
139
|
+
return;
|
|
138
140
|
return new Promise((resolve) => {
|
|
139
141
|
if (abortSignal?.aborted) {
|
|
140
142
|
return resolve();
|
|
@@ -913,9 +915,18 @@ function processInputPath(path, input, context) {
|
|
|
913
915
|
return jsonPathQuery(path, input, context);
|
|
914
916
|
}
|
|
915
917
|
function processPayloadTemplate(payloadTemplate, json, context) {
|
|
918
|
+
if (typeof payloadTemplate !== "object" || payloadTemplate === null) {
|
|
919
|
+
return payloadTemplate;
|
|
920
|
+
}
|
|
921
|
+
if (Array.isArray(payloadTemplate)) {
|
|
922
|
+
return payloadTemplate.map((value) => processPayloadTemplate(value, json, context));
|
|
923
|
+
}
|
|
916
924
|
const resolvedProperties = Object.entries(payloadTemplate).map(([key, value]) => {
|
|
917
925
|
let sanitizedKey = key;
|
|
918
926
|
let resolvedValue = value;
|
|
927
|
+
if (Array.isArray(value)) {
|
|
928
|
+
resolvedValue = value.map((innerValue) => processPayloadTemplate(innerValue, json, context));
|
|
929
|
+
}
|
|
919
930
|
if (isPlainObj(value)) {
|
|
920
931
|
resolvedValue = processPayloadTemplate(value, json, context);
|
|
921
932
|
}
|
|
@@ -1719,7 +1730,10 @@ var StateExecutor = class {
|
|
|
1719
1730
|
input,
|
|
1720
1731
|
error
|
|
1721
1732
|
);
|
|
1722
|
-
const { shouldRetry, waitTimeBeforeRetry, retrierIndex } = this.shouldRetry(
|
|
1733
|
+
const { shouldRetry, waitTimeBeforeRetry, retrierIndex } = this.shouldRetry(
|
|
1734
|
+
error,
|
|
1735
|
+
options.runOptions?.overrides?.retryIntervalOverrides
|
|
1736
|
+
);
|
|
1723
1737
|
if (shouldRetry) {
|
|
1724
1738
|
const stateDefinition = this.stateDefinition;
|
|
1725
1739
|
await sleep(waitTimeBeforeRetry, options.abortSignal);
|
|
@@ -1778,20 +1792,29 @@ var StateExecutor = class {
|
|
|
1778
1792
|
/**
|
|
1779
1793
|
* Decide whether this state should be retried, according to the `Retry` field.
|
|
1780
1794
|
*/
|
|
1781
|
-
shouldRetry(error) {
|
|
1795
|
+
shouldRetry(error, retryIntervalOverrides) {
|
|
1782
1796
|
if (!("Retry" in this.stateDefinition)) {
|
|
1783
1797
|
return { shouldRetry: false };
|
|
1784
1798
|
}
|
|
1785
1799
|
for (let i = 0; i < this.stateDefinition.Retry.length; i++) {
|
|
1786
1800
|
const retrier = this.stateDefinition.Retry[i];
|
|
1801
|
+
let intervalOverride = null;
|
|
1802
|
+
if (retryIntervalOverrides?.[this.stateName] !== void 0) {
|
|
1803
|
+
const override = retryIntervalOverrides[this.stateName];
|
|
1804
|
+
if (typeof override === "number") {
|
|
1805
|
+
intervalOverride = override / 1e3;
|
|
1806
|
+
} else if (override[i] !== void 0 && override[i] >= 0) {
|
|
1807
|
+
intervalOverride = override[i] / 1e3;
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1787
1810
|
const jitterStrategy = retrier.JitterStrategy ?? DEFAULT_JITTER_STRATEGY;
|
|
1788
1811
|
const maxAttempts = retrier.MaxAttempts ?? DEFAULT_MAX_ATTEMPTS;
|
|
1789
1812
|
const intervalSeconds = retrier.IntervalSeconds ?? DEFAULT_INTERVAL_SECONDS;
|
|
1790
1813
|
const backoffRate = retrier.BackoffRate ?? DEFAULT_BACKOFF_RATE;
|
|
1791
|
-
const waitInterval = intervalSeconds * Math.pow(backoffRate, this.retrierAttempts[i]);
|
|
1814
|
+
const waitInterval = intervalOverride ?? intervalSeconds * Math.pow(backoffRate, this.retrierAttempts[i]);
|
|
1792
1815
|
const retryable = error.isRetryable ?? true;
|
|
1793
|
-
let waitTimeBeforeRetry = clamp(waitInterval,
|
|
1794
|
-
if (jitterStrategy === "FULL") {
|
|
1816
|
+
let waitTimeBeforeRetry = clamp(waitInterval, 0, retrier.MaxDelaySeconds) * 1e3;
|
|
1817
|
+
if (jitterStrategy === "FULL" && intervalOverride === null) {
|
|
1795
1818
|
waitTimeBeforeRetry = getRandomNumber(0, waitTimeBeforeRetry);
|
|
1796
1819
|
}
|
|
1797
1820
|
for (const retrierError of retrier.ErrorEquals) {
|
|
@@ -2264,7 +2287,14 @@ var StateMachine = class {
|
|
|
2264
2287
|
*/
|
|
2265
2288
|
async execute(input, options, cleanupFn) {
|
|
2266
2289
|
options.eventLogger.dispatchExecutionStartedEvent(input);
|
|
2267
|
-
const context =
|
|
2290
|
+
const context = {
|
|
2291
|
+
...options.runOptions?.context,
|
|
2292
|
+
Execution: {
|
|
2293
|
+
...options.runOptions?.context?.Execution,
|
|
2294
|
+
Input: input,
|
|
2295
|
+
StartTime: (/* @__PURE__ */ new Date()).toISOString()
|
|
2296
|
+
}
|
|
2297
|
+
};
|
|
2268
2298
|
let currState = this.definition.States[this.definition.StartAt];
|
|
2269
2299
|
let currStateName = this.definition.StartAt;
|
|
2270
2300
|
let currInput = (0, import_cloneDeep3.default)(input);
|
package/build/main.node.esm.js
CHANGED
|
@@ -97,6 +97,8 @@ function isPlainObj(value) {
|
|
|
97
97
|
return !!value && Object.getPrototypeOf(value) === Object.prototype;
|
|
98
98
|
}
|
|
99
99
|
function sleep(ms, abortSignal) {
|
|
100
|
+
if (ms === 0)
|
|
101
|
+
return;
|
|
100
102
|
return new Promise((resolve) => {
|
|
101
103
|
if (abortSignal?.aborted) {
|
|
102
104
|
return resolve();
|
|
@@ -875,9 +877,18 @@ function processInputPath(path, input, context) {
|
|
|
875
877
|
return jsonPathQuery(path, input, context);
|
|
876
878
|
}
|
|
877
879
|
function processPayloadTemplate(payloadTemplate, json, context) {
|
|
880
|
+
if (typeof payloadTemplate !== "object" || payloadTemplate === null) {
|
|
881
|
+
return payloadTemplate;
|
|
882
|
+
}
|
|
883
|
+
if (Array.isArray(payloadTemplate)) {
|
|
884
|
+
return payloadTemplate.map((value) => processPayloadTemplate(value, json, context));
|
|
885
|
+
}
|
|
878
886
|
const resolvedProperties = Object.entries(payloadTemplate).map(([key, value]) => {
|
|
879
887
|
let sanitizedKey = key;
|
|
880
888
|
let resolvedValue = value;
|
|
889
|
+
if (Array.isArray(value)) {
|
|
890
|
+
resolvedValue = value.map((innerValue) => processPayloadTemplate(innerValue, json, context));
|
|
891
|
+
}
|
|
881
892
|
if (isPlainObj(value)) {
|
|
882
893
|
resolvedValue = processPayloadTemplate(value, json, context);
|
|
883
894
|
}
|
|
@@ -1681,7 +1692,10 @@ var StateExecutor = class {
|
|
|
1681
1692
|
input,
|
|
1682
1693
|
error
|
|
1683
1694
|
);
|
|
1684
|
-
const { shouldRetry, waitTimeBeforeRetry, retrierIndex } = this.shouldRetry(
|
|
1695
|
+
const { shouldRetry, waitTimeBeforeRetry, retrierIndex } = this.shouldRetry(
|
|
1696
|
+
error,
|
|
1697
|
+
options.runOptions?.overrides?.retryIntervalOverrides
|
|
1698
|
+
);
|
|
1685
1699
|
if (shouldRetry) {
|
|
1686
1700
|
const stateDefinition = this.stateDefinition;
|
|
1687
1701
|
await sleep(waitTimeBeforeRetry, options.abortSignal);
|
|
@@ -1740,20 +1754,29 @@ var StateExecutor = class {
|
|
|
1740
1754
|
/**
|
|
1741
1755
|
* Decide whether this state should be retried, according to the `Retry` field.
|
|
1742
1756
|
*/
|
|
1743
|
-
shouldRetry(error) {
|
|
1757
|
+
shouldRetry(error, retryIntervalOverrides) {
|
|
1744
1758
|
if (!("Retry" in this.stateDefinition)) {
|
|
1745
1759
|
return { shouldRetry: false };
|
|
1746
1760
|
}
|
|
1747
1761
|
for (let i = 0; i < this.stateDefinition.Retry.length; i++) {
|
|
1748
1762
|
const retrier = this.stateDefinition.Retry[i];
|
|
1763
|
+
let intervalOverride = null;
|
|
1764
|
+
if (retryIntervalOverrides?.[this.stateName] !== void 0) {
|
|
1765
|
+
const override = retryIntervalOverrides[this.stateName];
|
|
1766
|
+
if (typeof override === "number") {
|
|
1767
|
+
intervalOverride = override / 1e3;
|
|
1768
|
+
} else if (override[i] !== void 0 && override[i] >= 0) {
|
|
1769
|
+
intervalOverride = override[i] / 1e3;
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1749
1772
|
const jitterStrategy = retrier.JitterStrategy ?? DEFAULT_JITTER_STRATEGY;
|
|
1750
1773
|
const maxAttempts = retrier.MaxAttempts ?? DEFAULT_MAX_ATTEMPTS;
|
|
1751
1774
|
const intervalSeconds = retrier.IntervalSeconds ?? DEFAULT_INTERVAL_SECONDS;
|
|
1752
1775
|
const backoffRate = retrier.BackoffRate ?? DEFAULT_BACKOFF_RATE;
|
|
1753
|
-
const waitInterval = intervalSeconds * Math.pow(backoffRate, this.retrierAttempts[i]);
|
|
1776
|
+
const waitInterval = intervalOverride ?? intervalSeconds * Math.pow(backoffRate, this.retrierAttempts[i]);
|
|
1754
1777
|
const retryable = error.isRetryable ?? true;
|
|
1755
|
-
let waitTimeBeforeRetry = clamp(waitInterval,
|
|
1756
|
-
if (jitterStrategy === "FULL") {
|
|
1778
|
+
let waitTimeBeforeRetry = clamp(waitInterval, 0, retrier.MaxDelaySeconds) * 1e3;
|
|
1779
|
+
if (jitterStrategy === "FULL" && intervalOverride === null) {
|
|
1757
1780
|
waitTimeBeforeRetry = getRandomNumber(0, waitTimeBeforeRetry);
|
|
1758
1781
|
}
|
|
1759
1782
|
for (const retrierError of retrier.ErrorEquals) {
|
|
@@ -2226,7 +2249,14 @@ var StateMachine = class {
|
|
|
2226
2249
|
*/
|
|
2227
2250
|
async execute(input, options, cleanupFn) {
|
|
2228
2251
|
options.eventLogger.dispatchExecutionStartedEvent(input);
|
|
2229
|
-
const context =
|
|
2252
|
+
const context = {
|
|
2253
|
+
...options.runOptions?.context,
|
|
2254
|
+
Execution: {
|
|
2255
|
+
...options.runOptions?.context?.Execution,
|
|
2256
|
+
Input: input,
|
|
2257
|
+
StartTime: (/* @__PURE__ */ new Date()).toISOString()
|
|
2258
|
+
}
|
|
2259
|
+
};
|
|
2230
2260
|
let currState = this.definition.States[this.definition.StartAt];
|
|
2231
2261
|
let currStateName = this.definition.StartAt;
|
|
2232
2262
|
let currInput = cloneDeep3(input);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aws-local-stepfunctions",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Execute an AWS Step Function state machine locally",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"aws",
|
|
@@ -54,13 +54,13 @@
|
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@tsconfig/node16-strictest": "^1.0.4",
|
|
56
56
|
"@types/crypto-js": "^4.2.1",
|
|
57
|
-
"@types/jest": "^29.5.
|
|
58
|
-
"@types/lodash": "^4.14.
|
|
59
|
-
"@types/node": "^18.
|
|
57
|
+
"@types/jest": "^29.5.11",
|
|
58
|
+
"@types/lodash": "^4.14.202",
|
|
59
|
+
"@types/node": "^18.19.3",
|
|
60
60
|
"@types/picomatch": "^2.3.3",
|
|
61
61
|
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
|
62
62
|
"@typescript-eslint/parser": "^5.62.0",
|
|
63
|
-
"eslint": "^8.
|
|
63
|
+
"eslint": "^8.56.0",
|
|
64
64
|
"eslint-config-prettier": "^8.10.0",
|
|
65
65
|
"eslint-plugin-prettier": "^4.2.1",
|
|
66
66
|
"prettier": "^2.8.8",
|
|
@@ -69,8 +69,8 @@
|
|
|
69
69
|
"typescript": "^4.9.5"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@aws-sdk/client-lambda": "^3.
|
|
73
|
-
"@aws-sdk/credential-providers": "^3.
|
|
72
|
+
"@aws-sdk/client-lambda": "^3.481.0",
|
|
73
|
+
"@aws-sdk/credential-providers": "^3.481.0",
|
|
74
74
|
"asl-validator": "^3.8.2",
|
|
75
75
|
"commander": "^11.1.0",
|
|
76
76
|
"crypto-js": "^4.2.0",
|