@stacksjs/ts-cloud 0.7.59 → 0.7.61

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 (69) hide show
  1. package/dist/auth/encryption.d.ts +2 -1
  2. package/dist/auth/index.d.ts +1 -1
  3. package/dist/bin/cli.js +2973 -2973
  4. package/dist/{chunk-g126cfn9.js → chunk-c82m4yzn.js} +79 -67
  5. package/dist/{chunk-9m6b4m74.js → chunk-pbh6b828.js} +61 -17
  6. package/dist/{chunk-e05phx5f.js → chunk-rxhqny6z.js} +2 -2
  7. package/dist/{chunk-vdk53yyq.js → chunk-tq46tnxv.js} +102 -64
  8. package/dist/{chunk-exbcsab2.js → chunk-zvk0f89t.js} +1 -1
  9. package/dist/control-plane/index.d.ts +1 -1
  10. package/dist/control-plane/store.d.ts +2 -1
  11. package/dist/deploy/dashboard-config-module.d.ts +7 -1
  12. package/dist/deploy/dashboard-session.d.ts +2 -1
  13. package/dist/deploy/dashboard-users.d.ts +5 -4
  14. package/dist/deploy/index.d.ts +1 -1
  15. package/dist/deploy/index.js +7 -7
  16. package/dist/deploy/management-dashboard.d.ts +4 -3
  17. package/dist/drivers/index.js +2 -2
  18. package/dist/drivers/shared/releases.d.ts +32 -0
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.js +24 -10
  21. package/dist/ui/access-denied.html +2 -2
  22. package/dist/ui/account/automation.html +4 -4
  23. package/dist/ui/account/security.html +2 -2
  24. package/dist/ui/applications/compose.html +4 -4
  25. package/dist/ui/applications/new.html +2 -2
  26. package/dist/ui/data/backups.html +4 -4
  27. package/dist/ui/data/services.html +4 -4
  28. package/dist/ui/data/volumes.html +4 -4
  29. package/dist/ui/index.html +4 -4
  30. package/dist/ui/operations/alerts.html +4 -4
  31. package/dist/ui/operations/configuration.html +4 -4
  32. package/dist/ui/operations/jobs.html +4 -4
  33. package/dist/ui/operations/maintenance.html +4 -4
  34. package/dist/ui/operations/observability.html +4 -4
  35. package/dist/ui/operations/previews.html +4 -4
  36. package/dist/ui/operations/queue.html +4 -4
  37. package/dist/ui/operations/regions.html +4 -4
  38. package/dist/ui/operations/releases.html +4 -4
  39. package/dist/ui/operations/workloads.html +4 -4
  40. package/dist/ui/security.html +2 -2
  41. package/dist/ui/server/actions.html +4 -4
  42. package/dist/ui/server/activity.html +2 -2
  43. package/dist/ui/server/capacity.html +4 -4
  44. package/dist/ui/server/database.html +4 -4
  45. package/dist/ui/server/deployments.html +4 -4
  46. package/dist/ui/server/diagnostics.html +2 -2
  47. package/dist/ui/server/firewall.html +4 -4
  48. package/dist/ui/server/fleet.html +4 -4
  49. package/dist/ui/server/logs.html +4 -4
  50. package/dist/ui/server/metrics.html +2 -2
  51. package/dist/ui/server/security.html +2 -2
  52. package/dist/ui/server/services.html +2 -2
  53. package/dist/ui/server/sites.html +4 -4
  54. package/dist/ui/server/ssh-keys.html +4 -4
  55. package/dist/ui/server/team.html +4 -4
  56. package/dist/ui/serverless/alarms.html +3 -3
  57. package/dist/ui/serverless/assets.html +2 -2
  58. package/dist/ui/serverless/cost.html +2 -2
  59. package/dist/ui/serverless/data.html +4 -4
  60. package/dist/ui/serverless/deployments.html +2 -2
  61. package/dist/ui/serverless/firewall.html +2 -2
  62. package/dist/ui/serverless/functions.html +4 -4
  63. package/dist/ui/serverless/logs.html +4 -4
  64. package/dist/ui/serverless/metrics.html +2 -2
  65. package/dist/ui/serverless/queues.html +4 -4
  66. package/dist/ui/serverless/secrets.html +4 -4
  67. package/dist/ui/serverless/traces.html +4 -4
  68. package/dist/ui/serverless.html +3 -3
  69. package/package.json +3 -3
@@ -5,8 +5,10 @@ import {
5
5
  resolveAppDatabase,
6
6
  resolveCloudProvider,
7
7
  resolveManagementDashboardSites,
8
- resolveProjectStackName
9
- } from "./chunk-vdk53yyq.js";
8
+ resolveProjectStackName,
9
+ resolveStatePath,
10
+ statePath
11
+ } from "./chunk-tq46tnxv.js";
10
12
  import {
11
13
  EC2Client,
12
14
  SSMClient
@@ -3806,6 +3808,40 @@ function buildEnsureReleaseLayout(paths, sharedPaths = DEFAULT_SHARED_PATHS) {
3806
3808
  }
3807
3809
  return lines;
3808
3810
  }
3811
+ function buildDeployLock(paths, waitSeconds = 900) {
3812
+ const lock = `${deployMetaDir(paths.base)}/deploy.lock`;
3813
+ return [
3814
+ `mkdir -p "$(dirname ${lock})"`,
3815
+ `exec 9>${lock}`,
3816
+ `flock -w ${waitSeconds} 9 || { echo "[ts-cloud] another deploy of this site has held the lock for ${waitSeconds}s — refusing to race it" >&2; exit 1; }`
3817
+ ];
3818
+ }
3819
+ function buildResetReleaseDir(paths) {
3820
+ const staging = `${paths.release}.incoming`;
3821
+ return [
3822
+ `rm -rf ${staging}`,
3823
+ `mkdir -p ${staging}`,
3824
+ `if [ "$(readlink -f ${paths.current} 2>/dev/null || true)" = "${paths.release}" ]; then`,
3825
+ ` TS_CLOUD_STAGED=${staging}`,
3826
+ "else",
3827
+ ` rm -rf ${paths.release}`,
3828
+ ` mkdir -p ${paths.release}`,
3829
+ ` rmdir ${staging}`,
3830
+ ` TS_CLOUD_STAGED=${paths.release}`,
3831
+ "fi"
3832
+ ];
3833
+ }
3834
+ function buildPromoteStagedRelease(paths) {
3835
+ const staging = `${paths.release}.incoming`;
3836
+ return [
3837
+ `if [ "$TS_CLOUD_STAGED" = "${staging}" ]; then`,
3838
+ ` rm -rf ${paths.release}.previous`,
3839
+ ` mv -T ${paths.release} ${paths.release}.previous`,
3840
+ ` mv -T ${staging} ${paths.release}`,
3841
+ ` rm -rf ${paths.release}.previous`,
3842
+ "fi"
3843
+ ];
3844
+ }
3809
3845
  function buildLinkSharedPaths(paths, sharedPaths = DEFAULT_SHARED_PATHS) {
3810
3846
  const lines = [];
3811
3847
  for (const p of sharedPaths) {
@@ -3919,17 +3955,18 @@ function buildSiteDeployScript(options) {
3919
3955
  const preStart = preStartCommands.length > 0 ? [`cd ${paths.release}`, ...preStartCommands] : [];
3920
3956
  const stageRelease = [
3921
3957
  "set -euo pipefail",
3958
+ ...buildDeployLock(paths),
3922
3959
  `trap 'if [ $? -ne 0 ] && [ "$(readlink -f ${paths.current} 2>/dev/null || true)" != "${paths.release}" ]; then rm -rf ${paths.release}; fi' EXIT`,
3923
3960
  ...artifactFetch,
3924
3961
  ...buildEnsureReleaseLayout(paths, sharedPaths),
3925
- `rm -rf ${paths.release}`,
3926
- `mkdir -p ${paths.release}`,
3927
- `tar xzf ${tarball} -C ${paths.release}`,
3962
+ ...buildResetReleaseDir(paths),
3963
+ `tar xzf ${tarball} -C "$TS_CLOUD_STAGED"`,
3928
3964
  `rm -f ${tarball}`,
3929
3965
  `cat > ${paths.shared}/.env <<'TS_CLOUD_ENV_EOF'`,
3930
3966
  envFile,
3931
3967
  "TS_CLOUD_ENV_EOF",
3932
3968
  `chmod 600 ${paths.shared}/.env`,
3969
+ ...buildPromoteStagedRelease(paths),
3933
3970
  `for TS_CLOUD_ENV in ${paths.shared}/.env ${paths.release}/.env ${paths.release}/.env.*; do [ -f "$TS_CLOUD_ENV" ] && sed -i -E '/^[[:space:]]*(PORT|PORT_BACKEND|PORT_ADMIN|PORT_FRONTEND)[[:space:]]*=/d' "$TS_CLOUD_ENV" 2>/dev/null || true; done`,
3934
3971
  ...buildLinkSharedPaths(paths, sharedPaths),
3935
3972
  ...preStart
@@ -4007,12 +4044,13 @@ function buildStaticSiteDeployScript(options) {
4007
4044
  const preStart = preStartCommands.length > 0 ? [`cd ${paths.release}`, ...preStartCommands] : [];
4008
4045
  return [
4009
4046
  "set -euo pipefail",
4047
+ ...buildDeployLock(paths),
4010
4048
  `trap 'if [ $? -ne 0 ] && [ "$(readlink -f ${paths.current} 2>/dev/null || true)" != "${paths.release}" ]; then rm -rf ${paths.release}; fi' EXIT`,
4011
4049
  ...artifactFetch,
4012
4050
  ...buildEnsureReleaseLayout(paths, []),
4013
- `rm -rf ${paths.release}`,
4014
- `mkdir -p ${paths.release}`,
4015
- `tar xzf ${tarball} -C ${paths.release}`,
4051
+ ...buildResetReleaseDir(paths),
4052
+ `tar xzf ${tarball} -C "$TS_CLOUD_STAGED"`,
4053
+ ...buildPromoteStagedRelease(paths),
4016
4054
  `rm -f ${tarball}`,
4017
4055
  ...preStart,
4018
4056
  ...buildActivateRelease(paths),
@@ -4069,6 +4107,7 @@ function redactForDashboard(config) {
4069
4107
  if (safe.hetzner)
4070
4108
  delete safe.hetzner.apiToken;
4071
4109
  delete safe.aws;
4110
+ delete safe.stateDir;
4072
4111
  for (const site of Object.values(safe.sites ?? {})) {
4073
4112
  if (site?.env)
4074
4113
  site.env = blankValues(site.env);
@@ -4100,7 +4139,9 @@ function serializeDashboardConfig(config) {
4100
4139
 
4101
4140
  // src/deploy/management-dashboard.ts
4102
4141
  var MANAGEMENT_DASHBOARD_SITE = "dashboard";
4103
- var DASHBOARD_CREDENTIALS_FILE = join4(".ts-cloud", "dashboard-credentials.json");
4142
+ function dashboardCredentialsFile() {
4143
+ return statePath("dashboard-credentials.json");
4144
+ }
4104
4145
  function generatePassword() {
4105
4146
  return randomBytes(24).toString("base64url");
4106
4147
  }
@@ -4110,7 +4151,8 @@ function resolveDashboardAuth(cwd, username, logger) {
4110
4151
  return { password: explicit, source: "env" };
4111
4152
  if (truthy(process.env.TS_CLOUD_UI_PUBLIC))
4112
4153
  return { password: undefined, source: "public" };
4113
- const file = join4(cwd, DASHBOARD_CREDENTIALS_FILE);
4154
+ const credentialsFile = dashboardCredentialsFile();
4155
+ const file = resolveStatePath(cwd, "dashboard-credentials.json");
4114
4156
  try {
4115
4157
  if (existsSync2(file)) {
4116
4158
  const saved = JSON.parse(readFileSync3(file, "utf8"));
@@ -4124,10 +4166,10 @@ function resolveDashboardAuth(cwd, username, logger) {
4124
4166
  writeFileSync(file, `${JSON.stringify({ username, password, generatedAt: new Date().toISOString() }, null, 2)}
4125
4167
  `);
4126
4168
  chmodSync(file, 384);
4127
- logger.info(`Management dashboard: generated a password for '${username}' and saved it to ${DASHBOARD_CREDENTIALS_FILE} (read it there — it is not printed). Set TS_CLOUD_UI_PASSWORD to pin your own, or TS_CLOUD_UI_PUBLIC=1 to serve without auth.`);
4169
+ logger.info(`Management dashboard: generated a password for '${username}' and saved it to ${credentialsFile} (read it there — it is not printed). Set TS_CLOUD_UI_PASSWORD to pin your own, or TS_CLOUD_UI_PUBLIC=1 to serve without auth.`);
4128
4170
  } catch (error) {
4129
4171
  logger.warn(`Management dashboard: could not persist the generated password (${error?.message ?? error}). Using it for this deploy only — pass: ${password}
4130
- This password is now in your deploy log. Set TS_CLOUD_UI_PASSWORD to a value of your own and redeploy once ${DASHBOARD_CREDENTIALS_FILE} is writable.`);
4172
+ This password is now in your deploy log. Set TS_CLOUD_UI_PASSWORD to a value of your own and redeploy once ${credentialsFile} is writable.`);
4131
4173
  }
4132
4174
  return { password, source: "generated" };
4133
4175
  }
@@ -4135,7 +4177,9 @@ var noopLogger = { info: () => {}, warn: () => {} };
4135
4177
  function truthy(v) {
4136
4178
  return v != null && v !== "" && v !== "0" && v.toLowerCase() !== "false";
4137
4179
  }
4138
- var LIVE_STAGE_DIR = join4(".ts-cloud", "dashboard-release");
4180
+ function liveStageDir() {
4181
+ return statePath("dashboard-release");
4182
+ }
4139
4183
  function resolveDashboardVersion() {
4140
4184
  const explicit = process.env.TS_CLOUD_UI_VERSION?.trim();
4141
4185
  if (explicit)
@@ -4155,7 +4199,7 @@ function stageLiveDashboardRoot(config, cwd, logger) {
4155
4199
  logger.warn("Management dashboard: the cloud config has no project slug — skipping the live dashboard.");
4156
4200
  return null;
4157
4201
  }
4158
- const stage = join4(cwd, LIVE_STAGE_DIR);
4202
+ const stage = resolveStatePath(cwd, "dashboard-release");
4159
4203
  try {
4160
4204
  mkdirSync(stage, { recursive: true });
4161
4205
  writeFileSync(join4(stage, "cloud.config.ts"), serializeDashboardConfig(config));
@@ -4167,7 +4211,7 @@ function stageLiveDashboardRoot(config, cwd, logger) {
4167
4211
  };
4168
4212
  writeFileSync(join4(stage, "package.json"), `${JSON.stringify(pkg, null, 2)}
4169
4213
  `);
4170
- return LIVE_STAGE_DIR;
4214
+ return liveStageDir();
4171
4215
  } catch (error) {
4172
4216
  logger.warn(`Management dashboard: could not stage the live release (${error?.message ?? error}) — skipping.`);
4173
4217
  return null;
@@ -4246,7 +4290,7 @@ function ensureManagementDashboard(config, options = {}) {
4246
4290
  logger.info("Management dashboard: no domain resolved (set TS_CLOUD_UI_DOMAIN or configure a site domain) — skipping.");
4247
4291
  return config;
4248
4292
  }
4249
- const authNote = auth.source === "public" ? "NO AUTH — TS_CLOUD_UI_PUBLIC is set (dashboard is publicly reachable)" : auth.source === "env" ? "htpasswd-protected (TS_CLOUD_UI_PASSWORD)" : `htpasswd-protected (auto-generated — see ${DASHBOARD_CREDENTIALS_FILE})`;
4293
+ const authNote = auth.source === "public" ? "NO AUTH — TS_CLOUD_UI_PUBLIC is set (dashboard is publicly reachable)" : auth.source === "env" ? "htpasswd-protected (TS_CLOUD_UI_PASSWORD)" : `htpasswd-protected (auto-generated — see ${dashboardCredentialsFile()})`;
4250
4294
  logger.warn("Management dashboard: static mode — one shared password, and no per-site collaborators. Unset TS_CLOUD_UI_STATIC for the live dashboard.");
4251
4295
  for (const { name, site } of resolved) {
4252
4296
  sites[name] = site;
@@ -5281,4 +5325,4 @@ function buildCloudFrontOriginConfig(options) {
5281
5325
  CustomErrorResponses: { Quantity: 0 }
5282
5326
  };
5283
5327
  }
5284
- export { PANTRY_PROJECT_DIR, pgAdminCommand, BACKUP_RUNNER_PATH, buildBackupRestoreScript, siteInstallBase, isPhpSite, resolveSiteDeployTarget, resolveSiteKind, validateDeploymentConfig, shipsARelease, DEFAULT_RPX_CERTS_DIR, normalizeRoutePath, deriveRouteId, buildRpxConfig, buildRpxLbConfig, renderRpxLauncher, RPX_DIR, RPX_LAUNCHER_PATH, RPX_SERVICE_NAME, buildRpxProvisionScript, buildRpxFragmentRefreshScript, buildUbuntuBootstrapScript, AwsDriver, resolveHetznerLocation, HetznerClient, resolveHetznerApiToken2 as resolveHetznerApiToken, normalizeSshPublicKey, wrapCloudInitUserData, HetznerDriver, LocalBoxDriver, isBoxMode, createCloudDriver, CloudDriverFactory, cloudDrivers, ensureSshKey, ensureFirewall, ensureServer, serverPublicIpv4, buildSshArgs, sshExec, sshExecOrThrow, scpUpload, waitForSsh, waitForCloudInit, UBUNTU_2404_AMI_PARAM, buildBoxUserData, HetznerBoxProvisioner, AwsBoxProvisioner, createBoxProvisioner, releasePaths, buildRollbackScript, resolveExecStart, buildSiteDeployScript, buildStaticSiteDeployScript, releaseTarballTmpPath, buildAwsArtifactFetch, buildLocalArtifactFetch, buildHostCleanupScript, MANAGEMENT_DASHBOARD_SITE, DASHBOARD_CREDENTIALS_FILE, resolveDashboardAuth, resolveUiSource, ensureManagementDashboard, buildManagementDashboardArtifact, resolveSiteFramework, deploySiteRelease, deployAllComputeSites, reloadRpxGateway, renewRpxCertificates, MANAGED_CACHE_POLICY_OPTIMIZED, MANAGED_CACHE_POLICY_DISABLED, MANAGED_ORIGIN_REQUEST_POLICY_ALL_VIEWER, buildCloudFrontOriginConfig };
5328
+ export { PANTRY_PROJECT_DIR, pgAdminCommand, BACKUP_RUNNER_PATH, buildBackupRestoreScript, siteInstallBase, isPhpSite, resolveSiteDeployTarget, resolveSiteKind, validateDeploymentConfig, shipsARelease, DEFAULT_RPX_CERTS_DIR, normalizeRoutePath, deriveRouteId, buildRpxConfig, buildRpxLbConfig, renderRpxLauncher, RPX_DIR, RPX_LAUNCHER_PATH, RPX_SERVICE_NAME, buildRpxProvisionScript, buildRpxFragmentRefreshScript, buildUbuntuBootstrapScript, AwsDriver, resolveHetznerLocation, HetznerClient, resolveHetznerApiToken2 as resolveHetznerApiToken, normalizeSshPublicKey, wrapCloudInitUserData, HetznerDriver, LocalBoxDriver, isBoxMode, createCloudDriver, CloudDriverFactory, cloudDrivers, ensureSshKey, ensureFirewall, ensureServer, serverPublicIpv4, buildSshArgs, sshExec, sshExecOrThrow, scpUpload, waitForSsh, waitForCloudInit, UBUNTU_2404_AMI_PARAM, buildBoxUserData, HetznerBoxProvisioner, AwsBoxProvisioner, createBoxProvisioner, releasePaths, buildRollbackScript, resolveExecStart, buildSiteDeployScript, buildStaticSiteDeployScript, releaseTarballTmpPath, buildAwsArtifactFetch, buildLocalArtifactFetch, buildHostCleanupScript, MANAGEMENT_DASHBOARD_SITE, dashboardCredentialsFile, resolveDashboardAuth, resolveUiSource, ensureManagementDashboard, buildManagementDashboardArtifact, resolveSiteFramework, deploySiteRelease, deployAllComputeSites, reloadRpxGateway, renewRpxCertificates, MANAGED_CACHE_POLICY_OPTIMIZED, MANAGED_CACHE_POLICY_DISABLED, MANAGED_ORIGIN_REQUEST_POLICY_ALL_VIEWER, buildCloudFrontOriginConfig };
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  buildAndPushServerlessImage
3
- } from "./chunk-exbcsab2.js";
3
+ } from "./chunk-zvk0f89t.js";
4
4
  import"./chunk-50jpda9q.js";
5
- import"./chunk-vdk53yyq.js";
5
+ import"./chunk-tq46tnxv.js";
6
6
  import"./chunk-zqtpg06c.js";
7
7
  import"./chunk-v0bahtg2.js";
8
8
  export {