sst 2.0.1 → 2.0.2
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.js +14 -4
- package/cli/commands/env.js +8 -0
- package/constructs/ApiGatewayV1Api.js +1 -1
- package/constructs/AstroSite.js +4 -3
- package/constructs/EdgeFunction.d.ts +1 -0
- package/constructs/EdgeFunction.js +6 -2
- package/constructs/Function.d.ts +17 -50
- package/constructs/Function.js +0 -3
- package/constructs/NextjsSite.js +2 -1
- package/constructs/RemixSite.js +8 -3
- package/constructs/SolidStartSite.js +4 -3
- package/constructs/SsrFunction.d.ts +1 -0
- package/constructs/SsrFunction.js +6 -2
- package/constructs/SsrSite.d.ts +9 -0
- package/constructs/SsrSite.js +3 -3
- package/constructs/StaticSite.d.ts +2 -0
- package/constructs/StaticSite.js +17 -14
- package/package.json +1 -1
- package/sst.mjs +83 -67
package/bootstrap.js
CHANGED
|
@@ -55,11 +55,21 @@ async function loadCDKStatus() {
|
|
|
55
55
|
const { Stacks: stacks } = await client.send(new DescribeStacksCommand({
|
|
56
56
|
StackName: "CDKToolkit",
|
|
57
57
|
}));
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
// Check CDK bootstrap stack exists
|
|
59
|
+
if (!stacks || stacks.length === 0)
|
|
60
|
+
return false;
|
|
61
|
+
// Check CDK bootstrap stack deployed successfully
|
|
62
|
+
if (!["CREATE_COMPLETE", "UPDATE_COMPLETE"].includes(stacks[0].StackStatus)) {
|
|
63
|
+
return false;
|
|
62
64
|
}
|
|
65
|
+
// Check CDK bootstrap stack is up to date
|
|
66
|
+
// note: there is no a programmatical way to get the minimal required version
|
|
67
|
+
// of CDK bootstrap stack. We are going to hardcode it to 14 for now,
|
|
68
|
+
// which is the latest version as of CDK v2.62.2
|
|
69
|
+
const output = stacks[0].Outputs?.find((o) => o.OutputKey === "BootstrapVersion");
|
|
70
|
+
if (!output || parseInt(output.OutputValue) < 14)
|
|
71
|
+
return false;
|
|
72
|
+
return true;
|
|
63
73
|
}
|
|
64
74
|
catch (e) {
|
|
65
75
|
if (e.name === "ValidationError" &&
|
package/cli/commands/env.js
CHANGED
|
@@ -10,6 +10,8 @@ export const env = (program) => program.command("env <command>", "Load environme
|
|
|
10
10
|
const fs = await import("fs/promises");
|
|
11
11
|
const { SiteEnv } = await import("../../site-env.js");
|
|
12
12
|
const { spawnSync } = await import("child_process");
|
|
13
|
+
const { useAWSCredentials } = await import("../../credentials.js");
|
|
14
|
+
const { useProject } = await import("../../project.js");
|
|
13
15
|
let spinner;
|
|
14
16
|
while (true) {
|
|
15
17
|
const exists = await fs
|
|
@@ -24,10 +26,16 @@ export const env = (program) => program.command("env <command>", "Load environme
|
|
|
24
26
|
spinner?.succeed();
|
|
25
27
|
const sites = await SiteEnv.values();
|
|
26
28
|
const env = sites[process.cwd()] || {};
|
|
29
|
+
const project = useProject();
|
|
30
|
+
const credentials = await useAWSCredentials();
|
|
27
31
|
const result = spawnSync(args.command, {
|
|
28
32
|
env: {
|
|
29
33
|
...process.env,
|
|
30
34
|
...env,
|
|
35
|
+
AWS_ACCESS_KEY_ID: credentials.accessKeyId,
|
|
36
|
+
AWS_SECRET_ACCESS_KEY: credentials.secretAccessKey,
|
|
37
|
+
AWS_SESSION_TOKEN: credentials.sessionToken,
|
|
38
|
+
AWS_REGION: project.config.region,
|
|
31
39
|
},
|
|
32
40
|
stdio: "inherit",
|
|
33
41
|
shell: process.env.SHELL || true,
|
|
@@ -569,7 +569,7 @@ export class ApiGatewayV1Api extends Construct {
|
|
|
569
569
|
if (!value.userPoolIds) {
|
|
570
570
|
throw new Error(`Missing "userPoolIds" for "${key}" authorizer`);
|
|
571
571
|
}
|
|
572
|
-
const userPools = value.userPoolIds.map((userPoolId) => cognito.UserPool.fromUserPoolId(this, `${key}-ImportedUserPool`, userPoolId));
|
|
572
|
+
const userPools = value.userPoolIds.map((userPoolId) => cognito.UserPool.fromUserPoolId(this, `${key}-${userPoolId}-ImportedUserPool`, userPoolId));
|
|
573
573
|
this.authorizersData[key] = new apig.CognitoUserPoolsAuthorizer(this, key, {
|
|
574
574
|
cognitoUserPools: userPools,
|
|
575
575
|
authorizerName: value.name,
|
package/constructs/AstroSite.js
CHANGED
|
@@ -36,14 +36,14 @@ export class AstroSite extends SsrSite {
|
|
|
36
36
|
super.validateBuildOutput();
|
|
37
37
|
}
|
|
38
38
|
createFunctionForRegional() {
|
|
39
|
-
const { memorySize, timeout, environment, bind, cdk } = this.props;
|
|
39
|
+
const { runtime, memorySize, timeout, environment, bind, cdk } = this.props;
|
|
40
40
|
// Create function
|
|
41
41
|
const fn = new Function(this, `ServerFunction`, {
|
|
42
42
|
description: "Server handler",
|
|
43
43
|
handler: path.join(this.props.path, "dist", "server", "entry.handler"),
|
|
44
44
|
bind,
|
|
45
45
|
logRetention: "three_days",
|
|
46
|
-
runtime
|
|
46
|
+
runtime,
|
|
47
47
|
memorySize,
|
|
48
48
|
timeout,
|
|
49
49
|
nodejs: {
|
|
@@ -57,7 +57,7 @@ export class AstroSite extends SsrSite {
|
|
|
57
57
|
return fn;
|
|
58
58
|
}
|
|
59
59
|
createFunctionForEdge() {
|
|
60
|
-
const { timeout, memorySize, permissions, environment } = this.props;
|
|
60
|
+
const { runtime, timeout, memorySize, permissions, environment } = this.props;
|
|
61
61
|
// Create a directory that we will use to create the bundled version
|
|
62
62
|
// of the "core server build" along with our custom Lamba server handler.
|
|
63
63
|
const outputPath = path.resolve(path.join(useProject().paths.artifacts, `AstroSiteFunction-${this.node.id}-${this.node.addr}`));
|
|
@@ -91,6 +91,7 @@ export class AstroSite extends SsrSite {
|
|
|
91
91
|
scopeOverride: this,
|
|
92
92
|
bundlePath: outputPath,
|
|
93
93
|
handler: "entry.handler",
|
|
94
|
+
runtime,
|
|
94
95
|
timeout,
|
|
95
96
|
memorySize,
|
|
96
97
|
permissions,
|
|
@@ -7,6 +7,7 @@ import { Permissions } from "./util/permission.js";
|
|
|
7
7
|
export interface EdgeFunctionProps {
|
|
8
8
|
bundlePath: string;
|
|
9
9
|
handler: string;
|
|
10
|
+
runtime?: "nodejs14.x" | "nodejs16.x" | "nodejs18.x";
|
|
10
11
|
timeout: number | Duration;
|
|
11
12
|
memorySize: number | Size;
|
|
12
13
|
permissions?: Permissions;
|
|
@@ -108,7 +108,7 @@ ${exports}
|
|
|
108
108
|
return role;
|
|
109
109
|
}
|
|
110
110
|
createFunction(asset) {
|
|
111
|
-
const { timeout, memorySize } = this.props;
|
|
111
|
+
const { runtime, timeout, memorySize } = this.props;
|
|
112
112
|
const name = this.node.id;
|
|
113
113
|
// Create a S3 bucket in us-east-1 to store Lambda code. Create
|
|
114
114
|
// 1 bucket for all Edge functions.
|
|
@@ -122,7 +122,11 @@ ${exports}
|
|
|
122
122
|
S3Bucket: asset.s3BucketName,
|
|
123
123
|
S3Key: asset.s3ObjectKey,
|
|
124
124
|
},
|
|
125
|
-
Runtime:
|
|
125
|
+
Runtime: runtime === "nodejs14.x"
|
|
126
|
+
? lambda.Runtime.NODEJS_14_X.name
|
|
127
|
+
: runtime === "nodejs16.x"
|
|
128
|
+
? lambda.Runtime.NODEJS_16_X.name
|
|
129
|
+
: lambda.Runtime.NODEJS_18_X.name,
|
|
126
130
|
MemorySize: typeof memorySize === "string"
|
|
127
131
|
? toCdkSize(memorySize).toMebibytes()
|
|
128
132
|
: memorySize,
|
package/constructs/Function.d.ts
CHANGED
|
@@ -59,7 +59,7 @@ export interface FunctionProps extends Omit<lambda.FunctionOptions, "functionNam
|
|
|
59
59
|
* })
|
|
60
60
|
*```
|
|
61
61
|
*/
|
|
62
|
-
copyFiles?:
|
|
62
|
+
copyFiles?: FunctionCopyFilesProps[];
|
|
63
63
|
/**
|
|
64
64
|
* Used to configure nodejs function properties
|
|
65
65
|
*/
|
|
@@ -112,15 +112,13 @@ export interface FunctionProps extends Omit<lambda.FunctionOptions, "functionNam
|
|
|
112
112
|
*/
|
|
113
113
|
handler?: string;
|
|
114
114
|
/**
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* @default Defaults to the same directory as sst.json
|
|
118
|
-
*
|
|
115
|
+
* The runtime environment for the function.
|
|
116
|
+
* @default "nodejs16.x"
|
|
119
117
|
* @example
|
|
120
118
|
* ```js
|
|
121
119
|
* new Function(stack, "Function", {
|
|
122
|
-
* srcPath: "packages/backend",
|
|
123
120
|
* handler: "function.handler",
|
|
121
|
+
* runtime: "nodejs18.x",
|
|
124
122
|
* })
|
|
125
123
|
*```
|
|
126
124
|
*/
|
|
@@ -348,7 +346,7 @@ export interface NodeJSProps {
|
|
|
348
346
|
* @example
|
|
349
347
|
* ```js
|
|
350
348
|
* new Function(stack, "Function", {
|
|
351
|
-
*
|
|
349
|
+
* nodejs: {
|
|
352
350
|
* loader: {
|
|
353
351
|
* ".png": "file"
|
|
354
352
|
* }
|
|
@@ -363,7 +361,7 @@ export interface NodeJSProps {
|
|
|
363
361
|
* @example
|
|
364
362
|
* ```js
|
|
365
363
|
* new Function(stack, "Function", {
|
|
366
|
-
*
|
|
364
|
+
* nodejs: {
|
|
367
365
|
* nodeModules: ["pg"]
|
|
368
366
|
* }
|
|
369
367
|
* })
|
|
@@ -376,7 +374,7 @@ export interface NodeJSProps {
|
|
|
376
374
|
* @example
|
|
377
375
|
* ```js
|
|
378
376
|
* new Function(stack, "Function", {
|
|
379
|
-
*
|
|
377
|
+
* nodejs: {
|
|
380
378
|
* banner: "console.log('Function starting')"
|
|
381
379
|
* }
|
|
382
380
|
* })
|
|
@@ -395,7 +393,7 @@ export interface NodeJSProps {
|
|
|
395
393
|
* @example
|
|
396
394
|
* ```js
|
|
397
395
|
* new Function(stack, "Function", {
|
|
398
|
-
*
|
|
396
|
+
* nodejs: {
|
|
399
397
|
* minify: false
|
|
400
398
|
* }
|
|
401
399
|
* })
|
|
@@ -403,14 +401,14 @@ export interface NodeJSProps {
|
|
|
403
401
|
*/
|
|
404
402
|
minify?: boolean;
|
|
405
403
|
/**
|
|
406
|
-
* Configure
|
|
404
|
+
* Configure format
|
|
407
405
|
*
|
|
408
406
|
* @default "cjs"
|
|
409
407
|
*
|
|
410
408
|
* @example
|
|
411
409
|
* ```js
|
|
412
410
|
* new Function(stack, "Function", {
|
|
413
|
-
*
|
|
411
|
+
* nodejs: {
|
|
414
412
|
* format: "esm"
|
|
415
413
|
* }
|
|
416
414
|
* })
|
|
@@ -425,8 +423,8 @@ export interface NodeJSProps {
|
|
|
425
423
|
* @example
|
|
426
424
|
* ```js
|
|
427
425
|
* new Function(stack, "Function", {
|
|
428
|
-
*
|
|
429
|
-
*
|
|
426
|
+
* nodejs: {
|
|
427
|
+
* sourcemap: true
|
|
430
428
|
* }
|
|
431
429
|
* })
|
|
432
430
|
* ```
|
|
@@ -445,7 +443,7 @@ export interface JavaProps {
|
|
|
445
443
|
* @example
|
|
446
444
|
* ```js
|
|
447
445
|
* new Function(stack, "Function", {
|
|
448
|
-
*
|
|
446
|
+
* java: {
|
|
449
447
|
* buildTask: "bundle"
|
|
450
448
|
* }
|
|
451
449
|
* })
|
|
@@ -460,7 +458,7 @@ export interface JavaProps {
|
|
|
460
458
|
* @example
|
|
461
459
|
* ```js
|
|
462
460
|
* new Function(stack, "Function", {
|
|
463
|
-
*
|
|
461
|
+
* java: {
|
|
464
462
|
* buildOutputDir: "output"
|
|
465
463
|
* }
|
|
466
464
|
* })
|
|
@@ -475,7 +473,7 @@ export interface JavaProps {
|
|
|
475
473
|
* @example
|
|
476
474
|
* ```js
|
|
477
475
|
* new Function(stack, "Function", {
|
|
478
|
-
*
|
|
476
|
+
* java: {
|
|
479
477
|
* experimentalUseProvidedRuntime: "provided.al2"
|
|
480
478
|
* }
|
|
481
479
|
* })
|
|
@@ -483,47 +481,17 @@ export interface JavaProps {
|
|
|
483
481
|
*/
|
|
484
482
|
experimentalUseProvidedRuntime?: "provided" | "provided.al2";
|
|
485
483
|
}
|
|
486
|
-
export type FunctionBundleProp = FunctionBundlePythonProps | boolean;
|
|
487
|
-
interface FunctionBundleBase {
|
|
488
|
-
}
|
|
489
|
-
/**
|
|
490
|
-
* Used to configure Python bundling options
|
|
491
|
-
*/
|
|
492
|
-
export interface FunctionBundlePythonProps extends FunctionBundleBase {
|
|
493
|
-
/**
|
|
494
|
-
* A list of commands to override the [default installing behavior](Function#bundle) for Python dependencies.
|
|
495
|
-
*
|
|
496
|
-
* Each string in the array is a command that'll be run. For example:
|
|
497
|
-
*
|
|
498
|
-
* @default "[]"
|
|
499
|
-
*
|
|
500
|
-
* @example
|
|
501
|
-
* ```js
|
|
502
|
-
* new Function(stack, "Function", {
|
|
503
|
-
* bundle: {
|
|
504
|
-
* installCommands: [
|
|
505
|
-
* 'export VARNAME="my value"',
|
|
506
|
-
* 'pip install --index-url https://domain.com/pypi/myprivatemodule/simple/ --extra-index-url https://pypi.org/simple -r requirements.txt .',
|
|
507
|
-
* ]
|
|
508
|
-
* }
|
|
509
|
-
* })
|
|
510
|
-
* ```
|
|
511
|
-
*/
|
|
512
|
-
installCommands?: string[];
|
|
513
|
-
}
|
|
514
484
|
/**
|
|
515
485
|
* Used to configure additional files to copy into the function bundle
|
|
516
486
|
*
|
|
517
487
|
* @example
|
|
518
488
|
* ```js
|
|
519
489
|
* new Function(stack, "Function", {
|
|
520
|
-
*
|
|
521
|
-
* copyFiles: [{ from: "src/index.js" }]
|
|
522
|
-
* }
|
|
490
|
+
* copyFiles: [{ from: "src/index.js" }]
|
|
523
491
|
* })
|
|
524
492
|
*```
|
|
525
493
|
*/
|
|
526
|
-
|
|
494
|
+
interface FunctionCopyFilesProps {
|
|
527
495
|
/**
|
|
528
496
|
* Source path relative to sst.json
|
|
529
497
|
*/
|
|
@@ -603,7 +571,6 @@ export declare class Function extends lambda.Function implements SSTConstruct {
|
|
|
603
571
|
static normalizeMemorySize(memorySize?: number | Size): number;
|
|
604
572
|
static normalizeDiskSize(diskSize?: number | Size): cdk.Size;
|
|
605
573
|
static normalizeTimeout(timeout?: number | Duration): cdk.Duration;
|
|
606
|
-
static normalizeSrcPath(srcPath: string): string;
|
|
607
574
|
static handleImportedLayer(scope: Construct, layer: lambda.ILayerVersion): lambda.ILayerVersion;
|
|
608
575
|
static isInlineDefinition(definition: any): definition is FunctionInlineDefinition;
|
|
609
576
|
static fromDefinition(scope: Construct, id: string, definition: FunctionDefinition, inheritedProps?: FunctionProps, inheritErrorMessage?: string): Function;
|
package/constructs/Function.js
CHANGED
|
@@ -366,9 +366,6 @@ export class Function extends lambda.Function {
|
|
|
366
366
|
}
|
|
367
367
|
return cdk.Duration.seconds(timeout || 10);
|
|
368
368
|
}
|
|
369
|
-
static normalizeSrcPath(srcPath) {
|
|
370
|
-
return srcPath.replace(/\/+$/, "");
|
|
371
|
-
}
|
|
372
369
|
static handleImportedLayer(scope, layer) {
|
|
373
370
|
const layerStack = Stack.of(layer);
|
|
374
371
|
const currentStack = Stack.of(scope);
|
package/constructs/NextjsSite.js
CHANGED
|
@@ -37,11 +37,12 @@ export class NextjsSite extends SsrSite {
|
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
createFunctionForRegional() {
|
|
40
|
-
const { timeout, memorySize, permissions, environment, cdk } = this.props;
|
|
40
|
+
const { runtime, timeout, memorySize, permissions, environment, cdk } = this.props;
|
|
41
41
|
const ssrFn = new SsrFunction(this, `ServerFunction`, {
|
|
42
42
|
description: "Server handler for Next.js",
|
|
43
43
|
bundlePath: path.join(this.props.path, ".open-next", "server-function"),
|
|
44
44
|
handler: "index.handler",
|
|
45
|
+
runtime,
|
|
45
46
|
timeout,
|
|
46
47
|
memorySize,
|
|
47
48
|
permissions,
|
package/constructs/RemixSite.js
CHANGED
|
@@ -112,7 +112,7 @@ export class RemixSite extends SsrSite {
|
|
|
112
112
|
return outputPath;
|
|
113
113
|
}
|
|
114
114
|
createFunctionForRegional() {
|
|
115
|
-
const { timeout, memorySize, environment, cdk } = this.props;
|
|
115
|
+
const { runtime, timeout, memorySize, environment, cdk } = this.props;
|
|
116
116
|
const bundlePath = this.createServerLambdaBundle("regional-server.js");
|
|
117
117
|
return new lambda.Function(this, `ServerFunction`, {
|
|
118
118
|
description: "Server handler for Remix",
|
|
@@ -122,7 +122,11 @@ export class RemixSite extends SsrSite {
|
|
|
122
122
|
},
|
|
123
123
|
logRetention: logs.RetentionDays.THREE_DAYS,
|
|
124
124
|
code: lambda.Code.fromAsset(bundlePath),
|
|
125
|
-
runtime:
|
|
125
|
+
runtime: runtime === "nodejs14.x"
|
|
126
|
+
? lambda.Runtime.NODEJS_14_X
|
|
127
|
+
: runtime === "nodejs16.x"
|
|
128
|
+
? lambda.Runtime.NODEJS_16_X
|
|
129
|
+
: lambda.Runtime.NODEJS_18_X,
|
|
126
130
|
memorySize: typeof memorySize === "string"
|
|
127
131
|
? toCdkSize(memorySize).toMebibytes()
|
|
128
132
|
: memorySize,
|
|
@@ -134,13 +138,14 @@ export class RemixSite extends SsrSite {
|
|
|
134
138
|
});
|
|
135
139
|
}
|
|
136
140
|
createFunctionForEdge() {
|
|
137
|
-
const { timeout, memorySize, permissions, environment } = this.props;
|
|
141
|
+
const { runtime, timeout, memorySize, permissions, environment } = this.props;
|
|
138
142
|
const bundlePath = this.createServerLambdaBundle("edge-server.js");
|
|
139
143
|
return new EdgeFunction(this, `Server`, {
|
|
140
144
|
scopeOverride: this,
|
|
141
145
|
format: "cjs",
|
|
142
146
|
bundlePath,
|
|
143
147
|
handler: "server.handler",
|
|
148
|
+
runtime,
|
|
144
149
|
timeout,
|
|
145
150
|
memorySize,
|
|
146
151
|
permissions,
|
|
@@ -26,7 +26,7 @@ export class SolidStartSite extends SsrSite {
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
createFunctionForRegional() {
|
|
29
|
-
const { timeout, memorySize, environment, cdk } = this.props;
|
|
29
|
+
const { runtime, timeout, memorySize, environment, cdk } = this.props;
|
|
30
30
|
// Bundle code
|
|
31
31
|
const handler = path.join(this.props.path, "dist", "server", "index.handler");
|
|
32
32
|
// Create function
|
|
@@ -34,7 +34,7 @@ export class SolidStartSite extends SsrSite {
|
|
|
34
34
|
description: "Server handler",
|
|
35
35
|
handler,
|
|
36
36
|
logRetention: "three_days",
|
|
37
|
-
runtime
|
|
37
|
+
runtime,
|
|
38
38
|
memorySize,
|
|
39
39
|
timeout,
|
|
40
40
|
nodejs: {
|
|
@@ -48,7 +48,7 @@ export class SolidStartSite extends SsrSite {
|
|
|
48
48
|
return fn;
|
|
49
49
|
}
|
|
50
50
|
createFunctionForEdge() {
|
|
51
|
-
const { timeout, memorySize, permissions, environment } = this.props;
|
|
51
|
+
const { runtime, 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,6 +83,7 @@ export class SolidStartSite extends SsrSite {
|
|
|
83
83
|
scopeOverride: this,
|
|
84
84
|
bundlePath: outputPath,
|
|
85
85
|
handler: "server.handler",
|
|
86
|
+
runtime,
|
|
86
87
|
timeout,
|
|
87
88
|
memorySize,
|
|
88
89
|
permissions,
|
|
@@ -7,6 +7,7 @@ import { FunctionOptions } from "aws-cdk-lib/aws-lambda";
|
|
|
7
7
|
export interface SsrFunctionProps extends Omit<FunctionOptions, "memorySize" | "timeout" | "runtime"> {
|
|
8
8
|
bundlePath: string;
|
|
9
9
|
handler: string;
|
|
10
|
+
runtime?: "nodejs14.x" | "nodejs16.x" | "nodejs18.x";
|
|
10
11
|
timeout: number | Duration;
|
|
11
12
|
memorySize: number | Size;
|
|
12
13
|
permissions?: Permissions;
|
|
@@ -30,7 +30,7 @@ export class SsrFunction extends Construct {
|
|
|
30
30
|
attachPermissionsToRole(this.function.role, permissions);
|
|
31
31
|
}
|
|
32
32
|
createFunction() {
|
|
33
|
-
const { timeout, memorySize, handler, bundlePath } = this.props;
|
|
33
|
+
const { runtime, timeout, memorySize, handler, bundlePath } = this.props;
|
|
34
34
|
// Note: cannot point the bundlePath to the `.open-next/server-function`
|
|
35
35
|
// b/c the folder contains node_modules. And pnpm node_modules
|
|
36
36
|
// contains symlinks. CDK cannot zip symlinks correctly.
|
|
@@ -57,7 +57,11 @@ export class SsrFunction extends Construct {
|
|
|
57
57
|
handler,
|
|
58
58
|
logRetention: logs.RetentionDays.THREE_DAYS,
|
|
59
59
|
code: lambda.Code.fromBucket(asset.bucket, asset.s3ObjectKey),
|
|
60
|
-
runtime:
|
|
60
|
+
runtime: runtime === "nodejs14.x"
|
|
61
|
+
? lambda.Runtime.NODEJS_14_X
|
|
62
|
+
: runtime === "nodejs16.x"
|
|
63
|
+
? lambda.Runtime.NODEJS_16_X
|
|
64
|
+
: lambda.Runtime.NODEJS_18_X,
|
|
61
65
|
architecture: lambda.Architecture.ARM_64,
|
|
62
66
|
memorySize: typeof memorySize === "string"
|
|
63
67
|
? toCdkSize(memorySize).toMebibytes()
|
package/constructs/SsrSite.d.ts
CHANGED
|
@@ -94,6 +94,15 @@ export interface SsrSiteProps {
|
|
|
94
94
|
* ```
|
|
95
95
|
*/
|
|
96
96
|
memorySize?: number | Size;
|
|
97
|
+
/**
|
|
98
|
+
* The runtime environment for the SSR function.
|
|
99
|
+
* @default nodejs18.x
|
|
100
|
+
* @example
|
|
101
|
+
* ```js
|
|
102
|
+
* runtime: "nodejs16.x",
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
runtime?: "nodejs14.x" | "nodejs16.x" | "nodejs18.x";
|
|
97
106
|
/**
|
|
98
107
|
* Attaches the given list of permissions to the SSR function. Configuring this property is equivalent to calling `attachPermissions()` after the site is created.
|
|
99
108
|
* @example
|
package/constructs/SsrSite.js
CHANGED
|
@@ -57,6 +57,7 @@ export class SsrSite extends Construct {
|
|
|
57
57
|
this.props = {
|
|
58
58
|
path: ".",
|
|
59
59
|
waitForInvalidation: false,
|
|
60
|
+
runtime: "nodejs18.x",
|
|
60
61
|
timeout: "10 seconds",
|
|
61
62
|
memorySize: "1024 MB",
|
|
62
63
|
...props,
|
|
@@ -411,11 +412,10 @@ export class SsrSite extends Construct {
|
|
|
411
412
|
/////////////////////
|
|
412
413
|
validateCloudFrontDistributionSettings() {
|
|
413
414
|
const { cdk } = this.props;
|
|
414
|
-
|
|
415
|
-
if (cfDistributionProps.certificate) {
|
|
415
|
+
if (cdk?.distribution?.certificate) {
|
|
416
416
|
throw new Error(`Do not configure the "cfDistribution.certificate". Use the "customDomain" to configure the domain certificate.`);
|
|
417
417
|
}
|
|
418
|
-
if (
|
|
418
|
+
if (cdk?.distribution?.domainNames) {
|
|
419
419
|
throw new Error(`Do not configure the "cfDistribution.domainNames". Use the "customDomain" to configure the domain name.`);
|
|
420
420
|
}
|
|
421
421
|
}
|
|
@@ -320,6 +320,8 @@ export declare class StaticSite extends Construct implements SSTConstruct {
|
|
|
320
320
|
private bundleFilenamesAsset;
|
|
321
321
|
private createS3Bucket;
|
|
322
322
|
private createS3Deployment;
|
|
323
|
+
private validateCloudFrontDistributionSettings;
|
|
324
|
+
protected buildDistributionDomainNames(): string[];
|
|
323
325
|
private createCfDistribution;
|
|
324
326
|
private createCloudFrontInvalidation;
|
|
325
327
|
protected validateCustomDomainSettings(): void;
|
package/constructs/StaticSite.js
CHANGED
|
@@ -87,6 +87,7 @@ export class StaticSite extends Construct {
|
|
|
87
87
|
// Create S3 Deployment
|
|
88
88
|
const s3deployCR = this.createS3Deployment(cliLayer, assets, filenamesAsset);
|
|
89
89
|
// Create CloudFront
|
|
90
|
+
this.validateCloudFrontDistributionSettings();
|
|
90
91
|
this.distribution = this.createCfDistribution();
|
|
91
92
|
this.distribution.node.addDependency(s3deployCR);
|
|
92
93
|
// Invalidate CloudFront
|
|
@@ -367,21 +368,20 @@ interface ImportMeta {
|
|
|
367
368
|
/////////////////////
|
|
368
369
|
// CloudFront Distribution
|
|
369
370
|
/////////////////////
|
|
370
|
-
|
|
371
|
-
const { cdk,
|
|
372
|
-
const indexPage = this.props.indexPage || "index.html";
|
|
373
|
-
const errorPage = this.props.errorPage;
|
|
374
|
-
// Validate input
|
|
371
|
+
validateCloudFrontDistributionSettings() {
|
|
372
|
+
const { cdk, errorPage } = this.props;
|
|
375
373
|
if (cdk?.distribution?.certificate) {
|
|
376
|
-
throw new Error(`Do not configure the "cfDistribution.certificate". Use the "customDomain" to configure the
|
|
374
|
+
throw new Error(`Do not configure the "cfDistribution.certificate". Use the "customDomain" to configure the domain certificate.`);
|
|
377
375
|
}
|
|
378
376
|
if (cdk?.distribution?.domainNames) {
|
|
379
|
-
throw new Error(`Do not configure the "cfDistribution.domainNames". Use the "customDomain" to configure the
|
|
377
|
+
throw new Error(`Do not configure the "cfDistribution.domainNames". Use the "customDomain" to configure the domain name.`);
|
|
380
378
|
}
|
|
381
379
|
if (errorPage && cdk?.distribution?.errorResponses) {
|
|
382
380
|
throw new Error(`Cannot configure the "cfDistribution.errorResponses" when "errorPage" is passed in. Use one or the other to configure the behavior for error pages.`);
|
|
383
381
|
}
|
|
384
|
-
|
|
382
|
+
}
|
|
383
|
+
buildDistributionDomainNames() {
|
|
384
|
+
const { customDomain } = this.props;
|
|
385
385
|
const domainNames = [];
|
|
386
386
|
if (!customDomain) {
|
|
387
387
|
// no domain
|
|
@@ -397,18 +397,21 @@ interface ImportMeta {
|
|
|
397
397
|
domainNames.push(...customDomain.alternateNames);
|
|
398
398
|
}
|
|
399
399
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
400
|
+
return domainNames;
|
|
401
|
+
}
|
|
402
|
+
createCfDistribution() {
|
|
403
|
+
const { cdk, errorPage } = this.props;
|
|
404
|
+
const indexPage = this.props.indexPage || "index.html";
|
|
404
405
|
// Create CloudFront distribution
|
|
405
406
|
return new cloudfront.Distribution(this, "Distribution", {
|
|
406
407
|
// these values can be overwritten by cfDistributionProps
|
|
407
408
|
defaultRootObject: indexPage,
|
|
408
|
-
errorResponses
|
|
409
|
+
errorResponses: !errorPage || errorPage === "redirect_to_index_page"
|
|
410
|
+
? buildErrorResponsesForRedirectToIndex(indexPage)
|
|
411
|
+
: buildErrorResponsesFor404ErrorPage(errorPage),
|
|
409
412
|
...cdk?.distribution,
|
|
410
413
|
// these values can NOT be overwritten by cfDistributionProps
|
|
411
|
-
domainNames,
|
|
414
|
+
domainNames: this.buildDistributionDomainNames(),
|
|
412
415
|
certificate: this.certificate,
|
|
413
416
|
defaultBehavior: {
|
|
414
417
|
origin: new cfOrigins.S3Origin(this.bucket),
|
package/package.json
CHANGED
package/sst.mjs
CHANGED
|
@@ -793,70 +793,6 @@ var init_site_env = __esm({
|
|
|
793
793
|
}
|
|
794
794
|
});
|
|
795
795
|
|
|
796
|
-
// src/bus.ts
|
|
797
|
-
var bus_exports = {};
|
|
798
|
-
__export(bus_exports, {
|
|
799
|
-
useBus: () => useBus
|
|
800
|
-
});
|
|
801
|
-
import crypto from "crypto";
|
|
802
|
-
var DO_NOT_LOG, useBus;
|
|
803
|
-
var init_bus = __esm({
|
|
804
|
-
"src/bus.ts"() {
|
|
805
|
-
"use strict";
|
|
806
|
-
init_context();
|
|
807
|
-
init_logger();
|
|
808
|
-
DO_NOT_LOG = /* @__PURE__ */ new Set(["stacks.metadata"]);
|
|
809
|
-
useBus = Context.memo(() => {
|
|
810
|
-
const subscriptions = {};
|
|
811
|
-
function subscribers(type) {
|
|
812
|
-
let arr = subscriptions[type];
|
|
813
|
-
if (!arr) {
|
|
814
|
-
arr = [];
|
|
815
|
-
subscriptions[type] = arr;
|
|
816
|
-
}
|
|
817
|
-
return arr;
|
|
818
|
-
}
|
|
819
|
-
const sourceID = crypto.randomBytes(16).toString("hex");
|
|
820
|
-
const result = {
|
|
821
|
-
sourceID,
|
|
822
|
-
publish(type, properties) {
|
|
823
|
-
const payload = {
|
|
824
|
-
type,
|
|
825
|
-
properties,
|
|
826
|
-
sourceID
|
|
827
|
-
};
|
|
828
|
-
if (!DO_NOT_LOG.has(type)) {
|
|
829
|
-
Logger.debug(`Publishing event ${JSON.stringify(payload)}`);
|
|
830
|
-
}
|
|
831
|
-
for (const sub of subscribers(type))
|
|
832
|
-
sub.cb(payload);
|
|
833
|
-
},
|
|
834
|
-
unsubscribe(sub) {
|
|
835
|
-
const arr = subscribers(sub.type);
|
|
836
|
-
const index = arr.indexOf(sub);
|
|
837
|
-
if (index < 0)
|
|
838
|
-
return;
|
|
839
|
-
arr.splice(index, 1);
|
|
840
|
-
},
|
|
841
|
-
subscribe(type, cb) {
|
|
842
|
-
const sub = {
|
|
843
|
-
type,
|
|
844
|
-
cb
|
|
845
|
-
};
|
|
846
|
-
subscribers(type).push(sub);
|
|
847
|
-
return sub;
|
|
848
|
-
},
|
|
849
|
-
forward(..._types) {
|
|
850
|
-
return (type, cb) => {
|
|
851
|
-
return this.subscribe(type, cb);
|
|
852
|
-
};
|
|
853
|
-
}
|
|
854
|
-
};
|
|
855
|
-
return result;
|
|
856
|
-
});
|
|
857
|
-
}
|
|
858
|
-
});
|
|
859
|
-
|
|
860
796
|
// ../../node_modules/.pnpm/tslib@2.4.1/node_modules/tslib/tslib.es6.js
|
|
861
797
|
var tslib_es6_exports = {};
|
|
862
798
|
__export(tslib_es6_exports, {
|
|
@@ -1614,6 +1550,70 @@ var init_credentials = __esm({
|
|
|
1614
1550
|
}
|
|
1615
1551
|
});
|
|
1616
1552
|
|
|
1553
|
+
// src/bus.ts
|
|
1554
|
+
var bus_exports = {};
|
|
1555
|
+
__export(bus_exports, {
|
|
1556
|
+
useBus: () => useBus
|
|
1557
|
+
});
|
|
1558
|
+
import crypto from "crypto";
|
|
1559
|
+
var DO_NOT_LOG, useBus;
|
|
1560
|
+
var init_bus = __esm({
|
|
1561
|
+
"src/bus.ts"() {
|
|
1562
|
+
"use strict";
|
|
1563
|
+
init_context();
|
|
1564
|
+
init_logger();
|
|
1565
|
+
DO_NOT_LOG = /* @__PURE__ */ new Set(["stacks.metadata"]);
|
|
1566
|
+
useBus = Context.memo(() => {
|
|
1567
|
+
const subscriptions = {};
|
|
1568
|
+
function subscribers(type) {
|
|
1569
|
+
let arr = subscriptions[type];
|
|
1570
|
+
if (!arr) {
|
|
1571
|
+
arr = [];
|
|
1572
|
+
subscriptions[type] = arr;
|
|
1573
|
+
}
|
|
1574
|
+
return arr;
|
|
1575
|
+
}
|
|
1576
|
+
const sourceID = crypto.randomBytes(16).toString("hex");
|
|
1577
|
+
const result = {
|
|
1578
|
+
sourceID,
|
|
1579
|
+
publish(type, properties) {
|
|
1580
|
+
const payload = {
|
|
1581
|
+
type,
|
|
1582
|
+
properties,
|
|
1583
|
+
sourceID
|
|
1584
|
+
};
|
|
1585
|
+
if (!DO_NOT_LOG.has(type)) {
|
|
1586
|
+
Logger.debug(`Publishing event ${JSON.stringify(payload)}`);
|
|
1587
|
+
}
|
|
1588
|
+
for (const sub of subscribers(type))
|
|
1589
|
+
sub.cb(payload);
|
|
1590
|
+
},
|
|
1591
|
+
unsubscribe(sub) {
|
|
1592
|
+
const arr = subscribers(sub.type);
|
|
1593
|
+
const index = arr.indexOf(sub);
|
|
1594
|
+
if (index < 0)
|
|
1595
|
+
return;
|
|
1596
|
+
arr.splice(index, 1);
|
|
1597
|
+
},
|
|
1598
|
+
subscribe(type, cb) {
|
|
1599
|
+
const sub = {
|
|
1600
|
+
type,
|
|
1601
|
+
cb
|
|
1602
|
+
};
|
|
1603
|
+
subscribers(type).push(sub);
|
|
1604
|
+
return sub;
|
|
1605
|
+
},
|
|
1606
|
+
forward(..._types) {
|
|
1607
|
+
return (type, cb) => {
|
|
1608
|
+
return this.subscribe(type, cb);
|
|
1609
|
+
};
|
|
1610
|
+
}
|
|
1611
|
+
};
|
|
1612
|
+
return result;
|
|
1613
|
+
});
|
|
1614
|
+
}
|
|
1615
|
+
});
|
|
1616
|
+
|
|
1617
1617
|
// src/cli/local/router.ts
|
|
1618
1618
|
import * as trpc from "@trpc/server";
|
|
1619
1619
|
var router2;
|
|
@@ -2580,9 +2580,17 @@ async function loadCDKStatus() {
|
|
|
2580
2580
|
StackName: "CDKToolkit"
|
|
2581
2581
|
})
|
|
2582
2582
|
);
|
|
2583
|
-
if (stacks
|
|
2584
|
-
return
|
|
2583
|
+
if (!stacks || stacks.length === 0)
|
|
2584
|
+
return false;
|
|
2585
|
+
if (!["CREATE_COMPLETE", "UPDATE_COMPLETE"].includes(stacks[0].StackStatus)) {
|
|
2586
|
+
return false;
|
|
2585
2587
|
}
|
|
2588
|
+
const output = stacks[0].Outputs?.find(
|
|
2589
|
+
(o) => o.OutputKey === "BootstrapVersion"
|
|
2590
|
+
);
|
|
2591
|
+
if (!output || parseInt(output.OutputValue) < 14)
|
|
2592
|
+
return false;
|
|
2593
|
+
return true;
|
|
2586
2594
|
} catch (e) {
|
|
2587
2595
|
if (e.name === "ValidationError" && e.message === "Stack with id CDKToolkit does not exist") {
|
|
2588
2596
|
return false;
|
|
@@ -6239,6 +6247,8 @@ var env = (program2) => program2.command(
|
|
|
6239
6247
|
const fs18 = await import("fs/promises");
|
|
6240
6248
|
const { SiteEnv } = await Promise.resolve().then(() => (init_site_env(), site_env_exports));
|
|
6241
6249
|
const { spawnSync } = await import("child_process");
|
|
6250
|
+
const { useAWSCredentials: useAWSCredentials2 } = await Promise.resolve().then(() => (init_credentials(), credentials_exports));
|
|
6251
|
+
const { useProject: useProject2 } = await Promise.resolve().then(() => (init_project(), project_exports));
|
|
6242
6252
|
let spinner;
|
|
6243
6253
|
while (true) {
|
|
6244
6254
|
const exists = await fs18.access(SiteEnv.valuesFile()).then(() => true).catch(() => false);
|
|
@@ -6252,10 +6262,16 @@ var env = (program2) => program2.command(
|
|
|
6252
6262
|
spinner?.succeed();
|
|
6253
6263
|
const sites = await SiteEnv.values();
|
|
6254
6264
|
const env2 = sites[process.cwd()] || {};
|
|
6265
|
+
const project = useProject2();
|
|
6266
|
+
const credentials = await useAWSCredentials2();
|
|
6255
6267
|
const result = spawnSync(args.command, {
|
|
6256
6268
|
env: {
|
|
6257
6269
|
...process.env,
|
|
6258
|
-
...env2
|
|
6270
|
+
...env2,
|
|
6271
|
+
AWS_ACCESS_KEY_ID: credentials.accessKeyId,
|
|
6272
|
+
AWS_SECRET_ACCESS_KEY: credentials.secretAccessKey,
|
|
6273
|
+
AWS_SESSION_TOKEN: credentials.sessionToken,
|
|
6274
|
+
AWS_REGION: project.config.region
|
|
6259
6275
|
},
|
|
6260
6276
|
stdio: "inherit",
|
|
6261
6277
|
shell: process.env.SHELL || true
|