diff --git a/packages/core/src/awsService/appBuilder/explorer/nodes/deployedNode.ts b/packages/core/src/awsService/appBuilder/explorer/nodes/deployedNode.ts index 24fa77939f3..d24e07e06da 100644 --- a/packages/core/src/awsService/appBuilder/explorer/nodes/deployedNode.ts +++ b/packages/core/src/awsService/appBuilder/explorer/nodes/deployedNode.ts @@ -13,7 +13,7 @@ import { getLogger } from '../../../../shared/logger/logger' import { DefaultLambdaClient } from '../../../../shared/clients/lambdaClient' import globals from '../../../../shared/extensionGlobals' import { defaultPartition } from '../../../../shared/regions/regionProvider' -import { Lambda } from 'aws-sdk' +import { FunctionConfiguration } from '@aws-sdk/client-lambda' import { RestApi } from '@aws-sdk/client-api-gateway' import { LambdaNode } from '../../../../lambda/explorer/lambdaNodes' import { LambdaFunctionNode } from '../../../../lambda/explorer/lambdaFunctionNode' @@ -89,10 +89,10 @@ export async function generateDeployedNode( case SERVERLESS_FUNCTION_TYPE: { const defaultClient = new DefaultLambdaClient(regionCode) const lambdaNode = new LambdaNode(regionCode, defaultClient) - let configuration: Lambda.FunctionConfiguration + let configuration: FunctionConfiguration try { configuration = (await defaultClient.getFunction(deployedResource.PhysicalResourceId)) - .Configuration as Lambda.FunctionConfiguration + .Configuration as FunctionConfiguration newDeployedResource = new LambdaFunctionNode( lambdaNode, regionCode, diff --git a/packages/core/src/awsService/appBuilder/explorer/samProject.ts b/packages/core/src/awsService/appBuilder/explorer/samProject.ts index 722ec323192..faba9bcad76 100644 --- a/packages/core/src/awsService/appBuilder/explorer/samProject.ts +++ b/packages/core/src/awsService/appBuilder/explorer/samProject.ts @@ -9,6 +9,7 @@ import { SamConfig, SamConfigErrorCode } from '../../../shared/sam/config' import { getLogger } from '../../../shared/logger/logger' import { ToolkitError } from '../../../shared/errors' import { showViewLogsMessage } from '../../../shared/utilities/messages' +import { Runtime } from '@aws-sdk/client-lambda' export interface SamApp { location: SamAppLocation @@ -24,7 +25,7 @@ export interface SamAppLocation { export interface ResourceTreeEntity { Id: string Type: string - Runtime?: string + Runtime?: Runtime CodeUri?: string Handler?: string Events?: ResourceTreeEntity[] diff --git a/packages/core/src/awsService/appBuilder/lambda2sam/lambda2sam.ts b/packages/core/src/awsService/appBuilder/lambda2sam/lambda2sam.ts index 20f7c372583..75722842bc5 100644 --- a/packages/core/src/awsService/appBuilder/lambda2sam/lambda2sam.ts +++ b/packages/core/src/awsService/appBuilder/lambda2sam/lambda2sam.ts @@ -26,7 +26,7 @@ import { import { downloadUnzip, getLambdaClient, getCFNClient, isPermissionError } from '../utils' import { openProjectInWorkspace } from '../walkthrough' import { ToolkitError } from '../../../shared/errors' -import { ResourcesToImport, StackResource } from 'aws-sdk/clients/cloudformation' +import { ResourceToImport, StackResource } from '@aws-sdk/client-cloudformation' import { SignatureV4 } from '@smithy/signature-v4' import { Sha256 } from '@aws-crypto/sha256-js' import { getIAMConnection } from '../../../auth/utils' @@ -79,7 +79,7 @@ export async function lambdaToSam(lambdaNode: LambdaFunctionNode): Promise progress.report({ increment: 30, message: 'Generating template...' }) // 2.1 call api to get CFN let cfnTemplate: Template - let resourcesToImport: ResourcesToImport + let resourcesToImport: ResourceToImport[] try { ;[cfnTemplate, resourcesToImport] = await callExternalApiForCfnTemplate(lambdaNode) } catch (error) { @@ -282,7 +282,7 @@ export function ifSamTemplate(template: Template): boolean { */ export async function callExternalApiForCfnTemplate( lambdaNode: LambdaFunctionNode -): Promise<[Template, ResourcesToImport]> { +): Promise<[Template, ResourceToImport[]]> { const conn = await getIAMConnection() if (!conn || conn.type !== 'iam') { return [{}, []] @@ -333,7 +333,7 @@ export async function callExternalApiForCfnTemplate( let status: string | undefined = 'CREATE_IN_PROGRESS' let getGeneratedTemplateResponse - let resourcesToImport: ResourcesToImport = [] + let resourcesToImport: ResourceToImport[] = [] const cfn = await getCFNClient(lambdaNode.regionCode) // Wait for template generation to complete @@ -438,7 +438,7 @@ async function promptForProjectLocation(): Promise { */ export async function deployCfnTemplate( template: Template, - resourcesToImport: ResourcesToImport, + resourcesToImport: ResourceToImport[], stackName: string, region: string ): Promise { @@ -901,13 +901,13 @@ export async function getPhysicalIdfromCFNResourceName( // Find resources that start with the given name (SAM transform often adds suffixes) const matchingResources = resources.StackResources.filter((resource: StackResource) => - resource.LogicalResourceId.startsWith(name) + resource.LogicalResourceId?.startsWith(name) ) if (matchingResources.length === 0) { // Try a more flexible approach - check if the resource name is a substring const substringMatches = resources.StackResources.filter((resource: StackResource) => - resource.LogicalResourceId.includes(name) + resource.LogicalResourceId?.includes(name) ) if (substringMatches.length === 0) { @@ -926,7 +926,8 @@ export async function getPhysicalIdfromCFNResourceName( // If we have multiple matches, prefer exact prefix match // Sort by length to get the closest match (shortest additional suffix) matchingResources.sort( - (a: StackResource, b: StackResource) => a.LogicalResourceId.length - b.LogicalResourceId.length + (a: StackResource, b: StackResource) => + (a.LogicalResourceId?.length ?? 0) - (b.LogicalResourceId?.length ?? 0) ) const bestMatch = matchingResources[0] diff --git a/packages/core/src/awsService/appBuilder/utils.ts b/packages/core/src/awsService/appBuilder/utils.ts index bdaa6293b30..d88aa170f57 100644 --- a/packages/core/src/awsService/appBuilder/utils.ts +++ b/packages/core/src/awsService/appBuilder/utils.ts @@ -21,8 +21,51 @@ import { RuntimeFamily, getFamily } from '../../lambda/models/samLambdaRuntime' import { showMessage } from '../../shared/utilities/messages' import { DefaultLambdaClient } from '../../shared/clients/lambdaClient' import AdmZip from 'adm-zip' -import { CloudFormation, Lambda } from 'aws-sdk' +import { + CloudFormationClient, + CreateChangeSetCommand, + CreateChangeSetInput, + CreateChangeSetOutput, + DescribeChangeSetCommand, + DescribeChangeSetInput, + DescribeChangeSetOutput, + DescribeGeneratedTemplateCommand, + DescribeGeneratedTemplateInput, + DescribeGeneratedTemplateOutput, + DescribeStackResourceCommand, + DescribeStackResourceInput, + DescribeStackResourceOutput, + DescribeStackResourcesCommand, + DescribeStackResourcesInput, + DescribeStackResourcesOutput, + DescribeStacksCommand, + DescribeStacksInput, + DescribeStacksOutput, + ExecuteChangeSetCommand, + ExecuteChangeSetInput, + ExecuteChangeSetOutput, + GetGeneratedTemplateCommand, + GetGeneratedTemplateInput, + GetGeneratedTemplateOutput, + GetTemplateCommand, + GetTemplateInput, + GetTemplateOutput, + waitUntilChangeSetCreateComplete, + waitUntilStackImportComplete, + waitUntilStackUpdateComplete, +} from '@aws-sdk/client-cloudformation' +import { + FunctionConfiguration, + FunctionUrlConfig, + GetFunctionResponse, + GetLayerVersionResponse, + InvocationRequest, + InvocationResponse, + LayerVersionsListItem, + Runtime, +} from '@aws-sdk/client-lambda' import { isAwsError, UnknownError } from '../../shared/errors' +import { WaiterConfiguration } from '@aws-sdk/types' const localize = nls.loadMessageBundle() /** @@ -230,7 +273,7 @@ export class EnhancedLambdaClient { } } - async invoke(name: string, payload?: Lambda.InvocationRequest['Payload']): Promise { + async invoke(name: string, payload?: InvocationRequest['Payload']): Promise { try { return await this.client.invoke(name, payload) } catch (error) { @@ -246,7 +289,7 @@ export class EnhancedLambdaClient { } } - async *listFunctions(): AsyncIterableIterator { + async *listFunctions(): AsyncIterableIterator { try { yield* this.client.listFunctions() } catch (error) { @@ -257,7 +300,7 @@ export class EnhancedLambdaClient { } } - async getFunction(name: string): Promise { + async getFunction(name: string): Promise { try { return await this.client.getFunction(name) } catch (error) { @@ -273,7 +316,7 @@ export class EnhancedLambdaClient { } } - async getLayerVersion(name: string, version: number): Promise { + async getLayerVersion(name: string, version: number): Promise { try { return await this.client.getLayerVersion(name, version) } catch (error) { @@ -289,7 +332,7 @@ export class EnhancedLambdaClient { } } - async *listLayerVersions(name: string): AsyncIterableIterator { + async *listLayerVersions(name: string): AsyncIterableIterator { try { yield* this.client.listLayerVersions(name) } catch (error) { @@ -305,7 +348,7 @@ export class EnhancedLambdaClient { } } - async getFunctionUrlConfigs(name: string): Promise { + async getFunctionUrlConfigs(name: string): Promise { try { return await this.client.getFunctionUrlConfigs(name) } catch (error) { @@ -321,7 +364,7 @@ export class EnhancedLambdaClient { } } - async updateFunctionCode(name: string, zipFile: Uint8Array): Promise { + async updateFunctionCode(name: string, zipFile: Uint8Array): Promise { try { return await this.client.updateFunctionCode(name, zipFile) } catch (error) { @@ -343,13 +386,13 @@ export class EnhancedLambdaClient { */ export class EnhancedCloudFormationClient { constructor( - private readonly client: CloudFormation, + private readonly client: CloudFormationClient, private readonly regionCode: string ) {} - async describeStacks(params: CloudFormation.DescribeStacksInput): Promise { + async describeStacks(params: DescribeStacksInput): Promise { try { - return await this.client.describeStacks(params).promise() + return await this.client.send(new DescribeStacksCommand(params)) } catch (error) { if (isPermissionError(error)) { const stackArn = params.StackName @@ -361,9 +404,9 @@ export class EnhancedCloudFormationClient { } } - async getTemplate(params: CloudFormation.GetTemplateInput): Promise { + async getTemplate(params: GetTemplateInput): Promise { try { - return await this.client.getTemplate(params).promise() + return await this.client.send(new GetTemplateCommand(params)) } catch (error) { if (isPermissionError(error)) { const stackArn = params.StackName @@ -375,9 +418,9 @@ export class EnhancedCloudFormationClient { } } - async createChangeSet(params: CloudFormation.CreateChangeSetInput): Promise { + async createChangeSet(params: CreateChangeSetInput): Promise { try { - return await this.client.createChangeSet(params).promise() + return await this.client.send(new CreateChangeSetCommand(params)) } catch (error) { if (isPermissionError(error)) { const stackArn = params.StackName @@ -389,11 +432,9 @@ export class EnhancedCloudFormationClient { } } - async executeChangeSet( - params: CloudFormation.ExecuteChangeSetInput - ): Promise { + async executeChangeSet(params: ExecuteChangeSetInput): Promise { try { - return await this.client.executeChangeSet(params).promise() + return await this.client.send(new ExecuteChangeSetCommand(params)) } catch (error) { if (isPermissionError(error)) { const stackArn = params.StackName @@ -405,11 +446,9 @@ export class EnhancedCloudFormationClient { } } - async describeChangeSet( - params: CloudFormation.DescribeChangeSetInput - ): Promise { + async describeChangeSet(params: DescribeChangeSetInput): Promise { try { - return await this.client.describeChangeSet(params).promise() + return await this.client.send(new DescribeChangeSetCommand(params)) } catch (error) { if (isPermissionError(error)) { const stackArn = params.StackName @@ -421,11 +460,9 @@ export class EnhancedCloudFormationClient { } } - async describeStackResources( - params: CloudFormation.DescribeStackResourcesInput - ): Promise { + async describeStackResources(params: DescribeStackResourcesInput): Promise { try { - return await this.client.describeStackResources(params).promise() + return await this.client.send(new DescribeStackResourcesCommand(params)) } catch (error) { if (isPermissionError(error)) { const stackArn = params.StackName @@ -437,11 +474,9 @@ export class EnhancedCloudFormationClient { } } - async describeStackResource( - params: CloudFormation.DescribeStackResourceInput - ): Promise { + async describeStackResource(params: DescribeStackResourceInput): Promise { try { - return await this.client.describeStackResource(params).promise() + return await this.client.send(new DescribeStackResourceCommand(params)) } catch (error) { if (isPermissionError(error)) { const stackArn = params.StackName @@ -453,11 +488,9 @@ export class EnhancedCloudFormationClient { } } - async getGeneratedTemplate( - params: CloudFormation.GetGeneratedTemplateInput - ): Promise { + async getGeneratedTemplate(params: GetGeneratedTemplateInput): Promise { try { - return await this.client.getGeneratedTemplate(params).promise() + return await this.client.send(new GetGeneratedTemplateCommand(params)) } catch (error) { if (isPermissionError(error)) { throw createEnhancedPermissionError(error, 'cloudformation', 'getGeneratedTemplate') @@ -466,11 +499,9 @@ export class EnhancedCloudFormationClient { } } - async describeGeneratedTemplate( - params: CloudFormation.DescribeGeneratedTemplateInput - ): Promise { + async describeGeneratedTemplate(params: DescribeGeneratedTemplateInput): Promise { try { - return await this.client.describeGeneratedTemplate(params).promise() + return await this.client.send(new DescribeGeneratedTemplateCommand(params)) } catch (error) { if (isPermissionError(error)) { throw createEnhancedPermissionError(error, 'cloudformation', 'describeGeneratedTemplate') @@ -481,7 +512,20 @@ export class EnhancedCloudFormationClient { async waitFor(state: string, params: any): Promise { try { - return await this.client.waitFor(state as any, params).promise() + const waiterConfig = { + client: this.client, + maxWaitTime: 900, + } satisfies WaiterConfiguration + switch (state) { + case 'changeSetCreateComplete': + return await waitUntilChangeSetCreateComplete(waiterConfig, params) + case 'stackImportComplete': + return await waitUntilStackImportComplete(waiterConfig, params) + case 'stackUpdateComplete': + return await waitUntilStackUpdateComplete(waiterConfig, params) + default: + throw new Error(`Unsupported waiter state: ${state}`) + } } catch (error) { if (isPermissionError(error)) { // For waitFor operations, we'll provide a generic permission error since the specific action varies @@ -560,7 +604,7 @@ export async function getLambdaHandlerFile( folderUri: vscode.Uri, codeUri: string, handler: string, - runtime: string + runtime: Runtime ): Promise { const family = getFamily(runtime) if (!supportedRuntimeForHandler.has(family)) { @@ -704,6 +748,9 @@ export function getLambdaClient(region: string): EnhancedLambdaClient { } export async function getCFNClient(regionCode: string): Promise { - const originalClient = await globals.sdkClientBuilder.createAwsService(CloudFormation, {}, regionCode) + const originalClient = globals.sdkClientBuilderV3.createAwsService({ + serviceClient: CloudFormationClient, + region: regionCode, + }) return new EnhancedCloudFormationClient(originalClient, regionCode) } diff --git a/packages/core/src/eventSchemas/models/schemaCodeLangs.ts b/packages/core/src/eventSchemas/models/schemaCodeLangs.ts index c2bec2e29f6..fe83459251a 100644 --- a/packages/core/src/eventSchemas/models/schemaCodeLangs.ts +++ b/packages/core/src/eventSchemas/models/schemaCodeLangs.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Runtime } from 'aws-sdk/clients/lambda' +import { Runtime } from '@aws-sdk/client-lambda' import { Set as ImmutableSet } from 'immutable' import { goRuntimes } from '../../lambda/models/samLambdaRuntime' diff --git a/packages/core/src/lambda/activation.ts b/packages/core/src/lambda/activation.ts index eaebc17de3b..0b3224c2649 100644 --- a/packages/core/src/lambda/activation.ts +++ b/packages/core/src/lambda/activation.ts @@ -7,7 +7,7 @@ import * as path from 'path' import * as vscode from 'vscode' import * as nls from 'vscode-nls' -import { Lambda } from 'aws-sdk' +import { FunctionConfiguration } from '@aws-sdk/client-lambda' import { deleteLambda } from './commands/deleteLambda' import { uploadLambdaCommand } from './commands/uploadLambda' import { LambdaFunctionNode } from './explorer/lambdaFunctionNode' @@ -229,7 +229,7 @@ export async function activate(context: ExtContext): Promise { ), Commands.register('aws.appBuilder.tailLogs', async (node: LambdaFunctionNode | TreeNode) => { - let functionConfiguration: Lambda.FunctionConfiguration + let functionConfiguration: FunctionConfiguration try { const sourceNode = getSourceNode(node) functionConfiguration = sourceNode.configuration diff --git a/packages/core/src/lambda/commands/copyLambdaUrl.ts b/packages/core/src/lambda/commands/copyLambdaUrl.ts index d15a96a7d62..835525d0610 100644 --- a/packages/core/src/lambda/commands/copyLambdaUrl.ts +++ b/packages/core/src/lambda/commands/copyLambdaUrl.ts @@ -10,7 +10,7 @@ import { copyToClipboard } from '../../shared/utilities/messages' import { addCodiconToString } from '../../shared/utilities/textUtilities' import { createQuickPick, QuickPickPrompter } from '../../shared/ui/pickerPrompter' import { isValidResponse } from '../../shared/wizards/wizard' -import { FunctionUrlConfigList } from 'aws-sdk/clients/lambda' +import { FunctionUrlConfig } from '@aws-sdk/client-lambda' import { CancellationError } from '../../shared/utilities/timeoutUtils' import { lambdaFunctionUrlConfigUrl } from '../../shared/constants' @@ -40,7 +40,7 @@ export async function copyLambdaUrl( } } -async function _quickPickUrl(configList: FunctionUrlConfigList): Promise { +async function _quickPickUrl(configList: FunctionUrlConfig[]): Promise { const res = await createLambdaFuncUrlPrompter(configList).prompt() if (!isValidResponse(res)) { throw new CancellationError('user') @@ -48,10 +48,12 @@ async function _quickPickUrl(configList: FunctionUrlConfigList): Promise { - const items = configList.map((c) => ({ - label: c.FunctionArn, - data: c.FunctionUrl, - })) +export function createLambdaFuncUrlPrompter(configList: FunctionUrlConfig[]): QuickPickPrompter { + const items = configList + .filter((c) => c.FunctionArn && c.FunctionUrl) + .map((c) => ({ + label: c.FunctionArn!, + data: c.FunctionUrl!, + })) return createQuickPick(items, { title: 'Select function to copy url from.' }) } diff --git a/packages/core/src/lambda/commands/createNewSamApp.ts b/packages/core/src/lambda/commands/createNewSamApp.ts index c53edf2518b..7801976c435 100644 --- a/packages/core/src/lambda/commands/createNewSamApp.ts +++ b/packages/core/src/lambda/commands/createNewSamApp.ts @@ -43,7 +43,8 @@ import { getIdeProperties, getDebugNewSamAppDocUrl, getLaunchConfigDocUrl } from import { checklogs } from '../../shared/localizedText' import globals from '../../shared/extensionGlobals' import { telemetry } from '../../shared/telemetry/telemetry' -import { LambdaArchitecture, Result, Runtime } from '../../shared/telemetry/telemetry' +import { LambdaArchitecture, Result, Runtime as TelemetryRuntime } from '../../shared/telemetry/telemetry' +import { Runtime } from '@aws-sdk/client-lambda' import { getTelemetryReason, getTelemetryResult } from '../../shared/errors' import { openUrl, replaceVscodeVars } from '../../shared/utilities/vsCodeUtils' import { fs } from '../../shared/fs/fs' @@ -88,7 +89,7 @@ export async function resumeCreateNewSamApp( extContext, folder, templateUri, - samInitState?.isImage ? (samInitState?.runtime as Runtime | undefined) : undefined + samInitState?.isImage ? samInitState?.runtime : undefined ) const tryOpenReadme = await writeToolkitReadme(readmeUri.fsPath, configs) if (tryOpenReadme) { @@ -112,7 +113,7 @@ export async function resumeCreateNewSamApp( lambdaArchitecture: arch, result: createResult, reason: reason, - runtime: samInitState?.runtime as Runtime, + runtime: samInitState?.runtime as TelemetryRuntime, version: samVersion, }) } @@ -194,7 +195,7 @@ export async function createNewSamApplication( initArguments.baseImage = `amazon/${createRuntime}-base` } else { lambdaPackageType = 'Zip' - initArguments.runtime = createRuntime + initArguments.runtime! = createRuntime // in theory, templates could be provided with image-based lambdas, but that is currently not supported by SAM initArguments.template = config.template } @@ -348,7 +349,7 @@ export async function createNewSamApplication( lambdaArchitecture: initArguments?.architecture, result: createResult, reason: reason, - runtime: createRuntime, + runtime: createRuntime as TelemetryRuntime, version: samVersion, }) } diff --git a/packages/core/src/lambda/commands/deleteLambda.ts b/packages/core/src/lambda/commands/deleteLambda.ts index 29dea130f66..c6290eab3c6 100644 --- a/packages/core/src/lambda/commands/deleteLambda.ts +++ b/packages/core/src/lambda/commands/deleteLambda.ts @@ -10,7 +10,7 @@ import * as localizedText from '../../shared/localizedText' import { DefaultLambdaClient } from '../../shared/clients/lambdaClient' import { Result } from '../../shared/telemetry/telemetry' import { showConfirmationMessage, showViewLogsMessage } from '../../shared/utilities/messages' -import { FunctionConfiguration } from 'aws-sdk/clients/lambda' +import { FunctionConfiguration } from '@aws-sdk/client-lambda' import { getLogger } from '../../shared/logger/logger' import { telemetry } from '../../shared/telemetry/telemetry' diff --git a/packages/core/src/lambda/commands/uploadLambda.ts b/packages/core/src/lambda/commands/uploadLambda.ts index 6bfd3777463..98149674587 100644 --- a/packages/core/src/lambda/commands/uploadLambda.ts +++ b/packages/core/src/lambda/commands/uploadLambda.ts @@ -27,7 +27,7 @@ import { StepEstimator, Wizard, WIZARD_BACK } from '../../shared/wizards/wizard' import { createSingleFileDialog } from '../../shared/ui/common/openDialog' import { Prompter, PromptResult } from '../../shared/ui/prompter' import { ToolkitError } from '../../shared/errors' -import { FunctionConfiguration } from 'aws-sdk/clients/lambda' +import { FunctionConfiguration } from '@aws-sdk/client-lambda' import globals from '../../shared/extensionGlobals' import { toArrayAsync } from '../../shared/utilities/collectionUtils' import { fromExtensionManifest } from '../../shared/settings' diff --git a/packages/core/src/lambda/explorer/cloudFormationNodes.ts b/packages/core/src/lambda/explorer/cloudFormationNodes.ts index e2d9e9aae27..4ef298a391e 100644 --- a/packages/core/src/lambda/explorer/cloudFormationNodes.ts +++ b/packages/core/src/lambda/explorer/cloudFormationNodes.ts @@ -6,7 +6,7 @@ import * as nls from 'vscode-nls' const localize = nls.loadMessageBundle() -import { CloudFormation, Lambda } from 'aws-sdk' +import { FunctionConfiguration } from '@aws-sdk/client-lambda' import * as os from 'os' import * as vscode from 'vscode' import { CloudFormationClient, StackSummary } from '../../shared/clients/cloudFormation' @@ -78,7 +78,7 @@ export class CloudFormationStackNode extends AWSTreeNodeBase implements AWSResou this.iconPath = getIcon('aws-cloudformation-stack') } - public get stackId(): CloudFormation.StackId | undefined { + public get stackId(): string | undefined { return this.stackSummary.StackId } @@ -94,7 +94,7 @@ export class CloudFormationStackNode extends AWSTreeNodeBase implements AWSResou return this.stackName } - public get stackName(): CloudFormation.StackName { + public get stackName(): string { return this.stackSummary.StackName } @@ -122,7 +122,7 @@ export class CloudFormationStackNode extends AWSTreeNodeBase implements AWSResou private async updateChildren(): Promise { const resources: string[] = await this.resolveLambdaResources() - const functions: Map = toMap( + const functions: Map = toMap( await toArrayAsync(listLambdaFunctions(this.lambdaClient)), (functionInfo) => functionInfo.FunctionName ) @@ -151,7 +151,7 @@ export class CloudFormationStackNode extends AWSTreeNodeBase implements AWSResou function makeCloudFormationLambdaFunctionNode( parent: AWSTreeNodeBase, regionCode: string, - configuration: Lambda.FunctionConfiguration + configuration: FunctionConfiguration ): LambdaFunctionNode { const node = new LambdaFunctionNode(parent, regionCode, configuration, contextValueCloudformationLambdaFunction) diff --git a/packages/core/src/lambda/explorer/lambdaFunctionNode.ts b/packages/core/src/lambda/explorer/lambdaFunctionNode.ts index 7b79c88659d..d2a12d0b7d6 100644 --- a/packages/core/src/lambda/explorer/lambdaFunctionNode.ts +++ b/packages/core/src/lambda/explorer/lambdaFunctionNode.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Lambda } from 'aws-sdk' +import { FunctionConfiguration } from '@aws-sdk/client-lambda' import * as os from 'os' import * as vscode from 'vscode' import { getIcon } from '../../shared/icons' @@ -34,7 +34,7 @@ export class LambdaFunctionNode extends AWSTreeNodeBase implements AWSResourceNo public constructor( public readonly parent: AWSTreeNodeBase, public override readonly regionCode: string, - public configuration: Lambda.FunctionConfiguration, + public configuration: FunctionConfiguration, public override readonly contextValue?: string, public localDir?: string ) { @@ -50,7 +50,7 @@ export class LambdaFunctionNode extends AWSTreeNodeBase implements AWSResourceNo this.contextValue = contextValue } - public update(configuration: Lambda.FunctionConfiguration): void { + public update(configuration: FunctionConfiguration): void { this.configuration = configuration this.label = this.configuration.FunctionName || '' this.tooltip = `${this.configuration.FunctionName}${os.EOL}${this.configuration.FunctionArn}` diff --git a/packages/core/src/lambda/explorer/lambdaNodes.ts b/packages/core/src/lambda/explorer/lambdaNodes.ts index 62a01c6445a..dd753ce5594 100644 --- a/packages/core/src/lambda/explorer/lambdaNodes.ts +++ b/packages/core/src/lambda/explorer/lambdaNodes.ts @@ -6,7 +6,7 @@ import * as nls from 'vscode-nls' const localize = nls.loadMessageBundle() -import { Lambda } from 'aws-sdk' +import { FunctionConfiguration } from '@aws-sdk/client-lambda' import * as vscode from 'vscode' import { DefaultLambdaClient } from '../../shared/clients/lambdaClient' @@ -54,7 +54,7 @@ export class LambdaNode extends AWSTreeNodeBase { } public async updateChildren(): Promise { - const functions: Map = toMap( + const functions: Map = toMap( await toArrayAsync(listLambdaFunctions(this.client)), (configuration) => configuration.FunctionName ) @@ -71,10 +71,10 @@ export class LambdaNode extends AWSTreeNodeBase { function makeLambdaFunctionNode( parent: AWSTreeNodeBase, regionCode: string, - configuration: Lambda.FunctionConfiguration + configuration: FunctionConfiguration ): LambdaFunctionNode { let contextValue = contextValueLambdaFunction - const isImportableRuntime = samLambdaImportableRuntimes.contains(configuration.Runtime ?? '') + const isImportableRuntime = configuration.Runtime && samLambdaImportableRuntimes.contains(configuration.Runtime) if (isLocalStackConnection()) { if (isImportableRuntime && !isHotReloadingFunction(configuration?.CodeSha256)) { contextValue = contextValueLambdaFunctionDownloadOnly diff --git a/packages/core/src/lambda/models/samLambdaRuntime.ts b/packages/core/src/lambda/models/samLambdaRuntime.ts index 06e35dbcd2b..985e947afc9 100644 --- a/packages/core/src/lambda/models/samLambdaRuntime.ts +++ b/packages/core/src/lambda/models/samLambdaRuntime.ts @@ -7,7 +7,7 @@ import * as nls from 'vscode-nls' const localize = nls.loadMessageBundle() import * as vscode from 'vscode' -import { Runtime } from 'aws-sdk/clients/lambda' +import { Runtime } from '@aws-sdk/client-lambda' import { Map as ImmutableMap, Set as ImmutableSet } from 'immutable' import { isCloud9 } from '../../shared/extensionUtilities' import { PrompterButtons } from '../../shared/ui/buttons' @@ -30,7 +30,7 @@ export type RuntimePackageType = 'Image' | 'Zip' // TODO: Consolidate all of the runtime constructs into a single > map // We should be able to eliminate a fair amount of redundancy with that. export const nodeJsRuntimes: ImmutableSet = ImmutableSet([ - 'nodejs22.x', + 'nodejs22.x' as Runtime, 'nodejs20.x', 'nodejs18.x', 'nodejs16.x', @@ -51,7 +51,7 @@ export function getNodeMajorVersion(version?: string): number | undefined { } export const pythonRuntimes: ImmutableSet = ImmutableSet([ - 'python3.13', + 'python3.13' as Runtime, 'python3.12', 'python3.11', 'python3.10', @@ -68,7 +68,10 @@ export const javaRuntimes: ImmutableSet = ImmutableSet([ 'java21', ]) export const dotNetRuntimes: ImmutableSet = ImmutableSet(['dotnet6', 'dotnet8']) -export const rubyRuntimes: ImmutableSet = ImmutableSet(['ruby3.2', 'ruby3.3', 'ruby3.4']) +export const rubyRuntimes: ImmutableSet = ImmutableSet(['ruby3.2', 'ruby3.3', 'ruby3.4' as Runtime]) + +// Image runtimes are not a direct subset of valid ZIP lambda types +const dotnet50 = 'dotnet5.0' as Runtime /** * Deprecated runtimes can be found at https://docs.aws.amazon.com/lambda/latest/dg/runtime-support-policy.html @@ -91,8 +94,8 @@ export const deprecatedRuntimes: ImmutableSet = ImmutableSet([ 'ruby2.7', ]) const defaultRuntimes = ImmutableMap([ - [RuntimeFamily.NodeJS, 'nodejs22.x'], - [RuntimeFamily.Python, 'python3.13'], + [RuntimeFamily.NodeJS, 'nodejs22.x' as Runtime], + [RuntimeFamily.Python, 'python3.13' as Runtime], [RuntimeFamily.DotNet, 'dotnet8'], [RuntimeFamily.Go, 'go1.x'], [RuntimeFamily.Java, 'java21'], @@ -120,7 +123,7 @@ export const samZipLambdaRuntimes: ImmutableSet = ImmutableSet.union([ export const samArmLambdaRuntimes: ImmutableSet = ImmutableSet([ 'python3.9', 'python3.8', - 'nodejs22.x', + 'nodejs22.x' as Runtime, 'nodejs20.x', 'nodejs18.x', 'nodejs16.x', @@ -145,8 +148,6 @@ export function samLambdaCreatableRuntimes(cloud9: boolean = isCloud9()): Immuta return cloud9 ? cloud9SupportedRuntimes : samZipLambdaRuntimes } -// Image runtimes are not a direct subset of valid ZIP lambda types -const dotnet50 = 'dotnet5.0' export function samImageLambdaRuntimes(cloud9: boolean = isCloud9()): ImmutableSet { // Note: SAM also supports ruby, but Toolkit does not. return ImmutableSet([...samLambdaCreatableRuntimes(cloud9), ...(cloud9 ? [] : [dotnet50])]) @@ -172,7 +173,7 @@ export function getDependencyManager(runtime: Runtime): DependencyManager[] { throw new Error(`Runtime ${runtime} does not have an associated DependencyManager`) } -export function getFamily(runtime: string): RuntimeFamily { +export function getFamily(runtime: Runtime): RuntimeFamily { if (deprecatedRuntimes.has(runtime)) { handleDeprecatedRuntime(runtime) } else if (nodeJsRuntimes.has(runtime)) { @@ -248,7 +249,7 @@ export function getRuntimeFamily(langId: string): RuntimeFamily { /** * Provides the default runtime for a given `RuntimeFamily` or undefined if the runtime is invalid. */ -export function getDefaultRuntime(runtime: RuntimeFamily): string | undefined { +export function getDefaultRuntime(runtime: RuntimeFamily): Runtime | undefined { return defaultRuntimes.get(runtime) } diff --git a/packages/core/src/lambda/models/samTemplates.ts b/packages/core/src/lambda/models/samTemplates.ts index 5ec112a7dc4..ace9c93faf6 100644 --- a/packages/core/src/lambda/models/samTemplates.ts +++ b/packages/core/src/lambda/models/samTemplates.ts @@ -6,7 +6,7 @@ import * as nls from 'vscode-nls' const localize = nls.loadMessageBundle() import * as semver from 'semver' -import { Runtime } from 'aws-sdk/clients/lambda' +import { Runtime } from '@aws-sdk/client-lambda' import { Set as ImmutableSet } from 'immutable' import { supportsEventBridgeTemplates } from '../../../src/eventSchemas/models/schemaCodeLangs' import { RuntimePackageType } from './samLambdaRuntime' diff --git a/packages/core/src/lambda/remoteDebugging/lambdaDebugger.ts b/packages/core/src/lambda/remoteDebugging/lambdaDebugger.ts index 7d9867f8766..5fcb0d5048f 100644 --- a/packages/core/src/lambda/remoteDebugging/lambdaDebugger.ts +++ b/packages/core/src/lambda/remoteDebugging/lambdaDebugger.ts @@ -5,7 +5,7 @@ import * as vscode from 'vscode' import globals from '../../shared/extensionGlobals' -import type { Lambda } from 'aws-sdk' +import { FunctionConfiguration } from '@aws-sdk/client-lambda' import { getLogger } from '../../shared/logger/logger' const logger = getLogger() @@ -46,20 +46,20 @@ export interface LambdaDebugger { checkHealth(): Promise setup( progress: vscode.Progress<{ message?: string; increment?: number }>, - functionConfig: Lambda.FunctionConfiguration, + functionConfig: FunctionConfiguration, region: string ): Promise waitForSetup( progress: vscode.Progress<{ message?: string; increment?: number }>, - functionConfig: Lambda.FunctionConfiguration, + functionConfig: FunctionConfiguration, region: string ): Promise waitForFunctionUpdates(progress: vscode.Progress<{ message?: string; increment?: number }>): Promise - cleanup(functionConfig: Lambda.FunctionConfiguration): Promise + cleanup(functionConfig: FunctionConfiguration): Promise } // this should be called when the debug session is started -export async function persistLambdaSnapshot(config: Lambda.FunctionConfiguration | undefined): Promise { +export async function persistLambdaSnapshot(config: FunctionConfiguration | undefined): Promise { try { await globals.globalState.update(remoteDebugSnapshotString, config) } catch (error) { @@ -68,6 +68,6 @@ export async function persistLambdaSnapshot(config: Lambda.FunctionConfiguration } } -export function getLambdaSnapshot(): Lambda.FunctionConfiguration | undefined { - return globals.globalState.get(remoteDebugSnapshotString) +export function getLambdaSnapshot(): FunctionConfiguration | undefined { + return globals.globalState.get(remoteDebugSnapshotString) } diff --git a/packages/core/src/lambda/remoteDebugging/ldkClient.ts b/packages/core/src/lambda/remoteDebugging/ldkClient.ts index 4545889a7ba..a5d51adb7df 100644 --- a/packages/core/src/lambda/remoteDebugging/ldkClient.ts +++ b/packages/core/src/lambda/remoteDebugging/ldkClient.ts @@ -4,7 +4,7 @@ */ import * as vscode from 'vscode' -import { Lambda } from 'aws-sdk' +import { FunctionConfiguration } from '@aws-sdk/client-lambda' import { CloseTunnelCommand, IoTSecureTunnelingClient, @@ -41,9 +41,9 @@ export interface TunnelInfo { async function callUpdateFunctionConfiguration( lambda: DefaultLambdaClient, - config: Lambda.FunctionConfiguration, + config: FunctionConfiguration, waitForUpdate: boolean -): Promise { +): Promise { // Update function configuration back to original values return await lambda.updateFunctionConfiguration( { @@ -214,7 +214,7 @@ export class LdkClient { } } - async getFunctionDetail(functionArn: string): Promise { + async getFunctionDetail(functionArn: string): Promise { try { const region = getRegionFromArn(functionArn) if (!region) { @@ -227,7 +227,7 @@ export class LdkClient { return undefined } const client = this.getLambdaClient(region) - const configuration = (await client.getFunction(functionArn)).Configuration as Lambda.FunctionConfiguration + const configuration = (await client.getFunction(functionArn)).Configuration as FunctionConfiguration // get function detail // return function detail return configuration @@ -244,7 +244,7 @@ export class LdkClient { // 3: adding two param to lambda environment variable // {AWS_LAMBDA_EXEC_WRAPPER:/opt/bin/ldk_wrapper, AWS_LDK_DESTINATION_TOKEN: destinationToken } async createDebugDeployment( - config: Lambda.FunctionConfiguration, + config: FunctionConfiguration, destinationToken: string, lambdaTimeout: number, shouldPublishVersion: boolean, @@ -318,7 +318,7 @@ export class LdkClient { } // Create a temporary config for the update - const updateConfig: Lambda.FunctionConfiguration = { + const updateConfig: FunctionConfiguration = { FunctionName: config.FunctionName, Timeout: lambdaTimeout ?? 900, // 15 minutes Layers: updatedLayers.map((arn) => ({ Arn: arn })), @@ -362,7 +362,7 @@ export class LdkClient { // we are 1: reverting timeout to it's original snapshot // 2: reverting layer status according to it's original snapshot // 3: reverting environment back to it's original snapshot - async removeDebugDeployment(config: Lambda.FunctionConfiguration, check: boolean = true): Promise { + async removeDebugDeployment(config: FunctionConfiguration, check: boolean = true): Promise { try { if (!config.FunctionArn || !config.FunctionName) { throw new Error('Function ARN is missing') diff --git a/packages/core/src/lambda/remoteDebugging/ldkController.ts b/packages/core/src/lambda/remoteDebugging/ldkController.ts index 2b5553a8a05..83808f5f525 100644 --- a/packages/core/src/lambda/remoteDebugging/ldkController.ts +++ b/packages/core/src/lambda/remoteDebugging/ldkController.ts @@ -6,7 +6,7 @@ import * as vscode from 'vscode' import { getLogger } from '../../shared/logger/logger' import globals from '../../shared/extensionGlobals' -import type { Lambda } from 'aws-sdk' +import { FunctionConfiguration, Runtime } from '@aws-sdk/client-lambda' import { getRegionFromArn, LdkClient } from './ldkClient' import { getFamily, mapFamilyToDebugType } from '../models/samLambdaRuntime' import { findJavaPath } from '../../shared/utilities/pathFind' @@ -35,8 +35,8 @@ const mapExtensionToBackup = new Map([['ms-vscode.js-debug', 'ms // Helper function to create a human-readable diff message function createDiffMessage( - config: Lambda.FunctionConfiguration, - currentConfig: Lambda.FunctionConfiguration, + config: FunctionConfiguration, + currentConfig: FunctionConfiguration, isRevert: boolean = true ): string { let message = isRevert ? 'The following changes will be reverted:\n\n' : 'The following changes will be made:\n\n' @@ -248,7 +248,7 @@ function processOutFiles(outFiles: string[], localRoot: string): string[] { } async function getVscodeDebugConfig( - functionConfig: Lambda.FunctionConfiguration, + functionConfig: FunctionConfiguration, debugConfig: DebugConfig ): Promise { // Parse and validate otherDebugParams if provided @@ -283,7 +283,7 @@ async function getVscodeDebugConfig( const debugSessionName = `Debug ${functionConfig.FunctionArn!.split(':').pop()}` // Define debugConfig before the try block - const debugType = mapFamilyToDebugType.get(getFamily(functionConfig.Runtime ?? ''), 'unknown') + const debugType = mapFamilyToDebugType.get(getFamily(functionConfig.Runtime!), 'unknown') let vsCodeDebugConfig: vscode.DebugConfiguration switch (debugType) { case 'node': @@ -410,7 +410,7 @@ export class RemoteDebugController { } } - public supportCodeDownload(runtime: string | undefined, codeSha256: string | undefined = ''): boolean { + public supportCodeDownload(runtime: Runtime | undefined, codeSha256: string | undefined = ''): boolean { if (!runtime) { return false } @@ -426,7 +426,7 @@ export class RemoteDebugController { } } - public supportRuntimeRemoteDebug(runtime: string | undefined): boolean { + public supportRuntimeRemoteDebug(runtime: Runtime | undefined): boolean { if (!runtime) { return false } @@ -437,7 +437,7 @@ export class RemoteDebugController { } } - public async installDebugExtension(runtime: string | undefined): Promise { + public async installDebugExtension(runtime: Runtime | undefined): Promise { if (!runtime) { throw new ToolkitError('Runtime is undefined') } @@ -551,7 +551,7 @@ export class RemoteDebugController { } // Check if runtime / region is supported for remote debugging - if (!this.supportRuntimeRemoteDebug(runtime)) { + if (!this.supportRuntimeRemoteDebug(runtime as Runtime)) { throw new ToolkitError( `Runtime ${runtime} is not supported for remote debugging. ` + `Only Python, Node.js, and Java runtimes are supported.` diff --git a/packages/core/src/lambda/remoteDebugging/localStackLambdaDebugger.ts b/packages/core/src/lambda/remoteDebugging/localStackLambdaDebugger.ts index a7d98f06668..d74b6ac3471 100644 --- a/packages/core/src/lambda/remoteDebugging/localStackLambdaDebugger.ts +++ b/packages/core/src/lambda/remoteDebugging/localStackLambdaDebugger.ts @@ -4,7 +4,7 @@ */ import * as vscode from 'vscode' -import type { Lambda } from 'aws-sdk' +import { FunctionConfiguration } from '@aws-sdk/client-lambda' import globals from '../../shared/extensionGlobals' import { persistLambdaSnapshot, type LambdaDebugger, type DebugConfig } from './lambdaDebugger' import { getLambdaClientWithAgent, getLambdaDebugUserAgent } from './utils' @@ -35,7 +35,7 @@ export class LocalStackLambdaDebugger implements LambdaDebugger { public async setup( progress: vscode.Progress<{ message?: string; increment?: number }>, - functionConfig: Lambda.FunctionConfiguration, + functionConfig: FunctionConfiguration, region: string ): Promise { // No function update and version publishing needed for LocalStack @@ -95,7 +95,7 @@ export class LocalStackLambdaDebugger implements LambdaDebugger { public async waitForSetup( progress: vscode.Progress<{ message?: string; increment?: number }>, - functionConfig: Lambda.FunctionConfiguration, + functionConfig: FunctionConfiguration, region: string ): Promise { if (!functionConfig?.FunctionArn) { @@ -142,7 +142,7 @@ export class LocalStackLambdaDebugger implements LambdaDebugger { // b) Invokes for debug-enabled await being served until the debugger is connected } - public async cleanup(functionConfig: Lambda.FunctionConfiguration): Promise { + public async cleanup(functionConfig: FunctionConfiguration): Promise { await vscode.commands.executeCommand('workbench.action.debug.stop') const endpointUrl = globals.awsContext.getCredentialEndpointUrl() diff --git a/packages/core/src/lambda/remoteDebugging/remoteLambdaDebugger.ts b/packages/core/src/lambda/remoteDebugging/remoteLambdaDebugger.ts index 716f91d7e01..afc9f83abcd 100644 --- a/packages/core/src/lambda/remoteDebugging/remoteLambdaDebugger.ts +++ b/packages/core/src/lambda/remoteDebugging/remoteLambdaDebugger.ts @@ -4,7 +4,7 @@ */ import * as vscode from 'vscode' -import type { Lambda } from 'aws-sdk' +import { Architecture, FunctionConfiguration } from '@aws-sdk/client-lambda' import { persistLambdaSnapshot, type LambdaDebugger, type DebugConfig } from './lambdaDebugger' import { getLogger } from '../../shared/logger/logger' import { isTunnelInfo, LdkClient } from './ldkClient' @@ -14,7 +14,7 @@ import { getRemoteDebugLayerForArch } from './ldkLayers' export function getRemoteDebugLayer( region: string | undefined, - architectures: Lambda.ArchitecturesList | undefined + architectures: Architecture[] | undefined ): string | undefined { if (!region || !architectures) { return undefined @@ -50,7 +50,7 @@ export class RemoteLambdaDebugger implements LambdaDebugger { public async setup( progress: vscode.Progress<{ message?: string; increment?: number }>, - functionConfig: Lambda.FunctionConfiguration, + functionConfig: FunctionConfiguration, region: string ): Promise { const ldkClient = LdkClient.instance @@ -87,7 +87,7 @@ export class RemoteLambdaDebugger implements LambdaDebugger { public async waitForSetup( progress: vscode.Progress<{ message?: string; increment?: number }>, - functionConfig: Lambda.FunctionConfiguration, + functionConfig: FunctionConfiguration, region: string ): Promise { if (!this.tunnelInfo) { @@ -131,7 +131,7 @@ export class RemoteLambdaDebugger implements LambdaDebugger { } } - public async cleanup(functionConfig: Lambda.FunctionConfiguration): Promise { + public async cleanup(functionConfig: FunctionConfiguration): Promise { const ldkClient = LdkClient.instance if (!functionConfig?.FunctionArn) { throw new ToolkitError('No saved configuration found during cleanup') diff --git a/packages/core/src/lambda/utils.ts b/packages/core/src/lambda/utils.ts index a17783d37b8..9b8ffcb884a 100644 --- a/packages/core/src/lambda/utils.ts +++ b/packages/core/src/lambda/utils.ts @@ -8,7 +8,7 @@ const localize = nls.loadMessageBundle() import path from 'path' import xml2js = require('xml2js') -import { Lambda } from 'aws-sdk' +import { FunctionConfiguration, LayerVersionsListItem } from '@aws-sdk/client-lambda' import * as vscode from 'vscode' import { CloudFormationClient, StackSummary } from '../shared/clients/cloudFormation' import { DefaultLambdaClient, LambdaClient } from '../shared/clients/lambdaClient' @@ -36,7 +36,7 @@ export async function* listCloudFormationStacks(client: CloudFormationClient): A } } -export async function* listLambdaFunctions(client: LambdaClient): AsyncIterableIterator { +export async function* listLambdaFunctions(client: LambdaClient): AsyncIterableIterator { const status = vscode.window.setStatusBarMessage( localize('AWS.message.statusBar.loading.lambda', 'Loading Lambdas...') ) @@ -53,7 +53,7 @@ export async function* listLambdaFunctions(client: LambdaClient): AsyncIterableI export async function* listLayerVersions( client: LambdaClient, name: string -): AsyncIterableIterator { +): AsyncIterableIterator { const status = vscode.window.setStatusBarMessage( localize('AWS.message.statusBar.loading.lambda', 'Loading Lambda Layer Versions...') ) @@ -72,7 +72,7 @@ export async function* listLayerVersions( * Only works for supported languages (Python/JS) * @param configuration Lambda configuration object from getFunction */ -export function getLambdaDetails(configuration: Lambda.FunctionConfiguration): { +export function getLambdaDetails(configuration: FunctionConfiguration): { fileName: string functionName: string } { diff --git a/packages/core/src/lambda/vue/remoteInvoke/invokeLambda.ts b/packages/core/src/lambda/vue/remoteInvoke/invokeLambda.ts index d745de85f3e..9f72902f9e4 100644 --- a/packages/core/src/lambda/vue/remoteInvoke/invokeLambda.ts +++ b/packages/core/src/lambda/vue/remoteInvoke/invokeLambda.ts @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { _Blob } from 'aws-sdk/clients/lambda' import { readFileSync } from 'fs' // eslint-disable-line no-restricted-imports import * as _ from 'lodash' import * as vscode from 'vscode' @@ -19,7 +18,8 @@ import { getSampleLambdaPayloads, SampleRequest, isHotReloadingFunction } from ' import * as nls from 'vscode-nls' import { VueWebview } from '../../../webviews/main' -import { telemetry, Runtime } from '../../../shared/telemetry/telemetry' +import { telemetry, Runtime as TelemetryRuntime } from '../../../shared/telemetry/telemetry' +import { Runtime } from '@aws-sdk/client-lambda' import { runSamCliRemoteTestEvents, SamCliRemoteTestEventsParameters, @@ -58,7 +58,7 @@ export interface InitialData { Source?: string StackName?: string LogicalId?: string - Runtime?: string + Runtime?: Runtime LocalRootPath?: string LambdaFunctionNode?: LambdaFunctionNode supportCodeDownload?: boolean @@ -294,7 +294,8 @@ export class RemoteInvokeWebview extends VueWebview { ? await this.clientDebug.invoke(this.data.FunctionArn, input, qualifier) : await this.client.invoke(this.data.FunctionArn, input, qualifier) const logs = funcResponse.LogResult ? decodeBase64(funcResponse.LogResult) : '' - const payload = funcResponse.Payload ? funcResponse.Payload : JSON.stringify({}) + const decodedPayload = funcResponse.Payload ? new TextDecoder().decode(funcResponse.Payload) : '' + const payload = decodedPayload || JSON.stringify({}) this.channel.appendLine(`Invocation result for ${this.data.FunctionArn}`) this.channel.appendLine('Logs:') @@ -393,12 +394,14 @@ export class RemoteInvokeWebview extends VueWebview { return false } - const handlerFile = await getLambdaHandlerFile( - vscode.Uri.file(this.data.LocalRootPath), - '', - this.data.LambdaFunctionNode?.configuration.Handler ?? '', - this.data.Runtime ?? 'unknown' - ) + const handlerFile = this.data.Runtime + ? await getLambdaHandlerFile( + vscode.Uri.file(this.data.LocalRootPath), + '', + this.data.LambdaFunctionNode?.configuration.Handler ?? '', + this.data.Runtime + ) + : undefined if (!handlerFile || !(await fs.exists(handlerFile))) { this.handlerFileAvailable = false return false @@ -517,7 +520,7 @@ export class RemoteInvokeWebview extends VueWebview { // Download lambda code and update the local root path public async downloadRemoteCode(): Promise { return await telemetry.lambda_import.run(async (span) => { - span.record({ runtime: this.data.Runtime as Runtime | undefined, source: 'RemoteDebug' }) + span.record({ runtime: this.data.Runtime as TelemetryRuntime | undefined, source: 'RemoteDebug' }) try { if (this.data.LambdaFunctionNode) { const output = await runDownloadLambda(this.data.LambdaFunctionNode, true) @@ -762,7 +765,7 @@ export async function invokeRemoteLambda( const Panel = VueWebview.compilePanel(RemoteInvokeWebview) // Initialize support and debugging capabilities - const runtime = resource.configuration.Runtime ?? 'unknown' + const runtime = resource.configuration.Runtime const region = resource.regionCode const supportCodeDownload = RemoteDebugController.instance.supportCodeDownload( runtime, diff --git a/packages/core/src/lambda/wizards/samInitWizard.ts b/packages/core/src/lambda/wizards/samInitWizard.ts index 10906ec513d..9bd3a1b72fb 100644 --- a/packages/core/src/lambda/wizards/samInitWizard.ts +++ b/packages/core/src/lambda/wizards/samInitWizard.ts @@ -5,7 +5,7 @@ import * as nls from 'vscode-nls' import * as AWS from '@aws-sdk/types' -import { Runtime } from 'aws-sdk/clients/lambda' +import { Runtime } from '@aws-sdk/client-lambda' import * as path from 'path' import * as vscode from 'vscode' import { SchemasDataProvider } from '../../eventSchemas/providers/schemasDataProvider' @@ -231,7 +231,7 @@ export class CreateNewSamAppWizard extends Wizard { return false } - return samArmLambdaRuntimes.has(state.runtimeAndPackage?.runtime ?? 'unknown') + return state.runtimeAndPackage ? samArmLambdaRuntimes.has(state.runtimeAndPackage.runtime) : false } this.form.architecture.bindPrompter(createArchitecturePrompter, { diff --git a/packages/core/src/shared/activationReloadState.ts b/packages/core/src/shared/activationReloadState.ts index 70d236d2dd0..bcdefa925f3 100644 --- a/packages/core/src/shared/activationReloadState.ts +++ b/packages/core/src/shared/activationReloadState.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Runtime } from 'aws-sdk/clients/lambda' +import { Runtime } from '@aws-sdk/client-lambda' import globals from './extensionGlobals' export interface SamInitState { @@ -22,7 +22,7 @@ export class ActivationReloadState { return { template: globals.globalState.get('ACTIVATION_TEMPLATE_PATH_KEY'), readme: globals.globalState.get('ACTIVATION_LAUNCH_PATH_KEY'), - runtime: globals.globalState.get('SAM_INIT_RUNTIME_KEY'), + runtime: globals.globalState.get('SAM_INIT_RUNTIME_KEY'), architecture: globals.globalState.get('SAM_INIT_ARCH_KEY'), isImage: globals.globalState.get('SAM_INIT_IMAGE_BOOLEAN_KEY'), } diff --git a/packages/core/src/shared/clients/lambdaClient.ts b/packages/core/src/shared/clients/lambdaClient.ts index 949b80b2fee..d6805bf4a25 100644 --- a/packages/core/src/shared/clients/lambdaClient.ts +++ b/packages/core/src/shared/clients/lambdaClient.ts @@ -3,18 +3,45 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Lambda } from 'aws-sdk' -import { _Blob } from 'aws-sdk/clients/lambda' +import { BlobPayloadInputTypes } from '@smithy/types' import { ToolkitError } from '../errors' import globals from '../extensionGlobals' import { getLogger } from '../logger/logger' import { ClassToInterfaceType } from '../utilities/tsUtils' -import { LambdaClient as LambdaSdkClient, GetFunctionCommand, GetFunctionCommandOutput } from '@aws-sdk/client-lambda' +import { + LambdaClient as LambdaSdkClient, + GetFunctionCommand, + GetFunctionCommandOutput, + FunctionConfiguration, + InvocationResponse, + ListFunctionsRequest, + ListFunctionsResponse, + GetFunctionResponse, + GetLayerVersionResponse, + ListLayerVersionsRequest, + LayerVersionsListItem, + ListLayerVersionsResponse, + UpdateFunctionConfigurationRequest, + FunctionUrlConfig, + GetFunctionConfigurationCommand, + PublishVersionCommand, + UpdateFunctionConfigurationCommand, + UpdateFunctionCodeCommand, + ListFunctionUrlConfigsCommand, + ListLayerVersionsCommand, + GetLayerVersionCommand, + ListFunctionsCommand, + DeleteFunctionCommand, + InvokeCommand, + waitUntilFunctionUpdatedV2, + waitUntilFunctionActiveV2, +} from '@aws-sdk/client-lambda' import { CancellationError } from '../utilities/timeoutUtils' import { fromSSO } from '@aws-sdk/credential-provider-sso' import { getIAMConnection } from '../../auth/utils' import { WaiterConfiguration } from 'aws-sdk/lib/service' +import { NodeHttpHandler } from '@smithy/node-http-handler' export type LambdaClient = ClassToInterfaceType @@ -31,39 +58,35 @@ export class DefaultLambdaClient { public async deleteFunction(name: string, qualifier?: string): Promise { const sdkClient = await this.createSdkClient() - const response = await sdkClient - .deleteFunction({ + await sdkClient.send( + new DeleteFunctionCommand({ FunctionName: name, Qualifier: qualifier, }) - .promise() - - if (response.$response.error) { - throw response.$response.error - } + ) } - public async invoke(name: string, payload?: _Blob, version?: string): Promise { + public async invoke(name: string, payload?: BlobPayloadInputTypes, version?: string): Promise { const sdkClient = await this.createSdkClient() - const response = await sdkClient - .invoke({ + const response = await sdkClient.send( + new InvokeCommand({ FunctionName: name, LogType: 'Tail', Payload: payload, Qualifier: version, }) - .promise() + ) return response } - public async *listFunctions(): AsyncIterableIterator { + public async *listFunctions(): AsyncIterableIterator { const client = await this.createSdkClient() - const request: Lambda.ListFunctionsRequest = {} + const request: ListFunctionsRequest = {} do { - const response: Lambda.ListFunctionsResponse = await client.listFunctions(request).promise() + const response: ListFunctionsResponse = await client.send(new ListFunctionsCommand(request)) if (response.Functions) { yield* response.Functions @@ -73,12 +96,12 @@ export class DefaultLambdaClient { } while (request.Marker) } - public async getFunction(name: string): Promise { + public async getFunction(name: string): Promise { getLogger().debug(`GetFunction called for function: ${name}`) const client = await this.createSdkClient() try { - const response = await client.getFunction({ FunctionName: name }).promise() + const response = await client.send(new GetFunctionCommand({ FunctionName: name })) // prune `Code` from logs so we don't reveal a signed link to customer resources. getLogger().debug('GetFunction returned response (code section pruned): %O', { ...response, @@ -91,12 +114,12 @@ export class DefaultLambdaClient { } } - public async getLayerVersion(name: string, version: number): Promise { + public async getLayerVersion(name: string, version: number): Promise { getLogger().debug(`getLayerVersion called for LayerName: ${name}, VersionNumber ${version}`) const client = await this.createSdkClient() try { - const response = await client.getLayerVersion({ LayerName: name, VersionNumber: version }).promise() + const response = await client.send(new GetLayerVersionCommand({ LayerName: name, VersionNumber: version })) // prune `Code` from logs so we don't reveal a signed link to customer resources. getLogger().debug('getLayerVersion returned response (code section pruned): %O', { ...response, @@ -109,12 +132,12 @@ export class DefaultLambdaClient { } } - public async *listLayerVersions(name: string): AsyncIterableIterator { + public async *listLayerVersions(name: string): AsyncIterableIterator { const client = await this.createSdkClient() - const request: Lambda.ListLayerVersionsRequest = { LayerName: name } + const request: ListLayerVersionsRequest = { LayerName: name } do { - const response: Lambda.ListLayerVersionsResponse = await client.listLayerVersions(request).promise() + const response: ListLayerVersionsResponse = await client.send(new ListLayerVersionsCommand(request)) if (response.LayerVersions) { yield* response.LayerVersions @@ -124,38 +147,37 @@ export class DefaultLambdaClient { } while (request.Marker) } - public async getFunctionUrlConfigs(name: string): Promise { + public async getFunctionUrlConfigs(name: string): Promise { getLogger().debug(`GetFunctionUrlConfig called for function: ${name}`) const client = await this.createSdkClient() try { - const request = client.listFunctionUrlConfigs({ FunctionName: name }) - const response = await request.promise() + const response = await client.send(new ListFunctionUrlConfigsCommand({ FunctionName: name })) // prune `Code` from logs so we don't reveal a signed link to customer resources. getLogger().debug('GetFunctionUrlConfig returned response (code section pruned): %O', { ...response, Code: 'Pruned', }) - return response.FunctionUrlConfigs + return response.FunctionUrlConfigs ?? [] } catch (e) { throw ToolkitError.chain(e, 'Failed to get Lambda function URLs') } } - public async updateFunctionCode(name: string, zipFile: Uint8Array): Promise { + public async updateFunctionCode(name: string, zipFile: Uint8Array): Promise { getLogger().debug(`updateFunctionCode called for function: ${name}`) const client = await this.createSdkClient() try { - const response = await client - .updateFunctionCode({ + const response = await client.send( + new UpdateFunctionCodeCommand({ FunctionName: name, Publish: true, ZipFile: zipFile, }) - .promise() + ) getLogger().debug('updateFunctionCode returned response: %O', response) - await client.waitFor('functionUpdated', { FunctionName: name }).promise() + await waitUntilFunctionUpdatedV2({ client, maxWaitTime: 300 }, { FunctionName: name }) return response } catch (e) { @@ -165,14 +187,14 @@ export class DefaultLambdaClient { } public async updateFunctionConfiguration( - params: Lambda.UpdateFunctionConfigurationRequest, + params: UpdateFunctionConfigurationRequest, options: { maxRetries?: number initialDelayMs?: number backoffMultiplier?: number waitForUpdate?: boolean } = {} - ): Promise { + ): Promise { const client = await this.createSdkClient() const maxRetries = options.maxRetries ?? 5 const initialDelayMs = options.initialDelayMs ?? 1000 @@ -186,7 +208,7 @@ export class DefaultLambdaClient { // there could be race condition, if function is being updated, wait and retry while (retryCount <= maxRetries) { try { - const response = await client.updateFunctionConfiguration(params).promise() + const response = await client.send(new UpdateFunctionConfigurationCommand(params)) getLogger().debug('updateFunctionConfiguration returned response: %O', response) if (waitForUpdate) { // don't return if wait for result @@ -219,7 +241,9 @@ export class DefaultLambdaClient { let lastUpdateStatus = 'InProgress' while (lastUpdateStatus === 'InProgress') { await new Promise((resolve) => setTimeout(resolve, 1000)) - const response = await client.getFunctionConfiguration({ FunctionName: params.FunctionName }).promise() + const response = await client.send( + new GetFunctionConfigurationCommand({ FunctionName: params.FunctionName }) + ) lastUpdateStatus = response.LastUpdateStatus ?? 'Failed' if (lastUpdateStatus === 'Successful') { return response @@ -237,23 +261,23 @@ export class DefaultLambdaClient { public async publishVersion( name: string, options: { waitForUpdate?: boolean } = {} - ): Promise { + ): Promise { const client = await this.createSdkClient() // return until lambda update is completed const waitForUpdate = options.waitForUpdate ?? false - const response = await client - .publishVersion({ + const response = await client.send( + new PublishVersionCommand({ FunctionName: name, }) - .promise() + ) if (waitForUpdate) { let state = 'Pending' while (state === 'Pending') { await new Promise((resolve) => setTimeout(resolve, 1000)) - const statusResponse = await client - .getFunctionConfiguration({ FunctionName: name, Qualifier: response.Version }) - .promise() + const statusResponse = await client.send( + new GetFunctionConfigurationCommand({ FunctionName: name, Qualifier: response.Version }) + ) state = statusResponse.State ?? 'Failed' if (state === 'Active' || state === 'InActive') { // version creation finished @@ -280,27 +304,24 @@ export class DefaultLambdaClient { public async waitForActive(functionName: string, waiter?: WaiterConfiguration): Promise { const sdkClient = await this.createSdkClient() - await sdkClient - .waitFor('functionActive', { - FunctionName: functionName, - $waiter: waiter ?? { - delay: 1, - // In LocalStack, it requires 2 MBit/s connection to download ~150 MB Lambda image in 600 seconds - maxAttempts: 600, - }, - }) - .promise() + await waitUntilFunctionActiveV2( + { client: sdkClient, maxWaitTime: (waiter?.maxAttempts ?? 600) * (waiter?.delay ?? 1) }, + { FunctionName: functionName } + ) } - private async createSdkClient(): Promise { - return await globals.sdkClientBuilder.createAwsService( - Lambda, - { - httpOptions: { timeout: this.defaultTimeoutInMs }, - customUserAgent: this.userAgent, + private async createSdkClient(): Promise { + return globals.sdkClientBuilderV3.createAwsService({ + serviceClient: LambdaSdkClient, + userAgent: !this.userAgent, + clientOptions: { + userAgent: this.userAgent ? [[this.userAgent]] : undefined, + region: this.regionCode, + requestHandler: new NodeHttpHandler({ + requestTimeout: this.defaultTimeoutInMs, + }), }, - this.regionCode - ) + }) } } diff --git a/packages/core/src/shared/fs/templateRegistry.ts b/packages/core/src/shared/fs/templateRegistry.ts index 00afe876c4d..a9ec3a66ac8 100644 --- a/packages/core/src/shared/fs/templateRegistry.ts +++ b/packages/core/src/shared/fs/templateRegistry.ts @@ -18,6 +18,7 @@ import { Timeout } from '../utilities/timeoutUtils' import { localize } from '../utilities/vsCodeUtils' import { PerfLog } from '../logger/perfLogger' import { showMessageWithCancel } from '../utilities/messages' +import { Runtime } from '@aws-sdk/client-lambda' export class CloudFormationTemplateRegistry extends WatchedFiles { public name: string = 'CloudFormationTemplateRegistry' @@ -188,7 +189,7 @@ export function getResourcesForHandlerFromTemplateDatum( resource.Properties, 'Runtime', templateDatum.item - ) + ) as Runtime const registeredCodeUri = CloudFormation.getStringForProperty( resource.Properties, 'CodeUri', diff --git a/packages/core/src/shared/sam/cli/samCliInit.ts b/packages/core/src/shared/sam/cli/samCliInit.ts index b087b7cc5f4..366c7539519 100644 --- a/packages/core/src/shared/sam/cli/samCliInit.ts +++ b/packages/core/src/shared/sam/cli/samCliInit.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Runtime } from 'aws-sdk/clients/lambda' +import { Runtime } from '@aws-sdk/client-lambda' import { SchemaTemplateExtraContext } from '../../../eventSchemas/templates/schemasAppTemplateUtils' import { Architecture, DependencyManager } from '../../../lambda/models/samLambdaRuntime' import { getSamCliTemplateParameter, SamTemplate } from '../../../lambda/models/samTemplates' diff --git a/packages/core/src/shared/sam/cli/samCliLocalInvoke.ts b/packages/core/src/shared/sam/cli/samCliLocalInvoke.ts index 265b0c86338..c1e60ebcb41 100644 --- a/packages/core/src/shared/sam/cli/samCliLocalInvoke.ts +++ b/packages/core/src/shared/sam/cli/samCliLocalInvoke.ts @@ -15,7 +15,7 @@ import globals from '../../extensionGlobals' import { SamCliSettings } from './samCliSettings' import { addTelemetryEnvVar, collectSamErrors, SamCliError } from './samCliInvokerUtils' import { fs } from '../../fs/fs' -import { Runtime } from 'aws-sdk/clients/lambda' +import { Runtime } from '@aws-sdk/client-lambda' import { getSamCliPathAndVersion } from '../utils' import { deprecatedRuntimes } from '../../../lambda/models/samLambdaRuntime' diff --git a/packages/core/src/shared/sam/debugger/awsSamDebugConfiguration.ts b/packages/core/src/shared/sam/debugger/awsSamDebugConfiguration.ts index 389b91f6208..f11be86d00c 100644 --- a/packages/core/src/shared/sam/debugger/awsSamDebugConfiguration.ts +++ b/packages/core/src/shared/sam/debugger/awsSamDebugConfiguration.ts @@ -5,7 +5,7 @@ import * as vscode from 'vscode' import * as path from 'path' -import { Runtime } from 'aws-sdk/clients/lambda' +import { Runtime } from '@aws-sdk/client-lambda' import { getNormalizedRelativePath } from '../../utilities/pathUtils' import { APIGatewayProperties, diff --git a/packages/core/src/shared/sam/debugger/awsSamDebugConfigurationValidator.ts b/packages/core/src/shared/sam/debugger/awsSamDebugConfigurationValidator.ts index f71310f0261..b400746d7e6 100644 --- a/packages/core/src/shared/sam/debugger/awsSamDebugConfigurationValidator.ts +++ b/packages/core/src/shared/sam/debugger/awsSamDebugConfigurationValidator.ts @@ -20,6 +20,7 @@ import { } from './awsSamDebugConfiguration' import { tryGetAbsolutePath } from '../../utilities/workspaceUtils' import { CloudFormationTemplateRegistry } from '../../fs/templateRegistry' +import { Runtime } from '@aws-sdk/client-lambda' export interface ValidationResult { isValid: boolean @@ -187,7 +188,7 @@ export class DefaultAwsSamDebugConfigurationValidator implements AwsSamDebugConf } } // can't infer the runtime for image-based lambdas - if (!config.lambda?.runtime || !samImageLambdaRuntimes().has(config.lambda.runtime)) { + if (!config.lambda?.runtime || !samImageLambdaRuntimes().has(config.lambda.runtime as Runtime)) { return { isValid: false, message: localize( @@ -201,7 +202,7 @@ export class DefaultAwsSamDebugConfigurationValidator implements AwsSamDebugConf // TODO: Decide what to do with this re: refs. // As of now, this has to be directly declared without a ref, despite the fact that SAM will handle a ref. // Should we just pass validation off to SAM and ignore validation at this point, or should we directly process the value (like the handler)? - const runtime = CloudFormation.getStringForProperty(resource?.Properties, 'Runtime', cfnTemplate) + const runtime = CloudFormation.getStringForProperty(resource?.Properties, 'Runtime', cfnTemplate) as Runtime if (!runtime || !samZipLambdaRuntimes.has(runtime)) { return { isValid: false, @@ -262,7 +263,10 @@ export class DefaultAwsSamDebugConfigurationValidator implements AwsSamDebugConf } private validateCodeConfig(debugConfiguration: AwsSamDebuggerConfiguration): ValidationResult { - if (!debugConfiguration.lambda?.runtime || !samZipLambdaRuntimes.has(debugConfiguration.lambda.runtime)) { + if ( + !debugConfiguration.lambda?.runtime || + !samZipLambdaRuntimes.has(debugConfiguration.lambda.runtime as Runtime) + ) { return { isValid: false, message: localize( diff --git a/packages/core/src/shared/sam/debugger/awsSamDebugger.ts b/packages/core/src/shared/sam/debugger/awsSamDebugger.ts index 2b6e9311e6b..217ce451dcd 100644 --- a/packages/core/src/shared/sam/debugger/awsSamDebugger.ts +++ b/packages/core/src/shared/sam/debugger/awsSamDebugger.ts @@ -59,7 +59,8 @@ import { minSamCliVersionForImageSupport, minSamCliVersionForGoSupport } from '. import { getIdeProperties } from '../../extensionUtilities' import { resolve } from 'path' import globals from '../../extensionGlobals' -import { Runtime, telemetry } from '../../telemetry/telemetry' +import { telemetry, Runtime as TelemetryRuntime } from '../../telemetry/telemetry' +import { Runtime } from '@aws-sdk/client-lambda' import { ErrorInformation, isUserCancelledError, ToolkitError } from '../../errors' import { openLaunchJsonFile } from './commands/addSamDebugConfiguration' import { Logging } from '../../logger/commands' @@ -471,8 +472,8 @@ export class SamDebugConfigProvider implements vscode.DebugConfigurationProvider } const isZip = CloudFormation.isZipLambdaResource(templateResource?.Properties) - const runtime: string | undefined = - config.lambda?.runtime ?? + const runtime: Runtime | undefined = + (config.lambda?.runtime as Runtime) ?? (template && isZip ? CloudFormation.getStringForProperty(templateResource?.Properties, 'Runtime', template) : undefined) ?? @@ -690,7 +691,7 @@ export class SamDebugConfigProvider implements vscode.DebugConfigurationProvider public async invokeConfig(config: SamLaunchRequestArgs): Promise { telemetry.record({ debug: !config.noDebug, - runtime: config.runtime as Runtime, + runtime: config.runtime as TelemetryRuntime, lambdaArchitecture: config.architecture, lambdaPackageType: (await isImageLambdaConfig(config)) ? 'Image' : 'Zip', version: await getSamCliVersion(getSamCliContext()), diff --git a/packages/core/src/shared/sam/debugger/pythonSamDebug.ts b/packages/core/src/shared/sam/debugger/pythonSamDebug.ts index 670c2ddd71a..902dc85003d 100644 --- a/packages/core/src/shared/sam/debugger/pythonSamDebug.ts +++ b/packages/core/src/shared/sam/debugger/pythonSamDebug.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Runtime } from 'aws-sdk/clients/lambda' +import { Runtime } from '@aws-sdk/client-lambda' import * as os from 'os' import * as path from 'path' import { @@ -166,7 +166,7 @@ function getPythonExeAndBootstrap(runtime: Runtime) { return { python: '/var/lang/bin/python3.11', bootstrap: '/var/runtime/bootstrap.py' } case 'python3.12': return { python: '/var/lang/bin/python3.12', bootstrap: '/var/runtime/bootstrap.py' } - case 'python3.13': + case 'python3.13' as Runtime: return { python: '/var/lang/bin/python3.13', bootstrap: '/var/runtime/bootstrap.py' } default: throw new Error(`Python SAM debug logic ran for invalid Python runtime: ${runtime}`) diff --git a/packages/core/src/shared/sam/localLambdaRunner.ts b/packages/core/src/shared/sam/localLambdaRunner.ts index 6d28048be48..447fad81f26 100644 --- a/packages/core/src/shared/sam/localLambdaRunner.ts +++ b/packages/core/src/shared/sam/localLambdaRunner.ts @@ -32,6 +32,7 @@ import { SamCliError } from './cli/samCliInvokerUtils' import fs from '../fs/fs' import { getSpawnEnv } from '../env/resolveEnv' import { asEnvironmentVariables } from '../../auth/credentials/utils' +import { Runtime } from '@aws-sdk/client-lambda' const localize = nls.loadMessageBundle() @@ -247,7 +248,7 @@ async function invokeLambdaHandler( parameterOverrides: config.parameterOverrides, name: config.name, region: config.region, - runtime: config.lambda?.runtime, + runtime: config.lambda?.runtime as Runtime, } // sam local invoke ... @@ -524,7 +525,7 @@ export async function waitForPort(port: number, timeout: Timeout, isDebugPort: b } } -export function shouldAppendRelativePathToFuncHandler(runtime: string): boolean { +export function shouldAppendRelativePathToFuncHandler(runtime: Runtime): boolean { // getFamily will throw an error if the runtime doesn't exist switch (getFamily(runtime)) { case RuntimeFamily.NodeJS: diff --git a/packages/core/src/shared/sam/utils.ts b/packages/core/src/shared/sam/utils.ts index ca2446fe3e9..51e93e80645 100644 --- a/packages/core/src/shared/sam/utils.ts +++ b/packages/core/src/shared/sam/utils.ts @@ -18,6 +18,7 @@ import { telemetry } from '../telemetry/telemetry' import globals from '../extensionGlobals' import { getLogger } from '../logger/logger' import { ChildProcessResult } from '../utilities/processUtils' +import { Runtime } from '@aws-sdk/client-lambda' /** * @description determines the root directory of the project given Template Item @@ -66,7 +67,7 @@ export async function isDotnetRuntime(templateUri: vscode.Uri, contents?: string } } } - const globalRuntime = samTemplate.template.Globals?.Function?.Runtime as string + const globalRuntime = samTemplate.template.Globals?.Function?.Runtime as Runtime return globalRuntime ? getFamily(globalRuntime) === RuntimeFamily.DotNet : false } diff --git a/packages/core/src/shared/ui/sam/stackPrompter.ts b/packages/core/src/shared/ui/sam/stackPrompter.ts index be1350489c5..3e86dc08859 100644 --- a/packages/core/src/shared/ui/sam/stackPrompter.ts +++ b/packages/core/src/shared/ui/sam/stackPrompter.ts @@ -2,7 +2,7 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ -import { StackSummary } from 'aws-sdk/clients/cloudformation' +import { StackSummary } from '@aws-sdk/client-cloudformation' import { getAwsConsoleUrl } from '../../awsConsole' import { CloudFormationClient } from '../../clients/cloudFormation' import * as vscode from 'vscode' @@ -13,9 +13,10 @@ import { getRecentResponse } from '../../sam/utils' export const localize = nls.loadMessageBundle() -const canPickStack = (s: StackSummary) => s.StackStatus.endsWith('_COMPLETE') +const canPickStack = (s: StackSummary) => s.StackStatus?.endsWith('_COMPLETE') const canShowStack = (s: StackSummary) => - (s.StackStatus.endsWith('_COMPLETE') || s.StackStatus.endsWith('_IN_PROGRESS')) && !s.StackStatus.includes('DELETE') + (s.StackStatus?.endsWith('_COMPLETE') || s.StackStatus?.endsWith('_IN_PROGRESS')) && + !s.StackStatus.includes('DELETE') /** * Creates a quick pick prompter for choosing a CloudFormation stack diff --git a/packages/core/src/test/awsService/appBuilder/lambda2sam/lambda2samCoreLogic.test.ts b/packages/core/src/test/awsService/appBuilder/lambda2sam/lambda2samCoreLogic.test.ts index 05a5aad9ed4..c618dac2197 100644 --- a/packages/core/src/test/awsService/appBuilder/lambda2sam/lambda2samCoreLogic.test.ts +++ b/packages/core/src/test/awsService/appBuilder/lambda2sam/lambda2samCoreLogic.test.ts @@ -19,7 +19,7 @@ import { ToolkitError } from '../../../../shared/errors' import os from 'os' import path from 'path' import { LAMBDA_FUNCTION_TYPE } from '../../../../shared/cloudformation/cloudformation' -import { ResourcesToImport } from 'aws-sdk/clients/cloudformation' +import { ResourceToImport } from '@aws-sdk/client-cloudformation' describe('lambda2samCoreLogic', function () { let sandbox: sinon.SinonSandbox @@ -422,7 +422,7 @@ describe('lambda2samCoreLogic', function () { // Setup Lambda node const lambdaNode = mockLambdaNode() - const resourceToImport: ResourcesToImport = [ + const resourceToImport: ResourceToImport[] = [ { ResourceType: LAMBDA_FUNCTION_TYPE, LogicalResourceId: 'TestFunc', @@ -470,7 +470,7 @@ describe('lambda2samCoreLogic', function () { // Make createChangeSet fail cfnClientStub.createChangeSet.resolves({}) // No Id - const resourceToImport: ResourcesToImport = [ + const resourceToImport: ResourceToImport[] = [ { ResourceType: LAMBDA_FUNCTION_TYPE, LogicalResourceId: 'TestFunc', diff --git a/packages/core/src/test/awsService/appBuilder/utils.test.ts b/packages/core/src/test/awsService/appBuilder/utils.test.ts index eaaa69254d7..08edd14f47c 100644 --- a/packages/core/src/test/awsService/appBuilder/utils.test.ts +++ b/packages/core/src/test/awsService/appBuilder/utils.test.ts @@ -26,9 +26,11 @@ import { assertTextEditorContains } from '../../testUtil' import { DefaultLambdaClient } from '../../../shared/clients/lambdaClient' import { ToolkitError } from '../../../shared/errors' import globals from '../../../shared/extensionGlobals' +import { Runtime } from '@aws-sdk/client-lambda' +import { CloudFormationClient } from '@aws-sdk/client-cloudformation' interface TestScenario { - runtime: string + runtime: Runtime handler: string codeUri: string fileLocation: string @@ -505,7 +507,7 @@ describe('AppBuilder Utils', function () { mockLambdaClient.invoke.rejects(permissionError) try { - await enhancedClient.invoke('test-function', '{}') + await enhancedClient.invoke('test-function', new TextEncoder().encode('{}')) assert.fail('Expected error to be thrown') } catch (error) { assert(error instanceof ToolkitError) @@ -571,19 +573,13 @@ describe('AppBuilder Utils', function () { }) describe('EnhancedCloudFormationClient', function () { - let mockCfnClient: any + let mockCfnClient: sinon.SinonStubbedInstance let enhancedClient: EnhancedCloudFormationClient beforeEach(function () { // Create a mock CloudFormation client with all required methods - mockCfnClient = { - describeStacks: sandbox.stub(), - getTemplate: sandbox.stub(), - createChangeSet: sandbox.stub(), - describeStackResource: sandbox.stub(), - describeStackResources: sandbox.stub(), - } - enhancedClient = new EnhancedCloudFormationClient(mockCfnClient, 'us-east-1') + mockCfnClient = sandbox.createStubInstance(CloudFormationClient) + enhancedClient = new EnhancedCloudFormationClient(mockCfnClient as any, 'us-east-1') }) it('should enhance permission errors for describeStacks', async function () { @@ -592,9 +588,7 @@ describe('AppBuilder Utils', function () { time: new Date(), statusCode: 403, }) - mockCfnClient.describeStacks.returns({ - promise: sandbox.stub().rejects(permissionError), - } as any) + mockCfnClient.send.rejects(permissionError) try { await enhancedClient.describeStacks({ StackName: 'test-stack' }) @@ -619,9 +613,7 @@ describe('AppBuilder Utils', function () { time: new Date(), statusCode: 403, }) - mockCfnClient.getTemplate.returns({ - promise: sandbox.stub().rejects(permissionError), - } as any) + mockCfnClient.send.rejects(permissionError) try { await enhancedClient.getTemplate({ StackName: 'test-stack' }) @@ -644,9 +636,7 @@ describe('AppBuilder Utils', function () { time: new Date(), statusCode: 403, }) - mockCfnClient.createChangeSet.returns({ - promise: sandbox.stub().rejects(permissionError), - } as any) + mockCfnClient.send.rejects(permissionError) try { await enhancedClient.createChangeSet({ @@ -673,9 +663,7 @@ describe('AppBuilder Utils', function () { time: new Date(), statusCode: 403, }) - mockCfnClient.describeStackResource.returns({ - promise: sandbox.stub().rejects(permissionError), - } as any) + mockCfnClient.send.rejects(permissionError) try { await enhancedClient.describeStackResource({ @@ -701,9 +689,7 @@ describe('AppBuilder Utils', function () { time: new Date(), statusCode: 403, }) - mockCfnClient.describeStackResources.returns({ - promise: sandbox.stub().rejects(permissionError), - } as any) + mockCfnClient.send.rejects(permissionError) try { await enhancedClient.describeStackResources({ StackName: 'test-stack' }) @@ -722,9 +708,7 @@ describe('AppBuilder Utils', function () { it('should pass through non-permission errors', async function () { const nonPermissionError = new Error('Stack not found') - mockCfnClient.describeStacks.returns({ - promise: sandbox.stub().rejects(nonPermissionError), - } as any) + mockCfnClient.send.rejects(nonPermissionError) try { await enhancedClient.describeStacks({ StackName: 'test-stack' }) @@ -736,9 +720,7 @@ describe('AppBuilder Utils', function () { it('should return successful results when no errors occur', async function () { const mockResponse = { Stacks: [{ StackName: 'test-stack' }] } - mockCfnClient.describeStacks.returns({ - promise: sandbox.stub().resolves(mockResponse), - } as any) + mockCfnClient.send.resolves(mockResponse) const result = await enhancedClient.describeStacks({ StackName: 'test-stack' }) assert.strictEqual(result, mockResponse) @@ -748,7 +730,7 @@ describe('AppBuilder Utils', function () { describe('Client Factory Functions', function () { beforeEach(function () { // Stub the global SDK client builder - sandbox.stub(globals.sdkClientBuilder, 'createAwsService').resolves({} as any) + sandbox.stub(globals.sdkClientBuilderV3, 'createAwsService').resolves({} as any) }) it('should return EnhancedLambdaClient from getLambdaClient', function () { diff --git a/packages/core/src/test/eventSchemas/model/schemaCodeLangs.test.ts b/packages/core/src/test/eventSchemas/model/schemaCodeLangs.test.ts index 619f7bd035e..6c023a52676 100644 --- a/packages/core/src/test/eventSchemas/model/schemaCodeLangs.test.ts +++ b/packages/core/src/test/eventSchemas/model/schemaCodeLangs.test.ts @@ -10,6 +10,7 @@ import { schemaCodeLangs, } from '../../../eventSchemas/models/schemaCodeLangs' import { samZipLambdaRuntimes } from '../../../lambda/models/samLambdaRuntime' +import { Runtime } from '@aws-sdk/client-lambda' describe('getLanguageDetails', function () { it('should successfully return details for supported languages', function () { @@ -32,7 +33,7 @@ describe('getApiValueForSchemasDownload', function () { case 'python3.9': case 'python3.11': case 'python3.12': - case 'python3.13': + case 'python3.13' as Runtime: case 'python3.10': { const result = getApiValueForSchemasDownload(runtime) assert.strictEqual(result, 'Python36', 'Api value used by schemas api') diff --git a/packages/core/src/test/lambda/commands/copyLambdaUrl.test.ts b/packages/core/src/test/lambda/commands/copyLambdaUrl.test.ts index e55267182a3..acd3b98f052 100644 --- a/packages/core/src/test/lambda/commands/copyLambdaUrl.test.ts +++ b/packages/core/src/test/lambda/commands/copyLambdaUrl.test.ts @@ -10,7 +10,7 @@ import { LambdaFunctionNode } from '../../../lambda/explorer/lambdaFunctionNode' import { DefaultLambdaClient, LambdaClient } from '../../../shared/clients/lambdaClient' import { addCodiconToString } from '../../../shared/utilities/textUtilities' import { env } from 'vscode' -import { FunctionUrlConfig } from 'aws-sdk/clients/lambda' +import { FunctionUrlConfig } from '@aws-sdk/client-lambda' import { createQuickPickPrompterTester } from '../../shared/ui/testUtils' import { getTestWindow } from '../../shared/vscode/window' @@ -22,11 +22,11 @@ import { getTestWindow } from '../../shared/vscode/window' */ export function buildFunctionUrlConfig(options: Partial): FunctionUrlConfig { return { - AuthType: options.AuthType ?? '', - CreationTime: options.CreationTime ?? '', - FunctionArn: options.FunctionArn ?? '', - FunctionUrl: options.FunctionUrl ?? '', - LastModifiedTime: options.LastModifiedTime ?? '', + AuthType: options.AuthType, + CreationTime: options.CreationTime, + FunctionArn: options.FunctionArn, + FunctionUrl: options.FunctionUrl, + LastModifiedTime: options.LastModifiedTime, } } @@ -94,10 +94,10 @@ describe('lambda func url prompter', async () => { const tester = createQuickPickPrompterTester(prompter) tester.assertItems( configList.map((c) => { - return { label: c.FunctionArn, data: c.FunctionUrl } // order matters + return { label: c.FunctionArn!, data: c.FunctionUrl } // order matters }) ) - tester.acceptItem(configList[1].FunctionArn) + tester.acceptItem(configList[1].FunctionArn!) await tester.result(configList[1].FunctionUrl) }) }) diff --git a/packages/core/src/test/lambda/commands/createNewSamApp.test.ts b/packages/core/src/test/lambda/commands/createNewSamApp.test.ts index 8bb25119301..c31f922483c 100644 --- a/packages/core/src/test/lambda/commands/createNewSamApp.test.ts +++ b/packages/core/src/test/lambda/commands/createNewSamApp.test.ts @@ -26,7 +26,7 @@ import { import { normalize } from '../../../shared/utilities/pathUtils' import { getIdeProperties, isCloud9 } from '../../../shared/extensionUtilities' import globals from '../../../shared/extensionGlobals' -import { Runtime } from '../../../shared/telemetry/telemetry' +import { Runtime } from '@aws-sdk/client-lambda' import { stub } from '../../utilities/stubber' import sinon from 'sinon' import { fs } from '../../../shared' diff --git a/packages/core/src/test/lambda/local/debugConfiguration.test.ts b/packages/core/src/test/lambda/local/debugConfiguration.test.ts index 12192127eeb..0a0aab0dc99 100644 --- a/packages/core/src/test/lambda/local/debugConfiguration.test.ts +++ b/packages/core/src/test/lambda/local/debugConfiguration.test.ts @@ -18,7 +18,7 @@ import { CloudFormationTemplateRegistry } from '../../../shared/fs/templateRegis import { getArchitecture, isImageLambdaConfig } from '../../../lambda/local/debugConfiguration' import * as CloudFormation from '../../../shared/cloudformation/cloudformation' import globals from '../../../shared/extensionGlobals' -import { Runtime } from '../../../shared/telemetry/telemetry' +import { Runtime } from '@aws-sdk/client-lambda' import { fs } from '../../../shared' describe('makeCoreCLRDebugConfiguration', function () { diff --git a/packages/core/src/test/lambda/models/samLambdaRuntime.test.ts b/packages/core/src/test/lambda/models/samLambdaRuntime.test.ts index f47cc3fe06b..566c465a0dd 100644 --- a/packages/core/src/test/lambda/models/samLambdaRuntime.test.ts +++ b/packages/core/src/test/lambda/models/samLambdaRuntime.test.ts @@ -4,7 +4,6 @@ */ import assert from 'assert' -import { Runtime } from 'aws-sdk/clients/lambda' import { compareSamLambdaRuntime, getDependencyManager, @@ -16,11 +15,12 @@ import { getNodeMajorVersion, nodeJsRuntimes, } from '../../../lambda/models/samLambdaRuntime' +import { Runtime } from '@aws-sdk/client-lambda' describe('compareSamLambdaRuntime', async function () { const scenarios: { - lowerRuntime: Runtime - higherRuntime: Runtime + lowerRuntime: string + higherRuntime: string }[] = [ { lowerRuntime: 'nodejs14.x', higherRuntime: 'nodejs16.x' }, { lowerRuntime: 'nodejs16.x', higherRuntime: 'nodejs16.x (Image)' }, @@ -48,13 +48,13 @@ describe('getDependencyManager', function () { assert.throws(() => getDependencyManager('nodejs')) }) it('throws on unknown runtimes', function () { - assert.throws(() => getDependencyManager('BASIC')) + assert.throws(() => getDependencyManager('BASIC' as Runtime)) }) }) describe('getFamily', function () { it('unknown runtime name', function () { - assert.strictEqual(getFamily('foo'), RuntimeFamily.Unknown) + assert.strictEqual(getFamily('foo' as Runtime), RuntimeFamily.Unknown) }) it('handles all known runtimes', function () { for (const runtime of samZipLambdaRuntimes) { diff --git a/packages/core/src/test/lambda/models/samTemplates.test.ts b/packages/core/src/test/lambda/models/samTemplates.test.ts index 4abb3f87315..7fe78e630c8 100644 --- a/packages/core/src/test/lambda/models/samTemplates.test.ts +++ b/packages/core/src/test/lambda/models/samTemplates.test.ts @@ -20,6 +20,7 @@ import { import { Set } from 'immutable' import { samZipLambdaRuntimes } from '../../../lambda/models/samLambdaRuntime' +import { Runtime } from '@aws-sdk/client-lambda' let validTemplateOptions: Set let validPythonTemplateOptions: Set @@ -66,7 +67,7 @@ describe('getSamTemplateWizardOption', function () { case 'python3.10': case 'python3.11': case 'python3.12': - case 'python3.13': + case 'python3.13' as Runtime: assert.deepStrictEqual( result, validPythonTemplateOptions, diff --git a/packages/core/src/test/lambda/remoteDebugging/ldkClient.test.ts b/packages/core/src/test/lambda/remoteDebugging/ldkClient.test.ts index 24c9b956e70..c91be446753 100644 --- a/packages/core/src/test/lambda/remoteDebugging/ldkClient.test.ts +++ b/packages/core/src/test/lambda/remoteDebugging/ldkClient.test.ts @@ -5,7 +5,7 @@ import assert from 'assert' import sinon from 'sinon' -import { Lambda } from 'aws-sdk' +import { FunctionConfiguration } from '@aws-sdk/client-lambda' import { LdkClient, getRegionFromArn, isTunnelInfo } from '../../../lambda/remoteDebugging/ldkClient' import { LocalProxy } from '../../../lambda/remoteDebugging/localProxy' import * as utils from '../../../lambda/remoteDebugging/utils' @@ -191,7 +191,7 @@ describe('LdkClient', () => { }) describe('getFunctionDetail()', () => { - const mockFunctionConfig: Lambda.FunctionConfiguration = createMockFunctionConfig({ + const mockFunctionConfig: FunctionConfiguration = createMockFunctionConfig({ FunctionArn: 'arn:aws:lambda:us-east-1:123456789012:function:testFunction', }) @@ -220,7 +220,7 @@ describe('LdkClient', () => { }) describe('createDebugDeployment()', () => { - const mockFunctionConfig: Lambda.FunctionConfiguration = createMockFunctionConfig({ + const mockFunctionConfig: FunctionConfiguration = createMockFunctionConfig({ FunctionArn: 'arn:aws:lambda:us-east-1:123456789012:function:testFunction', }) @@ -299,7 +299,7 @@ describe('LdkClient', () => { }) describe('removeDebugDeployment()', () => { - const mockFunctionConfig: Lambda.FunctionConfiguration = createMockFunctionConfig({ + const mockFunctionConfig: FunctionConfiguration = createMockFunctionConfig({ FunctionArn: 'arn:aws:lambda:us-east-1:123456789012:function:testFunction', }) diff --git a/packages/core/src/test/lambda/remoteDebugging/ldkController.test.ts b/packages/core/src/test/lambda/remoteDebugging/ldkController.test.ts index fe4062bf673..525f8ad80f3 100644 --- a/packages/core/src/test/lambda/remoteDebugging/ldkController.test.ts +++ b/packages/core/src/test/lambda/remoteDebugging/ldkController.test.ts @@ -6,7 +6,7 @@ import assert from 'assert' import * as vscode from 'vscode' import sinon, { SinonStubbedInstance, createStubInstance } from 'sinon' -import { Lambda } from 'aws-sdk' +import { FunctionConfiguration } from '@aws-sdk/client-lambda' import { RemoteDebugController, activateRemoteDebugging, @@ -200,7 +200,7 @@ describe('RemoteDebugController', () => { describe('Debug Session Management', () => { let mockConfig: DebugConfig - let mockFunctionConfig: Lambda.FunctionConfiguration + let mockFunctionConfig: FunctionConfiguration beforeEach(() => { mockConfig = createMockDebugConfig({ @@ -406,7 +406,7 @@ describe('RemoteDebugController', () => { describe('Telemetry Verification', () => { let mockConfig: DebugConfig - let mockFunctionConfig: Lambda.FunctionConfiguration + let mockFunctionConfig: FunctionConfiguration beforeEach(() => { mockConfig = createMockDebugConfig({ diff --git a/packages/core/src/test/lambda/remoteDebugging/localStackLambdaDebugger.test.ts b/packages/core/src/test/lambda/remoteDebugging/localStackLambdaDebugger.test.ts index 46448cbbc08..d91fc150f71 100644 --- a/packages/core/src/test/lambda/remoteDebugging/localStackLambdaDebugger.test.ts +++ b/packages/core/src/test/lambda/remoteDebugging/localStackLambdaDebugger.test.ts @@ -18,7 +18,7 @@ import { setupMockVSCodeDebugAPIs, } from './testUtils' import { DebugConfig } from '../../../lambda/remoteDebugging/lambdaDebugger' -import { Lambda } from 'aws-sdk' +import { FunctionConfiguration, Runtime } from '@aws-sdk/client-lambda' import { assertTelemetry } from '../../testUtil' import * as remoteDebuggingUtils from '../../../lambda/remoteDebugging/utils' import { DefaultLambdaClient } from '../../../shared/clients/lambdaClient' @@ -31,7 +31,7 @@ describe('RemoteDebugController with LocalStackLambdaDebugger', () => { let controller: RemoteDebugController let mockGlobalState: any let mockConfig: DebugConfig - let mockFunctionConfig: Lambda.FunctionConfiguration + let mockFunctionConfig: FunctionConfiguration let fetchStub: sinon.SinonStub beforeEach(() => { @@ -60,7 +60,7 @@ describe('RemoteDebugController with LocalStackLambdaDebugger', () => { layerArn: undefined, lambdaTimeout: undefined, }) - mockFunctionConfig = createMockFunctionConfig({ Runtime: 'nodejs22.x' }) + mockFunctionConfig = createMockFunctionConfig({ Runtime: 'nodejs22.x' as Runtime }) }) afterEach(() => { diff --git a/packages/core/src/test/lambda/remoteDebugging/testUtils.ts b/packages/core/src/test/lambda/remoteDebugging/testUtils.ts index 03aec290426..42deaa4ec96 100644 --- a/packages/core/src/test/lambda/remoteDebugging/testUtils.ts +++ b/packages/core/src/test/lambda/remoteDebugging/testUtils.ts @@ -4,7 +4,7 @@ */ import sinon from 'sinon' -import { Lambda } from 'aws-sdk' +import { Architecture, FunctionConfiguration, Runtime, SnapStartApplyOn } from '@aws-sdk/client-lambda' import { LambdaFunctionNode } from '../../../lambda/explorer/lambdaFunctionNode' import { InitialData } from '../../../lambda/vue/remoteInvoke/invokeLambda' import type { DebugConfig } from '../../../lambda/remoteDebugging/lambdaDebugger' @@ -12,19 +12,17 @@ import type { DebugConfig } from '../../../lambda/remoteDebugging/lambdaDebugger /** * Creates a mock Lambda function configuration for testing */ -export function createMockFunctionConfig( - overrides: Partial = {} -): Lambda.FunctionConfiguration { +export function createMockFunctionConfig(overrides: Partial = {}): FunctionConfiguration { return { FunctionName: 'testFunction', FunctionArn: 'arn:aws:lambda:us-west-2:123456789012:function:testFunction', - Runtime: 'nodejs18.x', + Runtime: Runtime.nodejs18x, Handler: 'index.handler', Timeout: 30, Layers: [], Environment: { Variables: {} }, - Architectures: ['x86_64'], - SnapStart: { ApplyOn: 'None' }, + Architectures: [Architecture.x86_64], + SnapStart: { ApplyOn: SnapStartApplyOn.None }, ...overrides, } } diff --git a/packages/core/src/test/lambda/utils.test.ts b/packages/core/src/test/lambda/utils.test.ts index a3eebe043a7..7a8e82043cf 100644 --- a/packages/core/src/test/lambda/utils.test.ts +++ b/packages/core/src/test/lambda/utils.test.ts @@ -18,6 +18,7 @@ import { DefaultLambdaClient } from '../../shared/clients/lambdaClient' import { fs } from '../../shared/fs/fs' import { tempDirPath } from '../../shared/filesystemUtilities' import path from 'path' +import { Runtime } from '@aws-sdk/client-lambda' describe('lambda utils', function () { const mockLambda = { @@ -67,7 +68,7 @@ describe('lambda utils', function () { }) ) // runtime that isn't present, period - assert.throws(() => getLambdaDetails({ Runtime: 'COBOL-60', Handler: 'asdf.asdf' })) + assert.throws(() => getLambdaDetails({ Runtime: 'COBOL-60' as Runtime, Handler: 'asdf.asdf' })) }) }) diff --git a/packages/core/src/test/lambda/vue/remoteInvoke/invokeLambda.test.ts b/packages/core/src/test/lambda/vue/remoteInvoke/invokeLambda.test.ts index e04f017acfb..90f448e750e 100644 --- a/packages/core/src/test/lambda/vue/remoteInvoke/invokeLambda.test.ts +++ b/packages/core/src/test/lambda/vue/remoteInvoke/invokeLambda.test.ts @@ -22,6 +22,7 @@ import * as samCliRemoteTestEvent from '../../../../shared/sam/cli/samCliRemoteT import { TestEventsOperation, SamCliRemoteTestEventsParameters } from '../../../../shared/sam/cli/samCliRemoteTestEvent' import { assertLogsContain } from '../../../globalSetup.test' import { createResponse } from '../../../testUtil' +import { InvocationResponse } from '@aws-sdk/client-lambda' describe('RemoteInvokeWebview', () => { let outputChannel: vscode.OutputChannel @@ -61,8 +62,8 @@ describe('RemoteInvokeWebview', () => { const input = '{"key": "value"}' const mockResponse = { LogResult: Buffer.from('Test log').toString('base64'), - Payload: '{"result": "success"}', - } + Payload: new TextEncoder().encode('{"result": "success"}'), + } satisfies InvocationResponse client.invoke.resolves(mockResponse) const appendedLines: string[] = [] @@ -87,8 +88,8 @@ describe('RemoteInvokeWebview', () => { it('handles Lambda invocation with no payload', async () => { const mockResponse = { LogResult: Buffer.from('Test log').toString('base64'), - Payload: '', - } + Payload: new TextEncoder().encode(''), + } satisfies InvocationResponse client.invoke.resolves(mockResponse) const appendedLines: string[] = [] @@ -111,8 +112,8 @@ describe('RemoteInvokeWebview', () => { }) it('handles Lambda invocation with undefined LogResult', async () => { const mockResponse = { - Payload: '{"result": "success"}', - } + Payload: new TextEncoder().encode('{"result": "success"}'), + } satisfies InvocationResponse client.invoke.resolves(mockResponse) diff --git a/packages/core/src/test/lambda/vue/remoteInvoke/invokeLambdaDebugging.test.ts b/packages/core/src/test/lambda/vue/remoteInvoke/invokeLambdaDebugging.test.ts index 2d48d0cf0d8..f08bf474de8 100644 --- a/packages/core/src/test/lambda/vue/remoteInvoke/invokeLambdaDebugging.test.ts +++ b/packages/core/src/test/lambda/vue/remoteInvoke/invokeLambdaDebugging.test.ts @@ -20,6 +20,7 @@ import globals from '../../../../shared/extensionGlobals' import fs from '../../../../shared/fs/fs' import { ToolkitError } from '../../../../shared' import { createMockDebugConfig } from '../../remoteDebugging/testUtils' +import { InvocationResponse } from '@aws-sdk/client-lambda' describe('RemoteInvokeWebview - Debugging Functionality', () => { let outputChannel: vscode.OutputChannel @@ -394,8 +395,8 @@ describe('RemoteInvokeWebview - Debugging Functionality', () => { it('should invoke lambda with remote debugging enabled', async () => { const mockResponse = { LogResult: Buffer.from('Debug log').toString('base64'), - Payload: '{"result": "debug success"}', - } + Payload: new TextEncoder().encode('{"result": "debug success"}'), + } satisfies InvocationResponse client.invoke.resolves(mockResponse) mockDebugController.isDebugging = true mockDebugController.qualifier = 'v1' @@ -411,8 +412,8 @@ describe('RemoteInvokeWebview - Debugging Functionality', () => { it('should handle timer management during debugging invocation', async () => { const mockResponse = { LogResult: Buffer.from('Debug log').toString('base64'), - Payload: '{"result": "debug success"}', - } + Payload: new TextEncoder().encode('{"result": "debug success"}'), + } satisfies InvocationResponse client.invoke.resolves(mockResponse) mockDebugController.isDebugging = true @@ -520,8 +521,8 @@ describe('RemoteInvokeWebview - Debugging Functionality', () => { // 2. Test lambda invocation during debugging const mockResponse = { LogResult: Buffer.from('Debug invocation log').toString('base64'), - Payload: '{"debugResult": "success"}', - } + Payload: new TextEncoder().encode('{"debugResult": "success"}'), + } satisfies InvocationResponse client.invoke.resolves(mockResponse) await remoteInvokeWebview.invokeLambda('{"debugInput": "test"}', 'integration-test', true) @@ -581,8 +582,8 @@ describe('RemoteInvokeWebview - Debugging Functionality', () => { // Test invocation with version qualifier const mockResponse = { LogResult: Buffer.from('Version debug log').toString('base64'), - Payload: '{"versionResult": "success"}', - } + Payload: new TextEncoder().encode('{"versionResult": "success"}'), + } satisfies InvocationResponse client.invoke.resolves(mockResponse) await remoteInvokeWebview.invokeLambda('{"versionInput": "test"}', 'version-test', true) diff --git a/packages/core/src/test/lambda/vue/remoteInvoke/remoteInvoke.test.ts b/packages/core/src/test/lambda/vue/remoteInvoke/remoteInvoke.test.ts index 0fc94674c1e..852ba43d5bd 100644 --- a/packages/core/src/test/lambda/vue/remoteInvoke/remoteInvoke.test.ts +++ b/packages/core/src/test/lambda/vue/remoteInvoke/remoteInvoke.test.ts @@ -8,7 +8,7 @@ import * as vscode from 'vscode' import * as samCliRemoteTestEvent from '../../../../shared/sam/cli/samCliRemoteTestEvent' import { TestEventsOperation } from '../../../../shared/sam/cli/samCliRemoteTestEvent' import sinon, { SinonStubbedInstance, createStubInstance } from 'sinon' -import { Lambda } from 'aws-sdk' +import { InvocationResponse } from '@aws-sdk/client-lambda' // Tests to check that the internal integration between the functions operates correctly @@ -31,10 +31,10 @@ describe('RemoteInvokeWebview', function () { describe('Invoke Remote Lambda Function with Payload', () => { it('should invoke with a simple payload', async function () { const input = '{"key": "value"}' - const mockResponse: Lambda.InvocationResponse = { + const mockResponse = { LogResult: Buffer.from('Test log').toString('base64'), - Payload: '{"result": "success"}', - } + Payload: new TextEncoder().encode('{"result": "success"}'), + } satisfies InvocationResponse client.invoke.resolves(mockResponse) await remoteInvokeWebview.invokeLambda(input) sinon.assert.calledOnce(client.invoke) diff --git a/packages/core/src/test/shared/activationReloadState.test.ts b/packages/core/src/test/shared/activationReloadState.test.ts index d7ef8864adc..2dd0ba35bbd 100644 --- a/packages/core/src/test/shared/activationReloadState.test.ts +++ b/packages/core/src/test/shared/activationReloadState.test.ts @@ -8,6 +8,7 @@ import assert from 'assert' import { ActivationReloadState } from '../../shared/activationReloadState' import globals, { checkDidReload } from '../../shared/extensionGlobals' +import { Runtime } from '@aws-sdk/client-lambda' describe('ActivationReloadState', async function () { const activationReloadState = new ActivationReloadState() @@ -64,7 +65,7 @@ describe('ActivationReloadState', async function () { activationReloadState.setSamInitState({ template: 'sometemplate', readme: 'somepath', - runtime: 'someruntime', + runtime: 'someruntime' as Runtime, isImage: false, architecture: 'arm64', }) @@ -95,7 +96,7 @@ describe('ActivationReloadState', async function () { activationReloadState.setSamInitState({ template: 'sometemplate', readme: 'somepath', - runtime: 'someruntime', + runtime: 'someruntime' as Runtime, isImage: true, architecture: 'arm64', }) @@ -211,7 +212,7 @@ describe('ActivationReloadState', async function () { activationReloadState.setSamInitState({ template: 'sometemplate', readme: 'somepath', - runtime: 'someruntime', + runtime: 'someruntime' as Runtime, isImage: true, architecture: 'x86_64', }) diff --git a/packages/core/src/test/shared/applicationBuilder/explorer/nodes/deployedNode.test.ts b/packages/core/src/test/shared/applicationBuilder/explorer/nodes/deployedNode.test.ts index 0191fb3b60b..3edd66ab5d4 100644 --- a/packages/core/src/test/shared/applicationBuilder/explorer/nodes/deployedNode.test.ts +++ b/packages/core/src/test/shared/applicationBuilder/explorer/nodes/deployedNode.test.ts @@ -26,6 +26,7 @@ import { Any } from '../../../../../shared/utilities/typeConstructors' import { IamConnection, ProfileMetadata } from '../../../../../auth/connection' import * as AuthUtils from '../../../../../auth/utils' import { assertLogsContain } from '../../../../../test/globalSetup.test' +import { GetFunctionResponse } from '@aws-sdk/client-lambda' describe('DeployedResourceNode', () => { const expectedStackName = 'myStack' @@ -171,7 +172,7 @@ describe('generateDeployedNode', () => { FunctionArn: 'arn:aws:lambda:us-east-1:123456789012:function:my-project-lambda-function', Runtime: 'python3.12', }, - } as AWS.Lambda.GetFunctionResponse + } as GetFunctionResponse mockDefaultLambdaClientInstance.getFunction.resolves(defaultLambdaClientGetFunctionResponse) diff --git a/packages/core/src/test/shared/applicationBuilder/explorer/nodes/resourceNode.test.ts b/packages/core/src/test/shared/applicationBuilder/explorer/nodes/resourceNode.test.ts index 42486ea267b..43a76c0fca3 100644 --- a/packages/core/src/test/shared/applicationBuilder/explorer/nodes/resourceNode.test.ts +++ b/packages/core/src/test/shared/applicationBuilder/explorer/nodes/resourceNode.test.ts @@ -34,7 +34,7 @@ describe('ResourceNode', () => { Method: undefined, }, ], - } + } satisfies ResourceTreeEntity const workspaceFolder = { uri: vscode.Uri.parse('myworkspace'), name: 'my-workspace', diff --git a/packages/core/src/test/shared/sam/debugger/samDebugConfigProvider.test.ts b/packages/core/src/test/shared/sam/debugger/samDebugConfigProvider.test.ts index 9fe7c76e842..f17c5a2cf22 100644 --- a/packages/core/src/test/shared/sam/debugger/samDebugConfigProvider.test.ts +++ b/packages/core/src/test/shared/sam/debugger/samDebugConfigProvider.test.ts @@ -2906,7 +2906,7 @@ describe('ensureRelativePaths', function () { undefined, 'testName1', '/test1/project', - lambdaModel.getDefaultRuntime(lambdaModel.RuntimeFamily.NodeJS) ?? '' + lambdaModel.getDefaultRuntime(lambdaModel.RuntimeFamily.NodeJS)! ) assert.strictEqual((codeConfig.invokeTarget as CodeTargetProperties).projectRoot, '/test1/project') ensureRelativePaths(workspace, codeConfig) diff --git a/packages/core/src/testInteg/sam.test.ts b/packages/core/src/testInteg/sam.test.ts index 8dd8b5cdb9b..38c84d992df 100644 --- a/packages/core/src/testInteg/sam.test.ts +++ b/packages/core/src/testInteg/sam.test.ts @@ -4,7 +4,7 @@ */ import assert from 'assert' -import { Runtime } from 'aws-sdk/clients/lambda' +import { Runtime } from '@aws-sdk/client-lambda' import { mkdtempSync } from 'fs' // eslint-disable-line no-restricted-imports import * as path from 'path' import * as semver from 'semver' @@ -92,7 +92,7 @@ const dotnetDefaults = { vscodeMinimum: '1.80.0', } -const defaults: Record = { +const defaults: Record = { nodejs: nodeDefaults, java: javaDefaults, python: pythonDefaults, @@ -100,7 +100,7 @@ const defaults: Record = { } function generateScenario( - runtime: Runtime, + runtime: string, version: string, options: Partial = {}, fromImage: boolean = false @@ -110,7 +110,7 @@ function generateScenario( } const { sourceTag, ...defaultOverride } = options const source = `(${options.sourceTag ? `${options.sourceTag} ` : ''}${fromImage ? 'Image' : 'ZIP'})` - const fullName = `${runtime}${version}` + const fullName = `${runtime}${version}` as Runtime return { runtime: fullName, displayName: `${fullName} ${source}`,