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": {