@stacksjs/ts-cloud 0.7.111 → 0.7.113

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 (59) hide show
  1. package/dist/bin/cli.js +512 -512
  2. package/dist/bin/dashboard-server.js +398 -398
  3. package/dist/{chunk-wh1y5rtk.js → chunk-6xnwshtc.js} +87 -4
  4. package/dist/{chunk-3ee2jav4.js → chunk-ham2enem.js} +6 -2
  5. package/dist/deploy/index.js +6 -2
  6. package/dist/deploy/site-target.d.ts +20 -3
  7. package/dist/drivers/index.js +1 -1
  8. package/dist/drivers/shared/rpx-gateway.d.ts +3 -1
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.js +8 -2
  11. package/dist/ui/access-denied.html +2 -2
  12. package/dist/ui/account/automation.html +3 -3
  13. package/dist/ui/applications/compose.html +3 -3
  14. package/dist/ui/data/backups.html +3 -3
  15. package/dist/ui/data/services.html +4 -4
  16. package/dist/ui/data/volumes.html +3 -3
  17. package/dist/ui/index.html +4 -4
  18. package/dist/ui/infrastructure/topology.html +4 -4
  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 +3 -3
  22. package/dist/ui/operations/maintenance.html +4 -4
  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 +4 -4
  26. package/dist/ui/operations/regions.html +4 -4
  27. package/dist/ui/operations/releases.html +4 -4
  28. package/dist/ui/operations/spend.html +4 -4
  29. package/dist/ui/operations/workloads.html +3 -3
  30. package/dist/ui/security.html +2 -2
  31. package/dist/ui/server/actions.html +4 -4
  32. package/dist/ui/server/activity.html +2 -2
  33. package/dist/ui/server/capacity.html +4 -4
  34. package/dist/ui/server/database.html +4 -4
  35. package/dist/ui/server/deployments.html +4 -4
  36. package/dist/ui/server/diagnostics.html +2 -2
  37. package/dist/ui/server/firewall.html +3 -3
  38. package/dist/ui/server/fleet.html +4 -4
  39. package/dist/ui/server/logs.html +3 -3
  40. package/dist/ui/server/metrics.html +4 -4
  41. package/dist/ui/server/security.html +2 -2
  42. package/dist/ui/server/services.html +2 -2
  43. package/dist/ui/server/sites.html +4 -4
  44. package/dist/ui/server/ssh-keys.html +4 -4
  45. package/dist/ui/server/team.html +3 -3
  46. package/dist/ui/server/terminal.html +2 -2
  47. package/dist/ui/serverless/alarms.html +4 -4
  48. package/dist/ui/serverless/cost.html +2 -2
  49. package/dist/ui/serverless/data.html +4 -4
  50. package/dist/ui/serverless/deployments.html +2 -2
  51. package/dist/ui/serverless/firewall.html +2 -2
  52. package/dist/ui/serverless/functions.html +4 -4
  53. package/dist/ui/serverless/logs.html +4 -4
  54. package/dist/ui/serverless/metrics.html +2 -2
  55. package/dist/ui/serverless/queues.html +4 -4
  56. package/dist/ui/serverless/secrets.html +4 -4
  57. package/dist/ui/serverless/traces.html +4 -4
  58. package/dist/ui/serverless.html +4 -4
  59. package/package.json +3 -3
@@ -1336,6 +1336,16 @@ var PHP_SITE_TYPES = new Set([
1336
1336
  function isPhpSite(site) {
1337
1337
  return site.type != null && PHP_SITE_TYPES.has(site.type);
1338
1338
  }
1339
+ function resolveProxyUpstreams(site) {
1340
+ const raw = site.proxyTo;
1341
+ if (raw == null)
1342
+ return [];
1343
+ const list = Array.isArray(raw) ? raw : [raw];
1344
+ return list.map((entry) => String(entry).trim()).filter((entry) => entry.length > 0);
1345
+ }
1346
+ function hasProxyUpstream(site) {
1347
+ return resolveProxyUpstreams(site).length > 0;
1348
+ }
1339
1349
  function resolveSiteDeployTarget(site) {
1340
1350
  if (site.deploy)
1341
1351
  return site.deploy;
@@ -1348,6 +1358,8 @@ function resolveSiteDeployTarget(site) {
1348
1358
  function resolveSiteKind(site) {
1349
1359
  if (site.redirect)
1350
1360
  return "redirect";
1361
+ if (hasProxyUpstream(site))
1362
+ return "proxy";
1351
1363
  if (isPhpSite(site))
1352
1364
  return "server-php";
1353
1365
  const target = resolveSiteDeployTarget(site);
@@ -1387,10 +1399,34 @@ function validateDeploymentConfig(config) {
1387
1399
  serverOnly.push("start");
1388
1400
  if (site.root)
1389
1401
  serverOnly.push("root");
1402
+ if (site.proxyTo)
1403
+ serverOnly.push("proxyTo");
1390
1404
  if (serverOnly.length > 0)
1391
1405
  warnings.push(`Site '${name}' is a redirect site but also sets ${serverOnly.join(", ")}. These are ignored.`);
1392
1406
  continue;
1393
1407
  }
1408
+ if (kind === "proxy") {
1409
+ if (!site.domain)
1410
+ errors.push(`Site '${name}' is a proxy site but has no \`domain\` to route from.`);
1411
+ if (!computeConfigured) {
1412
+ errors.push(`Site '${name}' is a proxy site but no \`infrastructure.compute\` is configured to host the gateway that forwards it.`);
1413
+ }
1414
+ const ignored = [];
1415
+ if (site.start)
1416
+ ignored.push("start");
1417
+ if (site.root)
1418
+ ignored.push("root");
1419
+ if (typeof site.port === "number")
1420
+ ignored.push("port");
1421
+ if (site.build)
1422
+ ignored.push("build");
1423
+ if (site.preStart && site.preStart.length > 0)
1424
+ ignored.push("preStart");
1425
+ if (ignored.length > 0) {
1426
+ warnings.push(`Site '${name}' sets \`proxyTo\`, so ts-cloud ships and supervises nothing for it. ${ignored.join(", ")} ${ignored.length === 1 ? "is" : "are"} ignored — remove ${ignored.length === 1 ? "it" : "them"}, or drop \`proxyTo\` to let ts-cloud own the service.`);
1427
+ }
1428
+ continue;
1429
+ }
1394
1430
  if (target === "server" && !site.start && !site.root) {
1395
1431
  errors.push(`Site '${name}' sets deploy:'server' but declares neither \`start\` (dynamic app) nor \`root\` (static site to serve). Add one.`);
1396
1432
  continue;
@@ -1441,7 +1477,7 @@ function validateDeploymentConfig(config) {
1441
1477
  }
1442
1478
  function shipsARelease(site) {
1443
1479
  const kind = resolveSiteKind(site);
1444
- return kind !== "bucket" && kind !== "redirect";
1480
+ return kind !== "bucket" && kind !== "redirect" && kind !== "proxy";
1445
1481
  }
1446
1482
 
1447
1483
  // src/drivers/shared/rpx-gateway.ts
@@ -1512,6 +1548,22 @@ function buildRpxConfigInternal(sites, options, appBoxes) {
1512
1548
  domains.add(site.domain);
1513
1549
  continue;
1514
1550
  }
1551
+ if (kind === "proxy") {
1552
+ const upstreams = resolveProxyUpstreams(site);
1553
+ if (upstreams.length === 0)
1554
+ continue;
1555
+ const from = upstreams.length === 1 ? upstreams[0] : upstreams;
1556
+ proxies.push({
1557
+ to: site.domain,
1558
+ path,
1559
+ from,
1560
+ id,
1561
+ ...auth ? { auth } : {},
1562
+ ...Array.isArray(from) && loadBalancer ? { loadBalancer } : {}
1563
+ });
1564
+ domains.add(site.domain);
1565
+ continue;
1566
+ }
1515
1567
  if (kind === "server-app") {
1516
1568
  if (typeof site.port !== "number")
1517
1569
  continue;
@@ -1773,10 +1825,29 @@ function buildCertManagementCommands(options) {
1773
1825
  `EMAIL='${email}'`,
1774
1826
  `TLSX="${tlsxCli}"`,
1775
1827
  `DOMAINS='${csv}'`,
1828
+ "DNS_ATTEMPTS='24'",
1829
+ "DNS_DELAY_SECONDS='5'",
1830
+ "wait_for_dns() {",
1831
+ ' d="$1"',
1832
+ " attempt=1",
1833
+ ' while ! getent ahosts "$d" >/dev/null 2>&1; do',
1834
+ ' if [ "$attempt" -ge "$DNS_ATTEMPTS" ]; then',
1835
+ ' echo "DNS for $d did not become resolvable after $DNS_ATTEMPTS attempts" >&2',
1836
+ " return 1",
1837
+ " fi",
1838
+ ' echo "Waiting for public DNS before ACME: $d (attempt $attempt/$DNS_ATTEMPTS)"',
1839
+ ' sleep "$DNS_DELAY_SECONDS"',
1840
+ " attempt=$((attempt + 1))",
1841
+ " done",
1842
+ "}",
1776
1843
  'before=$(cat "$CERTS"/*.crt 2>/dev/null | sha256sum)',
1777
1844
  `for d in ${spaced}; do`,
1778
1845
  ' if [ ! -s "$CERTS/$d.crt" ]; then',
1779
- ' $TLSX acme:issue -d "$d" --method http-01 --webroot "$WEBROOT" --dir "$CERTS" --prod --email "$EMAIL" || echo "issue $d failed (non-fatal)"',
1846
+ ' if wait_for_dns "$d"; then',
1847
+ ' $TLSX acme:issue -d "$d" --method http-01 --webroot "$WEBROOT" --dir "$CERTS" --prod --email "$EMAIL" || echo "issue $d failed (non-fatal)"',
1848
+ " else",
1849
+ ' echo "issue $d skipped until DNS resolves (non-fatal)"',
1850
+ " fi",
1780
1851
  " # rpx reloads its SNI set when a PEM appears. Complete that reload",
1781
1852
  " # before the next hostname starts http-01, or :80 can disappear in",
1782
1853
  " # the middle of the following challenge on a multi-domain deploy.",
@@ -6298,6 +6369,9 @@ var noopLogger2 = {
6298
6369
  step: () => {},
6299
6370
  success: () => {}
6300
6371
  };
6372
+ function shellQuote2(value) {
6373
+ return `'${value.replace(/'/g, `'"'"'`)}'`;
6374
+ }
6301
6375
  async function deploySiteRelease(driver, options, logger = noopLogger2) {
6302
6376
  const { config, environment, siteName, site, slug, sha, runtime, localTarballPath } = options;
6303
6377
  const remoteKey = `releases/${siteName}/${sha}.tar.gz`;
@@ -6670,6 +6744,8 @@ async function deployAllComputeSites(options) {
6670
6744
  }
6671
6745
  if (kind === "redirect")
6672
6746
  return false;
6747
+ if (kind === "proxy")
6748
+ return false;
6673
6749
  return true;
6674
6750
  });
6675
6751
  if (deployable.length === 0)
@@ -6809,6 +6885,9 @@ async function renewRpxCertificates(options) {
6809
6885
  const rpxConfig = buildRpxConfig(routeSource.sites || {}, { proxy, slug: config.project.slug });
6810
6886
  if (rpxConfig.proxies.length === 0)
6811
6887
  return true;
6888
+ const certDomains = certDomainsForConfig(rpxConfig);
6889
+ if (certDomains.length === 0)
6890
+ return true;
6812
6891
  const slug = config.project.slug;
6813
6892
  const stackName = resolveProjectStackName(config, environment);
6814
6893
  let role = "lb";
@@ -6822,9 +6901,13 @@ async function renewRpxCertificates(options) {
6822
6901
  return true;
6823
6902
  }
6824
6903
  logger.step("Issuing rpx TLS certificates after DNS reconciliation...");
6904
+ const certChecks = certDomains.map((domain) => `test -s ${shellQuote2(`${rpxConfig.productionCerts.certsDir}/${domain}.crt`)}`).join(" && ");
6825
6905
  const result = await driver.runRemoteDeploy({
6826
6906
  targets,
6827
- commands: [`systemctl start ${rpxCertRenewServiceName(slug)}`],
6907
+ commands: [
6908
+ `systemctl start ${rpxCertRenewServiceName(slug)}`,
6909
+ certChecks
6910
+ ],
6828
6911
  comment: `ts-cloud rpx TLS issuance ${slug}`,
6829
6912
  tags: {
6830
6913
  Project: slug,
@@ -6927,4 +7010,4 @@ function buildCloudFrontOriginConfig(options) {
6927
7010
  CustomErrorResponses: { Quantity: 0 }
6928
7011
  };
6929
7012
  }
6930
- export { collectServerDnsDomains, removeStaleServerAddressRecords, normalizePublicIpv6, IPV6_EXCLUDED_HOST_LABELS, hostAcceptsIpv6, reconcileAddressRecords, verifyAddressRecord, PANTRY_PROJECT_DIR, buildPantryBootstrapScript, buildVitessProvisionScript, 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, planHetznerServerResize, isHetznerCapacityError, executeHetznerServerResize, buildSshArgs, sshExec, sshExecOrThrow, scpUpload, waitForSsh, waitForCloudInit, collectHetznerResizeManifest, prepareHetznerResize, verifyHetznerResize, resolveHetznerHostOptimizationPlan, buildHetznerHostOptimizationScript, applyHetznerHostOptimization, collectHetznerHostOptimizationReport, verifyHetznerHostOptimization, resizeCheckpointPath, resizeLockPath, readResizeCheckpoint, writeResizeCheckpoint, acquireResizeLock, ensureSshKey, ensureFirewall, ensureServer, serverPublicIpv4, 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 };
7013
+ export { collectServerDnsDomains, removeStaleServerAddressRecords, normalizePublicIpv6, IPV6_EXCLUDED_HOST_LABELS, hostAcceptsIpv6, reconcileAddressRecords, verifyAddressRecord, PANTRY_PROJECT_DIR, buildPantryBootstrapScript, buildVitessProvisionScript, pgAdminCommand, BACKUP_RUNNER_PATH, buildBackupRestoreScript, siteInstallBase, isPhpSite, resolveProxyUpstreams, hasProxyUpstream, 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, planHetznerServerResize, isHetznerCapacityError, executeHetznerServerResize, buildSshArgs, sshExec, sshExecOrThrow, scpUpload, waitForSsh, waitForCloudInit, collectHetznerResizeManifest, prepareHetznerResize, verifyHetznerResize, resolveHetznerHostOptimizationPlan, buildHetznerHostOptimizationScript, applyHetznerHostOptimization, collectHetznerHostOptimizationReport, verifyHetznerHostOptimization, resizeCheckpointPath, resizeLockPath, readResizeCheckpoint, writeResizeCheckpoint, acquireResizeLock, ensureSshKey, ensureFirewall, ensureServer, serverPublicIpv4, 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 };
@@ -50,7 +50,7 @@ import {
50
50
  resolveSiteKind,
51
51
  resolveUiSource,
52
52
  siteInstallBase
53
- } from "./chunk-wh1y5rtk.js";
53
+ } from "./chunk-6xnwshtc.js";
54
54
  import {
55
55
  SSMClient
56
56
  } from "./chunk-7m60qnc8.js";
@@ -30848,6 +30848,8 @@ function siteKindLabel(name, site) {
30848
30848
  const kind = resolveSiteKind(site);
30849
30849
  if (kind === "redirect")
30850
30850
  return "redirect";
30851
+ if (kind === "proxy")
30852
+ return "proxy";
30851
30853
  const build2 = String(site.build ?? "").toLowerCase();
30852
30854
  const start = String(site.start ?? "").toLowerCase();
30853
30855
  if (name === "main" || start.includes("buddy/src/cli.ts serve"))
@@ -30870,7 +30872,7 @@ function siteKindLabel(name, site) {
30870
30872
  }
30871
30873
  function siteRuntime(site) {
30872
30874
  const kind = resolveSiteKind(site);
30873
- if (kind === "redirect")
30875
+ if (kind === "redirect" || kind === "proxy")
30874
30876
  return "—";
30875
30877
  const command = `${site.start ?? ""} ${site.build ?? ""}`.toLowerCase();
30876
30878
  if (kind === "server-static")
@@ -30885,6 +30887,8 @@ function siteDeployLabel(site) {
30885
30887
  const kind = resolveSiteKind(site);
30886
30888
  if (kind === "redirect")
30887
30889
  return "redirect";
30890
+ if (kind === "proxy")
30891
+ return "proxy";
30888
30892
  if (kind === "server-app")
30889
30893
  return "service";
30890
30894
  if (kind === "server-static")
@@ -36,7 +36,7 @@ import {
36
36
  synchronizeDashboardUsers,
37
37
  trackDashboardOperation,
38
38
  verifyStaticApiOrigin
39
- } from "../chunk-3ee2jav4.js";
39
+ } from "../chunk-ham2enem.js";
40
40
  import {
41
41
  deleteStaticSite,
42
42
  deployStaticSite,
@@ -65,12 +65,14 @@ import {
65
65
  collectServerDnsDomains,
66
66
  dashboardCredentialsFile,
67
67
  ensureManagementDashboard,
68
+ hasProxyUpstream,
68
69
  hostAcceptsIpv6,
69
70
  isPhpSite,
70
71
  normalizePublicIpv6,
71
72
  reconcileAddressRecords,
72
73
  removeStaleServerAddressRecords,
73
74
  resolveDashboardAuth,
75
+ resolveProxyUpstreams,
74
76
  resolveSiteDeployTarget,
75
77
  resolveSiteKind,
76
78
  resolveUiSource,
@@ -78,7 +80,7 @@ import {
78
80
  siteInstallBase,
79
81
  validateDeploymentConfig,
80
82
  verifyAddressRecord
81
- } from "../chunk-wh1y5rtk.js";
83
+ } from "../chunk-6xnwshtc.js";
82
84
  import"../chunk-7m60qnc8.js";
83
85
  import"../chunk-4cjrg98a.js";
84
86
  import"../chunk-rds0sy87.js";
@@ -106,6 +108,7 @@ export {
106
108
  resolveUiSource,
107
109
  resolveSiteKind,
108
110
  resolveSiteDeployTarget,
111
+ resolveProxyUpstreams,
109
112
  resolveLegacyDashboardRoute,
110
113
  resolveDashboardData,
111
114
  resolveDashboardAuth,
@@ -120,6 +123,7 @@ export {
120
123
  infraEnvFromOutputs,
121
124
  hostAcceptsIpv6,
122
125
  hashContainerContext,
126
+ hasProxyUpstream,
123
127
  generateStaticSiteTemplate,
124
128
  generateExternalDnsStaticSiteTemplate,
125
129
  generateExistingStaticFullStackTemplate,
@@ -1,6 +1,6 @@
1
1
  import type { CloudConfig, SiteConfig, SiteDeployTarget } from '@ts-cloud/core';
2
2
  /**
3
- * The three resolved deployment kinds for a site:
3
+ * The resolved deployment kinds for a site:
4
4
  * - `'bucket'` — upload built `root` to object storage + CDN.
5
5
  * - `'server-app'` — `server` + `start`: dynamic app as a systemd service.
6
6
  * - `'server-static'` — `server` + no `start` (has static `root`): a static
@@ -8,8 +8,12 @@ import type { CloudConfig, SiteConfig, SiteDeployTarget } from '@ts-cloud/core';
8
8
  * (served by the operator's own proxy, e.g. rpx + tlsx).
9
9
  * - `'redirect'` — gateway-only: `redirect` is set. Nothing is shipped;
10
10
  * the gateway answers `domain` with an HTTP redirect.
11
+ * - `'proxy'` — gateway-only: `proxyTo` is set. Nothing is shipped and
12
+ * no unit is managed; the gateway forwards `domain` to an
13
+ * upstream somebody else runs. The domain still joins the
14
+ * gateway's TLS set, which is the point.
11
15
  */
12
- export type SiteDeployKind = 'bucket' | 'server-app' | 'server-static' | 'server-php' | 'redirect';
16
+ export type SiteDeployKind = 'bucket' | 'server-app' | 'server-static' | 'server-php' | 'redirect' | 'proxy';
13
17
  /**
14
18
  * On-disk base directory for a site's atomic release tree
15
19
  * (`<base>/releases/<sha>` + `<base>/current`).
@@ -33,6 +37,17 @@ export declare function siteInstallBase(slug: string, siteName: string): string;
33
37
  * `type` (laravel/php/statamic/wordpress).
34
38
  */
35
39
  export declare function isPhpSite(site: SiteConfig): boolean;
40
+ /**
41
+ * Normalize a proxy-only site's `proxyTo` into the upstream list the gateway
42
+ * routes to, dropping blanks so a stray empty string cannot produce a route
43
+ * pointing at nothing.
44
+ *
45
+ * Returns `[]` when the site declares no usable upstream, which is what
46
+ * {@link hasProxyUpstream} keys off.
47
+ */
48
+ export declare function resolveProxyUpstreams(site: SiteConfig): string[];
49
+ /** Does this site forward to an upstream ts-cloud does not manage? */
50
+ export declare function hasProxyUpstream(site: SiteConfig): boolean;
36
51
  /**
37
52
  * Resolve the explicit-or-inferred {@link SiteDeployTarget} for a site.
38
53
  *
@@ -68,8 +83,10 @@ export declare function validateDeploymentConfig(config: CloudConfig): Deploymen
68
83
  * Does this site produce a release the compute deploy has to build, package and
69
84
  * ship?
70
85
  *
71
- * `false` for the two kinds that ship nothing:
86
+ * `false` for the kinds that ship nothing:
72
87
  * - `bucket` — handled by the S3/CloudFront static-site path instead;
88
+ * - `proxy` — the gateway forwards the domain to a service ts-cloud does not
89
+ * manage, so there is nothing to build, package or restart;
73
90
  * - `redirect` — the gateway answers the domain with a Location header, so
74
91
  * there is no `root` to package. Filtering these BEFORE the packaging loop
75
92
  * matters: that loop reads `site.root` to build a tarball, and a redirect
@@ -68,7 +68,7 @@ import {
68
68
  waitForSsh,
69
69
  wrapCloudInitUserData,
70
70
  writeResizeCheckpoint
71
- } from "../chunk-wh1y5rtk.js";
71
+ } from "../chunk-6xnwshtc.js";
72
72
  import"../chunk-7m60qnc8.js";
73
73
  import"../chunk-4cjrg98a.js";
74
74
  import"../chunk-rds0sy87.js";
@@ -2,10 +2,12 @@
2
2
  * Generate the rpx reverse-proxy gateway config + provisioning from the `sites`
3
3
  * model.
4
4
  *
5
- * ts-cloud's per-site deploy model resolves each site to one of three kinds
5
+ * ts-cloud's per-site deploy model resolves each site to a kind
6
6
  * (see {@link import('../../deploy/site-target').resolveSiteKind}):
7
7
  * - `server-app` — a dynamic app running on a port (systemd service);
8
8
  * - `server-static` — a static site shipped to `/var/www/<name>`;
9
+ * - `redirect` — answered here with a Location header, nothing shipped;
10
+ * - `proxy` — forwarded here to an upstream ts-cloud does not manage;
9
11
  * - `bucket` — object storage + CDN (not on the box; ignored here).
10
12
  *
11
13
  * The rpx gateway fronts :80/:443 on the box and routes by host **and path**:
package/dist/index.d.ts CHANGED
@@ -32,7 +32,7 @@ export type { ObjectStorageConfig, ObjectStorageCredentials, ObjectStorageProvid
32
32
  export { keyMatchesFilters, migrateObjectStorage, remapKey } from './object-storage/migrate';
33
33
  export type { MigrateEndpoint, MigrateError, MigrateOptions, MigratePlanItem, MigrateProgress, MigrateResult, MigrateVerification, } from './object-storage/migrate';
34
34
  export * from './ssl';
35
- export { deployStaticSite, deployStaticSiteFull, uploadStaticFiles, invalidateCache, deleteStaticSite, generateStaticSiteTemplate, deployStaticSiteWithExternalDns, deployStaticSiteWithExternalDnsFull, generateExternalDnsStaticSiteTemplate, deploySite, resolveSiteDeployTarget, resolveSiteKind, validateDeploymentConfig, buildAndPushServerlessImage, buildFunctionEnv, deployServerlessApp, infraEnvFromOutputs, redeployServerlessApp, rollbackServerlessApp, runRemoteCommand, setMaintenance, buildManagementDashboardArtifact, dashboardCredentialsFile, ensureManagementDashboard, MANAGEMENT_DASHBOARD_SITE, resolveDashboardAuth, resolveUiSource, } from './deploy';
35
+ export { deployStaticSite, deployStaticSiteFull, uploadStaticFiles, invalidateCache, deleteStaticSite, generateStaticSiteTemplate, deployStaticSiteWithExternalDns, deployStaticSiteWithExternalDnsFull, generateExternalDnsStaticSiteTemplate, deploySite, hasProxyUpstream, resolveProxyUpstreams, resolveSiteDeployTarget, resolveSiteKind, shipsARelease, validateDeploymentConfig, buildAndPushServerlessImage, buildFunctionEnv, deployServerlessApp, infraEnvFromOutputs, redeployServerlessApp, rollbackServerlessApp, runRemoteCommand, setMaintenance, buildManagementDashboardArtifact, dashboardCredentialsFile, ensureManagementDashboard, MANAGEMENT_DASHBOARD_SITE, resolveDashboardAuth, resolveUiSource, } from './deploy';
36
36
  export { collectServerDnsDomains, hostAcceptsIpv6, IPV6_EXCLUDED_HOST_LABELS, normalizePublicIpv6, reconcileAddressRecords, removeStaleServerAddressRecords, verifyAddressRecord, } from './deploy/server-dns';
37
37
  export type { AddressRecordReport } from './deploy/server-dns';
38
38
  export type { EnsureDashboardLogger, ResolvedDashboardAuth, StaticSiteConfig, DeployResult, UploadOptions, ExternalDnsStaticSiteConfig, ExternalDnsDeployResult, DeploySiteConfig, DeploySiteResult, StaticSiteDnsProvider, SiteDeployKind, DeploymentValidationResult, BuildImageOptions, BuiltImage, CodeSource, DeployServerlessOptions, ResolvedContext, } from './deploy';
package/dist/index.js CHANGED
@@ -208,7 +208,7 @@ import {
208
208
  verifyUpdateSignature,
209
209
  webhookEndpoint,
210
210
  zeroCapacity
211
- } from "./chunk-3ee2jav4.js";
211
+ } from "./chunk-ham2enem.js";
212
212
  import {
213
213
  deleteStaticSite,
214
214
  deployStaticSite,
@@ -316,6 +316,7 @@ import {
316
316
  ensureManagementDashboard,
317
317
  ensureServer,
318
318
  ensureSshKey,
319
+ hasProxyUpstream,
319
320
  hostAcceptsIpv6,
320
321
  normalizePublicIpv6,
321
322
  normalizeSshPublicKey,
@@ -326,11 +327,13 @@ import {
326
327
  resolveDashboardAuth,
327
328
  resolveExecStart,
328
329
  resolveHetznerApiToken,
330
+ resolveProxyUpstreams,
329
331
  resolveSiteDeployTarget,
330
332
  resolveSiteKind,
331
333
  resolveUiSource,
332
334
  scpUpload,
333
335
  serverPublicIpv4,
336
+ shipsARelease,
334
337
  sshExec,
335
338
  sshExecOrThrow,
336
339
  validateDeploymentConfig,
@@ -338,7 +341,7 @@ import {
338
341
  waitForCloudInit,
339
342
  waitForSsh,
340
343
  wrapCloudInitUserData
341
- } from "./chunk-wh1y5rtk.js";
344
+ } from "./chunk-6xnwshtc.js";
342
345
  import {
343
346
  EC2Client,
344
347
  SSMClient
@@ -5333,6 +5336,7 @@ export {
5333
5336
  signRequest,
5334
5337
  signCloudFrontUrl,
5335
5338
  signCloudFrontCookies,
5339
+ shipsARelease,
5336
5340
  sharedRuntimeLoop,
5337
5341
  sharedRecursionGuard,
5338
5342
  sha256,
@@ -5396,6 +5400,7 @@ export {
5396
5400
  resolveQueues,
5397
5401
  resolveQueuedDeploymentCommand,
5398
5402
  resolveQueueNames,
5403
+ resolveProxyUpstreams,
5399
5404
  resolveProjectStackName,
5400
5405
  resolveObjectStorage,
5401
5406
  resolveManagementDashboardSites,
@@ -5558,6 +5563,7 @@ export {
5558
5563
  hashFile,
5559
5564
  hashDirectory,
5560
5565
  hashBuffer,
5566
+ hasProxyUpstream,
5561
5567
  hasManagementDashboardSite,
5562
5568
  handleSpendRequest,
5563
5569
  guardDutyManager,