UEA-Prodem

This commit is contained in:
2026-06-10 12:38:42 -03:00
parent 3f33154e16
commit c41625e542
9352 changed files with 1128292 additions and 14752 deletions
+3
View File
@@ -0,0 +1,3 @@
export { emitWarningIfUnsupportedVersion, getLongPollPlugin, setCredentialFeature, setFeature, setTokenFeature, state, } from "@aws-sdk/core/client";
export { AwsSdkSigV4ASigner, AwsSdkSigV4Signer, AwsSdkSigV4Signer as AWSSDKSigV4Signer, getBearerTokenEnvKey, NODE_AUTH_SCHEME_PREFERENCE_OPTIONS, NODE_SIGV4A_CONFIG_OPTIONS, resolveAwsSdkSigV4AConfig, resolveAwsSdkSigV4Config, resolveAwsSdkSigV4Config as resolveAWSSDKSigV4Config, validateSigningProperties, } from "@aws-sdk/core/httpAuthSchemes";
export { _toBool, _toNum, _toStr, awsExpectUnion, AwsEc2QueryProtocol, AwsJson1_0Protocol, AwsJson1_1Protocol, AwsJsonRpcProtocol, AwsQueryProtocol, AwsRestJsonProtocol, AwsRestXmlProtocol, AwsSmithyRpcV2CborProtocol, JsonCodec, JsonShapeDeserializer, JsonShapeSerializer, loadJsonRpcErrorCode, loadRestJsonErrorCode, loadRestXmlErrorCode, parseJsonBody, parseJsonErrorBody, parseXmlBody, parseXmlErrorBody, QueryShapeSerializer, XmlCodec, XmlShapeDeserializer, XmlShapeSerializer, } from "@aws-sdk/core/protocols";
@@ -0,0 +1,15 @@
import { normalizeProvider } from "@smithy/core/client";
import { DEFAULT_ACCOUNT_ID_ENDPOINT_MODE, validateAccountIdEndpointMode } from "./AccountIdEndpointModeConstants";
export const resolveAccountIdEndpointModeConfig = (input) => {
const { accountIdEndpointMode } = input;
const accountIdEndpointModeProvider = normalizeProvider(accountIdEndpointMode ?? DEFAULT_ACCOUNT_ID_ENDPOINT_MODE);
return Object.assign(input, {
accountIdEndpointMode: async () => {
const accIdMode = await accountIdEndpointModeProvider();
if (!validateAccountIdEndpointMode(accIdMode)) {
throw new Error(`Invalid value for accountIdEndpointMode: ${accIdMode}. Valid values are: "required", "preferred", "disabled".`);
}
return accIdMode;
},
});
};
@@ -0,0 +1,5 @@
export const DEFAULT_ACCOUNT_ID_ENDPOINT_MODE = "preferred";
export const ACCOUNT_ID_ENDPOINT_MODE_VALUES = ["disabled", "preferred", "required"];
export function validateAccountIdEndpointMode(value) {
return ACCOUNT_ID_ENDPOINT_MODE_VALUES.includes(value);
}
@@ -0,0 +1,24 @@
import { DEFAULT_ACCOUNT_ID_ENDPOINT_MODE, validateAccountIdEndpointMode } from "./AccountIdEndpointModeConstants";
const err = "Invalid AccountIdEndpointMode value";
const _throw = (message) => {
throw new Error(message);
};
export const ENV_ACCOUNT_ID_ENDPOINT_MODE = "AWS_ACCOUNT_ID_ENDPOINT_MODE";
export const CONFIG_ACCOUNT_ID_ENDPOINT_MODE = "account_id_endpoint_mode";
export const NODE_ACCOUNT_ID_ENDPOINT_MODE_CONFIG_OPTIONS = {
environmentVariableSelector: (env) => {
const value = env[ENV_ACCOUNT_ID_ENDPOINT_MODE];
if (value && !validateAccountIdEndpointMode(value)) {
_throw(err);
}
return value;
},
configFileSelector: (profile) => {
const value = profile[CONFIG_ACCOUNT_ID_ENDPOINT_MODE];
if (value && !validateAccountIdEndpointMode(value)) {
_throw(err);
}
return value;
},
default: DEFAULT_ACCOUNT_ID_ENDPOINT_MODE,
};
@@ -0,0 +1,3 @@
export * from "./AccountIdEndpointModeConfigResolver";
export * from "./AccountIdEndpointModeConstants";
export * from "./NodeAccountIdEndpointModeConfigOptions";
@@ -0,0 +1,24 @@
export const state = {
warningEmitted: false,
};
export const emitWarningIfUnsupportedVersion = (version) => {
if (version && !state.warningEmitted) {
if (process.env.AWS_SDK_JS_NODE_VERSION_SUPPORT_WARNING_DISABLED === "true") {
state.warningEmitted = true;
return;
}
const userMajorVersion = parseInt(version.substring(1, version.indexOf(".")));
const vv = 22;
if (userMajorVersion < vv) {
state.warningEmitted = true;
process.emitWarning(`NodeVersionSupportWarning: The AWS SDK for JavaScript (v3)
versions published after the first week of January 2027
will require node >=${vv}. You are running node ${version}.
To continue receiving updates to AWS services, bug fixes,
and security updates please upgrade to node >=${vv}.
More information can be found at: https://a.co/c895JFp`);
}
}
};
+36
View File
@@ -0,0 +1,36 @@
const no = Symbol.for("node-only");
export const emitWarningIfUnsupportedVersion = no;
export const state = no;
export { getLongPollPlugin } from "./longPollMiddleware";
export { setCredentialFeature } from "./setCredentialFeature";
export { setFeature } from "./setFeature";
export { setTokenFeature } from "./setTokenFeature";
export { hostHeaderMiddleware, hostHeaderMiddlewareOptions, getHostHeaderPlugin, resolveHostHeaderConfig, } from "./middleware-host-header/hostHeaderMiddleware";
export { loggerMiddleware, loggerMiddlewareOptions, getLoggerPlugin } from "./middleware-logger/loggerMiddleware";
export { recursionDetectionMiddlewareOptions } from "./middleware-recursion-detection/configuration";
export { getRecursionDetectionPlugin } from "./middleware-recursion-detection/getRecursionDetectionPlugin.browser";
export { recursionDetectionMiddleware } from "./middleware-recursion-detection/recursionDetectionMiddleware.browser";
export { DEFAULT_UA_APP_ID, resolveUserAgentConfig } from "./middleware-user-agent/configurations";
export { userAgentMiddleware, getUserAgentMiddlewareOptions, getUserAgentPlugin, } from "./middleware-user-agent/user-agent-middleware";
export { createDefaultUserAgentProvider, defaultUserAgent, fallback } from "./util-user-agent-browser/defaultUserAgent";
export const crtAvailability = no;
export const NODE_APP_ID_CONFIG_OPTIONS = no;
export const UA_APP_ID_ENV_NAME = no;
export const UA_APP_ID_INI_NAME = no;
export { createUserAgentStringParsingProvider } from "./util-user-agent-browser/createUserAgentStringParsingProvider";
export { awsEndpointFunctions } from "./util-endpoints/aws";
export { resolveEndpoint } from "./util-endpoints/resolveEndpoint";
export { resolveDefaultAwsRegionalEndpointsConfig, toEndpointV1, } from "./util-endpoints/resolveDefaultAwsRegionalEndpointsConfig";
export { isIpAddress } from "./util-endpoints/lib/isIpAddress";
export { isVirtualHostableS3Bucket } from "./util-endpoints/lib/aws/isVirtualHostableS3Bucket";
export { parseArn } from "./util-endpoints/lib/aws/parseArn";
export { partition, setPartitionInfo, useDefaultPartitionInfo, getUserAgentPrefix, } from "./util-endpoints/lib/aws/partition";
export { EndpointError } from "./util-endpoints/types/EndpointError";
export const REGION_ENV_NAME = no;
export const REGION_INI_NAME = no;
export const NODE_REGION_CONFIG_OPTIONS = no;
export const NODE_REGION_CONFIG_FILE_OPTIONS = no;
export { resolveRegionConfig } from "./region-config-resolver/awsRegionConfig";
export { stsRegionDefaultResolver } from "./region-config-resolver/stsRegionDefaultResolver.browser";
export const stsRegionWarning = no;
export { getAwsRegionExtensionConfiguration, resolveAwsRegionExtensionConfiguration, } from "./region-config-resolver/extensions";
+27
View File
@@ -0,0 +1,27 @@
export { emitWarningIfUnsupportedVersion, state } from "./emitWarningIfUnsupportedVersion";
export { getLongPollPlugin } from "./longPollMiddleware";
export { setCredentialFeature } from "./setCredentialFeature";
export { setFeature } from "./setFeature";
export { setTokenFeature } from "./setTokenFeature";
export { hostHeaderMiddleware, hostHeaderMiddlewareOptions, getHostHeaderPlugin, resolveHostHeaderConfig, } from "./middleware-host-header/hostHeaderMiddleware";
export { loggerMiddleware, loggerMiddlewareOptions, getLoggerPlugin } from "./middleware-logger/loggerMiddleware";
export { recursionDetectionMiddlewareOptions } from "./middleware-recursion-detection/configuration";
export { getRecursionDetectionPlugin } from "./middleware-recursion-detection/getRecursionDetectionPlugin";
export { recursionDetectionMiddleware } from "./middleware-recursion-detection/recursionDetectionMiddleware";
export { DEFAULT_UA_APP_ID, resolveUserAgentConfig } from "./middleware-user-agent/configurations";
export { userAgentMiddleware, getUserAgentMiddlewareOptions, getUserAgentPlugin, } from "./middleware-user-agent/user-agent-middleware";
export { createDefaultUserAgentProvider, defaultUserAgent, crtAvailability, } from "./util-user-agent-node/defaultUserAgent";
export { NODE_APP_ID_CONFIG_OPTIONS, UA_APP_ID_ENV_NAME, UA_APP_ID_INI_NAME, } from "./util-user-agent-node/nodeAppIdConfigOptions";
export { fallback } from "./util-user-agent-browser/defaultUserAgent";
export { createUserAgentStringParsingProvider } from "./util-user-agent-browser/createUserAgentStringParsingProvider";
export { awsEndpointFunctions } from "./util-endpoints/aws";
export { resolveEndpoint } from "./util-endpoints/resolveEndpoint";
export { resolveDefaultAwsRegionalEndpointsConfig, toEndpointV1, } from "./util-endpoints/resolveDefaultAwsRegionalEndpointsConfig";
export { isIpAddress } from "./util-endpoints/lib/isIpAddress";
export { isVirtualHostableS3Bucket } from "./util-endpoints/lib/aws/isVirtualHostableS3Bucket";
export { parseArn } from "./util-endpoints/lib/aws/parseArn";
export { partition, setPartitionInfo, useDefaultPartitionInfo, getUserAgentPrefix, } from "./util-endpoints/lib/aws/partition";
export { EndpointError } from "./util-endpoints/types/EndpointError";
export { REGION_ENV_NAME, REGION_INI_NAME, NODE_REGION_CONFIG_OPTIONS, NODE_REGION_CONFIG_FILE_OPTIONS, resolveRegionConfig, } from "./region-config-resolver/awsRegionConfig";
export { stsRegionDefaultResolver, warning as stsRegionWarning, } from "./region-config-resolver/stsRegionDefaultResolver";
export { getAwsRegionExtensionConfiguration, resolveAwsRegionExtensionConfiguration, } from "./region-config-resolver/extensions";
+37
View File
@@ -0,0 +1,37 @@
const no = Symbol.for("node-only");
export const emitWarningIfUnsupportedVersion = no;
export const state = no;
export { getLongPollPlugin } from "./longPollMiddleware";
export { setCredentialFeature } from "./setCredentialFeature";
export { setFeature } from "./setFeature";
export { setTokenFeature } from "./setTokenFeature";
export { hostHeaderMiddleware, hostHeaderMiddlewareOptions, getHostHeaderPlugin, resolveHostHeaderConfig, } from "./middleware-host-header/hostHeaderMiddleware";
export { loggerMiddleware, loggerMiddlewareOptions, getLoggerPlugin } from "./middleware-logger/loggerMiddleware";
export { recursionDetectionMiddlewareOptions } from "./middleware-recursion-detection/configuration";
export { getRecursionDetectionPlugin } from "./middleware-recursion-detection/getRecursionDetectionPlugin.browser";
export { recursionDetectionMiddleware } from "./middleware-recursion-detection/recursionDetectionMiddleware.native";
export { DEFAULT_UA_APP_ID, resolveUserAgentConfig } from "./middleware-user-agent/configurations";
export { userAgentMiddleware, getUserAgentMiddlewareOptions, getUserAgentPlugin, } from "./middleware-user-agent/user-agent-middleware";
export { createDefaultUserAgentProvider, defaultUserAgent } from "./util-user-agent-browser/defaultUserAgent.native";
export const crtAvailability = no;
export const NODE_APP_ID_CONFIG_OPTIONS = no;
export const UA_APP_ID_ENV_NAME = no;
export const UA_APP_ID_INI_NAME = no;
export { fallback } from "./util-user-agent-browser/defaultUserAgent";
export { createUserAgentStringParsingProvider } from "./util-user-agent-browser/createUserAgentStringParsingProvider";
export { awsEndpointFunctions } from "./util-endpoints/aws";
export { resolveEndpoint } from "./util-endpoints/resolveEndpoint";
export { resolveDefaultAwsRegionalEndpointsConfig, toEndpointV1, } from "./util-endpoints/resolveDefaultAwsRegionalEndpointsConfig";
export { isIpAddress } from "./util-endpoints/lib/isIpAddress";
export { isVirtualHostableS3Bucket } from "./util-endpoints/lib/aws/isVirtualHostableS3Bucket";
export { parseArn } from "./util-endpoints/lib/aws/parseArn";
export { partition, setPartitionInfo, useDefaultPartitionInfo, getUserAgentPrefix, } from "./util-endpoints/lib/aws/partition";
export { EndpointError } from "./util-endpoints/types/EndpointError";
export const REGION_ENV_NAME = no;
export const REGION_INI_NAME = no;
export const NODE_REGION_CONFIG_OPTIONS = no;
export const NODE_REGION_CONFIG_FILE_OPTIONS = no;
export { resolveRegionConfig } from "./region-config-resolver/awsRegionConfig";
export { stsRegionDefaultResolver } from "./region-config-resolver/stsRegionDefaultResolver.native";
export const stsRegionWarning = no;
export { getAwsRegionExtensionConfiguration, resolveAwsRegionExtensionConfiguration, } from "./region-config-resolver/extensions";
@@ -0,0 +1,15 @@
export const longPollMiddleware = () => (next, context) => async (args) => {
context.__retryLongPoll = true;
return next(args);
};
export const longPollMiddlewareOptions = {
name: "longPollMiddleware",
tags: ["RETRY"],
step: "initialize",
override: true,
};
export const getLongPollPlugin = (options) => ({
applyToStack: (clientStack) => {
clientStack.add(longPollMiddleware(), longPollMiddlewareOptions);
},
});
@@ -0,0 +1,33 @@
import { HttpRequest } from "@smithy/core/protocols";
export function resolveHostHeaderConfig(input) {
return input;
}
export const hostHeaderMiddleware = (options) => (next) => async (args) => {
if (!HttpRequest.isInstance(args.request))
return next(args);
const { request } = args;
const { handlerProtocol = "" } = options.requestHandler.metadata || {};
if (handlerProtocol.indexOf("h2") >= 0 && !request.headers[":authority"]) {
delete request.headers["host"];
request.headers[":authority"] = request.hostname + (request.port ? ":" + request.port : "");
}
else if (!request.headers["host"]) {
let host = request.hostname;
if (request.port != null)
host += `:${request.port}`;
request.headers["host"] = host;
}
return next(args);
};
export const hostHeaderMiddlewareOptions = {
name: "hostHeaderMiddleware",
step: "build",
priority: "low",
tags: ["HOST"],
override: true,
};
export const getHostHeaderPlugin = (options) => ({
applyToStack: (clientStack) => {
clientStack.add(hostHeaderMiddleware(options), hostHeaderMiddlewareOptions);
},
});
@@ -0,0 +1,42 @@
export const loggerMiddleware = () => (next, context) => async (args) => {
try {
const response = await next(args);
const { clientName, commandName, logger, dynamoDbDocumentClientOptions = {} } = context;
const { overrideInputFilterSensitiveLog, overrideOutputFilterSensitiveLog } = dynamoDbDocumentClientOptions;
const inputFilterSensitiveLog = overrideInputFilterSensitiveLog ?? context.inputFilterSensitiveLog;
const outputFilterSensitiveLog = overrideOutputFilterSensitiveLog ?? context.outputFilterSensitiveLog;
const { $metadata, ...outputWithoutMetadata } = response.output;
logger?.info?.({
clientName,
commandName,
input: inputFilterSensitiveLog(args.input),
output: outputFilterSensitiveLog(outputWithoutMetadata),
metadata: $metadata,
});
return response;
}
catch (error) {
const { clientName, commandName, logger, dynamoDbDocumentClientOptions = {} } = context;
const { overrideInputFilterSensitiveLog } = dynamoDbDocumentClientOptions;
const inputFilterSensitiveLog = overrideInputFilterSensitiveLog ?? context.inputFilterSensitiveLog;
logger?.error?.({
clientName,
commandName,
input: inputFilterSensitiveLog(args.input),
error,
metadata: error.$metadata,
});
throw error;
}
};
export const loggerMiddlewareOptions = {
name: "loggerMiddleware",
tags: ["LOGGER"],
step: "initialize",
override: true,
};
export const getLoggerPlugin = (options) => ({
applyToStack: (clientStack) => {
clientStack.add(loggerMiddleware(), loggerMiddlewareOptions);
},
});
@@ -0,0 +1,7 @@
export const recursionDetectionMiddlewareOptions = {
step: "build",
tags: ["RECURSION_DETECTION"],
name: "recursionDetectionMiddleware",
override: true,
priority: "low",
};
@@ -0,0 +1,3 @@
export const getRecursionDetectionPlugin = (options) => ({
applyToStack: (clientStack) => { },
});
@@ -0,0 +1,7 @@
import { recursionDetectionMiddlewareOptions } from "./configuration";
import { recursionDetectionMiddleware } from "./recursionDetectionMiddleware";
export const getRecursionDetectionPlugin = (options) => ({
applyToStack: (clientStack) => {
clientStack.add(recursionDetectionMiddleware(), recursionDetectionMiddlewareOptions);
},
});
@@ -0,0 +1 @@
export const recursionDetectionMiddleware = () => (next) => async (args) => next(args);
@@ -0,0 +1,29 @@
import { InvokeStore } from "@aws/lambda-invoke-store";
import { HttpRequest } from "@smithy/core/protocols";
const TRACE_ID_HEADER_NAME = "X-Amzn-Trace-Id";
const ENV_LAMBDA_FUNCTION_NAME = "AWS_LAMBDA_FUNCTION_NAME";
const ENV_TRACE_ID = "_X_AMZN_TRACE_ID";
export const recursionDetectionMiddleware = () => (next) => async (args) => {
const { request } = args;
if (!HttpRequest.isInstance(request)) {
return next(args);
}
const traceIdHeader = Object.keys(request.headers ?? {}).find((h) => h.toLowerCase() === TRACE_ID_HEADER_NAME.toLowerCase()) ??
TRACE_ID_HEADER_NAME;
if (request.headers.hasOwnProperty(traceIdHeader)) {
return next(args);
}
const functionName = process.env[ENV_LAMBDA_FUNCTION_NAME];
const traceIdFromEnv = process.env[ENV_TRACE_ID];
const invokeStore = await InvokeStore.getInstanceAsync();
const traceIdFromInvokeStore = invokeStore?.getXRayTraceId();
const traceId = traceIdFromInvokeStore ?? traceIdFromEnv;
const nonEmptyString = (str) => typeof str === "string" && str.length > 0;
if (nonEmptyString(functionName) && nonEmptyString(traceId)) {
request.headers[TRACE_ID_HEADER_NAME] = traceId;
}
return next({
...args,
request,
});
};
@@ -0,0 +1 @@
export const recursionDetectionMiddleware = () => (next) => async (args) => next(args);
@@ -0,0 +1,49 @@
import { RETRY_MODES } from "@smithy/core/retry";
import { setFeature } from "../setFeature";
const ACCOUNT_ID_ENDPOINT_REGEX = /\d{12}\.ddb/;
export async function checkFeatures(context, config, args) {
const request = args.request;
if (request?.headers?.["smithy-protocol"] === "rpc-v2-cbor") {
setFeature(context, "PROTOCOL_RPC_V2_CBOR", "M");
}
if (typeof config.retryStrategy === "function") {
const retryStrategy = await config.retryStrategy();
if (typeof retryStrategy.mode === "string") {
switch (retryStrategy.mode) {
case RETRY_MODES.ADAPTIVE:
setFeature(context, "RETRY_MODE_ADAPTIVE", "F");
break;
case RETRY_MODES.STANDARD:
setFeature(context, "RETRY_MODE_STANDARD", "E");
break;
}
}
}
if (typeof config.accountIdEndpointMode === "function") {
const endpointV2 = context.endpointV2;
if (String(endpointV2?.url?.hostname).match(ACCOUNT_ID_ENDPOINT_REGEX)) {
setFeature(context, "ACCOUNT_ID_ENDPOINT", "O");
}
switch (await config.accountIdEndpointMode?.()) {
case "disabled":
setFeature(context, "ACCOUNT_ID_MODE_DISABLED", "Q");
break;
case "preferred":
setFeature(context, "ACCOUNT_ID_MODE_PREFERRED", "P");
break;
case "required":
setFeature(context, "ACCOUNT_ID_MODE_REQUIRED", "R");
break;
}
}
const identity = context.__smithy_context?.selectedHttpAuthScheme?.identity;
if (identity?.$source) {
const credentials = identity;
if (credentials.accountId) {
setFeature(context, "RESOLVED_ACCOUNT_ID", "T");
}
for (const [key, value] of Object.entries(credentials.$source ?? {})) {
setFeature(context, key, value);
}
}
}
@@ -0,0 +1,28 @@
import { normalizeProvider } from "@smithy/core";
export const DEFAULT_UA_APP_ID = undefined;
function isValidUserAgentAppId(appId) {
if (appId === undefined) {
return true;
}
return typeof appId === "string" && appId.length <= 50;
}
export function resolveUserAgentConfig(input) {
const normalizedAppIdProvider = normalizeProvider(input.userAgentAppId ?? DEFAULT_UA_APP_ID);
const { customUserAgent } = input;
return Object.assign(input, {
customUserAgent: typeof customUserAgent === "string" ? [[customUserAgent]] : customUserAgent,
userAgentAppId: async () => {
const appId = await normalizedAppIdProvider();
if (!isValidUserAgentAppId(appId)) {
const logger = input.logger?.constructor?.name === "NoOpLogger" || !input.logger ? console : input.logger;
if (typeof appId !== "string") {
logger?.warn("userAgentAppId must be a string or undefined.");
}
else if (appId.length > 50) {
logger?.warn("The provided userAgentAppId exceeds the maximum length of 50 characters.");
}
}
return appId;
},
});
}
@@ -0,0 +1,7 @@
export const USER_AGENT = "user-agent";
export const X_AMZ_USER_AGENT = "x-amz-user-agent";
export const SPACE = " ";
export const UA_NAME_SEPARATOR = "/";
export const UA_NAME_ESCAPE_REGEX = /[^!$%&'*+\-.^_`|~\w]/g;
export const UA_VALUE_ESCAPE_REGEX = /[^!$%&'*+\-.^_`|~\w#]/g;
export const UA_ESCAPE_CHAR = "-";
@@ -0,0 +1,18 @@
const BYTE_LIMIT = 1024;
export function encodeFeatures(features) {
let buffer = "";
for (const key in features) {
const val = features[key];
if (buffer.length + val.length + 1 <= BYTE_LIMIT) {
if (buffer.length) {
buffer += "," + val;
}
else {
buffer += val;
}
continue;
}
break;
}
return buffer;
}
@@ -0,0 +1,82 @@
import { HttpRequest } from "@smithy/core/protocols";
import { getUserAgentPrefix } from "../util-endpoints/lib/aws/partition";
import { checkFeatures } from "./check-features";
import { SPACE, UA_ESCAPE_CHAR, UA_NAME_ESCAPE_REGEX, UA_NAME_SEPARATOR, UA_VALUE_ESCAPE_REGEX, USER_AGENT, X_AMZ_USER_AGENT, } from "./constants";
import { encodeFeatures } from "./encode-features";
export const userAgentMiddleware = (options) => (next, context) => async (args) => {
const { request } = args;
if (!HttpRequest.isInstance(request)) {
return next(args);
}
const { headers } = request;
const userAgent = context?.userAgent?.map(escapeUserAgent) || [];
const defaultUserAgent = (await options.defaultUserAgentProvider()).map(escapeUserAgent);
await checkFeatures(context, options, args);
const awsContext = context;
defaultUserAgent.push(`m/${encodeFeatures(Object.assign({}, context.__smithy_context?.features, awsContext.__aws_sdk_context?.features))}`);
const customUserAgent = options?.customUserAgent?.map(escapeUserAgent) || [];
const appId = await options.userAgentAppId();
if (appId) {
defaultUserAgent.push(escapeUserAgent([`app`, `${appId}`]));
}
const prefix = getUserAgentPrefix();
const sdkUserAgentValue = (prefix ? [prefix] : [])
.concat([...defaultUserAgent, ...userAgent, ...customUserAgent])
.join(SPACE);
const normalUAValue = [
...defaultUserAgent.filter((section) => section.startsWith("aws-sdk-")),
...customUserAgent,
].join(SPACE);
if (options.runtime !== "browser") {
if (normalUAValue) {
headers[X_AMZ_USER_AGENT] = headers[X_AMZ_USER_AGENT]
? `${headers[USER_AGENT]} ${normalUAValue}`
: normalUAValue;
}
headers[USER_AGENT] = sdkUserAgentValue;
}
else {
headers[X_AMZ_USER_AGENT] = sdkUserAgentValue;
}
return next({
...args,
request,
});
};
const escapeUserAgent = (userAgentPair) => {
const name = userAgentPair[0]
.split(UA_NAME_SEPARATOR)
.map((part) => part.replace(UA_NAME_ESCAPE_REGEX, UA_ESCAPE_CHAR))
.join(UA_NAME_SEPARATOR);
const version = userAgentPair[1]?.replace(UA_VALUE_ESCAPE_REGEX, UA_ESCAPE_CHAR);
const prefixSeparatorIndex = name.indexOf(UA_NAME_SEPARATOR);
const prefix = name.substring(0, prefixSeparatorIndex);
let uaName = name.substring(prefixSeparatorIndex + 1);
if (prefix === "api") {
uaName = uaName.toLowerCase();
}
return [prefix, uaName, version]
.filter((item) => item && item.length > 0)
.reduce((acc, item, index) => {
switch (index) {
case 0:
return item;
case 1:
return `${acc}/${item}`;
default:
return `${acc}#${item}`;
}
}, "");
};
export const getUserAgentMiddlewareOptions = {
name: "getUserAgentMiddleware",
step: "build",
priority: "low",
tags: ["SET_USER_AGENT", "USER_AGENT"],
override: true,
};
export const getUserAgentPlugin = (config) => ({
applyToStack: (clientStack) => {
clientStack.add(userAgentMiddleware(config), getUserAgentMiddlewareOptions);
},
});
@@ -0,0 +1,2 @@
export { REGION_ENV_NAME, REGION_INI_NAME, NODE_REGION_CONFIG_OPTIONS, NODE_REGION_CONFIG_FILE_OPTIONS, } from "@smithy/core/config";
export { resolveRegionConfig } from "@smithy/core/config";
@@ -0,0 +1,15 @@
export const getAwsRegionExtensionConfiguration = (runtimeConfig) => {
return {
setRegion(region) {
runtimeConfig.region = region;
},
region() {
return runtimeConfig.region;
},
};
};
export const resolveAwsRegionExtensionConfiguration = (awsRegionExtensionConfiguration) => {
return {
region: awsRegionExtensionConfiguration.region(),
};
};
@@ -0,0 +1,3 @@
export function stsRegionDefaultResolver() {
return async () => "us-east-1";
}
@@ -0,0 +1,15 @@
import { loadConfig, NODE_REGION_CONFIG_FILE_OPTIONS, NODE_REGION_CONFIG_OPTIONS, } from "@smithy/core/config";
export function stsRegionDefaultResolver(loaderConfig = {}) {
return loadConfig({
...NODE_REGION_CONFIG_OPTIONS,
async default() {
if (!warning.silence) {
console.warn("@aws-sdk - WARN - default STS region of us-east-1 used. See @aws-sdk/credential-providers README and set a region explicitly.");
}
return "us-east-1";
},
}, { ...NODE_REGION_CONFIG_FILE_OPTIONS, ...loaderConfig });
}
export const warning = {
silence: false,
};
@@ -0,0 +1,3 @@
export function stsRegionDefaultResolver() {
return async () => "us-east-1";
}
@@ -0,0 +1,7 @@
export function setCredentialFeature(credentials, feature, value) {
if (!credentials.$source) {
credentials.$source = {};
}
credentials.$source[feature] = value;
return credentials;
}
+13
View File
@@ -0,0 +1,13 @@
import { Retry } from "@smithy/core/retry";
Retry.v2026 ||= typeof process === "object" && process.env?.AWS_NEW_RETRIES_2026 === "true";
export function setFeature(context, feature, value) {
if (!context.__aws_sdk_context) {
context.__aws_sdk_context = {
features: {},
};
}
else if (!context.__aws_sdk_context.features) {
context.__aws_sdk_context.features = {};
}
context.__aws_sdk_context.features[feature] = value;
}
@@ -0,0 +1,7 @@
export function setTokenFeature(token, feature, value) {
if (!token.$source) {
token.$source = {};
}
token.$source[feature] = value;
return token;
}
@@ -0,0 +1,10 @@
import { customEndpointFunctions } from "@smithy/core/endpoints";
import { isVirtualHostableS3Bucket } from "./lib/aws/isVirtualHostableS3Bucket";
import { parseArn } from "./lib/aws/parseArn";
import { partition } from "./lib/aws/partition";
export const awsEndpointFunctions = {
isVirtualHostableS3Bucket: isVirtualHostableS3Bucket,
parseArn: parseArn,
partition: partition,
};
customEndpointFunctions.aws = awsEndpointFunctions;
@@ -0,0 +1,25 @@
import { isValidHostLabel } from "@smithy/core/endpoints";
import { isIpAddress } from "../isIpAddress";
export const isVirtualHostableS3Bucket = (value, allowSubDomains = false) => {
if (allowSubDomains) {
for (const label of value.split(".")) {
if (!isVirtualHostableS3Bucket(label)) {
return false;
}
}
return true;
}
if (!isValidHostLabel(value)) {
return false;
}
if (value.length < 3 || value.length > 63) {
return false;
}
if (value !== value.toLowerCase()) {
return false;
}
if (isIpAddress(value)) {
return false;
}
return true;
};
@@ -0,0 +1,18 @@
const ARN_DELIMITER = ":";
const RESOURCE_DELIMITER = "/";
export const parseArn = (value) => {
const segments = value.split(ARN_DELIMITER);
if (segments.length < 6)
return null;
const [arn, partition, service, region, accountId, ...resourcePath] = segments;
if (arn !== "arn" || partition === "" || service === "" || resourcePath.join(ARN_DELIMITER) === "")
return null;
const resourceId = resourcePath.map((resource) => resource.split(RESOURCE_DELIMITER)).flat();
return {
partition,
service,
region,
accountId,
resourceId,
};
};
@@ -0,0 +1,41 @@
import { partitionsInfo } from "./partitions";
let selectedPartitionsInfo = partitionsInfo;
let selectedUserAgentPrefix = "";
export const partition = (value) => {
const { partitions } = selectedPartitionsInfo;
for (const partition of partitions) {
const { regions, outputs } = partition;
for (const [region, regionData] of Object.entries(regions)) {
if (region === value) {
return {
...outputs,
...regionData,
};
}
}
}
for (const partition of partitions) {
const { regionRegex, outputs } = partition;
if (new RegExp(regionRegex).test(value)) {
return {
...outputs,
};
}
}
const DEFAULT_PARTITION = partitions.find((partition) => partition.id === "aws");
if (!DEFAULT_PARTITION) {
throw new Error("Provided region was not found in the partition array or regex," +
" and default partition with id 'aws' doesn't exist.");
}
return {
...DEFAULT_PARTITION.outputs,
};
};
export const setPartitionInfo = (partitionsInfo, userAgentPrefix = "") => {
selectedPartitionsInfo = partitionsInfo;
selectedUserAgentPrefix = userAgentPrefix;
};
export const useDefaultPartitionInfo = () => {
setPartitionInfo(partitionsInfo, "");
};
export const getUserAgentPrefix = () => selectedUserAgentPrefix;
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
export { isIpAddress } from "@smithy/core/endpoints";
@@ -0,0 +1,21 @@
import { parseUrl } from "@smithy/core/protocols";
export const resolveDefaultAwsRegionalEndpointsConfig = (input) => {
if (typeof input.endpointProvider !== "function") {
throw new Error("@aws-sdk/util-endpoint - endpointProvider and endpoint missing in config for this client.");
}
const { endpoint } = input;
if (endpoint === undefined) {
input.endpoint = async () => {
return toEndpointV1(input.endpointProvider({
Region: typeof input.region === "function" ? await input.region() : input.region,
UseDualStack: typeof input.useDualstackEndpoint === "function"
? await input.useDualstackEndpoint()
: input.useDualstackEndpoint,
UseFIPS: typeof input.useFipsEndpoint === "function" ? await input.useFipsEndpoint() : input.useFipsEndpoint,
Endpoint: undefined,
}, { logger: input.logger }));
};
}
return input;
};
export const toEndpointV1 = (endpoint) => parseUrl(endpoint.url);
@@ -0,0 +1 @@
export { resolveEndpoint } from "@smithy/core/endpoints";
@@ -0,0 +1 @@
export { EndpointError } from "@smithy/core/endpoints";
@@ -0,0 +1 @@
export {};
@@ -0,0 +1 @@
export {};
@@ -0,0 +1 @@
export {};
@@ -0,0 +1 @@
export {};
@@ -0,0 +1 @@
export {};
@@ -0,0 +1 @@
export {};
@@ -0,0 +1,20 @@
export const createUserAgentStringParsingProvider = ({ serviceId, clientVersion }) => async (config) => {
const module = await import("bowser");
const parse = module.parse ?? module.default.parse ?? (() => "");
const parsedUA = typeof window !== "undefined" && window?.navigator?.userAgent ? parse(window.navigator.userAgent) : undefined;
const sections = [
["aws-sdk-js", clientVersion],
["ua", "2.1"],
[`os/${parsedUA?.os?.name || "other"}`, parsedUA?.os?.version],
["lang/js"],
["md/browser", `${parsedUA?.browser?.name ?? "unknown"}_${parsedUA?.browser?.version ?? "unknown"}`],
];
if (serviceId) {
sections.push([`api/${serviceId}`, clientVersion]);
}
const appId = await config?.userAgentAppId?.();
if (appId) {
sections.push([`app/${appId}`]);
}
return sections;
};
@@ -0,0 +1 @@
export * from "./defaultUserAgent";
@@ -0,0 +1,53 @@
export { createUserAgentStringParsingProvider } from "./createUserAgentStringParsingProvider";
export const createDefaultUserAgentProvider = ({ serviceId, clientVersion }) => async (config) => {
const navigator = typeof window !== "undefined" ? window.navigator : undefined;
const uaString = navigator?.userAgent ?? "";
const osName = navigator?.userAgentData?.platform ?? fallback.os(uaString) ?? "other";
const osVersion = undefined;
const brands = navigator?.userAgentData?.brands ?? [];
const brand = brands[brands.length - 1];
const browserName = brand?.brand ?? fallback.browser(uaString) ?? "unknown";
const browserVersion = brand?.version ?? "unknown";
const sections = [
["aws-sdk-js", clientVersion],
["ua", "2.1"],
[`os/${osName}`, osVersion],
["lang/js"],
["md/browser", `${browserName}_${browserVersion}`],
];
if (serviceId) {
sections.push([`api/${serviceId}`, clientVersion]);
}
const appId = await config?.userAgentAppId?.();
if (appId) {
sections.push([`app/${appId}`]);
}
return sections;
};
export const fallback = {
os(ua) {
if (/iPhone|iPad|iPod/.test(ua))
return "iOS";
if (/Macintosh|Mac OS X/.test(ua))
return "macOS";
if (/Windows NT/.test(ua))
return "Windows";
if (/Android/.test(ua))
return "Android";
if (/Linux/.test(ua))
return "Linux";
return undefined;
},
browser(ua) {
if (/EdgiOS|EdgA|Edg\//.test(ua))
return "Microsoft Edge";
if (/Firefox\//.test(ua))
return "Firefox";
if (/Chrome\//.test(ua))
return "Chrome";
if (/Safari\//.test(ua))
return "Safari";
return undefined;
},
};
export const defaultUserAgent = createDefaultUserAgentProvider;
@@ -0,0 +1,18 @@
export const createDefaultUserAgentProvider = ({ serviceId, clientVersion }) => async (config) => {
const sections = [
["aws-sdk-js", clientVersion],
["ua", "2.1"],
["os/other"],
["lang/js"],
["md/rn"],
];
if (serviceId) {
sections.push([`api/${serviceId}`, clientVersion]);
}
const appId = await config?.userAgentAppId?.();
if (appId) {
sections.push([`app/${appId}`]);
}
return sections;
};
export const defaultUserAgent = createDefaultUserAgentProvider;
@@ -0,0 +1,3 @@
export const crtAvailability = {
isCrtAvailable: false,
};
@@ -0,0 +1,36 @@
import { platform, release } from "node:os";
import { env } from "node:process";
import { getRuntimeUserAgentPair } from "./getRuntimeUserAgentPair";
import { getTypeScriptUserAgentPair } from "./getTypeScriptUserAgentPair";
import { isCrtAvailable } from "./is-crt-available";
export { crtAvailability } from "./crt-availability";
export const createDefaultUserAgentProvider = ({ serviceId, clientVersion }) => {
const runtimeUserAgentPair = getRuntimeUserAgentPair();
return async (config) => {
const sections = [
["aws-sdk-js", clientVersion],
["ua", "2.1"],
[`os/${platform()}`, release()],
["lang/js"],
runtimeUserAgentPair,
];
const typescriptUserAgentPair = await getTypeScriptUserAgentPair();
if (typescriptUserAgentPair) {
sections.push(typescriptUserAgentPair);
}
const crtAvailable = isCrtAvailable();
if (crtAvailable) {
sections.push(crtAvailable);
}
if (serviceId) {
sections.push([`api/${serviceId}`, clientVersion]);
}
if (env.AWS_EXECUTION_ENV) {
sections.push([`exec-env/${env.AWS_EXECUTION_ENV}`]);
}
const appId = await config?.userAgentAppId?.();
const resolvedUserAgent = appId ? [...sections, [`app/${appId}`]] : [...sections];
return resolvedUserAgent;
};
};
export const defaultUserAgent = createDefaultUserAgentProvider;
@@ -0,0 +1,15 @@
import { normalize, sep } from "node:path";
export const getNodeModulesParentDirs = (dirname) => {
const cwd = process.cwd();
if (!dirname) {
return [cwd];
}
const normalizedPath = normalize(dirname);
const parts = normalizedPath.split(sep);
const nodeModulesIndex = parts.indexOf("node_modules");
const parentDir = nodeModulesIndex !== -1 ? parts.slice(0, nodeModulesIndex).join(sep) : normalizedPath;
if (cwd === parentDir) {
return [cwd];
}
return [parentDir, cwd];
};
@@ -0,0 +1,10 @@
import { versions } from "node:process";
export const getRuntimeUserAgentPair = () => {
const runtimesToCheck = ["deno", "bun", "llrt"];
for (const runtime of runtimesToCheck) {
if (versions[runtime]) {
return [`md/${runtime}`, versions[runtime]];
}
}
return ["md/nodejs", versions.node];
};
@@ -0,0 +1,14 @@
import { getSanitizedTypeScriptVersion } from "./getSanitizedTypeScriptVersion";
const ALLOWED_PREFIXES = ["^", "~", ">=", "<=", ">", "<"];
const ALLOWED_DIST_TAGS = ["latest", "beta", "dev", "rc", "insiders", "next"];
export const getSanitizedDevTypeScriptVersion = (version = "") => {
if (ALLOWED_DIST_TAGS.includes(version)) {
return version;
}
const prefix = ALLOWED_PREFIXES.find((p) => version.startsWith(p)) ?? "";
const sanitizedTypeScriptVersion = getSanitizedTypeScriptVersion(version.slice(prefix.length));
if (!sanitizedTypeScriptVersion) {
return undefined;
}
return `${prefix}${sanitizedTypeScriptVersion}`;
};
@@ -0,0 +1,9 @@
const SEMVER_REGEX = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*)?$/;
export const getSanitizedTypeScriptVersion = (version = "") => {
const match = version.match(SEMVER_REGEX);
if (!match) {
return undefined;
}
const [major, minor, patch, prerelease] = [match[1], match[2], match[3], match[4]];
return prerelease ? `${major}.${minor}.${patch}-${prerelease}` : `${major}.${minor}.${patch}`;
};
@@ -0,0 +1,75 @@
import { booleanSelector, SelectorType } from "@smithy/core/config";
import { readFile } from "node:fs/promises";
import { join } from "node:path";
import { getNodeModulesParentDirs } from "./getNodeModulesParentDirs";
import { getSanitizedDevTypeScriptVersion } from "./getSanitizedDevTypeScriptVersion";
import { getSanitizedTypeScriptVersion } from "./getSanitizedTypeScriptVersion";
let tscVersion;
const TS_PACKAGE_JSON = join("node_modules", "typescript", "package.json");
export const getTypeScriptUserAgentPair = async () => {
if (tscVersion === null) {
return undefined;
}
else if (typeof tscVersion === "string") {
return ["md/tsc", tscVersion];
}
let isTypeScriptDetectionDisabled = false;
try {
isTypeScriptDetectionDisabled =
booleanSelector(process.env, "AWS_SDK_JS_TYPESCRIPT_DETECTION_DISABLED", SelectorType.ENV) || false;
}
catch { }
if (isTypeScriptDetectionDisabled) {
tscVersion = null;
return undefined;
}
const dirname = typeof __dirname !== "undefined" ? __dirname : undefined;
const nodeModulesParentDirs = getNodeModulesParentDirs(dirname);
let versionFromApp;
for (const nodeModulesParentDir of nodeModulesParentDirs) {
try {
const appPackageJsonPath = join(nodeModulesParentDir, "package.json");
const packageJson = await readFile(appPackageJsonPath, "utf-8");
const { dependencies, devDependencies } = JSON.parse(packageJson);
const version = devDependencies?.typescript ?? dependencies?.typescript;
if (typeof version !== "string") {
continue;
}
versionFromApp = version;
break;
}
catch {
}
}
if (!versionFromApp) {
tscVersion = null;
return undefined;
}
let versionFromNodeModules;
for (const nodeModulesParentDir of nodeModulesParentDirs) {
try {
const tsPackageJsonPath = join(nodeModulesParentDir, TS_PACKAGE_JSON);
const packageJson = await readFile(tsPackageJsonPath, "utf-8");
const { version } = JSON.parse(packageJson);
const sanitizedVersion = getSanitizedTypeScriptVersion(version);
if (typeof sanitizedVersion !== "string") {
continue;
}
versionFromNodeModules = sanitizedVersion;
break;
}
catch {
}
}
if (versionFromNodeModules) {
tscVersion = versionFromNodeModules;
return ["md/tsc", tscVersion];
}
const sanitizedVersion = getSanitizedDevTypeScriptVersion(versionFromApp);
if (typeof sanitizedVersion !== "string") {
tscVersion = null;
return undefined;
}
tscVersion = `dev_${sanitizedVersion}`;
return ["md/tsc", tscVersion];
};
@@ -0,0 +1,7 @@
import { crtAvailability } from "./crt-availability";
export const isCrtAvailable = () => {
if (crtAvailability.isCrtAvailable) {
return ["md/crt-avail"];
}
return null;
};
@@ -0,0 +1,9 @@
import { DEFAULT_UA_APP_ID } from "../middleware-user-agent/configurations";
export const UA_APP_ID_ENV_NAME = "AWS_SDK_UA_APP_ID";
export const UA_APP_ID_INI_NAME = "sdk_ua_app_id";
const UA_APP_ID_INI_NAME_DEPRECATED = "sdk-ua-app-id";
export const NODE_APP_ID_CONFIG_OPTIONS = {
environmentVariableSelector: (env) => env[UA_APP_ID_ENV_NAME],
configFileSelector: (profile) => profile[UA_APP_ID_INI_NAME] ?? profile[UA_APP_ID_INI_NAME_DEPRECATED],
default: DEFAULT_UA_APP_ID,
};
@@ -0,0 +1,21 @@
import { HttpRequest } from "@smithy/core/protocols";
import { getSkewCorrectedDate } from "../utils";
import { AwsSdkSigV4Signer, validateSigningProperties } from "./AwsSdkSigV4Signer";
export class AwsSdkSigV4ASigner extends AwsSdkSigV4Signer {
async sign(httpRequest, identity, signingProperties) {
if (!HttpRequest.isInstance(httpRequest)) {
throw new Error("The request is not an instance of `HttpRequest` and cannot be signed");
}
const { config, signer, signingRegion, signingRegionSet, signingName } = await validateSigningProperties(signingProperties);
const configResolvedSigningRegionSet = await config.sigv4aSigningRegionSet?.();
const multiRegionOverride = (configResolvedSigningRegionSet ??
signingRegionSet ?? [signingRegion]).join(",");
signingProperties._preRequestSystemClockOffset = config.systemClockOffset;
const signedRequest = await signer.sign(httpRequest, {
signingDate: getSkewCorrectedDate(config.systemClockOffset),
signingRegion: multiRegionOverride,
signingService: signingName,
});
return signedRequest;
}
}
@@ -0,0 +1,77 @@
import { HttpRequest } from "@smithy/core/protocols";
import { getDateHeader, getSkewCorrectedDate, getUpdatedSystemClockOffset } from "../utils";
const throwSigningPropertyError = (name, property) => {
if (!property) {
throw new Error(`Property \`${name}\` is not resolved for AWS SDK SigV4Auth`);
}
return property;
};
export const validateSigningProperties = async (signingProperties) => {
const context = throwSigningPropertyError("context", signingProperties.context);
const config = throwSigningPropertyError("config", signingProperties.config);
const authScheme = context.endpointV2?.properties?.authSchemes?.[0];
const signerFunction = throwSigningPropertyError("signer", config.signer);
const signer = await signerFunction(authScheme);
const signingRegion = signingProperties?.signingRegion;
const signingRegionSet = signingProperties?.signingRegionSet;
const signingName = signingProperties?.signingName;
return {
config,
signer,
signingRegion,
signingRegionSet,
signingName,
};
};
export class AwsSdkSigV4Signer {
async sign(httpRequest, identity, signingProperties) {
if (!HttpRequest.isInstance(httpRequest)) {
throw new Error("The request is not an instance of `HttpRequest` and cannot be signed");
}
const validatedProps = await validateSigningProperties(signingProperties);
const { config, signer } = validatedProps;
let { signingRegion, signingName } = validatedProps;
const handlerExecutionContext = signingProperties.context;
if (handlerExecutionContext?.authSchemes?.length ?? 0 > 1) {
const [first, second] = handlerExecutionContext.authSchemes;
if (first?.name === "sigv4a" && second?.name === "sigv4") {
signingRegion = second?.signingRegion ?? signingRegion;
signingName = second?.signingName ?? signingName;
}
}
signingProperties._preRequestSystemClockOffset = config.systemClockOffset;
const signedRequest = await signer.sign(httpRequest, {
signingDate: getSkewCorrectedDate(config.systemClockOffset),
signingRegion: signingRegion,
signingService: signingName,
});
return signedRequest;
}
errorHandler(signingProperties) {
return (error) => {
const errorException = error;
const serverTime = errorException.ServerTime ?? getDateHeader(errorException.$response);
if (serverTime) {
const config = throwSigningPropertyError("config", signingProperties.config);
const preRequestOffset = signingProperties._preRequestSystemClockOffset;
const newOffset = getUpdatedSystemClockOffset(serverTime, config.systemClockOffset);
const isLocalCorrection = newOffset !== config.systemClockOffset;
const isConcurrentCorrection = preRequestOffset !== undefined && preRequestOffset !== newOffset;
const clockSkewCorrected = isLocalCorrection || isConcurrentCorrection;
if (clockSkewCorrected && errorException.$metadata) {
config.systemClockOffset = newOffset;
errorException.$metadata.clockSkewCorrected = true;
}
}
throw error;
};
}
successHandler(httpResponse, signingProperties) {
const dateHeader = getDateHeader(httpResponse);
if (dateHeader) {
const config = throwSigningPropertyError("config", signingProperties.config);
config.systemClockOffset = getUpdatedSystemClockOffset(dateHeader, config.systemClockOffset);
}
}
}
export const AWSSDKSigV4Signer = AwsSdkSigV4Signer;
@@ -0,0 +1,22 @@
import { getArrayForCommaSeparatedString } from "../utils/getArrayForCommaSeparatedString";
import { getBearerTokenEnvKey } from "../utils/getBearerTokenEnvKey";
const NODE_AUTH_SCHEME_PREFERENCE_ENV_KEY = "AWS_AUTH_SCHEME_PREFERENCE";
const NODE_AUTH_SCHEME_PREFERENCE_CONFIG_KEY = "auth_scheme_preference";
export const NODE_AUTH_SCHEME_PREFERENCE_OPTIONS = {
environmentVariableSelector: (env, options) => {
if (options?.signingName) {
const bearerTokenKey = getBearerTokenEnvKey(options.signingName);
if (bearerTokenKey in env)
return ["httpBearerAuth"];
}
if (!(NODE_AUTH_SCHEME_PREFERENCE_ENV_KEY in env))
return undefined;
return getArrayForCommaSeparatedString(env[NODE_AUTH_SCHEME_PREFERENCE_ENV_KEY]);
},
configFileSelector: (profile) => {
if (!(NODE_AUTH_SCHEME_PREFERENCE_CONFIG_KEY in profile))
return undefined;
return getArrayForCommaSeparatedString(profile[NODE_AUTH_SCHEME_PREFERENCE_CONFIG_KEY]);
},
default: [],
};
@@ -0,0 +1,5 @@
export { AwsSdkSigV4Signer, AWSSDKSigV4Signer, validateSigningProperties } from "./AwsSdkSigV4Signer";
export { AwsSdkSigV4ASigner } from "./AwsSdkSigV4ASigner";
export * from "./NODE_AUTH_SCHEME_PREFERENCE_OPTIONS";
export * from "./resolveAwsSdkSigV4AConfig";
export * from "./resolveAwsSdkSigV4Config";
@@ -0,0 +1,25 @@
import { normalizeProvider } from "@smithy/core";
import { ProviderError } from "@smithy/core/config";
export const resolveAwsSdkSigV4AConfig = (config) => {
config.sigv4aSigningRegionSet = normalizeProvider(config.sigv4aSigningRegionSet);
return config;
};
export const NODE_SIGV4A_CONFIG_OPTIONS = {
environmentVariableSelector(env) {
if (env.AWS_SIGV4A_SIGNING_REGION_SET) {
return env.AWS_SIGV4A_SIGNING_REGION_SET.split(",").map((_) => _.trim());
}
throw new ProviderError("AWS_SIGV4A_SIGNING_REGION_SET not set in env.", {
tryNextLink: true,
});
},
configFileSelector(profile) {
if (profile.sigv4a_signing_region_set) {
return (profile.sigv4a_signing_region_set ?? "").split(",").map((_) => _.trim());
}
throw new ProviderError("sigv4a_signing_region_set not set in profile.", {
tryNextLink: true,
});
},
default: undefined,
};
@@ -0,0 +1,139 @@
import { setCredentialFeature } from "@aws-sdk/core/client";
import { doesIdentityRequireRefresh, isIdentityExpired, memoizeIdentityProvider, normalizeProvider, } from "@smithy/core";
import { SignatureV4 } from "@smithy/signature-v4";
export const resolveAwsSdkSigV4Config = (config) => {
let inputCredentials = config.credentials;
let isUserSupplied = !!config.credentials;
let resolvedCredentials = undefined;
Object.defineProperty(config, "credentials", {
set(credentials) {
if (credentials && credentials !== inputCredentials && credentials !== resolvedCredentials) {
isUserSupplied = true;
}
inputCredentials = credentials;
const memoizedProvider = normalizeCredentialProvider(config, {
credentials: inputCredentials,
credentialDefaultProvider: config.credentialDefaultProvider,
});
const boundProvider = bindCallerConfig(config, memoizedProvider);
if (isUserSupplied && !boundProvider.attributed) {
const isCredentialObject = typeof inputCredentials === "object" && inputCredentials !== null;
resolvedCredentials = async (options) => {
const creds = await boundProvider(options);
const attributedCreds = creds;
if (isCredentialObject && (!attributedCreds.$source || Object.keys(attributedCreds.$source).length === 0)) {
return setCredentialFeature(attributedCreds, "CREDENTIALS_CODE", "e");
}
return attributedCreds;
};
resolvedCredentials.memoized = boundProvider.memoized;
resolvedCredentials.configBound = boundProvider.configBound;
resolvedCredentials.attributed = true;
}
else {
resolvedCredentials = boundProvider;
}
},
get() {
return resolvedCredentials;
},
enumerable: true,
configurable: true,
});
config.credentials = inputCredentials;
const { signingEscapePath = true, systemClockOffset = config.systemClockOffset || 0, sha256, } = config;
let signer;
if (config.signer) {
signer = normalizeProvider(config.signer);
}
else if (config.regionInfoProvider) {
signer = () => normalizeProvider(config.region)()
.then(async (region) => [
(await config.regionInfoProvider(region, {
useFipsEndpoint: await config.useFipsEndpoint(),
useDualstackEndpoint: await config.useDualstackEndpoint(),
})) || {},
region,
])
.then(([regionInfo, region]) => {
const { signingRegion, signingService } = regionInfo;
config.signingRegion = config.signingRegion || signingRegion || region;
config.signingName = config.signingName || signingService || config.serviceId;
const params = {
...config,
credentials: config.credentials,
region: config.signingRegion,
service: config.signingName,
sha256,
uriEscapePath: signingEscapePath,
};
const SignerCtor = config.signerConstructor || SignatureV4;
return new SignerCtor(params);
});
}
else {
signer = async (authScheme) => {
authScheme = Object.assign({}, {
name: "sigv4",
signingName: config.signingName || config.defaultSigningName,
signingRegion: await normalizeProvider(config.region)(),
properties: {},
}, authScheme);
const signingRegion = authScheme.signingRegion;
const signingService = authScheme.signingName;
config.signingRegion = config.signingRegion || signingRegion;
config.signingName = config.signingName || signingService || config.serviceId;
const params = {
...config,
credentials: config.credentials,
region: config.signingRegion,
service: config.signingName,
sha256,
uriEscapePath: signingEscapePath,
};
const SignerCtor = config.signerConstructor || SignatureV4;
return new SignerCtor(params);
};
}
const resolvedConfig = Object.assign(config, {
systemClockOffset,
signingEscapePath,
signer,
});
return resolvedConfig;
};
export const resolveAWSSDKSigV4Config = resolveAwsSdkSigV4Config;
function normalizeCredentialProvider(config, { credentials, credentialDefaultProvider, }) {
let credentialsProvider;
if (credentials) {
if (!credentials?.memoized) {
credentialsProvider = memoizeIdentityProvider(credentials, isIdentityExpired, doesIdentityRequireRefresh);
}
else {
credentialsProvider = credentials;
}
}
else {
if (credentialDefaultProvider) {
credentialsProvider = normalizeProvider(credentialDefaultProvider(Object.assign({}, config, {
parentClientConfig: config,
})));
}
else {
credentialsProvider = async () => {
throw new Error("@aws-sdk/core::resolveAwsSdkSigV4Config - `credentials` not provided and no credentialDefaultProvider was configured.");
};
}
}
credentialsProvider.memoized = true;
return credentialsProvider;
}
function bindCallerConfig(config, credentialsProvider) {
if (credentialsProvider.configBound) {
return credentialsProvider;
}
const fn = async (options) => credentialsProvider({ ...options, callerClientConfig: config });
fn.memoized = credentialsProvider.memoized;
fn.configBound = true;
return fn;
}
@@ -0,0 +1,2 @@
export * from "./aws_sdk";
export * from "./utils/getBearerTokenEnvKey";
@@ -0,0 +1 @@
export const getArrayForCommaSeparatedString = (str) => typeof str === "string" && str.length > 0 ? str.split(",").map((item) => item.trim()) : [];
@@ -0,0 +1 @@
export const getBearerTokenEnvKey = (signingName) => `AWS_BEARER_TOKEN_${signingName.replace(/[\s-]/g, "_").toUpperCase()}`;
@@ -0,0 +1,2 @@
import { HttpResponse } from "@smithy/core/protocols";
export const getDateHeader = (response) => HttpResponse.isInstance(response) ? response.headers?.date ?? response.headers?.Date : undefined;
@@ -0,0 +1 @@
export const getSkewCorrectedDate = (systemClockOffset) => new Date(Date.now() + systemClockOffset);
@@ -0,0 +1,8 @@
import { isClockSkewed } from "./isClockSkewed";
export const getUpdatedSystemClockOffset = (clockTime, currentSystemClockOffset) => {
const clockTimeInMs = Date.parse(clockTime);
if (isClockSkewed(clockTimeInMs, currentSystemClockOffset)) {
return clockTimeInMs - Date.now();
}
return currentSystemClockOffset;
};
@@ -0,0 +1,3 @@
export * from "./getDateHeader";
export * from "./getSkewCorrectedDate";
export * from "./getUpdatedSystemClockOffset";
@@ -0,0 +1,2 @@
import { getSkewCorrectedDate } from "./getSkewCorrectedDate";
export const isClockSkewed = (clockTime, systemClockOffset) => Math.abs(getSkewCorrectedDate(systemClockOffset).getTime() - clockTime) >= 300000;
@@ -0,0 +1,6 @@
export class SerdeContextConfig {
serdeContext;
setSerdeContext(serdeContext) {
this.serdeContext = serdeContext;
}
}
+141
View File
@@ -0,0 +1,141 @@
import { decorateServiceException } from "@smithy/core/client";
import { NormalizedSchema, TypeRegistry } from "@smithy/core/schema";
export class ProtocolLib {
queryCompat;
errorRegistry;
constructor(queryCompat = false) {
this.queryCompat = queryCompat;
}
resolveRestContentType(defaultContentType, inputSchema) {
const members = inputSchema.getMemberSchemas();
const httpPayloadMember = Object.values(members).find((m) => {
return !!m.getMergedTraits().httpPayload;
});
if (httpPayloadMember) {
const mediaType = httpPayloadMember.getMergedTraits().mediaType;
if (mediaType) {
return mediaType;
}
else if (httpPayloadMember.isStringSchema()) {
return "text/plain";
}
else if (httpPayloadMember.isBlobSchema()) {
return "application/octet-stream";
}
else {
return defaultContentType;
}
}
else if (!inputSchema.isUnitSchema()) {
const hasBody = Object.values(members).find((m) => {
const { httpQuery, httpQueryParams, httpHeader, httpLabel, httpPrefixHeaders } = m.getMergedTraits();
const noPrefixHeaders = httpPrefixHeaders === void 0;
return !httpQuery && !httpQueryParams && !httpHeader && !httpLabel && noPrefixHeaders;
});
if (hasBody) {
return defaultContentType;
}
}
}
async getErrorSchemaOrThrowBaseException(errorIdentifier, defaultNamespace, response, dataObject, metadata, getErrorSchema) {
let errorName = errorIdentifier;
if (errorIdentifier.includes("#")) {
[, errorName] = errorIdentifier.split("#");
}
const errorMetadata = {
$metadata: metadata,
$fault: response.statusCode < 500 ? "client" : "server",
};
if (!this.errorRegistry) {
throw new Error("@aws-sdk/core/protocols - error handler not initialized.");
}
try {
const errorSchema = getErrorSchema?.(this.errorRegistry, errorName) ??
this.errorRegistry.getSchema(errorIdentifier);
return { errorSchema, errorMetadata };
}
catch (e) {
dataObject.message = dataObject.message ?? dataObject.Message ?? "UnknownError";
const synthetic = this.errorRegistry;
const baseExceptionSchema = synthetic.getBaseException();
if (baseExceptionSchema) {
const ErrorCtor = synthetic.getErrorCtor(baseExceptionSchema) ?? Error;
throw this.decorateServiceException(Object.assign(new ErrorCtor({ name: errorName }), errorMetadata), dataObject);
}
const d = dataObject;
const message = d?.message ?? d?.Message ?? d?.Error?.Message ?? d?.Error?.message;
throw this.decorateServiceException(Object.assign(new Error(message), {
name: errorName,
}, errorMetadata), dataObject);
}
}
compose(composite, errorIdentifier, defaultNamespace) {
let namespace = defaultNamespace;
if (errorIdentifier.includes("#")) {
[namespace] = errorIdentifier.split("#");
}
const staticRegistry = TypeRegistry.for(namespace);
const defaultSyntheticRegistry = TypeRegistry.for("smithy.ts.sdk.synthetic." + defaultNamespace);
composite.copyFrom(staticRegistry);
composite.copyFrom(defaultSyntheticRegistry);
this.errorRegistry = composite;
}
decorateServiceException(exception, additions = {}) {
if (this.queryCompat) {
const msg = exception.Message ?? additions.Message;
const error = decorateServiceException(exception, additions);
if (msg) {
error.message = msg;
}
const errorObj = error.Error ?? {};
errorObj.Type = error.Error?.Type;
errorObj.Code = error.Error?.Code;
errorObj.Message = error.Error?.message ?? error.Error?.Message ?? msg;
error.Error = errorObj;
const reqId = error.$metadata.requestId;
if (reqId) {
error.RequestId = reqId;
}
return error;
}
return decorateServiceException(exception, additions);
}
setQueryCompatError(output, response) {
const queryErrorHeader = response.headers?.["x-amzn-query-error"];
if (output !== undefined && queryErrorHeader != null) {
const [Code, Type] = queryErrorHeader.split(";");
const keys = Object.keys(output);
const Error = {
Code,
Type,
};
output.Code = Code;
output.Type = Type;
for (let i = 0; i < keys.length; i++) {
const k = keys[i];
Error[k === "message" ? "Message" : k] = output[k];
}
delete Error.__type;
output.Error = Error;
}
}
queryCompatOutput(queryCompatErrorData, errorData) {
if (queryCompatErrorData.Error) {
errorData.Error = queryCompatErrorData.Error;
}
if (queryCompatErrorData.Type) {
errorData.Type = queryCompatErrorData.Type;
}
if (queryCompatErrorData.Code) {
errorData.Code = queryCompatErrorData.Code;
}
}
findQueryCompatibleError(registry, errorName) {
try {
return registry.getSchema(errorName);
}
catch (e) {
return registry.find((schema) => NormalizedSchema.of(schema).getMergedTraits().awsQueryError?.[0] === errorName);
}
}
}
+26
View File
@@ -0,0 +1,26 @@
export class UnionSerde {
from;
to;
keys;
constructor(from, to) {
this.from = from;
this.to = to;
const keys = Object.keys(this.from);
const set = new Set(keys);
set.delete("__type");
this.keys = set;
}
mark(key) {
this.keys.delete(key);
}
hasUnknown() {
return this.keys.size === 1 && Object.keys(this.to).length === 0;
}
writeUnknown() {
if (this.hasUnknown()) {
const k = this.keys.values().next().value;
const v = this.from[k];
this.to.$unknown = [k, v];
}
}
}
@@ -0,0 +1,50 @@
import { loadSmithyRpcV2CborErrorCode, SmithyRpcV2CborProtocol } from "@smithy/core/cbor";
import { NormalizedSchema } from "@smithy/core/schema";
import { ProtocolLib } from "../ProtocolLib";
export class AwsSmithyRpcV2CborProtocol extends SmithyRpcV2CborProtocol {
awsQueryCompatible;
mixin;
constructor({ defaultNamespace, errorTypeRegistries, awsQueryCompatible, }) {
super({ defaultNamespace, errorTypeRegistries });
this.awsQueryCompatible = !!awsQueryCompatible;
this.mixin = new ProtocolLib(this.awsQueryCompatible);
}
async serializeRequest(operationSchema, input, context) {
const request = await super.serializeRequest(operationSchema, input, context);
if (this.awsQueryCompatible) {
request.headers["x-amzn-query-mode"] = "true";
}
return request;
}
async handleError(operationSchema, context, response, dataObject, metadata) {
if (this.awsQueryCompatible) {
this.mixin.setQueryCompatError(dataObject, response);
}
const errorName = (() => {
const compatHeader = response.headers["x-amzn-query-error"];
if (compatHeader && this.awsQueryCompatible) {
return compatHeader.split(";")[0];
}
return loadSmithyRpcV2CborErrorCode(response, dataObject) ?? "Unknown";
})();
this.mixin.compose(this.compositeErrorRegistry, errorName, this.options.defaultNamespace);
const { errorSchema, errorMetadata } = await this.mixin.getErrorSchemaOrThrowBaseException(errorName, this.options.defaultNamespace, response, dataObject, metadata, this.awsQueryCompatible ? this.mixin.findQueryCompatibleError : undefined);
const ns = NormalizedSchema.of(errorSchema);
const message = dataObject.message ?? dataObject.Message ?? "UnknownError";
const ErrorCtor = this.compositeErrorRegistry.getErrorCtor(errorSchema) ?? Error;
const exception = new ErrorCtor({});
const output = {};
for (const [name, member] of ns.structIterator()) {
if (dataObject[name] != null) {
output[name] = this.deserializer.readValue(member, dataObject[name]);
}
}
if (this.awsQueryCompatible) {
this.mixin.queryCompatOutput(dataObject, output);
}
throw this.mixin.decorateServiceException(Object.assign(exception, errorMetadata, {
$fault: ns.getMergedTraits().error,
message,
}, output), dataObject);
}
}
@@ -0,0 +1,53 @@
export const _toStr = (val) => {
if (val == null) {
return val;
}
if (typeof val === "number" || typeof val === "bigint") {
const warning = new Error(`Received number ${val} where a string was expected.`);
warning.name = "Warning";
console.warn(warning);
return String(val);
}
if (typeof val === "boolean") {
const warning = new Error(`Received boolean ${val} where a string was expected.`);
warning.name = "Warning";
console.warn(warning);
return String(val);
}
return val;
};
export const _toBool = (val) => {
if (val == null) {
return val;
}
if (typeof val === "number") {
}
if (typeof val === "string") {
const lowercase = val.toLowerCase();
if (val !== "" && lowercase !== "false" && lowercase !== "true") {
const warning = new Error(`Received string "${val}" where a boolean was expected.`);
warning.name = "Warning";
console.warn(warning);
}
return val !== "" && lowercase !== "false";
}
return val;
};
export const _toNum = (val) => {
if (val == null) {
return val;
}
if (typeof val === "boolean") {
}
if (typeof val === "string") {
const num = Number(val);
if (num.toString() !== val) {
const warning = new Error(`Received string "${val}" where a number was expected.`);
warning.name = "Warning";
console.warn(warning);
return val;
}
return num;
}
return val;
};
+3
View File
@@ -0,0 +1,3 @@
import { collectBody } from "@smithy/core/protocols";
import { toUtf8 } from "@smithy/core/serde";
export const collectBodyString = (streamBody, context) => collectBody(streamBody, context).then((body) => (context?.utf8Encoder ?? toUtf8)(body));
+20
View File
@@ -0,0 +1,20 @@
export * from "./cbor/AwsSmithyRpcV2CborProtocol";
export * from "./coercing-serializers";
export * from "./json/AwsJson1_0Protocol";
export * from "./json/AwsJson1_1Protocol";
export * from "./json/AwsJsonRpcProtocol";
export * from "./json/AwsRestJsonProtocol";
export * from "./json/JsonCodec";
export * from "./json/JsonShapeDeserializer";
export * from "./json/JsonShapeSerializer";
export * from "./json/awsExpectUnion";
export * from "./json/parseJsonBody";
export * from "./query/AwsEc2QueryProtocol";
export * from "./query/AwsQueryProtocol";
export * from "./query/QuerySerializerSettings";
export * from "./query/QueryShapeSerializer";
export * from "./xml/AwsRestXmlProtocol";
export * from "./xml/XmlCodec";
export * from "./xml/XmlShapeDeserializer";
export * from "./xml/XmlShapeSerializer";
export * from "./xml/parseXmlBody";
@@ -0,0 +1,21 @@
import { AwsJsonRpcProtocol } from "./AwsJsonRpcProtocol";
export class AwsJson1_0Protocol extends AwsJsonRpcProtocol {
constructor({ defaultNamespace, errorTypeRegistries, serviceTarget, awsQueryCompatible, jsonCodec, }) {
super({
defaultNamespace,
errorTypeRegistries,
serviceTarget,
awsQueryCompatible,
jsonCodec,
});
}
getShapeId() {
return "aws.protocols#awsJson1_0";
}
getJsonRpcVersion() {
return "1.0";
}
getDefaultContentType() {
return "application/x-amz-json-1.0";
}
}
@@ -0,0 +1,21 @@
import { AwsJsonRpcProtocol } from "./AwsJsonRpcProtocol";
export class AwsJson1_1Protocol extends AwsJsonRpcProtocol {
constructor({ defaultNamespace, errorTypeRegistries, serviceTarget, awsQueryCompatible, jsonCodec, }) {
super({
defaultNamespace,
errorTypeRegistries,
serviceTarget,
awsQueryCompatible,
jsonCodec,
});
}
getShapeId() {
return "aws.protocols#awsJson1_1";
}
getJsonRpcVersion() {
return "1.1";
}
getDefaultContentType() {
return "application/x-amz-json-1.1";
}
}
@@ -0,0 +1,78 @@
import { RpcProtocol } from "@smithy/core/protocols";
import { deref, NormalizedSchema } from "@smithy/core/schema";
import { ProtocolLib } from "../ProtocolLib";
import { JsonCodec } from "./JsonCodec";
import { loadJsonRpcErrorCode } from "./parseJsonBody";
export class AwsJsonRpcProtocol extends RpcProtocol {
serializer;
deserializer;
serviceTarget;
codec;
mixin;
awsQueryCompatible;
constructor({ defaultNamespace, errorTypeRegistries, serviceTarget, awsQueryCompatible, jsonCodec, }) {
super({
defaultNamespace,
errorTypeRegistries,
});
this.serviceTarget = serviceTarget;
this.codec =
jsonCodec ??
new JsonCodec({
timestampFormat: {
useTrait: true,
default: 7,
},
jsonName: false,
});
this.serializer = this.codec.createSerializer();
this.deserializer = this.codec.createDeserializer();
this.awsQueryCompatible = !!awsQueryCompatible;
this.mixin = new ProtocolLib(this.awsQueryCompatible);
}
async serializeRequest(operationSchema, input, context) {
const request = await super.serializeRequest(operationSchema, input, context);
if (!request.path.endsWith("/")) {
request.path += "/";
}
request.headers["content-type"] = `application/x-amz-json-${this.getJsonRpcVersion()}`;
request.headers["x-amz-target"] = `${this.serviceTarget}.${operationSchema.name}`;
if (this.awsQueryCompatible) {
request.headers["x-amzn-query-mode"] = "true";
}
if (deref(operationSchema.input) === "unit" || !request.body) {
request.body = "{}";
}
return request;
}
getPayloadCodec() {
return this.codec;
}
async handleError(operationSchema, context, response, dataObject, metadata) {
const { awsQueryCompatible } = this;
if (awsQueryCompatible) {
this.mixin.setQueryCompatError(dataObject, response);
}
const errorIdentifier = loadJsonRpcErrorCode(response, dataObject, awsQueryCompatible) ?? "Unknown";
this.mixin.compose(this.compositeErrorRegistry, errorIdentifier, this.options.defaultNamespace);
const { errorSchema, errorMetadata } = await this.mixin.getErrorSchemaOrThrowBaseException(errorIdentifier, this.options.defaultNamespace, response, dataObject, metadata, awsQueryCompatible ? this.mixin.findQueryCompatibleError : undefined);
const ns = NormalizedSchema.of(errorSchema);
const message = dataObject.message ?? dataObject.Message ?? "UnknownError";
const ErrorCtor = this.compositeErrorRegistry.getErrorCtor(errorSchema) ?? Error;
const exception = new ErrorCtor({});
const output = {};
const errorDeserializer = this.codec.createDeserializer();
for (const [name, member] of ns.structIterator()) {
if (dataObject[name] != null) {
output[name] = errorDeserializer.readObject(member, dataObject[name]);
}
}
if (awsQueryCompatible) {
this.mixin.queryCompatOutput(dataObject, output);
}
throw this.mixin.decorateServiceException(Object.assign(exception, errorMetadata, {
$fault: ns.getMergedTraits().error,
message,
}, output), dataObject);
}
}
@@ -0,0 +1,85 @@
import { HttpBindingProtocol, HttpInterceptingShapeDeserializer, HttpInterceptingShapeSerializer, } from "@smithy/core/protocols";
import { NormalizedSchema } from "@smithy/core/schema";
import { ProtocolLib } from "../ProtocolLib";
import { JsonCodec } from "./JsonCodec";
import { loadRestJsonErrorCode } from "./parseJsonBody";
export class AwsRestJsonProtocol extends HttpBindingProtocol {
serializer;
deserializer;
codec;
mixin = new ProtocolLib();
constructor({ defaultNamespace, errorTypeRegistries, }) {
super({
defaultNamespace,
errorTypeRegistries,
});
const settings = {
timestampFormat: {
useTrait: true,
default: 7,
},
httpBindings: true,
jsonName: true,
};
this.codec = new JsonCodec(settings);
this.serializer = new HttpInterceptingShapeSerializer(this.codec.createSerializer(), settings);
this.deserializer = new HttpInterceptingShapeDeserializer(this.codec.createDeserializer(), settings);
}
getShapeId() {
return "aws.protocols#restJson1";
}
getPayloadCodec() {
return this.codec;
}
setSerdeContext(serdeContext) {
this.codec.setSerdeContext(serdeContext);
super.setSerdeContext(serdeContext);
}
async serializeRequest(operationSchema, input, context) {
const request = await super.serializeRequest(operationSchema, input, context);
const inputSchema = NormalizedSchema.of(operationSchema.input);
if (!request.headers["content-type"]) {
const contentType = this.mixin.resolveRestContentType(this.getDefaultContentType(), inputSchema);
if (contentType) {
request.headers["content-type"] = contentType;
}
}
if (request.body == null && request.headers["content-type"] === this.getDefaultContentType()) {
request.body = "{}";
}
return request;
}
async deserializeResponse(operationSchema, context, response) {
const output = await super.deserializeResponse(operationSchema, context, response);
const outputSchema = NormalizedSchema.of(operationSchema.output);
for (const [name, member] of outputSchema.structIterator()) {
if (member.getMemberTraits().httpPayload && !(name in output)) {
output[name] = null;
}
}
return output;
}
async handleError(operationSchema, context, response, dataObject, metadata) {
const errorIdentifier = loadRestJsonErrorCode(response, dataObject) ?? "Unknown";
this.mixin.compose(this.compositeErrorRegistry, errorIdentifier, this.options.defaultNamespace);
const { errorSchema, errorMetadata } = await this.mixin.getErrorSchemaOrThrowBaseException(errorIdentifier, this.options.defaultNamespace, response, dataObject, metadata);
const ns = NormalizedSchema.of(errorSchema);
const message = dataObject.message ?? dataObject.Message ?? "UnknownError";
const ErrorCtor = this.compositeErrorRegistry.getErrorCtor(errorSchema) ?? Error;
const exception = new ErrorCtor({});
await this.deserializeHttpMessage(errorSchema, context, response, dataObject);
const output = {};
const errorDeserializer = this.codec.createDeserializer();
for (const [name, member] of ns.structIterator()) {
const target = member.getMergedTraits().jsonName ?? name;
output[name] = errorDeserializer.readObject(member, dataObject[target]);
}
throw this.mixin.decorateServiceException(Object.assign(exception, errorMetadata, {
$fault: ns.getMergedTraits().error,
message,
}, output), dataObject);
}
getDefaultContentType() {
return "application/json";
}
}
@@ -0,0 +1,20 @@
import { SerdeContextConfig } from "../ConfigurableSerdeContext";
import { JsonShapeDeserializer } from "./JsonShapeDeserializer";
import { JsonShapeSerializer } from "./JsonShapeSerializer";
export class JsonCodec extends SerdeContextConfig {
settings;
constructor(settings) {
super();
this.settings = settings;
}
createSerializer() {
const serializer = new JsonShapeSerializer(this.settings);
serializer.setSerdeContext(this.serdeContext);
return serializer;
}
createDeserializer() {
const deserializer = new JsonShapeDeserializer(this.settings);
deserializer.setSerdeContext(this.serdeContext);
return deserializer;
}
}
@@ -0,0 +1,151 @@
import { determineTimestampFormat } from "@smithy/core/protocols";
import { NormalizedSchema } from "@smithy/core/schema";
import { LazyJsonString, NumericValue, parseEpochTimestamp, parseRfc3339DateTimeWithOffset, parseRfc7231DateTime, } from "@smithy/core/serde";
import { fromBase64 } from "@smithy/core/serde";
import { SerdeContextConfig } from "../ConfigurableSerdeContext";
import { UnionSerde } from "../UnionSerde";
import { jsonReviver } from "./jsonReviver";
import { parseJsonBody } from "./parseJsonBody";
export class JsonShapeDeserializer extends SerdeContextConfig {
settings;
constructor(settings) {
super();
this.settings = settings;
}
async read(schema, data) {
return this._read(schema, typeof data === "string" ? JSON.parse(data, jsonReviver) : await parseJsonBody(data, this.serdeContext));
}
readObject(schema, data) {
return this._read(schema, data);
}
_read(schema, value) {
const isObject = value !== null && typeof value === "object";
const ns = NormalizedSchema.of(schema);
if (isObject) {
if (ns.isStructSchema()) {
const record = value;
const union = ns.isUnionSchema();
const out = {};
let nameMap = void 0;
const { jsonName } = this.settings;
if (jsonName) {
nameMap = {};
}
let unionSerde;
if (union) {
unionSerde = new UnionSerde(record, out);
}
for (const [memberName, memberSchema] of ns.structIterator()) {
let fromKey = memberName;
if (jsonName) {
fromKey = memberSchema.getMergedTraits().jsonName ?? fromKey;
nameMap[fromKey] = memberName;
}
if (union) {
unionSerde.mark(fromKey);
}
if (record[fromKey] != null) {
out[memberName] = this._read(memberSchema, record[fromKey]);
}
}
if (union) {
unionSerde.writeUnknown();
}
else if (typeof record.__type === "string") {
for (const k in record) {
const v = record[k];
const t = jsonName ? nameMap[k] ?? k : k;
if (!(t in out)) {
out[t] = v;
}
}
}
return out;
}
if (Array.isArray(value) && ns.isListSchema()) {
const listMember = ns.getValueSchema();
const out = [];
for (const item of value) {
out.push(this._read(listMember, item));
}
return out;
}
if (ns.isMapSchema()) {
const mapMember = ns.getValueSchema();
const out = {};
for (const _k in value) {
out[_k] = this._read(mapMember, value[_k]);
}
return out;
}
}
if (ns.isBlobSchema() && typeof value === "string") {
return fromBase64(value);
}
const mediaType = ns.getMergedTraits().mediaType;
if (ns.isStringSchema() && typeof value === "string" && mediaType) {
const isJson = mediaType === "application/json" || mediaType.endsWith("+json");
if (isJson) {
return LazyJsonString.from(value);
}
return value;
}
if (ns.isTimestampSchema() && value != null) {
const format = determineTimestampFormat(ns, this.settings);
switch (format) {
case 5:
return parseRfc3339DateTimeWithOffset(value);
case 6:
return parseRfc7231DateTime(value);
case 7:
return parseEpochTimestamp(value);
default:
console.warn("Missing timestamp format, parsing value with Date constructor:", value);
return new Date(value);
}
}
if (ns.isBigIntegerSchema() && (typeof value === "number" || typeof value === "string")) {
return BigInt(value);
}
if (ns.isBigDecimalSchema() && value != undefined) {
if (value instanceof NumericValue) {
return value;
}
const untyped = value;
if (untyped.type === "bigDecimal" && "string" in untyped) {
return new NumericValue(untyped.string, untyped.type);
}
return new NumericValue(String(value), "bigDecimal");
}
if (ns.isNumericSchema() && typeof value === "string") {
switch (value) {
case "Infinity":
return Infinity;
case "-Infinity":
return -Infinity;
case "NaN":
return NaN;
}
return value;
}
if (ns.isDocumentSchema()) {
if (isObject) {
const out = Array.isArray(value) ? [] : {};
for (const k in value) {
const v = value[k];
if (v instanceof NumericValue) {
out[k] = v;
}
else {
out[k] = this._read(ns, v);
}
}
return out;
}
else {
return structuredClone(value);
}
}
return value;
}
}
@@ -0,0 +1,180 @@
import { determineTimestampFormat } from "@smithy/core/protocols";
import { NormalizedSchema } from "@smithy/core/schema";
import { dateToUtcString, generateIdempotencyToken, LazyJsonString, NumericValue, toBase64 } from "@smithy/core/serde";
import { SerdeContextConfig } from "../ConfigurableSerdeContext";
import { JsonReplacer } from "./jsonReplacer";
export class JsonShapeSerializer extends SerdeContextConfig {
settings;
buffer;
useReplacer = false;
rootSchema;
constructor(settings) {
super();
this.settings = settings;
}
write(schema, value) {
this.rootSchema = NormalizedSchema.of(schema);
this.buffer = this._write(this.rootSchema, value);
}
flush() {
const { rootSchema, useReplacer } = this;
this.rootSchema = undefined;
this.useReplacer = false;
if (rootSchema?.isStructSchema() || rootSchema?.isDocumentSchema()) {
if (!useReplacer) {
return JSON.stringify(this.buffer);
}
const replacer = new JsonReplacer();
return replacer.replaceInJson(JSON.stringify(this.buffer, replacer.createReplacer(), 0));
}
return this.buffer;
}
writeDiscriminatedDocument(schema, value) {
this.write(schema, value);
if (typeof this.buffer === "object") {
this.buffer.__type = NormalizedSchema.of(schema).getName(true);
}
}
_write(schema, value, container) {
const isObject = value !== null && typeof value === "object";
const ns = NormalizedSchema.of(schema);
if (isObject) {
if (ns.isStructSchema()) {
const record = value;
const out = {};
const { jsonName } = this.settings;
let nameMap = void 0;
if (jsonName) {
nameMap = {};
}
let outCount = 0;
for (const [memberName, memberSchema] of ns.structIterator()) {
const serializableValue = this._write(memberSchema, record[memberName], ns);
if (serializableValue !== undefined) {
let targetKey = memberName;
if (jsonName) {
targetKey = memberSchema.getMergedTraits().jsonName ?? memberName;
nameMap[memberName] = targetKey;
}
out[targetKey] = serializableValue;
outCount++;
}
}
if (ns.isUnionSchema() && outCount === 0) {
const { $unknown } = record;
if (Array.isArray($unknown)) {
const [k, v] = $unknown;
out[k] = this._write(15, v);
}
}
else if (typeof record.__type === "string") {
for (const k in record) {
const v = record[k];
const targetKey = jsonName ? nameMap[k] ?? k : k;
if (!(targetKey in out)) {
out[targetKey] = this._write(15, v);
}
}
}
return out;
}
if (Array.isArray(value) && ns.isListSchema()) {
const listMember = ns.getValueSchema();
const out = [];
const sparse = !!ns.getMergedTraits().sparse;
for (const item of value) {
if (sparse || item != null) {
out.push(this._write(listMember, item));
}
}
return out;
}
if (ns.isMapSchema()) {
const mapMember = ns.getValueSchema();
const out = {};
const sparse = !!ns.getMergedTraits().sparse;
for (const _k in value) {
const _v = value[_k];
if (sparse || _v != null) {
out[_k] = this._write(mapMember, _v);
}
}
return out;
}
if (value instanceof Uint8Array && (ns.isBlobSchema() || ns.isDocumentSchema())) {
if (ns === this.rootSchema) {
return value;
}
return (this.serdeContext?.base64Encoder ?? toBase64)(value);
}
if (value instanceof Date && (ns.isTimestampSchema() || ns.isDocumentSchema())) {
const format = determineTimestampFormat(ns, this.settings);
switch (format) {
case 5:
return value.toISOString().replace(".000Z", "Z");
case 6:
return dateToUtcString(value);
case 7:
return value.getTime() / 1000;
default:
console.warn("Missing timestamp format, using epoch seconds", value);
return value.getTime() / 1000;
}
}
if (value instanceof NumericValue) {
this.useReplacer = true;
}
}
if (value === null && container?.isStructSchema()) {
return void 0;
}
if (ns.isStringSchema()) {
if (typeof value === "undefined" && ns.isIdempotencyToken()) {
return generateIdempotencyToken();
}
const mediaType = ns.getMergedTraits().mediaType;
if (value != null && mediaType) {
const isJson = mediaType === "application/json" || mediaType.endsWith("+json");
if (isJson) {
return LazyJsonString.from(value);
}
}
return value;
}
if (typeof value === "number" && ns.isNumericSchema()) {
if (Math.abs(value) === Infinity || isNaN(value)) {
return String(value);
}
return value;
}
if (typeof value === "string" && ns.isBlobSchema()) {
if (ns === this.rootSchema) {
return value;
}
return (this.serdeContext?.base64Encoder ?? toBase64)(value);
}
if (typeof value === "bigint") {
this.useReplacer = true;
}
if (ns.isDocumentSchema()) {
if (isObject) {
const out = Array.isArray(value) ? [] : {};
for (const k in value) {
const v = value[k];
if (v instanceof NumericValue) {
this.useReplacer = true;
out[k] = v;
}
else {
out[k] = this._write(ns, v);
}
}
return out;
}
else {
return structuredClone(value);
}
}
return value;
}
}
@@ -0,0 +1,10 @@
import { expectUnion } from "@smithy/core/serde";
export const awsExpectUnion = (value) => {
if (value == null) {
return undefined;
}
if (typeof value === "object" && "__type" in value) {
delete value.__type;
}
return expectUnion(value);
};
@@ -0,0 +1,135 @@
import { determineTimestampFormat } from "@smithy/core/protocols";
import { NormalizedSchema } from "@smithy/core/schema";
import { dateToUtcString, generateIdempotencyToken, LazyJsonString, NumericValue, toBase64 } from "@smithy/core/serde";
import { SerdeContextConfig } from "../../ConfigurableSerdeContext";
export class SinglePassJsonShapeSerializer extends SerdeContextConfig {
settings;
buffer;
rootSchema;
constructor(settings) {
super();
this.settings = settings;
}
write(schema, value) {
this.rootSchema = NormalizedSchema.of(schema);
this.buffer = this.writeObject(this.rootSchema, value);
}
writeDiscriminatedDocument(schema, value) {
this.write(schema, value);
if (typeof this.buffer === "object") {
this.buffer.__type = NormalizedSchema.of(schema).getName(true);
}
}
flush() {
this.rootSchema = undefined;
return this.buffer;
}
writeObject(schema, value) {
if (value == undefined) {
return "";
}
let b = "";
const ns = NormalizedSchema.of(schema);
const sparse = !!ns.getMergedTraits().sparse;
if (Array.isArray(value) && (ns.isDocumentSchema() || ns.isListSchema())) {
b += "[";
for (let i = 0; i < value.length; ++i) {
const item = value[i];
if (item != null || sparse) {
b += this.writeValue(ns.getValueSchema(), item);
b += ",";
}
}
}
else if (ns.isStructSchema()) {
b += "{";
let didWriteMember = false;
for (const [name, member] of ns.structIterator()) {
const item = value[name];
const targetKey = this.settings.jsonName ? member.getMergedTraits().jsonName ?? name : name;
const serializableValue = this.writeValue(member, item);
if (item != null || member.isIdempotencyToken()) {
didWriteMember = true;
b += `"${targetKey}":${serializableValue}`;
b += ",";
}
}
if (!didWriteMember && ns.isUnionSchema()) {
const { $unknown } = value;
if (Array.isArray($unknown)) {
const [k, v] = $unknown;
b += `"${k}":${this.writeValue(15, v)}`;
}
}
}
else if (ns.isMapSchema() || ns.isDocumentSchema()) {
b += "{";
for (const k in value) {
const v = value[k];
if (v != null || sparse) {
b += `"${k}":${this.writeValue(ns, v)}`;
b += ",";
}
}
}
if (b[b.length - 1] === ",") {
b = b.slice(0, -1);
}
if (b[0] === "[") {
b += "]";
}
if (b[0] === "{") {
b += "}";
}
return b;
}
writeValue(schema, value) {
const isObject = value !== null && typeof value === "object";
const ns = NormalizedSchema.of(schema);
const quote = (_) => `"${_}"`;
if ((ns.isBlobSchema() && (value instanceof Uint8Array || typeof value === "string")) ||
(ns.isDocumentSchema() && value instanceof Uint8Array)) {
return quote((this.serdeContext?.base64Encoder ?? toBase64)(value));
}
if ((ns.isTimestampSchema() || ns.isDocumentSchema()) && value instanceof Date) {
const format = determineTimestampFormat(ns, this.settings);
switch (format) {
case 5:
return quote(value.toISOString().replace(".000Z", "Z"));
case 6:
return quote(dateToUtcString(value));
case 7:
return String(value.getTime() / 1000);
default:
console.warn("Missing timestamp format, using epoch seconds", value);
return String(value.getTime() / 1000);
}
}
if (ns.isNumericSchema() && typeof value === "number") {
if (Math.abs(value) === Infinity || isNaN(value)) {
return quote(String(value));
}
}
if (ns.isStringSchema()) {
if (typeof value === "undefined" && ns.isIdempotencyToken()) {
return quote(generateIdempotencyToken());
}
if (typeof value === "string") {
const mediaType = ns.getMergedTraits().mediaType;
if (mediaType) {
const isJson = mediaType === "application/json" || mediaType.endsWith("+json");
if (isJson) {
return quote(LazyJsonString.from(value).toString());
}
}
}
}
if (value instanceof NumericValue) {
return value.string;
}
if (isObject) {
return this.writeObject(ns, value);
}
return typeof value === "string" ? quote(value) : String(value);
}
}
@@ -0,0 +1,46 @@
import { NumericValue } from "@smithy/core/serde";
const NUMERIC_CONTROL_CHAR = String.fromCharCode(925);
export class JsonReplacer {
values = new Map();
counter = 0;
stage = 0;
createReplacer() {
if (this.stage === 1) {
throw new Error("@aws-sdk/core/protocols - JsonReplacer already created.");
}
if (this.stage === 2) {
throw new Error("@aws-sdk/core/protocols - JsonReplacer exhausted.");
}
this.stage = 1;
return (key, value) => {
if (value instanceof NumericValue) {
const v = `${NUMERIC_CONTROL_CHAR + "nv" + this.counter++}_` + value.string;
this.values.set(`"${v}"`, value.string);
return v;
}
if (typeof value === "bigint") {
const s = value.toString();
const v = `${NUMERIC_CONTROL_CHAR + "b" + this.counter++}_` + s;
this.values.set(`"${v}"`, s);
return v;
}
return value;
};
}
replaceInJson(json) {
if (this.stage === 0) {
throw new Error("@aws-sdk/core/protocols - JsonReplacer not created yet.");
}
if (this.stage === 2) {
throw new Error("@aws-sdk/core/protocols - JsonReplacer exhausted.");
}
this.stage = 2;
if (this.counter === 0) {
return json;
}
for (const [key, value] of this.values) {
json = json.replace(key, value);
}
return json;
}
}
@@ -0,0 +1,18 @@
import { NumericValue } from "@smithy/core/serde";
export function jsonReviver(key, value, context) {
if (context?.source) {
const numericString = context.source;
if (typeof value === "number") {
if (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER || numericString !== String(value)) {
const isFractional = numericString.includes(".");
if (isFractional) {
return new NumericValue(numericString, "bigDecimal");
}
else {
return BigInt(numericString);
}
}
}
}
return value;
}
@@ -0,0 +1,69 @@
import { collectBodyString } from "../common";
export const parseJsonBody = (streamBody, context) => collectBodyString(streamBody, context).then((encoded) => {
if (encoded.length) {
try {
return JSON.parse(encoded);
}
catch (e) {
if (e?.name === "SyntaxError") {
Object.defineProperty(e, "$responseBodyText", {
value: encoded,
});
}
throw e;
}
}
return {};
});
export const parseJsonErrorBody = async (errorBody, context) => {
const value = await parseJsonBody(errorBody, context);
value.message = value.message ?? value.Message;
return value;
};
const findKey = (object, key) => Object.keys(object).find((k) => k.toLowerCase() === key.toLowerCase());
const sanitizeErrorCode = (rawValue) => {
let cleanValue = rawValue;
if (typeof cleanValue === "number") {
cleanValue = cleanValue.toString();
}
if (cleanValue.indexOf(",") >= 0) {
cleanValue = cleanValue.split(",")[0];
}
if (cleanValue.indexOf(":") >= 0) {
cleanValue = cleanValue.split(":")[0];
}
if (cleanValue.indexOf("#") >= 0) {
cleanValue = cleanValue.split("#")[1];
}
return cleanValue;
};
export const loadRestJsonErrorCode = (output, data) => {
return loadErrorCode(output, data, ["header", "code", "type"]);
};
export const loadJsonRpcErrorCode = (output, data, queryCompat = false) => {
return loadErrorCode(output, data, queryCompat ? ["code", "header", "type"] : ["type", "code", "header"]);
};
const loadErrorCode = ({ headers }, data, order) => {
while (order.length > 0) {
const location = order.shift();
switch (location) {
case "header":
const headerKey = findKey(headers ?? {}, "x-amzn-errortype");
if (headerKey !== undefined) {
return sanitizeErrorCode(headers[headerKey]);
}
break;
case "code":
const codeKey = findKey(data ?? {}, "code");
if (codeKey && data[codeKey] !== undefined) {
return sanitizeErrorCode(data[codeKey]);
}
break;
case "type":
if (data?.__type !== undefined) {
return sanitizeErrorCode(data.__type);
}
break;
}
}
};
@@ -0,0 +1,21 @@
import { AwsQueryProtocol } from "./AwsQueryProtocol";
export class AwsEc2QueryProtocol extends AwsQueryProtocol {
options;
constructor(options) {
super(options);
this.options = options;
const ec2Settings = {
capitalizeKeys: true,
flattenLists: true,
serializeEmptyLists: false,
ec2: true,
};
Object.assign(this.serializer.settings, ec2Settings);
}
getShapeId() {
return "aws.protocols#ec2Query";
}
useNestedResult() {
return false;
}
}
@@ -0,0 +1,133 @@
import { collectBody, RpcProtocol } from "@smithy/core/protocols";
import { deref, NormalizedSchema } from "@smithy/core/schema";
import { ProtocolLib } from "../ProtocolLib";
import { XmlShapeDeserializer } from "../xml/XmlShapeDeserializer";
import { QueryShapeSerializer } from "./QueryShapeSerializer";
export class AwsQueryProtocol extends RpcProtocol {
options;
serializer;
deserializer;
mixin = new ProtocolLib();
constructor(options) {
super({
defaultNamespace: options.defaultNamespace,
errorTypeRegistries: options.errorTypeRegistries,
});
this.options = options;
const settings = {
timestampFormat: {
useTrait: true,
default: 5,
},
httpBindings: false,
xmlNamespace: options.xmlNamespace,
serviceNamespace: options.defaultNamespace,
serializeEmptyLists: true,
};
this.serializer = new QueryShapeSerializer(settings);
this.deserializer = new XmlShapeDeserializer(settings);
}
getShapeId() {
return "aws.protocols#awsQuery";
}
setSerdeContext(serdeContext) {
this.serializer.setSerdeContext(serdeContext);
this.deserializer.setSerdeContext(serdeContext);
}
getPayloadCodec() {
throw new Error("AWSQuery protocol has no payload codec.");
}
async serializeRequest(operationSchema, input, context) {
const request = await super.serializeRequest(operationSchema, input, context);
if (!request.path.endsWith("/")) {
request.path += "/";
}
request.headers["content-type"] = "application/x-www-form-urlencoded";
if (deref(operationSchema.input) === "unit" || !request.body) {
request.body = "";
}
const action = operationSchema.name.split("#")[1] ?? operationSchema.name;
request.body = `Action=${action}&Version=${this.options.version}` + request.body;
if (request.body.endsWith("&")) {
request.body = request.body.slice(-1);
}
return request;
}
async deserializeResponse(operationSchema, context, response) {
const deserializer = this.deserializer;
const ns = NormalizedSchema.of(operationSchema.output);
const dataObject = {};
if (response.statusCode >= 300) {
const bytes = await collectBody(response.body, context);
if (bytes.byteLength > 0) {
Object.assign(dataObject, await deserializer.read(15, bytes));
}
await this.handleError(operationSchema, context, response, dataObject, this.deserializeMetadata(response));
}
for (const header in response.headers) {
const value = response.headers[header];
delete response.headers[header];
response.headers[header.toLowerCase()] = value;
}
const shortName = operationSchema.name.split("#")[1] ?? operationSchema.name;
const awsQueryResultKey = ns.isStructSchema() && this.useNestedResult() ? shortName + "Result" : undefined;
const bytes = await collectBody(response.body, context);
if (bytes.byteLength > 0) {
Object.assign(dataObject, await deserializer.read(ns, bytes, awsQueryResultKey));
}
dataObject.$metadata = this.deserializeMetadata(response);
return dataObject;
}
useNestedResult() {
return true;
}
async handleError(operationSchema, context, response, dataObject, metadata) {
const errorIdentifier = this.loadQueryErrorCode(response, dataObject) ?? "Unknown";
this.mixin.compose(this.compositeErrorRegistry, errorIdentifier, this.options.defaultNamespace);
const errorData = this.loadQueryError(dataObject) ?? {};
const message = this.loadQueryErrorMessage(dataObject);
errorData.message = message;
errorData.Error = {
Type: errorData.Type,
Code: errorData.Code,
Message: message,
};
const { errorSchema, errorMetadata } = await this.mixin.getErrorSchemaOrThrowBaseException(errorIdentifier, this.options.defaultNamespace, response, errorData, metadata, this.mixin.findQueryCompatibleError);
const ns = NormalizedSchema.of(errorSchema);
const ErrorCtor = this.compositeErrorRegistry.getErrorCtor(errorSchema) ?? Error;
const exception = new ErrorCtor({});
const output = {
Type: errorData.Error.Type,
Code: errorData.Error.Code,
Error: errorData.Error,
};
for (const [name, member] of ns.structIterator()) {
const target = member.getMergedTraits().xmlName ?? name;
const value = errorData[target] ?? dataObject[target];
output[name] = this.deserializer.readSchema(member, value);
}
throw this.mixin.decorateServiceException(Object.assign(exception, errorMetadata, {
$fault: ns.getMergedTraits().error,
message,
}, output), dataObject);
}
loadQueryErrorCode(output, data) {
const code = (data.Errors?.[0]?.Error ?? data.Errors?.Error ?? data.Error)?.Code;
if (code !== undefined) {
return code;
}
if (output.statusCode == 404) {
return "NotFound";
}
}
loadQueryError(data) {
return data.Errors?.[0]?.Error ?? data.Errors?.Error ?? data.Error;
}
loadQueryErrorMessage(data) {
const errorData = this.loadQueryError(data);
return errorData?.message ?? errorData?.Message ?? data.message ?? data.Message ?? "Unknown";
}
getDefaultContentType() {
return "application/x-www-form-urlencoded";
}
}
@@ -0,0 +1 @@
export {};
@@ -0,0 +1,189 @@
import { determineTimestampFormat, extendedEncodeURIComponent } from "@smithy/core/protocols";
import { NormalizedSchema } from "@smithy/core/schema";
import { dateToUtcString } from "@smithy/core/serde";
import { generateIdempotencyToken, NumericValue, toBase64 } from "@smithy/core/serde";
import { SerdeContextConfig } from "../ConfigurableSerdeContext";
export class QueryShapeSerializer extends SerdeContextConfig {
settings;
buffer;
constructor(settings) {
super();
this.settings = settings;
}
write(schema, value, prefix = "") {
if (this.buffer === undefined) {
this.buffer = "";
}
const ns = NormalizedSchema.of(schema);
if (prefix && !prefix.endsWith(".")) {
prefix += ".";
}
if (ns.isBlobSchema()) {
if (typeof value === "string" || value instanceof Uint8Array) {
this.writeKey(prefix);
this.writeValue((this.serdeContext?.base64Encoder ?? toBase64)(value));
}
}
else if (ns.isBooleanSchema() || ns.isNumericSchema() || ns.isStringSchema()) {
if (value != null) {
this.writeKey(prefix);
this.writeValue(String(value));
}
else if (ns.isIdempotencyToken()) {
this.writeKey(prefix);
this.writeValue(generateIdempotencyToken());
}
}
else if (ns.isBigIntegerSchema()) {
if (value != null) {
this.writeKey(prefix);
this.writeValue(String(value));
}
}
else if (ns.isBigDecimalSchema()) {
if (value != null) {
this.writeKey(prefix);
this.writeValue(value instanceof NumericValue ? value.string : String(value));
}
}
else if (ns.isTimestampSchema()) {
if (value instanceof Date) {
this.writeKey(prefix);
const format = determineTimestampFormat(ns, this.settings);
switch (format) {
case 5:
this.writeValue(value.toISOString().replace(".000Z", "Z"));
break;
case 6:
this.writeValue(dateToUtcString(value));
break;
case 7:
this.writeValue(String(value.getTime() / 1000));
break;
}
}
}
else if (ns.isDocumentSchema()) {
if (Array.isArray(value)) {
this.write(64 | 15, value, prefix);
}
else if (value instanceof Date) {
this.write(4, value, prefix);
}
else if (value instanceof Uint8Array) {
this.write(21, value, prefix);
}
else if (value && typeof value === "object") {
this.write(128 | 15, value, prefix);
}
else {
this.writeKey(prefix);
this.writeValue(String(value));
}
}
else if (ns.isListSchema()) {
if (Array.isArray(value)) {
if (value.length === 0) {
if (this.settings.serializeEmptyLists) {
this.writeKey(prefix);
this.writeValue("");
}
}
else {
const member = ns.getValueSchema();
const flat = this.settings.flattenLists || ns.getMergedTraits().xmlFlattened;
let i = 1;
for (const item of value) {
if (item == null) {
continue;
}
const traits = member.getMergedTraits();
const suffix = this.getKey("member", traits.xmlName, traits.ec2QueryName);
const key = flat ? `${prefix}${i}` : `${prefix}${suffix}.${i}`;
this.write(member, item, key);
++i;
}
}
}
}
else if (ns.isMapSchema()) {
if (value && typeof value === "object") {
const keySchema = ns.getKeySchema();
const memberSchema = ns.getValueSchema();
const flat = ns.getMergedTraits().xmlFlattened;
let i = 1;
for (const k in value) {
const v = value[k];
if (v == null) {
continue;
}
const keyTraits = keySchema.getMergedTraits();
const keySuffix = this.getKey("key", keyTraits.xmlName, keyTraits.ec2QueryName);
const key = flat ? `${prefix}${i}.${keySuffix}` : `${prefix}entry.${i}.${keySuffix}`;
const valTraits = memberSchema.getMergedTraits();
const valueSuffix = this.getKey("value", valTraits.xmlName, valTraits.ec2QueryName);
const valueKey = flat ? `${prefix}${i}.${valueSuffix}` : `${prefix}entry.${i}.${valueSuffix}`;
this.write(keySchema, k, key);
this.write(memberSchema, v, valueKey);
++i;
}
}
}
else if (ns.isStructSchema()) {
if (value && typeof value === "object") {
let didWriteMember = false;
for (const [memberName, member] of ns.structIterator()) {
if (value[memberName] == null && !member.isIdempotencyToken()) {
continue;
}
const traits = member.getMergedTraits();
const suffix = this.getKey(memberName, traits.xmlName, traits.ec2QueryName, "struct");
const key = `${prefix}${suffix}`;
this.write(member, value[memberName], key);
didWriteMember = true;
}
if (!didWriteMember && ns.isUnionSchema()) {
const { $unknown } = value;
if (Array.isArray($unknown)) {
const [k, v] = $unknown;
const key = `${prefix}${k}`;
this.write(15, v, key);
}
}
}
}
else if (ns.isUnitSchema()) {
}
else {
throw new Error(`@aws-sdk/core/protocols - QuerySerializer unrecognized schema type ${ns.getName(true)}`);
}
}
flush() {
if (this.buffer === undefined) {
throw new Error("@aws-sdk/core/protocols - QuerySerializer cannot flush with nothing written to buffer.");
}
const str = this.buffer;
delete this.buffer;
return str;
}
getKey(memberName, xmlName, ec2QueryName, keySource) {
const { ec2, capitalizeKeys } = this.settings;
if (ec2 && ec2QueryName) {
return ec2QueryName;
}
const key = xmlName ?? memberName;
if (capitalizeKeys && keySource === "struct") {
return key[0].toUpperCase() + key.slice(1);
}
return key;
}
writeKey(key) {
if (key.endsWith(".")) {
key = key.slice(0, key.length - 1);
}
this.buffer += `&${extendedEncodeURIComponent(key)}=`;
}
writeValue(value) {
this.buffer += extendedEncodeURIComponent(value);
}
}
@@ -0,0 +1,99 @@
import { HttpBindingProtocol, HttpInterceptingShapeDeserializer, HttpInterceptingShapeSerializer, } from "@smithy/core/protocols";
import { NormalizedSchema } from "@smithy/core/schema";
import { ProtocolLib } from "../ProtocolLib";
import { loadRestXmlErrorCode } from "./parseXmlBody";
import { XmlCodec } from "./XmlCodec";
export class AwsRestXmlProtocol extends HttpBindingProtocol {
codec;
serializer;
deserializer;
mixin = new ProtocolLib();
constructor(options) {
super(options);
const settings = {
timestampFormat: {
useTrait: true,
default: 5,
},
httpBindings: true,
xmlNamespace: options.xmlNamespace,
serviceNamespace: options.defaultNamespace,
};
this.codec = new XmlCodec(settings);
this.serializer = new HttpInterceptingShapeSerializer(this.codec.createSerializer(), settings);
this.deserializer = new HttpInterceptingShapeDeserializer(this.codec.createDeserializer(), settings);
}
getPayloadCodec() {
return this.codec;
}
getShapeId() {
return "aws.protocols#restXml";
}
async serializeRequest(operationSchema, input, context) {
const request = await super.serializeRequest(operationSchema, input, context);
const inputSchema = NormalizedSchema.of(operationSchema.input);
if (!request.headers["content-type"]) {
const contentType = this.mixin.resolveRestContentType(this.getDefaultContentType(), inputSchema);
if (contentType) {
request.headers["content-type"] = contentType;
}
}
if (typeof request.body === "string" &&
request.headers["content-type"] === this.getDefaultContentType() &&
!request.body.startsWith("<?xml ") &&
!this.hasUnstructuredPayloadBinding(inputSchema)) {
request.body = '<?xml version="1.0" encoding="UTF-8"?>' + request.body;
}
return request;
}
async deserializeResponse(operationSchema, context, response) {
return super.deserializeResponse(operationSchema, context, response);
}
async handleError(operationSchema, context, response, dataObject, metadata) {
const errorIdentifier = loadRestXmlErrorCode(response, dataObject) ?? "Unknown";
this.mixin.compose(this.compositeErrorRegistry, errorIdentifier, this.options.defaultNamespace);
if (dataObject.Error && typeof dataObject.Error === "object") {
for (const key of Object.keys(dataObject.Error)) {
dataObject[key] = dataObject.Error[key];
if (key.toLowerCase() === "message") {
dataObject.message = dataObject.Error[key];
}
}
}
if (dataObject.RequestId && !metadata.requestId) {
metadata.requestId = dataObject.RequestId;
}
const { errorSchema, errorMetadata } = await this.mixin.getErrorSchemaOrThrowBaseException(errorIdentifier, this.options.defaultNamespace, response, dataObject, metadata);
const ns = NormalizedSchema.of(errorSchema);
const message = dataObject.Error?.message ??
dataObject.Error?.Message ??
dataObject.message ??
dataObject.Message ??
"UnknownError";
const ErrorCtor = this.compositeErrorRegistry.getErrorCtor(errorSchema) ?? Error;
const exception = new ErrorCtor({});
await this.deserializeHttpMessage(errorSchema, context, response, dataObject);
const output = {};
const errorDeserializer = this.codec.createDeserializer();
for (const [name, member] of ns.structIterator()) {
const target = member.getMergedTraits().xmlName ?? name;
const value = dataObject.Error?.[target] ?? dataObject[target];
output[name] = errorDeserializer.readSchema(member, value);
}
throw this.mixin.decorateServiceException(Object.assign(exception, errorMetadata, {
$fault: ns.getMergedTraits().error,
message,
}, output), dataObject);
}
getDefaultContentType() {
return "application/xml";
}
hasUnstructuredPayloadBinding(ns) {
for (const [, member] of ns.structIterator()) {
if (member.getMergedTraits().httpPayload) {
return !(member.isStructSchema() || member.isMapSchema() || member.isListSchema());
}
}
return false;
}
}
@@ -0,0 +1,20 @@
import { SerdeContextConfig } from "../ConfigurableSerdeContext";
import { XmlShapeDeserializer } from "./XmlShapeDeserializer";
import { XmlShapeSerializer } from "./XmlShapeSerializer";
export class XmlCodec extends SerdeContextConfig {
settings;
constructor(settings) {
super();
this.settings = settings;
}
createSerializer() {
const serializer = new XmlShapeSerializer(this.settings);
serializer.setSerdeContext(this.serdeContext);
return serializer;
}
createDeserializer() {
const deserializer = new XmlShapeDeserializer(this.settings);
deserializer.setSerdeContext(this.serdeContext);
return deserializer;
}
}
@@ -0,0 +1,153 @@
import { parseXML } from "@aws-sdk/xml-builder";
import { getValueFromTextNode } from "@smithy/core/client";
import { FromStringShapeDeserializer } from "@smithy/core/protocols";
import { NormalizedSchema } from "@smithy/core/schema";
import { toUtf8 } from "@smithy/core/serde";
import { SerdeContextConfig } from "../ConfigurableSerdeContext";
import { UnionSerde } from "../UnionSerde";
export class XmlShapeDeserializer extends SerdeContextConfig {
settings;
stringDeserializer;
constructor(settings) {
super();
this.settings = settings;
this.stringDeserializer = new FromStringShapeDeserializer(settings);
}
setSerdeContext(serdeContext) {
this.serdeContext = serdeContext;
this.stringDeserializer.setSerdeContext(serdeContext);
}
read(schema, bytes, key) {
const ns = NormalizedSchema.of(schema);
const memberSchemas = ns.getMemberSchemas();
const isEventPayload = ns.isStructSchema() &&
ns.isMemberSchema() &&
!!Object.values(memberSchemas).find((memberNs) => {
return !!memberNs.getMemberTraits().eventPayload;
});
if (isEventPayload) {
const output = {};
const memberName = Object.keys(memberSchemas)[0];
const eventMemberSchema = memberSchemas[memberName];
if (eventMemberSchema.isBlobSchema()) {
output[memberName] = bytes;
}
else {
output[memberName] = this.read(memberSchemas[memberName], bytes);
}
return output;
}
const xmlString = (this.serdeContext?.utf8Encoder ?? toUtf8)(bytes);
const parsedObject = this.parseXml(xmlString);
return this.readSchema(schema, key ? parsedObject[key] : parsedObject);
}
readSchema(_schema, value) {
const ns = NormalizedSchema.of(_schema);
if (ns.isUnitSchema()) {
return;
}
const traits = ns.getMergedTraits();
if (ns.isListSchema() && !Array.isArray(value)) {
return this.readSchema(ns, [value]);
}
if (value == null) {
return value;
}
if (typeof value === "object") {
const flat = !!traits.xmlFlattened;
if (ns.isListSchema()) {
const listValue = ns.getValueSchema();
const buffer = [];
const sourceKey = listValue.getMergedTraits().xmlName ?? "member";
const source = flat ? value : (value[0] ?? value)[sourceKey];
if (source == null) {
return buffer;
}
const sourceArray = Array.isArray(source) ? source : [source];
for (const v of sourceArray) {
buffer.push(this.readSchema(listValue, v));
}
return buffer;
}
const buffer = {};
if (ns.isMapSchema()) {
const keyNs = ns.getKeySchema();
const memberNs = ns.getValueSchema();
let entries;
if (flat) {
entries = Array.isArray(value) ? value : [value];
}
else {
entries = Array.isArray(value.entry) ? value.entry : [value.entry];
}
const keyProperty = keyNs.getMergedTraits().xmlName ?? "key";
const valueProperty = memberNs.getMergedTraits().xmlName ?? "value";
for (const entry of entries) {
const key = entry[keyProperty];
const value = entry[valueProperty];
buffer[key] = this.readSchema(memberNs, value);
}
return buffer;
}
if (ns.isStructSchema()) {
const union = ns.isUnionSchema();
let unionSerde;
if (union) {
unionSerde = new UnionSerde(value, buffer);
}
for (const [memberName, memberSchema] of ns.structIterator()) {
const memberTraits = memberSchema.getMergedTraits();
const xmlObjectKey = !memberTraits.httpPayload
? memberSchema.getMemberTraits().xmlName ?? memberName
: memberTraits.xmlName ?? memberSchema.getName();
if (union) {
unionSerde.mark(xmlObjectKey);
}
if (value[xmlObjectKey] != null) {
buffer[memberName] = this.readSchema(memberSchema, value[xmlObjectKey]);
}
}
if (union) {
unionSerde.writeUnknown();
}
return buffer;
}
if (ns.isDocumentSchema()) {
return value;
}
throw new Error(`@aws-sdk/core/protocols - xml deserializer unhandled schema type for ${ns.getName(true)}`);
}
if (ns.isListSchema()) {
return [];
}
if (ns.isMapSchema() || ns.isStructSchema()) {
return {};
}
return this.stringDeserializer.read(ns, value);
}
parseXml(xml) {
if (xml.length) {
let parsedObj;
try {
parsedObj = parseXML(xml);
}
catch (e) {
if (e && typeof e === "object") {
Object.defineProperty(e, "$responseBodyText", {
value: xml,
});
}
throw e;
}
const textNodeName = "#text";
const key = Object.keys(parsedObj)[0];
const parsedObjToReturn = parsedObj[key];
if (parsedObjToReturn[textNodeName]) {
parsedObjToReturn[key] = parsedObjToReturn[textNodeName];
delete parsedObjToReturn[textNodeName];
}
return getValueFromTextNode(parsedObjToReturn);
}
return {};
}
}
@@ -0,0 +1,296 @@
import { XmlNode, XmlText } from "@aws-sdk/xml-builder";
import { determineTimestampFormat } from "@smithy/core/protocols";
import { NormalizedSchema } from "@smithy/core/schema";
import { dateToUtcString } from "@smithy/core/serde";
import { fromBase64, generateIdempotencyToken, NumericValue, toBase64 } from "@smithy/core/serde";
import { SerdeContextConfig } from "../ConfigurableSerdeContext";
export class XmlShapeSerializer extends SerdeContextConfig {
settings;
stringBuffer;
byteBuffer;
buffer;
constructor(settings) {
super();
this.settings = settings;
}
write(schema, value) {
const ns = NormalizedSchema.of(schema);
if (ns.isStringSchema() && typeof value === "string") {
this.stringBuffer = value;
}
else if (ns.isBlobSchema()) {
this.byteBuffer =
"byteLength" in value
? value
: (this.serdeContext?.base64Decoder ?? fromBase64)(value);
}
else {
this.buffer = this.writeStruct(ns, value, undefined);
const traits = ns.getMergedTraits();
if (traits.httpPayload && !traits.xmlName) {
this.buffer.withName(ns.getName());
}
}
}
flush() {
if (this.byteBuffer !== undefined) {
const bytes = this.byteBuffer;
delete this.byteBuffer;
return bytes;
}
if (this.stringBuffer !== undefined) {
const str = this.stringBuffer;
delete this.stringBuffer;
return str;
}
const buffer = this.buffer;
if (this.settings.xmlNamespace) {
if (!buffer?.attributes?.["xmlns"]) {
buffer.addAttribute("xmlns", this.settings.xmlNamespace);
}
}
delete this.buffer;
return buffer.toString();
}
writeStruct(ns, value, parentXmlns) {
const traits = ns.getMergedTraits();
const name = ns.isMemberSchema() && !traits.httpPayload
? ns.getMemberTraits().xmlName ?? ns.getMemberName()
: traits.xmlName ?? ns.getName();
if (!name || !ns.isStructSchema()) {
throw new Error(`@aws-sdk/core/protocols - xml serializer, cannot write struct with empty name or non-struct, schema=${ns.getName(true)}.`);
}
const structXmlNode = XmlNode.of(name);
const [xmlnsAttr, xmlns] = this.getXmlnsAttribute(ns, parentXmlns);
for (const [memberName, memberSchema] of ns.structIterator()) {
const val = value[memberName];
if (val != null || memberSchema.isIdempotencyToken()) {
if (memberSchema.getMergedTraits().xmlAttribute) {
structXmlNode.addAttribute(memberSchema.getMergedTraits().xmlName ?? memberName, this.writeSimple(memberSchema, val));
continue;
}
if (memberSchema.isListSchema()) {
this.writeList(memberSchema, val, structXmlNode, xmlns);
}
else if (memberSchema.isMapSchema()) {
this.writeMap(memberSchema, val, structXmlNode, xmlns);
}
else if (memberSchema.isStructSchema()) {
structXmlNode.addChildNode(this.writeStruct(memberSchema, val, xmlns));
}
else {
const memberNode = XmlNode.of(memberSchema.getMergedTraits().xmlName ?? memberSchema.getMemberName());
this.writeSimpleInto(memberSchema, val, memberNode, xmlns);
structXmlNode.addChildNode(memberNode);
}
}
}
const { $unknown } = value;
if ($unknown && ns.isUnionSchema() && Array.isArray($unknown) && Object.keys(value).length === 1) {
const [k, v] = $unknown;
const node = XmlNode.of(k);
if (typeof v !== "string") {
if (value instanceof XmlNode || value instanceof XmlText) {
structXmlNode.addChildNode(value);
}
else {
throw new Error(`@aws-sdk - $unknown union member in XML requires ` +
`value of type string, @aws-sdk/xml-builder::XmlNode or XmlText.`);
}
}
this.writeSimpleInto(0, v, node, xmlns);
structXmlNode.addChildNode(node);
}
if (xmlns) {
structXmlNode.addAttribute(xmlnsAttr, xmlns);
}
return structXmlNode;
}
writeList(listMember, array, container, parentXmlns) {
if (!listMember.isMemberSchema()) {
throw new Error(`@aws-sdk/core/protocols - xml serializer, cannot write non-member list: ${listMember.getName(true)}`);
}
const listTraits = listMember.getMergedTraits();
const listValueSchema = listMember.getValueSchema();
const listValueTraits = listValueSchema.getMergedTraits();
const sparse = !!listValueTraits.sparse;
const flat = !!listTraits.xmlFlattened;
const [xmlnsAttr, xmlns] = this.getXmlnsAttribute(listMember, parentXmlns);
const writeItem = (container, value) => {
if (listValueSchema.isListSchema()) {
this.writeList(listValueSchema, Array.isArray(value) ? value : [value], container, xmlns);
}
else if (listValueSchema.isMapSchema()) {
this.writeMap(listValueSchema, value, container, xmlns);
}
else if (listValueSchema.isStructSchema()) {
const struct = this.writeStruct(listValueSchema, value, xmlns);
container.addChildNode(struct.withName(flat ? listTraits.xmlName ?? listMember.getMemberName() : listValueTraits.xmlName ?? "member"));
}
else {
const listItemNode = XmlNode.of(flat ? listTraits.xmlName ?? listMember.getMemberName() : listValueTraits.xmlName ?? "member");
this.writeSimpleInto(listValueSchema, value, listItemNode, xmlns);
container.addChildNode(listItemNode);
}
};
if (flat) {
for (const value of array) {
if (sparse || value != null) {
writeItem(container, value);
}
}
}
else {
const listNode = XmlNode.of(listTraits.xmlName ?? listMember.getMemberName());
if (xmlns) {
listNode.addAttribute(xmlnsAttr, xmlns);
}
for (const value of array) {
if (sparse || value != null) {
writeItem(listNode, value);
}
}
container.addChildNode(listNode);
}
}
writeMap(mapMember, map, container, parentXmlns, containerIsMap = false) {
if (!mapMember.isMemberSchema()) {
throw new Error(`@aws-sdk/core/protocols - xml serializer, cannot write non-member map: ${mapMember.getName(true)}`);
}
const mapTraits = mapMember.getMergedTraits();
const mapKeySchema = mapMember.getKeySchema();
const mapKeyTraits = mapKeySchema.getMergedTraits();
const keyTag = mapKeyTraits.xmlName ?? "key";
const mapValueSchema = mapMember.getValueSchema();
const mapValueTraits = mapValueSchema.getMergedTraits();
const valueTag = mapValueTraits.xmlName ?? "value";
const sparse = !!mapValueTraits.sparse;
const flat = !!mapTraits.xmlFlattened;
const [xmlnsAttr, xmlns] = this.getXmlnsAttribute(mapMember, parentXmlns);
const addKeyValue = (entry, key, val) => {
const keyNode = XmlNode.of(keyTag, key);
const [keyXmlnsAttr, keyXmlns] = this.getXmlnsAttribute(mapKeySchema, xmlns);
if (keyXmlns) {
keyNode.addAttribute(keyXmlnsAttr, keyXmlns);
}
entry.addChildNode(keyNode);
let valueNode = XmlNode.of(valueTag);
if (mapValueSchema.isListSchema()) {
this.writeList(mapValueSchema, val, valueNode, xmlns);
}
else if (mapValueSchema.isMapSchema()) {
this.writeMap(mapValueSchema, val, valueNode, xmlns, true);
}
else if (mapValueSchema.isStructSchema()) {
valueNode = this.writeStruct(mapValueSchema, val, xmlns);
}
else {
this.writeSimpleInto(mapValueSchema, val, valueNode, xmlns);
}
entry.addChildNode(valueNode);
};
if (flat) {
for (const key in map) {
const val = map[key];
if (sparse || val != null) {
const entry = XmlNode.of(mapTraits.xmlName ?? mapMember.getMemberName());
addKeyValue(entry, key, val);
container.addChildNode(entry);
}
}
}
else {
let mapNode;
if (!containerIsMap) {
mapNode = XmlNode.of(mapTraits.xmlName ?? mapMember.getMemberName());
if (xmlns) {
mapNode.addAttribute(xmlnsAttr, xmlns);
}
container.addChildNode(mapNode);
}
for (const key in map) {
const val = map[key];
if (sparse || val != null) {
const entry = XmlNode.of("entry");
addKeyValue(entry, key, val);
(containerIsMap ? container : mapNode).addChildNode(entry);
}
}
}
}
writeSimple(_schema, value) {
if (null === value) {
throw new Error("@aws-sdk/core/protocols - (XML serializer) cannot write null value.");
}
const ns = NormalizedSchema.of(_schema);
let nodeContents = null;
if (value && typeof value === "object") {
if (ns.isBlobSchema()) {
nodeContents = (this.serdeContext?.base64Encoder ?? toBase64)(value);
}
else if (ns.isTimestampSchema() && value instanceof Date) {
const format = determineTimestampFormat(ns, this.settings);
switch (format) {
case 5:
nodeContents = value.toISOString().replace(".000Z", "Z");
break;
case 6:
nodeContents = dateToUtcString(value);
break;
case 7:
nodeContents = String(value.getTime() / 1000);
break;
default:
console.warn("Missing timestamp format, using http date", value);
nodeContents = dateToUtcString(value);
break;
}
}
else if (ns.isBigDecimalSchema() && value) {
if (value instanceof NumericValue) {
return value.string;
}
return String(value);
}
else if (ns.isMapSchema() || ns.isListSchema()) {
throw new Error("@aws-sdk/core/protocols - xml serializer, cannot call _write() on List/Map schema, call writeList or writeMap() instead.");
}
else {
throw new Error(`@aws-sdk/core/protocols - xml serializer, unhandled schema type for object value and schema: ${ns.getName(true)}`);
}
}
if (ns.isBooleanSchema() || ns.isNumericSchema() || ns.isBigIntegerSchema() || ns.isBigDecimalSchema()) {
nodeContents = String(value);
}
if (ns.isStringSchema()) {
if (value === undefined && ns.isIdempotencyToken()) {
nodeContents = generateIdempotencyToken();
}
else {
nodeContents = String(value);
}
}
if (nodeContents === null) {
throw new Error(`Unhandled schema-value pair ${ns.getName(true)}=${value}`);
}
return nodeContents;
}
writeSimpleInto(_schema, value, into, parentXmlns) {
const nodeContents = this.writeSimple(_schema, value);
const ns = NormalizedSchema.of(_schema);
const content = new XmlText(nodeContents);
const [xmlnsAttr, xmlns] = this.getXmlnsAttribute(ns, parentXmlns);
if (xmlns) {
into.addAttribute(xmlnsAttr, xmlns);
}
into.addChildNode(content);
}
getXmlnsAttribute(ns, parentXmlns) {
const traits = ns.getMergedTraits();
const [prefix, xmlns] = traits.xmlNamespace ?? [];
if (xmlns && xmlns !== parentXmlns) {
return [prefix ? `xmlns:${prefix}` : "xmlns", xmlns];
}
return [void 0, void 0];
}
}

Some files were not shown because too many files have changed in this diff Show More