UNPKG

awscdk-construct-scte-scheduler

Version:

AWS CDK Construct for scheduling SCTE-35 events using the MediaLive schedule API

376 lines (349 loc) 14.4 kB
'use strict'; var client = require('@smithy/core/client'); var endpoints = require('@smithy/core/endpoints'); class ProviderError extends Error { name = "ProviderError"; tryNextLink; constructor(message, options = true) { let logger; let tryNextLink = true; if (typeof options === "boolean") { logger = undefined; tryNextLink = options; } else if (options != null && typeof options === "object") { logger = options.logger; tryNextLink = options.tryNextLink ?? true; } super(message); this.tryNextLink = tryNextLink; Object.setPrototypeOf(this, ProviderError.prototype); logger?.debug?.(`@smithy/property-provider ${tryNextLink ? "->" : "(!)"} ${message}`); } static from(error, options = true) { return Object.assign(new this(error.message, options), error); } } class CredentialsProviderError extends ProviderError { name = "CredentialsProviderError"; constructor(message, options = true) { super(message, options); Object.setPrototypeOf(this, CredentialsProviderError.prototype); } } class TokenProviderError extends ProviderError { name = "TokenProviderError"; constructor(message, options = true) { super(message, options); Object.setPrototypeOf(this, TokenProviderError.prototype); } } const chain = (...providers) => async () => { if (providers.length === 0) { throw new ProviderError("No providers in chain"); } let lastProviderError; for (const provider of providers) { try { const credentials = await provider(); return credentials; } catch (err) { lastProviderError = err; if (err?.tryNextLink) { continue; } throw err; } } throw lastProviderError; }; const fromValue = (staticValue) => () => Promise.resolve(staticValue); const memoize = (provider, isExpired, requiresRefresh) => { let resolved; let pending; let hasResult; let isConstant = false; const coalesceProvider = async () => { if (!pending) { pending = provider(); } try { resolved = await pending; hasResult = true; isConstant = false; } finally { pending = undefined; } return resolved; }; if (isExpired === undefined) { return async (options) => { if (!hasResult || options?.forceRefresh) { resolved = await coalesceProvider(); } return resolved; }; } return async (options) => { if (!hasResult || options?.forceRefresh) { resolved = await coalesceProvider(); } if (isConstant) { return resolved; } if (requiresRefresh && !requiresRefresh(resolved)) { isConstant = true; return resolved; } if (isExpired(resolved)) { await coalesceProvider(); return resolved; } return resolved; }; }; const booleanSelector = (obj, key, type) => { if (!(key in obj)) return undefined; if (obj[key] === "true") return true; if (obj[key] === "false") return false; throw new Error(`Cannot load ${type} "${key}". Expected "true" or "false", got ${obj[key]}.`); }; const numberSelector = (obj, key, type) => { if (!(key in obj)) return undefined; const numberValue = parseInt(obj[key], 10); if (Number.isNaN(numberValue)) { throw new TypeError(`Cannot load ${type} '${key}'. Expected number, got '${obj[key]}'.`); } return numberValue; }; exports.SelectorType = void 0; (function (SelectorType) { SelectorType["ENV"] = "env"; SelectorType["CONFIG"] = "shared config entry"; })(exports.SelectorType || (exports.SelectorType = {})); const resolveCustomEndpointsConfig = (input) => { const { tls, endpoint, urlParser, useDualstackEndpoint } = input; return Object.assign(input, { tls: tls ?? true, endpoint: client.normalizeProvider(typeof endpoint === "string" ? urlParser(endpoint) : endpoint), isCustomEndpoint: true, useDualstackEndpoint: client.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 = client.normalizeProvider(input.useDualstackEndpoint ?? false); const { endpoint, useFipsEndpoint, urlParser, tls } = input; return Object.assign(input, { tls: tls ?? true, endpoint: endpoint ? client.normalizeProvider(typeof endpoint === "string" ? urlParser(endpoint) : endpoint) : () => getEndpointFromRegion({ ...input, useDualstackEndpoint, useFipsEndpoint }), isCustomEndpoint: !!endpoint, useDualstackEndpoint, }); }; const validRegions = new Set(); const checkRegion = (region, check = endpoints.isValidHostLabel) => { if (!validRegions.has(region) && !check(region)) { if (region === "*") { console.warn(`@smithy/config-resolver WARN - Please use the caller region instead of "*". See "sigv4a" in https://github.com/aws/aws-sdk-js-v3/blob/main/supplemental-docs/CLIENTS.md.`); } else { throw new Error(`Region not accepted: region="${region}" is not a valid hostname component.`); } } else { validRegions.add(region); } }; 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 () => { const providedRegion = typeof region === "function" ? await region() : region; const realRegion = getRealRegion(providedRegion); checkRegion(realRegion); return realRegion; }, 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, }), }; }; const DEFAULTS_MODE_OPTIONS = ["in-region", "cross-region", "mobile", "standard", "legacy"]; const resolveDefaultsModeConfig = ({ defaultsMode, } = {}) => memoize(async () => { const mode = typeof defaultsMode === "function" ? await defaultsMode() : defaultsMode; switch (mode?.toLowerCase()) { case "auto": return Promise.resolve(useMobileConfiguration() ? "mobile" : "standard"); case "mobile": case "in-region": case "cross-region": case "standard": case "legacy": return Promise.resolve(mode?.toLocaleLowerCase()); case undefined: return Promise.resolve("legacy"); default: throw new Error(`Invalid parameter for "defaultsMode", expect ${DEFAULTS_MODE_OPTIONS.join(", ")}, got ${mode}`); } }); const useMobileConfiguration = () => { const navigator = window?.navigator; if (navigator?.connection) { const { effectiveType, rtt, downlink } = navigator?.connection; const slow = (typeof effectiveType === "string" && effectiveType !== "4g") || Number(rtt) > 100 || Number(downlink) < 10; if (slow) { return true; } } return (navigator?.userAgentData?.mobile || (typeof navigator?.maxTouchPoints === "number" && navigator?.maxTouchPoints > 1)); }; const no = Symbol.for("node-only"); const getHomeDir = no; const ENV_PROFILE = no; const DEFAULT_PROFILE = "default"; const getProfileName = no; const getSSOTokenFilepath = no; const getSSOTokenFromFile = no; const CONFIG_PREFIX_SEPARATOR = no; const loadSharedConfigFiles = no; const loadSsoSessionData = no; const parseKnownFiles = no; const externalDataInterceptor = no; const readFile = no; const loadConfig = no; const fromStatic = no; const ENV_USE_DUALSTACK_ENDPOINT = no; const CONFIG_USE_DUALSTACK_ENDPOINT = no; const DEFAULT_USE_DUALSTACK_ENDPOINT = false; const NODE_USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS = no; const nodeDualstackConfigSelectors = no; const ENV_USE_FIPS_ENDPOINT = no; const CONFIG_USE_FIPS_ENDPOINT = no; const DEFAULT_USE_FIPS_ENDPOINT = false; const NODE_USE_FIPS_ENDPOINT_CONFIG_OPTIONS = no; const nodeFipsConfigSelectors = no; const REGION_ENV_NAME = no; const REGION_INI_NAME = no; const NODE_REGION_CONFIG_OPTIONS = no; const NODE_REGION_CONFIG_FILE_OPTIONS = no; exports.CONFIG_PREFIX_SEPARATOR = CONFIG_PREFIX_SEPARATOR; exports.CONFIG_USE_DUALSTACK_ENDPOINT = CONFIG_USE_DUALSTACK_ENDPOINT; exports.CONFIG_USE_FIPS_ENDPOINT = CONFIG_USE_FIPS_ENDPOINT; exports.CredentialsProviderError = CredentialsProviderError; exports.DEFAULT_PROFILE = DEFAULT_PROFILE; exports.DEFAULT_USE_DUALSTACK_ENDPOINT = DEFAULT_USE_DUALSTACK_ENDPOINT; exports.DEFAULT_USE_FIPS_ENDPOINT = DEFAULT_USE_FIPS_ENDPOINT; exports.ENV_PROFILE = ENV_PROFILE; 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.ProviderError = ProviderError; exports.REGION_ENV_NAME = REGION_ENV_NAME; exports.REGION_INI_NAME = REGION_INI_NAME; exports.TokenProviderError = TokenProviderError; exports.booleanSelector = booleanSelector; exports.chain = chain; exports.externalDataInterceptor = externalDataInterceptor; exports.fromStatic = fromStatic; exports.fromValue = fromValue; exports.getHomeDir = getHomeDir; exports.getProfileName = getProfileName; exports.getRegionInfo = getRegionInfo; exports.getSSOTokenFilepath = getSSOTokenFilepath; exports.getSSOTokenFromFile = getSSOTokenFromFile; exports.loadConfig = loadConfig; exports.loadSharedConfigFiles = loadSharedConfigFiles; exports.loadSsoSessionData = loadSsoSessionData; exports.memoize = memoize; exports.nodeDualstackConfigSelectors = nodeDualstackConfigSelectors; exports.nodeFipsConfigSelectors = nodeFipsConfigSelectors; exports.numberSelector = numberSelector; exports.parseKnownFiles = parseKnownFiles; exports.readFile = readFile; exports.resolveCustomEndpointsConfig = resolveCustomEndpointsConfig; exports.resolveDefaultsModeConfig = resolveDefaultsModeConfig; exports.resolveEndpointsConfig = resolveEndpointsConfig; exports.resolveRegionConfig = resolveRegionConfig;