1
+ import { EndpointParameterInstructions } from "@smithy/middleware-endpoint" ;
1
2
import { constructStack } from "@smithy/middleware-stack" ;
2
- import type { HttpRequest as __HttpRequest } from "@smithy/protocol-http" ;
3
+ import type { HttpRequest } from "@smithy/protocol-http" ;
3
4
import type {
4
5
Command as ICommand ,
5
6
FinalizeHandlerArguments ,
6
7
Handler ,
7
8
HandlerExecutionContext ,
9
+ HttpRequest as IHttpRequest ,
10
+ HttpResponse as IHttpResponse ,
8
11
Logger ,
9
12
MetadataBearer ,
10
13
MiddlewareStack as IMiddlewareStack ,
11
14
Pluggable ,
12
15
RequestHandler ,
16
+ SerdeContext ,
13
17
} from "@smithy/types" ;
14
18
import { SMITHY_CONTEXT_KEY } from "@smithy/types" ;
15
19
@@ -23,8 +27,22 @@ export abstract class Command<
23
27
ClientInput extends object = any ,
24
28
ClientOutput extends MetadataBearer = any
25
29
> implements ICommand < ClientInput , Input , ClientOutput , Output , ResolvedClientConfiguration > {
26
- abstract input : Input ;
27
- readonly middlewareStack : IMiddlewareStack < Input , Output > = constructStack < Input , Output > ( ) ;
30
+ public abstract input : Input ;
31
+ public readonly middlewareStack : IMiddlewareStack < Input , Output > = constructStack < Input , Output > ( ) ;
32
+
33
+ /**
34
+ * Factory for Command ClassBuilder.
35
+ * @internal
36
+ */
37
+ public static classBuilder <
38
+ I extends SI ,
39
+ O extends SO ,
40
+ C extends { logger : Logger ; requestHandler : RequestHandler < any , any , any > } ,
41
+ SI extends object = any ,
42
+ SO extends MetadataBearer = any
43
+ > ( ) {
44
+ return new ClassBuilder < I , O , C , SI , SO > ( ) ;
45
+ }
28
46
29
47
abstract resolveMiddleware (
30
48
stack : IMiddlewareStack < ClientInput , ClientOutput > ,
@@ -35,81 +53,22 @@ export abstract class Command<
35
53
/**
36
54
* @internal
37
55
*/
38
- protected resolveBuilder ( ) {
39
- const args : ResolveMiddlewareContextArgs = {
40
- middlewareQueue : [ ] as Pluggable < any , any > [ ] ,
41
- commandName : "" ,
42
- clientName : "" ,
43
- smithyContext : { } ,
44
- inputFilterSensitiveLog : ( ) => { } ,
45
- outputFilterSensitiveLog : ( ) => { } ,
46
- } ;
47
- return {
48
- /**
49
- * Add any number of middleware.
50
- */
51
- m ( ...middleware : Pluggable < any , any > [ ] ) {
52
- args . middlewareQueue . push ( ...middleware ) ;
53
- return this ;
54
- } ,
55
- /**
56
- * Set the context record.
57
- */
58
- c ( smithyContext : Record < string , unknown > ) {
59
- args . smithyContext = smithyContext ;
60
- return this ;
61
- } ,
62
- /**
63
- * Set constant string identifiers for the operation.
64
- */
65
- n ( clientName : string , commandName : string ) {
66
- args . clientName = clientName ;
67
- args . commandName = commandName ;
68
- return this ;
69
- } ,
70
- /**
71
- * Set the input and output sensistive log filters.
72
- */
73
- f ( inputFilter : ( _ : any ) => any = ( _ ) => _ , outputFilter : ( _ : any ) => any = ( _ ) => _ ) {
74
- args . inputFilterSensitiveLog = inputFilter ;
75
- args . outputFilterSensitiveLog = outputFilter ;
76
- return this ;
77
- } ,
78
- /**
79
- * @returns the implementation of the built resolveMiddleware function.
80
- */
81
- build : ( ) => {
82
- return (
83
- clientStack : IMiddlewareStack < ClientInput , ClientOutput > ,
84
- configuration : ResolvedClientConfiguration & {
85
- logger : Logger ;
86
- requestHandler : RequestHandler < any , any , any > ;
87
- } ,
88
- options : any
89
- ) => {
90
- return this . __resolveMiddleware ( clientStack , configuration , options , args ) ;
91
- } ;
92
- } ,
93
- } ;
94
- }
95
-
96
- /**
97
- * @internal
98
- */
99
- protected __resolveMiddleware (
100
- clientStack : IMiddlewareStack < ClientInput , ClientOutput > ,
101
- configuration : ResolvedClientConfiguration & { logger : Logger ; requestHandler : RequestHandler < any , any , any > } ,
56
+ public resolveMiddlewareWithContext (
57
+ clientStack : IMiddlewareStack < any , any > ,
58
+ configuration : { logger : Logger ; requestHandler : RequestHandler < any , any , any > } ,
102
59
options : any ,
103
60
{
104
- middlewareQueue ,
61
+ middlewareFn ,
105
62
clientName,
106
63
commandName,
107
64
inputFilterSensitiveLog,
108
65
outputFilterSensitiveLog,
109
66
smithyContext,
67
+ additionalContext,
68
+ CommandCtor,
110
69
} : ResolveMiddlewareContextArgs
111
70
) {
112
- for ( const mw of middlewareQueue ) {
71
+ for ( const mw of middlewareFn . bind ( this ) ( CommandCtor , configuration ) ) {
113
72
this . middlewareStack . use ( mw ) ;
114
73
}
115
74
const stack = clientStack . concat ( this . middlewareStack ) ;
@@ -123,11 +82,11 @@ export abstract class Command<
123
82
[ SMITHY_CONTEXT_KEY ] : {
124
83
...smithyContext ,
125
84
} ,
85
+ ...additionalContext ,
126
86
} ;
127
87
const { requestHandler } = configuration ;
128
88
return stack . resolve (
129
- ( request : FinalizeHandlerArguments < any > ) =>
130
- requestHandler . handle ( request . request as __HttpRequest , options || { } ) ,
89
+ ( request : FinalizeHandlerArguments < any > ) => requestHandler . handle ( request . request as HttpRequest , options || { } ) ,
131
90
handlerExecutionContext
132
91
) ;
133
92
}
@@ -137,10 +96,187 @@ export abstract class Command<
137
96
* @internal
138
97
*/
139
98
type ResolveMiddlewareContextArgs = {
140
- middlewareQueue : Pluggable < any , any > [ ] ;
99
+ middlewareFn : ( CommandCtor : any , config : any ) => Pluggable < any , any > [ ] ;
141
100
clientName : string ;
142
101
commandName : string ;
143
102
smithyContext : Record < string , unknown > ;
103
+ additionalContext : HandlerExecutionContext ;
144
104
inputFilterSensitiveLog : ( _ : any ) => any ;
145
105
outputFilterSensitiveLog : ( _ : any ) => any ;
106
+ CommandCtor : any /* Command constructor */ ;
146
107
} ;
108
+
109
+ /**
110
+ * @internal
111
+ */
112
+ class ClassBuilder <
113
+ I extends SI ,
114
+ O extends SO ,
115
+ C extends { logger : Logger ; requestHandler : RequestHandler < any , any , any > } ,
116
+ SI extends object = any ,
117
+ SO extends MetadataBearer = any
118
+ > {
119
+ private _init : ( _ : Command < I , O , C , SI , SO > ) => void = ( ) => { } ;
120
+ private _ep : EndpointParameterInstructions = { } ;
121
+ private _middlewareFn : ( CommandCtor : any , config : any ) => Pluggable < any , any > [ ] = ( ) => [ ] ;
122
+ private _commandName = "" ;
123
+ private _clientName = "" ;
124
+ private _additionalContext = { } as HandlerExecutionContext ;
125
+ private _smithyContext = { } as Record < string , unknown > ;
126
+ private _inputFilterSensitiveLog = ( _ : any ) => _ ;
127
+ private _outputFilterSensitiveLog = ( _ : any ) => _ ;
128
+ private _serializer : ( input : I , context : SerdeContext | any ) => Promise < IHttpRequest > = null as any ;
129
+ private _deserializer : ( output : IHttpResponse , context : SerdeContext | any ) => Promise < O > = null as any ;
130
+ /**
131
+ * Optional init callback.
132
+ */
133
+ public init ( cb : ( _ : Command < I , O , C , SI , SO > ) => void ) {
134
+ this . _init = cb ;
135
+ }
136
+ /**
137
+ * Set the endpoint parameter instructions.
138
+ */
139
+ public ep ( endpointParameterInstructions : EndpointParameterInstructions ) : ClassBuilder < I , O , C , SI , SO > {
140
+ this . _ep = endpointParameterInstructions ;
141
+ return this ;
142
+ }
143
+ /**
144
+ * Add any number of middleware.
145
+ */
146
+ public m (
147
+ middlewareSupplier : ( CommandCtor : any , config : any ) => Pluggable < any , any > [ ]
148
+ ) : ClassBuilder < I , O , C , SI , SO > {
149
+ this . _middlewareFn = middlewareSupplier ;
150
+ return this ;
151
+ }
152
+ /**
153
+ * Set the initial handler execution context Smithy field.
154
+ */
155
+ public s (
156
+ service : string ,
157
+ operation : string ,
158
+ smithyContext : Record < string , unknown > = { }
159
+ ) : ClassBuilder < I , O , C , SI , SO > {
160
+ this . _smithyContext = {
161
+ service,
162
+ operation,
163
+ ...smithyContext ,
164
+ } ;
165
+ return this ;
166
+ }
167
+ /**
168
+ * Set the initial handler execution context.
169
+ */
170
+ public c ( additionalContext : HandlerExecutionContext = { } ) : ClassBuilder < I , O , C , SI , SO > {
171
+ this . _additionalContext = additionalContext ;
172
+ return this ;
173
+ }
174
+ /**
175
+ * Set constant string identifiers for the operation.
176
+ */
177
+ public n ( clientName : string , commandName : string ) : ClassBuilder < I , O , C , SI , SO > {
178
+ this . _clientName = clientName ;
179
+ this . _commandName = commandName ;
180
+ return this ;
181
+ }
182
+ /**
183
+ * Set the input and output sensistive log filters.
184
+ */
185
+ public f (
186
+ inputFilter : ( _ : any ) => any = ( _ ) => _ ,
187
+ outputFilter : ( _ : any ) => any = ( _ ) => _
188
+ ) : ClassBuilder < I , O , C , SI , SO > {
189
+ this . _inputFilterSensitiveLog = inputFilter ;
190
+ this . _outputFilterSensitiveLog = outputFilter ;
191
+ return this ;
192
+ }
193
+ /**
194
+ * Sets the serializer.
195
+ */
196
+ public ser (
197
+ serializer : ( input : I , context ?: SerdeContext | any ) => Promise < IHttpRequest >
198
+ ) : ClassBuilder < I , O , C , SI , SO > {
199
+ this . _serializer = serializer ;
200
+ return this ;
201
+ }
202
+ /**
203
+ * Sets the deserializer.
204
+ */
205
+ public de (
206
+ deserializer : ( output : IHttpResponse , context ?: SerdeContext | any ) => Promise < O >
207
+ ) : ClassBuilder < I , O , C , SI , SO > {
208
+ this . _deserializer = deserializer ;
209
+ return this ;
210
+ }
211
+ /**
212
+ * @returns a Command class with the classBuilder properties.
213
+ */
214
+ public build ( ) : {
215
+ new ( input : I ) : CommandImpl < I , O , C , SI , SO > ;
216
+ getEndpointParameterInstructions ( ) : EndpointParameterInstructions ;
217
+ } {
218
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
219
+ const closure = this ;
220
+ let CommandRef : any ;
221
+
222
+ return ( CommandRef = class extends Command < I , O , C , SI , SO > {
223
+ /**
224
+ * @public
225
+ */
226
+ public static getEndpointParameterInstructions ( ) : EndpointParameterInstructions {
227
+ return closure . _ep ;
228
+ }
229
+
230
+ /**
231
+ * @public
232
+ */
233
+ public constructor ( readonly input : I ) {
234
+ super ( ) ;
235
+ closure . _init ( this ) ;
236
+ }
237
+
238
+ /**
239
+ * @internal
240
+ */
241
+ public resolveMiddleware ( stack : IMiddlewareStack < any , any > , configuration : C , options : any ) : Handler < any , any > {
242
+ return this . resolveMiddlewareWithContext ( stack , configuration , options , {
243
+ CommandCtor : CommandRef ,
244
+ middlewareFn : closure . _middlewareFn ,
245
+ clientName : closure . _clientName ,
246
+ commandName : closure . _commandName ,
247
+ inputFilterSensitiveLog : closure . _inputFilterSensitiveLog ,
248
+ outputFilterSensitiveLog : closure . _outputFilterSensitiveLog ,
249
+ smithyContext : closure . _smithyContext ,
250
+ additionalContext : closure . _additionalContext ,
251
+ } ) ;
252
+ }
253
+
254
+ /**
255
+ * @internal
256
+ */
257
+ // @ts -ignore used in middlewareFn closure.
258
+ public serialize = closure . _serializer ;
259
+
260
+ /**
261
+ * @internal
262
+ */
263
+ // @ts -ignore used in middlewareFn closure.
264
+ public deserialize = closure . _deserializer ;
265
+ } ) ;
266
+ }
267
+ }
268
+
269
+ /**
270
+ * A concrete implementation of ICommand with no abstract members.
271
+ * @public
272
+ */
273
+ export interface CommandImpl <
274
+ I extends SI ,
275
+ O extends SO ,
276
+ C extends { logger : Logger ; requestHandler : RequestHandler < any , any , any > } ,
277
+ SI extends object = any ,
278
+ SO extends MetadataBearer = any
279
+ > extends Command < I , O , C , SI , SO > {
280
+ readonly input : I ;
281
+ resolveMiddleware ( stack : IMiddlewareStack < SI , SO > , configuration : C , options : any ) : Handler < I , O > ;
282
+ }
0 commit comments