sst 2.22.5 → 2.22.7

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.
@@ -172,6 +172,7 @@ export class Function extends CDKFunction {
172
172
  this.addEnvironment("SST_FUNCTION_ID", this.node.addr);
173
173
  useDeferredTasks().add(async () => {
174
174
  const bootstrap = await useBootstrap();
175
+ const bootstrapBucketArn = `arn:${Stack.of(this).partition}:s3:::${bootstrap.bucket}`;
175
176
  this.attachPermissions([
176
177
  new PolicyStatement({
177
178
  actions: ["iot:*"],
@@ -181,9 +182,7 @@ export class Function extends CDKFunction {
181
182
  new PolicyStatement({
182
183
  actions: ["s3:*"],
183
184
  effect: Effect.ALLOW,
184
- resources: [
185
- `arn:${Stack.of(this).partition}:s3:::${bootstrap.bucket}`,
186
- ],
185
+ resources: [bootstrapBucketArn, `${bootstrapBucketArn}/*`],
187
186
  }),
188
187
  ]);
189
188
  });
@@ -260,6 +260,7 @@ export class NextjsSite extends SsrSite {
260
260
  "rsc",
261
261
  "next-router-prefetch",
262
262
  "next-router-state-tree",
263
+ "next-url",
263
264
  ]);
264
265
  const serverBehavior = this.buildDefaultBehaviorForRegional(cachePolicy);
265
266
  return new Distribution(this, "Distribution", {
@@ -79,7 +79,7 @@ export class SsrFunction extends Construct {
79
79
  attachPermissionsToRole(this.function.role, permissions);
80
80
  }
81
81
  createFunction(assetBucket, assetKey) {
82
- const { runtime, timeout, memorySize, handler, logRetention } = this.props;
82
+ const { architecture, runtime, timeout, memorySize, handler, logRetention, } = this.props;
83
83
  return new CdkFunction(this, `ServerFunction`, {
84
84
  ...this.props,
85
85
  handler: handler.split(path.sep).join(path.posix.sep),
@@ -90,7 +90,7 @@ export class SsrFunction extends Construct {
90
90
  : runtime === "nodejs16.x"
91
91
  ? Runtime.NODEJS_16_X
92
92
  : Runtime.NODEJS_18_X,
93
- architecture: Architecture.ARM_64,
93
+ architecture: architecture || Architecture.ARM_64,
94
94
  memorySize: typeof memorySize === "string"
95
95
  ? toCdkSize(memorySize).toMebibytes()
96
96
  : memorySize,
@@ -356,25 +356,17 @@ export class Table extends Construct {
356
356
  else {
357
357
  consumerFunction = consumer;
358
358
  }
359
- eventSourceProps = {
360
- startingPosition: lambda.StartingPosition.LATEST,
361
- ...(eventSourceProps || {}),
362
- };
363
359
  // create function
364
360
  const fn = Fn.fromDefinition(scope, `Consumer_${this.node.id}_${consumerName}`, consumerFunction, this.props.defaults?.function, `The "defaults.function" cannot be applied if an instance of a Function construct is passed in. Make sure to define all the consumers using FunctionProps, so the Table construct can apply the "defaults.function" to them.`);
365
361
  this.functions[consumerName] = fn;
366
362
  // create event source
367
- const eventSource = new lambdaEventSources.DynamoEventSource(this.cdk.table, eventSourceProps);
368
- fn.addEventSource(eventSource);
369
- // set filter pattern
370
- if (filters && filters.length > 0) {
371
- const cfnEventSource = fn.node.children.find((c) => c instanceof lambda.EventSourceMapping)?.node.defaultChild;
372
- cfnEventSource.addPropertyOverride("FilterCriteria", {
373
- Filters: filters.map((filter) => ({
374
- Pattern: JSON.stringify(filter),
375
- })),
376
- });
377
- }
363
+ fn.addEventSource(new lambdaEventSources.DynamoEventSource(this.cdk.table, {
364
+ startingPosition: lambda.StartingPosition.LATEST,
365
+ filters: filters?.map((filter) => ({
366
+ pattern: JSON.stringify(filter),
367
+ })),
368
+ ...(eventSourceProps || {}),
369
+ }));
378
370
  // attach permissions
379
371
  this.permissionsAttachedForAllConsumers.forEach((permissions) => {
380
372
  fn.attachPermissions(permissions);
package/credentials.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import "@aws-sdk/types";
2
1
  import { Client } from "@aws-sdk/smithy-client";
3
2
  import { RegionInputConfig } from "@aws-sdk/config-resolver";
4
3
  import { RetryInputConfig } from "@aws-sdk/middleware-retry";
package/credentials.js CHANGED
@@ -1,4 +1,3 @@
1
- import "@aws-sdk/types";
2
1
  import { Context } from "./context/context.js";
3
2
  import { fromNodeProviderChain } from "@aws-sdk/credential-providers";
4
3
  import { GetCallerIdentityCommand, STSClient } from "@aws-sdk/client-sts";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "sideEffects": false,
3
3
  "name": "sst",
4
- "version": "2.22.5",
4
+ "version": "2.22.7",
5
5
  "bin": {
6
6
  "sst": "cli/sst.js"
7
7
  },
@@ -1,3 +1,4 @@
1
+ import os from "os";
1
2
  import path from "path";
2
3
  import fs from "fs/promises";
3
4
  import { exec } from "child_process";
@@ -9,14 +10,15 @@ import { Worker } from "worker_threads";
9
10
  import { useRuntimeHandlers } from "../handlers.js";
10
11
  import { useRuntimeWorkers } from "../workers.js";
11
12
  import { Context } from "../../context/context.js";
12
- import { VisibleError } from "../../error.js";
13
13
  import { Colors } from "../../cli/colors.js";
14
+ import { Logger } from "../../logger.js";
15
+ import { findAbove } from "../../util/fs.js";
14
16
  export const useNodeHandler = Context.memo(async () => {
15
17
  const workers = await useRuntimeWorkers();
16
18
  const handlers = useRuntimeHandlers();
17
- const cache = {};
19
+ const rebuildCache = {};
18
20
  process.on("exit", () => {
19
- for (const { ctx } of Object.values(cache)) {
21
+ for (const { ctx } of Object.values(rebuildCache)) {
20
22
  ctx.dispose();
21
23
  }
22
24
  });
@@ -24,14 +26,14 @@ export const useNodeHandler = Context.memo(async () => {
24
26
  const threads = new Map();
25
27
  handlers.register({
26
28
  shouldBuild: (input) => {
27
- const result = cache[input.functionID];
28
- if (!result)
29
+ const cache = rebuildCache[input.functionID];
30
+ if (!cache)
29
31
  return false;
30
32
  const relative = path
31
33
  .relative(project.paths.root, input.file)
32
34
  .split(path.sep)
33
35
  .join(path.posix.sep);
34
- return Boolean(result.last.metafile?.inputs[relative]);
36
+ return Boolean(cache.result.metafile?.inputs[relative]);
35
37
  },
36
38
  canHandle: (input) => input.startsWith("nodejs"),
37
39
  startWorker: async (input) => {
@@ -62,7 +64,6 @@ export const useNodeHandler = Context.memo(async () => {
62
64
  await worker?.terminate();
63
65
  },
64
66
  build: async (input) => {
65
- const exists = cache[input.functionID];
66
67
  const parsed = path.parse(input.props.handler);
67
68
  const file = [
68
69
  ".ts",
@@ -94,11 +95,29 @@ export const useNodeHandler = Context.memo(async () => {
94
95
  .relative(input.out, target.replace(extension, parsed.ext))
95
96
  .split(path.sep)
96
97
  .join(path.posix.sep);
98
+ if (input.mode === "start") {
99
+ const root = await findAbove(parsed.dir, "package.json");
100
+ if (!root) {
101
+ return {
102
+ type: "error",
103
+ errors: [
104
+ `Could not find package.json for handler "${input.props.handler}"`,
105
+ ],
106
+ };
107
+ }
108
+ const dir = path.join(root, "node_modules");
109
+ try {
110
+ await fs.symlink(path.resolve(dir), path.resolve(path.join(input.out, "node_modules")), "dir");
111
+ }
112
+ catch { }
113
+ }
114
+ // Rebuilt using existing esbuild context
115
+ const exists = rebuildCache[input.functionID];
97
116
  if (exists) {
98
117
  const result = await exists.ctx.rebuild();
99
- cache[input.functionID] = {
118
+ rebuildCache[input.functionID] = {
100
119
  ctx: exists.ctx,
101
- last: result,
120
+ result,
102
121
  };
103
122
  return {
104
123
  type: "success",
@@ -171,18 +190,16 @@ export const useNodeHandler = Context.memo(async () => {
171
190
  .forEach(({ path }) => {
172
191
  warnings.push(`You are importing from "${path}" in "${inputPath}". Did you mean to import from "sst/node"?`);
173
192
  }));
174
- async function find(dir, target) {
175
- if (dir === "/")
176
- throw new VisibleError("Could not find a package.json file");
177
- if (await fs
178
- .access(path.join(dir, target))
179
- .then(() => true)
180
- .catch(() => false))
181
- return dir;
182
- return find(path.join(dir, ".."), target);
183
- }
184
193
  if (input.mode === "deploy" && installPackages) {
185
- const src = await find(parsed.dir, "package.json");
194
+ const src = await findAbove(parsed.dir, "package.json");
195
+ if (!src) {
196
+ return {
197
+ type: "error",
198
+ errors: [
199
+ `Could not find package.json for handler "${input.props.handler}"`,
200
+ ],
201
+ };
202
+ }
186
203
  const json = JSON.parse(await fs
187
204
  .readFile(path.join(src, "package.json"))
188
205
  .then((x) => x.toString()));
@@ -204,17 +221,11 @@ export const useNodeHandler = Context.memo(async () => {
204
221
  });
205
222
  });
206
223
  }
224
+ // Cache esbuild result and context for rebuild
207
225
  if (input.mode === "start") {
208
- const dir = path.join(await find(parsed.dir, "package.json"), "node_modules");
209
- try {
210
- await fs.symlink(path.resolve(dir), path.resolve(path.join(input.out, "node_modules")), "dir");
211
- }
212
- catch { }
226
+ rebuildCache[input.functionID] = { ctx, result };
213
227
  }
214
- cache[input.functionID] = {
215
- ctx,
216
- last: result,
217
- };
228
+ logMemoryUsage(input.functionID, input.props.handler);
218
229
  return {
219
230
  type: "success",
220
231
  handler,
@@ -240,3 +251,18 @@ export const useNodeHandler = Context.memo(async () => {
240
251
  },
241
252
  });
242
253
  });
254
+ function logMemoryUsage(functionID, handler) {
255
+ const printInMB = (bytes) => `${Math.round(bytes / 1024 / 1024)} MB`;
256
+ const used = process.memoryUsage();
257
+ for (const key in used) {
258
+ // @ts-ignore
259
+ used[key] = printInMB(used[key]);
260
+ }
261
+ Logger.debug({
262
+ functionID,
263
+ handler,
264
+ freeMemory: printInMB(os.freemem()),
265
+ totalMemory: printInMB(os.totalmem()),
266
+ ...used,
267
+ });
268
+ }