@stacksjs/ts-cloud 0.7.2 → 0.7.4
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 +313 -313
- package/dist/drivers/aws/driver.d.ts +9 -0
- package/dist/drivers/index.d.ts +2 -2
- package/dist/index.js +112 -46
- 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/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
|
@@ -2,6 +2,14 @@ import type { CloudDriver, ComputeStackOutputs, ComputeTarget, FindComputeTarget
|
|
|
2
2
|
export interface AwsDriverOptions {
|
|
3
3
|
region?: string;
|
|
4
4
|
}
|
|
5
|
+
/**
|
|
6
|
+
* Local-state pin (parity with the Hetzner driver's shared-box support): a
|
|
7
|
+
* project riding an instance whose tags belong to another project records
|
|
8
|
+
* `{ "instanceId": "i-..." }` in `.ts-cloud/state/<stack>.json`, and target
|
|
9
|
+
* lookups trust that record when the tag scan finds nothing. Exported for
|
|
10
|
+
* tests.
|
|
11
|
+
*/
|
|
12
|
+
export declare function readPinnedInstanceId(stackName: string): string | null;
|
|
5
13
|
export declare class AwsDriver implements CloudDriver {
|
|
6
14
|
readonly name: "aws";
|
|
7
15
|
readonly usesCloudFormation = true;
|
|
@@ -26,6 +34,7 @@ export declare class AwsDriver implements CloudDriver {
|
|
|
26
34
|
getComputeOutputs(options: ProvisionComputeOptions): Promise<ComputeStackOutputs>;
|
|
27
35
|
uploadRelease(options: UploadReleaseOptions): Promise<UploadReleaseResult>;
|
|
28
36
|
findComputeTargets(options: FindComputeTargetsOptions): Promise<ComputeTarget[]>;
|
|
37
|
+
private reservationsToTargets;
|
|
29
38
|
/**
|
|
30
39
|
* SSM AWS-RunShellScript executes the joined commands with `/bin/sh` (dash on
|
|
31
40
|
* Ubuntu), which rejects bash-only syntax like `set -o pipefail`. Our deploy
|
package/dist/drivers/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export { HetznerClient, resolveHetznerApiToken } from './hetzner/client';
|
|
|
6
6
|
export { generateUbuntuAppCloudInit, wrapCloudInitUserData } from './hetzner/cloud-init';
|
|
7
7
|
export { buildAwsArtifactFetch, buildLocalArtifactFetch, buildSiteDeployScript, buildStaticSiteDeployScript, resolveExecStart, } from './shared/deploy-script';
|
|
8
8
|
export { deployAllComputeSites, deploySiteRelease, reloadRpxGateway } from './shared/compute-deploy';
|
|
9
|
-
export { buildRpxConfig, buildRpxProvisionScript, deriveRouteId, normalizeRoutePath, renderRpxLauncher, DEFAULT_RPX_CERTS_DIR, RPX_DIR, RPX_LAUNCHER_PATH, RPX_SERVICE_NAME, } from './shared/rpx-gateway';
|
|
10
|
-
export type { BuildRpxConfigOptions, BuildRpxProvisionOptions, RpxGatewayConfig, RpxRoute, } from './shared/rpx-gateway';
|
|
9
|
+
export { buildRpxConfig, buildRpxLbConfig, buildRpxProvisionScript, deriveRouteId, normalizeRoutePath, renderRpxLauncher, DEFAULT_RPX_CERTS_DIR, RPX_DIR, RPX_LAUNCHER_PATH, RPX_SERVICE_NAME, } from './shared/rpx-gateway';
|
|
10
|
+
export type { BuildRpxConfigOptions, BuildRpxProvisionOptions, RpxGatewayConfig, RpxLbAppBox, RpxRoute, } from './shared/rpx-gateway';
|
|
11
11
|
export { buildCloudFrontOriginConfig, MANAGED_CACHE_POLICY_DISABLED, MANAGED_CACHE_POLICY_OPTIMIZED, MANAGED_ORIGIN_REQUEST_POLICY_ALL_VIEWER, } from './shared/cloudfront-origin';
|
|
12
12
|
export type { BuildCloudFrontOriginOptions, OriginFrontedBehavior, } from './shared/cloudfront-origin';
|
package/dist/index.js
CHANGED
|
@@ -84592,12 +84592,12 @@ import { existsSync as existsSync26, statSync as statSync6 } from "node:fs";
|
|
|
84592
84592
|
import { readFile as readFile2, writeFile as writeFile6 } from "node:fs/promises";
|
|
84593
84593
|
import { mkdtempSync as mkdtempSync6 } from "node:fs";
|
|
84594
84594
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
84595
|
-
import { dirname as dirname9, extname as extname3, join as
|
|
84595
|
+
import { dirname as dirname9, extname as extname3, join as join25, normalize } from "node:path";
|
|
84596
84596
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
84597
84597
|
|
|
84598
84598
|
// src/deploy/dashboard-data-server.ts
|
|
84599
84599
|
import { existsSync as existsSync24, readFileSync as readFileSync18 } from "node:fs";
|
|
84600
|
-
import { join as
|
|
84600
|
+
import { join as join23 } from "node:path";
|
|
84601
84601
|
|
|
84602
84602
|
// src/drivers/factory.ts
|
|
84603
84603
|
await init_dist2();
|
|
@@ -84606,6 +84606,7 @@ await init_dist2();
|
|
|
84606
84606
|
init_cloudformation();
|
|
84607
84607
|
await init_dist2();
|
|
84608
84608
|
import { readFileSync as readFileSync15 } from "node:fs";
|
|
84609
|
+
import { join as join18 } from "node:path";
|
|
84609
84610
|
init_s3();
|
|
84610
84611
|
|
|
84611
84612
|
// src/drivers/shared/package-manager.ts
|
|
@@ -85716,6 +85717,16 @@ function resolveAwsImageId(config6) {
|
|
|
85716
85717
|
}
|
|
85717
85718
|
|
|
85718
85719
|
// src/drivers/aws/driver.ts
|
|
85720
|
+
function readPinnedInstanceId(stackName) {
|
|
85721
|
+
try {
|
|
85722
|
+
const raw = readFileSync15(join18(process.cwd(), ".ts-cloud/state", `${stackName}.json`), "utf8");
|
|
85723
|
+
const state = JSON.parse(raw);
|
|
85724
|
+
return typeof state.instanceId === "string" && state.instanceId.length > 0 ? state.instanceId : null;
|
|
85725
|
+
} catch {
|
|
85726
|
+
return null;
|
|
85727
|
+
}
|
|
85728
|
+
}
|
|
85729
|
+
|
|
85719
85730
|
class AwsDriver {
|
|
85720
85731
|
name = "aws";
|
|
85721
85732
|
usesCloudFormation = true;
|
|
@@ -85893,8 +85904,33 @@ class AwsDriver {
|
|
|
85893
85904
|
{ Name: "instance-state-name", Values: ["running", "pending"] }
|
|
85894
85905
|
];
|
|
85895
85906
|
const result = await ec22.describeInstances({ Filters: filters });
|
|
85907
|
+
const targets = this.reservationsToTargets(result.Reservations);
|
|
85908
|
+
if (targets.length > 0 || (options.role || "app") !== "app")
|
|
85909
|
+
return targets;
|
|
85910
|
+
const stackName = options.stackName ?? `${options.slug}-${options.environment}`;
|
|
85911
|
+
let pinnedId = readPinnedInstanceId(stackName);
|
|
85912
|
+
if (!pinnedId) {
|
|
85913
|
+
try {
|
|
85914
|
+
pinnedId = (await new CloudFormationClient(region).getStackOutputs(stackName)).appInstanceId ?? null;
|
|
85915
|
+
} catch {
|
|
85916
|
+
pinnedId = null;
|
|
85917
|
+
}
|
|
85918
|
+
}
|
|
85919
|
+
if (!pinnedId)
|
|
85920
|
+
return [];
|
|
85921
|
+
try {
|
|
85922
|
+
const pinned = await ec22.describeInstances({
|
|
85923
|
+
InstanceIds: [pinnedId],
|
|
85924
|
+
Filters: [{ Name: "instance-state-name", Values: ["running", "pending"] }]
|
|
85925
|
+
});
|
|
85926
|
+
return this.reservationsToTargets(pinned.Reservations);
|
|
85927
|
+
} catch {
|
|
85928
|
+
return [];
|
|
85929
|
+
}
|
|
85930
|
+
}
|
|
85931
|
+
reservationsToTargets(reservations) {
|
|
85896
85932
|
const targets = [];
|
|
85897
|
-
for (const reservation of
|
|
85933
|
+
for (const reservation of reservations || []) {
|
|
85898
85934
|
for (const instance of reservation.Instances || []) {
|
|
85899
85935
|
if (!instance.InstanceId)
|
|
85900
85936
|
continue;
|
|
@@ -85987,7 +86023,7 @@ class AwsDriver {
|
|
|
85987
86023
|
await init_dist2();
|
|
85988
86024
|
import { existsSync as existsSync20, readFileSync as readFileSync16 } from "node:fs";
|
|
85989
86025
|
import { homedir as homedir8 } from "node:os";
|
|
85990
|
-
import { join as
|
|
86026
|
+
import { join as join20 } from "node:path";
|
|
85991
86027
|
import { execSync as execSync3 } from "node:child_process";
|
|
85992
86028
|
|
|
85993
86029
|
// src/drivers/hetzner/client.ts
|
|
@@ -86291,6 +86327,17 @@ function buildRpxConfigInternal(sites, options, appBoxes) {
|
|
|
86291
86327
|
}
|
|
86292
86328
|
domains.add(site.domain);
|
|
86293
86329
|
}
|
|
86330
|
+
if (options.proxy.autoWww !== false) {
|
|
86331
|
+
for (const domain of [...domains]) {
|
|
86332
|
+
if (domain.split(".").length !== 2)
|
|
86333
|
+
continue;
|
|
86334
|
+
const wwwDomain = `www.${domain}`;
|
|
86335
|
+
if (domains.has(wwwDomain))
|
|
86336
|
+
continue;
|
|
86337
|
+
proxies.push({ to: wwwDomain, redirect: { to: `https://${domain}` }, id: deriveRouteId(wwwDomain) });
|
|
86338
|
+
domains.add(wwwDomain);
|
|
86339
|
+
}
|
|
86340
|
+
}
|
|
86294
86341
|
proxies.sort((a, b) => {
|
|
86295
86342
|
if (a.to !== b.to)
|
|
86296
86343
|
return a.to.localeCompare(b.to);
|
|
@@ -86607,10 +86654,10 @@ function matchesTsCloudLabels(labels, slug, environment, role = "app") {
|
|
|
86607
86654
|
|
|
86608
86655
|
// src/drivers/hetzner/state.ts
|
|
86609
86656
|
import { mkdir as mkdir4, readFile, writeFile as writeFile4 } from "node:fs/promises";
|
|
86610
|
-
import { join as
|
|
86657
|
+
import { join as join19 } from "node:path";
|
|
86611
86658
|
var STATE_DIR = ".ts-cloud/state";
|
|
86612
86659
|
function driverStatePath(stackName) {
|
|
86613
|
-
return
|
|
86660
|
+
return join19(process.cwd(), STATE_DIR, `${stackName}.json`);
|
|
86614
86661
|
}
|
|
86615
86662
|
async function readDriverState(stackName) {
|
|
86616
86663
|
try {
|
|
@@ -86622,7 +86669,7 @@ async function readDriverState(stackName) {
|
|
|
86622
86669
|
}
|
|
86623
86670
|
async function writeDriverState(stackName, state) {
|
|
86624
86671
|
const path = driverStatePath(stackName);
|
|
86625
|
-
await mkdir4(
|
|
86672
|
+
await mkdir4(join19(process.cwd(), STATE_DIR), { recursive: true });
|
|
86626
86673
|
await writeFile4(path, `${JSON.stringify(state, null, 2)}
|
|
86627
86674
|
`, "utf8");
|
|
86628
86675
|
}
|
|
@@ -86630,7 +86677,7 @@ async function writeDriverState(stackName, state) {
|
|
|
86630
86677
|
// src/drivers/hetzner/driver.ts
|
|
86631
86678
|
var SSH_MAX_BUFFER = 1024 * 1024 * 256;
|
|
86632
86679
|
function expandHome(path) {
|
|
86633
|
-
return path.startsWith("~/") ?
|
|
86680
|
+
return path.startsWith("~/") ? join20(homedir8(), path.slice(2)) : path;
|
|
86634
86681
|
}
|
|
86635
86682
|
|
|
86636
86683
|
class HetznerDriver {
|
|
@@ -86952,7 +86999,8 @@ class HetznerDriver {
|
|
|
86952
86999
|
const newServerIds = [];
|
|
86953
87000
|
let servicesServerId;
|
|
86954
87001
|
let servicesPrivateIp;
|
|
86955
|
-
|
|
87002
|
+
const wantsServicesBox = !!compute.servicesServer || !!compute.managedServices;
|
|
87003
|
+
if (topology.dedicatedServices && wantsServicesBox) {
|
|
86956
87004
|
const { firewall: svcFw } = await this.ensureFirewall(`${slug}-${environment}-services-fw`, tsCloudLabels(slug, environment, "services"), [
|
|
86957
87005
|
{ direction: "in", protocol: "tcp", port: "22", source_ips: ["0.0.0.0/0", "::/0"] },
|
|
86958
87006
|
{ direction: "in", protocol: "tcp", port: "3306", source_ips: [network.ip_range] },
|
|
@@ -87194,7 +87242,8 @@ class HetznerDriver {
|
|
|
87194
87242
|
const targets = await this.findComputeTargets({
|
|
87195
87243
|
slug: options.config.project.slug,
|
|
87196
87244
|
environment: options.environment,
|
|
87197
|
-
role: "app"
|
|
87245
|
+
role: "app",
|
|
87246
|
+
stackName: resolveProjectStackName(options.config, options.environment)
|
|
87198
87247
|
});
|
|
87199
87248
|
const first = targets[0];
|
|
87200
87249
|
return {
|
|
@@ -87208,7 +87257,8 @@ class HetznerDriver {
|
|
|
87208
87257
|
const targets = options.targets?.length ? options.targets : await this.findComputeTargets({
|
|
87209
87258
|
slug: options.config.project.slug,
|
|
87210
87259
|
environment: options.environment,
|
|
87211
|
-
role: "app"
|
|
87260
|
+
role: "app",
|
|
87261
|
+
stackName: resolveProjectStackName(options.config, options.environment)
|
|
87212
87262
|
});
|
|
87213
87263
|
if (targets.length === 0) {
|
|
87214
87264
|
throw new Error("No Hetzner compute targets found for release upload");
|
|
@@ -87236,6 +87286,20 @@ class HetznerDriver {
|
|
|
87236
87286
|
const exact = servers.filter((server) => matchesTsCloudLabels(server.labels, options.slug, options.environment, role));
|
|
87237
87287
|
if (exact.length > 0)
|
|
87238
87288
|
return exact.map(toTarget);
|
|
87289
|
+
if (role === "app") {
|
|
87290
|
+
const state = await readDriverState(options.stackName ?? `${options.slug}-${options.environment}`);
|
|
87291
|
+
const pinnedIds = [state?.serverId, ...state?.appServerIds ?? []].filter((id) => typeof id === "number");
|
|
87292
|
+
if (pinnedIds.length > 0) {
|
|
87293
|
+
const pinned = [];
|
|
87294
|
+
for (const id of pinnedIds) {
|
|
87295
|
+
const server = servers.find((candidate) => candidate.id === id) ?? await this.tryGetServer(id);
|
|
87296
|
+
if (server && server.status !== "off")
|
|
87297
|
+
pinned.push(server);
|
|
87298
|
+
}
|
|
87299
|
+
if (pinned.length > 0)
|
|
87300
|
+
return pinned.map(toTarget);
|
|
87301
|
+
}
|
|
87302
|
+
}
|
|
87239
87303
|
if (role === "app") {
|
|
87240
87304
|
const candidates = servers.filter((server) => server.status !== "off" && server.labels?.[`${TS_CLOUD_LABEL_PREFIX}/managed-by`] === "ts-cloud" && server.labels?.[`${TS_CLOUD_LABEL_PREFIX}/environment`] === options.environment && server.labels?.[`${TS_CLOUD_LABEL_PREFIX}/role`] === "app");
|
|
87241
87305
|
if (candidates.length === 1)
|
|
@@ -87718,10 +87782,10 @@ import { execSync as execSync5 } from "node:child_process";
|
|
|
87718
87782
|
import { randomBytes as randomBytes6 } from "node:crypto";
|
|
87719
87783
|
import { chmodSync, existsSync as existsSync21, mkdirSync as mkdirSync9, readFileSync as readFileSync17, writeFileSync as writeFileSync12 } from "node:fs";
|
|
87720
87784
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
87721
|
-
import { dirname as dirname8, isAbsolute as isAbsolute5, join as
|
|
87785
|
+
import { dirname as dirname8, isAbsolute as isAbsolute5, join as join21 } from "node:path";
|
|
87722
87786
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
87723
87787
|
var MANAGEMENT_DASHBOARD_SITE = "dashboard";
|
|
87724
|
-
var DASHBOARD_CREDENTIALS_FILE =
|
|
87788
|
+
var DASHBOARD_CREDENTIALS_FILE = join21(".ts-cloud", "dashboard-credentials.json");
|
|
87725
87789
|
function generatePassword() {
|
|
87726
87790
|
return randomBytes6(24).toString("base64url");
|
|
87727
87791
|
}
|
|
@@ -87731,7 +87795,7 @@ function resolveDashboardAuth(cwd, username, logger4) {
|
|
|
87731
87795
|
return { password: explicit, source: "env" };
|
|
87732
87796
|
if (truthy(process.env.TS_CLOUD_UI_PUBLIC))
|
|
87733
87797
|
return { password: undefined, source: "public" };
|
|
87734
|
-
const file =
|
|
87798
|
+
const file = join21(cwd, DASHBOARD_CREDENTIALS_FILE);
|
|
87735
87799
|
try {
|
|
87736
87800
|
if (existsSync21(file)) {
|
|
87737
87801
|
const saved = JSON.parse(readFileSync17(file, "utf8"));
|
|
@@ -87756,18 +87820,18 @@ function truthy(v) {
|
|
|
87756
87820
|
return v != null && v !== "" && v !== "0" && v.toLowerCase() !== "false";
|
|
87757
87821
|
}
|
|
87758
87822
|
function resolveUiSource(cwd) {
|
|
87759
|
-
if (existsSync21(
|
|
87823
|
+
if (existsSync21(join21(cwd, "packages", "ui", "pages")) || existsSync21(join21(cwd, "packages", "ui", "package.json"))) {
|
|
87760
87824
|
return { uiRoot: "packages/ui/dist", build: "cd packages/ui && bun install && bun run build" };
|
|
87761
87825
|
}
|
|
87762
87826
|
const here = dirname8(fileURLToPath4(import.meta.url));
|
|
87763
87827
|
const candidates = [
|
|
87764
|
-
|
|
87765
|
-
|
|
87766
|
-
|
|
87767
|
-
|
|
87828
|
+
join21(here, "ui"),
|
|
87829
|
+
join21(here, "..", "ui"),
|
|
87830
|
+
join21(here, "..", "..", "ui"),
|
|
87831
|
+
join21(here, "..", "dist", "ui")
|
|
87768
87832
|
];
|
|
87769
87833
|
for (const dir of candidates) {
|
|
87770
|
-
if (existsSync21(
|
|
87834
|
+
if (existsSync21(join21(dir, "index.html")) || existsSync21(join21(dir, "serverless.html")))
|
|
87771
87835
|
return { uiRoot: dir, build: false };
|
|
87772
87836
|
}
|
|
87773
87837
|
return null;
|
|
@@ -87820,12 +87884,12 @@ function buildManagementDashboardArtifact(site, options) {
|
|
|
87820
87884
|
logger4.info(`Management dashboard: building UI (${site.build})`);
|
|
87821
87885
|
execSync5(site.build, { cwd, stdio: "inherit" });
|
|
87822
87886
|
}
|
|
87823
|
-
const root = isAbsolute5(site.root) ? site.root :
|
|
87887
|
+
const root = isAbsolute5(site.root) ? site.root : join21(cwd, site.root);
|
|
87824
87888
|
if (!existsSync21(root)) {
|
|
87825
87889
|
logger4.warn(`Management dashboard: build output not found at ${root} — skipping dashboard artifact.`);
|
|
87826
87890
|
return null;
|
|
87827
87891
|
}
|
|
87828
|
-
const tarball =
|
|
87892
|
+
const tarball = join21(tmpdir6(), `${options.slug}-${MANAGEMENT_DASHBOARD_SITE}-${options.sha}.tar.gz`);
|
|
87829
87893
|
execSync5(`tar czf "${tarball}" -C "${root}" .`, { stdio: "inherit" });
|
|
87830
87894
|
return tarball;
|
|
87831
87895
|
} catch (error2) {
|
|
@@ -88354,10 +88418,11 @@ async function deploySiteRelease(driver, options, logger4 = noopLogger2) {
|
|
|
88354
88418
|
const targets = await driver.findComputeTargets({
|
|
88355
88419
|
slug,
|
|
88356
88420
|
environment,
|
|
88357
|
-
role: "app"
|
|
88421
|
+
role: "app",
|
|
88422
|
+
stackName
|
|
88358
88423
|
});
|
|
88359
88424
|
if (targets.length === 0) {
|
|
88360
|
-
const hint = driver.name === "aws" ? `Stack '${stackName}' has no EC2 instances tagged Project=${slug} Environment=${environment} Role=app.` : `No Hetzner servers labeled ts-cloud/project=${slug} ts-cloud/environment=${environment} ts-cloud/role=app.`;
|
|
88425
|
+
const hint = driver.name === "aws" ? `Stack '${stackName}' has no EC2 instances tagged Project=${slug} Environment=${environment} Role=app, and .ts-cloud/state/${stackName}.json pins no live instance. For a shared box, record its instanceId there.` : `No Hetzner servers labeled ts-cloud/project=${slug} ts-cloud/environment=${environment} ts-cloud/role=app, and .ts-cloud/state/${stackName}.json pins no live server. For a shared box, record its serverId there.`;
|
|
88361
88426
|
return { success: false, error: hint };
|
|
88362
88427
|
}
|
|
88363
88428
|
if (isPhpSite(site)) {
|
|
@@ -88587,7 +88652,8 @@ async function reloadRpxGateway(options) {
|
|
|
88587
88652
|
const targets = await driver.findComputeTargets({
|
|
88588
88653
|
slug: config6.project.slug,
|
|
88589
88654
|
environment,
|
|
88590
|
-
role: "app"
|
|
88655
|
+
role: "app",
|
|
88656
|
+
stackName: resolveProjectStackName(config6, environment)
|
|
88591
88657
|
});
|
|
88592
88658
|
if (targets.length === 0) {
|
|
88593
88659
|
logger4.warn("rpx gateway: no compute targets found — skipping gateway reload.");
|
|
@@ -88876,7 +88942,7 @@ function configuredRegion(config6) {
|
|
|
88876
88942
|
return config6.project.region ?? "us-east-1";
|
|
88877
88943
|
}
|
|
88878
88944
|
function loadLocalState(config6, environment) {
|
|
88879
|
-
const statePath =
|
|
88945
|
+
const statePath = join23(process.cwd(), ".ts-cloud", "state", `${config6.project.slug}-${environment}.json`);
|
|
88880
88946
|
if (!existsSync24(statePath))
|
|
88881
88947
|
return null;
|
|
88882
88948
|
try {
|
|
@@ -90837,10 +90903,10 @@ function selectedEnvironment(config6, requested) {
|
|
|
90837
90903
|
}
|
|
90838
90904
|
async function loadLocalEnv(cwd) {
|
|
90839
90905
|
const candidates = [
|
|
90840
|
-
|
|
90841
|
-
|
|
90842
|
-
|
|
90843
|
-
|
|
90906
|
+
join25(here, "..", "..", "..", "..", ".env"),
|
|
90907
|
+
join25(cwd, ".env"),
|
|
90908
|
+
join25(cwd, ".env.local"),
|
|
90909
|
+
join25(cwd, ".env.production")
|
|
90844
90910
|
];
|
|
90845
90911
|
for (const file of candidates) {
|
|
90846
90912
|
if (!existsSync26(file))
|
|
@@ -90864,10 +90930,10 @@ async function loadLocalEnv(cwd) {
|
|
|
90864
90930
|
}
|
|
90865
90931
|
function resolveCloudConfigPath(cwd) {
|
|
90866
90932
|
const candidates = [
|
|
90867
|
-
|
|
90868
|
-
|
|
90869
|
-
|
|
90870
|
-
|
|
90933
|
+
join25(cwd, "config", "cloud.ts"),
|
|
90934
|
+
join25(cwd, "config", "cloud.js"),
|
|
90935
|
+
join25(cwd, "cloud.config.ts"),
|
|
90936
|
+
join25(cwd, "cloud.config.js")
|
|
90871
90937
|
];
|
|
90872
90938
|
return candidates.find((file) => existsSync26(file)) ?? null;
|
|
90873
90939
|
}
|
|
@@ -90907,15 +90973,15 @@ async function resolveLiveDashboardData(config6, environment) {
|
|
|
90907
90973
|
}
|
|
90908
90974
|
function resolveUiSourceDir(cwd) {
|
|
90909
90975
|
const candidates = [
|
|
90910
|
-
|
|
90911
|
-
|
|
90912
|
-
|
|
90913
|
-
|
|
90914
|
-
|
|
90915
|
-
|
|
90976
|
+
join25(cwd, "packages", "ui"),
|
|
90977
|
+
join25(here, "..", "..", "..", "ui"),
|
|
90978
|
+
join25(here, "..", "..", "ui"),
|
|
90979
|
+
join25(here, "..", "ui-src"),
|
|
90980
|
+
join25(here, "..", "..", "ui-src"),
|
|
90981
|
+
join25(here, "..", "..", "dist", "ui-src")
|
|
90916
90982
|
];
|
|
90917
90983
|
for (const dir of candidates) {
|
|
90918
|
-
if (existsSync26(
|
|
90984
|
+
if (existsSync26(join25(dir, "pages")) && existsSync26(join25(dir, "package.json")))
|
|
90919
90985
|
return dir;
|
|
90920
90986
|
}
|
|
90921
90987
|
return null;
|
|
@@ -90925,8 +90991,8 @@ async function buildLiveUi(cwd, data) {
|
|
|
90925
90991
|
if (!uiDir)
|
|
90926
90992
|
return null;
|
|
90927
90993
|
try {
|
|
90928
|
-
const outDir = mkdtempSync6(
|
|
90929
|
-
const localStx =
|
|
90994
|
+
const outDir = mkdtempSync6(join25(tmpdir7(), "ts-cloud-dashboard-"));
|
|
90995
|
+
const localStx = join25(uiDir, "node_modules", ".bin", "stx");
|
|
90930
90996
|
const cmd = existsSync26(localStx) ? [localStx, "build", "--pages", "pages", "--out", outDir, "--no-sitemap", "--no-cache"] : ["bunx", "--bun", "@stacksjs/stx", "build", "--pages", "pages", "--out", outDir, "--no-sitemap", "--no-cache"];
|
|
90931
90997
|
const proc = Bun.spawn(cmd, {
|
|
90932
90998
|
cwd: uiDir,
|
|
@@ -91066,13 +91132,13 @@ function staticPath(uiRoot, pathname) {
|
|
|
91066
91132
|
const normalized = normalize(wanted);
|
|
91067
91133
|
if (normalized.startsWith("..") || normalized.includes("/../"))
|
|
91068
91134
|
return null;
|
|
91069
|
-
const base =
|
|
91135
|
+
const base = join25(uiRoot, normalized);
|
|
91070
91136
|
if (existsSync26(base) && !statSync6(base).isDirectory())
|
|
91071
91137
|
return base;
|
|
91072
91138
|
if (!extname3(base) && existsSync26(`${base}.html`))
|
|
91073
91139
|
return `${base}.html`;
|
|
91074
|
-
if (!extname3(base) && existsSync26(
|
|
91075
|
-
return
|
|
91140
|
+
if (!extname3(base) && existsSync26(join25(base, "index.html")))
|
|
91141
|
+
return join25(base, "index.html");
|
|
91076
91142
|
return null;
|
|
91077
91143
|
}
|
|
91078
91144
|
async function serveStatic(uiRoot, pathname) {
|