sst 2.0.0-rc.44 → 2.0.0-rc.46

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.
@@ -44,7 +44,7 @@ export const deploy = (program) => program.command("deploy [filter]", "Deploy yo
44
44
  Colors.line(`No stacks found matching ${blue(args.filter)}`);
45
45
  process.exit(1);
46
46
  }
47
- const component = render(React.createElement(DeploymentUI, { stacks: assembly.stacks.map((s) => s.stackName) }));
47
+ const component = render(React.createElement(DeploymentUI, { assembly: assembly }));
48
48
  const results = await Stacks.deployMany(assembly.stacks);
49
49
  component.clear();
50
50
  component.unmount();
@@ -39,16 +39,18 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
39
39
  const colors = ["#01cdfe", "#ff71ce", "#05ffa1", "#b967ff"];
40
40
  let index = 0;
41
41
  const pending = new Map();
42
- function start(requestID) {
42
+ function prefix(requestID) {
43
+ const exists = pending.get(requestID);
44
+ if (exists) {
45
+ return Colors.hex(exists.color)(Colors.prefix);
46
+ }
43
47
  pending.set(requestID, {
44
48
  requestID,
45
49
  started: Date.now(),
46
50
  color: colors[index % colors.length],
47
51
  });
48
52
  index++;
49
- }
50
- function prefix(requestID) {
51
- return Colors.hex(pending.get(requestID).color)(Colors.prefix);
53
+ return prefix(requestID);
52
54
  }
53
55
  function end(requestID) {
54
56
  // index--;
@@ -56,7 +58,6 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
56
58
  pending.delete(requestID);
57
59
  }
58
60
  bus.subscribe("function.invoked", async (evt) => {
59
- start(evt.properties.requestID);
60
61
  Colors.line(prefix(evt.properties.requestID), Colors.dim.bold("Invoked"), Colors.dim(useFunctions().fromID(evt.properties.functionID).handler));
61
62
  });
62
63
  bus.subscribe("worker.stdout", async (evt) => {
@@ -160,7 +161,7 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
160
161
  pending = undefined;
161
162
  if (lastDeployed)
162
163
  console.log();
163
- const component = render(React.createElement(DeploymentUI, { stacks: assembly.stacks.map((s) => s.stackName) }));
164
+ const component = render(React.createElement(DeploymentUI, { assembly: assembly }));
164
165
  const results = await Stacks.deployMany(assembly.stacks);
165
166
  component.clear();
166
167
  component.unmount();
@@ -18,7 +18,6 @@ export const usePothosBuilder = Context.memo(() => {
18
18
  await fs.writeFile(route.output, schema);
19
19
  // bus.publish("pothos.extracted", { file: route.output });
20
20
  await Promise.all(route.commands.map((cmd) => execAsync(cmd)));
21
- Colors.line(Colors.prefix);
22
21
  Colors.line(Colors.success(`✔`), " Extracted pothos schema");
23
22
  }
24
23
  catch (ex) {
@@ -32,7 +32,7 @@ export const remove = (program) => program.command("remove [filter]", "Remove yo
32
32
  console.log(`No stacks found matching ${blue(args.filter)}`);
33
33
  process.exit(1);
34
34
  }
35
- const component = render(React.createElement(DeploymentUI, { stacks: assembly.stacks.map((s) => s.stackName) }));
35
+ const component = render(React.createElement(DeploymentUI, { assembly: assembly }));
36
36
  const results = await Stacks.removeMany(target);
37
37
  component.clear();
38
38
  component.unmount();
@@ -1,8 +1,8 @@
1
1
  /// <reference types="react" resolution-mode="require"/>
2
2
  import { Stacks } from "../../stacks/index.js";
3
- import { CloudAssembly } from "aws-cdk-lib/cx-api";
3
+ import type { CloudAssembly } from "aws-cdk-lib/cx-api";
4
4
  interface Props {
5
- stacks: string[];
5
+ assembly: CloudAssembly;
6
6
  }
7
7
  export declare const DeploymentUI: (props: Props) => JSX.Element;
8
8
  export declare function printDeploymentResults(assembly: CloudAssembly, results: Awaited<ReturnType<typeof Stacks.deployMany>>): void;
package/cli/ui/deploy.js CHANGED
@@ -4,13 +4,12 @@ import { useBus } from "../../bus.js";
4
4
  import { Stacks } from "../../stacks/index.js";
5
5
  import inkSpinner from "ink-spinner";
6
6
  import { Colors } from "../colors.js";
7
+ import { useProject } from "../../project.js";
7
8
  // @ts-ignore
8
9
  const { default: Spinner } = inkSpinner;
9
10
  export const DeploymentUI = (props) => {
10
11
  const [resources, setResources] = useState({});
11
12
  useEffect(() => {
12
- Colors.gap();
13
- Colors.line(`${Colors.primary(`➜`)} ${Colors.bold(`Deploying...`)}`);
14
13
  Colors.gap();
15
14
  const bus = useBus();
16
15
  const event = bus.subscribe("stack.event", (payload) => {
@@ -19,7 +18,10 @@ export const DeploymentUI = (props) => {
19
18
  return;
20
19
  setResources((previous) => {
21
20
  if (Stacks.isFinal(event.ResourceStatus)) {
22
- Colors.line(Colors.warning(Colors.prefix), Colors.dim(`${event.StackName} ${event.ResourceType} ${event.LogicalResourceId}`), Stacks.isFailed(event.ResourceStatus)
21
+ const readable = logicalIdToCdkPath(props.assembly, event.StackName, event.LogicalResourceId);
22
+ Colors.line(Colors.warning(Colors.prefix), readable
23
+ ? Colors.dim(`${stackNameToId(event.StackName)} ${readable} ${event.ResourceType}`)
24
+ : Colors.dim(`${stackNameToId(event.StackName)} ${event.ResourceType}`), Stacks.isFailed(event.ResourceStatus)
23
25
  ? Colors.danger(event.ResourceStatus)
24
26
  : Colors.dim(event.ResourceStatus));
25
27
  const { [event.LogicalResourceId]: _, ...next } = previous;
@@ -44,64 +46,72 @@ export const DeploymentUI = (props) => {
44
46
  }
45
47
  return (React.createElement(Box, { flexDirection: "column" },
46
48
  Object.entries(resources).map(([_, evt]) => {
49
+ const readable = logicalIdToCdkPath(props.assembly, evt.StackName, evt.LogicalResourceId);
47
50
  return (React.createElement(Box, { key: evt.LogicalResourceId },
48
51
  React.createElement(Text, null,
49
52
  React.createElement(Spinner, null),
50
53
  " ",
51
- evt.StackName,
52
- " ",
53
- evt.ResourceType,
54
- " ",
55
- evt.LogicalResourceId,
54
+ readable
55
+ ? `${stackNameToId(evt.StackName)} ${readable} ${evt.ResourceType}`
56
+ : `${stackNameToId(evt.StackName)} ${evt.ResourceType}`,
56
57
  " "),
57
58
  React.createElement(Text, { color: color(evt.ResourceStatus || "") }, evt.ResourceStatus)));
58
59
  }),
59
60
  Object.entries(resources).length === 0 && (React.createElement(Box, null,
60
61
  React.createElement(Text, null,
61
62
  React.createElement(Spinner, null),
62
- " ")))));
63
+ " ",
64
+ React.createElement(Text, { dimColor: true }, "Deploying..."))))));
63
65
  };
64
66
  export function printDeploymentResults(assembly, results) {
65
- Colors.gap();
66
- Colors.line(Colors.success(`✔`), Colors.bold(` Deployed`));
67
- for (const [stack, result] of Object.entries(results)) {
68
- if (Object.values(result.errors).length)
69
- continue;
70
- const outputs = Object.entries(result.outputs).filter(([key, _]) => {
71
- if (key.startsWith("Export"))
72
- return false;
73
- if (key.includes("SstSiteEnv"))
74
- return false;
75
- if (key === "SSTMetadata")
76
- return false;
77
- return true;
78
- });
79
- Colors.line(` ${Colors.dim(stack)}`);
80
- if (outputs.length > 0) {
81
- for (const key of Object.keys(Object.fromEntries(outputs)).sort()) {
82
- const value = result.outputs[key];
83
- Colors.line(` ${Colors.bold.dim(key)}: ${value}`);
67
+ // Print success stacks
68
+ const success = Object.entries(results).filter(([_stack, result]) => Object.keys(result.errors).length === 0);
69
+ if (success.length) {
70
+ Colors.gap();
71
+ Colors.line(Colors.success(`✔`), Colors.bold(` Deployed:`));
72
+ for (const [stack, result] of success) {
73
+ const outputs = Object.entries(result.outputs).filter(([key, _]) => {
74
+ if (key.startsWith("Export"))
75
+ return false;
76
+ if (key.includes("SstSiteEnv"))
77
+ return false;
78
+ if (key === "SSTMetadata")
79
+ return false;
80
+ return true;
81
+ });
82
+ Colors.line(` ${Colors.dim(stackNameToId(stack))}`);
83
+ if (outputs.length > 0) {
84
+ for (const key of Object.keys(Object.fromEntries(outputs)).sort()) {
85
+ const value = result.outputs[key];
86
+ Colors.line(` ${Colors.bold.dim(key + ":")} ${value}`);
87
+ }
84
88
  }
85
89
  }
86
90
  }
87
- Colors.gap();
88
- if (Object.values(results).flatMap((s) => Object.keys(s.errors)).length) {
91
+ // Print failed stacks
92
+ const failed = Object.entries(results).filter(([_stack, result]) => Object.keys(result.errors).length > 0);
93
+ if (failed.length) {
94
+ Colors.gap();
89
95
  Colors.line(`${Colors.danger(`✖`)} ${Colors.bold.dim(`Errors`)}`);
90
- for (const [stack, result] of Object.entries(results)) {
91
- const hasErrors = Object.entries(result.errors).length > 0;
92
- if (!hasErrors)
93
- continue;
94
- Colors.line(` ${Colors.dim(stack)}`);
96
+ for (const [stack, result] of failed) {
97
+ Colors.line(` ${Colors.dim(stackNameToId(stack))}`);
95
98
  for (const [id, error] of Object.entries(result.errors)) {
96
- const found = Object.entries(assembly.manifest.artifacts?.[stack].metadata || {}).find(([_key, value]) => value[0]?.type === "aws:cdk:logicalId" && value[0]?.data === id)?.[0] || "";
97
- const readable = found
98
- .split("/")
99
- .filter(Boolean)
100
- .slice(1, -1)
101
- .join("/");
102
- Colors.line(` ${Colors.danger.bold(readable)}: ${error}`);
99
+ const readable = logicalIdToCdkPath(assembly, stack, id) || id;
100
+ Colors.line(` ${Colors.danger.bold(readable + ":")} ${error}`);
103
101
  }
104
102
  }
105
103
  Colors.gap();
106
104
  }
107
105
  }
106
+ function stackNameToId(stack) {
107
+ const project = useProject();
108
+ const prefix = `${project.config.stage}-${project.config.name}-`;
109
+ return stack.startsWith(prefix) ? stack.substring(prefix.length) : stack;
110
+ }
111
+ function logicalIdToCdkPath(assembly, stack, logicalId) {
112
+ const found = Object.entries(assembly.manifest.artifacts?.[stack].metadata || {}).find(([_key, value]) => value[0]?.type === "aws:cdk:logicalId" && value[0]?.data === logicalId)?.[0];
113
+ if (!found) {
114
+ return;
115
+ }
116
+ return found.split("/").filter(Boolean).slice(1, -1).join("/");
117
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sst",
3
- "version": "2.0.0-rc.44",
3
+ "version": "2.0.0-rc.46",
4
4
  "bin": {
5
5
  "sst": "cli/sst.js"
6
6
  },
package/sst.mjs CHANGED
@@ -3861,7 +3861,7 @@ async function synth(opts) {
3861
3861
  if (missing && missing.length) {
3862
3862
  const next = missing.map((x) => x.key);
3863
3863
  if (next.length === previous2.size && next.every((x) => previous2.has(x)))
3864
- throw new VisibleError(`Could not resolve context values for ${next}`);
3864
+ throw new VisibleError(formatErrorMessage(next.join("")));
3865
3865
  Logger.debug("Looking up context for:", next, "Previous:", previous2);
3866
3866
  previous2 = new Set(next);
3867
3867
  await contextproviders.provideContextValues(
@@ -3878,6 +3878,21 @@ async function synth(opts) {
3878
3878
  return assembly;
3879
3879
  }
3880
3880
  }
3881
+ function formatErrorMessage(message) {
3882
+ return formatCustomDomainError(message) || `Could not resolve context values for ${message}`;
3883
+ }
3884
+ function formatCustomDomainError(message) {
3885
+ const ret = message.match(/hosted-zone:account=\d+:domainName=(\S+):/);
3886
+ if (!ret) {
3887
+ return;
3888
+ }
3889
+ const hostedZone = ret && ret[1];
3890
+ return [
3891
+ `It seems you are configuring custom domains for you URL.`,
3892
+ hostedZone ? `And SST is not able to find the hosted zone "${hostedZone}" in your AWS Route 53 account.` : `And SST is not able to find the hosted zone in your AWS Route 53 account.`,
3893
+ `Please double check and make sure the zone exists, or pass in a different zone.`
3894
+ ].join(" ");
3895
+ }
3881
3896
  var init_synth = __esm({
3882
3897
  "src/stacks/synth.ts"() {
3883
3898
  "use strict";
@@ -5122,49 +5137,63 @@ import React, { useState, useEffect } from "react";
5122
5137
  import { Box, Text } from "ink";
5123
5138
  import inkSpinner from "ink-spinner";
5124
5139
  function printDeploymentResults(assembly, results) {
5125
- Colors.gap();
5126
- Colors.line(Colors.success(`\u2714`), Colors.bold(` Deployed`));
5127
- for (const [stack, result] of Object.entries(results)) {
5128
- if (Object.values(result.errors).length)
5129
- continue;
5130
- const outputs = Object.entries(result.outputs).filter(([key, _]) => {
5131
- if (key.startsWith("Export"))
5132
- return false;
5133
- if (key.includes("SstSiteEnv"))
5134
- return false;
5135
- if (key === "SSTMetadata")
5136
- return false;
5137
- return true;
5138
- });
5139
- Colors.line(` ${Colors.dim(stack)}`);
5140
- if (outputs.length > 0) {
5141
- for (const key of Object.keys(Object.fromEntries(outputs)).sort()) {
5142
- const value = result.outputs[key];
5143
- Colors.line(` ${Colors.bold.dim(key)}: ${value}`);
5140
+ const success = Object.entries(results).filter(
5141
+ ([_stack, result]) => Object.keys(result.errors).length === 0
5142
+ );
5143
+ if (success.length) {
5144
+ Colors.gap();
5145
+ Colors.line(Colors.success(`\u2714`), Colors.bold(` Deployed:`));
5146
+ for (const [stack, result] of success) {
5147
+ const outputs = Object.entries(result.outputs).filter(([key, _]) => {
5148
+ if (key.startsWith("Export"))
5149
+ return false;
5150
+ if (key.includes("SstSiteEnv"))
5151
+ return false;
5152
+ if (key === "SSTMetadata")
5153
+ return false;
5154
+ return true;
5155
+ });
5156
+ Colors.line(` ${Colors.dim(stackNameToId(stack))}`);
5157
+ if (outputs.length > 0) {
5158
+ for (const key of Object.keys(Object.fromEntries(outputs)).sort()) {
5159
+ const value = result.outputs[key];
5160
+ Colors.line(` ${Colors.bold.dim(key + ":")} ${value}`);
5161
+ }
5144
5162
  }
5145
5163
  }
5146
5164
  }
5147
- Colors.gap();
5148
- if (Object.values(results).flatMap((s) => Object.keys(s.errors)).length) {
5165
+ const failed = Object.entries(results).filter(
5166
+ ([_stack, result]) => Object.keys(result.errors).length > 0
5167
+ );
5168
+ if (failed.length) {
5169
+ Colors.gap();
5149
5170
  Colors.line(`${Colors.danger(`\u2716`)} ${Colors.bold.dim(`Errors`)}`);
5150
- for (const [stack, result] of Object.entries(results)) {
5151
- const hasErrors = Object.entries(result.errors).length > 0;
5152
- if (!hasErrors)
5153
- continue;
5154
- Colors.line(` ${Colors.dim(stack)}`);
5171
+ for (const [stack, result] of failed) {
5172
+ Colors.line(` ${Colors.dim(stackNameToId(stack))}`);
5155
5173
  for (const [id, error2] of Object.entries(result.errors)) {
5156
- const found = Object.entries(
5157
- assembly.manifest.artifacts?.[stack].metadata || {}
5158
- ).find(
5159
- ([_key, value]) => value[0]?.type === "aws:cdk:logicalId" && value[0]?.data === id
5160
- )?.[0] || "";
5161
- const readable = found.split("/").filter(Boolean).slice(1, -1).join("/");
5162
- Colors.line(` ${Colors.danger.bold(readable)}: ${error2}`);
5174
+ const readable = logicalIdToCdkPath(assembly, stack, id) || id;
5175
+ Colors.line(` ${Colors.danger.bold(readable + ":")} ${error2}`);
5163
5176
  }
5164
5177
  }
5165
5178
  Colors.gap();
5166
5179
  }
5167
5180
  }
5181
+ function stackNameToId(stack) {
5182
+ const project = useProject();
5183
+ const prefix = `${project.config.stage}-${project.config.name}-`;
5184
+ return stack.startsWith(prefix) ? stack.substring(prefix.length) : stack;
5185
+ }
5186
+ function logicalIdToCdkPath(assembly, stack, logicalId) {
5187
+ const found = Object.entries(
5188
+ assembly.manifest.artifacts?.[stack].metadata || {}
5189
+ ).find(
5190
+ ([_key, value]) => value[0]?.type === "aws:cdk:logicalId" && value[0]?.data === logicalId
5191
+ )?.[0];
5192
+ if (!found) {
5193
+ return;
5194
+ }
5195
+ return found.split("/").filter(Boolean).slice(1, -1).join("/");
5196
+ }
5168
5197
  var Spinner, DeploymentUI;
5169
5198
  var init_deploy2 = __esm({
5170
5199
  "src/cli/ui/deploy.tsx"() {
@@ -5172,12 +5201,11 @@ var init_deploy2 = __esm({
5172
5201
  init_bus();
5173
5202
  init_stacks();
5174
5203
  init_colors();
5204
+ init_project();
5175
5205
  ({ default: Spinner } = inkSpinner);
5176
5206
  DeploymentUI = (props) => {
5177
5207
  const [resources, setResources] = useState({});
5178
5208
  useEffect(() => {
5179
- Colors.gap();
5180
- Colors.line(`${Colors.primary(`\u279C`)} ${Colors.bold(`Deploying...`)}`);
5181
5209
  Colors.gap();
5182
5210
  const bus = useBus();
5183
5211
  const event = bus.subscribe("stack.event", (payload) => {
@@ -5186,10 +5214,17 @@ var init_deploy2 = __esm({
5186
5214
  return;
5187
5215
  setResources((previous2) => {
5188
5216
  if (stacks_exports.isFinal(event2.ResourceStatus)) {
5217
+ const readable = logicalIdToCdkPath(
5218
+ props.assembly,
5219
+ event2.StackName,
5220
+ event2.LogicalResourceId
5221
+ );
5189
5222
  Colors.line(
5190
5223
  Colors.warning(Colors.prefix),
5191
- Colors.dim(
5192
- `${event2.StackName} ${event2.ResourceType} ${event2.LogicalResourceId}`
5224
+ readable ? Colors.dim(
5225
+ `${stackNameToId(event2.StackName)} ${readable} ${event2.ResourceType}`
5226
+ ) : Colors.dim(
5227
+ `${stackNameToId(event2.StackName)} ${event2.ResourceType}`
5193
5228
  ),
5194
5229
  stacks_exports.isFailed(event2.ResourceStatus) ? Colors.danger(event2.ResourceStatus) : Colors.dim(event2.ResourceStatus)
5195
5230
  );
@@ -5214,8 +5249,13 @@ var init_deploy2 = __esm({
5214
5249
  return "yellow";
5215
5250
  }
5216
5251
  return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, Object.entries(resources).map(([_, evt]) => {
5217
- return /* @__PURE__ */ React.createElement(Box, { key: evt.LogicalResourceId }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Spinner, null), " ", evt.StackName, " ", evt.ResourceType, " ", evt.LogicalResourceId, " "), /* @__PURE__ */ React.createElement(Text, { color: color(evt.ResourceStatus || "") }, evt.ResourceStatus));
5218
- }), Object.entries(resources).length === 0 && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Spinner, null), " ")));
5252
+ const readable = logicalIdToCdkPath(
5253
+ props.assembly,
5254
+ evt.StackName,
5255
+ evt.LogicalResourceId
5256
+ );
5257
+ return /* @__PURE__ */ React.createElement(Box, { key: evt.LogicalResourceId }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Spinner, null), " ", readable ? `${stackNameToId(evt.StackName)} ${readable} ${evt.ResourceType}` : `${stackNameToId(evt.StackName)} ${evt.ResourceType}`, " "), /* @__PURE__ */ React.createElement(Text, { color: color(evt.ResourceStatus || "") }, evt.ResourceStatus));
5258
+ }), Object.entries(resources).length === 0 && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Spinner, null), " ", /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Deploying..."))));
5219
5259
  };
5220
5260
  }
5221
5261
  });
@@ -5410,7 +5450,6 @@ var init_pothos2 = __esm({
5410
5450
  });
5411
5451
  await fs15.writeFile(route.output, schema);
5412
5452
  await Promise.all(route.commands.map((cmd) => execAsync4(cmd)));
5413
- Colors.line(Colors.prefix);
5414
5453
  Colors.line(Colors.success(`\u2714`), " Extracted pothos schema");
5415
5454
  } catch (ex) {
5416
5455
  Colors.line(Colors.danger(`\u2716`), " Failed to extract schema from pothos:");
@@ -5975,22 +6014,23 @@ var dev = (program2) => program2.command(
5975
6014
  const colors = ["#01cdfe", "#ff71ce", "#05ffa1", "#b967ff"];
5976
6015
  let index = 0;
5977
6016
  const pending = /* @__PURE__ */ new Map();
5978
- function start(requestID) {
6017
+ function prefix(requestID) {
6018
+ const exists = pending.get(requestID);
6019
+ if (exists) {
6020
+ return Colors.hex(exists.color)(Colors.prefix);
6021
+ }
5979
6022
  pending.set(requestID, {
5980
6023
  requestID,
5981
6024
  started: Date.now(),
5982
6025
  color: colors[index % colors.length]
5983
6026
  });
5984
6027
  index++;
5985
- }
5986
- function prefix(requestID) {
5987
- return Colors.hex(pending.get(requestID).color)(Colors.prefix);
6028
+ return prefix(requestID);
5988
6029
  }
5989
6030
  function end(requestID) {
5990
6031
  pending.delete(requestID);
5991
6032
  }
5992
6033
  bus.subscribe("function.invoked", async (evt) => {
5993
- start(evt.properties.requestID);
5994
6034
  Colors.line(
5995
6035
  prefix(evt.properties.requestID),
5996
6036
  Colors.dim.bold("Invoked"),
@@ -6118,7 +6158,7 @@ var dev = (program2) => program2.command(
6118
6158
  if (lastDeployed)
6119
6159
  console.log();
6120
6160
  const component = render(
6121
- /* @__PURE__ */ React2.createElement(DeploymentUI2, { stacks: assembly.stacks.map((s) => s.stackName) })
6161
+ /* @__PURE__ */ React2.createElement(DeploymentUI2, { assembly })
6122
6162
  );
6123
6163
  const results = await Stacks.deployMany(assembly.stacks);
6124
6164
  component.clear();
@@ -6301,7 +6341,7 @@ var deploy2 = (program2) => program2.command(
6301
6341
  process.exit(1);
6302
6342
  }
6303
6343
  const component = render(
6304
- /* @__PURE__ */ React2.createElement(DeploymentUI2, { stacks: assembly.stacks.map((s) => s.stackName) })
6344
+ /* @__PURE__ */ React2.createElement(DeploymentUI2, { assembly })
6305
6345
  );
6306
6346
  const results = await Stacks.deployMany(assembly.stacks);
6307
6347
  component.clear();
@@ -6358,7 +6398,7 @@ var remove2 = (program2) => program2.command(
6358
6398
  process.exit(1);
6359
6399
  }
6360
6400
  const component = render(
6361
- /* @__PURE__ */ React2.createElement(DeploymentUI2, { stacks: assembly.stacks.map((s) => s.stackName) })
6401
+ /* @__PURE__ */ React2.createElement(DeploymentUI2, { assembly })
6362
6402
  );
6363
6403
  const results = await Stacks.removeMany(target);
6364
6404
  component.clear();
package/stacks/synth.js CHANGED
@@ -58,7 +58,7 @@ export async function synth(opts) {
58
58
  if (missing && missing.length) {
59
59
  const next = missing.map((x) => x.key);
60
60
  if (next.length === previous.size && next.every((x) => previous.has(x)))
61
- throw new VisibleError(`Could not resolve context values for ${next}`);
61
+ throw new VisibleError(formatErrorMessage(next.join("")));
62
62
  Logger.debug("Looking up context for:", next, "Previous:", previous);
63
63
  previous = new Set(next);
64
64
  await contextproviders.provideContextValues(missing, cfg.context, provider);
@@ -71,3 +71,21 @@ export async function synth(opts) {
71
71
  return assembly;
72
72
  }
73
73
  }
74
+ function formatErrorMessage(message) {
75
+ return formatCustomDomainError(message)
76
+ || `Could not resolve context values for ${message}`;
77
+ }
78
+ function formatCustomDomainError(message) {
79
+ const ret = message.match(/hosted-zone:account=\d+:domainName=(\S+):/);
80
+ if (!ret) {
81
+ return;
82
+ }
83
+ const hostedZone = ret && ret[1];
84
+ return [
85
+ `It seems you are configuring custom domains for you URL.`,
86
+ hostedZone
87
+ ? `And SST is not able to find the hosted zone "${hostedZone}" in your AWS Route 53 account.`
88
+ : `And SST is not able to find the hosted zone in your AWS Route 53 account.`,
89
+ `Please double check and make sure the zone exists, or pass in a different zone.`,
90
+ ].join(" ");
91
+ }