195 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			195 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						|
 | 
						|
var core = require('@smithy/core');
 | 
						|
var utilEndpoints = require('@aws-sdk/util-endpoints');
 | 
						|
var protocolHttp = require('@smithy/protocol-http');
 | 
						|
var core$1 = require('@aws-sdk/core');
 | 
						|
 | 
						|
const DEFAULT_UA_APP_ID = undefined;
 | 
						|
function isValidUserAgentAppId(appId) {
 | 
						|
    if (appId === undefined) {
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
    return typeof appId === "string" && appId.length <= 50;
 | 
						|
}
 | 
						|
function resolveUserAgentConfig(input) {
 | 
						|
    const normalizedAppIdProvider = core.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;
 | 
						|
        },
 | 
						|
    });
 | 
						|
}
 | 
						|
 | 
						|
const ACCOUNT_ID_ENDPOINT_REGEX = /\d{12}\.ddb/;
 | 
						|
async function checkFeatures(context, config, args) {
 | 
						|
    const request = args.request;
 | 
						|
    if (request?.headers?.["smithy-protocol"] === "rpc-v2-cbor") {
 | 
						|
        core$1.setFeature(context, "PROTOCOL_RPC_V2_CBOR", "M");
 | 
						|
    }
 | 
						|
    if (typeof config.retryStrategy === "function") {
 | 
						|
        const retryStrategy = await config.retryStrategy();
 | 
						|
        if (typeof retryStrategy.acquireInitialRetryToken === "function") {
 | 
						|
            if (retryStrategy.constructor?.name?.includes("Adaptive")) {
 | 
						|
                core$1.setFeature(context, "RETRY_MODE_ADAPTIVE", "F");
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                core$1.setFeature(context, "RETRY_MODE_STANDARD", "E");
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else {
 | 
						|
            core$1.setFeature(context, "RETRY_MODE_LEGACY", "D");
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if (typeof config.accountIdEndpointMode === "function") {
 | 
						|
        const endpointV2 = context.endpointV2;
 | 
						|
        if (String(endpointV2?.url?.hostname).match(ACCOUNT_ID_ENDPOINT_REGEX)) {
 | 
						|
            core$1.setFeature(context, "ACCOUNT_ID_ENDPOINT", "O");
 | 
						|
        }
 | 
						|
        switch (await config.accountIdEndpointMode?.()) {
 | 
						|
            case "disabled":
 | 
						|
                core$1.setFeature(context, "ACCOUNT_ID_MODE_DISABLED", "Q");
 | 
						|
                break;
 | 
						|
            case "preferred":
 | 
						|
                core$1.setFeature(context, "ACCOUNT_ID_MODE_PREFERRED", "P");
 | 
						|
                break;
 | 
						|
            case "required":
 | 
						|
                core$1.setFeature(context, "ACCOUNT_ID_MODE_REQUIRED", "R");
 | 
						|
                break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    const identity = context.__smithy_context?.selectedHttpAuthScheme?.identity;
 | 
						|
    if (identity?.$source) {
 | 
						|
        const credentials = identity;
 | 
						|
        if (credentials.accountId) {
 | 
						|
            core$1.setFeature(context, "RESOLVED_ACCOUNT_ID", "T");
 | 
						|
        }
 | 
						|
        for (const [key, value] of Object.entries(credentials.$source ?? {})) {
 | 
						|
            core$1.setFeature(context, key, value);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
const USER_AGENT = "user-agent";
 | 
						|
const X_AMZ_USER_AGENT = "x-amz-user-agent";
 | 
						|
const SPACE = " ";
 | 
						|
const UA_NAME_SEPARATOR = "/";
 | 
						|
const UA_NAME_ESCAPE_REGEX = /[^\!\$\%\&\'\*\+\-\.\^\_\`\|\~\d\w]/g;
 | 
						|
const UA_VALUE_ESCAPE_REGEX = /[^\!\$\%\&\'\*\+\-\.\^\_\`\|\~\d\w\#]/g;
 | 
						|
const UA_ESCAPE_CHAR = "-";
 | 
						|
 | 
						|
const BYTE_LIMIT = 1024;
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
const userAgentMiddleware = (options) => (next, context) => async (args) => {
 | 
						|
    const { request } = args;
 | 
						|
    if (!protocolHttp.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 = utilEndpoints.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}`;
 | 
						|
        }
 | 
						|
    }, "");
 | 
						|
};
 | 
						|
const getUserAgentMiddlewareOptions = {
 | 
						|
    name: "getUserAgentMiddleware",
 | 
						|
    step: "build",
 | 
						|
    priority: "low",
 | 
						|
    tags: ["SET_USER_AGENT", "USER_AGENT"],
 | 
						|
    override: true,
 | 
						|
};
 | 
						|
const getUserAgentPlugin = (config) => ({
 | 
						|
    applyToStack: (clientStack) => {
 | 
						|
        clientStack.add(userAgentMiddleware(config), getUserAgentMiddlewareOptions);
 | 
						|
    },
 | 
						|
});
 | 
						|
 | 
						|
exports.DEFAULT_UA_APP_ID = DEFAULT_UA_APP_ID;
 | 
						|
exports.getUserAgentMiddlewareOptions = getUserAgentMiddlewareOptions;
 | 
						|
exports.getUserAgentPlugin = getUserAgentPlugin;
 | 
						|
exports.resolveUserAgentConfig = resolveUserAgentConfig;
 | 
						|
exports.userAgentMiddleware = userAgentMiddleware;
 |