create-mastra 0.1.0-alpha.23 → 0.1.0-alpha.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +44 -0
- package/dist/AssumeRoleCommand-Cse3dzcY.js +3650 -0
- package/dist/AssumeRoleCommand-Cse3dzcY.js.map +1 -0
- package/dist/create-aggregated-client-BFp7oxSr.js +24 -0
- package/dist/create-aggregated-client-BFp7oxSr.js.map +1 -0
- package/dist/extended-encode-uri-component-Dlbpb2Wd.js +8 -0
- package/dist/extended-encode-uri-component-Dlbpb2Wd.js.map +1 -0
- package/dist/index-B6QXpY-b.js +37 -0
- package/dist/index-B6QXpY-b.js.map +1 -0
- package/dist/index-BRCgFUbU.js +37 -0
- package/dist/index-BRCgFUbU.js.map +1 -0
- package/dist/index-BZHBFaQF.js +37 -0
- package/dist/index-BZHBFaQF.js.map +1 -0
- package/dist/index-B_Yunpbk.js +37 -0
- package/dist/index-B_Yunpbk.js.map +1 -0
- package/dist/index-BpMCSgn8.js +1145 -0
- package/dist/index-BpMCSgn8.js.map +1 -0
- package/dist/index-BxJx8yLU.js +37 -0
- package/dist/index-BxJx8yLU.js.map +1 -0
- package/dist/index-CF0rZfmW.js +37 -0
- package/dist/index-CF0rZfmW.js.map +1 -0
- package/dist/index-DeZeG5u4.js +3726 -0
- package/dist/index-DeZeG5u4.js.map +1 -0
- package/dist/index-_YTyVz_X.js +298 -0
- package/dist/index-_YTyVz_X.js.map +1 -0
- package/dist/index-lqkrgSwk.js +37 -0
- package/dist/index-lqkrgSwk.js.map +1 -0
- package/dist/index.js +152931 -39
- package/dist/index.js.map +1 -0
- package/dist/loadCognitoIdentity-CWxGlq_8.js +828 -0
- package/dist/loadCognitoIdentity-CWxGlq_8.js.map +1 -0
- package/dist/loadSso-MEAVww3h.js +615 -0
- package/dist/loadSso-MEAVww3h.js.map +1 -0
- package/dist/loadSts-DEnlAvEU.js +40 -0
- package/dist/loadSts-DEnlAvEU.js.map +1 -0
- package/dist/parseJsonBody-C_mcRkFo.js +161 -0
- package/dist/parseJsonBody-C_mcRkFo.js.map +1 -0
- package/dist/requestBuilder-CuNXirlx.js +90 -0
- package/dist/requestBuilder-CuNXirlx.js.map +1 -0
- package/package.json +16 -5
- package/starter-files/config.ts +28 -0
- package/starter-files/mastra-pg.docker-compose.yaml +15 -0
- package/starter-files/tools.ts +95 -0
- package/starter-files/workflow.ts +173 -0
- package/dist/index.d.ts +0 -2
- package/dist/utils.d.ts +0 -1
- package/dist/utils.js +0 -11
|
@@ -0,0 +1,3726 @@
|
|
|
1
|
+
import { H as HttpRequest, T as fromString, B as fromUtf8, z as toBase64, C as toUtf8, U as EndpointURLScheme, V as HttpResponse, W as toHex, X as escapeUri, Y as isArrayBuffer, Z as fromHex, y as setCredentialFeature, _ as AlgorithmId, $ as CONFIG_PREFIX_SEPARATOR, G as loadConfig, A as parseUrl, a0 as fromArrayBuffer, a1 as memoize } from './index.js';
|
|
2
|
+
import { Buffer as Buffer$1 } from 'node:buffer';
|
|
3
|
+
import { Readable } from 'node:stream';
|
|
4
|
+
import crypto, { createHmac, createHash } from 'node:crypto';
|
|
5
|
+
import { platform, release } from 'node:os';
|
|
6
|
+
import { versions, env } from 'node:process';
|
|
7
|
+
import { lstatSync, fstatSync } from 'node:fs';
|
|
8
|
+
|
|
9
|
+
const getHttpHandlerExtensionConfiguration = (runtimeConfig) => {
|
|
10
|
+
let httpHandler = runtimeConfig.httpHandler;
|
|
11
|
+
return {
|
|
12
|
+
setHttpHandler(handler) {
|
|
13
|
+
httpHandler = handler;
|
|
14
|
+
},
|
|
15
|
+
httpHandler() {
|
|
16
|
+
return httpHandler;
|
|
17
|
+
},
|
|
18
|
+
updateHttpClientConfig(key, value) {
|
|
19
|
+
httpHandler.updateHttpClientConfig(key, value);
|
|
20
|
+
},
|
|
21
|
+
httpHandlerConfigs() {
|
|
22
|
+
return httpHandler.httpHandlerConfigs();
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
const resolveHttpHandlerRuntimeConfig = (httpHandlerExtensionConfiguration) => {
|
|
27
|
+
return {
|
|
28
|
+
httpHandler: httpHandlerExtensionConfiguration.httpHandler(),
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const SMITHY_CONTEXT_KEY = "__smithy_context";
|
|
33
|
+
|
|
34
|
+
function resolveHostHeaderConfig(input) {
|
|
35
|
+
return input;
|
|
36
|
+
}
|
|
37
|
+
const hostHeaderMiddleware = (options) => (next) => async (args) => {
|
|
38
|
+
if (!HttpRequest.isInstance(args.request))
|
|
39
|
+
return next(args);
|
|
40
|
+
const { request } = args;
|
|
41
|
+
const { handlerProtocol = "" } = options.requestHandler.metadata || {};
|
|
42
|
+
if (handlerProtocol.indexOf("h2") >= 0 && !request.headers[":authority"]) {
|
|
43
|
+
delete request.headers["host"];
|
|
44
|
+
request.headers[":authority"] = request.hostname + (request.port ? ":" + request.port : "");
|
|
45
|
+
}
|
|
46
|
+
else if (!request.headers["host"]) {
|
|
47
|
+
let host = request.hostname;
|
|
48
|
+
if (request.port != null)
|
|
49
|
+
host += `:${request.port}`;
|
|
50
|
+
request.headers["host"] = host;
|
|
51
|
+
}
|
|
52
|
+
return next(args);
|
|
53
|
+
};
|
|
54
|
+
const hostHeaderMiddlewareOptions = {
|
|
55
|
+
name: "hostHeaderMiddleware",
|
|
56
|
+
step: "build",
|
|
57
|
+
priority: "low",
|
|
58
|
+
tags: ["HOST"],
|
|
59
|
+
override: true,
|
|
60
|
+
};
|
|
61
|
+
const getHostHeaderPlugin = (options) => ({
|
|
62
|
+
applyToStack: (clientStack) => {
|
|
63
|
+
clientStack.add(hostHeaderMiddleware(options), hostHeaderMiddlewareOptions);
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const loggerMiddleware = () => (next, context) => async (args) => {
|
|
68
|
+
try {
|
|
69
|
+
const response = await next(args);
|
|
70
|
+
const { clientName, commandName, logger, dynamoDbDocumentClientOptions = {} } = context;
|
|
71
|
+
const { overrideInputFilterSensitiveLog, overrideOutputFilterSensitiveLog } = dynamoDbDocumentClientOptions;
|
|
72
|
+
const inputFilterSensitiveLog = overrideInputFilterSensitiveLog ?? context.inputFilterSensitiveLog;
|
|
73
|
+
const outputFilterSensitiveLog = overrideOutputFilterSensitiveLog ?? context.outputFilterSensitiveLog;
|
|
74
|
+
const { $metadata, ...outputWithoutMetadata } = response.output;
|
|
75
|
+
logger?.info?.({
|
|
76
|
+
clientName,
|
|
77
|
+
commandName,
|
|
78
|
+
input: inputFilterSensitiveLog(args.input),
|
|
79
|
+
output: outputFilterSensitiveLog(outputWithoutMetadata),
|
|
80
|
+
metadata: $metadata,
|
|
81
|
+
});
|
|
82
|
+
return response;
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
const { clientName, commandName, logger, dynamoDbDocumentClientOptions = {} } = context;
|
|
86
|
+
const { overrideInputFilterSensitiveLog } = dynamoDbDocumentClientOptions;
|
|
87
|
+
const inputFilterSensitiveLog = overrideInputFilterSensitiveLog ?? context.inputFilterSensitiveLog;
|
|
88
|
+
logger?.error?.({
|
|
89
|
+
clientName,
|
|
90
|
+
commandName,
|
|
91
|
+
input: inputFilterSensitiveLog(args.input),
|
|
92
|
+
error,
|
|
93
|
+
metadata: error.$metadata,
|
|
94
|
+
});
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const loggerMiddlewareOptions = {
|
|
99
|
+
name: "loggerMiddleware",
|
|
100
|
+
tags: ["LOGGER"],
|
|
101
|
+
step: "initialize",
|
|
102
|
+
override: true,
|
|
103
|
+
};
|
|
104
|
+
const getLoggerPlugin = (options) => ({
|
|
105
|
+
applyToStack: (clientStack) => {
|
|
106
|
+
clientStack.add(loggerMiddleware(), loggerMiddlewareOptions);
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const TRACE_ID_HEADER_NAME = "X-Amzn-Trace-Id";
|
|
111
|
+
const ENV_LAMBDA_FUNCTION_NAME = "AWS_LAMBDA_FUNCTION_NAME";
|
|
112
|
+
const ENV_TRACE_ID = "_X_AMZN_TRACE_ID";
|
|
113
|
+
const recursionDetectionMiddleware = (options) => (next) => async (args) => {
|
|
114
|
+
const { request } = args;
|
|
115
|
+
if (!HttpRequest.isInstance(request) ||
|
|
116
|
+
options.runtime !== "node" ||
|
|
117
|
+
request.headers.hasOwnProperty(TRACE_ID_HEADER_NAME)) {
|
|
118
|
+
return next(args);
|
|
119
|
+
}
|
|
120
|
+
const functionName = process.env[ENV_LAMBDA_FUNCTION_NAME];
|
|
121
|
+
const traceId = process.env[ENV_TRACE_ID];
|
|
122
|
+
const nonEmptyString = (str) => typeof str === "string" && str.length > 0;
|
|
123
|
+
if (nonEmptyString(functionName) && nonEmptyString(traceId)) {
|
|
124
|
+
request.headers[TRACE_ID_HEADER_NAME] = traceId;
|
|
125
|
+
}
|
|
126
|
+
return next({
|
|
127
|
+
...args,
|
|
128
|
+
request,
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
const addRecursionDetectionMiddlewareOptions = {
|
|
132
|
+
step: "build",
|
|
133
|
+
tags: ["RECURSION_DETECTION"],
|
|
134
|
+
name: "recursionDetectionMiddleware",
|
|
135
|
+
override: true,
|
|
136
|
+
priority: "low",
|
|
137
|
+
};
|
|
138
|
+
const getRecursionDetectionPlugin = (options) => ({
|
|
139
|
+
applyToStack: (clientStack) => {
|
|
140
|
+
clientStack.add(recursionDetectionMiddleware(options), addRecursionDetectionMiddlewareOptions);
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const getSmithyContext = (context) => context[SMITHY_CONTEXT_KEY] || (context[SMITHY_CONTEXT_KEY] = {});
|
|
145
|
+
|
|
146
|
+
const normalizeProvider$1 = (input) => {
|
|
147
|
+
if (typeof input === "function")
|
|
148
|
+
return input;
|
|
149
|
+
const promisified = Promise.resolve(input);
|
|
150
|
+
return () => promisified;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
function convertHttpAuthSchemesToMap(httpAuthSchemes) {
|
|
154
|
+
const map = new Map();
|
|
155
|
+
for (const scheme of httpAuthSchemes) {
|
|
156
|
+
map.set(scheme.schemeId, scheme);
|
|
157
|
+
}
|
|
158
|
+
return map;
|
|
159
|
+
}
|
|
160
|
+
const httpAuthSchemeMiddleware = (config, mwOptions) => (next, context) => async (args) => {
|
|
161
|
+
const options = config.httpAuthSchemeProvider(await mwOptions.httpAuthSchemeParametersProvider(config, context, args.input));
|
|
162
|
+
const authSchemes = convertHttpAuthSchemesToMap(config.httpAuthSchemes);
|
|
163
|
+
const smithyContext = getSmithyContext(context);
|
|
164
|
+
const failureReasons = [];
|
|
165
|
+
for (const option of options) {
|
|
166
|
+
const scheme = authSchemes.get(option.schemeId);
|
|
167
|
+
if (!scheme) {
|
|
168
|
+
failureReasons.push(`HttpAuthScheme \`${option.schemeId}\` was not enabled for this service.`);
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
const identityProvider = scheme.identityProvider(await mwOptions.identityProviderConfigProvider(config));
|
|
172
|
+
if (!identityProvider) {
|
|
173
|
+
failureReasons.push(`HttpAuthScheme \`${option.schemeId}\` did not have an IdentityProvider configured.`);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
const { identityProperties = {}, signingProperties = {} } = option.propertiesExtractor?.(config, context) || {};
|
|
177
|
+
option.identityProperties = Object.assign(option.identityProperties || {}, identityProperties);
|
|
178
|
+
option.signingProperties = Object.assign(option.signingProperties || {}, signingProperties);
|
|
179
|
+
smithyContext.selectedHttpAuthScheme = {
|
|
180
|
+
httpAuthOption: option,
|
|
181
|
+
identity: await identityProvider(option.identityProperties),
|
|
182
|
+
signer: scheme.signer,
|
|
183
|
+
};
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
if (!smithyContext.selectedHttpAuthScheme) {
|
|
187
|
+
throw new Error(failureReasons.join("\n"));
|
|
188
|
+
}
|
|
189
|
+
return next(args);
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const httpAuthSchemeEndpointRuleSetMiddlewareOptions = {
|
|
193
|
+
step: "serialize",
|
|
194
|
+
tags: ["HTTP_AUTH_SCHEME"],
|
|
195
|
+
name: "httpAuthSchemeMiddleware",
|
|
196
|
+
override: true,
|
|
197
|
+
relation: "before",
|
|
198
|
+
toMiddleware: "endpointV2Middleware",
|
|
199
|
+
};
|
|
200
|
+
const getHttpAuthSchemeEndpointRuleSetPlugin = (config, { httpAuthSchemeParametersProvider, identityProviderConfigProvider, }) => ({
|
|
201
|
+
applyToStack: (clientStack) => {
|
|
202
|
+
clientStack.addRelativeTo(httpAuthSchemeMiddleware(config, {
|
|
203
|
+
httpAuthSchemeParametersProvider,
|
|
204
|
+
identityProviderConfigProvider,
|
|
205
|
+
}), httpAuthSchemeEndpointRuleSetMiddlewareOptions);
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
const deserializerMiddleware = (options, deserializer) => (next) => async (args) => {
|
|
210
|
+
const { response } = await next(args);
|
|
211
|
+
try {
|
|
212
|
+
const parsed = await deserializer(response, options);
|
|
213
|
+
return {
|
|
214
|
+
response,
|
|
215
|
+
output: parsed,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
Object.defineProperty(error, "$response", {
|
|
220
|
+
value: response,
|
|
221
|
+
});
|
|
222
|
+
if (!("$metadata" in error)) {
|
|
223
|
+
const hint = `Deserialization error: to see the raw response, inspect the hidden field {error}.$response on this object.`;
|
|
224
|
+
error.message += "\n " + hint;
|
|
225
|
+
if (typeof error.$responseBodyText !== "undefined") {
|
|
226
|
+
if (error.$response) {
|
|
227
|
+
error.$response.body = error.$responseBodyText;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
throw error;
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
const serializerMiddleware = (options, serializer) => (next, context) => async (args) => {
|
|
236
|
+
const endpoint = context.endpointV2?.url && options.urlParser
|
|
237
|
+
? async () => options.urlParser(context.endpointV2.url)
|
|
238
|
+
: options.endpoint;
|
|
239
|
+
if (!endpoint) {
|
|
240
|
+
throw new Error("No valid endpoint provider available.");
|
|
241
|
+
}
|
|
242
|
+
const request = await serializer(args.input, { ...options, endpoint });
|
|
243
|
+
return next({
|
|
244
|
+
...args,
|
|
245
|
+
request,
|
|
246
|
+
});
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const deserializerMiddlewareOption = {
|
|
250
|
+
name: "deserializerMiddleware",
|
|
251
|
+
step: "deserialize",
|
|
252
|
+
tags: ["DESERIALIZER"],
|
|
253
|
+
override: true,
|
|
254
|
+
};
|
|
255
|
+
const serializerMiddlewareOption = {
|
|
256
|
+
name: "serializerMiddleware",
|
|
257
|
+
step: "serialize",
|
|
258
|
+
tags: ["SERIALIZER"],
|
|
259
|
+
override: true,
|
|
260
|
+
};
|
|
261
|
+
function getSerdePlugin(config, serializer, deserializer) {
|
|
262
|
+
return {
|
|
263
|
+
applyToStack: (commandStack) => {
|
|
264
|
+
commandStack.add(deserializerMiddleware(config, deserializer), deserializerMiddlewareOption);
|
|
265
|
+
commandStack.add(serializerMiddleware(config, serializer), serializerMiddlewareOption);
|
|
266
|
+
},
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
({
|
|
271
|
+
step: "serialize",
|
|
272
|
+
tags: ["HTTP_AUTH_SCHEME"],
|
|
273
|
+
name: "httpAuthSchemeMiddleware",
|
|
274
|
+
override: true,
|
|
275
|
+
relation: "before",
|
|
276
|
+
toMiddleware: serializerMiddlewareOption.name,
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
const defaultErrorHandler = (signingProperties) => (error) => {
|
|
280
|
+
throw error;
|
|
281
|
+
};
|
|
282
|
+
const defaultSuccessHandler = (httpResponse, signingProperties) => { };
|
|
283
|
+
const httpSigningMiddleware = (config) => (next, context) => async (args) => {
|
|
284
|
+
if (!HttpRequest.isInstance(args.request)) {
|
|
285
|
+
return next(args);
|
|
286
|
+
}
|
|
287
|
+
const smithyContext = getSmithyContext(context);
|
|
288
|
+
const scheme = smithyContext.selectedHttpAuthScheme;
|
|
289
|
+
if (!scheme) {
|
|
290
|
+
throw new Error(`No HttpAuthScheme was selected: unable to sign request`);
|
|
291
|
+
}
|
|
292
|
+
const { httpAuthOption: { signingProperties = {} }, identity, signer, } = scheme;
|
|
293
|
+
const output = await next({
|
|
294
|
+
...args,
|
|
295
|
+
request: await signer.sign(args.request, identity, signingProperties),
|
|
296
|
+
}).catch((signer.errorHandler || defaultErrorHandler)(signingProperties));
|
|
297
|
+
(signer.successHandler || defaultSuccessHandler)(output.response, signingProperties);
|
|
298
|
+
return output;
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
const httpSigningMiddlewareOptions = {
|
|
302
|
+
step: "finalizeRequest",
|
|
303
|
+
tags: ["HTTP_SIGNING"],
|
|
304
|
+
name: "httpSigningMiddleware",
|
|
305
|
+
aliases: ["apiKeyMiddleware", "tokenMiddleware", "awsAuthMiddleware"],
|
|
306
|
+
override: true,
|
|
307
|
+
relation: "after",
|
|
308
|
+
toMiddleware: "retryMiddleware",
|
|
309
|
+
};
|
|
310
|
+
const getHttpSigningPlugin = (config) => ({
|
|
311
|
+
applyToStack: (clientStack) => {
|
|
312
|
+
clientStack.addRelativeTo(httpSigningMiddleware(), httpSigningMiddlewareOptions);
|
|
313
|
+
},
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
const normalizeProvider = (input) => {
|
|
317
|
+
if (typeof input === "function")
|
|
318
|
+
return input;
|
|
319
|
+
const promisified = Promise.resolve(input);
|
|
320
|
+
return () => promisified;
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
const BASE64_REGEX = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
324
|
+
const fromBase64 = (input) => {
|
|
325
|
+
if ((input.length * 3) % 4 !== 0) {
|
|
326
|
+
throw new TypeError(`Incorrect padding on base64 string.`);
|
|
327
|
+
}
|
|
328
|
+
if (!BASE64_REGEX.exec(input)) {
|
|
329
|
+
throw new TypeError(`Invalid base64 string.`);
|
|
330
|
+
}
|
|
331
|
+
const buffer = fromString(input, "base64");
|
|
332
|
+
return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
const toUint8Array = (data) => {
|
|
336
|
+
if (typeof data === "string") {
|
|
337
|
+
return fromUtf8(data);
|
|
338
|
+
}
|
|
339
|
+
if (ArrayBuffer.isView(data)) {
|
|
340
|
+
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength / Uint8Array.BYTES_PER_ELEMENT);
|
|
341
|
+
}
|
|
342
|
+
return new Uint8Array(data);
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
function transformToString(payload, encoding = "utf-8") {
|
|
346
|
+
if (encoding === "base64") {
|
|
347
|
+
return toBase64(payload);
|
|
348
|
+
}
|
|
349
|
+
return toUtf8(payload);
|
|
350
|
+
}
|
|
351
|
+
function transformFromString(str, encoding) {
|
|
352
|
+
if (encoding === "base64") {
|
|
353
|
+
return Uint8ArrayBlobAdapter.mutate(fromBase64(str));
|
|
354
|
+
}
|
|
355
|
+
return Uint8ArrayBlobAdapter.mutate(fromUtf8(str));
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
class Uint8ArrayBlobAdapter extends Uint8Array {
|
|
359
|
+
static fromString(source, encoding = "utf-8") {
|
|
360
|
+
switch (typeof source) {
|
|
361
|
+
case "string":
|
|
362
|
+
return transformFromString(source, encoding);
|
|
363
|
+
default:
|
|
364
|
+
throw new Error(`Unsupported conversion from ${typeof source} to Uint8ArrayBlobAdapter.`);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
static mutate(source) {
|
|
368
|
+
Object.setPrototypeOf(source, Uint8ArrayBlobAdapter.prototype);
|
|
369
|
+
return source;
|
|
370
|
+
}
|
|
371
|
+
transformToString(encoding = "utf-8") {
|
|
372
|
+
return transformToString(this, encoding);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const collectBody = async (streamBody = new Uint8Array(), context) => {
|
|
377
|
+
if (streamBody instanceof Uint8Array) {
|
|
378
|
+
return Uint8ArrayBlobAdapter.mutate(streamBody);
|
|
379
|
+
}
|
|
380
|
+
if (!streamBody) {
|
|
381
|
+
return Uint8ArrayBlobAdapter.mutate(new Uint8Array());
|
|
382
|
+
}
|
|
383
|
+
const fromContext = context.streamCollector(streamBody);
|
|
384
|
+
return Uint8ArrayBlobAdapter.mutate(await fromContext);
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
function setFeature$1(context, feature, value) {
|
|
388
|
+
if (!context.__smithy_context) {
|
|
389
|
+
context.__smithy_context = {
|
|
390
|
+
features: {},
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
else if (!context.__smithy_context.features) {
|
|
394
|
+
context.__smithy_context.features = {};
|
|
395
|
+
}
|
|
396
|
+
context.__smithy_context.features[feature] = value;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
class DefaultIdentityProviderConfig {
|
|
400
|
+
constructor(config) {
|
|
401
|
+
this.authSchemes = new Map();
|
|
402
|
+
for (const [key, value] of Object.entries(config)) {
|
|
403
|
+
if (value !== undefined) {
|
|
404
|
+
this.authSchemes.set(key, value);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
getIdentityProvider(schemeId) {
|
|
409
|
+
return this.authSchemes.get(schemeId);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
class NoAuthSigner {
|
|
414
|
+
async sign(httpRequest, identity, signingProperties) {
|
|
415
|
+
return httpRequest;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const createIsIdentityExpiredFunction = (expirationMs) => (identity) => doesIdentityRequireRefresh(identity) && identity.expiration.getTime() - Date.now() < expirationMs;
|
|
420
|
+
const EXPIRATION_MS = 300000;
|
|
421
|
+
const isIdentityExpired = createIsIdentityExpiredFunction(EXPIRATION_MS);
|
|
422
|
+
const doesIdentityRequireRefresh = (identity) => identity.expiration !== undefined;
|
|
423
|
+
const memoizeIdentityProvider = (provider, isExpired, requiresRefresh) => {
|
|
424
|
+
if (provider === undefined) {
|
|
425
|
+
return undefined;
|
|
426
|
+
}
|
|
427
|
+
const normalizedProvider = typeof provider !== "function" ? async () => Promise.resolve(provider) : provider;
|
|
428
|
+
let resolved;
|
|
429
|
+
let pending;
|
|
430
|
+
let hasResult;
|
|
431
|
+
let isConstant = false;
|
|
432
|
+
const coalesceProvider = async (options) => {
|
|
433
|
+
if (!pending) {
|
|
434
|
+
pending = normalizedProvider(options);
|
|
435
|
+
}
|
|
436
|
+
try {
|
|
437
|
+
resolved = await pending;
|
|
438
|
+
hasResult = true;
|
|
439
|
+
isConstant = false;
|
|
440
|
+
}
|
|
441
|
+
finally {
|
|
442
|
+
pending = undefined;
|
|
443
|
+
}
|
|
444
|
+
return resolved;
|
|
445
|
+
};
|
|
446
|
+
if (isExpired === undefined) {
|
|
447
|
+
return async (options) => {
|
|
448
|
+
if (!hasResult || options?.forceRefresh) {
|
|
449
|
+
resolved = await coalesceProvider(options);
|
|
450
|
+
}
|
|
451
|
+
return resolved;
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
return async (options) => {
|
|
455
|
+
if (!hasResult || options?.forceRefresh) {
|
|
456
|
+
resolved = await coalesceProvider(options);
|
|
457
|
+
}
|
|
458
|
+
if (isConstant) {
|
|
459
|
+
return resolved;
|
|
460
|
+
}
|
|
461
|
+
if (!requiresRefresh(resolved)) {
|
|
462
|
+
isConstant = true;
|
|
463
|
+
return resolved;
|
|
464
|
+
}
|
|
465
|
+
if (isExpired(resolved)) {
|
|
466
|
+
await coalesceProvider(options);
|
|
467
|
+
return resolved;
|
|
468
|
+
}
|
|
469
|
+
return resolved;
|
|
470
|
+
};
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
const DEFAULT_UA_APP_ID = undefined;
|
|
474
|
+
function isValidUserAgentAppId(appId) {
|
|
475
|
+
if (appId === undefined) {
|
|
476
|
+
return true;
|
|
477
|
+
}
|
|
478
|
+
return typeof appId === "string" && appId.length <= 50;
|
|
479
|
+
}
|
|
480
|
+
function resolveUserAgentConfig(input) {
|
|
481
|
+
const normalizedAppIdProvider = normalizeProvider(input.userAgentAppId ?? DEFAULT_UA_APP_ID);
|
|
482
|
+
return {
|
|
483
|
+
...input,
|
|
484
|
+
customUserAgent: typeof input.customUserAgent === "string" ? [[input.customUserAgent]] : input.customUserAgent,
|
|
485
|
+
userAgentAppId: async () => {
|
|
486
|
+
const appId = await normalizedAppIdProvider();
|
|
487
|
+
if (!isValidUserAgentAppId(appId)) {
|
|
488
|
+
const logger = input.logger?.constructor?.name === "NoOpLogger" || !input.logger ? console : input.logger;
|
|
489
|
+
if (typeof appId !== "string") {
|
|
490
|
+
logger?.warn("userAgentAppId must be a string or undefined.");
|
|
491
|
+
}
|
|
492
|
+
else if (appId.length > 50) {
|
|
493
|
+
logger?.warn("The provided userAgentAppId exceeds the maximum length of 50 characters.");
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
return appId;
|
|
497
|
+
},
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
class EndpointCache {
|
|
502
|
+
constructor({ size, params }) {
|
|
503
|
+
this.data = new Map();
|
|
504
|
+
this.parameters = [];
|
|
505
|
+
this.capacity = size ?? 50;
|
|
506
|
+
if (params) {
|
|
507
|
+
this.parameters = params;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
get(endpointParams, resolver) {
|
|
511
|
+
const key = this.hash(endpointParams);
|
|
512
|
+
if (key === false) {
|
|
513
|
+
return resolver();
|
|
514
|
+
}
|
|
515
|
+
if (!this.data.has(key)) {
|
|
516
|
+
if (this.data.size > this.capacity + 10) {
|
|
517
|
+
const keys = this.data.keys();
|
|
518
|
+
let i = 0;
|
|
519
|
+
while (true) {
|
|
520
|
+
const { value, done } = keys.next();
|
|
521
|
+
this.data.delete(value);
|
|
522
|
+
if (done || ++i > 10) {
|
|
523
|
+
break;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
this.data.set(key, resolver());
|
|
528
|
+
}
|
|
529
|
+
return this.data.get(key);
|
|
530
|
+
}
|
|
531
|
+
size() {
|
|
532
|
+
return this.data.size;
|
|
533
|
+
}
|
|
534
|
+
hash(endpointParams) {
|
|
535
|
+
let buffer = "";
|
|
536
|
+
const { parameters } = this;
|
|
537
|
+
if (parameters.length === 0) {
|
|
538
|
+
return false;
|
|
539
|
+
}
|
|
540
|
+
for (const param of parameters) {
|
|
541
|
+
const val = String(endpointParams[param] ?? "");
|
|
542
|
+
if (val.includes("|;")) {
|
|
543
|
+
return false;
|
|
544
|
+
}
|
|
545
|
+
buffer += val + "|;";
|
|
546
|
+
}
|
|
547
|
+
return buffer;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
const IP_V4_REGEX = new RegExp(`^(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}$`);
|
|
552
|
+
const isIpAddress = (value) => IP_V4_REGEX.test(value) || (value.startsWith("[") && value.endsWith("]"));
|
|
553
|
+
|
|
554
|
+
const VALID_HOST_LABEL_REGEX = new RegExp(`^(?!.*-$)(?!-)[a-zA-Z0-9-]{1,63}$`);
|
|
555
|
+
const isValidHostLabel = (value, allowSubDomains = false) => {
|
|
556
|
+
if (!allowSubDomains) {
|
|
557
|
+
return VALID_HOST_LABEL_REGEX.test(value);
|
|
558
|
+
}
|
|
559
|
+
const labels = value.split(".");
|
|
560
|
+
for (const label of labels) {
|
|
561
|
+
if (!isValidHostLabel(label)) {
|
|
562
|
+
return false;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
return true;
|
|
566
|
+
};
|
|
567
|
+
|
|
568
|
+
const customEndpointFunctions = {};
|
|
569
|
+
|
|
570
|
+
const debugId = "endpoints";
|
|
571
|
+
|
|
572
|
+
function toDebugString(input) {
|
|
573
|
+
if (typeof input !== "object" || input == null) {
|
|
574
|
+
return input;
|
|
575
|
+
}
|
|
576
|
+
if ("ref" in input) {
|
|
577
|
+
return `$${toDebugString(input.ref)}`;
|
|
578
|
+
}
|
|
579
|
+
if ("fn" in input) {
|
|
580
|
+
return `${input.fn}(${(input.argv || []).map(toDebugString).join(", ")})`;
|
|
581
|
+
}
|
|
582
|
+
return JSON.stringify(input, null, 2);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
class EndpointError extends Error {
|
|
586
|
+
constructor(message) {
|
|
587
|
+
super(message);
|
|
588
|
+
this.name = "EndpointError";
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
const booleanEquals = (value1, value2) => value1 === value2;
|
|
593
|
+
|
|
594
|
+
const getAttrPathList = (path) => {
|
|
595
|
+
const parts = path.split(".");
|
|
596
|
+
const pathList = [];
|
|
597
|
+
for (const part of parts) {
|
|
598
|
+
const squareBracketIndex = part.indexOf("[");
|
|
599
|
+
if (squareBracketIndex !== -1) {
|
|
600
|
+
if (part.indexOf("]") !== part.length - 1) {
|
|
601
|
+
throw new EndpointError(`Path: '${path}' does not end with ']'`);
|
|
602
|
+
}
|
|
603
|
+
const arrayIndex = part.slice(squareBracketIndex + 1, -1);
|
|
604
|
+
if (Number.isNaN(parseInt(arrayIndex))) {
|
|
605
|
+
throw new EndpointError(`Invalid array index: '${arrayIndex}' in path: '${path}'`);
|
|
606
|
+
}
|
|
607
|
+
if (squareBracketIndex !== 0) {
|
|
608
|
+
pathList.push(part.slice(0, squareBracketIndex));
|
|
609
|
+
}
|
|
610
|
+
pathList.push(arrayIndex);
|
|
611
|
+
}
|
|
612
|
+
else {
|
|
613
|
+
pathList.push(part);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
return pathList;
|
|
617
|
+
};
|
|
618
|
+
|
|
619
|
+
const getAttr = (value, path) => getAttrPathList(path).reduce((acc, index) => {
|
|
620
|
+
if (typeof acc !== "object") {
|
|
621
|
+
throw new EndpointError(`Index '${index}' in '${path}' not found in '${JSON.stringify(value)}'`);
|
|
622
|
+
}
|
|
623
|
+
else if (Array.isArray(acc)) {
|
|
624
|
+
return acc[parseInt(index)];
|
|
625
|
+
}
|
|
626
|
+
return acc[index];
|
|
627
|
+
}, value);
|
|
628
|
+
|
|
629
|
+
const isSet = (value) => value != null;
|
|
630
|
+
|
|
631
|
+
const not = (value) => !value;
|
|
632
|
+
|
|
633
|
+
const DEFAULT_PORTS = {
|
|
634
|
+
[EndpointURLScheme.HTTP]: 80,
|
|
635
|
+
[EndpointURLScheme.HTTPS]: 443,
|
|
636
|
+
};
|
|
637
|
+
const parseURL = (value) => {
|
|
638
|
+
const whatwgURL = (() => {
|
|
639
|
+
try {
|
|
640
|
+
if (value instanceof URL) {
|
|
641
|
+
return value;
|
|
642
|
+
}
|
|
643
|
+
if (typeof value === "object" && "hostname" in value) {
|
|
644
|
+
const { hostname, port, protocol = "", path = "", query = {} } = value;
|
|
645
|
+
const url = new URL(`${protocol}//${hostname}${port ? `:${port}` : ""}${path}`);
|
|
646
|
+
url.search = Object.entries(query)
|
|
647
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
648
|
+
.join("&");
|
|
649
|
+
return url;
|
|
650
|
+
}
|
|
651
|
+
return new URL(value);
|
|
652
|
+
}
|
|
653
|
+
catch (error) {
|
|
654
|
+
return null;
|
|
655
|
+
}
|
|
656
|
+
})();
|
|
657
|
+
if (!whatwgURL) {
|
|
658
|
+
console.error(`Unable to parse ${JSON.stringify(value)} as a whatwg URL.`);
|
|
659
|
+
return null;
|
|
660
|
+
}
|
|
661
|
+
const urlString = whatwgURL.href;
|
|
662
|
+
const { host, hostname, pathname, protocol, search } = whatwgURL;
|
|
663
|
+
if (search) {
|
|
664
|
+
return null;
|
|
665
|
+
}
|
|
666
|
+
const scheme = protocol.slice(0, -1);
|
|
667
|
+
if (!Object.values(EndpointURLScheme).includes(scheme)) {
|
|
668
|
+
return null;
|
|
669
|
+
}
|
|
670
|
+
const isIp = isIpAddress(hostname);
|
|
671
|
+
const inputContainsDefaultPort = urlString.includes(`${host}:${DEFAULT_PORTS[scheme]}`) ||
|
|
672
|
+
(typeof value === "string" && value.includes(`${host}:${DEFAULT_PORTS[scheme]}`));
|
|
673
|
+
const authority = `${host}${inputContainsDefaultPort ? `:${DEFAULT_PORTS[scheme]}` : ``}`;
|
|
674
|
+
return {
|
|
675
|
+
scheme,
|
|
676
|
+
authority,
|
|
677
|
+
path: pathname,
|
|
678
|
+
normalizedPath: pathname.endsWith("/") ? pathname : `${pathname}/`,
|
|
679
|
+
isIp,
|
|
680
|
+
};
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
const stringEquals = (value1, value2) => value1 === value2;
|
|
684
|
+
|
|
685
|
+
const substring = (input, start, stop, reverse) => {
|
|
686
|
+
if (start >= stop || input.length < stop) {
|
|
687
|
+
return null;
|
|
688
|
+
}
|
|
689
|
+
if (!reverse) {
|
|
690
|
+
return input.substring(start, stop);
|
|
691
|
+
}
|
|
692
|
+
return input.substring(input.length - stop, input.length - start);
|
|
693
|
+
};
|
|
694
|
+
|
|
695
|
+
const uriEncode = (value) => encodeURIComponent(value).replace(/[!*'()]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
696
|
+
|
|
697
|
+
const endpointFunctions = {
|
|
698
|
+
booleanEquals,
|
|
699
|
+
getAttr,
|
|
700
|
+
isSet,
|
|
701
|
+
isValidHostLabel,
|
|
702
|
+
not,
|
|
703
|
+
parseURL,
|
|
704
|
+
stringEquals,
|
|
705
|
+
substring,
|
|
706
|
+
uriEncode,
|
|
707
|
+
};
|
|
708
|
+
|
|
709
|
+
const evaluateTemplate = (template, options) => {
|
|
710
|
+
const evaluatedTemplateArr = [];
|
|
711
|
+
const templateContext = {
|
|
712
|
+
...options.endpointParams,
|
|
713
|
+
...options.referenceRecord,
|
|
714
|
+
};
|
|
715
|
+
let currentIndex = 0;
|
|
716
|
+
while (currentIndex < template.length) {
|
|
717
|
+
const openingBraceIndex = template.indexOf("{", currentIndex);
|
|
718
|
+
if (openingBraceIndex === -1) {
|
|
719
|
+
evaluatedTemplateArr.push(template.slice(currentIndex));
|
|
720
|
+
break;
|
|
721
|
+
}
|
|
722
|
+
evaluatedTemplateArr.push(template.slice(currentIndex, openingBraceIndex));
|
|
723
|
+
const closingBraceIndex = template.indexOf("}", openingBraceIndex);
|
|
724
|
+
if (closingBraceIndex === -1) {
|
|
725
|
+
evaluatedTemplateArr.push(template.slice(openingBraceIndex));
|
|
726
|
+
break;
|
|
727
|
+
}
|
|
728
|
+
if (template[openingBraceIndex + 1] === "{" && template[closingBraceIndex + 1] === "}") {
|
|
729
|
+
evaluatedTemplateArr.push(template.slice(openingBraceIndex + 1, closingBraceIndex));
|
|
730
|
+
currentIndex = closingBraceIndex + 2;
|
|
731
|
+
}
|
|
732
|
+
const parameterName = template.substring(openingBraceIndex + 1, closingBraceIndex);
|
|
733
|
+
if (parameterName.includes("#")) {
|
|
734
|
+
const [refName, attrName] = parameterName.split("#");
|
|
735
|
+
evaluatedTemplateArr.push(getAttr(templateContext[refName], attrName));
|
|
736
|
+
}
|
|
737
|
+
else {
|
|
738
|
+
evaluatedTemplateArr.push(templateContext[parameterName]);
|
|
739
|
+
}
|
|
740
|
+
currentIndex = closingBraceIndex + 1;
|
|
741
|
+
}
|
|
742
|
+
return evaluatedTemplateArr.join("");
|
|
743
|
+
};
|
|
744
|
+
|
|
745
|
+
const getReferenceValue = ({ ref }, options) => {
|
|
746
|
+
const referenceRecord = {
|
|
747
|
+
...options.endpointParams,
|
|
748
|
+
...options.referenceRecord,
|
|
749
|
+
};
|
|
750
|
+
return referenceRecord[ref];
|
|
751
|
+
};
|
|
752
|
+
|
|
753
|
+
const evaluateExpression = (obj, keyName, options) => {
|
|
754
|
+
if (typeof obj === "string") {
|
|
755
|
+
return evaluateTemplate(obj, options);
|
|
756
|
+
}
|
|
757
|
+
else if (obj["fn"]) {
|
|
758
|
+
return callFunction(obj, options);
|
|
759
|
+
}
|
|
760
|
+
else if (obj["ref"]) {
|
|
761
|
+
return getReferenceValue(obj, options);
|
|
762
|
+
}
|
|
763
|
+
throw new EndpointError(`'${keyName}': ${String(obj)} is not a string, function or reference.`);
|
|
764
|
+
};
|
|
765
|
+
|
|
766
|
+
const callFunction = ({ fn, argv }, options) => {
|
|
767
|
+
const evaluatedArgs = argv.map((arg) => ["boolean", "number"].includes(typeof arg) ? arg : evaluateExpression(arg, "arg", options));
|
|
768
|
+
const fnSegments = fn.split(".");
|
|
769
|
+
if (fnSegments[0] in customEndpointFunctions && fnSegments[1] != null) {
|
|
770
|
+
return customEndpointFunctions[fnSegments[0]][fnSegments[1]](...evaluatedArgs);
|
|
771
|
+
}
|
|
772
|
+
return endpointFunctions[fn](...evaluatedArgs);
|
|
773
|
+
};
|
|
774
|
+
|
|
775
|
+
const evaluateCondition = ({ assign, ...fnArgs }, options) => {
|
|
776
|
+
if (assign && assign in options.referenceRecord) {
|
|
777
|
+
throw new EndpointError(`'${assign}' is already defined in Reference Record.`);
|
|
778
|
+
}
|
|
779
|
+
const value = callFunction(fnArgs, options);
|
|
780
|
+
options.logger?.debug?.(`${debugId} evaluateCondition: ${toDebugString(fnArgs)} = ${toDebugString(value)}`);
|
|
781
|
+
return {
|
|
782
|
+
result: value === "" ? true : !!value,
|
|
783
|
+
...(assign != null && { toAssign: { name: assign, value } }),
|
|
784
|
+
};
|
|
785
|
+
};
|
|
786
|
+
|
|
787
|
+
const evaluateConditions = (conditions = [], options) => {
|
|
788
|
+
const conditionsReferenceRecord = {};
|
|
789
|
+
for (const condition of conditions) {
|
|
790
|
+
const { result, toAssign } = evaluateCondition(condition, {
|
|
791
|
+
...options,
|
|
792
|
+
referenceRecord: {
|
|
793
|
+
...options.referenceRecord,
|
|
794
|
+
...conditionsReferenceRecord,
|
|
795
|
+
},
|
|
796
|
+
});
|
|
797
|
+
if (!result) {
|
|
798
|
+
return { result };
|
|
799
|
+
}
|
|
800
|
+
if (toAssign) {
|
|
801
|
+
conditionsReferenceRecord[toAssign.name] = toAssign.value;
|
|
802
|
+
options.logger?.debug?.(`${debugId} assign: ${toAssign.name} := ${toDebugString(toAssign.value)}`);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
return { result: true, referenceRecord: conditionsReferenceRecord };
|
|
806
|
+
};
|
|
807
|
+
|
|
808
|
+
const getEndpointHeaders = (headers, options) => Object.entries(headers).reduce((acc, [headerKey, headerVal]) => ({
|
|
809
|
+
...acc,
|
|
810
|
+
[headerKey]: headerVal.map((headerValEntry) => {
|
|
811
|
+
const processedExpr = evaluateExpression(headerValEntry, "Header value entry", options);
|
|
812
|
+
if (typeof processedExpr !== "string") {
|
|
813
|
+
throw new EndpointError(`Header '${headerKey}' value '${processedExpr}' is not a string`);
|
|
814
|
+
}
|
|
815
|
+
return processedExpr;
|
|
816
|
+
}),
|
|
817
|
+
}), {});
|
|
818
|
+
|
|
819
|
+
const getEndpointProperty = (property, options) => {
|
|
820
|
+
if (Array.isArray(property)) {
|
|
821
|
+
return property.map((propertyEntry) => getEndpointProperty(propertyEntry, options));
|
|
822
|
+
}
|
|
823
|
+
switch (typeof property) {
|
|
824
|
+
case "string":
|
|
825
|
+
return evaluateTemplate(property, options);
|
|
826
|
+
case "object":
|
|
827
|
+
if (property === null) {
|
|
828
|
+
throw new EndpointError(`Unexpected endpoint property: ${property}`);
|
|
829
|
+
}
|
|
830
|
+
return getEndpointProperties(property, options);
|
|
831
|
+
case "boolean":
|
|
832
|
+
return property;
|
|
833
|
+
default:
|
|
834
|
+
throw new EndpointError(`Unexpected endpoint property type: ${typeof property}`);
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
|
|
838
|
+
const getEndpointProperties = (properties, options) => Object.entries(properties).reduce((acc, [propertyKey, propertyVal]) => ({
|
|
839
|
+
...acc,
|
|
840
|
+
[propertyKey]: getEndpointProperty(propertyVal, options),
|
|
841
|
+
}), {});
|
|
842
|
+
|
|
843
|
+
const getEndpointUrl = (endpointUrl, options) => {
|
|
844
|
+
const expression = evaluateExpression(endpointUrl, "Endpoint URL", options);
|
|
845
|
+
if (typeof expression === "string") {
|
|
846
|
+
try {
|
|
847
|
+
return new URL(expression);
|
|
848
|
+
}
|
|
849
|
+
catch (error) {
|
|
850
|
+
console.error(`Failed to construct URL with ${expression}`, error);
|
|
851
|
+
throw error;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
throw new EndpointError(`Endpoint URL must be a string, got ${typeof expression}`);
|
|
855
|
+
};
|
|
856
|
+
|
|
857
|
+
const evaluateEndpointRule = (endpointRule, options) => {
|
|
858
|
+
const { conditions, endpoint } = endpointRule;
|
|
859
|
+
const { result, referenceRecord } = evaluateConditions(conditions, options);
|
|
860
|
+
if (!result) {
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
const endpointRuleOptions = {
|
|
864
|
+
...options,
|
|
865
|
+
referenceRecord: { ...options.referenceRecord, ...referenceRecord },
|
|
866
|
+
};
|
|
867
|
+
const { url, properties, headers } = endpoint;
|
|
868
|
+
options.logger?.debug?.(`${debugId} Resolving endpoint from template: ${toDebugString(endpoint)}`);
|
|
869
|
+
return {
|
|
870
|
+
...(headers != undefined && {
|
|
871
|
+
headers: getEndpointHeaders(headers, endpointRuleOptions),
|
|
872
|
+
}),
|
|
873
|
+
...(properties != undefined && {
|
|
874
|
+
properties: getEndpointProperties(properties, endpointRuleOptions),
|
|
875
|
+
}),
|
|
876
|
+
url: getEndpointUrl(url, endpointRuleOptions),
|
|
877
|
+
};
|
|
878
|
+
};
|
|
879
|
+
|
|
880
|
+
const evaluateErrorRule = (errorRule, options) => {
|
|
881
|
+
const { conditions, error } = errorRule;
|
|
882
|
+
const { result, referenceRecord } = evaluateConditions(conditions, options);
|
|
883
|
+
if (!result) {
|
|
884
|
+
return;
|
|
885
|
+
}
|
|
886
|
+
throw new EndpointError(evaluateExpression(error, "Error", {
|
|
887
|
+
...options,
|
|
888
|
+
referenceRecord: { ...options.referenceRecord, ...referenceRecord },
|
|
889
|
+
}));
|
|
890
|
+
};
|
|
891
|
+
|
|
892
|
+
const evaluateTreeRule = (treeRule, options) => {
|
|
893
|
+
const { conditions, rules } = treeRule;
|
|
894
|
+
const { result, referenceRecord } = evaluateConditions(conditions, options);
|
|
895
|
+
if (!result) {
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
return evaluateRules(rules, {
|
|
899
|
+
...options,
|
|
900
|
+
referenceRecord: { ...options.referenceRecord, ...referenceRecord },
|
|
901
|
+
});
|
|
902
|
+
};
|
|
903
|
+
|
|
904
|
+
const evaluateRules = (rules, options) => {
|
|
905
|
+
for (const rule of rules) {
|
|
906
|
+
if (rule.type === "endpoint") {
|
|
907
|
+
const endpointOrUndefined = evaluateEndpointRule(rule, options);
|
|
908
|
+
if (endpointOrUndefined) {
|
|
909
|
+
return endpointOrUndefined;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
else if (rule.type === "error") {
|
|
913
|
+
evaluateErrorRule(rule, options);
|
|
914
|
+
}
|
|
915
|
+
else if (rule.type === "tree") {
|
|
916
|
+
const endpointOrUndefined = evaluateTreeRule(rule, options);
|
|
917
|
+
if (endpointOrUndefined) {
|
|
918
|
+
return endpointOrUndefined;
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
else {
|
|
922
|
+
throw new EndpointError(`Unknown endpoint rule: ${rule}`);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
throw new EndpointError(`Rules evaluation failed`);
|
|
926
|
+
};
|
|
927
|
+
|
|
928
|
+
const resolveEndpoint = (ruleSetObject, options) => {
|
|
929
|
+
const { endpointParams, logger } = options;
|
|
930
|
+
const { parameters, rules } = ruleSetObject;
|
|
931
|
+
options.logger?.debug?.(`${debugId} Initial EndpointParams: ${toDebugString(endpointParams)}`);
|
|
932
|
+
const paramsWithDefault = Object.entries(parameters)
|
|
933
|
+
.filter(([, v]) => v.default != null)
|
|
934
|
+
.map(([k, v]) => [k, v.default]);
|
|
935
|
+
if (paramsWithDefault.length > 0) {
|
|
936
|
+
for (const [paramKey, paramDefaultValue] of paramsWithDefault) {
|
|
937
|
+
endpointParams[paramKey] = endpointParams[paramKey] ?? paramDefaultValue;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
const requiredParams = Object.entries(parameters)
|
|
941
|
+
.filter(([, v]) => v.required)
|
|
942
|
+
.map(([k]) => k);
|
|
943
|
+
for (const requiredParam of requiredParams) {
|
|
944
|
+
if (endpointParams[requiredParam] == null) {
|
|
945
|
+
throw new EndpointError(`Missing required parameter: '${requiredParam}'`);
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
const endpoint = evaluateRules(rules, { endpointParams, logger, referenceRecord: {} });
|
|
949
|
+
options.logger?.debug?.(`${debugId} Resolved endpoint: ${toDebugString(endpoint)}`);
|
|
950
|
+
return endpoint;
|
|
951
|
+
};
|
|
952
|
+
|
|
953
|
+
const isVirtualHostableS3Bucket = (value, allowSubDomains = false) => {
|
|
954
|
+
if (allowSubDomains) {
|
|
955
|
+
for (const label of value.split(".")) {
|
|
956
|
+
if (!isVirtualHostableS3Bucket(label)) {
|
|
957
|
+
return false;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
return true;
|
|
961
|
+
}
|
|
962
|
+
if (!isValidHostLabel(value)) {
|
|
963
|
+
return false;
|
|
964
|
+
}
|
|
965
|
+
if (value.length < 3 || value.length > 63) {
|
|
966
|
+
return false;
|
|
967
|
+
}
|
|
968
|
+
if (value !== value.toLowerCase()) {
|
|
969
|
+
return false;
|
|
970
|
+
}
|
|
971
|
+
if (isIpAddress(value)) {
|
|
972
|
+
return false;
|
|
973
|
+
}
|
|
974
|
+
return true;
|
|
975
|
+
};
|
|
976
|
+
|
|
977
|
+
const ARN_DELIMITER = ":";
|
|
978
|
+
const RESOURCE_DELIMITER = "/";
|
|
979
|
+
const parseArn = (value) => {
|
|
980
|
+
const segments = value.split(ARN_DELIMITER);
|
|
981
|
+
if (segments.length < 6)
|
|
982
|
+
return null;
|
|
983
|
+
const [arn, partition, service, region, accountId, ...resourcePath] = segments;
|
|
984
|
+
if (arn !== "arn" || partition === "" || service === "" || resourcePath.join(ARN_DELIMITER) === "")
|
|
985
|
+
return null;
|
|
986
|
+
const resourceId = resourcePath.map((resource) => resource.split(RESOURCE_DELIMITER)).flat();
|
|
987
|
+
return {
|
|
988
|
+
partition,
|
|
989
|
+
service,
|
|
990
|
+
region,
|
|
991
|
+
accountId,
|
|
992
|
+
resourceId,
|
|
993
|
+
};
|
|
994
|
+
};
|
|
995
|
+
|
|
996
|
+
var partitions = [
|
|
997
|
+
{
|
|
998
|
+
id: "aws",
|
|
999
|
+
outputs: {
|
|
1000
|
+
dnsSuffix: "amazonaws.com",
|
|
1001
|
+
dualStackDnsSuffix: "api.aws",
|
|
1002
|
+
implicitGlobalRegion: "us-east-1",
|
|
1003
|
+
name: "aws",
|
|
1004
|
+
supportsDualStack: true,
|
|
1005
|
+
supportsFIPS: true
|
|
1006
|
+
},
|
|
1007
|
+
regionRegex: "^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$",
|
|
1008
|
+
regions: {
|
|
1009
|
+
"af-south-1": {
|
|
1010
|
+
description: "Africa (Cape Town)"
|
|
1011
|
+
},
|
|
1012
|
+
"ap-east-1": {
|
|
1013
|
+
description: "Asia Pacific (Hong Kong)"
|
|
1014
|
+
},
|
|
1015
|
+
"ap-northeast-1": {
|
|
1016
|
+
description: "Asia Pacific (Tokyo)"
|
|
1017
|
+
},
|
|
1018
|
+
"ap-northeast-2": {
|
|
1019
|
+
description: "Asia Pacific (Seoul)"
|
|
1020
|
+
},
|
|
1021
|
+
"ap-northeast-3": {
|
|
1022
|
+
description: "Asia Pacific (Osaka)"
|
|
1023
|
+
},
|
|
1024
|
+
"ap-south-1": {
|
|
1025
|
+
description: "Asia Pacific (Mumbai)"
|
|
1026
|
+
},
|
|
1027
|
+
"ap-south-2": {
|
|
1028
|
+
description: "Asia Pacific (Hyderabad)"
|
|
1029
|
+
},
|
|
1030
|
+
"ap-southeast-1": {
|
|
1031
|
+
description: "Asia Pacific (Singapore)"
|
|
1032
|
+
},
|
|
1033
|
+
"ap-southeast-2": {
|
|
1034
|
+
description: "Asia Pacific (Sydney)"
|
|
1035
|
+
},
|
|
1036
|
+
"ap-southeast-3": {
|
|
1037
|
+
description: "Asia Pacific (Jakarta)"
|
|
1038
|
+
},
|
|
1039
|
+
"ap-southeast-4": {
|
|
1040
|
+
description: "Asia Pacific (Melbourne)"
|
|
1041
|
+
},
|
|
1042
|
+
"ap-southeast-5": {
|
|
1043
|
+
description: "Asia Pacific (Malaysia)"
|
|
1044
|
+
},
|
|
1045
|
+
"aws-global": {
|
|
1046
|
+
description: "AWS Standard global region"
|
|
1047
|
+
},
|
|
1048
|
+
"ca-central-1": {
|
|
1049
|
+
description: "Canada (Central)"
|
|
1050
|
+
},
|
|
1051
|
+
"ca-west-1": {
|
|
1052
|
+
description: "Canada West (Calgary)"
|
|
1053
|
+
},
|
|
1054
|
+
"eu-central-1": {
|
|
1055
|
+
description: "Europe (Frankfurt)"
|
|
1056
|
+
},
|
|
1057
|
+
"eu-central-2": {
|
|
1058
|
+
description: "Europe (Zurich)"
|
|
1059
|
+
},
|
|
1060
|
+
"eu-north-1": {
|
|
1061
|
+
description: "Europe (Stockholm)"
|
|
1062
|
+
},
|
|
1063
|
+
"eu-south-1": {
|
|
1064
|
+
description: "Europe (Milan)"
|
|
1065
|
+
},
|
|
1066
|
+
"eu-south-2": {
|
|
1067
|
+
description: "Europe (Spain)"
|
|
1068
|
+
},
|
|
1069
|
+
"eu-west-1": {
|
|
1070
|
+
description: "Europe (Ireland)"
|
|
1071
|
+
},
|
|
1072
|
+
"eu-west-2": {
|
|
1073
|
+
description: "Europe (London)"
|
|
1074
|
+
},
|
|
1075
|
+
"eu-west-3": {
|
|
1076
|
+
description: "Europe (Paris)"
|
|
1077
|
+
},
|
|
1078
|
+
"il-central-1": {
|
|
1079
|
+
description: "Israel (Tel Aviv)"
|
|
1080
|
+
},
|
|
1081
|
+
"me-central-1": {
|
|
1082
|
+
description: "Middle East (UAE)"
|
|
1083
|
+
},
|
|
1084
|
+
"me-south-1": {
|
|
1085
|
+
description: "Middle East (Bahrain)"
|
|
1086
|
+
},
|
|
1087
|
+
"sa-east-1": {
|
|
1088
|
+
description: "South America (Sao Paulo)"
|
|
1089
|
+
},
|
|
1090
|
+
"us-east-1": {
|
|
1091
|
+
description: "US East (N. Virginia)"
|
|
1092
|
+
},
|
|
1093
|
+
"us-east-2": {
|
|
1094
|
+
description: "US East (Ohio)"
|
|
1095
|
+
},
|
|
1096
|
+
"us-west-1": {
|
|
1097
|
+
description: "US West (N. California)"
|
|
1098
|
+
},
|
|
1099
|
+
"us-west-2": {
|
|
1100
|
+
description: "US West (Oregon)"
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
},
|
|
1104
|
+
{
|
|
1105
|
+
id: "aws-cn",
|
|
1106
|
+
outputs: {
|
|
1107
|
+
dnsSuffix: "amazonaws.com.cn",
|
|
1108
|
+
dualStackDnsSuffix: "api.amazonwebservices.com.cn",
|
|
1109
|
+
implicitGlobalRegion: "cn-northwest-1",
|
|
1110
|
+
name: "aws-cn",
|
|
1111
|
+
supportsDualStack: true,
|
|
1112
|
+
supportsFIPS: true
|
|
1113
|
+
},
|
|
1114
|
+
regionRegex: "^cn\\-\\w+\\-\\d+$",
|
|
1115
|
+
regions: {
|
|
1116
|
+
"aws-cn-global": {
|
|
1117
|
+
description: "AWS China global region"
|
|
1118
|
+
},
|
|
1119
|
+
"cn-north-1": {
|
|
1120
|
+
description: "China (Beijing)"
|
|
1121
|
+
},
|
|
1122
|
+
"cn-northwest-1": {
|
|
1123
|
+
description: "China (Ningxia)"
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
},
|
|
1127
|
+
{
|
|
1128
|
+
id: "aws-us-gov",
|
|
1129
|
+
outputs: {
|
|
1130
|
+
dnsSuffix: "amazonaws.com",
|
|
1131
|
+
dualStackDnsSuffix: "api.aws",
|
|
1132
|
+
implicitGlobalRegion: "us-gov-west-1",
|
|
1133
|
+
name: "aws-us-gov",
|
|
1134
|
+
supportsDualStack: true,
|
|
1135
|
+
supportsFIPS: true
|
|
1136
|
+
},
|
|
1137
|
+
regionRegex: "^us\\-gov\\-\\w+\\-\\d+$",
|
|
1138
|
+
regions: {
|
|
1139
|
+
"aws-us-gov-global": {
|
|
1140
|
+
description: "AWS GovCloud (US) global region"
|
|
1141
|
+
},
|
|
1142
|
+
"us-gov-east-1": {
|
|
1143
|
+
description: "AWS GovCloud (US-East)"
|
|
1144
|
+
},
|
|
1145
|
+
"us-gov-west-1": {
|
|
1146
|
+
description: "AWS GovCloud (US-West)"
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
},
|
|
1150
|
+
{
|
|
1151
|
+
id: "aws-iso",
|
|
1152
|
+
outputs: {
|
|
1153
|
+
dnsSuffix: "c2s.ic.gov",
|
|
1154
|
+
dualStackDnsSuffix: "c2s.ic.gov",
|
|
1155
|
+
implicitGlobalRegion: "us-iso-east-1",
|
|
1156
|
+
name: "aws-iso",
|
|
1157
|
+
supportsDualStack: false,
|
|
1158
|
+
supportsFIPS: true
|
|
1159
|
+
},
|
|
1160
|
+
regionRegex: "^us\\-iso\\-\\w+\\-\\d+$",
|
|
1161
|
+
regions: {
|
|
1162
|
+
"aws-iso-global": {
|
|
1163
|
+
description: "AWS ISO (US) global region"
|
|
1164
|
+
},
|
|
1165
|
+
"us-iso-east-1": {
|
|
1166
|
+
description: "US ISO East"
|
|
1167
|
+
},
|
|
1168
|
+
"us-iso-west-1": {
|
|
1169
|
+
description: "US ISO WEST"
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
},
|
|
1173
|
+
{
|
|
1174
|
+
id: "aws-iso-b",
|
|
1175
|
+
outputs: {
|
|
1176
|
+
dnsSuffix: "sc2s.sgov.gov",
|
|
1177
|
+
dualStackDnsSuffix: "sc2s.sgov.gov",
|
|
1178
|
+
implicitGlobalRegion: "us-isob-east-1",
|
|
1179
|
+
name: "aws-iso-b",
|
|
1180
|
+
supportsDualStack: false,
|
|
1181
|
+
supportsFIPS: true
|
|
1182
|
+
},
|
|
1183
|
+
regionRegex: "^us\\-isob\\-\\w+\\-\\d+$",
|
|
1184
|
+
regions: {
|
|
1185
|
+
"aws-iso-b-global": {
|
|
1186
|
+
description: "AWS ISOB (US) global region"
|
|
1187
|
+
},
|
|
1188
|
+
"us-isob-east-1": {
|
|
1189
|
+
description: "US ISOB East (Ohio)"
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
},
|
|
1193
|
+
{
|
|
1194
|
+
id: "aws-iso-e",
|
|
1195
|
+
outputs: {
|
|
1196
|
+
dnsSuffix: "cloud.adc-e.uk",
|
|
1197
|
+
dualStackDnsSuffix: "cloud.adc-e.uk",
|
|
1198
|
+
implicitGlobalRegion: "eu-isoe-west-1",
|
|
1199
|
+
name: "aws-iso-e",
|
|
1200
|
+
supportsDualStack: false,
|
|
1201
|
+
supportsFIPS: true
|
|
1202
|
+
},
|
|
1203
|
+
regionRegex: "^eu\\-isoe\\-\\w+\\-\\d+$",
|
|
1204
|
+
regions: {
|
|
1205
|
+
"eu-isoe-west-1": {
|
|
1206
|
+
description: "EU ISOE West"
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
},
|
|
1210
|
+
{
|
|
1211
|
+
id: "aws-iso-f",
|
|
1212
|
+
outputs: {
|
|
1213
|
+
dnsSuffix: "csp.hci.ic.gov",
|
|
1214
|
+
dualStackDnsSuffix: "csp.hci.ic.gov",
|
|
1215
|
+
implicitGlobalRegion: "us-isof-south-1",
|
|
1216
|
+
name: "aws-iso-f",
|
|
1217
|
+
supportsDualStack: false,
|
|
1218
|
+
supportsFIPS: true
|
|
1219
|
+
},
|
|
1220
|
+
regionRegex: "^us\\-isof\\-\\w+\\-\\d+$",
|
|
1221
|
+
regions: {
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
];
|
|
1225
|
+
var version = "1.1";
|
|
1226
|
+
var partitionsInfo = {
|
|
1227
|
+
partitions: partitions,
|
|
1228
|
+
version: version
|
|
1229
|
+
};
|
|
1230
|
+
|
|
1231
|
+
let selectedPartitionsInfo = partitionsInfo;
|
|
1232
|
+
const partition = (value) => {
|
|
1233
|
+
const { partitions } = selectedPartitionsInfo;
|
|
1234
|
+
for (const partition of partitions) {
|
|
1235
|
+
const { regions, outputs } = partition;
|
|
1236
|
+
for (const [region, regionData] of Object.entries(regions)) {
|
|
1237
|
+
if (region === value) {
|
|
1238
|
+
return {
|
|
1239
|
+
...outputs,
|
|
1240
|
+
...regionData,
|
|
1241
|
+
};
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
for (const partition of partitions) {
|
|
1246
|
+
const { regionRegex, outputs } = partition;
|
|
1247
|
+
if (new RegExp(regionRegex).test(value)) {
|
|
1248
|
+
return {
|
|
1249
|
+
...outputs,
|
|
1250
|
+
};
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
const DEFAULT_PARTITION = partitions.find((partition) => partition.id === "aws");
|
|
1254
|
+
if (!DEFAULT_PARTITION) {
|
|
1255
|
+
throw new Error("Provided region was not found in the partition array or regex," +
|
|
1256
|
+
" and default partition with id 'aws' doesn't exist.");
|
|
1257
|
+
}
|
|
1258
|
+
return {
|
|
1259
|
+
...DEFAULT_PARTITION.outputs,
|
|
1260
|
+
};
|
|
1261
|
+
};
|
|
1262
|
+
|
|
1263
|
+
const awsEndpointFunctions = {
|
|
1264
|
+
isVirtualHostableS3Bucket: isVirtualHostableS3Bucket,
|
|
1265
|
+
parseArn: parseArn,
|
|
1266
|
+
partition: partition,
|
|
1267
|
+
};
|
|
1268
|
+
customEndpointFunctions.aws = awsEndpointFunctions;
|
|
1269
|
+
|
|
1270
|
+
const state = {
|
|
1271
|
+
warningEmitted: false,
|
|
1272
|
+
};
|
|
1273
|
+
const emitWarningIfUnsupportedVersion$1 = (version) => {
|
|
1274
|
+
if (version && !state.warningEmitted && parseInt(version.substring(1, version.indexOf("."))) < 18) {
|
|
1275
|
+
state.warningEmitted = true;
|
|
1276
|
+
process.emitWarning(`NodeDeprecationWarning: The AWS SDK for JavaScript (v3) will
|
|
1277
|
+
no longer support Node.js 16.x on January 6, 2025.
|
|
1278
|
+
|
|
1279
|
+
To continue receiving updates to AWS services, bug fixes, and security
|
|
1280
|
+
updates please upgrade to a supported Node.js LTS version.
|
|
1281
|
+
|
|
1282
|
+
More information can be found at: https://a.co/74kJMmI`);
|
|
1283
|
+
}
|
|
1284
|
+
};
|
|
1285
|
+
|
|
1286
|
+
function setFeature(context, feature, value) {
|
|
1287
|
+
if (!context.__aws_sdk_context) {
|
|
1288
|
+
context.__aws_sdk_context = {
|
|
1289
|
+
features: {},
|
|
1290
|
+
};
|
|
1291
|
+
}
|
|
1292
|
+
else if (!context.__aws_sdk_context.features) {
|
|
1293
|
+
context.__aws_sdk_context.features = {};
|
|
1294
|
+
}
|
|
1295
|
+
context.__aws_sdk_context.features[feature] = value;
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
const getDateHeader = (response) => HttpResponse.isInstance(response) ? response.headers?.date ?? response.headers?.Date : undefined;
|
|
1299
|
+
|
|
1300
|
+
const getSkewCorrectedDate = (systemClockOffset) => new Date(Date.now() + systemClockOffset);
|
|
1301
|
+
|
|
1302
|
+
const isClockSkewed = (clockTime, systemClockOffset) => Math.abs(getSkewCorrectedDate(systemClockOffset).getTime() - clockTime) >= 300000;
|
|
1303
|
+
|
|
1304
|
+
const getUpdatedSystemClockOffset = (clockTime, currentSystemClockOffset) => {
|
|
1305
|
+
const clockTimeInMs = Date.parse(clockTime);
|
|
1306
|
+
if (isClockSkewed(clockTimeInMs, currentSystemClockOffset)) {
|
|
1307
|
+
return clockTimeInMs - Date.now();
|
|
1308
|
+
}
|
|
1309
|
+
return currentSystemClockOffset;
|
|
1310
|
+
};
|
|
1311
|
+
|
|
1312
|
+
const throwSigningPropertyError = (name, property) => {
|
|
1313
|
+
if (!property) {
|
|
1314
|
+
throw new Error(`Property \`${name}\` is not resolved for AWS SDK SigV4Auth`);
|
|
1315
|
+
}
|
|
1316
|
+
return property;
|
|
1317
|
+
};
|
|
1318
|
+
const validateSigningProperties = async (signingProperties) => {
|
|
1319
|
+
const context = throwSigningPropertyError("context", signingProperties.context);
|
|
1320
|
+
const config = throwSigningPropertyError("config", signingProperties.config);
|
|
1321
|
+
const authScheme = context.endpointV2?.properties?.authSchemes?.[0];
|
|
1322
|
+
const signerFunction = throwSigningPropertyError("signer", config.signer);
|
|
1323
|
+
const signer = await signerFunction(authScheme);
|
|
1324
|
+
const signingRegion = signingProperties?.signingRegion;
|
|
1325
|
+
const signingRegionSet = signingProperties?.signingRegionSet;
|
|
1326
|
+
const signingName = signingProperties?.signingName;
|
|
1327
|
+
return {
|
|
1328
|
+
config,
|
|
1329
|
+
signer,
|
|
1330
|
+
signingRegion,
|
|
1331
|
+
signingRegionSet,
|
|
1332
|
+
signingName,
|
|
1333
|
+
};
|
|
1334
|
+
};
|
|
1335
|
+
class AwsSdkSigV4Signer {
|
|
1336
|
+
async sign(httpRequest, identity, signingProperties) {
|
|
1337
|
+
if (!HttpRequest.isInstance(httpRequest)) {
|
|
1338
|
+
throw new Error("The request is not an instance of `HttpRequest` and cannot be signed");
|
|
1339
|
+
}
|
|
1340
|
+
const validatedProps = await validateSigningProperties(signingProperties);
|
|
1341
|
+
const { config, signer } = validatedProps;
|
|
1342
|
+
let { signingRegion, signingName } = validatedProps;
|
|
1343
|
+
const handlerExecutionContext = signingProperties.context;
|
|
1344
|
+
if (handlerExecutionContext?.authSchemes?.length ?? 0 > 1) {
|
|
1345
|
+
const [first, second] = handlerExecutionContext.authSchemes;
|
|
1346
|
+
if (first?.name === "sigv4a" && second?.name === "sigv4") {
|
|
1347
|
+
signingRegion = second?.signingRegion ?? signingRegion;
|
|
1348
|
+
signingName = second?.signingName ?? signingName;
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
const signedRequest = await signer.sign(httpRequest, {
|
|
1352
|
+
signingDate: getSkewCorrectedDate(config.systemClockOffset),
|
|
1353
|
+
signingRegion: signingRegion,
|
|
1354
|
+
signingService: signingName,
|
|
1355
|
+
});
|
|
1356
|
+
return signedRequest;
|
|
1357
|
+
}
|
|
1358
|
+
errorHandler(signingProperties) {
|
|
1359
|
+
return (error) => {
|
|
1360
|
+
const serverTime = error.ServerTime ?? getDateHeader(error.$response);
|
|
1361
|
+
if (serverTime) {
|
|
1362
|
+
const config = throwSigningPropertyError("config", signingProperties.config);
|
|
1363
|
+
const initialSystemClockOffset = config.systemClockOffset;
|
|
1364
|
+
config.systemClockOffset = getUpdatedSystemClockOffset(serverTime, config.systemClockOffset);
|
|
1365
|
+
const clockSkewCorrected = config.systemClockOffset !== initialSystemClockOffset;
|
|
1366
|
+
if (clockSkewCorrected && error.$metadata) {
|
|
1367
|
+
error.$metadata.clockSkewCorrected = true;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
throw error;
|
|
1371
|
+
};
|
|
1372
|
+
}
|
|
1373
|
+
successHandler(httpResponse, signingProperties) {
|
|
1374
|
+
const dateHeader = getDateHeader(httpResponse);
|
|
1375
|
+
if (dateHeader) {
|
|
1376
|
+
const config = throwSigningPropertyError("config", signingProperties.config);
|
|
1377
|
+
config.systemClockOffset = getUpdatedSystemClockOffset(dateHeader, config.systemClockOffset);
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
const ALGORITHM_QUERY_PARAM = "X-Amz-Algorithm";
|
|
1383
|
+
const CREDENTIAL_QUERY_PARAM = "X-Amz-Credential";
|
|
1384
|
+
const AMZ_DATE_QUERY_PARAM = "X-Amz-Date";
|
|
1385
|
+
const SIGNED_HEADERS_QUERY_PARAM = "X-Amz-SignedHeaders";
|
|
1386
|
+
const EXPIRES_QUERY_PARAM = "X-Amz-Expires";
|
|
1387
|
+
const SIGNATURE_QUERY_PARAM = "X-Amz-Signature";
|
|
1388
|
+
const TOKEN_QUERY_PARAM = "X-Amz-Security-Token";
|
|
1389
|
+
const AUTH_HEADER = "authorization";
|
|
1390
|
+
const AMZ_DATE_HEADER = AMZ_DATE_QUERY_PARAM.toLowerCase();
|
|
1391
|
+
const DATE_HEADER = "date";
|
|
1392
|
+
const GENERATED_HEADERS = [AUTH_HEADER, AMZ_DATE_HEADER, DATE_HEADER];
|
|
1393
|
+
const SIGNATURE_HEADER = SIGNATURE_QUERY_PARAM.toLowerCase();
|
|
1394
|
+
const SHA256_HEADER = "x-amz-content-sha256";
|
|
1395
|
+
const TOKEN_HEADER = TOKEN_QUERY_PARAM.toLowerCase();
|
|
1396
|
+
const ALWAYS_UNSIGNABLE_HEADERS = {
|
|
1397
|
+
authorization: true,
|
|
1398
|
+
"cache-control": true,
|
|
1399
|
+
connection: true,
|
|
1400
|
+
expect: true,
|
|
1401
|
+
from: true,
|
|
1402
|
+
"keep-alive": true,
|
|
1403
|
+
"max-forwards": true,
|
|
1404
|
+
pragma: true,
|
|
1405
|
+
referer: true,
|
|
1406
|
+
te: true,
|
|
1407
|
+
trailer: true,
|
|
1408
|
+
"transfer-encoding": true,
|
|
1409
|
+
upgrade: true,
|
|
1410
|
+
"user-agent": true,
|
|
1411
|
+
"x-amzn-trace-id": true,
|
|
1412
|
+
};
|
|
1413
|
+
const PROXY_HEADER_PATTERN = /^proxy-/;
|
|
1414
|
+
const SEC_HEADER_PATTERN = /^sec-/;
|
|
1415
|
+
const ALGORITHM_IDENTIFIER = "AWS4-HMAC-SHA256";
|
|
1416
|
+
const EVENT_ALGORITHM_IDENTIFIER = "AWS4-HMAC-SHA256-PAYLOAD";
|
|
1417
|
+
const UNSIGNED_PAYLOAD = "UNSIGNED-PAYLOAD";
|
|
1418
|
+
const MAX_CACHE_SIZE = 50;
|
|
1419
|
+
const KEY_TYPE_IDENTIFIER = "aws4_request";
|
|
1420
|
+
const MAX_PRESIGNED_TTL = 60 * 60 * 24 * 7;
|
|
1421
|
+
|
|
1422
|
+
const signingKeyCache = {};
|
|
1423
|
+
const cacheQueue = [];
|
|
1424
|
+
const createScope = (shortDate, region, service) => `${shortDate}/${region}/${service}/${KEY_TYPE_IDENTIFIER}`;
|
|
1425
|
+
const getSigningKey = async (sha256Constructor, credentials, shortDate, region, service) => {
|
|
1426
|
+
const credsHash = await hmac(sha256Constructor, credentials.secretAccessKey, credentials.accessKeyId);
|
|
1427
|
+
const cacheKey = `${shortDate}:${region}:${service}:${toHex(credsHash)}:${credentials.sessionToken}`;
|
|
1428
|
+
if (cacheKey in signingKeyCache) {
|
|
1429
|
+
return signingKeyCache[cacheKey];
|
|
1430
|
+
}
|
|
1431
|
+
cacheQueue.push(cacheKey);
|
|
1432
|
+
while (cacheQueue.length > MAX_CACHE_SIZE) {
|
|
1433
|
+
delete signingKeyCache[cacheQueue.shift()];
|
|
1434
|
+
}
|
|
1435
|
+
let key = `AWS4${credentials.secretAccessKey}`;
|
|
1436
|
+
for (const signable of [shortDate, region, service, KEY_TYPE_IDENTIFIER]) {
|
|
1437
|
+
key = await hmac(sha256Constructor, key, signable);
|
|
1438
|
+
}
|
|
1439
|
+
return (signingKeyCache[cacheKey] = key);
|
|
1440
|
+
};
|
|
1441
|
+
const hmac = (ctor, secret, data) => {
|
|
1442
|
+
const hash = new ctor(secret);
|
|
1443
|
+
hash.update(toUint8Array(data));
|
|
1444
|
+
return hash.digest();
|
|
1445
|
+
};
|
|
1446
|
+
|
|
1447
|
+
const getCanonicalHeaders = ({ headers }, unsignableHeaders, signableHeaders) => {
|
|
1448
|
+
const canonical = {};
|
|
1449
|
+
for (const headerName of Object.keys(headers).sort()) {
|
|
1450
|
+
if (headers[headerName] == undefined) {
|
|
1451
|
+
continue;
|
|
1452
|
+
}
|
|
1453
|
+
const canonicalHeaderName = headerName.toLowerCase();
|
|
1454
|
+
if (canonicalHeaderName in ALWAYS_UNSIGNABLE_HEADERS ||
|
|
1455
|
+
unsignableHeaders?.has(canonicalHeaderName) ||
|
|
1456
|
+
PROXY_HEADER_PATTERN.test(canonicalHeaderName) ||
|
|
1457
|
+
SEC_HEADER_PATTERN.test(canonicalHeaderName)) {
|
|
1458
|
+
if (!signableHeaders || (signableHeaders && !signableHeaders.has(canonicalHeaderName))) {
|
|
1459
|
+
continue;
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
canonical[canonicalHeaderName] = headers[headerName].trim().replace(/\s+/g, " ");
|
|
1463
|
+
}
|
|
1464
|
+
return canonical;
|
|
1465
|
+
};
|
|
1466
|
+
|
|
1467
|
+
const getCanonicalQuery = ({ query = {} }) => {
|
|
1468
|
+
const keys = [];
|
|
1469
|
+
const serialized = {};
|
|
1470
|
+
for (const key of Object.keys(query)) {
|
|
1471
|
+
if (key.toLowerCase() === SIGNATURE_HEADER) {
|
|
1472
|
+
continue;
|
|
1473
|
+
}
|
|
1474
|
+
const encodedKey = escapeUri(key);
|
|
1475
|
+
keys.push(encodedKey);
|
|
1476
|
+
const value = query[key];
|
|
1477
|
+
if (typeof value === "string") {
|
|
1478
|
+
serialized[encodedKey] = `${encodedKey}=${escapeUri(value)}`;
|
|
1479
|
+
}
|
|
1480
|
+
else if (Array.isArray(value)) {
|
|
1481
|
+
serialized[encodedKey] = value
|
|
1482
|
+
.slice(0)
|
|
1483
|
+
.reduce((encoded, value) => encoded.concat([`${encodedKey}=${escapeUri(value)}`]), [])
|
|
1484
|
+
.sort()
|
|
1485
|
+
.join("&");
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
return keys
|
|
1489
|
+
.sort()
|
|
1490
|
+
.map((key) => serialized[key])
|
|
1491
|
+
.filter((serialized) => serialized)
|
|
1492
|
+
.join("&");
|
|
1493
|
+
};
|
|
1494
|
+
|
|
1495
|
+
const getPayloadHash = async ({ headers, body }, hashConstructor) => {
|
|
1496
|
+
for (const headerName of Object.keys(headers)) {
|
|
1497
|
+
if (headerName.toLowerCase() === SHA256_HEADER) {
|
|
1498
|
+
return headers[headerName];
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
if (body == undefined) {
|
|
1502
|
+
return "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
|
|
1503
|
+
}
|
|
1504
|
+
else if (typeof body === "string" || ArrayBuffer.isView(body) || isArrayBuffer(body)) {
|
|
1505
|
+
const hashCtor = new hashConstructor();
|
|
1506
|
+
hashCtor.update(toUint8Array(body));
|
|
1507
|
+
return toHex(await hashCtor.digest());
|
|
1508
|
+
}
|
|
1509
|
+
return UNSIGNED_PAYLOAD;
|
|
1510
|
+
};
|
|
1511
|
+
|
|
1512
|
+
class HeaderFormatter {
|
|
1513
|
+
format(headers) {
|
|
1514
|
+
const chunks = [];
|
|
1515
|
+
for (const headerName of Object.keys(headers)) {
|
|
1516
|
+
const bytes = fromUtf8(headerName);
|
|
1517
|
+
chunks.push(Uint8Array.from([bytes.byteLength]), bytes, this.formatHeaderValue(headers[headerName]));
|
|
1518
|
+
}
|
|
1519
|
+
const out = new Uint8Array(chunks.reduce((carry, bytes) => carry + bytes.byteLength, 0));
|
|
1520
|
+
let position = 0;
|
|
1521
|
+
for (const chunk of chunks) {
|
|
1522
|
+
out.set(chunk, position);
|
|
1523
|
+
position += chunk.byteLength;
|
|
1524
|
+
}
|
|
1525
|
+
return out;
|
|
1526
|
+
}
|
|
1527
|
+
formatHeaderValue(header) {
|
|
1528
|
+
switch (header.type) {
|
|
1529
|
+
case "boolean":
|
|
1530
|
+
return Uint8Array.from([header.value ? 0 : 1]);
|
|
1531
|
+
case "byte":
|
|
1532
|
+
return Uint8Array.from([2, header.value]);
|
|
1533
|
+
case "short":
|
|
1534
|
+
const shortView = new DataView(new ArrayBuffer(3));
|
|
1535
|
+
shortView.setUint8(0, 3);
|
|
1536
|
+
shortView.setInt16(1, header.value, false);
|
|
1537
|
+
return new Uint8Array(shortView.buffer);
|
|
1538
|
+
case "integer":
|
|
1539
|
+
const intView = new DataView(new ArrayBuffer(5));
|
|
1540
|
+
intView.setUint8(0, 4);
|
|
1541
|
+
intView.setInt32(1, header.value, false);
|
|
1542
|
+
return new Uint8Array(intView.buffer);
|
|
1543
|
+
case "long":
|
|
1544
|
+
const longBytes = new Uint8Array(9);
|
|
1545
|
+
longBytes[0] = 5;
|
|
1546
|
+
longBytes.set(header.value.bytes, 1);
|
|
1547
|
+
return longBytes;
|
|
1548
|
+
case "binary":
|
|
1549
|
+
const binView = new DataView(new ArrayBuffer(3 + header.value.byteLength));
|
|
1550
|
+
binView.setUint8(0, 6);
|
|
1551
|
+
binView.setUint16(1, header.value.byteLength, false);
|
|
1552
|
+
const binBytes = new Uint8Array(binView.buffer);
|
|
1553
|
+
binBytes.set(header.value, 3);
|
|
1554
|
+
return binBytes;
|
|
1555
|
+
case "string":
|
|
1556
|
+
const utf8Bytes = fromUtf8(header.value);
|
|
1557
|
+
const strView = new DataView(new ArrayBuffer(3 + utf8Bytes.byteLength));
|
|
1558
|
+
strView.setUint8(0, 7);
|
|
1559
|
+
strView.setUint16(1, utf8Bytes.byteLength, false);
|
|
1560
|
+
const strBytes = new Uint8Array(strView.buffer);
|
|
1561
|
+
strBytes.set(utf8Bytes, 3);
|
|
1562
|
+
return strBytes;
|
|
1563
|
+
case "timestamp":
|
|
1564
|
+
const tsBytes = new Uint8Array(9);
|
|
1565
|
+
tsBytes[0] = 8;
|
|
1566
|
+
tsBytes.set(Int64.fromNumber(header.value.valueOf()).bytes, 1);
|
|
1567
|
+
return tsBytes;
|
|
1568
|
+
case "uuid":
|
|
1569
|
+
if (!UUID_PATTERN.test(header.value)) {
|
|
1570
|
+
throw new Error(`Invalid UUID received: ${header.value}`);
|
|
1571
|
+
}
|
|
1572
|
+
const uuidBytes = new Uint8Array(17);
|
|
1573
|
+
uuidBytes[0] = 9;
|
|
1574
|
+
uuidBytes.set(fromHex(header.value.replace(/\-/g, "")), 1);
|
|
1575
|
+
return uuidBytes;
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
var HEADER_VALUE_TYPE;
|
|
1580
|
+
(function (HEADER_VALUE_TYPE) {
|
|
1581
|
+
HEADER_VALUE_TYPE[HEADER_VALUE_TYPE["boolTrue"] = 0] = "boolTrue";
|
|
1582
|
+
HEADER_VALUE_TYPE[HEADER_VALUE_TYPE["boolFalse"] = 1] = "boolFalse";
|
|
1583
|
+
HEADER_VALUE_TYPE[HEADER_VALUE_TYPE["byte"] = 2] = "byte";
|
|
1584
|
+
HEADER_VALUE_TYPE[HEADER_VALUE_TYPE["short"] = 3] = "short";
|
|
1585
|
+
HEADER_VALUE_TYPE[HEADER_VALUE_TYPE["integer"] = 4] = "integer";
|
|
1586
|
+
HEADER_VALUE_TYPE[HEADER_VALUE_TYPE["long"] = 5] = "long";
|
|
1587
|
+
HEADER_VALUE_TYPE[HEADER_VALUE_TYPE["byteArray"] = 6] = "byteArray";
|
|
1588
|
+
HEADER_VALUE_TYPE[HEADER_VALUE_TYPE["string"] = 7] = "string";
|
|
1589
|
+
HEADER_VALUE_TYPE[HEADER_VALUE_TYPE["timestamp"] = 8] = "timestamp";
|
|
1590
|
+
HEADER_VALUE_TYPE[HEADER_VALUE_TYPE["uuid"] = 9] = "uuid";
|
|
1591
|
+
})(HEADER_VALUE_TYPE || (HEADER_VALUE_TYPE = {}));
|
|
1592
|
+
const UUID_PATTERN = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/;
|
|
1593
|
+
class Int64 {
|
|
1594
|
+
constructor(bytes) {
|
|
1595
|
+
this.bytes = bytes;
|
|
1596
|
+
if (bytes.byteLength !== 8) {
|
|
1597
|
+
throw new Error("Int64 buffers must be exactly 8 bytes");
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
static fromNumber(number) {
|
|
1601
|
+
if (number > 9223372036854776000 || number < -9223372036854776e3) {
|
|
1602
|
+
throw new Error(`${number} is too large (or, if negative, too small) to represent as an Int64`);
|
|
1603
|
+
}
|
|
1604
|
+
const bytes = new Uint8Array(8);
|
|
1605
|
+
for (let i = 7, remaining = Math.abs(Math.round(number)); i > -1 && remaining > 0; i--, remaining /= 256) {
|
|
1606
|
+
bytes[i] = remaining;
|
|
1607
|
+
}
|
|
1608
|
+
if (number < 0) {
|
|
1609
|
+
negate(bytes);
|
|
1610
|
+
}
|
|
1611
|
+
return new Int64(bytes);
|
|
1612
|
+
}
|
|
1613
|
+
valueOf() {
|
|
1614
|
+
const bytes = this.bytes.slice(0);
|
|
1615
|
+
const negative = bytes[0] & 0b10000000;
|
|
1616
|
+
if (negative) {
|
|
1617
|
+
negate(bytes);
|
|
1618
|
+
}
|
|
1619
|
+
return parseInt(toHex(bytes), 16) * (negative ? -1 : 1);
|
|
1620
|
+
}
|
|
1621
|
+
toString() {
|
|
1622
|
+
return String(this.valueOf());
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
function negate(bytes) {
|
|
1626
|
+
for (let i = 0; i < 8; i++) {
|
|
1627
|
+
bytes[i] ^= 0xff;
|
|
1628
|
+
}
|
|
1629
|
+
for (let i = 7; i > -1; i--) {
|
|
1630
|
+
bytes[i]++;
|
|
1631
|
+
if (bytes[i] !== 0)
|
|
1632
|
+
break;
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1636
|
+
const hasHeader = (soughtHeader, headers) => {
|
|
1637
|
+
soughtHeader = soughtHeader.toLowerCase();
|
|
1638
|
+
for (const headerName of Object.keys(headers)) {
|
|
1639
|
+
if (soughtHeader === headerName.toLowerCase()) {
|
|
1640
|
+
return true;
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
return false;
|
|
1644
|
+
};
|
|
1645
|
+
|
|
1646
|
+
const moveHeadersToQuery = (request, options = {}) => {
|
|
1647
|
+
const { headers, query = {} } = HttpRequest.clone(request);
|
|
1648
|
+
for (const name of Object.keys(headers)) {
|
|
1649
|
+
const lname = name.toLowerCase();
|
|
1650
|
+
if ((lname.slice(0, 6) === "x-amz-" && !options.unhoistableHeaders?.has(lname)) ||
|
|
1651
|
+
options.hoistableHeaders?.has(lname)) {
|
|
1652
|
+
query[name] = headers[name];
|
|
1653
|
+
delete headers[name];
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
return {
|
|
1657
|
+
...request,
|
|
1658
|
+
headers,
|
|
1659
|
+
query,
|
|
1660
|
+
};
|
|
1661
|
+
};
|
|
1662
|
+
|
|
1663
|
+
const prepareRequest = (request) => {
|
|
1664
|
+
request = HttpRequest.clone(request);
|
|
1665
|
+
for (const headerName of Object.keys(request.headers)) {
|
|
1666
|
+
if (GENERATED_HEADERS.indexOf(headerName.toLowerCase()) > -1) {
|
|
1667
|
+
delete request.headers[headerName];
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
return request;
|
|
1671
|
+
};
|
|
1672
|
+
|
|
1673
|
+
const iso8601 = (time) => toDate(time)
|
|
1674
|
+
.toISOString()
|
|
1675
|
+
.replace(/\.\d{3}Z$/, "Z");
|
|
1676
|
+
const toDate = (time) => {
|
|
1677
|
+
if (typeof time === "number") {
|
|
1678
|
+
return new Date(time * 1000);
|
|
1679
|
+
}
|
|
1680
|
+
if (typeof time === "string") {
|
|
1681
|
+
if (Number(time)) {
|
|
1682
|
+
return new Date(Number(time) * 1000);
|
|
1683
|
+
}
|
|
1684
|
+
return new Date(time);
|
|
1685
|
+
}
|
|
1686
|
+
return time;
|
|
1687
|
+
};
|
|
1688
|
+
|
|
1689
|
+
class SignatureV4 {
|
|
1690
|
+
constructor({ applyChecksum, credentials, region, service, sha256, uriEscapePath = true, }) {
|
|
1691
|
+
this.headerFormatter = new HeaderFormatter();
|
|
1692
|
+
this.service = service;
|
|
1693
|
+
this.sha256 = sha256;
|
|
1694
|
+
this.uriEscapePath = uriEscapePath;
|
|
1695
|
+
this.applyChecksum = typeof applyChecksum === "boolean" ? applyChecksum : true;
|
|
1696
|
+
this.regionProvider = normalizeProvider$1(region);
|
|
1697
|
+
this.credentialProvider = normalizeProvider$1(credentials);
|
|
1698
|
+
}
|
|
1699
|
+
async presign(originalRequest, options = {}) {
|
|
1700
|
+
const { signingDate = new Date(), expiresIn = 3600, unsignableHeaders, unhoistableHeaders, signableHeaders, hoistableHeaders, signingRegion, signingService, } = options;
|
|
1701
|
+
const credentials = await this.credentialProvider();
|
|
1702
|
+
this.validateResolvedCredentials(credentials);
|
|
1703
|
+
const region = signingRegion ?? (await this.regionProvider());
|
|
1704
|
+
const { longDate, shortDate } = formatDate(signingDate);
|
|
1705
|
+
if (expiresIn > MAX_PRESIGNED_TTL) {
|
|
1706
|
+
return Promise.reject("Signature version 4 presigned URLs" + " must have an expiration date less than one week in" + " the future");
|
|
1707
|
+
}
|
|
1708
|
+
const scope = createScope(shortDate, region, signingService ?? this.service);
|
|
1709
|
+
const request = moveHeadersToQuery(prepareRequest(originalRequest), { unhoistableHeaders, hoistableHeaders });
|
|
1710
|
+
if (credentials.sessionToken) {
|
|
1711
|
+
request.query[TOKEN_QUERY_PARAM] = credentials.sessionToken;
|
|
1712
|
+
}
|
|
1713
|
+
request.query[ALGORITHM_QUERY_PARAM] = ALGORITHM_IDENTIFIER;
|
|
1714
|
+
request.query[CREDENTIAL_QUERY_PARAM] = `${credentials.accessKeyId}/${scope}`;
|
|
1715
|
+
request.query[AMZ_DATE_QUERY_PARAM] = longDate;
|
|
1716
|
+
request.query[EXPIRES_QUERY_PARAM] = expiresIn.toString(10);
|
|
1717
|
+
const canonicalHeaders = getCanonicalHeaders(request, unsignableHeaders, signableHeaders);
|
|
1718
|
+
request.query[SIGNED_HEADERS_QUERY_PARAM] = getCanonicalHeaderList(canonicalHeaders);
|
|
1719
|
+
request.query[SIGNATURE_QUERY_PARAM] = await this.getSignature(longDate, scope, this.getSigningKey(credentials, region, shortDate, signingService), this.createCanonicalRequest(request, canonicalHeaders, await getPayloadHash(originalRequest, this.sha256)));
|
|
1720
|
+
return request;
|
|
1721
|
+
}
|
|
1722
|
+
async sign(toSign, options) {
|
|
1723
|
+
if (typeof toSign === "string") {
|
|
1724
|
+
return this.signString(toSign, options);
|
|
1725
|
+
}
|
|
1726
|
+
else if (toSign.headers && toSign.payload) {
|
|
1727
|
+
return this.signEvent(toSign, options);
|
|
1728
|
+
}
|
|
1729
|
+
else if (toSign.message) {
|
|
1730
|
+
return this.signMessage(toSign, options);
|
|
1731
|
+
}
|
|
1732
|
+
else {
|
|
1733
|
+
return this.signRequest(toSign, options);
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
async signEvent({ headers, payload }, { signingDate = new Date(), priorSignature, signingRegion, signingService }) {
|
|
1737
|
+
const region = signingRegion ?? (await this.regionProvider());
|
|
1738
|
+
const { shortDate, longDate } = formatDate(signingDate);
|
|
1739
|
+
const scope = createScope(shortDate, region, signingService ?? this.service);
|
|
1740
|
+
const hashedPayload = await getPayloadHash({ headers: {}, body: payload }, this.sha256);
|
|
1741
|
+
const hash = new this.sha256();
|
|
1742
|
+
hash.update(headers);
|
|
1743
|
+
const hashedHeaders = toHex(await hash.digest());
|
|
1744
|
+
const stringToSign = [
|
|
1745
|
+
EVENT_ALGORITHM_IDENTIFIER,
|
|
1746
|
+
longDate,
|
|
1747
|
+
scope,
|
|
1748
|
+
priorSignature,
|
|
1749
|
+
hashedHeaders,
|
|
1750
|
+
hashedPayload,
|
|
1751
|
+
].join("\n");
|
|
1752
|
+
return this.signString(stringToSign, { signingDate, signingRegion: region, signingService });
|
|
1753
|
+
}
|
|
1754
|
+
async signMessage(signableMessage, { signingDate = new Date(), signingRegion, signingService }) {
|
|
1755
|
+
const promise = this.signEvent({
|
|
1756
|
+
headers: this.headerFormatter.format(signableMessage.message.headers),
|
|
1757
|
+
payload: signableMessage.message.body,
|
|
1758
|
+
}, {
|
|
1759
|
+
signingDate,
|
|
1760
|
+
signingRegion,
|
|
1761
|
+
signingService,
|
|
1762
|
+
priorSignature: signableMessage.priorSignature,
|
|
1763
|
+
});
|
|
1764
|
+
return promise.then((signature) => {
|
|
1765
|
+
return { message: signableMessage.message, signature };
|
|
1766
|
+
});
|
|
1767
|
+
}
|
|
1768
|
+
async signString(stringToSign, { signingDate = new Date(), signingRegion, signingService } = {}) {
|
|
1769
|
+
const credentials = await this.credentialProvider();
|
|
1770
|
+
this.validateResolvedCredentials(credentials);
|
|
1771
|
+
const region = signingRegion ?? (await this.regionProvider());
|
|
1772
|
+
const { shortDate } = formatDate(signingDate);
|
|
1773
|
+
const hash = new this.sha256(await this.getSigningKey(credentials, region, shortDate, signingService));
|
|
1774
|
+
hash.update(toUint8Array(stringToSign));
|
|
1775
|
+
return toHex(await hash.digest());
|
|
1776
|
+
}
|
|
1777
|
+
async signRequest(requestToSign, { signingDate = new Date(), signableHeaders, unsignableHeaders, signingRegion, signingService, } = {}) {
|
|
1778
|
+
const credentials = await this.credentialProvider();
|
|
1779
|
+
this.validateResolvedCredentials(credentials);
|
|
1780
|
+
const region = signingRegion ?? (await this.regionProvider());
|
|
1781
|
+
const request = prepareRequest(requestToSign);
|
|
1782
|
+
const { longDate, shortDate } = formatDate(signingDate);
|
|
1783
|
+
const scope = createScope(shortDate, region, signingService ?? this.service);
|
|
1784
|
+
request.headers[AMZ_DATE_HEADER] = longDate;
|
|
1785
|
+
if (credentials.sessionToken) {
|
|
1786
|
+
request.headers[TOKEN_HEADER] = credentials.sessionToken;
|
|
1787
|
+
}
|
|
1788
|
+
const payloadHash = await getPayloadHash(request, this.sha256);
|
|
1789
|
+
if (!hasHeader(SHA256_HEADER, request.headers) && this.applyChecksum) {
|
|
1790
|
+
request.headers[SHA256_HEADER] = payloadHash;
|
|
1791
|
+
}
|
|
1792
|
+
const canonicalHeaders = getCanonicalHeaders(request, unsignableHeaders, signableHeaders);
|
|
1793
|
+
const signature = await this.getSignature(longDate, scope, this.getSigningKey(credentials, region, shortDate, signingService), this.createCanonicalRequest(request, canonicalHeaders, payloadHash));
|
|
1794
|
+
request.headers[AUTH_HEADER] =
|
|
1795
|
+
`${ALGORITHM_IDENTIFIER} ` +
|
|
1796
|
+
`Credential=${credentials.accessKeyId}/${scope}, ` +
|
|
1797
|
+
`SignedHeaders=${getCanonicalHeaderList(canonicalHeaders)}, ` +
|
|
1798
|
+
`Signature=${signature}`;
|
|
1799
|
+
return request;
|
|
1800
|
+
}
|
|
1801
|
+
createCanonicalRequest(request, canonicalHeaders, payloadHash) {
|
|
1802
|
+
const sortedHeaders = Object.keys(canonicalHeaders).sort();
|
|
1803
|
+
return `${request.method}
|
|
1804
|
+
${this.getCanonicalPath(request)}
|
|
1805
|
+
${getCanonicalQuery(request)}
|
|
1806
|
+
${sortedHeaders.map((name) => `${name}:${canonicalHeaders[name]}`).join("\n")}
|
|
1807
|
+
|
|
1808
|
+
${sortedHeaders.join(";")}
|
|
1809
|
+
${payloadHash}`;
|
|
1810
|
+
}
|
|
1811
|
+
async createStringToSign(longDate, credentialScope, canonicalRequest) {
|
|
1812
|
+
const hash = new this.sha256();
|
|
1813
|
+
hash.update(toUint8Array(canonicalRequest));
|
|
1814
|
+
const hashedRequest = await hash.digest();
|
|
1815
|
+
return `${ALGORITHM_IDENTIFIER}
|
|
1816
|
+
${longDate}
|
|
1817
|
+
${credentialScope}
|
|
1818
|
+
${toHex(hashedRequest)}`;
|
|
1819
|
+
}
|
|
1820
|
+
getCanonicalPath({ path }) {
|
|
1821
|
+
if (this.uriEscapePath) {
|
|
1822
|
+
const normalizedPathSegments = [];
|
|
1823
|
+
for (const pathSegment of path.split("/")) {
|
|
1824
|
+
if (pathSegment?.length === 0)
|
|
1825
|
+
continue;
|
|
1826
|
+
if (pathSegment === ".")
|
|
1827
|
+
continue;
|
|
1828
|
+
if (pathSegment === "..") {
|
|
1829
|
+
normalizedPathSegments.pop();
|
|
1830
|
+
}
|
|
1831
|
+
else {
|
|
1832
|
+
normalizedPathSegments.push(pathSegment);
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
const normalizedPath = `${path?.startsWith("/") ? "/" : ""}${normalizedPathSegments.join("/")}${normalizedPathSegments.length > 0 && path?.endsWith("/") ? "/" : ""}`;
|
|
1836
|
+
const doubleEncoded = escapeUri(normalizedPath);
|
|
1837
|
+
return doubleEncoded.replace(/%2F/g, "/");
|
|
1838
|
+
}
|
|
1839
|
+
return path;
|
|
1840
|
+
}
|
|
1841
|
+
async getSignature(longDate, credentialScope, keyPromise, canonicalRequest) {
|
|
1842
|
+
const stringToSign = await this.createStringToSign(longDate, credentialScope, canonicalRequest);
|
|
1843
|
+
const hash = new this.sha256(await keyPromise);
|
|
1844
|
+
hash.update(toUint8Array(stringToSign));
|
|
1845
|
+
return toHex(await hash.digest());
|
|
1846
|
+
}
|
|
1847
|
+
getSigningKey(credentials, region, shortDate, service) {
|
|
1848
|
+
return getSigningKey(this.sha256, credentials, shortDate, region, service || this.service);
|
|
1849
|
+
}
|
|
1850
|
+
validateResolvedCredentials(credentials) {
|
|
1851
|
+
if (typeof credentials !== "object" ||
|
|
1852
|
+
typeof credentials.accessKeyId !== "string" ||
|
|
1853
|
+
typeof credentials.secretAccessKey !== "string") {
|
|
1854
|
+
throw new Error("Resolved credential object is not valid");
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1858
|
+
const formatDate = (now) => {
|
|
1859
|
+
const longDate = iso8601(now).replace(/[\-:]/g, "");
|
|
1860
|
+
return {
|
|
1861
|
+
longDate,
|
|
1862
|
+
shortDate: longDate.slice(0, 8),
|
|
1863
|
+
};
|
|
1864
|
+
};
|
|
1865
|
+
const getCanonicalHeaderList = (headers) => Object.keys(headers).sort().join(";");
|
|
1866
|
+
|
|
1867
|
+
const resolveAwsSdkSigV4Config = (config) => {
|
|
1868
|
+
let isUserSupplied = false;
|
|
1869
|
+
let credentialsProvider;
|
|
1870
|
+
if (config.credentials) {
|
|
1871
|
+
isUserSupplied = true;
|
|
1872
|
+
credentialsProvider = memoizeIdentityProvider(config.credentials, isIdentityExpired, doesIdentityRequireRefresh);
|
|
1873
|
+
}
|
|
1874
|
+
if (!credentialsProvider) {
|
|
1875
|
+
if (config.credentialDefaultProvider) {
|
|
1876
|
+
credentialsProvider = normalizeProvider(config.credentialDefaultProvider(Object.assign({}, config, {
|
|
1877
|
+
parentClientConfig: config,
|
|
1878
|
+
})));
|
|
1879
|
+
}
|
|
1880
|
+
else {
|
|
1881
|
+
credentialsProvider = async () => {
|
|
1882
|
+
throw new Error("`credentials` is missing");
|
|
1883
|
+
};
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
const boundCredentialsProvider = async () => credentialsProvider({ callerClientConfig: config });
|
|
1887
|
+
const { signingEscapePath = true, systemClockOffset = config.systemClockOffset || 0, sha256, } = config;
|
|
1888
|
+
let signer;
|
|
1889
|
+
if (config.signer) {
|
|
1890
|
+
signer = normalizeProvider(config.signer);
|
|
1891
|
+
}
|
|
1892
|
+
else if (config.regionInfoProvider) {
|
|
1893
|
+
signer = () => normalizeProvider(config.region)()
|
|
1894
|
+
.then(async (region) => [
|
|
1895
|
+
(await config.regionInfoProvider(region, {
|
|
1896
|
+
useFipsEndpoint: await config.useFipsEndpoint(),
|
|
1897
|
+
useDualstackEndpoint: await config.useDualstackEndpoint(),
|
|
1898
|
+
})) || {},
|
|
1899
|
+
region,
|
|
1900
|
+
])
|
|
1901
|
+
.then(([regionInfo, region]) => {
|
|
1902
|
+
const { signingRegion, signingService } = regionInfo;
|
|
1903
|
+
config.signingRegion = config.signingRegion || signingRegion || region;
|
|
1904
|
+
config.signingName = config.signingName || signingService || config.serviceId;
|
|
1905
|
+
const params = {
|
|
1906
|
+
...config,
|
|
1907
|
+
credentials: boundCredentialsProvider,
|
|
1908
|
+
region: config.signingRegion,
|
|
1909
|
+
service: config.signingName,
|
|
1910
|
+
sha256,
|
|
1911
|
+
uriEscapePath: signingEscapePath,
|
|
1912
|
+
};
|
|
1913
|
+
const SignerCtor = config.signerConstructor || SignatureV4;
|
|
1914
|
+
return new SignerCtor(params);
|
|
1915
|
+
});
|
|
1916
|
+
}
|
|
1917
|
+
else {
|
|
1918
|
+
signer = async (authScheme) => {
|
|
1919
|
+
authScheme = Object.assign({}, {
|
|
1920
|
+
name: "sigv4",
|
|
1921
|
+
signingName: config.signingName || config.defaultSigningName,
|
|
1922
|
+
signingRegion: await normalizeProvider(config.region)(),
|
|
1923
|
+
properties: {},
|
|
1924
|
+
}, authScheme);
|
|
1925
|
+
const signingRegion = authScheme.signingRegion;
|
|
1926
|
+
const signingService = authScheme.signingName;
|
|
1927
|
+
config.signingRegion = config.signingRegion || signingRegion;
|
|
1928
|
+
config.signingName = config.signingName || signingService || config.serviceId;
|
|
1929
|
+
const params = {
|
|
1930
|
+
...config,
|
|
1931
|
+
credentials: boundCredentialsProvider,
|
|
1932
|
+
region: config.signingRegion,
|
|
1933
|
+
service: config.signingName,
|
|
1934
|
+
sha256,
|
|
1935
|
+
uriEscapePath: signingEscapePath,
|
|
1936
|
+
};
|
|
1937
|
+
const SignerCtor = config.signerConstructor || SignatureV4;
|
|
1938
|
+
return new SignerCtor(params);
|
|
1939
|
+
};
|
|
1940
|
+
}
|
|
1941
|
+
return {
|
|
1942
|
+
...config,
|
|
1943
|
+
systemClockOffset,
|
|
1944
|
+
signingEscapePath,
|
|
1945
|
+
credentials: isUserSupplied
|
|
1946
|
+
? async () => boundCredentialsProvider().then((creds) => setCredentialFeature(creds, "CREDENTIALS_CODE", "e"))
|
|
1947
|
+
: boundCredentialsProvider,
|
|
1948
|
+
signer,
|
|
1949
|
+
};
|
|
1950
|
+
};
|
|
1951
|
+
|
|
1952
|
+
const getAllAliases = (name, aliases) => {
|
|
1953
|
+
const _aliases = [];
|
|
1954
|
+
if (name) {
|
|
1955
|
+
_aliases.push(name);
|
|
1956
|
+
}
|
|
1957
|
+
if (aliases) {
|
|
1958
|
+
for (const alias of aliases) {
|
|
1959
|
+
_aliases.push(alias);
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
return _aliases;
|
|
1963
|
+
};
|
|
1964
|
+
const getMiddlewareNameWithAliases = (name, aliases) => {
|
|
1965
|
+
return `${name || "anonymous"}${aliases && aliases.length > 0 ? ` (a.k.a. ${aliases.join(",")})` : ""}`;
|
|
1966
|
+
};
|
|
1967
|
+
const constructStack = () => {
|
|
1968
|
+
let absoluteEntries = [];
|
|
1969
|
+
let relativeEntries = [];
|
|
1970
|
+
let identifyOnResolve = false;
|
|
1971
|
+
const entriesNameSet = new Set();
|
|
1972
|
+
const sort = (entries) => entries.sort((a, b) => stepWeights[b.step] - stepWeights[a.step] ||
|
|
1973
|
+
priorityWeights[b.priority || "normal"] - priorityWeights[a.priority || "normal"]);
|
|
1974
|
+
const removeByName = (toRemove) => {
|
|
1975
|
+
let isRemoved = false;
|
|
1976
|
+
const filterCb = (entry) => {
|
|
1977
|
+
const aliases = getAllAliases(entry.name, entry.aliases);
|
|
1978
|
+
if (aliases.includes(toRemove)) {
|
|
1979
|
+
isRemoved = true;
|
|
1980
|
+
for (const alias of aliases) {
|
|
1981
|
+
entriesNameSet.delete(alias);
|
|
1982
|
+
}
|
|
1983
|
+
return false;
|
|
1984
|
+
}
|
|
1985
|
+
return true;
|
|
1986
|
+
};
|
|
1987
|
+
absoluteEntries = absoluteEntries.filter(filterCb);
|
|
1988
|
+
relativeEntries = relativeEntries.filter(filterCb);
|
|
1989
|
+
return isRemoved;
|
|
1990
|
+
};
|
|
1991
|
+
const removeByReference = (toRemove) => {
|
|
1992
|
+
let isRemoved = false;
|
|
1993
|
+
const filterCb = (entry) => {
|
|
1994
|
+
if (entry.middleware === toRemove) {
|
|
1995
|
+
isRemoved = true;
|
|
1996
|
+
for (const alias of getAllAliases(entry.name, entry.aliases)) {
|
|
1997
|
+
entriesNameSet.delete(alias);
|
|
1998
|
+
}
|
|
1999
|
+
return false;
|
|
2000
|
+
}
|
|
2001
|
+
return true;
|
|
2002
|
+
};
|
|
2003
|
+
absoluteEntries = absoluteEntries.filter(filterCb);
|
|
2004
|
+
relativeEntries = relativeEntries.filter(filterCb);
|
|
2005
|
+
return isRemoved;
|
|
2006
|
+
};
|
|
2007
|
+
const cloneTo = (toStack) => {
|
|
2008
|
+
absoluteEntries.forEach((entry) => {
|
|
2009
|
+
toStack.add(entry.middleware, { ...entry });
|
|
2010
|
+
});
|
|
2011
|
+
relativeEntries.forEach((entry) => {
|
|
2012
|
+
toStack.addRelativeTo(entry.middleware, { ...entry });
|
|
2013
|
+
});
|
|
2014
|
+
toStack.identifyOnResolve?.(stack.identifyOnResolve());
|
|
2015
|
+
return toStack;
|
|
2016
|
+
};
|
|
2017
|
+
const expandRelativeMiddlewareList = (from) => {
|
|
2018
|
+
const expandedMiddlewareList = [];
|
|
2019
|
+
from.before.forEach((entry) => {
|
|
2020
|
+
if (entry.before.length === 0 && entry.after.length === 0) {
|
|
2021
|
+
expandedMiddlewareList.push(entry);
|
|
2022
|
+
}
|
|
2023
|
+
else {
|
|
2024
|
+
expandedMiddlewareList.push(...expandRelativeMiddlewareList(entry));
|
|
2025
|
+
}
|
|
2026
|
+
});
|
|
2027
|
+
expandedMiddlewareList.push(from);
|
|
2028
|
+
from.after.reverse().forEach((entry) => {
|
|
2029
|
+
if (entry.before.length === 0 && entry.after.length === 0) {
|
|
2030
|
+
expandedMiddlewareList.push(entry);
|
|
2031
|
+
}
|
|
2032
|
+
else {
|
|
2033
|
+
expandedMiddlewareList.push(...expandRelativeMiddlewareList(entry));
|
|
2034
|
+
}
|
|
2035
|
+
});
|
|
2036
|
+
return expandedMiddlewareList;
|
|
2037
|
+
};
|
|
2038
|
+
const getMiddlewareList = (debug = false) => {
|
|
2039
|
+
const normalizedAbsoluteEntries = [];
|
|
2040
|
+
const normalizedRelativeEntries = [];
|
|
2041
|
+
const normalizedEntriesNameMap = {};
|
|
2042
|
+
absoluteEntries.forEach((entry) => {
|
|
2043
|
+
const normalizedEntry = {
|
|
2044
|
+
...entry,
|
|
2045
|
+
before: [],
|
|
2046
|
+
after: [],
|
|
2047
|
+
};
|
|
2048
|
+
for (const alias of getAllAliases(normalizedEntry.name, normalizedEntry.aliases)) {
|
|
2049
|
+
normalizedEntriesNameMap[alias] = normalizedEntry;
|
|
2050
|
+
}
|
|
2051
|
+
normalizedAbsoluteEntries.push(normalizedEntry);
|
|
2052
|
+
});
|
|
2053
|
+
relativeEntries.forEach((entry) => {
|
|
2054
|
+
const normalizedEntry = {
|
|
2055
|
+
...entry,
|
|
2056
|
+
before: [],
|
|
2057
|
+
after: [],
|
|
2058
|
+
};
|
|
2059
|
+
for (const alias of getAllAliases(normalizedEntry.name, normalizedEntry.aliases)) {
|
|
2060
|
+
normalizedEntriesNameMap[alias] = normalizedEntry;
|
|
2061
|
+
}
|
|
2062
|
+
normalizedRelativeEntries.push(normalizedEntry);
|
|
2063
|
+
});
|
|
2064
|
+
normalizedRelativeEntries.forEach((entry) => {
|
|
2065
|
+
if (entry.toMiddleware) {
|
|
2066
|
+
const toMiddleware = normalizedEntriesNameMap[entry.toMiddleware];
|
|
2067
|
+
if (toMiddleware === undefined) {
|
|
2068
|
+
if (debug) {
|
|
2069
|
+
return;
|
|
2070
|
+
}
|
|
2071
|
+
throw new Error(`${entry.toMiddleware} is not found when adding ` +
|
|
2072
|
+
`${getMiddlewareNameWithAliases(entry.name, entry.aliases)} ` +
|
|
2073
|
+
`middleware ${entry.relation} ${entry.toMiddleware}`);
|
|
2074
|
+
}
|
|
2075
|
+
if (entry.relation === "after") {
|
|
2076
|
+
toMiddleware.after.push(entry);
|
|
2077
|
+
}
|
|
2078
|
+
if (entry.relation === "before") {
|
|
2079
|
+
toMiddleware.before.push(entry);
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
});
|
|
2083
|
+
const mainChain = sort(normalizedAbsoluteEntries)
|
|
2084
|
+
.map(expandRelativeMiddlewareList)
|
|
2085
|
+
.reduce((wholeList, expandedMiddlewareList) => {
|
|
2086
|
+
wholeList.push(...expandedMiddlewareList);
|
|
2087
|
+
return wholeList;
|
|
2088
|
+
}, []);
|
|
2089
|
+
return mainChain;
|
|
2090
|
+
};
|
|
2091
|
+
const stack = {
|
|
2092
|
+
add: (middleware, options = {}) => {
|
|
2093
|
+
const { name, override, aliases: _aliases } = options;
|
|
2094
|
+
const entry = {
|
|
2095
|
+
step: "initialize",
|
|
2096
|
+
priority: "normal",
|
|
2097
|
+
middleware,
|
|
2098
|
+
...options,
|
|
2099
|
+
};
|
|
2100
|
+
const aliases = getAllAliases(name, _aliases);
|
|
2101
|
+
if (aliases.length > 0) {
|
|
2102
|
+
if (aliases.some((alias) => entriesNameSet.has(alias))) {
|
|
2103
|
+
if (!override)
|
|
2104
|
+
throw new Error(`Duplicate middleware name '${getMiddlewareNameWithAliases(name, _aliases)}'`);
|
|
2105
|
+
for (const alias of aliases) {
|
|
2106
|
+
const toOverrideIndex = absoluteEntries.findIndex((entry) => entry.name === alias || entry.aliases?.some((a) => a === alias));
|
|
2107
|
+
if (toOverrideIndex === -1) {
|
|
2108
|
+
continue;
|
|
2109
|
+
}
|
|
2110
|
+
const toOverride = absoluteEntries[toOverrideIndex];
|
|
2111
|
+
if (toOverride.step !== entry.step || entry.priority !== toOverride.priority) {
|
|
2112
|
+
throw new Error(`"${getMiddlewareNameWithAliases(toOverride.name, toOverride.aliases)}" middleware with ` +
|
|
2113
|
+
`${toOverride.priority} priority in ${toOverride.step} step cannot ` +
|
|
2114
|
+
`be overridden by "${getMiddlewareNameWithAliases(name, _aliases)}" middleware with ` +
|
|
2115
|
+
`${entry.priority} priority in ${entry.step} step.`);
|
|
2116
|
+
}
|
|
2117
|
+
absoluteEntries.splice(toOverrideIndex, 1);
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
for (const alias of aliases) {
|
|
2121
|
+
entriesNameSet.add(alias);
|
|
2122
|
+
}
|
|
2123
|
+
}
|
|
2124
|
+
absoluteEntries.push(entry);
|
|
2125
|
+
},
|
|
2126
|
+
addRelativeTo: (middleware, options) => {
|
|
2127
|
+
const { name, override, aliases: _aliases } = options;
|
|
2128
|
+
const entry = {
|
|
2129
|
+
middleware,
|
|
2130
|
+
...options,
|
|
2131
|
+
};
|
|
2132
|
+
const aliases = getAllAliases(name, _aliases);
|
|
2133
|
+
if (aliases.length > 0) {
|
|
2134
|
+
if (aliases.some((alias) => entriesNameSet.has(alias))) {
|
|
2135
|
+
if (!override)
|
|
2136
|
+
throw new Error(`Duplicate middleware name '${getMiddlewareNameWithAliases(name, _aliases)}'`);
|
|
2137
|
+
for (const alias of aliases) {
|
|
2138
|
+
const toOverrideIndex = relativeEntries.findIndex((entry) => entry.name === alias || entry.aliases?.some((a) => a === alias));
|
|
2139
|
+
if (toOverrideIndex === -1) {
|
|
2140
|
+
continue;
|
|
2141
|
+
}
|
|
2142
|
+
const toOverride = relativeEntries[toOverrideIndex];
|
|
2143
|
+
if (toOverride.toMiddleware !== entry.toMiddleware || toOverride.relation !== entry.relation) {
|
|
2144
|
+
throw new Error(`"${getMiddlewareNameWithAliases(toOverride.name, toOverride.aliases)}" middleware ` +
|
|
2145
|
+
`${toOverride.relation} "${toOverride.toMiddleware}" middleware cannot be overridden ` +
|
|
2146
|
+
`by "${getMiddlewareNameWithAliases(name, _aliases)}" middleware ${entry.relation} ` +
|
|
2147
|
+
`"${entry.toMiddleware}" middleware.`);
|
|
2148
|
+
}
|
|
2149
|
+
relativeEntries.splice(toOverrideIndex, 1);
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
for (const alias of aliases) {
|
|
2153
|
+
entriesNameSet.add(alias);
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
relativeEntries.push(entry);
|
|
2157
|
+
},
|
|
2158
|
+
clone: () => cloneTo(constructStack()),
|
|
2159
|
+
use: (plugin) => {
|
|
2160
|
+
plugin.applyToStack(stack);
|
|
2161
|
+
},
|
|
2162
|
+
remove: (toRemove) => {
|
|
2163
|
+
if (typeof toRemove === "string")
|
|
2164
|
+
return removeByName(toRemove);
|
|
2165
|
+
else
|
|
2166
|
+
return removeByReference(toRemove);
|
|
2167
|
+
},
|
|
2168
|
+
removeByTag: (toRemove) => {
|
|
2169
|
+
let isRemoved = false;
|
|
2170
|
+
const filterCb = (entry) => {
|
|
2171
|
+
const { tags, name, aliases: _aliases } = entry;
|
|
2172
|
+
if (tags && tags.includes(toRemove)) {
|
|
2173
|
+
const aliases = getAllAliases(name, _aliases);
|
|
2174
|
+
for (const alias of aliases) {
|
|
2175
|
+
entriesNameSet.delete(alias);
|
|
2176
|
+
}
|
|
2177
|
+
isRemoved = true;
|
|
2178
|
+
return false;
|
|
2179
|
+
}
|
|
2180
|
+
return true;
|
|
2181
|
+
};
|
|
2182
|
+
absoluteEntries = absoluteEntries.filter(filterCb);
|
|
2183
|
+
relativeEntries = relativeEntries.filter(filterCb);
|
|
2184
|
+
return isRemoved;
|
|
2185
|
+
},
|
|
2186
|
+
concat: (from) => {
|
|
2187
|
+
const cloned = cloneTo(constructStack());
|
|
2188
|
+
cloned.use(from);
|
|
2189
|
+
cloned.identifyOnResolve(identifyOnResolve || cloned.identifyOnResolve() || (from.identifyOnResolve?.() ?? false));
|
|
2190
|
+
return cloned;
|
|
2191
|
+
},
|
|
2192
|
+
applyToStack: cloneTo,
|
|
2193
|
+
identify: () => {
|
|
2194
|
+
return getMiddlewareList(true).map((mw) => {
|
|
2195
|
+
const step = mw.step ??
|
|
2196
|
+
mw.relation +
|
|
2197
|
+
" " +
|
|
2198
|
+
mw.toMiddleware;
|
|
2199
|
+
return getMiddlewareNameWithAliases(mw.name, mw.aliases) + " - " + step;
|
|
2200
|
+
});
|
|
2201
|
+
},
|
|
2202
|
+
identifyOnResolve(toggle) {
|
|
2203
|
+
if (typeof toggle === "boolean")
|
|
2204
|
+
identifyOnResolve = toggle;
|
|
2205
|
+
return identifyOnResolve;
|
|
2206
|
+
},
|
|
2207
|
+
resolve: (handler, context) => {
|
|
2208
|
+
for (const middleware of getMiddlewareList()
|
|
2209
|
+
.map((entry) => entry.middleware)
|
|
2210
|
+
.reverse()) {
|
|
2211
|
+
handler = middleware(handler, context);
|
|
2212
|
+
}
|
|
2213
|
+
if (identifyOnResolve) {
|
|
2214
|
+
console.log(stack.identify());
|
|
2215
|
+
}
|
|
2216
|
+
return handler;
|
|
2217
|
+
},
|
|
2218
|
+
};
|
|
2219
|
+
return stack;
|
|
2220
|
+
};
|
|
2221
|
+
const stepWeights = {
|
|
2222
|
+
initialize: 5,
|
|
2223
|
+
serialize: 4,
|
|
2224
|
+
build: 3,
|
|
2225
|
+
finalizeRequest: 2,
|
|
2226
|
+
deserialize: 1,
|
|
2227
|
+
};
|
|
2228
|
+
const priorityWeights = {
|
|
2229
|
+
high: 3,
|
|
2230
|
+
normal: 2,
|
|
2231
|
+
low: 1,
|
|
2232
|
+
};
|
|
2233
|
+
|
|
2234
|
+
class Client {
|
|
2235
|
+
constructor(config) {
|
|
2236
|
+
this.config = config;
|
|
2237
|
+
this.middlewareStack = constructStack();
|
|
2238
|
+
}
|
|
2239
|
+
send(command, optionsOrCb, cb) {
|
|
2240
|
+
const options = typeof optionsOrCb !== "function" ? optionsOrCb : undefined;
|
|
2241
|
+
const callback = typeof optionsOrCb === "function" ? optionsOrCb : cb;
|
|
2242
|
+
const useHandlerCache = options === undefined && this.config.cacheMiddleware === true;
|
|
2243
|
+
let handler;
|
|
2244
|
+
if (useHandlerCache) {
|
|
2245
|
+
if (!this.handlers) {
|
|
2246
|
+
this.handlers = new WeakMap();
|
|
2247
|
+
}
|
|
2248
|
+
const handlers = this.handlers;
|
|
2249
|
+
if (handlers.has(command.constructor)) {
|
|
2250
|
+
handler = handlers.get(command.constructor);
|
|
2251
|
+
}
|
|
2252
|
+
else {
|
|
2253
|
+
handler = command.resolveMiddleware(this.middlewareStack, this.config, options);
|
|
2254
|
+
handlers.set(command.constructor, handler);
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
else {
|
|
2258
|
+
delete this.handlers;
|
|
2259
|
+
handler = command.resolveMiddleware(this.middlewareStack, this.config, options);
|
|
2260
|
+
}
|
|
2261
|
+
if (callback) {
|
|
2262
|
+
handler(command)
|
|
2263
|
+
.then((result) => callback(null, result.output), (err) => callback(err))
|
|
2264
|
+
.catch(() => { });
|
|
2265
|
+
}
|
|
2266
|
+
else {
|
|
2267
|
+
return handler(command).then((result) => result.output);
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
destroy() {
|
|
2271
|
+
this.config?.requestHandler?.destroy?.();
|
|
2272
|
+
delete this.handlers;
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2275
|
+
|
|
2276
|
+
class Command {
|
|
2277
|
+
constructor() {
|
|
2278
|
+
this.middlewareStack = constructStack();
|
|
2279
|
+
}
|
|
2280
|
+
static classBuilder() {
|
|
2281
|
+
return new ClassBuilder();
|
|
2282
|
+
}
|
|
2283
|
+
resolveMiddlewareWithContext(clientStack, configuration, options, { middlewareFn, clientName, commandName, inputFilterSensitiveLog, outputFilterSensitiveLog, smithyContext, additionalContext, CommandCtor, }) {
|
|
2284
|
+
for (const mw of middlewareFn.bind(this)(CommandCtor, clientStack, configuration, options)) {
|
|
2285
|
+
this.middlewareStack.use(mw);
|
|
2286
|
+
}
|
|
2287
|
+
const stack = clientStack.concat(this.middlewareStack);
|
|
2288
|
+
const { logger } = configuration;
|
|
2289
|
+
const handlerExecutionContext = {
|
|
2290
|
+
logger,
|
|
2291
|
+
clientName,
|
|
2292
|
+
commandName,
|
|
2293
|
+
inputFilterSensitiveLog,
|
|
2294
|
+
outputFilterSensitiveLog,
|
|
2295
|
+
[SMITHY_CONTEXT_KEY]: {
|
|
2296
|
+
commandInstance: this,
|
|
2297
|
+
...smithyContext,
|
|
2298
|
+
},
|
|
2299
|
+
...additionalContext,
|
|
2300
|
+
};
|
|
2301
|
+
const { requestHandler } = configuration;
|
|
2302
|
+
return stack.resolve((request) => requestHandler.handle(request.request, options || {}), handlerExecutionContext);
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
class ClassBuilder {
|
|
2306
|
+
constructor() {
|
|
2307
|
+
this._init = () => { };
|
|
2308
|
+
this._ep = {};
|
|
2309
|
+
this._middlewareFn = () => [];
|
|
2310
|
+
this._commandName = "";
|
|
2311
|
+
this._clientName = "";
|
|
2312
|
+
this._additionalContext = {};
|
|
2313
|
+
this._smithyContext = {};
|
|
2314
|
+
this._inputFilterSensitiveLog = (_) => _;
|
|
2315
|
+
this._outputFilterSensitiveLog = (_) => _;
|
|
2316
|
+
this._serializer = null;
|
|
2317
|
+
this._deserializer = null;
|
|
2318
|
+
}
|
|
2319
|
+
init(cb) {
|
|
2320
|
+
this._init = cb;
|
|
2321
|
+
}
|
|
2322
|
+
ep(endpointParameterInstructions) {
|
|
2323
|
+
this._ep = endpointParameterInstructions;
|
|
2324
|
+
return this;
|
|
2325
|
+
}
|
|
2326
|
+
m(middlewareSupplier) {
|
|
2327
|
+
this._middlewareFn = middlewareSupplier;
|
|
2328
|
+
return this;
|
|
2329
|
+
}
|
|
2330
|
+
s(service, operation, smithyContext = {}) {
|
|
2331
|
+
this._smithyContext = {
|
|
2332
|
+
service,
|
|
2333
|
+
operation,
|
|
2334
|
+
...smithyContext,
|
|
2335
|
+
};
|
|
2336
|
+
return this;
|
|
2337
|
+
}
|
|
2338
|
+
c(additionalContext = {}) {
|
|
2339
|
+
this._additionalContext = additionalContext;
|
|
2340
|
+
return this;
|
|
2341
|
+
}
|
|
2342
|
+
n(clientName, commandName) {
|
|
2343
|
+
this._clientName = clientName;
|
|
2344
|
+
this._commandName = commandName;
|
|
2345
|
+
return this;
|
|
2346
|
+
}
|
|
2347
|
+
f(inputFilter = (_) => _, outputFilter = (_) => _) {
|
|
2348
|
+
this._inputFilterSensitiveLog = inputFilter;
|
|
2349
|
+
this._outputFilterSensitiveLog = outputFilter;
|
|
2350
|
+
return this;
|
|
2351
|
+
}
|
|
2352
|
+
ser(serializer) {
|
|
2353
|
+
this._serializer = serializer;
|
|
2354
|
+
return this;
|
|
2355
|
+
}
|
|
2356
|
+
de(deserializer) {
|
|
2357
|
+
this._deserializer = deserializer;
|
|
2358
|
+
return this;
|
|
2359
|
+
}
|
|
2360
|
+
build() {
|
|
2361
|
+
const closure = this;
|
|
2362
|
+
let CommandRef;
|
|
2363
|
+
return (CommandRef = class extends Command {
|
|
2364
|
+
static getEndpointParameterInstructions() {
|
|
2365
|
+
return closure._ep;
|
|
2366
|
+
}
|
|
2367
|
+
constructor(...[input]) {
|
|
2368
|
+
super();
|
|
2369
|
+
this.serialize = closure._serializer;
|
|
2370
|
+
this.deserialize = closure._deserializer;
|
|
2371
|
+
this.input = input ?? {};
|
|
2372
|
+
closure._init(this);
|
|
2373
|
+
}
|
|
2374
|
+
resolveMiddleware(stack, configuration, options) {
|
|
2375
|
+
return this.resolveMiddlewareWithContext(stack, configuration, options, {
|
|
2376
|
+
CommandCtor: CommandRef,
|
|
2377
|
+
middlewareFn: closure._middlewareFn,
|
|
2378
|
+
clientName: closure._clientName,
|
|
2379
|
+
commandName: closure._commandName,
|
|
2380
|
+
inputFilterSensitiveLog: closure._inputFilterSensitiveLog,
|
|
2381
|
+
outputFilterSensitiveLog: closure._outputFilterSensitiveLog,
|
|
2382
|
+
smithyContext: closure._smithyContext,
|
|
2383
|
+
additionalContext: closure._additionalContext,
|
|
2384
|
+
});
|
|
2385
|
+
}
|
|
2386
|
+
});
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2389
|
+
|
|
2390
|
+
const SENSITIVE_STRING = "***SensitiveInformation***";
|
|
2391
|
+
|
|
2392
|
+
class ServiceException extends Error {
|
|
2393
|
+
constructor(options) {
|
|
2394
|
+
super(options.message);
|
|
2395
|
+
Object.setPrototypeOf(this, ServiceException.prototype);
|
|
2396
|
+
this.name = options.name;
|
|
2397
|
+
this.$fault = options.$fault;
|
|
2398
|
+
this.$metadata = options.$metadata;
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
const decorateServiceException = (exception, additions = {}) => {
|
|
2402
|
+
Object.entries(additions)
|
|
2403
|
+
.filter(([, v]) => v !== undefined)
|
|
2404
|
+
.forEach(([k, v]) => {
|
|
2405
|
+
if (exception[k] == undefined || exception[k] === "") {
|
|
2406
|
+
exception[k] = v;
|
|
2407
|
+
}
|
|
2408
|
+
});
|
|
2409
|
+
const message = exception.message || exception.Message || "UnknownError";
|
|
2410
|
+
exception.message = message;
|
|
2411
|
+
delete exception.Message;
|
|
2412
|
+
return exception;
|
|
2413
|
+
};
|
|
2414
|
+
|
|
2415
|
+
const throwDefaultError = ({ output, parsedBody, exceptionCtor, errorCode }) => {
|
|
2416
|
+
const $metadata = deserializeMetadata(output);
|
|
2417
|
+
const statusCode = $metadata.httpStatusCode ? $metadata.httpStatusCode + "" : undefined;
|
|
2418
|
+
const response = new exceptionCtor({
|
|
2419
|
+
name: parsedBody?.code || parsedBody?.Code || errorCode || statusCode || "UnknownError",
|
|
2420
|
+
$fault: "client",
|
|
2421
|
+
$metadata,
|
|
2422
|
+
});
|
|
2423
|
+
throw decorateServiceException(response, parsedBody);
|
|
2424
|
+
};
|
|
2425
|
+
const withBaseException = (ExceptionCtor) => {
|
|
2426
|
+
return ({ output, parsedBody, errorCode }) => {
|
|
2427
|
+
throwDefaultError({ output, parsedBody, exceptionCtor: ExceptionCtor, errorCode });
|
|
2428
|
+
};
|
|
2429
|
+
};
|
|
2430
|
+
const deserializeMetadata = (output) => ({
|
|
2431
|
+
httpStatusCode: output.statusCode,
|
|
2432
|
+
requestId: output.headers["x-amzn-requestid"] ?? output.headers["x-amzn-request-id"] ?? output.headers["x-amz-request-id"],
|
|
2433
|
+
extendedRequestId: output.headers["x-amz-id-2"],
|
|
2434
|
+
cfId: output.headers["x-amz-cf-id"],
|
|
2435
|
+
});
|
|
2436
|
+
|
|
2437
|
+
const loadConfigsForDefaultMode = (mode) => {
|
|
2438
|
+
switch (mode) {
|
|
2439
|
+
case "standard":
|
|
2440
|
+
return {
|
|
2441
|
+
retryMode: "standard",
|
|
2442
|
+
connectionTimeout: 3100,
|
|
2443
|
+
};
|
|
2444
|
+
case "in-region":
|
|
2445
|
+
return {
|
|
2446
|
+
retryMode: "standard",
|
|
2447
|
+
connectionTimeout: 1100,
|
|
2448
|
+
};
|
|
2449
|
+
case "cross-region":
|
|
2450
|
+
return {
|
|
2451
|
+
retryMode: "standard",
|
|
2452
|
+
connectionTimeout: 3100,
|
|
2453
|
+
};
|
|
2454
|
+
case "mobile":
|
|
2455
|
+
return {
|
|
2456
|
+
retryMode: "standard",
|
|
2457
|
+
connectionTimeout: 30000,
|
|
2458
|
+
};
|
|
2459
|
+
default:
|
|
2460
|
+
return {};
|
|
2461
|
+
}
|
|
2462
|
+
};
|
|
2463
|
+
|
|
2464
|
+
let warningEmitted = false;
|
|
2465
|
+
const emitWarningIfUnsupportedVersion = (version) => {
|
|
2466
|
+
if (version && !warningEmitted && parseInt(version.substring(1, version.indexOf("."))) < 16) {
|
|
2467
|
+
warningEmitted = true;
|
|
2468
|
+
}
|
|
2469
|
+
};
|
|
2470
|
+
|
|
2471
|
+
const getChecksumConfiguration = (runtimeConfig) => {
|
|
2472
|
+
const checksumAlgorithms = [];
|
|
2473
|
+
for (const id in AlgorithmId) {
|
|
2474
|
+
const algorithmId = AlgorithmId[id];
|
|
2475
|
+
if (runtimeConfig[algorithmId] === undefined) {
|
|
2476
|
+
continue;
|
|
2477
|
+
}
|
|
2478
|
+
checksumAlgorithms.push({
|
|
2479
|
+
algorithmId: () => algorithmId,
|
|
2480
|
+
checksumConstructor: () => runtimeConfig[algorithmId],
|
|
2481
|
+
});
|
|
2482
|
+
}
|
|
2483
|
+
return {
|
|
2484
|
+
_checksumAlgorithms: checksumAlgorithms,
|
|
2485
|
+
addChecksumAlgorithm(algo) {
|
|
2486
|
+
this._checksumAlgorithms.push(algo);
|
|
2487
|
+
},
|
|
2488
|
+
checksumAlgorithms() {
|
|
2489
|
+
return this._checksumAlgorithms;
|
|
2490
|
+
},
|
|
2491
|
+
};
|
|
2492
|
+
};
|
|
2493
|
+
const resolveChecksumRuntimeConfig = (clientConfig) => {
|
|
2494
|
+
const runtimeConfig = {};
|
|
2495
|
+
clientConfig.checksumAlgorithms().forEach((checksumAlgorithm) => {
|
|
2496
|
+
runtimeConfig[checksumAlgorithm.algorithmId()] = checksumAlgorithm.checksumConstructor();
|
|
2497
|
+
});
|
|
2498
|
+
return runtimeConfig;
|
|
2499
|
+
};
|
|
2500
|
+
|
|
2501
|
+
const getRetryConfiguration = (runtimeConfig) => {
|
|
2502
|
+
let _retryStrategy = runtimeConfig.retryStrategy;
|
|
2503
|
+
return {
|
|
2504
|
+
setRetryStrategy(retryStrategy) {
|
|
2505
|
+
_retryStrategy = retryStrategy;
|
|
2506
|
+
},
|
|
2507
|
+
retryStrategy() {
|
|
2508
|
+
return _retryStrategy;
|
|
2509
|
+
},
|
|
2510
|
+
};
|
|
2511
|
+
};
|
|
2512
|
+
const resolveRetryRuntimeConfig = (retryStrategyConfiguration) => {
|
|
2513
|
+
const runtimeConfig = {};
|
|
2514
|
+
runtimeConfig.retryStrategy = retryStrategyConfiguration.retryStrategy();
|
|
2515
|
+
return runtimeConfig;
|
|
2516
|
+
};
|
|
2517
|
+
|
|
2518
|
+
const getDefaultExtensionConfiguration = (runtimeConfig) => {
|
|
2519
|
+
return {
|
|
2520
|
+
...getChecksumConfiguration(runtimeConfig),
|
|
2521
|
+
...getRetryConfiguration(runtimeConfig),
|
|
2522
|
+
};
|
|
2523
|
+
};
|
|
2524
|
+
const resolveDefaultRuntimeConfig = (config) => {
|
|
2525
|
+
return {
|
|
2526
|
+
...resolveChecksumRuntimeConfig(config),
|
|
2527
|
+
...resolveRetryRuntimeConfig(config),
|
|
2528
|
+
};
|
|
2529
|
+
};
|
|
2530
|
+
|
|
2531
|
+
class NoOpLogger {
|
|
2532
|
+
trace() { }
|
|
2533
|
+
debug() { }
|
|
2534
|
+
info() { }
|
|
2535
|
+
warn() { }
|
|
2536
|
+
error() { }
|
|
2537
|
+
}
|
|
2538
|
+
|
|
2539
|
+
const collectBodyString = (streamBody, context) => collectBody(streamBody, context).then((body) => context.utf8Encoder(body));
|
|
2540
|
+
|
|
2541
|
+
const ACCOUNT_ID_ENDPOINT_REGEX = /\d{12}\.ddb/;
|
|
2542
|
+
async function checkFeatures(context, config, args) {
|
|
2543
|
+
const request = args.request;
|
|
2544
|
+
if (request?.headers?.["smithy-protocol"] === "rpc-v2-cbor") {
|
|
2545
|
+
setFeature(context, "PROTOCOL_RPC_V2_CBOR", "M");
|
|
2546
|
+
}
|
|
2547
|
+
if (typeof config.retryStrategy === "function") {
|
|
2548
|
+
const retryStrategy = await config.retryStrategy();
|
|
2549
|
+
if (typeof retryStrategy.acquireInitialRetryToken === "function") {
|
|
2550
|
+
if (retryStrategy.constructor?.name?.includes("Adaptive")) {
|
|
2551
|
+
setFeature(context, "RETRY_MODE_ADAPTIVE", "F");
|
|
2552
|
+
}
|
|
2553
|
+
else {
|
|
2554
|
+
setFeature(context, "RETRY_MODE_STANDARD", "E");
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
else {
|
|
2558
|
+
setFeature(context, "RETRY_MODE_LEGACY", "D");
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2561
|
+
if (typeof config.accountIdEndpointMode === "function") {
|
|
2562
|
+
const endpointV2 = context.endpointV2;
|
|
2563
|
+
if (String(endpointV2?.url?.hostname).match(ACCOUNT_ID_ENDPOINT_REGEX)) {
|
|
2564
|
+
setFeature(context, "ACCOUNT_ID_ENDPOINT", "O");
|
|
2565
|
+
}
|
|
2566
|
+
switch (await config.accountIdEndpointMode?.()) {
|
|
2567
|
+
case "disabled":
|
|
2568
|
+
setFeature(context, "ACCOUNT_ID_MODE_DISABLED", "Q");
|
|
2569
|
+
break;
|
|
2570
|
+
case "preferred":
|
|
2571
|
+
setFeature(context, "ACCOUNT_ID_MODE_PREFERRED", "P");
|
|
2572
|
+
break;
|
|
2573
|
+
case "required":
|
|
2574
|
+
setFeature(context, "ACCOUNT_ID_MODE_REQUIRED", "R");
|
|
2575
|
+
break;
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2578
|
+
const identity = context.__smithy_context?.selectedHttpAuthScheme?.identity;
|
|
2579
|
+
if (identity?.$source) {
|
|
2580
|
+
const credentials = identity;
|
|
2581
|
+
if (credentials.accountId) {
|
|
2582
|
+
setFeature(context, "RESOLVED_ACCOUNT_ID", "T");
|
|
2583
|
+
}
|
|
2584
|
+
for (const [key, value] of Object.entries(credentials.$source ?? {})) {
|
|
2585
|
+
setFeature(context, key, value);
|
|
2586
|
+
}
|
|
2587
|
+
}
|
|
2588
|
+
}
|
|
2589
|
+
|
|
2590
|
+
const USER_AGENT = "user-agent";
|
|
2591
|
+
const X_AMZ_USER_AGENT = "x-amz-user-agent";
|
|
2592
|
+
const SPACE = " ";
|
|
2593
|
+
const UA_NAME_SEPARATOR = "/";
|
|
2594
|
+
const UA_NAME_ESCAPE_REGEX = /[^\!\$\%\&\'\*\+\-\.\^\_\`\|\~\d\w]/g;
|
|
2595
|
+
const UA_VALUE_ESCAPE_REGEX = /[^\!\$\%\&\'\*\+\-\.\^\_\`\|\~\d\w\#]/g;
|
|
2596
|
+
const UA_ESCAPE_CHAR = "-";
|
|
2597
|
+
|
|
2598
|
+
const BYTE_LIMIT = 1024;
|
|
2599
|
+
function encodeFeatures(features) {
|
|
2600
|
+
let buffer = "";
|
|
2601
|
+
for (const key in features) {
|
|
2602
|
+
const val = features[key];
|
|
2603
|
+
if (buffer.length + val.length + 1 <= BYTE_LIMIT) {
|
|
2604
|
+
if (buffer.length) {
|
|
2605
|
+
buffer += "," + val;
|
|
2606
|
+
}
|
|
2607
|
+
else {
|
|
2608
|
+
buffer += val;
|
|
2609
|
+
}
|
|
2610
|
+
continue;
|
|
2611
|
+
}
|
|
2612
|
+
break;
|
|
2613
|
+
}
|
|
2614
|
+
return buffer;
|
|
2615
|
+
}
|
|
2616
|
+
|
|
2617
|
+
const userAgentMiddleware = (options) => (next, context) => async (args) => {
|
|
2618
|
+
const { request } = args;
|
|
2619
|
+
if (!HttpRequest.isInstance(request)) {
|
|
2620
|
+
return next(args);
|
|
2621
|
+
}
|
|
2622
|
+
const { headers } = request;
|
|
2623
|
+
const userAgent = context?.userAgent?.map(escapeUserAgent) || [];
|
|
2624
|
+
const defaultUserAgent = (await options.defaultUserAgentProvider()).map(escapeUserAgent);
|
|
2625
|
+
await checkFeatures(context, options, args);
|
|
2626
|
+
const awsContext = context;
|
|
2627
|
+
defaultUserAgent.push(`m/${encodeFeatures(Object.assign({}, context.__smithy_context?.features, awsContext.__aws_sdk_context?.features))}`);
|
|
2628
|
+
const customUserAgent = options?.customUserAgent?.map(escapeUserAgent) || [];
|
|
2629
|
+
const appId = await options.userAgentAppId();
|
|
2630
|
+
if (appId) {
|
|
2631
|
+
defaultUserAgent.push(escapeUserAgent([`app/${appId}`]));
|
|
2632
|
+
}
|
|
2633
|
+
const sdkUserAgentValue = ([])
|
|
2634
|
+
.concat([...defaultUserAgent, ...userAgent, ...customUserAgent])
|
|
2635
|
+
.join(SPACE);
|
|
2636
|
+
const normalUAValue = [
|
|
2637
|
+
...defaultUserAgent.filter((section) => section.startsWith("aws-sdk-")),
|
|
2638
|
+
...customUserAgent,
|
|
2639
|
+
].join(SPACE);
|
|
2640
|
+
if (options.runtime !== "browser") {
|
|
2641
|
+
if (normalUAValue) {
|
|
2642
|
+
headers[X_AMZ_USER_AGENT] = headers[X_AMZ_USER_AGENT]
|
|
2643
|
+
? `${headers[USER_AGENT]} ${normalUAValue}`
|
|
2644
|
+
: normalUAValue;
|
|
2645
|
+
}
|
|
2646
|
+
headers[USER_AGENT] = sdkUserAgentValue;
|
|
2647
|
+
}
|
|
2648
|
+
else {
|
|
2649
|
+
headers[X_AMZ_USER_AGENT] = sdkUserAgentValue;
|
|
2650
|
+
}
|
|
2651
|
+
return next({
|
|
2652
|
+
...args,
|
|
2653
|
+
request,
|
|
2654
|
+
});
|
|
2655
|
+
};
|
|
2656
|
+
const escapeUserAgent = (userAgentPair) => {
|
|
2657
|
+
const name = userAgentPair[0]
|
|
2658
|
+
.split(UA_NAME_SEPARATOR)
|
|
2659
|
+
.map((part) => part.replace(UA_NAME_ESCAPE_REGEX, UA_ESCAPE_CHAR))
|
|
2660
|
+
.join(UA_NAME_SEPARATOR);
|
|
2661
|
+
const version = userAgentPair[1]?.replace(UA_VALUE_ESCAPE_REGEX, UA_ESCAPE_CHAR);
|
|
2662
|
+
const prefixSeparatorIndex = name.indexOf(UA_NAME_SEPARATOR);
|
|
2663
|
+
const prefix = name.substring(0, prefixSeparatorIndex);
|
|
2664
|
+
let uaName = name.substring(prefixSeparatorIndex + 1);
|
|
2665
|
+
if (prefix === "api") {
|
|
2666
|
+
uaName = uaName.toLowerCase();
|
|
2667
|
+
}
|
|
2668
|
+
return [prefix, uaName, version]
|
|
2669
|
+
.filter((item) => item && item.length > 0)
|
|
2670
|
+
.reduce((acc, item, index) => {
|
|
2671
|
+
switch (index) {
|
|
2672
|
+
case 0:
|
|
2673
|
+
return item;
|
|
2674
|
+
case 1:
|
|
2675
|
+
return `${acc}/${item}`;
|
|
2676
|
+
default:
|
|
2677
|
+
return `${acc}#${item}`;
|
|
2678
|
+
}
|
|
2679
|
+
}, "");
|
|
2680
|
+
};
|
|
2681
|
+
const getUserAgentMiddlewareOptions = {
|
|
2682
|
+
name: "getUserAgentMiddleware",
|
|
2683
|
+
step: "build",
|
|
2684
|
+
priority: "low",
|
|
2685
|
+
tags: ["SET_USER_AGENT", "USER_AGENT"],
|
|
2686
|
+
override: true,
|
|
2687
|
+
};
|
|
2688
|
+
const getUserAgentPlugin = (config) => ({
|
|
2689
|
+
applyToStack: (clientStack) => {
|
|
2690
|
+
clientStack.add(userAgentMiddleware(config), getUserAgentMiddlewareOptions);
|
|
2691
|
+
},
|
|
2692
|
+
});
|
|
2693
|
+
|
|
2694
|
+
const booleanSelector = (obj, key, type) => {
|
|
2695
|
+
if (!(key in obj))
|
|
2696
|
+
return undefined;
|
|
2697
|
+
if (obj[key] === "true")
|
|
2698
|
+
return true;
|
|
2699
|
+
if (obj[key] === "false")
|
|
2700
|
+
return false;
|
|
2701
|
+
throw new Error(`Cannot load ${type} "${key}". Expected "true" or "false", got ${obj[key]}.`);
|
|
2702
|
+
};
|
|
2703
|
+
|
|
2704
|
+
var SelectorType;
|
|
2705
|
+
(function (SelectorType) {
|
|
2706
|
+
SelectorType["ENV"] = "env";
|
|
2707
|
+
SelectorType["CONFIG"] = "shared config entry";
|
|
2708
|
+
})(SelectorType || (SelectorType = {}));
|
|
2709
|
+
|
|
2710
|
+
const ENV_USE_DUALSTACK_ENDPOINT = "AWS_USE_DUALSTACK_ENDPOINT";
|
|
2711
|
+
const CONFIG_USE_DUALSTACK_ENDPOINT = "use_dualstack_endpoint";
|
|
2712
|
+
const NODE_USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS = {
|
|
2713
|
+
environmentVariableSelector: (env) => booleanSelector(env, ENV_USE_DUALSTACK_ENDPOINT, SelectorType.ENV),
|
|
2714
|
+
configFileSelector: (profile) => booleanSelector(profile, CONFIG_USE_DUALSTACK_ENDPOINT, SelectorType.CONFIG),
|
|
2715
|
+
default: false,
|
|
2716
|
+
};
|
|
2717
|
+
|
|
2718
|
+
const ENV_USE_FIPS_ENDPOINT = "AWS_USE_FIPS_ENDPOINT";
|
|
2719
|
+
const CONFIG_USE_FIPS_ENDPOINT = "use_fips_endpoint";
|
|
2720
|
+
const NODE_USE_FIPS_ENDPOINT_CONFIG_OPTIONS = {
|
|
2721
|
+
environmentVariableSelector: (env) => booleanSelector(env, ENV_USE_FIPS_ENDPOINT, SelectorType.ENV),
|
|
2722
|
+
configFileSelector: (profile) => booleanSelector(profile, CONFIG_USE_FIPS_ENDPOINT, SelectorType.CONFIG),
|
|
2723
|
+
default: false,
|
|
2724
|
+
};
|
|
2725
|
+
|
|
2726
|
+
const REGION_ENV_NAME = "AWS_REGION";
|
|
2727
|
+
const REGION_INI_NAME = "region";
|
|
2728
|
+
const NODE_REGION_CONFIG_OPTIONS = {
|
|
2729
|
+
environmentVariableSelector: (env) => env[REGION_ENV_NAME],
|
|
2730
|
+
configFileSelector: (profile) => profile[REGION_INI_NAME],
|
|
2731
|
+
default: () => {
|
|
2732
|
+
throw new Error("Region is missing");
|
|
2733
|
+
},
|
|
2734
|
+
};
|
|
2735
|
+
const NODE_REGION_CONFIG_FILE_OPTIONS = {
|
|
2736
|
+
preferredFile: "credentials",
|
|
2737
|
+
};
|
|
2738
|
+
|
|
2739
|
+
const isFipsRegion = (region) => typeof region === "string" && (region.startsWith("fips-") || region.endsWith("-fips"));
|
|
2740
|
+
|
|
2741
|
+
const getRealRegion = (region) => isFipsRegion(region)
|
|
2742
|
+
? ["fips-aws-global", "aws-fips"].includes(region)
|
|
2743
|
+
? "us-east-1"
|
|
2744
|
+
: region.replace(/fips-(dkr-|prod-)?|-fips/, "")
|
|
2745
|
+
: region;
|
|
2746
|
+
|
|
2747
|
+
const resolveRegionConfig = (input) => {
|
|
2748
|
+
const { region, useFipsEndpoint } = input;
|
|
2749
|
+
if (!region) {
|
|
2750
|
+
throw new Error("Region is missing");
|
|
2751
|
+
}
|
|
2752
|
+
return {
|
|
2753
|
+
...input,
|
|
2754
|
+
region: async () => {
|
|
2755
|
+
if (typeof region === "string") {
|
|
2756
|
+
return getRealRegion(region);
|
|
2757
|
+
}
|
|
2758
|
+
const providedRegion = await region();
|
|
2759
|
+
return getRealRegion(providedRegion);
|
|
2760
|
+
},
|
|
2761
|
+
useFipsEndpoint: async () => {
|
|
2762
|
+
const providedRegion = typeof region === "string" ? region : await region();
|
|
2763
|
+
if (isFipsRegion(providedRegion)) {
|
|
2764
|
+
return true;
|
|
2765
|
+
}
|
|
2766
|
+
return typeof useFipsEndpoint !== "function" ? Promise.resolve(!!useFipsEndpoint) : useFipsEndpoint();
|
|
2767
|
+
},
|
|
2768
|
+
};
|
|
2769
|
+
};
|
|
2770
|
+
|
|
2771
|
+
const CONTENT_LENGTH_HEADER = "content-length";
|
|
2772
|
+
function contentLengthMiddleware(bodyLengthChecker) {
|
|
2773
|
+
return (next) => async (args) => {
|
|
2774
|
+
const request = args.request;
|
|
2775
|
+
if (HttpRequest.isInstance(request)) {
|
|
2776
|
+
const { body, headers } = request;
|
|
2777
|
+
if (body &&
|
|
2778
|
+
Object.keys(headers)
|
|
2779
|
+
.map((str) => str.toLowerCase())
|
|
2780
|
+
.indexOf(CONTENT_LENGTH_HEADER) === -1) {
|
|
2781
|
+
try {
|
|
2782
|
+
const length = bodyLengthChecker(body);
|
|
2783
|
+
request.headers = {
|
|
2784
|
+
...request.headers,
|
|
2785
|
+
[CONTENT_LENGTH_HEADER]: String(length),
|
|
2786
|
+
};
|
|
2787
|
+
}
|
|
2788
|
+
catch (error) {
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2792
|
+
return next({
|
|
2793
|
+
...args,
|
|
2794
|
+
request,
|
|
2795
|
+
});
|
|
2796
|
+
};
|
|
2797
|
+
}
|
|
2798
|
+
const contentLengthMiddlewareOptions = {
|
|
2799
|
+
step: "build",
|
|
2800
|
+
tags: ["SET_CONTENT_LENGTH", "CONTENT_LENGTH"],
|
|
2801
|
+
name: "contentLengthMiddleware",
|
|
2802
|
+
override: true,
|
|
2803
|
+
};
|
|
2804
|
+
const getContentLengthPlugin = (options) => ({
|
|
2805
|
+
applyToStack: (clientStack) => {
|
|
2806
|
+
clientStack.add(contentLengthMiddleware(options.bodyLengthChecker), contentLengthMiddlewareOptions);
|
|
2807
|
+
},
|
|
2808
|
+
});
|
|
2809
|
+
|
|
2810
|
+
const resolveParamsForS3 = async (endpointParams) => {
|
|
2811
|
+
const bucket = endpointParams?.Bucket || "";
|
|
2812
|
+
if (typeof endpointParams.Bucket === "string") {
|
|
2813
|
+
endpointParams.Bucket = bucket.replace(/#/g, encodeURIComponent("#")).replace(/\?/g, encodeURIComponent("?"));
|
|
2814
|
+
}
|
|
2815
|
+
if (isArnBucketName(bucket)) {
|
|
2816
|
+
if (endpointParams.ForcePathStyle === true) {
|
|
2817
|
+
throw new Error("Path-style addressing cannot be used with ARN buckets");
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
else if (!isDnsCompatibleBucketName(bucket) ||
|
|
2821
|
+
(bucket.indexOf(".") !== -1 && !String(endpointParams.Endpoint).startsWith("http:")) ||
|
|
2822
|
+
bucket.toLowerCase() !== bucket ||
|
|
2823
|
+
bucket.length < 3) {
|
|
2824
|
+
endpointParams.ForcePathStyle = true;
|
|
2825
|
+
}
|
|
2826
|
+
if (endpointParams.DisableMultiRegionAccessPoints) {
|
|
2827
|
+
endpointParams.disableMultiRegionAccessPoints = true;
|
|
2828
|
+
endpointParams.DisableMRAP = true;
|
|
2829
|
+
}
|
|
2830
|
+
return endpointParams;
|
|
2831
|
+
};
|
|
2832
|
+
const DOMAIN_PATTERN = /^[a-z0-9][a-z0-9\.\-]{1,61}[a-z0-9]$/;
|
|
2833
|
+
const IP_ADDRESS_PATTERN = /(\d+\.){3}\d+/;
|
|
2834
|
+
const DOTS_PATTERN = /\.\./;
|
|
2835
|
+
const isDnsCompatibleBucketName = (bucketName) => DOMAIN_PATTERN.test(bucketName) && !IP_ADDRESS_PATTERN.test(bucketName) && !DOTS_PATTERN.test(bucketName);
|
|
2836
|
+
const isArnBucketName = (bucketName) => {
|
|
2837
|
+
const [arn, partition, service, , , bucket] = bucketName.split(":");
|
|
2838
|
+
const isArn = arn === "arn" && bucketName.split(":").length >= 6;
|
|
2839
|
+
const isValidArn = Boolean(isArn && partition && service && bucket);
|
|
2840
|
+
if (isArn && !isValidArn) {
|
|
2841
|
+
throw new Error(`Invalid ARN: ${bucketName} was an invalid ARN.`);
|
|
2842
|
+
}
|
|
2843
|
+
return isValidArn;
|
|
2844
|
+
};
|
|
2845
|
+
|
|
2846
|
+
const createConfigValueProvider = (configKey, canonicalEndpointParamKey, config) => {
|
|
2847
|
+
const configProvider = async () => {
|
|
2848
|
+
const configValue = config[configKey] ?? config[canonicalEndpointParamKey];
|
|
2849
|
+
if (typeof configValue === "function") {
|
|
2850
|
+
return configValue();
|
|
2851
|
+
}
|
|
2852
|
+
return configValue;
|
|
2853
|
+
};
|
|
2854
|
+
if (configKey === "credentialScope" || canonicalEndpointParamKey === "CredentialScope") {
|
|
2855
|
+
return async () => {
|
|
2856
|
+
const credentials = typeof config.credentials === "function" ? await config.credentials() : config.credentials;
|
|
2857
|
+
const configValue = credentials?.credentialScope ?? credentials?.CredentialScope;
|
|
2858
|
+
return configValue;
|
|
2859
|
+
};
|
|
2860
|
+
}
|
|
2861
|
+
if (configKey === "accountId" || canonicalEndpointParamKey === "AccountId") {
|
|
2862
|
+
return async () => {
|
|
2863
|
+
const credentials = typeof config.credentials === "function" ? await config.credentials() : config.credentials;
|
|
2864
|
+
const configValue = credentials?.accountId ?? credentials?.AccountId;
|
|
2865
|
+
return configValue;
|
|
2866
|
+
};
|
|
2867
|
+
}
|
|
2868
|
+
if (configKey === "endpoint" || canonicalEndpointParamKey === "endpoint") {
|
|
2869
|
+
return async () => {
|
|
2870
|
+
const endpoint = await configProvider();
|
|
2871
|
+
if (endpoint && typeof endpoint === "object") {
|
|
2872
|
+
if ("url" in endpoint) {
|
|
2873
|
+
return endpoint.url.href;
|
|
2874
|
+
}
|
|
2875
|
+
if ("hostname" in endpoint) {
|
|
2876
|
+
const { protocol, hostname, port, path } = endpoint;
|
|
2877
|
+
return `${protocol}//${hostname}${port ? ":" + port : ""}${path}`;
|
|
2878
|
+
}
|
|
2879
|
+
}
|
|
2880
|
+
return endpoint;
|
|
2881
|
+
};
|
|
2882
|
+
}
|
|
2883
|
+
return configProvider;
|
|
2884
|
+
};
|
|
2885
|
+
|
|
2886
|
+
const ENV_ENDPOINT_URL = "AWS_ENDPOINT_URL";
|
|
2887
|
+
const CONFIG_ENDPOINT_URL = "endpoint_url";
|
|
2888
|
+
const getEndpointUrlConfig = (serviceId) => ({
|
|
2889
|
+
environmentVariableSelector: (env) => {
|
|
2890
|
+
const serviceSuffixParts = serviceId.split(" ").map((w) => w.toUpperCase());
|
|
2891
|
+
const serviceEndpointUrl = env[[ENV_ENDPOINT_URL, ...serviceSuffixParts].join("_")];
|
|
2892
|
+
if (serviceEndpointUrl)
|
|
2893
|
+
return serviceEndpointUrl;
|
|
2894
|
+
const endpointUrl = env[ENV_ENDPOINT_URL];
|
|
2895
|
+
if (endpointUrl)
|
|
2896
|
+
return endpointUrl;
|
|
2897
|
+
return undefined;
|
|
2898
|
+
},
|
|
2899
|
+
configFileSelector: (profile, config) => {
|
|
2900
|
+
if (config && profile.services) {
|
|
2901
|
+
const servicesSection = config[["services", profile.services].join(CONFIG_PREFIX_SEPARATOR)];
|
|
2902
|
+
if (servicesSection) {
|
|
2903
|
+
const servicePrefixParts = serviceId.split(" ").map((w) => w.toLowerCase());
|
|
2904
|
+
const endpointUrl = servicesSection[[servicePrefixParts.join("_"), CONFIG_ENDPOINT_URL].join(CONFIG_PREFIX_SEPARATOR)];
|
|
2905
|
+
if (endpointUrl)
|
|
2906
|
+
return endpointUrl;
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
const endpointUrl = profile[CONFIG_ENDPOINT_URL];
|
|
2910
|
+
if (endpointUrl)
|
|
2911
|
+
return endpointUrl;
|
|
2912
|
+
return undefined;
|
|
2913
|
+
},
|
|
2914
|
+
default: undefined,
|
|
2915
|
+
});
|
|
2916
|
+
|
|
2917
|
+
const getEndpointFromConfig = async (serviceId) => loadConfig(getEndpointUrlConfig(serviceId ?? ""))();
|
|
2918
|
+
|
|
2919
|
+
const toEndpointV1 = (endpoint) => {
|
|
2920
|
+
if (typeof endpoint === "object") {
|
|
2921
|
+
if ("url" in endpoint) {
|
|
2922
|
+
return parseUrl(endpoint.url);
|
|
2923
|
+
}
|
|
2924
|
+
return endpoint;
|
|
2925
|
+
}
|
|
2926
|
+
return parseUrl(endpoint);
|
|
2927
|
+
};
|
|
2928
|
+
|
|
2929
|
+
const getEndpointFromInstructions = async (commandInput, instructionsSupplier, clientConfig, context) => {
|
|
2930
|
+
if (!clientConfig.endpoint) {
|
|
2931
|
+
let endpointFromConfig;
|
|
2932
|
+
if (clientConfig.serviceConfiguredEndpoint) {
|
|
2933
|
+
endpointFromConfig = await clientConfig.serviceConfiguredEndpoint();
|
|
2934
|
+
}
|
|
2935
|
+
else {
|
|
2936
|
+
endpointFromConfig = await getEndpointFromConfig(clientConfig.serviceId);
|
|
2937
|
+
}
|
|
2938
|
+
if (endpointFromConfig) {
|
|
2939
|
+
clientConfig.endpoint = () => Promise.resolve(toEndpointV1(endpointFromConfig));
|
|
2940
|
+
}
|
|
2941
|
+
}
|
|
2942
|
+
const endpointParams = await resolveParams(commandInput, instructionsSupplier, clientConfig);
|
|
2943
|
+
if (typeof clientConfig.endpointProvider !== "function") {
|
|
2944
|
+
throw new Error("config.endpointProvider is not set.");
|
|
2945
|
+
}
|
|
2946
|
+
const endpoint = clientConfig.endpointProvider(endpointParams, context);
|
|
2947
|
+
return endpoint;
|
|
2948
|
+
};
|
|
2949
|
+
const resolveParams = async (commandInput, instructionsSupplier, clientConfig) => {
|
|
2950
|
+
const endpointParams = {};
|
|
2951
|
+
const instructions = instructionsSupplier?.getEndpointParameterInstructions?.() || {};
|
|
2952
|
+
for (const [name, instruction] of Object.entries(instructions)) {
|
|
2953
|
+
switch (instruction.type) {
|
|
2954
|
+
case "staticContextParams":
|
|
2955
|
+
endpointParams[name] = instruction.value;
|
|
2956
|
+
break;
|
|
2957
|
+
case "contextParams":
|
|
2958
|
+
endpointParams[name] = commandInput[instruction.name];
|
|
2959
|
+
break;
|
|
2960
|
+
case "clientContextParams":
|
|
2961
|
+
case "builtInParams":
|
|
2962
|
+
endpointParams[name] = await createConfigValueProvider(instruction.name, name, clientConfig)();
|
|
2963
|
+
break;
|
|
2964
|
+
case "operationContextParams":
|
|
2965
|
+
endpointParams[name] = instruction.get(commandInput);
|
|
2966
|
+
break;
|
|
2967
|
+
default:
|
|
2968
|
+
throw new Error("Unrecognized endpoint parameter instruction: " + JSON.stringify(instruction));
|
|
2969
|
+
}
|
|
2970
|
+
}
|
|
2971
|
+
if (Object.keys(instructions).length === 0) {
|
|
2972
|
+
Object.assign(endpointParams, clientConfig);
|
|
2973
|
+
}
|
|
2974
|
+
if (String(clientConfig.serviceId).toLowerCase() === "s3") {
|
|
2975
|
+
await resolveParamsForS3(endpointParams);
|
|
2976
|
+
}
|
|
2977
|
+
return endpointParams;
|
|
2978
|
+
};
|
|
2979
|
+
|
|
2980
|
+
const endpointMiddleware = ({ config, instructions, }) => {
|
|
2981
|
+
return (next, context) => async (args) => {
|
|
2982
|
+
if (config.endpoint) {
|
|
2983
|
+
setFeature$1(context, "ENDPOINT_OVERRIDE", "N");
|
|
2984
|
+
}
|
|
2985
|
+
const endpoint = await getEndpointFromInstructions(args.input, {
|
|
2986
|
+
getEndpointParameterInstructions() {
|
|
2987
|
+
return instructions;
|
|
2988
|
+
},
|
|
2989
|
+
}, { ...config }, context);
|
|
2990
|
+
context.endpointV2 = endpoint;
|
|
2991
|
+
context.authSchemes = endpoint.properties?.authSchemes;
|
|
2992
|
+
const authScheme = context.authSchemes?.[0];
|
|
2993
|
+
if (authScheme) {
|
|
2994
|
+
context["signing_region"] = authScheme.signingRegion;
|
|
2995
|
+
context["signing_service"] = authScheme.signingName;
|
|
2996
|
+
const smithyContext = getSmithyContext(context);
|
|
2997
|
+
const httpAuthOption = smithyContext?.selectedHttpAuthScheme?.httpAuthOption;
|
|
2998
|
+
if (httpAuthOption) {
|
|
2999
|
+
httpAuthOption.signingProperties = Object.assign(httpAuthOption.signingProperties || {}, {
|
|
3000
|
+
signing_region: authScheme.signingRegion,
|
|
3001
|
+
signingRegion: authScheme.signingRegion,
|
|
3002
|
+
signing_service: authScheme.signingName,
|
|
3003
|
+
signingName: authScheme.signingName,
|
|
3004
|
+
signingRegionSet: authScheme.signingRegionSet,
|
|
3005
|
+
}, authScheme.properties);
|
|
3006
|
+
}
|
|
3007
|
+
}
|
|
3008
|
+
return next({
|
|
3009
|
+
...args,
|
|
3010
|
+
});
|
|
3011
|
+
};
|
|
3012
|
+
};
|
|
3013
|
+
|
|
3014
|
+
const endpointMiddlewareOptions = {
|
|
3015
|
+
step: "serialize",
|
|
3016
|
+
tags: ["ENDPOINT_PARAMETERS", "ENDPOINT_V2", "ENDPOINT"],
|
|
3017
|
+
name: "endpointV2Middleware",
|
|
3018
|
+
override: true,
|
|
3019
|
+
relation: "before",
|
|
3020
|
+
toMiddleware: serializerMiddlewareOption.name,
|
|
3021
|
+
};
|
|
3022
|
+
const getEndpointPlugin = (config, instructions) => ({
|
|
3023
|
+
applyToStack: (clientStack) => {
|
|
3024
|
+
clientStack.addRelativeTo(endpointMiddleware({
|
|
3025
|
+
config,
|
|
3026
|
+
instructions,
|
|
3027
|
+
}), endpointMiddlewareOptions);
|
|
3028
|
+
},
|
|
3029
|
+
});
|
|
3030
|
+
|
|
3031
|
+
const resolveEndpointConfig = (input) => {
|
|
3032
|
+
const tls = input.tls ?? true;
|
|
3033
|
+
const { endpoint } = input;
|
|
3034
|
+
const customEndpointProvider = endpoint != null ? async () => toEndpointV1(await normalizeProvider$1(endpoint)()) : undefined;
|
|
3035
|
+
const isCustomEndpoint = !!endpoint;
|
|
3036
|
+
const resolvedConfig = {
|
|
3037
|
+
...input,
|
|
3038
|
+
endpoint: customEndpointProvider,
|
|
3039
|
+
tls,
|
|
3040
|
+
isCustomEndpoint,
|
|
3041
|
+
useDualstackEndpoint: normalizeProvider$1(input.useDualstackEndpoint ?? false),
|
|
3042
|
+
useFipsEndpoint: normalizeProvider$1(input.useFipsEndpoint ?? false),
|
|
3043
|
+
};
|
|
3044
|
+
let configuredEndpointPromise = undefined;
|
|
3045
|
+
resolvedConfig.serviceConfiguredEndpoint = async () => {
|
|
3046
|
+
if (input.serviceId && !configuredEndpointPromise) {
|
|
3047
|
+
configuredEndpointPromise = getEndpointFromConfig(input.serviceId);
|
|
3048
|
+
}
|
|
3049
|
+
return configuredEndpointPromise;
|
|
3050
|
+
};
|
|
3051
|
+
return resolvedConfig;
|
|
3052
|
+
};
|
|
3053
|
+
|
|
3054
|
+
var RETRY_MODES;
|
|
3055
|
+
(function (RETRY_MODES) {
|
|
3056
|
+
RETRY_MODES["STANDARD"] = "standard";
|
|
3057
|
+
RETRY_MODES["ADAPTIVE"] = "adaptive";
|
|
3058
|
+
})(RETRY_MODES || (RETRY_MODES = {}));
|
|
3059
|
+
const DEFAULT_MAX_ATTEMPTS = 3;
|
|
3060
|
+
const DEFAULT_RETRY_MODE = RETRY_MODES.STANDARD;
|
|
3061
|
+
|
|
3062
|
+
const THROTTLING_ERROR_CODES = [
|
|
3063
|
+
"BandwidthLimitExceeded",
|
|
3064
|
+
"EC2ThrottledException",
|
|
3065
|
+
"LimitExceededException",
|
|
3066
|
+
"PriorRequestNotComplete",
|
|
3067
|
+
"ProvisionedThroughputExceededException",
|
|
3068
|
+
"RequestLimitExceeded",
|
|
3069
|
+
"RequestThrottled",
|
|
3070
|
+
"RequestThrottledException",
|
|
3071
|
+
"SlowDown",
|
|
3072
|
+
"ThrottledException",
|
|
3073
|
+
"Throttling",
|
|
3074
|
+
"ThrottlingException",
|
|
3075
|
+
"TooManyRequestsException",
|
|
3076
|
+
"TransactionInProgressException",
|
|
3077
|
+
];
|
|
3078
|
+
const TRANSIENT_ERROR_CODES = ["TimeoutError", "RequestTimeout", "RequestTimeoutException"];
|
|
3079
|
+
const TRANSIENT_ERROR_STATUS_CODES = [500, 502, 503, 504];
|
|
3080
|
+
const NODEJS_TIMEOUT_ERROR_CODES = ["ECONNRESET", "ECONNREFUSED", "EPIPE", "ETIMEDOUT"];
|
|
3081
|
+
|
|
3082
|
+
const isClockSkewCorrectedError = (error) => error.$metadata?.clockSkewCorrected;
|
|
3083
|
+
const isThrottlingError = (error) => error.$metadata?.httpStatusCode === 429 ||
|
|
3084
|
+
THROTTLING_ERROR_CODES.includes(error.name) ||
|
|
3085
|
+
error.$retryable?.throttling == true;
|
|
3086
|
+
const isTransientError = (error, depth = 0) => isClockSkewCorrectedError(error) ||
|
|
3087
|
+
TRANSIENT_ERROR_CODES.includes(error.name) ||
|
|
3088
|
+
NODEJS_TIMEOUT_ERROR_CODES.includes(error?.code || "") ||
|
|
3089
|
+
TRANSIENT_ERROR_STATUS_CODES.includes(error.$metadata?.httpStatusCode || 0) ||
|
|
3090
|
+
(error.cause !== undefined && depth <= 10 && isTransientError(error.cause, depth + 1));
|
|
3091
|
+
const isServerError = (error) => {
|
|
3092
|
+
if (error.$metadata?.httpStatusCode !== undefined) {
|
|
3093
|
+
const statusCode = error.$metadata.httpStatusCode;
|
|
3094
|
+
if (500 <= statusCode && statusCode <= 599 && !isTransientError(error)) {
|
|
3095
|
+
return true;
|
|
3096
|
+
}
|
|
3097
|
+
return false;
|
|
3098
|
+
}
|
|
3099
|
+
return false;
|
|
3100
|
+
};
|
|
3101
|
+
|
|
3102
|
+
class DefaultRateLimiter {
|
|
3103
|
+
constructor(options) {
|
|
3104
|
+
this.currentCapacity = 0;
|
|
3105
|
+
this.enabled = false;
|
|
3106
|
+
this.lastMaxRate = 0;
|
|
3107
|
+
this.measuredTxRate = 0;
|
|
3108
|
+
this.requestCount = 0;
|
|
3109
|
+
this.lastTimestamp = 0;
|
|
3110
|
+
this.timeWindow = 0;
|
|
3111
|
+
this.beta = options?.beta ?? 0.7;
|
|
3112
|
+
this.minCapacity = options?.minCapacity ?? 1;
|
|
3113
|
+
this.minFillRate = options?.minFillRate ?? 0.5;
|
|
3114
|
+
this.scaleConstant = options?.scaleConstant ?? 0.4;
|
|
3115
|
+
this.smooth = options?.smooth ?? 0.8;
|
|
3116
|
+
const currentTimeInSeconds = this.getCurrentTimeInSeconds();
|
|
3117
|
+
this.lastThrottleTime = currentTimeInSeconds;
|
|
3118
|
+
this.lastTxRateBucket = Math.floor(this.getCurrentTimeInSeconds());
|
|
3119
|
+
this.fillRate = this.minFillRate;
|
|
3120
|
+
this.maxCapacity = this.minCapacity;
|
|
3121
|
+
}
|
|
3122
|
+
getCurrentTimeInSeconds() {
|
|
3123
|
+
return Date.now() / 1000;
|
|
3124
|
+
}
|
|
3125
|
+
async getSendToken() {
|
|
3126
|
+
return this.acquireTokenBucket(1);
|
|
3127
|
+
}
|
|
3128
|
+
async acquireTokenBucket(amount) {
|
|
3129
|
+
if (!this.enabled) {
|
|
3130
|
+
return;
|
|
3131
|
+
}
|
|
3132
|
+
this.refillTokenBucket();
|
|
3133
|
+
if (amount > this.currentCapacity) {
|
|
3134
|
+
const delay = ((amount - this.currentCapacity) / this.fillRate) * 1000;
|
|
3135
|
+
await new Promise((resolve) => DefaultRateLimiter.setTimeoutFn(resolve, delay));
|
|
3136
|
+
}
|
|
3137
|
+
this.currentCapacity = this.currentCapacity - amount;
|
|
3138
|
+
}
|
|
3139
|
+
refillTokenBucket() {
|
|
3140
|
+
const timestamp = this.getCurrentTimeInSeconds();
|
|
3141
|
+
if (!this.lastTimestamp) {
|
|
3142
|
+
this.lastTimestamp = timestamp;
|
|
3143
|
+
return;
|
|
3144
|
+
}
|
|
3145
|
+
const fillAmount = (timestamp - this.lastTimestamp) * this.fillRate;
|
|
3146
|
+
this.currentCapacity = Math.min(this.maxCapacity, this.currentCapacity + fillAmount);
|
|
3147
|
+
this.lastTimestamp = timestamp;
|
|
3148
|
+
}
|
|
3149
|
+
updateClientSendingRate(response) {
|
|
3150
|
+
let calculatedRate;
|
|
3151
|
+
this.updateMeasuredRate();
|
|
3152
|
+
if (isThrottlingError(response)) {
|
|
3153
|
+
const rateToUse = !this.enabled ? this.measuredTxRate : Math.min(this.measuredTxRate, this.fillRate);
|
|
3154
|
+
this.lastMaxRate = rateToUse;
|
|
3155
|
+
this.calculateTimeWindow();
|
|
3156
|
+
this.lastThrottleTime = this.getCurrentTimeInSeconds();
|
|
3157
|
+
calculatedRate = this.cubicThrottle(rateToUse);
|
|
3158
|
+
this.enableTokenBucket();
|
|
3159
|
+
}
|
|
3160
|
+
else {
|
|
3161
|
+
this.calculateTimeWindow();
|
|
3162
|
+
calculatedRate = this.cubicSuccess(this.getCurrentTimeInSeconds());
|
|
3163
|
+
}
|
|
3164
|
+
const newRate = Math.min(calculatedRate, 2 * this.measuredTxRate);
|
|
3165
|
+
this.updateTokenBucketRate(newRate);
|
|
3166
|
+
}
|
|
3167
|
+
calculateTimeWindow() {
|
|
3168
|
+
this.timeWindow = this.getPrecise(Math.pow((this.lastMaxRate * (1 - this.beta)) / this.scaleConstant, 1 / 3));
|
|
3169
|
+
}
|
|
3170
|
+
cubicThrottle(rateToUse) {
|
|
3171
|
+
return this.getPrecise(rateToUse * this.beta);
|
|
3172
|
+
}
|
|
3173
|
+
cubicSuccess(timestamp) {
|
|
3174
|
+
return this.getPrecise(this.scaleConstant * Math.pow(timestamp - this.lastThrottleTime - this.timeWindow, 3) + this.lastMaxRate);
|
|
3175
|
+
}
|
|
3176
|
+
enableTokenBucket() {
|
|
3177
|
+
this.enabled = true;
|
|
3178
|
+
}
|
|
3179
|
+
updateTokenBucketRate(newRate) {
|
|
3180
|
+
this.refillTokenBucket();
|
|
3181
|
+
this.fillRate = Math.max(newRate, this.minFillRate);
|
|
3182
|
+
this.maxCapacity = Math.max(newRate, this.minCapacity);
|
|
3183
|
+
this.currentCapacity = Math.min(this.currentCapacity, this.maxCapacity);
|
|
3184
|
+
}
|
|
3185
|
+
updateMeasuredRate() {
|
|
3186
|
+
const t = this.getCurrentTimeInSeconds();
|
|
3187
|
+
const timeBucket = Math.floor(t * 2) / 2;
|
|
3188
|
+
this.requestCount++;
|
|
3189
|
+
if (timeBucket > this.lastTxRateBucket) {
|
|
3190
|
+
const currentRate = this.requestCount / (timeBucket - this.lastTxRateBucket);
|
|
3191
|
+
this.measuredTxRate = this.getPrecise(currentRate * this.smooth + this.measuredTxRate * (1 - this.smooth));
|
|
3192
|
+
this.requestCount = 0;
|
|
3193
|
+
this.lastTxRateBucket = timeBucket;
|
|
3194
|
+
}
|
|
3195
|
+
}
|
|
3196
|
+
getPrecise(num) {
|
|
3197
|
+
return parseFloat(num.toFixed(8));
|
|
3198
|
+
}
|
|
3199
|
+
}
|
|
3200
|
+
DefaultRateLimiter.setTimeoutFn = setTimeout;
|
|
3201
|
+
|
|
3202
|
+
const DEFAULT_RETRY_DELAY_BASE = 100;
|
|
3203
|
+
const MAXIMUM_RETRY_DELAY = 20 * 1000;
|
|
3204
|
+
const THROTTLING_RETRY_DELAY_BASE = 500;
|
|
3205
|
+
const INITIAL_RETRY_TOKENS = 500;
|
|
3206
|
+
const RETRY_COST = 5;
|
|
3207
|
+
const TIMEOUT_RETRY_COST = 10;
|
|
3208
|
+
const NO_RETRY_INCREMENT = 1;
|
|
3209
|
+
const INVOCATION_ID_HEADER = "amz-sdk-invocation-id";
|
|
3210
|
+
const REQUEST_HEADER = "amz-sdk-request";
|
|
3211
|
+
|
|
3212
|
+
const getDefaultRetryBackoffStrategy = () => {
|
|
3213
|
+
let delayBase = DEFAULT_RETRY_DELAY_BASE;
|
|
3214
|
+
const computeNextBackoffDelay = (attempts) => {
|
|
3215
|
+
return Math.floor(Math.min(MAXIMUM_RETRY_DELAY, Math.random() * 2 ** attempts * delayBase));
|
|
3216
|
+
};
|
|
3217
|
+
const setDelayBase = (delay) => {
|
|
3218
|
+
delayBase = delay;
|
|
3219
|
+
};
|
|
3220
|
+
return {
|
|
3221
|
+
computeNextBackoffDelay,
|
|
3222
|
+
setDelayBase,
|
|
3223
|
+
};
|
|
3224
|
+
};
|
|
3225
|
+
|
|
3226
|
+
const createDefaultRetryToken = ({ retryDelay, retryCount, retryCost, }) => {
|
|
3227
|
+
const getRetryCount = () => retryCount;
|
|
3228
|
+
const getRetryDelay = () => Math.min(MAXIMUM_RETRY_DELAY, retryDelay);
|
|
3229
|
+
const getRetryCost = () => retryCost;
|
|
3230
|
+
return {
|
|
3231
|
+
getRetryCount,
|
|
3232
|
+
getRetryDelay,
|
|
3233
|
+
getRetryCost,
|
|
3234
|
+
};
|
|
3235
|
+
};
|
|
3236
|
+
|
|
3237
|
+
class StandardRetryStrategy {
|
|
3238
|
+
constructor(maxAttempts) {
|
|
3239
|
+
this.maxAttempts = maxAttempts;
|
|
3240
|
+
this.mode = RETRY_MODES.STANDARD;
|
|
3241
|
+
this.capacity = INITIAL_RETRY_TOKENS;
|
|
3242
|
+
this.retryBackoffStrategy = getDefaultRetryBackoffStrategy();
|
|
3243
|
+
this.maxAttemptsProvider = typeof maxAttempts === "function" ? maxAttempts : async () => maxAttempts;
|
|
3244
|
+
}
|
|
3245
|
+
async acquireInitialRetryToken(retryTokenScope) {
|
|
3246
|
+
return createDefaultRetryToken({
|
|
3247
|
+
retryDelay: DEFAULT_RETRY_DELAY_BASE,
|
|
3248
|
+
retryCount: 0,
|
|
3249
|
+
});
|
|
3250
|
+
}
|
|
3251
|
+
async refreshRetryTokenForRetry(token, errorInfo) {
|
|
3252
|
+
const maxAttempts = await this.getMaxAttempts();
|
|
3253
|
+
if (this.shouldRetry(token, errorInfo, maxAttempts)) {
|
|
3254
|
+
const errorType = errorInfo.errorType;
|
|
3255
|
+
this.retryBackoffStrategy.setDelayBase(errorType === "THROTTLING" ? THROTTLING_RETRY_DELAY_BASE : DEFAULT_RETRY_DELAY_BASE);
|
|
3256
|
+
const delayFromErrorType = this.retryBackoffStrategy.computeNextBackoffDelay(token.getRetryCount());
|
|
3257
|
+
const retryDelay = errorInfo.retryAfterHint
|
|
3258
|
+
? Math.max(errorInfo.retryAfterHint.getTime() - Date.now() || 0, delayFromErrorType)
|
|
3259
|
+
: delayFromErrorType;
|
|
3260
|
+
const capacityCost = this.getCapacityCost(errorType);
|
|
3261
|
+
this.capacity -= capacityCost;
|
|
3262
|
+
return createDefaultRetryToken({
|
|
3263
|
+
retryDelay,
|
|
3264
|
+
retryCount: token.getRetryCount() + 1,
|
|
3265
|
+
retryCost: capacityCost,
|
|
3266
|
+
});
|
|
3267
|
+
}
|
|
3268
|
+
throw new Error("No retry token available");
|
|
3269
|
+
}
|
|
3270
|
+
recordSuccess(token) {
|
|
3271
|
+
this.capacity = Math.max(INITIAL_RETRY_TOKENS, this.capacity + (token.getRetryCost() ?? NO_RETRY_INCREMENT));
|
|
3272
|
+
}
|
|
3273
|
+
getCapacity() {
|
|
3274
|
+
return this.capacity;
|
|
3275
|
+
}
|
|
3276
|
+
async getMaxAttempts() {
|
|
3277
|
+
try {
|
|
3278
|
+
return await this.maxAttemptsProvider();
|
|
3279
|
+
}
|
|
3280
|
+
catch (error) {
|
|
3281
|
+
console.warn(`Max attempts provider could not resolve. Using default of ${DEFAULT_MAX_ATTEMPTS}`);
|
|
3282
|
+
return DEFAULT_MAX_ATTEMPTS;
|
|
3283
|
+
}
|
|
3284
|
+
}
|
|
3285
|
+
shouldRetry(tokenToRenew, errorInfo, maxAttempts) {
|
|
3286
|
+
const attempts = tokenToRenew.getRetryCount() + 1;
|
|
3287
|
+
return (attempts < maxAttempts &&
|
|
3288
|
+
this.capacity >= this.getCapacityCost(errorInfo.errorType) &&
|
|
3289
|
+
this.isRetryableError(errorInfo.errorType));
|
|
3290
|
+
}
|
|
3291
|
+
getCapacityCost(errorType) {
|
|
3292
|
+
return errorType === "TRANSIENT" ? TIMEOUT_RETRY_COST : RETRY_COST;
|
|
3293
|
+
}
|
|
3294
|
+
isRetryableError(errorType) {
|
|
3295
|
+
return errorType === "THROTTLING" || errorType === "TRANSIENT";
|
|
3296
|
+
}
|
|
3297
|
+
}
|
|
3298
|
+
|
|
3299
|
+
class AdaptiveRetryStrategy {
|
|
3300
|
+
constructor(maxAttemptsProvider, options) {
|
|
3301
|
+
this.maxAttemptsProvider = maxAttemptsProvider;
|
|
3302
|
+
this.mode = RETRY_MODES.ADAPTIVE;
|
|
3303
|
+
const { rateLimiter } = options ?? {};
|
|
3304
|
+
this.rateLimiter = rateLimiter ?? new DefaultRateLimiter();
|
|
3305
|
+
this.standardRetryStrategy = new StandardRetryStrategy(maxAttemptsProvider);
|
|
3306
|
+
}
|
|
3307
|
+
async acquireInitialRetryToken(retryTokenScope) {
|
|
3308
|
+
await this.rateLimiter.getSendToken();
|
|
3309
|
+
return this.standardRetryStrategy.acquireInitialRetryToken(retryTokenScope);
|
|
3310
|
+
}
|
|
3311
|
+
async refreshRetryTokenForRetry(tokenToRenew, errorInfo) {
|
|
3312
|
+
this.rateLimiter.updateClientSendingRate(errorInfo);
|
|
3313
|
+
return this.standardRetryStrategy.refreshRetryTokenForRetry(tokenToRenew, errorInfo);
|
|
3314
|
+
}
|
|
3315
|
+
recordSuccess(token) {
|
|
3316
|
+
this.rateLimiter.updateClientSendingRate({});
|
|
3317
|
+
this.standardRetryStrategy.recordSuccess(token);
|
|
3318
|
+
}
|
|
3319
|
+
}
|
|
3320
|
+
|
|
3321
|
+
const rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate
|
|
3322
|
+
|
|
3323
|
+
let poolPtr = rnds8Pool.length;
|
|
3324
|
+
function rng() {
|
|
3325
|
+
if (poolPtr > rnds8Pool.length - 16) {
|
|
3326
|
+
crypto.randomFillSync(rnds8Pool);
|
|
3327
|
+
poolPtr = 0;
|
|
3328
|
+
}
|
|
3329
|
+
|
|
3330
|
+
return rnds8Pool.slice(poolPtr, poolPtr += 16);
|
|
3331
|
+
}
|
|
3332
|
+
|
|
3333
|
+
/**
|
|
3334
|
+
* Convert array of 16 byte values to UUID string format of the form:
|
|
3335
|
+
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
|
3336
|
+
*/
|
|
3337
|
+
|
|
3338
|
+
const byteToHex = [];
|
|
3339
|
+
|
|
3340
|
+
for (let i = 0; i < 256; ++i) {
|
|
3341
|
+
byteToHex.push((i + 0x100).toString(16).slice(1));
|
|
3342
|
+
}
|
|
3343
|
+
|
|
3344
|
+
function unsafeStringify(arr, offset = 0) {
|
|
3345
|
+
// Note: Be careful editing this code! It's been tuned for performance
|
|
3346
|
+
// and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
|
|
3347
|
+
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
|
3348
|
+
}
|
|
3349
|
+
|
|
3350
|
+
var native = {
|
|
3351
|
+
randomUUID: crypto.randomUUID
|
|
3352
|
+
};
|
|
3353
|
+
|
|
3354
|
+
function v4(options, buf, offset) {
|
|
3355
|
+
if (native.randomUUID && true && !options) {
|
|
3356
|
+
return native.randomUUID();
|
|
3357
|
+
}
|
|
3358
|
+
|
|
3359
|
+
options = options || {};
|
|
3360
|
+
const rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
|
|
3361
|
+
|
|
3362
|
+
rnds[6] = rnds[6] & 0x0f | 0x40;
|
|
3363
|
+
rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
|
|
3364
|
+
|
|
3365
|
+
return unsafeStringify(rnds);
|
|
3366
|
+
}
|
|
3367
|
+
|
|
3368
|
+
const asSdkError = (error) => {
|
|
3369
|
+
if (error instanceof Error)
|
|
3370
|
+
return error;
|
|
3371
|
+
if (error instanceof Object)
|
|
3372
|
+
return Object.assign(new Error(), error);
|
|
3373
|
+
if (typeof error === "string")
|
|
3374
|
+
return new Error(error);
|
|
3375
|
+
return new Error(`AWS SDK error wrapper for ${error}`);
|
|
3376
|
+
};
|
|
3377
|
+
|
|
3378
|
+
const ENV_MAX_ATTEMPTS = "AWS_MAX_ATTEMPTS";
|
|
3379
|
+
const CONFIG_MAX_ATTEMPTS = "max_attempts";
|
|
3380
|
+
const NODE_MAX_ATTEMPT_CONFIG_OPTIONS = {
|
|
3381
|
+
environmentVariableSelector: (env) => {
|
|
3382
|
+
const value = env[ENV_MAX_ATTEMPTS];
|
|
3383
|
+
if (!value)
|
|
3384
|
+
return undefined;
|
|
3385
|
+
const maxAttempt = parseInt(value);
|
|
3386
|
+
if (Number.isNaN(maxAttempt)) {
|
|
3387
|
+
throw new Error(`Environment variable ${ENV_MAX_ATTEMPTS} mast be a number, got "${value}"`);
|
|
3388
|
+
}
|
|
3389
|
+
return maxAttempt;
|
|
3390
|
+
},
|
|
3391
|
+
configFileSelector: (profile) => {
|
|
3392
|
+
const value = profile[CONFIG_MAX_ATTEMPTS];
|
|
3393
|
+
if (!value)
|
|
3394
|
+
return undefined;
|
|
3395
|
+
const maxAttempt = parseInt(value);
|
|
3396
|
+
if (Number.isNaN(maxAttempt)) {
|
|
3397
|
+
throw new Error(`Shared config file entry ${CONFIG_MAX_ATTEMPTS} mast be a number, got "${value}"`);
|
|
3398
|
+
}
|
|
3399
|
+
return maxAttempt;
|
|
3400
|
+
},
|
|
3401
|
+
default: DEFAULT_MAX_ATTEMPTS,
|
|
3402
|
+
};
|
|
3403
|
+
const resolveRetryConfig = (input) => {
|
|
3404
|
+
const { retryStrategy } = input;
|
|
3405
|
+
const maxAttempts = normalizeProvider$1(input.maxAttempts ?? DEFAULT_MAX_ATTEMPTS);
|
|
3406
|
+
return {
|
|
3407
|
+
...input,
|
|
3408
|
+
maxAttempts,
|
|
3409
|
+
retryStrategy: async () => {
|
|
3410
|
+
if (retryStrategy) {
|
|
3411
|
+
return retryStrategy;
|
|
3412
|
+
}
|
|
3413
|
+
const retryMode = await normalizeProvider$1(input.retryMode)();
|
|
3414
|
+
if (retryMode === RETRY_MODES.ADAPTIVE) {
|
|
3415
|
+
return new AdaptiveRetryStrategy(maxAttempts);
|
|
3416
|
+
}
|
|
3417
|
+
return new StandardRetryStrategy(maxAttempts);
|
|
3418
|
+
},
|
|
3419
|
+
};
|
|
3420
|
+
};
|
|
3421
|
+
const ENV_RETRY_MODE = "AWS_RETRY_MODE";
|
|
3422
|
+
const CONFIG_RETRY_MODE = "retry_mode";
|
|
3423
|
+
const NODE_RETRY_MODE_CONFIG_OPTIONS = {
|
|
3424
|
+
environmentVariableSelector: (env) => env[ENV_RETRY_MODE],
|
|
3425
|
+
configFileSelector: (profile) => profile[CONFIG_RETRY_MODE],
|
|
3426
|
+
default: DEFAULT_RETRY_MODE,
|
|
3427
|
+
};
|
|
3428
|
+
|
|
3429
|
+
const isStreamingPayload = (request) => request?.body instanceof Readable ||
|
|
3430
|
+
(typeof ReadableStream !== "undefined" && request?.body instanceof ReadableStream);
|
|
3431
|
+
|
|
3432
|
+
const retryMiddleware = (options) => (next, context) => async (args) => {
|
|
3433
|
+
let retryStrategy = await options.retryStrategy();
|
|
3434
|
+
const maxAttempts = await options.maxAttempts();
|
|
3435
|
+
if (isRetryStrategyV2(retryStrategy)) {
|
|
3436
|
+
retryStrategy = retryStrategy;
|
|
3437
|
+
let retryToken = await retryStrategy.acquireInitialRetryToken(context["partition_id"]);
|
|
3438
|
+
let lastError = new Error();
|
|
3439
|
+
let attempts = 0;
|
|
3440
|
+
let totalRetryDelay = 0;
|
|
3441
|
+
const { request } = args;
|
|
3442
|
+
const isRequest = HttpRequest.isInstance(request);
|
|
3443
|
+
if (isRequest) {
|
|
3444
|
+
request.headers[INVOCATION_ID_HEADER] = v4();
|
|
3445
|
+
}
|
|
3446
|
+
while (true) {
|
|
3447
|
+
try {
|
|
3448
|
+
if (isRequest) {
|
|
3449
|
+
request.headers[REQUEST_HEADER] = `attempt=${attempts + 1}; max=${maxAttempts}`;
|
|
3450
|
+
}
|
|
3451
|
+
const { response, output } = await next(args);
|
|
3452
|
+
retryStrategy.recordSuccess(retryToken);
|
|
3453
|
+
output.$metadata.attempts = attempts + 1;
|
|
3454
|
+
output.$metadata.totalRetryDelay = totalRetryDelay;
|
|
3455
|
+
return { response, output };
|
|
3456
|
+
}
|
|
3457
|
+
catch (e) {
|
|
3458
|
+
const retryErrorInfo = getRetryErrorInfo(e);
|
|
3459
|
+
lastError = asSdkError(e);
|
|
3460
|
+
if (isRequest && isStreamingPayload(request)) {
|
|
3461
|
+
(context.logger instanceof NoOpLogger ? console : context.logger)?.warn("An error was encountered in a non-retryable streaming request.");
|
|
3462
|
+
throw lastError;
|
|
3463
|
+
}
|
|
3464
|
+
try {
|
|
3465
|
+
retryToken = await retryStrategy.refreshRetryTokenForRetry(retryToken, retryErrorInfo);
|
|
3466
|
+
}
|
|
3467
|
+
catch (refreshError) {
|
|
3468
|
+
if (!lastError.$metadata) {
|
|
3469
|
+
lastError.$metadata = {};
|
|
3470
|
+
}
|
|
3471
|
+
lastError.$metadata.attempts = attempts + 1;
|
|
3472
|
+
lastError.$metadata.totalRetryDelay = totalRetryDelay;
|
|
3473
|
+
throw lastError;
|
|
3474
|
+
}
|
|
3475
|
+
attempts = retryToken.getRetryCount();
|
|
3476
|
+
const delay = retryToken.getRetryDelay();
|
|
3477
|
+
totalRetryDelay += delay;
|
|
3478
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
3479
|
+
}
|
|
3480
|
+
}
|
|
3481
|
+
}
|
|
3482
|
+
else {
|
|
3483
|
+
retryStrategy = retryStrategy;
|
|
3484
|
+
if (retryStrategy?.mode)
|
|
3485
|
+
context.userAgent = [...(context.userAgent || []), ["cfg/retry-mode", retryStrategy.mode]];
|
|
3486
|
+
return retryStrategy.retry(next, args);
|
|
3487
|
+
}
|
|
3488
|
+
};
|
|
3489
|
+
const isRetryStrategyV2 = (retryStrategy) => typeof retryStrategy.acquireInitialRetryToken !== "undefined" &&
|
|
3490
|
+
typeof retryStrategy.refreshRetryTokenForRetry !== "undefined" &&
|
|
3491
|
+
typeof retryStrategy.recordSuccess !== "undefined";
|
|
3492
|
+
const getRetryErrorInfo = (error) => {
|
|
3493
|
+
const errorInfo = {
|
|
3494
|
+
error,
|
|
3495
|
+
errorType: getRetryErrorType(error),
|
|
3496
|
+
};
|
|
3497
|
+
const retryAfterHint = getRetryAfterHint(error.$response);
|
|
3498
|
+
if (retryAfterHint) {
|
|
3499
|
+
errorInfo.retryAfterHint = retryAfterHint;
|
|
3500
|
+
}
|
|
3501
|
+
return errorInfo;
|
|
3502
|
+
};
|
|
3503
|
+
const getRetryErrorType = (error) => {
|
|
3504
|
+
if (isThrottlingError(error))
|
|
3505
|
+
return "THROTTLING";
|
|
3506
|
+
if (isTransientError(error))
|
|
3507
|
+
return "TRANSIENT";
|
|
3508
|
+
if (isServerError(error))
|
|
3509
|
+
return "SERVER_ERROR";
|
|
3510
|
+
return "CLIENT_ERROR";
|
|
3511
|
+
};
|
|
3512
|
+
const retryMiddlewareOptions = {
|
|
3513
|
+
name: "retryMiddleware",
|
|
3514
|
+
tags: ["RETRY"],
|
|
3515
|
+
step: "finalizeRequest",
|
|
3516
|
+
priority: "high",
|
|
3517
|
+
override: true,
|
|
3518
|
+
};
|
|
3519
|
+
const getRetryPlugin = (options) => ({
|
|
3520
|
+
applyToStack: (clientStack) => {
|
|
3521
|
+
clientStack.add(retryMiddleware(options), retryMiddlewareOptions);
|
|
3522
|
+
},
|
|
3523
|
+
});
|
|
3524
|
+
const getRetryAfterHint = (response) => {
|
|
3525
|
+
if (!HttpResponse.isInstance(response))
|
|
3526
|
+
return;
|
|
3527
|
+
const retryAfterHeaderName = Object.keys(response.headers).find((key) => key.toLowerCase() === "retry-after");
|
|
3528
|
+
if (!retryAfterHeaderName)
|
|
3529
|
+
return;
|
|
3530
|
+
const retryAfter = response.headers[retryAfterHeaderName];
|
|
3531
|
+
const retryAfterSeconds = Number(retryAfter);
|
|
3532
|
+
if (!Number.isNaN(retryAfterSeconds))
|
|
3533
|
+
return new Date(retryAfterSeconds * 1000);
|
|
3534
|
+
const retryAfterDate = new Date(retryAfter);
|
|
3535
|
+
return retryAfterDate;
|
|
3536
|
+
};
|
|
3537
|
+
|
|
3538
|
+
const isCrtAvailable = () => {
|
|
3539
|
+
return null;
|
|
3540
|
+
};
|
|
3541
|
+
|
|
3542
|
+
const createDefaultUserAgentProvider = ({ serviceId, clientVersion }) => {
|
|
3543
|
+
return async (config) => {
|
|
3544
|
+
const sections = [
|
|
3545
|
+
["aws-sdk-js", clientVersion],
|
|
3546
|
+
["ua", "2.1"],
|
|
3547
|
+
[`os/${platform()}`, release()],
|
|
3548
|
+
["lang/js"],
|
|
3549
|
+
["md/nodejs", `${versions.node}`],
|
|
3550
|
+
];
|
|
3551
|
+
const crtAvailable = isCrtAvailable();
|
|
3552
|
+
if (crtAvailable) {
|
|
3553
|
+
sections.push(crtAvailable);
|
|
3554
|
+
}
|
|
3555
|
+
if (serviceId) {
|
|
3556
|
+
sections.push([`api/${serviceId}`, clientVersion]);
|
|
3557
|
+
}
|
|
3558
|
+
if (env.AWS_EXECUTION_ENV) {
|
|
3559
|
+
sections.push([`exec-env/${env.AWS_EXECUTION_ENV}`]);
|
|
3560
|
+
}
|
|
3561
|
+
const appId = await config?.userAgentAppId?.();
|
|
3562
|
+
const resolvedUserAgent = appId ? [...sections, [`app/${appId}`]] : [...sections];
|
|
3563
|
+
return resolvedUserAgent;
|
|
3564
|
+
};
|
|
3565
|
+
};
|
|
3566
|
+
|
|
3567
|
+
const UA_APP_ID_ENV_NAME = "AWS_SDK_UA_APP_ID";
|
|
3568
|
+
const UA_APP_ID_INI_NAME = "sdk_ua_app_id";
|
|
3569
|
+
const UA_APP_ID_INI_NAME_DEPRECATED = "sdk-ua-app-id";
|
|
3570
|
+
const NODE_APP_ID_CONFIG_OPTIONS = {
|
|
3571
|
+
environmentVariableSelector: (env) => env[UA_APP_ID_ENV_NAME],
|
|
3572
|
+
configFileSelector: (profile) => profile[UA_APP_ID_INI_NAME] ?? profile[UA_APP_ID_INI_NAME_DEPRECATED],
|
|
3573
|
+
default: DEFAULT_UA_APP_ID,
|
|
3574
|
+
};
|
|
3575
|
+
|
|
3576
|
+
class Hash {
|
|
3577
|
+
constructor(algorithmIdentifier, secret) {
|
|
3578
|
+
this.algorithmIdentifier = algorithmIdentifier;
|
|
3579
|
+
this.secret = secret;
|
|
3580
|
+
this.reset();
|
|
3581
|
+
}
|
|
3582
|
+
update(toHash, encoding) {
|
|
3583
|
+
this.hash.update(toUint8Array(castSourceData(toHash, encoding)));
|
|
3584
|
+
}
|
|
3585
|
+
digest() {
|
|
3586
|
+
return Promise.resolve(this.hash.digest());
|
|
3587
|
+
}
|
|
3588
|
+
reset() {
|
|
3589
|
+
this.hash = this.secret
|
|
3590
|
+
? createHmac(this.algorithmIdentifier, castSourceData(this.secret))
|
|
3591
|
+
: createHash(this.algorithmIdentifier);
|
|
3592
|
+
}
|
|
3593
|
+
}
|
|
3594
|
+
function castSourceData(toCast, encoding) {
|
|
3595
|
+
if (Buffer$1.isBuffer(toCast)) {
|
|
3596
|
+
return toCast;
|
|
3597
|
+
}
|
|
3598
|
+
if (typeof toCast === "string") {
|
|
3599
|
+
return fromString(toCast, encoding);
|
|
3600
|
+
}
|
|
3601
|
+
if (ArrayBuffer.isView(toCast)) {
|
|
3602
|
+
return fromArrayBuffer(toCast.buffer, toCast.byteOffset, toCast.byteLength);
|
|
3603
|
+
}
|
|
3604
|
+
return fromArrayBuffer(toCast);
|
|
3605
|
+
}
|
|
3606
|
+
|
|
3607
|
+
const calculateBodyLength = (body) => {
|
|
3608
|
+
if (!body) {
|
|
3609
|
+
return 0;
|
|
3610
|
+
}
|
|
3611
|
+
if (typeof body === "string") {
|
|
3612
|
+
return Buffer.byteLength(body);
|
|
3613
|
+
}
|
|
3614
|
+
else if (typeof body.byteLength === "number") {
|
|
3615
|
+
return body.byteLength;
|
|
3616
|
+
}
|
|
3617
|
+
else if (typeof body.size === "number") {
|
|
3618
|
+
return body.size;
|
|
3619
|
+
}
|
|
3620
|
+
else if (typeof body.start === "number" && typeof body.end === "number") {
|
|
3621
|
+
return body.end + 1 - body.start;
|
|
3622
|
+
}
|
|
3623
|
+
else if (typeof body.path === "string" || Buffer.isBuffer(body.path)) {
|
|
3624
|
+
return lstatSync(body.path).size;
|
|
3625
|
+
}
|
|
3626
|
+
else if (typeof body.fd === "number") {
|
|
3627
|
+
return fstatSync(body.fd).size;
|
|
3628
|
+
}
|
|
3629
|
+
throw new Error(`Body Length computation failed for ${body}`);
|
|
3630
|
+
};
|
|
3631
|
+
|
|
3632
|
+
const AWS_EXECUTION_ENV = "AWS_EXECUTION_ENV";
|
|
3633
|
+
const AWS_REGION_ENV = "AWS_REGION";
|
|
3634
|
+
const AWS_DEFAULT_REGION_ENV = "AWS_DEFAULT_REGION";
|
|
3635
|
+
const ENV_IMDS_DISABLED = "AWS_EC2_METADATA_DISABLED";
|
|
3636
|
+
const DEFAULTS_MODE_OPTIONS = ["in-region", "cross-region", "mobile", "standard", "legacy"];
|
|
3637
|
+
const IMDS_REGION_PATH = "/latest/meta-data/placement/region";
|
|
3638
|
+
|
|
3639
|
+
const AWS_DEFAULTS_MODE_ENV = "AWS_DEFAULTS_MODE";
|
|
3640
|
+
const AWS_DEFAULTS_MODE_CONFIG = "defaults_mode";
|
|
3641
|
+
const NODE_DEFAULTS_MODE_CONFIG_OPTIONS = {
|
|
3642
|
+
environmentVariableSelector: (env) => {
|
|
3643
|
+
return env[AWS_DEFAULTS_MODE_ENV];
|
|
3644
|
+
},
|
|
3645
|
+
configFileSelector: (profile) => {
|
|
3646
|
+
return profile[AWS_DEFAULTS_MODE_CONFIG];
|
|
3647
|
+
},
|
|
3648
|
+
default: "legacy",
|
|
3649
|
+
};
|
|
3650
|
+
|
|
3651
|
+
const resolveDefaultsModeConfig = ({ region = loadConfig(NODE_REGION_CONFIG_OPTIONS), defaultsMode = loadConfig(NODE_DEFAULTS_MODE_CONFIG_OPTIONS), } = {}) => memoize(async () => {
|
|
3652
|
+
const mode = typeof defaultsMode === "function" ? await defaultsMode() : defaultsMode;
|
|
3653
|
+
switch (mode?.toLowerCase()) {
|
|
3654
|
+
case "auto":
|
|
3655
|
+
return resolveNodeDefaultsModeAuto(region);
|
|
3656
|
+
case "in-region":
|
|
3657
|
+
case "cross-region":
|
|
3658
|
+
case "mobile":
|
|
3659
|
+
case "standard":
|
|
3660
|
+
case "legacy":
|
|
3661
|
+
return Promise.resolve(mode?.toLocaleLowerCase());
|
|
3662
|
+
case undefined:
|
|
3663
|
+
return Promise.resolve("legacy");
|
|
3664
|
+
default:
|
|
3665
|
+
throw new Error(`Invalid parameter for "defaultsMode", expect ${DEFAULTS_MODE_OPTIONS.join(", ")}, got ${mode}`);
|
|
3666
|
+
}
|
|
3667
|
+
});
|
|
3668
|
+
const resolveNodeDefaultsModeAuto = async (clientRegion) => {
|
|
3669
|
+
if (clientRegion) {
|
|
3670
|
+
const resolvedRegion = typeof clientRegion === "function" ? await clientRegion() : clientRegion;
|
|
3671
|
+
const inferredRegion = await inferPhysicalRegion();
|
|
3672
|
+
if (!inferredRegion) {
|
|
3673
|
+
return "standard";
|
|
3674
|
+
}
|
|
3675
|
+
if (resolvedRegion === inferredRegion) {
|
|
3676
|
+
return "in-region";
|
|
3677
|
+
}
|
|
3678
|
+
else {
|
|
3679
|
+
return "cross-region";
|
|
3680
|
+
}
|
|
3681
|
+
}
|
|
3682
|
+
return "standard";
|
|
3683
|
+
};
|
|
3684
|
+
const inferPhysicalRegion = async () => {
|
|
3685
|
+
if (process.env[AWS_EXECUTION_ENV] && (process.env[AWS_REGION_ENV] || process.env[AWS_DEFAULT_REGION_ENV])) {
|
|
3686
|
+
return process.env[AWS_REGION_ENV] ?? process.env[AWS_DEFAULT_REGION_ENV];
|
|
3687
|
+
}
|
|
3688
|
+
if (!process.env[ENV_IMDS_DISABLED]) {
|
|
3689
|
+
try {
|
|
3690
|
+
const { getInstanceMetadataEndpoint, httpRequest } = await import('./index-lqkrgSwk.js');
|
|
3691
|
+
const endpoint = await getInstanceMetadataEndpoint();
|
|
3692
|
+
return (await httpRequest({ ...endpoint, path: IMDS_REGION_PATH })).toString();
|
|
3693
|
+
}
|
|
3694
|
+
catch (e) {
|
|
3695
|
+
}
|
|
3696
|
+
}
|
|
3697
|
+
};
|
|
3698
|
+
|
|
3699
|
+
const getAwsRegionExtensionConfiguration = (runtimeConfig) => {
|
|
3700
|
+
let runtimeConfigRegion = async () => {
|
|
3701
|
+
if (runtimeConfig.region === undefined) {
|
|
3702
|
+
throw new Error("Region is missing from runtimeConfig");
|
|
3703
|
+
}
|
|
3704
|
+
const region = runtimeConfig.region;
|
|
3705
|
+
if (typeof region === "string") {
|
|
3706
|
+
return region;
|
|
3707
|
+
}
|
|
3708
|
+
return region();
|
|
3709
|
+
};
|
|
3710
|
+
return {
|
|
3711
|
+
setRegion(region) {
|
|
3712
|
+
runtimeConfigRegion = region;
|
|
3713
|
+
},
|
|
3714
|
+
region() {
|
|
3715
|
+
return runtimeConfigRegion;
|
|
3716
|
+
},
|
|
3717
|
+
};
|
|
3718
|
+
};
|
|
3719
|
+
const resolveAwsRegionExtensionConfiguration = (awsRegionExtensionConfiguration) => {
|
|
3720
|
+
return {
|
|
3721
|
+
region: awsRegionExtensionConfiguration.region(),
|
|
3722
|
+
};
|
|
3723
|
+
};
|
|
3724
|
+
|
|
3725
|
+
export { decorateServiceException as $, AwsSdkSigV4Signer as A, getHttpHandlerExtensionConfiguration as B, Command as C, DEFAULT_RETRY_MODE as D, EndpointCache as E, resolveAwsRegionExtensionConfiguration as F, resolveDefaultRuntimeConfig as G, Hash as H, resolveHttpHandlerRuntimeConfig as I, getAwsRegionExtensionConfiguration as J, resolveUserAgentConfig as K, resolveRetryConfig as L, resolveRegionConfig as M, NoAuthSigner as N, resolveEndpointConfig as O, getUserAgentPlugin as P, getRetryPlugin as Q, getContentLengthPlugin as R, getHostHeaderPlugin as S, getLoggerPlugin as T, getRecursionDetectionPlugin as U, getHttpAuthSchemeEndpointRuleSetPlugin as V, DefaultIdentityProviderConfig as W, getHttpSigningPlugin as X, resolveHostHeaderConfig as Y, ServiceException as Z, SENSITIVE_STRING as _, getEndpointPlugin as a, withBaseException as a0, Client as b, collectBodyString as c, getSmithyContext as d, resolveEndpoint as e, customEndpointFunctions as f, getSerdePlugin as g, awsEndpointFunctions as h, fromBase64 as i, NoOpLogger as j, emitWarningIfUnsupportedVersion as k, emitWarningIfUnsupportedVersion$1 as l, calculateBodyLength as m, normalizeProvider$1 as n, createDefaultUserAgentProvider as o, NODE_MAX_ATTEMPT_CONFIG_OPTIONS as p, NODE_REGION_CONFIG_FILE_OPTIONS as q, resolveAwsSdkSigV4Config as r, NODE_REGION_CONFIG_OPTIONS as s, NODE_RETRY_MODE_CONFIG_OPTIONS as t, NODE_USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS as u, NODE_USE_FIPS_ENDPOINT_CONFIG_OPTIONS as v, NODE_APP_ID_CONFIG_OPTIONS as w, resolveDefaultsModeConfig as x, loadConfigsForDefaultMode as y, getDefaultExtensionConfiguration as z };
|
|
3726
|
+
//# sourceMappingURL=index-DeZeG5u4.js.map
|