sst 2.22.10 → 2.23.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.
@@ -0,0 +1,584 @@
1
+ import path from "path";
2
+ import url from "url";
3
+ import fs from "fs";
4
+ import { VisibleError } from "../error.js";
5
+ import { execAsync } from "../util/process.js";
6
+ import { existsAsync } from "../util/fs.js";
7
+ import { Colors } from "../cli/colors.js";
8
+ import { Construct } from "constructs";
9
+ import { Duration as CdkDuration } from "aws-cdk-lib/core";
10
+ import { Role, Effect, PolicyStatement, AccountPrincipal, ServicePrincipal, CompositePrincipal, } from "aws-cdk-lib/aws-iam";
11
+ import { ViewerProtocolPolicy, AllowedMethods, CachedMethods, CachePolicy, CacheQueryStringBehavior, CacheHeaderBehavior, CacheCookieBehavior, OriginProtocolPolicy, OriginRequestPolicy, } from "aws-cdk-lib/aws-cloudfront";
12
+ import { HttpOrigin } from "aws-cdk-lib/aws-cloudfront-origins";
13
+ import { Stack } from "./Stack.js";
14
+ import { Distribution } from "./Distribution.js";
15
+ import { Function } from "./Function.js";
16
+ import { Secret } from "./Secret.js";
17
+ import { useDeferredTasks } from "./deferred_task.js";
18
+ import { attachPermissionsToRole } from "./util/permission.js";
19
+ import { bindEnvironment, bindPermissions, getParameterPath, getReferencedSecrets, } from "./util/functionBinding.js";
20
+ import { useProject } from "../project.js";
21
+ import { Vpc, } from "aws-cdk-lib/aws-ec2";
22
+ import { AwsLogDriver, Cluster, FargateTaskDefinition, ContainerImage, FargateService, } from "aws-cdk-lib/aws-ecs";
23
+ import { LogGroup, RetentionDays } from "aws-cdk-lib/aws-logs";
24
+ import { Platform } from "aws-cdk-lib/aws-ecr-assets";
25
+ import { ApplicationLoadBalancer, } from "aws-cdk-lib/aws-elasticloadbalancingv2";
26
+ import { createAppContext } from "./context.js";
27
+ const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
28
+ const NIXPACKS_IMAGE_NAME = "sst-nixpacks";
29
+ const supportedCpus = {
30
+ "0.25 vCPU": 256,
31
+ "0.5 vCPU": 512,
32
+ "1 vCPU": 1024,
33
+ "2 vCPU": 2048,
34
+ "4 vCPU": 4096,
35
+ "8 vCPU": 8192,
36
+ "16 vCPU": 16384,
37
+ };
38
+ const supportedMemories = {
39
+ "0.25 vCPU": {
40
+ "0.5 GB": 512,
41
+ "1 GB": 1024,
42
+ "2 GB": 2048,
43
+ },
44
+ "0.5 vCPU": {
45
+ "1 GB": 1024,
46
+ "2 GB": 2048,
47
+ "3 GB": 3072,
48
+ "4 GB": 4096,
49
+ },
50
+ "1 vCPU": {
51
+ "2 GB": 2048,
52
+ "3 GB": 3072,
53
+ "4 GB": 4096,
54
+ "5 GB": 5120,
55
+ "6 GB": 6144,
56
+ "7 GB": 7168,
57
+ "8 GB": 8192,
58
+ },
59
+ "2 vCPU": {
60
+ "4 GB": 4096,
61
+ "5 GB": 5120,
62
+ "6 GB": 6144,
63
+ "7 GB": 7168,
64
+ "8 GB": 8192,
65
+ "9 GB": 9216,
66
+ "10 GB": 10240,
67
+ "11 GB": 11264,
68
+ "12 GB": 12288,
69
+ "13 GB": 13312,
70
+ "14 GB": 14336,
71
+ "15 GB": 15360,
72
+ "16 GB": 16384,
73
+ },
74
+ "4 vCPU": {
75
+ "8 GB": 8192,
76
+ "9 GB": 9216,
77
+ "10 GB": 10240,
78
+ "11 GB": 11264,
79
+ "12 GB": 12288,
80
+ "13 GB": 13312,
81
+ "14 GB": 14336,
82
+ "15 GB": 15360,
83
+ "16 GB": 16384,
84
+ "17 GB": 17408,
85
+ "18 GB": 18432,
86
+ "19 GB": 19456,
87
+ "20 GB": 20480,
88
+ "21 GB": 21504,
89
+ "22 GB": 22528,
90
+ "23 GB": 23552,
91
+ "24 GB": 24576,
92
+ "25 GB": 25600,
93
+ "26 GB": 26624,
94
+ "27 GB": 27648,
95
+ "28 GB": 28672,
96
+ "29 GB": 29696,
97
+ "30 GB": 30720,
98
+ },
99
+ "8 vCPU": {
100
+ "16 GB": 16384,
101
+ "20 GB": 20480,
102
+ "24 GB": 24576,
103
+ "28 GB": 28672,
104
+ "32 GB": 32768,
105
+ "36 GB": 36864,
106
+ "40 GB": 40960,
107
+ "44 GB": 45056,
108
+ "48 GB": 49152,
109
+ "52 GB": 53248,
110
+ "56 GB": 57344,
111
+ "60 GB": 61440,
112
+ },
113
+ "16 vCPU": {
114
+ "32 GB": 32768,
115
+ "40 GB": 40960,
116
+ "48 GB": 49152,
117
+ "56 GB": 57344,
118
+ "64 GB": 65536,
119
+ "72 GB": 73728,
120
+ "80 GB": 81920,
121
+ "88 GB": 90112,
122
+ "96 GB": 98304,
123
+ "104 GB": 106496,
124
+ "112 GB": 114688,
125
+ "120 GB": 122880,
126
+ },
127
+ };
128
+ /**
129
+ * The `Service` construct is a higher level CDK construct that makes it easy to create modern web apps with Server Side Rendering capabilities.
130
+ * @example
131
+ * Deploys a service in the `app` directory.
132
+ *
133
+ * ```js
134
+ * new Service(stack, "myApp", {
135
+ * path: "app",
136
+ * });
137
+ * ```
138
+ */
139
+ export class Service extends Construct {
140
+ id;
141
+ props;
142
+ doNotDeploy;
143
+ devFunction;
144
+ vpc;
145
+ cluster;
146
+ container;
147
+ taskDefinition;
148
+ distribution;
149
+ constructor(scope, id, props) {
150
+ super(scope, id);
151
+ const app = scope.node.root;
152
+ const stack = Stack.of(this);
153
+ this.id = id;
154
+ this.props = {
155
+ path: ".",
156
+ waitForInvalidation: false,
157
+ cpu: props?.cpu || "0.25 vCPU",
158
+ memory: props?.memory || "0.5 GB",
159
+ port: props?.port || 3000,
160
+ ...props,
161
+ };
162
+ this.doNotDeploy =
163
+ !stack.isActive || (app.mode === "dev" && !this.props.dev?.deploy);
164
+ this.validateServiceExists();
165
+ this.validateMemoryAndCpu();
166
+ useServices().add(stack.stackName, id, this.props);
167
+ if (this.doNotDeploy) {
168
+ // @ts-expect-error
169
+ this.vpc = this.cluster = this.container = this.taskDefinition = null;
170
+ // @ts-expect-error
171
+ this.distribution = null;
172
+ this.devFunction = this.createDevFunction();
173
+ return;
174
+ }
175
+ // Create ECS cluster
176
+ const vpc = this.createVpc();
177
+ const { cluster, container, taskDefinition, service } = this.createService(vpc);
178
+ const { alb, target } = this.createLoadBalancer(vpc, service);
179
+ this.createAutoScaling(service, target);
180
+ // Create Distribution
181
+ this.distribution = this.createDistribution(alb);
182
+ this.vpc = vpc;
183
+ this.cluster = cluster;
184
+ this.container = container;
185
+ this.taskDefinition = taskDefinition;
186
+ this.bindForService(props?.bind || []);
187
+ this.attachPermissionsForService(props?.permissions || []);
188
+ Object.entries(props?.environment || {}).map(([key, value]) => this.addEnvironmentForService(key, value));
189
+ useDeferredTasks().add(async () => {
190
+ if (!app.isRunningSSTTest()) {
191
+ Colors.line(`➜ Building container image for the "${this.node.id}" service`);
192
+ // Build app
193
+ let dockerfile = "Dockerfile";
194
+ if (!(await existsAsync(path.join(this.props.path, dockerfile)))) {
195
+ await this.createNixpacksBuilder();
196
+ dockerfile = await this.runNixpacksBuild();
197
+ }
198
+ await this.runDockerBuild(dockerfile);
199
+ this.updateContainerImage(dockerfile, taskDefinition, container);
200
+ }
201
+ // Invalidate CloudFront
202
+ this.distribution.createInvalidation();
203
+ });
204
+ }
205
+ /////////////////////
206
+ // Public Properties
207
+ /////////////////////
208
+ /**
209
+ * The CloudFront URL of the website.
210
+ */
211
+ get url() {
212
+ if (this.doNotDeploy)
213
+ return this.props.dev?.url;
214
+ return this.distribution.url;
215
+ }
216
+ /**
217
+ * If the custom domain is enabled, this is the URL of the website with the
218
+ * custom domain.
219
+ */
220
+ get customDomainUrl() {
221
+ if (this.doNotDeploy)
222
+ return;
223
+ return this.distribution.customDomainUrl;
224
+ }
225
+ /**
226
+ * The internally created CDK resources.
227
+ */
228
+ get cdk() {
229
+ if (this.doNotDeploy)
230
+ return;
231
+ return {
232
+ vpc: this.vpc,
233
+ cluster: this.cluster,
234
+ distribution: this.distribution.cdk.distribution,
235
+ hostedZone: this.distribution.cdk.hostedZone,
236
+ certificate: this.distribution.cdk.certificate,
237
+ };
238
+ }
239
+ /////////////////////
240
+ // Public Methods
241
+ /////////////////////
242
+ getConstructMetadata() {
243
+ return {
244
+ type: "Service",
245
+ data: {
246
+ mode: this.doNotDeploy
247
+ ? "placeholder"
248
+ : "deployed",
249
+ path: this.props.path,
250
+ customDomainUrl: this.customDomainUrl,
251
+ url: this.url,
252
+ devFunction: this.devFunction?.functionArn,
253
+ task: this.taskDefinition?.taskDefinitionArn,
254
+ container: this.container?.containerName,
255
+ secrets: (this.props.bind || [])
256
+ .filter((c) => c instanceof Secret)
257
+ .map((c) => c.name),
258
+ },
259
+ };
260
+ }
261
+ /** @internal */
262
+ getFunctionBinding() {
263
+ const app = this.node.root;
264
+ return {
265
+ clientPackage: "service",
266
+ variables: {
267
+ url: this.doNotDeploy
268
+ ? {
269
+ type: "plain",
270
+ value: this.props.dev?.url ?? "localhost",
271
+ }
272
+ : {
273
+ // Do not set real value b/c we don't want to make the Lambda function
274
+ // depend on the Site. B/c often the site depends on the Api, causing
275
+ // a CloudFormation circular dependency if the Api and the Site belong
276
+ // to different stacks.
277
+ type: "site_url",
278
+ value: this.customDomainUrl || this.url,
279
+ },
280
+ },
281
+ permissions: {
282
+ "ssm:GetParameters": [
283
+ `arn:${Stack.of(this).partition}:ssm:${app.region}:${app.account}:parameter${getParameterPath(this, "url")}`,
284
+ ],
285
+ },
286
+ };
287
+ }
288
+ /**
289
+ * Binds additional resources to service.
290
+ *
291
+ * @example
292
+ * ```js
293
+ * service.bind([STRIPE_KEY, bucket]);
294
+ * ```
295
+ */
296
+ bind(constructs) {
297
+ this.devFunction?.bind(constructs);
298
+ this.bindForService(constructs);
299
+ }
300
+ /**
301
+ * Attaches the given list of permissions to allow the service
302
+ * to access other AWS resources.
303
+ *
304
+ * @example
305
+ * ```js
306
+ * service.attachPermissions(["sns"]);
307
+ * ```
308
+ */
309
+ attachPermissions(permissions) {
310
+ this.devFunction?.attachPermissions(permissions);
311
+ this.attachPermissionsForService(permissions);
312
+ }
313
+ /**
314
+ * Attaches additional environment variable to the service.
315
+ *
316
+ * @example
317
+ * ```js
318
+ * service.addEnvironment({
319
+ * DEBUG: "*"
320
+ * });
321
+ * ```
322
+ */
323
+ addEnvironment(name, value) {
324
+ this.devFunction?.addEnvironment(name, value);
325
+ this.addEnvironmentForService(name, value);
326
+ }
327
+ /////////////////////
328
+ // Bundle Cluster
329
+ /////////////////////
330
+ validateServiceExists() {
331
+ const { path: servicePath } = this.props;
332
+ if (!fs.existsSync(servicePath)) {
333
+ throw new Error(`No service found at "${path.resolve(servicePath)}"`);
334
+ }
335
+ }
336
+ validateMemoryAndCpu() {
337
+ const { memory, cpu } = this.props;
338
+ if (!supportedCpus[cpu]) {
339
+ throw new Error(`Only the following "cpu" settings are supported for the ${this.node.id} service: ${Object.keys(supportedCpus).join(", ")}`);
340
+ }
341
+ // @ts-ignore
342
+ if (!supportedMemories[cpu][memory]) {
343
+ throw new Error(`Only the following "memory" settings are supported with "${cpu}" for the ${this.node.id} service: ${Object.keys(supportedMemories[cpu]).join(", ")}`);
344
+ }
345
+ }
346
+ createVpc() {
347
+ const { cdk } = this.props;
348
+ return (cdk?.vpc ??
349
+ new Vpc(this, "Vpc", {
350
+ natGateways: 0,
351
+ }));
352
+ }
353
+ createService(vpc) {
354
+ const { cpu, memory, port } = this.props;
355
+ const app = this.node.root;
356
+ const clusterName = app.logicalPrefixedName(this.node.id);
357
+ const logGroup = new LogGroup(this, "LogGroup", {
358
+ logGroupName: `/sst/service/${clusterName}`,
359
+ retention: RetentionDays.INFINITE,
360
+ });
361
+ const cluster = new Cluster(this, "Cluster", {
362
+ clusterName,
363
+ vpc,
364
+ });
365
+ const taskDefinition = new FargateTaskDefinition(this, `TaskDefinition`, {
366
+ // @ts-ignore
367
+ memoryLimitMiB: supportedMemories[cpu][memory],
368
+ cpu: supportedCpus[cpu],
369
+ });
370
+ const container = taskDefinition.addContainer("Container", {
371
+ image: { bind: () => ({ imageName: "placeholder" }) },
372
+ logging: new AwsLogDriver({
373
+ logGroup,
374
+ streamPrefix: "service",
375
+ }),
376
+ portMappings: [{ containerPort: port }],
377
+ environment: {
378
+ SST_APP: app.name,
379
+ SST_STAGE: app.stage,
380
+ SST_SSM_PREFIX: useProject().config.ssmPrefix,
381
+ },
382
+ });
383
+ const service = new FargateService(this, "Service", {
384
+ cluster,
385
+ taskDefinition,
386
+ });
387
+ return { cluster, taskDefinition, container, service };
388
+ }
389
+ createLoadBalancer(vpc, service) {
390
+ const alb = new ApplicationLoadBalancer(this, "LoadBalancer", {
391
+ vpc,
392
+ internetFacing: true,
393
+ });
394
+ const listener = alb.addListener("Listener", { port: 80 });
395
+ const target = listener.addTargets("TargetGroup", {
396
+ port: 80,
397
+ targets: [service],
398
+ });
399
+ return { alb, target };
400
+ }
401
+ createAutoScaling(service, target) {
402
+ const { minContainers, maxContainers, cpuUtilization, memoryUtilization, requestsPerContainer, } = this.props.scaling ?? {};
403
+ const scaling = service.autoScaleTaskCount({
404
+ minCapacity: minContainers ?? 1,
405
+ maxCapacity: maxContainers ?? 1,
406
+ });
407
+ scaling.scaleOnCpuUtilization("CpuScaling", {
408
+ targetUtilizationPercent: cpuUtilization ?? 70,
409
+ scaleOutCooldown: CdkDuration.seconds(300),
410
+ });
411
+ scaling.scaleOnMemoryUtilization("MemoryScaling", {
412
+ targetUtilizationPercent: memoryUtilization ?? 70,
413
+ scaleOutCooldown: CdkDuration.seconds(300),
414
+ });
415
+ scaling.scaleOnRequestCount("RequestScaling", {
416
+ requestsPerTarget: requestsPerContainer ?? 500,
417
+ targetGroup: target,
418
+ });
419
+ }
420
+ createDistribution(alb) {
421
+ const { customDomain } = this.props;
422
+ const cachePolicy = new CachePolicy(this, "CachePolicy", {
423
+ queryStringBehavior: CacheQueryStringBehavior.all(),
424
+ headerBehavior: CacheHeaderBehavior.none(),
425
+ cookieBehavior: CacheCookieBehavior.none(),
426
+ defaultTtl: CdkDuration.days(0),
427
+ maxTtl: CdkDuration.days(365),
428
+ minTtl: CdkDuration.days(0),
429
+ enableAcceptEncodingBrotli: true,
430
+ enableAcceptEncodingGzip: true,
431
+ comment: "SST server response cache policy",
432
+ });
433
+ return new Distribution(this, "CDN", {
434
+ customDomain,
435
+ cdk: {
436
+ distribution: {
437
+ defaultRootObject: "",
438
+ defaultBehavior: {
439
+ viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
440
+ origin: new HttpOrigin(alb.loadBalancerDnsName, {
441
+ protocolPolicy: OriginProtocolPolicy.HTTP_ONLY,
442
+ readTimeout: CdkDuration.seconds(60),
443
+ }),
444
+ allowedMethods: AllowedMethods.ALLOW_ALL,
445
+ cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS,
446
+ compress: true,
447
+ cachePolicy,
448
+ originRequestPolicy: OriginRequestPolicy.ALL_VIEWER,
449
+ },
450
+ },
451
+ },
452
+ });
453
+ }
454
+ createDevFunction() {
455
+ const { permissions, environment, bind } = this.props;
456
+ const app = this.node.root;
457
+ const role = new Role(this, "ServerFunctionRole", {
458
+ assumedBy: new CompositePrincipal(new AccountPrincipal(app.account), new ServicePrincipal("lambda.amazonaws.com")),
459
+ maxSessionDuration: CdkDuration.hours(12),
460
+ });
461
+ return new Function(this, `ServerFunction`, {
462
+ description: "Service dev function",
463
+ handler: path.join(__dirname, "../support/service-dev-function", "index.handler"),
464
+ runtime: "nodejs18.x",
465
+ memorySize: "512 MB",
466
+ timeout: "10 seconds",
467
+ role,
468
+ bind,
469
+ environment,
470
+ permissions,
471
+ });
472
+ }
473
+ bindForService(constructs) {
474
+ // Get referenced secrets
475
+ const referencedSecrets = [];
476
+ constructs.forEach((c) => referencedSecrets.push(...getReferencedSecrets(c)));
477
+ [...constructs, ...referencedSecrets].forEach((c) => {
478
+ // Bind environment
479
+ const env = bindEnvironment(c);
480
+ Object.entries(env).forEach(([key, value]) => this.addEnvironmentForService(key, value));
481
+ // Bind permissions
482
+ const permissions = bindPermissions(c);
483
+ Object.entries(permissions).forEach(([action, resources]) => this.attachPermissionsForService([
484
+ new PolicyStatement({
485
+ actions: [action],
486
+ effect: Effect.ALLOW,
487
+ resources,
488
+ }),
489
+ ]));
490
+ });
491
+ }
492
+ addEnvironmentForService(name, value) {
493
+ this.container.addEnvironment(name, value);
494
+ }
495
+ attachPermissionsForService(permissions) {
496
+ attachPermissionsToRole(this.taskDefinition.taskRole, permissions);
497
+ }
498
+ /////////////////////
499
+ // Build App
500
+ /////////////////////
501
+ async createNixpacksBuilder() {
502
+ try {
503
+ await execAsync([
504
+ "docker",
505
+ "build",
506
+ `-t ${NIXPACKS_IMAGE_NAME}`,
507
+ "--platform=linux/amd64",
508
+ path.resolve(__dirname, "../support/nixpacks"),
509
+ ].join(" "), {
510
+ env: {
511
+ ...process.env,
512
+ },
513
+ });
514
+ }
515
+ catch (e) {
516
+ console.error(e);
517
+ throw new VisibleError(`Failed to setup Nixpacks builder for the ${this.node.id} service`);
518
+ }
519
+ }
520
+ async runNixpacksBuild() {
521
+ const { path: servicePath } = this.props;
522
+ try {
523
+ await execAsync([
524
+ "docker",
525
+ "run",
526
+ "--rm",
527
+ "--network=host",
528
+ `--name=sst-${this.node.id}-service`,
529
+ `-v=${path.resolve(servicePath)}:/service`,
530
+ `-w="/service"`,
531
+ NIXPACKS_IMAGE_NAME,
532
+ `build . --out .`,
533
+ ].join(" "), {
534
+ env: {
535
+ ...process.env,
536
+ },
537
+ });
538
+ }
539
+ catch (e) {
540
+ console.error(e);
541
+ throw new VisibleError(`Failed to run Nixpacks build for the ${this.node.id} service`);
542
+ }
543
+ return ".nixpacks/Dockerfile";
544
+ }
545
+ async runDockerBuild(dockerfile) {
546
+ try {
547
+ await execAsync([
548
+ "docker",
549
+ "build",
550
+ `-t sst-build:service-${this.node.id}`,
551
+ "--platform=linux/amd64",
552
+ `-f ${path.join(this.props.path, dockerfile)}`,
553
+ this.props.path,
554
+ ].join(" "), {
555
+ env: {
556
+ ...process.env,
557
+ },
558
+ });
559
+ }
560
+ catch (e) {
561
+ console.error(e);
562
+ throw new VisibleError(`Failed to build the ${this.node.id} service`);
563
+ }
564
+ }
565
+ updateContainerImage(dockerfile, taskDefinition, container) {
566
+ const image = ContainerImage.fromAsset(this.props.path, {
567
+ platform: Platform.LINUX_AMD64,
568
+ file: dockerfile,
569
+ });
570
+ const cfnTask = taskDefinition.node.defaultChild;
571
+ cfnTask.addPropertyOverride("ContainerDefinitions.0.Image", image.bind(this, container).imageName);
572
+ }
573
+ }
574
+ export const useServices = createAppContext(() => {
575
+ const sites = [];
576
+ return {
577
+ add(stack, name, props) {
578
+ sites.push({ stack, name, props });
579
+ },
580
+ get all() {
581
+ return sites;
582
+ },
583
+ };
584
+ });
@@ -1,14 +1,13 @@
1
1
  import { Construct } from "constructs";
2
2
  import { Bucket, BucketProps, IBucket } from "aws-cdk-lib/aws-s3";
3
3
  import { IFunction as ICdkFunction, FunctionProps } from "aws-cdk-lib/aws-lambda";
4
- import { IHostedZone } from "aws-cdk-lib/aws-route53";
5
- import { Distribution, ICachePolicy, IResponseHeadersPolicy, BehaviorOptions, CachePolicy, Function as CfFunction, FunctionEventType as CfFunctionEventType } from "aws-cdk-lib/aws-cloudfront";
6
- import { ICertificate } from "aws-cdk-lib/aws-certificatemanager";
4
+ import { ICachePolicy, IResponseHeadersPolicy, BehaviorOptions, CachePolicy, Function as CfFunction, FunctionEventType as CfFunctionEventType } from "aws-cdk-lib/aws-cloudfront";
5
+ import { Distribution, DistributionDomainProps } from "./Distribution.js";
7
6
  import { SSTConstruct } from "./Construct.js";
8
7
  import { NodeJSProps } from "./Function.js";
9
8
  import { SsrFunction } from "./SsrFunction.js";
10
9
  import { EdgeFunction } from "./EdgeFunction.js";
11
- import { BaseSiteFileOptions, BaseSiteDomainProps, BaseSiteReplaceProps, BaseSiteCdkDistributionProps } from "./BaseSite.js";
10
+ import { BaseSiteFileOptions, BaseSiteReplaceProps, BaseSiteCdkDistributionProps } from "./BaseSite.js";
12
11
  import { Size } from "./util/size.js";
13
12
  import { Duration } from "./util/duration.js";
14
13
  import { Permissions } from "./util/permission.js";
@@ -25,7 +24,7 @@ export type SsrBuildConfig = {
25
24
  };
26
25
  export interface SsrSiteNodeJSProps extends NodeJSProps {
27
26
  }
28
- export interface SsrDomainProps extends BaseSiteDomainProps {
27
+ export interface SsrDomainProps extends DistributionDomainProps {
29
28
  }
30
29
  export interface SsrSiteFileOptions extends BaseSiteFileOptions {
31
30
  }
@@ -280,8 +279,6 @@ export declare abstract class SsrSite extends Construct implements SSTConstruct
280
279
  private cfFunction;
281
280
  private s3Origin;
282
281
  private distribution;
283
- private hostedZone?;
284
- private certificate?;
285
282
  constructor(scope: Construct, id: string, props?: SsrSiteProps);
286
283
  /**
287
284
  * The CloudFront URL of the website.
@@ -298,9 +295,9 @@ export declare abstract class SsrSite extends Construct implements SSTConstruct
298
295
  get cdk(): {
299
296
  function: ICdkFunction | undefined;
300
297
  bucket: Bucket;
301
- distribution: Distribution;
302
- hostedZone: IHostedZone | undefined;
303
- certificate: ICertificate | undefined;
298
+ distribution: import("aws-cdk-lib/aws-cloudfront").IDistribution;
299
+ hostedZone: import("aws-cdk-lib/aws-route53").IHostedZone | undefined;
300
+ certificate: import("aws-cdk-lib/aws-certificatemanager").ICertificate | undefined;
304
301
  } | undefined;
305
302
  /**
306
303
  * Attaches the given list of permissions to allow the server side
@@ -340,12 +337,10 @@ export declare abstract class SsrSite extends Construct implements SSTConstruct
340
337
  protected createFunctionForDev(): SsrFunction;
341
338
  private grantServerS3Permissions;
342
339
  private grantServerCloudFrontPermissions;
343
- private validateCloudFrontDistributionSettings;
344
340
  private createCloudFrontS3Origin;
345
341
  private createCloudFrontFunction;
346
342
  protected createCloudFrontDistributionForRegional(): Distribution;
347
343
  protected createCloudFrontDistributionForEdge(): Distribution;
348
- protected buildDistributionDomainNames(): string[];
349
344
  protected buildDefaultBehaviorForRegional(cachePolicy: ICachePolicy): BehaviorOptions;
350
345
  protected buildDefaultBehaviorForEdge(cachePolicy: ICachePolicy): BehaviorOptions;
351
346
  protected buildBehaviorFunctionAssociations(): {
@@ -355,20 +350,17 @@ export declare abstract class SsrSite extends Construct implements SSTConstruct
355
350
  protected addStaticFileBehaviors(): void;
356
351
  protected buildServerCachePolicy(allowedHeaders?: string[]): CachePolicy;
357
352
  protected buildServerOriginRequestPolicy(): import("aws-cdk-lib/aws-cloudfront").IOriginRequestPolicy;
358
- private createCloudFrontInvalidation;
359
- protected validateCustomDomainSettings(): void;
360
- protected lookupHostedZone(): IHostedZone | undefined;
361
- private createCertificate;
362
- protected createRoute53Records(): void;
363
353
  private getS3ContentReplaceValues;
364
354
  private validateSiteExists;
365
355
  private validateTimeout;
366
356
  private writeTypesFile;
367
357
  protected generateBuildId(): string;
358
+ protected supportsStreaming(): boolean;
368
359
  }
369
360
  export declare const useSites: () => {
370
- add(name: string, type: string, props: SsrSiteNormalizedProps): void;
361
+ add(stack: string, name: string, type: string, props: SsrSiteNormalizedProps): void;
371
362
  readonly all: {
363
+ stack: string;
372
364
  name: string;
373
365
  type: string;
374
366
  props: SsrSiteNormalizedProps;