import { getUserAgentPrefix } from "@aws-sdk/util-endpoints"; import { HttpRequest } from "@smithy/protocol-http"; import { SPACE, UA_ESCAPE_CHAR, UA_NAME_ESCAPE_REGEX, UA_NAME_SEPARATOR, UA_VALUE_ESCAPE_REGEX, USER_AGENT, X_AMZ_USER_AGENT, } from "./constants"; 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); const customUserAgent = options?.customUserAgent?.map(escapeUserAgent) || []; 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); }, });