diff --git a/.github/scripts/label_missing_acknowledgement_section.js b/.github/scripts/label_missing_acknowledgement_section.js deleted file mode 100644 index d066d8bf87..0000000000 --- a/.github/scripts/label_missing_acknowledgement_section.js +++ /dev/null @@ -1,50 +0,0 @@ -const { - PR_ACTION, - PR_AUTHOR, - PR_BODY, - PR_NUMBER, - IGNORE_AUTHORS, - LABEL_BLOCK, - LABEL_BLOCK_MISSING_LICENSE_AGREEMENT, -} = require('./constants'); - -module.exports = async ({ github, context, core }) => { - if (IGNORE_AUTHORS.includes(PR_AUTHOR)) { - return core.notice('Author in IGNORE_AUTHORS list; skipping...'); - } - - if (PR_ACTION != 'opened') { - return core.notice( - 'Only newly open PRs are labelled to avoid spam; skipping' - ); - } - - const RELATED_ACK_SECTION_REGEX = - /By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice./; - - const isMatch = RELATED_ACK_SECTION_REGEX.exec(PR_BODY); - - if (isMatch == null) { - core.info( - `No acknowledgement section found, maybe the author didn't use the template but there is one.` - ); - - const msg = - "No acknowledgement section found. Please make sure you used the template to open a PR and didn't remove the acknowledgment section. Check the template here: https://github.com/aws-powertools/powertools-lambda-typescript/blob/develop/.github/PULL_REQUEST_TEMPLATE.md#acknowledgment"; - - await Promise.allSettled([ - github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - body: msg, - issue_number: PR_NUMBER, - }), - github.rest.issues.addLabels({ - issue_number: PR_NUMBER, - owner: context.repo.owner, - repo: context.repo.repo, - labels: [LABEL_BLOCK, LABEL_BLOCK_MISSING_LICENSE_AGREEMENT], - }), - ]); - } -}; diff --git a/.github/scripts/label_missing_related_issue.js b/.github/scripts/label_missing_related_issue.js deleted file mode 100644 index e7b9812a48..0000000000 --- a/.github/scripts/label_missing_related_issue.js +++ /dev/null @@ -1,54 +0,0 @@ -const { - PR_ACTION, - PR_AUTHOR, - PR_BODY, - PR_NUMBER, - IGNORE_AUTHORS, - LABEL_BLOCK, - LABEL_BLOCK_REASON, - RELATED_ISSUE_REGEX, -} = require("./constants"); - -module.exports = async ({ github, context, core }) => { - if (IGNORE_AUTHORS.includes(PR_AUTHOR)) { - return core.notice("Author in IGNORE_AUTHORS list; skipping..."); - } - - if (!["opened"].includes(PR_ACTION)) { - return core.notice( - "Only newly opened PRs are labelled to avoid spam; skipping" - ); - } - - const isMatch = RELATED_ISSUE_REGEX.exec(PR_BODY); - if (isMatch == null) { - core.info( - `No related issue found, maybe the author didn't use the template but there is one.` - ); - - let msg = - "No related issues found. Please ensure there is an open issue related to this change to avoid significant delays or closure."; - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - body: msg, - issue_number: PR_NUMBER, - }); - - return await github.rest.issues.addLabels({ - issue_number: PR_NUMBER, - owner: context.repo.owner, - repo: context.repo.repo, - labels: [LABEL_BLOCK, LABEL_BLOCK_REASON], - }); - } else { - const { closingWord, issue } = isMatch.groups; - core.info( - `Found related issue #${issue} ${ - closingWord === undefined - ? "without closing word" - : `with closing word ${closingWord}` - }` - ); - } -}; diff --git a/.github/semantic.yml b/.github/semantic.yml index 88988182c8..02bbdb2bd7 100644 --- a/.github/semantic.yml +++ b/.github/semantic.yml @@ -34,6 +34,7 @@ scopes: - deps - deps-dev - roadmap + - kafka # Always validate the PR title # and ignore the commits to lower the entry bar for contribution diff --git a/.github/workflows/label_pr_on_title.yml b/.github/workflows/label_pr_on_title.yml deleted file mode 100644 index 7c52408c55..0000000000 --- a/.github/workflows/label_pr_on_title.yml +++ /dev/null @@ -1,65 +0,0 @@ -name: Label PR based on title - -# PROCESS -# -# 1. Fetch PR details previously saved from untrusted location -# 2. Parse details for safety -# 3. Label PR based on semantic title (e.g., area, change type) - -# USAGE -# -# NOTE: meant to be used with ./.github/workflows/record_pr.yml -# -# Security Note: -# -# This workflow depends on "Record PR" workflow that runs in an untrusted location (forks) instead of `pull_request_target`. -# This enforces zero trust where "Record PR" workflow always runs on fork with zero permissions on GH_TOKEN. -# When "Record PR" completes, this workflow runs in our repository with the appropriate permissions and sanitize inputs. -# -# Coupled with "Approve GitHub Action to run on forks", we have confidence no privilege can be escalated, -# since any malicious change would need to be approved, and upon social engineering, it'll have zero permissions. - -on: - workflow_run: - workflows: ["Record PR details"] - types: - - completed - -permissions: - contents: read - -jobs: - get_pr_details: - permissions: - actions: read # download PR artifact - contents: read # checkout code - # Guardrails to only ever run if PR recording workflow was indeed - # run in a PR event and ran successfully - if: ${{ github.event.workflow_run.conclusion == 'success' }} - uses: ./.github/workflows/reusable_export_pr_details.yml - with: - record_pr_workflow_id: ${{ github.event.workflow_run.id }} - workflow_origin: ${{ github.event.repository.full_name }} - secrets: - token: ${{ secrets.GITHUB_TOKEN }} - label_pr: - needs: get_pr_details - runs-on: ubuntu-latest - permissions: - pull-requests: write # label respective PR - steps: - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: "Label PR based on title" - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 - env: - PR_NUMBER: ${{ needs.get_pr_details.outputs.prNumber }} - PR_TITLE: ${{ needs.get_pr_details.outputs.prTitle }} - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - # This safely runs in our base repo, not on fork - # thus allowing us to provide a write access token to label based on PR title - # and label PR based on semantic title accordingly - script: | - const script = require('.github/scripts/label_pr_based_on_title.js') - await script({github, context, core}) \ No newline at end of file diff --git a/.github/workflows/layers_partition_verify.yml b/.github/workflows/layers_partition_verify.yml new file mode 100644 index 0000000000..f258c94904 --- /dev/null +++ b/.github/workflows/layers_partition_verify.yml @@ -0,0 +1,132 @@ +# Parition Layer Verification +# --- +# This workflow queries the Parition layer info in production only + +on: + workflow_dispatch: + inputs: + environment: + description: Deployment environment + type: choice + options: + - Gamma + - Prod + required: true + version: + description: Layer version to verify + type: string + required: true + partition_version: + description: Layer version to verify, this is mostly used in Gamma where a version mismatch might exist + type: string + required: false + partition: + description: Partition to deploy to + type: choice + options: + - China + - GovCloud + workflow_call: + inputs: + environment: + description: Deployment environment + type: string + required: true + version: + description: Layer version to verify + type: string + required: true + partition_version: + description: Partition Layer version to verify, this is mostly used in Gamma where a version mismatch might exist + type: string + required: false + +name: Layer Verification (Partition) +run-name: Layer Verification (${{ inputs.partition }}) - ${{ inputs.environment }} / Version - ${{ inputs.version }} + +permissions: {} + +jobs: + setup: + runs-on: ubuntu-latest + outputs: + regions: ${{ format('{0}{1}', steps.regions_china.outputs.regions, steps.regions_govcloud.outputs.regions) }} + parition: ${{ format('{0}{1}', steps.regions_china.outputs.partition, steps.regions_govcloud.outputs.parition) }} + steps: + - id: regions_china + name: Parition (China) + if: ${{ inputs.partition == 'China' }} + run: | + echo regions='["cn-north-1", "cn-northwest-1"]'>> "$GITHUB_OUTPUT" + echo partition='aws-cn'>> "$GITHUB_OUTPUT" + - id: regions_govcloud + name: Partition (GovCloud) + if: ${{ inputs.partition == 'GovCloud' }} + run: | + echo regions='["us-gov-east-1", "us-gov-west-1"]'>> "$GITHUB_OUTPUT" + echo partition='aws-us-gov'>> "$GITHUB_OUTPUT" + commercial: + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + environment: Prod (Readonly) + steps: + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@b47578312673ae6fa5b5096b330d9fbac3d116df # v4.2.1 + with: + role-to-assume: ${{ secrets.AWS_IAM_ROLE }} + aws-region: us-east-1 + mask-aws-account-id: true + - name: Output AWSLambdaPowertoolsTypeScriptV2 + # fetch the specific layer version information from the us-east-1 commercial region + run: | + aws --region us-east-1 lambda get-layer-version-by-arn --arn 'arn:aws:lambda:us-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:${{ inputs.version }}' > AWSLambdaPowertoolsTypeScriptV2.json + - name: Store Metadata + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: AWSLambdaPowertoolsTypeScriptV2.json + path: AWSLambdaPowertoolsTypeScriptV2.json + retention-days: 1 + if-no-files-found: error + + verify: + name: Verify + needs: + - setup + - commercial + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + # Environment should interperlate as "GovCloud Prod" or "China Beta" + environment: ${{ inputs.partition }} ${{ inputs.environment }} + strategy: + matrix: + region: ${{ fromJson(needs.setup.outputs.regions) }} + steps: + - name: Download Metadata + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + name: AWSLambdaPowertoolsTypeScriptV2.json + - id: transform + run: | + echo 'CONVERTED_REGION=${{ matrix.region }}' | tr 'a-z\-' 'A-Z_' >> "$GITHUB_OUTPUT" + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@b47578312673ae6fa5b5096b330d9fbac3d116df # v4.2.1 + with: + role-to-assume: ${{ secrets[format('IAM_ROLE_{0}', steps.transform.outputs.CONVERTED_REGION)] }} + aws-region: ${{ matrix.region}} + mask-aws-account-id: true + - id: partition_version + name: Partition Layer Version + run: | + echo 'partition_version=$([[ -n "${{ inputs.partition_version}}" ]] && echo ${{ inputs.partition_version}} || echo ${{ inputs.version }} )' >> "$GITHUB_OUTPUT" + - name: Verify Layer + run: | + export layer_output='AWSLambdaPowertoolsTypeScriptV2-${{matrix.region}}.json' + aws --region ${{ matrix.region}} lambda get-layer-version-by-arn --arn "arn:${{ needs.setup.outputs.parition }}:lambda:${{ matrix.region}}:${{ secrets[format('AWS_ACCOUNT_{0}', steps.transform.outputs.CONVERTED_REGION)] }}:layer:AWSLambdaPowertoolsTypeScriptV2:${{ steps.partition_version.outputs.partition_version }}" > $layer_output + REMOTE_SHA=$(jq -r '.Content.CodeSha256' $layer_output) + LOCAL_SHA=$(jq -r '.Content.CodeSha256' AWSLambdaPowertoolsTypeScriptV2.json) + test "$REMOTE_SHA" == "$LOCAL_SHA" && echo "SHA OK: ${LOCAL_SHA}" || exit 1 + jq -s -r '["Layer Arn", "Runtimes", "Version", "Description", "SHA256"], ([.[0], .[1]] | .[] | [.LayerArn, (.CompatibleRuntimes | join("/")), .Version, .Description, .Content.CodeSha256]) |@tsv' AWSLambdaPowertoolsTypeScriptV2.json $layer_output | column -t -s $'\t' \ No newline at end of file diff --git a/.github/workflows/layers_partitions.yml b/.github/workflows/layers_partitions.yml new file mode 100644 index 0000000000..e4860062bd --- /dev/null +++ b/.github/workflows/layers_partitions.yml @@ -0,0 +1,169 @@ +# Partitioned Layer Publish +# --- +# This workflow publishes a specific layer version in an AWS account based on the environment input. +# +# We pull each the version of the layer and store them as artifacts, the we upload them to each of the Partitioned AWS accounts. +# +# A number of safety checks are performed to ensure safety. + +on: + workflow_dispatch: + inputs: + environment: + description: Deployment environment + type: choice + options: + - Gamma + - Prod + required: true + version: + description: Layer version to duplicate + type: string + required: true + partition: + description: Partition to deploy to + type: choice + options: + - China + - GovCloud + workflow_call: + inputs: + environment: + description: Deployment environment + type: string + required: true + version: + description: Layer version to duplicate + type: string + required: true + +name: Layer Deployment (Partitions) +run-name: Layer Deployment (${{ inputs.partition }}) - ${{ inputs.environment }} / Version - ${{ inputs.version }} + +permissions: + contents: read + +jobs: + setup: + runs-on: ubuntu-latest + outputs: + regions: ${{ format('{0}{1}', steps.regions_china.outputs.regions, steps.regions_govcloud.outputs.regions) }} + parition: ${{ format('{0}{1}', steps.regions_china.outputs.partition, steps.regions_govcloud.outputs.parition) }} + steps: + - id: regions_china + name: Parition (China) + if: ${{ inputs.partition == 'China' }} + run: | + echo regions='["cn-north-1", "cn-northwest-1"]'>> "$GITHUB_OUTPUT" + echo partition='aws-cn'>> "$GITHUB_OUTPUT" + - id: regions_govcloud + name: Partition (GovCloud) + if: ${{ inputs.partition == 'GovCloud' }} + run: | + echo regions='["us-gov-east-1", "us-gov-west-1"]'>> "$GITHUB_OUTPUT" + echo partition='aws-us-gov'>> "$GITHUB_OUTPUT" + download: + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + environment: Prod (Readonly) + steps: + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@b47578312673ae6fa5b5096b330d9fbac3d116df # v4.2.1 + with: + role-to-assume: ${{ secrets.AWS_IAM_ROLE }} + aws-region: us-east-1 + mask-aws-account-id: true + - name: Grab Zip + run: | + aws --region us-east-1 lambda get-layer-version-by-arn --arn arn:aws:lambda:us-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:${{ inputs.version }} --query 'Content.Location' | xargs curl -L -o AWSLambdaPowertoolsTypeScriptV2.zip + aws --region us-east-1 lambda get-layer-version-by-arn --arn arn:aws:lambda:us-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:${{ inputs.version }} > AWSLambdaPowertoolsTypeScriptV2.json + - name: Store Zip + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: AWSLambdaPowertoolsTypeScriptV2.zip + path: AWSLambdaPowertoolsTypeScriptV2.zip + retention-days: 1 + if-no-files-found: error + - name: Store Metadata + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: AWSLambdaPowertoolsTypeScriptV2.json + path: AWSLambdaPowertoolsTypeScriptV2.json + retention-days: 1 + if-no-files-found: error + + copy: + name: Copy + needs: + - setup + - download + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + # Environment should interperlate as "GovCloud Prod" or "China Beta" + environment: ${{ inputs.partition }} ${{ inputs.environment }} + strategy: + matrix: + region: ${{ fromJson(needs.setup.outputs.regions) }} + steps: + - name: Download Zip + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + name: AWSLambdaPowertoolsTypeScriptV2.zip + - name: Download Metadata + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + name: AWSLambdaPowertoolsTypeScriptV2.json + - name: Verify Layer Signature + run: | + SHA=$(jq -r '.Content.CodeSha256' 'AWSLambdaPowertoolsTypeScriptV2.json') + test "$(openssl dgst -sha256 -binary AWSLambdaPowertoolsTypeScriptV2.zip | openssl enc -base64)" == "$SHA" && echo "SHA OK: ${SHA}" || exit 1 + - id: transform + run: | + echo 'CONVERTED_REGION=${{ matrix.region }}' | tr 'a-z\-' 'A-Z_' >> "$GITHUB_OUTPUT" + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@b47578312673ae6fa5b5096b330d9fbac3d116df # v4.2.1 + with: + role-to-assume: ${{ secrets[format('IAM_ROLE_{0}', steps.transform.outputs.CONVERTED_REGION)] }} + aws-region: ${{ matrix.region}} + mask-aws-account-id: true + - name: Create Layer + id: create-layer + run: | + cat AWSLambdaPowertoolsTypeScriptV2.json | jq '{"LayerName": "AWSLambdaPowertoolsTypeScriptV2", "Description": .Description, "CompatibleRuntimes": .CompatibleRuntimes, "LicenseInfo": .LicenseInfo}' > input.json + + LAYER_VERSION=$(aws --region ${{ matrix.region}} lambda publish-layer-version \ + --zip-file fileb://./AWSLambdaPowertoolsTypeScriptV2.zip \ + --cli-input-json file://./input.json \ + --query 'Version' \ + --output text) + + echo "LAYER_VERSION=$LAYER_VERSION" >> "$GITHUB_OUTPUT" + + aws --region ${{ matrix.region}} lambda add-layer-version-permission \ + --layer-name 'AWSLambdaPowertoolsTypeScriptV2' \ + --statement-id 'PublicLayer' \ + --action lambda:GetLayerVersion \ + --principal '*' \ + --version-number "$LAYER_VERSION" + - name: Verify Layer + env: + LAYER_VERSION: ${{ steps.create-layer.outputs.LAYER_VERSION }} + run: | + export layer_output='AWSLambdaPowertoolsTypeScriptV2-${{matrix.region}}.json' + aws --region ${{ matrix.region}} lambda get-layer-version-by-arn --arn 'arn:${{ needs.setup.outputs.parition }}:lambda:${{ matrix.region}}:${{ secrets[format('AWS_ACCOUNT_{0}', steps.transform.outputs.CONVERTED_REGION)] }}:layer:AWSLambdaPowertoolsTypeScriptV2:${{ env.LAYER_VERSION }}' > $layer_output + REMOTE_SHA=$(jq -r '.Content.CodeSha256' $layer_output) + LOCAL_SHA=$(jq -r '.Content.CodeSha256' AWSLambdaPowertoolsTypeScriptV2.json) + test "$REMOTE_SHA" == "$LOCAL_SHA" && echo "SHA OK: ${LOCAL_SHA}" || exit 1 + jq -s -r '["Layer Arn", "Runtimes", "Version", "Description", "SHA256"], ([.[0], .[1]] | .[] | [.LayerArn, (.CompatibleRuntimes | join("/")), .Version, .Description, .Content.CodeSha256]) |@tsv' AWSLambdaPowertoolsTypeScriptV2.json $layer_output | column -t -s $'\t' + + - name: Store Metadata - ${{ matrix.region }} + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: AWSLambdaPowertoolsTypeScriptV2-${{ matrix.region }}.json + path: AWSLambdaPowertoolsTypeScriptV2-${{ matrix.region }}.json + retention-days: 1 + if-no-files-found: error \ No newline at end of file diff --git a/.github/workflows/on_closed_issues.yml b/.github/workflows/on_closed_issues.yml deleted file mode 100644 index 197466cffa..0000000000 --- a/.github/workflows/on_closed_issues.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Closed Issue Message - -# PROCESS -# -# 1. Comment on recently closed issues to warn future responses may not be looked after - -# USAGE -# -# Always triggered upon issue closure - -on: - issues: - types: [closed] - -permissions: - contents: read - -jobs: - auto_comment: - runs-on: ubuntu-latest - permissions: - issues: write # comment on issues - steps: - - uses: aws-powertools/actions/.github/actions/close-issue-message@428c1934f4b22c0984ff4a39b66c2f70765bbed6 - with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" - message: | - ⚠️ **COMMENT VISIBILITY WARNING** ⚠️ - - This issue is now closed. Please be mindful that future comments are hard for our team to see. - - If you need more assistance, please either tag a [team member](https://docs.powertools.aws.dev/lambda/typescript/latest/maintainers/#current-maintainers) or open a new issue that references this one. - - If you wish to keep having a conversation with other community members under this issue feel free to do so. \ No newline at end of file diff --git a/.github/workflows/on_opened_pr.yml b/.github/workflows/on_opened_pr.yml deleted file mode 100644 index e6aa602d4f..0000000000 --- a/.github/workflows/on_opened_pr.yml +++ /dev/null @@ -1,81 +0,0 @@ -name: On new PR - -# PROCESS -# -# 1. Fetch PR details previously saved from untrusted location -# 2. Parse details for safety -# 3. Confirm there is a related issue for newly opened PR -# 4. Verify if PR template is used and legal acknowledgement hasn't been removed - -# USAGE -# -# NOTE: meant to be used with ./.github/workflows/record_pr.yml -# -# Security Note: -# -# This workflow depends on "Record PR" workflow that runs in an untrusted location (forks) instead of `pull_request_target`. -# This enforces zero trust where "Record PR" workflow always runs on fork with zero permissions on GH_TOKEN. -# When "Record PR" completes, this workflow runs in our repository with the appropriate permissions and sanitize inputs. -# -# Coupled with "Approve GitHub Action to run on forks", we have confidence no privilege can be escalated, -# since any malicious change would need to be approved, and upon social engineering, it'll have zero permissions. - -on: - workflow_run: - workflows: ["Record PR details"] - types: - - completed - -permissions: - contents: read - -jobs: - get_pr_details: - permissions: - actions: read # download PR artifact - contents: read # checkout code - if: ${{ github.event.workflow_run.conclusion == 'success' }} - uses: ./.github/workflows/reusable_export_pr_details.yml - with: - record_pr_workflow_id: ${{ github.event.workflow_run.id }} - workflow_origin: ${{ github.event.repository.full_name }} - secrets: - token: ${{ secrets.GITHUB_TOKEN }} - check_related_issue: - permissions: - pull-requests: write # label and comment on PR if missing related issue (requirement) - needs: get_pr_details - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: "Ensure related issue is present" - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 - env: - PR_BODY: ${{ needs.get_pr_details.outputs.prBody }} - PR_NUMBER: ${{ needs.get_pr_details.outputs.prNumber }} - PR_ACTION: ${{ needs.get_pr_details.outputs.prAction }} - PR_AUTHOR: ${{ needs.get_pr_details.outputs.prAuthor }} - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const script = require('.github/scripts/label_missing_related_issue.js') - await script({github, context, core}) - check_acknowledge_section: - needs: get_pr_details - runs-on: ubuntu-latest - permissions: - pull-requests: write # label and comment on PR if missing acknowledge section (requirement) - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: "Ensure acknowledgement section is present" - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 - env: - PR_BODY: ${{ needs.get_pr_details.outputs.prBody }} - PR_NUMBER: ${{ needs.get_pr_details.outputs.prNumber }} - PR_ACTION: ${{ needs.get_pr_details.outputs.prAction }} - PR_AUTHOR: ${{ needs.get_pr_details.outputs.prAuthor }} - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const script = require('.github/scripts/label_missing_acknowledgement_section.js') - await script({github, context, core}) \ No newline at end of file diff --git a/.github/workflows/ossf_scorecard.yml b/.github/workflows/ossf_scorecard.yml index 827ca62c9a..edff5b3284 100644 --- a/.github/workflows/ossf_scorecard.yml +++ b/.github/workflows/ossf_scorecard.yml @@ -43,6 +43,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 + uses: github/codeql-action/upload-sarif@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0 with: sarif_file: results.sarif diff --git a/.github/workflows/reusable-run-linting-check-and-unit-tests.yml b/.github/workflows/reusable-run-linting-check-and-unit-tests.yml index ac214ec07e..844d687874 100644 --- a/.github/workflows/reusable-run-linting-check-and-unit-tests.yml +++ b/.github/workflows/reusable-run-linting-check-and-unit-tests.yml @@ -51,7 +51,8 @@ jobs: "packages/parser", "packages/parameters", "packages/validation", - "packages/metrics" + "packages/metrics", + "packages/kafka" ] fail-fast: false steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index 3186e3dcb4..a3349c4133 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,25 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.22.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.21.0...v2.22.0) (2025-06-20) + + +### Bug Fixes + +* **event-handler:** fix decorated scope in appsync events ([#3974](https://github.com/aws-powertools/powertools-lambda-typescript/issues/3974)) ([e539719](https://github.com/aws-powertools/powertools-lambda-typescript/commit/e5397199133da265f593c5feed0178c0ebe1e7c2)) + + +### Features + +* **kafka:** add logic to handle delimited protobufs ([#4071](https://github.com/aws-powertools/powertools-lambda-typescript/issues/4071)) ([db9ec0c](https://github.com/aws-powertools/powertools-lambda-typescript/commit/db9ec0c4af668c002460f8dc9171c7d4bfc155b2)) +* **kafka:** lazily deserialize key/value/headers ([#4068](https://github.com/aws-powertools/powertools-lambda-typescript/issues/4068)) ([ef9bb52](https://github.com/aws-powertools/powertools-lambda-typescript/commit/ef9bb5215a588f3d9a4e9ec9da7c0b307e3c4fa0)) +* **kafka:** new kafka utility ([#4058](https://github.com/aws-powertools/powertools-lambda-typescript/issues/4058)) ([006f27b](https://github.com/aws-powertools/powertools-lambda-typescript/commit/006f27bd9909e2da548cff9dbdcc1944ba76dbd1)) +* **layers:** add parameterised layer deployment and verification ([#4033](https://github.com/aws-powertools/powertools-lambda-typescript/issues/4033)) ([2214ba7](https://github.com/aws-powertools/powertools-lambda-typescript/commit/2214ba74301da31908b2fe717ec893a570efd6f7)) + + + + + # [2.21.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.20.0...v2.21.0) (2025-06-03) diff --git a/biome.json b/biome.json index 46c5a0c5d5..7d582f3a49 100644 --- a/biome.json +++ b/biome.json @@ -31,7 +31,9 @@ "lib", "cdk.out", "site", - ".aws-sam" + ".aws-sam", + "**/*.generated.js", + "**/*.generated.d.ts" ] } -} \ No newline at end of file +} diff --git a/docs/features/index.md b/docs/features/index.md index f06ae4701d..43653c06dc 100644 --- a/docs/features/index.md +++ b/docs/features/index.md @@ -87,4 +87,12 @@ description: Features of Powertools for AWS Lambda [:octicons-arrow-right-24: Read more](./validation.md) +- __Kafka__ + + --- + + Utility to easily handle message deserialization and parsing of Kafka events in AWS Lambda functions. + + [:octicons-arrow-right-24: Read more](./kafka.md) + diff --git a/docs/features/kafka.md b/docs/features/kafka.md new file mode 100644 index 0000000000..e6cb0cb9ff --- /dev/null +++ b/docs/features/kafka.md @@ -0,0 +1,418 @@ +--- +title: Kafka Consumer +description: Utility +status: new +--- + +The Kafka Consumer utility transparently handles message deserialization, provides an intuitive developer experience, and integrates seamlessly with the rest of the Powertools for AWS Lambda ecosystem. + +```mermaid +--8<-- "examples/snippets/kafka/diagrams/intro.mermaid" +``` + +## Key features + +* Automatic deserialization of Kafka messages (JSON, Avro, and Protocol Buffers) +* Simplified event record handling with intuitive interface +* Support for key and value deserialization +* Support for [Standard Schema](https://github.com/standard-schema/standard-schema) output parsing (e.g., Zod, Valibot, ArkType) +* Support for Event Source Mapping (ESM) with and without Schema Registry integration +* Out of the box error handling for deserialization issues + +## Terminology + +**Event Source Mapping (ESM)** A Lambda feature that reads from streaming sources (like Kafka) and invokes your Lambda function. It manages polling, batching, and error handling automatically, eliminating the need for consumer management code. + +**Record Key and Value** A Kafka messages contain two important parts: an optional key that determines the partition and a value containing the actual message data. Both are base64-encoded in Lambda events and can be independently deserialized. + +**Deserialization** The process of converting binary data (base64-encoded in Lambda events) into usable Python objects according to a specific format like JSON, Avro, or Protocol Buffers. Powertools handles this conversion automatically. + +**SchemaConfig class** Contains parameters that tell Powertools how to interpret message data, including the format type (JSON, Avro, Protocol Buffers) and optional schema definitions needed for binary formats. + +**Output parsing** A [Standard Schema](https://github.com/standard-schema/standard-schema) used to parse your data at runtime, allowing you to define how the deserialized data should be structured and validated. + +**Schema Registry** A centralized service that stores and validates schemas, ensuring producers and consumers maintain compatibility when message formats evolve over time. + +## Moving from traditional Kafka consumers + +Lambda processes Kafka messages as discrete events rather than continuous streams, requiring a different approach to consumer development that Powertools for AWS helps standardize. + +| Aspect | Traditional Kafka Consumers | Lambda Kafka Consumer | +|-----------------------|-------------------------------------|----------------------------------------------------------------| +| **Model** | Pull-based (you poll for messages) | Push-based (Lambda invoked with messages) | +| **Scaling** | Manual scaling configuration | Automatic scaling to partition count | +| **State** | Long-running application with state | Stateless, ephemeral executions | +| **Offsets** | Manual offset management | Automatic offset commitment | +| **Schema Validation** | Client-side schema validation | Optional Schema Registry integration with Event Source Mapping | +| **Error Handling** | Per-message retry control | Batch-level retry policies | + +## Getting started + +### Installation + +Depending on the schema types you want to use, install the library and the corresponding libraries: + +=== "JSON" + ```bash + npm install @aws-lambda-powertools/kafka + ``` + +=== "Avro" + ```bash + npm install @aws-lambda-powertools/kafka avro-js + ``` + +=== "Protobuf" + ```bash + npm install @aws-lambda-powertools/kafka protobufjs + ``` + +Additionally, if you want to use output parsing with [Standard Schema](https://github.com/standard-schema/standard-schema), you can install [any of the supported libraries](https://standardschema.dev/#what-schema-libraries-implement-the-spec), for example: Zod, Valibot, or ArkType. + + + +### Using ESM with Schema Registry + +The Event Source Mapping configuration determines which mode is used. With `JSON`, Lambda converts all messages to JSON before invoking your function. With `SOURCE` mode, Lambda preserves the original format, requiring you function to handle the appropriate deserialization. + +Powertools for AWS supports both Schema Registry integration modes in your Event Source Mapping configuration. + +### Processing Kafka events + +The Kafka consumer utility transforms raw Kafka events into an intuitive format for processing. To handle messages effectively, you'll need to configure a schema that matches your data format. + +???+ tip "Using Avro is recommended" + We recommend Avro for production Kafka implementations due to its schema evolution capabilities, compact binary format, and integration with Schema Registry. This offers better type safety and forward/backward compatibility compared to JSON. + +=== "Avro Messages" + + ```typescript hl_lines="2-3 8-13 15 19" + --8<-- "examples/snippets/kafka/gettingStartedAvro.ts" + ``` + +=== "Protocol Buffers" + + ```typescript hl_lines="1-2 8-13 15 19" + --8<-- "examples/snippets/kafka/gettingStartedProtobuf.ts" + ``` + +=== "JSON Messages" + + ```typescript hl_lines="1-2 7-11 13 17" + --8<-- "examples/snippets/kafka/gettingStartedJson.ts" + ``` + +### Deserializing keys and values + +The `kafkaConsumer` function can deserialize both keys and values independently based on your schema configuration. This flexibility allows you to work with different data formats in the same message. + +=== "index.ts" + + ```typescript hl_lines="9 13 22 25-26" + --8<-- "examples/snippets/kafka/gettingStartedKeyValue.ts:func" + ``` + +=== "types.ts" + + ```typescript + --8<-- "examples/snippets/kafka/gettingStartedKeyValue.ts:types" + ``` + +=== "ProductKey.avsc" + + ```json + --8<-- "examples/snippets/kafka/gettingStartedKeyValue.ts:2:8" + ``` + +=== "ProductInfo.avsc" + + ```json + --8<-- "examples/snippets/kafka/gettingStartedKeyValue.ts:12:20" + ``` + +You can configure the `kafkaConsumer` to handle only the value. This allows you to optimize your Lambda function for the specific data structure of your Kafka messages. + +### Handling primitive types + +When working with primitive data types (strings, integers, etc.) rather than structured objects, you can simplify your configuration by omitting the schema specification for that component. Powertools for AWS will deserialize the value always as a string. + +???+ tip "Common pattern: Keys with primitive values" + Using primitive types (strings, integers) as Kafka message keys is a common pattern for partitioning and identifying messages. The Kafka consumer automatically handles these primitive keys without requiring special configuration, making it easy to implement this popular design pattern. + +=== "Primitive key" + + ```typescript + --8<-- "examples/snippets/kafka/gettingStartedPrimitiveValues.ts" + ``` + +### Message format support and comparison + +The Kafka consumer utility supports multiple serialization formats to match your existing Kafka implementation. Choose the format that best suits your needs based on performance, schema evolution requirements, and ecosystem compatibility. + +???+ tip "Selecting the right format" + For new applications, consider Avro or Protocol Buffers over JSON. Both provide schema validation, evolution support, and significantly better performance with smaller message sizes. Avro is particularly well-suited for Kafka due to its built-in schema evolution capabilities. + +=== "Supported Formats" + + | Format | Schema Type | Description | Required Parameters | + |----------------------|--------------|-----------------------------------|--------------------------------------| + | **JSON** | `"JSON"` | Human-readable text format | None | + | **Avro** | `"AVRO"` | Compact binary format with schema | `value.schema` (Avro schema string) | + | **Protocol Buffers** | `"PROTOBUF"` | Efficient binary format | `value.schema` (Proto message class) | + +=== "Format Comparison" + + | Feature | JSON | Avro | Protocol Buffers | + |-------------------------------|----------|----------------------|-------------------------| + | **Schema Definition** | Optional | Required JSON schema | Required Protobuf class | + | **Schema Evolution** | None | Strong support | Strong support | + | **Size Efficiency** | Low | High | Highest | + | **Processing Speed** | Slower | Fast | Fastest | + | **Human Readability** | High | Low | Low | + | **Implementation Complexity** | Low | Medium | Medium | + | **Additional Dependencies** | None | `avro-js` module | `protobufjs` module | + +Choose the serialization format that best fits your needs: + +* **JSON**: Best for simplicity and when schema flexibility is important +* **Avro**: Best for systems with evolving schemas and when compatibility is critical +* **Protocol Buffers**: Best for performance-critical systems with structured data + +## Advanced + +### Accessing record metadata + +Each Kafka record contains important metadata that you can access alongside the deserialized message content. This metadata helps with message processing, troubleshooting, and implementing advanced patterns like exactly-once processing. + +=== "Working with Record Metadata" + + ```typescript hl_lines="10" + --8<-- "examples/snippets/kafka/advancedWorkingWithRecordMetadata.ts" + ``` + +For debugging purposes, you can also access the original key, value, and headers in their base64-encoded form, these are available in the `originalValue`, `originalKey`, and `originalHeaders` properties of the `record`. + +#### Available metadata properties + +| Property | Description | Example Use Case | +|-----------------------|------------------------------------------------------------------|---------------------------------------------------------------------| +| `topic` | Topic name the record was published to | Routing logic in multi-topic consumers | +| `partition` | Kafka partition number | Tracking message distribution | +| `offset` | Position in the partition | De-duplication, exactly-once processing | +| `timestamp` | Unix timestamp when record was created | Event timing analysis | +| `timestamp_type` | Timestamp type (`CREATE_TIME` or `LOG_APPEND_TIME`) | Data lineage verification | +| `headers` | Key-value pairs attached to the message | Cross-cutting concerns like correlation IDs | +| `key` | Deserialized message key | Customer ID or entity identifier | +| `value` | Deserialized message content | The actual business data | +| `originalValue` | Base64-encoded original message value | Debugging or custom deserialization | +| `originalKey` | Base64-encoded original message key | Debugging or custom deserialization | +| `originalHeaders` | Base64-encoded original message headers | Debugging or custom deserialization | +| `valueSchemaMetadata` | Metadata about the value schema like `schemaId` and `dataFormat` | Used by `kafkaConsumer` to process Protobuf, data format validation | +| `keySchemaMetadata` | Metadata about the key schema like `schemaId` and `dataFormat` | Used by `kafkaConsumer` to process Protobuf, data format validation | + +### Additional Parsing + +You can parse deserialized data using your preferred parsing library. This can help you integrate Kafka data with your domain schemas and application architecture, providing type hints, runtime parsing and validation, and advanced data transformations. + +=== "Zod" + + ```typescript hl_lines="25 29" + --8<-- "examples/snippets/kafka/advancedWorkingWithZod.ts" + ``` + +=== "Valibot" + + ```typescript hl_lines="28 32" + --8<-- "examples/snippets/kafka/advancedWorkingWithValibot.ts" + ``` + +=== "ArkType" + + ```typescript hl_lines="25 29" + --8<-- "examples/snippets/kafka/advancedWorkingWithArkType.ts" + ``` + +### Error handling + +Handle errors gracefully when processing Kafka messages to ensure your application maintains resilience and provides clear diagnostic information. The Kafka consumer utility provides specific exception types to help you identify and handle deserialization issues effectively. + +!!! tip + Fields like `value`, `key`, and `headers` are decoded lazily, meaning they are only deserialized when accessed. This allows you to handle deserialization errors at the point of access rather than when the record is first processed. + +=== "Basic Error Handling" + + ```typescript hl_lines="29 36 45" + --8<-- "examples/snippets/kafka/advancedBasicErrorHandling.ts:3" + ``` + + 1. If you want to handle deserialization and parsing errors, you should destructure or access the `value`, `key`, or `headers` properties of the record within the `for...of` loop. + +=== "Parser Error Handling" + + ```typescript hl_lines="41 44" + --8<-- "examples/snippets/kafka/advancedParserErrorHandling.ts:3" + ``` + + 1. The `cause` property of the error is populated with the original Standard Schema parsing error, allowing you to access detailed information about the parsing failure. + +#### Error types + +| Exception | Description | Common Causes | +|--------------------------------------|-----------------------------------------------|-----------------------------------------------------------------------------| +| `KafkaConsumerError`. | Base class for all Kafka consumer errors | General unhandled errors | +| `KafkaConsumerDeserializationError` | Thrown when message deserialization fails | Corrupted message data, schema mismatch, or wrong schema type configuration | +| `KafkaConsumerMissingSchemaError` | Thrown when a required schema is not provided | Missing schema for AVRO or PROTOBUF formats (required parameter) | +| `KafkaConsumerOutputSerializerError` | Thrown when additional schema parsing fails | Parsing failures in Standard Schema models | + +### Integrating with Idempotency + +When processing Kafka messages in Lambda, failed batches can result in message reprocessing. The [Idempotency utility](./idempotency.md) prevents duplicate processing by tracking which messages have already been handled, ensuring each message is processed exactly once. + +The Idempotency utility automatically stores the result of each successful operation, returning the cached result if the same message is processed again, which prevents potentially harmful duplicate operations like double-charging customers or double-counting metrics. + +!!! tip + By using the Kafka record's unique coordinates (topic, partition, offset) as the idempotency key, you ensure that even if a batch fails and Lambda retries the messages, each message will be processed exactly once. + +=== "Idempotent Kafka Processing" + + ```typescript hl_lines="44 51" + --8<-- "examples/snippets/kafka/advancedWorkingWithIdempotency.ts" + ``` + +### Best practices + +#### Handling large messages + +When processing large Kafka messages in Lambda, be mindful of memory limitations. Although the Kafka consumer utility optimizes memory usage, large deserialized messages can still exhaust the function resources. + +=== "Handling Large Messages" + + ```typescript hl_lines="18-20" + --8<-- "examples/snippets/kafka/advancedHandlingLargeMessages.ts:6" + ``` + +For large messages, consider these proven approaches: + +* **Store the data:** use Amazon S3 and include only the S3 reference in your Kafka message +* **Split large payloads:** use multiple smaller messages with sequence identifiers +* **Increase memory:** Increase your Lambda function's memory allocation, which also increases CPU capacity + +#### Batch size configuration + +The number of Kafka records processed per Lambda invocation is controlled by your Event Source Mapping configuration. Properly sized batches optimize cost and performance. + +=== "Handling Large Messages" + + ```yaml hl_lines="16" + --8<-- "examples/snippets/kafka/templates/advancedBatchSizeConfiguration.yaml" + ``` + +Different workloads benefit from different batch configurations: + +* **High-volume, simple processing:** Use larger batches (100-500 records) with short timeout +* **Complex processing with database operations:** Use smaller batches (10-50 records) +* **Mixed message sizes:** Set appropriate batching window (1-5 seconds) to handle variability + +#### Cross-language compatibility + +When using binary serialization formats across multiple programming languages, ensure consistent schema handling to prevent deserialization failures. + +Common cross-language challenges to address: + +* **Field naming conventions:** camelCase in Java vs snake_case in Python +* **Date/time:** representation differences +* **Numeric precision handling:** especially decimals, doubles, and floats + +### Troubleshooting + +#### Deserialization failures + +When encountering deserialization errors with your Kafka messages, follow this systematic troubleshooting approach to identify and resolve the root cause. + +First, check that your schema definition exactly matches the message format. Even minor discrepancies can cause deserialization failures, especially with binary formats like Avro and Protocol Buffers. + +For binary messages that fail to deserialize, examine the raw encoded data: + +```javascript +// DO NOT include this code in production handlers +// For troubleshooting purposes only +import base64 + +const rawBytes = Buffer.from(record.originalValue, 'base64'); +console.log(`Message size: ${rawBytes.length} bytes`); +console.log(`First 50 bytes (hex): ${rawBytes.slice(0, 50).toString('hex')}`); +``` + +#### Schema compatibility issues + +Schema compatibility issues often manifest as successful connections but failed deserialization. Common causes include: + +* **Schema evolution without backward compatibility**: New producer schema is incompatible with consumer schema +* **Field type mismatches**: For example, a field changed from string to integer across systems +* **Missing required fields**: Fields required by the consumer schema but absent in the message +* **Default value discrepancies**: Different handling of default values between languages + +When using Schema Registry, verify schema compatibility rules are properly configured for your topics and that all applications use the same registry. + +#### Memory and timeout optimization + +Lambda functions processing Kafka messages may encounter resource constraints, particularly with large batches or complex processing logic. + +For memory errors: + +* Increase Lambda memory allocation, which also provides more CPU resources +* Process fewer records per batch by adjusting the `BatchSize` parameter in your event source mapping +* Consider optimizing your message format to reduce memory footprint + +For timeout issues: + +* Extend your Lambda function timeout setting to accommodate processing time +* Implement chunked or asynchronous processing patterns for time-consuming operations +* Monitor and optimize database operations, external API calls, or other I/O operations in your handler + +!!! tip "Monitoring memory usage" + Use CloudWatch metrics to track your function's memory utilization. If it consistently exceeds 80% of allocated memory, consider increasing the memory allocation or optimizing your code. + +## Kafka consumer workflow + +### Using ESM with Schema Registry validation (SOURCE) + +
+```mermaid +--8<-- "examples/snippets/kafka/diagrams/usingESMWithSchemaRegistry.mermaid" +``` +
+ +### Using ESM with Schema Registry deserialization (JSON) + +
+```mermaid +--8<-- "examples/snippets/kafka/diagrams/usingESMWithJsonSchemaRegistry.mermaid" +``` +
+ +### Using ESM without Schema Registry integration + +
+```mermaid +--8<-- "examples/snippets/kafka/diagrams/usingESMWithoutSchemaRegistry.mermaid" +``` +
+ +## Testing your code + +Testing Kafka consumer code requires simulating Lambda events with Kafka messages. You can create simple test cases using local JSON files without needing a live Kafka cluster. Below an example of how to simulate a JSON message. + +=== "Testing your code" + + ```typescript + --8<-- "examples/snippets/kafka/advancedTestingYourCode.ts" + ``` diff --git a/docs/getting-started/lambda-layers.md b/docs/getting-started/lambda-layers.md index 77cf4f45b0..6aec4aa1b0 100644 --- a/docs/getting-started/lambda-layers.md +++ b/docs/getting-started/lambda-layers.md @@ -19,40 +19,40 @@ We publish the Lambda Layer for Powertools for AWS Lambda in all commercial regi | Region | Layer ARN | | ---------------- | --------------------------------------------------------------------------------------------------------- | -| `us-east-1` | [arn:aws:lambda:us-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `us-east-2` | [arn:aws:lambda:us-east-2:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `us-west-1` | [arn:aws:lambda:us-west-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `us-west-2` | [arn:aws:lambda:us-west-2:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `ap-south-1` | [arn:aws:lambda:ap-south-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `ap-south-2` | [arn:aws:lambda:ap-south-2:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `ap-east-1` | [arn:aws:lambda:ap-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `ap-southeast-5` | [arn:aws:lambda:ap-southeast-5:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `ap-southeast-7` | [arn:aws:lambda:ap-southeast-7:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `eu-central-1` | [arn:aws:lambda:eu-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `eu-central-2` | [arn:aws:lambda:eu-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `eu-west-1` | [arn:aws:lambda:eu-west-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `eu-west-2` | [arn:aws:lambda:eu-west-2:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `eu-west-3` | [arn:aws:lambda:eu-west-3:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `eu-north-1` | [arn:aws:lambda:eu-north-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `eu-south-1` | [arn:aws:lambda:eu-south-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `eu-south-2` | [arn:aws:lambda:eu-south-2:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `ca-central-1` | [arn:aws:lambda:ca-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `ca-west-1` | [arn:aws:lambda:ca-west-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `sa-east-1` | [arn:aws:lambda:sa-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `af-south-1` | [arn:aws:lambda:af-south-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `me-south-1` | [arn:aws:lambda:me-south-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `me-central-1` | [arn:aws:lambda:me-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `il-central-1` | [arn:aws:lambda:il-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `mx-central-1` | [arn:aws:lambda:mx-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `us-gov-west-1` | [arn:aws-us-gov:lambda:us-gov-west-1:165093116878:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | -| `us-gov-east-1` | [arn:aws-us-gov:lambda:us-gov-east-1:165087284144:layer:AWSLambdaPowertoolsTypeScriptV2:27](#){: .copyMe} | +| `us-east-1` | [arn:aws:lambda:us-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `us-east-2` | [arn:aws:lambda:us-east-2:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `us-west-1` | [arn:aws:lambda:us-west-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `us-west-2` | [arn:aws:lambda:us-west-2:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `ap-south-1` | [arn:aws:lambda:ap-south-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `ap-south-2` | [arn:aws:lambda:ap-south-2:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `ap-east-1` | [arn:aws:lambda:ap-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `ap-southeast-5` | [arn:aws:lambda:ap-southeast-5:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `ap-southeast-7` | [arn:aws:lambda:ap-southeast-7:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `eu-central-1` | [arn:aws:lambda:eu-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `eu-central-2` | [arn:aws:lambda:eu-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `eu-west-1` | [arn:aws:lambda:eu-west-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `eu-west-2` | [arn:aws:lambda:eu-west-2:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `eu-west-3` | [arn:aws:lambda:eu-west-3:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `eu-north-1` | [arn:aws:lambda:eu-north-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `eu-south-1` | [arn:aws:lambda:eu-south-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `eu-south-2` | [arn:aws:lambda:eu-south-2:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `ca-central-1` | [arn:aws:lambda:ca-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `ca-west-1` | [arn:aws:lambda:ca-west-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `sa-east-1` | [arn:aws:lambda:sa-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `af-south-1` | [arn:aws:lambda:af-south-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `me-south-1` | [arn:aws:lambda:me-south-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `me-central-1` | [arn:aws:lambda:me-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `il-central-1` | [arn:aws:lambda:il-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `mx-central-1` | [arn:aws:lambda:mx-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `us-gov-west-1` | [arn:aws-us-gov:lambda:us-gov-west-1:165093116878:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | +| `us-gov-east-1` | [arn:aws-us-gov:lambda:us-gov-east-1:165087284144:layer:AWSLambdaPowertoolsTypeScriptV2:28](#){: .copyMe} | ### Lookup Layer ARN via AWS SSM Parameter Store @@ -70,7 +70,7 @@ Parameter: LastModifiedDate: '2025-02-11T11:08:45.070000+01:00' Name: /aws/service/powertools/typescript/generic/all/2.14.0 Type: String - Value: arn:aws:lambda:eu-west-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27 + Value: arn:aws:lambda:eu-west-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28 Version: 1 ``` @@ -88,7 +88,7 @@ The pre-signed URL to download this Lambda Layer will be within `Location` key i Change `{aws::region}` to your AWS region, e.g. `eu-west-1`, and run the following command: ```bash title="AWS CLI command to download Lambda Layer content" -aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{aws::region}:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27 --region {aws::region} +aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{aws::region}:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28 --region {aws::region} # output { @@ -98,7 +98,7 @@ aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{aws::region}:094274105 "CodeSize": 3548324 }, "LayerArn": "arn:aws:lambda:eu-west-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2", - "LayerVersionArn": "arn:aws:lambda:eu-west-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27", + "LayerVersionArn": "arn:aws:lambda:eu-west-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28", "Description": "Powertools for AWS Lambda (TypeScript) version 2.18.0", "CreatedDate": "2025-04-08T07:38:30.424+0000", "Version": 24, @@ -133,7 +133,7 @@ aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{aws::region}:094274105 const powertoolsLayer = LayerVersion.fromLayerVersionArn( this, 'PowertoolsLayer', - `arn:aws:lambda:${Stack.of(this).region}:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27` + `arn:aws:lambda:${Stack.of(this).region}:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28` ); new NodejsFunction(this, 'Function', { @@ -203,7 +203,7 @@ aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{aws::region}:094274105 Type: AWS::Serverless::Function Properties: Layers: - - !Sub arn:aws:lambda:${AWS::Region}:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27 + - !Sub arn:aws:lambda:${AWS::Region}:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28 ``` You can also use AWS SSM Parameter Store to dynamically add Powertools for AWS Lambda and resolve the Layer ARN from SSM Parameter Store in your code, allowing you to pin to `latest` or a specific Powertools for AWS Lambda version. @@ -242,7 +242,7 @@ aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{aws::region}:094274105 hello: handler: lambda_function.lambda_handler layers: - - arn:aws:lambda:${aws:region}:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27 + - arn:aws:lambda:${aws:region}:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28 ``` If you use `esbuild` to bundle your code, make sure to exclude `@aws-lambda-powertools/*` and `@aws-sdk/*` from being bundled since the packages are already present the layer: @@ -277,7 +277,7 @@ aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{aws::region}:094274105 role = ... handler = "index.handler" runtime = "nodejs22.x" - layers = ["arn:aws:lambda:{aws::region}:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27"] + layers = ["arn:aws:lambda:{aws::region}:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28"] source_code_hash = filebase64sha256("lambda_function_payload.zip") } ``` @@ -312,7 +312,7 @@ aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{aws::region}:094274105 const lambdaFunction = new aws.lambda.Function('function', { layers: [ - pulumi.interpolate`arn:aws:lambda:${aws.getRegionOutput().name}:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27` + pulumi.interpolate`arn:aws:lambda:${aws.getRegionOutput().name}:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28` ], code: new pulumi.asset.FileArchive('lambda_function_payload.zip'), tracingConfig: { @@ -336,7 +336,7 @@ aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{aws::region}:094274105 name: "my-function", layers: { "@aws-lambda-powertools/*": - "arn:aws:lambda:${AWS::Region}:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:27", + "arn:aws:lambda:${AWS::Region}:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:28", }, }); ``` diff --git a/docs/index.md b/docs/index.md index d633659c76..1595509d5d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -54,6 +54,7 @@ Powertools for AWS Lambda (TypeScript) is built as a modular toolkit, so you can | [JMESPath Functions](./features/jmespath.md) | Built-in JMESPath functions to easily deserialize common encoded JSON payloads in Lambda functions. | | [Parser](./features/parser.md) | Utility to parse and validate AWS Lambda event payloads using Zod, a TypeScript-first schema declaration and validation library. | | [Validation](./features/validation.md) | JSON Schema validation for events and responses, including JMESPath support to unwrap events before validation. | +| [Kafka](./features/kafka.md) | Utility to easily handle message deserialization and parsing of Kafka events in AWS Lambda functions. | ## Examples diff --git a/docs/requirements.txt b/docs/requirements.txt index fc3842e77b..9a0f703f8f 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -374,9 +374,9 @@ pyyaml-env-tag==0.1 \ --hash=sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb \ --hash=sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069 # via mkdocs -requests==2.32.3 \ - --hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \ - --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 +requests==2.32.4 \ + --hash=sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c \ + --hash=sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422 # via mkdocs-material six==1.16.0 \ --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ @@ -430,9 +430,9 @@ typing-extensions==4.13.2 \ --hash=sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c \ --hash=sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef # via beautifulsoup4 -urllib3==2.2.3 \ - --hash=sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac \ - --hash=sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9 +urllib3==2.5.0 \ + --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ + --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc # via requests verspec==0.1.0 \ --hash=sha256:741877d5633cc9464c45a469ae2a31e801e6dbbaa85b9675d481cda100f11c31 \ diff --git a/examples/app/CHANGELOG.md b/examples/app/CHANGELOG.md index a599871ddb..cb054d33ae 100644 --- a/examples/app/CHANGELOG.md +++ b/examples/app/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.22.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.21.0...v2.22.0) (2025-06-20) + +**Note:** Version bump only for package powertools-sample-app + + + + + # [2.21.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.20.0...v2.21.0) (2025-06-03) **Note:** Version bump only for package powertools-sample-app diff --git a/examples/app/package.json b/examples/app/package.json index 03db01c83d..6a74f86e49 100644 --- a/examples/app/package.json +++ b/examples/app/package.json @@ -1,6 +1,6 @@ { "name": "powertools-sample-app", - "version": "2.21.0", + "version": "2.22.0", "author": { "name": "Amazon Web Services", "url": "https://aws.amazon.com" @@ -28,28 +28,28 @@ "#errors": "./functions/commons/errors.js" }, "devDependencies": { - "@types/aws-lambda": "^8.10.149", - "@types/node": "22.15.29", - "aws-cdk-lib": "^2.200.0", + "@types/aws-lambda": "^8.10.150", + "@types/node": "24.0.3", + "aws-cdk-lib": "^2.201.0", "constructs": "^10.4.2", "source-map-support": "^0.5.21", - "tsx": "^4.19.4", + "tsx": "^4.20.3", "typescript": "^5.8.3", "vitest": "^3.0.5" }, "dependencies": { - "@aws-lambda-powertools/batch": "^2.21.0", - "@aws-lambda-powertools/idempotency": "^2.21.0", - "@aws-lambda-powertools/logger": "^2.21.0", - "@aws-lambda-powertools/metrics": "^2.21.0", - "@aws-lambda-powertools/parameters": "^2.21.0", - "@aws-lambda-powertools/tracer": "^2.21.0", - "@aws-sdk/client-ssm": "^3.821.0", - "@aws-sdk/lib-dynamodb": "^3.821.0", + "@aws-lambda-powertools/batch": "^2.22.0", + "@aws-lambda-powertools/idempotency": "^2.22.0", + "@aws-lambda-powertools/logger": "^2.22.0", + "@aws-lambda-powertools/metrics": "^2.22.0", + "@aws-lambda-powertools/parameters": "^2.22.0", + "@aws-lambda-powertools/tracer": "^2.22.0", + "@aws-sdk/client-ssm": "^3.830.0", + "@aws-sdk/lib-dynamodb": "^3.830.0", "@middy/core": "^4.7.0", - "@types/aws-lambda": "^8.10.149", - "@types/node": "22.15.29", - "aws-cdk": "^2.1017.1", + "@types/aws-lambda": "^8.10.150", + "@types/node": "24.0.3", + "aws-cdk": "^2.1018.1", "constructs": "^10.4.2", "esbuild": "^0.25.5", "typescript": "^5.8.3" diff --git a/examples/snippets/CHANGELOG.md b/examples/snippets/CHANGELOG.md index 402509f1e0..d02b4cbb8a 100644 --- a/examples/snippets/CHANGELOG.md +++ b/examples/snippets/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.22.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.21.0...v2.22.0) (2025-06-20) + +**Note:** Version bump only for package code-snippets + + + + + # [2.21.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.20.0...v2.21.0) (2025-06-03) **Note:** Version bump only for package code-snippets diff --git a/examples/snippets/kafka/advancedBasicErrorHandling.ts b/examples/snippets/kafka/advancedBasicErrorHandling.ts new file mode 100644 index 0000000000..afb637b05e --- /dev/null +++ b/examples/snippets/kafka/advancedBasicErrorHandling.ts @@ -0,0 +1,54 @@ +declare function processRecord(record: unknown): Promise; + +import { readFileSync } from 'node:fs'; +import { SchemaType, kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import { KafkaConsumerDeserializationError } from '@aws-lambda-powertools/kafka/errors'; +import type { + ConsumerRecord, + SchemaConfig, +} from '@aws-lambda-powertools/kafka/types'; +import { Logger } from '@aws-lambda-powertools/logger'; + +const logger = new Logger({ serviceName: 'kafka-consumer' }); + +const schemaConfig = { + value: { + type: SchemaType.AVRO, + schema: readFileSync(new URL('./user.avsc', import.meta.url), 'utf8'), + }, +} satisfies SchemaConfig; + +export const handler = kafkaConsumer(async (event, _context) => { + const results: { + successful: number; + failed: Array>; + } = { + successful: 0, + failed: [], + }; + for (const record of event.records) { + try { + const { value, partition, offset, topic } = record; // (1)! + logger.setCorrelationId(`${topic}-${partition}-${offset}`); + + await processRecord(value); + + results.successful += 1; + } catch (error) { + if (error instanceof KafkaConsumerDeserializationError) { + results.failed.push(record); + logger.error('Error deserializing message', { error }); + } else { + logger.error('Error processing message', { error }); + } + } + + if (results.failed.length > 0) { + // Handle failed records, e.g., send to a dead-letter queue + } + + logger.info('Successfully processed records', { + successful: results.successful, + }); + } +}, schemaConfig); diff --git a/examples/snippets/kafka/advancedHandlingLargeMessages.ts b/examples/snippets/kafka/advancedHandlingLargeMessages.ts new file mode 100644 index 0000000000..a9ac47909e --- /dev/null +++ b/examples/snippets/kafka/advancedHandlingLargeMessages.ts @@ -0,0 +1,42 @@ +declare function processRecordFromS3({ + key, + bucket, +}: { key: string; bucket: string }): Promise; + +import { kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import { Logger } from '@aws-lambda-powertools/logger'; +import { object, safeParse, string } from 'valibot'; + +const logger = new Logger({ serviceName: 'kafka-consumer' }); + +const LargeMessage = object({ + key: string(), + bucket: string(), +}); + +export const handler = kafkaConsumer(async (event, _context) => { + for (const record of event.records) { + const { topic, value, originalValue } = record; + const valueSize = Buffer.byteLength(originalValue, 'utf8'); + const parsedValue = safeParse(LargeMessage, value); + if ( + topic === 'product-catalog' && + valueSize > 3_000_000 && + parsedValue.success + ) { + logger.info('Large message detected, processing from S3', { + size: valueSize, + }); + + const { key, bucket } = parsedValue.output; + await processRecordFromS3({ key, bucket }); + + logger.info('Processed large message from S3', { + key, + bucket, + }); + } + + // regular processing of the record + } +}); diff --git a/examples/snippets/kafka/advancedParserErrorHandling.ts b/examples/snippets/kafka/advancedParserErrorHandling.ts new file mode 100644 index 0000000000..3b554c1aa0 --- /dev/null +++ b/examples/snippets/kafka/advancedParserErrorHandling.ts @@ -0,0 +1,62 @@ +declare function processRecord(record: unknown): Promise; + +import { readFileSync } from 'node:fs'; +import { SchemaType, kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import { KafkaConsumerParserError } from '@aws-lambda-powertools/kafka/errors'; +import type { + ConsumerRecord, + SchemaConfig, +} from '@aws-lambda-powertools/kafka/types'; +import { Logger } from '@aws-lambda-powertools/logger'; +import { z } from 'zod/v4'; + +const logger = new Logger({ serviceName: 'kafka-consumer' }); + +const schemaConfig = { + value: { + type: SchemaType.AVRO, + schema: readFileSync(new URL('./user.avsc', import.meta.url), 'utf8'), + parserSchema: z.object({ + id: z.number(), + name: z.string(), + email: z.email(), + }), + }, +} satisfies SchemaConfig; + +export const handler = kafkaConsumer(async (event, _context) => { + const results: { + successful: number; + failed: Array>; + } = { + successful: 0, + failed: [], + }; + for (const record of event.records) { + try { + const { value, partition, offset, topic } = record; + logger.setCorrelationId(`${topic}-${partition}-${offset}`); + + await processRecord(value); + results.successful += 1; + } catch (error) { + if (error instanceof KafkaConsumerParserError) { + results.failed.push(record); + logger.error( + `Error deserializing message - ${z.prettifyError({ issues: error.cause } as z.ZodError)}`, + { error } // (1)! + ); + } else { + logger.error('Error processing message', { error }); + } + } + + if (results.failed.length > 0) { + // Handle failed records, e.g., send to a dead-letter queue + } + + logger.info('Successfully processed records', { + successful: results.successful, + }); + } +}, schemaConfig); diff --git a/examples/snippets/kafka/advancedTestingYourCode.ts b/examples/snippets/kafka/advancedTestingYourCode.ts new file mode 100644 index 0000000000..8de8694b19 --- /dev/null +++ b/examples/snippets/kafka/advancedTestingYourCode.ts @@ -0,0 +1,45 @@ +import type { MSKEvent } from '@aws-lambda-powertools/kafka/types'; +import type { Context } from 'aws-lambda'; +import { expect, it } from 'vitest'; +import { handler } from './gettingStartedPrimitiveValues.js'; + +it('handles complex protobuf messages from Glue Schema Registry', async () => { + // Prepare + const event = { + eventSource: 'aws:kafka', + eventSourceArn: + 'arn:aws:kafka:us-east-1:123456789012:cluster/MyCluster/12345678-1234-1234-1234-123456789012-1', + bootstrapServers: + 'b-1.mskcluster.abcde12345.us-east-1.kafka.amazonaws.com:9092', + records: { + 'orders-topic': [ + { + topic: 'orders-topic', + partition: 0, + offset: 15, + timestamp: 1545084650987, + timestampType: 'CREATE_TIME', + headers: [], + key: undefined, + keySchemaMetadata: { + dataFormat: 'JSON', + }, + valueSchemaMetadata: { + dataFormat: 'JSON', + schemaId: undefined, + }, + value: Buffer.from( + JSON.stringify({ order_id: '12345', amount: 99.95 }) + ).toString('base64'), + }, + ], + }, + } as MSKEvent; + + // Act + const result = await handler(event, {} as Context); + + // Assess + expect(result).toBeDefined(); + // You can add more specific assertions based on your handler's logic +}); diff --git a/examples/snippets/kafka/advancedWorkingWithArkType.ts b/examples/snippets/kafka/advancedWorkingWithArkType.ts new file mode 100644 index 0000000000..f0926efad7 --- /dev/null +++ b/examples/snippets/kafka/advancedWorkingWithArkType.ts @@ -0,0 +1,40 @@ +import { SchemaType, kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import type { SchemaConfig } from '@aws-lambda-powertools/kafka/types'; +import { Logger } from '@aws-lambda-powertools/logger'; +import { type } from 'arktype'; + +const logger = new Logger({ serviceName: 'kafka-consumer' }); + +const OrderItemSchema = type({ + productId: 'string', + quantity: 'number.integer >= 1', + price: 'number.integer', +}); + +const OrderSchema = type({ + id: 'string', + customerId: 'string', + items: OrderItemSchema.array().moreThanLength(0), + createdAt: 'string.date', + totalAmount: 'number.integer >= 0', +}); + +const schemaConfig = { + value: { + type: SchemaType.JSON, + parserSchema: OrderSchema, + }, +} satisfies SchemaConfig; + +export const handler = kafkaConsumer( + async (event, _context) => { + for (const record of event.records) { + const { + value: { id, items }, + } = record; + logger.setCorrelationId(id); + logger.debug(`order includes ${items.length} items`); + } + }, + schemaConfig +); diff --git a/examples/snippets/kafka/advancedWorkingWithIdempotency.ts b/examples/snippets/kafka/advancedWorkingWithIdempotency.ts new file mode 100644 index 0000000000..1c4a58c132 --- /dev/null +++ b/examples/snippets/kafka/advancedWorkingWithIdempotency.ts @@ -0,0 +1,53 @@ +import { + IdempotencyConfig, + makeIdempotent, +} from '@aws-lambda-powertools/idempotency'; +import { DynamoDBPersistenceLayer } from '@aws-lambda-powertools/idempotency/dynamodb'; +import { SchemaType, kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import type { SchemaConfig } from '@aws-lambda-powertools/kafka/types'; +import { Logger } from '@aws-lambda-powertools/logger'; +import { User } from './samples/user.es6.generated.js'; // protobuf generated class + +const logger = new Logger({ serviceName: 'kafka-consumer' }); +const persistenceStore = new DynamoDBPersistenceLayer({ + tableName: 'IdempotencyTable', +}); + +const schemaConfig = { + value: { + type: SchemaType.PROTOBUF, + schema: User, + }, +} satisfies SchemaConfig; + +const processRecord = makeIdempotent( + async (user, topic, partition, offset) => { + logger.info('processing user', { + userId: user.id, + meta: { + topic, + partition, + offset, + }, + }); + + // ...your business logic here + + return { + success: true, + userId: user.id, + }; + }, + { + persistenceStore, + config: new IdempotencyConfig({ + eventKeyJmesPath: `topic & '-' & partition & '-' & offset`, + }), + } +); + +export const handler = kafkaConsumer(async (event, _context) => { + for (const { value, topic, partition, offset } of event.records) { + await processRecord(value, topic, partition, offset); + } +}, schemaConfig); diff --git a/examples/snippets/kafka/advancedWorkingWithRecordMetadata.ts b/examples/snippets/kafka/advancedWorkingWithRecordMetadata.ts new file mode 100644 index 0000000000..7bda7f5f2d --- /dev/null +++ b/examples/snippets/kafka/advancedWorkingWithRecordMetadata.ts @@ -0,0 +1,38 @@ +import { SchemaType, kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import { Logger } from '@aws-lambda-powertools/logger'; +import { type IUser, User } from './samples/user.es6.generated.js'; // protobuf generated class + +const logger = new Logger({ serviceName: 'kafka-consumer' }); + +export const handler = kafkaConsumer( + async (event, _context) => { + for (const record of event.records) { + const { value, topic, partition, offset, timestamp, headers } = record; + logger.info(`processing message from topic ${topic}`, { + partition, + offset, + timestamp, + }); + + if (headers) { + for (const header of headers) { + logger.debug(`Header: ${header.key}`, { + value: header.value, + }); + } + } + + // Process the deserialized value + logger.info('User data', { + userId: value.id, + userName: value.name, + }); + } + }, + { + value: { + type: SchemaType.PROTOBUF, + schema: User, + }, + } +); diff --git a/examples/snippets/kafka/advancedWorkingWithValibot.ts b/examples/snippets/kafka/advancedWorkingWithValibot.ts new file mode 100644 index 0000000000..29c691aa4f --- /dev/null +++ b/examples/snippets/kafka/advancedWorkingWithValibot.ts @@ -0,0 +1,43 @@ +import { SchemaType, kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import type { SchemaConfig } from '@aws-lambda-powertools/kafka/types'; +import { Logger } from '@aws-lambda-powertools/logger'; +import * as v from 'valibot'; + +const logger = new Logger({ serviceName: 'kafka-consumer' }); + +const OrderItemSchema = v.object({ + productId: v.string(), + quantity: v.pipe(v.number(), v.integer(), v.toMinValue(1)), + price: v.pipe(v.number(), v.integer()), +}); + +const OrderSchema = v.object({ + id: v.string(), + customerId: v.string(), + items: v.pipe( + v.array(OrderItemSchema), + v.minLength(1, 'Order must have at least one item') + ), + createdAt: v.pipe(v.string(), v.isoDateTime()), + totalAmount: v.pipe(v.number(), v.toMinValue(0)), +}); + +const schemaConfig = { + value: { + type: SchemaType.JSON, + parserSchema: OrderSchema, + }, +} satisfies SchemaConfig; + +export const handler = kafkaConsumer>( + async (event, _context) => { + for (const record of event.records) { + const { + value: { id, items }, + } = record; + logger.setCorrelationId(id); + logger.debug(`order includes ${items.length} items`); + } + }, + schemaConfig +); diff --git a/examples/snippets/kafka/advancedWorkingWithZod.ts b/examples/snippets/kafka/advancedWorkingWithZod.ts new file mode 100644 index 0000000000..6bb9240f1d --- /dev/null +++ b/examples/snippets/kafka/advancedWorkingWithZod.ts @@ -0,0 +1,40 @@ +import { SchemaType, kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import type { SchemaConfig } from '@aws-lambda-powertools/kafka/types'; +import { Logger } from '@aws-lambda-powertools/logger'; +import { z } from 'zod/v4'; + +const logger = new Logger({ serviceName: 'kafka-consumer' }); + +const OrderItemSchema = z.object({ + productId: z.string(), + quantity: z.number().int().positive(), + price: z.number().positive(), +}); + +const OrderSchema = z.object({ + id: z.string(), + customerId: z.string(), + items: z.array(OrderItemSchema).min(1, 'Order must have at least one item'), + createdAt: z.iso.datetime(), + totalAmount: z.number().positive(), +}); + +const schemaConfig = { + value: { + type: SchemaType.JSON, + parserSchema: OrderSchema, + }, +} satisfies SchemaConfig; + +export const handler = kafkaConsumer>( + async (event, _context) => { + for (const record of event.records) { + const { + value: { id, items }, + } = record; + logger.setCorrelationId(id); + logger.debug(`order includes ${items.length} items`); + } + }, + schemaConfig +); diff --git a/examples/snippets/kafka/diagrams/intro.mermaid b/examples/snippets/kafka/diagrams/intro.mermaid new file mode 100644 index 0000000000..a86d656efd --- /dev/null +++ b/examples/snippets/kafka/diagrams/intro.mermaid @@ -0,0 +1,11 @@ +flowchart LR + KafkaTopic["Kafka Topic"] --> MSK["Amazon MSK"] + KafkaTopic --> MSKServerless["Amazon MSK Serverless"] + KafkaTopic --> SelfHosted["Self-hosted Kafka"] + MSK --> EventSourceMapping["Event Source Mapping"] + MSKServerless --> EventSourceMapping + SelfHosted --> EventSourceMapping + EventSourceMapping --> Lambda["Lambda Function"] + Lambda --> KafkaConsumer["Kafka Consumer Utility"] + KafkaConsumer --> Deserialization["Deserialization"] + Deserialization --> YourLogic["Your Business Logic"] \ No newline at end of file diff --git a/examples/snippets/kafka/diagrams/usingESMWithJsonSchemaRegistry.mermaid b/examples/snippets/kafka/diagrams/usingESMWithJsonSchemaRegistry.mermaid new file mode 100644 index 0000000000..6b1e1f91c5 --- /dev/null +++ b/examples/snippets/kafka/diagrams/usingESMWithJsonSchemaRegistry.mermaid @@ -0,0 +1,26 @@ +sequenceDiagram + participant Kafka + participant ESM as Event Source Mapping + participant SchemaRegistry as Schema Registry + participant Lambda + participant KafkaConsumer + participant YourCode + Kafka->>+ESM: Send batch of records + ESM->>+SchemaRegistry: Validate and deserialize + SchemaRegistry->>SchemaRegistry: Deserialize records + SchemaRegistry-->>-ESM: Return deserialized data + ESM->>+Lambda: Invoke with pre-deserialized JSON records + Lambda->>+KafkaConsumer: Pass Kafka event + KafkaConsumer->>KafkaConsumer: Parse event structure + loop For each record + KafkaConsumer->>KafkaConsumer: Record is already deserialized + alt Output serializer provided + KafkaConsumer->>KafkaConsumer: Apply output serializer + end + end + KafkaConsumer->>+YourCode: Provide ConsumerRecords + YourCode->>YourCode: Process records + YourCode-->>-KafkaConsumer: Return result + KafkaConsumer-->>-Lambda: Pass result back + Lambda-->>-ESM: Return response + ESM-->>-Kafka: Acknowledge processed batch \ No newline at end of file diff --git a/examples/snippets/kafka/diagrams/usingESMWithSchemaRegistry.mermaid b/examples/snippets/kafka/diagrams/usingESMWithSchemaRegistry.mermaid new file mode 100644 index 0000000000..5a29d771c8 --- /dev/null +++ b/examples/snippets/kafka/diagrams/usingESMWithSchemaRegistry.mermaid @@ -0,0 +1,26 @@ +sequenceDiagram + participant Kafka + participant ESM as Event Source Mapping + participant SchemaRegistry as Schema Registry + participant Lambda + participant KafkaConsumer + participant YourCode + Kafka->>+ESM: Send batch of records + ESM->>+SchemaRegistry: Validate schema + SchemaRegistry-->>-ESM: Confirm schema is valid + ESM->>+Lambda: Invoke with validated records (still encoded) + Lambda->>+KafkaConsumer: Pass Kafka event + KafkaConsumer->>KafkaConsumer: Parse event structure + loop For each record + KafkaConsumer->>KafkaConsumer: Decode base64 data + KafkaConsumer->>KafkaConsumer: Deserialize based on schema_type + alt Output serializer provided + KafkaConsumer->>KafkaConsumer: Apply output serializer + end + end + KafkaConsumer->>+YourCode: Provide ConsumerRecords + YourCode->>YourCode: Process records + YourCode-->>-KafkaConsumer: Return result + KafkaConsumer-->>-Lambda: Pass result back + Lambda-->>-ESM: Return response + ESM-->>-Kafka: Acknowledge processed batch \ No newline at end of file diff --git a/examples/snippets/kafka/diagrams/usingESMWithoutSchemaRegistry.mermaid b/examples/snippets/kafka/diagrams/usingESMWithoutSchemaRegistry.mermaid new file mode 100644 index 0000000000..f68ee58074 --- /dev/null +++ b/examples/snippets/kafka/diagrams/usingESMWithoutSchemaRegistry.mermaid @@ -0,0 +1,20 @@ +sequenceDiagram + participant Kafka + participant Lambda + participant KafkaConsumer + participant YourCode + Kafka->>+Lambda: Invoke with batch of records (direct integration) + Lambda->>+KafkaConsumer: Pass raw Kafka event + KafkaConsumer->>KafkaConsumer: Parse event structure + loop For each record + KafkaConsumer->>KafkaConsumer: Decode base64 data + KafkaConsumer->>KafkaConsumer: Deserialize based on schema_type + alt Output serializer provided + KafkaConsumer->>KafkaConsumer: Apply output serializer + end + end + KafkaConsumer->>+YourCode: Provide ConsumerRecords + YourCode->>YourCode: Process records + YourCode-->>-KafkaConsumer: Return result + KafkaConsumer-->>-Lambda: Pass result back + Lambda-->>-Kafka: Acknowledge processed batch \ No newline at end of file diff --git a/examples/snippets/kafka/gettingStartedAvro.ts b/examples/snippets/kafka/gettingStartedAvro.ts new file mode 100644 index 0000000000..2b2ce2066e --- /dev/null +++ b/examples/snippets/kafka/gettingStartedAvro.ts @@ -0,0 +1,19 @@ +import { readFileSync } from 'node:fs'; +import { SchemaType, kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import type { SchemaConfig } from '@aws-lambda-powertools/kafka/types'; +import { Logger } from '@aws-lambda-powertools/logger'; + +const logger = new Logger({ serviceName: 'kafka-consumer' }); + +const schemaConfig = { + value: { + type: SchemaType.AVRO, + schema: readFileSync(new URL('./user.avsc', import.meta.url), 'utf8'), + }, +} satisfies SchemaConfig; + +export const handler = kafkaConsumer(async (event, _context) => { + for (const { value } of event.records) { + logger.info('received value', { value }); + } +}, schemaConfig); diff --git a/examples/snippets/kafka/gettingStartedJson.ts b/examples/snippets/kafka/gettingStartedJson.ts new file mode 100644 index 0000000000..7030fb7512 --- /dev/null +++ b/examples/snippets/kafka/gettingStartedJson.ts @@ -0,0 +1,17 @@ +import { SchemaType, kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import type { SchemaConfig } from '@aws-lambda-powertools/kafka/types'; +import { Logger } from '@aws-lambda-powertools/logger'; + +const logger = new Logger({ serviceName: 'kafka-consumer' }); + +const schemaConfig = { + value: { + type: SchemaType.JSON, + }, +} satisfies SchemaConfig; + +export const handler = kafkaConsumer(async (event, _context) => { + for (const { value } of event.records) { + logger.info('received value', { value }); + } +}, schemaConfig); diff --git a/examples/snippets/kafka/gettingStartedKeyValue.ts b/examples/snippets/kafka/gettingStartedKeyValue.ts new file mode 100644 index 0000000000..3ba56caa78 --- /dev/null +++ b/examples/snippets/kafka/gettingStartedKeyValue.ts @@ -0,0 +1,70 @@ +const keySchema = ` +{ + "type": "record", + "name": "ProductKey", + "fields": [ + {"name": "product_id", "type": "string"} + ] +} +`; + +const valueSchema = ` +{ + "type": "record", + "name": "ProductInfo", + "fields": [ + {"name": "name", "type": "string"}, + {"name": "price", "type": "double"}, + {"name": "in_stock", "type": "boolean"} + ] +} +`; + +// --8<-- [start:types] + +type ProductKey = { + productId: string; +}; + +type ProductInfo = { + name: string; + price: number; + inStock: boolean; +}; + +// --8<-- [end:types] + +// --8<-- [start:func] + +import { readFileSync } from 'node:fs'; +import { SchemaType, kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import type { SchemaConfig } from '@aws-lambda-powertools/kafka/types'; +import { Logger } from '@aws-lambda-powertools/logger'; + +const logger = new Logger({ serviceName: 'kafka-consumer' }); + +const schemaConfig = { + key: { + type: SchemaType.AVRO, + schema: readFileSync(new URL('./ProductKey.avsc', import.meta.url), 'utf8'), + }, + value: { + type: SchemaType.AVRO, + schema: readFileSync( + new URL('./productInfo.avsc', import.meta.url), + 'utf8' + ), + }, +} satisfies SchemaConfig; + +export const handler = kafkaConsumer( + async (event, _context) => { + for (const { key, value } of event.records) { + logger.info('processing product ID', { productId: key.productId }); + logger.info('product', { name: value.name, price: value.price }); + } + }, + schemaConfig +); + +// --8<-- [end:func] diff --git a/examples/snippets/kafka/gettingStartedPrimitiveValues.ts b/examples/snippets/kafka/gettingStartedPrimitiveValues.ts new file mode 100644 index 0000000000..96b03a08bf --- /dev/null +++ b/examples/snippets/kafka/gettingStartedPrimitiveValues.ts @@ -0,0 +1,23 @@ +import { kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import { Logger } from '@aws-lambda-powertools/logger'; + +const logger = new Logger({ serviceName: 'kafka-consumer' }); + +export const handler = kafkaConsumer( + async (event, _context) => { + for (const record of event.records) { + // Key is automatically decoded as UTF-8 string + const { key } = record; + // Value is parsed as JSON object + const { value } = record; + + logger.info('received value', { + key, + product: { + id: value.id, + name: value.name, + }, + }); + } + } +); diff --git a/examples/snippets/kafka/gettingStartedProtobuf.ts b/examples/snippets/kafka/gettingStartedProtobuf.ts new file mode 100644 index 0000000000..34c9368f28 --- /dev/null +++ b/examples/snippets/kafka/gettingStartedProtobuf.ts @@ -0,0 +1,19 @@ +import { SchemaType, kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import type { SchemaConfig } from '@aws-lambda-powertools/kafka/types'; +import { Logger } from '@aws-lambda-powertools/logger'; +import { User } from './samples/user.es6.generated.js'; // protobuf generated class + +const logger = new Logger({ serviceName: 'kafka-consumer' }); + +const schemaConfig = { + value: { + type: SchemaType.PROTOBUF, + schema: User, + }, +} satisfies SchemaConfig; + +export const handler = kafkaConsumer(async (event, _context) => { + for (const { value } of event.records) { + logger.info('received value', { value }); + } +}, schemaConfig); diff --git a/examples/snippets/kafka/gettingStartedValueOnly.ts b/examples/snippets/kafka/gettingStartedValueOnly.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/examples/snippets/kafka/samples/user.es6.generated.d.ts b/examples/snippets/kafka/samples/user.es6.generated.d.ts new file mode 100644 index 0000000000..277a592edc --- /dev/null +++ b/examples/snippets/kafka/samples/user.es6.generated.d.ts @@ -0,0 +1,120 @@ +import * as $protobuf from "protobufjs"; +import Long = require("long"); +/** Properties of a User. */ +export interface IUser { + /** User id */ + id?: number | null; + + /** User name */ + name?: string | null; + + /** User price */ + price?: number | null; +} + +/** Represents a User. */ +export class User implements IUser { + /** + * Constructs a new User. + * @param [properties] Properties to set + */ + constructor(properties?: IUser); + + /** User id. */ + public id: number; + + /** User name. */ + public name: string; + + /** User price. */ + public price: number; + + /** + * Creates a new User instance using the specified properties. + * @param [properties] Properties to set + * @returns User instance + */ + public static create(properties?: IUser): User; + + /** + * Encodes the specified User message. Does not implicitly {@link User.verify|verify} messages. + * @param message User message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode( + message: IUser, + writer?: $protobuf.Writer, + ): $protobuf.Writer; + + /** + * Encodes the specified User message, length delimited. Does not implicitly {@link User.verify|verify} messages. + * @param message User message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited( + message: IUser, + writer?: $protobuf.Writer, + ): $protobuf.Writer; + + /** + * Decodes a User message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns User + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode( + reader: $protobuf.Reader | Uint8Array, + length?: number, + ): User; + + /** + * Decodes a User message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns User + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: $protobuf.Reader | Uint8Array): User; + + /** + * Verifies a User message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): string | null; + + /** + * Creates a User message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns User + */ + public static fromObject(object: { [k: string]: any }): User; + + /** + * Creates a plain object from a User message. Also converts values to other types if specified. + * @param message User + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject( + message: User, + options?: $protobuf.IConversionOptions, + ): { [k: string]: any }; + + /** + * Converts this User to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for User + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; +} diff --git a/examples/snippets/kafka/samples/user.es6.generated.js b/examples/snippets/kafka/samples/user.es6.generated.js new file mode 100644 index 0000000000..2b21fddd88 --- /dev/null +++ b/examples/snippets/kafka/samples/user.es6.generated.js @@ -0,0 +1,262 @@ +/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/ +import * as $protobuf from "protobufjs/minimal"; + +// Common aliases +const $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util; + +// Exported root namespace +const $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {}); + +export const User = $root.User = (() => { + + /** + * Properties of a User. + * @exports IUser + * @interface IUser + * @property {number|null} [id] User id + * @property {string|null} [name] User name + * @property {number|null} [price] User price + */ + + /** + * Constructs a new User. + * @exports User + * @classdesc Represents a User. + * @implements IUser + * @constructor + * @param {IUser=} [properties] Properties to set + */ + function User(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * User id. + * @member {number} id + * @memberof User + * @instance + */ + User.prototype.id = 0; + + /** + * User name. + * @member {string} name + * @memberof User + * @instance + */ + User.prototype.name = ""; + + /** + * User price. + * @member {number} price + * @memberof User + * @instance + */ + User.prototype.price = 0; + + /** + * Creates a new User instance using the specified properties. + * @function create + * @memberof User + * @static + * @param {IUser=} [properties] Properties to set + * @returns {User} User instance + */ + User.create = function create(properties) { + return new User(properties); + }; + + /** + * Encodes the specified User message. Does not implicitly {@link User.verify|verify} messages. + * @function encode + * @memberof User + * @static + * @param {IUser} message User message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + User.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.name); + if (message.price != null && Object.hasOwnProperty.call(message, "price")) + writer.uint32(/* id 3, wireType 1 =*/25).double(message.price); + return writer; + }; + + /** + * Encodes the specified User message, length delimited. Does not implicitly {@link User.verify|verify} messages. + * @function encodeDelimited + * @memberof User + * @static + * @param {IUser} message User message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + User.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a User message from the specified reader or buffer. + * @function decode + * @memberof User + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {User} User + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + User.decode = function decode(reader, length, error) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.User(); + while (reader.pos < end) { + let tag = reader.uint32(); + if (tag === error) + break; + switch (tag >>> 3) { + case 1: { + message.id = reader.int32(); + break; + } + case 2: { + message.name = reader.string(); + break; + } + case 3: { + message.price = reader.double(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a User message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof User + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {User} User + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + User.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a User message. + * @function verify + * @memberof User + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + User.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isInteger(message.id)) + return "id: integer expected"; + if (message.name != null && message.hasOwnProperty("name")) + if (!$util.isString(message.name)) + return "name: string expected"; + if (message.price != null && message.hasOwnProperty("price")) + if (typeof message.price !== "number") + return "price: number expected"; + return null; + }; + + /** + * Creates a User message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof User + * @static + * @param {Object.} object Plain object + * @returns {User} User + */ + User.fromObject = function fromObject(object) { + if (object instanceof $root.User) + return object; + let message = new $root.User(); + if (object.id != null) + message.id = object.id | 0; + if (object.name != null) + message.name = String(object.name); + if (object.price != null) + message.price = Number(object.price); + return message; + }; + + /** + * Creates a plain object from a User message. Also converts values to other types if specified. + * @function toObject + * @memberof User + * @static + * @param {User} message User + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + User.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.defaults) { + object.id = 0; + object.name = ""; + object.price = 0; + } + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + if (message.price != null && message.hasOwnProperty("price")) + object.price = options.json && !isFinite(message.price) ? String(message.price) : message.price; + return object; + }; + + /** + * Converts this User to JSON. + * @function toJSON + * @memberof User + * @instance + * @returns {Object.} JSON object + */ + User.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for User + * @function getTypeUrl + * @memberof User + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + User.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/User"; + }; + + return User; +})(); + +export { $root as default }; diff --git a/examples/snippets/kafka/templates/advancedBatchSizeConfiguration.yaml b/examples/snippets/kafka/templates/advancedBatchSizeConfiguration.yaml new file mode 100644 index 0000000000..8c9cf98b32 --- /dev/null +++ b/examples/snippets/kafka/templates/advancedBatchSizeConfiguration.yaml @@ -0,0 +1,21 @@ +Resources: +OrderProcessingFunction: + Type: AWS::Serverless::Function + Properties: + Handler: app.lambda_handler + Runtime: python3.9 + Events: + KafkaEvent: + Type: MSK + Properties: + Stream: !GetAtt OrdersMSKCluster.Arn + Topics: + - order-events + - payment-events + # Configuration for optimal throughput/latency balance + BatchSize: 100 + MaximumBatchingWindowInSeconds: 5 + StartingPosition: LATEST + # Enable partial batch success reporting + FunctionResponseTypes: + - ReportBatchItemFailures \ No newline at end of file diff --git a/examples/snippets/kafka/templates/gettingStartedWithMsk.yaml b/examples/snippets/kafka/templates/gettingStartedWithMsk.yaml new file mode 100644 index 0000000000..ab14d728ff --- /dev/null +++ b/examples/snippets/kafka/templates/gettingStartedWithMsk.yaml @@ -0,0 +1,20 @@ +AWSTemplateFormatVersion: '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Resources: + KafkaConsumerFunction: + Type: AWS::Serverless::Function + Properties: + Handler: app.lambda_handler + Runtime: python3.13 + Timeout: 30 + Events: + MSKEvent: + Type: MSK + Properties: + StartingPosition: LATEST + Stream: !GetAtt MyMSKCluster.Arn + Topics: + - my-topic-1 + - my-topic-2 + Policies: + - AWSLambdaMSKExecutionRole \ No newline at end of file diff --git a/examples/snippets/package.json b/examples/snippets/package.json index 782d4b07d6..85761f8d1f 100644 --- a/examples/snippets/package.json +++ b/examples/snippets/package.json @@ -1,6 +1,6 @@ { "name": "code-snippets", - "version": "2.21.0", + "version": "2.22.0", "description": "A collection code snippets for the Powertools for AWS Lambda (TypeScript) docs", "author": { "name": "Amazon Web Services", @@ -24,25 +24,29 @@ }, "homepage": "https://github.com/aws-powertools/powertools-lambda-typescript#readme", "devDependencies": { - "@aws-lambda-powertools/batch": "^2.21.0", - "@aws-lambda-powertools/event-handler": "^2.21.0", - "@aws-lambda-powertools/idempotency": "^2.21.0", - "@aws-lambda-powertools/jmespath": "^2.21.0", - "@aws-lambda-powertools/logger": "^2.21.0", - "@aws-lambda-powertools/metrics": "^2.21.0", - "@aws-lambda-powertools/parameters": "^2.21.0", - "@aws-lambda-powertools/parser": "^2.21.0", - "@aws-lambda-powertools/tracer": "^2.21.0", - "@aws-sdk/client-appconfigdata": "^3.821.0", - "@aws-sdk/client-dynamodb": "^3.821.0", - "@aws-sdk/client-secrets-manager": "^3.821.0", - "@aws-sdk/client-ssm": "^3.821.0", - "@aws-sdk/util-dynamodb": "^3.821.0", + "@aws-lambda-powertools/batch": "^2.22.0", + "@aws-lambda-powertools/event-handler": "^2.22.0", + "@aws-lambda-powertools/idempotency": "^2.22.0", + "@aws-lambda-powertools/jmespath": "^2.22.0", + "@aws-lambda-powertools/logger": "^2.22.0", + "@aws-lambda-powertools/metrics": "^2.22.0", + "@aws-lambda-powertools/parameters": "^2.22.0", + "@aws-lambda-powertools/parser": "^2.22.0", + "@aws-lambda-powertools/tracer": "^2.22.0", + "@aws-sdk/client-appconfigdata": "^3.830.0", + "@aws-sdk/client-dynamodb": "^3.830.0", + "@aws-sdk/client-secrets-manager": "^3.830.0", + "@aws-sdk/client-ssm": "^3.830.0", + "@aws-sdk/util-dynamodb": "^3.830.0", "@middy/core": "^4.7.0", - "@redis/client": "^5.1.1", + "@redis/client": "^5.5.6", "@valkey/valkey-glide": "^1.3.4", "aws-sdk": "^2.1692.0", "aws-sdk-client-mock": "^4.1.0", - "zod": "^3.25.48" + "zod": "^3.25.67" + }, + "dependencies": { + "arktype": "^2.1.20", + "valibot": "^1.1.0" } } diff --git a/layers/CHANGELOG.md b/layers/CHANGELOG.md index 631b7e6479..02f7e45e75 100644 --- a/layers/CHANGELOG.md +++ b/layers/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.22.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.21.0...v2.22.0) (2025-06-20) + +**Note:** Version bump only for package layers + + + + + # [2.21.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.20.0...v2.21.0) (2025-06-03) **Note:** Version bump only for package layers diff --git a/layers/package.json b/layers/package.json index e49cae5cbf..db970d4ee0 100644 --- a/layers/package.json +++ b/layers/package.json @@ -1,6 +1,6 @@ { "name": "layers", - "version": "2.21.0", + "version": "2.22.0", "bin": { "layer": "bin/layers.js" }, @@ -41,9 +41,9 @@ "source-map-support": "^0.5.21" }, "dependencies": { - "aws-cdk": "^2.1017.1", - "aws-cdk-lib": "^2.200.0", + "aws-cdk": "^2.1018.1", + "aws-cdk-lib": "^2.201.0", "esbuild": "^0.25.5", - "tsx": "^4.19.4" + "tsx": "^4.20.3" } } diff --git a/layers/src/canary-stack.ts b/layers/src/canary-stack.ts index 75c4c852a3..af562dd372 100644 --- a/layers/src/canary-stack.ts +++ b/layers/src/canary-stack.ts @@ -1,5 +1,6 @@ import { randomUUID } from 'node:crypto'; -import path from 'node:path'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; import { CustomResource, Duration, Stack, type StackProps } from 'aws-cdk-lib'; import { Effect, PolicyStatement } from 'aws-cdk-lib/aws-iam'; import { LayerVersion, Runtime, Tracing } from 'aws-cdk-lib/aws-lambda'; @@ -15,6 +16,9 @@ export interface CanaryStackProps extends StackProps { readonly ssmParameterLayerArn: string; } +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + export class CanaryStack extends Stack { public constructor(scope: Construct, id: string, props: CanaryStackProps) { super(scope, id, props); @@ -36,7 +40,7 @@ export class CanaryStack extends Stack { ]; const canaryFunction = new NodejsFunction(this, 'CanaryFunction', { - entry: path.join( + entry: join( __dirname, '../tests/e2e/layerPublisher.class.test.functionCode.ts' ), diff --git a/layers/src/layer-publisher-stack.ts b/layers/src/layer-publisher-stack.ts index b4b7260896..a47cea4bfd 100644 --- a/layers/src/layer-publisher-stack.ts +++ b/layers/src/layer-publisher-stack.ts @@ -1,6 +1,7 @@ import { execSync } from 'node:child_process'; import { randomUUID } from 'node:crypto'; -import { join, resolve, sep } from 'node:path'; +import { dirname, join, resolve, sep } from 'node:path'; +import { fileURLToPath } from 'node:url'; import { CfnOutput, RemovalPolicy, Stack, type StackProps } from 'aws-cdk-lib'; import { Architecture, @@ -12,6 +13,9 @@ import { import { StringParameter } from 'aws-cdk-lib/aws-ssm'; import type { Construct } from 'constructs'; +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + export interface LayerPublisherStackProps extends StackProps { readonly layerName?: string; readonly powertoolsPackageVersion?: string; diff --git a/lerna.json b/lerna.json index d1a5ab193a..9b5d765bc4 100644 --- a/lerna.json +++ b/lerna.json @@ -12,11 +12,12 @@ "packages/parser", "packages/event-handler", "packages/validation", + "packages/kafka", "examples/app", "layers", "examples/snippets" ], - "version": "2.21.0", + "version": "2.22.0", "npmClient": "npm", "message": "chore(release): %s [skip ci]" } diff --git a/mkdocs.yml b/mkdocs.yml index dd963129d4..bd1f584dfb 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -27,6 +27,8 @@ watch: [ examples/snippets/tracer, packages/validation/src, examples/snippets/validation, + packages/kafka/src, + examples/snippets/kafka, ] nav: @@ -52,6 +54,7 @@ nav: - features/jmespath.md - features/parser.md - features/validation.md + - features/kafka.md - Environment variables: environment-variables.md - Upgrade guide: upgrade.md - Community Content: we_made_this.md @@ -172,12 +175,14 @@ plugins: - features/logger.md - features/metrics.md - features/event-handler/appsync-events.md + - features/event-handler/bedrock-agents.md - features/parameters.md - features/idempotency.md - features/batch.md - features/jmespath.md - features/parser.md - features/validation.md + - features/kafka.md Environment variables: - environment-variables.md Upgrade guide: diff --git a/package-lock.json b/package-lock.json index 2a10d4d6cc..6d42303fd2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,16 +23,17 @@ "layers", "examples/app", "packages/event-handler", - "packages/validation" + "packages/validation", + "packages/kafka" ], "devDependencies": { "@biomejs/biome": "^1.9.4", - "@types/aws-lambda": "^8.10.149", - "@types/node": "^22.15.29", - "@vitest/coverage-v8": "^3.1.4", + "@types/aws-lambda": "^8.10.150", + "@types/node": "^24.0.3", + "@vitest/coverage-v8": "^3.2.3", "husky": "^9.1.7", "lerna": "8.1.2", - "lint-staged": "^16.1.0", + "lint-staged": "^16.1.2", "markdownlint-cli2": "^0.18.1", "middy4": "npm:@middy/core@^4.7.0", "middy5": "npm:@middy/core@^5.4.3", @@ -48,71 +49,75 @@ }, "examples/app": { "name": "powertools-sample-app", - "version": "2.21.0", + "version": "2.22.0", "license": "MIT-0", "dependencies": { - "@aws-lambda-powertools/batch": "^2.21.0", - "@aws-lambda-powertools/idempotency": "^2.21.0", - "@aws-lambda-powertools/logger": "^2.21.0", - "@aws-lambda-powertools/metrics": "^2.21.0", - "@aws-lambda-powertools/parameters": "^2.21.0", - "@aws-lambda-powertools/tracer": "^2.21.0", - "@aws-sdk/client-ssm": "^3.821.0", - "@aws-sdk/lib-dynamodb": "^3.821.0", + "@aws-lambda-powertools/batch": "^2.22.0", + "@aws-lambda-powertools/idempotency": "^2.22.0", + "@aws-lambda-powertools/logger": "^2.22.0", + "@aws-lambda-powertools/metrics": "^2.22.0", + "@aws-lambda-powertools/parameters": "^2.22.0", + "@aws-lambda-powertools/tracer": "^2.22.0", + "@aws-sdk/client-ssm": "^3.830.0", + "@aws-sdk/lib-dynamodb": "^3.830.0", "@middy/core": "^4.7.0", - "@types/aws-lambda": "^8.10.149", - "@types/node": "22.15.29", - "aws-cdk": "^2.1017.1", + "@types/aws-lambda": "^8.10.150", + "@types/node": "24.0.3", + "aws-cdk": "^2.1018.1", "constructs": "^10.4.2", "esbuild": "^0.25.5", "typescript": "^5.8.3" }, "devDependencies": { - "@types/aws-lambda": "^8.10.149", - "@types/node": "22.15.29", - "aws-cdk-lib": "^2.200.0", + "@types/aws-lambda": "^8.10.150", + "@types/node": "24.0.3", + "aws-cdk-lib": "^2.201.0", "constructs": "^10.4.2", "source-map-support": "^0.5.21", - "tsx": "^4.19.4", + "tsx": "^4.20.3", "typescript": "^5.8.3", "vitest": "^3.0.5" } }, "examples/snippets": { "name": "code-snippets", - "version": "2.21.0", + "version": "2.22.0", "license": "MIT-0", + "dependencies": { + "arktype": "^2.1.20", + "valibot": "^1.1.0" + }, "devDependencies": { - "@aws-lambda-powertools/batch": "^2.21.0", - "@aws-lambda-powertools/event-handler": "^2.21.0", - "@aws-lambda-powertools/idempotency": "^2.21.0", - "@aws-lambda-powertools/jmespath": "^2.21.0", - "@aws-lambda-powertools/logger": "^2.21.0", - "@aws-lambda-powertools/metrics": "^2.21.0", - "@aws-lambda-powertools/parameters": "^2.21.0", - "@aws-lambda-powertools/parser": "^2.21.0", - "@aws-lambda-powertools/tracer": "^2.21.0", - "@aws-sdk/client-appconfigdata": "^3.821.0", - "@aws-sdk/client-dynamodb": "^3.821.0", - "@aws-sdk/client-secrets-manager": "^3.821.0", - "@aws-sdk/client-ssm": "^3.821.0", - "@aws-sdk/util-dynamodb": "^3.821.0", + "@aws-lambda-powertools/batch": "^2.22.0", + "@aws-lambda-powertools/event-handler": "^2.22.0", + "@aws-lambda-powertools/idempotency": "^2.22.0", + "@aws-lambda-powertools/jmespath": "^2.22.0", + "@aws-lambda-powertools/logger": "^2.22.0", + "@aws-lambda-powertools/metrics": "^2.22.0", + "@aws-lambda-powertools/parameters": "^2.22.0", + "@aws-lambda-powertools/parser": "^2.22.0", + "@aws-lambda-powertools/tracer": "^2.22.0", + "@aws-sdk/client-appconfigdata": "^3.830.0", + "@aws-sdk/client-dynamodb": "^3.830.0", + "@aws-sdk/client-secrets-manager": "^3.830.0", + "@aws-sdk/client-ssm": "^3.830.0", + "@aws-sdk/util-dynamodb": "^3.830.0", "@middy/core": "^4.7.0", - "@redis/client": "^5.1.1", + "@redis/client": "^5.5.6", "@valkey/valkey-glide": "^1.3.4", "aws-sdk": "^2.1692.0", "aws-sdk-client-mock": "^4.1.0", - "zod": "^3.25.48" + "zod": "^3.25.67" } }, "layers": { - "version": "2.21.0", + "version": "2.22.0", "license": "MIT-0", "dependencies": { - "aws-cdk": "^2.1017.1", - "aws-cdk-lib": "^2.200.0", + "aws-cdk": "^2.1018.1", + "aws-cdk-lib": "^2.201.0", "esbuild": "^0.25.5", - "tsx": "^4.19.4" + "tsx": "^4.20.3" }, "bin": { "layer": "bin/layers.js" @@ -135,6 +140,21 @@ "node": ">=6.0.0" } }, + "node_modules/@ark/schema": { + "version": "0.46.0", + "resolved": "https://registry.npmjs.org/@ark/schema/-/schema-0.46.0.tgz", + "integrity": "sha512-c2UQdKgP2eqqDArfBqQIJppxJHvNNXuQPeuSPlDML4rjw+f1cu0qAlzOG4b8ujgm9ctIDWwhpyw6gjG5ledIVQ==", + "license": "MIT", + "dependencies": { + "@ark/util": "0.46.0" + } + }, + "node_modules/@ark/util": { + "version": "0.46.0", + "resolved": "https://registry.npmjs.org/@ark/util/-/util-0.46.0.tgz", + "integrity": "sha512-JPy/NGWn/lvf1WmGCPw2VGpBg5utZraE84I7wli18EDF3p3zc/e9WolT35tINeZO3l7C77SjqRJeAUoT0CvMRg==", + "license": "MIT" + }, "node_modules/@aws-cdk/asset-awscli-v1": { "version": "2.2.237", "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.237.tgz", @@ -167,9 +187,9 @@ } }, "node_modules/@aws-cdk/cloud-assembly-schema": { - "version": "44.1.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-44.1.0.tgz", - "integrity": "sha512-WvesvSbBw5FrVbH8LZfjX5iDDRdixDkEnbsFGN8H2GNR9geBo4kIBI1nlOiqoGB6dwPwif8qDEM/4NOfuzIChQ==", + "version": "44.5.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-44.5.0.tgz", + "integrity": "sha512-/dk9YtqF+BnBS6k4m7YWIp7Pd80m7jdjT8ED8gb3Rd9hAuAEUoJubO0M3EOlLFmknIesQNm95LYU6vt/MIQhWg==", "bundleDependencies": [ "jsonschema", "semver" @@ -180,7 +200,7 @@ "semver": "^7.7.2" }, "engines": { - "node": ">= 14.15.0" + "node": ">= 18.0.0" } }, "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/jsonschema": { @@ -271,12 +291,12 @@ } }, "node_modules/@aws-cdk/toolkit-lib": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/toolkit-lib/-/toolkit-lib-1.0.0.tgz", - "integrity": "sha512-2x6ZWiLiBdLmr9cx69wPclfXaUbR0PGaNwda+Kh3bqgwSKNKq9OBPRhwECEZatz/1ZBI9sdTQjhDrYyL9LngzA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@aws-cdk/toolkit-lib/-/toolkit-lib-1.1.1.tgz", + "integrity": "sha512-GTr33jhCeh8pQ7YvocAJW6jNydXupZAbSVFd2kD9X9+T2uo5X04Nm8x+u6yeldAEx7UQGv7oTXRcQgboqRNRtA==", "license": "Apache-2.0", "dependencies": { - "@aws-cdk/cloud-assembly-schema": ">=44.1.0", + "@aws-cdk/cloud-assembly-schema": ">=44.4.0", "@aws-cdk/cloudformation-diff": "^2", "@aws-cdk/cx-api": "^2", "@aws-sdk/client-appsync": "^3", @@ -300,19 +320,19 @@ "@aws-sdk/credential-providers": "^3", "@aws-sdk/ec2-metadata-service": "^3", "@aws-sdk/lib-storage": "^3", - "@smithy/middleware-endpoint": "^4.1.7", - "@smithy/property-provider": "^4.0.3", - "@smithy/shared-ini-file-loader": "^4.0.3", - "@smithy/util-retry": "^4.0.4", - "@smithy/util-waiter": "^4.0.4", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/property-provider": "^4.0.4", + "@smithy/shared-ini-file-loader": "^4.0.4", + "@smithy/util-retry": "^4.0.5", + "@smithy/util-waiter": "^4.0.5", "archiver": "^7.0.1", "cdk-assets": "^3", - "cdk-from-cfn": "^0.217.0", + "cdk-from-cfn": "^0.220.0", "chalk": "^4", "chokidar": "^3", "fs-extra": "^9", "glob": "^11.0.2", - "minimatch": "^10.0.1", + "minimatch": "10.0.1", "p-limit": "^3", "semver": "^7.7.2", "split2": "^4.2.0", @@ -321,7 +341,7 @@ "yaml": "^1" }, "engines": { - "node": ">= 14.15.0" + "node": ">= 18.0.0" }, "peerDependencies": { "@aws-cdk/cli-plugin-contract": "^2" @@ -343,14 +363,14 @@ } }, "node_modules/@aws-cdk/toolkit-lib/node_modules/glob": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.2.tgz", - "integrity": "sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", + "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", "license": "ISC", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^4.0.1", - "minimatch": "^10.0.0", + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.0.3", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" @@ -365,10 +385,25 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@aws-cdk/toolkit-lib/node_modules/glob/node_modules/minimatch": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", + "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "license": "ISC", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@aws-cdk/toolkit-lib/node_modules/jackspeak": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.0.tgz", - "integrity": "sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -695,6 +730,10 @@ "resolved": "packages/jmespath", "link": true }, + "node_modules/@aws-lambda-powertools/kafka": { + "resolved": "packages/kafka", + "link": true + }, "node_modules/@aws-lambda-powertools/logger": { "resolved": "packages/logger", "link": true @@ -724,46 +763,46 @@ "link": true }, "node_modules/@aws-sdk/client-appconfigdata": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-appconfigdata/-/client-appconfigdata-3.821.0.tgz", - "integrity": "sha512-IkPk1Hgj3McZvnzMlMA5C2XOt3OgfGTXz/bwmKMg62bzPFNoKsouMM1ECElCvwmrohJJwF6A+vmBmPXOPmxHgA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-appconfigdata/-/client-appconfigdata-3.830.0.tgz", + "integrity": "sha512-xZpOFk3k1/CM5RghLMDkqUrcSWT9VM3rJ9OjQVCX5rttO78VkL5ZUye5Nez4eflCMgSOSD9e9XSZBTRMFJNleA==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", - "@aws-sdk/credential-provider-node": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/credential-provider-node": "3.830.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -776,45 +815,45 @@ } }, "node_modules/@aws-sdk/client-appconfigdata/node_modules/@aws-sdk/client-sso": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.821.0.tgz", - "integrity": "sha512-aDEBZUKUd/+Tvudi0d9KQlqt2OW2P27LATZX0jkNC8yVk4145bAPS04EYoqdKLuyUn/U33DibEOgKUpxZB12jQ==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.830.0.tgz", + "integrity": "sha512-5zCEpfI+zwX2SIa258L+TItNbBoAvQQ6w74qdFM6YJufQ1F9tvwjTX8T+eSTT9nsFIvfYnUaGalWwJVfmJUgVQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -826,21 +865,25 @@ } }, "node_modules/@aws-sdk/client-appconfigdata/node_modules/@aws-sdk/core": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.821.0.tgz", - "integrity": "sha512-8eB3wKbmfciQFmxFq7hAjy7mXdUs7vBOR5SwT0ZtQBg0Txc18Lc9tMViqqdO6/KU7OukA6ib2IAVSjIJJEN7FQ==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.826.0.tgz", + "integrity": "sha512-BGbQYzWj3ps+dblq33FY5tz/SsgJCcXX0zjQlSC07tYvU1jHTUvsefphyig+fY38xZ4wdKjbTop+KUmXUYrOXw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.821.0", - "@smithy/core": "^3.5.1", + "@aws-sdk/xml-builder": "3.821.0", + "@smithy/core": "^3.5.3", "@smithy/node-config-provider": "^4.1.3", "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", "@smithy/signature-v4": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.4", + "@smithy/util-utf8": "^4.0.0", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" }, @@ -849,13 +892,13 @@ } }, "node_modules/@aws-sdk/client-appconfigdata/node_modules/@aws-sdk/credential-provider-env": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.821.0.tgz", - "integrity": "sha512-C+s/A72pd7CXwEsJj9+Uq9T726iIfIF18hGRY8o82xcIEfOyakiPnlisku8zZOaAu+jm0CihbbYN4NyYNQ+HZQ==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.826.0.tgz", + "integrity": "sha512-DK3pQY8+iKK3MGDdC3uOZQ2psU01obaKlTYhEwNu4VWzgwQL4Vi3sWj4xSWGEK41vqZxiRLq6fOq7ysRI+qEZA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -866,19 +909,19 @@ } }, "node_modules/@aws-sdk/client-appconfigdata/node_modules/@aws-sdk/credential-provider-http": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.821.0.tgz", - "integrity": "sha512-gIRzTLnAsRfRSNarCag7G7rhcHagz4x5nNTWRihQs5cwTOghEExDy7Tj5m4TEkv3dcTAsNn+l4tnR4nZXo6R+Q==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.826.0.tgz", + "integrity": "sha512-N+IVZBh+yx/9GbMZTKO/gErBi/FYZQtcFRItoLbY+6WU+0cSWyZYfkoeOxHmQV3iX9k65oljERIWUmL9x6OSQg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/node-http-handler": "^4.0.6", "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/util-stream": "^4.2.2", "tslib": "^2.6.2" @@ -888,19 +931,19 @@ } }, "node_modules/@aws-sdk/client-appconfigdata/node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.821.0.tgz", - "integrity": "sha512-VRTrmsca8kBHtY1tTek1ce+XkK/H0fzodBKcilM/qXjTyumMHPAzVAxKZfSvGC+28/pXyQzhOEyxZfw7giCiWA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.830.0.tgz", + "integrity": "sha512-zeQenzvh8JRY5nULd8izdjVGoCM1tgsVVsrLSwDkHxZTTW0hW/bmOmXfvdaE0wDdomXW7m2CkQDSmP7XdvNXZg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/credential-provider-env": "3.821.0", - "@aws-sdk/credential-provider-http": "3.821.0", - "@aws-sdk/credential-provider-process": "3.821.0", - "@aws-sdk/credential-provider-sso": "3.821.0", - "@aws-sdk/credential-provider-web-identity": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/credential-provider-env": "3.826.0", + "@aws-sdk/credential-provider-http": "3.826.0", + "@aws-sdk/credential-provider-process": "3.826.0", + "@aws-sdk/credential-provider-sso": "3.830.0", + "@aws-sdk/credential-provider-web-identity": "3.830.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -913,18 +956,18 @@ } }, "node_modules/@aws-sdk/client-appconfigdata/node_modules/@aws-sdk/credential-provider-node": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.821.0.tgz", - "integrity": "sha512-oBgbcgOXWMgknAfhIdTeHSSVIv+k2LXN9oTbxu1r++o4WWBWrEQ8mHU0Zo9dfr7Uaoqi3pezYZznsBkXnMLEOg==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.830.0.tgz", + "integrity": "sha512-X/2LrTgwtK1pkWrvofxQBI8VTi6QVLtSMpsKKPPnJQ0vgqC0e4czSIs3ZxiEsOkCBaQ2usXSiKyh0ccsQ6k2OA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "3.821.0", - "@aws-sdk/credential-provider-http": "3.821.0", - "@aws-sdk/credential-provider-ini": "3.821.0", - "@aws-sdk/credential-provider-process": "3.821.0", - "@aws-sdk/credential-provider-sso": "3.821.0", - "@aws-sdk/credential-provider-web-identity": "3.821.0", + "@aws-sdk/credential-provider-env": "3.826.0", + "@aws-sdk/credential-provider-http": "3.826.0", + "@aws-sdk/credential-provider-ini": "3.830.0", + "@aws-sdk/credential-provider-process": "3.826.0", + "@aws-sdk/credential-provider-sso": "3.830.0", + "@aws-sdk/credential-provider-web-identity": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -937,13 +980,13 @@ } }, "node_modules/@aws-sdk/client-appconfigdata/node_modules/@aws-sdk/credential-provider-process": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.821.0.tgz", - "integrity": "sha512-e18ucfqKB3ICNj5RP/FEdvUfhVK6E9MALOsl8pKP13mwegug46p/1BsZWACD5n+Zf9ViiiHxIO7td03zQixfwA==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.826.0.tgz", + "integrity": "sha512-kURrc4amu3NLtw1yZw7EoLNEVhmOMRUTs+chaNcmS+ERm3yK0nKjaJzmKahmwlTQTSl3wJ8jjK7x962VPo+zWw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -955,15 +998,15 @@ } }, "node_modules/@aws-sdk/client-appconfigdata/node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.821.0.tgz", - "integrity": "sha512-Dt+pheBLom4O/egO4L75/72k9C1qtUOLl0F0h6lmqZe4Mvhz+wDtjoO/MdGC/P1q0kcIX/bBKr0NQ3cIvAH8pA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.830.0.tgz", + "integrity": "sha512-+VdRpZmfekzpySqZikAKx6l5ndnLGluioIgUG4ZznrButgFD/iogzFtGmBDFB3ZLViX1l4pMXru0zFwJEZT21Q==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.821.0", - "@aws-sdk/core": "3.821.0", - "@aws-sdk/token-providers": "3.821.0", + "@aws-sdk/client-sso": "3.830.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/token-providers": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -975,14 +1018,14 @@ } }, "node_modules/@aws-sdk/client-appconfigdata/node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.821.0.tgz", - "integrity": "sha512-FF5wnRJkxSQaCVVvWNv53K1MhTMgH8d+O+MHTbkv51gVIgVATrtfFQMKBLcEAxzXrgAliIO3LiNv+1TqqBZ+BA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.830.0.tgz", + "integrity": "sha512-hPYrKsZeeOdLROJ59T6Y8yZ0iwC/60L3qhZXjapBFjbqBtMaQiMTI645K6xVXBioA6vxXq7B4aLOhYqk6Fy/Ww==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -1040,16 +1083,16 @@ } }, "node_modules/@aws-sdk/client-appconfigdata/node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.821.0.tgz", - "integrity": "sha512-rw8q3TxygMg3VrofN04QyWVCCyGwz3bVthYmBZZseENPWG3Krz1OCKcyqjkTcAxMQlEywOske+GIiOasGKnJ3w==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.828.0.tgz", + "integrity": "sha512-nixvI/SETXRdmrVab4D9LvXT3lrXkwAWGWk2GVvQvzlqN1/M/RfClj+o37Sn4FqRkGH9o9g7Fqb1YqZ4mqDAtA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", - "@smithy/core": "^3.5.1", + "@aws-sdk/util-endpoints": "3.828.0", + "@smithy/core": "^3.5.3", "@smithy/protocol-http": "^5.1.2", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" @@ -1059,45 +1102,45 @@ } }, "node_modules/@aws-sdk/client-appconfigdata/node_modules/@aws-sdk/nested-clients": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.821.0.tgz", - "integrity": "sha512-2IuHcUsWw44ftSEDYU4dvktTEqgyDvkOcfpoGC/UmT4Qo6TVCP3U5tWEGpNK9nN+7nLvekruxxG/jaMt5/oWVw==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.830.0.tgz", + "integrity": "sha512-5N5YTlBr1vtxf7+t+UaIQ625KEAmm7fY9o1e3MgGOi/paBoI0+axr3ud24qLIy0NSzFlAHEaxUSWxcERNjIoZw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -1127,14 +1170,14 @@ } }, "node_modules/@aws-sdk/client-appconfigdata/node_modules/@aws-sdk/token-providers": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.821.0.tgz", - "integrity": "sha512-qJ7wgKhdxGbPg718zWXbCYKDuSWZNU3TSw64hPRW6FtbZrIyZxObpiTKC6DKwfsVoZZhHEoP/imGykN1OdOTJA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.830.0.tgz", + "integrity": "sha512-aJ4guFwj92nV9D+EgJPaCFKK0I3y2uMchiDfh69Zqnmwfxxxfxat6F79VA7PS0BdbjRfhLbn+Ghjftnomu2c1g==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -1160,9 +1203,9 @@ } }, "node_modules/@aws-sdk/client-appconfigdata/node_modules/@aws-sdk/util-endpoints": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.821.0.tgz", - "integrity": "sha512-Uknt/zUZnLE76zaAAPEayOeF5/4IZ2puTFXvcSCWHsi9m3tqbb9UozlnlVqvCZLCRWfQryZQoG2W4XSS3qgk5A==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.828.0.tgz", + "integrity": "sha512-RvKch111SblqdkPzg3oCIdlGxlQs+k+P7Etory9FmxPHyPDvsP1j1c74PmgYqtzzMWmoXTjd+c9naUHh9xG8xg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1189,13 +1232,13 @@ } }, "node_modules/@aws-sdk/client-appconfigdata/node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.821.0.tgz", - "integrity": "sha512-YwMXc9EvuzJgnLBTyiQly2juPujXwDgcMHB0iSN92tHe7Dd1jJ1feBmTgdClaaqCeHFUaFpw+3JU/ZUJ6LjR+A==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.828.0.tgz", + "integrity": "sha512-LdN6fTBzTlQmc8O8f1wiZN0qF3yBWVGis7NwpWK7FUEzP9bEZRxYfIkV9oV9zpt6iNRze1SedK3JQVB/udxBoA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/types": "3.821.0", "@smithy/node-config-provider": "^4.1.3", "@smithy/types": "^4.3.1", @@ -1213,6 +1256,20 @@ } } }, + "node_modules/@aws-sdk/client-appconfigdata/node_modules/@aws-sdk/xml-builder": { + "version": "3.821.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.821.0.tgz", + "integrity": "sha512-DIIotRnefVL6DiaHtO6/21DhJ4JZnnIwdNbpwiAhdt/AVbttcE4yw925gsjur0OGv5BTYXQXU3YnANBYnZjuQA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@aws-sdk/client-appsync": { "version": "3.741.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-appsync/-/client-appsync-3.741.0.tgz", @@ -2364,47 +2421,47 @@ } }, "node_modules/@aws-sdk/client-cloudwatch": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch/-/client-cloudwatch-3.821.0.tgz", - "integrity": "sha512-mo7LlIpdXTMDLV2fbEa3t8oYu3t92eodOqpLbP24IMXLiCFe61RuUPahukbrSLUtrXIFVOM0alqQz84xegYpAA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch/-/client-cloudwatch-3.830.0.tgz", + "integrity": "sha512-Cvb5WLSLOWbmrERq3gxdPRF2HbB7P5Aj03XD4UsSNw3ay3DtsgJhDo4APqGKXznJVvu7jOvuwt/jfp1r5BuBJg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", - "@aws-sdk/credential-provider-node": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/credential-provider-node": "3.830.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", - "@smithy/middleware-compression": "^4.1.9", + "@smithy/middleware-compression": "^4.1.11", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -2803,45 +2860,45 @@ } }, "node_modules/@aws-sdk/client-cloudwatch/node_modules/@aws-sdk/client-sso": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.821.0.tgz", - "integrity": "sha512-aDEBZUKUd/+Tvudi0d9KQlqt2OW2P27LATZX0jkNC8yVk4145bAPS04EYoqdKLuyUn/U33DibEOgKUpxZB12jQ==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.830.0.tgz", + "integrity": "sha512-5zCEpfI+zwX2SIa258L+TItNbBoAvQQ6w74qdFM6YJufQ1F9tvwjTX8T+eSTT9nsFIvfYnUaGalWwJVfmJUgVQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -2853,21 +2910,25 @@ } }, "node_modules/@aws-sdk/client-cloudwatch/node_modules/@aws-sdk/core": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.821.0.tgz", - "integrity": "sha512-8eB3wKbmfciQFmxFq7hAjy7mXdUs7vBOR5SwT0ZtQBg0Txc18Lc9tMViqqdO6/KU7OukA6ib2IAVSjIJJEN7FQ==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.826.0.tgz", + "integrity": "sha512-BGbQYzWj3ps+dblq33FY5tz/SsgJCcXX0zjQlSC07tYvU1jHTUvsefphyig+fY38xZ4wdKjbTop+KUmXUYrOXw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.821.0", - "@smithy/core": "^3.5.1", + "@aws-sdk/xml-builder": "3.821.0", + "@smithy/core": "^3.5.3", "@smithy/node-config-provider": "^4.1.3", "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", "@smithy/signature-v4": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.4", + "@smithy/util-utf8": "^4.0.0", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" }, @@ -2876,13 +2937,13 @@ } }, "node_modules/@aws-sdk/client-cloudwatch/node_modules/@aws-sdk/credential-provider-env": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.821.0.tgz", - "integrity": "sha512-C+s/A72pd7CXwEsJj9+Uq9T726iIfIF18hGRY8o82xcIEfOyakiPnlisku8zZOaAu+jm0CihbbYN4NyYNQ+HZQ==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.826.0.tgz", + "integrity": "sha512-DK3pQY8+iKK3MGDdC3uOZQ2psU01obaKlTYhEwNu4VWzgwQL4Vi3sWj4xSWGEK41vqZxiRLq6fOq7ysRI+qEZA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -2893,19 +2954,19 @@ } }, "node_modules/@aws-sdk/client-cloudwatch/node_modules/@aws-sdk/credential-provider-http": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.821.0.tgz", - "integrity": "sha512-gIRzTLnAsRfRSNarCag7G7rhcHagz4x5nNTWRihQs5cwTOghEExDy7Tj5m4TEkv3dcTAsNn+l4tnR4nZXo6R+Q==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.826.0.tgz", + "integrity": "sha512-N+IVZBh+yx/9GbMZTKO/gErBi/FYZQtcFRItoLbY+6WU+0cSWyZYfkoeOxHmQV3iX9k65oljERIWUmL9x6OSQg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/node-http-handler": "^4.0.6", "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/util-stream": "^4.2.2", "tslib": "^2.6.2" @@ -2915,19 +2976,19 @@ } }, "node_modules/@aws-sdk/client-cloudwatch/node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.821.0.tgz", - "integrity": "sha512-VRTrmsca8kBHtY1tTek1ce+XkK/H0fzodBKcilM/qXjTyumMHPAzVAxKZfSvGC+28/pXyQzhOEyxZfw7giCiWA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.830.0.tgz", + "integrity": "sha512-zeQenzvh8JRY5nULd8izdjVGoCM1tgsVVsrLSwDkHxZTTW0hW/bmOmXfvdaE0wDdomXW7m2CkQDSmP7XdvNXZg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/credential-provider-env": "3.821.0", - "@aws-sdk/credential-provider-http": "3.821.0", - "@aws-sdk/credential-provider-process": "3.821.0", - "@aws-sdk/credential-provider-sso": "3.821.0", - "@aws-sdk/credential-provider-web-identity": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/credential-provider-env": "3.826.0", + "@aws-sdk/credential-provider-http": "3.826.0", + "@aws-sdk/credential-provider-process": "3.826.0", + "@aws-sdk/credential-provider-sso": "3.830.0", + "@aws-sdk/credential-provider-web-identity": "3.830.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -2940,18 +3001,18 @@ } }, "node_modules/@aws-sdk/client-cloudwatch/node_modules/@aws-sdk/credential-provider-node": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.821.0.tgz", - "integrity": "sha512-oBgbcgOXWMgknAfhIdTeHSSVIv+k2LXN9oTbxu1r++o4WWBWrEQ8mHU0Zo9dfr7Uaoqi3pezYZznsBkXnMLEOg==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.830.0.tgz", + "integrity": "sha512-X/2LrTgwtK1pkWrvofxQBI8VTi6QVLtSMpsKKPPnJQ0vgqC0e4czSIs3ZxiEsOkCBaQ2usXSiKyh0ccsQ6k2OA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "3.821.0", - "@aws-sdk/credential-provider-http": "3.821.0", - "@aws-sdk/credential-provider-ini": "3.821.0", - "@aws-sdk/credential-provider-process": "3.821.0", - "@aws-sdk/credential-provider-sso": "3.821.0", - "@aws-sdk/credential-provider-web-identity": "3.821.0", + "@aws-sdk/credential-provider-env": "3.826.0", + "@aws-sdk/credential-provider-http": "3.826.0", + "@aws-sdk/credential-provider-ini": "3.830.0", + "@aws-sdk/credential-provider-process": "3.826.0", + "@aws-sdk/credential-provider-sso": "3.830.0", + "@aws-sdk/credential-provider-web-identity": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -2964,13 +3025,13 @@ } }, "node_modules/@aws-sdk/client-cloudwatch/node_modules/@aws-sdk/credential-provider-process": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.821.0.tgz", - "integrity": "sha512-e18ucfqKB3ICNj5RP/FEdvUfhVK6E9MALOsl8pKP13mwegug46p/1BsZWACD5n+Zf9ViiiHxIO7td03zQixfwA==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.826.0.tgz", + "integrity": "sha512-kURrc4amu3NLtw1yZw7EoLNEVhmOMRUTs+chaNcmS+ERm3yK0nKjaJzmKahmwlTQTSl3wJ8jjK7x962VPo+zWw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -2982,15 +3043,15 @@ } }, "node_modules/@aws-sdk/client-cloudwatch/node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.821.0.tgz", - "integrity": "sha512-Dt+pheBLom4O/egO4L75/72k9C1qtUOLl0F0h6lmqZe4Mvhz+wDtjoO/MdGC/P1q0kcIX/bBKr0NQ3cIvAH8pA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.830.0.tgz", + "integrity": "sha512-+VdRpZmfekzpySqZikAKx6l5ndnLGluioIgUG4ZznrButgFD/iogzFtGmBDFB3ZLViX1l4pMXru0zFwJEZT21Q==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.821.0", - "@aws-sdk/core": "3.821.0", - "@aws-sdk/token-providers": "3.821.0", + "@aws-sdk/client-sso": "3.830.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/token-providers": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -3002,14 +3063,14 @@ } }, "node_modules/@aws-sdk/client-cloudwatch/node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.821.0.tgz", - "integrity": "sha512-FF5wnRJkxSQaCVVvWNv53K1MhTMgH8d+O+MHTbkv51gVIgVATrtfFQMKBLcEAxzXrgAliIO3LiNv+1TqqBZ+BA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.830.0.tgz", + "integrity": "sha512-hPYrKsZeeOdLROJ59T6Y8yZ0iwC/60L3qhZXjapBFjbqBtMaQiMTI645K6xVXBioA6vxXq7B4aLOhYqk6Fy/Ww==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -3067,16 +3128,16 @@ } }, "node_modules/@aws-sdk/client-cloudwatch/node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.821.0.tgz", - "integrity": "sha512-rw8q3TxygMg3VrofN04QyWVCCyGwz3bVthYmBZZseENPWG3Krz1OCKcyqjkTcAxMQlEywOske+GIiOasGKnJ3w==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.828.0.tgz", + "integrity": "sha512-nixvI/SETXRdmrVab4D9LvXT3lrXkwAWGWk2GVvQvzlqN1/M/RfClj+o37Sn4FqRkGH9o9g7Fqb1YqZ4mqDAtA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", - "@smithy/core": "^3.5.1", + "@aws-sdk/util-endpoints": "3.828.0", + "@smithy/core": "^3.5.3", "@smithy/protocol-http": "^5.1.2", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" @@ -3086,45 +3147,45 @@ } }, "node_modules/@aws-sdk/client-cloudwatch/node_modules/@aws-sdk/nested-clients": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.821.0.tgz", - "integrity": "sha512-2IuHcUsWw44ftSEDYU4dvktTEqgyDvkOcfpoGC/UmT4Qo6TVCP3U5tWEGpNK9nN+7nLvekruxxG/jaMt5/oWVw==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.830.0.tgz", + "integrity": "sha512-5N5YTlBr1vtxf7+t+UaIQ625KEAmm7fY9o1e3MgGOi/paBoI0+axr3ud24qLIy0NSzFlAHEaxUSWxcERNjIoZw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -3154,14 +3215,14 @@ } }, "node_modules/@aws-sdk/client-cloudwatch/node_modules/@aws-sdk/token-providers": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.821.0.tgz", - "integrity": "sha512-qJ7wgKhdxGbPg718zWXbCYKDuSWZNU3TSw64hPRW6FtbZrIyZxObpiTKC6DKwfsVoZZhHEoP/imGykN1OdOTJA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.830.0.tgz", + "integrity": "sha512-aJ4guFwj92nV9D+EgJPaCFKK0I3y2uMchiDfh69Zqnmwfxxxfxat6F79VA7PS0BdbjRfhLbn+Ghjftnomu2c1g==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -3187,9 +3248,9 @@ } }, "node_modules/@aws-sdk/client-cloudwatch/node_modules/@aws-sdk/util-endpoints": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.821.0.tgz", - "integrity": "sha512-Uknt/zUZnLE76zaAAPEayOeF5/4IZ2puTFXvcSCWHsi9m3tqbb9UozlnlVqvCZLCRWfQryZQoG2W4XSS3qgk5A==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.828.0.tgz", + "integrity": "sha512-RvKch111SblqdkPzg3oCIdlGxlQs+k+P7Etory9FmxPHyPDvsP1j1c74PmgYqtzzMWmoXTjd+c9naUHh9xG8xg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3216,13 +3277,13 @@ } }, "node_modules/@aws-sdk/client-cloudwatch/node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.821.0.tgz", - "integrity": "sha512-YwMXc9EvuzJgnLBTyiQly2juPujXwDgcMHB0iSN92tHe7Dd1jJ1feBmTgdClaaqCeHFUaFpw+3JU/ZUJ6LjR+A==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.828.0.tgz", + "integrity": "sha512-LdN6fTBzTlQmc8O8f1wiZN0qF3yBWVGis7NwpWK7FUEzP9bEZRxYfIkV9oV9zpt6iNRze1SedK3JQVB/udxBoA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/types": "3.821.0", "@smithy/node-config-provider": "^4.1.3", "@smithy/types": "^4.3.1", @@ -3240,6 +3301,20 @@ } } }, + "node_modules/@aws-sdk/client-cloudwatch/node_modules/@aws-sdk/xml-builder": { + "version": "3.821.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.821.0.tgz", + "integrity": "sha512-DIIotRnefVL6DiaHtO6/21DhJ4JZnnIwdNbpwiAhdt/AVbttcE4yw925gsjur0OGv5BTYXQXU3YnANBYnZjuQA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@aws-sdk/client-codebuild": { "version": "3.741.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-codebuild/-/client-codebuild-3.741.0.tgz", @@ -3758,46 +3833,46 @@ } }, "node_modules/@aws-sdk/client-dynamodb": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.821.0.tgz", - "integrity": "sha512-7GyFMN0B7NW6rv1pT0PSWcAFPsziEYnxdZUnF/sMsgXz5U0peviCnuPGUL5jqYL6sf6HgXLYYooHVjqLnVMVVQ==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.830.0.tgz", + "integrity": "sha512-jen+bjGipjJMkPKnnYDXPrq/6HYaNr/l4Axcr9RlbROHLmS+kRWqlViCqRtLN1DVFOOfldbD/qVUtiwUCBWI5A==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", - "@aws-sdk/credential-provider-node": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/credential-provider-node": "3.830.0", "@aws-sdk/middleware-endpoint-discovery": "3.821.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -3812,44 +3887,44 @@ } }, "node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/client-sso": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.821.0.tgz", - "integrity": "sha512-aDEBZUKUd/+Tvudi0d9KQlqt2OW2P27LATZX0jkNC8yVk4145bAPS04EYoqdKLuyUn/U33DibEOgKUpxZB12jQ==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.830.0.tgz", + "integrity": "sha512-5zCEpfI+zwX2SIa258L+TItNbBoAvQQ6w74qdFM6YJufQ1F9tvwjTX8T+eSTT9nsFIvfYnUaGalWwJVfmJUgVQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -3861,20 +3936,24 @@ } }, "node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/core": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.821.0.tgz", - "integrity": "sha512-8eB3wKbmfciQFmxFq7hAjy7mXdUs7vBOR5SwT0ZtQBg0Txc18Lc9tMViqqdO6/KU7OukA6ib2IAVSjIJJEN7FQ==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.826.0.tgz", + "integrity": "sha512-BGbQYzWj3ps+dblq33FY5tz/SsgJCcXX0zjQlSC07tYvU1jHTUvsefphyig+fY38xZ4wdKjbTop+KUmXUYrOXw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.821.0", - "@smithy/core": "^3.5.1", + "@aws-sdk/xml-builder": "3.821.0", + "@smithy/core": "^3.5.3", "@smithy/node-config-provider": "^4.1.3", "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", "@smithy/signature-v4": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.4", + "@smithy/util-utf8": "^4.0.0", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" }, @@ -3883,12 +3962,12 @@ } }, "node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/credential-provider-env": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.821.0.tgz", - "integrity": "sha512-C+s/A72pd7CXwEsJj9+Uq9T726iIfIF18hGRY8o82xcIEfOyakiPnlisku8zZOaAu+jm0CihbbYN4NyYNQ+HZQ==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.826.0.tgz", + "integrity": "sha512-DK3pQY8+iKK3MGDdC3uOZQ2psU01obaKlTYhEwNu4VWzgwQL4Vi3sWj4xSWGEK41vqZxiRLq6fOq7ysRI+qEZA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -3899,18 +3978,18 @@ } }, "node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/credential-provider-http": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.821.0.tgz", - "integrity": "sha512-gIRzTLnAsRfRSNarCag7G7rhcHagz4x5nNTWRihQs5cwTOghEExDy7Tj5m4TEkv3dcTAsNn+l4tnR4nZXo6R+Q==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.826.0.tgz", + "integrity": "sha512-N+IVZBh+yx/9GbMZTKO/gErBi/FYZQtcFRItoLbY+6WU+0cSWyZYfkoeOxHmQV3iX9k65oljERIWUmL9x6OSQg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/node-http-handler": "^4.0.6", "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/util-stream": "^4.2.2", "tslib": "^2.6.2" @@ -3920,18 +3999,18 @@ } }, "node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.821.0.tgz", - "integrity": "sha512-VRTrmsca8kBHtY1tTek1ce+XkK/H0fzodBKcilM/qXjTyumMHPAzVAxKZfSvGC+28/pXyQzhOEyxZfw7giCiWA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/credential-provider-env": "3.821.0", - "@aws-sdk/credential-provider-http": "3.821.0", - "@aws-sdk/credential-provider-process": "3.821.0", - "@aws-sdk/credential-provider-sso": "3.821.0", - "@aws-sdk/credential-provider-web-identity": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.830.0.tgz", + "integrity": "sha512-zeQenzvh8JRY5nULd8izdjVGoCM1tgsVVsrLSwDkHxZTTW0hW/bmOmXfvdaE0wDdomXW7m2CkQDSmP7XdvNXZg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.826.0", + "@aws-sdk/credential-provider-env": "3.826.0", + "@aws-sdk/credential-provider-http": "3.826.0", + "@aws-sdk/credential-provider-process": "3.826.0", + "@aws-sdk/credential-provider-sso": "3.830.0", + "@aws-sdk/credential-provider-web-identity": "3.830.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -3944,17 +4023,17 @@ } }, "node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/credential-provider-node": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.821.0.tgz", - "integrity": "sha512-oBgbcgOXWMgknAfhIdTeHSSVIv+k2LXN9oTbxu1r++o4WWBWrEQ8mHU0Zo9dfr7Uaoqi3pezYZznsBkXnMLEOg==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.830.0.tgz", + "integrity": "sha512-X/2LrTgwtK1pkWrvofxQBI8VTi6QVLtSMpsKKPPnJQ0vgqC0e4czSIs3ZxiEsOkCBaQ2usXSiKyh0ccsQ6k2OA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "3.821.0", - "@aws-sdk/credential-provider-http": "3.821.0", - "@aws-sdk/credential-provider-ini": "3.821.0", - "@aws-sdk/credential-provider-process": "3.821.0", - "@aws-sdk/credential-provider-sso": "3.821.0", - "@aws-sdk/credential-provider-web-identity": "3.821.0", + "@aws-sdk/credential-provider-env": "3.826.0", + "@aws-sdk/credential-provider-http": "3.826.0", + "@aws-sdk/credential-provider-ini": "3.830.0", + "@aws-sdk/credential-provider-process": "3.826.0", + "@aws-sdk/credential-provider-sso": "3.830.0", + "@aws-sdk/credential-provider-web-identity": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -3967,12 +4046,12 @@ } }, "node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/credential-provider-process": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.821.0.tgz", - "integrity": "sha512-e18ucfqKB3ICNj5RP/FEdvUfhVK6E9MALOsl8pKP13mwegug46p/1BsZWACD5n+Zf9ViiiHxIO7td03zQixfwA==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.826.0.tgz", + "integrity": "sha512-kURrc4amu3NLtw1yZw7EoLNEVhmOMRUTs+chaNcmS+ERm3yK0nKjaJzmKahmwlTQTSl3wJ8jjK7x962VPo+zWw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -3984,14 +4063,14 @@ } }, "node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.821.0.tgz", - "integrity": "sha512-Dt+pheBLom4O/egO4L75/72k9C1qtUOLl0F0h6lmqZe4Mvhz+wDtjoO/MdGC/P1q0kcIX/bBKr0NQ3cIvAH8pA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.830.0.tgz", + "integrity": "sha512-+VdRpZmfekzpySqZikAKx6l5ndnLGluioIgUG4ZznrButgFD/iogzFtGmBDFB3ZLViX1l4pMXru0zFwJEZT21Q==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.821.0", - "@aws-sdk/core": "3.821.0", - "@aws-sdk/token-providers": "3.821.0", + "@aws-sdk/client-sso": "3.830.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/token-providers": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -4003,13 +4082,13 @@ } }, "node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.821.0.tgz", - "integrity": "sha512-FF5wnRJkxSQaCVVvWNv53K1MhTMgH8d+O+MHTbkv51gVIgVATrtfFQMKBLcEAxzXrgAliIO3LiNv+1TqqBZ+BA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.830.0.tgz", + "integrity": "sha512-hPYrKsZeeOdLROJ59T6Y8yZ0iwC/60L3qhZXjapBFjbqBtMaQiMTI645K6xVXBioA6vxXq7B4aLOhYqk6Fy/Ww==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -4064,15 +4143,15 @@ } }, "node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.821.0.tgz", - "integrity": "sha512-rw8q3TxygMg3VrofN04QyWVCCyGwz3bVthYmBZZseENPWG3Krz1OCKcyqjkTcAxMQlEywOske+GIiOasGKnJ3w==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.828.0.tgz", + "integrity": "sha512-nixvI/SETXRdmrVab4D9LvXT3lrXkwAWGWk2GVvQvzlqN1/M/RfClj+o37Sn4FqRkGH9o9g7Fqb1YqZ4mqDAtA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", - "@smithy/core": "^3.5.1", + "@aws-sdk/util-endpoints": "3.828.0", + "@smithy/core": "^3.5.3", "@smithy/protocol-http": "^5.1.2", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" @@ -4082,44 +4161,44 @@ } }, "node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/nested-clients": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.821.0.tgz", - "integrity": "sha512-2IuHcUsWw44ftSEDYU4dvktTEqgyDvkOcfpoGC/UmT4Qo6TVCP3U5tWEGpNK9nN+7nLvekruxxG/jaMt5/oWVw==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.830.0.tgz", + "integrity": "sha512-5N5YTlBr1vtxf7+t+UaIQ625KEAmm7fY9o1e3MgGOi/paBoI0+axr3ud24qLIy0NSzFlAHEaxUSWxcERNjIoZw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -4148,13 +4227,13 @@ } }, "node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/token-providers": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.821.0.tgz", - "integrity": "sha512-qJ7wgKhdxGbPg718zWXbCYKDuSWZNU3TSw64hPRW6FtbZrIyZxObpiTKC6DKwfsVoZZhHEoP/imGykN1OdOTJA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.830.0.tgz", + "integrity": "sha512-aJ4guFwj92nV9D+EgJPaCFKK0I3y2uMchiDfh69Zqnmwfxxxfxat6F79VA7PS0BdbjRfhLbn+Ghjftnomu2c1g==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -4179,9 +4258,9 @@ } }, "node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/util-endpoints": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.821.0.tgz", - "integrity": "sha512-Uknt/zUZnLE76zaAAPEayOeF5/4IZ2puTFXvcSCWHsi9m3tqbb9UozlnlVqvCZLCRWfQryZQoG2W4XSS3qgk5A==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.828.0.tgz", + "integrity": "sha512-RvKch111SblqdkPzg3oCIdlGxlQs+k+P7Etory9FmxPHyPDvsP1j1c74PmgYqtzzMWmoXTjd+c9naUHh9xG8xg==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.821.0", @@ -4206,12 +4285,12 @@ } }, "node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.821.0.tgz", - "integrity": "sha512-YwMXc9EvuzJgnLBTyiQly2juPujXwDgcMHB0iSN92tHe7Dd1jJ1feBmTgdClaaqCeHFUaFpw+3JU/ZUJ6LjR+A==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.828.0.tgz", + "integrity": "sha512-LdN6fTBzTlQmc8O8f1wiZN0qF3yBWVGis7NwpWK7FUEzP9bEZRxYfIkV9oV9zpt6iNRze1SedK3JQVB/udxBoA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/types": "3.821.0", "@smithy/node-config-provider": "^4.1.3", "@smithy/types": "^4.3.1", @@ -4229,6 +4308,19 @@ } } }, + "node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/xml-builder": { + "version": "3.821.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.821.0.tgz", + "integrity": "sha512-DIIotRnefVL6DiaHtO6/21DhJ4JZnnIwdNbpwiAhdt/AVbttcE4yw925gsjur0OGv5BTYXQXU3YnANBYnZjuQA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@aws-sdk/client-ec2": { "version": "3.741.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-ec2/-/client-ec2-3.741.0.tgz", @@ -6281,26 +6373,26 @@ } }, "node_modules/@aws-sdk/client-lambda": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.821.0.tgz", - "integrity": "sha512-251WeT6d0L5EmpIMAhi3C9ujDftG9TEuzt78A8cW4EQp6BZrVTZFG+FZi+Yef06AUQRdZWY1rUx4nE6WOl6Hkw==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.830.0.tgz", + "integrity": "sha512-rdZPFteEN4Tw8vNVKh5rwPhf2zJz3cazx2gf1NSB8+GtleefY6bsAqyOQueSMSkE6fGZw7kmaPJBvWDxzMX4nQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", - "@aws-sdk/credential-provider-node": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/credential-provider-node": "3.830.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/eventstream-serde-browser": "^4.0.4", "@smithy/eventstream-serde-config-resolver": "^4.1.2", "@smithy/eventstream-serde-node": "^4.0.4", @@ -6308,21 +6400,21 @@ "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -6336,44 +6428,44 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/client-sso": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.821.0.tgz", - "integrity": "sha512-aDEBZUKUd/+Tvudi0d9KQlqt2OW2P27LATZX0jkNC8yVk4145bAPS04EYoqdKLuyUn/U33DibEOgKUpxZB12jQ==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.830.0.tgz", + "integrity": "sha512-5zCEpfI+zwX2SIa258L+TItNbBoAvQQ6w74qdFM6YJufQ1F9tvwjTX8T+eSTT9nsFIvfYnUaGalWwJVfmJUgVQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -6385,20 +6477,24 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/core": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.821.0.tgz", - "integrity": "sha512-8eB3wKbmfciQFmxFq7hAjy7mXdUs7vBOR5SwT0ZtQBg0Txc18Lc9tMViqqdO6/KU7OukA6ib2IAVSjIJJEN7FQ==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.826.0.tgz", + "integrity": "sha512-BGbQYzWj3ps+dblq33FY5tz/SsgJCcXX0zjQlSC07tYvU1jHTUvsefphyig+fY38xZ4wdKjbTop+KUmXUYrOXw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.821.0", - "@smithy/core": "^3.5.1", + "@aws-sdk/xml-builder": "3.821.0", + "@smithy/core": "^3.5.3", "@smithy/node-config-provider": "^4.1.3", "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", "@smithy/signature-v4": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.4", + "@smithy/util-utf8": "^4.0.0", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" }, @@ -6407,12 +6503,12 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-env": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.821.0.tgz", - "integrity": "sha512-C+s/A72pd7CXwEsJj9+Uq9T726iIfIF18hGRY8o82xcIEfOyakiPnlisku8zZOaAu+jm0CihbbYN4NyYNQ+HZQ==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.826.0.tgz", + "integrity": "sha512-DK3pQY8+iKK3MGDdC3uOZQ2psU01obaKlTYhEwNu4VWzgwQL4Vi3sWj4xSWGEK41vqZxiRLq6fOq7ysRI+qEZA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -6423,18 +6519,18 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-http": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.821.0.tgz", - "integrity": "sha512-gIRzTLnAsRfRSNarCag7G7rhcHagz4x5nNTWRihQs5cwTOghEExDy7Tj5m4TEkv3dcTAsNn+l4tnR4nZXo6R+Q==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.826.0.tgz", + "integrity": "sha512-N+IVZBh+yx/9GbMZTKO/gErBi/FYZQtcFRItoLbY+6WU+0cSWyZYfkoeOxHmQV3iX9k65oljERIWUmL9x6OSQg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/node-http-handler": "^4.0.6", "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/util-stream": "^4.2.2", "tslib": "^2.6.2" @@ -6444,18 +6540,18 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.821.0.tgz", - "integrity": "sha512-VRTrmsca8kBHtY1tTek1ce+XkK/H0fzodBKcilM/qXjTyumMHPAzVAxKZfSvGC+28/pXyQzhOEyxZfw7giCiWA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/credential-provider-env": "3.821.0", - "@aws-sdk/credential-provider-http": "3.821.0", - "@aws-sdk/credential-provider-process": "3.821.0", - "@aws-sdk/credential-provider-sso": "3.821.0", - "@aws-sdk/credential-provider-web-identity": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.830.0.tgz", + "integrity": "sha512-zeQenzvh8JRY5nULd8izdjVGoCM1tgsVVsrLSwDkHxZTTW0hW/bmOmXfvdaE0wDdomXW7m2CkQDSmP7XdvNXZg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.826.0", + "@aws-sdk/credential-provider-env": "3.826.0", + "@aws-sdk/credential-provider-http": "3.826.0", + "@aws-sdk/credential-provider-process": "3.826.0", + "@aws-sdk/credential-provider-sso": "3.830.0", + "@aws-sdk/credential-provider-web-identity": "3.830.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -6468,17 +6564,17 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-node": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.821.0.tgz", - "integrity": "sha512-oBgbcgOXWMgknAfhIdTeHSSVIv+k2LXN9oTbxu1r++o4WWBWrEQ8mHU0Zo9dfr7Uaoqi3pezYZznsBkXnMLEOg==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.830.0.tgz", + "integrity": "sha512-X/2LrTgwtK1pkWrvofxQBI8VTi6QVLtSMpsKKPPnJQ0vgqC0e4czSIs3ZxiEsOkCBaQ2usXSiKyh0ccsQ6k2OA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "3.821.0", - "@aws-sdk/credential-provider-http": "3.821.0", - "@aws-sdk/credential-provider-ini": "3.821.0", - "@aws-sdk/credential-provider-process": "3.821.0", - "@aws-sdk/credential-provider-sso": "3.821.0", - "@aws-sdk/credential-provider-web-identity": "3.821.0", + "@aws-sdk/credential-provider-env": "3.826.0", + "@aws-sdk/credential-provider-http": "3.826.0", + "@aws-sdk/credential-provider-ini": "3.830.0", + "@aws-sdk/credential-provider-process": "3.826.0", + "@aws-sdk/credential-provider-sso": "3.830.0", + "@aws-sdk/credential-provider-web-identity": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -6491,12 +6587,12 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-process": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.821.0.tgz", - "integrity": "sha512-e18ucfqKB3ICNj5RP/FEdvUfhVK6E9MALOsl8pKP13mwegug46p/1BsZWACD5n+Zf9ViiiHxIO7td03zQixfwA==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.826.0.tgz", + "integrity": "sha512-kURrc4amu3NLtw1yZw7EoLNEVhmOMRUTs+chaNcmS+ERm3yK0nKjaJzmKahmwlTQTSl3wJ8jjK7x962VPo+zWw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -6508,14 +6604,14 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.821.0.tgz", - "integrity": "sha512-Dt+pheBLom4O/egO4L75/72k9C1qtUOLl0F0h6lmqZe4Mvhz+wDtjoO/MdGC/P1q0kcIX/bBKr0NQ3cIvAH8pA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.830.0.tgz", + "integrity": "sha512-+VdRpZmfekzpySqZikAKx6l5ndnLGluioIgUG4ZznrButgFD/iogzFtGmBDFB3ZLViX1l4pMXru0zFwJEZT21Q==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.821.0", - "@aws-sdk/core": "3.821.0", - "@aws-sdk/token-providers": "3.821.0", + "@aws-sdk/client-sso": "3.830.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/token-providers": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -6527,13 +6623,13 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.821.0.tgz", - "integrity": "sha512-FF5wnRJkxSQaCVVvWNv53K1MhTMgH8d+O+MHTbkv51gVIgVATrtfFQMKBLcEAxzXrgAliIO3LiNv+1TqqBZ+BA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.830.0.tgz", + "integrity": "sha512-hPYrKsZeeOdLROJ59T6Y8yZ0iwC/60L3qhZXjapBFjbqBtMaQiMTI645K6xVXBioA6vxXq7B4aLOhYqk6Fy/Ww==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -6588,15 +6684,15 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.821.0.tgz", - "integrity": "sha512-rw8q3TxygMg3VrofN04QyWVCCyGwz3bVthYmBZZseENPWG3Krz1OCKcyqjkTcAxMQlEywOske+GIiOasGKnJ3w==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.828.0.tgz", + "integrity": "sha512-nixvI/SETXRdmrVab4D9LvXT3lrXkwAWGWk2GVvQvzlqN1/M/RfClj+o37Sn4FqRkGH9o9g7Fqb1YqZ4mqDAtA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", - "@smithy/core": "^3.5.1", + "@aws-sdk/util-endpoints": "3.828.0", + "@smithy/core": "^3.5.3", "@smithy/protocol-http": "^5.1.2", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" @@ -6606,44 +6702,44 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/nested-clients": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.821.0.tgz", - "integrity": "sha512-2IuHcUsWw44ftSEDYU4dvktTEqgyDvkOcfpoGC/UmT4Qo6TVCP3U5tWEGpNK9nN+7nLvekruxxG/jaMt5/oWVw==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.830.0.tgz", + "integrity": "sha512-5N5YTlBr1vtxf7+t+UaIQ625KEAmm7fY9o1e3MgGOi/paBoI0+axr3ud24qLIy0NSzFlAHEaxUSWxcERNjIoZw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -6672,13 +6768,13 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/token-providers": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.821.0.tgz", - "integrity": "sha512-qJ7wgKhdxGbPg718zWXbCYKDuSWZNU3TSw64hPRW6FtbZrIyZxObpiTKC6DKwfsVoZZhHEoP/imGykN1OdOTJA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.830.0.tgz", + "integrity": "sha512-aJ4guFwj92nV9D+EgJPaCFKK0I3y2uMchiDfh69Zqnmwfxxxfxat6F79VA7PS0BdbjRfhLbn+Ghjftnomu2c1g==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -6703,9 +6799,9 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/util-endpoints": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.821.0.tgz", - "integrity": "sha512-Uknt/zUZnLE76zaAAPEayOeF5/4IZ2puTFXvcSCWHsi9m3tqbb9UozlnlVqvCZLCRWfQryZQoG2W4XSS3qgk5A==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.828.0.tgz", + "integrity": "sha512-RvKch111SblqdkPzg3oCIdlGxlQs+k+P7Etory9FmxPHyPDvsP1j1c74PmgYqtzzMWmoXTjd+c9naUHh9xG8xg==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.821.0", @@ -6730,12 +6826,12 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.821.0.tgz", - "integrity": "sha512-YwMXc9EvuzJgnLBTyiQly2juPujXwDgcMHB0iSN92tHe7Dd1jJ1feBmTgdClaaqCeHFUaFpw+3JU/ZUJ6LjR+A==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.828.0.tgz", + "integrity": "sha512-LdN6fTBzTlQmc8O8f1wiZN0qF3yBWVGis7NwpWK7FUEzP9bEZRxYfIkV9oV9zpt6iNRze1SedK3JQVB/udxBoA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/types": "3.821.0", "@smithy/node-config-provider": "^4.1.3", "@smithy/types": "^4.3.1", @@ -6753,6 +6849,19 @@ } } }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/xml-builder": { + "version": "3.821.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.821.0.tgz", + "integrity": "sha512-DIIotRnefVL6DiaHtO6/21DhJ4JZnnIwdNbpwiAhdt/AVbttcE4yw925gsjur0OGv5BTYXQXU3YnANBYnZjuQA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@aws-sdk/client-route-53": { "version": "3.741.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-route-53/-/client-route-53-3.741.0.tgz", @@ -7304,45 +7413,45 @@ } }, "node_modules/@aws-sdk/client-secrets-manager": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.821.0.tgz", - "integrity": "sha512-qsjNmliylXGr1Dod64Nh4hm9NkScJujflBjcoEWmUc5+Z9IwEovgUGLseC1KLVKIBdsVySje6LAEVvvjcWovmw==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.830.0.tgz", + "integrity": "sha512-St2EK5i91vwv9LmDUmWevZYl+Y/TYRP/AHm7gxZm1LkEf1VEjkSizUMm91JOnH6y+0Clok9mqe6jZ/XossMXlw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", - "@aws-sdk/credential-provider-node": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/credential-provider-node": "3.830.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -7356,44 +7465,44 @@ } }, "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/client-sso": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.821.0.tgz", - "integrity": "sha512-aDEBZUKUd/+Tvudi0d9KQlqt2OW2P27LATZX0jkNC8yVk4145bAPS04EYoqdKLuyUn/U33DibEOgKUpxZB12jQ==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.830.0.tgz", + "integrity": "sha512-5zCEpfI+zwX2SIa258L+TItNbBoAvQQ6w74qdFM6YJufQ1F9tvwjTX8T+eSTT9nsFIvfYnUaGalWwJVfmJUgVQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -7405,20 +7514,24 @@ } }, "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/core": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.821.0.tgz", - "integrity": "sha512-8eB3wKbmfciQFmxFq7hAjy7mXdUs7vBOR5SwT0ZtQBg0Txc18Lc9tMViqqdO6/KU7OukA6ib2IAVSjIJJEN7FQ==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.826.0.tgz", + "integrity": "sha512-BGbQYzWj3ps+dblq33FY5tz/SsgJCcXX0zjQlSC07tYvU1jHTUvsefphyig+fY38xZ4wdKjbTop+KUmXUYrOXw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.821.0", - "@smithy/core": "^3.5.1", + "@aws-sdk/xml-builder": "3.821.0", + "@smithy/core": "^3.5.3", "@smithy/node-config-provider": "^4.1.3", "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", "@smithy/signature-v4": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.4", + "@smithy/util-utf8": "^4.0.0", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" }, @@ -7427,12 +7540,12 @@ } }, "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-env": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.821.0.tgz", - "integrity": "sha512-C+s/A72pd7CXwEsJj9+Uq9T726iIfIF18hGRY8o82xcIEfOyakiPnlisku8zZOaAu+jm0CihbbYN4NyYNQ+HZQ==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.826.0.tgz", + "integrity": "sha512-DK3pQY8+iKK3MGDdC3uOZQ2psU01obaKlTYhEwNu4VWzgwQL4Vi3sWj4xSWGEK41vqZxiRLq6fOq7ysRI+qEZA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -7443,18 +7556,18 @@ } }, "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-http": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.821.0.tgz", - "integrity": "sha512-gIRzTLnAsRfRSNarCag7G7rhcHagz4x5nNTWRihQs5cwTOghEExDy7Tj5m4TEkv3dcTAsNn+l4tnR4nZXo6R+Q==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.826.0.tgz", + "integrity": "sha512-N+IVZBh+yx/9GbMZTKO/gErBi/FYZQtcFRItoLbY+6WU+0cSWyZYfkoeOxHmQV3iX9k65oljERIWUmL9x6OSQg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/node-http-handler": "^4.0.6", "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/util-stream": "^4.2.2", "tslib": "^2.6.2" @@ -7464,18 +7577,18 @@ } }, "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.821.0.tgz", - "integrity": "sha512-VRTrmsca8kBHtY1tTek1ce+XkK/H0fzodBKcilM/qXjTyumMHPAzVAxKZfSvGC+28/pXyQzhOEyxZfw7giCiWA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/credential-provider-env": "3.821.0", - "@aws-sdk/credential-provider-http": "3.821.0", - "@aws-sdk/credential-provider-process": "3.821.0", - "@aws-sdk/credential-provider-sso": "3.821.0", - "@aws-sdk/credential-provider-web-identity": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.830.0.tgz", + "integrity": "sha512-zeQenzvh8JRY5nULd8izdjVGoCM1tgsVVsrLSwDkHxZTTW0hW/bmOmXfvdaE0wDdomXW7m2CkQDSmP7XdvNXZg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.826.0", + "@aws-sdk/credential-provider-env": "3.826.0", + "@aws-sdk/credential-provider-http": "3.826.0", + "@aws-sdk/credential-provider-process": "3.826.0", + "@aws-sdk/credential-provider-sso": "3.830.0", + "@aws-sdk/credential-provider-web-identity": "3.830.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -7488,17 +7601,17 @@ } }, "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-node": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.821.0.tgz", - "integrity": "sha512-oBgbcgOXWMgknAfhIdTeHSSVIv+k2LXN9oTbxu1r++o4WWBWrEQ8mHU0Zo9dfr7Uaoqi3pezYZznsBkXnMLEOg==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.830.0.tgz", + "integrity": "sha512-X/2LrTgwtK1pkWrvofxQBI8VTi6QVLtSMpsKKPPnJQ0vgqC0e4czSIs3ZxiEsOkCBaQ2usXSiKyh0ccsQ6k2OA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "3.821.0", - "@aws-sdk/credential-provider-http": "3.821.0", - "@aws-sdk/credential-provider-ini": "3.821.0", - "@aws-sdk/credential-provider-process": "3.821.0", - "@aws-sdk/credential-provider-sso": "3.821.0", - "@aws-sdk/credential-provider-web-identity": "3.821.0", + "@aws-sdk/credential-provider-env": "3.826.0", + "@aws-sdk/credential-provider-http": "3.826.0", + "@aws-sdk/credential-provider-ini": "3.830.0", + "@aws-sdk/credential-provider-process": "3.826.0", + "@aws-sdk/credential-provider-sso": "3.830.0", + "@aws-sdk/credential-provider-web-identity": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -7511,12 +7624,12 @@ } }, "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-process": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.821.0.tgz", - "integrity": "sha512-e18ucfqKB3ICNj5RP/FEdvUfhVK6E9MALOsl8pKP13mwegug46p/1BsZWACD5n+Zf9ViiiHxIO7td03zQixfwA==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.826.0.tgz", + "integrity": "sha512-kURrc4amu3NLtw1yZw7EoLNEVhmOMRUTs+chaNcmS+ERm3yK0nKjaJzmKahmwlTQTSl3wJ8jjK7x962VPo+zWw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -7528,14 +7641,14 @@ } }, "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.821.0.tgz", - "integrity": "sha512-Dt+pheBLom4O/egO4L75/72k9C1qtUOLl0F0h6lmqZe4Mvhz+wDtjoO/MdGC/P1q0kcIX/bBKr0NQ3cIvAH8pA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.830.0.tgz", + "integrity": "sha512-+VdRpZmfekzpySqZikAKx6l5ndnLGluioIgUG4ZznrButgFD/iogzFtGmBDFB3ZLViX1l4pMXru0zFwJEZT21Q==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.821.0", - "@aws-sdk/core": "3.821.0", - "@aws-sdk/token-providers": "3.821.0", + "@aws-sdk/client-sso": "3.830.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/token-providers": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -7547,13 +7660,13 @@ } }, "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.821.0.tgz", - "integrity": "sha512-FF5wnRJkxSQaCVVvWNv53K1MhTMgH8d+O+MHTbkv51gVIgVATrtfFQMKBLcEAxzXrgAliIO3LiNv+1TqqBZ+BA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.830.0.tgz", + "integrity": "sha512-hPYrKsZeeOdLROJ59T6Y8yZ0iwC/60L3qhZXjapBFjbqBtMaQiMTI645K6xVXBioA6vxXq7B4aLOhYqk6Fy/Ww==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -7608,15 +7721,15 @@ } }, "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.821.0.tgz", - "integrity": "sha512-rw8q3TxygMg3VrofN04QyWVCCyGwz3bVthYmBZZseENPWG3Krz1OCKcyqjkTcAxMQlEywOske+GIiOasGKnJ3w==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.828.0.tgz", + "integrity": "sha512-nixvI/SETXRdmrVab4D9LvXT3lrXkwAWGWk2GVvQvzlqN1/M/RfClj+o37Sn4FqRkGH9o9g7Fqb1YqZ4mqDAtA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", - "@smithy/core": "^3.5.1", + "@aws-sdk/util-endpoints": "3.828.0", + "@smithy/core": "^3.5.3", "@smithy/protocol-http": "^5.1.2", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" @@ -7626,44 +7739,44 @@ } }, "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/nested-clients": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.821.0.tgz", - "integrity": "sha512-2IuHcUsWw44ftSEDYU4dvktTEqgyDvkOcfpoGC/UmT4Qo6TVCP3U5tWEGpNK9nN+7nLvekruxxG/jaMt5/oWVw==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.830.0.tgz", + "integrity": "sha512-5N5YTlBr1vtxf7+t+UaIQ625KEAmm7fY9o1e3MgGOi/paBoI0+axr3ud24qLIy0NSzFlAHEaxUSWxcERNjIoZw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -7692,13 +7805,13 @@ } }, "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/token-providers": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.821.0.tgz", - "integrity": "sha512-qJ7wgKhdxGbPg718zWXbCYKDuSWZNU3TSw64hPRW6FtbZrIyZxObpiTKC6DKwfsVoZZhHEoP/imGykN1OdOTJA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.830.0.tgz", + "integrity": "sha512-aJ4guFwj92nV9D+EgJPaCFKK0I3y2uMchiDfh69Zqnmwfxxxfxat6F79VA7PS0BdbjRfhLbn+Ghjftnomu2c1g==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -7723,9 +7836,9 @@ } }, "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/util-endpoints": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.821.0.tgz", - "integrity": "sha512-Uknt/zUZnLE76zaAAPEayOeF5/4IZ2puTFXvcSCWHsi9m3tqbb9UozlnlVqvCZLCRWfQryZQoG2W4XSS3qgk5A==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.828.0.tgz", + "integrity": "sha512-RvKch111SblqdkPzg3oCIdlGxlQs+k+P7Etory9FmxPHyPDvsP1j1c74PmgYqtzzMWmoXTjd+c9naUHh9xG8xg==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.821.0", @@ -7750,12 +7863,12 @@ } }, "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.821.0.tgz", - "integrity": "sha512-YwMXc9EvuzJgnLBTyiQly2juPujXwDgcMHB0iSN92tHe7Dd1jJ1feBmTgdClaaqCeHFUaFpw+3JU/ZUJ6LjR+A==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.828.0.tgz", + "integrity": "sha512-LdN6fTBzTlQmc8O8f1wiZN0qF3yBWVGis7NwpWK7FUEzP9bEZRxYfIkV9oV9zpt6iNRze1SedK3JQVB/udxBoA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/types": "3.821.0", "@smithy/node-config-provider": "^4.1.3", "@smithy/types": "^4.3.1", @@ -7773,6 +7886,19 @@ } } }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/xml-builder": { + "version": "3.821.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.821.0.tgz", + "integrity": "sha512-DIIotRnefVL6DiaHtO6/21DhJ4JZnnIwdNbpwiAhdt/AVbttcE4yw925gsjur0OGv5BTYXQXU3YnANBYnZjuQA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@aws-sdk/client-sfn": { "version": "3.741.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sfn/-/client-sfn-3.741.0.tgz", @@ -8157,45 +8283,45 @@ } }, "node_modules/@aws-sdk/client-ssm": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-ssm/-/client-ssm-3.821.0.tgz", - "integrity": "sha512-4In4jRwq3Jsgs3E65fPnsnEB8AgId1L9AqMKSKoLhmnYyoXPcgdjGOsxFMe+f65LwFbdLGide0aeGt3J5NE/lA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-ssm/-/client-ssm-3.830.0.tgz", + "integrity": "sha512-eeYYfVldV7Od/tMcyWumufspKGwlu53XjhgF8zMC7e7P2D541iQ6LwvHuwScw8xhlqfHsBzMS/yCnsDeM4kNmw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", - "@aws-sdk/credential-provider-node": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/credential-provider-node": "3.830.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -8210,44 +8336,44 @@ } }, "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/client-sso": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.821.0.tgz", - "integrity": "sha512-aDEBZUKUd/+Tvudi0d9KQlqt2OW2P27LATZX0jkNC8yVk4145bAPS04EYoqdKLuyUn/U33DibEOgKUpxZB12jQ==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.830.0.tgz", + "integrity": "sha512-5zCEpfI+zwX2SIa258L+TItNbBoAvQQ6w74qdFM6YJufQ1F9tvwjTX8T+eSTT9nsFIvfYnUaGalWwJVfmJUgVQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -8259,20 +8385,24 @@ } }, "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/core": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.821.0.tgz", - "integrity": "sha512-8eB3wKbmfciQFmxFq7hAjy7mXdUs7vBOR5SwT0ZtQBg0Txc18Lc9tMViqqdO6/KU7OukA6ib2IAVSjIJJEN7FQ==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.826.0.tgz", + "integrity": "sha512-BGbQYzWj3ps+dblq33FY5tz/SsgJCcXX0zjQlSC07tYvU1jHTUvsefphyig+fY38xZ4wdKjbTop+KUmXUYrOXw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.821.0", - "@smithy/core": "^3.5.1", + "@aws-sdk/xml-builder": "3.821.0", + "@smithy/core": "^3.5.3", "@smithy/node-config-provider": "^4.1.3", "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", "@smithy/signature-v4": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.4", + "@smithy/util-utf8": "^4.0.0", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" }, @@ -8281,12 +8411,12 @@ } }, "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/credential-provider-env": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.821.0.tgz", - "integrity": "sha512-C+s/A72pd7CXwEsJj9+Uq9T726iIfIF18hGRY8o82xcIEfOyakiPnlisku8zZOaAu+jm0CihbbYN4NyYNQ+HZQ==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.826.0.tgz", + "integrity": "sha512-DK3pQY8+iKK3MGDdC3uOZQ2psU01obaKlTYhEwNu4VWzgwQL4Vi3sWj4xSWGEK41vqZxiRLq6fOq7ysRI+qEZA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -8297,18 +8427,18 @@ } }, "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/credential-provider-http": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.821.0.tgz", - "integrity": "sha512-gIRzTLnAsRfRSNarCag7G7rhcHagz4x5nNTWRihQs5cwTOghEExDy7Tj5m4TEkv3dcTAsNn+l4tnR4nZXo6R+Q==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.826.0.tgz", + "integrity": "sha512-N+IVZBh+yx/9GbMZTKO/gErBi/FYZQtcFRItoLbY+6WU+0cSWyZYfkoeOxHmQV3iX9k65oljERIWUmL9x6OSQg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/node-http-handler": "^4.0.6", "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/util-stream": "^4.2.2", "tslib": "^2.6.2" @@ -8318,18 +8448,18 @@ } }, "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.821.0.tgz", - "integrity": "sha512-VRTrmsca8kBHtY1tTek1ce+XkK/H0fzodBKcilM/qXjTyumMHPAzVAxKZfSvGC+28/pXyQzhOEyxZfw7giCiWA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/credential-provider-env": "3.821.0", - "@aws-sdk/credential-provider-http": "3.821.0", - "@aws-sdk/credential-provider-process": "3.821.0", - "@aws-sdk/credential-provider-sso": "3.821.0", - "@aws-sdk/credential-provider-web-identity": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.830.0.tgz", + "integrity": "sha512-zeQenzvh8JRY5nULd8izdjVGoCM1tgsVVsrLSwDkHxZTTW0hW/bmOmXfvdaE0wDdomXW7m2CkQDSmP7XdvNXZg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.826.0", + "@aws-sdk/credential-provider-env": "3.826.0", + "@aws-sdk/credential-provider-http": "3.826.0", + "@aws-sdk/credential-provider-process": "3.826.0", + "@aws-sdk/credential-provider-sso": "3.830.0", + "@aws-sdk/credential-provider-web-identity": "3.830.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -8342,17 +8472,17 @@ } }, "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/credential-provider-node": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.821.0.tgz", - "integrity": "sha512-oBgbcgOXWMgknAfhIdTeHSSVIv+k2LXN9oTbxu1r++o4WWBWrEQ8mHU0Zo9dfr7Uaoqi3pezYZznsBkXnMLEOg==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.830.0.tgz", + "integrity": "sha512-X/2LrTgwtK1pkWrvofxQBI8VTi6QVLtSMpsKKPPnJQ0vgqC0e4czSIs3ZxiEsOkCBaQ2usXSiKyh0ccsQ6k2OA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "3.821.0", - "@aws-sdk/credential-provider-http": "3.821.0", - "@aws-sdk/credential-provider-ini": "3.821.0", - "@aws-sdk/credential-provider-process": "3.821.0", - "@aws-sdk/credential-provider-sso": "3.821.0", - "@aws-sdk/credential-provider-web-identity": "3.821.0", + "@aws-sdk/credential-provider-env": "3.826.0", + "@aws-sdk/credential-provider-http": "3.826.0", + "@aws-sdk/credential-provider-ini": "3.830.0", + "@aws-sdk/credential-provider-process": "3.826.0", + "@aws-sdk/credential-provider-sso": "3.830.0", + "@aws-sdk/credential-provider-web-identity": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -8365,12 +8495,12 @@ } }, "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/credential-provider-process": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.821.0.tgz", - "integrity": "sha512-e18ucfqKB3ICNj5RP/FEdvUfhVK6E9MALOsl8pKP13mwegug46p/1BsZWACD5n+Zf9ViiiHxIO7td03zQixfwA==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.826.0.tgz", + "integrity": "sha512-kURrc4amu3NLtw1yZw7EoLNEVhmOMRUTs+chaNcmS+ERm3yK0nKjaJzmKahmwlTQTSl3wJ8jjK7x962VPo+zWw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -8382,14 +8512,14 @@ } }, "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.821.0.tgz", - "integrity": "sha512-Dt+pheBLom4O/egO4L75/72k9C1qtUOLl0F0h6lmqZe4Mvhz+wDtjoO/MdGC/P1q0kcIX/bBKr0NQ3cIvAH8pA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.830.0.tgz", + "integrity": "sha512-+VdRpZmfekzpySqZikAKx6l5ndnLGluioIgUG4ZznrButgFD/iogzFtGmBDFB3ZLViX1l4pMXru0zFwJEZT21Q==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.821.0", - "@aws-sdk/core": "3.821.0", - "@aws-sdk/token-providers": "3.821.0", + "@aws-sdk/client-sso": "3.830.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/token-providers": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -8401,13 +8531,13 @@ } }, "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.821.0.tgz", - "integrity": "sha512-FF5wnRJkxSQaCVVvWNv53K1MhTMgH8d+O+MHTbkv51gVIgVATrtfFQMKBLcEAxzXrgAliIO3LiNv+1TqqBZ+BA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.830.0.tgz", + "integrity": "sha512-hPYrKsZeeOdLROJ59T6Y8yZ0iwC/60L3qhZXjapBFjbqBtMaQiMTI645K6xVXBioA6vxXq7B4aLOhYqk6Fy/Ww==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -8462,15 +8592,15 @@ } }, "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.821.0.tgz", - "integrity": "sha512-rw8q3TxygMg3VrofN04QyWVCCyGwz3bVthYmBZZseENPWG3Krz1OCKcyqjkTcAxMQlEywOske+GIiOasGKnJ3w==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.828.0.tgz", + "integrity": "sha512-nixvI/SETXRdmrVab4D9LvXT3lrXkwAWGWk2GVvQvzlqN1/M/RfClj+o37Sn4FqRkGH9o9g7Fqb1YqZ4mqDAtA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", - "@smithy/core": "^3.5.1", + "@aws-sdk/util-endpoints": "3.828.0", + "@smithy/core": "^3.5.3", "@smithy/protocol-http": "^5.1.2", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" @@ -8480,44 +8610,44 @@ } }, "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/nested-clients": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.821.0.tgz", - "integrity": "sha512-2IuHcUsWw44ftSEDYU4dvktTEqgyDvkOcfpoGC/UmT4Qo6TVCP3U5tWEGpNK9nN+7nLvekruxxG/jaMt5/oWVw==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.830.0.tgz", + "integrity": "sha512-5N5YTlBr1vtxf7+t+UaIQ625KEAmm7fY9o1e3MgGOi/paBoI0+axr3ud24qLIy0NSzFlAHEaxUSWxcERNjIoZw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -8546,13 +8676,13 @@ } }, "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/token-providers": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.821.0.tgz", - "integrity": "sha512-qJ7wgKhdxGbPg718zWXbCYKDuSWZNU3TSw64hPRW6FtbZrIyZxObpiTKC6DKwfsVoZZhHEoP/imGykN1OdOTJA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.830.0.tgz", + "integrity": "sha512-aJ4guFwj92nV9D+EgJPaCFKK0I3y2uMchiDfh69Zqnmwfxxxfxat6F79VA7PS0BdbjRfhLbn+Ghjftnomu2c1g==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -8577,9 +8707,9 @@ } }, "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/util-endpoints": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.821.0.tgz", - "integrity": "sha512-Uknt/zUZnLE76zaAAPEayOeF5/4IZ2puTFXvcSCWHsi9m3tqbb9UozlnlVqvCZLCRWfQryZQoG2W4XSS3qgk5A==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.828.0.tgz", + "integrity": "sha512-RvKch111SblqdkPzg3oCIdlGxlQs+k+P7Etory9FmxPHyPDvsP1j1c74PmgYqtzzMWmoXTjd+c9naUHh9xG8xg==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.821.0", @@ -8604,12 +8734,12 @@ } }, "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.821.0.tgz", - "integrity": "sha512-YwMXc9EvuzJgnLBTyiQly2juPujXwDgcMHB0iSN92tHe7Dd1jJ1feBmTgdClaaqCeHFUaFpw+3JU/ZUJ6LjR+A==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.828.0.tgz", + "integrity": "sha512-LdN6fTBzTlQmc8O8f1wiZN0qF3yBWVGis7NwpWK7FUEzP9bEZRxYfIkV9oV9zpt6iNRze1SedK3JQVB/udxBoA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/types": "3.821.0", "@smithy/node-config-provider": "^4.1.3", "@smithy/types": "^4.3.1", @@ -8627,6 +8757,19 @@ } } }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/xml-builder": { + "version": "3.821.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.821.0.tgz", + "integrity": "sha512-DIIotRnefVL6DiaHtO6/21DhJ4JZnnIwdNbpwiAhdt/AVbttcE4yw925gsjur0OGv5BTYXQXU3YnANBYnZjuQA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@aws-sdk/client-sso": { "version": "3.808.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.808.0.tgz", @@ -8899,46 +9042,46 @@ } }, "node_modules/@aws-sdk/client-xray": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-xray/-/client-xray-3.821.0.tgz", - "integrity": "sha512-WTB4Y2aQS40rrwyhtB3g9WfVQvtBoa5Uo2F8AdpYcuBVnaMzVGpZjbPvPAcOIZ88eH6xsoSOa6fcRP8qA0l41Q==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-xray/-/client-xray-3.830.0.tgz", + "integrity": "sha512-P3PchwMM9khc3bN2PlioiFYdBw+NLtlybisWczmwyoqwLqQr0zBlrRkXTCx6fIHGVEAFzehIzE3AA5pABIgFog==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", - "@aws-sdk/credential-provider-node": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/credential-provider-node": "3.830.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -8950,45 +9093,45 @@ } }, "node_modules/@aws-sdk/client-xray/node_modules/@aws-sdk/client-sso": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.821.0.tgz", - "integrity": "sha512-aDEBZUKUd/+Tvudi0d9KQlqt2OW2P27LATZX0jkNC8yVk4145bAPS04EYoqdKLuyUn/U33DibEOgKUpxZB12jQ==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.830.0.tgz", + "integrity": "sha512-5zCEpfI+zwX2SIa258L+TItNbBoAvQQ6w74qdFM6YJufQ1F9tvwjTX8T+eSTT9nsFIvfYnUaGalWwJVfmJUgVQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -9000,21 +9143,25 @@ } }, "node_modules/@aws-sdk/client-xray/node_modules/@aws-sdk/core": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.821.0.tgz", - "integrity": "sha512-8eB3wKbmfciQFmxFq7hAjy7mXdUs7vBOR5SwT0ZtQBg0Txc18Lc9tMViqqdO6/KU7OukA6ib2IAVSjIJJEN7FQ==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.826.0.tgz", + "integrity": "sha512-BGbQYzWj3ps+dblq33FY5tz/SsgJCcXX0zjQlSC07tYvU1jHTUvsefphyig+fY38xZ4wdKjbTop+KUmXUYrOXw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.821.0", - "@smithy/core": "^3.5.1", + "@aws-sdk/xml-builder": "3.821.0", + "@smithy/core": "^3.5.3", "@smithy/node-config-provider": "^4.1.3", "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", "@smithy/signature-v4": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.4", + "@smithy/util-utf8": "^4.0.0", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" }, @@ -9023,13 +9170,13 @@ } }, "node_modules/@aws-sdk/client-xray/node_modules/@aws-sdk/credential-provider-env": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.821.0.tgz", - "integrity": "sha512-C+s/A72pd7CXwEsJj9+Uq9T726iIfIF18hGRY8o82xcIEfOyakiPnlisku8zZOaAu+jm0CihbbYN4NyYNQ+HZQ==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.826.0.tgz", + "integrity": "sha512-DK3pQY8+iKK3MGDdC3uOZQ2psU01obaKlTYhEwNu4VWzgwQL4Vi3sWj4xSWGEK41vqZxiRLq6fOq7ysRI+qEZA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -9040,19 +9187,19 @@ } }, "node_modules/@aws-sdk/client-xray/node_modules/@aws-sdk/credential-provider-http": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.821.0.tgz", - "integrity": "sha512-gIRzTLnAsRfRSNarCag7G7rhcHagz4x5nNTWRihQs5cwTOghEExDy7Tj5m4TEkv3dcTAsNn+l4tnR4nZXo6R+Q==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.826.0.tgz", + "integrity": "sha512-N+IVZBh+yx/9GbMZTKO/gErBi/FYZQtcFRItoLbY+6WU+0cSWyZYfkoeOxHmQV3iX9k65oljERIWUmL9x6OSQg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/node-http-handler": "^4.0.6", "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/util-stream": "^4.2.2", "tslib": "^2.6.2" @@ -9062,19 +9209,19 @@ } }, "node_modules/@aws-sdk/client-xray/node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.821.0.tgz", - "integrity": "sha512-VRTrmsca8kBHtY1tTek1ce+XkK/H0fzodBKcilM/qXjTyumMHPAzVAxKZfSvGC+28/pXyQzhOEyxZfw7giCiWA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.830.0.tgz", + "integrity": "sha512-zeQenzvh8JRY5nULd8izdjVGoCM1tgsVVsrLSwDkHxZTTW0hW/bmOmXfvdaE0wDdomXW7m2CkQDSmP7XdvNXZg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/credential-provider-env": "3.821.0", - "@aws-sdk/credential-provider-http": "3.821.0", - "@aws-sdk/credential-provider-process": "3.821.0", - "@aws-sdk/credential-provider-sso": "3.821.0", - "@aws-sdk/credential-provider-web-identity": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/credential-provider-env": "3.826.0", + "@aws-sdk/credential-provider-http": "3.826.0", + "@aws-sdk/credential-provider-process": "3.826.0", + "@aws-sdk/credential-provider-sso": "3.830.0", + "@aws-sdk/credential-provider-web-identity": "3.830.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -9087,18 +9234,18 @@ } }, "node_modules/@aws-sdk/client-xray/node_modules/@aws-sdk/credential-provider-node": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.821.0.tgz", - "integrity": "sha512-oBgbcgOXWMgknAfhIdTeHSSVIv+k2LXN9oTbxu1r++o4WWBWrEQ8mHU0Zo9dfr7Uaoqi3pezYZznsBkXnMLEOg==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.830.0.tgz", + "integrity": "sha512-X/2LrTgwtK1pkWrvofxQBI8VTi6QVLtSMpsKKPPnJQ0vgqC0e4czSIs3ZxiEsOkCBaQ2usXSiKyh0ccsQ6k2OA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "3.821.0", - "@aws-sdk/credential-provider-http": "3.821.0", - "@aws-sdk/credential-provider-ini": "3.821.0", - "@aws-sdk/credential-provider-process": "3.821.0", - "@aws-sdk/credential-provider-sso": "3.821.0", - "@aws-sdk/credential-provider-web-identity": "3.821.0", + "@aws-sdk/credential-provider-env": "3.826.0", + "@aws-sdk/credential-provider-http": "3.826.0", + "@aws-sdk/credential-provider-ini": "3.830.0", + "@aws-sdk/credential-provider-process": "3.826.0", + "@aws-sdk/credential-provider-sso": "3.830.0", + "@aws-sdk/credential-provider-web-identity": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -9111,13 +9258,13 @@ } }, "node_modules/@aws-sdk/client-xray/node_modules/@aws-sdk/credential-provider-process": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.821.0.tgz", - "integrity": "sha512-e18ucfqKB3ICNj5RP/FEdvUfhVK6E9MALOsl8pKP13mwegug46p/1BsZWACD5n+Zf9ViiiHxIO7td03zQixfwA==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.826.0.tgz", + "integrity": "sha512-kURrc4amu3NLtw1yZw7EoLNEVhmOMRUTs+chaNcmS+ERm3yK0nKjaJzmKahmwlTQTSl3wJ8jjK7x962VPo+zWw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -9129,15 +9276,15 @@ } }, "node_modules/@aws-sdk/client-xray/node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.821.0.tgz", - "integrity": "sha512-Dt+pheBLom4O/egO4L75/72k9C1qtUOLl0F0h6lmqZe4Mvhz+wDtjoO/MdGC/P1q0kcIX/bBKr0NQ3cIvAH8pA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.830.0.tgz", + "integrity": "sha512-+VdRpZmfekzpySqZikAKx6l5ndnLGluioIgUG4ZznrButgFD/iogzFtGmBDFB3ZLViX1l4pMXru0zFwJEZT21Q==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.821.0", - "@aws-sdk/core": "3.821.0", - "@aws-sdk/token-providers": "3.821.0", + "@aws-sdk/client-sso": "3.830.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/token-providers": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -9149,14 +9296,14 @@ } }, "node_modules/@aws-sdk/client-xray/node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.821.0.tgz", - "integrity": "sha512-FF5wnRJkxSQaCVVvWNv53K1MhTMgH8d+O+MHTbkv51gVIgVATrtfFQMKBLcEAxzXrgAliIO3LiNv+1TqqBZ+BA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.830.0.tgz", + "integrity": "sha512-hPYrKsZeeOdLROJ59T6Y8yZ0iwC/60L3qhZXjapBFjbqBtMaQiMTI645K6xVXBioA6vxXq7B4aLOhYqk6Fy/Ww==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -9214,16 +9361,16 @@ } }, "node_modules/@aws-sdk/client-xray/node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.821.0.tgz", - "integrity": "sha512-rw8q3TxygMg3VrofN04QyWVCCyGwz3bVthYmBZZseENPWG3Krz1OCKcyqjkTcAxMQlEywOske+GIiOasGKnJ3w==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.828.0.tgz", + "integrity": "sha512-nixvI/SETXRdmrVab4D9LvXT3lrXkwAWGWk2GVvQvzlqN1/M/RfClj+o37Sn4FqRkGH9o9g7Fqb1YqZ4mqDAtA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", - "@smithy/core": "^3.5.1", + "@aws-sdk/util-endpoints": "3.828.0", + "@smithy/core": "^3.5.3", "@smithy/protocol-http": "^5.1.2", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" @@ -9233,45 +9380,45 @@ } }, "node_modules/@aws-sdk/client-xray/node_modules/@aws-sdk/nested-clients": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.821.0.tgz", - "integrity": "sha512-2IuHcUsWw44ftSEDYU4dvktTEqgyDvkOcfpoGC/UmT4Qo6TVCP3U5tWEGpNK9nN+7nLvekruxxG/jaMt5/oWVw==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.830.0.tgz", + "integrity": "sha512-5N5YTlBr1vtxf7+t+UaIQ625KEAmm7fY9o1e3MgGOi/paBoI0+axr3ud24qLIy0NSzFlAHEaxUSWxcERNjIoZw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.821.0", + "@aws-sdk/core": "3.826.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.821.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.9", - "@smithy/middleware-retry": "^4.1.10", + "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-retry": "^4.1.12", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.17", - "@smithy/util-defaults-mode-node": "^4.0.17", + "@smithy/util-defaults-mode-browser": "^4.0.19", + "@smithy/util-defaults-mode-node": "^4.0.19", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -9301,14 +9448,14 @@ } }, "node_modules/@aws-sdk/client-xray/node_modules/@aws-sdk/token-providers": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.821.0.tgz", - "integrity": "sha512-qJ7wgKhdxGbPg718zWXbCYKDuSWZNU3TSw64hPRW6FtbZrIyZxObpiTKC6DKwfsVoZZhHEoP/imGykN1OdOTJA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.830.0.tgz", + "integrity": "sha512-aJ4guFwj92nV9D+EgJPaCFKK0I3y2uMchiDfh69Zqnmwfxxxfxat6F79VA7PS0BdbjRfhLbn+Ghjftnomu2c1g==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/nested-clients": "3.821.0", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -9334,9 +9481,9 @@ } }, "node_modules/@aws-sdk/client-xray/node_modules/@aws-sdk/util-endpoints": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.821.0.tgz", - "integrity": "sha512-Uknt/zUZnLE76zaAAPEayOeF5/4IZ2puTFXvcSCWHsi9m3tqbb9UozlnlVqvCZLCRWfQryZQoG2W4XSS3qgk5A==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.828.0.tgz", + "integrity": "sha512-RvKch111SblqdkPzg3oCIdlGxlQs+k+P7Etory9FmxPHyPDvsP1j1c74PmgYqtzzMWmoXTjd+c9naUHh9xG8xg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -9363,13 +9510,13 @@ } }, "node_modules/@aws-sdk/client-xray/node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.821.0.tgz", - "integrity": "sha512-YwMXc9EvuzJgnLBTyiQly2juPujXwDgcMHB0iSN92tHe7Dd1jJ1feBmTgdClaaqCeHFUaFpw+3JU/ZUJ6LjR+A==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.828.0.tgz", + "integrity": "sha512-LdN6fTBzTlQmc8O8f1wiZN0qF3yBWVGis7NwpWK7FUEzP9bEZRxYfIkV9oV9zpt6iNRze1SedK3JQVB/udxBoA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/types": "3.821.0", "@smithy/node-config-provider": "^4.1.3", "@smithy/types": "^4.3.1", @@ -9387,6 +9534,20 @@ } } }, + "node_modules/@aws-sdk/client-xray/node_modules/@aws-sdk/xml-builder": { + "version": "3.821.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.821.0.tgz", + "integrity": "sha512-DIIotRnefVL6DiaHtO6/21DhJ4JZnnIwdNbpwiAhdt/AVbttcE4yw925gsjur0OGv5BTYXQXU3YnANBYnZjuQA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@aws-sdk/core": { "version": "3.808.0", "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.808.0.tgz", @@ -9754,15 +9915,15 @@ } }, "node_modules/@aws-sdk/lib-dynamodb": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/lib-dynamodb/-/lib-dynamodb-3.821.0.tgz", - "integrity": "sha512-o87vY8SqlQtaI7WookHiWeTnPMzWrpv6H/IXuihj04AnNSwhTej2w4uL0kPTmWaA9DIRzmD8n2M9cjFnz6Pj6Q==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/lib-dynamodb/-/lib-dynamodb-3.830.0.tgz", + "integrity": "sha512-j8VtdHXIuheRfnujCuX6mTmsrJqXawL/mdVMdUgliNQe803QZUsfEuc/dKPjXWOSp+WRHU/zZaHtTh3cC04AmQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.821.0", - "@aws-sdk/util-dynamodb": "3.821.0", - "@smithy/core": "^3.5.1", - "@smithy/smithy-client": "^4.4.1", + "@aws-sdk/core": "3.826.0", + "@aws-sdk/util-dynamodb": "3.830.0", + "@smithy/core": "^3.5.3", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, @@ -9770,24 +9931,28 @@ "node": ">=18.0.0" }, "peerDependencies": { - "@aws-sdk/client-dynamodb": "^3.821.0" + "@aws-sdk/client-dynamodb": "^3.830.0" } }, "node_modules/@aws-sdk/lib-dynamodb/node_modules/@aws-sdk/core": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.821.0.tgz", - "integrity": "sha512-8eB3wKbmfciQFmxFq7hAjy7mXdUs7vBOR5SwT0ZtQBg0Txc18Lc9tMViqqdO6/KU7OukA6ib2IAVSjIJJEN7FQ==", + "version": "3.826.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.826.0.tgz", + "integrity": "sha512-BGbQYzWj3ps+dblq33FY5tz/SsgJCcXX0zjQlSC07tYvU1jHTUvsefphyig+fY38xZ4wdKjbTop+KUmXUYrOXw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.821.0", - "@smithy/core": "^3.5.1", + "@aws-sdk/xml-builder": "3.821.0", + "@smithy/core": "^3.5.3", "@smithy/node-config-provider": "^4.1.3", "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", "@smithy/signature-v4": "^5.1.2", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.4", + "@smithy/util-utf8": "^4.0.0", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" }, @@ -9808,6 +9973,19 @@ "node": ">=18.0.0" } }, + "node_modules/@aws-sdk/lib-dynamodb/node_modules/@aws-sdk/xml-builder": { + "version": "3.821.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.821.0.tgz", + "integrity": "sha512-DIIotRnefVL6DiaHtO6/21DhJ4JZnnIwdNbpwiAhdt/AVbttcE4yw925gsjur0OGv5BTYXQXU3YnANBYnZjuQA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@aws-sdk/lib-storage": { "version": "3.808.0", "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.808.0.tgz", @@ -9829,16 +10007,6 @@ "@aws-sdk/client-s3": "^3.808.0" } }, - "node_modules/@aws-sdk/lib-storage/node_modules/buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "license": "MIT", - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, "node_modules/@aws-sdk/lib-storage/node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -10412,9 +10580,9 @@ } }, "node_modules/@aws-sdk/util-dynamodb": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-dynamodb/-/util-dynamodb-3.821.0.tgz", - "integrity": "sha512-ziVGOwqsqiZzTuSEKTxbGA6NH0MvSivmH0k6WRqoVhgl1uu65BZKI/z7musNDuNruwMzvL5ChlCq+npOo6E0kA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-dynamodb/-/util-dynamodb-3.830.0.tgz", + "integrity": "sha512-TnBWMhTN8K5twhJf97zlfWYtWZp7l0XRkvfCG6Fxa/EcTeBDVm91mzYfTvTadf0U0DrifPFVKp3xQYkfULddhg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -10423,7 +10591,7 @@ "node": ">=18.0.0" }, "peerDependencies": { - "@aws-sdk/client-dynamodb": "^3.821.0" + "@aws-sdk/client-dynamodb": "^3.830.0" } }, "node_modules/@aws-sdk/util-endpoints": { @@ -11284,6 +11452,27 @@ "node": ">=6.9.0" } }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -11519,10 +11708,11 @@ } }, "node_modules/@lerna/create/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -12214,41 +12404,36 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true + "devOptional": true, + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true + "devOptional": true, + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/codegen": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true + "devOptional": true, + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true + "devOptional": true, + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "devOptional": true, "license": "BSD-3-Clause", - "optional": true, - "peer": true, "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -12258,46 +12443,41 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true + "devOptional": true, + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true + "devOptional": true, + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true + "devOptional": true, + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true + "devOptional": true, + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true + "devOptional": true, + "license": "BSD-3-Clause" }, "node_modules/@redis/client": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-5.1.1.tgz", - "integrity": "sha512-vojbBqUdbkD+ylCy3+ZDXLzSmgiYH9pLrv87kF+nDgsRaHKrVVxPV9B4u6EfWRx7XGvQGZqsXVkKFhsEOsG3LA==", + "version": "5.5.6", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-5.5.6.tgz", + "integrity": "sha512-M3Svdwt6oSfyfQdqEr0L2HOJH2vK7GgCFx1NfAQvpWAT4+ljoT1L5S5cKT3dA9NJrxrOPDkdoTPWJnIrGCOcmw==", "devOptional": true, "license": "MIT", "dependencies": { @@ -12308,9 +12488,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.41.0.tgz", - "integrity": "sha512-KxN+zCjOYHGwCl4UCtSfZ6jrq/qi88JDUtiEFk8LELEHq2Egfc/FgW+jItZiOLRuQfb/3xJSgFuNPC9jzggX+A==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.42.0.tgz", + "integrity": "sha512-gldmAyS9hpj+H6LpRNlcjQWbuKUtb94lodB9uCz71Jm+7BxK1VIOo7y62tZZwxhA7j1ylv/yQz080L5WkS+LoQ==", "cpu": [ "arm" ], @@ -12322,9 +12502,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.41.0.tgz", - "integrity": "sha512-yDvqx3lWlcugozax3DItKJI5j05B0d4Kvnjx+5mwiUpWramVvmAByYigMplaoAQ3pvdprGCTCE03eduqE/8mPQ==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.42.0.tgz", + "integrity": "sha512-bpRipfTgmGFdCZDFLRvIkSNO1/3RGS74aWkJJTFJBH7h3MRV4UijkaEUeOMbi9wxtxYmtAbVcnMtHTPBhLEkaw==", "cpu": [ "arm64" ], @@ -12336,9 +12516,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.41.0.tgz", - "integrity": "sha512-2KOU574vD3gzcPSjxO0eyR5iWlnxxtmW1F5CkNOHmMlueKNCQkxR6+ekgWyVnz6zaZihpUNkGxjsYrkTJKhkaw==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.42.0.tgz", + "integrity": "sha512-JxHtA081izPBVCHLKnl6GEA0w3920mlJPLh89NojpU2GsBSB6ypu4erFg/Wx1qbpUbepn0jY4dVWMGZM8gplgA==", "cpu": [ "arm64" ], @@ -12350,9 +12530,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.41.0.tgz", - "integrity": "sha512-gE5ACNSxHcEZyP2BA9TuTakfZvULEW4YAOtxl/A/YDbIir/wPKukde0BNPlnBiP88ecaN4BJI2TtAd+HKuZPQQ==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.42.0.tgz", + "integrity": "sha512-rv5UZaWVIJTDMyQ3dCEK+m0SAn6G7H3PRc2AZmExvbDvtaDc+qXkei0knQWcI3+c9tEs7iL/4I4pTQoPbNL2SA==", "cpu": [ "x64" ], @@ -12364,9 +12544,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.41.0.tgz", - "integrity": "sha512-GSxU6r5HnWij7FoSo7cZg3l5GPg4HFLkzsFFh0N/b16q5buW1NAWuCJ+HMtIdUEi6XF0qH+hN0TEd78laRp7Dg==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.42.0.tgz", + "integrity": "sha512-fJcN4uSGPWdpVmvLuMtALUFwCHgb2XiQjuECkHT3lWLZhSQ3MBQ9pq+WoWeJq2PrNxr9rPM1Qx+IjyGj8/c6zQ==", "cpu": [ "arm64" ], @@ -12378,9 +12558,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.41.0.tgz", - "integrity": "sha512-KGiGKGDg8qLRyOWmk6IeiHJzsN/OYxO6nSbT0Vj4MwjS2XQy/5emsmtoqLAabqrohbgLWJ5GV3s/ljdrIr8Qjg==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.42.0.tgz", + "integrity": "sha512-CziHfyzpp8hJpCVE/ZdTizw58gr+m7Y2Xq5VOuCSrZR++th2xWAz4Nqk52MoIIrV3JHtVBhbBsJcAxs6NammOQ==", "cpu": [ "x64" ], @@ -12392,9 +12572,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.41.0.tgz", - "integrity": "sha512-46OzWeqEVQyX3N2/QdiU/CMXYDH/lSHpgfBkuhl3igpZiaB3ZIfSjKuOnybFVBQzjsLwkus2mjaESy8H41SzvA==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.42.0.tgz", + "integrity": "sha512-UsQD5fyLWm2Fe5CDM7VPYAo+UC7+2Px4Y+N3AcPh/LdZu23YcuGPegQly++XEVaC8XUTFVPscl5y5Cl1twEI4A==", "cpu": [ "arm" ], @@ -12406,9 +12586,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.41.0.tgz", - "integrity": "sha512-lfgW3KtQP4YauqdPpcUZHPcqQXmTmH4nYU0cplNeW583CMkAGjtImw4PKli09NFi2iQgChk4e9erkwlfYem6Lg==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.42.0.tgz", + "integrity": "sha512-/i8NIrlgc/+4n1lnoWl1zgH7Uo0XK5xK3EDqVTf38KvyYgCU/Rm04+o1VvvzJZnVS5/cWSd07owkzcVasgfIkQ==", "cpu": [ "arm" ], @@ -12420,9 +12600,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.41.0.tgz", - "integrity": "sha512-nn8mEyzMbdEJzT7cwxgObuwviMx6kPRxzYiOl6o/o+ChQq23gfdlZcUNnt89lPhhz3BYsZ72rp0rxNqBSfqlqw==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.42.0.tgz", + "integrity": "sha512-eoujJFOvoIBjZEi9hJnXAbWg+Vo1Ov8n/0IKZZcPZ7JhBzxh2A+2NFyeMZIRkY9iwBvSjloKgcvnjTbGKHE44Q==", "cpu": [ "arm64" ], @@ -12434,9 +12614,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.41.0.tgz", - "integrity": "sha512-l+QK99je2zUKGd31Gh+45c4pGDAqZSuWQiuRFCdHYC2CSiO47qUWsCcenrI6p22hvHZrDje9QjwSMAFL3iwXwQ==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.42.0.tgz", + "integrity": "sha512-/3NrcOWFSR7RQUQIuZQChLND36aTU9IYE4j+TB40VU78S+RA0IiqHR30oSh6P1S9f9/wVOenHQnacs/Byb824g==", "cpu": [ "arm64" ], @@ -12448,9 +12628,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.41.0.tgz", - "integrity": "sha512-WbnJaxPv1gPIm6S8O/Wg+wfE/OzGSXlBMbOe4ie+zMyykMOeqmgD1BhPxZQuDqwUN+0T/xOFtL2RUWBspnZj3w==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.42.0.tgz", + "integrity": "sha512-O8AplvIeavK5ABmZlKBq9/STdZlnQo7Sle0LLhVA7QT+CiGpNVe197/t8Aph9bhJqbDVGCHpY2i7QyfEDDStDg==", "cpu": [ "loong64" ], @@ -12462,9 +12642,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.41.0.tgz", - "integrity": "sha512-eRDWR5t67/b2g8Q/S8XPi0YdbKcCs4WQ8vklNnUYLaSWF+Cbv2axZsp4jni6/j7eKvMLYCYdcsv8dcU+a6QNFg==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.42.0.tgz", + "integrity": "sha512-6Qb66tbKVN7VyQrekhEzbHRxXXFFD8QKiFAwX5v9Xt6FiJ3BnCVBuyBxa2fkFGqxOCSGGYNejxd8ht+q5SnmtA==", "cpu": [ "ppc64" ], @@ -12476,9 +12656,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.41.0.tgz", - "integrity": "sha512-TWrZb6GF5jsEKG7T1IHwlLMDRy2f3DPqYldmIhnA2DVqvvhY2Ai184vZGgahRrg8k9UBWoSlHv+suRfTN7Ua4A==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.42.0.tgz", + "integrity": "sha512-KQETDSEBamQFvg/d8jajtRwLNBlGc3aKpaGiP/LvEbnmVUKlFta1vqJqTrvPtsYsfbE/DLg5CC9zyXRX3fnBiA==", "cpu": [ "riscv64" ], @@ -12490,9 +12670,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.41.0.tgz", - "integrity": "sha512-ieQljaZKuJpmWvd8gW87ZmSFwid6AxMDk5bhONJ57U8zT77zpZ/TPKkU9HpnnFrM4zsgr4kiGuzbIbZTGi7u9A==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.42.0.tgz", + "integrity": "sha512-qMvnyjcU37sCo/tuC+JqeDKSuukGAd+pVlRl/oyDbkvPJ3awk6G6ua7tyum02O3lI+fio+eM5wsVd66X0jQtxw==", "cpu": [ "riscv64" ], @@ -12504,9 +12684,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.41.0.tgz", - "integrity": "sha512-/L3pW48SxrWAlVsKCN0dGLB2bi8Nv8pr5S5ocSM+S0XCn5RCVCXqi8GVtHFsOBBCSeR+u9brV2zno5+mg3S4Aw==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.42.0.tgz", + "integrity": "sha512-I2Y1ZUgTgU2RLddUHXTIgyrdOwljjkmcZ/VilvaEumtS3Fkuhbw4p4hgHc39Ypwvo2o7sBFNl2MquNvGCa55Iw==", "cpu": [ "s390x" ], @@ -12518,9 +12698,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.41.0.tgz", - "integrity": "sha512-XMLeKjyH8NsEDCRptf6LO8lJk23o9wvB+dJwcXMaH6ZQbbkHu2dbGIUindbMtRN6ux1xKi16iXWu6q9mu7gDhQ==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.42.0.tgz", + "integrity": "sha512-Gfm6cV6mj3hCUY8TqWa63DB8Mx3NADoFwiJrMpoZ1uESbK8FQV3LXkhfry+8bOniq9pqY1OdsjFWNsSbfjPugw==", "cpu": [ "x64" ], @@ -12532,9 +12712,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.41.0.tgz", - "integrity": "sha512-m/P7LycHZTvSQeXhFmgmdqEiTqSV80zn6xHaQ1JSqwCtD1YGtwEK515Qmy9DcB2HK4dOUVypQxvhVSy06cJPEg==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.42.0.tgz", + "integrity": "sha512-g86PF8YZ9GRqkdi0VoGlcDUb4rYtQKyTD1IVtxxN4Hpe7YqLBShA7oHMKU6oKTCi3uxwW4VkIGnOaH/El8de3w==", "cpu": [ "x64" ], @@ -12546,9 +12726,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.41.0.tgz", - "integrity": "sha512-4yodtcOrFHpbomJGVEqZ8fzD4kfBeCbpsUy5Pqk4RluXOdsWdjLnjhiKy2w3qzcASWd04fp52Xz7JKarVJ5BTg==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.42.0.tgz", + "integrity": "sha512-+axkdyDGSp6hjyzQ5m1pgcvQScfHnMCcsXkx8pTgy/6qBmWVhtRVlgxjWwDp67wEXXUr0x+vD6tp5W4x6V7u1A==", "cpu": [ "arm64" ], @@ -12560,9 +12740,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.41.0.tgz", - "integrity": "sha512-tmazCrAsKzdkXssEc65zIE1oC6xPHwfy9d5Ta25SRCDOZS+I6RypVVShWALNuU9bxIfGA0aqrmzlzoM5wO5SPQ==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.42.0.tgz", + "integrity": "sha512-F+5J9pelstXKwRSDq92J0TEBXn2nfUrQGg+HK1+Tk7VOL09e0gBqUHugZv7SW4MGrYj41oNCUe3IKCDGVlis2g==", "cpu": [ "ia32" ], @@ -12574,9 +12754,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.41.0.tgz", - "integrity": "sha512-h1J+Yzjo/X+0EAvR2kIXJDuTuyT7drc+t2ALY0nIcGPbTatNOf0VWdhEA2Z4AAjv6X1NJV7SYo5oCTYRJhSlVA==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.42.0.tgz", + "integrity": "sha512-LpHiJRwkaVz/LqjHjK8LCi8osq7elmpwujwbXKNW88bM8eeGxavJIKKjkjpMHAh/2xfnrt1ZSnhTv41WYUHYmA==", "cpu": [ "x64" ], @@ -12715,28 +12895,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@sigstore/sign/node_modules/glob": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", - "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@sigstore/sign/node_modules/http-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", @@ -12808,22 +12966,6 @@ "node": ">=8" } }, - "node_modules/@sigstore/sign/node_modules/minimatch": { - "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": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@sigstore/sign/node_modules/minipass-collect": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", @@ -13042,9 +13184,9 @@ } }, "node_modules/@smithy/core": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.5.1.tgz", - "integrity": "sha512-xSw7bZEFKwOKrm/iv8e2BLt2ur98YZdrRD6nII8ditQeUsY2Q1JmIQ0rpILOhaLKYxxG2ivnoOpokzr9qLyDWA==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.5.3.tgz", + "integrity": "sha512-xa5byV9fEguZNofCclv6v9ra0FYh5FATQW/da7FQUVTic94DfrN/NvmKZjrMyzbpqfot9ZjBaO8U1UeTbmSLuA==", "license": "Apache-2.0", "dependencies": { "@smithy/middleware-serde": "^4.0.8", @@ -13246,13 +13388,13 @@ } }, "node_modules/@smithy/middleware-compression": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@smithy/middleware-compression/-/middleware-compression-4.1.9.tgz", - "integrity": "sha512-rNLobMoMYliBzHIrLubgzhFuvvCdqOGkPybiA8U9+LMsM1x13D3j2v8NPj13aIGgjSpr01BSxPj7C0FxZRtpiQ==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@smithy/middleware-compression/-/middleware-compression-4.1.11.tgz", + "integrity": "sha512-NDmQHZu4s+MEPC7GMa+68GDJjhlWq0K6jpjf93TPdaOlg+eT/IFLA5CXbjsSWFQj80sBgjU18U3ny1iP+sbG7A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/is-array-buffer": "^4.0.0", "@smithy/node-config-provider": "^4.1.3", "@smithy/protocol-http": "^5.1.2", @@ -13282,12 +13424,12 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.9.tgz", - "integrity": "sha512-AjDgX4UjORLltD/LZCBQTwjQqEfyrx/GeDTHcYLzIgf87pIT70tMWnN87NQpJru1K4ITirY2htSOxNECZJCBOg==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.11.tgz", + "integrity": "sha512-zDogwtRLzKl58lVS8wPcARevFZNBOOqnmzWWxVe9XiaXU2CADFjvJ9XfNibgkOWs08sxLuSr81NrpY4mgp9OwQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.5.1", + "@smithy/core": "^3.5.3", "@smithy/middleware-serde": "^4.0.8", "@smithy/node-config-provider": "^4.1.3", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -13301,15 +13443,15 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.1.10.tgz", - "integrity": "sha512-RyhcA3sZIIvAo6r48b2Nx2qfg0OnyohlaV0fw415xrQyx5HQ2bvHl9vs/WBiDXIP49mCfws5wX4308c9Pi/isw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.1.12.tgz", + "integrity": "sha512-wvIH70c4e91NtRxdaLZF+mbLZ/HcC6yg7ySKUiufL6ESp6zJUSnJucZ309AvG9nqCFHSRB5I6T3Ez1Q9wCh0Ww==", "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^4.1.3", "@smithy/protocol-http": "^5.1.2", "@smithy/service-error-classification": "^4.0.5", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.5", @@ -13476,13 +13618,13 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.4.1.tgz", - "integrity": "sha512-XPbcHRfd0iwx8dY5XCBCGyI7uweMW0oezYezxXcG8ANgvZ5YPuC6Ylh+n0bTHpdU3SCMZOnhzgVklYz+p3fIhw==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.4.3.tgz", + "integrity": "sha512-xxzNYgA0HD6ETCe5QJubsxP0hQH3QK3kbpJz3QrosBCuIWyEXLR/CO5hFb2OeawEKUxMNhz3a1nuJNN2np2RMA==", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.5.1", - "@smithy/middleware-endpoint": "^4.1.9", + "@smithy/core": "^3.5.3", + "@smithy/middleware-endpoint": "^4.1.11", "@smithy/middleware-stack": "^4.0.4", "@smithy/protocol-http": "^5.1.2", "@smithy/types": "^4.3.1", @@ -13578,13 +13720,13 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.17.tgz", - "integrity": "sha512-HXq5181qnXmIwB7VrwqwP8rsJybHMoYuJnNoXy4PROs2pfSI4sWDMASF2i+7Lo+u64Y6xowhegcdxczowgJtZg==", + "version": "4.0.19", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.19.tgz", + "integrity": "sha512-mvLMh87xSmQrV5XqnUYEPoiFFeEGYeAKIDDKdhE2ahqitm8OHM3aSvhqL6rrK6wm1brIk90JhxDf5lf2hbrLbQ==", "license": "Apache-2.0", "dependencies": { "@smithy/property-provider": "^4.0.4", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "bowser": "^2.11.0", "tslib": "^2.6.2" @@ -13594,16 +13736,16 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.17.tgz", - "integrity": "sha512-RfU2A5LjFhEHw4Nwl1GZNitK4AUWu5jGtigAUDoQtfDUvYHpQxcuLw2QGAdKDtKRflIiHSZ8wXBDR36H9R2Ang==", + "version": "4.0.19", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.19.tgz", + "integrity": "sha512-8tYnx+LUfj6m+zkUUIrIQJxPM1xVxfRBvoGHua7R/i6qAxOMjqR6CpEpDwKoIs1o0+hOjGvkKE23CafKL0vJ9w==", "license": "Apache-2.0", "dependencies": { "@smithy/config-resolver": "^4.1.4", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/node-config-provider": "^4.1.3", "@smithy/property-provider": "^4.0.4", - "@smithy/smithy-client": "^4.4.1", + "@smithy/smithy-client": "^4.4.3", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, @@ -13719,6 +13861,12 @@ "node": ">=18.0.0" } }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "license": "MIT" + }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -13751,12 +13899,22 @@ } }, "node_modules/@types/aws-lambda": { - "version": "8.10.149", - "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.149.tgz", - "integrity": "sha512-NXSZIhfJjnXqJgtS7IwutqIF/SOy1Wz5Px4gUY1RWITp3AYTyuJS4xaXr/bIJY1v15XMzrJ5soGnPM+7uigZjA==", + "version": "8.10.150", + "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.150.tgz", + "integrity": "sha512-AX+AbjH/rH5ezX1fbK8onC/a+HyQHo7QGmvoxAE42n22OsciAxvZoZNEr22tbXs8WfP1nIsBjKDpgPm3HjOZbA==", "dev": true, "license": "MIT" }, + "node_modules/@types/chai": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz", + "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*" + } + }, "node_modules/@types/cls-hooked": { "version": "4.3.8", "resolved": "https://registry.npmjs.org/@types/cls-hooked/-/cls-hooked-4.3.8.tgz", @@ -13775,6 +13933,13 @@ "@types/ms": "*" } }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", @@ -13834,12 +13999,12 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.15.29", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.29.tgz", - "integrity": "sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ==", + "version": "24.0.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.3.tgz", + "integrity": "sha512-R4I/kzCYAdRLzfiCabn9hxWfbuHS573x+r0dJMkkzThEa7pbrcDWK+9zu3e7aBOouf+rQAciqPFMnxwr0aWgKg==", "license": "MIT", "dependencies": { - "undici-types": "~6.21.0" + "undici-types": "~7.8.0" } }, "node_modules/@types/normalize-package-data": { @@ -14069,15 +14234,16 @@ } }, "node_modules/@vitest/coverage-v8": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.1.4.tgz", - "integrity": "sha512-G4p6OtioySL+hPV7Y6JHlhpsODbJzt1ndwHAFkyk6vVjpK03PFsKnauZIzcd0PrK4zAbc5lc+jeZ+eNGiMA+iw==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.3.tgz", + "integrity": "sha512-D1QKzngg8PcDoCE8FHSZhREDuEy+zcKmMiMafYse41RZpBE5EDJyKOTdqK3RQfsV2S2nyKor5KCs8PyPRFqKPg==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.3.0", "@bcoe/v8-coverage": "^1.0.2", - "debug": "^4.4.0", + "ast-v8-to-istanbul": "^0.3.3", + "debug": "^4.4.1", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-lib-source-maps": "^5.0.6", @@ -14092,8 +14258,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "3.1.4", - "vitest": "3.1.4" + "@vitest/browser": "3.2.3", + "vitest": "3.2.3" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -14145,14 +14311,15 @@ } }, "node_modules/@vitest/expect": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.4.tgz", - "integrity": "sha512-xkD/ljeliyaClDYqHPNCiJ0plY5YIcM0OlRiZizLhlPmpXWpxnGMyTZXOHFhFeG7w9P5PBeL4IdtJ/HeQwTbQA==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.3.tgz", + "integrity": "sha512-W2RH2TPWVHA1o7UmaFKISPvdicFJH+mjykctJFoAkUw+SPTJTGjUNdKscFBrqM7IPnCVu6zihtKYa7TkZS1dkQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.1.4", - "@vitest/utils": "3.1.4", + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.3", + "@vitest/utils": "3.2.3", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" }, @@ -14161,13 +14328,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.4.tgz", - "integrity": "sha512-8IJ3CvwtSw/EFXqWFL8aCMu+YyYXG2WUSrQbViOZkWTKTVicVwZ/YiEZDSqD00kX+v/+W+OnxhNWoeVKorHygA==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.3.tgz", + "integrity": "sha512-cP6fIun+Zx8he4rbWvi+Oya6goKQDZK+Yq4hhlggwQBbrlOQ4qtZ+G4nxB6ZnzI9lyIb+JnvyiJnPC2AGbKSPA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.1.4", + "@vitest/spy": "3.2.3", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, @@ -14176,7 +14343,7 @@ }, "peerDependencies": { "msw": "^2.4.9", - "vite": "^5.0.0 || ^6.0.0" + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "peerDependenciesMeta": { "msw": { @@ -14188,9 +14355,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.4.tgz", - "integrity": "sha512-cqv9H9GvAEoTaoq+cYqUTCGscUjKqlJZC7PRwY5FMySVj5J+xOm1KQcCiYHJOEzOKRUhLH4R2pTwvFlWCEScsg==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.3.tgz", + "integrity": "sha512-yFglXGkr9hW/yEXngO+IKMhP0jxyFw2/qys/CK4fFUZnSltD+MU7dVYGrH8rvPcK/O6feXQA+EU33gjaBBbAng==", "dev": true, "license": "MIT", "dependencies": { @@ -14201,27 +14368,28 @@ } }, "node_modules/@vitest/runner": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.4.tgz", - "integrity": "sha512-djTeF1/vt985I/wpKVFBMWUlk/I7mb5hmD5oP8K9ACRmVXgKTae3TUOtXAEBfslNKPzUQvnKhNd34nnRSYgLNQ==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.3.tgz", + "integrity": "sha512-83HWYisT3IpMaU9LN+VN+/nLHVBCSIUKJzGxC5RWUOsK1h3USg7ojL+UXQR3b4o4UBIWCYdD2fxuzM7PQQ1u8w==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "3.1.4", - "pathe": "^2.0.3" + "@vitest/utils": "3.2.3", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/snapshot": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.4.tgz", - "integrity": "sha512-JPHf68DvuO7vilmvwdPr9TS0SuuIzHvxeaCkxYcCD4jTk67XwL45ZhEHFKIuCm8CYstgI6LZ4XbwD6ANrwMpFg==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.3.tgz", + "integrity": "sha512-9gIVWx2+tysDqUmmM1L0hwadyumqssOL1r8KJipwLx5JVYyxvVRfxvMq7DaWbZZsCqZnu/dZedaZQh4iYTtneA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.1.4", + "@vitest/pretty-format": "3.2.3", "magic-string": "^0.30.17", "pathe": "^2.0.3" }, @@ -14230,26 +14398,26 @@ } }, "node_modules/@vitest/spy": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.4.tgz", - "integrity": "sha512-Xg1bXhu+vtPXIodYN369M86K8shGLouNjoVI78g8iAq2rFoHFdajNvJJ5A/9bPMFcfQqdaCpOgWKEoMQg/s0Yg==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.3.tgz", + "integrity": "sha512-JHu9Wl+7bf6FEejTCREy+DmgWe+rQKbK+y32C/k5f4TBIAlijhJbRBIRIOCEpVevgRsCQR2iHRUH2/qKVM/plw==", "dev": true, "license": "MIT", "dependencies": { - "tinyspy": "^3.0.2" + "tinyspy": "^4.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.4.tgz", - "integrity": "sha512-yriMuO1cfFhmiGc8ataN51+9ooHRuURdfAZfwFd3usWynjzpLslZdYnRegTv32qdgtJTsj15FoeZe2g15fY1gg==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.3.tgz", + "integrity": "sha512-4zFBCU5Pf+4Z6v+rwnZ1HU1yzOKKvDkMXZrymE2PBlbjKJRlrOxbvpfPSvJTGRIwGoahaOGvp+kbCoxifhzJ1Q==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.1.4", + "@vitest/pretty-format": "3.2.3", "loupe": "^3.1.3", "tinyrainbow": "^2.0.0" }, @@ -14635,6 +14803,16 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/arktype": { + "version": "2.1.20", + "resolved": "https://registry.npmjs.org/arktype/-/arktype-2.1.20.tgz", + "integrity": "sha512-IZCEEXaJ8g+Ijd59WtSYwtjnqXiwM8sWQ5EjGamcto7+HVN9eK0C4p0zDlCuAwWhpqr6fIBkxPuYDl4/Mcj/+Q==", + "license": "MIT", + "dependencies": { + "@ark/schema": "0.46.0", + "@ark/util": "0.46.0" + } + }, "node_modules/array-differ": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", @@ -14678,6 +14856,25 @@ "node": ">=12" } }, + "node_modules/ast-v8-to-istanbul": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.3.tgz", + "integrity": "sha512-MuXMrSLVVoA6sYN/6Hke18vMzrT4TZNbZIj/hvh0fnYFpO+/kFXcLIaiPwXXWaQUPg4yJD8fj+lfJ7/1EBconw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "estree-walker": "^3.0.3", + "js-tokens": "^9.0.1" + } + }, + "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -14738,25 +14935,35 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/avro-js": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/avro-js/-/avro-js-1.12.0.tgz", + "integrity": "sha512-mBhOjtHHua2MHrrgQ71YKKTGfZpS1sPvgL+QcCQ5SkUyp6qLkeTsCnQXUmATfpiOvoXB6CczzFEqn5UKbPUn3Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "underscore": "^1.13.2" + } + }, "node_modules/aws-cdk": { - "version": "2.1017.1", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1017.1.tgz", - "integrity": "sha512-KtDdkMhfVjDeexjpMrVoSlz2mTYI5BE/KotvJ7iFbZy1G0nkpW1ImZ54TdBefeeFmZ+8DAjU3I6nUFtymyOI1A==", + "version": "2.1018.1", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1018.1.tgz", + "integrity": "sha512-kFPRox5kSm+ktJ451o0ng9rD+60p5Kt1CZIWw8kXnvqbsxN2xv6qbmyWSXw7sGVXVwqrRKVj+71/JeDr+LMAZw==", "license": "Apache-2.0", "bin": { "cdk": "bin/cdk" }, "engines": { - "node": ">= 14.15.0" + "node": ">= 18.0.0" }, "optionalDependencies": { "fsevents": "2.3.2" } }, "node_modules/aws-cdk-lib": { - "version": "2.200.0", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.200.0.tgz", - "integrity": "sha512-t4wGmFYuzlos7fFLFmv6ljtpMu+qYmPQnodfgUQ/BE0+y8S2MONQf9ihN+mZvsRqj96t6BwuVy3lR3UymtwGbw==", + "version": "2.201.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.201.0.tgz", + "integrity": "sha512-0ioqzM5dkJl02uchOfgeCY3thV3jTn9YkyZ/UF5P4Hq9iNGHQqmPu5xE/VcAV7+P72Z/zV+QLV0xkVT6iLF/bw==", "bundleDependencies": [ "@balena/dockerignore", "case", @@ -14774,7 +14981,7 @@ "dependencies": { "@aws-cdk/asset-awscli-v1": "2.2.237", "@aws-cdk/asset-node-proxy-agent-v6": "^2.1.0", - "@aws-cdk/cloud-assembly-schema": "^44.1.0", + "@aws-cdk/cloud-assembly-schema": "^44.2.0", "@balena/dockerignore": "^1.0.2", "case": "1.6.3", "fs-extra": "^11.3.0", @@ -14850,7 +15057,7 @@ "license": "MIT" }, "node_modules/aws-cdk-lib/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.12", "inBundle": true, "license": "MIT", "dependencies": { @@ -15300,9 +15507,10 @@ "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" }, "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==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -15319,27 +15527,13 @@ } }, "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", + "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "license": "MIT", "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" } }, "node_modules/buffer-crc32": { @@ -15505,14 +15699,14 @@ } }, "node_modules/cdk-assets/node_modules/glob": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.2.tgz", - "integrity": "sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", + "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", "license": "ISC", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^4.0.1", - "minimatch": "^10.0.0", + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.0.3", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" @@ -15528,9 +15722,9 @@ } }, "node_modules/cdk-assets/node_modules/jackspeak": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.0.tgz", - "integrity": "sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -15552,12 +15746,12 @@ } }, "node_modules/cdk-assets/node_modules/minimatch": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", - "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", + "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "@isaacs/brace-expansion": "^5.0.0" }, "engines": { "node": "20 || >=22" @@ -15583,9 +15777,9 @@ } }, "node_modules/cdk-from-cfn": { - "version": "0.217.0", - "resolved": "https://registry.npmjs.org/cdk-from-cfn/-/cdk-from-cfn-0.217.0.tgz", - "integrity": "sha512-L/XvHnXVbJenF6F9gAETk5iXqCU+mbmbO5lnLGtu6N+mEnDj0EDIrplQVE3nrgEFhL7MiEgMje1hMxNnWZ9Lyg==", + "version": "0.220.0", + "resolved": "https://registry.npmjs.org/cdk-from-cfn/-/cdk-from-cfn-0.220.0.tgz", + "integrity": "sha512-khVnUNqEfRrkkCkEKzSmibqgVHrt7jl/5by8JOyR8reaXbXOIWubLuKdu+QZpRvuRXIci1BpbvxczQKEsl+ldw==", "license": "MIT OR Apache-2.0" }, "node_modules/chai": { @@ -17208,11 +17402,12 @@ } }, "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.0", + "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" }, "engines": { @@ -18472,10 +18667,11 @@ } }, "node_modules/jake/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -18805,10 +19001,11 @@ } }, "node_modules/lerna/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -19015,9 +19212,9 @@ } }, "node_modules/lint-staged": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.1.0.tgz", - "integrity": "sha512-HkpQh69XHxgCjObjejBT3s2ILwNjFx8M3nw+tJ/ssBauDlIpkx2RpqWSi1fBgkXLSSXnbR3iEq1NkVtpvV+FLQ==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.1.2.tgz", + "integrity": "sha512-sQKw2Si2g9KUZNY3XNvRuDq4UJqpHwF0/FQzZR2M7I5MvtpWvibikCjUVJzZdGE0ByurEl3KQNvsGetd1ty1/Q==", "dev": true, "license": "MIT", "dependencies": { @@ -19458,9 +19655,8 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", - "license": "Apache-2.0", - "optional": true, - "peer": true + "devOptional": true, + "license": "Apache-2.0" }, "node_modules/loupe": { "version": "3.1.3", @@ -19672,9 +19868,9 @@ } }, "node_modules/markdownlint-cli2/node_modules/ignore": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.4.tgz", - "integrity": "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, "license": "MIT", "engines": { @@ -20769,10 +20965,11 @@ } }, "node_modules/multimatch/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -22268,9 +22465,9 @@ } }, "node_modules/postcss": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", - "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.4.tgz", + "integrity": "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==", "dev": true, "funding": [ { @@ -22288,7 +22485,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.8", + "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -22400,13 +22597,12 @@ } }, "node_modules/protobufjs": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.2.tgz", - "integrity": "sha512-f2ls6rpO6G153Cy+o2XQ+Y0sARLOZ17+OGVLHrc3VUKcLHYKEKWbkSujdBWQXM7gKn5NTfp0XnRPZn1MIu8n9w==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.3.tgz", + "integrity": "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==", + "devOptional": true, "hasInstallScript": true, "license": "BSD-3-Clause", - "optional": true, - "peer": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -23043,9 +23239,9 @@ } }, "node_modules/rollup": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.41.0.tgz", - "integrity": "sha512-HqMFpUbWlf/tvcxBFNKnJyzc7Lk+XO3FGc3pbNBLqEbOz0gPLRgcrlS3UF4MfUrVlstOaP/q0kM6GVvi+LrLRg==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.42.0.tgz", + "integrity": "sha512-LW+Vse3BJPyGJGAJt1j8pWDKPd73QM8cRXYK1IxOBgL2AGLu7Xd2YOW0M2sLUBCkF5MshXXtMApyEAEzMVMsnw==", "dev": true, "license": "MIT", "dependencies": { @@ -23059,26 +23255,26 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.41.0", - "@rollup/rollup-android-arm64": "4.41.0", - "@rollup/rollup-darwin-arm64": "4.41.0", - "@rollup/rollup-darwin-x64": "4.41.0", - "@rollup/rollup-freebsd-arm64": "4.41.0", - "@rollup/rollup-freebsd-x64": "4.41.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.41.0", - "@rollup/rollup-linux-arm-musleabihf": "4.41.0", - "@rollup/rollup-linux-arm64-gnu": "4.41.0", - "@rollup/rollup-linux-arm64-musl": "4.41.0", - "@rollup/rollup-linux-loongarch64-gnu": "4.41.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.41.0", - "@rollup/rollup-linux-riscv64-gnu": "4.41.0", - "@rollup/rollup-linux-riscv64-musl": "4.41.0", - "@rollup/rollup-linux-s390x-gnu": "4.41.0", - "@rollup/rollup-linux-x64-gnu": "4.41.0", - "@rollup/rollup-linux-x64-musl": "4.41.0", - "@rollup/rollup-win32-arm64-msvc": "4.41.0", - "@rollup/rollup-win32-ia32-msvc": "4.41.0", - "@rollup/rollup-win32-x64-msvc": "4.41.0", + "@rollup/rollup-android-arm-eabi": "4.42.0", + "@rollup/rollup-android-arm64": "4.42.0", + "@rollup/rollup-darwin-arm64": "4.42.0", + "@rollup/rollup-darwin-x64": "4.42.0", + "@rollup/rollup-freebsd-arm64": "4.42.0", + "@rollup/rollup-freebsd-x64": "4.42.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.42.0", + "@rollup/rollup-linux-arm-musleabihf": "4.42.0", + "@rollup/rollup-linux-arm64-gnu": "4.42.0", + "@rollup/rollup-linux-arm64-musl": "4.42.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.42.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.42.0", + "@rollup/rollup-linux-riscv64-gnu": "4.42.0", + "@rollup/rollup-linux-riscv64-musl": "4.42.0", + "@rollup/rollup-linux-s390x-gnu": "4.42.0", + "@rollup/rollup-linux-x64-gnu": "4.42.0", + "@rollup/rollup-linux-x64-musl": "4.42.0", + "@rollup/rollup-win32-arm64-msvc": "4.42.0", + "@rollup/rollup-win32-ia32-msvc": "4.42.0", + "@rollup/rollup-win32-x64-msvc": "4.42.0", "fsevents": "~2.3.2" } }, @@ -23794,6 +23990,26 @@ "node": ">=8" } }, + "node_modules/strip-literal": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz", + "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/strip-literal/node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, "node_modules/strnum": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", @@ -24034,9 +24250,9 @@ "license": "MIT" }, "node_modules/tinyglobby": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", - "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", "dev": true, "license": "MIT", "dependencies": { @@ -24051,9 +24267,9 @@ } }, "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.4.4", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", - "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", "dev": true, "license": "MIT", "peerDependencies": { @@ -24079,9 +24295,9 @@ } }, "node_modules/tinypool": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", - "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.0.tgz", + "integrity": "sha512-7CotroY9a8DKsKprEy/a14aCCm8jYVmR7aFy4fpkZM8sdpNJbKkixuNjgM50yCmip2ezc8z4N7k3oe2+rfRJCQ==", "dev": true, "license": "MIT", "engines": { @@ -24099,9 +24315,9 @@ } }, "node_modules/tinyspy": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", - "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.3.tgz", + "integrity": "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==", "dev": true, "license": "MIT", "engines": { @@ -24149,9 +24365,9 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, "node_modules/tsx": { - "version": "4.19.4", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.4.tgz", - "integrity": "sha512-gK5GVzDkJK1SI1zwHf32Mqxf2tSJkNx+eYcNly5+nHvWqXUJYUkWBQtKauoESz3ymezAI++ZwT855x5p5eop+Q==", + "version": "4.20.3", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.3.tgz", + "integrity": "sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==", "license": "MIT", "dependencies": { "esbuild": "~0.25.0", @@ -24431,7 +24647,7 @@ "version": "5.8.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -24460,10 +24676,17 @@ "node": ">=0.8.0" } }, + "node_modules/underscore": { + "version": "1.13.7", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", + "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==", + "dev": true, + "license": "MIT" + }, "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", + "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", "license": "MIT" }, "node_modules/unicorn-magic": { @@ -24567,6 +24790,20 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/valibot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/valibot/-/valibot-1.1.0.tgz", + "integrity": "sha512-Nk8lX30Qhu+9txPYTwM0cFlWLdPFsFr6LblzqIySfbZph9+BFsAHsNvHOymEviUepeIW6KFHzpX8TKhbptBXXw==", + "license": "MIT", + "peerDependencies": { + "typescript": ">=5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -24665,17 +24902,17 @@ } }, "node_modules/vite-node": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.1.4.tgz", - "integrity": "sha512-6enNwYnpyDo4hEgytbmc6mYWHXDHYEn0D1/rw4Q+tnHUGtKTJsn8T1YkX6Q18wI5LCrS8CTYlBaiCqxOy2kvUA==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.3.tgz", + "integrity": "sha512-gc8aAifGuDIpZHrPjuHyP4dpQmYXqWw7D1GmDnWeNWP654UEXzVfQ5IHPSK5HaHkwB/+p1atpYpSdw/2kOv8iQ==", "dev": true, "license": "MIT", "dependencies": { "cac": "^6.7.14", - "debug": "^4.4.0", + "debug": "^4.4.1", "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", - "vite": "^5.0.0 || ^6.0.0" + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" @@ -24688,9 +24925,9 @@ } }, "node_modules/vite/node_modules/fdir": { - "version": "6.4.4", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", - "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", "dev": true, "license": "MIT", "peerDependencies": { @@ -24731,32 +24968,34 @@ } }, "node_modules/vitest": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.1.4.tgz", - "integrity": "sha512-Ta56rT7uWxCSJXlBtKgIlApJnT6e6IGmTYxYcmxjJ4ujuZDI59GUQgVDObXXJujOmPDBYXHK1qmaGtneu6TNIQ==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.3.tgz", + "integrity": "sha512-E6U2ZFXe3N/t4f5BwUaVCKRLHqUpk1CBWeMh78UT4VaTPH/2dyvH6ALl29JTovEPu9dVKr/K/J4PkXgrMbw4Ww==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "3.1.4", - "@vitest/mocker": "3.1.4", - "@vitest/pretty-format": "^3.1.4", - "@vitest/runner": "3.1.4", - "@vitest/snapshot": "3.1.4", - "@vitest/spy": "3.1.4", - "@vitest/utils": "3.1.4", + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.3", + "@vitest/mocker": "3.2.3", + "@vitest/pretty-format": "^3.2.3", + "@vitest/runner": "3.2.3", + "@vitest/snapshot": "3.2.3", + "@vitest/spy": "3.2.3", + "@vitest/utils": "3.2.3", "chai": "^5.2.0", - "debug": "^4.4.0", + "debug": "^4.4.1", "expect-type": "^1.2.1", "magic-string": "^0.30.17", "pathe": "^2.0.3", + "picomatch": "^4.0.2", "std-env": "^3.9.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", - "tinyglobby": "^0.2.13", - "tinypool": "^1.0.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.0", "tinyrainbow": "^2.0.0", - "vite": "^5.0.0 || ^6.0.0", - "vite-node": "3.1.4", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.3", "why-is-node-running": "^2.3.0" }, "bin": { @@ -24772,8 +25011,8 @@ "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.1.4", - "@vitest/ui": "3.1.4", + "@vitest/browser": "3.2.3", + "@vitest/ui": "3.2.3", "happy-dom": "*", "jsdom": "*" }, @@ -24801,6 +25040,19 @@ } } }, + "node_modules/vitest/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", @@ -25196,9 +25448,9 @@ } }, "node_modules/zod": { - "version": "3.25.48", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.48.tgz", - "integrity": "sha512-0X1mz8FtgEIvaxGjdIImYpZEaZMrund9pGXm3M6vM7Reba0e2eI71KPjSCGXBfwKDPwPoywf6waUKc3/tFvX2Q==", + "version": "3.25.67", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.67.tgz", + "integrity": "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==", "devOptional": true, "license": "MIT", "funding": { @@ -25207,7 +25459,7 @@ }, "packages/batch": { "name": "@aws-lambda-powertools/batch", - "version": "2.21.0", + "version": "2.22.0", "license": "MIT-0", "devDependencies": { "@aws-lambda-powertools/testing-utils": "file:../testing" @@ -25215,7 +25467,7 @@ }, "packages/commons": { "name": "@aws-lambda-powertools/commons", - "version": "2.21.0", + "version": "2.22.0", "license": "MIT-0", "devDependencies": { "@aws-lambda-powertools/testing-utils": "file:../testing" @@ -25223,24 +25475,24 @@ }, "packages/event-handler": { "name": "@aws-lambda-powertools/event-handler", - "version": "2.21.0", + "version": "2.22.0", "license": "MIT-0", "dependencies": { - "@aws-lambda-powertools/commons": "2.21.0" + "@aws-lambda-powertools/commons": "2.22.0" } }, "packages/idempotency": { "name": "@aws-lambda-powertools/idempotency", - "version": "2.21.0", + "version": "2.22.0", "license": "MIT-0", "dependencies": { - "@aws-lambda-powertools/commons": "2.21.0", - "@aws-lambda-powertools/jmespath": "2.21.0" + "@aws-lambda-powertools/commons": "2.22.0", + "@aws-lambda-powertools/jmespath": "2.22.0" }, "devDependencies": { "@aws-lambda-powertools/testing-utils": "file:../testing", - "@aws-sdk/client-dynamodb": "^3.821.0", - "@aws-sdk/lib-dynamodb": "^3.821.0", + "@aws-sdk/client-dynamodb": "^3.830.0", + "@aws-sdk/lib-dynamodb": "^3.830.0", "aws-sdk-client-mock": "^4.1.0" }, "peerDependencies": { @@ -25270,18 +25522,48 @@ }, "packages/jmespath": { "name": "@aws-lambda-powertools/jmespath", - "version": "2.21.0", + "version": "2.22.0", + "license": "MIT-0", + "dependencies": { + "@aws-lambda-powertools/commons": "2.22.0" + } + }, + "packages/kafka": { + "name": "@aws-lambda-powertools/kafka", + "version": "2.22.0", "license": "MIT-0", "dependencies": { - "@aws-lambda-powertools/commons": "2.21.0" + "@aws-lambda-powertools/commons": "2.22.0", + "@standard-schema/spec": "^1.0.0" + }, + "devDependencies": { + "avro-js": "^1.12.0", + "protobufjs": "^7.5.3", + "zod": "^3.25.67" + }, + "peerDependencies": { + "arktype": ">=2.0.0", + "valibot": ">=1.0.0", + "zod": ">=3.24.0" + }, + "peerDependenciesMeta": { + "arktype": { + "optional": true + }, + "valibot": { + "optional": true + }, + "zod": { + "optional": true + } } }, "packages/logger": { "name": "@aws-lambda-powertools/logger", - "version": "2.21.0", + "version": "2.22.0", "license": "MIT-0", "dependencies": { - "@aws-lambda-powertools/commons": "2.21.0", + "@aws-lambda-powertools/commons": "2.22.0", "lodash.merge": "^4.6.2" }, "devDependencies": { @@ -25303,14 +25585,14 @@ }, "packages/metrics": { "name": "@aws-lambda-powertools/metrics", - "version": "2.21.0", + "version": "2.22.0", "license": "MIT-0", "dependencies": { - "@aws-lambda-powertools/commons": "2.21.0" + "@aws-lambda-powertools/commons": "2.22.0" }, "devDependencies": { "@aws-lambda-powertools/testing-utils": "file:../testing", - "@aws-sdk/client-cloudwatch": "^3.821.0", + "@aws-sdk/client-cloudwatch": "^3.830.0", "@types/promise-retry": "^1.1.3", "promise-retry": "^2.0.1" }, @@ -25325,18 +25607,18 @@ }, "packages/parameters": { "name": "@aws-lambda-powertools/parameters", - "version": "2.21.0", + "version": "2.22.0", "license": "MIT-0", "dependencies": { - "@aws-lambda-powertools/commons": "2.21.0" + "@aws-lambda-powertools/commons": "2.22.0" }, "devDependencies": { "@aws-lambda-powertools/testing-utils": "file:../testing", - "@aws-sdk/client-appconfigdata": "^3.821.0", - "@aws-sdk/client-dynamodb": "^3.821.0", - "@aws-sdk/client-secrets-manager": "^3.821.0", - "@aws-sdk/client-ssm": "^3.821.0", - "@aws-sdk/util-dynamodb": "^3.821.0", + "@aws-sdk/client-appconfigdata": "^3.830.0", + "@aws-sdk/client-dynamodb": "^3.830.0", + "@aws-sdk/client-secrets-manager": "^3.830.0", + "@aws-sdk/client-ssm": "^3.830.0", + "@aws-sdk/util-dynamodb": "^3.830.0", "@smithy/util-base64": "^4.0.0", "aws-sdk-client-mock": "^4.1.0" }, @@ -25371,10 +25653,10 @@ }, "packages/parser": { "name": "@aws-lambda-powertools/parser", - "version": "2.21.0", + "version": "2.22.0", "license": "MIT-0", "dependencies": { - "@aws-lambda-powertools/commons": "2.21.0" + "@aws-lambda-powertools/commons": "2.22.0" }, "peerDependencies": { "@middy/core": "4.x || 5.x || 6.x", @@ -25391,13 +25673,13 @@ }, "packages/testing": { "name": "@aws-lambda-powertools/testing-utils", - "version": "2.21.0", + "version": "2.22.0", "license": "MIT-0", "dependencies": { - "@aws-cdk/toolkit-lib": "^1.0.0", - "@aws-sdk/client-lambda": "^3.821.0", + "@aws-cdk/toolkit-lib": "^1.1.1", + "@aws-sdk/client-lambda": "^3.830.0", "@smithy/util-utf8": "^4.0.0", - "aws-cdk-lib": "^2.200.0", + "aws-cdk-lib": "^2.201.0", "esbuild": "^0.25.5", "promise-retry": "^2.0.1" }, @@ -25408,16 +25690,16 @@ }, "packages/tracer": { "name": "@aws-lambda-powertools/tracer", - "version": "2.21.0", + "version": "2.22.0", "license": "MIT-0", "dependencies": { - "@aws-lambda-powertools/commons": "2.21.0", + "@aws-lambda-powertools/commons": "2.22.0", "aws-xray-sdk-core": "^3.10.3" }, "devDependencies": { "@aws-lambda-powertools/testing-utils": "file:../testing", - "@aws-sdk/client-dynamodb": "^3.821.0", - "@aws-sdk/client-xray": "^3.821.0" + "@aws-sdk/client-dynamodb": "^3.830.0", + "@aws-sdk/client-xray": "^3.830.0" }, "peerDependencies": { "@middy/core": "4.x || 5.x || 6.x" @@ -25430,11 +25712,11 @@ }, "packages/validation": { "name": "@aws-lambda-powertools/validation", - "version": "2.21.0", + "version": "2.22.0", "license": "MIT-0", "dependencies": { - "@aws-lambda-powertools/commons": "2.21.0", - "@aws-lambda-powertools/jmespath": "2.21.0", + "@aws-lambda-powertools/commons": "2.22.0", + "@aws-lambda-powertools/jmespath": "2.22.0", "ajv": "^8.17.1" } } diff --git a/package.json b/package.json index 4c29cacff9..eed4f5fc5b 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "layers", "examples/app", "packages/event-handler", - "packages/validation" + "packages/validation", + "packages/kafka" ], "type": "module", "scripts": { @@ -52,12 +53,12 @@ "homepage": "https://github.com/aws-powertools/powertools-lambda-typescript#readme", "devDependencies": { "@biomejs/biome": "^1.9.4", - "@types/aws-lambda": "^8.10.149", - "@types/node": "^22.15.29", - "@vitest/coverage-v8": "^3.1.4", + "@types/aws-lambda": "^8.10.150", + "@types/node": "^24.0.3", + "@vitest/coverage-v8": "^3.2.3", "husky": "^9.1.7", "lerna": "8.1.2", - "lint-staged": "^16.1.0", + "lint-staged": "^16.1.2", "markdownlint-cli2": "^0.18.1", "middy4": "npm:@middy/core@^4.7.0", "middy5": "npm:@middy/core@^5.4.3", diff --git a/packages/batch/CHANGELOG.md b/packages/batch/CHANGELOG.md index af4089cc8d..4051b5fdee 100644 --- a/packages/batch/CHANGELOG.md +++ b/packages/batch/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.22.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.21.0...v2.22.0) (2025-06-20) + +**Note:** Version bump only for package @aws-lambda-powertools/batch + + + + + # [2.21.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.20.0...v2.21.0) (2025-06-03) **Note:** Version bump only for package @aws-lambda-powertools/batch diff --git a/packages/batch/package.json b/packages/batch/package.json index e28fd5fefe..1ef5d8b868 100644 --- a/packages/batch/package.json +++ b/packages/batch/package.json @@ -1,6 +1,6 @@ { "name": "@aws-lambda-powertools/batch", - "version": "2.21.0", + "version": "2.22.0", "description": "The batch processing package for the Powertools for AWS Lambda (TypeScript) library.", "author": { "name": "Amazon Web Services", diff --git a/packages/commons/CHANGELOG.md b/packages/commons/CHANGELOG.md index e37fd924d4..e61abe554c 100644 --- a/packages/commons/CHANGELOG.md +++ b/packages/commons/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.22.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.21.0...v2.22.0) (2025-06-20) + +**Note:** Version bump only for package @aws-lambda-powertools/commons + + + + + # [2.21.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.20.0...v2.21.0) (2025-06-03) diff --git a/packages/commons/package.json b/packages/commons/package.json index fa447c0ecc..47c6afa199 100644 --- a/packages/commons/package.json +++ b/packages/commons/package.json @@ -1,6 +1,6 @@ { "name": "@aws-lambda-powertools/commons", - "version": "2.21.0", + "version": "2.22.0", "description": "A shared utility package for Powertools for AWS Lambda (TypeScript) libraries", "author": { "name": "Amazon Web Services", diff --git a/packages/commons/src/version.ts b/packages/commons/src/version.ts index 53e977bccd..d956889c7a 100644 --- a/packages/commons/src/version.ts +++ b/packages/commons/src/version.ts @@ -1,2 +1,2 @@ // this file is auto generated, do not modify -export const PT_VERSION = '2.21.0'; +export const PT_VERSION = '2.22.0'; diff --git a/packages/event-handler/CHANGELOG.md b/packages/event-handler/CHANGELOG.md index 76429957f1..e38798f0c2 100644 --- a/packages/event-handler/CHANGELOG.md +++ b/packages/event-handler/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.22.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.21.0...v2.22.0) (2025-06-20) + + +### Bug Fixes + +* **event-handler:** fix decorated scope in appsync events ([#3974](https://github.com/aws-powertools/powertools-lambda-typescript/issues/3974)) ([e539719](https://github.com/aws-powertools/powertools-lambda-typescript/commit/e5397199133da265f593c5feed0178c0ebe1e7c2)) + + + + + # [2.21.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.20.0...v2.21.0) (2025-06-03) diff --git a/packages/event-handler/package.json b/packages/event-handler/package.json index 6e161ae667..10a440799a 100644 --- a/packages/event-handler/package.json +++ b/packages/event-handler/package.json @@ -1,6 +1,6 @@ { "name": "@aws-lambda-powertools/event-handler", - "version": "2.21.0", + "version": "2.22.0", "description": "Lightweight routing to reduce boilerplate for API Gateway REST/HTTP API, ALB, Lambda Function URLs, and AppSync.", "author": { "name": "Amazon Web Services", @@ -87,7 +87,7 @@ "url": "https://github.com/aws-powertools/powertools-lambda-typescript/issues" }, "dependencies": { - "@aws-lambda-powertools/commons": "2.21.0" + "@aws-lambda-powertools/commons": "2.22.0" }, "keywords": [ "aws", diff --git a/packages/event-handler/src/appsync-events/AppSyncEventsResolver.ts b/packages/event-handler/src/appsync-events/AppSyncEventsResolver.ts index 457ddbc30d..d889361104 100644 --- a/packages/event-handler/src/appsync-events/AppSyncEventsResolver.ts +++ b/packages/event-handler/src/appsync-events/AppSyncEventsResolver.ts @@ -5,6 +5,7 @@ import type { OnPublishHandlerAggregateFn, OnPublishHandlerFn, OnSubscribeHandler, + ResolveOptions, } from '../types/appsync-events.js'; import { Router } from './Router.js'; import { UnauthorizedException } from './errors.js'; @@ -67,7 +68,9 @@ class AppSyncEventsResolver extends Router { * } * * async handler(event, context) { - * return app.resolve(event, context); + * return app.resolve(event, context, { + * scope: this, // bind decorated methods to the class instance + * }); * } * } * @@ -78,7 +81,11 @@ class AppSyncEventsResolver extends Router { * @param event - The incoming event from AppSync Events * @param context - The context object provided by AWS Lambda */ - public async resolve(event: unknown, context: Context) { + public async resolve( + event: unknown, + context: Context, + options?: ResolveOptions + ) { if (!isAppSyncEventsEvent(event)) { this.logger.warn( 'Received an event that is not compatible with this resolver' @@ -87,11 +94,12 @@ class AppSyncEventsResolver extends Router { } if (isAppSyncEventsPublishEvent(event)) { - return await this.handleOnPublish(event, context); + return await this.handleOnPublish(event, context, options); } return await this.handleOnSubscribe( event as AppSyncEventsSubscribeEvent, - context + context, + options ); } @@ -100,10 +108,12 @@ class AppSyncEventsResolver extends Router { * * @param event - The incoming event from AppSync Events * @param context - The context object provided by AWS Lambda + * @param options - Optional resolve options */ protected async handleOnPublish( event: AppSyncEventsPublishEvent, - context: Context + context: Context, + options?: ResolveOptions ) { const { path } = event.info.channel; const routeHandlerOptions = this.onPublishRegistry.resolve(path); @@ -114,11 +124,10 @@ class AppSyncEventsResolver extends Router { if (aggregate) { try { return { - events: await (handler as OnPublishHandlerAggregateFn).apply(this, [ - event.events, - event, - context, - ]), + events: await (handler as OnPublishHandlerAggregateFn).apply( + options?.scope ?? this, + [event.events, event, context] + ), }; } catch (error) { this.logger.error(`An error occurred in handler ${path}`, error); @@ -131,11 +140,10 @@ class AppSyncEventsResolver extends Router { event.events.map(async (message) => { const { id, payload } = message; try { - const result = await (handler as OnPublishHandlerFn).apply(this, [ - payload, - event, - context, - ]); + const result = await (handler as OnPublishHandlerFn).apply( + options?.scope ?? this, + [payload, event, context] + ); return { id, payload: result, @@ -161,10 +169,12 @@ class AppSyncEventsResolver extends Router { * * @param event - The incoming event from AppSync Events * @param context - The context object provided by AWS Lambda + * @param options - Optional resolve options */ protected async handleOnSubscribe( event: AppSyncEventsSubscribeEvent, - context: Context + context: Context, + options?: ResolveOptions ) { const { path } = event.info.channel; const routeHandlerOptions = this.onSubscribeRegistry.resolve(path); @@ -173,7 +183,10 @@ class AppSyncEventsResolver extends Router { } const { handler } = routeHandlerOptions; try { - await (handler as OnSubscribeHandler).apply(this, [event, context]); + await (handler as OnSubscribeHandler).apply(options?.scope ?? this, [ + event, + context, + ]); } catch (error) { this.logger.error(`An error occurred in handler ${path}`, error); if (error instanceof UnauthorizedException) throw error; diff --git a/packages/event-handler/src/appsync-events/Router.ts b/packages/event-handler/src/appsync-events/Router.ts index f9402b53c8..7326fc1319 100644 --- a/packages/event-handler/src/appsync-events/Router.ts +++ b/packages/event-handler/src/appsync-events/Router.ts @@ -9,6 +9,9 @@ import type { } from '../types/appsync-events.js'; import { RouteHandlerRegistry } from './RouteHandlerRegistry.js'; +// Simple global approach - store the last instance per router +const routerInstanceMap = new WeakMap(); + /** * Class for registering routes for the `onPublish` and `onSubscribe` events in AWS AppSync Events APIs. */ @@ -194,11 +197,11 @@ class Router { return; } - return (_target, _propertyKey, descriptor: PropertyDescriptor) => { + return (target, _propertyKey, descriptor: PropertyDescriptor) => { const routeOptions = isRecord(handler) ? handler : options; this.onPublishRegistry.register({ path, - handler: descriptor.value, + handler: descriptor?.value, aggregate: (routeOptions?.aggregate ?? false) as T, }); return descriptor; @@ -276,7 +279,7 @@ class Router { return (_target, _propertyKey, descriptor: PropertyDescriptor) => { this.onSubscribeRegistry.register({ path, - handler: descriptor.value, + handler: descriptor?.value, }); return descriptor; }; diff --git a/packages/event-handler/src/types/appsync-events.ts b/packages/event-handler/src/types/appsync-events.ts index 1367cacd93..a225446190 100644 --- a/packages/event-handler/src/types/appsync-events.ts +++ b/packages/event-handler/src/types/appsync-events.ts @@ -1,8 +1,47 @@ import type { Context } from 'aws-lambda'; +import type { AppSyncEventsResolver } from '../appsync-events/AppSyncEventsResolver.js'; import type { RouteHandlerRegistry } from '../appsync-events/RouteHandlerRegistry.js'; import type { Router } from '../appsync-events/Router.js'; import type { Anything, GenericLogger } from './common.js'; +// #region resolve options + +/** + * Optional object to pass to the {@link AppSyncEventsResolver.resolve | `AppSyncEventsResolver.resolve()`} method. + */ +type ResolveOptions = { + /** + * Reference to `this` instance of the class that is calling the `resolve` method. + * + * This parameter should be used only when using {@link AppSyncEventsResolver.onPublish | `AppSyncEventsResolver.onPublish()`} + * and {@link AppSyncEventsResolver.onSubscribe | `AppSyncEventsResolver.onSubscribe()`} as class method decorators, and + * it's used to bind the decorated methods to your class instance. + * + * @example + * ```ts + * import { AppSyncEventsResolver } from '@aws-lambda-powertools/event-handler/appsync-events'; + * + * const app = new AppSyncEventsResolver(); + * + * class Lambda { + * public scope = 'scoped'; + * + * ⁣@app.onPublish('/foo') + * public async handleFoo(payload: string) { + * return `${this.scope} ${payload}`; + * } + * + * public async handler(event: unknown, context: Context) { + * return app.resolve(event, context, { scope: this }); + * } + * } + * const lambda = new Lambda(); + * const handler = lambda.handler.bind(lambda); + * ``` + */ + scope?: unknown; +}; + // #region OnPublish fn type OnPublishHandlerFn = ( @@ -17,11 +56,13 @@ type OnPublishHandlerSyncFn = ( context: Context ) => unknown; +type OnPublishAggregatePayload = Array<{ + payload: Anything; + id: string; +}>; + type OnPublishHandlerAggregateFn = ( - events: Array<{ - payload: Anything; - id: string; - }>, + events: OnPublishAggregatePayload, event: AppSyncEventsPublishEvent, context: Context ) => Promise; @@ -294,8 +335,10 @@ export type { OnPublishHandlerSyncFn, OnPublishHandlerSyncAggregateFn, OnPublishHandlerAggregateFn, + OnPublishAggregatePayload, OnSubscribeHandler, OnPublishAggregateOutput, OnPublishEventPayload, OnPublishOutput, + ResolveOptions, }; diff --git a/packages/event-handler/src/types/index.ts b/packages/event-handler/src/types/index.ts index dfa9f78985..f43b4c8de3 100644 --- a/packages/event-handler/src/types/index.ts +++ b/packages/event-handler/src/types/index.ts @@ -3,10 +3,12 @@ export type { AppSyncEventsPublishEvent, AppSyncEventsSubscribeEvent, OnPublishAggregateOutput, + OnPublishAggregatePayload, OnPublishEventPayload, OnPublishOutput, RouteOptions, RouterOptions, + ResolveOptions, } from './appsync-events.js'; export type { diff --git a/packages/event-handler/tests/unit/appsync-events/AppSyncEventsResolver.test.ts b/packages/event-handler/tests/unit/appsync-events/AppSyncEventsResolver.test.ts index d75bede42f..16da12ce63 100644 --- a/packages/event-handler/tests/unit/appsync-events/AppSyncEventsResolver.test.ts +++ b/packages/event-handler/tests/unit/appsync-events/AppSyncEventsResolver.test.ts @@ -1,9 +1,14 @@ import context from '@aws-lambda-powertools/testing-utils/context'; +import type { Context } from 'aws-lambda'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { AppSyncEventsResolver, UnauthorizedException, } from '../../../src/appsync-events/index.js'; +import type { + AppSyncEventsSubscribeEvent, + OnPublishAggregatePayload, +} from '../../../src/types/appsync-events.js'; import { onPublishEventFactory, onSubscribeEventFactory, @@ -63,6 +68,112 @@ describe('Class: AppSyncEventsResolver', () => { }); }); + it.each([ + { aggregate: true, channel: { path: '/foo', segments: ['foo'] } }, + { + aggregate: false, + channel: { + path: '/bar', + segments: ['bar'], + }, + }, + ])( + 'preserves the scope when decorating with onPublish aggregate=$aggregate', + async ({ aggregate, channel }) => { + // Prepare + const app = new AppSyncEventsResolver({ logger: console }); + + class Lambda { + public scope = 'scoped'; + + @app.onPublish('/foo', { aggregate }) + public async handleFoo(payloads: OnPublishAggregatePayload) { + return payloads.map((payload) => { + return { + id: payload.id, + payload: `${this.scope} ${payload.payload}`, + }; + }); + } + + @app.onPublish('/bar') + public async handleBar(payload: string) { + return `${this.scope} ${payload}`; + } + + public async handler(event: unknown, context: Context) { + return this.stuff(event, context); + } + + async stuff(event: unknown, context: Context) { + return app.resolve(event, context, { scope: this }); + } + } + const lambda = new Lambda(); + const handler = lambda.handler.bind(lambda); + + // Act + const result = await handler( + onPublishEventFactory( + [ + { + id: '1', + payload: 'foo', + }, + ], + channel + ), + context + ); + + // Assess + expect(result).toEqual({ + events: [ + { + id: '1', + payload: 'scoped foo', + }, + ], + }); + } + ); + + it('preserves the scope when decorating with onSubscribe', async () => { + // Prepare + const app = new AppSyncEventsResolver({ logger: console }); + + class Lambda { + public scope = 'scoped'; + + @app.onSubscribe('/foo') + public async handleFoo(payload: AppSyncEventsSubscribeEvent) { + console.debug(`${this.scope} ${payload.info.channel.path}`); + } + + public async handler(event: unknown, context: Context) { + return this.stuff(event, context); + } + + async stuff(event: unknown, context: Context) { + return app.resolve(event, context, { scope: this }); + } + } + const lambda = new Lambda(); + const handler = lambda.handler.bind(lambda); + + // Act + await handler( + onSubscribeEventFactory({ + path: '/foo', + segments: ['foo'], + }), + context + ); + + // Assess + expect(console.debug).toHaveBeenCalledWith('scoped /foo'); + }); + it('returns null if there are no onSubscribe handlers', async () => { // Prepare const app = new AppSyncEventsResolver({ logger: console }); diff --git a/packages/idempotency/CHANGELOG.md b/packages/idempotency/CHANGELOG.md index 9b41576d97..a0d925d998 100644 --- a/packages/idempotency/CHANGELOG.md +++ b/packages/idempotency/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.22.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.21.0...v2.22.0) (2025-06-20) + +**Note:** Version bump only for package @aws-lambda-powertools/idempotency + + + + + # [2.21.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.20.0...v2.21.0) (2025-06-03) **Note:** Version bump only for package @aws-lambda-powertools/idempotency diff --git a/packages/idempotency/package.json b/packages/idempotency/package.json index 7f6f3c98d6..080c938640 100644 --- a/packages/idempotency/package.json +++ b/packages/idempotency/package.json @@ -1,6 +1,6 @@ { "name": "@aws-lambda-powertools/idempotency", - "version": "2.21.0", + "version": "2.22.0", "description": "The idempotency package for the Powertools for AWS Lambda (TypeScript) library. It provides options to make your Lambda functions idempotent and safe to retry.", "author": { "name": "Amazon Web Services", @@ -114,8 +114,8 @@ "url": "https://github.com/aws-powertools/powertools-lambda-typescript/issues" }, "dependencies": { - "@aws-lambda-powertools/commons": "2.21.0", - "@aws-lambda-powertools/jmespath": "2.21.0" + "@aws-lambda-powertools/commons": "2.22.0", + "@aws-lambda-powertools/jmespath": "2.22.0" }, "peerDependencies": { "@aws-sdk/client-dynamodb": ">=3.x", @@ -151,8 +151,8 @@ ], "devDependencies": { "@aws-lambda-powertools/testing-utils": "file:../testing", - "@aws-sdk/client-dynamodb": "^3.821.0", - "@aws-sdk/lib-dynamodb": "^3.821.0", + "@aws-sdk/client-dynamodb": "^3.830.0", + "@aws-sdk/lib-dynamodb": "^3.830.0", "aws-sdk-client-mock": "^4.1.0" } } diff --git a/packages/jmespath/CHANGELOG.md b/packages/jmespath/CHANGELOG.md index 163f37410e..051b36c659 100644 --- a/packages/jmespath/CHANGELOG.md +++ b/packages/jmespath/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.22.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.21.0...v2.22.0) (2025-06-20) + +**Note:** Version bump only for package @aws-lambda-powertools/jmespath + + + + + # [2.21.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.20.0...v2.21.0) (2025-06-03) **Note:** Version bump only for package @aws-lambda-powertools/jmespath diff --git a/packages/jmespath/package.json b/packages/jmespath/package.json index a294bace3e..26411cb27e 100644 --- a/packages/jmespath/package.json +++ b/packages/jmespath/package.json @@ -1,6 +1,6 @@ { "name": "@aws-lambda-powertools/jmespath", - "version": "2.21.0", + "version": "2.22.0", "description": "A type safe and modern jmespath module to parse and extract data from JSON documents using JMESPath", "author": { "name": "Amazon Web Services", @@ -71,7 +71,7 @@ "lib" ], "dependencies": { - "@aws-lambda-powertools/commons": "^2.21.0" + "@aws-lambda-powertools/commons": "2.22.0" }, "repository": { "type": "git", diff --git a/packages/kafka/CHANGELOG.md b/packages/kafka/CHANGELOG.md new file mode 100644 index 0000000000..2de6699ad1 --- /dev/null +++ b/packages/kafka/CHANGELOG.md @@ -0,0 +1,13 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [2.22.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.21.0...v2.22.0) (2025-06-20) + + +### Features + +* **kafka:** add logic to handle delimited protobufs ([#4071](https://github.com/aws-powertools/powertools-lambda-typescript/issues/4071)) ([db9ec0c](https://github.com/aws-powertools/powertools-lambda-typescript/commit/db9ec0c4af668c002460f8dc9171c7d4bfc155b2)) +* **kafka:** lazily deserialize key/value/headers ([#4068](https://github.com/aws-powertools/powertools-lambda-typescript/issues/4068)) ([ef9bb52](https://github.com/aws-powertools/powertools-lambda-typescript/commit/ef9bb5215a588f3d9a4e9ec9da7c0b307e3c4fa0)) +* **kafka:** new kafka utility ([#4058](https://github.com/aws-powertools/powertools-lambda-typescript/issues/4058)) ([006f27b](https://github.com/aws-powertools/powertools-lambda-typescript/commit/006f27bd9909e2da548cff9dbdcc1944ba76dbd1)) diff --git a/packages/kafka/README.md b/packages/kafka/README.md new file mode 100644 index 0000000000..e60682ec3a --- /dev/null +++ b/packages/kafka/README.md @@ -0,0 +1,305 @@ +# Powertools for AWS Lambda (TypeScript) - Kafka Utility + +Powertools for AWS Lambda (TypeScript) is a developer toolkit to implement Serverless [best practices and increase developer velocity](https://docs.powertools.aws.dev/lambda/typescript/latest/#features). + +You can use the package in both TypeScript and JavaScript code bases. + +## Intro + +The Kafka Consumer utility transparently handles message deserialization, provides an intuitive developer experience, and integrates seamlessly with the rest of the Powertools for AWS Lambda ecosystem. + +## Usage + +To get started, depending on the schema types you want to use, install the library and the corresponding libraries: + +For JSON schemas: + +```bash +npm install @aws-lambda-powertools/kafka +``` + +For Avro schemas: + +```bash +npm install @aws-lambda-powertools/kafka avro-js +``` + +For Protobuf schemas: + +```bash +npm install @aws-lambda-powertools/kafka protobufjs +``` + +Additionally, if you want to use output parsing with [Standard Schema](https://github.com/standard-schema/standard-schema), you can install [any of the supported libraries](https://standardschema.dev/#what-schema-libraries-implement-the-spec), for example: Zod, Valibot, or ArkType. + +### Deserialization + +The Kafka consumer utility transforms raw Kafka events into an intuitive format for processing. To handle messages effectively, you'll need to configure a schema that matches your data format. + +#### JSON Schema + +```ts +import { SchemaType, kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import type { SchemaConfig } from '@aws-lambda-powertools/kafka/types'; +import { Logger } from '@aws-lambda-powertools/logger'; + +const logger = new Logger({ serviceName: 'kafka-consumer' }); + +const schemaConfig = { + value: { + type: SchemaType.JSON, + }, +} satisfies SchemaConfig; + +export const handler = kafkaConsumer(async (event, _context) => { + for (const { value } of event.records) { + logger.info('received value', { value }); + } +}, schemaConfig); +``` + +#### Avro Schema + +```ts +import { readFileSync } from 'node:fs'; +import { SchemaType, kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import type { SchemaConfig } from '@aws-lambda-powertools/kafka/types'; +import { Logger } from '@aws-lambda-powertools/logger'; + +const logger = new Logger({ serviceName: 'kafka-consumer' }); + +const schemaConfig = { + value: { + type: SchemaType.AVRO, + schema: readFileSync(new URL('./user.avsc', import.meta.url), 'utf8'), + }, +} satisfies SchemaConfig; + +export const handler = kafkaConsumer(async (event, _context) => { + for (const { value } of event.records) { + logger.info('received value', { value }); + } +}, schemaConfig); +``` + +#### Protobuf Schema + +```ts +import { SchemaType, kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import type { SchemaConfig } from '@aws-lambda-powertools/kafka/types'; +import { Logger } from '@aws-lambda-powertools/logger'; +import { User } from './samples/user.es6.generated.js'; // protobuf generated class + +const logger = new Logger({ serviceName: 'kafka-consumer' }); + +const schemaConfig = { + value: { + type: SchemaType.PROTOBUF, + schema: User, + }, +} satisfies SchemaConfig; + +export const handler = kafkaConsumer(async (event, _context) => { + for (const { value } of event.records) { + logger.info('received value', { value }); + } +}, schemaConfig); +``` + +### Additional Parsing + +You can parse deserialized data using your preferred parsing library. This can help you integrate Kafka data with your domain schemas and application architecture, providing type hints, runtime parsing and validation, and advanced data transformations. + +#### Zod + +```ts +import { SchemaType, kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import type { SchemaConfig } from '@aws-lambda-powertools/kafka/types'; +import { Logger } from '@aws-lambda-powertools/logger'; +import { z } from 'zod/v4'; + +const logger = new Logger({ serviceName: 'kafka-consumer' }); + +const OrderItemSchema = z.object({ + productId: z.string(), + quantity: z.number().int().positive(), + price: z.number().positive(), +}); + +const OrderSchema = z.object({ + id: z.string(), + customerId: z.string(), + items: z.array(OrderItemSchema).min(1, 'Order must have at least one item'), + createdAt: z.iso.datetime(), + totalAmount: z.number().positive(), +}); + +const schemaConfig = { + value: { + type: SchemaType.JSON, + parserSchema: OrderSchema, + }, +} satisfies SchemaConfig; + +export const handler = kafkaConsumer>( + async (event, _context) => { + for (const record of event.records) { + const { + value: { id, items }, + } = record; + logger.setCorrelationId(id); + logger.debug(`order includes ${items.length} items`); + } + }, + schemaConfig +); +``` + +#### Valibot + +```ts +import { SchemaType, kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import type { SchemaConfig } from '@aws-lambda-powertools/kafka/types'; +import { Logger } from '@aws-lambda-powertools/logger'; +import * as v from 'valibot'; + +const logger = new Logger({ serviceName: 'kafka-consumer' }); + +const OrderItemSchema = v.object({ + productId: v.string(), + quantity: v.pipe(v.number(), v.integer(), v.toMinValue(1)), + price: v.pipe(v.number(), v.integer()), +}); + +const OrderSchema = v.object({ + id: v.string(), + customerId: v.string(), + items: v.pipe( + v.array(OrderItemSchema), + v.minLength(1, 'Order must have at least one item') + ), + createdAt: v.pipe(v.string(), v.isoDateTime()), + totalAmount: v.pipe(v.number(), v.toMinValue(0)), +}); + +const schemaConfig = { + value: { + type: SchemaType.JSON, + parserSchema: OrderSchema, + }, +} satisfies SchemaConfig; + +export const handler = kafkaConsumer>( + async (event, _context) => { + for (const record of event.records) { + const { + value: { id, items }, + } = record; + logger.setCorrelationId(id); + logger.debug(`order includes ${items.length} items`); + } + }, + schemaConfig +); +``` + +#### ArkType + +```ts +import { SchemaType, kafkaConsumer } from '@aws-lambda-powertools/kafka'; +import type { SchemaConfig } from '@aws-lambda-powertools/kafka/types'; +import { Logger } from '@aws-lambda-powertools/logger'; +import { type } from 'arktype'; + +const logger = new Logger({ serviceName: 'kafka-consumer' }); + +const OrderItemSchema = type({ + productId: 'string', + quantity: 'number.integer >= 1', + price: 'number.integer', +}); + +const OrderSchema = type({ + id: 'string', + customerId: 'string', + items: OrderItemSchema.array().moreThanLength(0), + createdAt: 'string.date', + totalAmount: 'number.integer >= 0', +}); + +const schemaConfig = { + value: { + type: SchemaType.JSON, + parserSchema: OrderSchema, + }, +} satisfies SchemaConfig; + +export const handler = kafkaConsumer( + async (event, _context) => { + for (const record of event.records) { + const { + value: { id, items }, + } = record; + logger.setCorrelationId(id); + logger.debug(`order includes ${items.length} items`); + } + }, + schemaConfig +); +``` + +See the [documentation](https://docs.powertools.aws.dev/lambda/typescript/latest/features/kafka) for more details on how to use the Kafka utility. + +## Contribute + +If you are interested in contributing to this project, please refer to our [Contributing Guidelines](https://github.com/aws-powertools/powertools-lambda-typescript/blob/main/CONTRIBUTING.md). + +## Roadmap + +The roadmap of Powertools for AWS Lambda (TypeScript) is driven by customers’ demand. +Help us prioritize upcoming functionalities or utilities by [upvoting existing RFCs and feature requests](https://github.com/aws-powertools/powertools-lambda-typescript/issues), or [creating new ones](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose), in this GitHub repository. + +## Connect + +* **Powertools for AWS Lambda on Discord**: `#typescript` - **[Invite link](https://discord.gg/B8zZKbbyET)** +* **Email**: + +## How to support Powertools for AWS Lambda (TypeScript)? + +### Becoming a reference customer + +Knowing which companies are using this library is important to help prioritize the project internally. If your company is using Powertools for AWS Lambda (TypeScript), you can request to have your name and logo added to the README file by raising a [Support Powertools for AWS Lambda (TypeScript) (become a reference)](https://s12d.com/become-reference-pt-ts) issue. + +The following companies, among others, use Powertools: + +* [Alma Media](https://www.almamedia.fi) +* [AppYourself](https://appyourself.net) +* [Bailey Nelson](https://www.baileynelson.com.au) +* [Banxware](https://www.banxware.com) +* [Caylent](https://caylent.com/) +* [Certible](https://www.certible.com/) +* [Elva](https://elva-group.com) +* [Flyweight](https://flyweight.io/) +* [globaldatanet](https://globaldatanet.com/) +* [Guild](https://guild.com) +* [Hashnode](https://hashnode.com/) +* [Instil](https://instil.co/) +* [LocalStack](https://localstack.cloud/) +* [Ours Privacy](https://oursprivacy.com/) +* [Perfect Post](https://www.perfectpost.fr) +* [Sennder](https://sennder.com/) +* [tecRacer GmbH & Co. KG](https://www.tecracer.com/) +* [Trek10](https://www.trek10.com/) +* [WeSchool](https://www.weschool.com) + +### Sharing your work + +Share what you did with Powertools for AWS Lambda (TypeScript) 💞💞. Blog post, workshops, presentation, sample apps and others. Check out what the community has [already shared](https://docs.powertools.aws.dev/lambda/typescript/latest/we_made_this) about Powertools for AWS Lambda (TypeScript). + +### Using Lambda Layer + +This helps us understand who uses Powertools for AWS Lambda (TypeScript) in a non-intrusive way, and helps us gain future investments for other Powertools for AWS Lambda languages. When [using Layers](https://docs.powertools.aws.dev/lambda/typescript/latest/getting-started/lambda-layers/), you can add Powertools as a dev dependency to not impact the development process. + +## License + +This library is licensed under the MIT-0 License. See the LICENSE file. diff --git a/packages/kafka/package.json b/packages/kafka/package.json new file mode 100644 index 0000000000..e26e87b8c3 --- /dev/null +++ b/packages/kafka/package.json @@ -0,0 +1,123 @@ +{ + "name": "@aws-lambda-powertools/kafka", + "description": "Utility to easily handle message deserialization and parsing of Kafka events in AWS Lambda functions", + "version": "2.22.0", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com" + }, + "publishConfig": { + "access": "public" + }, + "scripts": { + "test": "vitest --run", + "test:unit": "vitest --run", + "test:unit:coverage": "vitest --run tests/unit --coverage.enabled --coverage.thresholds.100 --coverage.include='src/**'", + "test:unit:types": "echo 'Not Implemented'", + "test:e2e:nodejs18x": "echo \"Not implemented\"", + "test:e2e:nodejs20x": "echo \"Not implemented\"", + "test:e2e:nodejs22x": "echo \"Not implemented\"", + "test:e2e": "echo \"Not implemented\"", + "build:cjs": "tsc --build tsconfig.cjs.json && echo '{ \"type\": \"commonjs\" }' > lib/cjs/package.json", + "build:esm": "tsc --build tsconfig.json && echo '{ \"type\": \"module\" }' > lib/esm/package.json", + "build": "npm run build:esm & npm run build:cjs", + "lint": "biome lint .", + "lint:fix": "biome check --write .", + "prepack": "node ../../.github/scripts/release_patch_package_json.js .", + "proto:gen": "npx pbjs -t static-module -w es6 -o $(pwd)/tests/protos/product.es6.generated.js $(pwd)/tests/protos/product.proto && npx pbts -o $(pwd)/tests/protos/product.es6.generated.d.ts $(pwd)/tests/protos/product.es6.generated.js && npx pbjs -t static-module -w commonjs -o $(pwd)/tests/protos/product.cjs.generated.js $(pwd)/tests/protos/product.proto && npx pbts -o $(pwd)/tests/protos/product.cjs.generated.d.ts $(pwd)/tests/protos/product.cjs.generated.js" + }, + "license": "MIT-0", + "homepage": "https://github.com/aws-powertools/powertools-lambda-typescript#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/aws-powertools/powertools-lambda-typescript.git" + }, + "bugs": { + "url": "https://github.com/aws-powertools/powertools-lambda-typescript/issues" + }, + "keywords": [ + "aws", + "lambda", + "powertools", + "kafka", + "event", + "schema", + "validation", + "typescript", + "nodejs" + ], + "dependencies": { + "@aws-lambda-powertools/commons": "2.22.0", + "@standard-schema/spec": "^1.0.0" + }, + "peerDependencies": { + "arktype": ">=2.0.0", + "valibot": ">=1.0.0", + "zod": ">=3.24.0" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + }, + "valibot": { + "optional": true + }, + "arktype": { + "optional": true + } + }, + "files": [ + "lib" + ], + "type": "module", + "exports": { + ".": { + "require": { + "types": "./lib/cjs/index.d.ts", + "default": "./lib/cjs/index.js" + }, + "import": { + "types": "./lib/esm/index.d.ts", + "default": "./lib/esm/index.js" + } + }, + "./errors": { + "require": { + "types": "./lib/cjs/errors.d.ts", + "default": "./lib/cjs/errors.js" + }, + "import": { + "types": "./lib/esm/errors.d.ts", + "default": "./lib/esm/errors.js" + } + }, + "./types": { + "require": { + "types": "./lib/cjs/types/index.d.ts", + "default": "./lib/cjs/types/index.js" + }, + "import": { + "types": "./lib/esm/types/index.d.ts", + "default": "./lib/esm/types/index.js" + } + } + }, + "typesVersions": { + "*": { + "errors": [ + "lib/cjs/errors.d.ts", + "lib/esm/errors.d.ts" + ], + "types": [ + "lib/cjs/types/index.d.ts", + "lib/esm/types/index.d.ts" + ] + } + }, + "private": true, + "devDependencies": { + "avro-js": "^1.12.0", + "protobufjs": "^7.5.3", + "zod": "^3.25.67" + } +} diff --git a/packages/kafka/src/constants.ts b/packages/kafka/src/constants.ts new file mode 100644 index 0000000000..230276147b --- /dev/null +++ b/packages/kafka/src/constants.ts @@ -0,0 +1,10 @@ +/** + * Types of Kafka schema formats. + */ +const SchemaType = { + JSON: 'json', + AVRO: 'avro', + PROTOBUF: 'protobuf', +} as const; + +export { SchemaType }; diff --git a/packages/kafka/src/consumer.ts b/packages/kafka/src/consumer.ts new file mode 100644 index 0000000000..10436372f2 --- /dev/null +++ b/packages/kafka/src/consumer.ts @@ -0,0 +1,285 @@ +import type { AsyncHandler } from '@aws-lambda-powertools/commons/types'; +import { isNull, isRecord } from '@aws-lambda-powertools/commons/typeutils'; +import type { StandardSchemaV1 } from '@standard-schema/spec'; +import type { Context, Handler } from 'aws-lambda'; +import { deserialize as deserializeJson } from './deserializer/json.js'; +import { deserialize as deserializePrimitive } from './deserializer/primitive.js'; +import { + KafkaConsumerDeserializationError, + KafkaConsumerError, + KafkaConsumerMissingSchemaError, + KafkaConsumerParserError, +} from './errors.js'; +import type { + ConsumerRecord, + ConsumerRecords, + DeserializeOptions, + Deserializer, + Record as KafkaRecord, + MSKEvent, + SchemaConfig, + SchemaConfigValue, +} from './types/types.js'; + +/** + * Type guard to assert that the event is a valid {@link MSKEvent | `MSKEvent`}. + * + * @param event - The event to validate, expected to be an MSKEvent. + */ +const assertIsMSKEvent = (event: unknown): event is MSKEvent => { + if ( + !isRecord(event) || + !isRecord(event.records) || + !Object.values(event.records).every((arr) => Array.isArray(arr)) + ) { + throw new KafkaConsumerError( + 'Event is not a valid MSKEvent. Expected an object with a "records" property.' + ); + } + + return true; +}; + +/** + * Deserialize Kafka message headers from an array of header objects. + * + * It returns `null` if the headers are `null`, or an array of header objects + * where each header value is decoded as a UTF-8 string. + * + * @param headers - An array of header objects, where each object maps header keys (string) + * to header values (`number[]`), representing the raw bytes of each header value - + * i.e. `[{ "headerKey": [104, 101, 108, 108, 111] }]` + */ +const deserializeHeaders = (headers: Record[] | null) => { + if (headers === null) { + return null; + } + const result = []; + for (const header of headers) { + const entries = []; + for (const [headerKey, headerValue] of Object.entries(header)) { + entries.push([headerKey, Buffer.from(headerValue).toString('utf-8')]); + } + result.push(Object.fromEntries(entries)); + } + return result; +}; + +/** + * Deserialize a base64-encoded value using the provided schema configuration. + * + * It returns the deserialized value, which may be a string, object, or other type depending on the schema type. + * + * @param value - The base64-encoded string to deserialize. + * @param config - The schema configuration to use for deserialization. See {@link SchemaConfigValue | `SchemaConfigValue`}. + * If not provided, the value is decoded as a UTF-8 string. + */ +const deserialize = ({ + value, + deserializer, + config, + schemaMetadata, +}: DeserializeOptions) => { + if (config === undefined) { + return deserializer(value); + } + if (config.type === 'json') { + return deserializer(value); + } + + if (config.type === 'avro') { + if (!config.schema) { + throw new KafkaConsumerMissingSchemaError( + 'Schema string is required for avro deserialization' + ); + } + return deserializer(value, config.schema); + } + if (config.type === 'protobuf') { + if (!config.schema) { + throw new KafkaConsumerMissingSchemaError( + 'Schema string is required for protobuf deserialization' + ); + } + return deserializer(value, config.schema, schemaMetadata); + } +}; + +/** + * Get the deserializer function based on the provided type. + * + * @param type - The type of deserializer to use. Supported types are: `json`, `avro`, `protobuf`, or `undefined`. + * If `undefined`, it defaults to deserializing as a primitive string. + */ +const getDeserializer = async (type?: string) => { + if (!type) { + return deserializePrimitive as Deserializer; + } + if (type === 'json') { + return deserializeJson as Deserializer; + } + if (type === 'protobuf') { + const deserializer = await import('./deserializer/protobuf.js'); + return deserializer.deserialize as Deserializer; + } + if (type === 'avro') { + const deserializer = await import('./deserializer/avro.js'); + return deserializer.deserialize as Deserializer; + } + throw new KafkaConsumerDeserializationError( + `Unsupported deserialization type: ${type}. Supported types are: json, avro, protobuf.` + ); +}; + +/** + * Parse a value against a provided schema using the `~standard` property for validation. + * + * @param value - The value to parse against the schema. + * @param schema - The schema to validate against, which should be a {@link StandardSchemaV1 | `Standard Schema V1`} object. + */ +const parseSchema = (value: unknown, schema: StandardSchemaV1) => { + const result = schema['~standard'].validate(value); + /* v8 ignore start */ + if (result instanceof Promise) + throw new KafkaConsumerParserError( + 'Schema parsing supports only synchronous validation' + ); + /* v8 ignore stop */ + if (result.issues) { + throw new KafkaConsumerParserError('Schema validation failed', { + cause: result.issues, + }); + } + return result.value; +}; + +/** + * Deserialize a single record from an MSK event. + * + * @param record - A single record from the MSK event. + * @param config - The schema configuration for deserializing the record's key and value. + */ +const deserializeRecord = async ( + record: KafkaRecord, + config?: SchemaConfig +) => { + const { + key, + value, + headers, + valueSchemaMetadata, + keySchemaMetadata, + ...rest + } = record; + const { key: keyConfig, value: valueConfig } = config || {}; + + const deserializerKey = await getDeserializer(keyConfig?.type); + const deserializerValue = await getDeserializer(valueConfig?.type); + + return { + ...rest, + get key() { + if (key === undefined || key === '') { + return undefined; + } + if (isNull(key)) return null; + const deserializedKey = deserialize({ + value: key, + deserializer: deserializerKey, + config: keyConfig, + schemaMetadata: keySchemaMetadata, + }); + + return keyConfig?.parserSchema + ? parseSchema(deserializedKey, keyConfig.parserSchema) + : deserializedKey; + }, + originalKey: key, + get value() { + const deserializedValue = deserialize({ + value: value, + deserializer: deserializerValue, + config: valueConfig, + schemaMetadata: valueSchemaMetadata, + }); + + return valueConfig?.parserSchema + ? parseSchema(deserializedValue, valueConfig.parserSchema) + : deserializedValue; + }, + originalValue: value, + get headers() { + return deserializeHeaders(headers); + }, + originalHeaders: headers, + valueSchemaMetadata, + keySchemaMetadata, + }; +}; + +/** + * Wrap a handler function to automatically deserialize and validate Kafka records from an MSK event. + * + * The returned function will: + * - Deserialize the key and value of each record using the provided schema config. + * - Validate the deserialized key and value using Zod schemas if provided. + * - Replace the `records` property in the event with an array of deserialized and validated records. + * - Call the original handler with the modified event and original context/arguments. + * + * @example + * ```ts + * import { kafkaConsumer } from '@aws-lambda-powertools/kafka'; + * import { z } from 'zod'; + * + * const keySchema = z.string(); + * const valueSchema = z.object({ + * id: z.number(), + * }); + * + * export const handler = kafkaConsumer, z.infer>(async (event, context) => { + * // event.records is now an array of deserialized and validated records + * for (const record of event.records) { + * console.log(record.key, record.value); + * } + * }, { + * key: { type: 'json', parserSchema: keySchema }, + * value: { type: 'json', parserSchema: valueSchema }, + * }); + * ``` + * + * @typeParam K - Optional type of the deserialized key - defaults to `unknown`. + * @typeParam V - Optional type of the deserialized value - defaults to `unknown`. + * + * @param handler - The original handler function to wrap. It should accept the deserialized event as its first argument. + * @param config - The schema configuration for deserializing and validating record keys and values. + */ +const kafkaConsumer = ( + handler: AsyncHandler>>, + config?: SchemaConfig +): ((event: MSKEvent, context: Context) => Promise) => { + return async (event: MSKEvent, context: Context): Promise => { + assertIsMSKEvent(event); + + const consumerRecords: ConsumerRecord[] = []; + for (const recordsArray of Object.values(event.records)) { + for (const record of recordsArray) { + consumerRecords.push( + (await deserializeRecord( + record, + config + )) as unknown as ConsumerRecord + ); + } + } + + return handler( + { + ...event, + records: consumerRecords, + }, + context + ); + }; +}; + +export { kafkaConsumer }; diff --git a/packages/kafka/src/deserializer/avro.ts b/packages/kafka/src/deserializer/avro.ts new file mode 100644 index 0000000000..19d2888035 --- /dev/null +++ b/packages/kafka/src/deserializer/avro.ts @@ -0,0 +1,22 @@ +import avro from 'avro-js'; +import { KafkaConsumerDeserializationError } from '../errors.js'; + +/** + * Deserialize an Avro message from a base64-encoded string using the provided Avro schema. + * + * @param data - The base64-encoded string representing the Avro binary data. + * @param schema - The Avro schema as a JSON string. + */ +const deserialize = (data: string, schema: string) => { + try { + const type = avro.parse(schema); + const buffer = Buffer.from(data, 'base64'); + return type.fromBuffer(buffer); + } catch (error) { + throw new KafkaConsumerDeserializationError( + `Failed to deserialize Avro message: ${error}, message: ${data}, schema: ${schema}` + ); + } +}; + +export { deserialize }; diff --git a/packages/kafka/src/deserializer/json.ts b/packages/kafka/src/deserializer/json.ts new file mode 100644 index 0000000000..4b716101f5 --- /dev/null +++ b/packages/kafka/src/deserializer/json.ts @@ -0,0 +1,23 @@ +import { deserialize as deserializePrimitive } from './primitive.js'; + +/** + * Deserialize a base64 encoded string into either a JSON object or plain string + * + * @param data - The base64 encoded string to deserialize + * @returns The deserialized data as either a JSON object or string + */ +const deserialize = (data: string) => { + const plainText = deserializePrimitive(data); + try { + // Attempt to parse the decoded data as JSON + // we assume it's a JSON but it can also be a string, we don't know + return JSON.parse(plainText); + } catch (error) { + // If JSON parsing fails, log the error and return the decoded string + // in case we could not parse it we return the base64 decoded value + console.error(`Failed to parse JSON from base64 value: ${data}`, error); + return plainText; + } +}; + +export { deserialize }; diff --git a/packages/kafka/src/deserializer/primitive.ts b/packages/kafka/src/deserializer/primitive.ts new file mode 100644 index 0000000000..27dc286bb6 --- /dev/null +++ b/packages/kafka/src/deserializer/primitive.ts @@ -0,0 +1,16 @@ +import { fromBase64 } from '@aws-lambda-powertools/commons/utils/base64'; + +const decoder = new TextDecoder('utf-8'); + +/** + * Deserialize a base64-encoded primitive value (string). + * + * When customers don't provide a schema configuration, we assume the value is a base64-encoded string. + * + * @param data - The base64-encoded string to deserialize. + */ +const deserialize = (data: string) => { + return decoder.decode(fromBase64(data, 'base64')); +}; + +export { deserialize }; diff --git a/packages/kafka/src/deserializer/protobuf.ts b/packages/kafka/src/deserializer/protobuf.ts new file mode 100644 index 0000000000..46a7b4f8b4 --- /dev/null +++ b/packages/kafka/src/deserializer/protobuf.ts @@ -0,0 +1,94 @@ +import { BufferReader, type Message } from 'protobufjs'; +import { KafkaConsumerDeserializationError } from '../errors.js'; +import type { ProtobufMessage, SchemaMetadata } from '../types/types.js'; + +/** + * Default order of varint types used in Protobuf to attempt deserializing Confluent Schema Registry messages. + */ +const varintOrder: Array<'int32' | 'sint32'> = ['int32', 'sint32']; + +/** + * Deserialize a Protobuf message from a base64-encoded string. + * + * @template T - The type of the deserialized message object. + * + * @param data - The base64-encoded string representing the Protobuf binary data. + * @param messageType - The Protobuf message type definition - see {@link Message | `Message`} from {@link https://www.npmjs.com/package/protobufjs | `protobufjs`}. + */ +const deserialize = ( + data: string, + messageType: ProtobufMessage, + schemaMetadata: SchemaMetadata +): T => { + const buffer = Buffer.from(data, 'base64'); + try { + if (schemaMetadata.schemaId === undefined) { + return messageType.decode(buffer, buffer.length); + } + /** + * If `schemaId` is longer than 10 chars, it's an UUID, otherwise it's a numeric ID. + * + * When this is the case, we know the schema is coming from Glue Schema Registry, + * and the first byte of the buffer is a magic byte that we need to remove before + * decoding the message. + */ + if (schemaMetadata.schemaId.length > 10) { + // remove the first byte from the buffer + const reader = new BufferReader(buffer); + reader.uint32(); + return messageType.decode(reader); + } + } catch (error) { + throw new KafkaConsumerDeserializationError( + `Failed to deserialize Protobuf message: ${error}, message: ${data}, messageType: ${messageType}` + ); + } + + /** + * If schemaId is numeric, inferred from its length, we know it's coming from Confluent Schema Registry, + * so we need to remove the MessageIndex bytes. + * We don't know the type of the index, so we try both `int32` and `sint32`. If both fail, we throw an error. + */ + try { + const newBuffer = clipConfluentSchemaRegistryBuffer(buffer, varintOrder[0]); + return messageType.decode(newBuffer); + } catch (error) { + try { + const newBuffer = clipConfluentSchemaRegistryBuffer( + buffer, + varintOrder[1] + ); + const decoded = messageType.decode(newBuffer); + // swap varint order if the first attempt failed so we can use the correct one for subsequent messages + varintOrder.reverse(); + return decoded; + } catch { + throw new KafkaConsumerDeserializationError( + `Failed to deserialize Protobuf message: ${error}, message: ${data}, messageType: ${messageType}` + ); + } + } +}; + +/** + * Clip the Confluent Schema Registry buffer to remove the index bytes. + * + * @param buffer - The buffer to clip. + * @param intType - The type of the integer to read from the buffer, either 'int32' or 'sint32'. + */ +const clipConfluentSchemaRegistryBuffer = ( + buffer: Buffer, + intType: 'int32' | 'sint32' +) => { + const reader = new BufferReader(buffer); + /** + * Read the first varint byte to get the index count or 0. + * Doing so, also advances the reader position to the next byte after the index count. + */ + const indexCount = intType === 'int32' ? reader.int32() : reader.sint32(); + // Skip the index bytes + reader.skip(indexCount); + return reader; +}; + +export { deserialize }; diff --git a/packages/kafka/src/errors.ts b/packages/kafka/src/errors.ts new file mode 100644 index 0000000000..0686e21517 --- /dev/null +++ b/packages/kafka/src/errors.ts @@ -0,0 +1,47 @@ +/** + * Base error class for Kafka consumer-related errors. + * All Kafka consumer errors should extend this class. + */ +class KafkaConsumerError extends Error { + constructor(message: string, options?: ErrorOptions) { + super(message, options); + this.name = 'KafkaConsumerError'; + } +} + +/** + * Error thrown when deserialization of a Kafka message fails. + */ +class KafkaConsumerDeserializationError extends KafkaConsumerError { + constructor(message: string, options?: ErrorOptions) { + super(message, options); + this.name = 'KafkaConsumerDeserializationError'; + } +} + +/** + * Error thrown when a required Avro schema is missing during Kafka message consumption. + */ +class KafkaConsumerMissingSchemaError extends KafkaConsumerError { + constructor(message: string, options?: ErrorOptions) { + super(message, options); + this.name = 'KafkaConsumerMissingSchemaError'; + } +} + +/** + * Error thrown when parsing a Kafka message fails. + */ +class KafkaConsumerParserError extends KafkaConsumerError { + constructor(message: string, options?: ErrorOptions) { + super(message, options); + this.name = 'KafkaConsumerParserError'; + } +} + +export { + KafkaConsumerError, + KafkaConsumerMissingSchemaError, + KafkaConsumerDeserializationError, + KafkaConsumerParserError, +}; diff --git a/packages/kafka/src/index.ts b/packages/kafka/src/index.ts new file mode 100644 index 0000000000..30205b1aef --- /dev/null +++ b/packages/kafka/src/index.ts @@ -0,0 +1,2 @@ +export { SchemaType } from './constants.js'; +export { kafkaConsumer } from './consumer.js'; diff --git a/packages/kafka/src/types/avro-js.d.ts b/packages/kafka/src/types/avro-js.d.ts new file mode 100644 index 0000000000..ed6d21fcbb --- /dev/null +++ b/packages/kafka/src/types/avro-js.d.ts @@ -0,0 +1,32 @@ +/** + * Minimal TypeScript declaration for the avro-js library, which does not have its own type definitions. + */ +declare module 'avro-js' { + /** + * Interface for the parsed Avro type + */ + interface AvroType { + /** + * Deserialize an Avro message from a binary buffer + * + * @param buffer - Binary buffer containing Avro-encoded data + * @returns The deserialized object + */ + fromBuffer(buffer: Buffer): unknown; + } + + /** + * Parse an Avro schema from a JSON string + * + * @param schema - Avro schema as a JSON string + * @returns A parsed Avro type that can be used to serialize and deserialize data + */ + function parse(schema: string): AvroType; + + // Export the default object with the parse method + const avro: { + parse: typeof parse; + }; + + export default avro; +} diff --git a/packages/kafka/src/types/index.ts b/packages/kafka/src/types/index.ts new file mode 100644 index 0000000000..944b14b4eb --- /dev/null +++ b/packages/kafka/src/types/index.ts @@ -0,0 +1,12 @@ +export type { + ConsumerRecord, + ConsumerRecords, + MSKEvent, + ProtobufMessage, + Record, + RecordHeader, + SchemaType, + SchemaConfig, + SchemaConfigValue, + SchemaMetadata, +} from './types.js'; diff --git a/packages/kafka/src/types/types.ts b/packages/kafka/src/types/types.ts new file mode 100644 index 0000000000..632da35d1d --- /dev/null +++ b/packages/kafka/src/types/types.ts @@ -0,0 +1,274 @@ +import type { StandardSchemaV1 } from '@standard-schema/spec'; +import type { Reader } from 'protobufjs'; +import type { SchemaType as SchemaTypeMap } from '../constants.js'; + +/** + * Union type for supported schema types (JSON, Avro, Protobuf). + */ +type SchemaType = (typeof SchemaTypeMap)[keyof typeof SchemaTypeMap]; + +/** + * Metadata about the schema used for the field. + */ +type SchemaMetadata = { + /** + * The schema type of the value (JSON, AVRO, PROTOBUF) + */ + dataFormat: string; + /** + * The schema identifier + */ + schemaId?: string; +}; + +/** + * Represents a single Kafka consumer record with generic key and value types. + */ +type ConsumerRecord = { + /** + * The deserialized key of the record + */ + key: K; + /** + * The deserialized value of the record + */ + value: V; + /** + * The original (raw, encoded) key as received from Kafka, or `undefined` if not present + */ + originalKey?: string; + /** + * The original (raw, encoded) value as received from Kafka + */ + originalValue: string; + /** + * Optional array of headers as key-value string pairs, or `null/`undefined` if not present + */ + headers?: { [k: string]: string }[] | null; + /** + * Optional array of original record headers + */ + originalHeaders?: RecordHeader[] | null; + /** + * The topic from which the record was consumed + */ + topic: string; + /** + * The partition from which the record was consumed + */ + partition: number; + /** + * The offset of the record within the partition + */ + offset: number; + /** + * The timestamp of the record + */ + timestamp: number; + /** + * The type of timestamp (CREATE_TIME or LOG_APPEND_TIME) + */ + timestampType: 'CREATE_TIME' | 'LOG_APPEND_TIME'; + /** + * Metadata about the value schema + */ + valueSchemaMetadata: SchemaMetadata; + /** + * Metadata about the key schema + */ + keySchemaMetadata: SchemaMetadata; +}; + +/** + * Represents a collection of Kafka consumer records, along with MSK event metadata. + */ +type ConsumerRecords = { + /** + * Array of consumer records + */ + records: Array>; +} & Omit; + +/** + * Union type for supported schema configurations (JSON, Avro, Protobuf). + */ +type SchemaConfigValue = JsonConfig | AvroConfig | ProtobufConfig; + +/** + * Configuration for JSON schema validation. + */ +type JsonConfig = { + /** + * Indicates the schema type is JSON + */ + type: typeof SchemaTypeMap.JSON; + /** + * Optional {@link https://github.com/standard-schema/standard-schema | Standard Schema} for runtime validation + */ + parserSchema?: StandardSchemaV1; +}; + +/** + * Configuration for Avro schema validation. + */ +type AvroConfig = { + /** + * Indicates the schema type is Avro + */ + type: typeof SchemaTypeMap.AVRO; + /** + * Avro schema definition as a string + */ + schema: string; + /** + * Optional {@link https://github.com/standard-schema/standard-schema | Standard Schema} for runtime validation + */ + parserSchema?: StandardSchemaV1; +}; + +/** + * Configuration for Protobuf schema validation. + */ +type ProtobufConfig = { + /** + * Indicates the schema type is Protobuf + */ + type: typeof SchemaTypeMap.PROTOBUF; + /** + * Protobuf message type for decoding + */ + schema: ProtobufMessage; + /** + * Optional {@link https://github.com/standard-schema/standard-schema | Standard Schema} for runtime validation + */ + parserSchema?: StandardSchemaV1; +}; + +/** + * Configuration for key and value schema validation. + */ +type SchemaConfig = { + /** + * Schema type for the value. + * If not provided, the value will not be validated. + */ + value: SchemaConfigValue; + /** + * Schema type for the key. + * If not provided, the key will not be validated. + */ + key?: SchemaConfigValue; +}; + +/** + * Represents a Kafka record header as a mapping of header key to byte array. + */ +type RecordHeader = { + /** + * Header key mapped to its value as an array of bytes + */ + [headerKey: string]: number[]; +}; + +/** + * Represents a single Kafka record as received from MSK. + */ +type Record = { + /** + * Kafka topic name + */ + topic: string; + /** + * Partition number within the topic + */ + partition: number; + /** + * Offset of the record within the partition + */ + offset: number; + /** + * Timestamp of the record + */ + timestamp: number; + /** + * Type of timestamp (creation or log append time) + */ + timestampType: 'CREATE_TIME' | 'LOG_APPEND_TIME'; + /** + * Base64-encoded key of the record + */ + key?: string | null; + /** + * Base64-encoded value of the record + */ + value: string; + /** + * Array of record headers + */ + headers: RecordHeader[] | null; + /** + * Metadata about the value schema + */ + valueSchemaMetadata: SchemaMetadata; + /** + * Metadata about the key schema + */ + keySchemaMetadata: SchemaMetadata; +}; + +/** + * AWS Lambda event structure for MSK (Managed Streaming for Kafka). + * @see {@link https://docs.aws.amazon.com/lambda/latest/dg/with-msk.html | AWS Lambda with MSK} + */ +type MSKEvent = { + /** + * Event source identifier (always 'aws:kafka') + */ + eventSource: 'aws:kafka'; + /** + * ARN of the Kafka event source + */ + eventSourceArn: string; + /** + * Comma-separated list of Kafka bootstrap servers + */ + bootstrapServers: string; + /** + * Mapping of topic names to arrays of records + */ + records: { + [topic: string]: Record[]; + }; +}; + +type ProtobufMessage = { + decode(reader: Reader | Uint8Array, length?: number): T; +}; + +type Deserializer = ( + input: string, + schema?: unknown, + schemaMetadata?: SchemaMetadata +) => unknown; + +type DeserializeOptions = { + value: string; + deserializer: Deserializer; + config?: SchemaConfigValue; + schemaMetadata: SchemaMetadata; +}; + +export type { + ConsumerRecord, + ConsumerRecords, + Deserializer, + MSKEvent, + ProtobufMessage, + Record, + RecordHeader, + SchemaType, + SchemaConfig, + SchemaConfigValue, + SchemaMetadata, + DeserializeOptions, +}; diff --git a/packages/kafka/tests/events/avro.json b/packages/kafka/tests/events/avro.json new file mode 100644 index 0000000000..d495060d7c --- /dev/null +++ b/packages/kafka/tests/events/avro.json @@ -0,0 +1,51 @@ +{ + "eventSource": "aws:kafka", + "eventSourceArn": "arn:aws:kafka:us-east-1:0123456789019:cluster/SalesCluster/abcd1234-abcd-cafe-abab-9876543210ab-4", + "bootstrapServers": "b-2.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092,b-1.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092", + "records": { + "mytopic-0": [ + { + "topic": "mytopic", + "partition": 0, + "offset": 15, + "timestamp": 1545084650987, + "timestampType": "CREATE_TIME", + "key": "NDI=", + "value": "0g8MTGFwdG9wUrgehes/j0A=", + "headers": [ + { + "headerKey": [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101] + } + ] + }, + { + "topic": "mytopic", + "partition": 0, + "offset": 16, + "timestamp": 1545084650988, + "timestampType": "CREATE_TIME", + "key": "NDI=", + "value": "1A8UU21hcnRwaG9uZVK4HoXrv4JA", + "headers": [ + { + "headerKey": [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101] + } + ] + }, + { + "topic": "mytopic", + "partition": 0, + "offset": 17, + "timestamp": 1545084650989, + "timestampType": "CREATE_TIME", + "key": null, + "value": "1g8USGVhZHBob25lc0jhehSuv2JA", + "headers": [ + { + "headerKey": [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/packages/kafka/tests/events/default.json b/packages/kafka/tests/events/default.json new file mode 100644 index 0000000000..0f9aa2a80e --- /dev/null +++ b/packages/kafka/tests/events/default.json @@ -0,0 +1,50 @@ +{ + "eventSource": "aws:kafka", + "eventSourceArn": "arn:aws:kafka:us-east-1:0123456789019:cluster/SalesCluster/abcd1234-abcd-cafe-abab-9876543210ab-4", + "bootstrapServers": "b-2.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092,b-1.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092", + "records": { + "mytopic-0": [ + { + "topic": "mytopic", + "partition": 0, + "offset": 15, + "timestamp": 1545084650987, + "timestampType": "CREATE_TIME", + "key": "cmVjb3JkS2V5", + "value": "ewogICJpZCI6IDEyMzQ1LAogICJuYW1lIjogInByb2R1Y3Q1IiwKICAicHJpY2UiOiA0NQp9", + "headers": [ + { + "headerKey": [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101] + } + ] + }, + { + "topic": "mytopic", + "partition": 0, + "offset": 16, + "timestamp": 1545084650988, + "timestampType": "CREATE_TIME", + "value": "ewogICJpZCI6IDEyMzQ1LAogICJuYW1lIjogInByb2R1Y3Q1IiwKICAicHJpY2UiOiA0NQp9", + "headers": [ + { + "headerKey": [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101] + } + ] + }, + { + "topic": "mytopic", + "partition": 0, + "offset": 17, + "timestamp": 1545084650989, + "timestampType": "CREATE_TIME", + "key": null, + "value": "ewogICJpZCI6IDEyMzQ1LAogICJuYW1lIjogInByb2R1Y3Q1IiwKICAicHJpY2UiOiA0NQp9", + "headers": [ + { + "headerKey": [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101] + } + ] + } + ] + } +} diff --git a/packages/kafka/tests/events/protobuf-complex.confluent.json b/packages/kafka/tests/events/protobuf-complex.confluent.json new file mode 100644 index 0000000000..47f5e4c8de --- /dev/null +++ b/packages/kafka/tests/events/protobuf-complex.confluent.json @@ -0,0 +1,65 @@ +{ + "bootstrapServers": "boot-u18.abcdefg.kdhspn.c25.kafka.us-east-1.amazonaws.com:9098,boot-3xz.abcdefg.kdhspn.c25.kafka.us-east-1.amazonaws.com:9098,boot-vvi.abcdefg.kdhspn.c25.kafka.us-east-1.amazonaws.com:9098", + "eventSource": "aws:kafka", + "eventSourceArn": "arn:aws:kafka:us-east-1:123456789012:cluster/abcdefg/717bd2d1-e34b-4a86-9ae8-f7a16158c0f6-25", + "records": { + "confluent_proto-0": [ + { + "headers": [], + "key": "YThlNDA5NzEtMTU1Mi00MjBkLWE3YzktYjg5ODIzMjU3MDJk", + "offset": 4209910, + "partition": 0, + "timestamp": 1750358101849, + "timestampType": "CREATE_TIME", + "topic": "confluent_proto", + "value": "AgIKJGE4ZTQwOTcxLTE1NTItNDIwZC1hN2M5LWI4OTgyMzI1NzAyZBIDQm9iGg9ib2JAZXhhbXBsZS5jb20gHCgBMgoyMDI0LTAyLTAyOgR0YWcxOgR0YWcyQQAAAAAAAFZASg4KBXRoZW1lEgVsaWdodFIZCgcxMjMgQXZlEgdTZWF0dGxlGgU5ODEwMQ==", + "valueSchemaMetadata": { + "dataFormat": "PROTOBUF", + "schemaId": "1" + } + }, + { + "headers": [], + "key": "NGRjZmM2MWItMzk5My00OWMzLWEwNGYtOGE2YzdhYWY3ODgx", + "offset": 4209911, + "partition": 0, + "timestamp": 1750358102849, + "timestampType": "CREATE_TIME", + "topic": "confluent_proto", + "value": "AgIKJDRkY2ZjNjFiLTM5OTMtNDljMy1hMDRmLThhNmM3YWFmNzg4MRIDQm9iGg9ib2JAZXhhbXBsZS5jb20gHCgBMgoyMDI0LTAyLTAyOgR0YWcxOgR0YWcyQQAAAAAAAFZASg4KBXRoZW1lEgVsaWdodFIZCgcxMjMgQXZlEgdTZWF0dGxlGgU5ODEwMQ==", + "valueSchemaMetadata": { + "dataFormat": "PROTOBUF", + "schemaId": "1" + } + }, + { + "headers": [], + "key": "MmE4NjE2MjgtMDgwMC00Yjc2LWJkM2YtNmVjYmE3Y2QyODZj", + "offset": 4209912, + "partition": 0, + "timestamp": 1750358103849, + "timestampType": "CREATE_TIME", + "topic": "confluent_proto", + "value": "AgIKJDJhODYxNjI4LTA4MDAtNGI3Ni1iZDNmLTZlY2JhN2NkMjg2YxIDQm9iGg9ib2JAZXhhbXBsZS5jb20gHCgBMgoyMDI0LTAyLTAyOgR0YWcxOgR0YWcyQQAAAAAAAFZASg4KBXRoZW1lEgVsaWdodFIZCgcxMjMgQXZlEgdTZWF0dGxlGgU5ODEwMQ==", + "valueSchemaMetadata": { + "dataFormat": "PROTOBUF", + "schemaId": "1" + } + }, + { + "headers": [], + "key": "NzEzMjBjNzMtZWM1Ny00NDZlLWJkNWItOTI1MmQ2OTQzMTgy", + "offset": 4209913, + "partition": 0, + "timestamp": 1750358104849, + "timestampType": "CREATE_TIME", + "topic": "confluent_proto", + "value": "AgIKJDcxMzIwYzczLWVjNTctNDQ2ZS1iZDViLTkyNTJkNjk0MzE4MhIDQm9iGg9ib2JAZXhhbXBsZS5jb20gHCgBMgoyMDI0LTAyLTAyOgR0YWcxOgR0YWcyQQAAAAAAAFZASg4KBXRoZW1lEgVsaWdodFIZCgcxMjMgQXZlEgdTZWF0dGxlGgU5ODEwMQ==", + "valueSchemaMetadata": { + "dataFormat": "PROTOBUF", + "schemaId": "1" + } + } + ] + } +} \ No newline at end of file diff --git a/packages/kafka/tests/events/protobuf-complex.glue.json b/packages/kafka/tests/events/protobuf-complex.glue.json new file mode 100644 index 0000000000..f051e5f652 --- /dev/null +++ b/packages/kafka/tests/events/protobuf-complex.glue.json @@ -0,0 +1,39 @@ +{ + "bootstrapServers": "boot-u18.abcdefg.kdhspn.c25.kafka.us-east-1.amazonaws.com:9098,boot-3xz.abcdefg.kdhspn.c25.kafka.us-east-1.amazonaws.com:9098,boot-vvi.abcdefg.kdhspn.c25.kafka.us-east-1.amazonaws.com:9098", + "eventSource": "aws:kafka", + "eventSourceArn": "arn:aws:kafka:us-east-1:123456789012:cluster/abcdefg/717bd2d1-e34b-4a86-9ae8-f7a16158c0f6-25", + "records": { + "gsr_proto-0": [ + { + "topic": "gsr_proto", + "partition": 0, + "offset": 18, + "timestamp": 1545084650990, + "timestampType": "CREATE_TIME", + "key": "NDI=", + "value": "AQoDMTIzEgRUZXN0Ggx0ZXN0QGdteC5jb20gCjIKMjAyNS0wNi0yMDoEdGFnMToEdGFnMkoOCgV0aGVtZRIFbGlnaHRSGgoKTXl0aGVucXVhaRIGWnVyaWNoGgQ4MDAy", + "headers": [ + { + "headerKey": [ + 104, + 101, + 97, + 100, + 101, + 114, + 86, + 97, + 108, + 117, + 101 + ] + } + ], + "valueSchemaMetadata": { + "schemaId": "12345678-1234-1234-1234-123456789012", + "dataFormat": "PROTOBUF" + } + } + ] + } +} \ No newline at end of file diff --git a/packages/kafka/tests/events/protobuf.json b/packages/kafka/tests/events/protobuf.json new file mode 100644 index 0000000000..58ad47f5e0 --- /dev/null +++ b/packages/kafka/tests/events/protobuf.json @@ -0,0 +1,62 @@ +{ + "eventSource": "aws:kafka", + "eventSourceArn": "arn:aws:kafka:us-east-1:0123456789019:cluster/SalesCluster/abcd1234-abcd-cafe-abab-9876543210ab-4", + "bootstrapServers": "b-2.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092,b-1.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092", + "records": { + "mytopic-0": [ + { + "topic": "mytopic", + "partition": 0, + "offset": 15, + "timestamp": 1545084650987, + "timestampType": "CREATE_TIME", + "key": "NDI=", + "value": "COkHEgZMYXB0b3AZUrgehes/j0A=", + "headers": [ + { + "headerKey": [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101] + } + ], + "valueSchemaMetadata": { + "dataFormat": "PROTOBUF" + } + }, + { + "topic": "mytopic", + "partition": 0, + "offset": 16, + "timestamp": 1545084650988, + "timestampType": "CREATE_TIME", + "key": "NDI=", + "value": "COoHEgpTbWFydHBob25lGVK4HoXrv4JA", + "headers": [ + { + "headerKey": [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101] + } + ], + "valueSchemaMetadata": { + "dataFormat": "PROTOBUF", + "schemaId": "7d55d475-2244-4485-8341-f74468c1e058" + } + }, + { + "topic": "mytopic", + "partition": 0, + "offset": 17, + "timestamp": 1545084650989, + "timestampType": "CREATE_TIME", + "key": null, + "value": "COsHEgpIZWFkcGhvbmVzGUjhehSuv2JA", + "headers": [ + { + "headerKey": [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101] + } + ], + "valueSchemaMetadata": { + "dataFormat": "PROTOBUF", + "schemaId": "2" + } + } + ] + } +} \ No newline at end of file diff --git a/packages/kafka/tests/helpers/loadEvent.ts b/packages/kafka/tests/helpers/loadEvent.ts new file mode 100644 index 0000000000..9f3336f68f --- /dev/null +++ b/packages/kafka/tests/helpers/loadEvent.ts @@ -0,0 +1,16 @@ +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; +import type { MSKEvent } from '../../src/types/types.js'; + +/** + * Load a sample MSK event from a JSON file. + * + * @param fileName - The name of the file to load the event from. + */ +const loadEvent = (fileName: string) => { + return JSON.parse( + readFileSync(join(__dirname, '..', 'events', fileName), 'utf-8') + ) as unknown as MSKEvent; +}; + +export { loadEvent }; diff --git a/packages/kafka/tests/protos/complex.generated.d.ts b/packages/kafka/tests/protos/complex.generated.d.ts new file mode 100644 index 0000000000..99d6373075 --- /dev/null +++ b/packages/kafka/tests/protos/complex.generated.d.ts @@ -0,0 +1,267 @@ +import * as $protobuf from "protobufjs"; +import Long = require("long"); +/** Namespace com. */ +export namespace com { + + /** Namespace example. */ + namespace example { + + /** Namespace protobuf. */ + namespace protobuf { + + /** Properties of an Address. */ + interface IAddress { + + /** Address street */ + street?: (string|null); + + /** Address city */ + city?: (string|null); + + /** Address zip */ + zip?: (string|null); + } + + /** Represents an Address. */ + class Address implements IAddress { + + /** + * Constructs a new Address. + * @param [properties] Properties to set + */ + constructor(properties?: com.example.protobuf.IAddress); + + /** Address street. */ + public street: string; + + /** Address city. */ + public city: string; + + /** Address zip. */ + public zip: string; + + /** + * Creates a new Address instance using the specified properties. + * @param [properties] Properties to set + * @returns Address instance + */ + public static create(properties?: com.example.protobuf.IAddress): com.example.protobuf.Address; + + /** + * Encodes the specified Address message. Does not implicitly {@link com.example.protobuf.Address.verify|verify} messages. + * @param message Address message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: com.example.protobuf.IAddress, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Address message, length delimited. Does not implicitly {@link com.example.protobuf.Address.verify|verify} messages. + * @param message Address message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: com.example.protobuf.IAddress, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an Address message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Address + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): com.example.protobuf.Address; + + /** + * Decodes an Address message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Address + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): com.example.protobuf.Address; + + /** + * Verifies an Address message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an Address message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Address + */ + public static fromObject(object: { [k: string]: any }): com.example.protobuf.Address; + + /** + * Creates a plain object from an Address message. Also converts values to other types if specified. + * @param message Address + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: com.example.protobuf.Address, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Address to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for Address + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + + /** Properties of a UserProfile. */ + interface IUserProfile { + + /** UserProfile userId */ + userId?: (string|null); + + /** UserProfile name */ + name?: (string|null); + + /** UserProfile email */ + email?: (string|null); + + /** UserProfile age */ + age?: (number|null); + + /** UserProfile isActive */ + isActive?: (boolean|null); + + /** UserProfile signupDate */ + signupDate?: (string|null); + + /** UserProfile tags */ + tags?: (string[]|null); + + /** UserProfile preferences */ + preferences?: ({ [k: string]: string }|null); + + /** UserProfile address */ + address?: (com.example.protobuf.IAddress|null); + } + + /** Represents a UserProfile. */ + class UserProfile implements IUserProfile { + + /** + * Constructs a new UserProfile. + * @param [properties] Properties to set + */ + constructor(properties?: com.example.protobuf.IUserProfile); + + /** UserProfile userId. */ + public userId: string; + + /** UserProfile name. */ + public name: string; + + /** UserProfile email. */ + public email: string; + + /** UserProfile age. */ + public age: number; + + /** UserProfile isActive. */ + public isActive: boolean; + + /** UserProfile signupDate. */ + public signupDate: string; + + /** UserProfile tags. */ + public tags: string[]; + + /** UserProfile preferences. */ + public preferences: { [k: string]: string }; + + /** UserProfile address. */ + public address?: (com.example.protobuf.IAddress|null); + + /** + * Creates a new UserProfile instance using the specified properties. + * @param [properties] Properties to set + * @returns UserProfile instance + */ + public static create(properties?: com.example.protobuf.IUserProfile): com.example.protobuf.UserProfile; + + /** + * Encodes the specified UserProfile message. Does not implicitly {@link com.example.protobuf.UserProfile.verify|verify} messages. + * @param message UserProfile message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: com.example.protobuf.IUserProfile, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified UserProfile message, length delimited. Does not implicitly {@link com.example.protobuf.UserProfile.verify|verify} messages. + * @param message UserProfile message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: com.example.protobuf.IUserProfile, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a UserProfile message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns UserProfile + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): com.example.protobuf.UserProfile; + + /** + * Decodes a UserProfile message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns UserProfile + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): com.example.protobuf.UserProfile; + + /** + * Verifies a UserProfile message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a UserProfile message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns UserProfile + */ + public static fromObject(object: { [k: string]: any }): com.example.protobuf.UserProfile; + + /** + * Creates a plain object from a UserProfile message. Also converts values to other types if specified. + * @param message UserProfile + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: com.example.protobuf.UserProfile, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this UserProfile to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for UserProfile + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + } + } +} diff --git a/packages/kafka/tests/protos/complex.generated.js b/packages/kafka/tests/protos/complex.generated.js new file mode 100644 index 0000000000..e9a57dadd4 --- /dev/null +++ b/packages/kafka/tests/protos/complex.generated.js @@ -0,0 +1,746 @@ +/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/ +import * as $protobuf from "protobufjs/minimal"; + +// Common aliases +const $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util; + +// Exported root namespace +const $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {}); + +export const com = $root.com = (() => { + + /** + * Namespace com. + * @exports com + * @namespace + */ + const com = {}; + + com.example = (function() { + + /** + * Namespace example. + * @memberof com + * @namespace + */ + const example = {}; + + example.protobuf = (function() { + + /** + * Namespace protobuf. + * @memberof com.example + * @namespace + */ + const protobuf = {}; + + protobuf.Address = (function() { + + /** + * Properties of an Address. + * @memberof com.example.protobuf + * @interface IAddress + * @property {string|null} [street] Address street + * @property {string|null} [city] Address city + * @property {string|null} [zip] Address zip + */ + + /** + * Constructs a new Address. + * @memberof com.example.protobuf + * @classdesc Represents an Address. + * @implements IAddress + * @constructor + * @param {com.example.protobuf.IAddress=} [properties] Properties to set + */ + function Address(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Address street. + * @member {string} street + * @memberof com.example.protobuf.Address + * @instance + */ + Address.prototype.street = ""; + + /** + * Address city. + * @member {string} city + * @memberof com.example.protobuf.Address + * @instance + */ + Address.prototype.city = ""; + + /** + * Address zip. + * @member {string} zip + * @memberof com.example.protobuf.Address + * @instance + */ + Address.prototype.zip = ""; + + /** + * Creates a new Address instance using the specified properties. + * @function create + * @memberof com.example.protobuf.Address + * @static + * @param {com.example.protobuf.IAddress=} [properties] Properties to set + * @returns {com.example.protobuf.Address} Address instance + */ + Address.create = function create(properties) { + return new Address(properties); + }; + + /** + * Encodes the specified Address message. Does not implicitly {@link com.example.protobuf.Address.verify|verify} messages. + * @function encode + * @memberof com.example.protobuf.Address + * @static + * @param {com.example.protobuf.IAddress} message Address message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Address.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.street != null && Object.hasOwnProperty.call(message, "street")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.street); + if (message.city != null && Object.hasOwnProperty.call(message, "city")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.city); + if (message.zip != null && Object.hasOwnProperty.call(message, "zip")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.zip); + return writer; + }; + + /** + * Encodes the specified Address message, length delimited. Does not implicitly {@link com.example.protobuf.Address.verify|verify} messages. + * @function encodeDelimited + * @memberof com.example.protobuf.Address + * @static + * @param {com.example.protobuf.IAddress} message Address message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Address.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an Address message from the specified reader or buffer. + * @function decode + * @memberof com.example.protobuf.Address + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {com.example.protobuf.Address} Address + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Address.decode = function decode(reader, length, error) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.com.example.protobuf.Address(); + while (reader.pos < end) { + let tag = reader.uint32(); + if (tag === error) + break; + switch (tag >>> 3) { + case 1: { + message.street = reader.string(); + break; + } + case 2: { + message.city = reader.string(); + break; + } + case 3: { + message.zip = reader.string(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an Address message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof com.example.protobuf.Address + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {com.example.protobuf.Address} Address + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Address.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an Address message. + * @function verify + * @memberof com.example.protobuf.Address + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Address.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.street != null && message.hasOwnProperty("street")) + if (!$util.isString(message.street)) + return "street: string expected"; + if (message.city != null && message.hasOwnProperty("city")) + if (!$util.isString(message.city)) + return "city: string expected"; + if (message.zip != null && message.hasOwnProperty("zip")) + if (!$util.isString(message.zip)) + return "zip: string expected"; + return null; + }; + + /** + * Creates an Address message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof com.example.protobuf.Address + * @static + * @param {Object.} object Plain object + * @returns {com.example.protobuf.Address} Address + */ + Address.fromObject = function fromObject(object) { + if (object instanceof $root.com.example.protobuf.Address) + return object; + let message = new $root.com.example.protobuf.Address(); + if (object.street != null) + message.street = String(object.street); + if (object.city != null) + message.city = String(object.city); + if (object.zip != null) + message.zip = String(object.zip); + return message; + }; + + /** + * Creates a plain object from an Address message. Also converts values to other types if specified. + * @function toObject + * @memberof com.example.protobuf.Address + * @static + * @param {com.example.protobuf.Address} message Address + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Address.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.defaults) { + object.street = ""; + object.city = ""; + object.zip = ""; + } + if (message.street != null && message.hasOwnProperty("street")) + object.street = message.street; + if (message.city != null && message.hasOwnProperty("city")) + object.city = message.city; + if (message.zip != null && message.hasOwnProperty("zip")) + object.zip = message.zip; + return object; + }; + + /** + * Converts this Address to JSON. + * @function toJSON + * @memberof com.example.protobuf.Address + * @instance + * @returns {Object.} JSON object + */ + Address.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for Address + * @function getTypeUrl + * @memberof com.example.protobuf.Address + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + Address.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/com.example.protobuf.Address"; + }; + + return Address; + })(); + + protobuf.UserProfile = (function() { + + /** + * Properties of a UserProfile. + * @memberof com.example.protobuf + * @interface IUserProfile + * @property {string|null} [userId] UserProfile userId + * @property {string|null} [name] UserProfile name + * @property {string|null} [email] UserProfile email + * @property {number|null} [age] UserProfile age + * @property {boolean|null} [isActive] UserProfile isActive + * @property {string|null} [signupDate] UserProfile signupDate + * @property {Array.|null} [tags] UserProfile tags + * @property {Object.|null} [preferences] UserProfile preferences + * @property {com.example.protobuf.IAddress|null} [address] UserProfile address + */ + + /** + * Constructs a new UserProfile. + * @memberof com.example.protobuf + * @classdesc Represents a UserProfile. + * @implements IUserProfile + * @constructor + * @param {com.example.protobuf.IUserProfile=} [properties] Properties to set + */ + function UserProfile(properties) { + this.tags = []; + this.preferences = {}; + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * UserProfile userId. + * @member {string} userId + * @memberof com.example.protobuf.UserProfile + * @instance + */ + UserProfile.prototype.userId = ""; + + /** + * UserProfile name. + * @member {string} name + * @memberof com.example.protobuf.UserProfile + * @instance + */ + UserProfile.prototype.name = ""; + + /** + * UserProfile email. + * @member {string} email + * @memberof com.example.protobuf.UserProfile + * @instance + */ + UserProfile.prototype.email = ""; + + /** + * UserProfile age. + * @member {number} age + * @memberof com.example.protobuf.UserProfile + * @instance + */ + UserProfile.prototype.age = 0; + + /** + * UserProfile isActive. + * @member {boolean} isActive + * @memberof com.example.protobuf.UserProfile + * @instance + */ + UserProfile.prototype.isActive = false; + + /** + * UserProfile signupDate. + * @member {string} signupDate + * @memberof com.example.protobuf.UserProfile + * @instance + */ + UserProfile.prototype.signupDate = ""; + + /** + * UserProfile tags. + * @member {Array.} tags + * @memberof com.example.protobuf.UserProfile + * @instance + */ + UserProfile.prototype.tags = $util.emptyArray; + + /** + * UserProfile preferences. + * @member {Object.} preferences + * @memberof com.example.protobuf.UserProfile + * @instance + */ + UserProfile.prototype.preferences = $util.emptyObject; + + /** + * UserProfile address. + * @member {com.example.protobuf.IAddress|null|undefined} address + * @memberof com.example.protobuf.UserProfile + * @instance + */ + UserProfile.prototype.address = null; + + /** + * Creates a new UserProfile instance using the specified properties. + * @function create + * @memberof com.example.protobuf.UserProfile + * @static + * @param {com.example.protobuf.IUserProfile=} [properties] Properties to set + * @returns {com.example.protobuf.UserProfile} UserProfile instance + */ + UserProfile.create = function create(properties) { + return new UserProfile(properties); + }; + + /** + * Encodes the specified UserProfile message. Does not implicitly {@link com.example.protobuf.UserProfile.verify|verify} messages. + * @function encode + * @memberof com.example.protobuf.UserProfile + * @static + * @param {com.example.protobuf.IUserProfile} message UserProfile message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + UserProfile.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.userId != null && Object.hasOwnProperty.call(message, "userId")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.userId); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.name); + if (message.email != null && Object.hasOwnProperty.call(message, "email")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.email); + if (message.age != null && Object.hasOwnProperty.call(message, "age")) + writer.uint32(/* id 4, wireType 0 =*/32).int32(message.age); + if (message.isActive != null && Object.hasOwnProperty.call(message, "isActive")) + writer.uint32(/* id 5, wireType 0 =*/40).bool(message.isActive); + if (message.signupDate != null && Object.hasOwnProperty.call(message, "signupDate")) + writer.uint32(/* id 6, wireType 2 =*/50).string(message.signupDate); + if (message.tags != null && message.tags.length) + for (let i = 0; i < message.tags.length; ++i) + writer.uint32(/* id 7, wireType 2 =*/58).string(message.tags[i]); + if (message.preferences != null && Object.hasOwnProperty.call(message, "preferences")) + for (let keys = Object.keys(message.preferences), i = 0; i < keys.length; ++i) + writer.uint32(/* id 9, wireType 2 =*/74).fork().uint32(/* id 1, wireType 2 =*/10).string(keys[i]).uint32(/* id 2, wireType 2 =*/18).string(message.preferences[keys[i]]).ldelim(); + if (message.address != null && Object.hasOwnProperty.call(message, "address")) + $root.com.example.protobuf.Address.encode(message.address, writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified UserProfile message, length delimited. Does not implicitly {@link com.example.protobuf.UserProfile.verify|verify} messages. + * @function encodeDelimited + * @memberof com.example.protobuf.UserProfile + * @static + * @param {com.example.protobuf.IUserProfile} message UserProfile message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + UserProfile.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a UserProfile message from the specified reader or buffer. + * @function decode + * @memberof com.example.protobuf.UserProfile + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {com.example.protobuf.UserProfile} UserProfile + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + UserProfile.decode = function decode(reader, length, error) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.com.example.protobuf.UserProfile(), key, value; + while (reader.pos < end) { + let tag = reader.uint32(); + if (tag === error) + break; + switch (tag >>> 3) { + case 1: { + message.userId = reader.string(); + break; + } + case 2: { + message.name = reader.string(); + break; + } + case 3: { + message.email = reader.string(); + break; + } + case 4: { + message.age = reader.int32(); + break; + } + case 5: { + message.isActive = reader.bool(); + break; + } + case 6: { + message.signupDate = reader.string(); + break; + } + case 7: { + if (!(message.tags && message.tags.length)) + message.tags = []; + message.tags.push(reader.string()); + break; + } + case 9: { + if (message.preferences === $util.emptyObject) + message.preferences = {}; + let end2 = reader.uint32() + reader.pos; + key = ""; + value = ""; + while (reader.pos < end2) { + let tag2 = reader.uint32(); + switch (tag2 >>> 3) { + case 1: + key = reader.string(); + break; + case 2: + value = reader.string(); + break; + default: + reader.skipType(tag2 & 7); + break; + } + } + message.preferences[key] = value; + break; + } + case 10: { + message.address = $root.com.example.protobuf.Address.decode(reader, reader.uint32()); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a UserProfile message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof com.example.protobuf.UserProfile + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {com.example.protobuf.UserProfile} UserProfile + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + UserProfile.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a UserProfile message. + * @function verify + * @memberof com.example.protobuf.UserProfile + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + UserProfile.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.userId != null && message.hasOwnProperty("userId")) + if (!$util.isString(message.userId)) + return "userId: string expected"; + if (message.name != null && message.hasOwnProperty("name")) + if (!$util.isString(message.name)) + return "name: string expected"; + if (message.email != null && message.hasOwnProperty("email")) + if (!$util.isString(message.email)) + return "email: string expected"; + if (message.age != null && message.hasOwnProperty("age")) + if (!$util.isInteger(message.age)) + return "age: integer expected"; + if (message.isActive != null && message.hasOwnProperty("isActive")) + if (typeof message.isActive !== "boolean") + return "isActive: boolean expected"; + if (message.signupDate != null && message.hasOwnProperty("signupDate")) + if (!$util.isString(message.signupDate)) + return "signupDate: string expected"; + if (message.tags != null && message.hasOwnProperty("tags")) { + if (!Array.isArray(message.tags)) + return "tags: array expected"; + for (let i = 0; i < message.tags.length; ++i) + if (!$util.isString(message.tags[i])) + return "tags: string[] expected"; + } + if (message.preferences != null && message.hasOwnProperty("preferences")) { + if (!$util.isObject(message.preferences)) + return "preferences: object expected"; + let key = Object.keys(message.preferences); + for (let i = 0; i < key.length; ++i) + if (!$util.isString(message.preferences[key[i]])) + return "preferences: string{k:string} expected"; + } + if (message.address != null && message.hasOwnProperty("address")) { + let error = $root.com.example.protobuf.Address.verify(message.address); + if (error) + return "address." + error; + } + return null; + }; + + /** + * Creates a UserProfile message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof com.example.protobuf.UserProfile + * @static + * @param {Object.} object Plain object + * @returns {com.example.protobuf.UserProfile} UserProfile + */ + UserProfile.fromObject = function fromObject(object) { + if (object instanceof $root.com.example.protobuf.UserProfile) + return object; + let message = new $root.com.example.protobuf.UserProfile(); + if (object.userId != null) + message.userId = String(object.userId); + if (object.name != null) + message.name = String(object.name); + if (object.email != null) + message.email = String(object.email); + if (object.age != null) + message.age = object.age | 0; + if (object.isActive != null) + message.isActive = Boolean(object.isActive); + if (object.signupDate != null) + message.signupDate = String(object.signupDate); + if (object.tags) { + if (!Array.isArray(object.tags)) + throw TypeError(".com.example.protobuf.UserProfile.tags: array expected"); + message.tags = []; + for (let i = 0; i < object.tags.length; ++i) + message.tags[i] = String(object.tags[i]); + } + if (object.preferences) { + if (typeof object.preferences !== "object") + throw TypeError(".com.example.protobuf.UserProfile.preferences: object expected"); + message.preferences = {}; + for (let keys = Object.keys(object.preferences), i = 0; i < keys.length; ++i) + message.preferences[keys[i]] = String(object.preferences[keys[i]]); + } + if (object.address != null) { + if (typeof object.address !== "object") + throw TypeError(".com.example.protobuf.UserProfile.address: object expected"); + message.address = $root.com.example.protobuf.Address.fromObject(object.address); + } + return message; + }; + + /** + * Creates a plain object from a UserProfile message. Also converts values to other types if specified. + * @function toObject + * @memberof com.example.protobuf.UserProfile + * @static + * @param {com.example.protobuf.UserProfile} message UserProfile + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + UserProfile.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.arrays || options.defaults) + object.tags = []; + if (options.objects || options.defaults) + object.preferences = {}; + if (options.defaults) { + object.userId = ""; + object.name = ""; + object.email = ""; + object.age = 0; + object.isActive = false; + object.signupDate = ""; + object.address = null; + } + if (message.userId != null && message.hasOwnProperty("userId")) + object.userId = message.userId; + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + if (message.email != null && message.hasOwnProperty("email")) + object.email = message.email; + if (message.age != null && message.hasOwnProperty("age")) + object.age = message.age; + if (message.isActive != null && message.hasOwnProperty("isActive")) + object.isActive = message.isActive; + if (message.signupDate != null && message.hasOwnProperty("signupDate")) + object.signupDate = message.signupDate; + if (message.tags && message.tags.length) { + object.tags = []; + for (let j = 0; j < message.tags.length; ++j) + object.tags[j] = message.tags[j]; + } + let keys2; + if (message.preferences && (keys2 = Object.keys(message.preferences)).length) { + object.preferences = {}; + for (let j = 0; j < keys2.length; ++j) + object.preferences[keys2[j]] = message.preferences[keys2[j]]; + } + if (message.address != null && message.hasOwnProperty("address")) + object.address = $root.com.example.protobuf.Address.toObject(message.address, options); + return object; + }; + + /** + * Converts this UserProfile to JSON. + * @function toJSON + * @memberof com.example.protobuf.UserProfile + * @instance + * @returns {Object.} JSON object + */ + UserProfile.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for UserProfile + * @function getTypeUrl + * @memberof com.example.protobuf.UserProfile + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + UserProfile.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/com.example.protobuf.UserProfile"; + }; + + return UserProfile; + })(); + + return protobuf; + })(); + + return example; + })(); + + return com; +})(); + +export { $root as default }; diff --git a/packages/kafka/tests/protos/complex.proto b/packages/kafka/tests/protos/complex.proto new file mode 100644 index 0000000000..46d2171667 --- /dev/null +++ b/packages/kafka/tests/protos/complex.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; +package com.example.protobuf; + +message Address { + string street = 1; + string city = 2; + string zip = 3; +} + +message UserProfile { + string userId = 1; + string name = 2; + string email = 3; + int32 age = 4; + bool isActive = 5; + string signupDate = 6; + repeated string tags = 7; + map preferences = 9; + Address address = 10; +} \ No newline at end of file diff --git a/packages/kafka/tests/protos/product.generated.d.ts b/packages/kafka/tests/protos/product.generated.d.ts new file mode 100644 index 0000000000..ba2ec57ae6 --- /dev/null +++ b/packages/kafka/tests/protos/product.generated.d.ts @@ -0,0 +1,110 @@ +import * as $protobuf from "protobufjs"; +import Long = require("long"); +/** Properties of a Product. */ +export interface IProduct { + + /** Product id */ + id?: (number|null); + + /** Product name */ + name?: (string|null); + + /** Product price */ + price?: (number|null); +} + +/** Represents a Product. */ +export class Product implements IProduct { + + /** + * Constructs a new Product. + * @param [properties] Properties to set + */ + constructor(properties?: IProduct); + + /** Product id. */ + public id: number; + + /** Product name. */ + public name: string; + + /** Product price. */ + public price: number; + + /** + * Creates a new Product instance using the specified properties. + * @param [properties] Properties to set + * @returns Product instance + */ + public static create(properties?: IProduct): Product; + + /** + * Encodes the specified Product message. Does not implicitly {@link Product.verify|verify} messages. + * @param message Product message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: IProduct, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Product message, length delimited. Does not implicitly {@link Product.verify|verify} messages. + * @param message Product message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: IProduct, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Product message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Product + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Product; + + /** + * Decodes a Product message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Product + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Product; + + /** + * Verifies a Product message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Product message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Product + */ + public static fromObject(object: { [k: string]: any }): Product; + + /** + * Creates a plain object from a Product message. Also converts values to other types if specified. + * @param message Product + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: Product, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Product to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for Product + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; +} diff --git a/packages/kafka/tests/protos/product.generated.js b/packages/kafka/tests/protos/product.generated.js new file mode 100644 index 0000000000..c1127bc488 --- /dev/null +++ b/packages/kafka/tests/protos/product.generated.js @@ -0,0 +1,262 @@ +/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/ +import * as $protobuf from "protobufjs/minimal"; + +// Common aliases +const $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util; + +// Exported root namespace +const $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {}); + +export const Product = $root.Product = (() => { + + /** + * Properties of a Product. + * @exports IProduct + * @interface IProduct + * @property {number|null} [id] Product id + * @property {string|null} [name] Product name + * @property {number|null} [price] Product price + */ + + /** + * Constructs a new Product. + * @exports Product + * @classdesc Represents a Product. + * @implements IProduct + * @constructor + * @param {IProduct=} [properties] Properties to set + */ + function Product(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Product id. + * @member {number} id + * @memberof Product + * @instance + */ + Product.prototype.id = 0; + + /** + * Product name. + * @member {string} name + * @memberof Product + * @instance + */ + Product.prototype.name = ""; + + /** + * Product price. + * @member {number} price + * @memberof Product + * @instance + */ + Product.prototype.price = 0; + + /** + * Creates a new Product instance using the specified properties. + * @function create + * @memberof Product + * @static + * @param {IProduct=} [properties] Properties to set + * @returns {Product} Product instance + */ + Product.create = function create(properties) { + return new Product(properties); + }; + + /** + * Encodes the specified Product message. Does not implicitly {@link Product.verify|verify} messages. + * @function encode + * @memberof Product + * @static + * @param {IProduct} message Product message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Product.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.name); + if (message.price != null && Object.hasOwnProperty.call(message, "price")) + writer.uint32(/* id 3, wireType 1 =*/25).double(message.price); + return writer; + }; + + /** + * Encodes the specified Product message, length delimited. Does not implicitly {@link Product.verify|verify} messages. + * @function encodeDelimited + * @memberof Product + * @static + * @param {IProduct} message Product message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Product.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Product message from the specified reader or buffer. + * @function decode + * @memberof Product + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {Product} Product + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Product.decode = function decode(reader, length, error) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Product(); + while (reader.pos < end) { + let tag = reader.uint32(); + if (tag === error) + break; + switch (tag >>> 3) { + case 1: { + message.id = reader.int32(); + break; + } + case 2: { + message.name = reader.string(); + break; + } + case 3: { + message.price = reader.double(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Product message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof Product + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {Product} Product + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Product.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Product message. + * @function verify + * @memberof Product + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Product.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isInteger(message.id)) + return "id: integer expected"; + if (message.name != null && message.hasOwnProperty("name")) + if (!$util.isString(message.name)) + return "name: string expected"; + if (message.price != null && message.hasOwnProperty("price")) + if (typeof message.price !== "number") + return "price: number expected"; + return null; + }; + + /** + * Creates a Product message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof Product + * @static + * @param {Object.} object Plain object + * @returns {Product} Product + */ + Product.fromObject = function fromObject(object) { + if (object instanceof $root.Product) + return object; + let message = new $root.Product(); + if (object.id != null) + message.id = object.id | 0; + if (object.name != null) + message.name = String(object.name); + if (object.price != null) + message.price = Number(object.price); + return message; + }; + + /** + * Creates a plain object from a Product message. Also converts values to other types if specified. + * @function toObject + * @memberof Product + * @static + * @param {Product} message Product + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Product.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.defaults) { + object.id = 0; + object.name = ""; + object.price = 0; + } + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + if (message.price != null && message.hasOwnProperty("price")) + object.price = options.json && !isFinite(message.price) ? String(message.price) : message.price; + return object; + }; + + /** + * Converts this Product to JSON. + * @function toJSON + * @memberof Product + * @instance + * @returns {Object.} JSON object + */ + Product.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for Product + * @function getTypeUrl + * @memberof Product + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + Product.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/Product"; + }; + + return Product; +})(); + +export { $root as default }; diff --git a/packages/kafka/tests/protos/product.proto b/packages/kafka/tests/protos/product.proto new file mode 100644 index 0000000000..b9f815a118 --- /dev/null +++ b/packages/kafka/tests/protos/product.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message Product { + int32 id = 1; + string name = 2; + double price = 3; +} \ No newline at end of file diff --git a/packages/kafka/tests/tsconfig.json b/packages/kafka/tests/tsconfig.json new file mode 100644 index 0000000000..6b38e082b1 --- /dev/null +++ b/packages/kafka/tests/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "../../", + "noEmit": true, + "resolveJsonModule": true + }, + "include": [ + "../../testing/src/setupEnv.ts", + "../src/**/*", + "./**/*" + ] +} \ No newline at end of file diff --git a/packages/kafka/tests/unit/consumer.test.ts b/packages/kafka/tests/unit/consumer.test.ts new file mode 100644 index 0000000000..f653be5497 --- /dev/null +++ b/packages/kafka/tests/unit/consumer.test.ts @@ -0,0 +1,574 @@ +import type { Context } from 'aws-lambda'; +import { describe, expect, it } from 'vitest'; +import { z } from 'zod/v4'; +import { KafkaConsumerMissingSchemaError } from '../../src/errors.js'; +import { SchemaType, kafkaConsumer } from '../../src/index.js'; +import type { ConsumerRecords, MSKEvent } from '../../src/types/types.js'; +import { loadEvent } from '../helpers/loadEvent.js'; +import { com } from '../protos/complex.generated.js'; +import { Product as ProductProto } from '../protos/product.generated.js'; + +describe('Kafka consumer', () => { + const jsonTestEvent = loadEvent('default.json'); + const avroTestEvent = loadEvent('avro.json'); + const protobufTestEvent = loadEvent('protobuf.json'); + const protobufComplexConfluent = loadEvent('protobuf-complex.confluent.json'); + const protobufComplexGlue = loadEvent('protobuf-complex.glue.json'); + const context = {} as Context; + + it('deserializes json message', async () => { + // Prepare + const event = structuredClone(jsonTestEvent); + const handler = kafkaConsumer(async (event) => event, { + value: { type: 'json' }, + key: { type: 'json' }, + }); + + // Act + const result = (await handler(event, context)) as ConsumerRecords; + + // Assess + expect(result.records[0]).toEqual( + expect.objectContaining({ + key: 'recordKey', + value: { id: 12345, name: 'product5', price: 45 }, + originalKey: 'cmVjb3JkS2V5', + originalValue: + 'ewogICJpZCI6IDEyMzQ1LAogICJuYW1lIjogInByb2R1Y3Q1IiwKICAicHJpY2UiOiA0NQp9', + topic: 'mytopic', + partition: 0, + offset: 15, + timestamp: 1545084650987, + timestampType: 'CREATE_TIME', + headers: [{ headerKey: 'headerValue' }], + originalHeaders: [ + { headerKey: [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101] }, + ], + }) + ); + }); + + it('deserializes avro message', async () => { + // Prepare + const event = structuredClone(avroTestEvent); + const handler = kafkaConsumer(async (event) => event, { + value: { + type: 'avro', + schema: `{ + "type": "record", + "name": "Product", + "fields": [ + { "name": "id", "type": "int" }, + { "name": "name", "type": "string" }, + { "name": "price", "type": "double" } + ] + }`, + }, + key: { type: 'json' }, + }); + + // Act + const result = (await handler(event, context)) as ConsumerRecords; + + // Assess + expect(result.records[0]).toEqual( + expect.objectContaining({ + key: 42, + value: { id: 1001, name: 'Laptop', price: 999.99 }, + originalKey: 'NDI=', + originalValue: '0g8MTGFwdG9wUrgehes/j0A=', + topic: 'mytopic', + partition: 0, + offset: 15, + timestamp: 1545084650987, + timestampType: 'CREATE_TIME', + headers: [{ headerKey: 'headerValue' }], + originalHeaders: [ + { headerKey: [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101] }, + ], + }) + ); + }); + + it('deserializes protobuf message', async () => { + // Prepare + const event = structuredClone(protobufTestEvent); + const handler = kafkaConsumer(async (event) => event, { + value: { + type: 'protobuf', + schema: ProductProto, + }, + key: { type: 'json' }, + }); + + // Act + const result = (await handler(event, context)) as ConsumerRecords; + + // Assess + expect(result.records[0]).toEqual( + expect.objectContaining({ + key: 42, + value: { id: 1001, name: 'Laptop', price: 999.99 }, + originalKey: 'NDI=', + originalValue: 'COkHEgZMYXB0b3AZUrgehes/j0A=', + topic: 'mytopic', + partition: 0, + offset: 15, + timestamp: 1545084650987, + timestampType: 'CREATE_TIME', + headers: [{ headerKey: 'headerValue' }], + originalHeaders: [ + { headerKey: [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101] }, + ], + }) + ); + }); + + it.each([ + { + type: SchemaType.PROTOBUF, + event: structuredClone(protobufTestEvent), + error: KafkaConsumerMissingSchemaError, + }, + { + type: SchemaType.AVRO, + event: structuredClone(avroTestEvent), + error: KafkaConsumerMissingSchemaError, + }, + ])( + 'throws when schemaStr not passed for $type event', + async ({ type, error, event }) => { + // Prepare + const handler = kafkaConsumer( + async (event) => { + for (const record of event.records) { + try { + return record.value; + } catch (error) { + return error; + } + } + }, + { + // @ts-expect-error - testing missing schemaStr + value: { type }, + } + ); + + // Act + const result = await handler(event, context); + + // Assess + expect(result).toEqual( + expect.objectContaining({ + message: expect.stringContaining( + `Schema string is required for ${type} deserialization` + ), + name: error.name, + }) + ); + } + ); + + it('throws if using an unsupported schema type', async () => { + // Prepare + const event = structuredClone(jsonTestEvent); + const handler = kafkaConsumer(async (event) => event, { + value: { + // @ts-expect-error - testing unsupported type + type: 'xml', + }, + }); + + // Act & Assess + await expect(handler(event, context)).rejects.toEqual( + expect.objectContaining({ + message: expect.stringContaining( + 'Unsupported deserialization type: xml. Supported types are: json, avro, protobuf.' + ), + name: 'KafkaConsumerDeserializationError', + }) + ); + }); + + it('deserializes with no headers provided', async () => { + // Prepare + const event = structuredClone(jsonTestEvent); + event.records['mytopic-0'][0].headers = null; + const handler = kafkaConsumer(async (event) => event, { + value: { type: 'json' }, + }); + + // Act + const result = (await handler(event, context)) as ConsumerRecords; + + // Assess + expect(result.records[0]).toEqual( + expect.objectContaining({ + key: 'recordKey', + value: { id: 12345, name: 'product5', price: 45 }, + originalKey: 'cmVjb3JkS2V5', + originalValue: + 'ewogICJpZCI6IDEyMzQ1LAogICJuYW1lIjogInByb2R1Y3Q1IiwKICAicHJpY2UiOiA0NQp9', + headers: null, + originalHeaders: null, + }) + ); + }); + + it.each([ + { + type: 'key', + event: (() => { + const event = structuredClone(jsonTestEvent); + event.records['mytopic-0'][0].key = + 'eyJpZCI6NDIsIm5hbWUiOiJpbnZhbGlkUHJvZHVjdCIsInByaWNlIjotMTAwfQ=='; + return event; + })(), + }, + { + type: 'value', + event: (() => { + const event = structuredClone(jsonTestEvent); + event.records['mytopic-0'][0].value = + 'eyJpZCI6NDIsIm5hbWUiOiJpbnZhbGlkUHJvZHVjdCIsInByaWNlIjotMTAwfQ=='; + return event; + })(), + }, + ])( + 'throws when parser schema validation fails for $type', + async ({ event }) => { + // Prepare + const handler = kafkaConsumer( + async (event) => { + for (const record of event.records) { + try { + const { value, key } = record; + return [value, key]; + } catch (error) { + return error; + } + } + }, + { + value: { + type: SchemaType.JSON, + parserSchema: z.object({ + id: z.number(), + name: z.string(), + price: z.number().positive({ + message: "Price can't be negative", + }), + }), + }, + key: { + type: SchemaType.JSON, + parserSchema: z.string(), + }, + } + ); + + // Act & Assess + const result = await handler(event, context); + + expect(result).toEqual( + expect.objectContaining({ + message: expect.stringContaining('Schema validation failed'), + name: 'KafkaConsumerParserError', + cause: expect.arrayContaining([ + expect.objectContaining({ + code: expect.any(String), + message: expect.any(String), + }), + ]), + }) + ); + } + ); + + it('throws when non MSK event passed kafka consumer', async () => { + // Prepare + const event = {} as unknown as MSKEvent; + const handler = kafkaConsumer(async (event) => event, { + value: { type: 'json' }, + }); + + // Act & Assess + await expect(handler(event, context)).rejects.toThrow( + 'Event is not a valid MSKEvent. Expected an object with a "records" property.' + ); + }); + + it.each([ + { + type: 'key parserSchema but no value parserSchema', + config: { + key: { + type: SchemaType.JSON, + parserSchema: z.string(), + }, + value: { type: SchemaType.JSON }, + }, + }, + { + type: 'value parserSchema but no key parserSchema', + config: { + key: { type: SchemaType.JSON }, + value: { + type: SchemaType.JSON, + parserSchema: z.object({ + id: z.number(), + name: z.string(), + price: z.number().positive({ + message: "Price can't be negative", + }), + }), + }, + }, + }, + ])('deserializes with $type', async ({ config }) => { + // Prepare + const event = structuredClone(jsonTestEvent); + event.records['mytopic-0'][0].key = 'cmVjb3JkS2V5'; + event.records['mytopic-0'][0].value = + 'ewogICJpZCI6IDEyMzQ1LAogICJuYW1lIjogInByb2R1Y3Q1IiwKICAicHJpY2UiOiA0NQp9'; + event.records['mytopic-0'][0].headers = null; + const handler = kafkaConsumer(async (event) => event, config); + + // Act + const result = (await handler(event, context)) as ConsumerRecords; + + // Assess + expect(result.records[0]).toEqual( + expect.objectContaining({ + key: 'recordKey', + value: { id: 12345, name: 'product5', price: 45 }, + originalKey: 'cmVjb3JkS2V5', + originalValue: + 'ewogICJpZCI6IDEyMzQ1LAogICJuYW1lIjogInByb2R1Y3Q1IiwKICAicHJpY2UiOiA0NQp9', + headers: null, + originalHeaders: null, + }) + ); + }); + + it.each([ + { + type: 'undefined', + keyValue: undefined, + }, + { + type: 'empty string', + keyValue: '', + }, + ])('handles empty keys gracefully $type', async ({ keyValue }) => { + // Prepare + const event = structuredClone(jsonTestEvent); + event.records['mytopic-0'][0].key = keyValue; + const handler = kafkaConsumer(async (event) => event, { + value: { type: 'json' }, + key: { type: 'json' }, + }); + + // Act + const result = (await handler(event, context)) as ConsumerRecords; + + // Assess + expect(result.records[0].key).toBeUndefined(); + }); + + it('handles null keys gracefully', async () => { + // Prepare + const event = structuredClone(jsonTestEvent); + event.records['mytopic-0'][0].key = null; + const handler = kafkaConsumer(async (event) => event, { + value: { type: 'json' }, + key: { type: 'json' }, + }); + + // Act + const result = (await handler(event, context)) as ConsumerRecords; + + // Assess + expect(result.records[0].key).toBeNull(); + }); + + it('defaults to primitive types when no SchemaConfig is provided', async () => { + // Prepare + const event = structuredClone(jsonTestEvent); + const handler = kafkaConsumer(async (event) => event); + + // Act + const result = (await handler(event, context)) as ConsumerRecords< + unknown, + unknown + >; + + // Assess + expect(result.records[0]).toEqual( + expect.objectContaining({ + key: 'recordKey', + value: JSON.stringify( + { id: 12345, name: 'product5', price: 45 }, + null, + 2 + ), + headers: [ + { + headerKey: 'headerValue', + }, + ], + }) + ); + }); + + it('handles protobuf messages with delimiters', async () => { + // Prepare + const event = structuredClone(protobufTestEvent); + event.records['mytopic-0'][0].value = 'COkHEgZMYXB0b3AZUrgehes/j0A='; + event.records['mytopic-0'][0].valueSchemaMetadata.schemaId = undefined; + event.records['mytopic-0'][1].value = 'AAjpBxIGTGFwdG9wGVK4HoXrP49A'; + event.records['mytopic-0'][1].valueSchemaMetadata.schemaId = + '1111111111111111'; + event.records['mytopic-0'][2].value = 'AgEACOkHEgZMYXB0b3AZUrgehes/j0A='; + event.records['mytopic-0'][2].valueSchemaMetadata.schemaId = '1'; + + const handler = kafkaConsumer( + async (event) => { + const results = []; + for (const record of event.records) { + try { + const { value } = record; + results.push(value); + } catch (error) { + results.push(error); + } + } + return results; + }, + { + value: { + type: SchemaType.PROTOBUF, + schema: ProductProto, + }, + } + ); + + // Act + const result = (await handler(event, context)) as + | (typeof ProductProto)[] + | Error[]; + + // Assess + expect(result).toHaveLength(3); + expect(result[0]).toEqual({ id: 1001, name: 'Laptop', price: 999.99 }); + expect(result[1]).toEqual({ id: 1001, name: 'Laptop', price: 999.99 }); + expect(result[2]).toEqual({ id: 1001, name: 'Laptop', price: 999.99 }); + }); + + it('handles complex protobuf messages from Confluent Schema Registry', async () => { + // Prepare + const event = structuredClone(protobufComplexConfluent); + const handler = kafkaConsumer( + async (event) => { + const results = []; + for (const record of event.records) { + try { + const { value } = record; + results.push(value); + } catch (error) { + results.push(error); + } + } + return results; + }, + { + value: { + type: SchemaType.PROTOBUF, + schema: com.example.protobuf.UserProfile, + parserSchema: z.object({ + address: z.object({ + city: z.string(), + street: z.string(), + zip: z.string(), + }), + age: z.number().int().min(1), + isActive: z.boolean(), + preferences: z.object({ + theme: z.string().optional(), + }), + signupDate: z.string(), + tags: z.array(z.string()), + }), + }, + } + ); + + // Act + const result = (await handler(event, context)) as + | (typeof com.example.protobuf.UserProfile)[] + | Error[]; + + // Assess + expect(result).toHaveLength(4); + expect(result[0]).not.toBeInstanceOf(Error); + expect(result[1]).not.toBeInstanceOf(Error); + expect(result[2]).not.toBeInstanceOf(Error); + expect(result[3]).not.toBeInstanceOf(Error); + }); + + it('handles complex protobuf messages from Glue Schema Registry', async () => { + // Prepare + const event = structuredClone(protobufComplexGlue); + const handler = kafkaConsumer( + async (event) => { + const results = []; + for (const record of event.records) { + try { + const { value } = record; + results.push(value); + } catch (error) { + results.push(error); + } + } + return results; + }, + { + value: { + type: SchemaType.PROTOBUF, + schema: com.example.protobuf.UserProfile, + parserSchema: z.object({ + userId: z.string(), + address: z.object({ + city: z.string(), + street: z.string(), + zip: z.string(), + }), + age: z.number().int().min(1), + isActive: z.boolean(), + preferences: z.object({ + theme: z.string().optional(), + }), + signupDate: z.string(), + tags: z.array(z.string()), + }), + }, + } + ); + + // Act + const result = (await handler(event, context)) as + | (typeof com.example.protobuf.UserProfile)[] + | Error[]; + + // Assess + expect(result).toHaveLength(1); + expect(result[0]).not.toStrictEqual( + expect.objectContaining({ + message: expect.stringContaining( + 'Failed to deserialize Protobuf message' + ), + }) + ); + }); +}); diff --git a/packages/kafka/tests/unit/deserializer.avro.test.ts b/packages/kafka/tests/unit/deserializer.avro.test.ts new file mode 100644 index 0000000000..9893b5c258 --- /dev/null +++ b/packages/kafka/tests/unit/deserializer.avro.test.ts @@ -0,0 +1,60 @@ +import { describe, expect, it } from 'vitest'; +import { deserialize } from '../../src/deserializer/avro.js'; +import { KafkaConsumerDeserializationError } from '../../src/errors.js'; + +describe('Avro Deserializer: ', () => { + it('returns avro deserialised value', async () => { + // Prepare + const message = '0g8MTGFwdG9wUrgehes/j0A='; + const schema = `{ + "type": "record", + "name": "Product", + "fields": [ + { "name": "id", "type": "int" }, + { "name": "name", "type": "string" }, + { "name": "price", "type": "double" } + ] + }`; + const expected = { id: 1001, name: 'Laptop', price: 999.99 }; + + // Act & Assess + expect(await deserialize(message, schema)).toEqual(expected); + }); + + it('throws when avro deserialiser fails', async () => { + // Prepare + const message = '0g8MTGFwdG9wUrgehes/j0A='; + const schema = `{ + "type": "record", + "name": "Product", + "fields": [ + { "name": "id", "type": "int" }, + { "name": "name", "type": "string" }, + ] + }`; // Invalid schema, missing "price" field + + // Act & Assess + expect(() => deserialize(message, schema)).toThrow( + KafkaConsumerDeserializationError + ); + }); + + it('throws when avro deserialiser has not matching schema', async () => { + // Prepare + const message = '0g8MTGFwdG9wUrgehes/j0A='; + const schema = `{ + "type": "record", + "name": "Product", + "fields": [ + { "name": "productId", "type": "int" }, + { "name": "productName", "type": "string" }, + { "name": "productPrice", "type": "double" }, + ] + }`; // Valid schema, but does not match the message content + + // Act & Assess + expect(() => deserialize(message, schema)).toThrow( + KafkaConsumerDeserializationError + ); + }); +}); diff --git a/packages/kafka/tests/unit/deserializer.protobuf.test.ts b/packages/kafka/tests/unit/deserializer.protobuf.test.ts new file mode 100644 index 0000000000..07d9fcd4e1 --- /dev/null +++ b/packages/kafka/tests/unit/deserializer.protobuf.test.ts @@ -0,0 +1,51 @@ +import type { Message } from 'protobufjs'; +import { describe, expect, it } from 'vitest'; +import { deserialize } from '../../src/deserializer/protobuf.js'; +import { KafkaConsumerDeserializationError } from '../../src/errors.js'; +import type { ProtobufMessage } from '../../src/types/types.js'; +import { Product } from '../protos/product.generated.js'; + +describe('Protobuf deserialiser: ', () => { + it('throws when protobuf serialise fails', () => { + // Prepare + const data = 'COkHEgZMYXB0b3AZUrgehes/j0A='; + const invalidType = {} as ProtobufMessage; + const schemaMetadata = { + dataFormat: 'PROTOBUF', + }; + + // Act & Assess + expect(() => deserialize(data, invalidType, schemaMetadata)).toThrow( + KafkaConsumerDeserializationError + ); + }); + + it('returns protobuf deserialised value', () => { + // Prepare + const data = 'COkHEgZMYXB0b3AZUrgehes/j0A='; + const expected = { id: 1001, name: 'Laptop', price: 999.99 }; + const schemaMetadata = { + dataFormat: 'PROTOBUF', + }; + + // Act + const result = deserialize(data, Product, schemaMetadata); + + // Assess + expect(result).toEqual(expected); + }); + + it('throws if unable to parse a Confluent Schema Registry protobuf', () => { + // Prepare + const data = 'COkHEgZMYXB0b3AZUrgehes/j0A='; + const schemaMetadata = { + dataFormat: 'PROTOBUF', + schemaId: '1', + }; + + // Act & Assess + expect(() => deserialize(data, Product, schemaMetadata)).toThrow( + KafkaConsumerDeserializationError + ); + }); +}); diff --git a/packages/kafka/tsconfig.cjs.json b/packages/kafka/tsconfig.cjs.json new file mode 100644 index 0000000000..7d570c8dbe --- /dev/null +++ b/packages/kafka/tsconfig.cjs.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.cjs.json", + "compilerOptions": { + "composite": true, + "declaration": true, + "outDir": "./lib/cjs/", + "rootDir": "./src", + "tsBuildInfoFile": ".tsbuildinfo/cjs.json" + }, + "include": [ + "./src/**/*" + ] +} \ No newline at end of file diff --git a/packages/kafka/tsconfig.json b/packages/kafka/tsconfig.json new file mode 100644 index 0000000000..204ff253d4 --- /dev/null +++ b/packages/kafka/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "baseUrl": ".", + "outDir": "./lib/esm", + "rootDir": "./src", + "tsBuildInfoFile": ".tsbuildinfo/esm.json", + "composite": true, + "declaration": true + }, + "include": [ + "./src/**/*" + ] +} \ No newline at end of file diff --git a/packages/kafka/typedoc.json b/packages/kafka/typedoc.json new file mode 100644 index 0000000000..e56c23f196 --- /dev/null +++ b/packages/kafka/typedoc.json @@ -0,0 +1,11 @@ +{ + "extends": [ + "../../typedoc.base.json" + ], + "entryPoints": [ + "./src/index.ts", + "./src/types/types.ts", + "./src/errors.ts" + ], + "readme": "README.md" +} \ No newline at end of file diff --git a/packages/kafka/vitest.config.ts b/packages/kafka/vitest.config.ts new file mode 100644 index 0000000000..9f1196ef1f --- /dev/null +++ b/packages/kafka/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineProject } from 'vitest/config'; + +export default defineProject({ + test: { + environment: 'node', + setupFiles: ['../testing/src/setupEnv.ts'], + }, +}); diff --git a/packages/logger/CHANGELOG.md b/packages/logger/CHANGELOG.md index 95cd0d9224..58bdcf13e7 100644 --- a/packages/logger/CHANGELOG.md +++ b/packages/logger/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.22.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.21.0...v2.22.0) (2025-06-20) + +**Note:** Version bump only for package @aws-lambda-powertools/logger + + + + + # [2.21.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.20.0...v2.21.0) (2025-06-03) **Note:** Version bump only for package @aws-lambda-powertools/logger diff --git a/packages/logger/package.json b/packages/logger/package.json index f38211058a..efebaef81e 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -1,6 +1,6 @@ { "name": "@aws-lambda-powertools/logger", - "version": "2.21.0", + "version": "2.22.0", "description": "The logging package for the Powertools for AWS Lambda (TypeScript) library", "author": { "name": "Amazon Web Services", @@ -98,7 +98,7 @@ "url": "https://github.com/aws-powertools/powertools-lambda-typescript/issues" }, "dependencies": { - "@aws-lambda-powertools/commons": "^2.21.0", + "@aws-lambda-powertools/commons": "2.22.0", "lodash.merge": "^4.6.2" }, "keywords": [ diff --git a/packages/logger/tests/unit/formatters.test.ts b/packages/logger/tests/unit/formatters.test.ts index e8900adffe..0d2d218c21 100644 --- a/packages/logger/tests/unit/formatters.test.ts +++ b/packages/logger/tests/unit/formatters.test.ts @@ -334,6 +334,7 @@ describe('Formatters', () => { error: new Error('Something went wrong'), name: 'Error', expectedFields: { + location: expect.any(String), message: 'Something went wrong', cause: undefined, }, @@ -342,6 +343,7 @@ describe('Formatters', () => { error: new ReferenceError('doesNotExist is not defined'), name: 'ReferenceError', expectedFields: { + location: expect.any(String), message: 'doesNotExist is not defined', cause: undefined, }, @@ -370,6 +372,7 @@ describe('Formatters', () => { error: new RangeError('The argument must be between 10 and 20'), name: 'RangeError', expectedFields: { + location: expect.any(String), message: 'The argument must be between 10 and 20', cause: undefined, }, @@ -378,6 +381,7 @@ describe('Formatters', () => { error: new ReferenceError('foo is not defined'), name: 'ReferenceError', expectedFields: { + location: expect.any(String), message: 'foo is not defined', cause: undefined, }, @@ -386,6 +390,7 @@ describe('Formatters', () => { error: new SyntaxError(`Unexpected identifier 'bar'`), name: 'SyntaxError', expectedFields: { + location: expect.any(String), message: `Unexpected identifier 'bar'`, cause: undefined, }, @@ -394,6 +399,7 @@ describe('Formatters', () => { error: new TypeError(`Cannot read property 'foo' of null`), name: 'TypeError', expectedFields: { + location: expect.any(String), message: expect.stringMatching(/Cannot read property/), cause: undefined, }, @@ -402,6 +408,7 @@ describe('Formatters', () => { error: new URIError('URI malformed'), name: 'URIError', expectedFields: { + location: expect.any(String), message: 'URI malformed', cause: undefined, }, @@ -410,9 +417,10 @@ describe('Formatters', () => { error: new ErrorWithCause('foo', { cause: new Error('bar') }), name: 'ErrorWithCause', expectedFields: { + location: expect.any(String), message: 'foo', cause: { - location: expect.stringMatching(fileNameRegexp), + location: expect.any(String), message: 'bar', name: 'Error', stack: expect.stringMatching(fileNameRegexpWithLine), @@ -423,6 +431,7 @@ describe('Formatters', () => { error: new ErrorWithCauseString('foo', { cause: 'bar' }), name: 'ErrorWithCauseString', expectedFields: { + location: expect.any(String), message: 'foo', cause: 'bar', }, @@ -435,7 +444,6 @@ describe('Formatters', () => { // Assess expect(formattedError).toEqual({ - location: expect.stringMatching(fileNameRegexp), stack: expect.stringMatching(fileNameRegexpWithLine), name, ...expectedFields, @@ -479,7 +487,7 @@ describe('Formatters', () => { // Assess expect(formattedError).toEqual({ - location: expect.stringMatching(fileNameRegexp), + location: expect.any(String), stack: expect.stringMatching(fileNameRegexpWithLine), name: 'SuperCustomError', message: 'Something went wrong', diff --git a/packages/metrics/CHANGELOG.md b/packages/metrics/CHANGELOG.md index 4c86cd7e25..a9a10070b9 100644 --- a/packages/metrics/CHANGELOG.md +++ b/packages/metrics/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.22.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.21.0...v2.22.0) (2025-06-20) + +**Note:** Version bump only for package @aws-lambda-powertools/metrics + + + + + # [2.21.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.20.0...v2.21.0) (2025-06-03) **Note:** Version bump only for package @aws-lambda-powertools/metrics diff --git a/packages/metrics/package.json b/packages/metrics/package.json index 901ea4f79f..c7814a7969 100644 --- a/packages/metrics/package.json +++ b/packages/metrics/package.json @@ -1,6 +1,6 @@ { "name": "@aws-lambda-powertools/metrics", - "version": "2.21.0", + "version": "2.22.0", "description": "The metrics package for the Powertools for AWS Lambda (TypeScript) library", "author": { "name": "Amazon Web Services", @@ -65,7 +65,7 @@ "main": "./lib/cjs/index.js", "devDependencies": { "@aws-lambda-powertools/testing-utils": "file:../testing", - "@aws-sdk/client-cloudwatch": "^3.821.0", + "@aws-sdk/client-cloudwatch": "^3.830.0", "@types/promise-retry": "^1.1.3", "promise-retry": "^2.0.1" }, @@ -88,7 +88,7 @@ "url": "https://github.com/aws-powertools/powertools-lambda-typescript/issues" }, "dependencies": { - "@aws-lambda-powertools/commons": "2.21.0" + "@aws-lambda-powertools/commons": "2.22.0" }, "keywords": [ "aws", diff --git a/packages/parameters/CHANGELOG.md b/packages/parameters/CHANGELOG.md index 36263886db..83f7026373 100644 --- a/packages/parameters/CHANGELOG.md +++ b/packages/parameters/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.22.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.21.0...v2.22.0) (2025-06-20) + +**Note:** Version bump only for package @aws-lambda-powertools/parameters + + + + + # [2.21.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.20.0...v2.21.0) (2025-06-03) diff --git a/packages/parameters/package.json b/packages/parameters/package.json index 3ea2182b1f..bf9a27645c 100644 --- a/packages/parameters/package.json +++ b/packages/parameters/package.json @@ -1,6 +1,6 @@ { "name": "@aws-lambda-powertools/parameters", - "version": "2.21.0", + "version": "2.22.0", "description": "The parameters package for the Powertools for AWS Lambda (TypeScript) library", "author": { "name": "Amazon Web Services", @@ -156,16 +156,16 @@ ], "devDependencies": { "@aws-lambda-powertools/testing-utils": "file:../testing", - "@aws-sdk/client-appconfigdata": "^3.821.0", - "@aws-sdk/client-dynamodb": "^3.821.0", - "@aws-sdk/client-secrets-manager": "^3.821.0", - "@aws-sdk/client-ssm": "^3.821.0", - "@aws-sdk/util-dynamodb": "^3.821.0", + "@aws-sdk/client-appconfigdata": "^3.830.0", + "@aws-sdk/client-dynamodb": "^3.830.0", + "@aws-sdk/client-secrets-manager": "^3.830.0", + "@aws-sdk/client-ssm": "^3.830.0", + "@aws-sdk/util-dynamodb": "^3.830.0", "@smithy/util-base64": "^4.0.0", "aws-sdk-client-mock": "^4.1.0" }, "dependencies": { - "@aws-lambda-powertools/commons": "2.21.0" + "@aws-lambda-powertools/commons": "2.22.0" }, "peerDependencies": { "@aws-sdk/client-appconfigdata": ">=3.x", diff --git a/packages/parser/CHANGELOG.md b/packages/parser/CHANGELOG.md index c03aacfdf9..e0d72f40a8 100644 --- a/packages/parser/CHANGELOG.md +++ b/packages/parser/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.22.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.21.0...v2.22.0) (2025-06-20) + +**Note:** Version bump only for package @aws-lambda-powertools/parser + + + + + # [2.21.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.20.0...v2.21.0) (2025-06-03) **Note:** Version bump only for package @aws-lambda-powertools/parser diff --git a/packages/parser/package.json b/packages/parser/package.json index a309cd4329..c8bd0a9ae8 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -1,6 +1,6 @@ { "name": "@aws-lambda-powertools/parser", - "version": "2.21.0", + "version": "2.22.0", "description": "The parser package for the Powertools for AWS Lambda (TypeScript) library.", "author": { "name": "Amazon Web Services", @@ -200,7 +200,7 @@ "nodejs" ], "dependencies": { - "@aws-lambda-powertools/commons": "2.21.0" + "@aws-lambda-powertools/commons": "2.22.0" }, "peerDependencies": { "@middy/core": "4.x || 5.x || 6.x", diff --git a/packages/testing/CHANGELOG.md b/packages/testing/CHANGELOG.md index dc9d420af4..2a433f0147 100644 --- a/packages/testing/CHANGELOG.md +++ b/packages/testing/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.22.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.21.0...v2.22.0) (2025-06-20) + +**Note:** Version bump only for package @aws-lambda-powertools/testing-utils + + + + + # [2.21.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.20.0...v2.21.0) (2025-06-03) **Note:** Version bump only for package @aws-lambda-powertools/testing-utils diff --git a/packages/testing/package.json b/packages/testing/package.json index 2d42e5425a..ceed8d9d28 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -1,6 +1,6 @@ { "name": "@aws-lambda-powertools/testing-utils", - "version": "2.21.0", + "version": "2.22.0", "description": "A package containing utilities to test your serverless workloads", "author": { "name": "Amazon Web Services", @@ -97,10 +97,10 @@ }, "homepage": "https://github.com/aws-powertools/powertools-lambda-typescript/tree/main/packages/testing#readme", "dependencies": { - "@aws-cdk/toolkit-lib": "^1.0.0", - "@aws-sdk/client-lambda": "^3.821.0", + "@aws-cdk/toolkit-lib": "^1.1.1", + "@aws-sdk/client-lambda": "^3.830.0", "@smithy/util-utf8": "^4.0.0", - "aws-cdk-lib": "^2.200.0", + "aws-cdk-lib": "^2.201.0", "esbuild": "^0.25.5", "promise-retry": "^2.0.1" }, diff --git a/packages/tracer/CHANGELOG.md b/packages/tracer/CHANGELOG.md index 4a38221ec4..3f7284e0c4 100644 --- a/packages/tracer/CHANGELOG.md +++ b/packages/tracer/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.22.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.21.0...v2.22.0) (2025-06-20) + +**Note:** Version bump only for package @aws-lambda-powertools/tracer + + + + + # [2.21.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.20.0...v2.21.0) (2025-06-03) **Note:** Version bump only for package @aws-lambda-powertools/tracer diff --git a/packages/tracer/package.json b/packages/tracer/package.json index 53104193af..04b46c6a40 100644 --- a/packages/tracer/package.json +++ b/packages/tracer/package.json @@ -1,6 +1,6 @@ { "name": "@aws-lambda-powertools/tracer", - "version": "2.21.0", + "version": "2.22.0", "description": "The tracer package for the Powertools for AWS Lambda (TypeScript) library", "author": { "name": "Amazon Web Services", @@ -30,8 +30,8 @@ "license": "MIT-0", "devDependencies": { "@aws-lambda-powertools/testing-utils": "file:../testing", - "@aws-sdk/client-dynamodb": "^3.821.0", - "@aws-sdk/client-xray": "^3.821.0" + "@aws-sdk/client-dynamodb": "^3.830.0", + "@aws-sdk/client-xray": "^3.830.0" }, "peerDependencies": { "@middy/core": "4.x || 5.x || 6.x" @@ -87,7 +87,7 @@ "url": "https://github.com/aws-powertools/powertools-lambda-typescript/issues" }, "dependencies": { - "@aws-lambda-powertools/commons": "2.21.0", + "@aws-lambda-powertools/commons": "2.22.0", "aws-xray-sdk-core": "^3.10.3" }, "keywords": [ diff --git a/packages/validation/CHANGELOG.md b/packages/validation/CHANGELOG.md index 3e0efe0635..f5b862cf74 100644 --- a/packages/validation/CHANGELOG.md +++ b/packages/validation/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.22.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.21.0...v2.22.0) (2025-06-20) + +**Note:** Version bump only for package @aws-lambda-powertools/validation + + + + + # [2.21.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v2.20.0...v2.21.0) (2025-06-03) **Note:** Version bump only for package @aws-lambda-powertools/validation diff --git a/packages/validation/package.json b/packages/validation/package.json index 5bbea42e35..d7ebf208d9 100644 --- a/packages/validation/package.json +++ b/packages/validation/package.json @@ -1,6 +1,6 @@ { "name": "@aws-lambda-powertools/validation", - "version": "2.21.0", + "version": "2.22.0", "description": "An utility to validate events and responses using JSON Schemas", "author": { "name": "Amazon Web Services", @@ -96,8 +96,8 @@ "url": "https://github.com/aws-powertools/powertools-lambda-typescript/issues" }, "dependencies": { - "@aws-lambda-powertools/commons": "2.21.0", - "@aws-lambda-powertools/jmespath": "2.21.0", + "@aws-lambda-powertools/commons": "2.22.0", + "@aws-lambda-powertools/jmespath": "2.22.0", "ajv": "^8.17.1" }, "keywords": [