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 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 jsonpathPlus=require("jsonpath-plus"),clientLambda=require("@aws-sdk/client-lambda"),wcmatch=require("wildcard-match"),aslValidator=require("asl-validator"),set=require("lodash/set.js"),cloneDeep=require("lodash/cloneDeep.js");function _interopDefaultLegacy(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var wcmatch__default=_interopDefaultLegacy(wcmatch),aslValidator__default=_interopDefaultLegacy(aslValidator),set__default=_interopDefaultLegacy(set),cloneDeep__default=_interopDefaultLegacy(cloneDeep);function isPlainObj(e){return!!e&&Object.getPrototypeOf(e)===Object.prototype}function sleep(e){return new Promise(t=>{setTimeout(t,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$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
- ${a("\n")}`);this.states=e.States,this.currStateName=e.StartAt,this.currState=this.states[this.currStateName],this.rawInput={},this.currInput={},this.currResult=null,this.context={},this.stateHandlers={Task:this.handleTaskState.bind(this),Map:this.handleMapState.bind(this),Pass:this.handlePassState.bind(this),Wait:this.handleWaitState.bind(this),Choice:this.handleChoiceState.bind(this),Succeed:this.handleSucceedState.bind(this),Fail:this.handleFailState.bind(this)},this.validationOptions=t}}exports.StateMachine=StateMachine;
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 | any[];
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]: (...args: any) => any;
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 name of the state currently being executed.
171
+ * The structure of the State Machine as represented by the Amazon States Language.
171
172
  */
172
- private currStateName;
173
+ private readonly definition;
173
174
  /**
174
- * The current state being executed.
175
+ * A map of functions to execute each type of state.
175
176
  */
176
- private currState;
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 definiton.
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): Promise<JSONValue>;
218
- /**
219
- * Process the current input according to the path defined in the `InputPath` field, if specified in the current state.
220
- * @returns
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
- * Recursively process a payload template to resolve the properties that are JSONPaths.
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 processPayloadTemplate;
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 handleTaskState;
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 handleMapState;
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 handlePassState;
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 handleWaitState;
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 handleChoiceState;
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 handleSucceedState;
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 handleFailState;
314
- /**
315
- * Queries for a property in an object using a JSONPath expression.
316
- * @param pathExpression The JSONPath expression to query for.
317
- * @param json The object to evaluate (whether of null, boolean, number, string, object, or array type).
318
- * @returns The value of the property that was queried for, if found. Otherwise returns `undefined`.
319
- */
320
- private jsonQuery;
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{JSONPath as e}from"jsonpath-plus";import{LambdaClient as t,InvokeCommand as r}from"@aws-sdk/client-lambda";import a from"wildcard-match";import n from"asl-validator";import i from"lodash/set.js";import s from"lodash/cloneDeep.js";function isPlainObj(e){return!!e&&Object.getPrototypeOf(e)===Object.prototype}function sleep(e){return new Promise(t=>{setTimeout(t,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$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
- ${a("\n")}`);this.states=e.States,this.currStateName=e.StartAt,this.currState=this.states[this.currStateName],this.rawInput={},this.currInput={},this.currResult=null,this.context={},this.stateHandlers={Task:this.handleTaskState.bind(this),Map:this.handleMapState.bind(this),Pass:this.handlePassState.bind(this),Wait:this.handleWaitState.bind(this),Choice:this.handleChoiceState.bind(this),Succeed:this.handleSucceedState.bind(this),Fail:this.handleFailState.bind(this)},this.validationOptions=t}}export{StateMachine};
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.1.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 --target es2015 --minify src/main.ts",
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": "^17.0.31",
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.1.7",
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
  }