From 9fa7f29cba9680cd682fdd80cb2a75dae15d08b1 Mon Sep 17 00:00:00 2001 From: Fabio Gollinucci Date: Thu, 25 May 2023 16:45:33 +0200 Subject: [PATCH 01/13] feat(drivers): add 'aws-dynamodb' storage driver --- docs/content/6.drivers/aws-dynamodb.md | 64 +++++++ package.json | 7 +- pnpm-lock.yaml | 250 +++++++++++-------------- src/drivers/aws-dynamodb.ts | 136 ++++++++++++++ src/index.ts | 1 + test/drivers/aws-dynamodb.test.ts | 79 ++++++++ 6 files changed, 398 insertions(+), 139 deletions(-) create mode 100644 docs/content/6.drivers/aws-dynamodb.md create mode 100644 src/drivers/aws-dynamodb.ts create mode 100644 test/drivers/aws-dynamodb.test.ts diff --git a/docs/content/6.drivers/aws-dynamodb.md b/docs/content/6.drivers/aws-dynamodb.md new file mode 100644 index 00000000..4c77b33d --- /dev/null +++ b/docs/content/6.drivers/aws-dynamodb.md @@ -0,0 +1,64 @@ +# Amazon DynamoDB + +Store data in a [Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) table. + +This driver uses the DynamoDB table as a key value store. By default it uses the `key` as the table partition key and the `value` as content. This options can be changed using `attributes`. + +To use it, you will need to install `@aws-sdk/client-dynamodb` and `@aws-sdk/lib-dynamodb` in your project: + +```bash +npm i @aws-sdk/client-dynamodb @aws-sdk/lib-dynamodb +``` + +Usage: + +```js +import { createStorage } from "unstorage"; +import dynamoDbCacheDriver from "unstorage/drivers/aws-dynamodb"; + +const storage = createStorage({ + driver: dynamoDbCacheDriver({ + table: 'my-table-name', // required + region: 'us-east-1', + credentials: { + accessKeyId: 'xxxxxxxxxx', + secretAccessKey: 'xxxxxxxxxxxxxxxxxxxx', + }, + attributes: { + key: 'key', + value: 'value', + }; + }), +}); +``` + +**Authentication:** + +The driver supports the default [AWS SDK credentials](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html). + +The IAM role or user that use the driver need the following permissions: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "dynamodb:GetItem", + "dynamodb:PutItem", + "dynamodb:Scan", + "dynamodb:DeleteItem" + ], + "Resource": "arn:aws:dynamodb:*:*:table/my-table-name" + } + ] +} +``` + +**Options:** + +- `table`: The name of the DynamoDB table. +- `region`: The AWS region to use. +- `credentials`: The AWS SDK credentials object. +- `attributes`: The key/value attributes mapping to table item attributes. diff --git a/package.json b/package.json index 0f272249..259368f2 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,9 @@ "ufo": "^1.1.2" }, "devDependencies": { + "@aws-sdk/client-dynamodb": "^3.338.0", + "@aws-sdk/credential-providers": "^3.338.0", + "@aws-sdk/lib-dynamodb": "^3.338.0", "@azure/app-configuration": "^1.4.1", "@azure/cosmos": "^3.17.3", "@azure/data-tables": "^13.2.2", @@ -93,6 +96,8 @@ "vue": "^3.3.4" }, "peerDependencies": { + "@aws-sdk/client-dynamodb": "^3.338.0", + "@aws-sdk/lib-dynamodb": "^3.338.0", "@azure/app-configuration": "^1.4.1", "@azure/cosmos": "^3.17.3", "@azure/data-tables": "^13.2.2", @@ -133,4 +138,4 @@ } }, "packageManager": "pnpm@8.5.1" -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1917a177..7599ef28 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,6 +1,9 @@ lockfileVersion: '6.0' dependencies: + '@aws-sdk/credential-providers': + specifier: ^3.338.0 + version: 3.338.0 anymatch: specifier: ^3.1.3 version: 3.1.3 @@ -36,6 +39,12 @@ dependencies: version: 1.1.2 devDependencies: + '@aws-sdk/client-dynamodb': + specifier: ^3.338.0 + version: 3.338.0 + '@aws-sdk/lib-dynamodb': + specifier: ^3.338.0 + version: 3.338.0(@aws-sdk/client-dynamodb@3.338.0)(@aws-sdk/smithy-client@3.338.0)(@aws-sdk/types@3.338.0) '@azure/app-configuration': specifier: ^1.4.1 version: 1.4.1 @@ -116,7 +125,7 @@ devDependencies: version: 0.38.0 mongodb: specifier: ^5.5.0 - version: 5.5.0 + version: 5.5.0(@aws-sdk/credential-providers@3.338.0) mongodb-memory-server: specifier: ^8.12.2 version: 8.12.2 @@ -159,8 +168,6 @@ packages: resolution: {integrity: sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==} dependencies: tslib: 1.14.1 - dev: true - optional: true /@aws-crypto/sha256-browser@3.0.0: resolution: {integrity: sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==} @@ -173,8 +180,6 @@ packages: '@aws-sdk/util-locate-window': 3.310.0 '@aws-sdk/util-utf8-browser': 3.259.0 tslib: 1.14.1 - dev: true - optional: true /@aws-crypto/sha256-js@3.0.0: resolution: {integrity: sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==} @@ -182,15 +187,11 @@ packages: '@aws-crypto/util': 3.0.0 '@aws-sdk/types': 3.338.0 tslib: 1.14.1 - dev: true - optional: true /@aws-crypto/supports-web-crypto@3.0.0: resolution: {integrity: sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==} dependencies: tslib: 1.14.1 - dev: true - optional: true /@aws-crypto/util@3.0.0: resolution: {integrity: sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==} @@ -198,8 +199,6 @@ packages: '@aws-sdk/types': 3.338.0 '@aws-sdk/util-utf8-browser': 3.259.0 tslib: 1.14.1 - dev: true - optional: true /@aws-sdk/abort-controller@3.338.0: resolution: {integrity: sha512-/yLI32+HwFNBRJ39jMXw+/cn3AnlCuJpQd7Ax4887g32Dgte5eyrfY8sJUOL6902BUmAq4oSRI5QeBXNplO0Xw==} @@ -207,8 +206,6 @@ packages: dependencies: '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/client-cognito-identity@3.338.0: resolution: {integrity: sha512-1gu9gXJwrxGGGMlBzmM4d8mkNjD1M8tWo+vmT/Aq1EMBxGef3eN0k6SyeIruj2Jns3olC6pjTIU8zb3vVBkh5Q==} @@ -252,8 +249,53 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt + + /@aws-sdk/client-dynamodb@3.338.0: + resolution: {integrity: sha512-m1tYFDdO2KxD9LvAEZEzixgfFpvNnXz5LHjCG/oVaGCPPMB91AyuyW4NkloCJ0gxmY4WqaHPvWMkwuJ4RJsU7Q==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-crypto/sha256-browser': 3.0.0 + '@aws-crypto/sha256-js': 3.0.0 + '@aws-sdk/client-sts': 3.338.0 + '@aws-sdk/config-resolver': 3.338.0 + '@aws-sdk/credential-provider-node': 3.338.0 + '@aws-sdk/fetch-http-handler': 3.338.0 + '@aws-sdk/hash-node': 3.338.0 + '@aws-sdk/invalid-dependency': 3.338.0 + '@aws-sdk/middleware-content-length': 3.338.0 + '@aws-sdk/middleware-endpoint': 3.338.0 + '@aws-sdk/middleware-endpoint-discovery': 3.338.0 + '@aws-sdk/middleware-host-header': 3.338.0 + '@aws-sdk/middleware-logger': 3.338.0 + '@aws-sdk/middleware-recursion-detection': 3.338.0 + '@aws-sdk/middleware-retry': 3.338.0 + '@aws-sdk/middleware-serde': 3.338.0 + '@aws-sdk/middleware-signing': 3.338.0 + '@aws-sdk/middleware-stack': 3.338.0 + '@aws-sdk/middleware-user-agent': 3.338.0 + '@aws-sdk/node-config-provider': 3.338.0 + '@aws-sdk/node-http-handler': 3.338.0 + '@aws-sdk/smithy-client': 3.338.0 + '@aws-sdk/types': 3.338.0 + '@aws-sdk/url-parser': 3.338.0 + '@aws-sdk/util-base64': 3.310.0 + '@aws-sdk/util-body-length-browser': 3.310.0 + '@aws-sdk/util-body-length-node': 3.310.0 + '@aws-sdk/util-defaults-mode-browser': 3.338.0 + '@aws-sdk/util-defaults-mode-node': 3.338.0 + '@aws-sdk/util-endpoints': 3.338.0 + '@aws-sdk/util-retry': 3.338.0 + '@aws-sdk/util-user-agent-browser': 3.338.0 + '@aws-sdk/util-user-agent-node': 3.338.0 + '@aws-sdk/util-utf8': 3.310.0 + '@aws-sdk/util-waiter': 3.338.0 + '@smithy/protocol-http': 1.0.1 + '@smithy/types': 1.0.0 + tslib: 2.5.2 + uuid: 8.3.2 + transitivePeerDependencies: + - aws-crt dev: true - optional: true /@aws-sdk/client-sso-oidc@3.338.0: resolution: {integrity: sha512-mny5Q3LWKTcMMFS8WxeOCTinl193z7vS3b+eQz09K4jb1Lq04Bpjw25cySgBnhMGZ7QHQiYBscNLyu/TfOKiHA==} @@ -294,8 +336,6 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt - dev: true - optional: true /@aws-sdk/client-sso@3.338.0: resolution: {integrity: sha512-EglKsGlVph65PuFPKq1nGlxsY99XM2xHJaB1uX0bQEC94qrmS/M4a5kno5tiUnTWO1K+K4JBQiOxdGJs0GUS+w==} @@ -336,8 +376,6 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt - dev: true - optional: true /@aws-sdk/client-sts@3.338.0: resolution: {integrity: sha512-FBHy/G7BAPX0CdEeeGYpoAnKXVCSIIkESLU2wF6x880z+U2IqiL48Fzoa5qoLaLPQaK/30P7ytznkqm4vd1OFw==} @@ -382,8 +420,6 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt - dev: true - optional: true /@aws-sdk/config-resolver@3.338.0: resolution: {integrity: sha512-rB9WUaMfTB74Hd2mOiyPFR7Q1viT+w6SaDSR9SA1P8EeIg5H13FNdIKb736Z8/6QJhDj7whdyk1CTGV+DmXOOg==} @@ -393,8 +429,6 @@ packages: '@aws-sdk/util-config-provider': 3.310.0 '@aws-sdk/util-middleware': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/credential-provider-cognito-identity@3.338.0: resolution: {integrity: sha512-kKkBt1qCKx+HspbMq7kd5Yz3jWRW5N1Tegs4cGbTFJH9qMJTyQMoS9GNRcFfzgNEA9sfpHxeTnBbwBw6Ca4S9g==} @@ -406,8 +440,6 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt - dev: true - optional: true /@aws-sdk/credential-provider-env@3.338.0: resolution: {integrity: sha512-j14vApy80tpk87C3x3uBf1caQsuR8RdQ8iOW830H/AOhsa88XaZIB/NQSX7exaIKZa2RU0Vv2wIlGAA8ko7J6g==} @@ -416,8 +448,6 @@ packages: '@aws-sdk/property-provider': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/credential-provider-imds@3.338.0: resolution: {integrity: sha512-qsqeywYfJevg5pgUUUBmm7pK1bckVrl091PZB2IliFdQVnDvI5GFLf4B0oZqjaLAzPG1gVtxRvqIve+tnP/+xA==} @@ -428,8 +458,6 @@ packages: '@aws-sdk/types': 3.338.0 '@aws-sdk/url-parser': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/credential-provider-ini@3.338.0: resolution: {integrity: sha512-UhgYgymT9sJiRm0peqP5EvtR4dXiS2Q2AuFgDUjBvDz8JaZlqafsIS4cfyGwTHV/xY6cdiMu5rCTe8hTyXsukQ==} @@ -446,8 +474,6 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt - dev: true - optional: true /@aws-sdk/credential-provider-node@3.338.0: resolution: {integrity: sha512-nZjaMRxJqX0EXMV9LA5IbRQI1pDGGZiPYX2KDfZ1Y9Gc1Y/vIZhHKOHGb1uKMAonlR076CsXlev4/tjC8SGGuw==} @@ -465,8 +491,6 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt - dev: true - optional: true /@aws-sdk/credential-provider-process@3.338.0: resolution: {integrity: sha512-5I1EgJxFFEg8xel2kInMpkdBKajUut0hR2fBajqCmK7Pflu8s0I2NKDots9a3YJagNrFJq38+EzoDcUvRrd2dg==} @@ -476,8 +500,6 @@ packages: '@aws-sdk/shared-ini-file-loader': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/credential-provider-sso@3.338.0: resolution: {integrity: sha512-fpzYHK17iF/uFkrm4cLg/utDVKSBTWNjAiNlE3GF6CaixBCwc0QBLKHk2nG4d1ZZeMVCbIUMS7eoqfR0LYc/yw==} @@ -491,8 +513,6 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt - dev: true - optional: true /@aws-sdk/credential-provider-web-identity@3.338.0: resolution: {integrity: sha512-kjT/P18jM1icwjYwr8wfY//T8lv2s81ms7OC7vgiSqckmQOxpVkdsep9d44ymSUXwopmotFP7M9gGnEHS6HwAA==} @@ -501,8 +521,6 @@ packages: '@aws-sdk/property-provider': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/credential-providers@3.338.0: resolution: {integrity: sha512-QQkWsR3fyq3N5eTvyKLgk1IO45SEM5+zIDqGqchG74AAhAzTHpiVZ3AOBZckaIAXKyHU3Fgy3gt/u+fdXC4xyw==} @@ -525,8 +543,14 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt + + /@aws-sdk/endpoint-cache@3.310.0: + resolution: {integrity: sha512-y3wipforet41EDTI0vnzxILqwAGll1KfI5qcdX9pXF/WF1f+3frcOtPiWtQEZQpy4czRogKm3BHo70QBYAZxlQ==} + engines: {node: '>=14.0.0'} + dependencies: + mnemonist: 0.38.3 + tslib: 2.5.2 dev: true - optional: true /@aws-sdk/fetch-http-handler@3.338.0: resolution: {integrity: sha512-NOIQmeSa51J2nFAzl99IjxwQkq27cdNJzF59jQWzpUCGbxXfMD4WWy2NHubabSFuJ4FJU2eyoQHUNUFc6/uxXA==} @@ -536,8 +560,6 @@ packages: '@aws-sdk/types': 3.338.0 '@aws-sdk/util-base64': 3.310.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/hash-node@3.338.0: resolution: {integrity: sha512-udveX3ZRO1oUbyBTQH0LJ8Ika7uk0pHuXrqapdi66GGRJB50IhmOg372zUEwZjDB7DZYXfGTCuAj2OoEalgpBA==} @@ -547,24 +569,33 @@ packages: '@aws-sdk/util-buffer-from': 3.310.0 '@aws-sdk/util-utf8': 3.310.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/invalid-dependency@3.338.0: resolution: {integrity: sha512-m6r1fTTGSl0V6l8Z+Ii4Ei8VFpDmu0AT6A59ZhJaMZgxf925ywuCPydyDW9ZqTLE0e7CgxhEHEsH1+HzpVuHTw==} dependencies: '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/is-array-buffer@3.310.0: resolution: {integrity: sha512-urnbcCR+h9NWUnmOtet/s4ghvzsidFmspfhYaHAmSRdy9yDjdjBJMFjjsn85A1ODUktztm+cVncXjQ38WCMjMQ==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 + + /@aws-sdk/lib-dynamodb@3.338.0(@aws-sdk/client-dynamodb@3.338.0)(@aws-sdk/smithy-client@3.338.0)(@aws-sdk/types@3.338.0): + resolution: {integrity: sha512-eJTwzRrfKOzMBHKWOtYnBrw26B/oQEE5xwMQbRI2fHsOINaHbbBwDE/dE0da6IHXr07elf+R2sPkZmj+E/NyoQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@aws-sdk/client-dynamodb': ^3.0.0 + '@aws-sdk/smithy-client': ^3.0.0 + '@aws-sdk/types': ^3.0.0 + dependencies: + '@aws-sdk/client-dynamodb': 3.338.0 + '@aws-sdk/smithy-client': 3.338.0 + '@aws-sdk/types': 3.338.0 + '@aws-sdk/util-dynamodb': 3.338.0 + tslib: 2.5.2 dev: true - optional: true /@aws-sdk/middleware-content-length@3.338.0: resolution: {integrity: sha512-m2C+yJaNmbA3ocBp/7ImUUuimymV5JsFdV7yAibpbYMX22g3q83nieOF9x0I66J0+h+/bcriz/T1ZJAPANLz/g==} @@ -573,8 +604,16 @@ packages: '@aws-sdk/protocol-http': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + + /@aws-sdk/middleware-endpoint-discovery@3.338.0: + resolution: {integrity: sha512-LD2iQ7h65Q89Ef2rEo/tJqSsj6V4UpLjlbbnL7PkDSzOJNCIgRItH1nEXEHL6g94Kef5MQEzAKEg5W/H0ygJ3Q==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/endpoint-cache': 3.310.0 + '@aws-sdk/protocol-http': 3.338.0 + '@aws-sdk/types': 3.338.0 + tslib: 2.5.2 dev: true - optional: true /@aws-sdk/middleware-endpoint@3.338.0: resolution: {integrity: sha512-bzL9Q8lFidg2NTjGVGDKI6yPG/XiPS+VIAMHJeihQmcv1alIy+N3IL4bEN15Fg+cwaGm+P3BevcLIHmcCOVb4w==} @@ -585,8 +624,6 @@ packages: '@aws-sdk/url-parser': 3.338.0 '@aws-sdk/util-middleware': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/middleware-host-header@3.338.0: resolution: {integrity: sha512-k3C7oppkrqeKrAJt9XIl45SdELtnph9BF0QypjyRfT5MNEDnMMsQkc6xy3ZMqG5dWQq6B2l8C+JL7pOvkSQP3w==} @@ -595,8 +632,6 @@ packages: '@aws-sdk/protocol-http': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/middleware-logger@3.338.0: resolution: {integrity: sha512-btj9U0Xovq/UAu3Ur4lAfF7Q3DvvwJ/0UUWsI6GgSzzqSOFgKCz7hCP2GZIT8aXEA5hJOpBOEMkNMjWPNa91Hg==} @@ -604,8 +639,6 @@ packages: dependencies: '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/middleware-recursion-detection@3.338.0: resolution: {integrity: sha512-fu5KwiHHSqC8KTQH6xdJ9+dua4gQcXSFLE5fVsergqd0uVdsmhiI+IDfW6QNwF/lmCqnoKDkpeasuB98eG2tow==} @@ -614,8 +647,6 @@ packages: '@aws-sdk/protocol-http': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/middleware-retry@3.338.0: resolution: {integrity: sha512-nw1oPFkB7TdDG4Vlz2Td47ft/2Gmx1bA18QfE9K1mMWZ4nnoAL8xnHbowlTfHo62+BbFCAPu53PzDUCncBL0iw==} @@ -628,8 +659,6 @@ packages: '@aws-sdk/util-retry': 3.338.0 tslib: 2.5.2 uuid: 8.3.2 - dev: true - optional: true /@aws-sdk/middleware-sdk-sts@3.338.0: resolution: {integrity: sha512-aZ8eFVaot8oYQri1wOesrA3gLizeAHtlA/ELlqxoGDJtO011J4/hTHTn0iJGbktaCvc1L3TF6mgOsgXpudYqMg==} @@ -638,8 +667,6 @@ packages: '@aws-sdk/middleware-signing': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/middleware-serde@3.338.0: resolution: {integrity: sha512-AabRLrE6sk9tqQlQ7z3kn4gTHNN7Anjk/AM0ZEu96WcWjedcpgM1vVpKTBE7vjnxcTRNq0CEM3GLtQqaZ7/HjQ==} @@ -647,8 +674,6 @@ packages: dependencies: '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/middleware-signing@3.338.0: resolution: {integrity: sha512-AprhhShMF75mOx80SABujLwrU/w2uHQIvWd6aF3BsE5JRI3uQZRqspfjFCaK52HNLQPj3sCQUw1GeiZJ8GyWCw==} @@ -660,16 +685,12 @@ packages: '@aws-sdk/types': 3.338.0 '@aws-sdk/util-middleware': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/middleware-stack@3.338.0: resolution: {integrity: sha512-9zXyiklX9AK9ZIXuIPzWzz2vevBEcnBs9UNIxiHl4NBZ8d8oyTvaES1PtFuwL6f7ANSZ9EGVQ2rdTTnMNxMI1A==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/middleware-user-agent@3.338.0: resolution: {integrity: sha512-DMqODOsDMFMPcDw2Ya6a0i34AhaBDRpp3vJ+FK3zPxUIsv6iHA+XqEcXLOxROLLoydoyxus7k2U+EWibLZrFbQ==} @@ -679,8 +700,6 @@ packages: '@aws-sdk/types': 3.338.0 '@aws-sdk/util-endpoints': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/node-config-provider@3.338.0: resolution: {integrity: sha512-YO7yWg3ipnUI5u6D+Zn2NUpjj5krwc8zNWeY79ULVIp9g7faqGX3xMSjeRSrpZ83s5jg1dOm/+bB0gw7mCrRCw==} @@ -690,8 +709,6 @@ packages: '@aws-sdk/shared-ini-file-loader': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/node-http-handler@3.338.0: resolution: {integrity: sha512-V1BLzCruiv45tJ0vXjiamY8LncIsUFsXYJGDupomFYhWRN8L1MUB9f2vdKn5X3wXn/yKrluwTmNaryrIqd9akA==} @@ -702,8 +719,6 @@ packages: '@aws-sdk/querystring-builder': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/property-provider@3.338.0: resolution: {integrity: sha512-mC+ZJ738ipif6ZkH59gcipozYj1FOfpXr9pGVCA2hJGLDdaBwI2Jfpb2qCqbsTNtoCjBuIy+sQHGmUHyclgYHg==} @@ -711,8 +726,6 @@ packages: dependencies: '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/protocol-http@3.338.0: resolution: {integrity: sha512-JX03Q2gshdzOWtA/07kdpk0hqeOrOfwuF8TB97g66VCcIopYQkCeNH1zzkWu+RsGxfSlzQ7up+ZM6sclYXyB1A==} @@ -720,8 +733,6 @@ packages: dependencies: '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/querystring-builder@3.338.0: resolution: {integrity: sha512-IB3YhO93Htwt2SxJx4VWsN57Rt1KEsvZ6PbneO4bcS96E04BlfBujYMZ+QxEM3EJxorhpkwbI2QnI12IjD8FhA==} @@ -730,8 +741,6 @@ packages: '@aws-sdk/types': 3.338.0 '@aws-sdk/util-uri-escape': 3.310.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/querystring-parser@3.338.0: resolution: {integrity: sha512-vtI8Gqx4yj0BZlWonRMgLz68sHt5H48HN+ClnY+fDDB/8KLnCuwZ3TGKmYIbYbshL9wjJz0A9aLzuC6nPQ5JKw==} @@ -739,14 +748,10 @@ packages: dependencies: '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/service-error-classification@3.338.0: resolution: {integrity: sha512-BJFr2mx/N3NbycGTlMMGRBc0tGcHXHEbMPy1H2RbejzL23zh27MchaL1WAK9SvwVMKS29hSDbhkuVR2ABRjerA==} engines: {node: '>=14.0.0'} - dev: true - optional: true /@aws-sdk/shared-ini-file-loader@3.338.0: resolution: {integrity: sha512-MA1Sp97LFlOXcUaXgo47j86IsPRWYq1V/JqR+uu0zofZw4Xlt7Y6F+mmnDHvuuMy6R2ltzjXSwgrrW3k0bxFPA==} @@ -754,8 +759,6 @@ packages: dependencies: '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/signature-v4@3.338.0: resolution: {integrity: sha512-EwKTe/8Iwab/v0eo27w7DRYlqp9wEZEhuRfOMwTikUVH6iuTnW6AXjcIUfcRYBRbx2zqnRSiMAZkjN6ZFYm0bQ==} @@ -768,8 +771,6 @@ packages: '@aws-sdk/util-uri-escape': 3.310.0 '@aws-sdk/util-utf8': 3.310.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/smithy-client@3.338.0: resolution: {integrity: sha512-IpFLdLG8GwaiFdqVXf+WyU47Hfa2BMIupAU6iSkE2ZO0lBdg+efn/BBwis5WbBNTDCaaU0xH9y68SmnqqtD7pA==} @@ -778,8 +779,6 @@ packages: '@aws-sdk/middleware-stack': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/token-providers@3.338.0: resolution: {integrity: sha512-wuiEGcWiMeq5N68M489i2iGYcCad9p1btNEOFgus+JO3DRSA6HZXizLI1wqfbUm5Ei8512AvUKB6N8PMzahQsg==} @@ -792,16 +791,12 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt - dev: true - optional: true /@aws-sdk/types@3.338.0: resolution: {integrity: sha512-hrNK15o+EObLrl9oWOyxJN2dwjgbdBMGolLEVP/wR/+M9ojHgk/x1kMsCVcV82a8Vgdtqx1TyOC3UugUPT0+NA==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/url-parser@3.338.0: resolution: {integrity: sha512-x8a5swfZ6iWJZEA8rm99OKQ1A6xhWPP1taQUzoPavGCzPAOqyc8cd0FcXYMxvtXb3FeBhGaI8tiGKvelJro0+A==} @@ -809,8 +804,6 @@ packages: '@aws-sdk/querystring-parser': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/util-base64@3.310.0: resolution: {integrity: sha512-v3+HBKQvqgdzcbL+pFswlx5HQsd9L6ZTlyPVL2LS9nNXnCcR3XgGz9jRskikRUuUvUXtkSG1J88GAOnJ/apTPg==} @@ -818,23 +811,17 @@ packages: dependencies: '@aws-sdk/util-buffer-from': 3.310.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/util-body-length-browser@3.310.0: resolution: {integrity: sha512-sxsC3lPBGfpHtNTUoGXMQXLwjmR0zVpx0rSvzTPAuoVILVsp5AU/w5FphNPxD5OVIjNbZv9KsKTuvNTiZjDp9g==} dependencies: tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/util-body-length-node@3.310.0: resolution: {integrity: sha512-2tqGXdyKhyA6w4zz7UPoS8Ip+7sayOg9BwHNidiGm2ikbDxm1YrCfYXvCBdwaJxa4hJfRVz+aL9e+d3GqPI9pQ==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/util-buffer-from@3.310.0: resolution: {integrity: sha512-i6LVeXFtGih5Zs8enLrt+ExXY92QV25jtEnTKHsmlFqFAuL3VBeod6boeMXkN2p9lbSVVQ1sAOOYZOHYbYkntw==} @@ -842,16 +829,12 @@ packages: dependencies: '@aws-sdk/is-array-buffer': 3.310.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/util-config-provider@3.310.0: resolution: {integrity: sha512-xIBaYo8dwiojCw8vnUcIL4Z5tyfb1v3yjqyJKJWV/dqKUFOOS0U591plmXbM+M/QkXyML3ypon1f8+BoaDExrg==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/util-defaults-mode-browser@3.338.0: resolution: {integrity: sha512-Zfr5c7JKMJTfb7z+hgd0ioU5iw+wId6Cppc5V1HpZuS2YY4Mn3aJIixzyzhIoCzbmk/yIkf96981epM9eo3/TA==} @@ -861,8 +844,6 @@ packages: '@aws-sdk/types': 3.338.0 bowser: 2.11.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/util-defaults-mode-node@3.338.0: resolution: {integrity: sha512-DFM3BSpSetshZTgTjueCkAYZWS0tn5zl7SjkSpFhWQZ8Tt/Df3/DEjcPvxzmC/5vgYSUXNsqcI7lLAJk9aGZAA==} @@ -874,8 +855,13 @@ packages: '@aws-sdk/property-provider': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + + /@aws-sdk/util-dynamodb@3.338.0: + resolution: {integrity: sha512-hQzumWnMtFUpJRkLNR+oa1Ip9OGMVyI0hzO5pST8L66M9c+KCu75fLWj3KqE4pt/dIPUfFaeL4/ETEirydm5JA==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.5.2 dev: true - optional: true /@aws-sdk/util-endpoints@3.338.0: resolution: {integrity: sha512-0gBQcohbNcBsBR7oyaD0Dg2m6qOmfp0G1iN/NM23gwAr2H3ni8tUXfs1HsZzxikOwUr6dSLASokc30vQXBF44A==} @@ -883,32 +869,24 @@ packages: dependencies: '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/util-hex-encoding@3.310.0: resolution: {integrity: sha512-sVN7mcCCDSJ67pI1ZMtk84SKGqyix6/0A1Ab163YKn+lFBQRMKexleZzpYzNGxYzmQS6VanP/cfU7NiLQOaSfA==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/util-locate-window@3.310.0: resolution: {integrity: sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/util-middleware@3.338.0: resolution: {integrity: sha512-oQuAmhi16HWEqVa+Nq4VD4Ymet9vS+uiW92reaagQrW2QFjAgJW9A6pU0PcIHF9sWY1iDKeNdV5b9odQ45PDJA==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/util-retry@3.338.0: resolution: {integrity: sha512-diR6M3gJgSgBg/87L2e8iF8urG+LOW9ZGWxhntYpYX4uhiIjwNgUPUa993553C8GIOZDHez5X9ExU4asYGQ71Q==} @@ -916,16 +894,12 @@ packages: dependencies: '@aws-sdk/service-error-classification': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/util-uri-escape@3.310.0: resolution: {integrity: sha512-drzt+aB2qo2LgtDoiy/3sVG8w63cgLkqFIa2NFlGpUgHFWTXkqtbgf4L5QdjRGKWhmZsnqkbtL7vkSWEcYDJ4Q==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/util-user-agent-browser@3.338.0: resolution: {integrity: sha512-3e8D+SOtOQEtRtksOEF7EC26xPkuY6YK6biLgdtvR9JspK96rHk5eX1HEJeBJJqbxhyPaxpIw+OhWhnsrUS3hA==} @@ -933,8 +907,6 @@ packages: '@aws-sdk/types': 3.338.0 bowser: 2.11.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/util-user-agent-node@3.338.0: resolution: {integrity: sha512-rc+bC5KM9h25urRc+MXuViJkJ+qYG2NlCRw6xm2lSIvHFJTUjH1ZMO3mqNDYkGnQRbj0mmrVe+N77TJZGf3Q2Q==} @@ -948,15 +920,11 @@ packages: '@aws-sdk/node-config-provider': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/util-utf8-browser@3.259.0: resolution: {integrity: sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==} dependencies: tslib: 2.5.2 - dev: true - optional: true /@aws-sdk/util-utf8@3.310.0: resolution: {integrity: sha512-DnLfFT8uCO22uOJc0pt0DsSNau1GTisngBCDw8jQuWT5CqogMJu4b/uXmwEqfj8B3GX6Xsz8zOd6JpRlPftQoA==} @@ -964,8 +932,15 @@ packages: dependencies: '@aws-sdk/util-buffer-from': 3.310.0 tslib: 2.5.2 + + /@aws-sdk/util-waiter@3.338.0: + resolution: {integrity: sha512-15yWYJo/M4VDpZjlXgQDM4Du8UjX33eIVPJDrOmn/u+UrD6QUXoBuLXKns0uAMUTPFacBGZ0NwMywxieq0g11Q==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/abort-controller': 3.338.0 + '@aws-sdk/types': 3.338.0 + tslib: 2.5.2 dev: true - optional: true /@azure/abort-controller@1.1.0: resolution: {integrity: sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==} @@ -2000,16 +1975,12 @@ packages: dependencies: '@smithy/types': 1.0.0 tslib: 2.5.2 - dev: true - optional: true /@smithy/types@1.0.0: resolution: {integrity: sha512-kc1m5wPBHQCTixwuaOh9vnak/iJm21DrSf9UK6yDE5S3mQQ4u11pqAUiKWnlrZnYkeLfAI9UEHj9OaMT1v5Umg==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 - dev: true - optional: true /@tootallnate/once@2.0.0: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} @@ -2739,8 +2710,6 @@ packages: /bowser@2.11.0: resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} - dev: true - optional: true /bplist-parser@0.2.0: resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==} @@ -4039,8 +4008,6 @@ packages: hasBin: true dependencies: strnum: 1.0.5 - dev: true - optional: true /fast-xml-parser@4.2.2: resolution: {integrity: sha512-DLzIPtQqmvmdq3VUKR7T6omPK/VCRNqgFlGtbESfyhcH2R4I8EzK1/K6E8PkRCK2EabWrUHK32NjYRbEFnnz0Q==} @@ -5442,6 +5409,12 @@ packages: ufo: 1.1.2 dev: true + /mnemonist@0.38.3: + resolution: {integrity: sha512-2K9QYubXx/NAjv4VLq1d1Ly8pWNC5L3BrixtdkyTegXWJIqY+zLNDhhX/A+ZwWt70tB1S8H4BE8FLYEFyNoOBw==} + dependencies: + obliterator: 1.6.1 + dev: true + /moment-timezone@0.5.43: resolution: {integrity: sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ==} dependencies: @@ -5512,7 +5485,7 @@ packages: - aws-crt dev: true - /mongodb@5.5.0: + /mongodb@5.5.0(@aws-sdk/credential-providers@3.338.0): resolution: {integrity: sha512-XgrkUgAAdfnZKQfk5AsYL8j7O99WHd4YXPxYxnh8dZxD+ekYWFRA3JktUsBnfg+455Smf75/+asoU/YLwNGoQQ==} engines: {node: '>=14.20.1'} peerDependencies: @@ -5527,6 +5500,7 @@ packages: snappy: optional: true dependencies: + '@aws-sdk/credential-providers': 3.338.0 bson: 5.3.0 mongodb-connection-string-url: 2.6.0 socks: 2.7.1 @@ -5753,6 +5727,10 @@ packages: es-abstract: 1.21.2 dev: true + /obliterator@1.6.1: + resolution: {integrity: sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig==} + dev: true + /ofetch@1.0.1: resolution: {integrity: sha512-icBz2JYfEpt+wZz1FRoGcrMigjNKjzvufE26m9+yUiacRQRHwnNlGRPiDnW4op7WX/MR6aniwS8xw8jyVelF2g==} dependencies: @@ -6711,7 +6689,6 @@ packages: /strnum@1.0.5: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} - dev: true /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} @@ -6920,11 +6897,9 @@ packages: /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - dev: true /tslib@2.5.2: resolution: {integrity: sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==} - dev: true /tsutils@3.21.0(typescript@5.0.4): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} @@ -7149,7 +7124,6 @@ packages: /uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true - dev: true /uuid@9.0.0: resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} diff --git a/src/drivers/aws-dynamodb.ts b/src/drivers/aws-dynamodb.ts new file mode 100644 index 00000000..d31b82ed --- /dev/null +++ b/src/drivers/aws-dynamodb.ts @@ -0,0 +1,136 @@ +import { createRequiredError, defineDriver } from "./utils"; +import { DynamoDBClient } from "@aws-sdk/client-dynamodb"; +import { + DynamoDBDocumentClient, + GetCommand, + PutCommand, + DeleteCommand, + ScanCommand, +} from "@aws-sdk/lib-dynamodb"; + +export interface DynamoDBStorageOptions { + table: string; + region?: string; + credentials?: any; + attributes?: { + key?: string; + value?: string; + }; +} + +const DRIVER_NAME = "aws-dynamodb"; + +export default defineDriver((opts: DynamoDBStorageOptions) => { + if (!opts.table) { + throw createRequiredError(DRIVER_NAME, "table"); + } + + if (!opts.attributes) { + opts.attributes = { + key: "key", + value: "value", + }; + } else { + if (!opts.attributes.key) { + opts.attributes.key = "key"; + } + + if (!opts.attributes.value) { + opts.attributes.value = "value"; + } + } + + let client; + function getClient(): DynamoDBDocumentClient { + if (!client) { + client = DynamoDBDocumentClient.from( + new DynamoDBClient({ + region: opts.region, + credentials: opts.credentials, + }) + ); + } + return client; + } + + function createObject(key: string, value: any = null) { + const obj = {}; + obj[opts.attributes.key] = key; + if (value) { + obj[opts.attributes.value] = value; + } + return obj; + } + + async function getItemValue(key: string): Promise { + const { Item: item } = await getClient().send( + new GetCommand({ + TableName: opts.table, + Key: createObject(key), + }) + ); + if (!item) { + return null; + } + return item[opts.attributes.value]; + } + + async function putItemValue(key: string, value: any): Promise { + await getClient().send( + new PutCommand({ + TableName: opts.table, + Item: createObject(key, value), + }) + ); + } + + async function removeItem(key: string): Promise { + await getClient().send( + new DeleteCommand({ + TableName: opts.table, + Key: createObject(key), + }) + ); + } + + async function listKeys(startKey = undefined) { + const { Items: items, LastEvaluatedKey: lastKey } = await getClient().send( + new ScanCommand({ + TableName: opts.table, + ExclusiveStartKey: startKey, + }) + ); + + let keys = items.map((item) => item[opts.attributes.key] || null); + if (lastKey) { + keys = keys.concat(await listKeys(lastKey)); + } + + return keys; + } + + return { + name: DRIVER_NAME, + options: opts, + async hasItem(key) { + const item = await getItemValue(key); + return !!item; + }, + async getItem(key) { + return await getItemValue(key); + }, + async setItem(key, value) { + await putItemValue(key, value); + }, + async removeItem(key) { + await removeItem(key); + }, + async getKeys() { + return await listKeys(); + }, + async clear() { + const keys = await listKeys(); + await Promise.all(keys.map((key) => removeItem(key))); + }, + }; +}); diff --git a/src/index.ts b/src/index.ts index 4103582e..74eaa715 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,6 +4,7 @@ export * from "./utils"; export { defineDriver } from "./drivers/utils"; export const builtinDrivers = { + awsDynamoDB: "unstorage/drivers/aws-dynamodb", azureStorageTable: "unstorage/drivers/azure-storage-table", azureCosmos: "unstorage/drivers/azure-cosmos", azureStorageBlob: "unstorage/drivers/azure-storage-blob", diff --git a/test/drivers/aws-dynamodb.test.ts b/test/drivers/aws-dynamodb.test.ts new file mode 100644 index 00000000..d959747d --- /dev/null +++ b/test/drivers/aws-dynamodb.test.ts @@ -0,0 +1,79 @@ +import { describe, beforeAll, afterAll } from "vitest"; +import driver, { DynamoDBStorageOptions } from "../../src/drivers/aws-dynamodb"; +import { testDriver } from "./utils"; +import { fromIni } from "@aws-sdk/credential-providers"; +import { + DynamoDBClient, + CreateTableCommand, + DeleteTableCommand, + waitUntilTableExists, + waitUntilTableNotExists, +} from "@aws-sdk/client-dynamodb"; + +const TABLE_OPERATIONS_TIMEOUT_SECONDS = 30; // table need at lest 30s from creation to become available + +describe("drivers: aws-dynamodb", () => { + const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION; + const credentials = fromIni({ + profile: + process.env.AWS_PROFILE || process.env.AWS_DEFAULT_PROFILE || "default", + }); + + const options: DynamoDBStorageOptions = { + table: "tmp-unstorage-tests", + region, + credentials, + attributes: { + key: "key", + value: "value", + }, + }; + + const client = new DynamoDBClient({ + region: process.env.AWS_REGION, + credentials, + }); + + beforeAll(async () => { + await client.send( + new CreateTableCommand({ + TableName: options.table, + BillingMode: "PAY_PER_REQUEST", + AttributeDefinitions: [ + { + AttributeName: options.attributes?.key, + AttributeType: "S", + }, + ], + KeySchema: [ + { + AttributeName: options.attributes?.key, + KeyType: "HASH", + }, + ], + }) + ); + + await waitUntilTableExists( + { client, maxWaitTime: TABLE_OPERATIONS_TIMEOUT_SECONDS }, + { TableName: options.table } + ); + }, (TABLE_OPERATIONS_TIMEOUT_SECONDS + 2) * 1000); + + afterAll(async () => { + await client.send( + new DeleteTableCommand({ + TableName: options.table, + }) + ); + + await waitUntilTableNotExists( + { client, maxWaitTime: TABLE_OPERATIONS_TIMEOUT_SECONDS }, + { TableName: options.table } + ); + }, (TABLE_OPERATIONS_TIMEOUT_SECONDS + 2) * 1000); + + testDriver({ + driver: driver(options), + }); +}); From f1547d333b4e73f808f1091987e710ef19d484d4 Mon Sep 17 00:00:00 2001 From: Fabio Gollinucci Date: Thu, 25 May 2023 17:56:40 +0200 Subject: [PATCH 02/13] chore(aws-dynamodb) add TTL attribute support --- docs/content/6.drivers/aws-dynamodb.md | 26 ++++++++++------ src/drivers/aws-dynamodb.ts | 43 ++++++++++++++++++++++---- test/drivers/aws-dynamodb.test.ts | 12 +++++++ 3 files changed, 66 insertions(+), 15 deletions(-) diff --git a/docs/content/6.drivers/aws-dynamodb.md b/docs/content/6.drivers/aws-dynamodb.md index 4c77b33d..68efc29f 100644 --- a/docs/content/6.drivers/aws-dynamodb.md +++ b/docs/content/6.drivers/aws-dynamodb.md @@ -18,25 +18,32 @@ import dynamoDbCacheDriver from "unstorage/drivers/aws-dynamodb"; const storage = createStorage({ driver: dynamoDbCacheDriver({ - table: 'my-table-name', // required - region: 'us-east-1', + table: "my-table-name", // required + region: "us-east-1", credentials: { - accessKeyId: 'xxxxxxxxxx', - secretAccessKey: 'xxxxxxxxxxxxxxxxxxxx', + accessKeyId: "xxxxxxxxxx", + secretAccessKey: "xxxxxxxxxxxxxxxxxxxx", }, attributes: { - key: 'key', - value: 'value', - }; + key: "key", + value: "value", + ttl: "ttl", + }, + expireIn: 300, // seconds }), }); ``` +When `expireIn` is set to a number greater than 0 the driver will add seconds to the current timestamp and set the TTL attribute. +Otherwise removing the `expireIn` option or setting it to 0 will disable this functionality. + +Since the DynamoDB items deletion is asynchronous the driver will check the validity of the TTL attribute before returning them from `getItem` and `getKeys` operations. This in order to ensure that no expired items will be returned. + **Authentication:** The driver supports the default [AWS SDK credentials](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html). -The IAM role or user that use the driver need the following permissions: +The IAM role or IAM user that use the driver need the following permissions: ```json { @@ -61,4 +68,5 @@ The IAM role or user that use the driver need the following permissions: - `table`: The name of the DynamoDB table. - `region`: The AWS region to use. - `credentials`: The AWS SDK credentials object. -- `attributes`: The key/value attributes mapping to table item attributes. +- `attributes`: The key, value and TTL attributes mapping to table item attributes. +- `expireIn`: The number of seconds to add to the current timestamp to set the TTL attribute. Set to 0 to disable it. diff --git a/src/drivers/aws-dynamodb.ts b/src/drivers/aws-dynamodb.ts index d31b82ed..8207cbfb 100644 --- a/src/drivers/aws-dynamodb.ts +++ b/src/drivers/aws-dynamodb.ts @@ -1,4 +1,4 @@ -import { createRequiredError, defineDriver } from "./utils"; +import { createError, createRequiredError, defineDriver } from "./utils"; import { DynamoDBClient } from "@aws-sdk/client-dynamodb"; import { DynamoDBDocumentClient, @@ -15,7 +15,9 @@ export interface DynamoDBStorageOptions { attributes?: { key?: string; value?: string; + ttl?: string; }; + expireIn?: number; } const DRIVER_NAME = "aws-dynamodb"; @@ -29,6 +31,7 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { opts.attributes = { key: "key", value: "value", + ttl: "ttl", }; } else { if (!opts.attributes.key) { @@ -38,6 +41,16 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { if (!opts.attributes.value) { opts.attributes.value = "value"; } + + if (!opts.attributes.ttl) { + opts.attributes.value = "ttl"; + } + } + + opts.expireIn = + opts.expireIn === undefined ? 0 : parseInt(`${opts.expireIn}`); + if (Number.isNaN(opts.expireIn) || opts.expireIn < 0) { + throw createError(DRIVER_NAME, "expireIn"); } let client; @@ -53,12 +66,16 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { return client; } - function createObject(key: string, value: any = null) { + function createObject(key: string, value: any = undefined, ttl: number = 0) { const obj = {}; obj[opts.attributes.key] = key; if (value) { obj[opts.attributes.value] = value; } + if (ttl > 0) { + const timestamp = Math.round(Date.now() / 1000); + obj[opts.attributes.ttl] = timestamp + ttl; + } return obj; } @@ -69,9 +86,18 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { Key: createObject(key), }) ); + if (!item) { - return null; + return undefined; } + + if (opts.expireIn > 0) { + const timestamp = Math.round(Date.now() / 1000); + if (timestamp > parseInt(item.ttl || 0)) { + return undefined; + } + } + return item[opts.attributes.value]; } @@ -79,7 +105,7 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { await getClient().send( new PutCommand({ TableName: opts.table, - Item: createObject(key, value), + Item: createObject(key, value, opts.expireIn), }) ); } @@ -94,14 +120,19 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { } async function listKeys(startKey = undefined) { - const { Items: items, LastEvaluatedKey: lastKey } = await getClient().send( + let { Items: items, LastEvaluatedKey: lastKey } = await getClient().send( new ScanCommand({ TableName: opts.table, ExclusiveStartKey: startKey, }) ); - let keys = items.map((item) => item[opts.attributes.key] || null); + if (opts.expireIn > 0) { + const timestamp = Math.round(Date.now() / 1000); + items = items.filter((item) => parseInt(item.ttl || 0) >= timestamp); + } + + let keys = items.map((item) => item[opts.attributes.key]); if (lastKey) { keys = keys.concat(await listKeys(lastKey)); } diff --git a/test/drivers/aws-dynamodb.test.ts b/test/drivers/aws-dynamodb.test.ts index d959747d..3b66073a 100644 --- a/test/drivers/aws-dynamodb.test.ts +++ b/test/drivers/aws-dynamodb.test.ts @@ -5,6 +5,7 @@ import { fromIni } from "@aws-sdk/credential-providers"; import { DynamoDBClient, CreateTableCommand, + UpdateTimeToLiveCommand, DeleteTableCommand, waitUntilTableExists, waitUntilTableNotExists, @@ -26,6 +27,7 @@ describe("drivers: aws-dynamodb", () => { attributes: { key: "key", value: "value", + ttl: "ttl", }, }; @@ -58,6 +60,16 @@ describe("drivers: aws-dynamodb", () => { { client, maxWaitTime: TABLE_OPERATIONS_TIMEOUT_SECONDS }, { TableName: options.table } ); + + await client.send( + new UpdateTimeToLiveCommand({ + TableName: options.table, + TimeToLiveSpecification: { + AttributeName: options.attributes?.ttl, + Enabled: true, + }, + }) + ); }, (TABLE_OPERATIONS_TIMEOUT_SECONDS + 2) * 1000); afterAll(async () => { From 97952b2f8384223bd268e903880a8c6d9ea6cf69 Mon Sep 17 00:00:00 2001 From: Fabio Gollinucci Date: Thu, 25 May 2023 18:05:42 +0200 Subject: [PATCH 03/13] docs(aws-dynamodb) improve documentation about initilization --- docs/content/6.drivers/aws-dynamodb.md | 44 ++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/docs/content/6.drivers/aws-dynamodb.md b/docs/content/6.drivers/aws-dynamodb.md index 68efc29f..b9a821ee 100644 --- a/docs/content/6.drivers/aws-dynamodb.md +++ b/docs/content/6.drivers/aws-dynamodb.md @@ -10,7 +10,25 @@ To use it, you will need to install `@aws-sdk/client-dynamodb` and `@aws-sdk/lib npm i @aws-sdk/client-dynamodb @aws-sdk/lib-dynamodb ``` -Usage: +Minimal usage: + +```js +import { createStorage } from "unstorage"; +import dynamoDbCacheDriver from "unstorage/drivers/aws-dynamodb"; + +const storage = createStorage({ + driver: dynamoDbCacheDriver({ + table: "my-persistent-storage", // required + region: "us-east-1", // optional, retrieved via environment variables + credentials: { // optional, retrieved by AWS SDK via environment variables + accessKeyId: "xxxxxxxxxx", // DO NOT HARD-CODE SECRETS + secretAccessKey: "xxxxxxxxxxxxxxxxxxxx", // DO NOT HARD-CODE SECRETS + }, + }), +}); +``` + +Persistent configuration usage: ```js import { createStorage } from "unstorage"; @@ -19,17 +37,29 @@ import dynamoDbCacheDriver from "unstorage/drivers/aws-dynamodb"; const storage = createStorage({ driver: dynamoDbCacheDriver({ table: "my-table-name", // required - region: "us-east-1", - credentials: { - accessKeyId: "xxxxxxxxxx", - secretAccessKey: "xxxxxxxxxxxxxxxxxxxx", + attributes: { + key: "key", // optional, configure attributes name + value: "value", // optional, configure attributes name }, + }), +}); +``` + +Temporary configurations: + +```js +import { createStorage } from "unstorage"; +import dynamoDbCacheDriver from "unstorage/drivers/aws-dynamodb"; + +const storage = createStorage({ + driver: dynamoDbCacheDriver({ + table: "my-table-name", // required attributes: { key: "key", value: "value", - ttl: "ttl", + ttl: "ttl", // optional, configure attributes name }, - expireIn: 300, // seconds + expireIn: 300, // optional, values in seconds or 0 to disable }), }); ``` From 75c0fa6d94142a4deed9d21b8422eb3aface1764 Mon Sep 17 00:00:00 2001 From: Fabio Gollinucci Date: Thu, 25 May 2023 18:45:10 +0200 Subject: [PATCH 04/13] chore(aws-dynamodb) improve tests --- docs/content/6.drivers/aws-dynamodb.md | 3 +- src/drivers/aws-dynamodb.ts | 14 +++--- test/drivers/aws-dynamodb.test.ts | 60 ++++++++++++++++++++++---- 3 files changed, 62 insertions(+), 15 deletions(-) diff --git a/docs/content/6.drivers/aws-dynamodb.md b/docs/content/6.drivers/aws-dynamodb.md index b9a821ee..0da931a6 100644 --- a/docs/content/6.drivers/aws-dynamodb.md +++ b/docs/content/6.drivers/aws-dynamodb.md @@ -20,7 +20,8 @@ const storage = createStorage({ driver: dynamoDbCacheDriver({ table: "my-persistent-storage", // required region: "us-east-1", // optional, retrieved via environment variables - credentials: { // optional, retrieved by AWS SDK via environment variables + credentials: { + // optional, retrieved by AWS SDK via environment variables accessKeyId: "xxxxxxxxxx", // DO NOT HARD-CODE SECRETS secretAccessKey: "xxxxxxxxxxxxxxxxxxxx", // DO NOT HARD-CODE SECRETS }, diff --git a/src/drivers/aws-dynamodb.ts b/src/drivers/aws-dynamodb.ts index 8207cbfb..2fea46f3 100644 --- a/src/drivers/aws-dynamodb.ts +++ b/src/drivers/aws-dynamodb.ts @@ -50,7 +50,7 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { opts.expireIn = opts.expireIn === undefined ? 0 : parseInt(`${opts.expireIn}`); if (Number.isNaN(opts.expireIn) || opts.expireIn < 0) { - throw createError(DRIVER_NAME, "expireIn"); + throw createError(DRIVER_NAME, "Invalid option `expireIn`."); } let client; @@ -66,6 +66,10 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { return client; } + function getTimestamp(): number { + return Math.round(Date.now() / 1000); + } + function createObject(key: string, value: any = undefined, ttl: number = 0) { const obj = {}; obj[opts.attributes.key] = key; @@ -88,13 +92,13 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { ); if (!item) { - return undefined; + return null; } if (opts.expireIn > 0) { - const timestamp = Math.round(Date.now() / 1000); + const timestamp = getTimestamp(); if (timestamp > parseInt(item.ttl || 0)) { - return undefined; + return null; } } @@ -128,7 +132,7 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { ); if (opts.expireIn > 0) { - const timestamp = Math.round(Date.now() / 1000); + const timestamp = getTimestamp(); items = items.filter((item) => parseInt(item.ttl || 0) >= timestamp); } diff --git a/test/drivers/aws-dynamodb.test.ts b/test/drivers/aws-dynamodb.test.ts index 3b66073a..9f7c4209 100644 --- a/test/drivers/aws-dynamodb.test.ts +++ b/test/drivers/aws-dynamodb.test.ts @@ -1,7 +1,7 @@ -import { describe, beforeAll, afterAll } from "vitest"; +import { describe, beforeAll, afterAll, expect, it } from "vitest"; import driver, { DynamoDBStorageOptions } from "../../src/drivers/aws-dynamodb"; import { testDriver } from "./utils"; -import { fromIni } from "@aws-sdk/credential-providers"; +import { fromIni, fromEnv } from "@aws-sdk/credential-providers"; import { DynamoDBClient, CreateTableCommand, @@ -9,17 +9,31 @@ import { DeleteTableCommand, waitUntilTableExists, waitUntilTableNotExists, + GetItemCommand, } from "@aws-sdk/client-dynamodb"; const TABLE_OPERATIONS_TIMEOUT_SECONDS = 30; // table need at lest 30s from creation to become available describe("drivers: aws-dynamodb", () => { + // Load AWS credentials + const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION; - const credentials = fromIni({ - profile: - process.env.AWS_PROFILE || process.env.AWS_DEFAULT_PROFILE || "default", + const profile = process.env.AWS_PROFILE || process.env.AWS_DEFAULT_PROFILE; + const credentials = profile + ? fromIni({ + profile: profile, + }) + : fromEnv(); + + // Init client for test purpose + + const client = new DynamoDBClient({ + region, + credentials, }); + // Setup test driver options + const options: DynamoDBStorageOptions = { table: "tmp-unstorage-tests", region, @@ -29,12 +43,10 @@ describe("drivers: aws-dynamodb", () => { value: "value", ttl: "ttl", }, + expireIn: 300, }; - const client = new DynamoDBClient({ - region: process.env.AWS_REGION, - credentials, - }); + // Test hooks beforeAll(async () => { await client.send( @@ -85,7 +97,37 @@ describe("drivers: aws-dynamodb", () => { ); }, (TABLE_OPERATIONS_TIMEOUT_SECONDS + 2) * 1000); + // Common tests + testDriver({ driver: driver(options), + additionalTests: (ctx) => { + // Additional tests + + it("should set TTL attribute on item", async () => { + const timestamp = Math.round(Date.now() / 1000); + + await ctx.storage.setItem("test-with-ttl", "ok"); + + const key = {}; + key[options.attributes?.key as string] = { + S: "test-with-ttl", + }; + + const { Item: item } = await client.send( + new GetItemCommand({ + TableName: options.table, + Key: key, + }) + ); + + expect(item).not.toBeUndefined(); + expect(item?.[options.attributes?.value as string].S).toBe("ok"); + expect(item?.[options.attributes?.ttl as string].N).not.toBeUndefined(); + expect( + parseInt(item?.[options.attributes?.ttl as string].N as string) + ).toBeGreaterThanOrEqual(timestamp + (options.expireIn || 0)); + }); + }, }); }); From c161eb64c02e70e3d0c11645bbcbd6a7fa91e9e9 Mon Sep 17 00:00:00 2001 From: Fabio Gollinucci Date: Thu, 25 May 2023 18:50:50 +0200 Subject: [PATCH 05/13] chore(aws-dynamodb) reset pnpm-lock --- pnpm-lock.yaml | 79 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7599ef28..8ae48be6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,9 +1,6 @@ lockfileVersion: '6.0' dependencies: - '@aws-sdk/credential-providers': - specifier: ^3.338.0 - version: 3.338.0 anymatch: specifier: ^3.1.3 version: 3.1.3 @@ -42,6 +39,9 @@ devDependencies: '@aws-sdk/client-dynamodb': specifier: ^3.338.0 version: 3.338.0 + '@aws-sdk/credential-providers': + specifier: ^3.338.0 + version: 3.338.0 '@aws-sdk/lib-dynamodb': specifier: ^3.338.0 version: 3.338.0(@aws-sdk/client-dynamodb@3.338.0)(@aws-sdk/smithy-client@3.338.0)(@aws-sdk/types@3.338.0) @@ -168,6 +168,7 @@ packages: resolution: {integrity: sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==} dependencies: tslib: 1.14.1 + dev: true /@aws-crypto/sha256-browser@3.0.0: resolution: {integrity: sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==} @@ -180,6 +181,7 @@ packages: '@aws-sdk/util-locate-window': 3.310.0 '@aws-sdk/util-utf8-browser': 3.259.0 tslib: 1.14.1 + dev: true /@aws-crypto/sha256-js@3.0.0: resolution: {integrity: sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==} @@ -187,11 +189,13 @@ packages: '@aws-crypto/util': 3.0.0 '@aws-sdk/types': 3.338.0 tslib: 1.14.1 + dev: true /@aws-crypto/supports-web-crypto@3.0.0: resolution: {integrity: sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==} dependencies: tslib: 1.14.1 + dev: true /@aws-crypto/util@3.0.0: resolution: {integrity: sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==} @@ -199,6 +203,7 @@ packages: '@aws-sdk/types': 3.338.0 '@aws-sdk/util-utf8-browser': 3.259.0 tslib: 1.14.1 + dev: true /@aws-sdk/abort-controller@3.338.0: resolution: {integrity: sha512-/yLI32+HwFNBRJ39jMXw+/cn3AnlCuJpQd7Ax4887g32Dgte5eyrfY8sJUOL6902BUmAq4oSRI5QeBXNplO0Xw==} @@ -206,6 +211,7 @@ packages: dependencies: '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/client-cognito-identity@3.338.0: resolution: {integrity: sha512-1gu9gXJwrxGGGMlBzmM4d8mkNjD1M8tWo+vmT/Aq1EMBxGef3eN0k6SyeIruj2Jns3olC6pjTIU8zb3vVBkh5Q==} @@ -249,6 +255,7 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt + dev: true /@aws-sdk/client-dynamodb@3.338.0: resolution: {integrity: sha512-m1tYFDdO2KxD9LvAEZEzixgfFpvNnXz5LHjCG/oVaGCPPMB91AyuyW4NkloCJ0gxmY4WqaHPvWMkwuJ4RJsU7Q==} @@ -336,6 +343,7 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt + dev: true /@aws-sdk/client-sso@3.338.0: resolution: {integrity: sha512-EglKsGlVph65PuFPKq1nGlxsY99XM2xHJaB1uX0bQEC94qrmS/M4a5kno5tiUnTWO1K+K4JBQiOxdGJs0GUS+w==} @@ -376,6 +384,7 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt + dev: true /@aws-sdk/client-sts@3.338.0: resolution: {integrity: sha512-FBHy/G7BAPX0CdEeeGYpoAnKXVCSIIkESLU2wF6x880z+U2IqiL48Fzoa5qoLaLPQaK/30P7ytznkqm4vd1OFw==} @@ -420,6 +429,7 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt + dev: true /@aws-sdk/config-resolver@3.338.0: resolution: {integrity: sha512-rB9WUaMfTB74Hd2mOiyPFR7Q1viT+w6SaDSR9SA1P8EeIg5H13FNdIKb736Z8/6QJhDj7whdyk1CTGV+DmXOOg==} @@ -429,6 +439,7 @@ packages: '@aws-sdk/util-config-provider': 3.310.0 '@aws-sdk/util-middleware': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/credential-provider-cognito-identity@3.338.0: resolution: {integrity: sha512-kKkBt1qCKx+HspbMq7kd5Yz3jWRW5N1Tegs4cGbTFJH9qMJTyQMoS9GNRcFfzgNEA9sfpHxeTnBbwBw6Ca4S9g==} @@ -440,6 +451,7 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt + dev: true /@aws-sdk/credential-provider-env@3.338.0: resolution: {integrity: sha512-j14vApy80tpk87C3x3uBf1caQsuR8RdQ8iOW830H/AOhsa88XaZIB/NQSX7exaIKZa2RU0Vv2wIlGAA8ko7J6g==} @@ -448,6 +460,7 @@ packages: '@aws-sdk/property-provider': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/credential-provider-imds@3.338.0: resolution: {integrity: sha512-qsqeywYfJevg5pgUUUBmm7pK1bckVrl091PZB2IliFdQVnDvI5GFLf4B0oZqjaLAzPG1gVtxRvqIve+tnP/+xA==} @@ -458,6 +471,7 @@ packages: '@aws-sdk/types': 3.338.0 '@aws-sdk/url-parser': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/credential-provider-ini@3.338.0: resolution: {integrity: sha512-UhgYgymT9sJiRm0peqP5EvtR4dXiS2Q2AuFgDUjBvDz8JaZlqafsIS4cfyGwTHV/xY6cdiMu5rCTe8hTyXsukQ==} @@ -474,6 +488,7 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt + dev: true /@aws-sdk/credential-provider-node@3.338.0: resolution: {integrity: sha512-nZjaMRxJqX0EXMV9LA5IbRQI1pDGGZiPYX2KDfZ1Y9Gc1Y/vIZhHKOHGb1uKMAonlR076CsXlev4/tjC8SGGuw==} @@ -491,6 +506,7 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt + dev: true /@aws-sdk/credential-provider-process@3.338.0: resolution: {integrity: sha512-5I1EgJxFFEg8xel2kInMpkdBKajUut0hR2fBajqCmK7Pflu8s0I2NKDots9a3YJagNrFJq38+EzoDcUvRrd2dg==} @@ -500,6 +516,7 @@ packages: '@aws-sdk/shared-ini-file-loader': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/credential-provider-sso@3.338.0: resolution: {integrity: sha512-fpzYHK17iF/uFkrm4cLg/utDVKSBTWNjAiNlE3GF6CaixBCwc0QBLKHk2nG4d1ZZeMVCbIUMS7eoqfR0LYc/yw==} @@ -513,6 +530,7 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt + dev: true /@aws-sdk/credential-provider-web-identity@3.338.0: resolution: {integrity: sha512-kjT/P18jM1icwjYwr8wfY//T8lv2s81ms7OC7vgiSqckmQOxpVkdsep9d44ymSUXwopmotFP7M9gGnEHS6HwAA==} @@ -521,6 +539,7 @@ packages: '@aws-sdk/property-provider': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/credential-providers@3.338.0: resolution: {integrity: sha512-QQkWsR3fyq3N5eTvyKLgk1IO45SEM5+zIDqGqchG74AAhAzTHpiVZ3AOBZckaIAXKyHU3Fgy3gt/u+fdXC4xyw==} @@ -543,6 +562,7 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt + dev: true /@aws-sdk/endpoint-cache@3.310.0: resolution: {integrity: sha512-y3wipforet41EDTI0vnzxILqwAGll1KfI5qcdX9pXF/WF1f+3frcOtPiWtQEZQpy4czRogKm3BHo70QBYAZxlQ==} @@ -560,6 +580,7 @@ packages: '@aws-sdk/types': 3.338.0 '@aws-sdk/util-base64': 3.310.0 tslib: 2.5.2 + dev: true /@aws-sdk/hash-node@3.338.0: resolution: {integrity: sha512-udveX3ZRO1oUbyBTQH0LJ8Ika7uk0pHuXrqapdi66GGRJB50IhmOg372zUEwZjDB7DZYXfGTCuAj2OoEalgpBA==} @@ -569,18 +590,21 @@ packages: '@aws-sdk/util-buffer-from': 3.310.0 '@aws-sdk/util-utf8': 3.310.0 tslib: 2.5.2 + dev: true /@aws-sdk/invalid-dependency@3.338.0: resolution: {integrity: sha512-m6r1fTTGSl0V6l8Z+Ii4Ei8VFpDmu0AT6A59ZhJaMZgxf925ywuCPydyDW9ZqTLE0e7CgxhEHEsH1+HzpVuHTw==} dependencies: '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/is-array-buffer@3.310.0: resolution: {integrity: sha512-urnbcCR+h9NWUnmOtet/s4ghvzsidFmspfhYaHAmSRdy9yDjdjBJMFjjsn85A1ODUktztm+cVncXjQ38WCMjMQ==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 + dev: true /@aws-sdk/lib-dynamodb@3.338.0(@aws-sdk/client-dynamodb@3.338.0)(@aws-sdk/smithy-client@3.338.0)(@aws-sdk/types@3.338.0): resolution: {integrity: sha512-eJTwzRrfKOzMBHKWOtYnBrw26B/oQEE5xwMQbRI2fHsOINaHbbBwDE/dE0da6IHXr07elf+R2sPkZmj+E/NyoQ==} @@ -604,6 +628,7 @@ packages: '@aws-sdk/protocol-http': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/middleware-endpoint-discovery@3.338.0: resolution: {integrity: sha512-LD2iQ7h65Q89Ef2rEo/tJqSsj6V4UpLjlbbnL7PkDSzOJNCIgRItH1nEXEHL6g94Kef5MQEzAKEg5W/H0ygJ3Q==} @@ -624,6 +649,7 @@ packages: '@aws-sdk/url-parser': 3.338.0 '@aws-sdk/util-middleware': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/middleware-host-header@3.338.0: resolution: {integrity: sha512-k3C7oppkrqeKrAJt9XIl45SdELtnph9BF0QypjyRfT5MNEDnMMsQkc6xy3ZMqG5dWQq6B2l8C+JL7pOvkSQP3w==} @@ -632,6 +658,7 @@ packages: '@aws-sdk/protocol-http': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/middleware-logger@3.338.0: resolution: {integrity: sha512-btj9U0Xovq/UAu3Ur4lAfF7Q3DvvwJ/0UUWsI6GgSzzqSOFgKCz7hCP2GZIT8aXEA5hJOpBOEMkNMjWPNa91Hg==} @@ -639,6 +666,7 @@ packages: dependencies: '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/middleware-recursion-detection@3.338.0: resolution: {integrity: sha512-fu5KwiHHSqC8KTQH6xdJ9+dua4gQcXSFLE5fVsergqd0uVdsmhiI+IDfW6QNwF/lmCqnoKDkpeasuB98eG2tow==} @@ -647,6 +675,7 @@ packages: '@aws-sdk/protocol-http': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/middleware-retry@3.338.0: resolution: {integrity: sha512-nw1oPFkB7TdDG4Vlz2Td47ft/2Gmx1bA18QfE9K1mMWZ4nnoAL8xnHbowlTfHo62+BbFCAPu53PzDUCncBL0iw==} @@ -659,6 +688,7 @@ packages: '@aws-sdk/util-retry': 3.338.0 tslib: 2.5.2 uuid: 8.3.2 + dev: true /@aws-sdk/middleware-sdk-sts@3.338.0: resolution: {integrity: sha512-aZ8eFVaot8oYQri1wOesrA3gLizeAHtlA/ELlqxoGDJtO011J4/hTHTn0iJGbktaCvc1L3TF6mgOsgXpudYqMg==} @@ -667,6 +697,7 @@ packages: '@aws-sdk/middleware-signing': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/middleware-serde@3.338.0: resolution: {integrity: sha512-AabRLrE6sk9tqQlQ7z3kn4gTHNN7Anjk/AM0ZEu96WcWjedcpgM1vVpKTBE7vjnxcTRNq0CEM3GLtQqaZ7/HjQ==} @@ -674,6 +705,7 @@ packages: dependencies: '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/middleware-signing@3.338.0: resolution: {integrity: sha512-AprhhShMF75mOx80SABujLwrU/w2uHQIvWd6aF3BsE5JRI3uQZRqspfjFCaK52HNLQPj3sCQUw1GeiZJ8GyWCw==} @@ -685,12 +717,14 @@ packages: '@aws-sdk/types': 3.338.0 '@aws-sdk/util-middleware': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/middleware-stack@3.338.0: resolution: {integrity: sha512-9zXyiklX9AK9ZIXuIPzWzz2vevBEcnBs9UNIxiHl4NBZ8d8oyTvaES1PtFuwL6f7ANSZ9EGVQ2rdTTnMNxMI1A==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 + dev: true /@aws-sdk/middleware-user-agent@3.338.0: resolution: {integrity: sha512-DMqODOsDMFMPcDw2Ya6a0i34AhaBDRpp3vJ+FK3zPxUIsv6iHA+XqEcXLOxROLLoydoyxus7k2U+EWibLZrFbQ==} @@ -700,6 +734,7 @@ packages: '@aws-sdk/types': 3.338.0 '@aws-sdk/util-endpoints': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/node-config-provider@3.338.0: resolution: {integrity: sha512-YO7yWg3ipnUI5u6D+Zn2NUpjj5krwc8zNWeY79ULVIp9g7faqGX3xMSjeRSrpZ83s5jg1dOm/+bB0gw7mCrRCw==} @@ -709,6 +744,7 @@ packages: '@aws-sdk/shared-ini-file-loader': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/node-http-handler@3.338.0: resolution: {integrity: sha512-V1BLzCruiv45tJ0vXjiamY8LncIsUFsXYJGDupomFYhWRN8L1MUB9f2vdKn5X3wXn/yKrluwTmNaryrIqd9akA==} @@ -719,6 +755,7 @@ packages: '@aws-sdk/querystring-builder': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/property-provider@3.338.0: resolution: {integrity: sha512-mC+ZJ738ipif6ZkH59gcipozYj1FOfpXr9pGVCA2hJGLDdaBwI2Jfpb2qCqbsTNtoCjBuIy+sQHGmUHyclgYHg==} @@ -726,6 +763,7 @@ packages: dependencies: '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/protocol-http@3.338.0: resolution: {integrity: sha512-JX03Q2gshdzOWtA/07kdpk0hqeOrOfwuF8TB97g66VCcIopYQkCeNH1zzkWu+RsGxfSlzQ7up+ZM6sclYXyB1A==} @@ -733,6 +771,7 @@ packages: dependencies: '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/querystring-builder@3.338.0: resolution: {integrity: sha512-IB3YhO93Htwt2SxJx4VWsN57Rt1KEsvZ6PbneO4bcS96E04BlfBujYMZ+QxEM3EJxorhpkwbI2QnI12IjD8FhA==} @@ -741,6 +780,7 @@ packages: '@aws-sdk/types': 3.338.0 '@aws-sdk/util-uri-escape': 3.310.0 tslib: 2.5.2 + dev: true /@aws-sdk/querystring-parser@3.338.0: resolution: {integrity: sha512-vtI8Gqx4yj0BZlWonRMgLz68sHt5H48HN+ClnY+fDDB/8KLnCuwZ3TGKmYIbYbshL9wjJz0A9aLzuC6nPQ5JKw==} @@ -748,10 +788,12 @@ packages: dependencies: '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/service-error-classification@3.338.0: resolution: {integrity: sha512-BJFr2mx/N3NbycGTlMMGRBc0tGcHXHEbMPy1H2RbejzL23zh27MchaL1WAK9SvwVMKS29hSDbhkuVR2ABRjerA==} engines: {node: '>=14.0.0'} + dev: true /@aws-sdk/shared-ini-file-loader@3.338.0: resolution: {integrity: sha512-MA1Sp97LFlOXcUaXgo47j86IsPRWYq1V/JqR+uu0zofZw4Xlt7Y6F+mmnDHvuuMy6R2ltzjXSwgrrW3k0bxFPA==} @@ -759,6 +801,7 @@ packages: dependencies: '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/signature-v4@3.338.0: resolution: {integrity: sha512-EwKTe/8Iwab/v0eo27w7DRYlqp9wEZEhuRfOMwTikUVH6iuTnW6AXjcIUfcRYBRbx2zqnRSiMAZkjN6ZFYm0bQ==} @@ -771,6 +814,7 @@ packages: '@aws-sdk/util-uri-escape': 3.310.0 '@aws-sdk/util-utf8': 3.310.0 tslib: 2.5.2 + dev: true /@aws-sdk/smithy-client@3.338.0: resolution: {integrity: sha512-IpFLdLG8GwaiFdqVXf+WyU47Hfa2BMIupAU6iSkE2ZO0lBdg+efn/BBwis5WbBNTDCaaU0xH9y68SmnqqtD7pA==} @@ -779,6 +823,7 @@ packages: '@aws-sdk/middleware-stack': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/token-providers@3.338.0: resolution: {integrity: sha512-wuiEGcWiMeq5N68M489i2iGYcCad9p1btNEOFgus+JO3DRSA6HZXizLI1wqfbUm5Ei8512AvUKB6N8PMzahQsg==} @@ -791,12 +836,14 @@ packages: tslib: 2.5.2 transitivePeerDependencies: - aws-crt + dev: true /@aws-sdk/types@3.338.0: resolution: {integrity: sha512-hrNK15o+EObLrl9oWOyxJN2dwjgbdBMGolLEVP/wR/+M9ojHgk/x1kMsCVcV82a8Vgdtqx1TyOC3UugUPT0+NA==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 + dev: true /@aws-sdk/url-parser@3.338.0: resolution: {integrity: sha512-x8a5swfZ6iWJZEA8rm99OKQ1A6xhWPP1taQUzoPavGCzPAOqyc8cd0FcXYMxvtXb3FeBhGaI8tiGKvelJro0+A==} @@ -804,6 +851,7 @@ packages: '@aws-sdk/querystring-parser': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/util-base64@3.310.0: resolution: {integrity: sha512-v3+HBKQvqgdzcbL+pFswlx5HQsd9L6ZTlyPVL2LS9nNXnCcR3XgGz9jRskikRUuUvUXtkSG1J88GAOnJ/apTPg==} @@ -811,17 +859,20 @@ packages: dependencies: '@aws-sdk/util-buffer-from': 3.310.0 tslib: 2.5.2 + dev: true /@aws-sdk/util-body-length-browser@3.310.0: resolution: {integrity: sha512-sxsC3lPBGfpHtNTUoGXMQXLwjmR0zVpx0rSvzTPAuoVILVsp5AU/w5FphNPxD5OVIjNbZv9KsKTuvNTiZjDp9g==} dependencies: tslib: 2.5.2 + dev: true /@aws-sdk/util-body-length-node@3.310.0: resolution: {integrity: sha512-2tqGXdyKhyA6w4zz7UPoS8Ip+7sayOg9BwHNidiGm2ikbDxm1YrCfYXvCBdwaJxa4hJfRVz+aL9e+d3GqPI9pQ==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 + dev: true /@aws-sdk/util-buffer-from@3.310.0: resolution: {integrity: sha512-i6LVeXFtGih5Zs8enLrt+ExXY92QV25jtEnTKHsmlFqFAuL3VBeod6boeMXkN2p9lbSVVQ1sAOOYZOHYbYkntw==} @@ -829,12 +880,14 @@ packages: dependencies: '@aws-sdk/is-array-buffer': 3.310.0 tslib: 2.5.2 + dev: true /@aws-sdk/util-config-provider@3.310.0: resolution: {integrity: sha512-xIBaYo8dwiojCw8vnUcIL4Z5tyfb1v3yjqyJKJWV/dqKUFOOS0U591plmXbM+M/QkXyML3ypon1f8+BoaDExrg==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 + dev: true /@aws-sdk/util-defaults-mode-browser@3.338.0: resolution: {integrity: sha512-Zfr5c7JKMJTfb7z+hgd0ioU5iw+wId6Cppc5V1HpZuS2YY4Mn3aJIixzyzhIoCzbmk/yIkf96981epM9eo3/TA==} @@ -844,6 +897,7 @@ packages: '@aws-sdk/types': 3.338.0 bowser: 2.11.0 tslib: 2.5.2 + dev: true /@aws-sdk/util-defaults-mode-node@3.338.0: resolution: {integrity: sha512-DFM3BSpSetshZTgTjueCkAYZWS0tn5zl7SjkSpFhWQZ8Tt/Df3/DEjcPvxzmC/5vgYSUXNsqcI7lLAJk9aGZAA==} @@ -855,6 +909,7 @@ packages: '@aws-sdk/property-provider': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/util-dynamodb@3.338.0: resolution: {integrity: sha512-hQzumWnMtFUpJRkLNR+oa1Ip9OGMVyI0hzO5pST8L66M9c+KCu75fLWj3KqE4pt/dIPUfFaeL4/ETEirydm5JA==} @@ -869,24 +924,28 @@ packages: dependencies: '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/util-hex-encoding@3.310.0: resolution: {integrity: sha512-sVN7mcCCDSJ67pI1ZMtk84SKGqyix6/0A1Ab163YKn+lFBQRMKexleZzpYzNGxYzmQS6VanP/cfU7NiLQOaSfA==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 + dev: true /@aws-sdk/util-locate-window@3.310.0: resolution: {integrity: sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 + dev: true /@aws-sdk/util-middleware@3.338.0: resolution: {integrity: sha512-oQuAmhi16HWEqVa+Nq4VD4Ymet9vS+uiW92reaagQrW2QFjAgJW9A6pU0PcIHF9sWY1iDKeNdV5b9odQ45PDJA==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 + dev: true /@aws-sdk/util-retry@3.338.0: resolution: {integrity: sha512-diR6M3gJgSgBg/87L2e8iF8urG+LOW9ZGWxhntYpYX4uhiIjwNgUPUa993553C8GIOZDHez5X9ExU4asYGQ71Q==} @@ -894,12 +953,14 @@ packages: dependencies: '@aws-sdk/service-error-classification': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/util-uri-escape@3.310.0: resolution: {integrity: sha512-drzt+aB2qo2LgtDoiy/3sVG8w63cgLkqFIa2NFlGpUgHFWTXkqtbgf4L5QdjRGKWhmZsnqkbtL7vkSWEcYDJ4Q==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 + dev: true /@aws-sdk/util-user-agent-browser@3.338.0: resolution: {integrity: sha512-3e8D+SOtOQEtRtksOEF7EC26xPkuY6YK6biLgdtvR9JspK96rHk5eX1HEJeBJJqbxhyPaxpIw+OhWhnsrUS3hA==} @@ -907,6 +968,7 @@ packages: '@aws-sdk/types': 3.338.0 bowser: 2.11.0 tslib: 2.5.2 + dev: true /@aws-sdk/util-user-agent-node@3.338.0: resolution: {integrity: sha512-rc+bC5KM9h25urRc+MXuViJkJ+qYG2NlCRw6xm2lSIvHFJTUjH1ZMO3mqNDYkGnQRbj0mmrVe+N77TJZGf3Q2Q==} @@ -920,11 +982,13 @@ packages: '@aws-sdk/node-config-provider': 3.338.0 '@aws-sdk/types': 3.338.0 tslib: 2.5.2 + dev: true /@aws-sdk/util-utf8-browser@3.259.0: resolution: {integrity: sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==} dependencies: tslib: 2.5.2 + dev: true /@aws-sdk/util-utf8@3.310.0: resolution: {integrity: sha512-DnLfFT8uCO22uOJc0pt0DsSNau1GTisngBCDw8jQuWT5CqogMJu4b/uXmwEqfj8B3GX6Xsz8zOd6JpRlPftQoA==} @@ -932,6 +996,7 @@ packages: dependencies: '@aws-sdk/util-buffer-from': 3.310.0 tslib: 2.5.2 + dev: true /@aws-sdk/util-waiter@3.338.0: resolution: {integrity: sha512-15yWYJo/M4VDpZjlXgQDM4Du8UjX33eIVPJDrOmn/u+UrD6QUXoBuLXKns0uAMUTPFacBGZ0NwMywxieq0g11Q==} @@ -1975,12 +2040,14 @@ packages: dependencies: '@smithy/types': 1.0.0 tslib: 2.5.2 + dev: true /@smithy/types@1.0.0: resolution: {integrity: sha512-kc1m5wPBHQCTixwuaOh9vnak/iJm21DrSf9UK6yDE5S3mQQ4u11pqAUiKWnlrZnYkeLfAI9UEHj9OaMT1v5Umg==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.5.2 + dev: true /@tootallnate/once@2.0.0: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} @@ -2710,6 +2777,7 @@ packages: /bowser@2.11.0: resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} + dev: true /bplist-parser@0.2.0: resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==} @@ -4008,6 +4076,7 @@ packages: hasBin: true dependencies: strnum: 1.0.5 + dev: true /fast-xml-parser@4.2.2: resolution: {integrity: sha512-DLzIPtQqmvmdq3VUKR7T6omPK/VCRNqgFlGtbESfyhcH2R4I8EzK1/K6E8PkRCK2EabWrUHK32NjYRbEFnnz0Q==} @@ -6689,6 +6758,7 @@ packages: /strnum@1.0.5: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} + dev: true /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} @@ -6897,9 +6967,11 @@ packages: /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: true /tslib@2.5.2: resolution: {integrity: sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==} + dev: true /tsutils@3.21.0(typescript@5.0.4): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} @@ -7124,6 +7196,7 @@ packages: /uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true + dev: true /uuid@9.0.0: resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} From 5da5b15dc5f1912f2184cf13caf68bcfd364152f Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Mon, 7 Aug 2023 22:10:02 +0200 Subject: [PATCH 06/13] fomat code --- test/drivers/aws-dynamodb.test.ts | 100 ++++++++++++++++-------------- 1 file changed, 53 insertions(+), 47 deletions(-) diff --git a/test/drivers/aws-dynamodb.test.ts b/test/drivers/aws-dynamodb.test.ts index 9f7c4209..08044ff2 100644 --- a/test/drivers/aws-dynamodb.test.ts +++ b/test/drivers/aws-dynamodb.test.ts @@ -48,54 +48,60 @@ describe("drivers: aws-dynamodb", () => { // Test hooks - beforeAll(async () => { - await client.send( - new CreateTableCommand({ - TableName: options.table, - BillingMode: "PAY_PER_REQUEST", - AttributeDefinitions: [ - { - AttributeName: options.attributes?.key, - AttributeType: "S", + beforeAll( + async () => { + await client.send( + new CreateTableCommand({ + TableName: options.table, + BillingMode: "PAY_PER_REQUEST", + AttributeDefinitions: [ + { + AttributeName: options.attributes?.key, + AttributeType: "S", + }, + ], + KeySchema: [ + { + AttributeName: options.attributes?.key, + KeyType: "HASH", + }, + ], + }) + ); + + await waitUntilTableExists( + { client, maxWaitTime: TABLE_OPERATIONS_TIMEOUT_SECONDS }, + { TableName: options.table } + ); + + await client.send( + new UpdateTimeToLiveCommand({ + TableName: options.table, + TimeToLiveSpecification: { + AttributeName: options.attributes?.ttl, + Enabled: true, }, - ], - KeySchema: [ - { - AttributeName: options.attributes?.key, - KeyType: "HASH", - }, - ], - }) - ); - - await waitUntilTableExists( - { client, maxWaitTime: TABLE_OPERATIONS_TIMEOUT_SECONDS }, - { TableName: options.table } - ); - - await client.send( - new UpdateTimeToLiveCommand({ - TableName: options.table, - TimeToLiveSpecification: { - AttributeName: options.attributes?.ttl, - Enabled: true, - }, - }) - ); - }, (TABLE_OPERATIONS_TIMEOUT_SECONDS + 2) * 1000); - - afterAll(async () => { - await client.send( - new DeleteTableCommand({ - TableName: options.table, - }) - ); - - await waitUntilTableNotExists( - { client, maxWaitTime: TABLE_OPERATIONS_TIMEOUT_SECONDS }, - { TableName: options.table } - ); - }, (TABLE_OPERATIONS_TIMEOUT_SECONDS + 2) * 1000); + }) + ); + }, + (TABLE_OPERATIONS_TIMEOUT_SECONDS + 2) * 1000 + ); + + afterAll( + async () => { + await client.send( + new DeleteTableCommand({ + TableName: options.table, + }) + ); + + await waitUntilTableNotExists( + { client, maxWaitTime: TABLE_OPERATIONS_TIMEOUT_SECONDS }, + { TableName: options.table } + ); + }, + (TABLE_OPERATIONS_TIMEOUT_SECONDS + 2) * 1000 + ); // Common tests From 4104258286eb1c98e50dc8f9177e0bb4667d8dee Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Mon, 7 Aug 2023 22:11:45 +0200 Subject: [PATCH 07/13] update docs --- docs/content/6.drivers/aws-dynamodb.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/content/6.drivers/aws-dynamodb.md b/docs/content/6.drivers/aws-dynamodb.md index 0da931a6..0d884e9d 100644 --- a/docs/content/6.drivers/aws-dynamodb.md +++ b/docs/content/6.drivers/aws-dynamodb.md @@ -7,17 +7,17 @@ This driver uses the DynamoDB table as a key value store. By default it uses the To use it, you will need to install `@aws-sdk/client-dynamodb` and `@aws-sdk/lib-dynamodb` in your project: ```bash -npm i @aws-sdk/client-dynamodb @aws-sdk/lib-dynamodb +npm i -D @aws-sdk/client-dynamodb @aws-sdk/lib-dynamodb ``` -Minimal usage: +**Usage:** ```js import { createStorage } from "unstorage"; -import dynamoDbCacheDriver from "unstorage/drivers/aws-dynamodb"; +import dynamoDBDriver from "unstorage/drivers/aws-dynamodb"; const storage = createStorage({ - driver: dynamoDbCacheDriver({ + driver: dynamoDBDriver({ table: "my-persistent-storage", // required region: "us-east-1", // optional, retrieved via environment variables credentials: { @@ -33,10 +33,10 @@ Persistent configuration usage: ```js import { createStorage } from "unstorage"; -import dynamoDbCacheDriver from "unstorage/drivers/aws-dynamodb"; +import dynamoDBDriver from "unstorage/drivers/aws-dynamodb"; const storage = createStorage({ - driver: dynamoDbCacheDriver({ + driver: dynamoDBDriver({ table: "my-table-name", // required attributes: { key: "key", // optional, configure attributes name From 4453839315047eb6d9e45249842af58c57c26e43 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Mon, 7 Aug 2023 22:18:37 +0200 Subject: [PATCH 08/13] updates --- package.json | 6 +++++ src/drivers/aws-dynamodb.ts | 53 +++++++++++++------------------------ 2 files changed, 25 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index cb0dab3f..49f992fa 100644 --- a/package.json +++ b/package.json @@ -135,6 +135,12 @@ }, "@vercel/kv": { "optional": true + }, + "@aws-sdk/client-dynamodb": { + "optional": true + }, + "@aws-sdk/lib-dynamodb": { + "optional": true } }, "packageManager": "pnpm@8.6.7" diff --git a/src/drivers/aws-dynamodb.ts b/src/drivers/aws-dynamodb.ts index 2fea46f3..f20b2113 100644 --- a/src/drivers/aws-dynamodb.ts +++ b/src/drivers/aws-dynamodb.ts @@ -23,38 +23,23 @@ export interface DynamoDBStorageOptions { const DRIVER_NAME = "aws-dynamodb"; export default defineDriver((opts: DynamoDBStorageOptions) => { - if (!opts.table) { - throw createRequiredError(DRIVER_NAME, "table"); - } + const expireIn = parseInt(String(opts.expireIn)) || 0; - if (!opts.attributes) { - opts.attributes = { - key: "key", - value: "value", - ttl: "ttl", - }; - } else { - if (!opts.attributes.key) { - opts.attributes.key = "key"; - } + const attributes = { + key: "key", + value: "value", + ttl: "ttl", + ...opts.attributes, + }; - if (!opts.attributes.value) { - opts.attributes.value = "value"; + let client: DynamoDBDocumentClient; + function getClient(): DynamoDBDocumentClient { + if (!opts.table) { + throw createRequiredError(DRIVER_NAME, "table"); } - - if (!opts.attributes.ttl) { - opts.attributes.value = "ttl"; + if (Number.isNaN(opts.expireIn) || expireIn < 0) { + throw createError(DRIVER_NAME, "Invalid option `expireIn`."); } - } - - opts.expireIn = - opts.expireIn === undefined ? 0 : parseInt(`${opts.expireIn}`); - if (Number.isNaN(opts.expireIn) || opts.expireIn < 0) { - throw createError(DRIVER_NAME, "Invalid option `expireIn`."); - } - - let client; - function getClient(): DynamoDBDocumentClient { if (!client) { client = DynamoDBDocumentClient.from( new DynamoDBClient({ @@ -71,14 +56,14 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { } function createObject(key: string, value: any = undefined, ttl: number = 0) { - const obj = {}; - obj[opts.attributes.key] = key; + const obj: Record = {}; + obj[attributes.key] = key; if (value) { - obj[opts.attributes.value] = value; + obj[attributes.value] = value; } if (ttl > 0) { const timestamp = Math.round(Date.now() / 1000); - obj[opts.attributes.ttl] = timestamp + ttl; + obj[attributes.ttl] = timestamp + ttl; } return obj; } @@ -95,14 +80,14 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { return null; } - if (opts.expireIn > 0) { + if (expireIn > 0) { const timestamp = getTimestamp(); if (timestamp > parseInt(item.ttl || 0)) { return null; } } - return item[opts.attributes.value]; + return item[attributes.value]; } async function putItemValue(key: string, value: any): Promise { From 1eaffacc9f20817b7e1793532d7ad0442a10c473 Mon Sep 17 00:00:00 2001 From: Fabio Gollinucci Date: Mon, 28 Aug 2023 10:12:56 +0200 Subject: [PATCH 09/13] chore(aws-dynamodb): add optional driver param for dynamo client override --- src/drivers/aws-dynamodb.ts | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/drivers/aws-dynamodb.ts b/src/drivers/aws-dynamodb.ts index f20b2113..ccaa8b3b 100644 --- a/src/drivers/aws-dynamodb.ts +++ b/src/drivers/aws-dynamodb.ts @@ -18,6 +18,7 @@ export interface DynamoDBStorageOptions { ttl?: string; }; expireIn?: number; + client?: DynamoDBDocumentClient; } const DRIVER_NAME = "aws-dynamodb"; @@ -41,12 +42,14 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { throw createError(DRIVER_NAME, "Invalid option `expireIn`."); } if (!client) { - client = DynamoDBDocumentClient.from( - new DynamoDBClient({ - region: opts.region, - credentials: opts.credentials, - }) - ); + client = + opts.client || + DynamoDBDocumentClient.from( + new DynamoDBClient({ + region: opts.region, + credentials: opts.credentials, + }) + ); } return client; } @@ -108,7 +111,7 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { ); } - async function listKeys(startKey = undefined) { + async function listKeys(startKey: any = undefined) { let { Items: items, LastEvaluatedKey: lastKey } = await getClient().send( new ScanCommand({ TableName: opts.table, @@ -116,12 +119,14 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { }) ); - if (opts.expireIn > 0) { + items = items || []; + + if (expireIn > 0) { const timestamp = getTimestamp(); items = items.filter((item) => parseInt(item.ttl || 0) >= timestamp); } - let keys = items.map((item) => item[opts.attributes.key]); + let keys = items.map((item) => item[attributes.key]); if (lastKey) { keys = keys.concat(await listKeys(lastKey)); } From 63e41ac2caa2415999d0b94a43ea388ea562cee5 Mon Sep 17 00:00:00 2001 From: Fabio Gollinucci Date: Mon, 28 Aug 2023 10:13:43 +0200 Subject: [PATCH 10/13] test: mock DynamoDB API call --- package.json | 11 +- pnpm-lock.yaml | 1627 ++++++++++------------------- test/drivers/aws-dynamodb.test.ts | 156 +-- 3 files changed, 571 insertions(+), 1223 deletions(-) diff --git a/package.json b/package.json index 49f992fa..15efea4c 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "prepack": "pnpm build", "release": "pnpm test && changelogen --release && git push --follow-tags && pnpm publish", "test": "pnpm lint && pnpm test:types && vitest run --coverage", + "test:dynamodb": "vitest run test/drivers/aws-dynamodb.test.ts", "test:types": "tsc --noEmit --skipLibCheck", "unstorage": "pnpm jiti src/cli" }, @@ -56,9 +57,8 @@ "ufo": "^1.2.0" }, "devDependencies": { - "@aws-sdk/client-dynamodb": "^3.338.0", - "@aws-sdk/credential-providers": "^3.338.0", - "@aws-sdk/lib-dynamodb": "^3.338.0", + "@aws-sdk/client-dynamodb": "^3.398.0", + "@aws-sdk/lib-dynamodb": "^3.398.0", "@azure/app-configuration": "^1.4.1", "@azure/cosmos": "^3.17.3", "@azure/data-tables": "^13.2.2", @@ -76,6 +76,7 @@ "@vitejs/plugin-vue": "^4.2.3", "@vitest/coverage-v8": "^0.34.1", "@vue/compiler-sfc": "^3.3.4", + "aws-sdk-client-mock": "^3.0.0", "azurite": "^3.25.1", "changelogen": "^0.5.4", "eslint": "^8.46.0", @@ -96,8 +97,8 @@ "vue": "^3.3.4" }, "peerDependencies": { - "@aws-sdk/client-dynamodb": "^3.338.0", - "@aws-sdk/lib-dynamodb": "^3.338.0", + "@aws-sdk/client-dynamodb": "^3.398.0", + "@aws-sdk/lib-dynamodb": "^3.398.0", "@azure/app-configuration": "^1.4.1", "@azure/cosmos": "^3.17.3", "@azure/data-tables": "^13.2.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ac74b241..157fe1c7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,9 +1,5 @@ lockfileVersion: '6.0' -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - dependencies: anymatch: specifier: ^3.1.3 @@ -41,14 +37,11 @@ dependencies: devDependencies: '@aws-sdk/client-dynamodb': - specifier: ^3.338.0 - version: 3.338.0 - '@aws-sdk/credential-providers': - specifier: ^3.338.0 - version: 3.386.0 + specifier: ^3.398.0 + version: 3.398.0 '@aws-sdk/lib-dynamodb': - specifier: ^3.338.0 - version: 3.338.0(@aws-sdk/client-dynamodb@3.338.0)(@aws-sdk/smithy-client@3.374.0)(@aws-sdk/types@3.378.0) + specifier: ^3.398.0 + version: 3.398.0(@aws-sdk/client-dynamodb@3.398.0) '@azure/app-configuration': specifier: ^1.4.1 version: 1.4.1 @@ -100,6 +93,9 @@ devDependencies: '@vue/compiler-sfc': specifier: ^3.3.4 version: 3.3.4 + aws-sdk-client-mock: + specifier: ^3.0.0 + version: 3.0.0 azurite: specifier: ^3.25.1 version: 3.25.1 @@ -126,7 +122,7 @@ devDependencies: version: 0.41.0 mongodb: specifier: ^5.7.0 - version: 5.7.0(@aws-sdk/credential-providers@3.386.0) + version: 5.7.0 mongodb-memory-server: specifier: ^8.14.0 version: 8.14.0 @@ -174,7 +170,7 @@ packages: resolution: {integrity: sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==} dependencies: '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.378.0 + '@aws-sdk/types': 3.398.0 tslib: 1.14.1 dev: true @@ -191,7 +187,7 @@ packages: '@aws-crypto/sha256-js': 3.0.0 '@aws-crypto/supports-web-crypto': 3.0.0 '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.378.0 + '@aws-sdk/types': 3.398.0 '@aws-sdk/util-locate-window': 3.310.0 '@aws-sdk/util-utf8-browser': 3.259.0 tslib: 1.14.1 @@ -201,7 +197,7 @@ packages: resolution: {integrity: sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==} dependencies: '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.378.0 + '@aws-sdk/types': 3.398.0 tslib: 1.14.1 dev: true @@ -214,226 +210,137 @@ packages: /@aws-crypto/util@3.0.0: resolution: {integrity: sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==} dependencies: - '@aws-sdk/types': 3.378.0 + '@aws-sdk/types': 3.398.0 '@aws-sdk/util-utf8-browser': 3.259.0 tslib: 1.14.1 dev: true - /@aws-sdk/abort-controller@3.338.0: - resolution: {integrity: sha512-/yLI32+HwFNBRJ39jMXw+/cn3AnlCuJpQd7Ax4887g32Dgte5eyrfY8sJUOL6902BUmAq4oSRI5QeBXNplO0Xw==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/client-cognito-identity@3.386.0: - resolution: {integrity: sha512-greo255LzFJI2rMwOuAywb+CkO8iKNp058Ve4E4F1Xp/ipOoc9UnzQuO+99N/1PbRnph55qYbM8D2WE2cokx0Q==} + /@aws-sdk/client-cognito-identity@3.398.0: + resolution: {integrity: sha512-Pr/S1f8R2FsJ8DwBC6g0CSdtZNNV5dMHhlIi+t8YAmCJvP4KT+UhzFjbvQRINlBRLFuGUuP7p5vRcGVELD3+wA==} engines: {node: '>=14.0.0'} dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sts': 3.386.0 - '@aws-sdk/credential-provider-node': 3.386.0 - '@aws-sdk/middleware-host-header': 3.379.1 - '@aws-sdk/middleware-logger': 3.378.0 - '@aws-sdk/middleware-recursion-detection': 3.378.0 - '@aws-sdk/middleware-signing': 3.379.1 - '@aws-sdk/middleware-user-agent': 3.386.0 - '@aws-sdk/types': 3.378.0 - '@aws-sdk/util-endpoints': 3.386.0 - '@aws-sdk/util-user-agent-browser': 3.378.0 - '@aws-sdk/util-user-agent-node': 3.378.0 - '@smithy/config-resolver': 2.0.1 - '@smithy/fetch-http-handler': 2.0.1 - '@smithy/hash-node': 2.0.1 - '@smithy/invalid-dependency': 2.0.1 - '@smithy/middleware-content-length': 2.0.1 - '@smithy/middleware-endpoint': 2.0.1 - '@smithy/middleware-retry': 2.0.1 - '@smithy/middleware-serde': 2.0.1 + '@aws-sdk/client-sts': 3.398.0 + '@aws-sdk/credential-provider-node': 3.398.0 + '@aws-sdk/middleware-host-header': 3.398.0 + '@aws-sdk/middleware-logger': 3.398.0 + '@aws-sdk/middleware-recursion-detection': 3.398.0 + '@aws-sdk/middleware-signing': 3.398.0 + '@aws-sdk/middleware-user-agent': 3.398.0 + '@aws-sdk/types': 3.398.0 + '@aws-sdk/util-endpoints': 3.398.0 + '@aws-sdk/util-user-agent-browser': 3.398.0 + '@aws-sdk/util-user-agent-node': 3.398.0 + '@smithy/config-resolver': 2.0.5 + '@smithy/fetch-http-handler': 2.0.5 + '@smithy/hash-node': 2.0.5 + '@smithy/invalid-dependency': 2.0.5 + '@smithy/middleware-content-length': 2.0.5 + '@smithy/middleware-endpoint': 2.0.5 + '@smithy/middleware-retry': 2.0.5 + '@smithy/middleware-serde': 2.0.5 '@smithy/middleware-stack': 2.0.0 - '@smithy/node-config-provider': 2.0.1 - '@smithy/node-http-handler': 2.0.1 - '@smithy/protocol-http': 2.0.1 - '@smithy/smithy-client': 2.0.1 - '@smithy/types': 2.0.2 - '@smithy/url-parser': 2.0.1 + '@smithy/node-config-provider': 2.0.5 + '@smithy/node-http-handler': 2.0.5 + '@smithy/protocol-http': 2.0.5 + '@smithy/smithy-client': 2.0.5 + '@smithy/types': 2.2.2 + '@smithy/url-parser': 2.0.5 '@smithy/util-base64': 2.0.0 '@smithy/util-body-length-browser': 2.0.0 - '@smithy/util-body-length-node': 2.0.0 - '@smithy/util-defaults-mode-browser': 2.0.1 - '@smithy/util-defaults-mode-node': 2.0.1 + '@smithy/util-body-length-node': 2.1.0 + '@smithy/util-defaults-mode-browser': 2.0.5 + '@smithy/util-defaults-mode-node': 2.0.5 '@smithy/util-retry': 2.0.0 '@smithy/util-utf8': 2.0.0 tslib: 2.6.1 transitivePeerDependencies: - aws-crt dev: true + optional: true - /@aws-sdk/client-dynamodb@3.338.0: - resolution: {integrity: sha512-m1tYFDdO2KxD9LvAEZEzixgfFpvNnXz5LHjCG/oVaGCPPMB91AyuyW4NkloCJ0gxmY4WqaHPvWMkwuJ4RJsU7Q==} + /@aws-sdk/client-dynamodb@3.398.0: + resolution: {integrity: sha512-INYklo7u16T0Gia983MqfLdx4feZ96xqowH23+1XSYe4VSersCSfdBM+yeChQ5naTCW0GqFybC9+BytZX5/klw==} engines: {node: '>=14.0.0'} dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sts': 3.338.0 - '@aws-sdk/config-resolver': 3.338.0 - '@aws-sdk/credential-provider-node': 3.338.0 - '@aws-sdk/fetch-http-handler': 3.338.0 - '@aws-sdk/hash-node': 3.338.0 - '@aws-sdk/invalid-dependency': 3.338.0 - '@aws-sdk/middleware-content-length': 3.338.0 - '@aws-sdk/middleware-endpoint': 3.338.0 - '@aws-sdk/middleware-endpoint-discovery': 3.338.0 - '@aws-sdk/middleware-host-header': 3.338.0 - '@aws-sdk/middleware-logger': 3.338.0 - '@aws-sdk/middleware-recursion-detection': 3.338.0 - '@aws-sdk/middleware-retry': 3.338.0 - '@aws-sdk/middleware-serde': 3.338.0 - '@aws-sdk/middleware-signing': 3.338.0 - '@aws-sdk/middleware-stack': 3.338.0 - '@aws-sdk/middleware-user-agent': 3.338.0 - '@aws-sdk/node-config-provider': 3.338.0 - '@aws-sdk/node-http-handler': 3.338.0 - '@aws-sdk/smithy-client': 3.338.0 - '@aws-sdk/types': 3.338.0 - '@aws-sdk/url-parser': 3.338.0 - '@aws-sdk/util-base64': 3.310.0 - '@aws-sdk/util-body-length-browser': 3.310.0 - '@aws-sdk/util-body-length-node': 3.310.0 - '@aws-sdk/util-defaults-mode-browser': 3.338.0 - '@aws-sdk/util-defaults-mode-node': 3.338.0 - '@aws-sdk/util-endpoints': 3.338.0 - '@aws-sdk/util-retry': 3.338.0 - '@aws-sdk/util-user-agent-browser': 3.338.0 - '@aws-sdk/util-user-agent-node': 3.338.0 - '@aws-sdk/util-utf8': 3.310.0 - '@aws-sdk/util-waiter': 3.338.0 - '@smithy/protocol-http': 1.2.0 - '@smithy/types': 1.2.0 + '@aws-sdk/client-sts': 3.398.0 + '@aws-sdk/credential-provider-node': 3.398.0 + '@aws-sdk/middleware-endpoint-discovery': 3.398.0 + '@aws-sdk/middleware-host-header': 3.398.0 + '@aws-sdk/middleware-logger': 3.398.0 + '@aws-sdk/middleware-recursion-detection': 3.398.0 + '@aws-sdk/middleware-signing': 3.398.0 + '@aws-sdk/middleware-user-agent': 3.398.0 + '@aws-sdk/types': 3.398.0 + '@aws-sdk/util-endpoints': 3.398.0 + '@aws-sdk/util-user-agent-browser': 3.398.0 + '@aws-sdk/util-user-agent-node': 3.398.0 + '@smithy/config-resolver': 2.0.5 + '@smithy/fetch-http-handler': 2.0.5 + '@smithy/hash-node': 2.0.5 + '@smithy/invalid-dependency': 2.0.5 + '@smithy/middleware-content-length': 2.0.5 + '@smithy/middleware-endpoint': 2.0.5 + '@smithy/middleware-retry': 2.0.5 + '@smithy/middleware-serde': 2.0.5 + '@smithy/middleware-stack': 2.0.0 + '@smithy/node-config-provider': 2.0.5 + '@smithy/node-http-handler': 2.0.5 + '@smithy/protocol-http': 2.0.5 + '@smithy/smithy-client': 2.0.5 + '@smithy/types': 2.2.2 + '@smithy/url-parser': 2.0.5 + '@smithy/util-base64': 2.0.0 + '@smithy/util-body-length-browser': 2.0.0 + '@smithy/util-body-length-node': 2.1.0 + '@smithy/util-defaults-mode-browser': 2.0.5 + '@smithy/util-defaults-mode-node': 2.0.5 + '@smithy/util-retry': 2.0.0 + '@smithy/util-utf8': 2.0.0 + '@smithy/util-waiter': 2.0.5 tslib: 2.6.1 uuid: 8.3.2 transitivePeerDependencies: - aws-crt dev: true - /@aws-sdk/client-sso-oidc@3.338.0: - resolution: {integrity: sha512-mny5Q3LWKTcMMFS8WxeOCTinl193z7vS3b+eQz09K4jb1Lq04Bpjw25cySgBnhMGZ7QHQiYBscNLyu/TfOKiHA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/config-resolver': 3.338.0 - '@aws-sdk/fetch-http-handler': 3.338.0 - '@aws-sdk/hash-node': 3.338.0 - '@aws-sdk/invalid-dependency': 3.338.0 - '@aws-sdk/middleware-content-length': 3.338.0 - '@aws-sdk/middleware-endpoint': 3.338.0 - '@aws-sdk/middleware-host-header': 3.338.0 - '@aws-sdk/middleware-logger': 3.338.0 - '@aws-sdk/middleware-recursion-detection': 3.338.0 - '@aws-sdk/middleware-retry': 3.338.0 - '@aws-sdk/middleware-serde': 3.338.0 - '@aws-sdk/middleware-stack': 3.338.0 - '@aws-sdk/middleware-user-agent': 3.338.0 - '@aws-sdk/node-config-provider': 3.338.0 - '@aws-sdk/node-http-handler': 3.338.0 - '@aws-sdk/smithy-client': 3.338.0 - '@aws-sdk/types': 3.338.0 - '@aws-sdk/url-parser': 3.338.0 - '@aws-sdk/util-base64': 3.310.0 - '@aws-sdk/util-body-length-browser': 3.310.0 - '@aws-sdk/util-body-length-node': 3.310.0 - '@aws-sdk/util-defaults-mode-browser': 3.338.0 - '@aws-sdk/util-defaults-mode-node': 3.338.0 - '@aws-sdk/util-endpoints': 3.338.0 - '@aws-sdk/util-retry': 3.338.0 - '@aws-sdk/util-user-agent-browser': 3.338.0 - '@aws-sdk/util-user-agent-node': 3.338.0 - '@aws-sdk/util-utf8': 3.310.0 - '@smithy/protocol-http': 1.2.0 - '@smithy/types': 1.2.0 - tslib: 2.6.1 - transitivePeerDependencies: - - aws-crt - dev: true - - /@aws-sdk/client-sso@3.338.0: - resolution: {integrity: sha512-EglKsGlVph65PuFPKq1nGlxsY99XM2xHJaB1uX0bQEC94qrmS/M4a5kno5tiUnTWO1K+K4JBQiOxdGJs0GUS+w==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/config-resolver': 3.338.0 - '@aws-sdk/fetch-http-handler': 3.338.0 - '@aws-sdk/hash-node': 3.338.0 - '@aws-sdk/invalid-dependency': 3.338.0 - '@aws-sdk/middleware-content-length': 3.338.0 - '@aws-sdk/middleware-endpoint': 3.338.0 - '@aws-sdk/middleware-host-header': 3.338.0 - '@aws-sdk/middleware-logger': 3.338.0 - '@aws-sdk/middleware-recursion-detection': 3.338.0 - '@aws-sdk/middleware-retry': 3.338.0 - '@aws-sdk/middleware-serde': 3.338.0 - '@aws-sdk/middleware-stack': 3.338.0 - '@aws-sdk/middleware-user-agent': 3.338.0 - '@aws-sdk/node-config-provider': 3.338.0 - '@aws-sdk/node-http-handler': 3.338.0 - '@aws-sdk/smithy-client': 3.338.0 - '@aws-sdk/types': 3.338.0 - '@aws-sdk/url-parser': 3.338.0 - '@aws-sdk/util-base64': 3.310.0 - '@aws-sdk/util-body-length-browser': 3.310.0 - '@aws-sdk/util-body-length-node': 3.310.0 - '@aws-sdk/util-defaults-mode-browser': 3.338.0 - '@aws-sdk/util-defaults-mode-node': 3.338.0 - '@aws-sdk/util-endpoints': 3.338.0 - '@aws-sdk/util-retry': 3.338.0 - '@aws-sdk/util-user-agent-browser': 3.338.0 - '@aws-sdk/util-user-agent-node': 3.338.0 - '@aws-sdk/util-utf8': 3.310.0 - '@smithy/protocol-http': 1.2.0 - '@smithy/types': 1.2.0 - tslib: 2.6.1 - transitivePeerDependencies: - - aws-crt - dev: true - - /@aws-sdk/client-sso@3.386.0: - resolution: {integrity: sha512-UBgRo0q/XSle9CHCpoFhzq9wCfdc4kJw40cpPoHJPbb5m3JMcDu0mq4LTY7Nwnoy9jBThfRVYf3EF2BMF8fo6A==} + /@aws-sdk/client-sso@3.398.0: + resolution: {integrity: sha512-CygL0jhfibw4kmWXG/3sfZMFNjcXo66XUuPC4BqZBk8Rj5vFoxp1vZeMkDLzTIk97Nvo5J5Bh+QnXKhub6AckQ==} engines: {node: '>=14.0.0'} dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/middleware-host-header': 3.379.1 - '@aws-sdk/middleware-logger': 3.378.0 - '@aws-sdk/middleware-recursion-detection': 3.378.0 - '@aws-sdk/middleware-user-agent': 3.386.0 - '@aws-sdk/types': 3.378.0 - '@aws-sdk/util-endpoints': 3.386.0 - '@aws-sdk/util-user-agent-browser': 3.378.0 - '@aws-sdk/util-user-agent-node': 3.378.0 - '@smithy/config-resolver': 2.0.1 - '@smithy/fetch-http-handler': 2.0.1 - '@smithy/hash-node': 2.0.1 - '@smithy/invalid-dependency': 2.0.1 - '@smithy/middleware-content-length': 2.0.1 - '@smithy/middleware-endpoint': 2.0.1 - '@smithy/middleware-retry': 2.0.1 - '@smithy/middleware-serde': 2.0.1 + '@aws-sdk/middleware-host-header': 3.398.0 + '@aws-sdk/middleware-logger': 3.398.0 + '@aws-sdk/middleware-recursion-detection': 3.398.0 + '@aws-sdk/middleware-user-agent': 3.398.0 + '@aws-sdk/types': 3.398.0 + '@aws-sdk/util-endpoints': 3.398.0 + '@aws-sdk/util-user-agent-browser': 3.398.0 + '@aws-sdk/util-user-agent-node': 3.398.0 + '@smithy/config-resolver': 2.0.5 + '@smithy/fetch-http-handler': 2.0.5 + '@smithy/hash-node': 2.0.5 + '@smithy/invalid-dependency': 2.0.5 + '@smithy/middleware-content-length': 2.0.5 + '@smithy/middleware-endpoint': 2.0.5 + '@smithy/middleware-retry': 2.0.5 + '@smithy/middleware-serde': 2.0.5 '@smithy/middleware-stack': 2.0.0 - '@smithy/node-config-provider': 2.0.1 - '@smithy/node-http-handler': 2.0.1 - '@smithy/protocol-http': 2.0.1 - '@smithy/smithy-client': 2.0.1 - '@smithy/types': 2.0.2 - '@smithy/url-parser': 2.0.1 + '@smithy/node-config-provider': 2.0.5 + '@smithy/node-http-handler': 2.0.5 + '@smithy/protocol-http': 2.0.5 + '@smithy/smithy-client': 2.0.5 + '@smithy/types': 2.2.2 + '@smithy/url-parser': 2.0.5 '@smithy/util-base64': 2.0.0 '@smithy/util-body-length-browser': 2.0.0 - '@smithy/util-body-length-node': 2.0.0 - '@smithy/util-defaults-mode-browser': 2.0.1 - '@smithy/util-defaults-mode-node': 2.0.1 + '@smithy/util-body-length-node': 2.1.0 + '@smithy/util-defaults-mode-browser': 2.0.5 + '@smithy/util-defaults-mode-node': 2.0.5 '@smithy/util-retry': 2.0.0 '@smithy/util-utf8': 2.0.0 tslib: 2.6.1 @@ -441,88 +348,43 @@ packages: - aws-crt dev: true - /@aws-sdk/client-sts@3.338.0: - resolution: {integrity: sha512-FBHy/G7BAPX0CdEeeGYpoAnKXVCSIIkESLU2wF6x880z+U2IqiL48Fzoa5qoLaLPQaK/30P7ytznkqm4vd1OFw==} + /@aws-sdk/client-sts@3.398.0: + resolution: {integrity: sha512-/3Pa9wLMvBZipKraq3AtbmTfXW6q9kyvhwOno64f1Fz7kFb8ijQFMGoATS70B2pGEZTlxkUqJFWDiisT6Q6dFg==} engines: {node: '>=14.0.0'} dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/config-resolver': 3.338.0 - '@aws-sdk/credential-provider-node': 3.338.0 - '@aws-sdk/fetch-http-handler': 3.338.0 - '@aws-sdk/hash-node': 3.338.0 - '@aws-sdk/invalid-dependency': 3.338.0 - '@aws-sdk/middleware-content-length': 3.338.0 - '@aws-sdk/middleware-endpoint': 3.338.0 - '@aws-sdk/middleware-host-header': 3.338.0 - '@aws-sdk/middleware-logger': 3.338.0 - '@aws-sdk/middleware-recursion-detection': 3.338.0 - '@aws-sdk/middleware-retry': 3.338.0 - '@aws-sdk/middleware-sdk-sts': 3.338.0 - '@aws-sdk/middleware-serde': 3.338.0 - '@aws-sdk/middleware-signing': 3.338.0 - '@aws-sdk/middleware-stack': 3.338.0 - '@aws-sdk/middleware-user-agent': 3.338.0 - '@aws-sdk/node-config-provider': 3.338.0 - '@aws-sdk/node-http-handler': 3.338.0 - '@aws-sdk/smithy-client': 3.338.0 - '@aws-sdk/types': 3.338.0 - '@aws-sdk/url-parser': 3.338.0 - '@aws-sdk/util-base64': 3.310.0 - '@aws-sdk/util-body-length-browser': 3.310.0 - '@aws-sdk/util-body-length-node': 3.310.0 - '@aws-sdk/util-defaults-mode-browser': 3.338.0 - '@aws-sdk/util-defaults-mode-node': 3.338.0 - '@aws-sdk/util-endpoints': 3.338.0 - '@aws-sdk/util-retry': 3.338.0 - '@aws-sdk/util-user-agent-browser': 3.338.0 - '@aws-sdk/util-user-agent-node': 3.338.0 - '@aws-sdk/util-utf8': 3.310.0 - '@smithy/protocol-http': 1.2.0 - '@smithy/types': 1.2.0 - fast-xml-parser: 4.1.2 - tslib: 2.6.1 - transitivePeerDependencies: - - aws-crt - dev: true - - /@aws-sdk/client-sts@3.386.0: - resolution: {integrity: sha512-VK+tdZaI971IDP/1WqpYNorf+Q5uoJTqcp3y/bQY4Hr5bf8N3aztDrX7a2GaA07zgSdUa82VkScMKzW31jhsxw==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/credential-provider-node': 3.386.0 - '@aws-sdk/middleware-host-header': 3.379.1 - '@aws-sdk/middleware-logger': 3.378.0 - '@aws-sdk/middleware-recursion-detection': 3.378.0 - '@aws-sdk/middleware-sdk-sts': 3.379.1 - '@aws-sdk/middleware-signing': 3.379.1 - '@aws-sdk/middleware-user-agent': 3.386.0 - '@aws-sdk/types': 3.378.0 - '@aws-sdk/util-endpoints': 3.386.0 - '@aws-sdk/util-user-agent-browser': 3.378.0 - '@aws-sdk/util-user-agent-node': 3.378.0 - '@smithy/config-resolver': 2.0.1 - '@smithy/fetch-http-handler': 2.0.1 - '@smithy/hash-node': 2.0.1 - '@smithy/invalid-dependency': 2.0.1 - '@smithy/middleware-content-length': 2.0.1 - '@smithy/middleware-endpoint': 2.0.1 - '@smithy/middleware-retry': 2.0.1 - '@smithy/middleware-serde': 2.0.1 + '@aws-sdk/credential-provider-node': 3.398.0 + '@aws-sdk/middleware-host-header': 3.398.0 + '@aws-sdk/middleware-logger': 3.398.0 + '@aws-sdk/middleware-recursion-detection': 3.398.0 + '@aws-sdk/middleware-sdk-sts': 3.398.0 + '@aws-sdk/middleware-signing': 3.398.0 + '@aws-sdk/middleware-user-agent': 3.398.0 + '@aws-sdk/types': 3.398.0 + '@aws-sdk/util-endpoints': 3.398.0 + '@aws-sdk/util-user-agent-browser': 3.398.0 + '@aws-sdk/util-user-agent-node': 3.398.0 + '@smithy/config-resolver': 2.0.5 + '@smithy/fetch-http-handler': 2.0.5 + '@smithy/hash-node': 2.0.5 + '@smithy/invalid-dependency': 2.0.5 + '@smithy/middleware-content-length': 2.0.5 + '@smithy/middleware-endpoint': 2.0.5 + '@smithy/middleware-retry': 2.0.5 + '@smithy/middleware-serde': 2.0.5 '@smithy/middleware-stack': 2.0.0 - '@smithy/node-config-provider': 2.0.1 - '@smithy/node-http-handler': 2.0.1 - '@smithy/protocol-http': 2.0.1 - '@smithy/smithy-client': 2.0.1 - '@smithy/types': 2.0.2 - '@smithy/url-parser': 2.0.1 + '@smithy/node-config-provider': 2.0.5 + '@smithy/node-http-handler': 2.0.5 + '@smithy/protocol-http': 2.0.5 + '@smithy/smithy-client': 2.0.5 + '@smithy/types': 2.2.2 + '@smithy/url-parser': 2.0.5 '@smithy/util-base64': 2.0.0 '@smithy/util-body-length-browser': 2.0.0 - '@smithy/util-body-length-node': 2.0.0 - '@smithy/util-defaults-mode-browser': 2.0.1 - '@smithy/util-defaults-mode-node': 2.0.1 + '@smithy/util-body-length-node': 2.1.0 + '@smithy/util-defaults-mode-browser': 2.0.5 + '@smithy/util-defaults-mode-node': 2.0.5 '@smithy/util-retry': 2.0.0 '@smithy/util-utf8': 2.0.0 fast-xml-parser: 4.2.5 @@ -531,223 +393,127 @@ packages: - aws-crt dev: true - /@aws-sdk/config-resolver@3.338.0: - resolution: {integrity: sha512-rB9WUaMfTB74Hd2mOiyPFR7Q1viT+w6SaDSR9SA1P8EeIg5H13FNdIKb736Z8/6QJhDj7whdyk1CTGV+DmXOOg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.338.0 - '@aws-sdk/util-config-provider': 3.310.0 - '@aws-sdk/util-middleware': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/credential-provider-cognito-identity@3.386.0: - resolution: {integrity: sha512-bH160dPWs5Sz1duZL5OW6IEeJK36lxiGuYpmhAu7yndnyXszoBPtFXjWR3c4smE4VawEBdPY8mFxwrW1Ah794g==} + /@aws-sdk/credential-provider-cognito-identity@3.398.0: + resolution: {integrity: sha512-MFUhy1YayHg5ypRTk4OTfDumQRP+OJBagaGv14kA8DzhKH1sNrU4HV7A7y2J4SvkN5hG/KnLJqxpakCtB2/O2g==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/client-cognito-identity': 3.386.0 - '@aws-sdk/types': 3.378.0 + '@aws-sdk/client-cognito-identity': 3.398.0 + '@aws-sdk/types': 3.398.0 '@smithy/property-provider': 2.0.1 - '@smithy/types': 2.0.2 + '@smithy/types': 2.2.2 tslib: 2.6.1 transitivePeerDependencies: - aws-crt dev: true + optional: true - /@aws-sdk/credential-provider-env@3.338.0: - resolution: {integrity: sha512-j14vApy80tpk87C3x3uBf1caQsuR8RdQ8iOW830H/AOhsa88XaZIB/NQSX7exaIKZa2RU0Vv2wIlGAA8ko7J6g==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/property-provider': 3.338.0 - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/credential-provider-env@3.378.0: - resolution: {integrity: sha512-B2OVdO9kBClDwGgWTBLAQwFV8qYTYGyVujg++1FZFSFMt8ORFdZ5fNpErvJtiSjYiOOQMzyBeSNhKyYNXCiJjQ==} + /@aws-sdk/credential-provider-env@3.398.0: + resolution: {integrity: sha512-Z8Yj5z7FroAsR6UVML+XUdlpoqEe9Dnle8c2h8/xWwIC2feTfIBhjLhRVxfbpbM1pLgBSNEcZ7U8fwq5l7ESVQ==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.378.0 + '@aws-sdk/types': 3.398.0 '@smithy/property-provider': 2.0.1 - '@smithy/types': 2.0.2 - tslib: 2.6.1 - dev: true - - /@aws-sdk/credential-provider-imds@3.338.0: - resolution: {integrity: sha512-qsqeywYfJevg5pgUUUBmm7pK1bckVrl091PZB2IliFdQVnDvI5GFLf4B0oZqjaLAzPG1gVtxRvqIve+tnP/+xA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/node-config-provider': 3.338.0 - '@aws-sdk/property-provider': 3.338.0 - '@aws-sdk/types': 3.338.0 - '@aws-sdk/url-parser': 3.338.0 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true - /@aws-sdk/credential-provider-ini@3.338.0: - resolution: {integrity: sha512-UhgYgymT9sJiRm0peqP5EvtR4dXiS2Q2AuFgDUjBvDz8JaZlqafsIS4cfyGwTHV/xY6cdiMu5rCTe8hTyXsukQ==} + /@aws-sdk/credential-provider-ini@3.398.0: + resolution: {integrity: sha512-AsK1lStK3nB9Cn6S6ODb1ktGh7SRejsNVQVKX3t5d3tgOaX+aX1Iwy8FzM/ZEN8uCloeRifUGIY9uQFygg5mSw==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/credential-provider-env': 3.338.0 - '@aws-sdk/credential-provider-imds': 3.338.0 - '@aws-sdk/credential-provider-process': 3.338.0 - '@aws-sdk/credential-provider-sso': 3.338.0 - '@aws-sdk/credential-provider-web-identity': 3.338.0 - '@aws-sdk/property-provider': 3.338.0 - '@aws-sdk/shared-ini-file-loader': 3.338.0 - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - transitivePeerDependencies: - - aws-crt - dev: true - - /@aws-sdk/credential-provider-ini@3.386.0: - resolution: {integrity: sha512-TDeOFwCq6Ri58OP4CvVIAbc+iJPld7TpOFB+YYQ+q0ut+92zaVTNrNoWZkygPCXKmeHUGZcwC9Mjt/4L+fBAkg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/credential-provider-env': 3.378.0 - '@aws-sdk/credential-provider-process': 3.378.0 - '@aws-sdk/credential-provider-sso': 3.386.0 - '@aws-sdk/credential-provider-web-identity': 3.378.0 - '@aws-sdk/types': 3.378.0 + '@aws-sdk/credential-provider-env': 3.398.0 + '@aws-sdk/credential-provider-process': 3.398.0 + '@aws-sdk/credential-provider-sso': 3.398.0 + '@aws-sdk/credential-provider-web-identity': 3.398.0 + '@aws-sdk/types': 3.398.0 '@smithy/credential-provider-imds': 2.0.1 '@smithy/property-provider': 2.0.1 - '@smithy/shared-ini-file-loader': 2.0.1 - '@smithy/types': 2.0.2 + '@smithy/shared-ini-file-loader': 2.0.5 + '@smithy/types': 2.2.2 tslib: 2.6.1 transitivePeerDependencies: - aws-crt dev: true - /@aws-sdk/credential-provider-node@3.338.0: - resolution: {integrity: sha512-nZjaMRxJqX0EXMV9LA5IbRQI1pDGGZiPYX2KDfZ1Y9Gc1Y/vIZhHKOHGb1uKMAonlR076CsXlev4/tjC8SGGuw==} + /@aws-sdk/credential-provider-node@3.398.0: + resolution: {integrity: sha512-odmI/DSKfuWUYeDnGTCEHBbC8/MwnF6yEq874zl6+owoVv0ZsYP8qBHfiJkYqrwg7wQ7Pi40sSAPC1rhesGwzg==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/credential-provider-env': 3.338.0 - '@aws-sdk/credential-provider-imds': 3.338.0 - '@aws-sdk/credential-provider-ini': 3.338.0 - '@aws-sdk/credential-provider-process': 3.338.0 - '@aws-sdk/credential-provider-sso': 3.338.0 - '@aws-sdk/credential-provider-web-identity': 3.338.0 - '@aws-sdk/property-provider': 3.338.0 - '@aws-sdk/shared-ini-file-loader': 3.338.0 - '@aws-sdk/types': 3.338.0 + '@aws-sdk/credential-provider-env': 3.398.0 + '@aws-sdk/credential-provider-ini': 3.398.0 + '@aws-sdk/credential-provider-process': 3.398.0 + '@aws-sdk/credential-provider-sso': 3.398.0 + '@aws-sdk/credential-provider-web-identity': 3.398.0 + '@aws-sdk/types': 3.398.0 + '@smithy/credential-provider-imds': 2.0.5 + '@smithy/property-provider': 2.0.5 + '@smithy/shared-ini-file-loader': 2.0.5 + '@smithy/types': 2.2.2 tslib: 2.6.1 transitivePeerDependencies: - aws-crt dev: true - /@aws-sdk/credential-provider-node@3.386.0: - resolution: {integrity: sha512-dvYSN+T1B96TqiZE5tBV8bHCNU6TKq5meeI06AdClHz3VPvPKDN/EL0undXpl/GnlvuhKUftmVwdUBefG3otZA==} + /@aws-sdk/credential-provider-process@3.398.0: + resolution: {integrity: sha512-WrkBL1W7TXN508PA9wRXPFtzmGpVSW98gDaHEaa8GolAPHMPa5t2QcC/z/cFpglzrcVv8SA277zu9Z8tELdZhg==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/credential-provider-env': 3.378.0 - '@aws-sdk/credential-provider-ini': 3.386.0 - '@aws-sdk/credential-provider-process': 3.378.0 - '@aws-sdk/credential-provider-sso': 3.386.0 - '@aws-sdk/credential-provider-web-identity': 3.378.0 - '@aws-sdk/types': 3.378.0 - '@smithy/credential-provider-imds': 2.0.1 + '@aws-sdk/types': 3.398.0 '@smithy/property-provider': 2.0.1 - '@smithy/shared-ini-file-loader': 2.0.1 - '@smithy/types': 2.0.2 + '@smithy/shared-ini-file-loader': 2.0.5 + '@smithy/types': 2.2.2 tslib: 2.6.1 - transitivePeerDependencies: - - aws-crt dev: true - /@aws-sdk/credential-provider-process@3.338.0: - resolution: {integrity: sha512-5I1EgJxFFEg8xel2kInMpkdBKajUut0hR2fBajqCmK7Pflu8s0I2NKDots9a3YJagNrFJq38+EzoDcUvRrd2dg==} + /@aws-sdk/credential-provider-sso@3.398.0: + resolution: {integrity: sha512-2Dl35587xbnzR/GGZqA2MnFs8+kS4wbHQO9BioU0okA+8NRueohNMdrdQmQDdSNK4BfIpFspiZmFkXFNyEAfgw==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/property-provider': 3.338.0 - '@aws-sdk/shared-ini-file-loader': 3.338.0 - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/credential-provider-process@3.378.0: - resolution: {integrity: sha512-KFTIy7u+wXj3eDua4rgS0tODzMnXtXhAm1RxzCW9FL5JLBBrd82ymCj1Dp72217Sw5Do6NjCnDTTNkCHZMA77w==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.378.0 + '@aws-sdk/client-sso': 3.398.0 + '@aws-sdk/token-providers': 3.398.0 + '@aws-sdk/types': 3.398.0 '@smithy/property-provider': 2.0.1 - '@smithy/shared-ini-file-loader': 2.0.1 - '@smithy/types': 2.0.2 - tslib: 2.6.1 - dev: true - - /@aws-sdk/credential-provider-sso@3.338.0: - resolution: {integrity: sha512-fpzYHK17iF/uFkrm4cLg/utDVKSBTWNjAiNlE3GF6CaixBCwc0QBLKHk2nG4d1ZZeMVCbIUMS7eoqfR0LYc/yw==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/client-sso': 3.338.0 - '@aws-sdk/property-provider': 3.338.0 - '@aws-sdk/shared-ini-file-loader': 3.338.0 - '@aws-sdk/token-providers': 3.338.0 - '@aws-sdk/types': 3.338.0 + '@smithy/shared-ini-file-loader': 2.0.5 + '@smithy/types': 2.2.2 tslib: 2.6.1 transitivePeerDependencies: - aws-crt dev: true - /@aws-sdk/credential-provider-sso@3.386.0: - resolution: {integrity: sha512-7PvtrxMFpphQP8D5Zu5WpqZ/p7FBWiOQ2UQhzGKEry/9JIyTKiIZWsCu7OIWcfEx8RqSnLu3pDydc6HSTNs+lw==} + /@aws-sdk/credential-provider-web-identity@3.398.0: + resolution: {integrity: sha512-iG3905Alv9pINbQ8/MIsshgqYMbWx+NDQWpxbIW3W0MkSH3iAqdVpSCteYidYX9G/jv2Um1nW3y360ib20bvNg==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/client-sso': 3.386.0 - '@aws-sdk/token-providers': 3.386.0 - '@aws-sdk/types': 3.378.0 + '@aws-sdk/types': 3.398.0 '@smithy/property-provider': 2.0.1 - '@smithy/shared-ini-file-loader': 2.0.1 - '@smithy/types': 2.0.2 + '@smithy/types': 2.2.2 tslib: 2.6.1 - transitivePeerDependencies: - - aws-crt dev: true - /@aws-sdk/credential-provider-web-identity@3.338.0: - resolution: {integrity: sha512-kjT/P18jM1icwjYwr8wfY//T8lv2s81ms7OC7vgiSqckmQOxpVkdsep9d44ymSUXwopmotFP7M9gGnEHS6HwAA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/property-provider': 3.338.0 - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/credential-provider-web-identity@3.378.0: - resolution: {integrity: sha512-GWjydOszhc4xDF8xuPtBvboglXQr0gwCW1oHAvmLcOT38+Hd6qnKywnMSeoXYRPgoKfF9TkWQgW1jxplzCG0UA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.378.0 - '@smithy/property-provider': 2.0.1 - '@smithy/types': 2.0.2 - tslib: 2.6.1 - dev: true - - /@aws-sdk/credential-providers@3.386.0: - resolution: {integrity: sha512-e5v6uP4bz34rWjiBL5GeaC1Rqw5Oqs3vTLbtuhAXyLYy2MfM39DVqK6ccwyqu053WPIfLzsK6boaOBohRdlg3Q==} + /@aws-sdk/credential-providers@3.398.0: + resolution: {integrity: sha512-355vXmImn2e85mIWSYDVb101AF2lIVHKNCaH6sV1U/8i0ZOXh2cJYNdkRYrxNt1ezDB0k97lSKvuDx7RDvJyRg==} engines: {node: '>=14.0.0'} requiresBuild: true dependencies: - '@aws-sdk/client-cognito-identity': 3.386.0 - '@aws-sdk/client-sso': 3.386.0 - '@aws-sdk/client-sts': 3.386.0 - '@aws-sdk/credential-provider-cognito-identity': 3.386.0 - '@aws-sdk/credential-provider-env': 3.378.0 - '@aws-sdk/credential-provider-ini': 3.386.0 - '@aws-sdk/credential-provider-node': 3.386.0 - '@aws-sdk/credential-provider-process': 3.378.0 - '@aws-sdk/credential-provider-sso': 3.386.0 - '@aws-sdk/credential-provider-web-identity': 3.378.0 - '@aws-sdk/types': 3.378.0 + '@aws-sdk/client-cognito-identity': 3.398.0 + '@aws-sdk/client-sso': 3.398.0 + '@aws-sdk/client-sts': 3.398.0 + '@aws-sdk/credential-provider-cognito-identity': 3.398.0 + '@aws-sdk/credential-provider-env': 3.398.0 + '@aws-sdk/credential-provider-ini': 3.398.0 + '@aws-sdk/credential-provider-node': 3.398.0 + '@aws-sdk/credential-provider-process': 3.398.0 + '@aws-sdk/credential-provider-sso': 3.398.0 + '@aws-sdk/credential-provider-web-identity': 3.398.0 + '@aws-sdk/types': 3.398.0 '@smithy/credential-provider-imds': 2.0.1 '@smithy/property-provider': 2.0.1 - '@smithy/types': 2.0.2 + '@smithy/types': 2.2.2 tslib: 2.6.1 transitivePeerDependencies: - aws-crt dev: true + optional: true /@aws-sdk/endpoint-cache@3.310.0: resolution: {integrity: sha512-y3wipforet41EDTI0vnzxILqwAGll1KfI5qcdX9pXF/WF1f+3frcOtPiWtQEZQpy4czRogKm3BHo70QBYAZxlQ==} @@ -757,463 +523,154 @@ packages: tslib: 2.6.1 dev: true - /@aws-sdk/fetch-http-handler@3.338.0: - resolution: {integrity: sha512-NOIQmeSa51J2nFAzl99IjxwQkq27cdNJzF59jQWzpUCGbxXfMD4WWy2NHubabSFuJ4FJU2eyoQHUNUFc6/uxXA==} - dependencies: - '@aws-sdk/protocol-http': 3.338.0 - '@aws-sdk/querystring-builder': 3.338.0 - '@aws-sdk/types': 3.338.0 - '@aws-sdk/util-base64': 3.310.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/hash-node@3.338.0: - resolution: {integrity: sha512-udveX3ZRO1oUbyBTQH0LJ8Ika7uk0pHuXrqapdi66GGRJB50IhmOg372zUEwZjDB7DZYXfGTCuAj2OoEalgpBA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.338.0 - '@aws-sdk/util-buffer-from': 3.310.0 - '@aws-sdk/util-utf8': 3.310.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/invalid-dependency@3.338.0: - resolution: {integrity: sha512-m6r1fTTGSl0V6l8Z+Ii4Ei8VFpDmu0AT6A59ZhJaMZgxf925ywuCPydyDW9ZqTLE0e7CgxhEHEsH1+HzpVuHTw==} - dependencies: - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/is-array-buffer@3.310.0: - resolution: {integrity: sha512-urnbcCR+h9NWUnmOtet/s4ghvzsidFmspfhYaHAmSRdy9yDjdjBJMFjjsn85A1ODUktztm+cVncXjQ38WCMjMQ==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.6.1 - dev: true - - /@aws-sdk/lib-dynamodb@3.338.0(@aws-sdk/client-dynamodb@3.338.0)(@aws-sdk/smithy-client@3.374.0)(@aws-sdk/types@3.378.0): - resolution: {integrity: sha512-eJTwzRrfKOzMBHKWOtYnBrw26B/oQEE5xwMQbRI2fHsOINaHbbBwDE/dE0da6IHXr07elf+R2sPkZmj+E/NyoQ==} + /@aws-sdk/lib-dynamodb@3.398.0(@aws-sdk/client-dynamodb@3.398.0): + resolution: {integrity: sha512-d+xXyjenICSDqaMVLbIyzjwcM92EzeVMgJSrmbd5HY1Q80lkt4nQJ6rN2C8ZWpiCYHjFvK9Jxq5PzAN62HQA6g==} engines: {node: '>=14.0.0'} peerDependencies: '@aws-sdk/client-dynamodb': ^3.0.0 - '@aws-sdk/smithy-client': ^3.0.0 - '@aws-sdk/types': ^3.0.0 - dependencies: - '@aws-sdk/client-dynamodb': 3.338.0 - '@aws-sdk/smithy-client': 3.374.0 - '@aws-sdk/types': 3.378.0 - '@aws-sdk/util-dynamodb': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/middleware-content-length@3.338.0: - resolution: {integrity: sha512-m2C+yJaNmbA3ocBp/7ImUUuimymV5JsFdV7yAibpbYMX22g3q83nieOF9x0I66J0+h+/bcriz/T1ZJAPANLz/g==} - engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/protocol-http': 3.338.0 - '@aws-sdk/types': 3.338.0 + '@aws-sdk/client-dynamodb': 3.398.0 + '@aws-sdk/util-dynamodb': 3.398.0 tslib: 2.6.1 dev: true - /@aws-sdk/middleware-endpoint-discovery@3.338.0: - resolution: {integrity: sha512-LD2iQ7h65Q89Ef2rEo/tJqSsj6V4UpLjlbbnL7PkDSzOJNCIgRItH1nEXEHL6g94Kef5MQEzAKEg5W/H0ygJ3Q==} + /@aws-sdk/middleware-endpoint-discovery@3.398.0: + resolution: {integrity: sha512-Gf5HPhgCbTwPkoYlp50DnQRATljaTW3S9og7E+PrIIXdsTPGeZrlVFausreFhTXy3UOVP/3iGG3ajBQl84yNtw==} engines: {node: '>=14.0.0'} dependencies: '@aws-sdk/endpoint-cache': 3.310.0 - '@aws-sdk/protocol-http': 3.338.0 - '@aws-sdk/types': 3.338.0 + '@aws-sdk/types': 3.398.0 + '@smithy/protocol-http': 2.0.5 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true - /@aws-sdk/middleware-endpoint@3.338.0: - resolution: {integrity: sha512-bzL9Q8lFidg2NTjGVGDKI6yPG/XiPS+VIAMHJeihQmcv1alIy+N3IL4bEN15Fg+cwaGm+P3BevcLIHmcCOVb4w==} + /@aws-sdk/middleware-host-header@3.398.0: + resolution: {integrity: sha512-m+5laWdBaxIZK2ko0OwcCHJZJ5V1MgEIt8QVQ3k4/kOkN9ICjevOYmba751pHoTnbOYB7zQd6D2OT3EYEEsUcA==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/middleware-serde': 3.338.0 - '@aws-sdk/types': 3.338.0 - '@aws-sdk/url-parser': 3.338.0 - '@aws-sdk/util-middleware': 3.338.0 + '@aws-sdk/types': 3.398.0 + '@smithy/protocol-http': 2.0.5 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true - /@aws-sdk/middleware-host-header@3.338.0: - resolution: {integrity: sha512-k3C7oppkrqeKrAJt9XIl45SdELtnph9BF0QypjyRfT5MNEDnMMsQkc6xy3ZMqG5dWQq6B2l8C+JL7pOvkSQP3w==} + /@aws-sdk/middleware-logger@3.398.0: + resolution: {integrity: sha512-CiJjW+FL12elS6Pn7/UVjVK8HWHhXMfvHZvOwx/Qkpy340sIhkuzOO6fZEruECDTZhl2Wqn81XdJ1ZQ4pRKpCg==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/protocol-http': 3.338.0 - '@aws-sdk/types': 3.338.0 + '@aws-sdk/types': 3.398.0 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true - /@aws-sdk/middleware-host-header@3.379.1: - resolution: {integrity: sha512-LI4KpAFWNWVr2aH2vRVblr0Y8tvDz23lj8LOmbDmCrzd5M21nxuocI/8nEAQj55LiTIf9Zs+dHCdsyegnFXdrA==} + /@aws-sdk/middleware-recursion-detection@3.398.0: + resolution: {integrity: sha512-7QpOqPQAZNXDXv6vsRex4R8dLniL0E/80OPK4PPFsrCh9btEyhN9Begh4i1T+5lL28hmYkztLOkTQ2N5J3hgRQ==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.378.0 - '@smithy/protocol-http': 2.0.1 - '@smithy/types': 2.0.2 + '@aws-sdk/types': 3.398.0 + '@smithy/protocol-http': 2.0.5 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true - /@aws-sdk/middleware-logger@3.338.0: - resolution: {integrity: sha512-btj9U0Xovq/UAu3Ur4lAfF7Q3DvvwJ/0UUWsI6GgSzzqSOFgKCz7hCP2GZIT8aXEA5hJOpBOEMkNMjWPNa91Hg==} + /@aws-sdk/middleware-sdk-sts@3.398.0: + resolution: {integrity: sha512-+JH76XHEgfVihkY+GurohOQ5Z83zVN1nYcQzwCFnCDTh4dG4KwhnZKG+WPw6XJECocY0R+H0ivofeALHvVWJtQ==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.338.0 + '@aws-sdk/middleware-signing': 3.398.0 + '@aws-sdk/types': 3.398.0 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true - /@aws-sdk/middleware-logger@3.378.0: - resolution: {integrity: sha512-l1DyaDLm3KeBMNMuANI3scWh8Xvu248x+vw6Z7ExWOhGXFmQ1MW7YvASg/SdxWkhlF9HmkkTif1LdMB22x6QDA==} + /@aws-sdk/middleware-signing@3.398.0: + resolution: {integrity: sha512-O0KqXAix1TcvZBFt1qoFkHMUNJOSgjJTYS7lFTRKSwgsD27bdW2TM2r9R8DAccWFt5Amjkdt+eOwQMIXPGTm8w==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.378.0 - '@smithy/types': 2.0.2 - tslib: 2.6.1 - dev: true - - /@aws-sdk/middleware-recursion-detection@3.338.0: - resolution: {integrity: sha512-fu5KwiHHSqC8KTQH6xdJ9+dua4gQcXSFLE5fVsergqd0uVdsmhiI+IDfW6QNwF/lmCqnoKDkpeasuB98eG2tow==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/protocol-http': 3.338.0 - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/middleware-recursion-detection@3.378.0: - resolution: {integrity: sha512-mUMfHAz0oGNIWiTZHTVJb+I515Hqs2zx1j36Le4MMiiaMkPW1SRUF1FIwGuc1wh6E8jB5q+XfEMriDjRi4TZRA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.378.0 - '@smithy/protocol-http': 2.0.1 - '@smithy/types': 2.0.2 - tslib: 2.6.1 - dev: true - - /@aws-sdk/middleware-retry@3.338.0: - resolution: {integrity: sha512-nw1oPFkB7TdDG4Vlz2Td47ft/2Gmx1bA18QfE9K1mMWZ4nnoAL8xnHbowlTfHo62+BbFCAPu53PzDUCncBL0iw==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/protocol-http': 3.338.0 - '@aws-sdk/service-error-classification': 3.338.0 - '@aws-sdk/types': 3.338.0 - '@aws-sdk/util-middleware': 3.338.0 - '@aws-sdk/util-retry': 3.338.0 - tslib: 2.6.1 - uuid: 8.3.2 - dev: true - - /@aws-sdk/middleware-sdk-sts@3.338.0: - resolution: {integrity: sha512-aZ8eFVaot8oYQri1wOesrA3gLizeAHtlA/ELlqxoGDJtO011J4/hTHTn0iJGbktaCvc1L3TF6mgOsgXpudYqMg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/middleware-signing': 3.338.0 - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/middleware-sdk-sts@3.379.1: - resolution: {integrity: sha512-SK3gSyT0XbLiY12+AjLFYL9YngxOXHnZF3Z33Cdd4a+AUYrVBV7JBEEGD1Nlwrcmko+3XgaKlmgUaR5s91MYvg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/middleware-signing': 3.379.1 - '@aws-sdk/types': 3.378.0 - '@smithy/types': 2.0.2 - tslib: 2.6.1 - dev: true - - /@aws-sdk/middleware-serde@3.338.0: - resolution: {integrity: sha512-AabRLrE6sk9tqQlQ7z3kn4gTHNN7Anjk/AM0ZEu96WcWjedcpgM1vVpKTBE7vjnxcTRNq0CEM3GLtQqaZ7/HjQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/middleware-signing@3.338.0: - resolution: {integrity: sha512-AprhhShMF75mOx80SABujLwrU/w2uHQIvWd6aF3BsE5JRI3uQZRqspfjFCaK52HNLQPj3sCQUw1GeiZJ8GyWCw==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/property-provider': 3.338.0 - '@aws-sdk/protocol-http': 3.338.0 - '@aws-sdk/signature-v4': 3.338.0 - '@aws-sdk/types': 3.338.0 - '@aws-sdk/util-middleware': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/middleware-signing@3.379.1: - resolution: {integrity: sha512-kBk2ZUvR84EM4fICjr8K+Ykpf8SI1UzzPp2/UVYZ0X+4H/ZCjfSqohGRwHykMqeplne9qHSL7/rGJs1H3l3gPg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.378.0 - '@smithy/property-provider': 2.0.1 - '@smithy/protocol-http': 2.0.1 - '@smithy/signature-v4': 2.0.1 - '@smithy/types': 2.0.2 + '@aws-sdk/types': 3.398.0 + '@smithy/property-provider': 2.0.5 + '@smithy/protocol-http': 2.0.5 + '@smithy/signature-v4': 2.0.5 + '@smithy/types': 2.2.2 '@smithy/util-middleware': 2.0.0 tslib: 2.6.1 dev: true - /@aws-sdk/middleware-stack@3.338.0: - resolution: {integrity: sha512-9zXyiklX9AK9ZIXuIPzWzz2vevBEcnBs9UNIxiHl4NBZ8d8oyTvaES1PtFuwL6f7ANSZ9EGVQ2rdTTnMNxMI1A==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.6.1 - dev: true - - /@aws-sdk/middleware-user-agent@3.338.0: - resolution: {integrity: sha512-DMqODOsDMFMPcDw2Ya6a0i34AhaBDRpp3vJ+FK3zPxUIsv6iHA+XqEcXLOxROLLoydoyxus7k2U+EWibLZrFbQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/protocol-http': 3.338.0 - '@aws-sdk/types': 3.338.0 - '@aws-sdk/util-endpoints': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/middleware-user-agent@3.386.0: - resolution: {integrity: sha512-h6nVr5dvzrSLM+5BGbyqISh1p2NoTNv0+IZkMcGyig2jpdhbkMOPvvoOGMg16/cmelUQCguT26Jr7WYpLFDsTg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.378.0 - '@aws-sdk/util-endpoints': 3.386.0 - '@smithy/protocol-http': 2.0.1 - '@smithy/types': 2.0.2 - tslib: 2.6.1 - dev: true - - /@aws-sdk/node-config-provider@3.338.0: - resolution: {integrity: sha512-YO7yWg3ipnUI5u6D+Zn2NUpjj5krwc8zNWeY79ULVIp9g7faqGX3xMSjeRSrpZ83s5jg1dOm/+bB0gw7mCrRCw==} + /@aws-sdk/middleware-user-agent@3.398.0: + resolution: {integrity: sha512-nF1jg0L+18b5HvTcYzwyFgfZQQMELJINFqI0mi4yRKaX7T5a3aGp5RVLGGju/6tAGTuFbfBoEhkhU3kkxexPYQ==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/property-provider': 3.338.0 - '@aws-sdk/shared-ini-file-loader': 3.338.0 - '@aws-sdk/types': 3.338.0 + '@aws-sdk/types': 3.398.0 + '@aws-sdk/util-endpoints': 3.398.0 + '@smithy/protocol-http': 2.0.5 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true - /@aws-sdk/node-http-handler@3.338.0: - resolution: {integrity: sha512-V1BLzCruiv45tJ0vXjiamY8LncIsUFsXYJGDupomFYhWRN8L1MUB9f2vdKn5X3wXn/yKrluwTmNaryrIqd9akA==} + /@aws-sdk/token-providers@3.398.0: + resolution: {integrity: sha512-nrYgjzavGCKJL/48Vt0EL+OlIc5UZLfNGpgyUW9cv3XZwl+kXV0QB+HH0rHZZLfpbBgZ2RBIJR9uD5ieu/6hpQ==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/abort-controller': 3.338.0 - '@aws-sdk/protocol-http': 3.338.0 - '@aws-sdk/querystring-builder': 3.338.0 - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/property-provider@3.338.0: - resolution: {integrity: sha512-mC+ZJ738ipif6ZkH59gcipozYj1FOfpXr9pGVCA2hJGLDdaBwI2Jfpb2qCqbsTNtoCjBuIy+sQHGmUHyclgYHg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/protocol-http@3.338.0: - resolution: {integrity: sha512-JX03Q2gshdzOWtA/07kdpk0hqeOrOfwuF8TB97g66VCcIopYQkCeNH1zzkWu+RsGxfSlzQ7up+ZM6sclYXyB1A==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/querystring-builder@3.338.0: - resolution: {integrity: sha512-IB3YhO93Htwt2SxJx4VWsN57Rt1KEsvZ6PbneO4bcS96E04BlfBujYMZ+QxEM3EJxorhpkwbI2QnI12IjD8FhA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.338.0 - '@aws-sdk/util-uri-escape': 3.310.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/querystring-parser@3.338.0: - resolution: {integrity: sha512-vtI8Gqx4yj0BZlWonRMgLz68sHt5H48HN+ClnY+fDDB/8KLnCuwZ3TGKmYIbYbshL9wjJz0A9aLzuC6nPQ5JKw==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/service-error-classification@3.338.0: - resolution: {integrity: sha512-BJFr2mx/N3NbycGTlMMGRBc0tGcHXHEbMPy1H2RbejzL23zh27MchaL1WAK9SvwVMKS29hSDbhkuVR2ABRjerA==} - engines: {node: '>=14.0.0'} - dev: true - - /@aws-sdk/shared-ini-file-loader@3.338.0: - resolution: {integrity: sha512-MA1Sp97LFlOXcUaXgo47j86IsPRWYq1V/JqR+uu0zofZw4Xlt7Y6F+mmnDHvuuMy6R2ltzjXSwgrrW3k0bxFPA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/signature-v4@3.338.0: - resolution: {integrity: sha512-EwKTe/8Iwab/v0eo27w7DRYlqp9wEZEhuRfOMwTikUVH6iuTnW6AXjcIUfcRYBRbx2zqnRSiMAZkjN6ZFYm0bQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/is-array-buffer': 3.310.0 - '@aws-sdk/types': 3.338.0 - '@aws-sdk/util-hex-encoding': 3.310.0 - '@aws-sdk/util-middleware': 3.338.0 - '@aws-sdk/util-uri-escape': 3.310.0 - '@aws-sdk/util-utf8': 3.310.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/smithy-client@3.338.0: - resolution: {integrity: sha512-IpFLdLG8GwaiFdqVXf+WyU47Hfa2BMIupAU6iSkE2ZO0lBdg+efn/BBwis5WbBNTDCaaU0xH9y68SmnqqtD7pA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/middleware-stack': 3.338.0 - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/smithy-client@3.374.0: - resolution: {integrity: sha512-YQBdO/Nv5EXBg/qfMF4GgYYLNN3Y/06MyuVBYILC1TKAnMoLy2FV0VOYyediagepAcWPdJqyUq4MCNNBy0CPRg==} - engines: {node: '>=14.0.0'} - deprecated: This package has moved to @smithy/smithy-client - dependencies: - '@smithy/smithy-client': 1.1.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/token-providers@3.338.0: - resolution: {integrity: sha512-wuiEGcWiMeq5N68M489i2iGYcCad9p1btNEOFgus+JO3DRSA6HZXizLI1wqfbUm5Ei8512AvUKB6N8PMzahQsg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/client-sso-oidc': 3.338.0 - '@aws-sdk/property-provider': 3.338.0 - '@aws-sdk/shared-ini-file-loader': 3.338.0 - '@aws-sdk/types': 3.338.0 + '@aws-crypto/sha256-browser': 3.0.0 + '@aws-crypto/sha256-js': 3.0.0 + '@aws-sdk/middleware-host-header': 3.398.0 + '@aws-sdk/middleware-logger': 3.398.0 + '@aws-sdk/middleware-recursion-detection': 3.398.0 + '@aws-sdk/middleware-user-agent': 3.398.0 + '@aws-sdk/types': 3.398.0 + '@aws-sdk/util-endpoints': 3.398.0 + '@aws-sdk/util-user-agent-browser': 3.398.0 + '@aws-sdk/util-user-agent-node': 3.398.0 + '@smithy/config-resolver': 2.0.5 + '@smithy/fetch-http-handler': 2.0.5 + '@smithy/hash-node': 2.0.5 + '@smithy/invalid-dependency': 2.0.5 + '@smithy/middleware-content-length': 2.0.5 + '@smithy/middleware-endpoint': 2.0.5 + '@smithy/middleware-retry': 2.0.5 + '@smithy/middleware-serde': 2.0.5 + '@smithy/middleware-stack': 2.0.0 + '@smithy/node-config-provider': 2.0.5 + '@smithy/node-http-handler': 2.0.5 + '@smithy/property-provider': 2.0.1 + '@smithy/protocol-http': 2.0.5 + '@smithy/shared-ini-file-loader': 2.0.5 + '@smithy/smithy-client': 2.0.5 + '@smithy/types': 2.2.2 + '@smithy/url-parser': 2.0.5 + '@smithy/util-base64': 2.0.0 + '@smithy/util-body-length-browser': 2.0.0 + '@smithy/util-body-length-node': 2.1.0 + '@smithy/util-defaults-mode-browser': 2.0.5 + '@smithy/util-defaults-mode-node': 2.0.5 + '@smithy/util-retry': 2.0.0 + '@smithy/util-utf8': 2.0.0 tslib: 2.6.1 transitivePeerDependencies: - aws-crt dev: true - /@aws-sdk/token-providers@3.386.0: - resolution: {integrity: sha512-DStdqBtpO0FRC4mDCIPtrpLCFMnYJFo4cYlUyr9CKvKvh2IzPMU4rsKQjUhtmzdjLEvPTAcdfRx2Q9/sJkfe9Q==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.378.0 - '@smithy/property-provider': 2.0.1 - '@smithy/shared-ini-file-loader': 2.0.1 - '@smithy/types': 2.0.2 - tslib: 2.6.1 - dev: true - - /@aws-sdk/types@3.338.0: - resolution: {integrity: sha512-hrNK15o+EObLrl9oWOyxJN2dwjgbdBMGolLEVP/wR/+M9ojHgk/x1kMsCVcV82a8Vgdtqx1TyOC3UugUPT0+NA==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.6.1 - dev: true - - /@aws-sdk/types@3.378.0: - resolution: {integrity: sha512-qP0CvR/ItgktmN8YXpGQglzzR/6s0nrsQ4zIfx3HMwpsBTwuouYahcCtF1Vr82P4NFcoDA412EJahJ2pIqEd+w==} - engines: {node: '>=14.0.0'} - dependencies: - '@smithy/types': 2.0.2 - tslib: 2.6.1 - dev: true - - /@aws-sdk/url-parser@3.338.0: - resolution: {integrity: sha512-x8a5swfZ6iWJZEA8rm99OKQ1A6xhWPP1taQUzoPavGCzPAOqyc8cd0FcXYMxvtXb3FeBhGaI8tiGKvelJro0+A==} - dependencies: - '@aws-sdk/querystring-parser': 3.338.0 - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/util-base64@3.310.0: - resolution: {integrity: sha512-v3+HBKQvqgdzcbL+pFswlx5HQsd9L6ZTlyPVL2LS9nNXnCcR3XgGz9jRskikRUuUvUXtkSG1J88GAOnJ/apTPg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/util-buffer-from': 3.310.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/util-body-length-browser@3.310.0: - resolution: {integrity: sha512-sxsC3lPBGfpHtNTUoGXMQXLwjmR0zVpx0rSvzTPAuoVILVsp5AU/w5FphNPxD5OVIjNbZv9KsKTuvNTiZjDp9g==} - dependencies: - tslib: 2.6.1 - dev: true - - /@aws-sdk/util-body-length-node@3.310.0: - resolution: {integrity: sha512-2tqGXdyKhyA6w4zz7UPoS8Ip+7sayOg9BwHNidiGm2ikbDxm1YrCfYXvCBdwaJxa4hJfRVz+aL9e+d3GqPI9pQ==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.6.1 - dev: true - - /@aws-sdk/util-buffer-from@3.310.0: - resolution: {integrity: sha512-i6LVeXFtGih5Zs8enLrt+ExXY92QV25jtEnTKHsmlFqFAuL3VBeod6boeMXkN2p9lbSVVQ1sAOOYZOHYbYkntw==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/is-array-buffer': 3.310.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/util-config-provider@3.310.0: - resolution: {integrity: sha512-xIBaYo8dwiojCw8vnUcIL4Z5tyfb1v3yjqyJKJWV/dqKUFOOS0U591plmXbM+M/QkXyML3ypon1f8+BoaDExrg==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.6.1 - dev: true - - /@aws-sdk/util-defaults-mode-browser@3.338.0: - resolution: {integrity: sha512-Zfr5c7JKMJTfb7z+hgd0ioU5iw+wId6Cppc5V1HpZuS2YY4Mn3aJIixzyzhIoCzbmk/yIkf96981epM9eo3/TA==} - engines: {node: '>= 10.0.0'} - dependencies: - '@aws-sdk/property-provider': 3.338.0 - '@aws-sdk/types': 3.338.0 - bowser: 2.11.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/util-defaults-mode-node@3.338.0: - resolution: {integrity: sha512-DFM3BSpSetshZTgTjueCkAYZWS0tn5zl7SjkSpFhWQZ8Tt/Df3/DEjcPvxzmC/5vgYSUXNsqcI7lLAJk9aGZAA==} - engines: {node: '>= 10.0.0'} - dependencies: - '@aws-sdk/config-resolver': 3.338.0 - '@aws-sdk/credential-provider-imds': 3.338.0 - '@aws-sdk/node-config-provider': 3.338.0 - '@aws-sdk/property-provider': 3.338.0 - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/util-dynamodb@3.338.0: - resolution: {integrity: sha512-hQzumWnMtFUpJRkLNR+oa1Ip9OGMVyI0hzO5pST8L66M9c+KCu75fLWj3KqE4pt/dIPUfFaeL4/ETEirydm5JA==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.6.1 - dev: true - - /@aws-sdk/util-endpoints@3.338.0: - resolution: {integrity: sha512-0gBQcohbNcBsBR7oyaD0Dg2m6qOmfp0G1iN/NM23gwAr2H3ni8tUXfs1HsZzxikOwUr6dSLASokc30vQXBF44A==} + /@aws-sdk/types@3.398.0: + resolution: {integrity: sha512-r44fkS+vsEgKCuEuTV+TIk0t0m5ZlXHNjSDYEUvzLStbbfUFiNus/YG4UCa0wOk9R7VuQI67badsvvPeVPCGDQ==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.338.0 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true - /@aws-sdk/util-endpoints@3.386.0: - resolution: {integrity: sha512-FDQRC9f78Kx12KsR43MukLRfqF3BNz5VfFdKP9ZYx3KK+bMjU1czjmjOS8bNMJWYM1Sn+nobBpPS3e2uupBtpg==} + /@aws-sdk/util-dynamodb@3.398.0: + resolution: {integrity: sha512-IKKZWK0oLPmMAHjFTB61CPThHjQZ7YsBuTZ/lDrXjzSpNXz7KObsUnGOV7O7VCLEm3zPVHWGmkNUf7uPFc38Ng==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.378.0 tslib: 2.6.1 dev: true - /@aws-sdk/util-hex-encoding@3.310.0: - resolution: {integrity: sha512-sVN7mcCCDSJ67pI1ZMtk84SKGqyix6/0A1Ab163YKn+lFBQRMKexleZzpYzNGxYzmQS6VanP/cfU7NiLQOaSfA==} + /@aws-sdk/util-endpoints@3.398.0: + resolution: {integrity: sha512-Fy0gLYAei/Rd6BrXG4baspCnWTUSd0NdokU1pZh4KlfEAEN1i8SPPgfiO5hLk7+2inqtCmqxVJlfqbMVe9k4bw==} engines: {node: '>=14.0.0'} dependencies: + '@aws-sdk/types': 3.398.0 tslib: 2.6.1 dev: true @@ -1224,47 +681,17 @@ packages: tslib: 2.6.1 dev: true - /@aws-sdk/util-middleware@3.338.0: - resolution: {integrity: sha512-oQuAmhi16HWEqVa+Nq4VD4Ymet9vS+uiW92reaagQrW2QFjAgJW9A6pU0PcIHF9sWY1iDKeNdV5b9odQ45PDJA==} - engines: {node: '>=14.0.0'} + /@aws-sdk/util-user-agent-browser@3.398.0: + resolution: {integrity: sha512-A3Tzx1tkDHlBT+IgxmsMCHbV8LM7SwwCozq2ZjJRx0nqw3MCrrcxQFXldHeX/gdUMO+0Oocb7HGSnVODTq+0EA==} dependencies: - tslib: 2.6.1 - dev: true - - /@aws-sdk/util-retry@3.338.0: - resolution: {integrity: sha512-diR6M3gJgSgBg/87L2e8iF8urG+LOW9ZGWxhntYpYX4uhiIjwNgUPUa993553C8GIOZDHez5X9ExU4asYGQ71Q==} - engines: {node: '>= 14.0.0'} - dependencies: - '@aws-sdk/service-error-classification': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/util-uri-escape@3.310.0: - resolution: {integrity: sha512-drzt+aB2qo2LgtDoiy/3sVG8w63cgLkqFIa2NFlGpUgHFWTXkqtbgf4L5QdjRGKWhmZsnqkbtL7vkSWEcYDJ4Q==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.6.1 - dev: true - - /@aws-sdk/util-user-agent-browser@3.338.0: - resolution: {integrity: sha512-3e8D+SOtOQEtRtksOEF7EC26xPkuY6YK6biLgdtvR9JspK96rHk5eX1HEJeBJJqbxhyPaxpIw+OhWhnsrUS3hA==} - dependencies: - '@aws-sdk/types': 3.338.0 + '@aws-sdk/types': 3.398.0 + '@smithy/types': 2.2.2 bowser: 2.11.0 tslib: 2.6.1 dev: true - /@aws-sdk/util-user-agent-browser@3.378.0: - resolution: {integrity: sha512-FSCpagzftK1W+m7Ar6lpX7/Gr9y5P56nhFYz8U4EYQ4PkufS6czWX9YW+/FA5OYV0vlQ/SvPqMnzoHIPUNhZrQ==} - dependencies: - '@aws-sdk/types': 3.378.0 - '@smithy/types': 2.0.2 - bowser: 2.11.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/util-user-agent-node@3.338.0: - resolution: {integrity: sha512-rc+bC5KM9h25urRc+MXuViJkJ+qYG2NlCRw6xm2lSIvHFJTUjH1ZMO3mqNDYkGnQRbj0mmrVe+N77TJZGf3Q2Q==} + /@aws-sdk/util-user-agent-node@3.398.0: + resolution: {integrity: sha512-RTVQofdj961ej4//fEkppFf4KXqKGMTCqJYghx3G0C/MYXbg7MGl7LjfNGtJcboRE8pfHHQ/TUWBDA7RIAPPlQ==} engines: {node: '>=14.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -1272,23 +699,9 @@ packages: aws-crt: optional: true dependencies: - '@aws-sdk/node-config-provider': 3.338.0 - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/util-user-agent-node@3.378.0: - resolution: {integrity: sha512-IdwVJV0E96MkJeFte4dlWqvB+oiqCiZ5lOlheY3W9NynTuuX0GGYNC8Y9yIsV8Oava1+ujpJq0ww6qXdYxmO4A==} - engines: {node: '>=14.0.0'} - peerDependencies: - aws-crt: '>=1.0.0' - peerDependenciesMeta: - aws-crt: - optional: true - dependencies: - '@aws-sdk/types': 3.378.0 - '@smithy/node-config-provider': 2.0.1 - '@smithy/types': 2.0.2 + '@aws-sdk/types': 3.398.0 + '@smithy/node-config-provider': 2.0.5 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true @@ -1298,23 +711,6 @@ packages: tslib: 2.6.1 dev: true - /@aws-sdk/util-utf8@3.310.0: - resolution: {integrity: sha512-DnLfFT8uCO22uOJc0pt0DsSNau1GTisngBCDw8jQuWT5CqogMJu4b/uXmwEqfj8B3GX6Xsz8zOd6JpRlPftQoA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/util-buffer-from': 3.310.0 - tslib: 2.6.1 - dev: true - - /@aws-sdk/util-waiter@3.338.0: - resolution: {integrity: sha512-15yWYJo/M4VDpZjlXgQDM4Du8UjX33eIVPJDrOmn/u+UrD6QUXoBuLXKns0uAMUTPFacBGZ0NwMywxieq0g11Q==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/abort-controller': 3.338.0 - '@aws-sdk/types': 3.338.0 - tslib: 2.6.1 - dev: true - /@azure/abort-controller@1.1.0: resolution: {integrity: sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==} engines: {node: '>=12.0.0'} @@ -2548,27 +1944,61 @@ packages: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: true - /@smithy/abort-controller@1.1.0: - resolution: {integrity: sha512-5imgGUlZL4dW4YWdMYAKLmal9ny/tlenM81QZY7xYyb76z9Z/QOg7oM5Ak9HQl8QfFTlGVWwcMXl+54jroRgEQ==} - engines: {node: '>=14.0.0'} + /@sinonjs/commons@1.8.6: + resolution: {integrity: sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==} dependencies: - '@smithy/types': 1.2.0 - tslib: 2.6.1 + type-detect: 4.0.8 + dev: true + + /@sinonjs/commons@2.0.0: + resolution: {integrity: sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==} + dependencies: + type-detect: 4.0.8 + dev: true + + /@sinonjs/commons@3.0.0: + resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} + dependencies: + type-detect: 4.0.8 + dev: true + + /@sinonjs/fake-timers@10.3.0: + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + dependencies: + '@sinonjs/commons': 3.0.0 + dev: true + + /@sinonjs/fake-timers@9.1.2: + resolution: {integrity: sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==} + dependencies: + '@sinonjs/commons': 1.8.6 + dev: true + + /@sinonjs/samsam@7.0.1: + resolution: {integrity: sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw==} + dependencies: + '@sinonjs/commons': 2.0.0 + lodash.get: 4.4.2 + type-detect: 4.0.8 + dev: true + + /@sinonjs/text-encoding@0.7.2: + resolution: {integrity: sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==} dev: true - /@smithy/abort-controller@2.0.1: - resolution: {integrity: sha512-0s7XjIbsTwZyUW9OwXQ8J6x1UiA1TNCh60Vaw56nHahL7kUZsLhmTlWiaxfLkFtO2Utkj8YewcpHTYpxaTzO+w==} + /@smithy/abort-controller@2.0.5: + resolution: {integrity: sha512-byVZ2KWLMPYAZGKjRpniAzLcygJO4ruClZKdJTuB0eCB76ONFTdptBHlviHpAZXknRz7skYWPfcgO9v30A1SyA==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.0.2 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true - /@smithy/config-resolver@2.0.1: - resolution: {integrity: sha512-l83Pm7hV+8CBQOCmBRopWDtF+CURUJol7NsuPYvimiDhkC2F8Ba9T1imSFE+pD1UIJ9jlsDPAnZfPJT5cjnuEw==} + /@smithy/config-resolver@2.0.5: + resolution: {integrity: sha512-n0c2AXz+kjALY2FQr7Zy9zhYigXzboIh1AuUUVCqFBKFtdEvTwnwPXrTDoEehLiRTUHNL+4yzZ3s+D0kKYSLSg==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.0.2 + '@smithy/types': 2.2.2 '@smithy/util-config-provider': 2.0.0 '@smithy/util-middleware': 2.0.0 tslib: 2.6.1 @@ -2580,61 +2010,55 @@ packages: dependencies: '@smithy/node-config-provider': 2.0.1 '@smithy/property-provider': 2.0.1 - '@smithy/types': 2.0.2 + '@smithy/types': 2.2.2 '@smithy/url-parser': 2.0.1 tslib: 2.6.1 dev: true - /@smithy/eventstream-codec@2.0.1: - resolution: {integrity: sha512-/IiNB7gQM2y2ZC/GAWOWDa8+iXfhr1g9Xe5979cQEOdCWDISvrAiv18cn3OtIQUhbYOR3gm7QtCpkq1to2takQ==} + /@smithy/credential-provider-imds@2.0.5: + resolution: {integrity: sha512-KFcf/e0meFkQNyteJ65f1G19sgUEY1e5zL7hyAEUPz2SEfBmC9B37WyRq87G3MEEsvmAWwCRu7nFFYUKtR3svQ==} + engines: {node: '>=14.0.0'} dependencies: - '@aws-crypto/crc32': 3.0.0 - '@smithy/types': 2.0.2 - '@smithy/util-hex-encoding': 2.0.0 + '@smithy/node-config-provider': 2.0.5 + '@smithy/property-provider': 2.0.5 + '@smithy/types': 2.2.2 + '@smithy/url-parser': 2.0.5 tslib: 2.6.1 dev: true - /@smithy/fetch-http-handler@1.1.0: - resolution: {integrity: sha512-N22C9R44u5WGlcY+Wuv8EXmCAq62wWwriRAuoczMEwAIjPbvHSthyPSLqI4S7kAST1j6niWg8kwpeJ3ReAv3xg==} + /@smithy/eventstream-codec@2.0.5: + resolution: {integrity: sha512-iqR6OuOV3zbQK8uVs9o+9AxhVk8kW9NAxA71nugwUB+kTY9C35pUd0A5/m4PRT0Y0oIW7W4kgnSR3fdYXQjECw==} dependencies: - '@smithy/protocol-http': 1.2.0 - '@smithy/querystring-builder': 1.1.0 - '@smithy/types': 1.2.0 - '@smithy/util-base64': 1.1.0 + '@aws-crypto/crc32': 3.0.0 + '@smithy/types': 2.2.2 + '@smithy/util-hex-encoding': 2.0.0 tslib: 2.6.1 dev: true - /@smithy/fetch-http-handler@2.0.1: - resolution: {integrity: sha512-/SoU/ClazgcdOxgE4zA7RX8euiELwpsrKCSvulVQvu9zpmqJRyEJn8ZTWYFV17/eHOBdHTs9kqodhNhsNT+cUw==} + /@smithy/fetch-http-handler@2.0.5: + resolution: {integrity: sha512-EzFoMowdBNy1VqtvkiXgPFEdosIAt4/4bgZ8uiDiUyfhmNXq/3bV+CagPFFBsgFOR/X2XK4zFZHRsoa7PNHVVg==} dependencies: - '@smithy/protocol-http': 2.0.1 - '@smithy/querystring-builder': 2.0.1 - '@smithy/types': 2.0.2 + '@smithy/protocol-http': 2.0.5 + '@smithy/querystring-builder': 2.0.5 + '@smithy/types': 2.2.2 '@smithy/util-base64': 2.0.0 tslib: 2.6.1 dev: true - /@smithy/hash-node@2.0.1: - resolution: {integrity: sha512-oTKYimQdF4psX54ZonpcIE+MXjMUWFxLCNosjPkJPFQ9whRX0K/PFX/+JZGRQh3zO9RlEOEUIbhy9NO+Wha6hw==} + /@smithy/hash-node@2.0.5: + resolution: {integrity: sha512-mk551hIywBITT+kXruRNXk7f8Fy7DTzBjZJSr/V6nolYKmUHIG3w5QU6nO9qPYEQGKc/yEPtkpdS28ndeG93lA==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.0.2 + '@smithy/types': 2.2.2 '@smithy/util-buffer-from': 2.0.0 '@smithy/util-utf8': 2.0.0 tslib: 2.6.1 dev: true - /@smithy/invalid-dependency@2.0.1: - resolution: {integrity: sha512-2q/Eb0AE662zwyMV+z+TL7deBwcHCgaZZGc0RItamBE8kak3MzCi/EZCNoFWoBfxgQ4jfR12wm8KKsSXhJzJtQ==} - dependencies: - '@smithy/types': 2.0.2 - tslib: 2.6.1 - dev: true - - /@smithy/is-array-buffer@1.1.0: - resolution: {integrity: sha512-twpQ/n+3OWZJ7Z+xu43MJErmhB/WO/mMTnqR6PwWQShvSJ/emx5d1N59LQZk6ZpTAeuRWrc+eHhkzTp9NFjNRQ==} - engines: {node: '>=14.0.0'} + /@smithy/invalid-dependency@2.0.5: + resolution: {integrity: sha512-0wEi+JT0hM+UUwrJVYbqjuGFhy5agY/zXyiN7BNAJ1XoCDjU5uaNSj8ekPWsXd/d4yM6NSe8UbPd8cOc1+3oBQ==} dependencies: + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true @@ -2645,51 +2069,44 @@ packages: tslib: 2.6.1 dev: true - /@smithy/middleware-content-length@2.0.1: - resolution: {integrity: sha512-IZhRSk5GkVBcrKaqPXddBS2uKhaqwBgaSgbBb1OJyGsKe7SxRFbclWS0LqOR9fKUkDl+3lL8E2ffpo6EQg0igw==} + /@smithy/middleware-content-length@2.0.5: + resolution: {integrity: sha512-E7VwV5H02fgZIUGRli4GevBCAPvkyEI/fgl9SU47nPPi3DAAX3nEtUb8xfGbXjOcJ5BdSUoWWZn42tEd/blOqA==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/protocol-http': 2.0.1 - '@smithy/types': 2.0.2 + '@smithy/protocol-http': 2.0.5 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true - /@smithy/middleware-endpoint@2.0.1: - resolution: {integrity: sha512-uz/KI1MBd9WHrrkVFZO4L4Wyv24raf0oR4EsOYEeG5jPJO5U+C7MZGLcMxX8gWERDn1sycBDqmGv8fjUMLxT6w==} + /@smithy/middleware-endpoint@2.0.5: + resolution: {integrity: sha512-tyzDuoNTbsMQCq5Xkc4QOt6e2GACUllQIV8SQ5fc59FtOIV9/vbf58/GxVjZm2o8+MMbdDBANjTDZe/ijZKfyA==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/middleware-serde': 2.0.1 - '@smithy/types': 2.0.2 - '@smithy/url-parser': 2.0.1 + '@smithy/middleware-serde': 2.0.5 + '@smithy/types': 2.2.2 + '@smithy/url-parser': 2.0.5 '@smithy/util-middleware': 2.0.0 tslib: 2.6.1 dev: true - /@smithy/middleware-retry@2.0.1: - resolution: {integrity: sha512-NKHF4i0gjSyjO6C0ZyjEpNqzGgIu7s8HOK6oT/1Jqws2Q1GynR1xV8XTUs1gKXeaNRzbzKQRewHHmfPwZjOtHA==} + /@smithy/middleware-retry@2.0.5: + resolution: {integrity: sha512-ulIfbFyzQTVnJbLjUl1CTSi0etg6tej/ekwaLp0Gn8ybUkDkKYa+uB6CF/m2J5B6meRwyJlsryR+DjaOVyiicg==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/protocol-http': 2.0.1 + '@smithy/protocol-http': 2.0.5 '@smithy/service-error-classification': 2.0.0 - '@smithy/types': 2.0.2 + '@smithy/types': 2.2.2 '@smithy/util-middleware': 2.0.0 '@smithy/util-retry': 2.0.0 tslib: 2.6.1 uuid: 8.3.2 dev: true - /@smithy/middleware-serde@2.0.1: - resolution: {integrity: sha512-uKxPaC6ItH9ZXdpdqNtf8sda7GcU4SPMp0tomq/5lUg9oiMa/Q7+kD35MUrpKaX3IVXVrwEtkjCU9dogZ/RAUA==} - engines: {node: '>=14.0.0'} - dependencies: - '@smithy/types': 2.0.2 - tslib: 2.6.1 - dev: true - - /@smithy/middleware-stack@1.1.0: - resolution: {integrity: sha512-XynYiIvXNea2BbLcppvpNK0zu8o2woJqgnmxqYTn4FWagH/Hr2QIk8LOsUz7BIJ4tooFhmx8urHKCdlPbbPDCA==} + /@smithy/middleware-serde@2.0.5: + resolution: {integrity: sha512-in0AA5sous74dOfTGU9rMJBXJ0bDVNxwdXtEt5lh3FVd2sEyjhI+rqpLLRF1E4ixbw3RSEf80hfRpcPdjg4vvQ==} engines: {node: '>=14.0.0'} dependencies: + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true @@ -2705,30 +2122,29 @@ packages: engines: {node: '>=14.0.0'} dependencies: '@smithy/property-provider': 2.0.1 - '@smithy/shared-ini-file-loader': 2.0.1 - '@smithy/types': 2.0.2 + '@smithy/shared-ini-file-loader': 2.0.5 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true - /@smithy/node-http-handler@1.1.0: - resolution: {integrity: sha512-d3kRriEgaIiGXLziAM8bjnaLn1fthCJeTLZIwEIpzQqe6yPX0a+yQoLCTyjb2fvdLwkMoG4p7THIIB5cj5lkbg==} + /@smithy/node-config-provider@2.0.5: + resolution: {integrity: sha512-LRtjV9WkhONe2lVy+ipB/l1GX60ybzBmFyeRUoLUXWKdnZ3o81jsnbKzMK8hKq8eFSWPk+Lmyx6ZzCQabGeLxg==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/abort-controller': 1.1.0 - '@smithy/protocol-http': 1.2.0 - '@smithy/querystring-builder': 1.1.0 - '@smithy/types': 1.2.0 + '@smithy/property-provider': 2.0.5 + '@smithy/shared-ini-file-loader': 2.0.5 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true - /@smithy/node-http-handler@2.0.1: - resolution: {integrity: sha512-Zv3fxk3p9tsmPT2CKMsbuwbbxnq2gzLDIulxv+yI6aE+02WPYorObbbe9gh7SW3weadMODL1vTfOoJ9yFypDzg==} + /@smithy/node-http-handler@2.0.5: + resolution: {integrity: sha512-lZm5DZf4b3V0saUw9WTC4/du887P6cy2fUyQgQQKRRV6OseButyD5yTzeMmXE53CaXJBMBsUvvIQ0hRVxIq56w==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/abort-controller': 2.0.1 - '@smithy/protocol-http': 2.0.1 - '@smithy/querystring-builder': 2.0.1 - '@smithy/types': 2.0.2 + '@smithy/abort-controller': 2.0.5 + '@smithy/protocol-http': 2.0.5 + '@smithy/querystring-builder': 2.0.5 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true @@ -2736,49 +2152,48 @@ packages: resolution: {integrity: sha512-pmJRyY9SF6sutWIktIhe+bUdSQDxv/qZ4mYr3/u+u45riTPN7nmRxPo+e4sjWVoM0caKFjRSlj3tf5teRFy0Vg==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.0.2 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true - /@smithy/protocol-http@1.2.0: - resolution: {integrity: sha512-GfGfruksi3nXdFok5RhgtOnWe5f6BndzYfmEXISD+5gAGdayFGpjWu5pIqIweTudMtse20bGbc+7MFZXT1Tb8Q==} + /@smithy/property-provider@2.0.5: + resolution: {integrity: sha512-cAFSUhX6aiHcmpWfrCLKvwBtgN1F6A0N8qY/8yeSi0LRLmhGqsY1/YTxFE185MCVzYbqBGXVr9TBv4RUcIV4rA==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 1.2.0 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true - /@smithy/protocol-http@2.0.1: - resolution: {integrity: sha512-mrkMAp0wtaDEIkgRObWYxI1Kun1tm6Iu6rK+X4utb6Ah7Uc3Kk4VIWwK/rBHdYGReiLIrxFCB1rq4a2gyZnSgg==} + /@smithy/protocol-http@2.0.5: + resolution: {integrity: sha512-d2hhHj34mA2V86doiDfrsy2fNTnUOowGaf9hKb0hIPHqvcnShU4/OSc4Uf1FwHkAdYF3cFXTrj5VGUYbEuvMdw==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.0.2 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true - /@smithy/querystring-builder@1.1.0: - resolution: {integrity: sha512-gDEi4LxIGLbdfjrjiY45QNbuDmpkwh9DX4xzrR2AzjjXpxwGyfSpbJaYhXARw9p17VH0h9UewnNQXNwaQyYMDA==} + /@smithy/querystring-builder@2.0.5: + resolution: {integrity: sha512-4DCX9krxLzATj+HdFPC3i8pb7XTAWzzKqSw8aTZMjXjtQY+vhe4azMAqIvbb6g7JKwIkmkRAjK6EXO3YWSnJVQ==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 1.2.0 - '@smithy/util-uri-escape': 1.1.0 + '@smithy/types': 2.2.2 + '@smithy/util-uri-escape': 2.0.0 tslib: 2.6.1 dev: true - /@smithy/querystring-builder@2.0.1: - resolution: {integrity: sha512-bp+93WFzx1FojVEIeFPtG0A1pKsFdCUcZvVdZdRlmNooOUrz9Mm9bneRd8hDwAQ37pxiZkCOxopSXXRQN10mYw==} + /@smithy/querystring-parser@2.0.1: + resolution: {integrity: sha512-h+e7k1z+IvI2sSbUBG9Aq46JsgLl4UqIUl6aigAlRBj+P6ocNXpM6Yn1vMBw5ijtXeZbYpd1YvCxwDgdw3jhmg==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.0.2 - '@smithy/util-uri-escape': 2.0.0 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true - /@smithy/querystring-parser@2.0.1: - resolution: {integrity: sha512-h+e7k1z+IvI2sSbUBG9Aq46JsgLl4UqIUl6aigAlRBj+P6ocNXpM6Yn1vMBw5ijtXeZbYpd1YvCxwDgdw3jhmg==} + /@smithy/querystring-parser@2.0.5: + resolution: {integrity: sha512-C2stCULH0r54KBksv3AWcN8CLS3u9+WsEW8nBrvctrJ5rQTNa1waHkffpVaiKvcW2nP0aIMBPCobD/kYf/q9mA==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.0.2 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true @@ -2787,21 +2202,21 @@ packages: engines: {node: '>=14.0.0'} dev: true - /@smithy/shared-ini-file-loader@2.0.1: - resolution: {integrity: sha512-a463YiZrPGvM+F336rIF8pLfQsHAdCRAn/BiI/EWzg5xLoxbC7GSxIgliDDXrOu0z8gT3nhVsif85eU6jyct3A==} + /@smithy/shared-ini-file-loader@2.0.5: + resolution: {integrity: sha512-Mvtk6FwMtfbKRC4YuSsIqRYp9WTxsSUJVVo2djgyhcacKGMqicHDWSAmgy3sDrKv+G/G6xTZCPwm6pJARtdxVg==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.0.2 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true - /@smithy/signature-v4@2.0.1: - resolution: {integrity: sha512-jztv5Mirca42ilxmMDjzLdXcoAmRhZskGafGL49sRo5u7swEZcToEFrq6vtX5YMbSyTVrE9Teog5EFexY5Ff2Q==} + /@smithy/signature-v4@2.0.5: + resolution: {integrity: sha512-ABIzXmUDXK4n2c9cXjQLELgH2RdtABpYKT+U131e2I6RbCypFZmxIHmIBufJzU2kdMCQ3+thBGDWorAITFW04A==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/eventstream-codec': 2.0.1 + '@smithy/eventstream-codec': 2.0.5 '@smithy/is-array-buffer': 2.0.0 - '@smithy/types': 2.0.2 + '@smithy/types': 2.2.2 '@smithy/util-hex-encoding': 2.0.0 '@smithy/util-middleware': 2.0.0 '@smithy/util-uri-escape': 2.0.0 @@ -2809,35 +2224,18 @@ packages: tslib: 2.6.1 dev: true - /@smithy/smithy-client@1.1.0: - resolution: {integrity: sha512-j32SGgVhv2G9nBTmel9u3OXux8KG20ssxuFakJrEeDug3kqbl1qrGzVLCe+Eib402UDtA0Sp1a4NZ2SEXDBxag==} - engines: {node: '>=14.0.0'} - dependencies: - '@smithy/middleware-stack': 1.1.0 - '@smithy/types': 1.2.0 - '@smithy/util-stream': 1.1.0 - tslib: 2.6.1 - dev: true - - /@smithy/smithy-client@2.0.1: - resolution: {integrity: sha512-LHC5m6tYpEu1iNbONfvMbwtErboyTZJfEIPoD78Ei5MVr36vZQCaCla5mvo36+q/a2NAk2//fA5Rx3I1Kf7+lQ==} + /@smithy/smithy-client@2.0.5: + resolution: {integrity: sha512-kCTFr8wfOAWKDzGvfBElc6shHigWtHNhMQ1IbosjC4jOlayFyZMSs2PysKB+Ox/dhQ41KqOzgVjgiQ+PyWqHMQ==} engines: {node: '>=14.0.0'} dependencies: '@smithy/middleware-stack': 2.0.0 - '@smithy/types': 2.0.2 - '@smithy/util-stream': 2.0.1 - tslib: 2.6.1 - dev: true - - /@smithy/types@1.2.0: - resolution: {integrity: sha512-z1r00TvBqF3dh4aHhya7nz1HhvCg4TRmw51fjMrh5do3h+ngSstt/yKlNbHeb9QxJmFbmN8KEVSWgb1bRvfEoA==} - engines: {node: '>=14.0.0'} - dependencies: + '@smithy/types': 2.2.2 + '@smithy/util-stream': 2.0.5 tslib: 2.6.1 dev: true - /@smithy/types@2.0.2: - resolution: {integrity: sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==} + /@smithy/types@2.2.2: + resolution: {integrity: sha512-4PS0y1VxDnELGHGgBWlDksB2LJK8TG8lcvlWxIsgR+8vROI7Ms8h1P4FQUx+ftAX2QZv5g1CJCdhdRmQKyonyw==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.6.1 @@ -2847,15 +2245,15 @@ packages: resolution: {integrity: sha512-NpHVOAwddo+OyyIoujDL9zGL96piHWrTNXqltWmBvlUoWgt1HPyBuKs6oHjioyFnNZXUqveTOkEEq0U5w6Uv8A==} dependencies: '@smithy/querystring-parser': 2.0.1 - '@smithy/types': 2.0.2 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true - /@smithy/util-base64@1.1.0: - resolution: {integrity: sha512-FpYmDmVbOXAxqvoVCwqehUN0zXS+lN8V7VS9O7I8MKeVHdSTsZzlwiMEvGoyTNOXWn8luF4CTDYgNHnZViR30g==} - engines: {node: '>=14.0.0'} + /@smithy/url-parser@2.0.5: + resolution: {integrity: sha512-OdMBvZhpckQSkugCXNJQCvqJ71wE7Ftxce92UOQLQ9pwF6hoS5PLL7wEfpnuEXtStzBqJYkzu1C1ZfjuFGOXAA==} dependencies: - '@smithy/util-buffer-from': 1.1.0 + '@smithy/querystring-parser': 2.0.5 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true @@ -2873,18 +2271,10 @@ packages: tslib: 2.6.1 dev: true - /@smithy/util-body-length-node@2.0.0: - resolution: {integrity: sha512-ZV7Z/WHTMxHJe/xL/56qZwSUcl63/5aaPAGjkfynJm4poILjdD4GmFI+V+YWabh2WJIjwTKZ5PNsuvPQKt93Mg==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.6.1 - dev: true - - /@smithy/util-buffer-from@1.1.0: - resolution: {integrity: sha512-9m6NXE0ww+ra5HKHCHig20T+FAwxBAm7DIdwc/767uGWbRcY720ybgPacQNB96JMOI7xVr/CDa3oMzKmW4a+kw==} + /@smithy/util-body-length-node@2.1.0: + resolution: {integrity: sha512-/li0/kj/y3fQ3vyzn36NTLGmUwAICb7Jbe/CsWCktW363gh1MOcpEcSO3mJ344Gv2dqz8YJCLQpb6hju/0qOWw==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/is-array-buffer': 1.1.0 tslib: 2.6.1 dev: true @@ -2903,32 +2293,25 @@ packages: tslib: 2.6.1 dev: true - /@smithy/util-defaults-mode-browser@2.0.1: - resolution: {integrity: sha512-w72Qwsb+IaEYEFtYICn0Do42eFju78hTaBzzJfT107lFOPdbjWjKnFutV+6GL/nZd5HWXY7ccAKka++C3NrjHw==} + /@smithy/util-defaults-mode-browser@2.0.5: + resolution: {integrity: sha512-yciP6TPttLsj731aHTvekgyuCGXQrEAJibEwEWAh3kzaDsfGAVCuZSBlyvC2Dl3TZmHKCOQwHV8mIE7KQCTPuQ==} engines: {node: '>= 10.0.0'} dependencies: - '@smithy/property-provider': 2.0.1 - '@smithy/types': 2.0.2 + '@smithy/property-provider': 2.0.5 + '@smithy/types': 2.2.2 bowser: 2.11.0 tslib: 2.6.1 dev: true - /@smithy/util-defaults-mode-node@2.0.1: - resolution: {integrity: sha512-dNF45caelEBambo0SgkzQ0v76m4YM+aFKZNTtSafy7P5dVF8TbjZuR2UX1A5gJABD9XK6lzN+v/9Yfzj/EDgGg==} + /@smithy/util-defaults-mode-node@2.0.5: + resolution: {integrity: sha512-M07t99rWasXt+IaDZDyP3BkcoEm/mgIE1RIMASrE49LKSNxaVN7PVcgGc77+4uu2kzBAyqJKy79pgtezuknyjQ==} engines: {node: '>= 10.0.0'} dependencies: - '@smithy/config-resolver': 2.0.1 - '@smithy/credential-provider-imds': 2.0.1 - '@smithy/node-config-provider': 2.0.1 - '@smithy/property-provider': 2.0.1 - '@smithy/types': 2.0.2 - tslib: 2.6.1 - dev: true - - /@smithy/util-hex-encoding@1.1.0: - resolution: {integrity: sha512-7UtIE9eH0u41zpB60Jzr0oNCQ3hMJUabMcKRUVjmyHTXiWDE4vjSqN6qlih7rCNeKGbioS7f/y2Jgym4QZcKFg==} - engines: {node: '>=14.0.0'} - dependencies: + '@smithy/config-resolver': 2.0.5 + '@smithy/credential-provider-imds': 2.0.5 + '@smithy/node-config-provider': 2.0.5 + '@smithy/property-provider': 2.0.5 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true @@ -2954,27 +2337,13 @@ packages: tslib: 2.6.1 dev: true - /@smithy/util-stream@1.1.0: - resolution: {integrity: sha512-w3lsdGsntaLQIrwDWJkIFKrFscgZXwU/oxsse09aSTNv5TckPhDeYea3LhsDrU5MGAG3vprhVZAKr33S45coVA==} + /@smithy/util-stream@2.0.5: + resolution: {integrity: sha512-ylx27GwI05xLpYQ4hDIfS15vm+wYjNN0Sc2P0FxuzgRe8v0BOLHppGIQ+Bezcynk8C9nUzsUue3TmtRhjut43g==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/fetch-http-handler': 1.1.0 - '@smithy/node-http-handler': 1.1.0 - '@smithy/types': 1.2.0 - '@smithy/util-base64': 1.1.0 - '@smithy/util-buffer-from': 1.1.0 - '@smithy/util-hex-encoding': 1.1.0 - '@smithy/util-utf8': 1.1.0 - tslib: 2.6.1 - dev: true - - /@smithy/util-stream@2.0.1: - resolution: {integrity: sha512-2a0IOtwIKC46EEo7E7cxDN8u2jwOiYYJqcFKA6rd5rdXqKakHT2Gc+AqHWngr0IEHUfW92zX12wRQKwyoqZf2Q==} - engines: {node: '>=14.0.0'} - dependencies: - '@smithy/fetch-http-handler': 2.0.1 - '@smithy/node-http-handler': 2.0.1 - '@smithy/types': 2.0.2 + '@smithy/fetch-http-handler': 2.0.5 + '@smithy/node-http-handler': 2.0.5 + '@smithy/types': 2.2.2 '@smithy/util-base64': 2.0.0 '@smithy/util-buffer-from': 2.0.0 '@smithy/util-hex-encoding': 2.0.0 @@ -2982,13 +2351,6 @@ packages: tslib: 2.6.1 dev: true - /@smithy/util-uri-escape@1.1.0: - resolution: {integrity: sha512-/jL/V1xdVRt5XppwiaEU8Etp5WHZj609n0xMTuehmCqdoOFbId1M+aEeDWZsQ+8JbEB/BJ6ynY2SlYmOaKtt8w==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.6.1 - dev: true - /@smithy/util-uri-escape@2.0.0: resolution: {integrity: sha512-ebkxsqinSdEooQduuk9CbKcI+wheijxEb3utGXkCoYQkJnwTnLbH1JXGimJtUkQwNQbsbuYwG2+aFVyZf5TLaw==} engines: {node: '>=14.0.0'} @@ -2996,19 +2358,20 @@ packages: tslib: 2.6.1 dev: true - /@smithy/util-utf8@1.1.0: - resolution: {integrity: sha512-p/MYV+JmqmPyjdgyN2UxAeYDj9cBqCjp0C/NsTWnnjoZUVqoeZ6IrW915L9CAKWVECgv9lVQGc4u/yz26/bI1A==} + /@smithy/util-utf8@2.0.0: + resolution: {integrity: sha512-rctU1VkziY84n5OXe3bPNpKR001ZCME2JCaBBFgtiM2hfKbHFudc/BkMuPab8hRbLd0j3vbnBTTZ1igBf0wgiQ==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/util-buffer-from': 1.1.0 + '@smithy/util-buffer-from': 2.0.0 tslib: 2.6.1 dev: true - /@smithy/util-utf8@2.0.0: - resolution: {integrity: sha512-rctU1VkziY84n5OXe3bPNpKR001ZCME2JCaBBFgtiM2hfKbHFudc/BkMuPab8hRbLd0j3vbnBTTZ1igBf0wgiQ==} + /@smithy/util-waiter@2.0.5: + resolution: {integrity: sha512-1lkkUmI/bhaDX+LIT3RiUNAn+NzPmsWjE7beMq0oQ3H1/CffaILIN67riDA0aE1YBj6xll7uWMIy4tJqc+peXw==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/util-buffer-from': 2.0.0 + '@smithy/abort-controller': 2.0.5 + '@smithy/types': 2.2.2 tslib: 2.6.1 dev: true @@ -3110,6 +2473,16 @@ packages: '@types/node': 20.4.8 dev: true + /@types/sinon@10.0.16: + resolution: {integrity: sha512-j2Du5SYpXZjJVJtXBokASpPRj+e2z+VUhCPHmM6WMfe3dpHu6iVKJMU6AiBcMp/XTAYnEj6Wc1trJUWwZ0QaAQ==} + dependencies: + '@types/sinonjs__fake-timers': 8.1.2 + dev: true + + /@types/sinonjs__fake-timers@8.1.2: + resolution: {integrity: sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==} + dev: true + /@types/tough-cookie@4.0.2: resolution: {integrity: sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==} dev: true @@ -3662,6 +3035,14 @@ packages: engines: {node: '>= 0.4'} dev: true + /aws-sdk-client-mock@3.0.0: + resolution: {integrity: sha512-4mBiWhuLYLZe1+K/iB8eYy5SAZyW2se+Keyh5u9QouMt6/qJ5SRZhss68xvUX5g3ApzROJ06QPRziYHP6buuvQ==} + dependencies: + '@types/sinon': 10.0.16 + sinon: 14.0.2 + tslib: 2.6.1 + dev: true + /axios@0.21.4: resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} dependencies: @@ -4011,7 +3392,7 @@ packages: normalize-path: 3.0.0 readdirp: 3.6.0 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 /chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} @@ -4339,6 +3720,11 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true + /diff@5.1.0: + resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} + engines: {node: '>=0.3.1'} + dev: true + /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -5061,13 +4447,6 @@ packages: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} dev: true - /fast-xml-parser@4.1.2: - resolution: {integrity: sha512-CDYeykkle1LiA/uqQyNwYpFbyF6Axec6YapmpUP+/RHWIoR1zKjocdvNaTsxCxZzQ6v9MLXaSYm9Qq0thv0DHg==} - hasBin: true - dependencies: - strnum: 1.0.5 - dev: true - /fast-xml-parser@4.2.5: resolution: {integrity: sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==} hasBin: true @@ -5274,8 +4653,8 @@ packages: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: true - /fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true @@ -5963,6 +5342,10 @@ packages: dependencies: is-docker: 2.2.1 + /isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + dev: true + /isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} dev: true @@ -6149,6 +5532,10 @@ packages: semver: 7.5.4 dev: true + /just-extend@4.2.1: + resolution: {integrity: sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==} + dev: true + /jwa@1.4.1: resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} dependencies: @@ -6241,6 +5628,10 @@ packages: /lodash.defaults@4.2.0: resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + /lodash.get@4.4.2: + resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + dev: true + /lodash.isarguments@3.1.0: resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} @@ -6565,13 +5956,13 @@ packages: mongodb-connection-string-url: 2.6.0 socks: 2.7.1 optionalDependencies: - '@aws-sdk/credential-providers': 3.386.0 + '@aws-sdk/credential-providers': 3.398.0 saslprep: 1.0.3 transitivePeerDependencies: - aws-crt dev: true - /mongodb@5.7.0(@aws-sdk/credential-providers@3.386.0): + /mongodb@5.7.0: resolution: {integrity: sha512-zm82Bq33QbqtxDf58fLWBwTjARK3NSvKYjyz997KSy6hpat0prjeX/kxjbPVyZY60XYPDNETaHkHJI2UCzSLuw==} engines: {node: '>=14.20.1'} peerDependencies: @@ -6592,7 +5983,6 @@ packages: snappy: optional: true dependencies: - '@aws-sdk/credential-providers': 3.386.0 bson: 5.4.0 mongodb-connection-string-url: 2.6.0 socks: 2.7.1 @@ -6737,6 +6127,16 @@ packages: - supports-color dev: true + /nise@5.1.4: + resolution: {integrity: sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==} + dependencies: + '@sinonjs/commons': 2.0.0 + '@sinonjs/fake-timers': 10.3.0 + '@sinonjs/text-encoding': 0.7.2 + just-extend: 4.2.1 + path-to-regexp: 1.8.0 + dev: true + /node-abort-controller@3.1.1: resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} dev: true @@ -7050,6 +6450,12 @@ packages: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} dev: true + /path-to-regexp@1.8.0: + resolution: {integrity: sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==} + dependencies: + isarray: 0.0.1 + dev: true + /path-to-regexp@6.2.1: resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} dev: true @@ -7383,7 +6789,7 @@ packages: engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true /rrweb-cssom@0.6.0: @@ -7638,6 +7044,17 @@ packages: is-arrayish: 0.3.2 dev: true + /sinon@14.0.2: + resolution: {integrity: sha512-PDpV0ZI3ZCS3pEqx0vpNp6kzPhHrLx72wA0G+ZLaaJjLIYeE0n8INlgaohKuGy7hP0as5tbUd23QWu5U233t+w==} + dependencies: + '@sinonjs/commons': 2.0.0 + '@sinonjs/fake-timers': 9.1.2 + '@sinonjs/samsam': 7.0.1 + diff: 5.1.0 + nise: 5.1.4 + supports-color: 7.2.0 + dev: true + /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -8393,7 +7810,7 @@ packages: postcss: 8.4.27 rollup: 3.27.2 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true /vitest@0.34.1(jsdom@22.1.0): @@ -8735,3 +8152,7 @@ packages: resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} engines: {node: '>=12.20'} dev: true + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false diff --git a/test/drivers/aws-dynamodb.test.ts b/test/drivers/aws-dynamodb.test.ts index 08044ff2..de66b1bb 100644 --- a/test/drivers/aws-dynamodb.test.ts +++ b/test/drivers/aws-dynamodb.test.ts @@ -1,139 +1,65 @@ -import { describe, beforeAll, afterAll, expect, it } from "vitest"; +import { describe, afterEach, beforeEach } from "vitest"; import driver, { DynamoDBStorageOptions } from "../../src/drivers/aws-dynamodb"; import { testDriver } from "./utils"; -import { fromIni, fromEnv } from "@aws-sdk/credential-providers"; -import { - DynamoDBClient, - CreateTableCommand, - UpdateTimeToLiveCommand, - DeleteTableCommand, - waitUntilTableExists, - waitUntilTableNotExists, - GetItemCommand, -} from "@aws-sdk/client-dynamodb"; +import { mockClient } from "aws-sdk-client-mock"; +import { DynamoDBDocumentClient, GetCommand, PutCommand, ScanCommand, DeleteCommand } from "@aws-sdk/lib-dynamodb"; -const TABLE_OPERATIONS_TIMEOUT_SECONDS = 30; // table need at lest 30s from creation to become available +const TABLE_NAME = 'mocked' + +// Mocked in-memory data +let data = new Map() describe("drivers: aws-dynamodb", () => { - // Load AWS credentials + // Init mocked client for test purpose - const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION; - const profile = process.env.AWS_PROFILE || process.env.AWS_DEFAULT_PROFILE; - const credentials = profile - ? fromIni({ - profile: profile, - }) - : fromEnv(); + const client = mockClient( + DynamoDBDocumentClient + ); - // Init client for test purpose - - const client = new DynamoDBClient({ - region, - credentials, - }); + // Add command resolvers + + client + .on(GetCommand) + .callsFake(input => { + const key = input.Key.key + if (!data.has(key)) { + return { Item: undefined } + } + return { Item: { key, value: data.get(key) } } + }) + .on(ScanCommand) + .callsFake(() => { + return { Items: Array.from(data.entries()).map(([ key, value ]) => ({ key, value })) } + }) + .on(PutCommand) + .callsFake(input => { + data.set(input.Item.key, input.Item.value) + }) + .on(DeleteCommand) + .callsFake(input => { + data.delete(input.Key.key) + }) + // Setup test driver options const options: DynamoDBStorageOptions = { - table: "tmp-unstorage-tests", - region, - credentials, + table: TABLE_NAME, + region: "us-east-1", + credentials: {}, attributes: { key: "key", value: "value", ttl: "ttl", }, - expireIn: 300, + expireIn: 0, + client: client as unknown as DynamoDBDocumentClient, }; - // Test hooks - - beforeAll( - async () => { - await client.send( - new CreateTableCommand({ - TableName: options.table, - BillingMode: "PAY_PER_REQUEST", - AttributeDefinitions: [ - { - AttributeName: options.attributes?.key, - AttributeType: "S", - }, - ], - KeySchema: [ - { - AttributeName: options.attributes?.key, - KeyType: "HASH", - }, - ], - }) - ); - - await waitUntilTableExists( - { client, maxWaitTime: TABLE_OPERATIONS_TIMEOUT_SECONDS }, - { TableName: options.table } - ); - - await client.send( - new UpdateTimeToLiveCommand({ - TableName: options.table, - TimeToLiveSpecification: { - AttributeName: options.attributes?.ttl, - Enabled: true, - }, - }) - ); - }, - (TABLE_OPERATIONS_TIMEOUT_SECONDS + 2) * 1000 - ); - - afterAll( - async () => { - await client.send( - new DeleteTableCommand({ - TableName: options.table, - }) - ); - - await waitUntilTableNotExists( - { client, maxWaitTime: TABLE_OPERATIONS_TIMEOUT_SECONDS }, - { TableName: options.table } - ); - }, - (TABLE_OPERATIONS_TIMEOUT_SECONDS + 2) * 1000 - ); - // Common tests testDriver({ driver: driver(options), - additionalTests: (ctx) => { - // Additional tests - - it("should set TTL attribute on item", async () => { - const timestamp = Math.round(Date.now() / 1000); - - await ctx.storage.setItem("test-with-ttl", "ok"); - - const key = {}; - key[options.attributes?.key as string] = { - S: "test-with-ttl", - }; - - const { Item: item } = await client.send( - new GetItemCommand({ - TableName: options.table, - Key: key, - }) - ); - - expect(item).not.toBeUndefined(); - expect(item?.[options.attributes?.value as string].S).toBe("ok"); - expect(item?.[options.attributes?.ttl as string].N).not.toBeUndefined(); - expect( - parseInt(item?.[options.attributes?.ttl as string].N as string) - ).toBeGreaterThanOrEqual(timestamp + (options.expireIn || 0)); - }); - }, + additionalTests: () => {}, }); }); From 08c3b9f0102b268c4ae1208bb5c34deec70018b4 Mon Sep 17 00:00:00 2001 From: Fabio Gollinucci Date: Mon, 28 Aug 2023 12:05:28 +0200 Subject: [PATCH 11/13] chore(aws-dynamodb): remove temporary test command for DynamoDB --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 15efea4c..5d0d97ef 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,6 @@ "prepack": "pnpm build", "release": "pnpm test && changelogen --release && git push --follow-tags && pnpm publish", "test": "pnpm lint && pnpm test:types && vitest run --coverage", - "test:dynamodb": "vitest run test/drivers/aws-dynamodb.test.ts", "test:types": "tsc --noEmit --skipLibCheck", "unstorage": "pnpm jiti src/cli" }, From 1f7d9136e6fe4cf3dda4c53e7cefdf319b38fb72 Mon Sep 17 00:00:00 2001 From: Fabio Gollinucci Date: Tue, 29 Aug 2023 17:13:39 +0200 Subject: [PATCH 12/13] chore(aws-dynamodb): add "ttl" opt on root level, add setItem ttl param --- src/drivers/aws-dynamodb.ts | 34 +++++++++++++++++------- test/drivers/aws-dynamodb.test.ts | 44 ++++++++++++++++++------------- 2 files changed, 50 insertions(+), 28 deletions(-) diff --git a/src/drivers/aws-dynamodb.ts b/src/drivers/aws-dynamodb.ts index ccaa8b3b..521bca6d 100644 --- a/src/drivers/aws-dynamodb.ts +++ b/src/drivers/aws-dynamodb.ts @@ -17,14 +17,18 @@ export interface DynamoDBStorageOptions { value?: string; ttl?: string; }; - expireIn?: number; + ttl?: number; client?: DynamoDBDocumentClient; } +export interface DynamoDBSetItemOptions { + ttl?: number; +} + const DRIVER_NAME = "aws-dynamodb"; export default defineDriver((opts: DynamoDBStorageOptions) => { - const expireIn = parseInt(String(opts.expireIn)) || 0; + const ttl = opts.ttl !== undefined ? parseInt(String(opts.ttl)) : 0; const attributes = { key: "key", @@ -38,8 +42,8 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { if (!opts.table) { throw createRequiredError(DRIVER_NAME, "table"); } - if (Number.isNaN(opts.expireIn) || expireIn < 0) { - throw createError(DRIVER_NAME, "Invalid option `expireIn`."); + if (Number.isNaN(ttl) || ttl < 0) { + throw createError(DRIVER_NAME, "Invalid option `ttl`."); } if (!client) { client = @@ -83,7 +87,7 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { return null; } - if (expireIn > 0) { + if (ttl > 0) { const timestamp = getTimestamp(); if (timestamp > parseInt(item.ttl || 0)) { return null; @@ -93,11 +97,21 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { return item[attributes.value]; } - async function putItemValue(key: string, value: any): Promise { + async function putItemValue( + key: string, + value: any, + options: DynamoDBSetItemOptions = {} + ): Promise { + const ttlOverride = + options.ttl !== undefined ? parseInt(String(options.ttl)) : ttl; + if (Number.isNaN(ttlOverride) || ttlOverride < 0) { + throw createError(DRIVER_NAME, "Invalid option `ttl`."); + } + await getClient().send( new PutCommand({ TableName: opts.table, - Item: createObject(key, value, opts.expireIn), + Item: createObject(key, value, ttlOverride), }) ); } @@ -121,7 +135,7 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { items = items || []; - if (expireIn > 0) { + if (ttl > 0) { const timestamp = getTimestamp(); items = items.filter((item) => parseInt(item.ttl || 0) >= timestamp); } @@ -144,8 +158,8 @@ export default defineDriver((opts: DynamoDBStorageOptions) => { async getItem(key) { return await getItemValue(key); }, - async setItem(key, value) { - await putItemValue(key, value); + async setItem(key, value, opts: DynamoDBSetItemOptions = {}) { + await putItemValue(key, value, opts); }, async removeItem(key) { await removeItem(key); diff --git a/test/drivers/aws-dynamodb.test.ts b/test/drivers/aws-dynamodb.test.ts index de66b1bb..4cdf4664 100644 --- a/test/drivers/aws-dynamodb.test.ts +++ b/test/drivers/aws-dynamodb.test.ts @@ -2,44 +2,52 @@ import { describe, afterEach, beforeEach } from "vitest"; import driver, { DynamoDBStorageOptions } from "../../src/drivers/aws-dynamodb"; import { testDriver } from "./utils"; import { mockClient } from "aws-sdk-client-mock"; -import { DynamoDBDocumentClient, GetCommand, PutCommand, ScanCommand, DeleteCommand } from "@aws-sdk/lib-dynamodb"; +import { + DynamoDBDocumentClient, + GetCommand, + PutCommand, + ScanCommand, + DeleteCommand, +} from "@aws-sdk/lib-dynamodb"; -const TABLE_NAME = 'mocked' +const TABLE_NAME = "mocked"; // Mocked in-memory data -let data = new Map() +let data = new Map(); describe("drivers: aws-dynamodb", () => { // Init mocked client for test purpose - const client = mockClient( - DynamoDBDocumentClient - ); + const client = mockClient(DynamoDBDocumentClient); // Add command resolvers client .on(GetCommand) - .callsFake(input => { - const key = input.Key.key + .callsFake((input) => { + const key = input.Key.key; if (!data.has(key)) { - return { Item: undefined } + return { Item: undefined }; } - return { Item: { key, value: data.get(key) } } + return { Item: { key, value: data.get(key) } }; }) .on(ScanCommand) .callsFake(() => { - return { Items: Array.from(data.entries()).map(([ key, value ]) => ({ key, value })) } + return { + Items: Array.from(data.entries()).map(([key, value]) => ({ + key, + value, + })), + }; }) .on(PutCommand) - .callsFake(input => { - data.set(input.Item.key, input.Item.value) + .callsFake((input) => { + data.set(input.Item.key, input.Item.value); }) .on(DeleteCommand) - .callsFake(input => { - data.delete(input.Key.key) - }) - + .callsFake((input) => { + data.delete(input.Key.key); + }); // Setup test driver options @@ -52,7 +60,7 @@ describe("drivers: aws-dynamodb", () => { value: "value", ttl: "ttl", }, - expireIn: 0, + ttl: 0, client: client as unknown as DynamoDBDocumentClient, }; From b10053737594a45701e8de6170a223ae9c797aa8 Mon Sep 17 00:00:00 2001 From: Fabio Gollinucci Date: Tue, 29 Aug 2023 17:13:56 +0200 Subject: [PATCH 13/13] docs: update ttl options for dynamodb storage --- docs/content/6.drivers/aws-dynamodb.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/content/6.drivers/aws-dynamodb.md b/docs/content/6.drivers/aws-dynamodb.md index 0d884e9d..f4dd3815 100644 --- a/docs/content/6.drivers/aws-dynamodb.md +++ b/docs/content/6.drivers/aws-dynamodb.md @@ -56,17 +56,22 @@ const storage = createStorage({ driver: dynamoDbCacheDriver({ table: "my-table-name", // required attributes: { - key: "key", - value: "value", + key: "key", // optional but recommended + value: "value", // optional but recommended ttl: "ttl", // optional, configure attributes name }, - expireIn: 300, // optional, values in seconds or 0 to disable + ttl: 300, // optional, values in seconds or 0 to disable }), }); ``` -When `expireIn` is set to a number greater than 0 the driver will add seconds to the current timestamp and set the TTL attribute. -Otherwise removing the `expireIn` option or setting it to 0 will disable this functionality. +When `ttl` is set to a number greater than 0 the driver will add seconds to the current timestamp and set the TTL attribute. +Otherwise removing the `ttl` option or setting it to 0 will disable this functionality. + +The `setItem` method support an additional options which allows you to override the general `ttl` option: +```js +await storage.setItem('key', 'value', { ttl: 900 }) +``` Since the DynamoDB items deletion is asynchronous the driver will check the validity of the TTL attribute before returning them from `getItem` and `getKeys` operations. This in order to ensure that no expired items will be returned. @@ -100,4 +105,4 @@ The IAM role or IAM user that use the driver need the following permissions: - `region`: The AWS region to use. - `credentials`: The AWS SDK credentials object. - `attributes`: The key, value and TTL attributes mapping to table item attributes. -- `expireIn`: The number of seconds to add to the current timestamp to set the TTL attribute. Set to 0 to disable it. +- `ttl`: The number of seconds to add to the current timestamp to set the TTL attribute. Set to 0 to disable it.