sst 2.0.0-rc.55 → 2.0.0-rc.57

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.
@@ -17,7 +17,9 @@ export const usePothosBuilder = Context.memo(() => {
17
17
  });
18
18
  await fs.writeFile(route.output, schema);
19
19
  // bus.publish("pothos.extracted", { file: route.output });
20
- await Promise.all(route.commands.map((cmd) => execAsync(cmd)));
20
+ if (Array.isArray(route.commands) && route.commands.length > 0) {
21
+ await Promise.all(route.commands.map((cmd) => execAsync(cmd)));
22
+ }
21
23
  Colors.line(Colors.success(`✔`), " Pothos: Extracted pothos schema");
22
24
  }
23
25
  catch (ex) {
@@ -1,8 +1,7 @@
1
1
  export declare function weakImport(pkg: string): Promise<any>;
2
2
  import { Construct } from "constructs";
3
3
  import * as rds from "aws-cdk-lib/aws-rds";
4
- import * as cfnAppsync from "aws-cdk-lib/aws-appsync";
5
- import * as appsync from "@aws-cdk/aws-appsync-alpha";
4
+ import * as appsync from "aws-cdk-lib/aws-appsync";
6
5
  import * as dynamodb from "aws-cdk-lib/aws-dynamodb";
7
6
  import * as acm from "aws-cdk-lib/aws-certificatemanager";
8
7
  import * as secretsmanager from "aws-cdk-lib/aws-secretsmanager";
@@ -372,7 +371,7 @@ export declare class AppSyncApi extends Construct implements SSTConstruct {
372
371
  };
373
372
  private readonly props;
374
373
  private _customDomainUrl?;
375
- _cfnDomainName?: cfnAppsync.CfnDomainName;
374
+ _cfnDomainName?: appsync.CfnDomainName;
376
375
  private readonly functionsByDsKey;
377
376
  private readonly dataSourcesByDsKey;
378
377
  private readonly dsKeysByResKey;
@@ -11,7 +11,7 @@ export async function weakImport(pkg) {
11
11
  const { print, buildSchema } = await weakImport("graphql");
12
12
  const { mergeTypeDefs } = await weakImport("@graphql-tools/merge");
13
13
  import { Construct } from "constructs";
14
- import * as appsync from "@aws-cdk/aws-appsync-alpha";
14
+ import * as appsync from "aws-cdk-lib/aws-appsync";
15
15
  import * as appSyncApiDomain from "./util/appSyncApiDomain.js";
16
16
  import { getFunctionRef, isCDKConstruct } from "./Construct.js";
17
17
  import { Function as Fn, } from "./Function.js";
@@ -314,8 +314,8 @@ export class AppSyncApi extends Construct {
314
314
  if (domainData) {
315
315
  this._cfnDomainName = this.cdk.graphqlApi.node.children.find((child) => child.cfnResourceType ===
316
316
  "AWS::AppSync::DomainName");
317
- const cfnDomainNameApiAssociation = this.cdk.graphqlApi.node.children.find((child) => child
318
- .cfnResourceType === "AWS::AppSync::DomainNameApiAssociation");
317
+ const cfnDomainNameApiAssociation = this.cdk.graphqlApi.node.children.find((child) => child.cfnResourceType ===
318
+ "AWS::AppSync::DomainNameApiAssociation");
319
319
  if (this._cfnDomainName && cfnDomainNameApiAssociation) {
320
320
  cfnDomainNameApiAssociation.node.addDependency(this._cfnDomainName);
321
321
  }
@@ -45,6 +45,16 @@ export class Auth extends Construct {
45
45
  privatePath: getParameterPath(this, PRIVATE_KEY_PROP),
46
46
  },
47
47
  });
48
+ stack.customResourceHandler.role?.addToPrincipalPolicy(new PolicyStatement({
49
+ actions: [
50
+ "ssm:GetParameter",
51
+ "ssm:PutParameter",
52
+ "ssm:DeleteParameter",
53
+ ],
54
+ resources: [
55
+ `arn:${stack.partition}:ssm:${stack.region}:${stack.account}:parameter/*`,
56
+ ],
57
+ }));
48
58
  }
49
59
  /** @internal */
50
60
  getConstructMetadata() {
@@ -32,11 +32,11 @@ export declare class EdgeFunction extends Construct {
32
32
  private createAsset;
33
33
  private createRole;
34
34
  private createFunction;
35
- private createSingletonAwsCliLayer;
36
35
  private createLambdaCodeReplacer;
37
36
  private createSingletonBucketCR;
38
37
  private createFunctionCR;
39
38
  private createVersionCR;
39
+ private getLambdaContentReplaceValues;
40
40
  private updateVersionLogicalId;
41
41
  private trimFromStart;
42
42
  private calculateHash;
@@ -6,7 +6,6 @@ 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 { AwsCliLayer } from "aws-cdk-lib/lambda-layer-awscli";
10
9
  import { Lazy, Duration, CustomResource } from "aws-cdk-lib";
11
10
  import { Stack } from "./Stack.js";
12
11
  import { attachPermissionsToRole } from "./util/permission.js";
@@ -23,7 +22,7 @@ export class EdgeFunction extends Construct {
23
22
  constructor(scope, id, props) {
24
23
  super(scope, id);
25
24
  this.props = props;
26
- const { format, scopeOverride } = props;
25
+ const { scopeOverride } = props;
27
26
  // Correct scope
28
27
  this.scope = scopeOverride || this;
29
28
  // Wrap function code
@@ -63,7 +62,7 @@ const handler = async (event) => {
63
62
  // replacer to inject the environment variables assigned to the
64
63
  // EdgeFunction construct.
65
64
  //
66
- // "{{ _SST_EDGE_FUNCTION_ENVIRONMENT_ }}" will get replaced during
65
+ // "{{ _SST_FUNCTION_ENVIRONMENT_ }}" will get replaced during
67
66
  // deployment with an object of environment key-value pairs, ie.
68
67
  // const environment = {"API_URL": "https://api.example.com"};
69
68
  //
@@ -71,7 +70,7 @@ const handler = async (event) => {
71
70
  // support runtime environment variables. A downside of this approach
72
71
  // is that environment variables cannot be toggled after deployment,
73
72
  // each change to one requires a redeployment.
74
- const environment = "{{ _SST_EDGE_FUNCTION_ENVIRONMENT_ }}";
73
+ const environment = "{{ _SST_FUNCTION_ENVIRONMENT_ }}";
75
74
  process.env = { ...process.env, ...environment };
76
75
  } catch (e) {
77
76
  console.log("Failed to set SST Lambda@Edge environment.");
@@ -132,67 +131,29 @@ ${exports}
132
131
  const versionId = versionCR.getAttString("Version");
133
132
  this.updateVersionLogicalId(functionCR, versionCR);
134
133
  // Deploy after the code is updated
135
- const updaterCR = this.createLambdaCodeReplacer(name, asset);
134
+ const updaterCR = this.createLambdaCodeReplacer(asset);
136
135
  functionCR.node.addDependency(updaterCR);
137
136
  return { functionArn, versionId };
138
137
  }
139
- createSingletonAwsCliLayer() {
140
- // Do not recreate if exist
141
- const resId = "AwsCliLayer";
142
- const stack = Stack.of(this);
143
- const existingResource = stack.node.tryFindChild(resId);
144
- if (existingResource) {
145
- return existingResource;
146
- }
147
- // Create custom resource
148
- return new AwsCliLayer(stack, resId);
149
- }
150
- createLambdaCodeReplacer(name, asset) {
138
+ createLambdaCodeReplacer(asset) {
151
139
  // Note: Source code for the Lambda functions have "{{ ENV_KEY }}" in them.
152
140
  // They need to be replaced with real values before the Lambda
153
141
  // functions get deployed.
154
- const { format } = this.props;
155
- const providerId = "LambdaCodeReplacerProvider";
156
- const resId = `${name}LambdaCodeReplacer`;
157
142
  const stack = Stack.of(this);
158
- let provider = stack.node.tryFindChild(providerId);
159
- // Create provider if not already created
160
- if (!provider) {
161
- provider = new lambda.Function(stack, providerId, {
162
- code: lambda.Code.fromAsset(path.join(__dirname, "../support/edge-function-code-replacer")),
163
- layers: [this.createSingletonAwsCliLayer()],
164
- runtime: lambda.Runtime.PYTHON_3_7,
165
- handler: "lambda-code-updater.handler",
166
- timeout: Duration.minutes(15),
167
- memorySize: 1024,
168
- });
169
- }
170
- // Allow provider to perform search/replace on the asset
171
- provider.role?.addToPrincipalPolicy(new iam.PolicyStatement({
172
- effect: iam.Effect.ALLOW,
173
- actions: ["s3:*"],
174
- resources: [
175
- `arn:${stack.partition}:s3:::${asset.s3BucketName}/${asset.s3ObjectKey}`,
176
- ],
177
- }));
178
- // Create custom resource to replace the code
179
- const resource = new CustomResource(this.scope, resId, {
180
- serviceToken: provider.functionArn,
181
- resourceType: "Custom::SSTLambdaCodeUpdater",
143
+ const resource = new CustomResource(this.scope, "AssetReplacer", {
144
+ serviceToken: stack.customResourceHandler.functionArn,
145
+ resourceType: "Custom::AssetReplacer",
182
146
  properties: {
183
- Source: {
184
- BucketName: asset.s3BucketName,
185
- ObjectKey: asset.s3ObjectKey,
186
- },
187
- ReplaceValues: [
188
- {
189
- files: `index-wrapper.${format === "esm" ? "mjs" : "cjs"}`,
190
- search: '"{{ _SST_EDGE_FUNCTION_ENVIRONMENT_ }}"',
191
- replace: JSON.stringify(this.props.environment || {}),
192
- },
193
- ],
147
+ bucket: asset.s3BucketName,
148
+ key: asset.s3ObjectKey,
149
+ replacements: this.getLambdaContentReplaceValues(),
194
150
  },
195
151
  });
152
+ stack.customResourceHandler.role?.addToPrincipalPolicy(new iam.PolicyStatement({
153
+ effect: iam.Effect.ALLOW,
154
+ actions: ["s3:GetObject", "s3:PutObject"],
155
+ resources: [`arn:${stack.partition}:s3:::${asset.s3BucketName}/*`],
156
+ }));
196
157
  return resource;
197
158
  }
198
159
  createSingletonBucketCR() {
@@ -302,6 +263,32 @@ ${exports}
302
263
  /////////////////////
303
264
  // Internal Functions
304
265
  /////////////////////
266
+ getLambdaContentReplaceValues() {
267
+ const { format } = this.props;
268
+ const replaceValues = [];
269
+ Object.entries(this.props.environment || {}).forEach(([key, value]) => {
270
+ const token = `{{ ${key} }}`;
271
+ replaceValues.push({
272
+ files: "**/*.js",
273
+ search: token,
274
+ replace: value,
275
+ }, {
276
+ files: "**/*.cjs",
277
+ search: token,
278
+ replace: value,
279
+ }, {
280
+ files: "**/*.mjs",
281
+ search: token,
282
+ replace: value,
283
+ });
284
+ });
285
+ replaceValues.push({
286
+ files: `index-wrapper.${format === "esm" ? "mjs" : "cjs"}`,
287
+ search: '"{{ _SST_FUNCTION_ENVIRONMENT_ }}"',
288
+ replace: JSON.stringify(this.props.environment || {}),
289
+ });
290
+ return replaceValues;
291
+ }
305
292
  updateVersionLogicalId(functionCR, versionCR) {
306
293
  // Override the version's logical ID with a lazy string which includes the
307
294
  // hash of the function itself, so a new version resource is created when
@@ -1,13 +1,12 @@
1
1
  import fs from "fs";
2
2
  import url from "url";
3
3
  import path from "path";
4
- import spawn from "cross-spawn";
5
4
  import { Fn, Duration, RemovalPolicy } from "aws-cdk-lib";
6
5
  import * as logs from "aws-cdk-lib/aws-logs";
7
6
  import * as lambda from "aws-cdk-lib/aws-lambda";
8
7
  import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
9
8
  import * as origins from "aws-cdk-lib/aws-cloudfront-origins";
10
- import { useProject } from "../project.js";
9
+ import { SsrFunction } from "./SsrFunction.js";
11
10
  import { EdgeFunction } from "./EdgeFunction.js";
12
11
  import { SsrSite } from "./SsrSite.js";
13
12
  const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
@@ -38,36 +37,16 @@ export class NextjsSite extends SsrSite {
38
37
  }
39
38
  createFunctionForRegional() {
40
39
  const { defaults, environment } = this.props;
41
- // Note: cannot point the bundlePath to the `.open-next/server-function`
42
- // b/c the folder contains node_modules. And pnpm node_modules
43
- // contains symlinks. CDK cannot zip symlinks correctly.
44
- // https://github.com/aws/aws-cdk/issues/9251
45
- // We will zip the folder ourselves.
46
- const zipOutDir = path.resolve(path.join(useProject().paths.artifacts, `Site-${this.node.id}-${this.node.addr}`));
47
- const script = path.resolve(__dirname, "../support/ssr-site-function-archiver.mjs");
48
- const result = spawn.sync("node", [
49
- script,
50
- path.join(this.props.path, ".open-next", "server-function"),
51
- path.join(zipOutDir, "server-function.zip"),
52
- ], {
53
- stdio: "inherit",
54
- });
55
- if (result.status !== 0) {
56
- throw new Error(`There was a problem generating the assets package.`);
57
- }
58
- return new lambda.Function(this, `ServerFunction`, {
40
+ const ssrFn = new SsrFunction(this, `ServerFunction`, {
59
41
  description: "Server handler for Next.js",
42
+ bundlePath: path.join(this.props.path, ".open-next", "server-function"),
60
43
  handler: "index.handler",
61
- currentVersionOptions: {
62
- removalPolicy: RemovalPolicy.DESTROY,
63
- },
64
- logRetention: logs.RetentionDays.THREE_DAYS,
65
- code: lambda.Code.fromAsset(path.join(zipOutDir, "server-function.zip")),
66
- runtime: lambda.Runtime.NODEJS_18_X,
67
- memorySize: defaults?.function?.memorySize || 512,
68
- timeout: Duration.seconds(defaults?.function?.timeout || 10),
44
+ timeout: defaults?.function?.timeout,
45
+ memory: defaults?.function?.memorySize,
46
+ permissions: defaults?.function?.permissions,
69
47
  environment,
70
48
  });
49
+ return ssrFn.function;
71
50
  }
72
51
  createImageOptimizationFunctionForRegional() {
73
52
  const { defaults, path: sitePath } = this.props;
@@ -0,0 +1,21 @@
1
+ import { Construct } from "constructs";
2
+ import * as lambda from "aws-cdk-lib/aws-lambda";
3
+ import { Permissions } from "./util/permission.js";
4
+ export interface SsrFunctionProps {
5
+ description?: string;
6
+ bundlePath: string;
7
+ handler: string;
8
+ timeout?: number;
9
+ memory?: number;
10
+ permissions?: Permissions;
11
+ environment?: Record<string, string>;
12
+ }
13
+ export declare class SsrFunction extends Construct {
14
+ function: lambda.Function;
15
+ private props;
16
+ constructor(scope: Construct, id: string, props: SsrFunctionProps);
17
+ attachPermissions(permissions: Permissions): void;
18
+ private createFunction;
19
+ private createLambdaCodeReplacer;
20
+ private getLambdaContentReplaceValues;
21
+ }
@@ -0,0 +1,107 @@
1
+ import url from "url";
2
+ import path from "path";
3
+ import spawn from "cross-spawn";
4
+ import { Construct } from "constructs";
5
+ import * as iam from "aws-cdk-lib/aws-iam";
6
+ import * as logs from "aws-cdk-lib/aws-logs";
7
+ import * as lambda from "aws-cdk-lib/aws-lambda";
8
+ import * as s3Assets from "aws-cdk-lib/aws-s3-assets";
9
+ import { Duration, CustomResource } from "aws-cdk-lib";
10
+ import { Stack } from "./Stack.js";
11
+ import { useProject } from "../project.js";
12
+ import { attachPermissionsToRole } from "./util/permission.js";
13
+ const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
14
+ /////////////////////
15
+ // Construct
16
+ /////////////////////
17
+ export class SsrFunction extends Construct {
18
+ function;
19
+ props;
20
+ constructor(scope, id, props) {
21
+ super(scope, id);
22
+ this.props = props;
23
+ const { permissions } = props;
24
+ this.function = this.createFunction();
25
+ this.attachPermissions(permissions || []);
26
+ }
27
+ attachPermissions(permissions) {
28
+ attachPermissionsToRole(this.function.role, permissions);
29
+ }
30
+ createFunction() {
31
+ const { timeout, memory, handler, bundlePath, environment } = this.props;
32
+ // Note: cannot point the bundlePath to the `.open-next/server-function`
33
+ // b/c the folder contains node_modules. And pnpm node_modules
34
+ // contains symlinks. CDK cannot zip symlinks correctly.
35
+ // https://github.com/aws/aws-cdk/issues/9251
36
+ // We will zip the folder ourselves.
37
+ const zipOutDir = path.resolve(useProject().paths.artifacts, `Site-${this.node.id}-${this.node.addr}`);
38
+ const script = path.resolve(__dirname, "../support/ssr-site-function-archiver.mjs");
39
+ const result = spawn.sync("node", [
40
+ script,
41
+ path.join(bundlePath),
42
+ path.join(zipOutDir, "server-function.zip"),
43
+ ], { stdio: "inherit" });
44
+ if (result.status !== 0) {
45
+ throw new Error(`There was a problem generating the assets package.`);
46
+ }
47
+ // Create asset
48
+ const asset = new s3Assets.Asset(this, "Asset", {
49
+ path: path.join(zipOutDir, "server-function.zip"),
50
+ });
51
+ // Deploy after the code is updated
52
+ const replacer = this.createLambdaCodeReplacer(asset);
53
+ const fn = new lambda.Function(this, `ServerFunction`, {
54
+ description: this.props.description,
55
+ handler,
56
+ logRetention: logs.RetentionDays.THREE_DAYS,
57
+ code: lambda.Code.fromBucket(asset.bucket, asset.s3ObjectKey),
58
+ runtime: lambda.Runtime.NODEJS_18_X,
59
+ memorySize: memory || 512,
60
+ timeout: Duration.seconds(timeout || 10),
61
+ environment,
62
+ });
63
+ fn.node.addDependency(replacer);
64
+ return fn;
65
+ }
66
+ createLambdaCodeReplacer(asset) {
67
+ // Note: Source code for the Lambda functions have "{{ ENV_KEY }}" in them.
68
+ // They need to be replaced with real values before the Lambda
69
+ // functions get deployed.
70
+ const stack = Stack.of(this);
71
+ const resource = new CustomResource(this, "AssetReplacer", {
72
+ serviceToken: stack.customResourceHandler.functionArn,
73
+ resourceType: "Custom::AssetReplacer",
74
+ properties: {
75
+ bucket: asset.s3BucketName,
76
+ key: asset.s3ObjectKey,
77
+ replacements: this.getLambdaContentReplaceValues(),
78
+ },
79
+ });
80
+ stack.customResourceHandler.role?.addToPrincipalPolicy(new iam.PolicyStatement({
81
+ effect: iam.Effect.ALLOW,
82
+ actions: ["s3:GetObject", "s3:PutObject"],
83
+ resources: [`arn:${stack.partition}:s3:::${asset.s3BucketName}/*`],
84
+ }));
85
+ return resource;
86
+ }
87
+ getLambdaContentReplaceValues() {
88
+ const replaceValues = [];
89
+ Object.entries(this.props.environment || {}).forEach(([key, value]) => {
90
+ const token = `{{ ${key} }}`;
91
+ replaceValues.push({
92
+ files: "**/*.js",
93
+ search: token,
94
+ replace: value,
95
+ }, {
96
+ files: "**/*.cjs",
97
+ search: token,
98
+ replace: value,
99
+ }, {
100
+ files: "**/*.mjs",
101
+ search: token,
102
+ replace: value,
103
+ });
104
+ });
105
+ return replaceValues;
106
+ }
107
+ }
@@ -7,7 +7,7 @@ import * as acm from "aws-cdk-lib/aws-certificatemanager";
7
7
  import * as origins from "aws-cdk-lib/aws-cloudfront-origins";
8
8
  import { SSTConstruct } from "./Construct.js";
9
9
  import { EdgeFunction } from "./EdgeFunction.js";
10
- import { BaseSiteDomainProps, BaseSiteCdkDistributionProps } from "./BaseSite.js";
10
+ import { BaseSiteDomainProps, BaseSiteReplaceProps, BaseSiteCdkDistributionProps } from "./BaseSite.js";
11
11
  import { Permissions } from "./util/permission.js";
12
12
  import { FunctionBindingProps } from "./util/functionBinding.js";
13
13
  export type SsrBuildConfig = {
@@ -17,6 +17,8 @@ export type SsrBuildConfig = {
17
17
  };
18
18
  export interface SsrDomainProps extends BaseSiteDomainProps {
19
19
  }
20
+ export interface SsrSiteReplaceProps extends BaseSiteReplaceProps {
21
+ }
20
22
  export interface SsrCdkDistributionProps extends BaseSiteCdkDistributionProps {
21
23
  }
22
24
  export interface SsrSiteProps {
@@ -155,9 +157,6 @@ export declare class SsrSite extends Construct implements SSTConstruct {
155
157
  path: string;
156
158
  };
157
159
  private doNotDeploy;
158
- /**
159
- * The root SST directory used for builds.
160
- */
161
160
  protected buildConfig: SsrBuildConfig;
162
161
  private serverLambdaForEdge?;
163
162
  protected serverLambdaForRegional?: lambda.Function;
@@ -229,6 +228,7 @@ export declare class SsrSite extends Construct implements SSTConstruct {
229
228
  protected lookupHostedZone(): route53.IHostedZone | undefined;
230
229
  private createCertificate;
231
230
  protected createRoute53Records(): void;
231
+ private getS3ContentReplaceValues;
232
232
  private validateSiteExists;
233
233
  private registerSiteEnvironment;
234
234
  protected generateBuildId(): string;
@@ -6,7 +6,7 @@ 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, Duration, CfnOutput, RemovalPolicy, CustomResource, } from "aws-cdk-lib";
9
+ import { Fn, Token, Duration, CfnOutput, RemovalPolicy, CustomResource, } from "aws-cdk-lib";
10
10
  import * as s3 from "aws-cdk-lib/aws-s3";
11
11
  import * as iam from "aws-cdk-lib/aws-iam";
12
12
  import * as lambda from "aws-cdk-lib/aws-lambda";
@@ -43,9 +43,6 @@ export class SsrSite extends Construct {
43
43
  id;
44
44
  props;
45
45
  doNotDeploy;
46
- /**
47
- * The root SST directory used for builds.
48
- */
49
46
  buildConfig;
50
47
  serverLambdaForEdge;
51
48
  serverLambdaForRegional;
@@ -384,6 +381,7 @@ export class SsrSite extends Construct {
384
381
  cacheControl,
385
382
  ];
386
383
  }),
384
+ ReplaceValues: this.getS3ContentReplaceValues(),
387
385
  },
388
386
  });
389
387
  }
@@ -704,6 +702,24 @@ export class SsrSite extends Construct {
704
702
  /////////////////////
705
703
  // Helper Functions
706
704
  /////////////////////
705
+ getS3ContentReplaceValues() {
706
+ const replaceValues = [];
707
+ Object.entries(this.props.environment || {})
708
+ .filter(([, value]) => Token.isUnresolved(value))
709
+ .forEach(([key, value]) => {
710
+ const token = `{{ ${key} }}`;
711
+ replaceValues.push({
712
+ files: "**/*.html",
713
+ search: token,
714
+ replace: value,
715
+ }, {
716
+ files: "**/*.js",
717
+ search: token,
718
+ replace: value,
719
+ });
720
+ });
721
+ return replaceValues;
722
+ }
707
723
  validateSiteExists() {
708
724
  const { path: sitePath } = this.props;
709
725
  if (!fs.existsSync(sitePath)) {
@@ -174,7 +174,7 @@ export class Stack extends cdk.Stack {
174
174
  createCustomResourceHandler() {
175
175
  return new lambda.Function(this, "CustomResourceHandler", {
176
176
  code: lambda.Code.fromAsset(path.join(__dirname, "../support/custom-resources/"), {
177
- assetHash: this.stackName + "-custom-resources-v1",
177
+ assetHash: this.stackName + "-custom-resources-20230130",
178
178
  }),
179
179
  handler: "index.handler",
180
180
  runtime: lambda.Runtime.NODEJS_16_X,
@@ -179,19 +179,21 @@ export interface StaticSiteProps {
179
179
  * ```
180
180
  */
181
181
  purgeFiles?: boolean;
182
- /**
183
- * When running `sst start`, a placeholder site is deployed. This is to ensure that the site content remains unchanged, and subsequent `sst start` can start up quickly.
184
- *
185
- * @default false
186
- *
187
- * @example
188
- * ```js
189
- * new StaticSite(stack, "frontend", {
190
- * disablePlaceholder: true
191
- * });
192
- * ```
193
- */
194
- disablePlaceholder?: boolean;
182
+ dev?: {
183
+ /**
184
+ * When running `sst dev, site is not deployed. This is to ensure `sst dev` can start up quickly.
185
+ * @default false
186
+ * @example
187
+ * ```js
188
+ * new StaticSite(stack, "frontend", {
189
+ * dev: {
190
+ * deploy: true
191
+ * }
192
+ * });
193
+ * ```
194
+ */
195
+ deploy?: boolean;
196
+ };
195
197
  vite?: {
196
198
  /**
197
199
  * The path where code-gen should place the type definition for environment variables
@@ -209,11 +211,11 @@ export interface StaticSiteProps {
209
211
  };
210
212
  /**
211
213
  * 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.
212
- * @default true
214
+ * @default false
213
215
  * @example
214
216
  * ```js
215
217
  * new StaticSite(stack, "frontend", {
216
- * waitForInvalidation: false
218
+ * waitForInvalidation: true
217
219
  * });
218
220
  * ```
219
221
  */
@@ -280,55 +282,33 @@ export interface StaticSiteCdkDistributionProps extends BaseSiteCdkDistributionP
280
282
  */
281
283
  export declare class StaticSite extends Construct implements SSTConstruct {
282
284
  readonly id: string;
283
- readonly cdk: {
284
- /**
285
- * The internally created CDK `Bucket` instance.
286
- */
287
- bucket: s3.Bucket;
288
- /**
289
- * The internally created CDK `Distribution` instance.
290
- */
291
- distribution: cloudfront.Distribution;
292
- /**
293
- * The Route 53 hosted zone for the custom domain.
294
- */
295
- hostedZone?: route53.IHostedZone;
296
- certificate?: acm.ICertificate;
297
- };
298
285
  private props;
299
- private isPlaceholder;
300
- private assets;
301
- private filenamesAsset?;
302
- private awsCliLayer;
286
+ private doNotDeploy;
287
+ private bucket;
288
+ private distribution;
289
+ private hostedZone?;
290
+ private certificate?;
303
291
  constructor(scope: Construct, id: string, props?: StaticSiteProps);
304
292
  /**
305
293
  * The CloudFront URL of the website.
306
294
  */
307
- get url(): string;
295
+ get url(): string | undefined;
308
296
  /**
309
297
  * If the custom domain is enabled, this is the URL of the website with the custom domain.
310
298
  */
311
299
  get customDomainUrl(): string | undefined;
312
300
  /**
313
- * The ARN of the internally created S3 Bucket.
301
+ * The internally created CDK resources.
314
302
  */
315
- get bucketArn(): string;
316
- /**
317
- * The name of the internally created S3 Bucket.
318
- */
319
- get bucketName(): string;
320
- /**
321
- * The ID of the internally created CloudFront Distribution.
322
- */
323
- get distributionId(): string;
324
- /**
325
- * The domain name of the internally created CloudFront Distribution.
326
- */
327
- get distributionDomain(): string;
303
+ get cdk(): {
304
+ bucket: s3.Bucket;
305
+ distribution: cloudfront.Distribution;
306
+ hostedZone: route53.IHostedZone | undefined;
307
+ certificate: acm.ICertificate | undefined;
308
+ };
328
309
  getConstructMetadata(): {
329
310
  type: "StaticSite";
330
311
  data: {
331
- distributionId: string;
332
312
  customDomainUrl: string | undefined;
333
313
  };
334
314
  };