sst 2.23.1 → 2.23.2

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,18 +1,9 @@
1
- const PACKAGE_MATCH = [
2
- "sst",
3
- "astro-sst",
4
- "aws-cdk",
5
- "@aws-cdk",
6
- "constructs",
7
- "svelte-kit-sst",
8
- "solid-start-sst",
9
- ];
1
+ const PACKAGE_MATCH = ["aws-cdk", "@aws-cdk"];
10
2
  const FIELDS = ["dependencies", "devDependencies"];
11
3
  export const update = (program) => program.command("update [version]", "Update your SST and CDK packages", (yargs) => yargs.positional("version", {
12
4
  type: "string",
13
5
  describe: "Optionally specify a version to update to",
14
6
  }), async (args) => {
15
- const { green, yellow } = await import("colorette");
16
7
  const fs = await import("fs/promises");
17
8
  const path = await import("path");
18
9
  const { fetch } = await import("undici");
@@ -41,33 +32,33 @@ export const update = (program) => program.command("update [version]", "Update y
41
32
  const metadata = await fetch(`https://registry.npmjs.org/sst/${args.version || "latest"}`).then((resp) => resp.json());
42
33
  const results = new Map();
43
34
  const tasks = files.map(async (file) => {
44
- const data = await fs
45
- .readFile(file)
46
- .then((x) => x.toString())
47
- .then(JSON.parse);
35
+ const data = await fs.readFile(file).then((x) => x.toString());
36
+ // Note: preserve ending new line characters in package.json
37
+ const tailingNewline = data.match(/\r?\n$/)?.[0];
38
+ const json = JSON.parse(data);
48
39
  for (const field of FIELDS) {
49
- const deps = data[field];
50
- if (!deps)
51
- continue;
52
- for (const [pkg, existing] of Object.entries(deps)) {
53
- if (!PACKAGE_MATCH.some((x) => pkg.startsWith(x)))
54
- continue;
40
+ const deps = json[field];
41
+ for (const [pkg, existing] of Object.entries(deps || {})) {
55
42
  const desired = (() => {
56
- // Both sst and astro-sst should be sharing the same version
57
43
  if ([
58
44
  "sst",
59
45
  "astro-sst",
60
46
  "svelte-kit-sst",
61
47
  "solid-start-sst",
62
- ].includes(pkg))
48
+ ].includes(pkg)) {
63
49
  return metadata.version;
64
- if (pkg === "constructs")
50
+ }
51
+ else if (pkg === "constructs") {
65
52
  return metadata.dependencies.constructs;
66
- if (pkg.endsWith("alpha"))
67
- return metadata.dependencies["@aws-cdk/aws-apigatewayv2-alpha"];
68
- return metadata.dependencies["aws-cdk-lib"];
53
+ }
54
+ else if (pkg.startsWith("aws-cdk") ||
55
+ pkg.startsWith("@aws-cdk")) {
56
+ return pkg.endsWith("alpha")
57
+ ? metadata.dependencies["@aws-cdk/aws-apigatewayv2-alpha"]
58
+ : metadata.dependencies["aws-cdk-lib"];
59
+ }
69
60
  })();
70
- if (existing === desired)
61
+ if (!desired || existing === desired)
71
62
  continue;
72
63
  let arr = results.get(file);
73
64
  if (!arr) {
@@ -79,7 +70,7 @@ export const update = (program) => program.command("update [version]", "Update y
79
70
  }
80
71
  }
81
72
  if (results.has(file)) {
82
- await fs.writeFile(file, JSON.stringify(data, null, 2));
73
+ await fs.writeFile(file, `${JSON.stringify(json, null, 2)}${tailingNewline ?? ""}`);
83
74
  }
84
75
  });
85
76
  await Promise.all(tasks);
@@ -23,6 +23,7 @@ import { Effect, PolicyStatement } from "aws-cdk-lib/aws-iam";
23
23
  import { StringParameter } from "aws-cdk-lib/aws-ssm";
24
24
  import { Platform } from "aws-cdk-lib/aws-ecr-assets";
25
25
  import { useBootstrap } from "../bootstrap.js";
26
+ import { Colors } from "../cli/colors.js";
26
27
  const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
27
28
  const supportedRuntimes = {
28
29
  container: CDKRuntime.FROM_IMAGE,
@@ -223,6 +224,8 @@ export class Function extends CDKFunction {
223
224
  logRetentionRetryOptions: logRetention && { maxRetries: 100 },
224
225
  });
225
226
  useDeferredTasks().add(async () => {
227
+ if (props.runtime === "container")
228
+ Colors.line(`➜ Building the container image for the "${this.node.id}" function...`);
226
229
  // Build function
227
230
  const result = await useRuntimeHandlers().build(this.node.addr, "deploy");
228
231
  if (result.type === "error") {
package/constructs/Job.js CHANGED
@@ -3,6 +3,7 @@ import path from "path";
3
3
  import fs from "fs/promises";
4
4
  import { Construct } from "constructs";
5
5
  import { Duration as CdkDuration } from "aws-cdk-lib/core";
6
+ import { Platform } from "aws-cdk-lib/aws-ecr-assets";
6
7
  import { PolicyStatement, Effect } from "aws-cdk-lib/aws-iam";
7
8
  import { AssetCode, Code, Runtime, Function as CdkFunction, } from "aws-cdk-lib/aws-lambda";
8
9
  import { Project, LinuxBuildImage, BuildSpec, ComputeType, } from "aws-cdk-lib/aws-codebuild";
@@ -15,7 +16,7 @@ import { bindEnvironment, bindPermissions, getReferencedSecrets, } from "./util/
15
16
  import { useDeferredTasks } from "./deferred_task.js";
16
17
  import { useProject } from "../project.js";
17
18
  import { useRuntimeHandlers } from "../runtime/handlers.js";
18
- import { Platform } from "aws-cdk-lib/aws-ecr-assets";
19
+ import { Colors } from "../cli/colors.js";
19
20
  const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
20
21
  /////////////////////
21
22
  // Construct
@@ -194,6 +195,8 @@ export class Job extends Construct {
194
195
  buildCodeBuildProjectCode() {
195
196
  const { handler, architecture, runtime, container } = this.props;
196
197
  useDeferredTasks().add(async () => {
198
+ if (runtime === "container")
199
+ Colors.line(`➜ Building the container image for the "${this.node.id}" job...`);
197
200
  // Build function
198
201
  const result = await useRuntimeHandlers().build(this.node.addr, "deploy");
199
202
  if (result.type === "error") {
@@ -22,6 +22,11 @@ export interface ServiceProps {
22
22
  * @default "."
23
23
  */
24
24
  path?: string;
25
+ /**
26
+ * Path to Dockerfile relative to the defined "path".
27
+ * @default "Dockerfile"
28
+ */
29
+ file?: string;
25
30
  /**
26
31
  * The amount of cpu allocated.
27
32
  * @default "0.25 vCPU"
@@ -188,10 +188,16 @@ export class Service extends Construct {
188
188
  Object.entries(props?.environment || {}).map(([key, value]) => this.addEnvironmentForService(key, value));
189
189
  useDeferredTasks().add(async () => {
190
190
  if (!app.isRunningSSTTest()) {
191
- Colors.line(`➜ Building container image for the "${this.node.id}" service`);
191
+ Colors.line(`➜ Building the container image for the "${this.node.id}" service...`);
192
192
  // Build app
193
- let dockerfile = "Dockerfile";
194
- if (!(await existsAsync(path.join(this.props.path, dockerfile)))) {
193
+ let dockerfile;
194
+ if (this.props.file) {
195
+ dockerfile = this.props.file;
196
+ }
197
+ else if (await existsAsync(path.join(this.props.path, "Dockerfile"))) {
198
+ dockerfile = "Dockerfile";
199
+ }
200
+ else {
195
201
  await this.createNixpacksBuilder();
196
202
  dockerfile = await this.runNixpacksBuild();
197
203
  }
@@ -328,10 +334,16 @@ export class Service extends Construct {
328
334
  // Bundle Cluster
329
335
  /////////////////////
330
336
  validateServiceExists() {
331
- const { path: servicePath } = this.props;
337
+ const { path: servicePath, file } = this.props;
332
338
  if (!fs.existsSync(servicePath)) {
333
339
  throw new Error(`No service found at "${path.resolve(servicePath)}"`);
334
340
  }
341
+ if (file) {
342
+ const dockerfilePath = path.join(servicePath, file);
343
+ if (!fs.existsSync(dockerfilePath)) {
344
+ throw new Error(`No Dockerfile found at "${dockerfilePath}". Make sure to set the "file" property to the path of the Dockerfile relative to "${servicePath}".`);
345
+ }
346
+ }
335
347
  }
336
348
  validateMemoryAndCpu() {
337
349
  const { memory, cpu } = this.props;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "sideEffects": false,
3
3
  "name": "sst",
4
- "version": "2.23.1",
4
+ "version": "2.23.2",
5
5
  "bin": {
6
6
  "sst": "cli/sst.js"
7
7
  },
@@ -17,7 +17,7 @@ export const useJavaHandler = Context.memo(async () => {
17
17
  const handlers = useRuntimeHandlers();
18
18
  const processes = new Map();
19
19
  const sources = new Map();
20
- const handlerName = process.platform === "win32" ? `handler.exe` : `handler`;
20
+ const runningBuilds = new Map();
21
21
  handlers.register({
22
22
  shouldBuild: (input) => {
23
23
  if (!input.file.endsWith(".java"))
@@ -68,13 +68,26 @@ export const useJavaHandler = Context.memo(async () => {
68
68
  const buildTask = input.props.java?.buildTask || "build";
69
69
  const outputDir = input.props.java?.buildOutputDir || "distributions";
70
70
  sources.set(input.functionID, srcPath);
71
- try {
71
+ async function build() {
72
+ // build
72
73
  await execAsync(`${buildBinary} ${buildTask} -Dorg.gradle.logging.level=${process.env.DEBUG ? "debug" : "lifecycle"}`, {
73
74
  cwd: srcPath,
74
75
  });
76
+ // unzip
75
77
  const buildOutput = path.join(srcPath, "build", outputDir);
76
78
  const zip = (await fs.readdir(buildOutput)).find((f) => f.endsWith(".zip"));
77
- new AdmZip(path.join(buildOutput, zip)).extractAllTo(input.out);
79
+ await new Promise((resolve, reject) => {
80
+ const zipper = new AdmZip(path.join(buildOutput, zip));
81
+ zipper.extractAllToAsync(input.out, false, false, (err) => err ? reject(err) : resolve(undefined));
82
+ });
83
+ }
84
+ try {
85
+ // Run gradle build once per directory. Otherwise they'll interfere
86
+ // with one another
87
+ const buildPromise = runningBuilds.get(buildBinary) ?? build();
88
+ runningBuilds.set(buildBinary, buildPromise);
89
+ await buildPromise;
90
+ runningBuilds.delete(buildBinary);
78
91
  return {
79
92
  type: "success",
80
93
  handler: input.props.handler,
package/sst.mjs CHANGED
@@ -5522,7 +5522,7 @@ var init_java = __esm({
5522
5522
  const handlers = useRuntimeHandlers();
5523
5523
  const processes = /* @__PURE__ */ new Map();
5524
5524
  const sources = /* @__PURE__ */ new Map();
5525
- const handlerName = process.platform === "win32" ? `handler.exe` : `handler`;
5525
+ const runningBuilds = /* @__PURE__ */ new Map();
5526
5526
  handlers.register({
5527
5527
  shouldBuild: (input) => {
5528
5528
  if (!input.file.endsWith(".java"))
@@ -5579,7 +5579,7 @@ var init_java = __esm({
5579
5579
  const buildTask = input.props.java?.buildTask || "build";
5580
5580
  const outputDir = input.props.java?.buildOutputDir || "distributions";
5581
5581
  sources.set(input.functionID, srcPath);
5582
- try {
5582
+ async function build2() {
5583
5583
  await execAsync(
5584
5584
  `${buildBinary} ${buildTask} -Dorg.gradle.logging.level=${process.env.DEBUG ? "debug" : "lifecycle"}`,
5585
5585
  {
@@ -5590,7 +5590,21 @@ var init_java = __esm({
5590
5590
  const zip = (await fs13.readdir(buildOutput)).find(
5591
5591
  (f) => f.endsWith(".zip")
5592
5592
  );
5593
- new AdmZip(path15.join(buildOutput, zip)).extractAllTo(input.out);
5593
+ await new Promise((resolve2, reject) => {
5594
+ const zipper = new AdmZip(path15.join(buildOutput, zip));
5595
+ zipper.extractAllToAsync(
5596
+ input.out,
5597
+ false,
5598
+ false,
5599
+ (err) => err ? reject(err) : resolve2(void 0)
5600
+ );
5601
+ });
5602
+ }
5603
+ try {
5604
+ const buildPromise = runningBuilds.get(buildBinary) ?? build2();
5605
+ runningBuilds.set(buildBinary, buildPromise);
5606
+ await buildPromise;
5607
+ runningBuilds.delete(buildBinary);
5594
5608
  return {
5595
5609
  type: "success",
5596
5610
  handler: input.props.handler
@@ -8838,15 +8852,6 @@ function secrets(program2) {
8838
8852
  }
8839
8853
 
8840
8854
  // src/cli/commands/update.ts
8841
- var PACKAGE_MATCH = [
8842
- "sst",
8843
- "astro-sst",
8844
- "aws-cdk",
8845
- "@aws-cdk",
8846
- "constructs",
8847
- "svelte-kit-sst",
8848
- "solid-start-sst"
8849
- ];
8850
8855
  var FIELDS = ["dependencies", "devDependencies"];
8851
8856
  var update = (program2) => program2.command(
8852
8857
  "update [version]",
@@ -8856,7 +8861,6 @@ var update = (program2) => program2.command(
8856
8861
  describe: "Optionally specify a version to update to"
8857
8862
  }),
8858
8863
  async (args) => {
8859
- const { green, yellow } = await import("colorette");
8860
8864
  const fs19 = await import("fs/promises");
8861
8865
  const path22 = await import("path");
8862
8866
  const { fetch } = await import("undici");
@@ -8886,29 +8890,27 @@ var update = (program2) => program2.command(
8886
8890
  ).then((resp) => resp.json());
8887
8891
  const results = /* @__PURE__ */ new Map();
8888
8892
  const tasks = files.map(async (file) => {
8889
- const data2 = await fs19.readFile(file).then((x) => x.toString()).then(JSON.parse);
8893
+ const data2 = await fs19.readFile(file).then((x) => x.toString());
8894
+ const tailingNewline = data2.match(/\r?\n$/)?.[0];
8895
+ const json = JSON.parse(data2);
8890
8896
  for (const field of FIELDS) {
8891
- const deps = data2[field];
8892
- if (!deps)
8893
- continue;
8894
- for (const [pkg, existing] of Object.entries(deps)) {
8895
- if (!PACKAGE_MATCH.some((x) => pkg.startsWith(x)))
8896
- continue;
8897
+ const deps = json[field];
8898
+ for (const [pkg, existing] of Object.entries(deps || {})) {
8897
8899
  const desired = (() => {
8898
8900
  if ([
8899
8901
  "sst",
8900
8902
  "astro-sst",
8901
8903
  "svelte-kit-sst",
8902
8904
  "solid-start-sst"
8903
- ].includes(pkg))
8905
+ ].includes(pkg)) {
8904
8906
  return metadata3.version;
8905
- if (pkg === "constructs")
8907
+ } else if (pkg === "constructs") {
8906
8908
  return metadata3.dependencies.constructs;
8907
- if (pkg.endsWith("alpha"))
8908
- return metadata3.dependencies["@aws-cdk/aws-apigatewayv2-alpha"];
8909
- return metadata3.dependencies["aws-cdk-lib"];
8909
+ } else if (pkg.startsWith("aws-cdk") || pkg.startsWith("@aws-cdk")) {
8910
+ return pkg.endsWith("alpha") ? metadata3.dependencies["@aws-cdk/aws-apigatewayv2-alpha"] : metadata3.dependencies["aws-cdk-lib"];
8911
+ }
8910
8912
  })();
8911
- if (existing === desired)
8913
+ if (!desired || existing === desired)
8912
8914
  continue;
8913
8915
  let arr = results.get(file);
8914
8916
  if (!arr) {
@@ -8920,7 +8922,10 @@ var update = (program2) => program2.command(
8920
8922
  }
8921
8923
  }
8922
8924
  if (results.has(file)) {
8923
- await fs19.writeFile(file, JSON.stringify(data2, null, 2));
8925
+ await fs19.writeFile(
8926
+ file,
8927
+ `${JSON.stringify(json, null, 2)}${tailingNewline ?? ""}`
8928
+ );
8924
8929
  }
8925
8930
  });
8926
8931
  await Promise.all(tasks);