@ts-cloud/core 0.7.10 → 0.7.12
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/index.js +65 -28
- package/dist/presets/management-dashboard.d.ts +37 -6
- package/dist/types.d.ts +17 -2
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -22337,27 +22337,44 @@ function apexOf(domain) {
|
|
|
22337
22337
|
const parts = domain.split(".").filter(Boolean);
|
|
22338
22338
|
return parts.length <= 2 ? domain : parts.slice(-2).join(".");
|
|
22339
22339
|
}
|
|
22340
|
-
function
|
|
22341
|
-
if (explicit)
|
|
22342
|
-
return explicit;
|
|
22340
|
+
function collectDomains(config, environment) {
|
|
22343
22341
|
const candidates = [];
|
|
22342
|
+
const dnsDomain = config.infrastructure?.dns?.domain;
|
|
22343
|
+
if (dnsDomain)
|
|
22344
|
+
candidates.push(dnsDomain);
|
|
22345
|
+
if (environment && config.environments?.[environment]?.domain)
|
|
22346
|
+
candidates.push(config.environments[environment].domain);
|
|
22344
22347
|
for (const site of Object.values(config.sites ?? {})) {
|
|
22345
|
-
const
|
|
22348
|
+
const s = site;
|
|
22349
|
+
if (!s || s.redirect)
|
|
22350
|
+
continue;
|
|
22351
|
+
const d = s.domain;
|
|
22346
22352
|
if (typeof d === "string")
|
|
22347
22353
|
candidates.push(d);
|
|
22348
22354
|
else if (Array.isArray(d))
|
|
22349
22355
|
candidates.push(...d.filter((x) => typeof x === "string"));
|
|
22350
22356
|
}
|
|
22351
|
-
|
|
22352
|
-
|
|
22353
|
-
|
|
22354
|
-
if (
|
|
22355
|
-
|
|
22356
|
-
const base =
|
|
22357
|
+
return candidates.filter((d) => d && !d.startsWith("dashboard."));
|
|
22358
|
+
}
|
|
22359
|
+
function resolveDashboardDomain(config, environment, explicit) {
|
|
22360
|
+
if (explicit)
|
|
22361
|
+
return explicit;
|
|
22362
|
+
const base = collectDomains(config, environment)[0];
|
|
22357
22363
|
if (!base)
|
|
22358
22364
|
return null;
|
|
22359
22365
|
return `dashboard.${apexOf(base)}`;
|
|
22360
22366
|
}
|
|
22367
|
+
function resolveDashboardDomains(config, environment, explicit) {
|
|
22368
|
+
if (explicit)
|
|
22369
|
+
return [explicit];
|
|
22370
|
+
const apexes = [];
|
|
22371
|
+
for (const d of collectDomains(config, environment)) {
|
|
22372
|
+
const apex = apexOf(d);
|
|
22373
|
+
if (!apexes.includes(apex))
|
|
22374
|
+
apexes.push(apex);
|
|
22375
|
+
}
|
|
22376
|
+
return apexes.map((apex) => `dashboard.${apex}`);
|
|
22377
|
+
}
|
|
22361
22378
|
function hasManagementDashboardSite(config) {
|
|
22362
22379
|
return Object.entries(config.sites ?? {}).some(([name, site]) => {
|
|
22363
22380
|
if (!site)
|
|
@@ -22366,37 +22383,53 @@ function hasManagementDashboardSite(config) {
|
|
|
22366
22383
|
return name === "dashboard" || root === "ui/dist" || root.endsWith("/ui/dist") || root.endsWith("/dist/ui");
|
|
22367
22384
|
});
|
|
22368
22385
|
}
|
|
22369
|
-
|
|
22386
|
+
var MANAGEMENT_DASHBOARD_SITE_PREFIX = "dashboard-";
|
|
22387
|
+
function dashboardSiteName(domain, primary) {
|
|
22388
|
+
if (primary)
|
|
22389
|
+
return "dashboard";
|
|
22390
|
+
return MANAGEMENT_DASHBOARD_SITE_PREFIX + domain.replace(/^dashboard\./, "").replace(/\./g, "-");
|
|
22391
|
+
}
|
|
22392
|
+
function isManagementDashboardSiteName(name) {
|
|
22393
|
+
return name === "dashboard" || name.startsWith(MANAGEMENT_DASHBOARD_SITE_PREFIX);
|
|
22394
|
+
}
|
|
22395
|
+
function resolveManagementDashboardSites(config, environment, opts) {
|
|
22370
22396
|
if (hasManagementDashboardSite(config))
|
|
22371
|
-
return
|
|
22372
|
-
const domain = resolveDashboardDomain(config, environment, opts.domain);
|
|
22373
|
-
if (!domain)
|
|
22374
|
-
return null;
|
|
22397
|
+
return [];
|
|
22375
22398
|
const auth2 = opts.password ? { auth: { username: opts.username || "admin", password: opts.password, realm: opts.realm } } : {};
|
|
22399
|
+
const build = opts.build === false || opts.build === undefined ? {} : { build: opts.build };
|
|
22376
22400
|
if (opts.live) {
|
|
22401
|
+
const domain = resolveDashboardDomain(config, environment, opts.domain);
|
|
22402
|
+
if (!domain)
|
|
22403
|
+
return [];
|
|
22377
22404
|
const port = opts.port ?? 7676;
|
|
22378
|
-
const
|
|
22405
|
+
const site = {
|
|
22379
22406
|
root: opts.uiRoot,
|
|
22380
22407
|
deploy: "server",
|
|
22381
22408
|
domain,
|
|
22382
22409
|
start: `cloud dashboard:serve --box --host 127.0.0.1 --port ${port}`,
|
|
22383
22410
|
port,
|
|
22384
22411
|
ssl: { provider: "letsencrypt" },
|
|
22385
|
-
...
|
|
22412
|
+
...build,
|
|
22386
22413
|
...auth2
|
|
22387
22414
|
};
|
|
22388
|
-
return { name: "dashboard", site
|
|
22415
|
+
return [{ name: "dashboard", site }];
|
|
22389
22416
|
}
|
|
22390
|
-
const
|
|
22391
|
-
|
|
22392
|
-
|
|
22393
|
-
|
|
22394
|
-
|
|
22395
|
-
|
|
22396
|
-
|
|
22397
|
-
|
|
22398
|
-
|
|
22399
|
-
|
|
22417
|
+
const domains = resolveDashboardDomains(config, environment, opts.domain);
|
|
22418
|
+
return domains.map((domain, i) => ({
|
|
22419
|
+
name: dashboardSiteName(domain, i === 0),
|
|
22420
|
+
site: {
|
|
22421
|
+
root: opts.uiRoot,
|
|
22422
|
+
deploy: "server",
|
|
22423
|
+
type: "static",
|
|
22424
|
+
domain,
|
|
22425
|
+
ssl: { provider: "letsencrypt" },
|
|
22426
|
+
...build,
|
|
22427
|
+
...auth2
|
|
22428
|
+
}
|
|
22429
|
+
}));
|
|
22430
|
+
}
|
|
22431
|
+
function resolveManagementDashboardSite(config, environment, opts) {
|
|
22432
|
+
return resolveManagementDashboardSites(config, environment, opts)[0] ?? null;
|
|
22400
22433
|
}
|
|
22401
22434
|
// src/presets/extend.ts
|
|
22402
22435
|
function deepMerge(target, source) {
|
|
@@ -47207,9 +47240,11 @@ export {
|
|
|
47207
47240
|
resolveQueues,
|
|
47208
47241
|
resolveQueueNames,
|
|
47209
47242
|
resolveProjectStackName,
|
|
47243
|
+
resolveManagementDashboardSites,
|
|
47210
47244
|
resolveManagementDashboardSite,
|
|
47211
47245
|
resolveDeploymentMode,
|
|
47212
47246
|
resolveDeployBucketName,
|
|
47247
|
+
resolveDashboardDomains,
|
|
47213
47248
|
resolveDashboardDomain,
|
|
47214
47249
|
resolveCredentials,
|
|
47215
47250
|
resolveCloudProvider,
|
|
@@ -47255,6 +47290,7 @@ export {
|
|
|
47255
47290
|
isWebCryptoAvailable,
|
|
47256
47291
|
isValidRegion,
|
|
47257
47292
|
isNodeCryptoAvailable,
|
|
47293
|
+
isManagementDashboardSiteName,
|
|
47258
47294
|
isLocalDevelopment,
|
|
47259
47295
|
isLikelyTypo,
|
|
47260
47296
|
imageScanningManager,
|
|
@@ -47479,6 +47515,7 @@ export {
|
|
|
47479
47515
|
MigrationManager,
|
|
47480
47516
|
MetricsManager,
|
|
47481
47517
|
Messaging,
|
|
47518
|
+
MANAGEMENT_DASHBOARD_SITE_PREFIX,
|
|
47482
47519
|
MANAGED_NODE_VERSIONS,
|
|
47483
47520
|
LogsManager,
|
|
47484
47521
|
LambdaVersionsManager,
|
|
@@ -35,17 +35,48 @@ export interface ManagementDashboardOptions {
|
|
|
35
35
|
port?: number;
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
|
-
* Derive
|
|
39
|
-
*
|
|
40
|
-
* then
|
|
38
|
+
* Derive the PRIMARY dashboard hostname (`dashboard.<apex>`) for the project.
|
|
39
|
+
* Prefers `explicit`, else the project's canonical domain (`infrastructure.dns.domain`,
|
|
40
|
+
* then the environment domain), else the first site domain. Returns null when
|
|
41
|
+
* nothing is available.
|
|
41
42
|
*/
|
|
42
43
|
export declare function resolveDashboardDomain(config: Pick<CloudConfig, 'sites' | 'environments' | 'infrastructure'>, environment?: EnvironmentType, explicit?: string): string | null;
|
|
44
|
+
/**
|
|
45
|
+
* Derive EVERY dashboard hostname the project should expose — one
|
|
46
|
+
* `dashboard.<apex>` per distinct registrable apex across all configured
|
|
47
|
+
* domains, so each site gets a dashboard on its own domain. Deduped by apex,
|
|
48
|
+
* order-preserving (the first-seen apex leads, and stays the "primary").
|
|
49
|
+
*
|
|
50
|
+
* An `explicit` domain (e.g. `TS_CLOUD_UI_DOMAIN`) pins a single host and
|
|
51
|
+
* suppresses the per-apex fan-out — an operator asking for one host gets one.
|
|
52
|
+
*/
|
|
53
|
+
export declare function resolveDashboardDomains(config: Pick<CloudConfig, 'sites' | 'environments' | 'infrastructure'>, environment?: EnvironmentType, explicit?: string): string[];
|
|
43
54
|
/** Does the config already define the management dashboard as a site? */
|
|
44
55
|
export declare function hasManagementDashboardSite(config: Pick<CloudConfig, 'sites'>): boolean;
|
|
56
|
+
/** Prefix under which non-primary per-apex dashboards are keyed. */
|
|
57
|
+
export declare const MANAGEMENT_DASHBOARD_SITE_PREFIX = "dashboard-";
|
|
58
|
+
/** Is `name` a management-dashboard site key (the primary or a per-apex one)? */
|
|
59
|
+
export declare function isManagementDashboardSiteName(name: string): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Build EVERY management-dashboard site to auto-inject on a server deploy — one
|
|
62
|
+
* per distinct apex domain (each site's own `dashboard.<apex>` host), all sharing
|
|
63
|
+
* the same UI artifact and Basic-auth credentials. Returns an empty array when no
|
|
64
|
+
* domain resolves (the static-site model is domain-routed) or the user already
|
|
65
|
+
* configured a dashboard site by hand.
|
|
66
|
+
*
|
|
67
|
+
* Live mode stays single-host: a box-mode service binds one loopback port, so
|
|
68
|
+
* fanning it out per apex would collide. Per-apex dashboards are a static-model
|
|
69
|
+
* feature (the default) — the same files served on each domain.
|
|
70
|
+
*/
|
|
71
|
+
export declare function resolveManagementDashboardSites(config: Pick<CloudConfig, 'sites' | 'environments' | 'infrastructure'>, environment: EnvironmentType, opts: ManagementDashboardOptions): Array<{
|
|
72
|
+
name: string;
|
|
73
|
+
site: SiteConfig;
|
|
74
|
+
}>;
|
|
45
75
|
/**
|
|
46
|
-
* Build the management-dashboard site
|
|
47
|
-
*
|
|
48
|
-
*
|
|
76
|
+
* Build the primary management-dashboard site (the `dashboard.<apex>` on the
|
|
77
|
+
* project's first domain), or null when none resolves / one is already
|
|
78
|
+
* configured. Thin wrapper over {@link resolveManagementDashboardSites} kept for
|
|
79
|
+
* callers that only want the single primary host.
|
|
49
80
|
*/
|
|
50
81
|
export declare function resolveManagementDashboardSite(config: Pick<CloudConfig, 'sites' | 'environments' | 'infrastructure'>, environment: EnvironmentType, opts: ManagementDashboardOptions): {
|
|
51
82
|
name: string;
|
package/dist/types.d.ts
CHANGED
|
@@ -7,6 +7,16 @@ export interface CloudProviderConfig {
|
|
|
7
7
|
* @default 'aws'
|
|
8
8
|
*/
|
|
9
9
|
provider?: 'aws' | 'hetzner';
|
|
10
|
+
/**
|
|
11
|
+
* Attach this project's sites to a box owned by ANOTHER project instead of
|
|
12
|
+
* provisioning one. Set to the owner project's `project.slug` (e.g. `'stacks'`);
|
|
13
|
+
* the deploy targets the owner's `<slug>-<environment>-app` server, ships only
|
|
14
|
+
* this project's sites, and adds its own additive rpx `sites.d/<slug>.json`
|
|
15
|
+
* fragment + DNS — never touching the owner's box lifecycle, firewall, or other
|
|
16
|
+
* tenants. The owner provisions and manages the shared box; attachers only
|
|
17
|
+
* deploy onto it. Requires read access via the same `HCLOUD_TOKEN`.
|
|
18
|
+
*/
|
|
19
|
+
attachTo?: string;
|
|
10
20
|
}
|
|
11
21
|
/**
|
|
12
22
|
* Object storage provider selection.
|
|
@@ -1260,7 +1270,7 @@ export interface BucketConfig {
|
|
|
1260
1270
|
}
|
|
1261
1271
|
export interface DatabaseConfig {
|
|
1262
1272
|
type?: 'rds' | 'dynamodb';
|
|
1263
|
-
engine?: 'postgres' | 'mysql' | 'mariadb';
|
|
1273
|
+
engine?: 'postgres' | 'mysql' | 'mariadb' | 'singlestore';
|
|
1264
1274
|
instanceType?: string;
|
|
1265
1275
|
/** Database/schema name to create (e.g. `forge`). */
|
|
1266
1276
|
name?: string;
|
|
@@ -1270,8 +1280,13 @@ export interface DatabaseConfig {
|
|
|
1270
1280
|
password?: string;
|
|
1271
1281
|
/** Hostname for a managed/external database (default `127.0.0.1` on-box). */
|
|
1272
1282
|
host?: string;
|
|
1273
|
-
/** Port (defaults: mysql/mariadb 3306, postgres 5432). */
|
|
1283
|
+
/** Port (defaults: mysql/mariadb/singlestore 3306, postgres 5432). */
|
|
1274
1284
|
port?: number;
|
|
1285
|
+
/**
|
|
1286
|
+
* Require TLS to the database. Defaults on for managed SingleStore (Helios),
|
|
1287
|
+
* off for on-box engines. Set explicitly to override.
|
|
1288
|
+
*/
|
|
1289
|
+
ssl?: boolean;
|
|
1275
1290
|
/**
|
|
1276
1291
|
* Additional database users to create beyond the app {@link username}
|
|
1277
1292
|
* (the Forge Database Users feature). Each can be granted full or read-only
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ts-cloud/core",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Core CloudFormation generation library for ts-cloud",
|
|
6
6
|
"author": "Chris Breuer <chris@stacksjs.com>",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"typecheck": "tsc --noEmit"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@ts-cloud/aws-types": "0.7.
|
|
34
|
+
"@ts-cloud/aws-types": "0.7.12"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"typescript": "^5.9.3"
|