sst 2.0.0-rc.53 → 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.
Files changed (52) hide show
  1. package/bootstrap.d.ts +10 -0
  2. package/bootstrap.js +1 -1
  3. package/cdk/cloudformation-deployments-wrapper.js +8 -3
  4. package/cdk/deploy-stack.js +5 -0
  5. package/cli/commands/deploy.js +27 -2
  6. package/cli/commands/dev.js +38 -11
  7. package/cli/commands/remove.js +2 -1
  8. package/cli/local/server.js +1 -1
  9. package/cli/sst.js +4 -0
  10. package/cli/ui/deploy.js +4 -3
  11. package/constructs/Api.d.ts +1 -1
  12. package/constructs/Api.js +3 -6
  13. package/constructs/ApiGatewayV1Api.js +2 -2
  14. package/constructs/App.js +1 -1
  15. package/constructs/Auth.js +16 -16
  16. package/constructs/Cognito.js +28 -28
  17. package/constructs/EdgeFunction.js +8 -4
  18. package/constructs/NextjsSite.js +6 -4
  19. package/constructs/Queue.js +10 -10
  20. package/constructs/Secret.js +2 -2
  21. package/constructs/SolidStartSite.js +3 -1
  22. package/constructs/SsrSite.js +0 -1
  23. package/constructs/StaticSite.d.ts +50 -30
  24. package/constructs/StaticSite.js +105 -80
  25. package/constructs/Table.js +4 -4
  26. package/constructs/Topic.js +1 -1
  27. package/constructs/deprecated/NextjsSite.js +3 -1
  28. package/constructs/util/apiGatewayV2AccessLog.js +4 -4
  29. package/constructs/util/apiGatewayV2Domain.js +1 -3
  30. package/constructs/util/appSyncApiDomain.js +9 -15
  31. package/constructs/util/permission.js +12 -12
  32. package/constructs/util/warning.js +2 -2
  33. package/context/context.d.ts +2 -2
  34. package/context/context.js +4 -4
  35. package/node/auth/adapter/facebook.js +1 -1
  36. package/node/auth/adapter/google.js +2 -2
  37. package/node/auth/adapter/twitch.js +1 -1
  38. package/node/config/index.js +3 -8
  39. package/node/site/index.js +3 -5
  40. package/package.json +1 -1
  41. package/project.js +2 -2
  42. package/sst.mjs +230 -69
  43. package/stacks/app-metadata.d.ts +7 -0
  44. package/stacks/app-metadata.js +78 -0
  45. package/stacks/index.d.ts +1 -0
  46. package/stacks/index.js +1 -0
  47. package/stacks/synth.js +2 -2
  48. package/support/bootstrap-metadata-function/index.mjs +36 -25
  49. package/support/custom-resources/index.mjs +1 -4
  50. package/support/dotnet6-bootstrap/release/dotnet-bootstrap.deps.json +1 -1
  51. package/support/dotnet6-bootstrap/release/dotnet-bootstrap.runtimeconfig.json +1 -1
  52. package/support/remix-site-function/edge-server.js +1 -1
package/bootstrap.d.ts CHANGED
@@ -1,3 +1,13 @@
1
+ export declare const BootstrapContext: {
2
+ use(): {
3
+ version: string;
4
+ bucket: string;
5
+ };
6
+ provide(value: {
7
+ version: string;
8
+ bucket: string;
9
+ }): void;
10
+ };
1
11
  export declare const useBootstrap: () => {
2
12
  version: string;
3
13
  bucket: string;
package/bootstrap.js CHANGED
@@ -23,7 +23,7 @@ const OUTPUT_VERSION = "Version";
23
23
  const OUTPUT_BUCKET = "BucketName";
24
24
  const LATEST_VERSION = "6";
25
25
  const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
26
- const BootstrapContext = Context.create();
26
+ export const BootstrapContext = Context.create("Bootstrap");
27
27
  export const useBootstrap = BootstrapContext.use;
28
28
  export async function initBootstrap() {
29
29
  Logger.debug("Initializing bootstrap context");
@@ -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 && cloudFormationStack.stackStatus.name !== 'REVIEW_IN_PROGRESS',
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: ['CAPABILITY_IAM', 'CAPABILITY_NAMED_IAM', 'CAPABILITY_AUTO_EXPAND'],
109
+ Capabilities: [
110
+ "CAPABILITY_IAM",
111
+ "CAPABILITY_NAMED_IAM",
112
+ "CAPABILITY_AUTO_EXPAND",
113
+ ],
109
114
  Tags: options.tags,
110
115
  },
111
116
  };
@@ -459,6 +459,11 @@ async function canSkipDeploy(deployStackOptions, cloudFormationStack, parameterC
459
459
  debug(`${deployName}: no existing stack`);
460
460
  return false;
461
461
  }
462
+ // SST check: stack is not busy
463
+ if (cloudFormationStack.stackStatus.isInProgress) {
464
+ debug(`${deployName}: stack is busy`);
465
+ return false;
466
+ }
462
467
  // Template has changed (assets taken into account here)
463
468
  if (JSON.stringify(deployStackOptions.stack.template) !==
464
469
  JSON.stringify(await cloudFormationStack.template())) {
@@ -16,12 +16,21 @@ 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, Stacks } = await import("../../stacks/index.js");
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");
23
23
  const project = useProject();
24
- const identity = await useSTSIdentity();
24
+ const [identity, appMetadata] = await Promise.all([
25
+ useSTSIdentity(),
26
+ useAppMetadata(),
27
+ ]);
28
+ // Check app mode changed
29
+ if (appMetadata && appMetadata.mode !== "deploy") {
30
+ if (!(await promptChangeMode())) {
31
+ process.exit(0);
32
+ }
33
+ }
25
34
  Colors.line(`${Colors.primary.bold(`SST v${project.version}`)}`);
26
35
  Colors.gap();
27
36
  Colors.line(`${Colors.primary(`➜`)} ${Colors.bold("App:")} ${project.config.name}`);
@@ -61,5 +70,21 @@ export const deploy = (program) => program.command("deploy [filter]", "Deploy yo
61
70
  if (Object.values(results).some((stack) => Stacks.isFailed(stack.status)))
62
71
  process.exit(1);
63
72
  fs.writeFile(path.join(project.paths.out, "outputs.json"), JSON.stringify(mapValues(results, (val) => val.outputs), null, 2));
73
+ // Update app state
74
+ await saveAppMetadata({ mode: "deploy" });
64
75
  process.exit(0);
65
76
  });
77
+ async function promptChangeMode() {
78
+ const readline = await import("readline");
79
+ const rl = readline.createInterface({
80
+ input: process.stdin,
81
+ output: process.stdout,
82
+ });
83
+ return new Promise((resolve) => {
84
+ console.log("");
85
+ rl.question("You were previously running this stage in dev mode. It is recommended that you use a different stage for production. Read more here — https://docs.sst.dev/live-lambda-development\n\nAre you sure you want to deploy to this stage? (y/N) ", async (input) => {
86
+ rl.close();
87
+ resolve(input.trim() === "y");
88
+ });
89
+ });
90
+ }
@@ -10,21 +10,19 @@ 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 { Stacks } = await import("../../stacks/index.js");
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
- const { bold, magenta, green, blue, red } = await import("colorette");
16
+ const { bold, dim, yellow } = await import("colorette");
17
17
  const { render } = await import("ink");
18
18
  const React = await import("react");
19
19
  const { Context } = await import("../../context/context.js");
20
- const { DeploymentUI } = await import("../ui/deploy.js");
20
+ const { printDeploymentResults, DeploymentUI } = await import("../ui/deploy.js");
21
21
  const { useLocalServer } = await import("../local/server.js");
22
22
  const path = await import("path");
23
23
  const fs = await import("fs/promises");
24
24
  const crypto = await import("crypto");
25
- const { printDeploymentResults } = await import("../ui/deploy.js");
26
25
  const { useFunctions } = await import("../../constructs/Function.js");
27
- const { dim, gray, yellow } = await import("colorette");
28
26
  const { SiteEnv } = await import("../../site-env.js");
29
27
  const { usePothosBuilder } = await import("./plugins/pothos.js");
30
28
  const { useKyselyTypeGenerator } = await import("./plugins/kysely.js");
@@ -169,8 +167,13 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
169
167
  const results = await Stacks.deployMany(assembly.stacks);
170
168
  component.clear();
171
169
  component.unmount();
172
- lastDeployed = nextChecksum;
173
170
  printDeploymentResults(assembly, results);
171
+ // Update app state
172
+ if (!lastDeployed) {
173
+ await saveAppMetadata({ mode: "dev" });
174
+ }
175
+ lastDeployed = nextChecksum;
176
+ // Update site env
174
177
  const keys = await SiteEnv.keys();
175
178
  if (keys.length) {
176
179
  const result = {};
@@ -186,6 +189,7 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
186
189
  }
187
190
  await SiteEnv.writeValues(result);
188
191
  }
192
+ // Write outputs.json
189
193
  fs.writeFile(path.join(project.paths.out, "outputs.json"), JSON.stringify(pipe(results, omitBy((_, key) => key.includes("SstSiteEnv")), mapValues((val) => val.outputs)), null, 2));
190
194
  isWorking = false;
191
195
  if (isDirty)
@@ -217,11 +221,20 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
217
221
  });
218
222
  await build();
219
223
  });
220
- await useLocalServer({
221
- key: "",
222
- cert: "",
223
- live: true,
224
- });
224
+ const [appMetadata] = await Promise.all([
225
+ useAppMetadata(),
226
+ useLocalServer({
227
+ key: "",
228
+ cert: "",
229
+ live: true,
230
+ }),
231
+ ]);
232
+ // Check app mode changed
233
+ if (appMetadata && appMetadata.mode !== "dev") {
234
+ if (!(await promptChangeMode())) {
235
+ process.exit(0);
236
+ }
237
+ }
225
238
  clear();
226
239
  await printHeader({ console: true, hint: "ready!" });
227
240
  await Promise.all([
@@ -236,3 +249,17 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
236
249
  useStackBuilder(),
237
250
  ]);
238
251
  });
252
+ async function promptChangeMode() {
253
+ const readline = await import("readline");
254
+ const rl = readline.createInterface({
255
+ input: process.stdin,
256
+ output: process.stdout,
257
+ });
258
+ return new Promise((resolve) => {
259
+ console.log("");
260
+ rl.question("You have previously deployed this stage in production. It is recommended that you use a different stage for development. Read more here — https://docs.sst.dev/live-lambda-development\n\nAre you sure you want to run this stage in dev mode? [y/N] ", async (input) => {
261
+ rl.close();
262
+ resolve(input.trim() === "y");
263
+ });
264
+ });
265
+ }
@@ -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, Stacks } = await import("../../stacks/index.js");
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");
@@ -42,5 +42,6 @@ export const remove = (program) => program.command("remove [filter]", "Remove yo
42
42
  printDeploymentResults(assembly, results, true);
43
43
  if (Object.values(results).some((stack) => Stacks.isFailed(stack.status)))
44
44
  process.exit(1);
45
+ await clearAppMetadata();
45
46
  process.exit(0);
46
47
  });
@@ -20,7 +20,7 @@ export const useLocalServerConfig = Context.memo(async () => {
20
20
  });
21
21
  return {
22
22
  port,
23
- url: `https://console.sst.dev/${project.config.name}/${project.config.stage}${port !== 13557 ? `?port=${port}` : ""}`,
23
+ url: `https://console.sst.dev/${project.config.name}/${project.config.stage}${port !== 13557 ? `?_port=${port}` : ""}`,
24
24
  };
25
25
  });
26
26
  export async function useLocalServer(opts) {
package/cli/sst.js CHANGED
@@ -8,6 +8,10 @@ import dotenv from "dotenv";
8
8
  dotenv.config({
9
9
  override: true,
10
10
  });
11
+ dotenv.config({
12
+ path: ".env.local",
13
+ override: true,
14
+ });
11
15
  import { env } from "./commands/env.js";
12
16
  import { dev } from "./commands/dev.js";
13
17
  import { bind } from "./commands/bind.js";
package/cli/ui/deploy.js CHANGED
@@ -45,9 +45,11 @@ export const DeploymentUI = (props) => {
45
45
  return "yellow";
46
46
  }
47
47
  return (React.createElement(Box, { flexDirection: "column" },
48
- Object.entries(resources).map(([_, evt]) => {
48
+ Object.entries(resources)
49
+ .slice(0, process.stdout.rows - 2)
50
+ .map(([_, evt], index) => {
49
51
  const readable = logicalIdToCdkPath(props.assembly, evt.StackName, evt.LogicalResourceId);
50
- return (React.createElement(Box, { key: evt.LogicalResourceId },
52
+ return (React.createElement(Box, { key: index },
51
53
  React.createElement(Text, null,
52
54
  React.createElement(Spinner, null),
53
55
  " ",
@@ -113,7 +115,6 @@ function logicalIdToCdkPath(assembly, stack, logicalId) {
113
115
  return found.split("/").filter(Boolean).slice(1, -1).join("/");
114
116
  }
115
117
  function getHelper(error) {
116
- return `This is a common deploy error. Check out this GitHub issue for more details - https://github.com/serverless-stack/sst/issues/125`;
117
118
  return (getApiAccessLogPermissionsHelper(error) ||
118
119
  getAppSyncMultiResolverHelper(error) ||
119
120
  getApiLogRoleHelper(error));
@@ -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/App.js CHANGED
@@ -207,7 +207,6 @@ export class App extends cdk.App {
207
207
  Auth.injectConfig();
208
208
  this.ensureUniqueConstructIds();
209
209
  this.codegenTypes();
210
- this.buildConstructsMetadata();
211
210
  this.createBindingSsmParameters();
212
211
  this.removeGovCloudUnsupportedResourceProperties();
213
212
  for (const child of this.node.children) {
@@ -231,6 +230,7 @@ export class App extends cdk.App {
231
230
  }
232
231
  async finish() {
233
232
  await useDeferredTasks().run();
233
+ this.buildConstructsMetadata();
234
234
  }
235
235
  isRunningSSTTest() {
236
236
  // Check the env var set inside test/setup-tests.js
@@ -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);
@@ -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, } from "aws-cdk-lib";
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: [`arn:${stack.partition}:s3:::${asset.s3BucketName}/${asset.s3ObjectKey}`],
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;