sst 2.1.9 → 2.1.11

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/config.js CHANGED
@@ -117,21 +117,32 @@ export var Config;
117
117
  .flat()
118
118
  .filter((f) => f.type === "Function")
119
119
  .filter((f) => f.data.secrets.includes(key));
120
- await Promise.all(filtered.map(async (f) => {
121
- const config = await lambda.send(new GetFunctionConfigurationCommand({
122
- FunctionName: f.data.arn,
123
- }));
124
- await lambda.send(new UpdateFunctionConfigurationCommand({
125
- FunctionName: f.data.arn,
126
- Environment: {
127
- Variables: {
128
- ...(config.Environment?.Variables || {}),
129
- [SECRET_UPDATED_AT_ENV]: Date.now().toString(),
120
+ const restarted = await Promise.all(filtered.map(async (f) => {
121
+ // Note: in the case where the function is removed, but the metadata
122
+ // is not updated, we ignore the Function not found error.
123
+ try {
124
+ const config = await lambda.send(new GetFunctionConfigurationCommand({
125
+ FunctionName: f.data.arn,
126
+ }));
127
+ await lambda.send(new UpdateFunctionConfigurationCommand({
128
+ FunctionName: f.data.arn,
129
+ Environment: {
130
+ Variables: {
131
+ ...(config.Environment?.Variables || {}),
132
+ [SECRET_UPDATED_AT_ENV]: Date.now().toString(),
133
+ },
130
134
  },
131
- },
132
- }));
135
+ }));
136
+ return true;
137
+ }
138
+ catch (e) {
139
+ if (e.name === "ResourceNotFoundException" &&
140
+ e.message.startsWith("Function not found")) {
141
+ return;
142
+ }
143
+ }
133
144
  }));
134
- return filtered.length;
145
+ return restarted.filter(Boolean).length;
135
146
  }
136
147
  Config.restart = restart;
137
148
  })(Config || (Config = {}));
@@ -352,13 +352,11 @@ export interface NodeJSProps {
352
352
  *
353
353
  * @example
354
354
  * ```js
355
- * new Function(stack, "Function", {
356
- * nodejs: {
357
- * loader: {
358
- * ".png": "file"
359
- * }
355
+ * nodejs: {
356
+ * loader: {
357
+ * ".png": "file"
360
358
  * }
361
- * })
359
+ * }
362
360
  * ```
363
361
  */
364
362
  loader?: Record<string, Loader>;
@@ -367,11 +365,9 @@ export interface NodeJSProps {
367
365
  *
368
366
  * @example
369
367
  * ```js
370
- * new Function(stack, "Function", {
371
- * nodejs: {
372
- * install: ["pg"]
373
- * }
374
- * })
368
+ * nodejs: {
369
+ * install: ["pg"]
370
+ * }
375
371
  * ```
376
372
  */
377
373
  install?: string[];
@@ -380,11 +376,9 @@ export interface NodeJSProps {
380
376
  *
381
377
  * @example
382
378
  * ```js
383
- * new Function(stack, "Function", {
384
- * nodejs: {
385
- * banner: "console.log('Function starting')"
386
- * }
387
- * })
379
+ * nodejs: {
380
+ * banner: "console.log('Function starting')"
381
+ * }
388
382
  * ```
389
383
  */
390
384
  banner?: string;
@@ -399,11 +393,9 @@ export interface NodeJSProps {
399
393
  *
400
394
  * @example
401
395
  * ```js
402
- * new Function(stack, "Function", {
403
- * nodejs: {
404
- * minify: false
405
- * }
406
- * })
396
+ * nodejs: {
397
+ * minify: false
398
+ * }
407
399
  * ```
408
400
  */
409
401
  minify?: boolean;
@@ -414,11 +406,9 @@ export interface NodeJSProps {
414
406
  *
415
407
  * @example
416
408
  * ```js
417
- * new Function(stack, "Function", {
418
- * nodejs: {
419
- * format: "esm"
420
- * }
421
- * })
409
+ * nodejs: {
410
+ * format: "esm"
411
+ * }
422
412
  * ```
423
413
  */
424
414
  format?: "cjs" | "esm";
@@ -429,11 +419,9 @@ export interface NodeJSProps {
429
419
  *
430
420
  * @example
431
421
  * ```js
432
- * new Function(stack, "Function", {
433
- * nodejs: {
434
- * sourcemap: true
435
- * }
436
- * })
422
+ * nodejs: {
423
+ * sourcemap: true
424
+ * }
437
425
  * ```
438
426
  */
439
427
  sourcemap?: boolean;
@@ -1,11 +1,13 @@
1
1
  import { Construct } from "constructs";
2
2
  import { SSTConstruct } from "./Construct.js";
3
- import { Function } from "./Function.js";
3
+ import { Function, NodeJSProps } from "./Function.js";
4
4
  import { Duration } from "./util/duration.js";
5
5
  import { Permissions } from "./util/permission.js";
6
6
  import { FunctionBindingProps } from "./util/functionBinding.js";
7
7
  import { IVpc } from "aws-cdk-lib/aws-ec2";
8
8
  export type JobMemorySize = "3 GB" | "7 GB" | "15 GB" | "145 GB";
9
+ export interface JobNodeJSProps extends NodeJSProps {
10
+ }
9
11
  export interface JobProps {
10
12
  /**
11
13
  * Path to the entry point and handler function. Of the format:
@@ -47,6 +49,10 @@ export interface JobProps {
47
49
  *```
48
50
  */
49
51
  timeout?: Duration;
52
+ /**
53
+ * Used to configure nodejs function properties
54
+ */
55
+ nodejs?: JobNodeJSProps;
50
56
  /**
51
57
  * Can be used to disable Live Lambda Development when using `sst start`. Useful for things like Custom Resources that need to execute during deployment.
52
58
  *
@@ -249,8 +249,10 @@ export declare class SsrSite extends Construct implements SSTConstruct {
249
249
  protected buildDistributionDomainNames(): string[];
250
250
  private buildDistributionDefaultBehaviorForRegional;
251
251
  private buildDistributionDefaultBehaviorForEdge;
252
+ private buildBehaviorFunctionAssociations;
252
253
  protected buildDistributionStaticFileBehaviors(origin: S3Origin): Record<string, BehaviorOptions>;
253
254
  protected createCloudFrontServerCachePolicy(): CachePolicy;
255
+ protected createCloudFrontServerOriginRequestPolicy(): import("aws-cdk-lib/aws-cloudfront").IOriginRequestPolicy;
254
256
  private createCloudFrontInvalidation;
255
257
  protected validateCustomDomainSettings(): void;
256
258
  protected lookupHostedZone(): IHostedZone | undefined;
@@ -12,7 +12,7 @@ import { Effect, Policy, PolicyStatement } from "aws-cdk-lib/aws-iam";
12
12
  import { Function, Code, Runtime, FunctionUrlAuthType, } from "aws-cdk-lib/aws-lambda";
13
13
  import { HostedZone, ARecord, AaaaRecord, RecordTarget, } from "aws-cdk-lib/aws-route53";
14
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";
15
+ import { Distribution, ViewerProtocolPolicy, AllowedMethods, CachedMethods, LambdaEdgeEventType, CachePolicy, CacheQueryStringBehavior, CacheHeaderBehavior, CacheCookieBehavior, OriginRequestPolicy, Function as CfFunction, FunctionCode as CfFunctionCode, FunctionEventType as CfFunctionEventType, } from "aws-cdk-lib/aws-cloudfront";
16
16
  import { AwsCliLayer } from "aws-cdk-lib/lambda-layer-awscli";
17
17
  import { S3Origin, HttpOrigin } from "aws-cdk-lib/aws-cloudfront-origins";
18
18
  import { CloudFrontTarget } from "aws-cdk-lib/aws-route53-targets";
@@ -484,11 +484,13 @@ export class SsrSite extends Construct {
484
484
  });
485
485
  return {
486
486
  viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
487
+ functionAssociations: this.buildBehaviorFunctionAssociations(),
487
488
  origin: new HttpOrigin(Fn.parseDomainName(fnUrl.url)),
488
489
  allowedMethods: AllowedMethods.ALLOW_ALL,
489
490
  cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS,
490
491
  compress: true,
491
492
  cachePolicy: cdk?.serverCachePolicy ?? this.createCloudFrontServerCachePolicy(),
493
+ originRequestPolicy: this.createCloudFrontServerOriginRequestPolicy(),
492
494
  ...(cfDistributionProps.defaultBehavior || {}),
493
495
  };
494
496
  }
@@ -497,11 +499,13 @@ export class SsrSite extends Construct {
497
499
  const cfDistributionProps = cdk?.distribution || {};
498
500
  return {
499
501
  viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
502
+ functionAssociations: this.buildBehaviorFunctionAssociations(),
500
503
  origin,
501
504
  allowedMethods: AllowedMethods.ALLOW_ALL,
502
505
  cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS,
503
506
  compress: true,
504
507
  cachePolicy: cdk?.serverCachePolicy ?? this.createCloudFrontServerCachePolicy(),
508
+ originRequestPolicy: this.createCloudFrontServerOriginRequestPolicy(),
505
509
  ...(cfDistributionProps.defaultBehavior || {}),
506
510
  // concatenate edgeLambdas
507
511
  edgeLambdas: [
@@ -514,6 +518,21 @@ export class SsrSite extends Construct {
514
518
  ],
515
519
  };
516
520
  }
521
+ buildBehaviorFunctionAssociations() {
522
+ return [
523
+ {
524
+ eventType: CfFunctionEventType.VIEWER_REQUEST,
525
+ function: new CfFunction(this, "CloudFrontFunction", {
526
+ code: CfFunctionCode.fromInline(`
527
+ function handler(event) {
528
+ var request = event.request;
529
+ request.headers["x-forwarded-host"] = request.headers.host;
530
+ return request;
531
+ }`),
532
+ }),
533
+ },
534
+ ];
535
+ }
517
536
  buildDistributionStaticFileBehaviors(origin) {
518
537
  const { cdk } = this.props;
519
538
  // Create additional behaviours for statics
@@ -551,6 +570,10 @@ export class SsrSite extends Construct {
551
570
  comment: "SST server response cache policy",
552
571
  });
553
572
  }
573
+ createCloudFrontServerOriginRequestPolicy() {
574
+ // CloudFront's Managed-AllViewerExceptHostHeader policy
575
+ return OriginRequestPolicy.fromOriginRequestPolicyId(this, "ServerOriginRequestPolicy", "b689b0a8-53d0-40ab-baf2-68738e2966ac");
576
+ }
554
577
  createCloudFrontInvalidation() {
555
578
  const stack = Stack.of(this);
556
579
  const policy = new Policy(this, "CloudFrontInvalidatorPolicy", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sst",
3
- "version": "2.1.9",
3
+ "version": "2.1.11",
4
4
  "bin": {
5
5
  "sst": "cli/sst.js"
6
6
  },
@@ -186,13 +186,19 @@ export const useNodeHandler = Context.memo(async () => {
186
186
  }
187
187
  catch (ex) {
188
188
  const result = ex;
189
+ if ("errors" in result) {
190
+ return {
191
+ type: "error",
192
+ errors: result.errors.flatMap((x) => [
193
+ Colors.bold(x.text),
194
+ x.location?.file || "",
195
+ Colors.dim(x.location?.line, "│", x.location?.lineText),
196
+ ]),
197
+ };
198
+ }
189
199
  return {
190
200
  type: "error",
191
- errors: result.errors.flatMap((x) => [
192
- Colors.bold(x.text),
193
- x.location?.file || "",
194
- Colors.dim(x.location?.line, "│", x.location?.lineText),
195
- ]),
201
+ errors: [ex.toString()],
196
202
  };
197
203
  }
198
204
  },
@@ -133,7 +133,10 @@ export const usePythonHandler = Context.memo(async () => {
133
133
  */
134
134
  return {
135
135
  type: "success",
136
- handler: path.relative(src, path.resolve(input.props.handler)),
136
+ handler: path
137
+ .relative(src, path.resolve(input.props.handler))
138
+ .split(path.sep)
139
+ .join(path.posix.sep),
137
140
  };
138
141
  },
139
142
  });
package/sst.mjs CHANGED
@@ -5056,13 +5056,19 @@ var init_node = __esm({
5056
5056
  };
5057
5057
  } catch (ex) {
5058
5058
  const result = ex;
5059
+ if ("errors" in result) {
5060
+ return {
5061
+ type: "error",
5062
+ errors: result.errors.flatMap((x) => [
5063
+ Colors.bold(x.text),
5064
+ x.location?.file || "",
5065
+ Colors.dim(x.location?.line, "\u2502", x.location?.lineText)
5066
+ ])
5067
+ };
5068
+ }
5059
5069
  return {
5060
5070
  type: "error",
5061
- errors: result.errors.flatMap((x) => [
5062
- Colors.bold(x.text),
5063
- x.location?.file || "",
5064
- Colors.dim(x.location?.line, "\u2502", x.location?.lineText)
5065
- ])
5071
+ errors: [ex.toString()]
5066
5072
  };
5067
5073
  }
5068
5074
  }
@@ -5487,7 +5493,7 @@ var init_python = __esm({
5487
5493
  });
5488
5494
  return {
5489
5495
  type: "success",
5490
- handler: path14.relative(src, path14.resolve(input.props.handler))
5496
+ handler: path14.relative(src, path14.resolve(input.props.handler)).split(path14.sep).join(path14.posix.sep)
5491
5497
  };
5492
5498
  }
5493
5499
  });
@@ -6566,27 +6572,34 @@ var init_config = __esm({
6566
6572
  const lambda = useAWSClient(LambdaClient);
6567
6573
  const metadata3 = await stacks_exports.metadata();
6568
6574
  const filtered = Object.values(metadata3).flat().filter((f) => f.type === "Function").filter((f) => f.data.secrets.includes(key));
6569
- await Promise.all(
6575
+ const restarted = await Promise.all(
6570
6576
  filtered.map(async (f) => {
6571
- const config = await lambda.send(
6572
- new GetFunctionConfigurationCommand({
6573
- FunctionName: f.data.arn
6574
- })
6575
- );
6576
- await lambda.send(
6577
- new UpdateFunctionConfigurationCommand({
6578
- FunctionName: f.data.arn,
6579
- Environment: {
6580
- Variables: {
6581
- ...config.Environment?.Variables || {},
6582
- [SECRET_UPDATED_AT_ENV]: Date.now().toString()
6577
+ try {
6578
+ const config = await lambda.send(
6579
+ new GetFunctionConfigurationCommand({
6580
+ FunctionName: f.data.arn
6581
+ })
6582
+ );
6583
+ await lambda.send(
6584
+ new UpdateFunctionConfigurationCommand({
6585
+ FunctionName: f.data.arn,
6586
+ Environment: {
6587
+ Variables: {
6588
+ ...config.Environment?.Variables || {},
6589
+ [SECRET_UPDATED_AT_ENV]: Date.now().toString()
6590
+ }
6583
6591
  }
6584
- }
6585
- })
6586
- );
6592
+ })
6593
+ );
6594
+ return true;
6595
+ } catch (e) {
6596
+ if (e.name === "ResourceNotFoundException" && e.message.startsWith("Function not found")) {
6597
+ return;
6598
+ }
6599
+ }
6587
6600
  })
6588
6601
  );
6589
- return filtered.length;
6602
+ return restarted.filter(Boolean).length;
6590
6603
  }
6591
6604
  Config2.restart = restart;
6592
6605
  })(Config || (Config = {}));