diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 9b3dcc1c5c..fd211c218e 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -12,18 +12,32 @@ CMDCT- -### Important updates +### Notes --- -### Author checklist +### Pre-review checklist - [ ] I have performed a self-review of my code - [ ] I have added [thorough](https://shorturl.at/aejkF) tests, if necessary - [ ] I have updated relevant documentation, if necessary + +--- +### Pre-merge checklist + + +#### Review +- [ ] Design: This work has been reviewed and approved by design, if necessary +- [ ] Product: This work has been reviewed and approved by product owner, if necessary + +#### Security +_If either of the following are true, notify the team's ISSO (Information System Security Officer)._ + +- [ ] These changes are significant enough to require an update to the SIA. +- [ ] These changes are significant enough to require a penetration test. --- diff --git a/.github/audit-account.sh b/.github/audit-account.sh new file mode 100755 index 0000000000..5e214d454e --- /dev/null +++ b/.github/audit-account.sh @@ -0,0 +1,77 @@ +#!/bin/bash +set -o pipefail -o nounset -u +git fetch --all > /dev/null + +#Parse inputs +case ${1-} in + "ci_active"|"ci_inactive"|"cf_other"|"untagged") + OP=${1-} + ;; + *) + echo "Error: unkown operation" + echo "Usage: ${0} [ci_active|ci_inactive|cf_other|untagged] [resource_tagging_response|null]" && exit 1 + ;; +esac + +shift +if [ ! -z "${1-}" ]; then + if [ -f "${1-}" ]; then + RESOURCES=$(<"${1-}") + else + RESOURCES="${@-}" + fi + jq empty <<< "${RESOURCES}" + [ "$?" != 0 ] && echo "Error: supplied JSON is invalid." && echo ${RESOURCES} && exit 1 +else + RESOURCES=$(aws resourcegroupstaggingapi get-resources) +fi + +#Create array of objects with the branch name and the interpolated branch name (for bot created branches) +get_branches () { + RAW_BRANCHES=$(git for-each-ref --format='%(refname)' refs/remotes/origin | sed 's|^.\+\/||g') + BRANCHES=() + for B in $RAW_BRANCHES; do + [ "${B}" == "HEAD" ] && continue + IBRANCH=$(./setBranchName.sh ${B}) + BRANCHES+=($(echo '{"BRANCH":"'${B}'","IBRANCH":"'${IBRANCH}'"}')) + done + + jq -s '{BRANCHES:.}' <<< ${BRANCHES[*]} +} + +get_composite_ci () { + local BRANCHES=$(get_branches) + local RESOURCES=$(jq -r '{RESOURCES:[.ResourceTagMappingList[] | select(.Tags[]?.Key?=="STAGE")]}' <<< "${1}") + jq -rs 'reduce .[] as $item ({}; . * $item) + | [JOIN(INDEX(.BRANCHES[]; .IBRANCH); .RESOURCES[]; .Tags[].Value; add)] + | [.[] + | {"BRANCH":.BRANCH, "STAGE":.Tags[] + | select(.Key=="STAGE").Value, "ResourceARN":.ResourceARN}]' <<< $(echo ${BRANCHES}${RESOURCES}) +} + +#Produce report for active stacks created by the ci pipeline (has a corresponding branch) +ci_active () { + jq -r '[.[] | select(.BRANCH != null)] | sort_by(.STAGE)' <<< $(get_composite_ci "${1}") +} + +#Produce report for active stacks created by the ci pipeline (does NOT have a corresponding branch) +ci_inactive () { + jq -r '[.[] | select(.BRANCH == null)] | del(.[].BRANCH) | sort_by(.STAGE)' <<< $(get_composite_ci "${1}") +} + +#Produce report for resources that have tags but were not created by the ci pipeline +cf_other () { + jq -r '[.ResourceTagMappingList[] | select((.Tags? | length) > 0) | del(select(.Tags[].Key=="STAGE")) // empty | + { + InferredId: .Tags[] | select(.Key=="aws:cloudformation:stack-name" or .Key=="cms-cloud-service" or .Key=="Name").Value, + ResourceARN: .ResourceARN + }] | sort' <<< "${1}" +} + +#Produce report for resources that are untagged (some are still created by the ci pipeline) +untagged () { + jq -r '[{ResourceARN:.ResourceTagMappingList[] | select((.Tags? | length) < 1).ResourceARN}] | sort' <<< "${1}" +} + +#Execute operation +$OP "${RESOURCES}" diff --git a/.github/setBranchName.sh b/.github/setBranchName.sh index 00ffd55ffe..44aa50300e 100755 --- a/.github/setBranchName.sh +++ b/.github/setBranchName.sh @@ -7,9 +7,6 @@ GITHUB_REFNAME="${1}" [ -z "${GITHUB_REFNAME}" ] && echo "Error setting branch name. No input given." && exit 1 case ${GITHUB_REFNAME} in - $([[ "$GITHUB_REFNAME" =~ ^dependabot/.* ]] && echo ${GITHUB_REFNAME})) - echo ${GITHUB_REFNAME} | md5sum | head -c 10 | sed 's/^/x/' - ;; $([[ "$GITHUB_REFNAME" =~ ^snyk-* ]] && echo ${GITHUB_REFNAME})) echo ${GITHUB_REFNAME##*-} | head -c 10 | sed 's/^/s/' ;; diff --git a/.github/workflows/audit-account.yml b/.github/workflows/audit-account.yml new file mode 100644 index 0000000000..3df43fba48 --- /dev/null +++ b/.github/workflows/audit-account.yml @@ -0,0 +1,64 @@ +name: Audit Account + +on: + schedule: + - cron: "0 16 * * 1" # Every Monday at 1600 UTC + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.ref }} + cancel-in-progress: false + +permissions: + id-token: write + +jobs: + audit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: set variable values + run: ./.github/build_vars.sh set_values + env: + AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} + AWS_OIDC_ROLE_TO_ASSUME: ${{ secrets[env.BRANCH_SPECIFIC_VARNAME_AWS_OIDC_ROLE_TO_ASSUME] || secrets.AWS_OIDC_ROLE_TO_ASSUME }} + - name: Configure AWS credentials for GitHub Actions + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.AWS_OIDC_ROLE_TO_ASSUME }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} + - name: Collect resources from account + run: pushd .github && aws resourcegroupstaggingapi get-resources > resources.json + - name: List active resources created by CI pipeline + run: pushd .github && ./audit-account.sh ci_active resources.json + - name: List orphaned resources created by CI pipeline + run: pushd .github && ./audit-account.sh ci_inactive resources.json + - name: List resources created by Cloudformation but not from CI pipeline + run: pushd .github && ./audit-account.sh cf_other resources.json + - name: List untagged resources + run: pushd .github && ./audit-account.sh untagged resources.json + - name: Create reports dir + run: pushd .github && mkdir -p reports + - name: Assemble CSV files + run: | + #!/bin/bash + pushd .github + echo "Reports with no entries will be omitted" + CI_ACTIVE="$(./audit-account.sh ci_active resources.json)" + [[ $(jq -r 'length' <<< "${CI_ACTIVE}") -gt 0 ]] && jq -r '(.[0] + | keys_unsorted) as $keys | $keys, map([.[ $keys[] ]])[] | @csv' <<< "${CI_ACTIVE}" > reports/ci_active.csv + CI_INACTIVE="$(./audit-account.sh ci_inactive resources.json)" + [[ $(jq -r 'length' <<< "${CI_INACTIVE}") -gt 0 ]] && jq -r '(.[0] + | keys_unsorted) as $keys | $keys, map([.[ $keys[] ]])[] | @csv' <<< "${CI_INACTIVE}" > reports/ci_inactive.csv + CF_OTHER="$(./audit-account.sh cf_other resources.json)" + [[ $(jq -r 'length' <<< "${CF_OTHER}") -gt 0 ]] && jq -r '(.[0] + | keys_unsorted) as $keys | $keys, map([.[ $keys[] ]])[] | @csv' <<< "${CF_OTHER}" > reports/cf_other.csv + UNTAGGED="$(./audit-account.sh untagged resources.json)" + [[ $(jq -r 'length' <<< "${UNTAGGED}") -gt 0 ]] && jq -r '(.[0] + | keys_unsorted) as $keys | $keys, map([.[ $keys[] ]])[] | @csv' <<< "${UNTAGGED}" > reports/untagged.csv + - name: Upload reports + uses: actions/upload-artifact@v3 + with: + name: resource-reports + path: .github/reports/ + retention-days: 14 diff --git a/.github/workflows/dependabot-auto-approve.yml b/.github/workflows/dependabot-auto-approve.yml deleted file mode 100644 index 8a71d9fd41..0000000000 --- a/.github/workflows/dependabot-auto-approve.yml +++ /dev/null @@ -1,29 +0,0 @@ -# Adapted from https://docs.github.com/en/code-security/dependabot/working-with-dependabot/automating-dependabot-with-github-actions -name: Dependabot auto-approve -on: - pull_request: - workflow_dispatch: - -permissions: - pull-requests: write - contents: write - -jobs: - dependabot: - runs-on: ubuntu-latest - if: ${{ github.actor == 'dependabot[bot]' }} - steps: - - name: Dependabot Gather Metadata - id: metadata - uses: dependabot/fetch-metadata@v1 - - name: Approve a PR - run: gh pr review --approve "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - - name: Enable auto-merge for Dependabot PRs - if: ${{ steps.metadata.outputs.update-type != 'version-update:semver-major'}} - run: gh pr merge --auto --merge "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 29332636db..7c208d9976 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -4,7 +4,6 @@ on: push: branches: - "*" - - "dependabot/**" - "!skipci*" concurrency: @@ -28,20 +27,10 @@ jobs: SLS_DEPRECATION_DISABLE: "*" # Turn off deprecation warnings in the pipeline steps: - uses: actions/checkout@v4 - - name: set branch_name # Some integrations (Dependabot & Snyk) build very long branch names. This is a switch to make long branch names shorter. + - name: set branch_name # Some integrations (Snyk) build very long branch names. This is a switch to make long branch names shorter. run: | BRANCH_NAME=$(./.github/setBranchName.sh ${{ github.ref_name }}) echo "branch_name=${BRANCH_NAME}" >> $GITHUB_ENV - - name: "Setup jq" - uses: dcarbone/install-jq-action@v2.1.0 - with: - version: "${{ inputs.version }}" - force: "${{ inputs.force }}" - - name: "Check jq" - # language=sh - run: | - which jq - jq --version - name: Validate branch name run: ./.github/branchNameValidation.sh $STAGE_PREFIX$branch_name - name: set branch specific variable names @@ -86,72 +75,48 @@ jobs: application_endpoint: ${{ steps.endpoint.outputs.application_endpoint}} BRANCH_SPECIFIC_VARNAME_AWS_DEFAULT_REGION: ${{ steps.set_names.outputs.BRANCH_SPECIFIC_VARNAME_AWS_DEFAULT_REGION }} BRANCH_SPECIFIC_VARNAME_AWS_OIDC_ROLE_TO_ASSUME: ${{ steps.set_names.outputs.BRANCH_SPECIFIC_VARNAME_AWS_OIDC_ROLE_TO_ASSUME }} - # run e2e tests after deploy completes - e2e-tests-init: - name: Initialize End To End Tests - if: ${{ github.ref_name != 'master' && github.ref_name != 'val' && github.ref_name != 'prod' }} - needs: - - deploy + + register-runner: + name: Register GitHub Runner + if: ${{ github.ref_name != 'master' && github.ref_name != 'val' && github.ref_name != 'production' }} runs-on: ubuntu-latest + needs: deploy + env: + SLS_DEPRECATION_DISABLE: "*" # Turn off deprecation warnings in the pipeline steps: - - name: Verify Endpoint - if: ${{ needs.deploy.outputs.application_endpoint == ''}} - run: | - echo "No endpoint set, Check if the deploy workflow was successful." - exit 1 - - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@v4 + - name: set branch_name run: | BRANCH_NAME=$(./.github/setBranchName.sh ${{ github.ref_name }}) echo "branch_name=${BRANCH_NAME}" >> $GITHUB_ENV + - name: set branch specific variable names id: set_names run: ./.github/build_vars.sh set_names + - name: set variable values id: set_values run: ./.github/build_vars.sh set_values env: AWS_DEFAULT_REGION: ${{ secrets[env.BRANCH_SPECIFIC_VARNAME_AWS_DEFAULT_REGION] || secrets.AWS_DEFAULT_REGION }} AWS_OIDC_ROLE_TO_ASSUME: ${{ secrets[env.BRANCH_SPECIFIC_VARNAME_AWS_OIDC_ROLE_TO_ASSUME] || secrets.AWS_OIDC_ROLE_TO_ASSUME }} - INFRASTRUCTURE_TYPE: ${{ secrets[env.BRANCH_SPECIFIC_VARNAME_INFRASTRUCTURE_TYPE] || secrets.INFRASTRUCTURE_TYPE || 'development' }} STAGE_PREFIX: ${{ secrets.STAGE_PREFIX }} - COGNITO_TEST_USERS_PASSWORD: ${{ secrets[env.BRANCH_SPECIFIC_VARNAME_COGNITO_TEST_USERS_PASSWORD] || secrets.COGNITO_TEST_USERS_PASSWORD }} - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - uses: actions/setup-node@v3 - with: - node-version-file: ".nvmrc" - - name: Combine yarn.lock files to single file - run: find services -maxdepth 3 -name yarn.lock | xargs cat yarn.lock > combined-yarn.txt - - name: cache service dependencies - uses: actions/cache@v3 - with: - path: | - services/app-api/node_modules - services/uploads/node_modules - services/ui/node_modules - services/ui-auth/node_modules - services/ui-src/node_modules - node_modules - key: ${{ runner.os }}-${{ hashFiles('combined-yarn.txt') }} + - name: Configure AWS credentials for GitHub Actions uses: aws-actions/configure-aws-credentials@v4 with: - role-to-assume: ${{ env.AWS_OIDC_ROLE_TO_ASSUME }} - aws-region: ${{ env.AWS_DEFAULT_REGION }} - - name: Install dependencies - run: yarn install --frozen-lockfile - - name: set path - run: | - echo "PATH=$(pwd)/node_modules/.bin/:$PATH" >> $GITHUB_ENV - - name: Get Runner IP - id: get-ip + role-to-assume: ${{ secrets[env.BRANCH_SPECIFIC_VARNAME_AWS_OIDC_ROLE_TO_ASSUME] || secrets.AWS_OIDC_ROLE_TO_ASSUME }} + aws-region: ${{ secrets[env.BRANCH_SPECIFIC_VARNAME_AWS_DEFAULT_REGION] || secrets.AWS_DEFAULT_REGION }} + + - name: output account id + id: output_account_id run: | #!/bin/bash - # Get the IP address of the runner - IP_ADDRESS=$(curl https://api.ipify.org) - echo "Runner IP address: $IP_ADDRESS" - # Store the IP address as an output variable - echo "RUNNER_IP=$IP_ADDRESS/32" >> $GITHUB_OUTPUT + AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) + echo "Current Account ID: ${AWS_ACCOUNT_ID}" + - name: Get Github Actions CIDR Blocks id: get-gha-cidrs shell: bash @@ -162,18 +127,22 @@ jobs: IPV4_CIDR_ARR=($(echo $GHA_RESP | jq -r '.actions | .[]' | grep -v ':')) GHA_CIDRS_IPV4=$(echo $(IFS=" "; echo ${IPV4_CIDR_ARR[*]})) echo "GHA_CIDRS_IPV4=$GHA_CIDRS_IPV4" >> $GITHUB_OUTPUT + - name: Generate IP Set Name id: gen-ip-set-name run: | + #!/bin/bash STAGE_GH_IPSET_NAME=$STAGE_PREFIX$branch_name-gh-ipset echo "Github IP Set name: $STAGE_GH_IPSET_NAME" echo "STAGE_GH_IPSET_NAME=$STAGE_GH_IPSET_NAME" >> $GITHUB_OUTPUT - - name: Fetch AWS IP set Metadata + + - name: Fetch AWS IP Set Metadata id: fetch-ip-set-info run: | #!/bin/bash # Fetch AWS IP set ARNs using AWS CLI and store them in a variable AWS_IP_SET_INFO=$(aws wafv2 list-ip-sets --scope=CLOUDFRONT) + echo "Outputting AWS IP Set Info: ${AWS_IP_SET_INFO}" # Store the IP set ARNs in an output variable using GITHUB_OUTPUT IPSET_NAME=${{ steps.gen-ip-set-name.outputs.STAGE_GH_IPSET_NAME }} IPSET=$(jq '.IPSets | map(select(.Name == "'${IPSET_NAME}'")) | .[]' <<< ${AWS_IP_SET_INFO}) @@ -184,17 +153,78 @@ jobs: echo "IPSET_ARN=$IPSET_ARN" >> $GITHUB_OUTPUT echo "IPSET_NAME=$IPSET_NAME" >> $GITHUB_OUTPUT echo "IPSET_ID=$IPSET_ID" >> $GITHUB_OUTPUT + - name: Update IP Set id: update-ip-set run: ./.github/waf-controller.sh set ${{ steps.fetch-ip-set-info.outputs.IPSET_NAME }} ${{ steps.fetch-ip-set-info.outputs.IPSET_ID }} ${{ steps.get-gha-cidrs.outputs.GHA_CIDRS_IPV4 }} env: AWS_RETRY_MODE: adaptive AWS_MAX_ATTEMPTS: 10 + outputs: - application_endpoint: ${{ needs.deploy.outputs.application_endpoint }} ipset_name: ${{ steps.fetch-ip-set-info.outputs.IPSET_NAME }} ipset_id: ${{ steps.fetch-ip-set-info.outputs.IPSET_ID }} + e2e-tests-init: + name: Initialize End To End Tests + if: ${{ always() && !cancelled() && needs.deploy.result == 'success' && github.ref_name != 'master' && github.ref_name != 'val' && github.ref_name != 'prod' }} + needs: + - deploy + - register-runner + runs-on: ubuntu-latest + steps: + - name: Verify Endpoint + if: ${{ needs.deploy.outputs.application_endpoint == ''}} + run: | + echo "No endpoint set, Check if the deploy workflow was successful." + exit 1 + - uses: actions/checkout@v4 + - name: set branch_name + run: | + BRANCH_NAME=$(./.github/setBranchName.sh ${{ github.ref_name }}) + echo "branch_name=${BRANCH_NAME}" >> $GITHUB_ENV + - name: set branch specific variable names + id: set_names + run: ./.github/build_vars.sh set_names + - name: set variable values + id: set_values + run: ./.github/build_vars.sh set_values + env: + AWS_DEFAULT_REGION: ${{ secrets[env.BRANCH_SPECIFIC_VARNAME_AWS_DEFAULT_REGION] || secrets.AWS_DEFAULT_REGION }} + AWS_OIDC_ROLE_TO_ASSUME: ${{ secrets[env.BRANCH_SPECIFIC_VARNAME_AWS_OIDC_ROLE_TO_ASSUME] || secrets.AWS_OIDC_ROLE_TO_ASSUME }} + INFRASTRUCTURE_TYPE: ${{ secrets[env.BRANCH_SPECIFIC_VARNAME_INFRASTRUCTURE_TYPE] || secrets.INFRASTRUCTURE_TYPE || 'development' }} + STAGE_PREFIX: ${{ secrets.STAGE_PREFIX }} + COGNITO_TEST_USERS_PASSWORD: ${{ secrets[env.BRANCH_SPECIFIC_VARNAME_COGNITO_TEST_USERS_PASSWORD] || secrets.COGNITO_TEST_USERS_PASSWORD }} + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + - uses: actions/setup-node@v3 + with: + node-version-file: ".nvmrc" + - name: Combine yarn.lock files to single file + run: find services -maxdepth 3 -name yarn.lock | xargs cat yarn.lock > combined-yarn.txt + - name: cache service dependencies + uses: actions/cache@v3 + with: + path: | + services/app-api/node_modules + services/uploads/node_modules + services/ui/node_modules + services/ui-auth/node_modules + services/ui-src/node_modules + node_modules + key: ${{ runner.os }}-${{ hashFiles('combined-yarn.txt') }} + - name: Configure AWS credentials for GitHub Actions + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.AWS_OIDC_ROLE_TO_ASSUME }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} + - name: Install dependencies + run: yarn install --frozen-lockfile + - name: set path + run: | + echo "PATH=$(pwd)/node_modules/.bin/:$PATH" >> $GITHUB_ENV + outputs: + application_endpoint: ${{ needs.deploy.outputs.application_endpoint }} + setup-tests: name: "Setup End To End Tests" uses: ./.github/workflows/cypress-workflow.yml @@ -283,10 +313,6 @@ jobs: name: Accessibility Tests needs: - e2e-tests-init - - e2e-feature-tests - - child-e2e-measure-tests - - adult-e2e-measure-tests - - health-home-e2e-measure-tests uses: ./.github/workflows/cypress-workflow.yml with: test-path: "a11y" @@ -300,8 +326,8 @@ jobs: cypress-password: ${{ secrets.CYPRESS_TEST_PASSWORD_1 }} cleanup: - name: Deslist GHA Runner CIDR Blocks - if: ${{ github.ref != 'refs/heads/master' && github.ref != 'refs/heads/val' && github.ref != 'refs/heads/prod' }} + name: Delist GHA Runner CIDR Blocks + if: ${{ github.ref_name != 'master' && github.ref_name != 'val' && github.ref_name != 'prod' }} runs-on: ubuntu-latest needs: - e2e-tests-init @@ -310,6 +336,7 @@ jobs: - adult-e2e-measure-tests - health-home-e2e-measure-tests - deploy + - register-runner - a11y-tests env: SLS_DEPRECATION_DISABLE: "*" # Turn off deprecation warnings in the pipeline @@ -322,7 +349,7 @@ jobs: aws-region: ${{ secrets[env.BRANCH_SPECIFIC_VARNAME_AWS_DEFAULT_REGION] || secrets.AWS_DEFAULT_REGION }} - name: clean-up-iplist id: reset-ip-set - run: ./.github/waf-controller.sh set ${{ needs.e2e-tests-init.outputs.ipset_name }} ${{ needs.e2e-tests-init.outputs.ipset_id }} '[]' + run: ./.github/waf-controller.sh set ${{ needs.register-runner.outputs.ipset_name }} ${{ needs.register-runner.outputs.ipset_id }} '[]' env: AWS_RETRY_MODE: adaptive AWS_MAX_ATTEMPTS: 10 diff --git a/.github/workflows/destroy.yml b/.github/workflows/destroy.yml index 08ee56abd1..3da73075d4 100644 --- a/.github/workflows/destroy.yml +++ b/.github/workflows/destroy.yml @@ -1,6 +1,6 @@ name: Destroy -on: +on: delete: workflow_dispatch: inputs: diff --git a/.github/workflows/snyk-auto-merge.yml b/.github/workflows/snyk-auto-merge.yml index ece6352576..0694c999a3 100644 --- a/.github/workflows/snyk-auto-merge.yml +++ b/.github/workflows/snyk-auto-merge.yml @@ -1,4 +1,3 @@ -# Adapted from https://docs.github.com/en/code-security/dependabot/working-with-dependabot/automating-dependabot-with-github-actions name: Snyk auto-merge on: pull_request: @@ -9,21 +8,17 @@ permissions: contents: write jobs: - dependabot: + snyk: runs-on: ubuntu-latest if: ${{ github.actor == 'mdct-github-service-account' }} steps: - - name: Snyk Gather Metadata - id: metadata - uses: dependabot/fetch-metadata@v1 - - name: Approve a PR + - name: Auto-approve Snyk PR run: gh pr review --approve "$PR_URL" env: PR_URL: ${{github.event.pull_request.html_url}} GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - name: Enable auto-merge for Snyk PRs - if: ${{ steps.metadata.outputs.update-type != 'version-update:semver-major'}} - run: gh pr merge --auto --merge "$PR_URL" + run: gh pr merge --auto --squash "$PR_URL" env: PR_URL: ${{github.event.pull_request.html_url}} GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/README.md b/README.md index f5fd2910ed..dc39f945db 100644 --- a/README.md +++ b/README.md @@ -376,8 +376,6 @@ The Kafka Queues we link to are in the BigMac account and are currently not bein `postKafkaData`: Fires when an update to the database happens and syncs kafka to reflect the current state of the database. -`forceKafkaSync`: This can be manually triggered to force kafka to reflect the current state of the database. - ### Utilities --- diff --git a/package.json b/package.json index 1895093a6d..d501effd05 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "@types/yargs": "^15.0.10", "@typescript-eslint/eslint-plugin": "5.18.0", "@typescript-eslint/parser": "5.18.0", - "aws-sdk": "^2.1310.0", "dotenv": "^8.2.0", "eslint": "^7.32.0", "eslint-config-airbnb": "^18.2.1", diff --git a/services/app-api/handlers/banners/fetch.ts b/services/app-api/handlers/banners/fetch.ts index eeb615aaff..6f847be03c 100644 --- a/services/app-api/handlers/banners/fetch.ts +++ b/services/app-api/handlers/banners/fetch.ts @@ -1,6 +1,7 @@ import handler from "../../libs/handler-lib"; import dynamoDb from "../../libs/dynamodb-lib"; import { Errors, StatusCodes } from "../../utils/constants/constants"; +import { Banner } from "../../types"; export const fetchBanner = handler(async (event, _context) => { if (!event?.pathParameters?.bannerId!) { @@ -12,8 +13,8 @@ export const fetchBanner = handler(async (event, _context) => { key: event?.pathParameters?.bannerId!, }, }; - const response = await dynamoDb.get(params); + const response = await dynamoDb.get(params); const status = StatusCodes.SUCCESS; - return { status: status, body: response }; + return { status: status, body: { Item: response } }; }); diff --git a/services/app-api/handlers/banners/tests/create.test.ts b/services/app-api/handlers/banners/tests/create.test.ts index 518555dfc7..037b08f9a6 100644 --- a/services/app-api/handlers/banners/tests/create.test.ts +++ b/services/app-api/handlers/banners/tests/create.test.ts @@ -1,9 +1,8 @@ import { createBanner } from "../create"; -import { APIGatewayProxyEvent } from "aws-lambda"; +import { APIGatewayProxyEvent } from "../../../types"; import { testBanner, proxyEvent } from "./proxyEvent"; import dynamoDb from "../../../libs/dynamodb-lib"; import { Errors, StatusCodes } from "../../../utils/constants/constants"; -import { mockDocumentClient } from "../../../utils/testing/setupJest"; const mockHasRolePermissions = jest.fn(); jest.mock("../../../libs/authorization", () => ({ @@ -11,11 +10,6 @@ jest.mock("../../../libs/authorization", () => ({ hasRolePermissions: () => mockHasRolePermissions(), })); -jest.mock("../../../libs/debug-lib", () => ({ - init: jest.fn(), - flush: jest.fn(), -})); - const testEvent: APIGatewayProxyEvent = { ...proxyEvent, httpMethod: "PUT", @@ -28,15 +22,9 @@ const testEventNoTitle: APIGatewayProxyEvent = { body: JSON.stringify({ ...testBanner, title: "" }), }; -jest.spyOn(dynamoDb, "put").mockImplementation( - mockDocumentClient.put.promise.mockReturnValue({ - Item: { - ...testBanner, - createdAt: new Date().getTime(), - lastAltered: new Date().getTime(), - }, - }) -); +jest.mock("../../../libs/dynamodb-lib", () => ({ + put: jest.fn().mockResolvedValue("yep i put that thing!"), +})); describe("Test createBanner API method", () => { beforeEach(() => { diff --git a/services/app-api/handlers/banners/tests/delete.test.ts b/services/app-api/handlers/banners/tests/delete.test.ts index 1304b82fb1..292b76f53f 100644 --- a/services/app-api/handlers/banners/tests/delete.test.ts +++ b/services/app-api/handlers/banners/tests/delete.test.ts @@ -1,9 +1,8 @@ import { deleteBanner } from "../delete"; -import { APIGatewayProxyEvent } from "aws-lambda"; +import { APIGatewayProxyEvent } from "../../../types"; import { testBanner, proxyEvent } from "./proxyEvent"; import dynamoDb from "../../../libs/dynamodb-lib"; import { Errors, StatusCodes } from "../../../utils/constants/constants"; -import { mockDocumentClient } from "../../../utils/testing/setupJest"; const mockHasRolePermissions = jest.fn(); jest.mock("../../../libs/authorization", () => ({ @@ -11,23 +10,14 @@ jest.mock("../../../libs/authorization", () => ({ hasRolePermissions: () => mockHasRolePermissions(), })); -jest.mock("../../../libs/debug-lib", () => ({ - init: jest.fn(), - flush: jest.fn(), -})); - const testEvent: APIGatewayProxyEvent = { ...proxyEvent, httpMethod: "DEL", }; -jest.spyOn(dynamoDb, "delete").mockImplementation( - mockDocumentClient.delete.promise.mockReturnValue({ - Item: { - ...testBanner, - }, - }) -); +jest.mock("../../../libs/dynamodb-lib", () => ({ + delete: jest.fn().mockResolvedValue("DELETED"), +})); describe("Test deleteBanner API method", () => { beforeEach(() => { diff --git a/services/app-api/handlers/banners/tests/fetch.test.ts b/services/app-api/handlers/banners/tests/fetch.test.ts index 45e285a7f5..fb7f40c723 100644 --- a/services/app-api/handlers/banners/tests/fetch.test.ts +++ b/services/app-api/handlers/banners/tests/fetch.test.ts @@ -1,43 +1,39 @@ import { fetchBanner } from "../fetch"; -import { APIGatewayProxyEvent } from "aws-lambda"; -import { proxyEvent, testBanner } from "./proxyEvent"; +import { APIGatewayProxyEvent, EventParameters } from "../../../types"; import dynamoDb from "../../../libs/dynamodb-lib"; import { Errors, StatusCodes } from "../../../utils/constants/constants"; -import { mockDocumentClient } from "../../../utils/testing/setupJest"; jest.mock("../../../libs/authorization", () => ({ isAuthenticated: jest.fn().mockReturnValue(true), hasPermissions: jest.fn().mockReturnValue(true), })); -jest.mock("../../../libs/debug-lib", () => ({ - init: jest.fn(), - flush: jest.fn(), +jest.mock("../../../libs/dynamodb-lib", () => ({ + get: jest.fn().mockResolvedValue({ + title: "test banner", + description: "test description", + link: "https://www.example.com", + startDate: 1000, + endDate: 2000, + createdAt: new Date().getTime(), + lastAltered: new Date().getTime(), + }), })); -jest.spyOn(dynamoDb, "get").mockImplementation( - mockDocumentClient.get.promise.mockReturnValue({ - Item: { - ...testBanner, - createdAt: new Date().getTime(), - lastAltered: new Date().getTime(), - }, - }) -); - -const testEvent: APIGatewayProxyEvent = { - ...proxyEvent, - headers: { "cognito-identity-id": "test" }, - pathParameters: { bannerId: "testKey" }, -}; +const testEvent = { + headers: { + "cognito-identity-id": "test", + } as EventParameters, + pathParameters: { + bannerId: "testKey", + } as EventParameters, +} as APIGatewayProxyEvent; describe("Test fetchBanner API method", () => { test("Test Successful empty Banner Fetch", async () => { - jest.spyOn(dynamoDb, "get").mockImplementation( - mockDocumentClient.get.promise.mockReturnValueOnce({ - Item: undefined, - }) - ); + (dynamoDb.get as jest.Mock).mockResolvedValueOnce({ + Item: undefined, + }); const res = await fetchBanner(testEvent, null); expect(res.statusCode).toBe(StatusCodes.SUCCESS); }); @@ -46,11 +42,11 @@ describe("Test fetchBanner API method", () => { const res = await fetchBanner(testEvent, null); expect(res.statusCode).toBe(StatusCodes.SUCCESS); const parsedBody = JSON.parse(res.body); - expect(parsedBody.Item.title).toEqual(testBanner.title); - expect(parsedBody.Item.description).toEqual(testBanner.description); - expect(parsedBody.Item.startDate).toEqual(testBanner.startDate); - expect(parsedBody.Item.endDate).toEqual(testBanner.endDate); - expect(parsedBody.Item.link).toEqual(testBanner.link); + expect(parsedBody.Item.title).toEqual("test banner"); + expect(parsedBody.Item.description).toEqual("test description"); + expect(parsedBody.Item.startDate).toEqual(1000); + expect(parsedBody.Item.endDate).toEqual(2000); + expect(parsedBody.Item.link).toEqual("https://www.example.com"); }); test("Test bannerKey not provided throws 500 error", async () => { diff --git a/services/app-api/handlers/banners/tests/proxyEvent.ts b/services/app-api/handlers/banners/tests/proxyEvent.ts index e08717d8b1..91c481d8b4 100644 --- a/services/app-api/handlers/banners/tests/proxyEvent.ts +++ b/services/app-api/handlers/banners/tests/proxyEvent.ts @@ -1,4 +1,4 @@ -import { APIGatewayProxyEvent } from "aws-lambda"; +import { APIGatewayProxyEvent, EventParameters } from "../../../types"; export const testBanner = { title: "test banner", @@ -10,60 +10,17 @@ export const testBanner = { export const proxyEvent: APIGatewayProxyEvent = { body: "{}", - headers: { "x-api-key": "test" }, + headers: { "x-api-key": "test" } as EventParameters, httpMethod: "GET", isBase64Encoded: false, - multiValueHeaders: {}, - multiValueQueryStringParameters: {}, + multiValueHeaders: {} as EventParameters, + multiValueQueryStringParameters: {} as EventParameters, path: "", - pathParameters: { bannerId: "admin-banner-id" }, + pathParameters: { bannerId: "admin-banner-id" } as EventParameters, resource: "", stageVariables: null, - queryStringParameters: { bannerId: "testKey" }, + queryStringParameters: { bannerId: "testKey" } as EventParameters, requestContext: { - accountId: "", - apiId: "", - authorizer: () => {}, - httpMethod: "", - path: "", - protocol: "", - requestId: "", - requestTimeEpoch: 0, - resourceId: "", - resourcePath: "", - stage: "", - connectedAt: 0, - connectionId: "", - domainName: "", - domainPrefix: "", - eventType: "", - extendedRequestId: "", - messageDirection: "", - messageId: "", - requestTime: "", - routeKey: "", - identity: { - accessKey: "", - accountId: "", - apiKey: "", - apiKeyId: "", - caller: "", - cognitoAuthenticationProvider: "", - cognitoAuthenticationType: "", - cognitoIdentityId: "", - cognitoIdentityPoolId: "", - principalOrgId: "", - sourceIp: "", - user: "", - userAgent: "", - userArn: "", - clientCert: { - clientCertPem: "", - issuerDN: "", - serialNumber: "", - subjectDN: "", - validity: { notAfter: "", notBefore: "" }, - }, - }, + /* nope */ }, }; diff --git a/services/app-api/handlers/coreSets/create.ts b/services/app-api/handlers/coreSets/create.ts index 49ba98a885..54b192e425 100644 --- a/services/app-api/handlers/coreSets/create.ts +++ b/services/app-api/handlers/coreSets/create.ts @@ -76,7 +76,7 @@ export const createCoreSet = handler(async (event, context) => { }, }; - await dynamoDb.post(params); + await dynamoDb.put(params); return { status: StatusCodes.SUCCESS, body: params }; }); @@ -114,7 +114,7 @@ const createDependentMeasures = async ( }, }; - const result = await dynamoDb.post(params); + const result = await dynamoDb.put(params); dependentMeasures.push(result); } }; diff --git a/services/app-api/handlers/coreSets/delete.ts b/services/app-api/handlers/coreSets/delete.ts index 17c2afc6a5..9d3bf57602 100644 --- a/services/app-api/handlers/coreSets/delete.ts +++ b/services/app-api/handlers/coreSets/delete.ts @@ -43,7 +43,7 @@ const deleteDependentMeasures = async ( coreSet: string ) => { const measures = await getMeasures(state, year, coreSet); - const Items = measures.Items || []; + const Items = measures; for await (const { measure } of Items) { const dynamoKey = `${state}${year}${coreSet}${measure}`; @@ -67,6 +67,6 @@ const getMeasures = async (state: string, year: number, coreSet: string) => { "list" ), }; - const queryValue = await dynamoDb.scan(params); + const queryValue = await dynamoDb.scanAll(params); return queryValue; }; diff --git a/services/app-api/handlers/coreSets/get.ts b/services/app-api/handlers/coreSets/get.ts index d76c9a4b1a..7a6cd23023 100644 --- a/services/app-api/handlers/coreSets/get.ts +++ b/services/app-api/handlers/coreSets/get.ts @@ -8,12 +8,12 @@ import { hasRolePermissions, hasStatePermissions, } from "../../libs/authorization"; -import * as Types from "../../types"; import { Errors, StatusCodes } from "../../utils/constants/constants"; +import { CoreSet, CoreSetAbbr, UserRoles } from "../../types"; export const coreSetList = handler(async (event, context) => { // action limited to any admin type user and state users from corresponding state - const isStateUser = hasRolePermissions(event, [Types.UserRoles.STATE_USER]); + const isStateUser = hasRolePermissions(event, [UserRoles.STATE_USER]); if (isStateUser) { const isFromCorrespondingState = hasStatePermissions(event); if (!isFromCorrespondingState) { @@ -35,15 +35,15 @@ export const coreSetList = handler(async (event, context) => { ), }; - const results = await dynamoDb.scan(params); + const results = await dynamoDb.scanAll(params); // if the query value contains no results - if (results.Count === 0) { + if (results.length === 0) { // add an adult coreset and requery the db const createCoreSetEvent = { ...event, pathParameters: { ...event.pathParameters, - coreSet: Types.CoreSetAbbr.ACS, + coreSet: CoreSetAbbr.ACS, }, }; try { @@ -52,10 +52,12 @@ export const coreSetList = handler(async (event, context) => { context ); if (createCoreSetResult.statusCode === 200) { - const res = await dynamoDb.scan(params); + const res = await dynamoDb.scanAll(params); return { status: StatusCodes.SUCCESS, - body: res, + body: { + Items: res, + }, }; } else { throw new Error("Creation failed"); @@ -66,18 +68,20 @@ export const coreSetList = handler(async (event, context) => { } } else { // Update the progress measure numComplete - const updatedCoreSetProgressResults = - (await updateCoreSetProgress(results, event, context)) || results; + await updateCoreSetProgress(results, event, context); + return { status: StatusCodes.SUCCESS, - body: updatedCoreSetProgressResults, + body: { + Items: results, + }, }; } }); export const getCoreSet = handler(async (event, context) => { // action limited to any admin type user and state users from corresponding state - const isStateUser = hasRolePermissions(event, [Types.UserRoles.STATE_USER]); + const isStateUser = hasRolePermissions(event, [UserRoles.STATE_USER]); if (isStateUser) { const isFromCorrespondingState = hasStatePermissions(event); if (!isFromCorrespondingState) { @@ -99,6 +103,8 @@ export const getCoreSet = handler(async (event, context) => { const queryValue = await dynamoDb.get(params); return { status: StatusCodes.SUCCESS, - body: queryValue, + body: { + Item: queryValue, + }, }; }); diff --git a/services/app-api/handlers/coreSets/tests/create.test.ts b/services/app-api/handlers/coreSets/tests/create.test.ts index 904ccfb91f..581e40c9fa 100644 --- a/services/app-api/handlers/coreSets/tests/create.test.ts +++ b/services/app-api/handlers/coreSets/tests/create.test.ts @@ -23,12 +23,6 @@ jest.mock("../../../libs/authorization", () => ({ hasStatePermissions: () => mockHasStatePermissions(), })); -jest.mock("../../../libs/debug-lib", () => ({ - __esModule: true, - init: jest.fn(), - flush: jest.fn(), -})); - jest.mock("../../dynamoUtils/createCompoundKey", () => ({ __esModule: true, createCompoundKey: jest.fn().mockReturnValue("FL2021ACSFUA-AD"), @@ -93,6 +87,6 @@ describe("Testing the Create CoreSet Functions", () => { ); expect(res.statusCode).toBe(StatusCodes.SUCCESS); - expect(dynamoDb.post).toHaveBeenCalledTimes(list.length + 1); + expect(dynamoDb.put).toHaveBeenCalledTimes(list.length + 1); }); }); diff --git a/services/app-api/handlers/coreSets/tests/delete.test.ts b/services/app-api/handlers/coreSets/tests/delete.test.ts index fe8d806cee..dfc8311282 100644 --- a/services/app-api/handlers/coreSets/tests/delete.test.ts +++ b/services/app-api/handlers/coreSets/tests/delete.test.ts @@ -4,11 +4,8 @@ import { testEvent, testMeasure } from "../../../test-util/testEvents"; import { Errors, StatusCodes } from "../../../utils/constants/constants"; jest.mock("../../../libs/dynamodb-lib", () => ({ - __esModule: true, - default: { - delete: jest.fn(), - scan: jest.fn(), - }, + delete: jest.fn(), + scanAll: jest.fn(), })); const mockHasStatePermissions = jest.fn(); @@ -17,12 +14,6 @@ jest.mock("../../../libs/authorization", () => ({ hasStatePermissions: () => mockHasStatePermissions(), })); -jest.mock("../../../libs/debug-lib", () => ({ - __esModule: true, - init: jest.fn(), - flush: jest.fn(), -})); - jest.mock("../../dynamoUtils/createCompoundKey", () => ({ __esModule: true, createCompoundKey: jest.fn().mockReturnValue("FL2020ACSFUA-AD"), @@ -40,7 +31,7 @@ jest.mock("../../dynamoUtils/createCompoundKey", () => ({ describe("Testing Delete Core Set Functions", () => { beforeEach(() => { - (db.scan as jest.Mock).mockReset(); + (db.scanAll as jest.Mock).mockReset(); (db.delete as jest.Mock).mockReset(); mockHasStatePermissions.mockImplementation(() => true); }); @@ -59,9 +50,11 @@ describe("Testing Delete Core Set Functions", () => { }); test("Test deleteCoreSet with associated measures", async () => { - (db.scan as jest.Mock).mockReturnValue({ - Items: [testMeasure, testMeasure, testMeasure], - }); + (db.scanAll as jest.Mock).mockReturnValue([ + testMeasure, + testMeasure, + testMeasure, + ]); await deleteCoreSet( { @@ -71,12 +64,12 @@ describe("Testing Delete Core Set Functions", () => { null ); - expect(db.scan).toHaveBeenCalled(); + expect(db.scanAll).toHaveBeenCalled(); expect(db.delete).toHaveBeenCalledTimes(4); }); test("Test deleteCoreSet with no associated measures", async () => { - (db.scan as jest.Mock).mockReturnValue({}); + (db.scanAll as jest.Mock).mockReturnValue([]); await deleteCoreSet( { @@ -86,7 +79,7 @@ describe("Testing Delete Core Set Functions", () => { null ); - expect(db.scan).toHaveBeenCalled(); + expect(db.scanAll).toHaveBeenCalled(); expect(db.delete).toHaveBeenCalled(); }); }); diff --git a/services/app-api/handlers/coreSets/tests/get.test.ts b/services/app-api/handlers/coreSets/tests/get.test.ts index 3c24519f61..95f674b1de 100644 --- a/services/app-api/handlers/coreSets/tests/get.test.ts +++ b/services/app-api/handlers/coreSets/tests/get.test.ts @@ -13,7 +13,7 @@ jest.mock("../../../libs/dynamodb-lib", () => ({ __esModule: true, default: { get: jest.fn(), - scan: jest.fn(), + scanAll: jest.fn(), }, })); @@ -30,12 +30,6 @@ jest.mock("../../../libs/authorization", () => ({ hasStatePermissions: () => mockHasStatePermissions(), })); -jest.mock("../../../libs/debug-lib", () => ({ - __esModule: true, - init: jest.fn(), - flush: jest.fn(), -})); - jest.mock("../../../libs/updateCoreProgress", () => ({ __esModule: true, updateCoreSetProgress: jest.fn(), @@ -58,7 +52,7 @@ describe("Test Get Core Set Functions", () => { beforeEach(() => { (createCoreSet as jest.Mock).mockReset(); - (dynamodbLib.scan as jest.Mock).mockReset(); + (dynamodbLib.scanAll as jest.Mock).mockReset(); (updateCoreSetProgress as jest.Mock).mockReset(); mockHasRolePermissions.mockImplementation(() => false); }); @@ -91,8 +85,8 @@ describe("Test Get Core Set Functions", () => { test("Test coreSetList unauthorized user attempt (incorrect state)", async () => { mockHasRolePermissions.mockImplementation(() => true); mockHasStatePermissions.mockImplementation(() => false); - (dynamodbLib.scan as jest.Mock).mockReturnValue({ Count: 0 }); - (createCoreSet as jest.Mock).mockReturnValue({ statusCode: 200 }); + (dynamodbLib.scanAll as jest.Mock).mockResolvedValue({ Count: 0 }); + (createCoreSet as jest.Mock).mockResolvedValue({ statusCode: 200 }); const res = await coreSetList( { ...testEvent, @@ -104,9 +98,9 @@ describe("Test Get Core Set Functions", () => { expect(res.body).toContain(Errors.UNAUTHORIZED); }); - test("Test coreSetList with results.Count being 0 and statusCode 200", async () => { - (dynamodbLib.scan as jest.Mock).mockReturnValue({ Count: 0 }); - (createCoreSet as jest.Mock).mockReturnValue({ statusCode: 200 }); + test("Test coreSetList with no existing core sets and creating them successful", async () => { + (dynamodbLib.scanAll as jest.Mock).mockResolvedValue([]); + (createCoreSet as jest.Mock).mockResolvedValue({ statusCode: 200 }); const res = await coreSetList( { @@ -117,13 +111,13 @@ describe("Test Get Core Set Functions", () => { ); expect(createCoreSet).toHaveBeenCalled(); - expect(dynamodbLib.scan).toHaveBeenCalled(); + expect(dynamodbLib.scanAll).toHaveBeenCalled(); }); - test("Test coreSetList with results.Count being 0 and statusCode !== 200", async () => { + test("Test coreSetList with no existing core sets and creating them fails", async () => { console.log = jest.fn(); - (dynamodbLib.scan as jest.Mock).mockReturnValue({ Count: 0 }); - (createCoreSet as jest.Mock).mockReturnValue({ statusCode: 500 }); + (dynamodbLib.scanAll as jest.Mock).mockResolvedValue([]); + (createCoreSet as jest.Mock).mockResolvedValue({ statusCode: 500 }); const res = await coreSetList( { @@ -138,10 +132,10 @@ describe("Test Get Core Set Functions", () => { expect(res.body).toContain("Failed to create new coreset"); }); - test("Test coreSetList with results.Count being 0 but error thrown", async () => { + test("Test coreSetList with no existing core sets and creating them REALLY fails", async () => { console.log = jest.fn(); const testError = new Error("test error"); - (dynamodbLib.scan as jest.Mock).mockReturnValue({ Count: 0 }); + (dynamodbLib.scanAll as jest.Mock).mockResolvedValue([]); (createCoreSet as jest.Mock).mockImplementationOnce(() => { throw testError; }); @@ -158,26 +152,13 @@ describe("Test Get Core Set Functions", () => { expect(res.body).toContain("Failed to create new coreset"); }); - test("Test coreSetList with results.Count being non-zero and updateCoreSetProgress returns a value", async () => { - (dynamodbLib.scan as jest.Mock).mockReturnValue({ Count: 1 }); - (updateCoreSetProgress as jest.Mock).mockReturnValue({ - Count: 1, - }); - const res = await coreSetList( - { - ...testEvent, - pathParameters: { coreSet: CoreSetAbbr.ACS, year: "2021", state: "FL" }, - }, - null + test("Test coreSetList with existing core sets and updateCoreSetProgress successful", async () => { + (dynamodbLib.scanAll as jest.Mock).mockResolvedValue([ + { coreSet: "ACS", progress: {} }, + ]); + (updateCoreSetProgress as jest.Mock).mockImplementation((coreSets) => + coreSets.forEach((cs: any) => (cs.progress.numComplete = 1)) ); - - expect(res.body).toContain('"Count":1'); - expect(dynamodbLib.scan).toHaveBeenCalled(); - }); - - test("Test coreSetList with results.Count being non-zero and updateCoreSetProgress returns undefined", async () => { - (dynamodbLib.scan as jest.Mock).mockReturnValue({ Count: 1 }); - (updateCoreSetProgress as jest.Mock).mockReturnValue(undefined); const res = await coreSetList( { ...testEvent, @@ -185,6 +166,8 @@ describe("Test Get Core Set Functions", () => { }, null ); - expect(res.body).toContain('"Count":1'); + + expect(res.body).toContain('"progress":{"numComplete":1}'); + expect(dynamodbLib.scanAll).toHaveBeenCalled(); }); }); diff --git a/services/app-api/handlers/coreSets/tests/update.test.ts b/services/app-api/handlers/coreSets/tests/update.test.ts index 9194615119..226fa4c98a 100644 --- a/services/app-api/handlers/coreSets/tests/update.test.ts +++ b/services/app-api/handlers/coreSets/tests/update.test.ts @@ -6,10 +6,7 @@ import { editCoreSet } from "../update"; import { Errors, StatusCodes } from "../../../utils/constants/constants"; jest.mock("../../../libs/dynamodb-lib", () => ({ - __esModule: true, - default: { - update: jest.fn(), - }, + update: jest.fn(), })); const mockHasStatePermissions = jest.fn(); @@ -19,12 +16,6 @@ jest.mock("../../../libs/authorization", () => ({ hasStatePermissions: () => mockHasStatePermissions(), })); -jest.mock("../../../libs/debug-lib", () => ({ - __esModule: true, - init: jest.fn(), - flush: jest.fn(), -})); - jest.mock("../../dynamoUtils/createCompoundKey", () => ({ __esModule: true, createCompoundKey: jest.fn().mockReturnValue("FL2020ACSFUA-AD"), diff --git a/services/app-api/handlers/dynamoUtils/createCompoundKey.ts b/services/app-api/handlers/dynamoUtils/createCompoundKey.ts index 3e0e45e1f1..fe265863ad 100644 --- a/services/app-api/handlers/dynamoUtils/createCompoundKey.ts +++ b/services/app-api/handlers/dynamoUtils/createCompoundKey.ts @@ -1,4 +1,4 @@ -import { APIGatewayProxyEvent } from "aws-lambda"; +import { APIGatewayProxyEvent } from "../../types"; export const createCompoundKey = (event: APIGatewayProxyEvent) => { if (!event.pathParameters) throw new Error("No Path Parameters Object"); diff --git a/services/app-api/handlers/dynamoUtils/measureList.ts b/services/app-api/handlers/dynamoUtils/measureList.ts index 98d3807554..85503d467b 100644 --- a/services/app-api/handlers/dynamoUtils/measureList.ts +++ b/services/app-api/handlers/dynamoUtils/measureList.ts @@ -1098,6 +1098,7 @@ export const measures: Measure = { { type: "A", measure: "CPA-AD", + autocompleteOnCreation: true, }, { type: "A", @@ -1115,10 +1116,6 @@ export const measures: Measure = { type: "A", measure: "FUM-AD", }, - { - type: "A", - measure: "FVA-AD", - }, { type: "A", measure: "HBD-AD", @@ -1138,10 +1135,11 @@ export const measures: Measure = { { type: "A", measure: "MSC-AD", + autocompleteOnCreation: true, }, { type: "A", - measure: "NCIDDS-AD", + measure: "NCIIDD-AD", autocompleteOnCreation: true, }, { @@ -1158,7 +1156,7 @@ export const measures: Measure = { }, { type: "A", - measure: "PPC-AD", + measure: "PPC2-AD", }, { type: "A", diff --git a/services/app-api/handlers/kafka/get/forceKafkaSync.js b/services/app-api/handlers/kafka/get/forceKafkaSync.js deleted file mode 100644 index 243465638b..0000000000 --- a/services/app-api/handlers/kafka/get/forceKafkaSync.js +++ /dev/null @@ -1,111 +0,0 @@ -import handler from "../../../libs/handler-lib"; -import dynamoDb from "../../../libs/dynamodb-lib"; -import chunk from "lodash/chunk"; - -const tableNames = [ - process.env.AgeRangesTableName, - process.env.FormAnswersTableName, - process.env.FormQuestionsTableName, - process.env.FormsTableName, - process.env.FormTemplatesTableName, - process.env.StateFormsTableName, - process.env.StatesTableName, - process.env.StatusTableName, - process.env.AuthUserTableName, -]; - -const scanTable = async (tableName, startingKey, keepSearching) => { - let results = await dynamoDb.scanOnce({ - TableName: tableName, - ExclusiveStartKey: startingKey, - }); - if (results.LastEvaluatedKey) { - startingKey = results.LastEvaluatedKey; - return [startingKey, keepSearching, results]; - } else { - keepSearching = false; - return [null, keepSearching, results]; - } -}; - -const mergeLastSynced = (items, syncDateTime) => - items.map((item) => ({ ...item, lastSynced: syncDateTime })); - -const batchWrite = async (tableName, items) => { - console.log( - `Performing batchwrite for ${items.length} items in table: ${tableName}` - ); - // split items into chunks of 25 - const itemChunks = chunk(items, 25); - console.log( - `Items split into ${itemChunks.length} chunk(s) of not more than 25 items` - ); - for (const index in itemChunks) { - // Construct the request params for batchWrite - const itemArray = itemChunks[index].map((item) => { - return { - PutRequest: { - Item: item, - }, - }; - }); - - let requestItems = {}; - requestItems[tableName] = itemArray; - - const params = { - RequestItems: requestItems, - }; - - const { FailedItems } = await dynamoDb.batchWrite(params); - console.log(`BatchWrite performed for ${itemArray.length} items`); - if ((FailedItems?.length ?? 0) > 0) { - const keys = FailedItems.map((item) => item[Object.keys(item)[0]]); - console.log( - `BatchWrite ran with ${ - FailedItems.length ?? 0 - } numbers of failed item updates` - ); - console.log( - `The following items failed updating for the table ${tableName} - keys ${keys}` - ); - } - } -}; - -export const main = handler(async (event, context) => { - const syncDateTime = new Date().toISOString(); - - for (const tableName of tableNames) { - console.log(`Starting to scan table ${tableName}`); - let startingKey; - - let keepSearching = true; - // Looping to perform complete scan of tables due to 1 mb limit per iteration - while (keepSearching) { - let data; - - try { - [startingKey, keepSearching, data] = await scanTable( - tableName, - startingKey, - keepSearching - ); - } catch (err) { - console.error(`Database scan failed for the table ${tableName} - with startingKey ${startingKey} and the keepSearching flag is ${keepSearching}. - Error: ${err}`); - throw err; - } - - // Add lastSynced date time field - const updatedItems = mergeLastSynced(data.Items, syncDateTime); - try { - await batchWrite(tableName, updatedItems); - } catch (e) { - console.error(`BatchWrite failed with exception ${e}`); - throw e; - } - } - } -}); diff --git a/services/app-api/handlers/measures/get.ts b/services/app-api/handlers/measures/get.ts index 55cee1c60f..11b21faa58 100644 --- a/services/app-api/handlers/measures/get.ts +++ b/services/app-api/handlers/measures/get.ts @@ -9,7 +9,6 @@ import { } from "../../libs/authorization"; import { Measure, UserRoles } from "../../types"; import { Errors, StatusCodes } from "../../utils/constants/constants"; -import { Key } from "aws-sdk/clients/dynamodb"; export const listMeasures = handler(async (event, context) => { // action limited to any admin type user and state users from corresponding state @@ -34,25 +33,22 @@ export const listMeasures = handler(async (event, context) => { { state: state, year: parseInt(year), coreSet: coreSet }, "list" ), - ExclusiveStartKey: undefined as Key | undefined, }; - const scannedResults: any[] = []; - let queryValue = await dynamoDb.scan(params); - queryValue?.Items?.forEach((v) => { + let queriedMeasures = await dynamoDb.scanAll(params); + for (let v of queriedMeasures) { const measure = measures[parseInt(year)]?.filter( (m) => m.measure === (v as Measure)?.measure )[0]; - scannedResults.push({ - ...v, - autoCompleted: !!measure?.autocompleteOnCreation, - }); - }); - queryValue.Items = scannedResults; + v.autoCompleted = !!measure?.autocompleteOnCreation; + } + return { status: StatusCodes.SUCCESS, - body: queryValue, + body: { + Items: queriedMeasures, + }, }; }); @@ -77,10 +73,12 @@ export const getMeasure = handler(async (event, context) => { coreSet: event.pathParameters!.coreSet!, }, }; - const queryValue = await dynamoDb.get(params); + const queryValue = await dynamoDb.get(params); return { status: StatusCodes.SUCCESS, - body: queryValue, + body: { + Item: queryValue, + }, }; }); diff --git a/services/app-api/handlers/measures/tests/create.test.ts b/services/app-api/handlers/measures/tests/create.test.ts index 971cc97ad8..141a2d5576 100644 --- a/services/app-api/handlers/measures/tests/create.test.ts +++ b/services/app-api/handlers/measures/tests/create.test.ts @@ -1,15 +1,11 @@ import { createMeasure } from "../create"; -import { APIGatewayProxyEvent } from "aws-lambda"; +import { APIGatewayProxyEvent } from "../../../types"; import { testEvent } from "../../../test-util/testEvents"; import { StatusCodes, Errors } from "../../../utils/constants/constants"; jest.mock("../../../libs/dynamodb-lib", () => ({ - __esModule: true, - default: { - put: jest.fn(), - post: jest.fn().mockReturnValue({}), - }, + put: jest.fn(), })); const mockHasRolePermissions = jest.fn(); @@ -20,12 +16,6 @@ jest.mock("../../../libs/authorization", () => ({ hasStatePermissions: () => mockHasStatePermissions(), })); -jest.mock("../../../libs/debug-lib", () => ({ - __esModule: true, - init: jest.fn(), - flush: jest.fn(), -})); - jest.mock("../../dynamoUtils/createCompoundKey", () => ({ __esModule: true, createCompoundKey: jest.fn().mockReturnValue("FL2020ACSFUA-AD"), diff --git a/services/app-api/handlers/measures/tests/delete.test.ts b/services/app-api/handlers/measures/tests/delete.test.ts index 4e2e780111..160b2eea60 100644 --- a/services/app-api/handlers/measures/tests/delete.test.ts +++ b/services/app-api/handlers/measures/tests/delete.test.ts @@ -2,15 +2,12 @@ import { deleteMeasure } from "../delete"; import dbLib from "../../../libs/dynamodb-lib"; -import { APIGatewayProxyEvent } from "aws-lambda"; +import { APIGatewayProxyEvent } from "../../../types"; import { testEvent } from "../../../test-util/testEvents"; import { StatusCodes, Errors } from "../../../utils/constants/constants"; jest.mock("../../../libs/dynamodb-lib", () => ({ - __esModule: true, - default: { - delete: jest.fn(), - }, + delete: jest.fn(), })); const mockHasStatePermissions = jest.fn(); @@ -19,12 +16,6 @@ jest.mock("../../../libs/authorization", () => ({ hasStatePermissions: () => mockHasStatePermissions(), })); -jest.mock("../../../libs/debug-lib", () => ({ - __esModule: true, - init: jest.fn(), - flush: jest.fn(), -})); - jest.mock("../../dynamoUtils/createCompoundKey", () => ({ __esModule: true, createCompoundKey: jest.fn().mockReturnValue("FL2020ACSFUA-AD"), diff --git a/services/app-api/handlers/measures/tests/get.test.ts b/services/app-api/handlers/measures/tests/get.test.ts index 882864d599..939ab097dd 100644 --- a/services/app-api/handlers/measures/tests/get.test.ts +++ b/services/app-api/handlers/measures/tests/get.test.ts @@ -7,17 +7,16 @@ import { import dbLib from "../../../libs/dynamodb-lib"; -import { APIGatewayProxyEvent } from "aws-lambda"; +import { APIGatewayProxyEvent } from "../../../types"; import { testEvent } from "../../../test-util/testEvents"; import { convertToDynamoExpression } from "../../dynamoUtils/convertToDynamoExpressionVars"; import { Errors, StatusCodes } from "../../../utils/constants/constants"; jest.mock("../../../libs/dynamodb-lib", () => ({ - __esModule: true, - default: { - get: jest.fn().mockReturnValue("single measure"), - scan: jest.fn().mockReturnValue(["array", "of", "measures"]), - }, + get: jest.fn().mockResolvedValue("single measure"), + scanAll: jest + .fn() + .mockResolvedValue([{ measure: "CSQ" }, { measure: "LBW-CH" }]), })); const mockHasRolePermissions = jest.fn(); @@ -28,12 +27,6 @@ jest.mock("../../../libs/authorization", () => ({ hasStatePermissions: () => mockHasStatePermissions(), })); -jest.mock("../../../libs/debug-lib", () => ({ - __esModule: true, - init: jest.fn(), - flush: jest.fn(), -})); - jest.mock("../../dynamoUtils/createCompoundKey", () => ({ __esModule: true, createCompoundKey: jest.fn().mockReturnValue("FL2020ACSFUA-AD"), @@ -115,10 +108,9 @@ describe("Test Get Measure Handlers", () => { const res = await listMeasures(event, null); expect(res.statusCode).toBe(StatusCodes.SUCCESS); - expect(res.body).toContain("array"); - expect(res.body).toContain("of"); - expect(res.body).toContain("measures"); - expect(dbLib.scan).toHaveBeenCalledWith({ + expect(res.body).toContain("CSQ"); + expect(res.body).toContain("LBW-CH"); + expect(dbLib.scanAll).toHaveBeenCalledWith({ TableName: "SAMPLE TABLE", testValue: "test", }); diff --git a/services/app-api/handlers/measures/tests/update.test.ts b/services/app-api/handlers/measures/tests/update.test.ts index eb93edd40a..c3ed3e0112 100644 --- a/services/app-api/handlers/measures/tests/update.test.ts +++ b/services/app-api/handlers/measures/tests/update.test.ts @@ -2,7 +2,7 @@ import { editMeasure } from "../update"; import dbLib from "../../../libs/dynamodb-lib"; -import { APIGatewayProxyEvent } from "aws-lambda"; +import { APIGatewayProxyEvent } from "../../../types"; import { testEvent } from "../../../test-util/testEvents"; import { convertToDynamoExpression } from "../../dynamoUtils/convertToDynamoExpressionVars"; import { StatusCodes, Errors } from "../../../utils/constants/constants"; @@ -21,12 +21,6 @@ jest.mock("../../../libs/authorization", () => ({ hasStatePermissions: () => mockHasStatePermissions(), })); -jest.mock("../../../libs/debug-lib", () => ({ - __esModule: true, - init: jest.fn(), - flush: jest.fn(), -})); - jest.mock("../../dynamoUtils/createCompoundKey", () => ({ __esModule: true, createCompoundKey: jest.fn().mockReturnValue("FL2020ACSFUA-AD"), diff --git a/services/app-api/handlers/prince/pdf.ts b/services/app-api/handlers/prince/pdf.ts index 29c330aee7..529577c66d 100644 --- a/services/app-api/handlers/prince/pdf.ts +++ b/services/app-api/handlers/prince/pdf.ts @@ -12,26 +12,20 @@ export const getPDF = handler(async (event, _context) => { if (!rawBody) { throw new Error("Missing request body"); } - - let sanitizedBody; - if (DOMPurify.isSupported && typeof rawBody === "string") { - // decode body from base64, sanitize dangerous html - const decodedBody = Buffer.from(rawBody, "base64").toString(); - sanitizedBody = DOMPurify.sanitize(decodedBody); - } - if (!sanitizedBody) { - throw new Error("Could not process request"); + if (rawBody.startsWith("{")) { + throw new Error("Body must be base64-encoded HTML, not a JSON object"); } - const { docraptorApiKey, stage } = process.env; if (!docraptorApiKey) { throw new Error("No config found to make request to PDF API"); } + const decodedHtml = Buffer.from(rawBody, "base64").toString(); + const sanitizedHtml = sanitizeHtml(decodedHtml); const requestBody = { user_credentials: docraptorApiKey, doc: { - document_content: sanitizedBody, + document_content: sanitizedHtml, type: "pdf" as const, // This tag differentiates QMR and CARTS requests in DocRaptor's logs. tag: "QMR", @@ -67,6 +61,43 @@ async function sendDocRaptorRequest(request: DocRaptorRequestBody) { return response.arrayBuffer(); } +function sanitizeHtml(htmlString: string) { + if (!DOMPurify.isSupported) { + throw new Error("Could not process request"); + } + + /* + * DOMPurify will zap an entire

Hi

`; + const htmlWithoutComment = `

Hi

`; + const res = await getPDF( + { + ...testEvent, + body: Buffer.from(htmlWithCssComment).toString("base64"), + }, + null + ); + + expect(res.statusCode).toBe(200); + + expect(fetch).toHaveBeenCalled(); + const request = (fetch as jest.Mock).mock.calls[0][1]; + const body = JSON.parse(request.body); + expect(body).toEqual( + expect.objectContaining({ + doc: expect.objectContaining({ + document_content: htmlWithoutComment, + }), + }) + ); + }); + it("should handle an error response from the PDF API", async () => { (fetch as jest.Mock).mockResolvedValueOnce({ status: 500, diff --git a/services/app-api/libs/authorization.ts b/services/app-api/libs/authorization.ts index 5d1992d1af..5f172dd353 100644 --- a/services/app-api/libs/authorization.ts +++ b/services/app-api/libs/authorization.ts @@ -1,7 +1,5 @@ -import { APIGatewayProxyEvent } from "aws-lambda"; import jwt_decode from "jwt-decode"; -import { UserRoles, RequestMethods } from "../types"; -import { clearLogs } from "./debug-lib"; +import { APIGatewayProxyEvent, UserRoles } from "../types"; interface DecodedToken { "custom:cms_roles": string; diff --git a/services/app-api/libs/debug-lib.ts b/services/app-api/libs/debug-lib.ts index 8ad3b21e98..81afcb2150 100644 --- a/services/app-api/libs/debug-lib.ts +++ b/services/app-api/libs/debug-lib.ts @@ -1,37 +1,64 @@ import util from "util"; -import AWS from "aws-sdk"; -import { APIGatewayProxyEvent } from "aws-lambda"; +import { Logger } from "@smithy/types"; -let logs: { date: Date; string: string }[] = []; +type LogLevel = "trace" | "debug" | "info" | "warn" | "error"; +type LogEntry = { + date: Date; + level: LogLevel; + string: string; +}; -// Log AWS SDK calls -AWS.config.logger = { log: debug }; +const logs: LogEntry[] = []; -export default function debug(...args: any[]) { - logs.push({ - date: new Date(), - string: util.format.apply(null, args), - }); - return logs; -} +const buildLoggerForLevel = (level: LogLevel) => { + return function (...content: any[]) { + logs.push({ + date: new Date(), + level: level, + string: util.format.apply(null, content), + }); -export function init(event: APIGatewayProxyEvent, _context: any) { - logs = []; + /* + * If we have a function logging thousands of messages, + * better to take the console performance hit mid-operation + * than to let memory usage run away as well. + */ + if (logs.length > 99) { + flush(); + } + }; +}; - // Log API event - return debug("API event", { - body: event.body, - pathParameters: event.pathParameters, - queryStringParameters: event.queryStringParameters, - }); -} +/* + * Individual functions are exported to support handler-lib; + * This integrates SDK client logging with lambda logging. + */ +export const trace = buildLoggerForLevel("trace"); +export const debug = buildLoggerForLevel("debug"); +export const info = buildLoggerForLevel("info"); +export const warn = buildLoggerForLevel("warn"); +export const error = buildLoggerForLevel("error"); -export function flush(e: Error) { - logs.forEach(({ date, string }) => console.debug(date, string)); - console.error(e); +export function flush() { + while (logs.length > 0) { + const { date, level, string } = logs.shift()!; + // eslint-disable-next-line no-console + console[level](date, string); + } } -export function clearLogs() { - logs = []; - return logs; -} +/* + * This is only called at the beginning of a lambda handler, + * so the log buffer should be empty anyway. But it doesn't + * hurt to make sure! + */ +export const init = flush; + +/** + * A logger suitable for passing to any AWS client constructor. + * Note that the `trace` log level is excluded. + * + * This logger accumulates log messages in an internal buffer, + * eventually flushing them to the console. + */ +export const logger: Logger = { debug, info, warn, error }; diff --git a/services/app-api/libs/dynamodb-lib.ts b/services/app-api/libs/dynamodb-lib.ts index e48f2176e9..2465505918 100644 --- a/services/app-api/libs/dynamodb-lib.ts +++ b/services/app-api/libs/dynamodb-lib.ts @@ -1,66 +1,71 @@ -import AWS from "aws-sdk"; -import { ServiceConfigurationOptions } from "aws-sdk/lib/service"; +import { DynamoDBClient } from "@aws-sdk/client-dynamodb"; import { - CoreSet, - Measure, - DynamoCreate, - DynamoDelete, - DynamoUpdate, - DynamoFetch, - DynamoScan, -} from "../types"; + DeleteCommand, + DeleteCommandInput, + DynamoDBDocumentClient, + GetCommand, + GetCommandInput, + PutCommand, + PutCommandInput, + QueryCommandInput, + ScanCommandInput, + UpdateCommand, + UpdateCommandInput, + paginateScan, + paginateQuery, +} from "@aws-sdk/lib-dynamodb"; +import { CoreSet, Measure, Banner } from "../types"; +import { logger } from "./debug-lib"; -export function createDbClient() { - const dynamoConfig: AWS.DynamoDB.DocumentClient.DocumentClientOptions & - ServiceConfigurationOptions & - AWS.DynamoDB.ClientApiVersions = {}; +export type QmrDynamoTableType = CoreSet | Measure | Banner; - const endpoint = process.env.DYNAMODB_URL; - if (endpoint) { - dynamoConfig.endpoint = endpoint; - dynamoConfig.accessKeyId = "LOCALFAKEKEY"; // pragma: allowlist secret - dynamoConfig.secretAccessKey = "LOCALFAKESECRET"; // pragma: allowlist secret - } else { - dynamoConfig["region"] = "us-east-1"; - } +const localConfig = { + endpoint: process.env.DYNAMODB_URL, + region: "localhost", + credentials: { + accessKeyId: "LOCALFAKEKEY", // pragma: allowlist secret + secretAccessKey: "LOCALFAKESECRET", // pragma: allowlist secret + }, + logger, +}; - return new AWS.DynamoDB.DocumentClient(dynamoConfig); -} +const awsConfig = { + region: "us-east-1", + logger, +}; -const client = createDbClient(); +export const getConfig = () => { + return process.env.DYNAMODB_URL ? localConfig : awsConfig; +}; + +const client = DynamoDBDocumentClient.from(new DynamoDBClient(getConfig())); export default { - get: async (params: DynamoFetch) => { - const result = await client.get(params).promise(); - return { ...result, Item: result?.Item as Result | undefined }; + put: (params: PutCommandInput) => client.send(new PutCommand(params)), + get: async (params: GetCommandInput) => { + const result = await client.send(new GetCommand(params)); + return result.Item as Result | undefined; }, - put: (params: DynamoCreate) => client.put(params).promise(), - post: (params: DynamoCreate) => client.put(params).promise(), - /** - * Scan operation that continues for all results. More expensive but avoids stopping early when a index is not known. - */ - scan: async (params: DynamoScan) => { - const items = []; - let complete = false; - while (!complete) { - const result = await client.scan(params).promise(); - items.push(...((result?.Items as Result[]) ?? [])); - params.ExclusiveStartKey = result.LastEvaluatedKey; - complete = result.LastEvaluatedKey === undefined; + queryAll: async ( + params: QueryCommandInput + ) => { + let items: Result[] = []; + for await (let page of paginateQuery({ client }, params)) { + items = items.concat((page.Items as Result[]) ?? []); } - return { Items: items, Count: items.length }; + return items; }, - /** - * Scan operation that iterates and includes a LastEvaluatedKey. - * Useful for parsing the results of a scan one page at a time or stopping early. - */ - scanOnce: async (params: DynamoScan) => { - const result = await client.scan(params).promise(); - return { ...result, Items: result?.Items as Result[] | undefined }; + scanAll: async ( + params: ScanCommandInput + ) => { + let items: Result[] = []; + for await (let page of paginateScan({ client }, params)) { + items = items.concat((page.Items as Result[]) ?? []); + } + return items; }, - update: (params: DynamoUpdate) => client.update(params).promise(), - delete: (params: DynamoDelete) => client.delete(params).promise(), - - // unused - query: (params: any) => client.query(params).promise(), + update: (params: UpdateCommandInput) => + client.send(new UpdateCommand(params)), + delete: (params: DeleteCommandInput) => + client.send(new DeleteCommand(params)), }; diff --git a/services/app-api/libs/handler-lib.ts b/services/app-api/libs/handler-lib.ts index 831cbd272e..475fe7bae2 100644 --- a/services/app-api/libs/handler-lib.ts +++ b/services/app-api/libs/handler-lib.ts @@ -1,5 +1,5 @@ -import * as debug from "./debug-lib"; -import { APIGatewayProxyEvent } from "aws-lambda"; +import * as logger from "./debug-lib"; +import { APIGatewayProxyEvent } from "../types"; import { isAuthenticated } from "./authorization"; import { failure, buildResponse } from "./response-lib"; import { Errors, StatusCodes } from "../utils/constants/constants"; @@ -11,8 +11,12 @@ type LambdaFunction = ( export default function handler(lambda: LambdaFunction) { return async function (event: APIGatewayProxyEvent, context: any) { - // Start debugger - debug.init(event, context); + logger.init(); + logger.debug("API event: %O", { + body: event.body, + pathParameters: event.pathParameters, + queryStringParameters: event.queryStringParameters, + }); if (isAuthenticated(event)) { try { @@ -21,10 +25,12 @@ export default function handler(lambda: LambdaFunction) { return buildResponse(status, body); } catch (e: any) { // Print debug messages - debug.flush(e); + logger.error("Error: %O", e); const body = { error: e.message }; return failure(body); + } finally { + logger.flush(); } } else { const body = { error: Errors.UNAUTHORIZED }; diff --git a/services/app-api/libs/kafka-source-lib.js b/services/app-api/libs/kafka-source-lib.js index f3fec0be80..45cae0cf6c 100644 --- a/services/app-api/libs/kafka-source-lib.js +++ b/services/app-api/libs/kafka-source-lib.js @@ -1,4 +1,4 @@ -import AWS from "aws-sdk"; +const dynamoUtils = require("@aws-sdk/util-dynamodb"); const { Kafka } = require("kafkajs"); const STAGE = process.env.STAGE; @@ -56,7 +56,7 @@ class KafkaSourceLib { } unmarshall(r) { - return AWS.DynamoDB.Converter.unmarshall(r, this.unmarshallOptions); + return dynamoUtils.unmarshall(r, this.unmarshallOptions); } createPayload(record) { diff --git a/services/app-api/libs/tests/debug-lib.test.ts b/services/app-api/libs/tests/debug-lib.test.ts index 1e1c674121..85894ee7ae 100644 --- a/services/app-api/libs/tests/debug-lib.test.ts +++ b/services/app-api/libs/tests/debug-lib.test.ts @@ -1,116 +1,75 @@ -import { APIGatewayProxyEvent } from "aws-lambda"; -import { testEvent } from "../../test-util/testEvents"; -import debug, { clearLogs, flush, init } from "../debug-lib"; - -jest.mock("aws-sdk", () => ({ - __esModule: true, - default: { - config: { - logger: { log: undefined }, - }, - }, -})); - -//mock and suppress console calls -const mockedConsoleError = jest.fn(); -const mockedConsoleDebug = jest.fn(); -(global as any).console = { - error: mockedConsoleError, - debug: mockedConsoleDebug, -}; +/* eslint-disable no-console */ +import { + trace, + debug, + info, + warn, + error, + flush, + init, + logger, +} from "../debug-lib"; + +jest.spyOn(console, "trace").mockImplementation(); +jest.spyOn(console, "debug").mockImplementation(); +jest.spyOn(console, "info").mockImplementation(); +jest.spyOn(console, "warn").mockImplementation(); +jest.spyOn(console, "error").mockImplementation(); describe("Debug Library Functions", () => { - afterEach(() => { - clearLogs(); + beforeEach(() => { + jest.clearAllMocks(); + jest.resetModules(); }); - describe("Init Function", () => { - test("logs should have a length of one", () => { - const logs = init({ ...testEvent }, null); + test("Flush should write all logs in the buffer", () => { + debug("test message"); - expect(logs.length).toBe(1); - expect(logs[0].string.length).toBeGreaterThan(0); - }); + expect(console.debug).not.toHaveBeenCalled(); - test("logs should be overridden on init", () => { - const event = { ...testEvent }; + flush(); - debug(event); - debug(event); - debug(event); - const log1 = debug(event); + expect(console.debug).toHaveBeenCalledTimes(1); - const log2 = init(event, null); + flush(); - expect(log1.length).toBe(4); - expect(log2.length).toBe(1); - }); + // No additional calls for the second flush, because the buffer is empty + expect(console.debug).toHaveBeenCalledTimes(1); }); - describe("Flush function", () => { - test("flush should only call error by default", () => { - const error = new Error("test error"); - flush(error); - - expect(mockedConsoleError).toBeCalled(); - expect(mockedConsoleDebug).not.toBeCalled(); - expect(mockedConsoleError).toBeCalledWith(error); - }); - - test("flush should call debug for every log and error once", () => { - const event = { ...testEvent }; - const error = new Error("test error"); - - debug(event); - debug(event); - debug(event); - debug(event); - flush(error); - - expect(mockedConsoleError).toBeCalled(); - expect(mockedConsoleError).toBeCalledWith(error); - - expect(mockedConsoleDebug).toBeCalledTimes(4); - }); + test("Init should ensure an empty buffer", () => { + expect(init).toBe(flush); }); - describe("Debug Function", () => { - test("logs should have a new object", () => { - const logs = debug({ body: "test" }); - - expect(logs.length).toBe(1); - }); + test("Each log level should forward its messages to console", () => { + trace("test"); + debug("test"); + info("test"); + warn("test"); + error("test"); - test("logs should have event structured object", () => { - const event = { ...testEvent }; - debug(event); - debug(event); - debug(event); - const logs = debug(event); + flush(); - expect(logs.length).toBe(4); - expect(logs[0].string.length).toBeGreaterThan(0); - }); + expect(console.trace).toHaveBeenCalled(); + expect(console.debug).toHaveBeenCalled(); + expect(console.info).toHaveBeenCalled(); + expect(console.warn).toHaveBeenCalled(); + expect(console.error).toHaveBeenCalled(); }); - describe("clearLogs Function", () => { - test("logs should be empty", () => { - debug("test"); - debug("test"); - debug("test"); - debug("test"); - const logs = clearLogs(); - - expect(logs.length).toBe(0); - }); + test("AWS-compatible logger should have necessary functions", () => { + expect(logger.debug).toBeDefined(); + expect(logger.info).toBeDefined(); + expect(logger.warn).toBeDefined(); + expect(logger.error).toBeDefined(); + }); - test("only logs after clear should be seen", () => { - debug("test"); - clearLogs(); + test("Logger supports printf-style string formatting", () => { + debug("%s %d %O", "hello", 2, { person: "you" }); + flush(); - debug("test"); - const logs = debug("test"); - expect(logs.length).toBe(2); - }); + const [date, message] = (console.debug as jest.Mock).mock.calls[0]; + expect(date).toBeInstanceOf(Date); + expect(message).toBe(`hello 2 { person: 'you' }`); }); }); diff --git a/services/app-api/libs/tests/dynamodb-lib.test.ts b/services/app-api/libs/tests/dynamodb-lib.test.ts index 7ed533382a..2b06708bd6 100644 --- a/services/app-api/libs/tests/dynamodb-lib.test.ts +++ b/services/app-api/libs/tests/dynamodb-lib.test.ts @@ -1,100 +1,110 @@ -import dynamoLib, { createDbClient } from "../dynamodb-lib"; -import { CoreSetAbbr, MeasureStatus } from "../../types"; -import AWS from "aws-sdk"; - -const mockPromiseCall = jest.fn(); -const mockScanPromiseCall = jest - .fn() - .mockReturnValue({}) - .mockReturnValueOnce({ LastEvaluatedKey: { key: "val" } }); - -jest.mock("aws-sdk", () => ({ - __esModule: true, - default: { - DynamoDB: { - DocumentClient: jest.fn().mockImplementation((config) => { - return { - get: (x: any) => ({ promise: mockPromiseCall }), - put: (x: any) => ({ promise: mockPromiseCall }), - post: (x: any) => ({ promise: mockPromiseCall }), - query: (x: any) => ({ promise: mockPromiseCall }), - scan: (x: any) => ({ promise: mockScanPromiseCall }), - update: (x: any) => ({ promise: mockPromiseCall }), - delete: (x: any) => ({ promise: mockPromiseCall }), - }; - }), - }, - }, -})); - -describe("Test DynamoDB Interaction API Build Structure", () => { - test("API structure should be callable", async () => { - const testKeyTable = { - Key: { compoundKey: "testKey", coreSet: CoreSetAbbr.ACS }, - TableName: "testTable", - }; - const testItem = { - compoundKey: "dynamoKey", - state: "FL", - year: 2019, - coreSet: CoreSetAbbr.ACS, - measure: "event!.pathParameters!.measure!", - createdAt: Date.now(), - lastAltered: Date.now(), - lastAlteredBy: `event.headers["cognito-identity-id"]`, - status: MeasureStatus.COMPLETE, - description: "", - data: {}, - }; - await dynamoLib.query(true); - await dynamoLib.get(testKeyTable); - await dynamoLib.delete(testKeyTable); - await dynamoLib.put({ TableName: "testTable", Item: testItem }); - await dynamoLib.scan({ - ...testKeyTable, - ExpressionAttributeNames: {}, - ExpressionAttributeValues: {}, - }); - await dynamoLib.scanOnce({ - ...testKeyTable, - ExpressionAttributeNames: {}, - ExpressionAttributeValues: {}, - }); - await dynamoLib.update({ - ...testKeyTable, - ExpressionAttributeNames: {}, - ExpressionAttributeValues: {}, - }); - await dynamoLib.post({ - TableName: "", - Item: testItem, - }); +import dynamoLib, { getConfig } from "../dynamodb-lib"; +import { + DeleteCommand, + DynamoDBDocumentClient, + GetCommand, + QueryCommand, + ScanCommand, + ScanCommandInput, + UpdateCommand, +} from "@aws-sdk/lib-dynamodb"; +import { mockClient } from "aws-sdk-client-mock"; + +const dynamoClientMock = mockClient(DynamoDBDocumentClient); + +describe("DynamoDB Library", () => { + let originalUrl: string | undefined; + beforeAll(() => { + originalUrl = process.env.DYNAMODB_URL; + }); + afterAll(() => { + process.env.DYNAMODB_URL = originalUrl; + }); - expect(mockPromiseCall).toHaveBeenCalledTimes(6); - expect(mockScanPromiseCall).toHaveBeenCalledTimes(3); + beforeEach(() => { + dynamoClientMock.reset(); }); - describe("Checking Environment Variable Changes", () => { - test("Check if statement with DYNAMADB_URL undefined", () => { - process.env = { ...process.env, DYNAMODB_URL: undefined }; - jest.resetModules(); + test("Can put", async () => { + const mockPut = jest.fn(); + dynamoClientMock.on(UpdateCommand).callsFake(mockPut); - createDbClient(); - expect(AWS.DynamoDB.DocumentClient).toHaveBeenCalledWith({ - region: "us-east-1", - }); + await dynamoLib.update({ TableName: "foos", Key: { id: "fid" } }); + + expect(mockPut).toHaveBeenCalled(); + }); + + test("Can get", async () => { + const mockItem = { foo: "bar" }; + dynamoClientMock.on(GetCommand).resolves({ + Item: mockItem, }); - test("Check if statement with DYNAMADB_URL set", () => { - process.env = { ...process.env, DYNAMODB_URL: "endpoint" }; - jest.resetModules(); + const foo = await dynamoLib.get({ TableName: "foos", Key: { foo: "bar" } }); + + expect(foo).toBe(mockItem); + }); - createDbClient(); - expect(AWS.DynamoDB.DocumentClient).toHaveBeenCalledWith({ - endpoint: "endpoint", - accessKeyId: "LOCALFAKEKEY", // pragma: allowlist secret - secretAccessKey: "LOCALFAKESECRET", // pragma: allowlist secret - }); + test("Can query", async () => { + const mockItem = { foo: "bar" }; + dynamoClientMock.on(QueryCommand).resolves({ + Items: [mockItem], }); + + const foos = await dynamoLib.queryAll({ TableName: "foos" }); + + expect(foos[0]).toBe(mockItem); + }); + + test("Can scan all", async () => { + const mockKey = {}; + const mockItem1 = { foo: "bar" }; + const mockItem2 = { foo: "baz" }; + const extraCall = jest.fn(); + dynamoClientMock + .on(ScanCommand) + .resolvesOnce({ Items: [mockItem1], LastEvaluatedKey: mockKey }) + .callsFakeOnce((command: ScanCommandInput) => { + expect(command.ExclusiveStartKey).toBe(mockKey); + return Promise.resolve({ Items: [mockItem2] }); + }) + .callsFake(extraCall); + + const result = await dynamoLib.scanAll({ TableName: "foos" }); + + expect(result).toHaveLength(2); + expect(result[0]).toBe(mockItem1); + expect(result[1]).toBe(mockItem2); + expect(extraCall).not.toHaveBeenCalled(); + }); + + test("Can update", async () => { + const mockUpdate = jest.fn(); + dynamoClientMock.on(UpdateCommand).callsFake(mockUpdate); + + await dynamoLib.update({ TableName: "foos", Key: { id: "fid" } }); + + expect(mockUpdate).toHaveBeenCalled(); + }); + + test("Can delete", async () => { + const mockDelete = jest.fn(); + dynamoClientMock.on(DeleteCommand).callsFake(mockDelete); + + await dynamoLib.delete({ TableName: "foos", Key: { id: "fid" } }); + + expect(mockDelete).toHaveBeenCalled(); + }); + + test("Uses local config when appropriate", () => { + process.env.DYNAMODB_URL = "mock url"; + const config = getConfig(); + expect(config).toHaveProperty("region", "localhost"); + }); + + test("Uses AWS config when appropriate", () => { + delete process.env.DYNAMODB_URL; + const config = getConfig(); + expect(config).toHaveProperty("region", "us-east-1"); }); }); diff --git a/services/app-api/libs/tests/handler-lib.test.ts b/services/app-api/libs/tests/handler-lib.test.ts index 314dcb30a6..e1f74dad31 100644 --- a/services/app-api/libs/tests/handler-lib.test.ts +++ b/services/app-api/libs/tests/handler-lib.test.ts @@ -1,11 +1,12 @@ import handlerLib from "../handler-lib"; import { testEvent } from "../../test-util/testEvents"; import { isAuthenticated } from "../authorization"; -import { flush } from "../debug-lib"; +import * as logger from "../debug-lib"; jest.mock("../debug-lib", () => ({ - __esModule: true, init: jest.fn(), + debug: jest.fn(), + error: jest.fn(), flush: jest.fn(), })); @@ -24,6 +25,16 @@ describe("Test Lambda Handler Lib", () => { expect(res.statusCode).toBe(200); expect(res.body).toContain("test"); + expect(logger.init).toHaveBeenCalled(); + expect(logger.debug).toHaveBeenCalledWith( + "API event: %O", + expect.objectContaining({ + body: testEvent.body, + pathParameters: testEvent.pathParameters, + queryStringParameters: testEvent.queryStringParameters, + }) + ); + expect(logger.flush).toHaveBeenCalled(); expect(testFunc).toHaveBeenCalledWith(testEvent, null); }); @@ -50,7 +61,8 @@ describe("Test Lambda Handler Lib", () => { (isAuthenticated as jest.Mock).mockReturnValue(true); const res = await handler(testEvent, null); - expect(flush).toHaveBeenCalledWith(err); + expect(logger.error).toHaveBeenCalledWith("Error: %O", err); + expect(logger.flush).toHaveBeenCalled(); expect(res.statusCode).toBe(500); expect(res.body).toContain("Test Error"); expect(testFunc).toHaveBeenCalledWith(testEvent, null); diff --git a/services/app-api/libs/tests/updateCoreSetProgress.test.ts b/services/app-api/libs/tests/updateCoreSetProgress.test.ts index 0cd777edba..50ce1265a6 100644 --- a/services/app-api/libs/tests/updateCoreSetProgress.test.ts +++ b/services/app-api/libs/tests/updateCoreSetProgress.test.ts @@ -14,13 +14,13 @@ jest.mock("../../handlers/measures/get", () => ({ describe("Test the Update Core Set Progress", () => { test("Test updateCoreSetProgress with length 0", async () => { - const res = await updateCoreSetProgress({}, testEvent, null); - expect(res).toBeUndefined(); + await updateCoreSetProgress([], testEvent, null); + // No exception - we're all good here. }); describe("Test the updateCoreSetProgress with length > 0", () => { test("Test measure.status === complete", async () => { - const coreSet = { ...testCoreSet }; + const coreSet = JSON.parse(JSON.stringify(testCoreSet)); (listMeasures as jest.Mock).mockReturnValue({ body: JSON.stringify({ Items: [ @@ -31,20 +31,19 @@ describe("Test the Update Core Set Progress", () => { ], }), }); - const res = await updateCoreSetProgress( - { Items: [coreSet] }, - testEvent, - null + await updateCoreSetProgress([coreSet], testEvent, null); + expect(coreSet).toEqual( + expect.objectContaining({ + progress: { + numComplete: 1, + numAvailable: 1, + }, + }) ); - expect(res).toStrictEqual({ - Items: [ - { ...coreSet, progress: { ...coreSet.progress, numComplete: 1 } }, - ], - }); }); test("Test measure.status !== complete", async () => { - const coreSet = { ...testCoreSet }; + const coreSet = JSON.parse(JSON.stringify(testCoreSet)); (listMeasures as jest.Mock).mockReturnValue({ body: JSON.stringify({ Items: [ @@ -55,31 +54,32 @@ describe("Test the Update Core Set Progress", () => { ], }), }); - const res = await updateCoreSetProgress( - { Items: [coreSet] }, - testEvent, - null + await updateCoreSetProgress([coreSet], testEvent, null); + + expect(coreSet).toEqual( + expect.objectContaining({ + progress: { + numComplete: 0, + numAvailable: 1, + }, + }) ); - expect(res).toStrictEqual({ - Items: [ - { ...coreSet, progress: { ...coreSet.progress, numComplete: 0 } }, - ], - }); }); test("Test coreSet exists but no associated measures", async () => { - const coreSet = { ...testCoreSet }; + const coreSet = JSON.parse(JSON.stringify(testCoreSet)); (listMeasures as jest.Mock).mockReturnValue({ body: JSON.stringify({}), }); - const res = await updateCoreSetProgress( - { Items: [coreSet] }, - testEvent, - null + await updateCoreSetProgress([coreSet], testEvent, null); + expect(coreSet).toEqual( + expect.objectContaining({ + progress: { + numComplete: 0, + numAvailable: 0, + }, + }) ); - expect(res).toStrictEqual({ - Items: [{ ...coreSet }], - }); }); }); }); diff --git a/services/app-api/libs/updateCoreProgress.ts b/services/app-api/libs/updateCoreProgress.ts index f0cd904255..d345568ecf 100644 --- a/services/app-api/libs/updateCoreProgress.ts +++ b/services/app-api/libs/updateCoreProgress.ts @@ -1,40 +1,32 @@ -import { APIGatewayProxyEvent } from "aws-lambda"; +import { APIGatewayProxyEvent } from "../types"; import { listMeasures } from "../handlers/measures/get"; -import * as Types from "../types"; +import { CoreSet, Measure, MeasureStatus } from "../types"; export const updateCoreSetProgress = async ( - coreSets: Types.DynamoCoreSetList, + coreSets: CoreSet[], event: APIGatewayProxyEvent, context: any ) => { - const array = coreSets.Items; - if (array && array.length > 0) { - for (const coreSet of array) { - event.pathParameters!.coreSet = coreSet.coreSet; - const measuresResponse = await listMeasures(event, context); - const measuresList: Types.DynamoMeasureList = JSON.parse( - measuresResponse.body - ); + for (const coreSet of coreSets) { + event.pathParameters!.coreSet = coreSet.coreSet; + const measuresResponse = await listMeasures(event, context); + const measuresList: Measure[] = JSON.parse(measuresResponse.body).Items; - const measures = measuresList.Items; + const completedAmount = measuresList?.filter( + (measure) => + measure.status === MeasureStatus.COMPLETE && + measure.measure !== "CSQ" && + !measure.placeholder + ).length; - const completedAmount = measures?.filter( - (measure) => - measure.status === Types.MeasureStatus.COMPLETE && - measure.measure !== "CSQ" && - !measure.placeholder - ).length; + const availableAmount = measuresList?.filter( + (measure) => !measure.placeholder && measure.measure !== "CSQ" + ).length; - const availableAmount = measures?.filter( - (measure) => !measure.placeholder && measure.measure !== "CSQ" - ).length; + coreSet.progress!.numComplete = + completedAmount ?? coreSet.progress!.numComplete; - coreSet.progress.numComplete = - completedAmount ?? coreSet.progress.numComplete; - - coreSet.progress.numAvailable = - availableAmount ?? coreSet.progress.numAvailable; - } - return coreSets; + coreSet.progress!.numAvailable = + availableAmount ?? coreSet.progress!.numAvailable; } }; diff --git a/services/app-api/package.json b/services/app-api/package.json index a59aa8f408..2ba8957843 100644 --- a/services/app-api/package.json +++ b/services/app-api/package.json @@ -17,13 +17,12 @@ "url": "https://github.com/AnomalyInnovations/serverless-nodejs-starter.git" }, "devDependencies": { - "@types/aws-lambda": "^8.10.88", "@types/aws4": "^1.11.2", "@types/dompurify": "^3.0.5", "@types/jest": "^27.4.0", "@types/jsdom": "^21.1.6", "@types/prompt-sync": "^4.1.1", - "aws-lambda": "^1.0.7", + "aws-sdk-client-mock": "^3.0.1", "jest": "^27.4.7", "serverless": "^3.12.0", "serverless-api-client-certificate": "^1.0.2", @@ -35,7 +34,9 @@ "typescript": "^4.6.4" }, "dependencies": { - "aws-sdk": "^2.1310.0", + "@aws-sdk/client-dynamodb": "^3.523.0", + "@aws-sdk/lib-dynamodb": "^3.523.0", + "@aws-sdk/util-dynamodb": "^3.523.0", "aws4": "^1.11.0", "cross-fetch": "^4.0.0", "dompurify": "^3.0.9", diff --git a/services/app-api/serverless.yml b/services/app-api/serverless.yml index a78491cd7a..f4a9154a98 100644 --- a/services/app-api/serverless.yml +++ b/services/app-api/serverless.yml @@ -263,10 +263,6 @@ functions: method: post cors: true timeout: 60 - ForceKafkaSync: - handler: handlers/kafka/get/forceKafkaSync.main - timeout: 900 - memorySize: 3072 postKafkaData: handler: handlers/kafka/post/postKafkaData.handler events: diff --git a/services/app-api/test-util/testEvents.ts b/services/app-api/test-util/testEvents.ts index 808787e9ba..59e011a06b 100644 --- a/services/app-api/test-util/testEvents.ts +++ b/services/app-api/test-util/testEvents.ts @@ -1,4 +1,4 @@ -import { APIGatewayProxyEvent } from "aws-lambda"; +import { APIGatewayProxyEvent } from "../types"; import { CoreSet, CoreSetAbbr, Measure, MeasureStatus } from "../types"; export const testEvent: APIGatewayProxyEvent = { @@ -14,50 +14,7 @@ export const testEvent: APIGatewayProxyEvent = { stageVariables: null, queryStringParameters: {}, requestContext: { - accountId: "", - apiId: "", - authorizer: () => {}, - httpMethod: "", - path: "", - protocol: "", - requestId: "", - requestTimeEpoch: 0, - resourceId: "", - resourcePath: "", - stage: "", - connectedAt: 0, - connectionId: "", - domainName: "", - domainPrefix: "", - eventType: "", - extendedRequestId: "", - messageDirection: "", - messageId: "", - requestTime: "", - routeKey: "", - identity: { - accessKey: "", - accountId: "", - apiKey: "", - apiKeyId: "", - caller: "", - cognitoAuthenticationProvider: "", - cognitoAuthenticationType: "", - cognitoIdentityId: "", - cognitoIdentityPoolId: "", - principalOrgId: "", - sourceIp: "", - user: "", - userAgent: "", - userArn: "", - clientCert: { - clientCertPem: "", - issuerDN: "", - serialNumber: "", - subjectDN: "", - validity: { notAfter: "", notBefore: "" }, - }, - }, + /* not here */ }, }; diff --git a/services/app-api/types.ts b/services/app-api/types.ts index 6ff240e856..f59c13290e 100644 --- a/services/app-api/types.ts +++ b/services/app-api/types.ts @@ -1,5 +1,3 @@ -import { Key } from "aws-sdk/clients/dynamodb"; - export interface CoreSet { compoundKey: string; coreSet: CoreSetAbbr; @@ -15,12 +13,6 @@ export interface CoreSet { year: number; } -export interface DynamoCoreSetList { - Items?: CoreSet[]; - Count?: number; - ScannedCount?: number; -} - export interface Measure { compoundKey: string; coreSet: CoreSetAbbr; @@ -35,52 +27,24 @@ export interface Measure { userCreated?: boolean; year: number; placeholder?: boolean; + /** + * The `autoCompleted` property is not present on measures in the database; + * it is set on fetch, according to the metadata in measureList.ts. + */ + autoCompleted?: boolean; } -export interface DynamoMeasureList { - Items?: Measure[]; - Count?: number; - ScannedCount?: number; -} - -export interface DynamoCreate { - TableName: string; - Item: Measure | CoreSet; -} - -export interface DynamoDelete { - TableName: string; - Key: { - compoundKey: string; - coreSet: string; - }; -} - -export interface DynamoUpdate { - TableName: string; - Key: { - compoundKey: string; - coreSet: string; - }; - UpdateExpression?: string; - ExpressionAttributeNames: { [key: string]: string }; - ExpressionAttributeValues: { [key: string]: any }; -} +/** This type subject to change, if/when we move to a multi-banner system. */ +export interface Banner { + key: string; + title: string; + description: string; + startDate: number; + endDate: number; -export interface DynamoScan { - TableName: string; - FilterExpression?: string; - ExpressionAttributeNames: { [key: string]: string }; - ExpressionAttributeValues: { [key: string]: any }; - ExclusiveStartKey?: Key; -} - -export interface DynamoFetch { - TableName: string; - Key: { - compoundKey: string; - coreSet: string; - }; + createdAt: Date; + lastAltered: Date; + lastAlteredBy: string; } export const enum CoreSetAbbr { @@ -110,3 +74,27 @@ export const enum RequestMethods { PUT = "PUT", DELETE = "DELETE", } + +/** + * Abridged copy of the type used by `aws-lambda@1.0.7` (from `@types/aws-lambda@8.10.88`) + * We only use this one type from the package, and we use only a subset of the + * properties. Since `aws-lambda` depends on `aws-sdk` (that is, SDK v2), + * we can save ourselves a big dependency with this small redundancy. + */ +export interface APIGatewayProxyEvent { + body: string | null; + headers: EventParameters; + multiValueHeaders: EventParameters; + httpMethod: string; + isBase64Encoded: boolean; + path: string; + pathParameters: EventParameters | null; + queryStringParameters: EventParameters | null; + multiValueQueryStringParameters: EventParameters | null; + stageVariables: EventParameters | null; + /** The context is complicated, and we don't (as of 2023) use it at all. */ + requestContext: any; + resource: string; +} + +export type EventParameters = Record; diff --git a/services/app-api/utils/testing/setupJest.ts b/services/app-api/utils/testing/setupJest.ts deleted file mode 100644 index 16ecbef49a..0000000000 --- a/services/app-api/utils/testing/setupJest.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const mockDocumentClient = { - get: { promise: jest.fn() }, - query: { promise: jest.fn() }, - put: { promise: jest.fn() }, - delete: { promise: jest.fn() }, -}; diff --git a/services/app-api/yarn.lock b/services/app-api/yarn.lock index 75987d1177..6476c7a98a 100644 --- a/services/app-api/yarn.lock +++ b/services/app-api/yarn.lock @@ -18,6 +18,512 @@ "@jridgewell/gen-mapping" "^0.1.0" "@jridgewell/trace-mapping" "^0.3.9" +"@aws-crypto/crc32@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/crc32/-/crc32-3.0.0.tgz#07300eca214409c33e3ff769cd5697b57fdd38fa" + integrity sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA== + dependencies: + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + tslib "^1.11.1" + +"@aws-crypto/ie11-detection@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz#640ae66b4ec3395cee6a8e94ebcd9f80c24cd688" + integrity sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q== + dependencies: + tslib "^1.11.1" + +"@aws-crypto/sha256-browser@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz#05f160138ab893f1c6ba5be57cfd108f05827766" + integrity sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ== + dependencies: + "@aws-crypto/ie11-detection" "^3.0.0" + "@aws-crypto/sha256-js" "^3.0.0" + "@aws-crypto/supports-web-crypto" "^3.0.0" + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + "@aws-sdk/util-locate-window" "^3.0.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + +"@aws-crypto/sha256-js@3.0.0", "@aws-crypto/sha256-js@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz#f06b84d550d25521e60d2a0e2a90139341e007c2" + integrity sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ== + dependencies: + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + tslib "^1.11.1" + +"@aws-crypto/supports-web-crypto@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz#5d1bf825afa8072af2717c3e455f35cda0103ec2" + integrity sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg== + dependencies: + tslib "^1.11.1" + +"@aws-crypto/util@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/util/-/util-3.0.0.tgz#1c7ca90c29293f0883468ad48117937f0fe5bfb0" + integrity sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w== + dependencies: + "@aws-sdk/types" "^3.222.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + +"@aws-sdk/client-dynamodb@^3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-dynamodb/-/client-dynamodb-3.523.0.tgz#7d41263feac305c88938d11bd6f8f350dc1d5ff7" + integrity sha512-dRmpOyU+xsKjYbPgtiCjut4rKo5anErceZRRPtZdw3vAW7ldqf30p72s1Qp8c2xTNnczRa8nsDmeRTSHMzVCPQ== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/client-sts" "3.523.0" + "@aws-sdk/core" "3.523.0" + "@aws-sdk/credential-provider-node" "3.523.0" + "@aws-sdk/middleware-endpoint-discovery" "3.523.0" + "@aws-sdk/middleware-host-header" "3.523.0" + "@aws-sdk/middleware-logger" "3.523.0" + "@aws-sdk/middleware-recursion-detection" "3.523.0" + "@aws-sdk/middleware-user-agent" "3.523.0" + "@aws-sdk/region-config-resolver" "3.523.0" + "@aws-sdk/types" "3.523.0" + "@aws-sdk/util-endpoints" "3.523.0" + "@aws-sdk/util-user-agent-browser" "3.523.0" + "@aws-sdk/util-user-agent-node" "3.523.0" + "@smithy/config-resolver" "^2.1.3" + "@smithy/core" "^1.3.4" + "@smithy/fetch-http-handler" "^2.4.3" + "@smithy/hash-node" "^2.1.3" + "@smithy/invalid-dependency" "^2.1.3" + "@smithy/middleware-content-length" "^2.1.3" + "@smithy/middleware-endpoint" "^2.4.3" + "@smithy/middleware-retry" "^2.1.3" + "@smithy/middleware-serde" "^2.1.3" + "@smithy/middleware-stack" "^2.1.3" + "@smithy/node-config-provider" "^2.2.3" + "@smithy/node-http-handler" "^2.4.1" + "@smithy/protocol-http" "^3.2.1" + "@smithy/smithy-client" "^2.4.1" + "@smithy/types" "^2.10.1" + "@smithy/url-parser" "^2.1.3" + "@smithy/util-base64" "^2.1.1" + "@smithy/util-body-length-browser" "^2.1.1" + "@smithy/util-body-length-node" "^2.2.1" + "@smithy/util-defaults-mode-browser" "^2.1.3" + "@smithy/util-defaults-mode-node" "^2.2.2" + "@smithy/util-endpoints" "^1.1.3" + "@smithy/util-middleware" "^2.1.3" + "@smithy/util-retry" "^2.1.3" + "@smithy/util-utf8" "^2.1.1" + "@smithy/util-waiter" "^2.1.3" + tslib "^2.5.0" + uuid "^9.0.1" + +"@aws-sdk/client-sso-oidc@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.523.0.tgz#566313f15cb433c25e4f0ee9cda563c09049a759" + integrity sha512-OktkdiuJ5DtYgNrJlo53Tf7pJ+UWfOt7V7or0ije6MysLP18GwlTkbg2UE4EUtfOxt/baXxHMlExB1vmRtlATw== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/client-sts" "3.523.0" + "@aws-sdk/core" "3.523.0" + "@aws-sdk/middleware-host-header" "3.523.0" + "@aws-sdk/middleware-logger" "3.523.0" + "@aws-sdk/middleware-recursion-detection" "3.523.0" + "@aws-sdk/middleware-user-agent" "3.523.0" + "@aws-sdk/region-config-resolver" "3.523.0" + "@aws-sdk/types" "3.523.0" + "@aws-sdk/util-endpoints" "3.523.0" + "@aws-sdk/util-user-agent-browser" "3.523.0" + "@aws-sdk/util-user-agent-node" "3.523.0" + "@smithy/config-resolver" "^2.1.3" + "@smithy/core" "^1.3.4" + "@smithy/fetch-http-handler" "^2.4.3" + "@smithy/hash-node" "^2.1.3" + "@smithy/invalid-dependency" "^2.1.3" + "@smithy/middleware-content-length" "^2.1.3" + "@smithy/middleware-endpoint" "^2.4.3" + "@smithy/middleware-retry" "^2.1.3" + "@smithy/middleware-serde" "^2.1.3" + "@smithy/middleware-stack" "^2.1.3" + "@smithy/node-config-provider" "^2.2.3" + "@smithy/node-http-handler" "^2.4.1" + "@smithy/protocol-http" "^3.2.1" + "@smithy/smithy-client" "^2.4.1" + "@smithy/types" "^2.10.1" + "@smithy/url-parser" "^2.1.3" + "@smithy/util-base64" "^2.1.1" + "@smithy/util-body-length-browser" "^2.1.1" + "@smithy/util-body-length-node" "^2.2.1" + "@smithy/util-defaults-mode-browser" "^2.1.3" + "@smithy/util-defaults-mode-node" "^2.2.2" + "@smithy/util-endpoints" "^1.1.3" + "@smithy/util-middleware" "^2.1.3" + "@smithy/util-retry" "^2.1.3" + "@smithy/util-utf8" "^2.1.1" + tslib "^2.5.0" + +"@aws-sdk/client-sso@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.523.0.tgz#1e4a04324c7e2cf995266281619f3a64ed1deb2c" + integrity sha512-vob/Tk9bIr6VIyzScBWsKpP92ACI6/aOXBL2BITgvRWl5Umqi1jXFtfssj/N2UJHM4CBMRwxIJ33InfN0gPxZw== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/core" "3.523.0" + "@aws-sdk/middleware-host-header" "3.523.0" + "@aws-sdk/middleware-logger" "3.523.0" + "@aws-sdk/middleware-recursion-detection" "3.523.0" + "@aws-sdk/middleware-user-agent" "3.523.0" + "@aws-sdk/region-config-resolver" "3.523.0" + "@aws-sdk/types" "3.523.0" + "@aws-sdk/util-endpoints" "3.523.0" + "@aws-sdk/util-user-agent-browser" "3.523.0" + "@aws-sdk/util-user-agent-node" "3.523.0" + "@smithy/config-resolver" "^2.1.3" + "@smithy/core" "^1.3.4" + "@smithy/fetch-http-handler" "^2.4.3" + "@smithy/hash-node" "^2.1.3" + "@smithy/invalid-dependency" "^2.1.3" + "@smithy/middleware-content-length" "^2.1.3" + "@smithy/middleware-endpoint" "^2.4.3" + "@smithy/middleware-retry" "^2.1.3" + "@smithy/middleware-serde" "^2.1.3" + "@smithy/middleware-stack" "^2.1.3" + "@smithy/node-config-provider" "^2.2.3" + "@smithy/node-http-handler" "^2.4.1" + "@smithy/protocol-http" "^3.2.1" + "@smithy/smithy-client" "^2.4.1" + "@smithy/types" "^2.10.1" + "@smithy/url-parser" "^2.1.3" + "@smithy/util-base64" "^2.1.1" + "@smithy/util-body-length-browser" "^2.1.1" + "@smithy/util-body-length-node" "^2.2.1" + "@smithy/util-defaults-mode-browser" "^2.1.3" + "@smithy/util-defaults-mode-node" "^2.2.2" + "@smithy/util-endpoints" "^1.1.3" + "@smithy/util-middleware" "^2.1.3" + "@smithy/util-retry" "^2.1.3" + "@smithy/util-utf8" "^2.1.1" + tslib "^2.5.0" + +"@aws-sdk/client-sts@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.523.0.tgz#92989ae024368f7bf354f023fe16954804db1848" + integrity sha512-ggAkL8szaJkqD8oOsS68URJ9XMDbLA/INO/NPZJqv9BhmftecJvfy43uUVWGNs6n4YXNzfF0Y+zQ3DT0fZkv9g== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/core" "3.523.0" + "@aws-sdk/middleware-host-header" "3.523.0" + "@aws-sdk/middleware-logger" "3.523.0" + "@aws-sdk/middleware-recursion-detection" "3.523.0" + "@aws-sdk/middleware-user-agent" "3.523.0" + "@aws-sdk/region-config-resolver" "3.523.0" + "@aws-sdk/types" "3.523.0" + "@aws-sdk/util-endpoints" "3.523.0" + "@aws-sdk/util-user-agent-browser" "3.523.0" + "@aws-sdk/util-user-agent-node" "3.523.0" + "@smithy/config-resolver" "^2.1.3" + "@smithy/core" "^1.3.4" + "@smithy/fetch-http-handler" "^2.4.3" + "@smithy/hash-node" "^2.1.3" + "@smithy/invalid-dependency" "^2.1.3" + "@smithy/middleware-content-length" "^2.1.3" + "@smithy/middleware-endpoint" "^2.4.3" + "@smithy/middleware-retry" "^2.1.3" + "@smithy/middleware-serde" "^2.1.3" + "@smithy/middleware-stack" "^2.1.3" + "@smithy/node-config-provider" "^2.2.3" + "@smithy/node-http-handler" "^2.4.1" + "@smithy/protocol-http" "^3.2.1" + "@smithy/smithy-client" "^2.4.1" + "@smithy/types" "^2.10.1" + "@smithy/url-parser" "^2.1.3" + "@smithy/util-base64" "^2.1.1" + "@smithy/util-body-length-browser" "^2.1.1" + "@smithy/util-body-length-node" "^2.2.1" + "@smithy/util-defaults-mode-browser" "^2.1.3" + "@smithy/util-defaults-mode-node" "^2.2.2" + "@smithy/util-endpoints" "^1.1.3" + "@smithy/util-middleware" "^2.1.3" + "@smithy/util-retry" "^2.1.3" + "@smithy/util-utf8" "^2.1.1" + fast-xml-parser "4.2.5" + tslib "^2.5.0" + +"@aws-sdk/core@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.523.0.tgz#d9767982b8162c48bd9780455038637ec9ba2fdc" + integrity sha512-JHa3ngEWkTzZ2YTn6EavcADC8gv6zZU4U9WBAleClh6ioXH0kGMBawZje3y0F0mKyLTfLhFqFUlCV5sngI/Qcw== + dependencies: + "@smithy/core" "^1.3.4" + "@smithy/protocol-http" "^3.2.1" + "@smithy/signature-v4" "^2.1.3" + "@smithy/smithy-client" "^2.4.1" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-env@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.523.0.tgz#4bc04b32c15ff7237ba1de866b96ccea24e433c7" + integrity sha512-Y6DWdH6/OuMDoNKVzZlNeBc6f1Yjk1lYMjANKpIhMbkRCvLJw/PYZKOZa8WpXbTYdgg9XLjKybnLIb3ww3uuzA== + dependencies: + "@aws-sdk/types" "3.523.0" + "@smithy/property-provider" "^2.1.3" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-http@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.523.0.tgz#26a4d6dc4a1c624f6d8291b4baf0a7b3e3428c30" + integrity sha512-6YUtePbn3UFpY9qfVwHFWIVnFvVS5vsbGxxkTO02swvZBvVG4sdG0Xj0AbotUNQNY9QTCN7WkhwIrd50rfDQ9Q== + dependencies: + "@aws-sdk/types" "3.523.0" + "@smithy/fetch-http-handler" "^2.4.3" + "@smithy/node-http-handler" "^2.4.1" + "@smithy/property-provider" "^2.1.3" + "@smithy/protocol-http" "^3.2.1" + "@smithy/smithy-client" "^2.4.1" + "@smithy/types" "^2.10.1" + "@smithy/util-stream" "^2.1.3" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-ini@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.523.0.tgz#73febb2d13ed51543d24316fa2088550aa0aa745" + integrity sha512-dRch5Ts67FFRZY5r9DpiC3PM6BVHv1tRcy1b26hoqfFkxP9xYH3dsTSPBog1azIqaJa2GcXqEvKCqhghFTt4Xg== + dependencies: + "@aws-sdk/client-sts" "3.523.0" + "@aws-sdk/credential-provider-env" "3.523.0" + "@aws-sdk/credential-provider-process" "3.523.0" + "@aws-sdk/credential-provider-sso" "3.523.0" + "@aws-sdk/credential-provider-web-identity" "3.523.0" + "@aws-sdk/types" "3.523.0" + "@smithy/credential-provider-imds" "^2.2.3" + "@smithy/property-provider" "^2.1.3" + "@smithy/shared-ini-file-loader" "^2.3.3" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-node@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.523.0.tgz#b0e65d4b9c56c46f6ffc67f9d2146d5bf96c26be" + integrity sha512-0aW5ylA8pZmvv/8qA/+iel4acEyzSlHRiaHYL3L0qu9SSoe2a92+RHjrxKl6+Sb55eA2mRfQjaN8oOa5xiYyKA== + dependencies: + "@aws-sdk/credential-provider-env" "3.523.0" + "@aws-sdk/credential-provider-http" "3.523.0" + "@aws-sdk/credential-provider-ini" "3.523.0" + "@aws-sdk/credential-provider-process" "3.523.0" + "@aws-sdk/credential-provider-sso" "3.523.0" + "@aws-sdk/credential-provider-web-identity" "3.523.0" + "@aws-sdk/types" "3.523.0" + "@smithy/credential-provider-imds" "^2.2.3" + "@smithy/property-provider" "^2.1.3" + "@smithy/shared-ini-file-loader" "^2.3.3" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-process@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.523.0.tgz#8cf85637f5075065a164d008f392d3ae3539ea23" + integrity sha512-f0LP9KlFmMvPWdKeUKYlZ6FkQAECUeZMmISsv6NKtvPCI9e4O4cLTeR09telwDK8P0HrgcRuZfXM7E30m8re0Q== + dependencies: + "@aws-sdk/types" "3.523.0" + "@smithy/property-provider" "^2.1.3" + "@smithy/shared-ini-file-loader" "^2.3.3" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-sso@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.523.0.tgz#a8ae046a7989be566a5004091dba09f64c68419b" + integrity sha512-/VfOJuI8ImV//W4gr+yieF/4shzWAzWYeaaNu7hv161C5YW7/OoCygwRVHSnF4KKeUGQZomZWwml5zHZ57f8xQ== + dependencies: + "@aws-sdk/client-sso" "3.523.0" + "@aws-sdk/token-providers" "3.523.0" + "@aws-sdk/types" "3.523.0" + "@smithy/property-provider" "^2.1.3" + "@smithy/shared-ini-file-loader" "^2.3.3" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-web-identity@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.523.0.tgz#eb64cdd155267ffede97ceac2d04fb71e3a4c95c" + integrity sha512-EyBwVoTNZrhLRIHly3JnLzy86deT2hHGoxSCrT3+cVcF1Pq3FPp6n9fUkHd6Yel+wFrjpXCRggLddPvajUoXtQ== + dependencies: + "@aws-sdk/client-sts" "3.523.0" + "@aws-sdk/types" "3.523.0" + "@smithy/property-provider" "^2.1.3" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@aws-sdk/endpoint-cache@3.495.0": + version "3.495.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/endpoint-cache/-/endpoint-cache-3.495.0.tgz#f1c59a4315e61394ebd18b3dda211485c07ee7f8" + integrity sha512-XCDrpiS50WaPzPzp7FwsChPHtX9PQQUU4nRzcn2N7IkUtpcFCUx8m1PAZe086VQr6hrbdeE4Z4j8hUPNwVdJGQ== + dependencies: + mnemonist "0.38.3" + tslib "^2.5.0" + +"@aws-sdk/lib-dynamodb@^3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/lib-dynamodb/-/lib-dynamodb-3.523.0.tgz#710c502344b1d422f443462e53dbdfdeb0644230" + integrity sha512-WNAyiyvrr6m6mrH7FfJpMP0bAS/BEkMebALst0blejSfvFQl5aNWQql+sK9xWJwcYHtHEdfvoyZdKeDvx0Lang== + dependencies: + "@aws-sdk/util-dynamodb" "3.523.0" + "@smithy/smithy-client" "^2.4.1" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@aws-sdk/middleware-endpoint-discovery@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.523.0.tgz#b5f8e11f24b4fe2680d1d4074dc3ff0ca34c0c74" + integrity sha512-cAE2l6Sn7VLC+ZFkPaVbGy9leG6VfQVvCkOcYYFxNW5BGvJLl2AerB026xGc8Gc00eCfjgF0TAx/Q0sREhLqvQ== + dependencies: + "@aws-sdk/endpoint-cache" "3.495.0" + "@aws-sdk/types" "3.523.0" + "@smithy/node-config-provider" "^2.2.3" + "@smithy/protocol-http" "^3.2.1" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@aws-sdk/middleware-host-header@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.523.0.tgz#9aaa29edd668905eed8ee8af482b96162dafdeb1" + integrity sha512-4g3q7Ta9sdD9TMUuohBAkbx/e3I/juTqfKi7TPgP+8jxcYX72MOsgemAMHuP6CX27eyj4dpvjH+w4SIVDiDSmg== + dependencies: + "@aws-sdk/types" "3.523.0" + "@smithy/protocol-http" "^3.2.1" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@aws-sdk/middleware-logger@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.523.0.tgz#ad61bfdd73b5983ab8a8926b9c01825bc048babf" + integrity sha512-PeDNJNhfiaZx54LBaLTXzUaJ9LXFwDFFIksipjqjvxMafnoVcQwKbkoPUWLe5ytT4nnL1LogD3s55mERFUsnwg== + dependencies: + "@aws-sdk/types" "3.523.0" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@aws-sdk/middleware-recursion-detection@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.523.0.tgz#21d9ec52700545d7935d6c943cb40bffa69ab4b4" + integrity sha512-nZ3Vt7ehfSDYnrcg/aAfjjvpdE+61B3Zk68i6/hSUIegT3IH9H1vSW67NDKVp+50hcEfzWwM2HMPXxlzuyFyrw== + dependencies: + "@aws-sdk/types" "3.523.0" + "@smithy/protocol-http" "^3.2.1" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@aws-sdk/middleware-user-agent@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.523.0.tgz#fb7da981b54d470245cbb09b9faa4c8e22ba8a47" + integrity sha512-5OoKkmAPNaxLgJuS65gByW1QknGvvXdqzrIMXLsm9LjbsphTOscyvT439qk3Jf08TL4Zlw2x+pZMG7dZYuMAhQ== + dependencies: + "@aws-sdk/types" "3.523.0" + "@aws-sdk/util-endpoints" "3.523.0" + "@smithy/protocol-http" "^3.2.1" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@aws-sdk/region-config-resolver@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/region-config-resolver/-/region-config-resolver-3.523.0.tgz#828c0f20d298c939ce78d970f62cc45c6b05d029" + integrity sha512-IypIAecBc8b4jM0uVBEj90NYaIsc0vuLdSFyH4LPO7is4rQUet4CkkD+S036NvDdcdxBsQ4hJZBmWrqiizMHhQ== + dependencies: + "@aws-sdk/types" "3.523.0" + "@smithy/node-config-provider" "^2.2.3" + "@smithy/types" "^2.10.1" + "@smithy/util-config-provider" "^2.2.1" + "@smithy/util-middleware" "^2.1.3" + tslib "^2.5.0" + +"@aws-sdk/token-providers@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.523.0.tgz#0f981cf3940b3061e822ae840b1c7d590d4e76d7" + integrity sha512-m3sPEnLuGV3JY9A8ytcz90SogVtjxEyIxUDFeswxY4C5wP/36yOq3ivenRu07dH+QIJnBhsQdjnHwJfrIetG6g== + dependencies: + "@aws-sdk/client-sso-oidc" "3.523.0" + "@aws-sdk/types" "3.523.0" + "@smithy/property-provider" "^2.1.3" + "@smithy/shared-ini-file-loader" "^2.3.3" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@aws-sdk/types@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.523.0.tgz#2bb11390023949f31d9211212f41e245a7f03489" + integrity sha512-AqGIu4u+SxPiUuNBp2acCVcq80KDUFjxe6e3cMTvKWTzCbrVk1AXv0dAaJnCmdkWIha6zJDWxpIk/aL4EGhZ9A== + dependencies: + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@aws-sdk/types@^3.222.0": + version "3.468.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.468.0.tgz#f97b34fc92a800d1d8b866f47693ae8f3d46517b" + integrity sha512-rx/9uHI4inRbp2tw3Y4Ih4PNZkVj32h7WneSg3MVgVjAoVD5Zti9KhS5hkvsBxfgmQmg0AQbE+b1sy5WGAgntA== + dependencies: + "@smithy/types" "^2.7.0" + tslib "^2.5.0" + +"@aws-sdk/util-dynamodb@3.523.0", "@aws-sdk/util-dynamodb@^3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-dynamodb/-/util-dynamodb-3.523.0.tgz#79d40d0e1c40716ac8020e98250744f8bfb67704" + integrity sha512-w6wDrUo2V2Ag4MY0bS+7GSkAofrJIvXvRD0rmApq0rN7WCJEOTAoge58ALSJ7Ab8aBzenV/gnH7AhxywmbZx7w== + dependencies: + tslib "^2.5.0" + +"@aws-sdk/util-endpoints@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.523.0.tgz#e57bf5ff6a3c5ffa6df4226018c78de423cbb6bd" + integrity sha512-f4qe4AdafjAZoVGoVt69Jb2rXCgo306OOobSJ/f4bhQ0zgAjGELKJATNRRe0J7P28+ffmSxeuYwM3r4gDkD/QA== + dependencies: + "@aws-sdk/types" "3.523.0" + "@smithy/types" "^2.10.1" + "@smithy/util-endpoints" "^1.1.3" + tslib "^2.5.0" + +"@aws-sdk/util-locate-window@^3.0.0": + version "3.495.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-locate-window/-/util-locate-window-3.495.0.tgz#9034fd8db77991b28ed20e067acdd53e8b8f824b" + integrity sha512-MfaPXT0kLX2tQaR90saBT9fWQq2DHqSSJRzW+MZWsmF+y5LGCOhO22ac/2o6TKSQm7h0HRc2GaADqYYYor62yg== + dependencies: + tslib "^2.5.0" + +"@aws-sdk/util-user-agent-browser@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.523.0.tgz#77188e83f9d470ddf140fe8c5d4d51049c9d5898" + integrity sha512-6ZRNdGHX6+HQFqTbIA5+i8RWzxFyxsZv8D3soRfpdyWIKkzhSz8IyRKXRciwKBJDaC7OX2jzGE90wxRQft27nA== + dependencies: + "@aws-sdk/types" "3.523.0" + "@smithy/types" "^2.10.1" + bowser "^2.11.0" + tslib "^2.5.0" + +"@aws-sdk/util-user-agent-node@3.523.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.523.0.tgz#caabe7adc0693d96592c2ae36d4dd80b8ee62d4f" + integrity sha512-tW7vliJ77EsE8J1bzFpDYCiUyrw2NTcem+J5ddiWD4HA/xNQUyX0CMOXMBZCBA31xLTIchyz0LkZHlDsmB9LUw== + dependencies: + "@aws-sdk/types" "3.523.0" + "@smithy/node-config-provider" "^2.2.3" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@aws-sdk/util-utf8-browser@^3.0.0": + version "3.55.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.55.0.tgz#a045bf1a93f6e0ff9c846631b168ea55bbb37668" + integrity sha512-ljzqJcyjfJpEVSIAxwtIS8xMRUly84BdjlBXyp6cu4G8TUufgjNS31LWdhyGhgmW5vYBNr+LTz0Kwf6J+ou7Ug== + dependencies: + tslib "^2.3.1" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" @@ -764,6 +1270,34 @@ dependencies: type-detect "4.0.8" +"@sinonjs/commons@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3" + integrity sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg== + dependencies: + type-detect "4.0.8" + +"@sinonjs/commons@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd" + integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^10.3.0": + version "10.3.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" + integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== + dependencies: + "@sinonjs/commons" "^3.0.0" + +"@sinonjs/fake-timers@^11.2.2": + version "11.2.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz#50063cc3574f4a27bd8453180a04171c85cc9699" + integrity sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw== + dependencies: + "@sinonjs/commons" "^3.0.0" + "@sinonjs/fake-timers@^8.0.1": version "8.1.0" resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" @@ -771,6 +1305,413 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@sinonjs/samsam@^8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-8.0.0.tgz#0d488c91efb3fa1442e26abea81759dfc8b5ac60" + integrity sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew== + dependencies: + "@sinonjs/commons" "^2.0.0" + lodash.get "^4.4.2" + type-detect "^4.0.8" + +"@sinonjs/text-encoding@^0.7.2": + version "0.7.2" + resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz#5981a8db18b56ba38ef0efb7d995b12aa7b51918" + integrity sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ== + +"@smithy/abort-controller@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/abort-controller/-/abort-controller-2.1.3.tgz#19997b701b36294c8d27bbc5e59167da2c719fae" + integrity sha512-c2aYH2Wu1RVE3rLlVgg2kQOBJGM0WbjReQi5DnPTm2Zb7F0gk7J2aeQeaX2u/lQZoHl6gv8Oac7mt9alU3+f4A== + dependencies: + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@smithy/config-resolver@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/config-resolver/-/config-resolver-2.1.3.tgz#1f2ebe37bf340668dccb2ab04ea44679fad28acb" + integrity sha512-u3TAAUJieDAesbKHN0w+0PazLJNmJLE/oWuuf0DYa5lhJJYLfSzX919Bb/Ul50lZ22h9lS1rFWV+5ubTrnyFQw== + dependencies: + "@smithy/node-config-provider" "^2.2.3" + "@smithy/types" "^2.10.1" + "@smithy/util-config-provider" "^2.2.1" + "@smithy/util-middleware" "^2.1.3" + tslib "^2.5.0" + +"@smithy/core@^1.3.4": + version "1.3.4" + resolved "https://registry.yarnpkg.com/@smithy/core/-/core-1.3.4.tgz#40370036e59b8ae9c9fca5faefac5b175d8501e1" + integrity sha512-A466yS5wzrtL02L5x+XiAu4W77VYsof3pimGoBPgWVyaRf4sE3JvM7TV0htkIywVzRuSd9vIlDkfhgvrW8NhmA== + dependencies: + "@smithy/middleware-endpoint" "^2.4.3" + "@smithy/middleware-retry" "^2.1.3" + "@smithy/middleware-serde" "^2.1.3" + "@smithy/protocol-http" "^3.2.1" + "@smithy/smithy-client" "^2.4.1" + "@smithy/types" "^2.10.1" + "@smithy/util-middleware" "^2.1.3" + tslib "^2.5.0" + +"@smithy/credential-provider-imds@^2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@smithy/credential-provider-imds/-/credential-provider-imds-2.2.3.tgz#65df9420f925e7d76587a70f8a82742ed749154d" + integrity sha512-gTrddTHipIgi4ZeFx8yTMRXzmOMY2lii/h/cnL0o53c+F0wm6kP9b/bsBtKXDsmE95h9w+CiMl+5M5yyBDOEMg== + dependencies: + "@smithy/node-config-provider" "^2.2.3" + "@smithy/property-provider" "^2.1.3" + "@smithy/types" "^2.10.1" + "@smithy/url-parser" "^2.1.3" + tslib "^2.5.0" + +"@smithy/eventstream-codec@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-codec/-/eventstream-codec-2.1.3.tgz#6be114d3c4d94f3bfd2e32cb258851baa6129acf" + integrity sha512-rGlCVuwSDv6qfKH4/lRxFjcZQnIE0LZ3D4lkMHg7ZSltK9rA74r0VuGSvWVQ4N/d70VZPaniFhp4Z14QYZsa+A== + dependencies: + "@aws-crypto/crc32" "3.0.0" + "@smithy/types" "^2.10.1" + "@smithy/util-hex-encoding" "^2.1.1" + tslib "^2.5.0" + +"@smithy/fetch-http-handler@^2.4.3": + version "2.4.3" + resolved "https://registry.yarnpkg.com/@smithy/fetch-http-handler/-/fetch-http-handler-2.4.3.tgz#568bd2031af242fc9172e41dfb364d36d48631d1" + integrity sha512-Fn/KYJFo6L5I4YPG8WQb2hOmExgRmNpVH5IK2zU3JKrY5FKW7y9ar5e0BexiIC9DhSKqKX+HeWq/Y18fq7Dkpw== + dependencies: + "@smithy/protocol-http" "^3.2.1" + "@smithy/querystring-builder" "^2.1.3" + "@smithy/types" "^2.10.1" + "@smithy/util-base64" "^2.1.1" + tslib "^2.5.0" + +"@smithy/hash-node@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/hash-node/-/hash-node-2.1.3.tgz#649b056966e1cba9f738236cbf4f05e8e9820deb" + integrity sha512-FsAPCUj7VNJIdHbSxMd5uiZiF20G2zdSDgrgrDrHqIs/VMxK85Vqk5kMVNNDMCZmMezp6UKnac0B4nAyx7HJ9g== + dependencies: + "@smithy/types" "^2.10.1" + "@smithy/util-buffer-from" "^2.1.1" + "@smithy/util-utf8" "^2.1.1" + tslib "^2.5.0" + +"@smithy/invalid-dependency@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/invalid-dependency/-/invalid-dependency-2.1.3.tgz#0f0895d3db2e03493f933e10c27551f059b92b6c" + integrity sha512-wkra7d/G4CbngV4xsjYyAYOvdAhahQje/WymuQdVEnXFExJopEu7fbL5AEAlBPgWHXwu94VnCSG00gVzRfExyg== + dependencies: + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@smithy/is-array-buffer@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@smithy/is-array-buffer/-/is-array-buffer-2.1.1.tgz#07b4c77ae67ed58a84400c76edd482271f9f957b" + integrity sha512-xozSQrcUinPpNPNPds4S7z/FakDTh1MZWtRP/2vQtYB/u3HYrX2UXuZs+VhaKBd6Vc7g2XPr2ZtwGBNDN6fNKQ== + dependencies: + tslib "^2.5.0" + +"@smithy/middleware-content-length@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/middleware-content-length/-/middleware-content-length-2.1.3.tgz#243d74789a311366948dec5a85b03146ac580c51" + integrity sha512-aJduhkC+dcXxdnv5ZpM3uMmtGmVFKx412R1gbeykS5HXDmRU6oSsyy2SoHENCkfOGKAQOjVE2WVqDJibC0d21g== + dependencies: + "@smithy/protocol-http" "^3.2.1" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@smithy/middleware-endpoint@^2.4.3": + version "2.4.3" + resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-2.4.3.tgz#dfae0b6041079505da564ea80218878508094a0e" + integrity sha512-iwYHQiU4w6nqxvZFBSdy+TpbimbkpLOKPivXZ1Ee2sBz86Q/vE34hlGd5nKUo17P/Yk9Evg9+mj9EXRVHvJoNA== + dependencies: + "@smithy/middleware-serde" "^2.1.3" + "@smithy/node-config-provider" "^2.2.3" + "@smithy/shared-ini-file-loader" "^2.3.3" + "@smithy/types" "^2.10.1" + "@smithy/url-parser" "^2.1.3" + "@smithy/util-middleware" "^2.1.3" + tslib "^2.5.0" + +"@smithy/middleware-retry@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-2.1.3.tgz#8be32f1b314517cbf106d16ea5ebeb3050f1a5f7" + integrity sha512-5Ni2ax/D1x34/Rz1fa8kI/bzpl4iNsoHE5hqMeiYvxcfSS1OVqKlj2lLvFKxvgd9mFhQatiqbuMwsh6R/VSzGw== + dependencies: + "@smithy/node-config-provider" "^2.2.3" + "@smithy/protocol-http" "^3.2.1" + "@smithy/service-error-classification" "^2.1.3" + "@smithy/smithy-client" "^2.4.1" + "@smithy/types" "^2.10.1" + "@smithy/util-middleware" "^2.1.3" + "@smithy/util-retry" "^2.1.3" + tslib "^2.5.0" + uuid "^8.3.2" + +"@smithy/middleware-serde@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/middleware-serde/-/middleware-serde-2.1.3.tgz#dbb3c4257b66fdab3019809106b02f953bd42a44" + integrity sha512-s76LId+TwASrHhUa9QS4k/zeXDUAuNuddKklQzRgumbzge5BftVXHXIqL4wQxKGLocPwfgAOXWx+HdWhQk9hTg== + dependencies: + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@smithy/middleware-stack@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/middleware-stack/-/middleware-stack-2.1.3.tgz#7cf77e6ad5c885bc0b8b0857e9349017d530f7d1" + integrity sha512-opMFufVQgvBSld/b7mD7OOEBxF6STyraVr1xel1j0abVILM8ALJvRoFbqSWHGmaDlRGIiV9Q5cGbWi0sdiEaLQ== + dependencies: + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@smithy/node-config-provider@^2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@smithy/node-config-provider/-/node-config-provider-2.2.3.tgz#6cd1cd704752a5eaa80217e6c84e612cf2598fc8" + integrity sha512-+r8Dn5nq+jLGcayG3zrTxzlk2LJqtCf/F7FDOrjACgOutRpxFxZRkG9QOglRbSm/r1wfn7q4MiTMVdc2r0u3/Q== + dependencies: + "@smithy/property-provider" "^2.1.3" + "@smithy/shared-ini-file-loader" "^2.3.3" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@smithy/node-http-handler@^2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-2.4.1.tgz#08409108460fcfaa9068f78e1ef655d7af952fef" + integrity sha512-HCkb94soYhJMxPCa61wGKgmeKpJ3Gftx1XD6bcWEB2wMV1L9/SkQu/6/ysKBnbOzWRE01FGzwrTxucHypZ8rdg== + dependencies: + "@smithy/abort-controller" "^2.1.3" + "@smithy/protocol-http" "^3.2.1" + "@smithy/querystring-builder" "^2.1.3" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@smithy/property-provider@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/property-provider/-/property-provider-2.1.3.tgz#faaa9b7f605725168493e74600a74beca1b059fb" + integrity sha512-bMz3se+ySKWNrgm7eIiQMa2HO/0fl2D0HvLAdg9pTMcpgp4SqOAh6bz7Ik6y7uQqSrk4rLjIKgbQ6yzYgGehCQ== + dependencies: + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@smithy/protocol-http@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-3.2.1.tgz#946fcd076525f8208d659fbc70e2a32d21ed1291" + integrity sha512-KLrQkEw4yJCeAmAH7hctE8g9KwA7+H2nSJwxgwIxchbp/L0B5exTdOQi9D5HinPLlothoervGmhpYKelZ6AxIA== + dependencies: + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@smithy/querystring-builder@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/querystring-builder/-/querystring-builder-2.1.3.tgz#e64e126f565b2aae6e9abd1bebc9aa0839842e8d" + integrity sha512-kFD3PnNqKELe6m9GRHQw/ftFFSZpnSeQD4qvgDB6BQN6hREHELSosVFUMPN4M3MDKN2jAwk35vXHLoDrNfKu0A== + dependencies: + "@smithy/types" "^2.10.1" + "@smithy/util-uri-escape" "^2.1.1" + tslib "^2.5.0" + +"@smithy/querystring-parser@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/querystring-parser/-/querystring-parser-2.1.3.tgz#2786dfa36ac6c7a691eb651339fbcaf160891e69" + integrity sha512-3+CWJoAqcBMR+yvz6D+Fc5VdoGFtfenW6wqSWATWajrRMGVwJGPT3Vy2eb2bnMktJc4HU4bpjeovFa566P3knQ== + dependencies: + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@smithy/service-error-classification@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/service-error-classification/-/service-error-classification-2.1.3.tgz#13dd43ad56576e2b1b7c5a1581affdb9e34dc8ed" + integrity sha512-iUrpSsem97bbXHHT/v3s7vaq8IIeMo6P6cXdeYHrx0wOJpMeBGQF7CB0mbJSiTm3//iq3L55JiEm8rA7CTVI8A== + dependencies: + "@smithy/types" "^2.10.1" + +"@smithy/shared-ini-file-loader@^2.3.3": + version "2.3.3" + resolved "https://registry.yarnpkg.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.3.3.tgz#d125850d2ac41c47a3b4bd4a5e633a849b78309b" + integrity sha512-umdj358yVatYHG1vxtytCpvXxq3oMQEMYN61RAIfDVD8B26WRsqhucnUUdPl1MWEpLYB+7uDCltrgHZuHJ2kTQ== + dependencies: + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@smithy/signature-v4@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-2.1.3.tgz#ff6b812ce562be97ce182376aeb22e558b64776b" + integrity sha512-Jq4iPPdCmJojZTsPePn4r1ULShh6ONkokLuxp1Lnk4Sq7r7rJp4HlA1LbPBq4bD64TIzQezIpr1X+eh5NYkNxw== + dependencies: + "@smithy/eventstream-codec" "^2.1.3" + "@smithy/is-array-buffer" "^2.1.1" + "@smithy/types" "^2.10.1" + "@smithy/util-hex-encoding" "^2.1.1" + "@smithy/util-middleware" "^2.1.3" + "@smithy/util-uri-escape" "^2.1.1" + "@smithy/util-utf8" "^2.1.1" + tslib "^2.5.0" + +"@smithy/smithy-client@^2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-2.4.1.tgz#8c32c0000922838ebfbfcad638a5ae914d7ef28d" + integrity sha512-dt5wlcym8lryne1jcZ6/Vp41T4gS4nCTzQ91a0Dz1/EXDA64/TwGGp79LkvJNkBbHw0rjiJk83CSH6u1HrTCvQ== + dependencies: + "@smithy/middleware-endpoint" "^2.4.3" + "@smithy/middleware-stack" "^2.1.3" + "@smithy/protocol-http" "^3.2.1" + "@smithy/types" "^2.10.1" + "@smithy/util-stream" "^2.1.3" + tslib "^2.5.0" + +"@smithy/types@^2.10.1": + version "2.10.1" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.10.1.tgz#f2a923fd080447ad2ca19bfd8a77abf15be0b8e8" + integrity sha512-hjQO+4ru4cQ58FluQvKKiyMsFg0A6iRpGm2kqdH8fniyNd2WyanoOsYJfMX/IFLuLxEoW6gnRkNZy1y6fUUhtA== + dependencies: + tslib "^2.5.0" + +"@smithy/types@^2.7.0": + version "2.7.0" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.7.0.tgz#6ed9ba5bff7c4d28c980cff967e6d8456840a4f3" + integrity sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw== + dependencies: + tslib "^2.5.0" + +"@smithy/url-parser@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/url-parser/-/url-parser-2.1.3.tgz#f8a7176fb6fdd38a960d546606576541ae6eb7c0" + integrity sha512-X1NRA4WzK/ihgyzTpeGvI9Wn45y8HmqF4AZ/FazwAv8V203Ex+4lXqcYI70naX9ETqbqKVzFk88W6WJJzCggTQ== + dependencies: + "@smithy/querystring-parser" "^2.1.3" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@smithy/util-base64@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@smithy/util-base64/-/util-base64-2.1.1.tgz#af729085cc9d92ebd54a5d2c5d0aa5a0c31f83bf" + integrity sha512-UfHVpY7qfF/MrgndI5PexSKVTxSZIdz9InghTFa49QOvuu9I52zLPLUHXvHpNuMb1iD2vmc6R+zbv/bdMipR/g== + dependencies: + "@smithy/util-buffer-from" "^2.1.1" + tslib "^2.5.0" + +"@smithy/util-body-length-browser@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@smithy/util-body-length-browser/-/util-body-length-browser-2.1.1.tgz#1fc77072768013ae646415eedb9833cd252d055d" + integrity sha512-ekOGBLvs1VS2d1zM2ER4JEeBWAvIOUKeaFch29UjjJsxmZ/f0L3K3x0dEETgh3Q9bkZNHgT+rkdl/J/VUqSRag== + dependencies: + tslib "^2.5.0" + +"@smithy/util-body-length-node@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@smithy/util-body-length-node/-/util-body-length-node-2.2.1.tgz#a6f5c9911f1c3e23efb340d5ce7a590b62f2056e" + integrity sha512-/ggJG+ta3IDtpNVq4ktmEUtOkH1LW64RHB5B0hcr5ZaWBmo96UX2cIOVbjCqqDickTXqBWZ4ZO0APuaPrD7Abg== + dependencies: + tslib "^2.5.0" + +"@smithy/util-buffer-from@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@smithy/util-buffer-from/-/util-buffer-from-2.1.1.tgz#f9346bf8b23c5ba6f6bdb61dd9db779441ba8d08" + integrity sha512-clhNjbyfqIv9Md2Mg6FffGVrJxw7bgK7s3Iax36xnfVj6cg0fUG7I4RH0XgXJF8bxi+saY5HR21g2UPKSxVCXg== + dependencies: + "@smithy/is-array-buffer" "^2.1.1" + tslib "^2.5.0" + +"@smithy/util-config-provider@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@smithy/util-config-provider/-/util-config-provider-2.2.1.tgz#aea0a80236d6cedaee60473802899cff4a8cc0ba" + integrity sha512-50VL/tx9oYYcjJn/qKqNy7sCtpD0+s8XEBamIFo4mFFTclKMNp+rsnymD796uybjiIquB7VCB/DeafduL0y2kw== + dependencies: + tslib "^2.5.0" + +"@smithy/util-defaults-mode-browser@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.1.3.tgz#600745449db8963c411622a2b7b75dba55bc3f33" + integrity sha512-VSAB+fOLo9/b3Aedi1lNxLPxHjzfMdppc9IpD7rsKN51EkJJzDuqmZu18zC1Jpkmxig21BYFqMTH49i5d7Lsgw== + dependencies: + "@smithy/property-provider" "^2.1.3" + "@smithy/smithy-client" "^2.4.1" + "@smithy/types" "^2.10.1" + bowser "^2.11.0" + tslib "^2.5.0" + +"@smithy/util-defaults-mode-node@^2.2.2": + version "2.2.2" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.2.2.tgz#2531be5f76bf079af3c086db4713217d1781ce78" + integrity sha512-cbfyXbAIXYe6HYUJMAIDB9vV/9R9hBoPBK8M4znvBfCGheS7Uc32XuKFsVTnHsR1FB435Ob9UZgfJgl4A2PJOA== + dependencies: + "@smithy/config-resolver" "^2.1.3" + "@smithy/credential-provider-imds" "^2.2.3" + "@smithy/node-config-provider" "^2.2.3" + "@smithy/property-provider" "^2.1.3" + "@smithy/smithy-client" "^2.4.1" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@smithy/util-endpoints@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@smithy/util-endpoints/-/util-endpoints-1.1.3.tgz#24a811f7f3f3ef217fb9f8297b2abe4e7242d3ff" + integrity sha512-89LfHuyUEVjPo3e42U8P6TeWEkP1KDNs519xWKPEpoPFdIPrg77+0TrmIQWTCLgj7Dbvj5FbRbt+v+6sN5up3g== + dependencies: + "@smithy/node-config-provider" "^2.2.3" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@smithy/util-hex-encoding@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@smithy/util-hex-encoding/-/util-hex-encoding-2.1.1.tgz#978252b9fb242e0a59bae4ead491210688e0d15f" + integrity sha512-3UNdP2pkYUUBGEXzQI9ODTDK+Tcu1BlCyDBaRHwyxhA+8xLP8agEKQq4MGmpjqb4VQAjq9TwlCQX0kP6XDKYLg== + dependencies: + tslib "^2.5.0" + +"@smithy/util-middleware@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/util-middleware/-/util-middleware-2.1.3.tgz#6169d7b1088d2bb29d0129c9146c856a61026e98" + integrity sha512-/+2fm7AZ2ozl5h8wM++ZP0ovE9/tiUUAHIbCfGfb3Zd3+Dyk17WODPKXBeJ/TnK5U+x743QmA0xHzlSm8I/qhw== + dependencies: + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@smithy/util-retry@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/util-retry/-/util-retry-2.1.3.tgz#715a5c02c194ae56b9be49fda510b362fb075af3" + integrity sha512-Kbvd+GEMuozbNUU3B89mb99tbufwREcyx2BOX0X2+qHjq6Gvsah8xSDDgxISDwcOHoDqUWO425F0Uc/QIRhYkg== + dependencies: + "@smithy/service-error-classification" "^2.1.3" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + +"@smithy/util-stream@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-2.1.3.tgz#fd0de1d8dcb0015a95735df7229b4a1ded06b50e" + integrity sha512-HvpEQbP8raTy9n86ZfXiAkf3ezp1c3qeeO//zGqwZdrfaoOpGKQgF2Sv1IqZp7wjhna7pvczWaGUHjcOPuQwKw== + dependencies: + "@smithy/fetch-http-handler" "^2.4.3" + "@smithy/node-http-handler" "^2.4.1" + "@smithy/types" "^2.10.1" + "@smithy/util-base64" "^2.1.1" + "@smithy/util-buffer-from" "^2.1.1" + "@smithy/util-hex-encoding" "^2.1.1" + "@smithy/util-utf8" "^2.1.1" + tslib "^2.5.0" + +"@smithy/util-uri-escape@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@smithy/util-uri-escape/-/util-uri-escape-2.1.1.tgz#7eedc93b73ecda68f12fb9cf92e9fa0fbbed4d83" + integrity sha512-saVzI1h6iRBUVSqtnlOnc9ssU09ypo7n+shdQ8hBTZno/9rZ3AuRYvoHInV57VF7Qn7B+pFJG7qTzFiHxWlWBw== + dependencies: + tslib "^2.5.0" + +"@smithy/util-utf8@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@smithy/util-utf8/-/util-utf8-2.1.1.tgz#690018dd28f47f014114497735e51417ea5900a6" + integrity sha512-BqTpzYEcUMDwAKr7/mVRUtHDhs6ZoXDi9NypMvMfOr/+u1NW7JgqodPDECiiLboEm6bobcPcECxzjtQh865e9A== + dependencies: + "@smithy/util-buffer-from" "^2.1.1" + tslib "^2.5.0" + +"@smithy/util-waiter@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@smithy/util-waiter/-/util-waiter-2.1.3.tgz#b3e4c0374e5ee46ecc9eae7812fa870d7b192897" + integrity sha512-3R0wNFAQQoH9e4m+bVLDYNOst2qNxtxFgq03WoNHWTBOqQT3jFnOBRj1W51Rf563xDA5kwqjziksxn6RKkHB+Q== + dependencies: + "@smithy/abort-controller" "^2.1.3" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" + "@szmarczak/http-timer@^4.0.5": version "4.0.6" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" @@ -813,11 +1754,6 @@ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== -"@types/aws-lambda@^8.10.88": - version "8.10.95" - resolved "https://registry.yarnpkg.com/@types/aws-lambda/-/aws-lambda-8.10.95.tgz#7ba7b22b5967f40ceaf293082bbc3863a06e33f7" - integrity sha512-wGtzLbd04EmqhFjTZmXgLzvmhDdyVU7AMo/JkiPmA2VUdBFQfUBQFCEzaVVK+f1PP5aWx1ejnb7K/8MXYI/frQ== - "@types/aws4@^1.11.2": version "1.11.2" resolved "https://registry.yarnpkg.com/@types/aws4/-/aws4-1.11.2.tgz#7700aabe4646f8868b5d2b20820d9583225e7b78" @@ -975,6 +1911,18 @@ dependencies: "@types/node" "*" +"@types/sinon@^10.0.10": + version "10.0.20" + resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-10.0.20.tgz#f1585debf4c0d99f9938f4111e5479fb74865146" + integrity sha512-2APKKruFNCAZgx3daAyACGzWuJ028VVCUDk6o2rw/Z4PXT0ogwdV4KUegW0MwVs0Zu59auPXbbuBJHF12Sx1Eg== + dependencies: + "@types/sinonjs__fake-timers" "*" + +"@types/sinonjs__fake-timers@*": + version "8.1.5" + resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz#5fd3592ff10c1e9695d377020c033116cc2889f2" + integrity sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ== + "@types/stack-utils@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" @@ -1186,15 +2134,14 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -aws-lambda@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/aws-lambda/-/aws-lambda-1.0.7.tgz#c6b674df47458b5ecd43ab734899ad2e2d457013" - integrity sha512-9GNFMRrEMG5y3Jvv+V4azWvc+qNWdWLTjDdhf/zgMlz8haaaLWv0xeAIWxz9PuWUBawsVxy0zZotjCdR3Xq+2w== +aws-sdk-client-mock@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/aws-sdk-client-mock/-/aws-sdk-client-mock-3.0.1.tgz#f9ecc50ff5190fbe7286155e65ea99ad80f670ff" + integrity sha512-9VAzJLl8mz99KP9HjOm/93d8vznRRUTpJooPBOunRdUAnVYopCe9xmMuu7eVemu8fQ+w6rP7o5bBK1kAFkB2KQ== dependencies: - aws-sdk "^2.814.0" - commander "^3.0.2" - js-yaml "^3.14.1" - watchpack "^2.0.0-beta.10" + "@types/sinon" "^10.0.10" + sinon "^16.1.3" + tslib "^2.1.0" aws-sdk@^2.1303.0: version "2.1325.0" @@ -1212,37 +2159,6 @@ aws-sdk@^2.1303.0: uuid "8.0.0" xml2js "0.4.19" -aws-sdk@^2.1310.0: - version "2.1326.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1326.0.tgz#91da60f08d10e4e1db0640c97bc7d2298fde8f17" - integrity sha512-LSGiO4RSooupHnkvYbPOuOYqwAxmcnYinwIxBz4P1YI8ulhZZ/pypOj/HKqC629UyhY1ndSMtlM1l56U74UclA== - dependencies: - buffer "4.9.2" - events "1.1.1" - ieee754 "1.1.13" - jmespath "0.16.0" - querystring "0.2.0" - sax "1.2.1" - url "0.10.3" - util "^0.12.4" - uuid "8.0.0" - xml2js "0.4.19" - -aws-sdk@^2.814.0: - version "2.1129.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1129.0.tgz#c01dced8d45c4ee1113ea74f7e4af4c2e6bf4a2d" - integrity sha512-gQZaByfW7zKCg1n/kA+xDdLhI/SauaokRTq+lztK1cCCdFkR5CShcKeK/qUgVxjy43mwB7CkeTh1WUr2NMb0jg== - dependencies: - buffer "4.9.2" - events "1.1.1" - ieee754 "1.1.13" - jmespath "0.16.0" - querystring "0.2.0" - sax "1.2.1" - url "0.10.3" - uuid "3.3.2" - xml2js "0.4.19" - aws4@^1.11.0: version "1.11.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" @@ -1353,6 +2269,11 @@ bluebird@^3.7.2: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== +bowser@^2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" + integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1695,11 +2616,6 @@ commander@^2.8.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" - integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== - commander@~4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" @@ -2004,6 +2920,11 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +diff@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531" + integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -2310,6 +3231,13 @@ fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fast-xml-parser@4.2.5: + version "4.2.5" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz#a6747a09296a6cb34f2ae634019bf1738f3b421f" + integrity sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g== + dependencies: + strnum "^1.0.5" + fastest-levenshtein@^1.0.16: version "1.0.16" resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" @@ -2420,9 +3348,9 @@ flat@^5.0.2: integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== follow-redirects@^1.14.0: - version "1.15.4" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" - integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== for-each@^0.3.3: version "0.3.3" @@ -2596,11 +3524,6 @@ glob-parent@^5.1.2, glob-parent@~5.1.2: dependencies: is-glob "^4.0.1" -glob-to-regexp@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" - integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== - glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" @@ -3606,6 +4529,11 @@ jszip@^3.10.1: readable-stream "~2.3.6" setimmediate "^1.0.5" +just-extend@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-6.2.0.tgz#b816abfb3d67ee860482e7401564672558163947" + integrity sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw== + jwt-decode@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-2.2.0.tgz#7d86bd56679f58ce6a84704a657dd392bba81a79" @@ -3688,6 +4616,11 @@ lodash.flatten@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ== + lodash.isplainobject@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" @@ -3889,6 +4822,13 @@ mkdirp@^1.0.3: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +mnemonist@0.38.3: + version "0.38.3" + resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.3.tgz#35ec79c1c1f4357cfda2fe264659c2775ccd7d9d" + integrity sha512-2K9QYubXx/NAjv4VLq1d1Ly8pWNC5L3BrixtdkyTegXWJIqY+zLNDhhX/A+ZwWt70tB1S8H4BE8FLYEFyNoOBw== + dependencies: + obliterator "^1.6.1" + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -3938,6 +4878,17 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +nise@^5.1.4: + version "5.1.9" + resolved "https://registry.yarnpkg.com/nise/-/nise-5.1.9.tgz#0cb73b5e4499d738231a473cd89bd8afbb618139" + integrity sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww== + dependencies: + "@sinonjs/commons" "^3.0.0" + "@sinonjs/fake-timers" "^11.2.2" + "@sinonjs/text-encoding" "^0.7.2" + just-extend "^6.2.0" + path-to-regexp "^6.2.1" + node-dir@^0.1.17: version "0.1.17" resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" @@ -4031,6 +4982,11 @@ object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== +obliterator@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-1.6.1.tgz#dea03e8ab821f6c4d96a299e17aef6a3af994ef3" + integrity sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig== + once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -4197,6 +5153,11 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-to-regexp@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz#d54934d6798eb9e5ef14e7af7962c945906918e5" + integrity sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw== + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -4721,6 +5682,18 @@ simple-git@^3.16.0: "@kwsites/promise-deferred" "^1.1.1" debug "^4.3.4" +sinon@^16.1.3: + version "16.1.3" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-16.1.3.tgz#b760ddafe785356e2847502657b4a0da5501fba8" + integrity sha512-mjnWWeyxcAf9nC0bXcPmiDut+oE8HYridTNzBbF98AYVLmWwGRp2ISEpyhYflG1ifILT+eNn3BmKUJPxjXUPlA== + dependencies: + "@sinonjs/commons" "^3.0.0" + "@sinonjs/fake-timers" "^10.3.0" + "@sinonjs/samsam" "^8.0.0" + diff "^5.1.0" + nise "^5.1.4" + supports-color "^7.2.0" + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -4872,6 +5845,11 @@ strip-outer@^1.0.1: dependencies: escape-string-regexp "^1.0.2" +strnum@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" + integrity sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA== + strtok3@^6.2.4: version "6.3.0" resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.3.0.tgz#358b80ffe6d5d5620e19a073aa78ce947a90f9a0" @@ -4910,7 +5888,7 @@ supports-color@^6.1.0: dependencies: has-flag "^3.0.0" -supports-color@^7.0.0, supports-color@^7.1.0: +supports-color@^7.0.0, supports-color@^7.1.0, supports-color@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== @@ -5129,11 +6107,21 @@ ts-node@^10.7.0: v8-compile-cache-lib "^3.0.0" yn "3.1.1" +tslib@^1.11.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + tslib@^2.1.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== +tslib@^2.3.1, tslib@^2.5.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -5141,7 +6129,7 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -type-detect@4.0.8: +type-detect@4.0.8, type-detect@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== @@ -5252,11 +6240,6 @@ util@^0.12.4: is-typed-array "^1.1.3" which-typed-array "^1.1.2" -uuid@3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== - uuid@8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.0.0.tgz#bc6ccf91b5ff0ac07bbcdbf1c7c4e150db4dbb6c" @@ -5277,6 +6260,11 @@ uuid@^9.0.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== +uuid@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + v8-compile-cache-lib@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" @@ -5326,14 +6314,6 @@ walker@^1.0.7: dependencies: makeerror "1.0.12" -watchpack@^2.0.0-beta.10: - version "2.3.1" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25" - integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA== - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" diff --git a/services/database/scripts/remove2023QualifierHPCAD.ts b/services/database/scripts/remove2023QualifierHPCAD.ts index d3ec8ec6ce..57f3b6648d 100644 --- a/services/database/scripts/remove2023QualifierHPCAD.ts +++ b/services/database/scripts/remove2023QualifierHPCAD.ts @@ -136,7 +136,9 @@ function buildClient(isLocal: boolean) { new DynamoDBClient({ region: "us-east-1", logger: { - debug: console.debug, + debug: () => { + /* Dynamo's debug logs are extremely noisy */ + }, info: console.info, warn: console.warn, error: console.error, diff --git a/services/database/scripts/removeNullOPM.ts b/services/database/scripts/removeNullOPM.ts index cdc0b9369f..29ba2c6aba 100644 --- a/services/database/scripts/removeNullOPM.ts +++ b/services/database/scripts/removeNullOPM.ts @@ -1,40 +1,31 @@ +import { DynamoDBClient } from "@aws-sdk/client-dynamodb"; +import { + DynamoDBDocumentClient, + UpdateCommand, + QueryCommand, +} from "@aws-sdk/lib-dynamodb"; import prompt from "prompt-sync"; -import AWS from "aws-sdk"; -import { ServiceConfigurationOptions } from "aws-sdk/lib/service"; /*** * Run with `npx tsx removeNullOPM.ts` */ const removeNullOPM = async () => { - const dynamoConfig: AWS.DynamoDB.DocumentClient.DocumentClientOptions & - ServiceConfigurationOptions & - AWS.DynamoDB.ClientApiVersions = {}; - - const endpoint = process.env.DYNAMODB_URL; - if (endpoint) { - dynamoConfig.endpoint = endpoint; - dynamoConfig.accessKeyId = "LOCALFAKEKEY"; // pragma: allowlist secret - dynamoConfig.secretAccessKey = "LOCALFAKESECRET"; // pragma: allowlist secret - } else { - dynamoConfig["region"] = "us-east-1"; - } - - const client = new AWS.DynamoDB.DocumentClient(dynamoConfig); + const dbClient = buildClient(!!process.env.DYNAMODB_URL); const ratesField = "OtherPerformanceMeasure-Rates"; const p = prompt(); const measureID = p("Measure ID to clean: "); const tableName = p("What table would you like to modify: "); - const foundMeasure = await client - .query({ + const foundMeasure = await dbClient.send( + new QueryCommand({ TableName: tableName, KeyConditionExpression: "compoundKey = :compoundKey", ExpressionAttributeValues: { ":compoundKey": measureID, }, }) - .promise(); + ); if (foundMeasure.Items && foundMeasure.Items.length > 0) { const opmRates: any[] = foundMeasure.Items[0].data[ratesField]; @@ -55,9 +46,38 @@ const removeNullOPM = async () => { "#opmRates": ratesField, }, }; - await client.update(params).promise(); + await dbClient.send(new UpdateCommand(params)); console.log(`Removed null values from OPM Rates in measure ${measureID}'`); } }; removeNullOPM(); + +function buildClient(isLocal: boolean) { + if (isLocal) { + return DynamoDBDocumentClient.from( + new DynamoDBClient({ + region: "localhost", + endpoint: "http://localhost:8000", + credentials: { + accessKeyId: "LOCALFAKEKEY", // pragma: allowlist secret + secretAccessKey: "LOCALFAKESECRET", // pragma: allowlist secret + }, + }) + ); + } else { + return DynamoDBDocumentClient.from( + new DynamoDBClient({ + region: "us-east-1", + logger: { + debug: () => { + /* Dynamo's debug logs are extremely noisy */ + }, + info: console.info, + warn: console.warn, + error: console.error, + }, + }) + ); + } +} diff --git a/services/ui-auth/handlers/createUsers.js b/services/ui-auth/handlers/createUsers.js index 77c2cadd42..e5b0527aa6 100644 --- a/services/ui-auth/handlers/createUsers.js +++ b/services/ui-auth/handlers/createUsers.js @@ -27,11 +27,26 @@ async function myHandler(event, context, callback) { UserAttributes: users[i].attributes, }; - await cognitolib.createUser(poolData); - //userCreate must set a temp password first, calling setPassword to set the password configured in SSM for consistent dev login - await cognitolib.setPassword(passwordData); - //if user exists and attributes are updated in this file updateUserAttributes is needed to update the attributes - await cognitolib.updateUserAttributes(attributeData); + try { + // This may error if the user already exists + await cognitolib.createUser(poolData); + } catch { + /* swallow this exception and continue */ + } + + try { + //userCreate must set a temp password first, calling setPassword to set the password configured in SSM for consistent dev login + await cognitolib.setPassword(passwordData); + } catch { + /* swallow this exception and continue */ + } + + try { + //if user exists and attributes are updated in this file updateUserAttributes is needed to update the attributes + await cognitolib.updateUserAttributes(attributeData); + } catch { + /* swallow this exception and continue */ + } } } diff --git a/services/ui-auth/libs/cognito-lib.js b/services/ui-auth/libs/cognito-lib.js index d9803f892e..f944ef20d3 100644 --- a/services/ui-auth/libs/cognito-lib.js +++ b/services/ui-auth/libs/cognito-lib.js @@ -1,58 +1,31 @@ -var aws = require("aws-sdk"); -const COGNITO_CLIENT = new aws.CognitoIdentityServiceProvider({ +const { + CognitoIdentityProviderClient, + AdminCreateUserCommand, + AdminSetUserPasswordCommand, + AdminUpdateUserAttributesCommand, +} = require("@aws-sdk/client-cognito-identity-provider"); + +const COGNITO_CLIENT = new CognitoIdentityProviderClient({ apiVersion: "2016-04-19", region: "us-east-1", + logger: { + debug: () => { + /* Debug logs are very noisy */ + }, + info: console.info, // eslint-disable-line no-console + warn: console.warn, // eslint-disable-line no-console + error: console.error, // eslint-disable-line no-console + }, }); export async function createUser(params) { - await new Promise((resolve, reject) => { - COGNITO_CLIENT.adminCreateUser(params, function (err, data) { - var response; - if (err) { - console.log("FAILED ", err, err.stack); // an error occurred - response = { statusCode: 500, body: { message: "FAILED", error: err } }; - resolve(response); //if user already exists, we still continue and ignore - } else { - console.log("SUCCESS", data); // successful response - response = { statusCode: 200, body: { message: "SUCCESS" } }; - resolve(response); - } - }); - }); + await COGNITO_CLIENT.send(new AdminCreateUserCommand(params)); } export async function setPassword(params) { - await new Promise((resolve, reject) => { - COGNITO_CLIENT.adminSetUserPassword(params, function (err, data) { - if (err) { - console.log("FAILED to update password", err, err.stack); // an error occurred - var response = { - statusCode: 500, - body: { message: "FAILED", error: err }, - }; - reject(response); - } else { - console.log("SUCCESS", data); - resolve(); - } - }); - }); + await COGNITO_CLIENT.send(new AdminSetUserPasswordCommand(params)); } export async function updateUserAttributes(params) { - await new Promise((resolve, reject) => { - COGNITO_CLIENT.adminUpdateUserAttributes(params, function (err, data) { - if (err) { - console.log("FAILED to update user attributes", err, err.stack); // an error occurred - var response = { - statusCode: 500, - body: { message: "FAILED", error: err }, - }; - reject(response); - } else { - console.log("SUCCESS", data); - resolve(); - } - }); - }); + await COGNITO_CLIENT.send(new AdminUpdateUserAttributesCommand(params)); } diff --git a/services/ui-auth/libs/users.json b/services/ui-auth/libs/users.json index 4bc66da306..904f1a692b 100644 --- a/services/ui-auth/libs/users.json +++ b/services/ui-auth/libs/users.json @@ -1200,5 +1200,34 @@ "Value": "VI" } ] + }, + { + "username": "stateuserNC@test.com", + "attributes": [ + { + "Name": "email", + "Value": "stateuserNC@test.com" + }, + { + "Name": "given_name", + "Value": "David" + }, + { + "Name": "family_name", + "Value": "NC" + }, + { + "Name": "email_verified", + "Value": "true" + }, + { + "Name": "custom:cms_roles", + "Value": "mdctqmr-state-user" + }, + { + "Name": "custom:cms_state", + "Value": "NC" + } + ] } ] diff --git a/services/ui-auth/package.json b/services/ui-auth/package.json index f5372e61e2..dc1d50b28b 100644 --- a/services/ui-auth/package.json +++ b/services/ui-auth/package.json @@ -12,7 +12,7 @@ "serverless-s3-bucket-helper": "Enterprise-CMCS/serverless-s3-bucket-helper#0.1.1" }, "dependencies": { - "aws-sdk": "^2.1531.0", + "@aws-sdk/client-cognito-identity-provider": "^3.525.0", "xml2js": "0.6.0" } } diff --git a/services/ui-auth/yarn.lock b/services/ui-auth/yarn.lock index f44e75cdd7..1c2af32c31 100644 --- a/services/ui-auth/yarn.lock +++ b/services/ui-auth/yarn.lock @@ -2,171 +2,868 @@ # yarn lockfile v1 -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== - -aws-sdk@^2.1531.0: - version "2.1545.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1545.0.tgz#8678ae8117a426d4a6602408e7f47f176356d7ca" - integrity sha512-iDUv6ksG7lTA0l/HlOgYdO6vfYFA1D2/JzAEXSdgKY0C901WgJqBtfs2CncOkCgDe2CjmlMuqciBzAfxCIiKFA== - dependencies: - buffer "4.9.2" - events "1.1.1" - ieee754 "1.1.13" - jmespath "0.16.0" - querystring "0.2.0" - sax "1.2.1" - url "0.10.3" - util "^0.12.4" - uuid "8.0.0" - xml2js "0.6.2" - -base64-js@^1.0.2: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -buffer@4.9.2: - version "4.9.2" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" - integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - -call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -events@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" - integrity sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw== - -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" - integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== +"@aws-crypto/crc32@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/crc32/-/crc32-3.0.0.tgz#07300eca214409c33e3ff769cd5697b57fdd38fa" + integrity sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA== + dependencies: + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + tslib "^1.11.1" + +"@aws-crypto/ie11-detection@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz#640ae66b4ec3395cee6a8e94ebcd9f80c24cd688" + integrity sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q== + dependencies: + tslib "^1.11.1" + +"@aws-crypto/sha256-browser@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz#05f160138ab893f1c6ba5be57cfd108f05827766" + integrity sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ== + dependencies: + "@aws-crypto/ie11-detection" "^3.0.0" + "@aws-crypto/sha256-js" "^3.0.0" + "@aws-crypto/supports-web-crypto" "^3.0.0" + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + "@aws-sdk/util-locate-window" "^3.0.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + +"@aws-crypto/sha256-js@3.0.0", "@aws-crypto/sha256-js@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz#f06b84d550d25521e60d2a0e2a90139341e007c2" + integrity sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ== + dependencies: + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + tslib "^1.11.1" + +"@aws-crypto/supports-web-crypto@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz#5d1bf825afa8072af2717c3e455f35cda0103ec2" + integrity sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg== + dependencies: + tslib "^1.11.1" + +"@aws-crypto/util@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/util/-/util-3.0.0.tgz#1c7ca90c29293f0883468ad48117937f0fe5bfb0" + integrity sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w== + dependencies: + "@aws-sdk/types" "^3.222.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + +"@aws-sdk/client-cognito-identity-provider@^3.525.0": + version "3.540.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-cognito-identity-provider/-/client-cognito-identity-provider-3.540.0.tgz#f1202d3b44d3905765877cebb31265181713b37e" + integrity sha512-qjsDtoGbUjrdLuWYOq3ImyuuLnS2EtgT2ThkkaG3weoKkFXKHc0wGWUYSwqWsVvzkTWKT6NWnN7NCt1zAVbBCw== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/client-sts" "3.540.0" + "@aws-sdk/core" "3.535.0" + "@aws-sdk/credential-provider-node" "3.540.0" + "@aws-sdk/middleware-host-header" "3.535.0" + "@aws-sdk/middleware-logger" "3.535.0" + "@aws-sdk/middleware-recursion-detection" "3.535.0" + "@aws-sdk/middleware-user-agent" "3.540.0" + "@aws-sdk/region-config-resolver" "3.535.0" + "@aws-sdk/types" "3.535.0" + "@aws-sdk/util-endpoints" "3.540.0" + "@aws-sdk/util-user-agent-browser" "3.535.0" + "@aws-sdk/util-user-agent-node" "3.535.0" + "@smithy/config-resolver" "^2.2.0" + "@smithy/core" "^1.4.0" + "@smithy/fetch-http-handler" "^2.5.0" + "@smithy/hash-node" "^2.2.0" + "@smithy/invalid-dependency" "^2.2.0" + "@smithy/middleware-content-length" "^2.2.0" + "@smithy/middleware-endpoint" "^2.5.0" + "@smithy/middleware-retry" "^2.2.0" + "@smithy/middleware-serde" "^2.3.0" + "@smithy/middleware-stack" "^2.2.0" + "@smithy/node-config-provider" "^2.3.0" + "@smithy/node-http-handler" "^2.5.0" + "@smithy/protocol-http" "^3.3.0" + "@smithy/smithy-client" "^2.5.0" + "@smithy/types" "^2.12.0" + "@smithy/url-parser" "^2.2.0" + "@smithy/util-base64" "^2.3.0" + "@smithy/util-body-length-browser" "^2.2.0" + "@smithy/util-body-length-node" "^2.3.0" + "@smithy/util-defaults-mode-browser" "^2.2.0" + "@smithy/util-defaults-mode-node" "^2.3.0" + "@smithy/util-endpoints" "^1.2.0" + "@smithy/util-middleware" "^2.2.0" + "@smithy/util-retry" "^2.2.0" + "@smithy/util-utf8" "^2.3.0" + tslib "^2.6.2" + +"@aws-sdk/client-sso-oidc@3.540.0": + version "3.540.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.540.0.tgz#e4c52889d33ca969add269011b790f2d634fb6d2" + integrity sha512-LZYK0lBRQK8D8M3Sqc96XiXkAV2v70zhTtF6weyzEpgwxZMfSuFJjs0jFyhaeZBZbZv7BBghIdhJ5TPavNxGMQ== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/client-sts" "3.540.0" + "@aws-sdk/core" "3.535.0" + "@aws-sdk/middleware-host-header" "3.535.0" + "@aws-sdk/middleware-logger" "3.535.0" + "@aws-sdk/middleware-recursion-detection" "3.535.0" + "@aws-sdk/middleware-user-agent" "3.540.0" + "@aws-sdk/region-config-resolver" "3.535.0" + "@aws-sdk/types" "3.535.0" + "@aws-sdk/util-endpoints" "3.540.0" + "@aws-sdk/util-user-agent-browser" "3.535.0" + "@aws-sdk/util-user-agent-node" "3.535.0" + "@smithy/config-resolver" "^2.2.0" + "@smithy/core" "^1.4.0" + "@smithy/fetch-http-handler" "^2.5.0" + "@smithy/hash-node" "^2.2.0" + "@smithy/invalid-dependency" "^2.2.0" + "@smithy/middleware-content-length" "^2.2.0" + "@smithy/middleware-endpoint" "^2.5.0" + "@smithy/middleware-retry" "^2.2.0" + "@smithy/middleware-serde" "^2.3.0" + "@smithy/middleware-stack" "^2.2.0" + "@smithy/node-config-provider" "^2.3.0" + "@smithy/node-http-handler" "^2.5.0" + "@smithy/protocol-http" "^3.3.0" + "@smithy/smithy-client" "^2.5.0" + "@smithy/types" "^2.12.0" + "@smithy/url-parser" "^2.2.0" + "@smithy/util-base64" "^2.3.0" + "@smithy/util-body-length-browser" "^2.2.0" + "@smithy/util-body-length-node" "^2.3.0" + "@smithy/util-defaults-mode-browser" "^2.2.0" + "@smithy/util-defaults-mode-node" "^2.3.0" + "@smithy/util-endpoints" "^1.2.0" + "@smithy/util-middleware" "^2.2.0" + "@smithy/util-retry" "^2.2.0" + "@smithy/util-utf8" "^2.3.0" + tslib "^2.6.2" + +"@aws-sdk/client-sso@3.540.0": + version "3.540.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.540.0.tgz#732a7f325de3905a719c20ce05e555b445f82b4a" + integrity sha512-rrQZMuw4sxIo3eyAUUzPQRA336mPRnrAeSlSdVHBKZD8Fjvoy0lYry2vNhkPLpFZLso1J66KRyuIv4LzRR3v1Q== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/core" "3.535.0" + "@aws-sdk/middleware-host-header" "3.535.0" + "@aws-sdk/middleware-logger" "3.535.0" + "@aws-sdk/middleware-recursion-detection" "3.535.0" + "@aws-sdk/middleware-user-agent" "3.540.0" + "@aws-sdk/region-config-resolver" "3.535.0" + "@aws-sdk/types" "3.535.0" + "@aws-sdk/util-endpoints" "3.540.0" + "@aws-sdk/util-user-agent-browser" "3.535.0" + "@aws-sdk/util-user-agent-node" "3.535.0" + "@smithy/config-resolver" "^2.2.0" + "@smithy/core" "^1.4.0" + "@smithy/fetch-http-handler" "^2.5.0" + "@smithy/hash-node" "^2.2.0" + "@smithy/invalid-dependency" "^2.2.0" + "@smithy/middleware-content-length" "^2.2.0" + "@smithy/middleware-endpoint" "^2.5.0" + "@smithy/middleware-retry" "^2.2.0" + "@smithy/middleware-serde" "^2.3.0" + "@smithy/middleware-stack" "^2.2.0" + "@smithy/node-config-provider" "^2.3.0" + "@smithy/node-http-handler" "^2.5.0" + "@smithy/protocol-http" "^3.3.0" + "@smithy/smithy-client" "^2.5.0" + "@smithy/types" "^2.12.0" + "@smithy/url-parser" "^2.2.0" + "@smithy/util-base64" "^2.3.0" + "@smithy/util-body-length-browser" "^2.2.0" + "@smithy/util-body-length-node" "^2.3.0" + "@smithy/util-defaults-mode-browser" "^2.2.0" + "@smithy/util-defaults-mode-node" "^2.3.0" + "@smithy/util-endpoints" "^1.2.0" + "@smithy/util-middleware" "^2.2.0" + "@smithy/util-retry" "^2.2.0" + "@smithy/util-utf8" "^2.3.0" + tslib "^2.6.2" + +"@aws-sdk/client-sts@3.540.0": + version "3.540.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.540.0.tgz#16ce14db1c5387be3ad9be6dd4f8ed33b63193c8" + integrity sha512-ITHUQxvpqfQX6obfpIi3KYGzZYfe/I5Ixjfxoi5lB7ISCtmxqObKB1fzD93wonkMJytJ7LUO8panZl/ojiJ1uw== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/core" "3.535.0" + "@aws-sdk/middleware-host-header" "3.535.0" + "@aws-sdk/middleware-logger" "3.535.0" + "@aws-sdk/middleware-recursion-detection" "3.535.0" + "@aws-sdk/middleware-user-agent" "3.540.0" + "@aws-sdk/region-config-resolver" "3.535.0" + "@aws-sdk/types" "3.535.0" + "@aws-sdk/util-endpoints" "3.540.0" + "@aws-sdk/util-user-agent-browser" "3.535.0" + "@aws-sdk/util-user-agent-node" "3.535.0" + "@smithy/config-resolver" "^2.2.0" + "@smithy/core" "^1.4.0" + "@smithy/fetch-http-handler" "^2.5.0" + "@smithy/hash-node" "^2.2.0" + "@smithy/invalid-dependency" "^2.2.0" + "@smithy/middleware-content-length" "^2.2.0" + "@smithy/middleware-endpoint" "^2.5.0" + "@smithy/middleware-retry" "^2.2.0" + "@smithy/middleware-serde" "^2.3.0" + "@smithy/middleware-stack" "^2.2.0" + "@smithy/node-config-provider" "^2.3.0" + "@smithy/node-http-handler" "^2.5.0" + "@smithy/protocol-http" "^3.3.0" + "@smithy/smithy-client" "^2.5.0" + "@smithy/types" "^2.12.0" + "@smithy/url-parser" "^2.2.0" + "@smithy/util-base64" "^2.3.0" + "@smithy/util-body-length-browser" "^2.2.0" + "@smithy/util-body-length-node" "^2.3.0" + "@smithy/util-defaults-mode-browser" "^2.2.0" + "@smithy/util-defaults-mode-node" "^2.3.0" + "@smithy/util-endpoints" "^1.2.0" + "@smithy/util-middleware" "^2.2.0" + "@smithy/util-retry" "^2.2.0" + "@smithy/util-utf8" "^2.3.0" + tslib "^2.6.2" + +"@aws-sdk/core@3.535.0": + version "3.535.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.535.0.tgz#f3a726c297cea9634d19a1db4e958c918c506c8b" + integrity sha512-+Yusa9HziuaEDta1UaLEtMAtmgvxdxhPn7jgfRY6PplqAqgsfa5FR83sxy5qr2q7xjQTwHtV4MjQVuOjG9JsLw== + dependencies: + "@smithy/core" "^1.4.0" + "@smithy/protocol-http" "^3.3.0" + "@smithy/signature-v4" "^2.2.0" + "@smithy/smithy-client" "^2.5.0" + "@smithy/types" "^2.12.0" + fast-xml-parser "4.2.5" + tslib "^2.6.2" + +"@aws-sdk/credential-provider-env@3.535.0": + version "3.535.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.535.0.tgz#26248e263a8107953d5496cb3760d4e7c877abcf" + integrity sha512-XppwO8c0GCGSAvdzyJOhbtktSEaShg14VJKg8mpMa1XcgqzmcqqHQjtDWbx5rZheY1VdpXZhpEzJkB6LpQejpA== + dependencies: + "@aws-sdk/types" "3.535.0" + "@smithy/property-provider" "^2.2.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@aws-sdk/credential-provider-http@3.535.0": + version "3.535.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.535.0.tgz#0a42f6b1a61d927bbce9f4afd25112f486bd05da" + integrity sha512-kdj1wCmOMZ29jSlUskRqN04S6fJ4dvt0Nq9Z32SA6wO7UG8ht6Ot9h/au/eTWJM3E1somZ7D771oK7dQt9b8yw== + dependencies: + "@aws-sdk/types" "3.535.0" + "@smithy/fetch-http-handler" "^2.5.0" + "@smithy/node-http-handler" "^2.5.0" + "@smithy/property-provider" "^2.2.0" + "@smithy/protocol-http" "^3.3.0" + "@smithy/smithy-client" "^2.5.0" + "@smithy/types" "^2.12.0" + "@smithy/util-stream" "^2.2.0" + tslib "^2.6.2" + +"@aws-sdk/credential-provider-ini@3.540.0": + version "3.540.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.540.0.tgz#8e17b23bf242152775db1473f7d2952beb6a5ef9" + integrity sha512-igN/RbsnulIBwqXbwsWmR3srqmtbPF1dm+JteGvUY31FW65fTVvWvSr945Y/cf1UbhPmIQXntlsqESqpkhTHwg== + dependencies: + "@aws-sdk/client-sts" "3.540.0" + "@aws-sdk/credential-provider-env" "3.535.0" + "@aws-sdk/credential-provider-process" "3.535.0" + "@aws-sdk/credential-provider-sso" "3.540.0" + "@aws-sdk/credential-provider-web-identity" "3.540.0" + "@aws-sdk/types" "3.535.0" + "@smithy/credential-provider-imds" "^2.3.0" + "@smithy/property-provider" "^2.2.0" + "@smithy/shared-ini-file-loader" "^2.4.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@aws-sdk/credential-provider-node@3.540.0": + version "3.540.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.540.0.tgz#e6fd3404de68e7f9580f01aa542b16e9abc58e5c" + integrity sha512-HKQZJbLHlrHX9A0B1poiYNXIIQfy8whTjuosTCYKPDBhhUyVAQfxy/KG726j0v43IhaNPLgTGZCJve4hAsazSw== + dependencies: + "@aws-sdk/credential-provider-env" "3.535.0" + "@aws-sdk/credential-provider-http" "3.535.0" + "@aws-sdk/credential-provider-ini" "3.540.0" + "@aws-sdk/credential-provider-process" "3.535.0" + "@aws-sdk/credential-provider-sso" "3.540.0" + "@aws-sdk/credential-provider-web-identity" "3.540.0" + "@aws-sdk/types" "3.535.0" + "@smithy/credential-provider-imds" "^2.3.0" + "@smithy/property-provider" "^2.2.0" + "@smithy/shared-ini-file-loader" "^2.4.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@aws-sdk/credential-provider-process@3.535.0": + version "3.535.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.535.0.tgz#ea1e8a38a32e36bbdc3f75eb03352e6eafa0c659" + integrity sha512-9O1OaprGCnlb/kYl8RwmH7Mlg8JREZctB8r9sa1KhSsWFq/SWO0AuJTyowxD7zL5PkeS4eTvzFFHWCa3OO5epA== + dependencies: + "@aws-sdk/types" "3.535.0" + "@smithy/property-provider" "^2.2.0" + "@smithy/shared-ini-file-loader" "^2.4.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@aws-sdk/credential-provider-sso@3.540.0": + version "3.540.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.540.0.tgz#1fc5c53a0df8227249c73a3cb7660b1accb79186" + integrity sha512-tKkFqK227LF5ajc5EL6asXS32p3nkofpP8G7NRpU7zOEOQCg01KUc4JRX+ItI0T007CiN1J19yNoFqHLT/SqHg== + dependencies: + "@aws-sdk/client-sso" "3.540.0" + "@aws-sdk/token-providers" "3.540.0" + "@aws-sdk/types" "3.535.0" + "@smithy/property-provider" "^2.2.0" + "@smithy/shared-ini-file-loader" "^2.4.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@aws-sdk/credential-provider-web-identity@3.540.0": + version "3.540.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.540.0.tgz#775a2090e9f4f89efe2ebdf1e2c109a47561c0e9" + integrity sha512-OpDm9w3A168B44hSjpnvECP4rvnFzD86rN4VYdGADuCvEa5uEcdA/JuT5WclFPDqdWEmFBqS1pxBIJBf0g2Q9Q== + dependencies: + "@aws-sdk/client-sts" "3.540.0" + "@aws-sdk/types" "3.535.0" + "@smithy/property-provider" "^2.2.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@aws-sdk/middleware-host-header@3.535.0": + version "3.535.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.535.0.tgz#d5264f813592f5e77df25e5a14bbb0e6441812db" + integrity sha512-0h6TWjBWtDaYwHMQJI9ulafeS4lLaw1vIxRjbpH0svFRt6Eve+Sy8NlVhECfTU2hNz/fLubvrUxsXoThaLBIew== dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" + "@aws-sdk/types" "3.535.0" + "@smithy/protocol-http" "^3.3.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@aws-sdk/middleware-logger@3.535.0": + version "3.535.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.535.0.tgz#1a8ffd6c368edd6cb32e1edf7b1dced95c1820ee" + integrity sha512-huNHpONOrEDrdRTvSQr1cJiRMNf0S52NDXtaPzdxiubTkP+vni2MohmZANMOai/qT0olmEVX01LhZ0ZAOgmg6A== + dependencies: + "@aws-sdk/types" "3.535.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@aws-sdk/middleware-recursion-detection@3.535.0": + version "3.535.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.535.0.tgz#6aa1e1bd1e84730d58a73021b745e20d4341a92d" + integrity sha512-am2qgGs+gwqmR4wHLWpzlZ8PWhm4ktj5bYSgDrsOfjhdBlWNxvPoID9/pDAz5RWL48+oH7I6SQzMqxXsFDikrw== + dependencies: + "@aws-sdk/types" "3.535.0" + "@smithy/protocol-http" "^3.3.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@aws-sdk/middleware-user-agent@3.540.0": + version "3.540.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.540.0.tgz#4981c64c1eeb6b5c453bce02d060b8c71d44994d" + integrity sha512-8Rd6wPeXDnOYzWj1XCmOKcx/Q87L0K1/EHqOBocGjLVbN3gmRxBvpmR1pRTjf7IsWfnnzN5btqtcAkfDPYQUMQ== + dependencies: + "@aws-sdk/types" "3.535.0" + "@aws-sdk/util-endpoints" "3.540.0" + "@smithy/protocol-http" "^3.3.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@aws-sdk/region-config-resolver@3.535.0": + version "3.535.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/region-config-resolver/-/region-config-resolver-3.535.0.tgz#20a30fb5fbbe27ab70f2ed16327bae7e367b5cec" + integrity sha512-IXOznDiaItBjsQy4Fil0kzX/J3HxIOknEphqHbOfUf+LpA5ugcsxuQQONrbEQusCBnfJyymrldBvBhFmtlU9Wg== + dependencies: + "@aws-sdk/types" "3.535.0" + "@smithy/node-config-provider" "^2.3.0" + "@smithy/types" "^2.12.0" + "@smithy/util-config-provider" "^2.3.0" + "@smithy/util-middleware" "^2.2.0" + tslib "^2.6.2" + +"@aws-sdk/token-providers@3.540.0": + version "3.540.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.540.0.tgz#06fb874a62d3c496875768ac648bc6cca4c75a79" + integrity sha512-9BvtiVEZe5Ev88Wa4ZIUbtT6BVcPwhxmVInQ6c12MYNb0WNL54BN6wLy/eknAfF05gpX2/NDU2pUDOyMPdm/+g== + dependencies: + "@aws-sdk/client-sso-oidc" "3.540.0" + "@aws-sdk/types" "3.535.0" + "@smithy/property-provider" "^2.2.0" + "@smithy/shared-ini-file-loader" "^2.4.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@aws-sdk/types@3.535.0": + version "3.535.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.535.0.tgz#5e6479f31299dd9df170e63f4d10fe739008cf04" + integrity sha512-aY4MYfduNj+sRR37U7XxYR8wemfbKP6lx00ze2M2uubn7mZotuVrWYAafbMSXrdEMSToE5JDhr28vArSOoLcSg== + dependencies: + "@smithy/types" "^2.12.0" + tslib "^2.6.2" -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== +"@aws-sdk/types@^3.222.0": + version "3.523.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.523.0.tgz#2bb11390023949f31d9211212f41e245a7f03489" + integrity sha512-AqGIu4u+SxPiUuNBp2acCVcq80KDUFjxe6e3cMTvKWTzCbrVk1AXv0dAaJnCmdkWIha6zJDWxpIk/aL4EGhZ9A== dependencies: - get-intrinsic "^1.1.3" + "@smithy/types" "^2.10.1" + tslib "^2.5.0" -has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +"@aws-sdk/util-endpoints@3.540.0": + version "3.540.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.540.0.tgz#a7fea1d2a5e64623353aaa6ee32dbb86ab9cd3f8" + integrity sha512-1kMyQFAWx6f8alaI6UT65/5YW/7pDWAKAdNwL6vuJLea03KrZRX3PMoONOSJpAS5m3Ot7HlWZvf3wZDNTLELZw== + dependencies: + "@aws-sdk/types" "3.535.0" + "@smithy/types" "^2.12.0" + "@smithy/util-endpoints" "^1.2.0" + tslib "^2.6.2" + +"@aws-sdk/util-locate-window@^3.0.0": + version "3.495.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-locate-window/-/util-locate-window-3.495.0.tgz#9034fd8db77991b28ed20e067acdd53e8b8f824b" + integrity sha512-MfaPXT0kLX2tQaR90saBT9fWQq2DHqSSJRzW+MZWsmF+y5LGCOhO22ac/2o6TKSQm7h0HRc2GaADqYYYor62yg== + dependencies: + tslib "^2.5.0" -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== +"@aws-sdk/util-user-agent-browser@3.535.0": + version "3.535.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.535.0.tgz#d67d72e8b933051620f18ddb1c2be225f79f588f" + integrity sha512-RWMcF/xV5n+nhaA/Ff5P3yNP3Kur/I+VNZngog4TEs92oB/nwOdAg/2JL8bVAhUbMrjTjpwm7PItziYFQoqyig== + dependencies: + "@aws-sdk/types" "3.535.0" + "@smithy/types" "^2.12.0" + bowser "^2.11.0" + tslib "^2.6.2" + +"@aws-sdk/util-user-agent-node@3.535.0": + version "3.535.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.535.0.tgz#f5c26fb6f3f561d3cf35f96f303b1775afad0a5b" + integrity sha512-dRek0zUuIT25wOWJlsRm97nTkUlh1NDcLsQZIN2Y8KxhwoXXWtJs5vaDPT+qAg+OpcNj80i1zLR/CirqlFg/TQ== + dependencies: + "@aws-sdk/types" "3.535.0" + "@smithy/node-config-provider" "^2.3.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@aws-sdk/util-utf8-browser@^3.0.0": + version "3.259.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz#3275a6f5eb334f96ca76635b961d3c50259fd9ff" + integrity sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw== + dependencies: + tslib "^2.3.1" + +"@smithy/abort-controller@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/abort-controller/-/abort-controller-2.2.0.tgz#18983401a5e2154b5c94057730024a7d14cbcd35" + integrity sha512-wRlta7GuLWpTqtFfGo+nZyOO1vEvewdNR1R4rTxpC8XU6vG/NDyrFBhwLZsqg1NUoR1noVaXJPC/7ZK47QCySw== + dependencies: + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@smithy/config-resolver@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/config-resolver/-/config-resolver-2.2.0.tgz#54f40478bb61709b396960a3535866dba5422757" + integrity sha512-fsiMgd8toyUba6n1WRmr+qACzXltpdDkPTAaDqc8QqPBUzO+/JKwL6bUBseHVi8tu9l+3JOK+tSf7cay+4B3LA== + dependencies: + "@smithy/node-config-provider" "^2.3.0" + "@smithy/types" "^2.12.0" + "@smithy/util-config-provider" "^2.3.0" + "@smithy/util-middleware" "^2.2.0" + tslib "^2.6.2" + +"@smithy/core@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@smithy/core/-/core-1.4.0.tgz#5f9f86b681b9cbf23904041dad6f0531efe8375e" + integrity sha512-uu9ZDI95Uij4qk+L6kyFjdk11zqBkcJ3Lv0sc6jZrqHvLyr0+oeekD3CnqMafBn/5PRI6uv6ulW3kNLRBUHeVw== + dependencies: + "@smithy/middleware-endpoint" "^2.5.0" + "@smithy/middleware-retry" "^2.2.0" + "@smithy/middleware-serde" "^2.3.0" + "@smithy/protocol-http" "^3.3.0" + "@smithy/smithy-client" "^2.5.0" + "@smithy/types" "^2.12.0" + "@smithy/util-middleware" "^2.2.0" + tslib "^2.6.2" + +"@smithy/credential-provider-imds@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@smithy/credential-provider-imds/-/credential-provider-imds-2.3.0.tgz#326ce401b82e53f3c7ee4862a066136959a06166" + integrity sha512-BWB9mIukO1wjEOo1Ojgl6LrG4avcaC7T/ZP6ptmAaW4xluhSIPZhY+/PI5YKzlk+jsm+4sQZB45Bt1OfMeQa3w== + dependencies: + "@smithy/node-config-provider" "^2.3.0" + "@smithy/property-provider" "^2.2.0" + "@smithy/types" "^2.12.0" + "@smithy/url-parser" "^2.2.0" + tslib "^2.6.2" + +"@smithy/eventstream-codec@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-codec/-/eventstream-codec-2.2.0.tgz#63d74fa817188995eb55e792a38060b0ede98dc4" + integrity sha512-8janZoJw85nJmQZc4L8TuePp2pk1nxLgkxIR0TUjKJ5Dkj5oelB9WtiSSGXCQvNsJl0VSTvK/2ueMXxvpa9GVw== + dependencies: + "@aws-crypto/crc32" "3.0.0" + "@smithy/types" "^2.12.0" + "@smithy/util-hex-encoding" "^2.2.0" + tslib "^2.6.2" + +"@smithy/fetch-http-handler@^2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@smithy/fetch-http-handler/-/fetch-http-handler-2.5.0.tgz#0b8e1562807fdf91fe7dd5cde620d7a03ddc10ac" + integrity sha512-BOWEBeppWhLn/no/JxUL/ghTfANTjT7kg3Ww2rPqTUY9R4yHPXxJ9JhMe3Z03LN3aPwiwlpDIUcVw1xDyHqEhw== + dependencies: + "@smithy/protocol-http" "^3.3.0" + "@smithy/querystring-builder" "^2.2.0" + "@smithy/types" "^2.12.0" + "@smithy/util-base64" "^2.3.0" + tslib "^2.6.2" + +"@smithy/hash-node@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/hash-node/-/hash-node-2.2.0.tgz#df29e1e64811be905cb3577703b0e2d0b07fc5cc" + integrity sha512-zLWaC/5aWpMrHKpoDF6nqpNtBhlAYKF/7+9yMN7GpdR8CzohnWfGtMznPybnwSS8saaXBMxIGwJqR4HmRp6b3g== + dependencies: + "@smithy/types" "^2.12.0" + "@smithy/util-buffer-from" "^2.2.0" + "@smithy/util-utf8" "^2.3.0" + tslib "^2.6.2" + +"@smithy/invalid-dependency@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/invalid-dependency/-/invalid-dependency-2.2.0.tgz#ee3d8980022cb5edb514ac187d159b3e773640f0" + integrity sha512-nEDASdbKFKPXN2O6lOlTgrEEOO9NHIeO+HVvZnkqc8h5U9g3BIhWsvzFo+UcUbliMHvKNPD/zVxDrkP1Sbgp8Q== + dependencies: + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@smithy/is-array-buffer@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz#f84f0d9f9a36601a9ca9381688bd1b726fd39111" + integrity sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA== + dependencies: + tslib "^2.6.2" + +"@smithy/middleware-content-length@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/middleware-content-length/-/middleware-content-length-2.2.0.tgz#a82e97bd83d8deab69e07fea4512563bedb9461a" + integrity sha512-5bl2LG1Ah/7E5cMSC+q+h3IpVHMeOkG0yLRyQT1p2aMJkSrZG7RlXHPuAgb7EyaFeidKEnnd/fNaLLaKlHGzDQ== + dependencies: + "@smithy/protocol-http" "^3.3.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@smithy/middleware-endpoint@^2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-2.5.0.tgz#9f1459e9b4cbf00fadfd99e98f88d4b1a2aeb987" + integrity sha512-OBhI9ZEAG8Xen0xsFJwwNOt44WE2CWkfYIxTognC8x42Lfsdf0VN/wCMqpdkySMDio/vts10BiovAxQp0T0faA== + dependencies: + "@smithy/middleware-serde" "^2.3.0" + "@smithy/node-config-provider" "^2.3.0" + "@smithy/shared-ini-file-loader" "^2.4.0" + "@smithy/types" "^2.12.0" + "@smithy/url-parser" "^2.2.0" + "@smithy/util-middleware" "^2.2.0" + tslib "^2.6.2" + +"@smithy/middleware-retry@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-2.2.0.tgz#ff48ac01ad57394eeea15a0146a86079cf6364b7" + integrity sha512-PsjDOLpbevgn37yJbawmfVoanru40qVA8UEf2+YA1lvOefmhuhL6ZbKtGsLAWDRnE1OlAmedsbA/htH6iSZjNA== + dependencies: + "@smithy/node-config-provider" "^2.3.0" + "@smithy/protocol-http" "^3.3.0" + "@smithy/service-error-classification" "^2.1.5" + "@smithy/smithy-client" "^2.5.0" + "@smithy/types" "^2.12.0" + "@smithy/util-middleware" "^2.2.0" + "@smithy/util-retry" "^2.2.0" + tslib "^2.6.2" + uuid "^8.3.2" + +"@smithy/middleware-serde@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@smithy/middleware-serde/-/middleware-serde-2.3.0.tgz#a7615ba646a88b6f695f2d55de13d8158181dd13" + integrity sha512-sIADe7ojwqTyvEQBe1nc/GXB9wdHhi9UwyX0lTyttmUWDJLP655ZYE1WngnNyXREme8I27KCaUhyhZWRXL0q7Q== + dependencies: + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@smithy/middleware-stack@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/middleware-stack/-/middleware-stack-2.2.0.tgz#3fb49eae6313f16f6f30fdaf28e11a7321f34d9f" + integrity sha512-Qntc3jrtwwrsAC+X8wms8zhrTr0sFXnyEGhZd9sLtsJ/6gGQKFzNB+wWbOcpJd7BR8ThNCoKt76BuQahfMvpeA== + dependencies: + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@smithy/node-config-provider@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@smithy/node-config-provider/-/node-config-provider-2.3.0.tgz#9fac0c94a14c5b5b8b8fa37f20c310a844ab9922" + integrity sha512-0elK5/03a1JPWMDPaS726Iw6LpQg80gFut1tNpPfxFuChEEklo2yL823V94SpTZTxmKlXFtFgsP55uh3dErnIg== + dependencies: + "@smithy/property-provider" "^2.2.0" + "@smithy/shared-ini-file-loader" "^2.4.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@smithy/node-http-handler@^2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-2.5.0.tgz#7b5e0565dd23d340380489bd5fe4316d2bed32de" + integrity sha512-mVGyPBzkkGQsPoxQUbxlEfRjrj6FPyA3u3u2VXGr9hT8wilsoQdZdvKpMBFMB8Crfhv5dNkKHIW0Yyuc7eABqA== dependencies: - has-symbols "^1.0.2" + "@smithy/abort-controller" "^2.2.0" + "@smithy/protocol-http" "^3.3.0" + "@smithy/querystring-builder" "^2.2.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@smithy/property-provider@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/property-provider/-/property-provider-2.2.0.tgz#37e3525a3fa3e11749f86a4f89f0fd7765a6edb0" + integrity sha512-+xiil2lFhtTRzXkx8F053AV46QnIw6e7MV8od5Mi68E1ICOjCeCHw2XfLnDEUHnT9WGUIkwcqavXjfwuJbGlpg== + dependencies: + "@smithy/types" "^2.12.0" + tslib "^2.6.2" -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== +"@smithy/protocol-http@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-3.3.0.tgz#a37df7b4bb4960cdda560ce49acfd64c455e4090" + integrity sha512-Xy5XK1AFWW2nlY/biWZXu6/krgbaf2dg0q492D8M5qthsnU2H+UgFeZLbM76FnH7s6RO/xhQRkj+T6KBO3JzgQ== dependencies: - function-bind "^1.1.1" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" -ieee754@1.1.13: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== +"@smithy/querystring-builder@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/querystring-builder/-/querystring-builder-2.2.0.tgz#22937e19fcd0aaa1a3e614ef8cb6f8e86756a4ef" + integrity sha512-L1kSeviUWL+emq3CUVSgdogoM/D9QMFaqxL/dd0X7PCNWmPXqt+ExtrBjqT0V7HLN03Vs9SuiLrG3zy3JGnE5A== + dependencies: + "@smithy/types" "^2.12.0" + "@smithy/util-uri-escape" "^2.2.0" + tslib "^2.6.2" + +"@smithy/querystring-parser@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/querystring-parser/-/querystring-parser-2.2.0.tgz#24a5633f4b3806ff2888d4c2f4169e105fdffd79" + integrity sha512-BvHCDrKfbG5Yhbpj4vsbuPV2GgcpHiAkLeIlcA1LtfpMz3jrqizP1+OguSNSj1MwBHEiN+jwNisXLGdajGDQJA== + dependencies: + "@smithy/types" "^2.12.0" + tslib "^2.6.2" -ieee754@^1.1.4: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== +"@smithy/service-error-classification@^2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@smithy/service-error-classification/-/service-error-classification-2.1.5.tgz#0568a977cc0db36299d8703a5d8609c1f600c005" + integrity sha512-uBDTIBBEdAQryvHdc5W8sS5YX7RQzF683XrHePVdFmAgKiMofU15FLSM0/HU03hKTnazdNRFa0YHS7+ArwoUSQ== + dependencies: + "@smithy/types" "^2.12.0" -inherits@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +"@smithy/shared-ini-file-loader@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.4.0.tgz#1636d6eb9bff41e36ac9c60364a37fd2ffcb9947" + integrity sha512-WyujUJL8e1B6Z4PBfAqC/aGY1+C7T0w20Gih3yrvJSk97gpiVfB+y7c46T4Nunk+ZngLq0rOIdeVeIklk0R3OA== + dependencies: + "@smithy/types" "^2.12.0" + tslib "^2.6.2" -is-arguments@^1.0.4: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" - integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== +"@smithy/signature-v4@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-2.2.0.tgz#8fe6a574188b71fba6056111b88d50c84babb060" + integrity sha512-+B5TNzj/fRZzVW3z8UUJOkNx15+4E0CLuvJmJUA1JUIZFp3rdJ/M2H5r2SqltaVPXL0oIxv/6YK92T9TsFGbFg== + dependencies: + "@smithy/eventstream-codec" "^2.2.0" + "@smithy/is-array-buffer" "^2.2.0" + "@smithy/types" "^2.12.0" + "@smithy/util-hex-encoding" "^2.2.0" + "@smithy/util-middleware" "^2.2.0" + "@smithy/util-uri-escape" "^2.2.0" + "@smithy/util-utf8" "^2.3.0" + tslib "^2.6.2" + +"@smithy/smithy-client@^2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-2.5.0.tgz#8de4fff221d232dda34a8e706d6a4f2911dffe2e" + integrity sha512-DDXWHWdimtS3y/Kw1Jo46KQ0ZYsDKcldFynQERUGBPDpkW1lXOTHy491ALHjwfiBQvzsVKVxl5+ocXNIgJuX4g== dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" + "@smithy/middleware-endpoint" "^2.5.0" + "@smithy/middleware-stack" "^2.2.0" + "@smithy/protocol-http" "^3.3.0" + "@smithy/types" "^2.12.0" + "@smithy/util-stream" "^2.2.0" + tslib "^2.6.2" + +"@smithy/types@^2.10.1": + version "2.10.1" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.10.1.tgz#f2a923fd080447ad2ca19bfd8a77abf15be0b8e8" + integrity sha512-hjQO+4ru4cQ58FluQvKKiyMsFg0A6iRpGm2kqdH8fniyNd2WyanoOsYJfMX/IFLuLxEoW6gnRkNZy1y6fUUhtA== + dependencies: + tslib "^2.5.0" -is-callable@^1.1.3: - version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== +"@smithy/types@^2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.12.0.tgz#c44845f8ba07e5e8c88eda5aed7e6a0c462da041" + integrity sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw== + dependencies: + tslib "^2.6.2" -is-generator-function@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" - integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== +"@smithy/url-parser@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/url-parser/-/url-parser-2.2.0.tgz#6fcda6116391a4f61fef5580eb540e128359b3c0" + integrity sha512-hoA4zm61q1mNTpksiSWp2nEl1dt3j726HdRhiNgVJQMj7mLp7dprtF57mOB6JvEk/x9d2bsuL5hlqZbBuHQylQ== + dependencies: + "@smithy/querystring-parser" "^2.2.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@smithy/util-base64@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@smithy/util-base64/-/util-base64-2.3.0.tgz#312dbb4d73fb94249c7261aee52de4195c2dd8e2" + integrity sha512-s3+eVwNeJuXUwuMbusncZNViuhv2LjVJ1nMwTqSA0XAC7gjKhqqxRdJPhR8+YrkoZ9IiIbFk/yK6ACe/xlF+hw== dependencies: - has-tostringtag "^1.0.0" + "@smithy/util-buffer-from" "^2.2.0" + "@smithy/util-utf8" "^2.3.0" + tslib "^2.6.2" + +"@smithy/util-body-length-browser@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-body-length-browser/-/util-body-length-browser-2.2.0.tgz#25620645c6b62b42594ef4a93b66e6ab70e27d2c" + integrity sha512-dtpw9uQP7W+n3vOtx0CfBD5EWd7EPdIdsQnWTDoFf77e3VUf05uA7R7TGipIo8e4WL2kuPdnsr3hMQn9ziYj5w== + dependencies: + tslib "^2.6.2" -is-typed-array@^1.1.10, is-typed-array@^1.1.3: - version "1.1.10" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" - integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== +"@smithy/util-body-length-node@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@smithy/util-body-length-node/-/util-body-length-node-2.3.0.tgz#d065a9b5e305ff899536777bbfe075cdc980136f" + integrity sha512-ITWT1Wqjubf2CJthb0BuT9+bpzBfXeMokH/AAa5EJQgbv9aPMVfnM76iFIZVFf50hYXGbtiV71BHAthNWd6+dw== dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" + tslib "^2.6.2" -isarray@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== +"@smithy/util-buffer-from@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz#6fc88585165ec73f8681d426d96de5d402021e4b" + integrity sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA== + dependencies: + "@smithy/is-array-buffer" "^2.2.0" + tslib "^2.6.2" -jmespath@0.16.0: - version "0.16.0" - resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.16.0.tgz#b15b0a85dfd4d930d43e69ed605943c802785076" - integrity sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw== +"@smithy/util-config-provider@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@smithy/util-config-provider/-/util-config-provider-2.3.0.tgz#bc79f99562d12a1f8423100ca662a6fb07cde943" + integrity sha512-HZkzrRcuFN1k70RLqlNK4FnPXKOpkik1+4JaBoHNJn+RnJGYqaa3c5/+XtLOXhlKzlRgNvyaLieHTW2VwGN0VQ== + dependencies: + tslib "^2.6.2" -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== +"@smithy/util-defaults-mode-browser@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.2.0.tgz#963a9d3c3351272764dd1c5dc07c26f2c8abcb02" + integrity sha512-2okTdZaCBvOJszAPU/KSvlimMe35zLOKbQpHhamFJmR7t95HSe0K3C92jQPjKY3PmDBD+7iMkOnuW05F5OlF4g== + dependencies: + "@smithy/property-provider" "^2.2.0" + "@smithy/smithy-client" "^2.5.0" + "@smithy/types" "^2.12.0" + bowser "^2.11.0" + tslib "^2.6.2" + +"@smithy/util-defaults-mode-node@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.3.0.tgz#5005058ca0a299f0948b47c288f7c3d4f36cb26e" + integrity sha512-hfKXnNLmsW9cmLb/JXKIvtuO6Cf4SuqN5PN1C2Ru/TBIws+m1wSgb+A53vo0r66xzB6E82inKG2J7qtwdi+Kkw== + dependencies: + "@smithy/config-resolver" "^2.2.0" + "@smithy/credential-provider-imds" "^2.3.0" + "@smithy/node-config-provider" "^2.3.0" + "@smithy/property-provider" "^2.2.0" + "@smithy/smithy-client" "^2.5.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@smithy/util-endpoints@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-endpoints/-/util-endpoints-1.2.0.tgz#b8b805f47e8044c158372f69b88337703117665d" + integrity sha512-BuDHv8zRjsE5zXd3PxFXFknzBG3owCpjq8G3FcsXW3CykYXuEqM3nTSsmLzw5q+T12ZYuDlVUZKBdpNbhVtlrQ== + dependencies: + "@smithy/node-config-provider" "^2.3.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@smithy/util-hex-encoding@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-hex-encoding/-/util-hex-encoding-2.2.0.tgz#87edb7c88c2f422cfca4bb21f1394ae9602c5085" + integrity sha512-7iKXR+/4TpLK194pVjKiasIyqMtTYJsgKgM242Y9uzt5dhHnUDvMNb+3xIhRJ9QhvqGii/5cRUt4fJn3dtXNHQ== + dependencies: + tslib "^2.6.2" + +"@smithy/util-middleware@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-middleware/-/util-middleware-2.2.0.tgz#80cfad40f6cca9ffe42a5899b5cb6abd53a50006" + integrity sha512-L1qpleXf9QD6LwLCJ5jddGkgWyuSvWBkJwWAZ6kFkdifdso+sk3L3O1HdmPvCdnCK3IS4qWyPxev01QMnfHSBw== + dependencies: + "@smithy/types" "^2.12.0" + tslib "^2.6.2" -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== +"@smithy/util-retry@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-retry/-/util-retry-2.2.0.tgz#e8e019537ab47ba6b2e87e723ec51ee223422d85" + integrity sha512-q9+pAFPTfftHXRytmZ7GzLFFrEGavqapFc06XxzZFcSIGERXMerXxCitjOG1prVDR9QdjqotF40SWvbqcCpf8g== + dependencies: + "@smithy/service-error-classification" "^2.1.5" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@smithy/util-stream@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-2.2.0.tgz#b1279e417992a0f74afa78d7501658f174ed7370" + integrity sha512-17faEXbYWIRst1aU9SvPZyMdWmqIrduZjVOqCPMIsWFNxs5yQQgFrJL6b2SdiCzyW9mJoDjFtgi53xx7EH+BXA== + dependencies: + "@smithy/fetch-http-handler" "^2.5.0" + "@smithy/node-http-handler" "^2.5.0" + "@smithy/types" "^2.12.0" + "@smithy/util-base64" "^2.3.0" + "@smithy/util-buffer-from" "^2.2.0" + "@smithy/util-hex-encoding" "^2.2.0" + "@smithy/util-utf8" "^2.3.0" + tslib "^2.6.2" + +"@smithy/util-uri-escape@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-uri-escape/-/util-uri-escape-2.2.0.tgz#56f5764051a33b67bc93fdd2a869f971b0635406" + integrity sha512-jtmJMyt1xMD/d8OtbVJ2gFZOSKc+ueYJZPW20ULW1GOp/q/YIM0wNh+u8ZFao9UaIGz4WoPW8hC64qlWLIfoDA== + dependencies: + tslib "^2.6.2" -sax@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" - integrity sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA== +"@smithy/util-utf8@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@smithy/util-utf8/-/util-utf8-2.3.0.tgz#dd96d7640363259924a214313c3cf16e7dd329c5" + integrity sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A== + dependencies: + "@smithy/util-buffer-from" "^2.2.0" + tslib "^2.6.2" + +bowser@^2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" + integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA== + +fast-xml-parser@4.2.5: + version "4.2.5" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz#a6747a09296a6cb34f2ae634019bf1738f3b421f" + integrity sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g== + dependencies: + strnum "^1.0.5" sax@>=0.6.0: version "1.2.4" @@ -177,41 +874,25 @@ serverless-s3-bucket-helper@Enterprise-CMCS/serverless-s3-bucket-helper#0.1.1: version "1.0.0" resolved "https://codeload.github.com/Enterprise-CMCS/serverless-s3-bucket-helper/tar.gz/f0f6d6a1ffe54e292f0afc93777764bce16a4037" -url@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" - integrity sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ== - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -util@^0.12.4: - version "0.12.5" - resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" - integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== - dependencies: - inherits "^2.0.3" - is-arguments "^1.0.4" - is-generator-function "^1.0.7" - is-typed-array "^1.1.3" - which-typed-array "^1.1.2" - -uuid@8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.0.0.tgz#bc6ccf91b5ff0ac07bbcdbf1c7c4e150db4dbb6c" - integrity sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw== - -which-typed-array@^1.1.2: - version "1.1.9" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" - integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - is-typed-array "^1.1.10" +strnum@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" + integrity sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA== + +tslib@^1.11.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.3.1, tslib@^2.5.0, tslib@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== xml2js@0.6.0: version "0.6.0" @@ -221,14 +902,6 @@ xml2js@0.6.0: sax ">=0.6.0" xmlbuilder "~11.0.0" -xml2js@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.6.2.tgz#dd0b630083aa09c161e25a4d0901e2b2a929b499" - integrity sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA== - dependencies: - sax ">=0.6.0" - xmlbuilder "~11.0.0" - xmlbuilder@~11.0.0: version "11.0.1" resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" diff --git a/services/ui-src/public/index.html b/services/ui-src/public/index.html index 4448c12327..c1f6e02d7f 100644 --- a/services/ui-src/public/index.html +++ b/services/ui-src/public/index.html @@ -34,7 +34,7 @@