diff --git a/packages/amplify-category-hosting/__tests__/lib/S3AndCloudFront/helpers/cloudfront-manager.test.js b/packages/amplify-category-hosting/__tests__/lib/S3AndCloudFront/helpers/cloudfront-manager.test.js index c26650b880e..1eed323d0cd 100644 --- a/packages/amplify-category-hosting/__tests__/lib/S3AndCloudFront/helpers/cloudfront-manager.test.js +++ b/packages/amplify-category-hosting/__tests__/lib/S3AndCloudFront/helpers/cloudfront-manager.test.js @@ -62,23 +62,19 @@ describe('cloudfront-manager', () => { const mockcftInvalidationData = {}; - const mockInvalidateMethod = jest.fn(() => { - return { - promise: () => Promise.resolve(mockcftInvalidationData), - }; - }); + const mockSendMethod = jest.fn(() => Promise.resolve(mockcftInvalidationData)); - class mockCloudFront { + class mockCloudFrontClient { constructor() { - this.createInvalidation = mockInvalidateMethod; + this.send = mockSendMethod; } } test('invalidateCloudFront', async () => { - const mockCloudFrontClient = async (context, action) => Promise.resolve(new mockCloudFront()); - const result = await cloudFrontManager.invalidateCloudFront(mockContext, mockCloudFrontClient); + const mockCloudFrontClientFactory = async (context, action) => Promise.resolve(new mockCloudFrontClient()); + const result = await cloudFrontManager.invalidateCloudFront(mockContext, mockCloudFrontClientFactory); expect(result).toBe(mockContext); - expect(mockInvalidateMethod).toBeCalled(); + expect(mockSendMethod).toBeCalled(); expect(mockContext.exeInfo.cftInvalidationData).toEqual(mockcftInvalidationData); }); }); diff --git a/packages/amplify-category-hosting/lib/S3AndCloudFront/helpers/cloudfront-manager.js b/packages/amplify-category-hosting/lib/S3AndCloudFront/helpers/cloudfront-manager.js index 088b6420c36..56490e5db17 100644 --- a/packages/amplify-category-hosting/lib/S3AndCloudFront/helpers/cloudfront-manager.js +++ b/packages/amplify-category-hosting/lib/S3AndCloudFront/helpers/cloudfront-manager.js @@ -1,6 +1,6 @@ const chalk = require('chalk'); const constants = require('../../constants'); -const CloudFront = require('aws-sdk/clients/cloudfront'); +const { CloudFrontClient, CreateInvalidationCommand } = require('@aws-sdk/client-cloudfront'); const providerName = 'awscloudformation'; @@ -28,7 +28,8 @@ async function invalidate(context, cloudFrontClient = getCloudFrontClient) { }; try { - const data = await cloudFront.createInvalidation(invalidateParams).promise(); + const command = new CreateInvalidationCommand(invalidateParams); + const data = await cloudFront.send(command); context.print.info('CloudFront invalidation request sent successfuly.'); context.print.info(chalk.green(CloudFrontSecureURL)); context.exeInfo.cftInvalidationData = data; @@ -45,7 +46,7 @@ async function getCloudFrontClient(context, action) { const providerPlugins = context.amplify.getProviderPlugins(context); const provider = require(providerPlugins[providerName]); const config = await provider.getConfiguredAWSClientConfig(context, constants.CategoryName, action); - return new CloudFront(config); + return new CloudFrontClient(config); } module.exports = { diff --git a/packages/amplify-category-hosting/lib/S3AndCloudFront/helpers/file-uploader.js b/packages/amplify-category-hosting/lib/S3AndCloudFront/helpers/file-uploader.js index 7893cf7fdf0..d01de275b7e 100644 --- a/packages/amplify-category-hosting/lib/S3AndCloudFront/helpers/file-uploader.js +++ b/packages/amplify-category-hosting/lib/S3AndCloudFront/helpers/file-uploader.js @@ -3,7 +3,7 @@ const sequential = require('promise-sequential'); const fileScanner = require('./file-scanner'); const constants = require('../../constants'); const { uploadFile } = require('./upload-file'); -const S3 = require('aws-sdk/clients/s3'); +const { S3Client } = require('@aws-sdk/client-s3'); const serviceName = 'S3AndCloudFront'; const providerName = 'awscloudformation'; @@ -43,7 +43,7 @@ async function getS3Client(context, action) { const providerPlugins = context.amplify.getProviderPlugins(context); const provider = require(providerPlugins[providerName]); const config = await provider.getConfiguredAWSClientConfig(context, constants.CategoryName, action); - return new S3(config); + return new S3Client(config); } function getHostingBucketName(context) { diff --git a/packages/amplify-category-hosting/lib/S3AndCloudFront/helpers/upload-file.js b/packages/amplify-category-hosting/lib/S3AndCloudFront/helpers/upload-file.js index 65054fbe768..89fbeb41bd7 100644 --- a/packages/amplify-category-hosting/lib/S3AndCloudFront/helpers/upload-file.js +++ b/packages/amplify-category-hosting/lib/S3AndCloudFront/helpers/upload-file.js @@ -1,6 +1,7 @@ const fs = require('fs-extra'); const path = require('path'); const mime = require('mime-types'); +const { Upload } = require('@aws-sdk/lib-storage'); async function uploadFile(s3Client, hostingBucketName, distributionDirPath, filePath, hasCloudFront) { let relativeFilePath = path.relative(distributionDirPath, filePath); @@ -19,7 +20,12 @@ async function uploadFile(s3Client, hostingBucketName, distributionDirPath, file uploadParams.ACL = 'public-read'; } - const data = await s3Client.upload(uploadParams).promise(); + const upload = new Upload({ + client: s3Client, + params: uploadParams, + }); + + const data = await upload.done(); return data; } diff --git a/packages/amplify-category-hosting/package.json b/packages/amplify-category-hosting/package.json index 9b2985905b6..3bb8bd22c21 100644 --- a/packages/amplify-category-hosting/package.json +++ b/packages/amplify-category-hosting/package.json @@ -23,7 +23,9 @@ "dependencies": { "@aws-amplify/amplify-cli-core": "4.4.3", "@aws-amplify/amplify-prompts": "2.8.7", - "aws-sdk": "^2.1692.0", + "@aws-sdk/client-cloudfront": "^3.919.0", + "@aws-sdk/client-s3": "^3.919.0", + "@aws-sdk/lib-storage": "^3.919.0", "chalk": "^4.1.1", "fs-extra": "^8.1.0", "mime-types": "^2.1.26", diff --git a/packages/amplify-category-notifications/package.json b/packages/amplify-category-notifications/package.json index 288c386a88e..b70a223daee 100644 --- a/packages/amplify-category-notifications/package.json +++ b/packages/amplify-category-notifications/package.json @@ -31,7 +31,7 @@ "@aws-amplify/amplify-prompts": "2.8.7", "@aws-amplify/amplify-provider-awscloudformation": "8.11.14", "@aws-sdk/client-iam": "^3.919.0", - "@aws-sdk/client-pinpoint": "^3.919.0", + "@aws-sdk/client-pinpoint": "3.901.0", "@smithy/node-http-handler": "^4.4.3", "chalk": "^4.1.1", "fs-extra": "^8.1.0", diff --git a/packages/amplify-console-hosting/package.json b/packages/amplify-console-hosting/package.json index c53bad3b8f0..b6acde52784 100644 --- a/packages/amplify-console-hosting/package.json +++ b/packages/amplify-console-hosting/package.json @@ -12,7 +12,6 @@ "@aws-sdk/client-amplify": "^3.919.0", "@aws-sdk/client-s3": "^3.919.0", "archiver": "^7.0.1", - "aws-sdk": "^2.1692.0", "chalk": "^4.1.1", "cli-table3": "^0.6.0", "execa": "^5.1.1", diff --git a/packages/amplify-container-hosting/package.json b/packages/amplify-container-hosting/package.json index 1fab38ca869..4f71b674646 100644 --- a/packages/amplify-container-hosting/package.json +++ b/packages/amplify-container-hosting/package.json @@ -29,6 +29,8 @@ "@aws-amplify/amplify-category-api": "^5.15.1", "@aws-amplify/amplify-cli-core": "4.4.3", "@aws-amplify/amplify-environment-parameters": "1.9.22", + "@aws-sdk/client-s3": "^3.919.0", + "@aws-sdk/lib-storage": "^3.919.0", "fs-extra": "^8.1.0", "inquirer": "^7.3.3", "mime-types": "^2.1.26", diff --git a/packages/amplify-container-hosting/src/lib/ElasticContainer/file-uploader.js b/packages/amplify-container-hosting/src/lib/ElasticContainer/file-uploader.js index c2accf618d7..ef5f321dcd7 100644 --- a/packages/amplify-container-hosting/src/lib/ElasticContainer/file-uploader.js +++ b/packages/amplify-container-hosting/src/lib/ElasticContainer/file-uploader.js @@ -1,13 +1,14 @@ const fs = require('fs-extra'); const mime = require('mime-types'); const constants = require('../constants'); -const S3 = require('aws-sdk/clients/s3'); +const { S3Client } = require('@aws-sdk/client-s3'); +const { Upload } = require('@aws-sdk/lib-storage'); export async function getS3Client(context, action) { const providerPlugins = context.amplify.getProviderPlugins(context); const provider = require(providerPlugins[constants.providerName]); const config = await provider.getConfiguredAWSClientConfig(context, constants.CategoryName, action); - return new S3(config); + return new S3Client(config); } export async function uploadFile(s3Client, bucketName, filePath, fileKey) { @@ -20,7 +21,12 @@ export async function uploadFile(s3Client, bucketName, filePath, fileKey) { ContentType: contentType || 'text/plain', }; - const data = await s3Client.upload(uploadParams).promise(); + const upload = new Upload({ + client: s3Client, + params: uploadParams, + }); + + const data = await upload.done(); return data; } diff --git a/packages/amplify-e2e-core/package.json b/packages/amplify-e2e-core/package.json index d3d3dd2dd03..1fd9743ec0c 100644 --- a/packages/amplify-e2e-core/package.json +++ b/packages/amplify-e2e-core/package.json @@ -23,13 +23,30 @@ }, "dependencies": { "@aws-amplify/amplify-cli-core": "4.4.3", - "@aws-sdk/client-pinpoint": "^3.919.0", + "@aws-sdk/client-amplifybackend": "^3.919.0", + "@aws-sdk/client-amplifyuibuilder": "^3.919.0", + "@aws-sdk/client-appsync": "^3.919.0", + "@aws-sdk/client-cloudformation": "^3.919.0", + "@aws-sdk/client-cloudwatch-events": "^3.919.0", + "@aws-sdk/client-cloudwatch-logs": "^3.919.0", + "@aws-sdk/client-cognito-identity": "^3.919.0", + "@aws-sdk/client-cognito-identity-provider": "^3.919.0", + "@aws-sdk/client-dynamodb": "^3.919.0", + "@aws-sdk/client-iam": "^3.919.0", + "@aws-sdk/client-kinesis": "^3.919.0", + "@aws-sdk/client-lambda": "^3.919.0", + "@aws-sdk/client-lex-model-building-service": "^3.919.0", + "@aws-sdk/client-location": "^3.919.0", + "@aws-sdk/client-pinpoint": "3.901.0", + "@aws-sdk/client-rekognition": "^3.919.0", + "@aws-sdk/client-s3": "^3.919.0", + "@aws-sdk/client-ssm": "^3.919.0", "@aws-sdk/client-sts": "^3.919.0", "@aws-sdk/credential-providers": "^3.919.0", + "@aws-sdk/lib-dynamodb": "^3.919.0", "amplify-headless-interface": "1.17.8", "aws-amplify": "^5.3.16", "aws-appsync": "^4.1.1", - "aws-sdk": "^2.1464.0", "chalk": "^4.1.1", "dotenv": "^8.2.0", "execa": "^5.1.1", diff --git a/packages/amplify-e2e-core/src/categories/lambda-function.ts b/packages/amplify-e2e-core/src/categories/lambda-function.ts index 7dca51bcf5c..a8cf697e3e5 100644 --- a/packages/amplify-e2e-core/src/categories/lambda-function.ts +++ b/packages/amplify-e2e-core/src/categories/lambda-function.ts @@ -1,5 +1,5 @@ import { nspawn as spawn, ExecutionContext, KEY_DOWN_ARROW, getCLIPath, getProjectMeta, getBackendAmplifyMeta, invokeFunction } from '..'; -import { Lambda } from 'aws-sdk'; +import { InvokeCommandOutput } from '@aws-sdk/client-lambda'; import { singleSelect, multiSelect, moveUp, moveDown } from '../utils/selectors'; import { globSync } from 'glob'; import * as path from 'path'; @@ -636,10 +636,7 @@ export const functionMockAssert = ( }); }; -export const functionCloudInvoke = async ( - cwd: string, - settings: { funcName: string; payload: string }, -): Promise => { +export const functionCloudInvoke = async (cwd: string, settings: { funcName: string; payload: string }): Promise => { const meta = getProjectMeta(cwd); const lookupName = settings.funcName; expect(meta.function[lookupName]).toBeDefined(); @@ -647,10 +644,10 @@ export const functionCloudInvoke = async ( expect(functionName).toBeDefined(); expect(region).toBeDefined(); const result = await invokeFunction(functionName, settings.payload, region); - if (!result.$response.data) { - throw new Error('No data in lambda response'); + if (!result.Payload) { + throw new Error('No payload in lambda response'); } - return result.$response.data as Lambda.InvocationResponse; + return result; }; const getTemplateChoices = (runtime: FunctionRuntimes) => { diff --git a/packages/amplify-e2e-core/src/categories/uibuilder/myFormCheckout.component.ts b/packages/amplify-e2e-core/src/categories/uibuilder/myFormCheckout.component.ts index de159e6a93a..ff296306757 100644 --- a/packages/amplify-e2e-core/src/categories/uibuilder/myFormCheckout.component.ts +++ b/packages/amplify-e2e-core/src/categories/uibuilder/myFormCheckout.component.ts @@ -1,9 +1,9 @@ -import { AmplifyUIBuilder } from 'aws-sdk'; +import { CreateComponentData } from '@aws-sdk/client-amplifyuibuilder'; // FormCheckout used from AmplifyUIKit // Source: https://www.figma.com/community/file/1047600760128127424 -export const formCheckoutComponent: AmplifyUIBuilder.CreateComponentData = { +export const formCheckoutComponent: CreateComponentData = { name: 'FormCheckout', componentType: 'Flex', schemaVersion: '1.0', diff --git a/packages/amplify-e2e-core/src/categories/uibuilder/myIcon.component.ts b/packages/amplify-e2e-core/src/categories/uibuilder/myIcon.component.ts index 1b9f0feaa74..cf7bf9eb542 100644 --- a/packages/amplify-e2e-core/src/categories/uibuilder/myIcon.component.ts +++ b/packages/amplify-e2e-core/src/categories/uibuilder/myIcon.component.ts @@ -1,9 +1,9 @@ -import { AmplifyUIBuilder } from 'aws-sdk'; +import { CreateComponentData } from '@aws-sdk/client-amplifyuibuilder'; // MyIcon used from AmplifyUIKit // Source: https://www.figma.com/community/file/1047600760128127424 -export const myIconComponent: AmplifyUIBuilder.CreateComponentData = { +export const myIconComponent: CreateComponentData = { name: 'MyIcon', componentType: 'Icon', schemaVersion: '1.0', diff --git a/packages/amplify-e2e-core/src/utils/auth-utils.ts b/packages/amplify-e2e-core/src/utils/auth-utils.ts index 194efe18861..6ce30adc43d 100644 --- a/packages/amplify-e2e-core/src/utils/auth-utils.ts +++ b/packages/amplify-e2e-core/src/utils/auth-utils.ts @@ -1,6 +1,10 @@ import { Amplify, Auth } from 'aws-amplify'; import AWSAppSyncClient, { AUTH_TYPE } from 'aws-appsync'; -import { CognitoIdentityServiceProvider } from 'aws-sdk'; +import { + CognitoIdentityProviderClient, + AdminCreateUserCommand, + AdminAddUserToGroupCommand, +} from '@aws-sdk/client-cognito-identity-provider'; import fs from 'fs-extra'; import path from 'path'; import { getAwsAndroidConfig, getAwsIOSConfig, getBackendAmplifyMeta, getCLIInputs, getProjectMeta, setCLIInputs } from './projectMeta'; @@ -19,53 +23,48 @@ export async function setupUser( region?: string, ): Promise { const cognitoClient = getConfiguredCognitoClient(region); - await cognitoClient - .adminCreateUser({ - UserPoolId: userPoolId, - UserAttributes: [{ Name: 'email', Value: 'username@amazon.com' }], - Username: username, - MessageAction: 'SUPPRESS', - TemporaryPassword: tempPassword, - }) - .promise(); + const createUserCommand = new AdminCreateUserCommand({ + UserPoolId: userPoolId, + UserAttributes: [{ Name: 'email', Value: 'username@amazon.com' }], + Username: username, + MessageAction: 'SUPPRESS', + TemporaryPassword: tempPassword, + }); + await cognitoClient.send(createUserCommand); await authenticateUser(username, tempPassword, password); if (groupName) { - await cognitoClient - .adminAddUserToGroup({ - UserPoolId: userPoolId, - Username: username, - GroupName: groupName, - }) - .promise(); + const addToGroupCommand = new AdminAddUserToGroupCommand({ + UserPoolId: userPoolId, + Username: username, + GroupName: groupName, + }); + await cognitoClient.send(addToGroupCommand); } } export async function addUserToGroup(userPoolId: string, username: string, groupName: string, region?: string): Promise { const cognitoClient = getConfiguredCognitoClient(region); - await cognitoClient - .adminAddUserToGroup({ - UserPoolId: userPoolId, - Username: username, - GroupName: groupName, - }) - .promise(); + const command = new AdminAddUserToGroupCommand({ + UserPoolId: userPoolId, + Username: username, + GroupName: groupName, + }); + await cognitoClient.send(command); } -export function getConfiguredCognitoClient(region = process.env.CLI_REGION): CognitoIdentityServiceProvider { - const cognitoClient = new CognitoIdentityServiceProvider({ apiVersion: '2016-04-19', region }); - +export function getConfiguredCognitoClient(region = process.env.CLI_REGION): CognitoIdentityProviderClient { const awsconfig = { - accessKeyId: process.env.AWS_ACCESS_KEY_ID, - secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, - sessionToken: process.env.AWS_SESSION_TOKEN, + credentials: { + accessKeyId: process.env.AWS_ACCESS_KEY_ID, + secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, + sessionToken: process.env.AWS_SESSION_TOKEN, + }, region, }; - cognitoClient.config.update(awsconfig); - - return cognitoClient; + return new CognitoIdentityProviderClient(awsconfig); } export function getConfiguredAppsyncClientCognitoAuth(url: string, region: string, user: any) { diff --git a/packages/amplify-e2e-core/src/utils/pinpoint.ts b/packages/amplify-e2e-core/src/utils/pinpoint.ts index f1f459749ff..742ad2959c1 100644 --- a/packages/amplify-e2e-core/src/utils/pinpoint.ts +++ b/packages/amplify-e2e-core/src/utils/pinpoint.ts @@ -39,7 +39,7 @@ export async function pinpointAppExist(pinpointProjectId: string, region: string ApplicationId: pinpointProjectId, }); const response = await pinpointClient.send(command); - if (response.ApplicationResponse.Id === pinpointProjectId) { + if (response.ApplicationResponse?.Id === pinpointProjectId) { result = true; } } catch (err) { diff --git a/packages/amplify-e2e-core/src/utils/sdk-calls.ts b/packages/amplify-e2e-core/src/utils/sdk-calls.ts index 5e0f5f0acf4..645633c13d9 100644 --- a/packages/amplify-e2e-core/src/utils/sdk-calls.ts +++ b/packages/amplify-e2e-core/src/utils/sdk-calls.ts @@ -1,52 +1,88 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable no-return-await */ +import { DynamoDBClient, DescribeTableCommand, DeleteTableCommand } from '@aws-sdk/client-dynamodb'; +import { DynamoDBDocumentClient, PutCommand, ScanCommand } from '@aws-sdk/lib-dynamodb'; import { - DynamoDB, - S3, - CognitoIdentity, - CognitoIdentityServiceProvider, - Lambda, - LexModelBuildingService, - Rekognition, - AppSync, - CloudWatchLogs, - CloudWatchEvents, - Kinesis, - CloudFormation, - AmplifyBackend, - IAM, - SSM, - Location, -} from 'aws-sdk'; + S3Client, + HeadBucketCommand, + GetBucketEncryptionCommand, + ListObjectsCommand, + GetObjectCommand, + ListObjectVersionsCommand, + DeleteObjectsCommand, + DeleteBucketCommand, + waitUntilBucketNotExists, + ObjectIdentifier, +} from '@aws-sdk/client-s3'; +import { CognitoIdentityClient, GetIdentityPoolRolesCommand } from '@aws-sdk/client-cognito-identity'; +import { + CognitoIdentityProviderClient, + DescribeUserPoolCommand, + DeleteUserPoolDomainCommand, + DeleteIdentityProviderCommand, + ListIdentityProvidersCommand, + DescribeIdentityProviderCommand, + DescribeUserPoolDomainCommand, + ListUserPoolsCommand, + GetUserPoolMfaConfigCommand, + DescribeUserPoolClientCommand, + AdminCreateUserCommand, + ListUsersCommand, + AdminListGroupsForUserCommand, +} from '@aws-sdk/client-cognito-identity-provider'; +import { + LambdaClient, + GetFunctionCommand, + GetLayerVersionByArnCommand, + ListLayerVersionsCommand, + InvokeCommand, + ListEventSourceMappingsCommand, +} from '@aws-sdk/client-lambda'; +import { LexModelBuildingServiceClient, GetBotCommand } from '@aws-sdk/client-lex-model-building-service'; +import { RekognitionClient, DescribeCollectionCommand } from '@aws-sdk/client-rekognition'; +import { AppSyncClient, GetGraphqlApiCommand } from '@aws-sdk/client-appsync'; +import { CloudWatchLogsClient, DescribeLogStreamsCommand, GetLogEventsCommand } from '@aws-sdk/client-cloudwatch-logs'; +import { CloudWatchEventsClient, ListRuleNamesByTargetCommand } from '@aws-sdk/client-cloudwatch-events'; +import { KinesisClient, PutRecordsCommand } from '@aws-sdk/client-kinesis'; +import { CloudFormationClient, DescribeStacksCommand, DescribeStackResourcesCommand } from '@aws-sdk/client-cloudformation'; +import { AmplifyBackendClient, CreateBackendConfigCommand, GetBackendJobCommand } from '@aws-sdk/client-amplifybackend'; +import { IAMClient, ListRolePoliciesCommand, ListAttachedRolePoliciesCommand, GetRoleCommand } from '@aws-sdk/client-iam'; +import { SSMClient, GetParametersCommand, DeleteParameterCommand, GetParametersByPathCommand } from '@aws-sdk/client-ssm'; +import { + LocationClient, + DescribeMapCommand, + DescribePlaceIndexCommand, + DescribeGeofenceCollectionCommand, + GetGeofenceCommand, + ListGeofencesCommand, +} from '@aws-sdk/client-location'; import * as path from 'path'; import _ from 'lodash'; import { $TSAny } from '@aws-amplify/amplify-cli-core'; import { getProjectMeta } from './projectMeta'; export const getDDBTable = async (tableName: string, region: string) => { - const service = new DynamoDB({ region }); + const service = new DynamoDBClient({ region }); if (tableName) { - return await service.describeTable({ TableName: tableName }).promise(); + const command = new DescribeTableCommand({ TableName: tableName }); + return await service.send(command); } return undefined; }; export const checkIfBucketExists = async (bucketName: string, region: string) => { - const service = new S3({ region }); - return await service.headBucket({ Bucket: bucketName }).promise(); + const service = new S3Client({ region }); + const command = new HeadBucketCommand({ Bucket: bucketName }); + return await service.send(command); }; export const bucketNotExists = async (bucket: string) => { - const s3 = new S3(); - const params = { - Bucket: bucket, - $waiter: { maxAttempts: 10, delay: 30 }, - }; + const s3 = new S3Client({}); try { - await s3.waitFor('bucketNotExists', params).promise(); + await waitUntilBucketNotExists({ client: s3, maxWaitTime: 300 }, { Bucket: bucket }); return true; } catch (error) { - if (error.statusCode === 200) { + if (error.$metadata.httpStatusCode === 200) { return false; } throw error; @@ -54,24 +90,23 @@ export const bucketNotExists = async (bucket: string) => { }; export const getBucketEncryption = async (bucket: string) => { - const s3 = new S3(); - const params = { - Bucket: bucket, - }; + const s3 = new S3Client({}); + const command = new GetBucketEncryptionCommand({ Bucket: bucket }); try { - const result = await s3.getBucketEncryption(params).promise(); + const result = await s3.send(command); return result.ServerSideEncryptionConfiguration; } catch (err) { throw new Error(`Error fetching SSE info for bucket ${bucket}. Underlying error was [${err.message}]`); } }; -export const getBucketKeys = async (params: S3.ListObjectsRequest) => { - const s3 = new S3(); +export const getBucketKeys = async (params: { Bucket: string; Prefix?: string; Marker?: string; MaxKeys?: number }) => { + const s3 = new S3Client({}); + const command = new ListObjectsCommand(params); try { - const result = await s3.listObjects(params).promise(); - return result.Contents.map((contentObj) => contentObj.Key); + const result = await s3.send(command); + return result.Contents?.map((contentObj) => contentObj.Key); } catch (err) { throw new Error(`Error fetching keys for bucket ${params.Bucket}. Underlying error was [${err.message}]`); } @@ -80,28 +115,27 @@ export const getBucketKeys = async (params: S3.ListObjectsRequest) => { export const getDeploymentBucketObject = async (projectRoot: string, objectKey: string) => { const meta = getProjectMeta(projectRoot); const deploymentBucket = meta.providers.awscloudformation.DeploymentBucketName; - const s3 = new S3(); - const result = await s3 - .getObject({ - Bucket: deploymentBucket, - Key: objectKey, - }) - .promise(); - return result.Body.toLocaleString(); -}; - -export const deleteS3Bucket = async (bucket: string, providedS3Client: S3 | undefined = undefined) => { - const s3 = providedS3Client || new S3(); - let continuationToken: Required>; - const objectKeyAndVersion = []; + const s3 = new S3Client({}); + const command = new GetObjectCommand({ + Bucket: deploymentBucket, + Key: objectKey, + }); + const result = await s3.send(command); + return result.Body?.transformToString(); +}; + +export const deleteS3Bucket = async (bucket: string, providedS3Client: S3Client | undefined = undefined) => { + const s3 = providedS3Client || new S3Client({}); + let continuationToken: { KeyMarker?: string; VersionIdMarker?: string } = {}; + const objectKeyAndVersion: { Key?: string; VersionId?: string }[] = []; let truncated = false; + do { - const results = await s3 - .listObjectVersions({ - Bucket: bucket, - ...continuationToken, - }) - .promise(); + const command = new ListObjectVersionsCommand({ + Bucket: bucket, + ...continuationToken, + }); + const results = await s3.send(command); results.Versions?.forEach(({ Key, VersionId }) => { objectKeyAndVersion.push({ Key, VersionId }); @@ -111,32 +145,40 @@ export const deleteS3Bucket = async (bucket: string, providedS3Client: S3 | unde objectKeyAndVersion.push({ Key, VersionId }); }); - continuationToken = { KeyMarker: results.NextKeyMarker, VersionIdMarker: results.NextVersionIdMarker }; + continuationToken = { + KeyMarker: results.NextKeyMarker, + VersionIdMarker: results.NextVersionIdMarker, + }; truncated = results.IsTruncated; } while (truncated); + const chunkedResult = _.chunk(objectKeyAndVersion, 1000); const deleteReq = chunkedResult - .map((r) => ({ - Bucket: bucket, - Delete: { - Objects: r, - Quiet: true, - }, - })) - .map((delParams) => s3.deleteObjects(delParams).promise()); + .map( + (r) => + new DeleteObjectsCommand({ + Bucket: bucket, + Delete: { + Objects: r as ObjectIdentifier[], + Quiet: true, + }, + }), + ) + .map((delCommand) => s3.send(delCommand)); + await Promise.all(deleteReq); - await s3 - .deleteBucket({ - Bucket: bucket, - }) - .promise(); + + const deleteBucketCommand = new DeleteBucketCommand({ Bucket: bucket }); + await s3.send(deleteBucketCommand); await bucketNotExists(bucket); }; export const getUserPool = async (userpoolId, region) => { let res; try { - res = await new CognitoIdentityServiceProvider({ region }).describeUserPool({ UserPoolId: userpoolId }).promise(); + const client = new CognitoIdentityProviderClient({ region }); + const command = new DescribeUserPoolCommand({ UserPoolId: userpoolId }); + res = await client.send(command); } catch (e) { console.log(e); } @@ -146,7 +188,9 @@ export const getUserPool = async (userpoolId, region) => { export const deleteUserPoolDomain = async (domain: string, userpoolId: string, region: string) => { let res; try { - res = await new CognitoIdentityServiceProvider({ region }).deleteUserPoolDomain({ Domain: domain, UserPoolId: userpoolId }).promise(); + const client = new CognitoIdentityProviderClient({ region }); + const command = new DeleteUserPoolDomainCommand({ Domain: domain, UserPoolId: userpoolId }); + res = await client.send(command); } catch (e) { console.log(e); } @@ -154,11 +198,14 @@ export const deleteUserPoolDomain = async (domain: string, userpoolId: string, r }; export const deleteSocialIdpProviders = async (providers: string[], userpoolId: string, region: string) => { + const client = new CognitoIdentityProviderClient({ region }); for (const provider of providers) { try { - await new CognitoIdentityServiceProvider({ region }) - .deleteIdentityProvider({ ProviderName: provider, UserPoolId: userpoolId }) - .promise(); + const command = new DeleteIdentityProviderCommand({ + ProviderName: provider, + UserPoolId: userpoolId, + }); + await client.send(command); } catch (err) { console.log(err); } @@ -168,7 +215,9 @@ export const deleteSocialIdpProviders = async (providers: string[], userpoolId: export const listSocialIdpProviders = async (userpoolId: string, region: string) => { let res; try { - res = await new CognitoIdentityServiceProvider({ region }).listIdentityProviders({ UserPoolId: userpoolId }).promise(); + const client = new CognitoIdentityProviderClient({ region }); + const command = new ListIdentityProvidersCommand({ UserPoolId: userpoolId }); + res = await client.send(command); } catch (err) { console.log(err); } @@ -182,12 +231,12 @@ export const getSocialIdpProvider = async ( ) => { let res; try { - res = await new CognitoIdentityServiceProvider({ region }) - .describeIdentityProvider({ - UserPoolId: userpoolId, - ProviderName: providerName, - }) - .promise(); + const client = new CognitoIdentityProviderClient({ region }); + const command = new DescribeIdentityProviderCommand({ + UserPoolId: userpoolId, + ProviderName: providerName, + }); + res = await client.send(command); } catch (err) { console.log(err); } @@ -197,11 +246,9 @@ export const getSocialIdpProvider = async ( export const getUserPoolDomain = async (domain: string, region: string) => { let res; try { - res = await new CognitoIdentityServiceProvider({ region }) - .describeUserPoolDomain({ - Domain: domain, - }) - .promise(); + const client = new CognitoIdentityProviderClient({ region }); + const command = new DescribeUserPoolDomainCommand({ Domain: domain }); + res = await client.send(command); } catch (err) { console.log(err); } @@ -212,7 +259,9 @@ export const getIdentityPoolRoles = async (identityPoolId: string, region: strin let res; try { - res = await new CognitoIdentity({ region }).getIdentityPoolRoles({ IdentityPoolId: identityPoolId }).promise(); + const client = new CognitoIdentityClient({ region }); + const command = new GetIdentityPoolRolesCommand({ IdentityPoolId: identityPoolId }); + res = await client.send(command); } catch (e) { console.log(e); } @@ -223,24 +272,26 @@ export const getIdentityPoolRoles = async (identityPoolId: string, region: strin export const listUserPools = async (region, maxResults = 5) => { let res; try { - res = await new CognitoIdentityServiceProvider({ region }).listUserPools({ MaxResults: maxResults }).promise(); + const client = new CognitoIdentityProviderClient({ region }); + const command = new ListUserPoolsCommand({ MaxResults: maxResults }); + res = await client.send(command); } catch (e) { console.log(e); } return res?.UserPools ?? []; }; -export const getMFAConfiguration = async ( - userPoolId: string, - region: string, -): Promise => { - return await new CognitoIdentityServiceProvider({ region }).getUserPoolMfaConfig({ UserPoolId: userPoolId }).promise(); +export const getMFAConfiguration = async (userPoolId: string, region: string) => { + const client = new CognitoIdentityProviderClient({ region }); + const command = new GetUserPoolMfaConfigCommand({ UserPoolId: userPoolId }); + return await client.send(command); }; export const getLambdaFunction = async (functionName: string, region: string) => { - const lambda = new Lambda({ region }); + const client = new LambdaClient({ region }); try { - return await lambda.getFunction({ FunctionName: functionName }).promise(); + const command = new GetFunctionCommand({ FunctionName: functionName }); + return await client.send(command); } catch (e) { console.log(e); } @@ -248,16 +299,15 @@ export const getLambdaFunction = async (functionName: string, region: string) => }; export const getUserPoolClients = async (userPoolId: string, clientIds: string[], region: string) => { - const provider = new CognitoIdentityServiceProvider({ region }); + const provider = new CognitoIdentityProviderClient({ region }); const res = []; try { for (let i = 0; i < clientIds.length; i++) { - const clientData = await provider - .describeUserPoolClient({ - UserPoolId: userPoolId, - ClientId: clientIds[i], - }) - .promise(); + const command = new DescribeUserPoolClientCommand({ + UserPoolId: userPoolId, + ClientId: clientIds[i], + }); + const clientData = await provider.send(command); res.push(clientData); } } catch (e) { @@ -267,111 +317,127 @@ export const getUserPoolClients = async (userPoolId: string, clientIds: string[] }; export const addUserToUserPool = async (userPoolId: string, region: string) => { - const provider = new CognitoIdentityServiceProvider({ region }); - const params = { + const provider = new CognitoIdentityProviderClient({ region }); + const command = new AdminCreateUserCommand({ UserPoolId: userPoolId, UserAttributes: [{ Name: 'email', Value: 'username@amazon.com' }], Username: 'testUser', MessageAction: 'SUPPRESS', TemporaryPassword: 'password', - }; - await provider.adminCreateUser(params).promise(); + }); + await provider.send(command); }; /** * list all users in a Cognito user pool */ export const listUsersInUserPool = async (userPoolId: string, region: string): Promise => { - const provider = new CognitoIdentityServiceProvider({ region }); - const params = { - UserPoolId: userPoolId /* required */, - }; - const { Users } = await provider.listUsers(params).promise(); - return Users.map((u) => u.Username); + const provider = new CognitoIdentityProviderClient({ region }); + const command = new ListUsersCommand({ UserPoolId: userPoolId }); + const result = await provider.send(command); + return result.Users?.map((u) => u.Username) || []; }; /** * list all userPool groups to which a user belongs to */ export const listUserPoolGroupsForUser = async (userPoolId: string, userName: string, region: string): Promise => { - const provider = new CognitoIdentityServiceProvider({ region }); - const params = { - UserPoolId: userPoolId /* required */, - Username: userName /* required */, - }; - const res = await provider.adminListGroupsForUser(params).promise(); - const groups = res.Groups.map((group) => group.GroupName); + const provider = new CognitoIdentityProviderClient({ region }); + const command = new AdminListGroupsForUserCommand({ + UserPoolId: userPoolId, + Username: userName, + }); + const res = await provider.send(command); + const groups = res.Groups?.map((group) => group.GroupName) || []; return groups; }; export const getBot = async (botName: string, region: string) => { - const service = new LexModelBuildingService({ region }); - return await service.getBot({ name: botName, versionOrAlias: '$LATEST' }).promise(); + const service = new LexModelBuildingServiceClient({ region }); + const command = new GetBotCommand({ name: botName, versionOrAlias: '$LATEST' }); + return await service.send(command); }; export const getFunction = async (functionName: string, region: string) => { - const service = new Lambda({ region }); - return await service.getFunction({ FunctionName: functionName }).promise(); + const service = new LambdaClient({ region }); + const command = new GetFunctionCommand({ FunctionName: functionName }); + return await service.send(command); }; export const getLayerVersion = async (functionArn: string, region: string) => { - const service = new Lambda({ region }); - return await service.getLayerVersionByArn({ Arn: functionArn }).promise(); + const service = new LambdaClient({ region }); + const command = new GetLayerVersionByArnCommand({ Arn: functionArn }); + return await service.send(command); }; export const listVersions = async (layerName: string, region: string) => { - const service = new Lambda({ region }); - return await service.listLayerVersions({ LayerName: layerName }).promise(); + const service = new LambdaClient({ region }); + const command = new ListLayerVersionsCommand({ LayerName: layerName }); + return await service.send(command); }; export const invokeFunction = async (functionName: string, payload: string, region: string) => { - const service = new Lambda({ region }); - return await service.invoke({ FunctionName: functionName, Payload: payload }).promise(); + const service = new LambdaClient({ region }); + const command = new InvokeCommand({ FunctionName: functionName, Payload: payload }); + return await service.send(command); }; export const getCollection = async (collectionId: string, region: string) => { - const service = new Rekognition({ region }); - return await service.describeCollection({ CollectionId: collectionId }).promise(); + const service = new RekognitionClient({ region }); + const command = new DescribeCollectionCommand({ CollectionId: collectionId }); + return await service.send(command); }; export const getTable = async (tableName: string, region: string) => { - const service = new DynamoDB({ region }); - return await service.describeTable({ TableName: tableName }).promise(); + const service = new DynamoDBClient({ region }); + const command = new DescribeTableCommand({ TableName: tableName }); + return await service.send(command); }; export const getEventSourceMappings = async (functionName: string, region: string) => { - const service = new Lambda({ region }); - return (await service.listEventSourceMappings({ FunctionName: functionName }).promise()).EventSourceMappings; + const service = new LambdaClient({ region }); + const command = new ListEventSourceMappingsCommand({ FunctionName: functionName }); + const result = await service.send(command); + return result.EventSourceMappings || []; }; export const deleteTable = async (tableName: string, region: string) => { - const service = new DynamoDB({ region }); - return await service.deleteTable({ TableName: tableName }).promise(); + const service = new DynamoDBClient({ region }); + const command = new DeleteTableCommand({ TableName: tableName }); + return await service.send(command); }; export const putItemInTable = async (tableName: string, region: string, item: unknown) => { - const ddb = new DynamoDB.DocumentClient({ region }); - return await ddb.put({ TableName: tableName, Item: item }).promise(); + const ddb = new DynamoDBClient({ region }); + const docClient = DynamoDBDocumentClient.from(ddb); + const command = new PutCommand({ TableName: tableName, Item: item }); + return await docClient.send(command); }; export const scanTable = async (tableName: string, region: string) => { - const ddb = new DynamoDB.DocumentClient({ region }); - return await ddb.scan({ TableName: tableName }).promise(); + const ddb = new DynamoDBClient({ region }); + const docClient = DynamoDBDocumentClient.from(ddb); + const command = new ScanCommand({ TableName: tableName }); + return await docClient.send(command); }; export const getAppSyncApi = async (appSyncApiId: string, region: string) => { - const service = new AppSync({ region }); - return await service.getGraphqlApi({ apiId: appSyncApiId }).promise(); + const service = new AppSyncClient({ region }); + const command = new GetGraphqlApiCommand({ apiId: appSyncApiId }); + return await service.send(command); }; export const getCloudWatchLogs = async (region: string, logGroupName: string, logStreamName: string | undefined = undefined) => { - const cloudWatchLogsClient = new CloudWatchLogs({ region, retryDelayOptions: { base: 500 } }); + const cloudWatchLogsClient = new CloudWatchLogsClient({ region, retryMode: 'standard' }); let targetStreamName = logStreamName; if (targetStreamName === undefined) { - const describeStreamsResp = await cloudWatchLogsClient - .describeLogStreams({ logGroupName, descending: true, orderBy: 'LastEventTime' }) - .promise(); + const describeCommand = new DescribeLogStreamsCommand({ + logGroupName, + descending: true, + orderBy: 'LastEventTime', + }); + const describeStreamsResp = await cloudWatchLogsClient.send(describeCommand); if (describeStreamsResp.logStreams === undefined || describeStreamsResp.logStreams.length === 0) { return []; } @@ -379,20 +445,29 @@ export const getCloudWatchLogs = async (region: string, logGroupName: string, lo targetStreamName = describeStreamsResp.logStreams[0].logStreamName; } - const logsResp = await cloudWatchLogsClient.getLogEvents({ logGroupName, logStreamName: targetStreamName }).promise(); + const getLogsCommand = new GetLogEventsCommand({ + logGroupName, + logStreamName: targetStreamName, + }); + const logsResp = await cloudWatchLogsClient.send(getLogsCommand); return logsResp.events || []; }; export const describeCloudFormationStack = async (stackName: string, region: string, profileConfig?: $TSAny) => { - const service = profileConfig ? new CloudFormation(profileConfig) : new CloudFormation({ region }); - return (await service.describeStacks({ StackName: stackName }).promise()).Stacks.find( - (stack) => stack.StackName === stackName || stack.StackId === stackName, - ); + const clientConfig = profileConfig ? profileConfig : { region }; + const client = new CloudFormationClient(clientConfig); + const command = new DescribeStacksCommand({ StackName: stackName }); + const result = await client.send(command); + return result.Stacks?.find((stack) => stack.StackName === stackName || stack.StackId === stackName); }; export const getNestedStackID = async (stackName: string, region: string, logicalId: string): Promise => { - const cfnClient = new CloudFormation({ region }); - const resource = await cfnClient.describeStackResources({ StackName: stackName, LogicalResourceId: logicalId }).promise(); + const cfnClient = new CloudFormationClient({ region }); + const command = new DescribeStackResourcesCommand({ + StackName: stackName, + LogicalResourceId: logicalId, + }); + const resource = await cfnClient.send(command); return resource?.StackResources?.[0].PhysicalResourceId ?? null; }; @@ -405,47 +480,43 @@ export const getNestedStackID = async (stackName: string, region: string, logica */ export const getTableResourceId = async (region: string, table: string, StackId: string): Promise => { - const cfnClient = new CloudFormation({ region }); - const apiResources = await cfnClient - .describeStackResources({ - StackName: StackId, - }) - .promise(); - const resource = apiResources.StackResources.find((stackResource) => table === stackResource.LogicalResourceId); + const cfnClient = new CloudFormationClient({ region }); + const resourcesCommand = new DescribeStackResourcesCommand({ StackName: StackId }); + const apiResources = await cfnClient.send(resourcesCommand); + + const resource = apiResources.StackResources?.find((stackResource) => table === stackResource.LogicalResourceId); if (resource) { - const tableStack = await cfnClient.describeStacks({ StackName: resource.PhysicalResourceId }).promise(); + const stackCommand = new DescribeStacksCommand({ StackName: resource.PhysicalResourceId }); + const tableStack = await cfnClient.send(stackCommand); if (tableStack?.Stacks?.length > 0) { - const tableName = tableStack.Stacks[0].Outputs.find((out) => out.OutputKey === `GetAtt${resource.LogicalResourceId}TableName`); - return tableName.OutputValue; + const tableName = tableStack.Stacks[0].Outputs?.find((out) => out.OutputKey === `GetAtt${resource.LogicalResourceId}TableName`); + return tableName?.OutputValue || null; } } return null; }; export const putKinesisRecords = async (data: string, partitionKey: string, streamName: string, region: string) => { - const kinesis = new Kinesis({ region }); + const kinesis = new KinesisClient({ region }); + const command = new PutRecordsCommand({ + Records: [ + { + Data: new TextEncoder().encode(data), + PartitionKey: partitionKey, + }, + ], + StreamName: streamName, + }); - return await kinesis - .putRecords({ - Records: [ - { - Data: data, - PartitionKey: partitionKey, - }, - ], - StreamName: streamName, - }) - .promise(); + return await kinesis.send(command); }; export const getCloudWatchEventRule = async (targetName: string, region: string) => { - const service = new CloudWatchEvents({ region }); - const params = { - TargetArn: targetName /* required */, - }; + const service = new CloudWatchEventsClient({ region }); + const command = new ListRuleNamesByTargetCommand({ TargetArn: targetName }); let ruleName; try { - ruleName = await service.listRuleNamesByTarget(params).promise(); + ruleName = await service.send(command); } catch (e) { console.log(e); } @@ -453,49 +524,52 @@ export const getCloudWatchEventRule = async (targetName: string, region: string) }; export const setupAmplifyAdminUI = async (appId: string, region: string) => { - const amplifyBackend = new AmplifyBackend({ region }); - - return await amplifyBackend.createBackendConfig({ AppId: appId }).promise(); + const amplifyBackend = new AmplifyBackendClient({ region }); + const command = new CreateBackendConfigCommand({ AppId: appId }); + return await amplifyBackend.send(command); }; export const getAmplifyBackendJobStatus = async (jobId: string, appId: string, envName: string, region: string) => { - const amplifyBackend = new AmplifyBackend({ region }); - - return await amplifyBackend - .getBackendJob({ - JobId: jobId, - AppId: appId, - BackendEnvironmentName: envName, - }) - .promise(); + const amplifyBackend = new AmplifyBackendClient({ region }); + const command = new GetBackendJobCommand({ + JobId: jobId, + AppId: appId, + BackendEnvironmentName: envName, + }); + return await amplifyBackend.send(command); }; export const listRolePolicies = async (roleName: string, region: string) => { - const service = new IAM({ region }); - return (await service.listRolePolicies({ RoleName: roleName }).promise()).PolicyNames; + const service = new IAMClient({ region }); + const command = new ListRolePoliciesCommand({ RoleName: roleName }); + const result = await service.send(command); + return result.PolicyNames || []; }; export const listAttachedRolePolicies = async (roleName: string, region: string) => { - const service = new IAM({ region }); - return (await service.listAttachedRolePolicies({ RoleName: roleName }).promise()).AttachedPolicies; + const service = new IAMClient({ region }); + const command = new ListAttachedRolePoliciesCommand({ RoleName: roleName }); + const result = await service.send(command); + return result.AttachedPolicies || []; }; export const getPermissionsBoundary = async (roleName: string, region) => { - const iamClient = new IAM({ region }); - return (await iamClient.getRole({ RoleName: roleName }).promise())?.Role?.PermissionsBoundary?.PermissionsBoundaryArn; + const iamClient = new IAMClient({ region }); + const command = new GetRoleCommand({ RoleName: roleName }); + const result = await iamClient.send(command); + return result?.Role?.PermissionsBoundary?.PermissionsBoundaryArn; }; export const getSSMParameters = async (region: string, appId: string, envName: string, funcName: string, parameterNames: string[]) => { - const ssmClient = new SSM({ region }); + const ssmClient = new SSMClient({ region }); if (!parameterNames || parameterNames.length === 0) { throw new Error('no parameterNames specified'); } - return await ssmClient - .getParameters({ - Names: parameterNames.map((name) => path.posix.join('/amplify', appId, envName, `AMPLIFY_${funcName}_${name}`)), - WithDecryption: true, - }) - .promise(); + const command = new GetParametersCommand({ + Names: parameterNames.map((name) => path.posix.join('/amplify', appId, envName, `AMPLIFY_${funcName}_${name}`)), + WithDecryption: true, + }); + return await ssmClient.send(command); }; export const deleteSSMParameter = async ( @@ -506,12 +580,11 @@ export const deleteSSMParameter = async ( funcName: string, parameterName: string, ) => { - const ssmClient = new SSM({ region }); - return await ssmClient - .deleteParameter({ - Name: path.posix.join('/amplify', appId, envName, `AMPLIFY_${category}_${funcName}_${parameterName}`), - }) - .promise(); + const ssmClient = new SSMClient({ region }); + const command = new DeleteParameterCommand({ + Name: path.posix.join('/amplify', appId, envName, `AMPLIFY_${category}_${funcName}_${parameterName}`), + }); + return await ssmClient.send(command); }; export const getSSMParametersCategoryPrefix = async ( @@ -522,25 +595,25 @@ export const getSSMParametersCategoryPrefix = async ( resourceName: string, parameterNames: string[], ) => { - const ssmClient = new SSM({ region }); + const ssmClient = new SSMClient({ region }); if (!parameterNames || parameterNames.length === 0) { throw new Error('no parameterNames specified'); } - return ssmClient - .getParameters({ - Names: parameterNames.map((name) => `/amplify/${appId}/${envName}/AMPLIFY_${category}_${resourceName}_${name}`), - }) - .promise(); + const command = new GetParametersCommand({ + Names: parameterNames.map((name) => `/amplify/${appId}/${envName}/AMPLIFY_${category}_${resourceName}_${name}`), + }); + return ssmClient.send(command); }; export const getAllSSMParamatersForAppId = async (appId: string, region: string): Promise> => { - const ssmClient = new SSM({ region }); + const ssmClient = new SSMClient({ region }); const retrievedParameters: Array = []; let receivedNextToken = ''; do { const ssmArgument = getSsmSdkParametersByPath(appId, receivedNextToken); - const data = await ssmClient.getParametersByPath(ssmArgument).promise(); - retrievedParameters.push(...data.Parameters.map((returnedParameter) => returnedParameter.Name)); + const command = new GetParametersByPathCommand(ssmArgument); + const data = await ssmClient.send(command); + retrievedParameters.push(...(data.Parameters?.map((returnedParameter) => returnedParameter.Name) || [])); receivedNextToken = data.NextToken; } while (receivedNextToken); return retrievedParameters; @@ -558,9 +631,9 @@ export const expectParametersOptionalValue = async ( const parametersToRequest = expectToExist.map((exist) => exist.name).concat(expectNotExist); const result = await getSSMParametersCategoryPrefix(region, appId, envName, category, resourceName, parametersToRequest); const mapName = (name: string) => `/amplify/${appId}/${envName}/AMPLIFY_${category}_${resourceName}_${name}`; - expect(result.InvalidParameters.length).toBe(expectNotExist.length); + expect(result.InvalidParameters?.length || 0).toBe(expectNotExist.length); expect(result.InvalidParameters.sort()).toEqual(expectNotExist.map(mapName).sort()); - expect(result.Parameters.length).toBe(expectToExist.length); + expect(result.Parameters?.length || 0).toBe(expectToExist.length); const mappedResult = result.Parameters.map((param) => ({ name: param.Name, value: JSON.parse(param.Value) })).sort(sortByName); const mappedExpect = expectToExist .map((exist) => ({ name: mapName(exist.name), value: exist.value ? exist.value : '' })) @@ -594,50 +667,38 @@ type SsmGetParametersByPathArgument = { // Amazon location service calls export const getMap = async (mapName: string, region: string) => { - const service = new Location({ region }); - return await service - .describeMap({ - MapName: mapName, - }) - .promise(); + const service = new LocationClient({ region }); + const command = new DescribeMapCommand({ MapName: mapName }); + return await service.send(command); }; export const getPlaceIndex = async (placeIndexName: string, region: string) => { - const service = new Location({ region }); - return await service - .describePlaceIndex({ - IndexName: placeIndexName, - }) - .promise(); + const service = new LocationClient({ region }); + const command = new DescribePlaceIndexCommand({ IndexName: placeIndexName }); + return await service.send(command); }; export const getGeofenceCollection = async (geofenceCollectionName: string, region: string) => { - const service = new Location({ region }); - return await service - .describeGeofenceCollection({ - CollectionName: geofenceCollectionName, - }) - .promise(); + const service = new LocationClient({ region }); + const command = new DescribeGeofenceCollectionCommand({ CollectionName: geofenceCollectionName }); + return await service.send(command); }; export const getGeofence = async (geofenceCollectionName: string, geofenceId: string, region: string) => { - const service = new Location({ region }); - return ( - await service.getGeofence({ - CollectionName: geofenceCollectionName, - GeofenceId: geofenceId, - }) - ).promise(); + const service = new LocationClient({ region }); + const command = new GetGeofenceCommand({ + CollectionName: geofenceCollectionName, + GeofenceId: geofenceId, + }); + return await service.send(command); }; // eslint-disable-next-line spellcheck/spell-checker export const listGeofences = async (geofenceCollectionName: string, region: string, nextToken: string = null) => { - const service = new Location({ region }); - // eslint-disable-next-line spellcheck/spell-checker - return ( - await service.listGeofences({ - CollectionName: geofenceCollectionName, - NextToken: nextToken, - }) - ).promise(); + const client = new LocationClient({ region }); + const command = new ListGeofencesCommand({ + CollectionName: geofenceCollectionName, + NextToken: nextToken, + }); + return await client.send(command); }; diff --git a/packages/amplify-e2e-tests/functions/dynamodb-scan-v2.js b/packages/amplify-e2e-tests/functions/dynamodb-scan-v2.js deleted file mode 100644 index 9d3ccf1722e..00000000000 --- a/packages/amplify-e2e-tests/functions/dynamodb-scan-v2.js +++ /dev/null @@ -1,6 +0,0 @@ -const AWS = require('aws-sdk'); -const DDB = new AWS.DynamoDB(); - -exports.handler = async (event) => { - return await DDB.scan({ TableName: event.tableName }).promise(); -}; diff --git a/packages/amplify-e2e-tests/functions/mutation-appsync.js b/packages/amplify-e2e-tests/functions/mutation-appsync.js index 8ef68db28f2..fe76682dbb1 100644 --- a/packages/amplify-e2e-tests/functions/mutation-appsync.js +++ b/packages/amplify-e2e-tests/functions/mutation-appsync.js @@ -1,6 +1,6 @@ /* eslint-disable no-console */ require('isomorphic-fetch'); -const AWS = require('aws-sdk'); +const { fromNodeProviderChain } = require('@aws-sdk/credential-providers'); const AWSAppSyncClient = require('aws-appsync').default; const { AUTH_TYPE } = require('aws-appsync'); const gql = require('graphql-tag'); @@ -11,7 +11,8 @@ const runGQLMutation = async (gql_url, mutation, variables) => { region: process.env.REGION, auth: { type: AUTH_TYPE.AWS_IAM, - credentials: AWS.config.credentials, + // See documentation here: https://www.npmjs.com/package/@aws-sdk/credential-providers + credentials: fromNodeProviderChain(), }, disableOffline: true, }); diff --git a/packages/amplify-e2e-tests/functions/s3-list-objects.js b/packages/amplify-e2e-tests/functions/s3-list-objects.js index 849e88491ce..621829d4e8f 100644 --- a/packages/amplify-e2e-tests/functions/s3-list-objects.js +++ b/packages/amplify-e2e-tests/functions/s3-list-objects.js @@ -1,13 +1,13 @@ -const AWS = require('aws-sdk'); -const awsS3Client = new AWS.S3(); +const { S3Client, ListObjectsV2Command } = require('@aws-sdk/client-s3'); +const awsS3Client = new S3Client(); const bucketEnvVar = '{{bucketEnvVar}}'; // This value is replaced from test exports.handler = async () => { - const listObjects = await awsS3Client - .listObjectsV2({ - Bucket: process.env[bucketEnvVar], - }) - .promise(); + const command = new ListObjectsV2Command({ + Bucket: process.env[bucketEnvVar], + }); + + const listObjects = await awsS3Client.send(command); return listObjects; }; diff --git a/packages/amplify-e2e-tests/package.json b/packages/amplify-e2e-tests/package.json index 202fa72d0f2..3b454df64d3 100644 --- a/packages/amplify-e2e-tests/package.json +++ b/packages/amplify-e2e-tests/package.json @@ -30,10 +30,22 @@ "@aws-amplify/amplify-e2e-core": "5.7.6", "@aws-amplify/amplify-opensearch-simulator": "1.7.22", "@aws-amplify/graphql-transformer-core": "^2.11.2", + "@aws-sdk/client-amplify": "^3.919.0", + "@aws-sdk/client-amplifyuibuilder": "^3.919.0", "@aws-sdk/client-appsync": "^3.919.0", + "@aws-sdk/client-cloudformation": "^3.919.0", + "@aws-sdk/client-cloudfront": "^3.919.0", + "@aws-sdk/client-codebuild": "^3.919.0", + "@aws-sdk/client-cognito-identity-provider": "^3.919.0", "@aws-sdk/client-dynamodb": "^3.919.0", + "@aws-sdk/client-iam": "^3.919.0", + "@aws-sdk/client-organizations": "^3.920.0", + "@aws-sdk/client-pinpoint": "3.901.0", "@aws-sdk/client-s3": "^3.919.0", "@aws-sdk/client-ssm": "^3.919.0", + "@aws-sdk/client-sts": "^3.919.0", + "@aws-sdk/credential-providers": "^3.919.0", + "@aws-sdk/lib-storage": "^3.919.0", "@babel/core": "^7.23.2", "@babel/plugin-transform-modules-commonjs": "7.10.4", "amplify-dynamodb-simulator": "2.9.26", @@ -42,7 +54,6 @@ "aws-amplify": "^5.3.16", "aws-appsync": "^4.1.1", "aws-cdk-lib": "~2.189.1", - "aws-sdk": "^2.1464.0", "axios": "^1.11.0", "constructs": "^10.0.5", "dotenv": "^8.2.0", diff --git a/packages/amplify-e2e-tests/src/__tests__/api_1.test.ts b/packages/amplify-e2e-tests/src/__tests__/api_1.test.ts index 72256158db6..9ab144387d8 100644 --- a/packages/amplify-e2e-tests/src/__tests__/api_1.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/api_1.test.ts @@ -58,12 +58,12 @@ describe('amplify add api (GraphQL)', () => { expect(graphqlApi).toBeDefined(); expect(graphqlApi.apiId).toEqual(GraphQLAPIIdOutput); const tableName = `AmplifyDataStore-${graphqlApi.apiId}-${envName}`; - const error = { message: null }; + let error: Error; try { const table = await getDDBTable(tableName, region); - expect(table).toBeUndefined(); + expect(table.Table).toBeUndefined(); } catch (ex) { - Object.assign(error, ex); + error = ex; } expect(error).toBeDefined(); expect(error.message).toContain(`${tableName} not found`); @@ -117,12 +117,12 @@ describe('amplify add api (GraphQL)', () => { expect(graphqlApi).toBeDefined(); expect(graphqlApi.apiId).toEqual(GraphQLAPIIdOutput); const tableName = `AmplifyDataStore-${graphqlApi.apiId}-${envName}`; - const error = { message: null }; + let error: Error; try { const table = await getDDBTable(tableName, region); - expect(table).toBeUndefined(); + expect(table.Table).toBeUndefined(); } catch (ex) { - Object.assign(error, ex); + error = ex; } expect(error).toBeDefined(); expect(error.message).toContain(`${tableName} not found`); diff --git a/packages/amplify-e2e-tests/src/__tests__/api_7.test.ts b/packages/amplify-e2e-tests/src/__tests__/api_7.test.ts index a062cec5544..93871f4a899 100644 --- a/packages/amplify-e2e-tests/src/__tests__/api_7.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/api_7.test.ts @@ -59,12 +59,12 @@ describe('amplify add api (GraphQL)', () => { expect(graphqlApi).toBeDefined(); expect(graphqlApi.apiId).toEqual(GraphQLAPIIdOutput); const tableName = `AmplifyDataStore-${graphqlApi.apiId}-${envName}`; - const error = { message: null }; + let error: Error; try { const table = await getDDBTable(tableName, region); - expect(table).toBeUndefined(); + expect(table.Table).toBeUndefined(); } catch (ex) { - Object.assign(error, ex); + error = ex; } expect(error).toBeDefined(); expect(error.message).toContain(`${tableName} not found`); diff --git a/packages/amplify-e2e-tests/src/__tests__/api_9b.test.ts b/packages/amplify-e2e-tests/src/__tests__/api_9b.test.ts index 6eb1af05aa2..0581f3e0289 100644 --- a/packages/amplify-e2e-tests/src/__tests__/api_9b.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/api_9b.test.ts @@ -74,12 +74,12 @@ describe('amplify add api (GraphQL)', () => { expect(graphqlApi).toBeDefined(); expect(graphqlApi.apiId).toEqual(GraphQLAPIIdOutput); const tableName = `Comment-${GraphQLAPIIdOutput}-integtest`; - const error = { message: null }; + let error: Error; try { const table = await getDDBTable(tableName, region); - expect(table).toBeUndefined(); + expect(table.Table).toBeUndefined(); } catch (ex) { - Object.assign(error, ex); + error = ex; } expect(error).toBeDefined(); expect(error.message).toContain(`${tableName} not found`); diff --git a/packages/amplify-e2e-tests/src/__tests__/auth/admin-api.test.ts b/packages/amplify-e2e-tests/src/__tests__/auth/admin-api.test.ts index 45e16415a30..4f474735104 100644 --- a/packages/amplify-e2e-tests/src/__tests__/auth/admin-api.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/auth/admin-api.test.ts @@ -31,7 +31,7 @@ describe('auth admin api tests', () => { }; } const lambdaResponse = await invokeFunction(adminLambdaName, JSON.stringify(request), adminLambdaRegion); - return JSON.parse(lambdaResponse.Payload.toString()); + return JSON.parse(lambdaResponse.Payload.transformToString()); }; beforeAll(async () => { diff --git a/packages/amplify-e2e-tests/src/__tests__/auth/hosted-ui.test.ts b/packages/amplify-e2e-tests/src/__tests__/auth/hosted-ui.test.ts index b998be45e83..b57592f9fb2 100644 --- a/packages/amplify-e2e-tests/src/__tests__/auth/hosted-ui.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/auth/hosted-ui.test.ts @@ -135,7 +135,9 @@ describe('hosted ui tests', () => { const updatedDomainRes = await getUserPoolDomain(hostedUIDomain, region); expect(updatedDomainRes).toBeDefined(); const originalDomainRes = await getUserPoolDomain(originalHostedUIDomain, region); - expect(originalDomainRes).toEqual({ DomainDescription: {} }); + // originalDomainRes has 2 properties $metadata and DomainDescription, we expect DomainDescription to be an empty object + // $metadata property is common in SDK V3 objects + expect(originalDomainRes.DomainDescription).toEqual({}); const deleteOriginalDomainRes = await deleteUserPoolDomain(originalHostedUIDomain, userPoolId, region); // undefined response as it throws InvalidParameterException: No such domain or user pool exists. diff --git a/packages/amplify-e2e-tests/src/__tests__/auth_9.test.ts b/packages/amplify-e2e-tests/src/__tests__/auth_9.test.ts index f12047d033b..5ecced7c6ad 100644 --- a/packages/amplify-e2e-tests/src/__tests__/auth_9.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/auth_9.test.ts @@ -10,7 +10,7 @@ import { initJSProjectWithProfile, nspawn as spawn, } from '@aws-amplify/amplify-e2e-core'; -import { CognitoIdentityServiceProvider } from 'aws-sdk'; +import { DescribeUserPoolCommandOutput } from '@aws-sdk/client-cognito-identity-provider'; const defaultsSettings = { name: 'authTest', @@ -35,10 +35,7 @@ describe('amplify auth with trigger', () => { const meta = getProjectMeta(projRoot); const userPoolId = Object.keys(meta.auth).map((key) => meta.auth[key])[0].output.UserPoolId; - let userPool = (await getUserPool( - userPoolId, - meta.providers.awscloudformation.Region, - )) as CognitoIdentityServiceProvider.DescribeUserPoolResponse; + let userPool = (await getUserPool(userPoolId, meta.providers.awscloudformation.Region)) as DescribeUserPoolCommandOutput; expect(userPool.UserPool).toBeDefined(); expect(userPool.UserPool.LambdaConfig).toBeDefined(); @@ -50,10 +47,7 @@ describe('amplify auth with trigger', () => { await amplifyPushAuth(projRoot); - userPool = (await getUserPool( - userPoolId, - meta.providers.awscloudformation.Region, - )) as CognitoIdentityServiceProvider.DescribeUserPoolResponse; + userPool = (await getUserPool(userPoolId, meta.providers.awscloudformation.Region)) as DescribeUserPoolCommandOutput; expect(userPool.UserPool).toBeDefined(); expect(userPool.UserPool.EmailVerificationSubject).toBe('New code'); diff --git a/packages/amplify-e2e-tests/src/__tests__/custom_policies_container.test.ts b/packages/amplify-e2e-tests/src/__tests__/custom_policies_container.test.ts index 39c7bc53d93..98a2e0b4379 100644 --- a/packages/amplify-e2e-tests/src/__tests__/custom_policies_container.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/custom_policies_container.test.ts @@ -11,7 +11,7 @@ import { deleteProjectDir, } from '@aws-amplify/amplify-e2e-core'; import { JSONUtilities } from '@aws-amplify/amplify-cli-core'; -import AWS from 'aws-sdk'; +import { SSMClient, GetParameterCommand, PutParameterCommand } from '@aws-sdk/client-ssm'; import path from 'path'; const customIAMPolicy: CustomIAMPolicy = { @@ -50,21 +50,21 @@ it(`should init and deploy a api container, attach custom policies to the Fargat const region = meta?.providers?.awscloudformation.Region ?? undefined; // Put SSM parameter - const ssmClient = new AWS.SSM({ region }); - await ssmClient - .putParameter({ + const ssmClient = new SSMClient({ region }); + await ssmClient.send( + new PutParameterCommand({ Name: '/amplify/testCustomPolicies', Value: 'testCustomPoliciesValue', Type: 'String', Overwrite: true, - }) - .promise(); + }), + ); - const getParaResponse = await ssmClient - .getParameter({ + const getParaResponse = await ssmClient.send( + new GetParameterCommand({ Name: '/amplify/testCustomPolicies', - }) - .promise(); + }), + ); const ssmParameterArn = getParaResponse.Parameter.ARN; customIAMPolicy.Resource.push(ssmParameterArn); diff --git a/packages/amplify-e2e-tests/src/__tests__/custom_policies_function.test.ts b/packages/amplify-e2e-tests/src/__tests__/custom_policies_function.test.ts index e7a0952be1c..1aac8f8acac 100644 --- a/packages/amplify-e2e-tests/src/__tests__/custom_policies_function.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/custom_policies_function.test.ts @@ -88,7 +88,7 @@ it('should init and deploy storage DynamoDB + Lambda trigger, attach custom poli // check that the lambda response includes the secret value const response = await invokeFunction(`${funcName}-integtest`, JSON.stringify(lambdaEvent), region); - expect(JSON.parse(response.Payload.toString())?.Value).toEqual('testCustomPoliciesValue'); + expect(JSON.parse(response.Payload.transformToString())?.Value).toEqual('testCustomPoliciesValue'); }); type CustomIAMPolicy = { diff --git a/packages/amplify-e2e-tests/src/__tests__/delete.test.ts b/packages/amplify-e2e-tests/src/__tests__/delete.test.ts index 24f19f12e37..cf472608d04 100644 --- a/packages/amplify-e2e-tests/src/__tests__/delete.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/delete.test.ts @@ -1,4 +1,5 @@ -import { S3, Amplify } from 'aws-sdk'; +import { S3Client, HeadBucketCommand, PutObjectCommand } from '@aws-sdk/client-s3'; +import { AmplifyClient, GetAppCommand } from '@aws-sdk/client-amplify'; import { addPinpointAnalytics, addApiWithoutSchema, @@ -137,22 +138,22 @@ async function testDeletion(projRoot: string, settings: { ios?: boolean; android } async function putFiles(bucket: string, count = 1001) { - const s3 = new S3(); + const s3 = new S3Client(); const s3Params = [...Array(count)].map((_, num) => ({ Bucket: bucket, Body: 'dummy body', Key: `${num}.txt`, })); - await Promise.all(s3Params.map((p) => s3.putObject(p).promise())); + await Promise.all(s3Params.map((p) => s3.send(new PutObjectCommand(p)))); } async function bucketExists(bucket: string) { - const s3 = new S3(); + const s3 = new S3Client(); const params = { Bucket: bucket, }; try { - await s3.headBucket(params).promise(); + await s3.send(new HeadBucketCommand(params)); return true; } catch (error) { if (error.statusCode === 404) { @@ -163,9 +164,9 @@ async function bucketExists(bucket: string) { } async function appExists(appId: string, region: string) { - const amplify = new Amplify({ region }); + const amplify = new AmplifyClient({ region }); try { - await amplify.getApp({ appId }).promise(); + await amplify.send(new GetAppCommand({ appId })); return true; } catch (ex) { return false; diff --git a/packages/amplify-e2e-tests/src/__tests__/function_1.test.ts b/packages/amplify-e2e-tests/src/__tests__/function_1.test.ts index 4140bb6c41c..bc1c53b0bc4 100644 --- a/packages/amplify-e2e-tests/src/__tests__/function_1.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/function_1.test.ts @@ -50,7 +50,7 @@ describe('nodejs', () => { expect(region).toBeDefined(); const cloudFunction = await getFunction(Name, region); const response = await invokeFunction(Name, JSON.stringify({}), region); - const payload = JSON.parse(response.Payload.toString()); + const payload = JSON.parse(response.Payload.transformToString()); expect(payload.headers['Access-Control-Allow-Origin']).toEqual('*'); expect(payload.headers['Access-Control-Allow-Headers']).toEqual('*'); expect(cloudFunction.Configuration.FunctionArn).toEqual(functionArn); diff --git a/packages/amplify-e2e-tests/src/__tests__/function_11.test.ts b/packages/amplify-e2e-tests/src/__tests__/function_11.test.ts index 359035d59d6..de3035bdbd2 100644 --- a/packages/amplify-e2e-tests/src/__tests__/function_11.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/function_11.test.ts @@ -116,7 +116,7 @@ describe('Lambda AppSync nodejs:', () => { expect(fnResponse.StatusCode).toBe(200); expect(fnResponse.Payload).toBeDefined(); - const gqlResponse = JSON.parse(fnResponse.Payload as string); + const gqlResponse = JSON.parse(fnResponse.Payload.transformToString()); expect(gqlResponse.body).toBeDefined(); }); @@ -167,7 +167,7 @@ describe('Lambda AppSync nodejs:', () => { expect(fnResponse.StatusCode).toBe(200); expect(fnResponse.Payload).toBeDefined(); - const gqlResponse = JSON.parse(fnResponse.Payload as string); + const gqlResponse = JSON.parse(fnResponse.Payload.transformToString()); expect(gqlResponse.body).toBeDefined(); }); diff --git a/packages/amplify-e2e-tests/src/__tests__/function_2b.test.ts b/packages/amplify-e2e-tests/src/__tests__/function_2b.test.ts index 99e14b1a10e..15197670c65 100644 --- a/packages/amplify-e2e-tests/src/__tests__/function_2b.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/function_2b.test.ts @@ -77,7 +77,7 @@ describe('nodejs', () => { expect(result1.StatusCode).toBe(200); expect(result1.Payload).toBeDefined(); - const payload1 = JSON.parse(result1.Payload.toString()); + const payload1 = JSON.parse(result1.Payload.transformToString()); expect(payload1.errorType).toBeUndefined(); expect(payload1.errorMessage).toBeUndefined(); expect(payload1.Items).toBeDefined(); @@ -90,7 +90,7 @@ describe('nodejs', () => { expect(result2.StatusCode).toBe(200); expect(result2.Payload).toBeDefined(); - const payload2 = JSON.parse(result2.Payload.toString()); + const payload2 = JSON.parse(result2.Payload.transformToString()); expect(payload2.errorType).toBeUndefined(); expect(payload2.errorMessage).toBeUndefined(); expect(payload2.Items).toBeDefined(); @@ -153,7 +153,7 @@ describe('nodejs', () => { expect(result.StatusCode).toBe(200); expect(result.Payload).toBeDefined(); - const payload = JSON.parse(result.Payload.toString()); + const payload = JSON.parse(result.Payload.transformToString()); expect(payload.errorType).toBeUndefined(); expect(payload.errorMessage).toBeUndefined(); expect(payload.Items).toBeDefined(); diff --git a/packages/amplify-e2e-tests/src/__tests__/function_2d.test.ts b/packages/amplify-e2e-tests/src/__tests__/function_2d.test.ts index 2f881d3a036..ae99c912232 100644 --- a/packages/amplify-e2e-tests/src/__tests__/function_2d.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/function_2d.test.ts @@ -59,8 +59,8 @@ describe('nodejs', () => { }, }), }); - expect(JSON.parse(response.Payload.toString()).statusCode).toEqual(200); - expect(JSON.parse(response.Payload.toString()).body).toContain('post call succeed!'); + expect(JSON.parse(response.Payload.transformToString()).statusCode).toEqual(200); + expect(JSON.parse(response.Payload.transformToString()).body).toContain('post call succeed!'); response = await functionCloudInvoke(projRoot, { funcName, @@ -73,8 +73,8 @@ describe('nodejs', () => { }, }), }); - expect(JSON.parse(response.Payload.toString()).statusCode).toEqual(200); - expect(JSON.parse(response.Payload.toString()).body).toContain('post call succeed!'); + expect(JSON.parse(response.Payload.transformToString()).statusCode).toEqual(200); + expect(JSON.parse(response.Payload.transformToString()).body).toContain('post call succeed!'); response = await functionCloudInvoke(projRoot, { funcName, @@ -87,8 +87,8 @@ describe('nodejs', () => { }, }), }); - expect(JSON.parse(response.Payload.toString()).statusCode).toEqual(200); - expect(JSON.parse(response.Payload.toString()).body).toContain('put call succeed!'); + expect(JSON.parse(response.Payload.transformToString()).statusCode).toEqual(200); + expect(JSON.parse(response.Payload.transformToString()).body).toContain('put call succeed!'); response = await functionCloudInvoke(projRoot, { funcName, @@ -97,8 +97,8 @@ describe('nodejs', () => { httpMethod: 'GET', }), }); - expect(JSON.parse(response.Payload.toString()).statusCode).toEqual(200); - expect(JSON.parse(JSON.parse(response.Payload.toString()).body)).toEqual([item1]); + expect(JSON.parse(response.Payload.transformToString()).statusCode).toEqual(200); + expect(JSON.parse(JSON.parse(response.Payload.transformToString()).body)).toEqual([item1]); response = await functionCloudInvoke(projRoot, { funcName, @@ -107,8 +107,8 @@ describe('nodejs', () => { httpMethod: 'GET', }), }); - expect(JSON.parse(response.Payload.toString()).statusCode).toEqual(200); - expect(JSON.parse(JSON.parse(response.Payload.toString()).body)).toEqual(item2); + expect(JSON.parse(response.Payload.transformToString()).statusCode).toEqual(200); + expect(JSON.parse(JSON.parse(response.Payload.transformToString()).body)).toEqual(item2); response = await functionCloudInvoke(projRoot, { funcName, @@ -117,9 +117,9 @@ describe('nodejs', () => { httpMethod: 'GET', }), }); - expect(JSON.parse(response.Payload.toString()).statusCode).toEqual(200); - expect(JSON.parse(JSON.parse(response.Payload.toString()).body)).toContainEqual(item1); - expect(JSON.parse(JSON.parse(response.Payload.toString()).body)).toContainEqual(item2); + expect(JSON.parse(response.Payload.transformToString()).statusCode).toEqual(200); + expect(JSON.parse(JSON.parse(response.Payload.transformToString()).body)).toContainEqual(item1); + expect(JSON.parse(JSON.parse(response.Payload.transformToString()).body)).toContainEqual(item2); response = await functionCloudInvoke(projRoot, { funcName, @@ -128,7 +128,7 @@ describe('nodejs', () => { httpMethod: 'DELETE', }), }); - expect(JSON.parse(response.Payload.toString()).statusCode).toEqual(200); + expect(JSON.parse(response.Payload.transformToString()).statusCode).toEqual(200); }); }); }); diff --git a/packages/amplify-e2e-tests/src/__tests__/function_3a_dotnet.test.ts b/packages/amplify-e2e-tests/src/__tests__/function_3a_dotnet.test.ts index f34c4a22958..6c4566803f4 100644 --- a/packages/amplify-e2e-tests/src/__tests__/function_3a_dotnet.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/function_3a_dotnet.test.ts @@ -53,6 +53,6 @@ describe('dotnet function tests', () => { const payload = '{"key1":"value1","key2":"value2","key3":"value3"}'; await amplifyPushAuth(projRoot); const response = await functionCloudInvoke(projRoot, { funcName, payload }); - expect(JSON.parse(response.Payload.toString())).toEqual(helloWorldSuccessObj); + expect(JSON.parse(response.Payload.transformToString())).toEqual(helloWorldSuccessObj); }); }); diff --git a/packages/amplify-e2e-tests/src/__tests__/function_3a_go.test.ts b/packages/amplify-e2e-tests/src/__tests__/function_3a_go.test.ts index db523a78abe..99dde69aa85 100644 --- a/packages/amplify-e2e-tests/src/__tests__/function_3a_go.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/function_3a_go.test.ts @@ -39,6 +39,6 @@ describe('go function tests', () => { const payload = '{"name":"Amplify"}'; await amplifyPushAuth(projRoot); const response = await functionCloudInvoke(projRoot, { funcName, payload }); - expect(JSON.parse(response.Payload.toString())).toEqual(helloWorldSuccessOutput); + expect(JSON.parse(response.Payload.transformToString())).toEqual(helloWorldSuccessOutput); }); }); diff --git a/packages/amplify-e2e-tests/src/__tests__/function_3a_nodejs.test.ts b/packages/amplify-e2e-tests/src/__tests__/function_3a_nodejs.test.ts index 39764fc6b29..a980ce1fe34 100644 --- a/packages/amplify-e2e-tests/src/__tests__/function_3a_nodejs.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/function_3a_nodejs.test.ts @@ -58,7 +58,7 @@ describe('nodejs function tests', () => { const response = await functionCloudInvoke(projRoot, { funcName, payload }); - expect(JSON.parse(response.Payload.toString())).toEqual(helloWorldSuccessObj); + expect(JSON.parse(response.Payload.transformToString())).toEqual(helloWorldSuccessObj); }); it('add nodejs hello world function and mock locally, check buildType, push, check buildType', async () => { diff --git a/packages/amplify-e2e-tests/src/__tests__/function_3a_python.test.ts b/packages/amplify-e2e-tests/src/__tests__/function_3a_python.test.ts index 4f622dd0483..ee7d6c10587 100644 --- a/packages/amplify-e2e-tests/src/__tests__/function_3a_python.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/function_3a_python.test.ts @@ -65,6 +65,6 @@ describe('python function tests', () => { ...helloWorldSuccessOutput, body: JSON.stringify(helloWorldSuccessOutput.body), }; - expect(JSON.parse(response.Payload.toString())).toEqual(JSON.parse(JSON.stringify(helloWorldSuccessOutputCloud))); + expect(JSON.parse(response.Payload.transformToString())).toEqual(JSON.parse(JSON.stringify(helloWorldSuccessOutputCloud))); }); }); diff --git a/packages/amplify-e2e-tests/src/__tests__/function_3b.test.ts b/packages/amplify-e2e-tests/src/__tests__/function_3b.test.ts index 9af13f0d2a3..e1516fe542c 100644 --- a/packages/amplify-e2e-tests/src/__tests__/function_3b.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/function_3b.test.ts @@ -79,7 +79,7 @@ describe('dotnet function tests', () => { const payload = '{"key1":"value1","key2":"value2","key3":"value3"}'; await amplifyPushAuth(projRoot); const response = await functionCloudInvoke(projRoot, { funcName, payload }); - expect(JSON.parse(response.Payload.toString())).toEqual(helloWorldSuccessObj); + expect(JSON.parse(response.Payload.transformToString())).toEqual(helloWorldSuccessObj); assertDotNetVersion(); }); @@ -120,7 +120,7 @@ describe('dotnet function tests', () => { }); await amplifyPushAuth(projRoot); const response = await functionCloudInvoke(projRoot, { funcName, payload }); - expect(JSON.parse(response.Payload.toString()).statusCode).toEqual(200); + expect(JSON.parse(response.Payload.transformToString()).statusCode).toEqual(200); assertDotNetVersion(); }); diff --git a/packages/amplify-e2e-tests/src/__tests__/function_4.test.ts b/packages/amplify-e2e-tests/src/__tests__/function_4.test.ts index bada470a22b..3a8bc46a8f6 100644 --- a/packages/amplify-e2e-tests/src/__tests__/function_4.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/function_4.test.ts @@ -77,7 +77,7 @@ describe('add function with layers for runtime nodeJS', () => { const payload = '{}'; const response = await functionCloudInvoke(projRoot, { funcName: functionName, payload }); - expect(JSON.parse(JSON.parse(response.Payload.toString()).body)).toEqual(helloWorldSuccessOutput); + expect(JSON.parse(JSON.parse(response.Payload.transformToString()).body)).toEqual(helloWorldSuccessOutput); }); it('can add multiple project layers for nodejs', async () => { @@ -128,7 +128,7 @@ describe('add function with layers for runtime nodeJS', () => { const payload = '{}'; const response = await functionCloudInvoke(projRoot, { funcName: functionName, payload }); - expect(JSON.parse(JSON.parse(response.Payload.toString()).body)).toEqual(helloWorldSuccessOutput); + expect(JSON.parse(JSON.parse(response.Payload.transformToString()).body)).toEqual(helloWorldSuccessOutput); }); }); @@ -191,6 +191,6 @@ describe('add function with layers for runtime python', () => { const payload = '{}'; const response = await functionCloudInvoke(projRoot, { funcName: functionName, payload }); - expect(JSON.parse(response.Payload.toString()).body).toMatch(helloWorldSuccessOutput); + expect(JSON.parse(response.Payload.transformToString()).body).toMatch(helloWorldSuccessOutput); }); }); diff --git a/packages/amplify-e2e-tests/src/__tests__/function_7.test.ts b/packages/amplify-e2e-tests/src/__tests__/function_7.test.ts index 52b9154eeab..0421c9dc134 100644 --- a/packages/amplify-e2e-tests/src/__tests__/function_7.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/function_7.test.ts @@ -62,7 +62,7 @@ describe('function secret value', () => { // check that the lambda response includes the secret value const response = await invokeFunction(`${funcName}-integtest`, JSON.stringify(lambdaEvent), region); - expect(JSON.parse(response.Payload.toString())[0]?.Value).toEqual('testsecretvalue'); + expect(JSON.parse(response.Payload.transformToString())[0]?.Value).toEqual('testsecretvalue'); }); it('removes secrets immediately when func not pushed', async () => { diff --git a/packages/amplify-e2e-tests/src/__tests__/function_8.test.ts b/packages/amplify-e2e-tests/src/__tests__/function_8.test.ts index 976e1813bbb..030e80492e2 100644 --- a/packages/amplify-e2e-tests/src/__tests__/function_8.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/function_8.test.ts @@ -57,7 +57,7 @@ describe('java function tests', () => { const payload = '{"firstName":"John","lastName" : "Doe"}'; await amplifyPushAuth(projRoot); const response = await functionCloudInvoke(projRoot, { funcName, payload }); - expect(JSON.parse(response.Payload.toString())).toEqual(helloWorldSuccessObj); + expect(JSON.parse(response.Payload.transformToString())).toEqual(helloWorldSuccessObj); }); }); diff --git a/packages/amplify-e2e-tests/src/__tests__/function_9b.test.ts b/packages/amplify-e2e-tests/src/__tests__/function_9b.test.ts index 65a19100a96..b136dad9c8d 100644 --- a/packages/amplify-e2e-tests/src/__tests__/function_9b.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/function_9b.test.ts @@ -143,7 +143,7 @@ describe('nodejs', () => { expect(fnResponse.StatusCode).toBe(200); expect(fnResponse.Payload).toBeDefined(); - const gqlResponse = JSON.parse(fnResponse.Payload as string); + const gqlResponse = JSON.parse(fnResponse.Payload.transformToString()); expect(gqlResponse.data).toBeDefined(); expect(gqlResponse.data.createTodo.name).toEqual('todo'); @@ -203,7 +203,7 @@ describe('nodejs', () => { expect(fnResponse.StatusCode).toBe(200); expect(fnResponse.Payload).toBeDefined(); - const gqlResponse = JSON.parse(fnResponse.Payload as string); + const gqlResponse = JSON.parse(fnResponse.Payload.transformToString()); expect(gqlResponse.data).toBeDefined(); expect(gqlResponse.data.createTodo.name).toEqual('todo'); diff --git a/packages/amplify-e2e-tests/src/__tests__/function_9c.test.ts b/packages/amplify-e2e-tests/src/__tests__/function_9c.test.ts index 6608d476ee1..579af2095d2 100644 --- a/packages/amplify-e2e-tests/src/__tests__/function_9c.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/function_9c.test.ts @@ -70,7 +70,7 @@ describe('nodejs', () => { expect(fnResponse.StatusCode).toBe(200); expect(fnResponse.Payload).toBeDefined(); - const apiResponse = JSON.parse(fnResponse.Payload as string); + const apiResponse = JSON.parse(fnResponse.Payload.transformToString()); expect(apiResponse.graphqlApi).toBeDefined(); expect(apiResponse.graphqlApi.name).toContain(apiName); }); diff --git a/packages/amplify-e2e-tests/src/__tests__/git-clone-attach.test.ts b/packages/amplify-e2e-tests/src/__tests__/git-clone-attach.test.ts index ad7939eb021..94df019f0d5 100644 --- a/packages/amplify-e2e-tests/src/__tests__/git-clone-attach.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/git-clone-attach.test.ts @@ -25,16 +25,16 @@ import { nonInteractiveInitAttach, nonInteractivePullAttach, } from '@aws-amplify/amplify-e2e-core'; -import { S3 } from 'aws-sdk'; +import { S3Client, CreateBucketCommand, DeleteBucketCommand } from '@aws-sdk/client-s3'; import { getShortId, importS3 } from '../import-helpers'; describe('attach amplify to git-cloned project', () => { const envName = 'test'; let projRoot: string; - const s3Client = new S3(); + const s3Client = new S3Client(); const importBucketName = `git-clone-test-bucket-${getShortId()}`; beforeAll(async () => { - await s3Client.createBucket({ Bucket: importBucketName }).promise(); + await s3Client.send(new CreateBucketCommand({ Bucket: importBucketName })); projRoot = await createNewProjectDir('clone-test'); await initJSProjectWithProfile(projRoot, { envName, disableAmplifyAppCreation: false }); await addFunction( @@ -60,7 +60,7 @@ describe('attach amplify to git-cloned project', () => { await deleteProject(projRoot); deleteProjectDir(projRoot); } finally { - await s3Client.deleteBucket({ Bucket: importBucketName }).promise(); + await s3Client.send(new DeleteBucketCommand({ Bucket: importBucketName })); } }); diff --git a/packages/amplify-e2e-tests/src/__tests__/hostingPROD.test.ts b/packages/amplify-e2e-tests/src/__tests__/hostingPROD.test.ts index 826de4355ec..a55a73f2fed 100644 --- a/packages/amplify-e2e-tests/src/__tests__/hostingPROD.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/hostingPROD.test.ts @@ -1,4 +1,4 @@ -import { CloudFront } from 'aws-sdk'; +import { CloudFrontClient, GetDistributionCommand } from '@aws-sdk/client-cloudfront'; import { amplifyPublishWithoutUpdate, createReactTestProject, @@ -77,11 +77,11 @@ describe('amplify add hosting', () => { }); async function getCloudFrontDistribution(cloudFrontDistributionID: string) { - const cloudFrontClient = new CloudFront(); - const getDistributionResult = await cloudFrontClient - .getDistribution({ + const cloudFrontClient = new CloudFrontClient(); + const getDistributionResult = await cloudFrontClient.send( + new GetDistributionCommand({ Id: cloudFrontDistributionID, - }) - .promise(); + }), + ); return getDistributionResult.Distribution; } diff --git a/packages/amplify-e2e-tests/src/__tests__/import_s3_3.test.ts b/packages/amplify-e2e-tests/src/__tests__/import_s3_3.test.ts index 0e8ed5e3883..15d8f8dfe9f 100644 --- a/packages/amplify-e2e-tests/src/__tests__/import_s3_3.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/import_s3_3.test.ts @@ -1,4 +1,4 @@ -import * as aws from 'aws-sdk'; +import { S3Client, CreateBucketCommand, GetBucketLocationCommand, DeleteBucketCommand } from '@aws-sdk/client-s3'; import { addAuthWithDefault, amplifyPushAuth, @@ -36,26 +36,27 @@ describe('headless s3 import', () => { const shortId = getShortId(); bucketNameToImport = `${bucketPrefix}${shortId}`; - const s3 = new aws.S3(); + // setting default region for S3 Client + const s3 = new S3Client({ region: 'us-east-1' }); - await s3 - .createBucket({ + await s3.send( + new CreateBucketCommand({ Bucket: bucketNameToImport, - }) - .promise(); + }), + ); - const locationResponse = await s3 - .getBucketLocation({ + const locationResponse = await s3.send( + new GetBucketLocationCommand({ Bucket: bucketNameToImport, - }) - .promise(); + }), + ); // For us-east-1 buckets the LocationConstraint is always emtpy, we have to return a // region in every case. // https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLocation.html if ( locationResponse.LocationConstraint === undefined || - locationResponse.LocationConstraint === '' || + locationResponse.LocationConstraint.toString() === '' || locationResponse.LocationConstraint === null ) { bucketLocation = 'us-east-1'; @@ -65,14 +66,14 @@ describe('headless s3 import', () => { }); afterAll(async () => { - // Delete bucket - const s3 = new aws.S3(); + // Delete bucket- in SDK V3, buckets are very picky about the region their client is in + const s3 = new S3Client({ region: bucketLocation || 'us-east-1' }); - await s3 - .deleteBucket({ + await s3.send( + new DeleteBucketCommand({ Bucket: bucketNameToImport, - }) - .promise(); + }), + ); }); beforeEach(async () => { diff --git a/packages/amplify-e2e-tests/src/__tests__/layer-2.test.ts b/packages/amplify-e2e-tests/src/__tests__/layer-2.test.ts index a6007b19ebb..8ad289589b2 100644 --- a/packages/amplify-e2e-tests/src/__tests__/layer-2.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/layer-2.test.ts @@ -233,7 +233,7 @@ describe('amplify add lambda layer with changes', () => { const payload = '{}'; let response = await functionCloudInvoke(projRoot, { funcName: functionName, payload }); - expect(JSON.parse(JSON.parse(response.Payload.toString()).body)).toEqual(helloWorldUpperCaseOutput); + expect(JSON.parse(JSON.parse(response.Payload.transformToString()).body)).toEqual(helloWorldUpperCaseOutput); // 2. Step // - Update casing.js in layer @@ -266,7 +266,7 @@ describe('amplify add lambda layer with changes', () => { response = await functionCloudInvoke(projRoot, { funcName: functionName, payload }); - expect(JSON.parse(JSON.parse(response.Payload.toString()).body)).toEqual(helloWorldUpperCaseOutput); + expect(JSON.parse(JSON.parse(response.Payload.transformToString()).body)).toEqual(helloWorldUpperCaseOutput); // 3. Step // - Update function to use latest version of the layer @@ -296,7 +296,7 @@ describe('amplify add lambda layer with changes', () => { response = await functionCloudInvoke(projRoot, { funcName: functionName, payload }); - expect(JSON.parse(JSON.parse(response.Payload.toString()).body)).toEqual(helloWorldTitleCaseOutput); + expect(JSON.parse(JSON.parse(response.Payload.transformToString()).body)).toEqual(helloWorldTitleCaseOutput); }); /* diff --git a/packages/amplify-e2e-tests/src/__tests__/push.test.ts b/packages/amplify-e2e-tests/src/__tests__/push.test.ts index 5b6257ff2ab..d8196a0b105 100644 --- a/packages/amplify-e2e-tests/src/__tests__/push.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/push.test.ts @@ -9,7 +9,7 @@ import { initJSProjectWithProfile, amplifyPushAuth, } from '@aws-amplify/amplify-e2e-core'; -import * as AWS from 'aws-sdk'; +import { S3Client, DeleteObjectCommand } from '@aws-sdk/client-s3'; describe('amplify push ', () => { let pushProjRoot: string; @@ -33,13 +33,13 @@ describe('amplify push ', () => { const meta = amplifyMeta.providers.awscloudformation; const bucketName = meta.DeploymentBucketName; - const s3 = new AWS.S3(); - await s3 - .deleteObject({ + const s3 = new S3Client(); + await s3.send( + new DeleteObjectCommand({ Bucket: bucketName, Key: '#current-cloud-backend.zip', - }) - .promise(); + }), + ); await expect(amplifyPushAuth(pushProjRoot)).rejects.toThrow(); await amplifyPushForce(pushProjRoot); diff --git a/packages/amplify-e2e-tests/src/__tests__/schema-iterative-update-locking.test.ts b/packages/amplify-e2e-tests/src/__tests__/schema-iterative-update-locking.test.ts index bbfa4996da4..03cc5c166e0 100644 --- a/packages/amplify-e2e-tests/src/__tests__/schema-iterative-update-locking.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/schema-iterative-update-locking.test.ts @@ -14,7 +14,7 @@ import { getProjectMeta, sleep, } from '@aws-amplify/amplify-e2e-core'; -import S3 from 'aws-sdk/clients/s3'; +import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3'; import { DeploymentState, DeploymentStatus, JSONUtilities } from '@aws-amplify/amplify-cli-core'; describe('Schema iterative update - locking', () => { @@ -67,7 +67,7 @@ describe('Schema iterative update - locking', () => { const projectRegion = meta.providers.awscloudformation.Region; const deploymentBucketName = meta.providers.awscloudformation.DeploymentBucketName; - const s3 = new S3({ + const s3 = new S3Client({ region: projectRegion, }); @@ -79,14 +79,15 @@ describe('Schema iterative update - locking', () => { while (retry < maxRetries || !lockFileExists) { try { - const deploymentStateObject = await s3 - .getObject({ + const deploymentStateObject = await s3.send( + new GetObjectCommand({ Bucket: deploymentBucketName, Key: stateFileName, - }) - .promise(); + }), + ); - const deploymentState = JSONUtilities.parse(deploymentStateObject.Body.toString()); + const bodyString = await deploymentStateObject.Body?.transformToString(); + const deploymentState = JSONUtilities.parse(bodyString); if (deploymentState.status === DeploymentStatus.DEPLOYING) { lockFileExists = true; diff --git a/packages/amplify-e2e-tests/src/__tests__/storage-simulator/S3server.test.ts b/packages/amplify-e2e-tests/src/__tests__/storage-simulator/S3server.test.ts index 63e3305a61f..80e3e718d5d 100644 --- a/packages/amplify-e2e-tests/src/__tests__/storage-simulator/S3server.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/storage-simulator/S3server.test.ts @@ -1,5 +1,6 @@ import { AmplifyStorageSimulator } from 'amplify-storage-simulator'; -import * as AWS from 'aws-sdk'; +import { S3Client, ListObjectsV2Command, GetObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3'; +import { Upload } from '@aws-sdk/lib-storage'; import * as fs from 'fs-extra'; const port = 20005; // for testing @@ -17,16 +18,16 @@ let simulator; jest.setTimeout(2000000); beforeAll(async () => { - const ep = new AWS.Endpoint('http://localhost:20005'); - s3client = new AWS.S3({ - accessKeyId: fakeAccessId, - secretAccessKey: fakeSecretKey, + s3client = new S3Client({ + credentials: { + accessKeyId: fakeAccessId, + secretAccessKey: fakeSecretKey, + }, region: fakeRegion, apiVersion: '2006-03-01', - endpoint: ep.href, - s3BucketEndpoint: true, - sslEnabled: false, - s3ForcePathStyle: true, + endpoint: 'http://localhost:20005', + forcePathStyle: true, + tls: false, }); simulator = new AmplifyStorageSimulator({ port, route, localDirS3 }); @@ -57,59 +58,58 @@ describe('test server running', () => { describe('Test get api', () => { test('get image work ', async () => { - const data = await s3client.getObject({ Bucket: bucket, Key: '2.png' }).promise(); + const data = await s3client.send(new GetObjectCommand({ Bucket: bucket, Key: '2.png' })); expect(data).toBeDefined(); expect(data.Body).toBeDefined(); }); test('get text file', async () => { - const data = await s3client.getObject({ Bucket: bucket, Key: 'abc.txt' }).promise(); + const data = await s3client.send(new GetObjectCommand({ Bucket: bucket, Key: 'abc.txt' })); expect(data).toBeDefined(); expect(data.Body).toBeDefined(); - expect(data.Body.toString()).toEqual('Helloworld1234'); + const bodyString = await data.Body.transformToString(); + expect(bodyString).toEqual('Helloworld1234'); }); }); describe('Test list api', () => { test('get list', async () => { - const response = await s3client.listObjects({ Bucket: bucket, Prefix: 'normal' }).promise(); + const response = await s3client.send(new ListObjectsV2Command({ Bucket: bucket, Prefix: 'normal' })); expect(response).toBeDefined(); expect(response.Contents[0].Key).toEqual('normal/2.png'); expect(response.Contents.length).toEqual(1); }); test('get list', async () => { - const response = await s3client.listObjects({ Bucket: bucket }).promise(); + const response = await s3client.send(new ListObjectsV2Command({ Bucket: bucket, Prefix: '' })); expect(response).toBeDefined(); //expect(response.Contents.length).toEqual(1); }); test('empty bucket', async () => { - const response = await s3client.listObjects({ Bucket: bucket, Prefix: 'public' }).promise(); + const response = await s3client.send(new ListObjectsV2Command({ Bucket: bucket, Prefix: 'public' })); expect(response).toBeDefined(); - expect(response.Contents.length).toEqual(0); + expect(response.Contents).toBeUndefined(); }); test('list object pagination', async () => { const maxKeys = 2; let total = 7; - let response = await s3client - .listObjects({ + let response = await s3client.send( + new ListObjectsV2Command({ Bucket: bucket, Prefix: 'pagination', - Marker: '', MaxKeys: maxKeys, - }) - .promise(); + }), + ); while (response.IsTruncated === true) { expect(response).toBeDefined(); expect(response.Contents.length).toEqual(maxKeys); - response = await s3client - .listObjects({ + response = await s3client.send( + new ListObjectsV2Command({ Bucket: bucket, Prefix: 'pagination', - Marker: response.NextMarker, MaxKeys: maxKeys, - }) - .promise(); + }), + ); total = total - maxKeys; } expect(response.Contents.length).toEqual(total); @@ -123,7 +123,7 @@ describe('Test delete api', () => { fs.copySync(__dirname + '/test-data/normal/', dirPathOne + '/'); }); test('test one delete ', async () => { - await s3client.deleteObject({ Bucket: bucket, Key: 'deleteOne/2.png' }).promise(); + await s3client.send(new DeleteObjectCommand({ Bucket: bucket, Key: 'deleteOne/2.png' })); expect(fs.rmdirSync(dirPathOne)).toBeUndefined; }); }); @@ -138,7 +138,11 @@ describe('Test put api', () => { Prefix: 'upload', Body: buffer, }; - const data = await s3client.upload(params).promise(); + const upload = new Upload({ + client: s3client, + params, + }); + const data = await upload.done(); expect(data).toBeDefined(); }); @@ -181,7 +185,10 @@ describe('Test put api', () => { Key: 'upload/abc.txt', Body: buf1, }; - const data = await s3client.upload(params).promise(); + const data = await new Upload({ + client: s3client, + params, + }).done(); expect(data).toBeDefined(); }); @@ -192,7 +199,10 @@ describe('Test put api', () => { Body: JSON.stringify(Jsonobj), ContentType: 'application/json', }; - const data = await s3client.upload(params).promise(); + const data = await new Upload({ + client: s3client, + params, + }).done(); const jsonFile = __dirname + '/test-data/upload/abc.json'; const contents = fs.readFileSync(jsonFile); const obj = JSON.parse(contents.toString()); @@ -209,7 +219,10 @@ describe('Test put api', () => { Key: 'upload/long_image.jpg', Body: buf2, }; - const data = await s3client.upload(params).promise(); + const data = await new Upload({ + client: s3client, + params, + }).done(); expect(data.Key).toBe('upload/long_image.jpg'); }); @@ -219,21 +232,30 @@ describe('Test put api', () => { Key: 'upload/long_image1.jpg', Body: buf2, }; - const data = await s3client.upload(params1).promise(); + const data = await new Upload({ + client: s3client, + params: params1, + }).done(); const params2 = { Bucket: bucket, // pass your bucket name Key: 'upload/long_image2.jpg', Body: buf2, }; - const data2 = await s3client.upload(params2).promise(); + const data2 = await new Upload({ + client: s3client, + params: params2, + }).done(); const params3 = { Bucket: bucket, // pass your bucket name Key: 'upload/long_image3.jpg', Body: buf2, }; - const data3 = await s3client.upload(params3).promise(); + const data3 = await new Upload({ + client: s3client, + params: params3, + }).done(); expect(data.Key).toBe('upload/long_image1.jpg'); expect(data2.Key).toBe('upload/long_image2.jpg'); @@ -258,9 +280,9 @@ describe('Test put api', () => { }; const uploadPromises = []; - uploadPromises.push(s3client.upload(params1).promise()); - uploadPromises.push(s3client.upload(params2).promise()); - uploadPromises.push(s3client.upload(params3).promise()); + uploadPromises.push(new Upload({ client: s3client, params: params1 }).done()); + uploadPromises.push(new Upload({ client: s3client, params: params2 }).done()); + uploadPromises.push(new Upload({ client: s3client, params: params3 }).done()); const uploadResults = await Promise.all(uploadPromises); expect(uploadResults[0].Key).toBe('upload/long_image1.jpg'); diff --git a/packages/amplify-e2e-tests/src/__tests__/uibuilder.test.ts b/packages/amplify-e2e-tests/src/__tests__/uibuilder.test.ts index 21b477bd289..703e8665a88 100644 --- a/packages/amplify-e2e-tests/src/__tests__/uibuilder.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/uibuilder.test.ts @@ -14,7 +14,7 @@ import { amplifyStudioHeadlessPull, } from '@aws-amplify/amplify-e2e-core'; import { spawnSync, spawn } from 'child_process'; -import { AmplifyUIBuilder } from 'aws-sdk'; +import { AmplifyUIBuilderClient, CreateComponentCommand } from '@aws-sdk/client-amplifyuibuilder'; import fs from 'fs-extra'; import path from 'path'; import * as execa from 'execa'; @@ -51,23 +51,23 @@ describe('amplify pull with uibuilder', () => { appId = getAppId(projRoot); const meta = getBackendAmplifyMeta(projRoot); const region = meta.providers.awscloudformation.Region; - const amplifyUIBuilder = new AmplifyUIBuilder({ region }); + const amplifyUIBuilder = new AmplifyUIBuilderClient({ region }); - await amplifyUIBuilder - .createComponent({ + await amplifyUIBuilder.send( + new CreateComponentCommand({ appId, environmentName: envName, componentToCreate: myIconComponent, - }) - .promise(); + }), + ); - await amplifyUIBuilder - .createComponent({ + await amplifyUIBuilder.send( + new CreateComponentCommand({ appId, environmentName: envName, componentToCreate: formCheckoutComponent, - }) - .promise(); + }), + ); // needs to enable studio for resources to be pull down await enableAdminUI(appId, envName, region); diff --git a/packages/amplify-e2e-tests/src/aws-matchers/iamMatcher.ts b/packages/amplify-e2e-tests/src/aws-matchers/iamMatcher.ts index b06e6e6874f..164a639b1f6 100644 --- a/packages/amplify-e2e-tests/src/aws-matchers/iamMatcher.ts +++ b/packages/amplify-e2e-tests/src/aws-matchers/iamMatcher.ts @@ -1,11 +1,11 @@ -import { IAM } from 'aws-sdk'; +import { IAMClient, GetRoleCommand } from '@aws-sdk/client-iam'; export const toBeIAMRoleWithArn = async (roleName: string, arn?: string) => { - const iam = new IAM(); + const iam = new IAMClient(); let pass: boolean; let message: string; try { - const { Role: role } = await iam.getRole({ RoleName: roleName }).promise(); + const { Role: role } = await iam.send(new GetRoleCommand({ RoleName: roleName })); if (arn) { pass = role.Arn === arn ? true : false; if (pass) { @@ -33,13 +33,15 @@ export const toHaveValidPolicyConditionMatchingIdpId = async (roleName: string, let message = ''; try { - const iam = new IAM({ - accessKeyId: process.env.AWS_ACCESS_KEY_ID, - secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, - sessionToken: process.env.AWS_SESSION_TOKEN, + const iam = new IAMClient({ + credentials: { + accessKeyId: process.env.AWS_ACCESS_KEY_ID, + secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, + sessionToken: process.env.AWS_SESSION_TOKEN, + }, }); - const { Role: role } = await iam.getRole({ RoleName: roleName }).promise(); + const { Role: role } = await iam.send(new GetRoleCommand({ RoleName: roleName })); const assumeRolePolicyDocument = JSON.parse(decodeURIComponent(role.AssumeRolePolicyDocument)); pass = assumeRolePolicyDocument.Statement.some((statement) => { @@ -73,13 +75,15 @@ export const toHaveDenyAssumeRolePolicy = async (roleName: string) => { let message = ''; try { - const iam = new IAM({ - accessKeyId: process.env.AWS_ACCESS_KEY_ID, - secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, - sessionToken: process.env.AWS_SESSION_TOKEN, + const iam = new IAMClient({ + credentials: { + accessKeyId: process.env.AWS_ACCESS_KEY_ID, + secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, + sessionToken: process.env.AWS_SESSION_TOKEN, + }, }); - const { Role: role } = await iam.getRole({ RoleName: roleName }).promise(); + const { Role: role } = await iam.send(new GetRoleCommand({ RoleName: roleName })); const assumeRolePolicyDocument = JSON.parse(decodeURIComponent(role.AssumeRolePolicyDocument)); pass = assumeRolePolicyDocument?.Statement?.length === 1 && assumeRolePolicyDocument?.Statement?.[0]?.Effect === 'Deny'; diff --git a/packages/amplify-e2e-tests/src/aws-matchers/s3matcher.ts b/packages/amplify-e2e-tests/src/aws-matchers/s3matcher.ts index b007f43c47f..f5a9723b68a 100644 --- a/packages/amplify-e2e-tests/src/aws-matchers/s3matcher.ts +++ b/packages/amplify-e2e-tests/src/aws-matchers/s3matcher.ts @@ -1,10 +1,10 @@ -import { S3 } from 'aws-sdk'; +import { S3Client, HeadBucketCommand } from '@aws-sdk/client-s3'; export const toBeAS3Bucket = async (bucketName: string) => { - const s3 = new S3(); + const s3 = new S3Client(); let pass: boolean; try { - await s3.headBucket({ Bucket: bucketName }).promise(); + await s3.send(new HeadBucketCommand({ Bucket: bucketName })); pass = true; } catch (e) { pass = false; diff --git a/packages/amplify-e2e-tests/src/cleanup-codebuild-resources.ts b/packages/amplify-e2e-tests/src/cleanup-codebuild-resources.ts index 61c492499c4..22f18ae6de1 100644 --- a/packages/amplify-e2e-tests/src/cleanup-codebuild-resources.ts +++ b/packages/amplify-e2e-tests/src/cleanup-codebuild-resources.ts @@ -1,15 +1,55 @@ +import { AmplifyClient, ListAppsCommand, DeleteAppCommand, ListBackendEnvironmentsCommand } from '@aws-sdk/client-amplify'; +import { AppSyncClient, ListGraphqlApisCommand, DeleteGraphqlApiCommand } from '@aws-sdk/client-appsync'; import { - Amplify, - AppSync, - CloudFormation, - CodeBuild, - CognitoIdentityServiceProvider, - IAM, - Organizations, - Pinpoint, - S3, - STS, -} from 'aws-sdk'; + CloudFormationClient, + ListStacksCommand, + DeleteStackCommand, + DescribeStacksCommand, + ListStackResourcesCommand, + StackStatus, + Tag, + waitUntilStackDeleteComplete, +} from '@aws-sdk/client-cloudformation'; +import { + CognitoIdentityProviderClient, + ListUserPoolsCommand, + DeleteUserPoolCommand, + DescribeUserPoolCommand, + DeleteUserPoolDomainCommand, + UserPoolDescriptionType, +} from '@aws-sdk/client-cognito-identity-provider'; +import { + IAMClient, + ListRolesCommand, + DeleteRoleCommand, + ListRolePoliciesCommand, + DeleteRolePolicyCommand, + ListAttachedRolePoliciesCommand, + DetachRolePolicyCommand, + ListOpenIDConnectProvidersCommand, + DeleteOpenIDConnectProviderCommand, + Role, + AttachedPolicy, +} from '@aws-sdk/client-iam'; +import { OrganizationsClient, ListAccountsCommand } from '@aws-sdk/client-organizations'; +import { + PinpointClient, + GetAppsCommand, + DeleteAppCommand as DeletePinpointAppCommand, + ApplicationResponse, +} from '@aws-sdk/client-pinpoint'; +import { + S3Client, + ListBucketsCommand, + DeleteBucketCommand, + DeleteObjectsCommand, + GetBucketTaggingCommand, + ListObjectVersionsCommand, + Bucket, + GetBucketLocationCommand, + waitUntilBucketNotExists, +} from '@aws-sdk/client-s3'; +import { STSClient, GetCallerIdentityCommand, AssumeRoleCommand } from '@aws-sdk/client-sts'; import fs from 'fs-extra'; import _ from 'lodash'; import path from 'path'; @@ -54,7 +94,7 @@ type StackInfo = { resourcesFailedToDelete?: string[]; tags: Record; region: string; - cbInfo?: CodeBuild.Build; + buildId?: string; }; type AmplifyAppInfo = { @@ -66,7 +106,7 @@ type AmplifyAppInfo = { type S3BucketInfo = { name?: string; - cbInfo?: CodeBuild.Build; + buildId?: string; createTime?: Date; }; @@ -81,13 +121,13 @@ type PinpointAppInfo = { name?: string; arn: string; region: string; - cbInfo?: CodeBuild.Build; + buildId?: string; createTime: Date; }; type IamRoleInfo = { name: string; - cbInfo?: CodeBuild.Build; + buildId?: string; createTime: Date; }; @@ -95,13 +135,12 @@ type AppSyncApiInfo = { apiId?: string; name?: string; region: string; - cbInfo?: CodeBuild.Build; + buildId?: string; }; type ReportEntry = { jobId?: string; workflowId?: string; - cbInfo?: CodeBuild.Build; amplifyApps: AmplifyAppInfo[]; stacks: StackInfo[]; buckets: Record; @@ -113,13 +152,6 @@ type ReportEntry = { type JobFilterPredicate = (job: ReportEntry) => boolean; -type CIJobInfo = { - workflowId: string; - workflowName: string; - ciJobDetails: string; - buildStatus: string; -}; - type AWSAccountInfo = { accessKeyId: string; secretAccessKey: string; @@ -162,22 +194,22 @@ const isStale = (created: string | Date | undefined): boolean => { /** * We define a resource as viable for deletion if it matches TEST_REGEX in the name, and if it is > STALE_DURATION_MS old. */ -const testBucketStalenessFilter = (resource: S3.Bucket): boolean => { +const testBucketStalenessFilter = (resource: Bucket): boolean => { const isTestResource = !!resource?.Name?.match(BUCKET_TEST_REGEX); return isTestResource && isStale(resource.CreationDate); }; -const testRoleStalenessFilter = (resource: IAM.Role): boolean => { +const testRoleStalenessFilter = (resource: Role): boolean => { const isTestResource = !!resource?.RoleName?.match(IAM_TEST_REGEX); return isTestResource && isStale(resource.CreateDate); }; -const testUserPoolStalenessFilter = (resource: CognitoIdentityServiceProvider.UserPoolDescriptionType): boolean => { +const testUserPoolStalenessFilter = (resource: UserPoolDescriptionType): boolean => { const isTestResource = !!resource?.Name?.match(USER_POOL_TEST_REGEX); return isTestResource && isStale(resource.CreationDate); }; -const testAppSyncApiStalenessFilter = (resource: AppSync.GraphqlApi): boolean => { +const testAppSyncApiStalenessFilter = (resource: any): boolean => { const isTestResource = !!resource?.name?.match(APPSYNC_TEST_REGEX); const createTimeTagValue = resource?.tags?.['codebuild:create_time']; let isStaleResource = true; @@ -188,8 +220,8 @@ const testAppSyncApiStalenessFilter = (resource: AppSync.GraphqlApi): boolean => return isTestResource && isStaleResource; }; -const testPinpointAppStalenessFilter = (resource: Pinpoint.ApplicationResponse): boolean => { - const isTestResource = !!(resource.Name.match(PINPOINT_TEST_REGEX) && resource.CreationDate); +const testPinpointAppStalenessFilter = (resource: ApplicationResponse): boolean => { + const isTestResource = !!(resource.Name?.match(PINPOINT_TEST_REGEX) && resource.CreationDate); return isTestResource && isStale(resource.CreationDate); }; @@ -197,8 +229,8 @@ const testPinpointAppStalenessFilter = (resource: Pinpoint.ApplicationResponse): * Get all S3 buckets in the account, and filter down to the ones we consider stale. */ const getOrphanS3TestBuckets = async (account: AWSAccountInfo): Promise => { - const s3Client = new S3(getAWSConfig(account)); - const listBucketResponse = await s3Client.listBuckets().promise(); + const s3Client = new S3Client(getAWSConfig(account)); + const listBucketResponse = await s3Client.send(new ListBucketsCommand({})); const staleBuckets = listBucketResponse?.Buckets?.filter(testBucketStalenessFilter); return staleBuckets?.map((it) => ({ name: it.Name, createTime: it.CreationDate })) ?? []; }; @@ -207,38 +239,38 @@ const getOrphanS3TestBuckets = async (account: AWSAccountInfo): Promise => { - const iamClient = new IAM(getAWSConfig(account)); - const listRoleResponse = await iamClient.listRoles({ MaxItems: 1000 }).promise(); - const staleRoles = listRoleResponse.Roles.filter(testRoleStalenessFilter); - return staleRoles.map((it) => ({ name: it.RoleName, createTime: it.CreateDate })); + const iamClient = new IAMClient(getAWSConfig(account)); + const listRoleResponse = await iamClient.send(new ListRolesCommand({ MaxItems: 1000 })); + const staleRoles = listRoleResponse.Roles?.filter(testRoleStalenessFilter) ?? []; + return staleRoles.map((it) => ({ name: it.RoleName!, createTime: it.CreateDate! })); }; const getOrphanPinpointApplications = async (account: AWSAccountInfo, region: string): Promise => { - const pinpoint = new Pinpoint(getAWSConfig(account, region)); + const pinpoint = new PinpointClient(getAWSConfig(account, region)); const apps: PinpointAppInfo[] = []; let nextToken = undefined; do { - const result: Pinpoint.GetAppsResponse = await pinpoint.getApps({ Token: nextToken }).promise(); + const result = await pinpoint.send(new GetAppsCommand({ Token: nextToken })); apps.push( ...(result.ApplicationsResponse?.Item || []).filter(testPinpointAppStalenessFilter).map((it) => ({ - id: it.Id, + id: it.Id!, name: it.Name, - arn: it.Arn, + arn: it.Arn!, region, createTime: new Date(it?.CreationDate ?? 'Invalid Date'), })), ); - nextToken = result.ApplicationsResponse.NextToken; + nextToken = result.ApplicationsResponse?.NextToken; } while (nextToken); return apps; }; const getOrphanUserPools = async (account: AWSAccountInfo, region: string): Promise => { - const cognitoClient = new CognitoIdentityServiceProvider(getAWSConfig(account, region)); - const userPools = await cognitoClient.listUserPools({ MaxResults: 60 }).promise(); + const cognitoClient = new CognitoIdentityProviderClient(getAWSConfig(account, region)); + const userPools = await cognitoClient.send(new ListUserPoolsCommand({ MaxResults: 60 })); const staleUserPools = userPools?.UserPools?.filter(testUserPoolStalenessFilter); return staleUserPools?.map((it) => ({ name: it.Name, userPoolId: it.Id, region })) ?? []; }; @@ -247,8 +279,8 @@ const getOrphanUserPools = async (account: AWSAccountInfo, region: string): Prom * Get all AppSync Apis in the account, and filter down to the ones we consider stale. */ const getOrphanAppSyncApis = async (account: AWSAccountInfo, region: string): Promise => { - const appSyncClient = new AppSync(getAWSConfig(account, region)); - const listApisResponse = await appSyncClient.listGraphqlApis({ maxResults: 25 }).promise(); + const appSyncClient = new AppSyncClient(getAWSConfig(account, region)); + const listApisResponse = await appSyncClient.send(new ListGraphqlApisCommand({ maxResults: 25 })); const staleApis = listApisResponse?.graphqlApis?.filter(testAppSyncApiStalenessFilter); return staleApis?.map((it) => ({ apiId: it.apiId, name: it.name, region })) ?? []; }; @@ -257,14 +289,14 @@ const getOrphanAppSyncApis = async (account: AWSAccountInfo, region: string): Pr * Get all OIDC providers in the account that match */ const deleteOrphanedOidcProviders = async (account: AWSAccountInfo): Promise => { - const iamClient = new IAM(getAWSConfig(account)); - const response = await iamClient.listOpenIDConnectProviders().promise(); + const iamClient = new IAMClient(getAWSConfig(account)); + const response = await iamClient.send(new ListOpenIDConnectProvidersCommand({})); if (response.OpenIDConnectProviderList) { for (const provider of response.OpenIDConnectProviderList) { // these seem to be the only offending resources at this time, but we can add more later - if (provider.Arn.endsWith('oidc-provider/accounts.google.com')) { + if (provider.Arn?.endsWith('oidc-provider/accounts.google.com')) { console.log('OIDC PROVIDER:', provider.Arn); - await iamClient.deleteOpenIDConnectProvider({ OpenIDConnectProviderArn: provider.Arn }).promise(); + await iamClient.send(new DeleteOpenIDConnectProviderCommand({ OpenIDConnectProviderArn: provider.Arn })); } } } @@ -281,23 +313,28 @@ const getAWSConfig = ({ accessKeyId, secretAccessKey, sessionToken }: AWSAccount }, ...(region ? { region } : {}), maxRetries: 10, + requestHandler: { + connectionTimeout: 30000, + socketTimeout: 30000, + maxSockets: 100, + }, }); /** * delete an S3 bucket, copied from amplify-e2e-core */ -const deleteS3Bucket = async (bucket: string, providedS3Client: S3 | undefined = undefined) => { - const s3 = providedS3Client || new S3(); - let continuationToken: Pick | undefined = undefined; - const objectKeyAndVersion = []; +const deleteS3Bucket = async (bucket: string, providedS3Client: S3Client | undefined = undefined) => { + const s3 = providedS3Client || new S3Client({}); + let continuationToken: string | undefined = undefined; + const objectKeyAndVersion: { Key: string; VersionId?: string }[] = []; let truncated = true; while (truncated) { - const results: S3.ListObjectVersionsOutput = await s3 - .listObjectVersions({ + const results = await s3.send( + new ListObjectVersionsCommand({ Bucket: bucket, - ...(continuationToken ? continuationToken : {}), - }) - .promise(); + ...(continuationToken ? { KeyMarker: continuationToken } : {}), + }), + ); results.Versions?.forEach(({ Key, VersionId }) => { if (Key) { @@ -311,25 +348,25 @@ const deleteS3Bucket = async (bucket: string, providedS3Client: S3 | undefined = } }); - continuationToken = { KeyMarker: results.NextKeyMarker, VersionIdMarker: results.NextVersionIdMarker }; + continuationToken = results.NextKeyMarker; truncated = !!results.IsTruncated; } const chunkedResult = _.chunk(objectKeyAndVersion, 1000); const deleteReq = chunkedResult - .map((r: S3.ObjectIdentifier[]) => ({ + .map((r) => ({ Bucket: bucket, Delete: { Objects: r, Quiet: true, }, })) - .map((delParams: S3.DeleteObjectsRequest) => s3.deleteObjects(delParams).promise()); + .map((delParams) => s3.send(new DeleteObjectsCommand(delParams))); await Promise.all(deleteReq); - await s3 - .deleteBucket({ + await s3.send( + new DeleteBucketCommand({ Bucket: bucket, - }) - .promise(); + }), + ); await bucketNotExists(bucket); }; @@ -337,16 +374,12 @@ const deleteS3Bucket = async (bucket: string, providedS3Client: S3 | undefined = * Copied from amplify-e2e-core */ const bucketNotExists = async (bucket: string) => { - const s3 = new S3(); - const params = { - Bucket: bucket, - $waiter: { maxAttempts: 10, delay: 30 }, - }; + const s3 = new S3Client({}); try { - await s3.waitFor('bucketNotExists', params).promise(); + await waitUntilBucketNotExists({ client: s3, maxWaitTime: 300 }, { Bucket: bucket }); return true; } catch (error) { - if (error.statusCode === 200) { + if (error.$metadata.httpStatusCode === 200) { return false; } throw error; @@ -365,13 +398,13 @@ const sleep = async (milliseconds: number): Promise => new Promise((resolv * @param region aws region to query for amplify Apps * @returns Promise a list of Amplify Apps in the region with build info */ -const getAmplifyApps = async (account: AWSAccountInfo, region: string, cbClient: CodeBuild): Promise => { +const getAmplifyApps = async (account: AWSAccountInfo, region: string): Promise => { if (region === 'us-east-1' && account.parent) { return []; // temporarily disabled until us-east-1 is re-enabled for this account } - const amplifyClient = new Amplify(getAWSConfig(account, region)); + const amplifyClient = new AmplifyClient(getAWSConfig(account, region)); try { - const amplifyApps = await amplifyClient.listApps({ maxResults: 25 }).promise(); // keeping it to 25 as max supported is 25 + const amplifyApps = await amplifyClient.send(new ListAppsCommand({ maxResults: 25 })); // keeping it to 25 as max supported is 25 const result: AmplifyAppInfo[] = []; for (const app of amplifyApps.apps) { if (!isStale(app.createTime)) { @@ -379,12 +412,12 @@ const getAmplifyApps = async (account: AWSAccountInfo, region: string, cbClient: } const backends: Record = {}; try { - const backendEnvironments = await amplifyClient.listBackendEnvironments({ appId: app.appId, maxResults: 5 }).promise(); + const backendEnvironments = await amplifyClient.send(new ListBackendEnvironmentsCommand({ appId: app.appId, maxResults: 5 })); for (const backendEnv of backendEnvironments.backendEnvironments) { if (backendEnv.stackName) { - const buildInfo = await getStackDetails(backendEnv.stackName, account, region, cbClient); + const buildInfo = await getStackDetails(backendEnv.stackName, account, region); if (buildInfo) { - backends[backendEnv.environmentName] = buildInfo; + backends[backendEnv.environmentName!] = buildInfo; } } } @@ -392,8 +425,8 @@ const getAmplifyApps = async (account: AWSAccountInfo, region: string, cbClient: // console.log(e); } result.push({ - appId: app.appId, - name: app.name, + appId: app.appId!, + name: app.name!, region, backends, }); @@ -410,7 +443,7 @@ const getAmplifyApps = async (account: AWSAccountInfo, region: string, cbClient: * @param tags Tags associated with the resource * @returns build number or undefined */ -const getJobId = (tags: CloudFormation.Tags = []): string | undefined => { +const getJobId = (tags: Tag[] = []): string | undefined => { const jobId = tags.find((tag) => tag.Key === 'codebuild:build_id')?.Value; return jobId; }; @@ -425,17 +458,17 @@ const getJobId = (tags: CloudFormation.Tags = []): string | undefined => { * @param region region * @returns stack details */ -const getStackDetails = async (stackName: string, account: AWSAccountInfo, region: string, cbClient: CodeBuild): Promise => { - const cfnClient = new CloudFormation(getAWSConfig(account, region)); - const stack = await cfnClient.describeStacks({ StackName: stackName }).promise(); +const getStackDetails = async (stackName: string, account: AWSAccountInfo, region: string): Promise => { + const cfnClient = new CloudFormationClient(getAWSConfig(account, region)); + const stack = await cfnClient.send(new DescribeStacksCommand({ StackName: stackName })); const tags = stack?.Stacks?.[0].Tags ?? []; const stackStatus = stack?.Stacks?.[0]?.StackStatus ?? 'UNDEFINED'; let resourcesFailedToDelete: string[] = []; if (stackStatus === 'DELETE_FAILED') { // Todo: We need to investigate if we should go ahead and remove the resources to prevent account getting cluttered - const resources = await cfnClient.listStackResources({ StackName: stackName }).promise(); + const resources = await cfnClient.send(new ListStackResourcesCommand({ StackName: stackName })); resourcesFailedToDelete = - resources?.StackResourceSummaries?.filter((r) => r.ResourceStatus === 'DELETE_FAILED').map((r) => r.LogicalResourceId) ?? []; + resources?.StackResourceSummaries?.filter((r) => r.ResourceStatus === 'DELETE_FAILED').map((r) => r.LogicalResourceId!) ?? []; } const jobId = getJobId(tags); return { @@ -443,39 +476,39 @@ const getStackDetails = async (stackName: string, account: AWSAccountInfo, regio stackStatus, resourcesFailedToDelete, region, - tags: tags.reduce((acc, tag) => ({ ...acc, [tag.Key]: tag.Value }), {}), - cbInfo: jobId ? await getCIJobDetails(jobId, cbClient) : undefined, + tags: tags.reduce((acc, tag) => ({ ...acc, [tag.Key!]: tag.Value }), {}), + buildId: jobId, }; }; -const getStacks = async (account: AWSAccountInfo, region: string, cbClient: CodeBuild): Promise => { - const cfnClient = new CloudFormation(getAWSConfig(account, region)); +const getStacks = async (account: AWSAccountInfo, region: string): Promise => { + const cfnClient = new CloudFormationClient(getAWSConfig(account, region)); const stackStatusFilter = [ - 'CREATE_COMPLETE', - 'ROLLBACK_FAILED', - 'ROLLBACK_COMPLETE', - 'DELETE_FAILED', - 'UPDATE_COMPLETE', - 'UPDATE_ROLLBACK_FAILED', - 'UPDATE_ROLLBACK_COMPLETE', - 'IMPORT_COMPLETE', - 'IMPORT_ROLLBACK_FAILED', - 'IMPORT_ROLLBACK_COMPLETE', + StackStatus.CREATE_COMPLETE, + StackStatus.ROLLBACK_FAILED, + StackStatus.ROLLBACK_COMPLETE, + StackStatus.DELETE_FAILED, + StackStatus.UPDATE_COMPLETE, + StackStatus.UPDATE_ROLLBACK_FAILED, + StackStatus.UPDATE_ROLLBACK_COMPLETE, + StackStatus.IMPORT_COMPLETE, + StackStatus.IMPORT_ROLLBACK_FAILED, + StackStatus.IMPORT_ROLLBACK_COMPLETE, ]; - const stacks = await cfnClient - .listStacks({ + const stacks = await cfnClient.send( + new ListStacksCommand({ StackStatusFilter: stackStatusFilter, - }) - .promise(); + }), + ); // loop let nextToken = stacks.NextToken; while (nextToken && stacks?.StackSummaries?.length && stacks.StackSummaries.length < DELETE_LIMITS.PER_REGION.CFN_STACK) { - const nextPage = await cfnClient - .listStacks({ + const nextPage = await cfnClient.send( + new ListStacksCommand({ StackStatusFilter: stackStatusFilter, NextToken: nextToken, - }) - .promise(); + }), + ); if (nextPage?.StackSummaries?.length) { stacks.StackSummaries.push(...nextPage.StackSummaries); nextToken = nextPage.NextToken; @@ -505,7 +538,7 @@ const getStacks = async (account: AWSAccountInfo, region: string, cbClient: Code const results: StackInfo[] = []; for (const stack of rootStacks) { try { - const details = await getStackDetails(stack.StackName, account, region, cbClient); + const details = await getStackDetails(stack.StackName!, account, region); if (details) { results.push(details); } @@ -516,16 +549,9 @@ const getStacks = async (account: AWSAccountInfo, region: string, cbClient: Code return results; }; -const getCIJobDetails = async (build_id: string, cbClient: CodeBuild): Promise => { - const batchBuilds = await cbClient.batchGetBuilds({ ids: [build_id] }).promise(); - const buildInfo = batchBuilds?.builds?.[0]; - - return buildInfo; -}; - -const getS3Buckets = async (account: AWSAccountInfo, cbClient: CodeBuild): Promise => { - const s3Client = new S3(getAWSConfig(account)); - const buckets = await s3Client.listBuckets().promise(); +const getS3Buckets = async (account: AWSAccountInfo): Promise => { + const s3Client = new S3Client(getAWSConfig(account)); + const buckets = await s3Client.send(new ListBucketsCommand({})); if (buckets.Buckets === undefined) { return []; } @@ -535,17 +561,20 @@ const getS3Buckets = async (account: AWSAccountInfo, cbClient: CodeBuild): Promi continue; } try { - const bucketDetails = await s3Client.getBucketTagging({ Bucket: bucket.Name }).promise(); + const locationResponse = await s3Client.send(new GetBucketLocationCommand({ Bucket: bucket.Name })); + const bucketRegion = locationResponse.LocationConstraint || 'us-east-1'; + const bucketS3Client = new S3Client(getAWSConfig(account, bucketRegion)); + const bucketDetails = await bucketS3Client.send(new GetBucketTaggingCommand({ Bucket: bucket.Name })); const jobId = getJobId(bucketDetails.TagSet); if (jobId) { result.push({ name: bucket.Name, - cbInfo: await getCIJobDetails(jobId, cbClient), + buildId: jobId, createTime: bucket.CreationDate, }); } } catch (e) { - if (e.code !== 'NoSuchTagSet' && e.code !== 'NoSuchBucket') { + if (e.name !== 'NoSuchTagSet' && e.name !== 'NoSuchBucket') { throw e; } result.push({ @@ -557,16 +586,6 @@ const getS3Buckets = async (account: AWSAccountInfo, cbClient: CodeBuild): Promi return result; }; -/** - * extract and moves CI job details - */ -const extractCIJobInfo = (record: S3BucketInfo | StackInfo | AmplifyAppInfo): CIJobInfo => ({ - workflowId: _.get(record, ['0', 'cbInfo', 'workflows', 'workflow_id']), - workflowName: _.get(record, ['0', 'cbInfo', 'workflows', 'workflow_name']), - buildStatus: _.get(record, ['0', 'cbInfo', 'buildStatus']), - ciJobDetails: _.get(record, ['0', 'cbInfo']), -}); - /** * Merges stale resources and returns a list grouped by the CI jobId. Amplify Apps that don't have * any backend environment are grouped as Orphan apps and apps that have Backend created by different CI jobs are @@ -584,16 +603,16 @@ const mergeResourcesByCIJob = ( ): Record => { const result: Record = {}; - const stacksByJobId = _.groupBy(cfnStacks, (stack: StackInfo) => _.get(stack, ['cbInfo', 'id'], UNKNOWN)); + const stacksByJobId = _.groupBy(cfnStacks, (stack: StackInfo) => stack.buildId || UNKNOWN); - const bucketByJobId = _.groupBy(s3Buckets, (bucketInfo: S3BucketInfo) => _.get(bucketInfo, ['cbInfo', 'id'], UNKNOWN)); + const bucketByJobId = _.groupBy(s3Buckets, (bucketInfo: S3BucketInfo) => bucketInfo.buildId || UNKNOWN); const amplifyAppByJobId = _.groupBy(amplifyApp, (appInfo: AmplifyAppInfo) => { if (Object.keys(appInfo.backends).length === 0) { return ORPHAN; } - const buildIds = _.groupBy(appInfo.backends, (backendInfo: StackInfo) => _.get(backendInfo, ['cbInfo', 'id'], UNKNOWN)); + const buildIds = _.groupBy(appInfo.backends, (backendInfo: StackInfo) => backendInfo.buildId || UNKNOWN); if (Object.keys(buildIds).length === 1) { return Object.keys(buildIds)[0]; } @@ -606,7 +625,6 @@ const mergeResourcesByCIJob = ( _.pickBy(amplifyAppByJobId, (__: unknown, key: string) => key !== MULTI_JOB_APP), (val: any, src: AmplifyAppInfo, key: string) => ({ ...val, - ...extractCIJobInfo(src), jobId: key, amplifyApps: src, }), @@ -618,7 +636,6 @@ const mergeResourcesByCIJob = ( (__: unknown, key: string) => key !== ORPHAN, (val: any, src: StackInfo, key: string) => ({ ...val, - ...extractCIJobInfo(src), jobId: key, stacks: src, }), @@ -626,7 +643,6 @@ const mergeResourcesByCIJob = ( _.mergeWith(result, bucketByJobId, (val: any, src: S3BucketInfo, key: string) => ({ ...val, - ...extractCIJobInfo(src), jobId: key, buckets: src, })); @@ -695,12 +711,12 @@ const deleteAmplifyApps = async (account: AWSAccountInfo, accountIndex: number, const deleteAmplifyApp = async (account: AWSAccountInfo, accountIndex: number, app: AmplifyAppInfo): Promise => { const { name, appId, region } = app; console.log(`[ACCOUNT ${accountIndex}] Deleting App ${name}(${appId})`); - const amplifyClient = new Amplify(getAWSConfig(account, region)); + const amplifyClient = new AmplifyClient(getAWSConfig(account, region)); try { - await amplifyClient.deleteApp({ appId }).promise(); + await amplifyClient.send(new DeleteAppCommand({ appId })); } catch (e) { console.log(`[ACCOUNT ${accountIndex}] Deleting Amplify App ${appId} failed with the following error`, e); - if (e.code === 'ExpiredTokenException') { + if (e.name === 'ExpiredTokenException') { handleExpiredTokenException(); } } @@ -715,21 +731,21 @@ const deleteIamRole = async (account: AWSAccountInfo, accountIndex: number, role try { console.log(`[ACCOUNT ${accountIndex}] Deleting Iam Role ${roleName}`); console.log(`Role creation time (PST): ${role.createTime.toLocaleTimeString('en-US', { timeZone: 'America/Los_Angeles' })}`); - const iamClient = new IAM(getAWSConfig(account)); + const iamClient = new IAMClient(getAWSConfig(account)); await deleteAttachedRolePolicies(account, accountIndex, roleName); await deleteRolePolicies(account, accountIndex, roleName); - await iamClient.deleteRole({ RoleName: roleName }).promise(); + await iamClient.send(new DeleteRoleCommand({ RoleName: roleName })); } catch (e) { console.log(`[ACCOUNT ${accountIndex}] Deleting iam role ${roleName} failed with error ${e.message}`); - if (e.code === 'ExpiredTokenException') { + if (e.name === 'ExpiredTokenException') { handleExpiredTokenException(); } } }; const deleteAttachedRolePolicies = async (account: AWSAccountInfo, accountIndex: number, roleName: string): Promise => { - const iamClient = new IAM(getAWSConfig(account)); - const rolePolicies = await iamClient.listAttachedRolePolicies({ RoleName: roleName }).promise(); + const iamClient = new IAMClient(getAWSConfig(account)); + const rolePolicies = await iamClient.send(new ListAttachedRolePoliciesCommand({ RoleName: roleName })); if (rolePolicies?.AttachedPolicies) { await Promise.all(rolePolicies.AttachedPolicies.map((policy) => detachIamAttachedRolePolicy(account, accountIndex, roleName, policy))); } @@ -739,16 +755,16 @@ const detachIamAttachedRolePolicy = async ( account: AWSAccountInfo, accountIndex: number, roleName: string, - policy: IAM.AttachedPolicy, + policy: AttachedPolicy, ): Promise => { if (policy?.PolicyArn) { try { console.log(`[ACCOUNT ${accountIndex}] Detach Iam Attached Role Policy ${policy.PolicyName}`); - const iamClient = new IAM(getAWSConfig(account)); - await iamClient.detachRolePolicy({ RoleName: roleName, PolicyArn: policy.PolicyArn }).promise(); + const iamClient = new IAMClient(getAWSConfig(account)); + await iamClient.send(new DetachRolePolicyCommand({ RoleName: roleName, PolicyArn: policy.PolicyArn })); } catch (e) { console.log(`[ACCOUNT ${accountIndex}] Detach iam role policy ${policy.PolicyName} failed with error ${e.message}`); - if (e.code === 'ExpiredTokenException') { + if (e.name === 'ExpiredTokenException') { handleExpiredTokenException(); } } @@ -756,19 +772,19 @@ const detachIamAttachedRolePolicy = async ( }; const deleteRolePolicies = async (account: AWSAccountInfo, accountIndex: number, roleName: string): Promise => { - const iamClient = new IAM(getAWSConfig(account)); - const rolePolicies = await iamClient.listRolePolicies({ RoleName: roleName }).promise(); + const iamClient = new IAMClient(getAWSConfig(account)); + const rolePolicies = await iamClient.send(new ListRolePoliciesCommand({ RoleName: roleName })); await Promise.all(rolePolicies.PolicyNames.map((policy) => deleteIamRolePolicy(account, accountIndex, roleName, policy))); }; const deleteIamRolePolicy = async (account: AWSAccountInfo, accountIndex: number, roleName: string, policyName: string): Promise => { try { console.log(`[ACCOUNT ${accountIndex}] Deleting Iam Role Policy ${policyName}`); - const iamClient = new IAM(getAWSConfig(account)); - await iamClient.deleteRolePolicy({ RoleName: roleName, PolicyName: policyName }).promise(); + const iamClient = new IAMClient(getAWSConfig(account)); + await iamClient.send(new DeleteRolePolicyCommand({ RoleName: roleName, PolicyName: policyName })); } catch (e) { console.log(`[ACCOUNT ${accountIndex}] Deleting iam role policy ${policyName} failed with error ${e.message}`); - if (e.code === 'ExpiredTokenException') { + if (e.name === 'ExpiredTokenException') { handleExpiredTokenException(); } } @@ -784,11 +800,14 @@ const deleteBucket = async (account: AWSAccountInfo, accountIndex: number, bucke try { console.log(`[ACCOUNT ${accountIndex}] Deleting S3 Bucket ${name}`); console.log(`Bucket creation time (PST): ${createTime?.toLocaleTimeString('en-US', { timeZone: 'America/Los_Angeles' })}`); - const s3 = new S3(getAWSConfig(account)); - await deleteS3Bucket(name, s3); + const s3 = new S3Client(getAWSConfig(account)); + const locationResponse = await s3.send(new GetBucketLocationCommand({ Bucket: name })); + const bucketRegion = locationResponse.LocationConstraint || 'us-east-1'; + const regionalS3Client = new S3Client(getAWSConfig(account, bucketRegion)); + await deleteS3Bucket(name, regionalS3Client); } catch (e) { console.log(`[ACCOUNT ${accountIndex}] Deleting bucket ${name} failed with error ${e.message}`); - if (e.code === 'ExpiredTokenException') { + if (e.name === 'ExpiredTokenException') { handleExpiredTokenException(); } } @@ -804,8 +823,8 @@ const deletePinpointApp = async (account: AWSAccountInfo, accountIndex: number, try { console.log(`[ACCOUNT ${accountIndex}] Deleting Pinpoint App ${name}`); console.log(`Pinpoint creation time (PST): ${app.createTime.toLocaleTimeString('en-US', { timeZone: 'America/Los_Angeles' })}`); - const pinpoint = new Pinpoint(getAWSConfig(account, region)); - await pinpoint.deleteApp({ ApplicationId: id }).promise(); + const pinpoint = new PinpointClient(getAWSConfig(account, region)); + await pinpoint.send(new DeletePinpointAppCommand({ ApplicationId: id })); } catch (e) { console.log(`[ACCOUNT ${accountIndex}] Deleting pinpoint app ${name} failed with error ${e.message}`); } @@ -820,8 +839,8 @@ const deleteAppSyncApi = async (account: AWSAccountInfo, accountIndex: number, a if (apiId) { try { console.log(`[ACCOUNT ${accountIndex}] Deleting AppSync Api ${name}`); - const appSync = new AppSync(getAWSConfig(account, region)); - await appSync.deleteGraphqlApi({ apiId }).promise(); + const appSync = new AppSyncClient(getAWSConfig(account, region)); + await appSync.send(new DeleteGraphqlApiCommand({ apiId })); } catch (e) { console.log(`[ACCOUNT ${accountIndex}] Deleting AppSync Api ${name} failed with error ${e.message}`); } @@ -839,17 +858,17 @@ const deleteUserPool = async (account: AWSAccountInfo, accountIndex: number, use } try { console.log(`[ACCOUNT ${accountIndex}] Deleting UserPool ${name}`); - const cognitoClient = new CognitoIdentityServiceProvider(getAWSConfig(account, region)); - const userPoolDetails = await cognitoClient.describeUserPool({ UserPoolId: userPoolId }).promise(); + const cognitoClient = new CognitoIdentityProviderClient(getAWSConfig(account, region)); + const userPoolDetails = await cognitoClient.send(new DescribeUserPoolCommand({ UserPoolId: userPoolId })); if (userPoolDetails?.UserPool?.Domain) { - await cognitoClient - .deleteUserPoolDomain({ + await cognitoClient.send( + new DeleteUserPoolDomainCommand({ UserPoolId: userPoolId, Domain: userPoolDetails.UserPool.Domain, - }) - .promise(); + }), + ); } - await cognitoClient.deleteUserPool({ UserPoolId: userPoolId }).promise(); + await cognitoClient.send(new DeleteUserPoolCommand({ UserPoolId: userPoolId })); } catch (e) { console.log(`[ACCOUNT ${accountIndex}] Deleting UserPool ${name} failed with error ${e.message}`); } @@ -864,13 +883,13 @@ const deleteCfnStack = async (account: AWSAccountInfo, accountIndex: number, sta const resourceToRetain = resourcesFailedToDelete?.length ? resourcesFailedToDelete : undefined; console.log(`[ACCOUNT ${accountIndex}] Deleting CloudFormation stack ${stackName}`); try { - const cfnClient = new CloudFormation(getAWSConfig(account, region)); - await cfnClient.deleteStack({ StackName: stackName, RetainResources: resourceToRetain }).promise(); + const cfnClient = new CloudFormationClient(getAWSConfig(account, region)); + await cfnClient.send(new DeleteStackCommand({ StackName: stackName, RetainResources: resourceToRetain })); // we'll only wait up to a minute before moving on - await cfnClient.waitFor('stackDeleteComplete', { StackName: stackName, $waiter: { maxAttempts: 2 } }).promise(); + await waitUntilStackDeleteComplete({ client: cfnClient, maxWaitTime: 120 }, { StackName: stackName }); } catch (e) { console.log(`Deleting CloudFormation stack ${stackName} failed with error ${e.message}`); - if (e.code === 'ExpiredTokenException') { + if (e.name === 'ExpiredTokenException') { handleExpiredTokenException(); } } @@ -938,24 +957,26 @@ const deleteResources = async ( * to get all accounts within the root account organization. */ const getAccountsToCleanup = async (): Promise => { - const stsRes = new STS({ + const stsRes = new STSClient({ apiVersion: '2011-06-15', - accessKeyId: process.env.AWS_ACCESS_KEY_ID, - secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, - sessionToken: process.env.AWS_SESSION_TOKEN, + credentials: { + accessKeyId: process.env.AWS_ACCESS_KEY_ID!, + secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!, + sessionToken: process.env.AWS_SESSION_TOKEN!, + }, }); - const parentAccountIdentity = await stsRes.getCallerIdentity().promise(); - const orgApi = new Organizations({ + const parentAccountIdentity = await stsRes.send(new GetCallerIdentityCommand({})); + const orgApi = new OrganizationsClient({ apiVersion: '2016-11-28', // the region where the organization exists region: 'us-east-1', }); try { - const orgAccounts = await orgApi.listAccounts().promise(); + const orgAccounts = await orgApi.send(new ListAccountsCommand({})); const allAccounts = orgAccounts.Accounts ?? []; let nextToken = orgAccounts.NextToken; while (nextToken) { - const nextPage = await orgApi.listAccounts({ NextToken: nextToken }).promise(); + const nextPage = await orgApi.send(new ListAccountsCommand({ NextToken: nextToken })); if (!nextPage?.Accounts?.length) { break; } @@ -967,14 +988,14 @@ const getAccountsToCleanup = async (): Promise => { return getEnvVarCredentials(); } const randomNumber = Math.floor(Math.random() * 100000); - const assumeRoleRes = await stsRes - .assumeRole({ + const assumeRoleRes = await stsRes.send( + new AssumeRoleCommand({ RoleArn: `arn:aws:iam::${account.Id}:role/OrganizationAccountAccessRole`, RoleSessionName: `testSession${randomNumber}`, // One hour DurationSeconds: 1 * 60 * 60, - }) - .promise(); + }), + ); const accessKeyId = assumeRoleRes?.Credentials?.AccessKeyId ?? ''; const secretAccessKey = assumeRoleRes?.Credentials?.SecretAccessKey ?? ''; @@ -1012,10 +1033,9 @@ const getEnvVarCredentials = (): AWSAccountInfo => { }; const cleanupAccount = async (account: AWSAccountInfo, accountIndex: number, filterPredicate: JobFilterPredicate): Promise => { - const cbClient = new CodeBuild(getAWSConfig(account)); - const appPromises = AWS_REGIONS_TO_RUN_TESTS.map((region) => getAmplifyApps(account, region, cbClient)); - const stackPromises = AWS_REGIONS_TO_RUN_TESTS.map((region) => getStacks(account, region, cbClient)); - const bucketPromise = getS3Buckets(account, cbClient); + const appPromises = AWS_REGIONS_TO_RUN_TESTS.map((region) => getAmplifyApps(account, region)); + const stackPromises = AWS_REGIONS_TO_RUN_TESTS.map((region) => getStacks(account, region)); + const bucketPromise = getS3Buckets(account); const orphanPinpointApplicationsPromise = AWS_REGIONS_TO_RUN_TESTS_PINPOINT.map((region) => getOrphanPinpointApplications(account, region), ); @@ -1043,6 +1063,7 @@ const cleanupAccount = async (account: AWSAccountInfo, accountIndex: number, fil orphanAppSyncApis, orphanUserPools, ); + // cleanup resources that are but that are definitely amplify resources // this includes apps with names that include "test" or stacks that include both "amplify" & "test" const testApps = allResources['']?.amplifyApps?.filter((a) => a.name.toLocaleLowerCase().includes('test')); @@ -1065,13 +1086,14 @@ const cleanupAccount = async (account: AWSAccountInfo, accountIndex: number, fil /** * Execute the cleanup script. * Cleanup will happen in parallel across all accounts within a given organization, - * based on the requested filter parameters (i.e. for a given workflow, job, or all stale resources). + * based on the requested filter parameters (i.e. for a given workflow, or all stale resources). * Logs are emitted for given account ids anywhere we've fanned out, but we use an indexing scheme instead * of account ids since the logs these are written to will be effectively public. */ const cleanup = async (): Promise => { - const filterPredicateStaleResources = (job: ReportEntry) => job?.cbInfo?.buildStatus === 'finished' || job.jobId === ORPHAN; + const filterPredicateStaleResources = (job: ReportEntry) => job.jobId === ORPHAN || job.jobId !== UNKNOWN; const accounts = await getAccountsToCleanup(); + for (let i = 0; i < 3; ++i) { console.log('CLEANUP ROUND: ', i + 1); await Promise.all( @@ -1081,6 +1103,7 @@ const cleanup = async (): Promise => { ); await sleep(60 * 1000); // run again after 60 seconds } + console.log('Done cleaning all accounts!'); }; diff --git a/packages/amplify-e2e-tests/src/cleanup-e2e-resources.ts b/packages/amplify-e2e-tests/src/cleanup-e2e-resources.ts index 83da29fa3b5..68d6eba3445 100644 --- a/packages/amplify-e2e-tests/src/cleanup-e2e-resources.ts +++ b/packages/amplify-e2e-tests/src/cleanup-e2e-resources.ts @@ -2,7 +2,48 @@ /* eslint-disable spellcheck/spell-checker */ import { config } from 'dotenv'; import yargs from 'yargs'; -import * as aws from 'aws-sdk'; +import { S3Client, ListBucketsCommand, GetBucketTaggingCommand, GetBucketLocationCommand, Bucket } from '@aws-sdk/client-s3'; +import { + IAMClient, + ListRolesCommand, + ListOpenIDConnectProvidersCommand, + DeleteOpenIDConnectProviderCommand, + DeleteRoleCommand, + ListAttachedRolePoliciesCommand, + DetachRolePolicyCommand, + ListRolePoliciesCommand, + DeleteRolePolicyCommand, + Role, + AttachedPolicy, +} from '@aws-sdk/client-iam'; +import { PinpointClient, GetAppsCommand, DeleteAppCommand, ApplicationResponse } from '@aws-sdk/client-pinpoint'; +import { + CognitoIdentityProviderClient, + ListUserPoolsCommand, + DescribeUserPoolCommand, + DeleteUserPoolDomainCommand, + DeleteUserPoolCommand, + UserPoolDescriptionType, +} from '@aws-sdk/client-cognito-identity-provider'; +import { AppSyncClient, ListGraphqlApisCommand, DeleteGraphqlApiCommand } from '@aws-sdk/client-appsync'; +import { + AmplifyClient, + ListAppsCommand, + ListBackendEnvironmentsCommand, + DeleteAppCommand as AmplifyDeleteAppCommand, +} from '@aws-sdk/client-amplify'; +import { + CloudFormationClient, + DescribeStacksCommand, + ListStackResourcesCommand, + ListStacksCommand, + DeleteStackCommand, + waitUntilStackDeleteComplete, + StackStatus, + Tag, +} from '@aws-sdk/client-cloudformation'; +import { STSClient, GetCallerIdentityCommand, AssumeRoleCommand } from '@aws-sdk/client-sts'; +import { OrganizationsClient, ListAccountsCommand } from '@aws-sdk/client-organizations'; import _ from 'lodash'; import fs from 'fs-extra'; import path from 'path'; @@ -147,22 +188,22 @@ const isStale = (created: Date): boolean => { /** * We define a resource as viable for deletion if it matches TEST_REGEX in the name, and if it is > STALE_DURATION_MS old. */ -const testBucketStalenessFilter = (resource: aws.S3.Bucket): boolean => { +const testBucketStalenessFilter = (resource: Bucket): boolean => { const isTestResource = resource.Name.match(BUCKET_TEST_REGEX); return isTestResource && isStale(resource.CreationDate); }; -const testRoleStalenessFilter = (resource: aws.IAM.Role): boolean => { +const testRoleStalenessFilter = (resource: Role): boolean => { const isTestResource = resource.RoleName.match(IAM_TEST_REGEX); return isTestResource && isStale(resource.CreateDate); }; -const testUserPoolStalenessFilter = (resource: aws.CognitoIdentityServiceProvider.UserPoolDescriptionType): boolean => { +const testUserPoolStalenessFilter = (resource: UserPoolDescriptionType): boolean => { const isTestResource = resource.Name.match(USER_POOL_TEST_REGEX); return isTestResource && isStale(resource.CreationDate); }; -const testAppSyncApiStalenessFilter = (resource: aws.AppSync.GraphqlApi): boolean => { +const testAppSyncApiStalenessFilter = (resource: any): boolean => { const isTestResource = resource.name.match(APPSYNC_TEST_REGEX); const createTimeTagValue = resource.tags['circleci:create_time']; let isStaleResource = true; @@ -173,7 +214,7 @@ const testAppSyncApiStalenessFilter = (resource: aws.AppSync.GraphqlApi): boolea return isTestResource && isStaleResource; }; -const testPinpointAppStalenessFilter = (resource: aws.Pinpoint.ApplicationResponse): boolean => { +const testPinpointAppStalenessFilter = (resource: ApplicationResponse): boolean => { const isTestResource = resource.Name.match(PINPOINT_TEST_REGEX); return isTestResource && isStale(new Date(resource.CreationDate)); }; @@ -182,8 +223,8 @@ const testPinpointAppStalenessFilter = (resource: aws.Pinpoint.ApplicationRespon * Get all S3 buckets in the account, and filter down to the ones we consider stale. */ const getOrphanS3TestBuckets = async (account: AWSAccountInfo): Promise => { - const s3Client = new aws.S3(getAWSConfig(account)); - const listBucketResponse = await s3Client.listBuckets().promise(); + const s3Client = new S3Client(getAWSConfig(account)); + const listBucketResponse = await s3Client.send(new ListBucketsCommand({})); const staleBuckets = listBucketResponse.Buckets.filter(testBucketStalenessFilter); return staleBuckets.map((it) => ({ name: it.Name, createTime: it.CreationDate })); }; @@ -192,23 +233,23 @@ const getOrphanS3TestBuckets = async (account: AWSAccountInfo): Promise => { - const iamClient = new aws.IAM(getAWSConfig(account)); - const listRoleResponse = await iamClient.listRoles({ MaxItems: 1000 }).promise(); + const iamClient = new IAMClient(getAWSConfig(account)); + const listRoleResponse = await iamClient.send(new ListRolesCommand({ MaxItems: 1000 })); const staleRoles = listRoleResponse.Roles.filter(testRoleStalenessFilter); return staleRoles.map((it) => ({ name: it.RoleName, createTime: it.CreateDate })); }; const getOrphanPinpointApplications = async (account: AWSAccountInfo, region: string): Promise => { - const pinpoint = new aws.Pinpoint(getAWSConfig(account, region)); + const pinpoint = new PinpointClient(getAWSConfig(account, region)); const apps: PinpointAppInfo[] = []; let nextToken = null; do { - const result = await pinpoint - .getApps({ + const result = await pinpoint.send( + new GetAppsCommand({ Token: nextToken, - }) - .promise(); + }), + ); apps.push( ...result.ApplicationsResponse.Item.filter(testPinpointAppStalenessFilter).map((it) => ({ id: it.Id, @@ -226,8 +267,8 @@ const getOrphanPinpointApplications = async (account: AWSAccountInfo, region: st }; const getOrphanUserPools = async (account: AWSAccountInfo, region: string): Promise => { - const cognitoClient = new aws.CognitoIdentityServiceProvider(getAWSConfig(account, region)); - const userPools = await cognitoClient.listUserPools({ MaxResults: 60 }).promise(); + const cognitoClient = new CognitoIdentityProviderClient(getAWSConfig(account, region)); + const userPools = await cognitoClient.send(new ListUserPoolsCommand({ MaxResults: 60 })); const staleUserPools = userPools.UserPools.filter(testUserPoolStalenessFilter); return staleUserPools.map((it) => ({ name: it.Name, userPoolId: it.Id, region })); }; @@ -236,8 +277,8 @@ const getOrphanUserPools = async (account: AWSAccountInfo, region: string): Prom * Get all AppSync Apis in the account, and filter down to the ones we consider stale. */ const getOrphanAppSyncApis = async (account: AWSAccountInfo, region: string): Promise => { - const appSyncClient = new aws.AppSync(getAWSConfig(account, region)); - const listApisResponse = await appSyncClient.listGraphqlApis({ maxResults: 25 }).promise(); + const appSyncClient = new AppSyncClient(getAWSConfig(account, region)); + const listApisResponse = await appSyncClient.send(new ListGraphqlApisCommand({ maxResults: 25 })); const staleApis = listApisResponse.graphqlApis.filter(testAppSyncApiStalenessFilter); return staleApis.map((it) => ({ apiId: it.apiId, name: it.name, region })); }; @@ -246,14 +287,14 @@ const getOrphanAppSyncApis = async (account: AWSAccountInfo, region: string): Pr * Get all OIDC providers in the account that match */ const deleteOrphanedOidcProviders = async (account: AWSAccountInfo): Promise => { - const iamClient = new aws.IAM(getAWSConfig(account)); - const response = await iamClient.listOpenIDConnectProviders().promise(); + const iamClient = new IAMClient(getAWSConfig(account)); + const response = await iamClient.send(new ListOpenIDConnectProvidersCommand({})); if (response.OpenIDConnectProviderList) { for (const provider of response.OpenIDConnectProviderList) { // these seem to be the only offending resources at this time, but we can add more later if (provider.Arn.endsWith('oidc-provider/accounts.google.com')) { console.log('OIDC PROVIDER:', provider.Arn); - await iamClient.deleteOpenIDConnectProvider({ OpenIDConnectProviderArn: provider.Arn }).promise(); + await iamClient.send(new DeleteOpenIDConnectProviderCommand({ OpenIDConnectProviderArn: provider.Arn })); } } } @@ -262,14 +303,14 @@ const deleteOrphanedOidcProviders = async (account: AWSAccountInfo): Promise ({ +const getAWSConfig = ({ accessKeyId, secretAccessKey, sessionToken }: AWSAccountInfo, region?: string): any => ({ credentials: { accessKeyId, secretAccessKey, sessionToken, }, ...(region ? { region } : {}), - maxRetries: 10, + maxAttempts: 10, }); /** @@ -280,9 +321,9 @@ const getAWSConfig = ({ accessKeyId, secretAccessKey, sessionToken }: AWSAccount * @returns Promise a list of Amplify Apps in the region with build info */ const getAmplifyApps = async (account: AWSAccountInfo, region: string): Promise => { - const amplifyClient = new aws.Amplify(getAWSConfig(account, region)); + const amplifyClient = new AmplifyClient(getAWSConfig(account, region)); try { - const amplifyApps = await amplifyClient.listApps({ maxResults: 25 }).promise(); // keeping it to 25 as max supported is 25 + const amplifyApps = await amplifyClient.send(new ListAppsCommand({ maxResults: 25 })); // keeping it to 25 as max supported is 25 const result: AmplifyAppInfo[] = []; for (const app of amplifyApps.apps) { if (!isStale(app.createTime)) { @@ -290,7 +331,7 @@ const getAmplifyApps = async (account: AWSAccountInfo, region: string): Promise< } const backends: Record = {}; try { - const backendEnvironments = await amplifyClient.listBackendEnvironments({ appId: app.appId, maxResults: 5 }).promise(); + const backendEnvironments = await amplifyClient.send(new ListBackendEnvironmentsCommand({ appId: app.appId, maxResults: 5 })); for (const backendEnv of backendEnvironments.backendEnvironments) { const buildInfo = await getStackDetails(backendEnv.stackName, account, region); if (buildInfo) { @@ -319,7 +360,7 @@ const getAmplifyApps = async (account: AWSAccountInfo, region: string): Promise< * @param tags Tags associated with the resource * @returns build number or undefined */ -const getJobId = (tags: aws.CloudFormation.Tags = []): number | undefined => { +const getJobId = (tags: Tag[] = []): number | undefined => { const jobId = tags.find((tag) => tag.Key === 'circleci:build_id')?.Value; return jobId && Number.parseInt(jobId, 10); }; @@ -335,14 +376,14 @@ const getJobId = (tags: aws.CloudFormation.Tags = []): number | undefined => { * @returns stack details */ const getStackDetails = async (stackName: string, account: AWSAccountInfo, region: string): Promise => { - const cfnClient = new aws.CloudFormation(getAWSConfig(account, region)); - const stack = await cfnClient.describeStacks({ StackName: stackName }).promise(); + const cfnClient = new CloudFormationClient(getAWSConfig(account, region)); + const stack = await cfnClient.send(new DescribeStacksCommand({ StackName: stackName })); const tags = stack.Stacks.length && stack.Stacks[0].Tags; const stackStatus = stack.Stacks[0].StackStatus; let resourcesFailedToDelete: string[] = []; if (stackStatus === 'DELETE_FAILED') { // Todo: We need to investigate if we should go ahead and remove the resources to prevent account getting cluttered - const resources = await cfnClient.listStackResources({ StackName: stackName }).promise(); + const resources = await cfnClient.send(new ListStackResourcesCommand({ StackName: stackName })); resourcesFailedToDelete = resources.StackResourceSummaries.filter((r) => r.ResourceStatus === 'DELETE_FAILED').map( (r) => r.LogicalResourceId, ); @@ -357,33 +398,33 @@ const getStackDetails = async (stackName: string, account: AWSAccountInfo, regio }; const getStacks = async (account: AWSAccountInfo, region: string): Promise => { - const cfnClient = new aws.CloudFormation(getAWSConfig(account, region)); + const cfnClient = new CloudFormationClient(getAWSConfig(account, region)); const stackStatusFilter = [ - 'CREATE_COMPLETE', - 'ROLLBACK_FAILED', - 'ROLLBACK_COMPLETE', - 'DELETE_FAILED', - 'UPDATE_COMPLETE', - 'UPDATE_ROLLBACK_FAILED', - 'UPDATE_ROLLBACK_COMPLETE', - 'IMPORT_COMPLETE', - 'IMPORT_ROLLBACK_FAILED', - 'IMPORT_ROLLBACK_COMPLETE', + StackStatus.CREATE_COMPLETE, + StackStatus.ROLLBACK_FAILED, + StackStatus.ROLLBACK_COMPLETE, + StackStatus.DELETE_FAILED, + StackStatus.UPDATE_COMPLETE, + StackStatus.UPDATE_ROLLBACK_FAILED, + StackStatus.UPDATE_ROLLBACK_COMPLETE, + StackStatus.IMPORT_COMPLETE, + StackStatus.IMPORT_ROLLBACK_FAILED, + StackStatus.IMPORT_ROLLBACK_COMPLETE, ]; - const stacks = await cfnClient - .listStacks({ + const stacks = await cfnClient.send( + new ListStacksCommand({ StackStatusFilter: stackStatusFilter, - }) - .promise(); + }), + ); // loop let nextToken = stacks.NextToken; while (nextToken && stacks.StackSummaries.length < DELETE_LIMITS.PER_REGION.CFN_STACK) { - const nextPage = await cfnClient - .listStacks({ + const nextPage = await cfnClient.send( + new ListStacksCommand({ StackStatusFilter: stackStatusFilter, NextToken: nextToken, - }) - .promise(); + }), + ); stacks.StackSummaries.push(...nextPage.StackSummaries); nextToken = nextPage.NextToken; } @@ -421,12 +462,15 @@ const getStacks = async (account: AWSAccountInfo, region: string): Promise => { - const s3Client = new aws.S3(getAWSConfig(account)); - const buckets = await s3Client.listBuckets().promise(); + const s3Client = new S3Client(getAWSConfig(account)); + const buckets = await s3Client.send(new ListBucketsCommand({})); const result: S3BucketInfo[] = []; for (const bucket of buckets.Buckets) { try { - const bucketDetails = await s3Client.getBucketTagging({ Bucket: bucket.Name }).promise(); + const locationResponse = await s3Client.send(new GetBucketLocationCommand({ Bucket: bucket.Name })); + const bucketRegion = locationResponse.LocationConstraint || 'us-east-1'; + const bucketS3Client = new S3Client(getAWSConfig(account, bucketRegion)); + const bucketDetails = await bucketS3Client.send(new GetBucketTaggingCommand({ Bucket: bucket.Name })); const jobId = getJobId(bucketDetails.TagSet); if (jobId) { result.push({ @@ -435,7 +479,7 @@ const getS3Buckets = async (account: AWSAccountInfo): Promise => }); } } catch (e) { - if (e.code !== 'NoSuchTagSet' && e.code !== 'NoSuchBucket') { + if (e.name !== 'NoSuchTagSet' && e.name !== 'NoSuchBucket') { throw e; } result.push({ @@ -586,12 +630,12 @@ const deleteAmplifyApps = async (account: AWSAccountInfo, accountIndex: number, const deleteAmplifyApp = async (account: AWSAccountInfo, accountIndex: number, app: AmplifyAppInfo): Promise => { const { name, appId, region } = app; console.log(`[ACCOUNT ${accountIndex}] Deleting App ${name}(${appId})`); - const amplifyClient = new aws.Amplify(getAWSConfig(account, region)); + const amplifyClient = new AmplifyClient(getAWSConfig(account, region)); try { - await amplifyClient.deleteApp({ appId }).promise(); + await amplifyClient.send(new AmplifyDeleteAppCommand({ appId })); } catch (e) { console.log(`[ACCOUNT ${accountIndex}] Deleting Amplify App ${appId} failed with the following error`, e); - if (e.code === 'ExpiredTokenException') { + if (e.name === 'ExpiredTokenException') { handleExpiredTokenException(); } } @@ -606,21 +650,21 @@ const deleteIamRole = async (account: AWSAccountInfo, accountIndex: number, role try { console.log(`[ACCOUNT ${accountIndex}] Deleting Iam Role ${roleName}`); console.log(`Role creation time (PST): ${role.createTime.toLocaleTimeString('en-US', { timeZone: 'America/Los_Angeles' })}`); - const iamClient = new aws.IAM(getAWSConfig(account)); + const iamClient = new IAMClient(getAWSConfig(account)); await deleteAttachedRolePolicies(account, accountIndex, roleName); await deleteRolePolicies(account, accountIndex, roleName); - await iamClient.deleteRole({ RoleName: roleName }).promise(); + await iamClient.send(new DeleteRoleCommand({ RoleName: roleName })); } catch (e) { console.log(`[ACCOUNT ${accountIndex}] Deleting iam role ${roleName} failed with error ${e.message}`); - if (e.code === 'ExpiredTokenException') { + if (e.name === 'ExpiredTokenException') { handleExpiredTokenException(); } } }; const deleteAttachedRolePolicies = async (account: AWSAccountInfo, accountIndex: number, roleName: string): Promise => { - const iamClient = new aws.IAM(getAWSConfig(account)); - const rolePolicies = await iamClient.listAttachedRolePolicies({ RoleName: roleName }).promise(); + const iamClient = new IAMClient(getAWSConfig(account)); + const rolePolicies = await iamClient.send(new ListAttachedRolePoliciesCommand({ RoleName: roleName })); await Promise.all(rolePolicies.AttachedPolicies.map((policy) => detachIamAttachedRolePolicy(account, accountIndex, roleName, policy))); }; @@ -628,34 +672,34 @@ const detachIamAttachedRolePolicy = async ( account: AWSAccountInfo, accountIndex: number, roleName: string, - policy: aws.IAM.AttachedPolicy, + policy: AttachedPolicy, ): Promise => { try { console.log(`[ACCOUNT ${accountIndex}] Detach Iam Attached Role Policy ${policy.PolicyName}`); - const iamClient = new aws.IAM(getAWSConfig(account)); - await iamClient.detachRolePolicy({ RoleName: roleName, PolicyArn: policy.PolicyArn }).promise(); + const iamClient = new IAMClient(getAWSConfig(account)); + await iamClient.send(new DetachRolePolicyCommand({ RoleName: roleName, PolicyArn: policy.PolicyArn })); } catch (e) { console.log(`[ACCOUNT ${accountIndex}] Detach iam role policy ${policy.PolicyName} failed with error ${e.message}`); - if (e.code === 'ExpiredTokenException') { + if (e.name === 'ExpiredTokenException') { handleExpiredTokenException(); } } }; const deleteRolePolicies = async (account: AWSAccountInfo, accountIndex: number, roleName: string): Promise => { - const iamClient = new aws.IAM(getAWSConfig(account)); - const rolePolicies = await iamClient.listRolePolicies({ RoleName: roleName }).promise(); + const iamClient = new IAMClient(getAWSConfig(account)); + const rolePolicies = await iamClient.send(new ListRolePoliciesCommand({ RoleName: roleName })); await Promise.all(rolePolicies.PolicyNames.map((policy) => deleteIamRolePolicy(account, accountIndex, roleName, policy))); }; const deleteIamRolePolicy = async (account: AWSAccountInfo, accountIndex: number, roleName: string, policyName: string): Promise => { try { console.log(`[ACCOUNT ${accountIndex}] Deleting Iam Role Policy ${policyName}`); - const iamClient = new aws.IAM(getAWSConfig(account)); - await iamClient.deleteRolePolicy({ RoleName: roleName, PolicyName: policyName }).promise(); + const iamClient = new IAMClient(getAWSConfig(account)); + await iamClient.send(new DeleteRolePolicyCommand({ RoleName: roleName, PolicyName: policyName })); } catch (e) { console.log(`[ACCOUNT ${accountIndex}] Deleting iam role policy ${policyName} failed with error ${e.message}`); - if (e.code === 'ExpiredTokenException') { + if (e.name === 'ExpiredTokenException') { handleExpiredTokenException(); } } @@ -670,11 +714,14 @@ const deleteBucket = async (account: AWSAccountInfo, accountIndex: number, bucke try { console.log(`[ACCOUNT ${accountIndex}] Deleting S3 Bucket ${name}`); console.log(`Bucket creation time (PST): ${bucket.createTime.toLocaleTimeString('en-US', { timeZone: 'America/Los_Angeles' })}`); - const s3 = new aws.S3(getAWSConfig(account)); - await deleteS3Bucket(name, s3); + const s3 = new S3Client(getAWSConfig(account)); + const locationReponse = await s3.send(new GetBucketLocationCommand({ Bucket: name })); + const bucketRegion = locationReponse.LocationConstraint || 'us-east-1'; + const regionalS3Client = new S3Client(getAWSConfig(account, bucketRegion)); + await deleteS3Bucket(name, regionalS3Client); } catch (e) { console.log(`[ACCOUNT ${accountIndex}] Deleting bucket ${name} failed with error ${e.message}`); - if (e.code === 'ExpiredTokenException') { + if (e.name === 'ExpiredTokenException') { handleExpiredTokenException(); } } @@ -689,8 +736,8 @@ const deletePinpointApp = async (account: AWSAccountInfo, accountIndex: number, try { console.log(`[ACCOUNT ${accountIndex}] Deleting Pinpoint App ${name}`); console.log(`Pinpoint creation time (PST): ${app.createTime.toLocaleTimeString('en-US', { timeZone: 'America/Los_Angeles' })}`); - const pinpoint = new aws.Pinpoint(getAWSConfig(account, region)); - await pinpoint.deleteApp({ ApplicationId: id }).promise(); + const pinpoint = new PinpointClient(getAWSConfig(account, region)); + await pinpoint.send(new DeleteAppCommand({ ApplicationId: id })); } catch (e) { console.log(`[ACCOUNT ${accountIndex}] Deleting pinpoint app ${name} failed with error ${e.message}`); } @@ -704,8 +751,8 @@ const deleteAppSyncApi = async (account: AWSAccountInfo, accountIndex: number, a const { apiId, name, region } = api; try { console.log(`[ACCOUNT ${accountIndex}] Deleting AppSync Api ${name}`); - const appSync = new aws.AppSync(getAWSConfig(account, region)); - await appSync.deleteGraphqlApi({ apiId }).promise(); + const appSync = new AppSyncClient(getAWSConfig(account, region)); + await appSync.send(new DeleteGraphqlApiCommand({ apiId })); } catch (e) { console.log(`[ACCOUNT ${accountIndex}] Deleting AppSync Api ${name} failed with error ${e.message}`); } @@ -719,17 +766,17 @@ const deleteUserPool = async (account: AWSAccountInfo, accountIndex: number, use const { name, region, userPoolId } = userPool; try { console.log(`[ACCOUNT ${accountIndex}] Deleting UserPool ${name}`); - const cognitoClient = new aws.CognitoIdentityServiceProvider(getAWSConfig(account, region)); - const userPoolDetails = await cognitoClient.describeUserPool({ UserPoolId: userPoolId }).promise(); + const cognitoClient = new CognitoIdentityProviderClient(getAWSConfig(account, region)); + const userPoolDetails = await cognitoClient.send(new DescribeUserPoolCommand({ UserPoolId: userPoolId })); if (userPoolDetails.UserPool.Domain) { - await cognitoClient - .deleteUserPoolDomain({ + await cognitoClient.send( + new DeleteUserPoolDomainCommand({ UserPoolId: userPoolId, Domain: userPoolDetails.UserPool.Domain, - }) - .promise(); + }), + ); } - await cognitoClient.deleteUserPool({ UserPoolId: userPoolId }).promise(); + await cognitoClient.send(new DeleteUserPoolCommand({ UserPoolId: userPoolId })); } catch (e) { console.log(`[ACCOUNT ${accountIndex}] Deleting UserPool ${name} failed with error ${e.message}`); } @@ -744,13 +791,13 @@ const deleteCfnStack = async (account: AWSAccountInfo, accountIndex: number, sta const resourceToRetain = resourcesFailedToDelete.length ? resourcesFailedToDelete : undefined; console.log(`[ACCOUNT ${accountIndex}] Deleting CloudFormation stack ${stackName}`); try { - const cfnClient = new aws.CloudFormation(getAWSConfig(account, region)); - await cfnClient.deleteStack({ StackName: stackName, RetainResources: resourceToRetain }).promise(); + const cfnClient = new CloudFormationClient(getAWSConfig(account, region)); + await cfnClient.send(new DeleteStackCommand({ StackName: stackName, RetainResources: resourceToRetain })); // we'll only wait up to a minute before moving on - await cfnClient.waitFor('stackDeleteComplete', { StackName: stackName, $waiter: { maxAttempts: 2 } }).promise(); + await waitUntilStackDeleteComplete({ client: cfnClient, maxWaitTime: 120 }, { StackName: stackName }); } catch (e) { console.log(`Deleting CloudFormation stack ${stackName} failed with error ${e.message}`); - if (e.code === 'ExpiredTokenException') { + if (e.name === 'ExpiredTokenException') { handleExpiredTokenException(); } } @@ -842,24 +889,25 @@ const getFilterPredicate = (args: any): JobFilterPredicate => { * to get all accounts within the root account organization. */ const getAccountsToCleanup = async (): Promise => { - const stsRes = new aws.STS({ - apiVersion: '2011-06-15', - accessKeyId: process.env.AWS_ACCESS_KEY_ID, - secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, - sessionToken: process.env.AWS_SESSION_TOKEN, + const stsRes = new STSClient({ + credentials: { + accessKeyId: process.env.AWS_ACCESS_KEY_ID, + secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, + sessionToken: process.env.AWS_SESSION_TOKEN, + }, + endpoint: 'https://sts.amazonaws.com', }); - const parentAccountIdentity = await stsRes.getCallerIdentity().promise(); - const orgApi = new aws.Organizations({ - apiVersion: '2016-11-28', + const parentAccountIdentity = await stsRes.send(new GetCallerIdentityCommand({})); + const orgApi = new OrganizationsClient({ // the region where the organization exists region: 'us-east-1', }); try { - const orgAccounts = await orgApi.listAccounts().promise(); + const orgAccounts = await orgApi.send(new ListAccountsCommand({})); const allAccounts = orgAccounts.Accounts; let nextToken = orgAccounts.NextToken; while (nextToken) { - const nextPage = await orgApi.listAccounts({ NextToken: nextToken }).promise(); + const nextPage = await orgApi.send(new ListAccountsCommand({ NextToken: nextToken })); allAccounts.push(...nextPage.Accounts); nextToken = nextPage.NextToken; } @@ -873,14 +921,14 @@ const getAccountsToCleanup = async (): Promise => { }; } const randomNumber = Math.floor(Math.random() * 100000); - const assumeRoleRes = await stsRes - .assumeRole({ + const assumeRoleRes = await stsRes.send( + new AssumeRoleCommand({ RoleArn: `arn:aws:iam::${account.Id}:role/OrganizationAccountAccessRole`, RoleSessionName: `testSession${randomNumber}`, // One hour DurationSeconds: 1 * 60 * 60, - }) - .promise(); + }), + ); return { accessKeyId: assumeRoleRes.Credentials.AccessKeyId, secretAccessKey: assumeRoleRes.Credentials.SecretAccessKey, diff --git a/packages/amplify-e2e-tests/src/import-helpers/types.ts b/packages/amplify-e2e-tests/src/import-helpers/types.ts index 548763ec902..fc44773bd60 100644 --- a/packages/amplify-e2e-tests/src/import-helpers/types.ts +++ b/packages/amplify-e2e-tests/src/import-helpers/types.ts @@ -1,11 +1,4 @@ -import { - BooleanType, - CallbackURLsListType, - OAuthFlowsType, - ScopeListType, - SupportedIdentityProvidersListType, -} from 'aws-sdk/clients/cognitoidentityserviceprovider'; - +import { CreateUserPoolClientCommandInput } from '@aws-sdk/client-cognito-identity-provider'; import { $TSObject } from '@aws-amplify/amplify-cli-core'; export type AuthProjectDetails = { @@ -92,10 +85,10 @@ export type DynamoDBProjectDetails = { }; export type AppClientSettings = { - allowedOAuthFlows?: OAuthFlowsType; - callbackURLs?: CallbackURLsListType; - logoutURLs?: CallbackURLsListType; - allowedScopes?: ScopeListType; - supportedIdentityProviders?: SupportedIdentityProvidersListType; - allowedOAuthFlowsUserPoolClient?: BooleanType; + allowedOAuthFlows?: CreateUserPoolClientCommandInput['AllowedOAuthFlows']; + callbackURLs?: CreateUserPoolClientCommandInput['CallbackURLs']; + logoutURLs?: CreateUserPoolClientCommandInput['LogoutURLs']; + allowedScopes?: CreateUserPoolClientCommandInput['AllowedOAuthScopes']; + supportedIdentityProviders?: CreateUserPoolClientCommandInput['SupportedIdentityProviders']; + allowedOAuthFlowsUserPoolClient?: CreateUserPoolClientCommandInput['AllowedOAuthFlowsUserPoolClient']; }; diff --git a/packages/amplify-e2e-tests/src/import-helpers/utilities.ts b/packages/amplify-e2e-tests/src/import-helpers/utilities.ts index ba18f8e869e..9b575cd4cd8 100644 --- a/packages/amplify-e2e-tests/src/import-helpers/utilities.ts +++ b/packages/amplify-e2e-tests/src/import-helpers/utilities.ts @@ -8,7 +8,12 @@ import { getProjectMeta, getTeamProviderInfo, } from '@aws-amplify/amplify-e2e-core'; -import * as aws from 'aws-sdk'; +import { + CognitoIdentityProviderClient, + CreateUserPoolClientCommand, + DeleteUserPoolClientCommand, +} from '@aws-sdk/client-cognito-identity-provider'; +import { fromIni } from '@aws-sdk/credential-providers'; import * as fs from 'fs-extra'; import _ from 'lodash'; import * as path from 'path'; @@ -295,14 +300,14 @@ const addAppClient = async ( ) => { const projectDetails = getProjectMeta(projectRoot); const authDetails = getAuthProjectDetails(projectRoot); - const creds = new aws.SharedIniFileCredentials({ profile: profileName }); + const creds = fromIni({ profile: profileName }); - const cognitoClient = new aws.CognitoIdentityServiceProvider({ + const cognitoClient = new CognitoIdentityProviderClient({ credentials: creds, region: projectDetails.providers.awscloudformation.Region, }); - const response = await cognitoClient - .createUserPoolClient({ + const response = await cognitoClient.send( + new CreateUserPoolClientCommand({ ClientName: clientName, UserPoolId: authDetails.meta.UserPoolId, GenerateSecret: generateSecret, @@ -312,8 +317,8 @@ const addAppClient = async ( AllowedOAuthScopes: settings.allowedScopes, SupportedIdentityProviders: settings.supportedIdentityProviders, AllowedOAuthFlowsUserPoolClient: settings.allowedOAuthFlowsUserPoolClient, - }) - .promise(); + }), + ); // eslint-disable-next-line spellcheck/spell-checker return { appClientId: response.UserPoolClient.ClientId, appclientSecret: response.UserPoolClient.ClientSecret }; }; @@ -333,13 +338,13 @@ export const addAppClientWithoutSecret = async ( export const deleteAppClient = async (profileName: string, projectRoot: string, clientId: string): Promise => { const authDetails = getAuthProjectDetails(projectRoot); const projectDetails = getProjectMeta(projectRoot); - const creds = new aws.SharedIniFileCredentials({ profile: profileName }); + const creds = fromIni({ profile: profileName }); - const cognitoClient = new aws.CognitoIdentityServiceProvider({ + const cognitoClient = new CognitoIdentityProviderClient({ credentials: creds, region: projectDetails.providers.awscloudformation.Region, }); - await cognitoClient.deleteUserPoolClient({ ClientId: clientId, UserPoolId: authDetails.meta.UserPoolId }).promise(); + await cognitoClient.send(new DeleteUserPoolClientCommand({ ClientId: clientId, UserPoolId: authDetails.meta.UserPoolId })); }; /** diff --git a/packages/amplify-provider-awscloudformation/package.json b/packages/amplify-provider-awscloudformation/package.json index 1c5b860f44a..874bd556b77 100644 --- a/packages/amplify-provider-awscloudformation/package.json +++ b/packages/amplify-provider-awscloudformation/package.json @@ -68,7 +68,6 @@ "amplify-codegen": "^4.10.3", "archiver": "^7.0.1", "aws-cdk-lib": "~2.189.1", - "aws-sdk": "^2.1464.0", "bottleneck": "2.19.5", "chalk": "^4.1.1", "cloudform-types": "^4.2.0", diff --git a/packages/amplify-provider-awscloudformation/src/aws-utils/aws.js b/packages/amplify-provider-awscloudformation/src/aws-utils/aws.js deleted file mode 100644 index b7700eab815..00000000000 --- a/packages/amplify-provider-awscloudformation/src/aws-utils/aws.js +++ /dev/null @@ -1,46 +0,0 @@ -const path = require('path'); -const fs = require('fs-extra'); -const os = require('os'); - -const dotAWSDirPath = path.normalize(path.join(os.homedir(), '.aws')); -const credentialsFilePath = path.join(dotAWSDirPath, 'credentials'); -const configFilePath = path.join(dotAWSDirPath, 'config'); - -let aws; - -try { - delete require.cache[require.resolve('aws-sdk')]; - if (fs.existsSync(credentialsFilePath) && fs.existsSync(configFilePath)) { - process.env.AWS_SDK_LOAD_CONFIG = true; - } else { - delete process.env.AWS_SDK_LOAD_CONFIG; - } - aws = require('aws-sdk'); -} catch (e) { - delete require.cache[require.resolve('aws-sdk')]; - delete process.env.AWS_SDK_LOAD_CONFIG; - aws = require('aws-sdk'); -} - -// TODO: get rid of configureWithCreds after data Gen1 releases -const { ProxyAgent } = require('proxy-agent'); -const configurationManager = require('../configuration-manager'); - -aws.configureWithCreds = async (context) => { - const httpProxy = process.env.HTTP_PROXY || process.env.HTTPS_PROXY; - const config = await configurationManager.loadConfiguration(context, aws); - if (config) { - aws.config.update(config); - } - - if (httpProxy) { - aws.config.update({ - httpOptions: { - agent: new ProxyAgent(httpProxy), - }, - }); - } - return aws; -}; - -module.exports = aws; diff --git a/packages/amplify-provider-awscloudformation/src/configuration-manager.ts b/packages/amplify-provider-awscloudformation/src/configuration-manager.ts index 86399f7717d..59c8ff68bd3 100644 --- a/packages/amplify-provider-awscloudformation/src/configuration-manager.ts +++ b/packages/amplify-provider-awscloudformation/src/configuration-manager.ts @@ -65,6 +65,13 @@ const defaultAWSConfig: AwsConfig = { }; export async function init(context: $TSContext) { + const credentialsFilePath = pathManager.getAWSCredentialsFilePath(); + const configFilePath = pathManager.getAWSConfigFilePath(); + + if (fs.existsSync(credentialsFilePath) && fs.existsSync(configFilePath)) { + process.env.AWS_SDK_LOAD_CONFIG = 'true'; + } + if (context.exeInfo.existingLocalEnvInfo?.noUpdateBackend || (!context.exeInfo.isNewProject && doesAwsConfigExists(context))) { return context; } diff --git a/packages/amplify-provider-awscloudformation/src/index.ts b/packages/amplify-provider-awscloudformation/src/index.ts index 9ca7fd7fe27..ead5d79ec3e 100644 --- a/packages/amplify-provider-awscloudformation/src/index.ts +++ b/packages/amplify-provider-awscloudformation/src/index.ts @@ -8,7 +8,6 @@ const constants = require('./constants'); const configManager = require('./configuration-manager'); const setupNewUser = require('./setup-new-user'); const { displayHelpfulURLs } = require('./display-helpful-urls'); -const aws = require('./aws-utils/aws'); const { getLexRegionMapping } = require('./aws-utils/aws-lex'); const amplifyService = require('./aws-utils/aws-amplify'); const consoleCommand = require('./console'); @@ -119,19 +118,6 @@ async function getConfiguredAWSClientConfig(context, category, action) { return config; } -// TODO: get rid of this function after data Gen1 releases -async function getConfiguredAWSClient(context, category, action) { - await aws.configureWithCreds(context); - category = category || 'missing'; - action = action || ['missing']; - const userAgentAction = `${category}:${action[0]}`; - - aws.config.update({ - customUserAgent: formUserAgentParam(context, userAgentAction), - }); - return aws; -} - function getConfiguredAmplifyClient(context, category, action, options = {}) { return amplifyService.getConfiguredAmplifyClient(context, options); } @@ -188,7 +174,6 @@ module.exports = { storeCurrentCloudBackend, providerUtils, setupNewUser, - getConfiguredAWSClient, getConfiguredAWSClientConfig, getLexRegionMapping, getConfiguredAmplifyClient, diff --git a/shared-scripts.sh b/shared-scripts.sh index 77b63ba8448..627fd95ec95 100644 --- a/shared-scripts.sh +++ b/shared-scripts.sh @@ -774,6 +774,7 @@ function _cleanUpResources { echo "Executing resource cleanup" cd packages/amplify-e2e-tests yarn install + export NODE_OPTIONS="--max-old-space-size=8192" ts-node ./src/cleanup-codebuild-resources.ts _unassumeTestAccountCredentials } diff --git a/yarn.lock b/yarn.lock index 13483843ba8..5889c2bb63b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -315,7 +315,9 @@ __metadata: dependencies: "@aws-amplify/amplify-cli-core": 4.4.3 "@aws-amplify/amplify-prompts": 2.8.7 - aws-sdk: ^2.1692.0 + "@aws-sdk/client-cloudfront": ^3.919.0 + "@aws-sdk/client-s3": ^3.919.0 + "@aws-sdk/lib-storage": ^3.919.0 chalk: ^4.1.1 fs-extra: ^8.1.0 mime-types: ^2.1.26 @@ -347,7 +349,7 @@ __metadata: "@aws-amplify/amplify-prompts": 2.8.7 "@aws-amplify/amplify-provider-awscloudformation": 8.11.14 "@aws-sdk/client-iam": ^3.919.0 - "@aws-sdk/client-pinpoint": ^3.919.0 + "@aws-sdk/client-pinpoint": 3.901.0 "@smithy/node-http-handler": ^4.4.3 aws-sdk-client-mock: ^4.1.0 aws-sdk-client-mock-jest: ^4.1.0 @@ -478,7 +480,6 @@ __metadata: "@aws-sdk/client-amplify": ^3.919.0 "@aws-sdk/client-s3": ^3.919.0 archiver: ^7.0.1 - aws-sdk: ^2.1692.0 chalk: ^4.1.1 cli-table3: ^0.6.0 execa: ^5.1.1 @@ -519,6 +520,8 @@ __metadata: "@aws-amplify/amplify-category-api": ^5.15.1 "@aws-amplify/amplify-cli-core": 4.4.3 "@aws-amplify/amplify-environment-parameters": 1.9.22 + "@aws-sdk/client-s3": ^3.919.0 + "@aws-sdk/lib-storage": ^3.919.0 fs-extra: ^8.1.0 inquirer: ^7.3.3 mime-types: ^2.1.26 @@ -544,13 +547,30 @@ __metadata: resolution: "@aws-amplify/amplify-e2e-core@workspace:packages/amplify-e2e-core" dependencies: "@aws-amplify/amplify-cli-core": 4.4.3 - "@aws-sdk/client-pinpoint": ^3.919.0 + "@aws-sdk/client-amplifybackend": ^3.919.0 + "@aws-sdk/client-amplifyuibuilder": ^3.919.0 + "@aws-sdk/client-appsync": ^3.919.0 + "@aws-sdk/client-cloudformation": ^3.919.0 + "@aws-sdk/client-cloudwatch-events": ^3.919.0 + "@aws-sdk/client-cloudwatch-logs": ^3.919.0 + "@aws-sdk/client-cognito-identity": ^3.919.0 + "@aws-sdk/client-cognito-identity-provider": ^3.919.0 + "@aws-sdk/client-dynamodb": ^3.919.0 + "@aws-sdk/client-iam": ^3.919.0 + "@aws-sdk/client-kinesis": ^3.919.0 + "@aws-sdk/client-lambda": ^3.919.0 + "@aws-sdk/client-lex-model-building-service": ^3.919.0 + "@aws-sdk/client-location": ^3.919.0 + "@aws-sdk/client-pinpoint": 3.901.0 + "@aws-sdk/client-rekognition": ^3.919.0 + "@aws-sdk/client-s3": ^3.919.0 + "@aws-sdk/client-ssm": ^3.919.0 "@aws-sdk/client-sts": ^3.919.0 "@aws-sdk/credential-providers": ^3.919.0 + "@aws-sdk/lib-dynamodb": ^3.919.0 amplify-headless-interface: 1.17.8 aws-amplify: ^5.3.16 aws-appsync: ^4.1.1 - aws-sdk: ^2.1464.0 chalk: ^4.1.1 dotenv: ^8.2.0 execa: ^5.1.1 @@ -856,7 +876,6 @@ __metadata: amplify-codegen: ^4.10.3 archiver: ^7.0.1 aws-cdk-lib: ~2.189.1 - aws-sdk: ^2.1464.0 aws-sdk-client-mock: ^4.1.0 aws-sdk-client-mock-jest: ^4.1.0 bottleneck: 2.19.5 @@ -2409,6 +2428,103 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/client-cloudfront@npm:^3.919.0": + version: 3.919.0 + resolution: "@aws-sdk/client-cloudfront@npm:3.919.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.916.0 + "@aws-sdk/credential-provider-node": 3.919.0 + "@aws-sdk/middleware-host-header": 3.914.0 + "@aws-sdk/middleware-logger": 3.914.0 + "@aws-sdk/middleware-recursion-detection": 3.919.0 + "@aws-sdk/middleware-user-agent": 3.916.0 + "@aws-sdk/region-config-resolver": 3.914.0 + "@aws-sdk/types": 3.914.0 + "@aws-sdk/util-endpoints": 3.916.0 + "@aws-sdk/util-user-agent-browser": 3.914.0 + "@aws-sdk/util-user-agent-node": 3.916.0 + "@aws-sdk/xml-builder": 3.914.0 + "@smithy/config-resolver": ^4.4.0 + "@smithy/core": ^3.17.1 + "@smithy/fetch-http-handler": ^5.3.4 + "@smithy/hash-node": ^4.2.3 + "@smithy/invalid-dependency": ^4.2.3 + "@smithy/middleware-content-length": ^4.2.3 + "@smithy/middleware-endpoint": ^4.3.5 + "@smithy/middleware-retry": ^4.4.5 + "@smithy/middleware-serde": ^4.2.3 + "@smithy/middleware-stack": ^4.2.3 + "@smithy/node-config-provider": ^4.3.3 + "@smithy/node-http-handler": ^4.4.3 + "@smithy/protocol-http": ^5.3.3 + "@smithy/smithy-client": ^4.9.1 + "@smithy/types": ^4.8.0 + "@smithy/url-parser": ^4.2.3 + "@smithy/util-base64": ^4.3.0 + "@smithy/util-body-length-browser": ^4.2.0 + "@smithy/util-body-length-node": ^4.2.1 + "@smithy/util-defaults-mode-browser": ^4.3.4 + "@smithy/util-defaults-mode-node": ^4.2.6 + "@smithy/util-endpoints": ^3.2.3 + "@smithy/util-middleware": ^4.2.3 + "@smithy/util-retry": ^4.2.3 + "@smithy/util-stream": ^4.5.4 + "@smithy/util-utf8": ^4.2.0 + "@smithy/util-waiter": ^4.2.3 + tslib: ^2.6.2 + checksum: 971d4759825fc46f3a4808164acb69ec4621b504429be63d366cd972b7c310451826fe9b80c888eb86bc6c62ac242669dfe92dd63a2fc40e18370dea95937ca3 + languageName: node + linkType: hard + +"@aws-sdk/client-cloudwatch-events@npm:^3.919.0": + version: 3.919.0 + resolution: "@aws-sdk/client-cloudwatch-events@npm:3.919.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.916.0 + "@aws-sdk/credential-provider-node": 3.919.0 + "@aws-sdk/middleware-host-header": 3.914.0 + "@aws-sdk/middleware-logger": 3.914.0 + "@aws-sdk/middleware-recursion-detection": 3.919.0 + "@aws-sdk/middleware-user-agent": 3.916.0 + "@aws-sdk/region-config-resolver": 3.914.0 + "@aws-sdk/types": 3.914.0 + "@aws-sdk/util-endpoints": 3.916.0 + "@aws-sdk/util-user-agent-browser": 3.914.0 + "@aws-sdk/util-user-agent-node": 3.916.0 + "@smithy/config-resolver": ^4.4.0 + "@smithy/core": ^3.17.1 + "@smithy/fetch-http-handler": ^5.3.4 + "@smithy/hash-node": ^4.2.3 + "@smithy/invalid-dependency": ^4.2.3 + "@smithy/middleware-content-length": ^4.2.3 + "@smithy/middleware-endpoint": ^4.3.5 + "@smithy/middleware-retry": ^4.4.5 + "@smithy/middleware-serde": ^4.2.3 + "@smithy/middleware-stack": ^4.2.3 + "@smithy/node-config-provider": ^4.3.3 + "@smithy/node-http-handler": ^4.4.3 + "@smithy/protocol-http": ^5.3.3 + "@smithy/smithy-client": ^4.9.1 + "@smithy/types": ^4.8.0 + "@smithy/url-parser": ^4.2.3 + "@smithy/util-base64": ^4.3.0 + "@smithy/util-body-length-browser": ^4.2.0 + "@smithy/util-body-length-node": ^4.2.1 + "@smithy/util-defaults-mode-browser": ^4.3.4 + "@smithy/util-defaults-mode-node": ^4.2.6 + "@smithy/util-endpoints": ^3.2.3 + "@smithy/util-middleware": ^4.2.3 + "@smithy/util-retry": ^4.2.3 + "@smithy/util-utf8": ^4.2.0 + tslib: ^2.6.2 + checksum: e10cf68515c17a17977aa2190d4879dcf87c6e5779563bb1938301643b6c04b3d28bc03ff9895abec98816a0f181f589bb067208b2c6cafaa0a5f9b6f5b3f30a + languageName: node + linkType: hard + "@aws-sdk/client-cloudwatch-logs@npm:3.6.1": version: 3.6.1 resolution: "@aws-sdk/client-cloudwatch-logs@npm:3.6.1" @@ -2448,6 +2564,104 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/client-cloudwatch-logs@npm:^3.919.0": + version: 3.919.0 + resolution: "@aws-sdk/client-cloudwatch-logs@npm:3.919.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.916.0 + "@aws-sdk/credential-provider-node": 3.919.0 + "@aws-sdk/middleware-host-header": 3.914.0 + "@aws-sdk/middleware-logger": 3.914.0 + "@aws-sdk/middleware-recursion-detection": 3.919.0 + "@aws-sdk/middleware-user-agent": 3.916.0 + "@aws-sdk/region-config-resolver": 3.914.0 + "@aws-sdk/types": 3.914.0 + "@aws-sdk/util-endpoints": 3.916.0 + "@aws-sdk/util-user-agent-browser": 3.914.0 + "@aws-sdk/util-user-agent-node": 3.916.0 + "@smithy/config-resolver": ^4.4.0 + "@smithy/core": ^3.17.1 + "@smithy/eventstream-serde-browser": ^4.2.3 + "@smithy/eventstream-serde-config-resolver": ^4.3.3 + "@smithy/eventstream-serde-node": ^4.2.3 + "@smithy/fetch-http-handler": ^5.3.4 + "@smithy/hash-node": ^4.2.3 + "@smithy/invalid-dependency": ^4.2.3 + "@smithy/middleware-content-length": ^4.2.3 + "@smithy/middleware-endpoint": ^4.3.5 + "@smithy/middleware-retry": ^4.4.5 + "@smithy/middleware-serde": ^4.2.3 + "@smithy/middleware-stack": ^4.2.3 + "@smithy/node-config-provider": ^4.3.3 + "@smithy/node-http-handler": ^4.4.3 + "@smithy/protocol-http": ^5.3.3 + "@smithy/smithy-client": ^4.9.1 + "@smithy/types": ^4.8.0 + "@smithy/url-parser": ^4.2.3 + "@smithy/util-base64": ^4.3.0 + "@smithy/util-body-length-browser": ^4.2.0 + "@smithy/util-body-length-node": ^4.2.1 + "@smithy/util-defaults-mode-browser": ^4.3.4 + "@smithy/util-defaults-mode-node": ^4.2.6 + "@smithy/util-endpoints": ^3.2.3 + "@smithy/util-middleware": ^4.2.3 + "@smithy/util-retry": ^4.2.3 + "@smithy/util-utf8": ^4.2.0 + "@smithy/uuid": ^1.1.0 + tslib: ^2.6.2 + checksum: 5679a05e94759623ead7c256079277bf8776edfa7796ed2de180157c530b80e780f925211ee4048dbcd78d7e917b7827375131a1521125243c528c549863d35e + languageName: node + linkType: hard + +"@aws-sdk/client-codebuild@npm:^3.919.0": + version: 3.919.0 + resolution: "@aws-sdk/client-codebuild@npm:3.919.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.916.0 + "@aws-sdk/credential-provider-node": 3.919.0 + "@aws-sdk/middleware-host-header": 3.914.0 + "@aws-sdk/middleware-logger": 3.914.0 + "@aws-sdk/middleware-recursion-detection": 3.919.0 + "@aws-sdk/middleware-user-agent": 3.916.0 + "@aws-sdk/region-config-resolver": 3.914.0 + "@aws-sdk/types": 3.914.0 + "@aws-sdk/util-endpoints": 3.916.0 + "@aws-sdk/util-user-agent-browser": 3.914.0 + "@aws-sdk/util-user-agent-node": 3.916.0 + "@smithy/config-resolver": ^4.4.0 + "@smithy/core": ^3.17.1 + "@smithy/fetch-http-handler": ^5.3.4 + "@smithy/hash-node": ^4.2.3 + "@smithy/invalid-dependency": ^4.2.3 + "@smithy/middleware-content-length": ^4.2.3 + "@smithy/middleware-endpoint": ^4.3.5 + "@smithy/middleware-retry": ^4.4.5 + "@smithy/middleware-serde": ^4.2.3 + "@smithy/middleware-stack": ^4.2.3 + "@smithy/node-config-provider": ^4.3.3 + "@smithy/node-http-handler": ^4.4.3 + "@smithy/protocol-http": ^5.3.3 + "@smithy/smithy-client": ^4.9.1 + "@smithy/types": ^4.8.0 + "@smithy/url-parser": ^4.2.3 + "@smithy/util-base64": ^4.3.0 + "@smithy/util-body-length-browser": ^4.2.0 + "@smithy/util-body-length-node": ^4.2.1 + "@smithy/util-defaults-mode-browser": ^4.3.4 + "@smithy/util-defaults-mode-node": ^4.2.6 + "@smithy/util-endpoints": ^3.2.3 + "@smithy/util-middleware": ^4.2.3 + "@smithy/util-retry": ^4.2.3 + "@smithy/util-utf8": ^4.2.0 + tslib: ^2.6.2 + checksum: 83f2bbf7adb6dd86c41f0e2bcf8eed0238791291dc0b0e8d439247248c7ebb5238d92be876fe565f50010b7b05dc5f4d471f8120a929dba435b2b5c567cfd988 + languageName: node + linkType: hard + "@aws-sdk/client-cognito-identity-provider@npm:^3.919.0": version: 3.919.0 resolution: "@aws-sdk/client-cognito-identity-provider@npm:3.919.0" @@ -3009,6 +3223,57 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/client-kinesis@npm:^3.919.0": + version: 3.919.0 + resolution: "@aws-sdk/client-kinesis@npm:3.919.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.916.0 + "@aws-sdk/credential-provider-node": 3.919.0 + "@aws-sdk/middleware-host-header": 3.914.0 + "@aws-sdk/middleware-logger": 3.914.0 + "@aws-sdk/middleware-recursion-detection": 3.919.0 + "@aws-sdk/middleware-user-agent": 3.916.0 + "@aws-sdk/region-config-resolver": 3.914.0 + "@aws-sdk/types": 3.914.0 + "@aws-sdk/util-endpoints": 3.916.0 + "@aws-sdk/util-user-agent-browser": 3.914.0 + "@aws-sdk/util-user-agent-node": 3.916.0 + "@smithy/config-resolver": ^4.4.0 + "@smithy/core": ^3.17.1 + "@smithy/eventstream-serde-browser": ^4.2.3 + "@smithy/eventstream-serde-config-resolver": ^4.3.3 + "@smithy/eventstream-serde-node": ^4.2.3 + "@smithy/fetch-http-handler": ^5.3.4 + "@smithy/hash-node": ^4.2.3 + "@smithy/invalid-dependency": ^4.2.3 + "@smithy/middleware-content-length": ^4.2.3 + "@smithy/middleware-endpoint": ^4.3.5 + "@smithy/middleware-retry": ^4.4.5 + "@smithy/middleware-serde": ^4.2.3 + "@smithy/middleware-stack": ^4.2.3 + "@smithy/node-config-provider": ^4.3.3 + "@smithy/node-http-handler": ^4.4.3 + "@smithy/protocol-http": ^5.3.3 + "@smithy/smithy-client": ^4.9.1 + "@smithy/types": ^4.8.0 + "@smithy/url-parser": ^4.2.3 + "@smithy/util-base64": ^4.3.0 + "@smithy/util-body-length-browser": ^4.2.0 + "@smithy/util-body-length-node": ^4.2.1 + "@smithy/util-defaults-mode-browser": ^4.3.4 + "@smithy/util-defaults-mode-node": ^4.2.6 + "@smithy/util-endpoints": ^3.2.3 + "@smithy/util-middleware": ^4.2.3 + "@smithy/util-retry": ^4.2.3 + "@smithy/util-utf8": ^4.2.0 + "@smithy/util-waiter": ^4.2.3 + tslib: ^2.6.2 + checksum: 5873f6dceeceabf28d42628c53eab3ebc7f89e8afd45a3ba89cb9ca3a4fd26d7a1b017c9f141e94255e8bf75538fe2fe2da500c790597e6124f166e9c51f75fe + languageName: node + linkType: hard + "@aws-sdk/client-lambda@npm:3.624.0": version: 3.624.0 resolution: "@aws-sdk/client-lambda@npm:3.624.0" @@ -3341,6 +3606,53 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/client-organizations@npm:^3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/client-organizations@npm:3.920.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.920.0 + "@aws-sdk/credential-provider-node": 3.920.0 + "@aws-sdk/middleware-host-header": 3.920.0 + "@aws-sdk/middleware-logger": 3.920.0 + "@aws-sdk/middleware-recursion-detection": 3.920.0 + "@aws-sdk/middleware-user-agent": 3.920.0 + "@aws-sdk/region-config-resolver": 3.920.0 + "@aws-sdk/types": 3.920.0 + "@aws-sdk/util-endpoints": 3.920.0 + "@aws-sdk/util-user-agent-browser": 3.920.0 + "@aws-sdk/util-user-agent-node": 3.920.0 + "@smithy/config-resolver": ^4.4.0 + "@smithy/core": ^3.17.1 + "@smithy/fetch-http-handler": ^5.3.4 + "@smithy/hash-node": ^4.2.3 + "@smithy/invalid-dependency": ^4.2.3 + "@smithy/middleware-content-length": ^4.2.3 + "@smithy/middleware-endpoint": ^4.3.5 + "@smithy/middleware-retry": ^4.4.5 + "@smithy/middleware-serde": ^4.2.3 + "@smithy/middleware-stack": ^4.2.3 + "@smithy/node-config-provider": ^4.3.3 + "@smithy/node-http-handler": ^4.4.3 + "@smithy/protocol-http": ^5.3.3 + "@smithy/smithy-client": ^4.9.1 + "@smithy/types": ^4.8.0 + "@smithy/url-parser": ^4.2.3 + "@smithy/util-base64": ^4.3.0 + "@smithy/util-body-length-browser": ^4.2.0 + "@smithy/util-body-length-node": ^4.2.1 + "@smithy/util-defaults-mode-browser": ^4.3.4 + "@smithy/util-defaults-mode-node": ^4.2.6 + "@smithy/util-endpoints": ^3.2.3 + "@smithy/util-middleware": ^4.2.3 + "@smithy/util-retry": ^4.2.3 + "@smithy/util-utf8": ^4.2.0 + tslib: ^2.6.2 + checksum: 3038f29ff6d14c748b2efb4b52cf5e888a8727b144bea09d8ba55be9218fe9f505f49354586e242ce401d13e6f431e9f67f0def0e81e069e387758ef2ac803d5 + languageName: node + linkType: hard + "@aws-sdk/client-personalize-events@npm:3.6.1": version: 3.6.1 resolution: "@aws-sdk/client-personalize-events@npm:3.6.1" @@ -3380,50 +3692,50 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-pinpoint@npm:^3.919.0": - version: 3.919.0 - resolution: "@aws-sdk/client-pinpoint@npm:3.919.0" +"@aws-sdk/client-pinpoint@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/client-pinpoint@npm:3.901.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/core": 3.916.0 - "@aws-sdk/credential-provider-node": 3.919.0 - "@aws-sdk/middleware-host-header": 3.914.0 - "@aws-sdk/middleware-logger": 3.914.0 - "@aws-sdk/middleware-recursion-detection": 3.919.0 - "@aws-sdk/middleware-user-agent": 3.916.0 - "@aws-sdk/region-config-resolver": 3.914.0 - "@aws-sdk/types": 3.914.0 - "@aws-sdk/util-endpoints": 3.916.0 - "@aws-sdk/util-user-agent-browser": 3.914.0 - "@aws-sdk/util-user-agent-node": 3.916.0 - "@smithy/config-resolver": ^4.4.0 - "@smithy/core": ^3.17.1 - "@smithy/fetch-http-handler": ^5.3.4 - "@smithy/hash-node": ^4.2.3 - "@smithy/invalid-dependency": ^4.2.3 - "@smithy/middleware-content-length": ^4.2.3 - "@smithy/middleware-endpoint": ^4.3.5 - "@smithy/middleware-retry": ^4.4.5 - "@smithy/middleware-serde": ^4.2.3 - "@smithy/middleware-stack": ^4.2.3 - "@smithy/node-config-provider": ^4.3.3 - "@smithy/node-http-handler": ^4.4.3 - "@smithy/protocol-http": ^5.3.3 - "@smithy/smithy-client": ^4.9.1 - "@smithy/types": ^4.8.0 - "@smithy/url-parser": ^4.2.3 - "@smithy/util-base64": ^4.3.0 + "@aws-sdk/core": 3.901.0 + "@aws-sdk/credential-provider-node": 3.901.0 + "@aws-sdk/middleware-host-header": 3.901.0 + "@aws-sdk/middleware-logger": 3.901.0 + "@aws-sdk/middleware-recursion-detection": 3.901.0 + "@aws-sdk/middleware-user-agent": 3.901.0 + "@aws-sdk/region-config-resolver": 3.901.0 + "@aws-sdk/types": 3.901.0 + "@aws-sdk/util-endpoints": 3.901.0 + "@aws-sdk/util-user-agent-browser": 3.901.0 + "@aws-sdk/util-user-agent-node": 3.901.0 + "@smithy/config-resolver": ^4.3.0 + "@smithy/core": ^3.14.0 + "@smithy/fetch-http-handler": ^5.3.0 + "@smithy/hash-node": ^4.2.0 + "@smithy/invalid-dependency": ^4.2.0 + "@smithy/middleware-content-length": ^4.2.0 + "@smithy/middleware-endpoint": ^4.3.0 + "@smithy/middleware-retry": ^4.4.0 + "@smithy/middleware-serde": ^4.2.0 + "@smithy/middleware-stack": ^4.2.0 + "@smithy/node-config-provider": ^4.3.0 + "@smithy/node-http-handler": ^4.3.0 + "@smithy/protocol-http": ^5.3.0 + "@smithy/smithy-client": ^4.7.0 + "@smithy/types": ^4.6.0 + "@smithy/url-parser": ^4.2.0 + "@smithy/util-base64": ^4.2.0 "@smithy/util-body-length-browser": ^4.2.0 - "@smithy/util-body-length-node": ^4.2.1 - "@smithy/util-defaults-mode-browser": ^4.3.4 - "@smithy/util-defaults-mode-node": ^4.2.6 - "@smithy/util-endpoints": ^3.2.3 - "@smithy/util-middleware": ^4.2.3 - "@smithy/util-retry": ^4.2.3 + "@smithy/util-body-length-node": ^4.2.0 + "@smithy/util-defaults-mode-browser": ^4.2.0 + "@smithy/util-defaults-mode-node": ^4.2.0 + "@smithy/util-endpoints": ^3.2.0 + "@smithy/util-middleware": ^4.2.0 + "@smithy/util-retry": ^4.2.0 "@smithy/util-utf8": ^4.2.0 tslib: ^2.6.2 - checksum: 9ed34a2822a64a57331fd5c3c007d2d311453f9854f066adff8370e5c2e7235929680946394cbe55cfc590a58a816b4c3d86790c2a2420907be4ce0ab99028a3 + checksum: 82d987e33f0c4baa7e7412771ab0a3eac273502025388b2bef5d85f298cd1b66ef4f7d8e97d2a9b608a9771a48aba360ca6b993c8d6a71a8b5b5e58f998d85a8 languageName: node linkType: hard @@ -4147,6 +4459,52 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/client-sso@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/client-sso@npm:3.901.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.901.0 + "@aws-sdk/middleware-host-header": 3.901.0 + "@aws-sdk/middleware-logger": 3.901.0 + "@aws-sdk/middleware-recursion-detection": 3.901.0 + "@aws-sdk/middleware-user-agent": 3.901.0 + "@aws-sdk/region-config-resolver": 3.901.0 + "@aws-sdk/types": 3.901.0 + "@aws-sdk/util-endpoints": 3.901.0 + "@aws-sdk/util-user-agent-browser": 3.901.0 + "@aws-sdk/util-user-agent-node": 3.901.0 + "@smithy/config-resolver": ^4.3.0 + "@smithy/core": ^3.14.0 + "@smithy/fetch-http-handler": ^5.3.0 + "@smithy/hash-node": ^4.2.0 + "@smithy/invalid-dependency": ^4.2.0 + "@smithy/middleware-content-length": ^4.2.0 + "@smithy/middleware-endpoint": ^4.3.0 + "@smithy/middleware-retry": ^4.4.0 + "@smithy/middleware-serde": ^4.2.0 + "@smithy/middleware-stack": ^4.2.0 + "@smithy/node-config-provider": ^4.3.0 + "@smithy/node-http-handler": ^4.3.0 + "@smithy/protocol-http": ^5.3.0 + "@smithy/smithy-client": ^4.7.0 + "@smithy/types": ^4.6.0 + "@smithy/url-parser": ^4.2.0 + "@smithy/util-base64": ^4.2.0 + "@smithy/util-body-length-browser": ^4.2.0 + "@smithy/util-body-length-node": ^4.2.0 + "@smithy/util-defaults-mode-browser": ^4.2.0 + "@smithy/util-defaults-mode-node": ^4.2.0 + "@smithy/util-endpoints": ^3.2.0 + "@smithy/util-middleware": ^4.2.0 + "@smithy/util-retry": ^4.2.0 + "@smithy/util-utf8": ^4.2.0 + tslib: ^2.6.2 + checksum: b0a02868bf826411668c418c5fd8ab1225bff7dfc10587cebad400c027fb4a28174439eeb5b05bbed1eec167216ea492b3dfbea4b3c9a494a31e219c0abdd38c + languageName: node + linkType: hard + "@aws-sdk/client-sso@npm:3.919.0": version: 3.919.0 resolution: "@aws-sdk/client-sso@npm:3.919.0" @@ -4193,6 +4551,52 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/client-sso@npm:3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/client-sso@npm:3.920.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.920.0 + "@aws-sdk/middleware-host-header": 3.920.0 + "@aws-sdk/middleware-logger": 3.920.0 + "@aws-sdk/middleware-recursion-detection": 3.920.0 + "@aws-sdk/middleware-user-agent": 3.920.0 + "@aws-sdk/region-config-resolver": 3.920.0 + "@aws-sdk/types": 3.920.0 + "@aws-sdk/util-endpoints": 3.920.0 + "@aws-sdk/util-user-agent-browser": 3.920.0 + "@aws-sdk/util-user-agent-node": 3.920.0 + "@smithy/config-resolver": ^4.4.0 + "@smithy/core": ^3.17.1 + "@smithy/fetch-http-handler": ^5.3.4 + "@smithy/hash-node": ^4.2.3 + "@smithy/invalid-dependency": ^4.2.3 + "@smithy/middleware-content-length": ^4.2.3 + "@smithy/middleware-endpoint": ^4.3.5 + "@smithy/middleware-retry": ^4.4.5 + "@smithy/middleware-serde": ^4.2.3 + "@smithy/middleware-stack": ^4.2.3 + "@smithy/node-config-provider": ^4.3.3 + "@smithy/node-http-handler": ^4.4.3 + "@smithy/protocol-http": ^5.3.3 + "@smithy/smithy-client": ^4.9.1 + "@smithy/types": ^4.8.0 + "@smithy/url-parser": ^4.2.3 + "@smithy/util-base64": ^4.3.0 + "@smithy/util-body-length-browser": ^4.2.0 + "@smithy/util-body-length-node": ^4.2.1 + "@smithy/util-defaults-mode-browser": ^4.3.4 + "@smithy/util-defaults-mode-node": ^4.2.6 + "@smithy/util-endpoints": ^3.2.3 + "@smithy/util-middleware": ^4.2.3 + "@smithy/util-retry": ^4.2.3 + "@smithy/util-utf8": ^4.2.0 + tslib: ^2.6.2 + checksum: 099183cb26267ee5f8919d1b58aabb33020d0b9440859d5230c6d175035fb2fa51c7c9a4b0ea16c37c756a05fb3e88210839fe271fd02b77450cdca7b19c33e1 + languageName: node + linkType: hard + "@aws-sdk/client-sts@npm:3.186.3": version: 3.186.3 resolution: "@aws-sdk/client-sts@npm:3.186.3" @@ -4452,6 +4856,27 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/core@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/core@npm:3.901.0" + dependencies: + "@aws-sdk/types": 3.901.0 + "@aws-sdk/xml-builder": 3.901.0 + "@smithy/core": ^3.14.0 + "@smithy/node-config-provider": ^4.3.0 + "@smithy/property-provider": ^4.2.0 + "@smithy/protocol-http": ^5.3.0 + "@smithy/signature-v4": ^5.3.0 + "@smithy/smithy-client": ^4.7.0 + "@smithy/types": ^4.6.0 + "@smithy/util-base64": ^4.2.0 + "@smithy/util-middleware": ^4.2.0 + "@smithy/util-utf8": ^4.2.0 + tslib: ^2.6.2 + checksum: f86625938dedf959b2acbe89bb50e313f0996c59a4772593d57ef55f4023f492d5760b1dc7b9e4f4afa13e41e5cfd0a8b8d08df2f2e9d0347bc74d9d67515c14 + languageName: node + linkType: hard + "@aws-sdk/core@npm:3.916.0": version: 3.916.0 resolution: "@aws-sdk/core@npm:3.916.0" @@ -4473,6 +4898,27 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/core@npm:3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/core@npm:3.920.0" + dependencies: + "@aws-sdk/types": 3.920.0 + "@aws-sdk/xml-builder": 3.914.0 + "@smithy/core": ^3.17.1 + "@smithy/node-config-provider": ^4.3.3 + "@smithy/property-provider": ^4.2.3 + "@smithy/protocol-http": ^5.3.3 + "@smithy/signature-v4": ^5.3.3 + "@smithy/smithy-client": ^4.9.1 + "@smithy/types": ^4.8.0 + "@smithy/util-base64": ^4.3.0 + "@smithy/util-middleware": ^4.2.3 + "@smithy/util-utf8": ^4.2.0 + tslib: ^2.6.2 + checksum: ee9351a3bd87c33a3ecef9b1d016be8e213f139bc36a8ade7ea790f7620ab0584e08bae02b1389b5cf3b80dcfad288799914e155a4a5d371de70ba5ed232f838 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-cognito-identity@npm:3.919.0": version: 3.919.0 resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.919.0" @@ -4520,6 +4966,19 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-env@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.901.0" + dependencies: + "@aws-sdk/core": 3.901.0 + "@aws-sdk/types": 3.901.0 + "@smithy/property-provider": ^4.2.0 + "@smithy/types": ^4.6.0 + tslib: ^2.6.2 + checksum: e53ecdfa5fa96cf1129b38cde0b5a27c314863e612b8fac5fd9dedcd43a03c2a591deb4ab34f4316c0994480f438272660118ed77ddd591e2cc0dfed4dbde29e + languageName: node + linkType: hard + "@aws-sdk/credential-provider-env@npm:3.916.0": version: 3.916.0 resolution: "@aws-sdk/credential-provider-env@npm:3.916.0" @@ -4533,6 +4992,19 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-env@npm:3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.920.0" + dependencies: + "@aws-sdk/core": 3.920.0 + "@aws-sdk/types": 3.920.0 + "@smithy/property-provider": ^4.2.3 + "@smithy/types": ^4.8.0 + tslib: ^2.6.2 + checksum: 1238c4bb6c74b3bc1fef5ba64048851f89d1d6a1868f5c14e999d7c9d1758032f3071e7d7edfca77e4e2e40f3210690361224a056d41449ff0255a4d315bb502 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-http@npm:3.622.0": version: 3.622.0 resolution: "@aws-sdk/credential-provider-http@npm:3.622.0" @@ -4550,6 +5022,24 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-http@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.901.0" + dependencies: + "@aws-sdk/core": 3.901.0 + "@aws-sdk/types": 3.901.0 + "@smithy/fetch-http-handler": ^5.3.0 + "@smithy/node-http-handler": ^4.3.0 + "@smithy/property-provider": ^4.2.0 + "@smithy/protocol-http": ^5.3.0 + "@smithy/smithy-client": ^4.7.0 + "@smithy/types": ^4.6.0 + "@smithy/util-stream": ^4.4.0 + tslib: ^2.6.2 + checksum: 374398233aaab5de9be9802df00deeada0d420ffc2b6ed2f8fbcc2cd82aa4778dc22e7686ac995c41ae86774239f78418ddc5d2f6c57d0594a2eb1b0d886179e + languageName: node + linkType: hard + "@aws-sdk/credential-provider-http@npm:3.916.0": version: 3.916.0 resolution: "@aws-sdk/credential-provider-http@npm:3.916.0" @@ -4568,6 +5058,24 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-http@npm:3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.920.0" + dependencies: + "@aws-sdk/core": 3.920.0 + "@aws-sdk/types": 3.920.0 + "@smithy/fetch-http-handler": ^5.3.4 + "@smithy/node-http-handler": ^4.4.3 + "@smithy/property-provider": ^4.2.3 + "@smithy/protocol-http": ^5.3.3 + "@smithy/smithy-client": ^4.9.1 + "@smithy/types": ^4.8.0 + "@smithy/util-stream": ^4.5.4 + tslib: ^2.6.2 + checksum: 11ccc1ebc724c055282678a1c768cf49d0b3fbaecedb1f9278e9b5530f7024397f0b6578040e546165ab600578a0c3233a592b536ebcb2ecd22be180434883a2 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-imds@npm:3.186.0": version: 3.186.0 resolution: "@aws-sdk/credential-provider-imds@npm:3.186.0" @@ -4641,6 +5149,27 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-ini@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.901.0" + dependencies: + "@aws-sdk/core": 3.901.0 + "@aws-sdk/credential-provider-env": 3.901.0 + "@aws-sdk/credential-provider-http": 3.901.0 + "@aws-sdk/credential-provider-process": 3.901.0 + "@aws-sdk/credential-provider-sso": 3.901.0 + "@aws-sdk/credential-provider-web-identity": 3.901.0 + "@aws-sdk/nested-clients": 3.901.0 + "@aws-sdk/types": 3.901.0 + "@smithy/credential-provider-imds": ^4.2.0 + "@smithy/property-provider": ^4.2.0 + "@smithy/shared-ini-file-loader": ^4.3.0 + "@smithy/types": ^4.6.0 + tslib: ^2.6.2 + checksum: f3632c187db167912badc0013235592a874c2c8ef3c6d81b659b8873d9430914bef36556c786a9d8550d70926898dd9d305cafd5ae5ec572501d193fa263c1bb + languageName: node + linkType: hard + "@aws-sdk/credential-provider-ini@npm:3.919.0": version: 3.919.0 resolution: "@aws-sdk/credential-provider-ini@npm:3.919.0" @@ -4662,6 +5191,27 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-ini@npm:3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.920.0" + dependencies: + "@aws-sdk/core": 3.920.0 + "@aws-sdk/credential-provider-env": 3.920.0 + "@aws-sdk/credential-provider-http": 3.920.0 + "@aws-sdk/credential-provider-process": 3.920.0 + "@aws-sdk/credential-provider-sso": 3.920.0 + "@aws-sdk/credential-provider-web-identity": 3.920.0 + "@aws-sdk/nested-clients": 3.920.0 + "@aws-sdk/types": 3.920.0 + "@smithy/credential-provider-imds": ^4.2.3 + "@smithy/property-provider": ^4.2.3 + "@smithy/shared-ini-file-loader": ^4.3.3 + "@smithy/types": ^4.8.0 + tslib: ^2.6.2 + checksum: f5d4779080c1dcb4ca42f6ecc7ad21e66e3cda0a1c2bf66c000c481112c6984f095eb53dfa01bdfc09ff492d79509da98c3ec4949450e9a5de6f8af880816553 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-node@npm:3.186.0": version: 3.186.0 resolution: "@aws-sdk/credential-provider-node@npm:3.186.0" @@ -4716,7 +5266,27 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:3.919.0, @aws-sdk/credential-provider-node@npm:^3.919.0": +"@aws-sdk/credential-provider-node@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.901.0" + dependencies: + "@aws-sdk/credential-provider-env": 3.901.0 + "@aws-sdk/credential-provider-http": 3.901.0 + "@aws-sdk/credential-provider-ini": 3.901.0 + "@aws-sdk/credential-provider-process": 3.901.0 + "@aws-sdk/credential-provider-sso": 3.901.0 + "@aws-sdk/credential-provider-web-identity": 3.901.0 + "@aws-sdk/types": 3.901.0 + "@smithy/credential-provider-imds": ^4.2.0 + "@smithy/property-provider": ^4.2.0 + "@smithy/shared-ini-file-loader": ^4.3.0 + "@smithy/types": ^4.6.0 + tslib: ^2.6.2 + checksum: ae9965cb1bde4ddbfec5905158cdd385c165074c7af3626fc954e5dbc43f722438856c9a47779a49cf05b04939fc617800037bd0e3ab2848ded2a36ef5a4e72f + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-node@npm:3.919.0": version: 3.919.0 resolution: "@aws-sdk/credential-provider-node@npm:3.919.0" dependencies: @@ -4736,6 +5306,26 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-node@npm:3.920.0, @aws-sdk/credential-provider-node@npm:^3.919.0": + version: 3.920.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.920.0" + dependencies: + "@aws-sdk/credential-provider-env": 3.920.0 + "@aws-sdk/credential-provider-http": 3.920.0 + "@aws-sdk/credential-provider-ini": 3.920.0 + "@aws-sdk/credential-provider-process": 3.920.0 + "@aws-sdk/credential-provider-sso": 3.920.0 + "@aws-sdk/credential-provider-web-identity": 3.920.0 + "@aws-sdk/types": 3.920.0 + "@smithy/credential-provider-imds": ^4.2.3 + "@smithy/property-provider": ^4.2.3 + "@smithy/shared-ini-file-loader": ^4.3.3 + "@smithy/types": ^4.8.0 + tslib: ^2.6.2 + checksum: a69dbdaeeebff74ee08114905c6c7c933e53c52de39b16bb7f315fe45f7c73589d60fedc72915297ba99ccd8bb62ecc5b8d31c6cb1642383f771b78e496101c6 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-process@npm:3.186.0": version: 3.186.0 resolution: "@aws-sdk/credential-provider-process@npm:3.186.0" @@ -4774,6 +5364,20 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-process@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.901.0" + dependencies: + "@aws-sdk/core": 3.901.0 + "@aws-sdk/types": 3.901.0 + "@smithy/property-provider": ^4.2.0 + "@smithy/shared-ini-file-loader": ^4.3.0 + "@smithy/types": ^4.6.0 + tslib: ^2.6.2 + checksum: d920a1358c3a95778a78c1a01c066e2901d619e45cde8cb27a37d4f9727c72a3274df37167650e7ee0a7c2c6c0256cf322cb012123039bef7522b9029a3b9064 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-process@npm:3.916.0": version: 3.916.0 resolution: "@aws-sdk/credential-provider-process@npm:3.916.0" @@ -4788,6 +5392,20 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-process@npm:3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.920.0" + dependencies: + "@aws-sdk/core": 3.920.0 + "@aws-sdk/types": 3.920.0 + "@smithy/property-provider": ^4.2.3 + "@smithy/shared-ini-file-loader": ^4.3.3 + "@smithy/types": ^4.8.0 + tslib: ^2.6.2 + checksum: 60b71f62104b26caef892f24b53ea5f61f7cfa3a7121fd6c86715f9121c4c3e74ac5ef98691dc436f27891bd842ee9218c9af0a5dfccdc1bbfc2e404fdee6553 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-sso@npm:3.186.0": version: 3.186.0 resolution: "@aws-sdk/credential-provider-sso@npm:3.186.0" @@ -4816,6 +5434,22 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-sso@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.901.0" + dependencies: + "@aws-sdk/client-sso": 3.901.0 + "@aws-sdk/core": 3.901.0 + "@aws-sdk/token-providers": 3.901.0 + "@aws-sdk/types": 3.901.0 + "@smithy/property-provider": ^4.2.0 + "@smithy/shared-ini-file-loader": ^4.3.0 + "@smithy/types": ^4.6.0 + tslib: ^2.6.2 + checksum: b9795d0d685fa880cd177642a121c89ffe400ea2c1bc6be4bf2a634e4998230f63f15489cf1b0208482ad5ffb2d3cc8a59c563f2e09cd19f08d3e070a2839d8c + languageName: node + linkType: hard + "@aws-sdk/credential-provider-sso@npm:3.919.0": version: 3.919.0 resolution: "@aws-sdk/credential-provider-sso@npm:3.919.0" @@ -4832,6 +5466,22 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-sso@npm:3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.920.0" + dependencies: + "@aws-sdk/client-sso": 3.920.0 + "@aws-sdk/core": 3.920.0 + "@aws-sdk/token-providers": 3.920.0 + "@aws-sdk/types": 3.920.0 + "@smithy/property-provider": ^4.2.3 + "@smithy/shared-ini-file-loader": ^4.3.3 + "@smithy/types": ^4.8.0 + tslib: ^2.6.2 + checksum: 151653d16362a128f688a1cb99b83335f74837dbb1781d5eec023b49c891ee4b325a0c66fb720b0e07891933b86113f5cac62553c562b36819a38ad6dbe392fa + languageName: node + linkType: hard + "@aws-sdk/credential-provider-web-identity@npm:3.186.0": version: 3.186.0 resolution: "@aws-sdk/credential-provider-web-identity@npm:3.186.0" @@ -4857,6 +5507,21 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-web-identity@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.901.0" + dependencies: + "@aws-sdk/core": 3.901.0 + "@aws-sdk/nested-clients": 3.901.0 + "@aws-sdk/types": 3.901.0 + "@smithy/property-provider": ^4.2.0 + "@smithy/shared-ini-file-loader": ^4.3.0 + "@smithy/types": ^4.6.0 + tslib: ^2.6.2 + checksum: 5b7e1986d7c64d0082d0fbf060b76e5012416326df9c02f62e581759dfab669701de2f93d10d6b8e9b47520873359fecb7db88d3700a39851ff6c826c2bc8fa2 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-web-identity@npm:3.919.0": version: 3.919.0 resolution: "@aws-sdk/credential-provider-web-identity@npm:3.919.0" @@ -4872,6 +5537,21 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-web-identity@npm:3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.920.0" + dependencies: + "@aws-sdk/core": 3.920.0 + "@aws-sdk/nested-clients": 3.920.0 + "@aws-sdk/types": 3.920.0 + "@smithy/property-provider": ^4.2.3 + "@smithy/shared-ini-file-loader": ^4.3.3 + "@smithy/types": ^4.8.0 + tslib: ^2.6.2 + checksum: 7e7679c8c97e1ab46785f2011f38285a6227fca02d77715671618a7ad2398471302ab409b54125d009343de07a47efe1e208023c22e86dd7dbade89198ad223a + languageName: node + linkType: hard + "@aws-sdk/credential-providers@npm:^3.919.0": version: 3.919.0 resolution: "@aws-sdk/credential-providers@npm:3.919.0" @@ -5312,6 +5992,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-host-header@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.901.0" + dependencies: + "@aws-sdk/types": 3.901.0 + "@smithy/protocol-http": ^5.3.0 + "@smithy/types": ^4.6.0 + tslib: ^2.6.2 + checksum: f36cffb33532df97f7480a9a0705a0d3e874861b12e10d3b1713ef4f830e1d17e8568c3baff1c4c05ad681115af6e8e4f84d828a9834a9df8b6127fbc5af5f48 + languageName: node + linkType: hard + "@aws-sdk/middleware-host-header@npm:3.914.0": version: 3.914.0 resolution: "@aws-sdk/middleware-host-header@npm:3.914.0" @@ -5324,6 +6016,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-host-header@npm:3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.920.0" + dependencies: + "@aws-sdk/types": 3.920.0 + "@smithy/protocol-http": ^5.3.3 + "@smithy/types": ^4.8.0 + tslib: ^2.6.2 + checksum: 6118e3b5bf06d5ab60169175bfb564dc5dc9512b2478488281e2573cbf533754c13798fdb2bb08b9ed7a3d82b1a17f395b0ecba7497d9892660d2f0ee30ae143 + languageName: node + linkType: hard + "@aws-sdk/middleware-location-constraint@npm:3.914.0": version: 3.914.0 resolution: "@aws-sdk/middleware-location-constraint@npm:3.914.0" @@ -5366,6 +6070,17 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-logger@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/middleware-logger@npm:3.901.0" + dependencies: + "@aws-sdk/types": 3.901.0 + "@smithy/types": ^4.6.0 + tslib: ^2.6.2 + checksum: 6ad444c2d791d2f8158c1e5262cdc12591a41164f63c660eb8874d4f915f007001d152deb426874ff4d4b1326d5e6b18bbdfe3087fa6fdc9ce7c88ed6bb75997 + languageName: node + linkType: hard + "@aws-sdk/middleware-logger@npm:3.914.0": version: 3.914.0 resolution: "@aws-sdk/middleware-logger@npm:3.914.0" @@ -5377,6 +6092,17 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-logger@npm:3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/middleware-logger@npm:3.920.0" + dependencies: + "@aws-sdk/types": 3.920.0 + "@smithy/types": ^4.8.0 + tslib: ^2.6.2 + checksum: 10fe9fcec3a9fb64a08400457ca881f1023942021451f24bf3a6fa2d2faf7a6ab572b7e0314a6e02ff89bdfbad450ebd64e7308485a36542701c89be912983fc + languageName: node + linkType: hard + "@aws-sdk/middleware-recursion-detection@npm:3.186.0": version: 3.186.0 resolution: "@aws-sdk/middleware-recursion-detection@npm:3.186.0" @@ -5400,6 +6126,19 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-recursion-detection@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.901.0" + dependencies: + "@aws-sdk/types": 3.901.0 + "@aws/lambda-invoke-store": ^0.0.1 + "@smithy/protocol-http": ^5.3.0 + "@smithy/types": ^4.6.0 + tslib: ^2.6.2 + checksum: 428d2da0d4583c8b33e5c10153b5cfebf572962a11df7501c35b5361b9e39fc9ab7b8778484a8f29d521f1ba37865bf0a441650de7c539e707714d4321c13272 + languageName: node + linkType: hard + "@aws-sdk/middleware-recursion-detection@npm:3.919.0": version: 3.919.0 resolution: "@aws-sdk/middleware-recursion-detection@npm:3.919.0" @@ -5413,6 +6152,19 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-recursion-detection@npm:3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.920.0" + dependencies: + "@aws-sdk/types": 3.920.0 + "@aws/lambda-invoke-store": ^0.1.1 + "@smithy/protocol-http": ^5.3.3 + "@smithy/types": ^4.8.0 + tslib: ^2.6.2 + checksum: 89c58d7bb1d29b1079f6331b378c40d95924ea302c0b88a6d71601686b46c81f45fe8ced793adf016ab6030560ee7e93f7f3e4514bf4c1ff380418ae22e73ab9 + languageName: node + linkType: hard + "@aws-sdk/middleware-retry@npm:3.186.0": version: 3.186.0 resolution: "@aws-sdk/middleware-retry@npm:3.186.0" @@ -5657,6 +6409,21 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-user-agent@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.901.0" + dependencies: + "@aws-sdk/core": 3.901.0 + "@aws-sdk/types": 3.901.0 + "@aws-sdk/util-endpoints": 3.901.0 + "@smithy/core": ^3.14.0 + "@smithy/protocol-http": ^5.3.0 + "@smithy/types": ^4.6.0 + tslib: ^2.6.2 + checksum: 73d5913eca05799918c0119510d0a49b5c5b7626a098c5ff48954f1b7e42278b0fcfe589f06d2b79d1dec1c316647f4104228fb42d0e72932601b0fddc8ea142 + languageName: node + linkType: hard + "@aws-sdk/middleware-user-agent@npm:3.916.0": version: 3.916.0 resolution: "@aws-sdk/middleware-user-agent@npm:3.916.0" @@ -5672,6 +6439,67 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-user-agent@npm:3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.920.0" + dependencies: + "@aws-sdk/core": 3.920.0 + "@aws-sdk/types": 3.920.0 + "@aws-sdk/util-endpoints": 3.920.0 + "@smithy/core": ^3.17.1 + "@smithy/protocol-http": ^5.3.3 + "@smithy/types": ^4.8.0 + tslib: ^2.6.2 + checksum: 79a48c3efeaf6dbfb1906fd4767e51651f8b0ca534f26afd20f122c79514ba811fce1289356eb7ad757cc2a8dd4cfec3b965fc004f691ab16d46993eb0f47c97 + languageName: node + linkType: hard + +"@aws-sdk/nested-clients@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/nested-clients@npm:3.901.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.901.0 + "@aws-sdk/middleware-host-header": 3.901.0 + "@aws-sdk/middleware-logger": 3.901.0 + "@aws-sdk/middleware-recursion-detection": 3.901.0 + "@aws-sdk/middleware-user-agent": 3.901.0 + "@aws-sdk/region-config-resolver": 3.901.0 + "@aws-sdk/types": 3.901.0 + "@aws-sdk/util-endpoints": 3.901.0 + "@aws-sdk/util-user-agent-browser": 3.901.0 + "@aws-sdk/util-user-agent-node": 3.901.0 + "@smithy/config-resolver": ^4.3.0 + "@smithy/core": ^3.14.0 + "@smithy/fetch-http-handler": ^5.3.0 + "@smithy/hash-node": ^4.2.0 + "@smithy/invalid-dependency": ^4.2.0 + "@smithy/middleware-content-length": ^4.2.0 + "@smithy/middleware-endpoint": ^4.3.0 + "@smithy/middleware-retry": ^4.4.0 + "@smithy/middleware-serde": ^4.2.0 + "@smithy/middleware-stack": ^4.2.0 + "@smithy/node-config-provider": ^4.3.0 + "@smithy/node-http-handler": ^4.3.0 + "@smithy/protocol-http": ^5.3.0 + "@smithy/smithy-client": ^4.7.0 + "@smithy/types": ^4.6.0 + "@smithy/url-parser": ^4.2.0 + "@smithy/util-base64": ^4.2.0 + "@smithy/util-body-length-browser": ^4.2.0 + "@smithy/util-body-length-node": ^4.2.0 + "@smithy/util-defaults-mode-browser": ^4.2.0 + "@smithy/util-defaults-mode-node": ^4.2.0 + "@smithy/util-endpoints": ^3.2.0 + "@smithy/util-middleware": ^4.2.0 + "@smithy/util-retry": ^4.2.0 + "@smithy/util-utf8": ^4.2.0 + tslib: ^2.6.2 + checksum: 3b0211fbec00d3f2122270e70ff8a4dd2da510d9955655b5c8d39a49b9abd03e948d9f13e4db0329b941fd62cbd6c59043788d3ae1006ade4bfc225d2cec7caa + languageName: node + linkType: hard + "@aws-sdk/nested-clients@npm:3.919.0": version: 3.919.0 resolution: "@aws-sdk/nested-clients@npm:3.919.0" @@ -5718,6 +6546,52 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/nested-clients@npm:3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/nested-clients@npm:3.920.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.920.0 + "@aws-sdk/middleware-host-header": 3.920.0 + "@aws-sdk/middleware-logger": 3.920.0 + "@aws-sdk/middleware-recursion-detection": 3.920.0 + "@aws-sdk/middleware-user-agent": 3.920.0 + "@aws-sdk/region-config-resolver": 3.920.0 + "@aws-sdk/types": 3.920.0 + "@aws-sdk/util-endpoints": 3.920.0 + "@aws-sdk/util-user-agent-browser": 3.920.0 + "@aws-sdk/util-user-agent-node": 3.920.0 + "@smithy/config-resolver": ^4.4.0 + "@smithy/core": ^3.17.1 + "@smithy/fetch-http-handler": ^5.3.4 + "@smithy/hash-node": ^4.2.3 + "@smithy/invalid-dependency": ^4.2.3 + "@smithy/middleware-content-length": ^4.2.3 + "@smithy/middleware-endpoint": ^4.3.5 + "@smithy/middleware-retry": ^4.4.5 + "@smithy/middleware-serde": ^4.2.3 + "@smithy/middleware-stack": ^4.2.3 + "@smithy/node-config-provider": ^4.3.3 + "@smithy/node-http-handler": ^4.4.3 + "@smithy/protocol-http": ^5.3.3 + "@smithy/smithy-client": ^4.9.1 + "@smithy/types": ^4.8.0 + "@smithy/url-parser": ^4.2.3 + "@smithy/util-base64": ^4.3.0 + "@smithy/util-body-length-browser": ^4.2.0 + "@smithy/util-body-length-node": ^4.2.1 + "@smithy/util-defaults-mode-browser": ^4.3.4 + "@smithy/util-defaults-mode-node": ^4.2.6 + "@smithy/util-endpoints": ^3.2.3 + "@smithy/util-middleware": ^4.2.3 + "@smithy/util-retry": ^4.2.3 + "@smithy/util-utf8": ^4.2.0 + tslib: ^2.6.2 + checksum: 74a0920da726a94f9dd16e828fd46d8f7fd9c17ee4f4156dae711522df53d77477f813a8a1f8e94a28485840a3e863d42e360983f9ca10cf4b1dba717b02224e + languageName: node + linkType: hard + "@aws-sdk/node-config-provider@npm:3.186.0": version: 3.186.0 resolution: "@aws-sdk/node-config-provider@npm:3.186.0" @@ -5864,6 +6738,20 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/region-config-resolver@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.901.0" + dependencies: + "@aws-sdk/types": 3.901.0 + "@smithy/node-config-provider": ^4.3.0 + "@smithy/types": ^4.6.0 + "@smithy/util-config-provider": ^4.2.0 + "@smithy/util-middleware": ^4.2.0 + tslib: ^2.6.2 + checksum: a01f85908e38ea43cd6e69dcb2c33916cf2a8de3e7f0baa004e218317e3f331829746f17bcc2f79c4fc7ae7c9ff0716b30986618bd776800ee8d1b535f3849d7 + languageName: node + linkType: hard + "@aws-sdk/region-config-resolver@npm:3.914.0": version: 3.914.0 resolution: "@aws-sdk/region-config-resolver@npm:3.914.0" @@ -5876,6 +6764,19 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/region-config-resolver@npm:3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.920.0" + dependencies: + "@aws-sdk/types": 3.920.0 + "@smithy/config-resolver": ^4.4.0 + "@smithy/node-config-provider": ^4.3.3 + "@smithy/types": ^4.8.0 + tslib: ^2.6.2 + checksum: 0e0520491ec0f83042234580ca01b68671df9c736b55d378397119c1219d54058cc4eb8c6fab4215f7ecbdd1584cf5b852d72af489ccf938c22175eb8573545a + languageName: node + linkType: hard + "@aws-sdk/s3-request-presigner@npm:^3.919.0": version: 3.919.0 resolution: "@aws-sdk/s3-request-presigner@npm:3.919.0" @@ -6003,6 +6904,21 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/token-providers@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/token-providers@npm:3.901.0" + dependencies: + "@aws-sdk/core": 3.901.0 + "@aws-sdk/nested-clients": 3.901.0 + "@aws-sdk/types": 3.901.0 + "@smithy/property-provider": ^4.2.0 + "@smithy/shared-ini-file-loader": ^4.3.0 + "@smithy/types": ^4.6.0 + tslib: ^2.6.2 + checksum: d2f7adcc927d34fa63789061e6f0dfc817da7d8d116050d59fcd9cc7cef1b1db25cb03f7e631d464f6a95d6273be6e7c2105d66f2ec7948c5362f01f075d8a01 + languageName: node + linkType: hard + "@aws-sdk/token-providers@npm:3.919.0": version: 3.919.0 resolution: "@aws-sdk/token-providers@npm:3.919.0" @@ -6018,6 +6934,21 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/token-providers@npm:3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/token-providers@npm:3.920.0" + dependencies: + "@aws-sdk/core": 3.920.0 + "@aws-sdk/nested-clients": 3.920.0 + "@aws-sdk/types": 3.920.0 + "@smithy/property-provider": ^4.2.3 + "@smithy/shared-ini-file-loader": ^4.3.3 + "@smithy/types": ^4.8.0 + tslib: ^2.6.2 + checksum: 590a9d5fa5e5f2fb587594f96ccd0af663c82d086db1dbacc1c395af72545e3990c9dbe19c70748267c393e4c139edeb108c7bea45fa4c6e605dde8f9e5c2aba + languageName: node + linkType: hard + "@aws-sdk/types@npm:3.186.0": version: 3.186.0 resolution: "@aws-sdk/types@npm:3.186.0" @@ -6051,7 +6982,17 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:3.914.0, @aws-sdk/types@npm:^3.1.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.25.0, @aws-sdk/types@npm:^3.914.0": +"@aws-sdk/types@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/types@npm:3.901.0" + dependencies: + "@smithy/types": ^4.6.0 + tslib: ^2.6.2 + checksum: 38f1b7dac82b0e53faf764d0e741e32385c1e022b67c73d601fe3fd0f66d1a75d72dddd8f41dde89944441df766217f00a451a6d95caa256bebe08891206d949 + languageName: node + linkType: hard + +"@aws-sdk/types@npm:3.914.0": version: 3.914.0 resolution: "@aws-sdk/types@npm:3.914.0" dependencies: @@ -6061,6 +7002,16 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/types@npm:3.920.0, @aws-sdk/types@npm:^3.1.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.25.0, @aws-sdk/types@npm:^3.914.0": + version: 3.920.0 + resolution: "@aws-sdk/types@npm:3.920.0" + dependencies: + "@smithy/types": ^4.8.0 + tslib: ^2.6.2 + checksum: 7f8db5b6cf6c4d5d6237227dc53a483b03053d648b211c48524f71a3a6261a51e13bdf4b03bc1f4f1543020d7720c5f60c732195a1fccc6058501c0c6644e1c2 + languageName: node + linkType: hard + "@aws-sdk/url-parser-native@npm:3.6.1": version: 3.6.1 resolution: "@aws-sdk/url-parser-native@npm:3.6.1" @@ -6266,6 +7217,19 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-endpoints@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/util-endpoints@npm:3.901.0" + dependencies: + "@aws-sdk/types": 3.901.0 + "@smithy/types": ^4.6.0 + "@smithy/url-parser": ^4.2.0 + "@smithy/util-endpoints": ^3.2.0 + tslib: ^2.6.2 + checksum: ae6a2b15975e1b4e36211c30ff7ea2ac080bb5add13a7e5181b348bc393a74f82b6c5afb998c8dde9aedfe97eae23e0ce64da79cbd2b4061c594d1bd3d9d4a65 + languageName: node + linkType: hard + "@aws-sdk/util-endpoints@npm:3.916.0": version: 3.916.0 resolution: "@aws-sdk/util-endpoints@npm:3.916.0" @@ -6279,6 +7243,19 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-endpoints@npm:3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/util-endpoints@npm:3.920.0" + dependencies: + "@aws-sdk/types": 3.920.0 + "@smithy/types": ^4.8.0 + "@smithy/url-parser": ^4.2.3 + "@smithy/util-endpoints": ^3.2.3 + tslib: ^2.6.2 + checksum: 3df5578455b9c99339e7d5912a9d4fdd6c62d17a972c187068968d55e14ea1f69a3c173f764dd2fdb4e75c89d3614f25bbdb703c8a7d7db9042d6913479071cf + languageName: node + linkType: hard + "@aws-sdk/util-format-url@npm:3.609.0": version: 3.609.0 resolution: "@aws-sdk/util-format-url@npm:3.609.0" @@ -6400,6 +7377,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-user-agent-browser@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.901.0" + dependencies: + "@aws-sdk/types": 3.901.0 + "@smithy/types": ^4.6.0 + bowser: ^2.11.0 + tslib: ^2.6.2 + checksum: e389467f5d9d671902e11c4cf09d4d5f8fa1ced1af6c0d0a61c06afb487e13170ec05a40667c2b1b9d353e518b9d5064a82c2d2db4247e75f3619bac765f9a95 + languageName: node + linkType: hard + "@aws-sdk/util-user-agent-browser@npm:3.914.0": version: 3.914.0 resolution: "@aws-sdk/util-user-agent-browser@npm:3.914.0" @@ -6412,6 +7401,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-user-agent-browser@npm:3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.920.0" + dependencies: + "@aws-sdk/types": 3.920.0 + "@smithy/types": ^4.8.0 + bowser: ^2.11.0 + tslib: ^2.6.2 + checksum: 90ca6872a71162eda3b8b489aeafdb6b03ca75d72b31745d4e45c26d3e4a9296301ca056e5a14cf059e52a98f055ce94cfee80cff67c35f54e5831642484736f + languageName: node + linkType: hard + "@aws-sdk/util-user-agent-node@npm:3.186.0": version: 3.186.0 resolution: "@aws-sdk/util-user-agent-node@npm:3.186.0" @@ -6456,6 +7457,24 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-user-agent-node@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.901.0" + dependencies: + "@aws-sdk/middleware-user-agent": 3.901.0 + "@aws-sdk/types": 3.901.0 + "@smithy/node-config-provider": ^4.3.0 + "@smithy/types": ^4.6.0 + tslib: ^2.6.2 + peerDependencies: + aws-crt: ">=1.0.0" + peerDependenciesMeta: + aws-crt: + optional: true + checksum: d18c815bb04186ca4950abaf846d9998afaf4399380c2b6de351cc7d45733fabcd681d3cdc90eca40ce3a574d1d80652817d0d8e292e68710a9aab5d9dc7bd64 + languageName: node + linkType: hard + "@aws-sdk/util-user-agent-node@npm:3.916.0": version: 3.916.0 resolution: "@aws-sdk/util-user-agent-node@npm:3.916.0" @@ -6474,6 +7493,24 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-user-agent-node@npm:3.920.0": + version: 3.920.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.920.0" + dependencies: + "@aws-sdk/middleware-user-agent": 3.920.0 + "@aws-sdk/types": 3.920.0 + "@smithy/node-config-provider": ^4.3.3 + "@smithy/types": ^4.8.0 + tslib: ^2.6.2 + peerDependencies: + aws-crt: ">=1.0.0" + peerDependenciesMeta: + aws-crt: + optional: true + checksum: 0b3cdda09d724a3386033ffe3c31d4657cd3842651a3ac44f240f118a3064ed371f61c267f04a0e3e67b09e5172012796a9966c0015cf2f56e9f3f8b19a45100 + languageName: node + linkType: hard + "@aws-sdk/util-utf8-browser@npm:3.186.0, @aws-sdk/util-utf8-browser@npm:^3.0.0": version: 3.186.0 resolution: "@aws-sdk/util-utf8-browser@npm:3.186.0" @@ -6533,6 +7570,17 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/xml-builder@npm:3.901.0": + version: 3.901.0 + resolution: "@aws-sdk/xml-builder@npm:3.901.0" + dependencies: + "@smithy/types": ^4.6.0 + fast-xml-parser: 5.2.5 + tslib: ^2.6.2 + checksum: 407af75a7ea2d2d27021d54bfb59d53b3fd2f068234ade97b3b158ff6f753f85a0effa0d765c48b377a5b73194e1908f68f2959fb77e871e9137a8650b2caeef + languageName: node + linkType: hard + "@aws-sdk/xml-builder@npm:3.914.0": version: 3.914.0 resolution: "@aws-sdk/xml-builder@npm:3.914.0" @@ -6544,6 +7592,13 @@ __metadata: languageName: node linkType: hard +"@aws/lambda-invoke-store@npm:^0.0.1": + version: 0.0.1 + resolution: "@aws/lambda-invoke-store@npm:0.0.1" + checksum: 0bbf3060014a462177fb743e132e9b106a6743ad9cd905df4bd26e9ca8bfe2cc90473b03a79938fa908934e45e43f366f57af56a697991abda71d9ac92f5018f + languageName: node + linkType: hard + "@aws/lambda-invoke-store@npm:^0.1.1": version: 0.1.1 resolution: "@aws/lambda-invoke-store@npm:0.1.1" @@ -10663,7 +11718,7 @@ __metadata: languageName: node linkType: hard -"@smithy/config-resolver@npm:^4.4.0": +"@smithy/config-resolver@npm:^4.3.0, @smithy/config-resolver@npm:^4.4.0": version: 4.4.0 resolution: "@smithy/config-resolver@npm:4.4.0" dependencies: @@ -10693,7 +11748,7 @@ __metadata: languageName: node linkType: hard -"@smithy/core@npm:^3.17.1": +"@smithy/core@npm:^3.14.0, @smithy/core@npm:^3.17.1": version: 3.17.1 resolution: "@smithy/core@npm:3.17.1" dependencies: @@ -10724,7 +11779,7 @@ __metadata: languageName: node linkType: hard -"@smithy/credential-provider-imds@npm:^4.2.3": +"@smithy/credential-provider-imds@npm:^4.2.0, @smithy/credential-provider-imds@npm:^4.2.3": version: 4.2.3 resolution: "@smithy/credential-provider-imds@npm:4.2.3" dependencies: @@ -10873,7 +11928,7 @@ __metadata: languageName: node linkType: hard -"@smithy/fetch-http-handler@npm:^5.3.4": +"@smithy/fetch-http-handler@npm:^5.3.0, @smithy/fetch-http-handler@npm:^5.3.4": version: 5.3.4 resolution: "@smithy/fetch-http-handler@npm:5.3.4" dependencies: @@ -10910,7 +11965,7 @@ __metadata: languageName: node linkType: hard -"@smithy/hash-node@npm:^4.2.3": +"@smithy/hash-node@npm:^4.2.0, @smithy/hash-node@npm:^4.2.3": version: 4.2.3 resolution: "@smithy/hash-node@npm:4.2.3" dependencies: @@ -10943,7 +11998,7 @@ __metadata: languageName: node linkType: hard -"@smithy/invalid-dependency@npm:^4.2.3": +"@smithy/invalid-dependency@npm:^4.2.0, @smithy/invalid-dependency@npm:^4.2.3": version: 4.2.3 resolution: "@smithy/invalid-dependency@npm:4.2.3" dependencies: @@ -11002,7 +12057,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-content-length@npm:^4.2.3": +"@smithy/middleware-content-length@npm:^4.2.0, @smithy/middleware-content-length@npm:^4.2.3": version: 4.2.3 resolution: "@smithy/middleware-content-length@npm:4.2.3" dependencies: @@ -11029,7 +12084,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-endpoint@npm:^4.3.5": +"@smithy/middleware-endpoint@npm:^4.3.0, @smithy/middleware-endpoint@npm:^4.3.5": version: 4.3.5 resolution: "@smithy/middleware-endpoint@npm:4.3.5" dependencies: @@ -11062,7 +12117,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-retry@npm:^4.4.5": +"@smithy/middleware-retry@npm:^4.4.0, @smithy/middleware-retry@npm:^4.4.5": version: 4.4.5 resolution: "@smithy/middleware-retry@npm:4.4.5" dependencies: @@ -11089,7 +12144,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-serde@npm:^4.2.3": +"@smithy/middleware-serde@npm:^4.2.0, @smithy/middleware-serde@npm:^4.2.3": version: 4.2.3 resolution: "@smithy/middleware-serde@npm:4.2.3" dependencies: @@ -11110,7 +12165,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-stack@npm:^4.2.3": +"@smithy/middleware-stack@npm:^4.2.0, @smithy/middleware-stack@npm:^4.2.3": version: 4.2.3 resolution: "@smithy/middleware-stack@npm:4.2.3" dependencies: @@ -11132,7 +12187,7 @@ __metadata: languageName: node linkType: hard -"@smithy/node-config-provider@npm:^4.3.3": +"@smithy/node-config-provider@npm:^4.3.0, @smithy/node-config-provider@npm:^4.3.3": version: 4.3.3 resolution: "@smithy/node-config-provider@npm:4.3.3" dependencies: @@ -11157,7 +12212,7 @@ __metadata: languageName: node linkType: hard -"@smithy/node-http-handler@npm:^4.4.3": +"@smithy/node-http-handler@npm:^4.3.0, @smithy/node-http-handler@npm:^4.4.3": version: 4.4.3 resolution: "@smithy/node-http-handler@npm:4.4.3" dependencies: @@ -11180,7 +12235,7 @@ __metadata: languageName: node linkType: hard -"@smithy/property-provider@npm:^4.2.3": +"@smithy/property-provider@npm:^4.2.0, @smithy/property-provider@npm:^4.2.3": version: 4.2.3 resolution: "@smithy/property-provider@npm:4.2.3" dependencies: @@ -11200,7 +12255,7 @@ __metadata: languageName: node linkType: hard -"@smithy/protocol-http@npm:^5.3.3": +"@smithy/protocol-http@npm:^5.3.0, @smithy/protocol-http@npm:^5.3.3": version: 5.3.3 resolution: "@smithy/protocol-http@npm:5.3.3" dependencies: @@ -11280,7 +12335,7 @@ __metadata: languageName: node linkType: hard -"@smithy/shared-ini-file-loader@npm:^4.3.3": +"@smithy/shared-ini-file-loader@npm:^4.3.0, @smithy/shared-ini-file-loader@npm:^4.3.3": version: 4.3.3 resolution: "@smithy/shared-ini-file-loader@npm:4.3.3" dependencies: @@ -11306,7 +12361,7 @@ __metadata: languageName: node linkType: hard -"@smithy/signature-v4@npm:^5.3.3": +"@smithy/signature-v4@npm:^5.3.0, @smithy/signature-v4@npm:^5.3.3": version: 5.3.3 resolution: "@smithy/signature-v4@npm:5.3.3" dependencies: @@ -11337,7 +12392,7 @@ __metadata: languageName: node linkType: hard -"@smithy/smithy-client@npm:^4.9.1": +"@smithy/smithy-client@npm:^4.7.0, @smithy/smithy-client@npm:^4.9.1": version: 4.9.1 resolution: "@smithy/smithy-client@npm:4.9.1" dependencies: @@ -11361,7 +12416,7 @@ __metadata: languageName: node linkType: hard -"@smithy/types@npm:^4.8.0": +"@smithy/types@npm:^4.6.0, @smithy/types@npm:^4.8.0": version: 4.8.0 resolution: "@smithy/types@npm:4.8.0" dependencies: @@ -11381,7 +12436,7 @@ __metadata: languageName: node linkType: hard -"@smithy/url-parser@npm:^4.2.3": +"@smithy/url-parser@npm:^4.2.0, @smithy/url-parser@npm:^4.2.3": version: 4.2.3 resolution: "@smithy/url-parser@npm:4.2.3" dependencies: @@ -11403,7 +12458,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-base64@npm:^4.3.0": +"@smithy/util-base64@npm:^4.2.0, @smithy/util-base64@npm:^4.3.0": version: 4.3.0 resolution: "@smithy/util-base64@npm:4.3.0" dependencies: @@ -11441,7 +12496,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-body-length-node@npm:^4.2.1": +"@smithy/util-body-length-node@npm:^4.2.0, @smithy/util-body-length-node@npm:^4.2.1": version: 4.2.1 resolution: "@smithy/util-body-length-node@npm:4.2.1" dependencies: @@ -11511,7 +12566,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-browser@npm:^4.3.4": +"@smithy/util-defaults-mode-browser@npm:^4.2.0, @smithy/util-defaults-mode-browser@npm:^4.3.4": version: 4.3.4 resolution: "@smithy/util-defaults-mode-browser@npm:4.3.4" dependencies: @@ -11538,7 +12593,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-node@npm:^4.2.6": +"@smithy/util-defaults-mode-node@npm:^4.2.0, @smithy/util-defaults-mode-node@npm:^4.2.6": version: 4.2.6 resolution: "@smithy/util-defaults-mode-node@npm:4.2.6" dependencies: @@ -11564,7 +12619,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-endpoints@npm:^3.2.3": +"@smithy/util-endpoints@npm:^3.2.0, @smithy/util-endpoints@npm:^3.2.3": version: 3.2.3 resolution: "@smithy/util-endpoints@npm:3.2.3" dependencies: @@ -11603,7 +12658,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-middleware@npm:^4.2.3": +"@smithy/util-middleware@npm:^4.2.0, @smithy/util-middleware@npm:^4.2.3": version: 4.2.3 resolution: "@smithy/util-middleware@npm:4.2.3" dependencies: @@ -11624,7 +12679,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-retry@npm:^4.2.3": +"@smithy/util-retry@npm:^4.2.0, @smithy/util-retry@npm:^4.2.3": version: 4.2.3 resolution: "@smithy/util-retry@npm:4.2.3" dependencies: @@ -11651,7 +12706,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-stream@npm:^4.5.4": +"@smithy/util-stream@npm:^4.4.0, @smithy/util-stream@npm:^4.5.4": version: 4.5.4 resolution: "@smithy/util-stream@npm:4.5.4" dependencies: @@ -13914,10 +14969,22 @@ __metadata: "@aws-amplify/amplify-e2e-core": 5.7.6 "@aws-amplify/amplify-opensearch-simulator": 1.7.22 "@aws-amplify/graphql-transformer-core": ^2.11.2 + "@aws-sdk/client-amplify": ^3.919.0 + "@aws-sdk/client-amplifyuibuilder": ^3.919.0 "@aws-sdk/client-appsync": ^3.919.0 + "@aws-sdk/client-cloudformation": ^3.919.0 + "@aws-sdk/client-cloudfront": ^3.919.0 + "@aws-sdk/client-codebuild": ^3.919.0 + "@aws-sdk/client-cognito-identity-provider": ^3.919.0 "@aws-sdk/client-dynamodb": ^3.919.0 + "@aws-sdk/client-iam": ^3.919.0 + "@aws-sdk/client-organizations": ^3.920.0 + "@aws-sdk/client-pinpoint": 3.901.0 "@aws-sdk/client-s3": ^3.919.0 "@aws-sdk/client-ssm": ^3.919.0 + "@aws-sdk/client-sts": ^3.919.0 + "@aws-sdk/credential-providers": ^3.919.0 + "@aws-sdk/lib-storage": ^3.919.0 "@babel/core": ^7.23.2 "@babel/plugin-transform-modules-commonjs": 7.10.4 "@types/body-parser": ^1.19.2 @@ -13932,7 +14999,6 @@ __metadata: aws-amplify: ^5.3.16 aws-appsync: ^4.1.1 aws-cdk-lib: ~2.189.1 - aws-sdk: ^2.1464.0 axios: ^1.11.0 constructs: ^10.0.5 dotenv: ^8.2.0