@stacksjs/ts-cloud 0.7.22 → 0.7.24
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.
- package/dist/bin/cli.js +259 -258
- package/dist/{chunk-kcxxwg3j.js → chunk-5cfcv2s2.js} +50 -21
- package/dist/{chunk-js3vrvvn.js → chunk-khfnaap2.js} +1 -1
- package/dist/deploy/dashboard-config-module.d.ts +40 -0
- package/dist/deploy/dashboard-config-module.test.d.ts +1 -0
- package/dist/deploy/index.js +2 -2
- package/dist/deploy/management-dashboard.d.ts +10 -7
- package/dist/drivers/index.js +1 -1
- package/dist/index.js +2 -2
- package/dist/ui/index.html +3 -3
- package/dist/ui/server/actions.html +3 -3
- package/dist/ui/server/backups.html +3 -3
- package/dist/ui/server/database.html +3 -3
- package/dist/ui/server/deployments.html +3 -3
- package/dist/ui/server/firewall.html +3 -3
- package/dist/ui/server/logs.html +3 -3
- package/dist/ui/server/services.html +3 -3
- package/dist/ui/server/sites.html +3 -3
- package/dist/ui/server/ssh-keys.html +3 -3
- package/dist/ui/server/team.html +3 -3
- package/dist/ui/server/terminal.html +3 -3
- package/dist/ui/server/workers.html +3 -3
- package/dist/ui/serverless/alarms.html +3 -3
- package/dist/ui/serverless/assets.html +3 -3
- package/dist/ui/serverless/data.html +3 -3
- package/dist/ui/serverless/deployments.html +3 -3
- package/dist/ui/serverless/functions.html +3 -3
- package/dist/ui/serverless/logs.html +3 -3
- package/dist/ui/serverless/queues.html +3 -3
- package/dist/ui/serverless/scheduler.html +3 -3
- package/dist/ui/serverless/secrets.html +3 -3
- package/dist/ui/serverless/traces.html +3 -3
- package/dist/ui/serverless.html +3 -3
- package/package.json +3 -3
|
@@ -3818,17 +3818,59 @@ function buildLocalArtifactFetch(localPath, siteName) {
|
|
|
3818
3818
|
];
|
|
3819
3819
|
}
|
|
3820
3820
|
// src/drivers/shared/compute-deploy.ts
|
|
3821
|
-
import { copyFileSync
|
|
3821
|
+
import { copyFileSync } from "node:fs";
|
|
3822
3822
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
3823
3823
|
import { join as join5 } from "node:path";
|
|
3824
3824
|
|
|
3825
3825
|
// src/deploy/management-dashboard.ts
|
|
3826
3826
|
import { execSync as execSync2 } from "node:child_process";
|
|
3827
3827
|
import { randomBytes } from "node:crypto";
|
|
3828
|
-
import { chmodSync,
|
|
3828
|
+
import { chmodSync, existsSync as existsSync2, mkdirSync, readFileSync as readFileSync3, writeFileSync } from "node:fs";
|
|
3829
3829
|
import { tmpdir } from "node:os";
|
|
3830
3830
|
import { dirname, isAbsolute, join as join4 } from "node:path";
|
|
3831
3831
|
import { fileURLToPath } from "node:url";
|
|
3832
|
+
|
|
3833
|
+
// src/deploy/dashboard-config-module.ts
|
|
3834
|
+
function blankValues(record) {
|
|
3835
|
+
if (!record || typeof record !== "object")
|
|
3836
|
+
return record;
|
|
3837
|
+
return Object.fromEntries(Object.keys(record).map((key) => [key, ""]));
|
|
3838
|
+
}
|
|
3839
|
+
function redactForDashboard(config) {
|
|
3840
|
+
const safe = JSON.parse(JSON.stringify(config ?? {}));
|
|
3841
|
+
if (safe.hetzner)
|
|
3842
|
+
delete safe.hetzner.apiToken;
|
|
3843
|
+
delete safe.aws;
|
|
3844
|
+
for (const site of Object.values(safe.sites ?? {})) {
|
|
3845
|
+
if (site?.env)
|
|
3846
|
+
site.env = blankValues(site.env);
|
|
3847
|
+
if (site?.environment)
|
|
3848
|
+
site.environment = blankValues(site.environment);
|
|
3849
|
+
}
|
|
3850
|
+
for (const env2 of Object.values(safe.environments ?? {})) {
|
|
3851
|
+
if (env2?.variables)
|
|
3852
|
+
env2.variables = blankValues(env2.variables);
|
|
3853
|
+
}
|
|
3854
|
+
for (const db of Object.values(safe.infrastructure?.databases ?? {})) {
|
|
3855
|
+
if (db?.password)
|
|
3856
|
+
db.password = "";
|
|
3857
|
+
}
|
|
3858
|
+
return safe;
|
|
3859
|
+
}
|
|
3860
|
+
function serializeDashboardConfig(config) {
|
|
3861
|
+
const safe = redactForDashboard(config);
|
|
3862
|
+
return [
|
|
3863
|
+
"// Generated by ts-cloud for the management dashboard — do not edit.",
|
|
3864
|
+
"//",
|
|
3865
|
+
"// This is the project's resolved cloud config, inlined so it needs no",
|
|
3866
|
+
"// imports on the box. Credentials are deliberately absent.",
|
|
3867
|
+
`export default ${JSON.stringify(safe, null, 2)}`,
|
|
3868
|
+
""
|
|
3869
|
+
].join(`
|
|
3870
|
+
`);
|
|
3871
|
+
}
|
|
3872
|
+
|
|
3873
|
+
// src/deploy/management-dashboard.ts
|
|
3832
3874
|
var MANAGEMENT_DASHBOARD_SITE = "dashboard";
|
|
3833
3875
|
var DASHBOARD_CREDENTIALS_FILE = join4(".ts-cloud", "dashboard-credentials.json");
|
|
3834
3876
|
function generatePassword() {
|
|
@@ -3865,12 +3907,6 @@ function truthy(v) {
|
|
|
3865
3907
|
return v != null && v !== "" && v !== "0" && v.toLowerCase() !== "false";
|
|
3866
3908
|
}
|
|
3867
3909
|
var LIVE_STAGE_DIR = join4(".ts-cloud", "dashboard-release");
|
|
3868
|
-
var CONFIG_CANDIDATES = [
|
|
3869
|
-
["config", "cloud.ts"],
|
|
3870
|
-
["config", "cloud.js"],
|
|
3871
|
-
["cloud.config.ts"],
|
|
3872
|
-
["cloud.config.js"]
|
|
3873
|
-
];
|
|
3874
3910
|
function resolveDashboardVersion() {
|
|
3875
3911
|
const explicit = process.env.TS_CLOUD_UI_VERSION?.trim();
|
|
3876
3912
|
if (explicit)
|
|
@@ -3885,22 +3921,15 @@ function resolveDashboardVersion() {
|
|
|
3885
3921
|
}
|
|
3886
3922
|
return "latest";
|
|
3887
3923
|
}
|
|
3888
|
-
function stageLiveDashboardRoot(cwd, logger) {
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
logger.warn("Management dashboard: no cloud config found to ship — skipping the live dashboard.");
|
|
3924
|
+
function stageLiveDashboardRoot(config, cwd, logger) {
|
|
3925
|
+
if (!config?.project?.slug) {
|
|
3926
|
+
logger.warn("Management dashboard: the cloud config has no project slug — skipping the live dashboard.");
|
|
3892
3927
|
return null;
|
|
3893
3928
|
}
|
|
3894
3929
|
const stage = join4(cwd, LIVE_STAGE_DIR);
|
|
3895
3930
|
try {
|
|
3896
3931
|
mkdirSync(stage, { recursive: true });
|
|
3897
|
-
|
|
3898
|
-
if (isStacksLayout) {
|
|
3899
|
-
mkdirSync(join4(stage, "config"), { recursive: true });
|
|
3900
|
-
copyFileSync(source, join4(stage, "config", source.endsWith(".ts") ? "cloud.ts" : "cloud.js"));
|
|
3901
|
-
} else {
|
|
3902
|
-
copyFileSync(source, join4(stage, source.endsWith(".ts") ? "cloud.config.ts" : "cloud.config.js"));
|
|
3903
|
-
}
|
|
3932
|
+
writeFileSync(join4(stage, "cloud.config.ts"), serializeDashboardConfig(config));
|
|
3904
3933
|
const pkg = {
|
|
3905
3934
|
name: "ts-cloud-dashboard",
|
|
3906
3935
|
private: true,
|
|
@@ -3946,7 +3975,7 @@ function ensureManagementDashboard(config, options = {}) {
|
|
|
3946
3975
|
const port = Number(process.env.TS_CLOUD_UI_PORT) || undefined;
|
|
3947
3976
|
const sites = { ...config.sites ?? {} };
|
|
3948
3977
|
if (!truthy(process.env.TS_CLOUD_UI_STATIC)) {
|
|
3949
|
-
const uiRoot = stageLiveDashboardRoot(cwd, logger);
|
|
3978
|
+
const uiRoot = stageLiveDashboardRoot(config, cwd, logger);
|
|
3950
3979
|
if (!uiRoot)
|
|
3951
3980
|
return config;
|
|
3952
3981
|
const resolved2 = resolveManagementDashboardSites(config, environment ?? "production", {
|
|
@@ -4729,7 +4758,7 @@ async function deployAllComputeSites(options) {
|
|
|
4729
4758
|
}
|
|
4730
4759
|
try {
|
|
4731
4760
|
const copy = join5(tmpdir2(), `${slug}-${name}-${sha}.tar.gz`);
|
|
4732
|
-
|
|
4761
|
+
copyFileSync(dashboardTarball, copy);
|
|
4733
4762
|
dashboardTarballBySite.set(name, copy);
|
|
4734
4763
|
} catch {
|
|
4735
4764
|
dashboardTarballBySite.set(name, dashboardTarball);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialize the resolved cloud config into a self-contained module for the
|
|
3
|
+
* dashboard to read on the box.
|
|
4
|
+
*
|
|
5
|
+
* Copying the project's `cloud.config.ts` verbatim does not work: a real config
|
|
6
|
+
* imports things. Stacks' does
|
|
7
|
+
* `import { servers } from '~/cloud/servers'` and `import { env } from
|
|
8
|
+
* '@stacksjs/env'` — neither the path alias nor the package exists in the
|
|
9
|
+
* dashboard's release dir, so the import would throw and the dashboard would
|
|
10
|
+
* come up describing nothing.
|
|
11
|
+
*
|
|
12
|
+
* The deploy machine has already resolved the config to a plain object, so we
|
|
13
|
+
* ship THAT as a literal. No imports, no aliases, nothing to resolve.
|
|
14
|
+
*
|
|
15
|
+
* Credentials are stripped on the way out (see {@link redactForDashboard}).
|
|
16
|
+
*/
|
|
17
|
+
import type { CloudConfig } from '@ts-cloud/core';
|
|
18
|
+
/**
|
|
19
|
+
* Strip everything the dashboard does not need to read.
|
|
20
|
+
*
|
|
21
|
+
* Two rules:
|
|
22
|
+
*
|
|
23
|
+
* 1. **No credentials.** The Hetzner API token is the big one: it controls the
|
|
24
|
+
* whole cloud account (create and destroy any server), and unlike a site's
|
|
25
|
+
* own secrets it is otherwise NOT on the box at all. Putting it in the
|
|
26
|
+
* dashboard's release would turn a dashboard compromise into an account
|
|
27
|
+
* compromise. AWS credentials go for the same reason.
|
|
28
|
+
*
|
|
29
|
+
* 2. **Env keys, not env values.** The dashboard only ever displays which env
|
|
30
|
+
* vars a site defines, never their values — so ship the keys and blank the
|
|
31
|
+
* values. The running site has its own `.env` on the box regardless; there
|
|
32
|
+
* is no reason for a second copy to sit in the dashboard's directory.
|
|
33
|
+
*/
|
|
34
|
+
export declare function redactForDashboard(config: CloudConfig): Record<string, any>;
|
|
35
|
+
/**
|
|
36
|
+
* The `cloud.config.ts` module text shipped in the dashboard's release. Reads
|
|
37
|
+
* as a plain literal so bun can import it on the box with nothing installed
|
|
38
|
+
* beyond the ts-cloud package itself.
|
|
39
|
+
*/
|
|
40
|
+
export declare function serializeDashboardConfig(config: CloudConfig): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/deploy/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
sanitizeCloudConfig,
|
|
13
13
|
setMaintenance,
|
|
14
14
|
startLocalDashboardServer
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-khfnaap2.js";
|
|
16
16
|
import {
|
|
17
17
|
buildAndPushServerlessImage
|
|
18
18
|
} from "../chunk-5mejsd43.js";
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
resolveUiSource,
|
|
31
31
|
siteInstallBase,
|
|
32
32
|
validateDeploymentConfig
|
|
33
|
-
} from "../chunk-
|
|
33
|
+
} from "../chunk-5cfcv2s2.js";
|
|
34
34
|
import"../chunk-0tfwdnmf.js";
|
|
35
35
|
import"../chunk-93hjhs78.js";
|
|
36
36
|
import {
|
|
@@ -71,15 +71,18 @@ export declare const LIVE_STAGE_DIR: string;
|
|
|
71
71
|
*/
|
|
72
72
|
export declare function resolveDashboardVersion(): string;
|
|
73
73
|
/**
|
|
74
|
-
* Stage the live dashboard's release: the
|
|
75
|
-
*
|
|
76
|
-
*
|
|
74
|
+
* Stage the live dashboard's release: the RESOLVED cloud config inlined as a
|
|
75
|
+
* self-contained module, plus a `package.json` whose install pulls the CLI and
|
|
76
|
+
* UI from npm.
|
|
77
77
|
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
78
|
+
* The config is serialized rather than copied because a real one imports things
|
|
79
|
+
* that do not exist on the box — Stacks' does `import { servers } from
|
|
80
|
+
* '~/cloud/servers'` — and the import would throw, leaving the dashboard with
|
|
81
|
+
* nothing to describe. Credentials are stripped on the way out.
|
|
82
|
+
*
|
|
83
|
+
* Returns the staged directory relative to `cwd`, or null when staging fails.
|
|
81
84
|
*/
|
|
82
|
-
export declare function stageLiveDashboardRoot(cwd: string, logger: EnsureDashboardLogger): string | null;
|
|
85
|
+
export declare function stageLiveDashboardRoot(config: CloudConfig, cwd: string, logger: EnsureDashboardLogger): string | null;
|
|
83
86
|
/**
|
|
84
87
|
* Resolve the UI source to ship (STATIC mode only — the live dashboard gets its
|
|
85
88
|
* UI from the npm package it installs on the box). Prefers the repo's local
|
package/dist/drivers/index.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -55,7 +55,7 @@ import {
|
|
|
55
55
|
sanitizeCloudConfig,
|
|
56
56
|
setMaintenance,
|
|
57
57
|
startLocalDashboardServer
|
|
58
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-khfnaap2.js";
|
|
59
59
|
import {
|
|
60
60
|
buildAndPushServerlessImage
|
|
61
61
|
} from "./chunk-5mejsd43.js";
|
|
@@ -105,7 +105,7 @@ import {
|
|
|
105
105
|
waitForCloudInit,
|
|
106
106
|
waitForSsh,
|
|
107
107
|
wrapCloudInitUserData
|
|
108
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-5cfcv2s2.js";
|
|
109
109
|
import {
|
|
110
110
|
ABTestManager,
|
|
111
111
|
AI,
|