sst 2.0.0-rc.11 → 2.0.0-rc.13

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 (51) hide show
  1. package/bootstrap.js +3 -3
  2. package/cache.js +1 -1
  3. package/cli/commands/bind.js +2 -2
  4. package/cli/commands/build.js +4 -4
  5. package/cli/commands/deploy.js +4 -5
  6. package/cli/commands/dev.js +14 -16
  7. package/cli/commands/env.js +4 -3
  8. package/cli/commands/plugins/kysely.js +2 -2
  9. package/cli/commands/remove.js +4 -5
  10. package/cli/commands/update.js +4 -2
  11. package/cli/local/router.d.ts +1 -1
  12. package/cli/local/router.js +3 -3
  13. package/cli/local/server.js +3 -3
  14. package/cli/program.js +1 -1
  15. package/cli/telemetry/environment.js +1 -1
  16. package/cli/ui/deploy.js +2 -2
  17. package/config.js +5 -5
  18. package/constructs/App.js +1 -1
  19. package/constructs/AppSyncApi.js +1 -1
  20. package/constructs/Function.js +2 -2
  21. package/constructs/Job.js +2 -2
  22. package/constructs/SsrSite.js +1 -1
  23. package/constructs/Stack.js +1 -1
  24. package/constructs/StaticSite.js +1 -1
  25. package/constructs/deprecated/NextjsSite.js +1 -1
  26. package/credentials.js +6 -6
  27. package/index.d.ts +1 -0
  28. package/index.js +1 -0
  29. package/iot.js +2 -2
  30. package/logger.js +1 -1
  31. package/node/api/index.d.ts +2 -0
  32. package/node/api/index.js +8 -0
  33. package/package.json +4 -3
  34. package/project.d.ts +44 -0
  35. package/{app.js → project.js} +59 -51
  36. package/runtime/handlers/dotnet.js +1 -1
  37. package/runtime/handlers/java.js +1 -1
  38. package/runtime/handlers/node.js +1 -1
  39. package/runtime/handlers.js +1 -1
  40. package/runtime/runtime.d.ts +4 -0
  41. package/runtime/workers.js +4 -0
  42. package/site-env.js +1 -1
  43. package/sst.mjs +550 -549
  44. package/stacks/build.d.ts +1 -1
  45. package/stacks/build.js +9 -20
  46. package/stacks/metadata.js +5 -5
  47. package/stacks/synth.js +4 -4
  48. package/support/bridge/bridge.mjs +22 -22
  49. package/support/rds-migrator/index.mjs +22 -22
  50. package/watcher.js +1 -1
  51. package/app.d.ts +0 -36
package/bootstrap.js CHANGED
@@ -2,7 +2,7 @@ import { GetParametersCommand, SSMClient } from "@aws-sdk/client-ssm";
2
2
  import { Tags, Stack, RemovalPolicy, App } from "aws-cdk-lib";
3
3
  import { BlockPublicAccess, Bucket, BucketEncryption, } from "aws-cdk-lib/aws-s3";
4
4
  import { ParameterTier, StringParameter } from "aws-cdk-lib/aws-ssm";
5
- import { useProject } from "./app.js";
5
+ import { useProject } from "./project.js";
6
6
  import { createSpinner } from "./cli/spinner.js";
7
7
  import { Context } from "./context/context.js";
8
8
  import { useAWSClient } from "./credentials.js";
@@ -25,14 +25,14 @@ export const useBootstrap = Context.memo(async () => {
25
25
  const app = new App();
26
26
  const stack = new Stack(app, "SSTBootstrap", {
27
27
  env: {
28
- region: project.region,
28
+ region: project.config.region,
29
29
  },
30
30
  });
31
31
  const tags = {};
32
32
  for (const [key, value] of Object.entries(tags)) {
33
33
  Tags.of(app).add(key, value);
34
34
  }
35
- const bucket = new Bucket(stack, project.region, {
35
+ const bucket = new Bucket(stack, project.config.region, {
36
36
  encryption: BucketEncryption.S3_MANAGED,
37
37
  removalPolicy: RemovalPolicy.DESTROY,
38
38
  autoDeleteObjects: true,
package/cache.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import path from "path";
2
2
  import fs from "fs/promises";
3
- import { useProject } from "./app.js";
3
+ import { useProject } from "./project.js";
4
4
  import { Logger } from "./logger.js";
5
5
  import { Context } from "./context/context.js";
6
6
  export const useCache = Context.memo(async () => {
@@ -1,4 +1,4 @@
1
- import { useProject } from "../../app.js";
1
+ import { useProject } from "../../project.js";
2
2
  export const bind = (program) => program.command("bind <command>", "Binds blah", (yargs) => yargs.positional("command", {
3
3
  type: "string",
4
4
  describe: "Command to bind to",
@@ -16,7 +16,7 @@ export const bind = (program) => program.command("bind <command>", "Binds blah",
16
16
  AWS_ACCESS_KEY_ID: credentials.accessKeyId,
17
17
  AWS_SECRET_ACCESS_KEY: credentials.secretAccessKey,
18
18
  AWS_SESSION_TOKEN: credentials.sessionToken,
19
- AWS_REGION: project.region,
19
+ AWS_REGION: project.config.region,
20
20
  PATH: process.env.PATH,
21
21
  },
22
22
  stdio: "inherit",
@@ -1,11 +1,11 @@
1
+ import { useProject } from "../../project.js";
1
2
  import { createSpinner } from "../spinner.js";
2
- export const build = (program) => program.command("build", "Build stacks code", yargs => yargs.option("from", { type: "string" }), async () => {
3
+ export const build = (program) => program.command("build", "Build stacks code", (yargs) => yargs.option("from", { type: "string" }), async () => {
3
4
  const { Stacks } = await import("../../stacks/index.js");
4
5
  const spinner = createSpinner("Building stacks").start();
5
- const fn = await Stacks.build();
6
6
  await Stacks.synth({
7
- fn,
8
- mode: "deploy"
7
+ fn: useProject().stacks,
8
+ mode: "deploy",
9
9
  });
10
10
  spinner.succeed();
11
11
  process.exit(0);
@@ -10,22 +10,21 @@ export const deploy = (program) => program.command("deploy [filter]", "Work on y
10
10
  const React = await import("react");
11
11
  const { CloudAssembly } = await import("aws-cdk-lib/cx-api");
12
12
  const { blue, bold } = await import("colorette");
13
- const { useProject } = await import("../../app.js");
13
+ const { useProject } = await import("../../project.js");
14
14
  const { Stacks } = await import("../../stacks/index.js");
15
15
  const { render } = await import("ink");
16
16
  const { DeploymentUI } = await import("../ui/deploy.js");
17
+ const project = useProject();
17
18
  const assembly = await (async function () {
18
19
  if (args.from) {
19
20
  const result = new CloudAssembly(args.from);
20
21
  return result;
21
22
  }
22
- const fn = await Stacks.build();
23
23
  return await Stacks.synth({
24
- fn,
24
+ fn: project.stacks,
25
25
  mode: "deploy",
26
26
  });
27
27
  })();
28
- const project = useProject();
29
28
  const target = assembly.stacks.filter((s) => !args.filter ||
30
29
  s.stackName.toLowerCase().includes(args.filter.toLowerCase()));
31
30
  if (!target.length) {
@@ -33,7 +32,7 @@ export const deploy = (program) => program.command("deploy [filter]", "Work on y
33
32
  process.exit(1);
34
33
  return;
35
34
  }
36
- console.log(`Deploying ${bold(target.length + " stacks")} for stage ${blue(project.stage)}...`);
35
+ console.log(`Deploying ${bold(target.length + " stacks")} for stage ${blue(project.config.stage)}...`);
37
36
  let component = undefined;
38
37
  if (args.fullscreen) {
39
38
  process.stdout.write("\x1b[?1049h");
@@ -4,11 +4,11 @@ import crypto from "crypto";
4
4
  import { printDeploymentResults } from "../ui/deploy.js";
5
5
  import { useFunctions } from "../../constructs/Function.js";
6
6
  import { dim, gray, yellow } from "colorette";
7
- import { useProject } from "../../app.js";
8
7
  import { SiteEnv } from "../../site-env.js";
9
8
  import { usePothosBuilder } from "./plugins/pothos.js";
10
9
  import { useKyselyTypeGenerator } from "./plugins/kysely.js";
11
10
  import { useRDSWarmer } from "./plugins/warmer.js";
11
+ import { useProject } from "../../project.js";
12
12
  export const dev = (program) => program.command(["start", "dev"], "Work on your SST app locally", (yargs) => yargs.option("fullscreen", {
13
13
  type: "boolean",
14
14
  describe: "Disable full screen UI",
@@ -34,13 +34,13 @@ export const dev = (program) => program.command(["start", "dev"], "Work on your
34
34
  const useFunctionLogger = Context.memo(async () => {
35
35
  const bus = useBus();
36
36
  bus.subscribe("function.invoked", async (evt) => {
37
- console.log(bold(magenta(`Invoked `)), bold(useFunctions().fromID(evt.properties.functionID).handler));
37
+ console.log(bold(magenta(`Invoked `)), useFunctions().fromID(evt.properties.functionID).handler);
38
38
  });
39
39
  bus.subscribe("function.build.success", async (evt) => {
40
- console.log(bold(gray(`Built `)), bold(useFunctions().fromID(evt.properties.functionID).handler));
40
+ console.log(bold(gray(`Built `)), useFunctions().fromID(evt.properties.functionID).handler);
41
41
  });
42
42
  bus.subscribe("function.build.failed", async (evt) => {
43
- console.log(bold(red(`Build failed `)), bold(useFunctions().fromID(evt.properties.functionID).handler));
43
+ console.log(bold(red(`Build failed `)), useFunctions().fromID(evt.properties.functionID).handler);
44
44
  console.log(dim(evt.properties.errors.join("\n")));
45
45
  });
46
46
  bus.subscribe("worker.stdout", async (evt) => {
@@ -50,14 +50,14 @@ export const dev = (program) => program.command(["start", "dev"], "Work on your
50
50
  const line = lines[i];
51
51
  lines[i] = " " + line;
52
52
  }
53
- console.log(bold(blue(`Log `)), bold(useFunctions().fromID(evt.properties.functionID).handler));
53
+ console.log(bold(blue(`Log `)), useFunctions().fromID(evt.properties.functionID).handler);
54
54
  console.log(dim(lines.join("\n")));
55
55
  });
56
56
  bus.subscribe("function.success", async (evt) => {
57
- console.log(bold(green(`Success `)), bold(useFunctions().fromID(evt.properties.functionID).handler));
57
+ console.log(bold(green(`Success `)), useFunctions().fromID(evt.properties.functionID).handler);
58
58
  });
59
59
  bus.subscribe("function.error", async (evt) => {
60
- console.log(bold(red(`Error `)), bold(useFunctions().fromID(evt.properties.functionID).handler), evt.properties.errorMessage);
60
+ console.log(bold(red(`Error `)), useFunctions().fromID(evt.properties.functionID).handler, evt.properties.errorMessage);
61
61
  for (const line of evt.properties.trace || []) {
62
62
  console.log(` ${dim(line)}`);
63
63
  }
@@ -65,17 +65,19 @@ export const dev = (program) => program.command(["start", "dev"], "Work on your
65
65
  });
66
66
  const useStackBuilder = Context.memo(async () => {
67
67
  const watcher = useWatcher();
68
- const bus = useBus();
69
68
  const project = useProject();
69
+ const bus = useBus();
70
70
  let lastDeployed;
71
71
  let pending;
72
72
  let isDeploying = false;
73
73
  async function build() {
74
74
  const spinner = createSpinner("Building stacks").start();
75
75
  try {
76
- const fn = await Stacks.build();
76
+ const [metafile, sstConfig] = await Stacks.load(project.paths.config);
77
+ project.metafile = metafile;
78
+ project.stacks = sstConfig.stacks;
77
79
  const assembly = await Stacks.synth({
78
- fn,
80
+ fn: project.stacks,
79
81
  outDir: `.sst/cdk.out`,
80
82
  mode: "dev",
81
83
  });
@@ -151,14 +153,10 @@ export const dev = (program) => program.command(["start", "dev"], "Work on your
151
153
  .digest("hex");
152
154
  return hash;
153
155
  }
154
- let metafile;
155
- bus.subscribe("stack.built", async (evt) => {
156
- metafile = evt.properties.metafile;
157
- });
158
156
  watcher.subscribe("file.changed", async (evt) => {
159
- if (!metafile)
157
+ if (!project.metafile)
160
158
  return;
161
- if (!metafile.inputs[evt.properties.relative])
159
+ if (!project.metafile.inputs[evt.properties.relative])
162
160
  return;
163
161
  build();
164
162
  });
@@ -1,4 +1,4 @@
1
- import { useProject } from "../../app.js";
1
+ import { useProject } from "../../project.js";
2
2
  import { createSpinner } from "../spinner.js";
3
3
  import fs from "fs/promises";
4
4
  import path from "path";
@@ -10,17 +10,18 @@ export const env = (program) => program.command("env <command>", "description",
10
10
  demandOption: true,
11
11
  }), async (args) => {
12
12
  const project = useProject();
13
- const spinner = createSpinner("Waiting for SST to start").start();
13
+ let spinner;
14
14
  while (true) {
15
15
  const exists = await fs
16
16
  .access(SiteEnv.valuesFile())
17
17
  .then(() => true)
18
18
  .catch(() => false);
19
19
  if (!exists) {
20
+ spinner = createSpinner("Waiting for SST to start").start();
20
21
  await new Promise((resolve) => setTimeout(resolve, 1000));
21
22
  continue;
22
23
  }
23
- spinner.succeed();
24
+ spinner?.succeed();
24
25
  const sites = await SiteEnv.values();
25
26
  const current = path.relative(project.paths.root, process.cwd());
26
27
  const env = sites[current] || {};
@@ -5,7 +5,7 @@ import * as fs from "fs/promises";
5
5
  import { DatabaseMetadata, EnumCollection, PostgresDialect, Serializer, Transformer, } from "kysely-codegen";
6
6
  import { Context } from "../../../context/context.js";
7
7
  import { useBus } from "../../../bus.js";
8
- import { useProject } from "../../../app.js";
8
+ import { useProject } from "../../../project.js";
9
9
  export const useKyselyTypeGenerator = Context.memo(async () => {
10
10
  let databases = [];
11
11
  const bus = useBus();
@@ -21,7 +21,7 @@ export const useKyselyTypeGenerator = Context.memo(async () => {
21
21
  resourceArn: db.clusterArn,
22
22
  database: db.defaultDatabaseName,
23
23
  client: new RDSDataService({
24
- region: project.region,
24
+ region: project.config.region,
25
25
  }),
26
26
  },
27
27
  }),
@@ -5,7 +5,7 @@ export const remove = (program) => program.command("remove [filter]", "Remove al
5
5
  const React = await import("react");
6
6
  const { CloudAssembly } = await import("aws-cdk-lib/cx-api");
7
7
  const { blue, bold } = await import("colorette");
8
- const { useProject } = await import("../../app.js");
8
+ const { useProject } = await import("../../project.js");
9
9
  const { Stacks } = await import("../../stacks/index.js");
10
10
  const { render } = await import("ink");
11
11
  const { DeploymentUI } = await import("../ui/deploy.js");
@@ -14,9 +14,9 @@ export const remove = (program) => program.command("remove [filter]", "Remove al
14
14
  const result = new CloudAssembly(args.from);
15
15
  return result;
16
16
  }
17
- const fn = await Stacks.build();
17
+ const project = useProject();
18
18
  return await Stacks.synth({
19
- fn,
19
+ fn: project.stacks,
20
20
  mode: "remove",
21
21
  });
22
22
  })();
@@ -26,9 +26,8 @@ export const remove = (program) => program.command("remove [filter]", "Remove al
26
26
  if (!target.length) {
27
27
  console.log(`No stacks found matching ${blue(args.filter)}`);
28
28
  process.exit(1);
29
- return;
30
29
  }
31
- console.log(`Removing ${bold(target.length + " stacks")} for stage ${blue(project.stage)}...`);
30
+ console.log(`Removing ${bold(target.length + " stacks")} for stage ${blue(project.config.stage)}...`);
32
31
  process.stdout.write("\x1b[?1049h");
33
32
  const component = render(React.createElement(DeploymentUI, { stacks: target.map((s) => s.stackName) }));
34
33
  const results = await Stacks.removeMany(target);
@@ -1,14 +1,14 @@
1
1
  import { green, yellow } from "colorette";
2
2
  import fs from "fs/promises";
3
3
  import path from "path";
4
- const PACKAGE_MATCH = ["sst", "aws-cdk", "@aws-cdk"];
4
+ const PACKAGE_MATCH = ["sst", "aws-cdk", "@aws-cdk", "constructs"];
5
5
  const FIELDS = ["dependencies", "devDependencies"];
6
6
  export const update = (program) => program.command("update [ver]", "Update SST and CDK packages to another version", (yargs) => yargs.positional("ver", {
7
7
  type: "string",
8
8
  describe: "Optional SST version to update to",
9
9
  }), async (args) => {
10
10
  const { fetch } = await import("undici");
11
- const { useProject } = await import("../../app.js");
11
+ const { useProject } = await import("../../project.js");
12
12
  const project = useProject();
13
13
  const files = await find(project.paths.root);
14
14
  const metadata = await fetch(`https://registry.npmjs.org/sst/${args.ver || "latest"}`).then((resp) => resp.json());
@@ -28,6 +28,8 @@ export const update = (program) => program.command("update [ver]", "Update SST a
28
28
  const desired = (() => {
29
29
  if (pkg === "sst")
30
30
  return metadata.version;
31
+ if (pkg === "constructs")
32
+ return metadata.dependencies.constructs;
31
33
  if (pkg.endsWith("alpha"))
32
34
  return metadata.dependencies["@aws-cdk/aws-apigatewayv2-alpha"];
33
35
  return metadata.dependencies["aws-cdk-lib"];
@@ -32,7 +32,7 @@ export declare type Context = {
32
32
  state: State;
33
33
  };
34
34
  export declare const router: import("@trpc/server/dist/declarations/src/router.js").Router<Context, Context, Record<"getCredentials", import("@trpc/server/dist/declarations/src/internals/procedure.js").Procedure<Context, Context, undefined, undefined, {
35
- region: string;
35
+ region: string | undefined;
36
36
  credentials: {
37
37
  accessKeyId: string;
38
38
  secretAccessKey: string;
@@ -1,5 +1,5 @@
1
1
  import * as trpc from "@trpc/server";
2
- import { useProject } from "../../app.js";
2
+ import { useProject } from "../../project.js";
3
3
  import { useBus } from "../../bus.js";
4
4
  import { useAWSCredentials } from "../../credentials.js";
5
5
  export const router = trpc
@@ -9,7 +9,7 @@ export const router = trpc
9
9
  const project = useProject();
10
10
  const credentials = await useAWSCredentials();
11
11
  return {
12
- region: project.region,
12
+ region: project.config.region,
13
13
  credentials: {
14
14
  accessKeyId: credentials.accessKeyId,
15
15
  secretAccessKey: credentials.secretAccessKey,
@@ -24,7 +24,7 @@ export const router = trpc
24
24
  },
25
25
  })
26
26
  .mutation("deploy", {
27
- async resolve({ ctx }) {
27
+ async resolve() {
28
28
  return;
29
29
  },
30
30
  })
@@ -9,13 +9,13 @@ import { applyWSSHandler } from "@trpc/server/adapters/ws/dist/trpc-server-adapt
9
9
  import { router } from "./router.js";
10
10
  import { optimise } from "dendriform-immer-patch-optimiser";
11
11
  import { sync } from "cross-spawn";
12
- import { useProject } from "../../app.js";
12
+ import { useProject } from "../../project.js";
13
13
  import { useBus } from "../../bus.js";
14
14
  export async function useLocalServer(opts) {
15
15
  const project = useProject();
16
16
  let state = {
17
- app: project.name,
18
- stage: project.stage,
17
+ app: project.config.name,
18
+ stage: project.config.stage,
19
19
  live: opts.live,
20
20
  stacks: {
21
21
  status: "idle",
package/cli/program.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import yargs from "yargs";
2
2
  import { hideBin } from "yargs/helpers";
3
- import { initProject } from "../app.js";
3
+ import { initProject } from "../project.js";
4
4
  import { trackCli } from "./telemetry/telemetry.js";
5
5
  export const program = yargs(hideBin(process.argv))
6
6
  .scriptName("sst")
@@ -1,6 +1,6 @@
1
1
  import os from "os";
2
2
  import ciInfo from "ci-info";
3
- import { useProject } from "../../app.js";
3
+ import { useProject } from "../../project.js";
4
4
  let data;
5
5
  export function getEnvironmentData() {
6
6
  if (data) {
package/cli/ui/deploy.js CHANGED
@@ -3,7 +3,7 @@ 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 { useProject } from "../../app.js";
6
+ import { useProject } from "../../project.js";
7
7
  import { blue, bold, green, red } from "colorette";
8
8
  // @ts-ignore
9
9
  const { default: Spinner } = inkSpinner;
@@ -77,7 +77,7 @@ export const DeploymentUI = (props) => {
77
77
  "Deploying ",
78
78
  React.createElement(Text, { color: "bold" }, props.stacks.length),
79
79
  " stacks for stage ",
80
- React.createElement(Text, { color: "blue" }, useProject().stage)),
80
+ React.createElement(Text, { color: "blue" }, useProject().config.stage)),
81
81
  Object.entries(stacks).map(([stackID, status]) => {
82
82
  return (React.createElement(React.Fragment, { key: stackID },
83
83
  React.createElement(Text, null,
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 "./app.js";
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;
@@ -62,8 +62,8 @@ 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,
65
+ SST_APP: project.config.name,
66
+ SST_STAGE: project.config.stage,
67
67
  ...pipe(parameters, map((p) => [`SST_${p.type}_${p.prop}_${p.id}`, p.value]), Object.fromEntries),
68
68
  };
69
69
  return env;
@@ -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) {
package/constructs/App.js CHANGED
@@ -14,7 +14,7 @@ import { createRequire } from "module";
14
14
  import { Auth } from "./Auth.js";
15
15
  import { useDeferredTasks } from "./deferred_task.js";
16
16
  import { AppContext } from "./context.js";
17
- import { useProject } from "../app.js";
17
+ import { useProject } from "../project.js";
18
18
  import { Logger } from "../logger.js";
19
19
  import { SiteEnv } from "../site-env.js";
20
20
  const require = createRequire(import.meta.url);
@@ -15,7 +15,7 @@ import * as appsync from "@aws-cdk/aws-appsync-alpha";
15
15
  import * as appSyncApiDomain from "./util/appSyncApiDomain.js";
16
16
  import { getFunctionRef, isCDKConstruct } from "./Construct.js";
17
17
  import { Function as Fn, } from "./Function.js";
18
- import { useProject } from "../app.js";
18
+ import { useProject } from "../project.js";
19
19
  /////////////////////
20
20
  // Construct
21
21
  /////////////////////
@@ -18,7 +18,7 @@ import * as functionUrlCors from "./util/functionUrlCors.js";
18
18
  import url from "url";
19
19
  import { useDeferredTasks } from "./deferred_task.js";
20
20
  import { useWarning } from "./util/warning.js";
21
- import { useProject } from "../app.js";
21
+ import { useProject } from "../project.js";
22
22
  import { useRuntimeHandlers } from "../runtime/handlers.js";
23
23
  import { createAppContext } from "./context.js";
24
24
  const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
@@ -229,7 +229,7 @@ export class Function extends lambda.Function {
229
229
  // Add config
230
230
  this.addEnvironment("SST_APP", app.name, { removeInEdge: true });
231
231
  this.addEnvironment("SST_STAGE", app.stage, { removeInEdge: true });
232
- this.addEnvironment("SST_SSM_PREFIX", useProject().ssmPrefix, {
232
+ this.addEnvironment("SST_SSM_PREFIX", useProject().config.ssmPrefix, {
233
233
  removeInEdge: true,
234
234
  });
235
235
  this.addConfig(props.config || []);
package/constructs/Job.js CHANGED
@@ -12,7 +12,7 @@ import { attachPermissionsToRole } from "./util/permission.js";
12
12
  import { bindEnvironment, bindPermissions } from "./util/functionBinding.js";
13
13
  import { useDeferredTasks } from "./deferred_task.js";
14
14
  import { useWarning } from "./util/warning.js";
15
- import { useProject } from "../app.js";
15
+ import { useProject } from "../project.js";
16
16
  import { useRuntimeHandlers } from "../runtime/handlers.js";
17
17
  const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
18
18
  /////////////////////
@@ -165,7 +165,7 @@ export class Job extends Construct {
165
165
  environmentVariables: {
166
166
  SST_APP: { value: app.name },
167
167
  SST_STAGE: { value: app.stage },
168
- SST_SSM_PREFIX: { value: useProject().ssmPrefix },
168
+ SST_SSM_PREFIX: { value: useProject().config.ssmPrefix },
169
169
  },
170
170
  timeout: this.normalizeTimeout(this.props.timeout || "8 hours"),
171
171
  buildSpec: codebuild.BuildSpec.fromObject({
@@ -25,7 +25,7 @@ import { getBuildCmdEnvironment, buildErrorResponsesForRedirectToIndex, } from "
25
25
  import { attachPermissionsToRole } from "./util/permission.js";
26
26
  import { ENVIRONMENT_PLACEHOLDER, getParameterPath, } from "./util/functionBinding.js";
27
27
  import { SiteEnv } from "../site-env.js";
28
- import { useProject } from "../app.js";
28
+ import { useProject } from "../project.js";
29
29
  const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
30
30
  /**
31
31
  * The `SsrSite` construct is a higher level CDK construct that makes it easy to create modern web apps with Server Side Rendering capabilities.
@@ -7,7 +7,7 @@ import { Function as Fn } from "./Function.js";
7
7
  import { isConstruct } from "./Construct.js";
8
8
  import { createRequire } from "module";
9
9
  import { useApp } from "./context.js";
10
- import { useProject } from "../app.js";
10
+ import { useProject } from "../project.js";
11
11
  const require = createRequire(import.meta.url);
12
12
  const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
13
13
  /**
@@ -21,7 +21,7 @@ import { getBuildCmdEnvironment, buildErrorResponsesFor404ErrorPage, buildErrorR
21
21
  import { isCDKConstruct } from "./Construct.js";
22
22
  import { ENVIRONMENT_PLACEHOLDER, getParameterPath, } from "./util/functionBinding.js";
23
23
  import { gray } from "colorette";
24
- import { useProject } from "../app.js";
24
+ import { useProject } from "../project.js";
25
25
  import { SiteEnv } from "../site-env.js";
26
26
  const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
27
27
  /////////////////////
@@ -28,7 +28,7 @@ import { ENVIRONMENT_PLACEHOLDER, getParameterPath, } from "../util/functionBind
28
28
  import * as crossRegionHelper from "./cross-region-helper.js";
29
29
  import { gray, red } from "colorette";
30
30
  import { SiteEnv } from "../../site-env.js";
31
- import { useProject } from "../../app.js";
31
+ import { useProject } from "../../project.js";
32
32
  const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
33
33
  /////////////////////
34
34
  // Construct
package/credentials.js CHANGED
@@ -7,9 +7,9 @@ import { SdkProvider } from "aws-cdk/lib/api/aws-auth/sdk-provider.js";
7
7
  import { StandardRetryStrategy } from "@aws-sdk/middleware-retry";
8
8
  export const useAWSCredentialsProvider = Context.memo(() => {
9
9
  const project = useProject();
10
- Logger.debug("Using AWS profile", project.profile);
10
+ Logger.debug("Using AWS profile", project.config.profile);
11
11
  const provider = fromNodeProviderChain({
12
- profile: project.profile,
12
+ profile: project.config.profile,
13
13
  });
14
14
  return provider;
15
15
  });
@@ -31,7 +31,7 @@ export function useAWSClient(client, force = false) {
31
31
  return existing;
32
32
  const [project, credentials] = [useProject(), useAWSCredentialsProvider()];
33
33
  const result = new client({
34
- region: project.region,
34
+ region: project.config.region,
35
35
  credentials: credentials,
36
36
  retryStrategy: new StandardRetryStrategy(async () => 10000, {
37
37
  retryDecider: (err) => {
@@ -51,7 +51,7 @@ export function useAWSClient(client, force = false) {
51
51
  return result;
52
52
  }
53
53
  import aws from "aws-sdk";
54
- import { useProject } from "./app.js";
54
+ import { useProject } from "./project.js";
55
55
  const CredentialProviderChain = aws.CredentialProviderChain;
56
56
  /**
57
57
  * Do not use this. It is only used for AWS CDK compatibility.
@@ -81,9 +81,9 @@ export const useAWSProvider = Context.memo(async () => {
81
81
  secretAccessKey: creds.secretAccessKey,
82
82
  }),
83
83
  ]);
84
- const provider = new SdkProvider(chain, project.region, {
84
+ const provider = new SdkProvider(chain, project.config.region, {
85
85
  maxRetries: 10000,
86
- region: project.region,
86
+ region: project.config.region,
87
87
  });
88
88
  return provider;
89
89
  });
package/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export type { SSTConfig } from "./project.js";
package/index.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/iot.js CHANGED
@@ -15,7 +15,7 @@ export const useIOTEndpoint = Context.memo(async () => {
15
15
  });
16
16
  import iot from "aws-iot-device-sdk";
17
17
  import { useBus } from "./bus.js";
18
- import { useProject } from "./app.js";
18
+ import { useProject } from "./project.js";
19
19
  import { Logger } from "./logger.js";
20
20
  export const useIOT = Context.memo(async () => {
21
21
  const bus = useBus();
@@ -29,7 +29,7 @@ export const useIOT = Context.memo(async () => {
29
29
  secretKey: creds.secretAccessKey,
30
30
  sessionToken: creds.sessionToken,
31
31
  });
32
- const PREFIX = `/sst/${project.name}/${project.stage}`;
32
+ const PREFIX = `/sst/${project.config.name}/${project.config.stage}`;
33
33
  device.subscribe(`${PREFIX}/events`);
34
34
  const fragments = new Map();
35
35
  device.on("error", (err) => {
package/logger.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import fs from "fs/promises";
2
2
  import path from "path";
3
- import { useProject } from "./app.js";
3
+ import { useProject } from "./project.js";
4
4
  import { Context } from "./context/context.js";
5
5
  let previous = new Date();
6
6
  const useFile = Context.memo(async () => {
@@ -40,3 +40,5 @@ export declare function useHeader(key: string): string | undefined;
40
40
  export declare function useFormValue(name: string): string | null | undefined;
41
41
  export declare function useQueryParams(): import("aws-lambda").APIGatewayProxyEventQueryStringParameters;
42
42
  export declare function useQueryParam(name: string): string | undefined;
43
+ export declare function usePathParams(): import("aws-lambda").APIGatewayProxyEventPathParameters;
44
+ export declare function usePathParam(name: string): string | undefined;
package/node/api/index.js CHANGED
@@ -86,3 +86,11 @@ export function useQueryParams() {
86
86
  export function useQueryParam(name) {
87
87
  return useQueryParams()[name];
88
88
  }
89
+ export function usePathParams() {
90
+ const evt = useEvent("api");
91
+ const path = evt.pathParameters || {};
92
+ return path;
93
+ }
94
+ export function usePathParam(name) {
95
+ return usePathParams()[name];
96
+ }