diff --git a/.eslint-dictionary.json b/.eslint-dictionary.json index e662b50e813..0281e5f4f08 100644 --- a/.eslint-dictionary.json +++ b/.eslint-dictionary.json @@ -265,6 +265,7 @@ "multifactor", "multipart", "mutex", + "mygen2app", "namespace", "netcoreapp", "netmask", diff --git a/packages/amplify-migration-codegen-e2e/src/__tests__/migration_codegen_e2e.test.ts b/packages/amplify-migration-codegen-e2e/src/__tests__/migration_codegen_e2e.test.ts index 900069fcaef..c82068a8650 100644 --- a/packages/amplify-migration-codegen-e2e/src/__tests__/migration_codegen_e2e.test.ts +++ b/packages/amplify-migration-codegen-e2e/src/__tests__/migration_codegen_e2e.test.ts @@ -1,41 +1,51 @@ import path from 'node:path'; import assert from 'node:assert'; import { createNewProjectDir } from '@aws-amplify/amplify-e2e-core'; -import { - cleanupProjects, - setupAndPushGen1Project, - assertGen1Setup, - runCodegenCommand, - runGen2SandboxCommand, - assertUserPoolResource, - assertStorageResource, - assertFunctionResource, - assertDataResource, - copyFunctionFile, - copyGen1Schema, -} from '../helpers'; +import { createGen2Renderer } from '@aws-amplify/amplify-gen2-codegen'; +import { copyFunctionFile } from '../function-utils'; +import { copyGen1Schema } from '../api-utils'; +import { cleanupProjects, setupAndPushGen1Project, runCodegenCommand, runGen2SandboxCommand } from '..'; +import { assertGen1Setup, assertUserPoolResource, assertStorageResource, assertFunctionResource, assertDataResource } from '../assertions'; -void describe('Migration Codegen E2E tests', () => { - let projRoot: string; - beforeEach(async () => { - const baseDir = process.env.INIT_CWD ?? process.cwd(); - projRoot = await createNewProjectDir('codegen_e2e_flow_test', path.join(baseDir, '..', '..')); +void describe('Codegen E2E tests', () => { + void describe('render pipeline', () => { + void it('renders a project with no parameters', async () => { + const pipeline = createGen2Renderer({ + outputDir: path.join(process.env.INIT_CWD ?? './', 'output'), + auth: { + loginOptions: { + email: true, + }, + }, + }); + await assert.doesNotReject(pipeline.render); + }); }); + void describe('Full Migration Codegen Flow', () => { + let projRoot: string; + let projName: string; - afterEach(async () => { - await cleanupProjects(projRoot); - }); + beforeEach(async () => { + const baseDir = process.env.INIT_CWD ?? process.cwd(); + projRoot = await createNewProjectDir('codegen_e2e_flow_test', path.join(baseDir, '..', '..')); + projName = `test${Math.floor(Math.random() * 1000000)}`; + }); + + afterEach(async () => { + await cleanupProjects(projRoot); + }); - void it('performs full migration codegen flow with backend', async () => { - await setupAndPushGen1Project(projRoot, 'CodegenTest'); - const { gen1UserPoolId, gen1FunctionName, gen1BucketName, gen1GraphQLAPIId, gen1Region } = await assertGen1Setup(projRoot); - await assert.doesNotReject(runCodegenCommand(projRoot), 'Codegen failed'); - await copyFunctionFile(projRoot, gen1FunctionName); - await copyGen1Schema(projRoot); - await assert.doesNotReject(runGen2SandboxCommand(projRoot), 'Gen2 CDK deployment failed'); - await assertUserPoolResource(projRoot, gen1UserPoolId, gen1Region); - await assertStorageResource(projRoot, gen1BucketName, gen1Region); - await assertFunctionResource(projRoot, gen1FunctionName, gen1Region); - await assertDataResource(projRoot, gen1GraphQLAPIId, gen1Region); + void it('should init a project & add auth, function, storage, api with defaults & perform full migration codegen flow', async () => { + await setupAndPushGen1Project(projRoot, projName); + const { gen1UserPoolId, gen1FunctionName, gen1BucketName, gen1GraphqlApiId, gen1Region } = await assertGen1Setup(projRoot); + await assert.doesNotReject(runCodegenCommand(projRoot), 'Codegen failed'); + await copyFunctionFile(projRoot, gen1FunctionName); + await copyGen1Schema(projRoot, projName); + const gen2StackName = await runGen2SandboxCommand(projRoot); + await assertUserPoolResource(projRoot, gen1UserPoolId, gen1Region); + await assertStorageResource(projRoot, gen1BucketName, gen1Region); + await assertFunctionResource(projRoot, gen2StackName, gen1FunctionName, gen1Region); + await assertDataResource(projRoot, gen2StackName, gen1GraphqlApiId, gen1Region); + }); }); }); diff --git a/packages/amplify-migration-codegen-e2e/src/__tests__/render_backend.test.ts b/packages/amplify-migration-codegen-e2e/src/__tests__/render_backend.test.ts deleted file mode 100644 index 491bf7df849..00000000000 --- a/packages/amplify-migration-codegen-e2e/src/__tests__/render_backend.test.ts +++ /dev/null @@ -1,19 +0,0 @@ -import path from 'node:path'; -import assert from 'node:assert'; -import { createGen2Renderer } from '@aws-amplify/amplify-gen2-codegen'; - -void describe('Codegen e2e tests', () => { - void describe('render pipeline', () => { - void it('renders a project with no parameters', async () => { - const pipeline = createGen2Renderer({ - outputDir: path.join(process.env.INIT_CWD ?? './', 'output'), - auth: { - loginOptions: { - email: true, - }, - }, - }); - await assert.doesNotReject(pipeline.render); - }); - }); -}); diff --git a/packages/amplify-migration-codegen-e2e/src/api-utils.ts b/packages/amplify-migration-codegen-e2e/src/api-utils.ts new file mode 100644 index 00000000000..80fa69dd8e1 --- /dev/null +++ b/packages/amplify-migration-codegen-e2e/src/api-utils.ts @@ -0,0 +1,29 @@ +import { getProjectSchema } from '@aws-amplify/amplify-e2e-core'; +import * as fs from 'fs-extra'; +import path from 'node:path'; + +export function copyGen1Schema(projRoot: string, projName: string) { + const gen1Schema = getProjectSchema(path.join(projRoot, '.amplify', 'migration'), projName); + + const dataResourcePath = path.join(projRoot, 'amplify', 'data', 'resource.ts'); + const dataResourceContent = fs.readFileSync(dataResourcePath, 'utf-8'); + + const backendPath = path.join(projRoot, 'amplify', 'backend.ts'); + let backendContent = fs.readFileSync(backendPath, 'utf-8'); + + const schemaRegex = /"TODO: Add your existing graphql schema here"/; + const updatedContent = dataResourceContent.replace(schemaRegex, `\`${gen1Schema.trim()}\``); + + const errorRegex = /throw new Error\("TODO: Add Gen 1 GraphQL schema"\);?\s*/; + const finalContent = updatedContent.replace(errorRegex, ''); + + fs.writeFileSync(dataResourcePath, finalContent, 'utf-8'); + + const linesToAdd = ` + const todoTable = backend.data.resources.cfnResources.additionalCfnResources['Todo']; + todoTable.addOverride('Properties.sseSpecification', { sseEnabled: false }); + `; + + backendContent += linesToAdd; + fs.writeFileSync(backendPath, backendContent, 'utf-8'); +} diff --git a/packages/amplify-migration-codegen-e2e/src/assertions.ts b/packages/amplify-migration-codegen-e2e/src/assertions.ts new file mode 100644 index 00000000000..82d0d6a9690 --- /dev/null +++ b/packages/amplify-migration-codegen-e2e/src/assertions.ts @@ -0,0 +1,147 @@ +import { + getProjectMeta, + getUserPool, + checkIfBucketExists, + getFunction, + getAppSyncApi, + describeCloudFormationStack, +} from '@aws-amplify/amplify-e2e-core'; +import { getProjectOutputs } from './projectOutputs'; +import { getAppSyncDataSource, getResourceDetails } from './sdk-calls'; +import { removeProperties } from '.'; + +export async function assertGen1Setup(projRoot: string) { + const gen1Meta = getProjectMeta(projRoot); + const gen1Region = gen1Meta.providers.awscloudformation.Region; + const { UserPoolId: gen1UserPoolId } = Object.keys(gen1Meta.auth).map((key) => gen1Meta.auth[key])[0].output; + const { Arn: gen1FunctionArn, Name: gen1FunctionName } = Object.keys(gen1Meta.function).map((key) => gen1Meta.function[key])[0].output; + const { BucketName: gen1BucketName } = Object.keys(gen1Meta.storage).map((key) => gen1Meta.storage[key])[0].output; + const { + GraphQLAPIIdOutput: gen1GraphqlApiId, + GraphQLAPIEndpointOutput, + GraphQLAPIKeyOutput, + } = Object.keys(gen1Meta.api).map((key) => gen1Meta.api[key])[0].output; + const { graphqlApi } = await getAppSyncApi(gen1GraphqlApiId, gen1Region); + + expect(gen1Region).toBeDefined(); + + const cloudUserPool = await getUserPool(gen1UserPoolId, gen1Region); + expect(cloudUserPool.UserPool).toBeDefined(); + + expect(gen1FunctionArn).toBeDefined(); + expect(gen1FunctionName).toBeDefined(); + const cloudFunction = await getFunction(gen1FunctionName, gen1Region); + expect(cloudFunction.Configuration?.FunctionArn).toEqual(gen1FunctionArn); + + expect(gen1BucketName).toBeDefined(); + const bucketExists = await checkIfBucketExists(gen1BucketName, gen1Region); + expect(bucketExists).toMatchObject({}); + + expect(gen1GraphqlApiId).toBeDefined(); + expect(GraphQLAPIEndpointOutput).toBeDefined(); + expect(GraphQLAPIKeyOutput).toBeDefined(); + + expect(graphqlApi).toBeDefined(); + expect(graphqlApi?.apiId).toEqual(gen1GraphqlApiId); + return { gen1UserPoolId, gen1FunctionName, gen1BucketName, gen1GraphqlApiId, gen1Region }; +} + +export async function assertUserPoolResource(projRoot: string, gen1UserPoolId: string, gen1Region: string) { + const gen1Resource = await getResourceDetails('AWS::Cognito::UserPool', gen1UserPoolId, gen1Region); + removeProperties(gen1Resource, ['ProviderURL', 'ProviderName', 'UserPoolId', 'Arn']); + // TODO: remove below line after EmailMessage, EmailSubject, SmsMessage, SmsVerificationMessage, EmailVerificationMessage, EmailVerificationSubject, AccountRecoverySetting inconsistency is fixed + removeProperties(gen1Resource, [ + 'UserPoolTags', + 'VerificationMessageTemplate.EmailMessage', + 'VerificationMessageTemplate.EmailSubject', + 'EmailVerificationSubject', + 'AccountRecoverySetting', + 'EmailVerificationMessage', + ]); + const gen2Meta = getProjectOutputs(projRoot); + const gen2UserPoolId = gen2Meta.auth.user_pool_id; + const gen2Region = gen2Meta.auth.aws_region; + const gen2Resource = await getResourceDetails('AWS::Cognito::UserPool', gen2UserPoolId, gen2Region); + removeProperties(gen2Resource, ['ProviderURL', 'ProviderName', 'UserPoolId', 'Arn']); + // TODO: remove below line after EmailMessage, EmailSubject, SmsMessage, SmsVerificationMessage, EmailVerificationMessage, EmailVerificationSubject, AccountRecoverySetting inconsistency is fixed + removeProperties(gen2Resource, [ + 'UserPoolTags', + 'VerificationMessageTemplate.EmailMessage', + 'VerificationMessageTemplate.SmsMessage', + 'VerificationMessageTemplate.EmailSubject', + 'SmsVerificationMessage', + 'EmailVerificationSubject', + 'AccountRecoverySetting', + 'EmailVerificationMessage', + ]); + expect(gen2Resource).toEqual(gen1Resource); +} + +export async function assertStorageResource(projRoot: string, gen1BucketName: string, gen1Region: string) { + const gen1Resource = await getResourceDetails('AWS::S3::Bucket', gen1BucketName, gen1Region); + removeProperties(gen1Resource, ['DualStackDomainName', 'DomainName', 'BucketName', 'Arn', 'RegionalDomainName', 'Tags', 'WebsiteURL']); + // TODO: remove below line after CorsConfiguration.CorsRules[0].Id inconsistency is fixed + removeProperties(gen1Resource, ['CorsConfiguration.CorsRules[0].Id']); + + const gen2Meta = getProjectOutputs(projRoot); + const gen2BucketName = gen2Meta.storage.bucket_name; + const gen2Region = gen2Meta.storage.aws_region; + const gen2Resource = await getResourceDetails('AWS::S3::Bucket', gen2BucketName, gen2Region); + removeProperties(gen2Resource, ['DualStackDomainName', 'DomainName', 'BucketName', 'Arn', 'RegionalDomainName', 'Tags', 'WebsiteURL']); + + expect(gen2Resource).toEqual(gen1Resource); +} + +export async function assertFunctionResource( + projRoot: string, + gen2StackName: string | unknown, + gen1FunctionName: string, + gen1Region: string, +) { + const gen1Resource = await getResourceDetails('AWS::Lambda::Function', gen1FunctionName, gen1Region); + removeProperties(gen1Resource, ['Arn', 'FunctionName', 'LoggingConfig.LogGroup', 'Role']); + // TODO: remove below line after Tags inconsistency is fixed + removeProperties(gen1Resource, ['Tags']); + + const gen2Meta = getProjectOutputs(projRoot); + const gen2Region = gen2Meta.auth.aws_region; + const outputs = (await describeCloudFormationStack(gen2StackName as string, gen2Region)).Outputs; + const gen2FunctionName = JSON.parse(outputs?.find((output) => output.OutputKey === 'definedFunctions')?.OutputValue ?? '[]')[0]; + const gen2Resource = await getResourceDetails('AWS::Lambda::Function', gen2FunctionName, gen2Region); + removeProperties(gen2Resource, ['Arn', 'FunctionName', 'LoggingConfig.LogGroup', 'Role']); + // TODO: remove below line after Environment.Variables.AMPLIFY_SSM_ENV_CONFIG, Tags inconsistency is fixed + removeProperties(gen2Resource, ['Environment.Variables.AMPLIFY_SSM_ENV_CONFIG', 'Tags']); + + expect(gen2Resource).toEqual(gen1Resource); +} + +export async function assertDataResource(projRoot: string, gen2StackName: string | unknown, gen1GraphqlApiId: string, gen1Region: string) { + const gen1Resource = await getAppSyncApi(gen1GraphqlApiId, gen1Region); + const gen1DataSource = (await getAppSyncDataSource(gen1GraphqlApiId, 'TodoTable', gen1Region)) as Record; + removeProperties(gen1DataSource, ['dataSourceArn', 'serviceRoleArn']); + removeProperties(gen1Resource.graphqlApi as Record, ['name', 'apiId', 'arn', 'uris', 'tags', 'dns']); + // TODO: remove below line after authenticationType inconsistency is fixed + removeProperties(gen1Resource.graphqlApi as Record, ['authenticationType']); + + const gen2Meta = getProjectOutputs(projRoot); + const gen2Region = gen2Meta.data.aws_region; + const outputs = (await describeCloudFormationStack(gen2StackName as string, gen2Region)).Outputs; + const gen2GraphqlApiId = outputs?.find((output) => output.OutputKey === 'awsAppsyncApiId')?.OutputValue ?? ''; + const gen2Resource = await getAppSyncApi(gen2GraphqlApiId, gen2Region); + const gen2DataSource = (await getAppSyncDataSource(gen2GraphqlApiId, 'TodoTable', gen1Region)) as Record; + removeProperties(gen2DataSource, ['dataSourceArn', 'serviceRoleArn']); + removeProperties(gen2Resource.graphqlApi as Record, [ + 'name', + 'apiId', + 'arn', + 'uris', + 'tags', + 'additionalAuthenticationProviders', + 'dns', + ]); + // TODO: remove below line after authenticationType, userPoolConfig inconsistency is fixed + removeProperties(gen2Resource.graphqlApi as Record, ['authenticationType', 'userPoolConfig']); + + expect(gen2DataSource).toEqual(gen1DataSource); + expect(gen2Resource).toEqual(gen2Resource); +} diff --git a/packages/amplify-migration-codegen-e2e/src/function-utils.ts b/packages/amplify-migration-codegen-e2e/src/function-utils.ts new file mode 100644 index 00000000000..7dffb9637f2 --- /dev/null +++ b/packages/amplify-migration-codegen-e2e/src/function-utils.ts @@ -0,0 +1,23 @@ +import path from 'node:path'; +import * as fs from 'fs-extra'; + +export function copyFunctionFile(projRoot: string, gen1FunctionName: string) { + const sourcePath = path.join( + projRoot, + '.amplify', + 'migration', + 'amplify', + 'backend', + 'function', + gen1FunctionName.split('-')[0], + 'src', + 'index.js', + ); + const destinationPath = path.join(projRoot, 'amplify', 'function', gen1FunctionName.split('-')[0], 'handler.ts'); + const content = fs.readFileSync(sourcePath, 'utf8'); + + // Replace the first occurrence of 'event' with 'event: any' + const modifiedContent = content.replace(/(exports\.handler\s*=\s*async\s*\(\s*)event(\s*\))/, '$1event: any$2'); + + fs.writeFileSync(destinationPath, modifiedContent, 'utf8'); +} diff --git a/packages/amplify-migration-codegen-e2e/src/helpers.ts b/packages/amplify-migration-codegen-e2e/src/helpers.ts deleted file mode 100644 index 536e84ca274..00000000000 --- a/packages/amplify-migration-codegen-e2e/src/helpers.ts +++ /dev/null @@ -1,377 +0,0 @@ -import { - deleteProject as deleteGen1Project, - deleteProjectDir, - initJSProjectWithProfile, - addAuthWithDefault, - amplifyPush, - getProjectMeta, - getUserPool, - npmInstall, - getNpxPath, - nspawn as spawn, - addS3WithGuestAccess, - checkIfBucketExists, - addFunction, - functionBuild, - getFunction, - addApiWithoutSchema, - updateApiSchema, - getAppSyncApi, - amplifyPushForce, - describeCloudFormationStack, -} from '@aws-amplify/amplify-e2e-core'; -import * as fs from 'fs-extra'; -import { $TSAny } from '@aws-amplify/amplify-cli-core'; -import path from 'node:path'; -import { CloudControlClient, GetResourceCommand } from '@aws-sdk/client-cloudcontrol'; -import { AppSyncClient, GetDataSourceCommand } from '@aws-sdk/client-appsync'; -import { unset } from 'lodash'; -import { createHash } from 'crypto'; -import { userInfo } from 'os'; - -type AppId = string; -type ProjectName = string; -type BranchName = string; -type SandboxName = string; - -type BackendIdentifier = - | { - namespace: Readonly; - name: Readonly; - type: Readonly<'branch'>; - hash?: Readonly; - } - | { - namespace: Readonly; - name: Readonly; - type: Readonly<'sandbox'>; - hash?: Readonly; - }; - -const STACK_NAME_LENGTH_LIMIT = 128; -const AMPLIFY_PREFIX = 'amplify'; -const HASH_LENGTH = 10; -const NUM_DASHES = 4; -const pushTimeoutMS = 1000 * 60 * 20; // 20 minutes; - -function toStackName(backendId: BackendIdentifier): string { - const hash = getHash(backendId); - - // only take the first 50 chars here to make sure there is room in the stack name for the namespace as well - const name = sanitizeChars(backendId.name).slice(0, 50); - - const namespaceMaxLength = - STACK_NAME_LENGTH_LIMIT - AMPLIFY_PREFIX.length - backendId.type.length - name.length - NUM_DASHES - HASH_LENGTH; - - const namespace = sanitizeChars(backendId.namespace).slice(0, namespaceMaxLength - 1); - - return ['amplify', namespace, name, backendId.type, hash].join('-'); -} - -const getHash = (backendId: BackendIdentifier): string => - backendId.hash ?? - // md5 would be sufficient here because this hash does not need to be cryptographically secure, but this ensures that we don't get unnecessarily flagged by some security scanner - createHash('sha512').update(backendId.namespace).update(backendId.name).digest('hex').slice(0, HASH_LENGTH); - -/** - * Remove all non-alphanumeric characters from the input string - */ -const sanitizeChars = (str: string): string => { - return str.replace(/[^A-Za-z0-9]/g, ''); -}; - -export async function copyFunctionFile(projRoot: string, gen1FunctionName: string): Promise { - const sourcePath = path.join( - projRoot, - '.amplify', - 'migration', - 'amplify', - 'backend', - 'function', - gen1FunctionName.split('-')[0], - 'src', - 'index.js', - ); - const destinationPath = path.join(projRoot, 'amplify', 'function', gen1FunctionName.split('-')[0], 'handler.ts'); - const content = await fs.readFile(sourcePath, 'utf8'); - - // Replace the first occurrence of 'event' with 'event: any' - const modifiedContent = content.replace(/(exports\.handler\s*=\s*async\s*\(\s*)event(\s*\))/, '$1event: any$2'); - - await fs.writeFile(destinationPath, modifiedContent, 'utf8'); -} - -export async function copyGen1Schema(projRoot: string): Promise { - const gen1SchemaPath = path.join(projRoot, '.amplify', 'migration', 'amplify', 'backend', 'api', 'codegentest', 'schema.graphql'); - const gen1Schema = await fs.readFile(gen1SchemaPath, 'utf-8'); - const dataResourcePath = path.join(projRoot, 'amplify', 'data', 'resource.ts'); - const dataResourceContent = await fs.readFile(dataResourcePath, 'utf-8'); - const backendPath = path.join(projRoot, 'amplify', 'backend.ts'); - let backendContent = await fs.readFile(backendPath, 'utf-8'); - - const schemaRegex = /"TODO: Add your existing graphql schema here"/; - const updatedContent = dataResourceContent.replace(schemaRegex, `\`${gen1Schema.trim()}\``); - - const errorRegex = /throw new Error\("TODO: Add Gen 1 GraphQL schema"\);?\s*/; - const finalContent = updatedContent.replace(errorRegex, ''); - - await fs.writeFile(dataResourcePath, finalContent, 'utf-8'); - - const linesToAdd = ` - const todoTable = backend.data.resources.cfnResources.additionalCfnResources['Todo']; - todoTable.addOverride('Properties.sseSpecification', { sseEnabled: false }); - `; - - backendContent += linesToAdd; - await fs.writeFile(backendPath, backendContent, 'utf-8'); -} - -async function setEnableGen2MigrationFeatureFlag(projectRoot: string): Promise { - const cliJsonPath = path.join(projectRoot, 'amplify', 'cli.json'); - const cliJson = await fs.readJSON(cliJsonPath); - if (!cliJson.features) { - cliJson.features = {}; - } - if (!cliJson.features.graphqltransformer) { - cliJson.features.graphqltransformer = {}; - } - cliJson.features.graphqltransformer.enablegen2migration = true; - await fs.writeJSON(cliJsonPath, cliJson, { spaces: 2 }); -} - -async function updatePackageJsonDependency(cwd: string, dependencyName: string, version: string): Promise { - const packageJsonPath = path.join(cwd, 'package.json'); - const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8'); - const packageJson = JSON.parse(packageJsonContent); - - packageJson.devDependencies = packageJson.devDependencies || {}; - packageJson.devDependencies[dependencyName] = version; - - const updatedContent = JSON.stringify(packageJson, null, 2); - await fs.writeFile(packageJsonPath, updatedContent, 'utf-8'); -} - -async function getAppSyncDataSource(apiId: string, dataSourceName: string, region: string) { - const client = new AppSyncClient({ region }); - const command = new GetDataSourceCommand({ - apiId: apiId, - name: dataSourceName, - }); - const response = await client.send(command); - return response.dataSource; -} - -async function getResourceDetails(typeName: string, identifier: string, region: string) { - const client = new CloudControlClient({ region }); - const command = new GetResourceCommand({ - TypeName: typeName, - Identifier: identifier, - }); - const response = await client.send(command); - return JSON.parse(response.ResourceDescription.Properties); -} - -export async function runGen2SandboxCommand(cwd: string) { - await updatePackageJsonDependency(cwd, '@aws-amplify/backend', '0.0.0-test-20241003180022'); - npmInstall(cwd); - return spawn(getNpxPath(), ['ampx', 'sandbox', '--once'], { - cwd, - stripColors: true, - noOutputTimeout: pushTimeoutMS, - env: { ...process.env, npm_config_user_agent: 'npm' }, - }).runAsync(); -} - -export function runCodegenCommand(cwd: string) { - return spawn(getNpxPath(), ['@aws-amplify/migrate', 'to-gen-2', 'generate-code'], { - cwd, - stripColors: true, - noOutputTimeout: pushTimeoutMS, - env: { ...process.env, npm_config_user_agent: 'npm' }, - }).runAsync(); -} - -function deleteGen2Sandbox(cwd: string) { - return spawn(getNpxPath(), ['ampx', 'sandbox', 'delete'], { - cwd, - stripColors: true, - noOutputTimeout: pushTimeoutMS, - env: { ...process.env, npm_config_user_agent: 'npm' }, - }) - .wait("Are you sure you want to delete all the resources in your sandbox environment (This can't be undone)?") - .sendConfirmYes() - .wait('Finished deleting.') - .runAsync(); -} - -export async function setupAndPushGen1Project(projRoot: string, projectName: string) { - await initJSProjectWithProfile(projRoot, { name: projectName, disableAmplifyAppCreation: false }); - await addAuthWithDefault(projRoot); - await addFunction(projRoot, { functionTemplate: 'Hello World' }, 'nodejs'); - await functionBuild(projRoot); - await addS3WithGuestAccess(projRoot); - await addApiWithoutSchema(projRoot, { transformerVersion: 2 }); - await updateApiSchema(projRoot, projectName, 'simple_model.graphql'); - await amplifyPush(projRoot); - await setEnableGen2MigrationFeatureFlag(projRoot); - await amplifyPushForce(projRoot); -} - -export async function assertGen1Setup(projRoot: string) { - const gen1Meta = getProjectMeta(projRoot); - const gen1Region = gen1Meta.providers.awscloudformation.Region; - const { UserPoolId: gen1UserPoolId } = Object.keys(gen1Meta.auth).map((key) => gen1Meta.auth[key])[0].output; - const { Arn: gen1FunctionArn, Name: gen1FunctionName } = Object.keys(gen1Meta.function).map((key) => gen1Meta.function[key])[0].output; - const { BucketName: gen1BucketName } = Object.keys(gen1Meta.storage).map((key) => gen1Meta.storage[key])[0].output; - const { - GraphQLAPIIdOutput: gen1GraphQLAPIId, - GraphQLAPIEndpointOutput, - GraphQLAPIKeyOutput, - } = Object.keys(gen1Meta.api).map((key) => gen1Meta.api[key])[0].output; - const { graphqlApi } = await getAppSyncApi(gen1GraphQLAPIId, gen1Region); - - expect(gen1Region).toBeDefined(); - - const cloudUserPool = await getUserPool(gen1UserPoolId, gen1Region); - expect(cloudUserPool.UserPool).toBeDefined(); - - expect(gen1FunctionArn).toBeDefined(); - expect(gen1FunctionName).toBeDefined(); - const cloudFunction = await getFunction(gen1FunctionName, gen1Region); - expect(cloudFunction.Configuration?.FunctionArn).toEqual(gen1FunctionArn); - - expect(gen1BucketName).toBeDefined(); - const bucketExists = await checkIfBucketExists(gen1BucketName, gen1Region); - expect(bucketExists).toMatchObject({}); - - expect(gen1GraphQLAPIId).toBeDefined(); - expect(GraphQLAPIEndpointOutput).toBeDefined(); - expect(GraphQLAPIKeyOutput).toBeDefined(); - - expect(graphqlApi).toBeDefined(); - expect(graphqlApi?.apiId).toEqual(gen1GraphQLAPIId); - return { gen1UserPoolId, gen1FunctionName, gen1BucketName, gen1GraphQLAPIId, gen1Region }; -} - -export async function assertUserPoolResource(projRoot: string, gen1UserPoolId: string, gen1Region: string) { - const gen1Resource = await getResourceDetails('AWS::Cognito::UserPool', gen1UserPoolId, gen1Region); - removeProperties(gen1Resource, ['ProviderURL', 'ProviderName', 'UserPoolId', 'Arn']); - // TODO: remove below line after EmailMessage, EmailSubject, SmsMessage, SmsVerificationMessage, EmailVerificationMessage, EmailVerificationSubject, AccountRecoverySetting inconsistency is fixed - removeProperties(gen1Resource, [ - 'UserPoolTags', - 'VerificationMessageTemplate.EmailMessage', - 'VerificationMessageTemplate.EmailSubject', - 'EmailVerificationSubject', - 'AccountRecoverySetting', - 'EmailVerificationMessage', - ]); - const gen2Meta = getProjectOutputs(projRoot); - const gen2UserPoolId = gen2Meta.auth.user_pool_id; - const gen2Region = gen2Meta.auth.aws_region; - const gen2Resource = await getResourceDetails('AWS::Cognito::UserPool', gen2UserPoolId, gen2Region); - removeProperties(gen2Resource, ['ProviderURL', 'ProviderName', 'UserPoolId', 'Arn']); - // TODO: remove below line after EmailMessage, EmailSubject, SmsMessage, SmsVerificationMessage, EmailVerificationMessage, EmailVerificationSubject, AccountRecoverySetting inconsistency is fixed - removeProperties(gen2Resource, [ - 'UserPoolTags', - 'VerificationMessageTemplate.EmailMessage', - 'VerificationMessageTemplate.SmsMessage', - 'VerificationMessageTemplate.EmailSubject', - 'SmsVerificationMessage', - 'EmailVerificationSubject', - 'AccountRecoverySetting', - 'EmailVerificationMessage', - ]); - expect(gen2Resource).toEqual(gen1Resource); -} - -export async function assertStorageResource(projRoot: string, gen1BucketName: string, gen1Region: string) { - const gen1Resource = await getResourceDetails('AWS::S3::Bucket', gen1BucketName, gen1Region); - removeProperties(gen1Resource, ['DualStackDomainName', 'DomainName', 'BucketName', 'Arn', 'RegionalDomainName', 'Tags', 'WebsiteURL']); - // TODO: remove below line after CorsConfiguration.CorsRules[0].Id inconsistency is fixed - removeProperties(gen1Resource, ['CorsConfiguration.CorsRules[0].Id']); - - const gen2Meta = getProjectOutputs(projRoot); - const gen2BucketName = gen2Meta.storage.bucket_name; - const gen2Region = gen2Meta.storage.aws_region; - const gen2Resource = await getResourceDetails('AWS::S3::Bucket', gen2BucketName, gen2Region); - removeProperties(gen2Resource, ['DualStackDomainName', 'DomainName', 'BucketName', 'Arn', 'RegionalDomainName', 'Tags', 'WebsiteURL']); - - expect(gen2Resource).toEqual(gen1Resource); -} - -export async function assertFunctionResource(projRoot: string, gen1FunctionName: string, gen1Region: string) { - const gen1Resource = await getResourceDetails('AWS::Lambda::Function', gen1FunctionName, gen1Region); - removeProperties(gen1Resource, ['Arn', 'FunctionName', 'LoggingConfig.LogGroup', 'Role']); - // TODO: remove below line after Tags inconsistency is fixed - removeProperties(gen1Resource, ['Tags']); - - const gen2Meta = getProjectOutputs(projRoot); - const gen2Region = gen2Meta.auth.aws_region; - const gen2StackName = toStackName({ name: userInfo().username, namespace: 'my-gen2-app', type: 'sandbox' }); - const outputs = (await describeCloudFormationStack(gen2StackName, gen2Region)).Outputs; - const gen2FunctionName = JSON.parse( - outputs?.find((output: { OutputKey: string }) => output.OutputKey === 'definedFunctions')?.OutputValue ?? '[]', - )[0]; - const gen2Resource = await getResourceDetails('AWS::Lambda::Function', gen2FunctionName, gen2Region); - removeProperties(gen2Resource, ['Arn', 'FunctionName', 'LoggingConfig.LogGroup', 'Role']); - // TODO: remove below line after Environment.Variables.AMPLIFY_SSM_ENV_CONFIG, Tags inconsistency is fixed - removeProperties(gen2Resource, ['Environment.Variables.AMPLIFY_SSM_ENV_CONFIG', 'Tags']); - - expect(gen2Resource).toEqual(gen1Resource); -} - -export async function assertDataResource(projRoot: string, gen1GraphQLAPIId: string, gen1Region: string) { - const gen1Resource = await getAppSyncApi(gen1GraphQLAPIId, gen1Region); - const gen1DataSource = (await getAppSyncDataSource(gen1GraphQLAPIId, 'TodoTable', gen1Region)) as Record; - removeProperties(gen1DataSource, ['dataSourceArn', 'serviceRoleArn']); - removeProperties(gen1Resource, [ - 'graphqlApi.name', - 'graphqlApi.apiId', - 'graphqlApi.arn', - 'graphqlApi.uris', - 'graphqlApi.tags', - 'graphqlApi.dns', - ]); - // TODO: remove below line after authenticationType inconsistency is fixed - removeProperties(gen1Resource, ['graphqlApi.authenticationType']); - - const gen2Meta = getProjectOutputs(projRoot); - const gen2Region = gen2Meta.data.aws_region; - const gen2StackName = toStackName({ name: userInfo().username, namespace: 'my-gen2-app', type: 'sandbox' }); - const outputs = (await describeCloudFormationStack(gen2StackName, gen2Region)).Outputs; - const gen2GraphQLAPIId = outputs?.find((output: { OutputKey: string }) => output.OutputKey === 'awsAppsyncApiId')?.OutputValue ?? ''; - const gen2Resource = await getAppSyncApi(gen2GraphQLAPIId, gen2Region); - const gen2DataSource = (await getAppSyncDataSource(gen2GraphQLAPIId, 'TodoTable', gen1Region)) as Record; - removeProperties(gen2DataSource, ['dataSourceArn', 'serviceRoleArn']); - removeProperties(gen2Resource, [ - 'graphqlApi.name', - 'graphqlApi.apiId', - 'graphqlApi.arn', - 'graphqlApi.uris', - 'graphqlApi.tags', - 'graphqlApi.additionalAuthenticationProviders', - 'graphqlApi.dns', - ]); - // TODO: remove below line after authenticationType, userPoolConfig inconsistency is fixed - removeProperties(gen2Resource, ['graphqlApi.authenticationType', 'graphqlApi.userPoolConfig']); - - expect(gen2DataSource).toEqual(gen1DataSource); - expect(gen2Resource).toEqual(gen2Resource); -} - -function removeProperties(obj: Record, propertiesToRemove: string[]) { - propertiesToRemove.forEach((prop) => unset(obj, prop)); -} - -const getProjectOutputsPath = (projectRoot: string) => path.join(projectRoot, 'amplify_outputs.json'); - -const getProjectOutputs = (projectRoot: string): $TSAny => { - const metaFilePath: string = getProjectOutputsPath(projectRoot); - return JSON.parse(fs.readFileSync(metaFilePath, 'utf8')); -}; - -export async function cleanupProjects(cwd: string) { - await deleteGen1Project(path.join(cwd, '.amplify', 'migration')); - await deleteGen2Sandbox(cwd); - deleteProjectDir(cwd); -} diff --git a/packages/amplify-migration-codegen-e2e/src/index.ts b/packages/amplify-migration-codegen-e2e/src/index.ts new file mode 100644 index 00000000000..6e40f2db1ee --- /dev/null +++ b/packages/amplify-migration-codegen-e2e/src/index.ts @@ -0,0 +1,99 @@ +import { + deleteProject as deleteGen1Project, + deleteProjectDir, + initJSProjectWithProfile, + addAuthWithDefault, + amplifyPush, + npmInstall, + getNpxPath, + nspawn as spawn, + addS3WithGuestAccess, + addFunction, + functionBuild, + addApiWithoutSchema, + updateApiSchema, + amplifyPushForce, + addFeatureFlag, +} from '@aws-amplify/amplify-e2e-core'; +import { updatePackageDependency } from './updatePackageJson'; +import path from 'node:path'; +import { unset } from 'lodash'; + +export * from './sdk-calls'; +export * from './assertions'; +export * from './projectOutputs'; +export * from './updatePackageJson'; + +const pushTimeoutMS = 1000 * 60 * 20; // 20 minutes; + +export async function setupAndPushGen1Project(projRoot: string, projName: string) { + await initJSProjectWithProfile(projRoot, { name: projName, disableAmplifyAppCreation: false }); + await addAuthWithDefault(projRoot); + await addFunction(projRoot, { functionTemplate: 'Hello World' }, 'nodejs'); + await functionBuild(projRoot); + await addS3WithGuestAccess(projRoot); + await addApiWithoutSchema(projRoot, { transformerVersion: 2 }); + await updateApiSchema(projRoot, projName, 'simple_model.graphql'); + await amplifyPush(projRoot); + await addFeatureFlag(projRoot, 'graphqltransformer', 'enablegen2migration', true); + await amplifyPushForce(projRoot); +} + +export function runCodegenCommand(cwd: string) { + return spawn(getNpxPath(), ['@aws-amplify/migrate', 'to-gen-2', 'generate-code'], { + cwd, + stripColors: true, + noOutputTimeout: pushTimeoutMS, + env: { ...process.env, npm_config_user_agent: 'npm' }, + }).runAsync(); +} + +export async function runGen2SandboxCommand(cwd: string) { + updatePackageDependency(cwd, '@aws-amplify/backend', '0.0.0-test-20241003180022'); + npmInstall(cwd); + return new Promise((resolve, reject) => { + let stackName: string; + spawn(getNpxPath(), ['ampx', 'sandbox', '--once'], { + cwd, + stripColors: true, + noOutputTimeout: pushTimeoutMS, + env: { ...process.env, npm_config_user_agent: 'npm' }, + }) + .wait(/arn:aws:cloudformation:.*:stack\/([^/]+)\//, (data) => { + const match = data.match(/arn:aws:cloudformation:.*:stack\/([^/]+)\//); + if (match) { + stackName = match[1]; + } + }) + .run((err: Error) => { + if (!err && stackName) { + resolve(stackName); + } else { + reject(err); + } + }); + }); +} + +function deleteGen2Sandbox(cwd: string) { + return spawn(getNpxPath(), ['ampx', 'sandbox', 'delete'], { + cwd, + stripColors: true, + noOutputTimeout: pushTimeoutMS, + env: { ...process.env, npm_config_user_agent: 'npm' }, + }) + .wait("Are you sure you want to delete all the resources in your sandbox environment (This can't be undone)?") + .sendConfirmYes() + .wait('Finished deleting.') + .runAsync(); +} + +export async function cleanupProjects(cwd: string) { + await deleteGen1Project(path.join(cwd, '.amplify', 'migration')); + await deleteGen2Sandbox(cwd); + deleteProjectDir(cwd); +} + +export function removeProperties(obj: Record, propertiesToRemove: string[]) { + propertiesToRemove.forEach((prop) => unset(obj, prop)); +} diff --git a/packages/amplify-migration-codegen-e2e/src/projectOutputs.ts b/packages/amplify-migration-codegen-e2e/src/projectOutputs.ts new file mode 100644 index 00000000000..b7e1e4065e9 --- /dev/null +++ b/packages/amplify-migration-codegen-e2e/src/projectOutputs.ts @@ -0,0 +1,10 @@ +import path from 'node:path'; +import { $TSAny } from '@aws-amplify/amplify-cli-core'; +import { readJsonFile } from '@aws-amplify/amplify-e2e-core'; + +const getProjectOutputsPath = (projectRoot: string) => path.join(projectRoot, 'amplify_outputs.json'); + +export const getProjectOutputs = (projectRoot: string): $TSAny => { + const metaFilePath: string = getProjectOutputsPath(projectRoot); + return readJsonFile(metaFilePath); +}; diff --git a/packages/amplify-migration-codegen-e2e/src/sdk-calls.ts b/packages/amplify-migration-codegen-e2e/src/sdk-calls.ts new file mode 100644 index 00000000000..524e9260ea5 --- /dev/null +++ b/packages/amplify-migration-codegen-e2e/src/sdk-calls.ts @@ -0,0 +1,22 @@ +import { CloudControlClient, GetResourceCommand } from '@aws-sdk/client-cloudcontrol'; +import { AppSyncClient, GetDataSourceCommand } from '@aws-sdk/client-appsync'; + +export async function getAppSyncDataSource(apiId: string, dataSourceName: string, region: string) { + const client = new AppSyncClient({ region }); + const command = new GetDataSourceCommand({ + apiId: apiId, + name: dataSourceName, + }); + const response = await client.send(command); + return response.dataSource; +} + +export async function getResourceDetails(typeName: string, identifier: string, region: string) { + const client = new CloudControlClient({ region }); + const command = new GetResourceCommand({ + TypeName: typeName, + Identifier: identifier, + }); + const response = await client.send(command); + return JSON.parse(response.ResourceDescription.Properties); +} diff --git a/packages/amplify-migration-codegen-e2e/src/updatePackageJson.ts b/packages/amplify-migration-codegen-e2e/src/updatePackageJson.ts new file mode 100644 index 00000000000..930a9cac6c7 --- /dev/null +++ b/packages/amplify-migration-codegen-e2e/src/updatePackageJson.ts @@ -0,0 +1,14 @@ +import { readJsonFile } from '@aws-amplify/amplify-e2e-core'; +import * as fs from 'fs-extra'; +import path from 'node:path'; + +export function updatePackageDependency(cwd: string, dependencyName: string, version: string) { + const packageJsonPath = path.join(cwd, 'package.json'); + const packageJson = readJsonFile(packageJsonPath); + + packageJson.devDependencies = packageJson.devDependencies || {}; + packageJson.devDependencies[dependencyName] = version; + + const updatedContent = JSON.stringify(packageJson, null, 2); + fs.writeFileSync(packageJsonPath, updatedContent, 'utf-8'); +} diff --git a/yarn.lock b/yarn.lock index b2878efe2f0..5091af7c799 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2531,53 +2531,53 @@ __metadata: linkType: hard "@aws-sdk/client-cloudformation@npm:^3.592.0": - version: 3.624.0 - resolution: "@aws-sdk/client-cloudformation@npm:3.624.0" + version: 3.667.0 + resolution: "@aws-sdk/client-cloudformation@npm:3.667.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.624.0 - "@aws-sdk/client-sts": 3.624.0 - "@aws-sdk/core": 3.624.0 - "@aws-sdk/credential-provider-node": 3.624.0 - "@aws-sdk/middleware-host-header": 3.620.0 - "@aws-sdk/middleware-logger": 3.609.0 - "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-user-agent": 3.620.0 - "@aws-sdk/region-config-resolver": 3.614.0 - "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.614.0 - "@aws-sdk/util-user-agent-browser": 3.609.0 - "@aws-sdk/util-user-agent-node": 3.614.0 - "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.3.2 - "@smithy/fetch-http-handler": ^3.2.4 - "@smithy/hash-node": ^3.0.3 - "@smithy/invalid-dependency": ^3.0.3 - "@smithy/middleware-content-length": ^3.0.5 - "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.14 - "@smithy/middleware-serde": ^3.0.3 - "@smithy/middleware-stack": ^3.0.3 - "@smithy/node-config-provider": ^3.1.4 - "@smithy/node-http-handler": ^3.1.4 - "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.1.12 - "@smithy/types": ^3.3.0 - "@smithy/url-parser": ^3.0.3 + "@aws-sdk/client-sso-oidc": 3.667.0 + "@aws-sdk/client-sts": 3.667.0 + "@aws-sdk/core": 3.667.0 + "@aws-sdk/credential-provider-node": 3.667.0 + "@aws-sdk/middleware-host-header": 3.667.0 + "@aws-sdk/middleware-logger": 3.667.0 + "@aws-sdk/middleware-recursion-detection": 3.667.0 + "@aws-sdk/middleware-user-agent": 3.667.0 + "@aws-sdk/region-config-resolver": 3.667.0 + "@aws-sdk/types": 3.667.0 + "@aws-sdk/util-endpoints": 3.667.0 + "@aws-sdk/util-user-agent-browser": 3.667.0 + "@aws-sdk/util-user-agent-node": 3.667.0 + "@smithy/config-resolver": ^3.0.9 + "@smithy/core": ^2.4.8 + "@smithy/fetch-http-handler": ^3.2.9 + "@smithy/hash-node": ^3.0.7 + "@smithy/invalid-dependency": ^3.0.7 + "@smithy/middleware-content-length": ^3.0.9 + "@smithy/middleware-endpoint": ^3.1.4 + "@smithy/middleware-retry": ^3.0.23 + "@smithy/middleware-serde": ^3.0.7 + "@smithy/middleware-stack": ^3.0.7 + "@smithy/node-config-provider": ^3.1.8 + "@smithy/node-http-handler": ^3.2.4 + "@smithy/protocol-http": ^4.1.4 + "@smithy/smithy-client": ^3.4.0 + "@smithy/types": ^3.5.0 + "@smithy/url-parser": ^3.0.7 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.14 - "@smithy/util-defaults-mode-node": ^3.0.14 - "@smithy/util-endpoints": ^2.0.5 - "@smithy/util-middleware": ^3.0.3 - "@smithy/util-retry": ^3.0.3 + "@smithy/util-defaults-mode-browser": ^3.0.23 + "@smithy/util-defaults-mode-node": ^3.0.23 + "@smithy/util-endpoints": ^2.1.3 + "@smithy/util-middleware": ^3.0.7 + "@smithy/util-retry": ^3.0.7 "@smithy/util-utf8": ^3.0.0 - "@smithy/util-waiter": ^3.1.2 + "@smithy/util-waiter": ^3.1.6 tslib: ^2.6.2 uuid: ^9.0.1 - checksum: 6e53724db011a863fbc3cad7390640bdeb017bc350a4775f6fe5aa4f186ded57a0609e1419e6f86efe8a9d9aebb58f7e647dc2042be5e2d68b740db63289ab37 + checksum: 6d27baeeba5a2c7a33c393b662205848c13b9083b75a03d8a56a635cd943b78af1bed26286ae96dde083674da37b5659e2387f24f0adc69857838511ca6e27b7 languageName: node linkType: hard @@ -3915,6 +3915,55 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/client-sso-oidc@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/client-sso-oidc@npm:3.667.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.667.0 + "@aws-sdk/credential-provider-node": 3.667.0 + "@aws-sdk/middleware-host-header": 3.667.0 + "@aws-sdk/middleware-logger": 3.667.0 + "@aws-sdk/middleware-recursion-detection": 3.667.0 + "@aws-sdk/middleware-user-agent": 3.667.0 + "@aws-sdk/region-config-resolver": 3.667.0 + "@aws-sdk/types": 3.667.0 + "@aws-sdk/util-endpoints": 3.667.0 + "@aws-sdk/util-user-agent-browser": 3.667.0 + "@aws-sdk/util-user-agent-node": 3.667.0 + "@smithy/config-resolver": ^3.0.9 + "@smithy/core": ^2.4.8 + "@smithy/fetch-http-handler": ^3.2.9 + "@smithy/hash-node": ^3.0.7 + "@smithy/invalid-dependency": ^3.0.7 + "@smithy/middleware-content-length": ^3.0.9 + "@smithy/middleware-endpoint": ^3.1.4 + "@smithy/middleware-retry": ^3.0.23 + "@smithy/middleware-serde": ^3.0.7 + "@smithy/middleware-stack": ^3.0.7 + "@smithy/node-config-provider": ^3.1.8 + "@smithy/node-http-handler": ^3.2.4 + "@smithy/protocol-http": ^4.1.4 + "@smithy/smithy-client": ^3.4.0 + "@smithy/types": ^3.5.0 + "@smithy/url-parser": ^3.0.7 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.23 + "@smithy/util-defaults-mode-node": ^3.0.23 + "@smithy/util-endpoints": ^2.1.3 + "@smithy/util-middleware": ^3.0.7 + "@smithy/util-retry": ^3.0.7 + "@smithy/util-utf8": ^3.0.0 + tslib: ^2.6.2 + peerDependencies: + "@aws-sdk/client-sts": ^3.667.0 + checksum: 90e543370e0a09ead84b1aa2cdd3b955484dfd8d42c466609800d4c3f9118b468ad876fe0ef7545cdd4f502904c8985da791ce581d3e41f6df10062d911c538c + languageName: node + linkType: hard + "@aws-sdk/client-sso@npm:3.186.0": version: 3.186.0 resolution: "@aws-sdk/client-sso@npm:3.186.0" @@ -4219,6 +4268,52 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/client-sso@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/client-sso@npm:3.667.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.667.0 + "@aws-sdk/middleware-host-header": 3.667.0 + "@aws-sdk/middleware-logger": 3.667.0 + "@aws-sdk/middleware-recursion-detection": 3.667.0 + "@aws-sdk/middleware-user-agent": 3.667.0 + "@aws-sdk/region-config-resolver": 3.667.0 + "@aws-sdk/types": 3.667.0 + "@aws-sdk/util-endpoints": 3.667.0 + "@aws-sdk/util-user-agent-browser": 3.667.0 + "@aws-sdk/util-user-agent-node": 3.667.0 + "@smithy/config-resolver": ^3.0.9 + "@smithy/core": ^2.4.8 + "@smithy/fetch-http-handler": ^3.2.9 + "@smithy/hash-node": ^3.0.7 + "@smithy/invalid-dependency": ^3.0.7 + "@smithy/middleware-content-length": ^3.0.9 + "@smithy/middleware-endpoint": ^3.1.4 + "@smithy/middleware-retry": ^3.0.23 + "@smithy/middleware-serde": ^3.0.7 + "@smithy/middleware-stack": ^3.0.7 + "@smithy/node-config-provider": ^3.1.8 + "@smithy/node-http-handler": ^3.2.4 + "@smithy/protocol-http": ^4.1.4 + "@smithy/smithy-client": ^3.4.0 + "@smithy/types": ^3.5.0 + "@smithy/url-parser": ^3.0.7 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.23 + "@smithy/util-defaults-mode-node": ^3.0.23 + "@smithy/util-endpoints": ^2.1.3 + "@smithy/util-middleware": ^3.0.7 + "@smithy/util-retry": ^3.0.7 + "@smithy/util-utf8": ^3.0.0 + tslib: ^2.6.2 + checksum: 762045824773e51faadbde682be309e3cc646ae8ff1aa10b6d5677c1376fe432fd55140b9810e7fd8f03a68a289d40ec32f9239ba144b825748e69b13f6ecf77 + 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" @@ -4496,7 +4591,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-sts@npm:3.666.0, @aws-sdk/client-sts@npm:^3.303.0, @aws-sdk/client-sts@npm:^3.465.0, @aws-sdk/client-sts@npm:^3.658.1": +"@aws-sdk/client-sts@npm:3.666.0": version: 3.666.0 resolution: "@aws-sdk/client-sts@npm:3.666.0" dependencies: @@ -4544,6 +4639,54 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/client-sts@npm:3.667.0, @aws-sdk/client-sts@npm:^3.303.0, @aws-sdk/client-sts@npm:^3.465.0, @aws-sdk/client-sts@npm:^3.658.1": + version: 3.667.0 + resolution: "@aws-sdk/client-sts@npm:3.667.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sso-oidc": 3.667.0 + "@aws-sdk/core": 3.667.0 + "@aws-sdk/credential-provider-node": 3.667.0 + "@aws-sdk/middleware-host-header": 3.667.0 + "@aws-sdk/middleware-logger": 3.667.0 + "@aws-sdk/middleware-recursion-detection": 3.667.0 + "@aws-sdk/middleware-user-agent": 3.667.0 + "@aws-sdk/region-config-resolver": 3.667.0 + "@aws-sdk/types": 3.667.0 + "@aws-sdk/util-endpoints": 3.667.0 + "@aws-sdk/util-user-agent-browser": 3.667.0 + "@aws-sdk/util-user-agent-node": 3.667.0 + "@smithy/config-resolver": ^3.0.9 + "@smithy/core": ^2.4.8 + "@smithy/fetch-http-handler": ^3.2.9 + "@smithy/hash-node": ^3.0.7 + "@smithy/invalid-dependency": ^3.0.7 + "@smithy/middleware-content-length": ^3.0.9 + "@smithy/middleware-endpoint": ^3.1.4 + "@smithy/middleware-retry": ^3.0.23 + "@smithy/middleware-serde": ^3.0.7 + "@smithy/middleware-stack": ^3.0.7 + "@smithy/node-config-provider": ^3.1.8 + "@smithy/node-http-handler": ^3.2.4 + "@smithy/protocol-http": ^4.1.4 + "@smithy/smithy-client": ^3.4.0 + "@smithy/types": ^3.5.0 + "@smithy/url-parser": ^3.0.7 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.23 + "@smithy/util-defaults-mode-node": ^3.0.23 + "@smithy/util-endpoints": ^2.1.3 + "@smithy/util-middleware": ^3.0.7 + "@smithy/util-retry": ^3.0.7 + "@smithy/util-utf8": ^3.0.0 + tslib: ^2.6.2 + checksum: ba66862b31e69820a0aa0174a3a111985eef109f6e39b3e29e64413eabe80318ec82c7f9eb4df561aecc27aaa254d225140a59d8cea7123fcd2ff0d5c6bdd3f2 + languageName: node + linkType: hard + "@aws-sdk/client-textract@npm:3.6.1": version: 3.6.1 resolution: "@aws-sdk/client-textract@npm:3.6.1" @@ -4731,6 +4874,25 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/core@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/core@npm:3.667.0" + dependencies: + "@aws-sdk/types": 3.667.0 + "@smithy/core": ^2.4.8 + "@smithy/node-config-provider": ^3.1.8 + "@smithy/property-provider": ^3.1.7 + "@smithy/protocol-http": ^4.1.4 + "@smithy/signature-v4": ^4.2.0 + "@smithy/smithy-client": ^3.4.0 + "@smithy/types": ^3.5.0 + "@smithy/util-middleware": ^3.0.7 + fast-xml-parser: 4.4.1 + tslib: ^2.6.2 + checksum: 1f329f972c2ae8b39d6b727a2e70d32acc056ab287e666f192ba1ee61a2995509480c479de2b9151c49af7268d93a95999414023f8542fb2c3578262518751f7 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-cognito-identity@npm:3.382.0": version: 3.382.0 resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.382.0" @@ -4837,6 +4999,19 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-env@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.667.0" + dependencies: + "@aws-sdk/core": 3.667.0 + "@aws-sdk/types": 3.667.0 + "@smithy/property-provider": ^3.1.7 + "@smithy/types": ^3.5.0 + tslib: ^2.6.2 + checksum: 211ec650608320f55a2a5eeb8411949c037729a96e2e8ae9d40ec9d84cf63271b684051eb5e35c130ac15861fc42ab30fc79b8a4eae3bc64d1411f7fc7cfc321 + 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" @@ -4905,6 +5080,24 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-http@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.667.0" + dependencies: + "@aws-sdk/core": 3.667.0 + "@aws-sdk/types": 3.667.0 + "@smithy/fetch-http-handler": ^3.2.9 + "@smithy/node-http-handler": ^3.2.4 + "@smithy/property-provider": ^3.1.7 + "@smithy/protocol-http": ^4.1.4 + "@smithy/smithy-client": ^3.4.0 + "@smithy/types": ^3.5.0 + "@smithy/util-stream": ^3.1.9 + tslib: ^2.6.2 + checksum: 1296aacc3e82480b2c296b928810d53e24722162c7065ef3b8c70074c36dd89c5cd56bc8475b0739302bfc53966b1fce58c1b67e7bd4abed21758ce9c3ab302b + 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" @@ -5089,6 +5282,28 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-ini@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.667.0" + dependencies: + "@aws-sdk/core": 3.667.0 + "@aws-sdk/credential-provider-env": 3.667.0 + "@aws-sdk/credential-provider-http": 3.667.0 + "@aws-sdk/credential-provider-process": 3.667.0 + "@aws-sdk/credential-provider-sso": 3.667.0 + "@aws-sdk/credential-provider-web-identity": 3.667.0 + "@aws-sdk/types": 3.667.0 + "@smithy/credential-provider-imds": ^3.2.4 + "@smithy/property-provider": ^3.1.7 + "@smithy/shared-ini-file-loader": ^3.1.8 + "@smithy/types": ^3.5.0 + tslib: ^2.6.2 + peerDependencies: + "@aws-sdk/client-sts": ^3.667.0 + checksum: b017277d33c0f4b85180ed4d9d39ca837da2a349a15125aca4304b8e74496862b8d35c65e8e138e931f556a7bd698ddcab33562f7adbfc072a485984d4be8927 + 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" @@ -5240,6 +5455,26 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-node@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.667.0" + dependencies: + "@aws-sdk/credential-provider-env": 3.667.0 + "@aws-sdk/credential-provider-http": 3.667.0 + "@aws-sdk/credential-provider-ini": 3.667.0 + "@aws-sdk/credential-provider-process": 3.667.0 + "@aws-sdk/credential-provider-sso": 3.667.0 + "@aws-sdk/credential-provider-web-identity": 3.667.0 + "@aws-sdk/types": 3.667.0 + "@smithy/credential-provider-imds": ^3.2.4 + "@smithy/property-provider": ^3.1.7 + "@smithy/shared-ini-file-loader": ^3.1.8 + "@smithy/types": ^3.5.0 + tslib: ^2.6.2 + checksum: c320451b29fcf6366a5ab3d39aa0ae2a5fcb4cf20afa4d83c55b8103090f639cd6f762e5f73ca2dfc67ff54307a0e6bab2aeda97e49fc8fa113a4006ed32f16b + 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" @@ -5342,6 +5577,20 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-process@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.667.0" + dependencies: + "@aws-sdk/core": 3.667.0 + "@aws-sdk/types": 3.667.0 + "@smithy/property-provider": ^3.1.7 + "@smithy/shared-ini-file-loader": ^3.1.8 + "@smithy/types": ^3.5.0 + tslib: ^2.6.2 + checksum: f6bc550ba17ebfc9922be7dffafe900357530eece1bf93d6b710f4c4b04d63aebeba734384225945387a97a134acaf5dde48005daa85e5b9ea4b0bdf59c39698 + 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" @@ -5444,6 +5693,22 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-sso@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.667.0" + dependencies: + "@aws-sdk/client-sso": 3.667.0 + "@aws-sdk/core": 3.667.0 + "@aws-sdk/token-providers": 3.667.0 + "@aws-sdk/types": 3.667.0 + "@smithy/property-provider": ^3.1.7 + "@smithy/shared-ini-file-loader": ^3.1.8 + "@smithy/types": ^3.5.0 + tslib: ^2.6.2 + checksum: 44a70cae693b22a351e8677b4f4f57714f3d5fdfdd4684a01896da505ae7cffda039fa0b2a5a1496d3ffcb755389b2863de0f2d6055e789133dd185859beb974 + 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" @@ -5534,6 +5799,21 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-web-identity@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.667.0" + dependencies: + "@aws-sdk/core": 3.667.0 + "@aws-sdk/types": 3.667.0 + "@smithy/property-provider": ^3.1.7 + "@smithy/types": ^3.5.0 + tslib: ^2.6.2 + peerDependencies: + "@aws-sdk/client-sts": ^3.667.0 + checksum: d3a2021559e7a087fc1b524d21afaa5088d005bfbb9426005320b2ad16aff99d0a40b358f5629e412b041eef247b8afc0e2b486f5dc1e1d4f62209555b3cfdc4 + languageName: node + linkType: hard + "@aws-sdk/credential-providers@npm:^3.303.0": version: 3.382.0 resolution: "@aws-sdk/credential-providers@npm:3.382.0" @@ -6065,6 +6345,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-host-header@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.667.0" + dependencies: + "@aws-sdk/types": 3.667.0 + "@smithy/protocol-http": ^4.1.4 + "@smithy/types": ^3.5.0 + tslib: ^2.6.2 + checksum: 7db9ae0d59695b251a05f48835b2cd2cbcadb0c0f11a8c530c37f596e807479891dae9a0ace723113979d04b8f5d556541cf42131a6ac4bac8371bcd22b86910 + languageName: node + linkType: hard + "@aws-sdk/middleware-location-constraint@npm:3.649.0": version: 3.649.0 resolution: "@aws-sdk/middleware-location-constraint@npm:3.649.0" @@ -6161,6 +6453,17 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-logger@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/middleware-logger@npm:3.667.0" + dependencies: + "@aws-sdk/types": 3.667.0 + "@smithy/types": ^3.5.0 + tslib: ^2.6.2 + checksum: 8091b797b226d97b93aa1635fc475168dcc881f4d5fc24efe3153605108be26607d5ca8a008085e2d4c6e8ba6aabd2f97cdf4ca12cf7d295362b36d7064312fe + 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" @@ -6243,6 +6546,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-recursion-detection@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.667.0" + dependencies: + "@aws-sdk/types": 3.667.0 + "@smithy/protocol-http": ^4.1.4 + "@smithy/types": ^3.5.0 + tslib: ^2.6.2 + checksum: 87c305abb5df60883b468f000a17b4335188ba4be8845245f1de2d382dfa5f2d4f5ced2380d7b021a89029b8d488fa5139bd3f5c4b98e5c9712ee180b9a25a4d + 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" @@ -6600,6 +6915,21 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-user-agent@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.667.0" + dependencies: + "@aws-sdk/core": 3.667.0 + "@aws-sdk/types": 3.667.0 + "@aws-sdk/util-endpoints": 3.667.0 + "@smithy/core": ^2.4.8 + "@smithy/protocol-http": ^4.1.4 + "@smithy/types": ^3.5.0 + tslib: ^2.6.2 + checksum: b85626df127415f4252a779b729cc440d3012dae52284557690147480991db240e7c802ccf3f6e3913f2dbad404ee786c868b9d67d8cafce3d1ed76ed55518d9 + 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" @@ -6854,6 +7184,20 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/region-config-resolver@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.667.0" + dependencies: + "@aws-sdk/types": 3.667.0 + "@smithy/node-config-provider": ^3.1.8 + "@smithy/types": ^3.5.0 + "@smithy/util-config-provider": ^3.0.0 + "@smithy/util-middleware": ^3.0.7 + tslib: ^2.6.2 + checksum: ae3fb07a3e17515c902490c25d5885615f1e2c381b7681731a396319349ffdc80187116cf061763582e2925185b310dcd78fc96c49f1915abab21184f5c9554f + languageName: node + linkType: hard + "@aws-sdk/service-error-classification@npm:3.186.0": version: 3.186.0 resolution: "@aws-sdk/service-error-classification@npm:3.186.0" @@ -7080,6 +7424,21 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/token-providers@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/token-providers@npm:3.667.0" + dependencies: + "@aws-sdk/types": 3.667.0 + "@smithy/property-provider": ^3.1.7 + "@smithy/shared-ini-file-loader": ^3.1.8 + "@smithy/types": ^3.5.0 + tslib: ^2.6.2 + peerDependencies: + "@aws-sdk/client-sso-oidc": ^3.667.0 + checksum: 5ab543445bda169f0e250bd075044004618fc5915c2f0c11858687b823a7a5106c67c440bea391df2aca67f92ceb8a6ea3e066eaf1cd608d6409f262991772a5 + languageName: node + linkType: hard + "@aws-sdk/types@npm:3.186.0": version: 3.186.0 resolution: "@aws-sdk/types@npm:3.186.0" @@ -7152,7 +7511,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:3.664.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.664.0": version: 3.664.0 resolution: "@aws-sdk/types@npm:3.664.0" dependencies: @@ -7162,6 +7521,16 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/types@npm:3.667.0, @aws-sdk/types@npm:^3.1.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.25.0": + version: 3.667.0 + resolution: "@aws-sdk/types@npm:3.667.0" + dependencies: + "@smithy/types": ^3.5.0 + tslib: ^2.6.2 + checksum: c1173d4799e95f113eeb80505737d86a37b443e45fac52d1045683712078ea338678bf9b55403254615f68e1ee8176084b9647c60e286c6a3569198611ffb9f5 + 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" @@ -7486,6 +7855,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-endpoints@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/util-endpoints@npm:3.667.0" + dependencies: + "@aws-sdk/types": 3.667.0 + "@smithy/types": ^3.5.0 + "@smithy/util-endpoints": ^2.1.3 + tslib: ^2.6.2 + checksum: 53a378a1946024a3a3ce1854d6bf7e92b6155a2814aa0ad7d01109b083bb4fe3cb8ec4d04eb6e23e448fedb0cded7e7430d821d6bdd6f53f256de337ea3fa278 + 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" @@ -7682,6 +8063,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-user-agent-browser@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.667.0" + dependencies: + "@aws-sdk/types": 3.667.0 + "@smithy/types": ^3.5.0 + bowser: ^2.11.0 + tslib: ^2.6.2 + checksum: 56c2bb125e1814d3903bf11c4ff4c620dade040bb857d829da487e631934551c76ada4e6b2ad729baef1fe1db66895a8e146fe78d6e676f1d2591fc8f136f4ad + 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" @@ -7811,6 +8204,24 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-user-agent-node@npm:3.667.0": + version: 3.667.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.667.0" + dependencies: + "@aws-sdk/middleware-user-agent": 3.667.0 + "@aws-sdk/types": 3.667.0 + "@smithy/node-config-provider": ^3.1.8 + "@smithy/types": ^3.5.0 + tslib: ^2.6.2 + peerDependencies: + aws-crt: ">=1.0.0" + peerDependenciesMeta: + aws-crt: + optional: true + checksum: e6e2bbb8f220d12741820b6e67bd666812dafdedf09590f1debe461c1ff995aa6f070ddf9281e333fc5606f7f5b88122bcfb4fe401370e3d03b0d6082580eaa0 + 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" @@ -11928,7 +12339,7 @@ __metadata: languageName: node linkType: hard -"@smithy/abort-controller@npm:^3.1.4, @smithy/abort-controller@npm:^3.1.5": +"@smithy/abort-controller@npm:^3.1.5": version: 3.1.5 resolution: "@smithy/abort-controller@npm:3.1.5" dependencies: @@ -12890,14 +13301,14 @@ __metadata: languageName: node linkType: hard -"@smithy/util-waiter@npm:^3.1.2, @smithy/util-waiter@npm:^3.1.3, @smithy/util-waiter@npm:^3.1.5": - version: 3.1.5 - resolution: "@smithy/util-waiter@npm:3.1.5" +"@smithy/util-waiter@npm:^3.1.2, @smithy/util-waiter@npm:^3.1.3, @smithy/util-waiter@npm:^3.1.5, @smithy/util-waiter@npm:^3.1.6": + version: 3.1.6 + resolution: "@smithy/util-waiter@npm:3.1.6" dependencies: - "@smithy/abort-controller": ^3.1.4 - "@smithy/types": ^3.4.2 + "@smithy/abort-controller": ^3.1.5 + "@smithy/types": ^3.5.0 tslib: ^2.6.2 - checksum: d72733480f08a570a08eb1c4e57ac5779d2f41598d9608d62419e9adfccb86295b8c60103c51b3338167bb2f9179483db24c3dc9585da867419c5abf9efcad98 + checksum: dfa7cf04afa7be4736e78f54f96c6583c2f582fef6bd179cf925f5dd737f3fed0b37446d5198d9dedfb343a0b71c481f560b5954686f8e2b51155a37752bc586 languageName: node linkType: hard