diff --git a/packages/middleware-flexible-checksums/src/middleware-flexible-checksums.integ.spec.ts b/packages/middleware-flexible-checksums/src/middleware-flexible-checksums.integ.spec.ts index 027e8ad74b1f..40b0d1a045d2 100644 --- a/packages/middleware-flexible-checksums/src/middleware-flexible-checksums.integ.spec.ts +++ b/packages/middleware-flexible-checksums/src/middleware-flexible-checksums.integ.spec.ts @@ -137,7 +137,7 @@ describe("middleware-flexible-checksums", () => { requireRequestsFrom(client).toMatch({ headers: { - "user-agent": new RegExp(`(.*?) m\/${id}$`), + "user-agent": new RegExp(`(.*?) m\/${id},E$`), }, }); diff --git a/packages/middleware-sdk-s3/src/s3-express/middleware-s3-express.integ.spec.ts b/packages/middleware-sdk-s3/src/s3-express/middleware-s3-express.integ.spec.ts index a73facfe5d8c..e969678effe7 100644 --- a/packages/middleware-sdk-s3/src/s3-express/middleware-s3-express.integ.spec.ts +++ b/packages/middleware-sdk-s3/src/s3-express/middleware-s3-express.integ.spec.ts @@ -93,7 +93,7 @@ describe("middleware-s3-express", () => { requireRequestsFrom(client).toMatch({ headers: { - "user-agent": /(.*?) m\/J$/, + "user-agent": /(.*?) m\/J,E$/, }, }); diff --git a/packages/middleware-user-agent/src/check-features.ts b/packages/middleware-user-agent/src/check-features.ts index 18b41d24ac4e..6272b3085d78 100644 --- a/packages/middleware-user-agent/src/check-features.ts +++ b/packages/middleware-user-agent/src/check-features.ts @@ -6,7 +6,13 @@ import type { AwsSdkCredentialsFeatures, } from "@aws-sdk/types"; import type { IHttpRequest } from "@smithy/protocol-http"; -import type { AwsCredentialIdentityProvider, BuildHandlerArguments, Provider } from "@smithy/types"; +import type { + AwsCredentialIdentityProvider, + BuildHandlerArguments, + Provider, + RetryStrategy, + RetryStrategyV2, +} from "@smithy/types"; /** * @internal @@ -14,8 +20,14 @@ import type { AwsCredentialIdentityProvider, BuildHandlerArguments, Provider } f type PreviouslyResolved = Partial<{ credentials?: AwsCredentialIdentityProvider; accountIdEndpointMode?: Provider; + retryStrategy?: Provider; }>; +/** + * @internal + */ +const ACCOUNT_ID_ENDPOINT_REGEX = /\d{12}\.ddb/; + /** * @internal * Check for features that don't have a middleware activation site but @@ -26,9 +38,30 @@ export async function checkFeatures( config: PreviouslyResolved, args: BuildHandlerArguments ): Promise { - // eslint-disable-next-line const request = args.request as IHttpRequest; + + if (request?.headers?.["smithy-protocol"] === "rpc-v2-cbor") { + setFeature(context, "PROTOCOL_RPC_V2_CBOR", "M"); + } + + if (typeof config.retryStrategy === "function") { + const retryStrategy = await config.retryStrategy(); + if (typeof (retryStrategy as RetryStrategyV2).acquireInitialRetryToken === "function") { + if (retryStrategy.constructor?.name?.includes("Adaptive")) { + setFeature(context, "RETRY_MODE_ADAPTIVE", "F"); + } else { + setFeature(context, "RETRY_MODE_STANDARD", "E"); + } + } else { + setFeature(context, "RETRY_MODE_LEGACY", "D"); + } + } + if (typeof config.accountIdEndpointMode === "function") { + const endpointV2 = context.endpointV2; + if (String(endpointV2?.url?.hostname).match(ACCOUNT_ID_ENDPOINT_REGEX)) { + setFeature(context, "ACCOUNT_ID_ENDPOINT", "O"); + } switch (await config.accountIdEndpointMode?.()) { case "disabled": setFeature(context, "ACCOUNT_ID_MODE_DISABLED", "Q"); diff --git a/packages/middleware-user-agent/src/middleware-user-agent.integ.spec.ts b/packages/middleware-user-agent/src/middleware-user-agent.integ.spec.ts index ca98caeec642..2ee442d5bf28 100644 --- a/packages/middleware-user-agent/src/middleware-user-agent.integ.spec.ts +++ b/packages/middleware-user-agent/src/middleware-user-agent.integ.spec.ts @@ -27,24 +27,25 @@ describe("middleware-user-agent", () => { }); describe("features", () => { - it("should detect DDB mapper, and account id mode", async () => { + it("should detect DDB mapper, account id, and account id mode", async () => { const client = new DynamoDB({ - credentials: { - accessKeyId: "", - secretAccessKey: "", - accountId: "123", - }, - accountIdEndpointMode: async () => "preferred" as const, + accountIdEndpointMode: async () => "required" as const, }); const doc = DynamoDBDocument.from(client); requireRequestsFrom(doc).toMatch({ headers: { - "user-agent": /(.*?) m\/d,P$/, + "user-agent": /(.*?) m\/d,E,O,R$/, }, }); + client.config.credentials = async () => ({ + accessKeyId: "", + secretAccessKey: "", + accountId: "123456789012", + }); + await doc.get({ TableName: "table", Key: {