sst 2.40.3 → 2.40.5

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.
Files changed (69) hide show
  1. package/cli/commands/bind.js +1 -1
  2. package/cli/commands/secrets/list.js +1 -1
  3. package/constructs/Api.d.ts +4 -4
  4. package/constructs/Api.js +1 -1
  5. package/constructs/ApiGatewayV1Api.d.ts +4 -4
  6. package/constructs/ApiGatewayV1Api.js +1 -1
  7. package/constructs/App.d.ts +2 -1
  8. package/constructs/App.js +7 -11
  9. package/constructs/AppSyncApi.d.ts +4 -4
  10. package/constructs/AppSyncApi.js +1 -1
  11. package/constructs/Auth.d.ts +2 -2
  12. package/constructs/Auth.js +3 -3
  13. package/constructs/Bucket.d.ts +5 -5
  14. package/constructs/Bucket.js +1 -1
  15. package/constructs/Cognito.d.ts +4 -3
  16. package/constructs/Cognito.js +1 -1
  17. package/constructs/Construct.d.ts +2 -2
  18. package/constructs/Cron.d.ts +3 -2
  19. package/constructs/Cron.js +1 -1
  20. package/constructs/EdgeFunction.d.ts +2 -2
  21. package/constructs/EdgeFunction.js +6 -9
  22. package/constructs/EventBus.d.ts +4 -4
  23. package/constructs/EventBus.js +1 -1
  24. package/constructs/Function.d.ts +42 -6
  25. package/constructs/Function.js +19 -14
  26. package/constructs/Job.d.ts +43 -4
  27. package/constructs/Job.js +11 -14
  28. package/constructs/KinesisStream.d.ts +4 -4
  29. package/constructs/KinesisStream.js +1 -1
  30. package/constructs/NextjsSite.d.ts +2 -0
  31. package/constructs/NextjsSite.js +29 -9
  32. package/constructs/Parameter.d.ts +2 -2
  33. package/constructs/Parameter.js +1 -1
  34. package/constructs/Queue.d.ts +3 -3
  35. package/constructs/Queue.js +1 -1
  36. package/constructs/RDS.d.ts +2 -2
  37. package/constructs/RDS.js +1 -1
  38. package/constructs/RemixSite.d.ts +3 -2
  39. package/constructs/RemixSite.js +38 -12
  40. package/constructs/Script.d.ts +3 -2
  41. package/constructs/Script.js +2 -2
  42. package/constructs/Secret.d.ts +2 -2
  43. package/constructs/Secret.js +2 -2
  44. package/constructs/Service.d.ts +43 -4
  45. package/constructs/Service.js +31 -15
  46. package/constructs/SsrFunction.d.ts +3 -2
  47. package/constructs/SsrFunction.js +7 -13
  48. package/constructs/SsrSite.d.ts +3 -3
  49. package/constructs/SsrSite.js +2 -2
  50. package/constructs/Stack.d.ts +2 -2
  51. package/constructs/StaticSite.d.ts +2 -2
  52. package/constructs/StaticSite.js +2 -2
  53. package/constructs/Table.d.ts +4 -4
  54. package/constructs/Table.js +1 -1
  55. package/constructs/Topic.d.ts +4 -4
  56. package/constructs/Topic.js +1 -1
  57. package/constructs/WebSocketApi.d.ts +4 -4
  58. package/constructs/WebSocketApi.js +1 -1
  59. package/constructs/deprecated/NextjsSite.d.ts +2 -2
  60. package/constructs/deprecated/NextjsSite.js +2 -2
  61. package/constructs/future/Auth.d.ts +2 -2
  62. package/constructs/future/Auth.js +2 -2
  63. package/constructs/util/{functionBinding.d.ts → binding.d.ts} +14 -6
  64. package/constructs/util/{functionBinding.js → binding.js} +28 -14
  65. package/package.json +2 -2
  66. package/runtime/handlers/container.js +42 -0
  67. package/runtime/handlers/rust.js +3 -2
  68. package/support/remix-site-function/edge-server.js +0 -8
  69. package/support/remix-site-function/regional-server.js +0 -8
@@ -6,9 +6,10 @@ import zlib from "zlib";
6
6
  import { Stack } from "./Stack.js";
7
7
  import { Job } from "./Job.js";
8
8
  import { Secret } from "./Config.js";
9
+ import { isSSTConstruct } from "./Construct.js";
9
10
  import { toCdkSize } from "./util/size.js";
10
11
  import { toCdkDuration } from "./util/duration.js";
11
- import { bindEnvironment, bindPermissions, getReferencedSecrets, } from "./util/functionBinding.js";
12
+ import { getBindingEnvironments, getBindingPermissions, getBindingReferencedSecrets, } from "./util/binding.js";
12
13
  import { attachPermissionsToRole } from "./util/permission.js";
13
14
  import * as functionUrlCors from "./util/functionUrlCors.js";
14
15
  import url from "url";
@@ -251,6 +252,15 @@ export class Function extends CDKFunction {
251
252
  ...(props.container?.buildArgs
252
253
  ? { buildArgs: props.container.buildArgs }
253
254
  : {}),
255
+ ...(props.container?.buildSsh
256
+ ? { buildSsh: props.container.buildSsh }
257
+ : {}),
258
+ ...(props.container?.cacheFrom
259
+ ? { cacheFrom: props.container.cacheFrom }
260
+ : {}),
261
+ ...(props.container?.cacheTo
262
+ ? { cacheTo: props.container.cacheTo }
263
+ : {}),
254
264
  exclude: [".sst/dist", ".sst/artifacts"],
255
265
  ignoreMode: IgnoreMode.GLOB,
256
266
  });
@@ -341,20 +351,14 @@ export class Function extends CDKFunction {
341
351
  bind(constructs) {
342
352
  // Get referenced secrets
343
353
  const referencedSecrets = [];
344
- constructs.forEach((c) => referencedSecrets.push(...getReferencedSecrets(c)));
345
- [...constructs, ...referencedSecrets].forEach((c) => {
354
+ constructs.forEach((r) => referencedSecrets.push(...getBindingReferencedSecrets(r)));
355
+ [...constructs, ...referencedSecrets].forEach((r) => {
346
356
  // Bind environment
347
- const env = bindEnvironment(c);
357
+ const env = getBindingEnvironments(r);
348
358
  Object.entries(env).forEach(([key, value]) => this.addEnvironment(key, value));
349
359
  // Bind permissions
350
- const permissions = bindPermissions(c);
351
- Object.entries(permissions).forEach(([action, resources]) => this.attachPermissions([
352
- new PolicyStatement({
353
- actions: [action],
354
- effect: Effect.ALLOW,
355
- resources,
356
- }),
357
- ]));
360
+ const policyStatements = getBindingPermissions(r);
361
+ this.attachPermissions(policyStatements);
358
362
  });
359
363
  this.allBindings.push(...constructs, ...referencedSecrets);
360
364
  }
@@ -389,14 +393,15 @@ export class Function extends CDKFunction {
389
393
  missingSourcemap: this.missingSourcemap === true ? true : undefined,
390
394
  localId: this.node.addr,
391
395
  secrets: this.allBindings
392
- .filter((c) => c instanceof Secret)
396
+ .map((r) => (isSSTConstruct(r) ? r : r.resource))
397
+ .filter((r) => r instanceof Secret)
393
398
  .map((c) => c.name),
394
399
  prefetchSecrets: this.props.prefetchSecrets,
395
400
  },
396
401
  };
397
402
  }
398
403
  /** @internal */
399
- getFunctionBinding() {
404
+ getBindings() {
400
405
  return {
401
406
  clientPackage: "function",
402
407
  variables: {
@@ -1,4 +1,5 @@
1
1
  import { Construct } from "constructs";
2
+ import { DockerCacheOption } from "aws-cdk-lib/core";
2
3
  import { Function as CdkFunction } from "aws-cdk-lib/aws-lambda";
3
4
  import { Project } from "aws-cdk-lib/aws-codebuild";
4
5
  import { RetentionDays } from "aws-cdk-lib/aws-logs";
@@ -6,11 +7,13 @@ import { SSTConstruct } from "./Construct.js";
6
7
  import { NodeJSProps, FunctionCopyFilesProps } from "./Function.js";
7
8
  import { Duration } from "./util/duration.js";
8
9
  import { Permissions } from "./util/permission.js";
9
- import { FunctionBindingProps } from "./util/functionBinding.js";
10
+ import { BindingResource, BindingProps } from "./util/binding.js";
10
11
  import { ISecurityGroup, IVpc, SubnetSelection } from "aws-cdk-lib/aws-ec2";
11
12
  export type JobMemorySize = "3 GB" | "7 GB" | "15 GB" | "145 GB";
12
13
  export interface JobNodeJSProps extends NodeJSProps {
13
14
  }
15
+ export interface JobContainerCacheProps extends DockerCacheOption {
16
+ }
14
17
  export interface JobContainerProps {
15
18
  /**
16
19
  * Specify or override the CMD on the Docker image.
@@ -45,6 +48,42 @@ export interface JobContainerProps {
45
48
  * ```
46
49
  */
47
50
  buildArgs?: Record<string, string>;
51
+ /**
52
+ * SSH agent socket or keys to pass to the docker build command.
53
+ * Docker BuildKit must be enabled to use the ssh flag
54
+ * @default No --ssh flag is passed to the build command
55
+ * @example
56
+ * ```js
57
+ * container: {
58
+ * buildSsh: "default"
59
+ * }
60
+ * ```
61
+ */
62
+ buildSsh?: string;
63
+ /**
64
+ * Cache from options to pass to the docker build command.
65
+ * [DockerCacheOption](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr_assets.DockerCacheOption.html)[].
66
+ * @default No cache from options are passed to the build command
67
+ * @example
68
+ * ```js
69
+ * container: {
70
+ * cacheFrom: [{ type: 'registry', params: { ref: 'ghcr.io/myorg/myimage:cache' }}],
71
+ * }
72
+ * ```
73
+ */
74
+ cacheFrom?: JobContainerCacheProps[];
75
+ /**
76
+ * Cache to options to pass to the docker build command.
77
+ * [DockerCacheOption](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr_assets.DockerCacheOption.html)[].
78
+ * @default No cache to options are passed to the build command
79
+ * @example
80
+ * ```js
81
+ * container: {
82
+ * cacheTo: { type: 'registry', params: { ref: 'ghcr.io/myorg/myimage:cache', mode: 'max', compression: 'zstd' }},
83
+ * }
84
+ * ```
85
+ */
86
+ cacheTo?: JobContainerCacheProps;
48
87
  }
49
88
  export interface JobProps {
50
89
  /**
@@ -180,7 +219,7 @@ export interface JobProps {
180
219
  * })
181
220
  * ```
182
221
  */
183
- bind?: SSTConstruct[];
222
+ bind?: BindingResource[];
184
223
  /**
185
224
  * Attaches the given list of permissions to the job. Configuring this property is equivalent to calling `attachPermissions()` after the job is created.
186
225
  *
@@ -292,7 +331,7 @@ export declare class Job extends Construct implements SSTConstruct {
292
331
  };
293
332
  };
294
333
  /** @internal */
295
- getFunctionBinding(): FunctionBindingProps;
334
+ getBindings(): BindingProps;
296
335
  /**
297
336
  * Binds additional resources to job.
298
337
  *
@@ -301,7 +340,7 @@ export declare class Job extends Construct implements SSTConstruct {
301
340
  * job.bind([STRIPE_KEY, bucket]);
302
341
  * ```
303
342
  */
304
- bind(constructs: SSTConstruct[]): void;
343
+ bind(constructs: BindingResource[]): void;
305
344
  /**
306
345
  * Attaches the given list of [permissions](Permissions.md) to the job. This allows the job to access other AWS resources.
307
346
  *
package/constructs/Job.js CHANGED
@@ -2,7 +2,7 @@ import url from "url";
2
2
  import path from "path";
3
3
  import fs from "fs/promises";
4
4
  import { Construct } from "constructs";
5
- import { Duration as CdkDuration, IgnoreMode } from "aws-cdk-lib/core";
5
+ import { Duration as CdkDuration, IgnoreMode, } from "aws-cdk-lib/core";
6
6
  import { Platform } from "aws-cdk-lib/aws-ecr-assets";
7
7
  import { PolicyStatement, Effect } from "aws-cdk-lib/aws-iam";
8
8
  import { AssetCode, Code, Runtime, Function as CdkFunction, } from "aws-cdk-lib/aws-lambda";
@@ -12,7 +12,7 @@ import { Stack } from "./Stack.js";
12
12
  import { Function, useFunctions, } from "./Function.js";
13
13
  import { toCdkDuration } from "./util/duration.js";
14
14
  import { attachPermissionsToRole } from "./util/permission.js";
15
- import { bindEnvironment, bindPermissions, getReferencedSecrets, } from "./util/functionBinding.js";
15
+ import { getBindingEnvironments, getBindingPermissions, getBindingReferencedSecrets, } from "./util/binding.js";
16
16
  import { useDeferredTasks } from "./deferred_task.js";
17
17
  import { useProject } from "../project.js";
18
18
  import { useRuntimeHandlers } from "../runtime/handlers.js";
@@ -83,7 +83,7 @@ export class Job extends Construct {
83
83
  };
84
84
  }
85
85
  /** @internal */
86
- getFunctionBinding() {
86
+ getBindings() {
87
87
  return {
88
88
  clientPackage: "job",
89
89
  variables: {
@@ -219,6 +219,9 @@ export class Job extends Construct {
219
219
  : Platform.custom("linux/amd64"),
220
220
  file: container?.file,
221
221
  buildArgs: container?.buildArgs,
222
+ buildSsh: container?.buildSsh,
223
+ cacheFrom: container?.cacheFrom,
224
+ cacheTo: container?.cacheTo,
222
225
  exclude: [".sst/dist", ".sst/artifacts"],
223
226
  ignoreMode: IgnoreMode.GLOB,
224
227
  });
@@ -351,20 +354,14 @@ export class Job extends Construct {
351
354
  bindForCodeBuild(constructs) {
352
355
  // Get referenced secrets
353
356
  const referencedSecrets = [];
354
- constructs.forEach((c) => referencedSecrets.push(...getReferencedSecrets(c)));
355
- [...constructs, ...referencedSecrets].forEach((c) => {
357
+ constructs.forEach((r) => referencedSecrets.push(...getBindingReferencedSecrets(r)));
358
+ [...constructs, ...referencedSecrets].forEach((r) => {
356
359
  // Bind environment
357
- const env = bindEnvironment(c);
360
+ const env = getBindingEnvironments(r);
358
361
  Object.entries(env).forEach(([key, value]) => this.addEnvironmentForCodeBuild(key, value));
359
362
  // Bind permissions
360
- const permissions = bindPermissions(c);
361
- Object.entries(permissions).forEach(([action, resources]) => this.attachPermissionsForCodeBuild([
362
- new PolicyStatement({
363
- actions: [action],
364
- effect: Effect.ALLOW,
365
- resources,
366
- }),
367
- ]));
363
+ const policyStatements = getBindingPermissions(r);
364
+ this.attachPermissionsForCodeBuild(policyStatements);
368
365
  });
369
366
  }
370
367
  attachPermissionsForCodeBuild(permissions) {
@@ -3,7 +3,7 @@ import * as kinesis from "aws-cdk-lib/aws-kinesis";
3
3
  import * as lambdaEventSources from "aws-cdk-lib/aws-lambda-event-sources";
4
4
  import { SSTConstruct } from "./Construct.js";
5
5
  import { Function as Fn, FunctionProps, FunctionInlineDefinition, FunctionDefinition } from "./Function.js";
6
- import { FunctionBindingProps } from "./util/functionBinding.js";
6
+ import { BindingResource, BindingProps } from "./util/binding.js";
7
7
  import { Permissions } from "./util/permission.js";
8
8
  /**
9
9
  * Used to define the function consumer for the stream
@@ -166,7 +166,7 @@ export declare class KinesisStream extends Construct implements SSTConstruct {
166
166
  * stream.bind([STRIPE_KEY, bucket]]);
167
167
  * ```
168
168
  */
169
- bind(constructs: SSTConstruct[]): void;
169
+ bind(constructs: BindingResource[]): void;
170
170
  /**
171
171
  * Binds the given list of resources to a specific consumer.
172
172
  *
@@ -175,7 +175,7 @@ export declare class KinesisStream extends Construct implements SSTConstruct {
175
175
  * stream.bindToConsumer("consumer1", [STRIPE_KEY, bucket]);
176
176
  * ```
177
177
  */
178
- bindToConsumer(consumerName: string, constructs: SSTConstruct[]): void;
178
+ bindToConsumer(consumerName: string, constructs: BindingResource[]): void;
179
179
  /**
180
180
  * Attaches the given list of permissions to all the consumers. This allows the functions to access other AWS resources.
181
181
  *
@@ -218,7 +218,7 @@ export declare class KinesisStream extends Construct implements SSTConstruct {
218
218
  };
219
219
  };
220
220
  /** @internal */
221
- getFunctionBinding(): FunctionBindingProps;
221
+ getBindings(): BindingProps;
222
222
  private createStream;
223
223
  private addConsumer;
224
224
  }
@@ -149,7 +149,7 @@ export class KinesisStream extends Construct {
149
149
  };
150
150
  }
151
151
  /** @internal */
152
- getFunctionBinding() {
152
+ getBindings() {
153
153
  return {
154
154
  clientPackage: "kinesis-stream",
155
155
  variables: {
@@ -235,6 +235,7 @@ export declare class NextjsSite extends SsrSite {
235
235
  } | undefined;
236
236
  buildId?: string | undefined;
237
237
  };
238
+ private prefixPattern;
238
239
  private createRevalidationQueue;
239
240
  private createRevalidationTable;
240
241
  getConstructMetadata(): {
@@ -266,6 +267,7 @@ export declare class NextjsSite extends SsrSite {
266
267
  private usePagesManifest;
267
268
  private usePrerenderManifest;
268
269
  private useServerFunctionPerRouteLoggingInjection;
270
+ private useCloudFrontFunctionPrerenderBypassHeaderInjection;
269
271
  private getBuildId;
270
272
  private getSourcemapForAppRoute;
271
273
  private getSourcemapForPagesRoute;
@@ -20,13 +20,14 @@ import { useFunctions } from "./Function.js";
20
20
  import { useDeferredTasks } from "./deferred_task.js";
21
21
  import { Logger } from "../logger.js";
22
22
  const LAYER_VERSION = "2";
23
- const DEFAULT_OPEN_NEXT_VERSION = "2.3.1";
23
+ const DEFAULT_OPEN_NEXT_VERSION = "2.3.5";
24
24
  const DEFAULT_CACHE_POLICY_ALLOWED_HEADERS = [
25
25
  "accept",
26
26
  "rsc",
27
27
  "next-router-prefetch",
28
28
  "next-router-state-tree",
29
29
  "next-url",
30
+ "x-prerender-bypass",
30
31
  ];
31
32
  /**
32
33
  * The `NextjsSite` construct is a higher level CDK construct that makes it easy to create a Next.js app.
@@ -117,7 +118,10 @@ export class NextjsSite extends SsrSite {
117
118
  cloudFrontFunctions: {
118
119
  serverCfFunction: {
119
120
  constructId: "CloudFrontFunction",
120
- injections: [this.useCloudFrontFunctionHostHeaderInjection()],
121
+ injections: [
122
+ this.useCloudFrontFunctionHostHeaderInjection(),
123
+ this.useCloudFrontFunctionPrerenderBypassHeaderInjection(),
124
+ ],
121
125
  },
122
126
  },
123
127
  edgeFunctions: edge
@@ -187,14 +191,14 @@ export class NextjsSite extends SsrSite {
187
191
  },
188
192
  {
189
193
  cacheType: "server",
190
- pattern: "api/*",
194
+ pattern: this.prefixPattern("api/*"),
191
195
  cfFunction: "serverCfFunction",
192
196
  edgeFunction: "edgeServer",
193
197
  origin: "s3",
194
198
  },
195
199
  {
196
200
  cacheType: "server",
197
- pattern: "_next/data/*",
201
+ pattern: this.prefixPattern("_next/data/*"),
198
202
  cfFunction: "serverCfFunction",
199
203
  edgeFunction: "edgeServer",
200
204
  origin: "s3",
@@ -208,31 +212,31 @@ export class NextjsSite extends SsrSite {
208
212
  },
209
213
  {
210
214
  cacheType: "server",
211
- pattern: "api/*",
215
+ pattern: this.prefixPattern("api/*"),
212
216
  cfFunction: "serverCfFunction",
213
217
  origin: "regionalServer",
214
218
  },
215
219
  {
216
220
  cacheType: "server",
217
- pattern: "_next/data/*",
221
+ pattern: this.prefixPattern("_next/data/*"),
218
222
  cfFunction: "serverCfFunction",
219
223
  origin: "regionalServer",
220
224
  },
221
225
  ]),
222
226
  {
223
227
  cacheType: "server",
224
- pattern: "_next/image*",
228
+ pattern: this.prefixPattern("_next/image*"),
225
229
  cfFunction: "serverCfFunction",
226
230
  origin: "imageOptimizer",
227
231
  },
228
232
  // create 1 behaviour for each top level asset file/folder
229
233
  ...fs.readdirSync(path.join(sitePath, ".open-next/assets")).map((item) => ({
230
234
  cacheType: "static",
231
- pattern: fs
235
+ pattern: this.prefixPattern(fs
232
236
  .statSync(path.join(sitePath, ".open-next/assets", item))
233
237
  .isDirectory()
234
238
  ? `${item}/*`
235
- : item,
239
+ : item),
236
240
  origin: "s3",
237
241
  })),
238
242
  ],
@@ -242,6 +246,13 @@ export class NextjsSite extends SsrSite {
242
246
  buildId: this.getBuildId(),
243
247
  });
244
248
  }
249
+ prefixPattern(pattern) {
250
+ // Prefix CloudFront distribution behavior path patterns with `basePath` if configured
251
+ const { basePath } = this.useRoutesManifest();
252
+ return basePath && basePath.length > 0
253
+ ? `${basePath.slice(1)}/${pattern}`
254
+ : pattern;
255
+ }
245
256
  createRevalidationQueue() {
246
257
  if (!this.serverFunction)
247
258
  return;
@@ -520,6 +531,15 @@ if (event.rawPath) {
520
531
  },
521
532
  }));
522
533
  }
534
+ }`;
535
+ }
536
+ useCloudFrontFunctionPrerenderBypassHeaderInjection() {
537
+ // In Next.js page router preview mode (depends on the cookie __prerender_bypass),
538
+ // to ensure we receive the cached page instead of the preview version, we set the
539
+ // header "x-prerender-bypass", and add it to cache policy's allowed headers.
540
+ return `
541
+ if (request.cookies["__prerender_bypass"]) {
542
+ request.headers["x-prerender-bypass"] = { value: "true" };
523
543
  }`;
524
544
  }
525
545
  getBuildId() {
@@ -1,6 +1,6 @@
1
1
  import { Construct } from "constructs";
2
2
  import { SSTConstruct } from "./Construct.js";
3
- import { FunctionBindingProps } from "./util/functionBinding.js";
3
+ import { BindingProps } from "./util/binding.js";
4
4
  export interface ParameterProps {
5
5
  /**
6
6
  * Value of the parameter
@@ -32,6 +32,6 @@ export declare class Parameter extends Construct implements SSTConstruct {
32
32
  };
33
33
  };
34
34
  /** @internal */
35
- getFunctionBinding(): FunctionBindingProps;
35
+ getBindings(): BindingProps;
36
36
  static create<T extends Record<string, any>>(scope: Construct, parameters: T): { [key in keyof T]: Parameter; };
37
37
  }
@@ -33,7 +33,7 @@ export class Parameter extends Construct {
33
33
  };
34
34
  }
35
35
  /** @internal */
36
- getFunctionBinding() {
36
+ getBindings() {
37
37
  return {
38
38
  clientPackage: "config",
39
39
  variables: {
@@ -4,7 +4,7 @@ import * as lambda from "aws-cdk-lib/aws-lambda";
4
4
  import * as lambdaEventSources from "aws-cdk-lib/aws-lambda-event-sources";
5
5
  import { SSTConstruct } from "./Construct.js";
6
6
  import { Function as Fn, FunctionInlineDefinition, FunctionDefinition } from "./Function.js";
7
- import { FunctionBindingProps } from "./util/functionBinding.js";
7
+ import { BindingResource, BindingProps } from "./util/binding.js";
8
8
  import { Permissions } from "./util/permission.js";
9
9
  /**
10
10
  * Used to define the consumer for the queue and invocation details
@@ -164,7 +164,7 @@ export declare class Queue extends Construct implements SSTConstruct {
164
164
  * queue.bind([STRIPE_KEY, bucket]);
165
165
  * ```
166
166
  */
167
- bind(constructs: SSTConstruct[]): void;
167
+ bind(constructs: BindingResource[]): void;
168
168
  /**
169
169
  * Attaches additional permissions to the consumer function
170
170
  *
@@ -189,6 +189,6 @@ export declare class Queue extends Construct implements SSTConstruct {
189
189
  };
190
190
  };
191
191
  /** @internal */
192
- getFunctionBinding(): FunctionBindingProps;
192
+ getBindings(): BindingProps;
193
193
  private createQueue;
194
194
  }
@@ -158,7 +158,7 @@ export class Queue extends Construct {
158
158
  };
159
159
  }
160
160
  /** @internal */
161
- getFunctionBinding() {
161
+ getBindings() {
162
162
  return {
163
163
  clientPackage: "queue",
164
164
  variables: {
@@ -4,7 +4,7 @@ import { AuroraCapacityUnit, Endpoint, IServerlessCluster, ServerlessCluster, Se
4
4
  import { ISecret } from "aws-cdk-lib/aws-secretsmanager";
5
5
  import { SSTConstruct } from "./Construct.js";
6
6
  import { Function as Fn } from "./Function.js";
7
- import { FunctionBindingProps } from "./util/functionBinding.js";
7
+ import { BindingProps } from "./util/binding.js";
8
8
  export interface RDSTypes {
9
9
  path: string;
10
10
  camelCase?: boolean;
@@ -204,7 +204,7 @@ export declare class RDS extends Construct implements SSTConstruct {
204
204
  };
205
205
  };
206
206
  /** @internal */
207
- getFunctionBinding(): FunctionBindingProps;
207
+ getBindings(): BindingProps;
208
208
  private validateRequiredProps;
209
209
  private validateCDKPropWhenIsConstruct;
210
210
  private validateCDKPropWhenIsClusterProps;
package/constructs/RDS.js CHANGED
@@ -116,7 +116,7 @@ export class RDS extends Construct {
116
116
  };
117
117
  }
118
118
  /** @internal */
119
- getFunctionBinding() {
119
+ getBindings() {
120
120
  return {
121
121
  clientPackage: "rds",
122
122
  variables: {
@@ -58,7 +58,7 @@ export declare class RemixSite extends SsrSite {
58
58
  from: string;
59
59
  to: string;
60
60
  cached: true;
61
- versionedSubDir: string;
61
+ versionedSubDir: string | undefined;
62
62
  }[];
63
63
  };
64
64
  regionalServer?: {
@@ -91,7 +91,8 @@ export declare class RemixSite extends SsrSite {
91
91
  } | undefined;
92
92
  buildId?: string | undefined;
93
93
  };
94
- protected getServerModuleFormat(): "cjs" | "esm";
94
+ private hasViteConfig;
95
+ private getServerModuleFormat;
95
96
  private createServerLambdaBundle;
96
97
  getConstructMetadata(): {
97
98
  data: {
@@ -26,8 +26,9 @@ export class RemixSite extends SsrSite {
26
26
  }
27
27
  plan() {
28
28
  const { path: sitePath, edge } = this.props;
29
- const { handler, inject } = this.createServerLambdaBundle(edge ? "edge-server.js" : "regional-server.js");
30
- const format = this.getServerModuleFormat();
29
+ const isUsingVite = this.hasViteConfig();
30
+ const format = this.getServerModuleFormat(isUsingVite);
31
+ const { handler, inject } = this.createServerLambdaBundle(isUsingVite, edge ? "edge-server.js" : "regional-server.js");
31
32
  const serverConfig = {
32
33
  description: "Server handler for Remix",
33
34
  handler,
@@ -38,6 +39,11 @@ export class RemixSite extends SsrSite {
38
39
  },
39
40
  },
40
41
  };
42
+ // The path for all files that need to be in the "/" directory (static assets)
43
+ // is different when using Vite. These will be located in the "build/client"
44
+ // path of the output. It will be the "public" folder when using remix config.
45
+ const assetsPath = isUsingVite ? path.join("build", "client") : "public";
46
+ const assetsVersionedSubDir = isUsingVite ? undefined : "build";
41
47
  return this.validatePlan({
42
48
  edge: edge ?? false,
43
49
  cloudFrontFunctions: {
@@ -79,10 +85,10 @@ export class RemixSite extends SsrSite {
79
85
  type: "s3",
80
86
  copy: [
81
87
  {
82
- from: "public",
88
+ from: assetsPath,
83
89
  to: "",
84
90
  cached: true,
85
- versionedSubDir: "build",
91
+ versionedSubDir: assetsVersionedSubDir,
86
92
  },
87
93
  ],
88
94
  },
@@ -101,10 +107,10 @@ export class RemixSite extends SsrSite {
101
107
  origin: "regionalServer",
102
108
  },
103
109
  // create 1 behaviour for each top level asset file/folder
104
- ...fs.readdirSync(path.join(sitePath, "public")).map((item) => ({
110
+ ...fs.readdirSync(path.join(sitePath, assetsPath)).map((item) => ({
105
111
  cacheType: "static",
106
112
  pattern: fs
107
- .statSync(path.join(sitePath, "public", item))
113
+ .statSync(path.join(sitePath, assetsPath, item))
108
114
  .isDirectory()
109
115
  ? `${item}/*`
110
116
  : item,
@@ -114,8 +120,17 @@ export class RemixSite extends SsrSite {
114
120
  ],
115
121
  });
116
122
  }
117
- getServerModuleFormat() {
123
+ hasViteConfig() {
118
124
  const { path: sitePath } = this.props;
125
+ return (fs.existsSync(path.resolve(sitePath, "vite.config.ts")) ||
126
+ fs.existsSync(path.resolve(sitePath, "vite.config.js")));
127
+ }
128
+ getServerModuleFormat(isUsingVite) {
129
+ const { path: sitePath } = this.props;
130
+ // Remix has two possible config formats: "remix.config.js" or "vite.config.ts/js".
131
+ // If using the vite format, we can short circuit the logic and just return ESM.
132
+ if (isUsingVite)
133
+ return "esm";
119
134
  // Validate config path
120
135
  const configPath = path.resolve(sitePath, "remix.config.js");
121
136
  if (!fs.existsSync(configPath)) {
@@ -158,7 +173,7 @@ export class RemixSite extends SsrSite {
158
173
  });
159
174
  return format;
160
175
  }
161
- createServerLambdaBundle(wrapperFile) {
176
+ createServerLambdaBundle(isUsingVite, wrapperFile) {
162
177
  // Create a Lambda@Edge handler for the Remix server bundle.
163
178
  //
164
179
  // Note: Remix does perform their own internal ESBuild process, but it
@@ -178,13 +193,24 @@ export class RemixSite extends SsrSite {
178
193
  // Ensure build directory exists
179
194
  const buildPath = path.join(this.props.path, "build");
180
195
  fs.mkdirSync(buildPath, { recursive: true });
181
- // Copy the server lambda handler
182
- fs.copyFileSync(path.resolve(__dirname, `../support/remix-site-function/${wrapperFile}`), path.join(buildPath, "server.js"));
196
+ // Copy the server lambda handler and pre-append the build injection based
197
+ // on the config file used.
198
+ const content = [
199
+ // When using Vite config, the output build will be "server/index.js"
200
+ // and when using Remix config it will be `server.js`.
201
+ `// Import the server build that was produced by 'remix build'`,
202
+ isUsingVite
203
+ ? `import * as remixServerBuild from "./server/index.js";`
204
+ : `import * as remixServerBuild from "./index.js";`,
205
+ ``,
206
+ fs.readFileSync(path.resolve(__dirname, `../support/remix-site-function/${wrapperFile}`), { encoding: "utf8" }),
207
+ ].join("\n");
208
+ fs.writeFileSync(path.resolve(buildPath, "server.js"), content);
183
209
  // Copy the Remix polyfil to the server build directory
184
210
  //
185
211
  // Note: We need to ensure that the polyfills are injected above other code that
186
- // will depend on them. Importing them within the top of the lambda code
187
- // doesn't appear to guarantee this, we therefore leverage ESBUild's
212
+ // will depend on them when not using Vite. Importing them within the top of the
213
+ // lambda code doesn't appear to guarantee this, we therefore leverage ESBUild's
188
214
  // `inject` option to ensure that the polyfills are injected at the top of
189
215
  // the bundle.
190
216
  const polyfillDest = path.join(buildPath, "polyfill.js");
@@ -2,6 +2,7 @@ import { Construct } from "constructs";
2
2
  import { Function as Fn, FunctionProps, FunctionDefinition } from "./Function.js";
3
3
  import { SSTConstruct } from "./Construct.js";
4
4
  import { Permissions } from "./util/permission.js";
5
+ import { BindingResource } from "./util/binding.js";
5
6
  export interface ScriptProps {
6
7
  /**
7
8
  * An object of input parameters to be passed to the script. Made available in the `event` object of the function.
@@ -123,7 +124,7 @@ export declare class Script extends Construct implements SSTConstruct {
123
124
  * script.bind([STRIPE_KEY, bucket]);
124
125
  * ```
125
126
  */
126
- bind(constructs: SSTConstruct[]): void;
127
+ bind(constructs: BindingResource[]): void;
127
128
  /**
128
129
  * Grants additional permissions to the script
129
130
  *
@@ -156,5 +157,5 @@ export declare class Script extends Construct implements SSTConstruct {
156
157
  };
157
158
  };
158
159
  /** @internal */
159
- getFunctionBinding(): undefined;
160
+ getBindings(): undefined;
160
161
  }
@@ -6,7 +6,7 @@ import { PolicyStatement } from "aws-cdk-lib/aws-iam";
6
6
  import { Code, Runtime, Function as CdkFunction } from "aws-cdk-lib/aws-lambda";
7
7
  import { Stack } from "./Stack.js";
8
8
  import { Function as Fn, } from "./Function.js";
9
- import { getFunctionRef, } from "./Construct.js";
9
+ import { getFunctionRef } from "./Construct.js";
10
10
  const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
11
11
  /////////////////////
12
12
  // Construct
@@ -175,7 +175,7 @@ export class Script extends Construct {
175
175
  };
176
176
  }
177
177
  /** @internal */
178
- getFunctionBinding() {
178
+ getBindings() {
179
179
  return undefined;
180
180
  }
181
181
  }