sst 2.22.10 → 2.23.0

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/sst.mjs CHANGED
@@ -161,13 +161,6 @@ var init_module = __esm({
161
161
  });
162
162
 
163
163
  // src/util/fs.ts
164
- var fs_exports = {};
165
- __export(fs_exports, {
166
- existsAsync: () => existsAsync,
167
- findAbove: () => findAbove,
168
- findBelow: () => findBelow,
169
- isChild: () => isChild
170
- });
171
164
  import fs2 from "fs/promises";
172
165
  import path2 from "path";
173
166
  async function findAbove(dir, target) {
@@ -1328,7 +1321,8 @@ var init_monitor = __esm({
1328
1321
  "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS",
1329
1322
  "UPDATE_IN_PROGRESS",
1330
1323
  "UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS",
1331
- "UPDATE_ROLLBACK_IN_PROGRESS"
1324
+ "UPDATE_ROLLBACK_IN_PROGRESS",
1325
+ "PUBLISH_ASSETS_IN_PROGRESS"
1332
1326
  ];
1333
1327
  STATUSES_SUCCESS = [
1334
1328
  "CREATE_COMPLETE",
@@ -3494,6 +3488,10 @@ async function deploy(stack) {
3494
3488
  }));
3495
3489
  try {
3496
3490
  await addInUseExports(stack);
3491
+ bus.publish("stack.status", {
3492
+ stackID: stack.stackName,
3493
+ status: "PUBLISH_ASSETS_IN_PROGRESS"
3494
+ });
3497
3495
  const result = await deployment.deployStack({
3498
3496
  stack,
3499
3497
  quiet: true,
@@ -3723,6 +3721,7 @@ var init_cache = __esm({
3723
3721
  var metadata_exports = {};
3724
3722
  __export(metadata_exports, {
3725
3723
  metadata: () => metadata2,
3724
+ metadataForStack: () => metadataForStack,
3726
3725
  useMetadata: () => useMetadata
3727
3726
  });
3728
3727
  import {
@@ -3730,6 +3729,25 @@ import {
3730
3729
  GetObjectCommand as GetObjectCommand2,
3731
3730
  ListObjectsV2Command
3732
3731
  } from "@aws-sdk/client-s3";
3732
+ async function metadataForStack(stack) {
3733
+ const project = useProject();
3734
+ const [credentials, bootstrap2] = await Promise.all([
3735
+ useAWSCredentials(),
3736
+ useBootstrap()
3737
+ ]);
3738
+ const s3 = new S3Client2({
3739
+ region: project.config.region,
3740
+ credentials
3741
+ });
3742
+ const result = await s3.send(
3743
+ new GetObjectCommand2({
3744
+ Key: `stackMetadata/app.${project.config.name}/stage.${project.config.stage}/stack.${stack}.json`,
3745
+ Bucket: bootstrap2.bucket
3746
+ })
3747
+ );
3748
+ const body = await result.Body.transformToString();
3749
+ return JSON.parse(body);
3750
+ }
3733
3751
  async function metadata2() {
3734
3752
  Logger.debug("Fetching all metadata");
3735
3753
  const project = useProject();
@@ -4702,6 +4720,9 @@ var init_node = __esm({
4702
4720
  if (input.mode === "start") {
4703
4721
  rebuildCache[input.functionID] = { ctx, result };
4704
4722
  }
4723
+ if (input.mode === "deploy") {
4724
+ ctx.dispose();
4725
+ }
4705
4726
  logMemoryUsage(input.functionID, input.props.handler);
4706
4727
  return {
4707
4728
  type: "success",
@@ -5795,6 +5816,7 @@ __export(stacks_exports, {
5795
5816
  load: () => load,
5796
5817
  loadAssembly: () => loadAssembly,
5797
5818
  metadata: () => metadata2,
5819
+ metadataForStack: () => metadataForStack,
5798
5820
  monitor: () => monitor,
5799
5821
  publishAssets: () => publishAssets4,
5800
5822
  remove: () => remove,
@@ -5945,7 +5967,10 @@ async function bootstrapSST() {
5945
5967
  for (const [key, value] of Object.entries(bootstrap2?.tags || {})) {
5946
5968
  Tags.of(app).add(key, value);
5947
5969
  }
5948
- const bucket = new Bucket(stack, region, {
5970
+ const bucket = bootstrap2?.useExistingBucket ? {
5971
+ bucketName: bootstrap2.useExistingBucket,
5972
+ bucketArn: `arn:${stack.partition}:s3:::${bootstrap2.useExistingBucket}`
5973
+ } : new Bucket(stack, region, {
5949
5974
  encryption: BucketEncryption.S3_MANAGED,
5950
5975
  removalPolicy: RemovalPolicy.DESTROY,
5951
5976
  autoDeleteObjects: true,
@@ -6811,10 +6836,32 @@ var init_deploy2 = __esm({
6811
6836
  init_colors();
6812
6837
  init_project();
6813
6838
  DeploymentUI = (props) => {
6839
+ const [statuses, setStatuses] = useState({});
6814
6840
  const [resources, setResources] = useState({});
6815
6841
  useEffect(() => {
6816
6842
  Colors.gap();
6817
6843
  const bus = useBus();
6844
+ const status = bus.subscribe("stack.status", (payload) => {
6845
+ const { stackID, status: status2 } = payload.properties;
6846
+ setStatuses((previous2) => {
6847
+ if (status2 !== "PUBLISH_ASSETS_IN_PROGRESS") {
6848
+ if (previous2[stackID]) {
6849
+ Colors.line(
6850
+ Colors.warning(Colors.prefix),
6851
+ Colors.dim(stackNameToId(stackID)),
6852
+ Colors.dim("PUBLISH_ASSETS_COMPLETE"),
6853
+ ""
6854
+ );
6855
+ }
6856
+ const { [stackID]: _, ...next } = previous2;
6857
+ return next;
6858
+ }
6859
+ return {
6860
+ ...previous2,
6861
+ [stackID]: status2
6862
+ };
6863
+ });
6864
+ });
6818
6865
  const event = bus.subscribe("stack.event", (payload) => {
6819
6866
  const { event: event2 } = payload.properties;
6820
6867
  setResources((previous2) => {
@@ -6845,6 +6892,7 @@ var init_deploy2 = __esm({
6845
6892
  });
6846
6893
  return () => {
6847
6894
  bus.unsubscribe(event);
6895
+ bus.unsubscribe(status);
6848
6896
  };
6849
6897
  }, []);
6850
6898
  function color(status) {
@@ -6854,14 +6902,19 @@ var init_deploy2 = __esm({
6854
6902
  return "green";
6855
6903
  return "yellow";
6856
6904
  }
6857
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, Object.entries(resources).slice(0, process.stdout.rows - 2).map(([_, evt], index) => {
6905
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, Object.entries(statuses).slice(0, process.stdout.rows - 2).map(([stack, status], index) => {
6906
+ return /* @__PURE__ */ React.createElement(Box, { key: index }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Spinner, null), " ", stackNameToId(stack), " "), /* @__PURE__ */ React.createElement(Text, { color: color(status) }, status));
6907
+ }), Object.entries(resources).slice(
6908
+ 0,
6909
+ Math.max(0, process.stdout.rows - Object.entries(statuses).length - 2)
6910
+ ).map(([_, evt], index) => {
6858
6911
  const readable = logicalIdToCdkPath(
6859
6912
  props.assembly,
6860
6913
  evt.StackName,
6861
6914
  evt.LogicalResourceId
6862
6915
  );
6863
6916
  return /* @__PURE__ */ React.createElement(Box, { key: index }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Spinner, null), " ", readable ? `${stackNameToId(evt.StackName)} ${readable} ${evt.ResourceType}` : `${stackNameToId(evt.StackName)} ${evt.ResourceType}`, " "), /* @__PURE__ */ React.createElement(Text, { color: color(evt.ResourceStatus || "") }, evt.ResourceStatus));
6864
- }), Object.entries(resources).length === 0 && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Spinner, null), " ", /* @__PURE__ */ React.createElement(Text, { dimColor: true }, props.remove ? "Removing..." : "Deploying..."))));
6917
+ }), Object.entries(resources).length === 0 && Object.entries(statuses).length === 0 && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Spinner, null), " ", /* @__PURE__ */ React.createElement(Text, { dimColor: true }, props.remove ? "Removing..." : "Deploying..."))));
6865
6918
  };
6866
6919
  }
6867
6920
  });
@@ -7926,10 +7979,7 @@ var MetadataOutdatedError = class extends Error {
7926
7979
  var bind = (program2) => program2.command(
7927
7980
  ["bind <command..>", "env <command..>"],
7928
7981
  "Bind your app's resources to a command",
7929
- (yargs2) => yargs2.option("site", {
7930
- type: "boolean",
7931
- describe: "Run in site mode"
7932
- }).option("script", {
7982
+ (yargs2) => yargs2.option("script", {
7933
7983
  type: "boolean",
7934
7984
  describe: "Run in script mode"
7935
7985
  }).array("command").example(`sst bind vitest run`, "Bind resources to your tests").example(`sst bind next dev`, "Bind resources to your site").example(
@@ -7937,13 +7987,30 @@ var bind = (program2) => program2.command(
7937
7987
  "Bind resources to your site before deployment"
7938
7988
  ),
7939
7989
  async (args) => {
7990
+ const { Token } = await import("aws-cdk-lib");
7940
7991
  const { spawn: spawn8 } = await import("child_process");
7941
7992
  const kill = await import("tree-kill");
7942
7993
  const { useProject: useProject2 } = await Promise.resolve().then(() => (init_project(), project_exports));
7994
+ const { Stacks } = await Promise.resolve().then(() => (init_stacks(), stacks_exports));
7943
7995
  const { useBus: useBus2 } = await Promise.resolve().then(() => (init_bus(), bus_exports));
7944
7996
  const { useIOT: useIOT2 } = await Promise.resolve().then(() => (init_iot(), iot_exports));
7945
7997
  const { Colors: Colors2 } = await Promise.resolve().then(() => (init_colors(), colors_exports));
7946
7998
  const { Logger: Logger3 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
7999
+ const [
8000
+ { useServices },
8001
+ { useSites: useSsrSites },
8002
+ { useSites: useStaticSites },
8003
+ { useSites: useSlsNextjsSites },
8004
+ { Parameter },
8005
+ { getEnvironmentKey }
8006
+ ] = await Promise.all([
8007
+ import("../src/constructs/Service.js"),
8008
+ import("../src/constructs/SsrSite.js"),
8009
+ import("../src/constructs/StaticSite.js"),
8010
+ import("../src/constructs/deprecated/NextjsSite.js"),
8011
+ import("../src/constructs/Config.js"),
8012
+ import("../src/constructs/util/functionBinding.js")
8013
+ ]);
7947
8014
  if (args._[0] === "env") {
7948
8015
  Colors2.line(
7949
8016
  Colors2.warning(
@@ -7953,102 +8020,95 @@ var bind = (program2) => program2.command(
7953
8020
  )
7954
8021
  );
7955
8022
  }
8023
+ const command = args.command?.join(" ");
8024
+ if (!command) {
8025
+ throw new VisibleError(
8026
+ "Command is required, e.g. sst bind npm run script"
8027
+ );
8028
+ }
7956
8029
  await useIOT2();
7957
8030
  const bus = useBus2();
7958
8031
  const project = useProject2();
7959
- const command = args.command?.join(" ");
7960
- const isSite = await isRunningInSite();
7961
- const mode = args.site ? "site" : args.script ? "script" : "auto";
7962
8032
  let p;
7963
8033
  let timer;
7964
8034
  let siteConfigCache;
7965
- if (!command) {
7966
- throw new VisibleError(
7967
- `Command is required, e.g. sst bind ${isSite ? "next dev" : "vitest run"}`
7968
- );
8035
+ await buildApp();
8036
+ const ssrSite = isInSsrSite();
8037
+ const staticSite = isInStaticSite();
8038
+ const service = isInService();
8039
+ if (args.script || !ssrSite && !staticSite && !service) {
8040
+ return await runScript();
7969
8041
  }
7970
- if (args.script || !isSite && !args.site) {
7971
- Logger3.debug("Running in script mode.");
7972
- return await bindScript();
8042
+ try {
8043
+ await runSite("init");
8044
+ } catch (e) {
8045
+ if (!(e instanceof MetadataOutdatedError) && !(e instanceof MetadataNotFoundError)) {
8046
+ return;
8047
+ }
8048
+ Colors2.line(
8049
+ Colors2.warning(
8050
+ e instanceof MetadataOutdatedError ? "Warning: This was deployed with an old version of SST. Run `sst dev` or `sst deploy` to update." : "Warning: The site has not been deployed. Some resources might not be available."
8051
+ )
8052
+ );
8053
+ return await runSiteUndeployed();
7973
8054
  }
7974
- await bindSite("init");
7975
8055
  bus.subscribe(
7976
8056
  "stacks.metadata.updated",
7977
- () => bindSite("metadata_updated")
8057
+ () => runSite("metadata_updated")
7978
8058
  );
7979
8059
  bus.subscribe(
7980
8060
  "stacks.metadata.deleted",
7981
- () => bindSite("metadata_updated")
8061
+ () => runSite("metadata_updated")
7982
8062
  );
7983
8063
  bus.subscribe("config.secret.updated", (payload) => {
7984
8064
  const secretName = payload.properties.name;
7985
- if (!(siteConfigCache?.secrets || []).includes(secretName))
8065
+ if (!siteConfigCache.secrets.includes(secretName))
7986
8066
  return;
7987
8067
  Colors2.line(
7988
8068
  `
7989
8069
  `,
7990
8070
  `SST secrets have been updated. Restarting \`${command}\`...`
7991
8071
  );
7992
- bindSite("secrets_updated");
8072
+ runSite("secrets_updated");
7993
8073
  });
7994
- async function isRunningInSite() {
7995
- const { existsAsync: existsAsync3 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
7996
- const { readFile } = await import("fs/promises");
7997
- const SITE_CONFIGS = [
7998
- { file: "next.config", multiExtension: true },
7999
- { file: "astro.config", multiExtension: true },
8000
- { file: "remix.config", multiExtension: true },
8001
- { file: "svelte.config", multiExtension: true },
8002
- { file: "gatsby-config", multiExtension: true },
8003
- { file: "angular.json" },
8004
- { file: "ember-cli-build.js" },
8005
- {
8006
- file: "vite.config",
8007
- multiExtension: true,
8008
- match: /solid-start|plugin-vue|plugin-react|@preact\/preset-vite/
8009
- },
8010
- { file: "package.json", match: /react-scripts/ },
8011
- // CRA
8012
- { file: "index.html" }
8013
- // plain HTML
8014
- ];
8015
- const results = await Promise.all(
8016
- SITE_CONFIGS.map((site) => {
8017
- const files = site.multiExtension ? [".js", ".cjs", ".mjs", ".ts"].map(
8018
- (ext) => `${site.file}${ext}`
8019
- ) : [site.file];
8020
- return files.map(async (file) => {
8021
- const exists = await existsAsync3(file);
8022
- if (!exists)
8023
- return false;
8024
- if (site.match) {
8025
- const content = await readFile(file);
8026
- return content.toString().match(site.match);
8027
- }
8028
- return true;
8029
- });
8030
- }).flat()
8074
+ async function buildApp() {
8075
+ const [_metafile, sstConfig] = await Stacks.load(
8076
+ project.paths.config
8031
8077
  );
8032
- return results.some(Boolean);
8078
+ const cwd = process.cwd();
8079
+ process.chdir(project.paths.root);
8080
+ await Stacks.synth({
8081
+ fn: sstConfig.stacks,
8082
+ mode: "remove"
8083
+ });
8084
+ process.chdir(cwd);
8033
8085
  }
8034
- async function bindSite(reason) {
8035
- let siteMetadata;
8036
- try {
8037
- siteMetadata = await getSiteMetadata();
8038
- } catch (e) {
8039
- if (!(e instanceof MetadataOutdatedError) && !(e instanceof MetadataNotFoundError)) {
8040
- throw e;
8041
- }
8042
- if (reason !== "init")
8043
- return;
8044
- Colors2.line(
8045
- Colors2.warning(
8046
- e instanceof MetadataOutdatedError ? "Warning: This was deployed with an old version of SST. Run `sst dev` or `sst deploy` to update." : "Warning: The site has not been deployed. Some resources might not be available."
8047
- )
8048
- );
8049
- return await bindScript();
8050
- }
8051
- const siteConfig = await parseSiteMetadata(siteMetadata);
8086
+ function isInSsrSite() {
8087
+ const cwd = process.cwd();
8088
+ return useSsrSites().all.find(({ props }) => {
8089
+ console.log(path20.resolve(project.paths.root, props.path));
8090
+ return path20.resolve(project.paths.root, props.path) === cwd;
8091
+ });
8092
+ }
8093
+ function isInStaticSite() {
8094
+ const cwd = process.cwd();
8095
+ return useStaticSites().all.find(({ props }) => {
8096
+ console.log(path20.resolve(project.paths.root, props.path));
8097
+ return path20.resolve(project.paths.root, props.path) === cwd;
8098
+ }) || useSlsNextjsSites().all.find(({ props }) => {
8099
+ console.log(path20.resolve(project.paths.root, props.path));
8100
+ return path20.resolve(project.paths.root, props.path) === cwd;
8101
+ });
8102
+ }
8103
+ function isInService() {
8104
+ const cwd = process.cwd();
8105
+ return useServices().all.find(({ props }) => {
8106
+ console.log(path20.resolve(project.paths.root, props.path));
8107
+ return path20.resolve(project.paths.root, props.path) === cwd;
8108
+ });
8109
+ }
8110
+ async function runSite(reason) {
8111
+ const siteConfig = ssrSite ? await getSsrSiteMetadata() : staticSite ? await getStaticSiteMetadata() : await getServiceMetadata();
8052
8112
  if (reason === "metadata_updated") {
8053
8113
  if (areEnvsSame(siteConfig.envs, siteConfigCache?.envs || {}))
8054
8114
  return;
@@ -8065,49 +8125,125 @@ var bind = (program2) => program2.command(
8065
8125
  ...credentials
8066
8126
  });
8067
8127
  }
8068
- async function bindScript() {
8128
+ async function runSiteUndeployed() {
8129
+ const constructEnvs = {};
8130
+ Object.entries(
8131
+ (ssrSite || staticSite || service)?.props.environment || {}
8132
+ ).filter(([key, value]) => !Token.isUnresolved(value)).forEach(([key, value]) => constructEnvs[key] = value);
8133
+ ((ssrSite || service)?.props.bind || []).forEach((b) => {
8134
+ if (b instanceof Parameter && !Token.isUnresolved(b.value)) {
8135
+ constructEnvs[getEnvironmentKey(b, "name")] = b.value;
8136
+ }
8137
+ });
8138
+ const { Config: Config2 } = await Promise.resolve().then(() => (init_config(), config_exports));
8139
+ await runCommand({
8140
+ ...constructEnvs,
8141
+ ...await Config2.env(),
8142
+ ...await getLocalIamCredentials()
8143
+ });
8144
+ }
8145
+ async function runScript() {
8069
8146
  const { Config: Config2 } = await Promise.resolve().then(() => (init_config(), config_exports));
8070
8147
  await runCommand({
8071
8148
  ...await Config2.env(),
8072
8149
  ...await getLocalIamCredentials()
8073
8150
  });
8074
8151
  }
8075
- async function getSiteMetadata() {
8076
- const { metadata: metadata3 } = await Promise.resolve().then(() => (init_metadata(), metadata_exports));
8077
- const metadataData = await metadata3();
8078
- const data2 = Object.values(metadataData).flat().filter(
8152
+ async function getSsrSiteMetadata() {
8153
+ const [
8154
+ { metadataForStack: metadataForStack2 },
8155
+ { LambdaClient: LambdaClient2, GetFunctionCommand },
8156
+ { useAWSClient: useAWSClient2 }
8157
+ ] = await Promise.all([
8158
+ Promise.resolve().then(() => (init_metadata(), metadata_exports)),
8159
+ import("@aws-sdk/client-lambda"),
8160
+ Promise.resolve().then(() => (init_credentials(), credentials_exports))
8161
+ ]);
8162
+ const metadataData = await metadataForStack2(ssrSite.stack);
8163
+ const metadata3 = metadataData.filter(
8079
8164
  (c) => [
8080
- "StaticSite",
8081
8165
  "NextjsSite",
8082
8166
  "AstroSite",
8083
8167
  "RemixSite",
8084
8168
  "SolidStartSite",
8085
- "SvelteKitSite",
8086
- "SlsNextjsSite"
8169
+ "SvelteKitSite"
8087
8170
  ].includes(c.type)
8088
8171
  ).find((c) => {
8089
- const isSsr = c.type !== "StaticSite" && c.type !== "SlsNextjsSite";
8090
- if (!c.data.path || isSsr && !c.data.server || !isSsr && !c.data.environment) {
8172
+ if (!c.data.path || !c.data.server) {
8091
8173
  throw new MetadataOutdatedError();
8092
8174
  }
8093
8175
  return path20.resolve(project.paths.root, c.data.path) === process.cwd();
8094
8176
  });
8095
- if (!data2) {
8177
+ if (!metadata3)
8096
8178
  throw new MetadataNotFoundError();
8097
- }
8098
- return data2;
8179
+ const lambda = useAWSClient2(LambdaClient2);
8180
+ const { Configuration: functionConfig } = await lambda.send(
8181
+ new GetFunctionCommand({
8182
+ FunctionName: metadata3.data.server
8183
+ })
8184
+ );
8185
+ return {
8186
+ role: functionConfig?.Role,
8187
+ envs: functionConfig?.Environment?.Variables || {},
8188
+ secrets: metadata3.data.secrets
8189
+ };
8099
8190
  }
8100
- async function parseSiteMetadata(metadata3) {
8101
- const { LambdaClient: LambdaClient2, GetFunctionCommand } = await import("@aws-sdk/client-lambda");
8102
- const { useAWSClient: useAWSClient2 } = await Promise.resolve().then(() => (init_credentials(), credentials_exports));
8103
- const isBindSupported = metadata3.type !== "StaticSite" && metadata3.type !== "SlsNextjsSite";
8104
- if (!isBindSupported) {
8105
- return { envs: metadata3.data.environment };
8191
+ async function getStaticSiteMetadata() {
8192
+ const { metadataForStack: metadataForStack2 } = await Promise.resolve().then(() => (init_metadata(), metadata_exports));
8193
+ const metadataData = await metadataForStack2(staticSite.stack);
8194
+ const metadata3 = metadataData.filter(
8195
+ (c) => ["StaticSite", "SlsNextjsSite"].includes(c.type)
8196
+ ).find((c) => {
8197
+ if (!c.data.path || !c.data.environment) {
8198
+ throw new MetadataOutdatedError();
8199
+ }
8200
+ return path20.resolve(project.paths.root, c.data.path) === process.cwd();
8201
+ });
8202
+ if (!metadata3)
8203
+ throw new MetadataNotFoundError();
8204
+ return {
8205
+ envs: metadata3.data.environment,
8206
+ role: void 0,
8207
+ secrets: []
8208
+ };
8209
+ }
8210
+ async function getServiceMetadata() {
8211
+ const [
8212
+ { metadataForStack: metadataForStack2 },
8213
+ { LambdaClient: LambdaClient2, GetFunctionCommand },
8214
+ { ECSClient, DescribeTaskDefinitionCommand },
8215
+ { useAWSClient: useAWSClient2 }
8216
+ ] = await Promise.all([
8217
+ Promise.resolve().then(() => (init_metadata(), metadata_exports)),
8218
+ import("@aws-sdk/client-lambda"),
8219
+ import("@aws-sdk/client-ecs"),
8220
+ Promise.resolve().then(() => (init_credentials(), credentials_exports))
8221
+ ]);
8222
+ const metadataData = await metadataForStack2(service.stack);
8223
+ const metadata3 = metadataData.filter((c) => ["Service"].includes(c.type)).find((c) => {
8224
+ return path20.resolve(project.paths.root, c.data.path) === process.cwd();
8225
+ });
8226
+ if (!metadata3)
8227
+ throw new MetadataNotFoundError();
8228
+ if (metadata3.data.mode === "deployed") {
8229
+ const ecs = useAWSClient2(ECSClient);
8230
+ const task = await ecs.send(
8231
+ new DescribeTaskDefinitionCommand({
8232
+ taskDefinition: metadata3.data.task
8233
+ })
8234
+ );
8235
+ const envs = {};
8236
+ (task?.taskDefinition?.containerDefinitions[0].environment || []).forEach(({ name, value }) => envs[name] = value);
8237
+ return {
8238
+ role: task?.taskDefinition?.taskRoleArn,
8239
+ envs,
8240
+ secrets: metadata3.data.secrets
8241
+ };
8106
8242
  }
8107
8243
  const lambda = useAWSClient2(LambdaClient2);
8108
8244
  const { Configuration: functionConfig } = await lambda.send(
8109
8245
  new GetFunctionCommand({
8110
- FunctionName: metadata3.data.server
8246
+ FunctionName: metadata3.data.devFunction
8111
8247
  })
8112
8248
  );
8113
8249
  return {
@@ -8128,7 +8264,7 @@ var bind = (program2) => program2.command(
8128
8264
  `,
8129
8265
  `Your AWS session is about to expire. Creating a new session and restarting \`${command}\`...`
8130
8266
  );
8131
- bindSite("iam_expired");
8267
+ runSite("iam_expired");
8132
8268
  }, expireAt - Date.now());
8133
8269
  return {
8134
8270
  AWS_ACCESS_KEY_ID: credentials.AccessKeyId,
package/stacks/deploy.js CHANGED
@@ -84,6 +84,10 @@ export async function deploy(stack) {
84
84
  }));
85
85
  try {
86
86
  await addInUseExports(stack);
87
+ bus.publish("stack.status", {
88
+ stackID: stack.stackName,
89
+ status: "PUBLISH_ASSETS_IN_PROGRESS",
90
+ });
87
91
  const result = await deployment.deployStack({
88
92
  stack: stack,
89
93
  quiet: true,
@@ -6,5 +6,6 @@ declare module "../bus.js" {
6
6
  "stacks.metadata.deleted": {};
7
7
  }
8
8
  }
9
+ export declare function metadataForStack(stack: String): Promise<Metadata[]>;
9
10
  export declare function metadata(): Promise<Record<string, Metadata[]>>;
10
11
  export declare const useMetadata: () => Promise<Record<string, Metadata[]>>;
@@ -6,6 +6,23 @@ import { Context } from "../context/context.js";
6
6
  import { useBus } from "../bus.js";
7
7
  import { Logger } from "../logger.js";
8
8
  import { useProject } from "../project.js";
9
+ export async function metadataForStack(stack) {
10
+ const project = useProject();
11
+ const [credentials, bootstrap] = await Promise.all([
12
+ useAWSCredentials(),
13
+ useBootstrap(),
14
+ ]);
15
+ const s3 = new S3Client({
16
+ region: project.config.region,
17
+ credentials: credentials,
18
+ });
19
+ const result = await s3.send(new GetObjectCommand({
20
+ Key: `stackMetadata/app.${project.config.name}/stage.${project.config.stage}/stack.${stack}.json`,
21
+ Bucket: bootstrap.bucket,
22
+ }));
23
+ const body = await result.Body.transformToString();
24
+ return JSON.parse(body);
25
+ }
9
26
  export async function metadata() {
10
27
  Logger.debug("Fetching all metadata");
11
28
  const project = useProject();
@@ -18,7 +18,7 @@ declare module "../bus.js" {
18
18
  };
19
19
  }
20
20
  }
21
- export declare const STATUSES: readonly ["CREATE_IN_PROGRESS", "DELETE_IN_PROGRESS", "REVIEW_IN_PROGRESS", "ROLLBACK_IN_PROGRESS", "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", "UPDATE_IN_PROGRESS", "UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS", "UPDATE_ROLLBACK_IN_PROGRESS", "CREATE_COMPLETE", "UPDATE_COMPLETE", "DELETE_COMPLETE", "SKIPPED", "CREATE_FAILED", "DELETE_FAILED", "ROLLBACK_FAILED", "ROLLBACK_COMPLETE", "UPDATE_FAILED", "UPDATE_ROLLBACK_COMPLETE", "UPDATE_ROLLBACK_FAILED", "DEPENDENCY_FAILED"];
21
+ export declare const STATUSES: readonly ["CREATE_IN_PROGRESS", "DELETE_IN_PROGRESS", "REVIEW_IN_PROGRESS", "ROLLBACK_IN_PROGRESS", "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", "UPDATE_IN_PROGRESS", "UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS", "UPDATE_ROLLBACK_IN_PROGRESS", "PUBLISH_ASSETS_IN_PROGRESS", "CREATE_COMPLETE", "UPDATE_COMPLETE", "DELETE_COMPLETE", "SKIPPED", "CREATE_FAILED", "DELETE_FAILED", "ROLLBACK_FAILED", "ROLLBACK_COMPLETE", "UPDATE_FAILED", "UPDATE_ROLLBACK_COMPLETE", "UPDATE_ROLLBACK_FAILED", "DEPENDENCY_FAILED"];
22
22
  export declare function isFinal(input: string): boolean;
23
23
  export declare function isFailed(input: string): boolean;
24
24
  export declare function isSuccess(input: string): boolean;
package/stacks/monitor.js CHANGED
@@ -11,6 +11,7 @@ const STATUSES_PENDING = [
11
11
  "UPDATE_IN_PROGRESS",
12
12
  "UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS",
13
13
  "UPDATE_ROLLBACK_IN_PROGRESS",
14
+ "PUBLISH_ASSETS_IN_PROGRESS",
14
15
  ];
15
16
  const STATUSES_SUCCESS = [
16
17
  "CREATE_COMPLETE",
@@ -0,0 +1,6 @@
1
+ FROM debian:bookworm-slim
2
+ RUN apt-get update && apt-get install -y curl
3
+ RUN curl -LO https://github.com/railwayapp/nixpacks/releases/download/v1.11.0/nixpacks-v1.11.0-amd64.deb
4
+ RUN dpkg -i nixpacks-v1.11.0-amd64.deb
5
+
6
+ ENTRYPOINT ["nixpacks"]
@@ -0,0 +1 @@
1
+ export async function handler() {}