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.
- package/bootstrap.js +1 -0
- package/cli/commands/bind.js +302 -293
- package/cli/commands/bootstrap.js +8 -2
- package/cli/commands/build.js +16 -10
- package/cli/commands/connect.js +41 -34
- package/cli/commands/console.js +17 -11
- package/cli/commands/deploy.js +83 -72
- package/cli/commands/dev.js +294 -277
- package/cli/commands/diff.js +64 -58
- package/cli/commands/remove.js +46 -36
- package/cli/commands/secrets/get.d.ts +1 -1
- package/cli/commands/secrets/get.js +4 -1
- package/cli/commands/secrets/list.js +58 -51
- package/cli/commands/secrets/load.js +34 -28
- package/cli/commands/secrets/remove.js +4 -0
- package/cli/commands/secrets/secrets.d.ts +1 -1
- package/cli/commands/secrets/secrets.js +5 -5
- package/cli/commands/secrets/set.js +32 -26
- package/cli/commands/telemetry.js +13 -6
- package/cli/commands/transform.js +12 -5
- package/cli/commands/types.js +18 -12
- package/cli/commands/update.js +94 -88
- package/cli/commands/version.js +12 -5
- package/cli/program.d.ts +4 -0
- package/cli/program.js +36 -1
- package/cli/sst.js +8 -7
- package/cli/telemetry/telemetry.d.ts +16 -1
- package/cli/telemetry/telemetry.js +13 -3
- package/constructs/App.js +2 -5
- package/constructs/Function.js +1 -1
- package/constructs/SsrSite.js +1 -1
- package/constructs/deprecated/NextjsSite.js +3 -4
- package/error.d.ts +3 -0
- package/error.js +5 -0
- package/node/api/index.d.ts +4 -0
- package/node/api/index.js +17 -1
- package/node/future/auth/session.js +1 -3
- package/package.json +1 -1
package/cli/commands/dev.js
CHANGED
|
@@ -12,6 +12,7 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
|
|
|
12
12
|
const { useBus } = await import("../../bus.js");
|
|
13
13
|
const { useWatcher } = await import("../../watcher.js");
|
|
14
14
|
const { useAppMetadata, saveAppMetadata, Stacks } = await import("../../stacks/index.js");
|
|
15
|
+
const { exit, exitWithError, trackDevError, trackDevRunning } = await import("../program.js");
|
|
15
16
|
const { Logger } = await import("../../logger.js");
|
|
16
17
|
const { createSpinner } = await import("../spinner.js");
|
|
17
18
|
const { bold, dim, yellow } = await import("colorette");
|
|
@@ -32,302 +33,318 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
|
|
|
32
33
|
const { useIOT } = await import("../../iot.js");
|
|
33
34
|
const { clear } = await import("../terminal.js");
|
|
34
35
|
const { getCiInfo } = await import("../ci-info.js");
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const project = useProject();
|
|
39
|
-
const useFunctionLogger = Context.memo(async () => {
|
|
40
|
-
const bus = useBus();
|
|
41
|
-
const colors = ["#01cdfe", "#ff71ce", "#05ffa1", "#b967ff"];
|
|
42
|
-
let index = 0;
|
|
43
|
-
const pending = new Map();
|
|
44
|
-
function prefix(requestID) {
|
|
45
|
-
const exists = pending.get(requestID);
|
|
46
|
-
if (exists) {
|
|
47
|
-
return Colors.hex(exists.color)(Colors.prefix);
|
|
48
|
-
}
|
|
49
|
-
pending.set(requestID, {
|
|
50
|
-
requestID,
|
|
51
|
-
started: Date.now(),
|
|
52
|
-
color: colors[index % colors.length],
|
|
53
|
-
});
|
|
54
|
-
index++;
|
|
55
|
-
return prefix(requestID);
|
|
36
|
+
try {
|
|
37
|
+
if (args._[0] === "start") {
|
|
38
|
+
console.log(yellow(`Warning: ${bold(`sst start`)} has been renamed to ${bold(`sst dev`)}`));
|
|
56
39
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
prefix(evt.properties.requestID);
|
|
68
|
-
const { started } = pending.get(evt.properties.requestID);
|
|
69
|
-
for (let line of evt.properties.message.split("\n")) {
|
|
70
|
-
// Remove prefix from container logs
|
|
71
|
-
if (info?.runtime === "container") {
|
|
72
|
-
// handle Node.js container logs
|
|
73
|
-
// ie. 2023-07-05T00:13:42.448Z\td7330533-2429-4871-a632-ed29a1d32246\tINFO\tfoo!
|
|
74
|
-
const parts = line.split("\t");
|
|
75
|
-
if (parts.length >= 4 &&
|
|
76
|
-
Date.parse(parts[0]) &&
|
|
77
|
-
parts[1].length === 36) {
|
|
78
|
-
line = parts.slice(3).join("\t");
|
|
79
|
-
}
|
|
40
|
+
const project = useProject();
|
|
41
|
+
const useFunctionLogger = Context.memo(async () => {
|
|
42
|
+
const bus = useBus();
|
|
43
|
+
const colors = ["#01cdfe", "#ff71ce", "#05ffa1", "#b967ff"];
|
|
44
|
+
let index = 0;
|
|
45
|
+
const pending = new Map();
|
|
46
|
+
function prefix(requestID) {
|
|
47
|
+
const exists = pending.get(requestID);
|
|
48
|
+
if (exists) {
|
|
49
|
+
return Colors.hex(exists.color)(Colors.prefix);
|
|
80
50
|
}
|
|
81
|
-
|
|
51
|
+
pending.set(requestID, {
|
|
52
|
+
requestID,
|
|
53
|
+
started: Date.now(),
|
|
54
|
+
color: colors[index % colors.length],
|
|
55
|
+
});
|
|
56
|
+
index++;
|
|
57
|
+
return prefix(requestID);
|
|
82
58
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return;
|
|
88
|
-
if (info.enableLiveDev === false)
|
|
89
|
-
return;
|
|
90
|
-
if (info.runtime !== "container")
|
|
91
|
-
return;
|
|
92
|
-
Colors.line(Colors.dim(Colors.prefix, "Building", info.handler, "container"));
|
|
93
|
-
});
|
|
94
|
-
bus.subscribe("function.build.success", async (evt) => {
|
|
95
|
-
const info = useFunctions().fromID(evt.properties.functionID);
|
|
96
|
-
if (!info)
|
|
97
|
-
return;
|
|
98
|
-
if (info.enableLiveDev === false)
|
|
99
|
-
return;
|
|
100
|
-
Colors.line(info.runtime === "container"
|
|
101
|
-
? Colors.dim(Colors.prefix, "Built", info.handler, "container")
|
|
102
|
-
: Colors.dim(Colors.prefix, "Built", info.handler));
|
|
103
|
-
});
|
|
104
|
-
bus.subscribe("function.build.failed", async (evt) => {
|
|
105
|
-
const info = useFunctions().fromID(evt.properties.functionID);
|
|
106
|
-
if (!info)
|
|
107
|
-
return;
|
|
108
|
-
if (info.enableLiveDev === false)
|
|
109
|
-
return;
|
|
110
|
-
Colors.gap();
|
|
111
|
-
Colors.line(Colors.danger("✖ "), "Build failed", info.handler);
|
|
112
|
-
for (const line of evt.properties.errors) {
|
|
113
|
-
Colors.line(" ", line);
|
|
59
|
+
function end(requestID) {
|
|
60
|
+
// index--;
|
|
61
|
+
// if (index < 0) index = colors.length - 1;
|
|
62
|
+
pending.delete(requestID);
|
|
114
63
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
64
|
+
bus.subscribe("function.invoked", async (evt) => {
|
|
65
|
+
Colors.line(prefix(evt.properties.requestID), Colors.dim.bold("Invoked"), Colors.dim(useFunctions().fromID(evt.properties.functionID)?.handler));
|
|
66
|
+
});
|
|
67
|
+
bus.subscribe("worker.stdout", async (evt) => {
|
|
68
|
+
const info = useFunctions().fromID(evt.properties.functionID);
|
|
69
|
+
prefix(evt.properties.requestID);
|
|
70
|
+
const { started } = pending.get(evt.properties.requestID);
|
|
71
|
+
for (let line of evt.properties.message.split("\n")) {
|
|
72
|
+
// Remove prefix from container logs
|
|
73
|
+
if (info?.runtime === "container") {
|
|
74
|
+
// handle Node.js container logs
|
|
75
|
+
// ie. 2023-07-05T00:13:42.448Z\td7330533-2429-4871-a632-ed29a1d32246\tINFO\tfoo!
|
|
76
|
+
const parts = line.split("\t");
|
|
77
|
+
if (parts.length >= 4 &&
|
|
78
|
+
Date.parse(parts[0]) &&
|
|
79
|
+
parts[1].length === 36) {
|
|
80
|
+
line = parts.slice(3).join("\t");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
Colors.line(prefix(evt.properties.requestID), Colors.dim(("+" + (Date.now() - started) + "ms").padEnd(7)), Colors.dim(line));
|
|
134
84
|
}
|
|
135
|
-
|
|
136
|
-
|
|
85
|
+
});
|
|
86
|
+
bus.subscribe("function.build.started", async (evt) => {
|
|
87
|
+
const info = useFunctions().fromID(evt.properties.functionID);
|
|
88
|
+
if (!info)
|
|
89
|
+
return;
|
|
90
|
+
if (info.enableLiveDev === false)
|
|
91
|
+
return;
|
|
92
|
+
if (info.runtime !== "container")
|
|
93
|
+
return;
|
|
94
|
+
Colors.line(Colors.dim(Colors.prefix, "Building", info.handler, "container"));
|
|
95
|
+
});
|
|
96
|
+
bus.subscribe("function.build.success", async (evt) => {
|
|
97
|
+
const info = useFunctions().fromID(evt.properties.functionID);
|
|
98
|
+
if (!info)
|
|
99
|
+
return;
|
|
100
|
+
if (info.enableLiveDev === false)
|
|
101
|
+
return;
|
|
102
|
+
Colors.line(info.runtime === "container"
|
|
103
|
+
? Colors.dim(Colors.prefix, "Built", info.handler, "container")
|
|
104
|
+
: Colors.dim(Colors.prefix, "Built", info.handler));
|
|
105
|
+
});
|
|
106
|
+
bus.subscribe("function.build.failed", async (evt) => {
|
|
107
|
+
const info = useFunctions().fromID(evt.properties.functionID);
|
|
108
|
+
if (!info)
|
|
109
|
+
return;
|
|
110
|
+
if (info.enableLiveDev === false)
|
|
111
|
+
return;
|
|
112
|
+
Colors.gap();
|
|
113
|
+
Colors.line(Colors.danger("✖ "), "Build failed", info.handler);
|
|
114
|
+
for (const line of evt.properties.errors) {
|
|
115
|
+
Colors.line(" ", line);
|
|
116
|
+
}
|
|
117
|
+
Colors.gap();
|
|
118
|
+
});
|
|
119
|
+
bus.subscribe("function.success", async (evt) => {
|
|
120
|
+
// stdout logs sometimes come in after
|
|
121
|
+
const p = prefix(evt.properties.requestID);
|
|
122
|
+
const req = pending.get(evt.properties.requestID);
|
|
123
|
+
setTimeout(() => {
|
|
124
|
+
Colors.line(p, Colors.dim(`Done in ${Date.now() - req.started - 100}ms`));
|
|
125
|
+
end(evt.properties.requestID);
|
|
126
|
+
}, 100);
|
|
127
|
+
});
|
|
128
|
+
bus.subscribe("function.error", async (evt) => {
|
|
129
|
+
setTimeout(() => {
|
|
130
|
+
Colors.line(prefix(evt.properties.requestID), Colors.danger.bold("Error:"), Colors.danger.bold(evt.properties.errorMessage));
|
|
131
|
+
for (const line of evt.properties.trace || []) {
|
|
132
|
+
// Skip double printing error message
|
|
133
|
+
if (line.includes(evt.properties.errorMessage))
|
|
134
|
+
continue;
|
|
135
|
+
Colors.line(" ", `${dim(line)}`);
|
|
136
|
+
}
|
|
137
|
+
end(evt.properties.requestID);
|
|
138
|
+
}, 100);
|
|
139
|
+
});
|
|
137
140
|
});
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
isDirty = true;
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
isDirty = false;
|
|
151
|
-
isWorking = true;
|
|
152
|
-
Colors.gap();
|
|
153
|
-
const spinner = createSpinner({
|
|
154
|
-
color: "gray",
|
|
155
|
-
text: lastDeployed ? ` Building...` : dim(` Checking for changes`),
|
|
156
|
-
}).start();
|
|
157
|
-
try {
|
|
158
|
-
const [metafile, sstConfig] = await Stacks.load(project.paths.config);
|
|
159
|
-
project.metafile = metafile;
|
|
160
|
-
project.stacks = sstConfig.stacks;
|
|
161
|
-
const assembly = await Stacks.synth({
|
|
162
|
-
increaseTimeout: args["increase-timeout"],
|
|
163
|
-
scriptVersion,
|
|
164
|
-
fn: project.stacks,
|
|
165
|
-
outDir: `.sst/cdk.out`,
|
|
166
|
-
mode: "dev",
|
|
167
|
-
});
|
|
168
|
-
Logger.debug("Directory", assembly.directory);
|
|
169
|
-
const next = await checksum(assembly.directory);
|
|
170
|
-
Logger.debug("Checksum", "next", next, "old", lastDeployed);
|
|
171
|
-
if (next === lastDeployed) {
|
|
172
|
-
spinner.succeed(Colors.dim(" Built with no changes"));
|
|
173
|
-
isWorking = false;
|
|
174
|
-
if (isDirty)
|
|
175
|
-
build();
|
|
141
|
+
const useStackBuilder = Context.memo(async () => {
|
|
142
|
+
const watcher = useWatcher();
|
|
143
|
+
const scriptVersion = Date.now().toString();
|
|
144
|
+
let lastDeployed;
|
|
145
|
+
let isWorking = false;
|
|
146
|
+
let isDirty = false;
|
|
147
|
+
async function build() {
|
|
148
|
+
if (isWorking) {
|
|
149
|
+
isDirty = true;
|
|
176
150
|
return;
|
|
177
151
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
152
|
+
isDirty = false;
|
|
153
|
+
isWorking = true;
|
|
154
|
+
Colors.gap();
|
|
155
|
+
const spinner = createSpinner({
|
|
156
|
+
color: "gray",
|
|
157
|
+
text: lastDeployed
|
|
158
|
+
? ` Building...`
|
|
159
|
+
: dim(` Checking for changes`),
|
|
160
|
+
}).start();
|
|
161
|
+
try {
|
|
162
|
+
const [metafile, sstConfig] = await Stacks.load(project.paths.config);
|
|
163
|
+
project.metafile = metafile;
|
|
164
|
+
project.stacks = sstConfig.stacks;
|
|
165
|
+
const assembly = await Stacks.synth({
|
|
166
|
+
increaseTimeout: args["increase-timeout"],
|
|
167
|
+
scriptVersion,
|
|
168
|
+
fn: project.stacks,
|
|
169
|
+
outDir: `.sst/cdk.out`,
|
|
170
|
+
mode: "dev",
|
|
171
|
+
});
|
|
172
|
+
Logger.debug("Directory", assembly.directory);
|
|
173
|
+
const next = await checksum(assembly.directory);
|
|
174
|
+
Logger.debug("Checksum", "next", next, "old", lastDeployed);
|
|
175
|
+
if (next === lastDeployed) {
|
|
176
|
+
spinner.succeed(Colors.dim(" Built with no changes"));
|
|
177
|
+
isWorking = false;
|
|
178
|
+
if (isDirty)
|
|
179
|
+
build();
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (!lastDeployed) {
|
|
183
|
+
spinner.stop();
|
|
184
|
+
spinner.clear();
|
|
185
|
+
Colors.mode("gap");
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
spinner.succeed(Colors.dim(` Built`));
|
|
189
|
+
Colors.gap();
|
|
190
|
+
}
|
|
191
|
+
deploy(assembly);
|
|
182
192
|
}
|
|
183
|
-
|
|
184
|
-
|
|
193
|
+
catch (ex) {
|
|
194
|
+
isWorking = false;
|
|
195
|
+
spinner.fail();
|
|
196
|
+
Colors.line(ex.stack
|
|
197
|
+
.split("\n")
|
|
198
|
+
.map((line) => " " + line)
|
|
199
|
+
.join("\n"));
|
|
185
200
|
Colors.gap();
|
|
201
|
+
if (!lastDeployed) {
|
|
202
|
+
trackDevError(ex);
|
|
203
|
+
}
|
|
186
204
|
}
|
|
187
|
-
deploy(assembly);
|
|
188
205
|
}
|
|
189
|
-
|
|
206
|
+
async function deploy(assembly) {
|
|
207
|
+
const nextChecksum = await checksum(assembly.directory);
|
|
208
|
+
const component = render(React.createElement(DeploymentUI, { assembly: assembly }));
|
|
209
|
+
const results = await Stacks.deployMany(assembly.stacks);
|
|
210
|
+
component.clear();
|
|
211
|
+
component.unmount();
|
|
212
|
+
printDeploymentResults(assembly, results);
|
|
213
|
+
// Run after initial deploy
|
|
214
|
+
if (!lastDeployed) {
|
|
215
|
+
await saveAppMetadata({ mode: "dev" });
|
|
216
|
+
// Check failed stacks
|
|
217
|
+
const failed = Object.values(results).find((result) => Stacks.isFailed(result.status));
|
|
218
|
+
failed
|
|
219
|
+
? trackDevError(new Error(`CloudFormation status ${failed.status}`))
|
|
220
|
+
: trackDevRunning();
|
|
221
|
+
// print start frontend commands
|
|
222
|
+
useSites()
|
|
223
|
+
.all.filter(({ props }) => props.dev?.deploy !== true)
|
|
224
|
+
.forEach(({ type, props }) => {
|
|
225
|
+
const framework = type === "AstroSite"
|
|
226
|
+
? "Astro"
|
|
227
|
+
: type === "NextjsSite"
|
|
228
|
+
? "Next.js"
|
|
229
|
+
: type === "RemixSite"
|
|
230
|
+
? "Remix"
|
|
231
|
+
: type === "SolidStartSite"
|
|
232
|
+
? "SolidStart"
|
|
233
|
+
: type === "SvelteKitSite"
|
|
234
|
+
? "SvelteKit"
|
|
235
|
+
: undefined;
|
|
236
|
+
if (framework) {
|
|
237
|
+
const cdCmd = path.resolve(props.path) === process.cwd()
|
|
238
|
+
? ""
|
|
239
|
+
: `cd ${props.path} && `;
|
|
240
|
+
Colors.line(Colors.primary(`➜ `), Colors.bold(`Start ${framework}:`), `${cdCmd}npm run dev`);
|
|
241
|
+
Colors.gap();
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
lastDeployed = nextChecksum;
|
|
246
|
+
// Write outputs.json
|
|
247
|
+
fs.writeFile(project.config.outputs ||
|
|
248
|
+
path.join(project.paths.out, "outputs.json"), JSON.stringify(mapValues(results, (val) => val.outputs), null, 2));
|
|
190
249
|
isWorking = false;
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
.split("\n")
|
|
194
|
-
.map((line) => " " + line)
|
|
195
|
-
.join("\n"));
|
|
196
|
-
Colors.gap();
|
|
250
|
+
if (isDirty)
|
|
251
|
+
build();
|
|
197
252
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
.
|
|
212
|
-
.
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
: type === "NextjsSite"
|
|
216
|
-
? "Next.js"
|
|
217
|
-
: type === "RemixSite"
|
|
218
|
-
? "Remix"
|
|
219
|
-
: type === "SolidStartSite"
|
|
220
|
-
? "SolidStart"
|
|
221
|
-
: type === "SvelteKitSite"
|
|
222
|
-
? "SvelteKit"
|
|
223
|
-
: undefined;
|
|
224
|
-
if (framework) {
|
|
225
|
-
const cdCmd = path.resolve(props.path) === process.cwd()
|
|
226
|
-
? ""
|
|
227
|
-
: `cd ${props.path} && `;
|
|
228
|
-
Colors.line(Colors.primary(`➜ `), Colors.bold(`Start ${framework}:`), `${cdCmd}npm run dev`);
|
|
229
|
-
Colors.gap();
|
|
230
|
-
}
|
|
231
|
-
});
|
|
253
|
+
async function checksum(cdkOutPath) {
|
|
254
|
+
const manifestPath = path.join(cdkOutPath, "manifest.json");
|
|
255
|
+
const cdkManifest = JSON.parse(await fs.readFile(manifestPath).then((x) => x.toString()));
|
|
256
|
+
const checksumData = await Promise.all(Object.keys(cdkManifest.artifacts)
|
|
257
|
+
.filter((key) => cdkManifest.artifacts[key].type ===
|
|
258
|
+
"aws:cloudformation:stack")
|
|
259
|
+
.map(async (key) => {
|
|
260
|
+
const { templateFile } = cdkManifest.artifacts[key].properties;
|
|
261
|
+
const templatePath = path.join(cdkOutPath, templateFile);
|
|
262
|
+
const templateContent = await fs.readFile(templatePath);
|
|
263
|
+
return templateContent;
|
|
264
|
+
})).then((x) => x.join("\n"));
|
|
265
|
+
const hash = crypto
|
|
266
|
+
.createHash("sha256")
|
|
267
|
+
.update(checksumData)
|
|
268
|
+
.digest("hex");
|
|
269
|
+
return hash;
|
|
232
270
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
if (isDirty)
|
|
271
|
+
watcher.subscribe("file.changed", async (evt) => {
|
|
272
|
+
if (!project.metafile)
|
|
273
|
+
return;
|
|
274
|
+
if (!project.metafile.inputs[evt.properties.relative.split(path.sep).join(path.posix.sep)])
|
|
275
|
+
return;
|
|
239
276
|
build();
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
const manifestPath = path.join(cdkOutPath, "manifest.json");
|
|
243
|
-
const cdkManifest = JSON.parse(await fs.readFile(manifestPath).then((x) => x.toString()));
|
|
244
|
-
const checksumData = await Promise.all(Object.keys(cdkManifest.artifacts)
|
|
245
|
-
.filter((key) => cdkManifest.artifacts[key].type === "aws:cloudformation:stack")
|
|
246
|
-
.map(async (key) => {
|
|
247
|
-
const { templateFile } = cdkManifest.artifacts[key].properties;
|
|
248
|
-
const templatePath = path.join(cdkOutPath, templateFile);
|
|
249
|
-
const templateContent = await fs.readFile(templatePath);
|
|
250
|
-
return templateContent;
|
|
251
|
-
})).then((x) => x.join("\n"));
|
|
252
|
-
const hash = crypto
|
|
253
|
-
.createHash("sha256")
|
|
254
|
-
.update(checksumData)
|
|
255
|
-
.digest("hex");
|
|
256
|
-
return hash;
|
|
257
|
-
}
|
|
258
|
-
watcher.subscribe("file.changed", async (evt) => {
|
|
259
|
-
if (!project.metafile)
|
|
260
|
-
return;
|
|
261
|
-
if (!project.metafile.inputs[evt.properties.relative.split(path.sep).join(path.posix.sep)])
|
|
262
|
-
return;
|
|
263
|
-
build();
|
|
264
|
-
});
|
|
265
|
-
await build();
|
|
266
|
-
});
|
|
267
|
-
const useDisconnector = Context.memo(async () => {
|
|
268
|
-
const bus = useBus();
|
|
269
|
-
const iot = await useIOT();
|
|
270
|
-
bus.subscribe("cli.dev", async (evt) => {
|
|
271
|
-
const topic = `${iot.prefix}/events`;
|
|
272
|
-
iot.publish(topic, "cli.dev", evt.properties);
|
|
273
|
-
});
|
|
274
|
-
bus.publish("cli.dev", {
|
|
275
|
-
stage: project.config.stage,
|
|
276
|
-
app: project.config.name,
|
|
277
|
-
});
|
|
278
|
-
bus.subscribe("cli.dev", async (evt) => {
|
|
279
|
-
if (evt.properties.stage !== project.config.stage)
|
|
280
|
-
return;
|
|
281
|
-
if (evt.properties.app !== project.config.name)
|
|
282
|
-
return;
|
|
283
|
-
Colors.gap();
|
|
284
|
-
Colors.line(Colors.danger(`➜ `), "Another `sst dev` session has been started for this stage. Exiting...");
|
|
285
|
-
process.exit(0);
|
|
286
|
-
});
|
|
287
|
-
});
|
|
288
|
-
const [appMetadata] = await Promise.all([
|
|
289
|
-
useAppMetadata(),
|
|
290
|
-
useLocalServer({
|
|
291
|
-
key: "",
|
|
292
|
-
cert: "",
|
|
293
|
-
live: true,
|
|
294
|
-
}),
|
|
295
|
-
]);
|
|
296
|
-
async function promptChangeMode() {
|
|
297
|
-
const readline = await import("readline");
|
|
298
|
-
const rl = readline.createInterface({
|
|
299
|
-
input: process.stdin,
|
|
300
|
-
output: process.stdout,
|
|
277
|
+
});
|
|
278
|
+
await build();
|
|
301
279
|
});
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
280
|
+
const useDisconnector = Context.memo(async () => {
|
|
281
|
+
const bus = useBus();
|
|
282
|
+
const iot = await useIOT();
|
|
283
|
+
bus.subscribe("cli.dev", async (evt) => {
|
|
284
|
+
const topic = `${iot.prefix}/events`;
|
|
285
|
+
iot.publish(topic, "cli.dev", evt.properties);
|
|
286
|
+
});
|
|
287
|
+
bus.publish("cli.dev", {
|
|
288
|
+
stage: project.config.stage,
|
|
289
|
+
app: project.config.name,
|
|
290
|
+
});
|
|
291
|
+
bus.subscribe("cli.dev", async (evt) => {
|
|
292
|
+
if (evt.properties.stage !== project.config.stage)
|
|
293
|
+
return;
|
|
294
|
+
if (evt.properties.app !== project.config.name)
|
|
295
|
+
return;
|
|
296
|
+
Colors.gap();
|
|
297
|
+
Colors.line(Colors.danger(`➜ `), "Another `sst dev` session has been started for this stage. Exiting...");
|
|
298
|
+
await exit();
|
|
307
299
|
});
|
|
308
300
|
});
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
301
|
+
const [appMetadata] = await Promise.all([
|
|
302
|
+
useAppMetadata(),
|
|
303
|
+
useLocalServer({
|
|
304
|
+
key: "",
|
|
305
|
+
cert: "",
|
|
306
|
+
live: true,
|
|
307
|
+
}),
|
|
308
|
+
]);
|
|
309
|
+
async function promptChangeMode() {
|
|
310
|
+
const readline = await import("readline");
|
|
311
|
+
const rl = readline.createInterface({
|
|
312
|
+
input: process.stdin,
|
|
313
|
+
output: process.stdout,
|
|
314
|
+
});
|
|
315
|
+
return new Promise((resolve) => {
|
|
316
|
+
console.log("");
|
|
317
|
+
rl.question(`You have previously deployed the stage "${project.config.stage}" in production. It is recommended that you use a different stage for development. Read more here — https://docs.sst.dev/live-lambda-development\n\nAre you sure you want to run this stage in dev mode? [y/N] `, async (input) => {
|
|
318
|
+
rl.close();
|
|
319
|
+
resolve(input.trim() === "y");
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
// Check app mode changed
|
|
324
|
+
if (!project.config.advanced?.disableAppModeCheck &&
|
|
325
|
+
!getCiInfo().isCI &&
|
|
326
|
+
appMetadata &&
|
|
327
|
+
appMetadata.mode !== "dev") {
|
|
328
|
+
if (!(await promptChangeMode())) {
|
|
329
|
+
await exit();
|
|
330
|
+
}
|
|
317
331
|
}
|
|
332
|
+
clear();
|
|
333
|
+
await printHeader({ console: true, hint: "ready!" });
|
|
334
|
+
await useStackBuilder();
|
|
335
|
+
await Promise.all([
|
|
336
|
+
useDisconnector(),
|
|
337
|
+
useRuntimeWorkers(),
|
|
338
|
+
useIOTBridge(),
|
|
339
|
+
useRuntimeServer(),
|
|
340
|
+
usePothosBuilder(),
|
|
341
|
+
useMetadata(),
|
|
342
|
+
useKyselyTypeGenerator(),
|
|
343
|
+
useRDSWarmer(),
|
|
344
|
+
useFunctionLogger(),
|
|
345
|
+
]);
|
|
346
|
+
}
|
|
347
|
+
catch (e) {
|
|
348
|
+
await exitWithError(e);
|
|
318
349
|
}
|
|
319
|
-
clear();
|
|
320
|
-
await printHeader({ console: true, hint: "ready!" });
|
|
321
|
-
await useStackBuilder();
|
|
322
|
-
await Promise.all([
|
|
323
|
-
useDisconnector(),
|
|
324
|
-
useRuntimeWorkers(),
|
|
325
|
-
useIOTBridge(),
|
|
326
|
-
useRuntimeServer(),
|
|
327
|
-
usePothosBuilder(),
|
|
328
|
-
useMetadata(),
|
|
329
|
-
useKyselyTypeGenerator(),
|
|
330
|
-
useRDSWarmer(),
|
|
331
|
-
useFunctionLogger(),
|
|
332
|
-
]);
|
|
333
350
|
});
|