sst 2.0.0-rc.9 → 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/bootstrap.d.ts +2 -4
- package/bootstrap.js +208 -61
- package/bus.d.ts +3 -3
- package/bus.js +1 -1
- package/cache.js +1 -1
- package/cdk/cloudformation-deployments-wrapper.d.ts +3 -0
- package/cdk/cloudformation-deployments-wrapper.js +117 -0
- package/cdk/cloudformation-deployments.d.ts +19 -4
- package/cdk/deploy-stack.d.ts +17 -2
- package/cdk/deploy-stack.js +6 -1
- package/cli/colors.d.ts +28 -0
- package/cli/colors.js +27 -0
- package/cli/commands/bind.d.ts +4 -0
- package/cli/commands/bind.js +10 -7
- package/cli/commands/bootstrap.d.ts +13 -0
- package/cli/commands/bootstrap.js +11 -0
- package/cli/commands/build.d.ts +6 -2
- package/cli/commands/build.js +13 -8
- package/cli/commands/console.d.ts +5 -1
- package/cli/commands/console.js +8 -6
- package/cli/commands/deploy.d.ts +4 -2
- package/cli/commands/deploy.js +69 -29
- package/cli/commands/dev.d.ts +5 -1
- package/cli/commands/dev.js +157 -79
- package/cli/commands/diff.d.ts +15 -0
- package/cli/commands/diff.js +61 -0
- package/cli/commands/env.d.ts +5 -1
- package/cli/commands/env.js +14 -15
- package/cli/commands/plugins/kysely.js +13 -5
- package/cli/commands/plugins/pothos.js +9 -4
- package/cli/commands/remove.d.ts +4 -0
- package/cli/commands/remove.js +26 -18
- package/cli/commands/secrets/get.d.ts +7 -3
- package/cli/commands/secrets/get.js +11 -24
- package/cli/commands/secrets/list.d.ts +6 -2
- package/cli/commands/secrets/list.js +15 -7
- package/cli/commands/secrets/remove.d.ts +8 -4
- package/cli/commands/secrets/remove.js +18 -16
- package/cli/commands/secrets/secrets.js +3 -3
- package/cli/commands/secrets/set.d.ts +8 -6
- package/cli/commands/secrets/set.js +16 -33
- package/cli/commands/telemetry.d.ts +15 -0
- package/cli/commands/telemetry.js +17 -0
- package/cli/commands/transform.d.ts +15 -0
- package/cli/commands/transform.js +55 -0
- package/cli/commands/update.d.ts +6 -2
- package/cli/commands/update.js +41 -33
- package/cli/commands/version.d.ts +13 -0
- package/cli/commands/version.js +7 -0
- package/cli/local/router.d.ts +6 -6
- package/cli/local/router.js +3 -3
- package/cli/local/server.d.ts +5 -3
- package/cli/local/server.js +21 -14
- package/cli/program.d.ts +5 -1
- package/cli/program.js +29 -5
- package/cli/spinner.js +2 -0
- package/cli/sst.js +35 -23
- package/cli/telemetry/environment.d.ts +1 -1
- package/cli/telemetry/environment.js +1 -1
- package/cli/terminal.d.ts +1 -0
- package/cli/terminal.js +8 -0
- package/cli/ui/deploy.d.ts +3 -2
- package/cli/ui/deploy.js +106 -106
- package/cli/ui/functions.d.ts +2 -0
- package/cli/ui/functions.js +132 -0
- package/cli/ui/header.d.ts +5 -0
- package/cli/ui/header.js +16 -0
- package/cli/ui/stack.d.ts +1 -0
- package/cli/ui/stack.js +6 -0
- package/config.d.ts +1 -1
- package/config.js +8 -8
- package/constructs/Api.d.ts +3 -71
- package/constructs/Api.js +3 -42
- package/constructs/ApiGatewayV1Api.d.ts +3 -3
- package/constructs/ApiGatewayV1Api.js +4 -3
- package/constructs/App.d.ts +2 -22
- package/constructs/App.js +12 -25
- package/constructs/AppSyncApi.d.ts +4 -5
- package/constructs/AppSyncApi.js +8 -5
- package/constructs/AstroSite.d.ts +2 -3
- package/constructs/AstroSite.js +43 -53
- package/constructs/Auth.js +27 -16
- package/constructs/BaseSite.d.ts +10 -10
- package/constructs/BaseSite.js +2 -2
- package/constructs/Cognito.js +28 -28
- package/constructs/EdgeFunction.d.ts +6 -4
- package/constructs/EdgeFunction.js +56 -59
- package/constructs/EventBus.js +1 -1
- package/constructs/Function.d.ts +4 -44
- package/constructs/Function.js +14 -50
- package/constructs/FunctionalStack.d.ts +2 -2
- package/constructs/Job.d.ts +23 -63
- package/constructs/Job.js +11 -32
- package/constructs/Metadata.d.ts +18 -20
- package/constructs/NextjsSite.d.ts +21 -5
- package/constructs/NextjsSite.js +67 -101
- package/constructs/Queue.js +10 -10
- package/constructs/RDS.d.ts +1 -1
- package/constructs/RDS.js +1 -1
- package/constructs/RemixSite.d.ts +0 -2
- package/constructs/RemixSite.js +20 -20
- package/constructs/Script.js +1 -1
- package/constructs/Secret.js +5 -3
- package/constructs/SolidStartSite.d.ts +2 -3
- package/constructs/SolidStartSite.js +42 -52
- package/constructs/SsrFunction.d.ts +22 -0
- package/constructs/SsrFunction.js +113 -0
- package/constructs/SsrSite.d.ts +104 -104
- package/constructs/SsrSite.js +196 -217
- package/constructs/Stack.d.ts +1 -20
- package/constructs/Stack.js +3 -65
- package/constructs/StaticSite.d.ts +33 -53
- package/constructs/StaticSite.js +92 -118
- package/constructs/Table.d.ts +1 -1
- package/constructs/Table.js +4 -4
- package/constructs/Topic.js +1 -1
- package/constructs/cdk/certificate-base.d.ts +18 -0
- package/constructs/cdk/certificate-base.js +26 -0
- package/constructs/cdk/dns-validated-certificate.d.ts +77 -0
- package/constructs/cdk/dns-validated-certificate.js +125 -0
- package/constructs/cdk/website-redirect.d.ts +53 -0
- package/constructs/cdk/website-redirect.js +77 -0
- package/constructs/deferred_task.d.ts +1 -1
- package/constructs/deprecated/NextjsSite.js +8 -6
- package/constructs/index.d.ts +0 -6
- package/constructs/index.js +0 -6
- package/constructs/util/apiGatewayV1AccessLog.d.ts +1 -1
- package/constructs/util/apiGatewayV2AccessLog.js +4 -4
- package/constructs/util/apiGatewayV2Domain.js +9 -2
- package/constructs/util/appSyncApiDomain.d.ts +1 -1
- package/constructs/util/appSyncApiDomain.js +9 -15
- package/constructs/util/duration.d.ts +1 -1
- package/constructs/util/functionBinding.js +1 -1
- package/constructs/util/permission.d.ts +3 -3
- package/constructs/util/permission.js +16 -18
- package/constructs/util/size.d.ts +1 -1
- package/constructs/util/warning.js +2 -2
- package/context/context.d.ts +2 -2
- package/context/context.js +4 -4
- package/context/handler.d.ts +1 -1
- package/credentials.d.ts +1 -1
- package/credentials.js +42 -6
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/iot.js +6 -2
- package/logger.js +3 -1
- package/node/api/index.d.ts +2 -3
- package/node/api/index.js +8 -2
- package/node/auth/adapter/adapter.d.ts +1 -1
- package/node/auth/adapter/facebook.js +1 -1
- package/node/auth/adapter/github.js +4 -4
- package/node/auth/adapter/google.d.ts +1 -1
- package/node/auth/adapter/google.js +2 -2
- package/node/auth/adapter/twitch.js +1 -1
- package/node/auth/session.d.ts +1 -1
- package/node/config/index.d.ts +2 -2
- package/node/config/index.js +3 -8
- package/node/job/index.d.ts +2 -2
- package/node/site/index.js +3 -5
- package/package.json +26 -21
- package/pothos.js +1 -0
- package/project.d.ts +47 -0
- package/{app.js → project.js} +60 -53
- package/runtime/handlers/dotnet.d.ts +1 -1
- package/runtime/handlers/dotnet.js +4 -4
- package/runtime/handlers/go.d.ts +1 -1
- package/runtime/handlers/go.js +3 -3
- package/runtime/handlers/java.d.ts +1 -1
- package/runtime/handlers/java.js +4 -4
- package/runtime/handlers/node.d.ts +1 -1
- package/runtime/handlers/node.js +60 -39
- package/runtime/handlers/python.d.ts +1 -1
- package/runtime/handlers/python.js +3 -3
- package/runtime/handlers.js +15 -12
- package/runtime/iot.js +3 -0
- package/runtime/runtime.d.ts +4 -0
- package/runtime/server.d.ts +3 -3
- package/runtime/server.js +11 -5
- package/runtime/workers.d.ts +4 -2
- package/runtime/workers.js +13 -3
- package/site-env.js +2 -1
- package/sst.mjs +6357 -20848
- package/stacks/app-metadata.d.ts +7 -0
- package/stacks/app-metadata.js +78 -0
- package/stacks/assembly.d.ts +1 -0
- package/stacks/assembly.js +4 -0
- package/stacks/build.d.ts +1 -1
- package/stacks/build.js +41 -48
- package/stacks/deploy.d.ts +1 -0
- package/stacks/deploy.js +128 -7
- package/stacks/diff.d.ts +8 -0
- package/stacks/diff.js +62 -0
- package/stacks/index.d.ts +3 -0
- package/stacks/index.js +3 -0
- package/stacks/metadata.d.ts +2 -0
- package/stacks/metadata.js +14 -12
- package/stacks/monitor.d.ts +8 -3
- package/stacks/monitor.js +38 -4
- package/stacks/remove.js +0 -4
- package/stacks/synth.d.ts +1 -0
- package/stacks/synth.js +27 -13
- package/support/base-site-archiver.mjs +1 -1
- package/support/bootstrap-metadata-function/index.mjs +68740 -0
- package/support/bridge/bridge.mjs +28 -28
- package/support/certificate-requestor/index.js +549 -0
- package/support/custom-resources/index.mjs +3824 -26567
- package/support/dotnet6-bootstrap/release/dotnet-bootstrap.deps.json +1 -1
- package/support/dotnet6-bootstrap/release/dotnet-bootstrap.runtimeconfig.json +1 -1
- package/support/edge-function/edge-lambda.mjs +2 -2
- package/support/job-invoker/index.mjs +26 -0
- package/support/nodejs-runtime/index.mjs +75 -72
- package/support/rds-migrator/index.mjs +22 -23
- package/support/remix-site-function/edge-server.js +1 -1
- package/support/script-function/index.mjs +30485 -0
- package/support/{edge-function-code-replacer → sls-nextjs-site-function-code-replacer}/lambda-code-updater.py +0 -0
- package/support/ssr-site-function-archiver.mjs +96 -0
- package/watcher.js +1 -1
- package/app.d.ts +0 -36
- package/constructs/DebugApp.d.ts +0 -49
- package/constructs/DebugApp.js +0 -63
- package/constructs/DebugStack.d.ts +0 -34
- package/constructs/DebugStack.js +0 -132
- package/constructs/GraphQLApi.d.ts +0 -98
- package/constructs/GraphQLApi.js +0 -80
- package/constructs/ReactStaticSite.d.ts +0 -20
- package/constructs/ReactStaticSite.js +0 -54
- package/constructs/Script/cfn-response.d.ts +0 -19
- package/constructs/Script/cfn-response.js +0 -77
- package/constructs/Script/index.d.ts +0 -1
- package/constructs/Script/index.js +0 -78
- package/constructs/Script/outbound.d.ts +0 -10
- package/constructs/Script/outbound.js +0 -42
- package/constructs/Script/util.d.ts +0 -2
- package/constructs/Script/util.js +0 -11
- package/constructs/ViteStaticSite.d.ts +0 -32
- package/constructs/ViteStaticSite.js +0 -66
- package/support/astro-site-html-stub/index.html +0 -99
- package/support/base-site-archiver.cjs +0 -116
- package/support/nextjs-site-html-stub/index.html +0 -99
- package/support/remix-site-html-stub/index.html +0 -99
- package/support/solid-start-site-html-stub/index.html +0 -99
- package/support/static-site-stub/index.html +0 -90
package/constructs/StaticSite.js
CHANGED
|
@@ -7,22 +7,23 @@ import { Construct } from "constructs";
|
|
|
7
7
|
import { Token, Duration, CfnOutput, RemovalPolicy, CustomResource, } from "aws-cdk-lib";
|
|
8
8
|
import * as s3 from "aws-cdk-lib/aws-s3";
|
|
9
9
|
import * as s3Assets from "aws-cdk-lib/aws-s3-assets";
|
|
10
|
-
import * as acm from "aws-cdk-lib/aws-certificatemanager";
|
|
11
10
|
import * as iam from "aws-cdk-lib/aws-iam";
|
|
12
11
|
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
13
12
|
import * as route53 from "aws-cdk-lib/aws-route53";
|
|
14
|
-
import * as route53Patterns from "aws-cdk-lib/aws-route53-patterns";
|
|
15
13
|
import * as route53Targets from "aws-cdk-lib/aws-route53-targets";
|
|
16
14
|
import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
|
|
17
15
|
import * as cfOrigins from "aws-cdk-lib/aws-cloudfront-origins";
|
|
18
16
|
import { AwsCliLayer } from "aws-cdk-lib/lambda-layer-awscli";
|
|
19
17
|
import { Stack } from "./Stack.js";
|
|
20
18
|
import { getBuildCmdEnvironment, buildErrorResponsesFor404ErrorPage, buildErrorResponsesForRedirectToIndex, } from "./BaseSite.js";
|
|
19
|
+
import { HttpsRedirect } from "./cdk/website-redirect.js";
|
|
20
|
+
import { DnsValidatedCertificate } from "./cdk/dns-validated-certificate.js";
|
|
21
21
|
import { isCDKConstruct } from "./Construct.js";
|
|
22
22
|
import { ENVIRONMENT_PLACEHOLDER, getParameterPath, } from "./util/functionBinding.js";
|
|
23
23
|
import { gray } from "colorette";
|
|
24
|
-
import { useProject } from "../
|
|
24
|
+
import { useProject } from "../project.js";
|
|
25
25
|
import { SiteEnv } from "../site-env.js";
|
|
26
|
+
import { VisibleError } from "../error.js";
|
|
26
27
|
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
|
|
27
28
|
/////////////////////
|
|
28
29
|
// Construct
|
|
@@ -44,49 +45,53 @@ const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
|
|
|
44
45
|
*/
|
|
45
46
|
export class StaticSite extends Construct {
|
|
46
47
|
id;
|
|
47
|
-
cdk;
|
|
48
48
|
props;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
doNotDeploy;
|
|
50
|
+
bucket;
|
|
51
|
+
distribution;
|
|
52
|
+
hostedZone;
|
|
53
|
+
certificate;
|
|
53
54
|
constructor(scope, id, props) {
|
|
54
|
-
super(scope, props
|
|
55
|
+
super(scope, props?.cdk?.id || id);
|
|
56
|
+
const app = scope.node.root;
|
|
55
57
|
this.id = id;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
// @ts-ignore: "sstTestFileSizeLimitOverride" not exposed in props
|
|
63
|
-
props.sstTestFileSizeLimitOverride || 200
|
|
64
|
-
: 200;
|
|
65
|
-
this.props = props;
|
|
66
|
-
this.cdk = {};
|
|
67
|
-
this.awsCliLayer = new AwsCliLayer(this, "AwsCliLayer");
|
|
68
|
-
this.registerSiteEnvironment();
|
|
69
|
-
// Validate input
|
|
58
|
+
this.props = {
|
|
59
|
+
path: ".",
|
|
60
|
+
waitForInvalidation: false,
|
|
61
|
+
...props,
|
|
62
|
+
};
|
|
63
|
+
this.doNotDeploy = (app.local || app.skipBuild) && !this.props.dev?.deploy;
|
|
70
64
|
this.validateCustomDomainSettings();
|
|
71
|
-
|
|
65
|
+
this.registerSiteEnvironment();
|
|
72
66
|
this.generateViteTypes();
|
|
67
|
+
if (this.doNotDeploy) {
|
|
68
|
+
// @ts-ignore
|
|
69
|
+
this.bucket = this.distribution = null;
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const cliLayer = new AwsCliLayer(this, "AwsCliLayer");
|
|
73
73
|
// Build app
|
|
74
|
+
const fileSizeLimit = app.isRunningSSTTest()
|
|
75
|
+
? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
76
|
+
// @ts-ignore: "sstTestFileSizeLimitOverride" not exposed in props
|
|
77
|
+
this.props.sstTestFileSizeLimitOverride || 200
|
|
78
|
+
: 200;
|
|
74
79
|
this.buildApp();
|
|
75
|
-
|
|
76
|
-
|
|
80
|
+
const assets = this.bundleAssets(fileSizeLimit);
|
|
81
|
+
const filenamesAsset = this.bundleFilenamesAsset();
|
|
77
82
|
// Create Bucket
|
|
78
|
-
this.
|
|
83
|
+
this.bucket = this.createS3Bucket();
|
|
79
84
|
// Create Custom Domain
|
|
80
|
-
this.
|
|
81
|
-
this.
|
|
85
|
+
this.hostedZone = this.lookupHostedZone();
|
|
86
|
+
this.certificate = this.createCertificate();
|
|
82
87
|
// Create S3 Deployment
|
|
83
|
-
const s3deployCR = this.createS3Deployment();
|
|
88
|
+
const s3deployCR = this.createS3Deployment(cliLayer, assets, filenamesAsset);
|
|
84
89
|
// Create CloudFront
|
|
85
|
-
this.
|
|
86
|
-
this.
|
|
90
|
+
this.distribution = this.createCfDistribution();
|
|
91
|
+
this.distribution.node.addDependency(s3deployCR);
|
|
87
92
|
// Invalidate CloudFront
|
|
88
|
-
const invalidationCR = this.createCloudFrontInvalidation();
|
|
89
|
-
invalidationCR.node.addDependency(this.
|
|
93
|
+
const invalidationCR = this.createCloudFrontInvalidation(cliLayer, assets);
|
|
94
|
+
invalidationCR.node.addDependency(this.distribution);
|
|
90
95
|
// Connect Custom Domain to CloudFront Distribution
|
|
91
96
|
this.createRoute53Records();
|
|
92
97
|
}
|
|
@@ -94,12 +99,18 @@ export class StaticSite extends Construct {
|
|
|
94
99
|
* The CloudFront URL of the website.
|
|
95
100
|
*/
|
|
96
101
|
get url() {
|
|
97
|
-
|
|
102
|
+
if (this.doNotDeploy) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
return `https://${this.distribution.distributionDomainName}`;
|
|
98
106
|
}
|
|
99
107
|
/**
|
|
100
108
|
* If the custom domain is enabled, this is the URL of the website with the custom domain.
|
|
101
109
|
*/
|
|
102
110
|
get customDomainUrl() {
|
|
111
|
+
if (this.doNotDeploy) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
103
114
|
const { customDomain } = this.props;
|
|
104
115
|
if (!customDomain) {
|
|
105
116
|
return;
|
|
@@ -112,34 +123,23 @@ export class StaticSite extends Construct {
|
|
|
112
123
|
}
|
|
113
124
|
}
|
|
114
125
|
/**
|
|
115
|
-
* The
|
|
116
|
-
*/
|
|
117
|
-
get bucketArn() {
|
|
118
|
-
return this.cdk.bucket.bucketArn;
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* The name of the internally created S3 Bucket.
|
|
126
|
+
* The internally created CDK resources.
|
|
122
127
|
*/
|
|
123
|
-
get
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
* The domain name of the internally created CloudFront Distribution.
|
|
134
|
-
*/
|
|
135
|
-
get distributionDomain() {
|
|
136
|
-
return this.cdk.distribution.distributionDomainName;
|
|
128
|
+
get cdk() {
|
|
129
|
+
if (this.doNotDeploy) {
|
|
130
|
+
throw new VisibleError(`Cannot access CDK resources for the "${this.node.id}" site in dev mode`);
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
bucket: this.bucket,
|
|
134
|
+
distribution: this.distribution,
|
|
135
|
+
hostedZone: this.hostedZone,
|
|
136
|
+
certificate: this.certificate,
|
|
137
|
+
};
|
|
137
138
|
}
|
|
138
139
|
getConstructMetadata() {
|
|
139
140
|
return {
|
|
140
141
|
type: "StaticSite",
|
|
141
142
|
data: {
|
|
142
|
-
distributionId: this.cdk.distribution.distributionId,
|
|
143
143
|
customDomainUrl: this.customDomainUrl,
|
|
144
144
|
},
|
|
145
145
|
};
|
|
@@ -155,13 +155,13 @@ export class StaticSite extends Construct {
|
|
|
155
155
|
// depend on the Site. B/c often the site depends on the Api, causing
|
|
156
156
|
// a CloudFormation circular dependency if the Api and the Site belong
|
|
157
157
|
// to different stacks.
|
|
158
|
-
environment: ENVIRONMENT_PLACEHOLDER,
|
|
158
|
+
environment: this.doNotDeploy ? "" : ENVIRONMENT_PLACEHOLDER,
|
|
159
159
|
parameter: this.customDomainUrl || this.url,
|
|
160
160
|
},
|
|
161
161
|
},
|
|
162
162
|
permissions: {
|
|
163
163
|
"ssm:GetParameters": [
|
|
164
|
-
`arn:
|
|
164
|
+
`arn:${Stack.of(this).partition}:ssm:${app.region}:${app.account}:parameter${getParameterPath(this, "url")}`,
|
|
165
165
|
],
|
|
166
166
|
},
|
|
167
167
|
};
|
|
@@ -195,9 +195,6 @@ interface ImportMeta {
|
|
|
195
195
|
fs.writeFileSync(filePath, content);
|
|
196
196
|
}
|
|
197
197
|
buildApp() {
|
|
198
|
-
if (this.isPlaceholder) {
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
198
|
const { path: sitePath, buildCommand } = this.props;
|
|
202
199
|
// validate site path exists
|
|
203
200
|
if (!fs.existsSync(sitePath)) {
|
|
@@ -222,13 +219,6 @@ interface ImportMeta {
|
|
|
222
219
|
}
|
|
223
220
|
}
|
|
224
221
|
bundleAssets(fileSizeLimit) {
|
|
225
|
-
if (this.isPlaceholder) {
|
|
226
|
-
return [
|
|
227
|
-
new s3Assets.Asset(this, "Asset", {
|
|
228
|
-
path: path.resolve(__dirname, "../support/static-site-stub"),
|
|
229
|
-
}),
|
|
230
|
-
];
|
|
231
|
-
}
|
|
232
222
|
const { path: sitePath } = this.props;
|
|
233
223
|
const buildOutput = this.props.buildOutput || ".";
|
|
234
224
|
// validate buildOutput exists
|
|
@@ -237,7 +227,7 @@ interface ImportMeta {
|
|
|
237
227
|
throw new Error(`No build output found at "${siteOutputPath}" for the "${this.node.id}" StaticSite.`);
|
|
238
228
|
}
|
|
239
229
|
// create zip files
|
|
240
|
-
const script = path.join(__dirname, "../support/base-site-archiver.
|
|
230
|
+
const script = path.join(__dirname, "../support/base-site-archiver.mjs");
|
|
241
231
|
const zipPath = path.resolve(path.join(useProject().paths.artifacts, `StaticSite-${this.node.id}-${this.node.addr}`));
|
|
242
232
|
// clear zip path to ensure no partX.zip remain from previous build
|
|
243
233
|
fs.rmSync(zipPath, {
|
|
@@ -268,9 +258,6 @@ interface ImportMeta {
|
|
|
268
258
|
return assets;
|
|
269
259
|
}
|
|
270
260
|
bundleFilenamesAsset() {
|
|
271
|
-
if (this.isPlaceholder) {
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
261
|
if (this.props.purgeFiles === false) {
|
|
275
262
|
return;
|
|
276
263
|
}
|
|
@@ -307,7 +294,7 @@ interface ImportMeta {
|
|
|
307
294
|
});
|
|
308
295
|
}
|
|
309
296
|
}
|
|
310
|
-
createS3Deployment() {
|
|
297
|
+
createS3Deployment(cliLayer, assets, filenamesAsset) {
|
|
311
298
|
const fileOptions = this.props.fileOptions || [
|
|
312
299
|
{
|
|
313
300
|
exclude: "*",
|
|
@@ -323,18 +310,18 @@ interface ImportMeta {
|
|
|
323
310
|
// Create a Lambda function that will be doing the uploading
|
|
324
311
|
const uploader = new lambda.Function(this, "S3Uploader", {
|
|
325
312
|
code: lambda.Code.fromAsset(path.join(__dirname, "../support/base-site-custom-resource")),
|
|
326
|
-
layers: [
|
|
313
|
+
layers: [cliLayer],
|
|
327
314
|
runtime: lambda.Runtime.PYTHON_3_7,
|
|
328
315
|
handler: "s3-upload.handler",
|
|
329
316
|
timeout: Duration.minutes(15),
|
|
330
317
|
memorySize: 1024,
|
|
331
318
|
});
|
|
332
|
-
this.
|
|
333
|
-
|
|
319
|
+
this.bucket.grantReadWrite(uploader);
|
|
320
|
+
assets.forEach((asset) => asset.grantRead(uploader));
|
|
334
321
|
// Create the custom resource function
|
|
335
322
|
const handler = new lambda.Function(this, "S3Handler", {
|
|
336
323
|
code: lambda.Code.fromAsset(path.join(__dirname, "../support/base-site-custom-resource")),
|
|
337
|
-
layers: [
|
|
324
|
+
layers: [cliLayer],
|
|
338
325
|
runtime: lambda.Runtime.PYTHON_3_7,
|
|
339
326
|
handler: "s3-handler.handler",
|
|
340
327
|
timeout: Duration.minutes(15),
|
|
@@ -343,22 +330,22 @@ interface ImportMeta {
|
|
|
343
330
|
UPLOADER_FUNCTION_NAME: uploader.functionName,
|
|
344
331
|
},
|
|
345
332
|
});
|
|
346
|
-
this.
|
|
347
|
-
|
|
333
|
+
this.bucket.grantReadWrite(handler);
|
|
334
|
+
filenamesAsset?.grantRead(handler);
|
|
348
335
|
uploader.grantInvoke(handler);
|
|
349
336
|
// Create custom resource
|
|
350
337
|
return new CustomResource(this, "S3Deployment", {
|
|
351
338
|
serviceToken: handler.functionArn,
|
|
352
339
|
resourceType: "Custom::SSTBucketDeployment",
|
|
353
340
|
properties: {
|
|
354
|
-
Sources:
|
|
341
|
+
Sources: assets.map((asset) => ({
|
|
355
342
|
BucketName: asset.s3BucketName,
|
|
356
343
|
ObjectKey: asset.s3ObjectKey,
|
|
357
344
|
})),
|
|
358
|
-
DestinationBucketName: this.
|
|
359
|
-
Filenames:
|
|
360
|
-
BucketName:
|
|
361
|
-
ObjectKey:
|
|
345
|
+
DestinationBucketName: this.bucket.bucketName,
|
|
346
|
+
Filenames: filenamesAsset && {
|
|
347
|
+
BucketName: filenamesAsset.s3BucketName,
|
|
348
|
+
ObjectKey: filenamesAsset.s3ObjectKey,
|
|
362
349
|
},
|
|
363
350
|
FileOptions: (fileOptions || []).map(({ exclude, include, cacheControl }) => {
|
|
364
351
|
if (typeof exclude === "string") {
|
|
@@ -411,17 +398,9 @@ interface ImportMeta {
|
|
|
411
398
|
}
|
|
412
399
|
}
|
|
413
400
|
// Build errorResponses
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
errorResponses = buildErrorResponsesForRedirectToIndex(indexPage);
|
|
418
|
-
}
|
|
419
|
-
else {
|
|
420
|
-
errorResponses =
|
|
421
|
-
errorPage === "redirect_to_index_page" || errorPage === undefined
|
|
422
|
-
? buildErrorResponsesForRedirectToIndex(indexPage)
|
|
423
|
-
: buildErrorResponsesFor404ErrorPage(errorPage);
|
|
424
|
-
}
|
|
401
|
+
const errorResponses = errorPage === "redirect_to_index_page" || errorPage === undefined
|
|
402
|
+
? buildErrorResponsesForRedirectToIndex(indexPage)
|
|
403
|
+
: buildErrorResponsesFor404ErrorPage(errorPage);
|
|
425
404
|
// Create CloudFront distribution
|
|
426
405
|
return new cloudfront.Distribution(this, "Distribution", {
|
|
427
406
|
// these values can be overwritten by cfDistributionProps
|
|
@@ -430,19 +409,19 @@ interface ImportMeta {
|
|
|
430
409
|
...cdk?.distribution,
|
|
431
410
|
// these values can NOT be overwritten by cfDistributionProps
|
|
432
411
|
domainNames,
|
|
433
|
-
certificate: this.
|
|
412
|
+
certificate: this.certificate,
|
|
434
413
|
defaultBehavior: {
|
|
435
|
-
origin: new cfOrigins.S3Origin(this.
|
|
414
|
+
origin: new cfOrigins.S3Origin(this.bucket),
|
|
436
415
|
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
437
416
|
...cdk?.distribution?.defaultBehavior,
|
|
438
417
|
},
|
|
439
418
|
});
|
|
440
419
|
}
|
|
441
|
-
createCloudFrontInvalidation() {
|
|
420
|
+
createCloudFrontInvalidation(cliLayer, assets) {
|
|
442
421
|
// Create a Lambda function that will be doing the invalidation
|
|
443
422
|
const invalidator = new lambda.Function(this, "CloudFrontInvalidator", {
|
|
444
423
|
code: lambda.Code.fromAsset(path.join(__dirname, "../support/base-site-custom-resource")),
|
|
445
|
-
layers: [
|
|
424
|
+
layers: [cliLayer],
|
|
446
425
|
runtime: lambda.Runtime.PYTHON_3_7,
|
|
447
426
|
handler: "cf-invalidate.handler",
|
|
448
427
|
timeout: Duration.minutes(15),
|
|
@@ -460,22 +439,17 @@ interface ImportMeta {
|
|
|
460
439
|
// Need the AssetHash field so the CR gets updated on each deploy
|
|
461
440
|
const assetsHash = crypto
|
|
462
441
|
.createHash("md5")
|
|
463
|
-
.update(
|
|
442
|
+
.update(assets.map(({ assetHash }) => assetHash).join(""))
|
|
464
443
|
.digest("hex");
|
|
465
444
|
// Create custom resource
|
|
466
|
-
const waitForInvalidation = this.isPlaceholder
|
|
467
|
-
? false
|
|
468
|
-
: this.props.waitForInvalidation === false
|
|
469
|
-
? false
|
|
470
|
-
: true;
|
|
471
445
|
return new CustomResource(this, "CloudFrontInvalidation", {
|
|
472
446
|
serviceToken: invalidator.functionArn,
|
|
473
447
|
resourceType: "Custom::SSTCloudFrontInvalidation",
|
|
474
448
|
properties: {
|
|
475
449
|
AssetsHash: assetsHash,
|
|
476
|
-
DistributionId: this.
|
|
450
|
+
DistributionId: this.distribution.distributionId,
|
|
477
451
|
DistributionPaths: ["/*"],
|
|
478
|
-
WaitForInvalidation: waitForInvalidation,
|
|
452
|
+
WaitForInvalidation: this.props.waitForInvalidation,
|
|
479
453
|
},
|
|
480
454
|
});
|
|
481
455
|
}
|
|
@@ -543,11 +517,11 @@ interface ImportMeta {
|
|
|
543
517
|
}
|
|
544
518
|
let acmCertificate;
|
|
545
519
|
// HostedZone is set for Route 53 domains
|
|
546
|
-
if (this.
|
|
520
|
+
if (this.hostedZone) {
|
|
547
521
|
if (typeof customDomain === "string") {
|
|
548
|
-
acmCertificate = new
|
|
522
|
+
acmCertificate = new DnsValidatedCertificate(this, "Certificate", {
|
|
549
523
|
domainName: customDomain,
|
|
550
|
-
hostedZone: this.
|
|
524
|
+
hostedZone: this.hostedZone,
|
|
551
525
|
region: "us-east-1",
|
|
552
526
|
});
|
|
553
527
|
}
|
|
@@ -555,9 +529,9 @@ interface ImportMeta {
|
|
|
555
529
|
acmCertificate = customDomain.cdk.certificate;
|
|
556
530
|
}
|
|
557
531
|
else {
|
|
558
|
-
acmCertificate = new
|
|
532
|
+
acmCertificate = new DnsValidatedCertificate(this, "Certificate", {
|
|
559
533
|
domainName: customDomain.domainName,
|
|
560
|
-
hostedZone: this.
|
|
534
|
+
hostedZone: this.hostedZone,
|
|
561
535
|
region: "us-east-1",
|
|
562
536
|
});
|
|
563
537
|
}
|
|
@@ -572,7 +546,7 @@ interface ImportMeta {
|
|
|
572
546
|
}
|
|
573
547
|
createRoute53Records() {
|
|
574
548
|
const { customDomain } = this.props;
|
|
575
|
-
if (!customDomain || !this.
|
|
549
|
+
if (!customDomain || !this.hostedZone) {
|
|
576
550
|
return;
|
|
577
551
|
}
|
|
578
552
|
let recordName;
|
|
@@ -587,15 +561,15 @@ interface ImportMeta {
|
|
|
587
561
|
// Create DNS record
|
|
588
562
|
const recordProps = {
|
|
589
563
|
recordName,
|
|
590
|
-
zone: this.
|
|
591
|
-
target: route53.RecordTarget.fromAlias(new route53Targets.CloudFrontTarget(this.
|
|
564
|
+
zone: this.hostedZone,
|
|
565
|
+
target: route53.RecordTarget.fromAlias(new route53Targets.CloudFrontTarget(this.distribution)),
|
|
592
566
|
};
|
|
593
567
|
new route53.ARecord(this, "AliasRecord", recordProps);
|
|
594
568
|
new route53.AaaaRecord(this, "AliasRecordAAAA", recordProps);
|
|
595
569
|
// Create Alias redirect record
|
|
596
570
|
if (domainAlias) {
|
|
597
|
-
new
|
|
598
|
-
zone: this.
|
|
571
|
+
new HttpsRedirect(this, "Redirect", {
|
|
572
|
+
zone: this.hostedZone,
|
|
599
573
|
recordNames: [domainAlias],
|
|
600
574
|
targetDomain: recordName,
|
|
601
575
|
});
|
package/constructs/Table.d.ts
CHANGED
|
@@ -80,7 +80,7 @@ export interface TableGlobalIndexProps {
|
|
|
80
80
|
index?: Omit<dynamodb.GlobalSecondaryIndexProps, "indexName" | "partitionKey" | "sortKey">;
|
|
81
81
|
};
|
|
82
82
|
}
|
|
83
|
-
|
|
83
|
+
type TableFieldType = Lowercase<keyof typeof dynamodb.AttributeType>;
|
|
84
84
|
export interface TableProps {
|
|
85
85
|
/**
|
|
86
86
|
* An object defining the fields of the table. Key is the name of the field and the value is the type.
|
package/constructs/Table.js
CHANGED
|
@@ -269,7 +269,7 @@ export class Table extends Construct {
|
|
|
269
269
|
return {
|
|
270
270
|
clientPackage: "table",
|
|
271
271
|
variables: {
|
|
272
|
-
|
|
272
|
+
tableName: {
|
|
273
273
|
environment: this.tableName,
|
|
274
274
|
parameter: this.tableName,
|
|
275
275
|
},
|
|
@@ -368,11 +368,11 @@ export class Table extends Construct {
|
|
|
368
368
|
fn.addEventSource(eventSource);
|
|
369
369
|
// set filter pattern
|
|
370
370
|
if (filters && filters.length > 0) {
|
|
371
|
-
const cfnEventSource = fn.node.children.find(c => c instanceof lambda.EventSourceMapping)?.node.defaultChild;
|
|
371
|
+
const cfnEventSource = fn.node.children.find((c) => c instanceof lambda.EventSourceMapping)?.node.defaultChild;
|
|
372
372
|
cfnEventSource.addPropertyOverride("FilterCriteria", {
|
|
373
|
-
Filters: filters.map(filter => ({
|
|
373
|
+
Filters: filters.map((filter) => ({
|
|
374
374
|
Pattern: JSON.stringify(filter),
|
|
375
|
-
}))
|
|
375
|
+
})),
|
|
376
376
|
});
|
|
377
377
|
}
|
|
378
378
|
// attach permissions
|
package/constructs/Topic.js
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Metric, MetricOptions } from "aws-cdk-lib/aws-cloudwatch";
|
|
2
|
+
import { Resource } from "aws-cdk-lib";
|
|
3
|
+
import { ICertificate } from "aws-cdk-lib/aws-certificatemanager";
|
|
4
|
+
/**
|
|
5
|
+
* Shared implementation details of ICertificate implementations.
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export declare abstract class CertificateBase extends Resource implements ICertificate {
|
|
10
|
+
abstract readonly certificateArn: string;
|
|
11
|
+
/**
|
|
12
|
+
* If the certificate is provisionned in a different region than the
|
|
13
|
+
* containing stack, this should be the region in which the certificate lives
|
|
14
|
+
* so we can correctly create `Metric` instances.
|
|
15
|
+
*/
|
|
16
|
+
protected readonly region?: string;
|
|
17
|
+
metricDaysToExpiry(props?: MetricOptions): Metric;
|
|
18
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Metric, Stats } from "aws-cdk-lib/aws-cloudwatch";
|
|
2
|
+
import { Duration, Resource } from "aws-cdk-lib";
|
|
3
|
+
/**
|
|
4
|
+
* Shared implementation details of ICertificate implementations.
|
|
5
|
+
*
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export class CertificateBase extends Resource {
|
|
9
|
+
/**
|
|
10
|
+
* If the certificate is provisionned in a different region than the
|
|
11
|
+
* containing stack, this should be the region in which the certificate lives
|
|
12
|
+
* so we can correctly create `Metric` instances.
|
|
13
|
+
*/
|
|
14
|
+
region;
|
|
15
|
+
metricDaysToExpiry(props) {
|
|
16
|
+
return new Metric({
|
|
17
|
+
period: Duration.days(1),
|
|
18
|
+
...props,
|
|
19
|
+
dimensionsMap: { CertificateArn: this.certificateArn },
|
|
20
|
+
metricName: "DaysToExpiry",
|
|
21
|
+
namespace: "AWS/CertificateManager",
|
|
22
|
+
region: this.region,
|
|
23
|
+
statistic: Stats.MINIMUM,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Construct } from "constructs";
|
|
2
|
+
import { ITaggable, TagManager, RemovalPolicy } from "aws-cdk-lib";
|
|
3
|
+
import { CertificateProps, ICertificate } from "aws-cdk-lib/aws-certificatemanager";
|
|
4
|
+
import * as iam from "aws-cdk-lib/aws-iam";
|
|
5
|
+
import * as route53 from "aws-cdk-lib/aws-route53";
|
|
6
|
+
import { CertificateBase } from "./certificate-base.js";
|
|
7
|
+
/**
|
|
8
|
+
* Properties to create a DNS validated certificate managed by AWS Certificate Manager
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
export interface DnsValidatedCertificateProps extends CertificateProps {
|
|
12
|
+
/**
|
|
13
|
+
* Route 53 Hosted Zone used to perform DNS validation of the request. The zone
|
|
14
|
+
* must be authoritative for the domain name specified in the Certificate Request.
|
|
15
|
+
*/
|
|
16
|
+
readonly hostedZone: route53.IHostedZone;
|
|
17
|
+
/**
|
|
18
|
+
* AWS region that will host the certificate. This is needed especially
|
|
19
|
+
* for certificates used for CloudFront distributions, which require the region
|
|
20
|
+
* to be us-east-1.
|
|
21
|
+
*
|
|
22
|
+
* @default the region the stack is deployed in.
|
|
23
|
+
*/
|
|
24
|
+
readonly region?: string;
|
|
25
|
+
/**
|
|
26
|
+
* An endpoint of Route53 service, which is not necessary as AWS SDK could figure
|
|
27
|
+
* out the right endpoints for most regions, but for some regions such as those in
|
|
28
|
+
* aws-cn partition, the default endpoint is not working now, hence the right endpoint
|
|
29
|
+
* need to be specified through this prop.
|
|
30
|
+
*
|
|
31
|
+
* Route53 is not been officially launched in China, it is only available for AWS
|
|
32
|
+
* internal accounts now. To make DnsValidatedCertificate work for internal accounts
|
|
33
|
+
* now, a special endpoint needs to be provided.
|
|
34
|
+
*
|
|
35
|
+
* @default - The AWS SDK will determine the Route53 endpoint to use based on region
|
|
36
|
+
*/
|
|
37
|
+
readonly route53Endpoint?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Role to use for the custom resource that creates the validated certificate
|
|
40
|
+
*
|
|
41
|
+
* @default - A new role will be created
|
|
42
|
+
*/
|
|
43
|
+
readonly customResourceRole?: iam.IRole;
|
|
44
|
+
/**
|
|
45
|
+
* When set to true, when the DnsValidatedCertificate is deleted,
|
|
46
|
+
* the associated Route53 validation records are removed.
|
|
47
|
+
*
|
|
48
|
+
* CAUTION: If multiple certificates share the same domains (and same validation records),
|
|
49
|
+
* this can cause the other certificates to fail renewal and/or not validate.
|
|
50
|
+
* Not recommended for production use.
|
|
51
|
+
*
|
|
52
|
+
* @default false
|
|
53
|
+
*/
|
|
54
|
+
readonly cleanupRoute53Records?: boolean;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* A certificate managed by AWS Certificate Manager. Will be automatically
|
|
58
|
+
* validated using DNS validation against the specified Route 53 hosted zone.
|
|
59
|
+
*
|
|
60
|
+
* @resource AWS::CertificateManager::Certificate
|
|
61
|
+
*/
|
|
62
|
+
export declare class DnsValidatedCertificate extends CertificateBase implements ICertificate, ITaggable {
|
|
63
|
+
readonly certificateArn: string;
|
|
64
|
+
/**
|
|
65
|
+
* Resource Tags.
|
|
66
|
+
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-certificatemanager-certificate.html#cfn-certificatemanager-certificate-tags
|
|
67
|
+
*/
|
|
68
|
+
readonly tags: TagManager;
|
|
69
|
+
protected readonly region?: string;
|
|
70
|
+
private normalizedZoneName;
|
|
71
|
+
private hostedZoneId;
|
|
72
|
+
private domainName;
|
|
73
|
+
private _removalPolicy?;
|
|
74
|
+
constructor(scope: Construct, id: string, props: DnsValidatedCertificateProps);
|
|
75
|
+
applyRemovalPolicy(policy: RemovalPolicy): void;
|
|
76
|
+
private validateDnsValidatedCertificate;
|
|
77
|
+
}
|