@inizioevoke/evosynth 1.8.0 → 2.0.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/dist/cli/cli.d.ts +2 -0
- package/dist/cli/cli.js +23 -0
- package/dist/cli/evosynth.d.ts +17 -0
- package/dist/cli/evosynth.js +61 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +3 -0
- package/dist/cli/web-static-serverless.d.ts +52 -0
- package/dist/cli/web-static-serverless.js +73 -0
- package/dist/constructs/codebuild.d.ts +13 -5
- package/dist/constructs/codebuild.js +21 -6
- package/dist/constructs/codepipeline.js +4 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -2
- package/dist/stacks/web-static-serverless/web-global-stack.d.ts +4 -8
- package/dist/stacks/web-static-serverless/web-global-stack.js +57 -61
- package/dist/types.d.ts +16 -1
- package/package.json +9 -2
- package/readme.md +1 -1
- package/samples/app.ts +1 -1
- package/src/cli/cli.ts +29 -0
- package/src/cli/evosynth.ts +72 -0
- package/src/cli/index.ts +2 -0
- package/src/cli/web-static-serverless.ts +130 -0
- package/src/constructs/codebuild.ts +52 -9
- package/src/constructs/codepipeline.ts +3 -2
- package/src/index.ts +2 -1
- package/src/stacks/web-static-serverless/web-global-stack.ts +57 -72
- package/src/types.d.ts +16 -1
|
@@ -11,7 +11,33 @@ import type { ResourceProps } from "../types.d.ts";
|
|
|
11
11
|
|
|
12
12
|
export type EnvironmentVariables = Record<string, { value: any, type?: BuildEnvironmentVariableType }>;
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
export type CodeBuildImageId =
|
|
15
|
+
'aws/codebuild/amazonlinux2-aarch64-standard:1.0' |
|
|
16
|
+
'aws/codebuild/amazonlinux2-x86_64-standard:2.0' |
|
|
17
|
+
'aws/codebuild/amazonlinux2-x86_64-standard:3.0' |
|
|
18
|
+
'aws/codebuild/amazonlinux-x86_64-standard:4.0' |
|
|
19
|
+
'aws/codebuild/amazonlinux-x86_64-standard:5.0' |
|
|
20
|
+
'aws/codebuild/amazonlinux-x86_64-standard:6.0' |
|
|
21
|
+
'aws/codebuild/amazonlinux-x86_64-standard:corretto8' |
|
|
22
|
+
'aws/codebuild/amazonlinux-x86_64-standard:corretto11' |
|
|
23
|
+
'aws/codebuild/amazonlinux-aarch64-standard:2.0' |
|
|
24
|
+
'aws/codebuild/amazonlinux-aarch64-standard:3.0' |
|
|
25
|
+
'aws/codebuild/standard:3.0' |
|
|
26
|
+
'aws/codebuild/standard:4.0' |
|
|
27
|
+
'aws/codebuild/standard:5.0' | // nodejs 12, 14
|
|
28
|
+
'aws/codebuild/standard:6.0' | // nodejs 16
|
|
29
|
+
'aws/codebuild/standard:7.0' | // nodejs 18, 20, 22, 24
|
|
30
|
+
'aws/codebuild/standard:8.0' | // nodejs 22, 24
|
|
31
|
+
'aws/codebuild/windows-base:2019-1.0' |
|
|
32
|
+
'aws/codebuild/windows-base:2019-2.0' |
|
|
33
|
+
'aws/codebuild/windows-base:2019-3.0' |
|
|
34
|
+
'aws/codebuild/windows-base:2022-1.0' |
|
|
35
|
+
(string & {});
|
|
36
|
+
|
|
37
|
+
export type CodeBuildComputeType = 'SMALL' | 'MEDIUM' | 'LARGE' | 'X_LARGE' | 'X2_LARGE' | (string & {});
|
|
38
|
+
export type CodeBuildNodeJs = 12 | 14 | 16 | 18 | 20 | 22 | 24 | (number & {});
|
|
39
|
+
|
|
40
|
+
export interface CodeBuildSsmParameter extends SsmStringParameter {
|
|
15
41
|
encrypted?: boolean;
|
|
16
42
|
}
|
|
17
43
|
export interface EcrBuildImage {
|
|
@@ -21,13 +47,15 @@ export interface EcrBuildImage {
|
|
|
21
47
|
export interface CodeBuildPipelineProjectProps extends ResourceProps {
|
|
22
48
|
projectName?: string;
|
|
23
49
|
buildSpec?: string | object;
|
|
24
|
-
buildImage?: ('STANDARD_5_0' | 'STANDARD_6_0' | 'STANDARD_7_0') | IBuildImage;
|
|
25
50
|
ecrBuildImage?: EcrBuildImage,
|
|
26
|
-
|
|
51
|
+
buildImage?: IBuildImage;
|
|
52
|
+
buildImageNodeJS?: CodeBuildNodeJs;
|
|
53
|
+
buildImageId?: CodeBuildImageId;
|
|
54
|
+
computeType?: CodeBuildComputeType;
|
|
27
55
|
environmentVariables?: EnvironmentVariables;
|
|
28
56
|
cloudFrontDistributionArn?: string;
|
|
29
57
|
s3BucketName?: string;
|
|
30
|
-
ssmParameters?:
|
|
58
|
+
ssmParameters?: CodeBuildSsmParameter[];
|
|
31
59
|
}
|
|
32
60
|
|
|
33
61
|
export class CodeBuildPipelineProject extends Construct {
|
|
@@ -58,12 +86,27 @@ export class CodeBuildPipelineProject extends Construct {
|
|
|
58
86
|
Repository.fromRepositoryName(this, 'EcrRepository', props.ecrBuildImage.repository);
|
|
59
87
|
buildImage = LinuxBuildImage.fromEcrRepository(repository, props.ecrBuildImage.tag);
|
|
60
88
|
} else if (props.buildImage) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
89
|
+
buildImage = props.buildImage as IBuildImage;
|
|
90
|
+
} else if (props.buildImageNodeJS) {
|
|
91
|
+
let standard = 8;
|
|
92
|
+
switch (props.buildImageNodeJS) {
|
|
93
|
+
case 12:
|
|
94
|
+
case 14:
|
|
95
|
+
standard = 5;
|
|
96
|
+
break;
|
|
97
|
+
case 16:
|
|
98
|
+
standard = 6;
|
|
99
|
+
break;
|
|
100
|
+
case 18:
|
|
101
|
+
case 20:
|
|
102
|
+
standard = 7;
|
|
103
|
+
break;
|
|
65
104
|
}
|
|
66
|
-
|
|
105
|
+
buildImage = LinuxBuildImage.fromCodeBuildImageId(`aws/codebuild/standard:${standard}.0`);
|
|
106
|
+
} else if (props.buildImageId) {
|
|
107
|
+
buildImage = LinuxBuildImage.fromCodeBuildImageId(props.buildImageId);
|
|
108
|
+
}
|
|
109
|
+
|
|
67
110
|
|
|
68
111
|
this.project = new PipelineProject(this, 'CodeBuildPipelineProjectProps', {
|
|
69
112
|
projectName: props.projectName,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RemovalPolicy, PhysicalName, Aws } from "aws-cdk-lib";
|
|
2
2
|
import { Construct } from 'constructs';
|
|
3
3
|
import { IProject } from "aws-cdk-lib/aws-codebuild";
|
|
4
|
-
import { Artifact, Pipeline } from "aws-cdk-lib/aws-codepipeline";
|
|
4
|
+
import { Artifact, Pipeline, PipelineType } from "aws-cdk-lib/aws-codepipeline";
|
|
5
5
|
import { CodeBuildAction, CodeStarConnectionsSourceAction } from "aws-cdk-lib/aws-codepipeline-actions";
|
|
6
6
|
import { Bucket } from 'aws-cdk-lib/aws-s3';
|
|
7
7
|
import { StringParameter } from 'aws-cdk-lib/aws-ssm';
|
|
@@ -45,7 +45,8 @@ export class CodePipelineProject extends Construct {
|
|
|
45
45
|
|
|
46
46
|
this.pipeline = new Pipeline(this, 'CodePipelineProject', {
|
|
47
47
|
pipelineName: props.pipelineName,
|
|
48
|
-
artifactBucket: this.s3Bucket
|
|
48
|
+
artifactBucket: this.s3Bucket,
|
|
49
|
+
pipelineType: PipelineType.V2
|
|
49
50
|
});
|
|
50
51
|
|
|
51
52
|
tagResource(this.pipeline, props.tags);
|
package/src/index.ts
CHANGED
|
@@ -17,18 +17,7 @@ import { CloudFrontWebAcl } from '../../constructs/waf.js';
|
|
|
17
17
|
import { domainAsId } from '../../lib/utils.js';
|
|
18
18
|
import { addEvoStackTags } from '../../lib/tags.ts';
|
|
19
19
|
import { S3BucketOrigin } from 'aws-cdk-lib/aws-cloudfront-origins';
|
|
20
|
-
import type { BasicAuthCredentials, CspHeaders } from '../../types.d.ts';
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
type AWSManagedResponseHeadersPolicy =
|
|
24
|
-
'CORS_ALLOW_ALL_ORIGINS' |
|
|
25
|
-
'CORS_ALLOW_ALL_ORIGINS_AND_SECURITY_HEADERS' |
|
|
26
|
-
'CORS_ALLOW_ALL_ORIGINS_WITH_PREFLIGHT' |
|
|
27
|
-
'CORS_ALLOW_ALL_ORIGINS_WITH_PREFLIGHT_AND_SECURITY_HEADERS' |
|
|
28
|
-
'SECURITY_HEADERS';
|
|
29
|
-
|
|
30
|
-
type UUID = `${string}-${string}-${string}-${string}-${string}`;
|
|
31
|
-
type CloudFrontFunctionEventType = keyof typeof FunctionEventType;
|
|
20
|
+
import type { BasicAuthCredentials, CspHeaders, CloudFrontFunctionEventType, UUID, AWSManagedResponseHeadersPolicy } from '../../types.d.ts';
|
|
32
21
|
|
|
33
22
|
export interface WebGlobalStackProps {
|
|
34
23
|
envType: 'NOT_PROD' | 'PROD';
|
|
@@ -38,14 +27,14 @@ export interface WebGlobalStackProps {
|
|
|
38
27
|
domainName: string;
|
|
39
28
|
basicAuth?: string | BasicAuthCredentials | SsmStringParameter;
|
|
40
29
|
cloudfrontFunction?: {
|
|
41
|
-
eventType: CloudFrontFunctionEventType[];
|
|
42
30
|
code: string;
|
|
31
|
+
eventType: CloudFrontFunctionEventType[];
|
|
43
32
|
}
|
|
44
33
|
redirects?: CloudFrontFunctionRedirects;
|
|
45
34
|
redirectsCsvPath?: string;
|
|
46
35
|
// attachWebAcl?: boolean | string;
|
|
47
36
|
webAcl?: boolean | string | SsmStringParameter;
|
|
48
|
-
responseHeadersPolicy?: false | AWSManagedResponseHeadersPolicy |
|
|
37
|
+
responseHeadersPolicy?: false | AWSManagedResponseHeadersPolicy | UUID | SsmStringParameter;
|
|
49
38
|
responseHeadersPolicyProps?: ResponseHeadersPolicyProps;
|
|
50
39
|
responseCspHeaders?: CspHeaders;
|
|
51
40
|
destroy?: boolean;
|
|
@@ -82,69 +71,65 @@ export class WebGlobalStack extends Stack {
|
|
|
82
71
|
this.s3Bucket = _s3Bucket.bucket;
|
|
83
72
|
|
|
84
73
|
let responseHeadersPolicy: IResponseHeadersPolicy | undefined = undefined;
|
|
85
|
-
if (props.responseHeadersPolicy
|
|
86
|
-
if (props.responseHeadersPolicy) {
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
responseHeadersPolicy = ResponseHeadersPolicy[props.responseHeadersPolicy as keyof typeof ResponseHeadersPolicy] as IResponseHeadersPolicy ?? ResponseHeadersPolicy.SECURITY_HEADERS;
|
|
92
|
-
}
|
|
93
|
-
} else if (props.responseHeadersPolicy.path) {
|
|
94
|
-
responseHeadersPolicy = ResponseHeadersPolicy.fromResponseHeadersPolicyId(this, 'response-headers-policy-by-id', StringParameter.valueForStringParameter(this, props.responseHeadersPolicy.path, props.responseHeadersPolicy.version));
|
|
74
|
+
if (props.responseHeadersPolicy) {
|
|
75
|
+
if (typeof props.responseHeadersPolicy == 'string') {
|
|
76
|
+
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)) {
|
|
77
|
+
responseHeadersPolicy = ResponseHeadersPolicy.fromResponseHeadersPolicyId(this, 'response-headers-policy-by-id', props.responseHeadersPolicy);
|
|
78
|
+
} else {
|
|
79
|
+
responseHeadersPolicy = ResponseHeadersPolicy[props.responseHeadersPolicy as keyof typeof ResponseHeadersPolicy] as IResponseHeadersPolicy ?? ResponseHeadersPolicy.SECURITY_HEADERS;
|
|
95
80
|
}
|
|
81
|
+
} else if (props.responseHeadersPolicy.path) {
|
|
82
|
+
responseHeadersPolicy = ResponseHeadersPolicy.fromResponseHeadersPolicyId(this, 'response-headers-policy-by-id', StringParameter.valueForStringParameter(this, props.responseHeadersPolicy.path, props.responseHeadersPolicy.version));
|
|
96
83
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
// }
|
|
119
|
-
// };
|
|
120
|
-
|
|
121
|
-
const responseHeadersPolicyName = `${domainAsId(props.domainName)}-response-headers-policy`;
|
|
122
|
-
|
|
123
|
-
if (props.responseHeadersPolicyProps) {
|
|
124
|
-
responseHeadersPolicy = new ResponseHeadersPolicy(this, 'response-headers-policy', {
|
|
125
|
-
...ResponseHeadersPolicy.SECURITY_HEADERS,
|
|
126
|
-
...props.responseHeadersPolicyProps,
|
|
127
|
-
responseHeadersPolicyName: props.responseHeadersPolicyProps.responseHeadersPolicyName || responseHeadersPolicyName
|
|
128
|
-
});
|
|
129
|
-
} else if (props.responseCspHeaders) {
|
|
130
|
-
responseHeadersPolicy = new ResponseHeadersPolicy(this, 'response-headers-policy', {
|
|
131
|
-
securityHeadersBehavior: {
|
|
132
|
-
...ResponseHeadersPolicy.SECURITY_HEADERS,
|
|
133
|
-
contentSecurityPolicy: {
|
|
134
|
-
override: true,
|
|
135
|
-
contentSecurityPolicy: Object.entries(props.responseCspHeaders).map(([directive, values]) => {
|
|
136
|
-
return `${directive} ${values.join(' ')};`
|
|
137
|
-
}).join(' ')
|
|
138
|
-
},
|
|
139
|
-
},
|
|
140
|
-
responseHeadersPolicyName
|
|
141
|
-
});
|
|
142
|
-
} else {
|
|
143
|
-
responseHeadersPolicy = ResponseHeadersPolicy.SECURITY_HEADERS;
|
|
84
|
+
} else {
|
|
85
|
+
const baseHeadersBehavior: ResponseSecurityHeadersBehavior = {
|
|
86
|
+
strictTransportSecurity: {
|
|
87
|
+
override: true,
|
|
88
|
+
accessControlMaxAge: Duration.seconds(31536000)
|
|
89
|
+
},
|
|
90
|
+
contentTypeOptions: {
|
|
91
|
+
override: true
|
|
92
|
+
},
|
|
93
|
+
frameOptions: {
|
|
94
|
+
override: true,
|
|
95
|
+
frameOption: HeadersFrameOption.SAMEORIGIN,
|
|
96
|
+
},
|
|
97
|
+
referrerPolicy: {
|
|
98
|
+
override: true,
|
|
99
|
+
referrerPolicy: HeadersReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN
|
|
100
|
+
},
|
|
101
|
+
xssProtection: {
|
|
102
|
+
override: true,
|
|
103
|
+
protection: true,
|
|
104
|
+
modeBlock: true
|
|
144
105
|
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const responseHeadersPolicyName = `${domainAsId(props.domainName)}-response-headers-policy`;
|
|
109
|
+
|
|
110
|
+
if (props.responseHeadersPolicyProps) {
|
|
111
|
+
responseHeadersPolicy = new ResponseHeadersPolicy(this, 'response-headers-policy', {
|
|
112
|
+
...baseHeadersBehavior,
|
|
113
|
+
...props.responseHeadersPolicyProps,
|
|
114
|
+
responseHeadersPolicyName: props.responseHeadersPolicyProps.responseHeadersPolicyName || responseHeadersPolicyName
|
|
115
|
+
});
|
|
116
|
+
} else if (props.responseCspHeaders) {
|
|
117
|
+
responseHeadersPolicy = new ResponseHeadersPolicy(this, 'response-headers-policy', {
|
|
118
|
+
securityHeadersBehavior: {
|
|
119
|
+
...baseHeadersBehavior,
|
|
120
|
+
contentSecurityPolicy: {
|
|
121
|
+
override: true,
|
|
122
|
+
contentSecurityPolicy: Object.entries(props.responseCspHeaders).map(([directive, values]) => {
|
|
123
|
+
return `${directive} ${values.join(' ')};`
|
|
124
|
+
}).join(' ')
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
responseHeadersPolicyName
|
|
128
|
+
});
|
|
145
129
|
}
|
|
146
|
-
this.responseHeadersPolicy = responseHeadersPolicy;
|
|
147
130
|
}
|
|
131
|
+
// TODO: Figure out why the the policy is not getting updated in the CloudFront behavior
|
|
132
|
+
this.responseHeadersPolicy = responseHeadersPolicy;
|
|
148
133
|
|
|
149
134
|
const defaultBehavior: BehaviorOptions = {
|
|
150
135
|
origin: S3BucketOrigin.withOriginAccessControl(this.s3Bucket),
|
package/src/types.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
|
|
2
|
+
import { FunctionEventType } from 'aws-cdk-lib/aws-cloudfront';
|
|
3
|
+
|
|
1
4
|
export type DeepPartial<T> = T extends object ? {
|
|
2
5
|
[P in keyof T]?: DeepPartial<T[P]>;
|
|
3
6
|
} : T;
|
|
@@ -6,6 +9,11 @@ export type WithRequiredProperty<Type, Key extends keyof Type> = Omit<Type, Key>
|
|
|
6
9
|
[Property in Key]-?: Type[Property];
|
|
7
10
|
};
|
|
8
11
|
|
|
12
|
+
export type UUID = `${string}-${string}-${string}-${string}-${string}`; // & { readonly __brand: unique symbol };
|
|
13
|
+
|
|
14
|
+
export type EvosynthTagKey = 'Account' | 'Brand' | (string & {});
|
|
15
|
+
export type CloudFrontFunctionEventType = keyof typeof FunctionEventType;
|
|
16
|
+
|
|
9
17
|
export interface ResourceProps {
|
|
10
18
|
destroy?: boolean;
|
|
11
19
|
tags?: Record<string, string>;
|
|
@@ -18,4 +26,11 @@ export interface BasicAuthCredentials {
|
|
|
18
26
|
|
|
19
27
|
export type CspDirective = 'connect-src' | 'default-src' | 'font-src' | 'frame-src' | 'img-src' | 'media-src' | 'object-src' | 'script-src' | 'style-src';
|
|
20
28
|
export type CspDirectiveValue = "'self'" | "'none'" | "'unsafe-inline'" | "https:";
|
|
21
|
-
export type CspHeaders = Partial<Record<CspDirective, CspDirectiveValue[] | string[]>>;
|
|
29
|
+
export type CspHeaders = Partial<Record<CspDirective, CspDirectiveValue[] | string[]>>;
|
|
30
|
+
|
|
31
|
+
export type AWSManagedResponseHeadersPolicy =
|
|
32
|
+
'CORS_ALLOW_ALL_ORIGINS' |
|
|
33
|
+
'CORS_ALLOW_ALL_ORIGINS_AND_SECURITY_HEADERS' |
|
|
34
|
+
'CORS_ALLOW_ALL_ORIGINS_WITH_PREFLIGHT' |
|
|
35
|
+
'CORS_ALLOW_ALL_ORIGINS_WITH_PREFLIGHT_AND_SECURITY_HEADERS' |
|
|
36
|
+
'SECURITY_HEADERS';
|