diff --git a/.github/actions/install_dependencies/action.yml b/.github/actions/install_dependencies/action.yml new file mode 100644 index 000000000..108096bb8 --- /dev/null +++ b/.github/actions/install_dependencies/action.yml @@ -0,0 +1,35 @@ +name: "Install dependencies" +description: "Install dependencies including caching of npm packages" + +inputs: + npm-required: + description: "Set to true if npm dependencies are already installed" + required: false + default: "true" + GITHUB_TOKEN: + description: "GitHub token to access private npm packages" + required: true + +runs: + using: "composite" + steps: + - name: Setting up .npmrc + if: ${{ inputs.npm-required == 'true' }} + env: + NODE_AUTH_TOKEN: ${{ inputs.GITHUB_TOKEN }} + shell: bash + run: | + echo "//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}" >> ~/.npmrc + echo "@nhsdigital:registry=https://npm.pkg.github.com" >> ~/.npmrc + + - name: Cache npm dependencies + if: ${{ inputs.npm-required == 'true' }} + uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 + with: + path: ./node_modules + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + + - name: make install + if: ${{ inputs.npm-required == 'true' }} + shell: bash + run: make install diff --git a/.github/workflows/cdk_package_code.yml b/.github/workflows/cdk_package_code.yml new file mode 100644 index 000000000..b6767b504 --- /dev/null +++ b/.github/workflows/cdk_package_code.yml @@ -0,0 +1,65 @@ +name: cdk package code + +on: + workflow_call: + inputs: + pinned_image: + type: string + required: true + +jobs: + package_code: + runs-on: ubuntu-22.04 + container: + image: ${{ inputs.pinned_image }} + options: --user 1001:1001 --group-add 128 + defaults: + run: + shell: bash + permissions: + id-token: write + contents: read + packages: read + steps: + - name: copy .tool-versions + run: | + cp /home/vscode/.tool-versions "$HOME/.tool-versions" + cp /home/vscode/.tool-versions ./.tool-versions + + - name: Checkout code + uses: actions/checkout@v5 + + - name: Setting up .npmrc + env: + NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + echo "//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}" >> ~/.npmrc + echo "@nhsdigital:registry=https://npm.pkg.github.com" >> ~/.npmrc + + - name: make install + run: | + make install + make compile + + - name: download the get secrets lambda layer + run: | + make download-get-secrets-layer + + - name: "Tar files" + run: | + tar -cf artifact.tar \ + packages \ + node_modules \ + package.json \ + package-lock.json \ + tsconfig.defaults.json \ + tsconfig.build.json \ + Makefile \ + poetry.lock \ + pyproject.toml + + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f + name: upload build artifact + with: + name: build_artifact + path: artifact.tar diff --git a/.github/workflows/cdk_release_code.yml b/.github/workflows/cdk_release_code.yml new file mode 100644 index 000000000..f43135415 --- /dev/null +++ b/.github/workflows/cdk_release_code.yml @@ -0,0 +1,334 @@ +name: cdk release code + +on: + workflow_call: + inputs: + REAL_CDK_DEPLOYMENT: + type: boolean + default: false + IS_PULL_REQUEST: + type: boolean + default: false + STACK_NAME: + required: true + type: string + TARGET_ENVIRONMENT: + required: true + type: string + APIGEE_ENVIRONMENT: + required: true + type: string + ENABLE_MUTUAL_TLS: + required: true + type: boolean + BUILD_ARTIFACT: + required: true + type: string + TRUSTSTORE_FILE: + required: true + type: string + VERSION_NUMBER: + required: true + type: string + COMMIT_ID: + required: true + type: string + CDK_APP_NAME: + type: string + default: PfPApiApp + LOG_LEVEL: + required: true + type: string + LOG_RETENTION_DAYS: + required: true + type: string + CREATE_INT_RELEASE_NOTES: + type: boolean + default: false + CREATE_INT_RC_RELEASE_NOTES: + type: boolean + default: false + CREATE_PROD_RELEASE_NOTES: + type: boolean + default: false + MARK_JIRA_RELEASED: + type: boolean + default: false + TOGGLE_GET_STATUS_UPDATES: + type: boolean + default: false + RUN_REGRESSION_TESTS: + type: boolean + default: true + ENABLE_ALERTS: + type: boolean + default: true + STATE_MACHINE_LOG_LEVEL: + type: string + REGRESSION_TEST_PRODUCT: + type: string + FORWARD_CSOC_LOGS: + required: true + type: boolean + TC007_NHS_NUMBERS: + required: false + type: string + TC008_NHS_NUMBERS: + required: false + type: string + TC009_NHS_NUMBERS: + required: false + type: string + DEPLOY_APIGEE: + type: boolean + default: true + MTLS_KEY: + type: string + required: true + ALLOW_NHS_NUMBER_OVERRIDE: + required: true + type: boolean + REGRESSION_TEST_NON_PROXYGEN: + type: boolean + UPDATE_GH_PAGES_RELEASE_TAG: + type: boolean + default: false + pinned_image: + type: string + required: true + secrets: + CLOUD_FORMATION_DEPLOY_ROLE: + required: true + TARGET_SPINE_SERVER: + required: true + TARGET_SERVICE_SEARCH_SERVER: + required: true + DEV_CLOUD_FORMATION_CHECK_VERSION_ROLE: + required: false + INT_CLOUD_FORMATION_CHECK_VERSION_ROLE: + required: false + PROD_CLOUD_FORMATION_CHECK_VERSION_ROLE: + required: false + DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE: + required: false + REGRESSION_TESTS_PEM: + required: false + PROXYGEN_ROLE: + required: false + +jobs: + release_code_and_api: + runs-on: ubuntu-22.04 + environment: ${{ inputs.TARGET_ENVIRONMENT }} + container: + image: ${{ inputs.pinned_image }} + options: --user 1001:1001 --group-add 128 + defaults: + run: + shell: bash + name: deploy cdk app ${{ inputs.CDK_APP_NAME }} + permissions: + id-token: write + contents: write + env: + AWS_MAX_RETRY: 20 + + steps: + - name: copy .tool-versions + run: | + cp /home/vscode/.tool-versions "$HOME/.tool-versions" + + - name: Checkout local github actions + uses: actions/checkout@v5 + with: + fetch-depth: 0 + sparse-checkout: | + .github + + - name: create_int_rc_release_notes + uses: ./.github/actions/update_confluence_jira + if: ${{ inputs.CREATE_INT_RC_RELEASE_NOTES == true }} + with: + TARGET_ENVIRONMENT: int + RELEASE_TAG: ${{ inputs.VERSION_NUMBER }} + CONFLUENCE_PAGE_ID: "768067994" + CREATE_RC_RELEASE_NOTES: true + DEV_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_CHECK_VERSION_ROLE }} + TARGET_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.INT_CLOUD_FORMATION_CHECK_VERSION_ROLE }} + DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE }} + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v5 + with: + aws-region: eu-west-2 + role-to-assume: ${{ secrets.CLOUD_FORMATION_DEPLOY_ROLE }} + role-session-name: aws-pfp-release-code + + - name: download build artifact + uses: actions/download-artifact@v5 + with: + name: ${{ inputs.BUILD_ARTIFACT }} + path: . + + - name: extract build_artifact + run: | + tar -xf artifact.tar + + - name: install dependencies + uses: ./.github/actions/install_dependencies + with: + npm-required: false + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Show diff + env: + CDK_APP_NAME: ${{ inputs.CDK_APP_NAME }} + REQUIRE_APPROVAL: never + CDK_CONFIG_stackName: ${{ inputs.STACK_NAME }} + CDK_CONFIG_versionNumber: ${{ inputs.VERSION_NUMBER }} + CDK_CONFIG_commitId: ${{ inputs.COMMIT_ID }} + CDK_CONFIG_isPullRequest: ${{ inputs.IS_PULL_REQUEST }} + CDK_CONFIG_environment: ${{ inputs.TARGET_ENVIRONMENT }} + CDK_CONFIG_logRetentionInDays: ${{ inputs.LOG_RETENTION_DAYS }} + CDK_CONFIG_logLevel: ${{ inputs.LOG_LEVEL }} + CDK_CONFIG_targetSpineServer: ${{ secrets.TARGET_SPINE_SERVER }} + CDK_CONFIG_targetServiceSearchServer: ${{ secrets.TARGET_SERVICE_SEARCH_SERVER }} + CDK_CONFIG_toggleGetStatusUpdates: ${{ inputs.TOGGLE_GET_STATUS_UPDATES }} + CDK_CONFIG_allowNhsNumberOverride: ${{ inputs.ALLOW_NHS_NUMBER_OVERRIDE }} + CDK_CONFIG_tc007NhsNumberValue: ${{ inputs.TC007_NHS_NUMBERS || '9992387920' }} + CDK_CONFIG_tc008NhsNumberValue: ${{ inputs.TC008_NHS_NUMBERS || '9992387920' }} + CDK_CONFIG_tc009NhsNumberValue: ${{ inputs.TC009_NHS_NUMBERS || '9992387920' }} + CDK_CONFIG_trustStoreFile: ${{ inputs.TRUSTSTORE_FILE }} + CDK_CONFIG_forwardCsocLogs: ${{ inputs.FORWARD_CSOC_LOGS }} + run: npm run cdk-diff --workspace packages/cdk + + - name: Deploy code + env: + CDK_APP_NAME: ${{ inputs.CDK_APP_NAME }} + REQUIRE_APPROVAL: never + CDK_CONFIG_stackName: ${{ inputs.STACK_NAME }} + CDK_CONFIG_versionNumber: ${{ inputs.VERSION_NUMBER }} + CDK_CONFIG_commitId: ${{ inputs.COMMIT_ID }} + CDK_CONFIG_isPullRequest: ${{ inputs.IS_PULL_REQUEST }} + CDK_CONFIG_environment: ${{ inputs.TARGET_ENVIRONMENT }} + CDK_CONFIG_logRetentionInDays: ${{ inputs.LOG_RETENTION_DAYS }} + CDK_CONFIG_logLevel: ${{ inputs.LOG_LEVEL }} + CDK_CONFIG_targetSpineServer: ${{ secrets.TARGET_SPINE_SERVER }} + CDK_CONFIG_targetServiceSearchServer: ${{ secrets.TARGET_SERVICE_SEARCH_SERVER }} + CDK_CONFIG_toggleGetStatusUpdates: ${{ inputs.TOGGLE_GET_STATUS_UPDATES }} + CDK_CONFIG_allowNhsNumberOverride: ${{ inputs.ALLOW_NHS_NUMBER_OVERRIDE }} + CDK_CONFIG_tc007NhsNumberValue: ${{ inputs.TC007_NHS_NUMBERS || '9992387920' }} + CDK_CONFIG_tc008NhsNumberValue: ${{ inputs.TC008_NHS_NUMBERS || '9992387920' }} + CDK_CONFIG_tc009NhsNumberValue: ${{ inputs.TC009_NHS_NUMBERS || '9992387920' }} + CDK_CONFIG_trustStoreFile: ${{ inputs.TRUSTSTORE_FILE }} + CDK_CONFIG_forwardCsocLogs: ${{ inputs.FORWARD_CSOC_LOGS }} + run: npm run cdk-deploy --workspace packages/cdk + + - name: get mtls secrets + shell: bash + run: | + mkdir -p ~/.proxygen/tmp + client_private_key_arn=$(aws cloudformation list-exports --query "Exports[?Name=='account-resources:PfpClientKeySecret'].Value" --output text) + client_cert_arn=$(aws cloudformation list-exports --query "Exports[?Name=='account-resources:PfpClientCertSecret'].Value" --output text) + aws secretsmanager get-secret-value --secret-id "${client_private_key_arn}" --query SecretString --output text > ~/.proxygen/tmp/client_private_key + aws secretsmanager get-secret-value --secret-id "${client_cert_arn}" --query SecretString --output text > ~/.proxygen/tmp/client_cert + + - name: Configure AWS Credentials for api release + if: ${{ inputs.DEPLOY_APIGEE == true && always() && !failure() && !cancelled() }} + uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 + with: + aws-region: eu-west-2 + role-to-assume: ${{ secrets.PROXYGEN_ROLE }} + role-session-name: pfp-api-proxygen + + - name: Deploy PFP API to Apigee + shell: bash + if: ${{ inputs.DEPLOY_APIGEE == true && always() && !failure() && !cancelled() }} + env: + API_TYPE: standard + VERSION_NUMBER: ${{ inputs.VERSION_NUMBER }} + SPEC_PATH: ./packages/specification/dist/prescriptions-for-patients.resolved.json + STACK_NAME: ${{ inputs.STACK_NAME }} + AWS_ENVIRONMENT: ${{ inputs.TARGET_ENVIRONMENT }} + APIGEE_ENVIRONMENT: ${{ inputs.APIGEE_ENVIRONMENT }} + PROXYGEN_PRIVATE_KEY_NAME: PrescriptionsForPatientsProxygenPrivateKey + PROXYGEN_KID: "2026-01-22-PROD-prescriptions-for-patients-v2" + DRY_RUN: false + ENABLE_MUTUAL_TLS: ${{ inputs.ENABLE_MUTUAL_TLS }} + MTLS_KEY: ${{ inputs.MTLS_KEY }} + IS_PULL_REQUEST: ${{ inputs.IS_PULL_REQUEST }} + run: ./.github/scripts/deploy_api.sh + + - uses: actions/upload-artifact@v4 + name: Upload specs + if: ${{ inputs.REAL_CDK_DEPLOYMENT == true }} + with: + name: ${{ inputs.APIGEE_ENVIRONMENT }}-specs + path: | + ./packages/specification/dist/prescriptions-for-patients.resolved.json + + - name: create_int_release_notes + uses: ./.github/actions/update_confluence_jira + if: ${{ inputs.REAL_CDK_DEPLOYMENT == true && inputs.CREATE_INT_RELEASE_NOTES == true && always() && !failure() && !cancelled() }} + with: + TARGET_ENVIRONMENT: int + CONFLUENCE_PAGE_ID: "768067990" + CREATE_RC_RELEASE_NOTES: false + DEV_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_CHECK_VERSION_ROLE }} + TARGET_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.INT_CLOUD_FORMATION_CHECK_VERSION_ROLE }} + DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE }} + + - name: create_prod_release_notes + uses: ./.github/actions/update_confluence_jira + if: ${{ inputs.REAL_CDK_DEPLOYMENT == true && inputs.CREATE_PROD_RELEASE_NOTES == true && always() && !failure() && !cancelled() }} + with: + TARGET_ENVIRONMENT: prod + CONFLUENCE_PAGE_ID: "768067992" + CREATE_RC_RELEASE_NOTES: false + DEV_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_CHECK_VERSION_ROLE }} + TARGET_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.PROD_CLOUD_FORMATION_CHECK_VERSION_ROLE }} + DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE }} + + - name: mark_released_in_jira + uses: ./.github/actions/mark_jira_released + if: ${{ inputs.REAL_CDK_DEPLOYMENT == true && inputs.MARK_JIRA_RELEASED == true && always() && !failure() && !cancelled() }} + with: + RELEASE_TAG: ${{ inputs.VERSION_NUMBER }} + DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE }} + - name: Checkout gh-pages + if: ${{ inputs.REAL_CDK_DEPLOYMENT == true && inputs.IS_PULL_REQUEST == false }} + uses: actions/checkout@v5 + with: + ref: gh-pages + path: gh-pages + + - name: Update release tag in github pages + # if: ${{ inputs.REAL_CDK_DEPLOYMENT == true && inputs.IS_PULL_REQUEST == false }} + # Disabled by default; can be explicitly enabled by setting UPDATE_GH_PAGES_RELEASE_TAG to true. + if: ${{ inputs.UPDATE_GH_PAGES_RELEASE_TAG == true && inputs.IS_PULL_REQUEST == false }} + run: | + cd gh-pages + NOW=$(date +'%Y-%m-%dT%H:%M:%S') + echo "tag,release_datetime" > _data/${{ inputs.APIGEE_ENVIRONMENT }}_latest.csv + echo "${{ inputs.VERSION_NUMBER }},${NOW}" >> _data/${{ inputs.APIGEE_ENVIRONMENT }}_latest.csv + echo "${{ inputs.VERSION_NUMBER }},${NOW}" >> _data/${{ inputs.APIGEE_ENVIRONMENT }}_deployments.csv + git config user.name github-actions + git config user.email github-actions@github.com + git add _data/${{ inputs.APIGEE_ENVIRONMENT }}_latest.csv + git add _data/${{ inputs.APIGEE_ENVIRONMENT }}_deployments.csv + git commit -m 'update releases for ${{ inputs.APIGEE_ENVIRONMENT }}' + parallel --retries 10 --delay 3 ::: "git pull --rebase && git push" + + regression_tests: + name: Regression Tests + uses: ./.github/workflows/run_regression_tests.yml + if: ${{ always() && !failure() && !cancelled() && inputs.RUN_REGRESSION_TESTS == true }} + needs: [release_code_and_api] + with: + ENVIRONMENT: ${{ inputs.APIGEE_ENVIRONMENT }} + VERSION_NUMBER: ${{ inputs.VERSION_NUMBER }} + REGRESSION_TEST_PRODUCT: ${{ inputs.REGRESSION_TEST_PRODUCT }} + REGRESSION_TEST_NON_PROXYGEN: ${{ inputs.REGRESSION_TEST_NON_PROXYGEN }} + pinned_image: ${{ inputs.pinned_image }} + secrets: + REGRESSION_TESTS_PEM: ${{ secrets.REGRESSION_TESTS_PEM }} diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index e49997869..5f941a325 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -19,7 +19,6 @@ jobs: with: verify_published_from_main_image: false - quality_checks: uses: NHSDigital/eps-common-workflows/.github/workflows/quality-checks-devcontainer.yml@5ac2707dd9cd60ad127275179495b9c890d74711 needs: [get_config_values] @@ -119,12 +118,51 @@ jobs: TARGET_SPINE_SERVER: ${{ secrets.DEV_TARGET_SPINE_SERVER }} TARGET_SERVICE_SEARCH_SERVER: ${{ secrets.DEV_TARGET_SERVICE_SEARCH_SERVER }} PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} + + package_cdk_code: + needs: [get_issue_number, tag_release, get_config_values] + uses: ./.github/workflows/cdk_package_code.yml + with: + pinned_image: ${{ needs.get_config_values.outputs.pinned_image }} + + release_cdk_code: + needs: [get_issue_number, package_code, get_commit_id, get_config_values] + uses: ./.github/workflows/cdk_release_code.yml + with: + IS_PULL_REQUEST: true + STACK_NAME: pfp-pr-cdk-${{needs.get_issue_number.outputs.issue_number}} + TARGET_ENVIRONMENT: dev + APIGEE_ENVIRONMENT: internal-dev + ENABLE_MUTUAL_TLS: false + MTLS_KEY: prescriptions-for-patients-mtls-1 + BUILD_ARTIFACT: build_artifact + TRUSTSTORE_FILE: pfp-truststore-pr.pem + VERSION_NUMBER: PR-${{ needs.get_issue_number.outputs.issue_number }} + COMMIT_ID: ${{ needs.get_commit_id.outputs.commit_id }} + LOG_LEVEL: DEBUG + LOG_RETENTION_DAYS: 30 + TOGGLE_GET_STATUS_UPDATES: true + ENABLE_ALERTS: false + STATE_MACHINE_LOG_LEVEL: ALL + RUN_REGRESSION_TESTS: false # Don't run regression tests on CDK yet + REGRESSION_TEST_PRODUCT: PFP-AWS + FORWARD_CSOC_LOGS: false + DEPLOY_APIGEE: true + ALLOW_NHS_NUMBER_OVERRIDE: true + pinned_image: ${{ needs.get_config_values.outputs.pinned_image }} + secrets: + REGRESSION_TESTS_PEM: ${{ secrets.REGRESSION_TESTS_PEM }} + CLOUD_FORMATION_DEPLOY_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_DEPLOY_ROLE }} + TARGET_SPINE_SERVER: ${{ secrets.DEV_TARGET_SPINE_SERVER }} + TARGET_SERVICE_SEARCH_SERVER: ${{ secrets.DEV_TARGET_SERVICE_SEARCH_SERVER }} + PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} + release_sandbox_code: needs: [get_issue_number, package_code, get_commit_id, get_config_values] uses: ./.github/workflows/sam_release_code.yml with: IS_PULL_REQUEST: true - STACK_NAME: pfp-pr-${{needs.get_issue_number.outputs.issue_number}}-sandbox + STACK_NAME: pfp-pr-cdk-${{needs.get_issue_number.outputs.issue_number}}-sandbox ARTIFACT_BUCKET_PREFIX: PR-sandbox-${{needs.get_issue_number.outputs.issue_number}} TARGET_ENVIRONMENT: dev APIGEE_ENVIRONMENT: internal-dev-sandbox diff --git a/.gitignore b/.gitignore index 3bf963f19..bb7cf1944 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,10 @@ **/public/ **/coverage/ **/node_modules/ +cdk.out/ .#* __pycache__/ +.env .envrc .idea .vscode/settings.json diff --git a/.vscode/prescriptionsforpatients.code-workspace b/.vscode/prescriptionsforpatients.code-workspace index 26dacb3ea..ba295f4bd 100644 --- a/.vscode/prescriptionsforpatients.code-workspace +++ b/.vscode/prescriptionsforpatients.code-workspace @@ -4,6 +4,10 @@ "name": "prescriptionsforpatients-monorepo", "path": ".." }, + { + "name": "packages/cdk", + "path": "../packages/cdk" + }, { "name": "packages/capabilityStatement", "path": "../packages/capabilityStatement" diff --git a/Makefile b/Makefile index a135cc27f..8b627b594 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,20 @@ +SHELL = /bin/bash +.SHELLFLAGS = -o pipefail -c +stack_name ?= pfp-api +export CDK_APP_NAME=PfPApiApp +export CDK_CONFIG_stackName=${stack_name} +export CDK_CONFIG_versionNumber=undefined +export CDK_CONFIG_commitId=undefined +export CDK_CONFIG_isPullRequest=true # Turns off mTLS and drift detection when true +export CDK_CONFIG_environment=dev +export CDK_CONFIG_logRetentionInDays=30 +export CDK_CONFIG_logLevel=DEBUG +export CDK_CONFIG_targetSpineServer=msg.veit07.devspineservices.nhs.uk +export CDK_CONFIG_targetServiceSearchServer=int.api.service.nhs.uk +export CDK_CONFIG_toggleGetStatusUpdates=false +export CDK_CONFIG_allowNhsNumberOverride=false +export CDK_CONFIG_forwardCsocLogs=false + .PHONY: install build test publish release clean install-node install-python install-hooks sam-build sam-build-sandbox sam-run-local sam-sync sam-sync-sandbox sam-deploy sam-delete sam-list-endpoints sam-list-resources sam-list-outputs sam-validate sam-validate-sandbox sam-deploy-package compile-node compile compile-specification download-get-secrets-layer lint-node lint test clean deep-clean install: install-python install-hooks install-node @@ -104,6 +121,18 @@ sam-deploy-package: guard-artifact_bucket guard-artifact_bucket_prefix guard-sta EnableAlerts=$$ENABLE_ALERTS \ StateMachineLogLevel=$$STATE_MACHINE_LOG_LEVEL +cdk-deploy: download-get-secrets-layer + CDK_CONFIG_stackName=${stack_name} REQUIRE_APPROVAL="$${REQUIRE_APPROVAL:-any-change}" npm run cdk-deploy --workspace packages/cdk + +cdk-synth: download-get-secrets-layer + CDK_CONFIG_stackName=${stack_name} npm run cdk-synth --workspace packages/cdk + +cdk-diff: + CDK_CONFIG_stackName=${stack_name} npm run cdk-diff --workspace packages/cdk + +cdk-watch: download-get-secrets-layer + CDK_CONFIG_stackName=${stack_name} REQUIRE_APPROVAL="$${REQUIRE_APPROVAL:-any-change}" npm run cdk-watch --workspace packages/cdk + compile-node: npx tsc --build tsconfig.build.json @@ -128,6 +157,7 @@ download-get-secrets-layer: fi lint-node: compile-node + npm run lint --workspace packages/cdk npm run lint --workspace packages/capabilityStatement npm run lint --workspace packages/getMyPrescriptions npm run lint --workspace packages/enrichPrescriptions @@ -142,6 +172,7 @@ lint: lint-node actionlint shellcheck cfn-lint echo "Linting complete" test: compile + npm run test --workspace packages/cdk npm run test --workspace packages/capabilityStatement npm run test --workspace packages/getMyPrescriptions npm run test --workspace packages/enrichPrescriptions @@ -153,6 +184,7 @@ test: compile npm run test --workspace packages/common/testing clean: + rm -rf packages/cdk/coverage rm -rf packages/capabilityStatement/coverage rm -rf packages/getMyPrescriptions/coverage rm -rf packages/enrichPrescriptions/coverage diff --git a/nhsdigital-eps-cdk-constructs-1.6.0.tgz b/nhsdigital-eps-cdk-constructs-1.6.0.tgz new file mode 100644 index 000000000..62dcefa93 Binary files /dev/null and b/nhsdigital-eps-cdk-constructs-1.6.0.tgz differ diff --git a/package-lock.json b/package-lock.json index 0ba5d1fb3..79df2c137 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "MIT", "workspaces": [ + "packages/cdk", "packages/capabilityStatement", "packages/getMyPrescriptions", "packages/enrichPrescriptions", @@ -38,6 +39,114 @@ "vitest": "^4.1.0" } }, + "node_modules/@aws-cdk/asset-awscli-v1": { + "version": "2.2.263", + "license": "Apache-2.0" + }, + "node_modules/@aws-cdk/asset-node-proxy-agent-v6": { + "version": "2.1.1", + "license": "Apache-2.0" + }, + "node_modules/@aws-cdk/cloud-assembly-schema": { + "version": "52.2.0", + "bundleDependencies": [ + "jsonschema", + "semver" + ], + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "jsonschema": "~1.4.1", + "semver": "^7.7.3" + }, + "engines": { + "node": ">= 18.0.0" + } + }, + "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/jsonschema": { + "version": "1.4.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/semver": { + "version": "7.7.3", + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@aws-crypto/crc32": { + "version": "5.2.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/crc32c": { + "version": "5.2.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha1-browser": { + "version": "5.2.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-crypto/sha256-browser": { "version": "5.2.0", "license": "Apache-2.0", @@ -145,8 +254,6 @@ }, "node_modules/@aws-lambda-powertools/commons": { "version": "2.32.0", - "resolved": "https://registry.npmjs.org/@aws-lambda-powertools/commons/-/commons-2.32.0.tgz", - "integrity": "sha512-vsdakJDZu/KkJ5+1WHkawQ5R06aCK0XYB3nc3tpcBfO1YmOHkn+QpuGiZtkmpzIykGPAO9lnBjK5joAeim2o4A==", "license": "MIT-0", "dependencies": { "@aws/lambda-invoke-store": "0.2.4" @@ -154,8 +261,6 @@ }, "node_modules/@aws-lambda-powertools/logger": { "version": "2.32.0", - "resolved": "https://registry.npmjs.org/@aws-lambda-powertools/logger/-/logger-2.32.0.tgz", - "integrity": "sha512-ZfomsMv4FnxYkgUvU9S6BPrTzd+ntPiIBZcrvSNz+/aPvVwu2BGHSKDuVlXa7nr6rB1wjzaA5bmLVTESIdnsdQ==", "license": "MIT-0", "dependencies": { "@aws-lambda-powertools/commons": "2.32.0", @@ -176,8 +281,6 @@ }, "node_modules/@aws-lambda-powertools/parameters": { "version": "2.32.0", - "resolved": "https://registry.npmjs.org/@aws-lambda-powertools/parameters/-/parameters-2.32.0.tgz", - "integrity": "sha512-Fnr7AqWPOSvHQU6xlOQwmdafr24FWLHGFtQQJYw1ltVT3wW1z4JJSKZLOqLh2Me2zcUddpAxaJ9bB1MJ4Zabmw==", "license": "MIT-0", "dependencies": { "@aws-lambda-powertools/commons": "2.32.0" @@ -211,25 +314,186 @@ } } }, + "node_modules/@aws-sdk/client-cloudformation": { + "version": "3.1016.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.973.24", + "@aws-sdk/credential-provider-node": "^3.972.25", + "@aws-sdk/middleware-host-header": "^3.972.8", + "@aws-sdk/middleware-logger": "^3.972.8", + "@aws-sdk/middleware-recursion-detection": "^3.972.8", + "@aws-sdk/middleware-user-agent": "^3.972.25", + "@aws-sdk/region-config-resolver": "^3.972.9", + "@aws-sdk/types": "^3.973.6", + "@aws-sdk/util-endpoints": "^3.996.5", + "@aws-sdk/util-user-agent-browser": "^3.972.8", + "@aws-sdk/util-user-agent-node": "^3.973.11", + "@smithy/config-resolver": "^4.4.13", + "@smithy/core": "^3.23.12", + "@smithy/fetch-http-handler": "^5.3.15", + "@smithy/hash-node": "^4.2.12", + "@smithy/invalid-dependency": "^4.2.12", + "@smithy/middleware-content-length": "^4.2.12", + "@smithy/middleware-endpoint": "^4.4.27", + "@smithy/middleware-retry": "^4.4.44", + "@smithy/middleware-serde": "^4.2.15", + "@smithy/middleware-stack": "^4.2.12", + "@smithy/node-config-provider": "^4.3.12", + "@smithy/node-http-handler": "^4.5.0", + "@smithy/protocol-http": "^5.3.12", + "@smithy/smithy-client": "^4.12.7", + "@smithy/types": "^4.13.1", + "@smithy/url-parser": "^4.2.12", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.43", + "@smithy/util-defaults-mode-node": "^4.2.47", + "@smithy/util-endpoints": "^3.3.3", + "@smithy/util-middleware": "^4.2.12", + "@smithy/util-retry": "^4.2.12", + "@smithy/util-utf8": "^4.2.2", + "@smithy/util-waiter": "^4.2.13", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-route-53": { + "version": "3.1016.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.973.24", + "@aws-sdk/credential-provider-node": "^3.972.25", + "@aws-sdk/middleware-host-header": "^3.972.8", + "@aws-sdk/middleware-logger": "^3.972.8", + "@aws-sdk/middleware-recursion-detection": "^3.972.8", + "@aws-sdk/middleware-sdk-route53": "^3.972.10", + "@aws-sdk/middleware-user-agent": "^3.972.25", + "@aws-sdk/region-config-resolver": "^3.972.9", + "@aws-sdk/types": "^3.973.6", + "@aws-sdk/util-endpoints": "^3.996.5", + "@aws-sdk/util-user-agent-browser": "^3.972.8", + "@aws-sdk/util-user-agent-node": "^3.973.11", + "@smithy/config-resolver": "^4.4.13", + "@smithy/core": "^3.23.12", + "@smithy/fetch-http-handler": "^5.3.15", + "@smithy/hash-node": "^4.2.12", + "@smithy/invalid-dependency": "^4.2.12", + "@smithy/middleware-content-length": "^4.2.12", + "@smithy/middleware-endpoint": "^4.4.27", + "@smithy/middleware-retry": "^4.4.44", + "@smithy/middleware-serde": "^4.2.15", + "@smithy/middleware-stack": "^4.2.12", + "@smithy/node-config-provider": "^4.3.12", + "@smithy/node-http-handler": "^4.5.0", + "@smithy/protocol-http": "^5.3.12", + "@smithy/smithy-client": "^4.12.7", + "@smithy/types": "^4.13.1", + "@smithy/url-parser": "^4.2.12", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.43", + "@smithy/util-defaults-mode-node": "^4.2.47", + "@smithy/util-endpoints": "^3.3.3", + "@smithy/util-middleware": "^4.2.12", + "@smithy/util-retry": "^4.2.12", + "@smithy/util-utf8": "^4.2.2", + "@smithy/util-waiter": "^4.2.13", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-s3": { + "version": "3.1016.0", + "license": "Apache-2.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.973.24", + "@aws-sdk/credential-provider-node": "^3.972.25", + "@aws-sdk/middleware-bucket-endpoint": "^3.972.8", + "@aws-sdk/middleware-expect-continue": "^3.972.8", + "@aws-sdk/middleware-flexible-checksums": "^3.974.4", + "@aws-sdk/middleware-host-header": "^3.972.8", + "@aws-sdk/middleware-location-constraint": "^3.972.8", + "@aws-sdk/middleware-logger": "^3.972.8", + "@aws-sdk/middleware-recursion-detection": "^3.972.8", + "@aws-sdk/middleware-sdk-s3": "^3.972.24", + "@aws-sdk/middleware-ssec": "^3.972.8", + "@aws-sdk/middleware-user-agent": "^3.972.25", + "@aws-sdk/region-config-resolver": "^3.972.9", + "@aws-sdk/signature-v4-multi-region": "^3.996.12", + "@aws-sdk/types": "^3.973.6", + "@aws-sdk/util-endpoints": "^3.996.5", + "@aws-sdk/util-user-agent-browser": "^3.972.8", + "@aws-sdk/util-user-agent-node": "^3.973.11", + "@smithy/config-resolver": "^4.4.13", + "@smithy/core": "^3.23.12", + "@smithy/eventstream-serde-browser": "^4.2.12", + "@smithy/eventstream-serde-config-resolver": "^4.3.12", + "@smithy/eventstream-serde-node": "^4.2.12", + "@smithy/fetch-http-handler": "^5.3.15", + "@smithy/hash-blob-browser": "^4.2.13", + "@smithy/hash-node": "^4.2.12", + "@smithy/hash-stream-node": "^4.2.12", + "@smithy/invalid-dependency": "^4.2.12", + "@smithy/md5-js": "^4.2.12", + "@smithy/middleware-content-length": "^4.2.12", + "@smithy/middleware-endpoint": "^4.4.27", + "@smithy/middleware-retry": "^4.4.44", + "@smithy/middleware-serde": "^4.2.15", + "@smithy/middleware-stack": "^4.2.12", + "@smithy/node-config-provider": "^4.3.12", + "@smithy/node-http-handler": "^4.5.0", + "@smithy/protocol-http": "^5.3.12", + "@smithy/smithy-client": "^4.12.7", + "@smithy/types": "^4.13.1", + "@smithy/url-parser": "^4.2.12", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.43", + "@smithy/util-defaults-mode-node": "^4.2.47", + "@smithy/util-endpoints": "^3.3.3", + "@smithy/util-middleware": "^4.2.12", + "@smithy/util-retry": "^4.2.12", + "@smithy/util-stream": "^4.5.20", + "@smithy/util-utf8": "^4.2.2", + "@smithy/util-waiter": "^4.2.13", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/client-secrets-manager": { - "version": "3.1014.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.1014.0.tgz", - "integrity": "sha512-XRp6t0AHGxmCWwYqfELxJUiHnOIR5yUyWBNXJjeEp4t9Pzdg86pQw1aXfmfZ4sVdebT06lL9+D0NsP12ztoSlQ==", + "version": "3.1015.0", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.23", - "@aws-sdk/credential-provider-node": "^3.972.24", + "@aws-sdk/core": "^3.973.24", + "@aws-sdk/credential-provider-node": "^3.972.25", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", "@aws-sdk/middleware-recursion-detection": "^3.972.8", - "@aws-sdk/middleware-user-agent": "^3.972.24", + "@aws-sdk/middleware-user-agent": "^3.972.25", "@aws-sdk/region-config-resolver": "^3.972.9", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", - "@aws-sdk/util-user-agent-node": "^3.973.10", + "@aws-sdk/util-user-agent-node": "^3.973.11", "@smithy/config-resolver": "^4.4.13", "@smithy/core": "^3.23.12", "@smithy/fetch-http-handler": "^5.3.15", @@ -262,24 +526,23 @@ } }, "node_modules/@aws-sdk/client-ssm": { - "version": "3.1014.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-ssm/-/client-ssm-3.1014.0.tgz", - "integrity": "sha512-+TMGrFm0tOyOnHnyoDO+tbjqV4ADAT2VYC0rrlMM2ECWHBYRfDVTyewzEqsoouo539c1ru4MlBF9nCgT+taRxQ==", + "version": "3.1015.0", "license": "Apache-2.0", + "peer": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.23", - "@aws-sdk/credential-provider-node": "^3.972.24", + "@aws-sdk/core": "^3.973.24", + "@aws-sdk/credential-provider-node": "^3.972.25", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", "@aws-sdk/middleware-recursion-detection": "^3.972.8", - "@aws-sdk/middleware-user-agent": "^3.972.24", + "@aws-sdk/middleware-user-agent": "^3.972.25", "@aws-sdk/region-config-resolver": "^3.972.9", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", - "@aws-sdk/util-user-agent-node": "^3.973.10", + "@aws-sdk/util-user-agent-node": "^3.973.11", "@smithy/config-resolver": "^4.4.13", "@smithy/core": "^3.23.12", "@smithy/fetch-http-handler": "^5.3.15", @@ -313,9 +576,7 @@ } }, "node_modules/@aws-sdk/core": { - "version": "3.973.23", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.23.tgz", - "integrity": "sha512-aoJncvD1XvloZ9JLnKqTRL9dBy+Szkryoag9VT+V1TqsuUgIxV9cnBVM/hrDi2vE8bDqLiDR8nirdRcCdtJu0w==", + "version": "3.973.24", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.6", @@ -336,13 +597,22 @@ "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/crc64-nvme": { + "version": "3.972.5", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.972.21", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.21.tgz", - "integrity": "sha512-BkAfKq8Bd4shCtec1usNz//urPJF/SZy14qJyxkSaRJQ/Vv1gVh0VZSTmS7aE6aLMELkFV5wHHrS9ZcdG8Kxsg==", + "version": "3.972.22", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.23", + "@aws-sdk/core": "^3.973.24", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/types": "^4.13.1", @@ -353,12 +623,10 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.972.23", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.23.tgz", - "integrity": "sha512-4XZ3+Gu5DY8/n8zQFHBgcKTF7hWQl42G6CY9xfXVo2d25FM/lYkpmuzhYopYoPL1ITWkJ2OSBQfYEu5JRfHOhA==", + "version": "3.972.24", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.23", + "@aws-sdk/core": "^3.973.24", "@aws-sdk/types": "^3.973.6", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/node-http-handler": "^4.5.0", @@ -374,19 +642,17 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.972.23", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.23.tgz", - "integrity": "sha512-PZLSmU0JFpNCDFReidBezsgL5ji9jOBry8CnZdw4Jj6d0K2z3Ftnp44NXgADqYx5BLMu/ZHujfeJReaDoV+IwQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.23", - "@aws-sdk/credential-provider-env": "^3.972.21", - "@aws-sdk/credential-provider-http": "^3.972.23", - "@aws-sdk/credential-provider-login": "^3.972.23", - "@aws-sdk/credential-provider-process": "^3.972.21", - "@aws-sdk/credential-provider-sso": "^3.972.23", - "@aws-sdk/credential-provider-web-identity": "^3.972.23", - "@aws-sdk/nested-clients": "^3.996.13", + "version": "3.972.24", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.24", + "@aws-sdk/credential-provider-env": "^3.972.22", + "@aws-sdk/credential-provider-http": "^3.972.24", + "@aws-sdk/credential-provider-login": "^3.972.24", + "@aws-sdk/credential-provider-process": "^3.972.22", + "@aws-sdk/credential-provider-sso": "^3.972.24", + "@aws-sdk/credential-provider-web-identity": "^3.972.24", + "@aws-sdk/nested-clients": "^3.996.14", "@aws-sdk/types": "^3.973.6", "@smithy/credential-provider-imds": "^4.2.12", "@smithy/property-provider": "^4.2.12", @@ -399,13 +665,11 @@ } }, "node_modules/@aws-sdk/credential-provider-login": { - "version": "3.972.23", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.23.tgz", - "integrity": "sha512-OmE/pSkbMM3dCj1HdOnZ5kXnKK+R/Yz+kbBugraBecp0pGAs21eEURfQRz+1N2gzIHLVyGIP1MEjk/uSrFsngg==", + "version": "3.972.24", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.23", - "@aws-sdk/nested-clients": "^3.996.13", + "@aws-sdk/core": "^3.973.24", + "@aws-sdk/nested-clients": "^3.996.14", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/protocol-http": "^5.3.12", @@ -418,17 +682,15 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.972.24", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.24.tgz", - "integrity": "sha512-9Jwi7aps3AfUicJyF5udYadPypPpCwUZ6BSKr/QjRbVCpRVS1wc+1Q6AEZ/qz8J4JraeRd247pSzyMQSIHVebw==", + "version": "3.972.25", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "^3.972.21", - "@aws-sdk/credential-provider-http": "^3.972.23", - "@aws-sdk/credential-provider-ini": "^3.972.23", - "@aws-sdk/credential-provider-process": "^3.972.21", - "@aws-sdk/credential-provider-sso": "^3.972.23", - "@aws-sdk/credential-provider-web-identity": "^3.972.23", + "@aws-sdk/credential-provider-env": "^3.972.22", + "@aws-sdk/credential-provider-http": "^3.972.24", + "@aws-sdk/credential-provider-ini": "^3.972.24", + "@aws-sdk/credential-provider-process": "^3.972.22", + "@aws-sdk/credential-provider-sso": "^3.972.24", + "@aws-sdk/credential-provider-web-identity": "^3.972.24", "@aws-sdk/types": "^3.973.6", "@smithy/credential-provider-imds": "^4.2.12", "@smithy/property-provider": "^4.2.12", @@ -441,12 +703,10 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.972.21", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.21.tgz", - "integrity": "sha512-nRxbeOJ1E1gVA0lNQezuMVndx+ZcuyaW/RB05pUsznN5BxykSlH6KkZ/7Ca/ubJf3i5N3p0gwNO5zgPSCzj+ww==", + "version": "3.972.22", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.23", + "@aws-sdk/core": "^3.973.24", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", @@ -458,14 +718,12 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.972.23", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.23.tgz", - "integrity": "sha512-APUccADuYPLL0f2htpM8Z4czabSmHOdo4r41W6lKEZdy++cNJ42Radqy6x4TopENzr3hR6WYMyhiuiqtbf/nAA==", + "version": "3.972.24", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.23", - "@aws-sdk/nested-clients": "^3.996.13", - "@aws-sdk/token-providers": "3.1014.0", + "@aws-sdk/core": "^3.973.24", + "@aws-sdk/nested-clients": "^3.996.14", + "@aws-sdk/token-providers": "3.1015.0", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", @@ -477,13 +735,11 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.972.23", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.23.tgz", - "integrity": "sha512-H5JNqtIwOu/feInmMMWcK0dL5r897ReEn7n2m16Dd0DPD9gA2Hg8Cq4UDzZ/9OzaLh/uqBM6seixz0U6Fi2Eag==", + "version": "3.972.24", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.23", - "@aws-sdk/nested-clients": "^3.996.13", + "@aws-sdk/core": "^3.973.24", + "@aws-sdk/nested-clients": "^3.996.14", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", @@ -494,28 +750,28 @@ "node": ">=20.0.0" } }, - "node_modules/@aws-sdk/middleware-host-header": { + "node_modules/@aws-sdk/middleware-bucket-endpoint": { "version": "3.972.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.8.tgz", - "integrity": "sha512-wAr2REfKsqoKQ+OkNqvOShnBoh+nkPurDKW7uAeVSu6kUECnWlSJiPvnoqxGlfousEY/v9LfS9sNc46hjSYDIQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.6", + "@aws-sdk/util-arn-parser": "^3.972.3", + "@smithy/node-config-provider": "^4.3.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", + "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" } }, - "node_modules/@aws-sdk/middleware-logger": { + "node_modules/@aws-sdk/middleware-expect-continue": { "version": "3.972.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.8.tgz", - "integrity": "sha512-CWl5UCM57WUFaFi5kB7IBY1UmOeLvNZAZ2/OZ5l20ldiJ3TiIz1pC65gYj8X0BCPWkeR1E32mpsCk1L1I4n+lA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.6", + "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" }, @@ -523,59 +779,160 @@ "node": ">=20.0.0" } }, - "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.972.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.8.tgz", - "integrity": "sha512-BnnvYs2ZEpdlmZ2PNlV2ZyQ8j8AEkMTjN79y/YA475ER1ByFYrkVR85qmhni8oeTaJcDqbx364wDpitDAA/wCA==", + "node_modules/@aws-sdk/middleware-flexible-checksums": { + "version": "3.974.4", "license": "Apache-2.0", "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@aws-crypto/crc32c": "5.2.0", + "@aws-crypto/util": "5.2.0", + "@aws-sdk/core": "^3.973.24", + "@aws-sdk/crc64-nvme": "^3.972.5", "@aws-sdk/types": "^3.973.6", - "@aws/lambda-invoke-store": "^0.2.2", + "@smithy/is-array-buffer": "^4.2.2", + "@smithy/node-config-provider": "^4.3.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", + "@smithy/util-middleware": "^4.2.12", + "@smithy/util-stream": "^4.5.20", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" } }, - "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.972.24", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.24.tgz", - "integrity": "sha512-dLTWy6IfAMhNiSEvMr07g/qZ54be6pLqlxVblbF6AzafmmGAzMMj8qMoY9B4+YgT+gY9IcuxZslNh03L6PyMCQ==", + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.972.8", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.23", "@aws-sdk/types": "^3.973.6", - "@aws-sdk/util-endpoints": "^3.996.5", - "@smithy/core": "^3.23.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", - "@smithy/util-retry": "^4.2.12", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" } }, - "node_modules/@aws-sdk/nested-clients": { - "version": "3.996.13", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.13.tgz", - "integrity": "sha512-ptZ1HF4yYHNJX8cgFF+8NdYO69XJKZn7ft0/ynV3c0hCbN+89fAbrLS+fqniU2tW8o9Kfqhj8FUh+IPXb2Qsuw==", + "node_modules/@aws-sdk/middleware-location-constraint": { + "version": "3.972.8", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.6", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.972.8", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.6", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.972.8", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.6", + "@aws/lambda-invoke-store": "^0.2.2", + "@smithy/protocol-http": "^5.3.12", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-route53": { + "version": "3.972.10", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.6", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-s3": { + "version": "3.972.24", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.24", + "@aws-sdk/types": "^3.973.6", + "@aws-sdk/util-arn-parser": "^3.972.3", + "@smithy/core": "^3.23.12", + "@smithy/node-config-provider": "^4.3.12", + "@smithy/protocol-http": "^5.3.12", + "@smithy/signature-v4": "^5.3.12", + "@smithy/smithy-client": "^4.12.7", + "@smithy/types": "^4.13.1", + "@smithy/util-config-provider": "^4.2.2", + "@smithy/util-middleware": "^4.2.12", + "@smithy/util-stream": "^4.5.20", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-ssec": { + "version": "3.972.8", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.6", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.972.25", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.24", + "@aws-sdk/types": "^3.973.6", + "@aws-sdk/util-endpoints": "^3.996.5", + "@smithy/core": "^3.23.12", + "@smithy/protocol-http": "^5.3.12", + "@smithy/types": "^4.13.1", + "@smithy/util-retry": "^4.2.12", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/nested-clients": { + "version": "3.996.14", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.23", + "@aws-sdk/core": "^3.973.24", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", "@aws-sdk/middleware-recursion-detection": "^3.972.8", - "@aws-sdk/middleware-user-agent": "^3.972.24", + "@aws-sdk/middleware-user-agent": "^3.972.25", "@aws-sdk/region-config-resolver": "^3.972.9", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", - "@aws-sdk/util-user-agent-node": "^3.973.10", + "@aws-sdk/util-user-agent-node": "^3.973.11", "@smithy/config-resolver": "^4.4.13", "@smithy/core": "^3.23.12", "@smithy/fetch-http-handler": "^5.3.15", @@ -609,8 +966,6 @@ }, "node_modules/@aws-sdk/region-config-resolver": { "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.9.tgz", - "integrity": "sha512-eQ+dFU05ZRC/lC2XpYlYSPlXtX3VT8sn5toxN2Fv7EXlMoA2p9V7vUBKqHunfD4TRLpxUq8Y8Ol/nCqiv327Ng==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.6", @@ -623,14 +978,27 @@ "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.996.12", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-sdk-s3": "^3.972.24", + "@aws-sdk/types": "^3.973.6", + "@smithy/protocol-http": "^5.3.12", + "@smithy/signature-v4": "^5.3.12", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/token-providers": { - "version": "3.1014.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1014.0.tgz", - "integrity": "sha512-gHTHNUoaOGNrSWkl32A7wFsU78jlNTlqMccLu0byUk5CysYYXaxNMIonIVr4YcykC7vgtDS5ABuz83giy6fzJA==", + "version": "3.1015.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.23", - "@aws-sdk/nested-clients": "^3.996.13", + "@aws-sdk/core": "^3.973.24", + "@aws-sdk/nested-clients": "^3.996.14", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", @@ -643,8 +1011,6 @@ }, "node_modules/@aws-sdk/types": { "version": "3.973.6", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.6.tgz", - "integrity": "sha512-Atfcy4E++beKtwJHiDln2Nby8W/mam64opFPTiHEqgsthqeydFS1pY+OUlN1ouNOmf8ArPU/6cDS65anOP3KQw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.13.1", @@ -654,10 +1020,18 @@ "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/util-arn-parser": { + "version": "3.972.3", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/util-endpoints": { "version": "3.996.5", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.5.tgz", - "integrity": "sha512-Uh93L5sXFNbyR5sEPMzUU8tJ++Ku97EY4udmC01nB8Zu+xfBPwpIwJ6F7snqQeq8h2pf+8SGN5/NoytfKgYPIw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.6", @@ -682,8 +1056,6 @@ }, "node_modules/@aws-sdk/util-user-agent-browser": { "version": "3.972.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.8.tgz", - "integrity": "sha512-B3KGXJviV2u6Cdw2SDY2aDhoJkVfY/Q/Trwk2CMSkikE1Oi6gRzxhvhIfiRpHfmIsAhV4EA54TVEX8K6CbHbkA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.6", @@ -693,12 +1065,10 @@ } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.973.10", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.10.tgz", - "integrity": "sha512-E99zeTscCc+pTMfsvnfi6foPpKmdD1cZfOC7/P8UUrjsoQdg9VEWPRD+xdFduKnfPXwcvby58AlO9jwwF6U96g==", + "version": "3.973.11", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "^3.972.24", + "@aws-sdk/middleware-user-agent": "^3.972.25", "@aws-sdk/types": "^3.973.6", "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", @@ -719,8 +1089,6 @@ }, "node_modules/@aws-sdk/xml-builder": { "version": "3.972.15", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.15.tgz", - "integrity": "sha512-PxMRlCFNiQnke9YR29vjFQwz4jq+6Q04rOVFeTDR2K7Qpv9h9FOWOxG+zJjageimYbWqE3bTuLjmryWHAWbvaA==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.13.1", @@ -733,8 +1101,6 @@ }, "node_modules/@aws/lambda-invoke-store": { "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.4.tgz", - "integrity": "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==", "license": "Apache-2.0", "engines": { "node": ">=18.0.0" @@ -742,8 +1108,6 @@ }, "node_modules/@babel/code-frame": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { @@ -757,8 +1121,6 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, "license": "MIT", "engines": { @@ -767,8 +1129,6 @@ }, "node_modules/@babel/helper-validator-identifier": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { @@ -777,8 +1137,6 @@ }, "node_modules/@babel/parser": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", - "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "dev": true, "license": "MIT", "dependencies": { @@ -801,8 +1159,6 @@ }, "node_modules/@babel/types": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, "license": "MIT", "dependencies": { @@ -834,9 +1190,9 @@ } }, "node_modules/@emnapi/core": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.0.tgz", - "integrity": "sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", + "integrity": "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==", "dev": true, "license": "MIT", "optional": true, @@ -846,9 +1202,9 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.0.tgz", - "integrity": "sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", + "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", "dev": true, "license": "MIT", "optional": true, @@ -1143,8 +1499,6 @@ }, "node_modules/@esbuild/linux-x64": { "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz", - "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==", "cpu": [ "x64" ], @@ -1328,8 +1682,6 @@ }, "node_modules/@eslint/config-array": { "version": "0.23.3", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.3.tgz", - "integrity": "sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1343,8 +1695,6 @@ }, "node_modules/@eslint/config-helpers": { "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.3.tgz", - "integrity": "sha512-lzGN0onllOZCGroKJmRwY6QcEHxbjBw1gwB8SgRSqK8YbbtEXMvKynsXc3553ckIEBxsbMBU7oOZXKIPGZNeZw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1356,8 +1706,6 @@ }, "node_modules/@eslint/core": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.1.tgz", - "integrity": "sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1388,8 +1736,6 @@ }, "node_modules/@eslint/object-schema": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.3.tgz", - "integrity": "sha512-iM869Pugn9Nsxbh/YHRqYiqd23AmIbxJOcpUMOuWCVNdoQJ5ZtwL6h3t0bcZzJUlC3Dq9jCFCESBZnX0GTv7iQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1398,8 +1744,6 @@ }, "node_modules/@eslint/plugin-kit": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.6.1.tgz", - "integrity": "sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1417,8 +1761,6 @@ }, "node_modules/@faker-js/faker": { "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-7.6.0.tgz", - "integrity": "sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==", "dev": true, "license": "MIT", "engines": { @@ -1472,8 +1814,6 @@ }, "node_modules/@humanwhocodes/momoa": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@humanwhocodes/momoa/-/momoa-2.0.4.tgz", - "integrity": "sha512-RE815I4arJFtt+FVeU1Tgp9/Xvecacji8w/V6XtXsWWH/wz/eNkNbhb+ny/+PlVZjV0rxQpRSQKNKE3lcktHEA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1507,8 +1847,6 @@ }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { @@ -1537,8 +1875,6 @@ }, "node_modules/@middy/http-header-normalizer": { "version": "7.2.1", - "resolved": "https://registry.npmjs.org/@middy/http-header-normalizer/-/http-header-normalizer-7.2.1.tgz", - "integrity": "sha512-dCne3FMDbdMzhYt4MEOoIHm8R47N0ooPNdU1JleeReWZtp7u54VbMET0C16GChVmbdCVFk/4IxDtM2nY+IHx1w==", "license": "MIT", "engines": { "node": ">=22" @@ -1550,8 +1886,6 @@ }, "node_modules/@middy/input-output-logger": { "version": "7.2.1", - "resolved": "https://registry.npmjs.org/@middy/input-output-logger/-/input-output-logger-7.2.1.tgz", - "integrity": "sha512-52M/I3ZF/e0gNEE+4Mgu4SFxFvFFkLMmzczAeN7gUSfkQ1ZyCpLp3PyLMNybKUmo4HnUNte9DkWp86HKzBJA6Q==", "license": "MIT", "dependencies": { "@middy/util": "7.2.1" @@ -1566,8 +1900,6 @@ }, "node_modules/@middy/util": { "version": "7.2.1", - "resolved": "https://registry.npmjs.org/@middy/util/-/util-7.2.1.tgz", - "integrity": "sha512-vwtRPxQ5stQFR8Ulfsuqt8GgPJX6iXrF/9SiOTsJzw2nliNu/aPcZ8DR6sPj+gFar/QdUJuym6iyjevfeMNiFA==", "license": "MIT", "engines": { "node": ">=22" @@ -1603,6 +1935,21 @@ "uninstall": "^0.0.0" } }, + "node_modules/@nhsdigital/eps-cdk-constructs": { + "version": "1.0.0", + "resolved": "file:nhsdigital-eps-cdk-constructs-1.6.0.tgz", + "integrity": "sha512-XxrZKkdUJGy9jYml2Hy+YhIAQTIpKsP2rVrgI1dauyuqFWZ1F+MMkxbJPpofJfQcSN+ZgafJRGC7xTapOiGYLA==", + "license": "MIT", + "dependencies": { + "@aws-sdk/client-cloudformation": "^3.1013.0", + "@aws-sdk/client-route-53": "^3.1013.0", + "@aws-sdk/client-s3": "^3.1013.0", + "aws-cdk": "^2.1112.0", + "aws-cdk-lib": "^2.244.0", + "cdk-nag": "^2.37.52", + "constructs": "^10.5.1" + } + }, "node_modules/@nhsdigital/eps-spine-client": { "version": "2.1.78", "license": "MIT", @@ -1616,8 +1963,6 @@ }, "node_modules/@noble/hashes": { "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", "dev": true, "license": "MIT", "engines": { @@ -1631,6 +1976,7 @@ "version": "1.9.0", "dev": true, "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=8.0.0" } @@ -1812,8 +2158,6 @@ }, "node_modules/@oxc-project/runtime": { "version": "0.115.0", - "resolved": "https://registry.npmjs.org/@oxc-project/runtime/-/runtime-0.115.0.tgz", - "integrity": "sha512-Rg8Wlt5dCbXhQnsXPrkOjL1DTSvXLgb2R/KYfnf1/K+R0k6UMLEmbQXPM+kwrWqSmWA2t0B1EtHy2/3zikQpvQ==", "dev": true, "license": "MIT", "engines": { @@ -1822,8 +2166,6 @@ }, "node_modules/@oxc-project/types": { "version": "0.115.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.115.0.tgz", - "integrity": "sha512-4n91DKnebUS4yjUHl2g3/b2T+IUdCfmoZGhmwsovZCDaJSs+QkVAM+0AqqTxHSsHfeiMuueT75cZaZcT/m0pSw==", "dev": true, "license": "MIT", "funding": { @@ -1921,9 +2263,7 @@ "license": "MIT" }, "node_modules/@redocly/cli": { - "version": "2.24.1", - "resolved": "https://registry.npmjs.org/@redocly/cli/-/cli-2.24.1.tgz", - "integrity": "sha512-GTAKMPtyvO7vn3CrSp8Q5SJlMUr8q6wgMN/J4K5owphyp5gOQCZqMySyWcq+V5RPPXkTuIHZYEzgnecB6RF2bQ==", + "version": "2.25.1", "dev": true, "license": "MIT", "dependencies": { @@ -1931,8 +2271,9 @@ "@opentelemetry/resources": "2.0.1", "@opentelemetry/sdk-trace-node": "2.0.1", "@opentelemetry/semantic-conventions": "1.34.0", - "@redocly/openapi-core": "2.24.1", - "@redocly/respect-core": "2.24.1", + "@redocly/cli-otel": "0.1.2", + "@redocly/openapi-core": "2.25.1", + "@redocly/respect-core": "2.25.1", "abort-controller": "^3.0.0", "ajv": "npm:@redocly/ajv@8.18.0", "ajv-formats": "^3.0.1", @@ -1965,6 +2306,22 @@ "npm": ">=10" } }, + "node_modules/@redocly/cli-otel": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ulid": "^2.3.0" + } + }, + "node_modules/@redocly/cli-otel/node_modules/ulid": { + "version": "2.4.0", + "dev": true, + "license": "MIT", + "bin": { + "ulid": "bin/cli.js" + } + }, "node_modules/@redocly/cli/node_modules/ajv": { "name": "@redocly/ajv", "version": "8.18.0", @@ -2114,9 +2471,7 @@ } }, "node_modules/@redocly/config": { - "version": "0.44.1", - "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.44.1.tgz", - "integrity": "sha512-l6/ZE+/RBfNDdhzltau6cbW8+k5PgJbJBMqaBrlQlZQlmGBHMxqGyDaon4dPLj0jdi37gsMQ3yf95JBY/vaDSg==", + "version": "0.44.2", "dev": true, "license": "MIT", "dependencies": { @@ -2124,14 +2479,12 @@ } }, "node_modules/@redocly/openapi-core": { - "version": "2.24.1", - "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-2.24.1.tgz", - "integrity": "sha512-Iqc/4DI/CIQkKys8HRHkX+bpF/UosVUE7lc7tuxIOKzVIOk5QhQMglbd2yzbAYgJF7YAtCDDAKWosvXnvTTWsA==", + "version": "2.25.1", "dev": true, "license": "MIT", "dependencies": { "@redocly/ajv": "^8.18.0", - "@redocly/config": "^0.44.1", + "@redocly/config": "^0.44.2", "ajv": "npm:@redocly/ajv@8.18.0", "ajv-formats": "^3.0.1", "colorette": "^1.2.0", @@ -2149,8 +2502,6 @@ "node_modules/@redocly/openapi-core/node_modules/ajv": { "name": "@redocly/ajv", "version": "8.18.0", - "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-F+LMD2IDIXuHxgpLJh3nkLj9+tSaEzoUWd+7fONGq5pe2169FUDjpEkOfEpoGLz1sbZni/69p07OsecNfAOpqA==", "dev": true, "license": "MIT", "dependencies": { @@ -2166,22 +2517,18 @@ }, "node_modules/@redocly/openapi-core/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, "license": "MIT" }, "node_modules/@redocly/respect-core": { - "version": "2.24.1", - "resolved": "https://registry.npmjs.org/@redocly/respect-core/-/respect-core-2.24.1.tgz", - "integrity": "sha512-WMeg9TmAc0ZINp6Tza+ZWhMuIBM28us6ZyLj5DKWZhkBZhKaTNhXlmTYES11uM35eie+mYZStTov4vXYL//wqg==", + "version": "2.25.1", "dev": true, "license": "MIT", "dependencies": { "@faker-js/faker": "^7.6.0", "@noble/hashes": "^1.8.0", "@redocly/ajv": "^8.18.0", - "@redocly/openapi-core": "2.24.1", + "@redocly/openapi-core": "2.25.1", "ajv": "npm:@redocly/ajv@8.18.0", "better-ajv-errors": "^1.2.0", "colorette": "^2.0.20", @@ -2199,8 +2546,6 @@ "node_modules/@redocly/respect-core/node_modules/ajv": { "name": "@redocly/ajv", "version": "8.18.0", - "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-F+LMD2IDIXuHxgpLJh3nkLj9+tSaEzoUWd+7fONGq5pe2169FUDjpEkOfEpoGLz1sbZni/69p07OsecNfAOpqA==", "dev": true, "license": "MIT", "dependencies": { @@ -2216,15 +2561,11 @@ }, "node_modules/@redocly/respect-core/node_modules/colorette": { "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true, "license": "MIT" }, "node_modules/@redocly/respect-core/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, "license": "MIT" }, @@ -2383,8 +2724,6 @@ }, "node_modules/@rolldown/binding-linux-x64-gnu": { "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.9.tgz", - "integrity": "sha512-cVEl1vZtBsBZna3YMjGXNvnYYrOJ7RzuWvZU0ffvJUexWkukMaDuGhUXn0rjnV0ptzGVkvc+vW9Yqy6h8YX4pg==", "cpu": [ "x64" ], @@ -2400,8 +2739,6 @@ }, "node_modules/@rolldown/binding-linux-x64-musl": { "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.9.tgz", - "integrity": "sha512-UzYnKCIIc4heAKgI4PZ3dfBGUZefGCJ1TPDuLHoCzgrMYPb5Rv6TLFuYtyM4rWyHM7hymNdsg5ik2C+UD9VDbA==", "cpu": [ "x64" ], @@ -2485,15 +2822,11 @@ }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.9.tgz", - "integrity": "sha512-w6oiRWgEBl04QkFZgmW+jnU1EC9b57Oihi2ot3HNWIQRqgHp5PnYDia5iZ5FF7rpa4EQdiqMDXjlqKGXBhsoXw==", "dev": true, "license": "MIT" }, "node_modules/@smithy/abort-controller": { "version": "4.2.12", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.12.tgz", - "integrity": "sha512-xolrFw6b+2iYGl6EcOL7IJY71vvyZ0DJ3mcKtpykqPe2uscwtzDZJa1uVQXyP7w9Dd+kGwYnPbMsJrGISKiY/Q==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.13.1", @@ -2503,10 +2836,29 @@ "node": ">=18.0.0" } }, + "node_modules/@smithy/chunked-blob-reader": { + "version": "5.2.2", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/chunked-blob-reader-native": { + "version": "4.2.3", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-base64": "^4.3.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@smithy/config-resolver": { "version": "4.4.13", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.13.tgz", - "integrity": "sha512-iIzMC5NmOUP6WL6o8iPBjFhUhBZ9pPjpUpQYWMUFQqKyXXzOftbfK8zcQCz/jFV1Psmf05BK5ypx4K2r4Tnwdg==", "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^4.3.12", @@ -2522,8 +2874,6 @@ }, "node_modules/@smithy/core": { "version": "3.23.12", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.23.12.tgz", - "integrity": "sha512-o9VycsYNtgC+Dy3I0yrwCqv9CWicDnke0L7EVOrZtJpjb2t0EjaEofmMrYc0T1Kn3yk32zm6cspxF9u9Bj7e5w==", "license": "Apache-2.0", "dependencies": { "@smithy/protocol-http": "^5.3.12", @@ -2543,8 +2893,6 @@ }, "node_modules/@smithy/credential-provider-imds": { "version": "4.2.12", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.12.tgz", - "integrity": "sha512-cr2lR792vNZcYMriSIj+Um3x9KWrjcu98kn234xA6reOAFMmbRpQMOv8KPgEmLLtx3eldU6c5wALKFqNOhugmg==", "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^4.3.12", @@ -2557,10 +2905,68 @@ "node": ">=18.0.0" } }, + "node_modules/@smithy/eventstream-codec": { + "version": "4.2.12", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@smithy/types": "^4.13.1", + "@smithy/util-hex-encoding": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-browser": { + "version": "4.2.12", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^4.2.12", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-config-resolver": { + "version": "4.3.12", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-node": { + "version": "4.2.12", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^4.2.12", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-universal": { + "version": "4.2.12", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-codec": "^4.2.12", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@smithy/fetch-http-handler": { "version": "5.3.15", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.15.tgz", - "integrity": "sha512-T4jFU5N/yiIfrtrsb9uOQn7RdELdM/7HbyLNr6uO/mpkj1ctiVs7CihVr51w4LyQlXWDpXFn4BElf1WmQvZu/A==", "license": "Apache-2.0", "dependencies": { "@smithy/protocol-http": "^5.3.12", @@ -2573,10 +2979,21 @@ "node": ">=18.0.0" } }, + "node_modules/@smithy/hash-blob-browser": { + "version": "4.2.13", + "license": "Apache-2.0", + "dependencies": { + "@smithy/chunked-blob-reader": "^5.2.2", + "@smithy/chunked-blob-reader-native": "^4.2.3", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@smithy/hash-node": { "version": "4.2.12", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.12.tgz", - "integrity": "sha512-QhBYbGrbxTkZ43QoTPrK72DoYviDeg6YKDrHTMJbbC+A0sml3kSjzFtXP7BtbyJnXojLfTQldGdUR0RGD8dA3w==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.13.1", @@ -2588,10 +3005,20 @@ "node": ">=18.0.0" } }, + "node_modules/@smithy/hash-stream-node": { + "version": "4.2.12", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.1", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@smithy/invalid-dependency": { "version": "4.2.12", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.12.tgz", - "integrity": "sha512-/4F1zb7Z8LOu1PalTdESFHR0RbPwHd3FcaG1sI3UEIriQTWakysgJr65lc1jj6QY5ye7aFsisajotH6UhWfm/g==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.13.1", @@ -2611,10 +3038,20 @@ "node": ">=18.0.0" } }, + "node_modules/@smithy/md5-js": { + "version": "4.2.12", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.1", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@smithy/middleware-content-length": { "version": "4.2.12", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.12.tgz", - "integrity": "sha512-YE58Yz+cvFInWI/wOTrB+DbvUVz/pLn5mC5MvOV4fdRUc6qGwygyngcucRQjAhiCEbmfLOXX0gntSIcgMvAjmA==", "license": "Apache-2.0", "dependencies": { "@smithy/protocol-http": "^5.3.12", @@ -2627,8 +3064,6 @@ }, "node_modules/@smithy/middleware-endpoint": { "version": "4.4.27", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.27.tgz", - "integrity": "sha512-T3TFfUgXQlpcg+UdzcAISdZpj4Z+XECZ/cefgA6wLBd6V4lRi0svN2hBouN/be9dXQ31X4sLWz3fAQDf+nt6BA==", "license": "Apache-2.0", "dependencies": { "@smithy/core": "^3.23.12", @@ -2646,8 +3081,6 @@ }, "node_modules/@smithy/middleware-retry": { "version": "4.4.44", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.44.tgz", - "integrity": "sha512-Y1Rav7m5CFRPQyM4CI0koD/bXjyjJu3EQxZZhtLGD88WIrBrQ7kqXM96ncd6rYnojwOo/u9MXu57JrEvu/nLrA==", "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^4.3.12", @@ -2666,8 +3099,6 @@ }, "node_modules/@smithy/middleware-serde": { "version": "4.2.15", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.15.tgz", - "integrity": "sha512-ExYhcltZSli0pgAKOpQQe1DLFBLryeZ22605y/YS+mQpdNWekum9Ujb/jMKfJKgjtz1AZldtwA/wCYuKJgjjlg==", "license": "Apache-2.0", "dependencies": { "@smithy/core": "^3.23.12", @@ -2681,8 +3112,6 @@ }, "node_modules/@smithy/middleware-stack": { "version": "4.2.12", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.12.tgz", - "integrity": "sha512-kruC5gRHwsCOuyCd4ouQxYjgRAym2uDlCvQ5acuMtRrcdfg7mFBg6blaxcJ09STpt3ziEkis6bhg1uwrWU7txw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.13.1", @@ -2694,8 +3123,6 @@ }, "node_modules/@smithy/node-config-provider": { "version": "4.3.12", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.12.tgz", - "integrity": "sha512-tr2oKX2xMcO+rBOjobSwVAkV05SIfUKz8iI53rzxEmgW3GOOPOv0UioSDk+J8OpRQnpnhsO3Af6IEBabQBVmiw==", "license": "Apache-2.0", "dependencies": { "@smithy/property-provider": "^4.2.12", @@ -2709,8 +3136,6 @@ }, "node_modules/@smithy/node-http-handler": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.5.0.tgz", - "integrity": "sha512-Rnq9vQWiR1+/I6NZZMNzJHV6pZYyEHt2ZnuV3MG8z2NNenC4i/8Kzttz7CjZiHSmsN5frhXhg17z3Zqjjhmz1A==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^4.2.12", @@ -2725,8 +3150,6 @@ }, "node_modules/@smithy/property-provider": { "version": "4.2.12", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.12.tgz", - "integrity": "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.13.1", @@ -2738,8 +3161,6 @@ }, "node_modules/@smithy/protocol-http": { "version": "5.3.12", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.12.tgz", - "integrity": "sha512-fit0GZK9I1xoRlR4jXmbLhoN0OdEpa96ul8M65XdmXnxXkuMxM0Y8HDT0Fh0Xb4I85MBvBClOzgSrV1X2s1Hxw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.13.1", @@ -2751,8 +3172,6 @@ }, "node_modules/@smithy/querystring-builder": { "version": "4.2.12", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.12.tgz", - "integrity": "sha512-6wTZjGABQufekycfDGMEB84BgtdOE/rCVTov+EDXQ8NHKTUNIp/j27IliwP7tjIU9LR+sSzyGBOXjeEtVgzCHg==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.13.1", @@ -2765,8 +3184,6 @@ }, "node_modules/@smithy/querystring-parser": { "version": "4.2.12", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.12.tgz", - "integrity": "sha512-P2OdvrgiAKpkPNKlKUtWbNZKB1XjPxM086NeVhK+W+wI46pIKdWBe5QyXvhUm3MEcyS/rkLvY8rZzyUdmyDZBw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.13.1", @@ -2778,8 +3195,6 @@ }, "node_modules/@smithy/service-error-classification": { "version": "4.2.12", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.12.tgz", - "integrity": "sha512-LlP29oSQN0Tw0b6D0Xo6BIikBswuIiGYbRACy5ujw/JgWSzTdYj46U83ssf6Ux0GyNJVivs2uReU8pt7Eu9okQ==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.13.1" @@ -2790,8 +3205,6 @@ }, "node_modules/@smithy/shared-ini-file-loader": { "version": "4.4.7", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.7.tgz", - "integrity": "sha512-HrOKWsUb+otTeo1HxVWeEb99t5ER1XrBi/xka2Wv6NVmTbuCUC1dvlrksdvxFtODLBjsC+PHK+fuy2x/7Ynyiw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.13.1", @@ -2803,8 +3216,6 @@ }, "node_modules/@smithy/signature-v4": { "version": "5.3.12", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.12.tgz", - "integrity": "sha512-B/FBwO3MVOL00DaRSXfXfa/TRXRheagt/q5A2NM13u7q+sHS59EOVGQNfG7DkmVtdQm5m3vOosoKAXSqn/OEgw==", "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^4.2.2", @@ -2822,8 +3233,6 @@ }, "node_modules/@smithy/smithy-client": { "version": "4.12.7", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.12.7.tgz", - "integrity": "sha512-q3gqnwml60G44FECaEEsdQMplYhDMZYCtYhMCzadCnRnnHIobZJjegmdoUo6ieLQlPUzvrMdIJUpx6DoPmzANQ==", "license": "Apache-2.0", "dependencies": { "@smithy/core": "^3.23.12", @@ -2840,8 +3249,6 @@ }, "node_modules/@smithy/types": { "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.1.tgz", - "integrity": "sha512-787F3yzE2UiJIQ+wYW1CVg2odHjmaWLGksnKQHUrK/lYZSEcy1msuLVvxaR/sI2/aDe9U+TBuLsXnr3vod1g0g==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -2852,8 +3259,6 @@ }, "node_modules/@smithy/url-parser": { "version": "4.2.12", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.12.tgz", - "integrity": "sha512-wOPKPEpso+doCZGIlr+e1lVI6+9VAKfL4kZWFgzVgGWY2hZxshNKod4l2LXS3PRC9otH/JRSjtEHqQ/7eLciRA==", "license": "Apache-2.0", "dependencies": { "@smithy/querystring-parser": "^4.2.12", @@ -2919,8 +3324,6 @@ }, "node_modules/@smithy/util-defaults-mode-browser": { "version": "4.3.43", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.43.tgz", - "integrity": "sha512-Qd/0wCKMaXxev/z00TvNzGCH2jlKKKxXP1aDxB6oKwSQthe3Og2dMhSayGCnsma1bK/kQX1+X7SMP99t6FgiiQ==", "license": "Apache-2.0", "dependencies": { "@smithy/property-provider": "^4.2.12", @@ -2934,8 +3337,6 @@ }, "node_modules/@smithy/util-defaults-mode-node": { "version": "4.2.47", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.47.tgz", - "integrity": "sha512-qSRbYp1EQ7th+sPFuVcVO05AE0QH635hycdEXlpzIahqHHf2Fyd/Zl+8v0XYMJ3cgDVPa0lkMefU7oNUjAP+DQ==", "license": "Apache-2.0", "dependencies": { "@smithy/config-resolver": "^4.4.13", @@ -2952,8 +3353,6 @@ }, "node_modules/@smithy/util-endpoints": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.3.3.tgz", - "integrity": "sha512-VACQVe50j0HZPjpwWcjyT51KUQ4AnsvEaQ2lKHOSL4mNLD0G9BjEniQ+yCt1qqfKfiAHRAts26ud7hBjamrwig==", "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^4.3.12", @@ -2966,8 +3365,6 @@ }, "node_modules/@smithy/util-hex-encoding": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", - "integrity": "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -2978,8 +3375,6 @@ }, "node_modules/@smithy/util-middleware": { "version": "4.2.12", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.12.tgz", - "integrity": "sha512-Er805uFUOvgc0l8nv0e0su0VFISoxhJ/AwOn3gL2NWNY2LUEldP5WtVcRYSQBcjg0y9NfG8JYrCJaYDpupBHJQ==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.13.1", @@ -2991,8 +3386,6 @@ }, "node_modules/@smithy/util-retry": { "version": "4.2.12", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.12.tgz", - "integrity": "sha512-1zopLDUEOwumjcHdJ1mwBHddubYF8GMQvstVCLC54Y46rqoHwlIU+8ZzUeaBcD+WCJHyDGSeZ2ml9YSe9aqcoQ==", "license": "Apache-2.0", "dependencies": { "@smithy/service-error-classification": "^4.2.12", @@ -3005,8 +3398,6 @@ }, "node_modules/@smithy/util-stream": { "version": "4.5.20", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.20.tgz", - "integrity": "sha512-4yXLm5n/B5SRBR2p8cZ90Sbv4zL4NKsgxdzCzp/83cXw2KxLEumt5p+GAVyRNZgQOSrzXn9ARpO0lUe8XSlSDw==", "license": "Apache-2.0", "dependencies": { "@smithy/fetch-http-handler": "^5.3.15", @@ -3024,8 +3415,6 @@ }, "node_modules/@smithy/util-uri-escape": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", - "integrity": "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -3047,8 +3436,6 @@ }, "node_modules/@smithy/util-waiter": { "version": "4.2.13", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.13.tgz", - "integrity": "sha512-2zdZ9DTHngRtcYxJK1GUDxruNr53kv5W2Lupe0LMU+Imr6ohQg8M2T14MNkj1Y0wS3FFwpgpGQyvuaMF7CiTmQ==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^4.2.12", @@ -3071,8 +3458,6 @@ }, "node_modules/@standard-schema/spec": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "dev": true, "license": "MIT" }, @@ -3114,8 +3499,6 @@ }, "node_modules/@types/chai": { "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", - "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", "dev": true, "license": "MIT", "dependencies": { @@ -3125,15 +3508,11 @@ }, "node_modules/@types/deep-eql": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", "dev": true, "license": "MIT" }, "node_modules/@types/esrecurse": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", - "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", "dev": true, "license": "MIT" }, @@ -3157,10 +3536,9 @@ }, "node_modules/@types/node": { "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", - "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.18.0" } @@ -3177,17 +3555,15 @@ "optional": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.1.tgz", - "integrity": "sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==", + "version": "8.57.2", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/type-utils": "8.57.1", - "@typescript-eslint/utils": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/type-utils": "8.57.2", + "@typescript-eslint/utils": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -3200,22 +3576,21 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.57.1", + "@typescript-eslint/parser": "^8.57.2", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.1.tgz", - "integrity": "sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==", + "version": "8.57.2", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3" }, "engines": { @@ -3231,14 +3606,12 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.1.tgz", - "integrity": "sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==", + "version": "8.57.2", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.57.1", - "@typescript-eslint/types": "^8.57.1", + "@typescript-eslint/tsconfig-utils": "^8.57.2", + "@typescript-eslint/types": "^8.57.2", "debug": "^4.4.3" }, "engines": { @@ -3253,14 +3626,12 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.1.tgz", - "integrity": "sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==", + "version": "8.57.2", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1" + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3271,9 +3642,7 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.1.tgz", - "integrity": "sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==", + "version": "8.57.2", "dev": true, "license": "MIT", "engines": { @@ -3288,15 +3657,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.1.tgz", - "integrity": "sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==", + "version": "8.57.2", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1", - "@typescript-eslint/utils": "8.57.1", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/utils": "8.57.2", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -3313,9 +3680,7 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.1.tgz", - "integrity": "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==", + "version": "8.57.2", "dev": true, "license": "MIT", "engines": { @@ -3327,16 +3692,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.1.tgz", - "integrity": "sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==", + "version": "8.57.2", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.57.1", - "@typescript-eslint/tsconfig-utils": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", + "@typescript-eslint/project-service": "8.57.2", + "@typescript-eslint/tsconfig-utils": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -3355,16 +3718,14 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.1.tgz", - "integrity": "sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==", + "version": "8.57.2", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1" + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3379,13 +3740,11 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.1.tgz", - "integrity": "sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==", + "version": "8.57.2", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/types": "8.57.2", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -3398,8 +3757,6 @@ }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -3411,8 +3768,6 @@ }, "node_modules/@vitest/coverage-v8": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.0.tgz", - "integrity": "sha512-nDWulKeik2bL2Va/Wl4x7DLuTKAXa906iRFooIRPR+huHkcvp9QDkPQ2RJdmjOFrqOqvNfoSQLF68deE3xC3CQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3442,274 +3797,648 @@ }, "node_modules/@vitest/coverage-v8/node_modules/@bcoe/v8-coverage": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", - "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", "dev": true, "license": "MIT", "engines": { "node": ">=18" } }, - "node_modules/@vitest/expect": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.0.tgz", - "integrity": "sha512-EIxG7k4wlWweuCLG9Y5InKFwpMEOyrMb6ZJ1ihYu02LVj/bzUwn2VMU+13PinsjRW75XnITeFrQBMH5+dLvCDA==", - "dev": true, + "node_modules/@vitest/expect": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.0", + "@vitest/utils": "4.1.0", + "chai": "^6.2.2", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.0", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.0", + "@vitest/utils": "4.1.0", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.0", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.18.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/apim-spec": { + "resolved": "packages/specification", + "link": true + }, + "node_modules/arg": { + "version": "4.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-v8-to-istanbul": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.31", + "estree-walker": "^3.0.3", + "js-tokens": "^10.0.0" + } + }, + "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": { + "version": "10.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "license": "MIT" + }, + "node_modules/aws-cdk": { + "version": "2.1113.0", + "license": "Apache-2.0", + "bin": { + "cdk": "bin/cdk" + }, + "engines": { + "node": ">= 18.0.0" + } + }, + "node_modules/aws-cdk-lib": { + "version": "2.244.0", + "bundleDependencies": [ + "@balena/dockerignore", + "@aws-cdk/cloud-assembly-api", + "case", + "fs-extra", + "ignore", + "jsonschema", + "minimatch", + "punycode", + "semver", + "table", + "yaml", + "mime-types" + ], + "license": "Apache-2.0", + "dependencies": { + "@aws-cdk/asset-awscli-v1": "2.2.263", + "@aws-cdk/asset-node-proxy-agent-v6": "^2.1.1", + "@aws-cdk/cloud-assembly-api": "^2.1.1", + "@aws-cdk/cloud-assembly-schema": "^52.1.0", + "@balena/dockerignore": "^1.0.2", + "case": "1.6.3", + "fs-extra": "^11.3.3", + "ignore": "^5.3.2", + "jsonschema": "^1.5.0", + "mime-types": "^2.1.35", + "minimatch": "^10.2.3", + "punycode": "^2.3.1", + "semver": "^7.7.4", + "table": "^6.9.0", + "yaml": "1.10.2" + }, + "engines": { + "node": ">= 20.0.0" + }, + "peerDependencies": { + "constructs": "^10.5.0" + } + }, + "node_modules/aws-cdk-lib/node_modules/@aws-cdk/cloud-assembly-api": { + "version": "2.1.1", + "bundleDependencies": [ + "jsonschema", + "semver" + ], + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "jsonschema": "~1.4.1", + "semver": "^7.7.3" + }, + "engines": { + "node": ">= 18.0.0" + }, + "peerDependencies": { + "@aws-cdk/cloud-assembly-schema": ">=52.1.0" + } + }, + "node_modules/aws-cdk-lib/node_modules/@aws-cdk/cloud-assembly-api/node_modules/jsonschema": { + "version": "1.4.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/aws-cdk-lib/node_modules/@aws-cdk/cloud-assembly-api/node_modules/semver": { + "version": "7.7.3", + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/aws-cdk-lib/node_modules/@balena/dockerignore": { + "version": "1.0.2", + "inBundle": true, + "license": "Apache-2.0" + }, + "node_modules/aws-cdk-lib/node_modules/ajv": { + "version": "8.18.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/aws-cdk-lib/node_modules/ansi-regex": { + "version": "5.0.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/aws-cdk-lib/node_modules/ansi-styles": { + "version": "4.3.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/aws-cdk-lib/node_modules/astral-regex": { + "version": "2.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/aws-cdk-lib/node_modules/balanced-match": { + "version": "4.0.4", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/aws-cdk-lib/node_modules/brace-expansion": { + "version": "5.0.3", + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/aws-cdk-lib/node_modules/case": { + "version": "1.6.3", + "inBundle": true, + "license": "(MIT OR GPL-3.0-or-later)", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/aws-cdk-lib/node_modules/color-convert": { + "version": "2.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/aws-cdk-lib/node_modules/color-name": { + "version": "1.1.4", + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/emoji-regex": { + "version": "8.0.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/fast-deep-equal": { + "version": "3.1.3", + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/fast-uri": { + "version": "3.1.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "inBundle": true, + "license": "BSD-3-Clause" + }, + "node_modules/aws-cdk-lib/node_modules/fs-extra": { + "version": "11.3.3", + "inBundle": true, "license": "MIT", "dependencies": { - "@standard-schema/spec": "^1.1.0", - "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.0", - "@vitest/utils": "4.1.0", - "chai": "^6.2.2", - "tinyrainbow": "^3.0.3" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=14.14" } }, - "node_modules/@vitest/pretty-format": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.0.tgz", - "integrity": "sha512-3RZLZlh88Ib0J7NQTRATfc/3ZPOnSUn2uDBUoGNn5T36+bALixmzphN26OUD3LRXWkJu4H0s5vvUeqBiw+kS0A==", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/graceful-fs": { + "version": "4.2.11", + "inBundle": true, + "license": "ISC" + }, + "node_modules/aws-cdk-lib/node_modules/ignore": { + "version": "5.3.2", + "inBundle": true, "license": "MIT", - "dependencies": { - "tinyrainbow": "^3.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">= 4" } }, - "node_modules/@vitest/runner": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.0.tgz", - "integrity": "sha512-Duvx2OzQ7d6OjchL+trw+aSrb9idh7pnNfxrklo14p3zmNL4qPCDeIJAK+eBKYjkIwG96Bc6vYuxhqDXQOWpoQ==", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "inBundle": true, "license": "MIT", - "dependencies": { - "@vitest/utils": "4.1.0", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=8" } }, - "node_modules/@vitest/snapshot": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.0.tgz", - "integrity": "sha512-0Vy9euT1kgsnj1CHttwi9i9o+4rRLEaPRSOJ5gyv579GJkNpgJK+B4HSv/rAWixx2wdAFci1X4CEPjiu2bXIMg==", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/json-schema-traverse": { + "version": "1.0.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/jsonfile": { + "version": "6.2.0", + "inBundle": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.0", - "@vitest/utils": "4.1.0", - "magic-string": "^0.30.21", - "pathe": "^2.0.3" + "universalify": "^2.0.0" }, - "funding": { - "url": "https://opencollective.com/vitest" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/@vitest/spy": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.0.tgz", - "integrity": "sha512-pz77k+PgNpyMDv2FV6qmk5ZVau6c3R8HC8v342T2xlFxQKTrSeYw9waIJG8KgV9fFwAtTu4ceRzMivPTH6wSxw==", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/jsonschema": { + "version": "1.5.0", + "inBundle": true, "license": "MIT", - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": "*" } }, - "node_modules/@vitest/utils": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.0.tgz", - "integrity": "sha512-XfPXT6a8TZY3dcGY8EdwsBulFCIw+BeeX0RZn2x/BtiY/75YGh8FeWGG8QISN/WhaqSrE2OrlDgtF8q5uhOTmw==", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/lodash.truncate": { + "version": "4.4.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/mime-db": { + "version": "1.52.0", + "inBundle": true, "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "4.1.0", - "convert-source-map": "^2.0.0", - "tinyrainbow": "^3.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">= 0.6" } }, - "node_modules/abort-controller": { - "version": "3.0.0", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/mime-types": { + "version": "2.1.35", + "inBundle": true, "license": "MIT", "dependencies": { - "event-target-shim": "^5.0.0" + "mime-db": "1.52.0" }, "engines": { - "node": ">=6.5" + "node": ">= 0.6" } }, - "node_modules/acorn": { - "version": "8.16.0", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" + "node_modules/aws-cdk-lib/node_modules/minimatch": { + "version": "10.2.4", + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=0.4.0" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/punycode": { + "version": "2.3.1", + "inBundle": true, "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "engines": { + "node": ">=6" } }, - "node_modules/acorn-walk": { - "version": "8.3.4", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/require-from-string": { + "version": "2.0.2", + "inBundle": true, "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, "engines": { - "node": ">=0.4.0" + "node": ">=0.10.0" } }, - "node_modules/agent-base": { - "version": "7.1.4", - "dev": true, - "license": "MIT", + "node_modules/aws-cdk-lib/node_modules/semver": { + "version": "7.7.4", + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">= 14" + "node": ">=10" } }, - "node_modules/ajv": { - "version": "6.14.0", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/slice-ansi": { + "version": "4.0.0", + "inBundle": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/string-width": { + "version": "4.2.3", + "inBundle": true, "license": "MIT", "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "engines": { + "node": ">=8" } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/strip-ansi": { + "version": "6.0.1", + "inBundle": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "ansi-regex": "^5.0.1" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": ">=8" } }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "license": "MIT", + "node_modules/aws-cdk-lib/node_modules/table": { + "version": "6.9.0", + "inBundle": true, + "license": "BSD-3-Clause", "dependencies": { - "color-convert": "^2.0.1" + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=10.0.0" } }, - "node_modules/apim-spec": { - "resolved": "packages/specification", - "link": true - }, - "node_modules/arg": { - "version": "4.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/assertion-error": { + "node_modules/aws-cdk-lib/node_modules/universalify": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, + "inBundle": true, "license": "MIT", "engines": { - "node": ">=12" + "node": ">= 10.0.0" } }, - "node_modules/ast-v8-to-istanbul": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.0.tgz", - "integrity": "sha512-1fSfIwuDICFA4LKkCzRPO7F0hzFf0B7+Xqrl27ynQaa+Rh0e1Es0v6kWHPott3lU10AyAr7oKHa65OppjLn3Rg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.31", - "estree-walker": "^3.0.3", - "js-tokens": "^10.0.0" + "node_modules/aws-cdk-lib/node_modules/yaml": { + "version": "1.10.2", + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">= 6" } }, - "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", - "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "license": "MIT" - }, "node_modules/axios": { "version": "1.13.6", "license": "MIT", + "peer": true, "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", @@ -3745,8 +4474,6 @@ }, "node_modules/better-ajv-errors": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/better-ajv-errors/-/better-ajv-errors-1.2.0.tgz", - "integrity": "sha512-UW+IsFycygIo7bclP9h5ugkNH8EjCSgqyFB/yQ4Hqqa1OEYDtb0uFIkYE0b6+CjkgJYVM5UKI/pJPxjYe9EZlA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3803,10 +4530,20 @@ "resolved": "packages/capabilityStatement", "link": true }, + "node_modules/cdk": { + "resolved": "packages/cdk", + "link": true + }, + "node_modules/cdk-nag": { + "version": "2.37.55", + "license": "Apache-2.0", + "peerDependencies": { + "aws-cdk-lib": "^2.176.0", + "constructs": "^10.0.5" + } + }, "node_modules/chai": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", - "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", "dev": true, "license": "MIT", "engines": { @@ -3815,8 +4552,6 @@ }, "node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", "dependencies": { @@ -3940,10 +4675,13 @@ "node": ">= 0.8" } }, + "node_modules/constructs": { + "version": "10.5.1", + "license": "Apache-2.0", + "peer": true + }, "node_modules/convert-source-map": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, "license": "MIT" }, @@ -4041,8 +4779,6 @@ }, "node_modules/detect-libc": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -4108,8 +4844,6 @@ }, "node_modules/es-module-lexer": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", - "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", "dev": true, "license": "MIT" }, @@ -4143,8 +4877,6 @@ }, "node_modules/esbuild": { "version": "0.27.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.4.tgz", - "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==", "hasInstallScript": true, "license": "MIT", "bin": { @@ -4203,10 +4935,9 @@ }, "node_modules/eslint": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.1.0.tgz", - "integrity": "sha512-S9jlY/ELKEUwwQnqWDO+f+m6sercqOPSqXM5Go94l7DOmxHVDgmSFGWEzeE/gwgTAr0W103BWt0QLe/7mabIvA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", @@ -4273,8 +5004,6 @@ }, "node_modules/eslint-scope": { "version": "9.1.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", - "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -4322,8 +5051,6 @@ }, "node_modules/espree": { "version": "11.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", - "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -4340,8 +5067,6 @@ }, "node_modules/espree/node_modules/eslint-visitor-keys": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -4364,8 +5089,6 @@ }, "node_modules/esrecurse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -4385,8 +5108,6 @@ }, "node_modules/estree-walker": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, "license": "MIT", "dependencies": { @@ -4416,8 +5137,6 @@ }, "node_modules/expect-type": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -4461,8 +5180,6 @@ }, "node_modules/fast-xml-builder": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz", - "integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==", "funding": [ { "type": "github", @@ -4476,8 +5193,6 @@ }, "node_modules/fast-xml-parser": { "version": "5.5.8", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.8.tgz", - "integrity": "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ==", "funding": [ { "type": "github", @@ -4533,9 +5248,7 @@ } }, "node_modules/flatted": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", - "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "version": "3.3.3", "dev": true, "license": "ISC" }, @@ -4580,7 +5293,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -4641,7 +5353,6 @@ }, "node_modules/get-tsconfig": { "version": "4.13.0", - "dev": true, "license": "MIT", "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -4902,8 +5613,6 @@ }, "node_modules/js-yaml": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { @@ -4928,8 +5637,6 @@ }, "node_modules/json-schema-to-ts": { "version": "2.7.2", - "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-2.7.2.tgz", - "integrity": "sha512-R1JfqKqbBR4qE8UyBR56Ms30LL62/nlhoz+1UkfI/VE7p54Awu919FZ6ZUPG8zIa3XB65usPJgr1ONVncUGSaQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4953,8 +5660,6 @@ }, "node_modules/jsonpath-rfc9535": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsonpath-rfc9535/-/jsonpath-rfc9535-1.3.0.tgz", - "integrity": "sha512-3jFHya7oZ45aDxIIdx+/zQARahHXxFSMWBkcBUldfXpLS9VCXDJyTKt35kQfEXLqh0K3Ixw/9xFnvcDStaxh7Q==", "dev": true, "license": "Apache-2.0", "engines": { @@ -4963,8 +5668,6 @@ }, "node_modules/jsonpointer": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", "dev": true, "license": "MIT", "engines": { @@ -4981,8 +5684,6 @@ }, "node_modules/leven": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, "license": "MIT", "engines": { @@ -5003,8 +5704,6 @@ }, "node_modules/lightningcss": { "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", - "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", "dev": true, "license": "MPL-2.0", "dependencies": { @@ -5180,8 +5879,6 @@ }, "node_modules/lightningcss-linux-x64-gnu": { "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", - "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", "cpu": [ "x64" ], @@ -5201,8 +5898,6 @@ }, "node_modules/lightningcss-linux-x64-musl": { "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", - "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", "cpu": [ "x64" ], @@ -5299,8 +5994,6 @@ }, "node_modules/magic-string": { "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5309,8 +6002,6 @@ }, "node_modules/magicast": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.2.tgz", - "integrity": "sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5380,8 +6071,6 @@ }, "node_modules/minimatch": { "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -5396,8 +6085,6 @@ }, "node_modules/minimatch/node_modules/balanced-match": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, "license": "MIT", "engines": { @@ -5406,8 +6093,6 @@ }, "node_modules/minimatch/node_modules/brace-expansion": { "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "dev": true, "license": "MIT", "dependencies": { @@ -5437,6 +6122,7 @@ "version": "6.15.0", "dev": true, "license": "MIT", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/mobx" @@ -5653,8 +6339,6 @@ }, "node_modules/obug": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", - "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", "dev": true, "funding": [ "https://github.com/sponsors/sxzz", @@ -5690,8 +6374,6 @@ }, "node_modules/outdent": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.8.0.tgz", - "integrity": "sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A==", "dev": true, "license": "MIT" }, @@ -5738,8 +6420,6 @@ }, "node_modules/path-expression-matcher": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.2.0.tgz", - "integrity": "sha512-DwmPWeFn+tq7TiyJ2CxezCAirXjFxvaiD03npak3cRjlP9+OjTmSy1EpIrEbh+l6JgUundniloMLDQ/6VTdhLQ==", "funding": [ { "type": "github", @@ -5761,8 +6441,6 @@ }, "node_modules/pathe": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true, "license": "MIT" }, @@ -5777,9 +6455,7 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.3", "dev": true, "license": "MIT", "engines": { @@ -5937,6 +6613,7 @@ "version": "19.2.1", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -5945,6 +6622,7 @@ "version": "19.2.1", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -6078,7 +6756,6 @@ }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" @@ -6086,8 +6763,6 @@ }, "node_modules/rolldown": { "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.9.tgz", - "integrity": "sha512-9EbgWge7ZH+yqb4d2EnELAntgPTWbfL8ajiTW+SyhJEC4qhBbkCKbqFV4Ge4zmu5ziQuVbWxb/XwLZ+RIO7E8Q==", "dev": true, "license": "MIT", "dependencies": { @@ -6232,8 +6907,6 @@ }, "node_modules/siginfo": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, "license": "ISC" }, @@ -6289,8 +6962,6 @@ }, "node_modules/stackback": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true, "license": "MIT" }, @@ -6300,8 +6971,6 @@ }, "node_modules/std-env": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.0.0.tgz", - "integrity": "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==", "dev": true, "license": "MIT" }, @@ -6318,9 +6987,7 @@ } }, "node_modules/strnum": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.1.tgz", - "integrity": "sha512-BwRvNd5/QoAtyW1na1y1LsJGQNvRlkde6Q/ipqqEaivoMdV+B1OMOTVdwR+N/cwVUcIt9PYyHmV8HyexCZSupg==", + "version": "2.2.2", "funding": [ { "type": "github", @@ -6333,6 +7000,7 @@ "version": "6.3.9", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@emotion/is-prop-valid": "1.4.0", "@emotion/unitless": "0.10.0", @@ -6405,15 +7073,11 @@ }, "node_modules/tinybench": { "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true, "license": "MIT" }, "node_modules/tinyexec": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", - "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", "dev": true, "license": "MIT", "engines": { @@ -6453,8 +7117,6 @@ }, "node_modules/tinyrainbow": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", - "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", "dev": true, "license": "MIT", "engines": { @@ -6468,13 +7130,11 @@ }, "node_modules/ts-algebra": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-1.2.2.tgz", - "integrity": "sha512-kloPhf1hq3JbCPOTYoOWDKxebWjNb2o/LKnNfkWhxVVisFFmMJPPdJeGoGmM+iRLyoXAR61e08Pb+vUXINg8aA==", "dev": true, "license": "MIT" }, "node_modules/ts-api-utils": { - "version": "2.4.0", + "version": "2.5.0", "dev": true, "license": "MIT", "engines": { @@ -6532,7 +7192,6 @@ }, "node_modules/tsx": { "version": "4.21.0", - "dev": true, "license": "MIT", "dependencies": { "esbuild": "~0.27.0", @@ -6563,6 +7222,7 @@ "version": "5.9.3", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -6593,8 +7253,6 @@ }, "node_modules/undici": { "version": "6.24.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.24.0.tgz", - "integrity": "sha512-lVLNosgqo5EkGqh5XUDhGfsMSoO8K0BAN0TyJLvwNRSl4xWGZlCVYsAIpa/OpA3TvmnM01GWcoKmc3ZWo5wKKA==", "dev": true, "license": "MIT", "engines": { @@ -6643,10 +7301,9 @@ }, "node_modules/vitest": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.0.tgz", - "integrity": "sha512-YbDrMF9jM2Lqc++2530UourxZHmkKLxrs4+mYhEwqWS97WJ7wOYEkcr+QfRgJ3PW9wz3odRijLZjHEaRLTNbqw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@vitest/expect": "4.1.0", "@vitest/mocker": "4.1.0", @@ -6725,8 +7382,6 @@ }, "node_modules/vitest/node_modules/@vitest/mocker": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.0.tgz", - "integrity": "sha512-evxREh+Hork43+Y4IOhTo+h5lGmVRyjqI739Rz4RlUPqwrkFFDF6EMvOOYjTx4E8Tl6gyCLRL8Mu7Ry12a13Tw==", "dev": true, "license": "MIT", "dependencies": { @@ -6752,8 +7407,6 @@ }, "node_modules/vitest/node_modules/postcss": { "version": "8.5.8", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", - "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", "dev": true, "funding": [ { @@ -6781,10 +7434,9 @@ }, "node_modules/vitest/node_modules/vite": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.0.tgz", - "integrity": "sha512-fPGaRNj9Zytaf8LEiBhY7Z6ijnFKdzU/+mL8EFBaKr7Vw1/FWcTBAMW0wLPJAGMPX38ZPVCVgLceWiEqeoqL2Q==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@oxc-project/runtime": "0.115.0", "lightningcss": "^1.32.0", @@ -6888,8 +7540,6 @@ }, "node_modules/why-is-node-running": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, "license": "MIT", "dependencies": { @@ -7052,6 +7702,17 @@ "@pfp-common/testing": "^1.0.0" } }, + "packages/cdk": { + "version": "0.1.0", + "dependencies": { + "@nhsdigital/eps-cdk-constructs": "file:../../nhsdigital-eps-cdk-constructs-1.6.0.tgz", + "aws-cdk": "^2.1106.0", + "aws-cdk-lib": "^2.239.0", + "cdk-nag": "^2.37.55", + "constructs": "^10.4.5", + "tsx": "^4.21.0" + } + }, "packages/common/testing": { "name": "@pfp-common/testing", "version": "1.0.0", diff --git a/package.json b/package.json index 9b9fbac7c..bc3a747bc 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "author": "NHS Digital", "license": "MIT", "workspaces": [ + "packages/cdk", "packages/capabilityStatement", "packages/getMyPrescriptions", "packages/enrichPrescriptions", diff --git a/packages/cdk/bin/PfPApiApp.ts b/packages/cdk/bin/PfPApiApp.ts new file mode 100644 index 000000000..51d06e764 --- /dev/null +++ b/packages/cdk/bin/PfPApiApp.ts @@ -0,0 +1,57 @@ +import { + calculateVersionedStackName, + createApp, + getBooleanConfigFromEnvVar, + getConfigFromEnvVar, + getNumberConfigFromEnvVar +} from "@nhsdigital/eps-cdk-constructs" +import {buildParametersReadPolicyExportName, PfPApiStatefulStack} from "../stacks/PfPApiStatefulStack" +import {PfPApiStatelessStack} from "../stacks/PfPApiStatelessStack" + +const defaultTestNhsNumber = "9992387920" + +function main() { + const {app, props} = createApp({ + productName: "Prescriptions for Patients API", + appName: "PfPApiApp", + repoName: "prescriptionsforpatients", + driftDetectionGroup: "pfp-api" + }) + + const stackName = calculateVersionedStackName(getConfigFromEnvVar("stackName"), props) + + const statefulStack = new PfPApiStatefulStack(app, "PfPApiStatefulStack", { + ...props, + stackName, + tc007NhsNumberValue: getConfigFromEnvVar("tc007NhsNumberValue", "CDK_CONFIG_", defaultTestNhsNumber), + tc008NhsNumberValue: getConfigFromEnvVar("tc008NhsNumberValue", "CDK_CONFIG_", defaultTestNhsNumber), + tc009NhsNumberValue: getConfigFromEnvVar("tc009NhsNumberValue", "CDK_CONFIG_", defaultTestNhsNumber) + }) + + const statelessStack = new PfPApiStatelessStack(app, "PfPApiStatelessStack", { + ...props, + stackName, + logRetentionInDays: getNumberConfigFromEnvVar("logRetentionInDays"), + logLevel: getConfigFromEnvVar("logLevel"), + targetSpineServer: getConfigFromEnvVar("targetSpineServer"), + targetServiceSearchServer: getConfigFromEnvVar("targetServiceSearchServer"), + toggleGetStatusUpdates: getConfigFromEnvVar("toggleGetStatusUpdates"), + allowNhsNumberOverride: getConfigFromEnvVar("allowNhsNumberOverride"), + mutualTlsTrustStoreKey: props.isPullRequest ? undefined : getConfigFromEnvVar("trustStoreFile"), + // CSOC API GW log destination - do not change + csocApiGatewayDestination: "arn:aws:logs:eu-west-2:693466633220:destination:api_gateway_log_destination", + forwardCsocLogs: getBooleanConfigFromEnvVar("forwardCsocLogs"), + parametersReadPolicyExportName: buildParametersReadPolicyExportName(stackName) + }) + + statelessStack.addDependency(statefulStack) + + return statelessStack +} + +try { + main() +} catch (error) { + console.error(error) + process.exit(1) +} diff --git a/packages/cdk/bin/PfPApiSandboxApp.ts b/packages/cdk/bin/PfPApiSandboxApp.ts new file mode 100644 index 000000000..e3ebe54c4 --- /dev/null +++ b/packages/cdk/bin/PfPApiSandboxApp.ts @@ -0,0 +1,11 @@ +import {createApp} from "@nhsdigital/eps-cdk-constructs" +import {PfPApiSandboxStack} from "../stacks/PfPApiSandboxStack" + +const {app, props} = createApp({ + productName: "Prescriptions for Patients API", + appName: "PfPApiSandboxApp", + repoName: "prescriptionsforpatients", + driftDetectionGroup: "pfp-api" +}) + +new PfPApiSandboxStack(app, "PfPApiSandboxStack", props) diff --git a/packages/cdk/cdk.json b/packages/cdk/cdk.json new file mode 100644 index 000000000..4ff6fefe1 --- /dev/null +++ b/packages/cdk/cdk.json @@ -0,0 +1,76 @@ +{ + "watch": { + "include": [ + "packages/**" + ], + "exclude": [ + "**/README.md", + "**/cdk*.json", + "**/*.d.ts", + "**/*.js", + "**/tsconfig.json", + "**/package*.json", + "**/yarn.lock", + "**/node_modules", + "**/tests*", + "**/lib", + "**/coverage", + "**/jest.config.ts", + "**/jest.debug.config.ts" + ] + }, + "context": { + "@aws-cdk/aws-lambda:recognizeLayerVersion": true, + "@aws-cdk/core:checkSecretUsage": true, + "@aws-cdk/core:target-partitions": [ + "aws", + "aws-cn" + ], + "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, + "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, + "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, + "@aws-cdk/aws-iam:minimizePolicies": true, + "@aws-cdk/core:validateSnapshotRemovalPolicy": true, + "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, + "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, + "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, + "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, + "@aws-cdk/core:enablePartitionLiterals": true, + "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, + "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, + "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, + "@aws-cdk/aws-route53-patterns:useCertificate": true, + "@aws-cdk/customresources:installLatestAwsSdkDefault": false, + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, + "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, + "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, + "@aws-cdk/aws-redshift:columnId": true, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, + "@aws-cdk/aws-kms:aliasNameRef": true, + "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, + "@aws-cdk/core:includePrefixInUniqueNameGeneration": true, + "@aws-cdk/aws-efs:denyAnonymousAccess": true, + "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true, + "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true, + "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true, + "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true, + "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true, + "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true, + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true, + "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true, + "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true, + "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true, + "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true, + "@aws-cdk/aws-eks:nodegroupNameAttribute": true, + "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true, + "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true, + "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false, + "@aws-cdk/aws-s3:keepNotificationInImportedBucket": false, + "acknowledged-issue-numbers": [34892] + } +} diff --git a/packages/cdk/nagSuppressions.ts b/packages/cdk/nagSuppressions.ts new file mode 100644 index 000000000..1c1e55bb8 --- /dev/null +++ b/packages/cdk/nagSuppressions.ts @@ -0,0 +1,51 @@ +/* eslint-disable max-len */ +import {Stack} from "aws-cdk-lib" +import {safeAddNagSuppressionGroup, safeAddNagSuppression} from "@nhsdigital/eps-cdk-constructs" + +export const nagSuppressions = (stack: Stack) => { + safeAddNagSuppressionGroup( + stack, + [ + "/PfPApiStatelessStack/Functions/GetMyPrescriptionsLambda/LambdaPutLogsManagedPolicy/Resource", + "/PfPApiStatelessStack/Functions/EnrichPrescriptionsLambda/LambdaPutLogsManagedPolicy/Resource", + "/PfPApiStatelessStack/Functions/StatusLambda/LambdaPutLogsManagedPolicy/Resource", + "/PfPApiStatelessStack/StateMachines/GetMyPrescriptionsStateMachine/StateMachinePutLogsManagedPolicy/Resource" + ], + [ + { + id: "AwsSolutions-IAM5", + reason: "Suppress error for not having wildcards in permissions. This is a fine as we need to have permissions on all log streams under path" + } + ] + ) + + safeAddNagSuppression( + stack, + "/PfPApiStatelessStack/Apis/ApiGateway/ApiGateway/Resource", + [ + { + id: "AwsSolutions-APIG2", + reason: "Suppress error for request validation not being enabled. Validation will be handled by the service logic." + } + ] + ) + + safeAddNagSuppressionGroup( + stack, + [ + "/PfPApiStatelessStack/Apis/ApiGateway/ApiGateway/Default/Bundle/GET/Resource", + "/PfPApiStatelessStack/Apis/ApiGateway/ApiGateway/Default/_status/GET/Resource" + ], + [ + { + id: "AwsSolutions-APIG4", + reason: "Suppress error for not implementing authorization. Token endpoint should not have an authorizer" + }, + { + id: "AwsSolutions-COG4", + reason: "Suppress error for not implementing a Cognito user pool authorizer. Token endpoint should not have an authorizer" + } + ] + ) + +} diff --git a/packages/cdk/package.json b/packages/cdk/package.json new file mode 100644 index 000000000..35fd4d867 --- /dev/null +++ b/packages/cdk/package.json @@ -0,0 +1,23 @@ +{ + "name": "cdk", + "version": "0.1.0", + "scripts": { + "cdk-synth": "cdk synth --output ../../cdk.out --quiet --app \"npm run tsx -- bin/${CDK_APP_NAME}.ts\"", + "cdk-diff": "cdk diff --app \"npm run tsx -- bin/${CDK_APP_NAME}.ts\"", + "cdk-deploy": "cdk deploy --app \"npm run tsx -- bin/${CDK_APP_NAME}.ts\" --all --ci true --require-approval ${REQUIRE_APPROVAL}", + "cdk-watch": "cdk deploy --app \"npm run tsx -- bin/${CDK_APP_NAME}.ts\" --watch --all --ci true --require-approval ${REQUIRE_APPROVAL}", + "delete-main-stacks": "npm run tsx -- scripts/deleteMainStacks.ts", + "delete-old-pr-stacks": "npm run tsx -- scripts/deletePrStacks.ts", + "lint": "eslint --max-warnings 0 --fix --config ../../eslint.config.mjs .", + "test": "vitest run --coverage", + "tsx": "tsx" + }, + "dependencies": { + "@nhsdigital/eps-cdk-constructs": "file:../../nhsdigital-eps-cdk-constructs-1.6.0.tgz", + "aws-cdk": "^2.1106.0", + "aws-cdk-lib": "^2.239.0", + "cdk-nag": "^2.37.55", + "constructs": "^10.4.5", + "tsx": "^4.21.0" + } +} diff --git a/packages/cdk/resources/Apis.ts b/packages/cdk/resources/Apis.ts new file mode 100644 index 000000000..b3bd30c2a --- /dev/null +++ b/packages/cdk/resources/Apis.ts @@ -0,0 +1,65 @@ +import {HttpMethod} from "aws-cdk-lib/aws-lambda" +import { + ExpressStateMachine, + LambdaEndpoint, + RestApiGateway, + TypescriptLambdaFunction +} from "@nhsdigital/eps-cdk-constructs" +import {StateMachineEndpoint} from "@nhsdigital/eps-cdk-constructs/lib/src/constructs/RestApiGateway/StateMachineEndpoint.js" +import {Construct} from "constructs" + +export interface ApisProps { + readonly stackName: string + readonly logRetentionInDays: number + readonly mutualTlsTrustStoreKey: string | undefined + functions: {[key: string]: TypescriptLambdaFunction} + stateMachines: {[key: string]: ExpressStateMachine} + readonly forwardCsocLogs: boolean + readonly csocApiGatewayDestination: string +} + +export class Apis extends Construct { + apis: {[key: string]: RestApiGateway} + endpoints: {[key: string]: Construct} + + public constructor(scope: Construct, id: string, props: ApisProps) { + super(scope, id) + + const apiGateway = new RestApiGateway(this, "ApiGateway", { + stackName: props.stackName, + logRetentionInDays: props.logRetentionInDays, + mutualTlsTrustStoreKey: props.mutualTlsTrustStoreKey, + forwardCsocLogs: props.forwardCsocLogs, + csocApiGatewayDestination: props.csocApiGatewayDestination, + executionPolicies: [ + props.stateMachines.getMyPrescriptions.executionPolicy, + props.functions.status.executionPolicy + ] + }) + const rootResource = apiGateway.api.root + + const getMyPrescriptionsEndpoint = new StateMachineEndpoint(this, "GetMyPrescriptionsEndpoint", { + parentResource: rootResource, + resourceName: "Bundle", + method: HttpMethod.GET, + restApiGatewayRole: apiGateway.role, + stateMachine: props.stateMachines.getMyPrescriptions + }) + + const statusEndpoint = new LambdaEndpoint(this, "StatusEndpoint", { + parentResource: rootResource, + resourceName: "_status", + method: HttpMethod.GET, + restApiGatewayRole: apiGateway.role, + lambdaFunction: props.functions.status + }) + + this.apis = { + api: apiGateway + } + this.endpoints = { + getMyPrescriptions: getMyPrescriptionsEndpoint, + status: statusEndpoint + } + } +} diff --git a/packages/cdk/resources/Functions.ts b/packages/cdk/resources/Functions.ts new file mode 100644 index 000000000..4c343ffb3 --- /dev/null +++ b/packages/cdk/resources/Functions.ts @@ -0,0 +1,123 @@ +import {Fn, RemovalPolicy} from "aws-cdk-lib" +import {IManagedPolicy, ManagedPolicy} from "aws-cdk-lib/aws-iam" +import {Construct} from "constructs" +import {TypescriptLambdaFunction} from "@nhsdigital/eps-cdk-constructs" +import {Code, LayerVersion} from "aws-cdk-lib/aws-lambda" +import {join, resolve} from "node:path" + +export interface FunctionsProps { + readonly stackName: string + readonly version: string + readonly commitId: string + readonly deploymentEnvironment: string + readonly targetSpineServer: string + readonly targetServiceSearchServer: string + readonly toggleGetStatusUpdates: string + readonly allowNhsNumberOverride: string + readonly logRetentionInDays: number + readonly logLevel: string + readonly getPfPParametersPolicy: IManagedPolicy +} + +const baseDir = resolve(__dirname, "../../..") + +export class Functions extends Construct { + functions: {[key: string]: TypescriptLambdaFunction} + + public constructor(scope: Construct, id: string, props: FunctionsProps) { + super(scope, id) + + // Imports + const lambdaAccessSecretsPolicy = ManagedPolicy.fromManagedPolicyArn( + this, "lambdaAccessSecretsPolicy", Fn.importValue("account-resources:LambdaAccessSecretsPolicy")) + + const lambdaDecryptSecretsKMSPolicy = ManagedPolicy.fromManagedPolicyArn( + this, "lambdaDecryptSecretsKMSPolicy", Fn.importValue("account-resources:LambdaDecryptSecretsKMSPolicy")) + + const lambdaDefaultEnvironmentVariables: {[key: string]: string} = { + STACK_NAME: props.stackName, + TargetSpineServer: props.targetSpineServer, + TargetServiceSearchServer: props.targetServiceSearchServer, + SpinePrivateKeyARN: Fn.importValue("account-resources:SpinePrivateKey"), + SpinePublicCertificateARN: Fn.importValue("account-resources:SpinePublicCertificate"), + SpineASIDARN: Fn.importValue("account-resources:SpineASID"), + SpinePartyKeyARN: Fn.importValue("account-resources:SpinePartyKey"), + SpineCAChainARN: Fn.importValue("account-resources:SpineCAChain"), + ServiceSearch3ApiKeyARN: Fn.importValue("pfp-PfP-ServiceSearch-API-Key") + } + + const getSecretsLambdaLayer = new LayerVersion(this, "GetSecretsLambdaLayer", { + description: "get secrets layer", + // TODO: This should not rely on an asset + code: Code.fromAsset(join(baseDir, "packages/getSecretLayer/lib/get-secrets-layer.zip")), + removalPolicy: RemovalPolicy.RETAIN + }) + + // Resources + const getMyPrescriptionsLambda = new TypescriptLambdaFunction(this, "GetMyPrescriptionsLambda", { + functionName: `${props.stackName}-GetMyPrescriptions`, + projectBaseDir: baseDir, + packageBasePath: "packages/getMyPrescriptions", + entryPoint: "src/getMyPrescriptions.ts", + environmentVariables: { + ...lambdaDefaultEnvironmentVariables, + AWS_LAMBDA_EXEC_WRAPPER: "/opt/get-secrets-layer", + DEPLOYMENT_ENVIRONMENT: props.deploymentEnvironment, + GET_STATUS_UPDATES: props.toggleGetStatusUpdates, + ALLOW_NHS_NUMBER_OVERRIDE: props.allowNhsNumberOverride + }, + layers: [getSecretsLambdaLayer], + additionalPolicies: [ + lambdaAccessSecretsPolicy, + lambdaDecryptSecretsKMSPolicy, + props.getPfPParametersPolicy + ], + logRetentionInDays: props.logRetentionInDays, + logLevel: props.logLevel, + version: props.version, + commitId: props.commitId + }) + + const enrichPrescriptionsLambda = new TypescriptLambdaFunction(this, "EnrichPrescriptionsLambda", { + functionName: `${props.stackName}-EnrichPrescriptions`, + projectBaseDir: baseDir, + packageBasePath: "packages/enrichPrescriptions", + entryPoint: "src/enrichPrescriptions.ts", + environmentVariables: { + ...lambdaDefaultEnvironmentVariables, + DEPLOYMENT_ENVIRONMENT: props.deploymentEnvironment, + EXPECT_STATUS_UPDATES: props.toggleGetStatusUpdates + }, + additionalPolicies: [ + props.getPfPParametersPolicy + ], + logRetentionInDays: props.logRetentionInDays, + logLevel: props.logLevel, + version: props.version, + commitId: props.commitId + }) + + const statusLambda = new TypescriptLambdaFunction(this, "StatusLambda", { + functionName: `${props.stackName}-status`, + projectBaseDir: baseDir, + packageBasePath: "packages/statusLambda", + entryPoint: "src/statusLambda.ts", + environmentVariables: { + ...lambdaDefaultEnvironmentVariables, + AWS_LAMBDA_EXEC_WRAPPER: "/opt/get-secrets-layer" + }, + layers: [getSecretsLambdaLayer], + additionalPolicies: [lambdaAccessSecretsPolicy, lambdaDecryptSecretsKMSPolicy], + logRetentionInDays: props.logRetentionInDays, + logLevel: props.logLevel, + version: props.version, + commitId: props.commitId + }) + + this.functions = { + getMyPrescriptions: getMyPrescriptionsLambda, + enrichPrescriptions: enrichPrescriptionsLambda, + status: statusLambda + } + } +} diff --git a/packages/cdk/resources/Parameters.ts b/packages/cdk/resources/Parameters.ts new file mode 100644 index 000000000..c422030ae --- /dev/null +++ b/packages/cdk/resources/Parameters.ts @@ -0,0 +1,53 @@ +import {ManagedPolicy} from "aws-cdk-lib/aws-iam" +import {Construct} from "constructs" +import { + SsmParameterDefinition, + SsmParametersConstruct, + SsmParametersConstructProps +} from "@nhsdigital/eps-cdk-constructs" + +export interface ParametersProps { + readonly stackName: string + readonly tc007NhsNumberValue: string + readonly tc008NhsNumberValue: string + readonly tc009NhsNumberValue: string +} + +export class Parameters extends Construct { + public readonly readParametersPolicy: ManagedPolicy + + public constructor(scope: Construct, id: string, props: ParametersProps) { + super(scope, id) + + const parameterDefinitions: Array = [ + { + id: "TC007NHSNumberParameter", + nameSuffix: "TC007NHSNumber", + description: "List of NHS numbers that will trigger 'temporarily unavailable' response for testing purposes.", + value: props.tc007NhsNumberValue + }, + { + id: "TC008NHSNumberParameter", + nameSuffix: "TC008NHSNumber", + description: "List of NHS numbers that will trigger '500 system error' response for testing purposes.", + value: props.tc008NhsNumberValue + }, + { + id: "TC009NHSNumberParameter", + nameSuffix: "TC009NHSNumber", + description: + "List of NHS numbers that will trigger 'one or more prescriptions missing' response for testing purposes.", + value: props.tc009NhsNumberValue + } + ] + + const ssmParametersProps: SsmParametersConstructProps = { + namePrefix: props.stackName, + parameters: parameterDefinitions, + readPolicyDescription: "Allows reading SSM parameters" + } + + const ssmParameters = new SsmParametersConstruct(this, "PfPApiSsmParameters", ssmParametersProps) + this.readParametersPolicy = ssmParameters.readParametersPolicy + } +} diff --git a/packages/cdk/resources/StateMachineDefinitions/GetMyPrescriptions.ts b/packages/cdk/resources/StateMachineDefinitions/GetMyPrescriptions.ts new file mode 100644 index 000000000..a05953239 --- /dev/null +++ b/packages/cdk/resources/StateMachineDefinitions/GetMyPrescriptions.ts @@ -0,0 +1,70 @@ +import {IFunction} from "aws-cdk-lib/aws-lambda" +import { + Chain, + Choice, + Condition, + IChainable, + Pass, + TaskInput +} from "aws-cdk-lib/aws-stepfunctions" +import {LambdaInvoke} from "aws-cdk-lib/aws-stepfunctions-tasks" +import {CatchAllErrorPass} from "@nhsdigital/eps-cdk-constructs" +import {Construct} from "constructs" + +export interface DefinitionProps { + readonly getMyPrescriptionsFunction: IFunction + readonly enrichPrescriptionsFunction: IFunction + readonly getStatusUpdatesFunction: IFunction +} + +export class GetMyPrescriptions extends Construct { + public readonly definition: IChainable + + public constructor(scope: Construct, id: string, props: DefinitionProps){ + super(scope, id) + + const catchAllError = new CatchAllErrorPass(this, "Catch All Error") + + const getMyPrescriptions = LambdaInvoke.jsonata(this, "Get My Prescriptions", { + lambdaFunction: props.getMyPrescriptionsFunction, + payload: TaskInput.fromText("{% $states.input %}") + }) + getMyPrescriptions.addCatch(catchAllError.state) + + const failedGetMyPrescriptions = new Pass(this, "Failed Get My Prescriptions") + + const parseGetMyPrescriptionsBody = Pass.jsonata(this, "Parse Get My Prescriptions Body", { + outputs: "{% $parse($states.input.Payload.body) %}" + }) + + const enrichPrescriptions = LambdaInvoke.jsonata(this, "Enrich Prescriptions", { + lambdaFunction: props.enrichPrescriptionsFunction, + payload: TaskInput.fromText("{% $states.input %}") + }) + enrichPrescriptions.addCatch(catchAllError.state) + + const getStatusUpdates = LambdaInvoke.jsonata(this, "Get Status Updates", { + lambdaFunction: props.getStatusUpdatesFunction, + payload: TaskInput.fromText("{% $states.input.statusUpdateData %}"), + outputs: "{% $merge([$states.input, {'StatusUpdates': {'Payload': $states.result.Payload}}]) %}" + }) + getStatusUpdates.addCatch(enrichPrescriptions, { + outputs: "{% $merge([$states.input, {'error': $states.errorOutput}]) %}" + }) + + const checkGetMyPrescriptionsResult = Choice.jsonata(this, "Get My Prescriptions Result") + const evaluateToggleGetStatusUpdates = Choice.jsonata(this, "Evaluate Toggle Get Status Updates Parameter") + + this.definition = Chain + .start(getMyPrescriptions) + .next(checkGetMyPrescriptionsResult + .when(Condition.jsonata("{% $states.input.Payload.statusCode != 200 %}"), failedGetMyPrescriptions) + .otherwise(parseGetMyPrescriptionsBody + .next(evaluateToggleGetStatusUpdates + .when( + Condition.jsonata("{% $states.input.getStatusUpdates = true %}"), + getStatusUpdates.next(enrichPrescriptions) + ) + .otherwise(enrichPrescriptions)))) + } +} diff --git a/packages/cdk/resources/StateMachines.ts b/packages/cdk/resources/StateMachines.ts new file mode 100644 index 000000000..d7a6a18e6 --- /dev/null +++ b/packages/cdk/resources/StateMachines.ts @@ -0,0 +1,58 @@ +import {Fn} from "aws-cdk-lib" +import {ManagedPolicy, PolicyStatement} from "aws-cdk-lib/aws-iam" +import {Function} from "aws-cdk-lib/aws-lambda" +import {ExpressStateMachine, TypescriptLambdaFunction} from "@nhsdigital/eps-cdk-constructs" +import {Construct} from "constructs" +import {GetMyPrescriptions} from "./StateMachineDefinitions/GetMyPrescriptions" + +export interface StateMachinesProps { + readonly stackName: string + readonly logRetentionInDays: number + functions: {[key: string]: TypescriptLambdaFunction} +} + +export class StateMachines extends Construct { + stateMachines: {[key: string]: ExpressStateMachine} + + public constructor(scope: Construct, id: string, props: StateMachinesProps){ + super(scope, id) + + // Imports + const getStatusUpdates = Function.fromFunctionArn( + this, "GetStatusUpdates", `${Fn.importValue("psu:functions:GetStatusUpdates:FunctionArn")}:$LATEST`) + const callGetStatusUpdatesManagedPolicy = new ManagedPolicy(this, "CallGetStatusUpdatesManagedPolicy", { + description: "call get status updates lambda from get my prescriptions state machine", + statements: [ + new PolicyStatement({ + actions: [ + "lambda:InvokeFunction" + ], + resources: [ + getStatusUpdates.functionArn + ] + }) + ] + }) + + const getMyPrescriptions = new GetMyPrescriptions(this, "GetMyPrescriptionsStateMachineDefinition", { + getMyPrescriptionsFunction: props.functions.getMyPrescriptions.function, + enrichPrescriptionsFunction: props.functions.enrichPrescriptions.function, + getStatusUpdatesFunction: getStatusUpdates + }) + const getMyPrescriptionsStateMachine = new ExpressStateMachine(this, "GetMyPrescriptionsStateMachine", { + stackName: props.stackName, + stateMachineName: `${props.stackName}-GetMyPrescriptions`, + definition: getMyPrescriptions.definition, + logRetentionInDays: props.logRetentionInDays, + additionalPolicies: [ + props.functions.getMyPrescriptions.executionPolicy, + props.functions.enrichPrescriptions.executionPolicy, + callGetStatusUpdatesManagedPolicy + ] + }) + + this.stateMachines = { + getMyPrescriptions: getMyPrescriptionsStateMachine + } + } +} diff --git a/packages/cdk/scripts/deleteMainStacks.ts b/packages/cdk/scripts/deleteMainStacks.ts new file mode 100644 index 000000000..dfb3b28a8 --- /dev/null +++ b/packages/cdk/scripts/deleteMainStacks.ts @@ -0,0 +1,11 @@ +import {deleteUnusedMainStacks, getActiveApiVersions, getConfigFromEnvVar} from "@nhsdigital/eps-cdk-constructs" + +const awsEnvironment = getConfigFromEnvVar("AWS_ENVIRONMENT", "") +deleteUnusedMainStacks( + "pfp-api", + () => getActiveApiVersions("prescriptions-for-patients"), + `${awsEnvironment}.eps.national.nhs.uk.` +).catch((error) => { + console.error(error) + process.exit(1) +}) diff --git a/packages/cdk/scripts/deletePrStacks.ts b/packages/cdk/scripts/deletePrStacks.ts new file mode 100644 index 000000000..39977cbda --- /dev/null +++ b/packages/cdk/scripts/deletePrStacks.ts @@ -0,0 +1,10 @@ +import {deleteUnusedPrStacks} from "@nhsdigital/eps-cdk-constructs" + +deleteUnusedPrStacks( + "pfp-api", + "prescriptionsforpatients", + "dev.eps.national.nhs.uk." +).catch((error) => { + console.error(error) + process.exit(1) +}) diff --git a/packages/cdk/stacks/PfPApiSandboxStack.ts b/packages/cdk/stacks/PfPApiSandboxStack.ts new file mode 100644 index 000000000..49d392259 --- /dev/null +++ b/packages/cdk/stacks/PfPApiSandboxStack.ts @@ -0,0 +1,10 @@ +import {Stack, App} from "aws-cdk-lib" +import {StandardStackProps} from "@nhsdigital/eps-cdk-constructs" + +export class PfPApiSandboxStack extends Stack { + public constructor(scope: App, id: string, props: StandardStackProps){ + super(scope, id, props) + + // PLACEHOLDER FOR SANDBOX RESOURCES + } +} diff --git a/packages/cdk/stacks/PfPApiStatefulStack.ts b/packages/cdk/stacks/PfPApiStatefulStack.ts new file mode 100644 index 000000000..c4d2690a1 --- /dev/null +++ b/packages/cdk/stacks/PfPApiStatefulStack.ts @@ -0,0 +1,32 @@ +import {App, CfnOutput, Stack} from "aws-cdk-lib" +import {Parameters} from "../resources/Parameters" +import {StandardStackProps} from "@nhsdigital/eps-cdk-constructs" + +export interface PfPApiStatefulStackProps extends StandardStackProps { + readonly stackName: string + readonly tc007NhsNumberValue: string + readonly tc008NhsNumberValue: string + readonly tc009NhsNumberValue: string +} + +export function buildParametersReadPolicyExportName(stackName: string): string { + return `${stackName}:PfPApi:ReadParametersPolicyArn` +} + +export class PfPApiStatefulStack extends Stack { + public constructor(scope: App, id: string, props: PfPApiStatefulStackProps) { + super(scope, id, props) + + const params = new Parameters(this, "Parameters", { + stackName: props.stackName, + tc007NhsNumberValue: props.tc007NhsNumberValue, + tc008NhsNumberValue: props.tc008NhsNumberValue, + tc009NhsNumberValue: props.tc009NhsNumberValue + }) + + new CfnOutput(this, "ReadParametersPolicyArn", { + value: params.readParametersPolicy.managedPolicyArn, + exportName: buildParametersReadPolicyExportName(props.stackName) + }) + } +} diff --git a/packages/cdk/stacks/PfPApiStatelessStack.ts b/packages/cdk/stacks/PfPApiStatelessStack.ts new file mode 100644 index 000000000..a51274d39 --- /dev/null +++ b/packages/cdk/stacks/PfPApiStatelessStack.ts @@ -0,0 +1,66 @@ +import {App, Fn, Stack} from "aws-cdk-lib" +import {ManagedPolicy} from "aws-cdk-lib/aws-iam" +import {nagSuppressions} from "../nagSuppressions" +import {Functions} from "../resources/Functions" +import {StateMachines} from "../resources/StateMachines" +import {Apis} from "../resources/Apis" +import {StandardStackProps} from "@nhsdigital/eps-cdk-constructs" + +export interface PfPApiStatelessStackProps extends StandardStackProps { + readonly stackName: string + readonly logRetentionInDays: number + readonly logLevel: string + readonly targetSpineServer: string + readonly targetServiceSearchServer: string + readonly toggleGetStatusUpdates: string + readonly allowNhsNumberOverride: string + readonly mutualTlsTrustStoreKey: string | undefined + readonly csocApiGatewayDestination: string + readonly forwardCsocLogs: boolean + readonly parametersReadPolicyExportName: string +} + +export class PfPApiStatelessStack extends Stack { + public constructor(scope: App, id: string, props: PfPApiStatelessStackProps) { + super(scope, id, props) + + const parametersReadPolicy = ManagedPolicy.fromManagedPolicyArn( + this, + "ReadParametersPolicy", + Fn.importValue(props.parametersReadPolicyExportName) + ) + + // Resources + const functions = new Functions(this, "Functions", { + stackName: props.stackName, + version: props.version, + commitId: props.commitId, + deploymentEnvironment: props.environment, + targetSpineServer: props.targetSpineServer, + targetServiceSearchServer: props.targetServiceSearchServer, + toggleGetStatusUpdates: props.toggleGetStatusUpdates, + allowNhsNumberOverride: props.allowNhsNumberOverride, + logRetentionInDays: props.logRetentionInDays, + logLevel: props.logLevel, + getPfPParametersPolicy: parametersReadPolicy + }) + + const stateMachines = new StateMachines(this, "StateMachines", { + stackName: props.stackName, + logRetentionInDays: props.logRetentionInDays, + functions: functions.functions + }) + + new Apis(this, "Apis", { + stackName: props.stackName, + logRetentionInDays: props.logRetentionInDays, + mutualTlsTrustStoreKey: props.mutualTlsTrustStoreKey, + functions: functions.functions, + stateMachines: stateMachines.stateMachines, + csocApiGatewayDestination: props.csocApiGatewayDestination, + forwardCsocLogs: props.forwardCsocLogs + }) + + nagSuppressions(this) + } +} diff --git a/packages/cdk/tests/synth.test.ts b/packages/cdk/tests/synth.test.ts new file mode 100644 index 000000000..54237fad2 --- /dev/null +++ b/packages/cdk/tests/synth.test.ts @@ -0,0 +1,74 @@ +import {execFileSync} from "node:child_process" +import { + existsSync, + mkdirSync, + unlinkSync, + writeFileSync +} from "node:fs" +import {resolve} from "node:path" +import {describe, expect, it} from "vitest" + +const cdkPackageRoot = resolve(__dirname, "..") +const getSecretsLayerZipPath = resolve(cdkPackageRoot, "../getSecretLayer/lib/get-secrets-layer.zip") + +function createBaseEnv(): Record { + return { + ...process.env, + CI: "true", + CDK_DEFAULT_REGION: "eu-west-2", + CDK_CONFIG_versionNumber: "0.0.0-test", + CDK_CONFIG_commitId: "test-commit", + CDK_CONFIG_isPullRequest: "true", + CDK_CONFIG_environment: "test", + CDK_CONFIG_tc007NhsNumberValue: "9992387920", + CDK_CONFIG_tc008NhsNumberValue: "9992387920", + CDK_CONFIG_tc009NhsNumberValue: "9992387920" + } +} + +describe("CDK synth smoke tests", () => { + it("synthesizes the sandbox app", () => { + expect(() => { + execFileSync("npx", ["tsx", "bin/PfPApiSandboxApp.ts"], { + cwd: cdkPackageRoot, + stdio: "pipe", + env: createBaseEnv() + }) + }).not.toThrow() + }) + + it("synthesizes the main app", () => { + let shouldDeleteDummyLayer = false + + if (!existsSync(getSecretsLayerZipPath)) { + mkdirSync(resolve(getSecretsLayerZipPath, ".."), {recursive: true}) + // This file only needs to exist for CDK asset staging in synth tests. + writeFileSync(getSecretsLayerZipPath, Buffer.from("PK\u0003\u0004")) + shouldDeleteDummyLayer = true + } + + expect(() => { + try { + execFileSync("npx", ["tsx", "bin/PfPApiApp.ts"], { + cwd: cdkPackageRoot, + stdio: "pipe", + env: { + ...createBaseEnv(), + CDK_CONFIG_stackName: "pfp-test-stack", + CDK_CONFIG_logRetentionInDays: "7", + CDK_CONFIG_logLevel: "INFO", + CDK_CONFIG_targetSpineServer: "https://example-spine.test", + CDK_CONFIG_targetServiceSearchServer: "https://live/service-search-api/", + CDK_CONFIG_toggleGetStatusUpdates: "true", + CDK_CONFIG_allowNhsNumberOverride: "false", + CDK_CONFIG_forwardCsocLogs: "false" + } + }) + } finally { + if (shouldDeleteDummyLayer) { + unlinkSync(getSecretsLayerZipPath) + } + } + }).not.toThrow() + }) +}) diff --git a/packages/cdk/tsconfig.json b/packages/cdk/tsconfig.json new file mode 100644 index 000000000..f2046573b --- /dev/null +++ b/packages/cdk/tsconfig.json @@ -0,0 +1,40 @@ +{ + "extends": "../../tsconfig.defaults.json", + "compilerOptions": { + "module": "commonjs", + "rootDir": ".", + "outDir": "lib", + "noEmit": true, + "strict": false, + "lib": [ + "es2020" + ], + "noImplicitAny": true, + "strictNullChecks": true, + "noImplicitThis": true, + "alwaysStrict": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": false, + "inlineSources": true, + "experimentalDecorators": true, + "strictPropertyInitialization": false, + "typeRoots": [ + "../../node_modules/@types" + ] + }, + "include": [ + "resources/**/*", + "constructs/**/*", + "policies/**/*", + "stacks/**/*", + "tests/**/*", + "scripts/**/*", + "nagSuppressions.ts" + ], + "exclude": [ + "node_modules", + "cdk.out" + ] +} diff --git a/packages/cdk/vitest.config.ts b/packages/cdk/vitest.config.ts new file mode 100644 index 000000000..739bbad20 --- /dev/null +++ b/packages/cdk/vitest.config.ts @@ -0,0 +1,5 @@ +import {createVitestConfig} from "../../vitest.default.config" + +export default createVitestConfig({ + workspaceRoot: "../../" +}) diff --git a/packages/common/utilities/src/config.ts b/packages/common/utilities/src/config.ts index 68daa4c83..168479e79 100644 --- a/packages/common/utilities/src/config.ts +++ b/packages/common/utilities/src/config.ts @@ -1,4 +1,5 @@ import {SSMProvider} from "@aws-lambda-powertools/parameters/ssm" +import {Logger} from "@aws-lambda-powertools/logger" const defaultSsmProvider = new SSMProvider({ clientConfig: {region: process.env.AWS_REGION || "eu-west-2"} @@ -9,40 +10,41 @@ export class PfPConfig { static readonly TC008_NHS_NUMBERS_PARAM = "TC008NHSNumber" static readonly TC009_NHS_NUMBERS_PARAM = "TC009NHSNumber" - private ssmProvider: SSMProvider + private readonly ssmProvider: SSMProvider + private readonly logger: Logger constructor(ssmProvider?: SSMProvider) { + this.logger = new Logger() this.ssmProvider = ssmProvider || defaultSsmProvider } - async isTC007(nhsNumber: string) { - // TC007: test case functionality for supplier testing + async isTestCase(nhsNumber: string, param: string) { const env = process.env["DEPLOYMENT_ENVIRONMENT"] - if (env === "prod") return false - const stackName = process.env.STACK_NAME || "pfp" - const TC007_NHS_NUMBERS = await this.ssmProvider.get(`/${stackName}-${PfPConfig.TC007_NHS_NUMBERS_PARAM}`) - return TC007_NHS_NUMBERS ? TC007_NHS_NUMBERS.includes(nhsNumber) : false + + try { + const stackName = process.env.STACK_NAME || "pfp" + const paramValue = await this.ssmProvider.get(`/${stackName}-${param}`) + return paramValue ? paramValue.includes(nhsNumber) : false + } catch (error) { + this.logger.warn(`Cannot read parameter ${param}, continue with test case disabled:`, {error}) + return false + } + } + + async isTC007(nhsNumber: string) { + // TC007: test case functionality for supplier testing + return this.isTestCase(nhsNumber, PfPConfig.TC007_NHS_NUMBERS_PARAM) } async isTC008(nhsNumber: string) { // AEA-5653, AEA-5853 | TC008: force internal error response for supplier testing - const env = process.env["DEPLOYMENT_ENVIRONMENT"] - - if (env === "prod") return false - const stackName = process.env.STACK_NAME || "pfp" - const TC008_NHS_NUMBERS = await this.ssmProvider.get(`/${stackName}-${PfPConfig.TC008_NHS_NUMBERS_PARAM}`) - return TC008_NHS_NUMBERS ? TC008_NHS_NUMBERS.includes(nhsNumber) : false + return this.isTestCase(nhsNumber, PfPConfig.TC008_NHS_NUMBERS_PARAM) } async isTC009(nhsNumber: string) { // TC009: test case functionality for supplier testing - const env = process.env["DEPLOYMENT_ENVIRONMENT"] - - if (env === "prod") return false - const stackName = process.env.STACK_NAME || "pfp" - const TC009_NHS_NUMBERS = await this.ssmProvider.get(`/${stackName}-${PfPConfig.TC009_NHS_NUMBERS_PARAM}`) - return TC009_NHS_NUMBERS ? TC009_NHS_NUMBERS.includes(nhsNumber) : false + return this.isTestCase(nhsNumber, PfPConfig.TC009_NHS_NUMBERS_PARAM) } } diff --git a/template.env b/template.env new file mode 100644 index 000000000..96b9c5c56 --- /dev/null +++ b/template.env @@ -0,0 +1,5 @@ +export AWS_DEFAULT_PROFILE=Admin-591291862413 +export PATH="$PWD/node_modules/.bin:$PATH" +export stack_name= +export TARGET_SPINE_SERVER=msg.veit07.devspineservices.nhs.uk +export TARGET_SERVICE_SEARCH_SERVER=int.api.service.nhs.uk