1 | import { Logger } from "./logger";
|
2 | import { UserAgent } from "./util";
|
3 | export interface InitializeHandlerArguments<Input extends object> {
|
4 | /**
|
5 | * User input to a command. Reflects the userland representation of the
|
6 | * union of data types the command can effectively handle.
|
7 | */
|
8 | input: Input;
|
9 | }
|
10 | export interface InitializeHandlerOutput<Output extends object> extends DeserializeHandlerOutput<Output> {
|
11 | output: Output;
|
12 | }
|
13 | export interface SerializeHandlerArguments<Input extends object> extends InitializeHandlerArguments<Input> {
|
14 | /**
|
15 | * The user input serialized as a request object. The request object is unknown,
|
16 | * so you cannot modify it directly. When work with request, you need to guard its
|
17 | * type to e.g. HttpRequest with 'instanceof' operand
|
18 | *
|
19 | * During the build phase of the execution of a middleware stack, a built
|
20 | * request may or may not be available.
|
21 | */
|
22 | request?: unknown;
|
23 | }
|
24 | export interface SerializeHandlerOutput<Output extends object> extends InitializeHandlerOutput<Output> {
|
25 | }
|
26 | export interface BuildHandlerArguments<Input extends object> extends FinalizeHandlerArguments<Input> {
|
27 | }
|
28 | export interface BuildHandlerOutput<Output extends object> extends InitializeHandlerOutput<Output> {
|
29 | }
|
30 | export interface FinalizeHandlerArguments<Input extends object> extends SerializeHandlerArguments<Input> {
|
31 | /**
|
32 | * The user input serialized as a request.
|
33 | */
|
34 | request: unknown;
|
35 | }
|
36 | export interface FinalizeHandlerOutput<Output extends object> extends InitializeHandlerOutput<Output> {
|
37 | }
|
38 | export interface DeserializeHandlerArguments<Input extends object> extends FinalizeHandlerArguments<Input> {
|
39 | }
|
40 | export interface DeserializeHandlerOutput<Output extends object> {
|
41 | /**
|
42 | * The raw response object from runtime is deserialized to structured output object.
|
43 | * The response object is unknown so you cannot modify it directly. When work with
|
44 | * response, you need to guard its type to e.g. HttpResponse with 'instanceof' operand.
|
45 | *
|
46 | * During the deserialize phase of the execution of a middleware stack, a deserialized
|
47 | * response may or may not be available
|
48 | */
|
49 | response: unknown;
|
50 | output?: Output;
|
51 | }
|
52 | export interface InitializeHandler<Input extends object, Output extends object> {
|
53 | /**
|
54 | * Asynchronously converts an input object into an output object.
|
55 | *
|
56 | * @param args An object containing a input to the command as well as any
|
57 | * associated or previously generated execution artifacts.
|
58 | */
|
59 | (args: InitializeHandlerArguments<Input>): Promise<InitializeHandlerOutput<Output>>;
|
60 | }
|
61 | export declare type Handler<Input extends object, Output extends object> = InitializeHandler<Input, Output>;
|
62 | export interface SerializeHandler<Input extends object, Output extends object> {
|
63 | /**
|
64 | * Asynchronously converts an input object into an output object.
|
65 | *
|
66 | * @param args An object containing a input to the command as well as any
|
67 | * associated or previously generated execution artifacts.
|
68 | */
|
69 | (args: SerializeHandlerArguments<Input>): Promise<SerializeHandlerOutput<Output>>;
|
70 | }
|
71 | export interface FinalizeHandler<Input extends object, Output extends object> {
|
72 | /**
|
73 | * Asynchronously converts an input object into an output object.
|
74 | *
|
75 | * @param args An object containing a input to the command as well as any
|
76 | * associated or previously generated execution artifacts.
|
77 | */
|
78 | (args: FinalizeHandlerArguments<Input>): Promise<FinalizeHandlerOutput<Output>>;
|
79 | }
|
80 | export interface BuildHandler<Input extends object, Output extends object> {
|
81 | (args: BuildHandlerArguments<Input>): Promise<BuildHandlerOutput<Output>>;
|
82 | }
|
83 | export interface DeserializeHandler<Input extends object, Output extends object> {
|
84 | (args: DeserializeHandlerArguments<Input>): Promise<DeserializeHandlerOutput<Output>>;
|
85 | }
|
86 | /**
|
87 | * A factory function that creates functions implementing the {Handler}
|
88 | * interface.
|
89 | */
|
90 | export interface InitializeMiddleware<Input extends object, Output extends object> {
|
91 | /**
|
92 | * @param next The handler to invoke after this middleware has operated on
|
93 | * the user input and before this middleware operates on the output.
|
94 | *
|
95 | * @param context Invariant data and functions for use by the handler.
|
96 | */
|
97 | (next: InitializeHandler<Input, Output>, context: HandlerExecutionContext): InitializeHandler<Input, Output>;
|
98 | }
|
99 | /**
|
100 | * A factory function that creates functions implementing the {BuildHandler}
|
101 | * interface.
|
102 | */
|
103 | export interface SerializeMiddleware<Input extends object, Output extends object> {
|
104 | /**
|
105 | * @param next The handler to invoke after this middleware has operated on
|
106 | * the user input and before this middleware operates on the output.
|
107 | *
|
108 | * @param context Invariant data and functions for use by the handler.
|
109 | */
|
110 | (next: SerializeHandler<Input, Output>, context: HandlerExecutionContext): SerializeHandler<Input, Output>;
|
111 | }
|
112 | /**
|
113 | * A factory function that creates functions implementing the {FinalizeHandler}
|
114 | * interface.
|
115 | */
|
116 | export interface FinalizeRequestMiddleware<Input extends object, Output extends object> {
|
117 | /**
|
118 | * @param next The handler to invoke after this middleware has operated on
|
119 | * the user input and before this middleware operates on the output.
|
120 | *
|
121 | * @param context Invariant data and functions for use by the handler.
|
122 | */
|
123 | (next: FinalizeHandler<Input, Output>, context: HandlerExecutionContext): FinalizeHandler<Input, Output>;
|
124 | }
|
125 | export interface BuildMiddleware<Input extends object, Output extends object> {
|
126 | (next: BuildHandler<Input, Output>, context: HandlerExecutionContext): BuildHandler<Input, Output>;
|
127 | }
|
128 | export interface DeserializeMiddleware<Input extends object, Output extends object> {
|
129 | (next: DeserializeHandler<Input, Output>, context: HandlerExecutionContext): DeserializeHandler<Input, Output>;
|
130 | }
|
131 | export declare type MiddlewareType<Input extends object, Output extends object> = InitializeMiddleware<Input, Output> | SerializeMiddleware<Input, Output> | BuildMiddleware<Input, Output> | FinalizeRequestMiddleware<Input, Output> | DeserializeMiddleware<Input, Output>;
|
132 | /**
|
133 | * A factory function that creates the terminal handler atop which a middleware
|
134 | * stack sits.
|
135 | */
|
136 | export interface Terminalware {
|
137 | <Input extends object, Output extends object>(context: HandlerExecutionContext): DeserializeHandler<Input, Output>;
|
138 | }
|
139 | export declare type Step = "initialize" | "serialize" | "build" | "finalizeRequest" | "deserialize";
|
140 | export declare type Priority = "high" | "normal" | "low";
|
141 | export interface HandlerOptions {
|
142 | /**
|
143 | * Handlers are ordered using a "step" that describes the stage of command
|
144 | * execution at which the handler will be executed. The available steps are:
|
145 | *
|
146 | * - initialize: The input is being prepared. Examples of typical
|
147 | * initialization tasks include injecting default options computing
|
148 | * derived parameters.
|
149 | * - serialize: The input is complete and ready to be serialized. Examples
|
150 | * of typical serialization tasks include input validation and building
|
151 | * an HTTP request from user input.
|
152 | * - build: The input has been serialized into an HTTP request, but that
|
153 | * request may require further modification. Any request alterations
|
154 | * will be applied to all retries. Examples of typical build tasks
|
155 | * include injecting HTTP headers that describe a stable aspect of the
|
156 | * request, such as `Content-Length` or a body checksum.
|
157 | * - finalizeRequest: The request is being prepared to be sent over the wire. The
|
158 | * request in this stage should already be semantically complete and
|
159 | * should therefore only be altered as match the recipient's
|
160 | * expectations. Examples of typical finalization tasks include request
|
161 | * signing and injecting hop-by-hop headers.
|
162 | * - deserialize: The response has arrived, the middleware here will deserialize
|
163 | * the raw response object to structured response
|
164 | *
|
165 | * Unlike initialization and build handlers, which are executed once
|
166 | * per operation execution, finalization and deserialize handlers will be
|
167 | * executed foreach HTTP request sent.
|
168 | *
|
169 | * @default 'initialize'
|
170 | */
|
171 | step?: Step;
|
172 | /**
|
173 | * A list of strings to any that identify the general purpose or important
|
174 | * characteristics of a given handler.
|
175 | */
|
176 | tags?: Array<string>;
|
177 | /**
|
178 | * A unique name to refer to a middleware
|
179 | */
|
180 | name?: string;
|
181 | /**
|
182 | * A flag to override the existing middleware with the same name. Without
|
183 | * setting it, adding middleware with duplicated name will throw an exception.
|
184 | * @internal
|
185 | */
|
186 | override?: boolean;
|
187 | }
|
188 | export interface AbsoluteLocation {
|
189 | /**
|
190 | * By default middleware will be added to individual step in un-guaranteed order.
|
191 | * In the case that
|
192 | *
|
193 | * @default 'normal'
|
194 | */
|
195 | priority?: Priority;
|
196 | }
|
197 | export declare type Relation = "before" | "after";
|
198 | export interface RelativeLocation {
|
199 | /**
|
200 | * Specify the relation to be before or after a know middleware.
|
201 | */
|
202 | relation: Relation;
|
203 | /**
|
204 | * A known middleware name to indicate inserting middleware's location.
|
205 | */
|
206 | toMiddleware: string;
|
207 | }
|
208 | export declare type RelativeMiddlewareOptions = RelativeLocation & Omit<HandlerOptions, "step">;
|
209 | export interface InitializeHandlerOptions extends HandlerOptions {
|
210 | step?: "initialize";
|
211 | }
|
212 | export interface SerializeHandlerOptions extends HandlerOptions {
|
213 | step: "serialize";
|
214 | }
|
215 | export interface BuildHandlerOptions extends HandlerOptions {
|
216 | step: "build";
|
217 | }
|
218 | export interface FinalizeRequestHandlerOptions extends HandlerOptions {
|
219 | step: "finalizeRequest";
|
220 | }
|
221 | export interface DeserializeHandlerOptions extends HandlerOptions {
|
222 | step: "deserialize";
|
223 | }
|
224 | /**
|
225 | * A stack storing middleware. It can be resolved into a handler. It supports 2
|
226 | * approaches for adding middleware:
|
227 | * 1. Adding middleware to specific step with `add()`. The order of middleware
|
228 | * added into same step is determined by order of adding them. If one middleware
|
229 | * needs to be executed at the front of the step or at the end of step, set
|
230 | * `priority` options to `high` or `low`.
|
231 | * 2. Adding middleware to location relative to known middleware with `addRelativeTo()`.
|
232 | * This is useful when given middleware must be executed before or after specific
|
233 | * middleware(`toMiddleware`). You can add a middleware relatively to another
|
234 | * middleware which also added relatively. But eventually, this relative middleware
|
235 | * chain **must** be 'anchored' by a middleware that added using `add()` API
|
236 | * with absolute `step` and `priority`. This mothod will throw if specified
|
237 | * `toMiddleware` is not found.
|
238 | */
|
239 | export interface MiddlewareStack<Input extends object, Output extends object> extends Pluggable<Input, Output> {
|
240 | /**
|
241 | * Add middleware to the stack to be executed during the "initialize" step,
|
242 | * optionally specifying a priority, tags and name
|
243 | */
|
244 | add(middleware: InitializeMiddleware<Input, Output>, options?: InitializeHandlerOptions & AbsoluteLocation): void;
|
245 | /**
|
246 | * Add middleware to the stack to be executed during the "serialize" step,
|
247 | * optionally specifying a priority, tags and name
|
248 | */
|
249 | add(middleware: SerializeMiddleware<Input, Output>, options: SerializeHandlerOptions & AbsoluteLocation): void;
|
250 | /**
|
251 | * Add middleware to the stack to be executed during the "build" step,
|
252 | * optionally specifying a priority, tags and name
|
253 | */
|
254 | add(middleware: BuildMiddleware<Input, Output>, options: BuildHandlerOptions & AbsoluteLocation): void;
|
255 | /**
|
256 | * Add middleware to the stack to be executed during the "finalizeRequest" step,
|
257 | * optionally specifying a priority, tags and name
|
258 | */
|
259 | add(middleware: FinalizeRequestMiddleware<Input, Output>, options: FinalizeRequestHandlerOptions & AbsoluteLocation): void;
|
260 | /**
|
261 | * Add middleware to the stack to be executed during the "deserialize" step,
|
262 | * optionally specifying a priority, tags and name
|
263 | */
|
264 | add(middleware: DeserializeMiddleware<Input, Output>, options: DeserializeHandlerOptions & AbsoluteLocation): void;
|
265 | /**
|
266 | * Add middleware to a stack position before or after a known middleware,optionally
|
267 | * specifying name and tags.
|
268 | */
|
269 | addRelativeTo(middleware: MiddlewareType<Input, Output>, options: RelativeMiddlewareOptions): void;
|
270 | /**
|
271 | * Apply a customization function to mutate the middleware stack, often
|
272 | * used for customizations that requires mutating multiple middleware.
|
273 | */
|
274 | use(pluggable: Pluggable<Input, Output>): void;
|
275 | /**
|
276 | * Create a shallow clone of this stack. Step bindings and handler priorities
|
277 | * and tags are preserved in the copy.
|
278 | */
|
279 | clone(): MiddlewareStack<Input, Output>;
|
280 | /**
|
281 | * Removes middleware from the stack.
|
282 | *
|
283 | * If a string is provided, it will be treated as middleware name. If a middleware
|
284 | * is inserted with the given name, it will be removed.
|
285 | *
|
286 | * If a middleware class is provided, all usages thereof will be removed.
|
287 | */
|
288 | remove(toRemove: MiddlewareType<Input, Output> | string): boolean;
|
289 | /**
|
290 | * Removes middleware that contains given tag
|
291 | *
|
292 | * Multiple middleware will potentially be removed
|
293 | */
|
294 | removeByTag(toRemove: string): boolean;
|
295 | /**
|
296 | * Create a stack containing the middlewares in this stack as well as the
|
297 | * middlewares in the `from` stack. Neither source is modified, and step
|
298 | * bindings and handler priorities and tags are preserved in the copy.
|
299 | */
|
300 | concat<InputType extends Input, OutputType extends Output>(from: MiddlewareStack<InputType, OutputType>): MiddlewareStack<InputType, OutputType>;
|
301 | /**
|
302 | * Builds a single handler function from zero or more middleware classes and
|
303 | * a core handler. The core handler is meant to send command objects to AWS
|
304 | * services and return promises that will resolve with the operation result
|
305 | * or be rejected with an error.
|
306 | *
|
307 | * When a composed handler is invoked, the arguments will pass through all
|
308 | * middleware in a defined order, and the return from the innermost handler
|
309 | * will pass through all middleware in the reverse of that order.
|
310 | */
|
311 | resolve<InputType extends Input, OutputType extends Output>(handler: DeserializeHandler<InputType, OutputType>, context: HandlerExecutionContext): InitializeHandler<InputType, OutputType>;
|
312 | }
|
313 | /**
|
314 | * Data and helper objects that are not expected to change from one execution of
|
315 | * a composed handler to another.
|
316 | */
|
317 | export interface HandlerExecutionContext {
|
318 | /**
|
319 | * A logger that may be invoked by any handler during execution of an
|
320 | * operation.
|
321 | */
|
322 | logger?: Logger;
|
323 | /**
|
324 | * Additional user agent that inferred by middleware. It can be used to save
|
325 | * the internal user agent sections without overriding the `customUserAgent`
|
326 | * config in clients.
|
327 | */
|
328 | userAgent?: UserAgent;
|
329 | [key: string]: any;
|
330 | }
|
331 | export interface Pluggable<Input extends object, Output extends object> {
|
332 | /**
|
333 | * A function that mutate the passed in middleware stack. Functions implementing
|
334 | * this interface can add, remove, modify existing middleware stack from clients
|
335 | * or commands
|
336 | */
|
337 | applyToStack: (stack: MiddlewareStack<Input, Output>) => void;
|
338 | }
|