UNPKG

@bitblit/epsilon

Version:

Tiny adapter to simplify building API gateway Lambda APIS

197 lines (196 loc) 9.18 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.EpsilonWebsiteStack = void 0; const aws_s3_1 = require("aws-cdk-lib/aws-s3"); const aws_cdk_lib_1 = require("aws-cdk-lib"); const path_1 = __importDefault(require("path")); const aws_cloudfront_1 = require("aws-cdk-lib/aws-cloudfront"); const aws_route53_1 = require("aws-cdk-lib/aws-route53"); const aws_route53_targets_1 = require("aws-cdk-lib/aws-route53-targets"); const aws_s3_deployment_1 = require("aws-cdk-lib/aws-s3-deployment"); const epsilon_website_stack_props_1 = require("./epsilon-website-stack-props"); const string_ratchet_1 = require("@bitblit/ratchet/common/string-ratchet"); const error_ratchet_1 = require("@bitblit/ratchet/common/error-ratchet"); class EpsilonWebsiteStack extends aws_cdk_lib_1.Stack { constructor(scope, id, props) { var _a; super(scope, id, props); const originAccessId = new aws_cloudfront_1.OriginAccessIdentity(this, id + 'OriginAccessId'); const websiteBucket = new aws_s3_1.Bucket(this, id + 'DeployBucket', { bucketName: props.targetBucketName, //removalPolicy: RemovalPolicy.DESTROY, //autoDeleteObjects: true, versioned: false, publicReadAccess: false, encryption: aws_s3_1.BucketEncryption.S3_MANAGED, /* cors: [ { allowedMethods: [ HttpMethods.GET, HttpMethods.POST, HttpMethods.PUT, ], allowedOrigins: ['http://localhost:3000'], allowedHeaders: ['*'], }, ], lifecycleRules: [ { abortIncompleteMultipartUploadAfter: cdk.Duration.days(90), expiration: cdk.Duration.days(365), transitions: [ { storageClass: s3.StorageClass.INFREQUENT_ACCESS, transitionAfter: cdk.Duration.days(30), }, ], }, ], */ }); const extraBucketAndSource = (props.simpleAdditionalMappings || []).map((eb) => { const nextBucket = new aws_s3_1.Bucket(this, eb.bucketName + 'DeployBucket', { bucketName: eb.bucketName, //removalPolicy: RemovalPolicy.DESTROY, //autoDeleteObjects: true, versioned: false, publicReadAccess: false, encryption: aws_s3_1.BucketEncryption.S3_MANAGED, }); const nextBS = { bucket: nextBucket, sourceConfig: { s3OriginSource: { s3BucketSource: nextBucket, originAccessIdentity: originAccessId, }, behaviors: [ { pathPattern: eb.pathPattern, isDefaultBehavior: false, compress: true, defaultTtl: aws_cdk_lib_1.Duration.seconds(1), minTtl: aws_cdk_lib_1.Duration.seconds(1), maxTtl: aws_cdk_lib_1.Duration.seconds(1), forwardedValues: { queryString: false, }, }, ], }, }; return nextBS; }); //websiteBucket.grantReadWrite(webHandler); //websiteBucket.grantReadWrite(bgHandler); const assetSource = { s3OriginSource: { s3BucketSource: websiteBucket, originAccessIdentity: originAccessId, }, behaviors: [ { isDefaultBehavior: true, compress: true, defaultTtl: aws_cdk_lib_1.Duration.seconds(1), minTtl: aws_cdk_lib_1.Duration.seconds(1), maxTtl: aws_cdk_lib_1.Duration.seconds(1), forwardedValues: { queryString: false, }, }, ], }; //const parseUrl: URL = new URL(fnUrl.url); const apiSource = { customOriginSource: { domainName: props.apiDomainName, originProtocolPolicy: aws_cloudfront_1.OriginProtocolPolicy.HTTPS_ONLY, }, //originPath: '/', behaviors: [ { compress: true, forwardedValues: { queryString: true, cookies: { forward: 'whitelist', whitelistedNames: ['idToken'], }, headers: ['Accept', 'Referer', 'Authorization', 'Content-Type'], }, pathPattern: 'graphql', defaultTtl: aws_cdk_lib_1.Duration.seconds(0), maxTtl: aws_cdk_lib_1.Duration.seconds(0), minTtl: aws_cdk_lib_1.Duration.seconds(0), allowedMethods: aws_cloudfront_1.CloudFrontAllowedMethods.ALL, cachedMethods: aws_cloudfront_1.CloudFrontAllowedCachedMethods.GET_HEAD, }, ], }; const distributionProps = { httpVersion: aws_cloudfront_1.HttpVersion.HTTP2, defaultRootObject: 'index.html', originConfigs: [assetSource, apiSource, ...extraBucketAndSource.map((s) => s.sourceConfig)], errorConfigurations: [ { errorCode: 404, errorCachingMinTtl: 300, responseCode: 200, responsePagePath: '/index.html', }, { errorCode: 403, errorCachingMinTtl: 300, responseCode: 200, responsePagePath: '/index.html', }, ], priceClass: aws_cloudfront_1.PriceClass.PRICE_CLASS_ALL, viewerProtocolPolicy: aws_cloudfront_1.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, viewerCertificate: { aliases: props.cloudFrontDomainNames, props: { acmCertificateArn: props.cloudFrontHttpsCertificateArn, sslSupportMethod: 'sni-only', }, }, }; const cloudfrontDistro = new aws_cloudfront_1.CloudFrontWebDistribution(this, id + 'CloudfrontDistro', distributionProps); // Have to be able to skip this since SOME people don't do DNS in Route53 if ((props === null || props === void 0 ? void 0 : props.route53Handling) === epsilon_website_stack_props_1.EpsilonWebsiteStackPropsRoute53Handling.Update) { if ((_a = props === null || props === void 0 ? void 0 : props.cloudFrontDomainNames) === null || _a === void 0 ? void 0 : _a.length) { for (let i = 0; i < props.cloudFrontDomainNames.length; i++) { const domain = new aws_route53_1.RecordSet(this, id + 'DomainName-' + props.cloudFrontDomainNames[i], { recordType: aws_route53_1.RecordType.A, recordName: props.cloudFrontDomainNames[i], target: { aliasTarget: new aws_route53_targets_1.CloudFrontTarget(cloudfrontDistro), }, zone: aws_route53_1.HostedZone.fromLookup(this, id, { domainName: EpsilonWebsiteStack.extractApexDomain(props.cloudFrontDomainNames[i]) }), }); } } } // [Source.asset(path.resolve('../website/dist'))], new aws_s3_deployment_1.BucketDeployment(this, id + 'SiteDeploy', { sources: props.pathsToAssets.map((inPath) => aws_s3_deployment_1.Source.asset(path_1.default.resolve(inPath))), destinationBucket: websiteBucket, distribution: cloudfrontDistro, distributionPaths: ['/*'], //'/locales/*', '/index.html', '/manifest.webmanifest', '/service-worker.js'] }); } static extractApexDomain(domainName) { const pieces = string_ratchet_1.StringRatchet.trimToEmpty(domainName).split('.'); if (pieces.length < 2) { error_ratchet_1.ErrorRatchet.throwFormattedErr('Not a valid domain name : %s', domainName); } return pieces[pieces.length - 2] + '.' + pieces[pieces.length - 1]; } } exports.EpsilonWebsiteStack = EpsilonWebsiteStack; //# sourceMappingURL=epsilon-website-stack.js.map