@stacksjs/ts-cloud 0.7.91 → 0.7.92

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 (54) hide show
  1. package/dist/bin/cli.js +287 -276
  2. package/dist/bin/dashboard-server.js +156 -145
  3. package/dist/{chunk-j1kkmmrz.js → chunk-29fwqkb7.js} +1 -1
  4. package/dist/{chunk-3scf213a.js → chunk-fbwcv2vf.js} +53 -9
  5. package/dist/deploy/index.js +2 -2
  6. package/dist/drivers/index.js +1 -1
  7. package/dist/drivers/shared/rpx-gateway.d.ts +4 -0
  8. package/dist/index.js +2 -2
  9. package/dist/ui/access-denied.html +2 -2
  10. package/dist/ui/account/automation.html +4 -4
  11. package/dist/ui/account/security.html +2 -2
  12. package/dist/ui/applications/compose.html +4 -4
  13. package/dist/ui/applications/new.html +2 -2
  14. package/dist/ui/data/backups.html +4 -4
  15. package/dist/ui/data/services.html +4 -4
  16. package/dist/ui/data/volumes.html +4 -4
  17. package/dist/ui/index.html +4 -4
  18. package/dist/ui/integrations.html +2 -2
  19. package/dist/ui/operations/alerts.html +4 -4
  20. package/dist/ui/operations/configuration.html +4 -4
  21. package/dist/ui/operations/jobs.html +4 -4
  22. package/dist/ui/operations/maintenance.html +3 -3
  23. package/dist/ui/operations/observability.html +4 -4
  24. package/dist/ui/operations/previews.html +4 -4
  25. package/dist/ui/operations/queue.html +3 -3
  26. package/dist/ui/operations/regions.html +3 -3
  27. package/dist/ui/operations/releases.html +3 -3
  28. package/dist/ui/operations/workloads.html +4 -4
  29. package/dist/ui/server/actions.html +3 -3
  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/firewall.html +4 -4
  35. package/dist/ui/server/fleet.html +4 -4
  36. package/dist/ui/server/logs.html +4 -4
  37. package/dist/ui/server/metrics.html +4 -4
  38. package/dist/ui/server/sites.html +4 -4
  39. package/dist/ui/server/ssh-keys.html +3 -3
  40. package/dist/ui/server/team.html +4 -4
  41. package/dist/ui/server/terminal.html +2 -2
  42. package/dist/ui/serverless/alarms.html +4 -4
  43. package/dist/ui/serverless/assets.html +2 -2
  44. package/dist/ui/serverless/cost.html +2 -2
  45. package/dist/ui/serverless/data.html +3 -3
  46. package/dist/ui/serverless/firewall.html +2 -2
  47. package/dist/ui/serverless/functions.html +3 -3
  48. package/dist/ui/serverless/logs.html +4 -4
  49. package/dist/ui/serverless/metrics.html +2 -2
  50. package/dist/ui/serverless/queues.html +4 -4
  51. package/dist/ui/serverless/secrets.html +4 -4
  52. package/dist/ui/serverless/traces.html +3 -3
  53. package/dist/ui/serverless.html +4 -4
  54. package/package.json +3 -3
@@ -45,7 +45,7 @@ import {
45
45
  resolveSiteKind,
46
46
  resolveUiSource,
47
47
  siteInstallBase
48
- } from "./chunk-3scf213a.js";
48
+ } from "./chunk-fbwcv2vf.js";
49
49
  import {
50
50
  artifactKey,
51
51
  buildCloudFormationTemplate,
@@ -1347,6 +1347,35 @@ function writeFileHeredoc(path, content, delimiter, mode = "0644") {
1347
1347
  `chmod ${mode} ${path}`
1348
1348
  ];
1349
1349
  }
1350
+ function shellSingleQuote(value) {
1351
+ return `'${value.replaceAll("'", "'\\''")}'`;
1352
+ }
1353
+ function writeRpxFragment(path, content, delimiter, options) {
1354
+ if (!options.preserveManagementDashboardRoutes)
1355
+ return writeFileHeredoc(path, content, delimiter, "0600");
1356
+ const mergeScript = `
1357
+ const { readFileSync, writeFileSync } = require('node:fs')
1358
+ const currentPath = process.env.TS_CLOUD_RPX_CURRENT_FRAGMENT
1359
+ const candidatePath = process.env.TS_CLOUD_RPX_CANDIDATE_FRAGMENT
1360
+ const isDashboard = route => /^(?:dashboard|cloud)\\./i.test(String(route?.to || ''))
1361
+ const current = JSON.parse(readFileSync(currentPath, 'utf8'))
1362
+ const candidate = JSON.parse(readFileSync(candidatePath, 'utf8'))
1363
+ const retained = Array.isArray(current.proxies) ? current.proxies.filter(isDashboard) : []
1364
+ const next = Array.isArray(candidate.proxies) ? candidate.proxies.filter(route => !isDashboard(route)) : []
1365
+ candidate.proxies = [...next, ...retained]
1366
+ writeFileSync(candidatePath, JSON.stringify(candidate, null, 2) + '\\n', { mode: 0o600 })
1367
+ `.trim();
1368
+ return [
1369
+ `__tsc_fragment_candidate="$(mktemp "${path}.candidate.XXXXXX")"`,
1370
+ `cat > "$__tsc_fragment_candidate" <<'${delimiter}'`,
1371
+ content,
1372
+ delimiter,
1373
+ 'chmod 0600 "$__tsc_fragment_candidate"',
1374
+ `if [ -f ${path} ]; then TS_CLOUD_RPX_CURRENT_FRAGMENT=${path} TS_CLOUD_RPX_CANDIDATE_FRAGMENT="$__tsc_fragment_candidate" ${options.bunBin} -e ${shellSingleQuote(mergeScript)}; fi`,
1375
+ `mv -f "$__tsc_fragment_candidate" ${path}`,
1376
+ `chmod 0600 ${path}`
1377
+ ];
1378
+ }
1350
1379
  function rpxCertRenewServiceName(slug) {
1351
1380
  const safeSlug = (slug || "app").replace(/[^a-z0-9._-]+/gi, "-");
1352
1381
  return `rpx-cert-renew-${safeSlug}.service`;
@@ -1459,7 +1488,10 @@ function buildRpxProvisionScript(options) {
1459
1488
  `mv ${RPX_INSTALL_DIR}.next ${RPX_INSTALL_DIR}`,
1460
1489
  `rm -rf ${RPX_INSTALL_DIR}.prev`,
1461
1490
  `ln -sfn ${RPX_INSTALL_DIR}/node_modules ${RPX_DIR}/node_modules`,
1462
- ...writeFileHeredoc(`${RPX_SITES_DIR}/${slug}.json`, fragment, "TS_CLOUD_RPX_FRAGMENT_EOF", "0600"),
1491
+ ...writeRpxFragment(`${RPX_SITES_DIR}/${slug}.json`, fragment, "TS_CLOUD_RPX_FRAGMENT_EOF", {
1492
+ bunBin,
1493
+ preserveManagementDashboardRoutes: options.preserveManagementDashboardRoutes
1494
+ }),
1463
1495
  ...writeFileHeredoc(RPX_LAUNCHER_PATH, assembler, "TS_CLOUD_RPX_EOF"),
1464
1496
  `${bunBin} build --production --compile --outfile ${RPX_BINARY_PATH}.next ${RPX_LAUNCHER_PATH}`,
1465
1497
  `chmod 0755 ${RPX_BINARY_PATH}.next`,
@@ -1508,7 +1540,10 @@ function buildRpxFragmentRefreshScript(options) {
1508
1540
  return [
1509
1541
  "set -euo pipefail",
1510
1542
  `mkdir -p ${RPX_SITES_DIR}`,
1511
- ...writeFileHeredoc(`${RPX_SITES_DIR}/${slug}.json`, fragment, "TS_CLOUD_RPX_FRAGMENT_EOF", "0600"),
1543
+ ...writeRpxFragment(`${RPX_SITES_DIR}/${slug}.json`, fragment, "TS_CLOUD_RPX_FRAGMENT_EOF", {
1544
+ bunBin: "/usr/local/bin/bun",
1545
+ preserveManagementDashboardRoutes: options.preserveManagementDashboardRoutes
1546
+ }),
1512
1547
  `systemctl restart ${RPX_SERVICE_NAME}`
1513
1548
  ];
1514
1549
  }
@@ -5909,16 +5944,16 @@ async function deploySiteRelease(driver, options, logger = noopLogger2) {
5909
5944
  perInstance: result.perInstance
5910
5945
  };
5911
5946
  }
5912
- function shellSingleQuote(value) {
5947
+ function shellSingleQuote2(value) {
5913
5948
  return `'${value.replaceAll("'", "'\\''")}'`;
5914
5949
  }
5915
5950
  function buildManagementDashboardServiceReconciliationScript(slug, desiredSiteNames, serverOwner = false, desiredDomains = []) {
5916
5951
  const prefix = `${slug}-dashboard-`;
5917
5952
  const desiredUnits = desiredSiteNames.map((siteName) => `${slug}-${siteName}.service`);
5918
5953
  const routeReconciliation = serverOwner ? [
5919
- `export TS_CLOUD_DASHBOARD_KEEP_DOMAINS=${shellSingleQuote(JSON.stringify(desiredDomains))}`,
5954
+ `export TS_CLOUD_DASHBOARD_KEEP_DOMAINS=${shellSingleQuote2(JSON.stringify(desiredDomains))}`,
5920
5955
  "rm -f /run/ts-cloud-dashboard-routes-changed",
5921
- `/usr/local/bin/bun --bun -e ${shellSingleQuote(`
5956
+ `/usr/local/bin/bun --bun -e ${shellSingleQuote2(`
5922
5957
  const { chmodSync, existsSync, readdirSync, readFileSync, renameSync, statSync, writeFileSync } = require('node:fs')
5923
5958
  const { basename, join } = require('node:path')
5924
5959
  const root = '/etc/rpx/sites.d'
@@ -5954,9 +5989,9 @@ function buildManagementDashboardServiceReconciliationScript(slug, desiredSiteNa
5954
5989
  ] : [];
5955
5990
  return [
5956
5991
  "set -euo pipefail",
5957
- `TS_CLOUD_DASHBOARD_PREFIX=${shellSingleQuote(prefix)}`,
5992
+ `TS_CLOUD_DASHBOARD_PREFIX=${shellSingleQuote2(prefix)}`,
5958
5993
  `TS_CLOUD_DASHBOARD_SERVER_OWNER=${serverOwner ? "1" : "0"}`,
5959
- `TS_CLOUD_DASHBOARD_DESIRED=${shellSingleQuote(` ${desiredUnits.join(" ")} `)}`,
5994
+ `TS_CLOUD_DASHBOARD_DESIRED=${shellSingleQuote2(` ${desiredUnits.join(" ")} `)}`,
5960
5995
  "for TS_CLOUD_UNIT_FILE in /etc/systemd/system/*.service; do",
5961
5996
  ' [ -e "$TS_CLOUD_UNIT_FILE" ] || continue',
5962
5997
  ' TS_CLOUD_UNIT=$(basename "$TS_CLOUD_UNIT_FILE")',
@@ -6169,7 +6204,11 @@ async function reloadRpxGateway(options) {
6169
6204
  logger.step(`Reloading the load balancer's rpx gateway with ${lbConfig.proxies.length} route(s)...`);
6170
6205
  const result2 = await driver.runRemoteDeploy({
6171
6206
  targets: lbTargets,
6172
- commands: buildRpxFragmentRefreshScript({ config: lbConfig, slug }),
6207
+ commands: buildRpxFragmentRefreshScript({
6208
+ config: lbConfig,
6209
+ slug,
6210
+ preserveManagementDashboardRoutes: options.managementDashboard === false
6211
+ }),
6173
6212
  comment: `ts-cloud rpx gateway reload ${slug}`,
6174
6213
  tags: {
6175
6214
  Project: slug,
@@ -6200,7 +6239,12 @@ async function reloadRpxGateway(options) {
6200
6239
  return true;
6201
6240
  }
6202
6241
  logger.step(`Reloading rpx gateway with ${rpxConfig.proxies.length} route(s)...`);
6203
- const script = buildRpxProvisionScript({ proxy, config: rpxConfig, slug });
6242
+ const script = buildRpxProvisionScript({
6243
+ proxy,
6244
+ config: rpxConfig,
6245
+ slug,
6246
+ preserveManagementDashboardRoutes: options.managementDashboard === false
6247
+ });
6204
6248
  const result = await driver.runRemoteDeploy({
6205
6249
  targets,
6206
6250
  commands: script,
@@ -30,7 +30,7 @@ import {
30
30
  synchronizeDashboardUsers,
31
31
  trackDashboardOperation,
32
32
  verifyStaticApiOrigin
33
- } from "../chunk-j1kkmmrz.js";
33
+ } from "../chunk-29fwqkb7.js";
34
34
  import {
35
35
  deleteStaticSite,
36
36
  deployStaticSite,
@@ -70,7 +70,7 @@ import {
70
70
  siteInstallBase,
71
71
  validateDeploymentConfig,
72
72
  verifyAddressRecord
73
- } from "../chunk-3scf213a.js";
73
+ } from "../chunk-fbwcv2vf.js";
74
74
  import"../chunk-hmehkeqx.js";
75
75
  import"../chunk-7m60qnc8.js";
76
76
  import"../chunk-4cjrg98a.js";
@@ -68,7 +68,7 @@ import {
68
68
  waitForSsh,
69
69
  wrapCloudInitUserData,
70
70
  writeResizeCheckpoint
71
- } from "../chunk-3scf213a.js";
71
+ } from "../chunk-fbwcv2vf.js";
72
72
  import"../chunk-hmehkeqx.js";
73
73
  import"../chunk-7m60qnc8.js";
74
74
  import"../chunk-4cjrg98a.js";
@@ -272,6 +272,8 @@ export interface BuildRpxProvisionOptions {
272
272
  slug?: string;
273
273
  /** Absolute path to the `bun` binary on the box. @default '/usr/local/bin/bun' */
274
274
  bunBin?: string;
275
+ /** Keep the dashboard route currently running on the box during an app-only deploy. */
276
+ preserveManagementDashboardRoutes?: boolean;
275
277
  }
276
278
  export declare const RPX_CERT_RENEW_SCRIPT = "/etc/rpx/renew-certs.sh";
277
279
  export declare const RPX_CERT_RENEW_SERVICE = "rpx-cert-renew.service";
@@ -310,6 +312,8 @@ export interface BuildRpxFragmentRefreshOptions {
310
312
  * Defaults to `'app'`.
311
313
  */
312
314
  slug?: string;
315
+ /** Keep the dashboard route currently running on the box during an app-only deploy. */
316
+ preserveManagementDashboardRoutes?: boolean;
313
317
  }
314
318
  /**
315
319
  * Build the shell commands that rewrite ONLY this app's rpx route fragment
package/dist/index.js CHANGED
@@ -283,7 +283,7 @@ import {
283
283
  volumeCapabilities,
284
284
  webhookEndpoint,
285
285
  zeroCapacity
286
- } from "./chunk-j1kkmmrz.js";
286
+ } from "./chunk-29fwqkb7.js";
287
287
  import {
288
288
  deleteStaticSite,
289
289
  deployStaticSite,
@@ -403,7 +403,7 @@ import {
403
403
  waitForCloudInit,
404
404
  waitForSsh,
405
405
  wrapCloudInitUserData
406
- } from "./chunk-3scf213a.js";
406
+ } from "./chunk-fbwcv2vf.js";
407
407
  import {
408
408
  ABTestManager,
409
409
  AI,