From f464309317d7c059a7780466f2d3092a9219a072 Mon Sep 17 00:00:00 2001 From: hkobew Date: Fri, 22 Nov 2024 17:03:01 -0500 Subject: [PATCH 01/23] move in main file --- package-lock.json | 39 +++++ package.json | 1 + .../core/src/shared/awsClientBuilderV3.ts | 141 ++++++++++++++++++ packages/core/src/shared/utilities/tsUtils.ts | 10 ++ 4 files changed, 191 insertions(+) create mode 100644 packages/core/src/shared/awsClientBuilderV3.ts diff --git a/package-lock.json b/package-lock.json index 3cd83bc87a0..3e88fc0ceb9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "plugins/*" ], "dependencies": { + "@aws-sdk/protocol-http": "^3.370.0", "@types/node": "^22.7.5", "vscode-nls": "^5.2.0", "vscode-nls-dev": "^4.0.4" @@ -4658,6 +4659,44 @@ "node": ">= 12.0.0" } }, + "node_modules/@aws-sdk/protocol-http": { + "version": "3.370.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.370.0.tgz", + "integrity": "sha512-MfZCgSsVmir+4kJps7xT0awOPNi+swBpcVp9ZtAP7POduUVV6zVLurMNLXsppKsErggssD5E9HUgQFs5w06U4Q==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.370.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/protocol-http/node_modules/@aws-sdk/types": { + "version": "3.370.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.370.0.tgz", + "integrity": "sha512-8PGMKklSkRKjunFhzM2y5Jm0H2TBu7YRNISdYzXLUHKSP9zlMEYagseKVdmox0zKHf1LXVNuSlUV2b6SRrieCQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^1.1.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/protocol-http/node_modules/@smithy/types": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-1.2.0.tgz", + "integrity": "sha512-z1r00TvBqF3dh4aHhya7nz1HhvCg4TRmw51fjMrh5do3h+ngSstt/yKlNbHeb9QxJmFbmN8KEVSWgb1bRvfEoA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/region-config-resolver": { "version": "3.614.0", "license": "Apache-2.0", diff --git a/package.json b/package.json index 70f9d0f4c35..ba74a460f13 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "webpack-merge": "^5.10.0" }, "dependencies": { + "@aws-sdk/protocol-http": "^3.370.0", "@types/node": "^22.7.5", "vscode-nls": "^5.2.0", "vscode-nls-dev": "^4.0.4" diff --git a/packages/core/src/shared/awsClientBuilderV3.ts b/packages/core/src/shared/awsClientBuilderV3.ts new file mode 100644 index 00000000000..e06787828dd --- /dev/null +++ b/packages/core/src/shared/awsClientBuilderV3.ts @@ -0,0 +1,141 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +import { CredentialsShim } from '../auth/deprecated/loginManager' +import { AwsContext } from './awsContext' +import { AwsCredentialIdentityProvider } from '@smithy/types' +import { Client as IClient } from '@smithy/types' +import { getUserAgent } from './telemetry/util' +import { DevSettings } from './settings' +import { + DeserializeHandler, + DeserializeHandlerOptions, + DeserializeMiddleware, + HandlerExecutionContext, + Provider, + UserAgent, +} from '@aws-sdk/types' +import { HttpResponse } from '@aws-sdk/protocol-http' +import { telemetry } from './telemetry' +import { getRequestId } from './errors' +import { extensionVersion } from '.' +import { getLogger } from './logger' +import { omitIfPresent } from './utilities/tsUtils' + +export type AwsClient = IClient +interface AwsConfigOptions { + credentials: AwsCredentialIdentityProvider + region: string | Provider + customUserAgent: UserAgent + requestHandler: any + apiVersion: string + endpoint: string +} +export type AwsClientOptions = AwsConfigOptions + +export interface AWSClientBuilderV3 { + createAwsService( + type: new (o: AwsClientOptions) => C, + options?: Partial, + region?: string, + userAgent?: boolean, + settings?: DevSettings + ): Promise +} + +export class DefaultAWSClientBuilderV3 implements AWSClientBuilderV3 { + public constructor(private readonly context: AwsContext) {} + + private getShim(): CredentialsShim { + const shim = this.context.credentialsShim + if (!shim) { + throw new Error('Toolkit is not logged-in.') + } + return shim + } + + public async createAwsService( + type: new (o: AwsClientOptions) => C, + options?: Partial, + region?: string, + userAgent: boolean = true, + settings?: DevSettings + ): Promise { + const shim = this.getShim() + const opt = (options ?? {}) as AwsClientOptions + + if (!opt.region && region) { + opt.region = region + } + + if (!opt.customUserAgent && userAgent) { + opt.customUserAgent = [[getUserAgent({ includePlatform: true, includeClientId: true }), extensionVersion]] + } + // TODO: add tests for refresh logic. + opt.credentials = async () => { + const creds = await shim.get() + if (creds.expiration && creds.expiration.getTime() < Date.now()) { + return shim.refresh() + } + return creds + } + + const service = new type(opt) + // TODO: add middleware for logging, telemetry, endpoints. + service.middlewareStack.add(telemetryMiddleware, { step: 'deserialize' } as DeserializeHandlerOptions) + return service + } +} + +export function getServiceId(context: { clientName?: string; commandName?: string }): string { + return context.clientName?.toLowerCase().replace(/client$/, '') ?? 'unknown-service' +} + +/** + * Record request IDs to the current context, potentially overriding the field if + * multiple API calls are made in the same context. We only do failures as successes are generally uninteresting and noisy. + */ +export function recordErrorTelemetry(err: Error, serviceName?: string) { + interface RequestData { + requestId?: string + requestServiceType?: string + } + + telemetry.record({ + requestId: getRequestId(err), + requestServiceType: serviceName, + } satisfies RequestData as any) +} + +function logAndThrow(e: any, serviceId: string, errorMessageAppend: string): never { + if (e instanceof Error) { + recordErrorTelemetry(e, serviceId) + const err = { ...e } + delete err['stack'] + getLogger().error('API Response %s: %O', errorMessageAppend, err) + } + throw e +} +/** + * Telemetry logic to be added to all created clients. Adds logging and emitting metric on errors. + */ + +const telemetryMiddleware: DeserializeMiddleware = + (next: DeserializeHandler, context: HandlerExecutionContext) => async (args: any) => { + if (!HttpResponse.isInstance(args.request)) { + return next(args) + } + const serviceId = getServiceId(context as object) + const { hostname, path } = args.request + const logTail = `(${hostname} ${path})` + const result = await next(args).catch((e: any) => logAndThrow(e, serviceId, logTail)) + if (HttpResponse.isInstance(result.response)) { + // TODO: omit credentials / sensitive info from the logs / telemetry. + const output = omitIfPresent(result.output, []) + getLogger().debug('API Response %s: %O', logTail, output) + } + + return result + } diff --git a/packages/core/src/shared/utilities/tsUtils.ts b/packages/core/src/shared/utilities/tsUtils.ts index e4fbf5a2b3f..b6f5139d57c 100644 --- a/packages/core/src/shared/utilities/tsUtils.ts +++ b/packages/core/src/shared/utilities/tsUtils.ts @@ -151,3 +151,13 @@ export type FactoryFunction any> = ( /** Can be used to isolate all number fields of a record `T` */ export type NumericKeys = { [P in keyof T]-?: T[P] extends number | undefined ? P : never }[keyof T] + +export function omitIfPresent>(obj: T, keys: string[]): T { + const objCopy = { ...obj } + for (const key of keys) { + if (key in objCopy) { + ;(objCopy as any)[key] = '[omitted]' + } + } + return objCopy +} From afc0a2630fabf2df5c064dfdd9ee34284fd308ef Mon Sep 17 00:00:00 2001 From: hkobew Date: Fri, 22 Nov 2024 17:04:13 -0500 Subject: [PATCH 02/23] add test file --- .../shared/defaultAwsClientBuilderV3.test.ts | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts diff --git a/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts b/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts new file mode 100644 index 00000000000..5a7d2556eb0 --- /dev/null +++ b/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts @@ -0,0 +1,84 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +import assert from 'assert' +import { version } from 'vscode' +import { getClientId } from '../../shared/telemetry/util' +import { FakeMemento } from '../fakeExtensionContext' +import { FakeAwsContext } from '../utilities/fakeAwsContext' +import { GlobalState } from '../../shared/globalState' +import { + AWSClientBuilderV3, + DefaultAWSClientBuilderV3, + getServiceId, + recordErrorTelemetry, +} from '../../shared/awsClientBuilderV3' +import { Client } from '@aws-sdk/smithy-client' +import { extensionVersion } from '../../shared' +import { assertTelemetry } from '../testUtil' +import { telemetry } from '../../shared/telemetry' + +describe('DefaultAwsClientBuilderV3', function () { + let builder: AWSClientBuilderV3 + + beforeEach(function () { + builder = new DefaultAWSClientBuilderV3(new FakeAwsContext()) + }) + + describe('createAndConfigureSdkClient', function () { + it('includes Toolkit user-agent if no options are specified', async function () { + const service = await builder.createAwsService(Client as any) + const clientId = getClientId(new GlobalState(new FakeMemento())) + + assert.ok(service.config.customUserAgent) + assert.strictEqual( + service.config.customUserAgent![0][0].replace('---Insiders', ''), + `AWS-Toolkit-For-VSCode/testPluginVersion Visual-Studio-Code/${version} ClientId/${clientId}` + ) + assert.strictEqual(service.config.customUserAgent![0][1], extensionVersion) + }) + + it('adds region to client', async function () { + const service = await builder.createAwsService(Client as any, { region: 'us-west-2' }) + + assert.ok(service.config.region) + assert.strictEqual(service.config.region, 'us-west-2') + }) + + it('adds Client-Id to user agent', async function () { + const service = await builder.createAwsService(Client as any) + const clientId = getClientId(new GlobalState(new FakeMemento())) + const regex = new RegExp(`ClientId/${clientId}`) + assert.ok(service.config.customUserAgent![0][0].match(regex)) + }) + + it('does not override custom user-agent if specified in options', async function () { + const service = await builder.createAwsService(Client as any, { + customUserAgent: [['CUSTOM USER AGENT']], + }) + + assert.strictEqual(service.config.customUserAgent[0][0], 'CUSTOM USER AGENT') + }) + }) +}) + +describe('getServiceId', function () { + it('returns the service ID', function () { + assert.strictEqual(getServiceId({ clientName: 'ec2' }), 'ec2') + assert.strictEqual(getServiceId({ clientName: 'ec2client' }), 'ec2') + assert.strictEqual(getServiceId({ clientName: 's3client' }), 's3') + }) +}) + +describe('recordErrorTelemetry', function () { + it('includes requestServiceType in span', function () { + const e = new Error('test error') + // Using vscode_executeCommand as general span to test functionality. This metric is unrelated to what is done here. + telemetry.vscode_executeCommand.run((span) => { + recordErrorTelemetry(e, 'aws-service') + }) + assertTelemetry('vscode_executeCommand', { requestServiceType: 'aws-service' }) + }) +}) From be3c42a4693a4fe7bde7a293f900b8d9c91d6ac7 Mon Sep 17 00:00:00 2001 From: hkobew Date: Wed, 27 Nov 2024 15:51:59 -0500 Subject: [PATCH 03/23] add more detail to telemetry emitted --- packages/core/src/shared/awsClientBuilderV3.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/core/src/shared/awsClientBuilderV3.ts b/packages/core/src/shared/awsClientBuilderV3.ts index e06787828dd..12170faa69f 100644 --- a/packages/core/src/shared/awsClientBuilderV3.ts +++ b/packages/core/src/shared/awsClientBuilderV3.ts @@ -19,7 +19,7 @@ import { } from '@aws-sdk/types' import { HttpResponse } from '@aws-sdk/protocol-http' import { telemetry } from './telemetry' -import { getRequestId } from './errors' +import { getRequestId, getTelemetryReason, getTelemetryReasonDesc, getTelemetryResult } from './errors' import { extensionVersion } from '.' import { getLogger } from './logger' import { omitIfPresent } from './utilities/tsUtils' @@ -98,15 +98,13 @@ export function getServiceId(context: { clientName?: string; commandName?: strin * multiple API calls are made in the same context. We only do failures as successes are generally uninteresting and noisy. */ export function recordErrorTelemetry(err: Error, serviceName?: string) { - interface RequestData { - requestId?: string - requestServiceType?: string - } - telemetry.record({ requestId: getRequestId(err), requestServiceType: serviceName, - } satisfies RequestData as any) + reasonDesc: getTelemetryReasonDesc(err), + reason: getTelemetryReason(err), + result: getTelemetryResult(err), + }) } function logAndThrow(e: any, serviceId: string, errorMessageAppend: string): never { From 89ef7458a17370263dd09a587fc868015b8f4760 Mon Sep 17 00:00:00 2001 From: hkobew Date: Wed, 27 Nov 2024 15:59:30 -0500 Subject: [PATCH 04/23] add a default retry strategy --- packages/core/src/shared/awsClientBuilderV3.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/core/src/shared/awsClientBuilderV3.ts b/packages/core/src/shared/awsClientBuilderV3.ts index 12170faa69f..f3b2366f1fa 100644 --- a/packages/core/src/shared/awsClientBuilderV3.ts +++ b/packages/core/src/shared/awsClientBuilderV3.ts @@ -5,7 +5,7 @@ import { CredentialsShim } from '../auth/deprecated/loginManager' import { AwsContext } from './awsContext' -import { AwsCredentialIdentityProvider } from '@smithy/types' +import { AwsCredentialIdentityProvider, RetryStrategyV2 } from '@smithy/types' import { Client as IClient } from '@smithy/types' import { getUserAgent } from './telemetry/util' import { DevSettings } from './settings' @@ -15,9 +15,11 @@ import { DeserializeMiddleware, HandlerExecutionContext, Provider, + RetryStrategy, UserAgent, } from '@aws-sdk/types' import { HttpResponse } from '@aws-sdk/protocol-http' +import { ConfiguredRetryStrategy } from '@smithy/util-retry' import { telemetry } from './telemetry' import { getRequestId, getTelemetryReason, getTelemetryReasonDesc, getTelemetryResult } from './errors' import { extensionVersion } from '.' @@ -32,6 +34,7 @@ interface AwsConfigOptions { requestHandler: any apiVersion: string endpoint: string + retryStrategy: RetryStrategy | RetryStrategyV2 } export type AwsClientOptions = AwsConfigOptions @@ -73,6 +76,11 @@ export class DefaultAWSClientBuilderV3 implements AWSClientBuilderV3 { if (!opt.customUserAgent && userAgent) { opt.customUserAgent = [[getUserAgent({ includePlatform: true, includeClientId: true }), extensionVersion]] } + + if (!opt.retryStrategy) { + // Simple exponential backoff strategy as default. + opt.retryStrategy = new ConfiguredRetryStrategy(5, (attempt: number) => 1000 * 2 ** attempt) + } // TODO: add tests for refresh logic. opt.credentials = async () => { const creds = await shim.get() From 4890f73caa69c162632f80a6ab0d8a11c705a7ca Mon Sep 17 00:00:00 2001 From: hkobew Date: Mon, 2 Dec 2024 13:54:30 -0500 Subject: [PATCH 05/23] use class type instead of interface --- packages/core/src/shared/awsClientBuilderV3.ts | 16 ++++++++++++---- .../shared/defaultAwsClientBuilderV3.test.ts | 10 +++++----- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/core/src/shared/awsClientBuilderV3.ts b/packages/core/src/shared/awsClientBuilderV3.ts index f3b2366f1fa..4b4074e30f2 100644 --- a/packages/core/src/shared/awsClientBuilderV3.ts +++ b/packages/core/src/shared/awsClientBuilderV3.ts @@ -14,6 +14,8 @@ import { DeserializeHandlerOptions, DeserializeMiddleware, HandlerExecutionContext, + HttpHandlerOptions, + MetadataBearer, Provider, RetryStrategy, UserAgent, @@ -25,8 +27,14 @@ import { getRequestId, getTelemetryReason, getTelemetryReasonDesc, getTelemetryR import { extensionVersion } from '.' import { getLogger } from './logger' import { omitIfPresent } from './utilities/tsUtils' - -export type AwsClient = IClient +import { Client, SmithyResolvedConfiguration } from '@aws-sdk/smithy-client' +export type AwsClient = IClient +export type AwsClientClass = Client< + HttpHandlerOptions, + any, + MetadataBearer, + SmithyResolvedConfiguration +> interface AwsConfigOptions { credentials: AwsCredentialIdentityProvider region: string | Provider @@ -39,7 +47,7 @@ interface AwsConfigOptions { export type AwsClientOptions = AwsConfigOptions export interface AWSClientBuilderV3 { - createAwsService( + createAwsService( type: new (o: AwsClientOptions) => C, options?: Partial, region?: string, @@ -59,7 +67,7 @@ export class DefaultAWSClientBuilderV3 implements AWSClientBuilderV3 { return shim } - public async createAwsService( + public async createAwsService( type: new (o: AwsClientOptions) => C, options?: Partial, region?: string, diff --git a/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts b/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts index 5a7d2556eb0..f3338bbffa5 100644 --- a/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts +++ b/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts @@ -23,13 +23,13 @@ import { telemetry } from '../../shared/telemetry' describe('DefaultAwsClientBuilderV3', function () { let builder: AWSClientBuilderV3 - beforeEach(function () { + beforeEach(async function () { builder = new DefaultAWSClientBuilderV3(new FakeAwsContext()) }) describe('createAndConfigureSdkClient', function () { it('includes Toolkit user-agent if no options are specified', async function () { - const service = await builder.createAwsService(Client as any) + const service = await builder.createAwsService(Client) const clientId = getClientId(new GlobalState(new FakeMemento())) assert.ok(service.config.customUserAgent) @@ -41,21 +41,21 @@ describe('DefaultAwsClientBuilderV3', function () { }) it('adds region to client', async function () { - const service = await builder.createAwsService(Client as any, { region: 'us-west-2' }) + const service = await builder.createAwsService(Client, { region: 'us-west-2' }) assert.ok(service.config.region) assert.strictEqual(service.config.region, 'us-west-2') }) it('adds Client-Id to user agent', async function () { - const service = await builder.createAwsService(Client as any) + const service = await builder.createAwsService(Client) const clientId = getClientId(new GlobalState(new FakeMemento())) const regex = new RegExp(`ClientId/${clientId}`) assert.ok(service.config.customUserAgent![0][0].match(regex)) }) it('does not override custom user-agent if specified in options', async function () { - const service = await builder.createAwsService(Client as any, { + const service = await builder.createAwsService(Client, { customUserAgent: [['CUSTOM USER AGENT']], }) From ccfd4620dafb6aeaaf7408938f59c787b9df8319 Mon Sep 17 00:00:00 2001 From: hkobew Date: Mon, 2 Dec 2024 15:21:22 -0500 Subject: [PATCH 06/23] give up type info so that it compiles --- .../core/src/shared/awsClientBuilderV3.ts | 26 ++++++++++--------- .../shared/defaultAwsClientBuilderV3.test.ts | 7 +++-- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/packages/core/src/shared/awsClientBuilderV3.ts b/packages/core/src/shared/awsClientBuilderV3.ts index 4b4074e30f2..c0706eb9865 100644 --- a/packages/core/src/shared/awsClientBuilderV3.ts +++ b/packages/core/src/shared/awsClientBuilderV3.ts @@ -6,7 +6,6 @@ import { CredentialsShim } from '../auth/deprecated/loginManager' import { AwsContext } from './awsContext' import { AwsCredentialIdentityProvider, RetryStrategyV2 } from '@smithy/types' -import { Client as IClient } from '@smithy/types' import { getUserAgent } from './telemetry/util' import { DevSettings } from './settings' import { @@ -16,6 +15,7 @@ import { HandlerExecutionContext, HttpHandlerOptions, MetadataBearer, + MiddlewareStack, Provider, RetryStrategy, UserAgent, @@ -28,13 +28,15 @@ import { extensionVersion } from '.' import { getLogger } from './logger' import { omitIfPresent } from './utilities/tsUtils' import { Client, SmithyResolvedConfiguration } from '@aws-sdk/smithy-client' -export type AwsClient = IClient -export type AwsClientClass = Client< - HttpHandlerOptions, - any, - MetadataBearer, - SmithyResolvedConfiguration -> + +export type AwsClient = Client> +export type AwsClientConstructor = new (o: AwsClientOptions) => C + +interface AwsClient2 { + middlewareStack: AwsMiddlewareStack +} + +type AwsMiddlewareStack = any interface AwsConfigOptions { credentials: AwsCredentialIdentityProvider region: string | Provider @@ -47,8 +49,8 @@ interface AwsConfigOptions { export type AwsClientOptions = AwsConfigOptions export interface AWSClientBuilderV3 { - createAwsService( - type: new (o: AwsClientOptions) => C, + createAwsService( + type: AwsClientConstructor, options?: Partial, region?: string, userAgent?: boolean, @@ -67,8 +69,8 @@ export class DefaultAWSClientBuilderV3 implements AWSClientBuilderV3 { return shim } - public async createAwsService( - type: new (o: AwsClientOptions) => C, + public async createAwsService( + type: AwsClientConstructor, options?: Partial, region?: string, userAgent: boolean = true, diff --git a/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts b/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts index f3338bbffa5..a21a3939f98 100644 --- a/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts +++ b/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts @@ -10,7 +10,8 @@ import { FakeMemento } from '../fakeExtensionContext' import { FakeAwsContext } from '../utilities/fakeAwsContext' import { GlobalState } from '../../shared/globalState' import { - AWSClientBuilderV3, + AwsClient, + AwsClientConstructor, DefaultAWSClientBuilderV3, getServiceId, recordErrorTelemetry, @@ -19,12 +20,14 @@ import { Client } from '@aws-sdk/smithy-client' import { extensionVersion } from '../../shared' import { assertTelemetry } from '../testUtil' import { telemetry } from '../../shared/telemetry' +import { CloudFormationClient } from '@aws-sdk/client-cloudformation' describe('DefaultAwsClientBuilderV3', function () { - let builder: AWSClientBuilderV3 + let builder: DefaultAWSClientBuilderV3 beforeEach(async function () { builder = new DefaultAWSClientBuilderV3(new FakeAwsContext()) + const c = await builder.createAwsService(CloudFormationClient, undefined, 'us-east-1') }) describe('createAndConfigureSdkClient', function () { From 0675afe63f28468df785618153e9cad82c19966c Mon Sep 17 00:00:00 2001 From: hkobew Date: Mon, 2 Dec 2024 15:38:32 -0500 Subject: [PATCH 07/23] refactor types to have any middleware --- .../core/src/shared/awsClientBuilderV3.ts | 38 ++++++++++--------- .../shared/defaultAwsClientBuilderV3.test.ts | 13 ++----- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/packages/core/src/shared/awsClientBuilderV3.ts b/packages/core/src/shared/awsClientBuilderV3.ts index c0706eb9865..353000c5224 100644 --- a/packages/core/src/shared/awsClientBuilderV3.ts +++ b/packages/core/src/shared/awsClientBuilderV3.ts @@ -15,7 +15,7 @@ import { HandlerExecutionContext, HttpHandlerOptions, MetadataBearer, - MiddlewareStack, + //MiddlewareStack, Provider, RetryStrategy, UserAgent, @@ -32,11 +32,11 @@ import { Client, SmithyResolvedConfiguration } from '@aws-sdk/smithy-client' export type AwsClient = Client> export type AwsClientConstructor = new (o: AwsClientOptions) => C -interface AwsClient2 { - middlewareStack: AwsMiddlewareStack +interface AwsClient2 { + middlewareStack: AwsMiddlewareStack } -type AwsMiddlewareStack = any +type AwsMiddlewareStack = any interface AwsConfigOptions { credentials: AwsCredentialIdentityProvider region: string | Provider @@ -48,17 +48,17 @@ interface AwsConfigOptions { } export type AwsClientOptions = AwsConfigOptions -export interface AWSClientBuilderV3 { - createAwsService( - type: AwsClientConstructor, - options?: Partial, - region?: string, - userAgent?: boolean, - settings?: DevSettings - ): Promise -} - -export class DefaultAWSClientBuilderV3 implements AWSClientBuilderV3 { +// export interface AWSClientBuilderV3 { +// createAwsService>( +// type: AwsClientConstructor, +// options?: Partial, +// region?: string, +// userAgent?: boolean, +// settings?: DevSettings +// ): Promise +// } + +export class DefaultAWSClientBuilderV3 { public constructor(private readonly context: AwsContext) {} private getShim(): CredentialsShim { @@ -69,7 +69,11 @@ export class DefaultAWSClientBuilderV3 implements AWSClientBuilderV3 { return shim } - public async createAwsService( + public async createAwsService< + Input extends object, + Output extends MetadataBearer, + C extends AwsClient2, + >( type: AwsClientConstructor, options?: Partial, region?: string, @@ -102,7 +106,7 @@ export class DefaultAWSClientBuilderV3 implements AWSClientBuilderV3 { const service = new type(opt) // TODO: add middleware for logging, telemetry, endpoints. - service.middlewareStack.add(telemetryMiddleware, { step: 'deserialize' } as DeserializeHandlerOptions) + service.middlewareStack.add!(telemetryMiddleware, { step: 'deserialize' } as DeserializeHandlerOptions) return service } } diff --git a/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts b/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts index a21a3939f98..b5e136d70e2 100644 --- a/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts +++ b/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts @@ -9,25 +9,20 @@ import { getClientId } from '../../shared/telemetry/util' import { FakeMemento } from '../fakeExtensionContext' import { FakeAwsContext } from '../utilities/fakeAwsContext' import { GlobalState } from '../../shared/globalState' -import { - AwsClient, - AwsClientConstructor, - DefaultAWSClientBuilderV3, - getServiceId, - recordErrorTelemetry, -} from '../../shared/awsClientBuilderV3' +import { DefaultAWSClientBuilderV3, getServiceId, recordErrorTelemetry } from '../../shared/awsClientBuilderV3' import { Client } from '@aws-sdk/smithy-client' import { extensionVersion } from '../../shared' import { assertTelemetry } from '../testUtil' import { telemetry } from '../../shared/telemetry' -import { CloudFormationClient } from '@aws-sdk/client-cloudformation' +//import { ActivateOrganizationsAccessCommand, CloudFormationClient } from '@aws-sdk/client-cloudformation' describe('DefaultAwsClientBuilderV3', function () { let builder: DefaultAWSClientBuilderV3 beforeEach(async function () { builder = new DefaultAWSClientBuilderV3(new FakeAwsContext()) - const c = await builder.createAwsService(CloudFormationClient, undefined, 'us-east-1') + //const c = await builder.createAwsService(CloudFormationClient, undefined, 'us-east-1') + //await c.send(new ActivateOrganizationsAccessCommand({ dryRun: true })) }) describe('createAndConfigureSdkClient', function () { From 3e8caf6a3e81dedfcfeb1df117c6c3ad3a0bc545 Mon Sep 17 00:00:00 2001 From: hkobew Date: Mon, 2 Dec 2024 15:49:40 -0500 Subject: [PATCH 08/23] remove interface --- .../core/src/shared/awsClientBuilderV3.ts | 24 ++++--------------- .../shared/defaultAwsClientBuilderV3.test.ts | 3 --- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/packages/core/src/shared/awsClientBuilderV3.ts b/packages/core/src/shared/awsClientBuilderV3.ts index 353000c5224..7642952b335 100644 --- a/packages/core/src/shared/awsClientBuilderV3.ts +++ b/packages/core/src/shared/awsClientBuilderV3.ts @@ -15,7 +15,6 @@ import { HandlerExecutionContext, HttpHandlerOptions, MetadataBearer, - //MiddlewareStack, Provider, RetryStrategy, UserAgent, @@ -32,11 +31,10 @@ import { Client, SmithyResolvedConfiguration } from '@aws-sdk/smithy-client' export type AwsClient = Client> export type AwsClientConstructor = new (o: AwsClientOptions) => C -interface AwsClient2 { - middlewareStack: AwsMiddlewareStack +interface AwsClient2 { + middlewareStack: any // Ideally this would extends MiddlewareStack, but this causes issues on client construction. } -type AwsMiddlewareStack = any interface AwsConfigOptions { credentials: AwsCredentialIdentityProvider region: string | Provider @@ -48,16 +46,6 @@ interface AwsConfigOptions { } export type AwsClientOptions = AwsConfigOptions -// export interface AWSClientBuilderV3 { -// createAwsService>( -// type: AwsClientConstructor, -// options?: Partial, -// region?: string, -// userAgent?: boolean, -// settings?: DevSettings -// ): Promise -// } - export class DefaultAWSClientBuilderV3 { public constructor(private readonly context: AwsContext) {} @@ -69,11 +57,7 @@ export class DefaultAWSClientBuilderV3 { return shim } - public async createAwsService< - Input extends object, - Output extends MetadataBearer, - C extends AwsClient2, - >( + public async createAwsService( type: AwsClientConstructor, options?: Partial, region?: string, @@ -106,7 +90,7 @@ export class DefaultAWSClientBuilderV3 { const service = new type(opt) // TODO: add middleware for logging, telemetry, endpoints. - service.middlewareStack.add!(telemetryMiddleware, { step: 'deserialize' } as DeserializeHandlerOptions) + service.middlewareStack.add(telemetryMiddleware, { step: 'deserialize' } as DeserializeHandlerOptions) return service } } diff --git a/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts b/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts index b5e136d70e2..5094a3cb4e7 100644 --- a/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts +++ b/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts @@ -14,15 +14,12 @@ import { Client } from '@aws-sdk/smithy-client' import { extensionVersion } from '../../shared' import { assertTelemetry } from '../testUtil' import { telemetry } from '../../shared/telemetry' -//import { ActivateOrganizationsAccessCommand, CloudFormationClient } from '@aws-sdk/client-cloudformation' describe('DefaultAwsClientBuilderV3', function () { let builder: DefaultAWSClientBuilderV3 beforeEach(async function () { builder = new DefaultAWSClientBuilderV3(new FakeAwsContext()) - //const c = await builder.createAwsService(CloudFormationClient, undefined, 'us-east-1') - //await c.send(new ActivateOrganizationsAccessCommand({ dryRun: true })) }) describe('createAndConfigureSdkClient', function () { From 67784e170154c932135019a772cbc580500763a5 Mon Sep 17 00:00:00 2001 From: hkobew Date: Mon, 2 Dec 2024 15:51:09 -0500 Subject: [PATCH 09/23] remove unused types --- packages/core/src/shared/awsClientBuilderV3.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/core/src/shared/awsClientBuilderV3.ts b/packages/core/src/shared/awsClientBuilderV3.ts index 7642952b335..63d54710fbe 100644 --- a/packages/core/src/shared/awsClientBuilderV3.ts +++ b/packages/core/src/shared/awsClientBuilderV3.ts @@ -13,8 +13,6 @@ import { DeserializeHandlerOptions, DeserializeMiddleware, HandlerExecutionContext, - HttpHandlerOptions, - MetadataBearer, Provider, RetryStrategy, UserAgent, @@ -26,12 +24,10 @@ import { getRequestId, getTelemetryReason, getTelemetryReasonDesc, getTelemetryR import { extensionVersion } from '.' import { getLogger } from './logger' import { omitIfPresent } from './utilities/tsUtils' -import { Client, SmithyResolvedConfiguration } from '@aws-sdk/smithy-client' -export type AwsClient = Client> export type AwsClientConstructor = new (o: AwsClientOptions) => C -interface AwsClient2 { +interface AwsClient { middlewareStack: any // Ideally this would extends MiddlewareStack, but this causes issues on client construction. } @@ -57,7 +53,7 @@ export class DefaultAWSClientBuilderV3 { return shim } - public async createAwsService( + public async createAwsService( type: AwsClientConstructor, options?: Partial, region?: string, From 1d29b18d2ae2efe0997985314d81c0178e7d0c88 Mon Sep 17 00:00:00 2001 From: hkobew Date: Mon, 2 Dec 2024 15:54:32 -0500 Subject: [PATCH 10/23] simplify naming --- packages/core/src/shared/awsClientBuilderV3.ts | 2 +- .../src/test/shared/defaultAwsClientBuilderV3.test.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/core/src/shared/awsClientBuilderV3.ts b/packages/core/src/shared/awsClientBuilderV3.ts index 63d54710fbe..966084e7d1a 100644 --- a/packages/core/src/shared/awsClientBuilderV3.ts +++ b/packages/core/src/shared/awsClientBuilderV3.ts @@ -42,7 +42,7 @@ interface AwsConfigOptions { } export type AwsClientOptions = AwsConfigOptions -export class DefaultAWSClientBuilderV3 { +export class AWSClientBuilderV3 { public constructor(private readonly context: AwsContext) {} private getShim(): CredentialsShim { diff --git a/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts b/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts index 5094a3cb4e7..d0184be1ded 100644 --- a/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts +++ b/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts @@ -9,17 +9,17 @@ import { getClientId } from '../../shared/telemetry/util' import { FakeMemento } from '../fakeExtensionContext' import { FakeAwsContext } from '../utilities/fakeAwsContext' import { GlobalState } from '../../shared/globalState' -import { DefaultAWSClientBuilderV3, getServiceId, recordErrorTelemetry } from '../../shared/awsClientBuilderV3' +import { AWSClientBuilderV3, getServiceId, recordErrorTelemetry } from '../../shared/awsClientBuilderV3' import { Client } from '@aws-sdk/smithy-client' import { extensionVersion } from '../../shared' import { assertTelemetry } from '../testUtil' import { telemetry } from '../../shared/telemetry' -describe('DefaultAwsClientBuilderV3', function () { - let builder: DefaultAWSClientBuilderV3 +describe('AwsClientBuilderV3', function () { + let builder: AWSClientBuilderV3 beforeEach(async function () { - builder = new DefaultAWSClientBuilderV3(new FakeAwsContext()) + builder = new AWSClientBuilderV3(new FakeAwsContext()) }) describe('createAndConfigureSdkClient', function () { From 4500cdc92abd9d332bdad8a753988e7bd0693b7a Mon Sep 17 00:00:00 2001 From: hkobew Date: Mon, 2 Dec 2024 16:00:10 -0500 Subject: [PATCH 11/23] rename test file --- ...faultAwsClientBuilderV3.test.ts => AwsClientBuilderV3.test.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/core/src/test/shared/{defaultAwsClientBuilderV3.test.ts => AwsClientBuilderV3.test.ts} (100%) diff --git a/packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts b/packages/core/src/test/shared/AwsClientBuilderV3.test.ts similarity index 100% rename from packages/core/src/test/shared/defaultAwsClientBuilderV3.test.ts rename to packages/core/src/test/shared/AwsClientBuilderV3.test.ts From 4e2dffe5e7dad8a9257b697b1c735dd9d78bf0b9 Mon Sep 17 00:00:00 2001 From: hkobew Date: Mon, 2 Dec 2024 16:04:30 -0500 Subject: [PATCH 12/23] change name to temp --- .../{AwsClientBuilderV3.test.ts => awsClientBuilderV3z.test.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/core/src/test/shared/{AwsClientBuilderV3.test.ts => awsClientBuilderV3z.test.ts} (100%) diff --git a/packages/core/src/test/shared/AwsClientBuilderV3.test.ts b/packages/core/src/test/shared/awsClientBuilderV3z.test.ts similarity index 100% rename from packages/core/src/test/shared/AwsClientBuilderV3.test.ts rename to packages/core/src/test/shared/awsClientBuilderV3z.test.ts From 470e0f5b5bb52c00967e796fe8d295e989b98388 Mon Sep 17 00:00:00 2001 From: hkobew Date: Mon, 2 Dec 2024 16:04:44 -0500 Subject: [PATCH 13/23] switch name to lower case --- .../{awsClientBuilderV3z.test.ts => awsClientBuilderV3.test.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/core/src/test/shared/{awsClientBuilderV3z.test.ts => awsClientBuilderV3.test.ts} (100%) diff --git a/packages/core/src/test/shared/awsClientBuilderV3z.test.ts b/packages/core/src/test/shared/awsClientBuilderV3.test.ts similarity index 100% rename from packages/core/src/test/shared/awsClientBuilderV3z.test.ts rename to packages/core/src/test/shared/awsClientBuilderV3.test.ts From 6a04c9887260b197df17697e2c9d1325c8233ba2 Mon Sep 17 00:00:00 2001 From: hkobew Date: Thu, 9 Jan 2025 14:44:39 -0500 Subject: [PATCH 14/23] add link to relevant issue --- packages/core/src/shared/awsClientBuilderV3.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/core/src/shared/awsClientBuilderV3.ts b/packages/core/src/shared/awsClientBuilderV3.ts index 966084e7d1a..13a0e4f23b8 100644 --- a/packages/core/src/shared/awsClientBuilderV3.ts +++ b/packages/core/src/shared/awsClientBuilderV3.ts @@ -27,8 +27,10 @@ import { omitIfPresent } from './utilities/tsUtils' export type AwsClientConstructor = new (o: AwsClientOptions) => C +// AWS-SDKv3 does not export generic types for clients so we need to build them as needed +// https://github.com/aws/aws-sdk-js-v3/issues/5856#issuecomment-2096950979 interface AwsClient { - middlewareStack: any // Ideally this would extends MiddlewareStack, but this causes issues on client construction. + middlewareStack: any } interface AwsConfigOptions { From 58809be12c980dc288a233edaf589ac316c84943 Mon Sep 17 00:00:00 2001 From: hkobew Date: Tue, 14 Jan 2025 11:59:40 -0500 Subject: [PATCH 15/23] move dep to core module --- package-lock.json | 2 +- package.json | 1 - packages/core/package.json | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index a90ce026afb..e6f00056ba0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,6 @@ "plugins/*" ], "dependencies": { - "@aws-sdk/protocol-http": "^3.370.0", "@types/node": "^22.7.5", "vscode-nls": "^5.2.0", "vscode-nls-dev": "^4.0.4" @@ -21193,6 +21192,7 @@ "@aws-sdk/credential-provider-process": "3.37.0", "@aws-sdk/credential-provider-sso": "^3.345.0", "@aws-sdk/property-provider": "3.46.0", + "@aws-sdk/protocol-http": "^3.370.0", "@aws-sdk/smithy-client": "^3.46.0", "@aws-sdk/util-arn-parser": "^3.46.0", "@aws/mynah-ui": "^4.21.4", diff --git a/package.json b/package.json index 42948edf18a..cb669449f9d 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,6 @@ "webpack-merge": "^5.10.0" }, "dependencies": { - "@aws-sdk/protocol-http": "^3.370.0", "@types/node": "^22.7.5", "vscode-nls": "^5.2.0", "vscode-nls-dev": "^4.0.4" diff --git a/packages/core/package.json b/packages/core/package.json index 5f5e59bfa13..706db24721d 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -496,6 +496,7 @@ "dependencies": { "@amzn/amazon-q-developer-streaming-client": "file:../../src.gen/@amzn/amazon-q-developer-streaming-client", "@amzn/codewhisperer-streaming": "file:../../src.gen/@amzn/codewhisperer-streaming", + "@aws-sdk/protocol-http": "^3.370.0", "@aws-sdk/client-cloudformation": "^3.667.0", "@aws-sdk/client-cloudwatch-logs": "^3.666.0", "@aws-sdk/client-cognito-identity": "^3.637.0", From 4880c166275daea6b157af0a4464a2d74d541a7c Mon Sep 17 00:00:00 2001 From: hkobew Date: Tue, 14 Jan 2025 12:19:31 -0500 Subject: [PATCH 16/23] improve middleware typing --- packages/core/src/shared/awsClientBuilderV3.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/core/src/shared/awsClientBuilderV3.ts b/packages/core/src/shared/awsClientBuilderV3.ts index 13a0e4f23b8..90fae59bd6b 100644 --- a/packages/core/src/shared/awsClientBuilderV3.ts +++ b/packages/core/src/shared/awsClientBuilderV3.ts @@ -13,6 +13,8 @@ import { DeserializeHandlerOptions, DeserializeMiddleware, HandlerExecutionContext, + MetadataBearer, + MiddlewareStack, Provider, RetryStrategy, UserAgent, @@ -30,7 +32,9 @@ export type AwsClientConstructor = new (o: AwsClientOptions) => C // AWS-SDKv3 does not export generic types for clients so we need to build them as needed // https://github.com/aws/aws-sdk-js-v3/issues/5856#issuecomment-2096950979 interface AwsClient { - middlewareStack: any + middlewareStack: { + add: MiddlewareStack['add'] + } } interface AwsConfigOptions { From 6dc24057276688e5a54bff7cd239196f8055c76d Mon Sep 17 00:00:00 2001 From: hkobew Date: Tue, 14 Jan 2025 12:37:02 -0500 Subject: [PATCH 17/23] remove redundant type --- packages/core/src/shared/awsClientBuilderV3.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/core/src/shared/awsClientBuilderV3.ts b/packages/core/src/shared/awsClientBuilderV3.ts index 90fae59bd6b..5d73d0fe7b5 100644 --- a/packages/core/src/shared/awsClientBuilderV3.ts +++ b/packages/core/src/shared/awsClientBuilderV3.ts @@ -37,7 +37,7 @@ interface AwsClient { } } -interface AwsConfigOptions { +interface AwsClientOptions { credentials: AwsCredentialIdentityProvider region: string | Provider customUserAgent: UserAgent @@ -46,7 +46,6 @@ interface AwsConfigOptions { endpoint: string retryStrategy: RetryStrategy | RetryStrategyV2 } -export type AwsClientOptions = AwsConfigOptions export class AWSClientBuilderV3 { public constructor(private readonly context: AwsContext) {} From 222ff04db5903f96619dc2e847c35c459c7c59c2 Mon Sep 17 00:00:00 2001 From: hkobew Date: Tue, 14 Jan 2025 12:59:45 -0500 Subject: [PATCH 18/23] improve typing --- packages/core/src/shared/awsClientBuilderV3.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/core/src/shared/awsClientBuilderV3.ts b/packages/core/src/shared/awsClientBuilderV3.ts index 5d73d0fe7b5..b5a51c10b9b 100644 --- a/packages/core/src/shared/awsClientBuilderV3.ts +++ b/packages/core/src/shared/awsClientBuilderV3.ts @@ -16,6 +16,8 @@ import { MetadataBearer, MiddlewareStack, Provider, + RequestHandlerMetadata, + RequestHandlerOutput, RetryStrategy, UserAgent, } from '@aws-sdk/types' @@ -41,7 +43,11 @@ interface AwsClientOptions { credentials: AwsCredentialIdentityProvider region: string | Provider customUserAgent: UserAgent - requestHandler: any + requestHandler: { + metadata?: RequestHandlerMetadata + handle: (req: any, options?: any) => Promise> + destroy?: () => void + } apiVersion: string endpoint: string retryStrategy: RetryStrategy | RetryStrategyV2 From f0adfeebae3c4fc9dcef5446b24ae67a3d111add Mon Sep 17 00:00:00 2001 From: hkobew Date: Mon, 27 Jan 2025 13:42:42 -0500 Subject: [PATCH 19/23] refactor: customerUserAgent -> userAgent --- packages/core/src/shared/awsClientBuilderV3.ts | 6 +++--- .../core/src/test/shared/awsClientBuilderV3.test.ts | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/core/src/shared/awsClientBuilderV3.ts b/packages/core/src/shared/awsClientBuilderV3.ts index b5a51c10b9b..432627017f1 100644 --- a/packages/core/src/shared/awsClientBuilderV3.ts +++ b/packages/core/src/shared/awsClientBuilderV3.ts @@ -42,7 +42,7 @@ interface AwsClient { interface AwsClientOptions { credentials: AwsCredentialIdentityProvider region: string | Provider - customUserAgent: UserAgent + userAgent: UserAgent requestHandler: { metadata?: RequestHandlerMetadata handle: (req: any, options?: any) => Promise> @@ -78,8 +78,8 @@ export class AWSClientBuilderV3 { opt.region = region } - if (!opt.customUserAgent && userAgent) { - opt.customUserAgent = [[getUserAgent({ includePlatform: true, includeClientId: true }), extensionVersion]] + if (!opt.userAgent && userAgent) { + opt.userAgent = [[getUserAgent({ includePlatform: true, includeClientId: true }), extensionVersion]] } if (!opt.retryStrategy) { diff --git a/packages/core/src/test/shared/awsClientBuilderV3.test.ts b/packages/core/src/test/shared/awsClientBuilderV3.test.ts index d0184be1ded..4cee8a0653f 100644 --- a/packages/core/src/test/shared/awsClientBuilderV3.test.ts +++ b/packages/core/src/test/shared/awsClientBuilderV3.test.ts @@ -27,12 +27,12 @@ describe('AwsClientBuilderV3', function () { const service = await builder.createAwsService(Client) const clientId = getClientId(new GlobalState(new FakeMemento())) - assert.ok(service.config.customUserAgent) + assert.ok(service.config.userAgent) assert.strictEqual( - service.config.customUserAgent![0][0].replace('---Insiders', ''), + service.config.userAgent![0][0].replace('---Insiders', ''), `AWS-Toolkit-For-VSCode/testPluginVersion Visual-Studio-Code/${version} ClientId/${clientId}` ) - assert.strictEqual(service.config.customUserAgent![0][1], extensionVersion) + assert.strictEqual(service.config.userAgent![0][1], extensionVersion) }) it('adds region to client', async function () { @@ -46,15 +46,15 @@ describe('AwsClientBuilderV3', function () { const service = await builder.createAwsService(Client) const clientId = getClientId(new GlobalState(new FakeMemento())) const regex = new RegExp(`ClientId/${clientId}`) - assert.ok(service.config.customUserAgent![0][0].match(regex)) + assert.ok(service.config.userAgent![0][0].match(regex)) }) it('does not override custom user-agent if specified in options', async function () { const service = await builder.createAwsService(Client, { - customUserAgent: [['CUSTOM USER AGENT']], + userAgent: [['CUSTOM USER AGENT']], }) - assert.strictEqual(service.config.customUserAgent[0][0], 'CUSTOM USER AGENT') + assert.strictEqual(service.config.userAgent[0][0], 'CUSTOM USER AGENT') }) }) }) From 7bd08b3707860c02f7bf51858f8d8a1c2ddf148c Mon Sep 17 00:00:00 2001 From: hkobew Date: Mon, 27 Jan 2025 13:43:26 -0500 Subject: [PATCH 20/23] refactor: remove blank line --- packages/core/src/shared/awsClientBuilderV3.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/shared/awsClientBuilderV3.ts b/packages/core/src/shared/awsClientBuilderV3.ts index 432627017f1..92b6fc55618 100644 --- a/packages/core/src/shared/awsClientBuilderV3.ts +++ b/packages/core/src/shared/awsClientBuilderV3.ts @@ -132,7 +132,6 @@ function logAndThrow(e: any, serviceId: string, errorMessageAppend: string): nev /** * Telemetry logic to be added to all created clients. Adds logging and emitting metric on errors. */ - const telemetryMiddleware: DeserializeMiddleware = (next: DeserializeHandler, context: HandlerExecutionContext) => async (args: any) => { if (!HttpResponse.isInstance(args.request)) { From 688899b8e92080f0df39fa034a4232cbce903fc2 Mon Sep 17 00:00:00 2001 From: hkobew Date: Mon, 27 Jan 2025 13:44:26 -0500 Subject: [PATCH 21/23] refactor: use partialClone over omitIfPresent --- packages/core/src/shared/awsClientBuilderV3.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/src/shared/awsClientBuilderV3.ts b/packages/core/src/shared/awsClientBuilderV3.ts index 92b6fc55618..6b1798fbc0a 100644 --- a/packages/core/src/shared/awsClientBuilderV3.ts +++ b/packages/core/src/shared/awsClientBuilderV3.ts @@ -27,7 +27,7 @@ import { telemetry } from './telemetry' import { getRequestId, getTelemetryReason, getTelemetryReasonDesc, getTelemetryResult } from './errors' import { extensionVersion } from '.' import { getLogger } from './logger' -import { omitIfPresent } from './utilities/tsUtils' +import { partialClone } from './utilities/collectionUtils' export type AwsClientConstructor = new (o: AwsClientOptions) => C @@ -143,7 +143,7 @@ const telemetryMiddleware: DeserializeMiddleware = const result = await next(args).catch((e: any) => logAndThrow(e, serviceId, logTail)) if (HttpResponse.isInstance(result.response)) { // TODO: omit credentials / sensitive info from the logs / telemetry. - const output = omitIfPresent(result.output, []) + const output = partialClone(result.output) getLogger().debug('API Response %s: %O', logTail, output) } From 312c93cc0517fd7d16a69b69094afdcba10488fd Mon Sep 17 00:00:00 2001 From: hkobew Date: Mon, 27 Jan 2025 13:46:29 -0500 Subject: [PATCH 22/23] refactor: add depth field to partialClone --- packages/core/src/shared/awsClientBuilderV3.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/shared/awsClientBuilderV3.ts b/packages/core/src/shared/awsClientBuilderV3.ts index 6b1798fbc0a..c10796e8b19 100644 --- a/packages/core/src/shared/awsClientBuilderV3.ts +++ b/packages/core/src/shared/awsClientBuilderV3.ts @@ -143,7 +143,7 @@ const telemetryMiddleware: DeserializeMiddleware = const result = await next(args).catch((e: any) => logAndThrow(e, serviceId, logTail)) if (HttpResponse.isInstance(result.response)) { // TODO: omit credentials / sensitive info from the logs / telemetry. - const output = partialClone(result.output) + const output = partialClone(result.output, 3) getLogger().debug('API Response %s: %O', logTail, output) } From a110c1f906fe97a17eabead9ad77fe3be93f9681 Mon Sep 17 00:00:00 2001 From: hkobew Date: Mon, 27 Jan 2025 13:48:24 -0500 Subject: [PATCH 23/23] refactor: rename test file --- .../{defaultAwsClientBuilder.test.ts => awsClientBuilder.test.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/core/src/test/shared/{defaultAwsClientBuilder.test.ts => awsClientBuilder.test.ts} (100%) diff --git a/packages/core/src/test/shared/defaultAwsClientBuilder.test.ts b/packages/core/src/test/shared/awsClientBuilder.test.ts similarity index 100% rename from packages/core/src/test/shared/defaultAwsClientBuilder.test.ts rename to packages/core/src/test/shared/awsClientBuilder.test.ts