@stacksjs/ts-cloud 0.7.30 → 0.7.32

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 (46) hide show
  1. package/dist/bin/cli.js +781 -774
  2. package/dist/{chunk-xdd6qvre.js → chunk-dah449r1.js} +268 -105
  3. package/dist/{chunk-4ew46pj6.js → chunk-ebx9gjnn.js} +2 -2
  4. package/dist/{chunk-rr3j38qr.js → chunk-jgenfdz6.js} +28 -26
  5. package/dist/{chunk-k56wpkhg.js → chunk-stt1z5cx.js} +4 -1
  6. package/dist/{chunk-3mcfbrw8.js → chunk-tskj9fay.js} +1 -1
  7. package/dist/deploy/dashboard-database.d.ts +8 -6
  8. package/dist/deploy/index.js +4 -4
  9. package/dist/drivers/hetzner/client.d.ts +8 -0
  10. package/dist/drivers/hetzner/driver.d.ts +16 -0
  11. package/dist/drivers/index.d.ts +3 -3
  12. package/dist/drivers/index.js +6 -2
  13. package/dist/drivers/local-box/driver.d.ts +1 -1
  14. package/dist/drivers/shared/backups.d.ts +3 -1
  15. package/dist/drivers/shared/compute-deploy.d.ts +9 -3
  16. package/dist/drivers/shared/db-provision.d.ts +24 -2
  17. package/dist/drivers/shared/deploy-script.d.ts +12 -2
  18. package/dist/drivers/shared/fleet.d.ts +12 -1
  19. package/dist/drivers/shared/rpx-gateway.d.ts +26 -0
  20. package/dist/drivers/shared/ssh-keys.d.ts +3 -2
  21. package/dist/index.js +6 -4
  22. package/dist/ui/index.html +3 -3
  23. package/dist/ui/server/actions.html +3 -3
  24. package/dist/ui/server/backups.html +3 -3
  25. package/dist/ui/server/database.html +3 -3
  26. package/dist/ui/server/deployments.html +3 -3
  27. package/dist/ui/server/firewall.html +3 -3
  28. package/dist/ui/server/logs.html +3 -3
  29. package/dist/ui/server/services.html +3 -3
  30. package/dist/ui/server/sites.html +3 -3
  31. package/dist/ui/server/ssh-keys.html +3 -3
  32. package/dist/ui/server/team.html +3 -3
  33. package/dist/ui/server/terminal.html +3 -3
  34. package/dist/ui/server/workers.html +3 -3
  35. package/dist/ui/serverless/alarms.html +3 -3
  36. package/dist/ui/serverless/assets.html +3 -3
  37. package/dist/ui/serverless/data.html +3 -3
  38. package/dist/ui/serverless/deployments.html +3 -3
  39. package/dist/ui/serverless/functions.html +3 -3
  40. package/dist/ui/serverless/logs.html +3 -3
  41. package/dist/ui/serverless/queues.html +3 -3
  42. package/dist/ui/serverless/scheduler.html +3 -3
  43. package/dist/ui/serverless/secrets.html +3 -3
  44. package/dist/ui/serverless/traces.html +3 -3
  45. package/dist/ui/serverless.html +3 -3
  46. package/package.json +3 -3
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  buildAndPushServerlessImage
3
- } from "./chunk-3mcfbrw8.js";
3
+ } from "./chunk-tskj9fay.js";
4
4
  import"./chunk-hsk6fe6x.js";
5
- import"./chunk-k56wpkhg.js";
5
+ import"./chunk-stt1z5cx.js";
6
6
  import"./chunk-arsh1g5h.js";
7
7
  import"./chunk-v0bahtg2.js";
8
8
  export {
@@ -6,7 +6,7 @@ import {
6
6
  step,
7
7
  success,
8
8
  warn
9
- } from "./chunk-3mcfbrw8.js";
9
+ } from "./chunk-tskj9fay.js";
10
10
  import {
11
11
  CloudWatchLogsClient,
12
12
  CostExplorerClient,
@@ -22,19 +22,21 @@ import {
22
22
  buildBackupRestoreScript,
23
23
  buildRollbackScript,
24
24
  createCloudDriver,
25
+ pgAdminCommand,
25
26
  releasePaths,
26
27
  resolveHetznerLocation,
27
28
  resolveSiteFramework,
28
29
  resolveSiteKind,
29
30
  resolveUiSource,
30
31
  siteInstallBase
31
- } from "./chunk-xdd6qvre.js";
32
+ } from "./chunk-dah449r1.js";
32
33
  import {
33
34
  artifactKey,
34
35
  composeServerlessAppTemplate,
35
36
  laravelServerlessEnvDefaults,
36
37
  packagePhpApp,
37
38
  packageServerlessApp,
39
+ resolveAppDatabase,
38
40
  resolveDeploymentMode,
39
41
  resolveQueueNames,
40
42
  resolveQueues,
@@ -42,7 +44,7 @@ import {
42
44
  resolveServerlessArtifactBucketName,
43
45
  resolveServerlessAssetBucketName,
44
46
  resolveServerlessRuntime
45
- } from "./chunk-k56wpkhg.js";
47
+ } from "./chunk-stt1z5cx.js";
46
48
  import {
47
49
  deployStaticSiteWithExternalDnsFull
48
50
  } from "./chunk-d7p84vz5.js";
@@ -347,7 +349,7 @@ async function deployServerlessApp(config, environment, opts = {}) {
347
349
  }
348
350
  if (imageMode) {
349
351
  step("Building + pushing container image");
350
- const { buildAndPushServerlessImage } = await import("./chunk-4ew46pj6.js");
352
+ const { buildAndPushServerlessImage } = await import("./chunk-ebx9gjnn.js");
351
353
  const built = await buildAndPushServerlessImage({
352
354
  app,
353
355
  projectRoot,
@@ -10894,7 +10896,7 @@ function normalizeEngine(engine) {
10894
10896
  }
10895
10897
  function resolveDbEngine(config6) {
10896
10898
  const compute = config6.infrastructure?.compute;
10897
- const declared = config6.infrastructure?.appDatabase?.engine;
10899
+ const declared = resolveAppDatabase(config6)?.engine;
10898
10900
  if (declared)
10899
10901
  return normalizeEngine(declared);
10900
10902
  const managed = compute?.managedServices ?? {};
@@ -10912,33 +10914,33 @@ function mysqlExec(engine, sql) {
10912
10914
  const sock = engine === "mariadb" ? SOCKETS.mariadb : SOCKETS.mysql;
10913
10915
  return [`mysql --socket=${sock} -u root <<'TS_CLOUD_SQL_EOF'`, ...sql, "TS_CLOUD_SQL_EOF"];
10914
10916
  }
10915
- function pgExec(sql) {
10916
- return ["psql -h 127.0.0.1 -p 5432 -U postgres -tA <<'TS_CLOUD_PG_EOF'", ...sql, "TS_CLOUD_PG_EOF"];
10917
+ function pgExec(sql, database) {
10918
+ return [`${pgAdminCommand(database)} -tA <<'TS_CLOUD_PG_EOF'`, ...sql, "TS_CLOUD_PG_EOF"];
10917
10919
  }
10918
- function buildListScript(engine) {
10920
+ function buildListScript(engine, database) {
10919
10921
  if (engine === "postgres") {
10920
10922
  return pgExec([
10921
10923
  "SELECT 'DB=' || datname FROM pg_database WHERE datistemplate = false;",
10922
10924
  "SELECT 'USER=' || usename FROM pg_user;"
10923
- ]);
10925
+ ], database);
10924
10926
  }
10925
10927
  return mysqlExec(engine, [
10926
10928
  "SELECT CONCAT('DB=', schema_name) FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys');",
10927
10929
  "SELECT DISTINCT CONCAT('USER=', User) FROM mysql.user WHERE User NOT IN ('root', 'mysql.sys', 'mysql.session', 'mysql.infoschema', 'debian-sys-maint');"
10928
10930
  ]);
10929
10931
  }
10930
- function buildCreateDatabaseScript(engine, name) {
10932
+ function buildCreateDatabaseScript(engine, name, database) {
10931
10933
  if (engine === "postgres") {
10932
10934
  return pgExec([
10933
10935
  `SELECT 'CREATE DATABASE ${pgIdent(name)}' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = ${pgLit(name)})\\gexec`
10934
- ]);
10936
+ ], database);
10935
10937
  }
10936
10938
  return mysqlExec(engine, [
10937
10939
  `CREATE DATABASE IF NOT EXISTS \`${mysqlIdent(name)}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;`
10938
10940
  ]);
10939
10941
  }
10940
- function buildCreateUserScript(engine, input) {
10941
- const { username, password, database, access: access4 } = input;
10942
+ function buildCreateUserScript(engine, input, database) {
10943
+ const { username, password, database: grantDb, access: access4 } = input;
10942
10944
  if (engine === "postgres") {
10943
10945
  const lines2 = [
10944
10946
  "DO $$ BEGIN",
@@ -10946,10 +10948,10 @@ function buildCreateUserScript(engine, input) {
10946
10948
  ` ELSE ALTER ROLE ${pgIdent(username)} LOGIN PASSWORD ${pgLit(password)}; END IF;`,
10947
10949
  "END $$;"
10948
10950
  ];
10949
- if (database) {
10950
- lines2.push(access4 === "readonly" ? `GRANT CONNECT ON DATABASE ${pgIdent(database)} TO ${pgIdent(username)};` : `GRANT ALL PRIVILEGES ON DATABASE ${pgIdent(database)} TO ${pgIdent(username)};`);
10951
+ if (grantDb) {
10952
+ lines2.push(access4 === "readonly" ? `GRANT CONNECT ON DATABASE ${pgIdent(grantDb)} TO ${pgIdent(username)};` : `GRANT ALL PRIVILEGES ON DATABASE ${pgIdent(grantDb)} TO ${pgIdent(username)};`);
10951
10953
  }
10952
- return pgExec(lines2);
10954
+ return pgExec(lines2, database);
10953
10955
  }
10954
10956
  const priv = access4 === "readonly" ? "SELECT" : "ALL PRIVILEGES";
10955
10957
  const lines = [
@@ -10958,8 +10960,8 @@ function buildCreateUserScript(engine, input) {
10958
10960
  `ALTER USER '${mysqlLit(username)}'@'%' IDENTIFIED BY '${mysqlLit(password)}';`,
10959
10961
  `ALTER USER '${mysqlLit(username)}'@'localhost' IDENTIFIED BY '${mysqlLit(password)}';`
10960
10962
  ];
10961
- if (database) {
10962
- lines.push(`GRANT ${priv} ON \`${mysqlIdent(database)}\`.* TO '${mysqlLit(username)}'@'%';`, `GRANT ${priv} ON \`${mysqlIdent(database)}\`.* TO '${mysqlLit(username)}'@'localhost';`);
10963
+ if (grantDb) {
10964
+ lines.push(`GRANT ${priv} ON \`${mysqlIdent(grantDb)}\`.* TO '${mysqlLit(username)}'@'%';`, `GRANT ${priv} ON \`${mysqlIdent(grantDb)}\`.* TO '${mysqlLit(username)}'@'localhost';`);
10963
10965
  }
10964
10966
  lines.push("FLUSH PRIVILEGES;");
10965
10967
  return mysqlExec(engine, lines);
@@ -11001,24 +11003,24 @@ async function runDb(config6, environment, commands, comment) {
11001
11003
  }
11002
11004
  async function listDatabases(config6, environment) {
11003
11005
  const engine = resolveDbEngine(config6);
11004
- const r = await runDb(config6, environment, buildListScript(engine), "ts-cloud db:list");
11006
+ const r = await runDb(config6, environment, buildListScript(engine, resolveAppDatabase(config6)), "ts-cloud db:list");
11005
11007
  const parsed = r.ok && r.stdout ? parseDbList(r.stdout) : { databases: [], users: [] };
11006
11008
  return { ...r, engine, ...parsed };
11007
11009
  }
11008
11010
  async function createDatabase(config6, environment, name) {
11009
11011
  const engine = resolveDbEngine(config6);
11010
- return runDb(config6, environment, buildCreateDatabaseScript(engine, name), `ts-cloud db:create ${name}`);
11012
+ return runDb(config6, environment, buildCreateDatabaseScript(engine, name, resolveAppDatabase(config6)), `ts-cloud db:create ${name}`);
11011
11013
  }
11012
11014
  async function createDatabaseUser(config6, environment, input) {
11013
11015
  const engine = resolveDbEngine(config6);
11014
- return runDb(config6, environment, buildCreateUserScript(engine, input), `ts-cloud db:user ${input.username}`);
11016
+ return runDb(config6, environment, buildCreateUserScript(engine, input, resolveAppDatabase(config6)), `ts-cloud db:user ${input.username}`);
11015
11017
  }
11016
11018
  var DB_BACKUP_DIR = "/var/backups/ts-cloud/databases";
11017
- function buildBackupScript(engine, name, destDir = DB_BACKUP_DIR) {
11019
+ function buildBackupScript(engine, name, destDir = DB_BACKUP_DIR, database) {
11018
11020
  const file = `${destDir}/${name}-$(date +%Y%m%d-%H%M%S).sql.gz`;
11019
11021
  const mkdir4 = `mkdir -p ${destDir}`;
11020
11022
  if (engine === "postgres")
11021
- return [mkdir4, `pg_dump -h 127.0.0.1 -p 5432 -U postgres ${name} | gzip > "${file}"`, `echo "BACKUP=${file}"`, `ls -l "${file}"`];
11023
+ return [mkdir4, `${pgAdminCommand(database, "pg_dump")} ${name} | gzip > "${file}"`, `echo "BACKUP=${file}"`, `ls -l "${file}"`];
11022
11024
  const sock = engine === "mariadb" ? SOCKETS.mariadb : SOCKETS.mysql;
11023
11025
  return [mkdir4, `mysqldump --socket=${sock} -u root ${name} | gzip > "${file}"`, `echo "BACKUP=${file}"`, `ls -l "${file}"`];
11024
11026
  }
@@ -11044,7 +11046,7 @@ async function backupDatabase(config6, environment, name) {
11044
11046
  if (!isValidDbIdentifier(name))
11045
11047
  return { ok: false, error: "Database name must be a valid identifier.", database: name };
11046
11048
  const engine = resolveDbEngine(config6);
11047
- const r = await runDb(config6, environment, buildBackupScript(engine, name), `ts-cloud db:backup ${name}`);
11049
+ const r = await runDb(config6, environment, buildBackupScript(engine, name, DB_BACKUP_DIR, resolveAppDatabase(config6)), `ts-cloud db:backup ${name}`);
11048
11050
  return { ...r, database: name };
11049
11051
  }
11050
11052
  async function listDatabaseBackups(config6, environment) {
@@ -11626,7 +11628,7 @@ function buildDashboardOperations(config6, data) {
11626
11628
  const backups = config6.infrastructure?.compute?.backups;
11627
11629
  if (backups?.enabled) {
11628
11630
  ops.push({ id: "backup:run", label: "Run backup now", group: "backup", target: "backup", mutates: true, confirm: "backup" });
11629
- if (config6.infrastructure?.appDatabase)
11631
+ if (resolveAppDatabase(config6))
11630
11632
  ops.push({ id: "backup:restore", label: "Restore latest DB backup", group: "backup", target: "database", mutates: true, confirm: "restore", danger: true });
11631
11633
  }
11632
11634
  return ops;
@@ -11702,7 +11704,7 @@ async function runDashboardOperation(config6, environment, operation, options =
11702
11704
  return fromComputeOps(operation.id, `rollback ${operation.target}${to ? ` → ${to}` : ""}`, r);
11703
11705
  }
11704
11706
  if (operation.id === "backup:restore") {
11705
- const r = await restoreDatabaseBackup(ctx, { database: config6.infrastructure?.appDatabase });
11707
+ const r = await restoreDatabaseBackup(ctx, { database: resolveAppDatabase(config6) });
11706
11708
  return fromComputeOps(operation.id, "db restore", r);
11707
11709
  }
11708
11710
  const targets = await driver.findComputeTargets({ slug, environment, role: "app" });
@@ -1140,6 +1140,9 @@ function deploymentCoexistenceError(config) {
1140
1140
  }
1141
1141
  return null;
1142
1142
  }
1143
+ function resolveAppDatabase(config) {
1144
+ return config.infrastructure?.appDatabase ?? config.infrastructure?.compute?.database;
1145
+ }
1143
1146
  function resolveCloudProvider(config) {
1144
1147
  if (config.cloud?.provider)
1145
1148
  return config.cloud.provider;
@@ -46181,4 +46184,4 @@ class ResourceManagementManager {
46181
46184
  }
46182
46185
  var resourceManagementManager = new ResourceManagementManager;
46183
46186
 
46184
- export { detectServiceRegion, signRequest, signRequestAsync, createPresignedUrl, createPresignedUrlAsync, makeAWSRequest, makeAWSRequestOnce, makeAWSRequestAsync, parseXMLResponse, parseJSONResponse, clearSigningKeyCache, getSigningKeyCacheSize, isNodeCryptoAvailable, isWebCryptoAvailable, QueuePresets, RealtimePresets, detectDeploymentTargets, resolveDeploymentMode, deploymentCoexistenceError, resolveCloudProvider, TemplateBuilder, Pseudo, generateResourceName, generateLogicalId, getTimestamp, sanitizeName, resolveProjectStackName, resolveSiteStackName, resolveSiteResourceName, resolveSiteBucketName, resolveStorageBucketName, resolveDeployBucketName, resolveServerlessAppStackName, resolveServerlessArtifactBucketName, resolveServerlessAssetBucketName, DependencyGraph, analyzeStackDiff, formatDiff, Storage, Registry, CDN, DNS, Security, Compute, Network, FileSystem, Email, exports_incoming_call, Phone, Queue, JobLoader, StacksIntegration, exports_send, SMS, AI, Database, Cache, Permissions, ApiGateway, Messaging, Workflow, Monitoring, Auth, Deployment, AssetHasher, Secrets, ParameterStore, Search, Redirects, Communication, Fn2, Arn, AWS_PSEUDO_PARAMETERS, CloudFormationBuilder, buildCloudFormationTemplate, createStaticSitePreset, createNodeJsServerPreset, createNodeJsServerlessPreset, createServerlessNodePreset, createFullStackAppPreset, createApiBackendPreset, createWordPressPreset, createJamstackPreset, createMicroservicesPreset, createRealtimeAppPreset, createDataPipelinePreset, createMLApiPreset, createTraditionalWebAppPreset, createLaravelPreset, createServerlessLaravelPreset, createDashboardSite, DASHBOARD_STATE_DIR, DASHBOARD_ENTRY, DASHBOARD_PORT_BASE, DASHBOARD_PORT_SPAN, deriveManagementDashboardPort, resolveDashboardDomain, resolveDashboardDomains, hasManagementDashboardSite, MANAGEMENT_DASHBOARD_SITE_PREFIX, managementDashboardSiteName, isManagementDashboardSiteName, resolveManagementDashboardSites, resolveManagementDashboardSite, extendPreset, composePresets, createPreset, mergeInfrastructure, withMonitoring, withSecurity, withDatabase, withCache, withCDN, withQueue, fromEnvironment, fromSharedCredentials, fromEC2Metadata, fromECSMetadata, fromWebIdentity, getCredentials, createCredentialProvider, resolveCredentials, resolveRegion, getAccountId, S3Error, createS3Client, CloudError, ConfigurationError, CredentialError, DeploymentError, ValidationError, AWSAPIError, ErrorCodes, getErrorDetails, createError, DebugLogger, validateConfiguration, detectMisconfigurations, validateCredentials, checkIAMPermissions, getRequiredPermissions, suggestIAMPolicy, DEFAULT_SERVICE_LIMITS, checkServiceQuotas, getQuotaUsageSummary, suggestQuotaIncrease, FileCache, TemplateCache, templateCache, hashFile, hashString, hashBuffer, hashDirectory, hashManifest, quickHash, findChangedFiles, HashCache, parallel, batch, parallelMap, parallelWithRetry, sequence, withTimeout, RateLimiter, chunk, processInChunks, diffTemplates, getDiffSummary, requiresReplacement, categorizeChanges, getDeploymentStrategy, getDiffStats, cloud_config_schema_default, validateAgainstSchema, defaultLocalConfig, getLocalConfig, isLocalDevelopment, getLocalEndpoint, getLocalCredentials, getLocalEnvVars, MockCloudFormation, MockS3, MockDynamoDB, createMockAWS, PreviewEnvironmentManager, previewManager, generatePreviewWorkflow, generateCleanupWorkflow, generateCostReportWorkflow, PreviewNotificationService, previewNotifications, formatTable, formatTree, formatProgressBar, formatBytes, formatDuration, formatList, formatKeyValue, ProgressBar, MultiStepProgress, Spinner, TaskList, suggestCommand, formatSuggestion, isLikelyTypo, getContextualHelp, searchCommands, autocomplete, suggestFlags, formatFlagSuggestions, getCommandUsage, validateCommand, REPL, REPLContext, REPLCommandBuilder, CommandHistory, formatHistory, formatHistoryStats, MultiRegionManager, multiRegionManager, CrossRegionReferenceManager, GlobalResourceManager, RegionPairManager, StackDependencyManager, crossRegionReferenceManager, globalResourceManager, regionPairManager, stackDependencyManager, AWS_REGIONS, getRegion, getAllRegions, getRegionsByLocation, getRegionsByCompliance, getRegionsByPricingTier, isValidRegion, getClosestRegion, suggestRegions, suggestRegionPairs, formatRegion, formatRegionList, getRegionStats, MultiAccountManager, OrganizationManager, multiAccountManager, organizationManager, RECOMMENDED_ACCOUNT_STRUCTURES, RECOMMENDED_SCPS, COMMON_CROSS_ACCOUNT_ROLES, getRecommendedStructure, generateCrossAccountRoleCF, validateAccountStructure, formatAccountStructure, generateDeploymentWorkflow, generateMultiEnvWorkflow, generatePRPreviewWorkflow, generateScheduledWorkflow, generateMatrixWorkflow, generateDeploymentPipeline, generateMultiEnvPipeline, generatePreviewPipeline, generateScheduledPipeline, generateManualPipeline, generateDeploymentConfig, generateMultiEnvConfig, generateScheduledConfig, generateApprovalConfig, generateParallelConfig, BackupManager, backupManager, DisasterRecoveryManager, drManager, AWSConfigManager, awsConfigManager, CloudTrailManager, cloudTrailManager, GuardDutyManager, guardDutyManager, SecurityHubManager, securityHubManager, BlueGreenManager, blueGreenManager, CanaryManager, canaryManager, ABTestManager, abTestManager, ProgressiveDeploymentManager, progressiveDeploymentManager, XRayManager, xrayManager, MetricsManager, metricsManager, LogsManager, logsManager, SyntheticsManager, syntheticsManager, MigrationManager, migrationManager, ReplicaManager, replicaManager, PerformanceManager, performanceManager, DatabaseUserManager, databaseUserManager, SecretsRotationManager, secretsRotationManager, SecretsManager, secretsManager, CertificateManager, certificateManager, SecurityScanningManager, securityScanningManager, ImageScanningManager, imageScanningManager, BuildOptimizationManager, buildOptimizationManager, ContainerRegistryManager, containerRegistryManager, ServiceMeshManager, serviceMeshManager, LambdaLayersManager, lambdaLayersManager, LambdaVersionsManager, lambdaVersionsManager, LambdaConcurrencyManager, lambdaConcurrencyManager, LambdaDestinationsManager, lambdaDestinationsManager, LambdaVPCManager, lambdaVPCManager, LambdaDLQManager, lambdaDLQManager, Route53RoutingManager, route53RoutingManager, DNSSECManager, dnssecManager, Route53ResolverManager, route53ResolverManager, BounceComplaintHandler, bounceComplaintHandler, EmailAnalyticsManager, emailAnalyticsManager, SenderReputationManager, senderReputationManager, EmailTemplateManager, emailTemplateManager, exports_advanced, exports_inbound, exports_advanced2, exports_advanced3, FIFOQueueManager, fifoQueueManager, DLQMonitoringManager, dlqMonitoringManager, BatchProcessingManager, batchProcessingManager, QueueManagementManager, queueManagementManager, createZip, generateBootstrap, runBuildHooks, sha256, artifactKey, packageServerlessApp, MANAGED_NODE_VERSIONS, resolveServerlessRuntime, resolveQueues, resolveQueueNames, composeServerlessAppTemplate, PHP_LAYER_EXTENSIONS, phpLayerPackages, phpLayerBuildStage, generatePhpLayerDockerfile, generateAppImageDockerfile, sharedRuntimeLoop, buildNodeRuntimeLayerZip, buildBunRuntimeLayerZip, resolveApp, eventToRequest, responseToResult, createHttpHandler, createQueueHandler, createCliHandler, createHandlers, generatePhpFpmConfig, phpRuntimeLayerAssets, laravelServerlessEnvDefaults, LARAVEL_SERVERLESS_BUILD_STEPS, buildPhpRuntimeLayerZip, PHP_DEFAULT_EXCLUDES, runPhpBuildHooks, collectPhpAppEntries, packagePhpApp, StaticSiteManager, staticSiteManager, StorageAdvancedManager, storageAdvancedManager, HealthCheckManager, healthCheckManager, NetworkSecurityManager, networkSecurityManager, ResourceManagementManager, resourceManagementManager };
46187
+ export { detectServiceRegion, signRequest, signRequestAsync, createPresignedUrl, createPresignedUrlAsync, makeAWSRequest, makeAWSRequestOnce, makeAWSRequestAsync, parseXMLResponse, parseJSONResponse, clearSigningKeyCache, getSigningKeyCacheSize, isNodeCryptoAvailable, isWebCryptoAvailable, QueuePresets, RealtimePresets, detectDeploymentTargets, resolveDeploymentMode, deploymentCoexistenceError, resolveAppDatabase, resolveCloudProvider, TemplateBuilder, Pseudo, generateResourceName, generateLogicalId, getTimestamp, sanitizeName, resolveProjectStackName, resolveSiteStackName, resolveSiteResourceName, resolveSiteBucketName, resolveStorageBucketName, resolveDeployBucketName, resolveServerlessAppStackName, resolveServerlessArtifactBucketName, resolveServerlessAssetBucketName, DependencyGraph, analyzeStackDiff, formatDiff, Storage, Registry, CDN, DNS, Security, Compute, Network, FileSystem, Email, exports_incoming_call, Phone, Queue, JobLoader, StacksIntegration, exports_send, SMS, AI, Database, Cache, Permissions, ApiGateway, Messaging, Workflow, Monitoring, Auth, Deployment, AssetHasher, Secrets, ParameterStore, Search, Redirects, Communication, Fn2, Arn, AWS_PSEUDO_PARAMETERS, CloudFormationBuilder, buildCloudFormationTemplate, createStaticSitePreset, createNodeJsServerPreset, createNodeJsServerlessPreset, createServerlessNodePreset, createFullStackAppPreset, createApiBackendPreset, createWordPressPreset, createJamstackPreset, createMicroservicesPreset, createRealtimeAppPreset, createDataPipelinePreset, createMLApiPreset, createTraditionalWebAppPreset, createLaravelPreset, createServerlessLaravelPreset, createDashboardSite, DASHBOARD_STATE_DIR, DASHBOARD_ENTRY, DASHBOARD_PORT_BASE, DASHBOARD_PORT_SPAN, deriveManagementDashboardPort, resolveDashboardDomain, resolveDashboardDomains, hasManagementDashboardSite, MANAGEMENT_DASHBOARD_SITE_PREFIX, managementDashboardSiteName, isManagementDashboardSiteName, resolveManagementDashboardSites, resolveManagementDashboardSite, extendPreset, composePresets, createPreset, mergeInfrastructure, withMonitoring, withSecurity, withDatabase, withCache, withCDN, withQueue, fromEnvironment, fromSharedCredentials, fromEC2Metadata, fromECSMetadata, fromWebIdentity, getCredentials, createCredentialProvider, resolveCredentials, resolveRegion, getAccountId, S3Error, createS3Client, CloudError, ConfigurationError, CredentialError, DeploymentError, ValidationError, AWSAPIError, ErrorCodes, getErrorDetails, createError, DebugLogger, validateConfiguration, detectMisconfigurations, validateCredentials, checkIAMPermissions, getRequiredPermissions, suggestIAMPolicy, DEFAULT_SERVICE_LIMITS, checkServiceQuotas, getQuotaUsageSummary, suggestQuotaIncrease, FileCache, TemplateCache, templateCache, hashFile, hashString, hashBuffer, hashDirectory, hashManifest, quickHash, findChangedFiles, HashCache, parallel, batch, parallelMap, parallelWithRetry, sequence, withTimeout, RateLimiter, chunk, processInChunks, diffTemplates, getDiffSummary, requiresReplacement, categorizeChanges, getDeploymentStrategy, getDiffStats, cloud_config_schema_default, validateAgainstSchema, defaultLocalConfig, getLocalConfig, isLocalDevelopment, getLocalEndpoint, getLocalCredentials, getLocalEnvVars, MockCloudFormation, MockS3, MockDynamoDB, createMockAWS, PreviewEnvironmentManager, previewManager, generatePreviewWorkflow, generateCleanupWorkflow, generateCostReportWorkflow, PreviewNotificationService, previewNotifications, formatTable, formatTree, formatProgressBar, formatBytes, formatDuration, formatList, formatKeyValue, ProgressBar, MultiStepProgress, Spinner, TaskList, suggestCommand, formatSuggestion, isLikelyTypo, getContextualHelp, searchCommands, autocomplete, suggestFlags, formatFlagSuggestions, getCommandUsage, validateCommand, REPL, REPLContext, REPLCommandBuilder, CommandHistory, formatHistory, formatHistoryStats, MultiRegionManager, multiRegionManager, CrossRegionReferenceManager, GlobalResourceManager, RegionPairManager, StackDependencyManager, crossRegionReferenceManager, globalResourceManager, regionPairManager, stackDependencyManager, AWS_REGIONS, getRegion, getAllRegions, getRegionsByLocation, getRegionsByCompliance, getRegionsByPricingTier, isValidRegion, getClosestRegion, suggestRegions, suggestRegionPairs, formatRegion, formatRegionList, getRegionStats, MultiAccountManager, OrganizationManager, multiAccountManager, organizationManager, RECOMMENDED_ACCOUNT_STRUCTURES, RECOMMENDED_SCPS, COMMON_CROSS_ACCOUNT_ROLES, getRecommendedStructure, generateCrossAccountRoleCF, validateAccountStructure, formatAccountStructure, generateDeploymentWorkflow, generateMultiEnvWorkflow, generatePRPreviewWorkflow, generateScheduledWorkflow, generateMatrixWorkflow, generateDeploymentPipeline, generateMultiEnvPipeline, generatePreviewPipeline, generateScheduledPipeline, generateManualPipeline, generateDeploymentConfig, generateMultiEnvConfig, generateScheduledConfig, generateApprovalConfig, generateParallelConfig, BackupManager, backupManager, DisasterRecoveryManager, drManager, AWSConfigManager, awsConfigManager, CloudTrailManager, cloudTrailManager, GuardDutyManager, guardDutyManager, SecurityHubManager, securityHubManager, BlueGreenManager, blueGreenManager, CanaryManager, canaryManager, ABTestManager, abTestManager, ProgressiveDeploymentManager, progressiveDeploymentManager, XRayManager, xrayManager, MetricsManager, metricsManager, LogsManager, logsManager, SyntheticsManager, syntheticsManager, MigrationManager, migrationManager, ReplicaManager, replicaManager, PerformanceManager, performanceManager, DatabaseUserManager, databaseUserManager, SecretsRotationManager, secretsRotationManager, SecretsManager, secretsManager, CertificateManager, certificateManager, SecurityScanningManager, securityScanningManager, ImageScanningManager, imageScanningManager, BuildOptimizationManager, buildOptimizationManager, ContainerRegistryManager, containerRegistryManager, ServiceMeshManager, serviceMeshManager, LambdaLayersManager, lambdaLayersManager, LambdaVersionsManager, lambdaVersionsManager, LambdaConcurrencyManager, lambdaConcurrencyManager, LambdaDestinationsManager, lambdaDestinationsManager, LambdaVPCManager, lambdaVPCManager, LambdaDLQManager, lambdaDLQManager, Route53RoutingManager, route53RoutingManager, DNSSECManager, dnssecManager, Route53ResolverManager, route53ResolverManager, BounceComplaintHandler, bounceComplaintHandler, EmailAnalyticsManager, emailAnalyticsManager, SenderReputationManager, senderReputationManager, EmailTemplateManager, emailTemplateManager, exports_advanced, exports_inbound, exports_advanced2, exports_advanced3, FIFOQueueManager, fifoQueueManager, DLQMonitoringManager, dlqMonitoringManager, BatchProcessingManager, batchProcessingManager, QueueManagementManager, queueManagementManager, createZip, generateBootstrap, runBuildHooks, sha256, artifactKey, packageServerlessApp, MANAGED_NODE_VERSIONS, resolveServerlessRuntime, resolveQueues, resolveQueueNames, composeServerlessAppTemplate, PHP_LAYER_EXTENSIONS, phpLayerPackages, phpLayerBuildStage, generatePhpLayerDockerfile, generateAppImageDockerfile, sharedRuntimeLoop, buildNodeRuntimeLayerZip, buildBunRuntimeLayerZip, resolveApp, eventToRequest, responseToResult, createHttpHandler, createQueueHandler, createCliHandler, createHandlers, generatePhpFpmConfig, phpRuntimeLayerAssets, laravelServerlessEnvDefaults, LARAVEL_SERVERLESS_BUILD_STEPS, buildPhpRuntimeLayerZip, PHP_DEFAULT_EXCLUDES, runPhpBuildHooks, collectPhpAppEntries, packagePhpApp, StaticSiteManager, staticSiteManager, StorageAdvancedManager, storageAdvancedManager, HealthCheckManager, healthCheckManager, NetworkSecurityManager, networkSecurityManager, ResourceManagementManager, resourceManagementManager };
@@ -8,7 +8,7 @@ import {
8
8
  phpRuntimeLayerAssets,
9
9
  runPhpBuildHooks,
10
10
  sha256
11
- } from "./chunk-k56wpkhg.js";
11
+ } from "./chunk-stt1z5cx.js";
12
12
 
13
13
  // src/deploy/serverless-image.ts
14
14
  import { execFileSync } from "node:child_process";
@@ -4,20 +4,20 @@
4
4
  * the pantry UNIX socket; Postgres over local TCP — mirroring the provisioning
5
5
  * path in {@link import('../drivers/shared/db-provision')}.
6
6
  */
7
- import type { CloudConfig, EnvironmentType } from '@ts-cloud/core';
7
+ import type { CloudConfig, DatabaseConfig, EnvironmentType } from '@ts-cloud/core';
8
8
  export type DbEngine = 'mysql' | 'mariadb' | 'postgres';
9
9
  /** Valid SQL identifier for a database/user name (kept strict for safety). */
10
10
  export declare function isValidDbIdentifier(value: string): boolean;
11
11
  export declare function resolveDbEngine(config: CloudConfig): DbEngine;
12
- export declare function buildListScript(engine: DbEngine): string[];
13
- export declare function buildCreateDatabaseScript(engine: DbEngine, name: string): string[];
12
+ export declare function buildListScript(engine: DbEngine, database?: DatabaseConfig): string[];
13
+ export declare function buildCreateDatabaseScript(engine: DbEngine, name: string, database?: DatabaseConfig): string[];
14
14
  export interface CreateUserInput {
15
15
  username: string;
16
16
  password: string;
17
17
  database?: string;
18
18
  access?: 'all' | 'readonly';
19
19
  }
20
- export declare function buildCreateUserScript(engine: DbEngine, input: CreateUserInput): string[];
20
+ export declare function buildCreateUserScript(engine: DbEngine, input: CreateUserInput, database?: DatabaseConfig): string[];
21
21
  export declare function parseDbList(output: string): {
22
22
  databases: string[];
23
23
  users: string[];
@@ -40,9 +40,11 @@ export declare const DB_BACKUP_DIR = "/var/backups/ts-cloud/databases";
40
40
  /**
41
41
  * Script that dumps a single database to a timestamped, gzipped file. The name
42
42
  * is a validated SQL identifier (no shell metacharacters), so it is safe to
43
- * embed directly. The timestamp is computed on the box.
43
+ * embed directly. The timestamp is computed on the box. Postgres connects over
44
+ * the local unix socket for a co-located engine, or TCP with credentials for
45
+ * an external host (see {@link pgAdminCommand}).
44
46
  */
45
- export declare function buildBackupScript(engine: DbEngine, name: string, destDir?: string): string[];
47
+ export declare function buildBackupScript(engine: DbEngine, name: string, destDir?: string, database?: DatabaseConfig): string[];
46
48
  /** Script that lists the most recent dumps (newest first). */
47
49
  export declare function buildListBackupsScript(destDir?: string): string[];
48
50
  export declare function parseBackups(output: string): Array<{
@@ -12,10 +12,10 @@ import {
12
12
  sanitizeCloudConfig,
13
13
  setMaintenance,
14
14
  startLocalDashboardServer
15
- } from "../chunk-rr3j38qr.js";
15
+ } from "../chunk-jgenfdz6.js";
16
16
  import {
17
17
  buildAndPushServerlessImage
18
- } from "../chunk-3mcfbrw8.js";
18
+ } from "../chunk-tskj9fay.js";
19
19
  import"../chunk-b82pbxyp.js";
20
20
  import"../chunk-hsk6fe6x.js";
21
21
  import {
@@ -30,8 +30,8 @@ import {
30
30
  resolveUiSource,
31
31
  siteInstallBase,
32
32
  validateDeploymentConfig
33
- } from "../chunk-xdd6qvre.js";
34
- import"../chunk-k56wpkhg.js";
33
+ } from "../chunk-dah449r1.js";
34
+ import"../chunk-stt1z5cx.js";
35
35
  import"../chunk-93hjhs78.js";
36
36
  import {
37
37
  deleteStaticSite,
@@ -144,6 +144,14 @@ export declare class HetznerClient {
144
144
  private fetchImpl;
145
145
  constructor(options: HetznerClientOptions);
146
146
  private request;
147
+ /**
148
+ * Fetch every page of a list endpoint. Hetzner paginates lists at 25 items by
149
+ * default (max 50/page) and follows `meta.pagination.next_page`; without this,
150
+ * an account with more than one page of resources silently truncates — target
151
+ * lookups miss the project's own servers, and find-or-create attempts a
152
+ * duplicate create (409) for firewalls/keys that already exist.
153
+ */
154
+ private requestAll;
147
155
  listServers(): Promise<HetznerServer[]>;
148
156
  getServer(id: number): Promise<HetznerServer>;
149
157
  createServer(options: CreateServerOptions): Promise<{
@@ -93,6 +93,22 @@ export declare class HetznerDriver implements CloudDriver {
93
93
  private ensureSshKey;
94
94
  /** getServer that returns null instead of throwing when the server is gone. */
95
95
  private tryGetServer;
96
+ /**
97
+ * Rewrite a bun-fleet LB box's rpx route fragment (`sites.d/<slug>.json`)
98
+ * from the CURRENT sites model and the CURRENT app-box upstreams, then
99
+ * restart the gateway so the assembler re-merges. The LB box long outlives
100
+ * any single provision — without this refresh, the routes frozen at its
101
+ * first boot never learn about sites added/removed later or a changed
102
+ * app-fleet upstream set.
103
+ *
104
+ * App boxes without a routable address are dropped from the upstream list;
105
+ * when NO app box is routable the refresh is skipped entirely — rewriting
106
+ * the fragment with zero real upstreams would turn every route into a
107
+ * guaranteed 502, strictly worse than leaving the stale fragment in place.
108
+ * An SSH failure propagates: a deploy that cannot reach its LB to update
109
+ * routes must fail loudly, not silently serve stale ones.
110
+ */
111
+ private refreshLbRoutes;
96
112
  /**
97
113
  * Look up an existing ts-cloud server for this project/environment by labels
98
114
  * (falling back to name match). Used for idempotency when local state is
@@ -10,9 +10,9 @@ export { buildSshArgs, scpUpload, sshExec, sshExecOrThrow, waitForCloudInit, wai
10
10
  export type { RemoteExecOptions, RemoteExecResult, WaitOptions } from './shared/remote-exec';
11
11
  export { AwsBoxProvisioner, buildBoxUserData, createBoxProvisioner, HetznerBoxProvisioner, UBUNTU_2404_AMI_PARAM, } from './shared/box-provision';
12
12
  export type { AwsBoxProvisionerOptions, BoxPort, BoxProviderName, BoxProvisioner, BoxSpec, CreateBoxProvisionerOptions, ProvisionedBox, } from './shared/box-provision';
13
- export { buildAwsArtifactFetch, buildLocalArtifactFetch, buildSiteDeployScript, buildStaticSiteDeployScript, resolveExecStart, } from './shared/deploy-script';
13
+ export { buildAwsArtifactFetch, buildLocalArtifactFetch, buildSiteDeployScript, buildStaticSiteDeployScript, releaseTarballTmpPath, resolveExecStart, } from './shared/deploy-script';
14
14
  export { deployAllComputeSites, deploySiteRelease, reloadRpxGateway } from './shared/compute-deploy';
15
- export { buildRpxConfig, buildRpxLbConfig, buildRpxProvisionScript, deriveRouteId, normalizeRoutePath, renderRpxLauncher, DEFAULT_RPX_CERTS_DIR, RPX_DIR, RPX_LAUNCHER_PATH, RPX_SERVICE_NAME, } from './shared/rpx-gateway';
16
- export type { BuildRpxConfigOptions, BuildRpxProvisionOptions, RpxGatewayConfig, RpxLbAppBox, RpxRoute, } from './shared/rpx-gateway';
15
+ export { buildRpxConfig, buildRpxFragmentRefreshScript, buildRpxLbConfig, buildRpxProvisionScript, deriveRouteId, normalizeRoutePath, renderRpxLauncher, DEFAULT_RPX_CERTS_DIR, RPX_DIR, RPX_LAUNCHER_PATH, RPX_SERVICE_NAME, } from './shared/rpx-gateway';
16
+ export type { BuildRpxConfigOptions, BuildRpxFragmentRefreshOptions, BuildRpxProvisionOptions, RpxGatewayConfig, RpxLbAppBox, RpxRoute, } from './shared/rpx-gateway';
17
17
  export { buildCloudFrontOriginConfig, MANAGED_CACHE_POLICY_DISABLED, MANAGED_CACHE_POLICY_OPTIMIZED, MANAGED_ORIGIN_REQUEST_POLICY_ALL_VIEWER, } from './shared/cloudfront-origin';
18
18
  export type { BuildCloudFrontOriginOptions, OriginFrontedBehavior, } from './shared/cloudfront-origin';
@@ -19,6 +19,7 @@ import {
19
19
  buildCloudFrontOriginConfig,
20
20
  buildLocalArtifactFetch,
21
21
  buildRpxConfig,
22
+ buildRpxFragmentRefreshScript,
22
23
  buildRpxLbConfig,
23
24
  buildRpxProvisionScript,
24
25
  buildSiteDeployScript,
@@ -37,6 +38,7 @@ import {
37
38
  isBoxMode,
38
39
  normalizeRoutePath,
39
40
  normalizeSshPublicKey,
41
+ releaseTarballTmpPath,
40
42
  reloadRpxGateway,
41
43
  renderRpxLauncher,
42
44
  resolveExecStart,
@@ -48,8 +50,8 @@ import {
48
50
  waitForCloudInit,
49
51
  waitForSsh,
50
52
  wrapCloudInitUserData
51
- } from "../chunk-xdd6qvre.js";
52
- import"../chunk-k56wpkhg.js";
53
+ } from "../chunk-dah449r1.js";
54
+ import"../chunk-stt1z5cx.js";
53
55
  import"../chunk-93hjhs78.js";
54
56
  import"../chunk-qpj3edwz.js";
55
57
  import"../chunk-vd87cpvn.js";
@@ -67,6 +69,7 @@ export {
67
69
  resolveExecStart,
68
70
  renderRpxLauncher,
69
71
  reloadRpxGateway,
72
+ releaseTarballTmpPath,
70
73
  normalizeSshPublicKey,
71
74
  normalizeRoutePath,
72
75
  isBoxMode,
@@ -85,6 +88,7 @@ export {
85
88
  buildSiteDeployScript,
86
89
  buildRpxProvisionScript,
87
90
  buildRpxLbConfig,
91
+ buildRpxFragmentRefreshScript,
88
92
  buildRpxConfig,
89
93
  buildLocalArtifactFetch,
90
94
  buildCloudFrontOriginConfig,
@@ -13,7 +13,7 @@ export declare class LocalBoxDriver implements CloudDriver {
13
13
  readonly usesCloudFormation = false;
14
14
  getComputeOutputs(): Promise<ComputeStackOutputs>;
15
15
  uploadRelease(options: UploadReleaseOptions): Promise<UploadReleaseResult>;
16
- findComputeTargets(_options: FindComputeTargetsOptions): Promise<ComputeTarget[]>;
16
+ findComputeTargets(options: FindComputeTargetsOptions): Promise<ComputeTarget[]>;
17
17
  runRemoteDeploy(options: RunRemoteDeployOptions): Promise<RemoteDeployResult>;
18
18
  }
19
19
  /** Truthy-env check shared by the box-mode gate. */
@@ -34,7 +34,9 @@ export interface BackupRestoreOptions {
34
34
  * Build the commands that restore a database from a ts-backups dump on the box.
35
35
  * With no `from`, the newest dump under {@link BACKUP_OUTPUT_DIR} matching the
36
36
  * database name is used. Handles plain `.sql` and gzipped `.sql.gz`. MySQL/
37
- * MariaDB restore over the root unix socket; Postgres via `psql -U postgres`.
37
+ * MariaDB restore over the root unix socket; Postgres over the local unix
38
+ * socket for a co-located engine, or TCP with credentials for an external
39
+ * host (see {@link pgAdminCommand}).
38
40
  * Returns `[]` when the database has no name.
39
41
  */
40
42
  export declare function buildBackupRestoreScript(database: DatabaseConfig | undefined, options?: BackupRestoreOptions): string[];
@@ -36,8 +36,14 @@ export interface DeployAllSitesOptions {
36
36
  export declare function deployAllComputeSites(options: DeployAllSitesOptions): Promise<boolean>;
37
37
  /**
38
38
  * Regenerate the rpx gateway config from the sites model and (re)start the
39
- * gateway on the compute targets. No-op (returns `true`) unless
40
- * `compute.proxy.engine === 'rpx'`. Re-runnable: the provision script writes the
41
- * launcher + unit and `systemctl restart`s, which reloads the new routes.
39
+ * gateway. No-op (returns `true`) unless `compute.proxy.engine === 'rpx'`.
40
+ *
41
+ * Two shapes, resolved by probing for a dedicated load-balancer target:
42
+ * - **Fleet** (bun-style: one rpx LB box fronts N gateway-less app boxes) —
43
+ * rewrite ONLY the LB's route fragment with the multi-upstream LB config
44
+ * ({@link buildRpxLbConfig} + {@link buildRpxFragmentRefreshScript}).
45
+ * - **Single box** — the gateway is co-located with the app, so the full
46
+ * provision script runs on the app targets. Re-runnable: it rewrites the
47
+ * launcher + unit and `systemctl restart`s, reloading the new routes.
42
48
  */
43
49
  export declare function reloadRpxGateway(options: DeployAllSitesOptions): Promise<boolean>;
@@ -6,10 +6,32 @@
6
6
  * install nothing and just wire `.env` — see {@link buildManagedDbEnv}.
7
7
  *
8
8
  * pantry services listen on TCP localhost ports (mysql/mariadb 3306, postgres
9
- * 5432, redis 6379, memcached 11211, meilisearch 7700); DB setup connects over
10
- * TCP, and the engine clients are on PATH via `pantry env`.
9
+ * 5432, redis 6379, memcached 11211, meilisearch 7700) and the engine clients
10
+ * are on PATH via `pantry env`. Admin commands (db setup, dumps, restores)
11
+ * connect over the engine's local unix socket — see {@link pgAdminCommand}.
11
12
  */
12
13
  import type { ComputeServicesConfig, DatabaseConfig } from '@ts-cloud/core';
14
+ /**
15
+ * True when the database is co-located with the box (the managed-services
16
+ * engine): no host configured, or an explicit loopback host. Anything else is
17
+ * an external/managed database reached over TCP.
18
+ */
19
+ export declare function isLocalDatabase(database: DatabaseConfig | undefined): boolean;
20
+ /**
21
+ * Build the connection prefix for a postgres admin command (`psql`/`pg_dump`)
22
+ * run on the box.
23
+ *
24
+ * The pantry postgres pg_hba grants `trust` on the local unix socket but
25
+ * requires md5 password auth over TCP loopback — and the `postgres` superuser
26
+ * has no password — so against the co-located engine admin clients MUST use
27
+ * the socket: omit `-h` entirely and the pantry client uses its compiled-in
28
+ * default socket dir, which matches the server's by construction (verified
29
+ * on-box: `psql -U postgres` from root connects passwordless). Against an
30
+ * external/managed host, use TCP with the configured credentials
31
+ * (`PGPASSWORD` inline + `-w`, so a missing password fails fast instead of
32
+ * prompting forever).
33
+ */
34
+ export declare function pgAdminCommand(database: DatabaseConfig | undefined, tool?: 'psql' | 'pg_dump'): string;
13
35
  /**
14
36
  * Build pantry install + enable/start commands for each requested on-box
15
37
  * service. Idempotent (pantry install/enable/start are no-ops when satisfied).
@@ -77,6 +77,8 @@ export interface BuildSiteDeployScriptOptions {
77
77
  export declare function buildSiteDeployScript(options: BuildSiteDeployScriptOptions): string[];
78
78
  export interface BuildStaticSiteDeployScriptOptions {
79
79
  siteName: string;
80
+ /** Project slug — namespaces the staged tarball on shared boxes. */
81
+ slug?: string;
80
82
  /** How the remote host obtains the release tarball */
81
83
  artifactFetch: string[];
82
84
  /** Site base dir holding `releases/`, `current`. Default `/var/www/<site>`. */
@@ -101,5 +103,13 @@ export interface BuildStaticSiteDeployScriptOptions {
101
103
  * tlsx), which ts-cloud points at the symlink. Old releases are pruned.
102
104
  */
103
105
  export declare function buildStaticSiteDeployScript(options: BuildStaticSiteDeployScriptOptions): string[];
104
- export declare function buildAwsArtifactFetch(bucket: string, key: string, region: string, siteName: string): string[];
105
- export declare function buildLocalArtifactFetch(localPath: string, siteName: string): string[];
106
+ /**
107
+ * Box-local staging path for the uploaded release tarball. Namespaced by
108
+ * project slug + site + release id so two projects sharing a box (or two
109
+ * overlapping deploys of one site) never clobber each other's tarball between
110
+ * the fetch and the extract — the flat `/tmp/<site>-release.tar.gz` layout
111
+ * cross-contaminated releases on shared boxes.
112
+ */
113
+ export declare function releaseTarballTmpPath(slug: string | undefined, siteName: string, releaseId: string): string;
114
+ export declare function buildAwsArtifactFetch(bucket: string, key: string, region: string, destPath: string): string[];
115
+ export declare function buildLocalArtifactFetch(localPath: string, destPath: string): string[];
@@ -12,7 +12,7 @@
12
12
  * private network, and (required) a dedicated services box so every app server
13
13
  * shares one database/cache.
14
14
  */
15
- import type { ComputeConfig, DatabaseConfig } from '@ts-cloud/core';
15
+ import type { CloudConfig, ComputeConfig, DatabaseConfig } from '@ts-cloud/core';
16
16
  export type FleetRole = 'app' | 'services' | 'lb';
17
17
  export interface FleetTopology {
18
18
  /** Number of application servers. */
@@ -32,3 +32,14 @@ export declare function resolveFleetTopology(compute?: ComputeConfig): FleetTopo
32
32
  * under `site.env` (explicit values win).
33
33
  */
34
34
  export declare function buildFleetServicesEnv(servicesPrivateIp: string, database?: DatabaseConfig): Record<string, string>;
35
+ /**
36
+ * Build the provision commands for a fleet's dedicated services box (DB /
37
+ * cache / search only — no app runtime, no gateway). Shared by the PHP fleet
38
+ * and the bun/node/deno fleet so the two paths can never drift: engine
39
+ * installs bound to the private network, the app database + user, box
40
+ * maintenance, the on-box notifier (so the monitoring cron can report — a
41
+ * no-op unless notifications are configured), and — when `compute.backups`
42
+ * is enabled — the nightly DB backup, which MUST run here (where the
43
+ * database lives), never on an app box.
44
+ */
45
+ export declare function buildFleetServicesBoxProvision(config: CloudConfig): string[];
@@ -297,3 +297,29 @@ export declare function buildCertManagementCommands(options: BuildRpxProvisionOp
297
297
  * server-app/server-static sites appear in the gateway automatically.
298
298
  */
299
299
  export declare function buildRpxProvisionScript(options: BuildRpxProvisionOptions): string[];
300
+ export interface BuildRpxFragmentRefreshOptions {
301
+ /** The gateway config this deploy resolved (single-box or LB multi-upstream). */
302
+ config: RpxGatewayConfig;
303
+ /**
304
+ * This project's slug — the registry fragment is rewritten at
305
+ * `<sites.d>/<slug>.json`, exactly as in {@link buildRpxProvisionScript}.
306
+ * Defaults to `'app'`.
307
+ */
308
+ slug?: string;
309
+ }
310
+ /**
311
+ * Build the shell commands that rewrite ONLY this app's rpx route fragment
312
+ * (`<sites.d>/<slug>.json`) and restart the gateway, so the running assembler
313
+ * re-merges every fragment and the new routes go live.
314
+ *
315
+ * Unlike {@link buildRpxProvisionScript} this does NOT reinstall rpx/tlsx,
316
+ * rewrite the assembler launcher, or touch the systemd unit — it is the cheap
317
+ * reload for a box whose gateway is already provisioned. That is exactly the
318
+ * bun-fleet load-balancer situation: the LB box is created once (cloud-init
319
+ * writes the fragment at first boot) but long outlives any single deploy, so
320
+ * its routes must be refreshed from the CURRENT sites model + CURRENT app-box
321
+ * upstreams on every provision/deploy — otherwise sites added later 404 and
322
+ * app-fleet scale changes never reach the gateway. The `systemctl restart`
323
+ * re-runs the stable assembler, which re-reads all of {@link RPX_SITES_DIR}.
324
+ */
325
+ export declare function buildRpxFragmentRefreshScript(options: BuildRpxFragmentRefreshOptions): string[];
@@ -15,7 +15,8 @@ export interface AuthorizedKeysOptions {
15
15
  }
16
16
  /**
17
17
  * Build the commands that reconcile the managed key block in authorized_keys.
18
- * Strips any previous ts-cloud block, then appends the current set. Returns `[]`
19
- * when there are no keys to manage.
18
+ * Strips any previous ts-cloud block, then appends the current set. An empty
19
+ * key set still strips the block — removing your last key from the config must
20
+ * remove it from the box (e.g. revoking a compromised key).
20
21
  */
21
22
  export declare function buildAuthorizedKeysScript(keys?: SshKeyConfig[], options?: AuthorizedKeysOptions): string[];
package/dist/index.js CHANGED
@@ -55,10 +55,10 @@ import {
55
55
  sanitizeCloudConfig,
56
56
  setMaintenance,
57
57
  startLocalDashboardServer
58
- } from "./chunk-rr3j38qr.js";
58
+ } from "./chunk-jgenfdz6.js";
59
59
  import {
60
60
  buildAndPushServerlessImage
61
- } from "./chunk-3mcfbrw8.js";
61
+ } from "./chunk-tskj9fay.js";
62
62
  import {
63
63
  CloudWatchLogsClient,
64
64
  EFSClient,
@@ -105,7 +105,7 @@ import {
105
105
  waitForCloudInit,
106
106
  waitForSsh,
107
107
  wrapCloudInitUserData
108
- } from "./chunk-xdd6qvre.js";
108
+ } from "./chunk-dah449r1.js";
109
109
  import {
110
110
  ABTestManager,
111
111
  AI,
@@ -446,6 +446,7 @@ import {
446
446
  replicaManager,
447
447
  requiresReplacement,
448
448
  resolveApp,
449
+ resolveAppDatabase,
449
450
  resolveCloudProvider,
450
451
  resolveCredentials,
451
452
  resolveDashboardDomain,
@@ -509,7 +510,7 @@ import {
509
510
  withSecurity,
510
511
  withTimeout,
511
512
  xrayManager
512
- } from "./chunk-k56wpkhg.js";
513
+ } from "./chunk-stt1z5cx.js";
513
514
  import {
514
515
  EC2Client,
515
516
  SSMClient
@@ -4729,6 +4730,7 @@ export {
4729
4730
  resolveDashboardAction,
4730
4731
  resolveCredentials,
4731
4732
  resolveCloudProvider,
4733
+ resolveAppDatabase,
4732
4734
  resolveApp,
4733
4735
  requiresReplacement,
4734
4736
  replicaManager,