From d75c6203ea427057281826071a704647bb815900 Mon Sep 17 00:00:00 2001 From: AllanFly120 Date: Wed, 16 Oct 2019 23:47:23 -0700 Subject: [PATCH] feat: update runtime plugin interface (#400) * feat: remove generated SerDe runtime dependencies Instead, use the runtime-specific utils specified in client config * fix: change plugin interface to callback functions mutating the stack --- .../client-rds-data-node/RDSDataClient.ts | 14 ++- .../commands/ExecuteStatementCommand.ts | 27 ++---- .../protocol/AwsRestJson1_1.ts | 96 +++++++++---------- .../protocol/ExecuteStatement.ts | 7 +- .../middleware-content-length/src/index.ts | 13 ++- .../src/deserializerMiddleware.ts | 34 +++++++ packages/middleware-serde/src/index.ts | 94 +----------------- packages/middleware-serde/src/serdePlugin.ts | 33 +++++++ .../src/serializerMiddleware.ts | 29 ++++++ packages/middleware-user-agent/package.json | 2 +- .../middleware-user-agent/src/middleware.ts | 18 ++-- packages/protocol-rest-json/src/index.ts | 12 +-- .../retry-middleware/src/retryMiddleware.ts | 22 ++--- packages/signing-middleware/src/middleware.ts | 13 ++- packages/smithy-client/package.json | 2 +- packages/smithy-client/src/client.ts | 24 +---- packages/smithy-client/src/command.ts | 21 +--- packages/types/src/deserializer.ts | 14 +-- packages/types/src/middleware.ts | 42 ++------ packages/types/src/serializer.ts | 8 +- 20 files changed, 226 insertions(+), 299 deletions(-) create mode 100644 packages/middleware-serde/src/deserializerMiddleware.ts create mode 100644 packages/middleware-serde/src/serdePlugin.ts create mode 100644 packages/middleware-serde/src/serializerMiddleware.ts diff --git a/clients/node/client-rds-data-node/RDSDataClient.ts b/clients/node/client-rds-data-node/RDSDataClient.ts index 17b0e79a5bf3..85c9e5a19101 100644 --- a/clients/node/client-rds-data-node/RDSDataClient.ts +++ b/clients/node/client-rds-data-node/RDSDataClient.ts @@ -1,7 +1,7 @@ import { contentLengthPlugin } from "@aws-sdk/middleware-content-length"; -import { UserAgentPlugin, UserAgentConfig } from "@aws-sdk/middleware-user-agent"; +import { userAgentPlugin, UserAgentConfig } from "@aws-sdk/middleware-user-agent"; import { retryPlugin, RetryConfig } from "@aws-sdk/retry-middleware"; -import { signingPlugin, AwsAuthConfiguration } from "@aws-sdk/signing-middleware"; +import { awsAuthPlugin, AwsAuthConfiguration } from "@aws-sdk/signing-middleware"; import { RDSDataConfiguration, RDSDataResolvedConfiguration, @@ -22,19 +22,17 @@ export class RDSDataClient extends SmithyClient 0) { - super.use(retryPlugin(this.config)); - } - super.use(signingPlugin(this.config)); - super.use(UserAgentPlugin(this.config)); + super.use(retryPlugin(this.config)); + super.use(awsAuthPlugin(this.config)); + super.use(userAgentPlugin(this.config)); } destroy(): void { diff --git a/clients/node/client-rds-data-node/commands/ExecuteStatementCommand.ts b/clients/node/client-rds-data-node/commands/ExecuteStatementCommand.ts index 958bb054a3b7..7cdbdb7e3bcd 100644 --- a/clients/node/client-rds-data-node/commands/ExecuteStatementCommand.ts +++ b/clients/node/client-rds-data-node/commands/ExecuteStatementCommand.ts @@ -1,9 +1,6 @@ import { Command } from "@aws-sdk/smithy-client"; -import { - deserializerPlugin, - serializerPlugin -} from "@aws-sdk/middleware-serde"; -import * as __aws_sdk_types from "@aws-sdk/types"; +import { serdePlugin } from "@aws-sdk/middleware-serde"; +import { HttpOptions, Handler, HandlerExecutionContext } from "@aws-sdk/types"; import { RDSDataResolvedConfiguration } from "../RDSDataConfiguration"; import { HttpRequest } from "@aws-sdk/protocol-http"; import { @@ -22,7 +19,7 @@ type OutputTypesUnion = any; export class ExecuteStatementCommand extends Command< ExecuteStatementRequest, ExecuteStatementResponse -> { + > { constructor(readonly input: ExecuteStatementRequest) { super(); } @@ -30,30 +27,24 @@ export class ExecuteStatementCommand extends Command< resolveMiddleware( clientStack: MiddlewareStack, configuration: RDSDataResolvedConfiguration, - options?: __aws_sdk_types.HttpOptions - ): __aws_sdk_types.Handler< + options?: HttpOptions + ): Handler< ExecuteStatementRequest, ExecuteStatementResponse > { - const { httpHandler } = configuration; + const { protocol: { handler } } = configuration; - this.use(serializerPlugin(configuration, executeStatementSerializer)); - this.use( - deserializerPlugin( - configuration, - executeStatementDeserializer - ) - ); + this.use(serdePlugin(configuration, executeStatementSerializer, executeStatementDeserializer)); const stack = clientStack.concat(this.middlewareStack); - const handlerExecutionContext: __aws_sdk_types.HandlerExecutionContext = { + const handlerExecutionContext: HandlerExecutionContext = { logger: {} as any }; return stack.resolve( (request: FinalizeHandlerArguments) => - httpHandler.handle(request.request as HttpRequest, options || {}), + handler.handle(request.request as HttpRequest, options || {}), handlerExecutionContext ); } diff --git a/clients/node/client-rds-data-node/protocol/AwsRestJson1_1.ts b/clients/node/client-rds-data-node/protocol/AwsRestJson1_1.ts index 8d85ee362118..8acb3dcaf219 100644 --- a/clients/node/client-rds-data-node/protocol/AwsRestJson1_1.ts +++ b/clients/node/client-rds-data-node/protocol/AwsRestJson1_1.ts @@ -12,15 +12,11 @@ import { } from "../models/rdsdataservice"; import { HttpRequest, HttpResponse } from "@aws-sdk/protocol-http"; import { SerializerUtils, DeserializerUtils } from "@aws-sdk/types"; -import * as __aws_sdk_stream_collector_node from "@aws-sdk/stream-collector-node"; -import * as __aws_sdk_util_utf8_node from "@aws-sdk/util-utf8-node"; import { ResponseMetadata } from "@aws-sdk/types"; -type Utils = { [key: string]: any }; - export function executeStatementAwsRestJson1_1Serialize( input: ExecuteStatementRequest, - utils?: Utils + utils: SerializerUtils ): HttpRequest { let body: any = {}; if (input.resourceArn !== undefined) { @@ -44,7 +40,7 @@ export function executeStatementAwsRestJson1_1Serialize( } if (input.parameters !== undefined) { - body.parameters = sqlParameterListAwsRestJson1_1Serialize(input.parameters); + body.parameters = sqlParameterListAwsRestJson1_1Serialize(input.parameters, utils); } if (input.transactionId !== undefined) { @@ -72,51 +68,54 @@ export function executeStatementAwsRestJson1_1Serialize( export async function executeStatementAwsRestJson1_1Deserialize( output: HttpResponse, - utils?: Utils + utils: DeserializerUtils ): Promise { if (output.statusCode !== 200) { - return executeStatementAwsRestJson1_1DeserializeError(output); + return executeStatementAwsRestJson1_1DeserializeError(output, utils); } let data: any = await parseBody(output.body, utils); return Promise.resolve({ $metadata: deserializeMetadata(output), __type: "com.amazon.rdsdataservice#ExecuteStatementResponse", - records: recordsAwsRestJson1_1Deserialize(data.records), + records: recordsAwsRestJson1_1Deserialize(data.records, utils), columnMetadata: columnMetadataListAwsRestJson1_1Deserialize( - data.columnMetadata + data.columnMetadata, + utils ), numberOfRecordsUpdated: data.numberOfRecordsUpdated, generatedFields: generatedFieldsAwsRestJson1_1Deserialize( - data.generatedFields + data.generatedFields, + utils ) }); } async function executeStatementAwsRestJson1_1DeserializeError( - output: HttpResponse + output: HttpResponse, + utils: DeserializerUtils ): Promise { - let data = await parseBody(output.body); + let data = await parseBody(output.body, utils); let response: any; switch (output.headers["x-amzn-ErrorType"]) { case "BadRequestException": case "com.amazon.rdsdataservice#BadRequestException": - response = badRequestExceptionDeserialize(data); + response = badRequestExceptionDeserialize(data, utils); break; case "StatementTimeoutException": case "com.amazon.rdsdataservice#StatementTimeoutException": - response = statementTimeoutExceptionDeserialize(data); + response = statementTimeoutExceptionDeserialize(data, utils); break; case "ForbiddenException": case "com.amazon.rdsdataservice#ForbiddenException": - response = forbiddenExceptionDeserialize(data); + response = forbiddenExceptionDeserialize(data, utils); break; case "InternalServerErrorException": case "com.amazon.rdsdataservice#InternalServerErrorException": - response = internalServerErrorExceptionDeserialize(data); + response = internalServerErrorExceptionDeserialize(data, utils); break; case "ServiceUnavailableError": case "com.amazon.rdsdataservice#ServiceUnavailableError": - response = serviceUnavailableErrorDeserialize(data); + response = serviceUnavailableErrorDeserialize(data, utils); break; default: response = { @@ -130,19 +129,20 @@ async function executeStatementAwsRestJson1_1DeserializeError( } const sqlParameterListAwsRestJson1_1Serialize = ( - input: Array + input: Array, + utils: SerializerUtils ): Array => input && - input.map(sqlParameter => sqlParameterAwsRestJson1_1Serialize(sqlParameter)); + input.map(sqlParameter => sqlParameterAwsRestJson1_1Serialize(sqlParameter, utils)); -const sqlParameterAwsRestJson1_1Serialize = (input: SqlParameter): any => +const sqlParameterAwsRestJson1_1Serialize = (input: SqlParameter, utils: SerializerUtils): any => input.name && input.value && { name: input.name, - value: fieldAwsRestJson1_1Serialize(input.value) + value: fieldAwsRestJson1_1Serialize(input.value, utils) }; -const fieldAwsRestJson1_1Serialize = (input: Field): any => +const fieldAwsRestJson1_1Serialize = (input: Field, utils: SerializerUtils): any => Field.visit(input, { blobValue: value => { value; @@ -174,7 +174,8 @@ const fieldAwsRestJson1_1Serialize = (input: Field): any => }); export function columnMetadataAwsRestJson1_1Deserialize( - input: any + input: any, + utils: DeserializerUtils ): ColumnMetadata { let columnMetadata: any = { $namespace: "com.amazon.rdsdataservice", @@ -240,14 +241,15 @@ export function columnMetadataAwsRestJson1_1Deserialize( } const columnMetadataListAwsRestJson1_1Deserialize = ( - input: any + input: any, + utils: DeserializerUtils ): Array => input && input.map((columnMetadata: any) => - columnMetadataAwsRestJson1_1Deserialize(columnMetadata) + columnMetadataAwsRestJson1_1Deserialize(columnMetadata, utils) ); -const fieldAwsRestJson1_1Deserialize = (input: any): any => +const fieldAwsRestJson1_1Deserialize = (input: any, utils: DeserializerUtils): any => Field.visit(input, { blobValue: value => { value; @@ -278,19 +280,19 @@ const fieldAwsRestJson1_1Deserialize = (input: any): any => } }); -const generatedFieldsAwsRestJson1_1Deserialize = (input: any): Array => - input && input.map((field: any) => fieldAwsRestJson1_1Deserialize(field)); +const generatedFieldsAwsRestJson1_1Deserialize = (input: any, utils: DeserializerUtils): Array => + input && input.map((field: any) => fieldAwsRestJson1_1Deserialize(field, utils)); -const recordsAwsRestJson1_1Deserialize = (input: any): Array> => +const recordsAwsRestJson1_1Deserialize = (input: any, utils: DeserializerUtils): Array> => input && input.map((recordsList: any) => - recordsListAwsRestJson1_1Deserialize(recordsList) + recordsListAwsRestJson1_1Deserialize(recordsList, utils) ); -const recordsListAwsRestJson1_1Deserialize = (input: any): Array => - input && input.map((field: any) => fieldAwsRestJson1_1Deserialize(field)); +const recordsListAwsRestJson1_1Deserialize = (input: any, utils: DeserializerUtils): Array => + input && input.map((field: any) => fieldAwsRestJson1_1Deserialize(field, utils)); -const badRequestExceptionDeserialize = (input: any): BadRequestException => ({ +const badRequestExceptionDeserialize = (input: any, utils: DeserializerUtils): BadRequestException => ({ __type: "com.amazon.rdsdataservice#BadRequestException", $name: "BadRequestException", $fault: "client", @@ -298,7 +300,8 @@ const badRequestExceptionDeserialize = (input: any): BadRequestException => ({ }); const statementTimeoutExceptionDeserialize = ( - input: any + input: any, + utils: DeserializerUtils ): StatementTimeoutException => ({ __type: "com.amazon.rdsdataservice#StatementTimeoutException", $name: "StatementTimeoutException", @@ -307,7 +310,7 @@ const statementTimeoutExceptionDeserialize = ( dbConnectionId: input.dbConnectionId }); -const forbiddenExceptionDeserialize = (input: any): ForbiddenException => ({ +const forbiddenExceptionDeserialize = (input: any, utils: DeserializerUtils): ForbiddenException => ({ __type: "com.amazon.rdsdataservice#ForbiddenException", $name: "ForbiddenException", $fault: "client", @@ -315,7 +318,8 @@ const forbiddenExceptionDeserialize = (input: any): ForbiddenException => ({ }); const internalServerErrorExceptionDeserialize = ( - input: any + input: any, + utils: DeserializerUtils ): InternalServerErrorException => ({ __type: "com.amazon.rdsdataservice#InternalServerErrorException", $name: "InternalServerErrorException", @@ -323,7 +327,8 @@ const internalServerErrorExceptionDeserialize = ( }); const serviceUnavailableErrorDeserialize = ( - input: any + input: any, + utils: DeserializerUtils ): ServiceUnavailableError => ({ __type: "com.amazon.rdsdataservice#ServiceUnavailableError", $name: "ServiceUnavailableError", @@ -336,17 +341,8 @@ const deserializeMetadata = (output: HttpResponse): ResponseMetadata => ({ requestId: output.headers["x-amzn-requestid"] }); -const parseBody = (streamBody: any, utils?: Utils): any => { - const streamCollector = - utils && utils["streamCollector"] - ? (utils)["streamCollector"] - : __aws_sdk_stream_collector_node.streamCollector; - const toUtf8 = - utils && utils["streamCollector"] - ? (utils)["utf8Encoder"] - : __aws_sdk_util_utf8_node.toUtf8; - - return streamCollector(streamBody).then(body => { - return JSON.parse(toUtf8(body)); +const parseBody = (streamBody: any, utils: DeserializerUtils): any => { + return utils.streamCollector(streamBody).then(body => { + return JSON.parse(utils.utf8Encoder(body)); }); }; diff --git a/clients/node/client-rds-data-node/protocol/ExecuteStatement.ts b/clients/node/client-rds-data-node/protocol/ExecuteStatement.ts index 53bc195c5a0a..804b2115e99a 100644 --- a/clients/node/client-rds-data-node/protocol/ExecuteStatement.ts +++ b/clients/node/client-rds-data-node/protocol/ExecuteStatement.ts @@ -1,4 +1,5 @@ import { HttpRequest, HttpResponse } from "@aws-sdk/protocol-http"; +import { SerializerUtils, DeserializerUtils } from "@aws-sdk/types"; import { ExecuteStatementRequest, ExecuteStatementResponse @@ -8,12 +9,10 @@ import { executeStatementAwsRestJson1_1Deserialize } from "./AwsRestJson1_1"; -type Utils = { [key: string]: any }; - export function executeStatementSerializer( input: ExecuteStatementRequest, protocol: string, - utils?: Utils + utils: SerializerUtils ): HttpRequest { switch (protocol) { case "aws.rest-json-1.1": @@ -26,7 +25,7 @@ export function executeStatementSerializer( export async function executeStatementDeserializer( output: HttpResponse, protocol: string, - utils?: Utils + utils: DeserializerUtils ): Promise { switch (protocol) { case "aws.rest-json-1.1": diff --git a/packages/middleware-content-length/src/index.ts b/packages/middleware-content-length/src/index.ts index 16f97c786754..12efb1fd7a54 100644 --- a/packages/middleware-content-length/src/index.ts +++ b/packages/middleware-content-length/src/index.ts @@ -5,7 +5,7 @@ import { BodyLengthCalculator, MetadataBearer, BuildHandlerOutput, - InjectableMiddleware + Injectable } from "@aws-sdk/types"; import { HttpRequest } from "@aws-sdk/protocol-http"; @@ -44,12 +44,11 @@ export function contentLengthMiddleware( }; } -export function contentLengthPlugin(options: { +export const contentLengthPlugin = (options: { bodyLengthChecker: BodyLengthCalculator; -}): InjectableMiddleware { - return { - middleware: contentLengthMiddleware(options.bodyLengthChecker), +}): Injectable => clientStack => { + clientStack.add(contentLengthMiddleware(options.bodyLengthChecker), { step: "build", tags: { SET_CONTENT_LENGTH: true } - }; -} + }); +}; diff --git a/packages/middleware-serde/src/deserializerMiddleware.ts b/packages/middleware-serde/src/deserializerMiddleware.ts new file mode 100644 index 000000000000..d239625c8b6c --- /dev/null +++ b/packages/middleware-serde/src/deserializerMiddleware.ts @@ -0,0 +1,34 @@ +import { + ResponseDeserializer, + DeserializeMiddleware, + DeserializeHandler, + DeserializeHandlerArguments, + DeserializeHandlerOutput, + Protocol +} from "@aws-sdk/types"; + +export function deserializerMiddleware< + Input extends object, + Output extends object, + RuntimeUtils = any +>( + options: { protocol: Protocol } & RuntimeUtils, + deserializer: ResponseDeserializer +): DeserializeMiddleware { + return ( + next: DeserializeHandler + ): DeserializeHandler => async ( + args: DeserializeHandlerArguments + ): Promise> => { + const { response } = await next(args); + const parsed = await options.protocol.deserialize( + deserializer, + response, + options + ); + return { + response, + output: parsed as Output + }; + }; +} diff --git a/packages/middleware-serde/src/index.ts b/packages/middleware-serde/src/index.ts index 05de97d411dc..ac6ed6853d6f 100644 --- a/packages/middleware-serde/src/index.ts +++ b/packages/middleware-serde/src/index.ts @@ -1,91 +1,3 @@ -import { - RequestSerializer, - SerializeHandler, - SerializeHandlerArguments, - SerializeMiddleware, - SerializeHandlerOutput, - ResponseDeserializer, - DeserializeHandler, - DeserializeHandlerArguments, - DeserializeMiddleware, - DeserializeHandlerOutput, - Protocol, - SerializerUtils, - DeserializerUtils, - InjectableMiddleware -} from "@aws-sdk/types"; - -export function deserializerMiddleware< - Input extends object, - Output extends object ->( - options: DeserializerMiddlewareConfig, - deserializer: ResponseDeserializer -): DeserializeMiddleware { - return ( - next: DeserializeHandler - ): DeserializeHandler => async ( - args: DeserializeHandlerArguments - ): Promise> => { - const { response } = await next(args); - const parsed = await options.protocol.deserialize( - deserializer, - response, - options - ); - return { - response, - output: parsed as Output - }; - }; -} - -export interface DeserializerMiddlewareConfig extends DeserializerUtils { - protocol: Protocol; -} - -export function deserializerPlugin( - config: DeserializerMiddlewareConfig, - serializer: ResponseDeserializer -): InjectableMiddleware { - return { - middleware: deserializerMiddleware(config, serializer), - step: "deserialize", - tags: { DESERIALIZER: true } - }; -} - -export function serializerMiddleware< - Input extends object, - Output extends object ->( - options: SerializerMiddlewareConfig, - serializer: RequestSerializer -): SerializeMiddleware { - return ( - next: SerializeHandler - ): SerializeHandler => async ( - args: SerializeHandlerArguments - ): Promise> => { - const request = options.protocol.serialize(serializer, args.input, options); - return next({ - ...args, - request - }); - }; -} - -export interface SerializerMiddlewareConfig extends SerializerUtils { - protocol: Protocol; -} - -export function serializerPlugin( - config: SerializerMiddlewareConfig, - serializer: RequestSerializer -): InjectableMiddleware { - return { - middleware: serializerMiddleware(config, serializer), - step: "serialize", - tags: { SERIALIZER: true } - }; -} +export * from "./deserializerMiddleware"; +export * from "./serializerMiddleware"; +export * from "./serdePlugin"; diff --git a/packages/middleware-serde/src/serdePlugin.ts b/packages/middleware-serde/src/serdePlugin.ts new file mode 100644 index 000000000000..38027c966d53 --- /dev/null +++ b/packages/middleware-serde/src/serdePlugin.ts @@ -0,0 +1,33 @@ +import { + RequestSerializer, + ResponseDeserializer, + Injectable, + Protocol, + MetadataBearer, + MiddlewareStack +} from "@aws-sdk/types"; +import { deserializerMiddleware } from "./deserializerMiddleware"; +import { serializerMiddleware } from "./serializerMiddleware"; + +export function serdePlugin< + InputType extends object, + SerializerRuntimeUtils, + OutputType extends MetadataBearer, + DeserializerRuntimeUtils +>( + config: SerializerRuntimeUtils & + DeserializerRuntimeUtils & { protocol: Protocol }, + serializer: RequestSerializer, + deserializer: ResponseDeserializer +): Injectable { + return (commandStack: MiddlewareStack) => { + commandStack.add(deserializerMiddleware(config, deserializer), { + step: "deserialize", + tags: { DESERIALIZER: true } + }); + commandStack.add(serializerMiddleware(config, serializer), { + step: "serialize", + tags: { SERIALIZER: true } + }); + }; +} diff --git a/packages/middleware-serde/src/serializerMiddleware.ts b/packages/middleware-serde/src/serializerMiddleware.ts new file mode 100644 index 000000000000..72adf4249542 --- /dev/null +++ b/packages/middleware-serde/src/serializerMiddleware.ts @@ -0,0 +1,29 @@ +import { + RequestSerializer, + SerializeHandler, + SerializeHandlerArguments, + SerializeHandlerOutput, + SerializeMiddleware, + Protocol +} from "@aws-sdk/types"; + +export function serializerMiddleware< + Input extends object, + Output extends object, + RuntimeUtils = any +>( + options: { protocol: Protocol } & RuntimeUtils, + serializer: RequestSerializer +): SerializeMiddleware { + return ( + next: SerializeHandler + ): SerializeHandler => async ( + args: SerializeHandlerArguments + ): Promise> => { + const request = options.protocol.serialize(serializer, args.input, options); + return next({ + ...args, + request + }); + }; +} diff --git a/packages/middleware-user-agent/package.json b/packages/middleware-user-agent/package.json index 40d901874194..1cee9aa368b8 100644 --- a/packages/middleware-user-agent/package.json +++ b/packages/middleware-user-agent/package.json @@ -4,7 +4,7 @@ "scripts": { "prepublishOnly": "tsc", "pretest": "tsc -p tsconfig.test.json", - "test": "jest" + "test": "jest --passWithNoTests" }, "main": "./build/index.js", "types": "./build/index.d.ts", diff --git a/packages/middleware-user-agent/src/middleware.ts b/packages/middleware-user-agent/src/middleware.ts index 1a6cd787403b..0b572609925f 100644 --- a/packages/middleware-user-agent/src/middleware.ts +++ b/packages/middleware-user-agent/src/middleware.ts @@ -1,17 +1,16 @@ import { - BuildMiddleware, BuildHandlerArguments, BuildHandler, MetadataBearer, BuildHandlerOutput, - InjectableMiddleware + Injectable } from "@aws-sdk/types"; import { HttpRequest } from "@aws-sdk/protocol-http"; import { UserAgentConfig } from "./configurations"; const userAgentHeader = "User-Agent"; -export function UserAgentMiddleware(options: UserAgentConfig.Resolved) { +export function userAgentMiddleware(options: UserAgentConfig.Resolved) { return ( next: BuildHandler ): BuildHandler => ( @@ -35,12 +34,11 @@ export function UserAgentMiddleware(options: UserAgentConfig.Resolved) { }; } -export function UserAgentPlugin( - options: UserAgentConfig.Resolved -): InjectableMiddleware { - return { - middleware: UserAgentMiddleware(options), +export const userAgentPlugin = ( + config: UserAgentConfig.Resolved +): Injectable => clientStack => { + clientStack.add(userAgentMiddleware(config), { step: "build", tags: { SET_USER_AGENT: true } - }; -} + }); +}; diff --git a/packages/protocol-rest-json/src/index.ts b/packages/protocol-rest-json/src/index.ts index 721a61dace04..8f8f94e1b98a 100644 --- a/packages/protocol-rest-json/src/index.ts +++ b/packages/protocol-rest-json/src/index.ts @@ -20,17 +20,17 @@ export class RestJsonProtocol extends Protocol< super(handler); } serialize( - serializer: RequestSerializer, + serializer: RequestSerializer, input: any, - utils?: SerializerUtils + utils: SerializerUtils ) { - return serializer(input, "aws.rest-json-1.1"); + return serializer(input, "aws.rest-json-1.1", utils); } deserialize( - parser: ResponseDeserializer, + deserializer: ResponseDeserializer, output: HttpResponse, - utils?: DeserializerUtils + utils: DeserializerUtils ) { - return parser(output, "aws.rest-json-1.1") as any; + return deserializer(output, "aws.rest-json-1.1", utils) as any; } } diff --git a/packages/retry-middleware/src/retryMiddleware.ts b/packages/retry-middleware/src/retryMiddleware.ts index 3bac44958930..ef0060501f84 100644 --- a/packages/retry-middleware/src/retryMiddleware.ts +++ b/packages/retry-middleware/src/retryMiddleware.ts @@ -3,7 +3,7 @@ import { FinalizeHandlerArguments, MetadataBearer, FinalizeHandlerOutput, - InjectableMiddleware + Injectable } from "@aws-sdk/types"; import { RetryConfig } from "./configurations"; @@ -17,13 +17,13 @@ export function retryMiddleware(options: RetryConfig.Resolved) { }; } -export function retryPlugin< - Input extends object, - Output extends MetadataBearer ->(options: RetryConfig.Resolved): InjectableMiddleware { - return { - middleware: retryMiddleware(options), - step: "finalizeRequest", - tags: { RETRY: true } - }; -} +export const retryPlugin = ( + options: RetryConfig.Resolved +): Injectable => clientStack => { + if (options.maxRetries > 0) { + clientStack.add(retryMiddleware(options), { + step: "finalizeRequest", + tags: { RETRY: true } + }); + } +}; diff --git a/packages/signing-middleware/src/middleware.ts b/packages/signing-middleware/src/middleware.ts index bbcd92ae58a0..3ec95212eae9 100644 --- a/packages/signing-middleware/src/middleware.ts +++ b/packages/signing-middleware/src/middleware.ts @@ -3,7 +3,7 @@ import { FinalizeHandlerArguments, FinalizeRequestMiddleware, FinalizeHandlerOutput, - InjectableMiddleware + Injectable } from "@aws-sdk/types"; import { AwsAuthConfiguration } from "./configurations"; import { HttpRequest } from "@aws-sdk/protocol-http"; @@ -25,12 +25,11 @@ export function signingMiddleware( }; } -export function signingPlugin( +export const awsAuthPlugin = ( options: AwsAuthConfiguration.Resolved -): InjectableMiddleware { - return { - middleware: signingMiddleware(options), +): Injectable => clientStack => { + clientStack.add(signingMiddleware(options), { step: "finalizeRequest", tags: { SIGNATURE: true } - }; -} + }); +}; diff --git a/packages/smithy-client/package.json b/packages/smithy-client/package.json index 6b191621f979..b3629fdebaab 100644 --- a/packages/smithy-client/package.json +++ b/packages/smithy-client/package.json @@ -4,7 +4,7 @@ "scripts": { "prepublishOnly": "tsc", "pretest": "tsc -p tsconfig.test.json", - "test": "jest" + "test": "jest --passWithNoTests" }, "main": "./build/index.js", "types": "./build/index.d.ts", diff --git a/packages/smithy-client/src/client.ts b/packages/smithy-client/src/client.ts index 683b33c1ef6d..4b0447c7f5ad 100644 --- a/packages/smithy-client/src/client.ts +++ b/packages/smithy-client/src/client.ts @@ -1,11 +1,5 @@ import { MiddlewareStack } from "@aws-sdk/middleware-stack"; -import { - Protocol, - Command, - MetadataBearer, - InjectableMiddleware, - HandlerOptions as InjectOptions -} from "@aws-sdk/types"; +import { Protocol, Command, MetadataBearer, Injectable } from "@aws-sdk/types"; export interface SmithyConfiguration { protocol: Protocol; @@ -25,20 +19,8 @@ export class Client< constructor(config: SmithyConfiguration) { this.config = config; } - use( - injectable: InjectableMiddleware, - options: InjectOptions = {} - ) { - const { middleware, step, priority, tags } = injectable; - this.middlewareStack.add( - // @ts-ignore -- Middleware and option type matching safety is enforced by InjectableMiddleware types - middleware, - { - step: options.step || step, - priority: options.priority || priority, - tags: { ...tags, ...options.tags } - } - ); + use(injectable: Injectable) { + injectable(this.middlewareStack); } send( command: Command< diff --git a/packages/smithy-client/src/command.ts b/packages/smithy-client/src/command.ts index 2648c9eb0d74..095e10f1ef82 100644 --- a/packages/smithy-client/src/command.ts +++ b/packages/smithy-client/src/command.ts @@ -1,24 +1,9 @@ import { MiddlewareStack } from "@aws-sdk/middleware-stack"; -import { - InjectableMiddleware, - HandlerOptions as InjectOptions -} from "@aws-sdk/types"; +import { Injectable, HandlerOptions as InjectOptions } from "@aws-sdk/types"; export class Command { readonly middlewareStack = new MiddlewareStack(); - use( - injectable: InjectableMiddleware, - options: InjectOptions = {} - ) { - const { middleware, step, priority, tags } = injectable; - this.middlewareStack.add( - // @ts-ignore - middleware, - { - step: options.step || step, - priority: options.priority || priority, - tags: { ...tags, ...options.tags } - } - ); + use(injectable: Injectable) { + injectable(this.middlewareStack); } } diff --git a/packages/types/src/deserializer.ts b/packages/types/src/deserializer.ts index bfd81f4404db..9ac0c0493ced 100644 --- a/packages/types/src/deserializer.ts +++ b/packages/types/src/deserializer.ts @@ -18,7 +18,11 @@ export interface DeserializerUtils { streamCollector: StreamCollector; } -export interface ResponseDeserializer { +export interface ResponseDeserializer< + OutputType, + ResponseType = any, + RuntimeUtils = any +> { /** * Converts the output of an operation into JavaScript types. * @@ -29,9 +33,7 @@ export interface ResponseDeserializer { * @param utils The runtime-specific util functions. If provided will * overwrite the provided ones */ - ( - output: ResponseType, - protocolName: string, - utils?: { [key: string]: any } - ): Promise; + (output: ResponseType, protocolName: string, utils: RuntimeUtils): Promise< + OutputType + >; } diff --git a/packages/types/src/middleware.ts b/packages/types/src/middleware.ts index 1b9292f68aed..460344481ae3 100644 --- a/packages/types/src/middleware.ts +++ b/packages/types/src/middleware.ts @@ -366,37 +366,11 @@ export interface HandlerExecutionContext { logger: Logger; } -export type InjectableMiddleware< - Input extends object = any, - Output extends object = any -> = - | { - middleware: Middleware; - step: "initialize"; - priority?: number; - tags?: { [tag: string]: any }; - } - | { - middleware: SerializeMiddleware; - step: "serialize"; - priority?: number; - tags?: { [tag: string]: any }; - } - | { - middleware: FinalizeRequestMiddleware; - step: "build"; - priority?: number; - tags?: { [tag: string]: any }; - } - | { - middleware: FinalizeRequestMiddleware; - step: "finalizeRequest"; - priority?: number; - tags?: { [tag: string]: any }; - } - | { - middleware: DeserializeMiddleware; - step: "deserialize"; - priority?: number; - tags?: { [tag: string]: any }; - }; +export interface Injectable { + /** + * A function that mutate the passed in middleware stack. Functions implementing + * this interface can add, remove, modify existing middleware stack from clients + * or commands + */ + (stack: MiddlewareStack): void; +} diff --git a/packages/types/src/serializer.ts b/packages/types/src/serializer.ts index d12df2a98301..6b2ffd78f3b8 100644 --- a/packages/types/src/serializer.ts +++ b/packages/types/src/serializer.ts @@ -8,7 +8,7 @@ export interface SerializerUtils { base64Encoder: Encoder; } -export interface RequestSerializer { +export interface RequestSerializer { /** * Converts the provided `input` into a request object * @@ -19,9 +19,5 @@ export interface RequestSerializer { * @param config The runtime-specific util functions. If provided will * overwrite the provided ones */ - ( - input: any, - transferProtocol: string, - utils?: { [key: string]: any } - ): Request; + (input: any, transferProtocol: string, utils: RuntimeUtils): Request; }