Skip to content

Commit 5cd2feb

Browse files
committed
command class builder
1 parent 1a2b63f commit 5cd2feb

File tree

4 files changed

+348
-188
lines changed

4 files changed

+348
-188
lines changed

packages/smithy-client/src/command.ts

Lines changed: 204 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
<<<<<<< HEAD
12
import type { EndpointParameterInstructions } from "@smithy/middleware-endpoint";
3+
=======
4+
import { EndpointParameterInstructions } from "@smithy/middleware-endpoint";
5+
>>>>>>> d3694aaca (command class builder)
26
import { constructStack } from "@smithy/middleware-stack";
37
import type { HttpRequest } from "@smithy/protocol-http";
48
import type {
@@ -53,6 +57,7 @@ export abstract class Command<
5357
/**
5458
* @internal
5559
*/
60+
<<<<<<< HEAD
5661
<<<<<<< HEAD
5762
public resolveMiddlewareWithContext(
5863
clientStack: IMiddlewareStack<any, any>,
@@ -135,18 +140,29 @@ export abstract class Command<
135140
protected __resolveMiddleware(
136141
clientStack: IMiddlewareStack<ClientInput, ClientOutput>,
137142
configuration: ResolvedClientConfiguration & { logger: Logger; requestHandler: RequestHandler<any, any, any> },
143+
=======
144+
public resolveMiddlewareWithContext(
145+
clientStack: IMiddlewareStack<any, any>,
146+
configuration: { logger: Logger; requestHandler: RequestHandler<any, any, any> },
147+
>>>>>>> d3694aaca (command class builder)
138148
options: any,
139149
{
140-
middlewareQueue,
150+
middlewareFn,
141151
clientName,
142152
commandName,
143153
inputFilterSensitiveLog,
144154
outputFilterSensitiveLog,
145155
smithyContext,
156+
additionalContext,
157+
CommandCtor,
146158
}: ResolveMiddlewareContextArgs
147159
) {
160+
<<<<<<< HEAD
148161
for (const mw of middlewareQueue) {
149162
>>>>>>> 74a500ee1 (feat: command codegen)
163+
=======
164+
for (const mw of middlewareFn.bind(this)(CommandCtor, clientStack, configuration, options)) {
165+
>>>>>>> d3694aaca (command class builder)
150166
this.middlewareStack.use(mw);
151167
}
152168
const stack = clientStack.concat(this.middlewareStack);
@@ -163,6 +179,7 @@ export abstract class Command<
163179
...smithyContext,
164180
},
165181
...additionalContext,
182+
<<<<<<< HEAD
166183
};
167184
const { requestHandler } = configuration;
168185
return stack.resolve(
@@ -371,11 +388,12 @@ export interface CommandImpl<
371388
...smithyContext,
372389
>>>>>>> 8fc21143c (update ts pkg)
373390
},
391+
=======
392+
>>>>>>> d3694aaca (command class builder)
374393
};
375394
const { requestHandler } = configuration;
376395
return stack.resolve(
377-
(request: FinalizeHandlerArguments<any>) =>
378-
requestHandler.handle(request.request as __HttpRequest, options || {}),
396+
(request: FinalizeHandlerArguments<any>) => requestHandler.handle(request.request as HttpRequest, options || {}),
379397
handlerExecutionContext
380398
);
381399
}
@@ -386,10 +404,192 @@ export interface CommandImpl<
386404
* @internal
387405
*/
388406
type ResolveMiddlewareContextArgs = {
389-
middlewareQueue: Pluggable<any, any>[];
407+
middlewareFn: (CommandCtor: any, clientStack: any, config: any, options: any) => Pluggable<any, any>[];
390408
clientName: string;
391409
commandName: string;
392410
smithyContext: Record<string, unknown>;
411+
additionalContext: HandlerExecutionContext;
393412
inputFilterSensitiveLog: (_: any) => any;
394413
outputFilterSensitiveLog: (_: any) => any;
414+
CommandCtor: any /* Command constructor */;
395415
};
416+
417+
/**
418+
* @internal
419+
*/
420+
class ClassBuilder<
421+
I extends SI,
422+
O extends SO,
423+
C extends { logger: Logger; requestHandler: RequestHandler<any, any, any> },
424+
SI extends object = any,
425+
SO extends MetadataBearer = any
426+
> {
427+
private _init: (_: Command<I, O, C, SI, SO>) => void = () => {};
428+
private _ep: EndpointParameterInstructions = {};
429+
private _middlewareFn: (
430+
CommandCtor: any,
431+
clientStack: any,
432+
config: any,
433+
options: any
434+
) => Pluggable<any, any>[] = () => [];
435+
private _commandName = "";
436+
private _clientName = "";
437+
private _additionalContext = {} as HandlerExecutionContext;
438+
private _smithyContext = {} as Record<string, unknown>;
439+
private _inputFilterSensitiveLog = (_: any) => _;
440+
private _outputFilterSensitiveLog = (_: any) => _;
441+
private _serializer: (input: I, context: SerdeContext | any) => Promise<IHttpRequest> = null as any;
442+
private _deserializer: (output: IHttpResponse, context: SerdeContext | any) => Promise<O> = null as any;
443+
/**
444+
* Optional init callback.
445+
*/
446+
public init(cb: (_: Command<I, O, C, SI, SO>) => void) {
447+
this._init = cb;
448+
}
449+
/**
450+
* Set the endpoint parameter instructions.
451+
*/
452+
public ep(endpointParameterInstructions: EndpointParameterInstructions): ClassBuilder<I, O, C, SI, SO> {
453+
this._ep = endpointParameterInstructions;
454+
return this;
455+
}
456+
/**
457+
* Add any number of middleware.
458+
*/
459+
public m(
460+
middlewareSupplier: (CommandCtor: any, clientStack: any, config: any, options: any) => Pluggable<any, any>[]
461+
): ClassBuilder<I, O, C, SI, SO> {
462+
this._middlewareFn = middlewareSupplier;
463+
return this;
464+
}
465+
/**
466+
* Set the initial handler execution context Smithy field.
467+
*/
468+
public s(
469+
service: string,
470+
operation: string,
471+
smithyContext: Record<string, unknown> = {}
472+
): ClassBuilder<I, O, C, SI, SO> {
473+
this._smithyContext = {
474+
service,
475+
operation,
476+
...smithyContext,
477+
};
478+
return this;
479+
}
480+
/**
481+
* Set the initial handler execution context.
482+
*/
483+
public c(additionalContext: HandlerExecutionContext = {}): ClassBuilder<I, O, C, SI, SO> {
484+
this._additionalContext = additionalContext;
485+
return this;
486+
}
487+
/**
488+
* Set constant string identifiers for the operation.
489+
*/
490+
public n(clientName: string, commandName: string): ClassBuilder<I, O, C, SI, SO> {
491+
this._clientName = clientName;
492+
this._commandName = commandName;
493+
return this;
494+
}
495+
/**
496+
* Set the input and output sensistive log filters.
497+
*/
498+
public f(
499+
inputFilter: (_: any) => any = (_) => _,
500+
outputFilter: (_: any) => any = (_) => _
501+
): ClassBuilder<I, O, C, SI, SO> {
502+
this._inputFilterSensitiveLog = inputFilter;
503+
this._outputFilterSensitiveLog = outputFilter;
504+
return this;
505+
}
506+
/**
507+
* Sets the serializer.
508+
*/
509+
public ser(
510+
serializer: (input: I, context?: SerdeContext | any) => Promise<IHttpRequest>
511+
): ClassBuilder<I, O, C, SI, SO> {
512+
this._serializer = serializer;
513+
return this;
514+
}
515+
/**
516+
* Sets the deserializer.
517+
*/
518+
public de(
519+
deserializer: (output: IHttpResponse, context?: SerdeContext | any) => Promise<O>
520+
): ClassBuilder<I, O, C, SI, SO> {
521+
this._deserializer = deserializer;
522+
return this;
523+
}
524+
/**
525+
* @returns a Command class with the classBuilder properties.
526+
*/
527+
public build(): {
528+
new (input: I): CommandImpl<I, O, C, SI, SO>;
529+
getEndpointParameterInstructions(): EndpointParameterInstructions;
530+
} {
531+
// eslint-disable-next-line @typescript-eslint/no-this-alias
532+
const closure = this;
533+
let CommandRef: any;
534+
535+
return (CommandRef = class extends Command<I, O, C, SI, SO> {
536+
/**
537+
* @public
538+
*/
539+
public static getEndpointParameterInstructions(): EndpointParameterInstructions {
540+
return closure._ep;
541+
}
542+
543+
/**
544+
* @public
545+
*/
546+
public constructor(readonly input: I) {
547+
super();
548+
closure._init(this);
549+
}
550+
551+
/**
552+
* @internal
553+
*/
554+
public resolveMiddleware(stack: IMiddlewareStack<any, any>, configuration: C, options: any): Handler<any, any> {
555+
return this.resolveMiddlewareWithContext(stack, configuration, options, {
556+
CommandCtor: CommandRef,
557+
middlewareFn: closure._middlewareFn,
558+
clientName: closure._clientName,
559+
commandName: closure._commandName,
560+
inputFilterSensitiveLog: closure._inputFilterSensitiveLog,
561+
outputFilterSensitiveLog: closure._outputFilterSensitiveLog,
562+
smithyContext: closure._smithyContext,
563+
additionalContext: closure._additionalContext,
564+
});
565+
}
566+
567+
/**
568+
* @internal
569+
*/
570+
// @ts-ignore used in middlewareFn closure.
571+
public serialize = closure._serializer;
572+
573+
/**
574+
* @internal
575+
*/
576+
// @ts-ignore used in middlewareFn closure.
577+
public deserialize = closure._deserializer;
578+
});
579+
}
580+
}
581+
582+
/**
583+
* A concrete implementation of ICommand with no abstract members.
584+
* @public
585+
*/
586+
export interface CommandImpl<
587+
I extends SI,
588+
O extends SO,
589+
C extends { logger: Logger; requestHandler: RequestHandler<any, any, any> },
590+
SI extends object = any,
591+
SO extends MetadataBearer = any
592+
> extends Command<I, O, C, SI, SO> {
593+
readonly input: I;
594+
resolveMiddleware(stack: IMiddlewareStack<SI, SO>, configuration: C, options: any): Handler<I, O>;
595+
}

0 commit comments

Comments
 (0)