diff --git a/README.ja.md b/README.ja.md index e2eca95..458f14f 100644 --- a/README.ja.md +++ b/README.ja.md @@ -16,7 +16,10 @@ サブフォルダ[`zola`](zola/README.ja.md)をご覧ください。 -## Continuous Delivery +## DevOps + +以下の["DevOps"](https://en.wikipedia.org/wiki/DevOps)機能も提供します。 +- Continuous Delivery: このレポジトリの`main`ブランチが更新されると、codemongerウェブサイトを更新するためのワークフローが開始します。 +- データウェアハウス: codemongerウェブサイトのアクセスログはデータウェアハウスに格納されます。 -このレポジトリの`main`ブランチが更新されると、codemongerウェブサイトを更新するためのワークフローが開始します。 詳しくはサブフォルダ[`cdk-ops`](cdk-ops/README.ja.md)をご覧ください。 \ No newline at end of file diff --git a/README.md b/README.md index 5459deb..ce97c82 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,10 @@ Please refer to the subfolder [`cdk`](cdk). Please refer to the subfolder [`zola`](zola). -## Continuous delivery +## DevOps + +The following ["DevOps"](https://en.wikipedia.org/wiki/DevOps) features are also provided, +- Continuous delivery: when the `main` branch of this repository is updated, the workflow to update the codemonger website starts. +- Data warehouse: access logs of the codemonger website are stored in the data warehouse. -When the `main` branch of this repository is updated, the workflow to update the codemonger website starts. Please refer to the subfolder [`cdk-ops`](cdk-ops) for more details. \ No newline at end of file diff --git a/cdk-ops/.gitignore b/cdk-ops/.gitignore index 04d61cd..007324c 100644 --- a/cdk-ops/.gitignore +++ b/cdk-ops/.gitignore @@ -1,5 +1,6 @@ *.js !jest.config.js +!/bin/populate-data-warehouse.js *.d.ts node_modules diff --git a/cdk-ops/README.ja.md b/cdk-ops/README.ja.md index 0d85dc2..f3f7534 100644 --- a/cdk-ops/README.ja.md +++ b/cdk-ops/README.ja.md @@ -21,6 +21,11 @@ codemongerウェブサイトのコンテンツを保管し配信するAWSリソ ワークフローは`main`ブランチが更新された際(例えばプルリクエストがマージされた際)に開始されます。 プルリクエストの作成前に作成者は[`zola serve`](https://www.getzola.org/documentation/getting-started/cli-usage/#serve)でローカルにコンテンツをレビューしなければなりません。 +## アクセスログ用のデータウェアハウス + +このCDKスタックはアクセスログ用のデータウェアハウスを確保します。 +詳しくは[`docs/data-warehouse.ja.md`](./docs/data-warehouse.ja.md)をご参照ください。 + ## 事前準備 ### コンテンツのためのCDKスタックをデプロイする @@ -106,6 +111,44 @@ npx cdk deploy --toolkit-stack-name $TOOLKIT_STACK_NAME -c "@aws-cdk/core:bootst CDKスタックをデプロイすると、CloudFormationスタック`codemonger-operation`が作成または更新されます。 +#### Amazon Redshift Serverlessネームスペースの管理ユーザー + +このCDKスタックは[Amazon Redshift Serverless (Redshift Serverless)](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-serverless.html)ネームスペースの確保時に管理ユーザーを作成します。 +管理ユーザーのパスワードは[AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html)の管理するシークレットとして作成されます。 +**CloudFormationはRedshift Serverlessネームスペースの管理ユーザー名とパスワードを一度作成すると変更することができない**ので、**シークレットが更新(再生成)されると管理パスワードが失われます**。 + +これが起きてしまったら、別のスーパーユーザーで管理パスワードを手作業で更新しなければなりません。 +Redshift Serverlessコンソールで管理パスワードを変更するか、CloudFormationの実行ロール\*で[Query Editor v2](https://aws.amazon.com/redshift/query-editor-v2/)を実行して管理パスワードをリセットすることもできます。 + +\* Redshift Serverlessはネームスペースの作成者に管理権限を与えます。 +Redshift Serverlessネームスペースの確保にCDK (CloudFormation)を使用しているので、CloudFormationの実行ロールがその力を授かることになります。 + +## デプロイ後 + +### データウェアハウスにデータベースとテーブルを作成する + +このCDKスタックをデプロイした後、データウェアハウスにデータベースとテーブルを作成しなければなりません。 +以下のコマンドを実行してください。 + +```sh +npm run populate-dw -- development +npm run populate-dw -- production +``` + +`populate-dw`スクリプトは[`bin/populate-data-warehouse.js`](./bin/populate-data-warehouse.js)を実行します。 + +この手続きはCDKスタックを最初に確保した際に一度だけ必要です。 + +### 日々のアクセスログ読み込みを有効にする + +このCDKスタックは、CloudFrontのアクセスログをデータウェアハウスに読み込むLambda関数を1日に1回実行する[Amazon EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html)のルールを確保します。 +ルールはデフォルトで無効化されているので、日々のアクセスログ読み込みを実行するには有効化しなければなりません。 +開発用\*と製品用で別々のルールがあります。 + +確実に[データウェアハウスにデータベースとテーブルを作成](#データウェアハウスにデータベースとテーブルを作成する)しておいてください。 + +\* 開発用のルールは**毎時**トリガーされます。 + ## なぜExportを使わないのか? このCDKスタックはメインとなるcodemongerのCloudFormationスタックに依存します。 diff --git a/cdk-ops/README.md b/cdk-ops/README.md index 5988491..d9257e6 100644 --- a/cdk-ops/README.md +++ b/cdk-ops/README.md @@ -21,6 +21,11 @@ This CDK stack provisions a [AWS CodePipeline](https://docs.aws.amazon.com/codep The workflow is triggered when the `main` branch is updated; e.g., a pull request is merged. An author of a pull request has to locally review contents with [`zola serve`](https://www.getzola.org/documentation/getting-started/cli-usage/#serve) before making the pull request. +## Data warehouse for access logs + +This CDK stack provisions a data warehouse for access logs. +Please refer to [`docs/data-warehouse.md`](./docs/data-warehouse.md) for more details. + ## Prerequisites ### Deploying CDK stack for contents @@ -106,6 +111,44 @@ npx cdk deploy --toolkit-stack-name $TOOLKIT_STACK_NAME -c "@aws-cdk/core:bootst After deploying the CDK stack, you will find the CloudFormation stack `codemonger-operation` created or updated. +#### Admin user of the Amazon Redshift Serverless namespace + +This CDK stack creates the admin user of the [Amazon Redshift Serverless (Redshift Serverless)](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-serverless.html) namespace when it provisions the namespace. +The password of the admin user is created as a secret managed by [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html). +Since **CloudFormation cannot change the admin username and password of the Redshift Serverless namespace** once it is provisioned, the **admin password is lost in case the secret is updated (regenerated)**. + +If this happens, you have to manually update the admin password as another superuser. +You can change the admin password on the Redshift Serverless console, or you can assume the CloudFormation execution role\* on [Query Editor v2](https://aws.amazon.com/redshift/query-editor-v2/) to reset the admin password. + +\* Redshift Serverless gives the creator of a new namespace an admin privilege of it. +Because we are using CDK (CloudFormation) to provision a Redshift Serverless namespace, the execution role of CloudFormation deserves the power. + +## Post deployment + +### Populating the database and tables on the data warehouse + +After deploying this CDK stack, you have to populate the database and tables on the data warehouse. +Please run the following commands. + +```sh +npm run populate-dw -- development +npm run populate-dw -- production +``` + +The `populate-dw` script runs [`bin/populate-data-warehouse.js`](./bin/populate-data-warehouse.js). + +This procedure is necessary only once when you deploy this CDK stack for the first time. + +### Enabling the daily access log loading + +This CDK stack provisions an [Amazon EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html) rule that runs the Lambda function that loads CloudFront access logs onto the data warehouse once a day. +Since the rule is disabled by default, you have to enable the rule to run the daily access log loading. +There are separate rules for development\* and production. + +Please make sure that you have [populated the database and tables on the data warehouse](#populating-the-database-and-tables-on-the-data-warehouse). + +\* The rule for development triggers **every hour**. + ## Why am I not using exports? This CDK stack depends on the main codemonger CloudFormation stacks. diff --git a/cdk-ops/bin/cdk-ops.ts b/cdk-ops/bin/cdk-ops.ts index b27a6fe..ed92b34 100644 --- a/cdk-ops/bin/cdk-ops.ts +++ b/cdk-ops/bin/cdk-ops.ts @@ -23,6 +23,15 @@ resolveCodemongerResourceNames() // env: { account: '123456789012', region: 'us-east-1' }, /* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */ + env: { + // without the following properties `account` and `region`, + // the stack becomes "environment-agnostic." + // only two availability zones (AZs) are visible in an + // evironment-agnostic stack. + // https://docs.aws.amazon.com/cdk/v2/guide/environments.html + account: process.env.CDK_DEFAULT_ACCOUNT, + region: process.env.CDK_DEFAULT_REGION, + }, codemongerResourceNames: names, tags: { project: 'codemonger', diff --git a/cdk-ops/bin/populate-data-warehouse.js b/cdk-ops/bin/populate-data-warehouse.js new file mode 100644 index 0000000..3572ef4 --- /dev/null +++ b/cdk-ops/bin/populate-data-warehouse.js @@ -0,0 +1,76 @@ +/* Populates the data warehouse. */ + +const yargs = require('yargs/yargs'); +const { hideBin } = require('yargs/helpers'); +const { + CloudFormationClient, + DescribeStacksCommand, +} = require('@aws-sdk/client-cloudformation'); +const { LambdaClient, InvokeCommand } = require('@aws-sdk/client-lambda'); + +const CODEMONGER_OPERATIONS_STACK_NAME = 'codemonger-operations'; + +yargs(hideBin(process.argv)) + .command( + '$0 ', + 'populates the data warehouse', + _yargs => { + _yargs.positional('stage', { + describe: 'deployment stage of the data warehouse', + choices: ['development', 'production'], + }); + }, + run, + ) + .help() + .argv; + +async function run({ stage }) { + console.log('obtaining populate function for', stage); + const functionArn = await getPopulateFunctionArn(stage); + console.log('running populate function for', stage); + await runPopulate(functionArn); + console.log('populated the data warehouse for', stage); +} + +// obtains the ARN of the Lambda function that populates the database and +// tables. +async function getPopulateFunctionArn(stage) { + const client = new CloudFormationClient({}); + const command = new DescribeStacksCommand({ + StackName: CODEMONGER_OPERATIONS_STACK_NAME, + }); + const results = await client.send(command); + const outputs = (results.Stacks ?? [])[0]?.Outputs; + if (outputs == null) { + throw new Error( + `please deploy the latest stack ${CODEMONGER_OPERATIONS_STACK_NAME}`, + ); + } + const outputKey = stage === 'production' + ? 'PopulateProductionDwDatabaseLambdaArn' + : 'PopulateDevelopmentDwDatabaseLambdaArn'; + const output = outputs.find(o => o.OutputKey === outputKey); + if (output == null) { + throw new Error( + `please deploy the latest stack ${CODEMONGER_OPERATIONS_STACK_NAME}`, + ); + } + return output.OutputValue; +} + +// runs a given populate function. +async function runPopulate(functionArn) { + const client = new LambdaClient({}); + const command = new InvokeCommand({ + FunctionName: functionArn, + Payload: '{}', + }); + const results = await client.send(command); + if (results.StatusCode !== 200) { + const decoder = new TextDecoder(); + const payload = decoder.decode(results.Payload); + console.error('failed to populate the data warehouse', payload); + throw new Error('failed to populate the data warehouse'); + } +} diff --git a/cdk-ops/docs/data-warehouse-aws-architecture.drawio b/cdk-ops/docs/data-warehouse-aws-architecture.drawio new file mode 100644 index 0000000..5b44d6c --- /dev/null +++ b/cdk-ops/docs/data-warehouse-aws-architecture.drawio @@ -0,0 +1 @@ +7V1bc6M4Fv41eewUQuLiR1/i2dlKqlzjrZ7Zp5RsFJtpjLwgx8n8+pW42ULCxnEwjkN3VwcdQAKd850bR8odHK7efovwevlEPRLcmYb3dgdHd6YJoOXwH4LynlLcHkgJi8j3sot2hKn/D8mIRkbd+B6JpQsZpQHz1zJxTsOQzJlEw1FEt/JlLzSQR13jBVEI0zkOVOqfvseWGRXYvd2JfxF/scyGds3shVc4vzh7k3iJPbrdI8GHOziMKGXp0eptSAIxefm8pPeNK84WDxaRkNW54f1HH0Dn55RMcPAD/3x++jeY/8h6ecXBJnvhn5Nh9rzsPZ+ENfVDlkykNeD/+DhD487iZ4aidW9aJUK57cgEoLZEHzKh3HZkAih3D0rjg/ID7hGUltS9URrf2HtA/g8O6IYFfkiGhcgZnLiIsOdzVgxpQCNOC2nIZ2+wZKuAtwA/3C59RqZrPBezuuVw4bQXGrJM6IGZt7OJF71ysWaYjxVlfSScINHDK0kZkl4TBHgd+7PirojMN1Hsv5I/SJx2LqhcANfiePW2EFi9x9sY3S8iulknj/87H0t79vl1PRe3s4j+Ivnr3ZnQRK4LkHhoPwhKr/1KIuZzFPUDfyF6ZVQMgrNWQF6Y6JHPhR8uHpPWCBrZ++8N0e8PnIHL6R6Ol8TLXiSTWT4EeasEAyggxnUToSvCond+SXaDlaMyU0vIRGl7uwM5zHXQcg/fJrAz5ZIplkXR9w57/CCD3wlQNBUoTiL/FTMisLiZhYR1uOxwuY/LWHTns/fn3cXTBKR5x2XEAuQ8DPolxHL6gz02x+7nwbYY53TYVlupSiwDGcrQUJBs9jRIBo7REJKhgmQFufEvwubLbGK0cluaUv53LB6hSp5LHEUj0+n3FRnILpbYkvP8Ec9IMKGxz/xE4GaUMbo6KhRzIgRfRtQx9OB4nb7oi/8mnkOBD6iCBQm9XOmdIU/mQXmCzjF5clxVnHLap0sTUqTpN24Utpj3bAcCj7OIHy3EUT47irjxGWIyiyKhgfBONeENo5lOAjruloVg5XueuHkg26CR3h3QSiFXWqFXiOG+zNhNchdI3AVGT2GvTltYTSkLq31lAceubaLbUxazzZzP3PPWZ8tnOvub91JbbRy2OKYD7i1JjHqq++hYF1QStiI0xONxbNakEVvSBQ1x8LCjlvC3u+aRCp4l0/o3Yew9Y47QEDLn0jHFQIfnkT8X3URzcsjC57E9jhbkELgtPWMiEmDGHStp1E+fZeeLzzJCF5rl7NZJaoxy2CAke2ogD7ryLtLnmhQmLONVP4qEtSsuy0xO9Tg2kseBsMT6tMedIBTv+HHZcL+4bMCaooFgI7JhGbJCtUwod5G+wPmyUYoW8nHGH7u+GVnqKT5B/88pJwwDuvEUOeuyAN86C8APn+eJYOhydLkn2FyOrhji03N0sha3VRcLcKrGyTKbStHlumAfmCv8D+dMhs1xRL979NU7yNOSNgWGqzLV0YRfsKnwK3c8a8dfWm2r1bg6ravVvKr2lS5L9KFmhDJRR3NUIlAvy1WoStTRdPaifDfQ3A1Kd1dr67rhLD/XQ9ZobO6dG/lcv2ZRaShcKjXetfrQGFg6dfmS/LnGoFdrHrgaSbyi1DgIraIzE4lxeEk0U3PAtmwJ2G0nzYCK4utwxw/5e8ej5LpOulWRA7tMmAzUBHhhJqdQTVvi+ZzE3Gc3Arrg/6dpm86KHrCibg0zal0yiwnULPVhM9pAGnNgGC4a3V4aU4j1CqdP2JhIuTloiw/ibWtwNTFeKJE/iBcvfR6RKKpkhBnmx3gl2BXOYvGjP/m9UybVnHcc+XsX6jltKxO788m/sk8+HqOxOzjNJx8MAbTsb+OTE6H1Z5GfuIoNKnU5hdK6V+607yWMEMeMc3teQoBXMw8/v2zCedOugtmTpEonVkgjVqgxsXIVsXqk2OsnYcUjXcSd+a9v/gv0HzP/zaXk1M8fCgNvIJjPHeyjwXyqNdsK5vPH1PnhiVYapFasg1g1xGxXglj7We/8xToPu/Owb9TDjhlZF97QeeWih9Hds0vuUJ65aMvLzrGslA9M+ZTwH+NiUjqdXc1VU86HmT3Yts6GbXhBfA6j97+y+5PGf0Xj3sqbo7f9k6P3/daERD5/+aQ+YlcU0OD3EaemS1VVeXAhl+oKkuVdGHy2hnDl5AqCqt6/aBhsqhnzn3i+2az+kyjwTtlXsxLJDjpyNcrevKiyv9aC7vNC3rr1x2nesjX9fK113udNvlnXOLY7+ddaSH2eZ+J+Dcnv3eLk50u+jk9+q6tL4KlJmc4tvEK30DVlX8I27HbdQqimAyZ0veESTUZbUS8xw3HnHR5M38qpANvSVKK7l/QO4YECu+ramCmJ+OQESaldx+0qbttArmRFvbZr6yC6SaNs1TTKyNDz60JG+dT12d2Xkqv6UtKtDzj6pSTKLUaDStUyZaXadnUpbCW/UiTTi8Y1J9PrJmtgM6vFndKSEmT15C4qVot/1iJcWKMMpfGS9rHhAvWb7ZcPxyKaAOpS6qZu4SNC1UJ63h4+ahHNzk83QrwicbLyWPHZk4nqvPVqThuykjAdTWym+0zbmLeO1CzOwcVPLMJh/EKjFZ+7bgVU7RVQdmn/Rs0GPOCi+zgh1TrcQJSGam8LYn+GE3D6bh4lHyF9jGZ350BXsL9ft2XXZ2gRbhpK+3gVAtXWRl6oqw25gY8AsFeKd1suDUFqFmtEAh5MdmskarETymZGVwtoX/IDAFJXSKr8LHua/9uQTRdMnMBmTrhXgavldHNupbpk7gnHvzrcfmSfBJinkFpb24TUpWqdef9y5r28iTDMd5Fqzb5/jyVzqG5999mbVJ63pbNxi5Nv1a2iSqW8tclX829lg9k5RmfaURNqHOCL1kTkCf5uv6HPt6MpHJrMushuNnA1ORed9XSaEqZWVlY1rq/rfr9FrVa9WleQ8OqQ/DEkw9LeERzJmoD5oliGp24x09VrXVW91thCDo9mTqrXGjoAgrEC31ut14rJPCIsfl7hEC+SB2nM7wNm6fta23Vbdiuh1ZdaBF17kR1sdV8ZqGbCsl0KUvFWw7SnTN67QO0AYI0a1eu6lazNRWrfe0kZPDcZ8qG6CABsWQ7yVQ2NFkZY1pWyGtQNmey6XG11/wjr1P1RGwiZkstvMGTaxPU9qsO/vgQUv0ewWDfW8sZAlhob9b2VH34bi3qUYfKOHo4mzXnRLX+sa10LX1eh1l7k1dD3Gt6MKGX7Zk5A/Yl6RFzxfw== \ No newline at end of file diff --git a/cdk-ops/docs/data-warehouse-aws-architecture.png b/cdk-ops/docs/data-warehouse-aws-architecture.png new file mode 100644 index 0000000..735dd9b Binary files /dev/null and b/cdk-ops/docs/data-warehouse-aws-architecture.png differ diff --git a/cdk-ops/docs/data-warehouse.ja.md b/cdk-ops/docs/data-warehouse.ja.md new file mode 100644 index 0000000..b55aff6 --- /dev/null +++ b/cdk-ops/docs/data-warehouse.ja.md @@ -0,0 +1,122 @@ +[English](./data-warehouse.md) / 日本語 + +# アクセスログ用のデータウェアハウス + +このCDKスタックはアクセスログ用のデータウェアハウスを確保します。 +データウェアハウスは[Amazon Redshift Serverless](https://aws.amazon.com/redshift/redshift-serverless/)を使って実現しています。 + +## AWSアーキテクチャ + +以下の図はデータウェアハウスのAWSアーキテクチャを表しています。 + +![データウェアハウスのAWSアーキテクチャ](./data-warehouse-aws-architecture.png) + +### Amazon CloudFront + +`Amazon CloudFront`は我々のウェブサイトのコンテンツを配布しアクセスログを[`Amazon S3 access log bucket`](#amazon-s3-access-log-bucket)に保存します。 + +### Amazon S3 access log bucket + +`Amazon S3 access log bucket`は[Amazon S3 (S3)](https://aws.amazon.com/s3/)のバケットで、[`Amazon CloudFront`](#amazon-cloudfront)が作成したアクセスログを格納します。 +このバケットはアクセスログファイルがPUTされた際、[`MaskAccessLogs queue`](#maskaccesslogs-queue)にイベントを送ります。 + +### MaskAccessLogs queue + +`MaskAccessLogs queue`は[Amazon Simple Queue Service (SQS)](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html)のキューで、[`MaskAccessLogs`](#maskaccesslogs)を呼び出します。 +[`Amazon S3 access log bucket`](#amazon-s3-access-log-bucket)はアクセスログファイルがPUTされた際、このキューにイベントを送ります。 + +### MaskAccessLogs + +`MaskAccessLogs`は[AWS Lambda (Lambda)](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html)関数で、[`Amazon S3 access log bucket`](#amazon-s3-access-log-bucket)のアクセスログを変換します。 +この関数は[CloudFrontアクセスログ](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html#LogFileFormat)内のIPアドレス(`c-ip`と`x-forwarded-for`)をマスクします。 +この関数はアクセスログレコードの順序を保持するために行番号のカラムも追加します。 +この関数は変換結果を[`Amazon S3 transformed log bucket`](#amazon-s3-transformed-log-bucket)に保存します。 +[`Amazon S3 access log bucket`](#amazon-s3-access-log-bucket)はアクセスログファイルをフラットに展開するのに対して、この関数はアクセスログレコードの年月日に相当するフォルダ階層を作成します。 +このフォルダ構造は[`LoadAccessLogs`](#loadaccesslogs)が特定の日付のアクセスログをバッチで処理するのに役立ちます。 + +### Amazon S3 transformed log bucket + +`Amazon S3 transformed log bucket`はS3バケットで、[`MaskAccessLogs`](#maskaccesslogs)が変換したアクセスログを格納します。 +このバケットは変換されたアクセスログファイルがPUTされると[`DeleteAccessLogs queue`](#deleteaccesslogs-queue)にイベントを送ります。 + +### DeleteAccessLogs queue + +`DeleteAccessLogs queue`はSQSキューで、[`DeleteAccessLogs`](#deleteaccesslogs)を呼び出します。 +[`Amazon S3 transformed log bucket`](#amazon-s3-transformed-log-bucket)は変換されたアクセスログがPUTされるとこのキューにイベントを送ります。 + +### DeleteAccessLogs + +`DeleteAccessLogs`はLambda関数で、[`MaskAccessLogs`](#maskaccesslogs)が変換し[`Amazon S3 transformed log bucket`](#amazon-s3-transformed-log-bucket)に保存したアクセスログファイルを[`Amazon S3 access log bucket`](#amazon-s3-access-log-bucket)から削除します。 + +### Amazon Redshift Serverless + +`Amazon Redshift Serverless`は[Amazon Redshift Serverless](https://aws.amazon.com/redshift/)のリソースをまとめたもので、データウェアハウスのコアとなります。 + +ひとつの[ファクトテーブル](https://en.wikipedia.org/wiki/Fact_table)と +- `access_log` + +5つの[ディメンジョンテーブル](https://en.wikipedia.org/wiki/Dimension_(data_warehouse))からなります。 +- `referer` +- `page` +- `edge_location` +- `user_agent` +- `result_type` + +`Amazon Redshift Serverless`のノードはプライベートサブネットに配置されます。 +Lambda関数([`PopulateDwDatabase`](#populatedwdatabase), [`LoadAccessLogs`](#loadaccesslogs), [`VacuumTable`](#vacuumtable))は[`Amazon Redshift Data API`](#amazon-redshift-data-api)を介して`Amazon Redshift Serverless`を操作します。 + +[Amazon Redshift Serverlessネームスペース](https://docs.aws.amazon.com/redshift/latest/mgmt/serverless-workgroup-namespace.html)のデフォルトロール([`Redshift namespace role`](#redshift-namespace-role))は[`Amazon S3 transformed log bucket`](#amazon-s3-transformed-log-bucket)からオブジェクトを読み込むことができます。 +`Amazon Redshift Serverless`は[`Gateway endpoint`](#gateway-endpoint)を介して[`Amazon S3 transformed log bucket`](#amazon-s3-transformed-log-bucket)にアクセスします。 + +このCDKスタックは`Amazon Redshift Serverless`を確保する際に管理ユーザーを作成します。 +[`AWS Secrets Manager`](#aws-secrets-manager)は管理ユーザーのパスワードを生成・管理します。 + +### Redshift namespace role + +`Redshift namespace role`は[AWS Identity and Access Management (IAM)](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html)のロールで、[`Amazon Redshift Serverless`](#amazon-redshift-serverless)のネームスペースのデフォルトロールであり[`Amazon S3 transformed log bucket`](#amazon-s3-transformed-log-bucket)からオブジェクトを読み込むことができます。 + +### Gateway endpoint + +`Gateway endpoint`は[`Amazon Redshift Serverless`](#amazon-redshift-serverless)と[`Amazon S3 transformed log bucket`](#amazon-s3-transformed-log-bucket)の間のトラフィックがインターネットに出て行かないようにします。 +詳しくは["Enhanced VPC routing in Amazon Redshift" - *Amazon Redshift Management Guide*](https://docs.aws.amazon.com/redshift/latest/mgmt/enhanced-vpc-routing.html)をご参照ください。 + +### AWS Secrets Manager + +`AWS Secrets Manager`は[`Amazon Redshift Serverless`](#amazon-redshift-serverless)の管理ユーザーのパスワードを生成・管理します。 +[*AWS Secrets Manager User Guide*](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html)もご参照ください。 + +残念ながら、`AWS Secrets Manager`が管理するシークレットは[`Amazon Redshift Serverless`](#amazon-redshift-serverless)の管理パスワードと同期していません(初回生成時を除く)。 +なので`AWS Secrets Manager`が新しいシークレットを生成してしまった際には、[`Amazon Redshift Serverless`](#amazon-redshift-serverless)の管理パスワードを手作業でリセットしなければなりません(対処方法は[READMEの「Amazon Redshift Serverlessネームスペースの管理ユーザー」](../README.ja.md#amazon-redshift-serverlessネームスペースの管理ユーザー)をご参照ください)。 + +### Amazon Redshift Data API + +`Amazon Redshift Data API`は[`Amazon Redshift Serverless`](#amazon-redshift-serverless)のクライアントをデータベースへの接続を管理することから解放してくれます。 +詳しくは["Using the Amazon Redshift Data API" - *Amazon Redshift Management Guide*](https://docs.aws.amazon.com/redshift/latest/mgmt/data-api.html)をご参照ください。 + +### PopulateDwDatabase + +`PopulateDwDatabase`はLambda関数で、アクセスログを格納するデータベースとテーブルを[`Amazon Redshift Serverless`](#amazon-redshift-serverless)に作成します。 +この関数は[`Amazon Redshift Serverless`](#amazon-redshift-serverless)の管理クレデンシャルを[`AWS Secrets Manager`](#aws-secrets-manager)から取得します。 +管理者(`Admin`)はこのCDKスタックをデプロイした後にこの関数を呼び出さなければなりません。 + +### Amazon EventBridge + +`Amazon EventBridge`は毎日午前2時(UTC)に[`LoadAccessLogs`](#loadaccesslogs)を実行する[Amazon EventBridgeのルール](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule-schedule.html)を定義します。 + +### LoadAccessLogs + +`LoadAccessLogs`はLambda関数で、指定した日付のアクセスログを[`Amazon Redshift Serverless`](#amazon-redshift-serverless)に読み込みます。 +この関数はアクセスログの読み込みが終了すると[`AWS Step Functions`](#aws-step-functions)を実行します。 +[`Amazon EventBridge`](#amazon-eventbridge)は1日に1回この関数を実行します。 + +この関数は[`Amazon EventBridge`](#amazon-eventbridge)から呼び出すことを想定していますが、適切なペイロードを与えて手作業で実行することもできます。 + +### AWS Step Functions + +`AWS Step Functions`は[`Amazon Redshift Serverless`](#amazon-redshift-serverless)のすべてのテーブル(`access_log`, `referer`, `page`, `edge_location`, `user_agent`, `result_type`)に対して[`VacuumTable`](#vacuumtable)を実行する[AWS Step Functionsのステートマシン](https://docs.aws.amazon.com/step-functions/latest/dg/welcome.html)を定義します。 +[`VACUUM` SQLコマンド](https://docs.aws.amazon.com/redshift/latest/dg/r_VACUUM_command.html)の実行は同時に1つしか許されていないので、`AWS Step Functions`はテーブルをひとつずつ[`VacuumTable`](#vacuumtable)で処理します。 + +### VacuumTable + +`VacuumTable`はLambda関数で、[`VACUUM` SQLコマンド](https://docs.aws.amazon.com/redshift/latest/dg/r_VACUUM_command.html)を指定したテーブルに対して実行します。 +この関数は[`Amazon Redshift Serverless`](#amazon-redshift-serverless)の管理クレデンシャルを[`AWS Secrets Manager`](#aws-secrets-manager)から取得します。 \ No newline at end of file diff --git a/cdk-ops/docs/data-warehouse.md b/cdk-ops/docs/data-warehouse.md new file mode 100644 index 0000000..4a80014 --- /dev/null +++ b/cdk-ops/docs/data-warehouse.md @@ -0,0 +1,122 @@ +English / [日本語](./data-warehouse.ja.md) + +# Data warehouse for access logs + +This CDK stack provisions a data warehouse for access logs. +The data warehouse is backed by [Amazon Redshift Serverless](https://aws.amazon.com/redshift/redshift-serverless/). + +## AWS architecture + +The following diagram shows the AWS architecture of the data warehouse. + +![AWS architecture for data warehouse](./data-warehouse-aws-architecture.png) + +### Amazon CloudFront + +`Amazon CloudFront` distributes the contents of our website and saves access logs in [`Amazon S3 access log bucket`](#amazon-s3-access-log-bucket). + +### Amazon S3 access log bucket + +`Amazon S3 access log bucket` is an [Amazon S3 (S3)](https://aws.amazon.com/s3/) bucket that stores access logs created by [`Amazon CloudFront`](#amazon-cloudfront). +This bucket sends an event to [`MaskAccessLogs queue`](#maskaccesslogs-queue) when an access logs file is PUT into this bucket. + +### MaskAccessLogs queue + +`MaskAccessLogs queue` is an [Amazon Simple Queue Service (SQS)](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html) queue that invokes [`MaskAccessLogs`](#maskaccesslogs). +[`Amazon S3 access log bucket`](#amazon-s3-access-log-bucket) sends an event to this queue when an access logs file is PUT into the bucket. + +### MaskAccessLogs + +`MaskAccessLogs` is an [AWS Lambda (Lambda)](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) function that transforms access logs in [`Amazon S3 access log bucket`](#amazon-s3-access-log-bucket). +This function masks IP addresses, `c-ip` and `x-forwarded-for`, in the [CloudFront access logs](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html#LogFileFormat). +This function also introduces a new column of row numbers to retain the order of the access log records. +This function saves transformed results in [`Amazon S3 transformed log bucket`](#amazon-s3-transformed-log-bucket). +While [`Amazon S3 access log bucket`](#amazon-s3-access-log-bucket) spreads access logs files flat, this function creates a folder hierarchy corresponding to the year, month, and day of access log records. +This folder structure helps [`LoadAccessLogs`](#loadaccesslogs) to process access logs on a specific date in a batch. + +### Amazon S3 transformed log bucket + +`Amazon S3 transformed log bucket` is an S3 bucket that stores access logs transformed by [`MaskAccessLogs`](#maskaccesslogs). +This bucket sends an event to [`DeleteAccessLogs queue`](#deleteaccesslogs-queue) when a transformed access logs file is PUT into this bucket. + +### DeleteAccessLogs queue + +`DeleteAccessLogs queue` is an SQS queue that invokes [`DeleteAccessLogs`](#deleteaccesslogs). +[`Amazon S3 transformed log bucket`](#amazon-s3-transformed-log-bucket) sends an event to this queue when a transformed access logs file is PUT into the bucket. + +### DeleteAccessLogs + +`DeleteAccessLogs` is a Lambda function that deletes an access logs file from [`Amazon S3 access log bucket`](#amazon-s3-access-log-bucket), which [`MaskAccessLogs`](#maskaccesslogs) has transformed and saved in [`Amazon S3 transformed log bucket`](#amazon-s3-transformed-log-bucket). + +### Amazon Redshift Serverless + +`Amazon Redshift Serverless` is a bundle of [Amazon Redshift Serverless](https://aws.amazon.com/redshift/) resources, which is the core of the data warehouse. + +It has one [fact table](https://en.wikipedia.org/wiki/Fact_table), +- `access_log` + +and five [dimension tables](https://en.wikipedia.org/wiki/Dimension_(data_warehouse)), +- `referer` +- `page` +- `edge_location` +- `user_agent` +- `result_type` + +Nodes of `Amazon Redshift Serverless` reside in a private subnet. +Lambda functions, [`PopulateDwDatabase`](#populatedwdatabase), [`LoadAccessLogs`](#loadaccesslogs), and [`VacuumTable`](#vacuumtable) operate `Amazon Redshift Serverless` via [`Amazon Redshift Data API`](#amazon-redshift-data-api). + +The default role of the [Amazon Redshift Serverless namespace](https://docs.aws.amazon.com/redshift/latest/mgmt/serverless-workgroup-namespace.html) ([`Redshift namespace role`](#redshift-namespace-role)) can read objects from [`Amazon S3 transformed log bucket`](#amazon-s3-transformed-log-bucket). +`Amazon Redshift Serverless` accesses [`Amazon S3 transformed log bucket`](#amazon-s3-transformed-log-bucket) through [`Gateway endpoint`](#gateway-endpoint). + +This CDK stack creates an admin user when it provisions `Amazon Redshift Serverless`. +[`AWS Secrets Manager`](#aws-secrets-manager) generates and manages the password of the admin user. + +### Redshift namespace role + +`Redshift namespace role` is an [AWS Identity and Access Management (IAM)](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html) role that is the default role of the namespace of [`Amazon Redshift Serverless`](#amazon-redshift-serverless) and can read objects from [`Amazon S3 transformed log bucket`](#amazon-s3-transformed-log-bucket). + +### Gateway endpoint + +`Gateway endpoint` ensures traffic between [`Amazon Redshift Serverless`](#amazon-redshift-serverless) and [`Amazon S3 transformed log bucket`](#amazon-s3-transformed-log-bucket) never goes through the Internet. +Please refer to ["Enhanced VPC routing in Amazon Redshift" - *Amazon Redshift Management Guide*](https://docs.aws.amazon.com/redshift/latest/mgmt/enhanced-vpc-routing.html) for more details. + +### AWS Secrets Manager + +`AWS Secrets Manager` generates and manages the password of the admin user of [`Amazon Redshift Serverless`](#amazon-redshift-serverless). +Please also refer to [*AWS Secrets Manager User Guide*](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html). + +Unfortunately, the secret managed by `AWS Secrets Manager` does not sync with the admin password of [`Amazon Redshift Serverless`](#amazon-redshift-serverless) except for the first time it is generated. +So you have to manually reset the admin password of [`Amazon Redshift Serverless`](#amazon-redshift-serverless) in case `AWS Secrets Manager` generates a new secret; please refer to ["Admin user of the Amazon Redshift Serverless namespace" in *README*](../README.md#admin-user-of-the-amazon-redshift-serverless-namespace) for how to deal with it. + +### Amazon Redshift Data API + +`Amazon Redshift Data API` relieves clients of [`Amazon Redshift Serverless`](#amazon-redshift-serverless) of managing connections to the database. +Please refer to ["Using the Amazon Redshift Data API" - *Amazon Redshift Management Guide*](https://docs.aws.amazon.com/redshift/latest/mgmt/data-api.html) for more details. + +### PopulateDwDatabase + +`PopulateDwDatabase` is a Lambda function that populates the database and tables to store access logs on [`Amazon Redshift Serverless`](#amazon-redshift-serverless). +This function obtains the admin credentials of [`Amazon Redshift Serverless`](#amazon-redshift-serverless) from [`AWS Secrets Manager`](#aws-secrets-manager). +The administrator (`Admin`) has to run this function after deploying this CDK stack. + +### Amazon EventBridge + +`Amazon EventBridge` defines an [Amazon EventBridge rule](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule-schedule.html) that runs [`LoadAccessLogs`](#loadaccesslogs) every 2 AM in UTC. + +### LoadAccessLogs + +`LoadAccessLogs` is a Lambda function that loads access logs on a specific date onto [`Amazon Redshift Serverless`](#amazon-redshift-serverless). +This function executes [`AWS Step Functions`](#aws-step-functions) after the access log loading finishes. +[`Amazon EventBridge`](#amazon-eventbridge) runs this function once a day. + +While this function is intended to be invoked by [`Amazon EventBridge`](#amazon-eventbridge), you can also manually run this function with a proper payload. + +### AWS Step Functions + +`AWS Step Functions` defines an [AWS Step Functions state machine](https://docs.aws.amazon.com/step-functions/latest/dg/welcome.html) that runs [`VacuumTable`](#vacuumtable) over every table on [`Amazon Redshift Serverless`](#amazon-redshift-serverless); `access_log`, `referer`, `page`, `edge_location`, `user_agent`, and `result_type`. +Since only a single execution of the [`VACUUM` SQL command](https://docs.aws.amazon.com/redshift/latest/dg/r_VACUUM_command.html) is allowed at once, `AWS Step Functions` processes tables with [`VacuumTable`](#vacuumtable) one by one. + +### VacuumTable + +`VacuumTable` is a Lambda function that runs the [`VACUUM` SQL command](https://docs.aws.amazon.com/redshift/latest/dg/r_VACUUM_command.html) over a specified table. +This function obtains the admin credentials of [`Amazon Redshift Serverless`](#amazon-redshift-serverless) from [`AWS Secrets Manager`](#aws-secrets-manager). \ No newline at end of file diff --git a/cdk-ops/lambda/delete-access-logs/index.py b/cdk-ops/lambda/delete-access-logs/index.py new file mode 100644 index 0000000..2c28a40 --- /dev/null +++ b/cdk-ops/lambda/delete-access-logs/index.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- + +"""Deletes the original CloudFront access logs file corresponding to a given +masked access logs file. + +You have to specify the following environment variables, +* ``SOURCE_BUCKET_NAME``: name of the S3 bucket containing original CloudFront + access logs files +* ``DESTINATION_BUCKET_NAME``: name of the S3 bucket containing transformed + CloudFront access logs files +* ``DESTINATION_KEY_PREFIX``: prefix of S3 object keys, which corresponds to + masked access logs +""" + +import json +import logging +import os +import boto3 +from botocore.exceptions import ClientError + + +SOURCE_BUCKET_NAME = os.environ['SOURCE_BUCKET_NAME'] +DESTINATION_BUCKET_NAME = os.environ['DESTINATION_BUCKET_NAME'] +DESTINATION_KEY_PREFIX = os.environ['DESTINATION_KEY_PREFIX'] + +LOGGER = logging.getLogger(__name__) +LOGGER.setLevel(logging.DEBUG) + +s3 = boto3.resource('s3') +source_bucket = s3.Bucket(SOURCE_BUCKET_NAME) + + +def lambda_handler(event, _): + """Delete original CloudFront access logs files. + + ``event`` is supposed to be SQS events described at + https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html + + Each SQS event is supposed to be an object-creation notification from the + S3 bucket containing masked access logs. + """ + for record in event['Records']: + body = record.get('body') + if body is None: + LOGGER.error('invalid SQS record: %s', str(record)) + continue + try: + message = json.loads(body) + except json.JSONDecodeError: + LOGGER.error('invalid SQS record: %s', str(record)) + continue + # may receive a test message "s3:TestEvent" + # and a test message does not have "Records" + entries = message.get('Records') + if entries is None: + LOGGER.debug('maybe a test message: %s', str(message)) + continue + for entry in entries: + event_name = entry.get('eventName', '?') + if event_name.startswith('ObjectCreated:'): + s3_object = entry.get('s3') + if s3_object is None: + LOGGER.error('invalid S3 event: %s', str(entry)) + else: + process_s3_object(s3_object) + else: + LOGGER.error( + 'event "%s" other than S3 object creation was notified.' + ' please check the event source configuration', + event_name, + ) + return {} + + +def process_s3_object(s3_object): + """Processes a given S3 object event. + + ``s3_object`` must conform to an S3 object creation event described at + https://docs.aws.amazon.com/lambda/latest/dg/with-s3.html + """ + LOGGER.debug('processing S3 object event: %s', str(s3_object)) + # makes sure that the destination bucket matches + bucket_name = s3_object.get('bucket', {}).get('name') + if bucket_name is None: + LOGGER.error('no bucket name in S3 object event: %s', str(s3_object)) + return + if bucket_name != DESTINATION_BUCKET_NAME: + LOGGER.warning( + 'bucket name must be "%s" but "%s" was given.' + ' please check the event source configuration', + DESTINATION_BUCKET_NAME, + bucket_name, + ) + return + key = s3_object.get('object', {}).get('key') + if key is None: + LOGGER.error('no object key in S3 object event: %s', str(s3_object)) + return + if not key.startswith(DESTINATION_KEY_PREFIX): + LOGGER.warning( + '"%s" does not have the preifx "%s".' + ' please check the event source configuration', + key, + DESTINATION_KEY_PREFIX, + ) + return + # key should be like, + # {DESTINATION_KEY_PREFIX}{year}/{month}/{date}/{original_key} + # so the last segment separated by a slash ('/') is the key for the + # original access logs file. + src_key = key.split('/')[-1] + if len(src_key) > 0: + src = source_bucket.Object(src_key) + try: + res = src.delete() + LOGGER.debug('deleted object "%s": %s', src_key, str(res)) + except ClientError as exc: + LOGGER.error('failed to delete object "%s": %s', src_key, str(exc)) + else: + LOGGER.warning('ignoring invalid key: %s', key) diff --git a/cdk-ops/lambda/latest-boto3/requirements.txt b/cdk-ops/lambda/latest-boto3/requirements.txt new file mode 100644 index 0000000..031ddd5 --- /dev/null +++ b/cdk-ops/lambda/latest-boto3/requirements.txt @@ -0,0 +1,2 @@ +boto3==1.24.75 +botocore==1.27.75 diff --git a/cdk-ops/lambda/libdatawarehouse/.gitignore b/cdk-ops/lambda/libdatawarehouse/.gitignore new file mode 100644 index 0000000..d3b6142 --- /dev/null +++ b/cdk-ops/lambda/libdatawarehouse/.gitignore @@ -0,0 +1,2 @@ +/build +*.egg-info diff --git a/cdk-ops/lambda/libdatawarehouse/pyproject.toml b/cdk-ops/lambda/libdatawarehouse/pyproject.toml new file mode 100644 index 0000000..9787c3b --- /dev/null +++ b/cdk-ops/lambda/libdatawarehouse/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" diff --git a/cdk-ops/lambda/libdatawarehouse/setup.cfg b/cdk-ops/lambda/libdatawarehouse/setup.cfg new file mode 100644 index 0000000..35d5dcf --- /dev/null +++ b/cdk-ops/lambda/libdatawarehouse/setup.cfg @@ -0,0 +1,13 @@ +[metadata] +name = libdatawarehouse +version = attr: libdatawarehouse.VERSION +description = Library for Codemonger Data Warehouse + +[options] +packages = + libdatawarehouse +package_dir = + = src + +[options.package_data] +libdatawarehouse = *.pyi, py.typed diff --git a/cdk-ops/lambda/libdatawarehouse/src/libdatawarehouse/__init__.py b/cdk-ops/lambda/libdatawarehouse/src/libdatawarehouse/__init__.py new file mode 100644 index 0000000..77e4928 --- /dev/null +++ b/cdk-ops/lambda/libdatawarehouse/src/libdatawarehouse/__init__.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- + +"""Library for Codemonger Data Warehouse. +""" + +VERSION = '0.1.0' + +ACCESS_LOGS_DATABASE_NAME = 'access_logs' diff --git a/cdk-ops/lambda/libdatawarehouse/src/libdatawarehouse/data_api.py b/cdk-ops/lambda/libdatawarehouse/src/libdatawarehouse/data_api.py new file mode 100644 index 0000000..826ea90 --- /dev/null +++ b/cdk-ops/lambda/libdatawarehouse/src/libdatawarehouse/data_api.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- + +"""Provides utilities to access the Redshift Data API. +""" + +import time +from typing import Dict, Optional, Tuple + + +RUNNING_STATUSES = ['SUBMITTED', 'PICKED', 'STARTED'] + + +def wait_for_results( + client, + statement_id: str, + polling_interval: float = 0.05, + timeout: float = 300.0, + cancel_at_timeout: bool = True, +) -> Tuple[Optional[str], Dict]: + """Waits for a given statement to finish. + + :param RedshiftDataAPIService.Client client: Redshift Data API client. + + :param float polling_interval: interval in seconds between two consecutive + pollings. + + :param float timeout: timeout in seconds. + + :param bool cancel_at_timeout: whether cancels the statement when it times + out. + """ + start_time = time.time() + while True: + res = client.describe_statement(Id=statement_id) + status = res['Status'] + if status not in RUNNING_STATUSES: + return status, res + elapsed = time.time() - start_time + if elapsed >= timeout: + if cancel_at_timeout: + client.cancel_statement(Id=statement_id) + return None, res + time.sleep(polling_interval) diff --git a/cdk-ops/lambda/libdatawarehouse/src/libdatawarehouse/exceptions.py b/cdk-ops/lambda/libdatawarehouse/src/libdatawarehouse/exceptions.py new file mode 100644 index 0000000..7e16388 --- /dev/null +++ b/cdk-ops/lambda/libdatawarehouse/src/libdatawarehouse/exceptions.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +"""Common exceptions. +""" + +class DataWarehouseException(Exception): + """Base exception raised when a data warehouse operation fails. + """ + def __init__(self, message: str): + """Initializes with a message. + """ + self.message = message + + + def __str__(self) -> str: + classname = type(self).__name__ + return f'{classname}({self.message})' + + + def __repr__(self) -> str: + classname = type(self).__name__ + return f'{classname}({repr(self.message)})' diff --git a/cdk-ops/lambda/libdatawarehouse/src/libdatawarehouse/py.typed b/cdk-ops/lambda/libdatawarehouse/src/libdatawarehouse/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/cdk-ops/lambda/libdatawarehouse/src/libdatawarehouse/tables.py b/cdk-ops/lambda/libdatawarehouse/src/libdatawarehouse/tables.py new file mode 100644 index 0000000..1a727fa --- /dev/null +++ b/cdk-ops/lambda/libdatawarehouse/src/libdatawarehouse/tables.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- + +"""Tables in the data warehouse. +""" + +ACCESS_LOG_TABLE_NAME = 'access_log' + +REFERER_TABLE_NAME = 'referer' + +PAGE_TABLE_NAME = 'page' + +USER_AGENT_TABLE_NAME = 'user_agent' + +EDGE_LOCATION_TABLE_NAME = 'edge_location' + +RESULT_TYPE_TABLE_NAME = 'result_type' diff --git a/cdk-ops/lambda/load-access-logs/index.py b/cdk-ops/lambda/load-access-logs/index.py new file mode 100644 index 0000000..98bcfa1 --- /dev/null +++ b/cdk-ops/lambda/load-access-logs/index.py @@ -0,0 +1,576 @@ +# -*- coding: utf-8 -*- + +"""Loads CloudFront access logs onto the data warehouse. + +You have to specify the following environment variables, +* ``SOURCE_BUCKET_NAME``: name of the S3 bucket containing access logs to be + loaded. +* ``SOURCE_OBJECT_KEY_PREFIX``: prefix of the S3 object keys to be loaded. +* ``REDSHIFT_WORKGROUP_NAME``: name of the Redshift Serverless workgroup. +* ``COPY_ROLE_ARN``: ARN of the IAM role to COPY data from the S3 object. +""" + +import datetime +import json +import logging +import os +import boto3 +from libdatawarehouse import ACCESS_LOGS_DATABASE_NAME, data_api, tables +from libdatawarehouse.exceptions import DataWarehouseException + + +SOURCE_BUCKET_NAME = os.environ['SOURCE_BUCKET_NAME'] +SOURCE_KEY_PREFIX = os.environ['SOURCE_KEY_PREFIX'] +REDSHIFT_WORKGROUP_NAME = os.environ['REDSHIFT_WORKGROUP_NAME'] +COPY_ROLE_ARN = os.environ['COPY_ROLE_ARN'] +VACUUM_WORKFLOW_ARN = os.environ['VACUUM_WORKFLOW_ARN'] + +LOGGER = logging.getLogger(__name__) +LOGGER.setLevel(logging.DEBUG) + +s3 = boto3.client('s3') + +redshift = boto3.client('redshift-serverless') +redshift_data = boto3.client('redshift-data') +stepfunctions = boto3.client('stepfunctions') + + +def has_access_logs(date: datetime.datetime) -> bool: + """Returns whether there are access logs on a given date. + """ + access_logs_prefix = get_access_logs_prefix(date) + res = s3.list_objects_v2( + Bucket=SOURCE_BUCKET_NAME, + Prefix=access_logs_prefix, + MaxKeys=1, + ) + return len(res.get('Contents', [])) > 0 + + +def execute_load_script(date: datetime.datetime): + """Executes the script to load CloudFront access logs. + + :param datetime.datetime date: date on which CloudFront access logs are to + be loaded. + """ + batch_res = redshift_data.batch_execute_statement( + WorkgroupName=REDSHIFT_WORKGROUP_NAME, + Database=ACCESS_LOGS_DATABASE_NAME, + Sqls=[ + # drops remaining temporary tables just in case + get_drop_raw_access_log_table_statement(), + get_drop_referer_stage_table_statement(), + get_drop_page_stage_table_statement(), + get_drop_edge_location_stage_table_statement(), + get_drop_user_agent_stage_table_statement(), + get_drop_access_log_stage_2_table_statement(), + get_drop_access_log_stage_table_statement(), + + get_create_raw_access_log_table_statement(), + get_load_access_logs_statement(date), + get_create_access_log_stage_table_statement(), + get_drop_raw_access_log_table_statement(), + get_create_referer_stage_table_statement(), + get_delete_existing_referers_statement(), + get_insert_referers_statement(), + get_drop_referer_stage_table_statement(), + get_create_page_stage_table_statement(), + get_delete_existing_pages_statement(), + get_insert_pages_statement(), + get_drop_page_stage_table_statement(), + get_create_edge_location_stage_table_statement(), + get_delete_existing_edge_locations_statement(), + get_insert_edge_locations_statement(), + get_drop_edge_location_stage_table_statement(), + get_create_user_agent_stage_table_statement(), + get_delete_existing_user_agents_statement(), + get_insert_user_agents_statement(), + get_drop_user_agent_stage_table_statement(), + get_create_result_type_stage_table_statement(), + get_delete_existing_result_types_statement(), + get_insert_result_types_statement(), + get_drop_result_type_stage_table_statement(), + get_encode_foreign_keys_statement(), + get_insert_access_logs_statement(), + get_drop_access_log_stage_2_table_statement(), + get_drop_access_log_stage_table_statement(), + ], + ) + statement_id = batch_res['Id'] + status, res = data_api.wait_for_results(redshift_data, statement_id) + if status != 'FINISHED': + if status is not None: + if status == 'FAILED': + LOGGER.error('failed to load access logs: %s', str(res)) + raise DataWarehouseException( + f'failed to load access logs: {status}', + ) + raise DataWarehouseException('loading access logs timed out') + LOGGER.debug( + 'loaded access logs in %.3f ms', + res.get('Duration', 0) * 0.001 * 0.001, # ns → ms + ) + + +def get_create_raw_access_log_table_statement() -> str: + """Returns an SQL statement that creates a temporary table to load raw + access logs from the S3 bucket. + """ + return ''.join([ + 'CREATE TABLE #raw_access_log (', + ' seq_num INT,', + ' date DATE,', + ' time TIME,', + ' edge_location VARCHAR,', + ' sc_bytes BIGINT,', + ' c_ip VARCHAR,', + ' cs_method VARCHAR,', + ' cs_host VARCHAR,', + ' cs_uri_stem VARCHAR(2048),', + ' status SMALLINT,', + ' referer VARCHAR(2048),', + ' user_agent VARCHAR(2048),', + ' cs_uri_query VARCHAR,', + ' cs_cookie VARCHAR,', + ' edge_result_type VARCHAR,', + ' edge_request_id VARCHAR,', + ' host_header VARCHAR,', + ' cs_protocol VARCHAR,', + ' cs_bytes BIGINT,', + ' time_taken FLOAT4,', + ' forwarded_for VARCHAR,', + ' ssl_protocol VARCHAR,', + ' ssl_cipher VARCHAR,', + ' edge_response_result_type VARCHAR,', + ' cs_protocol_version VARCHAR,', + ' fle_status VARCHAR,', + ' fle_encrypted_fields VARCHAR,', + ' c_port INT,', + ' time_to_first_byte FLOAT4,', + ' edge_detailed_result_type VARCHAR,', + ' sc_content_type VARCHAR,', + ' sc_content_len BIGINT,', + ' sc_range_start BIGINT,', + ' sc_range_end BIGINT', + ')', + 'SORTKEY (date, time, seq_num)', + ]) + + +def get_load_access_logs_statement(date: datetime.datetime) -> str: + """Returns an SQL statement that loads access logs from the S3 bucket. + """ + access_logs_prefix = get_access_logs_prefix(date) + return ''.join([ + 'COPY #raw_access_log', + f" FROM 's3://{SOURCE_BUCKET_NAME}/{access_logs_prefix}'", + f" IAM_ROLE '{COPY_ROLE_ARN}'", + ' GZIP', + " DELIMITER '\t'", + ' IGNOREHEADER 1', + " NULL AS '-'", + ]) + + +def get_create_access_log_stage_table_statement() -> str: + """Returns an SQL statement that creates a temporary table to select and + format access log columns. + """ + return ''.join([ + 'CREATE TABLE #access_log_stage (', + ' datetime,', + ' seq_num,', + ' edge_location,', + ' sc_bytes,', + ' cs_method,', + ' cs_uri_stem,', + ' status,', + ' referer,', + ' user_agent,', + ' cs_protocol,', + ' cs_bytes,', + ' time_taken,', + ' edge_response_result_type,', + ' time_to_first_byte', + ')', + ' SORTKEY ("datetime", seq_num)', + ' AS SELECT', + ' ("date" || \' \' || "time")::TIMESTAMP,', + ' seq_num,', + ' edge_location,', + ' sc_bytes,', + ' cs_method,', + ' cs_uri_stem,', + ' status,', + " CASE WHEN referer IS NULL THEN '-' ELSE referer END,", + " CASE WHEN user_agent IS NULL THEN '-' ELSE user_agent END,", + ' cs_protocol,', + ' cs_bytes,', + ' time_taken,', + ' edge_response_result_type,', + ' time_to_first_byte', + ' FROM #raw_access_log', + ]) + + +def get_drop_raw_access_log_table_statement() -> str: + """Returns an SQL statement that drops the temporary table to load raw + access logs from the S3 bucket. + """ + return get_drop_table_statement('#raw_access_log') + + +def get_create_referer_stage_table_statement() -> str: + """Returns an SQL statement that creates a temporary table to aggregate + referers. + """ + return ''.join([ + 'CREATE TABLE #referer_stage (url)', + ' SORTKEY (url)', + ' AS SELECT referer FROM #access_log_stage', + ]) + + +def get_delete_existing_referers_statement() -> str: + """Returns an SQL statement that deletes existing referers from the + temporary referer table. + """ + return ''.join([ + 'DELETE FROM #referer_stage', + f' USING {tables.REFERER_TABLE_NAME}', + ' WHERE', + f' #referer_stage.url = {tables.REFERER_TABLE_NAME}.url', + ]) + + +def get_insert_referers_statement() -> str: + """Returns an SQL statement that inserts new referers in the temporary + table into the referer table. + """ + return ''.join([ + f'INSERT INTO {tables.REFERER_TABLE_NAME} (url)', + ' SELECT url FROM #referer_stage GROUP BY url', + ]) + + +def get_drop_referer_stage_table_statement() -> str: + """Returns an SQL statement that drops the temporary table to aggregate + referers. + """ + return get_drop_table_statement('#referer_stage') + + +def get_create_page_stage_table_statement() -> str: + """Returns an SQL statement that creates a temporary table to aggregate + pages. + """ + return ''.join([ + 'CREATE TABLE #page_stage (path)', + ' SORTKEY (path)', + ' AS SELECT cs_uri_stem FROM #access_log_stage', + ]) + + +def get_delete_existing_pages_statement() -> str: + """Returns an SQL statement that deletes existing pages from the temporary + page table. + """ + return ''.join([ + 'DELETE FROM #page_stage', + f' USING {tables.PAGE_TABLE_NAME}', + ' WHERE', + f' #page_stage.path = {tables.PAGE_TABLE_NAME}.path', + ]) + + +def get_insert_pages_statement() -> str: + """Returns an SQL statement that inserts new pages in the temporary table + into the stage table. + """ + return ''.join([ + f'INSERT INTO {tables.PAGE_TABLE_NAME} (path)', + ' SELECT path FROM #page_stage GROUP BY path', + ]) + + +def get_drop_page_stage_table_statement() -> str: + """Returns an SQL statement that drops the temporary table to aggregate + pages. + """ + return get_drop_table_statement('#page_stage') + + +def get_create_edge_location_stage_table_statement() -> str: + """Returns an SQL statement that creates a temporary table to aggregate edge + locations. + """ + return ''.join([ + 'CREATE TABLE #edge_location_stage (code)', + ' SORTKEY (code)', + ' AS SELECT edge_location FROM #access_log_stage', + ]) + + +def get_delete_existing_edge_locations_statement() -> str: + """Returns an SQL statement that deletes existing edge locations from the + tempoary edge location table. + """ + return ''.join([ + 'DELETE FROM #edge_location_stage', + f' USING {tables.EDGE_LOCATION_TABLE_NAME}', + ' WHERE', + f' #edge_location_stage.code = {tables.EDGE_LOCATION_TABLE_NAME}.code', + ]) + + +def get_insert_edge_locations_statement() -> str: + """Returns an SQL statement that inserts new edge locations in the temporary + table into the edge location table. + """ + return ''.join([ + f'INSERT INTO {tables.EDGE_LOCATION_TABLE_NAME} (code)', + ' SELECT code FROM #edge_location_stage GROUP BY code', + ]) + + +def get_drop_edge_location_stage_table_statement() -> str: + """Returns an SQL statement that drops the temporary table to aggregate edge + locations. + """ + return get_drop_table_statement('#edge_location_stage') + + +def get_create_user_agent_stage_table_statement() -> str: + """Returns an SQL statement that creates a temporary table to aggregate user + agents. + """ + return ''.join([ + 'CREATE TABLE #user_agent_stage (user_agent)', + ' SORTKEY (user_agent)', + ' AS SELECT user_agent FROM #access_log_stage', + ]) + + +def get_delete_existing_user_agents_statement() -> str: + """Returns an SQL statement that deletes existing user agents from the + temporary user agent table. + """ + return ''.join([ + 'DELETE FROM #user_agent_stage', + f' USING {tables.USER_AGENT_TABLE_NAME}', + ' WHERE', + f' #user_agent_stage.user_agent = {tables.USER_AGENT_TABLE_NAME}.user_agent', + ]) + + +def get_insert_user_agents_statement() -> str: + """Returns an SQL statement that inserts user agents in the temporary table + into the user agent table. + """ + return ''.join([ + f'INSERT INTO {tables.USER_AGENT_TABLE_NAME} (user_agent)', + ' SELECT user_agent FROM #user_agent_stage GROUP BY user_agent', + ]) + + +def get_drop_user_agent_stage_table_statement() -> str: + """Returns an SQL statement that drops the temporary table to aggregate user + agents. + """ + return get_drop_table_statement('#user_agent_stage') + + +def get_create_result_type_stage_table_statement() -> str: + """Returns an SQL statement that creates a temporary table to aggregate + result types. + """ + return ''.join([ + 'CREATE TABLE #result_type_stage (result_type)', + ' SORTKEY (result_type)', + ' AS SELECT edge_response_result_type FROM #access_log_stage', + ]) + + +def get_delete_existing_result_types_statement() -> str: + """Returns an SQL statement that deletes existing result types from the + temporary result type table. + """ + return ''.join([ + 'DELETE FROM #result_type_stage', + f' USING {tables.RESULT_TYPE_TABLE_NAME}', + ' WHERE', + f' #result_type_stage.result_type = {tables.RESULT_TYPE_TABLE_NAME}.result_type', + ]) + + +def get_insert_result_types_statement() -> str: + """Returns an SQL statement that inserts result types in the temporary table + into the result type table. + """ + return ''.join([ + f'INSERT INTO {tables.RESULT_TYPE_TABLE_NAME} (result_type)', + ' SELECT result_type FROM #result_type_stage GROUP BY result_type', + ]) + + +def get_drop_result_type_stage_table_statement() -> str: + """Returns an SQL statement that drops the temporary table to aggregate + result types. + """ + return get_drop_table_statement('#result_type_stage') + + +def get_encode_foreign_keys_statement() -> str: + """Returns an SQL statement that decodes foreign keys in the temporary + access log table and creates a temporary second staging table. + """ + return ''.join([ + 'CREATE TABLE #access_log_stage_2 (', + ' datetime,', + ' seq_num,', + ' edge_location,', + ' sc_bytes,', + ' cs_method,', + ' page,', + ' status,', + ' referer,', + ' user_agent,', + ' cs_protocol,', + ' cs_bytes,', + ' time_taken,', + ' edge_response_result_type,', + ' time_to_first_byte', + ')', + ' DISTKEY (referer)', + ' SORTKEY ("datetime", seq_num)', + ' AS SELECT', + ' #access_log_stage.datetime,', + ' #access_log_stage.seq_num,', + f' {tables.EDGE_LOCATION_TABLE_NAME}.id,', + ' #access_log_stage.sc_bytes,', + ' #access_log_stage.cs_method,', + f' {tables.PAGE_TABLE_NAME}.id,', + ' #access_log_stage.status,', + f' {tables.REFERER_TABLE_NAME}.id,', + f' {tables.USER_AGENT_TABLE_NAME}.id,', + ' #access_log_stage.cs_protocol,', + ' #access_log_stage.cs_bytes,', + ' #access_log_stage.time_taken,', + f' {tables.RESULT_TYPE_TABLE_NAME}.id,', + ' #access_log_stage.time_to_first_byte', + ' FROM', + ' #access_log_stage,' + f' {tables.EDGE_LOCATION_TABLE_NAME},', + f' {tables.PAGE_TABLE_NAME},', + f' {tables.REFERER_TABLE_NAME},', + f' {tables.USER_AGENT_TABLE_NAME},', + f' {tables.RESULT_TYPE_TABLE_NAME}', + ' WHERE', + f' (#access_log_stage.edge_location = {tables.EDGE_LOCATION_TABLE_NAME}.code)', + f' AND (#access_log_stage.cs_uri_stem = {tables.PAGE_TABLE_NAME}.path)', + f' AND (#access_log_stage.referer = {tables.REFERER_TABLE_NAME}.url)', + f' AND (#access_log_stage.user_agent = {tables.USER_AGENT_TABLE_NAME}.user_agent)', + ' AND (#access_log_stage.edge_response_result_type =', + f' {tables.RESULT_TYPE_TABLE_NAME}.result_type)', + ]) + + +def get_insert_access_logs_statement() -> str: + """Returns an SQL statement that inserts access logs in the temporary second + staging table into the access log table. + """ + return ''.join([ + f'INSERT INTO {tables.ACCESS_LOG_TABLE_NAME}', + ' SELECT * FROM #access_log_stage_2', + ]) + +def get_drop_access_log_stage_2_table_statement() -> str: + """Returns an SQL statement that drops the temporary second staging table + for access logs. + """ + return get_drop_table_statement('#access_log_stage_2') + + +def get_drop_access_log_stage_table_statement() -> str: + """Returns an SQL statement that drops the temporary table to select and + format access log columns. + """ + return get_drop_table_statement('#access_log_stage') + + +def get_drop_table_statement(table_name: str) -> str: + """Returns an SQL statement that drops a given table. + """ + return f'DROP TABLE IF EXISTS {table_name}' + + +def parse_time(time_str: str) -> datetime.datetime: + """Parses a given "time" string. + """ + return datetime.datetime.strptime(time_str, '%Y-%m-%dT%H:%M:%S%z') + + +def get_access_logs_prefix(date: datetime.datetime) -> str: + """Returns the S3 object key prefix of access log files on a given date. + + A returned string contains a trailing slash (/). + """ + return f'{SOURCE_KEY_PREFIX}{format_date_part(date)}' + + +def format_date_part(date: datetime.datetime) -> str: + """Converts a given date into the date part of an S3 object path. + + A returned string contains a trailing slash (/). + """ + return f'{date.year:04d}/{date.month:02d}/{date.day:02d}/' + + +def start_vacuum(): + """Starts VACUUM over the updated tables. + """ + res = stepfunctions.start_execution( + stateMachineArn=VACUUM_WORKFLOW_ARN, + input=json.dumps({ + # "SORT ONLY" is sufficient because no deletes have been performed + 'mode': 'SORT ONLY', + }), + ) + LOGGER.debug('started VACUUM: %s', str(res)) + + +def lambda_handler(event, _): + """Loads CloudFront access logs onto the data warehouse. + + This function is indented to be invoked by Amazon EventBridge. + So ``event`` must be an object with ``time`` field. + + .. code-block:: python + + { + 'time': '2020-04-28T07:20:20Z' + } + + Loads CloudFront access logs on the day before the date specified to + ``time``. + """ + LOGGER.debug('loading access logs: %s', str(event)) + invocation_date = parse_time(event['time']) + target_date = invocation_date - datetime.timedelta(days=1) + if has_access_logs(target_date): + LOGGER.debug('loading access logs on %s', str(target_date)) + res = redshift.get_credentials( + workgroupName=REDSHIFT_WORKGROUP_NAME, + dbName=ACCESS_LOGS_DATABASE_NAME, + ) + LOGGER.debug('accessing database as %s', res['dbUser']) + execute_load_script(target_date) + # we need VACUUM to sort the updated tables. + # runs VACUUM in a different session (e.g., Step Functions) because, + # - VACUUM needs an owner or superuser privilege + # - VACUUM is time consuming + # - only one VACUUM can run at the same time + start_vacuum() + else: + LOGGER.debug('no access logs on %s', str(target_date)) + return {} diff --git a/cdk-ops/lambda/mask-access-logs/index.py b/cdk-ops/lambda/mask-access-logs/index.py new file mode 100644 index 0000000..d144621 --- /dev/null +++ b/cdk-ops/lambda/mask-access-logs/index.py @@ -0,0 +1,495 @@ +# -*- coding: utf-8 -*- + +"""Masks information in CloudFront access logs files. + +You have to specify the following environment variables, +* SOURCE_BUCKET_NAME: name of the S3 bucket containing CloudFront access logs + files to be masked. +* DESTINATION_BUCKET_NAME: name of the S3 bucket where masked CloudFront access + logs files are to be written. +* DESTINATION_KEY_PREFIX: prefix to be prepended to the keys of objects in the + destination bucket. +""" + +import array +import csv +import gzip +import io +import ipaddress +import json +import logging +import os +import time +from contextlib import contextmanager +from typing import Dict, Iterable, Iterator, Sequence, TextIO +import boto3 +from botocore.exceptions import ClientError + + +SOURCE_BUCKET_NAME = os.environ['SOURCE_BUCKET_NAME'] +DESTINATION_BUCKET_NAME = os.environ['DESTINATION_BUCKET_NAME'] +DESTINATION_KEY_PREFIX = os.environ['DESTINATION_KEY_PREFIX'] + +LOGGER = logging.getLogger(__name__) +LOGGER.setLevel(logging.DEBUG) + +s3 = boto3.resource('s3') +source_bucket = s3.Bucket(SOURCE_BUCKET_NAME) +destination_bucket = s3.Bucket(DESTINATION_BUCKET_NAME) + + +def translate_logs(logs_in: Iterable[str]) -> Iterator[str]: + """Translates CloudFront access logs read from a given iterator and returns + a new iterator of translated lines. + + CloudFront access logs starts with the following lines, + + .. code-block:: + + #Version: 1.0 + #Fields: date time ... + + Column names follows the prefix "#Fields:" in the second line. + To parse CloudFront access logs as valid TSV data with a header line, we + have to skip the first line, drop ``#Fields:`` from the second line and + replace space characters with tabs in the second line. + """ + for line in logs_in: + if line.startswith('#Version:'): + continue + if line.startswith('#Fields:'): + columns = line.split(' ')[1:] + yield '\t'.join(columns) + yield line + + +def mask_row(row: Dict[str, str]) -> Dict[str, str]: + """Masks a given row in CloudFront access logs. + """ + addr = row['c-ip'] + if addr != '-': + row['c-ip'] = mask_ip_address(addr) + addr = row['x-forwarded-for'] + if addr != '-': + row['x-forwarded-for'] = mask_ip_address(addr) + return row + + +def mask_ip_address(addr: str) -> str: + """Masks a given IP address. + + Leaves 8 MSBs of an IPv4 address. + Leaves 32 MSBs of an IPv6 address. + Reference: https://cloudonaut.io/anonymize-cloudfront-access-logs/ + """ + ip_addr = ipaddress.ip_address(addr) + if ip_addr.version == 4: + return mask_ip_address_v4(addr) + if ip_addr.version == 6: + return mask_ip_address_v6(addr) + # invalid IP address + raise ValueError(f'invalid IP address: {addr}') + + +def mask_ip_address_v4(addr: str) -> str: + """Masks a given IPv4 address. + + Leaves 8 MSBs. + """ + # makes strict=False to ignore host bits + net = ipaddress.ip_network(f'{addr}/8', strict=False) + return str(net.network_address) + + +def mask_ip_address_v6(addr: str) -> str: + """Masks a given IPv6 address. + + Leaves 32 MSBs. + """ + # makes strict=False to ignore host bits + net = ipaddress.ip_network(f'{addr}/32', strict=False) + return str(net.network_address) + + +def process_logs(src_key: str, logs_in: Iterator[str]): + """Processes given CloudFront logs and outputs to given stream. + """ + tsv_in = csv.DictReader(translate_logs(logs_in), delimiter='\t') + # drops the first row as it contains column names + next(tsv_in) + column_names = tsv_in.fieldnames + if column_names is None: + raise ValueError('no field names are specified in the input') + with LogDispatcher(src_key, column_names) as dispatcher: + for row in tsv_in: + row = mask_row(row) + dispatcher.writerow(row) + + +def lambda_handler(event, _): + """Masks information in given CloudFront access logs files on S3. + + ``event`` is supposed to be an SQS message event described at + https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html + + Each SQS message event is supposed to be an object-creation notification + from the S3 bucket specified by ``SOURCE_BUCKET_NAME``. + + This handler masks information in the given S3 objects and stores masked + results into the S3 bucket specified by ``DESTINATION_BUCKET_NAME`` with + the same object key but with ``DESTINATION_KEY_PREFIX``, year, month, and + date prefixed. + + ``{DESTINATION_KEY_PREFIX}{year}/{month}/{date}/{key}`` + + where ``year``, ``month``, and ``date`` are the timestamp of a log record. + """ + for record in event['Records']: + try: + message = json.loads(record['body']) + except json.JSONDecodeError: + LOGGER.error('invalid SQS record: %s', str(record)) + continue + # may receive a test message "s3:TestEvent" + # and a test message does not have "Records" + entries = message.get('Records') + if entries is None: + LOGGER.debug('maybe a test message: %s', str(message)) + continue + for entry in entries: + event_name = entry.get('eventName', '?') + if event_name.startswith('ObjectCreated:'): + s3_object = entry.get('s3') + if s3_object is not None: + process_s3_object(s3_object) + else: + LOGGER.error('invalid S3 event: %s', str(entry)) + else: + LOGGER.error( + 'event "%s" other than S3 object creation was notified.' + ' please check the event source configuration', + event_name, + ) + return {} + + +def process_s3_object(s3_object): + """Processes a given S3 object event. + + ``s3_object`` must conform to an S3 object creation event described at + https://docs.aws.amazon.com/lambda/latest/dg/with-s3.html + """ + LOGGER.debug('processing S3 object event: %s', str(s3_object)) + # makes sure that the source bucket matches + bucket_name = s3_object.get('bucket', {}).get('name') + if bucket_name is None: + LOGGER.error('no bucket name in S3 object event: %s', str(s3_object)) + return + if bucket_name != SOURCE_BUCKET_NAME: + LOGGER.warning( + 'bucket name must be "%s" but "%s" was given.' + ' please check the event source configuration', + SOURCE_BUCKET_NAME, + bucket_name, + ) + return + key = s3_object.get('object', {}).get('key') + if key is None: + LOGGER.error('no object key in S3 object event: %s', str(s3_object)) + return + src = source_bucket.Object(key) + try: + results = src.get() + except s3.meta.client.exceptions.NoSuchKey: + LOGGER.debug('object "%s" no longer exists', key) + return + with open_body(results) as body: + with gzip.open(body, mode='rt') as tsv_in: + process_logs(key, tsv_in) + + +class S3OutputStream(io.RawIOBase): + """File object that can write an S3 object. + """ + + MIN_PART_SIZE_IN_BYTES = 5 * 1024 * 1024 # 5MB + + def __init__(self, dest_object): + self.dest_object = dest_object + # initiates the multipart upload + self.multipart_upload = self.dest_object.initiate_multipart_upload( + ServerSideEncryption='AES256', + ) + self.uploaded_part_etags = [] + self.part_buffer = array.array('B') + + + def writable(self): + return True + + + def write(self, b): + # appends to the part buffer + self.part_buffer.extend(b) + if len(self.part_buffer) >= S3OutputStream.MIN_PART_SIZE_IN_BYTES: + self.upload_part() + return len(b) + + + def upload_part(self): + """Uploads the buffered part and flushes the buffer. + """ + part_number = self.next_part_number + LOGGER.debug( + 'multipart upload [%d]: size=%d', + part_number, + len(self.part_buffer), + ) + # according to the boto3 documentation, + # Part requires an str for its parameter, but actually an int. + part = self.multipart_upload.Part(part_number) + res = part.upload(Body=self.part_buffer.tobytes()) + self.uploaded_part_etags.append(res['ETag']) + # resets the part buffer + self.part_buffer = array.array('B') + + + @property + def next_part_number(self): + """Next part number. + """ + return len(self.uploaded_part_etags) + 1 # part number from 1 + + + def close(self): + """Completes the multipart upload. + """ + if self.multipart_upload is not None: + LOGGER.debug('closing the multipart upload') + try: + # uploads the last part if it remains + if len(self.part_buffer) > 0: + self.upload_part() + # lists parts and completes + part_list = [ + { + 'ETag': etag, + 'PartNumber': i + 1, + } for (i, etag) in enumerate(self.uploaded_part_etags) + ] + self.multipart_upload.complete( + MultipartUpload={ + 'Parts': part_list, + }, + ) + except: + LOGGER.warning( + 'aborting the multipart upload (as close failed)', + ) + self.multipart_upload.abort() + raise + finally: + self.multipart_upload = None + + + def abort(self): + """Aborts the multipart upload. + """ + if self.multipart_upload is not None: + LOGGER.debug('aborting the multipart upload') + try: + self.multipart_upload.abort() + finally: + self.multipart_upload = None + + + def __exit__(self, exc_type, exc_value, traceback): + """Calls ``abort`` if an exception has occurred. + """ + if exc_type is not None: + self.abort() + return False # propagates the exception + return super().__exit__(exc_type, exc_value, traceback) + + + def __del__(self): + """Calls ``abort``. + + You have to use ``with`` statement or explicitly call ``close`` to + complete the multipart upload. + """ + self.abort() + + +class GzippedTsvOnS3: + """Gzipped TSV file in an S3 bucket. + """ + + underlying: S3OutputStream + gzipped: TextIO + tsv_writer: csv.DictWriter + _next_row_number: int + + + def __init__( + self, + underlying: S3OutputStream, + gzipped: TextIO, + tsv_writer: csv.DictWriter, + ): + self.underlying = underlying + self.gzipped = gzipped + self.tsv_writer = tsv_writer + self._next_row_number = 1 + + + def next_row_number(self) -> int: + """Returns the next row number. + + Every call of this method increments the row number. + """ + row_number = self._next_row_number + self._next_row_number += 1 + return row_number + + + def close(self): + """Completes the upload of the CSV file. + """ + try: + self.gzipped.close() + except IOError as exc: + LOGGER.error('failed to close a gzip stream: %s', str(exc)) + self.underlying.abort() + else: + try: + self.underlying.close() + except ClientError as exc: + LOGGER.error( + 'failed to finish an S3 object upload: %s', + str(exc), + ) + + + def abort(self): + """Aborts the upload of the CSV file. + """ + try: + self.gzipped.close() + except IOError as exc: + LOGGER.error('failed to close a gzip stream: %s', str(exc)) + try: + self.underlying.abort() + except ClientError as exc: + # TODO: possible exceptions? + LOGGER.error( + 'failed to abort an S3 object upload: %s', + str(exc), + ) + + +class LogDispatcher: + """Distributes access log records to S3 objects corresponding to their + dates. + + You should wrap this object in a ``with`` statement. + """ + + LOG_DATE_FORMAT = '%Y-%m-%d' + + ROW_NUMBER_COLUMN = 'row_num' + + dest_map: Dict[time.struct_time, GzippedTsvOnS3] + + + def __init__(self, src_key: str, column_names: Sequence[str]): + """Initializes with the column names. + + Prepends a column for row numbers to ``column_names``. + """ + self.src_key = src_key + self.column_names = [LogDispatcher.ROW_NUMBER_COLUMN] + column_names + self.dest_map = {} + + + def writerow(self, row: Dict[str, str]): + """Writes a given row into a matching S3 object. + + Ignores an invalid row. + + Prepends a row number column to ``row``. + """ + try: + date = time.strptime(row['date'], LogDispatcher.LOG_DATE_FORMAT) + except KeyError: + LOGGER.warning('log record must have date: %s', str(row)) + except ValueError: + LOGGER.warning('invalid date format: %s', row['date']) + else: + dest = self.get_destination(date) + ext_row = row.copy() + ext_row.update({ + LogDispatcher.ROW_NUMBER_COLUMN: f'{dest.next_row_number():d}', + }) + dest.tsv_writer.writerow(ext_row) + + + def get_destination(self, date: time.struct_time) -> GzippedTsvOnS3: + """Obtains the output stream corresponding to a given date. + + Opens a new ``S3OutputStream`` if none has been opened yet. + """ + if date in self.dest_map: + return self.dest_map[date] + year = f'{date.tm_year:04d}' + month = f'{date.tm_mon:02d}' + mday = f'{date.tm_mday:02d}' + key = f'{DESTINATION_KEY_PREFIX}{year}/{month}/{mday}/{self.src_key}' + dest_stream = S3OutputStream(destination_bucket.Object(key)) + dest_gzip = gzip.open(dest_stream, mode='wt') + dest_tsv = csv.DictWriter( + dest_gzip, + fieldnames=self.column_names, + delimiter='\t', + ) + dest = GzippedTsvOnS3(dest_stream, dest_gzip, dest_tsv) + self.dest_map[date] = dest + dest_tsv.writeheader() + return dest + + + def close(self): + """Completes log dispatch and S3 object uploads. + """ + for dest in self.dest_map.values(): + dest.close() + + + def abort(self): + """Aborts log dispatch and S3 object uploads. + """ + for dest in self.dest_map.values(): + dest.abort() + + + def __enter__(self): + return self + + + def __exit__(self, exc_type, _exc_val, _exc_tb): + if exc_type is None: + self.close() + else: + self.abort() + return False + + +@contextmanager +def open_body(s3_get_results): + """Enables ``with`` statement for a body got from an S3 bucket. + """ + body = s3_get_results['Body'] + try: + yield body + finally: + body.close() diff --git a/cdk-ops/lambda/populate-dw-database/index.py b/cdk-ops/lambda/populate-dw-database/index.py new file mode 100644 index 0000000..9394aaa --- /dev/null +++ b/cdk-ops/lambda/populate-dw-database/index.py @@ -0,0 +1,204 @@ +# -*- coding: utf-8 -*- + +"""Populates the data warehouse database and tables. + +You have to configure the following environment variables, +- ``WORKGROUP_NAME``: name of the Redshift Serverless workgroup to connect to +- ``ADMIN_SECRET_ARN``: ARN of the admin secret +- ``ADMIN_DATABASE_NAME``: name of the admin database +""" + +import logging +import os +from typing import Sequence +import boto3 +from libdatawarehouse import ACCESS_LOGS_DATABASE_NAME, data_api, tables +from libdatawarehouse.exceptions import DataWarehouseException + + +WORKGROUP_NAME = os.environ['WORKGROUP_NAME'] +ADMIN_SECRET_ARN = os.environ['ADMIN_SECRET_ARN'] +ADMIN_DATABASE_NAME = os.environ['ADMIN_DATABASE_NAME'] + +LOGGER = logging.getLogger(__name__) +LOGGER.setLevel(logging.DEBUG) + +redshift_data = boto3.client('redshift-data') + + +def get_create_database_statement() -> str: + """Returns an SQL statement to create the database for access logs. + """ + return f'CREATE DATABASE {ACCESS_LOGS_DATABASE_NAME}' + + +def get_create_tables_script() -> Sequence[str]: + """Returns SQL statements to create tables. + """ + return [ + get_create_referer_table_statement(), + get_grant_public_table_access_statement(tables.REFERER_TABLE_NAME), + get_create_page_table_statement(), + get_grant_public_table_access_statement(tables.PAGE_TABLE_NAME), + get_create_edge_location_table_statement(), + get_grant_public_table_access_statement( + tables.EDGE_LOCATION_TABLE_NAME, + ), + get_create_user_agent_table_statement(), + get_grant_public_table_access_statement(tables.USER_AGENT_TABLE_NAME), + get_create_result_type_table_statement(), + get_grant_public_table_access_statement(tables.RESULT_TYPE_TABLE_NAME), + get_create_access_log_table_statement(), + get_grant_public_table_access_statement(tables.ACCESS_LOG_TABLE_NAME), + ] + + +def get_create_referer_table_statement() -> str: + """Returns an SQL statement to create the table for referers. + """ + return ''.join([ + f'CREATE TABLE IF NOT EXISTS {tables.REFERER_TABLE_NAME} (', + ' id BIGINT IDENTITY(1, 1) DISTKEY,', + ' url VARCHAR(2048) NOT NULL SORTKEY UNIQUE,', + ' PRIMARY KEY (id)', + ')', + ]) + + +def get_create_page_table_statement() -> str: + """Returns an SQL statement to create the table for pages. + """ + return ''.join([ + f'CREATE TABLE IF NOT EXISTS {tables.PAGE_TABLE_NAME} (', + ' id INT IDENTITY(1, 1),', + ' path VARCHAR(2048) NOT NULL SORTKEY UNIQUE,' + ' PRIMARY KEY (id)', + ')', + ]) + + +def get_create_edge_location_table_statement() -> str: + """Returns an SQL statement to create the table for edge locations. + """ + return ''.join([ + f'CREATE TABLE IF NOT EXISTS {tables.EDGE_LOCATION_TABLE_NAME} (', + ' id INT IDENTITY(1, 1),', + ' code VARCHAR NOT NULL SORTKEY UNIQUE,', + ' PRIMARY KEY (id)', + ')' + ]) + + +def get_create_user_agent_table_statement() -> str: + """Returns an SQL statement to create the table for user agents. + """ + return ''.join([ + f'CREATE TABLE IF NOT EXISTS {tables.USER_AGENT_TABLE_NAME} (' + ' id BIGINT IDENTITY(1, 1),', + ' user_agent VARCHAR(2048) NOT NULL SORTKEY UNIQUE,', + ' PRIMARY KEY (id)', + ')', + ]) + + +def get_create_result_type_table_statement() -> str: + """Returns an SQL statement to create the table for result types. + """ + return ''.join([ + f'CREATE TABLE IF NOT EXISTS {tables.RESULT_TYPE_TABLE_NAME} (' + ' id INT IDENTITY(1, 1),', + ' result_type VARCHAR NOT NULL SORTKEY UNIQUE,', + ' PRIMARY KEY (id)', + ')', + ]) + + +def get_create_access_log_table_statement() -> str: + """Returns an SQL statement to create the table for access logs. + """ + return ''.join([ + f'CREATE TABLE IF NOT EXISTS {tables.ACCESS_LOG_TABLE_NAME} (', + ' datetime TIMESTAMP NOT NULL,', + ' seq_num INT NOT NULL,', + ' edge_location INT NOT NULL,', + ' sc_bytes BIGINT NOT NULL,', + ' cs_method VARCHAR NOT NULL,', + ' page INT NOT NULL,', + ' status SMALLINT NOT NULL,', + ' referer BIGINT DISTKEY,', + ' user_agent BIGINT NOT NULL,', + ' cs_protocol VARCHAR NOT NULL,', + ' cs_bytes BIGINT NOT NULL,', + ' time_taken FLOAT4 NOT NULL,', + ' edge_response_result_type INT NOT NULL,', + ' time_to_first_byte FLOAT4 NOT NULL,', + f' FOREIGN KEY (edge_location) REFERENCES {tables.EDGE_LOCATION_TABLE_NAME},' + f' FOREIGN KEY (page) REFERENCES {tables.PAGE_TABLE_NAME},' + f' FOREIGN KEY (referer) REFERENCES {tables.REFERER_TABLE_NAME},' + f' FOREIGN KEY (user_agent) REFERENCES {tables.USER_AGENT_TABLE_NAME},' + f' FOREIGN KEY (edge_response_result_type) REFERENCES {tables.RESULT_TYPE_TABLE_NAME}' + ') SORTKEY (datetime, seq_num)', + ]) + + +def get_grant_public_table_access_statement(table_name: str) -> str: + """Returns an SQL statement to grant access on a given table to public. + """ + return f'GRANT SELECT,INSERT,UPDATE,DELETE ON {table_name} TO PUBLIC' + + +def lambda_handler(event, _): + """Populates the data warehouse database and tables. + """ + LOGGER.debug( + 'populating data warehouse database and tables: %s', + str(event), + ) + # populates the database + res = redshift_data.execute_statement( + WorkgroupName=WORKGROUP_NAME, + SecretArn=ADMIN_SECRET_ARN, + Database=ADMIN_DATABASE_NAME, + Sql=get_create_database_statement(), + ) + status, res = data_api.wait_for_results(redshift_data, res['Id']) + if status != 'FINISHED': + if status == 'FAILED': + # just warns if the database already exists + if res.get('Error', '').lower().endswith('already exists'): + LOGGER.warning('database already exists') + else: + raise DataWarehouseException( + f'failed to create the database: {res.get("Error")}', + ) + else: + raise DataWarehouseException( + f'failed to create the database: {status or "timeout"}', + ) + LOGGER.debug( + 'populated database in %.3f ms', + res.get('Duration', 0) * 0.001 * 0.001, # ns → ms + ) + # populates the tables + res = redshift_data.batch_execute_statement( + WorkgroupName=WORKGROUP_NAME, + SecretArn=ADMIN_SECRET_ARN, + Database=ACCESS_LOGS_DATABASE_NAME, + Sqls=get_create_tables_script(), + ) + status, res = data_api.wait_for_results(redshift_data, res['Id']) + if status != 'FINISHED': + if status == 'FAILED': + raise DataWarehouseException( + f'failed to populate tables: {res.get("Error")}', + ) + raise DataWarehouseException( + f'failed to populate tables: {status or "timeout"}', + ) + LOGGER.debug( + 'populated tables in %.3f ms', + res.get('Duration') * 0.001 * 0.001, # ns → ms + ) + return { + 'statusCode': 200, + } diff --git a/cdk-ops/lambda/vacuum-table/index.py b/cdk-ops/lambda/vacuum-table/index.py new file mode 100644 index 0000000..3fe066d --- /dev/null +++ b/cdk-ops/lambda/vacuum-table/index.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- + +"""Runs VACUUM over a given table. + +You have to specify the following environment variables. +* ``WORKGROUP_NAME``: name of the Redshift Serverless workgroup. +* ``ADMIN_SECRET_ARN``: ARN of the secret containing the admin password. +""" + +import logging +import os +import boto3 +from libdatawarehouse import ACCESS_LOGS_DATABASE_NAME, data_api + + +WORKGROUP_NAME = os.environ['WORKGROUP_NAME'] +ADMIN_SECRET_ARN = os.environ['ADMIN_SECRET_ARN'] + +LOGGER = logging.getLogger(__name__) +LOGGER.setLevel(logging.DEBUG) + +redshift_data = boto3.client('redshift-data') + + +def lambda_handler(event, _): + """Runs VACUUM over a given table. + + ``event`` must be a ``dict`` similar to the following, + + .. code-block:: python + + { + 'tableName': '', + 'mode': 'SORT ONLY' + } + """ + LOGGER.debug('running VACUUM: %s', str(event)) + table_name = event['tableName'] + # TODO: verify table_name + mode = event['mode'] + # TODO: verify mode + queue_res = redshift_data.execute_statement( + WorkgroupName=WORKGROUP_NAME, + SecretArn=ADMIN_SECRET_ARN, + Database=ACCESS_LOGS_DATABASE_NAME, + Sql=f'VACUUM {mode} {table_name}', + ) + status, res = data_api.wait_for_results(redshift_data, queue_res['Id']) + if status == 'FAILED': + LOGGER.error('VACUUM over %s failed: %s', table_name, str(res)) + elif status is None: + LOGGER.error('VACUUM over %s timed out', table_name) + status = 'TIMEOUT' + elif status == 'FINISHED': + LOGGER.debug( + 'VACUUM over %s finished in %.3f ms', + table_name, + res.get('Duration', 0) * 0.001 * 0.001, # ns → ms + ) + else: + LOGGER.error('VACUUM over %s failed: %s', table_name, status) + return { + 'status': status, + } diff --git a/cdk-ops/lib/access-logs-etl.ts b/cdk-ops/lib/access-logs-etl.ts new file mode 100644 index 0000000..62a1ad8 --- /dev/null +++ b/cdk-ops/lib/access-logs-etl.ts @@ -0,0 +1,232 @@ +import * as path from 'path'; + +import { PythonFunction } from '@aws-cdk/aws-lambda-python-alpha'; +import { + Duration, + RemovalPolicy, + aws_events as events, + aws_events_targets as events_targets, + aws_iam as iam, + aws_lambda as lambda, + aws_lambda_event_sources as lambda_event, + aws_s3 as s3, + aws_s3_notifications as s3n, + aws_sqs as sqs, +} from 'aws-cdk-lib'; +import { Construct } from 'constructs'; + +import type { DeploymentStage } from 'cdk-common'; + +import { DataWarehouse } from './data-warehouse'; +import { LatestBoto3Layer } from './latest-boto3-layer'; +import { LibdatawarehouseLayer } from './libdatawarehouse-layer'; + +export interface Props { + /** S3 bucket that stores CloudFront access logs. */ + accessLogsBucket: s3.IBucket; + /** Data warehouse. */ + dataWarehouse: DataWarehouse; + /** Lambda layer containing the latest boto3. */ + latestBoto3: LatestBoto3Layer; + /** Lambda layer of the data warehouse library. */ + libdatawarehouse: LibdatawarehouseLayer; + /** Deployment stage. */ + deploymentStage: DeploymentStage; +} + +/** + * CDK construct that provisions resources to process CloudFront access logs. + * + * @remarks + * + * Defines extract, transform, and load (ETL) operations. + */ +export class AccessLogsETL extends Construct { + /** S3 bucket for masked access logs. */ + readonly outputAccessLogsBucket: s3.IBucket; + + constructor(scope: Construct, id: string, props: Props) { + super(scope, id); + + const { + accessLogsBucket, + dataWarehouse, + deploymentStage, + latestBoto3, + libdatawarehouse, + } = props; + + // S3 bucket for processed access logs. + this.outputAccessLogsBucket = new s3.Bucket( + this, + 'MaskedAccessLogsBucket', + { + blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, + encryption: s3.BucketEncryption.S3_MANAGED, + enforceSSL: true, + lifecycleRules: [ + { + // safeguard for incomplete multipart uploads. + // minimum resoluation is one day. + abortIncompleteMultipartUploadAfter: Duration.days(1), + }, + ], + removalPolicy: RemovalPolicy.RETAIN, + }, + ); + // allows the data warehouse to read the bucket + // so that it can COPY objects from the bucket. + this.outputAccessLogsBucket.grantRead(dataWarehouse.namespaceRole); + + // masks newly created CloudFront access logs + // - Lambda function + const maskedAccessLogsKeyPrefix = 'masked/'; + const maskAccessLogsLambdaTimeout = Duration.seconds(30); + const maskAccessLogsLambda = new PythonFunction( + this, + 'MaskAccessLogsLambda', + { + description: `Masks information in a given CloudFront access logs file (${deploymentStage})`, + runtime: lambda.Runtime.PYTHON_3_8, + entry: path.join('lambda', 'mask-access-logs'), + index: 'index.py', + handler: 'lambda_handler', + environment: { + SOURCE_BUCKET_NAME: accessLogsBucket.bucketName, + DESTINATION_BUCKET_NAME: this.outputAccessLogsBucket.bucketName, + DESTINATION_KEY_PREFIX: maskedAccessLogsKeyPrefix, + }, + timeout: maskAccessLogsLambdaTimeout, + }, + ); + accessLogsBucket.grantRead(maskAccessLogsLambda); + this.outputAccessLogsBucket.grantPut(maskAccessLogsLambda); + // - SQS queue to capture creation of access logs files, which triggers + // the above Lambda function + const maxBatchingWindow = Duration.minutes(5); // least frequency + const newLogsQueue = new sqs.Queue(this, 'NewLogsQueue', { + retentionPeriod: Duration.days(1), + // at least (6 * Lambda timeout) + (maximum batch window) + // https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html#events-sqs-eventsource + visibilityTimeout: maxBatchingWindow.plus( + Duration.seconds(6 * maskAccessLogsLambdaTimeout.toSeconds()), + ), + }); + accessLogsBucket.addEventNotification( + s3.EventType.OBJECT_CREATED, + new s3n.SqsDestination(newLogsQueue), + ); + maskAccessLogsLambda.addEventSource( + new lambda_event.SqsEventSource(newLogsQueue, { + enabled: true, + batchSize: 10, + maxBatchingWindow, + // the following filter did not work as I intended, and I gave up. + /* + filters: [ + // SQS queue may receive a test message "s3:TestEvent". + // non-test message must contain the "Records" field. + lambda.FilterCriteria.filter({ + body: { + Records: lambda.FilterRule.exists(), + }, + }), + ], */ + }), + ); + + // deletes original CloudFront access logs. + // - Lambda function + const deleteAccessLogsLambdaTimeout = Duration.seconds(10); + const deleteAccessLogsLambda = new PythonFunction( + this, + 'DeleteAccessLogsLambda', + { + description: `Deletes the original CloudFront access logs file (${deploymentStage})`, + runtime: lambda.Runtime.PYTHON_3_8, + entry: path.join('lambda', 'delete-access-logs'), + index: 'index.py', + handler: 'lambda_handler', + environment: { + SOURCE_BUCKET_NAME: accessLogsBucket.bucketName, + // bucket name for masked logs is necessary to verify input events. + DESTINATION_BUCKET_NAME: this.outputAccessLogsBucket.bucketName, + DESTINATION_KEY_PREFIX: maskedAccessLogsKeyPrefix, + }, + timeout: deleteAccessLogsLambdaTimeout, + }, + ); + accessLogsBucket.grantDelete(deleteAccessLogsLambda); + // - SQS queue to capture creation of masked access logs files, which + // triggers the above Lambda function + const maskedLogsQueue = new sqs.Queue(this, 'MaskedLogsQueue', { + retentionPeriod: Duration.days(1), + visibilityTimeout: maxBatchingWindow.plus( + Duration.seconds(6 * deleteAccessLogsLambdaTimeout.toSeconds()), + ), + }); + this.outputAccessLogsBucket.addEventNotification( + s3.EventType.OBJECT_CREATED, + new s3n.SqsDestination(maskedLogsQueue), + { prefix: maskedAccessLogsKeyPrefix }, + ); + deleteAccessLogsLambda.addEventSource( + new lambda_event.SqsEventSource(maskedLogsQueue, { + enabled: true, + batchSize: 10, + maxBatchingWindow, + }), + ); + + // loads processed logs onto the data warehouse once a day. + // - Lambda function + const loadAccessLogsLambda = new PythonFunction( + this, + 'LoadAccessLogsLambda', + { + description: `Loads processed CloudFront access logs onto the data warehouse (${deploymentStage})`, + runtime: lambda.Runtime.PYTHON_3_8, + architecture: lambda.Architecture.ARM_64, + entry: path.join('lambda', 'load-access-logs'), + index: 'index.py', + handler: 'lambda_handler', + layers: [latestBoto3.layer, libdatawarehouse.layer], + environment: { + SOURCE_BUCKET_NAME: this.outputAccessLogsBucket.bucketName, + SOURCE_KEY_PREFIX: maskedAccessLogsKeyPrefix, + REDSHIFT_WORKGROUP_NAME: dataWarehouse.workgroupName, + COPY_ROLE_ARN: dataWarehouse.namespaceRole.roleArn, + VACUUM_WORKFLOW_ARN: dataWarehouse.vacuumWorkflow.stateMachineArn, + }, + timeout: Duration.minutes(15), + memorySize: 256, + }, + ); + this.outputAccessLogsBucket.grantRead(loadAccessLogsLambda); + dataWarehouse.grantQuery(loadAccessLogsLambda); + dataWarehouse.vacuumWorkflow.grantStartExecution(loadAccessLogsLambda); + // - schedules running loadAccessLogsLambda + const loadSchedule = new events.Rule(this, 'LoadAccessLogsSchedule', { + description: `Periodically loads access logs (${deploymentStage})`, + // do not forget to enable the rule + enabled: false, + schedule: events.Schedule.cron( + deploymentStage === 'development' ? { + // every hour for development + // DO NOT FORGET to disable the rule after testing it + minute: '0', + } : { + // at 2:00 AM every day for production + hour: '2', + minute: '0', + }, + ), + targets: [ + new events_targets.LambdaFunction(loadAccessLogsLambda, { + maxEventAge: Duration.hours(1), + retryAttempts: 2, + }), + ], + }); + } +} diff --git a/cdk-ops/lib/cdk-ops-stack.ts b/cdk-ops/lib/cdk-ops-stack.ts index 8f36313..7422626 100644 --- a/cdk-ops/lib/cdk-ops-stack.ts +++ b/cdk-ops/lib/cdk-ops-stack.ts @@ -1,11 +1,15 @@ -import { Stack, StackProps } from 'aws-cdk-lib'; +import { CfnOutput, Stack, StackProps } from 'aws-cdk-lib'; import { Construct } from 'constructs'; +import { AccessLogsETL } from './access-logs-etl'; import { CodemongerResources, CodemongerResourceNames, } from './codemonger-resources'; import { ContentsPipeline } from './contents-pipeline'; +import { DataWarehouse } from './data-warehouse'; +import { LatestBoto3Layer } from './latest-boto3-layer'; +import { LibdatawarehouseLayer } from './libdatawarehouse-layer'; type Props = StackProps & Readonly<{ // names of the main codemonger resources. @@ -21,8 +25,62 @@ export class CdkOpsStack extends Stack { 'CodemongerResources', props.codemongerResourceNames, ); + const latestBoto3 = new LatestBoto3Layer(this, 'LatestBoto3'); + const libdatawarehouse = + new LibdatawarehouseLayer(this, 'Libdatawarehouse'); const pipeline = new ContentsPipeline(this, 'ContentsPipeline', { codemongerResources, }); + const developmentDataWarehouse = new DataWarehouse( + this, + 'DevelopmentDataWarehouse', + { + latestBoto3, + libdatawarehouse, + deploymentStage: 'development', + }, + ); + const developmentContentsAccessLogsETL = new AccessLogsETL( + this, + 'DevelopmentContentsAccessLogsETL', + { + accessLogsBucket: + codemongerResources.developmentContentsAccessLogsBucket, + dataWarehouse: developmentDataWarehouse, + latestBoto3, + libdatawarehouse, + deploymentStage: 'development', + }, + ); + const productionDataWarehouse = new DataWarehouse( + this, + 'ProductionDataWarehouse', + { + latestBoto3, + libdatawarehouse, + deploymentStage: 'production', + }, + ); + const productionContentsAccessLogsETL = new AccessLogsETL( + this, + 'ProductionContentsAccessLogsETL', + { + accessLogsBucket: + codemongerResources.productionContentsAccessLogsBucket, + dataWarehouse: productionDataWarehouse, + latestBoto3, + libdatawarehouse, + deploymentStage: 'production', + }, + ); + // Outputs + new CfnOutput(this, 'PopulateDevelopmentDwDatabaseLambdaArn', { + description: 'ARN of the Lambda function that populates the data warehouse database and tables (development)', + value: developmentDataWarehouse.populateDwDatabaseLambda.functionArn, + }); + new CfnOutput(this, 'PopulateProductionDwDatabaseLambdaArn', { + description: 'ARN of the Lambda function that populates the data warehouse database and tables (production)', + value: productionDataWarehouse.populateDwDatabaseLambda.functionArn, + }); } } diff --git a/cdk-ops/lib/codemonger-resources.ts b/cdk-ops/lib/codemonger-resources.ts index 9fccf01..a45c90d 100644 --- a/cdk-ops/lib/codemonger-resources.ts +++ b/cdk-ops/lib/codemonger-resources.ts @@ -21,6 +21,10 @@ export type CodemongerResourceNames = { developmentDistributionDomainName: string; /** Name of the S3 bucket for production contents. */ productionContentsBucketName: string; + /** Name of the S3 bucket of CloudFront access logs for development. */ + developmentContentsAccessLogsBucketName: string; + /** Name of the S3 bucket of CloudFront access logs for production. */ + productionContentsAccessLogsBucketName: string; }; /** @@ -50,10 +54,22 @@ export async function resolveCodemongerResourceNames(): if (productionContentsBucketName == null) { throw new Error('contents bucket for production is not available'); } + const developmentContentsAccessLogsBucketName = + developmentOutputs.get('ContentsAccessLogsBucketName'); + if (developmentContentsAccessLogsBucketName == null) { + throw new Error('access logs bucket for development is not available'); + } + const productionContentsAccessLogsBucketName = + productionOutputs.get('ContentsAccessLogsBucketName'); + if (productionContentsAccessLogsBucketName == null) { + throw new Error('access logs bucket for production is not available'); + } return { developmentContentsBucketName, developmentDistributionDomainName, productionContentsBucketName, + developmentContentsAccessLogsBucketName, + productionContentsAccessLogsBucketName, }; } @@ -71,7 +87,7 @@ export async function resolveCodemongerResourceNames(): async function fetchStackOutput(stage: DeploymentStage): Promise> { - const stackName = `${CODEMONGER_STACK_PREFIX}-${stage}`; + const stackName = `${CODEMONGER_STACK_PREFIX}${stage}`; const client = new CloudFormationClient({}); const command = new DescribeStacksCommand({ StackName: stackName, @@ -104,6 +120,10 @@ export class CodemongerResources extends Construct { readonly productionContentsBucket: s3.IBucket; /** Domain name for production. */ readonly productionDomainName = CODEMONGER_DOMAIN_NAME; + /** S3 bucket of CloudFront access logs for development. */ + readonly developmentContentsAccessLogsBucket: s3.IBucket; + /** S3 bucket of CloudFront access logs for development. */ + readonly productionContentsAccessLogsBucket: s3.IBucket; constructor( scope: Construct, @@ -113,8 +133,10 @@ export class CodemongerResources extends Construct { super(scope, id); const { + developmentContentsAccessLogsBucketName, developmentContentsBucketName, developmentDistributionDomainName, + productionContentsAccessLogsBucketName, productionContentsBucketName, } = resourceNames; @@ -129,5 +151,15 @@ export class CodemongerResources extends Construct { 'ProductionContentsBucket', productionContentsBucketName, ); + this.developmentContentsAccessLogsBucket = s3.Bucket.fromBucketName( + this, + 'DevelopmentContentsAccessLogsBucket', + developmentContentsAccessLogsBucketName, + ); + this.productionContentsAccessLogsBucket = s3.Bucket.fromBucketName( + this, + 'ProductionContentsAccessLogsBucket', + productionContentsAccessLogsBucketName, + ); } } diff --git a/cdk-ops/lib/data-warehouse.ts b/cdk-ops/lib/data-warehouse.ts new file mode 100644 index 0000000..e2af1f7 --- /dev/null +++ b/cdk-ops/lib/data-warehouse.ts @@ -0,0 +1,278 @@ +import * as path from 'path'; + +import { + Arn, + Duration, + Stack, + aws_ec2 as ec2, + aws_iam as iam, + aws_lambda as lambda, + aws_redshiftserverless as redshift, + aws_secretsmanager as secrets, + aws_stepfunctions as sfn, + aws_stepfunctions_tasks as sfn_tasks, +} from 'aws-cdk-lib'; +import { Construct } from 'constructs'; +import { PythonFunction } from '@aws-cdk/aws-lambda-python-alpha'; + +import type { DeploymentStage } from 'cdk-common'; + +import { LatestBoto3Layer } from './latest-boto3-layer'; +import { LibdatawarehouseLayer } from './libdatawarehouse-layer'; + +/** Name of the admin user. */ +export const ADMIN_USER_NAME = 'dwadmin'; + +/** Subnet group name of the cluster for Redshift Serverless. */ +export const CLUSTER_SUBNET_GROUP_NAME = 'dw-cluster'; + +export interface Props { + /** Lambda layer containing the latest boto3. */ + latestBoto3: LatestBoto3Layer; + /** Lambda layer containing libdatawarehouse. */ + libdatawarehouse: LibdatawarehouseLayer; + /** Deployment stage. */ + deploymentStage: DeploymentStage; +} + +/** Provisions resources for the data warehouse. */ +export class DataWarehouse extends Construct { + /** VPC for Redshift Serverless clusters. */ + readonly vpc: ec2.IVpc; + // TODO: unnecessary exposure of `adminSecret` + /** Secret for the admin user. */ + readonly adminSecret: secrets.ISecret; + /** Default IAM role associated with the Redshift Serverless namespace. */ + readonly namespaceRole: iam.IRole; + /** Name of the Redshift Serverless workgroup. */ + readonly workgroupName: string; + /** Redshift Serverless workgroup. */ + readonly workgroup: redshift.CfnWorkgroup; + /** Lambda function to populate the database and tables. */ + readonly populateDwDatabaseLambda: lambda.IFunction; + /** Step Functions to run VACUUM over tables. */ + readonly vacuumWorkflow: sfn.IStateMachine; + + constructor(scope: Construct, id: string, props: Props) { + super(scope, id); + + const { deploymentStage, latestBoto3, libdatawarehouse } = props; + + this.vpc = new ec2.Vpc(this, `DwVpc`, { + cidr: '192.168.0.0/16', + enableDnsSupport: true, + enableDnsHostnames: true, + subnetConfiguration: [ + { + name: CLUSTER_SUBNET_GROUP_NAME, + subnetType: ec2.SubnetType.PRIVATE_ISOLATED, + // to reserve private addresses for the future + // allocates up to 1024 private addresses in each subnet + cidrMask: 22, + }, + ], + gatewayEndpoints: { + S3: { + service: ec2.GatewayVpcEndpointAwsService.S3, + }, + }, + }); + + // provisions Redshift Serverless resources + // - secret for admin + this.adminSecret = new secrets.Secret(this, 'DwAdminSecret', { + description: `Data Warehouse secret (${deploymentStage})`, + generateSecretString: { + // the following requirement is too strict, but should not matter. + excludePunctuation: true, + // the structure of a secret value for Redshift is described below + // https://docs.aws.amazon.com/secretsmanager/latest/userguide/reference_secret_json_structure.html#reference_secret_json_structure_RS + // + // whether it also works with Redshift Serverless is unclear. + // as far as I tested, only "username" and "password" are required. + secretStringTemplate: JSON.stringify({ + username: ADMIN_USER_NAME, + }), + generateStringKey: 'password', + }, + }); + // - IAM role for the namespace + this.namespaceRole = new iam.Role(this, 'DwNamespaceRole', { + description: `Data Warehouse Role (${deploymentStage})`, + assumedBy: new iam.CompositePrincipal( + new iam.ServicePrincipal('redshift-serverless.amazonaws.com'), + new iam.ServicePrincipal('redshift.amazonaws.com'), + ), + }); + // - namespace + const dwNamespace = new redshift.CfnNamespace(this, 'DwNamespace', { + namespaceName: `datawarehouse-${deploymentStage}`, + adminUsername: ADMIN_USER_NAME, + adminUserPassword: + this.adminSecret.secretValueFromJson('password').unsafeUnwrap(), + defaultIamRoleArn: this.namespaceRole.roleArn, + iamRoles: [this.namespaceRole.roleArn], + tags: [ + { + key: 'project', + value: 'codemonger', + }, + { + key: 'stage', + value: deploymentStage, + }, + ], + }); + dwNamespace.addDependsOn( + this.adminSecret.node.defaultChild as secrets.CfnSecret, + ); + // - workgroup + this.workgroupName = `datawarehouse-${deploymentStage}`; + this.workgroup = new redshift.CfnWorkgroup(this, 'DwWorkgroup', { + workgroupName: this.workgroupName, + namespaceName: dwNamespace.namespaceName, + baseCapacity: 32, + subnetIds: this.getSubnetIdsForCluster(), + enhancedVpcRouting: true, + tags: [ + { + key: 'project', + value: 'codemonger', + }, + { + key: 'stage', + value: deploymentStage, + }, + ], + }); + this.workgroup.addDependsOn(dwNamespace); + + // Lambda function that populates the database and tables. + this.populateDwDatabaseLambda = new PythonFunction( + this, + 'PopulateDwDatabaseLambda', + { + description: `Populates the data warehouse database and tables (${deploymentStage})`, + runtime: lambda.Runtime.PYTHON_3_8, + architecture: lambda.Architecture.ARM_64, + entry: path.join('lambda', 'populate-dw-database'), + index: 'index.py', + handler: 'lambda_handler', + layers: [latestBoto3.layer, libdatawarehouse.layer], + environment: { + WORKGROUP_NAME: this.workgroupName, + ADMIN_SECRET_ARN: this.adminSecret.secretArn, + ADMIN_DATABASE_NAME: 'dev', + }, + timeout: Duration.minutes(15), + // a Lambda function does not have to join the VPC + // as long as it uses Redshift Data API. + // + // if we want to directly connect to the Redshift cluster from a Lambda, + // we have to put the Lambda in the VPC and allocate a VPC endpoint. + // but I cannot afford VPC endpoints for now. + // + // alternatively, we could run the Redshift cluster in a public subnet. + }, + ); + // Redshift Data API uses the execution role of the Lambda function to + // retrieve the secret. + this.adminSecret.grantRead(this.populateDwDatabaseLambda); + // TODO: too permissive? + this.populateDwDatabaseLambda.role?.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonRedshiftDataFullAccess')); + + // Step Functions that perform VACUUM over tables. + // - Lambda function that runs VACUUM over a given table + const vacuumTableLambda = new PythonFunction(this, 'VacuumTableLambda', { + description: `Runs VACUUM over a table (${deploymentStage})`, + runtime: lambda.Runtime.PYTHON_3_8, + architecture: lambda.Architecture.ARM_64, + entry: path.join('lambda', 'vacuum-table'), + index: 'index.py', + handler: 'lambda_handler', + layers: [latestBoto3.layer, libdatawarehouse.layer], + environment: { + WORKGROUP_NAME: this.workgroupName, + ADMIN_SECRET_ARN: this.adminSecret.secretArn, + }, + timeout: Duration.minutes(15), + }); + this.adminSecret.grantRead(vacuumTableLambda); + this.grantQuery(vacuumTableLambda); + // - state machine + // - lists table names + const listTableNamesState = new sfn.Pass(this, 'ListTables', { + comment: 'Lists table names', + result: sfn.Result.fromArray([ + 'access_log', + 'referer', + 'page', + 'edge_location', + 'user_agent', + 'result_type', + ]), + resultPath: '$.tables', + // produces something like + // { + // mode: 'SORT ONLY', + // tableNames: ['access_log', ...] + // } + }); + this.vacuumWorkflow = new sfn.StateMachine(this, 'VacuumWorkflow', { + definition: + listTableNamesState.next( + new sfn.Map(this, 'MapTables', { + comment: 'Iterates over tables', + maxConcurrency: 1, // sequential + itemsPath: '$.tables', + parameters: { + 'tableName.$': '$$.Map.Item.Value', + 'mode.$': '$.mode', + }, + }).iterator( + new sfn_tasks.LambdaInvoke(this, 'VacuumTable', { + lambdaFunction: vacuumTableLambda, + }), + ), + ), + timeout: Duration.hours(1), + }); + } + + /** Returns subnet IDs for the cluster of Redshift Serverless. */ + getSubnetIdsForCluster(): string[] { + return this.vpc.selectSubnets({ + subnetGroupName: CLUSTER_SUBNET_GROUP_NAME, + }).subnetIds; + } + + /** + * Grants permissions to query this data warehouse via the Redshift Data API. + * + * Allows `grantee` to call `redshift-serverless:GetCredentials`. + */ + grantQuery(grantee: iam.IGrantable): iam.Grant { + iam.Grant + .addToPrincipal({ + grantee, + actions: ['redshift-serverless:GetCredentials'], + resourceArns: [ + // TODO: how can we get the ARN of the workgroup? + Arn.format( + { + service: 'redshift-serverless', + resource: 'workgroup', + resourceName: '*', + }, + Stack.of(this.workgroup), + ), + ], + }) + .assertSuccess(); + return iam.Grant.addToPrincipal({ + grantee, + actions: ['redshift-data:*'], + resourceArns: ['*'], + }); + } +} diff --git a/cdk-ops/lib/latest-boto3-layer.ts b/cdk-ops/lib/latest-boto3-layer.ts new file mode 100644 index 0000000..409bc67 --- /dev/null +++ b/cdk-ops/lib/latest-boto3-layer.ts @@ -0,0 +1,28 @@ +import * as path from 'path'; + +import { aws_lambda as lambda } from 'aws-cdk-lib'; +import { Construct } from 'constructs'; +import { PythonLayerVersion } from '@aws-cdk/aws-lambda-python-alpha'; + +/** CDK construct that provisions a Lambda layer containing the latest boto3. */ +export class LatestBoto3Layer extends Construct { + /** Lambda layer containing the latest boto3. */ + readonly layer: lambda.ILayerVersion; + + constructor(scope: Construct, id: string) { + super(scope, id); + + this.layer = new PythonLayerVersion(this, 'LambdaLayer', { + description: 'Lambda layer containing the latest boto3', + entry: path.join('lambda', 'latest-boto3'), + compatibleRuntimes: [ + lambda.Runtime.PYTHON_3_8, + lambda.Runtime.PYTHON_3_9, + ], + compatibleArchitectures: [ + lambda.Architecture.ARM_64, + lambda.Architecture.X86_64, + ], + }); + } +} diff --git a/cdk-ops/lib/libdatawarehouse-layer.ts b/cdk-ops/lib/libdatawarehouse-layer.ts new file mode 100644 index 0000000..8e91260 --- /dev/null +++ b/cdk-ops/lib/libdatawarehouse-layer.ts @@ -0,0 +1,20 @@ +import * as path from 'path'; +import { aws_lambda as lambda } from 'aws-cdk-lib'; +import { Construct } from 'constructs'; + +import { PythonLibraryLayer } from 'cdk2-python-library-layer'; + +/** CDK construct that provisions a Lambda layer of `libdatawarehouse`. */ +export class LibdatawarehouseLayer extends Construct { + /** Lambda layer of `libdatawarehouse`. */ + readonly layer: lambda.ILayerVersion; + + constructor(scope: Construct, id: string) { + super(scope, id); + + this.layer = new PythonLibraryLayer(this, 'Layer', { + runtime: lambda.Runtime.PYTHON_3_8, + entry: path.join('lambda', 'libdatawarehouse'), + }); + } +} diff --git a/cdk-ops/package-lock.json b/cdk-ops/package-lock.json index f75f51d..43deed5 100644 --- a/cdk-ops/package-lock.json +++ b/cdk-ops/package-lock.json @@ -8,11 +8,15 @@ "name": "cdk-ops", "version": "0.1.0", "dependencies": { - "@aws-sdk/client-cloudformation": "^3.112.0", - "aws-cdk-lib": "^2.28.1", + "@aws-cdk/aws-lambda-python-alpha": "^2.45.0-alpha.0", + "@aws-sdk/client-cloudformation": "^3.186.0", + "@aws-sdk/client-lambda": "^3.186.0", + "aws-cdk-lib": "^2.45.0", "cdk-common": "file:../cdk-common", - "constructs": "^10.1.42", - "source-map-support": "^0.5.21" + "cdk2-python-library-layer": "github:kikuomax/cdk-python-library-layer#v0.1.0-v2", + "constructs": "^10.1.128", + "source-map-support": "^0.5.21", + "yargs": "^17.6.0" }, "bin": { "cdk-ops": "bin/cdk-ops.js" @@ -21,10 +25,10 @@ "@types/jest": "^27.5.0", "@types/node": "10.17.27", "@types/prettier": "2.6.0", - "aws-cdk": "^2.28.1", + "aws-cdk": "^2.45.0", "jest": "^27.5.1", "ts-jest": "^27.1.4", - "ts-node": "^10.7.0", + "ts-node": "^10.9.1", "typescript": "~3.9.7" } }, @@ -52,10 +56,22 @@ "node": ">=6.0.0" } }, + "node_modules/@aws-cdk/aws-lambda-python-alpha": { + "version": "2.45.0-alpha.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-lambda-python-alpha/-/aws-lambda-python-alpha-2.45.0-alpha.0.tgz", + "integrity": "sha512-seRYApZ/FUSi19PHS/3cXfpeijdrc8JuMlnUl688IE3FOxAYaT+geFx5KldW3+9mG5cRSxCYlXukf3NOW2ZCjw==", + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "aws-cdk-lib": "^2.45.0", + "constructs": "^10.0.0" + } + }, "node_modules/@aws-crypto/ie11-detection": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-2.0.0.tgz", - "integrity": "sha512-pkVXf/dq6PITJ0jzYZ69VhL8VFOFoPZLZqtU/12SGnzYuJOOGNfF41q9GxdI1yqC8R13Rq3jOLKDFpUJFT5eTA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-2.0.2.tgz", + "integrity": "sha512-5XDMQY98gMAf/WRTic5G++jfmS/VLM0rwpiOpaainKi4L0nqWMSB1SzsrEG5rjFZGYN6ZAefO+/Yta2dFM0kMw==", "dependencies": { "tslib": "^1.11.1" } @@ -101,9 +117,9 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@aws-crypto/supports-web-crypto": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-2.0.0.tgz", - "integrity": "sha512-Ge7WQ3E0OC7FHYprsZV3h0QIcpdyJLvIeg+uTuHqRYm8D6qCFJoiC+edSzSyFiHtZf+NOQDJ1q46qxjtzIY2nA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-2.0.2.tgz", + "integrity": "sha512-6mbSsLHwZ99CTOOswvCRP3C+VCWnzBf+1SnbWxzzJ9lR0mA0JnY2JEAhp8rqmTE0GPFy88rrM27ffgp62oErMQ==", "dependencies": { "tslib": "^1.11.1" } @@ -114,11 +130,11 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@aws-crypto/util": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-2.0.1.tgz", - "integrity": "sha512-JJmFFwvbm08lULw4Nm5QOLg8+lAQeC8aCXK5xrtxntYzYXCGfHwUJ4Is3770Q7HmICsXthGQ+ZsDL7C2uH3yBQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-2.0.2.tgz", + "integrity": "sha512-Lgu5v/0e/BcrZ5m/IWqzPUf3UYFTy/PpeED+uc9SWUR1iZQL8XXbGQg10UfllwwBryO3hFF5dizK+78aoXC1eA==", "dependencies": { - "@aws-sdk/types": "^3.1.0", + "@aws-sdk/types": "^3.110.0", "@aws-sdk/util-utf8-browser": "^3.0.0", "tslib": "^1.11.1" } @@ -129,11 +145,11 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@aws-sdk/abort-controller": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.110.0.tgz", - "integrity": "sha512-zok/WEVuK7Jh6V9YeA56pNZtxUASon9LTkS7vE65A4UFmNkPGNBCNgoiBcbhWfxwrZ8wtXcQk6rtUut39831mA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.186.0.tgz", + "integrity": "sha512-JFvvvtEcbYOvVRRXasi64Dd1VcOz5kJmPvtzsJ+HzMHvPbGGs/aopOJAZQJMJttzJmJwVTay0QL6yag9Kk8nYA==", "dependencies": { - "@aws-sdk/types": "3.110.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -141,44 +157,44 @@ } }, "node_modules/@aws-sdk/client-cloudformation": { - "version": "3.112.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudformation/-/client-cloudformation-3.112.0.tgz", - "integrity": "sha512-CQ0HQ5qoXcjP1uoz9AtRYCfar0s/3xq4xGHcCqaeSa6j7nQicHFfT9GsfF5oK9OkE8wZ1EX5OJSUHMm0ONvMQQ==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudformation/-/client-cloudformation-3.186.0.tgz", + "integrity": "sha512-CAZAX9anSOmrqW9YX34pHIz05Nje2GRd3p/U2NrOs4X4gu9jeg0yf2Ea6O9u6UTSH6hniZKZD3ITbmSFA/5Lgw==", "dependencies": { "@aws-crypto/sha256-browser": "2.0.0", "@aws-crypto/sha256-js": "2.0.0", - "@aws-sdk/client-sts": "3.112.0", - "@aws-sdk/config-resolver": "3.110.0", - "@aws-sdk/credential-provider-node": "3.112.0", - "@aws-sdk/fetch-http-handler": "3.110.0", - "@aws-sdk/hash-node": "3.110.0", - "@aws-sdk/invalid-dependency": "3.110.0", - "@aws-sdk/middleware-content-length": "3.110.0", - "@aws-sdk/middleware-host-header": "3.110.0", - "@aws-sdk/middleware-logger": "3.110.0", - "@aws-sdk/middleware-recursion-detection": "3.110.0", - "@aws-sdk/middleware-retry": "3.110.0", - "@aws-sdk/middleware-serde": "3.110.0", - "@aws-sdk/middleware-signing": "3.110.0", - "@aws-sdk/middleware-stack": "3.110.0", - "@aws-sdk/middleware-user-agent": "3.110.0", - "@aws-sdk/node-config-provider": "3.110.0", - "@aws-sdk/node-http-handler": "3.110.0", - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/smithy-client": "3.110.0", - "@aws-sdk/types": "3.110.0", - "@aws-sdk/url-parser": "3.110.0", - "@aws-sdk/util-base64-browser": "3.109.0", - "@aws-sdk/util-base64-node": "3.55.0", - "@aws-sdk/util-body-length-browser": "3.55.0", - "@aws-sdk/util-body-length-node": "3.55.0", - "@aws-sdk/util-defaults-mode-browser": "3.110.0", - "@aws-sdk/util-defaults-mode-node": "3.110.0", - "@aws-sdk/util-user-agent-browser": "3.110.0", - "@aws-sdk/util-user-agent-node": "3.110.0", - "@aws-sdk/util-utf8-browser": "3.109.0", - "@aws-sdk/util-utf8-node": "3.109.0", - "@aws-sdk/util-waiter": "3.110.0", + "@aws-sdk/client-sts": "3.186.0", + "@aws-sdk/config-resolver": "3.186.0", + "@aws-sdk/credential-provider-node": "3.186.0", + "@aws-sdk/fetch-http-handler": "3.186.0", + "@aws-sdk/hash-node": "3.186.0", + "@aws-sdk/invalid-dependency": "3.186.0", + "@aws-sdk/middleware-content-length": "3.186.0", + "@aws-sdk/middleware-host-header": "3.186.0", + "@aws-sdk/middleware-logger": "3.186.0", + "@aws-sdk/middleware-recursion-detection": "3.186.0", + "@aws-sdk/middleware-retry": "3.186.0", + "@aws-sdk/middleware-serde": "3.186.0", + "@aws-sdk/middleware-signing": "3.186.0", + "@aws-sdk/middleware-stack": "3.186.0", + "@aws-sdk/middleware-user-agent": "3.186.0", + "@aws-sdk/node-config-provider": "3.186.0", + "@aws-sdk/node-http-handler": "3.186.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/smithy-client": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/url-parser": "3.186.0", + "@aws-sdk/util-base64-browser": "3.186.0", + "@aws-sdk/util-base64-node": "3.186.0", + "@aws-sdk/util-body-length-browser": "3.186.0", + "@aws-sdk/util-body-length-node": "3.186.0", + "@aws-sdk/util-defaults-mode-browser": "3.186.0", + "@aws-sdk/util-defaults-mode-node": "3.186.0", + "@aws-sdk/util-user-agent-browser": "3.186.0", + "@aws-sdk/util-user-agent-node": "3.186.0", + "@aws-sdk/util-utf8-browser": "3.186.0", + "@aws-sdk/util-utf8-node": "3.186.0", + "@aws-sdk/util-waiter": "3.186.0", "entities": "2.2.0", "fast-xml-parser": "3.19.0", "tslib": "^2.3.1", @@ -188,41 +204,86 @@ "node": ">=12.0.0" } }, + "node_modules/@aws-sdk/client-lambda": { + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.186.0.tgz", + "integrity": "sha512-Wr/s591KMRhRRMnv4eWpJ56Kvt5wMjHFW/XGb4NBEPBkLnd/92jVDXp76tGhmbILa/zNpMBaHTx2eqDvHA6AXQ==", + "dependencies": { + "@aws-crypto/sha256-browser": "2.0.0", + "@aws-crypto/sha256-js": "2.0.0", + "@aws-sdk/client-sts": "3.186.0", + "@aws-sdk/config-resolver": "3.186.0", + "@aws-sdk/credential-provider-node": "3.186.0", + "@aws-sdk/fetch-http-handler": "3.186.0", + "@aws-sdk/hash-node": "3.186.0", + "@aws-sdk/invalid-dependency": "3.186.0", + "@aws-sdk/middleware-content-length": "3.186.0", + "@aws-sdk/middleware-host-header": "3.186.0", + "@aws-sdk/middleware-logger": "3.186.0", + "@aws-sdk/middleware-recursion-detection": "3.186.0", + "@aws-sdk/middleware-retry": "3.186.0", + "@aws-sdk/middleware-serde": "3.186.0", + "@aws-sdk/middleware-signing": "3.186.0", + "@aws-sdk/middleware-stack": "3.186.0", + "@aws-sdk/middleware-user-agent": "3.186.0", + "@aws-sdk/node-config-provider": "3.186.0", + "@aws-sdk/node-http-handler": "3.186.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/smithy-client": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/url-parser": "3.186.0", + "@aws-sdk/util-base64-browser": "3.186.0", + "@aws-sdk/util-base64-node": "3.186.0", + "@aws-sdk/util-body-length-browser": "3.186.0", + "@aws-sdk/util-body-length-node": "3.186.0", + "@aws-sdk/util-defaults-mode-browser": "3.186.0", + "@aws-sdk/util-defaults-mode-node": "3.186.0", + "@aws-sdk/util-user-agent-browser": "3.186.0", + "@aws-sdk/util-user-agent-node": "3.186.0", + "@aws-sdk/util-utf8-browser": "3.186.0", + "@aws-sdk/util-utf8-node": "3.186.0", + "@aws-sdk/util-waiter": "3.186.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@aws-sdk/client-sso": { - "version": "3.112.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.112.0.tgz", - "integrity": "sha512-FwFmiapxuVQiyMdDaBvCpajnJkVWEUHBdO+7rIpzgKHkODEPou5/AwboaGRPEFYULOyYeI0HiDFzpK0G6de+7Q==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.186.0.tgz", + "integrity": "sha512-qwLPomqq+fjvp42izzEpBEtGL2+dIlWH5pUCteV55hTEwHgo+m9LJPIrMWkPeoMBzqbNiu5n6+zihnwYlCIlEA==", "dependencies": { "@aws-crypto/sha256-browser": "2.0.0", "@aws-crypto/sha256-js": "2.0.0", - "@aws-sdk/config-resolver": "3.110.0", - "@aws-sdk/fetch-http-handler": "3.110.0", - "@aws-sdk/hash-node": "3.110.0", - "@aws-sdk/invalid-dependency": "3.110.0", - "@aws-sdk/middleware-content-length": "3.110.0", - "@aws-sdk/middleware-host-header": "3.110.0", - "@aws-sdk/middleware-logger": "3.110.0", - "@aws-sdk/middleware-recursion-detection": "3.110.0", - "@aws-sdk/middleware-retry": "3.110.0", - "@aws-sdk/middleware-serde": "3.110.0", - "@aws-sdk/middleware-stack": "3.110.0", - "@aws-sdk/middleware-user-agent": "3.110.0", - "@aws-sdk/node-config-provider": "3.110.0", - "@aws-sdk/node-http-handler": "3.110.0", - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/smithy-client": "3.110.0", - "@aws-sdk/types": "3.110.0", - "@aws-sdk/url-parser": "3.110.0", - "@aws-sdk/util-base64-browser": "3.109.0", - "@aws-sdk/util-base64-node": "3.55.0", - "@aws-sdk/util-body-length-browser": "3.55.0", - "@aws-sdk/util-body-length-node": "3.55.0", - "@aws-sdk/util-defaults-mode-browser": "3.110.0", - "@aws-sdk/util-defaults-mode-node": "3.110.0", - "@aws-sdk/util-user-agent-browser": "3.110.0", - "@aws-sdk/util-user-agent-node": "3.110.0", - "@aws-sdk/util-utf8-browser": "3.109.0", - "@aws-sdk/util-utf8-node": "3.109.0", + "@aws-sdk/config-resolver": "3.186.0", + "@aws-sdk/fetch-http-handler": "3.186.0", + "@aws-sdk/hash-node": "3.186.0", + "@aws-sdk/invalid-dependency": "3.186.0", + "@aws-sdk/middleware-content-length": "3.186.0", + "@aws-sdk/middleware-host-header": "3.186.0", + "@aws-sdk/middleware-logger": "3.186.0", + "@aws-sdk/middleware-recursion-detection": "3.186.0", + "@aws-sdk/middleware-retry": "3.186.0", + "@aws-sdk/middleware-serde": "3.186.0", + "@aws-sdk/middleware-stack": "3.186.0", + "@aws-sdk/middleware-user-agent": "3.186.0", + "@aws-sdk/node-config-provider": "3.186.0", + "@aws-sdk/node-http-handler": "3.186.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/smithy-client": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/url-parser": "3.186.0", + "@aws-sdk/util-base64-browser": "3.186.0", + "@aws-sdk/util-base64-node": "3.186.0", + "@aws-sdk/util-body-length-browser": "3.186.0", + "@aws-sdk/util-body-length-node": "3.186.0", + "@aws-sdk/util-defaults-mode-browser": "3.186.0", + "@aws-sdk/util-defaults-mode-node": "3.186.0", + "@aws-sdk/util-user-agent-browser": "3.186.0", + "@aws-sdk/util-user-agent-node": "3.186.0", + "@aws-sdk/util-utf8-browser": "3.186.0", + "@aws-sdk/util-utf8-node": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -230,43 +291,43 @@ } }, "node_modules/@aws-sdk/client-sts": { - "version": "3.112.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.112.0.tgz", - "integrity": "sha512-hSApRO2wg3jk9VRGM6SCZO3aFP7DKVSUqs6FrvlXlj+JU88ZKObjrGE61cCzXoD89Dh+b9t8A2T6W51Nzriaxw==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.186.0.tgz", + "integrity": "sha512-lyAPI6YmIWWYZHQ9fBZ7QgXjGMTtktL5fk8kOcZ98ja+8Vu0STH1/u837uxqvZta8/k0wijunIL3jWUhjsNRcg==", "dependencies": { "@aws-crypto/sha256-browser": "2.0.0", "@aws-crypto/sha256-js": "2.0.0", - "@aws-sdk/config-resolver": "3.110.0", - "@aws-sdk/credential-provider-node": "3.112.0", - "@aws-sdk/fetch-http-handler": "3.110.0", - "@aws-sdk/hash-node": "3.110.0", - "@aws-sdk/invalid-dependency": "3.110.0", - "@aws-sdk/middleware-content-length": "3.110.0", - "@aws-sdk/middleware-host-header": "3.110.0", - "@aws-sdk/middleware-logger": "3.110.0", - "@aws-sdk/middleware-recursion-detection": "3.110.0", - "@aws-sdk/middleware-retry": "3.110.0", - "@aws-sdk/middleware-sdk-sts": "3.110.0", - "@aws-sdk/middleware-serde": "3.110.0", - "@aws-sdk/middleware-signing": "3.110.0", - "@aws-sdk/middleware-stack": "3.110.0", - "@aws-sdk/middleware-user-agent": "3.110.0", - "@aws-sdk/node-config-provider": "3.110.0", - "@aws-sdk/node-http-handler": "3.110.0", - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/smithy-client": "3.110.0", - "@aws-sdk/types": "3.110.0", - "@aws-sdk/url-parser": "3.110.0", - "@aws-sdk/util-base64-browser": "3.109.0", - "@aws-sdk/util-base64-node": "3.55.0", - "@aws-sdk/util-body-length-browser": "3.55.0", - "@aws-sdk/util-body-length-node": "3.55.0", - "@aws-sdk/util-defaults-mode-browser": "3.110.0", - "@aws-sdk/util-defaults-mode-node": "3.110.0", - "@aws-sdk/util-user-agent-browser": "3.110.0", - "@aws-sdk/util-user-agent-node": "3.110.0", - "@aws-sdk/util-utf8-browser": "3.109.0", - "@aws-sdk/util-utf8-node": "3.109.0", + "@aws-sdk/config-resolver": "3.186.0", + "@aws-sdk/credential-provider-node": "3.186.0", + "@aws-sdk/fetch-http-handler": "3.186.0", + "@aws-sdk/hash-node": "3.186.0", + "@aws-sdk/invalid-dependency": "3.186.0", + "@aws-sdk/middleware-content-length": "3.186.0", + "@aws-sdk/middleware-host-header": "3.186.0", + "@aws-sdk/middleware-logger": "3.186.0", + "@aws-sdk/middleware-recursion-detection": "3.186.0", + "@aws-sdk/middleware-retry": "3.186.0", + "@aws-sdk/middleware-sdk-sts": "3.186.0", + "@aws-sdk/middleware-serde": "3.186.0", + "@aws-sdk/middleware-signing": "3.186.0", + "@aws-sdk/middleware-stack": "3.186.0", + "@aws-sdk/middleware-user-agent": "3.186.0", + "@aws-sdk/node-config-provider": "3.186.0", + "@aws-sdk/node-http-handler": "3.186.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/smithy-client": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/url-parser": "3.186.0", + "@aws-sdk/util-base64-browser": "3.186.0", + "@aws-sdk/util-base64-node": "3.186.0", + "@aws-sdk/util-body-length-browser": "3.186.0", + "@aws-sdk/util-body-length-node": "3.186.0", + "@aws-sdk/util-defaults-mode-browser": "3.186.0", + "@aws-sdk/util-defaults-mode-node": "3.186.0", + "@aws-sdk/util-user-agent-browser": "3.186.0", + "@aws-sdk/util-user-agent-node": "3.186.0", + "@aws-sdk/util-utf8-browser": "3.186.0", + "@aws-sdk/util-utf8-node": "3.186.0", "entities": "2.2.0", "fast-xml-parser": "3.19.0", "tslib": "^2.3.1" @@ -276,14 +337,14 @@ } }, "node_modules/@aws-sdk/config-resolver": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.110.0.tgz", - "integrity": "sha512-7VvtKy4CL63BAktQ2vgsjhWDSXpkXO5YdiI56LQnHztrvSuJBBaxJ7R1p/k0b2tEUhYKUziAIW8EKE/7EGPR4g==", - "dependencies": { - "@aws-sdk/signature-v4": "3.110.0", - "@aws-sdk/types": "3.110.0", - "@aws-sdk/util-config-provider": "3.109.0", - "@aws-sdk/util-middleware": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.186.0.tgz", + "integrity": "sha512-l8DR7Q4grEn1fgo2/KvtIfIHJS33HGKPQnht8OPxkl0dMzOJ0jxjOw/tMbrIcPnr2T3Fi7LLcj3dY1Fo1poruQ==", + "dependencies": { + "@aws-sdk/signature-v4": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/util-config-provider": "3.186.0", + "@aws-sdk/util-middleware": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -291,12 +352,12 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.110.0.tgz", - "integrity": "sha512-oFU3IYk/Bl5tdsz1qigtm3I25a9cvXPqlE8VjYjxVDdLujF5zd/4HLbhP4GQWhpEwZmM1ijcSNfLcyywVevTZg==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.186.0.tgz", + "integrity": "sha512-N9LPAqi1lsQWgxzmU4NPvLPnCN5+IQ3Ai1IFf3wM6FFPNoSUd1kIA2c6xaf0BE7j5Kelm0raZOb4LnV3TBAv+g==", "dependencies": { - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -304,14 +365,14 @@ } }, "node_modules/@aws-sdk/credential-provider-imds": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.110.0.tgz", - "integrity": "sha512-atl+7/dAB+8fG9XI2fYyCgXKYDbOzot65VAwis+14bOEUCVp7PCJifBEZ/L8GEq564p+Fa2p1IpV0wuQXxqFUQ==", - "dependencies": { - "@aws-sdk/node-config-provider": "3.110.0", - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/types": "3.110.0", - "@aws-sdk/url-parser": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.186.0.tgz", + "integrity": "sha512-iJeC7KrEgPPAuXjCZ3ExYZrRQvzpSdTZopYgUm5TnNZ8S1NU/4nvv5xVy61JvMj3JQAeG8UDYYgC421Foc8wQw==", + "dependencies": { + "@aws-sdk/node-config-provider": "3.186.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/url-parser": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -319,17 +380,17 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.112.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.112.0.tgz", - "integrity": "sha512-ebgZ6/jZdTGHQ3zfq/ccmS+7YmLk6yUWHDmh69VK+B1Dd+S1jFwbD9EQ+pYWCp/gEl9F620NSwb6KghRylPWEQ==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.110.0", - "@aws-sdk/credential-provider-imds": "3.110.0", - "@aws-sdk/credential-provider-sso": "3.112.0", - "@aws-sdk/credential-provider-web-identity": "3.110.0", - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/shared-ini-file-loader": "3.110.0", - "@aws-sdk/types": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.186.0.tgz", + "integrity": "sha512-ecrFh3MoZhAj5P2k/HXo/hMJQ3sfmvlommzXuZ/D1Bj2yMcyWuBhF1A83Fwd2gtYrWRrllsK3IOMM5Jr8UIVZA==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.186.0", + "@aws-sdk/credential-provider-imds": "3.186.0", + "@aws-sdk/credential-provider-sso": "3.186.0", + "@aws-sdk/credential-provider-web-identity": "3.186.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/shared-ini-file-loader": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -337,19 +398,19 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.112.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.112.0.tgz", - "integrity": "sha512-7txS7P3BAaU4cksFw/PnoVskVvO8h/TPvOl/BxFtCiUdwA6FRltLvBeMlN08fwUoqgM6z06q8areBdeDqCHOSw==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.110.0", - "@aws-sdk/credential-provider-imds": "3.110.0", - "@aws-sdk/credential-provider-ini": "3.112.0", - "@aws-sdk/credential-provider-process": "3.110.0", - "@aws-sdk/credential-provider-sso": "3.112.0", - "@aws-sdk/credential-provider-web-identity": "3.110.0", - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/shared-ini-file-loader": "3.110.0", - "@aws-sdk/types": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.186.0.tgz", + "integrity": "sha512-HIt2XhSRhEvVgRxTveLCzIkd/SzEBQfkQ6xMJhkBtfJw1o3+jeCk+VysXM0idqmXytctL0O3g9cvvTHOsUgxOA==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.186.0", + "@aws-sdk/credential-provider-imds": "3.186.0", + "@aws-sdk/credential-provider-ini": "3.186.0", + "@aws-sdk/credential-provider-process": "3.186.0", + "@aws-sdk/credential-provider-sso": "3.186.0", + "@aws-sdk/credential-provider-web-identity": "3.186.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/shared-ini-file-loader": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -357,13 +418,13 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.110.0.tgz", - "integrity": "sha512-JJcZePvRTfQHYj/+EEY13yItnZH/e8exlARFUjN0L13UrgHpOJtDQBa+YBHXo6MbTFQh+re25z2kzc+zOYSMNQ==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.186.0.tgz", + "integrity": "sha512-ATRU6gbXvWC1TLnjOEZugC/PBXHBoZgBADid4fDcEQY1vF5e5Ux1kmqkJxyHtV5Wl8sE2uJfwWn+FlpUHRX67g==", "dependencies": { - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/shared-ini-file-loader": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/shared-ini-file-loader": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -371,14 +432,14 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.112.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.112.0.tgz", - "integrity": "sha512-b6rOrSXbNK3fGyPvNpyF5zdktmAoNOqHCTmFSUcxRxOipyRGb5JACsbjWthIQkpWkpNCT8GFNLEg9spXPFIdLA==", - "dependencies": { - "@aws-sdk/client-sso": "3.112.0", - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/shared-ini-file-loader": "3.110.0", - "@aws-sdk/types": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.186.0.tgz", + "integrity": "sha512-mJ+IZljgXPx99HCmuLgBVDPLepHrwqnEEC/0wigrLCx6uz3SrAWmGZsNbxSEtb2CFSAaczlTHcU/kIl7XZIyeQ==", + "dependencies": { + "@aws-sdk/client-sso": "3.186.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/shared-ini-file-loader": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -386,12 +447,12 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.110.0.tgz", - "integrity": "sha512-e4e5u7v3fsUFZsMcFMhMy1NdJBQpunYcLwpYlszm3OEICwTTekQ+hVvnVRd134doHvzepE4yp9sAop0Cj+IRVQ==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.186.0.tgz", + "integrity": "sha512-KqzI5eBV72FE+8SuOQAu+r53RXGVHg4AuDJmdXyo7Gc4wS/B9FNElA8jVUjjYgVnf0FSiri+l41VzQ44dCopSA==", "dependencies": { - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -399,24 +460,24 @@ } }, "node_modules/@aws-sdk/fetch-http-handler": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.110.0.tgz", - "integrity": "sha512-vk+K4GeCZL2J2rtvKO+T0Q7i3MDpEGZBMg5K2tj9sMcEQwty0BF0aFnP7Eu2l4/Zif2z1mWuUFM2WcZI6DVnbw==", - "dependencies": { - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/querystring-builder": "3.110.0", - "@aws-sdk/types": "3.110.0", - "@aws-sdk/util-base64-browser": "3.109.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.186.0.tgz", + "integrity": "sha512-k2v4AAHRD76WnLg7arH94EvIclClo/YfuqO7NoQ6/KwOxjRhs4G6TgIsAZ9E0xmqoJoV81Xqy8H8ldfy9F8LEw==", + "dependencies": { + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/querystring-builder": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/util-base64-browser": "3.186.0", "tslib": "^2.3.1" } }, "node_modules/@aws-sdk/hash-node": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.110.0.tgz", - "integrity": "sha512-wakl+kP2O8wTGYiQ3InZy+CVfGrIpFfq9fo4zif9PZac0BbUbguUU1dkY34uZiaf+4o2/9MoDYrHU2HYeXKxWw==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.186.0.tgz", + "integrity": "sha512-G3zuK8/3KExDTxqrGqko+opOMLRF0BwcwekV/wm3GKIM/NnLhHblBs2zd/yi7VsEoWmuzibfp6uzxgFpEoJ87w==", "dependencies": { - "@aws-sdk/types": "3.110.0", - "@aws-sdk/util-buffer-from": "3.55.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/util-buffer-from": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -424,18 +485,18 @@ } }, "node_modules/@aws-sdk/invalid-dependency": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.110.0.tgz", - "integrity": "sha512-O8J1InmtJkoiUMbQDtxBfOzgigBp9iSVsNXQrhs2qHh3826cJOfE7NGT3u+NMw73Pk5j2cfmOh1+7k/76IqxOg==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.186.0.tgz", + "integrity": "sha512-hjeZKqORhG2DPWYZ776lQ9YO3gjw166vZHZCZU/43kEYaCZHsF4mexHwHzreAY6RfS25cH60Um7dUh1aeVIpkw==", "dependencies": { - "@aws-sdk/types": "3.110.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "node_modules/@aws-sdk/is-array-buffer": { - "version": "3.55.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.55.0.tgz", - "integrity": "sha512-NbiPHVYuPxdqdFd6FxzzN3H1BQn/iWA3ri3Ry7AyLeP/tGs1yzEWMwf8BN8TSMALI0GXT6Sh0GDWy3Ok5xB6DA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.186.0.tgz", + "integrity": "sha512-fObm+P6mjWYzxoFY4y2STHBmSdgKbIAXez0xope563mox62I8I4hhVPUCaDVydXvDpJv8tbedJMk0meJl22+xA==", "dependencies": { "tslib": "^2.3.1" }, @@ -444,12 +505,12 @@ } }, "node_modules/@aws-sdk/middleware-content-length": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.110.0.tgz", - "integrity": "sha512-hKU+zdqfAJQg22LXMVu/z35nNIHrVAKpVKPe9+WYVdL/Z7JKUPK7QymqKGOyDuDbzW6OxyulC1zKGEX12zGmdA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.186.0.tgz", + "integrity": "sha512-Ol3c1ks3IK1s+Okc/rHIX7w2WpXofuQdoAEme37gHeml+8FtUlWH/881h62xfMdf+0YZpRuYv/eM7lBmJBPNJw==", "dependencies": { - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -457,12 +518,12 @@ } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.110.0.tgz", - "integrity": "sha512-/Cknn1vL2LTlclI0MX2RzmtdPlCJ5palCRXxm/mod1oHwg4oNTKRlUX3LUD+L8g7JuJ4h053Ch9KS/A0vanE5Q==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.186.0.tgz", + "integrity": "sha512-5bTzrRzP2IGwyF3QCyMGtSXpOOud537x32htZf344IvVjrqZF/P8CDfGTkHkeBCIH+wnJxjK+l/QBb3ypAMIqQ==", "dependencies": { - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -470,11 +531,11 @@ } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.110.0.tgz", - "integrity": "sha512-+pz+a+8dfTnzLj79nHrv3aONMp/N36/erMd+7JXeR84QEosVLrFBUwKA8x5x6O3s1iBbQzRKMYEIuja9xn1BPA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.186.0.tgz", + "integrity": "sha512-/1gGBImQT8xYh80pB7QtyzA799TqXtLZYQUohWAsFReYB7fdh5o+mu2rX0FNzZnrLIh2zBUNs4yaWGsnab4uXg==", "dependencies": { - "@aws-sdk/types": "3.110.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -482,12 +543,12 @@ } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.110.0.tgz", - "integrity": "sha512-Wav782zd7bcd1e6txRob76CDOdVOaUQ8HXoywiIm/uFrEEUZvhs2mgnXjVUVCMBUehdNgnL99z420aS13JeL/Q==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.186.0.tgz", + "integrity": "sha512-Za7k26Kovb4LuV5tmC6wcVILDCt0kwztwSlB991xk4vwNTja8kKxSt53WsYG8Q2wSaW6UOIbSoguZVyxbIY07Q==", "dependencies": { - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -495,14 +556,14 @@ } }, "node_modules/@aws-sdk/middleware-retry": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.110.0.tgz", - "integrity": "sha512-lwLAQQveCiUqymQvVYjCee6QOXw3Zqbc9yq+pxYdXbs1Cv1XMA6PeJeUU5r5KEVuSceBLyyrnl6E0R1l1om1MQ==", - "dependencies": { - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/service-error-classification": "3.110.0", - "@aws-sdk/types": "3.110.0", - "@aws-sdk/util-middleware": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.186.0.tgz", + "integrity": "sha512-/VI9emEKhhDzlNv9lQMmkyxx3GjJ8yPfXH3HuAeOgM1wx1BjCTLRYEWnTbQwq7BDzVENdneleCsGAp7yaj80Aw==", + "dependencies": { + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/service-error-classification": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/util-middleware": "3.186.0", "tslib": "^2.3.1", "uuid": "^8.3.2" }, @@ -511,15 +572,15 @@ } }, "node_modules/@aws-sdk/middleware-sdk-sts": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.110.0.tgz", - "integrity": "sha512-EjY/YFdlr5jECde6qIrTIyGBbn/34CKcQGKvmvRd31+3qaClIJLAwNuHfcVzWvCUGbAslsfvdbOpLju33pSQRA==", - "dependencies": { - "@aws-sdk/middleware-signing": "3.110.0", - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/signature-v4": "3.110.0", - "@aws-sdk/types": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.186.0.tgz", + "integrity": "sha512-GDcK0O8rjtnd+XRGnxzheq1V2jk4Sj4HtjrxW/ROyhzLOAOyyxutBt+/zOpDD6Gba3qxc69wE+Cf/qngOkEkDw==", + "dependencies": { + "@aws-sdk/middleware-signing": "3.186.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/signature-v4": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -527,11 +588,11 @@ } }, "node_modules/@aws-sdk/middleware-serde": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.110.0.tgz", - "integrity": "sha512-brVupxgEAmcZ9cZvdHEH8zncjvGKIiud8pOe4fiimp5NpHmjBLew4jUbnOKNZNAjaidcKUtz//cxtutD6yXEww==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.186.0.tgz", + "integrity": "sha512-6FEAz70RNf18fKL5O7CepPSwTKJEIoyG9zU6p17GzKMgPeFsxS5xO94Hcq5tV2/CqeHliebjqhKY7yi+Pgok7g==", "dependencies": { - "@aws-sdk/types": "3.110.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -539,14 +600,15 @@ } }, "node_modules/@aws-sdk/middleware-signing": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.110.0.tgz", - "integrity": "sha512-y6ZKrGYfgDlFMzWhZmoq5J1UctBgZOUvMmnU9sSeZ020IlEPiOxFMvR0Zu6TcYThp8uy3P0wyjQtGYeTl9Z/kA==", - "dependencies": { - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/signature-v4": "3.110.0", - "@aws-sdk/types": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.186.0.tgz", + "integrity": "sha512-riCJYG/LlF/rkgVbHkr4xJscc0/sECzDivzTaUmfb9kJhAwGxCyNqnTvg0q6UO00kxSdEB9zNZI2/iJYVBijBQ==", + "dependencies": { + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/signature-v4": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/util-middleware": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -554,9 +616,9 @@ } }, "node_modules/@aws-sdk/middleware-stack": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.110.0.tgz", - "integrity": "sha512-iaLHw6ctOuGa9UxNueU01Xes+15dR+mqioRpUOUZ9Zx+vhXVpD7C8lnNqhRnYeFXs10/rNIzASgsIrAHTlnlIQ==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.186.0.tgz", + "integrity": "sha512-fENMoo0pW7UBrbuycPf+3WZ+fcUgP9PnQ0jcOK3WWZlZ9d2ewh4HNxLh4EE3NkNYj4VIUFXtTUuVNHlG8trXjQ==", "dependencies": { "tslib": "^2.3.1" }, @@ -565,12 +627,12 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.110.0.tgz", - "integrity": "sha512-Y6FgiZr99DilYq6AjeaaWcNwVlSQpNGKrILzvV4Tmz03OaBIspe4KL+8EZ2YA/sAu5Lpw80vItdezqDOwGAlnQ==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.186.0.tgz", + "integrity": "sha512-fb+F2PF9DLKOVMgmhkr+ltN8ZhNJavTla9aqmbd01846OLEaN1n5xEnV7p8q5+EznVBWDF38Oz9Ae5BMt3Hs7w==", "dependencies": { - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -578,13 +640,13 @@ } }, "node_modules/@aws-sdk/node-config-provider": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.110.0.tgz", - "integrity": "sha512-46p4dCPGYctuybTQTwLpjenA1QFHeyJw/OyggGbtUJUy+833+ldnAwcPVML2aXJKUKv3APGI8vq1kaloyNku3Q==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.186.0.tgz", + "integrity": "sha512-De93mgmtuUUeoiKXU8pVHXWKPBfJQlS/lh1k2H9T2Pd9Tzi0l7p5ttddx4BsEx4gk+Pc5flNz+DeptiSjZpa4A==", "dependencies": { - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/shared-ini-file-loader": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/shared-ini-file-loader": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -592,14 +654,14 @@ } }, "node_modules/@aws-sdk/node-http-handler": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.110.0.tgz", - "integrity": "sha512-/rP+hY516DpP8fZhwFW5xM/ElH0w6lxw/15VvZCoY5EnOLAF5XIsJdzscWPSEW2FHCylBM4SNrKhGar14BDXhA==", - "dependencies": { - "@aws-sdk/abort-controller": "3.110.0", - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/querystring-builder": "3.110.0", - "@aws-sdk/types": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.186.0.tgz", + "integrity": "sha512-CbkbDuPZT9UNJ4dAZJWB3BV+Z65wFy7OduqGkzNNrKq6ZYMUfehthhUOTk8vU6RMe/0FkN+J0fFXlBx/bs/cHw==", + "dependencies": { + "@aws-sdk/abort-controller": "3.186.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/querystring-builder": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -607,11 +669,11 @@ } }, "node_modules/@aws-sdk/property-provider": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.110.0.tgz", - "integrity": "sha512-7NkpmYeOkK3mhWBNU+/zSDqwzeaSPH1qrq4L//WV7WS/weYyE/jusQeZoOxVsuZQnQEXHt5O2hKVeUwShl12xA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.186.0.tgz", + "integrity": "sha512-nWKqt36UW3xV23RlHUmat+yevw9up+T+953nfjcmCBKtgWlCWu/aUzewTRhKj3VRscbN+Wer95SBw9Lr/MMOlQ==", "dependencies": { - "@aws-sdk/types": "3.110.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -619,11 +681,11 @@ } }, "node_modules/@aws-sdk/protocol-http": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.110.0.tgz", - "integrity": "sha512-qdi2gCbJiyPyLn+afebPNp/5nVCRh1X7t7IRIFl3FHVEC+o54u/ojay/MLZ4M/+X9Fa4Zxsb0Wpp3T0xAHVDBg==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.186.0.tgz", + "integrity": "sha512-l/KYr/UBDUU5ginqTgHtFfHR3X6ljf/1J1ThIiUg3C3kVC/Zwztm7BEOw8hHRWnWQGU/jYasGYcrcPLdQqFZyQ==", "dependencies": { - "@aws-sdk/types": "3.110.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -631,12 +693,12 @@ } }, "node_modules/@aws-sdk/querystring-builder": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.110.0.tgz", - "integrity": "sha512-7V3CDXj519izmbBn9ZE68ymASwGriA+Aq+cb/yHSVtffnvXjPtvONNw7G/5iVblisGLSCUe2hSvpYtcaXozbHw==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.186.0.tgz", + "integrity": "sha512-mweCpuLufImxfq/rRBTEpjGuB4xhQvbokA+otjnUxlPdIobytLqEs7pCGQfLzQ7+1ZMo8LBXt70RH4A2nSX/JQ==", "dependencies": { - "@aws-sdk/types": "3.110.0", - "@aws-sdk/util-uri-escape": "3.55.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/util-uri-escape": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -644,11 +706,11 @@ } }, "node_modules/@aws-sdk/querystring-parser": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.110.0.tgz", - "integrity": "sha512-//pJHH7hrhdDMZGBPKXKymmC/tJM7gFT0w/qbu/yd3Wm4W2fMB+8gkmj6EZctx7jrsWlfRQuvFejKqEfapur/g==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.186.0.tgz", + "integrity": "sha512-0iYfEloghzPVXJjmnzHamNx1F1jIiTW9Svy5ZF9LVqyr/uHZcQuiWYsuhWloBMLs8mfWarkZM02WfxZ8buAuhg==", "dependencies": { - "@aws-sdk/types": "3.110.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -656,18 +718,19 @@ } }, "node_modules/@aws-sdk/service-error-classification": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.110.0.tgz", - "integrity": "sha512-ccgCE0pU/4RmXR6CP3fLAdhPAve7bK/yXBbGzpSHGAQOXqNxYzOsAvQ30Jg6X+qjLHsI/HR2pLIE65z4k6tynw==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.186.0.tgz", + "integrity": "sha512-DRl3ORk4tF+jmH5uvftlfaq0IeKKpt0UPAOAFQ/JFWe+TjOcQd/K+VC0iiIG97YFp3aeFmH1JbEgsNxd+8fdxw==", "engines": { "node": ">= 12.0.0" } }, "node_modules/@aws-sdk/shared-ini-file-loader": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.110.0.tgz", - "integrity": "sha512-E1ERoqEoG206XNBYWCKLgHkzCbTxdpDEGbsLET2DnvjFsT0s9p2dPvVux3bYl7JVAhyGduE+qcqWk7MzhFCBNQ==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.186.0.tgz", + "integrity": "sha512-2FZqxmICtwN9CYid4dwfJSz/gGFHyStFQ3HCOQ8DsJUf2yREMSBsVmKqsyWgOrYcQ98gPcD5GIa7QO5yl3XF6A==", "dependencies": { + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -675,15 +738,15 @@ } }, "node_modules/@aws-sdk/signature-v4": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.110.0.tgz", - "integrity": "sha512-utxxdllOnmQDhbpipnFAbuQ4c2pwefZ+2hi48jKvQRULQ2PO4nxLmdZm6B0FXaTijbKsyO7GrMik+EZ6mi3ARQ==", - "dependencies": { - "@aws-sdk/is-array-buffer": "3.55.0", - "@aws-sdk/types": "3.110.0", - "@aws-sdk/util-hex-encoding": "3.109.0", - "@aws-sdk/util-middleware": "3.110.0", - "@aws-sdk/util-uri-escape": "3.55.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.186.0.tgz", + "integrity": "sha512-18i96P5c4suMqwSNhnEOqhq4doqqyjH4fn0YV3F8TkekHPIWP4mtIJ0PWAN4eievqdtcKgD/GqVO6FaJG9texw==", + "dependencies": { + "@aws-sdk/is-array-buffer": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/util-hex-encoding": "3.186.0", + "@aws-sdk/util-middleware": "3.186.0", + "@aws-sdk/util-uri-escape": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -691,12 +754,12 @@ } }, "node_modules/@aws-sdk/smithy-client": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.110.0.tgz", - "integrity": "sha512-gNLYrmdAe/1hVF2Nv2LF4OkL1A0a1o708pEMZHzql9xP164omRDaLrGDhz9tH7tsJEgLz+Bf4E8nTuISeDwvGg==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.186.0.tgz", + "integrity": "sha512-rdAxSFGSnrSprVJ6i1BXi65r4X14cuya6fYe8dSdgmFSa+U2ZevT97lb3tSINCUxBGeMXhENIzbVGkRZuMh+DQ==", "dependencies": { - "@aws-sdk/middleware-stack": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/middleware-stack": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -704,37 +767,37 @@ } }, "node_modules/@aws-sdk/types": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.110.0.tgz", - "integrity": "sha512-dLVoqODU3laaqNFPyN1QLtlQnwX4gNPMXptEBIt/iJpuZf66IYJe6WCzVZGt4Zfa1CnUmrlA428AzdcA/KCr2A==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.186.0.tgz", + "integrity": "sha512-NatmSU37U+XauMFJCdFI6nougC20JUFZar+ump5wVv0i54H+2Refg1YbFDxSs0FY28TSB9jfhWIpfFBmXgL5MQ==", "engines": { "node": ">= 12.0.0" } }, "node_modules/@aws-sdk/url-parser": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.110.0.tgz", - "integrity": "sha512-tILFB8/Q73yzgO0dErJNnELmmBszd0E6FucwAnG3hfDefjqCBe09Q/1yhu2aARXyRmZa4AKp0sWcdwIWHc8dnA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.186.0.tgz", + "integrity": "sha512-jfdJkKqJZp8qjjwEjIGDqbqTuajBsddw02f86WiL8bPqD8W13/hdqbG4Fpwc+Bm6GwR6/4MY6xWXFnk8jDUKeA==", "dependencies": { - "@aws-sdk/querystring-parser": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/querystring-parser": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "node_modules/@aws-sdk/util-base64-browser": { - "version": "3.109.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64-browser/-/util-base64-browser-3.109.0.tgz", - "integrity": "sha512-lAZ6fyDGiRLaIsKT9qh7P9FGuNyZ4gAbr1YOSQk/5mHtaTuUvxlPptZuInNM/0MPQm6lpcot00D8IWTucn4PbA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64-browser/-/util-base64-browser-3.186.0.tgz", + "integrity": "sha512-TpQL8opoFfzTwUDxKeon/vuc83kGXpYqjl6hR8WzmHoQgmFfdFlV+0KXZOohra1001OP3FhqvMqaYbO8p9vXVQ==", "dependencies": { "tslib": "^2.3.1" } }, "node_modules/@aws-sdk/util-base64-node": { - "version": "3.55.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64-node/-/util-base64-node-3.55.0.tgz", - "integrity": "sha512-UQ/ZuNoAc8CFMpSiRYmevaTsuRKzLwulZTnM8LNlIt9Wx1tpNvqp80cfvVj7yySKROtEi20wq29h31dZf1eYNQ==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64-node/-/util-base64-node-3.186.0.tgz", + "integrity": "sha512-wH5Y/EQNBfGS4VkkmiMyZXU+Ak6VCoFM1GKWopV+sj03zR2D4FHexi4SxWwEBMpZCd6foMtihhbNBuPA5fnh6w==", "dependencies": { - "@aws-sdk/util-buffer-from": "3.55.0", + "@aws-sdk/util-buffer-from": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -742,17 +805,17 @@ } }, "node_modules/@aws-sdk/util-body-length-browser": { - "version": "3.55.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.55.0.tgz", - "integrity": "sha512-Ei2OCzXQw5N6ZkTMZbamUzc1z+z1R1Ja5tMEagz5BxuX4vWdBObT+uGlSzL8yvTbjoPjnxWA2aXyEqaUP3JS8Q==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.186.0.tgz", + "integrity": "sha512-zKtjkI/dkj9oGkjo+7fIz+I9KuHrVt1ROAeL4OmDESS8UZi3/O8uMDFMuCp8jft6H+WFuYH6qRVWAVwXMiasXw==", "dependencies": { "tslib": "^2.3.1" } }, "node_modules/@aws-sdk/util-body-length-node": { - "version": "3.55.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.55.0.tgz", - "integrity": "sha512-lU1d4I+9wJwydduXs0SxSfd+mHKjxeyd39VwOv6i2KSwWkPbji9UQqpflKLKw+r45jL7+xU/zfeTUg5Tt/3Gew==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.186.0.tgz", + "integrity": "sha512-U7Ii8u8Wvu9EnBWKKeuwkdrWto3c0j7LG677Spe6vtwWkvY70n9WGfiKHTgBpVeLNv8jvfcx5+H0UOPQK1o9SQ==", "dependencies": { "tslib": "^2.3.1" }, @@ -761,11 +824,11 @@ } }, "node_modules/@aws-sdk/util-buffer-from": { - "version": "3.55.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.55.0.tgz", - "integrity": "sha512-uVzKG1UgvnV7XX2FPTylBujYMKBPBaq/qFBxfl0LVNfrty7YjpfieQxAe6yRLD+T0Kir/WDQwGvYC+tOYG3IGA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.186.0.tgz", + "integrity": "sha512-be2GCk2lsLWg/2V5Y+S4/9pOMXhOQo4DR4dIqBdR2R+jrMMHN9Xsr5QrkT6chcqLaJ/SBlwiAEEi3StMRmCOXA==", "dependencies": { - "@aws-sdk/is-array-buffer": "3.55.0", + "@aws-sdk/is-array-buffer": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -773,9 +836,9 @@ } }, "node_modules/@aws-sdk/util-config-provider": { - "version": "3.109.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.109.0.tgz", - "integrity": "sha512-GrAZl/aBv0A28LkyNyq8SPJ5fmViCwz80fWLMeWx/6q5AbivuILogjlWwEZSvZ9zrlHOcFC0+AnCa5pQrjaslw==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.186.0.tgz", + "integrity": "sha512-71Qwu/PN02XsRLApyxG0EUy/NxWh/CXxtl2C7qY14t+KTiRapwbDkdJ1cMsqYqghYP4BwJoj1M+EFMQSSlkZQQ==", "dependencies": { "tslib": "^2.3.1" }, @@ -784,12 +847,12 @@ } }, "node_modules/@aws-sdk/util-defaults-mode-browser": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.110.0.tgz", - "integrity": "sha512-Y2dcOOD20S3bv/IjUqpdKIiDt6995SXNG5Pu/LeSdXNyLCOIm9rX4gHTxl9fC1KK5M/gR9fGJ362f67WwqEEqw==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.186.0.tgz", + "integrity": "sha512-U8GOfIdQ0dZ7RRVpPynGteAHx4URtEh+JfWHHVfS6xLPthPHWTbyRhkQX++K/F8Jk+T5U8Anrrqlea4TlcO2DA==", "dependencies": { - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/types": "3.186.0", "bowser": "^2.11.0", "tslib": "^2.3.1" }, @@ -798,15 +861,15 @@ } }, "node_modules/@aws-sdk/util-defaults-mode-node": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.110.0.tgz", - "integrity": "sha512-Cr3Z5nyrw1KowjbW76xp8hkT/zJtYjAVZ9PS4l84KxIicbVvDOBpxG3yNddkuQcavmlH6G4wH9uM5DcnpKDncg==", - "dependencies": { - "@aws-sdk/config-resolver": "3.110.0", - "@aws-sdk/credential-provider-imds": "3.110.0", - "@aws-sdk/node-config-provider": "3.110.0", - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/types": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.186.0.tgz", + "integrity": "sha512-N6O5bpwCiE4z8y7SPHd7KYlszmNOYREa+mMgtOIXRU3VXSEHVKVWTZsHKvNTTHpW0qMqtgIvjvXCo3vsch5l3A==", + "dependencies": { + "@aws-sdk/config-resolver": "3.186.0", + "@aws-sdk/credential-provider-imds": "3.186.0", + "@aws-sdk/node-config-provider": "3.186.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -814,9 +877,9 @@ } }, "node_modules/@aws-sdk/util-hex-encoding": { - "version": "3.109.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.109.0.tgz", - "integrity": "sha512-s8CgTNrn3cLkrdiohfxLuOYPCanzvHn/aH5RW6DaMoeQiG5Hl9QUiP/WtdQ9QQx3xvpQFpmvxIaSBwSgFNLQxA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.186.0.tgz", + "integrity": "sha512-UL9rdgIZz1E/jpAfaKH8QgUxNK9VP5JPgoR0bSiaefMjnsoBh0x/VVMsfUyziOoJCMLebhJzFowtwrSKEGsxNg==", "dependencies": { "tslib": "^2.3.1" }, @@ -825,9 +888,9 @@ } }, "node_modules/@aws-sdk/util-locate-window": { - "version": "3.55.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.55.0.tgz", - "integrity": "sha512-0sPmK2JaJE2BbTcnvybzob/VrFKCXKfN4CUKcvn0yGg/me7Bz+vtzQRB3Xp+YSx+7OtWxzv63wsvHoAnXvgxgg==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.186.0.tgz", + "integrity": "sha512-fmQLkH16ga6c5fWsA+kBYklQJjlPlcc8uayTR4avi5g3Nxqm6wPpyUwo5CppwjwWMeS+NXG0HgITtkkGntcRNg==", "dependencies": { "tslib": "^2.3.1" }, @@ -836,9 +899,9 @@ } }, "node_modules/@aws-sdk/util-middleware": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.110.0.tgz", - "integrity": "sha512-PTVWrI5fA9d5hHJs6RzX2dIS2jRQ3uW073Fm0BePpQeDdZrEk+S5KNwRhUtpN6sdSV45vm6S9rrjZUG51qwGmA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.186.0.tgz", + "integrity": "sha512-fddwDgXtnHyL9mEZ4s1tBBsKnVQHqTUmFbZKUUKPrg9CxOh0Y/zZxEa5Olg/8dS/LzM1tvg0ATkcyd4/kEHIhg==", "dependencies": { "tslib": "^2.3.1" }, @@ -847,9 +910,9 @@ } }, "node_modules/@aws-sdk/util-uri-escape": { - "version": "3.55.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.55.0.tgz", - "integrity": "sha512-mmdDLUpFCN2nkfwlLdOM54lTD528GiGSPN1qb8XtGLgZsJUmg3uJSFIN2lPeSbEwJB3NFjVas/rnQC48i7mV8w==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.186.0.tgz", + "integrity": "sha512-imtOrJFpIZAipAg8VmRqYwv1G/x4xzyoxOJ48ZSn1/ZGnKEEnB6n6E9gwYRebi4mlRuMSVeZwCPLq0ey5hReeQ==", "dependencies": { "tslib": "^2.3.1" }, @@ -858,42 +921,50 @@ } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.110.0.tgz", - "integrity": "sha512-rNdhmHDMV5dNJctqlBWimkZLJRB+x03DB+61pm+SKSFk6gPIVIvc1WNXqDFphkiswT4vA13ZUkGHzt+N4+noQQ==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.186.0.tgz", + "integrity": "sha512-fbRcTTutMk4YXY3A2LePI4jWSIeHOT8DaYavpc/9Xshz/WH9RTGMmokeVOcClRNBeDSi5cELPJJ7gx6SFD3ZlQ==", "dependencies": { - "@aws-sdk/types": "3.110.0", + "@aws-sdk/types": "3.186.0", "bowser": "^2.11.0", "tslib": "^2.3.1" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.110.0.tgz", - "integrity": "sha512-OQ915TPCCBwZWz5Np8zkNWn7U6KvrTZfFoCOy/VIemK3dUqmnBZ7HqGpuZx8SwJ2R9JE1x+j0niYSJ5fWJZZKA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.186.0.tgz", + "integrity": "sha512-oWZR7hN6NtOgnT6fUvHaafgbipQc2xJCRB93XHiF9aZGptGNLJzznIOP7uURdn0bTnF73ejbUXWLQIm8/6ue6w==", "dependencies": { - "@aws-sdk/node-config-provider": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/node-config-provider": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { "node": ">= 12.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } } }, "node_modules/@aws-sdk/util-utf8-browser": { - "version": "3.109.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.109.0.tgz", - "integrity": "sha512-FmcGSz0v7Bqpl1SE8G1Gc0CtDpug+rvqNCG/szn86JApD/f5x8oByjbEiAyTU2ZH2VevUntx6EW68ulHyH+x+w==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.186.0.tgz", + "integrity": "sha512-n+IdFYF/4qT2WxhMOCeig8LndDggaYHw3BJJtfIBZRiS16lgwcGYvOUmhCkn0aSlG1f/eyg9YZHQG0iz9eLdHQ==", "dependencies": { "tslib": "^2.3.1" } }, "node_modules/@aws-sdk/util-utf8-node": { - "version": "3.109.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-node/-/util-utf8-node-3.109.0.tgz", - "integrity": "sha512-Ti/ZBdvz2eSTElsucjzNmzpyg2MwfD1rXmxD0hZuIF8bPON/0+sZYnWd5CbDw9kgmhy28dmKue086tbZ1G0iLQ==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-node/-/util-utf8-node-3.186.0.tgz", + "integrity": "sha512-7qlE0dOVdjuRbZTb7HFywnHHCrsN7AeQiTnsWT63mjXGDbPeUWQQw3TrdI20um3cxZXnKoeudGq8K6zbXyQ4iA==", "dependencies": { - "@aws-sdk/util-buffer-from": "3.55.0", + "@aws-sdk/util-buffer-from": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -901,12 +972,12 @@ } }, "node_modules/@aws-sdk/util-waiter": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-waiter/-/util-waiter-3.110.0.tgz", - "integrity": "sha512-8dE6W6XYfjk1gx/aeb8NeLfMMLkLFhlV1lmKpFSBJhY8msajU8aQahTuykq5JW8QT/wCGbqbu7dH35SdX7kO+A==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-waiter/-/util-waiter-3.186.0.tgz", + "integrity": "sha512-oSm45VadBBWC/K2W1mrRNzm9RzbXt6VopBQ5iTDU7B3qIXlyAG9k1JqOvmYIdYq1oOgjM3Hv2+9sngi3+MZs1A==", "dependencies": { - "@aws-sdk/abort-controller": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/abort-controller": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" }, "engines": { @@ -914,42 +985,42 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dev": true, "dependencies": { - "@babel/highlight": "^7.16.7" + "@babel/highlight": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.18.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.5.tgz", - "integrity": "sha512-BxhE40PVCBxVEJsSBhB6UWyAuqJRxGsAw8BdHMJ3AKGydcwuWW4kOO3HmqBQAdcq/OP+/DlTVxLvsCzRTnZuGg==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.4.tgz", + "integrity": "sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.18.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.5.tgz", - "integrity": "sha512-MGY8vg3DxMnctw0LdvSEojOsumc70g0t18gNyUdAZqB1Rpd1Bqo/svHGvt+UJ6JcGX+DIekGFDxxIWofBxLCnQ==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", + "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.18.2", - "@babel/helper-compilation-targets": "^7.18.2", - "@babel/helper-module-transforms": "^7.18.0", - "@babel/helpers": "^7.18.2", - "@babel/parser": "^7.18.5", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.5", - "@babel/types": "^7.18.4", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helpers": "^7.19.0", + "@babel/parser": "^7.19.3", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.3", + "@babel/types": "^7.19.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -965,13 +1036,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.2.tgz", - "integrity": "sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==", + "version": "7.19.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.5.tgz", + "integrity": "sha512-DxbNz9Lz4aMZ99qPpO1raTbcrI1ZeYh+9NR9qhfkQIbFtVEqotHojEBxHzmxhVONkGt6VyrqVQcgpefMy9pqcg==", "dev": true, "dependencies": { - "@babel/types": "^7.18.2", - "@jridgewell/gen-mapping": "^0.3.0", + "@babel/types": "^7.19.4", + "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, "engines": { @@ -979,12 +1050,12 @@ } }, "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", - "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.0", + "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" }, @@ -993,14 +1064,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.2.tgz", - "integrity": "sha512-s1jnPotJS9uQnzFtiZVBUxe67CuBa679oWFHpxYYnTpRL/1ffhyX44R9uYiXoa/pLXcY9H2moJta0iaanlk/rQ==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", + "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.17.10", - "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.20.2", + "@babel/compat-data": "^7.19.3", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", "semver": "^6.3.0" }, "engines": { @@ -1011,142 +1082,151 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.2.tgz", - "integrity": "sha512-14GQKWkX9oJzPiQQ7/J36FTXcD4kSp8egKjO9nINlSKiHITRA9q/R74qu8S9xlc/b/yjsJItQUeeh3xnGN0voQ==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", - "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "dev": true, "dependencies": { - "@babel/template": "^7.16.7", - "@babel/types": "^7.17.0" + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.0.tgz", - "integrity": "sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", + "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.17.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.0", - "@babel/types": "^7.18.0" + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.18.6", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz", - "integrity": "sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", + "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz", - "integrity": "sha512-7LIrjYzndorDY88MycupkpQLKS1AFfsVRm2k/9PtKScSy5tZq0McZTj+DiMRynboZfIqOKvo03pmhTaUgiD6fQ==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", + "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", "dev": true, "dependencies": { - "@babel/types": "^7.18.2" + "@babel/types": "^7.19.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.2.tgz", - "integrity": "sha512-j+d+u5xT5utcQSzrh9p+PaJX94h++KN+ng9b9WEJq7pkUPAd61FGqhjuUEdfknb3E/uDBb7ruwEeKkIxNJPIrg==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.4.tgz", + "integrity": "sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==", "dev": true, "dependencies": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.2", - "@babel/types": "^7.18.2" + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.4", + "@babel/types": "^7.19.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz", - "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -1226,9 +1306,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.18.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.5.tgz", - "integrity": "sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.4.tgz", + "integrity": "sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -1385,12 +1465,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.12.tgz", - "integrity": "sha512-TYY0SXFiO31YXtNg3HtFwNJHjLsAyIIhAhNWkQ5whPPS7HWUFlg9z0Ta4qAQNjQbP1wsSt/oKkmZ/4/WWdMUpw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", + "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -1400,33 +1480,33 @@ } }, "node_modules/@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.18.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.5.tgz", - "integrity": "sha512-aKXj1KT66sBj0vVzk6rEeAO6Z9aiiQ68wfDgge3nHhA/my6xMM/7HGQUNumKZaoa2qUPQ5whJG9aAifsxUKfLA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.18.2", - "@babel/helper-environment-visitor": "^7.18.2", - "@babel/helper-function-name": "^7.17.9", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.18.5", - "@babel/types": "^7.18.4", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.4.tgz", + "integrity": "sha512-w3K1i+V5u2aJUOXBFFC5pveFLmtq1s3qcdDNC2qRI6WPBQIDaKFqXxDEqDO/h1dQ3HjsZoZMyIy6jGLq0xtw+g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.4", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.19.4", + "@babel/types": "^7.19.4", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1435,12 +1515,13 @@ } }, "node_modules/@babel/types": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.4.tgz", - "integrity": "sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1754,37 +1835,37 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", - "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", - "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "version": "0.3.16", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.16.tgz", + "integrity": "sha512-LCQ+NeThyJ4k1W2d+vIKdxuSt9R3pQSZ4P92m7EakaYuXcVWbHuT5bjNcqLd4Rdgi6xYWYDvBJZJLZSLanjDcA==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "node_modules/@sinonjs/commons": { @@ -1871,9 +1952,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.17.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.17.1.tgz", - "integrity": "sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", + "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", "dev": true, "dependencies": { "@babel/types": "^7.3.0" @@ -1962,9 +2043,9 @@ "dev": true }, "node_modules/acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2035,7 +2116,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -2044,7 +2124,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -2090,9 +2169,9 @@ "dev": true }, "node_modules/aws-cdk": { - "version": "2.28.1", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.28.1.tgz", - "integrity": "sha512-0Kklrj9HHg6HkYZQuTnJ+2+RLTqlVcxECUmlDudBxbPxJQcc5pEA9stfo8wwh1CtoWYuF4A4moP7B19Yvw4nJg==", + "version": "2.45.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.45.0.tgz", + "integrity": "sha512-AIug6Ugvtd3I0+U3gTNZtJVDhOgpGpxwWMoOQUlX6xKGwDgQxWrWdq2QWe7ZyKgCRnY9SM90fa+Yxbx+VYk9Bw==", "dev": true, "bin": { "cdk": "bin/cdk" @@ -2105,9 +2184,9 @@ } }, "node_modules/aws-cdk-lib": { - "version": "2.28.1", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.28.1.tgz", - "integrity": "sha512-YFJKvv3lU7HUfud+4uyQT5tNyJhidBB1ftBmc6NzML+UXAuelPZICJLdGuoE/dA6dU3mB/sT15S+fTzATTwvfg==", + "version": "2.45.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.45.0.tgz", + "integrity": "sha512-oEeZZF8xjub9KYAB7n01A60wwQXSzNapmiih3t5uf9aEvlvqT+0as8/WrPdNIeAaf9Lhb0WQXdZ2o2DlsFHbAg==", "bundleDependencies": [ "@balena/dockerignore", "case", @@ -2420,9 +2499,9 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.20.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.4.tgz", - "integrity": "sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==", + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "dev": true, "funding": [ { @@ -2435,11 +2514,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001349", - "electron-to-chromium": "^1.4.147", - "escalade": "^3.1.1", - "node-releases": "^2.0.5", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" }, "bin": { "browserslist": "cli.js" @@ -2493,9 +2571,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001355", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001355.tgz", - "integrity": "sha512-Sd6pjJHF27LzCB7pT7qs+kuX2ndurzCzkpJl6Qct7LPSZ9jn0bkOA8mdgMgmqnQAWLVOOGjLpc+66V57eLtb1g==", + "version": "1.0.30001418", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz", + "integrity": "sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==", "dev": true, "funding": [ { @@ -2512,6 +2590,21 @@ "resolved": "../cdk-common", "link": true }, + "node_modules/cdk2-python-library-layer": { + "version": "0.1.0", + "resolved": "git+ssh://git@github.com/kikuomax/cdk-python-library-layer.git#d1133709d2e9e3833acc4ab097a641568e3ede2b", + "license": "MIT", + "dependencies": { + "fs-extra": "^10.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "aws-cdk-lib": ">=2.0.0", + "constructs": ">=10.0.0" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -2538,9 +2631,9 @@ } }, "node_modules/ci-info": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", - "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", + "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==", "dev": true }, "node_modules/cjs-module-lexer": { @@ -2550,14 +2643,16 @@ "dev": true }, "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/co": { @@ -2580,7 +2675,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -2591,8 +2685,7 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/combined-stream": { "version": "1.0.8", @@ -2613,21 +2706,18 @@ "dev": true }, "node_modules/constructs": { - "version": "10.1.42", - "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.1.42.tgz", - "integrity": "sha512-5AELa/PFtZG+WTjn9HoXhqsDZYV6l3J7Li9xw6vREYVMasF8cnVbTZvA4crP1gIyKtBAxAlnZCmzmCbicnH6eg==", + "version": "10.1.128", + "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.1.128.tgz", + "integrity": "sha512-X2QvdedBwVRAqwU5I2Hv+xcB7xumYO/Z+PNozubDIRgtetWRWIOOkZCRXeERm7xfCjLVyQdAPHDKVuoVuGRoHA==", "engines": { "node": ">= 14.17.0" } }, "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true }, "node_modules/create-require": { "version": "1.1.1", @@ -2705,9 +2795,9 @@ } }, "node_modules/decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.1.tgz", + "integrity": "sha512-F29o+vci4DodHYT9UrR5IEbfBw9pE5eSapIJdTqXK5+6hq+t8VRxwQyKlW2i+KDKFkkJQRvFyI/QXD83h8LyQw==", "dev": true }, "node_modules/dedent": { @@ -2789,9 +2879,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.158", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.158.tgz", - "integrity": "sha512-gppO3/+Y6sP432HtvwvuU8S+YYYLH4PmAYvQwqUtt9HDOmEsBwQfLnK9T8+1NIKwAS1BEygIjTaATC4H5EzvxQ==", + "version": "1.4.276", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.276.tgz", + "integrity": "sha512-EpuHPqu8YhonqLBXHoU6hDJCD98FCe6KDoet3/gY1qsQ6usjJoHqBH2YIVs8FXaAtHwVL8Uqa/fsYao/vq9VWQ==", "dev": true }, "node_modules/emittery": { @@ -2809,8 +2899,7 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/entities": { "version": "2.2.0", @@ -2833,7 +2922,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, "engines": { "node": ">=6" } @@ -2972,9 +3060,9 @@ } }, "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, "dependencies": { "bser": "2.1.1" @@ -3019,6 +3107,19 @@ "node": ">= 6" } }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3058,7 +3159,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -3116,8 +3216,7 @@ "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "node_modules/has": { "version": "1.0.3", @@ -3257,9 +3356,9 @@ "dev": true }, "node_modules/is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -3272,7 +3371,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -3335,9 +3433,9 @@ } }, "node_modules/istanbul-lib-instrument": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", - "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "dependencies": { "@babel/core": "^7.12.3", @@ -3379,9 +3477,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", - "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -3494,6 +3592,35 @@ } } }, + "node_modules/jest-cli/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/jest-cli/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/jest-config": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", @@ -3912,9 +4039,9 @@ } }, "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -4114,6 +4241,17 @@ "node": ">=6" } }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -4297,9 +4435,9 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz", - "integrity": "sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", "dev": true }, "node_modules/normalize-path": { @@ -4324,9 +4462,9 @@ } }, "node_modules/nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", + "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", "dev": true }, "node_modules/once": { @@ -4551,9 +4689,9 @@ } }, "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true }, "node_modules/punycode": { @@ -4565,6 +4703,12 @@ "node": ">=6" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -4575,18 +4719,23 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "node_modules/resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "dev": true, "dependencies": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -4642,12 +4791,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -4769,7 +4912,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -4783,7 +4925,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -4834,9 +4975,9 @@ } }, "node_modules/supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", "dev": true, "dependencies": { "has-flag": "^4.0.0", @@ -4928,19 +5069,29 @@ } }, "node_modules/tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", + "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", "dev": true, "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", - "universalify": "^0.1.2" + "universalify": "^0.2.0", + "url-parse": "^1.5.3" }, "engines": { "node": ">=6" } }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/tr46": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", @@ -4997,9 +5148,9 @@ } }, "node_modules/ts-jest/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -5012,9 +5163,9 @@ } }, "node_modules/ts-node": { - "version": "10.8.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.1.tgz", - "integrity": "sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", @@ -5124,12 +5275,47 @@ } }, "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "engines": { - "node": ">= 4.0.0" + "node": ">= 10.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" } }, "node_modules/uuid": { @@ -5265,7 +5451,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -5297,9 +5482,9 @@ } }, "node_modules/ws": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz", - "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==", + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", "dev": true, "engines": { "node": ">=8.3.0" @@ -5333,7 +5518,6 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, "engines": { "node": ">=10" } @@ -5345,21 +5529,20 @@ "dev": true }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz", + "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==", "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.0.0" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-parser": { @@ -5371,6 +5554,14 @@ "node": ">=10" } }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", @@ -5392,10 +5583,16 @@ "@jridgewell/trace-mapping": "^0.3.9" } }, + "@aws-cdk/aws-lambda-python-alpha": { + "version": "2.45.0-alpha.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-lambda-python-alpha/-/aws-lambda-python-alpha-2.45.0-alpha.0.tgz", + "integrity": "sha512-seRYApZ/FUSi19PHS/3cXfpeijdrc8JuMlnUl688IE3FOxAYaT+geFx5KldW3+9mG5cRSxCYlXukf3NOW2ZCjw==", + "requires": {} + }, "@aws-crypto/ie11-detection": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-2.0.0.tgz", - "integrity": "sha512-pkVXf/dq6PITJ0jzYZ69VhL8VFOFoPZLZqtU/12SGnzYuJOOGNfF41q9GxdI1yqC8R13Rq3jOLKDFpUJFT5eTA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-2.0.2.tgz", + "integrity": "sha512-5XDMQY98gMAf/WRTic5G++jfmS/VLM0rwpiOpaainKi4L0nqWMSB1SzsrEG5rjFZGYN6ZAefO+/Yta2dFM0kMw==", "requires": { "tslib": "^1.11.1" }, @@ -5447,9 +5644,9 @@ } }, "@aws-crypto/supports-web-crypto": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-2.0.0.tgz", - "integrity": "sha512-Ge7WQ3E0OC7FHYprsZV3h0QIcpdyJLvIeg+uTuHqRYm8D6qCFJoiC+edSzSyFiHtZf+NOQDJ1q46qxjtzIY2nA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-2.0.2.tgz", + "integrity": "sha512-6mbSsLHwZ99CTOOswvCRP3C+VCWnzBf+1SnbWxzzJ9lR0mA0JnY2JEAhp8rqmTE0GPFy88rrM27ffgp62oErMQ==", "requires": { "tslib": "^1.11.1" }, @@ -5462,11 +5659,11 @@ } }, "@aws-crypto/util": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-2.0.1.tgz", - "integrity": "sha512-JJmFFwvbm08lULw4Nm5QOLg8+lAQeC8aCXK5xrtxntYzYXCGfHwUJ4Is3770Q7HmICsXthGQ+ZsDL7C2uH3yBQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-2.0.2.tgz", + "integrity": "sha512-Lgu5v/0e/BcrZ5m/IWqzPUf3UYFTy/PpeED+uc9SWUR1iZQL8XXbGQg10UfllwwBryO3hFF5dizK+78aoXC1eA==", "requires": { - "@aws-sdk/types": "^3.1.0", + "@aws-sdk/types": "^3.110.0", "@aws-sdk/util-utf8-browser": "^3.0.0", "tslib": "^1.11.1" }, @@ -5479,677 +5676,721 @@ } }, "@aws-sdk/abort-controller": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.110.0.tgz", - "integrity": "sha512-zok/WEVuK7Jh6V9YeA56pNZtxUASon9LTkS7vE65A4UFmNkPGNBCNgoiBcbhWfxwrZ8wtXcQk6rtUut39831mA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.186.0.tgz", + "integrity": "sha512-JFvvvtEcbYOvVRRXasi64Dd1VcOz5kJmPvtzsJ+HzMHvPbGGs/aopOJAZQJMJttzJmJwVTay0QL6yag9Kk8nYA==", "requires": { - "@aws-sdk/types": "3.110.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/client-cloudformation": { - "version": "3.112.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudformation/-/client-cloudformation-3.112.0.tgz", - "integrity": "sha512-CQ0HQ5qoXcjP1uoz9AtRYCfar0s/3xq4xGHcCqaeSa6j7nQicHFfT9GsfF5oK9OkE8wZ1EX5OJSUHMm0ONvMQQ==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudformation/-/client-cloudformation-3.186.0.tgz", + "integrity": "sha512-CAZAX9anSOmrqW9YX34pHIz05Nje2GRd3p/U2NrOs4X4gu9jeg0yf2Ea6O9u6UTSH6hniZKZD3ITbmSFA/5Lgw==", "requires": { "@aws-crypto/sha256-browser": "2.0.0", "@aws-crypto/sha256-js": "2.0.0", - "@aws-sdk/client-sts": "3.112.0", - "@aws-sdk/config-resolver": "3.110.0", - "@aws-sdk/credential-provider-node": "3.112.0", - "@aws-sdk/fetch-http-handler": "3.110.0", - "@aws-sdk/hash-node": "3.110.0", - "@aws-sdk/invalid-dependency": "3.110.0", - "@aws-sdk/middleware-content-length": "3.110.0", - "@aws-sdk/middleware-host-header": "3.110.0", - "@aws-sdk/middleware-logger": "3.110.0", - "@aws-sdk/middleware-recursion-detection": "3.110.0", - "@aws-sdk/middleware-retry": "3.110.0", - "@aws-sdk/middleware-serde": "3.110.0", - "@aws-sdk/middleware-signing": "3.110.0", - "@aws-sdk/middleware-stack": "3.110.0", - "@aws-sdk/middleware-user-agent": "3.110.0", - "@aws-sdk/node-config-provider": "3.110.0", - "@aws-sdk/node-http-handler": "3.110.0", - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/smithy-client": "3.110.0", - "@aws-sdk/types": "3.110.0", - "@aws-sdk/url-parser": "3.110.0", - "@aws-sdk/util-base64-browser": "3.109.0", - "@aws-sdk/util-base64-node": "3.55.0", - "@aws-sdk/util-body-length-browser": "3.55.0", - "@aws-sdk/util-body-length-node": "3.55.0", - "@aws-sdk/util-defaults-mode-browser": "3.110.0", - "@aws-sdk/util-defaults-mode-node": "3.110.0", - "@aws-sdk/util-user-agent-browser": "3.110.0", - "@aws-sdk/util-user-agent-node": "3.110.0", - "@aws-sdk/util-utf8-browser": "3.109.0", - "@aws-sdk/util-utf8-node": "3.109.0", - "@aws-sdk/util-waiter": "3.110.0", + "@aws-sdk/client-sts": "3.186.0", + "@aws-sdk/config-resolver": "3.186.0", + "@aws-sdk/credential-provider-node": "3.186.0", + "@aws-sdk/fetch-http-handler": "3.186.0", + "@aws-sdk/hash-node": "3.186.0", + "@aws-sdk/invalid-dependency": "3.186.0", + "@aws-sdk/middleware-content-length": "3.186.0", + "@aws-sdk/middleware-host-header": "3.186.0", + "@aws-sdk/middleware-logger": "3.186.0", + "@aws-sdk/middleware-recursion-detection": "3.186.0", + "@aws-sdk/middleware-retry": "3.186.0", + "@aws-sdk/middleware-serde": "3.186.0", + "@aws-sdk/middleware-signing": "3.186.0", + "@aws-sdk/middleware-stack": "3.186.0", + "@aws-sdk/middleware-user-agent": "3.186.0", + "@aws-sdk/node-config-provider": "3.186.0", + "@aws-sdk/node-http-handler": "3.186.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/smithy-client": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/url-parser": "3.186.0", + "@aws-sdk/util-base64-browser": "3.186.0", + "@aws-sdk/util-base64-node": "3.186.0", + "@aws-sdk/util-body-length-browser": "3.186.0", + "@aws-sdk/util-body-length-node": "3.186.0", + "@aws-sdk/util-defaults-mode-browser": "3.186.0", + "@aws-sdk/util-defaults-mode-node": "3.186.0", + "@aws-sdk/util-user-agent-browser": "3.186.0", + "@aws-sdk/util-user-agent-node": "3.186.0", + "@aws-sdk/util-utf8-browser": "3.186.0", + "@aws-sdk/util-utf8-node": "3.186.0", + "@aws-sdk/util-waiter": "3.186.0", "entities": "2.2.0", "fast-xml-parser": "3.19.0", "tslib": "^2.3.1", "uuid": "^8.3.2" } }, + "@aws-sdk/client-lambda": { + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.186.0.tgz", + "integrity": "sha512-Wr/s591KMRhRRMnv4eWpJ56Kvt5wMjHFW/XGb4NBEPBkLnd/92jVDXp76tGhmbILa/zNpMBaHTx2eqDvHA6AXQ==", + "requires": { + "@aws-crypto/sha256-browser": "2.0.0", + "@aws-crypto/sha256-js": "2.0.0", + "@aws-sdk/client-sts": "3.186.0", + "@aws-sdk/config-resolver": "3.186.0", + "@aws-sdk/credential-provider-node": "3.186.0", + "@aws-sdk/fetch-http-handler": "3.186.0", + "@aws-sdk/hash-node": "3.186.0", + "@aws-sdk/invalid-dependency": "3.186.0", + "@aws-sdk/middleware-content-length": "3.186.0", + "@aws-sdk/middleware-host-header": "3.186.0", + "@aws-sdk/middleware-logger": "3.186.0", + "@aws-sdk/middleware-recursion-detection": "3.186.0", + "@aws-sdk/middleware-retry": "3.186.0", + "@aws-sdk/middleware-serde": "3.186.0", + "@aws-sdk/middleware-signing": "3.186.0", + "@aws-sdk/middleware-stack": "3.186.0", + "@aws-sdk/middleware-user-agent": "3.186.0", + "@aws-sdk/node-config-provider": "3.186.0", + "@aws-sdk/node-http-handler": "3.186.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/smithy-client": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/url-parser": "3.186.0", + "@aws-sdk/util-base64-browser": "3.186.0", + "@aws-sdk/util-base64-node": "3.186.0", + "@aws-sdk/util-body-length-browser": "3.186.0", + "@aws-sdk/util-body-length-node": "3.186.0", + "@aws-sdk/util-defaults-mode-browser": "3.186.0", + "@aws-sdk/util-defaults-mode-node": "3.186.0", + "@aws-sdk/util-user-agent-browser": "3.186.0", + "@aws-sdk/util-user-agent-node": "3.186.0", + "@aws-sdk/util-utf8-browser": "3.186.0", + "@aws-sdk/util-utf8-node": "3.186.0", + "@aws-sdk/util-waiter": "3.186.0", + "tslib": "^2.3.1" + } + }, "@aws-sdk/client-sso": { - "version": "3.112.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.112.0.tgz", - "integrity": "sha512-FwFmiapxuVQiyMdDaBvCpajnJkVWEUHBdO+7rIpzgKHkODEPou5/AwboaGRPEFYULOyYeI0HiDFzpK0G6de+7Q==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.186.0.tgz", + "integrity": "sha512-qwLPomqq+fjvp42izzEpBEtGL2+dIlWH5pUCteV55hTEwHgo+m9LJPIrMWkPeoMBzqbNiu5n6+zihnwYlCIlEA==", "requires": { "@aws-crypto/sha256-browser": "2.0.0", "@aws-crypto/sha256-js": "2.0.0", - "@aws-sdk/config-resolver": "3.110.0", - "@aws-sdk/fetch-http-handler": "3.110.0", - "@aws-sdk/hash-node": "3.110.0", - "@aws-sdk/invalid-dependency": "3.110.0", - "@aws-sdk/middleware-content-length": "3.110.0", - "@aws-sdk/middleware-host-header": "3.110.0", - "@aws-sdk/middleware-logger": "3.110.0", - "@aws-sdk/middleware-recursion-detection": "3.110.0", - "@aws-sdk/middleware-retry": "3.110.0", - "@aws-sdk/middleware-serde": "3.110.0", - "@aws-sdk/middleware-stack": "3.110.0", - "@aws-sdk/middleware-user-agent": "3.110.0", - "@aws-sdk/node-config-provider": "3.110.0", - "@aws-sdk/node-http-handler": "3.110.0", - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/smithy-client": "3.110.0", - "@aws-sdk/types": "3.110.0", - "@aws-sdk/url-parser": "3.110.0", - "@aws-sdk/util-base64-browser": "3.109.0", - "@aws-sdk/util-base64-node": "3.55.0", - "@aws-sdk/util-body-length-browser": "3.55.0", - "@aws-sdk/util-body-length-node": "3.55.0", - "@aws-sdk/util-defaults-mode-browser": "3.110.0", - "@aws-sdk/util-defaults-mode-node": "3.110.0", - "@aws-sdk/util-user-agent-browser": "3.110.0", - "@aws-sdk/util-user-agent-node": "3.110.0", - "@aws-sdk/util-utf8-browser": "3.109.0", - "@aws-sdk/util-utf8-node": "3.109.0", + "@aws-sdk/config-resolver": "3.186.0", + "@aws-sdk/fetch-http-handler": "3.186.0", + "@aws-sdk/hash-node": "3.186.0", + "@aws-sdk/invalid-dependency": "3.186.0", + "@aws-sdk/middleware-content-length": "3.186.0", + "@aws-sdk/middleware-host-header": "3.186.0", + "@aws-sdk/middleware-logger": "3.186.0", + "@aws-sdk/middleware-recursion-detection": "3.186.0", + "@aws-sdk/middleware-retry": "3.186.0", + "@aws-sdk/middleware-serde": "3.186.0", + "@aws-sdk/middleware-stack": "3.186.0", + "@aws-sdk/middleware-user-agent": "3.186.0", + "@aws-sdk/node-config-provider": "3.186.0", + "@aws-sdk/node-http-handler": "3.186.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/smithy-client": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/url-parser": "3.186.0", + "@aws-sdk/util-base64-browser": "3.186.0", + "@aws-sdk/util-base64-node": "3.186.0", + "@aws-sdk/util-body-length-browser": "3.186.0", + "@aws-sdk/util-body-length-node": "3.186.0", + "@aws-sdk/util-defaults-mode-browser": "3.186.0", + "@aws-sdk/util-defaults-mode-node": "3.186.0", + "@aws-sdk/util-user-agent-browser": "3.186.0", + "@aws-sdk/util-user-agent-node": "3.186.0", + "@aws-sdk/util-utf8-browser": "3.186.0", + "@aws-sdk/util-utf8-node": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/client-sts": { - "version": "3.112.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.112.0.tgz", - "integrity": "sha512-hSApRO2wg3jk9VRGM6SCZO3aFP7DKVSUqs6FrvlXlj+JU88ZKObjrGE61cCzXoD89Dh+b9t8A2T6W51Nzriaxw==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.186.0.tgz", + "integrity": "sha512-lyAPI6YmIWWYZHQ9fBZ7QgXjGMTtktL5fk8kOcZ98ja+8Vu0STH1/u837uxqvZta8/k0wijunIL3jWUhjsNRcg==", "requires": { "@aws-crypto/sha256-browser": "2.0.0", "@aws-crypto/sha256-js": "2.0.0", - "@aws-sdk/config-resolver": "3.110.0", - "@aws-sdk/credential-provider-node": "3.112.0", - "@aws-sdk/fetch-http-handler": "3.110.0", - "@aws-sdk/hash-node": "3.110.0", - "@aws-sdk/invalid-dependency": "3.110.0", - "@aws-sdk/middleware-content-length": "3.110.0", - "@aws-sdk/middleware-host-header": "3.110.0", - "@aws-sdk/middleware-logger": "3.110.0", - "@aws-sdk/middleware-recursion-detection": "3.110.0", - "@aws-sdk/middleware-retry": "3.110.0", - "@aws-sdk/middleware-sdk-sts": "3.110.0", - "@aws-sdk/middleware-serde": "3.110.0", - "@aws-sdk/middleware-signing": "3.110.0", - "@aws-sdk/middleware-stack": "3.110.0", - "@aws-sdk/middleware-user-agent": "3.110.0", - "@aws-sdk/node-config-provider": "3.110.0", - "@aws-sdk/node-http-handler": "3.110.0", - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/smithy-client": "3.110.0", - "@aws-sdk/types": "3.110.0", - "@aws-sdk/url-parser": "3.110.0", - "@aws-sdk/util-base64-browser": "3.109.0", - "@aws-sdk/util-base64-node": "3.55.0", - "@aws-sdk/util-body-length-browser": "3.55.0", - "@aws-sdk/util-body-length-node": "3.55.0", - "@aws-sdk/util-defaults-mode-browser": "3.110.0", - "@aws-sdk/util-defaults-mode-node": "3.110.0", - "@aws-sdk/util-user-agent-browser": "3.110.0", - "@aws-sdk/util-user-agent-node": "3.110.0", - "@aws-sdk/util-utf8-browser": "3.109.0", - "@aws-sdk/util-utf8-node": "3.109.0", + "@aws-sdk/config-resolver": "3.186.0", + "@aws-sdk/credential-provider-node": "3.186.0", + "@aws-sdk/fetch-http-handler": "3.186.0", + "@aws-sdk/hash-node": "3.186.0", + "@aws-sdk/invalid-dependency": "3.186.0", + "@aws-sdk/middleware-content-length": "3.186.0", + "@aws-sdk/middleware-host-header": "3.186.0", + "@aws-sdk/middleware-logger": "3.186.0", + "@aws-sdk/middleware-recursion-detection": "3.186.0", + "@aws-sdk/middleware-retry": "3.186.0", + "@aws-sdk/middleware-sdk-sts": "3.186.0", + "@aws-sdk/middleware-serde": "3.186.0", + "@aws-sdk/middleware-signing": "3.186.0", + "@aws-sdk/middleware-stack": "3.186.0", + "@aws-sdk/middleware-user-agent": "3.186.0", + "@aws-sdk/node-config-provider": "3.186.0", + "@aws-sdk/node-http-handler": "3.186.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/smithy-client": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/url-parser": "3.186.0", + "@aws-sdk/util-base64-browser": "3.186.0", + "@aws-sdk/util-base64-node": "3.186.0", + "@aws-sdk/util-body-length-browser": "3.186.0", + "@aws-sdk/util-body-length-node": "3.186.0", + "@aws-sdk/util-defaults-mode-browser": "3.186.0", + "@aws-sdk/util-defaults-mode-node": "3.186.0", + "@aws-sdk/util-user-agent-browser": "3.186.0", + "@aws-sdk/util-user-agent-node": "3.186.0", + "@aws-sdk/util-utf8-browser": "3.186.0", + "@aws-sdk/util-utf8-node": "3.186.0", "entities": "2.2.0", "fast-xml-parser": "3.19.0", "tslib": "^2.3.1" } }, "@aws-sdk/config-resolver": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.110.0.tgz", - "integrity": "sha512-7VvtKy4CL63BAktQ2vgsjhWDSXpkXO5YdiI56LQnHztrvSuJBBaxJ7R1p/k0b2tEUhYKUziAIW8EKE/7EGPR4g==", - "requires": { - "@aws-sdk/signature-v4": "3.110.0", - "@aws-sdk/types": "3.110.0", - "@aws-sdk/util-config-provider": "3.109.0", - "@aws-sdk/util-middleware": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.186.0.tgz", + "integrity": "sha512-l8DR7Q4grEn1fgo2/KvtIfIHJS33HGKPQnht8OPxkl0dMzOJ0jxjOw/tMbrIcPnr2T3Fi7LLcj3dY1Fo1poruQ==", + "requires": { + "@aws-sdk/signature-v4": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/util-config-provider": "3.186.0", + "@aws-sdk/util-middleware": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/credential-provider-env": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.110.0.tgz", - "integrity": "sha512-oFU3IYk/Bl5tdsz1qigtm3I25a9cvXPqlE8VjYjxVDdLujF5zd/4HLbhP4GQWhpEwZmM1ijcSNfLcyywVevTZg==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.186.0.tgz", + "integrity": "sha512-N9LPAqi1lsQWgxzmU4NPvLPnCN5+IQ3Ai1IFf3wM6FFPNoSUd1kIA2c6xaf0BE7j5Kelm0raZOb4LnV3TBAv+g==", "requires": { - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/credential-provider-imds": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.110.0.tgz", - "integrity": "sha512-atl+7/dAB+8fG9XI2fYyCgXKYDbOzot65VAwis+14bOEUCVp7PCJifBEZ/L8GEq564p+Fa2p1IpV0wuQXxqFUQ==", - "requires": { - "@aws-sdk/node-config-provider": "3.110.0", - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/types": "3.110.0", - "@aws-sdk/url-parser": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.186.0.tgz", + "integrity": "sha512-iJeC7KrEgPPAuXjCZ3ExYZrRQvzpSdTZopYgUm5TnNZ8S1NU/4nvv5xVy61JvMj3JQAeG8UDYYgC421Foc8wQw==", + "requires": { + "@aws-sdk/node-config-provider": "3.186.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/url-parser": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/credential-provider-ini": { - "version": "3.112.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.112.0.tgz", - "integrity": "sha512-ebgZ6/jZdTGHQ3zfq/ccmS+7YmLk6yUWHDmh69VK+B1Dd+S1jFwbD9EQ+pYWCp/gEl9F620NSwb6KghRylPWEQ==", - "requires": { - "@aws-sdk/credential-provider-env": "3.110.0", - "@aws-sdk/credential-provider-imds": "3.110.0", - "@aws-sdk/credential-provider-sso": "3.112.0", - "@aws-sdk/credential-provider-web-identity": "3.110.0", - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/shared-ini-file-loader": "3.110.0", - "@aws-sdk/types": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.186.0.tgz", + "integrity": "sha512-ecrFh3MoZhAj5P2k/HXo/hMJQ3sfmvlommzXuZ/D1Bj2yMcyWuBhF1A83Fwd2gtYrWRrllsK3IOMM5Jr8UIVZA==", + "requires": { + "@aws-sdk/credential-provider-env": "3.186.0", + "@aws-sdk/credential-provider-imds": "3.186.0", + "@aws-sdk/credential-provider-sso": "3.186.0", + "@aws-sdk/credential-provider-web-identity": "3.186.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/shared-ini-file-loader": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/credential-provider-node": { - "version": "3.112.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.112.0.tgz", - "integrity": "sha512-7txS7P3BAaU4cksFw/PnoVskVvO8h/TPvOl/BxFtCiUdwA6FRltLvBeMlN08fwUoqgM6z06q8areBdeDqCHOSw==", - "requires": { - "@aws-sdk/credential-provider-env": "3.110.0", - "@aws-sdk/credential-provider-imds": "3.110.0", - "@aws-sdk/credential-provider-ini": "3.112.0", - "@aws-sdk/credential-provider-process": "3.110.0", - "@aws-sdk/credential-provider-sso": "3.112.0", - "@aws-sdk/credential-provider-web-identity": "3.110.0", - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/shared-ini-file-loader": "3.110.0", - "@aws-sdk/types": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.186.0.tgz", + "integrity": "sha512-HIt2XhSRhEvVgRxTveLCzIkd/SzEBQfkQ6xMJhkBtfJw1o3+jeCk+VysXM0idqmXytctL0O3g9cvvTHOsUgxOA==", + "requires": { + "@aws-sdk/credential-provider-env": "3.186.0", + "@aws-sdk/credential-provider-imds": "3.186.0", + "@aws-sdk/credential-provider-ini": "3.186.0", + "@aws-sdk/credential-provider-process": "3.186.0", + "@aws-sdk/credential-provider-sso": "3.186.0", + "@aws-sdk/credential-provider-web-identity": "3.186.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/shared-ini-file-loader": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/credential-provider-process": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.110.0.tgz", - "integrity": "sha512-JJcZePvRTfQHYj/+EEY13yItnZH/e8exlARFUjN0L13UrgHpOJtDQBa+YBHXo6MbTFQh+re25z2kzc+zOYSMNQ==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.186.0.tgz", + "integrity": "sha512-ATRU6gbXvWC1TLnjOEZugC/PBXHBoZgBADid4fDcEQY1vF5e5Ux1kmqkJxyHtV5Wl8sE2uJfwWn+FlpUHRX67g==", "requires": { - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/shared-ini-file-loader": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/shared-ini-file-loader": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/credential-provider-sso": { - "version": "3.112.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.112.0.tgz", - "integrity": "sha512-b6rOrSXbNK3fGyPvNpyF5zdktmAoNOqHCTmFSUcxRxOipyRGb5JACsbjWthIQkpWkpNCT8GFNLEg9spXPFIdLA==", - "requires": { - "@aws-sdk/client-sso": "3.112.0", - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/shared-ini-file-loader": "3.110.0", - "@aws-sdk/types": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.186.0.tgz", + "integrity": "sha512-mJ+IZljgXPx99HCmuLgBVDPLepHrwqnEEC/0wigrLCx6uz3SrAWmGZsNbxSEtb2CFSAaczlTHcU/kIl7XZIyeQ==", + "requires": { + "@aws-sdk/client-sso": "3.186.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/shared-ini-file-loader": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/credential-provider-web-identity": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.110.0.tgz", - "integrity": "sha512-e4e5u7v3fsUFZsMcFMhMy1NdJBQpunYcLwpYlszm3OEICwTTekQ+hVvnVRd134doHvzepE4yp9sAop0Cj+IRVQ==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.186.0.tgz", + "integrity": "sha512-KqzI5eBV72FE+8SuOQAu+r53RXGVHg4AuDJmdXyo7Gc4wS/B9FNElA8jVUjjYgVnf0FSiri+l41VzQ44dCopSA==", "requires": { - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/fetch-http-handler": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.110.0.tgz", - "integrity": "sha512-vk+K4GeCZL2J2rtvKO+T0Q7i3MDpEGZBMg5K2tj9sMcEQwty0BF0aFnP7Eu2l4/Zif2z1mWuUFM2WcZI6DVnbw==", - "requires": { - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/querystring-builder": "3.110.0", - "@aws-sdk/types": "3.110.0", - "@aws-sdk/util-base64-browser": "3.109.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.186.0.tgz", + "integrity": "sha512-k2v4AAHRD76WnLg7arH94EvIclClo/YfuqO7NoQ6/KwOxjRhs4G6TgIsAZ9E0xmqoJoV81Xqy8H8ldfy9F8LEw==", + "requires": { + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/querystring-builder": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/util-base64-browser": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/hash-node": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.110.0.tgz", - "integrity": "sha512-wakl+kP2O8wTGYiQ3InZy+CVfGrIpFfq9fo4zif9PZac0BbUbguUU1dkY34uZiaf+4o2/9MoDYrHU2HYeXKxWw==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.186.0.tgz", + "integrity": "sha512-G3zuK8/3KExDTxqrGqko+opOMLRF0BwcwekV/wm3GKIM/NnLhHblBs2zd/yi7VsEoWmuzibfp6uzxgFpEoJ87w==", "requires": { - "@aws-sdk/types": "3.110.0", - "@aws-sdk/util-buffer-from": "3.55.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/util-buffer-from": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/invalid-dependency": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.110.0.tgz", - "integrity": "sha512-O8J1InmtJkoiUMbQDtxBfOzgigBp9iSVsNXQrhs2qHh3826cJOfE7NGT3u+NMw73Pk5j2cfmOh1+7k/76IqxOg==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.186.0.tgz", + "integrity": "sha512-hjeZKqORhG2DPWYZ776lQ9YO3gjw166vZHZCZU/43kEYaCZHsF4mexHwHzreAY6RfS25cH60Um7dUh1aeVIpkw==", "requires": { - "@aws-sdk/types": "3.110.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/is-array-buffer": { - "version": "3.55.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.55.0.tgz", - "integrity": "sha512-NbiPHVYuPxdqdFd6FxzzN3H1BQn/iWA3ri3Ry7AyLeP/tGs1yzEWMwf8BN8TSMALI0GXT6Sh0GDWy3Ok5xB6DA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.186.0.tgz", + "integrity": "sha512-fObm+P6mjWYzxoFY4y2STHBmSdgKbIAXez0xope563mox62I8I4hhVPUCaDVydXvDpJv8tbedJMk0meJl22+xA==", "requires": { "tslib": "^2.3.1" } }, "@aws-sdk/middleware-content-length": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.110.0.tgz", - "integrity": "sha512-hKU+zdqfAJQg22LXMVu/z35nNIHrVAKpVKPe9+WYVdL/Z7JKUPK7QymqKGOyDuDbzW6OxyulC1zKGEX12zGmdA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.186.0.tgz", + "integrity": "sha512-Ol3c1ks3IK1s+Okc/rHIX7w2WpXofuQdoAEme37gHeml+8FtUlWH/881h62xfMdf+0YZpRuYv/eM7lBmJBPNJw==", "requires": { - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/middleware-host-header": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.110.0.tgz", - "integrity": "sha512-/Cknn1vL2LTlclI0MX2RzmtdPlCJ5palCRXxm/mod1oHwg4oNTKRlUX3LUD+L8g7JuJ4h053Ch9KS/A0vanE5Q==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.186.0.tgz", + "integrity": "sha512-5bTzrRzP2IGwyF3QCyMGtSXpOOud537x32htZf344IvVjrqZF/P8CDfGTkHkeBCIH+wnJxjK+l/QBb3ypAMIqQ==", "requires": { - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/middleware-logger": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.110.0.tgz", - "integrity": "sha512-+pz+a+8dfTnzLj79nHrv3aONMp/N36/erMd+7JXeR84QEosVLrFBUwKA8x5x6O3s1iBbQzRKMYEIuja9xn1BPA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.186.0.tgz", + "integrity": "sha512-/1gGBImQT8xYh80pB7QtyzA799TqXtLZYQUohWAsFReYB7fdh5o+mu2rX0FNzZnrLIh2zBUNs4yaWGsnab4uXg==", "requires": { - "@aws-sdk/types": "3.110.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/middleware-recursion-detection": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.110.0.tgz", - "integrity": "sha512-Wav782zd7bcd1e6txRob76CDOdVOaUQ8HXoywiIm/uFrEEUZvhs2mgnXjVUVCMBUehdNgnL99z420aS13JeL/Q==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.186.0.tgz", + "integrity": "sha512-Za7k26Kovb4LuV5tmC6wcVILDCt0kwztwSlB991xk4vwNTja8kKxSt53WsYG8Q2wSaW6UOIbSoguZVyxbIY07Q==", "requires": { - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/middleware-retry": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.110.0.tgz", - "integrity": "sha512-lwLAQQveCiUqymQvVYjCee6QOXw3Zqbc9yq+pxYdXbs1Cv1XMA6PeJeUU5r5KEVuSceBLyyrnl6E0R1l1om1MQ==", - "requires": { - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/service-error-classification": "3.110.0", - "@aws-sdk/types": "3.110.0", - "@aws-sdk/util-middleware": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.186.0.tgz", + "integrity": "sha512-/VI9emEKhhDzlNv9lQMmkyxx3GjJ8yPfXH3HuAeOgM1wx1BjCTLRYEWnTbQwq7BDzVENdneleCsGAp7yaj80Aw==", + "requires": { + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/service-error-classification": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/util-middleware": "3.186.0", "tslib": "^2.3.1", "uuid": "^8.3.2" } }, "@aws-sdk/middleware-sdk-sts": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.110.0.tgz", - "integrity": "sha512-EjY/YFdlr5jECde6qIrTIyGBbn/34CKcQGKvmvRd31+3qaClIJLAwNuHfcVzWvCUGbAslsfvdbOpLju33pSQRA==", - "requires": { - "@aws-sdk/middleware-signing": "3.110.0", - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/signature-v4": "3.110.0", - "@aws-sdk/types": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.186.0.tgz", + "integrity": "sha512-GDcK0O8rjtnd+XRGnxzheq1V2jk4Sj4HtjrxW/ROyhzLOAOyyxutBt+/zOpDD6Gba3qxc69wE+Cf/qngOkEkDw==", + "requires": { + "@aws-sdk/middleware-signing": "3.186.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/signature-v4": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/middleware-serde": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.110.0.tgz", - "integrity": "sha512-brVupxgEAmcZ9cZvdHEH8zncjvGKIiud8pOe4fiimp5NpHmjBLew4jUbnOKNZNAjaidcKUtz//cxtutD6yXEww==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.186.0.tgz", + "integrity": "sha512-6FEAz70RNf18fKL5O7CepPSwTKJEIoyG9zU6p17GzKMgPeFsxS5xO94Hcq5tV2/CqeHliebjqhKY7yi+Pgok7g==", "requires": { - "@aws-sdk/types": "3.110.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/middleware-signing": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.110.0.tgz", - "integrity": "sha512-y6ZKrGYfgDlFMzWhZmoq5J1UctBgZOUvMmnU9sSeZ020IlEPiOxFMvR0Zu6TcYThp8uy3P0wyjQtGYeTl9Z/kA==", - "requires": { - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/signature-v4": "3.110.0", - "@aws-sdk/types": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.186.0.tgz", + "integrity": "sha512-riCJYG/LlF/rkgVbHkr4xJscc0/sECzDivzTaUmfb9kJhAwGxCyNqnTvg0q6UO00kxSdEB9zNZI2/iJYVBijBQ==", + "requires": { + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/signature-v4": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/util-middleware": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/middleware-stack": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.110.0.tgz", - "integrity": "sha512-iaLHw6ctOuGa9UxNueU01Xes+15dR+mqioRpUOUZ9Zx+vhXVpD7C8lnNqhRnYeFXs10/rNIzASgsIrAHTlnlIQ==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.186.0.tgz", + "integrity": "sha512-fENMoo0pW7UBrbuycPf+3WZ+fcUgP9PnQ0jcOK3WWZlZ9d2ewh4HNxLh4EE3NkNYj4VIUFXtTUuVNHlG8trXjQ==", "requires": { "tslib": "^2.3.1" } }, "@aws-sdk/middleware-user-agent": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.110.0.tgz", - "integrity": "sha512-Y6FgiZr99DilYq6AjeaaWcNwVlSQpNGKrILzvV4Tmz03OaBIspe4KL+8EZ2YA/sAu5Lpw80vItdezqDOwGAlnQ==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.186.0.tgz", + "integrity": "sha512-fb+F2PF9DLKOVMgmhkr+ltN8ZhNJavTla9aqmbd01846OLEaN1n5xEnV7p8q5+EznVBWDF38Oz9Ae5BMt3Hs7w==", "requires": { - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/node-config-provider": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.110.0.tgz", - "integrity": "sha512-46p4dCPGYctuybTQTwLpjenA1QFHeyJw/OyggGbtUJUy+833+ldnAwcPVML2aXJKUKv3APGI8vq1kaloyNku3Q==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.186.0.tgz", + "integrity": "sha512-De93mgmtuUUeoiKXU8pVHXWKPBfJQlS/lh1k2H9T2Pd9Tzi0l7p5ttddx4BsEx4gk+Pc5flNz+DeptiSjZpa4A==", "requires": { - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/shared-ini-file-loader": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/shared-ini-file-loader": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/node-http-handler": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.110.0.tgz", - "integrity": "sha512-/rP+hY516DpP8fZhwFW5xM/ElH0w6lxw/15VvZCoY5EnOLAF5XIsJdzscWPSEW2FHCylBM4SNrKhGar14BDXhA==", - "requires": { - "@aws-sdk/abort-controller": "3.110.0", - "@aws-sdk/protocol-http": "3.110.0", - "@aws-sdk/querystring-builder": "3.110.0", - "@aws-sdk/types": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.186.0.tgz", + "integrity": "sha512-CbkbDuPZT9UNJ4dAZJWB3BV+Z65wFy7OduqGkzNNrKq6ZYMUfehthhUOTk8vU6RMe/0FkN+J0fFXlBx/bs/cHw==", + "requires": { + "@aws-sdk/abort-controller": "3.186.0", + "@aws-sdk/protocol-http": "3.186.0", + "@aws-sdk/querystring-builder": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/property-provider": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.110.0.tgz", - "integrity": "sha512-7NkpmYeOkK3mhWBNU+/zSDqwzeaSPH1qrq4L//WV7WS/weYyE/jusQeZoOxVsuZQnQEXHt5O2hKVeUwShl12xA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.186.0.tgz", + "integrity": "sha512-nWKqt36UW3xV23RlHUmat+yevw9up+T+953nfjcmCBKtgWlCWu/aUzewTRhKj3VRscbN+Wer95SBw9Lr/MMOlQ==", "requires": { - "@aws-sdk/types": "3.110.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/protocol-http": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.110.0.tgz", - "integrity": "sha512-qdi2gCbJiyPyLn+afebPNp/5nVCRh1X7t7IRIFl3FHVEC+o54u/ojay/MLZ4M/+X9Fa4Zxsb0Wpp3T0xAHVDBg==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.186.0.tgz", + "integrity": "sha512-l/KYr/UBDUU5ginqTgHtFfHR3X6ljf/1J1ThIiUg3C3kVC/Zwztm7BEOw8hHRWnWQGU/jYasGYcrcPLdQqFZyQ==", "requires": { - "@aws-sdk/types": "3.110.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/querystring-builder": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.110.0.tgz", - "integrity": "sha512-7V3CDXj519izmbBn9ZE68ymASwGriA+Aq+cb/yHSVtffnvXjPtvONNw7G/5iVblisGLSCUe2hSvpYtcaXozbHw==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.186.0.tgz", + "integrity": "sha512-mweCpuLufImxfq/rRBTEpjGuB4xhQvbokA+otjnUxlPdIobytLqEs7pCGQfLzQ7+1ZMo8LBXt70RH4A2nSX/JQ==", "requires": { - "@aws-sdk/types": "3.110.0", - "@aws-sdk/util-uri-escape": "3.55.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/util-uri-escape": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/querystring-parser": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.110.0.tgz", - "integrity": "sha512-//pJHH7hrhdDMZGBPKXKymmC/tJM7gFT0w/qbu/yd3Wm4W2fMB+8gkmj6EZctx7jrsWlfRQuvFejKqEfapur/g==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.186.0.tgz", + "integrity": "sha512-0iYfEloghzPVXJjmnzHamNx1F1jIiTW9Svy5ZF9LVqyr/uHZcQuiWYsuhWloBMLs8mfWarkZM02WfxZ8buAuhg==", "requires": { - "@aws-sdk/types": "3.110.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/service-error-classification": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.110.0.tgz", - "integrity": "sha512-ccgCE0pU/4RmXR6CP3fLAdhPAve7bK/yXBbGzpSHGAQOXqNxYzOsAvQ30Jg6X+qjLHsI/HR2pLIE65z4k6tynw==" + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.186.0.tgz", + "integrity": "sha512-DRl3ORk4tF+jmH5uvftlfaq0IeKKpt0UPAOAFQ/JFWe+TjOcQd/K+VC0iiIG97YFp3aeFmH1JbEgsNxd+8fdxw==" }, "@aws-sdk/shared-ini-file-loader": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.110.0.tgz", - "integrity": "sha512-E1ERoqEoG206XNBYWCKLgHkzCbTxdpDEGbsLET2DnvjFsT0s9p2dPvVux3bYl7JVAhyGduE+qcqWk7MzhFCBNQ==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.186.0.tgz", + "integrity": "sha512-2FZqxmICtwN9CYid4dwfJSz/gGFHyStFQ3HCOQ8DsJUf2yREMSBsVmKqsyWgOrYcQ98gPcD5GIa7QO5yl3XF6A==", "requires": { + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/signature-v4": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.110.0.tgz", - "integrity": "sha512-utxxdllOnmQDhbpipnFAbuQ4c2pwefZ+2hi48jKvQRULQ2PO4nxLmdZm6B0FXaTijbKsyO7GrMik+EZ6mi3ARQ==", - "requires": { - "@aws-sdk/is-array-buffer": "3.55.0", - "@aws-sdk/types": "3.110.0", - "@aws-sdk/util-hex-encoding": "3.109.0", - "@aws-sdk/util-middleware": "3.110.0", - "@aws-sdk/util-uri-escape": "3.55.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.186.0.tgz", + "integrity": "sha512-18i96P5c4suMqwSNhnEOqhq4doqqyjH4fn0YV3F8TkekHPIWP4mtIJ0PWAN4eievqdtcKgD/GqVO6FaJG9texw==", + "requires": { + "@aws-sdk/is-array-buffer": "3.186.0", + "@aws-sdk/types": "3.186.0", + "@aws-sdk/util-hex-encoding": "3.186.0", + "@aws-sdk/util-middleware": "3.186.0", + "@aws-sdk/util-uri-escape": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/smithy-client": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.110.0.tgz", - "integrity": "sha512-gNLYrmdAe/1hVF2Nv2LF4OkL1A0a1o708pEMZHzql9xP164omRDaLrGDhz9tH7tsJEgLz+Bf4E8nTuISeDwvGg==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.186.0.tgz", + "integrity": "sha512-rdAxSFGSnrSprVJ6i1BXi65r4X14cuya6fYe8dSdgmFSa+U2ZevT97lb3tSINCUxBGeMXhENIzbVGkRZuMh+DQ==", "requires": { - "@aws-sdk/middleware-stack": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/middleware-stack": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/types": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.110.0.tgz", - "integrity": "sha512-dLVoqODU3laaqNFPyN1QLtlQnwX4gNPMXptEBIt/iJpuZf66IYJe6WCzVZGt4Zfa1CnUmrlA428AzdcA/KCr2A==" + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.186.0.tgz", + "integrity": "sha512-NatmSU37U+XauMFJCdFI6nougC20JUFZar+ump5wVv0i54H+2Refg1YbFDxSs0FY28TSB9jfhWIpfFBmXgL5MQ==" }, "@aws-sdk/url-parser": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.110.0.tgz", - "integrity": "sha512-tILFB8/Q73yzgO0dErJNnELmmBszd0E6FucwAnG3hfDefjqCBe09Q/1yhu2aARXyRmZa4AKp0sWcdwIWHc8dnA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.186.0.tgz", + "integrity": "sha512-jfdJkKqJZp8qjjwEjIGDqbqTuajBsddw02f86WiL8bPqD8W13/hdqbG4Fpwc+Bm6GwR6/4MY6xWXFnk8jDUKeA==", "requires": { - "@aws-sdk/querystring-parser": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/querystring-parser": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/util-base64-browser": { - "version": "3.109.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64-browser/-/util-base64-browser-3.109.0.tgz", - "integrity": "sha512-lAZ6fyDGiRLaIsKT9qh7P9FGuNyZ4gAbr1YOSQk/5mHtaTuUvxlPptZuInNM/0MPQm6lpcot00D8IWTucn4PbA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64-browser/-/util-base64-browser-3.186.0.tgz", + "integrity": "sha512-TpQL8opoFfzTwUDxKeon/vuc83kGXpYqjl6hR8WzmHoQgmFfdFlV+0KXZOohra1001OP3FhqvMqaYbO8p9vXVQ==", "requires": { "tslib": "^2.3.1" } }, "@aws-sdk/util-base64-node": { - "version": "3.55.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64-node/-/util-base64-node-3.55.0.tgz", - "integrity": "sha512-UQ/ZuNoAc8CFMpSiRYmevaTsuRKzLwulZTnM8LNlIt9Wx1tpNvqp80cfvVj7yySKROtEi20wq29h31dZf1eYNQ==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64-node/-/util-base64-node-3.186.0.tgz", + "integrity": "sha512-wH5Y/EQNBfGS4VkkmiMyZXU+Ak6VCoFM1GKWopV+sj03zR2D4FHexi4SxWwEBMpZCd6foMtihhbNBuPA5fnh6w==", "requires": { - "@aws-sdk/util-buffer-from": "3.55.0", + "@aws-sdk/util-buffer-from": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/util-body-length-browser": { - "version": "3.55.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.55.0.tgz", - "integrity": "sha512-Ei2OCzXQw5N6ZkTMZbamUzc1z+z1R1Ja5tMEagz5BxuX4vWdBObT+uGlSzL8yvTbjoPjnxWA2aXyEqaUP3JS8Q==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.186.0.tgz", + "integrity": "sha512-zKtjkI/dkj9oGkjo+7fIz+I9KuHrVt1ROAeL4OmDESS8UZi3/O8uMDFMuCp8jft6H+WFuYH6qRVWAVwXMiasXw==", "requires": { "tslib": "^2.3.1" } }, "@aws-sdk/util-body-length-node": { - "version": "3.55.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.55.0.tgz", - "integrity": "sha512-lU1d4I+9wJwydduXs0SxSfd+mHKjxeyd39VwOv6i2KSwWkPbji9UQqpflKLKw+r45jL7+xU/zfeTUg5Tt/3Gew==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.186.0.tgz", + "integrity": "sha512-U7Ii8u8Wvu9EnBWKKeuwkdrWto3c0j7LG677Spe6vtwWkvY70n9WGfiKHTgBpVeLNv8jvfcx5+H0UOPQK1o9SQ==", "requires": { "tslib": "^2.3.1" } }, "@aws-sdk/util-buffer-from": { - "version": "3.55.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.55.0.tgz", - "integrity": "sha512-uVzKG1UgvnV7XX2FPTylBujYMKBPBaq/qFBxfl0LVNfrty7YjpfieQxAe6yRLD+T0Kir/WDQwGvYC+tOYG3IGA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.186.0.tgz", + "integrity": "sha512-be2GCk2lsLWg/2V5Y+S4/9pOMXhOQo4DR4dIqBdR2R+jrMMHN9Xsr5QrkT6chcqLaJ/SBlwiAEEi3StMRmCOXA==", "requires": { - "@aws-sdk/is-array-buffer": "3.55.0", + "@aws-sdk/is-array-buffer": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/util-config-provider": { - "version": "3.109.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.109.0.tgz", - "integrity": "sha512-GrAZl/aBv0A28LkyNyq8SPJ5fmViCwz80fWLMeWx/6q5AbivuILogjlWwEZSvZ9zrlHOcFC0+AnCa5pQrjaslw==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.186.0.tgz", + "integrity": "sha512-71Qwu/PN02XsRLApyxG0EUy/NxWh/CXxtl2C7qY14t+KTiRapwbDkdJ1cMsqYqghYP4BwJoj1M+EFMQSSlkZQQ==", "requires": { "tslib": "^2.3.1" } }, "@aws-sdk/util-defaults-mode-browser": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.110.0.tgz", - "integrity": "sha512-Y2dcOOD20S3bv/IjUqpdKIiDt6995SXNG5Pu/LeSdXNyLCOIm9rX4gHTxl9fC1KK5M/gR9fGJ362f67WwqEEqw==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.186.0.tgz", + "integrity": "sha512-U8GOfIdQ0dZ7RRVpPynGteAHx4URtEh+JfWHHVfS6xLPthPHWTbyRhkQX++K/F8Jk+T5U8Anrrqlea4TlcO2DA==", "requires": { - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/types": "3.186.0", "bowser": "^2.11.0", "tslib": "^2.3.1" } }, "@aws-sdk/util-defaults-mode-node": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.110.0.tgz", - "integrity": "sha512-Cr3Z5nyrw1KowjbW76xp8hkT/zJtYjAVZ9PS4l84KxIicbVvDOBpxG3yNddkuQcavmlH6G4wH9uM5DcnpKDncg==", - "requires": { - "@aws-sdk/config-resolver": "3.110.0", - "@aws-sdk/credential-provider-imds": "3.110.0", - "@aws-sdk/node-config-provider": "3.110.0", - "@aws-sdk/property-provider": "3.110.0", - "@aws-sdk/types": "3.110.0", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.186.0.tgz", + "integrity": "sha512-N6O5bpwCiE4z8y7SPHd7KYlszmNOYREa+mMgtOIXRU3VXSEHVKVWTZsHKvNTTHpW0qMqtgIvjvXCo3vsch5l3A==", + "requires": { + "@aws-sdk/config-resolver": "3.186.0", + "@aws-sdk/credential-provider-imds": "3.186.0", + "@aws-sdk/node-config-provider": "3.186.0", + "@aws-sdk/property-provider": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/util-hex-encoding": { - "version": "3.109.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.109.0.tgz", - "integrity": "sha512-s8CgTNrn3cLkrdiohfxLuOYPCanzvHn/aH5RW6DaMoeQiG5Hl9QUiP/WtdQ9QQx3xvpQFpmvxIaSBwSgFNLQxA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.186.0.tgz", + "integrity": "sha512-UL9rdgIZz1E/jpAfaKH8QgUxNK9VP5JPgoR0bSiaefMjnsoBh0x/VVMsfUyziOoJCMLebhJzFowtwrSKEGsxNg==", "requires": { "tslib": "^2.3.1" } }, "@aws-sdk/util-locate-window": { - "version": "3.55.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.55.0.tgz", - "integrity": "sha512-0sPmK2JaJE2BbTcnvybzob/VrFKCXKfN4CUKcvn0yGg/me7Bz+vtzQRB3Xp+YSx+7OtWxzv63wsvHoAnXvgxgg==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.186.0.tgz", + "integrity": "sha512-fmQLkH16ga6c5fWsA+kBYklQJjlPlcc8uayTR4avi5g3Nxqm6wPpyUwo5CppwjwWMeS+NXG0HgITtkkGntcRNg==", "requires": { "tslib": "^2.3.1" } }, "@aws-sdk/util-middleware": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.110.0.tgz", - "integrity": "sha512-PTVWrI5fA9d5hHJs6RzX2dIS2jRQ3uW073Fm0BePpQeDdZrEk+S5KNwRhUtpN6sdSV45vm6S9rrjZUG51qwGmA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.186.0.tgz", + "integrity": "sha512-fddwDgXtnHyL9mEZ4s1tBBsKnVQHqTUmFbZKUUKPrg9CxOh0Y/zZxEa5Olg/8dS/LzM1tvg0ATkcyd4/kEHIhg==", "requires": { "tslib": "^2.3.1" } }, "@aws-sdk/util-uri-escape": { - "version": "3.55.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.55.0.tgz", - "integrity": "sha512-mmdDLUpFCN2nkfwlLdOM54lTD528GiGSPN1qb8XtGLgZsJUmg3uJSFIN2lPeSbEwJB3NFjVas/rnQC48i7mV8w==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.186.0.tgz", + "integrity": "sha512-imtOrJFpIZAipAg8VmRqYwv1G/x4xzyoxOJ48ZSn1/ZGnKEEnB6n6E9gwYRebi4mlRuMSVeZwCPLq0ey5hReeQ==", "requires": { "tslib": "^2.3.1" } }, "@aws-sdk/util-user-agent-browser": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.110.0.tgz", - "integrity": "sha512-rNdhmHDMV5dNJctqlBWimkZLJRB+x03DB+61pm+SKSFk6gPIVIvc1WNXqDFphkiswT4vA13ZUkGHzt+N4+noQQ==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.186.0.tgz", + "integrity": "sha512-fbRcTTutMk4YXY3A2LePI4jWSIeHOT8DaYavpc/9Xshz/WH9RTGMmokeVOcClRNBeDSi5cELPJJ7gx6SFD3ZlQ==", "requires": { - "@aws-sdk/types": "3.110.0", + "@aws-sdk/types": "3.186.0", "bowser": "^2.11.0", "tslib": "^2.3.1" } }, "@aws-sdk/util-user-agent-node": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.110.0.tgz", - "integrity": "sha512-OQ915TPCCBwZWz5Np8zkNWn7U6KvrTZfFoCOy/VIemK3dUqmnBZ7HqGpuZx8SwJ2R9JE1x+j0niYSJ5fWJZZKA==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.186.0.tgz", + "integrity": "sha512-oWZR7hN6NtOgnT6fUvHaafgbipQc2xJCRB93XHiF9aZGptGNLJzznIOP7uURdn0bTnF73ejbUXWLQIm8/6ue6w==", "requires": { - "@aws-sdk/node-config-provider": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/node-config-provider": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/util-utf8-browser": { - "version": "3.109.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.109.0.tgz", - "integrity": "sha512-FmcGSz0v7Bqpl1SE8G1Gc0CtDpug+rvqNCG/szn86JApD/f5x8oByjbEiAyTU2ZH2VevUntx6EW68ulHyH+x+w==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.186.0.tgz", + "integrity": "sha512-n+IdFYF/4qT2WxhMOCeig8LndDggaYHw3BJJtfIBZRiS16lgwcGYvOUmhCkn0aSlG1f/eyg9YZHQG0iz9eLdHQ==", "requires": { "tslib": "^2.3.1" } }, "@aws-sdk/util-utf8-node": { - "version": "3.109.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-node/-/util-utf8-node-3.109.0.tgz", - "integrity": "sha512-Ti/ZBdvz2eSTElsucjzNmzpyg2MwfD1rXmxD0hZuIF8bPON/0+sZYnWd5CbDw9kgmhy28dmKue086tbZ1G0iLQ==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-node/-/util-utf8-node-3.186.0.tgz", + "integrity": "sha512-7qlE0dOVdjuRbZTb7HFywnHHCrsN7AeQiTnsWT63mjXGDbPeUWQQw3TrdI20um3cxZXnKoeudGq8K6zbXyQ4iA==", "requires": { - "@aws-sdk/util-buffer-from": "3.55.0", + "@aws-sdk/util-buffer-from": "3.186.0", "tslib": "^2.3.1" } }, "@aws-sdk/util-waiter": { - "version": "3.110.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-waiter/-/util-waiter-3.110.0.tgz", - "integrity": "sha512-8dE6W6XYfjk1gx/aeb8NeLfMMLkLFhlV1lmKpFSBJhY8msajU8aQahTuykq5JW8QT/wCGbqbu7dH35SdX7kO+A==", + "version": "3.186.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-waiter/-/util-waiter-3.186.0.tgz", + "integrity": "sha512-oSm45VadBBWC/K2W1mrRNzm9RzbXt6VopBQ5iTDU7B3qIXlyAG9k1JqOvmYIdYq1oOgjM3Hv2+9sngi3+MZs1A==", "requires": { - "@aws-sdk/abort-controller": "3.110.0", - "@aws-sdk/types": "3.110.0", + "@aws-sdk/abort-controller": "3.186.0", + "@aws-sdk/types": "3.186.0", "tslib": "^2.3.1" } }, "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dev": true, "requires": { - "@babel/highlight": "^7.16.7" + "@babel/highlight": "^7.18.6" } }, "@babel/compat-data": { - "version": "7.18.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.5.tgz", - "integrity": "sha512-BxhE40PVCBxVEJsSBhB6UWyAuqJRxGsAw8BdHMJ3AKGydcwuWW4kOO3HmqBQAdcq/OP+/DlTVxLvsCzRTnZuGg==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.4.tgz", + "integrity": "sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==", "dev": true }, "@babel/core": { - "version": "7.18.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.5.tgz", - "integrity": "sha512-MGY8vg3DxMnctw0LdvSEojOsumc70g0t18gNyUdAZqB1Rpd1Bqo/svHGvt+UJ6JcGX+DIekGFDxxIWofBxLCnQ==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", + "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", "dev": true, "requires": { "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.18.2", - "@babel/helper-compilation-targets": "^7.18.2", - "@babel/helper-module-transforms": "^7.18.0", - "@babel/helpers": "^7.18.2", - "@babel/parser": "^7.18.5", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.5", - "@babel/types": "^7.18.4", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helpers": "^7.19.0", + "@babel/parser": "^7.19.3", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.3", + "@babel/types": "^7.19.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -6158,23 +6399,23 @@ } }, "@babel/generator": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.2.tgz", - "integrity": "sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==", + "version": "7.19.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.5.tgz", + "integrity": "sha512-DxbNz9Lz4aMZ99qPpO1raTbcrI1ZeYh+9NR9qhfkQIbFtVEqotHojEBxHzmxhVONkGt6VyrqVQcgpefMy9pqcg==", "dev": true, "requires": { - "@babel/types": "^7.18.2", - "@jridgewell/gen-mapping": "^0.3.0", + "@babel/types": "^7.19.4", + "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, "dependencies": { "@jridgewell/gen-mapping": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", - "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "dev": true, "requires": { - "@jridgewell/set-array": "^1.0.0", + "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" } @@ -6182,121 +6423,127 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.2.tgz", - "integrity": "sha512-s1jnPotJS9uQnzFtiZVBUxe67CuBa679oWFHpxYYnTpRL/1ffhyX44R9uYiXoa/pLXcY9H2moJta0iaanlk/rQ==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", + "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", "dev": true, "requires": { - "@babel/compat-data": "^7.17.10", - "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.20.2", + "@babel/compat-data": "^7.19.3", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", "semver": "^6.3.0" } }, "@babel/helper-environment-visitor": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.2.tgz", - "integrity": "sha512-14GQKWkX9oJzPiQQ7/J36FTXcD4kSp8egKjO9nINlSKiHITRA9q/R74qu8S9xlc/b/yjsJItQUeeh3xnGN0voQ==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", "dev": true }, "@babel/helper-function-name": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", - "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "dev": true, "requires": { - "@babel/template": "^7.16.7", - "@babel/types": "^7.17.0" + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" } }, "@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.18.6" } }, "@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.18.6" } }, "@babel/helper-module-transforms": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.0.tgz", - "integrity": "sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", + "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.17.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.0", - "@babel/types": "^7.18.0" + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.18.6", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" } }, "@babel/helper-plugin-utils": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz", - "integrity": "sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", + "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", "dev": true }, "@babel/helper-simple-access": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz", - "integrity": "sha512-7LIrjYzndorDY88MycupkpQLKS1AFfsVRm2k/9PtKScSy5tZq0McZTj+DiMRynboZfIqOKvo03pmhTaUgiD6fQ==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", + "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", "dev": true, "requires": { - "@babel/types": "^7.18.2" + "@babel/types": "^7.19.4" } }, "@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.18.6" } }, + "@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true + }, "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true }, "@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", "dev": true }, "@babel/helpers": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.2.tgz", - "integrity": "sha512-j+d+u5xT5utcQSzrh9p+PaJX94h++KN+ng9b9WEJq7pkUPAd61FGqhjuUEdfknb3E/uDBb7ruwEeKkIxNJPIrg==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.4.tgz", + "integrity": "sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==", "dev": true, "requires": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.2", - "@babel/types": "^7.18.2" + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.4", + "@babel/types": "^7.19.4" } }, "@babel/highlight": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz", - "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -6360,9 +6607,9 @@ } }, "@babel/parser": { - "version": "7.18.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.5.tgz", - "integrity": "sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.4.tgz", + "integrity": "sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -6474,50 +6721,51 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.12.tgz", - "integrity": "sha512-TYY0SXFiO31YXtNg3HtFwNJHjLsAyIIhAhNWkQ5whPPS7HWUFlg9z0Ta4qAQNjQbP1wsSt/oKkmZ/4/WWdMUpw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", + "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dev": true, "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" } }, "@babel/traverse": { - "version": "7.18.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.5.tgz", - "integrity": "sha512-aKXj1KT66sBj0vVzk6rEeAO6Z9aiiQ68wfDgge3nHhA/my6xMM/7HGQUNumKZaoa2qUPQ5whJG9aAifsxUKfLA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.18.2", - "@babel/helper-environment-visitor": "^7.18.2", - "@babel/helper-function-name": "^7.17.9", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.18.5", - "@babel/types": "^7.18.4", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.4.tgz", + "integrity": "sha512-w3K1i+V5u2aJUOXBFFC5pveFLmtq1s3qcdDNC2qRI6WPBQIDaKFqXxDEqDO/h1dQ3HjsZoZMyIy6jGLq0xtw+g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.4", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.19.4", + "@babel/types": "^7.19.4", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.4.tgz", - "integrity": "sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" } }, @@ -6769,31 +7017,31 @@ } }, "@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true }, "@jridgewell/set-array": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", - "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true }, "@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", - "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "version": "0.3.16", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.16.tgz", + "integrity": "sha512-LCQ+NeThyJ4k1W2d+vIKdxuSt9R3pQSZ4P92m7EakaYuXcVWbHuT5bjNcqLd4Rdgi6xYWYDvBJZJLZSLanjDcA==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "@sinonjs/commons": { @@ -6877,9 +7125,9 @@ } }, "@types/babel__traverse": { - "version": "7.17.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.17.1.tgz", - "integrity": "sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", + "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -6968,9 +7216,9 @@ "dev": true }, "acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "dev": true }, "acorn-globals": { @@ -7018,14 +7266,12 @@ "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -7062,18 +7308,18 @@ "dev": true }, "aws-cdk": { - "version": "2.28.1", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.28.1.tgz", - "integrity": "sha512-0Kklrj9HHg6HkYZQuTnJ+2+RLTqlVcxECUmlDudBxbPxJQcc5pEA9stfo8wwh1CtoWYuF4A4moP7B19Yvw4nJg==", + "version": "2.45.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.45.0.tgz", + "integrity": "sha512-AIug6Ugvtd3I0+U3gTNZtJVDhOgpGpxwWMoOQUlX6xKGwDgQxWrWdq2QWe7ZyKgCRnY9SM90fa+Yxbx+VYk9Bw==", "dev": true, "requires": { "fsevents": "2.3.2" } }, "aws-cdk-lib": { - "version": "2.28.1", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.28.1.tgz", - "integrity": "sha512-YFJKvv3lU7HUfud+4uyQT5tNyJhidBB1ftBmc6NzML+UXAuelPZICJLdGuoE/dA6dU3mB/sT15S+fTzATTwvfg==", + "version": "2.45.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.45.0.tgz", + "integrity": "sha512-oEeZZF8xjub9KYAB7n01A60wwQXSzNapmiih3t5uf9aEvlvqT+0as8/WrPdNIeAaf9Lhb0WQXdZ2o2DlsFHbAg==", "requires": { "@balena/dockerignore": "^1.0.2", "case": "1.6.3", @@ -7291,16 +7537,15 @@ "dev": true }, "browserslist": { - "version": "4.20.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.4.tgz", - "integrity": "sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==", + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001349", - "electron-to-chromium": "^1.4.147", - "escalade": "^3.1.1", - "node-releases": "^2.0.5", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" } }, "bs-logger": { @@ -7339,9 +7584,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001355", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001355.tgz", - "integrity": "sha512-Sd6pjJHF27LzCB7pT7qs+kuX2ndurzCzkpJl6Qct7LPSZ9jn0bkOA8mdgMgmqnQAWLVOOGjLpc+66V57eLtb1g==", + "version": "1.0.30001418", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz", + "integrity": "sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==", "dev": true }, "cdk-common": { @@ -7351,6 +7596,13 @@ "typescript": "^3.9.10" } }, + "cdk2-python-library-layer": { + "version": "git+ssh://git@github.com/kikuomax/cdk-python-library-layer.git#d1133709d2e9e3833acc4ab097a641568e3ede2b", + "from": "cdk2-python-library-layer@github:kikuomax/cdk-python-library-layer#v0.1.0-v2", + "requires": { + "fs-extra": "^10.0.0" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -7368,9 +7620,9 @@ "dev": true }, "ci-info": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", - "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", + "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==", "dev": true }, "cjs-module-lexer": { @@ -7380,13 +7632,12 @@ "dev": true }, "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "requires": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, @@ -7406,7 +7657,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -7414,8 +7664,7 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "combined-stream": { "version": "1.0.8", @@ -7433,18 +7682,15 @@ "dev": true }, "constructs": { - "version": "10.1.42", - "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.1.42.tgz", - "integrity": "sha512-5AELa/PFtZG+WTjn9HoXhqsDZYV6l3J7Li9xw6vREYVMasF8cnVbTZvA4crP1gIyKtBAxAlnZCmzmCbicnH6eg==" + "version": "10.1.128", + "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.1.128.tgz", + "integrity": "sha512-X2QvdedBwVRAqwU5I2Hv+xcB7xumYO/Z+PNozubDIRgtetWRWIOOkZCRXeERm7xfCjLVyQdAPHDKVuoVuGRoHA==" }, "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true }, "create-require": { "version": "1.1.1", @@ -7507,9 +7753,9 @@ } }, "decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.1.tgz", + "integrity": "sha512-F29o+vci4DodHYT9UrR5IEbfBw9pE5eSapIJdTqXK5+6hq+t8VRxwQyKlW2i+KDKFkkJQRvFyI/QXD83h8LyQw==", "dev": true }, "dedent": { @@ -7572,9 +7818,9 @@ } }, "electron-to-chromium": { - "version": "1.4.158", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.158.tgz", - "integrity": "sha512-gppO3/+Y6sP432HtvwvuU8S+YYYLH4PmAYvQwqUtt9HDOmEsBwQfLnK9T8+1NIKwAS1BEygIjTaATC4H5EzvxQ==", + "version": "1.4.276", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.276.tgz", + "integrity": "sha512-EpuHPqu8YhonqLBXHoU6hDJCD98FCe6KDoet3/gY1qsQ6usjJoHqBH2YIVs8FXaAtHwVL8Uqa/fsYao/vq9VWQ==", "dev": true }, "emittery": { @@ -7586,8 +7832,7 @@ "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "entities": { "version": "2.2.0", @@ -7606,8 +7851,7 @@ "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "escape-string-regexp": { "version": "2.0.0", @@ -7699,9 +7943,9 @@ "integrity": "sha512-4pXwmBplsCPv8FOY1WRakF970TjNGnGnfbOnLqjlYvMiF1SR3yOHyxMR/YCXpPTOspNF5gwudqktIP4VsWkvBg==" }, "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, "requires": { "bser": "2.1.1" @@ -7737,6 +7981,16 @@ "mime-types": "^2.1.12" } }, + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -7765,8 +8019,7 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-package-type": { "version": "0.1.0", @@ -7803,8 +8056,7 @@ "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "has": { "version": "1.0.3", @@ -7911,9 +8163,9 @@ "dev": true }, "is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", "dev": true, "requires": { "has": "^1.0.3" @@ -7922,8 +8174,7 @@ "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "is-generator-fn": { "version": "2.1.0", @@ -7968,9 +8219,9 @@ "dev": true }, "istanbul-lib-instrument": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", - "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "requires": { "@babel/core": "^7.12.3", @@ -8003,9 +8254,9 @@ } }, "istanbul-reports": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", - "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -8079,6 +8330,34 @@ "jest-validate": "^27.5.1", "prompts": "^2.0.1", "yargs": "^16.2.0" + }, + "dependencies": { + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + } } }, "jest-config": { @@ -8419,9 +8698,9 @@ }, "dependencies": { "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -8571,6 +8850,15 @@ "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", "dev": true }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -8718,9 +9006,9 @@ "dev": true }, "node-releases": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz", - "integrity": "sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", "dev": true }, "normalize-path": { @@ -8739,9 +9027,9 @@ } }, "nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", + "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", "dev": true }, "once": { @@ -8905,9 +9193,9 @@ } }, "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true }, "punycode": { @@ -8916,6 +9204,12 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -8925,16 +9219,21 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "dev": true }, "resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "dev": true, "requires": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -8969,12 +9268,6 @@ "glob": "^7.1.3" } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -9072,7 +9365,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -9083,7 +9375,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "requires": { "ansi-regex": "^5.0.1" } @@ -9116,9 +9407,9 @@ } }, "supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", "dev": true, "requires": { "has-flag": "^4.0.0", @@ -9186,14 +9477,23 @@ } }, "tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", + "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", "dev": true, "requires": { "psl": "^1.1.33", "punycode": "^2.1.1", - "universalify": "^0.1.2" + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "dependencies": { + "universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true + } } }, "tr46": { @@ -9222,9 +9522,9 @@ }, "dependencies": { "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -9233,9 +9533,9 @@ } }, "ts-node": { - "version": "10.8.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.1.tgz", - "integrity": "sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", @@ -9303,10 +9603,29 @@ "dev": true }, "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + }, + "update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } }, "uuid": { "version": "8.3.2", @@ -9416,7 +9735,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -9442,9 +9760,9 @@ } }, "ws": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz", - "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==", + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", "dev": true, "requires": {} }, @@ -9463,8 +9781,7 @@ "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" }, "yallist": { "version": "4.0.0", @@ -9473,18 +9790,24 @@ "dev": true }, "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz", + "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==", "requires": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.0.0" + }, + "dependencies": { + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + } } }, "yargs-parser": { diff --git a/cdk-ops/package.json b/cdk-ops/package.json index a315f28..2a63e0d 100644 --- a/cdk-ops/package.json +++ b/cdk-ops/package.json @@ -8,23 +8,28 @@ "build": "tsc", "watch": "tsc -w", "test": "jest", - "cdk": "cdk" + "cdk": "cdk", + "populate-dw": "node bin/populate-data-warehouse.js" }, "devDependencies": { "@types/jest": "^27.5.0", "@types/node": "10.17.27", "@types/prettier": "2.6.0", - "aws-cdk": "^2.28.1", + "aws-cdk": "^2.45.0", "jest": "^27.5.1", "ts-jest": "^27.1.4", - "ts-node": "^10.7.0", + "ts-node": "^10.9.1", "typescript": "~3.9.7" }, "dependencies": { - "@aws-sdk/client-cloudformation": "^3.112.0", - "aws-cdk-lib": "^2.28.1", + "@aws-cdk/aws-lambda-python-alpha": "^2.45.0-alpha.0", + "@aws-sdk/client-cloudformation": "^3.186.0", + "@aws-sdk/client-lambda": "^3.186.0", + "aws-cdk-lib": "^2.45.0", "cdk-common": "file:../cdk-common", - "constructs": "^10.1.42", - "source-map-support": "^0.5.21" + "cdk2-python-library-layer": "github:kikuomax/cdk-python-library-layer#v0.1.0-v2", + "constructs": "^10.1.128", + "source-map-support": "^0.5.21", + "yargs": "^17.6.0" } } diff --git a/cdk/lib/cdk-stack.ts b/cdk/lib/cdk-stack.ts index a9e3398..04309ce 100644 --- a/cdk/lib/cdk-stack.ts +++ b/cdk/lib/cdk-stack.ts @@ -36,5 +36,11 @@ export class CdkStack extends Stack { description: 'Domain name of the CloudFront distribution for contents of the codemonger website', value: contentsDistribution.distribution.distributionDomainName, }); + if (contentsDistribution.accessLogsBucketName != null) { + new CfnOutput(this, 'ContentsAccessLogsBucketName', { + description: 'Name of the S3 bucket for CloudFront access logs', + value: contentsDistribution.accessLogsBucketName, + }); + } } } diff --git a/cdk/lib/contents-distribution.ts b/cdk/lib/contents-distribution.ts index 1cf106e..49de376 100644 --- a/cdk/lib/contents-distribution.ts +++ b/cdk/lib/contents-distribution.ts @@ -2,6 +2,8 @@ import * as path from 'path'; import { Duration, + Fn, + Stack, aws_certificatemanager as acm, aws_cloudfront as cloudfront, aws_cloudfront_origins as origins, @@ -45,6 +47,8 @@ const NO_DOMAIN_NAME_CDK_CONTEXT = 'codemonger:no-domain-name'; export class ContentsDistribution extends Construct { /** CloudFront distribution for contents of the codemonger website. */ readonly distribution: cloudfront.IDistribution; + /** Name of the S3 bucket for access logs. */ + readonly accessLogsBucketName: string | undefined; constructor(scope: Construct, id: string, props: Props) { super(scope, id); @@ -109,6 +113,45 @@ export class ContentsDistribution extends Construct { ...certificateParams, }, ); + + // obtains the logging bucket created by the distribution. + // we have to access the underlying CloudFormation properties. + // + // see below for how to access the CloudFormation properties, + // https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_cloudfront.CfnDistribution.html + const cfnDistribution = + this.distribution.node.defaultChild as cloudfront.CfnDistribution; + const stack = Stack.of(this); + const distributionConfig = stack.resolve(cfnDistribution.distributionConfig) as cloudfront.CfnDistribution.DistributionConfigProperty; + if (distributionConfig.logging != null) { + const loggingConfig = stack.resolve(distributionConfig.logging) as cloudfront.CfnDistribution.LoggingProperty; + // loggingConfig.bucket should be an `Fn::GetAtt` intrinsic function to + // obtain the regional domain name from the bucket for access logs. + // so we can extract the logical name of the bucket and then obtain the + // bucket name by Ref. + // + // TODO: too much dependence on the CDK implementation + // https://github.com/aws/aws-cdk/blob/7d8ef0bad461a05caa41d140678481c5afb9d33e/packages/%40aws-cdk/aws-cloudfront/lib/distribution.ts#L443-L457 + const bucketRef: any = loggingConfig.bucket; + if (typeof bucketRef !== 'object') { + throw new Error( + 'logical name of the bucket for access logs must be available', + ); + } + const getAtt: any = bucketRef['Fn::GetAtt']; + if (!Array.isArray(getAtt)) { + throw new Error( + 'logical name of the bucket for access logs must be available', + ); + } + const bucketLogicalId = getAtt[0]; + if (typeof bucketLogicalId !== 'string') { + throw new Error( + 'logical name of the bucket for access logs must be available', + ); + } + this.accessLogsBucketName = Fn.ref(bucketLogicalId); + } } }