UNPKG

open-next-cdk

Version:

Deploy a NextJS app using OpenNext packaging to serverless AWS using CDK

154 lines (153 loc) 7.43 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.validateMrapAlias = exports.validateNoFIPS = exports.validateNoDualstack = exports.getArnResources = exports.validateCustomEndpoint = exports.validateDNSHostLabel = exports.validateAccountId = exports.validateRegionalClient = exports.validateRegion = exports.validatePartition = exports.validateOutpostService = exports.validateS3Service = exports.validateService = exports.validateArnEndpointOptions = exports.getSuffixForArnEndpoint = exports.getSuffix = exports.isDnsCompatibleBucketName = exports.isBucketNameOptions = exports.S3_HOSTNAME_PATTERN = exports.DOT_PATTERN = void 0; const DOMAIN_PATTERN = /^[a-z0-9][a-z0-9\.\-]{1,61}[a-z0-9]$/; const IP_ADDRESS_PATTERN = /(\d+\.){3}\d+/; const DOTS_PATTERN = /\.\./; exports.DOT_PATTERN = /\./; exports.S3_HOSTNAME_PATTERN = /^(.+\.)?s3(-fips)?(\.dualstack)?[.-]([a-z0-9-]+)\./; const S3_US_EAST_1_ALTNAME_PATTERN = /^s3(-external-1)?\.amazonaws\.com$/; const AWS_PARTITION_SUFFIX = "amazonaws.com"; const isBucketNameOptions = (options) => typeof options.bucketName === "string"; exports.isBucketNameOptions = isBucketNameOptions; const isDnsCompatibleBucketName = (bucketName) => DOMAIN_PATTERN.test(bucketName) && !IP_ADDRESS_PATTERN.test(bucketName) && !DOTS_PATTERN.test(bucketName); exports.isDnsCompatibleBucketName = isDnsCompatibleBucketName; const getRegionalSuffix = (hostname) => { const parts = hostname.match(exports.S3_HOSTNAME_PATTERN); return [parts[4], hostname.replace(new RegExp(`^${parts[0]}`), "")]; }; const getSuffix = (hostname) => S3_US_EAST_1_ALTNAME_PATTERN.test(hostname) ? ["us-east-1", AWS_PARTITION_SUFFIX] : getRegionalSuffix(hostname); exports.getSuffix = getSuffix; const getSuffixForArnEndpoint = (hostname) => S3_US_EAST_1_ALTNAME_PATTERN.test(hostname) ? [hostname.replace(`.${AWS_PARTITION_SUFFIX}`, ""), AWS_PARTITION_SUFFIX] : getRegionalSuffix(hostname); exports.getSuffixForArnEndpoint = getSuffixForArnEndpoint; const validateArnEndpointOptions = (options) => { if (options.pathStyleEndpoint) { throw new Error("Path-style S3 endpoint is not supported when bucket is an ARN"); } if (options.accelerateEndpoint) { throw new Error("Accelerate endpoint is not supported when bucket is an ARN"); } if (!options.tlsCompatible) { throw new Error("HTTPS is required when bucket is an ARN"); } }; exports.validateArnEndpointOptions = validateArnEndpointOptions; const validateService = (service) => { if (service !== "s3" && service !== "s3-outposts" && service !== "s3-object-lambda") { throw new Error("Expect 's3' or 's3-outposts' or 's3-object-lambda' in ARN service component"); } }; exports.validateService = validateService; const validateS3Service = (service) => { if (service !== "s3") { throw new Error("Expect 's3' in Accesspoint ARN service component"); } }; exports.validateS3Service = validateS3Service; const validateOutpostService = (service) => { if (service !== "s3-outposts") { throw new Error("Expect 's3-posts' in Outpost ARN service component"); } }; exports.validateOutpostService = validateOutpostService; const validatePartition = (partition, options) => { if (partition !== options.clientPartition) { throw new Error(`Partition in ARN is incompatible, got "${partition}" but expected "${options.clientPartition}"`); } }; exports.validatePartition = validatePartition; const validateRegion = (region, options) => { if (region === "") { throw new Error("ARN region is empty"); } if (options.useFipsEndpoint) { if (!options.allowFipsRegion) { throw new Error("FIPS region is not supported"); } else if (!isEqualRegions(region, options.clientRegion)) { throw new Error(`Client FIPS region ${options.clientRegion} doesn't match region ${region} in ARN`); } } if (!options.useArnRegion && !isEqualRegions(region, options.clientRegion || "") && !isEqualRegions(region, options.clientSigningRegion || "")) { throw new Error(`Region in ARN is incompatible, got ${region} but expected ${options.clientRegion}`); } }; exports.validateRegion = validateRegion; const validateRegionalClient = (region) => { if (["s3-external-1", "aws-global"].includes(region)) { throw new Error(`Client region ${region} is not regional`); } }; exports.validateRegionalClient = validateRegionalClient; const isEqualRegions = (regionA, regionB) => regionA === regionB; const validateAccountId = (accountId) => { if (!/[0-9]{12}/.exec(accountId)) { throw new Error("Access point ARN accountID does not match regex '[0-9]{12}'"); } }; exports.validateAccountId = validateAccountId; const validateDNSHostLabel = (label, options = { tlsCompatible: true }) => { if (label.length >= 64 || !/^[a-z0-9][a-z0-9.-]*[a-z0-9]$/.test(label) || /(\d+\.){3}\d+/.test(label) || /[.-]{2}/.test(label) || ((options === null || options === void 0 ? void 0 : options.tlsCompatible) && exports.DOT_PATTERN.test(label))) { throw new Error(`Invalid DNS label ${label}`); } }; exports.validateDNSHostLabel = validateDNSHostLabel; const validateCustomEndpoint = (options) => { if (options.isCustomEndpoint) { if (options.dualstackEndpoint) throw new Error("Dualstack endpoint is not supported with custom endpoint"); if (options.accelerateEndpoint) throw new Error("Accelerate endpoint is not supported with custom endpoint"); } }; exports.validateCustomEndpoint = validateCustomEndpoint; const getArnResources = (resource) => { const delimiter = resource.includes(":") ? ":" : "/"; const [resourceType, ...rest] = resource.split(delimiter); if (resourceType === "accesspoint") { if (rest.length !== 1 || rest[0] === "") { throw new Error(`Access Point ARN should have one resource accesspoint${delimiter}{accesspointname}`); } return { accesspointName: rest[0] }; } else if (resourceType === "outpost") { if (!rest[0] || rest[1] !== "accesspoint" || !rest[2] || rest.length !== 3) { throw new Error(`Outpost ARN should have resource outpost${delimiter}{outpostId}${delimiter}accesspoint${delimiter}{accesspointName}`); } const [outpostId, _, accesspointName] = rest; return { outpostId, accesspointName }; } else { throw new Error(`ARN resource should begin with 'accesspoint${delimiter}' or 'outpost${delimiter}'`); } }; exports.getArnResources = getArnResources; const validateNoDualstack = (dualstackEndpoint) => { if (dualstackEndpoint) throw new Error("Dualstack endpoint is not supported with Outpost or Multi-region Access Point ARN."); }; exports.validateNoDualstack = validateNoDualstack; const validateNoFIPS = (useFipsEndpoint) => { if (useFipsEndpoint) throw new Error(`FIPS region is not supported with Outpost.`); }; exports.validateNoFIPS = validateNoFIPS; const validateMrapAlias = (name) => { try { name.split(".").forEach((label) => { (0, exports.validateDNSHostLabel)(label); }); } catch (e) { throw new Error(`"${name}" is not a DNS compatible name.`); } }; exports.validateMrapAlias = validateMrapAlias;