diff --git a/.github/workflows/ab-testing-checks.yml b/.github/workflows/ab-testing-checks.yml deleted file mode 100644 index ef6d066476a..00000000000 --- a/.github/workflows/ab-testing-checks.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: Checks - -permissions: - contents: read - -on: - workflow_call: - inputs: - save_build_artifact: - description: 'Whether to save the built files as an artifact' - required: false - type: boolean - default: false - secrets: - FASTLY_AB_TESTING_CONFIG: - required: true - FASTLY_API_TOKEN: - required: true - -jobs: - checks: - runs-on: ubuntu-latest - name: Checks - defaults: - run: - working-directory: ab-testing - env: - FASTLY_AB_TESTING_CONFIG: ${{ secrets.FASTLY_AB_TESTING_CONFIG }} - FASTLY_API_TOKEN: ${{ secrets.FASTLY_API_TOKEN }} - steps: - - uses: actions/checkout@v5 - - - name: Set up Node environment - uses: ./.github/actions/setup-node-env - - - name: Test - run: pnpm test - - - name: Lint - run: pnpm lint - - - name: Prettier Check - run: pnpm prettier:check - - - name: Typecheck - run: pnpm tsc - - - name: Validate - run: pnpm validate - - - name: Build - run: pnpm build - - - if: ${{ inputs.save_build_artifact }} - uses: actions/upload-artifact@v5 - with: - name: ab-testing-build - path: ab-testing/dist diff --git a/.github/workflows/ab-testing-ci-code.yml b/.github/workflows/ab-testing-ci-code.yml deleted file mode 100644 index 85b5f9ca826..00000000000 --- a/.github/workflows/ab-testing-ci-code.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: 🧪 AB testing CI (CODE) - -permissions: - contents: read - -on: - workflow_dispatch: - -jobs: - ci: - uses: ./.github/workflows/ab-testing-checks.yml - with: - save_build_artifact: true - secrets: - FASTLY_AB_TESTING_CONFIG: ${{ secrets.FASTLY_CODE_AB_TESTING_CONFIG }} - FASTLY_API_TOKEN: ${{ secrets.FASTLY_CODE_API_TOKEN }} - - deploy: - name: Deploy CODE - needs: ci - uses: ./.github/workflows/ab-testing-deploy.yml - with: - stage: code - secrets: - FASTLY_AB_TESTING_CONFIG: ${{ secrets.FASTLY_CODE_AB_TESTING_CONFIG }} - FASTLY_API_TOKEN: ${{ secrets.FASTLY_CODE_API_TOKEN }} diff --git a/.github/workflows/ab-testing-ci.yml b/.github/workflows/ab-testing-ci.yml index 9aa98702ba3..45558648e79 100644 --- a/.github/workflows/ab-testing-ci.yml +++ b/.github/workflows/ab-testing-ci.yml @@ -4,34 +4,127 @@ permissions: contents: read on: - pull_request: - paths: - - 'ab-testing/**' - - '.github/workflows/ab-testing-*.yml' push: - branches: - - main paths: - 'ab-testing/**' - - '.github/workflows/ab-testing-*.yml' + - '!ab-testing/deployment-lambda/**' + - '.github/workflows/ab-testing-ci.yml' jobs: - ci: - name: CI - uses: ./.github/workflows/ab-testing-checks.yml - with: - save_build_artifact: true - secrets: + config-ci: + runs-on: ubuntu-latest + name: Config CI + defaults: + run: + working-directory: ab-testing/config + env: FASTLY_AB_TESTING_CONFIG: ${{ secrets.FASTLY_PROD_AB_TESTING_CONFIG }} FASTLY_API_TOKEN: ${{ secrets.FASTLY_PROD_API_TOKEN }} - deploy: - name: Deploy - needs: ci - if: github.ref == 'refs/heads/main' - uses: ./.github/workflows/ab-testing-deploy.yml - with: - stage: prod - secrets: - FASTLY_AB_TESTING_CONFIG: ${{ secrets.FASTLY_PROD_AB_TESTING_CONFIG }} - FASTLY_API_TOKEN: ${{ secrets.FASTLY_PROD_API_TOKEN }} + steps: + - uses: actions/checkout@v5 + + - name: Set up Node environment + uses: ./.github/actions/setup-node-env + + - name: Test + run: pnpm test + + - name: Lint + run: pnpm lint + + - name: Prettier Check + run: pnpm prettier:check + + - name: Typecheck + run: pnpm tsc + + - name: Validate + run: pnpm validate + + - name: Build + run: pnpm build + + - uses: actions/upload-artifact@v5 + with: + name: ab-testing-build + path: ab-testing/config/dist + + ui-ci: + name: UI CI + runs-on: ubuntu-latest + defaults: + run: + working-directory: ab-testing/frontend + permissions: + contents: read + steps: + - uses: actions/checkout@v5 + + - name: Set up Node environment + uses: ./.github/actions/setup-node-env + + - name: Build UI + run: pnpm build + + - name: Save build + uses: actions/upload-artifact@v5 + with: + name: ui-build + path: ab-testing/frontend/output/ab-tests.html + if-no-files-found: error + + riff-raff: + name: Riff-Raff Artifacts + runs-on: ubuntu-latest + needs: [config-ci, ui-ci] + permissions: + id-token: write + contents: read + pull-requests: write + defaults: + run: + working-directory: ab-testing + + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Set up Node + uses: ./.github/actions/setup-node-env + + - name: Fetch config build + uses: actions/download-artifact@v6.0.0 + with: + name: ab-testing-build + path: ab-testing/config/dist + + - name: Fetch UI build + uses: actions/download-artifact@v6.0.0 + with: + name: ui-build + path: ab-testing/frontend/output/ab-tests.html + + - name: CDK Test + run: pnpm --filter @guardian/ab-testing-cdk test + + - name: CDK synth + run: pnpm --filter @guardian/ab-testing-cdk synth:ab-testing-config + + - name: Riff-Raff Upload + uses: guardian/actions-riff-raff@v4.1.9 + with: + roleArn: ${{ secrets.GU_RIFF_RAFF_ROLE_ARN }} + githubToken: ${{ secrets.GITHUB_TOKEN }} + projectName: dotcom:ab-testing + configPath: ab-testing/cdk/cdk.out/ab-testing-config/riff-raff.yaml + contentDirectories: | + ab-testing-config-artifacts: + - ab-testing/config/dist + ab-testing-ui-artifact: + - ab-testing/frontend/output/ab-tests.html + cdk.out/ab-testing-config: + - ab-testing/cdk/cdk.out/ab-testing-config diff --git a/.github/workflows/ab-testing-deploy.yml b/.github/workflows/ab-testing-deploy.yml deleted file mode 100644 index 39bd334df11..00000000000 --- a/.github/workflows/ab-testing-deploy.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: 🧪 Deploy AB Testing Config - -permissions: - contents: read - -on: - workflow_call: - inputs: - stage: - description: 'Stage to deploy to (e.g., code, prod)' - required: true - type: string - secrets: - FASTLY_AB_TESTING_CONFIG: - required: true - FASTLY_API_TOKEN: - required: true - -jobs: - deploy: - name: Deploy - runs-on: ubuntu-latest - defaults: - run: - working-directory: ab-testing - steps: - - uses: actions/checkout@v5 - - - name: Set up Node environment - uses: ./.github/actions/setup-node-env - - - name: Download build artifact - uses: actions/download-artifact@v6.0.0 - with: - name: ab-testing-build - path: ab-testing/dist - - - name: Deploy - run: pnpm run deploy - env: - FASTLY_AB_TESTING_CONFIG: ${{ secrets.FASTLY_AB_TESTING_CONFIG }} - FASTLY_API_TOKEN: ${{ secrets.FASTLY_API_TOKEN }} diff --git a/.github/workflows/ab-testing-lambda-ci.yml b/.github/workflows/ab-testing-lambda-ci.yml new file mode 100644 index 00000000000..1c0c5255eee --- /dev/null +++ b/.github/workflows/ab-testing-lambda-ci.yml @@ -0,0 +1,89 @@ +name: 🧪 AB testing Lambda + +permissions: + contents: read + +on: + push: + paths: + - 'ab-testing/deploy-lambda/**' + - 'ab-testing/cdk/**' + - 'ab-testing/config/lib/**' + - '.github/workflows/ab-testing-lambda-ci.yml' + +jobs: + ci: + name: CI + runs-on: ubuntu-latest + defaults: + run: + working-directory: ab-testing/deploy-lambda + permissions: + contents: read + steps: + - uses: actions/checkout@v5 + + - name: Set up Node environment + uses: ./.github/actions/setup-node-env + + - name: Build Lambda + run: pnpm build + + - name: Zip app artifact + run: | + cd dist + zip -r lambda.zip . + zip -j lambda.zip ../package.json + + - name: Save build + uses: actions/upload-artifact@v5 + with: + name: ab-testing-lambda-build + path: ab-testing/deploy-lambda/dist/lambda.zip + + riff-raff: + name: Riff-Raff Artifacts + runs-on: ubuntu-latest + needs: [ci] + permissions: + id-token: write + contents: read + pull-requests: write + defaults: + run: + working-directory: ab-testing + + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Set up Node + uses: ./.github/actions/setup-node-env + + - name: Fetch Lambda build + uses: actions/download-artifact@v6.0.0 + with: + name: ab-testing-lambda-build + path: ab-testing/deploy-lambda/dist/lambda.zip + + - name: CDK Test + run: pnpm --filter @guardian/ab-testing-cdk test + + - name: CDK synth + run: pnpm --filter @guardian/ab-testing-cdk synth:deployment-lambda + + - name: Riff-Raff Upload + uses: guardian/actions-riff-raff@v4.1.9 + with: + roleArn: ${{ secrets.GU_RIFF_RAFF_ROLE_ARN }} + githubToken: ${{ secrets.GITHUB_TOKEN }} + projectName: dotcom:ab-testing-deployment-lambda + configPath: ab-testing/cdk/cdk.out/deployment-lambda/riff-raff.yaml + contentDirectories: | + ab-testing-deployment-lambda: + - ab-testing/deploy-lambda/dist/lambda.zip + cdk.out/deployment-lambda: + - ab-testing/cdk/cdk.out/deployment-lambda diff --git a/.github/workflows/ab-testing-ui.yml b/.github/workflows/ab-testing-ui.yml deleted file mode 100644 index 6ace87e1a3c..00000000000 --- a/.github/workflows/ab-testing-ui.yml +++ /dev/null @@ -1,73 +0,0 @@ -name: 🧪 AB testing UI -on: - pull_request: - paths: - - 'ab-testing/**' - - '.github/workflows/ab-testing-*.yml' - push: - branches: - - main - paths: - - 'ab-testing/**' - - '.github/workflows/ab-testing-*.yml' - -jobs: - build-ui: - name: AB testing UI build - runs-on: ubuntu-latest - defaults: - run: - working-directory: ab-testing/frontend - permissions: - contents: read - steps: - - uses: actions/checkout@v5 - - - name: Set up Node environment - uses: ./.github/actions/setup-node-env - - - name: Build UI - run: pnpm build - - - name: Save build - uses: actions/upload-artifact@v5 - with: - name: ui-build - path: ab-testing/frontend/output/ab-tests.html - if-no-files-found: error - - riff-raff: - name: AB testing Riffraff upload - runs-on: ubuntu-latest - needs: build-ui - permissions: - id-token: write - contents: read - pull-requests: write - - steps: - - name: Checkout - uses: actions/checkout@v5 - with: - fetch-depth: 0 - persist-credentials: false - - - name: Set up Node - uses: ./.github/actions/setup-node-env - - - name: Fetch build - uses: actions/download-artifact@v6.0.0 - with: - name: ui-build - path: output/ab-tests.html - - - name: Riff-Raff Upload - uses: guardian/actions-riff-raff@v4.1.9 - with: - roleArn: ${{ secrets.GU_RIFF_RAFF_ROLE_ARN }} - githubToken: ${{ secrets.GITHUB_TOKEN }} - projectName: dotcom:ab-testing - configPath: ab-testing/riff-raff.yaml - contentDirectories: | - admin/ab-testing: - - output/ab-tests.html diff --git a/ab-testing/.gitignore b/ab-testing/.gitignore new file mode 100644 index 00000000000..b5b74b15f3e --- /dev/null +++ b/ab-testing/.gitignore @@ -0,0 +1 @@ +cdk.out diff --git a/ab-testing/README.md b/ab-testing/README.md index 4797763ef19..650e8f61d64 100644 --- a/ab-testing/README.md +++ b/ab-testing/README.md @@ -2,16 +2,23 @@ This directory contains the code and configuration for the AB testing framework used on theguardian.com. If you're looking to set up a new server or client side AB test using the new framework then please visit the docs [here](https://github.com/guardian/dotcom-rendering/blob/main/dotcom-rendering/docs/development/ab-testing-in-dcr.md#beta-ab-test-framework). +### Structure + +- `config/` - Contains the configuration and scripts for building and validating AB tests. +- `frontend/` - Contains the source code for the admin interface that shows current test state, viewable from https://frontend.gutools.co.uk/analytics/ab-testing (or https://frontend.code.dev-gutools.co.uk/analytics/ab-testing for CODE) +- `deploy-lambda/` - Contains the code for the lambda function that deploys the AB test state to Fastly edge-dictionaries. +- `cdk/` - Contains the AWS CDK code for deploying the test configuration, UI and lambda function. + ## How it works -The AB testing framework uses Deno to run scripts that validate and deploy the tests. The `deno.json` file contains the tasks that can be run, such as `validate`, `deploy`, and `build`. +The AB testing framework runs scripts that validate, build and deploy the tests. -Which tests using which mvt ids is computed by the `build` task, which generates the `dist/mvts.json` file. This file contains the mapping of AB tests to MVT IDs. +Which tests using which mvt ids is computed by the `build` task, which generates the `config/dist/mvts.json` file. This file contains the mapping of AB tests to MVT IDs. The algorithm allocates tests available MVT IDs based on the audience size and space. Allocation is deterministic, so the same test (with the same name) will always be assigned the same MVT ID as long as the test hasn't been removed, allowing for consistent user experience when tests are added/updated/removed. This also means that new/update tests will not use contiguous MVT IDs, but will instead use whichever MVT IDs are available. However, the allocation is completely separate for each audience space, so if you have a test in space `A` and move it to space `B`, it will be allocated different MVT IDs. -The state of the AB tests is stored in Fastly dictionaries, which are updated when the `deploy` task is run. Logic in fastly VCL will then use these dictionaries to determine which users are in which test groups and set appropriate headers and/or cookies. +The state of the AB tests is uploaded to Fastly edge-dictionaries, where our fastly service can read the test definitions and MVT ID mappings to determine which test groups a user should see. See the [fastly-edge-cache documentation](https://github.com/guardian/fastly-edge-cache/blob/main/theguardiancom/docs/ab-testing.md) for even more details. diff --git a/ab-testing/cdk/bin/ab-testing-config.cdk.ts b/ab-testing/cdk/bin/ab-testing-config.cdk.ts new file mode 100644 index 00000000000..6a186cc7982 --- /dev/null +++ b/ab-testing/cdk/bin/ab-testing-config.cdk.ts @@ -0,0 +1,66 @@ +import "source-map-support/register.js"; +import { RiffRaffYamlFile } from "@guardian/cdk/lib/riff-raff-yaml-file/index.js"; +import { App } from "aws-cdk-lib"; +import { AbTestingConfig } from "../lib/abTestingConfig.ts"; + +const app = new App({ outdir: "cdk.out/ab-testing-config" }); + +new AbTestingConfig(app, "AbTestingConfigCode", { + stack: "frontend", + stage: "CODE", + env: { + region: "eu-west-1", + }, +}); + +new AbTestingConfig(app, "AbTestingConfigProd", { + stack: "frontend", + stage: "PROD", + env: { + region: "eu-west-1", + }, +}); + +const riffRaff = new RiffRaffYamlFile(app); +const { + riffRaffYaml: { deployments }, +} = riffRaff; + +deployments.set("config/ab-testing", { + app: "ab-testing-config-artifact", + contentDirectory: "ab-testing-config-artifacts", + type: "aws-s3", + regions: new Set(["eu-west-1"]), + stacks: new Set(["frontend"]), + parameters: { + bucketSsmKey: "/account/services/dotcom-store.bucket", + cacheControl: "public, max-age=315360000", + prefixStack: false, + publicReadAcl: false, + }, +}); + +deployments.set("admin/ab-testing", { + app: "ab-testing-ui-artifact", + contentDirectory: "ab-testing-ui-artifact", + type: "aws-s3", + regions: new Set(["eu-west-1"]), + stacks: new Set(["frontend"]), + parameters: { + bucketSsmKey: "/account/services/dotcom-store.bucket", + cacheControl: "public, max-age=315360000", + prefixStack: false, + publicReadAcl: false, + }, +}); + +const cfnDeployment = deployments.get( + `cfn-eu-west-1-frontend-ab-testing-config`, +)!; + +// We need the test artifacts in place before deploying the lambda that uses them +cfnDeployment.dependencies = cfnDeployment.dependencies + ? [...cfnDeployment.dependencies, "config/ab-testing"] + : ["config/ab-testing"]; + +riffRaff.synth(); diff --git a/ab-testing/cdk/bin/deployment-lambda.cdk.ts b/ab-testing/cdk/bin/deployment-lambda.cdk.ts new file mode 100644 index 00000000000..05fa16364b6 --- /dev/null +++ b/ab-testing/cdk/bin/deployment-lambda.cdk.ts @@ -0,0 +1,21 @@ +import "source-map-support/register.js"; +import { GuRoot } from "@guardian/cdk/lib/constructs/root.js"; +import { AbTestingDeploymentLambda } from "../lib/deploymentLambda.ts"; + +const app = new GuRoot({ outdir: "cdk.out/deployment-lambda" }); + +new AbTestingDeploymentLambda(app, "AbTestingDeploymentLambdaCode", { + stack: "frontend", + stage: "CODE", + env: { + region: "eu-west-1", + }, +}); + +new AbTestingDeploymentLambda(app, "AbTestingDeploymentLambdaProd", { + stack: "frontend", + stage: "PROD", + env: { + region: "eu-west-1", + }, +}); diff --git a/ab-testing/cdk/cdk.json b/ab-testing/cdk/cdk.json new file mode 100644 index 00000000000..85ba8a27e69 --- /dev/null +++ b/ab-testing/cdk/cdk.json @@ -0,0 +1,6 @@ +{ + "context": { + "aws-cdk:enableDiffNoFail": "true", + "@aws-cdk/core:stackRelativeExports": "true" + } +} diff --git a/ab-testing/cdk/lib/__snapshots__/abTestingConfig.test.ts.snap b/ab-testing/cdk/lib/__snapshots__/abTestingConfig.test.ts.snap new file mode 100644 index 00000000000..088ca4513ec --- /dev/null +++ b/ab-testing/cdk/lib/__snapshots__/abTestingConfig.test.ts.snap @@ -0,0 +1,69 @@ +exports[`The ID5 Baton Lambda stack > matches the CODE snapshot 1`] = ` +{ + "Metadata": { + "gu:cdk:constructs": [], + "gu:cdk:version": "62.0.1" + }, + "Resources": { + "InvokeDictionaryDeployLambda": { + "Type": "Custom::FastlyEdgeDictionaryDeploy", + "Properties": { + "ServiceToken": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":lambda:eu-west-1:", + { + "Ref": "AWS::AccountId" + }, + ":function:ab-testing-deployment-lambda-CODE" + ] + ] + }, + "ServiceTimeout": "300" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + } +} +`; + +exports[`The ID5 Baton Lambda stack > matches the PROD snapshot 1`] = ` +{ + "Metadata": { + "gu:cdk:constructs": [], + "gu:cdk:version": "62.0.1" + }, + "Resources": { + "InvokeDictionaryDeployLambda": { + "Type": "Custom::FastlyEdgeDictionaryDeploy", + "Properties": { + "ServiceToken": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":lambda:eu-west-1:", + { + "Ref": "AWS::AccountId" + }, + ":function:ab-testing-deployment-lambda-PROD" + ] + ] + }, + "ServiceTimeout": "300" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + } +} +`; diff --git a/ab-testing/cdk/lib/__snapshots__/deploymentLambda.test.ts.snap b/ab-testing/cdk/lib/__snapshots__/deploymentLambda.test.ts.snap new file mode 100644 index 00000000000..72619cbfd9e --- /dev/null +++ b/ab-testing/cdk/lib/__snapshots__/deploymentLambda.test.ts.snap @@ -0,0 +1,643 @@ +exports[`The ID5 Baton Lambda stack > matches the CODE snapshot 1`] = ` +{ + "Metadata": { + "gu:cdk:constructs": [ + "GuDistributionBucketParameter", + "GuLambdaFunction" + ], + "gu:cdk:version": "62.0.1" + }, + "Parameters": { + "SsmParameterValueaccountservicesdotcomstorebucketC96584B6F00A464EAD1953AFF4B05118Parameter": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/account/services/dotcom-store.bucket" + }, + "DistributionBucketName": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/account/services/artifact.bucket", + "Description": "SSM parameter containing the S3 bucket name holding distribution artifacts" + } + }, + "Resources": { + "AbTestingDeploymentLambdaServiceRoleC1809305": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ], + "Tags": [ + { + "Key": "App", + "Value": "ab-testing-deployment-lambda" + }, + { + "Key": "gu:cdk:version", + "Value": "62.0.1" + }, + { + "Key": "gu:repo", + "Value": "guardian/dotcom-rendering" + }, + { + "Key": "Stack", + "Value": "frontend" + }, + { + "Key": "Stage", + "Value": "CODE" + } + ] + } + }, + "AbTestingDeploymentLambdaServiceRoleDefaultPolicyC65D820D": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":s3:::", + { + "Ref": "DistributionBucketName" + } + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":s3:::", + { + "Ref": "DistributionBucketName" + }, + "/frontend/CODE/ab-testing-deployment-lambda/lambda.zip" + ] + ] + } + ] + }, + { + "Action": "ssm:GetParametersByPath", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:eu-west-1:", + { + "Ref": "AWS::AccountId" + }, + ":parameter/CODE/frontend/ab-testing-deployment-lambda" + ] + ] + } + }, + { + "Action": [ + "ssm:GetParameters", + "ssm:GetParameter" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:eu-west-1:", + { + "Ref": "AWS::AccountId" + }, + ":parameter/CODE/frontend/ab-testing-deployment-lambda/*" + ] + ] + } + }, + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":s3:::", + { + "Ref": "SsmParameterValueaccountservicesdotcomstorebucketC96584B6F00A464EAD1953AFF4B05118Parameter" + } + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":s3:::", + { + "Ref": "SsmParameterValueaccountservicesdotcomstorebucketC96584B6F00A464EAD1953AFF4B05118Parameter" + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "ssm:DescribeParameters", + "ssm:GetParameters", + "ssm:GetParameter", + "ssm:GetParameterHistory" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ssm:eu-west-1:", + { + "Ref": "AWS::AccountId" + }, + ":parameter/ab-testing/CODE/fastly-api-token" + ] + ] + } + }, + { + "Action": [ + "ssm:DescribeParameters", + "ssm:GetParameters", + "ssm:GetParameter", + "ssm:GetParameterHistory" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ssm:eu-west-1:", + { + "Ref": "AWS::AccountId" + }, + ":parameter/ab-testing/CODE/fastly-config" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "AbTestingDeploymentLambdaServiceRoleDefaultPolicyC65D820D", + "Roles": [ + { + "Ref": "AbTestingDeploymentLambdaServiceRoleC1809305" + } + ] + } + }, + "AbTestingDeploymentLambda3C53337B": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Ref": "DistributionBucketName" + }, + "S3Key": "frontend/CODE/ab-testing-deployment-lambda/lambda.zip" + }, + "Environment": { + "Variables": { + "STAGE": "CODE", + "ARTIFACT_BUCKET_NAME": { + "Ref": "SsmParameterValueaccountservicesdotcomstorebucketC96584B6F00A464EAD1953AFF4B05118Parameter" + }, + "STACK": "frontend", + "APP": "ab-testing-deployment-lambda" + } + }, + "FunctionName": "ab-testing-deployment-lambda-CODE", + "Handler": "index.handler", + "LoggingConfig": { + "LogFormat": "JSON" + }, + "MemorySize": 256, + "Role": { + "Fn::GetAtt": [ + "AbTestingDeploymentLambdaServiceRoleC1809305", + "Arn" + ] + }, + "Runtime": "nodejs22.x", + "Tags": [ + { + "Key": "App", + "Value": "ab-testing-deployment-lambda" + }, + { + "Key": "gu:cdk:version", + "Value": "62.0.1" + }, + { + "Key": "gu:repo", + "Value": "guardian/dotcom-rendering" + }, + { + "Key": "Stack", + "Value": "frontend" + }, + { + "Key": "Stage", + "Value": "CODE" + } + ], + "Timeout": 30 + }, + "DependsOn": [ + "AbTestingDeploymentLambdaServiceRoleDefaultPolicyC65D820D", + "AbTestingDeploymentLambdaServiceRoleC1809305" + ] + } + } +} +`; + +exports[`The ID5 Baton Lambda stack > matches the PROD snapshot 1`] = ` +{ + "Metadata": { + "gu:cdk:constructs": [ + "GuDistributionBucketParameter", + "GuLambdaFunction" + ], + "gu:cdk:version": "62.0.1" + }, + "Parameters": { + "SsmParameterValueaccountservicesdotcomstorebucketC96584B6F00A464EAD1953AFF4B05118Parameter": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/account/services/dotcom-store.bucket" + }, + "DistributionBucketName": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/account/services/artifact.bucket", + "Description": "SSM parameter containing the S3 bucket name holding distribution artifacts" + } + }, + "Resources": { + "AbTestingDeploymentLambdaServiceRoleC1809305": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ], + "Tags": [ + { + "Key": "App", + "Value": "ab-testing-deployment-lambda" + }, + { + "Key": "gu:cdk:version", + "Value": "62.0.1" + }, + { + "Key": "gu:repo", + "Value": "guardian/dotcom-rendering" + }, + { + "Key": "Stack", + "Value": "frontend" + }, + { + "Key": "Stage", + "Value": "PROD" + } + ] + } + }, + "AbTestingDeploymentLambdaServiceRoleDefaultPolicyC65D820D": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":s3:::", + { + "Ref": "DistributionBucketName" + } + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":s3:::", + { + "Ref": "DistributionBucketName" + }, + "/frontend/PROD/ab-testing-deployment-lambda/lambda.zip" + ] + ] + } + ] + }, + { + "Action": "ssm:GetParametersByPath", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:eu-west-1:", + { + "Ref": "AWS::AccountId" + }, + ":parameter/PROD/frontend/ab-testing-deployment-lambda" + ] + ] + } + }, + { + "Action": [ + "ssm:GetParameters", + "ssm:GetParameter" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:eu-west-1:", + { + "Ref": "AWS::AccountId" + }, + ":parameter/PROD/frontend/ab-testing-deployment-lambda/*" + ] + ] + } + }, + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":s3:::", + { + "Ref": "SsmParameterValueaccountservicesdotcomstorebucketC96584B6F00A464EAD1953AFF4B05118Parameter" + } + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":s3:::", + { + "Ref": "SsmParameterValueaccountservicesdotcomstorebucketC96584B6F00A464EAD1953AFF4B05118Parameter" + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "ssm:DescribeParameters", + "ssm:GetParameters", + "ssm:GetParameter", + "ssm:GetParameterHistory" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ssm:eu-west-1:", + { + "Ref": "AWS::AccountId" + }, + ":parameter/ab-testing/PROD/fastly-api-token" + ] + ] + } + }, + { + "Action": [ + "ssm:DescribeParameters", + "ssm:GetParameters", + "ssm:GetParameter", + "ssm:GetParameterHistory" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ssm:eu-west-1:", + { + "Ref": "AWS::AccountId" + }, + ":parameter/ab-testing/PROD/fastly-config" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "AbTestingDeploymentLambdaServiceRoleDefaultPolicyC65D820D", + "Roles": [ + { + "Ref": "AbTestingDeploymentLambdaServiceRoleC1809305" + } + ] + } + }, + "AbTestingDeploymentLambda3C53337B": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Ref": "DistributionBucketName" + }, + "S3Key": "frontend/PROD/ab-testing-deployment-lambda/lambda.zip" + }, + "Environment": { + "Variables": { + "STAGE": "PROD", + "ARTIFACT_BUCKET_NAME": { + "Ref": "SsmParameterValueaccountservicesdotcomstorebucketC96584B6F00A464EAD1953AFF4B05118Parameter" + }, + "STACK": "frontend", + "APP": "ab-testing-deployment-lambda" + } + }, + "FunctionName": "ab-testing-deployment-lambda-PROD", + "Handler": "index.handler", + "LoggingConfig": { + "LogFormat": "JSON" + }, + "MemorySize": 256, + "Role": { + "Fn::GetAtt": [ + "AbTestingDeploymentLambdaServiceRoleC1809305", + "Arn" + ] + }, + "Runtime": "nodejs22.x", + "Tags": [ + { + "Key": "App", + "Value": "ab-testing-deployment-lambda" + }, + { + "Key": "gu:cdk:version", + "Value": "62.0.1" + }, + { + "Key": "gu:repo", + "Value": "guardian/dotcom-rendering" + }, + { + "Key": "Stack", + "Value": "frontend" + }, + { + "Key": "Stage", + "Value": "PROD" + } + ], + "Timeout": 30 + }, + "DependsOn": [ + "AbTestingDeploymentLambdaServiceRoleDefaultPolicyC65D820D", + "AbTestingDeploymentLambdaServiceRoleC1809305" + ] + } + } +} +`; diff --git a/ab-testing/cdk/lib/abTestingConfig.test.ts b/ab-testing/cdk/lib/abTestingConfig.test.ts new file mode 100644 index 00000000000..1b8daf2036a --- /dev/null +++ b/ab-testing/cdk/lib/abTestingConfig.test.ts @@ -0,0 +1,41 @@ +import { describe, it } from "node:test"; +import { snapshot } from "node:test"; +import { basename } from "path"; +import { GuRoot } from "@guardian/cdk/lib/constructs/root.js"; +import { Template } from "aws-cdk-lib/assertions"; +import { AbTestingConfig } from "./abTestingConfig.ts"; + +snapshot.setResolveSnapshotPath( + () => + `${import.meta.dirname}/__snapshots__/${basename( + import.meta.filename, + )}.snap`, +); + +void describe("The ID5 Baton Lambda stack", () => { + void it("matches the CODE snapshot", ({ assert }) => { + const app = new GuRoot(); + const stack = new AbTestingConfig(app, "AbTestingConfig", { + stack: "frontend", + stage: "CODE", + env: { + region: "eu-west-1", + }, + }); + const template = Template.fromStack(stack); + assert.snapshot(template.toJSON()); + }); + + void it("matches the PROD snapshot", ({ assert }) => { + const app = new GuRoot(); + const stack = new AbTestingConfig(app, "AbTestingConfig", { + stack: "frontend", + stage: "PROD", + env: { + region: "eu-west-1", + }, + }); + const template = Template.fromStack(stack); + assert.snapshot(template.toJSON()); + }); +}); diff --git a/ab-testing/cdk/lib/abTestingConfig.ts b/ab-testing/cdk/lib/abTestingConfig.ts new file mode 100644 index 00000000000..42b0cee0d91 --- /dev/null +++ b/ab-testing/cdk/lib/abTestingConfig.ts @@ -0,0 +1,25 @@ +import type { GuStackProps } from "@guardian/cdk/lib/constructs/core/stack.js"; +import { GuStack } from "@guardian/cdk/lib/constructs/core/stack.js"; +import type { App } from "aws-cdk-lib"; +import { CustomResource, Duration } from "aws-cdk-lib"; +import { Function } from "aws-cdk-lib/aws-lambda"; +import { lambdaFunctionName } from "./deploymentLambda.ts"; + +export class AbTestingConfig extends GuStack { + constructor(scope: App, id: string, props: GuStackProps) { + super(scope, id, props); + + const lambda = Function.fromFunctionName( + this, + "DeploymentLambdaFunction", + `${lambdaFunctionName}-${this.stage}`, + ); + + // Trigger the Lambda to run upon deployment + new CustomResource(this, "InvokeDictionaryDeployLambda", { + serviceToken: lambda.functionArn, + serviceTimeout: Duration.minutes(5), + resourceType: "Custom::FastlyEdgeDictionaryDeploy", + }); + } +} diff --git a/ab-testing/cdk/lib/deploymentLambda.test.ts b/ab-testing/cdk/lib/deploymentLambda.test.ts new file mode 100644 index 00000000000..c3d5bcab5ab --- /dev/null +++ b/ab-testing/cdk/lib/deploymentLambda.test.ts @@ -0,0 +1,49 @@ +import { describe, it } from "node:test"; +import { snapshot } from "node:test"; +import { basename } from "path"; +import { GuRoot } from "@guardian/cdk/lib/constructs/root.js"; +import { Template } from "aws-cdk-lib/assertions"; +import { AbTestingDeploymentLambda } from "./deploymentLambda.ts"; + +snapshot.setResolveSnapshotPath( + () => + `${import.meta.dirname}/__snapshots__/${basename( + import.meta.filename, + )}.snap`, +); + +void describe("The ID5 Baton Lambda stack", () => { + void it("matches the CODE snapshot", ({ assert }) => { + const app = new GuRoot(); + const stack = new AbTestingDeploymentLambda( + app, + "AbTestingDeploymentLambda", + { + stack: "frontend", + stage: "CODE", + env: { + region: "eu-west-1", + }, + }, + ); + const template = Template.fromStack(stack); + assert.snapshot(template.toJSON()); + }); + + void it("matches the PROD snapshot", ({ assert }) => { + const app = new GuRoot(); + const stack = new AbTestingDeploymentLambda( + app, + "AbTestingDeploymentLambda", + { + stack: "frontend", + stage: "PROD", + env: { + region: "eu-west-1", + }, + }, + ); + const template = Template.fromStack(stack); + assert.snapshot(template.toJSON()); + }); +}); diff --git a/ab-testing/cdk/lib/deploymentLambda.ts b/ab-testing/cdk/lib/deploymentLambda.ts new file mode 100644 index 00000000000..2acd2449e09 --- /dev/null +++ b/ab-testing/cdk/lib/deploymentLambda.ts @@ -0,0 +1,59 @@ +import type { GuStackProps } from "@guardian/cdk/lib/constructs/core/stack.js"; +import { GuStack } from "@guardian/cdk/lib/constructs/core/stack.js"; +import { GuLambdaFunction } from "@guardian/cdk/lib/constructs/lambda/index.js"; +import { GuS3Bucket } from "@guardian/cdk/lib/constructs/s3/index.js"; +import type { App } from "aws-cdk-lib"; +import { Runtime } from "aws-cdk-lib/aws-lambda"; +import { StringParameter } from "aws-cdk-lib/aws-ssm"; + +export const lambdaFunctionName = "ab-testing-deployment-lambda"; + +export class AbTestingDeploymentLambda extends GuStack { + constructor(scope: App, id: string, props: GuStackProps) { + super(scope, id, props); + + const s3Bucket = GuS3Bucket.fromBucketName( + this, + "DictionaryDeployBucket", + StringParameter.valueForStringParameter( + this, + `/account/services/dotcom-store.bucket`, + ), + ); + + const fastlyApiKeyParameter = + StringParameter.fromSecureStringParameterAttributes( + this, + "FastlyApiKeyParameter", + { + parameterName: `/ab-testing/${this.stage}/fastly-api-token`, + }, + ); + + const fastlyConfigParameter = + StringParameter.fromSecureStringParameterAttributes( + this, + "FastlyAbTestingConfigParameter", + { + parameterName: `/ab-testing/${this.stage}/fastly-config`, + }, + ); + + const lambda = new GuLambdaFunction(this, "AbTestingDeploymentLambda", { + functionName: `${lambdaFunctionName}-${this.stage}`, + fileName: "lambda.zip", + handler: "index.handler", + app: lambdaFunctionName, + runtime: Runtime.NODEJS_22_X, + memorySize: 256, + environment: { + STAGE: this.stage, + ARTIFACT_BUCKET_NAME: s3Bucket.bucketName, + }, + }); + + s3Bucket.grantRead(lambda); + fastlyApiKeyParameter.grantRead(lambda); + fastlyConfigParameter.grantRead(lambda); + } +} diff --git a/ab-testing/cdk/package.json b/ab-testing/cdk/package.json new file mode 100644 index 00000000000..1e95063fb31 --- /dev/null +++ b/ab-testing/cdk/package.json @@ -0,0 +1,38 @@ +{ + "name": "@guardian/ab-testing-cdk", + "version": "1.0.0", + "description": "CDK stacks for AB testing infrastructure", + "main": "config/index.ts", + "type": "module", + "scripts": { + "test": "node --test --test-reporter spec cdk/*/*.test.ts", + "test-update": "node --test --test-reporter spec --test-update-snapshots cdk/*/*.test.ts", + "synth:ab-testing-config": "cdk synth --path-metadata false --version-reporting false --app 'node bin/ab-testing-config.cdk.ts' --output ./cdk.out/ab-testing-config", + "synth:deployment-lambda": "cdk synth --path-metadata false --version-reporting false --app 'node bin/deployment-lambda.cdk.ts' --output ./cdk.out/deployment-lambda", + "lint": "eslint .", + "prettier:check": "prettier . --check --cache", + "prettier:fix": "prettier . --write --cache", + "lint-staged": "lint-staged" + }, + "dependencies": {}, + "lint-staged": { + "*.ts": [ + "pnpm lint --fix", + "pnpm prettier:fix" + ] + }, + "devDependencies": { + "@aws-sdk/client-s3": "3.931.0", + "@aws-sdk/client-ssm": "3.621.0", + "@guardian/cdk": "62.0.1", + "@guardian/eslint-config": "12.0.1", + "@guardian/tsconfig": "1.0.1", + "@types/node": "22.17.0", + "aws-cdk": "2.1030.0", + "aws-cdk-lib": "2.220.0", + "eslint": "9.39.1", + "prettier": "3.0.3", + "source-map-support": "0.5.21", + "typescript": "5.9.3" + } +} diff --git a/ab-testing/cdk/tsconfig.json b/ab-testing/cdk/tsconfig.json new file mode 100644 index 00000000000..3a84c85996f --- /dev/null +++ b/ab-testing/cdk/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "@guardian/tsconfig/tsconfig.json", + "compilerOptions": { + "noEmit": true, + "skipLibCheck": true, + "allowImportingTsExtensions": true, + "moduleResolution": "nodenext", + "module": "nodenext" + }, + "exclude": ["node_modules"] +} diff --git a/ab-testing/abTests.ts b/ab-testing/config/abTests.ts similarity index 100% rename from ab-testing/abTests.ts rename to ab-testing/config/abTests.ts diff --git a/ab-testing/index.ts b/ab-testing/config/index.ts similarity index 100% rename from ab-testing/index.ts rename to ab-testing/config/index.ts diff --git a/ab-testing/scripts/lib/config.ts b/ab-testing/config/lib/config.ts similarity index 51% rename from ab-testing/scripts/lib/config.ts rename to ab-testing/config/lib/config.ts index dc972c5a66f..6a6359ac4b1 100644 --- a/ab-testing/scripts/lib/config.ts +++ b/ab-testing/config/lib/config.ts @@ -17,27 +17,15 @@ const configStruct = object({ abTestsDictionaryName: string(), }); -const config = JSON.parse(getEnv("FASTLY_AB_TESTING_CONFIG")) as unknown; +const getConfigFromEnv = () => { + const config = JSON.parse(getEnv("FASTLY_AB_TESTING_CONFIG")) as unknown; + assert(config, configStruct); -const apiToken = getEnv("FASTLY_API_TOKEN"); - -assert(config, configStruct); - -const { - serviceName, - serviceId, - mvtDictionaryId, - mvtDictionaryName, - abTestsDictionaryId, - abTestsDictionaryName, -} = config; - -export { - apiToken, - serviceName, - serviceId, - mvtDictionaryId, - mvtDictionaryName, - abTestsDictionaryId, - abTestsDictionaryName, + return config; }; +const getApiTokenFromEnv = () => { + const apiToken = getEnv("FASTLY_API_TOKEN"); + return apiToken; +}; + +export { getConfigFromEnv, getApiTokenFromEnv, getEnv, configStruct }; diff --git a/ab-testing/scripts/lib/constants.ts b/ab-testing/config/lib/constants.ts similarity index 100% rename from ab-testing/scripts/lib/constants.ts rename to ab-testing/config/lib/constants.ts diff --git a/ab-testing/scripts/lib/fastly-subfield.test.ts b/ab-testing/config/lib/fastly-subfield.test.ts similarity index 100% rename from ab-testing/scripts/lib/fastly-subfield.test.ts rename to ab-testing/config/lib/fastly-subfield.test.ts diff --git a/ab-testing/scripts/lib/fastly-subfield.ts b/ab-testing/config/lib/fastly-subfield.ts similarity index 100% rename from ab-testing/scripts/lib/fastly-subfield.ts rename to ab-testing/config/lib/fastly-subfield.ts diff --git a/ab-testing/config/lib/fastly/client.test.ts b/ab-testing/config/lib/fastly/client.test.ts new file mode 100644 index 00000000000..153ee44db21 --- /dev/null +++ b/ab-testing/config/lib/fastly/client.test.ts @@ -0,0 +1,274 @@ +import { deepEqual, equal, match, rejects } from "node:assert"; +import type { Mock } from "node:test"; +import test, { describe, mock } from "node:test"; +import { FastlyClient } from "./client.ts"; + +type MockedFetch = Mock; + +function mockFetch(response: unknown, status = 200, statusText = "OK") { + const mockResponse = new Response(JSON.stringify(response), { + status, + statusText, + headers: { "Content-Type": "application/json" }, + }); + + globalThis.fetch = mock.fn(async () => Promise.resolve(mockResponse)); +} + +describe("FastlyClient", async () => { + await test("fetch - successfully fetches data", async () => { + const mockResponse = { data: "test" }; + mockFetch(mockResponse); + + const client = new FastlyClient("test-api-token"); + const result = await client.fetch("test-endpoint"); + + deepEqual(result, mockResponse); + equal((globalThis.fetch as MockedFetch).mock.calls.length, 1); + }); + + await test("fetch - throws error on fetch failure", async () => { + mockFetch( + { error: "Something went wrong" }, + 500, + "Internal Server Error", + ); + + const client = new FastlyClient("test-api-token"); + + await rejects( + async () => { + await client.fetch("test-endpoint"); + }, + Error, + "Failed to fetch from Fastly: 500", + ); + }); + + await test("getService - returns service config", async () => { + const mockResponse = { + id: "service-123", + name: "test-service", + versions: [ + { active: false, number: 1 }, + { active: true, number: 2 }, + ], + }; + mockFetch(mockResponse); + + const client = new FastlyClient("test-api-token"); + const result = await client.getService("service-123", "test-service"); + + deepEqual(result, { + id: "service-123", + name: "test-service", + activeVersion: 2, + client, + }); + }); + + await test("getService - throws error when service name doesn't match", async () => { + const mockResponse = { + id: "service-123", + name: "wrong-service", + versions: [{ active: true, number: 1 }], + }; + mockFetch(mockResponse); + + const client = new FastlyClient("test-api-token"); + + await rejects( + async () => { + await client.getService("service-123", "test-service"); + }, + Error, + "Service ID service-123 does not match the expected service name test-service", + ); + }); + + await test("getService - throws error when no active version found", async () => { + const mockResponse = { + id: "service-123", + name: "test-service", + versions: [{ active: false, number: 1 }], + }; + mockFetch(mockResponse); + + const client = new FastlyClient("test-api-token"); + + await rejects( + async () => { + await client.getService("service-123", "test-service"); + }, + Error, + "No active version found for service test-service", + ); + }); + + await test("getDictionary - returns dictionary config", async () => { + const mockResponse = { + id: "dict-123", + name: "test-dictionary", + }; + mockFetch(mockResponse); + + const client = new FastlyClient("test-api-token"); + const result = await client.getDictionary({ + activeVersion: 1, + dictionaryName: "test-dictionary", + serviceId: "service-123", + }); + + deepEqual(result, mockResponse); + match( + (globalThis.fetch as MockedFetch).mock.calls[0] + ?.arguments[0] as string, + /service-123\/version\/1\/dictionary\/test-dictionary/, + ); + }); + + await test("getDictionaryItems - fetches and returns dictionary items", async () => { + const mockResponse = [ + { + service_id: "test-service", + item_key: "key1", + item_value: "value1", + dictionary_id: "test-dict", + created_at: "2023-01-01", + updated_at: "2023-01-01", + deleted_at: null, + }, + ]; + + mockFetch(mockResponse); + + const client = new FastlyClient("test-api-token"); + const result = await client.getDictionaryItems({ + dictionaryId: "test-dict", + serviceId: "service-123", + }); + + deepEqual(result, mockResponse); + equal((globalThis.fetch as MockedFetch).mock.calls.length, 1); + match( + (globalThis.fetch as MockedFetch).mock.calls[0] + ?.arguments[0] as string, + /dictionary\/test-dict\/items\?per_page=1000/, + ); + }); + + await test("getDictionaryItems - throws error on invalid response", async () => { + // Mock invalid response format + mockFetch("not an array"); + + const client = new FastlyClient("test-api-token"); + + await rejects( + async () => { + await client.getDictionaryItems({ + dictionaryId: "test-dict", + serviceId: "service-123", + }); + }, + Error, + "Expected an array", + ); + }); + + await test("updateDictionaryItems - makes PATCH request with correct data", async () => { + mockFetch({ status: "ok" }); + + const client = new FastlyClient("test-api-token"); + const items = [ + { item_key: "key1", item_value: "value1", op: "create" as const }, + ]; + await client.updateDictionaryItems({ + dictionaryId: "dict-123", + serviceId: "service-123", + items, + }); + + equal((globalThis.fetch as MockedFetch).mock.calls.length, 1); + equal( + (globalThis.fetch as MockedFetch).mock.calls[0]?.arguments[1] + ?.method, + "PATCH", + ); + + const requestBody = JSON.parse( + (globalThis.fetch as MockedFetch).mock.calls[0]?.arguments[1] + ?.body as string, + ) as { + items: Array<{ + item_key: string; + item_value: string; + op: "create" | "update" | "delete"; + }>; + }; + + deepEqual(requestBody.items, items); + }); + + await test("updateDictionaryItems - throws error on non-ok status", async () => { + mockFetch({ status: "error" }); + + const client = new FastlyClient("test-api-token"); + const items = [ + { item_key: "key1", item_value: "value1", op: "create" as const }, + ]; + + await rejects( + async () => { + await client.updateDictionaryItems({ + dictionaryId: "dict-123", + serviceId: "service-123", + items, + }); + }, + Error, + "Failed to update dictionary: error", + ); + }); + + await test("verifyDictionaryName - succeeds when IDs match", async () => { + const mockResponse = { + id: "dict-123", + name: "test-dictionary", + }; + mockFetch(mockResponse); + + const client = new FastlyClient("test-api-token"); + await client.verifyDictionaryName({ + serviceId: "service-123", + activeVersion: 1, + dictionaryName: "test-dictionary", + dictionaryId: "dict-123", + }); + + // No error thrown means success + equal((globalThis.fetch as MockedFetch).mock.calls.length, 1); + }); + + await test("verifyDictionaryName - throws error when IDs don't match", async () => { + const mockResponse = { + id: "dict-456", + name: "test-dictionary", + }; + mockFetch(mockResponse); + + const client = new FastlyClient("test-api-token"); + + await rejects( + async () => { + await client.verifyDictionaryName({ + serviceId: "service-123", + activeVersion: 1, + dictionaryName: "test-dictionary", + dictionaryId: "dict-123", + }); + }, + Error, + "Dictionary ID dict-123 does not match the expected dictionary test-dictionary", + ); + }); +}); diff --git a/ab-testing/config/lib/fastly/client.ts b/ab-testing/config/lib/fastly/client.ts new file mode 100644 index 00000000000..b946434a10a --- /dev/null +++ b/ab-testing/config/lib/fastly/client.ts @@ -0,0 +1,228 @@ +import { + array, + assert, + boolean, + nullable, + number, + object, + string, + type, +} from "superstruct"; +import { FastlyService } from "./service.ts"; + +const dictionaryItemStruct = object({ + service_id: string(), + item_key: string(), + item_value: string(), + dictionary_id: string(), + created_at: string(), + updated_at: string(), + deleted_at: nullable(string()), +}); + +export type DictionaryItem = { + service_id: string; + item_key: string; + item_value: string; + dictionary_id: string; + created_at: string; + updated_at: string; + deleted_at: string | null; +}; + +export type UpdateDictionaryItemRequest = + | { + item_key: string; + item_value: string; + op: "create" | "update" | "upsert"; + } + | { + item_key: string; + op: "delete"; + }; + +export type ServiceConfig = { + id: string; + name: string; + activeVersion: number; +}; + +export class FastlyClient { + apiToken: string; + baseUrl: string = "https://api.fastly.com/service"; + + constructor(apiToken: string, baseUrl?: string) { + this.apiToken = apiToken; + if (baseUrl) { + this.baseUrl = baseUrl; + } + } + /** + * Fetch data from Fastly API + * We're using fetch instead of the Fastly API client as it doesn't play nicely with Deno, nor is it typed + * + * @param url - The URL to fetch + * @param options - Fetch options + * @returns The parsed JSON response + * @throws Error if the response is not ok or if the response cannot be parsed + */ + async fetch(url: string, options: RequestInit = {}): Promise { + const response = await fetch(`${this.baseUrl}/${url}`, { + ...options, + headers: { + ...options.headers, + "Fastly-Key": this.apiToken, + }, + }); + if (!response.ok) { + console.error(await response.text()); + throw new Error( + `Failed to fetch from Fastly: ${response.status} ${response.statusText}`, + ); + } + const data = (await response.json()) as unknown; + if (!data) { + throw new Error(`Failed to parse response from Fastly`); + } + return data as T; + } + + async getService( + serviceId: string, + serviceName: string, + ): Promise { + const serviceConfig = await this.fetch(serviceId); + + assert( + serviceConfig, + type({ + id: string(), + name: string(), + versions: array( + type({ + active: boolean(), + number: number(), + }), + ), + }), + ); + + if (serviceConfig.name !== serviceName) { + throw new Error( + `Service with ID ${serviceId} does not match the expected service name ${serviceName}`, + ); + } + + const activeVersion = serviceConfig.versions.find( + (v: { active: boolean }) => v.active, + ); + + if (!activeVersion) { + throw new Error( + `No active version found for service ${serviceConfig.name}`, + ); + } + + return new FastlyService(this, { + id: serviceConfig.id, + name: serviceConfig.name, + activeVersion: activeVersion.number, + }); + } + + async getDictionary({ + activeVersion, + dictionaryName, + serviceId, + }: { + activeVersion: number; + dictionaryName: string; + serviceId: string; + }): Promise<{ id: string; name: string }> { + const dictionary = await this.fetch( + `${serviceId}/version/${activeVersion}/dictionary/${dictionaryName}`, + ); + assert(dictionary, type({ id: string(), name: string() })); + + return dictionary; + } + + async getDictionaryItems({ + dictionaryId, + serviceId, + }: { + dictionaryId: string; + serviceId: string; + }): Promise { + const dictionary = await this.fetch( + `${serviceId}/dictionary/${dictionaryId}/items?per_page=1000`, + ); + + assert(dictionary, array(dictionaryItemStruct)); + + return dictionary; + } + + async updateDictionaryItems({ + dictionaryId, + serviceId, + items, + }: { + dictionaryId: string; + serviceId: string; + items: UpdateDictionaryItemRequest[]; + }): Promise<{ status: string }> { + const dictionary = await this.fetch( + `${serviceId}/dictionary/${dictionaryId}/items`, + { + method: "PATCH", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + service_id: serviceId, + dictionary_id: dictionaryId, + items, + }), + }, + ); + + assert(dictionary, object({ status: string() })); + if (dictionary.status !== "ok") { + throw new Error( + `Failed to update dictionary: ${dictionary.status}`, + ); + } + return dictionary; + } + + /** + * Verify that the service and dictionary names match the expected IDs + * + */ + async verifyDictionaryName({ + serviceId, + activeVersion, + dictionaryName, + dictionaryId, + }: { + serviceId: string; + activeVersion: number; + dictionaryName: string; + dictionaryId: string; + }) { + const dictionary = await this.getDictionary({ + serviceId, + activeVersion, + dictionaryName, + }); + + if (dictionary.id !== dictionaryId) { + throw new Error( + `Dictionary ID ${dictionaryId} does not match the expected dictionary ${dictionaryName}`, + ); + } + + return; + } +} diff --git a/ab-testing/config/lib/fastly/dictionary.test.ts b/ab-testing/config/lib/fastly/dictionary.test.ts new file mode 100644 index 00000000000..cf3f2b4bcd7 --- /dev/null +++ b/ab-testing/config/lib/fastly/dictionary.test.ts @@ -0,0 +1,72 @@ +import { deepEqual, equal } from "node:assert"; +import type { Mock } from "node:test"; +import test, { describe, mock } from "node:test"; +import { FastlyClient } from "./client.ts"; +import { FastlyDictionary } from "./dictionary.ts"; +import { FastlyService } from "./service.ts"; + +type MockedFetch = Mock; + +function mockFetch(response: unknown, status = 200, statusText = "OK") { + const mockResponse = new Response(JSON.stringify(response), { + status, + statusText, + headers: { "Content-Type": "application/json" }, + }); + + globalThis.fetch = mock.fn(async () => Promise.resolve(mockResponse)); +} + +describe("FastlyDictionary", async () => { + await test("getItems - calls service.getDictionaryItems", async () => { + const mockResponse = [ + { + service_id: "test-service", + item_key: "key1", + item_value: "value1", + dictionary_id: "dict-123", + created_at: "2023-01-01", + updated_at: "2023-01-01", + deleted_at: null, + }, + ]; + mockFetch(mockResponse); + + const client = new FastlyClient("test-api-token"); + const service = new FastlyService(client, { + id: "service-123", + name: "test-service", + activeVersion: 1, + }); + const dictionary = new FastlyDictionary(service, { + id: "dict-123", + name: "test-dictionary", + }); + + const items = await dictionary.getItems(); + + deepEqual(items, mockResponse); + }); + + await test("updateItems - calls service.updateDictionaryItems", async () => { + mockFetch({ status: "ok" }); + + const client = new FastlyClient("test-api-token"); + const service = new FastlyService(client, { + id: "service-123", + name: "test-service", + activeVersion: 1, + }); + const dictionary = new FastlyDictionary(service, { + id: "dict-123", + name: "test-dictionary", + }); + + const items = [ + { item_key: "key1", item_value: "value1", op: "create" as const }, + ]; + await dictionary.updateItems(items); + + equal((globalThis.fetch as MockedFetch).mock.calls.length, 1); + }); +}); diff --git a/ab-testing/config/lib/fastly/dictionary.ts b/ab-testing/config/lib/fastly/dictionary.ts new file mode 100644 index 00000000000..fa11a7c22a5 --- /dev/null +++ b/ab-testing/config/lib/fastly/dictionary.ts @@ -0,0 +1,25 @@ +import type { UpdateDictionaryItemRequest } from "./client.ts"; +import type { FastlyService } from "./service.ts"; + +export class FastlyDictionary { + id: string; + name: string; + service: FastlyService; + + constructor( + service: FastlyService, + { id, name }: { id: string; name: string }, + ) { + this.service = service; + this.id = id; + this.name = name; + } + + async getItems() { + return this.service.getDictionaryItems(this.id); + } + + async updateItems(items: UpdateDictionaryItemRequest[]) { + return this.service.updateDictionaryItems(this.id, items); + } +} diff --git a/ab-testing/config/lib/fastly/service.test.ts b/ab-testing/config/lib/fastly/service.test.ts new file mode 100644 index 00000000000..7b52a5e55d3 --- /dev/null +++ b/ab-testing/config/lib/fastly/service.test.ts @@ -0,0 +1,86 @@ +import { deepEqual, equal } from "node:assert"; +import type { Mock } from "node:test"; +import test, { describe, mock } from "node:test"; +import { FastlyClient } from "./client.ts"; +import { FastlyDictionary } from "./dictionary.ts"; +import { FastlyService } from "./service.ts"; + +type MockedFetch = Mock; + +function mockFetch(response: unknown, status = 200, statusText = "OK") { + const mockResponse = new Response(JSON.stringify(response), { + status, + statusText, + headers: { "Content-Type": "application/json" }, + }); + + globalThis.fetch = mock.fn(async () => Promise.resolve(mockResponse)); +} + +describe("FastlyService", async () => { + await test.only("getDictionary - returns FastlyDictionary instance", async () => { + const mockResponse = { + id: "dict-123", + name: "test-dictionary", + }; + mockFetch(mockResponse); + + const client = new FastlyClient("test-api-token"); + const service = new FastlyService(client, { + id: "service-123", + name: "test-service", + activeVersion: 1, + }); + + const dictionary = await service.getDictionary("test-dictionary"); + + equal(dictionary instanceof FastlyDictionary, true); + equal(dictionary.id, "dict-123"); + equal(dictionary.name, "test-dictionary"); + equal(dictionary.service, service); + }); + + await test("getDictionaryItems - calls client.getDictionaryItems", async () => { + const mockResponse = [ + { + service_id: "test-service", + item_key: "key1", + item_value: "value1", + dictionary_id: "dict-123", + created_at: "2023-01-01", + updated_at: "2023-01-01", + deleted_at: null, + }, + ]; + mockFetch(mockResponse); + + const client = new FastlyClient("test-api-token"); + const service = new FastlyService(client, { + id: "service-123", + name: "test-service", + activeVersion: 1, + }); + + const items = await service.getDictionaryItems("dict-123"); + + deepEqual(items, mockResponse); + }); + + await test("updateDictionaryItems - calls client.updateDictionaryItems", async () => { + mockFetch({ status: "ok" }); + + const client = new FastlyClient("test-api-token"); + const service = new FastlyService(client, { + id: "service-123", + name: "test-service", + activeVersion: 1, + }); + + const items = [ + { item_key: "key1", item_value: "value1", op: "create" as const }, + ]; + await service.updateDictionaryItems("dict-123", items); + + equal((globalThis.fetch as MockedFetch).mock.calls.length, 1); + }); +}); diff --git a/ab-testing/config/lib/fastly/service.ts b/ab-testing/config/lib/fastly/service.ts new file mode 100644 index 00000000000..b41a49f2e69 --- /dev/null +++ b/ab-testing/config/lib/fastly/service.ts @@ -0,0 +1,66 @@ +import type { FastlyClient, UpdateDictionaryItemRequest } from "./client.ts"; +import { FastlyDictionary } from "./dictionary.ts"; + +export class FastlyService { + id: string; + name: string; + activeVersion: number; + client: FastlyClient; + + constructor( + client: FastlyClient, + { + id, + name, + activeVersion, + }: { id: string; name: string; activeVersion: number }, + ) { + this.client = client; + this.id = id; + this.name = name; + this.activeVersion = activeVersion; + } + + async getDictionary(name: string): Promise { + const dictionaryConfig = await this.client.getDictionary({ + activeVersion: this.activeVersion, + dictionaryName: name, + serviceId: this.id, + }); + + return new FastlyDictionary(this, dictionaryConfig); + } + + async getDictionaryItems(dictionaryId: string) { + return this.client.getDictionaryItems({ + dictionaryId, + serviceId: this.id, + }); + } + + async updateDictionaryItems( + dictionaryId: string, + items: UpdateDictionaryItemRequest[], + ) { + return this.client.updateDictionaryItems({ + dictionaryId, + serviceId: this.id, + items, + }); + } + + async verifyDictionaryName({ + dictionaryName, + dictionaryId, + }: { + dictionaryName: string; + dictionaryId: string; + }) { + return this.client.verifyDictionaryName({ + serviceId: this.id, + activeVersion: this.activeVersion, + dictionaryName, + dictionaryId, + }); + } +} diff --git a/ab-testing/config/lib/fastly/utils.test.ts b/ab-testing/config/lib/fastly/utils.test.ts new file mode 100644 index 00000000000..6b2d08bf6cd --- /dev/null +++ b/ab-testing/config/lib/fastly/utils.test.ts @@ -0,0 +1,132 @@ +import { deepEqual, equal } from "node:assert"; +import test from "node:test"; +import { calculateUpdates, encodeObject } from "./utils.ts"; + +test("calculateUpdates - creates new items", () => { + const currentDictionary: Array<{ item_key: string; item_value: string }> = + []; + const newDictionary = [ + { item_key: "test1", item_value: "value1" }, + { item_key: "test2", item_value: "value2" }, + ]; + + const result = calculateUpdates(newDictionary, currentDictionary); + + equal(result.length, 2); + deepEqual(result[0], { + item_key: "test1", + item_value: "value1", + op: "create", + }); + deepEqual(result[1], { + item_key: "test2", + item_value: "value2", + op: "create", + }); +}); + +test("calculateUpdates - updates existing items", () => { + const currentDictionary = [ + { item_key: "test1", item_value: "old_value1" }, + { item_key: "test2", item_value: "value2" }, + ]; + const newDictionary = [ + { item_key: "test1", item_value: "new_value1" }, + { item_key: "test2", item_value: "value2" }, + ]; + + const result = calculateUpdates(newDictionary, currentDictionary); + + equal(result.length, 1); + deepEqual(result[0], { + item_key: "test1", + item_value: "new_value1", + op: "update", + }); +}); + +test("calculateUpdates - deletes removed items", () => { + const currentDictionary = [ + { item_key: "test1", item_value: "value1" }, + { item_key: "test2", item_value: "value2" }, + ]; + const newDictionary = [{ item_key: "test1", item_value: "value1" }]; + + const result = calculateUpdates(newDictionary, currentDictionary); + + equal(result.length, 1); + deepEqual(result[0], { + item_key: "test2", + op: "delete", + }); +}); + +test("calculateUpdates - no changes needed", () => { + const currentDictionary = [ + { item_key: "test1", item_value: "value1" }, + { item_key: "test2", item_value: "value2" }, + ]; + const newDictionary = [ + { item_key: "test1", item_value: "value1" }, + { item_key: "test2", item_value: "value2" }, + ]; + + const result = calculateUpdates(newDictionary, currentDictionary); + + equal(result.length, 0); +}); + +test("calculateUpdates - combination of operations", () => { + const currentDictionary = [ + { item_key: "keep", item_value: "same_value" }, + { item_key: "update", item_value: "old_value" }, + { item_key: "delete", item_value: "will_be_deleted" }, + ]; + const newDictionary = [ + { item_key: "keep", item_value: "same_value" }, + { item_key: "update", item_value: "new_value" }, + { item_key: "create", item_value: "new_item" }, + ]; + + const result = calculateUpdates(newDictionary, currentDictionary); + + equal(result.length, 3); + + const deleteOp = result.find((op) => op.op === "delete"); + deepEqual(deleteOp, { + item_key: "delete", + op: "delete", + }); + + const updateOp = result.find((op) => op.op === "update"); + deepEqual(updateOp, { + item_key: "update", + item_value: "new_value", + op: "update", + }); + + const createOp = result.find((op) => op.op === "create"); + deepEqual(createOp, { + item_key: "create", + item_value: "new_item", + op: "create", + }); +}); + +test("encodeObject - encodes object to string", () => { + const obj = { + test: "value", + another: 123, + bool: true, + }; + + const result = encodeObject(obj); + equal(result, "test=value,another=123,bool=true"); +}); + +test("encodeObject - handles arrays", () => { + const arr = ["test", "another"]; + + const result = encodeObject(arr); + equal(result, "0=test,1=another"); +}); diff --git a/ab-testing/config/lib/fastly/utils.ts b/ab-testing/config/lib/fastly/utils.ts new file mode 100644 index 00000000000..c119027ae4c --- /dev/null +++ b/ab-testing/config/lib/fastly/utils.ts @@ -0,0 +1,89 @@ +import type { UpdateDictionaryItemRequest } from "./client.ts"; + +/** + * Calculate the bulk updates for a dictionary + * Compare the new dictionary with the current dictionary and return the operations required + * + * @param updatedDictionary + * @param currentDictionary + * @returns + */ +export const calculateUpdates = ( + updatedDictionary: Array<{ + item_key: string; + item_value: string; + }>, + currentDictionary: Array<{ + item_key: string; + item_value: string; + }>, +): UpdateDictionaryItemRequest[] => { + const currentDictionaryKeys = new Set( + currentDictionary.map((group) => group.item_key), + ); + + const updateDeleteOps = currentDictionary.reduce<{ + updates: UpdateDictionaryItemRequest[]; + deletes: UpdateDictionaryItemRequest[]; + }>( + (ops, group) => { + const updatedGroup = updatedDictionary.find( + (newGroup) => newGroup.item_key === group.item_key, + ); + + if (!updatedGroup) { + return { + ...ops, + deletes: [ + ...ops.deletes, + { + item_key: group.item_key, + op: "delete", + }, + ], + }; + } + + if (group.item_value !== updatedGroup.item_value) { + return { + ...ops, + updates: [ + ...ops.updates, + { + item_key: group.item_key, + item_value: updatedGroup.item_value, + op: "update", + }, + ], + }; + } + + return ops; + }, + { + updates: [], + deletes: [], + }, + ); + + const createOpts: UpdateDictionaryItemRequest[] = updatedDictionary + .filter((group) => !currentDictionaryKeys.has(group.item_key)) + .map(({ item_key, item_value }) => ({ + item_key, + item_value, + op: "create", + })); + + const bulkUpdates = [ + ...updateDeleteOps.deletes, + ...updateDeleteOps.updates, + ...createOpts, + ]; + + return bulkUpdates; +}; + +export const encodeObject = (obj: Record | string[]) => + Object.entries(obj) + .map(([key, value]) => `${key}=${String(value)}`) + .join(","); diff --git a/ab-testing/scripts/lib/types.ts b/ab-testing/config/lib/types.ts similarity index 100% rename from ab-testing/scripts/lib/types.ts rename to ab-testing/config/lib/types.ts diff --git a/ab-testing/package.json b/ab-testing/config/package.json similarity index 60% rename from ab-testing/package.json rename to ab-testing/config/package.json index 2023d407d3c..b7ad40564f3 100644 --- a/ab-testing/package.json +++ b/ab-testing/config/package.json @@ -1,5 +1,5 @@ { - "name": "@guardian/ab-testing", + "name": "@guardian/ab-testing-config", "version": "1.0.0", "description": "A/B test definitions and configuration", "main": "index.ts", @@ -8,21 +8,33 @@ "validate": "node scripts/validation/index.ts", "deploy": "node scripts/deploy/index.ts --mvts=dist/mvts.json --ab-tests=dist/ab-tests.json", "build": "node scripts/build/index.ts --mvts=dist/mvts.json --ab-tests=dist/ab-tests.json", - "build-ui": "pnpm --filter @guardian/ab-testing-frontend run build", - "test": "node --test", + "test": "node --test --test-reporter spec ./**/*.test.ts", "lint": "eslint .", "prettier:check": "prettier . --check --cache", - "prettier:fix": "prettier . --write --cache" + "prettier:fix": "prettier . --write --cache", + "lint-staged": "lint-staged" }, "dependencies": { "superstruct": "2.0.2" }, + "lint-staged": { + "*.ts": [ + "pnpm lint --fix", + "pnpm prettier:fix" + ] + }, "devDependencies": { + "@aws-sdk/client-s3": "3.931.0", + "@aws-sdk/client-ssm": "3.621.0", + "@guardian/cdk": "62.0.1", "@guardian/eslint-config": "12.0.1", "@guardian/tsconfig": "1.0.1", "@types/node": "22.17.0", + "aws-cdk": "2.1030.0", + "aws-cdk-lib": "2.220.0", "eslint": "9.39.1", "prettier": "3.0.3", + "source-map-support": "0.5.21", "typescript": "5.9.3" } } diff --git a/ab-testing/scripts/build/build-ab-tests-dict.ts b/ab-testing/config/scripts/build/build-ab-tests-dict.ts similarity index 84% rename from ab-testing/scripts/build/build-ab-tests-dict.ts rename to ab-testing/config/scripts/build/build-ab-tests-dict.ts index 9c56e3493f8..036959112cf 100644 --- a/ab-testing/scripts/build/build-ab-tests-dict.ts +++ b/ab-testing/config/scripts/build/build-ab-tests-dict.ts @@ -1,5 +1,5 @@ +import { stringifyFastlySubfield } from "../../lib/fastly-subfield.ts"; import type { ABTest } from "../../types.ts"; -import { stringifyFastlySubfield } from "../lib/fastly-subfield.ts"; const buildABTestGroupKeyValues = (tests: ABTest[]) => tests.flatMap((test) => diff --git a/ab-testing/scripts/build/calculate-mvt-updates.test.ts b/ab-testing/config/scripts/build/calculate-mvt-updates.test.ts similarity index 99% rename from ab-testing/scripts/build/calculate-mvt-updates.test.ts rename to ab-testing/config/scripts/build/calculate-mvt-updates.test.ts index c2a905a56a5..b19fe0ac74a 100644 --- a/ab-testing/scripts/build/calculate-mvt-updates.test.ts +++ b/ab-testing/config/scripts/build/calculate-mvt-updates.test.ts @@ -1,11 +1,11 @@ import { deepEqual, equal, throws } from "node:assert"; import { test } from "node:test"; -import type { ABTest } from "../../types.ts"; import type { AllSpace, AudienceSpace, FastlyTestParams, -} from "../lib/types.ts"; +} from "../../lib/types.ts"; +import type { ABTest } from "../../types.ts"; import { calculateAllSpaceUpdates, calculateSpaceUpdates, diff --git a/ab-testing/scripts/build/calculate-mvt-updates.ts b/ab-testing/config/scripts/build/calculate-mvt-updates.ts similarity index 96% rename from ab-testing/scripts/build/calculate-mvt-updates.ts rename to ab-testing/config/scripts/build/calculate-mvt-updates.ts index 40aca5581a6..ba0b1c35a28 100644 --- a/ab-testing/scripts/build/calculate-mvt-updates.ts +++ b/ab-testing/config/scripts/build/calculate-mvt-updates.ts @@ -1,10 +1,10 @@ -import type { ABTest } from "../../types.ts"; -import { AUDIENCE_SPACES, MVT_COUNT } from "../lib/constants.ts"; +import { AUDIENCE_SPACES, MVT_COUNT } from "../../lib/constants.ts"; import type { AllSpace, AudienceSpace, FastlyTestParams, -} from "../lib/types.ts"; +} from "../../lib/types.ts"; +import type { ABTest } from "../../types.ts"; import { TestGroupMVTManager } from "./test-group-mvt-manager.ts"; const getTestGroupName = ( diff --git a/ab-testing/scripts/build/index.ts b/ab-testing/config/scripts/build/index.ts similarity index 71% rename from ab-testing/scripts/build/index.ts rename to ab-testing/config/scripts/build/index.ts index e97db9d42b7..4f4f1800688 100644 --- a/ab-testing/scripts/build/index.ts +++ b/ab-testing/config/scripts/build/index.ts @@ -2,8 +2,9 @@ import { mkdir, writeFile } from "node:fs/promises"; import { dirname } from "node:path"; import { parseArgs } from "node:util"; import { activeABtests } from "../../abTests.ts"; -import { getMVTGroupsFromDictionary } from "../lib/fastly-api.ts"; -import { parseMVTValue, stringifyMVTValue } from "../lib/fastly-subfield.ts"; +import { getApiTokenFromEnv, getConfigFromEnv } from "../../lib/config.ts"; +import { FastlyClient } from "../../lib/fastly/client.ts"; +import { parseMVTValue, stringifyMVTValue } from "../../lib/fastly-subfield.ts"; import { buildABTestGroupKeyValues } from "./build-ab-tests-dict.ts"; import { calculateAllSpaceUpdates } from "./calculate-mvt-updates.ts"; @@ -28,10 +29,18 @@ if (!flags["mvts"] || !flags["ab-tests"]) { process.exit(1); } -const mvtGroupsDictionary = await getMVTGroupsFromDictionary(); +const { serviceId, serviceName, mvtDictionaryName } = getConfigFromEnv(); + +const fastly = new FastlyClient(getApiTokenFromEnv()); + +const service = await fastly.getService(serviceId, serviceName); + +const mvtGroupsDictionary = await service.getDictionary(mvtDictionaryName); + +const mvtGroupsDictionaryItems = await mvtGroupsDictionary.getItems(); const mvtGroups = new Map( - mvtGroupsDictionary.map(({ item_key, item_value }) => { + mvtGroupsDictionaryItems.map(({ item_key, item_value }) => { const testGroups = parseMVTValue(item_value); return [item_key, testGroups]; }), diff --git a/ab-testing/scripts/build/test-group-mvt-manager.test.ts b/ab-testing/config/scripts/build/test-group-mvt-manager.test.ts similarity index 99% rename from ab-testing/scripts/build/test-group-mvt-manager.test.ts rename to ab-testing/config/scripts/build/test-group-mvt-manager.test.ts index 004c61c5622..a87909c77d5 100644 --- a/ab-testing/scripts/build/test-group-mvt-manager.test.ts +++ b/ab-testing/config/scripts/build/test-group-mvt-manager.test.ts @@ -1,6 +1,6 @@ import { deepEqual, equal, throws } from "node:assert"; import test from "node:test"; -import type { AudienceSpace } from "../lib/types.ts"; +import type { AudienceSpace } from "../../lib/types.ts"; import { TestGroupMVTManager } from "./test-group-mvt-manager.ts"; // Helper function to create mock AudienceSpace diff --git a/ab-testing/scripts/build/test-group-mvt-manager.ts b/ab-testing/config/scripts/build/test-group-mvt-manager.ts similarity index 97% rename from ab-testing/scripts/build/test-group-mvt-manager.ts rename to ab-testing/config/scripts/build/test-group-mvt-manager.ts index 37aa5f2e49d..296fff1cd78 100644 --- a/ab-testing/scripts/build/test-group-mvt-manager.ts +++ b/ab-testing/config/scripts/build/test-group-mvt-manager.ts @@ -1,5 +1,5 @@ -import { MVT_COUNT } from "../lib/constants.ts"; -import type { AudienceSpace } from "../lib/types.ts"; +import { MVT_COUNT } from "../../lib/constants.ts"; +import type { AudienceSpace } from "../../lib/types.ts"; /** * A class to manage MVTs for test groups in a test space. diff --git a/ab-testing/scripts/validation/enoughSpace.test.ts b/ab-testing/config/scripts/validation/enoughSpace.test.ts similarity index 100% rename from ab-testing/scripts/validation/enoughSpace.test.ts rename to ab-testing/config/scripts/validation/enoughSpace.test.ts diff --git a/ab-testing/scripts/validation/enoughSpace.ts b/ab-testing/config/scripts/validation/enoughSpace.ts similarity index 100% rename from ab-testing/scripts/validation/enoughSpace.ts rename to ab-testing/config/scripts/validation/enoughSpace.ts diff --git a/ab-testing/scripts/validation/index.ts b/ab-testing/config/scripts/validation/index.ts similarity index 100% rename from ab-testing/scripts/validation/index.ts rename to ab-testing/config/scripts/validation/index.ts diff --git a/ab-testing/scripts/validation/limitServerSide.test.ts b/ab-testing/config/scripts/validation/limitServerSide.test.ts similarity index 95% rename from ab-testing/scripts/validation/limitServerSide.test.ts rename to ab-testing/config/scripts/validation/limitServerSide.test.ts index 5f8a21a5d73..e503c90e774 100644 --- a/ab-testing/scripts/validation/limitServerSide.test.ts +++ b/ab-testing/config/scripts/validation/limitServerSide.test.ts @@ -1,7 +1,7 @@ import { equal, throws } from "node:assert"; import test from "node:test"; +import { MAX_SERVER_SIDE_TESTS } from "../../lib/constants.ts"; import type { ABTest } from "../../types.ts"; -import { MAX_SERVER_SIDE_TESTS } from "../lib/constants.ts"; import { limitServerSideTests } from "./limitServerSide.ts"; test("limitServerSideTests - throws if the amount of tests exceeds the limit", () => { diff --git a/ab-testing/scripts/validation/limitServerSide.ts b/ab-testing/config/scripts/validation/limitServerSide.ts similarity index 83% rename from ab-testing/scripts/validation/limitServerSide.ts rename to ab-testing/config/scripts/validation/limitServerSide.ts index 7ba85bfe2d6..ddb19054961 100644 --- a/ab-testing/scripts/validation/limitServerSide.ts +++ b/ab-testing/config/scripts/validation/limitServerSide.ts @@ -1,5 +1,5 @@ +import { MAX_SERVER_SIDE_TESTS } from "../../lib/constants.ts"; import type { ABTest } from "../../types.ts"; -import { MAX_SERVER_SIDE_TESTS } from "../lib/constants.ts"; export function limitServerSideTests(tests: ABTest[]) { const serverSideTests = tests.filter((test) => test.type === "server"); diff --git a/ab-testing/scripts/validation/uniqueName.test.ts b/ab-testing/config/scripts/validation/uniqueName.test.ts similarity index 100% rename from ab-testing/scripts/validation/uniqueName.test.ts rename to ab-testing/config/scripts/validation/uniqueName.test.ts diff --git a/ab-testing/scripts/validation/uniqueName.ts b/ab-testing/config/scripts/validation/uniqueName.ts similarity index 100% rename from ab-testing/scripts/validation/uniqueName.ts rename to ab-testing/config/scripts/validation/uniqueName.ts diff --git a/ab-testing/scripts/validation/validExpiration.test.ts b/ab-testing/config/scripts/validation/validExpiration.test.ts similarity index 100% rename from ab-testing/scripts/validation/validExpiration.test.ts rename to ab-testing/config/scripts/validation/validExpiration.test.ts diff --git a/ab-testing/scripts/validation/validExpiration.ts b/ab-testing/config/scripts/validation/validExpiration.ts similarity index 100% rename from ab-testing/scripts/validation/validExpiration.ts rename to ab-testing/config/scripts/validation/validExpiration.ts diff --git a/ab-testing/tsconfig.json b/ab-testing/config/tsconfig.json similarity index 100% rename from ab-testing/tsconfig.json rename to ab-testing/config/tsconfig.json diff --git a/ab-testing/types.ts b/ab-testing/config/types.ts similarity index 100% rename from ab-testing/types.ts rename to ab-testing/config/types.ts diff --git a/ab-testing/deploy-lambda/package.json b/ab-testing/deploy-lambda/package.json new file mode 100644 index 00000000000..7891e4517f2 --- /dev/null +++ b/ab-testing/deploy-lambda/package.json @@ -0,0 +1,37 @@ +{ + "name": "@guardian/ab-testing-deploy-lambda", + "version": "1.0.0", + "description": "Lambda that deploys AB test configuration to Fastly edge-dictionaries", + "main": "index.ts", + "type": "module", + "scripts": { + "build": "rollup -c rollup.config.js", + "test": "node --test", + "lint": "eslint .", + "prettier:check": "prettier . --check --cache", + "prettier:fix": "prettier . --write --cache" + }, + "dependencies": { + "@aws-sdk/client-s3": "3.931.0", + "@aws-sdk/client-ssm": "3.621.0", + "superstruct": "2.0.2" + }, + "devDependencies": { + "@guardian/cdk": "62.0.1", + "@guardian/eslint-config": "12.0.1", + "@guardian/tsconfig": "1.0.1", + "@rollup/plugin-commonjs": "29.0.0", + "@rollup/plugin-json": "6.1.0", + "@rollup/plugin-node-resolve": "16.0.3", + "@types/aws-lambda": "8.10.158", + "@types/node": "22.17.0", + "aws-cdk-lib": "2.220.0", + "aws-lambda": "1.0.7", + "esbuild": "0.27.0", + "eslint": "9.39.1", + "prettier": "3.0.3", + "rollup": "4.53.2", + "rollup-plugin-esbuild": "6.2.1", + "typescript": "5.9.3" + } +} diff --git a/ab-testing/deploy-lambda/rollup.config.js b/ab-testing/deploy-lambda/rollup.config.js new file mode 100644 index 00000000000..e607ad43109 --- /dev/null +++ b/ab-testing/deploy-lambda/rollup.config.js @@ -0,0 +1,45 @@ +import commonjs from "@rollup/plugin-commonjs"; +import json from "@rollup/plugin-json"; +import { nodeResolve } from "@rollup/plugin-node-resolve"; +import esbuild from "rollup-plugin-esbuild"; + +/** @type {import('rollup').RollupOptions} */ +const rollupConfig = { + input: `src/index.ts`, + output: { + dir: "dist", + format: "module", + preserveModules: true, + preserveModulesRoot: "src", + sourcemap: true, + entryFileNames: (chunkInfo) => { + if (chunkInfo.name.includes("node_modules")) { + // Simplify node_modules paths, if it's in node_modules without a package.json + // it'll be assumed to be a commonjs module, which is incorrect and causes issues. + return ( + chunkInfo.name.replace( + /node_modules\/\.pnpm\/.*\/node_modules/, + "external", + ) + ".js" + ); + } + + return "[name].js"; + }, + }, + external: ["@aws-sdk/*"], + plugins: [ + commonjs(), + nodeResolve({ + preferBuiltins: true, + exportConditions: ["node"], + resolveOnly: (moduleName) => !moduleName.startsWith("@aws-sdk"), + }), + json(), + esbuild({ + include: /\.[jt]s?$/, + }), + ], +}; + +export default rollupConfig; diff --git a/ab-testing/deploy-lambda/src/custom-resource-response.ts b/ab-testing/deploy-lambda/src/custom-resource-response.ts new file mode 100644 index 00000000000..c4670723775 --- /dev/null +++ b/ab-testing/deploy-lambda/src/custom-resource-response.ts @@ -0,0 +1,56 @@ +import type { CloudFormationCustomResourceEvent, Context } from "aws-lambda"; + +const SUCCESS = "SUCCESS"; +const FAILED = "FAILED"; + +type Status = typeof SUCCESS | typeof FAILED; + +const maskCredentialsAndSignature = (message: string) => { + return message + .replace(/X-Amz-Credential=[^&\s]+/i, "X-Amz-Credential=*****") + .replace(/X-Amz-Signature=[^&\s]+/i, "X-Amz-Signature=*****"); +}; + +// Modernised implementation of cfn-response's send function using fetch +// https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-lambda-function-code-cfnresponsemodule.html +const send = async ( + event: CloudFormationCustomResourceEvent, + context: Context, + responseStatus: Status, + responseData?: unknown, + physicalResourceId?: string, +) => { + const responseBody = JSON.stringify({ + Status: responseStatus, + Reason: + "See the details in CloudWatch Log Stream: " + + context.logStreamName, + PhysicalResourceId: physicalResourceId ?? context.logStreamName, + StackId: event.StackId, + RequestId: event.RequestId, + LogicalResourceId: event.LogicalResourceId, + Data: responseData, + }); + + console.log("Response body:\n", responseBody); + console.log("Sending response to:", event.ResponseURL); + + try { + await fetch(event.ResponseURL, { + method: "PUT", + headers: { + "content-type": "", + }, + body: responseBody, + }); + } catch (error) { + console.log( + "send(..) failed executing fetch: " + + maskCredentialsAndSignature(String(error)), + ); + throw error; + } +}; + +export { send, SUCCESS, FAILED }; +export type { Status }; diff --git a/ab-testing/deploy-lambda/src/deploy-dictionary.ts b/ab-testing/deploy-lambda/src/deploy-dictionary.ts new file mode 100644 index 00000000000..a90f13d96e1 --- /dev/null +++ b/ab-testing/deploy-lambda/src/deploy-dictionary.ts @@ -0,0 +1,39 @@ +import type { FastlyDictionary } from "../../config/lib/fastly/dictionary.ts"; +import { calculateUpdates } from "../../config/lib/fastly/utils.ts"; +import type { KeyValue } from "./fetch-artifact.ts"; + +/** + * Deploys key-value pairs to a Fastly edge dictionary. + * Uses `calculateUpdates` to determine necessary CRUD operations. + * + * @param config Configuration for the dictionary deployment. + * @param keyValues An array of key-value pairs to deploy to the dictionary. + */ +export const deployDictionary = async ( + dictionary: FastlyDictionary, + keyValues: KeyValue[], +) => { + const currentKeyValues = await dictionary.getItems(); + + const updates = calculateUpdates(keyValues, currentKeyValues); + + if (updates.length === 0) { + console.log(`No key-values need updating in '${dictionary.name}'`); + } else { + Map.groupBy(updates, (item) => item.op).forEach((items, op) => { + console.log( + `Performing ${items.length} ${op} operations in '${dictionary.name}'`, + ); + }); + + console.log( + `Performing ${updates.length} total operations in '${dictionary.name}'`, + ); + + const response = await dictionary.updateItems(updates); + + if (response.status !== "ok") { + throw new Error(`Failed to update mvt groups dictionary`); + } + } +}; diff --git a/ab-testing/deploy-lambda/src/deploy.ts b/ab-testing/deploy-lambda/src/deploy.ts new file mode 100644 index 00000000000..16300ed2a22 --- /dev/null +++ b/ab-testing/deploy-lambda/src/deploy.ts @@ -0,0 +1,40 @@ +import { getEnv } from "../../config/lib/config.ts"; +import type { FastlyDictionary } from "../../config/lib/fastly/dictionary.ts"; +import { deployDictionary } from "./deploy-dictionary.ts"; +import { fetchDictionaryArtifact } from "./fetch-artifact.ts"; + +const ARTIFACT_BUCKET_NAME = getEnv("ARTIFACT_BUCKET_NAME"); +const STAGE = getEnv("STAGE"); + +const CONFIG_PREFIX = `${STAGE}/config/ab-testing`; + +type ArtifactInfo = { + artifact: string; + dictionary: FastlyDictionary; +}; + +/** + * Fetches dictionary artifacts from S3 and deploys them to Fastly dictionaries in parallel. + * @param serviceInfo The Fastly service information including active version and service ID. + * @param deployments An array of artifact deployment information. + */ +export const fetchAndDeployArtifacts = async (deployments: ArtifactInfo[]) => { + try { + await Promise.all( + deployments.map(({ artifact, dictionary }) => { + console.log( + `Fetching artifact /${ARTIFACT_BUCKET_NAME}${CONFIG_PREFIX}/${artifact} from S3 and deploying to Fastly dictionary ${dictionary.name}`, + ); + return fetchDictionaryArtifact( + ARTIFACT_BUCKET_NAME, + `${CONFIG_PREFIX}/${artifact}`, + ).then((abTestGroups) => + deployDictionary(dictionary, abTestGroups), + ); + }), + ); + } catch (error) { + console.error("Error in fetchAndDeployArtifacts:", error); + throw error; + } +}; diff --git a/ab-testing/deploy-lambda/src/fetch-artifact.ts b/ab-testing/deploy-lambda/src/fetch-artifact.ts new file mode 100644 index 00000000000..2cf9ecffe63 --- /dev/null +++ b/ab-testing/deploy-lambda/src/fetch-artifact.ts @@ -0,0 +1,51 @@ +import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3"; +import type { Infer } from "superstruct"; +import { array, create, object, string } from "superstruct"; + +const fastlyKVStruct = object({ + item_key: string(), + item_value: string(), +}); + +type KeyValue = Infer; + +/** + * Fetches the dictionary artifact from the given s3 location, using the AWS SDK. + * @param Bucket The S3 bucket name. + * @param Key The S3 object key. + * @returns A promise that resolves to the artifact JSON. + */ +const fetchDictionaryArtifact = async ( + Bucket: string, + Key: string, +): Promise => { + const s3Client = new S3Client({ region: "eu-west-1" }); + + const getObjectCommand = new GetObjectCommand({ + Bucket, + Key, + }); + + try { + const response = await s3Client.send(getObjectCommand); + + if (!response.Body) { + throw new Error("No body found in S3 object response"); + } + + const bodyString = await response.Body.transformToString(); + const parsed = JSON.parse(bodyString) as unknown; + + const result = create(parsed, array(fastlyKVStruct)); + + return result; + } catch (error) { + console.error( + `Failed to fetch artifact from Bucket: ${Bucket}, Key: ${Key}`, + ); + console.error("Error fetching or parsing artifact:", error); + throw error; + } +}; + +export { fetchDictionaryArtifact, type KeyValue }; diff --git a/ab-testing/deploy-lambda/src/index.ts b/ab-testing/deploy-lambda/src/index.ts new file mode 100644 index 00000000000..260ce559615 --- /dev/null +++ b/ab-testing/deploy-lambda/src/index.ts @@ -0,0 +1,87 @@ +import { GetParameterCommand, SSMClient } from "@aws-sdk/client-ssm"; +import type { Handler } from "aws-cdk-lib/aws-lambda"; +import type { CloudFormationCustomResourceEvent, Context } from "aws-lambda"; +import { assert } from "superstruct"; +import { configStruct } from "../../config/lib/config.ts"; +import { FastlyClient } from "../../config/lib/fastly/client.ts"; +import { send } from "./custom-resource-response.ts"; +import { fetchAndDeployArtifacts } from "./deploy.ts"; + +const getSecureString = async (name: string) => { + const ssmClient = new SSMClient({ region: "eu-west-1" }); + + const response = await ssmClient.send( + new GetParameterCommand({ + Name: name, + WithDecryption: true, + }), + ); + return response.Parameter?.Value; +}; + +const getFastlyConfig = async () => { + const stringParam = await getSecureString( + `/ab-testing/${process.env.STAGE}/fastly-config`, + ); + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string is invalid JSON too + const json = JSON.parse(stringParam || "{}") as unknown; + + assert(json, configStruct); + + return json; +}; + +export const handler: Handler = async ( + event: CloudFormationCustomResourceEvent, + context: Context, +): Promise => { + if (event.RequestType === "Delete") { + // No action needed on delete + await send(event, context, "SUCCESS"); + return; + } + try { + const apiToken = await getSecureString( + `/ab-testing/${process.env.STAGE}/fastly-api-token`, + ); + + if (!apiToken) { + throw new Error( + "Fastly API token not found in SSM Parameter Store", + ); + } + + const { + serviceId, + serviceName, + abTestsDictionaryName, + mvtDictionaryName, + } = await getFastlyConfig(); + + const fastly = new FastlyClient(apiToken); + const service = await fastly.getService(serviceId, serviceName); + + const abTestsDictionary = await service.getDictionary( + abTestsDictionaryName, + ); + const mvtDictionary = await service.getDictionary(mvtDictionaryName); + + await fetchAndDeployArtifacts([ + { + artifact: "ab-tests.json", + dictionary: abTestsDictionary, + }, + { + artifact: "mvts.json", + dictionary: mvtDictionary, + }, + ]); + + await send(event, context, "SUCCESS"); + } catch (error) { + console.error("Error deploying dictionaries:", error); + await send(event, context, "FAILED", { + error: (error as Error).message, + }); + } +}; diff --git a/ab-testing/deploy-lambda/src/run.ts b/ab-testing/deploy-lambda/src/run.ts new file mode 100644 index 00000000000..bb58df52e68 --- /dev/null +++ b/ab-testing/deploy-lambda/src/run.ts @@ -0,0 +1,75 @@ +#!/usr/bin/env node +/** + * Run the lambda handler locally using frontend AWS account credentials + * + * Usage: + * STAGE=CODE pnpm tsx src/run.ts + * STAGE=PROD pnpm tsx src/run.ts + * + * Prerequisites: + * - AWS credentials for the frontend account must be configured + * - Use `aws-vault exec frontend -- pnpm tsx src/run.ts` if using aws-vault + */ + +import type { CloudFormationCustomResourceEvent, Context } from "aws-lambda"; +import { handler } from "./index.ts"; + +const stage = process.env.STAGE ?? "CODE"; + +// Create a mock CloudFormation event +const mockEvent: CloudFormationCustomResourceEvent = { + RequestType: "Create", + ServiceToken: + "arn:aws:lambda:eu-west-1:123456789012:function:mock-function", + ResponseURL: + "https://cloudformation-custom-resource-response.s3.amazonaws.com/mock-url", + StackId: + "arn:aws:cloudformation:eu-west-1:123456789012:stack/mock-stack/mock-id", + RequestId: "mock-request-id", + LogicalResourceId: "MockResource", + ResourceType: "Custom::DictionaryDeployer", + ResourceProperties: { + ServiceToken: + "arn:aws:lambda:eu-west-1:123456789012:function:mock-function", + }, +}; + +// Create a mock Lambda context +const mockContext: Context = { + callbackWaitsForEmptyEventLoop: false, + functionName: "ab-testing-deploy-lambda-local", + functionVersion: "$LATEST", + invokedFunctionArn: + "arn:aws:lambda:eu-west-1:123456789012:function:mock-function", + memoryLimitInMB: "512", + awsRequestId: "mock-request-id", + logGroupName: "/aws/lambda/ab-testing-deploy-lambda-local", + logStreamName: "2025/11/19/[$LATEST]mock-stream", + getRemainingTimeInMillis: () => 300000, + done: () => {}, + fail: () => {}, + succeed: () => {}, +}; + +console.log(`Running lambda handler locally with STAGE=${stage}`); +console.log(`Using artifact bucket: ${process.env.ARTIFACT_BUCKET_NAME}`); +console.log(""); + +// Run the handler +// Cast to unknown then to the correct function type to work around typing issues +const runHandler = handler as unknown as ( + event: CloudFormationCustomResourceEvent, + context: Context, + callback: () => void, +) => Promise; + +void (async () => { + try { + await runHandler(mockEvent, mockContext, () => {}); + console.log("\n✅ Lambda handler completed successfully"); + process.exit(0); + } catch (error) { + console.error("\n❌ Lambda handler failed:", error); + process.exit(1); + } +})(); diff --git a/ab-testing/deploy-lambda/tsconfig.json b/ab-testing/deploy-lambda/tsconfig.json new file mode 100644 index 00000000000..6f69de8a60b --- /dev/null +++ b/ab-testing/deploy-lambda/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "@guardian/tsconfig/tsconfig.json", + "compilerOptions": { + "allowImportingTsExtensions": true, + "noEmit": true + }, + "exclude": ["node_modules"] +} diff --git a/ab-testing/eslint.config.mjs b/ab-testing/eslint.config.mjs index 5d3ac179d99..c0416ccb8d1 100644 --- a/ab-testing/eslint.config.mjs +++ b/ab-testing/eslint.config.mjs @@ -2,7 +2,12 @@ import guardian from "@guardian/eslint-config"; import { defineConfig, globalIgnores } from "eslint/config"; export default defineConfig([ - globalIgnores(["frontend", "eslint.config.mjs", "index.ts"]), + globalIgnores([ + "frontend/output/**", + "eslint.config.mjs", + "config/index.ts", + "deploy-lambda/dist/**", + ]), ...guardian.configs.recommended, { languageOptions: { diff --git a/ab-testing/frontend/deno.lock b/ab-testing/frontend/deno.lock deleted file mode 100644 index 6f144b6b22f..00000000000 --- a/ab-testing/frontend/deno.lock +++ /dev/null @@ -1,615 +0,0 @@ -{ - "version": "5", - "specifiers": { - "npm:@sveltejs/adapter-auto@6": "6.0.1_@sveltejs+kit@2.21.0__@sveltejs+vite-plugin-svelte@5.0.3___svelte@5.28.6____acorn@8.14.1___vite@6.3.5____picomatch@4.0.2__svelte@5.28.6___acorn@8.14.1__vite@6.3.5___picomatch@4.0.2__acorn@8.14.1_@sveltejs+vite-plugin-svelte@5.0.3__svelte@5.28.6___acorn@8.14.1__vite@6.3.5___picomatch@4.0.2_svelte@5.28.6__acorn@8.14.1_vite@6.3.5__picomatch@4.0.2", - "npm:@sveltejs/adapter-static@^3.0.8": "3.0.8_@sveltejs+kit@2.21.0__@sveltejs+vite-plugin-svelte@5.0.3___svelte@5.28.6____acorn@8.14.1___vite@6.3.5____picomatch@4.0.2__svelte@5.28.6___acorn@8.14.1__vite@6.3.5___picomatch@4.0.2__acorn@8.14.1_@sveltejs+vite-plugin-svelte@5.0.3__svelte@5.28.6___acorn@8.14.1__vite@6.3.5___picomatch@4.0.2_svelte@5.28.6__acorn@8.14.1_vite@6.3.5__picomatch@4.0.2", - "npm:@sveltejs/kit@^2.16.0": "2.21.0_@sveltejs+vite-plugin-svelte@5.0.3__svelte@5.28.6___acorn@8.14.1__vite@6.3.5___picomatch@4.0.2_svelte@5.28.6__acorn@8.14.1_vite@6.3.5__picomatch@4.0.2_acorn@8.14.1", - "npm:@sveltejs/vite-plugin-svelte@5": "5.0.3_svelte@5.28.6__acorn@8.14.1_vite@6.3.5__picomatch@4.0.2", - "npm:svelte-check@4": "4.1.7_svelte@5.28.6__acorn@8.14.1_typescript@5.8.3", - "npm:svelte@5": "5.28.6_acorn@8.14.1", - "npm:typescript@5": "5.8.3", - "npm:vite@^6.2.6": "6.3.5_picomatch@4.0.2" - }, - "npm": { - "@ampproject/remapping@2.3.0": { - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dependencies": [ - "@jridgewell/gen-mapping", - "@jridgewell/trace-mapping" - ] - }, - "@esbuild/aix-ppc64@0.25.4": { - "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", - "os": ["aix"], - "cpu": ["ppc64"] - }, - "@esbuild/android-arm64@0.25.4": { - "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", - "os": ["android"], - "cpu": ["arm64"] - }, - "@esbuild/android-arm@0.25.4": { - "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", - "os": ["android"], - "cpu": ["arm"] - }, - "@esbuild/android-x64@0.25.4": { - "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", - "os": ["android"], - "cpu": ["x64"] - }, - "@esbuild/darwin-arm64@0.25.4": { - "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", - "os": ["darwin"], - "cpu": ["arm64"] - }, - "@esbuild/darwin-x64@0.25.4": { - "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", - "os": ["darwin"], - "cpu": ["x64"] - }, - "@esbuild/freebsd-arm64@0.25.4": { - "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", - "os": ["freebsd"], - "cpu": ["arm64"] - }, - "@esbuild/freebsd-x64@0.25.4": { - "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", - "os": ["freebsd"], - "cpu": ["x64"] - }, - "@esbuild/linux-arm64@0.25.4": { - "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", - "os": ["linux"], - "cpu": ["arm64"] - }, - "@esbuild/linux-arm@0.25.4": { - "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", - "os": ["linux"], - "cpu": ["arm"] - }, - "@esbuild/linux-ia32@0.25.4": { - "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", - "os": ["linux"], - "cpu": ["ia32"] - }, - "@esbuild/linux-loong64@0.25.4": { - "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", - "os": ["linux"], - "cpu": ["loong64"] - }, - "@esbuild/linux-mips64el@0.25.4": { - "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", - "os": ["linux"], - "cpu": ["mips64el"] - }, - "@esbuild/linux-ppc64@0.25.4": { - "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", - "os": ["linux"], - "cpu": ["ppc64"] - }, - "@esbuild/linux-riscv64@0.25.4": { - "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", - "os": ["linux"], - "cpu": ["riscv64"] - }, - "@esbuild/linux-s390x@0.25.4": { - "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", - "os": ["linux"], - "cpu": ["s390x"] - }, - "@esbuild/linux-x64@0.25.4": { - "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", - "os": ["linux"], - "cpu": ["x64"] - }, - "@esbuild/netbsd-arm64@0.25.4": { - "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", - "os": ["netbsd"], - "cpu": ["arm64"] - }, - "@esbuild/netbsd-x64@0.25.4": { - "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", - "os": ["netbsd"], - "cpu": ["x64"] - }, - "@esbuild/openbsd-arm64@0.25.4": { - "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", - "os": ["openbsd"], - "cpu": ["arm64"] - }, - "@esbuild/openbsd-x64@0.25.4": { - "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", - "os": ["openbsd"], - "cpu": ["x64"] - }, - "@esbuild/sunos-x64@0.25.4": { - "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", - "os": ["sunos"], - "cpu": ["x64"] - }, - "@esbuild/win32-arm64@0.25.4": { - "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", - "os": ["win32"], - "cpu": ["arm64"] - }, - "@esbuild/win32-ia32@0.25.4": { - "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", - "os": ["win32"], - "cpu": ["ia32"] - }, - "@esbuild/win32-x64@0.25.4": { - "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", - "os": ["win32"], - "cpu": ["x64"] - }, - "@jridgewell/gen-mapping@0.3.8": { - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", - "dependencies": [ - "@jridgewell/set-array", - "@jridgewell/sourcemap-codec", - "@jridgewell/trace-mapping" - ] - }, - "@jridgewell/resolve-uri@3.1.2": { - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==" - }, - "@jridgewell/set-array@1.2.1": { - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==" - }, - "@jridgewell/sourcemap-codec@1.5.0": { - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" - }, - "@jridgewell/trace-mapping@0.3.25": { - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dependencies": [ - "@jridgewell/resolve-uri", - "@jridgewell/sourcemap-codec" - ] - }, - "@polka/url@1.0.0-next.29": { - "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==" - }, - "@rollup/rollup-android-arm-eabi@4.40.2": { - "integrity": "sha512-JkdNEq+DFxZfUwxvB58tHMHBHVgX23ew41g1OQinthJ+ryhdRk67O31S7sYw8u2lTjHUPFxwar07BBt1KHp/hg==", - "os": ["android"], - "cpu": ["arm"] - }, - "@rollup/rollup-android-arm64@4.40.2": { - "integrity": "sha512-13unNoZ8NzUmnndhPTkWPWbX3vtHodYmy+I9kuLxN+F+l+x3LdVF7UCu8TWVMt1POHLh6oDHhnOA04n8oJZhBw==", - "os": ["android"], - "cpu": ["arm64"] - }, - "@rollup/rollup-darwin-arm64@4.40.2": { - "integrity": "sha512-Gzf1Hn2Aoe8VZzevHostPX23U7N5+4D36WJNHK88NZHCJr7aVMG4fadqkIf72eqVPGjGc0HJHNuUaUcxiR+N/w==", - "os": ["darwin"], - "cpu": ["arm64"] - }, - "@rollup/rollup-darwin-x64@4.40.2": { - "integrity": "sha512-47N4hxa01a4x6XnJoskMKTS8XZ0CZMd8YTbINbi+w03A2w4j1RTlnGHOz/P0+Bg1LaVL6ufZyNprSg+fW5nYQQ==", - "os": ["darwin"], - "cpu": ["x64"] - }, - "@rollup/rollup-freebsd-arm64@4.40.2": { - "integrity": "sha512-8t6aL4MD+rXSHHZUR1z19+9OFJ2rl1wGKvckN47XFRVO+QL/dUSpKA2SLRo4vMg7ELA8pzGpC+W9OEd1Z/ZqoQ==", - "os": ["freebsd"], - "cpu": ["arm64"] - }, - "@rollup/rollup-freebsd-x64@4.40.2": { - "integrity": "sha512-C+AyHBzfpsOEYRFjztcYUFsH4S7UsE9cDtHCtma5BK8+ydOZYgMmWg1d/4KBytQspJCld8ZIujFMAdKG1xyr4Q==", - "os": ["freebsd"], - "cpu": ["x64"] - }, - "@rollup/rollup-linux-arm-gnueabihf@4.40.2": { - "integrity": "sha512-de6TFZYIvJwRNjmW3+gaXiZ2DaWL5D5yGmSYzkdzjBDS3W+B9JQ48oZEsmMvemqjtAFzE16DIBLqd6IQQRuG9Q==", - "os": ["linux"], - "cpu": ["arm"] - }, - "@rollup/rollup-linux-arm-musleabihf@4.40.2": { - "integrity": "sha512-urjaEZubdIkacKc930hUDOfQPysezKla/O9qV+O89enqsqUmQm8Xj8O/vh0gHg4LYfv7Y7UsE3QjzLQzDYN1qg==", - "os": ["linux"], - "cpu": ["arm"] - }, - "@rollup/rollup-linux-arm64-gnu@4.40.2": { - "integrity": "sha512-KlE8IC0HFOC33taNt1zR8qNlBYHj31qGT1UqWqtvR/+NuCVhfufAq9fxO8BMFC22Wu0rxOwGVWxtCMvZVLmhQg==", - "os": ["linux"], - "cpu": ["arm64"] - }, - "@rollup/rollup-linux-arm64-musl@4.40.2": { - "integrity": "sha512-j8CgxvfM0kbnhu4XgjnCWJQyyBOeBI1Zq91Z850aUddUmPeQvuAy6OiMdPS46gNFgy8gN1xkYyLgwLYZG3rBOg==", - "os": ["linux"], - "cpu": ["arm64"] - }, - "@rollup/rollup-linux-loongarch64-gnu@4.40.2": { - "integrity": "sha512-Ybc/1qUampKuRF4tQXc7G7QY9YRyeVSykfK36Y5Qc5dmrIxwFhrOzqaVTNoZygqZ1ZieSWTibfFhQ5qK8jpWxw==", - "os": ["linux"], - "cpu": ["loong64"] - }, - "@rollup/rollup-linux-powerpc64le-gnu@4.40.2": { - "integrity": "sha512-3FCIrnrt03CCsZqSYAOW/k9n625pjpuMzVfeI+ZBUSDT3MVIFDSPfSUgIl9FqUftxcUXInvFah79hE1c9abD+Q==", - "os": ["linux"], - "cpu": ["ppc64"] - }, - "@rollup/rollup-linux-riscv64-gnu@4.40.2": { - "integrity": "sha512-QNU7BFHEvHMp2ESSY3SozIkBPaPBDTsfVNGx3Xhv+TdvWXFGOSH2NJvhD1zKAT6AyuuErJgbdvaJhYVhVqrWTg==", - "os": ["linux"], - "cpu": ["riscv64"] - }, - "@rollup/rollup-linux-riscv64-musl@4.40.2": { - "integrity": "sha512-5W6vNYkhgfh7URiXTO1E9a0cy4fSgfE4+Hl5agb/U1sa0kjOLMLC1wObxwKxecE17j0URxuTrYZZME4/VH57Hg==", - "os": ["linux"], - "cpu": ["riscv64"] - }, - "@rollup/rollup-linux-s390x-gnu@4.40.2": { - "integrity": "sha512-B7LKIz+0+p348JoAL4X/YxGx9zOx3sR+o6Hj15Y3aaApNfAshK8+mWZEf759DXfRLeL2vg5LYJBB7DdcleYCoQ==", - "os": ["linux"], - "cpu": ["s390x"] - }, - "@rollup/rollup-linux-x64-gnu@4.40.2": { - "integrity": "sha512-lG7Xa+BmBNwpjmVUbmyKxdQJ3Q6whHjMjzQplOs5Z+Gj7mxPtWakGHqzMqNER68G67kmCX9qX57aRsW5V0VOng==", - "os": ["linux"], - "cpu": ["x64"] - }, - "@rollup/rollup-linux-x64-musl@4.40.2": { - "integrity": "sha512-tD46wKHd+KJvsmije4bUskNuvWKFcTOIM9tZ/RrmIvcXnbi0YK/cKS9FzFtAm7Oxi2EhV5N2OpfFB348vSQRXA==", - "os": ["linux"], - "cpu": ["x64"] - }, - "@rollup/rollup-win32-arm64-msvc@4.40.2": { - "integrity": "sha512-Bjv/HG8RRWLNkXwQQemdsWw4Mg+IJ29LK+bJPW2SCzPKOUaMmPEppQlu/Fqk1d7+DX3V7JbFdbkh/NMmurT6Pg==", - "os": ["win32"], - "cpu": ["arm64"] - }, - "@rollup/rollup-win32-ia32-msvc@4.40.2": { - "integrity": "sha512-dt1llVSGEsGKvzeIO76HToiYPNPYPkmjhMHhP00T9S4rDern8P2ZWvWAQUEJ+R1UdMWJ/42i/QqJ2WV765GZcA==", - "os": ["win32"], - "cpu": ["ia32"] - }, - "@rollup/rollup-win32-x64-msvc@4.40.2": { - "integrity": "sha512-bwspbWB04XJpeElvsp+DCylKfF4trJDa2Y9Go8O6A7YLX2LIKGcNK/CYImJN6ZP4DcuOHB4Utl3iCbnR62DudA==", - "os": ["win32"], - "cpu": ["x64"] - }, - "@sveltejs/acorn-typescript@1.0.5_acorn@8.14.1": { - "integrity": "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==", - "dependencies": [ - "acorn" - ] - }, - "@sveltejs/adapter-auto@6.0.1_@sveltejs+kit@2.21.0__@sveltejs+vite-plugin-svelte@5.0.3___svelte@5.28.6____acorn@8.14.1___vite@6.3.5____picomatch@4.0.2__svelte@5.28.6___acorn@8.14.1__vite@6.3.5___picomatch@4.0.2__acorn@8.14.1_@sveltejs+vite-plugin-svelte@5.0.3__svelte@5.28.6___acorn@8.14.1__vite@6.3.5___picomatch@4.0.2_svelte@5.28.6__acorn@8.14.1_vite@6.3.5__picomatch@4.0.2": { - "integrity": "sha512-mcWud3pYGPWM2Pphdj8G9Qiq24nZ8L4LB7coCUckUEy5Y7wOWGJ/enaZ4AtJTcSm5dNK1rIkBRoqt+ae4zlxcQ==", - "dependencies": [ - "@sveltejs/kit" - ] - }, - "@sveltejs/adapter-static@3.0.8_@sveltejs+kit@2.21.0__@sveltejs+vite-plugin-svelte@5.0.3___svelte@5.28.6____acorn@8.14.1___vite@6.3.5____picomatch@4.0.2__svelte@5.28.6___acorn@8.14.1__vite@6.3.5___picomatch@4.0.2__acorn@8.14.1_@sveltejs+vite-plugin-svelte@5.0.3__svelte@5.28.6___acorn@8.14.1__vite@6.3.5___picomatch@4.0.2_svelte@5.28.6__acorn@8.14.1_vite@6.3.5__picomatch@4.0.2": { - "integrity": "sha512-YaDrquRpZwfcXbnlDsSrBQNCChVOT9MGuSg+dMAyfsAa1SmiAhrA5jUYUiIMC59G92kIbY/AaQOWcBdq+lh+zg==", - "dependencies": [ - "@sveltejs/kit" - ] - }, - "@sveltejs/kit@2.21.0_@sveltejs+vite-plugin-svelte@5.0.3__svelte@5.28.6___acorn@8.14.1__vite@6.3.5___picomatch@4.0.2_svelte@5.28.6__acorn@8.14.1_vite@6.3.5__picomatch@4.0.2_acorn@8.14.1": { - "integrity": "sha512-kvu4h9qXduiPk1Q1oqFKDLFGu/7mslEYbVaqpbBcBxjlRJnvNCFwEvEwKt0Mx9TtSi8J77xRelvJobrGlst4nQ==", - "dependencies": [ - "@sveltejs/acorn-typescript", - "@sveltejs/vite-plugin-svelte", - "@types/cookie", - "acorn", - "cookie", - "devalue", - "esm-env", - "kleur", - "magic-string", - "mrmime", - "sade", - "set-cookie-parser", - "sirv", - "svelte", - "vite" - ], - "bin": true - }, - "@sveltejs/vite-plugin-svelte-inspector@4.0.1_@sveltejs+vite-plugin-svelte@5.0.3__svelte@5.28.6___acorn@8.14.1__vite@6.3.5___picomatch@4.0.2_svelte@5.28.6__acorn@8.14.1_vite@6.3.5__picomatch@4.0.2": { - "integrity": "sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw==", - "dependencies": [ - "@sveltejs/vite-plugin-svelte", - "debug", - "svelte", - "vite" - ] - }, - "@sveltejs/vite-plugin-svelte@5.0.3_svelte@5.28.6__acorn@8.14.1_vite@6.3.5__picomatch@4.0.2": { - "integrity": "sha512-MCFS6CrQDu1yGwspm4qtli0e63vaPCehf6V7pIMP15AsWgMKrqDGCPFF/0kn4SP0ii4aySu4Pa62+fIRGFMjgw==", - "dependencies": [ - "@sveltejs/vite-plugin-svelte-inspector", - "debug", - "deepmerge", - "kleur", - "magic-string", - "svelte", - "vite", - "vitefu" - ] - }, - "@types/cookie@0.6.0": { - "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" - }, - "@types/estree@1.0.7": { - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==" - }, - "acorn@8.14.1": { - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", - "bin": true - }, - "aria-query@5.3.2": { - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==" - }, - "axobject-query@4.1.0": { - "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==" - }, - "chokidar@4.0.3": { - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dependencies": [ - "readdirp" - ] - }, - "clsx@2.1.1": { - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==" - }, - "cookie@0.6.0": { - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==" - }, - "debug@4.4.1": { - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "dependencies": [ - "ms" - ] - }, - "deepmerge@4.3.1": { - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==" - }, - "devalue@5.1.1": { - "integrity": "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==" - }, - "esbuild@0.25.4": { - "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", - "optionalDependencies": [ - "@esbuild/aix-ppc64", - "@esbuild/android-arm", - "@esbuild/android-arm64", - "@esbuild/android-x64", - "@esbuild/darwin-arm64", - "@esbuild/darwin-x64", - "@esbuild/freebsd-arm64", - "@esbuild/freebsd-x64", - "@esbuild/linux-arm", - "@esbuild/linux-arm64", - "@esbuild/linux-ia32", - "@esbuild/linux-loong64", - "@esbuild/linux-mips64el", - "@esbuild/linux-ppc64", - "@esbuild/linux-riscv64", - "@esbuild/linux-s390x", - "@esbuild/linux-x64", - "@esbuild/netbsd-arm64", - "@esbuild/netbsd-x64", - "@esbuild/openbsd-arm64", - "@esbuild/openbsd-x64", - "@esbuild/sunos-x64", - "@esbuild/win32-arm64", - "@esbuild/win32-ia32", - "@esbuild/win32-x64" - ], - "scripts": true, - "bin": true - }, - "esm-env@1.2.2": { - "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==" - }, - "esrap@1.4.6": { - "integrity": "sha512-F/D2mADJ9SHY3IwksD4DAXjTt7qt7GWUf3/8RhCNWmC/67tyb55dpimHmy7EplakFaflV0R/PC+fdSPqrRHAQw==", - "dependencies": [ - "@jridgewell/sourcemap-codec" - ] - }, - "fdir@6.4.4_picomatch@4.0.2": { - "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", - "dependencies": [ - "picomatch" - ], - "optionalPeers": [ - "picomatch" - ] - }, - "fsevents@2.3.3": { - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "os": ["darwin"], - "scripts": true - }, - "is-reference@3.0.3": { - "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", - "dependencies": [ - "@types/estree" - ] - }, - "kleur@4.1.5": { - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==" - }, - "locate-character@3.0.0": { - "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" - }, - "magic-string@0.30.17": { - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "dependencies": [ - "@jridgewell/sourcemap-codec" - ] - }, - "mri@1.2.0": { - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==" - }, - "mrmime@2.0.1": { - "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==" - }, - "ms@2.1.3": { - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "nanoid@3.3.11": { - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "bin": true - }, - "picocolors@1.1.1": { - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" - }, - "picomatch@4.0.2": { - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==" - }, - "postcss@8.5.3": { - "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", - "dependencies": [ - "nanoid", - "picocolors", - "source-map-js" - ] - }, - "readdirp@4.1.2": { - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==" - }, - "rollup@4.40.2": { - "integrity": "sha512-tfUOg6DTP4rhQ3VjOO6B4wyrJnGOX85requAXvqYTHsOgb2TFJdZ3aWpT8W2kPoypSGP7dZUyzxJ9ee4buM5Fg==", - "dependencies": [ - "@types/estree" - ], - "optionalDependencies": [ - "@rollup/rollup-android-arm-eabi", - "@rollup/rollup-android-arm64", - "@rollup/rollup-darwin-arm64", - "@rollup/rollup-darwin-x64", - "@rollup/rollup-freebsd-arm64", - "@rollup/rollup-freebsd-x64", - "@rollup/rollup-linux-arm-gnueabihf", - "@rollup/rollup-linux-arm-musleabihf", - "@rollup/rollup-linux-arm64-gnu", - "@rollup/rollup-linux-arm64-musl", - "@rollup/rollup-linux-loongarch64-gnu", - "@rollup/rollup-linux-powerpc64le-gnu", - "@rollup/rollup-linux-riscv64-gnu", - "@rollup/rollup-linux-riscv64-musl", - "@rollup/rollup-linux-s390x-gnu", - "@rollup/rollup-linux-x64-gnu", - "@rollup/rollup-linux-x64-musl", - "@rollup/rollup-win32-arm64-msvc", - "@rollup/rollup-win32-ia32-msvc", - "@rollup/rollup-win32-x64-msvc", - "fsevents" - ], - "bin": true - }, - "sade@1.8.1": { - "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", - "dependencies": [ - "mri" - ] - }, - "set-cookie-parser@2.7.1": { - "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==" - }, - "sirv@3.0.1": { - "integrity": "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==", - "dependencies": [ - "@polka/url", - "mrmime", - "totalist" - ] - }, - "source-map-js@1.2.1": { - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==" - }, - "svelte-check@4.1.7_svelte@5.28.6__acorn@8.14.1_typescript@5.8.3": { - "integrity": "sha512-1jX4BzXrQJhC/Jt3SqYf6Ntu//vmfc6VWp07JkRfK2nn+22yIblspVUo96gzMkg0Zov8lQicxhxsMzOctwcMQQ==", - "dependencies": [ - "@jridgewell/trace-mapping", - "chokidar", - "fdir", - "picocolors", - "sade", - "svelte", - "typescript" - ], - "bin": true - }, - "svelte@5.28.6_acorn@8.14.1": { - "integrity": "sha512-9qqr7mw8YR9PAnxGFfzCK6PUlNGtns7wVavrhnxyf3fpB1mP/Ol55Z2UnIapsSzNNl3k9qw7cZ22PdE8+xT/jQ==", - "dependencies": [ - "@ampproject/remapping", - "@jridgewell/sourcemap-codec", - "@sveltejs/acorn-typescript", - "@types/estree", - "acorn", - "aria-query", - "axobject-query", - "clsx", - "esm-env", - "esrap", - "is-reference", - "locate-character", - "magic-string", - "zimmerframe" - ] - }, - "tinyglobby@0.2.13_picomatch@4.0.2": { - "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", - "dependencies": [ - "fdir", - "picomatch" - ] - }, - "totalist@3.0.1": { - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==" - }, - "typescript@5.8.3": { - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "bin": true - }, - "vite@6.3.5_picomatch@4.0.2": { - "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", - "dependencies": [ - "esbuild", - "fdir", - "picomatch", - "postcss", - "rollup", - "tinyglobby" - ], - "optionalDependencies": [ - "fsevents" - ], - "bin": true - }, - "vitefu@1.0.6_vite@6.3.5__picomatch@4.0.2": { - "integrity": "sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA==", - "dependencies": [ - "vite" - ], - "optionalPeers": [ - "vite" - ] - }, - "zimmerframe@1.1.2": { - "integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==" - } - }, - "workspace": { - "packageJson": { - "dependencies": [ - "npm:@sveltejs/adapter-auto@6", - "npm:@sveltejs/adapter-static@^3.0.8", - "npm:@sveltejs/kit@^2.16.0", - "npm:@sveltejs/vite-plugin-svelte@5", - "npm:svelte-check@4", - "npm:svelte@5", - "npm:typescript@5", - "npm:vite@^6.2.6" - ] - } - } -} diff --git a/ab-testing/frontend/package.json b/ab-testing/frontend/package.json index e0b67082b73..25e946ee7ab 100644 --- a/ab-testing/frontend/package.json +++ b/ab-testing/frontend/package.json @@ -12,7 +12,7 @@ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" }, "devDependencies": { - "@guardian/ab-testing": "workspace:ab-testing", + "@guardian/ab-testing-config": "workspace:ab-testing-config", "@sveltejs/adapter-auto": "^6.0.0", "@sveltejs/adapter-static": "^3.0.8", "@sveltejs/kit": "^2.16.0", diff --git a/ab-testing/frontend/src/routes/+page.svelte b/ab-testing/frontend/src/routes/+page.svelte index 6da266f7452..a50f702943c 100644 --- a/ab-testing/frontend/src/routes/+page.svelte +++ b/ab-testing/frontend/src/routes/+page.svelte @@ -1,5 +1,5 @@ diff --git a/ab-testing/riff-raff.yaml b/ab-testing/riff-raff.yaml deleted file mode 100644 index 086024eb7e2..00000000000 --- a/ab-testing/riff-raff.yaml +++ /dev/null @@ -1,13 +0,0 @@ -regions: [eu-west-1] -stacks: [frontend] -allowedStages: - - CODE - - PROD -deployments: - admin/ab-testing: - type: aws-s3 - parameters: - bucketSsmKey: /account/services/dotcom-store.bucket - cacheControl: public, max-age=315360000 - prefixStack: false - publicReadAcl: false diff --git a/ab-testing/scripts/deploy/deploy-ab-tests.ts b/ab-testing/scripts/deploy/deploy-ab-tests.ts deleted file mode 100644 index 6cfaba9cf1c..00000000000 --- a/ab-testing/scripts/deploy/deploy-ab-tests.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { - calculateUpdates, - getABTestGroupsFromDictionary, - updateABTestGroups, -} from "../lib/fastly-api.ts"; -import { getUpdatedABTestGroups } from "./read-built-dictionaries.ts"; - -const deployABTests = async (filePath: string) => { - // update ab test groups first - const updatedABTestGroups = await getUpdatedABTestGroups(filePath); - const currentABTestGroups = await getABTestGroupsFromDictionary(); - - const abTestGroupUpdates = calculateUpdates( - updatedABTestGroups, - currentABTestGroups, - ); - - if (abTestGroupUpdates.length === 0) { - console.log("No ab test groups to update"); - } else { - Map.groupBy(abTestGroupUpdates, (item) => item.op).forEach( - (items, op) => { - if (op === "delete") { - console.log( - `Deleting ${items.length} ab test groups from dictionary`, - ); - } - if (op === "update") { - console.log( - `Updating ${items.length} ab test groups in dictionary`, - ); - } - if (op === "create") { - console.log( - `Creating ${items.length} ab test groups in dictionary`, - ); - } - }, - ); - - const updateABTestGroupsResponse = - await updateABTestGroups(abTestGroupUpdates); - - if (updateABTestGroupsResponse.status !== "ok") { - throw new Error(`Failed to update ab test groups dictionary`); - } - } -}; - -export { deployABTests }; diff --git a/ab-testing/scripts/deploy/deploy-mvts.ts b/ab-testing/scripts/deploy/deploy-mvts.ts deleted file mode 100644 index ceb0bb1f777..00000000000 --- a/ab-testing/scripts/deploy/deploy-mvts.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { - calculateUpdates, - getMVTGroupsFromDictionary, - updateMVTGroups, -} from "../lib/fastly-api.ts"; -import { getMVTGroups } from "./read-built-dictionaries.ts"; - -const deployMVTs = async (filePath: string) => { - // update mvt groups - const mvtGroups = await getMVTGroups(filePath); - const currentMVTGroups = await getMVTGroupsFromDictionary(); - - console.log(`Current MVT Groups: ${currentMVTGroups.length}`); - console.log(`New MVT Groups: ${mvtGroups.length}`); - - const mvtGroupUpdates = calculateUpdates(mvtGroups, currentMVTGroups); - - if (mvtGroupUpdates.length === 0) { - console.log("No mvt groups to update"); - } else { - Map.groupBy(mvtGroupUpdates, (item) => item.op).forEach((items, op) => { - if (op === "delete") { - console.log( - `Deleting ${items.length} mvt groups from dictionary`, - ); - } - if (op === "update") { - console.log( - `Updating ${items.length} mvt groups in dictionary`, - ); - } - if (op === "create") { - console.log( - `Creating ${items.length} mvt groups in dictionary`, - ); - } - }); - - console.log( - `Performing ${mvtGroupUpdates.length} mvt groups dictionary operations`, - ); - - const updateMVTGroupsResponse = await updateMVTGroups(mvtGroupUpdates); - - if (updateMVTGroupsResponse.status !== "ok") { - throw new Error(`Failed to update mvt groups dictionary`); - } - } -}; - -export { deployMVTs }; diff --git a/ab-testing/scripts/deploy/index.ts b/ab-testing/scripts/deploy/index.ts deleted file mode 100644 index 6d70391f3a1..00000000000 --- a/ab-testing/scripts/deploy/index.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { parseArgs } from "node:util"; -import { - abTestsDictionaryId, - abTestsDictionaryName, - mvtDictionaryId, - mvtDictionaryName, - serviceId, - serviceName, -} from "../lib/config.ts"; -import { getService, verifyDictionaryName } from "../lib/fastly-api.ts"; -import { deployABTests } from "./deploy-ab-tests.ts"; -import { deployMVTs } from "./deploy-mvts.ts"; - -const flags = parseArgs({ - args: process.argv.slice(2), - options: { - mvts: { - type: "string", - short: "m", - }, - "ab-tests": { - type: "string", - short: "a", - }, - }, -}).values; - -if (!flags["mvts"] || !flags["ab-tests"]) { - console.error( - "Please provide the path to the mvt and ab test groups dictionaries", - ); - process.exit(1); -} - -const service = await getService(serviceId); -if (service.name !== serviceName) { - throw new Error( - `Service ID ${serviceId} does not match the expected service name ${serviceName}`, - ); -} - -const activeVersion = service.versions.find( - (v: { active: boolean }) => v.active, -); - -if (!activeVersion) { - throw new Error(`No active version found for service ${service.name}`); -} - -// Verify that the service ID and dictionary names match the expected values -await Promise.all([ - verifyDictionaryName({ - activeVersion: activeVersion.number, - dictionaryName: mvtDictionaryName, - dictionaryId: mvtDictionaryId, - }), - verifyDictionaryName({ - activeVersion: activeVersion.number, - dictionaryName: abTestsDictionaryName, - dictionaryId: abTestsDictionaryId, - }), -]); - -await Promise.all([ - deployABTests(flags["ab-tests"]), - deployMVTs(flags["mvts"]), -]); - -console.log("Successfully updated ab test groups and mvt groups dictionaries"); diff --git a/ab-testing/scripts/deploy/read-built-dictionaries.ts b/ab-testing/scripts/deploy/read-built-dictionaries.ts deleted file mode 100644 index 56bd59c15e6..00000000000 --- a/ab-testing/scripts/deploy/read-built-dictionaries.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { readFile } from "fs/promises"; -import { array, assert, object, string } from "superstruct"; - -const fastlyKVStruct = object({ - item_key: string(), - item_value: string(), -}); - -const getUpdatedABTestGroups = async (file: string) => { - const updatedABTestGroups = JSON.parse( - await readFile(file, { - encoding: "utf-8", - }), - ) as unknown; - - assert(updatedABTestGroups, array(fastlyKVStruct)); - - return updatedABTestGroups; -}; - -const getMVTGroups = async (file: string) => { - const mvtGroups = JSON.parse( - await readFile(file, { - encoding: "utf-8", - }), - ) as unknown; - - assert(mvtGroups, array(fastlyKVStruct)); - return mvtGroups; -}; - -export { getUpdatedABTestGroups, getMVTGroups }; diff --git a/ab-testing/scripts/lib/fastly-api.test.ts b/ab-testing/scripts/lib/fastly-api.test.ts deleted file mode 100644 index b00e1a2bc94..00000000000 --- a/ab-testing/scripts/lib/fastly-api.test.ts +++ /dev/null @@ -1,321 +0,0 @@ -import { deepEqual, equal, match, rejects } from "node:assert"; -import type { Mock } from "node:test"; -import test, { mock } from "node:test"; - -const mockConfig = { - serviceName: "test-service", - serviceId: "test-service-id", - mvtDictionaryId: "test-mvt-dictionary-id", - mvtDictionaryName: "test-mvt-dictionary", - abTestsDictionaryId: "test-ab-tests-dictionary-id", - abTestsDictionaryName: "test-ab-tests-dictionary", -}; - -// Mock environment variables -process.env.FASTLY_AB_TESTING_CONFIG = JSON.stringify(mockConfig); -process.env.FASTLY_API_TOKEN = "test-api-token"; - -type MockedFetch = Mock; - -function mockFetch(response: unknown, status = 200, statusText = "OK") { - const mockResponse = new Response(JSON.stringify(response), { - status, - statusText, - headers: { "Content-Type": "application/json" }, - }); - - globalThis.fetch = mock.fn(async () => Promise.resolve(mockResponse)); -} - -// Import after mocking -const { - calculateUpdates, - getDictionaryItems, - getMVTGroupsFromDictionary, - getABTestGroupsFromDictionary, - updateMVTGroups, - updateABTestGroups, - encodeObject, -} = await import("./fastly-api.ts"); - -test("calculateUpdates - creates new items", () => { - const currentDictionary: Array<{ item_key: string; item_value: string }> = - []; - const newDictionary = [ - { item_key: "test1", item_value: "value1" }, - { item_key: "test2", item_value: "value2" }, - ]; - - const result = calculateUpdates(newDictionary, currentDictionary); - - equal(result.length, 2); - deepEqual(result[0], { - item_key: "test1", - item_value: "value1", - op: "create", - }); - deepEqual(result[1], { - item_key: "test2", - item_value: "value2", - op: "create", - }); -}); - -test("calculateUpdates - updates existing items", () => { - const currentDictionary = [ - { item_key: "test1", item_value: "old_value1" }, - { item_key: "test2", item_value: "value2" }, - ]; - const newDictionary = [ - { item_key: "test1", item_value: "new_value1" }, - { item_key: "test2", item_value: "value2" }, - ]; - - const result = calculateUpdates(newDictionary, currentDictionary); - - equal(result.length, 1); - deepEqual(result[0], { - item_key: "test1", - item_value: "new_value1", - op: "update", - }); -}); - -test("calculateUpdates - deletes removed items", () => { - const currentDictionary = [ - { item_key: "test1", item_value: "value1" }, - { item_key: "test2", item_value: "value2" }, - ]; - const newDictionary = [{ item_key: "test1", item_value: "value1" }]; - - const result = calculateUpdates(newDictionary, currentDictionary); - - equal(result.length, 1); - deepEqual(result[0], { - item_key: "test2", - op: "delete", - }); -}); - -test("calculateUpdates - no changes needed", () => { - const currentDictionary = [ - { item_key: "test1", item_value: "value1" }, - { item_key: "test2", item_value: "value2" }, - ]; - const newDictionary = [ - { item_key: "test1", item_value: "value1" }, - { item_key: "test2", item_value: "value2" }, - ]; - - const result = calculateUpdates(newDictionary, currentDictionary); - - equal(result.length, 0); -}); - -test("calculateUpdates - combination of operations", () => { - const currentDictionary = [ - { item_key: "keep", item_value: "same_value" }, - { item_key: "update", item_value: "old_value" }, - { item_key: "delete", item_value: "will_be_deleted" }, - ]; - const newDictionary = [ - { item_key: "keep", item_value: "same_value" }, - { item_key: "update", item_value: "new_value" }, - { item_key: "create", item_value: "new_item" }, - ]; - - const result = calculateUpdates(newDictionary, currentDictionary); - - equal(result.length, 3); - - const deleteOp = result.find((op) => op.op === "delete"); - deepEqual(deleteOp, { - item_key: "delete", - op: "delete", - }); - - const updateOp = result.find((op) => op.op === "update"); - deepEqual(updateOp, { - item_key: "update", - item_value: "new_value", - op: "update", - }); - - const createOp = result.find((op) => op.op === "create"); - deepEqual(createOp, { - item_key: "create", - item_value: "new_item", - op: "create", - }); -}); - -test("getDictionaryItems - fetches and returns dictionary items", async () => { - const mockResponse = [ - { - service_id: "test-service", - item_key: "key1", - item_value: "value1", - dictionary_id: "test-dict", - created_at: "2023-01-01", - updated_at: "2023-01-01", - deleted_at: null, - }, - ]; - - mockFetch(mockResponse); - - const result = await getDictionaryItems({ - dictionaryId: "test-dict", - }); - - deepEqual(result, mockResponse); - equal((globalThis.fetch as MockedFetch).mock.calls.length, 1); - equal( - (globalThis.fetch as MockedFetch).mock.calls[0]?.arguments[0], - `https://api.fastly.com/service/${mockConfig.serviceId}/dictionary/test-dict/items?per_page=1000`, - ); -}); - -test("getDictionaryItems - throws error on invalid response", async () => { - // Mock invalid response format - mockFetch("not an array"); - - await rejects( - async () => { - await getDictionaryItems({ - dictionaryId: "test-dict", - }); - }, - Error, - "Expected an array", - ); -}); - -test("getDictionaryItems - throws error on fetch failure", async () => { - mockFetch({ error: "Something went wrong" }, 500, "Internal Server Error"); - - await rejects( - async () => { - await getDictionaryItems({ - dictionaryId: "test-dict", - }); - }, - Error, - "Failed to fetch from Fastly: 500", - ); -}); - -test("getMVTGroupsFromDictionary - calls the right endpoint", async () => { - const mockResponse = [] as unknown; - mockFetch(mockResponse); - - await getMVTGroupsFromDictionary(); - - equal((globalThis.fetch as MockedFetch).mock.calls.length, 1); - match( - (globalThis.fetch as MockedFetch).mock.calls[0]?.arguments[0] as string, - new RegExp(`/dictionary/${mockConfig.mvtDictionaryId}/items`), - ); -}); - -test("getABTestGroupsFromDictionary - calls the right endpoint", async () => { - const mockResponse = [] as unknown; - mockFetch(mockResponse); - - await getABTestGroupsFromDictionary(); - - equal((globalThis.fetch as MockedFetch).mock.calls.length, 1); - match( - (globalThis.fetch as MockedFetch).mock.calls[0]?.arguments[0] as string, - new RegExp(`/dictionary/${mockConfig.abTestsDictionaryId}/items`), - ); -}); - -test("updateMVTGroups - makes PATCH request with correct data", async () => { - mockFetch({ status: "ok" }); - - const items = [ - { item_key: "key1", item_value: "value1", op: "create" as const }, - ]; - await updateMVTGroups(items); - - equal((globalThis.fetch as MockedFetch).mock.calls.length, 1); - equal( - (globalThis.fetch as MockedFetch).mock.calls[0]?.arguments[1]?.method, - "PATCH", - ); - - const requestBody = JSON.parse( - (globalThis.fetch as MockedFetch).mock.calls[0]?.arguments[1] - ?.body as string, - ) as { - items: Array<{ - item_key: string; - item_value: string; - op: "create" | "update" | "delete"; - }>; - }; - - deepEqual(requestBody.items, items); -}); - -test("updateABTestGroups - makes PATCH request with correct data", async () => { - mockFetch({ status: "ok" }); - - const items = [ - { item_key: "key1", item_value: "value1", op: "update" as const }, - ]; - await updateABTestGroups(items); - - equal((globalThis.fetch as MockedFetch).mock.calls.length, 1); - equal( - (globalThis.fetch as MockedFetch).mock.calls[0]?.arguments[1]?.method, - "PATCH", - ); - - const requestBody = JSON.parse( - (globalThis.fetch as MockedFetch).mock.calls[0]?.arguments[1] - ?.body as string, - ) as { - items: Array<{ - item_key: string; - item_value: string; - op: "create" | "update" | "delete"; - }>; - }; - deepEqual(requestBody.items, items); -}); - -test("updateABTestGroups - throws error on non-ok status", async () => { - mockFetch({ status: "error" }); - - const items = [ - { item_key: "key1", item_value: "value1", op: "create" as const }, - ]; - - await rejects( - async () => { - await updateABTestGroups(items); - }, - Error, - "Failed to update dictionary: error", - ); -}); - -test("encodeObject - encodes object to string", () => { - const obj = { - test: "value", - another: 123, - bool: true, - }; - - const result = encodeObject(obj); - equal(result, "test=value,another=123,bool=true"); -}); - -test("encodeObject - handles arrays", () => { - const arr = ["test", "another"]; - - const result = encodeObject(arr); - equal(result, "0=test,1=another"); -}); diff --git a/ab-testing/scripts/lib/fastly-api.ts b/ab-testing/scripts/lib/fastly-api.ts deleted file mode 100644 index c00b2115042..00000000000 --- a/ab-testing/scripts/lib/fastly-api.ts +++ /dev/null @@ -1,300 +0,0 @@ -import { - array, - assert, - boolean, - nullable, - number, - object, - string, - type, -} from "superstruct"; -import { - abTestsDictionaryId, - apiToken, - mvtDictionaryId, - serviceId, -} from "./config.ts"; - -const dictionaryItemStruct = object({ - service_id: string(), - item_key: string(), - item_value: string(), - dictionary_id: string(), - created_at: string(), - updated_at: string(), - deleted_at: nullable(string()), -}); - -type UpdateDictionaryItemRequest = - | { - item_key: string; - item_value: string; - op: "create" | "update" | "upsert"; - } - | { - item_key: string; - op: "delete"; - }; - -const FASTLY_API_BASE_URL = "https://api.fastly.com/service"; - -/** - * Fetch data from Fastly API - * We're using fetch instead of the Fastly API client as it doesn't play nicely with Deno, nor is it typed - * - * @param url - The URL to fetch - * @param options - Fetch options - * @returns The parsed JSON response - * @throws Error if the response is not ok or if the response cannot be parsed - */ -const fetchFromFastly = async ( - url: string, - options: RequestInit = {}, -): Promise => { - const response = await fetch(url, { - ...options, - headers: { - ...options.headers, - "Fastly-Key": apiToken, - }, - }); - if (!response.ok) { - console.error(await response.text()); - throw new Error( - `Failed to fetch from Fastly: ${response.status} ${response.statusText}`, - ); - } - const data = (await response.json()) as unknown; - if (!data) { - throw new Error(`Failed to parse response from Fastly`); - } - return data as T; -}; - -const getService = async (serviceId: string) => { - const service = await fetchFromFastly( - `${FASTLY_API_BASE_URL}/${serviceId}`, - ); - - assert( - service, - type({ - id: string(), - name: string(), - versions: array( - type({ - active: boolean(), - number: number(), - }), - ), - }), - ); - - return service; -}; - -const getDictionary = async ({ - activeVersion, - dictionaryName, -}: { - activeVersion: number; - dictionaryName: string; -}) => { - const dictionary = await fetchFromFastly( - `${FASTLY_API_BASE_URL}/${serviceId}/version/${activeVersion}/dictionary/${dictionaryName}`, - ); - assert(dictionary, type({ id: string(), name: string() })); - - return dictionary; -}; - -const getDictionaryItems = async ({ - dictionaryId, -}: { - dictionaryId: string; -}) => { - const dictionary = await fetchFromFastly( - `${FASTLY_API_BASE_URL}/${serviceId}/dictionary/${dictionaryId}/items?per_page=1000`, - ); - - assert(dictionary, array(dictionaryItemStruct)); - - return dictionary; -}; - -const updateDictionaryItems = async ({ - dictionaryId, - items, -}: { - dictionaryId: string; - items: UpdateDictionaryItemRequest[]; -}) => { - const dictionary = await fetchFromFastly( - `${FASTLY_API_BASE_URL}/${serviceId}/dictionary/${dictionaryId}/items`, - { - method: "PATCH", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - service_id: serviceId, - dictionary_id: dictionaryId, - items, - }), - }, - ); - - assert(dictionary, object({ status: string() })); - if (dictionary.status !== "ok") { - throw new Error(`Failed to update dictionary: ${dictionary.status}`); - } - return dictionary; -}; - -/** - * Calculate the bulk updates for a dictionary - * Compare the new dictionary with the current dictionary and return the operations required - * - * @param updatedDictionary - * @param currentDictionary - * @returns - */ -const calculateUpdates = ( - updatedDictionary: Array<{ - item_key: string; - item_value: string; - }>, - currentDictionary: Array<{ - item_key: string; - item_value: string; - }>, -): UpdateDictionaryItemRequest[] => { - const currentDictionaryKeys = new Set( - currentDictionary.map((group) => group.item_key), - ); - - const updateDeleteOps = currentDictionary.reduce<{ - updates: UpdateDictionaryItemRequest[]; - deletes: UpdateDictionaryItemRequest[]; - }>( - (ops, group) => { - const updatedGroup = updatedDictionary.find( - (newGroup) => newGroup.item_key === group.item_key, - ); - - if (!updatedGroup) { - return { - ...ops, - deletes: [ - ...ops.deletes, - { - item_key: group.item_key, - op: "delete", - }, - ], - }; - } - - if (group.item_value !== updatedGroup.item_value) { - return { - ...ops, - updates: [ - ...ops.updates, - { - item_key: group.item_key, - item_value: updatedGroup.item_value, - op: "update", - }, - ], - }; - } - - return ops; - }, - { - updates: [], - deletes: [], - }, - ); - - const createOpts: UpdateDictionaryItemRequest[] = updatedDictionary - .filter((group) => !currentDictionaryKeys.has(group.item_key)) - .map(({ item_key, item_value }) => ({ - item_key, - item_value, - op: "create", - })); - - const bulkUpdates = [ - ...updateDeleteOps.deletes, - ...updateDeleteOps.updates, - ...createOpts, - ]; - - return bulkUpdates; -}; - -/** - * Verify that the service and dictionary names match the expected IDs - * - */ -const verifyDictionaryName = async ({ - activeVersion, - dictionaryName, - dictionaryId, -}: { - activeVersion: number; - dictionaryName: string; - dictionaryId: string; -}) => { - const dictionary = await getDictionary({ - activeVersion: activeVersion, - dictionaryName, - }); - - if (dictionary.id !== dictionaryId) { - throw new Error( - `Dictionary ID ${dictionaryId} does not match the expected dictionary ${dictionaryName}`, - ); - } - - return; -}; - -const getMVTGroupsFromDictionary = () => - getDictionaryItems({ - dictionaryId: mvtDictionaryId, - }); - -const getABTestGroupsFromDictionary = () => - getDictionaryItems({ - dictionaryId: abTestsDictionaryId, - }); - -const updateMVTGroups = (items: UpdateDictionaryItemRequest[]) => - updateDictionaryItems({ - dictionaryId: mvtDictionaryId, - items, - }); -const updateABTestGroups = (items: UpdateDictionaryItemRequest[]) => - updateDictionaryItems({ - dictionaryId: abTestsDictionaryId, - items, - }); - -const encodeObject = (obj: Record | string[]) => - Object.entries(obj) - .map(([key, value]) => `${key}=${String(value)}`) - .join(","); - -export { - getMVTGroupsFromDictionary, - getABTestGroupsFromDictionary, - getService, - getDictionaryItems, - updateMVTGroups, - updateABTestGroups, - calculateUpdates, - encodeObject, - verifyDictionaryName, -}; diff --git a/dotcom-rendering/package.json b/dotcom-rendering/package.json index 049567d60a5..5528134adb8 100644 --- a/dotcom-rendering/package.json +++ b/dotcom-rendering/package.json @@ -27,7 +27,7 @@ "@emotion/react": "11.14.0", "@emotion/server": "11.11.0", "@guardian/ab-core": "8.0.0", - "@guardian/ab-testing": "workspace:ab-testing", + "@guardian/ab-testing-config": "workspace:ab-testing-config", "@guardian/braze-components": "22.2.0", "@guardian/bridget": "8.7.0", "@guardian/browserslist-config": "6.1.0", diff --git a/dotcom-rendering/src/components/Metrics.importable.tsx b/dotcom-rendering/src/components/Metrics.importable.tsx index 5f3c80ee169..d4961c2b6e7 100644 --- a/dotcom-rendering/src/components/Metrics.importable.tsx +++ b/dotcom-rendering/src/components/Metrics.importable.tsx @@ -1,5 +1,5 @@ import type { ABTest, ABTestAPI } from '@guardian/ab-core'; -import { activeABtests } from '@guardian/ab-testing'; +import { activeABtests } from '@guardian/ab-testing-config'; import { bypassCommercialMetricsSampling, EventTimer, diff --git a/package.json b/package.json index b5b91611fab..236778c84a2 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ }, "lint-staged": { "*": "prettier --ignore-unknown --write", - "ab-testing/**/*": "cd ab-testing && deno run validate" + "ab-testing/**/*": "pnpm --filter ab-testing lint-staged" }, "dependencies": { "@guardian/prettier": "5.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5d1201362e0..8f0ca9ac0b6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,36 +35,154 @@ importers: specifier: 2.6.2 version: 2.6.2 - ab-testing: + ab-testing/cdk: + devDependencies: + '@aws-sdk/client-s3': + specifier: 3.931.0 + version: 3.931.0 + '@aws-sdk/client-ssm': + specifier: 3.621.0 + version: 3.621.0 + '@guardian/cdk': + specifier: 62.0.1 + version: 62.0.1(aws-cdk-lib@2.220.0(constructs@10.4.2))(aws-cdk@2.1030.0)(constructs@10.4.2) + '@guardian/eslint-config': + specifier: 12.0.1 + version: 12.0.1(eslint-plugin-import@2.29.1(eslint@9.39.1))(eslint@9.39.1)(typescript@5.9.3) + '@guardian/tsconfig': + specifier: 1.0.1 + version: 1.0.1 + '@types/node': + specifier: 22.17.0 + version: 22.17.0 + aws-cdk: + specifier: 2.1030.0 + version: 2.1030.0 + aws-cdk-lib: + specifier: 2.220.0 + version: 2.220.0(constructs@10.4.2) + eslint: + specifier: 9.39.1 + version: 9.39.1 + prettier: + specifier: 3.0.3 + version: 3.0.3 + source-map-support: + specifier: 0.5.21 + version: 0.5.21 + typescript: + specifier: 5.9.3 + version: 5.9.3 + + ab-testing/config: + dependencies: + superstruct: + specifier: 2.0.2 + version: 2.0.2 + devDependencies: + '@aws-sdk/client-s3': + specifier: 3.931.0 + version: 3.931.0 + '@aws-sdk/client-ssm': + specifier: 3.621.0 + version: 3.621.0 + '@guardian/cdk': + specifier: 62.0.1 + version: 62.0.1(aws-cdk-lib@2.220.0(constructs@10.4.2))(aws-cdk@2.1030.0)(constructs@10.4.2) + '@guardian/eslint-config': + specifier: 12.0.1 + version: 12.0.1(eslint-plugin-import@2.29.1(eslint@9.39.1))(eslint@9.39.1)(typescript@5.9.3) + '@guardian/tsconfig': + specifier: 1.0.1 + version: 1.0.1 + '@types/node': + specifier: 22.17.0 + version: 22.17.0 + aws-cdk: + specifier: 2.1030.0 + version: 2.1030.0 + aws-cdk-lib: + specifier: 2.220.0 + version: 2.220.0(constructs@10.4.2) + eslint: + specifier: 9.39.1 + version: 9.39.1 + prettier: + specifier: 3.0.3 + version: 3.0.3 + source-map-support: + specifier: 0.5.21 + version: 0.5.21 + typescript: + specifier: 5.9.3 + version: 5.9.3 + + ab-testing/deploy-lambda: dependencies: + '@aws-sdk/client-s3': + specifier: 3.931.0 + version: 3.931.0 + '@aws-sdk/client-ssm': + specifier: 3.621.0 + version: 3.621.0 superstruct: specifier: 2.0.2 version: 2.0.2 devDependencies: + '@guardian/cdk': + specifier: 62.0.1 + version: 62.0.1(aws-cdk-lib@2.220.0(constructs@10.4.2))(aws-cdk@2.1030.0)(constructs@10.4.2) '@guardian/eslint-config': specifier: 12.0.1 version: 12.0.1(eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.22.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1))(eslint@9.39.1)(typescript@5.9.3) '@guardian/tsconfig': specifier: 1.0.1 version: 1.0.1 + '@rollup/plugin-commonjs': + specifier: 29.0.0 + version: 29.0.0(rollup@4.53.2) + '@rollup/plugin-json': + specifier: 6.1.0 + version: 6.1.0(rollup@4.53.2) + '@rollup/plugin-node-resolve': + specifier: 16.0.3 + version: 16.0.3(rollup@4.53.2) + '@types/aws-lambda': + specifier: 8.10.158 + version: 8.10.158 '@types/node': specifier: 22.17.0 version: 22.17.0 + aws-cdk-lib: + specifier: 2.220.0 + version: 2.220.0(constructs@10.4.2) + aws-lambda: + specifier: 1.0.7 + version: 1.0.7 + esbuild: + specifier: 0.27.0 + version: 0.27.0 eslint: specifier: 9.39.1 version: 9.39.1 prettier: specifier: 3.0.3 version: 3.0.3 + rollup: + specifier: 4.53.2 + version: 4.53.2 + rollup-plugin-esbuild: + specifier: 6.2.1 + version: 6.2.1(esbuild@0.27.0)(rollup@4.53.2) typescript: specifier: 5.9.3 version: 5.9.3 ab-testing/frontend: devDependencies: - '@guardian/ab-testing': - specifier: workspace:ab-testing - version: link:.. + '@guardian/ab-testing-config': + specifier: workspace:ab-testing-config + version: link:../config '@sveltejs/adapter-auto': specifier: ^6.0.0 version: 6.1.1(@sveltejs/kit@2.46.5(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.40.0)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)))(svelte@5.40.0)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0))) @@ -289,7 +407,7 @@ importers: version: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) webpack-cli: specifier: 6.0.1 - version: 6.0.1(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.2.2)(webpack@5.102.1) + version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.102.1) webpack-dev-server: specifier: 5.2.2 version: 5.2.2(webpack-cli@6.0.1)(webpack@5.102.1) @@ -332,9 +450,9 @@ importers: '@guardian/ab-core': specifier: 8.0.0 version: 8.0.0(tslib@2.6.2)(typescript@5.5.3) - '@guardian/ab-testing': - specifier: workspace:ab-testing - version: link:../ab-testing + '@guardian/ab-testing-config': + specifier: workspace:ab-testing-config + version: link:../ab-testing/config '@guardian/braze-components': specifier: 22.2.0 version: 22.2.0(@emotion/react@11.14.0(@types/react@18.3.1)(react@18.3.1))(@guardian/libs@26.1.0(@guardian/ophan-tracker-js@2.6.3)(tslib@2.6.2)(typescript@5.5.3))(@guardian/source@11.3.0(@emotion/react@11.14.0(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1)(tslib@2.6.2)(typescript@5.5.3))(react@18.3.1) @@ -397,13 +515,13 @@ importers: version: 10.0.7(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2))) '@storybook/addon-docs': specifier: 10.0.7 - version: 10.0.7(@types/react@18.3.1)(esbuild@0.25.5)(rollup@4.52.4)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2))(webpack@5.102.1) + version: 10.0.7(@types/react@18.3.1)(esbuild@0.27.0)(rollup@4.53.2)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2))(webpack@5.102.1) '@storybook/addon-webpack5-compiler-swc': specifier: 4.0.2 version: 4.0.2(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(webpack@5.102.1) '@storybook/react-webpack5': specifier: 10.0.7 - version: 10.0.7(@swc/core@1.13.5)(esbuild@0.25.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(typescript@5.5.3)(webpack-cli@6.0.1) + version: 10.0.7(@swc/core@1.13.5)(esbuild@0.27.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(typescript@5.5.3)(webpack-cli@6.0.1) '@svgr/webpack': specifier: 8.1.0 version: 8.1.0(typescript@5.5.3) @@ -508,13 +626,13 @@ importers: version: 0.0.6 '@types/webpack-bundle-analyzer': specifier: 4.7.0 - version: 4.7.0(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) + version: 4.7.0(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1) '@types/webpack-env': specifier: 1.18.8 version: 1.18.8 '@types/webpack-node-externals': specifier: 3.0.4 - version: 3.0.4(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) + version: 3.0.4(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1) '@types/youtube': specifier: 0.0.50 version: 0.0.50 @@ -571,10 +689,10 @@ importers: version: 8.57.1 eslint-config-airbnb-base: specifier: 15.0.0 - version: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1))(eslint@8.57.1) + version: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1))(eslint@8.57.1) eslint-config-airbnb-typescript: specifier: 17.0.0 - version: 17.0.0(@typescript-eslint/eslint-plugin@8.22.0(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1)(typescript@5.5.3))(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1))(eslint@8.57.1) + version: 17.0.0(@typescript-eslint/eslint-plugin@8.22.0(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1)(typescript@5.5.3))(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-custom-elements: specifier: 0.0.8 version: 0.0.8(eslint@8.57.1) @@ -583,7 +701,7 @@ importers: version: 6.7.1(eslint@8.57.1) eslint-plugin-jsx-expressions: specifier: 1.3.1 - version: 1.3.1(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1)(typescript@5.5.3) + version: 1.3.1(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1)(typescript@5.5.3) eslint-plugin-mocha: specifier: 10.1.0 version: 10.1.0(eslint@8.57.1) @@ -745,7 +863,7 @@ importers: version: 4.2.3 webpack: specifier: 5.102.1 - version: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) + version: 5.102.1(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1) webpack-assets-manifest: specifier: 6.3.0 version: 6.3.0(webpack@5.102.1) @@ -851,8 +969,8 @@ packages: resolution: {integrity: sha512-eLLKMwORBJ32YyKRo2LhWtYAYoWdnEPZSo6CyD4QUcsOosvPGdJgz4s13O3AmC60Sn43X5g3Zc4vgKvhZCfkUw==} engines: {node: '>=18.0.0'} - '@aws-sdk/client-s3@3.842.0': - resolution: {integrity: sha512-T5Rh72Rcq1xIaM8KkTr1Wpr7/WPCYO++KrM+/Em0rq2jxpjMMhj77ITpgH7eEmNxWmwIndTwqpgfmbpNfk7Gbw==} + '@aws-sdk/client-s3@3.931.0': + resolution: {integrity: sha512-p+ZSRvmylk/pNImGDvLt3lOkILOexNcYvsCjvN2TR9X8RvxvPURISVp2qdGKdwUr/zkshteg1x/30GYlcTKs5g==} engines: {node: '>=18.0.0'} '@aws-sdk/client-ssm@3.621.0': @@ -885,6 +1003,10 @@ packages: resolution: {integrity: sha512-oEWXhe2RHiSPKxhrq1qp7M4fxOsxMIJc4d75z8tTLLm5ujlmTZYU3kd0l2uBBaZSlbkrMiefntT6XrGint1ibw==} engines: {node: '>=18.0.0'} + '@aws-sdk/client-sso@3.931.0': + resolution: {integrity: sha512-GM/CARsIUQGEspM9VhZaftFVXnNtFNUUXjpM1ePO4CHk1J/VFvXcsQr3SHWIs0F4Ll6pvy5LpcRlWW5pK7T4aQ==} + engines: {node: '>=18.0.0'} + '@aws-sdk/client-sts@3.621.0': resolution: {integrity: sha512-707uiuReSt+nAx6d0c21xLjLm2lxeKc7padxjv92CIrIocnQSlJPxSCM7r5zBhwiahJA6MNQwmTl2xznU67KgA==} engines: {node: '>=16.0.0'} @@ -901,6 +1023,10 @@ packages: resolution: {integrity: sha512-b/FVNyPxZMmBp+xDwANDgR6o5Ehh/RTY9U/labH56jJpte196Psru/FmQULX3S6kvIiafQA9JefWUq81SfWVLg==} engines: {node: '>=18.0.0'} + '@aws-sdk/core@3.931.0': + resolution: {integrity: sha512-l/b6AQbto4TuXL2FIm7Z+tbVjrp0LN7ESm97Sf3nneB0vjKtB6R0TS/IySzCYMgyOC3Hxz+Ka34HJXZk9eXTFw==} + engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-cognito-identity@3.621.0': resolution: {integrity: sha512-Q+3awvTVJSqIGRjCUQflRwKPKlZ0TfmL3EQHgFLhZZrToeBapEA62+FY+T70aTKAZZZZprlvYeFPtBloNd5ziA==} engines: {node: '>=16.0.0'} @@ -921,6 +1047,10 @@ packages: resolution: {integrity: sha512-Os8I5XtTLBBVyHJLxrEB06gSAZeFMH2jVoKhAaFybjOTiV7wnjBgjvWjRfStnnXs7p9d+vc/gd6wIZHjony5YQ==} engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-env@3.931.0': + resolution: {integrity: sha512-dTNBpkKXyBdcpEjyfgkE/EFU/0NRoukLs+Pj0S8K1Dg216J9uIijpi6CaBBN+HvnaTlEItm2tzXiJpPVI+TqHQ==} + engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-http@3.621.0': resolution: {integrity: sha512-/jc2tEsdkT1QQAI5Dvoci50DbSxtJrevemwFsm0B73pwCcOQZ5ZwwSdVqGsPutzYzUVx3bcXg3LRL7jLACqRIg==} engines: {node: '>=16.0.0'} @@ -933,6 +1063,10 @@ packages: resolution: {integrity: sha512-3KiGsTlqMnvthv90K88Uv3SvaUbmcTShBIVWYNaHdbrhrjVRR08dm2Y6XjQILazLf1NPFkxUou1YwCWK4nae1Q==} engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-http@3.931.0': + resolution: {integrity: sha512-7Ge26fhMDn51BTbHgopx5+uOl4I47k15BDzYc4YT6zyjS99uycYNCA7zB500DGTTn2HK27ZDTyAyhTKZGxRxbA==} + engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-ini@3.621.0': resolution: {integrity: sha512-0EWVnSc+JQn5HLnF5Xv405M8n4zfdx9gyGdpnCmAmFqEDHA8LmBdxJdpUk1Ovp/I5oPANhjojxabIW5f1uU0RA==} engines: {node: '>=16.0.0'} @@ -947,6 +1081,10 @@ packages: resolution: {integrity: sha512-/8x9LKKaLGarvF1++bFEFdIvd9/djBb+HTULbJAf4JVg3tUlpHtGe7uquuZaQkQGeW4XPbcpB9RMWx5YlZkw3w==} engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-ini@3.931.0': + resolution: {integrity: sha512-uzicpP7IHBxvAMjwGdmeke2bGTxjsKCSW7N48zuv0t0d56hmGHfcZIK5p4ry2OBJxzScp182OUAdAEG8wuSuuA==} + engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-node@3.621.0': resolution: {integrity: sha512-4JqpccUgz5Snanpt2+53hbOBbJQrSFq7E1sAAbgY6BKVQUsW5qyXqnjvSF32kDeKa5JpBl3bBWLZl04IadcPHw==} engines: {node: '>=16.0.0'} @@ -959,6 +1097,10 @@ packages: resolution: {integrity: sha512-Zz5tF/U4q9ir3rfVnPLlxbhMTHjPaPv78TarspFYn9mNN7cPVXBaXVVnMNu6ypZzBdTB8M44UYo827Qcw3kouA==} engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-node@3.931.0': + resolution: {integrity: sha512-eO8mfWNHz0dyYdVfPLVzmqXaSA3agZF/XvBO9/fRU90zCb8lKlXfgUmghGW7LhDkiv2v5uuizUiag7GsKoIcJw==} + engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-process@3.620.1': resolution: {integrity: sha512-hWqFMidqLAkaV9G460+1at6qa9vySbjQKKc04p59OT7lZ5cO5VH5S4aI05e+m4j364MBROjjk2ugNvfNf/8ILg==} engines: {node: '>=16.0.0'} @@ -971,6 +1113,10 @@ packages: resolution: {integrity: sha512-l1lZfHIl/z0SxXibt7wMQ2HmRIyIZjlOrT6a554xlO//y671uxPPwScVw7QW4fPIvwfmKbl8dYCwGI//AgQ0bA==} engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-process@3.931.0': + resolution: {integrity: sha512-8Mu9r+5BUKqmKSI/WYHl5o4GeoonEb51RmoLEqG6431Uz4Y8C6gzAT69yjOJ+MwoWQ2Os37OZLOTv7SgxyOgrQ==} + engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-sso@3.621.0': resolution: {integrity: sha512-Kza0jcFeA/GEL6xJlzR2KFf1PfZKMFnxfGzJzl5yN7EjoGdMijl34KaRyVnfRjnCWcsUpBWKNIDk9WZVMY9yiw==} engines: {node: '>=16.0.0'} @@ -983,6 +1129,10 @@ packages: resolution: {integrity: sha512-cwc9bmomjUqPDF58THUCmEnpAIsCFV3Y9FHlQmQbMkYUm7Wlrb5E2iFrZ4WDefAHuh25R/gtj+Yo74r3gl9kbw==} engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-sso@3.931.0': + resolution: {integrity: sha512-FP31lfMgNMDG4ZDX4NUZ+uoHWn76etcG8UWEgzZb4YOPV4M8a7gwU95iD+RBaK4lV3KvwH2tu68Hmne1qQpFqQ==} + engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-web-identity@3.621.0': resolution: {integrity: sha512-w7ASSyfNvcx7+bYGep3VBgC3K6vEdLmlpjT7nSIHxxQf+WSdvy+HynwJosrpZax0sK5q0D1Jpn/5q+r5lwwW6w==} engines: {node: '>=16.0.0'} @@ -997,6 +1147,10 @@ packages: resolution: {integrity: sha512-HFQgZm1+7WisJ8tqcZkNRRmnoFO+So+L12wViVxneVJ+OclfL2vE/CoKqHTozP6+JCOKMlv6Vi61Lu6xDtKdTA==} engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-web-identity@3.931.0': + resolution: {integrity: sha512-hfX0Buw2+ie0FBiSFMmnXfugQc9fO0KvEojnNnzhk4utlWjZobMcUprOQ/VKUueg0Kga1b1xu8gEP6g1aEh3zw==} + engines: {node: '>=18.0.0'} + '@aws-sdk/credential-providers@3.621.0': resolution: {integrity: sha512-FQbC7I8ae/72ZekLBa45jWJ+Q3d+YPhc3bW/rCks6RrldM6RgLTGr8pTOPCxHl828ky10RjkBiBmVU818rliyw==} engines: {node: '>=16.0.0'} @@ -1016,20 +1170,20 @@ packages: peerDependencies: '@aws-sdk/client-dynamodb': ^3.840.0 - '@aws-sdk/middleware-bucket-endpoint@3.840.0': - resolution: {integrity: sha512-+gkQNtPwcSMmlwBHFd4saVVS11In6ID1HczNzpM3MXKXRBfSlbZJbCt6wN//AZ8HMklZEik4tcEOG0qa9UY8SQ==} + '@aws-sdk/middleware-bucket-endpoint@3.930.0': + resolution: {integrity: sha512-cnCLWeKPYgvV4yRYPFH6pWMdUByvu2cy2BAlfsPpvnm4RaVioztyvxmQj5PmVN5fvWs5w/2d6U7le8X9iye2sA==} engines: {node: '>=18.0.0'} '@aws-sdk/middleware-endpoint-discovery@3.840.0': resolution: {integrity: sha512-IJDShY5NOg9luTE8h4o2Bm+gsPnHIU0tVWCjMz8vZMLevYjKdIsatcXiu3huTOjKSnelzC9fBHfU6KKsHmjjBQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-expect-continue@3.840.0': - resolution: {integrity: sha512-iJg2r6FKsKKvdiU4oCOuCf7Ro/YE0Q2BT/QyEZN3/Rt8Nr4SAZiQOlcBXOCpGvuIKOEAhvDOUnW3aDHL01PdVw==} + '@aws-sdk/middleware-expect-continue@3.930.0': + resolution: {integrity: sha512-5HEQ+JU4DrLNWeY27wKg/jeVa8Suy62ivJHOSUf6e6hZdVIMx0h/kXS1fHEQNNiLu2IzSEP/bFXsKBaW7x7s0g==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-flexible-checksums@3.840.0': - resolution: {integrity: sha512-Kg/o2G6o72sdoRH0J+avdcf668gM1bp6O4VeEXpXwUj/urQnV5qiB2q1EYT110INHUKWOLXPND3sQAqh6sTqHw==} + '@aws-sdk/middleware-flexible-checksums@3.931.0': + resolution: {integrity: sha512-eYWwUKeEommCrrm0Ro6fGDwVO0x2bL3niOmSnHIlIdpu7ruzAGaphj+2MekCxaSPORzkZ3yheHUzV45D8Qj63A==} engines: {node: '>=18.0.0'} '@aws-sdk/middleware-host-header@3.620.0': @@ -1044,8 +1198,12 @@ packages: resolution: {integrity: sha512-F9Lqeu80/aTM6S/izZ8RtwSmjfhWjIuxX61LX+/9mxJyEkgaECRxv0chsLQsLHJumkGnXRy/eIyMLBhcTPF5vg==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-location-constraint@3.840.0': - resolution: {integrity: sha512-KVLD0u0YMF3aQkVF8bdyHAGWSUY6N1Du89htTLgqCcIhSxxAJ9qifrosVZ9jkAzqRW99hcufyt2LylcVU2yoKQ==} + '@aws-sdk/middleware-host-header@3.930.0': + resolution: {integrity: sha512-x30jmm3TLu7b/b+67nMyoV0NlbnCVT5DI57yDrhXAPCtdgM1KtdLWt45UcHpKOm1JsaIkmYRh2WYu7Anx4MG0g==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/middleware-location-constraint@3.930.0': + resolution: {integrity: sha512-QIGNsNUdRICog+LYqmtJ03PLze6h2KCORXUs5td/hAEjVP5DMmubhtrGg1KhWyctACluUH/E/yrD14p4pRXxwA==} engines: {node: '>=18.0.0'} '@aws-sdk/middleware-logger@3.609.0': @@ -1060,6 +1218,10 @@ packages: resolution: {integrity: sha512-3LJyyfs1USvRuRDla1pGlzGRtXJBXD1zC9F+eE9Iz/V5nkmhyv52A017CvKWmYoR0DM9dzjLyPOI0BSSppEaTw==} engines: {node: '>=18.0.0'} + '@aws-sdk/middleware-logger@3.930.0': + resolution: {integrity: sha512-vh4JBWzMCBW8wREvAwoSqB2geKsZwSHTa0nSt0OMOLp2PdTYIZDi0ZiVMmpfnjcx9XbS6aSluLv9sKx4RrG46A==} + engines: {node: '>=18.0.0'} + '@aws-sdk/middleware-recursion-detection@3.620.0': resolution: {integrity: sha512-nh91S7aGK3e/o1ck64sA/CyoFw+gAYj2BDOnoNa6ouyCrVJED96ZXWbhye/fz9SgmNUZR2g7GdVpiLpMKZoI5w==} engines: {node: '>=16.0.0'} @@ -1072,12 +1234,16 @@ packages: resolution: {integrity: sha512-m/oLz0EoCy+WoIVBnXRXJ4AtGpdl0kPE7U+VH9TsuUzHgxY1Re/176Q1HWLBRVlz4gr++lNsgsMWEC+VnAwMpw==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-sdk-s3@3.840.0': - resolution: {integrity: sha512-rOUji7CayWN3O09zvvgLzDVQe0HiJdZkxoTS6vzOS3WbbdT7joGdVtAJHtn+x776QT3hHzbKU5gnfhel0o6gQA==} + '@aws-sdk/middleware-recursion-detection@3.930.0': + resolution: {integrity: sha512-gv0sekNpa2MBsIhm2cjP3nmYSfI4nscx/+K9u9ybrWZBWUIC4kL2sV++bFjjUz4QxUIlvKByow3/a9ARQyCu7Q==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/middleware-sdk-s3@3.931.0': + resolution: {integrity: sha512-uWF78ht8Wgxljn6y0cEcIWfbeTVnJ0cE1Gha9ScCqscmuBCpHuFMSd/p53w3whoDhpQL3ln9mOyY3tfST/NUQA==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-ssec@3.840.0': - resolution: {integrity: sha512-CBZP9t1QbjDFGOrtnUEHL1oAvmnCUUm7p0aPNbIdSzNtH42TNKjPRN3TuEIJDGjkrqpL3MXyDSmNayDcw/XW7Q==} + '@aws-sdk/middleware-ssec@3.930.0': + resolution: {integrity: sha512-N2/SvodmaDS6h7CWfuapt3oJyn1T2CBz0CsDIiTDv9cSagXAVFjPdm2g4PFJqrNBeqdDIoYBnnta336HmamWHg==} engines: {node: '>=18.0.0'} '@aws-sdk/middleware-user-agent@3.620.0': @@ -1092,6 +1258,10 @@ packages: resolution: {integrity: sha512-djpnECwDLI/4sck1wxK/cZJmZX5pAhRvjONyJqr0AaOfJyuIAG0PHLe7xwCrv2rCAvIBR9ofnNFzPIGTJPDUwg==} engines: {node: '>=18.0.0'} + '@aws-sdk/middleware-user-agent@3.931.0': + resolution: {integrity: sha512-Ftd+f3+y5KNYKzLXaGknwJ9hCkFWshi5C9TLLsz+fEohWc1FvIKU7MlXTeFms2eN76TTVHuG8N2otaujl6CuHg==} + engines: {node: '>=18.0.0'} + '@aws-sdk/nested-clients@3.840.0': resolution: {integrity: sha512-LXYYo9+n4hRqnRSIMXLBb+BLz+cEmjMtTudwK1BF6Bn2RfdDv29KuyeDRrPCS3TwKl7ZKmXUmE9n5UuHAPfBpA==} engines: {node: '>=18.0.0'} @@ -1100,6 +1270,10 @@ packages: resolution: {integrity: sha512-Jr/smgVrLZECQgMyP4nbGqgJwzFFbkjOVrU8wh/gbVIZy1+Gu6R7Shai7KHDkEjwkGcHpN1MCCO67jTAOoSlMw==} engines: {node: '>=18.0.0'} + '@aws-sdk/nested-clients@3.931.0': + resolution: {integrity: sha512-6/dXrX2nWgiWdHxooEtmKpOErms4+79AQawEvhhxpLPpa+tixl4i/MSFgHk9sjkGv5a1/P3DbnedpZWl+2wMOg==} + engines: {node: '>=18.0.0'} + '@aws-sdk/region-config-resolver@3.614.0': resolution: {integrity: sha512-vDCeMXvic/LU0KFIUjpC3RiSTIkkvESsEfbVHiHH0YINfl8HnEqR5rj+L8+phsCeVg2+LmYwYxd5NRz4PHxt5g==} engines: {node: '>=16.0.0'} @@ -1112,8 +1286,12 @@ packages: resolution: {integrity: sha512-gzQAkuHI3xyG6toYnH/pju+kc190XmvnB7X84vtN57GjgdQJICt9So/BD0U6h+eSfk9VBnafkVrAzBzWMEFZVw==} engines: {node: '>=18.0.0'} - '@aws-sdk/signature-v4-multi-region@3.840.0': - resolution: {integrity: sha512-8AoVgHrkSfhvGPtwx23hIUO4MmMnux2pjnso1lrLZGqxfElM6jm2w4jTNLlNXk8uKHGyX89HaAIuT0lL6dJj9g==} + '@aws-sdk/region-config-resolver@3.930.0': + resolution: {integrity: sha512-KL2JZqH6aYeQssu1g1KuWsReupdfOoxD6f1as2VC+rdwYFUu4LfzMsFfXnBvvQWWqQ7rZHWOw1T+o5gJmg7Dzw==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/signature-v4-multi-region@3.931.0': + resolution: {integrity: sha512-EGYYDSSk7k1xbSHtb8MfEMILf5achdNnnsYKgFk0+Oul3tPQ4xUmOt5qRP6sOO3/LQHF37gBYHUF9OSA/+uVCw==} engines: {node: '>=18.0.0'} '@aws-sdk/token-providers@3.614.0': @@ -1130,6 +1308,10 @@ packages: resolution: {integrity: sha512-dQr3pFpzemKyrB7SEJ2ipPtWrZiL5vaimg2PkXpwyzGrigYRc8F2R9DMUckU5zi32ozvQqq4PI3bOrw6xUfcbQ==} engines: {node: '>=18.0.0'} + '@aws-sdk/token-providers@3.931.0': + resolution: {integrity: sha512-dr+02X9oxqmXG0856odFJ7wAXy12pr/tq2Zg+IS0TDThFvgtvx4yChkpqmc89wGoW+Aly47JPfPUXh0IMpGzIg==} + engines: {node: '>=18.0.0'} + '@aws-sdk/types@3.609.0': resolution: {integrity: sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q==} engines: {node: '>=16.0.0'} @@ -1142,8 +1324,12 @@ packages: resolution: {integrity: sha512-o67gL3vjf4nhfmuSUNNkit0d62QJEwwHLxucwVJkR/rw9mfUtAWsgBs8Tp16cdUbMgsyQtCQilL8RAJDoGtadQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/util-arn-parser@3.804.0': - resolution: {integrity: sha512-wmBJqn1DRXnZu3b4EkE6CWnoWMo1ZMvlfkqU5zPz67xx1GMaXlDCchFvKAXMjk4jn/L1O3tKnoFDNsoLV1kgNQ==} + '@aws-sdk/types@3.930.0': + resolution: {integrity: sha512-we/vaAgwlEFW7IeftmCLlLMw+6hFs3DzZPJw7lVHbj/5HJ0bz9gndxEsS2lQoeJ1zhiiLqAqvXxmM43s0MBg0A==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/util-arn-parser@3.893.0': + resolution: {integrity: sha512-u8H4f2Zsi19DGnwj5FSZzDMhytYF/bCh37vAtBsn3cNDL3YG578X5oc+wSX54pM3tOxS+NY7tvOAo52SW7koUA==} engines: {node: '>=18.0.0'} '@aws-sdk/util-dynamodb@3.840.0': @@ -1164,6 +1350,10 @@ packages: resolution: {integrity: sha512-6XgdNe42ibP8zCQgNGDWoOF53RfEKzpU/S7Z29FTTJ7hcZv0SytC0ZNQQZSx4rfBl036YWYwJRoJMlT4AA7q9A==} engines: {node: '>=18.0.0'} + '@aws-sdk/util-endpoints@3.930.0': + resolution: {integrity: sha512-M2oEKBzzNAYr136RRc6uqw3aWlwCxqTP1Lawps9E1d2abRPvl1p1ztQmmXp1Ak4rv8eByIZ+yQyKQ3zPdRG5dw==} + engines: {node: '>=18.0.0'} + '@aws-sdk/util-locate-window@3.465.0': resolution: {integrity: sha512-f+QNcWGswredzC1ExNAB/QzODlxwaTdXkNT5cvke2RLX8SFU5pYk6h4uCtWC0vWPELzOfMfloBrJefBzlarhsw==} engines: {node: '>=14.0.0'} @@ -1177,6 +1367,9 @@ packages: '@aws-sdk/util-user-agent-browser@3.910.0': resolution: {integrity: sha512-iOdrRdLZHrlINk9pezNZ82P/VxO/UmtmpaOAObUN+xplCUJu31WNM2EE/HccC8PQw6XlAudpdA6HDTGiW6yVGg==} + '@aws-sdk/util-user-agent-browser@3.930.0': + resolution: {integrity: sha512-q6lCRm6UAe+e1LguM5E4EqM9brQlDem4XDcQ87NzEvlTW6GzmNCO0w1jS0XgCFXQHjDxjdlNFX+5sRbHijwklg==} + '@aws-sdk/util-user-agent-node@3.614.0': resolution: {integrity: sha512-15ElZT88peoHnq5TEoEtZwoXTXRxNrk60TZNdpl/TUBJ5oNJ9Dqb5Z4ryb8ofN6nm9aFf59GVAerFDz8iUoHBA==} engines: {node: '>=16.0.0'} @@ -1204,6 +1397,15 @@ packages: aws-crt: optional: true + '@aws-sdk/util-user-agent-node@3.931.0': + resolution: {integrity: sha512-j5if01rt7JCGYDVXck39V7IUyKAN73vKUPzmu+jp1apU3Q0lLSTZA/HCfL2HkMUKVLE67ibjKb+NCoEg0QhujA==} + engines: {node: '>=18.0.0'} + peerDependencies: + aws-crt: '>=1.0.0' + peerDependenciesMeta: + aws-crt: + optional: true + '@aws-sdk/xml-builder@3.821.0': resolution: {integrity: sha512-DIIotRnefVL6DiaHtO6/21DhJ4JZnnIwdNbpwiAhdt/AVbttcE4yw925gsjur0OGv5BTYXQXU3YnANBYnZjuQA==} engines: {node: '>=18.0.0'} @@ -1212,10 +1414,18 @@ packages: resolution: {integrity: sha512-UK0NzRknzUITYlkDibDSgkWvhhC11OLhhhGajl6pYCACup+6QE4SsLvmAGMkyNtGVCJ6Q+BM6PwDCBZyBgwl9A==} engines: {node: '>=18.0.0'} + '@aws-sdk/xml-builder@3.930.0': + resolution: {integrity: sha512-YIfkD17GocxdmlUVc3ia52QhcWuRIUJonbF8A2CYfcWNV3HzvAqpcPeC0bYUhkK+8e8YO1ARnLKZQE0TlwzorA==} + engines: {node: '>=18.0.0'} + '@aws/lambda-invoke-store@0.0.1': resolution: {integrity: sha512-ORHRQ2tmvnBXc8t/X9Z8IcSbBA4xTLKuN873FopzklHMeqBst7YG0d+AX97inkvDX+NChYtSr+qGfcqGFaI8Zw==} engines: {node: '>=18.0.0'} + '@aws/lambda-invoke-store@0.1.1': + resolution: {integrity: sha512-RcLam17LdlbSOSp9VxmUu1eI6Mwxp+OwhD2QhiSNmNCzoDb0EeUXTD2n/WbcnrAYMGlmf05th6QYq23VqvJqpA==} + engines: {node: '>=18.0.0'} + '@babel/code-frame@7.27.1': resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} @@ -1979,6 +2189,12 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.27.0': + resolution: {integrity: sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.18.20': resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} engines: {node: '>=12'} @@ -1991,6 +2207,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.27.0': + resolution: {integrity: sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.18.20': resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} engines: {node: '>=12'} @@ -2003,6 +2225,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.27.0': + resolution: {integrity: sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.18.20': resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} engines: {node: '>=12'} @@ -2015,6 +2243,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.27.0': + resolution: {integrity: sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.18.20': resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} engines: {node: '>=12'} @@ -2027,6 +2261,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.27.0': + resolution: {integrity: sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.18.20': resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} engines: {node: '>=12'} @@ -2039,6 +2279,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.27.0': + resolution: {integrity: sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.18.20': resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} engines: {node: '>=12'} @@ -2051,6 +2297,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.27.0': + resolution: {integrity: sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.18.20': resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} engines: {node: '>=12'} @@ -2063,6 +2315,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.27.0': + resolution: {integrity: sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.18.20': resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} engines: {node: '>=12'} @@ -2075,6 +2333,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.27.0': + resolution: {integrity: sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.18.20': resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} engines: {node: '>=12'} @@ -2087,6 +2351,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.27.0': + resolution: {integrity: sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.18.20': resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} engines: {node: '>=12'} @@ -2099,6 +2369,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.27.0': + resolution: {integrity: sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.18.20': resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} engines: {node: '>=12'} @@ -2111,6 +2387,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.27.0': + resolution: {integrity: sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.18.20': resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} engines: {node: '>=12'} @@ -2123,6 +2405,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.27.0': + resolution: {integrity: sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.18.20': resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} engines: {node: '>=12'} @@ -2135,6 +2423,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.27.0': + resolution: {integrity: sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.18.20': resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} engines: {node: '>=12'} @@ -2147,6 +2441,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.27.0': + resolution: {integrity: sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.18.20': resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} engines: {node: '>=12'} @@ -2159,6 +2459,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.27.0': + resolution: {integrity: sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.18.20': resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} engines: {node: '>=12'} @@ -2171,12 +2477,24 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.27.0': + resolution: {integrity: sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.25.5': resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.27.0': + resolution: {integrity: sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.18.20': resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} engines: {node: '>=12'} @@ -2189,12 +2507,24 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.27.0': + resolution: {integrity: sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.25.5': resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.27.0': + resolution: {integrity: sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.18.20': resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} engines: {node: '>=12'} @@ -2207,6 +2537,18 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.27.0': + resolution: {integrity: sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.0': + resolution: {integrity: sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.18.20': resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} engines: {node: '>=12'} @@ -2219,6 +2561,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.27.0': + resolution: {integrity: sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.18.20': resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} engines: {node: '>=12'} @@ -2231,6 +2579,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.27.0': + resolution: {integrity: sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.18.20': resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} engines: {node: '>=12'} @@ -2243,6 +2597,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.27.0': + resolution: {integrity: sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.18.20': resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} engines: {node: '>=12'} @@ -2255,6 +2615,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.27.0': + resolution: {integrity: sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-plugin-eslint-comments@4.4.1': resolution: {integrity: sha512-lb/Z/MzbTf7CaVYM9WCFNQZ4L1yi3ev2fsFPF99h31ljhSEyUoyEsKsNWiU+qD1glbYTDJdqgyaLKtyTkkqtuQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2790,113 +3156,149 @@ packages: '@polka/url@1.0.0-next.24': resolution: {integrity: sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==} - '@rollup/rollup-android-arm-eabi@4.52.4': - resolution: {integrity: sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==} + '@rollup/plugin-commonjs@29.0.0': + resolution: {integrity: sha512-U2YHaxR2cU/yAiwKJtJRhnyLk7cifnQw0zUpISsocBDoHDJn+HTV74ABqnwr5bEgWUwFZC9oFL6wLe21lHu5eQ==} + engines: {node: '>=16.0.0 || 14 >= 14.17'} + peerDependencies: + rollup: ^2.68.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-json@6.1.0': + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-node-resolve@16.0.3': + resolution: {integrity: sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.53.2': + resolution: {integrity: sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.52.4': - resolution: {integrity: sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==} + '@rollup/rollup-android-arm64@4.53.2': + resolution: {integrity: sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.52.4': - resolution: {integrity: sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==} + '@rollup/rollup-darwin-arm64@4.53.2': + resolution: {integrity: sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.52.4': - resolution: {integrity: sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==} + '@rollup/rollup-darwin-x64@4.53.2': + resolution: {integrity: sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.52.4': - resolution: {integrity: sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==} + '@rollup/rollup-freebsd-arm64@4.53.2': + resolution: {integrity: sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.52.4': - resolution: {integrity: sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==} + '@rollup/rollup-freebsd-x64@4.53.2': + resolution: {integrity: sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.52.4': - resolution: {integrity: sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==} + '@rollup/rollup-linux-arm-gnueabihf@4.53.2': + resolution: {integrity: sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.52.4': - resolution: {integrity: sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==} + '@rollup/rollup-linux-arm-musleabihf@4.53.2': + resolution: {integrity: sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.52.4': - resolution: {integrity: sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==} + '@rollup/rollup-linux-arm64-gnu@4.53.2': + resolution: {integrity: sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.52.4': - resolution: {integrity: sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==} + '@rollup/rollup-linux-arm64-musl@4.53.2': + resolution: {integrity: sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.52.4': - resolution: {integrity: sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==} + '@rollup/rollup-linux-loong64-gnu@4.53.2': + resolution: {integrity: sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.52.4': - resolution: {integrity: sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==} + '@rollup/rollup-linux-ppc64-gnu@4.53.2': + resolution: {integrity: sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.52.4': - resolution: {integrity: sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==} + '@rollup/rollup-linux-riscv64-gnu@4.53.2': + resolution: {integrity: sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.52.4': - resolution: {integrity: sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==} + '@rollup/rollup-linux-riscv64-musl@4.53.2': + resolution: {integrity: sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.52.4': - resolution: {integrity: sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==} + '@rollup/rollup-linux-s390x-gnu@4.53.2': + resolution: {integrity: sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.52.4': - resolution: {integrity: sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==} + '@rollup/rollup-linux-x64-gnu@4.53.2': + resolution: {integrity: sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.52.4': - resolution: {integrity: sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==} + '@rollup/rollup-linux-x64-musl@4.53.2': + resolution: {integrity: sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==} cpu: [x64] os: [linux] - '@rollup/rollup-openharmony-arm64@4.52.4': - resolution: {integrity: sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==} + '@rollup/rollup-openharmony-arm64@4.53.2': + resolution: {integrity: sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.52.4': - resolution: {integrity: sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==} + '@rollup/rollup-win32-arm64-msvc@4.53.2': + resolution: {integrity: sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.52.4': - resolution: {integrity: sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==} + '@rollup/rollup-win32-ia32-msvc@4.53.2': + resolution: {integrity: sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.52.4': - resolution: {integrity: sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==} + '@rollup/rollup-win32-x64-gnu@4.53.2': + resolution: {integrity: sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.52.4': - resolution: {integrity: sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==} + '@rollup/rollup-win32-x64-msvc@4.53.2': + resolution: {integrity: sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==} cpu: [x64] os: [win32] @@ -2947,30 +3349,22 @@ packages: resolution: {integrity: sha512-MBJBiidoe+0cTFhyxT8g+9g7CeVccLM0IOKKUMCNQ1CNMJ/eIfoo0RTfVrXOONEI1UCN1W+zkiHSbzUNE9dZtQ==} engines: {node: '>=16.0.0'} - '@smithy/abort-controller@4.2.3': - resolution: {integrity: sha512-xWL9Mf8b7tIFuAlpjKtRPnHrR8XVrwTj5NPYO/QwZPtc0SDLsPxb56V5tzi5yspSMytISHybifez+4jlrx0vkQ==} - engines: {node: '>=18.0.0'} - '@smithy/abort-controller@4.2.5': resolution: {integrity: sha512-j7HwVkBw68YW8UmFRcjZOmssE77Rvk0GWAIN1oFBhsaovQmZWYCIcGa9/pwRB0ExI8Sk9MWNALTjftjHZea7VA==} engines: {node: '>=18.0.0'} - '@smithy/chunked-blob-reader-native@4.0.0': - resolution: {integrity: sha512-R9wM2yPmfEMsUmlMlIgSzOyICs0x9uu7UTHoccMyt7BWw8shcGM8HqB355+BZCPBcySvbTYMs62EgEQkNxz2ig==} + '@smithy/chunked-blob-reader-native@4.2.1': + resolution: {integrity: sha512-lX9Ay+6LisTfpLid2zZtIhSEjHMZoAR5hHCR4H7tBz/Zkfr5ea8RcQ7Tk4mi0P76p4cN+Btz16Ffno7YHpKXnQ==} engines: {node: '>=18.0.0'} - '@smithy/chunked-blob-reader@5.0.0': - resolution: {integrity: sha512-+sKqDBQqb036hh4NPaUiEkYFkTUGYzRsn3EuFhyfQfMy6oGHEUJDurLP9Ufb5dasr/XiAmPNMr6wa9afjQB+Gw==} + '@smithy/chunked-blob-reader@5.2.0': + resolution: {integrity: sha512-WmU0TnhEAJLWvfSeMxBNe5xtbselEO8+4wG0NtZeL8oR21WgH1xiO37El+/Y+H/Ie4SCwBy3MxYWmOYaGgZueA==} engines: {node: '>=18.0.0'} '@smithy/config-resolver@3.0.5': resolution: {integrity: sha512-SkW5LxfkSI1bUC74OtfBbdz+grQXYiPYolyu8VfpLIjEoN/sHVBlLeGXMQ1vX4ejkgfv6sxVbQJ32yF2cl1veA==} engines: {node: '>=16.0.0'} - '@smithy/config-resolver@4.3.3': - resolution: {integrity: sha512-xSql8A1Bl41O9JvGU/CtgiLBlwkvpHTSKRlvz9zOBvBCPjXghZ6ZkcVzmV2f7FLAA+80+aqKmIOmy8pEDrtCaw==} - engines: {node: '>=18.0.0'} - '@smithy/config-resolver@4.4.3': resolution: {integrity: sha512-ezHLe1tKLUxDJo2LHtDuEDyWXolw8WGOR92qb4bQdWq/zKenO5BvctZGrVJBK08zjezSk7bmbKFOXIVyChvDLw==} engines: {node: '>=18.0.0'} @@ -2979,12 +3373,8 @@ packages: resolution: {integrity: sha512-BC7VMXx/1BCmRPCVzzn4HGWAtsrb7/0758EtwOGFJQrlSwJBEjCcDLNZLFoL/68JexYa2s+KmgL/UfmXdG6v1w==} engines: {node: '>=16.0.0'} - '@smithy/core@3.17.0': - resolution: {integrity: sha512-Tir3DbfoTO97fEGUZjzGeoXgcQAUBRDTmuH9A8lxuP8ATrgezrAJ6cLuRvwdKN4ZbYNlHgKlBX69Hyu3THYhtg==} - engines: {node: '>=18.0.0'} - - '@smithy/core@3.18.0': - resolution: {integrity: sha512-vGSDXOJFZgOPTatSI1ly7Gwyy/d/R9zh2TO3y0JZ0uut5qQ88p9IaWaZYIWSSqtdekNM4CGok/JppxbAff4KcQ==} + '@smithy/core@3.18.3': + resolution: {integrity: sha512-qqpNskkbHOSfrbFbjhYj5o8VMXO26fvN1K/+HbCzUNlTuxgNcPRouUDNm+7D6CkN244WG7aK533Ne18UtJEgAA==} engines: {node: '>=18.0.0'} deprecated: Please upgrade your lockfile to use the latest 3.x version of @smithy/core for various fixes, see https://github.com/smithy-lang/smithy-typescript/blob/main/packages/core/CHANGELOG.md @@ -3000,64 +3390,52 @@ packages: resolution: {integrity: sha512-BZwotjoZWn9+36nimwm/OLIcVe+KYRwzMjfhd4QT7QxPm9WY0HiOV8t/Wlh+HVUif0SBVV7ksq8//hPaBC/okQ==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-codec@4.0.4': - resolution: {integrity: sha512-7XoWfZqWb/QoR/rAU4VSi0mWnO2vu9/ltS6JZ5ZSZv0eovLVfDfu0/AX4ub33RsJTOth3TiFWSHS5YdztvFnig==} + '@smithy/eventstream-codec@4.2.5': + resolution: {integrity: sha512-Ogt4Zi9hEbIP17oQMd68qYOHUzmH47UkK7q7Gl55iIm9oKt27MUGrC5JfpMroeHjdkOliOA4Qt3NQ1xMq/nrlA==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-browser@4.0.4': - resolution: {integrity: sha512-3fb/9SYaYqbpy/z/H3yIi0bYKyAa89y6xPmIqwr2vQiUT2St+avRt8UKwsWt9fEdEasc5d/V+QjrviRaX1JRFA==} + '@smithy/eventstream-serde-browser@4.2.5': + resolution: {integrity: sha512-HohfmCQZjppVnKX2PnXlf47CW3j92Ki6T/vkAT2DhBR47e89pen3s4fIa7otGTtrVxmj7q+IhH0RnC5kpR8wtw==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-config-resolver@4.1.2': - resolution: {integrity: sha512-JGtambizrWP50xHgbzZI04IWU7LdI0nh/wGbqH3sJesYToMi2j/DcoElqyOcqEIG/D4tNyxgRuaqBXWE3zOFhQ==} + '@smithy/eventstream-serde-config-resolver@4.3.5': + resolution: {integrity: sha512-ibjQjM7wEXtECiT6my1xfiMH9IcEczMOS6xiCQXoUIYSj5b1CpBbJ3VYbdwDy8Vcg5JHN7eFpOCGk8nyZAltNQ==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-node@4.0.4': - resolution: {integrity: sha512-RD6UwNZ5zISpOWPuhVgRz60GkSIp0dy1fuZmj4RYmqLVRtejFqQ16WmfYDdoSoAjlp1LX+FnZo+/hkdmyyGZ1w==} + '@smithy/eventstream-serde-node@4.2.5': + resolution: {integrity: sha512-+elOuaYx6F2H6x1/5BQP5ugv12nfJl66GhxON8+dWVUEDJ9jah/A0tayVdkLRP0AeSac0inYkDz5qBFKfVp2Gg==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-universal@4.0.4': - resolution: {integrity: sha512-UeJpOmLGhq1SLox79QWw/0n2PFX+oPRE1ZyRMxPIaFEfCqWaqpB7BU9C8kpPOGEhLF7AwEqfFbtwNxGy4ReENA==} + '@smithy/eventstream-serde-universal@4.2.5': + resolution: {integrity: sha512-G9WSqbST45bmIFaeNuP/EnC19Rhp54CcVdX9PDL1zyEB514WsDVXhlyihKlGXnRycmHNmVv88Bvvt4EYxWef/Q==} engines: {node: '>=18.0.0'} '@smithy/fetch-http-handler@3.2.4': resolution: {integrity: sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==} - '@smithy/fetch-http-handler@5.3.4': - resolution: {integrity: sha512-bwigPylvivpRLCm+YK9I5wRIYjFESSVwl8JQ1vVx/XhCw0PtCi558NwTnT2DaVCl5pYlImGuQTSwMsZ+pIavRw==} - engines: {node: '>=18.0.0'} - '@smithy/fetch-http-handler@5.3.6': resolution: {integrity: sha512-3+RG3EA6BBJ/ofZUeTFJA7mHfSYrZtQIrDP9dI8Lf7X6Jbos2jptuLrAAteDiFVrmbEmLSuRG/bUKzfAXk7dhg==} engines: {node: '>=18.0.0'} - '@smithy/hash-blob-browser@4.0.4': - resolution: {integrity: sha512-WszRiACJiQV3QG6XMV44i5YWlkrlsM5Yxgz4jvsksuu7LDXA6wAtypfPajtNTadzpJy3KyJPoWehYpmZGKUFIQ==} + '@smithy/hash-blob-browser@4.2.6': + resolution: {integrity: sha512-8P//tA8DVPk+3XURk2rwcKgYwFvwGwmJH/wJqQiSKwXZtf/LiZK+hbUZmPj/9KzM+OVSwe4o85KTp5x9DUZTjw==} engines: {node: '>=18.0.0'} '@smithy/hash-node@3.0.3': resolution: {integrity: sha512-2ctBXpPMG+B3BtWSGNnKELJ7SH9e4TNefJS0cd2eSkOOROeBnnVBnAy9LtJ8tY4vUEoe55N4CNPxzbWvR39iBw==} engines: {node: '>=16.0.0'} - '@smithy/hash-node@4.2.3': - resolution: {integrity: sha512-6+NOdZDbfuU6s1ISp3UOk5Rg953RJ2aBLNLLBEcamLjHAg1Po9Ha7QIB5ZWhdRUVuOUrT8BVFR+O2KIPmw027g==} - engines: {node: '>=18.0.0'} - '@smithy/hash-node@4.2.5': resolution: {integrity: sha512-DpYX914YOfA3UDT9CN1BM787PcHfWRBB43fFGCYrZFUH0Jv+5t8yYl+Pd5PW4+QzoGEDvn5d5QIO4j2HyYZQSA==} engines: {node: '>=18.0.0'} - '@smithy/hash-stream-node@4.0.4': - resolution: {integrity: sha512-wHo0d8GXyVmpmMh/qOR0R7Y46/G1y6OR8U+bSTB4ppEzRxd1xVAQ9xOE9hOc0bSjhz0ujCPAbfNLkLrpa6cevg==} + '@smithy/hash-stream-node@4.2.5': + resolution: {integrity: sha512-6+do24VnEyvWcGdHXomlpd0m8bfZePpUKBy7m311n+JuRwug8J4dCanJdTymx//8mi0nlkflZBvJe+dEO/O12Q==} engines: {node: '>=18.0.0'} '@smithy/invalid-dependency@3.0.3': resolution: {integrity: sha512-ID1eL/zpDULmHJbflb864k72/SNOZCADRc9i7Exq3RUNJw6raWUSlFEQ+3PX3EYs++bTxZB2dE9mEHTQLv61tw==} - '@smithy/invalid-dependency@4.2.3': - resolution: {integrity: sha512-Cc9W5DwDuebXEDMpOpl4iERo8I0KFjTnomK2RMdhhR87GwrSmUmwMxS4P5JdRf+LsjOdIqumcerwRgYMr/tZ9Q==} - engines: {node: '>=18.0.0'} - '@smithy/invalid-dependency@4.2.5': resolution: {integrity: sha512-2L2erASEro1WC5nV+plwIMxrTXpvpfzl4e+Nre6vBVRR2HKeGGcvpJyyL3/PpiSg+cJG2KpTmZmq934Olb6e5A==} engines: {node: '>=18.0.0'} @@ -3074,8 +3452,8 @@ packages: resolution: {integrity: sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==} engines: {node: '>=18.0.0'} - '@smithy/md5-js@4.0.4': - resolution: {integrity: sha512-uGLBVqcOwrLvGh/v/jw423yWHq/ofUGK1W31M2TNspLQbUV1Va0F5kTxtirkoHawODAZcjXTSGi7JwbnPcDPJg==} + '@smithy/md5-js@4.2.5': + resolution: {integrity: sha512-Bt6jpSTMWfjCtC0s79gZ/WZ1w90grfmopVOWqkI2ovhjpD5Q2XRXuecIPB9689L2+cCySMbaXDhBPU56FKNDNg==} engines: {node: '>=18.0.0'} '@smithy/middleware-compression@3.0.7': @@ -3090,10 +3468,6 @@ packages: resolution: {integrity: sha512-ILEzC2eyxx6ncej3zZSwMpB5RJ0zuqH7eMptxC4KN3f+v9bqT8ohssKbhNR78k/2tWW+KS5Spw+tbPF4Ejyqvw==} engines: {node: '>=16.0.0'} - '@smithy/middleware-content-length@4.2.3': - resolution: {integrity: sha512-/atXLsT88GwKtfp5Jr0Ks1CSa4+lB+IgRnkNrrYP0h1wL4swHNb0YONEvTceNKNdZGJsye+W2HH8W7olbcPUeA==} - engines: {node: '>=18.0.0'} - '@smithy/middleware-content-length@4.2.5': resolution: {integrity: sha512-Y/RabVa5vbl5FuHYV2vUCwvh/dqzrEY/K2yWPSqvhFUwIY0atLqO4TienjBXakoy4zrKAMCZwg+YEqmH7jaN7A==} engines: {node: '>=18.0.0'} @@ -3102,34 +3476,22 @@ packages: resolution: {integrity: sha512-5y5aiKCEwg9TDPB4yFE7H6tYvGFf1OJHNczeY10/EFF8Ir8jZbNntQJxMWNfeQjC1mxPsaQ6mR9cvQbf+0YeMw==} engines: {node: '>=16.0.0'} - '@smithy/middleware-endpoint@4.3.4': - resolution: {integrity: sha512-/RJhpYkMOaUZoJEkddamGPPIYeKICKXOu/ojhn85dKDM0n5iDIhjvYAQLP3K5FPhgB203O3GpWzoK2OehEoIUw==} - engines: {node: '>=18.0.0'} - - '@smithy/middleware-endpoint@4.3.7': - resolution: {integrity: sha512-i8Mi8OuY6Yi82Foe3iu7/yhBj1HBRoOQwBSsUNYglJTNSFaWYTNM2NauBBs/7pq2sqkLRqeUXA3Ogi2utzpUlQ==} + '@smithy/middleware-endpoint@4.3.10': + resolution: {integrity: sha512-SoAag3QnWBFoXjwa1jenEThkzJYClidZUyqsLKwWZ8kOlZBwehrLBp4ygVDjNEM2a2AamCQ2FBA/HuzKJ/LiTA==} engines: {node: '>=18.0.0'} '@smithy/middleware-retry@3.0.13': resolution: {integrity: sha512-zvCLfaRYCaUmjbF2yxShGZdolSHft7NNCTA28HVN9hKcEbOH+g5irr1X9s+in8EpambclGnevZY4A3lYpvDCFw==} engines: {node: '>=16.0.0'} - '@smithy/middleware-retry@4.4.4': - resolution: {integrity: sha512-vSgABQAkuUHRO03AhR2rWxVQ1un284lkBn+NFawzdahmzksAoOeVMnXXsuPViL4GlhRHXqFaMlc8Mj04OfQk1w==} - engines: {node: '>=18.0.0'} - - '@smithy/middleware-retry@4.4.7': - resolution: {integrity: sha512-E7Vc6WHCHlzDRTx1W0jZ6J1L6ziEV0PIWcUdmfL4y+c8r7WYr6I+LkQudaD8Nfb7C5c4P3SQ972OmXHtv6m/OA==} + '@smithy/middleware-retry@4.4.10': + resolution: {integrity: sha512-6fOwX34gXxcqKa3bsG0mR0arc2Cw4ddOS6tp3RgUD2yoTrDTbQ2aVADnDjhUuxaiDZN2iilxndgGDhnpL/XvJA==} engines: {node: '>=18.0.0'} '@smithy/middleware-serde@3.0.3': resolution: {integrity: sha512-puUbyJQBcg9eSErFXjKNiGILJGtiqmuuNKEYNYfUD57fUl4i9+mfmThtQhvFXU0hCVG0iEJhvQUipUf+/SsFdA==} engines: {node: '>=16.0.0'} - '@smithy/middleware-serde@4.2.3': - resolution: {integrity: sha512-8g4NuUINpYccxiCXM5s1/V+uLtts8NcX4+sPEbvYQDZk4XoJfDpq5y2FQxfmUL89syoldpzNzA0R9nhzdtdKnQ==} - engines: {node: '>=18.0.0'} - '@smithy/middleware-serde@4.2.5': resolution: {integrity: sha512-La1ldWTJTZ5NqQyPqnCNeH9B+zjFhrNoQIL1jTh4zuqXRlmXhxYHhMtI1/92OlnoAtp6JoN7kzuwhWoXrBwPqg==} engines: {node: '>=18.0.0'} @@ -3138,10 +3500,6 @@ packages: resolution: {integrity: sha512-r4klY9nFudB0r9UdSMaGSyjyQK5adUyPnQN/ZM6M75phTxOdnc/AhpvGD1fQUvgmqjQEBGCwpnPbDm8pH5PapA==} engines: {node: '>=16.0.0'} - '@smithy/middleware-stack@4.2.3': - resolution: {integrity: sha512-iGuOJkH71faPNgOj/gWuEGS6xvQashpLwWB1HjHq1lNNiVfbiJLpZVbhddPuDbx9l4Cgl0vPLq5ltRfSaHfspA==} - engines: {node: '>=18.0.0'} - '@smithy/middleware-stack@4.2.5': resolution: {integrity: sha512-bYrutc+neOyWxtZdbB2USbQttZN0mXaOyYLIsaTbJhFsfpXyGWUxJpEuO1rJ8IIJm2qH4+xJT0mxUSsEDTYwdQ==} engines: {node: '>=18.0.0'} @@ -3150,10 +3508,6 @@ packages: resolution: {integrity: sha512-YvnElQy8HR4vDcAjoy7Xkx9YT8xZP4cBXcbJSgm/kxmiQu08DwUwj8rkGnyoJTpfl/3xYHH+d8zE+eHqoDCSdQ==} engines: {node: '>=16.0.0'} - '@smithy/node-config-provider@4.3.3': - resolution: {integrity: sha512-NzI1eBpBSViOav8NVy1fqOlSfkLgkUjUTlohUSgAEhHaFWA3XJiLditvavIP7OpvTjDp5u2LhtlBhkBlEisMwA==} - engines: {node: '>=18.0.0'} - '@smithy/node-config-provider@4.3.5': resolution: {integrity: sha512-UTurh1C4qkVCtqggI36DGbLB2Kv8UlcFdMXDcWMbqVY2uRg0XmT9Pb4Vj6oSQ34eizO1fvR0RnFV4Axw4IrrAg==} engines: {node: '>=18.0.0'} @@ -3162,10 +3516,6 @@ packages: resolution: {integrity: sha512-+UmxgixgOr/yLsUxcEKGH0fMNVteJFGkmRltYFHnBMlogyFdpzn2CwqWmxOrfJELhV34v0WSlaqG1UtE1uXlJg==} engines: {node: '>=16.0.0'} - '@smithy/node-http-handler@4.4.2': - resolution: {integrity: sha512-MHFvTjts24cjGo1byXqhXrbqm7uznFD/ESFx8npHMWTFQVdBZjrT1hKottmp69LBTRm/JQzP/sn1vPt0/r6AYQ==} - engines: {node: '>=18.0.0'} - '@smithy/node-http-handler@4.4.5': resolution: {integrity: sha512-CMnzM9R2WqlqXQGtIlsHMEZfXKJVTIrqCNoSd/QpAyp+Dw0a1Vps13l6ma1fH8g7zSPNsA59B/kWgeylFuA/lw==} engines: {node: '>=18.0.0'} @@ -3190,10 +3540,6 @@ packages: resolution: {integrity: sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==} engines: {node: '>=16.0.0'} - '@smithy/protocol-http@5.3.3': - resolution: {integrity: sha512-Mn7f/1aN2/jecywDcRDvWWWJF4uwg/A0XjFMJtj72DsgHTByfjRltSqcT9NyE9RTdBSN6X1RSXrhn/YWQl8xlw==} - engines: {node: '>=18.0.0'} - '@smithy/protocol-http@5.3.5': resolution: {integrity: sha512-RlaL+sA0LNMp03bf7XPbFmT5gN+w3besXSWMkA8rcmxLSVfiEXElQi4O2IWwPfxzcHkxqrwBFMbngB8yx/RvaQ==} engines: {node: '>=18.0.0'} @@ -3202,10 +3548,6 @@ packages: resolution: {integrity: sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==} engines: {node: '>=16.0.0'} - '@smithy/querystring-builder@4.2.3': - resolution: {integrity: sha512-LOVCGCmwMahYUM/P0YnU/AlDQFjcu+gWbFJooC417QRB/lDJlWSn8qmPSDp+s4YVAHOgtgbNG4sR+SxF/VOcJQ==} - engines: {node: '>=18.0.0'} - '@smithy/querystring-builder@4.2.5': resolution: {integrity: sha512-y98otMI1saoajeik2kLfGyRp11e5U/iJYH/wLCh3aTV/XutbGT9nziKGkgCaMD1ghK7p6htHMm6b6scl9JRUWg==} engines: {node: '>=18.0.0'} @@ -3214,10 +3556,6 @@ packages: resolution: {integrity: sha512-zahM1lQv2YjmznnfQsWbYojFe55l0SLG/988brlLv1i8z3dubloLF+75ATRsqPBboUXsW6I9CPGE5rQgLfY0vQ==} engines: {node: '>=16.0.0'} - '@smithy/querystring-parser@4.2.3': - resolution: {integrity: sha512-cYlSNHcTAX/wc1rpblli3aUlLMGgKZ/Oqn8hhjFASXMCXjIqeuQBei0cnq2JR8t4RtU9FpG6uyl6PxyArTiwKA==} - engines: {node: '>=18.0.0'} - '@smithy/querystring-parser@4.2.5': resolution: {integrity: sha512-031WCTdPYgiQRYNPXznHXof2YM0GwL6SeaSyTH/P72M1Vz73TvCNH2Nq8Iu2IEPq9QP2yx0/nrw5YmSeAi/AjQ==} engines: {node: '>=18.0.0'} @@ -3226,10 +3564,6 @@ packages: resolution: {integrity: sha512-Jn39sSl8cim/VlkLsUhRFq/dKDnRUFlfRkvhOJaUbLBXUsLRLNf9WaxDv/z9BjuQ3A6k/qE8af1lsqcwm7+DaQ==} engines: {node: '>=16.0.0'} - '@smithy/service-error-classification@4.2.3': - resolution: {integrity: sha512-NkxsAxFWwsPsQiwFG2MzJ/T7uIR6AQNh1SzcxSUnmmIqIQMlLRQDKhc17M7IYjiuBXhrQRjQTo3CxX+DobS93g==} - engines: {node: '>=18.0.0'} - '@smithy/service-error-classification@4.2.5': resolution: {integrity: sha512-8fEvK+WPE3wUAcDvqDQG1Vk3ANLR8Px979te96m84CbKAjBVf25rPYSzb4xU4hlTyho7VhOGnh5i62D/JVF0JQ==} engines: {node: '>=18.0.0'} @@ -3238,10 +3572,6 @@ packages: resolution: {integrity: sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ==} engines: {node: '>=16.0.0'} - '@smithy/shared-ini-file-loader@4.3.3': - resolution: {integrity: sha512-9f9Ixej0hFhroOK2TxZfUUDR13WVa8tQzhSzPDgXe5jGL3KmaM9s8XN7RQwqtEypI82q9KHnKS71CJ+q/1xLtQ==} - engines: {node: '>=18.0.0'} - '@smithy/shared-ini-file-loader@4.4.0': resolution: {integrity: sha512-5WmZ5+kJgJDjwXXIzr1vDTG+RhF9wzSODQBfkrQ2VVkYALKGvZX1lgVSxEkgicSAFnFhPj5rudJV0zoinqS0bA==} engines: {node: '>=18.0.0'} @@ -3250,10 +3580,6 @@ packages: resolution: {integrity: sha512-aRryp2XNZeRcOtuJoxjydO6QTaVhxx/vjaR+gx7ZjaFgrgPRyZ3HCTbfwqYj6ZWEBHkCSUfcaymKPURaByukag==} engines: {node: '>=16.0.0'} - '@smithy/signature-v4@5.3.3': - resolution: {integrity: sha512-CmSlUy+eEYbIEYN5N3vvQTRfqt0lJlQkaQUIf+oizu7BbDut0pozfDjBGecfcfWf7c62Yis4JIEgqQ/TCfodaA==} - engines: {node: '>=18.0.0'} - '@smithy/signature-v4@5.3.5': resolution: {integrity: sha512-xSUfMu1FT7ccfSXkoLl/QRQBi2rOvi3tiBZU2Tdy3I6cgvZ6SEi9QNey+lqps/sJRnogIS+lq+B1gxxbra2a/w==} engines: {node: '>=18.0.0'} @@ -3262,12 +3588,8 @@ packages: resolution: {integrity: sha512-l0BpyYkciNyMaS+PnFFz4aO5sBcXvGLoJd7mX9xrMBIm2nIQBVvYgp2ZpPDMzwjKCavsXu06iuCm0F6ZJZc6yQ==} engines: {node: '>=16.0.0'} - '@smithy/smithy-client@4.9.0': - resolution: {integrity: sha512-qz7RTd15GGdwJ3ZCeBKLDQuUQ88m+skh2hJwcpPm1VqLeKzgZvXf6SrNbxvx7uOqvvkjCMXqx3YB5PDJyk00ww==} - engines: {node: '>=18.0.0'} - - '@smithy/smithy-client@4.9.3': - resolution: {integrity: sha512-8tlueuTgV5n7inQCkhyptrB3jo2AO80uGrps/XTYZivv5MFQKKBj3CIWIGMI2fRY5LEduIiazOhAWdFknY1O9w==} + '@smithy/smithy-client@4.9.6': + resolution: {integrity: sha512-hGz42hggqReicRRZUvrKDQiAmoJnx1Q+XfAJnYAGu544gOfxQCAC3hGGD7+Px2gEUUxB/kKtQV7LOtBRNyxteQ==} engines: {node: '>=18.0.0'} '@smithy/types@2.12.0': @@ -3278,10 +3600,6 @@ packages: resolution: {integrity: sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==} engines: {node: '>=16.0.0'} - '@smithy/types@4.8.0': - resolution: {integrity: sha512-QpELEHLO8SsQVtqP+MkEgCYTFW0pleGozfs3cZ183ZBj9z3VC1CX1/wtFMK64p+5bhtZo41SeLK1rBRtd25nHQ==} - engines: {node: '>=18.0.0'} - '@smithy/types@4.9.0': resolution: {integrity: sha512-MvUbdnXDTwykR8cB1WZvNNwqoWVaTRA0RLlLmf/cIFNMM2cKWz01X4Ly6SMC4Kks30r8tT3Cty0jmeWfiuyHTA==} engines: {node: '>=18.0.0'} @@ -3289,10 +3607,6 @@ packages: '@smithy/url-parser@3.0.3': resolution: {integrity: sha512-pw3VtZtX2rg+s6HMs6/+u9+hu6oY6U7IohGhVNnjbgKy86wcIsSZwgHrFR+t67Uyxvp4Xz3p3kGXXIpTNisq8A==} - '@smithy/url-parser@4.2.3': - resolution: {integrity: sha512-I066AigYvY3d9VlU3zG9XzZg1yT10aNqvCaBTw9EPgu5GrsEl1aUkcMvhkIXascYH1A8W0LQo3B1Kr1cJNcQEw==} - engines: {node: '>=18.0.0'} - '@smithy/url-parser@4.2.5': resolution: {integrity: sha512-VaxMGsilqFnK1CeBX+LXnSuaMx4sTL/6znSZh2829txWieazdVxr54HmiyTsIbpOTLcf5nYpq9lpzmwRdxj6rQ==} engines: {node: '>=18.0.0'} @@ -3344,34 +3658,22 @@ packages: resolution: {integrity: sha512-ZIRSUsnnMRStOP6OKtW+gCSiVFkwnfQF2xtf32QKAbHR6ACjhbAybDvry+3L5qQYdh3H6+7yD/AiUE45n8mTTw==} engines: {node: '>= 10.0.0'} - '@smithy/util-defaults-mode-browser@4.3.3': - resolution: {integrity: sha512-vqHoybAuZXbFXZqgzquiUXtdY+UT/aU33sxa4GBPkiYklmR20LlCn+d3Wc3yA5ZM13gQ92SZe/D8xh6hkjx+IQ==} - engines: {node: '>=18.0.0'} - - '@smithy/util-defaults-mode-browser@4.3.6': - resolution: {integrity: sha512-kbpuXbEf2YQ9zEE6eeVnUCQWO0e1BjMnKrXL8rfXgiWA0m8/E0leU4oSNzxP04WfCmW8vjEqaDeXWxwE4tpOjQ==} + '@smithy/util-defaults-mode-browser@4.3.9': + resolution: {integrity: sha512-Bh5bU40BgdkXE2BcaNazhNtEXi1TC0S+1d84vUwv5srWfvbeRNUKFzwKQgC6p6MXPvEgw+9+HdX3pOwT6ut5aw==} engines: {node: '>=18.0.0'} '@smithy/util-defaults-mode-node@3.0.13': resolution: {integrity: sha512-voUa8TFJGfD+U12tlNNLCDlXibt9vRdNzRX45Onk/WxZe7TS+hTOZouEZRa7oARGicdgeXvt1A0W45qLGYdy+g==} engines: {node: '>= 10.0.0'} - '@smithy/util-defaults-mode-node@4.2.4': - resolution: {integrity: sha512-X5/xrPHedifo7hJUUWKlpxVb2oDOiqPUXlvsZv1EZSjILoutLiJyWva3coBpn00e/gPSpH8Rn2eIbgdwHQdW7Q==} - engines: {node: '>=18.0.0'} - - '@smithy/util-defaults-mode-node@4.2.9': - resolution: {integrity: sha512-dgyribrVWN5qE5usYJ0m5M93mVM3L3TyBPZWe1Xl6uZlH2gzfQx3dz+ZCdW93lWqdedJRkOecnvbnoEEXRZ5VQ==} + '@smithy/util-defaults-mode-node@4.2.12': + resolution: {integrity: sha512-EHZwe1E9Q7umImIyCKQg/Cm+S+7rjXxCRvfGmKifqwYvn7M8M4ZcowwUOQzvuuxUUmdzCkqL0Eq0z1m74Pq6pw==} engines: {node: '>=18.0.0'} '@smithy/util-endpoints@2.0.5': resolution: {integrity: sha512-ReQP0BWihIE68OAblC/WQmDD40Gx+QY1Ez8mTdFMXpmjfxSyz2fVQu3A4zXRfQU9sZXtewk3GmhfOHswvX+eNg==} engines: {node: '>=16.0.0'} - '@smithy/util-endpoints@3.2.3': - resolution: {integrity: sha512-aCfxUOVv0CzBIkU10TubdgKSx5uRvzH064kaiPEWfNIvKOtNpu642P4FP1hgOFkjQIkDObrfIDnKMKkeyrejvQ==} - engines: {node: '>=18.0.0'} - '@smithy/util-endpoints@3.2.5': resolution: {integrity: sha512-3O63AAWu2cSNQZp+ayl9I3NapW1p1rR5mlVHcF6hAB1dPZUQFfRPYtplWX/3xrzWthPGj5FqB12taJJCfH6s8A==} engines: {node: '>=18.0.0'} @@ -3388,10 +3690,6 @@ packages: resolution: {integrity: sha512-l+StyYYK/eO3DlVPbU+4Bi06Jjal+PFLSMmlWM1BEwyLxZ3aKkf1ROnoIakfaA7mC6uw3ny7JBkau4Yc+5zfWw==} engines: {node: '>=16.0.0'} - '@smithy/util-middleware@4.2.3': - resolution: {integrity: sha512-v5ObKlSe8PWUHCqEiX2fy1gNv6goiw6E5I/PN2aXg3Fb/hse0xeaAnSpXDiWl7x6LamVKq7senB+m5LOYHUAHw==} - engines: {node: '>=18.0.0'} - '@smithy/util-middleware@4.2.5': resolution: {integrity: sha512-6Y3+rvBF7+PZOc40ybeZMcGln6xJGVeY60E7jy9Mv5iKpMJpHgRE6dKy9ScsVxvfAYuEX4Q9a65DQX90KaQ3bA==} engines: {node: '>=18.0.0'} @@ -3400,10 +3698,6 @@ packages: resolution: {integrity: sha512-AFw+hjpbtVApzpNDhbjNG5NA3kyoMs7vx0gsgmlJF4s+yz1Zlepde7J58zpIRIsdjc+emhpAITxA88qLkPF26w==} engines: {node: '>=16.0.0'} - '@smithy/util-retry@4.2.3': - resolution: {integrity: sha512-lLPWnakjC0q9z+OtiXk+9RPQiYPNAovt2IXD3CP4LkOnd9NpUsxOjMx1SnoUVB7Orb7fZp67cQMtTBKMFDvOGg==} - engines: {node: '>=18.0.0'} - '@smithy/util-retry@4.2.5': resolution: {integrity: sha512-GBj3+EZBbN4NAqJ/7pAhsXdfzdlznOh8PydUijy6FpNIMnHPSMO2/rP4HKu+UFeikJxShERk528oy7GT79YiJg==} engines: {node: '>=18.0.0'} @@ -3412,10 +3706,6 @@ packages: resolution: {integrity: sha512-FIv/bRhIlAxC0U7xM1BCnF2aDRPq0UaelqBHkM2lsCp26mcBbgI0tCVTv+jGdsQLUmAMybua/bjDsSu8RQHbmw==} engines: {node: '>=16.0.0'} - '@smithy/util-stream@4.5.3': - resolution: {integrity: sha512-oZvn8a5bwwQBNYHT2eNo0EU8Kkby3jeIg1P2Lu9EQtqDxki1LIjGRJM6dJ5CZUig8QmLxWxqOKWvg3mVoOBs5A==} - engines: {node: '>=18.0.0'} - '@smithy/util-stream@4.5.6': resolution: {integrity: sha512-qWw/UM59TiaFrPevefOZ8CNBKbYEP6wBAIlLqxn3VAIo9rgnTNc4ASbVrqDmhuwI87usnjhdQrxodzAGFFzbRQ==} engines: {node: '>=18.0.0'} @@ -3444,8 +3734,8 @@ packages: resolution: {integrity: sha512-4pP0EV3iTsexDx+8PPGAKCQpd/6hsQBaQhqWzU4hqKPHN5epPsxKbvUTIiYIHTxaKt6/kEaqPBpu/ufvfbrRzw==} engines: {node: '>=16.0.0'} - '@smithy/util-waiter@4.0.6': - resolution: {integrity: sha512-slcr1wdRbX7NFphXZOxtxRNA7hXAAtJAXJDE/wdoMAos27SIquVCKiSqfB6/28YzQ8FCsB5NKkhdM5gMADbqxg==} + '@smithy/util-waiter@4.2.5': + resolution: {integrity: sha512-Dbun99A3InifQdIrsXZ+QLcC0PGBPAdrl4cj1mTgJvyc9N2zf7QSxg8TBkzsCmGJdE3TLbO9ycwpY0EkWahQ/g==} engines: {node: '>=18.0.0'} '@smithy/uuid@1.1.0': @@ -3955,6 +4245,9 @@ packages: '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + '@types/aws-lambda@8.10.158': + resolution: {integrity: sha512-v/n2WsL1ksRKigfqZ9ff7ANobfT3t/T8kI8UOiur98tREwFulv9lRv+pDrocGPWOe3DpD2Y2GKRO+OiyxwgaCQ==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -4172,6 +4465,9 @@ packages: '@types/relateurl@0.2.33': resolution: {integrity: sha512-bTQCKsVbIdzLqZhLkF5fcJQreE4y1ro4DIyVrlDNSCJRRwHhB8Z+4zXXa8jN6eDvc2HbRsEYgbvrnGvi54EpSw==} + '@types/resolve@1.20.2': + resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + '@types/resolve@1.20.6': resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==} @@ -4849,6 +5145,10 @@ packages: engines: {node: '>= 18.0.0'} hasBin: true + aws-lambda@1.0.7: + resolution: {integrity: sha512-9GNFMRrEMG5y3Jvv+V4azWvc+qNWdWLTjDdhf/zgMlz8haaaLWv0xeAIWxz9PuWUBawsVxy0zZotjCdR3Xq+2w==} + hasBin: true + aws-sdk@2.1692.0: resolution: {integrity: sha512-x511uiJ/57FIsbgUe5csJ13k3uzu25uWQE+XqfBis/sB0SFoiElJWXRkgEAUh0U6n40eT3ay5Ue4oPkRMu1LYw==} engines: {node: '>= 10.0.0'} @@ -4989,9 +5289,6 @@ packages: boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - bowser@2.11.0: - resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} - bowser@2.12.1: resolution: {integrity: sha512-z4rE2Gxh7tvshQ4hluIT7XcFrgLIQaw9X3A+kTTRdovCz5PMukm/0QC/BKSYPj3omF5Qfypn9O/c5kgpmvYUCw==} @@ -5287,6 +5584,9 @@ packages: commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + commander@3.0.2: + resolution: {integrity: sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==} + commander@6.2.1: resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} engines: {node: '>= 6'} @@ -5914,6 +6214,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.27.0: + resolution: {integrity: sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -6195,6 +6500,9 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} @@ -7047,6 +7355,9 @@ packages: is-mobile@3.1.1: resolution: {integrity: sha512-RRoXXR2HNFxNkUnxtaBdGBXtFlUMFa06S0NUKf/LCF+MuGLu13gi9iBCkoEmc6+rpXuwi5Mso5V8Zf7mNynMBQ==} + is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + is-negative-zero@2.0.3: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} @@ -7093,6 +7404,9 @@ packages: is-promise@4.0.0: resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + is-reference@3.0.3: resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} @@ -8177,6 +8491,9 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + pathval@2.0.0: resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} @@ -8656,8 +8973,15 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - rollup@4.52.4: - resolution: {integrity: sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==} + rollup-plugin-esbuild@6.2.1: + resolution: {integrity: sha512-jTNOMGoMRhs0JuueJrJqbW8tOwxumaWYq+V5i+PD+8ecSCVkuX27tGW7BXqDgoULQ55rO7IdNxPcnsWtshz3AA==} + engines: {node: '>=14.18.0'} + peerDependencies: + esbuild: '>=0.18.0' + rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 + + rollup@4.53.2: + resolution: {integrity: sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -9605,6 +9929,10 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + unplugin-utils@0.2.5: + resolution: {integrity: sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg==} + engines: {node: '>=18.12.0'} + unplugin@1.16.1: resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} engines: {node: '>=14.0.0'} @@ -10141,20 +10469,20 @@ snapshots: '@aws-crypto/crc32@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.910.0 + '@aws-sdk/types': 3.930.0 tslib: 2.6.2 '@aws-crypto/crc32c@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.910.0 + '@aws-sdk/types': 3.930.0 tslib: 2.6.2 '@aws-crypto/sha1-browser@5.2.0': dependencies: '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.910.0 + '@aws-sdk/types': 3.930.0 '@aws-sdk/util-locate-window': 3.465.0 '@smithy/util-utf8': 2.3.0 tslib: 2.6.2 @@ -10164,7 +10492,7 @@ snapshots: '@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.609.0 + '@aws-sdk/types': 3.930.0 '@aws-sdk/util-locate-window': 3.465.0 '@smithy/util-utf8': 2.3.0 tslib: 2.6.2 @@ -10172,7 +10500,7 @@ snapshots: '@aws-crypto/sha256-js@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.609.0 + '@aws-sdk/types': 3.930.0 tslib: 2.6.2 '@aws-crypto/supports-web-crypto@5.2.0': @@ -10181,7 +10509,7 @@ snapshots: '@aws-crypto/util@5.2.0': dependencies: - '@aws-sdk/types': 3.609.0 + '@aws-sdk/types': 3.930.0 '@smithy/util-utf8': 2.3.0 tslib: 2.6.2 @@ -10248,33 +10576,33 @@ snapshots: '@aws-sdk/util-endpoints': 3.840.0 '@aws-sdk/util-user-agent-browser': 3.840.0 '@aws-sdk/util-user-agent-node': 3.840.0 - '@smithy/config-resolver': 4.3.3 - '@smithy/core': 3.17.0 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/hash-node': 4.2.3 - '@smithy/invalid-dependency': 4.2.3 + '@smithy/config-resolver': 4.4.3 + '@smithy/core': 3.18.3 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/hash-node': 4.2.5 + '@smithy/invalid-dependency': 4.2.5 '@smithy/middleware-compression': 4.1.12 - '@smithy/middleware-content-length': 4.2.3 - '@smithy/middleware-endpoint': 4.3.4 - '@smithy/middleware-retry': 4.4.4 - '@smithy/middleware-serde': 4.2.3 - '@smithy/middleware-stack': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/node-http-handler': 4.4.2 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@smithy/middleware-content-length': 4.2.5 + '@smithy/middleware-endpoint': 4.3.10 + '@smithy/middleware-retry': 4.4.10 + '@smithy/middleware-serde': 4.2.5 + '@smithy/middleware-stack': 4.2.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/node-http-handler': 4.4.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.6 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.3 - '@smithy/util-defaults-mode-node': 4.2.4 - '@smithy/util-endpoints': 3.2.3 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.9 + '@smithy/util-defaults-mode-node': 4.2.12 + '@smithy/util-endpoints': 3.2.5 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-retry': 4.2.5 '@smithy/util-utf8': 4.2.0 - '@smithy/util-waiter': 4.0.6 + '@smithy/util-waiter': 4.2.5 tslib: 2.6.2 transitivePeerDependencies: - aws-crt @@ -10340,30 +10668,30 @@ snapshots: '@aws-sdk/util-endpoints': 3.840.0 '@aws-sdk/util-user-agent-browser': 3.840.0 '@aws-sdk/util-user-agent-node': 3.840.0 - '@smithy/config-resolver': 4.3.3 - '@smithy/core': 3.17.0 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/hash-node': 4.2.3 - '@smithy/invalid-dependency': 4.2.3 - '@smithy/middleware-content-length': 4.2.3 - '@smithy/middleware-endpoint': 4.3.4 - '@smithy/middleware-retry': 4.4.4 - '@smithy/middleware-serde': 4.2.3 - '@smithy/middleware-stack': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/node-http-handler': 4.4.2 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@smithy/config-resolver': 4.4.3 + '@smithy/core': 3.18.3 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/hash-node': 4.2.5 + '@smithy/invalid-dependency': 4.2.5 + '@smithy/middleware-content-length': 4.2.5 + '@smithy/middleware-endpoint': 4.3.10 + '@smithy/middleware-retry': 4.4.10 + '@smithy/middleware-serde': 4.2.5 + '@smithy/middleware-stack': 4.2.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/node-http-handler': 4.4.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.6 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.3 - '@smithy/util-defaults-mode-node': 4.2.4 - '@smithy/util-endpoints': 3.2.3 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.9 + '@smithy/util-defaults-mode-node': 4.2.12 + '@smithy/util-endpoints': 3.2.5 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-retry': 4.2.5 '@smithy/util-utf8': 4.2.0 tslib: 2.6.2 transitivePeerDependencies: @@ -10385,98 +10713,95 @@ snapshots: '@aws-sdk/util-endpoints': 3.840.0 '@aws-sdk/util-user-agent-browser': 3.840.0 '@aws-sdk/util-user-agent-node': 3.840.0 - '@smithy/config-resolver': 4.3.3 - '@smithy/core': 3.17.0 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/hash-node': 4.2.3 - '@smithy/invalid-dependency': 4.2.3 - '@smithy/middleware-content-length': 4.2.3 - '@smithy/middleware-endpoint': 4.3.4 - '@smithy/middleware-retry': 4.4.4 - '@smithy/middleware-serde': 4.2.3 - '@smithy/middleware-stack': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/node-http-handler': 4.4.2 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@smithy/config-resolver': 4.4.3 + '@smithy/core': 3.18.3 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/hash-node': 4.2.5 + '@smithy/invalid-dependency': 4.2.5 + '@smithy/middleware-content-length': 4.2.5 + '@smithy/middleware-endpoint': 4.3.10 + '@smithy/middleware-retry': 4.4.10 + '@smithy/middleware-serde': 4.2.5 + '@smithy/middleware-stack': 4.2.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/node-http-handler': 4.4.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.6 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.3 - '@smithy/util-defaults-mode-node': 4.2.4 - '@smithy/util-endpoints': 3.2.3 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.9 + '@smithy/util-defaults-mode-node': 4.2.12 + '@smithy/util-endpoints': 3.2.5 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-retry': 4.2.5 '@smithy/util-utf8': 4.2.0 - '@smithy/util-waiter': 4.0.6 + '@smithy/util-waiter': 4.2.5 '@types/uuid': 9.0.8 tslib: 2.6.2 uuid: 9.0.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-s3@3.842.0': + '@aws-sdk/client-s3@3.931.0': dependencies: '@aws-crypto/sha1-browser': 5.2.0 '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.840.0 - '@aws-sdk/credential-provider-node': 3.840.0 - '@aws-sdk/middleware-bucket-endpoint': 3.840.0 - '@aws-sdk/middleware-expect-continue': 3.840.0 - '@aws-sdk/middleware-flexible-checksums': 3.840.0 - '@aws-sdk/middleware-host-header': 3.840.0 - '@aws-sdk/middleware-location-constraint': 3.840.0 - '@aws-sdk/middleware-logger': 3.840.0 - '@aws-sdk/middleware-recursion-detection': 3.840.0 - '@aws-sdk/middleware-sdk-s3': 3.840.0 - '@aws-sdk/middleware-ssec': 3.840.0 - '@aws-sdk/middleware-user-agent': 3.840.0 - '@aws-sdk/region-config-resolver': 3.840.0 - '@aws-sdk/signature-v4-multi-region': 3.840.0 - '@aws-sdk/types': 3.840.0 - '@aws-sdk/util-endpoints': 3.840.0 - '@aws-sdk/util-user-agent-browser': 3.840.0 - '@aws-sdk/util-user-agent-node': 3.840.0 - '@aws-sdk/xml-builder': 3.821.0 - '@smithy/config-resolver': 4.3.3 - '@smithy/core': 3.17.0 - '@smithy/eventstream-serde-browser': 4.0.4 - '@smithy/eventstream-serde-config-resolver': 4.1.2 - '@smithy/eventstream-serde-node': 4.0.4 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/hash-blob-browser': 4.0.4 - '@smithy/hash-node': 4.2.3 - '@smithy/hash-stream-node': 4.0.4 - '@smithy/invalid-dependency': 4.2.3 - '@smithy/md5-js': 4.0.4 - '@smithy/middleware-content-length': 4.2.3 - '@smithy/middleware-endpoint': 4.3.4 - '@smithy/middleware-retry': 4.4.4 - '@smithy/middleware-serde': 4.2.3 - '@smithy/middleware-stack': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/node-http-handler': 4.4.2 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@aws-sdk/core': 3.931.0 + '@aws-sdk/credential-provider-node': 3.931.0 + '@aws-sdk/middleware-bucket-endpoint': 3.930.0 + '@aws-sdk/middleware-expect-continue': 3.930.0 + '@aws-sdk/middleware-flexible-checksums': 3.931.0 + '@aws-sdk/middleware-host-header': 3.930.0 + '@aws-sdk/middleware-location-constraint': 3.930.0 + '@aws-sdk/middleware-logger': 3.930.0 + '@aws-sdk/middleware-recursion-detection': 3.930.0 + '@aws-sdk/middleware-sdk-s3': 3.931.0 + '@aws-sdk/middleware-ssec': 3.930.0 + '@aws-sdk/middleware-user-agent': 3.931.0 + '@aws-sdk/region-config-resolver': 3.930.0 + '@aws-sdk/signature-v4-multi-region': 3.931.0 + '@aws-sdk/types': 3.930.0 + '@aws-sdk/util-endpoints': 3.930.0 + '@aws-sdk/util-user-agent-browser': 3.930.0 + '@aws-sdk/util-user-agent-node': 3.931.0 + '@smithy/config-resolver': 4.4.3 + '@smithy/core': 3.18.3 + '@smithy/eventstream-serde-browser': 4.2.5 + '@smithy/eventstream-serde-config-resolver': 4.3.5 + '@smithy/eventstream-serde-node': 4.2.5 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/hash-blob-browser': 4.2.6 + '@smithy/hash-node': 4.2.5 + '@smithy/hash-stream-node': 4.2.5 + '@smithy/invalid-dependency': 4.2.5 + '@smithy/md5-js': 4.2.5 + '@smithy/middleware-content-length': 4.2.5 + '@smithy/middleware-endpoint': 4.3.10 + '@smithy/middleware-retry': 4.4.10 + '@smithy/middleware-serde': 4.2.5 + '@smithy/middleware-stack': 4.2.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/node-http-handler': 4.4.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.6 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.3 - '@smithy/util-defaults-mode-node': 4.2.4 - '@smithy/util-endpoints': 3.2.3 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 - '@smithy/util-stream': 4.5.3 + '@smithy/util-defaults-mode-browser': 4.3.9 + '@smithy/util-defaults-mode-node': 4.2.12 + '@smithy/util-endpoints': 3.2.5 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-retry': 4.2.5 + '@smithy/util-stream': 4.5.6 '@smithy/util-utf8': 4.2.0 - '@smithy/util-waiter': 4.0.6 - '@types/uuid': 9.0.8 + '@smithy/util-waiter': 4.2.5 tslib: 2.6.2 - uuid: 9.0.1 transitivePeerDependencies: - aws-crt @@ -10543,32 +10868,32 @@ snapshots: '@aws-sdk/util-endpoints': 3.840.0 '@aws-sdk/util-user-agent-browser': 3.840.0 '@aws-sdk/util-user-agent-node': 3.840.0 - '@smithy/config-resolver': 4.3.3 - '@smithy/core': 3.17.0 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/hash-node': 4.2.3 - '@smithy/invalid-dependency': 4.2.3 - '@smithy/middleware-content-length': 4.2.3 - '@smithy/middleware-endpoint': 4.3.4 - '@smithy/middleware-retry': 4.4.4 - '@smithy/middleware-serde': 4.2.3 - '@smithy/middleware-stack': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/node-http-handler': 4.4.2 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@smithy/config-resolver': 4.4.3 + '@smithy/core': 3.18.3 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/hash-node': 4.2.5 + '@smithy/invalid-dependency': 4.2.5 + '@smithy/middleware-content-length': 4.2.5 + '@smithy/middleware-endpoint': 4.3.10 + '@smithy/middleware-retry': 4.4.10 + '@smithy/middleware-serde': 4.2.5 + '@smithy/middleware-stack': 4.2.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/node-http-handler': 4.4.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.6 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.3 - '@smithy/util-defaults-mode-node': 4.2.4 - '@smithy/util-endpoints': 3.2.3 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.9 + '@smithy/util-defaults-mode-node': 4.2.12 + '@smithy/util-endpoints': 3.2.5 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-retry': 4.2.5 '@smithy/util-utf8': 4.2.0 - '@smithy/util-waiter': 4.0.6 + '@smithy/util-waiter': 4.2.5 '@types/uuid': 9.0.8 tslib: 2.6.2 uuid: 9.0.1 @@ -10636,26 +10961,26 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.910.0 '@aws-sdk/util-user-agent-node': 3.910.0 '@smithy/config-resolver': 4.4.3 - '@smithy/core': 3.18.0 + '@smithy/core': 3.18.3 '@smithy/fetch-http-handler': 5.3.6 '@smithy/hash-node': 4.2.5 '@smithy/invalid-dependency': 4.2.5 '@smithy/middleware-content-length': 4.2.5 - '@smithy/middleware-endpoint': 4.3.7 - '@smithy/middleware-retry': 4.4.7 + '@smithy/middleware-endpoint': 4.3.10 + '@smithy/middleware-retry': 4.4.10 '@smithy/middleware-serde': 4.2.5 '@smithy/middleware-stack': 4.2.5 '@smithy/node-config-provider': 4.3.5 '@smithy/node-http-handler': 4.4.5 '@smithy/protocol-http': 5.3.5 - '@smithy/smithy-client': 4.9.3 + '@smithy/smithy-client': 4.9.6 '@smithy/types': 4.9.0 '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.6 - '@smithy/util-defaults-mode-node': 4.2.9 + '@smithy/util-defaults-mode-browser': 4.3.9 + '@smithy/util-defaults-mode-node': 4.2.12 '@smithy/util-endpoints': 3.2.5 '@smithy/util-middleware': 4.2.5 '@smithy/util-retry': 4.2.5 @@ -10721,30 +11046,30 @@ snapshots: '@aws-sdk/util-endpoints': 3.840.0 '@aws-sdk/util-user-agent-browser': 3.840.0 '@aws-sdk/util-user-agent-node': 3.840.0 - '@smithy/config-resolver': 4.3.3 - '@smithy/core': 3.17.0 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/hash-node': 4.2.3 - '@smithy/invalid-dependency': 4.2.3 - '@smithy/middleware-content-length': 4.2.3 - '@smithy/middleware-endpoint': 4.3.4 - '@smithy/middleware-retry': 4.4.4 - '@smithy/middleware-serde': 4.2.3 - '@smithy/middleware-stack': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/node-http-handler': 4.4.2 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@smithy/config-resolver': 4.4.3 + '@smithy/core': 3.18.3 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/hash-node': 4.2.5 + '@smithy/invalid-dependency': 4.2.5 + '@smithy/middleware-content-length': 4.2.5 + '@smithy/middleware-endpoint': 4.3.10 + '@smithy/middleware-retry': 4.4.10 + '@smithy/middleware-serde': 4.2.5 + '@smithy/middleware-stack': 4.2.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/node-http-handler': 4.4.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.6 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.3 - '@smithy/util-defaults-mode-node': 4.2.4 - '@smithy/util-endpoints': 3.2.3 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.9 + '@smithy/util-defaults-mode-node': 4.2.12 + '@smithy/util-endpoints': 3.2.5 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-retry': 4.2.5 '@smithy/util-utf8': 4.2.0 tslib: 2.6.2 transitivePeerDependencies: @@ -10765,26 +11090,69 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.910.0 '@aws-sdk/util-user-agent-node': 3.910.0 '@smithy/config-resolver': 4.4.3 - '@smithy/core': 3.18.0 + '@smithy/core': 3.18.3 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/hash-node': 4.2.5 + '@smithy/invalid-dependency': 4.2.5 + '@smithy/middleware-content-length': 4.2.5 + '@smithy/middleware-endpoint': 4.3.10 + '@smithy/middleware-retry': 4.4.10 + '@smithy/middleware-serde': 4.2.5 + '@smithy/middleware-stack': 4.2.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/node-http-handler': 4.4.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.6 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-body-length-node': 4.2.1 + '@smithy/util-defaults-mode-browser': 4.3.9 + '@smithy/util-defaults-mode-node': 4.2.12 + '@smithy/util-endpoints': 3.2.5 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-retry': 4.2.5 + '@smithy/util-utf8': 4.2.0 + tslib: 2.6.2 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/client-sso@3.931.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.931.0 + '@aws-sdk/middleware-host-header': 3.930.0 + '@aws-sdk/middleware-logger': 3.930.0 + '@aws-sdk/middleware-recursion-detection': 3.930.0 + '@aws-sdk/middleware-user-agent': 3.931.0 + '@aws-sdk/region-config-resolver': 3.930.0 + '@aws-sdk/types': 3.930.0 + '@aws-sdk/util-endpoints': 3.930.0 + '@aws-sdk/util-user-agent-browser': 3.930.0 + '@aws-sdk/util-user-agent-node': 3.931.0 + '@smithy/config-resolver': 4.4.3 + '@smithy/core': 3.18.3 '@smithy/fetch-http-handler': 5.3.6 '@smithy/hash-node': 4.2.5 '@smithy/invalid-dependency': 4.2.5 '@smithy/middleware-content-length': 4.2.5 - '@smithy/middleware-endpoint': 4.3.7 - '@smithy/middleware-retry': 4.4.7 + '@smithy/middleware-endpoint': 4.3.10 + '@smithy/middleware-retry': 4.4.10 '@smithy/middleware-serde': 4.2.5 '@smithy/middleware-stack': 4.2.5 '@smithy/node-config-provider': 4.3.5 '@smithy/node-http-handler': 4.4.5 '@smithy/protocol-http': 5.3.5 - '@smithy/smithy-client': 4.9.3 + '@smithy/smithy-client': 4.9.6 '@smithy/types': 4.9.0 '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.6 - '@smithy/util-defaults-mode-node': 4.2.9 + '@smithy/util-defaults-mode-browser': 4.3.9 + '@smithy/util-defaults-mode-node': 4.2.12 '@smithy/util-endpoints': 3.2.5 '@smithy/util-middleware': 4.2.5 '@smithy/util-retry': 4.2.5 @@ -10854,16 +11222,16 @@ snapshots: dependencies: '@aws-sdk/types': 3.840.0 '@aws-sdk/xml-builder': 3.821.0 - '@smithy/core': 3.17.0 - '@smithy/node-config-provider': 4.3.3 - '@smithy/property-provider': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/signature-v4': 5.3.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 + '@smithy/core': 3.18.3 + '@smithy/node-config-provider': 4.3.5 + '@smithy/property-provider': 4.2.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/signature-v4': 5.3.5 + '@smithy/smithy-client': 4.9.6 + '@smithy/types': 4.9.0 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 - '@smithy/util-middleware': 4.2.3 + '@smithy/util-middleware': 4.2.5 '@smithy/util-utf8': 4.2.0 fast-xml-parser: 4.4.1 tslib: 2.6.2 @@ -10872,12 +11240,28 @@ snapshots: dependencies: '@aws-sdk/types': 3.910.0 '@aws-sdk/xml-builder': 3.910.0 - '@smithy/core': 3.18.0 + '@smithy/core': 3.18.3 + '@smithy/node-config-provider': 4.3.5 + '@smithy/property-provider': 4.2.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/signature-v4': 5.3.5 + '@smithy/smithy-client': 4.9.6 + '@smithy/types': 4.9.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-utf8': 4.2.0 + tslib: 2.6.2 + + '@aws-sdk/core@3.931.0': + dependencies: + '@aws-sdk/types': 3.930.0 + '@aws-sdk/xml-builder': 3.930.0 + '@smithy/core': 3.18.3 '@smithy/node-config-provider': 4.3.5 '@smithy/property-provider': 4.2.5 '@smithy/protocol-http': 5.3.5 '@smithy/signature-v4': 5.3.5 - '@smithy/smithy-client': 4.9.3 + '@smithy/smithy-client': 4.9.6 '@smithy/types': 4.9.0 '@smithy/util-base64': 4.3.0 '@smithy/util-middleware': 4.2.5 @@ -10898,8 +11282,8 @@ snapshots: dependencies: '@aws-sdk/client-cognito-identity': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/property-provider': 4.2.5 + '@smithy/types': 4.9.0 tslib: 2.6.2 transitivePeerDependencies: - aws-crt @@ -10915,8 +11299,8 @@ snapshots: dependencies: '@aws-sdk/core': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/property-provider': 4.2.5 + '@smithy/types': 4.9.0 tslib: 2.6.2 '@aws-sdk/credential-provider-env@3.910.0': @@ -10927,6 +11311,14 @@ snapshots: '@smithy/types': 4.9.0 tslib: 2.6.2 + '@aws-sdk/credential-provider-env@3.931.0': + dependencies: + '@aws-sdk/core': 3.931.0 + '@aws-sdk/types': 3.930.0 + '@smithy/property-provider': 4.2.5 + '@smithy/types': 4.9.0 + tslib: 2.6.2 + '@aws-sdk/credential-provider-http@3.621.0': dependencies: '@aws-sdk/types': 3.609.0 @@ -10943,13 +11335,13 @@ snapshots: dependencies: '@aws-sdk/core': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/node-http-handler': 4.4.2 - '@smithy/property-provider': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 - '@smithy/util-stream': 4.5.3 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/node-http-handler': 4.4.5 + '@smithy/property-provider': 4.2.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.6 + '@smithy/types': 4.9.0 + '@smithy/util-stream': 4.5.6 tslib: 2.6.2 '@aws-sdk/credential-provider-http@3.910.0': @@ -10960,7 +11352,20 @@ snapshots: '@smithy/node-http-handler': 4.4.5 '@smithy/property-provider': 4.2.5 '@smithy/protocol-http': 5.3.5 - '@smithy/smithy-client': 4.9.3 + '@smithy/smithy-client': 4.9.6 + '@smithy/types': 4.9.0 + '@smithy/util-stream': 4.5.6 + tslib: 2.6.2 + + '@aws-sdk/credential-provider-http@3.931.0': + dependencies: + '@aws-sdk/core': 3.931.0 + '@aws-sdk/types': 3.930.0 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/node-http-handler': 4.4.5 + '@smithy/property-provider': 4.2.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.6 '@smithy/types': 4.9.0 '@smithy/util-stream': 4.5.6 tslib: 2.6.2 @@ -11011,10 +11416,10 @@ snapshots: '@aws-sdk/credential-provider-web-identity': 3.840.0 '@aws-sdk/nested-clients': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/credential-provider-imds': 4.2.3 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/credential-provider-imds': 4.2.5 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 tslib: 2.6.2 transitivePeerDependencies: - aws-crt @@ -11037,6 +11442,24 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/credential-provider-ini@3.931.0': + dependencies: + '@aws-sdk/core': 3.931.0 + '@aws-sdk/credential-provider-env': 3.931.0 + '@aws-sdk/credential-provider-http': 3.931.0 + '@aws-sdk/credential-provider-process': 3.931.0 + '@aws-sdk/credential-provider-sso': 3.931.0 + '@aws-sdk/credential-provider-web-identity': 3.931.0 + '@aws-sdk/nested-clients': 3.931.0 + '@aws-sdk/types': 3.930.0 + '@smithy/credential-provider-imds': 4.2.5 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 + tslib: 2.6.2 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/credential-provider-node@3.621.0(@aws-sdk/client-sso-oidc@3.621.0(@aws-sdk/client-sts@3.621.0))(@aws-sdk/client-sts@3.621.0)': dependencies: '@aws-sdk/credential-provider-env': 3.620.1 @@ -11084,10 +11507,10 @@ snapshots: '@aws-sdk/credential-provider-sso': 3.840.0 '@aws-sdk/credential-provider-web-identity': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/credential-provider-imds': 4.2.3 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/credential-provider-imds': 4.2.5 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 tslib: 2.6.2 transitivePeerDependencies: - aws-crt @@ -11109,6 +11532,23 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/credential-provider-node@3.931.0': + dependencies: + '@aws-sdk/credential-provider-env': 3.931.0 + '@aws-sdk/credential-provider-http': 3.931.0 + '@aws-sdk/credential-provider-ini': 3.931.0 + '@aws-sdk/credential-provider-process': 3.931.0 + '@aws-sdk/credential-provider-sso': 3.931.0 + '@aws-sdk/credential-provider-web-identity': 3.931.0 + '@aws-sdk/types': 3.930.0 + '@smithy/credential-provider-imds': 4.2.5 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 + tslib: 2.6.2 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/credential-provider-process@3.620.1': dependencies: '@aws-sdk/types': 3.609.0 @@ -11121,9 +11561,9 @@ snapshots: dependencies: '@aws-sdk/core': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 tslib: 2.6.2 '@aws-sdk/credential-provider-process@3.910.0': @@ -11135,6 +11575,15 @@ snapshots: '@smithy/types': 4.9.0 tslib: 2.6.2 + '@aws-sdk/credential-provider-process@3.931.0': + dependencies: + '@aws-sdk/core': 3.931.0 + '@aws-sdk/types': 3.930.0 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 + tslib: 2.6.2 + '@aws-sdk/credential-provider-sso@3.621.0(@aws-sdk/client-sso-oidc@3.621.0(@aws-sdk/client-sts@3.621.0))': dependencies: '@aws-sdk/client-sso': 3.621.0 @@ -11167,9 +11616,9 @@ snapshots: '@aws-sdk/core': 3.840.0 '@aws-sdk/token-providers': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 tslib: 2.6.2 transitivePeerDependencies: - aws-crt @@ -11187,6 +11636,19 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/credential-provider-sso@3.931.0': + dependencies: + '@aws-sdk/client-sso': 3.931.0 + '@aws-sdk/core': 3.931.0 + '@aws-sdk/token-providers': 3.931.0 + '@aws-sdk/types': 3.930.0 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 + tslib: 2.6.2 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/credential-provider-web-identity@3.621.0(@aws-sdk/client-sts@3.621.0)': dependencies: '@aws-sdk/client-sts': 3.621.0 @@ -11200,8 +11662,8 @@ snapshots: '@aws-sdk/core': 3.840.0 '@aws-sdk/nested-clients': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/property-provider': 4.2.5 + '@smithy/types': 4.9.0 tslib: 2.6.2 transitivePeerDependencies: - aws-crt @@ -11218,6 +11680,18 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/credential-provider-web-identity@3.931.0': + dependencies: + '@aws-sdk/core': 3.931.0 + '@aws-sdk/nested-clients': 3.931.0 + '@aws-sdk/types': 3.930.0 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 + tslib: 2.6.2 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/credential-providers@3.621.0(@aws-sdk/client-sso-oidc@3.910.0)': dependencies: '@aws-sdk/client-cognito-identity': 3.621.0 @@ -11254,12 +11728,12 @@ snapshots: '@aws-sdk/credential-provider-web-identity': 3.840.0 '@aws-sdk/nested-clients': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/config-resolver': 4.3.3 - '@smithy/core': 3.17.0 + '@smithy/config-resolver': 4.4.3 + '@smithy/core': 3.18.3 '@smithy/credential-provider-imds': 4.2.3 - '@smithy/node-config-provider': 4.3.3 + '@smithy/node-config-provider': 4.3.5 '@smithy/property-provider': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.6.2 transitivePeerDependencies: - aws-crt @@ -11274,18 +11748,18 @@ snapshots: '@aws-sdk/client-dynamodb': 3.840.0 '@aws-sdk/core': 3.840.0 '@aws-sdk/util-dynamodb': 3.840.0(@aws-sdk/client-dynamodb@3.840.0) - '@smithy/core': 3.17.0 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 + '@smithy/core': 3.18.3 + '@smithy/smithy-client': 4.9.6 + '@smithy/types': 4.9.0 tslib: 2.6.2 - '@aws-sdk/middleware-bucket-endpoint@3.840.0': + '@aws-sdk/middleware-bucket-endpoint@3.930.0': dependencies: - '@aws-sdk/types': 3.840.0 - '@aws-sdk/util-arn-parser': 3.804.0 - '@smithy/node-config-provider': 4.3.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.930.0 + '@aws-sdk/util-arn-parser': 3.893.0 + '@smithy/node-config-provider': 4.3.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 '@smithy/util-config-provider': 4.2.0 tslib: 2.6.2 @@ -11293,31 +11767,31 @@ snapshots: dependencies: '@aws-sdk/endpoint-cache': 3.804.0 '@aws-sdk/types': 3.840.0 - '@smithy/node-config-provider': 4.3.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/node-config-provider': 4.3.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 tslib: 2.6.2 - '@aws-sdk/middleware-expect-continue@3.840.0': + '@aws-sdk/middleware-expect-continue@3.930.0': dependencies: - '@aws-sdk/types': 3.840.0 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.930.0 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 tslib: 2.6.2 - '@aws-sdk/middleware-flexible-checksums@3.840.0': + '@aws-sdk/middleware-flexible-checksums@3.931.0': dependencies: '@aws-crypto/crc32': 5.2.0 '@aws-crypto/crc32c': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/core': 3.840.0 - '@aws-sdk/types': 3.840.0 + '@aws-sdk/core': 3.931.0 + '@aws-sdk/types': 3.930.0 '@smithy/is-array-buffer': 4.2.0 - '@smithy/node-config-provider': 4.3.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-stream': 4.5.3 + '@smithy/node-config-provider': 4.3.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-stream': 4.5.6 '@smithy/util-utf8': 4.2.0 tslib: 2.6.2 @@ -11331,8 +11805,8 @@ snapshots: '@aws-sdk/middleware-host-header@3.840.0': dependencies: '@aws-sdk/types': 3.840.0 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 tslib: 2.6.2 '@aws-sdk/middleware-host-header@3.910.0': @@ -11342,10 +11816,17 @@ snapshots: '@smithy/types': 4.9.0 tslib: 2.6.2 - '@aws-sdk/middleware-location-constraint@3.840.0': + '@aws-sdk/middleware-host-header@3.930.0': dependencies: - '@aws-sdk/types': 3.840.0 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.930.0 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 + tslib: 2.6.2 + + '@aws-sdk/middleware-location-constraint@3.930.0': + dependencies: + '@aws-sdk/types': 3.930.0 + '@smithy/types': 4.9.0 tslib: 2.6.2 '@aws-sdk/middleware-logger@3.609.0': @@ -11357,7 +11838,7 @@ snapshots: '@aws-sdk/middleware-logger@3.840.0': dependencies: '@aws-sdk/types': 3.840.0 - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.6.2 '@aws-sdk/middleware-logger@3.910.0': @@ -11366,6 +11847,12 @@ snapshots: '@smithy/types': 4.9.0 tslib: 2.6.2 + '@aws-sdk/middleware-logger@3.930.0': + dependencies: + '@aws-sdk/types': 3.930.0 + '@smithy/types': 4.9.0 + tslib: 2.6.2 + '@aws-sdk/middleware-recursion-detection@3.620.0': dependencies: '@aws-sdk/types': 3.609.0 @@ -11376,8 +11863,8 @@ snapshots: '@aws-sdk/middleware-recursion-detection@3.840.0': dependencies: '@aws-sdk/types': 3.840.0 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 tslib: 2.6.2 '@aws-sdk/middleware-recursion-detection@3.910.0': @@ -11388,27 +11875,35 @@ snapshots: '@smithy/types': 4.9.0 tslib: 2.6.2 - '@aws-sdk/middleware-sdk-s3@3.840.0': + '@aws-sdk/middleware-recursion-detection@3.930.0': dependencies: - '@aws-sdk/core': 3.840.0 - '@aws-sdk/types': 3.840.0 - '@aws-sdk/util-arn-parser': 3.804.0 - '@smithy/core': 3.17.0 - '@smithy/node-config-provider': 4.3.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/signature-v4': 5.3.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.930.0 + '@aws/lambda-invoke-store': 0.1.1 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 + tslib: 2.6.2 + + '@aws-sdk/middleware-sdk-s3@3.931.0': + dependencies: + '@aws-sdk/core': 3.931.0 + '@aws-sdk/types': 3.930.0 + '@aws-sdk/util-arn-parser': 3.893.0 + '@smithy/core': 3.18.3 + '@smithy/node-config-provider': 4.3.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/signature-v4': 5.3.5 + '@smithy/smithy-client': 4.9.6 + '@smithy/types': 4.9.0 '@smithy/util-config-provider': 4.2.0 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-stream': 4.5.3 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-stream': 4.5.6 '@smithy/util-utf8': 4.2.0 tslib: 2.6.2 - '@aws-sdk/middleware-ssec@3.840.0': + '@aws-sdk/middleware-ssec@3.930.0': dependencies: - '@aws-sdk/types': 3.840.0 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.930.0 + '@smithy/types': 4.9.0 tslib: 2.6.2 '@aws-sdk/middleware-user-agent@3.620.0': @@ -11424,9 +11919,9 @@ snapshots: '@aws-sdk/core': 3.840.0 '@aws-sdk/types': 3.840.0 '@aws-sdk/util-endpoints': 3.840.0 - '@smithy/core': 3.17.0 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/core': 3.18.3 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 tslib: 2.6.2 '@aws-sdk/middleware-user-agent@3.910.0': @@ -11434,7 +11929,17 @@ snapshots: '@aws-sdk/core': 3.910.0 '@aws-sdk/types': 3.910.0 '@aws-sdk/util-endpoints': 3.910.0 - '@smithy/core': 3.18.0 + '@smithy/core': 3.18.3 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 + tslib: 2.6.2 + + '@aws-sdk/middleware-user-agent@3.931.0': + dependencies: + '@aws-sdk/core': 3.931.0 + '@aws-sdk/types': 3.930.0 + '@aws-sdk/util-endpoints': 3.930.0 + '@smithy/core': 3.18.3 '@smithy/protocol-http': 5.3.5 '@smithy/types': 4.9.0 tslib: 2.6.2 @@ -11453,30 +11958,30 @@ snapshots: '@aws-sdk/util-endpoints': 3.840.0 '@aws-sdk/util-user-agent-browser': 3.840.0 '@aws-sdk/util-user-agent-node': 3.840.0 - '@smithy/config-resolver': 4.3.3 - '@smithy/core': 3.17.0 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/hash-node': 4.2.3 - '@smithy/invalid-dependency': 4.2.3 - '@smithy/middleware-content-length': 4.2.3 - '@smithy/middleware-endpoint': 4.3.4 - '@smithy/middleware-retry': 4.4.4 - '@smithy/middleware-serde': 4.2.3 - '@smithy/middleware-stack': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/node-http-handler': 4.4.2 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@smithy/config-resolver': 4.4.3 + '@smithy/core': 3.18.3 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/hash-node': 4.2.5 + '@smithy/invalid-dependency': 4.2.5 + '@smithy/middleware-content-length': 4.2.5 + '@smithy/middleware-endpoint': 4.3.10 + '@smithy/middleware-retry': 4.4.10 + '@smithy/middleware-serde': 4.2.5 + '@smithy/middleware-stack': 4.2.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/node-http-handler': 4.4.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.6 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.3 - '@smithy/util-defaults-mode-node': 4.2.4 - '@smithy/util-endpoints': 3.2.3 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.9 + '@smithy/util-defaults-mode-node': 4.2.12 + '@smithy/util-endpoints': 3.2.5 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-retry': 4.2.5 '@smithy/util-utf8': 4.2.0 tslib: 2.6.2 transitivePeerDependencies: @@ -11497,26 +12002,69 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.910.0 '@aws-sdk/util-user-agent-node': 3.910.0 '@smithy/config-resolver': 4.4.3 - '@smithy/core': 3.18.0 + '@smithy/core': 3.18.3 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/hash-node': 4.2.5 + '@smithy/invalid-dependency': 4.2.5 + '@smithy/middleware-content-length': 4.2.5 + '@smithy/middleware-endpoint': 4.3.10 + '@smithy/middleware-retry': 4.4.10 + '@smithy/middleware-serde': 4.2.5 + '@smithy/middleware-stack': 4.2.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/node-http-handler': 4.4.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.6 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-body-length-node': 4.2.1 + '@smithy/util-defaults-mode-browser': 4.3.9 + '@smithy/util-defaults-mode-node': 4.2.12 + '@smithy/util-endpoints': 3.2.5 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-retry': 4.2.5 + '@smithy/util-utf8': 4.2.0 + tslib: 2.6.2 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/nested-clients@3.931.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.931.0 + '@aws-sdk/middleware-host-header': 3.930.0 + '@aws-sdk/middleware-logger': 3.930.0 + '@aws-sdk/middleware-recursion-detection': 3.930.0 + '@aws-sdk/middleware-user-agent': 3.931.0 + '@aws-sdk/region-config-resolver': 3.930.0 + '@aws-sdk/types': 3.930.0 + '@aws-sdk/util-endpoints': 3.930.0 + '@aws-sdk/util-user-agent-browser': 3.930.0 + '@aws-sdk/util-user-agent-node': 3.931.0 + '@smithy/config-resolver': 4.4.3 + '@smithy/core': 3.18.3 '@smithy/fetch-http-handler': 5.3.6 '@smithy/hash-node': 4.2.5 '@smithy/invalid-dependency': 4.2.5 '@smithy/middleware-content-length': 4.2.5 - '@smithy/middleware-endpoint': 4.3.7 - '@smithy/middleware-retry': 4.4.7 + '@smithy/middleware-endpoint': 4.3.10 + '@smithy/middleware-retry': 4.4.10 '@smithy/middleware-serde': 4.2.5 '@smithy/middleware-stack': 4.2.5 '@smithy/node-config-provider': 4.3.5 '@smithy/node-http-handler': 4.4.5 '@smithy/protocol-http': 5.3.5 - '@smithy/smithy-client': 4.9.3 + '@smithy/smithy-client': 4.9.6 '@smithy/types': 4.9.0 '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.6 - '@smithy/util-defaults-mode-node': 4.2.9 + '@smithy/util-defaults-mode-browser': 4.3.9 + '@smithy/util-defaults-mode-node': 4.2.12 '@smithy/util-endpoints': 3.2.5 '@smithy/util-middleware': 4.2.5 '@smithy/util-retry': 4.2.5 @@ -11537,10 +12085,10 @@ snapshots: '@aws-sdk/region-config-resolver@3.840.0': dependencies: '@aws-sdk/types': 3.840.0 - '@smithy/node-config-provider': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/node-config-provider': 4.3.5 + '@smithy/types': 4.9.0 '@smithy/util-config-provider': 4.2.0 - '@smithy/util-middleware': 4.2.3 + '@smithy/util-middleware': 4.2.5 tslib: 2.6.2 '@aws-sdk/region-config-resolver@3.910.0': @@ -11552,13 +12100,21 @@ snapshots: '@smithy/util-middleware': 4.2.5 tslib: 2.6.2 - '@aws-sdk/signature-v4-multi-region@3.840.0': + '@aws-sdk/region-config-resolver@3.930.0': dependencies: - '@aws-sdk/middleware-sdk-s3': 3.840.0 - '@aws-sdk/types': 3.840.0 - '@smithy/protocol-http': 5.3.3 - '@smithy/signature-v4': 5.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.930.0 + '@smithy/config-resolver': 4.4.3 + '@smithy/node-config-provider': 4.3.5 + '@smithy/types': 4.9.0 + tslib: 2.6.2 + + '@aws-sdk/signature-v4-multi-region@3.931.0': + dependencies: + '@aws-sdk/middleware-sdk-s3': 3.931.0 + '@aws-sdk/types': 3.930.0 + '@smithy/protocol-http': 5.3.5 + '@smithy/signature-v4': 5.3.5 + '@smithy/types': 4.9.0 tslib: 2.6.2 '@aws-sdk/token-providers@3.614.0(@aws-sdk/client-sso-oidc@3.621.0(@aws-sdk/client-sts@3.621.0))': @@ -11584,9 +12140,9 @@ snapshots: '@aws-sdk/core': 3.840.0 '@aws-sdk/nested-clients': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 tslib: 2.6.2 transitivePeerDependencies: - aws-crt @@ -11603,6 +12159,18 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/token-providers@3.931.0': + dependencies: + '@aws-sdk/core': 3.931.0 + '@aws-sdk/nested-clients': 3.931.0 + '@aws-sdk/types': 3.930.0 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 + tslib: 2.6.2 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/types@3.609.0': dependencies: '@smithy/types': 3.3.0 @@ -11610,15 +12178,20 @@ snapshots: '@aws-sdk/types@3.840.0': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.6.2 '@aws-sdk/types@3.910.0': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.6.2 - '@aws-sdk/util-arn-parser@3.804.0': + '@aws-sdk/types@3.930.0': + dependencies: + '@smithy/types': 4.9.0 + tslib: 2.6.2 + + '@aws-sdk/util-arn-parser@3.893.0': dependencies: tslib: 2.6.2 @@ -11637,8 +12210,8 @@ snapshots: '@aws-sdk/util-endpoints@3.840.0': dependencies: '@aws-sdk/types': 3.840.0 - '@smithy/types': 4.8.0 - '@smithy/util-endpoints': 3.2.3 + '@smithy/types': 4.9.0 + '@smithy/util-endpoints': 3.2.5 tslib: 2.6.2 '@aws-sdk/util-endpoints@3.910.0': @@ -11649,6 +12222,14 @@ snapshots: '@smithy/util-endpoints': 3.2.5 tslib: 2.6.2 + '@aws-sdk/util-endpoints@3.930.0': + dependencies: + '@aws-sdk/types': 3.930.0 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 + '@smithy/util-endpoints': 3.2.5 + tslib: 2.6.2 + '@aws-sdk/util-locate-window@3.465.0': dependencies: tslib: 2.6.2 @@ -11657,13 +12238,13 @@ snapshots: dependencies: '@aws-sdk/types': 3.609.0 '@smithy/types': 3.3.0 - bowser: 2.11.0 + bowser: 2.12.1 tslib: 2.6.2 '@aws-sdk/util-user-agent-browser@3.840.0': dependencies: '@aws-sdk/types': 3.840.0 - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 bowser: 2.12.1 tslib: 2.6.2 @@ -11674,6 +12255,13 @@ snapshots: bowser: 2.12.1 tslib: 2.6.2 + '@aws-sdk/util-user-agent-browser@3.930.0': + dependencies: + '@aws-sdk/types': 3.930.0 + '@smithy/types': 4.9.0 + bowser: 2.12.1 + tslib: 2.6.2 + '@aws-sdk/util-user-agent-node@3.614.0': dependencies: '@aws-sdk/types': 3.609.0 @@ -11685,8 +12273,8 @@ snapshots: dependencies: '@aws-sdk/middleware-user-agent': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/node-config-provider': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/node-config-provider': 4.3.5 + '@smithy/types': 4.9.0 tslib: 2.6.2 '@aws-sdk/util-user-agent-node@3.910.0': @@ -11697,9 +12285,17 @@ snapshots: '@smithy/types': 4.9.0 tslib: 2.6.2 + '@aws-sdk/util-user-agent-node@3.931.0': + dependencies: + '@aws-sdk/middleware-user-agent': 3.931.0 + '@aws-sdk/types': 3.930.0 + '@smithy/node-config-provider': 4.3.5 + '@smithy/types': 4.9.0 + tslib: 2.6.2 + '@aws-sdk/xml-builder@3.821.0': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.6.2 '@aws-sdk/xml-builder@3.910.0': @@ -11708,8 +12304,16 @@ snapshots: fast-xml-parser: 5.2.5 tslib: 2.6.2 + '@aws-sdk/xml-builder@3.930.0': + dependencies: + '@smithy/types': 4.9.0 + fast-xml-parser: 5.2.5 + tslib: 2.6.2 + '@aws/lambda-invoke-store@0.0.1': {} + '@aws/lambda-invoke-store@0.1.1': {} + '@babel/code-frame@7.27.1': dependencies: '@babel/helper-validator-identifier': 7.27.1 @@ -12649,144 +13253,222 @@ snapshots: '@esbuild/aix-ppc64@0.25.5': optional: true + '@esbuild/aix-ppc64@0.27.0': + optional: true + '@esbuild/android-arm64@0.18.20': optional: true '@esbuild/android-arm64@0.25.5': optional: true + '@esbuild/android-arm64@0.27.0': + optional: true + '@esbuild/android-arm@0.18.20': optional: true '@esbuild/android-arm@0.25.5': optional: true + '@esbuild/android-arm@0.27.0': + optional: true + '@esbuild/android-x64@0.18.20': optional: true '@esbuild/android-x64@0.25.5': optional: true + '@esbuild/android-x64@0.27.0': + optional: true + '@esbuild/darwin-arm64@0.18.20': optional: true '@esbuild/darwin-arm64@0.25.5': optional: true + '@esbuild/darwin-arm64@0.27.0': + optional: true + '@esbuild/darwin-x64@0.18.20': optional: true '@esbuild/darwin-x64@0.25.5': optional: true + '@esbuild/darwin-x64@0.27.0': + optional: true + '@esbuild/freebsd-arm64@0.18.20': optional: true '@esbuild/freebsd-arm64@0.25.5': optional: true + '@esbuild/freebsd-arm64@0.27.0': + optional: true + '@esbuild/freebsd-x64@0.18.20': optional: true '@esbuild/freebsd-x64@0.25.5': optional: true + '@esbuild/freebsd-x64@0.27.0': + optional: true + '@esbuild/linux-arm64@0.18.20': optional: true '@esbuild/linux-arm64@0.25.5': optional: true + '@esbuild/linux-arm64@0.27.0': + optional: true + '@esbuild/linux-arm@0.18.20': optional: true '@esbuild/linux-arm@0.25.5': optional: true + '@esbuild/linux-arm@0.27.0': + optional: true + '@esbuild/linux-ia32@0.18.20': optional: true '@esbuild/linux-ia32@0.25.5': optional: true + '@esbuild/linux-ia32@0.27.0': + optional: true + '@esbuild/linux-loong64@0.18.20': optional: true '@esbuild/linux-loong64@0.25.5': optional: true + '@esbuild/linux-loong64@0.27.0': + optional: true + '@esbuild/linux-mips64el@0.18.20': optional: true '@esbuild/linux-mips64el@0.25.5': optional: true + '@esbuild/linux-mips64el@0.27.0': + optional: true + '@esbuild/linux-ppc64@0.18.20': optional: true '@esbuild/linux-ppc64@0.25.5': optional: true + '@esbuild/linux-ppc64@0.27.0': + optional: true + '@esbuild/linux-riscv64@0.18.20': optional: true '@esbuild/linux-riscv64@0.25.5': optional: true + '@esbuild/linux-riscv64@0.27.0': + optional: true + '@esbuild/linux-s390x@0.18.20': optional: true '@esbuild/linux-s390x@0.25.5': optional: true + '@esbuild/linux-s390x@0.27.0': + optional: true + '@esbuild/linux-x64@0.18.20': optional: true '@esbuild/linux-x64@0.25.5': optional: true + '@esbuild/linux-x64@0.27.0': + optional: true + '@esbuild/netbsd-arm64@0.25.5': optional: true + '@esbuild/netbsd-arm64@0.27.0': + optional: true + '@esbuild/netbsd-x64@0.18.20': optional: true '@esbuild/netbsd-x64@0.25.5': optional: true + '@esbuild/netbsd-x64@0.27.0': + optional: true + '@esbuild/openbsd-arm64@0.25.5': optional: true + '@esbuild/openbsd-arm64@0.27.0': + optional: true + '@esbuild/openbsd-x64@0.18.20': optional: true '@esbuild/openbsd-x64@0.25.5': optional: true + '@esbuild/openbsd-x64@0.27.0': + optional: true + + '@esbuild/openharmony-arm64@0.27.0': + optional: true + '@esbuild/sunos-x64@0.18.20': optional: true '@esbuild/sunos-x64@0.25.5': optional: true + '@esbuild/sunos-x64@0.27.0': + optional: true + '@esbuild/win32-arm64@0.18.20': optional: true '@esbuild/win32-arm64@0.25.5': optional: true + '@esbuild/win32-arm64@0.27.0': + optional: true + '@esbuild/win32-ia32@0.18.20': optional: true '@esbuild/win32-ia32@0.25.5': optional: true + '@esbuild/win32-ia32@0.27.0': + optional: true + '@esbuild/win32-x64@0.18.20': optional: true '@esbuild/win32-x64@0.25.5': optional: true + '@esbuild/win32-x64@0.27.0': + optional: true + '@eslint-community/eslint-plugin-eslint-comments@4.4.1(eslint@9.39.1)': dependencies: escape-string-regexp: 4.0.0 @@ -13012,6 +13694,27 @@ snapshots: - supports-color - typescript + '@guardian/eslint-config@12.0.1(eslint-plugin-import@2.29.1(eslint@9.39.1))(eslint@9.39.1)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-plugin-eslint-comments': 4.4.1(eslint@9.39.1) + '@eslint/js': 9.19.0 + '@stylistic/eslint-plugin': 2.11.0(eslint@9.39.1)(typescript@5.9.3) + eslint: 9.39.1 + eslint-config-prettier: 9.1.0(eslint@9.39.1) + eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import-x@4.6.1(eslint@9.39.1)(typescript@5.9.3))(eslint-plugin-import@2.29.1(eslint@9.39.1))(eslint@9.39.1) + eslint-plugin-import-x: 4.6.1(eslint@9.39.1)(typescript@5.9.3) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.1) + eslint-plugin-react: 7.37.2(eslint@9.39.1) + eslint-plugin-react-hooks: 5.1.0(eslint@9.39.1) + eslint-plugin-storybook: 0.11.1(eslint@9.39.1)(typescript@5.9.3) + globals: 15.14.0 + read-package-up: 11.0.0 + typescript-eslint: 8.22.0(eslint@9.39.1)(typescript@5.9.3) + transitivePeerDependencies: + - eslint-plugin-import + - supports-color + - typescript + '@guardian/eslint-config@9.0.0(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1)(tslib@2.6.2)': dependencies: eslint: 8.57.1 @@ -13140,7 +13843,7 @@ snapshots: dependencies: '@aws-sdk/client-cloudwatch': 3.841.0 '@aws-sdk/client-dynamodb': 3.840.0 - '@aws-sdk/client-s3': 3.842.0 + '@aws-sdk/client-s3': 3.931.0 '@aws-sdk/client-ssm': 3.840.0 '@aws-sdk/credential-providers': 3.840.0 '@aws-sdk/lib-dynamodb': 3.840.0(@aws-sdk/client-dynamodb@3.840.0) @@ -13521,70 +14224,106 @@ snapshots: '@polka/url@1.0.0-next.24': {} - '@rollup/rollup-android-arm-eabi@4.52.4': + '@rollup/plugin-commonjs@29.0.0(rollup@4.53.2)': + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.53.2) + commondir: 1.0.1 + estree-walker: 2.0.2 + fdir: 6.5.0(picomatch@4.0.3) + is-reference: 1.2.1 + magic-string: 0.30.17 + picomatch: 4.0.3 + optionalDependencies: + rollup: 4.53.2 + + '@rollup/plugin-json@6.1.0(rollup@4.53.2)': + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.53.2) + optionalDependencies: + rollup: 4.53.2 + + '@rollup/plugin-node-resolve@16.0.3(rollup@4.53.2)': + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.53.2) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-module: 1.0.0 + resolve: 1.22.10 + optionalDependencies: + rollup: 4.53.2 + + '@rollup/pluginutils@5.3.0(rollup@4.53.2)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.3 + optionalDependencies: + rollup: 4.53.2 + + '@rollup/rollup-android-arm-eabi@4.53.2': optional: true - '@rollup/rollup-android-arm64@4.52.4': + '@rollup/rollup-android-arm64@4.53.2': optional: true - '@rollup/rollup-darwin-arm64@4.52.4': + '@rollup/rollup-darwin-arm64@4.53.2': optional: true - '@rollup/rollup-darwin-x64@4.52.4': + '@rollup/rollup-darwin-x64@4.53.2': optional: true - '@rollup/rollup-freebsd-arm64@4.52.4': + '@rollup/rollup-freebsd-arm64@4.53.2': optional: true - '@rollup/rollup-freebsd-x64@4.52.4': + '@rollup/rollup-freebsd-x64@4.53.2': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.52.4': + '@rollup/rollup-linux-arm-gnueabihf@4.53.2': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.52.4': + '@rollup/rollup-linux-arm-musleabihf@4.53.2': optional: true - '@rollup/rollup-linux-arm64-gnu@4.52.4': + '@rollup/rollup-linux-arm64-gnu@4.53.2': optional: true - '@rollup/rollup-linux-arm64-musl@4.52.4': + '@rollup/rollup-linux-arm64-musl@4.53.2': optional: true - '@rollup/rollup-linux-loong64-gnu@4.52.4': + '@rollup/rollup-linux-loong64-gnu@4.53.2': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.52.4': + '@rollup/rollup-linux-ppc64-gnu@4.53.2': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.52.4': + '@rollup/rollup-linux-riscv64-gnu@4.53.2': optional: true - '@rollup/rollup-linux-riscv64-musl@4.52.4': + '@rollup/rollup-linux-riscv64-musl@4.53.2': optional: true - '@rollup/rollup-linux-s390x-gnu@4.52.4': + '@rollup/rollup-linux-s390x-gnu@4.53.2': optional: true - '@rollup/rollup-linux-x64-gnu@4.52.4': + '@rollup/rollup-linux-x64-gnu@4.53.2': optional: true - '@rollup/rollup-linux-x64-musl@4.52.4': + '@rollup/rollup-linux-x64-musl@4.53.2': optional: true - '@rollup/rollup-openharmony-arm64@4.52.4': + '@rollup/rollup-openharmony-arm64@4.53.2': optional: true - '@rollup/rollup-win32-arm64-msvc@4.52.4': + '@rollup/rollup-win32-arm64-msvc@4.53.2': optional: true - '@rollup/rollup-win32-ia32-msvc@4.52.4': + '@rollup/rollup-win32-ia32-msvc@4.53.2': optional: true - '@rollup/rollup-win32-x64-gnu@4.52.4': + '@rollup/rollup-win32-x64-gnu@4.53.2': optional: true - '@rollup/rollup-win32-x64-msvc@4.52.4': + '@rollup/rollup-win32-x64-msvc@4.53.2': optional: true '@sec-ant/readable-stream@0.4.1': {} @@ -13636,22 +14375,17 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/abort-controller@4.2.3': - dependencies: - '@smithy/types': 4.8.0 - tslib: 2.6.2 - '@smithy/abort-controller@4.2.5': dependencies: '@smithy/types': 4.9.0 tslib: 2.6.2 - '@smithy/chunked-blob-reader-native@4.0.0': + '@smithy/chunked-blob-reader-native@4.2.1': dependencies: '@smithy/util-base64': 4.3.0 tslib: 2.6.2 - '@smithy/chunked-blob-reader@5.0.0': + '@smithy/chunked-blob-reader@5.2.0': dependencies: tslib: 2.6.2 @@ -13663,14 +14397,6 @@ snapshots: '@smithy/util-middleware': 3.0.3 tslib: 2.6.2 - '@smithy/config-resolver@4.3.3': - dependencies: - '@smithy/node-config-provider': 4.3.3 - '@smithy/types': 4.8.0 - '@smithy/util-config-provider': 4.2.0 - '@smithy/util-middleware': 4.2.3 - tslib: 2.6.2 - '@smithy/config-resolver@4.4.3': dependencies: '@smithy/node-config-provider': 4.3.5 @@ -13691,20 +14417,7 @@ snapshots: '@smithy/util-middleware': 3.0.3 tslib: 2.6.2 - '@smithy/core@3.17.0': - dependencies: - '@smithy/middleware-serde': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 - '@smithy/util-base64': 4.3.0 - '@smithy/util-body-length-browser': 4.2.0 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-stream': 4.5.3 - '@smithy/util-utf8': 4.2.0 - '@smithy/uuid': 1.1.0 - tslib: 2.6.2 - - '@smithy/core@3.18.0': + '@smithy/core@3.18.3': dependencies: '@smithy/middleware-serde': 4.2.5 '@smithy/protocol-http': 5.3.5 @@ -13727,10 +14440,10 @@ snapshots: '@smithy/credential-provider-imds@4.2.3': dependencies: - '@smithy/node-config-provider': 4.3.3 - '@smithy/property-provider': 4.2.3 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@smithy/node-config-provider': 4.3.5 + '@smithy/property-provider': 4.2.5 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 tslib: 2.6.2 '@smithy/credential-provider-imds@4.2.5': @@ -13741,34 +14454,34 @@ snapshots: '@smithy/url-parser': 4.2.5 tslib: 2.6.2 - '@smithy/eventstream-codec@4.0.4': + '@smithy/eventstream-codec@4.2.5': dependencies: '@aws-crypto/crc32': 5.2.0 - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 '@smithy/util-hex-encoding': 4.2.0 tslib: 2.6.2 - '@smithy/eventstream-serde-browser@4.0.4': + '@smithy/eventstream-serde-browser@4.2.5': dependencies: - '@smithy/eventstream-serde-universal': 4.0.4 - '@smithy/types': 4.8.0 + '@smithy/eventstream-serde-universal': 4.2.5 + '@smithy/types': 4.9.0 tslib: 2.6.2 - '@smithy/eventstream-serde-config-resolver@4.1.2': + '@smithy/eventstream-serde-config-resolver@4.3.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.6.2 - '@smithy/eventstream-serde-node@4.0.4': + '@smithy/eventstream-serde-node@4.2.5': dependencies: - '@smithy/eventstream-serde-universal': 4.0.4 - '@smithy/types': 4.8.0 + '@smithy/eventstream-serde-universal': 4.2.5 + '@smithy/types': 4.9.0 tslib: 2.6.2 - '@smithy/eventstream-serde-universal@4.0.4': + '@smithy/eventstream-serde-universal@4.2.5': dependencies: - '@smithy/eventstream-codec': 4.0.4 - '@smithy/types': 4.8.0 + '@smithy/eventstream-codec': 4.2.5 + '@smithy/types': 4.9.0 tslib: 2.6.2 '@smithy/fetch-http-handler@3.2.4': @@ -13779,14 +14492,6 @@ snapshots: '@smithy/util-base64': 3.0.0 tslib: 2.6.2 - '@smithy/fetch-http-handler@5.3.4': - dependencies: - '@smithy/protocol-http': 5.3.3 - '@smithy/querystring-builder': 4.2.3 - '@smithy/types': 4.8.0 - '@smithy/util-base64': 4.3.0 - tslib: 2.6.2 - '@smithy/fetch-http-handler@5.3.6': dependencies: '@smithy/protocol-http': 5.3.5 @@ -13795,11 +14500,11 @@ snapshots: '@smithy/util-base64': 4.3.0 tslib: 2.6.2 - '@smithy/hash-blob-browser@4.0.4': + '@smithy/hash-blob-browser@4.2.6': dependencies: - '@smithy/chunked-blob-reader': 5.0.0 - '@smithy/chunked-blob-reader-native': 4.0.0 - '@smithy/types': 4.8.0 + '@smithy/chunked-blob-reader': 5.2.0 + '@smithy/chunked-blob-reader-native': 4.2.1 + '@smithy/types': 4.9.0 tslib: 2.6.2 '@smithy/hash-node@3.0.3': @@ -13809,13 +14514,6 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.6.2 - '@smithy/hash-node@4.2.3': - dependencies: - '@smithy/types': 4.8.0 - '@smithy/util-buffer-from': 4.2.0 - '@smithy/util-utf8': 4.2.0 - tslib: 2.6.2 - '@smithy/hash-node@4.2.5': dependencies: '@smithy/types': 4.9.0 @@ -13823,9 +14521,9 @@ snapshots: '@smithy/util-utf8': 4.2.0 tslib: 2.6.2 - '@smithy/hash-stream-node@4.0.4': + '@smithy/hash-stream-node@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 '@smithy/util-utf8': 4.2.0 tslib: 2.6.2 @@ -13834,11 +14532,6 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/invalid-dependency@4.2.3': - dependencies: - '@smithy/types': 4.8.0 - tslib: 2.6.2 - '@smithy/invalid-dependency@4.2.5': dependencies: '@smithy/types': 4.9.0 @@ -13856,9 +14549,9 @@ snapshots: dependencies: tslib: 2.6.2 - '@smithy/md5-js@4.0.4': + '@smithy/md5-js@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 '@smithy/util-utf8': 4.2.0 tslib: 2.6.2 @@ -13876,13 +14569,13 @@ snapshots: '@smithy/middleware-compression@4.1.12': dependencies: - '@smithy/core': 3.17.0 + '@smithy/core': 3.18.3 '@smithy/is-array-buffer': 4.2.0 - '@smithy/node-config-provider': 4.3.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/node-config-provider': 4.3.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 '@smithy/util-config-provider': 4.2.0 - '@smithy/util-middleware': 4.2.3 + '@smithy/util-middleware': 4.2.5 '@smithy/util-utf8': 4.2.0 fflate: 0.8.1 tslib: 2.6.2 @@ -13893,12 +14586,6 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/middleware-content-length@4.2.3': - dependencies: - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 - tslib: 2.6.2 - '@smithy/middleware-content-length@4.2.5': dependencies: '@smithy/protocol-http': 5.3.5 @@ -13915,20 +14602,9 @@ snapshots: '@smithy/util-middleware': 3.0.3 tslib: 2.6.2 - '@smithy/middleware-endpoint@4.3.4': + '@smithy/middleware-endpoint@4.3.10': dependencies: - '@smithy/core': 3.17.0 - '@smithy/middleware-serde': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 - '@smithy/util-middleware': 4.2.3 - tslib: 2.6.2 - - '@smithy/middleware-endpoint@4.3.7': - dependencies: - '@smithy/core': 3.18.0 + '@smithy/core': 3.18.3 '@smithy/middleware-serde': 4.2.5 '@smithy/node-config-provider': 4.3.5 '@smithy/shared-ini-file-loader': 4.4.0 @@ -13949,24 +14625,12 @@ snapshots: tslib: 2.6.2 uuid: 9.0.1 - '@smithy/middleware-retry@4.4.4': - dependencies: - '@smithy/node-config-provider': 4.3.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/service-error-classification': 4.2.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 - '@smithy/uuid': 1.1.0 - tslib: 2.6.2 - - '@smithy/middleware-retry@4.4.7': + '@smithy/middleware-retry@4.4.10': dependencies: '@smithy/node-config-provider': 4.3.5 '@smithy/protocol-http': 5.3.5 '@smithy/service-error-classification': 4.2.5 - '@smithy/smithy-client': 4.9.3 + '@smithy/smithy-client': 4.9.6 '@smithy/types': 4.9.0 '@smithy/util-middleware': 4.2.5 '@smithy/util-retry': 4.2.5 @@ -13978,12 +14642,6 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/middleware-serde@4.2.3': - dependencies: - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 - tslib: 2.6.2 - '@smithy/middleware-serde@4.2.5': dependencies: '@smithy/protocol-http': 5.3.5 @@ -13995,11 +14653,6 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/middleware-stack@4.2.3': - dependencies: - '@smithy/types': 4.8.0 - tslib: 2.6.2 - '@smithy/middleware-stack@4.2.5': dependencies: '@smithy/types': 4.9.0 @@ -14012,13 +14665,6 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/node-config-provider@4.3.3': - dependencies: - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 - tslib: 2.6.2 - '@smithy/node-config-provider@4.3.5': dependencies: '@smithy/property-provider': 4.2.5 @@ -14034,14 +14680,6 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/node-http-handler@4.4.2': - dependencies: - '@smithy/abort-controller': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/querystring-builder': 4.2.3 - '@smithy/types': 4.8.0 - tslib: 2.6.2 - '@smithy/node-http-handler@4.4.5': dependencies: '@smithy/abort-controller': 4.2.5 @@ -14062,7 +14700,7 @@ snapshots: '@smithy/property-provider@4.2.3': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.6.2 '@smithy/property-provider@4.2.5': @@ -14075,11 +14713,6 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/protocol-http@5.3.3': - dependencies: - '@smithy/types': 4.8.0 - tslib: 2.6.2 - '@smithy/protocol-http@5.3.5': dependencies: '@smithy/types': 4.9.0 @@ -14091,12 +14724,6 @@ snapshots: '@smithy/util-uri-escape': 3.0.0 tslib: 2.6.2 - '@smithy/querystring-builder@4.2.3': - dependencies: - '@smithy/types': 4.8.0 - '@smithy/util-uri-escape': 4.2.0 - tslib: 2.6.2 - '@smithy/querystring-builder@4.2.5': dependencies: '@smithy/types': 4.9.0 @@ -14108,11 +14735,6 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/querystring-parser@4.2.3': - dependencies: - '@smithy/types': 4.8.0 - tslib: 2.6.2 - '@smithy/querystring-parser@4.2.5': dependencies: '@smithy/types': 4.9.0 @@ -14122,10 +14744,6 @@ snapshots: dependencies: '@smithy/types': 3.3.0 - '@smithy/service-error-classification@4.2.3': - dependencies: - '@smithy/types': 4.8.0 - '@smithy/service-error-classification@4.2.5': dependencies: '@smithy/types': 4.9.0 @@ -14135,11 +14753,6 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/shared-ini-file-loader@4.3.3': - dependencies: - '@smithy/types': 4.8.0 - tslib: 2.6.2 - '@smithy/shared-ini-file-loader@4.4.0': dependencies: '@smithy/types': 4.9.0 @@ -14156,17 +14769,6 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.6.2 - '@smithy/signature-v4@5.3.3': - dependencies: - '@smithy/is-array-buffer': 4.2.0 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 - '@smithy/util-hex-encoding': 4.2.0 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-uri-escape': 4.2.0 - '@smithy/util-utf8': 4.2.0 - tslib: 2.6.2 - '@smithy/signature-v4@5.3.5': dependencies: '@smithy/is-array-buffer': 4.2.0 @@ -14187,20 +14789,10 @@ snapshots: '@smithy/util-stream': 3.1.3 tslib: 2.6.2 - '@smithy/smithy-client@4.9.0': - dependencies: - '@smithy/core': 3.17.0 - '@smithy/middleware-endpoint': 4.3.4 - '@smithy/middleware-stack': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 - '@smithy/util-stream': 4.5.3 - tslib: 2.6.2 - - '@smithy/smithy-client@4.9.3': + '@smithy/smithy-client@4.9.6': dependencies: - '@smithy/core': 3.18.0 - '@smithy/middleware-endpoint': 4.3.7 + '@smithy/core': 3.18.3 + '@smithy/middleware-endpoint': 4.3.10 '@smithy/middleware-stack': 4.2.5 '@smithy/protocol-http': 5.3.5 '@smithy/types': 4.9.0 @@ -14215,10 +14807,6 @@ snapshots: dependencies: tslib: 2.6.2 - '@smithy/types@4.8.0': - dependencies: - tslib: 2.6.2 - '@smithy/types@4.9.0': dependencies: tslib: 2.6.2 @@ -14229,12 +14817,6 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/url-parser@4.2.3': - dependencies: - '@smithy/querystring-parser': 4.2.3 - '@smithy/types': 4.8.0 - tslib: 2.6.2 - '@smithy/url-parser@4.2.5': dependencies: '@smithy/querystring-parser': 4.2.5 @@ -14297,20 +14879,13 @@ snapshots: '@smithy/property-provider': 3.1.3 '@smithy/smithy-client': 3.1.11 '@smithy/types': 3.3.0 - bowser: 2.11.0 - tslib: 2.6.2 - - '@smithy/util-defaults-mode-browser@4.3.3': - dependencies: - '@smithy/property-provider': 4.2.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 + bowser: 2.12.1 tslib: 2.6.2 - '@smithy/util-defaults-mode-browser@4.3.6': + '@smithy/util-defaults-mode-browser@4.3.9': dependencies: '@smithy/property-provider': 4.2.5 - '@smithy/smithy-client': 4.9.3 + '@smithy/smithy-client': 4.9.6 '@smithy/types': 4.9.0 tslib: 2.6.2 @@ -14324,23 +14899,13 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/util-defaults-mode-node@4.2.4': - dependencies: - '@smithy/config-resolver': 4.3.3 - '@smithy/credential-provider-imds': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/property-provider': 4.2.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 - tslib: 2.6.2 - - '@smithy/util-defaults-mode-node@4.2.9': + '@smithy/util-defaults-mode-node@4.2.12': dependencies: '@smithy/config-resolver': 4.4.3 '@smithy/credential-provider-imds': 4.2.5 '@smithy/node-config-provider': 4.3.5 '@smithy/property-provider': 4.2.5 - '@smithy/smithy-client': 4.9.3 + '@smithy/smithy-client': 4.9.6 '@smithy/types': 4.9.0 tslib: 2.6.2 @@ -14350,12 +14915,6 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/util-endpoints@3.2.3': - dependencies: - '@smithy/node-config-provider': 4.3.3 - '@smithy/types': 4.8.0 - tslib: 2.6.2 - '@smithy/util-endpoints@3.2.5': dependencies: '@smithy/node-config-provider': 4.3.5 @@ -14375,11 +14934,6 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/util-middleware@4.2.3': - dependencies: - '@smithy/types': 4.8.0 - tslib: 2.6.2 - '@smithy/util-middleware@4.2.5': dependencies: '@smithy/types': 4.9.0 @@ -14391,12 +14945,6 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/util-retry@4.2.3': - dependencies: - '@smithy/service-error-classification': 4.2.3 - '@smithy/types': 4.8.0 - tslib: 2.6.2 - '@smithy/util-retry@4.2.5': dependencies: '@smithy/service-error-classification': 4.2.5 @@ -14414,17 +14962,6 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.6.2 - '@smithy/util-stream@4.5.3': - dependencies: - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/node-http-handler': 4.4.2 - '@smithy/types': 4.8.0 - '@smithy/util-base64': 4.3.0 - '@smithy/util-buffer-from': 4.2.0 - '@smithy/util-hex-encoding': 4.2.0 - '@smithy/util-utf8': 4.2.0 - tslib: 2.6.2 - '@smithy/util-stream@4.5.6': dependencies: '@smithy/fetch-http-handler': 5.3.6 @@ -14465,10 +15002,10 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/util-waiter@4.0.6': + '@smithy/util-waiter@4.2.5': dependencies: - '@smithy/abort-controller': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/abort-controller': 4.2.5 + '@smithy/types': 4.9.0 tslib: 2.6.2 '@smithy/uuid@1.1.0': @@ -14480,13 +15017,13 @@ snapshots: '@storybook/addon-a11y@10.0.7(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))': dependencies: '@storybook/global': 5.0.0 - axe-core: 4.8.2 + axe-core: 4.11.0 storybook: 10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)) - '@storybook/addon-docs@10.0.7(@types/react@18.3.1)(esbuild@0.25.5)(rollup@4.52.4)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2))(webpack@5.102.1)': + '@storybook/addon-docs@10.0.7(@types/react@18.3.1)(esbuild@0.27.0)(rollup@4.53.2)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2))(webpack@5.102.1)': dependencies: '@mdx-js/react': 3.1.0(@types/react@18.3.1)(react@18.3.1) - '@storybook/csf-plugin': 10.0.7(esbuild@0.25.5)(rollup@4.52.4)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2))(webpack@5.102.1) + '@storybook/csf-plugin': 10.0.7(esbuild@0.27.0)(rollup@4.53.2)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2))(webpack@5.102.1) '@storybook/icons': 1.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@storybook/react-dom-shim': 10.0.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2))) react: 18.3.1 @@ -14530,7 +15067,7 @@ snapshots: - '@swc/helpers' - webpack - '@storybook/builder-webpack5@10.0.7(@swc/core@1.13.5)(esbuild@0.25.5)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(typescript@5.5.3)(webpack-cli@6.0.1)': + '@storybook/builder-webpack5@10.0.7(@swc/core@1.13.5)(esbuild@0.27.0)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(typescript@5.5.3)(webpack-cli@6.0.1)': dependencies: '@storybook/core-webpack': 10.0.7(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2))) case-sensitive-paths-webpack-plugin: 2.4.0 @@ -14542,9 +15079,9 @@ snapshots: magic-string: 0.30.17 storybook: 10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)) style-loader: 4.0.0(webpack@5.102.1) - terser-webpack-plugin: 5.3.14(@swc/core@1.13.5)(esbuild@0.25.5)(webpack@5.102.1) + terser-webpack-plugin: 5.3.14(@swc/core@1.13.5)(esbuild@0.27.0)(webpack@5.102.1) ts-dedent: 2.2.0 - webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) + webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1) webpack-dev-middleware: 6.1.3(webpack@5.102.1) webpack-hot-middleware: 2.26.1 webpack-virtual-modules: 0.6.2 @@ -14594,15 +15131,15 @@ snapshots: storybook: 9.1.13(@testing-library/dom@10.4.1)(prettier@3.0.3)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)) ts-dedent: 2.2.0 - '@storybook/csf-plugin@10.0.7(esbuild@0.25.5)(rollup@4.52.4)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2))(webpack@5.102.1)': + '@storybook/csf-plugin@10.0.7(esbuild@0.27.0)(rollup@4.53.2)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2))(webpack@5.102.1)': dependencies: storybook: 10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)) unplugin: 2.3.10 optionalDependencies: - esbuild: 0.25.5 - rollup: 4.52.4 + esbuild: 0.27.0 + rollup: 4.53.2 vite: 6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2) - webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) + webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1) '@storybook/csf-plugin@9.1.13(storybook@9.1.13(@testing-library/dom@10.4.1)(prettier@3.0.3)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))': dependencies: @@ -14625,7 +15162,7 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@storybook/preset-react-webpack@10.0.7(@swc/core@1.13.5)(esbuild@0.25.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(typescript@5.5.3)(webpack-cli@6.0.1)': + '@storybook/preset-react-webpack@10.0.7(@swc/core@1.13.5)(esbuild@0.27.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(typescript@5.5.3)(webpack-cli@6.0.1)': dependencies: '@storybook/core-webpack': 10.0.7(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2))) '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@5.5.3)(webpack@5.102.1) @@ -14638,7 +15175,7 @@ snapshots: semver: 7.5.4 storybook: 10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)) tsconfig-paths: 4.2.0 - webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) + webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1) optionalDependencies: typescript: 5.5.3 transitivePeerDependencies: @@ -14698,10 +15235,10 @@ snapshots: react-dom: 18.3.1(react@18.3.1) storybook: 9.1.13(@testing-library/dom@10.4.1)(prettier@3.0.3)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)) - '@storybook/react-webpack5@10.0.7(@swc/core@1.13.5)(esbuild@0.25.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(typescript@5.5.3)(webpack-cli@6.0.1)': + '@storybook/react-webpack5@10.0.7(@swc/core@1.13.5)(esbuild@0.27.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(typescript@5.5.3)(webpack-cli@6.0.1)': dependencies: - '@storybook/builder-webpack5': 10.0.7(@swc/core@1.13.5)(esbuild@0.25.5)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(typescript@5.5.3)(webpack-cli@6.0.1) - '@storybook/preset-react-webpack': 10.0.7(@swc/core@1.13.5)(esbuild@0.25.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(typescript@5.5.3)(webpack-cli@6.0.1) + '@storybook/builder-webpack5': 10.0.7(@swc/core@1.13.5)(esbuild@0.27.0)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(typescript@5.5.3)(webpack-cli@6.0.1) + '@storybook/preset-react-webpack': 10.0.7(@swc/core@1.13.5)(esbuild@0.27.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(typescript@5.5.3)(webpack-cli@6.0.1) '@storybook/react': 10.0.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.0.7(@testing-library/dom@10.4.1)(prettier@3.0.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@6.4.0(@types/node@22.17.0)(terser@5.44.0)(tsx@4.6.2)))(typescript@5.5.3) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -15101,6 +15638,8 @@ snapshots: '@types/aria-query@5.0.4': {} + '@types/aws-lambda@8.10.158': {} + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.28.4 @@ -15367,6 +15906,8 @@ snapshots: '@types/relateurl@0.2.33': {} + '@types/resolve@1.20.2': {} + '@types/resolve@1.20.6': {} '@types/response-time@2.3.8': @@ -15448,11 +15989,11 @@ snapshots: '@types/uuid@9.0.8': {} - '@types/webpack-bundle-analyzer@4.7.0(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1)': + '@types/webpack-bundle-analyzer@4.7.0(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1)': dependencies: '@types/node': 22.17.0 tapable: 2.2.1 - webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) + webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1) transitivePeerDependencies: - '@swc/core' - esbuild @@ -15461,10 +16002,10 @@ snapshots: '@types/webpack-env@1.18.8': {} - '@types/webpack-node-externals@3.0.4(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1)': + '@types/webpack-node-externals@3.0.4(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1)': dependencies: '@types/node': 22.17.0 - webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) + webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1) transitivePeerDependencies: - '@swc/core' - esbuild @@ -15520,10 +16061,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.22.0(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1)(typescript@5.5.3)': + '@typescript-eslint/eslint-plugin@8.22.0(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1)(typescript@5.5.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.1.0(eslint@8.57.1)(typescript@5.5.3) + '@typescript-eslint/parser': 8.22.0(eslint@8.57.1)(typescript@5.5.3) '@typescript-eslint/scope-manager': 8.22.0 '@typescript-eslint/type-utils': 8.22.0(eslint@8.57.1)(typescript@5.5.3) '@typescript-eslint/utils': 8.22.0(eslint@8.57.1)(typescript@5.5.3) @@ -15575,6 +16116,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.22.0 + '@typescript-eslint/types': 8.22.0 + '@typescript-eslint/typescript-estree': 8.22.0(typescript@5.5.3) + '@typescript-eslint/visitor-keys': 8.22.0 + debug: 4.4.3(supports-color@8.1.1) + eslint: 8.57.1 + typescript: 5.5.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/parser@8.22.0(eslint@9.39.1)(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 8.22.0 @@ -15967,17 +16520,17 @@ snapshots: '@webpack-cli/configtest@3.0.1(webpack-cli@6.0.1)(webpack@5.102.1)': dependencies: webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.2.2)(webpack@5.102.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.102.1) '@webpack-cli/info@3.0.1(webpack-cli@6.0.1)(webpack@5.102.1)': dependencies: webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.2.2)(webpack@5.102.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.102.1) '@webpack-cli/serve@3.0.1(webpack-cli@6.0.1)(webpack-dev-server@5.2.2)(webpack@5.102.1)': dependencies: webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.2.2)(webpack@5.102.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.102.1) optionalDependencies: webpack-dev-server: 5.2.2(webpack-cli@6.0.1)(webpack@5.102.1) @@ -16310,6 +16863,13 @@ snapshots: optionalDependencies: fsevents: 2.3.2 + aws-lambda@1.0.7: + dependencies: + aws-sdk: 2.1692.0 + commander: 3.0.2 + js-yaml: 3.14.1 + watchpack: 2.4.4 + aws-sdk@2.1692.0: dependencies: buffer: 4.9.2 @@ -16502,8 +17062,6 @@ snapshots: boolbase@1.0.0: {} - bowser@2.11.0: {} - bowser@2.12.1: {} brace-expansion@1.1.12: @@ -16794,6 +17352,8 @@ snapshots: commander@2.20.3: {} + commander@3.0.2: {} + commander@6.2.1: {} commander@7.2.0: {} @@ -16968,7 +17528,7 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.5.4 optionalDependencies: - webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) + webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1) css-select@4.3.0: dependencies: @@ -17495,6 +18055,35 @@ snapshots: '@esbuild/win32-ia32': 0.25.5 '@esbuild/win32-x64': 0.25.5 + esbuild@0.27.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.0 + '@esbuild/android-arm': 0.27.0 + '@esbuild/android-arm64': 0.27.0 + '@esbuild/android-x64': 0.27.0 + '@esbuild/darwin-arm64': 0.27.0 + '@esbuild/darwin-x64': 0.27.0 + '@esbuild/freebsd-arm64': 0.27.0 + '@esbuild/freebsd-x64': 0.27.0 + '@esbuild/linux-arm': 0.27.0 + '@esbuild/linux-arm64': 0.27.0 + '@esbuild/linux-ia32': 0.27.0 + '@esbuild/linux-loong64': 0.27.0 + '@esbuild/linux-mips64el': 0.27.0 + '@esbuild/linux-ppc64': 0.27.0 + '@esbuild/linux-riscv64': 0.27.0 + '@esbuild/linux-s390x': 0.27.0 + '@esbuild/linux-x64': 0.27.0 + '@esbuild/netbsd-arm64': 0.27.0 + '@esbuild/netbsd-x64': 0.27.0 + '@esbuild/openbsd-arm64': 0.27.0 + '@esbuild/openbsd-x64': 0.27.0 + '@esbuild/openharmony-arm64': 0.27.0 + '@esbuild/sunos-x64': 0.27.0 + '@esbuild/win32-arm64': 0.27.0 + '@esbuild/win32-ia32': 0.27.0 + '@esbuild/win32-x64': 0.27.0 + escalade@3.2.0: {} escape-html@1.0.3: {} @@ -17515,22 +18104,22 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1))(eslint@8.57.1): + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1))(eslint@8.57.1): dependencies: confusing-browser-globals: 1.0.11 eslint: 8.57.1 - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1) object.assign: 4.1.7 object.entries: 1.1.7 semver: 6.3.1 - eslint-config-airbnb-typescript@17.0.0(@typescript-eslint/eslint-plugin@8.22.0(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1)(typescript@5.5.3))(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1))(eslint@8.57.1): + eslint-config-airbnb-typescript@17.0.0(@typescript-eslint/eslint-plugin@8.22.0(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1)(typescript@5.5.3))(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1))(eslint@8.57.1): dependencies: - '@typescript-eslint/eslint-plugin': 8.22.0(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1)(typescript@5.5.3) - '@typescript-eslint/parser': 8.1.0(eslint@8.57.1)(typescript@5.5.3) + '@typescript-eslint/eslint-plugin': 8.22.0(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1)(typescript@5.5.3) + '@typescript-eslint/parser': 8.22.0(eslint@8.57.1)(typescript@5.5.3) eslint: 8.57.1 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1) eslint-config-prettier@9.1.0(eslint@8.57.1): dependencies: @@ -17556,7 +18145,7 @@ snapshots: eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) fast-glob: 3.3.3 - get-tsconfig: 4.7.2 + get-tsconfig: 4.13.0 is-core-module: 2.16.1 is-glob: 4.0.3 transitivePeerDependencies: @@ -17582,6 +18171,23 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-import-resolver-typescript@3.7.0(eslint-plugin-import-x@4.6.1(eslint@9.39.1)(typescript@5.9.3))(eslint-plugin-import@2.29.1(eslint@9.39.1))(eslint@9.39.1): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.3(supports-color@8.1.1) + enhanced-resolve: 5.18.3 + eslint: 9.39.1 + fast-glob: 3.3.3 + get-tsconfig: 4.13.0 + is-bun-module: 1.3.0 + is-glob: 4.0.3 + stable-hash: 0.0.4 + optionalDependencies: + eslint-plugin-import: 2.29.1(eslint@9.39.1) + eslint-plugin-import-x: 4.6.1(eslint@9.39.1)(typescript@5.9.3) + transitivePeerDependencies: + - supports-color + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): dependencies: debug: 3.2.7 @@ -17593,6 +18199,16 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.22.0(eslint@8.57.1)(typescript@5.5.3) + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.22.0(eslint@9.39.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1): dependencies: debug: 3.2.7 @@ -17661,6 +18277,33 @@ snapshots: - eslint-import-resolver-webpack - supports-color + eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1): + dependencies: + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.22.0(eslint@8.57.1)(typescript@5.5.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.22.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1): dependencies: array-includes: 3.1.9 @@ -17689,6 +18332,32 @@ snapshots: - supports-color optional: true + eslint-plugin-import@2.29.1(eslint@9.39.1): + dependencies: + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.39.1 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.22.0(eslint@9.39.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + optional: true + eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.1): dependencies: aria-query: 5.3.2 @@ -17728,10 +18397,10 @@ snapshots: object.fromentries: 2.0.8 semver: 6.3.1 - eslint-plugin-jsx-expressions@1.3.1(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1)(typescript@5.5.3): + eslint-plugin-jsx-expressions@1.3.1(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1)(typescript@5.5.3): dependencies: '@typescript-eslint/experimental-utils': 5.62.0(eslint@8.57.1)(typescript@5.5.3) - '@typescript-eslint/parser': 8.1.0(eslint@8.57.1)(typescript@5.5.3) + '@typescript-eslint/parser': 8.22.0(eslint@8.57.1)(typescript@5.5.3) eslint: 8.57.1 tsutils: 3.21.0(typescript@5.5.3) optionalDependencies: @@ -17983,6 +18652,8 @@ snapshots: estraverse@5.3.0: {} + estree-walker@2.0.2: {} + estree-walker@3.0.3: dependencies: '@types/estree': 1.0.8 @@ -18332,7 +19003,7 @@ snapshots: semver: 7.5.4 tapable: 2.3.0 typescript: 5.5.3 - webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) + webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1) form-data-encoder@2.1.4: {} @@ -18999,6 +19670,8 @@ snapshots: is-mobile@3.1.1: {} + is-module@1.0.0: {} + is-negative-zero@2.0.3: {} is-network-error@1.3.0: {} @@ -19028,6 +19701,10 @@ snapshots: is-promise@4.0.0: {} + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.8 + is-reference@3.0.3: dependencies: '@types/estree': 1.0.8 @@ -19807,7 +20484,7 @@ snapshots: magic-string@0.30.17: dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/sourcemap-codec': 1.5.4 make-dir@3.1.0: dependencies: @@ -20433,6 +21110,8 @@ snapshots: path-type@4.0.0: {} + pathe@2.0.3: {} + pathval@2.0.0: {} peek-readable@5.3.1: {} @@ -20541,7 +21220,7 @@ snapshots: postcss-styled-syntax@0.6.3(postcss@8.4.38): dependencies: postcss: 8.4.38 - typescript: 5.5.3 + typescript: 5.9.3 postcss-value-parser@4.2.0: {} @@ -20955,32 +21634,43 @@ snapshots: dependencies: glob: 7.2.3 - rollup@4.52.4: + rollup-plugin-esbuild@6.2.1(esbuild@0.27.0)(rollup@4.53.2): + dependencies: + debug: 4.4.3(supports-color@8.1.1) + es-module-lexer: 1.7.0 + esbuild: 0.27.0 + get-tsconfig: 4.13.0 + rollup: 4.53.2 + unplugin-utils: 0.2.5 + transitivePeerDependencies: + - supports-color + + rollup@4.53.2: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.52.4 - '@rollup/rollup-android-arm64': 4.52.4 - '@rollup/rollup-darwin-arm64': 4.52.4 - '@rollup/rollup-darwin-x64': 4.52.4 - '@rollup/rollup-freebsd-arm64': 4.52.4 - '@rollup/rollup-freebsd-x64': 4.52.4 - '@rollup/rollup-linux-arm-gnueabihf': 4.52.4 - '@rollup/rollup-linux-arm-musleabihf': 4.52.4 - '@rollup/rollup-linux-arm64-gnu': 4.52.4 - '@rollup/rollup-linux-arm64-musl': 4.52.4 - '@rollup/rollup-linux-loong64-gnu': 4.52.4 - '@rollup/rollup-linux-ppc64-gnu': 4.52.4 - '@rollup/rollup-linux-riscv64-gnu': 4.52.4 - '@rollup/rollup-linux-riscv64-musl': 4.52.4 - '@rollup/rollup-linux-s390x-gnu': 4.52.4 - '@rollup/rollup-linux-x64-gnu': 4.52.4 - '@rollup/rollup-linux-x64-musl': 4.52.4 - '@rollup/rollup-openharmony-arm64': 4.52.4 - '@rollup/rollup-win32-arm64-msvc': 4.52.4 - '@rollup/rollup-win32-ia32-msvc': 4.52.4 - '@rollup/rollup-win32-x64-gnu': 4.52.4 - '@rollup/rollup-win32-x64-msvc': 4.52.4 + '@rollup/rollup-android-arm-eabi': 4.53.2 + '@rollup/rollup-android-arm64': 4.53.2 + '@rollup/rollup-darwin-arm64': 4.53.2 + '@rollup/rollup-darwin-x64': 4.53.2 + '@rollup/rollup-freebsd-arm64': 4.53.2 + '@rollup/rollup-freebsd-x64': 4.53.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.53.2 + '@rollup/rollup-linux-arm-musleabihf': 4.53.2 + '@rollup/rollup-linux-arm64-gnu': 4.53.2 + '@rollup/rollup-linux-arm64-musl': 4.53.2 + '@rollup/rollup-linux-loong64-gnu': 4.53.2 + '@rollup/rollup-linux-ppc64-gnu': 4.53.2 + '@rollup/rollup-linux-riscv64-gnu': 4.53.2 + '@rollup/rollup-linux-riscv64-musl': 4.53.2 + '@rollup/rollup-linux-s390x-gnu': 4.53.2 + '@rollup/rollup-linux-x64-gnu': 4.53.2 + '@rollup/rollup-linux-x64-musl': 4.53.2 + '@rollup/rollup-openharmony-arm64': 4.53.2 + '@rollup/rollup-win32-arm64-msvc': 4.53.2 + '@rollup/rollup-win32-ia32-msvc': 4.53.2 + '@rollup/rollup-win32-x64-gnu': 4.53.2 + '@rollup/rollup-win32-x64-msvc': 4.53.2 fsevents: 2.3.3 router@2.2.0: @@ -21586,7 +22276,7 @@ snapshots: style-loader@4.0.0(webpack@5.102.1): dependencies: - webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) + webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1) stylelint-config-recommended@14.0.0(stylelint@16.5.0(typescript@5.5.3)): dependencies: @@ -21712,7 +22402,7 @@ snapshots: dependencies: '@swc/core': 1.13.5 '@swc/counter': 0.1.3 - webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) + webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1) swr@1.3.0(react@18.3.1): dependencies: @@ -21752,6 +22442,18 @@ snapshots: '@swc/core': 1.13.5 esbuild: 0.25.5 + terser-webpack-plugin@5.3.14(@swc/core@1.13.5)(esbuild@0.27.0)(webpack@5.102.1): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + terser: 5.44.0 + webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1) + optionalDependencies: + '@swc/core': 1.13.5 + esbuild: 0.27.0 + terser@5.26.0: dependencies: '@jridgewell/source-map': 0.3.6 @@ -22164,6 +22866,11 @@ snapshots: unpipe@1.0.0: {} + unplugin-utils@0.2.5: + dependencies: + pathe: 2.0.3 + picomatch: 4.0.3 + unplugin@1.16.1: dependencies: acorn: 8.15.0 @@ -22271,7 +22978,7 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.52.4 + rollup: 4.53.2 tinyglobby: 0.2.15 optionalDependencies: '@types/node': 22.17.0 @@ -22326,7 +23033,7 @@ snapshots: lockfile: 1.0.4 schema-utils: 4.3.3 tapable: 2.3.0 - webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) + webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1) webpack-bundle-analyzer@4.10.2: dependencies: @@ -22360,12 +23067,31 @@ snapshots: import-local: 3.2.0 interpret: 3.1.1 rechoir: 0.8.0 - webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) + webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1) webpack-merge: 6.0.1 optionalDependencies: webpack-bundle-analyzer: 4.10.2 webpack-dev-server: 5.2.2(webpack-cli@6.0.1)(webpack@5.102.1) + webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.102.1): + dependencies: + '@discoveryjs/json-ext': 0.6.3 + '@webpack-cli/configtest': 3.0.1(webpack-cli@6.0.1)(webpack@5.102.1) + '@webpack-cli/info': 3.0.1(webpack-cli@6.0.1)(webpack@5.102.1) + '@webpack-cli/serve': 3.0.1(webpack-cli@6.0.1)(webpack-dev-server@5.2.2)(webpack@5.102.1) + colorette: 2.0.20 + commander: 12.1.0 + cross-spawn: 7.0.6 + envinfo: 7.14.0 + fastest-levenshtein: 1.0.16 + import-local: 3.2.0 + interpret: 3.1.1 + rechoir: 0.8.0 + webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) + webpack-merge: 6.0.1 + optionalDependencies: + webpack-dev-server: 5.2.2(webpack-cli@6.0.1)(webpack@5.102.1) + webpack-dev-middleware@6.1.3(webpack@5.102.1): dependencies: colorette: 2.0.20 @@ -22396,7 +23122,7 @@ snapshots: range-parser: 1.2.1 schema-utils: 4.3.3 optionalDependencies: - webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) + webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1) webpack-dev-server@5.2.2(webpack-cli@6.0.1)(webpack@5.102.1): dependencies: @@ -22430,7 +23156,7 @@ snapshots: ws: 8.18.3 optionalDependencies: webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.2.2)(webpack@5.102.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.102.1) transitivePeerDependencies: - bufferutil - debug @@ -22452,7 +23178,7 @@ snapshots: debug: 3.2.7 require-from-string: 2.0.2 source-map-support: 0.5.21 - webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.25.5)(webpack-cli@6.0.1) + webpack: 5.102.1(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1) transitivePeerDependencies: - supports-color @@ -22512,6 +23238,40 @@ snapshots: terser-webpack-plugin: 5.3.14(@swc/core@1.13.5)(esbuild@0.25.5)(webpack@5.102.1) watchpack: 2.4.4 webpack-sources: 3.3.3 + optionalDependencies: + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.102.1) + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + + webpack@5.102.1(@swc/core@1.13.5)(esbuild@0.27.0)(webpack-cli@6.0.1): + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.15.0 + acorn-import-phases: 1.0.4(acorn@8.15.0) + browserslist: 4.26.3 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.18.3 + es-module-lexer: 1.7.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.1 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.0 + terser-webpack-plugin: 5.3.14(@swc/core@1.13.5)(esbuild@0.27.0)(webpack@5.102.1) + watchpack: 2.4.4 + webpack-sources: 3.3.3 optionalDependencies: webpack-cli: 6.0.1(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.2.2)(webpack@5.102.1) transitivePeerDependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index fbb97180128..5e0c01b31fe 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,5 +1,4 @@ packages: - 'apps-rendering' - 'dotcom-rendering' - - 'ab-testing' - - 'ab-testing/frontend' + - 'ab-testing/*'