sst 2.3.6 → 2.4.0

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.
@@ -2,6 +2,7 @@ import fs from "fs";
2
2
  import url from "url";
3
3
  import path from "path";
4
4
  import crypto from "crypto";
5
+ import spawn from "cross-spawn";
5
6
  import { Construct } from "constructs";
6
7
  import { Effect, Role, Policy, PolicyStatement, CompositePrincipal, ServicePrincipal, ManagedPolicy, } from "aws-cdk-lib/aws-iam";
7
8
  import { Version, Code, Runtime, Function as CdkFunction, } from "aws-cdk-lib/aws-lambda";
@@ -135,9 +136,20 @@ export class EdgeFunction extends Construct {
135
136
  const filePath = path.join(bundle, handlerFilename);
136
137
  const fileData = fs.readFileSync(filePath, "utf8");
137
138
  fs.writeFileSync(filePath, `process.env = { ...process.env, ..."{{ _SST_FUNCTION_ENVIRONMENT_ }}" };\n${fileData}`);
139
+ // Note: cannot point the bundle to the `.open-next/server-function`
140
+ // b/c the folder contains node_modules. And pnpm node_modules
141
+ // contains symlinks. CDK cannot zip symlinks correctly.
142
+ // https://github.com/aws/aws-cdk/issues/9251
143
+ // We will zip the folder ourselves.
144
+ const outputPath = path.resolve(useProject().paths.artifacts, `SsrFunction-${this.node.id}-${this.node.addr}`);
145
+ const script = path.resolve(__dirname, "../support/ssr-site-function-archiver.mjs");
146
+ const result = spawn.sync("node", [script, path.join(bundle), path.join(outputPath, "server-function.zip")], { stdio: "inherit" });
147
+ if (result.status !== 0) {
148
+ throw new Error(`There was a problem generating the assets package.`);
149
+ }
138
150
  // Create asset
139
151
  const asset = new Asset(this.scope, `FunctionAsset`, {
140
- path: bundle,
152
+ path: path.join(outputPath, "server-function.zip"),
141
153
  });
142
154
  return { handlerFilename, asset };
143
155
  }
@@ -1,9 +1,10 @@
1
1
  import { Construct } from "constructs";
2
2
  import { Function as CdkFunction } from "aws-cdk-lib/aws-lambda";
3
- import { Distribution, CachePolicy } from "aws-cdk-lib/aws-cloudfront";
3
+ import { Distribution } from "aws-cdk-lib/aws-cloudfront";
4
+ import { EdgeFunction } from "./EdgeFunction.js";
4
5
  import { SsrSite, SsrSiteProps } from "./SsrSite.js";
5
6
  import { Size } from "./util/size.js";
6
- export interface NextjsSiteProps extends Omit<SsrSiteProps, "edge" | "nodejs"> {
7
+ export interface NextjsSiteProps extends Omit<SsrSiteProps, "nodejs"> {
7
8
  imageOptimization?: {
8
9
  /**
9
10
  * The amount of memory in MB allocated for image optimization function.
@@ -43,9 +44,15 @@ export declare class NextjsSite extends SsrSite {
43
44
  clientBuildVersionedSubDir: string;
44
45
  };
45
46
  protected createFunctionForRegional(): CdkFunction;
46
- private createImageOptimizationFunctionForRegional;
47
- private createMiddlewareEdgeFunctionForRegional;
47
+ protected createFunctionForEdge(): EdgeFunction;
48
+ private createImageOptimizationFunction;
48
49
  protected createCloudFrontDistributionForRegional(): Distribution;
49
- protected createCloudFrontServerCachePolicy(): CachePolicy;
50
+ protected createCloudFrontDistributionForEdge(): Distribution;
51
+ private buildServerBehaviorForRegional;
52
+ private buildServerBehaviorForEdge;
53
+ private buildImageBehavior;
54
+ private buildStaticFileBehavior;
55
+ private buildDefaultNextjsBehaviorForRegional;
56
+ private buildDefaultNextjsBehaviorForEdge;
50
57
  protected generateBuildId(): string;
51
58
  }
@@ -4,7 +4,7 @@ import path from "path";
4
4
  import { Fn, Duration as CdkDuration, RemovalPolicy } from "aws-cdk-lib";
5
5
  import { RetentionDays } from "aws-cdk-lib/aws-logs";
6
6
  import { Function as CdkFunction, Code, Runtime, Architecture, FunctionUrlAuthType, } from "aws-cdk-lib/aws-lambda";
7
- import { Distribution, ViewerProtocolPolicy, AllowedMethods, LambdaEdgeEventType, CachedMethods, CachePolicy, CacheQueryStringBehavior, CacheCookieBehavior, CacheHeaderBehavior, } from "aws-cdk-lib/aws-cloudfront";
7
+ import { Distribution, ViewerProtocolPolicy, AllowedMethods, LambdaEdgeEventType, CachedMethods, CachePolicy, } from "aws-cdk-lib/aws-cloudfront";
8
8
  import { S3Origin, HttpOrigin, OriginGroup, } from "aws-cdk-lib/aws-cloudfront-origins";
9
9
  import { SsrFunction } from "./SsrFunction.js";
10
10
  import { EdgeFunction } from "./EdgeFunction.js";
@@ -54,7 +54,20 @@ export class NextjsSite extends SsrSite {
54
54
  });
55
55
  return ssrFn.function;
56
56
  }
57
- createImageOptimizationFunctionForRegional() {
57
+ createFunctionForEdge() {
58
+ const { runtime, timeout, memorySize, bind, permissions, environment } = this.props;
59
+ return new EdgeFunction(this, "ServerFunction", {
60
+ bundle: path.join(this.props.path, ".open-next", "server-function"),
61
+ handler: "index.handler",
62
+ runtime,
63
+ timeout,
64
+ memorySize,
65
+ bind,
66
+ permissions,
67
+ environment,
68
+ });
69
+ }
70
+ createImageOptimizationFunction() {
58
71
  const { imageOptimization, path: sitePath } = this.props;
59
72
  return new CdkFunction(this, `ImageFunction`, {
60
73
  description: "Image optimization handler for Next.js",
@@ -83,86 +96,7 @@ export class NextjsSite extends SsrSite {
83
96
  ],
84
97
  });
85
98
  }
86
- createMiddlewareEdgeFunctionForRegional() {
87
- const { permissions, environment, path: sitePath } = this.props;
88
- const middlewarePath = path.resolve(sitePath, ".open-next/middleware-function");
89
- if (fs.existsSync(middlewarePath)) {
90
- return new EdgeFunction(this, "Middleware", {
91
- bundle: middlewarePath,
92
- handler: "index.handler",
93
- runtime: "nodejs18.x",
94
- timeout: 5,
95
- memorySize: 128,
96
- permissions,
97
- environment,
98
- nodejs: {
99
- format: "esm",
100
- },
101
- });
102
- }
103
- }
104
99
  createCloudFrontDistributionForRegional() {
105
- const { cdk } = this.props;
106
- const cfDistributionProps = cdk?.distribution || {};
107
- const s3Origin = new S3Origin(this.cdk.bucket);
108
- // Create server behavior
109
- const middlewareFn = this.createMiddlewareEdgeFunctionForRegional();
110
- const serverFnUrl = this.serverLambdaForRegional.addFunctionUrl({
111
- authType: FunctionUrlAuthType.NONE,
112
- });
113
- const serverBehavior = {
114
- viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
115
- origin: new HttpOrigin(Fn.parseDomainName(serverFnUrl.url)),
116
- allowedMethods: AllowedMethods.ALLOW_ALL,
117
- cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS,
118
- compress: true,
119
- cachePolicy: cdk?.serverCachePolicy ?? this.createCloudFrontServerCachePolicy(),
120
- edgeLambdas: middlewareFn && [
121
- {
122
- eventType: LambdaEdgeEventType.VIEWER_REQUEST,
123
- functionVersion: middlewareFn.currentVersion,
124
- },
125
- ],
126
- };
127
- // Create image optimization behavior
128
- const imageFn = this.createImageOptimizationFunctionForRegional();
129
- const imageFnUrl = imageFn.addFunctionUrl({
130
- authType: FunctionUrlAuthType.NONE,
131
- });
132
- const imageBehavior = {
133
- viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
134
- origin: new HttpOrigin(Fn.parseDomainName(imageFnUrl.url)),
135
- allowedMethods: AllowedMethods.ALLOW_ALL,
136
- cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS,
137
- compress: true,
138
- cachePolicy: serverBehavior.cachePolicy,
139
- };
140
- // Create statics behavior
141
- const staticFileBehaviour = {
142
- origin: s3Origin,
143
- viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
144
- allowedMethods: AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
145
- cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS,
146
- compress: true,
147
- cachePolicy: CachePolicy.CACHING_OPTIMIZED,
148
- };
149
- // Create default behavior
150
- // default handler for requests that don't match any other path:
151
- // - try lambda handler first
152
- // - if failed, fall back to S3
153
- const fallbackOriginGroup = new OriginGroup({
154
- primaryOrigin: serverBehavior.origin,
155
- fallbackOrigin: s3Origin,
156
- fallbackStatusCodes: [404],
157
- });
158
- const defaultBehavior = {
159
- origin: fallbackOriginGroup,
160
- viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
161
- compress: true,
162
- cachePolicy: serverBehavior.cachePolicy,
163
- edgeLambdas: serverBehavior.edgeLambdas,
164
- ...(cfDistributionProps.defaultBehavior || {}),
165
- };
166
100
  /**
167
101
  * Next.js requests
168
102
  *
@@ -212,6 +146,42 @@ export class NextjsSite extends SsrSite {
212
146
  * - Cache-Control: public, max-age=0, must-revalidate
213
147
  * - x-vercel-cache: MISS
214
148
  */
149
+ const { cdk } = this.props;
150
+ const cfDistributionProps = cdk?.distribution || {};
151
+ const s3Origin = new S3Origin(this.cdk.bucket);
152
+ const serverFnUrl = this.serverLambdaForRegional.addFunctionUrl({
153
+ authType: FunctionUrlAuthType.NONE,
154
+ });
155
+ const serverOrigin = new HttpOrigin(Fn.parseDomainName(serverFnUrl.url));
156
+ const cachePolicy = cdk?.serverCachePolicy ?? this.buildServerCachePolicy();
157
+ const originRequestPolicy = this.buildServerOriginRequestPolicy();
158
+ const serverBehavior = this.buildServerBehaviorForRegional(serverOrigin, cachePolicy, originRequestPolicy);
159
+ return new Distribution(this, "Distribution", {
160
+ // these values can be overwritten by cfDistributionProps
161
+ defaultRootObject: "",
162
+ // Override props.
163
+ ...cfDistributionProps,
164
+ // these values can NOT be overwritten by cfDistributionProps
165
+ domainNames: this.buildDistributionDomainNames(),
166
+ certificate: this.cdk.certificate,
167
+ defaultBehavior: this.buildDefaultNextjsBehaviorForRegional(serverOrigin, s3Origin, cachePolicy, originRequestPolicy),
168
+ additionalBehaviors: {
169
+ "api/*": serverBehavior,
170
+ "_next/data/*": serverBehavior,
171
+ "_next/image*": this.buildImageBehavior(cachePolicy),
172
+ "_next/*": this.buildStaticFileBehavior(s3Origin),
173
+ ...(cfDistributionProps.additionalBehaviors || {}),
174
+ },
175
+ });
176
+ }
177
+ createCloudFrontDistributionForEdge() {
178
+ const { cdk } = this.props;
179
+ const cfDistributionProps = cdk?.distribution || {};
180
+ const s3Origin = new S3Origin(this.cdk.bucket);
181
+ const cachePolicy = cdk?.serverCachePolicy ?? this.buildServerCachePolicy();
182
+ const originRequestPolicy = this.buildServerOriginRequestPolicy();
183
+ const functionVersion = this.serverLambdaForEdge.currentVersion;
184
+ const serverBehavior = this.buildServerBehaviorForEdge(functionVersion, s3Origin, cachePolicy, originRequestPolicy);
215
185
  return new Distribution(this, "Distribution", {
216
186
  // these values can be overwritten by cfDistributionProps
217
187
  defaultRootObject: "",
@@ -220,34 +190,111 @@ export class NextjsSite extends SsrSite {
220
190
  // these values can NOT be overwritten by cfDistributionProps
221
191
  domainNames: this.buildDistributionDomainNames(),
222
192
  certificate: this.cdk.certificate,
223
- defaultBehavior: defaultBehavior,
193
+ defaultBehavior: this.buildDefaultNextjsBehaviorForEdge(functionVersion, s3Origin, cachePolicy, originRequestPolicy),
224
194
  additionalBehaviors: {
225
195
  "api/*": serverBehavior,
226
196
  "_next/data/*": serverBehavior,
227
- "_next/image*": imageBehavior,
228
- "_next/*": staticFileBehaviour,
197
+ "_next/image*": this.buildImageBehavior(cachePolicy),
198
+ "_next/*": this.buildStaticFileBehavior(s3Origin),
229
199
  ...(cfDistributionProps.additionalBehaviors || {}),
230
200
  },
231
201
  });
232
202
  }
233
- createCloudFrontServerCachePolicy() {
234
- return new CachePolicy(this, "ServerCache", {
235
- queryStringBehavior: CacheQueryStringBehavior.all(),
236
- headerBehavior: CacheHeaderBehavior.allowList(
237
- // required by image optimization request
238
- "accept",
239
- // required by server request
240
- "x-op-middleware-request-headers", "x-op-middleware-response-headers", "x-nextjs-data", "x-middleware-prefetch",
241
- // required by server request (in-place routing)
242
- "rsc", "next-router-prefetch", "next-router-state-tree"),
243
- cookieBehavior: CacheCookieBehavior.all(),
244
- defaultTtl: CdkDuration.days(0),
245
- maxTtl: CdkDuration.days(365),
246
- minTtl: CdkDuration.days(0),
247
- enableAcceptEncodingBrotli: true,
248
- enableAcceptEncodingGzip: true,
249
- comment: "SST server response cache policy",
203
+ buildServerBehaviorForRegional(serverOrigin, cachePolicy, originRequestPolicy) {
204
+ return {
205
+ viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
206
+ origin: serverOrigin,
207
+ allowedMethods: AllowedMethods.ALLOW_ALL,
208
+ cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS,
209
+ compress: true,
210
+ cachePolicy,
211
+ originRequestPolicy,
212
+ };
213
+ }
214
+ buildServerBehaviorForEdge(functionVersion, s3Origin, cachePolicy, originRequestPolicy) {
215
+ return {
216
+ viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
217
+ origin: s3Origin,
218
+ allowedMethods: AllowedMethods.ALLOW_ALL,
219
+ cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS,
220
+ compress: true,
221
+ cachePolicy,
222
+ originRequestPolicy,
223
+ edgeLambdas: [
224
+ {
225
+ includeBody: true,
226
+ eventType: LambdaEdgeEventType.ORIGIN_REQUEST,
227
+ functionVersion,
228
+ },
229
+ ],
230
+ };
231
+ }
232
+ buildImageBehavior(cachePolicy) {
233
+ const imageFn = this.createImageOptimizationFunction();
234
+ const imageFnUrl = imageFn.addFunctionUrl({
235
+ authType: FunctionUrlAuthType.NONE,
250
236
  });
237
+ return {
238
+ viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
239
+ origin: new HttpOrigin(Fn.parseDomainName(imageFnUrl.url)),
240
+ allowedMethods: AllowedMethods.ALLOW_ALL,
241
+ cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS,
242
+ compress: true,
243
+ cachePolicy,
244
+ };
245
+ }
246
+ buildStaticFileBehavior(s3Origin) {
247
+ return {
248
+ origin: s3Origin,
249
+ viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
250
+ allowedMethods: AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
251
+ cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS,
252
+ compress: true,
253
+ cachePolicy: CachePolicy.CACHING_OPTIMIZED,
254
+ };
255
+ }
256
+ buildDefaultNextjsBehaviorForRegional(serverOrigin, s3Origin, cachePolicy, originRequestPolicy) {
257
+ // Create default behavior
258
+ // default handler for requests that don't match any other path:
259
+ // - try lambda handler first
260
+ // - if failed, fall back to S3
261
+ const { cdk } = this.props;
262
+ const cfDistributionProps = cdk?.distribution || {};
263
+ const fallbackOriginGroup = new OriginGroup({
264
+ primaryOrigin: serverOrigin,
265
+ fallbackOrigin: s3Origin,
266
+ fallbackStatusCodes: [404],
267
+ });
268
+ return {
269
+ origin: fallbackOriginGroup,
270
+ viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
271
+ compress: true,
272
+ cachePolicy,
273
+ originRequestPolicy,
274
+ ...(cfDistributionProps.defaultBehavior || {}),
275
+ };
276
+ }
277
+ buildDefaultNextjsBehaviorForEdge(functionVersion, s3Origin, cachePolicy, originRequestPolicy) {
278
+ const { cdk } = this.props;
279
+ const cfDistributionProps = cdk?.distribution || {};
280
+ return {
281
+ viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
282
+ origin: s3Origin,
283
+ allowedMethods: AllowedMethods.ALLOW_ALL,
284
+ cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS,
285
+ compress: true,
286
+ cachePolicy,
287
+ originRequestPolicy,
288
+ ...(cfDistributionProps.defaultBehavior || {}),
289
+ edgeLambdas: [
290
+ {
291
+ includeBody: true,
292
+ eventType: LambdaEdgeEventType.ORIGIN_REQUEST,
293
+ functionVersion,
294
+ },
295
+ ...(cfDistributionProps.defaultBehavior?.edgeLambdas || []),
296
+ ],
297
+ };
251
298
  }
252
299
  generateBuildId() {
253
300
  const filePath = path.join(this.props.path, ".next/BUILD_ID");
@@ -4,7 +4,6 @@ import { Function as CdkFunction, FunctionProps } from "aws-cdk-lib/aws-lambda";
4
4
  import { IHostedZone } from "aws-cdk-lib/aws-route53";
5
5
  import { Distribution, ICachePolicy, BehaviorOptions, CachePolicy } from "aws-cdk-lib/aws-cloudfront";
6
6
  import { ICertificate } from "aws-cdk-lib/aws-certificatemanager";
7
- import { S3Origin } from "aws-cdk-lib/aws-cloudfront-origins";
8
7
  import { SSTConstruct } from "./Construct.js";
9
8
  import { NodeJSProps, Function } from "./Function.js";
10
9
  import { EdgeFunction } from "./EdgeFunction.js";
@@ -198,7 +197,7 @@ export declare class SsrSite extends Construct implements SSTConstruct {
198
197
  protected props: SsrSiteNormalizedProps;
199
198
  private doNotDeploy;
200
199
  protected buildConfig: SsrBuildConfig;
201
- private serverLambdaForEdge?;
200
+ protected serverLambdaForEdge?: EdgeFunction;
202
201
  protected serverLambdaForRegional?: CdkFunction;
203
202
  private serverLambdaForDev?;
204
203
  private bucket;
@@ -264,14 +263,14 @@ export declare class SsrSite extends Construct implements SSTConstruct {
264
263
  private createFunctionPermissionsForEdge;
265
264
  private validateCloudFrontDistributionSettings;
266
265
  protected createCloudFrontDistributionForRegional(): Distribution;
267
- private createCloudFrontDistributionForEdge;
266
+ protected createCloudFrontDistributionForEdge(): Distribution;
268
267
  protected buildDistributionDomainNames(): string[];
269
- private buildDistributionDefaultBehaviorForRegional;
270
- private buildDistributionDefaultBehaviorForEdge;
268
+ protected buildDefaultBehaviorForRegional(): BehaviorOptions;
269
+ private buildDefaultBehaviorForEdge;
271
270
  private buildBehaviorFunctionAssociations;
272
- protected buildDistributionStaticFileBehaviors(origin: S3Origin): Record<string, BehaviorOptions>;
273
- protected createCloudFrontServerCachePolicy(): CachePolicy;
274
- protected createCloudFrontServerOriginRequestPolicy(): import("aws-cdk-lib/aws-cloudfront").IOriginRequestPolicy;
271
+ private buildStaticFileBehaviors;
272
+ protected buildServerCachePolicy(): CachePolicy;
273
+ protected buildServerOriginRequestPolicy(): import("aws-cdk-lib/aws-cloudfront").IOriginRequestPolicy;
275
274
  private createCloudFrontInvalidation;
276
275
  protected validateCustomDomainSettings(): void;
277
276
  protected lookupHostedZone(): IHostedZone | undefined;
@@ -466,9 +466,9 @@ export class SsrSite extends Construct {
466
466
  // these values can NOT be overwritten by cfDistributionProps
467
467
  domainNames: this.buildDistributionDomainNames(),
468
468
  certificate: this.certificate,
469
- defaultBehavior: this.buildDistributionDefaultBehaviorForRegional(),
469
+ defaultBehavior: this.buildDefaultBehaviorForRegional(),
470
470
  additionalBehaviors: {
471
- ...this.buildDistributionStaticFileBehaviors(s3Origin),
471
+ ...this.buildStaticFileBehaviors(s3Origin),
472
472
  ...(cfDistributionProps.additionalBehaviors || {}),
473
473
  },
474
474
  });
@@ -485,9 +485,9 @@ export class SsrSite extends Construct {
485
485
  // these values can NOT be overwritten by cfDistributionProps
486
486
  domainNames: this.buildDistributionDomainNames(),
487
487
  certificate: this.certificate,
488
- defaultBehavior: this.buildDistributionDefaultBehaviorForEdge(s3Origin),
488
+ defaultBehavior: this.buildDefaultBehaviorForEdge(s3Origin),
489
489
  additionalBehaviors: {
490
- ...this.buildDistributionStaticFileBehaviors(s3Origin),
490
+ ...this.buildStaticFileBehaviors(s3Origin),
491
491
  ...(cfDistributionProps.additionalBehaviors || {}),
492
492
  },
493
493
  });
@@ -511,7 +511,7 @@ export class SsrSite extends Construct {
511
511
  }
512
512
  return domainNames;
513
513
  }
514
- buildDistributionDefaultBehaviorForRegional() {
514
+ buildDefaultBehaviorForRegional() {
515
515
  const { cdk } = this.props;
516
516
  const cfDistributionProps = cdk?.distribution || {};
517
517
  const fnUrl = this.serverLambdaForRegional.addFunctionUrl({
@@ -524,12 +524,12 @@ export class SsrSite extends Construct {
524
524
  allowedMethods: AllowedMethods.ALLOW_ALL,
525
525
  cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS,
526
526
  compress: true,
527
- cachePolicy: cdk?.serverCachePolicy ?? this.createCloudFrontServerCachePolicy(),
528
- originRequestPolicy: this.createCloudFrontServerOriginRequestPolicy(),
527
+ cachePolicy: cdk?.serverCachePolicy ?? this.buildServerCachePolicy(),
528
+ originRequestPolicy: this.buildServerOriginRequestPolicy(),
529
529
  ...(cfDistributionProps.defaultBehavior || {}),
530
530
  };
531
531
  }
532
- buildDistributionDefaultBehaviorForEdge(origin) {
532
+ buildDefaultBehaviorForEdge(origin) {
533
533
  const { cdk } = this.props;
534
534
  const cfDistributionProps = cdk?.distribution || {};
535
535
  return {
@@ -539,10 +539,9 @@ export class SsrSite extends Construct {
539
539
  allowedMethods: AllowedMethods.ALLOW_ALL,
540
540
  cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS,
541
541
  compress: true,
542
- cachePolicy: cdk?.serverCachePolicy ?? this.createCloudFrontServerCachePolicy(),
543
- originRequestPolicy: this.createCloudFrontServerOriginRequestPolicy(),
542
+ cachePolicy: cdk?.serverCachePolicy ?? this.buildServerCachePolicy(),
543
+ originRequestPolicy: this.buildServerOriginRequestPolicy(),
544
544
  ...(cfDistributionProps.defaultBehavior || {}),
545
- // concatenate edgeLambdas
546
545
  edgeLambdas: [
547
546
  {
548
547
  includeBody: true,
@@ -568,7 +567,7 @@ function handler(event) {
568
567
  },
569
568
  ];
570
569
  }
571
- buildDistributionStaticFileBehaviors(origin) {
570
+ buildStaticFileBehaviors(origin) {
572
571
  const { cdk } = this.props;
573
572
  // Create additional behaviours for statics
574
573
  const staticBehaviourOptions = {
@@ -592,7 +591,7 @@ function handler(event) {
592
591
  }
593
592
  return staticsBehaviours;
594
593
  }
595
- createCloudFrontServerCachePolicy() {
594
+ buildServerCachePolicy() {
596
595
  return new CachePolicy(this, "ServerCache", {
597
596
  queryStringBehavior: CacheQueryStringBehavior.all(),
598
597
  headerBehavior: CacheHeaderBehavior.none(),
@@ -605,7 +604,7 @@ function handler(event) {
605
604
  comment: "SST server response cache policy",
606
605
  });
607
606
  }
608
- createCloudFrontServerOriginRequestPolicy() {
607
+ buildServerOriginRequestPolicy() {
609
608
  // CloudFront's Managed-AllViewerExceptHostHeader policy
610
609
  return OriginRequestPolicy.fromOriginRequestPolicyId(this, "ServerOriginRequestPolicy", "b689b0a8-53d0-40ab-baf2-68738e2966ac");
611
610
  }
@@ -0,0 +1,16 @@
1
+ import { OauthBasicConfig } from "./oauth.js";
2
+ export declare const FacebookAdapter: (config: OauthBasicConfig) => () => Promise<{
3
+ type: "success";
4
+ properties: {
5
+ tokenset: import("openid-client").TokenSet;
6
+ client: import("openid-client").BaseClient;
7
+ };
8
+ } | {
9
+ type: "step";
10
+ properties: {
11
+ statusCode: number;
12
+ headers: {
13
+ location: string;
14
+ };
15
+ };
16
+ }>;
@@ -0,0 +1,27 @@
1
+ import { Issuer } from "openid-client";
2
+ import { OauthAdapter } from "./oauth.js";
3
+ // Facebook's OIDC flow returns "id_token" as uri hash in redirect uri. Hashes
4
+ // are not passed to Lambda event object. It is likely that Facebook only wants
5
+ // to support redirecting to a frontend uri.
6
+ //
7
+ // We are only going to support the OAuth flow for now. More details about the flow:
8
+ // https://developers.facebook.com/docs/facebook-login/guides/advanced/oidc-token
9
+ //
10
+ // Also note that Facebook's discover uri does not work for the OAuth flow, as the
11
+ // token_endpoint and userinfo_endpoint are not included in the response.
12
+ // await Issuer.discover("https://www.facebook.com/.well-known/openid-configuration/");
13
+ const issuer = new Issuer({
14
+ issuer: "https://www.facebook.com",
15
+ authorization_endpoint: "https://facebook.com/dialog/oauth/",
16
+ jwks_uri: "https://www.facebook.com/.well-known/oauth/openid/jwks/",
17
+ token_endpoint: "https://graph.facebook.com/oauth/access_token",
18
+ userinfo_endpoint: "https://graph.facebook.com/oauth/access_token",
19
+ });
20
+ export const FacebookAdapter =
21
+ /* @__PURE__ */
22
+ (config) => {
23
+ return OauthAdapter({
24
+ issuer,
25
+ ...config,
26
+ });
27
+ };
@@ -5,7 +5,9 @@ export * from "./adapter/oidc.js";
5
5
  export * from "./adapter/google.js";
6
6
  export * from "./adapter/link.js";
7
7
  export * from "./adapter/github.js";
8
+ export * from "./adapter/facebook.js";
8
9
  export * from "./adapter/oauth.js";
9
10
  export type { Adapter } from "./adapter/adapter.js";
10
11
  export * from "./session.js";
11
12
  export * from "./handler.js";
13
+ export { Issuer } from "openid-client";
@@ -5,6 +5,8 @@ export * from "./adapter/oidc.js";
5
5
  export * from "./adapter/google.js";
6
6
  export * from "./adapter/link.js";
7
7
  export * from "./adapter/github.js";
8
+ export * from "./adapter/facebook.js";
8
9
  export * from "./adapter/oauth.js";
9
10
  export * from "./session.js";
10
11
  export * from "./handler.js";
12
+ export { Issuer } from "openid-client";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sst",
3
- "version": "2.3.6",
3
+ "version": "2.4.0",
4
4
  "bin": {
5
5
  "sst": "cli/sst.js"
6
6
  },