From fac2916382035ebb9f51a653c43c057e6126ee83 Mon Sep 17 00:00:00 2001
From: zirkelc <chris.zirkel@gmail.com>
Date: Wed, 18 Dec 2024 17:53:20 +0100
Subject: [PATCH 01/13] feat: preview

---
 .github/workflows/preview.yml | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 .github/workflows/preview.yml

diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml
new file mode 100644
index 00000000..aca2c24e
--- /dev/null
+++ b/.github/workflows/preview.yml
@@ -0,0 +1,28 @@
+name: Preview
+
+on:
+  pull_request:
+
+permissions:
+  checks: write
+  id-token: write
+  contents: write
+  pull-requests: write
+
+jobs:
+  preview:
+    name: Preview
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+
+      - uses: actions/setup-node@v2.1.4
+        with:
+          node-version: 14
+
+      - run: corepack enable
+
+      - run: npm install
+
+      - name: Publish Preview
+        run: npx pkg-pr-new publish

From 9f798aa23ec71f3bbb7608fdc9d25a1fe67d6cfe Mon Sep 17 00:00:00 2001
From: zirkelc <chris.zirkel@gmail.com>
Date: Thu, 19 Dec 2024 08:32:50 +0100
Subject: [PATCH 02/13] ci: node v20

---
 .github/workflows/preview.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml
index aca2c24e..a8f65ac8 100644
--- a/.github/workflows/preview.yml
+++ b/.github/workflows/preview.yml
@@ -16,9 +16,9 @@ jobs:
     steps:
       - uses: actions/checkout@v4
 
-      - uses: actions/setup-node@v2.1.4
+      - uses: actions/setup-node@v4
         with:
-          node-version: 14
+          node-version: 20
 
       - run: corepack enable
 

From 0679e26675401a3e39546de96d9edef1b913a9c9 Mon Sep 17 00:00:00 2001
From: zirkelc <chris.zirkel@gmail.com>
Date: Thu, 19 Dec 2024 08:36:10 +0100
Subject: [PATCH 03/13] ci: legacy peer deps

---
 .github/workflows/preview.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml
index a8f65ac8..15f930d3 100644
--- a/.github/workflows/preview.yml
+++ b/.github/workflows/preview.yml
@@ -22,7 +22,7 @@ jobs:
 
       - run: corepack enable
 
-      - run: npm install
+      - run: npm install --legacy-peer-deps
 
       - name: Publish Preview
         run: npx pkg-pr-new publish

From 4862bbd119199ca68a56033f89d0d45ab4f7386b Mon Sep 17 00:00:00 2001
From: lukehedger <lh4@pm.me>
Date: Thu, 9 Jan 2025 21:37:43 +0000
Subject: [PATCH 04/13] chore: bump asl-validator to 3.11.0

---
 package-lock.json | 73 ++++++++++++++++++++++++++++++++++++++---------
 package.json      |  4 +--
 2 files changed, 61 insertions(+), 16 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index eec48433..7a170f01 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
       "license": "MIT",
       "dependencies": {
         "@serverless/utils": "^6.7.0",
-        "asl-validator": "^3.8.0",
+        "asl-validator": "^3.11.0",
         "bluebird": "^3.4.0",
         "chalk": "^4.1.2",
         "joi": "^17.7.0",
@@ -995,6 +995,30 @@
         "@jridgewell/sourcemap-codec": "^1.4.10"
       }
     },
+    "node_modules/@jsep-plugin/assignment": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.3.0.tgz",
+      "integrity": "sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 10.16.0"
+      },
+      "peerDependencies": {
+        "jsep": "^0.4.0||^1.0.0"
+      }
+    },
+    "node_modules/@jsep-plugin/regex": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.4.tgz",
+      "integrity": "sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 10.16.0"
+      },
+      "peerDependencies": {
+        "jsep": "^0.4.0||^1.0.0"
+      }
+    },
     "node_modules/@kwsites/file-exists": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz",
@@ -3197,22 +3221,24 @@
       "dev": true
     },
     "node_modules/asl-path-validator": {
-      "version": "0.12.0",
-      "resolved": "https://registry.npmjs.org/asl-path-validator/-/asl-path-validator-0.12.0.tgz",
-      "integrity": "sha512-pzBX2mKp8NQ7p1xM6sfSd2vFQJDX0UdUCun/YcRKMNSv7j93erTomK7iIU79N5rjJD++kPr9qwWhA67pFVpdhA==",
+      "version": "0.15.0",
+      "resolved": "https://registry.npmjs.org/asl-path-validator/-/asl-path-validator-0.15.0.tgz",
+      "integrity": "sha512-rIvxPZOu03VIyDSNkvrjkE8LQZFSCFLfsl43anCNjz/eEsIaCcydhbjyiNIx2dk7gKZ7LqYGeI/B3zWeaf+93Q==",
+      "license": "MIT",
       "dependencies": {
-        "jsonpath-plus": "^7.0.0"
+        "jsonpath-plus": "^10.1.0"
       }
     },
     "node_modules/asl-validator": {
-      "version": "3.8.0",
-      "resolved": "https://registry.npmjs.org/asl-validator/-/asl-validator-3.8.0.tgz",
-      "integrity": "sha512-xFIPmTS+ehk2AELWnRFHUkRyHRtt75D4AbKHmEqjD+9lZf+gNvIa/cCnABk/1f72JUuo5SoI6i2CXp2a7D08fg==",
+      "version": "3.11.0",
+      "resolved": "https://registry.npmjs.org/asl-validator/-/asl-validator-3.11.0.tgz",
+      "integrity": "sha512-MQ3mfrQiW0uE6QnWY9EMOO29GJGSqmvjiQ45u+Lg9oMBH/pb1HREiRDNSCrBLuHREJbbsZjIC28QN9xUkBZxGw==",
+      "license": "Apache-2.0",
       "dependencies": {
         "ajv": "^8.12.0",
-        "asl-path-validator": "^0.12.0",
+        "asl-path-validator": "^0.15.0",
         "commander": "^10.0.1",
-        "jsonpath-plus": "^7.2.0",
+        "jsonpath-plus": "^10.2.0",
         "yaml": "^2.3.1"
       },
       "bin": {
@@ -8874,6 +8900,15 @@
       "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==",
       "dev": true
     },
+    "node_modules/jsep": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.4.0.tgz",
+      "integrity": "sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 10.16.0"
+      }
+    },
     "node_modules/jsesc": {
       "version": "2.5.2",
       "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
@@ -9023,11 +9058,21 @@
       ]
     },
     "node_modules/jsonpath-plus": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.2.0.tgz",
-      "integrity": "sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA==",
+      "version": "10.2.0",
+      "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.2.0.tgz",
+      "integrity": "sha512-T9V+8iNYKFL2n2rF+w02LBOT2JjDnTjioaNFrxRy0Bv1y/hNsqR/EBK7Ojy2ythRHwmz2cRIls+9JitQGZC/sw==",
+      "license": "MIT",
+      "dependencies": {
+        "@jsep-plugin/assignment": "^1.3.0",
+        "@jsep-plugin/regex": "^1.0.4",
+        "jsep": "^1.4.0"
+      },
+      "bin": {
+        "jsonpath": "bin/jsonpath-cli.js",
+        "jsonpath-plus": "bin/jsonpath-cli.js"
+      },
       "engines": {
-        "node": ">=12.0.0"
+        "node": ">=18.0.0"
       }
     },
     "node_modules/JSONStream": {
diff --git a/package.json b/package.json
index ffc86b71..f4536f0c 100644
--- a/package.json
+++ b/package.json
@@ -44,11 +44,11 @@
     "sinon": "^12.0.1"
   },
   "dependencies": {
-    "joi": "^17.7.0",
     "@serverless/utils": "^6.7.0",
-    "asl-validator": "^3.8.0",
+    "asl-validator": "^3.11.0",
     "bluebird": "^3.4.0",
     "chalk": "^4.1.2",
+    "joi": "^17.7.0",
     "lodash": "^4.17.11"
   },
   "peerDependencies": {

From 1900d043b62cc86aa2fb4804dc00f1271db4e515 Mon Sep 17 00:00:00 2001
From: zirkelc <chris.zirkel@gmail.com>
Date: Fri, 24 Jan 2025 17:36:53 +0100
Subject: [PATCH 05/13] fix: iam roles for dynamodb and tests

---
 lib/deploy/stepFunctions/compileIamRole.js    |  58 ++++++++--
 .../stepFunctions/compileIamRole.test.js      | 108 ++++++------------
 2 files changed, 85 insertions(+), 81 deletions(-)

diff --git a/lib/deploy/stepFunctions/compileIamRole.js b/lib/deploy/stepFunctions/compileIamRole.js
index 864491be..8772a204 100644
--- a/lib/deploy/stepFunctions/compileIamRole.js
+++ b/lib/deploy/stepFunctions/compileIamRole.js
@@ -196,25 +196,61 @@ function getEcsPermissions() {
   }];
 }
 
+function isJsonPathParameter(state, key) {
+  const jsonPath = `${key}.$`;
+  return state.Parameters && state.Parameters[jsonPath];
+}
+
+function isJsonataArgument(state, key) {
+  return state.Arguments && state.Arguments[key] && typeof state.Arguments[key] === 'string' && state.Arguments[key].trim().startsWith('{%');
+}
+
+function getParameterOrArgument(state, key) {
+  if (state.QueryLanguage === 'JSONata') return state.Arguments && state.Arguments[key];
+
+  if (state.QueryLanguage === 'JSONPath') return state.Parameters && state.Parameters[key];
+
+  if (state.Parameters && !state.Arguments) return state.Parameters[key];
+
+  if (state.Arguments && !state.Parameters) return state.Arguments[key];
+
+  return undefined;
+}
+
+function hasParameterOrArgument(state, key) {
+  if (state.QueryLanguage === 'JSONata') return state.Arguments && state.Arguments[key];
+
+  if (state.QueryLanguage === 'JSONPath') return state.Parameters && state.Parameters[key];
+
+  // If no query language is specified, we would need to go to the top-level definition
+  // and check if the key is present at the state machine definition
+  // As workaround, we will simply check if eitehr Parameters or Arguments is present
+  if (state.Parameters && !state.Arguments) return state.Parameters[key];
+
+  if (state.Arguments && !state.Parameters) return state.Arguments[key];
+
+  return false;
+}
+
 function getDynamoDBPermissions(action, state) {
   let resource;
 
-  if (state.Parameters['TableName.$']) {
+  if (isJsonPathParameter(state, 'TableName') || isJsonataArgument(state, 'TableName')) {
     // When the TableName is only known at runtime, we
     // have to provide * permissions during deployment.
     resource = '*';
-  } else if (state.Parameters['IndexName.$'] || state.Parameters.IndexName) {
+  } else if (isJsonPathParameter(state, 'IndexName') || isJsonataArgument(state, 'IndexName')) {
+    // We must provide * here instead of state.Parameters['IndexName.$'], because we don't know
+    // which index will be targeted when we the step function runs
+    resource = getDynamoDBArn(`${getParameterOrArgument(state, 'TableName')}/index/*`);
+  } else if (hasParameterOrArgument(state, 'IndexName')) {
     // When the Parameters contain an IndexName, we have to build a
     // longer arn that includes the index.
-    const indexName = state.Parameters['IndexName.$']
-      // We must provide * here instead of state.Parameters['IndexName.$'], because we don't know
-      // which index will be targeted when we the step function runs
-      ? '*'
-      : state.Parameters.IndexName;
+    const indexName = getParameterOrArgument(state, 'IndexName');
 
-    resource = getDynamoDBArn(`${state.Parameters.TableName}/index/${indexName}`);
+    resource = getDynamoDBArn(`${getParameterOrArgument(state, 'TableName')}/index/${indexName}`);
   } else {
-    resource = getDynamoDBArn(state.Parameters.TableName);
+    resource = getDynamoDBArn(getParameterOrArgument(state, 'TableName'));
   }
 
   return [{
@@ -224,7 +260,7 @@ function getDynamoDBPermissions(action, state) {
 }
 
 function getBatchDynamoDBPermissions(action, state) {
-  if (state.Parameters['RequestItems.$']) {
+  if (isJsonPathParameter(state, 'RequestItems') || isJsonataArgument(state, 'RequestItems')) {
     // When the RequestItems object is only known at runtime,
     // we have to provide * permissions during deployment.
     return [{
@@ -236,7 +272,7 @@ function getBatchDynamoDBPermissions(action, state) {
   // table names as keys. We can use these to generate roles
   // whether the array of requests for that table is known
   // at deploy time or not
-  const tableNames = Object.keys(state.Parameters.RequestItems);
+  const tableNames = Object.keys(getParameterOrArgument(state, 'RequestItems'));
 
   return tableNames.map(tableName => ({
     action,
diff --git a/lib/deploy/stepFunctions/compileIamRole.test.js b/lib/deploy/stepFunctions/compileIamRole.test.js
index d9f76a2b..e6603ef6 100644
--- a/lib/deploy/stepFunctions/compileIamRole.test.js
+++ b/lib/deploy/stepFunctions/compileIamRole.test.js
@@ -1,12 +1,19 @@
 'use strict';
 
 const _ = require('lodash');
+const itParam = require('mocha-param');
 const expect = require('chai').expect;
 const sinon = require('sinon');
 const Serverless = require('serverless/lib/Serverless');
 const AwsProvider = require('serverless/lib/plugins/aws/provider');
 const ServerlessStepFunctions = require('./../../index');
 
+function getParamsOrArgs(queryLanguage, params, args) {
+  return queryLanguage === 'JSONPath'
+    ? { Parameters: params }
+    : { Arguments: args === undefined ? params : args };
+}
+
 describe('#compileIamRole', () => {
   let serverless;
   let serverlessStepFunctions;
@@ -536,7 +543,7 @@ describe('#compileIamRole', () => {
     expect(policy.PolicyDocument.Statement[0].Resource).to.have.lengthOf(0);
   });
 
-  it('should give dynamodb permission for only tables referenced by state machine', () => {
+  itParam('should give dynamodb permission for only tables referenced by state machine: ${value}', ['JSONPath', 'JSONata'], (queryLanguage) => {
     const helloTable = 'hello';
     const helloTableArn = {
       'Fn::Join': [
@@ -554,50 +561,42 @@ describe('#compileIamRole', () => {
       id,
       definition: {
         StartAt: 'A',
+        QueryLanguage: queryLanguage,
         States: {
           A: {
             Type: 'Task',
             Resource: resources[0],
-            Parameters: {
-              TableName: tableName,
-            },
+            ...getParamsOrArgs(queryLanguage, { TableName: tableName }),
             Next: 'B',
           },
           B: {
             Type: 'Task',
             Resource: resources[1],
-            Parameters: {
-              TableName: tableName,
-            },
+            ...getParamsOrArgs(queryLanguage, { TableName: tableName }),
             Next: 'C',
           },
           C: {
             Type: 'Task',
             Resource: 'arn:aws:states:::dynamodb:getItem',
-            Parameters: {
-              TableName: tableName,
-            },
+            ...getParamsOrArgs(queryLanguage, { TableName: tableName }),
             Next: 'D',
           },
           D: {
             Type: 'Task',
             Resource: 'arn:aws:states:::dynamodb:deleteItem',
-            Parameters: {
-              TableName: tableName,
-            },
+            ...getParamsOrArgs(queryLanguage, { TableName: tableName }),
             End: true,
           },
           E: {
             Type: 'Task',
             Resource: 'arn:aws:states:::aws-sdk:dynamodb:updateTable',
-            Parameters: {
-              TableName: tableName,
-            },
+            ...getParamsOrArgs(queryLanguage, { TableName: tableName }),
             End: true,
           },
         },
       },
     });
+
     serverless.service.stepFunctions = {
       stateMachines: {
         myStateMachine1: genStateMachine('StateMachine1', helloTable, ['arn:aws:states:::dynamodb:updateItem', 'arn:aws:states:::dynamodb:putItem']),
@@ -636,7 +635,7 @@ describe('#compileIamRole', () => {
       .to.be.deep.equal([worldTableArn]);
   });
 
-  it('should give dynamodb permission for table name imported from external stack', () => {
+  itParam('should give dynamodb permission for table name imported from external stack', ['JSONPath', 'JSONata'], (queryLanguage) => {
     // Necessary to convince the region is in the gov cloud infrastructure.
     const externalHelloTable = { 'Fn::ImportValue': 'HelloStack:Table:Name' };
     const helloTableArn = {
@@ -660,33 +659,25 @@ describe('#compileIamRole', () => {
           A: {
             Type: 'Task',
             Resource: resources[0],
-            Parameters: {
-              TableName: tableName,
-            },
+            ...getParamsOrArgs(queryLanguage, { TableName: tableName }),
             Next: 'B',
           },
           B: {
             Type: 'Task',
             Resource: resources[1],
-            Parameters: {
-              TableName: tableName,
-            },
+            ...getParamsOrArgs(queryLanguage, { TableName: tableName }),
             Next: 'C',
           },
           C: {
             Type: 'Task',
             Resource: 'arn:aws:states:::dynamodb:getItem',
-            Parameters: {
-              TableName: tableName,
-            },
+            ...getParamsOrArgs(queryLanguage, { TableName: tableName }),
             Next: 'D',
           },
           D: {
             Type: 'Task',
             Resource: 'arn:aws:states:::dynamodb:deleteItem',
-            Parameters: {
-              TableName: tableName,
-            },
+            ...getParamsOrArgs(queryLanguage, { TableName: tableName }),
             End: true,
           },
         },
@@ -731,7 +722,7 @@ describe('#compileIamRole', () => {
       .to.be.deep.equal([worldTableArn]);
   });
 
-  it('should give dynamodb permission to index table whenever IndexName is provided', () => {
+  itParam('should give dynamodb permission to index table whenever IndexName is provided: ${value}', ['JSONPath', 'JSONata'], (queryLanguage) => {
     const helloTable = 'hello';
 
     const genStateMachine = (id, tableName) => ({
@@ -742,18 +733,13 @@ describe('#compileIamRole', () => {
           A: {
             Type: 'Task',
             Resource: 'arn:aws:states:::aws-sdk:dynamodb:query',
-            Parameters: {
-              TableName: tableName,
-            },
+            ...getParamsOrArgs(queryLanguage, { TableName: tableName }),
             Next: 'B',
           },
           B: {
             Type: 'Task',
             Resource: 'arn:aws:states:::aws-sdk:dynamodb:query',
-            Parameters: {
-              TableName: tableName,
-              IndexName: 'GSI1',
-            },
+            ...getParamsOrArgs(queryLanguage, { TableName: tableName, IndexName: 'GSI1' }),
             End: true,
           },
         },
@@ -783,7 +769,7 @@ describe('#compileIamRole', () => {
     });
   });
 
-  it('should give dynamodb permission to * whenever TableName.$ is seen', () => {
+  itParam('should give dynamodb permission to * whenever TableName.$ is seen: ${value}', ['JSONPath', 'JSONata'], (queryLanguage) => {
     const helloTable = 'hello';
 
     const genStateMachine = (id, tableName) => ({
@@ -794,17 +780,13 @@ describe('#compileIamRole', () => {
           A: {
             Type: 'Task',
             Resource: 'arn:aws:states:::dynamodb:updateItem',
-            Parameters: {
-              TableName: tableName,
-            },
+            ...getParamsOrArgs(queryLanguage, { TableName: tableName }),
             Next: 'B',
           },
           B: {
             Type: 'Task',
             Resource: 'arn:aws:states:::dynamodb:updateItem',
-            Parameters: {
-              'TableName.$': '$.tableName',
-            },
+            ...getParamsOrArgs(queryLanguage, { 'TableName.$': '$.tableName' }, { TableName: '{% $tableName %}' }),
             End: true,
           },
         },
@@ -830,7 +812,7 @@ describe('#compileIamRole', () => {
     expect(policy.PolicyDocument.Statement[0].Resource).to.equal('*');
   });
 
-  it('should give dynamodb permission to table/TableName/index/* when IndexName.$ is seen', () => {
+  itParam('should give dynamodb permission to table/TableName/index/* when IndexName.$ is seen: ${value}', ['JSONPath', 'JSONata'], (queryLanguage) => {
     const helloTable = 'hello';
 
     const genStateMachine = (id, tableName) => ({
@@ -841,10 +823,10 @@ describe('#compileIamRole', () => {
           A: {
             Type: 'Task',
             Resource: 'arn:aws:states:::aws-sdk:dynamodb:query',
-            Parameters: {
+            ...getParamsOrArgs(queryLanguage, {
               TableName: tableName,
               'IndexName.$': '$.myDynamicIndexName',
-            },
+            }, { TableName: tableName, IndexName: '{% $myDynamicIndexName %}' }),
             End: true,
           },
         },
@@ -870,7 +852,7 @@ describe('#compileIamRole', () => {
     expect(policy.PolicyDocument.Statement[0].Resource[0]['Fn::Join'][1][5]).to.equal('table/hello/index/*');
   });
 
-  it('should give dynamodb permission to table/* whenever TableName.$ and IndexName.$ are seen', () => {
+  itParam('should give dynamodb permission to table/* whenever TableName.$ and IndexName.$ are seen: ${value}', ['JSONPath', 'JSONata'], (queryLanguage) => {
     const genStateMachine = id => ({
       id,
       definition: {
@@ -879,10 +861,10 @@ describe('#compileIamRole', () => {
           A: {
             Type: 'Task',
             Resource: 'arn:aws:states:::aws-sdk:dynamodb:query',
-            Parameters: {
+            ...getParamsOrArgs(queryLanguage, {
               'TableName.$': '$.myDynamicTableName',
               'IndexName.$': '$.myDynamicIndexName',
-            },
+            }, { TableName: '{% $myDynamicTableName %}', IndexName: '{% $myDynamicIndexName %}' }),
             End: true,
           },
         },
@@ -908,7 +890,7 @@ describe('#compileIamRole', () => {
     expect(policy.PolicyDocument.Statement[0].Resource[0]).to.equal('*');
   });
 
-  it('should give batch dynamodb permission for only tables referenced by state machine', () => {
+  itParam('should give batch dynamodb permission for only tables referenced by state machine: ${value}', ['JSONPath', 'JSONata'], (queryLanguage) => {
     const helloTable = 'hello';
     const helloTableArn = {
       'Fn::Join': [
@@ -930,21 +912,13 @@ describe('#compileIamRole', () => {
           A: {
             Type: 'Task',
             Resource: 'arn:aws:states:::aws-sdk:dynamodb:batchWriteItem',
-            Parameters: {
-              RequestItems: {
-                [tableName]: [],
-              },
-            },
+            ...getParamsOrArgs(queryLanguage, { RequestItems: { [tableName]: [] } }),
             Next: 'B',
           },
           B: {
             Type: 'Task',
             Resource: 'arn:aws:states:::aws-sdk:dynamodb:batchGetItem',
-            Parameters: {
-              RequestItems: {
-                [tableName]: {},
-              },
-            },
+            ...getParamsOrArgs(queryLanguage, { RequestItems: { [tableName]: {} } }),
             End: true,
           },
         },
@@ -977,7 +951,7 @@ describe('#compileIamRole', () => {
       .to.be.deep.equal([worldTableArn]);
   });
 
-  it('should give batch dynamodb permission to * whenever RequestItems.$ is seen', () => {
+  itParam('should give batch dynamodb permission to * whenever RequestItems.$ is seen: ${value}', ['JSONPath', 'JSONata'], (queryLanguage) => {
     const genStateMachine = id => ({
       id,
       definition: {
@@ -986,19 +960,13 @@ describe('#compileIamRole', () => {
           A: {
             Type: 'Task',
             Resource: 'arn:aws:states:::aws-sdk:dynamodb:batchWriteItem',
-            Parameters: {
-              RequestItems: {
-                tableName: [],
-              },
-            },
+            ...getParamsOrArgs(queryLanguage, { RequestItems: { tableName: [] } }),
             Next: 'B',
           },
           B: {
             Type: 'Task',
             Resource: 'arn:aws:states:::aws-sdk:dynamodb:batchWriteItem',
-            Parameters: {
-              'RequestItems.$': '$.requestItems',
-            },
+            ...getParamsOrArgs(queryLanguage, { 'RequestItems.$': '$.requestItems' }, { RequestItems: '{% $requestItems %}' }),
             End: true,
           },
         },

From fcc00eaa3416c4c1990995b66bc9035f3df18964 Mon Sep 17 00:00:00 2001
From: zirkelc <chris.zirkel@gmail.com>
Date: Thu, 30 Jan 2025 07:37:22 +0100
Subject: [PATCH 06/13] fix: remove preview file

---
 .github/workflows/preview.yml | 28 ----------------------------
 1 file changed, 28 deletions(-)
 delete mode 100644 .github/workflows/preview.yml

diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml
deleted file mode 100644
index 15f930d3..00000000
--- a/.github/workflows/preview.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-name: Preview
-
-on:
-  pull_request:
-
-permissions:
-  checks: write
-  id-token: write
-  contents: write
-  pull-requests: write
-
-jobs:
-  preview:
-    name: Preview
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v4
-
-      - uses: actions/setup-node@v4
-        with:
-          node-version: 20
-
-      - run: corepack enable
-
-      - run: npm install --legacy-peer-deps
-
-      - name: Publish Preview
-        run: npx pkg-pr-new publish

From 260570130018726980a3c7981ee55adfda27dd71 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 14 Feb 2025 20:10:11 +0000
Subject: [PATCH 07/13] chore(deps): bump serialize-javascript and mocha

Bumps [serialize-javascript](https://github.com/yahoo/serialize-javascript) to 6.0.2 and updates ancestor dependency [mocha](https://github.com/mochajs/mocha). These dependencies need to be updated together.


Updates `serialize-javascript` from 6.0.0 to 6.0.2
- [Release notes](https://github.com/yahoo/serialize-javascript/releases)
- [Commits](https://github.com/yahoo/serialize-javascript/compare/v6.0.0...v6.0.2)

Updates `mocha` from 9.2.2 to 11.1.0
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v9.2.2...v11.1.0)

---
updated-dependencies:
- dependency-name: serialize-javascript
  dependency-type: indirect
- dependency-name: mocha
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
---
 package-lock.json | 498 +++++++++++++++++++++++++++++++---------------
 package.json      |   2 +-
 2 files changed, 336 insertions(+), 164 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 7a170f01..7492e03b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -29,7 +29,7 @@
         "eslint-plugin-react": "^7.14.2",
         "husky": "^1.3.1",
         "lint-staged": "^13.2.1",
-        "mocha": "^9.1.3",
+        "mocha": "^11.1.0",
         "mocha-lcov-reporter": "^1.2.0",
         "mocha-param": "^2.0.0",
         "nyc": "^15.0.0",
@@ -890,6 +890,89 @@
       "deprecated": "Use @eslint/object-schema instead",
       "dev": true
     },
+    "node_modules/@isaacs/cliui": {
+      "version": "8.0.2",
+      "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+      "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "string-width": "^5.1.2",
+        "string-width-cjs": "npm:string-width@^4.2.0",
+        "strip-ansi": "^7.0.1",
+        "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+        "wrap-ansi": "^8.1.0",
+        "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+      "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/@isaacs/cliui/node_modules/string-width": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+      "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "eastasianwidth": "^0.2.0",
+        "emoji-regex": "^9.2.2",
+        "strip-ansi": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+      "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+      }
+    },
+    "node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+      "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-styles": "^6.1.0",
+        "string-width": "^5.0.1",
+        "strip-ansi": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+      }
+    },
     "node_modules/@istanbuljs/load-nyc-config": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@@ -1224,6 +1307,17 @@
         "@octokit/openapi-types": "^18.0.0"
       }
     },
+    "node_modules/@pkgjs/parseargs": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+      "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=14"
+      }
+    },
     "node_modules/@pnpm/config.env-replace": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz",
@@ -2454,11 +2548,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/@serverless/utils/node_modules/ms": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
-    },
     "node_modules/@serverless/utils/node_modules/open": {
       "version": "8.4.2",
       "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
@@ -2725,12 +2814,6 @@
       "integrity": "sha512-txGIh+0eDFzKGC25zORnswy+br1Ha7hj5cMVwKIU7+s0U2AxxJru/jZSMU6OC9MJWP6+pc/hc6ZjyZShpsyY2g==",
       "dev": true
     },
-    "node_modules/@ungap/promise-all-settled": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
-      "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
-      "dev": true
-    },
     "node_modules/2-thenable": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/2-thenable/-/2-thenable-1.0.0.tgz",
@@ -2846,10 +2929,11 @@
       }
     },
     "node_modules/ansi-colors": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
-      "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+      "version": "4.1.3",
+      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
+      "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
       "dev": true,
+      "license": "MIT",
       "engines": {
         "node": ">=6"
       }
@@ -4903,12 +4987,13 @@
       "dev": true
     },
     "node_modules/debug": {
-      "version": "4.3.4",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
-      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+      "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "ms": "2.1.2"
+        "ms": "^2.1.3"
       },
       "engines": {
         "node": ">=6.0"
@@ -7406,15 +7491,6 @@
         "lodash": "^4.17.15"
       }
     },
-    "node_modules/growl": {
-      "version": "1.10.5",
-      "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
-      "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
-      "dev": true,
-      "engines": {
-        "node": ">=4.x"
-      }
-    },
     "node_modules/handlebars": {
       "version": "4.7.7",
       "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
@@ -8847,6 +8923,22 @@
         "node": ">=8"
       }
     },
+    "node_modules/jackspeak": {
+      "version": "3.4.3",
+      "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+      "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "dependencies": {
+        "@isaacs/cliui": "^8.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      },
+      "optionalDependencies": {
+        "@pkgjs/parseargs": "^0.11.0"
+      }
+    },
     "node_modules/java-properties": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz",
@@ -10339,46 +10431,39 @@
       }
     },
     "node_modules/mocha": {
-      "version": "9.2.2",
-      "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz",
-      "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==",
-      "dev": true,
-      "dependencies": {
-        "@ungap/promise-all-settled": "1.1.2",
-        "ansi-colors": "4.1.1",
-        "browser-stdout": "1.3.1",
-        "chokidar": "3.5.3",
-        "debug": "4.3.3",
-        "diff": "5.0.0",
-        "escape-string-regexp": "4.0.0",
-        "find-up": "5.0.0",
-        "glob": "7.2.0",
-        "growl": "1.10.5",
-        "he": "1.2.0",
-        "js-yaml": "4.1.0",
-        "log-symbols": "4.1.0",
-        "minimatch": "4.2.1",
-        "ms": "2.1.3",
-        "nanoid": "3.3.1",
-        "serialize-javascript": "6.0.0",
-        "strip-json-comments": "3.1.1",
-        "supports-color": "8.1.1",
-        "which": "2.0.2",
-        "workerpool": "6.2.0",
-        "yargs": "16.2.0",
-        "yargs-parser": "20.2.4",
-        "yargs-unparser": "2.0.0"
+      "version": "11.1.0",
+      "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz",
+      "integrity": "sha512-8uJR5RTC2NgpY3GrYcgpZrsEd9zKbPDpob1RezyR2upGHRQtHWofmzTMzTMSV6dru3tj5Ukt0+Vnq1qhFEEwAg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-colors": "^4.1.3",
+        "browser-stdout": "^1.3.1",
+        "chokidar": "^3.5.3",
+        "debug": "^4.3.5",
+        "diff": "^5.2.0",
+        "escape-string-regexp": "^4.0.0",
+        "find-up": "^5.0.0",
+        "glob": "^10.4.5",
+        "he": "^1.2.0",
+        "js-yaml": "^4.1.0",
+        "log-symbols": "^4.1.0",
+        "minimatch": "^5.1.6",
+        "ms": "^2.1.3",
+        "serialize-javascript": "^6.0.2",
+        "strip-json-comments": "^3.1.1",
+        "supports-color": "^8.1.1",
+        "workerpool": "^6.5.1",
+        "yargs": "^17.7.2",
+        "yargs-parser": "^21.1.1",
+        "yargs-unparser": "^2.0.0"
       },
       "bin": {
         "_mocha": "bin/_mocha",
-        "mocha": "bin/mocha"
+        "mocha": "bin/mocha.js"
       },
       "engines": {
-        "node": ">= 12.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/mochajs"
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
       }
     },
     "node_modules/mocha-lcov-reporter": {
@@ -10396,45 +10481,22 @@
       "integrity": "sha512-TDrDAChx9XtkGmRKWGOzMoQefwHsfYUxyjNWgkfAze+EFRIRT28yJVcpcNhw9iWg2NvfeMQZnSwWCNMYwPxZew==",
       "dev": true
     },
-    "node_modules/mocha/node_modules/cliui": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
-      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
-      "dev": true,
-      "dependencies": {
-        "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.0",
-        "wrap-ansi": "^7.0.0"
-      }
-    },
-    "node_modules/mocha/node_modules/debug": {
-      "version": "4.3.3",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
-      "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+    "node_modules/mocha/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "ms": "2.1.2"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
+        "balanced-match": "^1.0.0"
       }
     },
-    "node_modules/mocha/node_modules/debug/node_modules/ms": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-      "dev": true
-    },
     "node_modules/mocha/node_modules/diff": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
-      "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
+      "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
       "dev": true,
+      "license": "BSD-3-Clause",
       "engines": {
         "node": ">=0.3.1"
       }
@@ -10467,37 +10529,58 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/mocha/node_modules/glob": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
-      "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
-      "deprecated": "Glob versions prior to v9 are no longer supported",
+    "node_modules/mocha/node_modules/foreground-child": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
+      "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
       "dev": true,
+      "license": "ISC",
       "dependencies": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.0.4",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
+        "cross-spawn": "^7.0.0",
+        "signal-exit": "^4.0.1"
       },
       "engines": {
-        "node": "*"
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/mocha/node_modules/glob": {
+      "version": "10.4.5",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+      "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "foreground-child": "^3.1.0",
+        "jackspeak": "^3.1.2",
+        "minimatch": "^9.0.4",
+        "minipass": "^7.1.2",
+        "package-json-from-dist": "^1.0.0",
+        "path-scurry": "^1.11.1"
+      },
+      "bin": {
+        "glob": "dist/esm/bin.mjs"
       },
       "funding": {
         "url": "https://github.com/sponsors/isaacs"
       }
     },
     "node_modules/mocha/node_modules/glob/node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "version": "9.0.5",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
       "dev": true,
+      "license": "ISC",
       "dependencies": {
-        "brace-expansion": "^1.1.7"
+        "brace-expansion": "^2.0.1"
       },
       "engines": {
-        "node": "*"
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
     "node_modules/mocha/node_modules/locate-path": {
@@ -10516,22 +10599,27 @@
       }
     },
     "node_modules/mocha/node_modules/minimatch": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz",
-      "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==",
+      "version": "5.1.6",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+      "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
       "dev": true,
+      "license": "ISC",
       "dependencies": {
-        "brace-expansion": "^1.1.7"
+        "brace-expansion": "^2.0.1"
       },
       "engines": {
         "node": ">=10"
       }
     },
-    "node_modules/mocha/node_modules/ms": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-      "dev": true
+    "node_modules/mocha/node_modules/minipass": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+      "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      }
     },
     "node_modules/mocha/node_modules/p-limit": {
       "version": "3.1.0",
@@ -10563,31 +10651,27 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/mocha/node_modules/yargs": {
-      "version": "16.2.0",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
-      "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+    "node_modules/mocha/node_modules/signal-exit": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+      "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
       "dev": true,
-      "dependencies": {
-        "cliui": "^7.0.2",
-        "escalade": "^3.1.1",
-        "get-caller-file": "^2.0.5",
-        "require-directory": "^2.1.1",
-        "string-width": "^4.2.0",
-        "y18n": "^5.0.5",
-        "yargs-parser": "^20.2.2"
-      },
+      "license": "ISC",
       "engines": {
-        "node": ">=10"
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
     "node_modules/mocha/node_modules/yargs-parser": {
-      "version": "20.2.4",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
-      "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
+      "version": "21.1.1",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
       "dev": true,
+      "license": "ISC",
       "engines": {
-        "node": ">=10"
+        "node": ">=12"
       }
     },
     "node_modules/modify-values": {
@@ -10600,10 +10684,10 @@
       }
     },
     "node_modules/ms": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-      "dev": true
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+      "license": "MIT"
     },
     "node_modules/mute-stream": {
       "version": "0.0.8",
@@ -10617,18 +10701,6 @@
       "dev": true,
       "optional": true
     },
-    "node_modules/nanoid": {
-      "version": "3.3.1",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
-      "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
-      "dev": true,
-      "bin": {
-        "nanoid": "bin/nanoid.cjs"
-      },
-      "engines": {
-        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
-      }
-    },
     "node_modules/napi-build-utils": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
@@ -14526,6 +14598,13 @@
         "node": ">=8"
       }
     },
+    "node_modules/package-json-from-dist": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+      "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+      "dev": true,
+      "license": "BlueOak-1.0.0"
+    },
     "node_modules/package-json/node_modules/registry-auth-token": {
       "version": "4.2.2",
       "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.2.tgz",
@@ -14638,6 +14717,30 @@
       "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
       "dev": true
     },
+    "node_modules/path-scurry": {
+      "version": "1.11.1",
+      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+      "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "dependencies": {
+        "lru-cache": "^10.2.0",
+        "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/path-scurry/node_modules/lru-cache": {
+      "version": "10.4.3",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+      "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+      "dev": true,
+      "license": "ISC"
+    },
     "node_modules/path-to-regexp": {
       "version": "1.8.0",
       "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
@@ -15169,6 +15272,7 @@
       "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
       "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
         "safe-buffer": "^5.1.0"
       }
@@ -16197,10 +16301,11 @@
       }
     },
     "node_modules/serialize-javascript": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
-      "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+      "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
       "dev": true,
+      "license": "BSD-3-Clause",
       "dependencies": {
         "randombytes": "^2.1.0"
       }
@@ -17052,6 +17157,39 @@
         "node": ">=8"
       }
     },
+    "node_modules/string-width-cjs": {
+      "name": "string-width",
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/string-width-cjs/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/string-width/node_modules/emoji-regex": {
       "version": "8.0.0",
       "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -17140,6 +17278,20 @@
         "node": ">=8"
       }
     },
+    "node_modules/strip-ansi-cjs": {
+      "name": "strip-ansi",
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/strip-bom": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
@@ -18513,10 +18665,11 @@
       "dev": true
     },
     "node_modules/workerpool": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
-      "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==",
-      "dev": true
+      "version": "6.5.1",
+      "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz",
+      "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==",
+      "dev": true,
+      "license": "Apache-2.0"
     },
     "node_modules/wrap-ansi": {
       "version": "7.0.0",
@@ -18534,6 +18687,25 @@
         "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
       }
     },
+    "node_modules/wrap-ansi-cjs": {
+      "name": "wrap-ansi",
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+      }
+    },
     "node_modules/wrappy": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
diff --git a/package.json b/package.json
index f4536f0c..47228925 100644
--- a/package.json
+++ b/package.json
@@ -35,7 +35,7 @@
     "eslint-plugin-react": "^7.14.2",
     "husky": "^1.3.1",
     "lint-staged": "^13.2.1",
-    "mocha": "^9.1.3",
+    "mocha": "^11.1.0",
     "mocha-lcov-reporter": "^1.2.0",
     "mocha-param": "^2.0.0",
     "nyc": "^15.0.0",

From 59403cd56dfa0ba7bb3268b1c48b3e2e46a5cf26 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 18 Feb 2025 22:43:05 +0000
Subject: [PATCH 08/13] chore(deps): bump jsonpath-plus from 10.2.0 to 10.3.0

Bumps [jsonpath-plus](https://github.com/s3u/JSONPath) from 10.2.0 to 10.3.0.
- [Release notes](https://github.com/s3u/JSONPath/releases)
- [Changelog](https://github.com/JSONPath-Plus/JSONPath/blob/main/CHANGES.md)
- [Commits](https://github.com/s3u/JSONPath/compare/v10.2.0...v10.3.0)

---
updated-dependencies:
- dependency-name: jsonpath-plus
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
---
 package-lock.json | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 7a170f01..1d44aef0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9058,9 +9058,9 @@
       ]
     },
     "node_modules/jsonpath-plus": {
-      "version": "10.2.0",
-      "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.2.0.tgz",
-      "integrity": "sha512-T9V+8iNYKFL2n2rF+w02LBOT2JjDnTjioaNFrxRy0Bv1y/hNsqR/EBK7Ojy2ythRHwmz2cRIls+9JitQGZC/sw==",
+      "version": "10.3.0",
+      "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.3.0.tgz",
+      "integrity": "sha512-8TNmfeTCk2Le33A3vRRwtuworG/L5RrgMvdjhKZxvyShO+mBu2fP50OWUjRLNtvw344DdDarFh9buFAZs5ujeA==",
       "license": "MIT",
       "dependencies": {
         "@jsep-plugin/assignment": "^1.3.0",

From cd896bac2095dfae28bc5839925feea0c63bb3dd Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 1 May 2025 10:35:01 +0200
Subject: [PATCH 09/13] chore(deps-dev): bump tar-fs from 1.16.3 to 1.16.4
 (#646)

Bumps [tar-fs](https://github.com/mafintosh/tar-fs) from 1.16.3 to 1.16.4.
- [Commits](https://github.com/mafintosh/tar-fs/compare/v1.16.3...v1.16.4)

---
updated-dependencies:
- dependency-name: tar-fs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
 package-lock.json | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 70c8e80d..d854c8cd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17763,10 +17763,11 @@
       }
     },
     "node_modules/tar-fs": {
-      "version": "1.16.3",
-      "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz",
-      "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==",
+      "version": "1.16.4",
+      "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.4.tgz",
+      "integrity": "sha512-u3XczWoYAIVXe5GOKK6+VeWaHjtc47W7hyuTo3+4cNakcCcuDmlkYiiHEsECwTkcI3h1VUgtwBQ54+RvY6cM4w==",
       "dev": true,
+      "license": "MIT",
       "optional": true,
       "dependencies": {
         "chownr": "^1.0.1",

From 02c6177aa092bcc255d524784fcf094fcbcb5b40 Mon Sep 17 00:00:00 2001
From: Chris <chris.zirkel@gmail.com>
Date: Thu, 1 May 2025 10:46:33 +0200
Subject: [PATCH 10/13] chore: update ubuntu image (#649)

---
 .github/workflows/config.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/config.yml b/.github/workflows/config.yml
index 9a1ad05e..3248dada 100644
--- a/.github/workflows/config.yml
+++ b/.github/workflows/config.yml
@@ -4,7 +4,7 @@ on: [push, pull_request]
 
 jobs:
   test:
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v4
       - uses: actions/setup-node@v4

From 6e9847b6929de043147dc8a9903772ff67a06d94 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alex=20J=C3=A4ger?= <lxhunter@users.noreply.github.com>
Date: Sat, 3 May 2025 05:55:59 +0200
Subject: [PATCH 11/13] feat: add multiple custom templates (#632)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* feat: add multiple custom templates

* fix: indentation

* fix: responseParameters were not working as expected

---------

Co-authored-by: Alex Jäger <alexander.jaeger@the-fittest.de>
---
 README.md                                    | 241 +++++++++++--------
 lib/deploy/events/apiGateway/methods.js      |  65 +++--
 lib/deploy/events/apiGateway/methods.test.js | 147 +++++++++++
 3 files changed, 332 insertions(+), 121 deletions(-)

diff --git a/README.md b/README.md
index d16aab3b..3a6fd5e5 100644
--- a/README.md
+++ b/README.md
@@ -9,67 +9,67 @@ Serverless Framework v2.32.0 or later is required.
 
 ## TOC
 
- - [Install](#install)
- - [Setup](#Setup)
-     - [Adding a custom name for a state machine](#adding-a-custom-name-for-a-statemachine)
-     - [Adding a custom logical id for a stateMachine](#adding-a-custom-logical-id-for-a-statemachine)
-     - [Depending on another logical id](#depending-on-another-logical-id)
-     - [Adding retain property for a state machine](#adding-retain-property-for-a-statemachine)
-     - [CloudWatch Alarms](#cloudwatch-alarms)
-     - [CloudWatch Notifications](#cloudwatch-notifications)
-     - [Blue-Green deployments](#blue-green-deployment)
-     - [Pre-deployment validation](#pre-deployment-validation)
-     - [Express Workflow](#express-workflow)
-     - [CloudWatch Logs](#cloudwatch-logs)
-     - [X-Ray](#x-ray)
- - [Current Gotcha](#current-gotcha)
- - [Events](#events)
-     - [API Gateway](#api-gateway)
-         - [Simple HTTP endpoint](#simple-http-endpoint)
-         - [Custom Step Functions Action](#custom-step-functions-action)
-         - [HTTP Endpoint with custom IAM Role](#http-endpoint-with-custom-iam-role)
-         - [Share API Gateway and API Resources](#share-api-gateway-and-api-resources)
-         - [Enabling CORS](#enabling-cors)
-         - [HTTP Endpoints with AWS_IAM Authorizers](#http-endpoints-with-aws_iam-authorizers)
-         - [HTTP Endpoints with Custom Authorizers](#http-endpoints-with-custom-authorizers)
-         - [Shared Authorizer](#shared-authorizer)
-         - [LAMBDA_PROXY request template](#lambda_proxy-request-template)
-         - [Customizing request body mapping templates](#customizing-request-body-mapping-templates)
-         - [Customizing response headers and templates](#customizing-response-headers-and-templates)
-         - [Send request to an API](#send-request-to-an-api)
-         - [Setting API keys for your Rest API](#setting-api-keys-for-your-rest-api)
-         - [Request Schema Validators](#request-schema-validators)
-     - [Schedule](#schedule)
-         - [Enabling / Disabling](#enabling--disabling)
-         - [Specify Name and Description](#specify-name-and-description)
-         - [Scheduled Events IAM Role](#scheduled-events-iam-role)
-         - [Specify InputTransformer](#specify-inputtransformer)
-         - [Use EventBridge Scheduler instead of EventBridge rules](#use-eventbridge-scheduler-instead-of-eventbridge-rules)
-     - [CloudWatch Event](#cloudwatch-event)
-         - [Simple event definition](#simple-event-definition)
-         - [Enabling / Disabling](#enabling--disabling-1)
-         - [Specify Input or Inputpath or InputTransformer](#specify-input-or-inputpath-or-inputtransformer)
-         - [Specifying a Description](#specifying-a-description)
-         - [Specifying a Name](#specifying-a-name)
-         - [Specifying a RoleArn](#specifying-a-rolearn)
-         - [Specifying a custom CloudWatch EventBus](#specifying-a-custom-cloudwatch-eventbus)
-         - [Specifying a custom EventBridge EventBus](#specifying-a-custom-eventbridge-eventbus)
-         - [Specifying a DeadLetterQueue](#specifying-a-deadletterqueue)
- - [Tags](#tags)
- - [Commands](#commands)
-     - [deploy](#deploy)
-     - [invoke](#invoke)
- - [IAM Role](#iam-role)
- - [Tips](#tips)
-     - [How to specify the stateMachine ARN to environment variables](#how-to-specify-the-statemachine-arn-to-environment-variables)
-     - [How to split up state machines into files](#how-to-split-up-state-machines-into-files)
- - [Sample statemachines setting in serverless.yml](#sample-statemachines-setting-in-serverlessyml)
-     - [Wait State](#wait-state)
-     - [Retry Failure](#retry-failure)
-     - [Parallel](#parallel)
-     - [Catch Failure](#catch-failure)
-     - [Choice](#choice)
-     - [Map](#map)
+- [Install](#install)
+- [Setup](#Setup)
+  - [Adding a custom name for a state machine](#adding-a-custom-name-for-a-statemachine)
+  - [Adding a custom logical id for a stateMachine](#adding-a-custom-logical-id-for-a-statemachine)
+  - [Depending on another logical id](#depending-on-another-logical-id)
+  - [Adding retain property for a state machine](#adding-retain-property-for-a-statemachine)
+  - [CloudWatch Alarms](#cloudwatch-alarms)
+  - [CloudWatch Notifications](#cloudwatch-notifications)
+  - [Blue-Green deployments](#blue-green-deployment)
+  - [Pre-deployment validation](#pre-deployment-validation)
+  - [Express Workflow](#express-workflow)
+  - [CloudWatch Logs](#cloudwatch-logs)
+  - [X-Ray](#x-ray)
+- [Current Gotcha](#current-gotcha)
+- [Events](#events)
+  - [API Gateway](#api-gateway)
+    - [Simple HTTP endpoint](#simple-http-endpoint)
+    - [Custom Step Functions Action](#custom-step-functions-action)
+    - [HTTP Endpoint with custom IAM Role](#http-endpoint-with-custom-iam-role)
+    - [Share API Gateway and API Resources](#share-api-gateway-and-api-resources)
+    - [Enabling CORS](#enabling-cors)
+    - [HTTP Endpoints with AWS_IAM Authorizers](#http-endpoints-with-aws_iam-authorizers)
+    - [HTTP Endpoints with Custom Authorizers](#http-endpoints-with-custom-authorizers)
+    - [Shared Authorizer](#shared-authorizer)
+    - [LAMBDA_PROXY request template](#lambda_proxy-request-template)
+    - [Customizing request body mapping templates](#customizing-request-body-mapping-templates)
+    - [Customizing response headers and templates](#customizing-response-headers-and-templates)
+    - [Send request to an API](#send-request-to-an-api)
+    - [Setting API keys for your Rest API](#setting-api-keys-for-your-rest-api)
+    - [Request Schema Validators](#request-schema-validators)
+  - [Schedule](#schedule)
+    - [Enabling / Disabling](#enabling--disabling)
+    - [Specify Name and Description](#specify-name-and-description)
+    - [Scheduled Events IAM Role](#scheduled-events-iam-role)
+    - [Specify InputTransformer](#specify-inputtransformer)
+    - [Use EventBridge Scheduler instead of EventBridge rules](#use-eventbridge-scheduler-instead-of-eventbridge-rules)
+  - [CloudWatch Event](#cloudwatch-event)
+    - [Simple event definition](#simple-event-definition)
+    - [Enabling / Disabling](#enabling--disabling-1)
+    - [Specify Input or Inputpath or InputTransformer](#specify-input-or-inputpath-or-inputtransformer)
+    - [Specifying a Description](#specifying-a-description)
+    - [Specifying a Name](#specifying-a-name)
+    - [Specifying a RoleArn](#specifying-a-rolearn)
+    - [Specifying a custom CloudWatch EventBus](#specifying-a-custom-cloudwatch-eventbus)
+    - [Specifying a custom EventBridge EventBus](#specifying-a-custom-eventbridge-eventbus)
+    - [Specifying a DeadLetterQueue](#specifying-a-deadletterqueue)
+- [Tags](#tags)
+- [Commands](#commands)
+  - [deploy](#deploy)
+  - [invoke](#invoke)
+- [IAM Role](#iam-role)
+- [Tips](#tips)
+  - [How to specify the stateMachine ARN to environment variables](#how-to-specify-the-statemachine-arn-to-environment-variables)
+  - [How to split up state machines into files](#how-to-split-up-state-machines-into-files)
+- [Sample statemachines setting in serverless.yml](#sample-statemachines-setting-in-serverlessyml)
+  - [Wait State](#wait-state)
+  - [Retry Failure](#retry-failure)
+  - [Parallel](#parallel)
+  - [Catch Failure](#catch-failure)
+  - [Choice](#choice)
+  - [Map](#map)
 
 ## Install
 
@@ -425,8 +425,8 @@ stepFunctions:
           - lambda: LAMBDA_FUNCTION_ARN
           - kinesis: KINESIS_STREAM_ARN
           - kinesis:
-               arn: KINESIS_STREAM_ARN
-               partitionKeyPath: $.id # used to choose the parition key from payload
+              arn: KINESIS_STREAM_ARN
+              partitionKeyPath: $.id # used to choose the parition key from payload
           - firehose: FIREHOSE_STREAM_ARN
           - stepFunctions: STATE_MACHINE_ARN
         FAILED:
@@ -790,7 +790,7 @@ stepFunctions:
     createUser:
       ...
       events:
-        - http:
+          - http:
             path: /users
             ...
             authorizer:
@@ -873,6 +873,43 @@ stepFunctions:
       definition:
 ```
 
+If you want to add multiple custom templates for different status codes, headers and content types, you can do so by including them in the `responses` object like so:
+
+```yml
+
+stepFunctions:
+  stateMachines:
+    hello:
+      events:
+        - http:
+            path: posts/create
+            method: POST
+            responses:
+              200:
+                statusCode: 200
+                responseParameters:
+                  method.response.header.Content-Type: "'application/json'"
+                  method.response.header.X-Application-Id: "'my-app'"
+                responseTemplates:
+                  application/json: |
+                    {
+                      "status": 200,
+                      "info": "OK"
+                    }
+              400:
+                statusCode: 400
+                responseParameters:
+                  method.response.header.Content-Type: "'application/json'"
+                  method.response.header.X-Application-Id: "'my-app'"
+                responseTemplates:
+                  application/json: |
+                    {
+                      "status": 400,
+                      "info": "Bad Request"
+                    }
+      definition:
+```
+
 #### Send request to an API
 
 You can input an value as json in request body, the value is passed as the input value of your statemachine
@@ -982,7 +1019,7 @@ provider:
             name: PostCreateModel
             schema: ${file(api_schema/post_add_schema.json)}
             description: "A Model validation for adding posts"
- 
+
 stepFunctions:
   stateMachines:
     create:
@@ -1089,10 +1126,10 @@ stepFunctions:
   stateMachines:
     stateMachineScheduled:
       events:
-        - schedule: 
+        - schedule:
             rate: cron(30 12 ? * 1-5 *)
             inputTransformer:
-              inputPathsMap: 
+              inputPathsMap:
                 time: '$.time'
                 stage: '$.stageVariables'
               inputTemplate: '{"time": <time>, "stage" : <stage> }'
@@ -1424,8 +1461,8 @@ Then
 # to get the Arn of the 1st EventBridge rule
 !GetAtt Hellostepfunc1EventsRuleCloudWatchEvent1.Arn
 
-# to get the Arn of the 2nd EventBridge rule
-!GetAtt Hellostepfunc1EventsRuleCloudWatchEvent2.Arn
+  # to get the Arn of the 2nd EventBridge rule
+  !GetAtt Hellostepfunc1EventsRuleCloudWatchEvent2.Arn
 ```
 
 ## Tags
@@ -1505,12 +1542,12 @@ resources:
         Path: /path_of_state_machine_roles/
         AssumeRolePolicyDocument:
           Statement:
-          - Effect: Allow
-            Principal:
-              Service:
-                - states.amazonaws.com
-            Action:
-              - sts:AssumeRole
+            - Effect: Allow
+              Principal:
+                Service:
+                  - states.amazonaws.com
+              Action:
+                - sts:AssumeRole
         Policies:
           - PolicyName: statePolicy
             PolicyDocument:
@@ -1740,21 +1777,21 @@ stepFunctions:
             Type: Parallel
             Next: Final State
             Branches:
-            - StartAt: Wait 20s
-              States:
-                Wait 20s:
-                  Type: Wait
-                  Seconds: 20
-                  End: true
-            - StartAt: Pass
-              States:
-                Pass:
-                  Type: Pass
-                  Next: Wait 10s
-                Wait 10s:
-                  Type: Wait
-                  Seconds: 10
-                  End: true
+              - StartAt: Wait 20s
+                States:
+                  Wait 20s:
+                    Type: Wait
+                    Seconds: 20
+                    End: true
+              - StartAt: Pass
+                States:
+                  Pass:
+                    Type: Pass
+                    Next: Wait 10s
+                  Wait 10s:
+                    Type: Wait
+                    Seconds: 10
+                    End: true
           Final State:
             Type: Pass
             End: true
@@ -1782,12 +1819,12 @@ stepFunctions:
             Resource:
               Fn::GetAtt: [hello, Arn]
             Catch:
-            - ErrorEquals: ["HandledError"]
-              Next: CustomErrorFallback
-            - ErrorEquals: ["States.TaskFailed"]
-              Next: ReservedTypeFallback
-            - ErrorEquals: ["States.ALL"]
-              Next: CatchAllFallback
+              - ErrorEquals: ["HandledError"]
+                Next: CustomErrorFallback
+              - ErrorEquals: ["States.TaskFailed"]
+                Next: ReservedTypeFallback
+              - ErrorEquals: ["States.ALL"]
+                Next: CatchAllFallback
             End: true
           CustomErrorFallback:
             Type: Pass
@@ -1834,12 +1871,12 @@ stepFunctions:
           ChoiceState:
             Type: Choice
             Choices:
-            - Variable: "$.foo"
-              NumericEquals: 1
-              Next: FirstMatchState
-            - Variable: "$.foo"
-              NumericEquals: 2
-              Next: SecondMatchState
+              - Variable: "$.foo"
+                NumericEquals: 1
+                Next: FirstMatchState
+              - Variable: "$.foo"
+                NumericEquals: 2
+                Next: SecondMatchState
             Default: DefaultState
           FirstMatchState:
             Type: Task
diff --git a/lib/deploy/events/apiGateway/methods.js b/lib/deploy/events/apiGateway/methods.js
index 3bb894f5..bad6476a 100644
--- a/lib/deploy/events/apiGateway/methods.js
+++ b/lib/deploy/events/apiGateway/methods.js
@@ -103,6 +103,13 @@ const LAMBDA_PROXY_FORM_URL_ENCODED_REQUEST_TEMPLATE = `
   #end
   ${LAMBDA_PROXY_REQUEST_TEMPLATE}`;
 
+function generateResponseParameters(responseHeaders) {
+  return _.mapKeys(
+    responseHeaders,
+    (value, key) => `method.response.header.${key}`,
+  );
+}
+
 module.exports = {
 
   compileMethods() {
@@ -186,29 +193,49 @@ module.exports = {
       ),
     };
 
-    const responseParams = _.mapKeys(
-      _.get(http, 'response.headers', {}),
-      (value, key) => `method.response.header.${key}`,
-    );
-    const responseTemplates = _.get(http, 'response.template', {});
-
-    const integrationResponse = {
-      IntegrationResponses: [
-        {
-          StatusCode: 200,
-          SelectionPattern: 200,
-          ResponseParameters: responseParams,
-          ResponseTemplates: responseTemplates,
+    let responses;
+
+    if (_.has(http, 'responses')) {
+      responses = _.get(http, 'responses', {});
+    } else {
+      const response = _.get(http, 'response');
+      const responseHeaders = _.get(response, 'headers', {});
+      const responseTemplates = _.get(response, 'template', {});
+      const responseParameters = generateResponseParameters(responseHeaders);
+      responses = {
+        200: {
+          statusCode: 200,
+          selectionPattern: 200,
+          responseParameters,
+          responseTemplates,
         },
-        {
-          StatusCode: 400,
-          SelectionPattern: 400,
-          ResponseParameters: {},
-          ResponseTemplates: {},
+        400: {
+          statusCode: 400,
+          selectionPattern: 400,
+          responseParameters: {},
+          responseTemplates: {},
         },
-      ],
+      };
+    }
+
+    const integrationResponse = {
+      IntegrationResponses: [],
     };
 
+    _.forOwn(responses, (value, key) => {
+      const responseParameters = _.get(value, 'responseParameters', {});
+      const responseTemplates = _.get(value, 'responseTemplates', {});
+      const statusCode = _.get(value, 'statusCode', _.toInteger(key));
+      const selectionPattern = _.get(value, 'selectionPattern', _.toInteger(key));
+
+      integrationResponse.IntegrationResponses.push({
+        StatusCode: statusCode,
+        SelectionPattern: selectionPattern,
+        ResponseParameters: responseParameters,
+        ResponseTemplates: responseTemplates,
+      });
+    });
+
     if (http && http.cors) {
       let origin = http.cors.origin;
       if (http.cors.origins && http.cors.origins.length) {
diff --git a/lib/deploy/events/apiGateway/methods.test.js b/lib/deploy/events/apiGateway/methods.test.js
index ad0e6e85..8dc81999 100644
--- a/lib/deploy/events/apiGateway/methods.test.js
+++ b/lib/deploy/events/apiGateway/methods.test.js
@@ -191,8 +191,155 @@ describe('#methods()', () => {
         expect(intResponseParams['method.response.header.X-Application-Id'])
           .to.be.equal('id');
       });
+
+    it('should return custom headers and template when given',
+      () => {
+        const httpWithResponseHeaders = {
+          path: 'foo/bar1',
+          method: 'post',
+          response: {
+            headers: {
+              'Content-Type': 'text',
+              'X-Application-Id': 'id',
+            },
+            template: {
+              'application/json': 'custom template',
+            },
+          },
+        };
+        const resource = serverlessStepFunctions
+          .getMethodIntegration('stateMachine', undefined, httpWithResponseHeaders);
+
+        const integrationResponses = resource
+          .Properties.Integration.IntegrationResponses
+          .find(x => x.StatusCode === 200);
+        expect(integrationResponses.ResponseParameters['method.response.header.Content-Type'])
+          .to.be.equal('text');
+        expect(integrationResponses.ResponseParameters['method.response.header.X-Application-Id'])
+          .to.be.equal('id');
+        expect(integrationResponses.ResponseTemplates['application/json'])
+          .to.be.equal('custom template');
+      });
+
+    it('should return a custom template for application/json when responses are given',
+      () => {
+        const httpWithResponseTemplate = {
+          path: 'foo/bar1',
+          method: 'post',
+          responses: {
+            200: {
+              statusCode: 200,
+              responseTemplates: {
+                'application/json': 'custom template',
+              },
+            },
+          },
+        };
+        const resource = serverlessStepFunctions
+          .getMethodIntegration('stateMachine', undefined, httpWithResponseTemplate);
+        const responseTemplates = resource
+          .Properties.Integration.IntegrationResponses
+          .find(x => x.StatusCode === 200)
+          .ResponseTemplates;
+        expect(responseTemplates['application/json'])
+          .to.be.equal('custom template');
+      });
+
+    it('should return multiple custom templates for application/json when responses are given',
+      () => {
+        const httpWithResponseTemplate = {
+          path: 'foo/bar1',
+          method: 'post',
+          responses: {
+            200: {
+              statusCode: 200,
+              responseTemplates: {
+                'application/json': 'custom 200 template',
+              },
+            },
+            400: {
+              statusCode: 400,
+              responseTemplates: {
+                'application/json': 'custom 400 template',
+              },
+            },
+          },
+        };
+        const resource = serverlessStepFunctions
+          .getMethodIntegration('stateMachine', undefined, httpWithResponseTemplate);
+        const response200Templates = resource
+          .Properties.Integration.IntegrationResponses
+          .find(x => x.StatusCode === 200)
+          .ResponseTemplates;
+        expect(response200Templates['application/json'])
+          .to.be.equal('custom 200 template');
+        const response400Templates = resource
+          .Properties.Integration.IntegrationResponses
+          .find(x => x.StatusCode === 400)
+          .ResponseTemplates;
+        expect(response400Templates['application/json'])
+          .to.be.equal('custom 400 template');
+      });
+
+    it('should return custom headers when when responses are given',
+      () => {
+        const httpWithResponseHeaders = {
+          path: 'foo/bar1',
+          method: 'post',
+          responses: {
+            200: {
+              responseParameters: {
+                'method.response.header.Content-Type': 'text',
+                'method.response.header.X-Application-Id': 'id',
+              },
+            },
+          },
+        };
+        const resource = serverlessStepFunctions
+          .getMethodIntegration('stateMachine', undefined, httpWithResponseHeaders);
+
+        const intResponseParams = resource
+          .Properties.Integration.IntegrationResponses
+          .find(x => x.StatusCode === 200)
+          .ResponseParameters;
+        expect(intResponseParams['method.response.header.Content-Type'])
+          .to.be.equal('text');
+        expect(intResponseParams['method.response.header.X-Application-Id'])
+          .to.be.equal('id');
+      });
   });
 
+  it('should return custom headers and template when responses are given',
+    () => {
+      const httpWithResponseHeaders = {
+        path: 'foo/bar1',
+        method: 'post',
+        responses: {
+          200: {
+            responseParameters: {
+              'method.response.header.Content-Type': 'application/json',
+              'method.response.header.X-Application-Id': 'id',
+            },
+            responseTemplates: {
+              'application/json': 'custom template',
+            },
+          },
+        },
+      };
+      const resource = serverlessStepFunctions
+        .getMethodIntegration('stateMachine', undefined, httpWithResponseHeaders);
+
+      const integrationResponses = resource
+        .Properties.Integration.IntegrationResponses
+        .find(x => x.StatusCode === 200);
+      expect(integrationResponses.ResponseParameters['method.response.header.Content-Type'])
+        .to.be.equal('application/json');
+      expect(integrationResponses.ResponseParameters['method.response.header.X-Application-Id'])
+        .to.be.equal('id');
+      expect(integrationResponses.ResponseTemplates['application/json'])
+        .to.be.equal('custom template');
+    });
+
   describe('#getIntegrationRequestTemplates()', () => {
     it('should set stateMachinelogical ID in default templates when customName is not set', () => {
       const requestTemplates = serverlessStepFunctions

From c7e7eafe0c414eed8b2364dea46539e4fca2bc7b Mon Sep 17 00:00:00 2001
From: Edvaldo Szymonek <edvaldoszy@gmail.com>
Date: Sat, 3 May 2025 01:27:56 -0300
Subject: [PATCH 12/13] feat: support `Arguments` for Lambda when query
 language is JSONata (#645)

* fix: correctly resolve lambda function name from Arguments or Parameters

* test: use itParam to test both JSONPath and JSONata scenarios

* fix: lambda permissions for jsonata

---------

Co-authored-by: zirkelc <chris.zirkel@gmail.com>
---
 lib/deploy/stepFunctions/compileIamRole.js    |  18 ++-
 .../stepFunctions/compileIamRole.test.js      | 141 ++++++++++++++----
 2 files changed, 123 insertions(+), 36 deletions(-)

diff --git a/lib/deploy/stepFunctions/compileIamRole.js b/lib/deploy/stepFunctions/compileIamRole.js
index 8772a204..90ec17eb 100644
--- a/lib/deploy/stepFunctions/compileIamRole.js
+++ b/lib/deploy/stepFunctions/compileIamRole.js
@@ -360,9 +360,18 @@ function getRedshiftDataPermissions(action, state) {
 }
 
 function getLambdaPermissions(state) {
+  if (isJsonPathParameter(state, 'FunctionName') || isJsonataArgument(state, 'FunctionName')) {
+    const allowedFunctions = getParameterOrArgument(state, 'AllowedFunctions');
+    return [{
+      action: 'lambda:InvokeFunction',
+      resource: allowedFunctions || '*',
+    }];
+  }
+
   // function name can be name-only, name-only with alias, full arn or partial arn
   // https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestParameters
-  const functionName = state.Parameters.FunctionName;
+  const functionName = getParameterOrArgument(state, 'FunctionName');
+
   if (_.isString(functionName)) {
     const segments = functionName.split(':');
 
@@ -429,13 +438,6 @@ function getLambdaPermissions(state) {
     }];
   }
 
-  if (state.Parameters['FunctionName.$']) {
-    return [{
-      action: 'lambda:InvokeFunction',
-      resource: state.Parameters.AllowedFunctions ? state.Parameters.AllowedFunctions : '*',
-    }];
-  }
-
   // hope for the best...
   return [{
     action: 'lambda:InvokeFunction',
diff --git a/lib/deploy/stepFunctions/compileIamRole.test.js b/lib/deploy/stepFunctions/compileIamRole.test.js
index e6603ef6..07729863 100644
--- a/lib/deploy/stepFunctions/compileIamRole.test.js
+++ b/lib/deploy/stepFunctions/compileIamRole.test.js
@@ -3587,7 +3587,49 @@ describe('#compileIamRole', () => {
     ]);
   });
 
-  it('should support variable FunctionName', () => {
+  itParam('should resolve FunctionName: ${value}', ['JSONPath', 'JSONata'], (queryLanguage) => {
+    serverless.service.stepFunctions = {
+      stateMachines: {
+        myStateMachine1: {
+          id: 'StateMachine1',
+          definition: {
+            StartAt: 'A',
+            States: {
+              A: {
+                Type: 'Task',
+                Resource: 'arn:aws:states:::lambda:invoke',
+                ...getParamsOrArgs(
+                  queryLanguage,
+                  {
+                    FunctionName: 'arn:aws:lambda:us-west-2:1234567890:function:foo',
+                    'Payload.$': '$.Payload',
+                  },
+                  {
+                    FunctionName: 'arn:aws:lambda:us-west-2:1234567890:function:foo',
+                    Payload: '{% $states.input.Payload %}',
+                  },
+                ),
+                End: true,
+              },
+            },
+          },
+        },
+      },
+    };
+
+    serverlessStepFunctions.compileIamRole();
+    const statements = serverlessStepFunctions.serverless.service
+      .provider.compiledCloudFormationTemplate.Resources.StateMachine1Role
+      .Properties.Policies[0].PolicyDocument.Statement;
+    const lambdaPermissions = statements.filter(s => _.isEqual(s.Action, ['lambda:InvokeFunction']));
+    expect(lambdaPermissions).to.have.lengthOf(1);
+    expect(lambdaPermissions[0].Resource).to.deep.equal([
+      'arn:aws:lambda:us-west-2:1234567890:function:foo',
+      'arn:aws:lambda:us-west-2:1234567890:function:foo:*',
+    ]);
+  });
+
+  itParam('should support variable FunctionName: ${value}', ['JSONPath', 'JSONata'], (queryLanguage) => {
     serverless.service.stepFunctions = {
       stateMachines: {
         myStateMachine1: {
@@ -3598,26 +3640,47 @@ describe('#compileIamRole', () => {
               A: {
                 Type: 'Task',
                 Resource: 'arn:aws:states:::lambda:invoke.waitForTaskToken',
-                Parameters: {
-                  'FunctionName.$': '$.functionName',
-                  Payload: {
-                    'model.$': '$.new_model',
-                    'token.$': '$$.Task.Token',
+                ...getParamsOrArgs(
+                  queryLanguage,
+                  {
+                    'FunctionName.$': '$.functionName',
+                    Payload: {
+                      'model.$': '$.new_model',
+                      'token.$': '$$.Task.Token',
+                    },
                   },
-                },
+                  {
+                    FunctionName: '{% $states.input.functionName %}',
+                    Payload: {
+                      model: '{% $states.input.new_model %}',
+                      token: '{% $states.context.Task.Token %}',
+                    },
+                  },
+                ),
                 Next: 'B',
               },
               B: {
                 Type: 'Task',
                 Resource: 'arn:aws:states:::lambda:invoke.waitForTaskToken',
-                Parameters: {
-                  'FunctionName.$': '$.functionName',
-                  AllowedFunctions: '*limited*',
-                  Payload: {
-                    'model.$': '$.new_model',
-                    'token.$': '$$.Task.Token',
+                ...getParamsOrArgs(
+                  queryLanguage,
+                  {
+                    'FunctionName.$': '$.functionName',
+                    AllowedFunctions: '*limited*',
+                    Payload: {
+                      'model.$': '$.new_model',
+                      'token.$': '$$.Task.Token',
+                    },
                   },
-                },
+                  {
+                    FunctionName: '{% $states.input.functionName %}',
+                    AllowedFunctions: '*limited*',
+                    Payload: {
+                      model: '{% $states.input.new_model %}',
+                      token: '{% $states.context.Task.Token %}',
+                    },
+                  },
+                ),
                 End: true,
               },
             },
@@ -3643,27 +3706,49 @@ describe('#compileIamRole', () => {
               A: {
                 Type: 'Task',
                 Resource: 'arn:aws:states:::lambda:invoke.waitForTaskToken',
-                Parameters: {
-                  'FunctionName.$': '$.functionName',
-                  AllowedFunctions: 'arn:aws:lambda:us-west-2:1234567890:function:foo',
-                  Payload: {
-                    'model.$': '$.new_model',
-                    'token.$': '$$.Task.Token',
+                ...getParamsOrArgs(
+                  queryLanguage,
+                  {
+                    'FunctionName.$': '$.functionName',
+                    AllowedFunctions: 'arn:aws:lambda:us-west-2:1234567890:function:foo',
+                    Payload: {
+                      'model.$': '$.new_model',
+                      'token.$': '$$.Task.Token',
+                    },
                   },
-                },
+                  {
+                    FunctionName: '{% $states.input.functionName %}',
+                    AllowedFunctions: 'arn:aws:lambda:us-west-2:1234567890:function:foo',
+                    Payload: {
+                      model: '{% $states.input.new_model %}',
+                      token: '{% $states.context.Task.Token %}',
+                    },
+                  },
+                ),
                 Next: 'B',
               },
               B: {
                 Type: 'Task',
                 Resource: 'arn:aws:states:::lambda:invoke.waitForTaskToken',
-                Parameters: {
-                  'FunctionName.$': '$.functionName',
-                  AllowedFunctions: '*limited*',
-                  Payload: {
-                    'model.$': '$.new_model',
-                    'token.$': '$$.Task.Token',
+                ...getParamsOrArgs(
+                  queryLanguage,
+                  {
+                    'FunctionName.$': '$.functionName',
+                    AllowedFunctions: '*limited*',
+                    Payload: {
+                      'model.$': '$.new_model',
+                      'token.$': '$$.Task.Token',
+                    },
                   },
-                },
+                  {
+                    FunctionName: '{% $states.input.functionName %}',
+                    AllowedFunctions: '*limited*',
+                    Payload: {
+                      model: '{% $states.input.new_model %}',
+                      token: '{% $states.context.Task.Token %}',
+                    },
+                  },
+                ),
                 End: true,
               },
             },

From 63abc6055ff69311bd8828383df04a226d19028a Mon Sep 17 00:00:00 2001
From: zirkelc <chris.zirkel@gmail.com>
Date: Thu, 8 May 2025 08:16:34 +0200
Subject: [PATCH 13/13] chore: package version

---
 package-lock.json | 4 ++--
 package.json      | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index d854c8cd..0d6c07dc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "serverless-step-functions",
-  "version": "3.11.1",
+  "version": "3.23.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "serverless-step-functions",
-      "version": "3.11.1",
+      "version": "3.23.0",
       "license": "MIT",
       "dependencies": {
         "@serverless/utils": "^6.7.0",
diff --git a/package.json b/package.json
index 47228925..7ee2f9c8 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "serverless-step-functions",
-  "version": "3.11.1",
+  "version": "3.23.0",
   "description": "The module is AWS Step Functions plugin for Serverless Framework",
   "main": "lib/index.js",
   "scripts": {