sst 2.7.2 → 2.8.1

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.
@@ -161,6 +161,7 @@ export const bind = (program) => program
161
161
  "AstroSite",
162
162
  "RemixSite",
163
163
  "SolidStartSite",
164
+ "SvelteKitSite",
164
165
  "SlsNextjsSite",
165
166
  ].includes(c.type))
166
167
  .find((c) => {
@@ -192,7 +192,9 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
192
192
  ? "Remix"
193
193
  : type === "SolidStartSite"
194
194
  ? "SolidStart"
195
- : undefined;
195
+ : type === "SvelteKitSite"
196
+ ? "SvelteKit"
197
+ : undefined;
196
198
  if (framework) {
197
199
  const cdCmd = path.resolve(props.path) === process.cwd()
198
200
  ? ""
@@ -4,6 +4,7 @@ const PACKAGE_MATCH = [
4
4
  "aws-cdk",
5
5
  "@aws-cdk",
6
6
  "constructs",
7
+ "svelte-kit-sst",
7
8
  "solid-start-sst",
8
9
  ];
9
10
  const FIELDS = ["dependencies", "devDependencies"];
package/config.js CHANGED
@@ -122,7 +122,8 @@ export var Config;
122
122
  .filter((c) => c.type === "AstroSite" ||
123
123
  c.type === "NextjsSite" ||
124
124
  c.type === "RemixSite" ||
125
- c.type === "SolidStartSite")
125
+ c.type === "SolidStartSite" ||
126
+ c.type === "SvelteKitSite")
126
127
  .filter((c) => keys.some((key) => c.data.secrets.includes(key)));
127
128
  const siteDataPlaceholder = siteData.filter((c) => c.data.mode === "placeholder");
128
129
  const siteDataEdge = siteData
@@ -1,8 +1,7 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
- import { Architecture } from "aws-cdk-lib/aws-lambda";
4
3
  import { SsrSite } from "./SsrSite.js";
5
- import { Function } from "./Function.js";
4
+ import { SsrFunction } from "./SsrFunction.js";
6
5
  import { EdgeFunction } from "./EdgeFunction.js";
7
6
  /**
8
7
  * The `AstroSite` construct is a higher level CDK construct that makes it easy to create a Astro app.
@@ -34,10 +33,9 @@ export class AstroSite extends SsrSite {
34
33
  }
35
34
  createFunctionForRegional() {
36
35
  const { runtime, timeout, memorySize, permissions, environment, nodejs, bind, cdk, } = this.props;
37
- const fn = new Function(this, `ServerFunction`, {
38
- description: "Server handler",
36
+ const ssrFn = new SsrFunction(this, `ServerFunction`, {
37
+ description: "Server handler for Astro",
39
38
  handler: path.join(this.props.path, "dist", "server", "entry.handler"),
40
- logRetention: "three_days",
41
39
  runtime,
42
40
  memorySize,
43
41
  timeout,
@@ -49,10 +47,8 @@ export class AstroSite extends SsrSite {
49
47
  environment,
50
48
  permissions,
51
49
  ...cdk?.server,
52
- architecture: cdk?.server?.architecture === Architecture.ARM_64 ? "arm_64" : "x86_64",
53
50
  });
54
- fn._doNotAllowOthersToBind = true;
55
- return fn;
51
+ return ssrFn.function;
56
52
  }
57
53
  createFunctionForEdge() {
58
54
  const { runtime, timeout, memorySize, bind, permissions, environment, nodejs, } = this.props;
@@ -75,7 +75,7 @@ export class EdgeFunction extends Construct {
75
75
  const lambdaBucket = this.createSingletonBucketInUsEast1();
76
76
  const { fn, fnArn } = this.createFunctionInUsEast1(assetBucket, assetKey, lambdaBucket);
77
77
  const { versionId } = this.createVersionInUsEast1(fn, fnArn);
78
- // Deploy after the code is updated
78
+ // Create function after the code is updated
79
79
  fn.node.addDependency(assetReplacer);
80
80
  this.function = fn;
81
81
  this.functionArn = fnArn;
@@ -182,6 +182,10 @@ export class EdgeFunction extends Construct {
182
182
  }
183
183
  createCodeReplacer(assetBucket, assetKey, handlerFilename) {
184
184
  const { environment } = this.props;
185
+ const stack = Stack.of(this);
186
+ // Note: Source code for the Lambda functions have "{{ ENV_KEY }}" in them.
187
+ // They need to be replaced with real values before the Lambda
188
+ // functions get deployed.
185
189
  const replacements = [
186
190
  {
187
191
  files: handlerFilename,
@@ -192,15 +196,11 @@ export class EdgeFunction extends Construct {
192
196
  }),
193
197
  },
194
198
  ...Object.entries(environment).map(([key, value]) => ({
195
- files: "**/*.*js",
199
+ files: "**/*.@(*js|json|html)",
196
200
  search: `{{ ${key} }}`,
197
201
  replace: value,
198
202
  })),
199
203
  ];
200
- // Note: Source code for the Lambda functions have "{{ ENV_KEY }}" in them.
201
- // They need to be replaced with real values before the Lambda
202
- // functions get deployed.
203
- const stack = Stack.of(this);
204
204
  const policy = new Policy(this, "AssetReplacerPolicy", {
205
205
  statements: [
206
206
  new PolicyStatement({
@@ -122,6 +122,7 @@ export class Function extends CDKFunction {
122
122
  environment: props.environment,
123
123
  layers: Function.buildLayers(scope, id, props),
124
124
  logRetention,
125
+ logRetentionRetryOptions: logRetention && { maxRetries: 100 },
125
126
  });
126
127
  }
127
128
  // Handle local development (ie. sst start)
@@ -156,6 +157,7 @@ export class Function extends CDKFunction {
156
157
  environment: props.environment,
157
158
  layers: [],
158
159
  logRetention,
160
+ logRetentionRetryOptions: logRetention && { maxRetries: 100 },
159
161
  retryAttempts: 0,
160
162
  ...(debugOverrideProps || {}),
161
163
  });
@@ -194,6 +196,7 @@ export class Function extends CDKFunction {
194
196
  environment: props.environment,
195
197
  layers: Function.buildLayers(scope, id, props),
196
198
  logRetention,
199
+ logRetentionRetryOptions: logRetention && { maxRetries: 100 },
197
200
  });
198
201
  useDeferredTasks().add(async () => {
199
202
  // Build function
@@ -3,9 +3,8 @@ import url from "url";
3
3
  import path from "path";
4
4
  import { createRequire } from "module";
5
5
  const require = createRequire(import.meta.url);
6
- import { Architecture } from "aws-cdk-lib/aws-lambda";
7
6
  import { SsrSite } from "./SsrSite.js";
8
- import { Function } from "./Function.js";
7
+ import { SsrFunction } from "./SsrFunction.js";
9
8
  import { EdgeFunction } from "./EdgeFunction.js";
10
9
  const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
11
10
  /**
@@ -92,10 +91,9 @@ export class RemixSite extends SsrSite {
92
91
  createFunctionForRegional() {
93
92
  const { runtime, timeout, memorySize, permissions, environment, bind, nodejs, cdk, } = this.props;
94
93
  const { handler, esbuild } = this.createServerLambdaBundle("regional-server.js");
95
- const fn = new Function(this, `ServerFunction`, {
96
- description: "Server handler",
94
+ const ssrFn = new SsrFunction(this, `ServerFunction`, {
95
+ description: "Server handler for Remix",
97
96
  handler,
98
- logRetention: "three_days",
99
97
  runtime,
100
98
  memorySize,
101
99
  timeout,
@@ -112,10 +110,8 @@ export class RemixSite extends SsrSite {
112
110
  environment,
113
111
  permissions,
114
112
  ...cdk?.server,
115
- architecture: cdk?.server?.architecture === Architecture.ARM_64 ? "arm_64" : "x86_64",
116
113
  });
117
- fn._doNotAllowOthersToBind = true;
118
- return fn;
114
+ return ssrFn.function;
119
115
  }
120
116
  createFunctionForEdge() {
121
117
  const { runtime, timeout, memorySize, bind, permissions, environment, nodejs, } = this.props;
@@ -1,7 +1,6 @@
1
1
  import path from "path";
2
- import { Architecture } from "aws-cdk-lib/aws-lambda";
3
2
  import { SsrSite } from "./SsrSite.js";
4
- import { Function } from "./Function.js";
3
+ import { SsrFunction } from "./SsrFunction.js";
5
4
  import { EdgeFunction } from "./EdgeFunction.js";
6
5
  /**
7
6
  * The `SolidStartSite` construct is a higher level CDK construct that makes it easy to create a SolidStart app.
@@ -25,11 +24,9 @@ export class SolidStartSite extends SsrSite {
25
24
  }
26
25
  createFunctionForRegional() {
27
26
  const { runtime, timeout, memorySize, bind, nodejs, permissions, environment, cdk, } = this.props;
28
- // Create function
29
- const fn = new Function(this, `ServerFunction`, {
30
- description: "Server handler",
27
+ const ssrFn = new SsrFunction(this, `ServerFunction`, {
28
+ description: "Server handler for Solid",
31
29
  handler: path.join(this.props.path, "dist", "server", "index.handler"),
32
- logRetention: "three_days",
33
30
  runtime,
34
31
  memorySize,
35
32
  timeout,
@@ -41,10 +38,8 @@ export class SolidStartSite extends SsrSite {
41
38
  environment,
42
39
  permissions,
43
40
  ...cdk?.server,
44
- architecture: cdk?.server?.architecture === Architecture.ARM_64 ? "arm_64" : "x86_64",
45
41
  });
46
- fn._doNotAllowOthersToBind = true;
47
- return fn;
42
+ return ssrFn.function;
48
43
  }
49
44
  createFunctionForEdge() {
50
45
  const { runtime, timeout, memorySize, bind, permissions, environment, nodejs, } = this.props;
@@ -1,11 +1,12 @@
1
1
  import { Construct } from "constructs";
2
2
  import { FunctionOptions, Function as CdkFunction } from "aws-cdk-lib/aws-lambda";
3
+ import { NodeJSProps, FunctionCopyFilesProps } from "./Function.js";
3
4
  import { SSTConstruct } from "./Construct.js";
4
5
  import { Permissions } from "./util/permission.js";
5
6
  import { Size } from "./util/size.js";
6
7
  import { Duration } from "./util/duration.js";
7
8
  export interface SsrFunctionProps extends Omit<FunctionOptions, "memorySize" | "timeout" | "runtime"> {
8
- bundle: string;
9
+ bundle?: string;
9
10
  handler: string;
10
11
  runtime?: "nodejs14.x" | "nodejs16.x" | "nodejs18.x";
11
12
  timeout: number | Duration;
@@ -13,14 +14,21 @@ export interface SsrFunctionProps extends Omit<FunctionOptions, "memorySize" | "
13
14
  permissions?: Permissions;
14
15
  environment?: Record<string, string>;
15
16
  bind?: SSTConstruct[];
17
+ nodejs?: NodeJSProps;
18
+ copyFiles?: FunctionCopyFilesProps[];
16
19
  }
17
20
  export declare class SsrFunction extends Construct {
18
21
  function: CdkFunction;
22
+ private assetReplacer;
23
+ private assetReplacerPolicy;
19
24
  private props;
20
25
  constructor(scope: Construct, id: string, props: SsrFunctionProps);
21
26
  attachPermissions(permissions: Permissions): void;
22
- private createCodeAsset;
23
27
  private createFunction;
24
28
  private createCodeReplacer;
25
29
  private bind;
30
+ private buildAssetFromHandler;
31
+ private buildAssetFromBundle;
32
+ private updateCodeReplacer;
33
+ private updateFunction;
26
34
  }
@@ -2,12 +2,16 @@ import url from "url";
2
2
  import path from "path";
3
3
  import spawn from "cross-spawn";
4
4
  import { Construct } from "constructs";
5
- import { Effect, Policy, PolicyStatement } from "aws-cdk-lib/aws-iam";
5
+ import { Effect, Policy, PolicyStatement, } from "aws-cdk-lib/aws-iam";
6
6
  import { RetentionDays } from "aws-cdk-lib/aws-logs";
7
- import { Architecture, Runtime, Code, Function as CdkFunction, } from "aws-cdk-lib/aws-lambda";
7
+ import { Architecture, AssetCode, Runtime, Code, Function as CdkFunction, } from "aws-cdk-lib/aws-lambda";
8
+ import { Bucket } from "aws-cdk-lib/aws-s3";
8
9
  import { Asset } from "aws-cdk-lib/aws-s3-assets";
9
- import { Duration as CdkDuration, CustomResource } from "aws-cdk-lib";
10
+ import { Duration as CdkDuration, CustomResource, } from "aws-cdk-lib";
10
11
  import { useProject } from "../project.js";
12
+ import { useRuntimeHandlers } from "../runtime/handlers.js";
13
+ import { useFunctions, } from "./Function.js";
14
+ import { useDeferredTasks } from "./deferred_task.js";
11
15
  import { Stack } from "./Stack.js";
12
16
  import { bindEnvironment, bindPermissions, getReferencedSecrets, } from "./util/functionBinding.js";
13
17
  import { attachPermissionsToRole } from "./util/permission.js";
@@ -19,6 +23,8 @@ const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
19
23
  /////////////////////
20
24
  export class SsrFunction extends Construct {
21
25
  function;
26
+ assetReplacer;
27
+ assetReplacerPolicy;
22
28
  props;
23
29
  constructor(scope, id, props) {
24
30
  super(scope, id);
@@ -27,41 +33,48 @@ export class SsrFunction extends Construct {
27
33
  environment: props.environment || {},
28
34
  permissions: props.permissions || [],
29
35
  };
30
- const asset = this.createCodeAsset();
31
- const assetReplacer = this.createCodeReplacer(asset);
32
- this.function = this.createFunction(asset);
36
+ const { assetBucket, assetKey } = (props.bundle
37
+ ? // Case: bundle is pre-built
38
+ () => {
39
+ const asset = this.buildAssetFromBundle(props.bundle);
40
+ return {
41
+ assetBucket: asset.s3BucketName,
42
+ assetKey: asset.s3ObjectKey,
43
+ };
44
+ }
45
+ : // Case: bundle is NOT pre-built
46
+ () => {
47
+ this.buildAssetFromHandler((code) => {
48
+ const codeConfig = code.bind(this.function);
49
+ const assetBucket = codeConfig.s3Location?.bucketName;
50
+ const assetKey = codeConfig.s3Location?.objectKey;
51
+ this.updateCodeReplacer(assetBucket, assetKey);
52
+ this.updateFunction(code, assetBucket, assetKey);
53
+ });
54
+ return {
55
+ assetBucket: "placeholder",
56
+ assetKey: "placeholder",
57
+ };
58
+ })();
59
+ const { assetReplacer, assetReplacerPolicy } = this.createCodeReplacer(assetBucket, assetKey);
60
+ this.function = this.createFunction(assetBucket, assetKey);
33
61
  this.attachPermissions(props.permissions || []);
34
62
  this.bind(props.bind || []);
63
+ // Create function after the code is updated
35
64
  this.function.node.addDependency(assetReplacer);
65
+ this.assetReplacer = assetReplacer;
66
+ this.assetReplacerPolicy = assetReplacerPolicy;
36
67
  }
37
68
  attachPermissions(permissions) {
38
69
  attachPermissionsToRole(this.function.role, permissions);
39
70
  }
40
- createCodeAsset() {
41
- const { bundle } = this.props;
42
- // Note: cannot point the bundle to the `.open-next/server-function`
43
- // b/c the folder contains node_modules. And pnpm node_modules
44
- // contains symlinks. CDK cannot zip symlinks correctly.
45
- // https://github.com/aws/aws-cdk/issues/9251
46
- // We will zip the folder ourselves.
47
- const outputPath = path.resolve(useProject().paths.artifacts, `SsrFunction-${this.node.id}-${this.node.addr}`);
48
- const script = path.resolve(__dirname, "../support/ssr-site-function-archiver.mjs");
49
- const result = spawn.sync("node", [script, path.join(bundle), path.join(outputPath, "server-function.zip")], { stdio: "inherit" });
50
- if (result.status !== 0) {
51
- throw new Error(`There was a problem generating the assets package.`);
52
- }
53
- // Create asset
54
- return new Asset(this, "Asset", {
55
- path: path.join(outputPath, "server-function.zip"),
56
- });
57
- }
58
- createFunction(asset) {
71
+ createFunction(assetBucket, assetKey) {
59
72
  const { runtime, timeout, memorySize, handler } = this.props;
60
73
  return new CdkFunction(this, `ServerFunction`, {
61
74
  ...this.props,
62
75
  handler,
63
76
  logRetention: RetentionDays.THREE_DAYS,
64
- code: Code.fromBucket(asset.bucket, asset.s3ObjectKey),
77
+ code: Code.fromBucket(Bucket.fromBucketName(this, "IServerFunctionBucket", assetBucket), assetKey),
65
78
  runtime: runtime === "nodejs14.x"
66
79
  ? Runtime.NODEJS_14_X
67
80
  : runtime === "nodejs16.x"
@@ -76,18 +89,21 @@ export class SsrFunction extends Construct {
76
89
  : CdkDuration.seconds(timeout),
77
90
  });
78
91
  }
79
- createCodeReplacer(asset) {
92
+ createCodeReplacer(assetBucket, assetKey) {
80
93
  const { environment } = this.props;
81
94
  // Note: Source code for the Lambda functions have "{{ ENV_KEY }}" in them.
82
95
  // They need to be replaced with real values before the Lambda
83
96
  // functions get deployed.
97
+ // - "*.js" files: ie. Next.js server function
98
+ // - "*.html" files: ie. SvelteKit prerendered pages data
99
+ // - "*.json" files: ie. SvelteKit prerendered + SSR data
84
100
  const stack = Stack.of(this);
85
101
  const policy = new Policy(this, "AssetReplacerPolicy", {
86
102
  statements: [
87
103
  new PolicyStatement({
88
104
  effect: Effect.ALLOW,
89
105
  actions: ["s3:GetObject", "s3:PutObject"],
90
- resources: [`arn:${stack.partition}:s3:::${asset.s3BucketName}/*`],
106
+ resources: [`arn:${stack.partition}:s3:::${assetBucket}/*`],
91
107
  }),
92
108
  ],
93
109
  });
@@ -96,17 +112,17 @@ export class SsrFunction extends Construct {
96
112
  serviceToken: stack.customResourceHandler.functionArn,
97
113
  resourceType: "Custom::AssetReplacer",
98
114
  properties: {
99
- bucket: asset.s3BucketName,
100
- key: asset.s3ObjectKey,
115
+ bucket: assetBucket,
116
+ key: assetKey,
101
117
  replacements: Object.entries(environment).map(([key, value]) => ({
102
- files: "**/*.*js",
118
+ files: "**/*.@(*js|json|html)",
103
119
  search: `{{ ${key} }}`,
104
120
  replace: value,
105
121
  })),
106
122
  },
107
123
  });
108
124
  resource.node.addDependency(policy);
109
- return resource;
125
+ return { assetReplacer: resource, assetReplacerPolicy: policy };
110
126
  }
111
127
  bind(constructs) {
112
128
  const app = this.node.root;
@@ -131,4 +147,55 @@ export class SsrFunction extends Construct {
131
147
  ]));
132
148
  });
133
149
  }
150
+ buildAssetFromHandler(onBundled) {
151
+ useFunctions().add(this.node.addr, {
152
+ handler: this.props.handler,
153
+ runtime: this.props.runtime,
154
+ nodejs: this.props.nodejs,
155
+ copyFiles: this.props.copyFiles,
156
+ });
157
+ useDeferredTasks().add(async () => {
158
+ // Build function
159
+ const bundle = await useRuntimeHandlers().build(this.node.addr, "deploy");
160
+ // create wrapper that calls the handler
161
+ if (bundle.type === "error")
162
+ throw new Error(`There was a problem bundling the SSR function for the "${this.node.id}" Site.`);
163
+ const code = AssetCode.fromAsset(bundle.out);
164
+ onBundled(code);
165
+ });
166
+ }
167
+ buildAssetFromBundle(bundle) {
168
+ // Note: cannot point the bundle to the `.open-next/server-function`
169
+ // b/c the folder contains node_modules. And pnpm node_modules
170
+ // contains symlinks. CDK cannot zip symlinks correctly.
171
+ // https://github.com/aws/aws-cdk/issues/9251
172
+ // We will zip the folder ourselves.
173
+ const outputPath = path.resolve(useProject().paths.artifacts, `SsrFunction-${this.node.id}-${this.node.addr}`);
174
+ const script = path.resolve(__dirname, "../support/ssr-site-function-archiver.mjs");
175
+ const result = spawn.sync("node", [script, path.join(bundle), path.join(outputPath, "server-function.zip")], { stdio: "inherit" });
176
+ if (result.status !== 0) {
177
+ throw new Error(`There was a problem generating the assets package.`);
178
+ }
179
+ // Create asset
180
+ return new Asset(this, `FunctionAsset`, {
181
+ path: path.join(outputPath, "server-function.zip"),
182
+ });
183
+ }
184
+ updateCodeReplacer(assetBucket, assetKey) {
185
+ const stack = Stack.of(this);
186
+ const cfnReplacer = this.assetReplacer.node
187
+ .defaultChild;
188
+ cfnReplacer.addPropertyOverride("bucket", assetBucket);
189
+ cfnReplacer.addPropertyOverride("key", assetKey);
190
+ const cfnPolicy = this.assetReplacerPolicy.node.defaultChild;
191
+ cfnPolicy.addPropertyOverride("PolicyDocument.Statement.0.Resource", `arn:${stack.partition}:s3:::${assetBucket}/*`);
192
+ }
193
+ updateFunction(code, assetBucket, assetKey) {
194
+ const cfnFunction = this.function.node.defaultChild;
195
+ cfnFunction.code = {
196
+ s3Bucket: assetBucket,
197
+ s3Key: assetKey,
198
+ };
199
+ code.bindToResource(cfnFunction);
200
+ }
134
201
  }
@@ -5,19 +5,21 @@ import { IHostedZone } from "aws-cdk-lib/aws-route53";
5
5
  import { Distribution, ICachePolicy, BehaviorOptions, CachePolicy, Function as CfFunction, FunctionEventType as CfFunctionEventType } from "aws-cdk-lib/aws-cloudfront";
6
6
  import { ICertificate } from "aws-cdk-lib/aws-certificatemanager";
7
7
  import { SSTConstruct } from "./Construct.js";
8
- import { NodeJSProps, Function } from "./Function.js";
8
+ import { NodeJSProps } from "./Function.js";
9
9
  import { EdgeFunction } from "./EdgeFunction.js";
10
10
  import { BaseSiteDomainProps, BaseSiteReplaceProps, BaseSiteCdkDistributionProps } from "./BaseSite.js";
11
11
  import { Size } from "./util/size.js";
12
12
  import { Duration } from "./util/duration.js";
13
13
  import { Permissions } from "./util/permission.js";
14
14
  import { FunctionBindingProps } from "./util/functionBinding.js";
15
- type SsrSiteType = "NextjsSite" | "RemixSite" | "AstroSite" | "SolidStartSite";
15
+ type SsrSiteType = "NextjsSite" | "RemixSite" | "AstroSite" | "SolidStartSite" | "SvelteKitSite";
16
16
  export type SsrBuildConfig = {
17
17
  typesPath: string;
18
18
  serverBuildOutputFile: string;
19
+ serverCFFunctionInjection?: string;
19
20
  clientBuildOutputDir: string;
20
21
  clientBuildVersionedSubDir: string;
22
+ prerenderedBuildOutputDir?: string;
21
23
  };
22
24
  export interface SsrSiteNodeJSProps extends NodeJSProps {
23
25
  }
@@ -259,7 +261,7 @@ export declare class SsrSite extends Construct implements SSTConstruct {
259
261
  private createS3Deployment;
260
262
  protected createFunctionForRegional(): CdkFunction;
261
263
  protected createFunctionForEdge(): EdgeFunction;
262
- protected createFunctionForDev(): Function;
264
+ protected createFunctionForDev(): CdkFunction;
263
265
  private createFunctionPermissionsForRegional;
264
266
  private createFunctionPermissionsForEdge;
265
267
  private validateCloudFrontDistributionSettings;
@@ -20,8 +20,8 @@ import { Stack } from "./Stack.js";
20
20
  import { Logger } from "../logger.js";
21
21
  import { createAppContext } from "./context.js";
22
22
  import { isCDKConstruct } from "./Construct.js";
23
- import { Function } from "./Function.js";
24
23
  import { Secret } from "./Secret.js";
24
+ import { SsrFunction } from "./SsrFunction.js";
25
25
  import { getBuildCmdEnvironment, } from "./BaseSite.js";
26
26
  import { HttpsRedirect } from "./cdk/website-redirect.js";
27
27
  import { DnsValidatedCertificate } from "./cdk/dns-validated-certificate.js";
@@ -167,8 +167,10 @@ export class SsrSite extends Construct {
167
167
  * ```
168
168
  */
169
169
  attachPermissions(permissions) {
170
- this.serverLambdaForDev?.attachPermissions(permissions);
171
170
  this.serverLambdaForEdge?.attachPermissions(permissions);
171
+ if (this.serverLambdaForDev) {
172
+ attachPermissionsToRole(this.serverLambdaForDev.role, permissions);
173
+ }
172
174
  if (this.serverLambdaForRegional) {
173
175
  attachPermissionsToRole(this.serverLambdaForRegional.role, permissions);
174
176
  }
@@ -291,7 +293,14 @@ export class SsrSite extends Construct {
291
293
  : 200;
292
294
  const result = spawn.sync("node", [
293
295
  script,
294
- path.join(this.props.path, this.buildConfig.clientBuildOutputDir),
296
+ [
297
+ path.join(this.props.path, this.buildConfig.clientBuildOutputDir),
298
+ ...(this.buildConfig.prerenderedBuildOutputDir
299
+ ? [
300
+ path.join(this.props.path, this.buildConfig.prerenderedBuildOutputDir),
301
+ ]
302
+ : []),
303
+ ].join(","),
295
304
  zipOutDir,
296
305
  `${fileSizeLimit}`,
297
306
  ], {
@@ -425,22 +434,20 @@ export class SsrSite extends Construct {
425
434
  assumedBy: new AnyPrincipal(),
426
435
  maxSessionDuration: CdkDuration.hours(12),
427
436
  });
428
- const fn = new Function(this, `ServerFunction`, {
437
+ const ssrFn = new SsrFunction(this, `ServerFunction`, {
429
438
  description: "Server handler placeholder",
430
- handler: "placeholder",
439
+ bundle: path.join(__dirname, "../../support/ssr-site-function-stub"),
440
+ handler: "index.handler",
431
441
  runtime,
432
442
  memorySize,
433
443
  timeout,
444
+ role,
434
445
  bind,
435
446
  environment,
436
447
  permissions,
437
- role,
438
- // Force enable live dev to prevent the function handler to be built
439
- // in the case user set "enableLiveDev: false" on the app or stack.
440
- enableLiveDev: true,
448
+ // note: do not need to set vpc settings b/c this function is not being used
441
449
  });
442
- fn._doNotAllowOthersToBind = true;
443
- return fn;
450
+ return ssrFn.function;
444
451
  }
445
452
  createFunctionPermissionsForRegional() {
446
453
  this.bucket.grantReadWrite(this.serverLambdaForRegional.role);
@@ -466,6 +473,7 @@ export class SsrSite extends Construct {
466
473
  function handler(event) {
467
474
  var request = event.request;
468
475
  request.headers["x-forwarded-host"] = request.headers.host;
476
+ ${this.buildConfig.serverCFFunctionInjection || ""}
469
477
  return request;
470
478
  }`),
471
479
  });
@@ -786,6 +794,10 @@ function handler(event) {
786
794
  files: "**/*.js",
787
795
  search: token,
788
796
  replace: value,
797
+ }, {
798
+ files: "**/*.json",
799
+ search: token,
800
+ replace: value,
789
801
  });
790
802
  });
791
803
  return replaceValues;
@@ -0,0 +1,27 @@
1
+ import { Function as CdkFunction } from "aws-cdk-lib/aws-lambda";
2
+ import { SsrSite } from "./SsrSite.js";
3
+ import { EdgeFunction } from "./EdgeFunction.js";
4
+ /**
5
+ * The `SvelteKitSite` construct is a higher level CDK construct that makes it easy to create a SvelteKit app.
6
+ * @example
7
+ * Deploys a SvelteKit app in the `my-svelte-app` directory.
8
+ *
9
+ * ```js
10
+ * new SvelteKitSite(stack, "web", {
11
+ * path: "my-svelte-app/",
12
+ * });
13
+ * ```
14
+ */
15
+ export declare class SvelteKitSite extends SsrSite {
16
+ protected initBuildConfig(): {
17
+ typesPath: string;
18
+ serverBuildOutputFile: string;
19
+ serverCFFunctionInjection: string;
20
+ clientBuildOutputDir: string;
21
+ clientBuildVersionedSubDir: string;
22
+ prerenderedBuildOutputDir: string;
23
+ };
24
+ protected createFunctionForRegional(): CdkFunction;
25
+ protected createFunctionForEdge(): EdgeFunction;
26
+ protected generateBuildId(): string;
27
+ }