sst 2.38.4 → 2.38.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.
@@ -21,7 +21,7 @@ export const bind = (program) => program
21
21
  const { useProject } = await import("../../project.js");
22
22
  const { Stacks } = await import("../../stacks/index.js");
23
23
  const { useBus } = await import("../../bus.js");
24
- const { useIOT } = await import("../../iot.js");
24
+ const { useIOT, isSupported } = await import("../../iot.js");
25
25
  const { Colors } = await import("../colors.js");
26
26
  const { Logger } = await import("../../logger.js");
27
27
  const [{ useServices }, { useSites: useSsrSites }, { useSites: useStaticSites }, { useSites: useSlsNextjsSites }, { Parameter }, { getEnvironmentKey },] = await Promise.all([
@@ -42,7 +42,9 @@ export const bind = (program) => program
42
42
  if (!command) {
43
43
  throw new VisibleError("Command is required, e.g. sst bind npm run script");
44
44
  }
45
- useIOT();
45
+ if (isSupported()) {
46
+ useIOT();
47
+ }
46
48
  const bus = useBus();
47
49
  const project = useProject();
48
50
  let p;
@@ -1,3 +1,4 @@
1
+ import { VisibleError } from "../../error.js";
1
2
  export const dev = (program) => program.command(["dev", "start"], "Work on your app locally", (yargs) => yargs.option("increase-timeout", {
2
3
  type: "boolean",
3
4
  description: "Increase function timeout",
@@ -20,11 +21,15 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
20
21
  const { getCiInfo } = await import("../ci-info.js");
21
22
  const { useMetadataCache } = await import("../../stacks/metadata.js");
22
23
  const { lazy } = await import("../../util/lazy.js");
24
+ const { useIOT, isSupported } = await import("../../iot.js");
23
25
  try {
24
26
  if (args._[0] === "start") {
25
27
  console.log(yellow(`Warning: ${bold(`sst start`)} has been renamed to ${bold(`sst dev`)}`));
26
28
  }
27
29
  const project = useProject();
30
+ if (!isSupported()) {
31
+ throw new VisibleError(`Live Lambda is not currently supported in the "${project.config.region}" region. To fix this, you can pick an alternative region just for your local environment - https://docs.sst.dev/live-lambda-development#supported-regions`);
32
+ }
28
33
  const useFunctionLogger = lazy(async () => {
29
34
  const { useFunctions } = await import("../../constructs/Function.js");
30
35
  const bus = useBus();
@@ -296,7 +301,7 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
296
301
  });
297
302
  const useDisconnector = lazy(async () => {
298
303
  const bus = useBus();
299
- const iot = await import("../../iot.js").then((mod) => mod.useIOT());
304
+ const iot = await useIOT();
300
305
  bus.subscribe("cli.dev", async (evt) => {
301
306
  const topic = `${iot.prefix}/events`;
302
307
  iot.publish(topic, "cli.dev", evt.properties);
@@ -151,6 +151,7 @@ export class Function extends CDKFunction {
151
151
  ...props,
152
152
  ...(props.runtime === "container"
153
153
  ? {
154
+ description: "SST Live Lambda handler",
154
155
  code: Code.fromAssetImage(path.resolve(__dirname, "../support/bridge"), {
155
156
  ...(architecture?.dockerPlatform
156
157
  ? { platform: Platform.custom(architecture.dockerPlatform) }
@@ -161,9 +162,10 @@ export class Function extends CDKFunction {
161
162
  layers: undefined,
162
163
  }
163
164
  : {
165
+ description: "SST Live Lambda handler",
164
166
  runtime: CDKRuntime.NODEJS_18_X,
165
167
  code: Code.fromAsset(path.resolve(__dirname, "../support/bridge")),
166
- handler: "bridge.handler",
168
+ handler: "live-lambda.handler",
167
169
  layers: [],
168
170
  }),
169
171
  architecture,
package/credentials.js CHANGED
@@ -53,10 +53,22 @@ export function useAWSClient(client, force = false) {
53
53
  const [project, credentials] = [useProject(), useAWSCredentialsProvider()];
54
54
  const printNoInternet = (() => {
55
55
  let lastPrinted = 0;
56
- return () => {
56
+ return (message) => {
57
+ const isIotUnreachable = message.includes(`iot.${project.config.region}.amazonaws.com`);
57
58
  const now = Date.now();
58
59
  if (now - lastPrinted > 5000) {
59
- console.log("Waiting for internet connection...");
60
+ if (isIotUnreachable) {
61
+ console.log("\nConnecting to Live Lambda...");
62
+ if (lastPrinted === 0) {
63
+ console.log("");
64
+ console.log("Connecting to Live Lambda is taking long:");
65
+ console.log(" - Check if your machine is able to connect to AWS.");
66
+ console.log(" - Or, if you're connecting to a new AWS account for the first time, give it 10 minutes.");
67
+ }
68
+ }
69
+ else {
70
+ console.log("\nWaiting for internet connection...");
71
+ }
60
72
  lastPrinted = now;
61
73
  }
62
74
  };
@@ -68,7 +80,7 @@ export function useAWSClient(client, force = false) {
68
80
  retryDecider: (e) => {
69
81
  // Handle no internet connection => retry
70
82
  if (e.code === "ENOTFOUND") {
71
- printNoInternet();
83
+ printNoInternet(e.message);
72
84
  return true;
73
85
  }
74
86
  // Handle throttling errors => retry
package/iot.d.ts CHANGED
@@ -4,3 +4,4 @@ export declare const useIOT: () => Promise<{
4
4
  prefix: string;
5
5
  publish<Type extends keyof Events>(topic: string, type: Type, properties: Events[Type]): Promise<void>;
6
6
  }>;
7
+ export declare const isSupported: () => boolean;
package/iot.js CHANGED
@@ -161,3 +161,28 @@ export const useIOT = lazy(async () => {
161
161
  },
162
162
  };
163
163
  });
164
+ export const isSupported = () => [
165
+ "eu-central-1",
166
+ "eu-west-1",
167
+ "eu-west-2",
168
+ "eu-west-3",
169
+ "eu-north-1",
170
+ "ap-south-1",
171
+ "ap-northeast-2",
172
+ "ap-northeast-1",
173
+ "me-south-1",
174
+ "me-central-1",
175
+ "sa-east-1",
176
+ "ca-central-1",
177
+ "ap-east-1",
178
+ "ap-southeast-1",
179
+ "ap-southeast-2",
180
+ "us-east-1",
181
+ "us-east-2",
182
+ "us-west-1",
183
+ "us-west-2",
184
+ "us-gov-east-1",
185
+ "us-gov-west-1",
186
+ "cn-north-1",
187
+ "cn-northwest-1",
188
+ ].includes(useProject().config.region);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "sideEffects": false,
3
3
  "name": "sst",
4
- "version": "2.38.4",
4
+ "version": "2.38.5",
5
5
  "bin": {
6
6
  "sst": "cli/sst.js"
7
7
  },
@@ -120,7 +120,7 @@
120
120
  "@types/ws": "^8.5.3",
121
121
  "@types/yargs": "^17.0.13",
122
122
  "archiver": "^5.3.1",
123
- "astro-sst": "2.38.4",
123
+ "astro-sst": "2.38.5",
124
124
  "async": "^3.2.4",
125
125
  "tsx": "^3.12.1",
126
126
  "typescript": "^5.2.2",
@@ -1,3 +1,5 @@
1
+ import process from "process";
2
+ import { release, networkInterfaces } from "os";
1
3
  import http from "http";
2
4
  import { spawn } from "child_process";
3
5
  import { useRuntimeWorkers } from "../workers.js";
@@ -50,10 +52,11 @@ export const useContainerHandler = () => {
50
52
  const server = await useRuntimeServerConfig();
51
53
  const workers = await useRuntimeWorkers();
52
54
  const fn = useFunctions().fromID(input.functionID);
55
+ const host = isWSL() ? getInternalHost() : "host.docker.internal";
53
56
  dockerRun(input, {
54
57
  cmd: fn?.container?.cmd,
55
58
  envs: {
56
- AWS_LAMBDA_RUNTIME_API: `host.docker.internal:${server.port}/${input.workerID}`,
59
+ AWS_LAMBDA_RUNTIME_API: `${host}:${server.port}/${input.workerID}`,
57
60
  },
58
61
  }, () => {
59
62
  workers.exited(input.workerID);
@@ -261,3 +264,12 @@ export const useContainerHandler = () => {
261
264
  },
262
265
  };
263
266
  };
267
+ function isWSL() {
268
+ return (process.platform == "linux" && release().toLowerCase().includes("microsoft"));
269
+ }
270
+ function getInternalHost() {
271
+ const host = []
272
+ .concat(...Object.values(networkInterfaces()))
273
+ .find((x) => !x?.internal && x?.family === "IPv4")?.address;
274
+ return host ?? "host.docker.internal";
275
+ }
@@ -87,7 +87,9 @@ export const useNodeHandler = () => {
87
87
  const extension = isESM ? ".mjs" : ".cjs";
88
88
  const target = path.join(input.out, !relative.startsWith("..") && !path.isAbsolute(input.props.handler)
89
89
  ? relative
90
- : "", parsed.name + extension);
90
+ : "",
91
+ // Lambda handler can only contain 1 dot separating the file name and function name
92
+ parsed.name.replace(".", "-") + extension);
91
93
  const handler = path
92
94
  .relative(input.out, target.replace(extension, parsed.ext))
93
95
  .split(path.sep)
@@ -1,3 +1,3 @@
1
1
  FROM public.ecr.aws/lambda/nodejs:18
2
- COPY bridge.mjs ${LAMBDA_TASK_ROOT}
3
- CMD ["bridge.handler"]
2
+ COPY live-lambda.mjs ${LAMBDA_TASK_ROOT}
3
+ CMD ["live-lambda.handler"]
package/util/wsl.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare const isWSL: () => boolean;
2
+ export declare const getInternalHost: () => string | undefined;
package/util/wsl.js ADDED
@@ -0,0 +1,10 @@
1
+ import process from "process";
2
+ import { release, networkInterfaces } from "os";
3
+ export const isWSL = () => {
4
+ return (process.platform == "linux" && release().toLowerCase().includes("microsoft"));
5
+ };
6
+ export const getInternalHost = () => {
7
+ return []
8
+ .concat(...Object.values(networkInterfaces()))
9
+ .find((x) => !x?.internal && x?.family === "IPv4")?.address;
10
+ };
File without changes