sst 2.0.0-rc.54 → 2.0.0-rc.55
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/cdk/cloudformation-deployments-wrapper.js +8 -3
- package/cli/commands/deploy.js +2 -2
- package/cli/commands/dev.js +2 -2
- package/cli/commands/remove.js +1 -1
- package/constructs/Api.d.ts +1 -1
- package/constructs/Api.js +3 -6
- package/constructs/ApiGatewayV1Api.js +2 -2
- package/constructs/Auth.js +16 -16
- package/constructs/Cognito.js +28 -28
- package/constructs/EdgeFunction.js +8 -4
- package/constructs/NextjsSite.js +6 -4
- package/constructs/Queue.js +10 -10
- package/constructs/Secret.js +2 -2
- package/constructs/SolidStartSite.js +3 -1
- package/constructs/SsrSite.js +0 -1
- package/constructs/Table.js +4 -4
- package/constructs/Topic.js +1 -1
- package/constructs/deprecated/NextjsSite.js +3 -1
- package/constructs/util/apiGatewayV2AccessLog.js +4 -4
- package/constructs/util/apiGatewayV2Domain.js +1 -3
- package/constructs/util/appSyncApiDomain.js +9 -15
- package/constructs/util/permission.js +12 -12
- package/constructs/util/warning.js +2 -2
- package/node/auth/adapter/facebook.js +1 -1
- package/node/auth/adapter/google.js +2 -2
- package/node/auth/adapter/twitch.js +1 -1
- package/node/config/index.js +3 -8
- package/node/site/index.js +3 -5
- package/package.json +1 -1
- package/sst.mjs +17 -27
- package/stacks/app-metadata.js +1 -1
- package/stacks/synth.js +2 -2
- package/support/bootstrap-metadata-function/index.mjs +36 -25
- package/support/custom-resources/index.mjs +1 -4
- package/support/dotnet6-bootstrap/release/dotnet-bootstrap.deps.json +1 -1
- package/support/dotnet6-bootstrap/release/dotnet-bootstrap.runtimeconfig.json +1 -1
- package/support/remix-site-function/edge-server.js +1 -1
|
@@ -62,7 +62,7 @@ const useDeployment = Context.memo(() => {
|
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
64
|
return state.get(sdkProvider);
|
|
65
|
-
}
|
|
65
|
+
},
|
|
66
66
|
};
|
|
67
67
|
});
|
|
68
68
|
async function deployStack(options) {
|
|
@@ -99,13 +99,18 @@ async function deployStack(options) {
|
|
|
99
99
|
parallel: options.assetParallelism,
|
|
100
100
|
});
|
|
101
101
|
return {
|
|
102
|
-
isUpdate: cloudFormationStack.exists &&
|
|
102
|
+
isUpdate: cloudFormationStack.exists &&
|
|
103
|
+
cloudFormationStack.stackStatus.name !== "REVIEW_IN_PROGRESS",
|
|
103
104
|
params: {
|
|
104
105
|
StackName: deployName,
|
|
105
106
|
TemplateBody: bodyParameter.TemplateBody,
|
|
106
107
|
TemplateURL: bodyParameter.TemplateURL,
|
|
107
108
|
Parameters: stackParams.apiParameters,
|
|
108
|
-
Capabilities: [
|
|
109
|
+
Capabilities: [
|
|
110
|
+
"CAPABILITY_IAM",
|
|
111
|
+
"CAPABILITY_NAMED_IAM",
|
|
112
|
+
"CAPABILITY_AUTO_EXPAND",
|
|
113
|
+
],
|
|
109
114
|
Tags: options.tags,
|
|
110
115
|
},
|
|
111
116
|
};
|
package/cli/commands/deploy.js
CHANGED
|
@@ -16,7 +16,7 @@ export const deploy = (program) => program.command("deploy [filter]", "Deploy yo
|
|
|
16
16
|
const { createSpinner } = await import("../spinner.js");
|
|
17
17
|
const { dim, blue, bold } = await import("colorette");
|
|
18
18
|
const { useProject } = await import("../../project.js");
|
|
19
|
-
const { loadAssembly, useAppMetadata, saveAppMetadata, Stacks
|
|
19
|
+
const { loadAssembly, useAppMetadata, saveAppMetadata, Stacks } = await import("../../stacks/index.js");
|
|
20
20
|
const { render } = await import("ink");
|
|
21
21
|
const { DeploymentUI } = await import("../ui/deploy.js");
|
|
22
22
|
const { mapValues } = await import("remeda");
|
|
@@ -27,7 +27,7 @@ export const deploy = (program) => program.command("deploy [filter]", "Deploy yo
|
|
|
27
27
|
]);
|
|
28
28
|
// Check app mode changed
|
|
29
29
|
if (appMetadata && appMetadata.mode !== "deploy") {
|
|
30
|
-
if (!await promptChangeMode()) {
|
|
30
|
+
if (!(await promptChangeMode())) {
|
|
31
31
|
process.exit(0);
|
|
32
32
|
}
|
|
33
33
|
}
|
package/cli/commands/dev.js
CHANGED
|
@@ -10,7 +10,7 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
|
|
|
10
10
|
const { useRuntimeServer } = await import("../../runtime/server.js");
|
|
11
11
|
const { useBus } = await import("../../bus.js");
|
|
12
12
|
const { useWatcher } = await import("../../watcher.js");
|
|
13
|
-
const { useAppMetadata, saveAppMetadata, Stacks
|
|
13
|
+
const { useAppMetadata, saveAppMetadata, Stacks } = await import("../../stacks/index.js");
|
|
14
14
|
const { Logger } = await import("../../logger.js");
|
|
15
15
|
const { createSpinner } = await import("../spinner.js");
|
|
16
16
|
const { bold, dim, yellow } = await import("colorette");
|
|
@@ -231,7 +231,7 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
|
|
|
231
231
|
]);
|
|
232
232
|
// Check app mode changed
|
|
233
233
|
if (appMetadata && appMetadata.mode !== "dev") {
|
|
234
|
-
if (!await promptChangeMode()) {
|
|
234
|
+
if (!(await promptChangeMode())) {
|
|
235
235
|
process.exit(0);
|
|
236
236
|
}
|
|
237
237
|
}
|
package/cli/commands/remove.js
CHANGED
|
@@ -5,7 +5,7 @@ export const remove = (program) => program.command("remove [filter]", "Remove yo
|
|
|
5
5
|
const React = await import("react");
|
|
6
6
|
const { dim, blue, bold } = await import("colorette");
|
|
7
7
|
const { useProject } = await import("../../project.js");
|
|
8
|
-
const { loadAssembly, clearAppMetadata, Stacks
|
|
8
|
+
const { loadAssembly, clearAppMetadata, Stacks } = await import("../../stacks/index.js");
|
|
9
9
|
const { render } = await import("ink");
|
|
10
10
|
const { DeploymentUI } = await import("../ui/deploy.js");
|
|
11
11
|
const { printDeploymentResults } = await import("../ui/deploy.js");
|
package/constructs/Api.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ 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 type ApiPayloadFormatVersion = typeof PayloadFormatVersions[number];
|
|
17
|
+
export type ApiPayloadFormatVersion = (typeof PayloadFormatVersions)[number];
|
|
18
18
|
export type ApiAuthorizer = ApiUserPoolAuthorizer | ApiJwtAuthorizer | ApiLambdaAuthorizer;
|
|
19
19
|
interface ApiBaseAuthorizer {
|
|
20
20
|
/**
|
package/constructs/Api.js
CHANGED
|
@@ -127,8 +127,7 @@ export class Api extends Construct {
|
|
|
127
127
|
const route = this.routesData[this.normalizeRouteKey(routeKey)];
|
|
128
128
|
if (!route)
|
|
129
129
|
return;
|
|
130
|
-
if (route.type === "function" ||
|
|
131
|
-
route.type === "graphql") {
|
|
130
|
+
if (route.type === "function" || route.type === "graphql") {
|
|
132
131
|
return route.function;
|
|
133
132
|
}
|
|
134
133
|
}
|
|
@@ -143,8 +142,7 @@ export class Api extends Construct {
|
|
|
143
142
|
*/
|
|
144
143
|
bind(constructs) {
|
|
145
144
|
for (const route of Object.values(this.routesData)) {
|
|
146
|
-
if (route.type === "function" ||
|
|
147
|
-
route.type === "graphql") {
|
|
145
|
+
if (route.type === "function" || route.type === "graphql") {
|
|
148
146
|
route.function.bind(constructs);
|
|
149
147
|
}
|
|
150
148
|
}
|
|
@@ -183,8 +181,7 @@ export class Api extends Construct {
|
|
|
183
181
|
*/
|
|
184
182
|
attachPermissions(permissions) {
|
|
185
183
|
for (const route of Object.values(this.routesData)) {
|
|
186
|
-
if (route.type === "function" ||
|
|
187
|
-
route.type === "graphql") {
|
|
184
|
+
if (route.type === "function" || route.type === "graphql") {
|
|
188
185
|
route.function.attachPermissions(permissions);
|
|
189
186
|
}
|
|
190
187
|
}
|
|
@@ -665,7 +665,7 @@ export class ApiGatewayV1Api extends Construct {
|
|
|
665
665
|
const [routeProps, lambda] = (() => {
|
|
666
666
|
if (Fn.isInlineDefinition(routeValue)) {
|
|
667
667
|
const routeProps = {
|
|
668
|
-
function: routeValue
|
|
668
|
+
function: routeValue,
|
|
669
669
|
};
|
|
670
670
|
return [
|
|
671
671
|
routeProps,
|
|
@@ -709,7 +709,7 @@ export class ApiGatewayV1Api extends Construct {
|
|
|
709
709
|
const root = scope.node.root;
|
|
710
710
|
if (root.local) {
|
|
711
711
|
lambda.addEnvironment("SST_DEBUG_IS_API_ROUTE", "1", {
|
|
712
|
-
removeInEdge: true
|
|
712
|
+
removeInEdge: true,
|
|
713
713
|
});
|
|
714
714
|
}
|
|
715
715
|
this.functions[routeKey] = lambda;
|
package/constructs/Auth.js
CHANGED
|
@@ -2,7 +2,7 @@ import * as ssm from "aws-cdk-lib/aws-ssm";
|
|
|
2
2
|
import { Effect, PolicyStatement } from "aws-cdk-lib/aws-iam";
|
|
3
3
|
import { Construct } from "constructs";
|
|
4
4
|
import { Stack } from "./Stack.js";
|
|
5
|
-
import { ENVIRONMENT_PLACEHOLDER, getEnvironmentKey, getParameterPath } from "./util/functionBinding.js";
|
|
5
|
+
import { ENVIRONMENT_PLACEHOLDER, getEnvironmentKey, getParameterPath, } from "./util/functionBinding.js";
|
|
6
6
|
import { CustomResource } from "aws-cdk-lib";
|
|
7
7
|
const PUBLIC_KEY_PROP = "publicKey";
|
|
8
8
|
const PRIVATE_KEY_PROP = "privateKey";
|
|
@@ -42,15 +42,15 @@ export class Auth extends Construct {
|
|
|
42
42
|
resourceType: "Custom::AuthKeys",
|
|
43
43
|
properties: {
|
|
44
44
|
publicPath: getParameterPath(this, PUBLIC_KEY_PROP),
|
|
45
|
-
privatePath: getParameterPath(this, PRIVATE_KEY_PROP)
|
|
46
|
-
}
|
|
45
|
+
privatePath: getParameterPath(this, PRIVATE_KEY_PROP),
|
|
46
|
+
},
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
/** @internal */
|
|
50
50
|
getConstructMetadata() {
|
|
51
51
|
return {
|
|
52
52
|
type: "Auth",
|
|
53
|
-
data: {}
|
|
53
|
+
data: {},
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
56
|
/** @internal */
|
|
@@ -62,14 +62,14 @@ export class Auth extends Construct {
|
|
|
62
62
|
publicKey: {
|
|
63
63
|
environment: ENVIRONMENT_PLACEHOLDER,
|
|
64
64
|
// SSM parameters will be created by the custom resource
|
|
65
|
-
parameter: undefined
|
|
66
|
-
}
|
|
65
|
+
parameter: undefined,
|
|
66
|
+
},
|
|
67
67
|
},
|
|
68
68
|
permissions: {
|
|
69
69
|
"ssm:GetParameters": [
|
|
70
|
-
`arn:${Stack.of(this).partition}:ssm:${app.region}:${app.account}:parameter${getParameterPath(this, PUBLIC_KEY_PROP)}
|
|
71
|
-
]
|
|
72
|
-
}
|
|
70
|
+
`arn:${Stack.of(this).partition}:ssm:${app.region}:${app.account}:parameter${getParameterPath(this, PUBLIC_KEY_PROP)}`,
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
75
|
/**
|
|
@@ -93,7 +93,7 @@ export class Auth extends Construct {
|
|
|
93
93
|
throw new Error("This Auth construct has already been attached to this Api construct.");
|
|
94
94
|
}
|
|
95
95
|
// Validate: one Api can only have one Auth attached to it
|
|
96
|
-
if (Array.from(Auth.list).some(auth => auth.apis.has(props.api))) {
|
|
96
|
+
if (Array.from(Auth.list).some((auth) => auth.apis.has(props.api))) {
|
|
97
97
|
throw new Error("This Api construct already has an Auth construct attached.");
|
|
98
98
|
}
|
|
99
99
|
const prefix = props.prefix || "/auth";
|
|
@@ -101,8 +101,8 @@ export class Auth extends Construct {
|
|
|
101
101
|
props.api.addRoutes(scope, {
|
|
102
102
|
[path]: {
|
|
103
103
|
type: "function",
|
|
104
|
-
function: this.authenticator
|
|
105
|
-
}
|
|
104
|
+
function: this.authenticator,
|
|
105
|
+
},
|
|
106
106
|
});
|
|
107
107
|
// Auth construct has two types of Function bindinds:
|
|
108
108
|
// - Api routes: bindings defined in `getFunctionBinding()`
|
|
@@ -117,9 +117,9 @@ export class Auth extends Construct {
|
|
|
117
117
|
actions: ["ssm:GetParameters"],
|
|
118
118
|
effect: Effect.ALLOW,
|
|
119
119
|
resources: [
|
|
120
|
-
`arn:${Stack.of(this).partition}:ssm:${app.region}:${app.account}:parameter${getParameterPath(this, "*")}
|
|
121
|
-
]
|
|
122
|
-
})
|
|
120
|
+
`arn:${Stack.of(this).partition}:ssm:${app.region}:${app.account}:parameter${getParameterPath(this, "*")}`,
|
|
121
|
+
],
|
|
122
|
+
}),
|
|
123
123
|
]);
|
|
124
124
|
}
|
|
125
125
|
// Create a parameter for prefix
|
|
@@ -128,7 +128,7 @@ export class Auth extends Construct {
|
|
|
128
128
|
if (this.apis.size === 0) {
|
|
129
129
|
new ssm.StringParameter(this, "prefix", {
|
|
130
130
|
parameterName: getParameterPath(this, PREFIX_PROP),
|
|
131
|
-
stringValue: prefix
|
|
131
|
+
stringValue: prefix,
|
|
132
132
|
});
|
|
133
133
|
}
|
|
134
134
|
this.apis.add(props.api);
|
package/constructs/Cognito.js
CHANGED
|
@@ -2,9 +2,9 @@ import { Construct } from "constructs";
|
|
|
2
2
|
import * as iam from "aws-cdk-lib/aws-iam";
|
|
3
3
|
import * as cognito from "aws-cdk-lib/aws-cognito";
|
|
4
4
|
import { Stack } from "./Stack.js";
|
|
5
|
-
import { getFunctionRef, isCDKConstruct } from "./Construct.js";
|
|
6
|
-
import { Function as Fn } from "./Function.js";
|
|
7
|
-
import { attachPermissionsToRole, attachPermissionsToPolicy } from "./util/permission.js";
|
|
5
|
+
import { getFunctionRef, isCDKConstruct, } from "./Construct.js";
|
|
6
|
+
import { Function as Fn, } from "./Function.js";
|
|
7
|
+
import { attachPermissionsToRole, attachPermissionsToPolicy, } from "./util/permission.js";
|
|
8
8
|
const CognitoUserPoolTriggerOperationMapping = {
|
|
9
9
|
createAuthChallenge: cognito.UserPoolOperation.CREATE_AUTH_CHALLENGE,
|
|
10
10
|
customEmailSender: cognito.UserPoolOperation.CUSTOM_EMAIL_SENDER,
|
|
@@ -17,7 +17,7 @@ const CognitoUserPoolTriggerOperationMapping = {
|
|
|
17
17
|
preSignUp: cognito.UserPoolOperation.PRE_SIGN_UP,
|
|
18
18
|
preTokenGeneration: cognito.UserPoolOperation.PRE_TOKEN_GENERATION,
|
|
19
19
|
userMigration: cognito.UserPoolOperation.USER_MIGRATION,
|
|
20
|
-
verifyAuthChallengeResponse: cognito.UserPoolOperation.VERIFY_AUTH_CHALLENGE_RESPONSE
|
|
20
|
+
verifyAuthChallengeResponse: cognito.UserPoolOperation.VERIFY_AUTH_CHALLENGE_RESPONSE,
|
|
21
21
|
};
|
|
22
22
|
/////////////////////
|
|
23
23
|
// Construct
|
|
@@ -79,7 +79,7 @@ export class Cognito extends Construct {
|
|
|
79
79
|
return this.attachPermissionsForUsers(this.cdk.unauthRole, arg1, arg2);
|
|
80
80
|
}
|
|
81
81
|
bindForTriggers(constructs) {
|
|
82
|
-
Object.values(this.functions).forEach(fn => fn.bind(constructs));
|
|
82
|
+
Object.values(this.functions).forEach((fn) => fn.bind(constructs));
|
|
83
83
|
}
|
|
84
84
|
bindForTrigger(triggerKey, constructs) {
|
|
85
85
|
const fn = this.getFunction(triggerKey);
|
|
@@ -89,7 +89,7 @@ export class Cognito extends Construct {
|
|
|
89
89
|
fn.bind(constructs);
|
|
90
90
|
}
|
|
91
91
|
attachPermissionsForTriggers(permissions) {
|
|
92
|
-
Object.values(this.functions).forEach(fn => fn.attachPermissions(permissions));
|
|
92
|
+
Object.values(this.functions).forEach((fn) => fn.attachPermissions(permissions));
|
|
93
93
|
}
|
|
94
94
|
attachPermissionsForTrigger(triggerKey, permissions) {
|
|
95
95
|
const fn = this.getFunction(triggerKey);
|
|
@@ -109,9 +109,9 @@ export class Cognito extends Construct {
|
|
|
109
109
|
userPoolId: this.cdk.userPool.userPoolId,
|
|
110
110
|
triggers: Object.entries(this.functions).map(([name, fun]) => ({
|
|
111
111
|
name,
|
|
112
|
-
fn: getFunctionRef(fun)
|
|
113
|
-
}))
|
|
114
|
-
}
|
|
112
|
+
fn: getFunctionRef(fun),
|
|
113
|
+
})),
|
|
114
|
+
},
|
|
115
115
|
};
|
|
116
116
|
}
|
|
117
117
|
/** @internal */
|
|
@@ -169,7 +169,7 @@ export class Cognito extends Construct {
|
|
|
169
169
|
selfSignUpEnabled: true,
|
|
170
170
|
signInCaseSensitive: false,
|
|
171
171
|
signInAliases: this.buildSignInAliases(login),
|
|
172
|
-
...cognitoUserPoolProps
|
|
172
|
+
...cognitoUserPoolProps,
|
|
173
173
|
});
|
|
174
174
|
}
|
|
175
175
|
}
|
|
@@ -183,7 +183,7 @@ export class Cognito extends Construct {
|
|
|
183
183
|
{});
|
|
184
184
|
this.cdk.userPoolClient = new cognito.UserPoolClient(this, "UserPoolClient", {
|
|
185
185
|
userPool: this.cdk.userPool,
|
|
186
|
-
...clientProps
|
|
186
|
+
...clientProps,
|
|
187
187
|
});
|
|
188
188
|
}
|
|
189
189
|
}
|
|
@@ -203,7 +203,7 @@ export class Cognito extends Construct {
|
|
|
203
203
|
const urlSuffix = Stack.of(this).urlSuffix;
|
|
204
204
|
cognitoIdentityProviders.push({
|
|
205
205
|
providerName: `cognito-idp.${app.region}.${urlSuffix}/${this.cdk.userPool.userPoolId}`,
|
|
206
|
-
clientId: this.cdk.userPoolClient.userPoolClientId
|
|
206
|
+
clientId: this.cdk.userPoolClient.userPoolClientId,
|
|
207
207
|
});
|
|
208
208
|
if (typeof identityPoolFederation === "object") {
|
|
209
209
|
const { auth0, amazon, apple, facebook, google, twitter } = identityPoolFederation;
|
|
@@ -221,7 +221,7 @@ export class Cognito extends Construct {
|
|
|
221
221
|
url: auth0.domain.startsWith("https://")
|
|
222
222
|
? auth0.domain
|
|
223
223
|
: `https://${auth0.domain}`,
|
|
224
|
-
clientIds: [auth0.clientId]
|
|
224
|
+
clientIds: [auth0.clientId],
|
|
225
225
|
});
|
|
226
226
|
openIdConnectProviderArns.push(provider.openIdConnectProviderArn);
|
|
227
227
|
}
|
|
@@ -272,7 +272,7 @@ export class Cognito extends Construct {
|
|
|
272
272
|
cognitoIdentityProviders,
|
|
273
273
|
supportedLoginProviders,
|
|
274
274
|
openIdConnectProviderArns,
|
|
275
|
-
...identityPoolProps
|
|
275
|
+
...identityPoolProps,
|
|
276
276
|
});
|
|
277
277
|
this.cdk.authRole = this.createAuthRole(this.cdk.cfnIdentityPool);
|
|
278
278
|
this.cdk.unauthRole = this.createUnauthRole(this.cdk.cfnIdentityPool);
|
|
@@ -281,8 +281,8 @@ export class Cognito extends Construct {
|
|
|
281
281
|
identityPoolId: this.cdk.cfnIdentityPool.ref,
|
|
282
282
|
roles: {
|
|
283
283
|
authenticated: this.cdk.authRole.roleArn,
|
|
284
|
-
unauthenticated: this.cdk.unauthRole.roleArn
|
|
285
|
-
}
|
|
284
|
+
unauthenticated: this.cdk.unauthRole.roleArn,
|
|
285
|
+
},
|
|
286
286
|
});
|
|
287
287
|
}
|
|
288
288
|
addTriggers() {
|
|
@@ -315,21 +315,21 @@ export class Cognito extends Construct {
|
|
|
315
315
|
const role = new iam.Role(this, "IdentityPoolAuthRole", {
|
|
316
316
|
assumedBy: new iam.FederatedPrincipal("cognito-identity.amazonaws.com", {
|
|
317
317
|
StringEquals: {
|
|
318
|
-
"cognito-identity.amazonaws.com:aud": identityPool.ref
|
|
318
|
+
"cognito-identity.amazonaws.com:aud": identityPool.ref,
|
|
319
319
|
},
|
|
320
320
|
"ForAnyValue:StringLike": {
|
|
321
|
-
"cognito-identity.amazonaws.com:amr": "authenticated"
|
|
322
|
-
}
|
|
323
|
-
}, "sts:AssumeRoleWithWebIdentity")
|
|
321
|
+
"cognito-identity.amazonaws.com:amr": "authenticated",
|
|
322
|
+
},
|
|
323
|
+
}, "sts:AssumeRoleWithWebIdentity"),
|
|
324
324
|
});
|
|
325
325
|
role.addToPolicy(new iam.PolicyStatement({
|
|
326
326
|
effect: iam.Effect.ALLOW,
|
|
327
327
|
actions: [
|
|
328
328
|
"mobileanalytics:PutEvents",
|
|
329
329
|
"cognito-sync:*",
|
|
330
|
-
"cognito-identity:*"
|
|
330
|
+
"cognito-identity:*",
|
|
331
331
|
],
|
|
332
|
-
resources: ["*"]
|
|
332
|
+
resources: ["*"],
|
|
333
333
|
}));
|
|
334
334
|
return role;
|
|
335
335
|
}
|
|
@@ -337,17 +337,17 @@ export class Cognito extends Construct {
|
|
|
337
337
|
const role = new iam.Role(this, "IdentityPoolUnauthRole", {
|
|
338
338
|
assumedBy: new iam.FederatedPrincipal("cognito-identity.amazonaws.com", {
|
|
339
339
|
StringEquals: {
|
|
340
|
-
"cognito-identity.amazonaws.com:aud": identityPool.ref
|
|
340
|
+
"cognito-identity.amazonaws.com:aud": identityPool.ref,
|
|
341
341
|
},
|
|
342
342
|
"ForAnyValue:StringLike": {
|
|
343
|
-
"cognito-identity.amazonaws.com:amr": "unauthenticated"
|
|
344
|
-
}
|
|
345
|
-
}, "sts:AssumeRoleWithWebIdentity")
|
|
343
|
+
"cognito-identity.amazonaws.com:amr": "unauthenticated",
|
|
344
|
+
},
|
|
345
|
+
}, "sts:AssumeRoleWithWebIdentity"),
|
|
346
346
|
});
|
|
347
347
|
role.addToPolicy(new iam.PolicyStatement({
|
|
348
348
|
effect: iam.Effect.ALLOW,
|
|
349
349
|
actions: ["mobileanalytics:PutEvents", "cognito-sync:*"],
|
|
350
|
-
resources: ["*"]
|
|
350
|
+
resources: ["*"],
|
|
351
351
|
}));
|
|
352
352
|
return role;
|
|
353
353
|
}
|
|
@@ -359,7 +359,7 @@ export class Cognito extends Construct {
|
|
|
359
359
|
email: login.includes("email"),
|
|
360
360
|
phone: login.includes("phone"),
|
|
361
361
|
username: login.includes("username"),
|
|
362
|
-
preferredUsername: login.includes("preferredUsername")
|
|
362
|
+
preferredUsername: login.includes("preferredUsername"),
|
|
363
363
|
};
|
|
364
364
|
}
|
|
365
365
|
}
|
|
@@ -7,7 +7,7 @@ import * as iam from "aws-cdk-lib/aws-iam";
|
|
|
7
7
|
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
8
8
|
import * as s3Assets from "aws-cdk-lib/aws-s3-assets";
|
|
9
9
|
import { AwsCliLayer } from "aws-cdk-lib/lambda-layer-awscli";
|
|
10
|
-
import { Lazy, Duration, CustomResource
|
|
10
|
+
import { Lazy, Duration, CustomResource } from "aws-cdk-lib";
|
|
11
11
|
import { Stack } from "./Stack.js";
|
|
12
12
|
import { attachPermissionsToRole } from "./util/permission.js";
|
|
13
13
|
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
|
|
@@ -171,7 +171,9 @@ ${exports}
|
|
|
171
171
|
provider.role?.addToPrincipalPolicy(new iam.PolicyStatement({
|
|
172
172
|
effect: iam.Effect.ALLOW,
|
|
173
173
|
actions: ["s3:*"],
|
|
174
|
-
resources: [
|
|
174
|
+
resources: [
|
|
175
|
+
`arn:${stack.partition}:s3:::${asset.s3BucketName}/${asset.s3ObjectKey}`,
|
|
176
|
+
],
|
|
175
177
|
}));
|
|
176
178
|
// Create custom resource to replace the code
|
|
177
179
|
const resource = new CustomResource(this.scope, resId, {
|
|
@@ -182,11 +184,13 @@ ${exports}
|
|
|
182
184
|
BucketName: asset.s3BucketName,
|
|
183
185
|
ObjectKey: asset.s3ObjectKey,
|
|
184
186
|
},
|
|
185
|
-
ReplaceValues: [
|
|
187
|
+
ReplaceValues: [
|
|
188
|
+
{
|
|
186
189
|
files: `index-wrapper.${format === "esm" ? "mjs" : "cjs"}`,
|
|
187
190
|
search: '"{{ _SST_EDGE_FUNCTION_ENVIRONMENT_ }}"',
|
|
188
191
|
replace: JSON.stringify(this.props.environment || {}),
|
|
189
|
-
}
|
|
192
|
+
},
|
|
193
|
+
],
|
|
190
194
|
},
|
|
191
195
|
});
|
|
192
196
|
return resource;
|
package/constructs/NextjsSite.js
CHANGED
|
@@ -2,7 +2,7 @@ import fs from "fs";
|
|
|
2
2
|
import url from "url";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import spawn from "cross-spawn";
|
|
5
|
-
import { Fn, Duration, RemovalPolicy
|
|
5
|
+
import { Fn, Duration, RemovalPolicy } from "aws-cdk-lib";
|
|
6
6
|
import * as logs from "aws-cdk-lib/aws-logs";
|
|
7
7
|
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
8
8
|
import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
|
|
@@ -84,7 +84,7 @@ export class NextjsSite extends SsrSite {
|
|
|
84
84
|
timeout: Duration.seconds(defaults?.function?.timeout || 10),
|
|
85
85
|
environment: {
|
|
86
86
|
BUCKET_NAME: this.cdk.bucket.bucketName,
|
|
87
|
-
}
|
|
87
|
+
},
|
|
88
88
|
});
|
|
89
89
|
}
|
|
90
90
|
createMiddlewareEdgeFunctionForRegional() {
|
|
@@ -129,10 +129,12 @@ export class NextjsSite extends SsrSite {
|
|
|
129
129
|
cachePolicy: cdk?.cachePolicies?.serverRequests ??
|
|
130
130
|
this.createCloudFrontServerCachePolicy(),
|
|
131
131
|
edgeLambdas: isMiddlewareEnabled
|
|
132
|
-
? [
|
|
132
|
+
? [
|
|
133
|
+
{
|
|
133
134
|
eventType: cloudfront.LambdaEdgeEventType.VIEWER_REQUEST,
|
|
134
135
|
functionVersion: middlewareFn.currentVersion,
|
|
135
|
-
}
|
|
136
|
+
},
|
|
137
|
+
]
|
|
136
138
|
: undefined,
|
|
137
139
|
};
|
|
138
140
|
// Create image optimization behavior
|
package/constructs/Queue.js
CHANGED
|
@@ -2,7 +2,7 @@ import { Construct } from "constructs";
|
|
|
2
2
|
import * as sqs from "aws-cdk-lib/aws-sqs";
|
|
3
3
|
import * as lambdaEventSources from "aws-cdk-lib/aws-lambda-event-sources";
|
|
4
4
|
import { getFunctionRef, isCDKConstruct } from "./Construct.js";
|
|
5
|
-
import { Function as Fn } from "./Function.js";
|
|
5
|
+
import { Function as Fn, } from "./Function.js";
|
|
6
6
|
import { toCdkDuration } from "./util/duration.js";
|
|
7
7
|
/////////////////////
|
|
8
8
|
// Construct
|
|
@@ -105,7 +105,7 @@ export class Queue extends Construct {
|
|
|
105
105
|
const fn = Fn.fromDefinition(scope, `Consumer_${this.node.id}`, functionDefinition);
|
|
106
106
|
fn.addEventSource(new lambdaEventSources.SqsEventSource(this.cdk.queue, eventSourceProps));
|
|
107
107
|
// Attach permissions
|
|
108
|
-
this.permissionsAttachedForAllConsumers.forEach(permissions => {
|
|
108
|
+
this.permissionsAttachedForAllConsumers.forEach((permissions) => {
|
|
109
109
|
fn.attachPermissions(permissions);
|
|
110
110
|
});
|
|
111
111
|
fn.bind(this.bindingForAllConsumers);
|
|
@@ -151,8 +151,8 @@ export class Queue extends Construct {
|
|
|
151
151
|
data: {
|
|
152
152
|
name: this.cdk.queue.queueName,
|
|
153
153
|
url: this.cdk.queue.queueUrl,
|
|
154
|
-
consumer: getFunctionRef(this.consumerFunction)
|
|
155
|
-
}
|
|
154
|
+
consumer: getFunctionRef(this.consumerFunction),
|
|
155
|
+
},
|
|
156
156
|
};
|
|
157
157
|
}
|
|
158
158
|
/** @internal */
|
|
@@ -162,12 +162,12 @@ export class Queue extends Construct {
|
|
|
162
162
|
variables: {
|
|
163
163
|
queueUrl: {
|
|
164
164
|
environment: this.queueUrl,
|
|
165
|
-
parameter: this.queueUrl
|
|
166
|
-
}
|
|
165
|
+
parameter: this.queueUrl,
|
|
166
|
+
},
|
|
167
167
|
},
|
|
168
168
|
permissions: {
|
|
169
|
-
"sqs:*": [this.queueArn]
|
|
170
|
-
}
|
|
169
|
+
"sqs:*": [this.queueArn],
|
|
170
|
+
},
|
|
171
171
|
};
|
|
172
172
|
}
|
|
173
173
|
createQueue() {
|
|
@@ -191,7 +191,7 @@ export class Queue extends Construct {
|
|
|
191
191
|
// TODO
|
|
192
192
|
console.log(toCdkDuration("900 seconds"));
|
|
193
193
|
debugOverrideProps = {
|
|
194
|
-
visibilityTimeout: toCdkDuration("900 seconds")
|
|
194
|
+
visibilityTimeout: toCdkDuration("900 seconds"),
|
|
195
195
|
};
|
|
196
196
|
}
|
|
197
197
|
}
|
|
@@ -199,7 +199,7 @@ export class Queue extends Construct {
|
|
|
199
199
|
this.cdk.queue = new sqs.Queue(this, "Queue", {
|
|
200
200
|
queueName: name,
|
|
201
201
|
...sqsQueueProps,
|
|
202
|
-
...debugOverrideProps
|
|
202
|
+
...debugOverrideProps,
|
|
203
203
|
});
|
|
204
204
|
}
|
|
205
205
|
}
|
package/constructs/Secret.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Construct } from "constructs";
|
|
2
2
|
import { Stack } from "./Stack.js";
|
|
3
|
-
import { ENVIRONMENT_PLACEHOLDER, getParameterPath, getParameterFallbackPath } from "./util/functionBinding.js";
|
|
3
|
+
import { ENVIRONMENT_PLACEHOLDER, getParameterPath, getParameterFallbackPath, } from "./util/functionBinding.js";
|
|
4
4
|
/**
|
|
5
5
|
* The `Secret` construct is a higher level CDK construct that makes it easy to manage app secrets.
|
|
6
6
|
*
|
|
@@ -46,7 +46,7 @@ export class Secret extends Construct {
|
|
|
46
46
|
permissions: {
|
|
47
47
|
"ssm:GetParameters": [
|
|
48
48
|
`arn:${partition}:ssm:${app.region}:${app.account}:parameter${getParameterPath(this, "value")}`,
|
|
49
|
-
`arn:${partition}:ssm:${app.region}:${app.account}:parameter${getParameterFallbackPath(this, "value")}
|
|
49
|
+
`arn:${partition}:ssm:${app.region}:${app.account}:parameter${getParameterFallbackPath(this, "value")}`,
|
|
50
50
|
],
|
|
51
51
|
},
|
|
52
52
|
};
|
|
@@ -54,7 +54,9 @@ export class SolidStartSite extends SsrSite {
|
|
|
54
54
|
const outputPath = path.resolve(path.join(useProject().paths.artifacts, `SolidStartSiteFunction-${this.node.id}-${this.node.addr}`));
|
|
55
55
|
// Bundle code
|
|
56
56
|
const result = esbuild.buildSync({
|
|
57
|
-
entryPoints: [
|
|
57
|
+
entryPoints: [
|
|
58
|
+
path.join(this.props.path, this.buildConfig.serverBuildOutputFile),
|
|
59
|
+
],
|
|
58
60
|
target: "esnext",
|
|
59
61
|
format: "esm",
|
|
60
62
|
platform: "node",
|
package/constructs/SsrSite.js
CHANGED
|
@@ -143,7 +143,6 @@ export class SsrSite extends Construct {
|
|
|
143
143
|
if (this.doNotDeploy) {
|
|
144
144
|
throw new VisibleError(`Cannot access CDK resources for the "${this.node.id}" site in dev mode`);
|
|
145
145
|
}
|
|
146
|
-
;
|
|
147
146
|
return {
|
|
148
147
|
function: this.serverLambdaForRegional,
|
|
149
148
|
bucket: this.bucket,
|
package/constructs/Table.js
CHANGED
|
@@ -269,7 +269,7 @@ export class Table extends Construct {
|
|
|
269
269
|
return {
|
|
270
270
|
clientPackage: "table",
|
|
271
271
|
variables: {
|
|
272
|
-
|
|
272
|
+
tableName: {
|
|
273
273
|
environment: this.tableName,
|
|
274
274
|
parameter: this.tableName,
|
|
275
275
|
},
|
|
@@ -368,11 +368,11 @@ export class Table extends Construct {
|
|
|
368
368
|
fn.addEventSource(eventSource);
|
|
369
369
|
// set filter pattern
|
|
370
370
|
if (filters && filters.length > 0) {
|
|
371
|
-
const cfnEventSource = fn.node.children.find(c => c instanceof lambda.EventSourceMapping)?.node.defaultChild;
|
|
371
|
+
const cfnEventSource = fn.node.children.find((c) => c instanceof lambda.EventSourceMapping)?.node.defaultChild;
|
|
372
372
|
cfnEventSource.addPropertyOverride("FilterCriteria", {
|
|
373
|
-
Filters: filters.map(filter => ({
|
|
373
|
+
Filters: filters.map((filter) => ({
|
|
374
374
|
Pattern: JSON.stringify(filter),
|
|
375
|
-
}))
|
|
375
|
+
})),
|
|
376
376
|
});
|
|
377
377
|
}
|
|
378
378
|
// attach permissions
|
package/constructs/Topic.js
CHANGED
|
@@ -473,7 +473,9 @@ export class NextjsSite extends Construct {
|
|
|
473
473
|
provider.role?.addToPrincipalPolicy(new iam.PolicyStatement({
|
|
474
474
|
effect: iam.Effect.ALLOW,
|
|
475
475
|
actions: ["s3:*"],
|
|
476
|
-
resources: [
|
|
476
|
+
resources: [
|
|
477
|
+
`arn:${Stack.of(this).partition}:s3:::${asset.s3BucketName}/${asset.s3ObjectKey}`,
|
|
478
|
+
],
|
|
477
479
|
}));
|
|
478
480
|
// Create custom resource
|
|
479
481
|
const resource = new CustomResource(this, resId, {
|
|
@@ -17,7 +17,7 @@ const defaultHttpFields = [
|
|
|
17
17
|
// caller info
|
|
18
18
|
`"ip":"$context.identity.sourceIp"`,
|
|
19
19
|
`"userAgent":"$context.identity.userAgent"`,
|
|
20
|
-
`"cognitoIdentityId":"$context.identity.cognitoIdentityId"
|
|
20
|
+
`"cognitoIdentityId":"$context.identity.cognitoIdentityId"`,
|
|
21
21
|
];
|
|
22
22
|
const defaultWebSocketFields = [
|
|
23
23
|
// request info
|
|
@@ -36,7 +36,7 @@ const defaultWebSocketFields = [
|
|
|
36
36
|
`"userAgent":"$context.identity.userAgent"`,
|
|
37
37
|
`"cognitoIdentityId":"$context.identity.cognitoIdentityId"`,
|
|
38
38
|
`"connectedAt":"$context.connectedAt"`,
|
|
39
|
-
`"connectionId":"$context.connectionId"
|
|
39
|
+
`"connectionId":"$context.connectionId"`,
|
|
40
40
|
];
|
|
41
41
|
export function buildAccessLogData(scope, accessLog, apiStage, isDefaultStage) {
|
|
42
42
|
if (accessLog === false) {
|
|
@@ -60,9 +60,9 @@ export function buildAccessLogData(scope, accessLog, apiStage, isDefaultStage) {
|
|
|
60
60
|
logGroupName: [
|
|
61
61
|
`/aws/vendedlogs/apis`,
|
|
62
62
|
`/${cleanupLogGroupName(apiName)}-${apiStage.api.apiId}`,
|
|
63
|
-
`/${cleanupLogGroupName(apiStage.stageName)}
|
|
63
|
+
`/${cleanupLogGroupName(apiStage.stageName)}`,
|
|
64
64
|
].join(""),
|
|
65
|
-
retention: buildLogGroupRetention(accessLog)
|
|
65
|
+
retention: buildLogGroupRetention(accessLog),
|
|
66
66
|
});
|
|
67
67
|
destinationArn = logGroup.logGroupArn;
|
|
68
68
|
}
|
|
@@ -204,7 +204,5 @@ function parseRoute53Domain(domainName) {
|
|
|
204
204
|
// If the domain contains subdomain, ie. api.example.com,
|
|
205
205
|
// strip the subdomain and use the root domain, ie. example.com.
|
|
206
206
|
// Otherwise, use the domain as is.
|
|
207
|
-
return parts.length <= 2
|
|
208
|
-
? domainName
|
|
209
|
-
: parts.slice(1).join(".");
|
|
207
|
+
return parts.length <= 2 ? domainName : parts.slice(1).join(".");
|
|
210
208
|
}
|
|
@@ -26,16 +26,13 @@ function buildDataForStringInput(scope, customDomain) {
|
|
|
26
26
|
}
|
|
27
27
|
assertDomainNameIsLowerCase(customDomain);
|
|
28
28
|
const domainName = customDomain;
|
|
29
|
-
const hostedZoneDomain = domainName
|
|
30
|
-
.split(".")
|
|
31
|
-
.slice(1)
|
|
32
|
-
.join(".");
|
|
29
|
+
const hostedZoneDomain = domainName.split(".").slice(1).join(".");
|
|
33
30
|
const hostedZone = lookupHostedZone(scope, hostedZoneDomain);
|
|
34
31
|
const certificate = createCertificate(scope, domainName, hostedZone);
|
|
35
32
|
createRecord(scope, hostedZone, domainName);
|
|
36
33
|
return {
|
|
37
34
|
certificate,
|
|
38
|
-
domainName
|
|
35
|
+
domainName,
|
|
39
36
|
};
|
|
40
37
|
}
|
|
41
38
|
function buildDataForInternalDomainInput(scope, customDomain) {
|
|
@@ -63,10 +60,7 @@ function buildDataForInternalDomainInput(scope, customDomain) {
|
|
|
63
60
|
hostedZone = customDomain.cdk.hostedZone;
|
|
64
61
|
}
|
|
65
62
|
else {
|
|
66
|
-
const hostedZoneDomain = domainName
|
|
67
|
-
.split(".")
|
|
68
|
-
.slice(1)
|
|
69
|
-
.join(".");
|
|
63
|
+
const hostedZoneDomain = domainName.split(".").slice(1).join(".");
|
|
70
64
|
hostedZone = lookupHostedZone(scope, hostedZoneDomain);
|
|
71
65
|
}
|
|
72
66
|
// Create certificate
|
|
@@ -78,7 +72,7 @@ function buildDataForInternalDomainInput(scope, customDomain) {
|
|
|
78
72
|
createRecord(scope, hostedZone, domainName);
|
|
79
73
|
return {
|
|
80
74
|
certificate,
|
|
81
|
-
domainName
|
|
75
|
+
domainName,
|
|
82
76
|
};
|
|
83
77
|
}
|
|
84
78
|
function buildDataForExternalDomainInput(scope, customDomain) {
|
|
@@ -95,18 +89,18 @@ function buildDataForExternalDomainInput(scope, customDomain) {
|
|
|
95
89
|
const certificate = customDomain.cdk.certificate;
|
|
96
90
|
return {
|
|
97
91
|
certificate,
|
|
98
|
-
domainName
|
|
92
|
+
domainName,
|
|
99
93
|
};
|
|
100
94
|
}
|
|
101
95
|
function lookupHostedZone(scope, hostedZoneDomain) {
|
|
102
96
|
return route53.HostedZone.fromLookup(scope, "HostedZone", {
|
|
103
|
-
domainName: hostedZoneDomain
|
|
97
|
+
domainName: hostedZoneDomain,
|
|
104
98
|
});
|
|
105
99
|
}
|
|
106
100
|
function createCertificate(scope, domainName, hostedZone) {
|
|
107
101
|
return new acm.Certificate(scope, "Certificate", {
|
|
108
102
|
domainName,
|
|
109
|
-
validation: acm.CertificateValidation.fromDns(hostedZone)
|
|
103
|
+
validation: acm.CertificateValidation.fromDns(hostedZone),
|
|
110
104
|
});
|
|
111
105
|
}
|
|
112
106
|
function createRecord(scope, hostedZone, domainName) {
|
|
@@ -117,8 +111,8 @@ function createRecord(scope, hostedZone, domainName) {
|
|
|
117
111
|
domainName: Lazy.string({
|
|
118
112
|
produce() {
|
|
119
113
|
return scope._cfnDomainName.attrAppSyncDomainName;
|
|
120
|
-
}
|
|
121
|
-
})
|
|
114
|
+
},
|
|
115
|
+
}),
|
|
122
116
|
});
|
|
123
117
|
// note: If domainName is a TOKEN string ie. ${TOKEN..}, the route53.ARecord
|
|
124
118
|
// construct will append ".${hostedZoneName}" to the end of the domain.
|
|
@@ -18,8 +18,8 @@ import { RDS } from "../RDS.js";
|
|
|
18
18
|
import { Job } from "../Job.js";
|
|
19
19
|
export function attachPermissionsToRole(role, permissions) {
|
|
20
20
|
const { statements, grants } = permissionsToStatementsAndGrants(permissions);
|
|
21
|
-
statements.forEach(statement => role.addToPolicy(statement));
|
|
22
|
-
grants.forEach(grant => {
|
|
21
|
+
statements.forEach((statement) => role.addToPolicy(statement));
|
|
22
|
+
grants.forEach((grant) => {
|
|
23
23
|
const construct = grant[0];
|
|
24
24
|
const methodName = grant[1];
|
|
25
25
|
construct[methodName](role);
|
|
@@ -27,8 +27,8 @@ export function attachPermissionsToRole(role, permissions) {
|
|
|
27
27
|
}
|
|
28
28
|
export function attachPermissionsToPolicy(policy, permissions) {
|
|
29
29
|
const { statements, grants } = permissionsToStatementsAndGrants(permissions);
|
|
30
|
-
statements.forEach(statement => policy.addStatements(statement));
|
|
31
|
-
grants.forEach(grant => {
|
|
30
|
+
statements.forEach((statement) => policy.addStatements(statement));
|
|
31
|
+
grants.forEach((grant) => {
|
|
32
32
|
throw new Error(`Cannot attach the "${grant[1]}" permission to an IAM policy.`);
|
|
33
33
|
});
|
|
34
34
|
}
|
|
@@ -57,7 +57,7 @@ function permissionsToStatementsAndGrants(permissions) {
|
|
|
57
57
|
if (permissions === "*") {
|
|
58
58
|
return {
|
|
59
59
|
statements: [buildPolicyStatement(permissions, ["*"])],
|
|
60
|
-
grants: []
|
|
60
|
+
grants: [],
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
63
|
if (!Array.isArray(permissions)) {
|
|
@@ -87,31 +87,31 @@ function permissionsToStatementsAndGrants(permissions) {
|
|
|
87
87
|
const httpApi = permission.cdk.httpApi;
|
|
88
88
|
const { account, region, partition } = Stack.of(httpApi);
|
|
89
89
|
statements.push(buildPolicyStatement("execute-api:Invoke", [
|
|
90
|
-
`arn:${partition}:execute-api:${region}:${account}:${httpApi.httpApiId}
|
|
90
|
+
`arn:${partition}:execute-api:${region}:${account}:${httpApi.httpApiId}/*`,
|
|
91
91
|
]));
|
|
92
92
|
}
|
|
93
93
|
else if (permission instanceof ApiGatewayV1Api) {
|
|
94
94
|
const restApi = permission.cdk.restApi;
|
|
95
95
|
const { account, region, partition } = Stack.of(restApi);
|
|
96
96
|
statements.push(buildPolicyStatement("execute-api:Invoke", [
|
|
97
|
-
`arn:${partition}:execute-api:${region}:${account}:${restApi.restApiId}
|
|
97
|
+
`arn:${partition}:execute-api:${region}:${account}:${restApi.restApiId}/*`,
|
|
98
98
|
]));
|
|
99
99
|
}
|
|
100
100
|
else if (permission instanceof WebSocketApi) {
|
|
101
101
|
const webSocketApi = permission.cdk.webSocketApi;
|
|
102
102
|
const { account, region, partition } = Stack.of(webSocketApi);
|
|
103
103
|
statements.push(buildPolicyStatement("execute-api:Invoke", [
|
|
104
|
-
`arn:${partition}:execute-api:${region}:${account}:${webSocketApi.apiId}
|
|
104
|
+
`arn:${partition}:execute-api:${region}:${account}:${webSocketApi.apiId}/*`,
|
|
105
105
|
]));
|
|
106
106
|
statements.push(buildPolicyStatement("execute-api:ManageConnections", [
|
|
107
|
-
permission._connectionsArn
|
|
107
|
+
permission._connectionsArn,
|
|
108
108
|
]));
|
|
109
109
|
}
|
|
110
110
|
else if (permission instanceof AppSyncApi) {
|
|
111
111
|
const graphqlApi = permission.cdk.graphqlApi;
|
|
112
112
|
const { account, region, partition } = Stack.of(graphqlApi);
|
|
113
113
|
statements.push(buildPolicyStatement("appsync:GraphQL", [
|
|
114
|
-
`arn:${partition}:appsync:${region}:${account}:apis/${graphqlApi.apiId}
|
|
114
|
+
`arn:${partition}:appsync:${region}:${account}:apis/${graphqlApi.apiId}/*`,
|
|
115
115
|
]));
|
|
116
116
|
}
|
|
117
117
|
else if (permission instanceof Table) {
|
|
@@ -177,7 +177,7 @@ function permissionsToStatementsAndGrants(permissions) {
|
|
|
177
177
|
else if (permission.deliveryStreamArn &&
|
|
178
178
|
permission.deliveryStreamName) {
|
|
179
179
|
statements.push(buildPolicyStatement("firehose:*", [
|
|
180
|
-
permission.deliveryStreamArn
|
|
180
|
+
permission.deliveryStreamArn,
|
|
181
181
|
]));
|
|
182
182
|
}
|
|
183
183
|
else if (permission.bucketArn &&
|
|
@@ -222,6 +222,6 @@ function buildPolicyStatement(actions, resources) {
|
|
|
222
222
|
return new iam.PolicyStatement({
|
|
223
223
|
effect: iam.Effect.ALLOW,
|
|
224
224
|
actions: typeof actions === "string" ? [actions] : actions,
|
|
225
|
-
resources
|
|
225
|
+
resources,
|
|
226
226
|
});
|
|
227
227
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createAppContext } from "../context.js";
|
|
2
2
|
const WARNINGS = {
|
|
3
3
|
"config.deprecated": `WARNING: The "config" prop is deprecated, and will be removed in SST v2. Pass Parameters and Secrets in through the "bind" prop. Read more about how to upgrade here — https://docs.serverless-stack.com/upgrade-guide#upgrade-to-v116`,
|
|
4
|
-
"permissions.noConstructs": `WARNING: Passing SST constructs into "permissions" is deprecated, and will be removed in SST v2. Pass them into the "bind" prop. Read more about how to upgrade here — https://docs.serverless-stack.com/upgrade-guide#upgrade-to-v116
|
|
4
|
+
"permissions.noConstructs": `WARNING: Passing SST constructs into "permissions" is deprecated, and will be removed in SST v2. Pass them into the "bind" prop. Read more about how to upgrade here — https://docs.serverless-stack.com/upgrade-guide#upgrade-to-v116`,
|
|
5
5
|
};
|
|
6
6
|
export const useWarning = createAppContext(() => {
|
|
7
7
|
const set = new Set();
|
|
@@ -13,6 +13,6 @@ export const useWarning = createAppContext(() => {
|
|
|
13
13
|
for (const key of set) {
|
|
14
14
|
console.warn(WARNINGS[key]);
|
|
15
15
|
}
|
|
16
|
-
}
|
|
16
|
+
},
|
|
17
17
|
};
|
|
18
18
|
});
|
|
@@ -7,12 +7,12 @@ export const GoogleAdapter = /* @__PURE__ */ createAdapter((config) => {
|
|
|
7
7
|
if ("clientSecret" in config) {
|
|
8
8
|
return OauthAdapter({
|
|
9
9
|
issuer,
|
|
10
|
-
...config
|
|
10
|
+
...config,
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
13
|
return OidcAdapter({
|
|
14
14
|
issuer,
|
|
15
15
|
scope: "openid email profile",
|
|
16
|
-
...config
|
|
16
|
+
...config,
|
|
17
17
|
});
|
|
18
18
|
});
|
package/node/config/index.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import { GetParametersCommand, SSMClient } from "@aws-sdk/client-ssm";
|
|
1
|
+
import { GetParametersCommand, SSMClient, } from "@aws-sdk/client-ssm";
|
|
2
2
|
const ssm = new SSMClient({});
|
|
3
|
-
import { createProxy, parseEnvironment, buildSsmPath, buildSsmFallbackPath, ssmNameToConstructId, ssmFallbackNameToConstructId } from "../util/index.js";
|
|
4
|
-
;
|
|
5
|
-
;
|
|
6
|
-
;
|
|
3
|
+
import { createProxy, parseEnvironment, buildSsmPath, buildSsmFallbackPath, ssmNameToConstructId, ssmFallbackNameToConstructId, } from "../util/index.js";
|
|
7
4
|
export const Config = createProxy("Config");
|
|
8
5
|
const metadata = parseMetadataEnvironment();
|
|
9
6
|
const parametersRaw = parseEnvironment("Parameter", ["value"]);
|
|
@@ -39,9 +36,7 @@ function flattenConfigValues(configValues) {
|
|
|
39
36
|
}
|
|
40
37
|
async function replaceSecretsWithRealValues() {
|
|
41
38
|
// Find all the secrets and params that match the prefix
|
|
42
|
-
const names = Object
|
|
43
|
-
.keys(secrets)
|
|
44
|
-
.filter((name) => secrets[name] === "__FETCH_FROM_SSM__");
|
|
39
|
+
const names = Object.keys(secrets).filter((name) => secrets[name] === "__FETCH_FROM_SSM__");
|
|
45
40
|
if (names.length === 0) {
|
|
46
41
|
return;
|
|
47
42
|
}
|
package/node/site/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { GetParametersCommand, SSMClient } from "@aws-sdk/client-ssm";
|
|
1
|
+
import { GetParametersCommand, SSMClient, } from "@aws-sdk/client-ssm";
|
|
2
2
|
const ssm = new SSMClient({});
|
|
3
|
-
import { createProxy, parseEnvironment, buildSsmPath, ssmNameToConstructId } from "../util/index.js";
|
|
3
|
+
import { createProxy, parseEnvironment, buildSsmPath, ssmNameToConstructId, } from "../util/index.js";
|
|
4
4
|
export const StaticSite = createProxy("StaticSite");
|
|
5
5
|
export const ReactStaticSite = createProxy("ReactStaticSite");
|
|
6
6
|
export const ViteStaticSite = createProxy("ViteStaticSite");
|
|
@@ -23,9 +23,7 @@ Object.assign(NextjsSite, nextjsSiteData);
|
|
|
23
23
|
Object.assign(RemixSite, remixSiteData);
|
|
24
24
|
async function replaceWithSsmValues(className, siteData) {
|
|
25
25
|
// Find all the site data that match the prefix
|
|
26
|
-
const names = Object
|
|
27
|
-
.keys(siteData)
|
|
28
|
-
.filter((name) => siteData[name].url === "__FETCH_FROM_SSM__");
|
|
26
|
+
const names = Object.keys(siteData).filter((name) => siteData[name].url === "__FETCH_FROM_SSM__");
|
|
29
27
|
if (names.length === 0) {
|
|
30
28
|
return;
|
|
31
29
|
}
|
package/package.json
CHANGED
package/sst.mjs
CHANGED
|
@@ -1060,16 +1060,13 @@ var init_credentials = __esm({
|
|
|
1060
1060
|
});
|
|
1061
1061
|
return new Promise((resolve) => {
|
|
1062
1062
|
Logger.debug(`Require MFA token for serial ARN ${serialArn}`);
|
|
1063
|
-
const prompt = () => rl.question(
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
resolve(input.trim());
|
|
1068
|
-
rl.close();
|
|
1069
|
-
}
|
|
1070
|
-
prompt();
|
|
1063
|
+
const prompt = () => rl.question(`Enter MFA code for ${serialArn}: `, async (input) => {
|
|
1064
|
+
if (input.trim() !== "") {
|
|
1065
|
+
resolve(input.trim());
|
|
1066
|
+
rl.close();
|
|
1071
1067
|
}
|
|
1072
|
-
|
|
1068
|
+
prompt();
|
|
1069
|
+
});
|
|
1073
1070
|
prompt();
|
|
1074
1071
|
});
|
|
1075
1072
|
}
|
|
@@ -2417,7 +2414,11 @@ async function deployStack2(options) {
|
|
|
2417
2414
|
TemplateBody: bodyParameter.TemplateBody,
|
|
2418
2415
|
TemplateURL: bodyParameter.TemplateURL,
|
|
2419
2416
|
Parameters: stackParams.apiParameters,
|
|
2420
|
-
Capabilities: [
|
|
2417
|
+
Capabilities: [
|
|
2418
|
+
"CAPABILITY_IAM",
|
|
2419
|
+
"CAPABILITY_NAMED_IAM",
|
|
2420
|
+
"CAPABILITY_AUTO_EXPAND"
|
|
2421
|
+
],
|
|
2421
2422
|
Tags: options.tags
|
|
2422
2423
|
}
|
|
2423
2424
|
};
|
|
@@ -6148,7 +6149,9 @@ var env = (program2) => program2.command(
|
|
|
6148
6149
|
while (true) {
|
|
6149
6150
|
const exists = await fs18.access(SiteEnv.valuesFile()).then(() => true).catch(() => false);
|
|
6150
6151
|
if (!exists) {
|
|
6151
|
-
spinner = createSpinner2(
|
|
6152
|
+
spinner = createSpinner2(
|
|
6153
|
+
"Cannot find SST environment variables. Waiting for SST to start..."
|
|
6154
|
+
).start();
|
|
6152
6155
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
6153
6156
|
continue;
|
|
6154
6157
|
}
|
|
@@ -6186,11 +6189,7 @@ var dev = (program2) => program2.command(
|
|
|
6186
6189
|
const { useRuntimeServer: useRuntimeServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
6187
6190
|
const { useBus: useBus2 } = await Promise.resolve().then(() => (init_bus(), bus_exports));
|
|
6188
6191
|
const { useWatcher: useWatcher2 } = await Promise.resolve().then(() => (init_watcher(), watcher_exports));
|
|
6189
|
-
const {
|
|
6190
|
-
useAppMetadata: useAppMetadata2,
|
|
6191
|
-
saveAppMetadata: saveAppMetadata2,
|
|
6192
|
-
Stacks
|
|
6193
|
-
} = await Promise.resolve().then(() => (init_stacks(), stacks_exports));
|
|
6192
|
+
const { useAppMetadata: useAppMetadata2, saveAppMetadata: saveAppMetadata2, Stacks } = await Promise.resolve().then(() => (init_stacks(), stacks_exports));
|
|
6194
6193
|
const { Logger: Logger2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
|
|
6195
6194
|
const { createSpinner: createSpinner2 } = await Promise.resolve().then(() => (init_spinner(), spinner_exports));
|
|
6196
6195
|
const { bold: bold2, dim: dim2, yellow } = await import("colorette");
|
|
@@ -6560,12 +6559,7 @@ var deploy2 = (program2) => program2.command(
|
|
|
6560
6559
|
const { createSpinner: createSpinner2 } = await Promise.resolve().then(() => (init_spinner(), spinner_exports));
|
|
6561
6560
|
const { dim: dim2, blue: blue4, bold: bold2 } = await import("colorette");
|
|
6562
6561
|
const { useProject: useProject2 } = await Promise.resolve().then(() => (init_project(), project_exports));
|
|
6563
|
-
const {
|
|
6564
|
-
loadAssembly: loadAssembly2,
|
|
6565
|
-
useAppMetadata: useAppMetadata2,
|
|
6566
|
-
saveAppMetadata: saveAppMetadata2,
|
|
6567
|
-
Stacks
|
|
6568
|
-
} = await Promise.resolve().then(() => (init_stacks(), stacks_exports));
|
|
6562
|
+
const { loadAssembly: loadAssembly2, useAppMetadata: useAppMetadata2, saveAppMetadata: saveAppMetadata2, Stacks } = await Promise.resolve().then(() => (init_stacks(), stacks_exports));
|
|
6569
6563
|
const { render } = await import("ink");
|
|
6570
6564
|
const { DeploymentUI: DeploymentUI2 } = await Promise.resolve().then(() => (init_deploy2(), deploy_exports));
|
|
6571
6565
|
const { mapValues: mapValues2 } = await import("remeda");
|
|
@@ -6659,11 +6653,7 @@ var remove2 = (program2) => program2.command(
|
|
|
6659
6653
|
const React2 = await import("react");
|
|
6660
6654
|
const { dim: dim2, blue: blue4, bold: bold2 } = await import("colorette");
|
|
6661
6655
|
const { useProject: useProject2 } = await Promise.resolve().then(() => (init_project(), project_exports));
|
|
6662
|
-
const {
|
|
6663
|
-
loadAssembly: loadAssembly2,
|
|
6664
|
-
clearAppMetadata: clearAppMetadata2,
|
|
6665
|
-
Stacks
|
|
6666
|
-
} = await Promise.resolve().then(() => (init_stacks(), stacks_exports));
|
|
6656
|
+
const { loadAssembly: loadAssembly2, clearAppMetadata: clearAppMetadata2, Stacks } = await Promise.resolve().then(() => (init_stacks(), stacks_exports));
|
|
6667
6657
|
const { render } = await import("ink");
|
|
6668
6658
|
const { DeploymentUI: DeploymentUI2 } = await Promise.resolve().then(() => (init_deploy2(), deploy_exports));
|
|
6669
6659
|
const { printDeploymentResults: printDeploymentResults2 } = await Promise.resolve().then(() => (init_deploy2(), deploy_exports));
|
package/stacks/app-metadata.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useBootstrap } from "../bootstrap.js";
|
|
2
|
-
import { useAWSCredentials
|
|
2
|
+
import { useAWSCredentials } from "../credentials.js";
|
|
3
3
|
import { S3Client, GetObjectCommand, PutObjectCommand, DeleteObjectCommand, } from "@aws-sdk/client-s3";
|
|
4
4
|
import { json } from "stream/consumers";
|
|
5
5
|
import { Context } from "../context/context.js";
|
package/stacks/synth.js
CHANGED
|
@@ -72,8 +72,8 @@ export async function synth(opts) {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
function formatErrorMessage(message) {
|
|
75
|
-
return formatCustomDomainError(message)
|
|
76
|
-
|
|
75
|
+
return (formatCustomDomainError(message) ||
|
|
76
|
+
`Could not resolve context values for ${message}`);
|
|
77
77
|
}
|
|
78
78
|
function formatCustomDomainError(message) {
|
|
79
79
|
const ret = message.match(/hosted-zone:account=\d+:domainName=(\S+):/);
|
|
@@ -68617,7 +68617,10 @@ async function handler(event) {
|
|
|
68617
68617
|
}
|
|
68618
68618
|
__name(handler, "handler");
|
|
68619
68619
|
async function processRecord(record) {
|
|
68620
|
-
console.log("EventBridge event details:", {
|
|
68620
|
+
console.log("EventBridge event details:", {
|
|
68621
|
+
source: record.source,
|
|
68622
|
+
detailType: record["detail-type"]
|
|
68623
|
+
});
|
|
68621
68624
|
if (record.source !== "aws.cloudformation" || record["detail-type"] !== "CloudFormation Stack Status Change") {
|
|
68622
68625
|
return;
|
|
68623
68626
|
}
|
|
@@ -68644,32 +68647,38 @@ async function processRecord(record) {
|
|
|
68644
68647
|
}
|
|
68645
68648
|
__name(processRecord, "processRecord");
|
|
68646
68649
|
async function sendIotEvent(app, stage, type) {
|
|
68647
|
-
await callAWS(
|
|
68648
|
-
|
|
68649
|
-
|
|
68650
|
-
|
|
68651
|
-
|
|
68652
|
-
|
|
68650
|
+
await callAWS(
|
|
68651
|
+
() => iot.send(
|
|
68652
|
+
new import_client_iot_data_plane.PublishCommand({
|
|
68653
|
+
topic: `/sst/${app}/${stage}/events`,
|
|
68654
|
+
payload: Buffer.from(JSON.stringify({ type }))
|
|
68655
|
+
})
|
|
68656
|
+
)
|
|
68657
|
+
);
|
|
68653
68658
|
}
|
|
68654
68659
|
__name(sendIotEvent, "sendIotEvent");
|
|
68655
68660
|
async function saveMetadata(stack, bucket, app, stage, metadata) {
|
|
68656
|
-
await callAWS(
|
|
68657
|
-
|
|
68658
|
-
|
|
68659
|
-
|
|
68660
|
-
|
|
68661
|
-
|
|
68662
|
-
|
|
68661
|
+
await callAWS(
|
|
68662
|
+
() => s3.send(
|
|
68663
|
+
new import_client_s3.PutObjectCommand({
|
|
68664
|
+
Bucket: bucket,
|
|
68665
|
+
Key: `stackMetadata/app.${app}/stage.${stage}/stack.${stack}.json`,
|
|
68666
|
+
Body: JSON.stringify(metadata)
|
|
68667
|
+
})
|
|
68668
|
+
)
|
|
68669
|
+
);
|
|
68663
68670
|
}
|
|
68664
68671
|
__name(saveMetadata, "saveMetadata");
|
|
68665
68672
|
async function deleteMetadata(stackName, bucket, app, stage) {
|
|
68666
68673
|
try {
|
|
68667
|
-
await callAWS(
|
|
68668
|
-
|
|
68669
|
-
|
|
68670
|
-
|
|
68671
|
-
|
|
68672
|
-
|
|
68674
|
+
await callAWS(
|
|
68675
|
+
() => s3.send(
|
|
68676
|
+
new import_client_s3.DeleteObjectCommand({
|
|
68677
|
+
Bucket: bucket,
|
|
68678
|
+
Key: `stackMetadata/app.${app}/stage.${stage}/stack.${stackName}.json`
|
|
68679
|
+
})
|
|
68680
|
+
)
|
|
68681
|
+
);
|
|
68673
68682
|
} catch (e) {
|
|
68674
68683
|
if (e.code === "NoSuchBucket") {
|
|
68675
68684
|
console.log(e);
|
|
@@ -68680,11 +68689,13 @@ async function deleteMetadata(stackName, bucket, app, stage) {
|
|
|
68680
68689
|
}
|
|
68681
68690
|
__name(deleteMetadata, "deleteMetadata");
|
|
68682
68691
|
async function getMetadata(stackName) {
|
|
68683
|
-
const ret = await callAWS(
|
|
68684
|
-
|
|
68685
|
-
|
|
68686
|
-
|
|
68687
|
-
|
|
68692
|
+
const ret = await callAWS(
|
|
68693
|
+
() => cf.send(
|
|
68694
|
+
new import_client_cloudformation.DescribeStacksCommand({
|
|
68695
|
+
StackName: stackName
|
|
68696
|
+
})
|
|
68697
|
+
)
|
|
68698
|
+
);
|
|
68688
68699
|
const metadataOutput = ret.Stacks?.at(0)?.Outputs?.find(
|
|
68689
68700
|
(o) => o.OutputKey === "SSTMetadata"
|
|
68690
68701
|
)?.OutputValue;
|
|
@@ -47171,10 +47171,7 @@ async function AuthKeys(cfnRequest) {
|
|
|
47171
47171
|
]);
|
|
47172
47172
|
break;
|
|
47173
47173
|
case "Update":
|
|
47174
|
-
const {
|
|
47175
|
-
privatePath: oldPrivatePath,
|
|
47176
|
-
publicPath: oldPublicPath
|
|
47177
|
-
} = cfnRequest.OldResourceProperties;
|
|
47174
|
+
const { privatePath: oldPrivatePath, publicPath: oldPublicPath } = cfnRequest.OldResourceProperties;
|
|
47178
47175
|
if (oldPrivatePath !== privatePath) {
|
|
47179
47176
|
try {
|
|
47180
47177
|
const oldPrivateKey = await client.send(
|