@stacksjs/ts-cloud 0.7.61 → 0.7.63

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 (58) hide show
  1. package/dist/bin/cli.js +305 -305
  2. package/dist/{chunk-pbh6b828.js → chunk-0zbqbrqg.js} +20 -6
  3. package/dist/{chunk-c82m4yzn.js → chunk-t092y37p.js} +1 -1
  4. package/dist/deploy/index.js +2 -2
  5. package/dist/drivers/index.js +1 -1
  6. package/dist/drivers/shared/releases.d.ts +22 -0
  7. package/dist/index.js +2 -2
  8. package/dist/ui/access-denied.html +2 -2
  9. package/dist/ui/account/automation.html +4 -4
  10. package/dist/ui/account/security.html +2 -2
  11. package/dist/ui/applications/compose.html +4 -4
  12. package/dist/ui/applications/new.html +2 -2
  13. package/dist/ui/data/backups.html +4 -4
  14. package/dist/ui/data/services.html +4 -4
  15. package/dist/ui/data/volumes.html +4 -4
  16. package/dist/ui/index.html +4 -4
  17. package/dist/ui/integrations.html +2 -2
  18. package/dist/ui/operations/alerts.html +4 -4
  19. package/dist/ui/operations/configuration.html +4 -4
  20. package/dist/ui/operations/jobs.html +4 -4
  21. package/dist/ui/operations/maintenance.html +3 -3
  22. package/dist/ui/operations/observability.html +4 -4
  23. package/dist/ui/operations/previews.html +4 -4
  24. package/dist/ui/operations/queue.html +4 -4
  25. package/dist/ui/operations/regions.html +4 -4
  26. package/dist/ui/operations/releases.html +4 -4
  27. package/dist/ui/operations/workloads.html +4 -4
  28. package/dist/ui/security.html +2 -2
  29. package/dist/ui/server/actions.html +4 -4
  30. package/dist/ui/server/activity.html +2 -2
  31. package/dist/ui/server/capacity.html +4 -4
  32. package/dist/ui/server/database.html +4 -4
  33. package/dist/ui/server/deployments.html +4 -4
  34. package/dist/ui/server/diagnostics.html +2 -2
  35. package/dist/ui/server/firewall.html +4 -4
  36. package/dist/ui/server/fleet.html +4 -4
  37. package/dist/ui/server/logs.html +4 -4
  38. package/dist/ui/server/metrics.html +2 -2
  39. package/dist/ui/server/security.html +2 -2
  40. package/dist/ui/server/services.html +2 -2
  41. package/dist/ui/server/sites.html +4 -4
  42. package/dist/ui/server/ssh-keys.html +4 -4
  43. package/dist/ui/server/team.html +4 -4
  44. package/dist/ui/server/terminal.html +2 -2
  45. package/dist/ui/serverless/alarms.html +4 -4
  46. package/dist/ui/serverless/assets.html +2 -2
  47. package/dist/ui/serverless/cost.html +2 -2
  48. package/dist/ui/serverless/data.html +4 -4
  49. package/dist/ui/serverless/deployments.html +2 -2
  50. package/dist/ui/serverless/firewall.html +2 -2
  51. package/dist/ui/serverless/functions.html +4 -4
  52. package/dist/ui/serverless/logs.html +4 -4
  53. package/dist/ui/serverless/metrics.html +2 -2
  54. package/dist/ui/serverless/queues.html +4 -4
  55. package/dist/ui/serverless/secrets.html +4 -4
  56. package/dist/ui/serverless/traces.html +4 -4
  57. package/dist/ui/serverless.html +4 -4
  58. package/package.json +3 -3
@@ -3821,7 +3821,8 @@ function buildResetReleaseDir(paths) {
3821
3821
  return [
3822
3822
  `rm -rf ${staging}`,
3823
3823
  `mkdir -p ${staging}`,
3824
- `if [ "$(readlink -f ${paths.current} 2>/dev/null || true)" = "${paths.release}" ]; then`,
3824
+ ...buildIsReleaseLive(paths),
3825
+ 'if [ "$TS_CLOUD_IS_LIVE" = "yes" ]; then',
3825
3826
  ` TS_CLOUD_STAGED=${staging}`,
3826
3827
  "else",
3827
3828
  ` rm -rf ${paths.release}`,
@@ -3831,13 +3832,26 @@ function buildResetReleaseDir(paths) {
3831
3832
  "fi"
3832
3833
  ];
3833
3834
  }
3835
+ function buildStrandedReleaseTrap(paths) {
3836
+ const live = `TS_CLOUD_TRAP_LIVE="$(readlink -f ${paths.current} 2>/dev/null || true)"`;
3837
+ const target = `TS_CLOUD_TRAP_TARGET="$(readlink -f ${paths.release} 2>/dev/null || echo ${paths.release})"`;
3838
+ const body = `if [ $? -ne 0 ]; then ${live}; ${target}; [ "$TS_CLOUD_TRAP_LIVE" = "$TS_CLOUD_TRAP_TARGET" ] || rm -rf ${paths.release}; fi`;
3839
+ return `trap '${body}' EXIT`;
3840
+ }
3841
+ function buildIsReleaseLive(paths) {
3842
+ return [
3843
+ `TS_CLOUD_LIVE_PATH="$(readlink -f ${paths.current} 2>/dev/null || true)"`,
3844
+ `TS_CLOUD_RELEASE_PATH="$(readlink -f ${paths.release} 2>/dev/null || echo ${paths.release})"`,
3845
+ 'if [ -n "$TS_CLOUD_LIVE_PATH" ] && [ "$TS_CLOUD_LIVE_PATH" = "$TS_CLOUD_RELEASE_PATH" ]; then TS_CLOUD_IS_LIVE=yes; else TS_CLOUD_IS_LIVE=no; fi'
3846
+ ];
3847
+ }
3834
3848
  function buildPromoteStagedRelease(paths) {
3835
3849
  const staging = `${paths.release}.incoming`;
3836
3850
  return [
3837
3851
  `if [ "$TS_CLOUD_STAGED" = "${staging}" ]; then`,
3838
3852
  ` rm -rf ${paths.release}.previous`,
3839
- ` mv -T ${paths.release} ${paths.release}.previous`,
3840
- ` mv -T ${staging} ${paths.release}`,
3853
+ ` mv ${paths.release} ${paths.release}.previous`,
3854
+ ` mv ${staging} ${paths.release}`,
3841
3855
  ` rm -rf ${paths.release}.previous`,
3842
3856
  "fi"
3843
3857
  ];
@@ -3956,7 +3970,7 @@ function buildSiteDeployScript(options) {
3956
3970
  const stageRelease = [
3957
3971
  "set -euo pipefail",
3958
3972
  ...buildDeployLock(paths),
3959
- `trap 'if [ $? -ne 0 ] && [ "$(readlink -f ${paths.current} 2>/dev/null || true)" != "${paths.release}" ]; then rm -rf ${paths.release}; fi' EXIT`,
3973
+ buildStrandedReleaseTrap(paths),
3960
3974
  ...artifactFetch,
3961
3975
  ...buildEnsureReleaseLayout(paths, sharedPaths),
3962
3976
  ...buildResetReleaseDir(paths),
@@ -3997,7 +4011,7 @@ function buildSiteDeployScript(options) {
3997
4011
  "systemctl daemon-reload",
3998
4012
  `TS_CLOUD_OLD_UNITS=$(systemctl list-units --plain --no-legend --type=service "${unitBase}@*.service" 2>/dev/null | awk '{print $1}' | grep -v "^${instance}$" || true)`,
3999
4013
  `if [ -f /etc/systemd/system/${serviceName} ] && systemctl is-active --quiet ${serviceName}; then echo "[ts-cloud] retiring pre-zero-downtime unit ${serviceName} (one-time restart cutover)"; systemctl stop ${serviceName}; fi`,
4000
- `systemctl start ${instance}`,
4014
+ `systemctl restart ${instance}`,
4001
4015
  `TS_CLOUD_GATE_OK=1; for TS_CLOUD_I in $(seq 1 ${Math.max(1, healthGateSeconds)}); do sleep 1; systemctl is-active --quiet ${instance} || { TS_CLOUD_GATE_OK=0; break; }; done`,
4002
4016
  `if [ "$TS_CLOUD_GATE_OK" -ne 1 ]; then echo "[ts-cloud] release ${releaseId} could not overlap the previous release (no SO_REUSEPORT?) — retiring old instances and retrying" >&2; for TS_CLOUD_RU in \${TS_CLOUD_OLD_UNITS}; do systemctl stop "$TS_CLOUD_RU" 2>/dev/null || true; done; systemctl restart ${instance}; for TS_CLOUD_I in $(seq 1 ${Math.max(1, healthGateSeconds)}); do sleep 1; systemctl is-active --quiet ${instance} || ${failGate}; done; fi`,
4003
4017
  ...gatePath ? [`curl -sf -o /dev/null --max-time 10 "http://127.0.0.1:${port}${gatePath}" || ${failGate}`] : [],
@@ -4045,7 +4059,7 @@ function buildStaticSiteDeployScript(options) {
4045
4059
  return [
4046
4060
  "set -euo pipefail",
4047
4061
  ...buildDeployLock(paths),
4048
- `trap 'if [ $? -ne 0 ] && [ "$(readlink -f ${paths.current} 2>/dev/null || true)" != "${paths.release}" ]; then rm -rf ${paths.release}; fi' EXIT`,
4062
+ buildStrandedReleaseTrap(paths),
4049
4063
  ...artifactFetch,
4050
4064
  ...buildEnsureReleaseLayout(paths, []),
4051
4065
  ...buildResetReleaseDir(paths),
@@ -45,7 +45,7 @@ import {
45
45
  resolveSiteKind,
46
46
  resolveUiSource,
47
47
  siteInstallBase
48
- } from "./chunk-pbh6b828.js";
48
+ } from "./chunk-0zbqbrqg.js";
49
49
  import {
50
50
  artifactKey,
51
51
  buildCloudFormationTemplate,
@@ -32,7 +32,7 @@ import {
32
32
  synchronizeDashboardUsers,
33
33
  trackDashboardOperation,
34
34
  verifyStaticApiOrigin
35
- } from "../chunk-c82m4yzn.js";
35
+ } from "../chunk-t092y37p.js";
36
36
  import {
37
37
  deleteStaticSite,
38
38
  deployStaticSite,
@@ -65,7 +65,7 @@ import {
65
65
  shipsARelease,
66
66
  siteInstallBase,
67
67
  validateDeploymentConfig
68
- } from "../chunk-pbh6b828.js";
68
+ } from "../chunk-0zbqbrqg.js";
69
69
  import"../chunk-tq46tnxv.js";
70
70
  import"../chunk-703nkybg.js";
71
71
  import"../chunk-4cjrg98a.js";
@@ -52,7 +52,7 @@ import {
52
52
  waitForCloudInit,
53
53
  waitForSsh,
54
54
  wrapCloudInitUserData
55
- } from "../chunk-pbh6b828.js";
55
+ } from "../chunk-0zbqbrqg.js";
56
56
  import"../chunk-tq46tnxv.js";
57
57
  import"../chunk-703nkybg.js";
58
58
  import"../chunk-4cjrg98a.js";
@@ -70,6 +70,28 @@ export declare function buildDeployLock(paths: ReleasePaths, waitSeconds?: numbe
70
70
  * two renames, which is atomic enough that no request lands mid-swap.
71
71
  */
72
72
  export declare function buildResetReleaseDir(paths: ReleasePaths): string[];
73
+ /**
74
+ * Remove a half-built release if the deploy fails before it went live.
75
+ *
76
+ * The check has to run *when the trap fires*, not when it is armed. A deploy
77
+ * arms this at the top and activates the release much later, so a value
78
+ * computed up front says "not live" for the rest of the script — and a failure
79
+ * in any step after activation would then delete the release the site had just
80
+ * started serving. Both paths are resolved at that moment for the reason in
81
+ * {@link buildIsReleaseLive}.
82
+ */
83
+ export declare function buildStrandedReleaseTrap(paths: ReleasePaths): string;
84
+ /**
85
+ * Set `TS_CLOUD_IS_LIVE` to "yes" when `current` resolves to this release.
86
+ *
87
+ * Both sides are resolved before comparing. Comparing a resolved `current`
88
+ * against the literal release path looks equivalent and is not: one symlinked
89
+ * ancestor anywhere above the site — `/var/www` moved onto a data volume, a
90
+ * `/tmp` that is really `/private/tmp` — makes the two spellings differ, the
91
+ * guard misses, and the branch it was guarding deletes the directory the site
92
+ * is being served from.
93
+ */
94
+ export declare function buildIsReleaseLive(paths: ReleasePaths): string[];
73
95
  /**
74
96
  * Move a staged release into place, if it was staged (see
75
97
  * {@link buildResetReleaseDir}). A no-op when the deploy extracted directly.
package/dist/index.js CHANGED
@@ -285,7 +285,7 @@ import {
285
285
  volumeCapabilities,
286
286
  webhookEndpoint,
287
287
  zeroCapacity
288
- } from "./chunk-c82m4yzn.js";
288
+ } from "./chunk-t092y37p.js";
289
289
  import {
290
290
  deleteStaticSite,
291
291
  deployStaticSite,
@@ -398,7 +398,7 @@ import {
398
398
  waitForCloudInit,
399
399
  waitForSsh,
400
400
  wrapCloudInitUserData
401
- } from "./chunk-pbh6b828.js";
401
+ } from "./chunk-0zbqbrqg.js";
402
402
  import {
403
403
  ABTestManager,
404
404
  AI,