172 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						|
 | 
						|
var utilConfigProvider = require('@smithy/util-config-provider');
 | 
						|
var utilMiddleware = require('@smithy/util-middleware');
 | 
						|
 | 
						|
const ENV_USE_DUALSTACK_ENDPOINT = "AWS_USE_DUALSTACK_ENDPOINT";
 | 
						|
const CONFIG_USE_DUALSTACK_ENDPOINT = "use_dualstack_endpoint";
 | 
						|
const DEFAULT_USE_DUALSTACK_ENDPOINT = false;
 | 
						|
const NODE_USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS = {
 | 
						|
    environmentVariableSelector: (env) => utilConfigProvider.booleanSelector(env, ENV_USE_DUALSTACK_ENDPOINT, utilConfigProvider.SelectorType.ENV),
 | 
						|
    configFileSelector: (profile) => utilConfigProvider.booleanSelector(profile, CONFIG_USE_DUALSTACK_ENDPOINT, utilConfigProvider.SelectorType.CONFIG),
 | 
						|
    default: false,
 | 
						|
};
 | 
						|
 | 
						|
const ENV_USE_FIPS_ENDPOINT = "AWS_USE_FIPS_ENDPOINT";
 | 
						|
const CONFIG_USE_FIPS_ENDPOINT = "use_fips_endpoint";
 | 
						|
const DEFAULT_USE_FIPS_ENDPOINT = false;
 | 
						|
const NODE_USE_FIPS_ENDPOINT_CONFIG_OPTIONS = {
 | 
						|
    environmentVariableSelector: (env) => utilConfigProvider.booleanSelector(env, ENV_USE_FIPS_ENDPOINT, utilConfigProvider.SelectorType.ENV),
 | 
						|
    configFileSelector: (profile) => utilConfigProvider.booleanSelector(profile, CONFIG_USE_FIPS_ENDPOINT, utilConfigProvider.SelectorType.CONFIG),
 | 
						|
    default: false,
 | 
						|
};
 | 
						|
 | 
						|
const resolveCustomEndpointsConfig = (input) => {
 | 
						|
    const { tls, endpoint, urlParser, useDualstackEndpoint } = input;
 | 
						|
    return Object.assign(input, {
 | 
						|
        tls: tls ?? true,
 | 
						|
        endpoint: utilMiddleware.normalizeProvider(typeof endpoint === "string" ? urlParser(endpoint) : endpoint),
 | 
						|
        isCustomEndpoint: true,
 | 
						|
        useDualstackEndpoint: utilMiddleware.normalizeProvider(useDualstackEndpoint ?? false),
 | 
						|
    });
 | 
						|
};
 | 
						|
 | 
						|
const getEndpointFromRegion = async (input) => {
 | 
						|
    const { tls = true } = input;
 | 
						|
    const region = await input.region();
 | 
						|
    const dnsHostRegex = new RegExp(/^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])$/);
 | 
						|
    if (!dnsHostRegex.test(region)) {
 | 
						|
        throw new Error("Invalid region in client config");
 | 
						|
    }
 | 
						|
    const useDualstackEndpoint = await input.useDualstackEndpoint();
 | 
						|
    const useFipsEndpoint = await input.useFipsEndpoint();
 | 
						|
    const { hostname } = (await input.regionInfoProvider(region, { useDualstackEndpoint, useFipsEndpoint })) ?? {};
 | 
						|
    if (!hostname) {
 | 
						|
        throw new Error("Cannot resolve hostname from client config");
 | 
						|
    }
 | 
						|
    return input.urlParser(`${tls ? "https:" : "http:"}//${hostname}`);
 | 
						|
};
 | 
						|
 | 
						|
const resolveEndpointsConfig = (input) => {
 | 
						|
    const useDualstackEndpoint = utilMiddleware.normalizeProvider(input.useDualstackEndpoint ?? false);
 | 
						|
    const { endpoint, useFipsEndpoint, urlParser, tls } = input;
 | 
						|
    return Object.assign(input, {
 | 
						|
        tls: tls ?? true,
 | 
						|
        endpoint: endpoint
 | 
						|
            ? utilMiddleware.normalizeProvider(typeof endpoint === "string" ? urlParser(endpoint) : endpoint)
 | 
						|
            : () => getEndpointFromRegion({ ...input, useDualstackEndpoint, useFipsEndpoint }),
 | 
						|
        isCustomEndpoint: !!endpoint,
 | 
						|
        useDualstackEndpoint,
 | 
						|
    });
 | 
						|
};
 | 
						|
 | 
						|
const REGION_ENV_NAME = "AWS_REGION";
 | 
						|
const REGION_INI_NAME = "region";
 | 
						|
const NODE_REGION_CONFIG_OPTIONS = {
 | 
						|
    environmentVariableSelector: (env) => env[REGION_ENV_NAME],
 | 
						|
    configFileSelector: (profile) => profile[REGION_INI_NAME],
 | 
						|
    default: () => {
 | 
						|
        throw new Error("Region is missing");
 | 
						|
    },
 | 
						|
};
 | 
						|
const NODE_REGION_CONFIG_FILE_OPTIONS = {
 | 
						|
    preferredFile: "credentials",
 | 
						|
};
 | 
						|
 | 
						|
const isFipsRegion = (region) => typeof region === "string" && (region.startsWith("fips-") || region.endsWith("-fips"));
 | 
						|
 | 
						|
const getRealRegion = (region) => isFipsRegion(region)
 | 
						|
    ? ["fips-aws-global", "aws-fips"].includes(region)
 | 
						|
        ? "us-east-1"
 | 
						|
        : region.replace(/fips-(dkr-|prod-)?|-fips/, "")
 | 
						|
    : region;
 | 
						|
 | 
						|
const resolveRegionConfig = (input) => {
 | 
						|
    const { region, useFipsEndpoint } = input;
 | 
						|
    if (!region) {
 | 
						|
        throw new Error("Region is missing");
 | 
						|
    }
 | 
						|
    return Object.assign(input, {
 | 
						|
        region: async () => {
 | 
						|
            if (typeof region === "string") {
 | 
						|
                return getRealRegion(region);
 | 
						|
            }
 | 
						|
            const providedRegion = await region();
 | 
						|
            return getRealRegion(providedRegion);
 | 
						|
        },
 | 
						|
        useFipsEndpoint: async () => {
 | 
						|
            const providedRegion = typeof region === "string" ? region : await region();
 | 
						|
            if (isFipsRegion(providedRegion)) {
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
            return typeof useFipsEndpoint !== "function" ? Promise.resolve(!!useFipsEndpoint) : useFipsEndpoint();
 | 
						|
        },
 | 
						|
    });
 | 
						|
};
 | 
						|
 | 
						|
const getHostnameFromVariants = (variants = [], { useFipsEndpoint, useDualstackEndpoint }) => variants.find(({ tags }) => useFipsEndpoint === tags.includes("fips") && useDualstackEndpoint === tags.includes("dualstack"))?.hostname;
 | 
						|
 | 
						|
const getResolvedHostname = (resolvedRegion, { regionHostname, partitionHostname }) => regionHostname
 | 
						|
    ? regionHostname
 | 
						|
    : partitionHostname
 | 
						|
        ? partitionHostname.replace("{region}", resolvedRegion)
 | 
						|
        : undefined;
 | 
						|
 | 
						|
const getResolvedPartition = (region, { partitionHash }) => Object.keys(partitionHash || {}).find((key) => partitionHash[key].regions.includes(region)) ?? "aws";
 | 
						|
 | 
						|
const getResolvedSigningRegion = (hostname, { signingRegion, regionRegex, useFipsEndpoint }) => {
 | 
						|
    if (signingRegion) {
 | 
						|
        return signingRegion;
 | 
						|
    }
 | 
						|
    else if (useFipsEndpoint) {
 | 
						|
        const regionRegexJs = regionRegex.replace("\\\\", "\\").replace(/^\^/g, "\\.").replace(/\$$/g, "\\.");
 | 
						|
        const regionRegexmatchArray = hostname.match(regionRegexJs);
 | 
						|
        if (regionRegexmatchArray) {
 | 
						|
            return regionRegexmatchArray[0].slice(1, -1);
 | 
						|
        }
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
const getRegionInfo = (region, { useFipsEndpoint = false, useDualstackEndpoint = false, signingService, regionHash, partitionHash, }) => {
 | 
						|
    const partition = getResolvedPartition(region, { partitionHash });
 | 
						|
    const resolvedRegion = region in regionHash ? region : partitionHash[partition]?.endpoint ?? region;
 | 
						|
    const hostnameOptions = { useFipsEndpoint, useDualstackEndpoint };
 | 
						|
    const regionHostname = getHostnameFromVariants(regionHash[resolvedRegion]?.variants, hostnameOptions);
 | 
						|
    const partitionHostname = getHostnameFromVariants(partitionHash[partition]?.variants, hostnameOptions);
 | 
						|
    const hostname = getResolvedHostname(resolvedRegion, { regionHostname, partitionHostname });
 | 
						|
    if (hostname === undefined) {
 | 
						|
        throw new Error(`Endpoint resolution failed for: ${{ resolvedRegion, useFipsEndpoint, useDualstackEndpoint }}`);
 | 
						|
    }
 | 
						|
    const signingRegion = getResolvedSigningRegion(hostname, {
 | 
						|
        signingRegion: regionHash[resolvedRegion]?.signingRegion,
 | 
						|
        regionRegex: partitionHash[partition].regionRegex,
 | 
						|
        useFipsEndpoint,
 | 
						|
    });
 | 
						|
    return {
 | 
						|
        partition,
 | 
						|
        signingService,
 | 
						|
        hostname,
 | 
						|
        ...(signingRegion && { signingRegion }),
 | 
						|
        ...(regionHash[resolvedRegion]?.signingService && {
 | 
						|
            signingService: regionHash[resolvedRegion].signingService,
 | 
						|
        }),
 | 
						|
    };
 | 
						|
};
 | 
						|
 | 
						|
exports.CONFIG_USE_DUALSTACK_ENDPOINT = CONFIG_USE_DUALSTACK_ENDPOINT;
 | 
						|
exports.CONFIG_USE_FIPS_ENDPOINT = CONFIG_USE_FIPS_ENDPOINT;
 | 
						|
exports.DEFAULT_USE_DUALSTACK_ENDPOINT = DEFAULT_USE_DUALSTACK_ENDPOINT;
 | 
						|
exports.DEFAULT_USE_FIPS_ENDPOINT = DEFAULT_USE_FIPS_ENDPOINT;
 | 
						|
exports.ENV_USE_DUALSTACK_ENDPOINT = ENV_USE_DUALSTACK_ENDPOINT;
 | 
						|
exports.ENV_USE_FIPS_ENDPOINT = ENV_USE_FIPS_ENDPOINT;
 | 
						|
exports.NODE_REGION_CONFIG_FILE_OPTIONS = NODE_REGION_CONFIG_FILE_OPTIONS;
 | 
						|
exports.NODE_REGION_CONFIG_OPTIONS = NODE_REGION_CONFIG_OPTIONS;
 | 
						|
exports.NODE_USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS = NODE_USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS;
 | 
						|
exports.NODE_USE_FIPS_ENDPOINT_CONFIG_OPTIONS = NODE_USE_FIPS_ENDPOINT_CONFIG_OPTIONS;
 | 
						|
exports.REGION_ENV_NAME = REGION_ENV_NAME;
 | 
						|
exports.REGION_INI_NAME = REGION_INI_NAME;
 | 
						|
exports.getRegionInfo = getRegionInfo;
 | 
						|
exports.resolveCustomEndpointsConfig = resolveCustomEndpointsConfig;
 | 
						|
exports.resolveEndpointsConfig = resolveEndpointsConfig;
 | 
						|
exports.resolveRegionConfig = resolveRegionConfig;
 |