@inizioevoke/evosynth 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +12 -0
- package/dist/constructs/certificatemanager.d.ts +12 -0
- package/dist/constructs/certificatemanager.js +19 -0
- package/dist/constructs/cloudfront.d.ts +55 -0
- package/dist/constructs/cloudfront.js +84 -0
- package/dist/constructs/codebuild.d.ts +31 -0
- package/dist/constructs/codebuild.js +95 -0
- package/dist/constructs/codepipeline.d.ts +30 -0
- package/dist/constructs/codepipeline.js +63 -0
- package/dist/constructs/route53.d.ts +14 -0
- package/dist/constructs/route53.js +24 -0
- package/dist/constructs/s3.d.ts +11 -0
- package/dist/constructs/s3.js +17 -0
- package/dist/constructs/ssm.d.ts +9 -0
- package/dist/constructs/ssm.js +17 -0
- package/dist/constructs/waf.d.ts +21 -0
- package/dist/constructs/waf.js +89 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +26 -0
- package/dist/lib/const.d.ts +1 -0
- package/dist/lib/const.js +2 -0
- package/dist/lib/csv-redirects.d.ts +3 -0
- package/dist/lib/csv-redirects.js +124 -0
- package/dist/lib/tags.d.ts +19 -0
- package/dist/lib/tags.js +47 -0
- package/dist/lib/types.d.ts +14 -0
- package/dist/lib/types.js +2 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +7 -0
- package/dist/lib/version.d.ts +1 -0
- package/dist/lib/version.js +5 -0
- package/dist/stacks/web-static-serverless/codepipeline-stack.d.ts +17 -0
- package/dist/stacks/web-static-serverless/codepipeline-stack.js +28 -0
- package/dist/stacks/web-static-serverless/web-global-stack.d.ts +43 -0
- package/dist/stacks/web-static-serverless/web-global-stack.js +142 -0
- package/dist/stages/str8r-clm-stage.d.ts +17 -0
- package/dist/stages/str8r-clm-stage.js +41 -0
- package/dist/stages/web-static-serverless-stage.d.ts +19 -0
- package/dist/stages/web-static-serverless-stage.js +51 -0
- package/dist/templates/cffn-default-doc-basic-auth.js +155 -0
- package/dist/templates/cffn-default-doc.js +132 -0
- package/inizioevoke-evosynth.code-workspace +8 -0
- package/package.json +24 -0
- package/readme.md +114 -0
- package/samples/app.ts +103 -0
- package/samples/codebuild/buildspec.yml +24 -0
- package/samples/config/redirects.csv +6 -0
- package/src/constructs/certificatemanager.ts +28 -0
- package/src/constructs/cloudfront.ts +148 -0
- package/src/constructs/codebuild.ts +124 -0
- package/src/constructs/codepipeline.ts +93 -0
- package/src/constructs/route53.ts +34 -0
- package/src/constructs/s3.ts +25 -0
- package/src/constructs/ssm.ts +24 -0
- package/src/constructs/waf.ts +118 -0
- package/src/index.ts +35 -0
- package/src/lib/const.ts +1 -0
- package/src/lib/csv-redirects.ts +139 -0
- package/src/lib/tags.ts +55 -0
- package/src/lib/types.ts +17 -0
- package/src/lib/utils.ts +7 -0
- package/src/lib/version.ts +6 -0
- package/src/stacks/web-static-serverless/codepipeline-stack.ts +42 -0
- package/src/stacks/web-static-serverless/web-global-stack.ts +184 -0
- package/src/stages/str8r-clm-stage.ts +57 -0
- package/src/stages/web-static-serverless-stage.ts +69 -0
- package/src/templates/cffn-default-doc-basic-auth.js +155 -0
- package/src/templates/cffn-default-doc.js +132 -0
- package/tasks/clean.js +7 -0
- package/tasks/copy-templates.js +13 -0
- package/tsconfig.json +32 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { Stack, PhysicalName } from 'aws-cdk-lib/core';
|
|
2
|
+
import { FunctionEventType, ResponseHeadersPolicy } from 'aws-cdk-lib/aws-cloudfront';
|
|
3
|
+
import { StringParameter } from 'aws-cdk-lib/aws-ssm';
|
|
4
|
+
import { SSLCertificate } from '../../constructs/certificatemanager.js';
|
|
5
|
+
import { CloudFrontFunction, CloudFrontDistribution } from '../../constructs/cloudfront.js';
|
|
6
|
+
import { getHostedZone, CloudFrontAlias } from '../../constructs/route53.js';
|
|
7
|
+
import { S3Bucket } from '../../constructs/s3.js';
|
|
8
|
+
import { CloudFrontWebAcl } from '../../constructs/waf.js';
|
|
9
|
+
import { domainAsId } from '../../lib/utils.js';
|
|
10
|
+
import { addEvoStackTags } from "../../lib/tags.js";
|
|
11
|
+
import { S3BucketOrigin } from 'aws-cdk-lib/aws-cloudfront-origins';
|
|
12
|
+
export class WebGlobalStack extends Stack {
|
|
13
|
+
sslCertificate;
|
|
14
|
+
s3Bucket;
|
|
15
|
+
cloudFrontFunction;
|
|
16
|
+
cloudFrontDistribution;
|
|
17
|
+
webAcl;
|
|
18
|
+
responseHeadersPolicy;
|
|
19
|
+
aRecord;
|
|
20
|
+
aaaaRecord;
|
|
21
|
+
constructor(scope, id, props) {
|
|
22
|
+
super(scope, id, props);
|
|
23
|
+
addEvoStackTags(this, 'WebGlobalStack');
|
|
24
|
+
const hostedZone = getHostedZone(this, 'getHostedZone', props.hostedZone);
|
|
25
|
+
const _sslCert = new SSLCertificate(this, 'SSLCertificate', {
|
|
26
|
+
hostedZone: hostedZone,
|
|
27
|
+
domainName: props.domainName,
|
|
28
|
+
destroy: props.destroy
|
|
29
|
+
});
|
|
30
|
+
this.sslCertificate = _sslCert.certificate;
|
|
31
|
+
const _s3Bucket = new S3Bucket(this, 'S3Bucket', {
|
|
32
|
+
bucketName: props.bucketName ?? PhysicalName.GENERATE_IF_NEEDED,
|
|
33
|
+
destroy: props.destroy
|
|
34
|
+
});
|
|
35
|
+
this.s3Bucket = _s3Bucket.bucket;
|
|
36
|
+
let responseHeadersPolicy = undefined;
|
|
37
|
+
if (props.responseHeadersPolicy) {
|
|
38
|
+
if (typeof props.responseHeadersPolicy == 'string') {
|
|
39
|
+
if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(props.responseHeadersPolicy)) {
|
|
40
|
+
responseHeadersPolicy = ResponseHeadersPolicy.fromResponseHeadersPolicyId(this, 'response-headers-policy-by-id', props.responseHeadersPolicy);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
responseHeadersPolicy = ResponseHeadersPolicy[props.responseHeadersPolicy] ?? ResponseHeadersPolicy.SECURITY_HEADERS;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else if (props.responseHeadersPolicy.path) {
|
|
47
|
+
responseHeadersPolicy = ResponseHeadersPolicy.fromResponseHeadersPolicyId(this, 'response-headers-policy-by-id', StringParameter.valueForStringParameter(this, props.responseHeadersPolicy.path, props.responseHeadersPolicy.version));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (!responseHeadersPolicy && props.responseHeadersPolicyProps) {
|
|
51
|
+
responseHeadersPolicy = new ResponseHeadersPolicy(this, 'response-headers-policy', {
|
|
52
|
+
...props.responseHeadersPolicyProps,
|
|
53
|
+
responseHeadersPolicyName: props.responseHeadersPolicyProps.responseHeadersPolicyName || `${domainAsId(props.domainName)}-response-headers-policy`
|
|
54
|
+
});
|
|
55
|
+
this.responseHeadersPolicy = responseHeadersPolicy;
|
|
56
|
+
}
|
|
57
|
+
const defaultBehavior = {
|
|
58
|
+
origin: S3BucketOrigin.withOriginAccessControl(this.s3Bucket),
|
|
59
|
+
functionAssociations: [],
|
|
60
|
+
responseHeadersPolicy: responseHeadersPolicy ?? props.responseHeadersPolicy !== false ? ResponseHeadersPolicy.SECURITY_HEADERS : undefined
|
|
61
|
+
};
|
|
62
|
+
let cffn;
|
|
63
|
+
if (props.basicAuth) {
|
|
64
|
+
if (typeof props.basicAuth != 'string') {
|
|
65
|
+
if (props.basicAuth.user && props.basicAuth.password) {
|
|
66
|
+
props.basicAuth = Buffer.from(`${props.basicAuth.user}:${props.basicAuth.password}`).toString('base64');
|
|
67
|
+
}
|
|
68
|
+
else if (props.basicAuth.path) {
|
|
69
|
+
props.basicAuth = StringParameter.valueForStringParameter(this, props.basicAuth.path, props.basicAuth.version);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
props.basicAuth = undefined;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (props.viewerRequestResponse) {
|
|
77
|
+
cffn = CloudFrontFunction.createViewerRequestResponseFunction(this, null, {
|
|
78
|
+
credentials: props.basicAuth,
|
|
79
|
+
redirects: props.redirects,
|
|
80
|
+
redirectsCsvPath: props.redirectsCsvPath,
|
|
81
|
+
code: props.viewerRequestResponse,
|
|
82
|
+
destroy: props.destroy
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
else if (props.basicAuth) {
|
|
86
|
+
cffn = CloudFrontFunction.createBasicAuthDefaultDoc(this, {
|
|
87
|
+
credentials: props.basicAuth,
|
|
88
|
+
redirects: props.redirects,
|
|
89
|
+
redirectsCsvPath: props.redirectsCsvPath,
|
|
90
|
+
destroy: props.destroy
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
cffn = CloudFrontFunction.createDefaultDoc(this, {
|
|
95
|
+
redirects: props.redirects,
|
|
96
|
+
redirectsCsvPath: props.redirectsCsvPath,
|
|
97
|
+
destroy: props.destroy
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
this.cloudFrontFunction = cffn.fn;
|
|
101
|
+
defaultBehavior.functionAssociations.push({
|
|
102
|
+
eventType: FunctionEventType.VIEWER_REQUEST,
|
|
103
|
+
function: this.cloudFrontFunction
|
|
104
|
+
});
|
|
105
|
+
defaultBehavior.functionAssociations.push({
|
|
106
|
+
eventType: FunctionEventType.VIEWER_RESPONSE,
|
|
107
|
+
function: this.cloudFrontFunction
|
|
108
|
+
});
|
|
109
|
+
let webAclId = undefined;
|
|
110
|
+
if (typeof props.webAcl == 'string' && props.webAcl.startsWith('arn:aws')) {
|
|
111
|
+
webAclId = props.webAcl;
|
|
112
|
+
}
|
|
113
|
+
else if (props.webAcl.path) {
|
|
114
|
+
webAclId = StringParameter.valueForStringParameter(this, props.webAcl.path, props.webAcl.version);
|
|
115
|
+
}
|
|
116
|
+
else if (props.webAcl === true) {
|
|
117
|
+
const waf = new CloudFrontWebAcl(this, 'CloudFrontWebAcl', {
|
|
118
|
+
name: `${domainAsId(props.domainName)}`,
|
|
119
|
+
destroy: props.destroy
|
|
120
|
+
});
|
|
121
|
+
this.webAcl = waf.acl;
|
|
122
|
+
webAclId = waf.acl.attrArn;
|
|
123
|
+
}
|
|
124
|
+
const cfDistribution = new CloudFrontDistribution(this, 'CloudFrontDistribution', {
|
|
125
|
+
domainName: props.domainName,
|
|
126
|
+
description: props.description ?? props.domainName,
|
|
127
|
+
priceClass: props.envType,
|
|
128
|
+
certificate: this.sslCertificate,
|
|
129
|
+
defaultBehavior,
|
|
130
|
+
webAclId
|
|
131
|
+
});
|
|
132
|
+
this.cloudFrontDistribution = cfDistribution.distribution;
|
|
133
|
+
const cfAlias = new CloudFrontAlias(this, 'CloudFrontAlias', {
|
|
134
|
+
distribution: cfDistribution.distribution,
|
|
135
|
+
domainName: props.domainName,
|
|
136
|
+
hostedZone: hostedZone
|
|
137
|
+
});
|
|
138
|
+
this.aRecord = cfAlias.aRecord;
|
|
139
|
+
this.aaaaRecord = cfAlias.aaaaRecord;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViLWdsb2JhbC1zdGFjay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zdGFja3Mvd2ViLXN0YXRpYy1zZXJ2ZXJsZXNzL3dlYi1nbG9iYWwtc3RhY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBYyxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUluRSxPQUFPLEVBQTBCLGlCQUFpQixFQUF1RSxxQkFBcUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBR25MLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUd0RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDeEUsT0FBTyxFQUErQixrQkFBa0IsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3pILE9BQU8sRUFBRSxhQUFhLEVBQUUsZUFBZSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDN0UsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2xELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzNELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBaUNwRSxNQUFNLE9BQU8sY0FBZSxTQUFRLEtBQUs7SUFDdkIsY0FBYyxDQUFjO0lBQzVCLFFBQVEsQ0FBUztJQUNqQixrQkFBa0IsQ0FBVztJQUM3QixzQkFBc0IsQ0FBZTtJQUNyQyxNQUFNLENBQXdCO0lBQzlCLHFCQUFxQixDQUFxQztJQUMxRCxPQUFPLENBQVU7SUFDakIsVUFBVSxDQUFhO0lBRXZDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBdUM7UUFDL0UsS0FBSyxD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L0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDO0lBQ3ZDLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFN0YWNrLCBTdGFja1Byb3BzLCBQaHlzaWNhbE5hbWUgfSBmcm9tICdhd3MtY2RrLWxpYi9jb3JlJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuXG5pbXBvcnQgeyBDZXJ0aWZpY2F0ZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2VydGlmaWNhdGVtYW5hZ2VyXCI7XG5pbXBvcnQgeyBEaXN0cmlidXRpb24sIEZ1bmN0aW9uLCBGdW5jdGlvbkV2ZW50VHlwZSwgSVJlc3BvbnNlSGVhZGVyc1BvbGljeSwgUmVzcG9uc2VIZWFkZXJzUG9saWN5UHJvcHMsIEJlaGF2aW9yT3B0aW9ucywgUmVzcG9uc2VIZWFkZXJzUG9saWN5IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWNsb3VkZnJvbnQnO1xuaW1wb3J0IHsgQVJlY29yZCwgQWFhYVJlY29yZCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtcm91dGU1M1wiO1xuaW1wb3J0IHsgQnVja2V0IH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1zM1wiO1xuaW1wb3J0IHsgU3RyaW5nUGFyYW1ldGVyIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLXNzbSc7XG5pbXBvcnQgeyBDZm5XZWJBQ0wgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3Mtd2FmdjInO1xuXG5pbXBvcnQgeyBTU0xDZXJ0aWZpY2F0ZSB9IGZyb20gJy4uLy4uL2NvbnN0cnVjdHMvY2VydGlmaWNhdGVtYW5hZ2VyLmpzJztcbmltcG9ydCB7IENsb3VkRnJvbnRGdW5jdGlvblJlZGlyZWN0cywgQ2xvdWRGcm9udEZ1bmN0aW9uLCBDbG91ZEZyb250RGlzdHJpYnV0aW9uIH0gZnJvbSAnLi4vLi4vY29uc3RydWN0cy9jbG91ZGZyb250LmpzJztcbmltcG9ydCB7IGdldEhvc3RlZFpvbmUsIENsb3VkRnJvbnRBbGlhcyB9IGZyb20gJy4uLy4uL2NvbnN0cnVjdHMvcm91dGU1My5qcyc7XG5pbXBvcnQgeyBTM0J1Y2tldCB9IGZyb20gJy4uLy4uL2NvbnN0cnVjdHMvczMuanMnO1xuaW1wb3J0IHsgQ2xvdWRGcm9udFdlYkFjbCB9IGZyb20gJy4uLy4uL2NvbnN0cnVjdHMvd2FmLmpzJztcbmltcG9ydCB7IGRvbWFpbkFzSWQgfSBmcm9tICcuLi8uLi9saWIvdXRpbHMuanMnO1xuaW1wb3J0IHsgYWRkRXZvU3RhY2tUYWdzIH0gZnJvbSAnLi4vLi4vbGliL3RhZ3MudHMnO1xuaW1wb3J0IHsgU3NtU3RyaW5nUGFyYW1ldGVyIH0gZnJvbSAnLi4vLi4vbGliL3R5cGVzLnRzJztcbmltcG9ydCB7IFMzQnVja2V0T3JpZ2luIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWNsb3VkZnJvbnQtb3JpZ2lucyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQmFzaWNBdXRoQ3JlZGVudGlhbHMge1xuICB1c2VyOiBzdHJpbmc7XG4gIHBhc3N3b3JkOiBzdHJpbmc7XG59XG5cbnR5cGUgQVdTTWFuYWdlZFJlc3BvbnNlSGVhZGVyc1BvbGljeSA9IFxuICAnQ09SU19BTExPV19BTExfT1JJR0lOUycgfFxuICAnQ09SU19BTExPV19BTExfT1JJR0lOU19BTkRfU0VDVVJJVFlfSEVBREVSUycgfFxuICAnQ09SU19BTExPV19BTExfT1JJR0lOU19XSVRIX1BSRUZMSUdIVCcgfFxuICAnQ09SU19BTExPV19BTExfT1JJR0lOU19XSVRIX1BSRUZMSUdIVF9BTkRfU0VDVVJJVFlfSEVBREVSUycgfFxuICAnU0VDVVJJVFlfSEVBREVSUyc7XG5cbnR5cGUgVVVJRCA9IGAke3N0cmluZ30tJHtzdHJpbmd9LSR7c3RyaW5nfS0ke3N0cmluZ30tJHtzdHJpbmd9YDtcbmV4cG9ydCBpbnRlcmZhY2UgV2ViR2xvYmFsU3RhY2tQcm9wcyB7XG4gIGVudlR5cGU6ICdOT1RfUFJPRCcgfCAnUFJPRCc7XG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICBidWNrZXROYW1lPzogc3RyaW5nO1xuICBob3N0ZWRab25lOiBzdHJpbmc7XG4gIGRvbWFpbk5hbWU6IHN0cmluZztcbiAgYmFzaWNBdXRoPzogc3RyaW5nIHwgQmFzaWNBdXRoQ3JlZGVudGlhbHMgfCBTc21TdHJpbmdQYXJhbWV0ZXI7XG4gIHZpZXdlclJlcXVlc3RSZXNwb25zZT86IHN0cmluZztcbiAgcmVkaXJlY3RzPzogQ2xvdWRGcm9udEZ1bmN0aW9uUmVkaXJlY3RzO1xuICByZWRpcmVjdHNDc3ZQYXRoPzogc3RyaW5nO1xuICAvLyBhdHRhY2hXZWJBY2w/OiBib29sZWFuIHwgc3RyaW5nO1xuICB3ZWJBY2w/OiBib29sZWFuIHwgc3RyaW5nIHwgU3NtU3RyaW5nUGFyYW1ldGVyO1xuICByZXNwb25zZUhlYWRlcnNQb2xpY3k/OiBmYWxzZSB8IEFXU01hbmFnZWRSZXNwb25zZUhlYWRlcnNQb2xpY3kgfCBVVUlEIHwgU3NtU3RyaW5nUGFyYW1ldGVyO1xuICByZXNwb25zZUhlYWRlcnNQb2xpY3lQcm9wcz86IFJlc3BvbnNlSGVhZGVyc1BvbGljeVByb3BzO1xuICBkZXN0cm95PzogYm9vbGVhbjtcbiAgdGFncz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJHbG9iYWxTdGFjayBleHRlbmRzIFN0YWNrIHtcbiAgcHVibGljIHJlYWRvbmx5IHNzbENlcnRpZmljYXRlOiBDZXJ0aWZpY2F0ZTtcbiAgcHVibGljIHJlYWRvbmx5IHMzQnVja2V0OiBCdWNrZXQ7XG4gIHB1YmxpYyByZWFkb25seSBjbG91ZEZyb250RnVuY3Rpb246IEZ1bmN0aW9uO1xuICBwdWJsaWMgcmVhZG9ubHkgY2xvdWRGcm9udERpc3RyaWJ1dGlvbjogRGlzdHJpYnV0aW9uO1xuICBwdWJsaWMgcmVhZG9ubHkgd2ViQWNsOiBDZm5XZWJBQ0wgfCB1bmRlZmluZWQ7XG4gIHB1YmxpYyByZWFkb25seSByZXNwb25zZUhlYWRlcnNQb2xpY3k6IElSZXNwb25zZUhlYWRlcnNQb2xpY3kgfCB1bmRlZmluZWQ7XG4gIHB1YmxpYyByZWFkb25seSBhUmVjb3JkOiBBUmVjb3JkO1xuICBwdWJsaWMgcmVhZG9ubHkgYWFhYVJlY29yZDogQWFhYVJlY29yZDtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogV2ViR2xvYmFsU3RhY2tQcm9wcyAmIFN0YWNrUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHByb3BzKTtcbiAgICBhZGRFdm9TdGFja1RhZ3ModGhpcywgJ1dlYkdsb2JhbFN0YWNrJyk7XG5cbiAgICBjb25zdCBob3N0ZWRab25lID0gZ2V0SG9zdGVkWm9uZSh0aGlzLCAnZ2V0SG9zdGVkWm9uZScsIHByb3BzLmhvc3RlZFpvbmUpO1xuXG4gICAgY29uc3QgX3NzbENlcnQgPSBuZXcgU1NMQ2VydGlmaWNhdGUodGhpcywgJ1NTTENlcnRpZmljYXRlJywge1xuICAgICAgaG9zdGVkWm9uZTogaG9zdGVkWm9uZSxcbiAgICAgIGRvbWFpbk5hbWU6IHByb3BzLmRvbWFpbk5hbWUsXG4gICAgICBkZXN0cm95OiBwcm9wcy5kZXN0cm95XG4gICAgfSk7XG4gICAgdGhpcy5zc2xDZXJ0aWZpY2F0ZSA9IF9zc2xDZXJ0LmNlcnRpZmljYXRlO1xuXG4gICAgY29uc3QgX3MzQnVja2V0ID0gbmV3IFMzQnVja2V0KHRoaXMsICdTM0J1Y2tldCcsIHtcbiAgICAgIGJ1Y2tldE5hbWU6IHByb3BzLmJ1Y2tldE5hbWUgPz8gUGh5c2ljYWxOYW1lLkdFTkVSQVRFX0lGX05FRURFRCxcbiAgICAgIGRlc3Ryb3k6IHByb3BzLmRlc3Ryb3lcbiAgICB9KTtcbiAgICB0aGlzLnMzQnVja2V0ID0gX3MzQnVja2V0LmJ1Y2tldDtcblxuICAgIGxldCByZXNwb25zZUhlYWRlcnNQb2xpY3k6IElSZXNwb25zZUhlYWRlcnNQb2xpY3kgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgaWYgKHByb3BzLnJlc3BvbnNlSGVhZGVyc1BvbGljeSkge1xuICAgICAgaWYgKHR5cGVvZiBwcm9wcy5yZXNwb25zZUhlYWRlcnNQb2xpY3kgPT0gJ3N0cmluZycpIHtcbiAgICAgICAgaWYgKC9eWzAtOWEtZl17OH0tWzAtOWEtZl17NH0tWzAtOWEtZl17NH0tWzAtOWEtZl17NH0tWzAtOWEtZl17MTJ9JC9pLnRlc3QocHJvcHMucmVzcG9uc2VIZWFkZXJzUG9saWN5KSkge1xuICAgICAgICAgIHJlc3BvbnNlSGVhZGVyc1BvbGljeSA9IFJlc3BvbnNlSGVhZGVyc1BvbGljeS5mcm9tUmVzcG9uc2VIZWFkZXJzUG9saWN5SWQodGhpcywgJ3Jlc3BvbnNlLWhlYWRlcnMtcG9saWN5LWJ5LWlkJywgcHJvcHMucmVzcG9uc2VIZWFkZXJzUG9saWN5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNwb25zZUhlYWRlcnNQb2xpY3kgPSBSZXNwb25zZUhlYWRlcnNQb2xpY3lbcHJvcHMucmVzcG9uc2VIZWFkZXJzUG9saWN5IGFzIGtleW9mIHR5cGVvZiBSZXNwb25zZUhlYWRlcnNQb2xpY3ldIGFzIElSZXNwb25zZUhlYWRlcnNQb2xpY3kgPz8gUmVzcG9uc2VIZWFkZXJzUG9saWN5LlNFQ1VSSVRZX0hFQURFUlM7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAocHJvcHMucmVzcG9uc2VIZWFkZXJzUG9saWN5LnBhdGgpIHtcbiAgICAgICAgcmVzcG9uc2VIZWFkZXJzUG9saWN5ID0gUmVzcG9uc2VIZWFkZXJzUG9saWN5LmZyb21SZXNwb25zZUhlYWRlcnNQb2xpY3lJZCh0aGlzLCAncmVzcG9uc2UtaGVhZGVycy1wb2xpY3ktYnktaWQnLCBTdHJpbmdQYXJhbWV0ZXIudmFsdWVGb3JTdHJpbmdQYXJhbWV0ZXIodGhpcywgcHJvcHMucmVzcG9uc2VIZWFkZXJzUG9saWN5LnBhdGgsIHByb3BzLnJlc3BvbnNlSGVhZGVyc1BvbGljeS52ZXJzaW9uKSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghcmVzcG9uc2VIZWFkZXJzUG9saWN5ICYmIHByb3BzLnJlc3BvbnNlSGVhZGVyc1BvbGljeVByb3BzKSB7XG4gICAgICByZXNwb25zZUhlYWRlcnNQb2xpY3kgPSBuZXcgUmVzcG9uc2VIZWFkZXJzUG9saWN5KHRoaXMsICdyZXNwb25zZS1oZWFkZXJzLXBvbGljeScsIHtcbiAgICAgICAgLi4ucHJvcHMucmVzcG9uc2VIZWFkZXJzUG9saWN5UHJvcHMsXG4gICAgICAgIHJlc3BvbnNlSGVhZGVyc1BvbGljeU5hbWU6IHByb3BzLnJlc3BvbnNlSGVhZGVyc1BvbGljeVByb3BzLnJlc3BvbnNlSGVhZGVyc1BvbGljeU5hbWUgfHwgYCR7ZG9tYWluQXNJZChwcm9wcy5kb21haW5OYW1lKX0tcmVzcG9uc2UtaGVhZGVycy1wb2xpY3lgXG4gICAgICB9KTtcbiAgICAgIHRoaXMucmVzcG9uc2VIZWFkZXJzUG9saWN5ID0gcmVzcG9uc2VIZWFkZXJzUG9saWN5O1xuICAgIH1cblxuICAgIGNvbnN0IGRlZmF1bHRCZWhhdmlvcjogQmVoYXZpb3JPcHRpb25zID0ge1xuICAgICAgb3JpZ2luOiBTM0J1Y2tldE9yaWdpbi53aXRoT3JpZ2luQWNjZXNzQ29udHJvbCh0aGlzLnMzQnVja2V0KSxcbiAgICAgIGZ1bmN0aW9uQXNzb2NpYXRpb25zOiBbXSxcbiAgICAgIHJlc3BvbnNlSGVhZGVyc1BvbGljeTogcmVzcG9uc2VIZWFkZXJzUG9saWN5ID8/IHByb3BzLnJlc3BvbnNlSGVhZGVyc1BvbGljeSAhPT0gZmFsc2UgPyBSZXNwb25zZUhlYWRlcnNQb2xpY3kuU0VDVVJJVFlfSEVBREVSUyA6IHVuZGVmaW5lZFxuICAgIH07XG5cbiAgICBsZXQgY2ZmbjogQ2xvdWRGcm9udEZ1bmN0aW9uO1xuICAgIGlmIChwcm9wcy5iYXNpY0F1dGgpIHtcbiAgICAgIGlmICh0eXBlb2YgcHJvcHMuYmFzaWNBdXRoICE9ICdzdHJpbmcnKSB7XG4gICAgICAgIGlmICgocHJvcHMuYmFzaWNBdXRoIGFzIEJhc2ljQXV0aENyZWRlbnRpYWxzKS51c2VyICYmIChwcm9wcy5iYXNpY0F1dGggYXMgQmFzaWNBdXRoQ3JlZGVudGlhbHMpLnBhc3N3b3JkKSB7XG4gICAgICAgICAgcHJvcHMuYmFzaWNBdXRoID0gQnVmZmVyLmZyb20oYCR7KHByb3BzLmJhc2ljQXV0aCBhcyBCYXNpY0F1dGhDcmVkZW50aWFscykudXNlcn06JHsocHJvcHMuYmFzaWNBdXRoIGFzIEJhc2ljQXV0aENyZWRlbnRpYWxzKS5wYXNzd29yZH1gKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgICAgIH0gZWxzZSBpZiAoKHByb3BzLmJhc2ljQXV0aCBhcyBTc21TdHJpbmdQYXJhbWV0ZXIpLnBhdGgpIHtcbiAgICAgICAgICBwcm9wcy5iYXNpY0F1dGggPSBTdHJpbmdQYXJhbWV0ZXIudmFsdWVGb3JTdHJpbmdQYXJhbWV0ZXIodGhpcywgKHByb3BzLmJhc2ljQXV0aCBhcyBTc21TdHJpbmdQYXJhbWV0ZXIpLnBhdGgsIChwcm9wcy5iYXNpY0F1dGggYXMgU3NtU3RyaW5nUGFyYW1ldGVyKS52ZXJzaW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcm9wcy5iYXNpY0F1dGggPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHByb3BzLnZpZXdlclJlcXVlc3RSZXNwb25zZSkge1xuICAgICAgY2ZmbiA9IENsb3VkRnJvbnRGdW5jdGlvbi5jcmVhdGVWaWV3ZXJSZXF1ZXN0UmVzcG9uc2VGdW5jdGlvbih0aGlzLCBudWxsLCB7XG4gICAgICAgIGNyZWRlbnRpYWxzOiBwcm9wcy5iYXNpY0F1dGgsXG4gICAgICAgIHJlZGlyZWN0czogcHJvcHMucmVkaXJlY3RzLFxuICAgICAgICByZWRpcmVjdHNDc3ZQYXRoOiBwcm9wcy5yZWRpcmVjdHNDc3ZQYXRoLFxuICAgICAgICBjb2RlOiBwcm9wcy52aWV3ZXJSZXF1ZXN0UmVzcG9uc2UsXG4gICAgICAgIGRlc3Ryb3k6IHByb3BzLmRlc3Ryb3lcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAocHJvcHMuYmFzaWNBdXRoKSB7XG4gICAgICBjZmZuID0gQ2xvdWRGcm9udEZ1bmN0aW9uLmNyZWF0ZUJhc2ljQXV0aERlZmF1bHREb2ModGhpcywge1xuICAgICAgICBjcmVkZW50aWFsczogcHJvcHMuYmFzaWNBdXRoLFxuICAgICAgICByZWRpcmVjdHM6IHByb3BzLnJlZGlyZWN0cyxcbiAgICAgICAgcmVkaXJlY3RzQ3N2UGF0aDogcHJvcHMucmVkaXJlY3RzQ3N2UGF0aCxcbiAgICAgICAgZGVzdHJveTogcHJvcHMuZGVzdHJveVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNmZm4gPSBDbG91ZEZyb250RnVuY3Rpb24uY3JlYXRlRGVmYXVsdERvYyh0aGlzLCB7XG4gICAgICAgIHJlZGlyZWN0czogcHJvcHMucmVkaXJlY3RzLFxuICAgICAgICByZWRpcmVjdHNDc3ZQYXRoOiBwcm9wcy5yZWRpcmVjdHNDc3ZQYXRoLFxuICAgICAgICBkZXN0cm95OiBwcm9wcy5kZXN0cm95XG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhpcy5jbG91ZEZyb250RnVuY3Rpb24gPSBjZmZuLmZuO1xuICAgIFxuICAgIGRlZmF1bHRCZWhhdmlvci5mdW5jdGlvbkFzc29jaWF0aW9ucyEucHVzaCh7XG4gICAgICBldmVudFR5cGU6IEZ1bmN0aW9uRXZlbnRUeXBlLlZJRVdFUl9SRVFVRVNULFxuICAgICAgZnVuY3Rpb246IHRoaXMuY2xvdWRGcm9udEZ1bmN0aW9uXG4gICAgfSk7XG4gICAgZGVmYXVsdEJlaGF2aW9yLmZ1bmN0aW9uQXNzb2NpYXRpb25zIS5wdXNoKHtcbiAgICAgIGV2ZW50VHlwZTogRnVuY3Rpb25FdmVudFR5cGUuVklFV0VSX1JFU1BPTlNFLFxuICAgICAgZnVuY3Rpb246IHRoaXMuY2xvdWRGcm9udEZ1bmN0aW9uXG4gICAgfSk7XG4gICAgXG4gICAgbGV0IHdlYkFjbElkOiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgaWYgKHR5cGVvZiBwcm9wcy53ZWJBY2wgPT0gJ3N0cmluZycgJiYgcHJvcHMud2ViQWNsLnN0YXJ0c1dpdGgoJ2Fybjphd3MnKSkge1xuICAgICAgd2ViQWNsSWQgPSBwcm9wcy53ZWJBY2w7XG4gICAgfSBlbHNlIGlmICgocHJvcHMud2ViQWNsIGFzIFNzbVN0cmluZ1BhcmFtZXRlcikucGF0aCkge1xuICAgICAgd2ViQWNsSWQgPSBTdHJpbmdQYXJhbWV0ZXIudmFsdWVGb3JTdHJpbmdQYXJhbWV0ZXIodGhpcywgKHByb3BzLndlYkFjbCBhcyBTc21TdHJpbmdQYXJhbWV0ZXIpLnBhdGgsIChwcm9wcy53ZWJBY2wgYXMgU3NtU3RyaW5nUGFyYW1ldGVyKS52ZXJzaW9uKTtcbiAgICB9IGVsc2UgaWYgKHByb3BzLndlYkFjbCA9PT0gdHJ1ZSkge1xuICAgICAgY29uc3Qgd2FmID0gbmV3IENsb3VkRnJvbnRXZWJBY2wodGhpcywgJ0Nsb3VkRnJvbnRXZWJBY2wnLCB7XG4gICAgICAgIG5hbWU6IGAke2RvbWFpbkFzSWQocHJvcHMuZG9tYWluTmFtZSl9YCxcbiAgICAgICAgZGVzdHJveTogcHJvcHMuZGVzdHJveVxuICAgICAgfSk7XG4gICAgICB0aGlzLndlYkFjbCA9IHdhZi5hY2w7XG4gICAgICB3ZWJBY2xJZCA9IHdhZi5hY2wuYXR0ckFybjtcbiAgICB9XG5cbiAgICBjb25zdCBjZkRpc3RyaWJ1dGlvbiA9IG5ldyBDbG91ZEZyb250RGlzdHJpYnV0aW9uKHRoaXMsICdDbG91ZEZyb250RGlzdHJpYnV0aW9uJywge1xuICAgICAgZG9tYWluTmFtZTogcHJvcHMuZG9tYWluTmFtZSxcbiAgICAgIGRlc2NyaXB0aW9uOiBwcm9wcy5kZXNjcmlwdGlvbiA/PyBwcm9wcy5kb21haW5OYW1lLFxuICAgICAgcHJpY2VDbGFzczogcHJvcHMuZW52VHlwZSxcbiAgICAgIGNlcnRpZmljYXRlOiB0aGlzLnNzbENlcnRpZmljYXRlLFxuICAgICAgZGVmYXVsdEJlaGF2aW9yLFxuICAgICAgd2ViQWNsSWRcbiAgICB9KTtcbiAgICB0aGlzLmNsb3VkRnJvbnREaXN0cmlidXRpb24gPSBjZkRpc3RyaWJ1dGlvbi5kaXN0cmlidXRpb247XG5cbiAgICBjb25zdCBjZkFsaWFzID0gbmV3IENsb3VkRnJvbnRBbGlhcyh0aGlzLCAnQ2xvdWRGcm9udEFsaWFzJywge1xuICAgICAgZGlzdHJpYnV0aW9uOiBjZkRpc3RyaWJ1dGlvbi5kaXN0cmlidXRpb24sXG4gICAgICBkb21haW5OYW1lOiBwcm9wcy5kb21haW5OYW1lLFxuICAgICAgaG9zdGVkWm9uZTogaG9zdGVkWm9uZVxuICAgIH0pO1xuICAgIHRoaXMuYVJlY29yZCA9IGNmQWxpYXMuYVJlY29yZDtcbiAgICB0aGlzLmFhYWFSZWNvcmQgPSBjZkFsaWFzLmFhYWFSZWNvcmQ7XG4gIH1cbn0iXX0=
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Stage, StageProps } from 'aws-cdk-lib/core';
|
|
2
|
+
import { Construct } from 'constructs';
|
|
3
|
+
import { CodeBuildPipelineProjectProps } from '../constructs/codebuild.js';
|
|
4
|
+
import { WebGlobalStack, WebGlobalStackProps } from '../stacks/web-static-serverless/web-global-stack.js';
|
|
5
|
+
import { CodePipelineStack, CodePipelineStackProps } from '../stacks/web-static-serverless/codepipeline-stack.js';
|
|
6
|
+
export interface Str8rClmStageProps extends WebGlobalStackProps {
|
|
7
|
+
pipeline?: Omit<CodePipelineStackProps, 'codeBuildProject'> & {
|
|
8
|
+
codeBuildProject?: Omit<CodeBuildPipelineProjectProps, 'cloudFrontDistributionArn' | 's3BucketName' | 'destroy' | 'tags'>;
|
|
9
|
+
};
|
|
10
|
+
destroy?: boolean;
|
|
11
|
+
tags?: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
export declare class Str8rClmStage extends Stage {
|
|
14
|
+
readonly webStack: WebGlobalStack;
|
|
15
|
+
readonly codePipelineStack: CodePipelineStack;
|
|
16
|
+
constructor(scope: Construct, id: string, props: Str8rClmStageProps & StageProps);
|
|
17
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Stage } from 'aws-cdk-lib/core';
|
|
2
|
+
import { WebGlobalStack } from '../stacks/web-static-serverless/web-global-stack.js';
|
|
3
|
+
import { CodePipelineStack } from '../stacks/web-static-serverless/codepipeline-stack.js';
|
|
4
|
+
import { mergeTags, createEvoVersionTag, createEvoStageTag } from "../lib/tags.js";
|
|
5
|
+
export class Str8rClmStage extends Stage {
|
|
6
|
+
webStack;
|
|
7
|
+
codePipelineStack;
|
|
8
|
+
constructor(scope, id, props) {
|
|
9
|
+
super(scope, id, props);
|
|
10
|
+
props.tags = mergeTags(props.tags, createEvoVersionTag(), createEvoStageTag('Str8rClmStage'));
|
|
11
|
+
if (props.destroy === undefined) {
|
|
12
|
+
props.destroy = true;
|
|
13
|
+
}
|
|
14
|
+
this.webStack = new WebGlobalStack(this, 'web-global', {
|
|
15
|
+
...props,
|
|
16
|
+
env: {
|
|
17
|
+
account: props.env?.account,
|
|
18
|
+
region: 'us-east-1'
|
|
19
|
+
},
|
|
20
|
+
stackName: `${props.stageName}-web-global-stack`,
|
|
21
|
+
destroy: props.destroy,
|
|
22
|
+
tags: props.tags
|
|
23
|
+
});
|
|
24
|
+
if (props.pipeline) {
|
|
25
|
+
props.pipeline.codeBuildProject = props.pipeline.codeBuildProject ?? {};
|
|
26
|
+
if (!props.pipeline.codeBuildProject.ecrBuildImage && !props.pipeline.codeBuildProject.buildImage) {
|
|
27
|
+
props.pipeline.codeBuildProject.ecrBuildImage = { repository: 'str8r-v3/codebuild', tag: 'veeva-clm' };
|
|
28
|
+
}
|
|
29
|
+
props.pipeline.codeBuildProject.cloudFrontDistributionArn = this.webStack.cloudFrontDistribution.distributionArn;
|
|
30
|
+
props.pipeline.codeBuildProject.s3BucketName = this.webStack.s3Bucket.bucketName;
|
|
31
|
+
this.codePipelineStack = new CodePipelineStack(this, 'codepipeline', {
|
|
32
|
+
...props.pipeline,
|
|
33
|
+
env: props.env,
|
|
34
|
+
stackName: `${props.stageName}-codepipeline-stack`,
|
|
35
|
+
destroy: props.destroy,
|
|
36
|
+
tags: props.tags
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RyOHItY2xtLXN0YWdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N0YWdlcy9zdHI4ci1jbG0tc3RhZ2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBYyxNQUFNLGtCQUFrQixDQUFDO0FBSXJELE9BQU8sRUFBRSxjQUFjLEVBQXVCLE1BQU0scURBQXFELENBQUM7QUFDMUcsT0FBTyxFQUFFLGlCQUFpQixFQUEwQixNQUFNLHVEQUF1RCxDQUFDO0FBQ2xILE9BQU8sRUFBRSxTQUFTLEVBQUUsbUJBQW1CLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQVVuRixNQUFNLE9BQU8sYUFBYyxTQUFRLEtBQUs7SUFDdEIsUUFBUSxDQUFpQjtJQUN6QixpQkFBaUIsQ0FBb0I7SUFFckQsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFzQztRQUM5RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN4QixLQUFLLENBQUMsSUFBSSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLG1CQUFtQixFQUFFLEVBQUUsaUJBQWlCLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztRQUU5RixJQUFJLEtBQUssQ0FBQyxPQUFPLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDaEMsS0FBSyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7UUFDdkIsQ0FBQztRQUVELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxjQUFjLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRTtZQUNyRCxHQUFHLEtBQUs7WUFDUixHQUFHLEVBQUU7Z0JBQ0gsT0FBTyxFQUFFLEtBQUssQ0FBQyxHQUFHLEVBQUUsT0FBTztnQkFDM0IsTUFBTSxFQUFFLFdBQVc7YUFDcEI7WUFDRCxTQUFTLEVBQUUsR0FBRyxLQUFLLENBQUMsU0FBUyxtQkFBbUI7WUFDaEQsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO1lBQ3RCLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSTtTQUNqQixDQUFDLENBQUM7UUFFSCxJQUFJLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNuQixLQUFLLENBQUMsUUFBUSxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLElBQUksRUFBRSxDQUFDO1lBQ3hFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLGFBQWEsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ2xHLEtBQUssQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxHQUFHLEVBQUUsVUFBVSxFQUFFLG9CQUFvQixFQUFFLEdBQUcsRUFBRSxXQUFXLEVBQUUsQ0FBQztZQUN6RyxDQUFDO1lBQ0EsS0FBSyxDQUFDLFFBQVEsQ0FBQyxnQkFBa0QsQ0FBQyx5QkFBeUIsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLHNCQUFzQixDQUFDLGVBQWUsQ0FBQztZQUNuSixLQUFLLENBQUMsUUFBUSxDQUFDLGdCQUFrRCxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUM7WUFFcEgsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksaUJBQWlCLENBQUMsSUFBSSxFQUFFLGNBQWMsRUFBRTtnQkFDbkUsR0FBRyxLQUFLLENBQUMsUUFBUTtnQkFDakIsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHO2dCQUNkLFNBQVMsRUFBRSxHQUFHLEtBQUssQ0FBQyxTQUFTLHFCQUFxQjtnQkFDbEQsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO2dCQUN0QixJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUk7YUFDakIsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFN0YWdlLCBTdGFnZVByb3BzIH0gZnJvbSAnYXdzLWNkay1saWIvY29yZSc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcblxuaW1wb3J0IHsgQ29kZUJ1aWxkUGlwZWxpbmVQcm9qZWN0UHJvcHMgfSBmcm9tICcuLi9jb25zdHJ1Y3RzL2NvZGVidWlsZC5qcyc7XG5pbXBvcnQgeyBXZWJHbG9iYWxTdGFjaywgV2ViR2xvYmFsU3RhY2tQcm9wcyB9IGZyb20gJy4uL3N0YWNrcy93ZWItc3RhdGljLXNlcnZlcmxlc3Mvd2ViLWdsb2JhbC1zdGFjay5qcyc7XG5pbXBvcnQgeyBDb2RlUGlwZWxpbmVTdGFjaywgQ29kZVBpcGVsaW5lU3RhY2tQcm9wcyB9IGZyb20gJy4uL3N0YWNrcy93ZWItc3RhdGljLXNlcnZlcmxlc3MvY29kZXBpcGVsaW5lLXN0YWNrLmpzJztcbmltcG9ydCB7IG1lcmdlVGFncywgY3JlYXRlRXZvVmVyc2lvblRhZywgY3JlYXRlRXZvU3RhZ2VUYWcgfSBmcm9tICcuLi9saWIvdGFncy50cyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RyOHJDbG1TdGFnZVByb3BzIGV4dGVuZHMgV2ViR2xvYmFsU3RhY2tQcm9wcyB7XG4gIHBpcGVsaW5lPzogT21pdDxDb2RlUGlwZWxpbmVTdGFja1Byb3BzLCAnY29kZUJ1aWxkUHJvamVjdCc+ICYge1xuICAgIGNvZGVCdWlsZFByb2plY3Q/OiBPbWl0PENvZGVCdWlsZFBpcGVsaW5lUHJvamVjdFByb3BzLCAnY2xvdWRGcm9udERpc3RyaWJ1dGlvbkFybicgfCAnczNCdWNrZXROYW1lJyB8ICdkZXN0cm95JyB8ICd0YWdzJz5cbiAgfVxuICBkZXN0cm95PzogYm9vbGVhbjtcbiAgdGFncz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG59XG5cbmV4cG9ydCBjbGFzcyBTdHI4ckNsbVN0YWdlIGV4dGVuZHMgU3RhZ2Uge1xuICBwdWJsaWMgcmVhZG9ubHkgd2ViU3RhY2s6IFdlYkdsb2JhbFN0YWNrO1xuICBwdWJsaWMgcmVhZG9ubHkgY29kZVBpcGVsaW5lU3RhY2s6IENvZGVQaXBlbGluZVN0YWNrO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBTdHI4ckNsbVN0YWdlUHJvcHMgJiBTdGFnZVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCBwcm9wcyk7XG4gICAgcHJvcHMudGFncyA9IG1lcmdlVGFncyhwcm9wcy50YWdzLCBjcmVhdGVFdm9WZXJzaW9uVGFnKCksIGNyZWF0ZUV2b1N0YWdlVGFnKCdTdHI4ckNsbVN0YWdlJykpO1xuXG4gICAgaWYgKHByb3BzLmRlc3Ryb3kgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcHJvcHMuZGVzdHJveSA9IHRydWU7XG4gICAgfVxuXG4gICAgdGhpcy53ZWJTdGFjayA9IG5ldyBXZWJHbG9iYWxTdGFjayh0aGlzLCAnd2ViLWdsb2JhbCcsIHtcbiAgICAgIC4uLnByb3BzLFxuICAgICAgZW52OiB7XG4gICAgICAgIGFjY291bnQ6IHByb3BzLmVudj8uYWNjb3VudCxcbiAgICAgICAgcmVnaW9uOiAndXMtZWFzdC0xJ1xuICAgICAgfSxcbiAgICAgIHN0YWNrTmFtZTogYCR7cHJvcHMuc3RhZ2VOYW1lfS13ZWItZ2xvYmFsLXN0YWNrYCxcbiAgICAgIGRlc3Ryb3k6IHByb3BzLmRlc3Ryb3ksXG4gICAgICB0YWdzOiBwcm9wcy50YWdzXG4gICAgfSk7XG5cbiAgICBpZiAocHJvcHMucGlwZWxpbmUpIHtcbiAgICAgIHByb3BzLnBpcGVsaW5lLmNvZGVCdWlsZFByb2plY3QgPSBwcm9wcy5waXBlbGluZS5jb2RlQnVpbGRQcm9qZWN0ID8/IHt9O1xuICAgICAgaWYgKCFwcm9wcy5waXBlbGluZS5jb2RlQnVpbGRQcm9qZWN0LmVjckJ1aWxkSW1hZ2UgJiYgIXByb3BzLnBpcGVsaW5lLmNvZGVCdWlsZFByb2plY3QuYnVpbGRJbWFnZSkge1xuICAgICAgICBwcm9wcy5waXBlbGluZS5jb2RlQnVpbGRQcm9qZWN0LmVjckJ1aWxkSW1hZ2UgPSB7IHJlcG9zaXRvcnk6ICdzdHI4ci12My9jb2RlYnVpbGQnLCB0YWc6ICd2ZWV2YS1jbG0nIH07XG4gICAgICB9XG4gICAgICAocHJvcHMucGlwZWxpbmUuY29kZUJ1aWxkUHJvamVjdCBhcyBDb2RlQnVpbGRQaXBlbGluZVByb2plY3RQcm9wcykuY2xvdWRGcm9udERpc3RyaWJ1dGlvbkFybiA9IHRoaXMud2ViU3RhY2suY2xvdWRGcm9udERpc3RyaWJ1dGlvbi5kaXN0cmlidXRpb25Bcm47XG4gICAgICAocHJvcHMucGlwZWxpbmUuY29kZUJ1aWxkUHJvamVjdCBhcyBDb2RlQnVpbGRQaXBlbGluZVByb2plY3RQcm9wcykuczNCdWNrZXROYW1lID0gdGhpcy53ZWJTdGFjay5zM0J1Y2tldC5idWNrZXROYW1lO1xuXG4gICAgICB0aGlzLmNvZGVQaXBlbGluZVN0YWNrID0gbmV3IENvZGVQaXBlbGluZVN0YWNrKHRoaXMsICdjb2RlcGlwZWxpbmUnLCB7XG4gICAgICAgIC4uLnByb3BzLnBpcGVsaW5lLFxuICAgICAgICBlbnY6IHByb3BzLmVudixcbiAgICAgICAgc3RhY2tOYW1lOiBgJHtwcm9wcy5zdGFnZU5hbWV9LWNvZGVwaXBlbGluZS1zdGFja2AsXG4gICAgICAgIGRlc3Ryb3k6IHByb3BzLmRlc3Ryb3ksXG4gICAgICAgIHRhZ3M6IHByb3BzLnRhZ3NcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Environment, Stage, StageProps } from 'aws-cdk-lib/core';
|
|
2
|
+
import { Construct } from 'constructs';
|
|
3
|
+
import { CodeBuildPipelineProjectProps } from '../constructs/codebuild.js';
|
|
4
|
+
import { WebGlobalStack, WebGlobalStackProps } from '../stacks/web-static-serverless/web-global-stack.js';
|
|
5
|
+
import { CodePipelineStack, CodePipelineStackProps } from '../stacks/web-static-serverless/codepipeline-stack.js';
|
|
6
|
+
export interface WebStaticServerlessStageProps extends WebGlobalStackProps {
|
|
7
|
+
pipeline?: Omit<CodePipelineStackProps, 'codeBuildProject'> & {
|
|
8
|
+
codeBuildProject?: Omit<CodeBuildPipelineProjectProps, 'cloudFrontDistributionArn' | 's3BucketName' | 'destroy' | 'tags'>;
|
|
9
|
+
};
|
|
10
|
+
env?: Environment;
|
|
11
|
+
destroy?: boolean;
|
|
12
|
+
tags?: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
export declare class WebStaticServerlessStage extends Stage {
|
|
15
|
+
readonly webStack: WebGlobalStack;
|
|
16
|
+
readonly codePipelineStack: CodePipelineStack;
|
|
17
|
+
constructor(scope: Construct, id: string, props: WebStaticServerlessStageProps & StageProps);
|
|
18
|
+
static create(scope: Construct, id: string, props: WebStaticServerlessStageProps & StageProps): WebStaticServerlessStage;
|
|
19
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Stage } from 'aws-cdk-lib/core';
|
|
2
|
+
import { WebGlobalStack } from '../stacks/web-static-serverless/web-global-stack.js';
|
|
3
|
+
// import { WebRegionalStack } from '../stacks/web-static-serverless/web-regional-stack';
|
|
4
|
+
import { CodePipelineStack } from '../stacks/web-static-serverless/codepipeline-stack.js';
|
|
5
|
+
import { mergeTags, createEvoVersionTag, createEvoStageTag } from "../lib/tags.js";
|
|
6
|
+
export class WebStaticServerlessStage extends Stage {
|
|
7
|
+
// public readonly regionalStack: WebRegionalStack;
|
|
8
|
+
webStack;
|
|
9
|
+
codePipelineStack;
|
|
10
|
+
constructor(scope, id, props) {
|
|
11
|
+
super(scope, id, props);
|
|
12
|
+
props.tags = mergeTags(props.tags, createEvoVersionTag(), createEvoStageTag('WebStaticServerlessStage'));
|
|
13
|
+
if (props.destroy === undefined) {
|
|
14
|
+
props.destroy = true;
|
|
15
|
+
}
|
|
16
|
+
this.webStack = new WebGlobalStack(this, 'web-global', {
|
|
17
|
+
...props,
|
|
18
|
+
env: {
|
|
19
|
+
account: props.env?.account,
|
|
20
|
+
region: 'us-east-1'
|
|
21
|
+
},
|
|
22
|
+
stackName: `${props.stageName}-web-global-stack`,
|
|
23
|
+
// s3BucketName: this.regionalStack.s3Bucket.bucketName
|
|
24
|
+
destroy: props.destroy,
|
|
25
|
+
tags: props.tags
|
|
26
|
+
});
|
|
27
|
+
if (props.pipeline) {
|
|
28
|
+
props.pipeline.codeBuildProject = props.pipeline.codeBuildProject ?? {};
|
|
29
|
+
props.pipeline.codeBuildProject.cloudFrontDistributionArn = this.webStack.cloudFrontDistribution.distributionArn;
|
|
30
|
+
props.pipeline.codeBuildProject.s3BucketName = this.webStack.s3Bucket.bucketName;
|
|
31
|
+
this.codePipelineStack = new CodePipelineStack(this, 'codepipeline', {
|
|
32
|
+
...props.pipeline,
|
|
33
|
+
env: props.env,
|
|
34
|
+
stackName: `${props.stageName}-codepipeline-stack`,
|
|
35
|
+
destroy: props.destroy,
|
|
36
|
+
tags: props.tags
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
static create(scope, id, props) {
|
|
41
|
+
const env = {
|
|
42
|
+
account: props.env?.account ?? process.env.CDK_DEFAULT_ACCOUNT,
|
|
43
|
+
region: props.env?.region ?? process.env.CDK_DEFAULT_REGION
|
|
44
|
+
};
|
|
45
|
+
return new WebStaticServerlessStage(scope, id, {
|
|
46
|
+
...props,
|
|
47
|
+
...env
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViLXN0YXRpYy1zZXJ2ZXJsZXNzLXN0YWdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N0YWdlcy93ZWItc3RhdGljLXNlcnZlcmxlc3Mtc3RhZ2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFlLEtBQUssRUFBYyxNQUFNLGtCQUFrQixDQUFDO0FBSWxFLE9BQU8sRUFBRSxjQUFjLEVBQXVCLE1BQU0scURBQXFELENBQUM7QUFDMUcseUZBQXlGO0FBQ3pGLE9BQU8sRUFBRSxpQkFBaUIsRUFBMEIsTUFBTSx1REFBdUQsQ0FBQztBQUNsSCxPQUFPLEVBQUUsU0FBUyxFQUFFLG1CQUFtQixFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFXbkYsTUFBTSxPQUFPLHdCQUF5QixTQUFRLEtBQUs7SUFDakQsbURBQW1EO0lBQ25DLFFBQVEsQ0FBaUI7SUFDekIsaUJBQWlCLENBQW9CO0lBRXJELFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBaUQ7UUFDekYsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDeEIsS0FBSyxDQUFDLElBQUksR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxtQkFBbUIsRUFBRSxFQUFFLGlCQUFpQixDQUFDLDBCQUEwQixDQUFDLENBQUMsQ0FBQztRQUV6RyxJQUFJLEtBQUssQ0FBQyxPQUFPLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDaEMsS0FBSyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7UUFDdkIsQ0FBQztRQUVELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxjQUFjLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRTtZQUNyRCxHQUFHLEtBQUs7WUFDUixHQUFHLEVBQUU7Z0JBQ0gsT0FBTyxFQUFFLEtBQUssQ0FBQyxHQUFHLEVBQUUsT0FBTztnQkFDM0IsTUFBTSxFQUFFLFdBQVc7YUFDcEI7WUFDRCxTQUFTLEVBQUUsR0FBRyxLQUFLLENBQUMsU0FBUyxtQkFBbUI7WUFDaEQsdURBQXVEO1lBQ3ZELE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTztZQUN0QixJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUk7U0FDakIsQ0FBQyxDQUFDO1FBRUgsSUFBSSxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDbkIsS0FBSyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDLGdCQUFnQixJQUFJLEVBQUUsQ0FBQztZQUN2RSxLQUFLLENBQUMsUUFBUSxDQUFDLGdCQUFrRCxDQUFDLHlCQUF5QixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsc0JBQXNCLENBQUMsZUFBZSxDQUFDO1lBQ25KLEtBQUssQ0FBQyxRQUFRLENBQUMsZ0JBQWtELENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQztZQUVwSCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsY0FBYyxFQUFFO2dCQUNuRSxHQUFHLEtBQUssQ0FBQyxRQUFRO2dCQUNqQixHQUFHLEVBQUUsS0FBSyxDQUFDLEdBQUc7Z0JBQ2QsU0FBUyxFQUFFLEdBQUcsS0FBSyxDQUFDLFNBQVMscUJBQXFCO2dCQUNsRCxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87Z0JBQ3RCLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSTthQUNqQixDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBaUQ7UUFDM0YsTUFBTSxHQUFHLEdBQUc7WUFDVixPQUFPLEVBQUUsS0FBSyxDQUFDLEdBQUcsRUFBRSxPQUFPLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUI7WUFDOUQsTUFBTSxFQUFFLEtBQUssQ0FBQyxHQUFHLEVBQUUsTUFBTSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWtCO1NBQzVELENBQUM7UUFDRixPQUFPLElBQUksd0JBQXdCLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRTtZQUM3QyxHQUFHLEtBQUs7WUFDUixHQUFHLEdBQUc7U0FDUCxDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFbnZpcm9ubWVudCwgU3RhZ2UsIFN0YWdlUHJvcHMgfSBmcm9tICdhd3MtY2RrLWxpYi9jb3JlJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuXG5pbXBvcnQgeyBDb2RlQnVpbGRQaXBlbGluZVByb2plY3RQcm9wcyB9IGZyb20gJy4uL2NvbnN0cnVjdHMvY29kZWJ1aWxkLmpzJztcbmltcG9ydCB7IFdlYkdsb2JhbFN0YWNrLCBXZWJHbG9iYWxTdGFja1Byb3BzIH0gZnJvbSAnLi4vc3RhY2tzL3dlYi1zdGF0aWMtc2VydmVybGVzcy93ZWItZ2xvYmFsLXN0YWNrLmpzJztcbi8vIGltcG9ydCB7IFdlYlJlZ2lvbmFsU3RhY2sgfSBmcm9tICcuLi9zdGFja3Mvd2ViLXN0YXRpYy1zZXJ2ZXJsZXNzL3dlYi1yZWdpb25hbC1zdGFjayc7XG5pbXBvcnQgeyBDb2RlUGlwZWxpbmVTdGFjaywgQ29kZVBpcGVsaW5lU3RhY2tQcm9wcyB9IGZyb20gJy4uL3N0YWNrcy93ZWItc3RhdGljLXNlcnZlcmxlc3MvY29kZXBpcGVsaW5lLXN0YWNrLmpzJztcbmltcG9ydCB7IG1lcmdlVGFncywgY3JlYXRlRXZvVmVyc2lvblRhZywgY3JlYXRlRXZvU3RhZ2VUYWcgfSBmcm9tICcuLi9saWIvdGFncy50cyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgV2ViU3RhdGljU2VydmVybGVzc1N0YWdlUHJvcHMgZXh0ZW5kcyBXZWJHbG9iYWxTdGFja1Byb3BzIHtcbiAgcGlwZWxpbmU/OiBPbWl0PENvZGVQaXBlbGluZVN0YWNrUHJvcHMsICdjb2RlQnVpbGRQcm9qZWN0Jz4gJiB7XG4gICAgY29kZUJ1aWxkUHJvamVjdD86IE9taXQ8Q29kZUJ1aWxkUGlwZWxpbmVQcm9qZWN0UHJvcHMsICdjbG91ZEZyb250RGlzdHJpYnV0aW9uQXJuJyB8ICdzM0J1Y2tldE5hbWUnIHwgJ2Rlc3Ryb3knIHwgJ3RhZ3MnPlxuICB9XG4gIGVudj86IEVudmlyb25tZW50O1xuICBkZXN0cm95PzogYm9vbGVhbjtcbiAgdGFncz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJTdGF0aWNTZXJ2ZXJsZXNzU3RhZ2UgZXh0ZW5kcyBTdGFnZSB7XG4gIC8vIHB1YmxpYyByZWFkb25seSByZWdpb25hbFN0YWNrOiBXZWJSZWdpb25hbFN0YWNrO1xuICBwdWJsaWMgcmVhZG9ubHkgd2ViU3RhY2s6IFdlYkdsb2JhbFN0YWNrO1xuICBwdWJsaWMgcmVhZG9ubHkgY29kZVBpcGVsaW5lU3RhY2s6IENvZGVQaXBlbGluZVN0YWNrO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBXZWJTdGF0aWNTZXJ2ZXJsZXNzU3RhZ2VQcm9wcyAmIFN0YWdlUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHByb3BzKTtcbiAgICBwcm9wcy50YWdzID0gbWVyZ2VUYWdzKHByb3BzLnRhZ3MsIGNyZWF0ZUV2b1ZlcnNpb25UYWcoKSwgY3JlYXRlRXZvU3RhZ2VUYWcoJ1dlYlN0YXRpY1NlcnZlcmxlc3NTdGFnZScpKTtcblxuICAgIGlmIChwcm9wcy5kZXN0cm95ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHByb3BzLmRlc3Ryb3kgPSB0cnVlO1xuICAgIH1cblxuICAgIHRoaXMud2ViU3RhY2sgPSBuZXcgV2ViR2xvYmFsU3RhY2sodGhpcywgJ3dlYi1nbG9iYWwnLCB7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIGVudjoge1xuICAgICAgICBhY2NvdW50OiBwcm9wcy5lbnY/LmFjY291bnQsXG4gICAgICAgIHJlZ2lvbjogJ3VzLWVhc3QtMSdcbiAgICAgIH0sXG4gICAgICBzdGFja05hbWU6IGAke3Byb3BzLnN0YWdlTmFtZX0td2ViLWdsb2JhbC1zdGFja2AsXG4gICAgICAvLyBzM0J1Y2tldE5hbWU6IHRoaXMucmVnaW9uYWxTdGFjay5zM0J1Y2tldC5idWNrZXROYW1lXG4gICAgICBkZXN0cm95OiBwcm9wcy5kZXN0cm95LFxuICAgICAgdGFnczogcHJvcHMudGFnc1xuICAgIH0pO1xuXG4gICAgaWYgKHByb3BzLnBpcGVsaW5lKSB7XG4gICAgICBwcm9wcy5waXBlbGluZS5jb2RlQnVpbGRQcm9qZWN0ID0gcHJvcHMucGlwZWxpbmUuY29kZUJ1aWxkUHJvamVjdCA/PyB7fTtcbiAgICAgIChwcm9wcy5waXBlbGluZS5jb2RlQnVpbGRQcm9qZWN0IGFzIENvZGVCdWlsZFBpcGVsaW5lUHJvamVjdFByb3BzKS5jbG91ZEZyb250RGlzdHJpYnV0aW9uQXJuID0gdGhpcy53ZWJTdGFjay5jbG91ZEZyb250RGlzdHJpYnV0aW9uLmRpc3RyaWJ1dGlvbkFybjtcbiAgICAgIChwcm9wcy5waXBlbGluZS5jb2RlQnVpbGRQcm9qZWN0IGFzIENvZGVCdWlsZFBpcGVsaW5lUHJvamVjdFByb3BzKS5zM0J1Y2tldE5hbWUgPSB0aGlzLndlYlN0YWNrLnMzQnVja2V0LmJ1Y2tldE5hbWU7XG5cbiAgICAgIHRoaXMuY29kZVBpcGVsaW5lU3RhY2sgPSBuZXcgQ29kZVBpcGVsaW5lU3RhY2sodGhpcywgJ2NvZGVwaXBlbGluZScsIHtcbiAgICAgICAgLi4ucHJvcHMucGlwZWxpbmUsXG4gICAgICAgIGVudjogcHJvcHMuZW52LFxuICAgICAgICBzdGFja05hbWU6IGAke3Byb3BzLnN0YWdlTmFtZX0tY29kZXBpcGVsaW5lLXN0YWNrYCxcbiAgICAgICAgZGVzdHJveTogcHJvcHMuZGVzdHJveSxcbiAgICAgICAgdGFnczogcHJvcHMudGFnc1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGNyZWF0ZShzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogV2ViU3RhdGljU2VydmVybGVzc1N0YWdlUHJvcHMgJiBTdGFnZVByb3BzKSB7XG4gICAgY29uc3QgZW52ID0ge1xuICAgICAgYWNjb3VudDogcHJvcHMuZW52Py5hY2NvdW50ID8/IHByb2Nlc3MuZW52LkNES19ERUZBVUxUX0FDQ09VTlQsXG4gICAgICByZWdpb246IHByb3BzLmVudj8ucmVnaW9uID8/IHByb2Nlc3MuZW52LkNES19ERUZBVUxUX1JFR0lPTlxuICAgIH07XG4gICAgcmV0dXJuIG5ldyBXZWJTdGF0aWNTZXJ2ZXJsZXNzU3RhZ2Uoc2NvcGUsIGlkLCB7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIC4uLmVudlxuICAgIH0pO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Viewer Request - handle basic authorization, redirects, append index.html to origin
|
|
3
|
+
* Viewer Response - handle 301 redirect with request querystring
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const DEFAULT_DOCUMENT = "__DEFAULT_DOCUMENT__";
|
|
7
|
+
const BASIC_AUTH = ["Basic __CREDENTIALS__"];
|
|
8
|
+
|
|
9
|
+
/** @type {Record<string, string | [string, 301|302|303|307|308]>} */
|
|
10
|
+
const redirects = __REDIRECTS__;
|
|
11
|
+
|
|
12
|
+
const useTrailingSlash = __TRAILING_SLASH__;
|
|
13
|
+
const shouldRedirDefDoc = __REDIR_DEF_DOC__;
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
function handler(event) {
|
|
17
|
+
switch (event.context.eventType) {
|
|
18
|
+
case "viewer-request":
|
|
19
|
+
return handleRequest(event);
|
|
20
|
+
case "viewer-response":
|
|
21
|
+
return handleResponse(event);
|
|
22
|
+
default:
|
|
23
|
+
return {
|
|
24
|
+
statusCode: 400,
|
|
25
|
+
statusDescription: "Bad request",
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function handleRequest(event) {
|
|
31
|
+
if (authorized(event)) {
|
|
32
|
+
const request = event.request;
|
|
33
|
+
const uri = request.uri;
|
|
34
|
+
|
|
35
|
+
const redirect = redirects ? redirects[uri] : null;
|
|
36
|
+
if (redirect) {
|
|
37
|
+
const redir = Array.isArray(redirect) ? redirect : [redirect, 301];
|
|
38
|
+
return redirectResponse(event, redir[0], redir[1]);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (/^(?:.+?)\.[^\.\/]+$/.test(uri)) {
|
|
42
|
+
// uri has a file extension
|
|
43
|
+
if (uri.endsWith(DEFAULT_DOCUMENT) && shouldRedirDefDoc === true) {
|
|
44
|
+
return redirectResponse(event, uri.slice(0, -1 * DEFAULT_DOCUMENT.length - (useTrailingSlash ? 0 : 1)));
|
|
45
|
+
} else {
|
|
46
|
+
return request;
|
|
47
|
+
}
|
|
48
|
+
} else if (useTrailingSlash === true && !uri.endsWith("/")) {
|
|
49
|
+
return redirectResponse(event, `${uri}/`);
|
|
50
|
+
} else if (uri !== '/' && useTrailingSlash === false && uri.endsWith("/")) {
|
|
51
|
+
return redirectResponse(event, uri.slice(0, -1));
|
|
52
|
+
} else {
|
|
53
|
+
request.uri = `${uri}${uri.endsWith("/") ? "" : "/"}${DEFAULT_DOCUMENT}`;
|
|
54
|
+
return request;
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
return {
|
|
58
|
+
statusCode: 401,
|
|
59
|
+
statusDescription: "Unauthorized",
|
|
60
|
+
headers: {
|
|
61
|
+
"www-authenticate": { value: "Basic" },
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function authorized(event) {
|
|
68
|
+
let flag = false;
|
|
69
|
+
const authHeader = event.request.headers["authorization"];
|
|
70
|
+
if (authHeader && authHeader.value) {
|
|
71
|
+
BASIC_AUTH.every((val) => {
|
|
72
|
+
flag = authHeader.value === val;
|
|
73
|
+
return !flag;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return flag;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function handleResponse(event) {
|
|
80
|
+
switch (event.response.statusCode) {
|
|
81
|
+
case 301:
|
|
82
|
+
case 302:
|
|
83
|
+
case 303:
|
|
84
|
+
case 307:
|
|
85
|
+
case 308:
|
|
86
|
+
return redirectResponse(event);
|
|
87
|
+
default:
|
|
88
|
+
return event.response;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
var STATUS_DESCRIPTIONS = {
|
|
93
|
+
301: "Moved Permanently",
|
|
94
|
+
302: "Found",
|
|
95
|
+
303: "See Other",
|
|
96
|
+
307: "Temporary Redirect",
|
|
97
|
+
308: "Permanent Redirect"
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
function redirectResponse(event, location, statusCode) {
|
|
101
|
+
var response = event.response || {};
|
|
102
|
+
var code = statusCode || response.statusCode || 301;
|
|
103
|
+
response.statusCode = code;
|
|
104
|
+
response.statusDescription = STATUS_DESCRIPTIONS[code] || "Moved Permanently";
|
|
105
|
+
var path = location || getLocationHeaderValue(response.headers) || '/';
|
|
106
|
+
var querystring = event.request.querystring;
|
|
107
|
+
response.headers = updateLocationHeader(response.headers, pathWithQS(path, querystring));
|
|
108
|
+
return response;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function getLocationHeaderValue(headers) {
|
|
112
|
+
return headers && headers["location"] ? headers["location"].value : undefined;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function updateLocationHeader(headers, location) {
|
|
116
|
+
headers = headers || {};
|
|
117
|
+
headers["location"] = {
|
|
118
|
+
value: location,
|
|
119
|
+
};
|
|
120
|
+
return headers;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function qsParamExists(path, key, value) {
|
|
124
|
+
return path.indexOf(`${key}=${value}`) != -1;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function pathWithQS(path, querystring) {
|
|
128
|
+
let qs = [];
|
|
129
|
+
if (querystring) {
|
|
130
|
+
qs = Object.keys(querystring)
|
|
131
|
+
.map(function (key) {
|
|
132
|
+
if (querystring[key].multiValue) {
|
|
133
|
+
return querystring[key].multiValue.map((multiKey) => {
|
|
134
|
+
return !qsParamExists(path, key, multiKey.value)
|
|
135
|
+
? `${key}=${multiKey.value}`
|
|
136
|
+
: null;
|
|
137
|
+
});
|
|
138
|
+
} else {
|
|
139
|
+
return !qsParamExists(path, key, querystring[key].value)
|
|
140
|
+
? `${key}=${querystring[key].value}`
|
|
141
|
+
: null;
|
|
142
|
+
}
|
|
143
|
+
})
|
|
144
|
+
.reduce((r, item) => {
|
|
145
|
+
(item instanceof Array ? item : [item]).forEach((i) => {
|
|
146
|
+
r.push(i);
|
|
147
|
+
});
|
|
148
|
+
return r;
|
|
149
|
+
}, [])
|
|
150
|
+
.filter((item) => {
|
|
151
|
+
return item !== null;
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
return `${path}${qs.length > 0 ? (path.indexOf("?") == -1 ? "?" : "&") : ""}${qs.join("&")}`;
|
|
155
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Viewer Request - redirects, append index.html to origin
|
|
3
|
+
* Viewer Response - handle 301 redirect with request querystring
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const DEFAULT_DOCUMENT = "__DEFAULT_DOCUMENT__";
|
|
7
|
+
|
|
8
|
+
/** @type {Record<string, string | [string, 301|302|303|307|308]>} */
|
|
9
|
+
const redirects = __REDIRECTS__;
|
|
10
|
+
|
|
11
|
+
const useTrailingSlash = __TRAILING_SLASH__;
|
|
12
|
+
const shouldRedirDefDoc = __REDIR_DEF_DOC__;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
function handler(event) {
|
|
16
|
+
switch (event.context.eventType) {
|
|
17
|
+
case "viewer-request":
|
|
18
|
+
return handleRequest(event);
|
|
19
|
+
case "viewer-response":
|
|
20
|
+
return handleResponse(event);
|
|
21
|
+
default:
|
|
22
|
+
return {
|
|
23
|
+
statusCode: 400,
|
|
24
|
+
statusDescription: "Bad request",
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function handleRequest(event) {
|
|
30
|
+
const request = event.request;
|
|
31
|
+
const uri = request.uri;
|
|
32
|
+
|
|
33
|
+
const redirect = redirects ? redirects[uri] : null;
|
|
34
|
+
if (redirect) {
|
|
35
|
+
const redir = Array.isArray(redirect) ? redirect : [redirect, 301];
|
|
36
|
+
return redirectResponse(event, redir[0], redir[1]);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (/^(?:.+?)\.[^\.\/]+$/.test(uri)) {
|
|
40
|
+
// uri has a file extension
|
|
41
|
+
if (uri.endsWith(DEFAULT_DOCUMENT) && shouldRedirDefDoc === true) {
|
|
42
|
+
return redirectResponse(event, uri.slice(0, -1 * DEFAULT_DOCUMENT.length - (useTrailingSlash ? 0 : 1)));
|
|
43
|
+
} else {
|
|
44
|
+
return request;
|
|
45
|
+
}
|
|
46
|
+
} else if (useTrailingSlash === true && !uri.endsWith("/")) {
|
|
47
|
+
return redirectResponse(event, `${uri}/`);
|
|
48
|
+
} else if (uri !== '/' && useTrailingSlash === false && uri.endsWith("/")) {
|
|
49
|
+
return redirectResponse(event, uri.slice(0, -1));
|
|
50
|
+
} else {
|
|
51
|
+
request.uri = `${uri}${uri.endsWith("/") ? "" : "/"}${DEFAULT_DOCUMENT}`;
|
|
52
|
+
return request;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function handleResponse(event) {
|
|
57
|
+
switch (event.response.statusCode) {
|
|
58
|
+
case 301:
|
|
59
|
+
case 302:
|
|
60
|
+
case 303:
|
|
61
|
+
case 307:
|
|
62
|
+
case 308:
|
|
63
|
+
return redirectResponse(event);
|
|
64
|
+
default:
|
|
65
|
+
return event.response;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
var STATUS_DESCRIPTIONS = {
|
|
70
|
+
301: "Moved Permanently",
|
|
71
|
+
302: "Found",
|
|
72
|
+
303: "See Other",
|
|
73
|
+
307: "Temporary Redirect",
|
|
74
|
+
308: "Permanent Redirect"
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
function redirectResponse(event, location, statusCode) {
|
|
78
|
+
var response = event.response || {};
|
|
79
|
+
var code = statusCode || response.statusCode || 301;
|
|
80
|
+
response.statusCode = code;
|
|
81
|
+
response.statusDescription = STATUS_DESCRIPTIONS[code] || "Moved Permanently";
|
|
82
|
+
var path = location || getLocationHeaderValue(response.headers) || '/';
|
|
83
|
+
var querystring = event.request.querystring;
|
|
84
|
+
response.headers = updateLocationHeader(response.headers, pathWithQS(path, querystring));
|
|
85
|
+
return response;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function getLocationHeaderValue(headers) {
|
|
89
|
+
return headers && headers["location"] ? headers["location"].value : undefined;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function updateLocationHeader(headers, location) {
|
|
93
|
+
headers = headers || {};
|
|
94
|
+
headers["location"] = {
|
|
95
|
+
value: location,
|
|
96
|
+
};
|
|
97
|
+
return headers;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function qsParamExists(path, key, value) {
|
|
101
|
+
return path.indexOf(`${key}=${value}`) != -1;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function pathWithQS(path, querystring) {
|
|
105
|
+
let qs = [];
|
|
106
|
+
if (querystring) {
|
|
107
|
+
qs = Object.keys(querystring)
|
|
108
|
+
.map(function (key) {
|
|
109
|
+
if (querystring[key].multiValue) {
|
|
110
|
+
return querystring[key].multiValue.map((multiKey) => {
|
|
111
|
+
return !qsParamExists(path, key, multiKey.value)
|
|
112
|
+
? `${key}=${multiKey.value}`
|
|
113
|
+
: null;
|
|
114
|
+
});
|
|
115
|
+
} else {
|
|
116
|
+
return !qsParamExists(path, key, querystring[key].value)
|
|
117
|
+
? `${key}=${querystring[key].value}`
|
|
118
|
+
: null;
|
|
119
|
+
}
|
|
120
|
+
})
|
|
121
|
+
.reduce((r, item) => {
|
|
122
|
+
(item instanceof Array ? item : [item]).forEach((i) => {
|
|
123
|
+
r.push(i);
|
|
124
|
+
});
|
|
125
|
+
return r;
|
|
126
|
+
}, [])
|
|
127
|
+
.filter((item) => {
|
|
128
|
+
return item !== null;
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return `${path}${qs.length > 0 ? (path.indexOf("?") == -1 ? "?" : "&") : ""}${qs.join("&")}`;
|
|
132
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@inizioevoke/evosynth",
|
|
3
|
+
"version": "1.6.0",
|
|
4
|
+
"author": "",
|
|
5
|
+
"license": "ISC",
|
|
6
|
+
"description": "",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./dist/index.js",
|
|
10
|
+
"./constructs/*": "./dist/constructs/*.js",
|
|
11
|
+
"./stacks/*": "./dist/stacks/*.js",
|
|
12
|
+
"./stages/*": "./dist/stages/*.js"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"prepublishOnly": "npm run build",
|
|
16
|
+
"build": "node ./tasks/clean.js && npx tsc && node ./tasks/copy-templates.js"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/node": "^25.3.0",
|
|
20
|
+
"aws-cdk-lib": "^2.238.0",
|
|
21
|
+
"constructs": "^10.5.1",
|
|
22
|
+
"typescript": "^5.9.3"
|
|
23
|
+
}
|
|
24
|
+
}
|