@stacksjs/ts-cloud 0.7.58 → 0.7.60

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 (74) hide show
  1. package/dist/auth/encryption.d.ts +2 -1
  2. package/dist/auth/index.d.ts +1 -1
  3. package/dist/aws/index.js +1 -1
  4. package/dist/bin/cli.js +2973 -2973
  5. package/dist/{chunk-fv1bj3yt.js → chunk-001z7khv.js} +36 -0
  6. package/dist/{chunk-fw3q88wk.js → chunk-cz17nhnx.js} +80 -68
  7. package/dist/{chunk-vvkd46k1.js → chunk-gcsv7g83.js} +3 -3
  8. package/dist/{chunk-e05phx5f.js → chunk-rxhqny6z.js} +2 -2
  9. package/dist/{chunk-9m6b4m74.js → chunk-sd9h1baj.js} +19 -11
  10. package/dist/{chunk-vdk53yyq.js → chunk-tq46tnxv.js} +102 -64
  11. package/dist/{chunk-0z43x8re.js → chunk-z3bakpnh.js} +2 -2
  12. package/dist/{chunk-exbcsab2.js → chunk-zvk0f89t.js} +1 -1
  13. package/dist/control-plane/index.d.ts +1 -1
  14. package/dist/control-plane/store.d.ts +2 -1
  15. package/dist/deploy/dashboard-config-module.d.ts +7 -1
  16. package/dist/deploy/dashboard-session.d.ts +2 -1
  17. package/dist/deploy/dashboard-users.d.ts +5 -4
  18. package/dist/deploy/index.d.ts +1 -1
  19. package/dist/deploy/index.js +9 -9
  20. package/dist/deploy/management-dashboard.d.ts +4 -3
  21. package/dist/dns/index.js +1 -1
  22. package/dist/dns/porkbun.d.ts +27 -0
  23. package/dist/dns/types.d.ts +8 -1
  24. package/dist/drivers/index.js +2 -2
  25. package/dist/index.d.ts +1 -1
  26. package/dist/index.js +26 -12
  27. package/dist/ui/account/automation.html +3 -3
  28. package/dist/ui/account/security.html +2 -2
  29. package/dist/ui/applications/compose.html +4 -4
  30. package/dist/ui/applications/new.html +2 -2
  31. package/dist/ui/data/backups.html +4 -4
  32. package/dist/ui/data/services.html +4 -4
  33. package/dist/ui/data/volumes.html +4 -4
  34. package/dist/ui/index.html +4 -4
  35. package/dist/ui/integrations.html +2 -2
  36. package/dist/ui/operations/alerts.html +4 -4
  37. package/dist/ui/operations/configuration.html +4 -4
  38. package/dist/ui/operations/jobs.html +4 -4
  39. package/dist/ui/operations/maintenance.html +4 -4
  40. package/dist/ui/operations/observability.html +4 -4
  41. package/dist/ui/operations/previews.html +4 -4
  42. package/dist/ui/operations/queue.html +4 -4
  43. package/dist/ui/operations/regions.html +4 -4
  44. package/dist/ui/operations/releases.html +4 -4
  45. package/dist/ui/operations/workloads.html +4 -4
  46. package/dist/ui/security.html +2 -2
  47. package/dist/ui/server/actions.html +3 -3
  48. package/dist/ui/server/activity.html +2 -2
  49. package/dist/ui/server/capacity.html +4 -4
  50. package/dist/ui/server/database.html +4 -4
  51. package/dist/ui/server/deployments.html +4 -4
  52. package/dist/ui/server/diagnostics.html +2 -2
  53. package/dist/ui/server/firewall.html +4 -4
  54. package/dist/ui/server/fleet.html +4 -4
  55. package/dist/ui/server/logs.html +4 -4
  56. package/dist/ui/server/metrics.html +2 -2
  57. package/dist/ui/server/services.html +2 -2
  58. package/dist/ui/server/sites.html +3 -3
  59. package/dist/ui/server/ssh-keys.html +4 -4
  60. package/dist/ui/server/team.html +4 -4
  61. package/dist/ui/server/terminal.html +2 -2
  62. package/dist/ui/serverless/alarms.html +4 -4
  63. package/dist/ui/serverless/assets.html +2 -2
  64. package/dist/ui/serverless/data.html +4 -4
  65. package/dist/ui/serverless/deployments.html +2 -2
  66. package/dist/ui/serverless/firewall.html +2 -2
  67. package/dist/ui/serverless/functions.html +4 -4
  68. package/dist/ui/serverless/logs.html +4 -4
  69. package/dist/ui/serverless/metrics.html +2 -2
  70. package/dist/ui/serverless/queues.html +4 -4
  71. package/dist/ui/serverless/secrets.html +4 -4
  72. package/dist/ui/serverless/traces.html +4 -4
  73. package/dist/ui/serverless.html +4 -4
  74. 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
@@ -4069,6 +4071,7 @@ function redactForDashboard(config) {
4069
4071
  if (safe.hetzner)
4070
4072
  delete safe.hetzner.apiToken;
4071
4073
  delete safe.aws;
4074
+ delete safe.stateDir;
4072
4075
  for (const site of Object.values(safe.sites ?? {})) {
4073
4076
  if (site?.env)
4074
4077
  site.env = blankValues(site.env);
@@ -4100,7 +4103,9 @@ function serializeDashboardConfig(config) {
4100
4103
 
4101
4104
  // src/deploy/management-dashboard.ts
4102
4105
  var MANAGEMENT_DASHBOARD_SITE = "dashboard";
4103
- var DASHBOARD_CREDENTIALS_FILE = join4(".ts-cloud", "dashboard-credentials.json");
4106
+ function dashboardCredentialsFile() {
4107
+ return statePath("dashboard-credentials.json");
4108
+ }
4104
4109
  function generatePassword() {
4105
4110
  return randomBytes(24).toString("base64url");
4106
4111
  }
@@ -4110,7 +4115,8 @@ function resolveDashboardAuth(cwd, username, logger) {
4110
4115
  return { password: explicit, source: "env" };
4111
4116
  if (truthy(process.env.TS_CLOUD_UI_PUBLIC))
4112
4117
  return { password: undefined, source: "public" };
4113
- const file = join4(cwd, DASHBOARD_CREDENTIALS_FILE);
4118
+ const credentialsFile = dashboardCredentialsFile();
4119
+ const file = resolveStatePath(cwd, "dashboard-credentials.json");
4114
4120
  try {
4115
4121
  if (existsSync2(file)) {
4116
4122
  const saved = JSON.parse(readFileSync3(file, "utf8"));
@@ -4124,10 +4130,10 @@ function resolveDashboardAuth(cwd, username, logger) {
4124
4130
  writeFileSync(file, `${JSON.stringify({ username, password, generatedAt: new Date().toISOString() }, null, 2)}
4125
4131
  `);
4126
4132
  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.`);
4133
+ 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
4134
  } catch (error) {
4129
4135
  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.`);
4136
+ 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
4137
  }
4132
4138
  return { password, source: "generated" };
4133
4139
  }
@@ -4135,7 +4141,9 @@ var noopLogger = { info: () => {}, warn: () => {} };
4135
4141
  function truthy(v) {
4136
4142
  return v != null && v !== "" && v !== "0" && v.toLowerCase() !== "false";
4137
4143
  }
4138
- var LIVE_STAGE_DIR = join4(".ts-cloud", "dashboard-release");
4144
+ function liveStageDir() {
4145
+ return statePath("dashboard-release");
4146
+ }
4139
4147
  function resolveDashboardVersion() {
4140
4148
  const explicit = process.env.TS_CLOUD_UI_VERSION?.trim();
4141
4149
  if (explicit)
@@ -4155,7 +4163,7 @@ function stageLiveDashboardRoot(config, cwd, logger) {
4155
4163
  logger.warn("Management dashboard: the cloud config has no project slug — skipping the live dashboard.");
4156
4164
  return null;
4157
4165
  }
4158
- const stage = join4(cwd, LIVE_STAGE_DIR);
4166
+ const stage = resolveStatePath(cwd, "dashboard-release");
4159
4167
  try {
4160
4168
  mkdirSync(stage, { recursive: true });
4161
4169
  writeFileSync(join4(stage, "cloud.config.ts"), serializeDashboardConfig(config));
@@ -4167,7 +4175,7 @@ function stageLiveDashboardRoot(config, cwd, logger) {
4167
4175
  };
4168
4176
  writeFileSync(join4(stage, "package.json"), `${JSON.stringify(pkg, null, 2)}
4169
4177
  `);
4170
- return LIVE_STAGE_DIR;
4178
+ return liveStageDir();
4171
4179
  } catch (error) {
4172
4180
  logger.warn(`Management dashboard: could not stage the live release (${error?.message ?? error}) — skipping.`);
4173
4181
  return null;
@@ -4246,7 +4254,7 @@ function ensureManagementDashboard(config, options = {}) {
4246
4254
  logger.info("Management dashboard: no domain resolved (set TS_CLOUD_UI_DOMAIN or configure a site domain) — skipping.");
4247
4255
  return config;
4248
4256
  }
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})`;
4257
+ 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
4258
  logger.warn("Management dashboard: static mode — one shared password, and no per-site collaborators. Unset TS_CLOUD_UI_STATIC for the live dashboard.");
4251
4259
  for (const { name, site } of resolved) {
4252
4260
  sites[name] = site;
@@ -5281,4 +5289,4 @@ function buildCloudFrontOriginConfig(options) {
5281
5289
  CustomErrorResponses: { Quantity: 0 }
5282
5290
  };
5283
5291
  }
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 };
5292
+ 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 };
@@ -4,43 +4,44 @@ import {
4
4
 
5
5
  // ../core/dist/index.js
6
6
  import { createRequire } from "node:module";
7
+ import { isAbsolute, join, relative } from "node:path";
7
8
  import { existsSync, readdirSync } from "node:fs";
8
- import { join } from "node:path";
9
+ import { join as join2 } from "node:path";
9
10
  import { createHash } from "node:crypto";
10
11
  import { copyFileSync, existsSync as existsSync2, readdirSync as readdirSync2, readFileSync, statSync, writeFileSync } from "node:fs";
11
- import { basename, dirname, extname, join as join2 } from "node:path";
12
+ import { basename, dirname, extname, join as join3 } from "node:path";
12
13
  import { existsSync as existsSync3, readFileSync as readFileSync2 } from "node:fs";
13
14
  import { homedir } from "node:os";
14
- import { join as join3 } from "node:path";
15
+ import { join as join4 } from "node:path";
15
16
  import { createHash as createHash2 } from "node:crypto";
16
17
  import { existsSync as existsSync4, mkdirSync, readdirSync as readdirSync3, readFileSync as readFileSync3, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
17
- import { join as join4 } from "node:path";
18
+ import { join as join5 } from "node:path";
18
19
  import { createHash as createHash3 } from "node:crypto";
19
20
  import { createReadStream, readdirSync as readdirSync4, statSync as statSync2 } from "node:fs";
20
- import { join as join5, relative } from "node:path";
21
+ import { join as join6, relative as relative2 } from "node:path";
21
22
  import { deflateRawSync } from "node:zlib";
22
23
  import { execSync } from "node:child_process";
23
24
  import { createHash as createHash4 } from "node:crypto";
24
25
  import { cpSync, mkdtempSync, rmSync, writeFileSync as writeFileSync3 } from "node:fs";
25
26
  import { tmpdir } from "node:os";
26
- import { dirname as dirname2, isAbsolute, join as join6, resolve } from "node:path";
27
+ import { dirname as dirname2, isAbsolute as isAbsolute2, join as join7, resolve } from "node:path";
27
28
  import { fileURLToPath } from "node:url";
28
29
  import { execFileSync } from "node:child_process";
29
30
  import { mkdtempSync as mkdtempSync2, readFileSync as readFileSync4, rmSync as rmSync2 } from "node:fs";
30
31
  import { tmpdir as tmpdir2 } from "node:os";
31
- import { dirname as dirname3, join as join7 } from "node:path";
32
+ import { dirname as dirname3, join as join8 } from "node:path";
32
33
  import { fileURLToPath as fileURLToPath2 } from "node:url";
33
34
  import { readFileSync as readFileSync5 } from "node:fs";
34
- import { dirname as dirname4, join as join8 } from "node:path";
35
+ import { dirname as dirname4, join as join9 } from "node:path";
35
36
  import { fileURLToPath as fileURLToPath3 } from "node:url";
36
37
  import { execFileSync as execFileSync2 } from "node:child_process";
37
38
  import { existsSync as existsSync5, mkdirSync as mkdirSync2, mkdtempSync as mkdtempSync3, readdirSync as readdirSync5, readFileSync as readFileSync6, rmSync as rmSync3, statSync as statSync3, writeFileSync as writeFileSync4 } from "node:fs";
38
39
  import { tmpdir as tmpdir3 } from "node:os";
39
- import { join as join9, relative as relative2 } from "node:path";
40
+ import { join as join10, relative as relative3 } from "node:path";
40
41
  import { execSync as execSync2 } from "node:child_process";
41
42
  import { createHash as createHash5 } from "node:crypto";
42
43
  import { readdirSync as readdirSync6, readFileSync as readFileSync7, statSync as statSync4 } from "node:fs";
43
- import { join as join10, relative as relative3, resolve as resolve2 } from "node:path";
44
+ import { join as join11, relative as relative4, resolve as resolve2 } from "node:path";
44
45
  var __defProp = Object.defineProperty;
45
46
  var __returnValue = (v) => v;
46
47
  function __exportSetter(name, newValue) {
@@ -1058,6 +1059,32 @@ var RealtimePresets = {
1058
1059
  }
1059
1060
  }
1060
1061
  };
1062
+ var DEFAULT_STATE_DIR = ".ts-cloud";
1063
+ var STATE_DIR_ENV_VAR = "TS_CLOUD_STATE_DIR";
1064
+ var configuredStateDir = null;
1065
+ function setStateDir(dir) {
1066
+ const trimmed = dir?.trim();
1067
+ configuredStateDir = trimmed || null;
1068
+ }
1069
+ function stateDir() {
1070
+ const fromEnv = process.env[STATE_DIR_ENV_VAR]?.trim();
1071
+ return fromEnv || configuredStateDir || DEFAULT_STATE_DIR;
1072
+ }
1073
+ function statePath(...segments) {
1074
+ return join(stateDir(), ...segments);
1075
+ }
1076
+ function resolveStatePath(cwd, ...segments) {
1077
+ const dir = stateDir();
1078
+ return isAbsolute(dir) ? join(dir, ...segments) : join(cwd, dir, ...segments);
1079
+ }
1080
+ function isStatePath(path, root = process.cwd()) {
1081
+ const inside = (parent, child) => {
1082
+ const rel = relative(parent, child);
1083
+ return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
1084
+ };
1085
+ const absolute = isAbsolute(path) ? path : join(root, path);
1086
+ return inside(resolveStatePath(root), absolute);
1087
+ }
1061
1088
  function detectDeploymentTargets(config) {
1062
1089
  const server = config.infrastructure?.compute != null;
1063
1090
  const serverless = Object.values(config.environments ?? {}).some((env) => env?.app != null);
@@ -2169,11 +2196,11 @@ class Storage {
2169
2196
  static docsExist(options = {}) {
2170
2197
  const { projectRoot = process.cwd(), docsPaths = ["docs", "documentation", "doc"] } = options;
2171
2198
  for (const docsPath of docsPaths) {
2172
- const fullPath = join(projectRoot, docsPath);
2199
+ const fullPath = join2(projectRoot, docsPath);
2173
2200
  if (existsSync(fullPath)) {
2174
2201
  const distPaths = ["dist", "build", ".bunpress/dist", "_site", "out", "public"];
2175
2202
  for (const distPath of distPaths) {
2176
- const fullDistPath = join(fullPath, distPath);
2203
+ const fullDistPath = join2(fullPath, distPath);
2177
2204
  if (existsSync(fullDistPath)) {
2178
2205
  try {
2179
2206
  const files = readdirSync(fullDistPath);
@@ -2288,16 +2315,16 @@ class Storage {
2288
2315
  const privatePath = paths.private || "private";
2289
2316
  return {
2290
2317
  web: {
2291
- exists: existsSync(join(projectRoot, webPath)),
2292
- path: join(projectRoot, webPath)
2318
+ exists: existsSync(join2(projectRoot, webPath)),
2319
+ path: join2(projectRoot, webPath)
2293
2320
  },
2294
2321
  docs: {
2295
- exists: existsSync(join(projectRoot, docsPath)),
2296
- path: join(projectRoot, docsPath)
2322
+ exists: existsSync(join2(projectRoot, docsPath)),
2323
+ path: join2(projectRoot, docsPath)
2297
2324
  },
2298
2325
  private: {
2299
- exists: existsSync(join(projectRoot, privatePath)),
2300
- path: join(projectRoot, privatePath)
2326
+ exists: existsSync(join2(projectRoot, privatePath)),
2327
+ path: join2(projectRoot, privatePath)
2301
2328
  }
2302
2329
  };
2303
2330
  }
@@ -14811,7 +14838,7 @@ class AssetHasher {
14811
14838
  if (dir === ".") {
14812
14839
  return `${name}.${hash2}${ext}`;
14813
14840
  }
14814
- return join2(dir, `${name}.${hash2}${ext}`);
14841
+ return join3(dir, `${name}.${hash2}${ext}`);
14815
14842
  }
14816
14843
  static collectFiles(directory, relativeTo) {
14817
14844
  const files = [];
@@ -14821,7 +14848,7 @@ class AssetHasher {
14821
14848
  }
14822
14849
  const entries = readdirSync2(directory, { withFileTypes: true });
14823
14850
  for (const entry of entries) {
14824
- const fullPath = join2(directory, entry.name);
14851
+ const fullPath = join3(directory, entry.name);
14825
14852
  if (entry.isDirectory()) {
14826
14853
  files.push(...AssetHasher.collectFiles(fullPath, baseDir));
14827
14854
  } else if (entry.isFile()) {
@@ -14851,7 +14878,7 @@ class AssetHasher {
14851
14878
  assets.push(asset);
14852
14879
  hashMap[relativePath] = hashedRelativePath;
14853
14880
  if (outputDir) {
14854
- const destPath = join2(outputDir, hashedRelativePath);
14881
+ const destPath = join3(outputDir, hashedRelativePath);
14855
14882
  const destDir = dirname(destPath);
14856
14883
  if (!existsSync2(destDir)) {
14857
14884
  const { mkdirSync: mkdirSync3 } = __require2("node:fs");
@@ -14869,7 +14896,7 @@ class AssetHasher {
14869
14896
  hashMap
14870
14897
  };
14871
14898
  if (outputDir) {
14872
- const manifestPath = join2(outputDir, "asset-manifest.json");
14899
+ const manifestPath = join3(outputDir, "asset-manifest.json");
14873
14900
  writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
14874
14901
  }
14875
14902
  return manifest;
@@ -14964,7 +14991,7 @@ class AssetHasher {
14964
14991
  cc = cacheControl.hashed || "public, max-age=31536000, immutable";
14965
14992
  }
14966
14993
  return {
14967
- localPath: join2(sourceDir, asset.originalPath),
14994
+ localPath: join3(sourceDir, asset.originalPath),
14968
14995
  s3Key: keyPrefix ? `${keyPrefix}/${asset.hashedPath}` : asset.hashedPath,
14969
14996
  contentType: asset.contentType,
14970
14997
  cacheControl: cc,
@@ -21869,7 +21896,7 @@ function createDashboardSite(options) {
21869
21896
  }
21870
21897
  };
21871
21898
  }
21872
- var DASHBOARD_STATE_DIR = ".ts-cloud";
21899
+ var DASHBOARD_STATE_DIR = DEFAULT_STATE_DIR;
21873
21900
  var DASHBOARD_ENTRY = "./node_modules/@stacksjs/ts-cloud/dist/bin/cli.js";
21874
21901
  function apexOf(domain) {
21875
21902
  const parts = domain.split(".").filter(Boolean);
@@ -22065,7 +22092,7 @@ function fromEnvironment() {
22065
22092
  }
22066
22093
  function fromSharedCredentials(options) {
22067
22094
  const profile = options?.profile || process.env.AWS_PROFILE || "default";
22068
- const credentialsPath = options?.credentialsFile || join3(homedir(), ".aws", "credentials");
22095
+ const credentialsPath = options?.credentialsFile || join4(homedir(), ".aws", "credentials");
22069
22096
  if (!existsSync3(credentialsPath)) {
22070
22097
  return null;
22071
22098
  }
@@ -22302,7 +22329,7 @@ function resolveRegion(profile) {
22302
22329
  if (envRegion) {
22303
22330
  return envRegion;
22304
22331
  }
22305
- const configPath = join3(homedir(), ".aws", "config");
22332
+ const configPath = join4(homedir(), ".aws", "config");
22306
22333
  if (existsSync3(configPath)) {
22307
22334
  try {
22308
22335
  const content = readFileSync2(configPath, "utf-8");
@@ -23675,13 +23702,14 @@ class FileCache {
23675
23702
  constructor(cacheDir, options = {}) {
23676
23703
  this.cacheDir = cacheDir;
23677
23704
  this.ttl = options.ttl || 86400000;
23678
- if (!existsSync4(cacheDir)) {
23679
- mkdirSync(cacheDir, { recursive: true });
23680
- }
23705
+ }
23706
+ ensureCacheDir() {
23707
+ if (!existsSync4(this.cacheDir))
23708
+ mkdirSync(this.cacheDir, { recursive: true });
23681
23709
  }
23682
23710
  getCachePath(key) {
23683
23711
  const hash2 = createHash2("sha256").update(key).digest("hex");
23684
- return join4(this.cacheDir, `${hash2}.json`);
23712
+ return join5(this.cacheDir, `${hash2}.json`);
23685
23713
  }
23686
23714
  get(key) {
23687
23715
  const cachePath = this.getCachePath(key);
@@ -23702,6 +23730,7 @@ class FileCache {
23702
23730
  }
23703
23731
  }
23704
23732
  set(key, value, hash2) {
23733
+ this.ensureCacheDir();
23705
23734
  const cachePath = this.getCachePath(key);
23706
23735
  const entry = {
23707
23736
  value,
@@ -23714,16 +23743,20 @@ class FileCache {
23714
23743
  return this.get(key) !== undefined;
23715
23744
  }
23716
23745
  clear() {
23746
+ if (!existsSync4(this.cacheDir))
23747
+ return;
23717
23748
  const files = readdirSync3(this.cacheDir);
23718
23749
  for (const file of files) {
23719
- unlinkSync(join4(this.cacheDir, file));
23750
+ unlinkSync(join5(this.cacheDir, file));
23720
23751
  }
23721
23752
  }
23722
23753
  prune() {
23754
+ if (!existsSync4(this.cacheDir))
23755
+ return;
23723
23756
  const files = readdirSync3(this.cacheDir);
23724
23757
  const now = Date.now();
23725
23758
  for (const file of files) {
23726
- const filePath = join4(this.cacheDir, file);
23759
+ const filePath = join5(this.cacheDir, file);
23727
23760
  try {
23728
23761
  const data = readFileSync3(filePath, "utf-8");
23729
23762
  const entry = JSON.parse(data);
@@ -23739,7 +23772,7 @@ class FileCache {
23739
23772
 
23740
23773
  class TemplateCache {
23741
23774
  cache;
23742
- constructor(cacheDir = ".ts-cloud/cache/templates") {
23775
+ constructor(cacheDir = statePath("cache", "templates")) {
23743
23776
  this.cache = new FileCache(cacheDir, {
23744
23777
  ttl: 86400000
23745
23778
  });
@@ -23770,7 +23803,12 @@ class TemplateCache {
23770
23803
  this.cache.prune();
23771
23804
  }
23772
23805
  }
23773
- var templateCache = new TemplateCache;
23806
+ var sharedTemplateCache = null;
23807
+ function templateCache() {
23808
+ if (!sharedTemplateCache)
23809
+ sharedTemplateCache = new TemplateCache;
23810
+ return sharedTemplateCache;
23811
+ }
23774
23812
  async function hashFile(filePath, options = {}) {
23775
23813
  const algorithm = options.algorithm || "sha256";
23776
23814
  const chunkSize = options.chunkSize || 65536;
@@ -23789,13 +23827,13 @@ function hashBuffer(buffer, algorithm = "sha256") {
23789
23827
  return createHash3(algorithm).update(buffer).digest("hex");
23790
23828
  }
23791
23829
  async function hashDirectory(dirPath, options = {}) {
23792
- const ignorePatterns = options.ignorePatterns || ["node_modules", ".git", "dist", "build", ".ts-cloud"];
23830
+ const ignorePatterns = options.ignorePatterns || ["node_modules", ".git", "dist", "build", stateDir()];
23793
23831
  const files = [];
23794
23832
  async function walk(dir) {
23795
23833
  const entries = readdirSync4(dir, { withFileTypes: true });
23796
23834
  for (const entry of entries) {
23797
- const fullPath = join5(dir, entry.name);
23798
- const relativePath = relative(dirPath, fullPath);
23835
+ const fullPath = join6(dir, entry.name);
23836
+ const relativePath = relative2(dirPath, fullPath);
23799
23837
  if (ignorePatterns.some((pattern) => relativePath.includes(pattern))) {
23800
23838
  continue;
23801
23839
  }
@@ -44333,7 +44371,7 @@ export const cli = __handlers.cli
44333
44371
  `;
44334
44372
  }
44335
44373
  function adapterSourcePath() {
44336
- return join6(dirname2(fileURLToPath(import.meta.url)), "runtime", "adapter.ts");
44374
+ return join7(dirname2(fileURLToPath(import.meta.url)), "runtime", "adapter.ts");
44337
44375
  }
44338
44376
  function runBuildHooks(hooks, cwd, onStep) {
44339
44377
  for (const hook of hooks ?? []) {
@@ -44355,11 +44393,11 @@ async function packageServerlessApp(opts) {
44355
44393
  const entry = app.entry;
44356
44394
  if (!entry)
44357
44395
  throw new Error("serverless app: `entry` is required to package a Node/Bun application");
44358
- const entryPath = isAbsolute(entry) ? entry : join6(projectRoot, entry);
44359
- const stage = mkdtempSync(join6(tmpdir(), "tscloud-pkg-"));
44396
+ const entryPath = isAbsolute2(entry) ? entry : join7(projectRoot, entry);
44397
+ const stage = mkdtempSync(join7(tmpdir(), "tscloud-pkg-"));
44360
44398
  try {
44361
- cpSync(adapterSourcePath(), join6(stage, "adapter.ts"));
44362
- const bootstrapPath = join6(stage, "bootstrap.ts");
44399
+ cpSync(adapterSourcePath(), join7(stage, "adapter.ts"));
44400
+ const bootstrapPath = join7(stage, "bootstrap.ts");
44363
44401
  writeFileSync3(bootstrapPath, generateBootstrap({ entryImport: entryPath, adapterImport: "./adapter" }));
44364
44402
  opts.onStep?.("bundling application");
44365
44403
  const result = await Bun.build({
@@ -45345,27 +45383,27 @@ function assetsDir() {
45345
45383
  return dirname3(fileURLToPath2(import.meta.url));
45346
45384
  }
45347
45385
  function sharedRuntimeLoop() {
45348
- return readFileSync4(join7(assetsDir(), "runtime.mjs"), "utf-8");
45386
+ return readFileSync4(join8(assetsDir(), "runtime.mjs"), "utf-8");
45349
45387
  }
45350
45388
  function bootstrap(kind) {
45351
- return readFileSync4(join7(assetsDir(), `${kind}-bootstrap`), "utf-8");
45389
+ return readFileSync4(join8(assetsDir(), `${kind}-bootstrap`), "utf-8");
45352
45390
  }
45353
45391
  function buildNodeRuntimeLayerZip(options) {
45354
45392
  const architecture = options.architecture ?? "x86_64";
45355
45393
  const nodeArch = architecture === "arm64" ? "arm64" : "x64";
45356
45394
  const version = options.version.replace(/^v/, "");
45357
45395
  const step = options.onStep ?? (() => {});
45358
- const stage = mkdtempSync2(join7(tmpdir2(), "tscloud-node-layer-"));
45396
+ const stage = mkdtempSync2(join8(tmpdir2(), "tscloud-node-layer-"));
45359
45397
  try {
45360
45398
  const exact = version.includes(".") ? version : resolveLatestNode(version);
45361
45399
  const dir = `node-v${exact}-linux-${nodeArch}`;
45362
45400
  const url = `https://nodejs.org/dist/v${exact}/${dir}.tar.xz`;
45363
45401
  step(`downloading Node ${exact} (${architecture})`);
45364
- const tar = join7(stage, "node.tar.xz");
45402
+ const tar = join8(stage, "node.tar.xz");
45365
45403
  fetchToFile(url, tar);
45366
45404
  step("extracting node binary");
45367
45405
  execFileSync("tar", ["-xf", tar, "-C", stage, `${dir}/bin/node`], { stdio: "inherit" });
45368
- const nodeBin = readFileSync4(join7(stage, dir, "bin", "node"));
45406
+ const nodeBin = readFileSync4(join8(stage, dir, "bin", "node"));
45369
45407
  step("packaging layer");
45370
45408
  const entries = [
45371
45409
  { name: "bootstrap", data: bootstrap("node"), mode: 493 },
@@ -45382,15 +45420,15 @@ function buildBunRuntimeLayerZip(options) {
45382
45420
  const bunArch = architecture === "arm64" ? "bun-linux-aarch64" : "bun-linux-x64";
45383
45421
  const version = options.version === "latest" ? "" : options.version.replace(/^v/, "");
45384
45422
  const step = options.onStep ?? (() => {});
45385
- const stage = mkdtempSync2(join7(tmpdir2(), "tscloud-bun-layer-"));
45423
+ const stage = mkdtempSync2(join8(tmpdir2(), "tscloud-bun-layer-"));
45386
45424
  try {
45387
45425
  const url = version ? `https://github.com/oven-sh/bun/releases/download/bun-v${version}/${bunArch}.zip` : `https://github.com/oven-sh/bun/releases/latest/download/${bunArch}.zip`;
45388
45426
  step(`downloading Bun ${version || "latest"} (${architecture})`);
45389
- const zipPath = join7(stage, "bun.zip");
45427
+ const zipPath = join8(stage, "bun.zip");
45390
45428
  fetchToFile(url, zipPath);
45391
45429
  step("extracting bun binary");
45392
45430
  execFileSync("unzip", ["-o", "-q", zipPath, "-d", stage], { stdio: "inherit" });
45393
- const bunBin = readFileSync4(join7(stage, bunArch, "bun"));
45431
+ const bunBin = readFileSync4(join8(stage, bunArch, "bun"));
45394
45432
  step("packaging layer");
45395
45433
  const entries = [
45396
45434
  { name: "bootstrap", data: bootstrap("bun"), mode: 493 },
@@ -45572,11 +45610,11 @@ clear_env = no
45572
45610
  `;
45573
45611
  }
45574
45612
  function assetsDir2() {
45575
- return join8(dirname4(fileURLToPath3(import.meta.url)), "runtime-assets");
45613
+ return join9(dirname4(fileURLToPath3(import.meta.url)), "runtime-assets");
45576
45614
  }
45577
45615
  function phpRuntimeLayerAssets() {
45578
45616
  const dir = assetsDir2();
45579
- const read = (f) => readFileSync5(join8(dir, f), "utf-8");
45617
+ const read = (f) => readFileSync5(join9(dir, f), "utf-8");
45580
45618
  return [
45581
45619
  { path: "bootstrap", contents: read("bootstrap"), mode: 493 },
45582
45620
  { path: "tscloud/runtime.php", contents: read("runtime.php"), mode: 420 },
@@ -45613,7 +45651,7 @@ var LARAVEL_SERVERLESS_BUILD_STEPS = [
45613
45651
  ];
45614
45652
  function* walk(dir) {
45615
45653
  for (const entry of readdirSync5(dir)) {
45616
- const full = join9(dir, entry);
45654
+ const full = join10(dir, entry);
45617
45655
  if (statSync3(full).isDirectory())
45618
45656
  yield* walk(full);
45619
45657
  else
@@ -45624,26 +45662,26 @@ function buildPhpRuntimeLayerZip(options = {}) {
45624
45662
  const architecture = options.architecture ?? "x86_64";
45625
45663
  const platform = options.platform ?? (architecture === "arm64" ? "linux/arm64" : "linux/amd64");
45626
45664
  const step = options.onStep ?? (() => {});
45627
- const stage = mkdtempSync3(join9(tmpdir3(), "tscloud-php-layer-"));
45665
+ const stage = mkdtempSync3(join10(tmpdir3(), "tscloud-php-layer-"));
45628
45666
  const imageTag = "tscloud-php-layer:build";
45629
45667
  try {
45630
- writeFileSync4(join9(stage, "Dockerfile"), generatePhpLayerDockerfile(options));
45668
+ writeFileSync4(join10(stage, "Dockerfile"), generatePhpLayerDockerfile(options));
45631
45669
  step("Building PHP runtime image (docker)");
45632
45670
  execFileSync2("docker", ["build", "--platform", platform, "-t", imageTag, stage], { stdio: "inherit" });
45633
45671
  step("Extracting /opt/php from image");
45634
45672
  const cid = execFileSync2("docker", ["create", "--platform", platform, imageTag], { encoding: "utf-8" }).trim();
45635
- const optDir = join9(stage, "opt");
45673
+ const optDir = join10(stage, "opt");
45636
45674
  mkdirSync2(optDir, { recursive: true });
45637
45675
  try {
45638
- execFileSync2("docker", ["cp", `${cid}:/opt/php`, join9(optDir, "php")], { stdio: "inherit" });
45676
+ execFileSync2("docker", ["cp", `${cid}:/opt/php`, join10(optDir, "php")], { stdio: "inherit" });
45639
45677
  } finally {
45640
45678
  execFileSync2("docker", ["rm", cid], { stdio: "ignore" });
45641
45679
  }
45642
- if (!existsSync5(join9(optDir, "php", "bin", "php")))
45680
+ if (!existsSync5(join10(optDir, "php", "bin", "php")))
45643
45681
  throw new Error("layer build produced no /opt/php/bin/php");
45644
45682
  const entries = [];
45645
45683
  for (const file of walk(optDir)) {
45646
- const rel = relative2(optDir, file).replace(/\\/g, "/");
45684
+ const rel = relative3(optDir, file).replace(/\\/g, "/");
45647
45685
  const mode = statSync3(file).mode & 73 ? 493 : 420;
45648
45686
  entries.push({ name: rel, data: readFileSync6(file), mode });
45649
45687
  }
@@ -45680,8 +45718,8 @@ function isExcluded(rel, excludes) {
45680
45718
  }
45681
45719
  function* walk2(dir, root, excludes) {
45682
45720
  for (const entry of readdirSync6(dir)) {
45683
- const full = join10(dir, entry);
45684
- const rel = relative3(root, full).replace(/\\/g, "/");
45721
+ const full = join11(dir, entry);
45722
+ const rel = relative4(root, full).replace(/\\/g, "/");
45685
45723
  if (isExcluded(rel, excludes))
45686
45724
  continue;
45687
45725
  if (statSync4(full).isDirectory())
@@ -45702,10 +45740,10 @@ function runPhpBuildHooks(opts) {
45702
45740
  }
45703
45741
  function collectPhpAppEntries(projectRoot, exclude = []) {
45704
45742
  const root = resolve2(projectRoot);
45705
- const excludes = [...PHP_DEFAULT_EXCLUDES, ...exclude];
45743
+ const excludes = [...PHP_DEFAULT_EXCLUDES, stateDir(), ...exclude];
45706
45744
  const entries = [];
45707
45745
  for (const file of walk2(root, root, excludes)) {
45708
- const rel = relative3(root, file).replace(/\\/g, "/");
45746
+ const rel = relative4(root, file).replace(/\\/g, "/");
45709
45747
  const executable = (statSync4(file).mode & 73) !== 0;
45710
45748
  entries.push({ name: rel, data: readFileSync7(file), mode: executable ? 493 : 420 });
45711
45749
  }
@@ -46170,4 +46208,4 @@ class ResourceManagementManager {
46170
46208
  }
46171
46209
  var resourceManagementManager = new ResourceManagementManager;
46172
46210
 
46173
- 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, Sftp, 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, createExistingStaticFullStackPreset, 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 };
46211
+ export { detectServiceRegion, signRequest, signRequestAsync, createPresignedUrl, createPresignedUrlAsync, makeAWSRequest, makeAWSRequestOnce, makeAWSRequestAsync, parseXMLResponse, parseJSONResponse, clearSigningKeyCache, getSigningKeyCacheSize, isNodeCryptoAvailable, isWebCryptoAvailable, QueuePresets, RealtimePresets, DEFAULT_STATE_DIR, STATE_DIR_ENV_VAR, setStateDir, stateDir, statePath, resolveStatePath, isStatePath, 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, Sftp, 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, createExistingStaticFullStackPreset, 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 };
@@ -5,9 +5,9 @@ import {
5
5
  generateStaticSiteTemplate,
6
6
  invalidateCache,
7
7
  uploadStaticFiles
8
- } from "./chunk-vvkd46k1.js";
8
+ } from "./chunk-gcsv7g83.js";
9
9
  import"./chunk-01d86gt1.js";
10
- import"./chunk-fv1bj3yt.js";
10
+ import"./chunk-001z7khv.js";
11
11
  import"./chunk-4cjrg98a.js";
12
12
  import"./chunk-32e7ya18.js";
13
13
  import"./chunk-wj3s95p9.js";
@@ -8,7 +8,7 @@ import {
8
8
  phpRuntimeLayerAssets,
9
9
  runPhpBuildHooks,
10
10
  sha256
11
- } from "./chunk-vdk53yyq.js";
11
+ } from "./chunk-tq46tnxv.js";
12
12
 
13
13
  // src/deploy/serverless-image.ts
14
14
  import { execFileSync } from "node:child_process";
@@ -1,6 +1,6 @@
1
1
  export { CONTROL_PLANE_SCHEMA_VERSION, controlPlaneMigrations } from './migrations';
2
2
  export type { ControlPlaneMigration } from './migrations';
3
- export { CONTROL_PLANE_DATABASE_FILE, ControlPlaneStore, MAX_CONTROL_PLANE_ERROR_BYTES, MAX_CONTROL_PLANE_JSON_BYTES, sanitizeControlPlaneValue, } from './store';
3
+ export { controlPlaneDatabaseFile, ControlPlaneStore, MAX_CONTROL_PLANE_ERROR_BYTES, MAX_CONTROL_PLANE_JSON_BYTES, sanitizeControlPlaneValue, } from './store';
4
4
  export * from './types';
5
5
  export { searchControlPlane } from './search';
6
6
  export type { ControlPlaneSearchOptions, ControlPlaneSearchResult, ControlPlaneSearchResultType } from './search';
@@ -1,6 +1,7 @@
1
1
  import type { AppendEventInput, AuthorizationGrant, AuthorizationScope, AuthorizationTarget, CompactResult, ControlPlaneActor, ControlPlaneEnvironment, ControlPlaneEvent, ControlPlaneHealth, ControlPlaneOperation, ControlPlaneOrganization, ControlPlaneProject, ControlPlaneResource, ControlPlaneSnapshot, ControlPlaneStoreOptions, ControlPlaneTag, CreateActorInput, CreateEnvironmentInput, CreateGrantInput, CreateInvitationInput, CreateMembershipInput, CreateOperationInput, CreateOrganizationInput, CreateProjectInput, CreateResourceInput, EventListOptions, ImportSnapshotOptions, JsonValue, NavigationPreference, OperationListOptions, OrganizationInvitation, OrganizationMembership, ReconcileResult, SavedFilter, TransitionOperationInput, UpdateProjectInput, UpdateResourceInput } from './types';
2
2
  import { Database } from 'bun:sqlite';
3
- export declare const CONTROL_PLANE_DATABASE_FILE: string;
3
+ /** Project-relative location of the control-plane database. */
4
+ export declare function controlPlaneDatabaseFile(): string;
4
5
  export declare const MAX_CONTROL_PLANE_JSON_BYTES: number;
5
6
  export declare const MAX_CONTROL_PLANE_ERROR_BYTES: number;
6
7
  export declare function sanitizeControlPlaneValue(value: unknown, maxBytes?: number): JsonValue;
@@ -18,7 +18,7 @@ import type { CloudConfig } from '@ts-cloud/core';
18
18
  /**
19
19
  * Strip everything the dashboard does not need to read.
20
20
  *
21
- * Two rules:
21
+ * Three rules:
22
22
  *
23
23
  * 1. **No credentials.** The Hetzner API token is the big one: it controls the
24
24
  * whole cloud account (create and destroy any server), and unlike a site's
@@ -30,6 +30,12 @@ import type { CloudConfig } from '@ts-cloud/core';
30
30
  * vars a site defines, never their values — so ship the keys and blank the
31
31
  * values. The running site has its own `.env` on the box regardless; there
32
32
  * is no reason for a second copy to sit in the dashboard's directory.
33
+ *
34
+ * 3. **No local paths.** `stateDir` says where the operator's machine keeps
35
+ * ts-cloud state; it means nothing on the box, whose dashboard state lives
36
+ * in the release's `DASHBOARD_STATE_DIR` (the path the deploy preserves
37
+ * across releases via `sharedPaths`). Shipping it would move the box's users
38
+ * and session key outside that shared path and wipe them every deploy.
33
39
  */
34
40
  export declare function redactForDashboard(config: CloudConfig): Record<string, any>;
35
41
  /**