sst 2.22.11 → 2.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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();
@@ -5798,6 +5816,7 @@ __export(stacks_exports, {
5798
5816
  load: () => load,
5799
5817
  loadAssembly: () => loadAssembly,
5800
5818
  metadata: () => metadata2,
5819
+ metadataForStack: () => metadataForStack,
5801
5820
  monitor: () => monitor,
5802
5821
  publishAssets: () => publishAssets4,
5803
5822
  remove: () => remove,
@@ -5869,16 +5888,26 @@ async function loadCDKStatus() {
5869
5888
  );
5870
5889
  if (!stacks || stacks.length === 0)
5871
5890
  return { status: "bootstrap" };
5872
- if (!["CREATE_COMPLETE", "UPDATE_COMPLETE"].includes(stacks[0].StackStatus)) {
5891
+ if (![
5892
+ "CREATE_COMPLETE",
5893
+ "UPDATE_COMPLETE",
5894
+ "UPDATE_ROLLBACK_COMPLETE"
5895
+ ].includes(stacks[0].StackStatus)) {
5873
5896
  return { status: "bootstrap" };
5874
5897
  }
5875
- const output = stacks[0].Outputs?.find(
5876
- (o) => o.OutputKey === "BootstrapVersion"
5877
- );
5878
- if (!output || parseInt(output.OutputValue) < 14) {
5898
+ let version2;
5899
+ let bucket;
5900
+ const output = stacks[0].Outputs?.forEach((o) => {
5901
+ if (o.OutputKey === "BootstrapVersion") {
5902
+ version2 = parseInt(o.OutputValue);
5903
+ } else if (o.OutputKey === "BucketName") {
5904
+ bucket = o.OutputValue;
5905
+ }
5906
+ });
5907
+ if (!version2 || version2 < 14 || !bucket) {
5879
5908
  return { status: "update" };
5880
5909
  }
5881
- return { status: "ready" };
5910
+ return { status: "ready", version: version2, bucket };
5882
5911
  } catch (e) {
5883
5912
  if (e.name === "ValidationError" && e.message === `Stack with id ${stackName} does not exist`) {
5884
5913
  return { status: "bootstrap" };
@@ -5927,7 +5956,7 @@ async function loadSSTStatus() {
5927
5956
  }
5928
5957
  return { status: "ready", version: version2, bucket };
5929
5958
  }
5930
- async function bootstrapSST() {
5959
+ async function bootstrapSST(cdkBucket) {
5931
5960
  const { region, bootstrap: bootstrap2, cdk } = useProject().config;
5932
5961
  const app = new App();
5933
5962
  const stackName = bootstrap2?.stackName || SST_STACK_NAME;
@@ -5948,7 +5977,10 @@ async function bootstrapSST() {
5948
5977
  for (const [key, value] of Object.entries(bootstrap2?.tags || {})) {
5949
5978
  Tags.of(app).add(key, value);
5950
5979
  }
5951
- const bucket = new Bucket(stack, region, {
5980
+ const bucket = bootstrap2?.useCdkBucket ? {
5981
+ bucketName: cdkBucket,
5982
+ bucketArn: `arn:${stack.partition}:s3:::${cdkBucket}`
5983
+ } : new Bucket(stack, region, {
5952
5984
  encryption: BucketEncryption.S3_MANAGED,
5953
5985
  removalPolicy: RemovalPolicy.DESTROY,
5954
5986
  autoDeleteObjects: true,
@@ -6111,9 +6143,12 @@ var init_bootstrap = __esm({
6111
6143
  ).start();
6112
6144
  if (needToBootstrapCDK) {
6113
6145
  await bootstrapCDK();
6146
+ cdkStatus = await loadCDKStatus();
6147
+ if (cdkStatus.status !== "ready")
6148
+ throw new VisibleError("Failed to load bootstrap stack status");
6114
6149
  }
6115
6150
  if (needToBootstrapSST) {
6116
- await bootstrapSST();
6151
+ await bootstrapSST(cdkStatus.bucket);
6117
6152
  sstStatus = await loadSSTStatus();
6118
6153
  if (sstStatus.status !== "ready")
6119
6154
  throw new VisibleError("Failed to load bootstrap stack status");
@@ -6814,10 +6849,32 @@ var init_deploy2 = __esm({
6814
6849
  init_colors();
6815
6850
  init_project();
6816
6851
  DeploymentUI = (props) => {
6852
+ const [statuses, setStatuses] = useState({});
6817
6853
  const [resources, setResources] = useState({});
6818
6854
  useEffect(() => {
6819
6855
  Colors.gap();
6820
6856
  const bus = useBus();
6857
+ const status = bus.subscribe("stack.status", (payload) => {
6858
+ const { stackID, status: status2 } = payload.properties;
6859
+ setStatuses((previous2) => {
6860
+ if (status2 !== "PUBLISH_ASSETS_IN_PROGRESS") {
6861
+ if (previous2[stackID]) {
6862
+ Colors.line(
6863
+ Colors.warning(Colors.prefix),
6864
+ Colors.dim(stackNameToId(stackID)),
6865
+ Colors.dim("PUBLISH_ASSETS_COMPLETE"),
6866
+ ""
6867
+ );
6868
+ }
6869
+ const { [stackID]: _, ...next } = previous2;
6870
+ return next;
6871
+ }
6872
+ return {
6873
+ ...previous2,
6874
+ [stackID]: status2
6875
+ };
6876
+ });
6877
+ });
6821
6878
  const event = bus.subscribe("stack.event", (payload) => {
6822
6879
  const { event: event2 } = payload.properties;
6823
6880
  setResources((previous2) => {
@@ -6848,6 +6905,7 @@ var init_deploy2 = __esm({
6848
6905
  });
6849
6906
  return () => {
6850
6907
  bus.unsubscribe(event);
6908
+ bus.unsubscribe(status);
6851
6909
  };
6852
6910
  }, []);
6853
6911
  function color(status) {
@@ -6857,14 +6915,19 @@ var init_deploy2 = __esm({
6857
6915
  return "green";
6858
6916
  return "yellow";
6859
6917
  }
6860
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, Object.entries(resources).slice(0, process.stdout.rows - 2).map(([_, evt], index) => {
6918
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, Object.entries(statuses).slice(0, process.stdout.rows - 2).map(([stack, status], index) => {
6919
+ 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));
6920
+ }), Object.entries(resources).slice(
6921
+ 0,
6922
+ Math.max(0, process.stdout.rows - Object.entries(statuses).length - 2)
6923
+ ).map(([_, evt], index) => {
6861
6924
  const readable = logicalIdToCdkPath(
6862
6925
  props.assembly,
6863
6926
  evt.StackName,
6864
6927
  evt.LogicalResourceId
6865
6928
  );
6866
6929
  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));
6867
- }), 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..."))));
6930
+ }), 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..."))));
6868
6931
  };
6869
6932
  }
6870
6933
  });
@@ -7929,10 +7992,7 @@ var MetadataOutdatedError = class extends Error {
7929
7992
  var bind = (program2) => program2.command(
7930
7993
  ["bind <command..>", "env <command..>"],
7931
7994
  "Bind your app's resources to a command",
7932
- (yargs2) => yargs2.option("site", {
7933
- type: "boolean",
7934
- describe: "Run in site mode"
7935
- }).option("script", {
7995
+ (yargs2) => yargs2.option("script", {
7936
7996
  type: "boolean",
7937
7997
  describe: "Run in script mode"
7938
7998
  }).array("command").example(`sst bind vitest run`, "Bind resources to your tests").example(`sst bind next dev`, "Bind resources to your site").example(
@@ -7940,13 +8000,30 @@ var bind = (program2) => program2.command(
7940
8000
  "Bind resources to your site before deployment"
7941
8001
  ),
7942
8002
  async (args) => {
8003
+ const { Token } = await import("aws-cdk-lib");
7943
8004
  const { spawn: spawn8 } = await import("child_process");
7944
8005
  const kill = await import("tree-kill");
7945
8006
  const { useProject: useProject2 } = await Promise.resolve().then(() => (init_project(), project_exports));
8007
+ const { Stacks } = await Promise.resolve().then(() => (init_stacks(), stacks_exports));
7946
8008
  const { useBus: useBus2 } = await Promise.resolve().then(() => (init_bus(), bus_exports));
7947
8009
  const { useIOT: useIOT2 } = await Promise.resolve().then(() => (init_iot(), iot_exports));
7948
8010
  const { Colors: Colors2 } = await Promise.resolve().then(() => (init_colors(), colors_exports));
7949
8011
  const { Logger: Logger3 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
8012
+ const [
8013
+ { useServices },
8014
+ { useSites: useSsrSites },
8015
+ { useSites: useStaticSites },
8016
+ { useSites: useSlsNextjsSites },
8017
+ { Parameter },
8018
+ { getEnvironmentKey }
8019
+ ] = await Promise.all([
8020
+ import("../src/constructs/Service.js"),
8021
+ import("../src/constructs/SsrSite.js"),
8022
+ import("../src/constructs/StaticSite.js"),
8023
+ import("../src/constructs/deprecated/NextjsSite.js"),
8024
+ import("../src/constructs/Config.js"),
8025
+ import("../src/constructs/util/functionBinding.js")
8026
+ ]);
7950
8027
  if (args._[0] === "env") {
7951
8028
  Colors2.line(
7952
8029
  Colors2.warning(
@@ -7956,102 +8033,95 @@ var bind = (program2) => program2.command(
7956
8033
  )
7957
8034
  );
7958
8035
  }
8036
+ const command = args.command?.join(" ");
8037
+ if (!command) {
8038
+ throw new VisibleError(
8039
+ "Command is required, e.g. sst bind npm run script"
8040
+ );
8041
+ }
7959
8042
  await useIOT2();
7960
8043
  const bus = useBus2();
7961
8044
  const project = useProject2();
7962
- const command = args.command?.join(" ");
7963
- const isSite = await isRunningInSite();
7964
- const mode = args.site ? "site" : args.script ? "script" : "auto";
7965
8045
  let p;
7966
8046
  let timer;
7967
8047
  let siteConfigCache;
7968
- if (!command) {
7969
- throw new VisibleError(
7970
- `Command is required, e.g. sst bind ${isSite ? "next dev" : "vitest run"}`
7971
- );
8048
+ await buildApp();
8049
+ const ssrSite = isInSsrSite();
8050
+ const staticSite = isInStaticSite();
8051
+ const service = isInService();
8052
+ if (args.script || !ssrSite && !staticSite && !service) {
8053
+ return await runScript();
7972
8054
  }
7973
- if (args.script || !isSite && !args.site) {
7974
- Logger3.debug("Running in script mode.");
7975
- return await bindScript();
8055
+ try {
8056
+ await runSite("init");
8057
+ } catch (e) {
8058
+ if (!(e instanceof MetadataOutdatedError) && !(e instanceof MetadataNotFoundError)) {
8059
+ return;
8060
+ }
8061
+ Colors2.line(
8062
+ Colors2.warning(
8063
+ 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."
8064
+ )
8065
+ );
8066
+ return await runSiteUndeployed();
7976
8067
  }
7977
- await bindSite("init");
7978
8068
  bus.subscribe(
7979
8069
  "stacks.metadata.updated",
7980
- () => bindSite("metadata_updated")
8070
+ () => runSite("metadata_updated")
7981
8071
  );
7982
8072
  bus.subscribe(
7983
8073
  "stacks.metadata.deleted",
7984
- () => bindSite("metadata_updated")
8074
+ () => runSite("metadata_updated")
7985
8075
  );
7986
8076
  bus.subscribe("config.secret.updated", (payload) => {
7987
8077
  const secretName = payload.properties.name;
7988
- if (!(siteConfigCache?.secrets || []).includes(secretName))
8078
+ if (!siteConfigCache.secrets.includes(secretName))
7989
8079
  return;
7990
8080
  Colors2.line(
7991
8081
  `
7992
8082
  `,
7993
8083
  `SST secrets have been updated. Restarting \`${command}\`...`
7994
8084
  );
7995
- bindSite("secrets_updated");
8085
+ runSite("secrets_updated");
7996
8086
  });
7997
- async function isRunningInSite() {
7998
- const { existsAsync: existsAsync3 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
7999
- const { readFile } = await import("fs/promises");
8000
- const SITE_CONFIGS = [
8001
- { file: "next.config", multiExtension: true },
8002
- { file: "astro.config", multiExtension: true },
8003
- { file: "remix.config", multiExtension: true },
8004
- { file: "svelte.config", multiExtension: true },
8005
- { file: "gatsby-config", multiExtension: true },
8006
- { file: "angular.json" },
8007
- { file: "ember-cli-build.js" },
8008
- {
8009
- file: "vite.config",
8010
- multiExtension: true,
8011
- match: /solid-start|plugin-vue|plugin-react|@preact\/preset-vite/
8012
- },
8013
- { file: "package.json", match: /react-scripts/ },
8014
- // CRA
8015
- { file: "index.html" }
8016
- // plain HTML
8017
- ];
8018
- const results = await Promise.all(
8019
- SITE_CONFIGS.map((site) => {
8020
- const files = site.multiExtension ? [".js", ".cjs", ".mjs", ".ts"].map(
8021
- (ext) => `${site.file}${ext}`
8022
- ) : [site.file];
8023
- return files.map(async (file) => {
8024
- const exists = await existsAsync3(file);
8025
- if (!exists)
8026
- return false;
8027
- if (site.match) {
8028
- const content = await readFile(file);
8029
- return content.toString().match(site.match);
8030
- }
8031
- return true;
8032
- });
8033
- }).flat()
8087
+ async function buildApp() {
8088
+ const [_metafile, sstConfig] = await Stacks.load(
8089
+ project.paths.config
8034
8090
  );
8035
- return results.some(Boolean);
8091
+ const cwd = process.cwd();
8092
+ process.chdir(project.paths.root);
8093
+ await Stacks.synth({
8094
+ fn: sstConfig.stacks,
8095
+ mode: "remove"
8096
+ });
8097
+ process.chdir(cwd);
8036
8098
  }
8037
- async function bindSite(reason) {
8038
- let siteMetadata;
8039
- try {
8040
- siteMetadata = await getSiteMetadata();
8041
- } catch (e) {
8042
- if (!(e instanceof MetadataOutdatedError) && !(e instanceof MetadataNotFoundError)) {
8043
- throw e;
8044
- }
8045
- if (reason !== "init")
8046
- return;
8047
- Colors2.line(
8048
- Colors2.warning(
8049
- 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."
8050
- )
8051
- );
8052
- return await bindScript();
8053
- }
8054
- const siteConfig = await parseSiteMetadata(siteMetadata);
8099
+ function isInSsrSite() {
8100
+ const cwd = process.cwd();
8101
+ return useSsrSites().all.find(({ props }) => {
8102
+ console.log(path20.resolve(project.paths.root, props.path));
8103
+ return path20.resolve(project.paths.root, props.path) === cwd;
8104
+ });
8105
+ }
8106
+ function isInStaticSite() {
8107
+ const cwd = process.cwd();
8108
+ return useStaticSites().all.find(({ props }) => {
8109
+ console.log(path20.resolve(project.paths.root, props.path));
8110
+ return path20.resolve(project.paths.root, props.path) === cwd;
8111
+ }) || useSlsNextjsSites().all.find(({ props }) => {
8112
+ console.log(path20.resolve(project.paths.root, props.path));
8113
+ return path20.resolve(project.paths.root, props.path) === cwd;
8114
+ });
8115
+ }
8116
+ function isInService() {
8117
+ const cwd = process.cwd();
8118
+ return useServices().all.find(({ props }) => {
8119
+ console.log(path20.resolve(project.paths.root, props.path));
8120
+ return path20.resolve(project.paths.root, props.path) === cwd;
8121
+ });
8122
+ }
8123
+ async function runSite(reason) {
8124
+ const siteConfig = ssrSite ? await getSsrSiteMetadata() : staticSite ? await getStaticSiteMetadata() : await getServiceMetadata();
8055
8125
  if (reason === "metadata_updated") {
8056
8126
  if (areEnvsSame(siteConfig.envs, siteConfigCache?.envs || {}))
8057
8127
  return;
@@ -8068,49 +8138,125 @@ var bind = (program2) => program2.command(
8068
8138
  ...credentials
8069
8139
  });
8070
8140
  }
8071
- async function bindScript() {
8141
+ async function runSiteUndeployed() {
8142
+ const constructEnvs = {};
8143
+ Object.entries(
8144
+ (ssrSite || staticSite || service)?.props.environment || {}
8145
+ ).filter(([key, value]) => !Token.isUnresolved(value)).forEach(([key, value]) => constructEnvs[key] = value);
8146
+ ((ssrSite || service)?.props.bind || []).forEach((b) => {
8147
+ if (b instanceof Parameter && !Token.isUnresolved(b.value)) {
8148
+ constructEnvs[getEnvironmentKey(b, "name")] = b.value;
8149
+ }
8150
+ });
8072
8151
  const { Config: Config2 } = await Promise.resolve().then(() => (init_config(), config_exports));
8073
8152
  await runCommand({
8153
+ ...constructEnvs,
8074
8154
  ...await Config2.env(),
8075
8155
  ...await getLocalIamCredentials()
8076
8156
  });
8077
8157
  }
8078
- async function getSiteMetadata() {
8079
- const { metadata: metadata3 } = await Promise.resolve().then(() => (init_metadata(), metadata_exports));
8080
- const metadataData = await metadata3();
8081
- const data2 = Object.values(metadataData).flat().filter(
8158
+ async function runScript() {
8159
+ const { Config: Config2 } = await Promise.resolve().then(() => (init_config(), config_exports));
8160
+ await runCommand({
8161
+ ...await Config2.env(),
8162
+ ...await getLocalIamCredentials()
8163
+ });
8164
+ }
8165
+ async function getSsrSiteMetadata() {
8166
+ const [
8167
+ { metadataForStack: metadataForStack2 },
8168
+ { LambdaClient: LambdaClient2, GetFunctionCommand },
8169
+ { useAWSClient: useAWSClient2 }
8170
+ ] = await Promise.all([
8171
+ Promise.resolve().then(() => (init_metadata(), metadata_exports)),
8172
+ import("@aws-sdk/client-lambda"),
8173
+ Promise.resolve().then(() => (init_credentials(), credentials_exports))
8174
+ ]);
8175
+ const metadataData = await metadataForStack2(ssrSite.stack);
8176
+ const metadata3 = metadataData.filter(
8082
8177
  (c) => [
8083
- "StaticSite",
8084
8178
  "NextjsSite",
8085
8179
  "AstroSite",
8086
8180
  "RemixSite",
8087
8181
  "SolidStartSite",
8088
- "SvelteKitSite",
8089
- "SlsNextjsSite"
8182
+ "SvelteKitSite"
8090
8183
  ].includes(c.type)
8091
8184
  ).find((c) => {
8092
- const isSsr = c.type !== "StaticSite" && c.type !== "SlsNextjsSite";
8093
- if (!c.data.path || isSsr && !c.data.server || !isSsr && !c.data.environment) {
8185
+ if (!c.data.path || !c.data.server) {
8094
8186
  throw new MetadataOutdatedError();
8095
8187
  }
8096
8188
  return path20.resolve(project.paths.root, c.data.path) === process.cwd();
8097
8189
  });
8098
- if (!data2) {
8190
+ if (!metadata3)
8099
8191
  throw new MetadataNotFoundError();
8100
- }
8101
- return data2;
8192
+ const lambda = useAWSClient2(LambdaClient2);
8193
+ const { Configuration: functionConfig } = await lambda.send(
8194
+ new GetFunctionCommand({
8195
+ FunctionName: metadata3.data.server
8196
+ })
8197
+ );
8198
+ return {
8199
+ role: functionConfig?.Role,
8200
+ envs: functionConfig?.Environment?.Variables || {},
8201
+ secrets: metadata3.data.secrets
8202
+ };
8102
8203
  }
8103
- async function parseSiteMetadata(metadata3) {
8104
- const { LambdaClient: LambdaClient2, GetFunctionCommand } = await import("@aws-sdk/client-lambda");
8105
- const { useAWSClient: useAWSClient2 } = await Promise.resolve().then(() => (init_credentials(), credentials_exports));
8106
- const isBindSupported = metadata3.type !== "StaticSite" && metadata3.type !== "SlsNextjsSite";
8107
- if (!isBindSupported) {
8108
- return { envs: metadata3.data.environment };
8204
+ async function getStaticSiteMetadata() {
8205
+ const { metadataForStack: metadataForStack2 } = await Promise.resolve().then(() => (init_metadata(), metadata_exports));
8206
+ const metadataData = await metadataForStack2(staticSite.stack);
8207
+ const metadata3 = metadataData.filter(
8208
+ (c) => ["StaticSite", "SlsNextjsSite"].includes(c.type)
8209
+ ).find((c) => {
8210
+ if (!c.data.path || !c.data.environment) {
8211
+ throw new MetadataOutdatedError();
8212
+ }
8213
+ return path20.resolve(project.paths.root, c.data.path) === process.cwd();
8214
+ });
8215
+ if (!metadata3)
8216
+ throw new MetadataNotFoundError();
8217
+ return {
8218
+ envs: metadata3.data.environment,
8219
+ role: void 0,
8220
+ secrets: []
8221
+ };
8222
+ }
8223
+ async function getServiceMetadata() {
8224
+ const [
8225
+ { metadataForStack: metadataForStack2 },
8226
+ { LambdaClient: LambdaClient2, GetFunctionCommand },
8227
+ { ECSClient, DescribeTaskDefinitionCommand },
8228
+ { useAWSClient: useAWSClient2 }
8229
+ ] = await Promise.all([
8230
+ Promise.resolve().then(() => (init_metadata(), metadata_exports)),
8231
+ import("@aws-sdk/client-lambda"),
8232
+ import("@aws-sdk/client-ecs"),
8233
+ Promise.resolve().then(() => (init_credentials(), credentials_exports))
8234
+ ]);
8235
+ const metadataData = await metadataForStack2(service.stack);
8236
+ const metadata3 = metadataData.filter((c) => ["Service"].includes(c.type)).find((c) => {
8237
+ return path20.resolve(project.paths.root, c.data.path) === process.cwd();
8238
+ });
8239
+ if (!metadata3)
8240
+ throw new MetadataNotFoundError();
8241
+ if (metadata3.data.mode === "deployed") {
8242
+ const ecs = useAWSClient2(ECSClient);
8243
+ const task = await ecs.send(
8244
+ new DescribeTaskDefinitionCommand({
8245
+ taskDefinition: metadata3.data.task
8246
+ })
8247
+ );
8248
+ const envs = {};
8249
+ (task?.taskDefinition?.containerDefinitions[0].environment || []).forEach(({ name, value }) => envs[name] = value);
8250
+ return {
8251
+ role: task?.taskDefinition?.taskRoleArn,
8252
+ envs,
8253
+ secrets: metadata3.data.secrets
8254
+ };
8109
8255
  }
8110
8256
  const lambda = useAWSClient2(LambdaClient2);
8111
8257
  const { Configuration: functionConfig } = await lambda.send(
8112
8258
  new GetFunctionCommand({
8113
- FunctionName: metadata3.data.server
8259
+ FunctionName: metadata3.data.devFunction
8114
8260
  })
8115
8261
  );
8116
8262
  return {
@@ -8131,7 +8277,7 @@ var bind = (program2) => program2.command(
8131
8277
  `,
8132
8278
  `Your AWS session is about to expire. Creating a new session and restarting \`${command}\`...`
8133
8279
  );
8134
- bindSite("iam_expired");
8280
+ runSite("iam_expired");
8135
8281
  }, expireAt - Date.now());
8136
8282
  return {
8137
8283
  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() {}