sst 2.0.0-rc.57 → 2.0.0-rc.60
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/constructs/AstroSite.js +8 -8
- package/constructs/EdgeFunction.d.ts +5 -3
- package/constructs/EdgeFunction.js +13 -7
- package/constructs/Job.d.ts +22 -23
- package/constructs/NextjsSite.d.ts +18 -0
- package/constructs/NextjsSite.js +21 -15
- package/constructs/RemixSite.js +16 -8
- package/constructs/SolidStartSite.js +8 -8
- package/constructs/SsrFunction.d.ts +4 -2
- package/constructs/SsrFunction.js +10 -4
- package/constructs/SsrSite.d.ts +55 -31
- package/constructs/SsrSite.js +66 -64
- package/constructs/StaticSite.js +1 -1
- package/constructs/util/functionBinding.js +1 -1
- package/package.json +1 -1
- package/runtime/server.js +2 -1
- package/runtime/workers.d.ts +1 -0
- package/runtime/workers.js +4 -0
- package/sst.mjs +7 -5
- package/stacks/monitor.js +1 -1
- package/support/nodejs-runtime/index.mjs +1 -0
package/constructs/AstroSite.js
CHANGED
|
@@ -35,7 +35,7 @@ export class AstroSite extends SsrSite {
|
|
|
35
35
|
super.validateBuildOutput();
|
|
36
36
|
}
|
|
37
37
|
createFunctionForRegional() {
|
|
38
|
-
const {
|
|
38
|
+
const { memorySize, timeout, environment, bind, cdk } = this.props;
|
|
39
39
|
// Create function
|
|
40
40
|
const fn = new Function(this, `ServerFunction`, {
|
|
41
41
|
description: "Server handler",
|
|
@@ -43,19 +43,19 @@ export class AstroSite extends SsrSite {
|
|
|
43
43
|
bind,
|
|
44
44
|
logRetention: "three_days",
|
|
45
45
|
runtime: "nodejs16.x",
|
|
46
|
-
memorySize
|
|
47
|
-
timeout
|
|
46
|
+
memorySize,
|
|
47
|
+
timeout,
|
|
48
48
|
nodejs: {
|
|
49
49
|
format: "esm",
|
|
50
50
|
},
|
|
51
|
-
enableLiveDev: false,
|
|
52
51
|
environment,
|
|
52
|
+
...cdk?.server,
|
|
53
53
|
});
|
|
54
54
|
fn._disableBind = true;
|
|
55
55
|
return fn;
|
|
56
56
|
}
|
|
57
57
|
createFunctionForEdge() {
|
|
58
|
-
const {
|
|
58
|
+
const { timeout, memorySize, permissions, environment } = this.props;
|
|
59
59
|
// Create a directory that we will use to create the bundled version
|
|
60
60
|
// of the "core server build" along with our custom Lamba server handler.
|
|
61
61
|
const outputPath = path.resolve(path.join(useProject().paths.artifacts, `AstroSiteFunction-${this.node.id}-${this.node.addr}`));
|
|
@@ -89,9 +89,9 @@ export class AstroSite extends SsrSite {
|
|
|
89
89
|
scopeOverride: this,
|
|
90
90
|
bundlePath: outputPath,
|
|
91
91
|
handler: "entry.handler",
|
|
92
|
-
timeout
|
|
93
|
-
|
|
94
|
-
permissions
|
|
92
|
+
timeout,
|
|
93
|
+
memorySize,
|
|
94
|
+
permissions,
|
|
95
95
|
environment,
|
|
96
96
|
format: "esm",
|
|
97
97
|
});
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { Construct, IConstruct } from "constructs";
|
|
2
2
|
import * as iam from "aws-cdk-lib/aws-iam";
|
|
3
3
|
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
4
|
+
import { Size } from "./util/size.js";
|
|
5
|
+
import { Duration } from "./util/duration.js";
|
|
4
6
|
import { Permissions } from "./util/permission.js";
|
|
5
7
|
export interface EdgeFunctionProps {
|
|
6
8
|
bundlePath: string;
|
|
7
9
|
handler: string;
|
|
8
|
-
timeout
|
|
9
|
-
|
|
10
|
+
timeout: number | Duration;
|
|
11
|
+
memorySize: number | Size;
|
|
10
12
|
permissions?: Permissions;
|
|
11
|
-
format
|
|
13
|
+
format: "cjs" | "esm";
|
|
12
14
|
environment?: Record<string, string>;
|
|
13
15
|
/**
|
|
14
16
|
* This is intended to be used internally by SST to make constructs
|
|
@@ -6,8 +6,10 @@ import { Construct } from "constructs";
|
|
|
6
6
|
import * as iam from "aws-cdk-lib/aws-iam";
|
|
7
7
|
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
8
8
|
import * as s3Assets from "aws-cdk-lib/aws-s3-assets";
|
|
9
|
-
import { Lazy, Duration, CustomResource } from "aws-cdk-lib";
|
|
9
|
+
import { Lazy, Duration as CdkDuration, CustomResource, } from "aws-cdk-lib";
|
|
10
10
|
import { Stack } from "./Stack.js";
|
|
11
|
+
import { toCdkSize } from "./util/size.js";
|
|
12
|
+
import { toCdkDuration } from "./util/duration.js";
|
|
11
13
|
import { attachPermissionsToRole } from "./util/permission.js";
|
|
12
14
|
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
|
|
13
15
|
/////////////////////
|
|
@@ -106,7 +108,7 @@ ${exports}
|
|
|
106
108
|
return role;
|
|
107
109
|
}
|
|
108
110
|
createFunction(asset) {
|
|
109
|
-
const { timeout,
|
|
111
|
+
const { timeout, memorySize } = this.props;
|
|
110
112
|
const name = this.node.id;
|
|
111
113
|
// Create a S3 bucket in us-east-1 to store Lambda code. Create
|
|
112
114
|
// 1 bucket for all Edge functions.
|
|
@@ -121,8 +123,12 @@ ${exports}
|
|
|
121
123
|
S3Key: asset.s3ObjectKey,
|
|
122
124
|
},
|
|
123
125
|
Runtime: lambda.Runtime.NODEJS_18_X.name,
|
|
124
|
-
MemorySize:
|
|
125
|
-
|
|
126
|
+
MemorySize: typeof memorySize === "string"
|
|
127
|
+
? toCdkSize(memorySize).toMebibytes()
|
|
128
|
+
: memorySize,
|
|
129
|
+
Timeout: typeof timeout === "string"
|
|
130
|
+
? toCdkDuration(timeout).toSeconds()
|
|
131
|
+
: timeout,
|
|
126
132
|
Role: this.role.roleArn,
|
|
127
133
|
});
|
|
128
134
|
const functionArn = functionCR.getAttString("FunctionArn");
|
|
@@ -170,7 +176,7 @@ ${exports}
|
|
|
170
176
|
code: lambda.Code.fromAsset(path.join(__dirname, "../support/edge-function")),
|
|
171
177
|
handler: "s3-bucket.handler",
|
|
172
178
|
runtime: lambda.Runtime.NODEJS_16_X,
|
|
173
|
-
timeout:
|
|
179
|
+
timeout: CdkDuration.minutes(15),
|
|
174
180
|
memorySize: 1024,
|
|
175
181
|
initialPolicy: [
|
|
176
182
|
new iam.PolicyStatement({
|
|
@@ -202,7 +208,7 @@ ${exports}
|
|
|
202
208
|
code: lambda.Code.fromAsset(path.join(__dirname, "../support/edge-function")),
|
|
203
209
|
handler: "edge-lambda.handler",
|
|
204
210
|
runtime: lambda.Runtime.NODEJS_16_X,
|
|
205
|
-
timeout:
|
|
211
|
+
timeout: CdkDuration.minutes(15),
|
|
206
212
|
memorySize: 1024,
|
|
207
213
|
initialPolicy: [
|
|
208
214
|
new iam.PolicyStatement({
|
|
@@ -240,7 +246,7 @@ ${exports}
|
|
|
240
246
|
code: lambda.Code.fromAsset(path.join(__dirname, "../support/edge-function")),
|
|
241
247
|
handler: "edge-lambda-version.handler",
|
|
242
248
|
runtime: lambda.Runtime.NODEJS_16_X,
|
|
243
|
-
timeout:
|
|
249
|
+
timeout: CdkDuration.minutes(15),
|
|
244
250
|
memorySize: 1024,
|
|
245
251
|
initialPolicy: [
|
|
246
252
|
new iam.PolicyStatement({
|
package/constructs/Job.d.ts
CHANGED
|
@@ -98,29 +98,28 @@ export interface JobProps {
|
|
|
98
98
|
* ```
|
|
99
99
|
*/
|
|
100
100
|
permissions?: Permissions;
|
|
101
|
-
cdk?:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
vpc?: IVpc;
|
|
101
|
+
cdk?: {
|
|
102
|
+
/**
|
|
103
|
+
* Allows you to override default id for this construct.
|
|
104
|
+
*/
|
|
105
|
+
id?: string;
|
|
106
|
+
/**
|
|
107
|
+
* Runs codebuild job in the specified VPC. Note this will only work once deployed.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```js
|
|
111
|
+
* new Job(stack, "MyJob", {
|
|
112
|
+
* handler: "src/job.handler",
|
|
113
|
+
* cdk: {
|
|
114
|
+
* vpc: Vpc.fromLookup(stack, "VPC", {
|
|
115
|
+
* vpcId: "vpc-xxxxxxxxxx",
|
|
116
|
+
* }),
|
|
117
|
+
* }
|
|
118
|
+
* })
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
vpc?: IVpc;
|
|
122
|
+
};
|
|
124
123
|
}
|
|
125
124
|
/**
|
|
126
125
|
* The `Cron` construct is a higher level CDK construct that makes it easy to create a cron job.
|
|
@@ -2,7 +2,20 @@ import { Construct } from "constructs";
|
|
|
2
2
|
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
3
3
|
import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
|
|
4
4
|
import { SsrSite, SsrSiteProps } from "./SsrSite.js";
|
|
5
|
+
import { Size } from "./util/size.js";
|
|
6
|
+
import { Duration } from "./util/duration.js";
|
|
5
7
|
export interface NextjsSiteProps extends Omit<SsrSiteProps, "edge"> {
|
|
8
|
+
imageOptimization?: {
|
|
9
|
+
/**
|
|
10
|
+
* The amount of memory in MB allocated for image optimization function.
|
|
11
|
+
* @default 1024 MB
|
|
12
|
+
* @example
|
|
13
|
+
* ```js
|
|
14
|
+
* memorySize: "512 MB",
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
memorySize?: number | Size;
|
|
18
|
+
};
|
|
6
19
|
}
|
|
7
20
|
/**
|
|
8
21
|
* The `NextjsSite` construct is a higher level CDK construct that makes it easy to create a Next.js app.
|
|
@@ -16,6 +29,11 @@ export interface NextjsSiteProps extends Omit<SsrSiteProps, "edge"> {
|
|
|
16
29
|
* ```
|
|
17
30
|
*/
|
|
18
31
|
export declare class NextjsSite extends SsrSite {
|
|
32
|
+
protected props: Omit<NextjsSiteProps, "path"> & {
|
|
33
|
+
path: string;
|
|
34
|
+
timeout: number | Duration;
|
|
35
|
+
memorySize: number | Size;
|
|
36
|
+
};
|
|
19
37
|
constructor(scope: Construct, id: string, props?: NextjsSiteProps);
|
|
20
38
|
protected initBuildConfig(): {
|
|
21
39
|
serverBuildOutputFile: string;
|
package/constructs/NextjsSite.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import url from "url";
|
|
3
3
|
import path from "path";
|
|
4
|
-
import { Fn, Duration, RemovalPolicy } from "aws-cdk-lib";
|
|
4
|
+
import { Fn, Duration as CdkDuration, RemovalPolicy } from "aws-cdk-lib";
|
|
5
5
|
import * as logs from "aws-cdk-lib/aws-logs";
|
|
6
6
|
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
7
7
|
import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
|
|
@@ -9,6 +9,7 @@ import * as origins from "aws-cdk-lib/aws-cloudfront-origins";
|
|
|
9
9
|
import { SsrFunction } from "./SsrFunction.js";
|
|
10
10
|
import { EdgeFunction } from "./EdgeFunction.js";
|
|
11
11
|
import { SsrSite } from "./SsrSite.js";
|
|
12
|
+
import { toCdkSize } from "./util/size.js";
|
|
12
13
|
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
|
13
14
|
/**
|
|
14
15
|
* The `NextjsSite` construct is a higher level CDK construct that makes it easy to create a Next.js app.
|
|
@@ -36,20 +37,20 @@ export class NextjsSite extends SsrSite {
|
|
|
36
37
|
};
|
|
37
38
|
}
|
|
38
39
|
createFunctionForRegional() {
|
|
39
|
-
const {
|
|
40
|
+
const { timeout, memorySize, permissions, environment } = this.props;
|
|
40
41
|
const ssrFn = new SsrFunction(this, `ServerFunction`, {
|
|
41
42
|
description: "Server handler for Next.js",
|
|
42
43
|
bundlePath: path.join(this.props.path, ".open-next", "server-function"),
|
|
43
44
|
handler: "index.handler",
|
|
44
|
-
timeout
|
|
45
|
-
|
|
46
|
-
permissions
|
|
45
|
+
timeout,
|
|
46
|
+
memorySize,
|
|
47
|
+
permissions,
|
|
47
48
|
environment,
|
|
48
49
|
});
|
|
49
50
|
return ssrFn.function;
|
|
50
51
|
}
|
|
51
52
|
createImageOptimizationFunctionForRegional() {
|
|
52
|
-
const {
|
|
53
|
+
const { imageOptimization, path: sitePath, cdk } = this.props;
|
|
53
54
|
return new lambda.Function(this, `ImageFunction`, {
|
|
54
55
|
description: "Image optimization handler for Next.js",
|
|
55
56
|
handler: "index.handler",
|
|
@@ -59,15 +60,20 @@ export class NextjsSite extends SsrSite {
|
|
|
59
60
|
logRetention: logs.RetentionDays.THREE_DAYS,
|
|
60
61
|
code: lambda.Code.fromAsset(path.join(sitePath, ".open-next/image-optimization-function")),
|
|
61
62
|
runtime: lambda.Runtime.NODEJS_18_X,
|
|
62
|
-
memorySize:
|
|
63
|
-
|
|
63
|
+
memorySize: imageOptimization?.memorySize
|
|
64
|
+
? typeof imageOptimization.memorySize === "string"
|
|
65
|
+
? toCdkSize(imageOptimization.memorySize).toMebibytes()
|
|
66
|
+
: imageOptimization.memorySize
|
|
67
|
+
: 512,
|
|
68
|
+
timeout: CdkDuration.seconds(25),
|
|
64
69
|
environment: {
|
|
65
70
|
BUCKET_NAME: this.cdk.bucket.bucketName,
|
|
66
71
|
},
|
|
72
|
+
...cdk?.server,
|
|
67
73
|
});
|
|
68
74
|
}
|
|
69
75
|
createMiddlewareEdgeFunctionForRegional() {
|
|
70
|
-
const {
|
|
76
|
+
const { permissions, environment, path: sitePath } = this.props;
|
|
71
77
|
const middlewarePath = path.resolve(sitePath, ".open-next/middleware-function");
|
|
72
78
|
const isMiddlewareEnabled = fs.existsSync(middlewarePath);
|
|
73
79
|
let bundlePath, handler;
|
|
@@ -82,9 +88,9 @@ export class NextjsSite extends SsrSite {
|
|
|
82
88
|
const fn = new EdgeFunction(this, "Middleware", {
|
|
83
89
|
bundlePath,
|
|
84
90
|
handler,
|
|
85
|
-
timeout:
|
|
86
|
-
|
|
87
|
-
permissions
|
|
91
|
+
timeout: 10,
|
|
92
|
+
memorySize: 512,
|
|
93
|
+
permissions,
|
|
88
94
|
environment,
|
|
89
95
|
format: "esm",
|
|
90
96
|
});
|
|
@@ -230,9 +236,9 @@ export class NextjsSite extends SsrSite {
|
|
|
230
236
|
// required by server request
|
|
231
237
|
"x-op-middleware-request-headers", "x-op-middleware-response-headers", "x-nextjs-data", "x-middleware-prefetch"),
|
|
232
238
|
cookieBehavior: cloudfront.CacheCookieBehavior.all(),
|
|
233
|
-
defaultTtl:
|
|
234
|
-
maxTtl:
|
|
235
|
-
minTtl:
|
|
239
|
+
defaultTtl: CdkDuration.days(0),
|
|
240
|
+
maxTtl: CdkDuration.days(365),
|
|
241
|
+
minTtl: CdkDuration.days(0),
|
|
236
242
|
enableAcceptEncodingBrotli: true,
|
|
237
243
|
enableAcceptEncodingGzip: true,
|
|
238
244
|
comment: "SST server response cache policy",
|
package/constructs/RemixSite.js
CHANGED
|
@@ -4,13 +4,15 @@ import path from "path";
|
|
|
4
4
|
import * as esbuild from "esbuild";
|
|
5
5
|
import { createRequire } from "module";
|
|
6
6
|
const require = createRequire(import.meta.url);
|
|
7
|
-
import { Duration, RemovalPolicy } from "aws-cdk-lib";
|
|
7
|
+
import { Duration as CdkDuration, RemovalPolicy } from "aws-cdk-lib";
|
|
8
8
|
import * as logs from "aws-cdk-lib/aws-logs";
|
|
9
9
|
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
10
10
|
import { Logger } from "../logger.js";
|
|
11
11
|
import { SsrSite } from "./SsrSite.js";
|
|
12
12
|
import { useProject } from "../project.js";
|
|
13
13
|
import { EdgeFunction } from "./EdgeFunction.js";
|
|
14
|
+
import { toCdkSize } from "./util/size.js";
|
|
15
|
+
import { toCdkDuration } from "./util/duration.js";
|
|
14
16
|
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
|
15
17
|
/**
|
|
16
18
|
* The `RemixSite` construct is a higher level CDK construct that makes it easy to create a Remix app.
|
|
@@ -110,7 +112,7 @@ export class RemixSite extends SsrSite {
|
|
|
110
112
|
return outputPath;
|
|
111
113
|
}
|
|
112
114
|
createFunctionForRegional() {
|
|
113
|
-
const {
|
|
115
|
+
const { timeout, memorySize, environment, cdk } = this.props;
|
|
114
116
|
const bundlePath = this.createServerLambdaBundle("regional-server.js");
|
|
115
117
|
return new lambda.Function(this, `ServerFunction`, {
|
|
116
118
|
description: "Server handler for Remix",
|
|
@@ -121,21 +123,27 @@ export class RemixSite extends SsrSite {
|
|
|
121
123
|
logRetention: logs.RetentionDays.THREE_DAYS,
|
|
122
124
|
code: lambda.Code.fromAsset(bundlePath),
|
|
123
125
|
runtime: lambda.Runtime.NODEJS_16_X,
|
|
124
|
-
memorySize:
|
|
125
|
-
|
|
126
|
+
memorySize: typeof memorySize === "string"
|
|
127
|
+
? toCdkSize(memorySize).toMebibytes()
|
|
128
|
+
: memorySize,
|
|
129
|
+
timeout: typeof timeout === "string"
|
|
130
|
+
? toCdkDuration(timeout)
|
|
131
|
+
: CdkDuration.seconds(timeout),
|
|
126
132
|
environment,
|
|
133
|
+
...cdk?.server,
|
|
127
134
|
});
|
|
128
135
|
}
|
|
129
136
|
createFunctionForEdge() {
|
|
130
|
-
const {
|
|
137
|
+
const { timeout, memorySize, permissions, environment } = this.props;
|
|
131
138
|
const bundlePath = this.createServerLambdaBundle("edge-server.js");
|
|
132
139
|
return new EdgeFunction(this, `Server`, {
|
|
133
140
|
scopeOverride: this,
|
|
141
|
+
format: "cjs",
|
|
134
142
|
bundlePath,
|
|
135
143
|
handler: "server.handler",
|
|
136
|
-
timeout
|
|
137
|
-
|
|
138
|
-
permissions
|
|
144
|
+
timeout,
|
|
145
|
+
memorySize,
|
|
146
|
+
permissions,
|
|
139
147
|
environment,
|
|
140
148
|
});
|
|
141
149
|
}
|
|
@@ -27,7 +27,7 @@ export class SolidStartSite extends SsrSite {
|
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
createFunctionForRegional() {
|
|
30
|
-
const {
|
|
30
|
+
const { timeout, memorySize, environment, cdk } = this.props;
|
|
31
31
|
// Bundle code
|
|
32
32
|
const handler = path.join(this.props.path, "dist", "server", "index.handler");
|
|
33
33
|
// Create function
|
|
@@ -36,19 +36,19 @@ export class SolidStartSite extends SsrSite {
|
|
|
36
36
|
handler,
|
|
37
37
|
logRetention: "three_days",
|
|
38
38
|
runtime: "nodejs16.x",
|
|
39
|
-
memorySize
|
|
40
|
-
timeout
|
|
39
|
+
memorySize,
|
|
40
|
+
timeout,
|
|
41
41
|
nodejs: {
|
|
42
42
|
format: "esm",
|
|
43
43
|
},
|
|
44
|
-
enableLiveDev: false,
|
|
45
44
|
environment,
|
|
45
|
+
...cdk?.server,
|
|
46
46
|
});
|
|
47
47
|
fn._disableBind = true;
|
|
48
48
|
return fn;
|
|
49
49
|
}
|
|
50
50
|
createFunctionForEdge() {
|
|
51
|
-
const {
|
|
51
|
+
const { timeout, memorySize, permissions, environment } = this.props;
|
|
52
52
|
// Create a directory that we will use to create the bundled version
|
|
53
53
|
// of the "core server build" along with our custom Lamba server handler.
|
|
54
54
|
const outputPath = path.resolve(path.join(useProject().paths.artifacts, `SolidStartSiteFunction-${this.node.id}-${this.node.addr}`));
|
|
@@ -83,9 +83,9 @@ export class SolidStartSite extends SsrSite {
|
|
|
83
83
|
scopeOverride: this,
|
|
84
84
|
bundlePath: outputPath,
|
|
85
85
|
handler: "server.handler",
|
|
86
|
-
timeout
|
|
87
|
-
|
|
88
|
-
permissions
|
|
86
|
+
timeout,
|
|
87
|
+
memorySize,
|
|
88
|
+
permissions,
|
|
89
89
|
environment,
|
|
90
90
|
format: "esm",
|
|
91
91
|
});
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { Construct } from "constructs";
|
|
2
2
|
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
3
3
|
import { Permissions } from "./util/permission.js";
|
|
4
|
+
import { Size } from "./util/size.js";
|
|
5
|
+
import { Duration } from "./util/duration.js";
|
|
4
6
|
export interface SsrFunctionProps {
|
|
5
7
|
description?: string;
|
|
6
8
|
bundlePath: string;
|
|
7
9
|
handler: string;
|
|
8
|
-
timeout
|
|
9
|
-
|
|
10
|
+
timeout: number | Duration;
|
|
11
|
+
memorySize: number | Size;
|
|
10
12
|
permissions?: Permissions;
|
|
11
13
|
environment?: Record<string, string>;
|
|
12
14
|
}
|
|
@@ -6,10 +6,12 @@ import * as iam from "aws-cdk-lib/aws-iam";
|
|
|
6
6
|
import * as logs from "aws-cdk-lib/aws-logs";
|
|
7
7
|
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
8
8
|
import * as s3Assets from "aws-cdk-lib/aws-s3-assets";
|
|
9
|
-
import { Duration, CustomResource } from "aws-cdk-lib";
|
|
9
|
+
import { Duration as CdkDuration, CustomResource } from "aws-cdk-lib";
|
|
10
10
|
import { Stack } from "./Stack.js";
|
|
11
11
|
import { useProject } from "../project.js";
|
|
12
12
|
import { attachPermissionsToRole } from "./util/permission.js";
|
|
13
|
+
import { toCdkSize } from "./util/size.js";
|
|
14
|
+
import { toCdkDuration } from "./util/duration.js";
|
|
13
15
|
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
|
|
14
16
|
/////////////////////
|
|
15
17
|
// Construct
|
|
@@ -28,7 +30,7 @@ export class SsrFunction extends Construct {
|
|
|
28
30
|
attachPermissionsToRole(this.function.role, permissions);
|
|
29
31
|
}
|
|
30
32
|
createFunction() {
|
|
31
|
-
const { timeout,
|
|
33
|
+
const { timeout, memorySize, handler, bundlePath, environment } = this.props;
|
|
32
34
|
// Note: cannot point the bundlePath to the `.open-next/server-function`
|
|
33
35
|
// b/c the folder contains node_modules. And pnpm node_modules
|
|
34
36
|
// contains symlinks. CDK cannot zip symlinks correctly.
|
|
@@ -56,8 +58,12 @@ export class SsrFunction extends Construct {
|
|
|
56
58
|
logRetention: logs.RetentionDays.THREE_DAYS,
|
|
57
59
|
code: lambda.Code.fromBucket(asset.bucket, asset.s3ObjectKey),
|
|
58
60
|
runtime: lambda.Runtime.NODEJS_18_X,
|
|
59
|
-
memorySize:
|
|
60
|
-
|
|
61
|
+
memorySize: typeof memorySize === "string"
|
|
62
|
+
? toCdkSize(memorySize).toMebibytes()
|
|
63
|
+
: memorySize,
|
|
64
|
+
timeout: typeof timeout === "string"
|
|
65
|
+
? toCdkDuration(timeout)
|
|
66
|
+
: CdkDuration.seconds(timeout),
|
|
61
67
|
environment,
|
|
62
68
|
});
|
|
63
69
|
fn.node.addDependency(replacer);
|
package/constructs/SsrSite.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { Construct } from "constructs";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
2
|
+
import { Bucket, BucketProps, IBucket } from "aws-cdk-lib/aws-s3";
|
|
3
|
+
import { Function, FunctionProps } from "aws-cdk-lib/aws-lambda";
|
|
4
|
+
import { IHostedZone } from "aws-cdk-lib/aws-route53";
|
|
5
|
+
import { Distribution, ICachePolicy, BehaviorOptions, CachePolicy } from "aws-cdk-lib/aws-cloudfront";
|
|
6
|
+
import { ICertificate } from "aws-cdk-lib/aws-certificatemanager";
|
|
7
|
+
import { S3Origin } from "aws-cdk-lib/aws-cloudfront-origins";
|
|
8
8
|
import { SSTConstruct } from "./Construct.js";
|
|
9
9
|
import { EdgeFunction } from "./EdgeFunction.js";
|
|
10
10
|
import { BaseSiteDomainProps, BaseSiteReplaceProps, BaseSiteCdkDistributionProps } from "./BaseSite.js";
|
|
11
|
+
import { Size } from "./util/size.js";
|
|
12
|
+
import { Duration } from "./util/duration.js";
|
|
11
13
|
import { Permissions } from "./util/permission.js";
|
|
12
14
|
import { FunctionBindingProps } from "./util/functionBinding.js";
|
|
13
15
|
export type SsrBuildConfig = {
|
|
@@ -34,11 +36,6 @@ export interface SsrSiteProps {
|
|
|
34
36
|
* ```
|
|
35
37
|
*/
|
|
36
38
|
bind?: SSTConstruct[];
|
|
37
|
-
/**
|
|
38
|
-
* The SSR function is deployed to Lambda in a single region. Alternatively, you can enable this option to deploy to Lambda@Edge.
|
|
39
|
-
* @default false
|
|
40
|
-
*/
|
|
41
|
-
edge?: boolean;
|
|
42
39
|
/**
|
|
43
40
|
* Path to the directory where the app is located.
|
|
44
41
|
* @default "."
|
|
@@ -74,6 +71,37 @@ export interface SsrSiteProps {
|
|
|
74
71
|
* ```
|
|
75
72
|
*/
|
|
76
73
|
customDomain?: string | SsrDomainProps;
|
|
74
|
+
/**
|
|
75
|
+
* The SSR function is deployed to Lambda in a single region. Alternatively, you can enable this option to deploy to Lambda@Edge.
|
|
76
|
+
* @default false
|
|
77
|
+
*/
|
|
78
|
+
edge?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* The execution timeout in seconds for SSR function.
|
|
81
|
+
* @default 10 seconds
|
|
82
|
+
* @example
|
|
83
|
+
* ```js
|
|
84
|
+
* timeout: "5 seconds",
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
timeout?: number | Duration;
|
|
88
|
+
/**
|
|
89
|
+
* The amount of memory in MB allocated for SSR function.
|
|
90
|
+
* @default 1024 MB
|
|
91
|
+
* @example
|
|
92
|
+
* ```js
|
|
93
|
+
* memorySize: "512 MB",
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
memorySize?: number | Size;
|
|
97
|
+
/**
|
|
98
|
+
* Attaches the given list of permissions to the SSR function. Configuring this property is equivalent to calling `attachPermissions()` after the site is created.
|
|
99
|
+
* @example
|
|
100
|
+
* ```js
|
|
101
|
+
* permissions: ["ses"]
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
permissions?: Permissions;
|
|
77
105
|
/**
|
|
78
106
|
* An object with the key being the environment variable name.
|
|
79
107
|
*
|
|
@@ -99,13 +127,6 @@ export interface SsrSiteProps {
|
|
|
99
127
|
*/
|
|
100
128
|
deploy?: boolean;
|
|
101
129
|
};
|
|
102
|
-
defaults?: {
|
|
103
|
-
function?: {
|
|
104
|
-
timeout?: number;
|
|
105
|
-
memorySize?: number;
|
|
106
|
-
permissions?: Permissions;
|
|
107
|
-
};
|
|
108
|
-
};
|
|
109
130
|
/**
|
|
110
131
|
* While deploying, SST waits for the CloudFront cache invalidation process to finish. This ensures that the new content will be served once the deploy command finishes. However, this process can sometimes take more than 5 mins. For non-prod environments it might make sense to pass in `false`. That'll skip waiting for the cache to invalidate and speed up the deploy process.
|
|
111
132
|
* @default false
|
|
@@ -119,7 +140,7 @@ export interface SsrSiteProps {
|
|
|
119
140
|
/**
|
|
120
141
|
* Allows you to override default settings this construct uses internally to ceate the bucket
|
|
121
142
|
*/
|
|
122
|
-
bucket?:
|
|
143
|
+
bucket?: BucketProps | IBucket;
|
|
123
144
|
/**
|
|
124
145
|
* Pass in a value to override the default settings this construct uses to
|
|
125
146
|
* create the CDK `Distribution` internally.
|
|
@@ -136,8 +157,9 @@ export interface SsrSiteProps {
|
|
|
136
157
|
* @note The default cache policy that is used in the abscene of this property
|
|
137
158
|
* is one that performs no caching of the server response.
|
|
138
159
|
*/
|
|
139
|
-
serverRequests?:
|
|
160
|
+
serverRequests?: ICachePolicy;
|
|
140
161
|
};
|
|
162
|
+
server?: Pick<FunctionProps, "vpc" | "vpcSubnets" | "securityGroups" | "allowAllOutbound" | "allowPublicSubnet">;
|
|
141
163
|
};
|
|
142
164
|
}
|
|
143
165
|
/**
|
|
@@ -155,11 +177,13 @@ export declare class SsrSite extends Construct implements SSTConstruct {
|
|
|
155
177
|
readonly id: string;
|
|
156
178
|
protected props: Omit<SsrSiteProps, "path"> & {
|
|
157
179
|
path: string;
|
|
180
|
+
timeout: number | Duration;
|
|
181
|
+
memorySize: number | Size;
|
|
158
182
|
};
|
|
159
183
|
private doNotDeploy;
|
|
160
184
|
protected buildConfig: SsrBuildConfig;
|
|
161
185
|
private serverLambdaForEdge?;
|
|
162
|
-
protected serverLambdaForRegional?:
|
|
186
|
+
protected serverLambdaForRegional?: Function;
|
|
163
187
|
private bucket;
|
|
164
188
|
private distribution;
|
|
165
189
|
private hostedZone?;
|
|
@@ -178,11 +202,11 @@ export declare class SsrSite extends Construct implements SSTConstruct {
|
|
|
178
202
|
* The internally created CDK resources.
|
|
179
203
|
*/
|
|
180
204
|
get cdk(): {
|
|
181
|
-
function:
|
|
182
|
-
bucket:
|
|
183
|
-
distribution:
|
|
184
|
-
hostedZone:
|
|
185
|
-
certificate:
|
|
205
|
+
function: Function | undefined;
|
|
206
|
+
bucket: Bucket;
|
|
207
|
+
distribution: Distribution;
|
|
208
|
+
hostedZone: IHostedZone | undefined;
|
|
209
|
+
certificate: ICertificate | undefined;
|
|
186
210
|
};
|
|
187
211
|
/**
|
|
188
212
|
* Attaches the given list of permissions to allow the Astro server side
|
|
@@ -211,21 +235,21 @@ export declare class SsrSite extends Construct implements SSTConstruct {
|
|
|
211
235
|
private createS3AssetFileOptions;
|
|
212
236
|
private createS3Bucket;
|
|
213
237
|
private createS3Deployment;
|
|
214
|
-
protected createFunctionForRegional():
|
|
238
|
+
protected createFunctionForRegional(): Function;
|
|
215
239
|
protected createFunctionForEdge(): EdgeFunction;
|
|
216
240
|
private createFunctionPermissionsForRegional;
|
|
217
241
|
private createFunctionPermissionsForEdge;
|
|
218
242
|
private validateCloudFrontDistributionSettings;
|
|
219
|
-
protected createCloudFrontDistributionForRegional():
|
|
243
|
+
protected createCloudFrontDistributionForRegional(): Distribution;
|
|
220
244
|
private createCloudFrontDistributionForEdge;
|
|
221
245
|
protected buildDistributionDomainNames(): string[];
|
|
222
246
|
private buildDistributionDefaultBehaviorForRegional;
|
|
223
247
|
private buildDistributionDefaultBehaviorForEdge;
|
|
224
|
-
protected buildDistributionStaticFileBehaviors(origin:
|
|
225
|
-
protected createCloudFrontServerCachePolicy():
|
|
248
|
+
protected buildDistributionStaticFileBehaviors(origin: S3Origin): Record<string, BehaviorOptions>;
|
|
249
|
+
protected createCloudFrontServerCachePolicy(): CachePolicy;
|
|
226
250
|
private createCloudFrontInvalidation;
|
|
227
251
|
protected validateCustomDomainSettings(): void;
|
|
228
|
-
protected lookupHostedZone():
|
|
252
|
+
protected lookupHostedZone(): IHostedZone | undefined;
|
|
229
253
|
private createCertificate;
|
|
230
254
|
protected createRoute53Records(): void;
|
|
231
255
|
private getS3ContentReplaceValues;
|
package/constructs/SsrSite.js
CHANGED
|
@@ -6,18 +6,18 @@ import crypto from "crypto";
|
|
|
6
6
|
import spawn from "cross-spawn";
|
|
7
7
|
import { execSync } from "child_process";
|
|
8
8
|
import { Construct } from "constructs";
|
|
9
|
-
import { Fn, Token, Duration, CfnOutput, RemovalPolicy, CustomResource, } from "aws-cdk-lib";
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
import
|
|
9
|
+
import { Fn, Token, Duration as CdkDuration, CfnOutput, RemovalPolicy, CustomResource, } from "aws-cdk-lib";
|
|
10
|
+
import { Bucket } from "aws-cdk-lib/aws-s3";
|
|
11
|
+
import { Effect, PolicyStatement } from "aws-cdk-lib/aws-iam";
|
|
12
|
+
import { Function, Code, Runtime, FunctionUrlAuthType, } from "aws-cdk-lib/aws-lambda";
|
|
13
|
+
import { HostedZone, ARecord, AaaaRecord, RecordTarget, } from "aws-cdk-lib/aws-route53";
|
|
14
|
+
import { Asset } from "aws-cdk-lib/aws-s3-assets";
|
|
15
|
+
import { Distribution, ViewerProtocolPolicy, AllowedMethods, CachedMethods, LambdaEdgeEventType, CachePolicy, CacheQueryStringBehavior, CacheHeaderBehavior, CacheCookieBehavior, } from "aws-cdk-lib/aws-cloudfront";
|
|
16
|
+
import { DnsValidatedCertificate, } from "aws-cdk-lib/aws-certificatemanager";
|
|
17
17
|
import { AwsCliLayer } from "aws-cdk-lib/lambda-layer-awscli";
|
|
18
|
-
import
|
|
19
|
-
import
|
|
20
|
-
import
|
|
18
|
+
import { S3Origin, HttpOrigin } from "aws-cdk-lib/aws-cloudfront-origins";
|
|
19
|
+
import { CloudFrontTarget } from "aws-cdk-lib/aws-route53-targets";
|
|
20
|
+
import { HttpsRedirect } from "aws-cdk-lib/aws-route53-patterns";
|
|
21
21
|
import { Stack } from "./Stack.js";
|
|
22
22
|
import { Logger } from "../logger.js";
|
|
23
23
|
import { isCDKConstruct } from "./Construct.js";
|
|
@@ -57,6 +57,8 @@ export class SsrSite extends Construct {
|
|
|
57
57
|
this.props = {
|
|
58
58
|
path: ".",
|
|
59
59
|
waitForInvalidation: false,
|
|
60
|
+
timeout: "10 seconds",
|
|
61
|
+
memorySize: "1024 MB",
|
|
60
62
|
...props,
|
|
61
63
|
};
|
|
62
64
|
this.doNotDeploy = (app.local || app.skipBuild) && !this.props.dev?.deploy;
|
|
@@ -186,7 +188,7 @@ export class SsrSite extends Construct {
|
|
|
186
188
|
// depend on the Site. B/c often the site depends on the Api, causing
|
|
187
189
|
// a CloudFormation circular dependency if the Api and the Site belong
|
|
188
190
|
// to different stacks.
|
|
189
|
-
environment: ENVIRONMENT_PLACEHOLDER,
|
|
191
|
+
environment: this.doNotDeploy ? "" : ENVIRONMENT_PLACEHOLDER,
|
|
190
192
|
parameter: this.customDomainUrl || this.url,
|
|
191
193
|
},
|
|
192
194
|
},
|
|
@@ -283,7 +285,7 @@ export class SsrSite extends Construct {
|
|
|
283
285
|
if (!fs.existsSync(zipFilePath)) {
|
|
284
286
|
break;
|
|
285
287
|
}
|
|
286
|
-
assets.push(new
|
|
288
|
+
assets.push(new Asset(this, `Asset${partId}`, {
|
|
287
289
|
path: zipFilePath,
|
|
288
290
|
}));
|
|
289
291
|
}
|
|
@@ -327,7 +329,7 @@ export class SsrSite extends Construct {
|
|
|
327
329
|
// cdk.bucket is a prop
|
|
328
330
|
else {
|
|
329
331
|
const bucketProps = cdk?.bucket;
|
|
330
|
-
return new
|
|
332
|
+
return new Bucket(this, "S3Bucket", {
|
|
331
333
|
publicReadAccess: true,
|
|
332
334
|
autoDeleteObjects: true,
|
|
333
335
|
removalPolicy: RemovalPolicy.DESTROY,
|
|
@@ -337,23 +339,23 @@ export class SsrSite extends Construct {
|
|
|
337
339
|
}
|
|
338
340
|
createS3Deployment(cliLayer, assets, fileOptions) {
|
|
339
341
|
// Create a Lambda function that will be doing the uploading
|
|
340
|
-
const uploader = new
|
|
341
|
-
code:
|
|
342
|
+
const uploader = new Function(this, "S3Uploader", {
|
|
343
|
+
code: Code.fromAsset(path.join(__dirname, "../support/base-site-custom-resource")),
|
|
342
344
|
layers: [cliLayer],
|
|
343
|
-
runtime:
|
|
345
|
+
runtime: Runtime.PYTHON_3_7,
|
|
344
346
|
handler: "s3-upload.handler",
|
|
345
|
-
timeout:
|
|
347
|
+
timeout: CdkDuration.minutes(15),
|
|
346
348
|
memorySize: 1024,
|
|
347
349
|
});
|
|
348
350
|
this.bucket.grantReadWrite(uploader);
|
|
349
351
|
assets.forEach((asset) => asset.grantRead(uploader));
|
|
350
352
|
// Create the custom resource function
|
|
351
|
-
const handler = new
|
|
352
|
-
code:
|
|
353
|
+
const handler = new Function(this, "S3Handler", {
|
|
354
|
+
code: Code.fromAsset(path.join(__dirname, "../support/base-site-custom-resource")),
|
|
353
355
|
layers: [cliLayer],
|
|
354
|
-
runtime:
|
|
356
|
+
runtime: Runtime.PYTHON_3_7,
|
|
355
357
|
handler: "s3-handler.handler",
|
|
356
|
-
timeout:
|
|
358
|
+
timeout: CdkDuration.minutes(15),
|
|
357
359
|
memorySize: 1024,
|
|
358
360
|
environment: {
|
|
359
361
|
UPLOADER_FUNCTION_NAME: uploader.functionName,
|
|
@@ -395,10 +397,10 @@ export class SsrSite extends Construct {
|
|
|
395
397
|
return {};
|
|
396
398
|
}
|
|
397
399
|
createFunctionPermissionsForRegional() {
|
|
398
|
-
const {
|
|
400
|
+
const { permissions } = this.props;
|
|
399
401
|
this.bucket.grantReadWrite(this.serverLambdaForRegional.role);
|
|
400
|
-
if (
|
|
401
|
-
attachPermissionsToRole(this.serverLambdaForRegional.role,
|
|
402
|
+
if (permissions) {
|
|
403
|
+
attachPermissionsToRole(this.serverLambdaForRegional.role, permissions);
|
|
402
404
|
}
|
|
403
405
|
}
|
|
404
406
|
createFunctionPermissionsForEdge() {
|
|
@@ -420,8 +422,8 @@ export class SsrSite extends Construct {
|
|
|
420
422
|
createCloudFrontDistributionForRegional() {
|
|
421
423
|
const { cdk } = this.props;
|
|
422
424
|
const cfDistributionProps = cdk?.distribution || {};
|
|
423
|
-
const s3Origin = new
|
|
424
|
-
return new
|
|
425
|
+
const s3Origin = new S3Origin(this.bucket);
|
|
426
|
+
return new Distribution(this, "Distribution", {
|
|
425
427
|
// these values can be overwritten by cfDistributionProps
|
|
426
428
|
defaultRootObject: "",
|
|
427
429
|
// Override props.
|
|
@@ -439,8 +441,8 @@ export class SsrSite extends Construct {
|
|
|
439
441
|
createCloudFrontDistributionForEdge() {
|
|
440
442
|
const { cdk } = this.props;
|
|
441
443
|
const cfDistributionProps = cdk?.distribution || {};
|
|
442
|
-
const s3Origin = new
|
|
443
|
-
return new
|
|
444
|
+
const s3Origin = new S3Origin(this.bucket);
|
|
445
|
+
return new Distribution(this, "Distribution", {
|
|
444
446
|
// these values can be overwritten by cfDistributionProps
|
|
445
447
|
defaultRootObject: "",
|
|
446
448
|
// Override props.
|
|
@@ -473,13 +475,13 @@ export class SsrSite extends Construct {
|
|
|
473
475
|
const { cdk } = this.props;
|
|
474
476
|
const cfDistributionProps = cdk?.distribution || {};
|
|
475
477
|
const fnUrl = this.serverLambdaForRegional.addFunctionUrl({
|
|
476
|
-
authType:
|
|
478
|
+
authType: FunctionUrlAuthType.NONE,
|
|
477
479
|
});
|
|
478
480
|
return {
|
|
479
|
-
viewerProtocolPolicy:
|
|
480
|
-
origin: new
|
|
481
|
-
allowedMethods:
|
|
482
|
-
cachedMethods:
|
|
481
|
+
viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
482
|
+
origin: new HttpOrigin(Fn.parseDomainName(fnUrl.url)),
|
|
483
|
+
allowedMethods: AllowedMethods.ALLOW_ALL,
|
|
484
|
+
cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS,
|
|
483
485
|
compress: true,
|
|
484
486
|
cachePolicy: cdk?.cachePolicies?.serverRequests ??
|
|
485
487
|
this.createCloudFrontServerCachePolicy(),
|
|
@@ -490,10 +492,10 @@ export class SsrSite extends Construct {
|
|
|
490
492
|
const { cdk } = this.props;
|
|
491
493
|
const cfDistributionProps = cdk?.distribution || {};
|
|
492
494
|
return {
|
|
493
|
-
viewerProtocolPolicy:
|
|
495
|
+
viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
494
496
|
origin,
|
|
495
|
-
allowedMethods:
|
|
496
|
-
cachedMethods:
|
|
497
|
+
allowedMethods: AllowedMethods.ALLOW_ALL,
|
|
498
|
+
cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS,
|
|
497
499
|
compress: true,
|
|
498
500
|
cachePolicy: cdk?.cachePolicies?.serverRequests ??
|
|
499
501
|
this.createCloudFrontServerCachePolicy(),
|
|
@@ -502,7 +504,7 @@ export class SsrSite extends Construct {
|
|
|
502
504
|
edgeLambdas: [
|
|
503
505
|
{
|
|
504
506
|
includeBody: true,
|
|
505
|
-
eventType:
|
|
507
|
+
eventType: LambdaEdgeEventType.ORIGIN_REQUEST,
|
|
506
508
|
functionVersion: this.serverLambdaForEdge.currentVersion,
|
|
507
509
|
},
|
|
508
510
|
...(cfDistributionProps.defaultBehavior?.edgeLambdas || []),
|
|
@@ -513,12 +515,12 @@ export class SsrSite extends Construct {
|
|
|
513
515
|
const { cdk } = this.props;
|
|
514
516
|
// Create additional behaviours for statics
|
|
515
517
|
const staticBehaviourOptions = {
|
|
516
|
-
viewerProtocolPolicy:
|
|
518
|
+
viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
517
519
|
origin,
|
|
518
|
-
allowedMethods:
|
|
519
|
-
cachedMethods:
|
|
520
|
+
allowedMethods: AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
|
|
521
|
+
cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS,
|
|
520
522
|
compress: true,
|
|
521
|
-
cachePolicy:
|
|
523
|
+
cachePolicy: CachePolicy.CACHING_OPTIMIZED,
|
|
522
524
|
};
|
|
523
525
|
// Add behaviour for public folder statics (excluding build)
|
|
524
526
|
const staticsBehaviours = {};
|
|
@@ -534,13 +536,13 @@ export class SsrSite extends Construct {
|
|
|
534
536
|
return staticsBehaviours;
|
|
535
537
|
}
|
|
536
538
|
createCloudFrontServerCachePolicy() {
|
|
537
|
-
return new
|
|
538
|
-
queryStringBehavior:
|
|
539
|
-
headerBehavior:
|
|
540
|
-
cookieBehavior:
|
|
541
|
-
defaultTtl:
|
|
542
|
-
maxTtl:
|
|
543
|
-
minTtl:
|
|
539
|
+
return new CachePolicy(this, "ServerCache", {
|
|
540
|
+
queryStringBehavior: CacheQueryStringBehavior.all(),
|
|
541
|
+
headerBehavior: CacheHeaderBehavior.none(),
|
|
542
|
+
cookieBehavior: CacheCookieBehavior.all(),
|
|
543
|
+
defaultTtl: CdkDuration.days(0),
|
|
544
|
+
maxTtl: CdkDuration.days(365),
|
|
545
|
+
minTtl: CdkDuration.days(0),
|
|
544
546
|
enableAcceptEncodingBrotli: true,
|
|
545
547
|
enableAcceptEncodingGzip: true,
|
|
546
548
|
comment: "SST server response cache policy",
|
|
@@ -548,17 +550,17 @@ export class SsrSite extends Construct {
|
|
|
548
550
|
}
|
|
549
551
|
createCloudFrontInvalidation(cliLayer) {
|
|
550
552
|
// Create a Lambda function that will be doing the invalidation
|
|
551
|
-
const invalidator = new
|
|
552
|
-
code:
|
|
553
|
+
const invalidator = new Function(this, "CloudFrontInvalidator", {
|
|
554
|
+
code: Code.fromAsset(path.join(__dirname, "../support/base-site-custom-resource")),
|
|
553
555
|
layers: [cliLayer],
|
|
554
|
-
runtime:
|
|
556
|
+
runtime: Runtime.PYTHON_3_7,
|
|
555
557
|
handler: "cf-invalidate.handler",
|
|
556
|
-
timeout:
|
|
558
|
+
timeout: CdkDuration.minutes(15),
|
|
557
559
|
memorySize: 1024,
|
|
558
560
|
});
|
|
559
561
|
// Grant permissions to invalidate CF Distribution
|
|
560
|
-
invalidator.addToRolePolicy(new
|
|
561
|
-
effect:
|
|
562
|
+
invalidator.addToRolePolicy(new PolicyStatement({
|
|
563
|
+
effect: Effect.ALLOW,
|
|
562
564
|
actions: [
|
|
563
565
|
"cloudfront:GetInvalidation",
|
|
564
566
|
"cloudfront:CreateInvalidation",
|
|
@@ -608,7 +610,7 @@ export class SsrSite extends Construct {
|
|
|
608
610
|
}
|
|
609
611
|
let hostedZone;
|
|
610
612
|
if (typeof customDomain === "string") {
|
|
611
|
-
hostedZone =
|
|
613
|
+
hostedZone = HostedZone.fromLookup(this, "HostedZone", {
|
|
612
614
|
domainName: customDomain,
|
|
613
615
|
});
|
|
614
616
|
}
|
|
@@ -616,7 +618,7 @@ export class SsrSite extends Construct {
|
|
|
616
618
|
hostedZone = customDomain.cdk.hostedZone;
|
|
617
619
|
}
|
|
618
620
|
else if (typeof customDomain.hostedZone === "string") {
|
|
619
|
-
hostedZone =
|
|
621
|
+
hostedZone = HostedZone.fromLookup(this, "HostedZone", {
|
|
620
622
|
domainName: customDomain.hostedZone,
|
|
621
623
|
});
|
|
622
624
|
}
|
|
@@ -625,7 +627,7 @@ export class SsrSite extends Construct {
|
|
|
625
627
|
if (customDomain.isExternalDomain === true) {
|
|
626
628
|
return;
|
|
627
629
|
}
|
|
628
|
-
hostedZone =
|
|
630
|
+
hostedZone = HostedZone.fromLookup(this, "HostedZone", {
|
|
629
631
|
domainName: customDomain.domainName,
|
|
630
632
|
});
|
|
631
633
|
}
|
|
@@ -643,7 +645,7 @@ export class SsrSite extends Construct {
|
|
|
643
645
|
// HostedZone is set for Route 53 domains
|
|
644
646
|
if (this.hostedZone) {
|
|
645
647
|
if (typeof customDomain === "string") {
|
|
646
|
-
acmCertificate = new
|
|
648
|
+
acmCertificate = new DnsValidatedCertificate(this, "Certificate", {
|
|
647
649
|
domainName: customDomain,
|
|
648
650
|
hostedZone: this.hostedZone,
|
|
649
651
|
region: "us-east-1",
|
|
@@ -653,7 +655,7 @@ export class SsrSite extends Construct {
|
|
|
653
655
|
acmCertificate = customDomain.cdk.certificate;
|
|
654
656
|
}
|
|
655
657
|
else {
|
|
656
|
-
acmCertificate = new
|
|
658
|
+
acmCertificate = new DnsValidatedCertificate(this, "Certificate", {
|
|
657
659
|
domainName: customDomain.domainName,
|
|
658
660
|
hostedZone: this.hostedZone,
|
|
659
661
|
region: "us-east-1",
|
|
@@ -686,13 +688,13 @@ export class SsrSite extends Construct {
|
|
|
686
688
|
const recordProps = {
|
|
687
689
|
recordName,
|
|
688
690
|
zone: this.hostedZone,
|
|
689
|
-
target:
|
|
691
|
+
target: RecordTarget.fromAlias(new CloudFrontTarget(this.distribution)),
|
|
690
692
|
};
|
|
691
|
-
new
|
|
692
|
-
new
|
|
693
|
+
new ARecord(this, "AliasRecord", recordProps);
|
|
694
|
+
new AaaaRecord(this, "AliasRecordAAAA", recordProps);
|
|
693
695
|
// Create Alias redirect record
|
|
694
696
|
if (domainAlias) {
|
|
695
|
-
new
|
|
697
|
+
new HttpsRedirect(this, "Redirect", {
|
|
696
698
|
zone: this.hostedZone,
|
|
697
699
|
recordNames: [domainAlias],
|
|
698
700
|
targetDomain: recordName,
|
package/constructs/StaticSite.js
CHANGED
|
@@ -155,7 +155,7 @@ 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
|
},
|
|
@@ -19,7 +19,7 @@ export function bindParameters(c) {
|
|
|
19
19
|
}
|
|
20
20
|
const app = c.node.root;
|
|
21
21
|
Object.entries(binding.variables)
|
|
22
|
-
.filter(([, variable]) => variable.parameter)
|
|
22
|
+
.filter(([, variable]) => variable.parameter !== undefined)
|
|
23
23
|
.forEach(([prop, variable]) => {
|
|
24
24
|
const resId = `Parameter_${prop}`;
|
|
25
25
|
if (!c.node.tryFindChild(resId)) {
|
package/package.json
CHANGED
package/runtime/server.js
CHANGED
|
@@ -58,6 +58,8 @@ export const useRuntimeServer = Context.memo(async () => {
|
|
|
58
58
|
}), async (req, res) => {
|
|
59
59
|
const worker = workers.fromID(req.params.workerID);
|
|
60
60
|
bus.publish("function.error", {
|
|
61
|
+
requestID: workers.getCurrentRequestID(worker.workerID),
|
|
62
|
+
workerID: worker.workerID,
|
|
61
63
|
functionID: worker.functionID,
|
|
62
64
|
...req.body,
|
|
63
65
|
});
|
|
@@ -66,7 +68,6 @@ export const useRuntimeServer = Context.memo(async () => {
|
|
|
66
68
|
app.get(`/:workerID/${cfg.API_VERSION}/runtime/invocation/next`, async (req, res) => {
|
|
67
69
|
Logger.debug("Worker", req.params.workerID, "is waiting for next invocation");
|
|
68
70
|
const payload = await next(req.params.workerID);
|
|
69
|
-
workers.setCurrentRequestID(req.params.workerID, payload.context.awsRequestId);
|
|
70
71
|
Logger.debug("Worker", req.params.workerID, "sending next payload");
|
|
71
72
|
res.set({
|
|
72
73
|
"Lambda-Runtime-Aws-Request-Id": payload.context.awsRequestId,
|
package/runtime/workers.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ interface Worker {
|
|
|
26
26
|
}
|
|
27
27
|
export declare const useRuntimeWorkers: () => Promise<{
|
|
28
28
|
fromID(workerID: string): Worker;
|
|
29
|
+
getCurrentRequestID(workerID: string): string | undefined;
|
|
29
30
|
setCurrentRequestID(workerID: string, requestID: string): void;
|
|
30
31
|
stdout(workerID: string, message: string): void;
|
|
31
32
|
exited(workerID: string): void;
|
package/runtime/workers.js
CHANGED
|
@@ -35,6 +35,7 @@ export const useRuntimeWorkers = Context.memo(async () => {
|
|
|
35
35
|
const build = await builder.artifact(evt.properties.functionID);
|
|
36
36
|
if (!build)
|
|
37
37
|
return;
|
|
38
|
+
lastRequestId.set(evt.properties.workerID, evt.properties.requestID);
|
|
38
39
|
await handler.startWorker({
|
|
39
40
|
...build,
|
|
40
41
|
workerID: evt.properties.workerID,
|
|
@@ -54,6 +55,9 @@ export const useRuntimeWorkers = Context.memo(async () => {
|
|
|
54
55
|
fromID(workerID) {
|
|
55
56
|
return workers.get(workerID);
|
|
56
57
|
},
|
|
58
|
+
getCurrentRequestID(workerID) {
|
|
59
|
+
return lastRequestId.get(workerID);
|
|
60
|
+
},
|
|
57
61
|
setCurrentRequestID(workerID, requestID) {
|
|
58
62
|
lastRequestId.set(workerID, requestID);
|
|
59
63
|
},
|
package/sst.mjs
CHANGED
|
@@ -1366,7 +1366,7 @@ async function monitor(stack) {
|
|
|
1366
1366
|
if (resource.ResourceStatusReason?.includes(
|
|
1367
1367
|
"Resource creation cancelled"
|
|
1368
1368
|
) || resource.ResourceStatusReason?.includes(
|
|
1369
|
-
"Resource
|
|
1369
|
+
"Resource update cancelled"
|
|
1370
1370
|
) || resource.ResourceStatusReason?.includes("Resource creation Initiated"))
|
|
1371
1371
|
continue;
|
|
1372
1372
|
if (resource.ResourceStatusReason)
|
|
@@ -3041,6 +3041,8 @@ var init_server = __esm({
|
|
|
3041
3041
|
async (req, res) => {
|
|
3042
3042
|
const worker = workers.fromID(req.params.workerID);
|
|
3043
3043
|
bus.publish("function.error", {
|
|
3044
|
+
requestID: workers.getCurrentRequestID(worker.workerID),
|
|
3045
|
+
workerID: worker.workerID,
|
|
3044
3046
|
functionID: worker.functionID,
|
|
3045
3047
|
...req.body
|
|
3046
3048
|
});
|
|
@@ -3056,10 +3058,6 @@ var init_server = __esm({
|
|
|
3056
3058
|
"is waiting for next invocation"
|
|
3057
3059
|
);
|
|
3058
3060
|
const payload = await next(req.params.workerID);
|
|
3059
|
-
workers.setCurrentRequestID(
|
|
3060
|
-
req.params.workerID,
|
|
3061
|
-
payload.context.awsRequestId
|
|
3062
|
-
);
|
|
3063
3061
|
Logger.debug("Worker", req.params.workerID, "sending next payload");
|
|
3064
3062
|
res.set({
|
|
3065
3063
|
"Lambda-Runtime-Aws-Request-Id": payload.context.awsRequestId,
|
|
@@ -3209,6 +3207,7 @@ var init_workers = __esm({
|
|
|
3209
3207
|
const build2 = await builder.artifact(evt.properties.functionID);
|
|
3210
3208
|
if (!build2)
|
|
3211
3209
|
return;
|
|
3210
|
+
lastRequestId.set(evt.properties.workerID, evt.properties.requestID);
|
|
3212
3211
|
await handler.startWorker({
|
|
3213
3212
|
...build2,
|
|
3214
3213
|
workerID: evt.properties.workerID,
|
|
@@ -3228,6 +3227,9 @@ var init_workers = __esm({
|
|
|
3228
3227
|
fromID(workerID) {
|
|
3229
3228
|
return workers.get(workerID);
|
|
3230
3229
|
},
|
|
3230
|
+
getCurrentRequestID(workerID) {
|
|
3231
|
+
return lastRequestId.get(workerID);
|
|
3232
|
+
},
|
|
3231
3233
|
setCurrentRequestID(workerID, requestID) {
|
|
3232
3234
|
lastRequestId.set(workerID, requestID);
|
|
3233
3235
|
},
|
package/stacks/monitor.js
CHANGED
|
@@ -89,7 +89,7 @@ export async function monitor(stack) {
|
|
|
89
89
|
});
|
|
90
90
|
for (const resource of resources.StackResources || []) {
|
|
91
91
|
if (resource.ResourceStatusReason?.includes("Resource creation cancelled") ||
|
|
92
|
-
resource.ResourceStatusReason?.includes("Resource
|
|
92
|
+
resource.ResourceStatusReason?.includes("Resource update cancelled") ||
|
|
93
93
|
resource.ResourceStatusReason?.includes("Resource creation Initiated"))
|
|
94
94
|
continue;
|
|
95
95
|
if (resource.ResourceStatusReason)
|
|
@@ -14618,6 +14618,7 @@ try {
|
|
|
14618
14618
|
trace: ex.stack?.split("\n")
|
|
14619
14619
|
})
|
|
14620
14620
|
});
|
|
14621
|
+
process.exit(1);
|
|
14621
14622
|
}
|
|
14622
14623
|
var timeout;
|
|
14623
14624
|
while (true) {
|