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 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
- if (stacks &&
59
- stacks.length > 0 &&
60
- ["CREATE_COMPLETE", "UPDATE_COMPLETE"].includes(stacks[0].StackStatus)) {
61
- return true;
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" &&
@@ -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,
@@ -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: "nodejs16.x",
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: lambda.Runtime.NODEJS_18_X.name,
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,
@@ -59,7 +59,7 @@ export interface FunctionProps extends Omit<lambda.FunctionOptions, "functionNam
59
59
  * })
60
60
  *```
61
61
  */
62
- copyFiles?: FunctionBundleCopyFilesProps[];
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
- * Root directory of the project, typically where package.json is located. Set if using a monorepo with multiple subpackages
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
- * bundle: {
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
- * bundle: {
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
- * bundle: {
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
- * bundle: {
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 bundle format
404
+ * Configure format
407
405
  *
408
406
  * @default "cjs"
409
407
  *
410
408
  * @example
411
409
  * ```js
412
410
  * new Function(stack, "Function", {
413
- * bundle: {
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
- * bundle: {
429
- * sourcemap: true
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
- * bundle: {
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
- * bundle: {
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
- * bundle: {
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
- * bundle: {
521
- * copyFiles: [{ from: "src/index.js" }]
522
- * }
490
+ * copyFiles: [{ from: "src/index.js" }]
523
491
  * })
524
492
  *```
525
493
  */
526
- export interface FunctionBundleCopyFilesProps {
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;
@@ -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);
@@ -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,
@@ -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: lambda.Runtime.NODEJS_16_X,
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: "nodejs16.x",
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: lambda.Runtime.NODEJS_18_X,
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()
@@ -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
@@ -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
- const cfDistributionProps = cdk?.distribution || {};
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 (cfDistributionProps.domainNames) {
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;
@@ -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
- createCfDistribution() {
371
- const { cdk, customDomain } = this.props;
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 StaticSite domain certificate.`);
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 StaticSite domain.`);
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
- // Build domainNames
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
- // Build errorResponses
401
- const errorResponses = errorPage === "redirect_to_index_page" || errorPage === undefined
402
- ? buildErrorResponsesForRedirectToIndex(indexPage)
403
- : buildErrorResponsesFor404ErrorPage(errorPage);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sst",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "bin": {
5
5
  "sst": "cli/sst.js"
6
6
  },
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 && stacks.length > 0 && ["CREATE_COMPLETE", "UPDATE_COMPLETE"].includes(stacks[0].StackStatus)) {
2584
- return true;
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