aws-local-stepfunctions 0.1.0 → 0.2.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,153 @@
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
+ ## Features
10
+
11
+ To see a list of features that have full support, partial support, or no support, refer to [this document](/docs/feature-support.md).
12
+
13
+ ## Installation
14
+
15
+ ```sh
16
+ npm install aws-local-stepfunctions
17
+ ```
18
+
19
+ ## Importing
20
+
21
+ Currently, the only supported environment to import the package is Node.js. Browser support is not available yet.
22
+
23
+ ### Node.js
24
+
25
+ #### CommonJS
26
+
27
+ ```js
28
+ const { StateMachine } = require('aws-local-stepfunctions');
29
+ ```
30
+
31
+ #### ES Module
32
+
33
+ ```js
34
+ import { StateMachine } from 'aws-local-stepfunctions';
35
+ ```
36
+
37
+ ## API
38
+
39
+ ### Constructor: `new StateMachine(definition[, validationOptions])`
40
+
41
+ The constructor takes the following parameters:
42
+
43
+ - `definition`: The Amazon States Language definition of the state machine.
44
+ - `validationOptions` (optional): An object that specifies how the definition should be validated.
45
+ - `checkPaths`: If set to `false`, won't validate JSONPaths.
46
+ - `checkArn`: If set to `false`, won't validate ARN syntax in `Task` states.
47
+
48
+ 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.
49
+
50
+ Example:
51
+
52
+ ```js
53
+ import { StateMachine } from 'aws-local-stepfunctions';
54
+
55
+ const machineDefinition = {
56
+ Comment: 'A simple minimal example of the States language',
57
+ StartAt: 'Hello World',
58
+ States: {
59
+ 'Hello World': {
60
+ Type: 'Task',
61
+ Resource: 'arn:aws:lambda:us-east-1:123456789012:function:HelloWorld',
62
+ End: true,
63
+ },
64
+ },
65
+ };
66
+
67
+ // Instantiate a new state machine with the given definition and don't validate JSONPaths.
68
+ const stateMachine = new StateMachine(machineDefinition, { checkPaths: false });
69
+ ```
70
+
71
+ ### `async StateMachine.run(input[, options])`
72
+
73
+ Executes the state machine with the given `input` parameter and returns the result of the execution.
74
+
75
+ It takes the following parameters:
76
+
77
+ - `input`: The initial input to pass to the state machine. This can be any valid JSON value.
78
+ - `options` (optional):
79
+ - `overrides`: An object to overrides the behavior of certain states:
80
+ - `taskResourceLocalHandlers`: Overrides the resource of the specified `Task` states to run a local function.
81
+ - `waitTimeOverrides`: Overrides the wait duration of the specified `Wait` states. The specifed override duration should be in milliseconds.
82
+
83
+ Example without `options`:
84
+
85
+ ```js
86
+ import { StateMachine } from 'aws-local-stepfunctions';
87
+
88
+ const machineDefinition = {
89
+ StartAt: 'Hello World',
90
+ States: {
91
+ 'Hello World': {
92
+ Type: 'Task',
93
+ Resource: 'arn:aws:lambda:us-east-1:123456789012:function:HelloWorld',
94
+ End: true,
95
+ },
96
+ },
97
+ };
98
+
99
+ const stateMachine = new StateMachine(machineDefinition, { checkPaths: false });
100
+ const myInput = { value1: 'hello', value2: 123, value3: true };
101
+ const result = await stateMachine.run(myInput); // execute the state machine
102
+
103
+ console.log(result); // log the result of the execution
104
+ ```
105
+
106
+ Example with `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
+ Next: 'AddNumbers',
118
+ },
119
+ AddNumbers: {
120
+ Type: 'Task',
121
+ Resource: 'arn:aws:lambda:us-east-1:123456789012:function:AddNumbers',
122
+ Next: 'Wait10Seconds',
123
+ },
124
+ Wait10Seconds: {
125
+ Type: 'Wait',
126
+ Seconds: 10,
127
+ End: true,
128
+ },
129
+ },
130
+ };
131
+
132
+ function addNumbersLocal(input) {
133
+ return input.num1 + input.num2;
134
+ }
135
+
136
+ const stateMachine = new StateMachine(machineDefinition, { checkPaths: false });
137
+ const myInput = { value1: 'hello', value2: 123, value3: true };
138
+ const result = await stateMachine.run(myInput, {
139
+ overrides: {
140
+ taskResourceLocalHandlers: {
141
+ AddNumbers: addNumbersLocal, // call the `addNumbersLocal` function instead of invoking the Lambda function specified for the `AddNumbers` state
142
+ },
143
+ waitTimeOverrides: {
144
+ Wait10Seconds: 500, // wait for 500 milliseconds instead of the 10 seconds specified in the `Wait10Seconds` state
145
+ },
146
+ },
147
+ });
148
+
149
+ console.log(result); // log the result of the execution
150
+ ```
151
+
5
152
  ## License
6
153
 
7
154
  [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:
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"),pLimit=require("p-limit");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),pLimit__default=_interopDefaultLegacy(pLimit);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),y=wcmatch__default.default(e.StringMatches,{separator:!1});return y(P)}if("NumericEquals"in e){let b=r(e.Variable,t);return b===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 g=r(e.Variable,t),q=r(e.NumericLessThanPath,t);return g<q}if("NumericGreaterThan"in e){let L=r(e.Variable,t);return L>e.NumericGreaterThan}if("NumericGreaterThanPath"in e){let v=r(e.Variable,t),V=r(e.NumericGreaterThanPath,t);return v>V}if("NumericLessThanEquals"in e){let N=r(e.Variable,t);return N<=e.NumericLessThanEquals}if("NumericLessThanEqualsPath"in e){let _=r(e.Variable,t),G=r(e.NumericLessThanEqualsPath,t);return _<=G}if("NumericGreaterThanEquals"in e){let R=r(e.Variable,t);return R>=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 M=new Date(r(e.Variable,t)),$=new Date(e.TimestampEquals);return M.getTime()===$.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 J=new Date(r(e.Variable,t)),H=new Date(e.TimestampGreaterThan);return J>H}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*(){var r,a;let n=t.currState,i=new LambdaClient,s=null==e?void 0:null==(r=e.overrides)?void 0:null==(a=r.taskResourceLocalHandlers)?void 0:a[t.currStateName];try{if(s){let u=yield s(t.currInput);t.currResult=u;return}let l=yield i.invokeFunction(n.Resource,t.currInput);t.currResult=l}catch(c){throw c instanceof LambdaExecutionError?console.error(c.toString()):console.error(c),c}})()}handleMapState(e){var t=this;return _asyncToGenerator(function*(){let r=t.currState,a=t.currInput;if(r.ItemsPath&&(a=t.jsonQuery(r.ItemsPath,t.currInput)),!Array.isArray(a))return;let n=(a,n)=>{let i;t.context.Map={Item:{Index:n,Value:a}},r.Parameters&&(i=t.processPayloadTemplate(r.Parameters,t.currInput));let s=new StateMachine(r.Iterator,t.validationOptions);return s.run(null!=i?i:a,e)},i=pLimit__default.default(r.MaxConcurrency||40),s=a.map((e,t)=>i(()=>n(e,t))),u=yield Promise.all(s);delete t.context.Map,t.currResult=u})()}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(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
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;
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:
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";import u from"p-limit";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 g=r(e.Variable,t);return g<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 N=r(e.Variable,t),R=r(e.NumericGreaterThanPath,t);return N>R}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 C=r(e.Variable,t);return C===e.BooleanEquals}if("BooleanEqualsPath"in e){let $=r(e.Variable,t),_=r(e.BooleanEqualsPath,t);return $===_}if("TimestampEquals"in e){let M=new Date(r(e.Variable,t)),k=new Date(e.TimestampEquals);return M.getTime()===k.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*(){var r,a;let n=t.currState,i=new LambdaClient,s=null==e?void 0:null==(r=e.overrides)?void 0:null==(a=r.taskResourceLocalHandlers)?void 0:a[t.currStateName];try{if(s){let u=yield s(t.currInput);t.currResult=u;return}let l=yield i.invokeFunction(n.Resource,t.currInput);t.currResult=l}catch(o){throw o instanceof LambdaExecutionError?console.error(o.toString()):console.error(o),o}})()}handleMapState(e){var t=this;return _asyncToGenerator(function*(){let r=t.currState,a=t.currInput;if(r.ItemsPath&&(a=t.jsonQuery(r.ItemsPath,t.currInput)),!Array.isArray(a))return;let n=(a,n)=>{let i;t.context.Map={Item:{Index:n,Value:a}},r.Parameters&&(i=t.processPayloadTemplate(r.Parameters,t.currInput));let s=new StateMachine(r.Iterator,t.validationOptions);return s.run(null!=i?i:a,e)},i=u(r.MaxConcurrency||40),s=a.map((e,t)=>i(()=>n(e,t))),l=yield Promise.all(s);delete t.context.Map,t.currResult=l})()}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(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
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};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aws-local-stepfunctions",
3
- "version": "0.1.0",
3
+ "version": "0.2.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"
@@ -47,7 +47,7 @@
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
  }