sst 2.0.0-rc.47 → 2.0.0-rc.49
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/cli/commands/build.js +5 -4
- package/cli/commands/console.js +3 -3
- package/cli/commands/deploy.js +9 -3
- package/cli/commands/dev.js +4 -7
- package/cli/commands/diff.js +10 -15
- package/cli/commands/plugins/pothos.js +2 -2
- package/cli/commands/remove.js +9 -6
- package/cli/commands/secrets/get.js +3 -3
- package/cli/commands/secrets/list.js +5 -0
- package/cli/commands/secrets/remove.js +11 -4
- package/cli/commands/secrets/set.js +3 -3
- package/cli/commands/{update-mod.d.ts → transform.d.ts} +2 -2
- package/cli/commands/{update-mod.js → transform.js} +6 -4
- package/cli/commands/update.js +6 -4
- package/cli/commands/version.d.ts +2 -4
- package/cli/commands/version.js +5 -35
- package/cli/sst.js +4 -2
- package/cli/ui/deploy.d.ts +1 -1
- package/cli/ui/deploy.js +32 -2
- package/cli/ui/header.d.ts +1 -0
- package/cli/ui/header.js +4 -3
- package/cli/ui/stack.d.ts +1 -0
- package/cli/ui/stack.js +6 -0
- package/constructs/Api.d.ts +1 -69
- package/constructs/Api.js +0 -36
- package/constructs/App.d.ts +0 -16
- package/constructs/App.js +2 -19
- package/constructs/AstroSite.js +5 -2
- package/constructs/Function.d.ts +0 -39
- package/constructs/Function.js +2 -34
- package/constructs/Job.d.ts +0 -39
- package/constructs/Job.js +1 -27
- package/constructs/Metadata.d.ts +1 -3
- package/constructs/SsrSite.d.ts +12 -0
- package/constructs/SsrSite.js +7 -5
- package/constructs/Stack.d.ts +0 -16
- package/constructs/Stack.js +0 -17
- package/constructs/index.d.ts +0 -3
- package/constructs/index.js +0 -3
- package/package.json +1 -1
- package/project.d.ts +1 -0
- package/project.js +13 -11
- package/sst.mjs +245 -132
- package/stacks/diff.js +2 -2
- package/constructs/GraphQLApi.d.ts +0 -98
- package/constructs/GraphQLApi.js +0 -80
- package/constructs/ReactStaticSite.d.ts +0 -20
- package/constructs/ReactStaticSite.js +0 -55
- package/constructs/ViteStaticSite.d.ts +0 -32
- package/constructs/ViteStaticSite.js +0 -67
package/cli/commands/build.js
CHANGED
|
@@ -3,14 +3,15 @@ export const build = (program) => program.command("build", "Build your app", (ya
|
|
|
3
3
|
describe: "Output directory, defaults to .sst/dist",
|
|
4
4
|
}), async (args) => {
|
|
5
5
|
const { useProject } = await import("../../project.js");
|
|
6
|
-
const { createSpinner } = await import("../spinner.js");
|
|
7
6
|
const { Stacks } = await import("../../stacks/index.js");
|
|
8
|
-
const
|
|
9
|
-
await
|
|
7
|
+
const { Colors } = await import("../colors.js");
|
|
8
|
+
const path = await import("path");
|
|
9
|
+
const result = await Stacks.synth({
|
|
10
10
|
fn: useProject().stacks,
|
|
11
11
|
buildDir: args.to,
|
|
12
12
|
mode: "deploy",
|
|
13
13
|
});
|
|
14
|
-
|
|
14
|
+
Colors.line("");
|
|
15
|
+
Colors.line(Colors.success(`✔`), Colors.bold(" Built:"), `${result.stacks.length} stack${result.stacks.length > 1 ? "s" : ""} to ${path.relative(process.cwd(), result.directory)}`);
|
|
15
16
|
process.exit(0);
|
|
16
17
|
});
|
package/cli/commands/console.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { useLocalServerConfig } from "../local/server.js";
|
|
2
1
|
export const consoleCommand = async (program) => program.command("console", "Start the SST Console", (yargs) => yargs, async () => {
|
|
3
2
|
const { blue } = await import("colorette");
|
|
4
3
|
const { useRuntimeServer } = await import("../../runtime/server.js");
|
|
5
4
|
const { useLocalServer } = await import("../local/server.js");
|
|
5
|
+
const { printHeader } = await import("../ui/header.js");
|
|
6
6
|
await Promise.all([
|
|
7
7
|
useRuntimeServer(),
|
|
8
8
|
useLocalServer({
|
|
@@ -11,6 +11,6 @@ export const consoleCommand = async (program) => program.command("console", "Sta
|
|
|
11
11
|
live: false,
|
|
12
12
|
}),
|
|
13
13
|
]);
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
console.clear();
|
|
15
|
+
printHeader({ console: true, hint: "ready!" });
|
|
16
16
|
});
|
package/cli/commands/deploy.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { useSTSIdentity } from "../../credentials.js";
|
|
1
2
|
import { Colors } from "../colors.js";
|
|
2
|
-
import { printHeader } from "../ui/header.js";
|
|
3
3
|
export const deploy = (program) => program.command("deploy [filter]", "Deploy your app to AWS", (yargs) => yargs
|
|
4
4
|
.option("from", {
|
|
5
5
|
type: "string",
|
|
@@ -18,7 +18,14 @@ export const deploy = (program) => program.command("deploy [filter]", "Deploy yo
|
|
|
18
18
|
const { render } = await import("ink");
|
|
19
19
|
const { DeploymentUI } = await import("../ui/deploy.js");
|
|
20
20
|
const project = useProject();
|
|
21
|
-
|
|
21
|
+
const identity = await useSTSIdentity();
|
|
22
|
+
Colors.line(`${Colors.primary.bold(`SST v${project.version}`)}`);
|
|
23
|
+
Colors.gap();
|
|
24
|
+
Colors.line(`${Colors.primary(`➜`)} ${Colors.bold("App:")} ${project.config.name}`);
|
|
25
|
+
Colors.line(` ${Colors.bold("Stage:")} ${project.config.stage}`);
|
|
26
|
+
Colors.line(` ${Colors.bold("Region:")} ${project.config.region}`);
|
|
27
|
+
Colors.line(` ${Colors.bold("Account:")} ${identity.Account}`);
|
|
28
|
+
Colors.gap();
|
|
22
29
|
// Generate cloud assembly
|
|
23
30
|
// - if --from is specified, we will use the existing cloud assembly
|
|
24
31
|
// - if --from is not specified, we will call synth to generate
|
|
@@ -35,7 +42,6 @@ export const deploy = (program) => program.command("deploy [filter]", "Deploy yo
|
|
|
35
42
|
mode: "deploy",
|
|
36
43
|
});
|
|
37
44
|
spinner.succeed();
|
|
38
|
-
console.log();
|
|
39
45
|
return result;
|
|
40
46
|
})();
|
|
41
47
|
const target = assembly.stacks.filter((s) => !args.filter ||
|
package/cli/commands/dev.js
CHANGED
|
@@ -107,9 +107,7 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
|
|
|
107
107
|
Colors.gap();
|
|
108
108
|
const spinner = createSpinner({
|
|
109
109
|
color: "gray",
|
|
110
|
-
text: lastDeployed
|
|
111
|
-
? ` Building stacks`
|
|
112
|
-
: dim(` Checking for changes`),
|
|
110
|
+
text: lastDeployed ? ` Building...` : dim(` Checking for changes`),
|
|
113
111
|
}).start();
|
|
114
112
|
try {
|
|
115
113
|
const [metafile, sstConfig] = await Stacks.load(project.paths.config);
|
|
@@ -125,8 +123,7 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
|
|
|
125
123
|
const next = await checksum(assembly.directory);
|
|
126
124
|
Logger.debug("Checksum", "next", next, "old", lastDeployed);
|
|
127
125
|
if (next === lastDeployed) {
|
|
128
|
-
spinner.succeed("
|
|
129
|
-
Colors.gap();
|
|
126
|
+
spinner.succeed(Colors.dim(" Built with no changes"));
|
|
130
127
|
return;
|
|
131
128
|
}
|
|
132
129
|
if (!lastDeployed) {
|
|
@@ -135,7 +132,7 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
|
|
|
135
132
|
Colors.mode("gap");
|
|
136
133
|
}
|
|
137
134
|
else {
|
|
138
|
-
spinner.succeed(`
|
|
135
|
+
spinner.succeed(Colors.dim(` Built`));
|
|
139
136
|
Colors.mode("gap");
|
|
140
137
|
}
|
|
141
138
|
pending = assembly;
|
|
@@ -222,7 +219,7 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
|
|
|
222
219
|
live: true,
|
|
223
220
|
});
|
|
224
221
|
console.clear();
|
|
225
|
-
await printHeader({ console: true });
|
|
222
|
+
await printHeader({ console: true, hint: "ready!" });
|
|
226
223
|
/*
|
|
227
224
|
console.log(` ${primary(`➜`)} ${bold(dim(`Outputs:`))}`);
|
|
228
225
|
for (let i = 0; i < 3; i++) {
|
package/cli/commands/diff.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { stackNameToId } from "../ui/stack.js";
|
|
1
2
|
export const diff = (program) => program.command("diff", "Compare your app with what is deployed on AWS", (yargs) => yargs.option("dev", {
|
|
2
3
|
type: "boolean",
|
|
3
4
|
describe: "Compare in dev mode",
|
|
@@ -8,15 +9,13 @@ export const diff = (program) => program.command("diff", "Compare your app with
|
|
|
8
9
|
const { CloudFormationClient, GetTemplateCommand } = await import("@aws-sdk/client-cloudformation");
|
|
9
10
|
const { createSpinner } = await import("../spinner.js");
|
|
10
11
|
const { green } = await import("colorette");
|
|
12
|
+
const { Colors } = await import("../colors.js");
|
|
11
13
|
// Build app
|
|
12
|
-
const spinner = createSpinner("Building stacks");
|
|
13
14
|
const project = useProject();
|
|
14
15
|
const assembly = await Stacks.synth({
|
|
15
16
|
fn: project.stacks,
|
|
16
17
|
mode: args.dev ? "dev" : "deploy",
|
|
17
18
|
});
|
|
18
|
-
spinner.succeed();
|
|
19
|
-
console.log("");
|
|
20
19
|
// Diff each stack
|
|
21
20
|
let changesAcc = 0;
|
|
22
21
|
let changedStacks = 0;
|
|
@@ -33,19 +32,19 @@ export const diff = (program) => program.command("diff", "Compare your app with
|
|
|
33
32
|
spinner.clear();
|
|
34
33
|
// print diff result
|
|
35
34
|
if (count === 0) {
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
Colors.line(`➜ ${Colors.dim.bold(stackNameToId(stack.stackName) + ":")} No changes`);
|
|
36
|
+
Colors.gap();
|
|
38
37
|
}
|
|
39
38
|
else if (count === 1) {
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
Colors.line(`➜ ${Colors.dim.bold(stackNameToId(stack.stackName) + ":")} ${count} change`);
|
|
40
|
+
Colors.gap();
|
|
42
41
|
console.log(diff);
|
|
43
42
|
changesAcc += count;
|
|
44
43
|
changedStacks++;
|
|
45
44
|
}
|
|
46
45
|
else {
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
Colors.line(`➜ ${Colors.dim.bold(stackNameToId(stack.stackName) + ":")} ${count} changes`);
|
|
47
|
+
Colors.gap();
|
|
49
48
|
console.log(diff);
|
|
50
49
|
changesAcc += count;
|
|
51
50
|
changedStacks++;
|
|
@@ -53,14 +52,10 @@ export const diff = (program) => program.command("diff", "Compare your app with
|
|
|
53
52
|
}
|
|
54
53
|
// Handle no changes
|
|
55
54
|
if (changedStacks === 0) {
|
|
56
|
-
|
|
55
|
+
Colors.line(Colors.success(`✔`), Colors.bold(" Diff:"), "No changes");
|
|
57
56
|
}
|
|
58
57
|
else {
|
|
59
|
-
|
|
60
|
-
? "1 change found in"
|
|
61
|
-
: `${changesAcc} changes found in`, changedStacks === 1
|
|
62
|
-
? "1 stack"
|
|
63
|
-
: `${changedStacks} stacks`);
|
|
58
|
+
Colors.line(Colors.success(`✔`), Colors.bold(" Diff:"), changesAcc === 1 ? "1 change found in" : `${changesAcc} changes in`, changedStacks === 1 ? "1 stack" : `${changedStacks} stacks`);
|
|
64
59
|
}
|
|
65
60
|
process.exit(0);
|
|
66
61
|
});
|
|
@@ -18,10 +18,10 @@ 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.success(`✔`), " Extracted pothos schema");
|
|
21
|
+
Colors.line(Colors.success(`✔`), " Pothos: Extracted pothos schema");
|
|
22
22
|
}
|
|
23
23
|
catch (ex) {
|
|
24
|
-
Colors.line(Colors.danger(`✖`), " Failed to extract schema
|
|
24
|
+
Colors.line(Colors.danger(`✖`), " Pothos: Failed to extract schema:");
|
|
25
25
|
for (let line of ex.message.split("\n")) {
|
|
26
26
|
console.log(` `, line);
|
|
27
27
|
}
|
package/cli/commands/remove.js
CHANGED
|
@@ -10,12 +10,15 @@ export const remove = (program) => program.command("remove [filter]", "Remove yo
|
|
|
10
10
|
const { DeploymentUI } = await import("../ui/deploy.js");
|
|
11
11
|
const { printDeploymentResults } = await import("../ui/deploy.js");
|
|
12
12
|
const { Colors } = await import("../colors.js");
|
|
13
|
+
const { useSTSIdentity } = await import("../../credentials.js");
|
|
13
14
|
const project = useProject();
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
const identity = await useSTSIdentity();
|
|
16
|
+
Colors.line(`${Colors.primary.bold(`SST v${project.version}`)}`);
|
|
17
|
+
Colors.gap();
|
|
18
|
+
Colors.line(`${Colors.primary(`➜`)} ${Colors.bold("App:")} ${project.config.name}`);
|
|
19
|
+
Colors.line(` ${Colors.bold("Stage:")} ${project.config.stage}`);
|
|
20
|
+
Colors.line(` ${Colors.bold("Region:")} ${project.config.region}`);
|
|
21
|
+
Colors.line(` ${Colors.bold("Account:")} ${identity.Account}`);
|
|
19
22
|
const assembly = await (async function () {
|
|
20
23
|
if (args.from) {
|
|
21
24
|
const result = await loadAssembly(args.from);
|
|
@@ -36,7 +39,7 @@ export const remove = (program) => program.command("remove [filter]", "Remove yo
|
|
|
36
39
|
const results = await Stacks.removeMany(target);
|
|
37
40
|
component.clear();
|
|
38
41
|
component.unmount();
|
|
39
|
-
printDeploymentResults(assembly, results);
|
|
42
|
+
printDeploymentResults(assembly, results, true);
|
|
40
43
|
if (Object.values(results).some((stack) => Stacks.isFailed(stack.status)))
|
|
41
44
|
process.exit(1);
|
|
42
45
|
process.exit(0);
|
|
@@ -10,15 +10,15 @@ export const get = (program) => program.command("get <name>", "Get the value of
|
|
|
10
10
|
}), async (args) => {
|
|
11
11
|
const { red } = await import("colorette");
|
|
12
12
|
const { Config } = await import("../../../config.js");
|
|
13
|
-
const {
|
|
13
|
+
const { Colors } = await import("../../colors.js");
|
|
14
14
|
try {
|
|
15
15
|
const result = await Config.getSecret({
|
|
16
16
|
key: args.name,
|
|
17
17
|
fallback: args.fallback === true,
|
|
18
18
|
});
|
|
19
|
-
console.log(
|
|
19
|
+
console.log(result);
|
|
20
20
|
}
|
|
21
21
|
catch {
|
|
22
|
-
|
|
22
|
+
Colors.line(Colors.danger(`✖ `), `"${args.name}" is not set`);
|
|
23
23
|
}
|
|
24
24
|
});
|
|
@@ -4,7 +4,12 @@ export const list = (program) => program.command("list [format]", "Fetch all the
|
|
|
4
4
|
}), async (args) => {
|
|
5
5
|
const { Config } = await import("../../../config.js");
|
|
6
6
|
const { gray } = await import("colorette");
|
|
7
|
+
const { Colors } = await import("../../colors.js");
|
|
7
8
|
const secrets = await Config.secrets();
|
|
9
|
+
if (Object.entries(secrets).length === 0) {
|
|
10
|
+
Colors.line("No secrets set");
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
8
13
|
switch (args.format || "table") {
|
|
9
14
|
case "env":
|
|
10
15
|
for (const [key, value] of Object.entries(secrets)) {
|
|
@@ -9,8 +9,15 @@ export const remove = (program) => program.command("remove <name>", "Remove a se
|
|
|
9
9
|
describe: "Remove the fallback value",
|
|
10
10
|
}), async (args) => {
|
|
11
11
|
const { Config } = await import("../../../config.js");
|
|
12
|
-
await
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const { Colors } = await import("../../colors.js");
|
|
13
|
+
try {
|
|
14
|
+
await Config.removeSecret({
|
|
15
|
+
key: args.name,
|
|
16
|
+
fallback: args.fallback === true,
|
|
17
|
+
});
|
|
18
|
+
Colors.line(Colors.success(`✔ `), `Removed "${args.name}"`);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
Colors.line(Colors.danger(`✖ `), `"${args.name}" is not set`);
|
|
22
|
+
}
|
|
16
23
|
});
|
|
@@ -16,14 +16,14 @@ export const set = (program) => program.command("set <name> <value>", "Set the v
|
|
|
16
16
|
const { Config } = await import("../../../config.js");
|
|
17
17
|
const { blue } = await import("colorette");
|
|
18
18
|
const { createSpinner } = await import("../../spinner.js");
|
|
19
|
-
const setting = createSpinner(`Setting
|
|
19
|
+
const setting = createSpinner(` Setting "${args.name}"`).start();
|
|
20
20
|
await Config.setSecret({
|
|
21
21
|
key: args.name,
|
|
22
22
|
value: args.value,
|
|
23
23
|
fallback: args.fallback === true,
|
|
24
24
|
});
|
|
25
25
|
setting.succeed();
|
|
26
|
-
const restarting = createSpinner(`Restarting all functions using ${blue(args.name)}...`).start();
|
|
26
|
+
const restarting = createSpinner(` Restarting all functions using ${blue(args.name)}...`).start();
|
|
27
27
|
const count = await Config.restart(args.name);
|
|
28
|
-
restarting.succeed(`Restarted ${
|
|
28
|
+
restarting.succeed(` Restarted ${count} functions`);
|
|
29
29
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="yargs" />
|
|
2
2
|
import type { Program } from "../program.js";
|
|
3
|
-
export declare const
|
|
3
|
+
export declare const transform: (program: Program) => import("yargs").Argv<{
|
|
4
4
|
stage: string | undefined;
|
|
5
5
|
} & {
|
|
6
6
|
profile: string | undefined;
|
|
@@ -11,5 +11,5 @@ export declare const updateMod: (program: Program) => import("yargs").Argv<{
|
|
|
11
11
|
} & {
|
|
12
12
|
role: string | undefined;
|
|
13
13
|
} & {
|
|
14
|
-
|
|
14
|
+
mod: string;
|
|
15
15
|
}>;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const transform = (program) => program.command("transform <mod>", "Apply a transform to your SST app", (yargs) => yargs.positional("mod", {
|
|
2
2
|
type: "string",
|
|
3
3
|
describe: "Name of the transform",
|
|
4
4
|
demandOption: true,
|
|
5
5
|
}), async (args) => {
|
|
6
|
-
const {
|
|
7
|
-
if (args.
|
|
6
|
+
const { Colors } = await import("../colors.js");
|
|
7
|
+
if (args.mod === "resource-binding-secrets") {
|
|
8
8
|
await handleSecretsMigration();
|
|
9
|
+
Colors.line(Colors.success(`✔ `), `Transform "${args.mod}" applied successfully!`);
|
|
10
|
+
return;
|
|
9
11
|
}
|
|
10
|
-
|
|
12
|
+
Colors.line(Colors.danger(`✖ `), `Transform "${args.mod}" not found`);
|
|
11
13
|
});
|
|
12
14
|
async function handleSecretsMigration() {
|
|
13
15
|
const { useProject } = await import("../../project.js");
|
package/cli/commands/update.js
CHANGED
|
@@ -9,6 +9,7 @@ export const update = (program) => program.command("update [version]", "Update y
|
|
|
9
9
|
const path = await import("path");
|
|
10
10
|
const { fetch } = await import("undici");
|
|
11
11
|
const { useProject } = await import("../../project.js");
|
|
12
|
+
const { Colors } = await import("../colors.js");
|
|
12
13
|
async function find(dir) {
|
|
13
14
|
const children = await fs.readdir(dir);
|
|
14
15
|
const tasks = children.map(async (item) => {
|
|
@@ -67,14 +68,15 @@ export const update = (program) => program.command("update [version]", "Update y
|
|
|
67
68
|
});
|
|
68
69
|
await Promise.all(tasks);
|
|
69
70
|
if (results.size === 0) {
|
|
70
|
-
|
|
71
|
+
Colors.line(Colors.success(`✔ `), `Already using v${metadata.version}`);
|
|
71
72
|
return;
|
|
72
73
|
}
|
|
73
74
|
for (const [file, pkgs] of results.entries()) {
|
|
74
|
-
|
|
75
|
+
Colors.line(Colors.success(`✔ `), Colors.bold.dim(path.relative(project.paths.root, file)));
|
|
75
76
|
for (const [pkg, version] of pkgs) {
|
|
76
|
-
|
|
77
|
+
Colors.line(Colors.dim(` ${pkg}@${version}`));
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
|
-
|
|
80
|
+
Colors.gap();
|
|
81
|
+
Colors.line(`${Colors.primary(`➜`)} ${Colors.warning("Make sure to run: npm install (or pnpm install, or yarn)")}`);
|
|
80
82
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="yargs" />
|
|
2
|
-
import { Program } from "../program.js";
|
|
3
|
-
export declare const
|
|
2
|
+
import type { Program } from "../program.js";
|
|
3
|
+
export declare const version: (program: Program) => import("yargs").Argv<{
|
|
4
4
|
stage: string | undefined;
|
|
5
5
|
} & {
|
|
6
6
|
profile: string | undefined;
|
|
@@ -10,6 +10,4 @@ export declare const env: (program: Program) => import("yargs").Argv<{
|
|
|
10
10
|
verbose: boolean | undefined;
|
|
11
11
|
} & {
|
|
12
12
|
role: string | undefined;
|
|
13
|
-
} & {
|
|
14
|
-
command: string;
|
|
15
13
|
}>;
|
package/cli/commands/version.js
CHANGED
|
@@ -1,37 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import { SiteEnv } from "../../site-env.js";
|
|
5
|
-
import { spawnSync } from "child_process";
|
|
6
|
-
export const env = (program) => program.command("env <command>", "description", (yargs) => yargs.positional("command", {
|
|
7
|
-
type: "string",
|
|
8
|
-
describe: "Command to run with environment variabels loaded",
|
|
9
|
-
demandOption: true,
|
|
10
|
-
}), async (args) => {
|
|
1
|
+
export const version = (program) => program.command("version", "Print SST and CDK version", (yargs) => yargs, async (args) => {
|
|
2
|
+
const { Colors } = await import("../colors.js");
|
|
3
|
+
const { useProject } = await import("../../project.js");
|
|
11
4
|
const project = useProject();
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const exists = await fs
|
|
15
|
-
.access(SiteEnv.valuesFile())
|
|
16
|
-
.then(() => true)
|
|
17
|
-
.catch(() => false);
|
|
18
|
-
if (!exists) {
|
|
19
|
-
spinner = createSpinner("Waiting for SST to start").start();
|
|
20
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
21
|
-
continue;
|
|
22
|
-
}
|
|
23
|
-
spinner?.succeed();
|
|
24
|
-
const sites = await SiteEnv.values();
|
|
25
|
-
const env = sites[process.cwd()] || {};
|
|
26
|
-
const result = spawnSync(args.command, {
|
|
27
|
-
env: {
|
|
28
|
-
...process.env,
|
|
29
|
-
...env,
|
|
30
|
-
},
|
|
31
|
-
stdio: "inherit",
|
|
32
|
-
shell: process.env.SHELL || true,
|
|
33
|
-
});
|
|
34
|
-
process.exitCode = result.status || undefined;
|
|
35
|
-
break;
|
|
36
|
-
}
|
|
5
|
+
Colors.line(Colors.bold(`SST:`), `v${project.version}`);
|
|
6
|
+
Colors.line(Colors.bold(`CDK:`), `v${project.cdkVersion}`);
|
|
37
7
|
});
|
package/cli/sst.js
CHANGED
|
@@ -17,8 +17,9 @@ import { remove } from "./commands/remove.js";
|
|
|
17
17
|
import { consoleCommand } from "./commands/console.js";
|
|
18
18
|
import { secrets } from "./commands/secrets/secrets.js";
|
|
19
19
|
import { update } from "./commands/update.js";
|
|
20
|
-
import {
|
|
20
|
+
import { transform } from "./commands/transform.js";
|
|
21
21
|
import { diff } from "./commands/diff.js";
|
|
22
|
+
import { version } from "./commands/version.js";
|
|
22
23
|
dev(program);
|
|
23
24
|
deploy(program);
|
|
24
25
|
build(program);
|
|
@@ -27,9 +28,10 @@ env(program);
|
|
|
27
28
|
secrets(program);
|
|
28
29
|
remove(program);
|
|
29
30
|
update(program);
|
|
30
|
-
|
|
31
|
+
transform(program);
|
|
31
32
|
consoleCommand(program);
|
|
32
33
|
diff(program);
|
|
34
|
+
version(program);
|
|
33
35
|
// @ts-expect-error
|
|
34
36
|
process.setSourceMapsEnabled(true);
|
|
35
37
|
process.removeAllListeners("uncaughtException");
|
package/cli/ui/deploy.d.ts
CHANGED
|
@@ -5,5 +5,5 @@ interface Props {
|
|
|
5
5
|
assembly: CloudAssembly;
|
|
6
6
|
}
|
|
7
7
|
export declare const DeploymentUI: (props: Props) => JSX.Element;
|
|
8
|
-
export declare function printDeploymentResults(assembly: CloudAssembly, results: Awaited<ReturnType<typeof Stacks.deployMany
|
|
8
|
+
export declare function printDeploymentResults(assembly: CloudAssembly, results: Awaited<ReturnType<typeof Stacks.deployMany>>, remove?: boolean): void;
|
|
9
9
|
export {};
|
package/cli/ui/deploy.js
CHANGED
|
@@ -63,12 +63,12 @@ export const DeploymentUI = (props) => {
|
|
|
63
63
|
" ",
|
|
64
64
|
React.createElement(Text, { dimColor: true }, "Deploying..."))))));
|
|
65
65
|
};
|
|
66
|
-
export function printDeploymentResults(assembly, results) {
|
|
66
|
+
export function printDeploymentResults(assembly, results, remove) {
|
|
67
67
|
// Print success stacks
|
|
68
68
|
const success = Object.entries(results).filter(([_stack, result]) => Object.keys(result.errors).length === 0);
|
|
69
69
|
if (success.length) {
|
|
70
70
|
Colors.gap();
|
|
71
|
-
Colors.line(Colors.success(`✔`), Colors.bold(` Deployed:`));
|
|
71
|
+
Colors.line(Colors.success(`✔`), Colors.bold(remove ? ` Removed:` : ` Deployed:`));
|
|
72
72
|
for (const [stack, result] of success) {
|
|
73
73
|
const outputs = Object.entries(result.outputs).filter(([key, _]) => {
|
|
74
74
|
if (key.startsWith("Export"))
|
|
@@ -98,6 +98,10 @@ export function printDeploymentResults(assembly, results) {
|
|
|
98
98
|
for (const [id, error] of Object.entries(result.errors)) {
|
|
99
99
|
const readable = logicalIdToCdkPath(assembly, stack, id) || id;
|
|
100
100
|
Colors.line(` ${Colors.danger.bold(readable + ":")} ${error}`);
|
|
101
|
+
const helper = getHelper(error);
|
|
102
|
+
if (helper) {
|
|
103
|
+
Colors.line(` ${Colors.warning.bold("⮑ Hint:")} ${helper}`);
|
|
104
|
+
}
|
|
101
105
|
}
|
|
102
106
|
}
|
|
103
107
|
Colors.gap();
|
|
@@ -115,3 +119,29 @@ function logicalIdToCdkPath(assembly, stack, logicalId) {
|
|
|
115
119
|
}
|
|
116
120
|
return found.split("/").filter(Boolean).slice(1, -1).join("/");
|
|
117
121
|
}
|
|
122
|
+
function getHelper(error) {
|
|
123
|
+
return `This is a common deploy error. Check out this GitHub issue for more details - https://github.com/serverless-stack/sst/issues/125`;
|
|
124
|
+
return getApiAccessLogPermissionsHelper(error)
|
|
125
|
+
|| getAppSyncMultiResolverHelper(error)
|
|
126
|
+
|| getApiLogRoleHelper(error);
|
|
127
|
+
}
|
|
128
|
+
function getApiAccessLogPermissionsHelper(error) {
|
|
129
|
+
// Can run into this issue when enabling access logs for API Gateway
|
|
130
|
+
// note: this should be handled in SST as access log group names are now
|
|
131
|
+
// hardcoded with /aws/vendedlogs/apis prefix.
|
|
132
|
+
if (error.indexOf("Insufficient permissions to enable logging") > -1) {
|
|
133
|
+
return `This is a common deploy error. Check out this GitHub issue for more details - https://github.com/serverless-stack/sst/issues/125`;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function getAppSyncMultiResolverHelper(error) {
|
|
137
|
+
// Can run into this issue when updating an AppSyncApi resolver
|
|
138
|
+
if (error.indexOf("Only one resolver is allowed per field. (Service: AWSAppSync") > -1) {
|
|
139
|
+
return `This is a common error for deploying AppSync APIs. Check out this GitHub issue for more details - https://github.com/aws/aws-cdk/issues/13269`;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function getApiLogRoleHelper(error) {
|
|
143
|
+
// Can run into this issue when enabling access logs for WebSocketApi
|
|
144
|
+
if (error.indexOf("CloudWatch Logs role ARN must be set in account settings to enable logging (Service: AmazonApiGatewayV2") > -1) {
|
|
145
|
+
return `This is a common error when configuring Access Log for WebSocket APIs. The AWS API Gateway service in your AWS account does not have permissions to the CloudWatch logs service. Follow this article to create an IAM role for logging to CloudWatch - https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-cloudwatch-logs/`;
|
|
146
|
+
}
|
|
147
|
+
}
|
package/cli/ui/header.d.ts
CHANGED
package/cli/ui/header.js
CHANGED
|
@@ -3,12 +3,13 @@ import { Colors } from "../colors.js";
|
|
|
3
3
|
import { useLocalServerConfig } from "../local/server.js";
|
|
4
4
|
export async function printHeader(input) {
|
|
5
5
|
const project = useProject();
|
|
6
|
-
Colors.line(`${Colors.primary.bold(
|
|
6
|
+
Colors.line(`${Colors.primary.bold(`SST v${project.version}`)} ${input.hint ? Colors.dim(`ready!`) : ""}`);
|
|
7
7
|
Colors.gap();
|
|
8
|
-
Colors.line(`${Colors.primary(`➜`)} ${Colors.bold("
|
|
8
|
+
Colors.line(`${Colors.primary(`➜`)} ${Colors.bold("App:")} ${project.config.name}`);
|
|
9
|
+
Colors.line(`${Colors.primary(` `)} ${Colors.bold("Stage:")} ${project.config.stage}`);
|
|
9
10
|
if (input.console) {
|
|
10
11
|
const local = await useLocalServerConfig();
|
|
11
|
-
Colors.line(`${Colors.primary(
|
|
12
|
+
Colors.line(`${Colors.primary(` `)} ${Colors.bold("Console:")} ${Colors.link(local.url)}`);
|
|
12
13
|
}
|
|
13
14
|
Colors.gap();
|
|
14
15
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function stackNameToId(stack: string): string;
|
package/cli/ui/stack.js
ADDED
package/constructs/Api.d.ts
CHANGED
|
@@ -393,7 +393,7 @@ export interface ApiProps<Authorizers extends Record<string, ApiAuthorizer> = Re
|
|
|
393
393
|
httpStages?: Omit<apig.HttpStageProps, "httpApi">[];
|
|
394
394
|
};
|
|
395
395
|
}
|
|
396
|
-
export type ApiRouteProps<AuthorizerKeys> = FunctionInlineDefinition | ApiFunctionRouteProps<AuthorizerKeys> | ApiHttpRouteProps<AuthorizerKeys> | ApiAlbRouteProps<AuthorizerKeys> | ApiGraphQLRouteProps<AuthorizerKeys
|
|
396
|
+
export type ApiRouteProps<AuthorizerKeys> = FunctionInlineDefinition | ApiFunctionRouteProps<AuthorizerKeys> | ApiHttpRouteProps<AuthorizerKeys> | ApiAlbRouteProps<AuthorizerKeys> | ApiGraphQLRouteProps<AuthorizerKeys>;
|
|
397
397
|
interface ApiBaseRouteProps<AuthorizerKeys = string> {
|
|
398
398
|
authorizer?: "none" | "iam" | (string extends AuthorizerKeys ? Omit<AuthorizerKeys, "none" | "iam"> : AuthorizerKeys);
|
|
399
399
|
authorizationScopes?: string[];
|
|
@@ -485,63 +485,6 @@ export interface ApiAlbRouteProps<AuthorizersKeys> extends ApiBaseRouteProps<Aut
|
|
|
485
485
|
integration?: apigIntegrations.HttpAlbIntegrationProps;
|
|
486
486
|
};
|
|
487
487
|
}
|
|
488
|
-
/**
|
|
489
|
-
* Specify a route handler that handles GraphQL queries using Pothos
|
|
490
|
-
* @deprecated "pothos" routes are deprecated for the Api construct, and will be removed in SST v2. Use "graphql" routes instead. Read more about how to upgrade here — https://docs.sst.dev/upgrade-guide#upgrade-to-v118
|
|
491
|
-
* @example
|
|
492
|
-
* ```js
|
|
493
|
-
* // Change
|
|
494
|
-
* api.addRoutes(stack, {
|
|
495
|
-
* "POST /graphql": {
|
|
496
|
-
* type: "pothos",
|
|
497
|
-
* function: {
|
|
498
|
-
* handler: "functions/graphql/graphql.ts",
|
|
499
|
-
* },
|
|
500
|
-
* schema: "backend/functions/graphql/schema.ts",
|
|
501
|
-
* output: "graphql/schema.graphql",
|
|
502
|
-
* commands: [
|
|
503
|
-
* "./genql graphql/graphql.schema graphql/
|
|
504
|
-
* ]
|
|
505
|
-
* }
|
|
506
|
-
* })
|
|
507
|
-
*
|
|
508
|
-
* // To
|
|
509
|
-
* api.addRoutes(stack, {
|
|
510
|
-
* "POST /graphql": {
|
|
511
|
-
* type: "graphql",
|
|
512
|
-
* function: {
|
|
513
|
-
* handler: "functions/graphql/graphql.ts",
|
|
514
|
-
* },
|
|
515
|
-
* pothos: {
|
|
516
|
-
* schema: "backend/functions/graphql/schema.ts",
|
|
517
|
-
* output: "graphql/schema.graphql",
|
|
518
|
-
* commands: [
|
|
519
|
-
* "./genql graphql/graphql.schema graphql/
|
|
520
|
-
* ]
|
|
521
|
-
* }
|
|
522
|
-
* }
|
|
523
|
-
* })
|
|
524
|
-
* ```
|
|
525
|
-
*/
|
|
526
|
-
export interface ApiPothosRouteProps<AuthorizerKeys> extends ApiBaseRouteProps<AuthorizerKeys> {
|
|
527
|
-
type: "pothos";
|
|
528
|
-
/**
|
|
529
|
-
* The function definition used to create the function for this route. Must be a graphql handler
|
|
530
|
-
*/
|
|
531
|
-
function: FunctionDefinition;
|
|
532
|
-
/**
|
|
533
|
-
* Path to pothos schema
|
|
534
|
-
*/
|
|
535
|
-
schema?: string;
|
|
536
|
-
/**
|
|
537
|
-
* File to write graphql schema to
|
|
538
|
-
*/
|
|
539
|
-
output?: string;
|
|
540
|
-
/**
|
|
541
|
-
* Commands to run after generating schema. Useful for code generation steps
|
|
542
|
-
*/
|
|
543
|
-
commands?: string[];
|
|
544
|
-
}
|
|
545
488
|
/**
|
|
546
489
|
* Specify a route handler that handles GraphQL queries using Pothos
|
|
547
490
|
*
|
|
@@ -752,16 +695,6 @@ export declare class Api<Authorizers extends Record<string, ApiAuthorizer> = Rec
|
|
|
752
695
|
schema?: undefined;
|
|
753
696
|
output?: undefined;
|
|
754
697
|
commands?: undefined;
|
|
755
|
-
} | {
|
|
756
|
-
type: "pothos";
|
|
757
|
-
route: string;
|
|
758
|
-
fn: {
|
|
759
|
-
node: string;
|
|
760
|
-
stack: string;
|
|
761
|
-
} | undefined;
|
|
762
|
-
schema: string | undefined;
|
|
763
|
-
output: string | undefined;
|
|
764
|
-
commands: string[] | undefined;
|
|
765
698
|
} | {
|
|
766
699
|
type: "graphql";
|
|
767
700
|
route: string;
|
|
@@ -798,7 +731,6 @@ export declare class Api<Authorizers extends Record<string, ApiAuthorizer> = Rec
|
|
|
798
731
|
private addRoute;
|
|
799
732
|
private createHttpIntegration;
|
|
800
733
|
private createAlbIntegration;
|
|
801
|
-
protected createPothosIntegration(scope: Construct, routeKey: string, routeProps: ApiPothosRouteProps<keyof Authorizers>, postfixName: string): apig.HttpRouteIntegration;
|
|
802
734
|
protected createGraphQLIntegration(scope: Construct, routeKey: string, routeProps: ApiGraphQLRouteProps<keyof Authorizers>, postfixName: string): apig.HttpRouteIntegration;
|
|
803
735
|
protected createCdkFunctionIntegration(scope: Construct, routeKey: string, routeProps: ApiFunctionRouteProps<keyof Authorizers>, postfixName: string): apig.HttpRouteIntegration;
|
|
804
736
|
protected createFunctionIntegration(scope: Construct, routeKey: string, routeProps: ApiFunctionRouteProps<keyof Authorizers>, postfixName: string): apig.HttpRouteIntegration;
|