sst 2.0.0-rc.9 → 2.0.1
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.d.ts +2 -4
- package/bootstrap.js +208 -61
- package/bus.d.ts +3 -3
- package/bus.js +1 -1
- package/cache.js +1 -1
- package/cdk/cloudformation-deployments-wrapper.d.ts +3 -0
- package/cdk/cloudformation-deployments-wrapper.js +117 -0
- package/cdk/cloudformation-deployments.d.ts +19 -4
- package/cdk/deploy-stack.d.ts +17 -2
- package/cdk/deploy-stack.js +6 -1
- package/cli/colors.d.ts +28 -0
- package/cli/colors.js +27 -0
- package/cli/commands/bind.d.ts +4 -0
- package/cli/commands/bind.js +10 -7
- package/cli/commands/bootstrap.d.ts +13 -0
- package/cli/commands/bootstrap.js +11 -0
- package/cli/commands/build.d.ts +6 -2
- package/cli/commands/build.js +13 -8
- package/cli/commands/console.d.ts +5 -1
- package/cli/commands/console.js +8 -6
- package/cli/commands/deploy.d.ts +4 -2
- package/cli/commands/deploy.js +69 -29
- package/cli/commands/dev.d.ts +5 -1
- package/cli/commands/dev.js +157 -79
- package/cli/commands/diff.d.ts +15 -0
- package/cli/commands/diff.js +61 -0
- package/cli/commands/env.d.ts +5 -1
- package/cli/commands/env.js +14 -15
- package/cli/commands/plugins/kysely.js +13 -5
- package/cli/commands/plugins/pothos.js +9 -4
- package/cli/commands/remove.d.ts +4 -0
- package/cli/commands/remove.js +26 -18
- package/cli/commands/secrets/get.d.ts +7 -3
- package/cli/commands/secrets/get.js +11 -24
- package/cli/commands/secrets/list.d.ts +6 -2
- package/cli/commands/secrets/list.js +15 -7
- package/cli/commands/secrets/remove.d.ts +8 -4
- package/cli/commands/secrets/remove.js +18 -16
- package/cli/commands/secrets/secrets.js +3 -3
- package/cli/commands/secrets/set.d.ts +8 -6
- package/cli/commands/secrets/set.js +16 -33
- package/cli/commands/telemetry.d.ts +15 -0
- package/cli/commands/telemetry.js +17 -0
- package/cli/commands/transform.d.ts +15 -0
- package/cli/commands/transform.js +55 -0
- package/cli/commands/update.d.ts +6 -2
- package/cli/commands/update.js +41 -33
- package/cli/commands/version.d.ts +13 -0
- package/cli/commands/version.js +7 -0
- package/cli/local/router.d.ts +6 -6
- package/cli/local/router.js +3 -3
- package/cli/local/server.d.ts +5 -3
- package/cli/local/server.js +21 -14
- package/cli/program.d.ts +5 -1
- package/cli/program.js +29 -5
- package/cli/spinner.js +2 -0
- package/cli/sst.js +35 -23
- package/cli/telemetry/environment.d.ts +1 -1
- package/cli/telemetry/environment.js +1 -1
- package/cli/terminal.d.ts +1 -0
- package/cli/terminal.js +8 -0
- package/cli/ui/deploy.d.ts +3 -2
- package/cli/ui/deploy.js +106 -106
- package/cli/ui/functions.d.ts +2 -0
- package/cli/ui/functions.js +132 -0
- package/cli/ui/header.d.ts +5 -0
- package/cli/ui/header.js +16 -0
- package/cli/ui/stack.d.ts +1 -0
- package/cli/ui/stack.js +6 -0
- package/config.d.ts +1 -1
- package/config.js +8 -8
- package/constructs/Api.d.ts +3 -71
- package/constructs/Api.js +3 -42
- package/constructs/ApiGatewayV1Api.d.ts +3 -3
- package/constructs/ApiGatewayV1Api.js +4 -3
- package/constructs/App.d.ts +2 -22
- package/constructs/App.js +12 -25
- package/constructs/AppSyncApi.d.ts +4 -5
- package/constructs/AppSyncApi.js +8 -5
- package/constructs/AstroSite.d.ts +2 -3
- package/constructs/AstroSite.js +43 -53
- package/constructs/Auth.js +27 -16
- package/constructs/BaseSite.d.ts +10 -10
- package/constructs/BaseSite.js +2 -2
- package/constructs/Cognito.js +28 -28
- package/constructs/EdgeFunction.d.ts +6 -4
- package/constructs/EdgeFunction.js +56 -59
- package/constructs/EventBus.js +1 -1
- package/constructs/Function.d.ts +4 -44
- package/constructs/Function.js +14 -50
- package/constructs/FunctionalStack.d.ts +2 -2
- package/constructs/Job.d.ts +23 -63
- package/constructs/Job.js +11 -32
- package/constructs/Metadata.d.ts +18 -20
- package/constructs/NextjsSite.d.ts +21 -5
- package/constructs/NextjsSite.js +67 -101
- package/constructs/Queue.js +10 -10
- package/constructs/RDS.d.ts +1 -1
- package/constructs/RDS.js +1 -1
- package/constructs/RemixSite.d.ts +0 -2
- package/constructs/RemixSite.js +20 -20
- package/constructs/Script.js +1 -1
- package/constructs/Secret.js +5 -3
- package/constructs/SolidStartSite.d.ts +2 -3
- package/constructs/SolidStartSite.js +42 -52
- package/constructs/SsrFunction.d.ts +22 -0
- package/constructs/SsrFunction.js +113 -0
- package/constructs/SsrSite.d.ts +104 -104
- package/constructs/SsrSite.js +196 -217
- package/constructs/Stack.d.ts +1 -20
- package/constructs/Stack.js +3 -65
- package/constructs/StaticSite.d.ts +33 -53
- package/constructs/StaticSite.js +92 -118
- package/constructs/Table.d.ts +1 -1
- package/constructs/Table.js +4 -4
- package/constructs/Topic.js +1 -1
- package/constructs/cdk/certificate-base.d.ts +18 -0
- package/constructs/cdk/certificate-base.js +26 -0
- package/constructs/cdk/dns-validated-certificate.d.ts +77 -0
- package/constructs/cdk/dns-validated-certificate.js +125 -0
- package/constructs/cdk/website-redirect.d.ts +53 -0
- package/constructs/cdk/website-redirect.js +77 -0
- package/constructs/deferred_task.d.ts +1 -1
- package/constructs/deprecated/NextjsSite.js +8 -6
- package/constructs/index.d.ts +0 -6
- package/constructs/index.js +0 -6
- package/constructs/util/apiGatewayV1AccessLog.d.ts +1 -1
- package/constructs/util/apiGatewayV2AccessLog.js +4 -4
- package/constructs/util/apiGatewayV2Domain.js +9 -2
- package/constructs/util/appSyncApiDomain.d.ts +1 -1
- package/constructs/util/appSyncApiDomain.js +9 -15
- package/constructs/util/duration.d.ts +1 -1
- package/constructs/util/functionBinding.js +1 -1
- package/constructs/util/permission.d.ts +3 -3
- package/constructs/util/permission.js +16 -18
- package/constructs/util/size.d.ts +1 -1
- package/constructs/util/warning.js +2 -2
- package/context/context.d.ts +2 -2
- package/context/context.js +4 -4
- package/context/handler.d.ts +1 -1
- package/credentials.d.ts +1 -1
- package/credentials.js +42 -6
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/iot.js +6 -2
- package/logger.js +3 -1
- package/node/api/index.d.ts +2 -3
- package/node/api/index.js +8 -2
- package/node/auth/adapter/adapter.d.ts +1 -1
- package/node/auth/adapter/facebook.js +1 -1
- package/node/auth/adapter/github.js +4 -4
- package/node/auth/adapter/google.d.ts +1 -1
- package/node/auth/adapter/google.js +2 -2
- package/node/auth/adapter/twitch.js +1 -1
- package/node/auth/session.d.ts +1 -1
- package/node/config/index.d.ts +2 -2
- package/node/config/index.js +3 -8
- package/node/job/index.d.ts +2 -2
- package/node/site/index.js +3 -5
- package/package.json +26 -21
- package/pothos.js +1 -0
- package/project.d.ts +47 -0
- package/{app.js → project.js} +60 -53
- package/runtime/handlers/dotnet.d.ts +1 -1
- package/runtime/handlers/dotnet.js +4 -4
- package/runtime/handlers/go.d.ts +1 -1
- package/runtime/handlers/go.js +3 -3
- package/runtime/handlers/java.d.ts +1 -1
- package/runtime/handlers/java.js +4 -4
- package/runtime/handlers/node.d.ts +1 -1
- package/runtime/handlers/node.js +60 -39
- package/runtime/handlers/python.d.ts +1 -1
- package/runtime/handlers/python.js +3 -3
- package/runtime/handlers.js +15 -12
- package/runtime/iot.js +3 -0
- package/runtime/runtime.d.ts +4 -0
- package/runtime/server.d.ts +3 -3
- package/runtime/server.js +11 -5
- package/runtime/workers.d.ts +4 -2
- package/runtime/workers.js +13 -3
- package/site-env.js +2 -1
- package/sst.mjs +6357 -20848
- package/stacks/app-metadata.d.ts +7 -0
- package/stacks/app-metadata.js +78 -0
- package/stacks/assembly.d.ts +1 -0
- package/stacks/assembly.js +4 -0
- package/stacks/build.d.ts +1 -1
- package/stacks/build.js +41 -48
- package/stacks/deploy.d.ts +1 -0
- package/stacks/deploy.js +128 -7
- package/stacks/diff.d.ts +8 -0
- package/stacks/diff.js +62 -0
- package/stacks/index.d.ts +3 -0
- package/stacks/index.js +3 -0
- package/stacks/metadata.d.ts +2 -0
- package/stacks/metadata.js +14 -12
- package/stacks/monitor.d.ts +8 -3
- package/stacks/monitor.js +38 -4
- package/stacks/remove.js +0 -4
- package/stacks/synth.d.ts +1 -0
- package/stacks/synth.js +27 -13
- package/support/base-site-archiver.mjs +1 -1
- package/support/bootstrap-metadata-function/index.mjs +68740 -0
- package/support/bridge/bridge.mjs +28 -28
- package/support/certificate-requestor/index.js +549 -0
- package/support/custom-resources/index.mjs +3824 -26567
- package/support/dotnet6-bootstrap/release/dotnet-bootstrap.deps.json +1 -1
- package/support/dotnet6-bootstrap/release/dotnet-bootstrap.runtimeconfig.json +1 -1
- package/support/edge-function/edge-lambda.mjs +2 -2
- package/support/job-invoker/index.mjs +26 -0
- package/support/nodejs-runtime/index.mjs +75 -72
- package/support/rds-migrator/index.mjs +22 -23
- package/support/remix-site-function/edge-server.js +1 -1
- package/support/script-function/index.mjs +30485 -0
- package/support/{edge-function-code-replacer → sls-nextjs-site-function-code-replacer}/lambda-code-updater.py +0 -0
- package/support/ssr-site-function-archiver.mjs +96 -0
- package/watcher.js +1 -1
- package/app.d.ts +0 -36
- package/constructs/DebugApp.d.ts +0 -49
- package/constructs/DebugApp.js +0 -63
- package/constructs/DebugStack.d.ts +0 -34
- package/constructs/DebugStack.js +0 -132
- 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 -54
- package/constructs/Script/cfn-response.d.ts +0 -19
- package/constructs/Script/cfn-response.js +0 -77
- package/constructs/Script/index.d.ts +0 -1
- package/constructs/Script/index.js +0 -78
- package/constructs/Script/outbound.d.ts +0 -10
- package/constructs/Script/outbound.js +0 -42
- package/constructs/Script/util.d.ts +0 -2
- package/constructs/Script/util.js +0 -11
- package/constructs/ViteStaticSite.d.ts +0 -32
- package/constructs/ViteStaticSite.js +0 -66
- package/support/astro-site-html-stub/index.html +0 -99
- package/support/base-site-archiver.cjs +0 -116
- package/support/nextjs-site-html-stub/index.html +0 -99
- package/support/remix-site-html-stub/index.html +0 -99
- package/support/solid-start-site-html-stub/index.html +0 -99
- package/support/static-site-stub/index.html +0 -90
package/cli/ui/deploy.js
CHANGED
|
@@ -3,66 +3,39 @@ import { Box, Text } from "ink";
|
|
|
3
3
|
import { useBus } from "../../bus.js";
|
|
4
4
|
import { Stacks } from "../../stacks/index.js";
|
|
5
5
|
import inkSpinner from "ink-spinner";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { Colors } from "../colors.js";
|
|
7
|
+
import { useProject } from "../../project.js";
|
|
8
8
|
// @ts-ignore
|
|
9
9
|
const { default: Spinner } = inkSpinner;
|
|
10
|
-
const FullScreen = (props) => {
|
|
11
|
-
const [size, setSize] = useState({
|
|
12
|
-
columns: process.stdout.columns,
|
|
13
|
-
rows: process.stdout.rows,
|
|
14
|
-
});
|
|
15
|
-
useEffect(() => {
|
|
16
|
-
function onResize() {
|
|
17
|
-
setSize({
|
|
18
|
-
columns: process.stdout.columns,
|
|
19
|
-
rows: process.stdout.rows,
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
process.stdout.on("resize", onResize);
|
|
23
|
-
return () => {
|
|
24
|
-
process.stdout.off("resize", onResize);
|
|
25
|
-
};
|
|
26
|
-
}, []);
|
|
27
|
-
return (React.createElement(Box, { width: size.columns, height: size.rows, flexDirection: "column" }, props.children));
|
|
28
|
-
};
|
|
29
10
|
export const DeploymentUI = (props) => {
|
|
30
|
-
const [stacks, setStacks] = useState(Object.fromEntries(props.stacks.map((s) => [s, ""])));
|
|
31
11
|
const [resources, setResources] = useState({});
|
|
32
12
|
useEffect(() => {
|
|
13
|
+
Colors.gap();
|
|
33
14
|
const bus = useBus();
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
[payload.properties.stackID]: "",
|
|
38
|
-
}));
|
|
39
|
-
});
|
|
40
|
-
const status = bus.subscribe("stack.status", (payload) => {
|
|
41
|
-
setStacks((prev) => ({
|
|
42
|
-
...prev,
|
|
43
|
-
[payload.properties.stackID]: payload.properties.status,
|
|
44
|
-
}));
|
|
45
|
-
});
|
|
46
|
-
const resourcesSub = bus.subscribe("stack.resources", (payload) => {
|
|
15
|
+
const event = bus.subscribe("stack.event", (payload) => {
|
|
16
|
+
const { event } = payload.properties;
|
|
17
|
+
// if (event.ResourceType === "AWS::CloudFormation::Stack") return;
|
|
47
18
|
setResources((previous) => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
19
|
+
if (Stacks.isFinal(event.ResourceStatus)) {
|
|
20
|
+
const readable = logicalIdToCdkPath(props.assembly, event.StackName, event.LogicalResourceId);
|
|
21
|
+
Colors.line(Colors.warning(Colors.prefix), readable
|
|
22
|
+
? Colors.dim(`${stackNameToId(event.StackName)} ${readable} ${event.ResourceType}`)
|
|
23
|
+
: Colors.dim(`${stackNameToId(event.StackName)} ${event.ResourceType}`), Stacks.isFailed(event.ResourceStatus)
|
|
24
|
+
? Colors.danger(event.ResourceStatus)
|
|
25
|
+
: Colors.dim(event.ResourceStatus), Stacks.isFailed(event.ResourceStatus) && event.ResourceStatusReason
|
|
26
|
+
? event.ResourceStatusReason
|
|
27
|
+
: "");
|
|
28
|
+
const { [event.LogicalResourceId]: _, ...next } = previous;
|
|
29
|
+
return next;
|
|
30
|
+
}
|
|
56
31
|
return {
|
|
57
32
|
...previous,
|
|
58
|
-
[payload.properties.
|
|
33
|
+
[payload.properties.event.LogicalResourceId]: payload.properties.event,
|
|
59
34
|
};
|
|
60
35
|
});
|
|
61
36
|
});
|
|
62
37
|
return () => {
|
|
63
|
-
bus.unsubscribe(
|
|
64
|
-
bus.unsubscribe(update);
|
|
65
|
-
bus.unsubscribe(status);
|
|
38
|
+
bus.unsubscribe(event);
|
|
66
39
|
};
|
|
67
40
|
}, []);
|
|
68
41
|
function color(status) {
|
|
@@ -72,71 +45,98 @@ export const DeploymentUI = (props) => {
|
|
|
72
45
|
return "green";
|
|
73
46
|
return "yellow";
|
|
74
47
|
}
|
|
75
|
-
return (React.createElement(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
React.createElement(
|
|
81
|
-
Object.entries(stacks).map(([stackID, status]) => {
|
|
82
|
-
return (React.createElement(React.Fragment, { key: stackID },
|
|
48
|
+
return (React.createElement(Box, { flexDirection: "column" },
|
|
49
|
+
Object.entries(resources)
|
|
50
|
+
.slice(0, process.stdout.rows - 2)
|
|
51
|
+
.map(([_, evt], index) => {
|
|
52
|
+
const readable = logicalIdToCdkPath(props.assembly, evt.StackName, evt.LogicalResourceId);
|
|
53
|
+
return (React.createElement(Box, { key: index },
|
|
83
54
|
React.createElement(Text, null,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
" ",
|
|
98
|
-
resource.ResourceType,
|
|
99
|
-
" ",
|
|
100
|
-
resource.LogicalResourceId,
|
|
101
|
-
" ",
|
|
102
|
-
resource.ResourceStatusReason,
|
|
103
|
-
" "),
|
|
104
|
-
React.createElement(Text, { color: color(resource.ResourceStatus || "") }, resource.ResourceStatus))))));
|
|
105
|
-
})));
|
|
55
|
+
React.createElement(Spinner, null),
|
|
56
|
+
" ",
|
|
57
|
+
readable
|
|
58
|
+
? `${stackNameToId(evt.StackName)} ${readable} ${evt.ResourceType}`
|
|
59
|
+
: `${stackNameToId(evt.StackName)} ${evt.ResourceType}`,
|
|
60
|
+
" "),
|
|
61
|
+
React.createElement(Text, { color: color(evt.ResourceStatus || "") }, evt.ResourceStatus)));
|
|
62
|
+
}),
|
|
63
|
+
Object.entries(resources).length === 0 && (React.createElement(Box, null,
|
|
64
|
+
React.createElement(Text, null,
|
|
65
|
+
React.createElement(Spinner, null),
|
|
66
|
+
" ",
|
|
67
|
+
React.createElement(Text, { dimColor: true }, "Deploying..."))))));
|
|
106
68
|
};
|
|
107
|
-
export function printDeploymentResults(results) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if (
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (key.startsWith("Export"))
|
|
122
|
-
return false;
|
|
123
|
-
if (key.includes("SstSiteEnv"))
|
|
124
|
-
return false;
|
|
125
|
-
return true;
|
|
126
|
-
});
|
|
127
|
-
if (outputs.length > 0) {
|
|
128
|
-
console.log(` ${blue("Outputs:")}`);
|
|
129
|
-
for (const key of Object.keys(Object.fromEntries(outputs)).sort()) {
|
|
130
|
-
const value = result.outputs[key];
|
|
131
|
-
console.log(bold(` ${key}: ${value}`));
|
|
69
|
+
export function printDeploymentResults(assembly, results, remove) {
|
|
70
|
+
// Print success stacks
|
|
71
|
+
const success = Object.entries(results).filter(([_stack, result]) => Stacks.isSuccess(result.status));
|
|
72
|
+
if (success.length) {
|
|
73
|
+
Colors.gap();
|
|
74
|
+
Colors.line(Colors.success(`✔`), Colors.bold(remove ? ` Removed:` : ` Deployed:`));
|
|
75
|
+
for (const [stack, result] of success) {
|
|
76
|
+
const outputs = Object.entries(result.outputs).filter(([key, _]) => !key.includes("SstSiteEnv"));
|
|
77
|
+
Colors.line(` ${Colors.dim(stackNameToId(stack))}`);
|
|
78
|
+
if (outputs.length > 0) {
|
|
79
|
+
for (const key of Object.keys(Object.fromEntries(outputs)).sort()) {
|
|
80
|
+
const value = result.outputs[key];
|
|
81
|
+
Colors.line(` ${Colors.bold.dim(key + ":")} ${value}`);
|
|
82
|
+
}
|
|
132
83
|
}
|
|
133
84
|
}
|
|
134
|
-
|
|
135
|
-
|
|
85
|
+
Colors.gap();
|
|
86
|
+
}
|
|
87
|
+
// Print failed stacks
|
|
88
|
+
const failed = Object.entries(results).filter(([_stack, result]) => Stacks.isFailed(result.status));
|
|
89
|
+
if (failed.length) {
|
|
90
|
+
Colors.gap();
|
|
91
|
+
Colors.line(`${Colors.danger(`✖`)} ${Colors.bold.dim(`Errors`)}`);
|
|
92
|
+
for (const [stack, result] of failed) {
|
|
93
|
+
Colors.line(` ${Colors.dim(stackNameToId(stack))} ${Colors.dim(result.status)}`);
|
|
136
94
|
for (const [id, error] of Object.entries(result.errors)) {
|
|
137
|
-
|
|
95
|
+
const readable = logicalIdToCdkPath(assembly, stack, id) || id;
|
|
96
|
+
Colors.line(` ${Colors.danger.bold(readable + ":")} ${error}`);
|
|
97
|
+
const helper = getHelper(error);
|
|
98
|
+
if (helper) {
|
|
99
|
+
Colors.line(` ${Colors.warning.bold("⮑ Hint:")} ${helper}`);
|
|
100
|
+
}
|
|
138
101
|
}
|
|
139
102
|
}
|
|
103
|
+
Colors.gap();
|
|
104
|
+
}
|
|
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
|
+
}
|
|
118
|
+
function getHelper(error) {
|
|
119
|
+
return (getApiAccessLogPermissionsHelper(error) ||
|
|
120
|
+
getAppSyncMultiResolverHelper(error) ||
|
|
121
|
+
getApiLogRoleHelper(error));
|
|
122
|
+
}
|
|
123
|
+
function getApiAccessLogPermissionsHelper(error) {
|
|
124
|
+
// Can run into this issue when enabling access logs for API Gateway
|
|
125
|
+
// note: this should be handled in SST as access log group names are now
|
|
126
|
+
// hardcoded with /aws/vendedlogs/apis prefix.
|
|
127
|
+
if (error.indexOf("Insufficient permissions to enable logging") > -1) {
|
|
128
|
+
return `This is a common deploy error. Check out this GitHub issue for more details - https://github.com/serverless-stack/sst/issues/125`;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
function getAppSyncMultiResolverHelper(error) {
|
|
132
|
+
// Can run into this issue when updating an AppSyncApi resolver
|
|
133
|
+
if (error.indexOf("Only one resolver is allowed per field. (Service: AWSAppSync") > -1) {
|
|
134
|
+
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`;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function getApiLogRoleHelper(error) {
|
|
138
|
+
// Can run into this issue when enabling access logs for WebSocketApi
|
|
139
|
+
if (error.indexOf("CloudWatch Logs role ARN must be set in account settings to enable logging (Service: AmazonApiGatewayV2") > -1) {
|
|
140
|
+
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/`;
|
|
140
141
|
}
|
|
141
|
-
console.log();
|
|
142
142
|
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { dim } from "colorette";
|
|
2
|
+
import { Text } from "ink";
|
|
3
|
+
import inkSpinner from "ink-spinner";
|
|
4
|
+
import React, { useEffect, useState } from "react";
|
|
5
|
+
import { useBus } from "../../bus.js";
|
|
6
|
+
import { useFunctions } from "../../constructs/Function.js";
|
|
7
|
+
import { Colors } from "../colors.js";
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
const { default: Spinner } = inkSpinner;
|
|
10
|
+
export function Functions() {
|
|
11
|
+
const [functions, setFunctions] = useState({});
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
const bus = useBus();
|
|
14
|
+
const invoke = bus.subscribe("function.invoked", (evt) => {
|
|
15
|
+
setFunctions((functions) => {
|
|
16
|
+
setTimeout(() => {
|
|
17
|
+
setFunctions((functions) => {
|
|
18
|
+
const existing = functions[evt.properties.requestID];
|
|
19
|
+
if (!existing)
|
|
20
|
+
return functions;
|
|
21
|
+
return { ...functions };
|
|
22
|
+
});
|
|
23
|
+
}, 500);
|
|
24
|
+
return {
|
|
25
|
+
...functions,
|
|
26
|
+
[evt.properties.requestID]: {
|
|
27
|
+
requestID: evt.properties.requestID,
|
|
28
|
+
functionID: evt.properties.functionID,
|
|
29
|
+
started: Date.now(),
|
|
30
|
+
logs: [],
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
const stdout = bus.subscribe("worker.stdout", (evt) => {
|
|
36
|
+
setFunctions((functions) => {
|
|
37
|
+
const existing = functions[evt.properties.requestID];
|
|
38
|
+
if (!existing)
|
|
39
|
+
return functions;
|
|
40
|
+
return {
|
|
41
|
+
...functions,
|
|
42
|
+
[evt.properties.requestID]: {
|
|
43
|
+
...existing,
|
|
44
|
+
logs: [...existing.logs, evt.properties.message],
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
// This is all ugly but the timeouts are for UI smootheness
|
|
50
|
+
const success = bus.subscribe("function.success", (evt) => {
|
|
51
|
+
function print(input, diff) {
|
|
52
|
+
setTimeout(() => {
|
|
53
|
+
console.log(Colors.primary(` ➜ `), useFunctions().fromID(input.functionID).handler);
|
|
54
|
+
for (const log of input.logs) {
|
|
55
|
+
console.log(` ${dim(log)}`);
|
|
56
|
+
}
|
|
57
|
+
console.log(` ${dim(`Done in ${diff}ms`)}`);
|
|
58
|
+
console.log();
|
|
59
|
+
}, diff > 500 ? 60 : 0);
|
|
60
|
+
}
|
|
61
|
+
setFunctions((functions) => {
|
|
62
|
+
const { [evt.properties.requestID]: existing, ...next } = functions;
|
|
63
|
+
if (!existing)
|
|
64
|
+
return functions;
|
|
65
|
+
const diff = Date.now() - existing.started;
|
|
66
|
+
if (diff > 500 && diff < 1500) {
|
|
67
|
+
setTimeout(() => {
|
|
68
|
+
setFunctions((functions) => {
|
|
69
|
+
const { [evt.properties.requestID]: existing, ...next } = functions;
|
|
70
|
+
print(existing, diff);
|
|
71
|
+
return next;
|
|
72
|
+
});
|
|
73
|
+
}, 1500 - diff);
|
|
74
|
+
return functions;
|
|
75
|
+
}
|
|
76
|
+
print(existing, diff);
|
|
77
|
+
return next;
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
const error = bus.subscribe("function.error", (evt) => {
|
|
81
|
+
function print(input, diff) {
|
|
82
|
+
setTimeout(() => {
|
|
83
|
+
console.log(Colors.primary(` ➜ `), useFunctions().fromID(input.functionID).handler);
|
|
84
|
+
for (const log of input.logs) {
|
|
85
|
+
console.log(` ${dim(log)}`);
|
|
86
|
+
}
|
|
87
|
+
console.log(` ${Colors.danger(evt.properties.errorMessage)}`);
|
|
88
|
+
for (const line of evt.properties.trace || []) {
|
|
89
|
+
console.log(` ${dim(line)}`);
|
|
90
|
+
}
|
|
91
|
+
console.log();
|
|
92
|
+
}, diff > 500 ? 60 : 0);
|
|
93
|
+
}
|
|
94
|
+
setFunctions((functions) => {
|
|
95
|
+
const { [evt.properties.requestID]: existing, ...next } = functions;
|
|
96
|
+
if (!existing)
|
|
97
|
+
return functions;
|
|
98
|
+
const diff = Date.now() - existing.started;
|
|
99
|
+
if (diff > 500 && diff < 1500) {
|
|
100
|
+
setTimeout(() => {
|
|
101
|
+
setFunctions((functions) => {
|
|
102
|
+
const { [evt.properties.requestID]: existing, ...next } = functions;
|
|
103
|
+
print(existing, diff);
|
|
104
|
+
return next;
|
|
105
|
+
});
|
|
106
|
+
}, 1500 - diff);
|
|
107
|
+
return functions;
|
|
108
|
+
}
|
|
109
|
+
print(existing, diff);
|
|
110
|
+
return next;
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
return () => {
|
|
114
|
+
bus.unsubscribe(invoke);
|
|
115
|
+
bus.unsubscribe(success);
|
|
116
|
+
bus.unsubscribe(error);
|
|
117
|
+
bus.unsubscribe(stdout);
|
|
118
|
+
};
|
|
119
|
+
}, []);
|
|
120
|
+
return (React.createElement(React.Fragment, null, Object.values(functions)
|
|
121
|
+
.filter((f) => Date.now() - f.started >= 500)
|
|
122
|
+
.map((evt) => (React.createElement(React.Fragment, { key: evt.requestID },
|
|
123
|
+
React.createElement(Text, null,
|
|
124
|
+
" ",
|
|
125
|
+
React.createElement(Spinner, null),
|
|
126
|
+
" ",
|
|
127
|
+
useFunctions().fromID(evt.functionID).handler),
|
|
128
|
+
evt.logs.map((log, index) => (React.createElement(Text, { dimColor: true, key: index },
|
|
129
|
+
" ",
|
|
130
|
+
log))),
|
|
131
|
+
React.createElement(Text, null, " "))))));
|
|
132
|
+
}
|
package/cli/ui/header.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useProject } from "../../project.js";
|
|
2
|
+
import { Colors } from "../colors.js";
|
|
3
|
+
import { useLocalServerConfig } from "../local/server.js";
|
|
4
|
+
export async function printHeader(input) {
|
|
5
|
+
const project = useProject();
|
|
6
|
+
Colors.line(`${Colors.primary.bold(`SST v${project.version}`)} ${input.hint ? Colors.dim(`ready!`) : ""}`);
|
|
7
|
+
Colors.gap();
|
|
8
|
+
Colors.line(`${Colors.primary(`➜`)} ${Colors.bold("App:")} ${project.config.name}`);
|
|
9
|
+
Colors.line(`${Colors.primary(` `)} ${Colors.bold("Stage:")} ${project.config.stage}`);
|
|
10
|
+
if (input.console) {
|
|
11
|
+
const local = await useLocalServerConfig();
|
|
12
|
+
Colors.line(`${Colors.primary(` `)} ${Colors.bold("Console:")} ${Colors.link(local.url)}`);
|
|
13
|
+
}
|
|
14
|
+
Colors.gap();
|
|
15
|
+
}
|
|
16
|
+
export function printConsole() { }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function stackNameToId(stack: string): string;
|
package/cli/ui/stack.js
ADDED
package/config.d.ts
CHANGED
package/config.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DeleteParameterCommand, GetParameterCommand, GetParametersByPathCommand, PutParameterCommand, SSMClient, } from "@aws-sdk/client-ssm";
|
|
2
2
|
import { GetFunctionConfigurationCommand, LambdaClient, UpdateFunctionConfigurationCommand, } from "@aws-sdk/client-lambda";
|
|
3
3
|
import { pipe, map } from "remeda";
|
|
4
|
-
import { useProject } from "./
|
|
4
|
+
import { useProject } from "./project.js";
|
|
5
5
|
import { useAWSClient } from "./credentials.js";
|
|
6
6
|
import { Stacks } from "./stacks/index.js";
|
|
7
7
|
export var Config;
|
|
@@ -30,7 +30,7 @@ export var Config;
|
|
|
30
30
|
}
|
|
31
31
|
Config.parameters = parameters;
|
|
32
32
|
function envFor(input) {
|
|
33
|
-
return `SST_${input.type}_${input.prop}_${input.id}`;
|
|
33
|
+
return `SST_${input.type}_${input.prop}_${normalizeID(input.id)}`;
|
|
34
34
|
}
|
|
35
35
|
Config.envFor = envFor;
|
|
36
36
|
function pathFor(input) {
|
|
@@ -62,9 +62,9 @@ export var Config;
|
|
|
62
62
|
const project = useProject();
|
|
63
63
|
const parameters = await Config.parameters();
|
|
64
64
|
const env = {
|
|
65
|
-
SST_APP: project.name,
|
|
66
|
-
SST_STAGE: project.stage,
|
|
67
|
-
...pipe(parameters, map((p) => [
|
|
65
|
+
SST_APP: project.config.name,
|
|
66
|
+
SST_STAGE: project.config.stage,
|
|
67
|
+
...pipe(parameters, map((p) => [envFor(p), p.value]), Object.fromEntries),
|
|
68
68
|
};
|
|
69
69
|
return env;
|
|
70
70
|
}
|
|
@@ -156,11 +156,11 @@ const SECRET_UPDATED_AT_ENV = "SST_ADMIN_SECRET_UPDATED_AT";
|
|
|
156
156
|
const PREFIX = {
|
|
157
157
|
get STAGE() {
|
|
158
158
|
const project = useProject();
|
|
159
|
-
return `/sst/${project.name}/${project.stage}/`;
|
|
159
|
+
return `/sst/${project.config.name}/${project.config.stage}/`;
|
|
160
160
|
},
|
|
161
161
|
get FALLBACK() {
|
|
162
162
|
const project = useProject();
|
|
163
|
-
return `/sst/${project.name}/${FALLBACK_STAGE}/`;
|
|
163
|
+
return `/sst/${project.config.name}/${FALLBACK_STAGE}/`;
|
|
164
164
|
},
|
|
165
165
|
};
|
|
166
166
|
function parse(ssmName) {
|
|
@@ -168,6 +168,6 @@ function parse(ssmName) {
|
|
|
168
168
|
return {
|
|
169
169
|
type: parts[4],
|
|
170
170
|
id: parts[5],
|
|
171
|
-
prop: parts.slice(6),
|
|
171
|
+
prop: parts.slice(6).join("/"),
|
|
172
172
|
};
|
|
173
173
|
}
|
package/constructs/Api.d.ts
CHANGED
|
@@ -14,8 +14,8 @@ import * as apigV2Cors from "./util/apiGatewayV2Cors.js";
|
|
|
14
14
|
import * as apigV2Domain from "./util/apiGatewayV2Domain.js";
|
|
15
15
|
import * as apigV2AccessLog from "./util/apiGatewayV2AccessLog.js";
|
|
16
16
|
declare const PayloadFormatVersions: readonly ["1.0", "2.0"];
|
|
17
|
-
export
|
|
18
|
-
export
|
|
17
|
+
export type ApiPayloadFormatVersion = (typeof PayloadFormatVersions)[number];
|
|
18
|
+
export type ApiAuthorizer = ApiUserPoolAuthorizer | ApiJwtAuthorizer | ApiLambdaAuthorizer;
|
|
19
19
|
interface ApiBaseAuthorizer {
|
|
20
20
|
/**
|
|
21
21
|
* The name of the authorizer.
|
|
@@ -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
|
|
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;
|