Skip to content
Draft
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
77a1e9e
refactor: start provider-cloudformation
Jul 11, 2025
aca2d07
refactor: category storage
Jul 14, 2025
28e12ba
chore: returning aws-sdk for now
Jul 15, 2025
6bb961e
fix: yarn lock
Jul 15, 2025
4b26596
fix: some adjustments
Jul 16, 2025
53cb005
fix: fixed some tests
Jul 16, 2025
ba3238d
refactor: most of provider-awscloudformation
Jul 17, 2025
d2a8a87
fix: import lex
Jul 17, 2025
ef3fe96
refactor: last set of non-test files
Jul 17, 2025
ccb5895
refactor: updated some unit tests
Jul 18, 2025
6da13ea
Merge branch 'dev' into sdk-migrations-2.5
Jul 18, 2025
b4cc448
chore: post merge removals
Jul 18, 2025
c780d67
refactor: unit tests
Jul 18, 2025
953656f
fix: lint, api, yarn
Jul 18, 2025
558de09
fix: init, delete, and push commands
Aug 5, 2025
da54da4
fix: publish, add hosting
Aug 6, 2025
9d833a1
chore: debugging
Aug 6, 2025
5f9abfc
fix: pull
Aug 7, 2025
3bf519a
fix: push and pull
Aug 7, 2025
2c57be9
fix: pull and debugging
Aug 7, 2025
94c5f03
Merge branch 'dev' into sdk-migrations-2.5
Aug 7, 2025
c353d50
chore: debugging
Aug 8, 2025
30d0f93
fix: update
Aug 8, 2025
dafab7a
fix: typing
Aug 9, 2025
4ed8adc
refactor: switch credentials object over to sdk v3 object
Aug 12, 2025
de651f2
fix: sdk v3 creds config in tests
Aug 12, 2025
ff3706b
fix: legacy sdk v2 creds, api
Aug 12, 2025
7164c6a
fix: feedback
Aug 19, 2025
8033901
fix: update types to 20, function mocks
Aug 19, 2025
237554d
fix: test
Aug 19, 2025
d10ec78
fix: another test
Aug 19, 2025
af3919b
refactor: console hosting
Aug 20, 2025
56c3fed
chore: fix yarn and debugging
Aug 20, 2025
5074543
fix: function secrets
Aug 21, 2025
f297ef5
fix: secrets
Aug 21, 2025
e85dea9
chore: debugging
Aug 21, 2025
033b301
chore: debugging
Aug 22, 2025
2521f89
chore: update tests
Aug 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/amplify-category-storage/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@
"@aws-amplify/amplify-prompts": "2.8.7",
"@aws-amplify/amplify-util-import": "2.8.3",
"@aws-amplify/cli-extensibility-helper": "3.0.39",
"@aws-sdk/client-dynamodb": "^3.515.0",
"@aws-sdk/client-s3": "^3.515.0",
"amplify-headless-interface": "1.17.8",
"amplify-util-headless-input": "1.9.19",
"aws-cdk-lib": "~2.189.1",
"aws-sdk": "^2.1464.0",
"chalk": "^4.1.1",
"constructs": "^10.0.5",
"enquirer": "^2.3.6",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
} from '@aws-amplify/amplify-cli-core';
import { printer } from '@aws-amplify/amplify-prompts';
import { IS3Service } from '@aws-amplify/amplify-util-import';
import { Bucket } from 'aws-sdk/clients/s3';
import { Bucket } from '@aws-sdk/client-s3';
import Enquirer from 'enquirer';
import _ from 'lodash';
import { v4 as uuid } from 'uuid';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { $TSContext, $TSObject } from '@aws-amplify/amplify-cli-core';
import { IDynamoDBService, IS3Service } from '@aws-amplify/amplify-util-import';
import { Bucket } from 'aws-sdk/clients/s3';
import { TableDescription } from 'aws-sdk/clients/dynamodb';
import { Bucket } from '@aws-sdk/client-s3';
import { TableDescription } from '@aws-sdk/client-dynamodb';

// parameters.json
export type S3ResourceParameters = {
Expand Down
25 changes: 25 additions & 0 deletions packages/amplify-provider-awscloudformation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,31 @@
"@aws-amplify/cli-extensibility-helper": "3.0.39",
"@aws-amplify/graphql-transformer-core": "^2.11.1",
"@aws-amplify/graphql-transformer-interfaces": "^3.12.0",
"@aws-sdk/client-amplify": "^3.624.0",
"@aws-sdk/client-api-gateway": "^3.624.0",
"@aws-sdk/client-appsync": "^3.624.0",
"@aws-sdk/client-cloudformation": "^3.624.0",
"@aws-sdk/client-cognito-identity": "^3.624.0",
"@aws-sdk/client-cognito-identity-provider": "^3.624.0",
"@aws-sdk/client-dynamodb": "^3.624.0",
"@aws-sdk/client-ecr": "^3.624.0",
"@aws-sdk/client-iam": "^3.624.0",
"@aws-sdk/client-lambda": "^3.624.0",
"@aws-sdk/client-location": "^3.624.0",
"@aws-sdk/client-polly": "^3.624.0",
"@aws-sdk/client-route-53": "^3.624.0",
"@aws-sdk/client-s3": "^3.624.0",
"@aws-sdk/client-secrets-manager": "^3.624.0",
"@aws-sdk/client-sns": "^3.624.0",
"@aws-sdk/client-ssm": "^3.624.0",
"@aws-sdk/client-sts": "^3.624.0",
"@aws-sdk/credential-provider-node": "^3.624.0",
"@aws-sdk/credential-providers": "^3.624.0",
"@aws-sdk/lib-dynamodb": "^3.624.0",
"@aws-sdk/lib-storage": "^3.624.0",
"@aws-sdk/s3-request-presigner": "^3.624.0",
"@aws-sdk/types": "^3.624.0",
"@smithy/node-http-handler": "^4.1.0",
"amplify-codegen": "^4.10.3",
"archiver": "^7.0.1",
"aws-cdk-lib": "~2.189.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,57 @@
import { $TSContext } from '@aws-amplify/amplify-cli-core';
import { createS3Service } from '../../aws-utils/S3Service';
import { HeadBucketCommand } from '@aws-sdk/client-s3';

jest.mock('aws-sdk', () => {
const mockHeadBucketForUsEast1 = jest.fn().mockImplementation((params: { Bucket: string }) => {
return {
promise: jest.fn().mockImplementation(() => {
if (params.Bucket.includes('us-east-1')) {
return Promise.resolve({});
}
return Promise.reject({ code: 'BadRequest', region: 'eu-south-1' });
}),
};
// Mock the AWS SDK v3 S3Client
jest.mock('@aws-sdk/client-s3', () => {
const mockSendForUsEast1 = jest.fn().mockImplementation(async (command) => {
if (command instanceof HeadBucketCommand) {
const params = command.input;
if (params.Bucket!.includes('us-east-1')) {
return {};
}
const error = new Error('BadRequest');
error.name = 'BadRequest';
throw error;
}
return {};
});

const mockSendForEuSouth1 = jest.fn().mockImplementation(async (command) => {
if (command instanceof HeadBucketCommand) {
const params = command.input;
if (params.Bucket!.includes('eu-south-1')) {
return {};
}
const error = new Error('BadRequest');
error.name = 'BadRequest';
throw error;
}
return {};
});

const mockHeadBucketForEuSouth1 = jest.fn().mockImplementation((params) => {
// Mock S3Client constructor
const mockS3Client = jest.fn().mockImplementation((options) => {
const region = options.region || 'us-east-1';

return {
promise: jest.fn().mockImplementation(() => {
if (params.Bucket.includes('eu-south-1')) {
return Promise.resolve({});
}
return Promise.reject({ code: 'BadRequest', region: 'us-east-1' });
}),
send: region === 'eu-south-1' ? mockSendForEuSouth1 : mockSendForUsEast1,
config: {
region,
credentials: options.credentials,
},
};
});

return {
S3: jest.fn((options) => {
const region = options.region || 'us-east-1';
if (region === 'eu-south-1') {
return {
headBucket: mockHeadBucketForEuSouth1,
};
}
S3Client: mockS3Client,
HeadBucketCommand: jest.fn().mockImplementation((params) => {
return {
config: {
region,
},
headBucket: mockHeadBucketForUsEast1,
input: params,
};
}),
ListBucketsCommand: jest.fn(),
GetBucketLocationCommand: jest.fn(),
};
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { $TSContext } from '@aws-amplify/amplify-cli-core';
import fs from 'fs-extra';
import { CredentialProviderChain, ProcessCredentials } from 'aws-sdk';
import { fromProcess } from '@aws-sdk/credential-providers';
import { getProfileCredentials, getProfiledAwsConfig } from '../system-config-manager';

jest.setTimeout(15000);
Expand All @@ -11,9 +11,8 @@ jest.mock('../utils/aws-logger', () => ({
jest.mock('fs-extra');
const fs_mock = fs as jest.Mocked<typeof fs>;

jest.mock('aws-sdk');
const ProcessCredentialsMock = ProcessCredentials as jest.MockedClass<typeof ProcessCredentials>;
const CredentialProviderChainMock = CredentialProviderChain as jest.MockedClass<typeof CredentialProviderChain>;
jest.mock('@aws-sdk/credential-providers');
const fromProcessMock = fromProcess as jest.MockedFunction<typeof fromProcess>;

const context_stub = {
print: {
Expand All @@ -29,14 +28,14 @@ describe('profile tests', () => {
fs_mock.existsSync.mockReturnValue(true);

describe('credential process loading', () => {
const mockResolvePromise = jest.fn().mockReturnValue(
Promise.resolve({
accessKeyId: 'chainTestAccessKey',
secretAccessKey: 'chainTestSecret',
sessionToken: 'chainTestSessionToken',
expireTime: new Date(1234),
}),
);
const mockCredentials = {
accessKeyId: 'chainTestAccessKey',
secretAccessKey: 'chainTestSecret',
sessionToken: 'chainTestSessionToken',
expiration: new Date(1234),
};

const mockCredentialProvider = jest.fn().mockResolvedValue(mockCredentials);

beforeEach(() => {
// setup
Expand All @@ -47,24 +46,7 @@ describe('profile tests', () => {

fs_mock.readFileSync.mockReturnValue(awsConfigContent);

CredentialProviderChainMock.mockImplementation(() => ({
providers: [],
resolvePromise: mockResolvePromise,
resolve: jest.fn(),
}));

ProcessCredentialsMock.mockImplementation(() => ({
accessKeyId: 'testAccessKey',
secretAccessKey: 'testSecret',
sessionToken: 'testSessionToken',
expireTime: new Date(1234),
expired: false,
get: jest.fn(),
getPromise: jest.fn(),
needsRefresh: jest.fn(),
refresh: jest.fn(),
refreshPromise: jest.fn(),
}));
fromProcessMock.mockReturnValue(mockCredentialProvider);
});

it('should use credential_process defined in config file', async () => {
Expand All @@ -73,24 +55,29 @@ describe('profile tests', () => {

// expect
expect(profile_config).toBeDefined();
expect(mockResolvePromise).toBeCalled();
expect(fromProcessMock).toHaveBeenCalledWith({ profile: 'fake' });
expect(mockCredentialProvider).toHaveBeenCalled();
expect(profile_config.accessKeyId).toBe('chainTestAccessKey');
expect(profile_config.secretAccessKey).toBe('chainTestSecret');
expect(profile_config.sessionToken).toBe('chainTestSessionToken');
expect(profile_config.expiration).toEqual(new Date(1234));
});

it('sets AWS_SDK_LOAD_CONFIG while ProcessCredentials executes', async () => {
it('sets AWS_SDK_LOAD_CONFIG while credential provider executes', async () => {
const sdkLoadConfigOriginal = process.env.AWS_SDK_LOAD_CONFIG;
mockResolvePromise.mockImplementationOnce(() => {
mockCredentialProvider.mockImplementationOnce(() => {
expect(process.env.AWS_SDK_LOAD_CONFIG).toBeTruthy();

return Promise.resolve({
accessKeyId: 'chainTestAccessKey',
secretAccessKey: 'chainTestSecret',
sessionToken: 'chainTestSessionToken',
expiration: new Date(1234),
});
});

await getProfiledAwsConfig(context_stub, 'fake');
expect(mockResolvePromise).toBeCalled();
expect(fromProcessMock).toHaveBeenCalledWith({ profile: 'fake' });
expect(mockCredentialProvider).toHaveBeenCalled();
expect(process.env.AWS_SDK_LOAD_CONFIG).toStrictEqual(sdkLoadConfigOriginal);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ import { checkAmplifyServiceIAMPermission } from './amplify-service-permission-c
import { $TSContext, stateManager, AmplifyFault, AmplifyError } from '@aws-amplify/amplify-cli-core';
import { fileLogger } from './utils/aws-logger';
import { loadConfigurationForEnv } from './configuration-manager';
import {
CreateAppCommand,
CreateBackendEnvironmentCommand,
DeleteBackendEnvironmentCommand,
GetAppCommand,
GetBackendEnvironmentCommand,
ListAppsCommand,
} from '@aws-sdk/client-amplify';

const logger = fileLogger('amplify-service-manager');

Expand Down Expand Up @@ -47,11 +55,7 @@ export async function init(amplifyServiceParams) {
])();

try {
const getAppResult = await amplifyClient
.getApp({
appId: inputAmplifyAppId,
})
.promise();
const getAppResult = await amplifyClient.send(new GetAppCommand({ appId: inputAmplifyAppId }));
context.print.info(`Amplify AppID found: ${inputAmplifyAppId}. Amplify App name is: ${getAppResult.app.name}`);
amplifyAppId = inputAmplifyAppId;
} catch (e) {
Expand Down Expand Up @@ -95,12 +99,12 @@ export async function init(amplifyServiceParams) {
maxResults: 25,
},
])();
listAppsResponse = await amplifyClient
.listApps({
listAppsResponse = await amplifyClient.send(
new ListAppsCommand({
nextToken: listAppsResponse.nextToken,
maxResults: 25,
})
.promise();
}),
);
apps = apps.concat(listAppsResponse.apps);
} while (listAppsResponse.nextToken);

Expand All @@ -126,11 +130,11 @@ export async function init(amplifyServiceParams) {
logger('init.amplifyClient.createApp', [createAppParams])();
try {
if (amplifyAppCreationEnabled()) {
const createAppResponse = await amplifyClient.createApp(createAppParams).promise();
const createAppResponse = await amplifyClient.send(new CreateAppCommand(createAppParams));
amplifyAppId = createAppResponse.app.appId;
}
} catch (e) {
if (e.code === 'LimitExceededException') {
if (e.name === 'LimitExceededException') {
throw new AmplifyError(
'ProjectInitError',
{
Expand All @@ -141,9 +145,9 @@ export async function init(amplifyServiceParams) {
e,
);
}
if (context?.exeInfo?.awsConfigInfo?.configLevel === 'general' && e.code === 'ConfigError') {
if (context?.exeInfo?.awsConfigInfo?.configLevel === 'general' && e.name === 'ConfigError') {
throw new AmplifyError('ConfigurationError', {
code: e.code,
code: e.name,
message: e.message,
resolution: 'https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html',
});
Expand Down Expand Up @@ -177,12 +181,12 @@ export async function init(amplifyServiceParams) {

try {
log();
const { backendEnvironment } = await amplifyClient
.getBackendEnvironment({
const { backendEnvironment } = await amplifyClient.send(
new GetBackendEnvironmentCommand({
appId: amplifyAppId,
environmentName: envName,
})
.promise();
}),
);

if (backendEnvironment) {
verifiedStackName = backendEnvironment.stackName;
Expand All @@ -204,7 +208,7 @@ export async function init(amplifyServiceParams) {
deploymentArtifacts: deploymentBucketName,
};
logger('init.amplifyClient.getBackendEnvironment', [createEnvParams])();
await amplifyClient.createBackendEnvironment(createEnvParams).promise();
await amplifyClient.send(new CreateBackendEnvironmentCommand(createEnvParams));
}

return {
Expand Down Expand Up @@ -241,9 +245,9 @@ export async function deleteEnv(context: $TSContext, envName: string, awsConfigI
};
logger('deleteEnv.amplifyClient.deleteBackendEnvironment', [deleteEnvParams])();
try {
await amplifyClient.deleteBackendEnvironment(deleteEnvParams).promise();
await amplifyClient.send(new DeleteBackendEnvironmentCommand(deleteEnvParams));
} catch (ex) {
if (ex.code === 'NotFoundException') {
if (ex.name === 'NotFoundException') {
context.print.warning(ex.message);
} else {
throw new AmplifyFault(
Expand Down Expand Up @@ -325,14 +329,14 @@ export async function postPushCheck(context) {
logger('postPushCheck.amplifyClient.createApp', [createAppParams])();
try {
if (amplifyAppCreationEnabled()) {
const createAppResponse = await amplifyClient.createApp(createAppParams).promise();
const createAppResponse = await amplifyClient.send(new CreateAppCommand(createAppParams));
amplifyAppId = createAppResponse.app.appId;
}
} catch (e) {
if (e.code === 'LimitExceededException') {
if (e.name === 'LimitExceededException') {
// Do nothing
} else if (
e.code === 'BadRequestException' &&
e.name === 'BadRequestException' &&
e.message.includes('Rate exceeded while calling CreateApp, please slow down or try again later.')
) {
// Do nothing
Expand All @@ -359,7 +363,7 @@ export async function postPushCheck(context) {
deploymentArtifacts: teamProviderInfo[envName][ProviderName].DeploymentBucketName,
};
logger('postPushCheck.amplifyClient.createBackendEnvironment', [createEnvParams])();
await amplifyClient.createBackendEnvironment(createEnvParams).promise();
await amplifyClient.send(new CreateBackendEnvironmentCommand(createEnvParams));
}

providerMeta[AmplifyAppIdLabel] = amplifyAppId;
Expand Down
Loading
Loading