sst 2.24.15 → 2.24.17

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.
@@ -2,18 +2,24 @@ export const build = (program) => program.command("build", "Build your app", (ya
2
2
  type: "string",
3
3
  describe: "Output directory, defaults to .sst/dist",
4
4
  }), async (args) => {
5
+ const { exit, exitWithError } = await import("../program.js");
5
6
  const { useProject } = await import("../../project.js");
6
7
  const { Stacks } = await import("../../stacks/index.js");
7
8
  const { Colors } = await import("../colors.js");
8
9
  const path = await import("path");
9
- const project = useProject();
10
- const [_metafile, sstConfig] = await Stacks.load(project.paths.config);
11
- const result = await Stacks.synth({
12
- fn: sstConfig.stacks,
13
- buildDir: args.to,
14
- mode: "deploy",
15
- });
16
- Colors.line("");
17
- Colors.line(Colors.success(`✔`), Colors.bold(" Built:"), `${result.stacks.length} stack${result.stacks.length > 1 ? "s" : ""} to ${path.relative(process.cwd(), result.directory)}`);
18
- process.exit(0);
10
+ try {
11
+ const project = useProject();
12
+ const [_metafile, sstConfig] = await Stacks.load(project.paths.config);
13
+ const result = await Stacks.synth({
14
+ fn: sstConfig.stacks,
15
+ buildDir: args.to,
16
+ mode: "deploy",
17
+ });
18
+ Colors.line("");
19
+ Colors.line(Colors.success(`✔`), Colors.bold(" Built:"), `${result.stacks.length} stack${result.stacks.length > 1 ? "s" : ""} to ${path.relative(process.cwd(), result.directory)}`);
20
+ await exit();
21
+ }
22
+ catch (e) {
23
+ await exitWithError(e);
24
+ }
19
25
  });
@@ -6,43 +6,50 @@ export const connect = (program) => program.command("connect", "Connect a stage
6
6
  }), async (args) => {
7
7
  if (!args.future)
8
8
  throw new Error("This command is not yet available.");
9
+ const { exit, exitWithError } = await import("../program.js");
9
10
  const { useAWSClient } = await import("../../credentials.js");
10
11
  const { useProject } = await import("../../project.js");
11
12
  const { useSTSIdentity } = await import("../../credentials.js");
12
13
  const { IAMClient, CreateRoleCommand, AttachRolePolicyCommand } = await import("@aws-sdk/client-iam");
13
- const client = useAWSClient(IAMClient);
14
- if (args.dev) {
15
- Colors.line(Colors.warning("⚠"), Colors.bold(" Connecting to dev stage"));
16
- }
17
- await client
18
- .send(new CreateRoleCommand({
19
- RoleName: "sst",
20
- AssumeRolePolicyDocument: JSON.stringify({
21
- Version: "2012-10-17",
22
- Statement: [
23
- {
24
- Effect: "Allow",
25
- Principal: {
26
- AWS: `arn:aws:iam::${args.dev ? "917397401067" : "226609089145"}:root`,
14
+ try {
15
+ const client = useAWSClient(IAMClient);
16
+ if (args.dev) {
17
+ Colors.line(Colors.warning("⚠"), Colors.bold(" Connecting to dev stage"));
18
+ }
19
+ await client
20
+ .send(new CreateRoleCommand({
21
+ RoleName: "sst",
22
+ AssumeRolePolicyDocument: JSON.stringify({
23
+ Version: "2012-10-17",
24
+ Statement: [
25
+ {
26
+ Effect: "Allow",
27
+ Principal: {
28
+ AWS: `arn:aws:iam::${args.dev ? "917397401067" : "226609089145"}:root`,
29
+ },
30
+ Action: "sts:AssumeRole",
27
31
  },
28
- Action: "sts:AssumeRole",
29
- },
30
- ],
31
- }),
32
- }))
33
- .catch((e) => {
34
- if (e.Error.Code === "EntityAlreadyExists")
35
- return;
36
- throw e;
37
- });
38
- await client.send(new AttachRolePolicyCommand({
39
- RoleName: "sst",
40
- PolicyArn: "arn:aws:iam::aws:policy/AdministratorAccess",
41
- }));
42
- const project = useProject();
43
- const identity = await useSTSIdentity();
44
- const host = args.dev
45
- ? "http://localhost:3000"
46
- : "https://console.production.sst.dev";
47
- console.log(`${host}/connect?app=${project.config.name}&stage=${project.config.stage}&aws_account_id=${identity.Account}&region=${project.config.region}`);
32
+ ],
33
+ }),
34
+ }))
35
+ .catch((e) => {
36
+ if (e.Error.Code === "EntityAlreadyExists")
37
+ return;
38
+ throw e;
39
+ });
40
+ await client.send(new AttachRolePolicyCommand({
41
+ RoleName: "sst",
42
+ PolicyArn: "arn:aws:iam::aws:policy/AdministratorAccess",
43
+ }));
44
+ const project = useProject();
45
+ const identity = await useSTSIdentity();
46
+ const host = args.dev
47
+ ? "http://localhost:3000"
48
+ : "https://console.production.sst.dev";
49
+ console.log(`${host}/connect?app=${project.config.name}&stage=${project.config.stage}&aws_account_id=${identity.Account}&region=${project.config.region}`);
50
+ await exit();
51
+ }
52
+ catch (e) {
53
+ await exitWithError(e);
54
+ }
48
55
  });
@@ -1,17 +1,23 @@
1
1
  export const consoleCommand = async (program) => program.command("console", "Start the SST Console", (yargs) => yargs, async () => {
2
- const { blue } = await import("colorette");
2
+ const { exit, exitWithError } = await import("../program.js");
3
3
  const { useRuntimeServer } = await import("../../runtime/server.js");
4
4
  const { useLocalServer } = await import("../local/server.js");
5
5
  const { printHeader } = await import("../ui/header.js");
6
6
  const { clear } = await import("../terminal.js");
7
- await Promise.all([
8
- useRuntimeServer(),
9
- useLocalServer({
10
- key: "",
11
- cert: "",
12
- live: false,
13
- }),
14
- ]);
15
- clear();
16
- printHeader({ console: true, hint: "ready!" });
7
+ try {
8
+ await Promise.all([
9
+ useRuntimeServer(),
10
+ useLocalServer({
11
+ key: "",
12
+ cert: "",
13
+ live: false,
14
+ }),
15
+ ]);
16
+ clear();
17
+ printHeader({ console: true, hint: "ready!" });
18
+ await exit();
19
+ }
20
+ catch (e) {
21
+ await exitWithError(e);
22
+ }
17
23
  });
@@ -15,87 +15,98 @@ export const deploy = (program) => program.command("deploy [filter]", "Deploy yo
15
15
  const { printDeploymentResults } = await import("../ui/deploy.js");
16
16
  const { createSpinner } = await import("../spinner.js");
17
17
  const { dim, blue, bold } = await import("colorette");
18
+ const { exit, exitWithError } = await import("../program.js");
18
19
  const { useProject } = await import("../../project.js");
20
+ const { SilentError } = await import("../../error.js");
19
21
  const { loadAssembly, useAppMetadata, saveAppMetadata, Stacks } = await import("../../stacks/index.js");
20
22
  const { getCiInfo } = await import("../ci-info.js");
21
23
  const { render } = await import("ink");
22
24
  const { DeploymentUI } = await import("../ui/deploy.js");
23
25
  const { mapValues } = await import("remeda");
24
- const project = useProject();
25
- const [identity, appMetadata] = await Promise.all([
26
- useSTSIdentity(),
27
- useAppMetadata(),
28
- ]);
29
- async function promptChangeMode() {
30
- const readline = await import("readline");
31
- const rl = readline.createInterface({
32
- input: process.stdin,
33
- output: process.stdout,
34
- });
35
- return new Promise((resolve) => {
36
- console.log("");
37
- rl.question(`You were previously running the stage "${project.config.stage}" in dev mode. It is recommended that you use a different stage for production. Read more here — https://docs.sst.dev/live-lambda-development\n\nAre you sure you want to deploy to this stage? (y/N) `, async (input) => {
38
- rl.close();
39
- resolve(input.trim() === "y");
26
+ try {
27
+ const project = useProject();
28
+ const [identity, appMetadata] = await Promise.all([
29
+ useSTSIdentity(),
30
+ useAppMetadata(),
31
+ ]);
32
+ async function promptChangeMode() {
33
+ const readline = await import("readline");
34
+ const rl = readline.createInterface({
35
+ input: process.stdin,
36
+ output: process.stdout,
37
+ });
38
+ return new Promise((resolve) => {
39
+ console.log("");
40
+ rl.question(`You were previously running the stage "${project.config.stage}" in dev mode. It is recommended that you use a different stage for production. Read more here — https://docs.sst.dev/live-lambda-development\n\nAre you sure you want to deploy to this stage? (y/N) `, async (input) => {
41
+ rl.close();
42
+ resolve(input.trim() === "y");
43
+ });
40
44
  });
41
- });
42
- }
43
- // Check app mode changed
44
- if (!project.config.advanced?.disableAppModeCheck &&
45
- !getCiInfo().isCI &&
46
- appMetadata &&
47
- appMetadata.mode !== "deploy") {
48
- if (!(await promptChangeMode())) {
49
- process.exit(0);
50
45
  }
51
- }
52
- Colors.line(`${Colors.primary.bold(`SST v${project.version}`)}`);
53
- Colors.gap();
54
- Colors.line(`${Colors.primary(`➜`)} ${Colors.bold("App:")} ${project.config.name}`);
55
- Colors.line(` ${Colors.bold("Stage:")} ${project.config.stage}`);
56
- Colors.line(` ${Colors.bold("Region:")} ${project.config.region}`);
57
- Colors.line(` ${Colors.bold("Account:")} ${identity.Account}`);
58
- Colors.gap();
59
- const isActiveStack = (stackId) => !args.filter ||
60
- stackId
61
- .toLowerCase()
62
- .replace(project.config.name.toLowerCase(), "")
63
- .replace(project.config.stage.toLowerCase(), "")
64
- .includes(args.filter.toLowerCase());
65
- // Generate cloud assembly
66
- // - if --from is specified, we will use the existing cloud assembly
67
- // - if --from is not specified, we will call synth to generate
68
- const assembly = await (async function () {
69
- if (args.from) {
70
- const result = await loadAssembly(args.from);
46
+ // Check app mode changed
47
+ if (!project.config.advanced?.disableAppModeCheck &&
48
+ !getCiInfo().isCI &&
49
+ appMetadata &&
50
+ appMetadata.mode !== "deploy") {
51
+ if (!(await promptChangeMode())) {
52
+ await exit();
53
+ }
54
+ }
55
+ Colors.line(`${Colors.primary.bold(`SST v${project.version}`)}`);
56
+ Colors.gap();
57
+ Colors.line(`${Colors.primary(`➜`)} ${Colors.bold("App:")} ${project.config.name}`);
58
+ Colors.line(` ${Colors.bold("Stage:")} ${project.config.stage}`);
59
+ Colors.line(` ${Colors.bold("Region:")} ${project.config.region}`);
60
+ Colors.line(` ${Colors.bold("Account:")} ${identity.Account}`);
61
+ Colors.gap();
62
+ const isActiveStack = (stackId) => !args.filter ||
63
+ stackId
64
+ .toLowerCase()
65
+ .replace(project.config.name.toLowerCase(), "")
66
+ .replace(project.config.stage.toLowerCase(), "")
67
+ .includes(args.filter.toLowerCase());
68
+ // Generate cloud assembly
69
+ // - if --from is specified, we will use the existing cloud assembly
70
+ // - if --from is not specified, we will call synth to generate
71
+ const assembly = await (async function () {
72
+ if (args.from) {
73
+ const result = await loadAssembly(args.from);
74
+ return result;
75
+ }
76
+ const spinner = createSpinner({
77
+ text: " Building...",
78
+ });
79
+ const [_metafile, sstConfig] = await Stacks.load(project.paths.config);
80
+ const result = await Stacks.synth({
81
+ fn: sstConfig.stacks,
82
+ mode: "deploy",
83
+ isActiveStack,
84
+ });
85
+ spinner.succeed();
71
86
  return result;
87
+ })();
88
+ const target = assembly.stacks.filter((s) => isActiveStack(s.id));
89
+ if (!target.length) {
90
+ Colors.line(`No stacks found matching ${blue(args.filter)}`);
91
+ throw new SilentError(`No stacks found matching ${args.filter}`);
72
92
  }
73
- const spinner = createSpinner({
74
- text: " Building...",
75
- });
76
- const [_metafile, sstConfig] = await Stacks.load(project.paths.config);
77
- const result = await Stacks.synth({
78
- fn: sstConfig.stacks,
79
- mode: "deploy",
80
- isActiveStack,
81
- });
82
- spinner.succeed();
83
- return result;
84
- })();
85
- const target = assembly.stacks.filter((s) => isActiveStack(s.id));
86
- if (!target.length) {
87
- Colors.line(`No stacks found matching ${blue(args.filter)}`);
88
- process.exit(1);
93
+ const component = render(React.createElement(DeploymentUI, { assembly: assembly }));
94
+ const results = await Stacks.deployMany(target);
95
+ component.clear();
96
+ component.unmount();
97
+ printDeploymentResults(assembly, results);
98
+ // Check failed stacks
99
+ const failed = Object.values(results).find((result) => Stacks.isFailed(result.status));
100
+ if (failed) {
101
+ throw new SilentError(`CloudFormation status ${failed.status}`);
102
+ }
103
+ fs.writeFile(project.config.outputs ||
104
+ path.join(project.paths.out, "outputs.json"), JSON.stringify(mapValues(results, (val) => val.outputs), null, 2));
105
+ // Update app state
106
+ await saveAppMetadata({ mode: "deploy" });
107
+ await exit();
108
+ }
109
+ catch (e) {
110
+ await exitWithError(e);
89
111
  }
90
- const component = render(React.createElement(DeploymentUI, { assembly: assembly }));
91
- const results = await Stacks.deployMany(target);
92
- component.clear();
93
- component.unmount();
94
- printDeploymentResults(assembly, results);
95
- if (Object.values(results).some((stack) => Stacks.isFailed(stack.status)))
96
- process.exit(1);
97
- fs.writeFile(project.config.outputs || path.join(project.paths.out, "outputs.json"), JSON.stringify(mapValues(results, (val) => val.outputs), null, 2));
98
- // Update app state
99
- await saveAppMetadata({ mode: "deploy" });
100
- process.exit(0);
101
112
  });