aws-local-stepfunctions 0.1.0 → 0.3.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.
- package/README.md +210 -0
- package/build/main.cjs +3 -3
- package/build/main.d.ts +39 -77
- package/build/main.esm.js +3 -3
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -2,6 +2,216 @@
|
|
|
2
2
|
|
|
3
3
|
A Node.js implementation of the [Amazon States Language specification](https://states-language.net/spec.html).
|
|
4
4
|
|
|
5
|
+
This package lets you run AWS Step Functions locally on your machine!
|
|
6
|
+
|
|
7
|
+
> NOTE: This is a work in progress. Some features defined in the specification might not be supported at all yet or might have limited support.
|
|
8
|
+
|
|
9
|
+
## Table of Contents
|
|
10
|
+
|
|
11
|
+
- [Features](#features)
|
|
12
|
+
- [Installation](#installation)
|
|
13
|
+
- [Importing](#importing)
|
|
14
|
+
- [Node.js](#nodejs)
|
|
15
|
+
- [CommonJS](#commonjs)
|
|
16
|
+
- [ES Module](#es-module)
|
|
17
|
+
- [API](#api)
|
|
18
|
+
- [Constructor](#constructor-new-statemachinedefinition-validationoptions)
|
|
19
|
+
- [StateMachine.run](#statemachineruninput-options)
|
|
20
|
+
- [License](#license)
|
|
21
|
+
|
|
22
|
+
## Features
|
|
23
|
+
|
|
24
|
+
To see a list of features that have full support, partial support, or no support, refer to [this document](/docs/feature-support.md).
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
npm install aws-local-stepfunctions
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Importing
|
|
33
|
+
|
|
34
|
+
Currently, the only supported environment to import the package is Node.js. Browser support is not available yet.
|
|
35
|
+
|
|
36
|
+
### Node.js
|
|
37
|
+
|
|
38
|
+
#### CommonJS
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
const { StateMachine } = require('aws-local-stepfunctions');
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
#### ES Module
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
import { StateMachine } from 'aws-local-stepfunctions';
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## API
|
|
51
|
+
|
|
52
|
+
### Constructor: `new StateMachine(definition[, validationOptions])`
|
|
53
|
+
|
|
54
|
+
#### Parameters
|
|
55
|
+
|
|
56
|
+
The constructor takes the following parameters:
|
|
57
|
+
|
|
58
|
+
- `definition`: The Amazon States Language definition of the state machine.
|
|
59
|
+
- `validationOptions` (optional): An object that specifies how the definition should be validated.
|
|
60
|
+
- `checkPaths`: If set to `false`, won't validate JSONPaths.
|
|
61
|
+
- `checkArn`: If set to `false`, won't validate ARN syntax in `Task` states.
|
|
62
|
+
|
|
63
|
+
The constructor will attempt to validate the definition by default, unless the `validationOptions` param is specified. If the definition is not valid, an error will be thrown.
|
|
64
|
+
|
|
65
|
+
#### Example
|
|
66
|
+
|
|
67
|
+
```js
|
|
68
|
+
import { StateMachine } from 'aws-local-stepfunctions';
|
|
69
|
+
|
|
70
|
+
const machineDefinition = {
|
|
71
|
+
Comment: 'A simple minimal example of the States language',
|
|
72
|
+
StartAt: 'Hello World',
|
|
73
|
+
States: {
|
|
74
|
+
'Hello World': {
|
|
75
|
+
Type: 'Task',
|
|
76
|
+
Resource: 'arn:aws:lambda:us-east-1:123456789012:function:HelloWorld',
|
|
77
|
+
End: true,
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// Instantiate a new state machine with the given definition and don't validate JSONPaths.
|
|
83
|
+
const stateMachine = new StateMachine(machineDefinition, { checkPaths: false });
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### `StateMachine.run(input[, options])`
|
|
87
|
+
|
|
88
|
+
Runs the state machine with the given `input` parameter and returns an object with the following properties:
|
|
89
|
+
|
|
90
|
+
- `abort`: A function that takes no parameters and doesn't return any value. If called, aborts the execution and throws an `ExecutionAbortedError`, unless the `noThrowOnAbort` option is set.
|
|
91
|
+
- `result`: A `Promise` that resolves with the execution result once it finishes.
|
|
92
|
+
|
|
93
|
+
Each execution is independent of all others, meaning that you can concurrently call this method as many times as needed, without worrying about race conditions.
|
|
94
|
+
|
|
95
|
+
#### Parameters
|
|
96
|
+
|
|
97
|
+
- `input`: The initial input to pass to the state machine. This can be any valid JSON value.
|
|
98
|
+
- `options` (optional):
|
|
99
|
+
- `overrides`: An object to override the behavior of certain states:
|
|
100
|
+
- `taskResourceLocalHandlers`: Overrides the resource of the specified `Task` states to run a local function.
|
|
101
|
+
- `waitTimeOverrides`: Overrides the wait duration of the specified `Wait` states. The specifed override duration should be in milliseconds.
|
|
102
|
+
- `noThrowOnAbort`: If this option is set to `true`, aborting the execution will simply return `null` as result instead of throwing.
|
|
103
|
+
|
|
104
|
+
#### Examples
|
|
105
|
+
|
|
106
|
+
##### Example without `options`:
|
|
107
|
+
|
|
108
|
+
```js
|
|
109
|
+
import { StateMachine } from 'aws-local-stepfunctions';
|
|
110
|
+
|
|
111
|
+
const machineDefinition = {
|
|
112
|
+
StartAt: 'Hello World',
|
|
113
|
+
States: {
|
|
114
|
+
'Hello World': {
|
|
115
|
+
Type: 'Task',
|
|
116
|
+
Resource: 'arn:aws:lambda:us-east-1:123456789012:function:HelloWorld',
|
|
117
|
+
End: true,
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const stateMachine = new StateMachine(machineDefinition);
|
|
123
|
+
const myInput = { value1: 'hello', value2: 123, value3: true };
|
|
124
|
+
const execution = stateMachine.run(myInput); // execute the state machine
|
|
125
|
+
|
|
126
|
+
const result = await execution.result; // wait until the execution finishes to get the result
|
|
127
|
+
console.log(result); // log the result of the execution
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
##### Example with `options`:
|
|
131
|
+
|
|
132
|
+
```js
|
|
133
|
+
import { StateMachine } from 'aws-local-stepfunctions';
|
|
134
|
+
|
|
135
|
+
const machineDefinition = {
|
|
136
|
+
StartAt: 'Hello World',
|
|
137
|
+
States: {
|
|
138
|
+
'Hello World': {
|
|
139
|
+
Type: 'Task',
|
|
140
|
+
Resource: 'arn:aws:lambda:us-east-1:123456789012:function:HelloWorld',
|
|
141
|
+
Next: 'AddNumbers',
|
|
142
|
+
},
|
|
143
|
+
AddNumbers: {
|
|
144
|
+
Type: 'Task',
|
|
145
|
+
Resource: 'arn:aws:lambda:us-east-1:123456789012:function:AddNumbers',
|
|
146
|
+
Next: 'Wait10Seconds',
|
|
147
|
+
},
|
|
148
|
+
Wait10Seconds: {
|
|
149
|
+
Type: 'Wait',
|
|
150
|
+
Seconds: 10,
|
|
151
|
+
End: true,
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
function addNumbersLocal(input) {
|
|
157
|
+
return input.num1 + input.num2;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const stateMachine = new StateMachine(machineDefinition);
|
|
161
|
+
const myInput = { value1: 'hello', value2: 123, value3: true };
|
|
162
|
+
const execution = stateMachine.run(myInput, {
|
|
163
|
+
overrides: {
|
|
164
|
+
taskResourceLocalHandlers: {
|
|
165
|
+
AddNumbers: addNumbersLocal, // call the `addNumbersLocal` function instead of invoking the Lambda function specified for the `AddNumbers` state
|
|
166
|
+
},
|
|
167
|
+
waitTimeOverrides: {
|
|
168
|
+
Wait10Seconds: 500, // wait for 500 milliseconds instead of the 10 seconds specified in the `Wait10Seconds` state
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const result = await execution.result;
|
|
174
|
+
console.log(result);
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
##### Aborting an execution
|
|
178
|
+
|
|
179
|
+
```js
|
|
180
|
+
import { StateMachine, ExecutionAbortedError } from 'aws-local-stepfunctions';
|
|
181
|
+
|
|
182
|
+
const machineDefinition = {
|
|
183
|
+
StartAt: 'Hello World',
|
|
184
|
+
States: {
|
|
185
|
+
'Hello World': {
|
|
186
|
+
Type: 'Task',
|
|
187
|
+
Resource: 'arn:aws:lambda:us-east-1:123456789012:function:HelloWorld',
|
|
188
|
+
End: true,
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const stateMachine = new StateMachine(machineDefinition);
|
|
194
|
+
const myInput = { value1: 'hello', value2: 123, value3: true };
|
|
195
|
+
const execution = stateMachine.run(myInput);
|
|
196
|
+
|
|
197
|
+
// abort the execution after 3 seconds
|
|
198
|
+
setTimeout(() => {
|
|
199
|
+
execution.abort();
|
|
200
|
+
}, 3000);
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
const result = await execution.result;
|
|
204
|
+
console.log(result);
|
|
205
|
+
} catch (e) {
|
|
206
|
+
if (e instanceof ExecutionAbortedError) {
|
|
207
|
+
// since execution was aborted, type of error is `ExecutionAbortedError`
|
|
208
|
+
console.log('Execution was aborted');
|
|
209
|
+
} else {
|
|
210
|
+
console.error('Some other error', e);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
5
215
|
## License
|
|
6
216
|
|
|
7
217
|
[MIT](https://github.com/nibble-4bits/aws-local-stepfunctions/blob/develop/LICENSE)
|
package/build/main.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
Object.defineProperty(exports,"__esModule",{value:!0});var
|
|
2
|
-
${this.wrappedError.stack}`}constructor(e,t){super(`Execution of Lambda function "${t}" failed`),this.name="LambdaExecutionError",this.wrappedError=Error(e.errorMessage),this.wrappedError.stack=e.trace.join("\n")}}function asyncGeneratorStep$1(e,t,r,a,n,i,s){try{var u=e[i](s),l=u.value}catch(c){r(c);return}u.done?t(l):Promise.resolve(l).then(a,n)}function _asyncToGenerator$1(e){return function(){var t=this,r=arguments;return new Promise(function(a,n){var i=e.apply(t,r);function s(e){asyncGeneratorStep$1(i,a,n,s,u,"next",e)}function u(e){asyncGeneratorStep$1(i,a,n,s,u,"throw",e)}s(void 0)})}}class LambdaClient{invokeFunction(e,t){var r=this;return _asyncToGenerator$1(function*(){let a=Buffer.from(JSON.stringify(t)),n=new clientLambda.InvokeCommand({FunctionName:e,Payload:a}),i=yield r.client.send(n),s=null;if(i.Payload&&(s=JSON.parse(s=Buffer.from(i.Payload).toString())),i.FunctionError)throw new LambdaExecutionError(s,e);return s})()}constructor(e){this.client=new clientLambda.LambdaClient(null!=e?e:{})}}function testChoiceRule(e,t,r){if("And"in e)return e.And.every(e=>testChoiceRule(e,t,r));if("Or"in e)return e.Or.some(e=>testChoiceRule(e,t,r));if("Not"in e)return!testChoiceRule(e.Not,t,r);if("StringEquals"in e){let a=r(e.Variable,t);return a===e.StringEquals}if("StringEqualsPath"in e){let n=r(e.Variable,t),i=r(e.StringEqualsPath,t);return n===i}if("StringLessThan"in e){let s=r(e.Variable,t);return s<e.StringLessThan}if("StringLessThanPath"in e){let u=r(e.Variable,t),l=r(e.StringLessThanPath,t);return u<l}if("StringGreaterThan"in e){let c=r(e.Variable,t);return c>e.StringGreaterThan}if("StringGreaterThanPath"in e){let o=r(e.Variable,t),h=r(e.StringGreaterThanPath,t);return o>h}if("StringLessThanEquals"in e){let p=r(e.Variable,t);return p<=e.StringLessThanEquals}if("StringLessThanEqualsPath"in e){let m=r(e.Variable,t),d=r(e.StringLessThanEqualsPath,t);return m<=d}if("StringGreaterThanEquals"in e){let f=r(e.Variable,t);return f>=e.StringGreaterThanEquals}if("StringGreaterThanEqualsPath"in e){let T=r(e.Variable,t),S=r(e.StringGreaterThanEqualsPath,t);return T>=S}if("StringMatches"in e){let P=r(e.Variable,t),b=wcmatch__default.default(e.StringMatches,{separator:!1});return b(P)}if("NumericEquals"in e){let y=r(e.Variable,t);return y===e.NumericEquals}if("NumericEqualsPath"in e){let w=r(e.Variable,t),E=r(e.NumericEqualsPath,t);return w===E}if("NumericLessThan"in e){let I=r(e.Variable,t);return I<e.NumericLessThan}if("NumericLessThanPath"in e){let v=r(e.Variable,t),g=r(e.NumericLessThanPath,t);return v<g}if("NumericGreaterThan"in e){let q=r(e.Variable,t);return q>e.NumericGreaterThan}if("NumericGreaterThanPath"in e){let V=r(e.Variable,t),L=r(e.NumericGreaterThanPath,t);return V>L}if("NumericLessThanEquals"in e){let N=r(e.Variable,t);return N<=e.NumericLessThanEquals}if("NumericLessThanEqualsPath"in e){let G=r(e.Variable,t),R=r(e.NumericLessThanEqualsPath,t);return G<=R}if("NumericGreaterThanEquals"in e){let _=r(e.Variable,t);return _>=e.NumericGreaterThanEquals}if("NumericGreaterThanEqualsPath"in e){let D=r(e.Variable,t),j=r(e.NumericGreaterThanEqualsPath,t);return D>=j}if("BooleanEquals"in e){let O=r(e.Variable,t);return O===e.BooleanEquals}if("BooleanEqualsPath"in e){let x=r(e.Variable,t),C=r(e.BooleanEqualsPath,t);return x===C}if("TimestampEquals"in e){let $=new Date(r(e.Variable,t)),M=new Date(e.TimestampEquals);return $.getTime()===M.getTime()}if("TimestampEqualsPath"in e){let k=new Date(r(e.Variable,t)),B=new Date(r(e.TimestampEqualsPath,t));return k.getTime()===B.getTime()}if("TimestampLessThan"in e){let F=new Date(r(e.Variable,t)),Q=new Date(e.TimestampLessThan);return F<Q}if("TimestampLessThanPath"in e){let A=new Date(r(e.Variable,t)),W=new Date(r(e.TimestampLessThanPath,t));return A<W}if("TimestampGreaterThan"in e){let H=new Date(r(e.Variable,t)),J=new Date(e.TimestampGreaterThan);return H>J}if("TimestampGreaterThanPath"in e){let Z=new Date(r(e.Variable,t)),z=new Date(r(e.TimestampGreaterThanPath,t));return Z>z}if("TimestampLessThanEquals"in e){let K=new Date(r(e.Variable,t)),U=new Date(e.TimestampLessThanEquals);return K<=U}if("TimestampLessThanEqualsPath"in e){let X=new Date(r(e.Variable,t)),Y=new Date(r(e.TimestampLessThanEqualsPath,t));return X<=Y}if("TimestampGreaterThanEquals"in e){let ee=new Date(r(e.Variable,t)),et=new Date(e.TimestampGreaterThanEquals);return ee>=et}if("TimestampGreaterThanEqualsPath"in e){let er=new Date(r(e.Variable,t)),ea=new Date(r(e.TimestampGreaterThanEqualsPath,t));return er>=ea}if("IsNull"in e){let en=r(e.Variable,t),ei=e.IsNull;return ei&&null===en}if("IsPresent"in e){let es=r(e.Variable,t),eu=e.IsPresent;return eu&&!!es}if("IsNumeric"in e){let el=r(e.Variable,t),ec=e.IsNumeric;return ec&&"number"==typeof el}if("IsString"in e){let eo=r(e.Variable,t),eh=e.IsString;return eh&&"string"==typeof eo}if("IsBoolean"in e){let ep=r(e.Variable,t),em=e.IsBoolean;return em&&"boolean"==typeof ep}if("IsTimestamp"in e){let ed=r(e.Variable,t),ef=e.IsTimestamp;return ef&&/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|(\+|-)\d{2}:\d{2})/.test(ed)}return!1}function asyncGeneratorStep(e,t,r,a,n,i,s){try{var u=e[i](s),l=u.value}catch(c){r(c);return}u.done?t(l):Promise.resolve(l).then(a,n)}function _asyncToGenerator(e){return function(){var t=this,r=arguments;return new Promise(function(a,n){var i=e.apply(t,r);function s(e){asyncGeneratorStep(i,a,n,s,u,"next",e)}function u(e){asyncGeneratorStep(i,a,n,s,u,"throw",e)}s(void 0)})}}function _extends(){return(_extends=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var a in r)Object.prototype.hasOwnProperty.call(r,a)&&(e[a]=r[a])}return e}).apply(this,arguments)}class StateMachine{run(e,t){var r=this;return _asyncToGenerator(function*(){r.rawInput=e,r.currInput=e;let a=!1;do r.currState=r.states[r.currStateName],r.processInput(),yield r.stateHandlers[r.currState.Type](t),r.processResult(),r.rawInput=r.currResult,r.currInput=r.currResult,"Next"in r.currState&&(r.currStateName=r.currState.Next),("End"in r.currState||"Succeed"===r.currState.Type||"Fail"===r.currState.Type)&&(a=!0);while(!a);return r.currResult})()}processInputPath(){return"InputPath"in this.currState?null===this.currState.InputPath?{}:this.jsonQuery(this.currState.InputPath,this.currInput):this.currInput}processPayloadTemplate(e,t){let r=Object.entries(e).map(([e,r])=>{let a=e,n=r;return isPlainObj(r)&&(n=this.processPayloadTemplate(r,t)),e.endsWith(".$")&&"string"==typeof r&&(a=e.replace(".$",""),n=this.jsonQuery(r,t)),[a,n]});return Object.fromEntries(r)}processInput(){this.currInput=this.processInputPath(),"Parameters"in this.currState&&"Map"!==this.currState.Type&&(this.currInput=this.processPayloadTemplate(this.currState.Parameters,this.currInput))}processResultPath(){if("ResultPath"in this.currState){if(null===this.currState.ResultPath)return this.rawInput;let e=this.currState.ResultPath.replace("$.","");if(isPlainObj(this.rawInput)){let t=cloneDeep__default.default(this.rawInput);return set__default.default(t,e,this.currResult)}}return this.currResult}processOutputPath(){return"OutputPath"in this.currState?null===this.currState.OutputPath?{}:this.jsonQuery(this.currState.OutputPath,this.currResult):this.currResult}processResult(){"ResultSelector"in this.currState&&(this.currResult=this.processPayloadTemplate(this.currState.ResultSelector,this.currResult)),this.currResult=this.processResultPath(),this.currResult=this.processOutputPath()}handleTaskState(e){var t=this;return _asyncToGenerator(function*(){let r=t.currState,a=new LambdaClient;try{var n,i,s,u;if(null==e?void 0:null==(n=e.overrides)?void 0:null==(i=n.taskResourceLocalHandlers)?void 0:i[t.currStateName]){let l=null==e?void 0:null==(s=e.overrides)?void 0:null==(u=s.taskResourceLocalHandlers)?void 0:u[t.currStateName],c=yield l(t.currInput);t.currResult=c;return}let o=yield a.invokeFunction(r.Resource,t.currInput);t.currResult=o}catch(h){throw h instanceof LambdaExecutionError?console.error(h.toString()):console.error(h),h}})()}handleMapState(e){var t=this;return _asyncToGenerator(function*(){let r;let a=t.currState,n=t.currInput;if(a.ItemsPath&&(n=t.jsonQuery(a.ItemsPath,t.currInput)),!Array.isArray(n))return;let i=Array(n.length);for(let s=0;s<n.length;s++){let u=n[s];t.context.Map={Item:{Index:s,Value:u}},a.Parameters&&(r=t.processPayloadTemplate(a.Parameters,t.currInput));let l=new StateMachine(a.Iterator,t.validationOptions);i[s]=yield l.run(null!=r?r:u,e)}delete t.context.Map,t.currResult=i})()}handlePassState(e){var t=this;return _asyncToGenerator(function*(){let e=t.currState;e.Result?t.currResult=e.Result:t.currResult=t.currInput})()}handleWaitState(e){var t=this;return _asyncToGenerator(function*(){var r,a;let n=t.currState,i=null==e?void 0:null==(r=e.overrides)?void 0:null==(a=r.waitTimeOverrides)?void 0:a[t.currStateName];if("number"==typeof i){yield sleep(i),t.currResult=t.currInput;return}if(n.Seconds)yield sleep(1e3*n.Seconds);else if(n.Timestamp){let s=new Date(n.Timestamp),u=Date.now(),l=s.getTime()-u;yield sleep(l)}else if(n.SecondsPath){let c=t.jsonQuery(n.SecondsPath,t.currInput);yield sleep(1e3*c)}else if(n.TimestampPath){let o=t.jsonQuery(n.TimestampPath,t.currInput),h=new Date(o),p=Date.now(),m=h.getTime()-p;yield sleep(m)}t.currResult=t.currInput})()}handleChoiceState(e){var t=this;return _asyncToGenerator(function*(){let e=t.currState;for(let r of e.Choices){let a=testChoiceRule(r,t.currInput,t.jsonQuery);if(a){t.currStateName=r.Next,t.currResult=t.currInput;return}}if(e.Default){t.currStateName=e.Default,t.currResult=t.currInput;return}})()}handleSucceedState(e){var t=this;return _asyncToGenerator(function*(){t.currResult=t.currInput})()}handleFailState(e){return _asyncToGenerator(function*(){})()}jsonQuery(e,t){return e.startsWith("$$")?jsonpathPlus.JSONPath({path:e.slice(1),json:this.context,wrap:!1}):jsonpathPlus.JSONPath({path:e,json:t,wrap:!1})}constructor(e,t){let{isValid:r,errorsText:a}=aslValidator__default.default(e,_extends({checkArn:!0,checkPaths:!0},t));if(!r)throw Error(`State machine definition is invalid, see error(s) below:
|
|
3
|
-
${
|
|
1
|
+
Object.defineProperty(exports,"__esModule",{value:!0});var clientLambda=require("@aws-sdk/client-lambda"),jsonpathPlus=require("jsonpath-plus"),cloneDeep=require("lodash/cloneDeep.js"),set=require("lodash/set.js"),pLimit=require("p-limit"),wcmatch=require("wildcard-match"),aslValidator=require("asl-validator");function _interopDefaultLegacy(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var cloneDeep__default=_interopDefaultLegacy(cloneDeep),set__default=_interopDefaultLegacy(set),pLimit__default=_interopDefaultLegacy(pLimit),wcmatch__default=_interopDefaultLegacy(wcmatch),aslValidator__default=_interopDefaultLegacy(aslValidator);class BaseStateHandler{buildExecutionResult(e){let t={stateResult:e,nextState:"",isEndState:!1};return"Next"in this.stateDefinition&&(t.nextState=this.stateDefinition.Next),"End"in this.stateDefinition&&(t.isEndState=this.stateDefinition.End),t}constructor(e){this.stateDefinition=e}}class CustomError extends Error{constructor(e){super(e)}}class LambdaExecutionError extends CustomError{toString(){return`${this.name}: ${this.message}. The error thrown by the Lambda was:
|
|
2
|
+
${this.wrappedError.stack}`}constructor(e,t){super(`Execution of Lambda function "${t}" failed`),this.name="LambdaExecutionError",this.wrappedError=Error(e.errorMessage),this.wrappedError.stack=e.trace.join("\n")}}function asyncGeneratorStep$8(e,t,r,n,a,i,s){try{var o=e[i](s),u=o.value}catch(l){r(l);return}o.done?t(u):Promise.resolve(u).then(n,a)}function _asyncToGenerator$8(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var i=e.apply(t,r);function s(e){asyncGeneratorStep$8(i,n,a,s,o,"next",e)}function o(e){asyncGeneratorStep$8(i,n,a,s,o,"throw",e)}s(void 0)})}}class LambdaClient{invokeFunction(e,t){var r=this;return _asyncToGenerator$8(function*(){let n=Buffer.from(JSON.stringify(t)),a=new clientLambda.InvokeCommand({FunctionName:e,Payload:n}),i=yield r.client.send(a),s=null;if(i.Payload&&(s=JSON.parse(s=Buffer.from(i.Payload).toString())),i.FunctionError)throw new LambdaExecutionError(s,e);return s})()}constructor(e){this.client=new clientLambda.LambdaClient(null!=e?e:{})}}function asyncGeneratorStep$7(e,t,r,n,a,i,s){try{var o=e[i](s),u=o.value}catch(l){r(l);return}o.done?t(u):Promise.resolve(u).then(n,a)}function _asyncToGenerator$7(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var i=e.apply(t,r);function s(e){asyncGeneratorStep$7(i,n,a,s,o,"next",e)}function o(e){asyncGeneratorStep$7(i,n,a,s,o,"throw",e)}s(void 0)})}}class TaskStateHandler extends BaseStateHandler{executeState(e,t,r){var n=this;return _asyncToGenerator$7(function*(){let t=n.stateDefinition,a=new LambdaClient;try{if(null==r?void 0:r.overrideFn){let i=yield r.overrideFn(e);return n.buildExecutionResult(i)}let s=yield a.invokeFunction(t.Resource,e);return n.buildExecutionResult(s)}catch(o){throw o instanceof LambdaExecutionError?console.error(o.toString()):console.error(o),o}})()}constructor(e){super(e)}}function jsonPathQuery(e,t,r){return e.startsWith("$$")?jsonpathPlus.JSONPath({path:e.slice(1),json:null!=r?r:null,wrap:!1}):jsonpathPlus.JSONPath({path:e,json:t,wrap:!1})}function isPlainObj(e){return!!e&&Object.getPrototypeOf(e)===Object.prototype}function sleep(e,t){return new Promise(r=>{let n=setTimeout(r,e);null==t||t.addEventListener("abort",()=>{n.unref()})})}function processInputPath(e,t,r){return void 0===e?t:null===e?{}:jsonPathQuery(e,t,r)}function processPayloadTemplate(e,t,r){let n=Object.entries(e).map(([e,n])=>{let a=e,i=n;return isPlainObj(n)&&(i=processPayloadTemplate(n,t)),e.endsWith(".$")&&"string"==typeof n&&(a=e.replace(".$",""),i=jsonPathQuery(n,t,r)),[a,i]});return Object.fromEntries(n)}function processResultPath(e,t,r){if(void 0===e)return r;if(null===e)return t;let n=e.replace("$.","");if(isPlainObj(t)){let a=cloneDeep__default.default(t);return set__default.default(a,n,r)}throw Error("TODO: Change this error message for a more descriptive one")}function processOutputPath(e,t,r){return void 0===e?t:null===e?{}:jsonPathQuery(e,t,r)}function asyncGeneratorStep$6(e,t,r,n,a,i,s){try{var o=e[i](s),u=o.value}catch(l){r(l);return}o.done?t(u):Promise.resolve(u).then(n,a)}function _asyncToGenerator$6(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var i=e.apply(t,r);function s(e){asyncGeneratorStep$6(i,n,a,s,o,"next",e)}function o(e){asyncGeneratorStep$6(i,n,a,s,o,"throw",e)}s(void 0)})}}class MapStateHandler extends BaseStateHandler{processItem(e,t,r,n,a){let i;let s=this.stateDefinition;r.Map={Item:{Index:n,Value:e}},s.Parameters&&(i=processPayloadTemplate(s.Parameters,t,r));let o=new StateMachine(s.Iterator,null==a?void 0:a.validationOptions),{result:u}=o.run(null!=i?i:e,null==a?void 0:a.runOptions);return u}executeState(e,t,r){var n=this;return _asyncToGenerator$6(function*(){let a=n.stateDefinition,i=e;if(a.ItemsPath&&(i=jsonPathQuery(a.ItemsPath,e,t)),!Array.isArray(i))return n.buildExecutionResult([]);let s=pLimit__default.default(a.MaxConcurrency||40),o=i.map((a,i)=>s(()=>n.processItem(a,e,t,i,r))),u=yield Promise.all(o);return delete t.Map,n.buildExecutionResult(u)})()}constructor(e){super(e)}}function asyncGeneratorStep$5(e,t,r,n,a,i,s){try{var o=e[i](s),u=o.value}catch(l){r(l);return}o.done?t(u):Promise.resolve(u).then(n,a)}function _asyncToGenerator$5(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var i=e.apply(t,r);function s(e){asyncGeneratorStep$5(i,n,a,s,o,"next",e)}function o(e){asyncGeneratorStep$5(i,n,a,s,o,"throw",e)}s(void 0)})}}class PassStateHandler extends BaseStateHandler{executeState(e,t,r){var n=this;return _asyncToGenerator$5(function*(){return n.stateDefinition.Result?n.buildExecutionResult(n.stateDefinition.Result):n.buildExecutionResult(e)})()}constructor(e){super(e)}}function asyncGeneratorStep$4(e,t,r,n,a,i,s){try{var o=e[i](s),u=o.value}catch(l){r(l);return}o.done?t(u):Promise.resolve(u).then(n,a)}function _asyncToGenerator$4(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var i=e.apply(t,r);function s(e){asyncGeneratorStep$4(i,n,a,s,o,"next",e)}function o(e){asyncGeneratorStep$4(i,n,a,s,o,"throw",e)}s(void 0)})}}class WaitStateHandler extends BaseStateHandler{executeState(e,t,r){var n=this;return _asyncToGenerator$4(function*(){let a=n.stateDefinition;if((null==r?void 0:r.waitTimeOverrideOption)!==void 0)return yield sleep(r.waitTimeOverrideOption,r.abortSignal),n.buildExecutionResult(e);if(a.Seconds)yield sleep(1e3*a.Seconds,null==r?void 0:r.abortSignal);else if(a.Timestamp){let i=new Date(a.Timestamp),s=Date.now(),o=i.getTime()-s;yield sleep(o,null==r?void 0:r.abortSignal)}else if(a.SecondsPath){let u=jsonPathQuery(a.SecondsPath,e,t);yield sleep(1e3*u,null==r?void 0:r.abortSignal)}else if(a.TimestampPath){let l=jsonPathQuery(a.TimestampPath,e,t),c=new Date(l),h=Date.now(),d=c.getTime()-h;yield sleep(d,null==r?void 0:r.abortSignal)}return n.buildExecutionResult(e)})()}constructor(e){super(e)}}function asyncGeneratorStep$3(e,t,r,n,a,i,s){try{var o=e[i](s),u=o.value}catch(l){r(l);return}o.done?t(u):Promise.resolve(u).then(n,a)}function _asyncToGenerator$3(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var i=e.apply(t,r);function s(e){asyncGeneratorStep$3(i,n,a,s,o,"next",e)}function o(e){asyncGeneratorStep$3(i,n,a,s,o,"throw",e)}s(void 0)})}}class ChoiceStateHandler extends BaseStateHandler{testChoiceRule(e,t){if("And"in e)return e.And.every(e=>this.testChoiceRule(e,t));if("Or"in e)return e.Or.some(e=>this.testChoiceRule(e,t));if("Not"in e)return!this.testChoiceRule(e.Not,t);if("StringEquals"in e){let r=jsonPathQuery(e.Variable,t);return r===e.StringEquals}if("StringEqualsPath"in e){let n=jsonPathQuery(e.Variable,t),a=jsonPathQuery(e.StringEqualsPath,t);return n===a}if("StringLessThan"in e){let i=jsonPathQuery(e.Variable,t);return i<e.StringLessThan}if("StringLessThanPath"in e){let s=jsonPathQuery(e.Variable,t),o=jsonPathQuery(e.StringLessThanPath,t);return s<o}if("StringGreaterThan"in e){let u=jsonPathQuery(e.Variable,t);return u>e.StringGreaterThan}if("StringGreaterThanPath"in e){let l=jsonPathQuery(e.Variable,t),c=jsonPathQuery(e.StringGreaterThanPath,t);return l>c}if("StringLessThanEquals"in e){let h=jsonPathQuery(e.Variable,t);return h<=e.StringLessThanEquals}if("StringLessThanEqualsPath"in e){let d=jsonPathQuery(e.Variable,t),f=jsonPathQuery(e.StringLessThanEqualsPath,t);return d<=f}if("StringGreaterThanEquals"in e){let p=jsonPathQuery(e.Variable,t);return p>=e.StringGreaterThanEquals}if("StringGreaterThanEqualsPath"in e){let y=jsonPathQuery(e.Variable,t),P=jsonPathQuery(e.StringGreaterThanEqualsPath,t);return y>=P}if("StringMatches"in e){let m=jsonPathQuery(e.Variable,t),S=wcmatch__default.default(e.StringMatches,{separator:!1});return S(m)}if("NumericEquals"in e){let T=jsonPathQuery(e.Variable,t);return T===e.NumericEquals}if("NumericEqualsPath"in e){let v=jsonPathQuery(e.Variable,t),b=jsonPathQuery(e.NumericEqualsPath,t);return v===b}if("NumericLessThan"in e){let E=jsonPathQuery(e.Variable,t);return E<e.NumericLessThan}if("NumericLessThanPath"in e){let x=jsonPathQuery(e.Variable,t),w=jsonPathQuery(e.NumericLessThanPath,t);return x<w}if("NumericGreaterThan"in e){let j=jsonPathQuery(e.Variable,t);return j>e.NumericGreaterThan}if("NumericGreaterThanPath"in e){let G=jsonPathQuery(e.Variable,t),Q=jsonPathQuery(e.NumericGreaterThanPath,t);return G>Q}if("NumericLessThanEquals"in e){let g=jsonPathQuery(e.Variable,t);return g<=e.NumericLessThanEquals}if("NumericLessThanEqualsPath"in e){let _=jsonPathQuery(e.Variable,t),D=jsonPathQuery(e.NumericLessThanEqualsPath,t);return _<=D}if("NumericGreaterThanEquals"in e){let L=jsonPathQuery(e.Variable,t);return L>=e.NumericGreaterThanEquals}if("NumericGreaterThanEqualsPath"in e){let $=jsonPathQuery(e.Variable,t),q=jsonPathQuery(e.NumericGreaterThanEqualsPath,t);return $>=q}if("BooleanEquals"in e){let V=jsonPathQuery(e.Variable,t);return V===e.BooleanEquals}if("BooleanEqualsPath"in e){let O=jsonPathQuery(e.Variable,t),N=jsonPathQuery(e.BooleanEqualsPath,t);return O===N}if("TimestampEquals"in e){let R=new Date(jsonPathQuery(e.Variable,t)),I=new Date(e.TimestampEquals);return R.getTime()===I.getTime()}if("TimestampEqualsPath"in e){let H=new Date(jsonPathQuery(e.Variable,t)),C=new Date(jsonPathQuery(e.TimestampEqualsPath,t));return H.getTime()===C.getTime()}if("TimestampLessThan"in e){let M=new Date(jsonPathQuery(e.Variable,t)),B=new Date(e.TimestampLessThan);return M<B}if("TimestampLessThanPath"in e){let k=new Date(jsonPathQuery(e.Variable,t)),A=new Date(jsonPathQuery(e.TimestampLessThanPath,t));return k<A}if("TimestampGreaterThan"in e){let F=new Date(jsonPathQuery(e.Variable,t)),W=new Date(e.TimestampGreaterThan);return F>W}if("TimestampGreaterThanPath"in e){let J=new Date(jsonPathQuery(e.Variable,t)),Z=new Date(jsonPathQuery(e.TimestampGreaterThanPath,t));return J>Z}if("TimestampLessThanEquals"in e){let z=new Date(jsonPathQuery(e.Variable,t)),K=new Date(e.TimestampLessThanEquals);return z<=K}if("TimestampLessThanEqualsPath"in e){let U=new Date(jsonPathQuery(e.Variable,t)),X=new Date(jsonPathQuery(e.TimestampLessThanEqualsPath,t));return U<=X}if("TimestampGreaterThanEquals"in e){let Y=new Date(jsonPathQuery(e.Variable,t)),ee=new Date(e.TimestampGreaterThanEquals);return Y>=ee}if("TimestampGreaterThanEqualsPath"in e){let et=new Date(jsonPathQuery(e.Variable,t)),er=new Date(jsonPathQuery(e.TimestampGreaterThanEqualsPath,t));return et>=er}if("IsNull"in e){let en=jsonPathQuery(e.Variable,t),ea=e.IsNull;return ea&&null===en}if("IsPresent"in e){let ei=jsonPathQuery(e.Variable,t),es=e.IsPresent;return es&&void 0!==ei}if("IsNumeric"in e){let eo=jsonPathQuery(e.Variable,t),eu=e.IsNumeric;return eu&&"number"==typeof eo}if("IsString"in e){let el=jsonPathQuery(e.Variable,t),ec=e.IsString;return ec&&"string"==typeof el}if("IsBoolean"in e){let eh=jsonPathQuery(e.Variable,t),ed=e.IsBoolean;return ed&&"boolean"==typeof eh}if("IsTimestamp"in e){let ef=jsonPathQuery(e.Variable,t),ep=e.IsTimestamp;return ep&&/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|(\+|-)\d{2}:\d{2})/.test(ef)}return!1}executeState(e,t,r){var n=this;return _asyncToGenerator$3(function*(){let t=n.stateDefinition;for(let r of t.Choices){let a=n.testChoiceRule(r,e);if(a)return{stateResult:e,nextState:r.Next,isEndState:!1}}if(t.Default)return{stateResult:e,nextState:t.Default,isEndState:!1};throw Error("States.NoChoiceMatched")})()}constructor(e){super(e)}}function asyncGeneratorStep$2(e,t,r,n,a,i,s){try{var o=e[i](s),u=o.value}catch(l){r(l);return}o.done?t(u):Promise.resolve(u).then(n,a)}function _asyncToGenerator$2(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var i=e.apply(t,r);function s(e){asyncGeneratorStep$2(i,n,a,s,o,"next",e)}function o(e){asyncGeneratorStep$2(i,n,a,s,o,"throw",e)}s(void 0)})}}class SucceedStateHandler extends BaseStateHandler{executeState(e,t,r){return _asyncToGenerator$2(function*(){return{stateResult:e,nextState:"",isEndState:!0}})()}constructor(e){super(e)}}function asyncGeneratorStep$1(e,t,r,n,a,i,s){try{var o=e[i](s),u=o.value}catch(l){r(l);return}o.done?t(u):Promise.resolve(u).then(n,a)}function _asyncToGenerator$1(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var i=e.apply(t,r);function s(e){asyncGeneratorStep$1(i,n,a,s,o,"next",e)}function o(e){asyncGeneratorStep$1(i,n,a,s,o,"throw",e)}s(void 0)})}}class FailStateHandler extends BaseStateHandler{executeState(e,t,r){return _asyncToGenerator$1(function*(){return{stateResult:e,nextState:"",isEndState:!0}})()}constructor(e){super(e)}}class ExecutionAbortedError extends CustomError{toString(){return"Execution aborted"}constructor(){super("Execution aborted"),this.name="ExecutionAbortedError"}}function asyncGeneratorStep(e,t,r,n,a,i,s){try{var o=e[i](s),u=o.value}catch(l){r(l);return}o.done?t(u):Promise.resolve(u).then(n,a)}function _asyncToGenerator(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var i=e.apply(t,r);function s(e){asyncGeneratorStep(i,n,a,s,o,"next",e)}function o(e){asyncGeneratorStep(i,n,a,s,o,"throw",e)}s(void 0)})}}function _extends(){return(_extends=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}class StateMachine{run(e,t){let r=new AbortController,n=new Promise((e,n)=>{(null==t?void 0:t.noThrowOnAbort)?r.signal.addEventListener("abort",()=>e(null)):r.signal.addEventListener("abort",()=>n(new ExecutionAbortedError))}),a=this.execute(e,{runOptions:t,abortSignal:r.signal}),i=Promise.race([a,n]);return{abort:()=>r.abort(),result:i}}execute(e,t){var r=this;return _asyncToGenerator(function*(){let n=r.definition.States[r.definition.StartAt],a=r.definition.StartAt,i=cloneDeep__default.default(e),s=cloneDeep__default.default(e),o=null,u="",l=!1,c={};do s=r.processInput(n,s,c),({stateResult:o,nextState:u,isEndState:l}=yield r.stateExecutors[n.Type](n,s,c,a,t)),i=o=r.processResult(n,o,i,c),s=o,n=r.definition.States[u],a=u;while(!l&&!t.abortSignal.aborted);return o})()}processInput(e,t,r){let n=t;return"InputPath"in e&&(n=processInputPath(e.InputPath,n,r)),"Parameters"in e&&"Map"!==e.Type&&(n=processPayloadTemplate(e.Parameters,n,r)),n}processResult(e,t,r,n){let a=t;return"ResultSelector"in e&&(a=processPayloadTemplate(e.ResultSelector,a,n)),"ResultPath"in e&&(a=processResultPath(e.ResultPath,r,a)),"OutputPath"in e&&(a=processOutputPath(e.OutputPath,a,n)),a}executeTaskState(e,t,r,n,a){return _asyncToGenerator(function*(){var i,s,o;let u=null==(i=a.runOptions)?void 0:null==(s=i.overrides)?void 0:null==(o=s.taskResourceLocalHandlers)?void 0:o[n],l=new TaskStateHandler(e),c=yield l.executeState(t,r,{overrideFn:u});return c})()}executeMapState(e,t,r,n,a){var i=this;return _asyncToGenerator(function*(){let n=new MapStateHandler(e),s=yield n.executeState(t,r,{validationOptions:i.validationOptions,runOptions:a.runOptions});return s})()}executePassState(e,t,r,n,a){return _asyncToGenerator(function*(){let n=new PassStateHandler(e),a=yield n.executeState(t,r);return a})()}executeWaitState(e,t,r,n,a){return _asyncToGenerator(function*(){var i,s,o;let u=null==(i=a.runOptions)?void 0:null==(s=i.overrides)?void 0:null==(o=s.waitTimeOverrides)?void 0:o[n],l=a.abortSignal,c=new WaitStateHandler(e),h=yield c.executeState(t,r,{waitTimeOverrideOption:u,abortSignal:l});return h})()}executeChoiceState(e,t,r,n,a){return _asyncToGenerator(function*(){let n=new ChoiceStateHandler(e),a=yield n.executeState(t,r);return a})()}executeSucceedState(e,t,r,n,a){return _asyncToGenerator(function*(){let n=new SucceedStateHandler(e),a=yield n.executeState(t,r);return a})()}executeFailState(e,t,r,n,a){return _asyncToGenerator(function*(){let n=new FailStateHandler(e),a=yield n.executeState(t,r);return a})()}constructor(e,t){let{isValid:r,errorsText:n}=aslValidator__default.default(e,_extends({checkArn:!0,checkPaths:!0},t));if(!r)throw Error(`State machine definition is invalid, see error(s) below:
|
|
3
|
+
${n("\n")}`);this.definition=e,this.stateExecutors={Task:this.executeTaskState,Map:this.executeMapState,Pass:this.executePassState,Wait:this.executeWaitState,Choice:this.executeChoiceState,Succeed:this.executeSucceedState,Fail:this.executeFailState},this.validationOptions=t}}exports.ExecutionAbortedError=ExecutionAbortedError,exports.StateMachine=StateMachine;
|
package/build/main.d.ts
CHANGED
|
@@ -109,7 +109,7 @@ interface BaseMapState extends BaseState, CanHaveInputPath, CanHaveParameters, C
|
|
|
109
109
|
}
|
|
110
110
|
declare type MapState = (IntermediateState | TerminalState) & BaseMapState;
|
|
111
111
|
|
|
112
|
-
declare type JSONValue = null | boolean | number | string | object |
|
|
112
|
+
declare type JSONValue = null | boolean | number | string | object | JSONValue[];
|
|
113
113
|
|
|
114
114
|
interface BasePassState extends BaseState, CanHaveInputPath, CanHaveParameters, CanHaveResultPath, CanHaveOutputPath {
|
|
115
115
|
Type: 'Pass';
|
|
@@ -148,7 +148,7 @@ interface StateMachineDefinition {
|
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
declare type TaskStateResourceLocalHandler = {
|
|
151
|
-
[taskStateName: string]: (
|
|
151
|
+
[taskStateName: string]: (input: JSONValue) => Promise<JSONValue>;
|
|
152
152
|
};
|
|
153
153
|
declare type WaitStateTimeOverride = {
|
|
154
154
|
[waitStateName: string]: number;
|
|
@@ -159,6 +159,7 @@ interface Overrides {
|
|
|
159
159
|
}
|
|
160
160
|
interface RunOptions {
|
|
161
161
|
overrides?: Overrides;
|
|
162
|
+
noThrowOnAbort?: boolean;
|
|
162
163
|
}
|
|
163
164
|
interface ValidationOptions {
|
|
164
165
|
readonly checkPaths?: boolean;
|
|
@@ -167,37 +168,13 @@ interface ValidationOptions {
|
|
|
167
168
|
|
|
168
169
|
declare class StateMachine {
|
|
169
170
|
/**
|
|
170
|
-
* The
|
|
171
|
+
* The structure of the State Machine as represented by the Amazon States Language.
|
|
171
172
|
*/
|
|
172
|
-
private
|
|
173
|
+
private readonly definition;
|
|
173
174
|
/**
|
|
174
|
-
*
|
|
175
|
+
* A map of functions to execute each type of state.
|
|
175
176
|
*/
|
|
176
|
-
private
|
|
177
|
-
/**
|
|
178
|
-
* The unmodified input to the current state.
|
|
179
|
-
*/
|
|
180
|
-
private rawInput;
|
|
181
|
-
/**
|
|
182
|
-
* The input that can be modified according to the `InputPath` and `Parameters` fields of the current state.
|
|
183
|
-
*/
|
|
184
|
-
private currInput;
|
|
185
|
-
/**
|
|
186
|
-
* The result that can be modified according to the `ResultSelector`, `ResultPath` and `OutputPath` fields of the current state.
|
|
187
|
-
*/
|
|
188
|
-
private currResult;
|
|
189
|
-
/**
|
|
190
|
-
* The context object of the state machine.
|
|
191
|
-
*/
|
|
192
|
-
private context;
|
|
193
|
-
/**
|
|
194
|
-
* A map of all states defined in the state machine.
|
|
195
|
-
*/
|
|
196
|
-
private readonly states;
|
|
197
|
-
/**
|
|
198
|
-
* A map of functions to handle each type of state.
|
|
199
|
-
*/
|
|
200
|
-
private readonly stateHandlers;
|
|
177
|
+
private readonly stateExecutors;
|
|
201
178
|
/**
|
|
202
179
|
* Options to control whether to apply certain validations to the state machine definition.
|
|
203
180
|
*/
|
|
@@ -210,47 +187,26 @@ declare class StateMachine {
|
|
|
210
187
|
*/
|
|
211
188
|
constructor(definition: StateMachineDefinition, validationOptions?: ValidationOptions);
|
|
212
189
|
/**
|
|
213
|
-
* Executes the state machine, running through the states specified in the
|
|
190
|
+
* Executes the state machine, running through the states specified in the definition.
|
|
191
|
+
*
|
|
192
|
+
* By default, if the execution is aborted, the result will throw an `ExecutionAbortedError`. This behavior can be changed by setting
|
|
193
|
+
* the `noThrowOnAbort` option to `true`, in which case the result will be `null`.
|
|
194
|
+
*
|
|
214
195
|
* @param input The input to pass to this state machine execution.
|
|
215
196
|
* @param options Miscellaneous options to control certain behaviors of the execution.
|
|
216
197
|
*/
|
|
217
|
-
run(input: JSONValue, options?: RunOptions):
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
* * If `InputPath` is not specified, returns the current input unmodified.
|
|
222
|
-
* * If `InputPath` is `null`, returns an empty object (`{}`).
|
|
223
|
-
* * If `InputPath` is a string, it's considered a JSONPath and the selected portion of the current input is returned.
|
|
224
|
-
*/
|
|
225
|
-
private processInputPath;
|
|
198
|
+
run(input: JSONValue, options?: RunOptions): {
|
|
199
|
+
abort: () => void;
|
|
200
|
+
result: Promise<JSONValue>;
|
|
201
|
+
};
|
|
226
202
|
/**
|
|
227
|
-
*
|
|
228
|
-
* @param payloadTemplate The payload template to process.
|
|
229
|
-
* @param json The object to evaluate with JSONPath (whether of null, boolean, number, string, object, or array type).
|
|
230
|
-
* @returns The processed payload template.
|
|
203
|
+
* Helper method that handles the execution of the machine states and the transitions between them.
|
|
231
204
|
*/
|
|
232
|
-
private
|
|
205
|
+
private execute;
|
|
233
206
|
/**
|
|
234
207
|
* Process the current input according to the `InputPath` and `Parameters` fields.
|
|
235
208
|
*/
|
|
236
209
|
private processInput;
|
|
237
|
-
/**
|
|
238
|
-
* Process the current result according to the path defined in the `ResultPath` field, if specified in the current state.
|
|
239
|
-
* @returns
|
|
240
|
-
* * If `ResultPath` is not specified, returns the current result unmodified.
|
|
241
|
-
* * If `ResultPath` is `null`, returns the raw input (i.e. the input passed to current state).
|
|
242
|
-
* * If `ResultPath` is a string, it's considered a JSONPath and returns a combination of the raw input with the current result,
|
|
243
|
-
* by placing the current result in the specified path.
|
|
244
|
-
*/
|
|
245
|
-
private processResultPath;
|
|
246
|
-
/**
|
|
247
|
-
* Process the current result according to the path defined in the `OutputPath` field, if specified in the current state.
|
|
248
|
-
* @returns
|
|
249
|
-
* * If `OutputPath` is not specified, returns the current result unmodified.
|
|
250
|
-
* * If `OutputPath` is `null`, returns an empty object (`{}`).
|
|
251
|
-
* * If `OutputPath` is a string, it's considered a JSONPath and the selected portion of the current result is returned.
|
|
252
|
-
*/
|
|
253
|
-
private processOutputPath;
|
|
254
210
|
/**
|
|
255
211
|
* Process the current result according to the `ResultSelector`, `ResultPath` and `OutputPath` fields.
|
|
256
212
|
*/
|
|
@@ -261,7 +217,7 @@ declare class StateMachine {
|
|
|
261
217
|
* Invokes the Lambda function specified in the `Resource` field
|
|
262
218
|
* and sets the current result of the state machine to the value returned by the Lambda.
|
|
263
219
|
*/
|
|
264
|
-
private
|
|
220
|
+
private executeTaskState;
|
|
265
221
|
/**
|
|
266
222
|
* Handler for map states.
|
|
267
223
|
*
|
|
@@ -269,21 +225,21 @@ declare class StateMachine {
|
|
|
269
225
|
* by the `ItemsPath` field, and then processes each item by passing it
|
|
270
226
|
* as the input to the state machine specified in the `Iterator` field.
|
|
271
227
|
*/
|
|
272
|
-
private
|
|
228
|
+
private executeMapState;
|
|
273
229
|
/**
|
|
274
230
|
* Handler for pass states.
|
|
275
231
|
*
|
|
276
232
|
* If the `Result` field is specified, copies `Result` into the current result.
|
|
277
233
|
* Else, copies the current input into the current result.
|
|
278
234
|
*/
|
|
279
|
-
private
|
|
235
|
+
private executePassState;
|
|
280
236
|
/**
|
|
281
237
|
* Handler for wait states.
|
|
282
238
|
*
|
|
283
239
|
* Pauses the state machine execution for a certain amount of time
|
|
284
240
|
* based on one of the `Seconds`, `Timestamp`, `SecondsPath` or `TimestampPath` fields.
|
|
285
241
|
*/
|
|
286
|
-
private
|
|
242
|
+
private executeWaitState;
|
|
287
243
|
/**
|
|
288
244
|
* Handler for choice states.
|
|
289
245
|
*
|
|
@@ -298,26 +254,32 @@ declare class StateMachine {
|
|
|
298
254
|
* If no rule matches and the `Default` field is not specified, throws a
|
|
299
255
|
* States.NoChoiceMatched error.
|
|
300
256
|
*/
|
|
301
|
-
private
|
|
257
|
+
private executeChoiceState;
|
|
302
258
|
/**
|
|
303
259
|
* Handler for succeed states.
|
|
304
260
|
*
|
|
305
261
|
* Ends the state machine execution successfully.
|
|
306
262
|
*/
|
|
307
|
-
private
|
|
263
|
+
private executeSucceedState;
|
|
308
264
|
/**
|
|
309
265
|
* Handler for fail states.
|
|
310
266
|
*
|
|
311
267
|
* Ends the state machine execution and marks it as a failure.
|
|
312
268
|
*/
|
|
313
|
-
private
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
269
|
+
private executeFailState;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
declare abstract class CustomError extends Error {
|
|
273
|
+
constructor(message?: string);
|
|
274
|
+
abstract toString(): string;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Represents the abortion of a state machine execution.
|
|
279
|
+
*/
|
|
280
|
+
declare class ExecutionAbortedError extends CustomError {
|
|
281
|
+
constructor();
|
|
282
|
+
toString(): string;
|
|
321
283
|
}
|
|
322
284
|
|
|
323
|
-
export { StateMachine };
|
|
285
|
+
export { ExecutionAbortedError, StateMachine };
|
package/build/main.esm.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{
|
|
2
|
-
${this.wrappedError.stack}`}constructor(e,t){super(`Execution of Lambda function "${t}" failed`),this.name="LambdaExecutionError",this.wrappedError=Error(e.errorMessage),this.wrappedError.stack=e.trace.join("\n")}}function asyncGeneratorStep$1(e,t,r,a,n,i,s){try{var u=e[i](s),l=u.value}catch(o){r(o);return}u.done?t(l):Promise.resolve(l).then(a,n)}function _asyncToGenerator$1(e){return function(){var t=this,r=arguments;return new Promise(function(a,n){var i=e.apply(t,r);function s(e){asyncGeneratorStep$1(i,a,n,s,u,"next",e)}function u(e){asyncGeneratorStep$1(i,a,n,s,u,"throw",e)}s(void 0)})}}class LambdaClient{invokeFunction(e,t){var a=this;return _asyncToGenerator$1(function*(){let n=Buffer.from(JSON.stringify(t)),i=new r({FunctionName:e,Payload:n}),s=yield a.client.send(i),u=null;if(s.Payload&&(u=JSON.parse(u=Buffer.from(s.Payload).toString())),s.FunctionError)throw new LambdaExecutionError(u,e);return u})()}constructor(e){this.client=new t(null!=e?e:{})}}function testChoiceRule(e,t,r){if("And"in e)return e.And.every(e=>testChoiceRule(e,t,r));if("Or"in e)return e.Or.some(e=>testChoiceRule(e,t,r));if("Not"in e)return!testChoiceRule(e.Not,t,r);if("StringEquals"in e){let n=r(e.Variable,t);return n===e.StringEquals}if("StringEqualsPath"in e){let i=r(e.Variable,t),s=r(e.StringEqualsPath,t);return i===s}if("StringLessThan"in e){let u=r(e.Variable,t);return u<e.StringLessThan}if("StringLessThanPath"in e){let l=r(e.Variable,t),o=r(e.StringLessThanPath,t);return l<o}if("StringGreaterThan"in e){let c=r(e.Variable,t);return c>e.StringGreaterThan}if("StringGreaterThanPath"in e){let h=r(e.Variable,t),p=r(e.StringGreaterThanPath,t);return h>p}if("StringLessThanEquals"in e){let m=r(e.Variable,t);return m<=e.StringLessThanEquals}if("StringLessThanEqualsPath"in e){let f=r(e.Variable,t),d=r(e.StringLessThanEqualsPath,t);return f<=d}if("StringGreaterThanEquals"in e){let T=r(e.Variable,t);return T>=e.StringGreaterThanEquals}if("StringGreaterThanEqualsPath"in e){let S=r(e.Variable,t),P=r(e.StringGreaterThanEqualsPath,t);return S>=P}if("StringMatches"in e){let b=r(e.Variable,t),y=a(e.StringMatches,{separator:!1});return y(b)}if("NumericEquals"in e){let E=r(e.Variable,t);return E===e.NumericEquals}if("NumericEqualsPath"in e){let w=r(e.Variable,t),I=r(e.NumericEqualsPath,t);return w===I}if("NumericLessThan"in e){let v=r(e.Variable,t);return v<e.NumericLessThan}if("NumericLessThanPath"in e){let g=r(e.Variable,t),G=r(e.NumericLessThanPath,t);return g<G}if("NumericGreaterThan"in e){let N=r(e.Variable,t);return N>e.NumericGreaterThan}if("NumericGreaterThanPath"in e){let R=r(e.Variable,t),q=r(e.NumericGreaterThanPath,t);return R>q}if("NumericLessThanEquals"in e){let V=r(e.Variable,t);return V<=e.NumericLessThanEquals}if("NumericLessThanEqualsPath"in e){let L=r(e.Variable,t),D=r(e.NumericLessThanEqualsPath,t);return L<=D}if("NumericGreaterThanEquals"in e){let O=r(e.Variable,t);return O>=e.NumericGreaterThanEquals}if("NumericGreaterThanEqualsPath"in e){let j=r(e.Variable,t),x=r(e.NumericGreaterThanEqualsPath,t);return j>=x}if("BooleanEquals"in e){let $=r(e.Variable,t);return $===e.BooleanEquals}if("BooleanEqualsPath"in e){let C=r(e.Variable,t),_=r(e.BooleanEqualsPath,t);return C===_}if("TimestampEquals"in e){let k=new Date(r(e.Variable,t)),M=new Date(e.TimestampEquals);return k.getTime()===M.getTime()}if("TimestampEqualsPath"in e){let B=new Date(r(e.Variable,t)),F=new Date(r(e.TimestampEqualsPath,t));return B.getTime()===F.getTime()}if("TimestampLessThan"in e){let Q=new Date(r(e.Variable,t)),A=new Date(e.TimestampLessThan);return Q<A}if("TimestampLessThanPath"in e){let W=new Date(r(e.Variable,t)),H=new Date(r(e.TimestampLessThanPath,t));return W<H}if("TimestampGreaterThan"in e){let J=new Date(r(e.Variable,t)),Z=new Date(e.TimestampGreaterThan);return J>Z}if("TimestampGreaterThanPath"in e){let z=new Date(r(e.Variable,t)),K=new Date(r(e.TimestampGreaterThanPath,t));return z>K}if("TimestampLessThanEquals"in e){let U=new Date(r(e.Variable,t)),X=new Date(e.TimestampLessThanEquals);return U<=X}if("TimestampLessThanEqualsPath"in e){let Y=new Date(r(e.Variable,t)),ee=new Date(r(e.TimestampLessThanEqualsPath,t));return Y<=ee}if("TimestampGreaterThanEquals"in e){let et=new Date(r(e.Variable,t)),er=new Date(e.TimestampGreaterThanEquals);return et>=er}if("TimestampGreaterThanEqualsPath"in e){let ea=new Date(r(e.Variable,t)),en=new Date(r(e.TimestampGreaterThanEqualsPath,t));return ea>=en}if("IsNull"in e){let ei=r(e.Variable,t),es=e.IsNull;return es&&null===ei}if("IsPresent"in e){let eu=r(e.Variable,t),el=e.IsPresent;return el&&!!eu}if("IsNumeric"in e){let eo=r(e.Variable,t),ec=e.IsNumeric;return ec&&"number"==typeof eo}if("IsString"in e){let eh=r(e.Variable,t),ep=e.IsString;return ep&&"string"==typeof eh}if("IsBoolean"in e){let em=r(e.Variable,t),ef=e.IsBoolean;return ef&&"boolean"==typeof em}if("IsTimestamp"in e){let ed=r(e.Variable,t),eT=e.IsTimestamp;return eT&&/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|(\+|-)\d{2}:\d{2})/.test(ed)}return!1}function asyncGeneratorStep(e,t,r,a,n,i,s){try{var u=e[i](s),l=u.value}catch(o){r(o);return}u.done?t(l):Promise.resolve(l).then(a,n)}function _asyncToGenerator(e){return function(){var t=this,r=arguments;return new Promise(function(a,n){var i=e.apply(t,r);function s(e){asyncGeneratorStep(i,a,n,s,u,"next",e)}function u(e){asyncGeneratorStep(i,a,n,s,u,"throw",e)}s(void 0)})}}function _extends(){return(_extends=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var a in r)Object.prototype.hasOwnProperty.call(r,a)&&(e[a]=r[a])}return e}).apply(this,arguments)}class StateMachine{run(e,t){var r=this;return _asyncToGenerator(function*(){r.rawInput=e,r.currInput=e;let a=!1;do r.currState=r.states[r.currStateName],r.processInput(),yield r.stateHandlers[r.currState.Type](t),r.processResult(),r.rawInput=r.currResult,r.currInput=r.currResult,"Next"in r.currState&&(r.currStateName=r.currState.Next),("End"in r.currState||"Succeed"===r.currState.Type||"Fail"===r.currState.Type)&&(a=!0);while(!a);return r.currResult})()}processInputPath(){return"InputPath"in this.currState?null===this.currState.InputPath?{}:this.jsonQuery(this.currState.InputPath,this.currInput):this.currInput}processPayloadTemplate(e,t){let r=Object.entries(e).map(([e,r])=>{let a=e,n=r;return isPlainObj(r)&&(n=this.processPayloadTemplate(r,t)),e.endsWith(".$")&&"string"==typeof r&&(a=e.replace(".$",""),n=this.jsonQuery(r,t)),[a,n]});return Object.fromEntries(r)}processInput(){this.currInput=this.processInputPath(),"Parameters"in this.currState&&"Map"!==this.currState.Type&&(this.currInput=this.processPayloadTemplate(this.currState.Parameters,this.currInput))}processResultPath(){if("ResultPath"in this.currState){if(null===this.currState.ResultPath)return this.rawInput;let e=this.currState.ResultPath.replace("$.","");if(isPlainObj(this.rawInput)){let t=s(this.rawInput);return i(t,e,this.currResult)}}return this.currResult}processOutputPath(){return"OutputPath"in this.currState?null===this.currState.OutputPath?{}:this.jsonQuery(this.currState.OutputPath,this.currResult):this.currResult}processResult(){"ResultSelector"in this.currState&&(this.currResult=this.processPayloadTemplate(this.currState.ResultSelector,this.currResult)),this.currResult=this.processResultPath(),this.currResult=this.processOutputPath()}handleTaskState(e){var t=this;return _asyncToGenerator(function*(){let r=t.currState,a=new LambdaClient;try{var n,i,s,u;if(null==e?void 0:null==(n=e.overrides)?void 0:null==(i=n.taskResourceLocalHandlers)?void 0:i[t.currStateName]){let l=null==e?void 0:null==(s=e.overrides)?void 0:null==(u=s.taskResourceLocalHandlers)?void 0:u[t.currStateName],o=yield l(t.currInput);t.currResult=o;return}let c=yield a.invokeFunction(r.Resource,t.currInput);t.currResult=c}catch(h){throw h instanceof LambdaExecutionError?console.error(h.toString()):console.error(h),h}})()}handleMapState(e){var t=this;return _asyncToGenerator(function*(){let r;let a=t.currState,n=t.currInput;if(a.ItemsPath&&(n=t.jsonQuery(a.ItemsPath,t.currInput)),!Array.isArray(n))return;let i=Array(n.length);for(let s=0;s<n.length;s++){let u=n[s];t.context.Map={Item:{Index:s,Value:u}},a.Parameters&&(r=t.processPayloadTemplate(a.Parameters,t.currInput));let l=new StateMachine(a.Iterator,t.validationOptions);i[s]=yield l.run(null!=r?r:u,e)}delete t.context.Map,t.currResult=i})()}handlePassState(e){var t=this;return _asyncToGenerator(function*(){let e=t.currState;e.Result?t.currResult=e.Result:t.currResult=t.currInput})()}handleWaitState(e){var t=this;return _asyncToGenerator(function*(){var r,a;let n=t.currState,i=null==e?void 0:null==(r=e.overrides)?void 0:null==(a=r.waitTimeOverrides)?void 0:a[t.currStateName];if("number"==typeof i){yield sleep(i),t.currResult=t.currInput;return}if(n.Seconds)yield sleep(1e3*n.Seconds);else if(n.Timestamp){let s=new Date(n.Timestamp),u=Date.now(),l=s.getTime()-u;yield sleep(l)}else if(n.SecondsPath){let o=t.jsonQuery(n.SecondsPath,t.currInput);yield sleep(1e3*o)}else if(n.TimestampPath){let c=t.jsonQuery(n.TimestampPath,t.currInput),h=new Date(c),p=Date.now(),m=h.getTime()-p;yield sleep(m)}t.currResult=t.currInput})()}handleChoiceState(e){var t=this;return _asyncToGenerator(function*(){let e=t.currState;for(let r of e.Choices){let a=testChoiceRule(r,t.currInput,t.jsonQuery);if(a){t.currStateName=r.Next,t.currResult=t.currInput;return}}if(e.Default){t.currStateName=e.Default,t.currResult=t.currInput;return}})()}handleSucceedState(e){var t=this;return _asyncToGenerator(function*(){t.currResult=t.currInput})()}handleFailState(e){return _asyncToGenerator(function*(){})()}jsonQuery(t,r){return t.startsWith("$$")?e({path:t.slice(1),json:this.context,wrap:!1}):e({path:t,json:r,wrap:!1})}constructor(e,t){let{isValid:r,errorsText:a}=n(e,_extends({checkArn:!0,checkPaths:!0},t));if(!r)throw Error(`State machine definition is invalid, see error(s) below:
|
|
3
|
-
${
|
|
1
|
+
import{LambdaClient as e,InvokeCommand as t}from"@aws-sdk/client-lambda";import{JSONPath as r}from"jsonpath-plus";import n from"lodash/cloneDeep.js";import a from"lodash/set.js";import i from"p-limit";import s from"wildcard-match";import o from"asl-validator";class BaseStateHandler{buildExecutionResult(e){let t={stateResult:e,nextState:"",isEndState:!1};return"Next"in this.stateDefinition&&(t.nextState=this.stateDefinition.Next),"End"in this.stateDefinition&&(t.isEndState=this.stateDefinition.End),t}constructor(e){this.stateDefinition=e}}class CustomError extends Error{constructor(e){super(e)}}class LambdaExecutionError extends CustomError{toString(){return`${this.name}: ${this.message}. The error thrown by the Lambda was:
|
|
2
|
+
${this.wrappedError.stack}`}constructor(e,t){super(`Execution of Lambda function "${t}" failed`),this.name="LambdaExecutionError",this.wrappedError=Error(e.errorMessage),this.wrappedError.stack=e.trace.join("\n")}}function asyncGeneratorStep$8(e,t,r,n,a,i,s){try{var o=e[i](s),u=o.value}catch(l){r(l);return}o.done?t(u):Promise.resolve(u).then(n,a)}function _asyncToGenerator$8(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var i=e.apply(t,r);function s(e){asyncGeneratorStep$8(i,n,a,s,o,"next",e)}function o(e){asyncGeneratorStep$8(i,n,a,s,o,"throw",e)}s(void 0)})}}class LambdaClient{invokeFunction(e,r){var n=this;return _asyncToGenerator$8(function*(){let a=Buffer.from(JSON.stringify(r)),i=new t({FunctionName:e,Payload:a}),s=yield n.client.send(i),o=null;if(s.Payload&&(o=JSON.parse(o=Buffer.from(s.Payload).toString())),s.FunctionError)throw new LambdaExecutionError(o,e);return o})()}constructor(t){this.client=new e(null!=t?t:{})}}function asyncGeneratorStep$7(e,t,r,n,a,i,s){try{var o=e[i](s),u=o.value}catch(l){r(l);return}o.done?t(u):Promise.resolve(u).then(n,a)}function _asyncToGenerator$7(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var i=e.apply(t,r);function s(e){asyncGeneratorStep$7(i,n,a,s,o,"next",e)}function o(e){asyncGeneratorStep$7(i,n,a,s,o,"throw",e)}s(void 0)})}}class TaskStateHandler extends BaseStateHandler{executeState(e,t,r){var n=this;return _asyncToGenerator$7(function*(){let t=n.stateDefinition,a=new LambdaClient;try{if(null==r?void 0:r.overrideFn){let i=yield r.overrideFn(e);return n.buildExecutionResult(i)}let s=yield a.invokeFunction(t.Resource,e);return n.buildExecutionResult(s)}catch(o){throw o instanceof LambdaExecutionError?console.error(o.toString()):console.error(o),o}})()}constructor(e){super(e)}}function jsonPathQuery(e,t,n){return e.startsWith("$$")?r({path:e.slice(1),json:null!=n?n:null,wrap:!1}):r({path:e,json:t,wrap:!1})}function isPlainObj(e){return!!e&&Object.getPrototypeOf(e)===Object.prototype}function sleep(e,t){return new Promise(r=>{let n=setTimeout(r,e);null==t||t.addEventListener("abort",()=>{n.unref()})})}function processInputPath(e,t,r){return void 0===e?t:null===e?{}:jsonPathQuery(e,t,r)}function processPayloadTemplate(e,t,r){let n=Object.entries(e).map(([e,n])=>{let a=e,i=n;return isPlainObj(n)&&(i=processPayloadTemplate(n,t)),e.endsWith(".$")&&"string"==typeof n&&(a=e.replace(".$",""),i=jsonPathQuery(n,t,r)),[a,i]});return Object.fromEntries(n)}function processResultPath(e,t,r){if(void 0===e)return r;if(null===e)return t;let i=e.replace("$.","");if(isPlainObj(t)){let s=n(t);return a(s,i,r)}throw Error("TODO: Change this error message for a more descriptive one")}function processOutputPath(e,t,r){return void 0===e?t:null===e?{}:jsonPathQuery(e,t,r)}function asyncGeneratorStep$6(e,t,r,n,a,i,s){try{var o=e[i](s),u=o.value}catch(l){r(l);return}o.done?t(u):Promise.resolve(u).then(n,a)}function _asyncToGenerator$6(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var i=e.apply(t,r);function s(e){asyncGeneratorStep$6(i,n,a,s,o,"next",e)}function o(e){asyncGeneratorStep$6(i,n,a,s,o,"throw",e)}s(void 0)})}}class MapStateHandler extends BaseStateHandler{processItem(e,t,r,n,a){let i;let s=this.stateDefinition;r.Map={Item:{Index:n,Value:e}},s.Parameters&&(i=processPayloadTemplate(s.Parameters,t,r));let o=new StateMachine(s.Iterator,null==a?void 0:a.validationOptions),{result:u}=o.run(null!=i?i:e,null==a?void 0:a.runOptions);return u}executeState(e,t,r){var n=this;return _asyncToGenerator$6(function*(){let a=n.stateDefinition,s=e;if(a.ItemsPath&&(s=jsonPathQuery(a.ItemsPath,e,t)),!Array.isArray(s))return n.buildExecutionResult([]);let o=i(a.MaxConcurrency||40),u=s.map((a,i)=>o(()=>n.processItem(a,e,t,i,r))),l=yield Promise.all(u);return delete t.Map,n.buildExecutionResult(l)})()}constructor(e){super(e)}}function asyncGeneratorStep$5(e,t,r,n,a,i,s){try{var o=e[i](s),u=o.value}catch(l){r(l);return}o.done?t(u):Promise.resolve(u).then(n,a)}function _asyncToGenerator$5(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var i=e.apply(t,r);function s(e){asyncGeneratorStep$5(i,n,a,s,o,"next",e)}function o(e){asyncGeneratorStep$5(i,n,a,s,o,"throw",e)}s(void 0)})}}class PassStateHandler extends BaseStateHandler{executeState(e,t,r){var n=this;return _asyncToGenerator$5(function*(){return n.stateDefinition.Result?n.buildExecutionResult(n.stateDefinition.Result):n.buildExecutionResult(e)})()}constructor(e){super(e)}}function asyncGeneratorStep$4(e,t,r,n,a,i,s){try{var o=e[i](s),u=o.value}catch(l){r(l);return}o.done?t(u):Promise.resolve(u).then(n,a)}function _asyncToGenerator$4(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var i=e.apply(t,r);function s(e){asyncGeneratorStep$4(i,n,a,s,o,"next",e)}function o(e){asyncGeneratorStep$4(i,n,a,s,o,"throw",e)}s(void 0)})}}class WaitStateHandler extends BaseStateHandler{executeState(e,t,r){var n=this;return _asyncToGenerator$4(function*(){let a=n.stateDefinition;if((null==r?void 0:r.waitTimeOverrideOption)!==void 0)return yield sleep(r.waitTimeOverrideOption,r.abortSignal),n.buildExecutionResult(e);if(a.Seconds)yield sleep(1e3*a.Seconds,null==r?void 0:r.abortSignal);else if(a.Timestamp){let i=new Date(a.Timestamp),s=Date.now(),o=i.getTime()-s;yield sleep(o,null==r?void 0:r.abortSignal)}else if(a.SecondsPath){let u=jsonPathQuery(a.SecondsPath,e,t);yield sleep(1e3*u,null==r?void 0:r.abortSignal)}else if(a.TimestampPath){let l=jsonPathQuery(a.TimestampPath,e,t),c=new Date(l),h=Date.now(),d=c.getTime()-h;yield sleep(d,null==r?void 0:r.abortSignal)}return n.buildExecutionResult(e)})()}constructor(e){super(e)}}function asyncGeneratorStep$3(e,t,r,n,a,i,s){try{var o=e[i](s),u=o.value}catch(l){r(l);return}o.done?t(u):Promise.resolve(u).then(n,a)}function _asyncToGenerator$3(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var i=e.apply(t,r);function s(e){asyncGeneratorStep$3(i,n,a,s,o,"next",e)}function o(e){asyncGeneratorStep$3(i,n,a,s,o,"throw",e)}s(void 0)})}}class ChoiceStateHandler extends BaseStateHandler{testChoiceRule(e,t){if("And"in e)return e.And.every(e=>this.testChoiceRule(e,t));if("Or"in e)return e.Or.some(e=>this.testChoiceRule(e,t));if("Not"in e)return!this.testChoiceRule(e.Not,t);if("StringEquals"in e){let r=jsonPathQuery(e.Variable,t);return r===e.StringEquals}if("StringEqualsPath"in e){let n=jsonPathQuery(e.Variable,t),a=jsonPathQuery(e.StringEqualsPath,t);return n===a}if("StringLessThan"in e){let i=jsonPathQuery(e.Variable,t);return i<e.StringLessThan}if("StringLessThanPath"in e){let o=jsonPathQuery(e.Variable,t),u=jsonPathQuery(e.StringLessThanPath,t);return o<u}if("StringGreaterThan"in e){let l=jsonPathQuery(e.Variable,t);return l>e.StringGreaterThan}if("StringGreaterThanPath"in e){let c=jsonPathQuery(e.Variable,t),h=jsonPathQuery(e.StringGreaterThanPath,t);return c>h}if("StringLessThanEquals"in e){let d=jsonPathQuery(e.Variable,t);return d<=e.StringLessThanEquals}if("StringLessThanEqualsPath"in e){let f=jsonPathQuery(e.Variable,t),p=jsonPathQuery(e.StringLessThanEqualsPath,t);return f<=p}if("StringGreaterThanEquals"in e){let y=jsonPathQuery(e.Variable,t);return y>=e.StringGreaterThanEquals}if("StringGreaterThanEqualsPath"in e){let m=jsonPathQuery(e.Variable,t),P=jsonPathQuery(e.StringGreaterThanEqualsPath,t);return m>=P}if("StringMatches"in e){let S=jsonPathQuery(e.Variable,t),T=s(e.StringMatches,{separator:!1});return T(S)}if("NumericEquals"in e){let v=jsonPathQuery(e.Variable,t);return v===e.NumericEquals}if("NumericEqualsPath"in e){let E=jsonPathQuery(e.Variable,t),b=jsonPathQuery(e.NumericEqualsPath,t);return E===b}if("NumericLessThan"in e){let x=jsonPathQuery(e.Variable,t);return x<e.NumericLessThan}if("NumericLessThanPath"in e){let w=jsonPathQuery(e.Variable,t),j=jsonPathQuery(e.NumericLessThanPath,t);return w<j}if("NumericGreaterThan"in e){let G=jsonPathQuery(e.Variable,t);return G>e.NumericGreaterThan}if("NumericGreaterThanPath"in e){let Q=jsonPathQuery(e.Variable,t),g=jsonPathQuery(e.NumericGreaterThanPath,t);return Q>g}if("NumericLessThanEquals"in e){let $=jsonPathQuery(e.Variable,t);return $<=e.NumericLessThanEquals}if("NumericLessThanEqualsPath"in e){let q=jsonPathQuery(e.Variable,t),D=jsonPathQuery(e.NumericLessThanEqualsPath,t);return q<=D}if("NumericGreaterThanEquals"in e){let V=jsonPathQuery(e.Variable,t);return V>=e.NumericGreaterThanEquals}if("NumericGreaterThanEqualsPath"in e){let L=jsonPathQuery(e.Variable,t),O=jsonPathQuery(e.NumericGreaterThanEqualsPath,t);return L>=O}if("BooleanEquals"in e){let N=jsonPathQuery(e.Variable,t);return N===e.BooleanEquals}if("BooleanEqualsPath"in e){let R=jsonPathQuery(e.Variable,t),_=jsonPathQuery(e.BooleanEqualsPath,t);return R===_}if("TimestampEquals"in e){let I=new Date(jsonPathQuery(e.Variable,t)),H=new Date(e.TimestampEquals);return I.getTime()===H.getTime()}if("TimestampEqualsPath"in e){let C=new Date(jsonPathQuery(e.Variable,t)),B=new Date(jsonPathQuery(e.TimestampEqualsPath,t));return C.getTime()===B.getTime()}if("TimestampLessThan"in e){let M=new Date(jsonPathQuery(e.Variable,t)),k=new Date(e.TimestampLessThan);return M<k}if("TimestampLessThanPath"in e){let A=new Date(jsonPathQuery(e.Variable,t)),F=new Date(jsonPathQuery(e.TimestampLessThanPath,t));return A<F}if("TimestampGreaterThan"in e){let W=new Date(jsonPathQuery(e.Variable,t)),J=new Date(e.TimestampGreaterThan);return W>J}if("TimestampGreaterThanPath"in e){let Z=new Date(jsonPathQuery(e.Variable,t)),z=new Date(jsonPathQuery(e.TimestampGreaterThanPath,t));return Z>z}if("TimestampLessThanEquals"in e){let K=new Date(jsonPathQuery(e.Variable,t)),U=new Date(e.TimestampLessThanEquals);return K<=U}if("TimestampLessThanEqualsPath"in e){let X=new Date(jsonPathQuery(e.Variable,t)),Y=new Date(jsonPathQuery(e.TimestampLessThanEqualsPath,t));return X<=Y}if("TimestampGreaterThanEquals"in e){let ee=new Date(jsonPathQuery(e.Variable,t)),et=new Date(e.TimestampGreaterThanEquals);return ee>=et}if("TimestampGreaterThanEqualsPath"in e){let er=new Date(jsonPathQuery(e.Variable,t)),en=new Date(jsonPathQuery(e.TimestampGreaterThanEqualsPath,t));return er>=en}if("IsNull"in e){let ea=jsonPathQuery(e.Variable,t),ei=e.IsNull;return ei&&null===ea}if("IsPresent"in e){let es=jsonPathQuery(e.Variable,t),eo=e.IsPresent;return eo&&void 0!==es}if("IsNumeric"in e){let eu=jsonPathQuery(e.Variable,t),el=e.IsNumeric;return el&&"number"==typeof eu}if("IsString"in e){let ec=jsonPathQuery(e.Variable,t),eh=e.IsString;return eh&&"string"==typeof ec}if("IsBoolean"in e){let ed=jsonPathQuery(e.Variable,t),ef=e.IsBoolean;return ef&&"boolean"==typeof ed}if("IsTimestamp"in e){let ep=jsonPathQuery(e.Variable,t),ey=e.IsTimestamp;return ey&&/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|(\+|-)\d{2}:\d{2})/.test(ep)}return!1}executeState(e,t,r){var n=this;return _asyncToGenerator$3(function*(){let t=n.stateDefinition;for(let r of t.Choices){let a=n.testChoiceRule(r,e);if(a)return{stateResult:e,nextState:r.Next,isEndState:!1}}if(t.Default)return{stateResult:e,nextState:t.Default,isEndState:!1};throw Error("States.NoChoiceMatched")})()}constructor(e){super(e)}}function asyncGeneratorStep$2(e,t,r,n,a,i,s){try{var o=e[i](s),u=o.value}catch(l){r(l);return}o.done?t(u):Promise.resolve(u).then(n,a)}function _asyncToGenerator$2(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var i=e.apply(t,r);function s(e){asyncGeneratorStep$2(i,n,a,s,o,"next",e)}function o(e){asyncGeneratorStep$2(i,n,a,s,o,"throw",e)}s(void 0)})}}class SucceedStateHandler extends BaseStateHandler{executeState(e,t,r){return _asyncToGenerator$2(function*(){return{stateResult:e,nextState:"",isEndState:!0}})()}constructor(e){super(e)}}function asyncGeneratorStep$1(e,t,r,n,a,i,s){try{var o=e[i](s),u=o.value}catch(l){r(l);return}o.done?t(u):Promise.resolve(u).then(n,a)}function _asyncToGenerator$1(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var i=e.apply(t,r);function s(e){asyncGeneratorStep$1(i,n,a,s,o,"next",e)}function o(e){asyncGeneratorStep$1(i,n,a,s,o,"throw",e)}s(void 0)})}}class FailStateHandler extends BaseStateHandler{executeState(e,t,r){return _asyncToGenerator$1(function*(){return{stateResult:e,nextState:"",isEndState:!0}})()}constructor(e){super(e)}}class ExecutionAbortedError extends CustomError{toString(){return"Execution aborted"}constructor(){super("Execution aborted"),this.name="ExecutionAbortedError"}}function asyncGeneratorStep(e,t,r,n,a,i,s){try{var o=e[i](s),u=o.value}catch(l){r(l);return}o.done?t(u):Promise.resolve(u).then(n,a)}function _asyncToGenerator(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var i=e.apply(t,r);function s(e){asyncGeneratorStep(i,n,a,s,o,"next",e)}function o(e){asyncGeneratorStep(i,n,a,s,o,"throw",e)}s(void 0)})}}function _extends(){return(_extends=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}class StateMachine{run(e,t){let r=new AbortController,n=new Promise((e,n)=>{(null==t?void 0:t.noThrowOnAbort)?r.signal.addEventListener("abort",()=>e(null)):r.signal.addEventListener("abort",()=>n(new ExecutionAbortedError))}),a=this.execute(e,{runOptions:t,abortSignal:r.signal}),i=Promise.race([a,n]);return{abort:()=>r.abort(),result:i}}execute(e,t){var r=this;return _asyncToGenerator(function*(){let a=r.definition.States[r.definition.StartAt],i=r.definition.StartAt,s=n(e),o=n(e),u=null,l="",c=!1,h={};do o=r.processInput(a,o,h),({stateResult:u,nextState:l,isEndState:c}=yield r.stateExecutors[a.Type](a,o,h,i,t)),s=u=r.processResult(a,u,s,h),o=u,a=r.definition.States[l],i=l;while(!c&&!t.abortSignal.aborted);return u})()}processInput(e,t,r){let n=t;return"InputPath"in e&&(n=processInputPath(e.InputPath,n,r)),"Parameters"in e&&"Map"!==e.Type&&(n=processPayloadTemplate(e.Parameters,n,r)),n}processResult(e,t,r,n){let a=t;return"ResultSelector"in e&&(a=processPayloadTemplate(e.ResultSelector,a,n)),"ResultPath"in e&&(a=processResultPath(e.ResultPath,r,a)),"OutputPath"in e&&(a=processOutputPath(e.OutputPath,a,n)),a}executeTaskState(e,t,r,n,a){return _asyncToGenerator(function*(){var i,s,o;let u=null==(i=a.runOptions)?void 0:null==(s=i.overrides)?void 0:null==(o=s.taskResourceLocalHandlers)?void 0:o[n],l=new TaskStateHandler(e),c=yield l.executeState(t,r,{overrideFn:u});return c})()}executeMapState(e,t,r,n,a){var i=this;return _asyncToGenerator(function*(){let n=new MapStateHandler(e),s=yield n.executeState(t,r,{validationOptions:i.validationOptions,runOptions:a.runOptions});return s})()}executePassState(e,t,r,n,a){return _asyncToGenerator(function*(){let n=new PassStateHandler(e),a=yield n.executeState(t,r);return a})()}executeWaitState(e,t,r,n,a){return _asyncToGenerator(function*(){var i,s,o;let u=null==(i=a.runOptions)?void 0:null==(s=i.overrides)?void 0:null==(o=s.waitTimeOverrides)?void 0:o[n],l=a.abortSignal,c=new WaitStateHandler(e),h=yield c.executeState(t,r,{waitTimeOverrideOption:u,abortSignal:l});return h})()}executeChoiceState(e,t,r,n,a){return _asyncToGenerator(function*(){let n=new ChoiceStateHandler(e),a=yield n.executeState(t,r);return a})()}executeSucceedState(e,t,r,n,a){return _asyncToGenerator(function*(){let n=new SucceedStateHandler(e),a=yield n.executeState(t,r);return a})()}executeFailState(e,t,r,n,a){return _asyncToGenerator(function*(){let n=new FailStateHandler(e),a=yield n.executeState(t,r);return a})()}constructor(e,t){let{isValid:r,errorsText:n}=o(e,_extends({checkArn:!0,checkPaths:!0},t));if(!r)throw Error(`State machine definition is invalid, see error(s) below:
|
|
3
|
+
${n("\n")}`);this.definition=e,this.stateExecutors={Task:this.executeTaskState,Map:this.executeMapState,Pass:this.executePassState,Wait:this.executeWaitState,Choice:this.executeChoiceState,Succeed:this.executeSucceedState,Fail:this.executeFailState},this.validationOptions=t}}export{ExecutionAbortedError,StateMachine};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aws-local-stepfunctions",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Execute an AWS Step Function locally",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"aws",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"test": "jest",
|
|
37
|
-
"build": "bunchee --
|
|
37
|
+
"build": "bunchee --minify src/main.ts",
|
|
38
38
|
"prettier": "prettier --write src/**/*.ts",
|
|
39
39
|
"lint": "eslint src/**/*.ts",
|
|
40
40
|
"lint:fix": "eslint src/**/*.ts --fix"
|
|
@@ -43,11 +43,11 @@
|
|
|
43
43
|
"@tsconfig/node16-strictest": "^1.0.4",
|
|
44
44
|
"@types/jest": "^29.0.3",
|
|
45
45
|
"@types/lodash": "^4.14.184",
|
|
46
|
-
"@types/node": "^
|
|
46
|
+
"@types/node": "^18.14.0",
|
|
47
47
|
"@types/picomatch": "^2.3.0",
|
|
48
48
|
"@typescript-eslint/eslint-plugin": "^5.22.0",
|
|
49
49
|
"@typescript-eslint/parser": "^5.22.0",
|
|
50
|
-
"bunchee": "^2.
|
|
50
|
+
"bunchee": "^2.2.0",
|
|
51
51
|
"eslint": "^8.14.0",
|
|
52
52
|
"eslint-config-prettier": "^8.5.0",
|
|
53
53
|
"eslint-plugin-prettier": "^4.0.0",
|
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
"asl-validator": "^3.0.8",
|
|
61
61
|
"jsonpath-plus": "^6.0.1",
|
|
62
62
|
"lodash": "^4.17.21",
|
|
63
|
+
"p-limit": "^3.1.0",
|
|
63
64
|
"wildcard-match": "^5.1.2"
|
|
64
65
|
}
|
|
65
66
|
}
|