sst 2.42.0 → 2.43.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.
@@ -1,35 +1,20 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
- import zlib from "zlib";
4
3
  import crypto from "crypto";
5
- import { globSync } from "glob";
6
- import { Duration as CdkDuration, RemovalPolicy, CustomResource, } from "aws-cdk-lib/core";
7
- import { Code, Runtime, Function as CdkFunction, Architecture, LayerVersion, } from "aws-cdk-lib/aws-lambda";
4
+ import { Duration as CdkDuration, RemovalPolicy, CustomResource, Fn, } from "aws-cdk-lib/core";
5
+ import { Code, Runtime, Function as CdkFunction, Architecture, } from "aws-cdk-lib/aws-lambda";
8
6
  import { AttributeType, Billing, TableV2 as Table, } from "aws-cdk-lib/aws-dynamodb";
9
7
  import { Provider } from "aws-cdk-lib/custom-resources";
10
8
  import { Queue } from "aws-cdk-lib/aws-sqs";
11
9
  import { SqsEventSource } from "aws-cdk-lib/aws-lambda-event-sources";
12
10
  import { Stack } from "./Stack.js";
13
- import { SsrSite } from "./SsrSite.js";
11
+ import { SsrSite, } from "./SsrSite.js";
14
12
  import { toCdkSize } from "./util/size.js";
15
- import { Effect, Policy, PolicyStatement } from "aws-cdk-lib/aws-iam";
13
+ import { PolicyStatement } from "aws-cdk-lib/aws-iam";
16
14
  import { RetentionDays } from "aws-cdk-lib/aws-logs";
17
15
  import { VisibleError } from "../error.js";
18
- import { Asset } from "aws-cdk-lib/aws-s3-assets";
19
- import { useFunctions } from "./Function.js";
20
- import { useDeferredTasks } from "./deferred_task.js";
21
16
  import { Logger } from "../logger.js";
22
- const LAYER_VERSION = "2";
23
- const DEFAULT_OPEN_NEXT_VERSION = "2.3.8";
24
- const DEFAULT_CACHE_POLICY_ALLOWED_HEADERS = [
25
- "accept",
26
- "rsc",
27
- "next-router-prefetch",
28
- "next-router-state-tree",
29
- "next-url",
30
- "x-prerender-bypass",
31
- "x-prerender-revalidate",
32
- ];
17
+ const DEFAULT_OPEN_NEXT_VERSION = "3.0.2";
33
18
  /**
34
19
  * The `NextjsSite` construct is a higher level CDK construct that makes it easy to create a Next.js app.
35
20
  * @example
@@ -48,118 +33,135 @@ export class NextjsSite extends SsrSite {
48
33
  appPathsManifest;
49
34
  pagesManifest;
50
35
  prerenderManifest;
51
- constructor(scope, id, rawProps) {
52
- const props = {
53
- logging: rawProps?.logging ?? "per-route",
54
- experimental: {
55
- streaming: rawProps?.experimental?.streaming ?? false,
56
- disableDynamoDBCache: rawProps?.experimental?.disableDynamoDBCache ?? false,
57
- disableIncrementalCache: rawProps?.experimental?.disableIncrementalCache ?? false,
58
- ...rawProps?.experimental,
59
- },
60
- ...rawProps,
61
- };
36
+ openNextOutput;
37
+ constructor(scope, id, props = {}) {
62
38
  super(scope, id, {
63
39
  buildCommand: [
64
40
  "npx",
65
41
  "--yes",
66
42
  `open-next@${props?.openNextVersion ?? DEFAULT_OPEN_NEXT_VERSION}`,
67
43
  "build",
68
- ...(props.openNext?.buildOutputPath
69
- ? ["--build-output-path", props.openNext.buildOutputPath]
70
- : []),
71
- ...(props.experimental.streaming ? ["--streaming"] : []),
72
- ...(props.experimental.disableDynamoDBCache
73
- ? ["--dangerously-disable-dynamodb-cache"]
74
- : []),
75
- ...(props.experimental.disableIncrementalCache
76
- ? ["--dangerously-disable-incremental-cache"]
77
- : []),
78
44
  ].join(" "),
79
45
  ...props,
80
46
  });
47
+ const disableIncrementalCache = this.openNextOutput?.additionalProps?.disableIncrementalCache ?? false;
48
+ const disableTagCache = this.openNextOutput?.additionalProps?.disableTagCache ?? false;
81
49
  this.handleMissingSourcemap();
82
- if (this.isPerRouteLoggingEnabled()) {
83
- //this.disableDefaultLogging();
84
- this.uploadSourcemaps();
50
+ if (this.openNextOutput?.edgeFunctions?.middleware) {
51
+ this.setMiddlewareEnv();
85
52
  }
86
- if (!props.experimental.disableIncrementalCache) {
53
+ if (!disableIncrementalCache) {
87
54
  this.createRevalidationQueue();
88
- if (!props.experimental.disableDynamoDBCache) {
55
+ if (!disableTagCache) {
89
56
  this.createRevalidationTable();
90
57
  }
91
58
  }
92
59
  }
93
- static buildDefaultServerCachePolicyProps() {
94
- return super.buildDefaultServerCachePolicyProps(DEFAULT_CACHE_POLICY_ALLOWED_HEADERS);
60
+ createFunctionOrigin(fn, key, bucket) {
61
+ const { path: sitePath, environment, cdk } = this.props;
62
+ const baseServerConfig = {
63
+ description: "Next.js Server",
64
+ environment: {
65
+ CACHE_BUCKET_NAME: bucket.bucketName,
66
+ CACHE_BUCKET_KEY_PREFIX: "_cache",
67
+ CACHE_BUCKET_REGION: Stack.of(this).region,
68
+ },
69
+ };
70
+ return {
71
+ type: "function",
72
+ constructId: `${key}ServerFunction`,
73
+ function: {
74
+ ...baseServerConfig,
75
+ handler: fn.handler,
76
+ bundle: path.join(sitePath, fn.bundle),
77
+ runtime: "nodejs18.x",
78
+ architecture: Architecture.ARM_64,
79
+ memorySize: 1536,
80
+ environment: {
81
+ ...environment,
82
+ ...baseServerConfig.environment,
83
+ },
84
+ },
85
+ streaming: fn.streaming,
86
+ injections: [],
87
+ };
88
+ }
89
+ createEcsOrigin(ecs, key, bucket) {
90
+ throw new Error("Ecs origin are not supported yet");
95
91
  }
96
- plan(bucket) {
97
- const { path: sitePath, edge, experimental, imageOptimization, cdk, } = this.props;
98
- const stack = Stack.of(this);
99
- const serverConfig = {
100
- description: "Next.js server",
101
- bundle: path.join(sitePath, ".open-next", "server-function"),
102
- handler: "index.handler",
92
+ createEdgeOrigin(fn, key, bucket) {
93
+ const { path: sitePath, cdk, environment } = this.props;
94
+ const baseServerConfig = {
103
95
  environment: {
104
96
  CACHE_BUCKET_NAME: bucket.bucketName,
105
97
  CACHE_BUCKET_KEY_PREFIX: "_cache",
106
98
  CACHE_BUCKET_REGION: Stack.of(this).region,
107
99
  },
108
- layers: this.isPerRouteLoggingEnabled()
109
- ? [
110
- LayerVersion.fromLayerVersionArn(this, "SSTExtension", cdk?.server?.architecture?.name === Architecture.X86_64.name
111
- ? `arn:aws:lambda:${stack.region}:226609089145:layer:sst-extension-amd64:${LAYER_VERSION}`
112
- : `arn:aws:lambda:${stack.region}:226609089145:layer:sst-extension-arm64:${LAYER_VERSION}`),
113
- ]
114
- : undefined,
115
100
  };
116
- this.removeSourcemaps();
101
+ return {
102
+ constructId: `${key}EdgeFunction`,
103
+ function: {
104
+ handler: fn.handler,
105
+ bundle: path.join(sitePath, fn.bundle),
106
+ runtime: "nodejs18.x",
107
+ memorySize: 1024,
108
+ environment: {
109
+ ...environment,
110
+ ...baseServerConfig.environment,
111
+ },
112
+ },
113
+ };
114
+ }
115
+ plan(bucket) {
116
+ const { path: sitePath } = this.props;
117
+ const imageOptimization = this.props.imageOptimization;
118
+ const openNextOutputPath = path.join(sitePath ?? ".", ".open-next", "open-next.output.json");
119
+ if (!fs.existsSync(openNextOutputPath)) {
120
+ throw new VisibleError(`Failed to load ".open-next/output.json" for the "${this.id}" site.`);
121
+ }
122
+ const openNextOutput = JSON.parse(fs.readFileSync(openNextOutputPath).toString());
123
+ this.openNextOutput = openNextOutput;
124
+ const imageOpt = openNextOutput.origins
125
+ .imageOptimizer;
126
+ const defaultOrigin = openNextOutput.origins.default;
127
+ const remainingOrigins = Object.entries(openNextOutput.origins).filter(([key, value]) => {
128
+ const result = key !== "imageOptimizer" && key !== "default" && key !== "s3";
129
+ return result;
130
+ });
131
+ const edgeFunctions = Object.entries(openNextOutput.edgeFunctions).reduce((acc, [key, value]) => {
132
+ return { ...acc, [key]: this.createEdgeOrigin(value, key, bucket) };
133
+ }, {});
117
134
  return this.validatePlan({
118
- edge: edge ?? false,
135
+ edge: false,
119
136
  cloudFrontFunctions: {
120
137
  serverCfFunction: {
121
138
  constructId: "CloudFrontFunction",
122
139
  injections: [
123
140
  this.useCloudFrontFunctionHostHeaderInjection(),
124
- this.useCloudFrontFunctionPrerenderBypassHeaderInjection(),
141
+ this.useCloudFrontFunctionCacheHeaderKey(),
142
+ this.useCloudfrontGeoHeadersInjection(),
125
143
  ],
126
144
  },
127
145
  },
128
- edgeFunctions: edge
129
- ? {
130
- edgeServer: {
131
- constructId: "ServerFunction",
132
- function: serverConfig,
133
- },
134
- }
135
- : undefined,
146
+ edgeFunctions,
136
147
  origins: {
137
- ...(edge
138
- ? {}
139
- : {
140
- regionalServer: {
141
- type: "function",
142
- constructId: "ServerFunction",
143
- function: serverConfig,
144
- streaming: experimental?.streaming,
145
- injections: this.isPerRouteLoggingEnabled()
146
- ? [this.useServerFunctionPerRouteLoggingInjection()]
147
- : [],
148
- },
149
- }),
148
+ s3: openNextOutput.origins.s3,
150
149
  imageOptimizer: {
151
150
  type: "image-optimization-function",
152
- constructId: "ImageFunction",
153
151
  function: {
154
- description: "Next.js image optimizer",
155
- handler: "index.handler",
156
- code: Code.fromAsset(path.join(sitePath, ".open-next/image-optimization-function")),
152
+ description: "Next.js Image Optimization Function",
153
+ handler: imageOpt.handler,
154
+ code: Code.fromAsset(path.join(sitePath, imageOpt.bundle)),
157
155
  runtime: Runtime.NODEJS_18_X,
158
156
  architecture: Architecture.ARM_64,
159
157
  environment: {
160
158
  BUCKET_NAME: bucket.bucketName,
161
159
  BUCKET_KEY_PREFIX: "_assets",
160
+ ...(this.props.imageOptimization?.staticImageOptimization
161
+ ? { OPENNEXT_STATIC_ETAG: "true" }
162
+ : {}),
162
163
  },
164
+ permissions: ["s3"],
163
165
  memorySize: imageOptimization?.memorySize
164
166
  ? typeof imageOptimization.memorySize === "string"
165
167
  ? toCdkSize(imageOptimization.memorySize).toMebibytes()
@@ -167,98 +169,55 @@ export class NextjsSite extends SsrSite {
167
169
  : 1536,
168
170
  },
169
171
  },
170
- s3: {
171
- type: "s3",
172
- originPath: "_assets",
173
- copy: [
174
- {
175
- from: ".open-next/assets",
176
- to: "_assets",
177
- cached: true,
178
- versionedSubDir: "_next",
179
- },
180
- { from: ".open-next/cache", to: "_cache", cached: false },
181
- ],
182
- },
172
+ default: defaultOrigin.type === "ecs"
173
+ ? this.createEcsOrigin(defaultOrigin, "default", bucket)
174
+ : this.createFunctionOrigin(defaultOrigin, "default", bucket),
175
+ ...Object.fromEntries(remainingOrigins.map(([key, value]) => [
176
+ key,
177
+ value.type === "ecs"
178
+ ? this.createEcsOrigin(value, key, bucket)
179
+ : this.createFunctionOrigin(value, key, bucket),
180
+ ])),
183
181
  },
184
- behaviors: [
185
- ...(edge
186
- ? [
187
- {
188
- cacheType: "server",
189
- cfFunction: "serverCfFunction",
190
- edgeFunction: "edgeServer",
191
- origin: "s3",
192
- },
193
- {
194
- cacheType: "server",
195
- pattern: this.prefixPattern("api/*"),
196
- cfFunction: "serverCfFunction",
197
- edgeFunction: "edgeServer",
198
- origin: "s3",
199
- },
200
- {
201
- cacheType: "server",
202
- pattern: this.prefixPattern("_next/data/*"),
203
- cfFunction: "serverCfFunction",
204
- edgeFunction: "edgeServer",
205
- origin: "s3",
206
- },
207
- ]
208
- : [
209
- {
210
- cacheType: "server",
211
- cfFunction: "serverCfFunction",
212
- origin: "regionalServer",
213
- },
214
- {
215
- cacheType: "server",
216
- pattern: this.prefixPattern("api/*"),
217
- cfFunction: "serverCfFunction",
218
- origin: "regionalServer",
219
- },
220
- {
221
- cacheType: "server",
222
- pattern: this.prefixPattern("_next/data/*"),
223
- cfFunction: "serverCfFunction",
224
- origin: "regionalServer",
225
- },
226
- ]),
227
- {
228
- cacheType: "server",
229
- pattern: this.prefixPattern("_next/image*"),
182
+ behaviors: openNextOutput.behaviors.map((behavior) => {
183
+ return {
184
+ pattern: behavior.pattern === "*" ? undefined : behavior.pattern,
185
+ origin: behavior.origin,
186
+ cacheType: behavior.origin === "s3" ? "static" : "server",
230
187
  cfFunction: "serverCfFunction",
231
- origin: "imageOptimizer",
232
- },
233
- // create 1 behaviour for each top level asset file/folder
234
- ...fs.readdirSync(path.join(sitePath, ".open-next/assets")).map((item) => ({
235
- cacheType: "static",
236
- pattern: this.prefixPattern(fs
237
- .statSync(path.join(sitePath, ".open-next/assets", item))
238
- .isDirectory()
239
- ? `${item}/*`
240
- : item),
241
- origin: "s3",
242
- })),
243
- ],
188
+ edgeFunction: behavior.edgeFunction ?? "",
189
+ };
190
+ }),
191
+ buildId: this.getBuildId(),
192
+ warmer: openNextOutput.additionalProps?.warmer
193
+ ? {
194
+ function: path.join(sitePath, openNextOutput.additionalProps.warmer.bundle),
195
+ }
196
+ : undefined,
244
197
  serverCachePolicy: {
245
- allowedHeaders: DEFAULT_CACHE_POLICY_ALLOWED_HEADERS,
198
+ allowedHeaders: ["x-open-next-cache-key"],
246
199
  },
247
- buildId: this.getBuildId(),
248
200
  });
249
201
  }
250
- prefixPattern(pattern) {
251
- // Prefix CloudFront distribution behavior path patterns with `basePath` if configured
252
- const { basePath } = this.useRoutesManifest();
253
- return basePath && basePath.length > 0
254
- ? `${basePath.slice(1)}/${pattern}`
255
- : pattern;
202
+ setMiddlewareEnv() {
203
+ const origins = this.serverFunctions.reduce((acc, server) => {
204
+ return {
205
+ ...acc,
206
+ [server.function
207
+ ? server.id.replace("ServerFunction", "")
208
+ : server.id.replace("ServerContainer", "")]: {
209
+ host: Fn.parseDomainName(server.url ?? ""),
210
+ port: 443,
211
+ protocol: "https",
212
+ },
213
+ };
214
+ }, {});
215
+ this.edgeFunctions?.middleware?.addEnvironment("OPEN_NEXT_ORIGIN", Fn.toJsonString(origins));
256
216
  }
257
217
  createRevalidationQueue() {
258
218
  if (!this.serverFunction)
259
219
  return;
260
220
  const { cdk } = this.props;
261
- const server = this.serverFunction;
262
221
  const queue = new Queue(this, "RevalidationQueue", {
263
222
  fifo: true,
264
223
  receiveMessageWaitTime: CdkDuration.seconds(20),
@@ -272,16 +231,17 @@ export class NextjsSite extends SsrSite {
272
231
  ...cdk?.revalidation,
273
232
  });
274
233
  consumer.addEventSource(new SqsEventSource(queue, { batchSize: 5 }));
275
- // Allow server to send messages to the queue
276
- server.addEnvironment("REVALIDATION_QUEUE_URL", queue.queueUrl);
277
- server.addEnvironment("REVALIDATION_QUEUE_REGION", Stack.of(this).region);
278
- queue.grantSendMessages(server.role);
234
+ this.serverFunctions.forEach((server) => {
235
+ // Allow server to send messages to the queue
236
+ server.addEnvironment("REVALIDATION_QUEUE_URL", queue.queueUrl);
237
+ server.addEnvironment("REVALIDATION_QUEUE_REGION", Stack.of(this).region);
238
+ queue.grantSendMessages(server.role);
239
+ });
279
240
  }
280
241
  createRevalidationTable() {
281
242
  if (!this.serverFunction)
282
243
  return;
283
244
  const { path: sitePath } = this.props;
284
- const server = this.serverFunction;
285
245
  const table = new Table(this, "RevalidationTable", {
286
246
  partitionKey: { name: "tag", type: AttributeType.STRING },
287
247
  sortKey: { name: "path", type: AttributeType.STRING },
@@ -296,8 +256,10 @@ export class NextjsSite extends SsrSite {
296
256
  ],
297
257
  removalPolicy: RemovalPolicy.DESTROY,
298
258
  });
299
- server?.addEnvironment("CACHE_DYNAMO_TABLE", table.tableName);
300
- table.grantReadWriteData(server.role);
259
+ this.serverFunctions.forEach((server) => {
260
+ server?.addEnvironment("CACHE_DYNAMO_TABLE", table.tableName);
261
+ table.grantReadWriteData(server.role);
262
+ });
301
263
  const dynamodbProviderPath = path.join(sitePath, ".open-next", "dynamodb-provider");
302
264
  if (fs.existsSync(dynamodbProviderPath)) {
303
265
  // Provision 128MB of memory for every 4,000 prerendered routes,
@@ -338,35 +300,11 @@ export class NextjsSite extends SsrSite {
338
300
  }
339
301
  }
340
302
  getConstructMetadata() {
341
- const metadata = this.getConstructMetadataBase();
342
303
  return {
343
- ...metadata,
344
304
  type: "NextjsSite",
345
- data: {
346
- ...metadata.data,
347
- routes: this.isPerRouteLoggingEnabled()
348
- ? {
349
- logGroupPrefix: `/sst/lambda/${this.serverFunction.functionName}`,
350
- data: this.useRoutes().map(({ route, logGroupPath }) => ({
351
- route,
352
- logGroupPath,
353
- })),
354
- }
355
- : undefined,
356
- },
305
+ ...this.getConstructMetadataBase(),
357
306
  };
358
307
  }
359
- removeSourcemaps() {
360
- const { path: sitePath } = this.props;
361
- const files = globSync("**/*.js.map", {
362
- cwd: path.join(sitePath, ".open-next", "server-function"),
363
- nodir: true,
364
- dot: true,
365
- });
366
- for (const file of files) {
367
- fs.rmSync(path.join(sitePath, ".open-next", "server-function", file));
368
- }
369
- }
370
308
  useRoutes() {
371
309
  if (this._routes)
372
310
  return this._routes;
@@ -510,38 +448,57 @@ export class NextjsSite extends SsrSite {
510
448
  Logger.debug("Failed to load prerender-manifest.json", e);
511
449
  }
512
450
  }
513
- useServerFunctionPerRouteLoggingInjection() {
451
+ // This function is used to improve cache hit ratio by setting the cache key based on the request headers and the path
452
+ // next/image only need the accept header, and this header is not useful for the rest of the query
453
+ useCloudFrontFunctionCacheHeaderKey() {
514
454
  return `
515
- if (event.rawPath) {
516
- const routeData = ${JSON.stringify(
517
- // @ts-expect-error
518
- this.useRoutes().map(({ regexMatch, prefixMatch, logGroupPath }) => ({
519
- regex: regexMatch,
520
- prefix: prefixMatch,
521
- logGroupPath,
522
- })))}.find(({ regex, prefix }) => {
523
- if (regex) return event.rawPath.match(new RegExp(regex));
524
- if (prefix) return event.rawPath === prefix || (event.rawPath === prefix + "/");
525
- return false;
526
- });
527
- if (routeData) {
528
- console.log("::sst::" + JSON.stringify({
529
- action:"log.split",
530
- properties: {
531
- logGroupName:"/sst/lambda/" + context.functionName + routeData.logGroupPath,
532
- },
533
- }));
455
+ function getHeader(key) {
456
+ var header = request.headers[key];
457
+ if(header) {
458
+ if(header.multiValue){
459
+ return header.multiValue.map((header) => header.value).join(",");
460
+ }
461
+ if(header.value){
462
+ return header.value;
463
+ }
464
+ }
465
+ return ""
466
+ }
467
+ var cacheKey = "";
468
+ if(request.uri.startsWith("/_next/image")) {
469
+ cacheKey = getHeader("accept");
470
+ }else {
471
+ cacheKey = getHeader("rsc") + getHeader("next-router-prefetch") + getHeader("next-router-state-tree") + getHeader("next-url") + getHeader("x-prerender-revalidate");
472
+ }
473
+ if(request.cookies["__prerender_bypass"]) {
474
+ cacheKey += request.cookies["__prerender_bypass"] ? request.cookies["__prerender_bypass"].value : "";
534
475
  }
535
- }`;
476
+ var crypto = require('crypto');
477
+
478
+ var hashedKey = crypto.createHash('md5').update(cacheKey).digest('hex');
479
+ request.headers["x-open-next-cache-key"] = {value: hashedKey};
480
+ `;
536
481
  }
537
- useCloudFrontFunctionPrerenderBypassHeaderInjection() {
538
- // In Next.js page router preview mode (depends on the cookie __prerender_bypass),
539
- // to ensure we receive the cached page instead of the preview version, we set the
540
- // header "x-prerender-bypass", and add it to cache policy's allowed headers.
482
+ // Inject the CloudFront viewer country, region, latitude, and longitude headers into the request headers
483
+ // for OpenNext to use them
484
+ useCloudfrontGeoHeadersInjection() {
541
485
  return `
542
- if (request.cookies["__prerender_bypass"]) {
543
- request.headers["x-prerender-bypass"] = { value: "true" };
544
- }`;
486
+ if(request.headers["cloudfront-viewer-city"]) {
487
+ request.headers["x-open-next-city"] = request.headers["cloudfront-viewer-city"];
488
+ }
489
+ if(request.headers["cloudfront-viewer-country"]) {
490
+ request.headers["x-open-next-country"] = request.headers["cloudfront-viewer-country"];
491
+ }
492
+ if(request.headers["cloudfront-viewer-region"]) {
493
+ request.headers["x-open-next-region"] = request.headers["cloudfront-viewer-region"];
494
+ }
495
+ if(request.headers["cloudfront-viewer-latitude"]) {
496
+ request.headers["x-open-next-latitude"] = request.headers["cloudfront-viewer-latitude"];
497
+ }
498
+ if(request.headers["cloudfront-viewer-longitude"]) {
499
+ request.headers["x-open-next-longitude"] = request.headers["cloudfront-viewer-longitude"];
500
+ }
501
+ `;
545
502
  }
546
503
  getBuildId() {
547
504
  const { path: sitePath } = this.props;
@@ -605,11 +562,6 @@ if (request.cookies["__prerender_bypass"]) {
605
562
  return;
606
563
  return sourcemapPath;
607
564
  }
608
- isPerRouteLoggingEnabled() {
609
- return (!this.doNotDeploy &&
610
- !this.props.edge &&
611
- this.props.logging === "per-route");
612
- }
613
565
  handleMissingSourcemap() {
614
566
  if (this.doNotDeploy || this.props.edge)
615
567
  return;
@@ -618,48 +570,6 @@ if (request.cookies["__prerender_bypass"]) {
618
570
  return;
619
571
  this.serverFunction._overrideMissingSourcemap();
620
572
  }
621
- disableDefaultLogging() {
622
- const stack = Stack.of(this);
623
- const server = this.serverFunction;
624
- const policy = new Policy(this, "DisableLoggingPolicy", {
625
- statements: [
626
- new PolicyStatement({
627
- effect: Effect.DENY,
628
- actions: [
629
- "logs:CreateLogGroup",
630
- "logs:CreateLogStream",
631
- "logs:PutLogEvents",
632
- ],
633
- resources: [
634
- `arn:aws:logs:${stack.region}:${stack.account}:log-group:/aws/lambda/${server.functionName}`,
635
- `arn:aws:logs:${stack.region}:${stack.account}:log-group:/aws/lambda/${server.functionName}:*`,
636
- ],
637
- }),
638
- ],
639
- });
640
- server.role?.attachInlinePolicy(policy);
641
- }
642
- uploadSourcemaps() {
643
- const stack = Stack.of(this);
644
- const server = this.serverFunction;
645
- this.useRoutes().forEach(({ sourcemapPath, sourcemapKey }) => {
646
- if (!sourcemapPath || !sourcemapKey)
647
- return;
648
- useDeferredTasks().add(async () => {
649
- // zip sourcemap
650
- const zipPath = `${sourcemapPath}.gz.zip`;
651
- const data = await fs.promises.readFile(sourcemapPath);
652
- await fs.promises.writeFile(zipPath, zlib.gzipSync(data));
653
- const asset = new Asset(this, `Sourcemap-${sourcemapKey}`, {
654
- path: zipPath,
655
- });
656
- useFunctions().sourcemaps.add(stack.stackName, {
657
- asset,
658
- tarKey: path.join(server.functionArn, sourcemapKey),
659
- });
660
- });
661
- });
662
- }
663
573
  static buildCloudWatchRouteName(route) {
664
574
  return route.replace(/[^a-zA-Z0-9_\-/.#]/g, "");
665
575
  }
@@ -90,6 +90,9 @@ export declare class RemixSite extends SsrSite {
90
90
  allowedHeaders?: string[] | undefined;
91
91
  } | undefined;
92
92
  buildId?: string | undefined;
93
+ warmer?: {
94
+ function: string;
95
+ } | undefined;
93
96
  };
94
97
  private hasViteConfig;
95
98
  private getServerModuleFormat;
@@ -72,6 +72,9 @@ export declare class SolidStartSite extends SsrSite {
72
72
  allowedHeaders?: string[] | undefined;
73
73
  } | undefined;
74
74
  buildId?: string | undefined;
75
+ warmer?: {
76
+ function: string;
77
+ } | undefined;
75
78
  };
76
79
  getConstructMetadata(): {
77
80
  data: {
@@ -1,7 +1,7 @@
1
1
  import { Construct } from "constructs";
2
2
  import { IGrantable } from "aws-cdk-lib/aws-iam";
3
3
  import { RetentionDays } from "aws-cdk-lib/aws-logs";
4
- import { FunctionOptions, Function as CdkFunction, FunctionUrlOptions } from "aws-cdk-lib/aws-lambda";
4
+ import { FunctionOptions, Function as CdkFunction, FunctionUrlOptions, FunctionUrl } from "aws-cdk-lib/aws-lambda";
5
5
  import { NodeJSProps, FunctionCopyFilesProps } from "./Function.js";
6
6
  import { SSTConstruct } from "./Construct.js";
7
7
  import { BindingResource } from "./util/binding.js";
@@ -29,6 +29,7 @@ export declare class SsrFunction extends Construct implements SSTConstruct {
29
29
  /** @internal */
30
30
  readonly _doNotAllowOthersToBind = true;
31
31
  function: CdkFunction;
32
+ private functionUrl?;
32
33
  private assetReplacer;
33
34
  private assetReplacerPolicy;
34
35
  private missingSourcemap?;
@@ -37,8 +38,9 @@ export declare class SsrFunction extends Construct implements SSTConstruct {
37
38
  get role(): import("aws-cdk-lib/aws-iam").IRole | undefined;
38
39
  get functionArn(): string;
39
40
  get functionName(): string;
41
+ get url(): string | undefined;
40
42
  addEnvironment(key: string, value: string): CdkFunction;
41
- addFunctionUrl(props?: FunctionUrlOptions): import("aws-cdk-lib/aws-lambda").FunctionUrl;
43
+ addFunctionUrl(props?: FunctionUrlOptions): FunctionUrl;
42
44
  grantInvoke(grantee: IGrantable): import("aws-cdk-lib/aws-iam").Grant;
43
45
  attachPermissions(permissions: Permissions): void;
44
46
  _overrideMissingSourcemap(): void;