@brewnet/cli 0.0.8 → 0.0.9
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/admin-server-FN7HZVZW.js +16 -0
- package/dist/{app-manager-BD3DG3RL.js → app-manager-6PEKSRZ2.js} +4 -4
- package/dist/{boilerplate-manager-WEFTHL2O.js → boilerplate-manager-5GPTMOYL.js} +4 -4
- package/dist/{chunk-OH233QV2.js → chunk-7VX572H4.js} +9 -9
- package/dist/{chunk-ZKMWE5AH.js → chunk-BD4MDAIG.js} +2 -2
- package/dist/{chunk-HCHY5UIQ.js → chunk-F2M6G5C7.js} +3 -3
- package/dist/chunk-F2M6G5C7.js.map +1 -0
- package/dist/{chunk-54WFZCU6.js → chunk-F2Y226UA.js} +3 -3
- package/dist/{chunk-76C5BGZK.js → chunk-JMKFUHZO.js} +19 -15
- package/dist/chunk-JMKFUHZO.js.map +1 -0
- package/dist/{chunk-AXSHZEB3.js → chunk-MOQNPKUG.js} +2 -2
- package/dist/{chunk-YAYXULLO.js → chunk-MSVYAYKQ.js} +4 -4
- package/dist/{compose-generator-OFJ2YWMB.js → compose-generator-MIAP3RBT.js} +3 -3
- package/dist/index.js +28 -43
- package/dist/index.js.map +1 -1
- package/dist/services/admin-daemon.js +6 -6
- package/dist/{state-2SI3P4JG.js → state-CJSUDM4H.js} +3 -3
- package/package.json +1 -1
- package/dist/admin-server-CBZFDDWG.js +0 -16
- package/dist/chunk-76C5BGZK.js.map +0 -1
- package/dist/chunk-HCHY5UIQ.js.map +0 -1
- /package/dist/{admin-server-CBZFDDWG.js.map → admin-server-FN7HZVZW.js.map} +0 -0
- /package/dist/{app-manager-BD3DG3RL.js.map → app-manager-6PEKSRZ2.js.map} +0 -0
- /package/dist/{boilerplate-manager-WEFTHL2O.js.map → boilerplate-manager-5GPTMOYL.js.map} +0 -0
- /package/dist/{chunk-OH233QV2.js.map → chunk-7VX572H4.js.map} +0 -0
- /package/dist/{chunk-ZKMWE5AH.js.map → chunk-BD4MDAIG.js.map} +0 -0
- /package/dist/{chunk-54WFZCU6.js.map → chunk-F2Y226UA.js.map} +0 -0
- /package/dist/{chunk-AXSHZEB3.js.map → chunk-MOQNPKUG.js.map} +0 -0
- /package/dist/{chunk-YAYXULLO.js.map → chunk-MSVYAYKQ.js.map} +0 -0
- /package/dist/{compose-generator-OFJ2YWMB.js.map → compose-generator-MIAP3RBT.js.map} +0 -0
- /package/dist/{state-2SI3P4JG.js.map → state-CJSUDM4H.js.map} +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
createAdminServer
|
|
4
|
+
} from "./chunk-JMKFUHZO.js";
|
|
5
|
+
import "./chunk-7VX572H4.js";
|
|
6
|
+
import "./chunk-MSVYAYKQ.js";
|
|
7
|
+
import "./chunk-JIPAYMOA.js";
|
|
8
|
+
import "./chunk-YXFDB5YX.js";
|
|
9
|
+
import "./chunk-MOQNPKUG.js";
|
|
10
|
+
import "./chunk-BD4MDAIG.js";
|
|
11
|
+
import "./chunk-F2M6G5C7.js";
|
|
12
|
+
import "./chunk-SYV6PK3R.js";
|
|
13
|
+
export {
|
|
14
|
+
createAdminServer
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=admin-server-FN7HZVZW.js.map
|
|
@@ -21,10 +21,10 @@ import {
|
|
|
21
21
|
startApp,
|
|
22
22
|
stopApp,
|
|
23
23
|
updateDeploySettings
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-7VX572H4.js";
|
|
25
25
|
import "./chunk-JIPAYMOA.js";
|
|
26
|
-
import "./chunk-
|
|
27
|
-
import "./chunk-
|
|
26
|
+
import "./chunk-BD4MDAIG.js";
|
|
27
|
+
import "./chunk-F2M6G5C7.js";
|
|
28
28
|
export {
|
|
29
29
|
createApp,
|
|
30
30
|
deployApp,
|
|
@@ -48,4 +48,4 @@ export {
|
|
|
48
48
|
stopApp,
|
|
49
49
|
updateDeploySettings
|
|
50
50
|
};
|
|
51
|
-
//# sourceMappingURL=app-manager-
|
|
51
|
+
//# sourceMappingURL=app-manager-6PEKSRZ2.js.map
|
|
@@ -9,11 +9,11 @@ import {
|
|
|
9
9
|
reinitGit,
|
|
10
10
|
startContainers,
|
|
11
11
|
verifyEndpoints
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-F2Y226UA.js";
|
|
13
|
+
import "./chunk-MOQNPKUG.js";
|
|
14
14
|
import {
|
|
15
15
|
BOILERPLATE_REPO_URL
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-F2M6G5C7.js";
|
|
17
17
|
export {
|
|
18
18
|
BOILERPLATE_REPO_URL,
|
|
19
19
|
cloneStack,
|
|
@@ -26,4 +26,4 @@ export {
|
|
|
26
26
|
startContainers,
|
|
27
27
|
verifyEndpoints
|
|
28
28
|
};
|
|
29
|
-
//# sourceMappingURL=boilerplate-manager-
|
|
29
|
+
//# sourceMappingURL=boilerplate-manager-5GPTMOYL.js.map
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
getLastProject,
|
|
12
12
|
loadState
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-BD4MDAIG.js";
|
|
14
14
|
|
|
15
15
|
// src/services/app-manager.ts
|
|
16
16
|
import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, readdirSync } from "fs";
|
|
@@ -527,7 +527,7 @@ async function _runDeploy(job, appName) {
|
|
|
527
527
|
if (isShallowNew) {
|
|
528
528
|
appendLog(job, "[pull] shallow clone detected \u2014 unshallowing");
|
|
529
529
|
await execa("git", ["fetch", "--unshallow", "origin"], { cwd: app.appDir }).catch(async () => {
|
|
530
|
-
const { reinitGit } = await import("./boilerplate-manager-
|
|
530
|
+
const { reinitGit } = await import("./boilerplate-manager-5GPTMOYL.js");
|
|
531
531
|
await reinitGit(app.appDir);
|
|
532
532
|
});
|
|
533
533
|
}
|
|
@@ -549,7 +549,7 @@ async function _runDeploy(job, appName) {
|
|
|
549
549
|
if (isShallow) {
|
|
550
550
|
appendLog(job, "[pull] shallow clone detected \u2014 unshallowing");
|
|
551
551
|
await execa("git", ["fetch", "--unshallow", "origin"], { cwd: app.appDir }).catch(async () => {
|
|
552
|
-
const { reinitGit } = await import("./boilerplate-manager-
|
|
552
|
+
const { reinitGit } = await import("./boilerplate-manager-5GPTMOYL.js");
|
|
553
553
|
await reinitGit(app.appDir);
|
|
554
554
|
});
|
|
555
555
|
}
|
|
@@ -677,7 +677,7 @@ async function _injectQuickTunnelIfNeeded(appDir, appName, port) {
|
|
|
677
677
|
const last = getLastProject();
|
|
678
678
|
const state = loadState(last ?? "");
|
|
679
679
|
if (state?.domain?.cloudflare?.tunnelMode !== "quick") return;
|
|
680
|
-
const { injectTraefikForQuickTunnel } = await import("./boilerplate-manager-
|
|
680
|
+
const { injectTraefikForQuickTunnel } = await import("./boilerplate-manager-5GPTMOYL.js");
|
|
681
681
|
injectTraefikForQuickTunnel(appDir, appName, port);
|
|
682
682
|
} catch (err) {
|
|
683
683
|
console.error(`[Quick Tunnel] Failed to inject Traefik labels for ${appName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -959,7 +959,7 @@ async function _createModeA(job, opts, ctx, gitea, appsJson) {
|
|
|
959
959
|
const shallowCheck = await execa("git", ["rev-parse", "--is-shallow-repository"], { cwd: meta.appDir }).catch(() => ({ stdout: "false" }));
|
|
960
960
|
if (shallowCheck.stdout.trim() === "true") {
|
|
961
961
|
await execa("git", ["fetch", "--unshallow", "origin"], { cwd: meta.appDir }).catch(async () => {
|
|
962
|
-
const { reinitGit } = await import("./boilerplate-manager-
|
|
962
|
+
const { reinitGit } = await import("./boilerplate-manager-5GPTMOYL.js");
|
|
963
963
|
await reinitGit(meta.appDir);
|
|
964
964
|
});
|
|
965
965
|
}
|
|
@@ -999,7 +999,7 @@ async function _createModeB(job, opts, ctx, gitea, appsJson) {
|
|
|
999
999
|
const port = opts.port ?? 8080;
|
|
1000
1000
|
const appDir = join(ctx.projectPath, "apps", opts.appName);
|
|
1001
1001
|
setStep(job, 2, "running", "Cloning external repository...");
|
|
1002
|
-
const { reinitGit: reinitGitB } = await import("./boilerplate-manager-
|
|
1002
|
+
const { reinitGit: reinitGitB } = await import("./boilerplate-manager-5GPTMOYL.js");
|
|
1003
1003
|
const { rmSync } = await import("fs");
|
|
1004
1004
|
if (existsSync2(appDir)) {
|
|
1005
1005
|
rmSync(appDir, { recursive: true, force: true });
|
|
@@ -1012,7 +1012,7 @@ async function _createModeB(job, opts, ctx, gitea, appsJson) {
|
|
|
1012
1012
|
const envExPath = join(appDir, ".env.example");
|
|
1013
1013
|
const envPath = join(appDir, ".env");
|
|
1014
1014
|
if (existsSync2(envExPath)) {
|
|
1015
|
-
const { findFreePort: findFreePortB } = await import("./boilerplate-manager-
|
|
1015
|
+
const { findFreePort: findFreePortB } = await import("./boilerplate-manager-5GPTMOYL.js");
|
|
1016
1016
|
let envContent = readFileSync2(envExPath, "utf-8");
|
|
1017
1017
|
envContent = envContent.replace(/^BACKEND_PORT=.*/m, `BACKEND_PORT=${port}`);
|
|
1018
1018
|
const fePort = await findFreePortB(port + 1);
|
|
@@ -1062,7 +1062,7 @@ async function _createModeB(job, opts, ctx, gitea, appsJson) {
|
|
|
1062
1062
|
});
|
|
1063
1063
|
}
|
|
1064
1064
|
async function _createModeC(job, opts, ctx, gitea, appsJson) {
|
|
1065
|
-
const { cloneStack, generateEnv, reinitGit, findFreePort } = await import("./boilerplate-manager-
|
|
1065
|
+
const { cloneStack, generateEnv, reinitGit, findFreePort } = await import("./boilerplate-manager-5GPTMOYL.js");
|
|
1066
1066
|
const { getStackById } = await import("./stacks-M4FBTVO5.js");
|
|
1067
1067
|
const stackId = opts._resolvedStackId;
|
|
1068
1068
|
const requestedPort = opts.port ?? 8080;
|
|
@@ -1156,4 +1156,4 @@ export {
|
|
|
1156
1156
|
stopApp,
|
|
1157
1157
|
removeApp2 as removeApp
|
|
1158
1158
|
};
|
|
1159
|
-
//# sourceMappingURL=chunk-
|
|
1159
|
+
//# sourceMappingURL=chunk-7VX572H4.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
ACCESS_LOG_MAX_BYTES,
|
|
4
4
|
CLI_LOG_RETENTION_DAYS,
|
|
5
5
|
SCHEMA_VERSION
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-F2M6G5C7.js";
|
|
7
7
|
|
|
8
8
|
// src/wizard/state.ts
|
|
9
9
|
import {
|
|
@@ -441,4 +441,4 @@ export {
|
|
|
441
441
|
listProjects,
|
|
442
442
|
_resetGlobalConfig
|
|
443
443
|
};
|
|
444
|
-
//# sourceMappingURL=chunk-
|
|
444
|
+
//# sourceMappingURL=chunk-BD4MDAIG.js.map
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
var SCHEMA_VERSION = 7;
|
|
5
5
|
var DOCKER_COMPOSE_FILENAME = "docker-compose.yml";
|
|
6
6
|
var DB_VERSIONS = {
|
|
7
|
-
postgresql: ["18.3"
|
|
8
|
-
mysql: ["8.4"
|
|
7
|
+
postgresql: ["18.3"],
|
|
8
|
+
mysql: ["8.4"],
|
|
9
9
|
sqlite: ["3"]
|
|
10
10
|
};
|
|
11
11
|
var BOILERPLATE_REPO_URL = "https://github.com/claude-code-expert/brewnet-boilerplate.git";
|
|
@@ -298,4 +298,4 @@ export {
|
|
|
298
298
|
LOG_QUERY_DEFAULT_LIMIT,
|
|
299
299
|
LOG_QUERY_MAX_LIMIT
|
|
300
300
|
};
|
|
301
|
-
//# sourceMappingURL=chunk-
|
|
301
|
+
//# sourceMappingURL=chunk-F2M6G5C7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../shared/src/utils/constants.ts","../../shared/src/types/errors.ts","../../shared/src/schemas/wizard-state.schema.ts","../../shared/src/schemas/config.schema.ts"],"sourcesContent":["// T013 — Shared constants used across the Brewnet CLI and Dashboard\n\n// ─── Schema & Versioning ────────────────────────────────────────────────────\n\n/** Current wizard state schema version */\nexport const SCHEMA_VERSION = 7 as const;\n\n/** Minimum schema version that can be migrated (older versions are reset) */\nexport const MIN_MIGRATABLE_SCHEMA_VERSION = 3;\n\n// ─── Project Defaults ────────────────────────────────────────────────────────\n\nexport const DEFAULT_PROJECT_NAME = 'my-homeserver';\nexport const DEFAULT_PROJECT_PATH_PREFIX = '~/brewnet';\nexport const DEFAULT_DATA_DIR = '~/.brewnet';\nexport const DEFAULT_CONFIG_FILENAME = 'brewnet.config.json';\n\n// ─── Admin & Credentials ────────────────────────────────────────────────────\n\nexport const DEFAULT_ADMIN_USERNAME = 'admin';\nexport const DEFAULT_ADMIN_PASSWORD_LENGTH = 20;\nexport const DEFAULT_SERVICE_PASSWORD_LENGTH = 16;\nexport const DEFAULT_DB_NAME = 'brewnet';\nexport const DEFAULT_DB_USER = 'brewnet';\n\n// ─── Port Defaults ───────────────────────────────────────────────────────────\n\nexport const DEFAULT_SSH_PORT = 2222;\nexport const DEFAULT_GIT_WEB_PORT = 3000;\nexport const DEFAULT_GIT_SSH_PORT = 3022;\nexport const DEFAULT_HTTP_PORT = 80;\nexport const DEFAULT_HTTPS_PORT = 443;\nexport const DEFAULT_TRAEFIK_DASHBOARD_PORT = 8080;\n\n// ─── Health Check ────────────────────────────────────────────────────────────\n\n/** Maximum time to wait for all health checks to pass (ms) */\nexport const HEALTH_CHECK_TIMEOUT_MS = 120_000;\n\n/** Interval between health check polls (ms) */\nexport const HEALTH_CHECK_INTERVAL_MS = 2_000;\n\n/** Number of consecutive successes required to consider a service healthy */\nexport const HEALTH_CHECK_SUCCESS_THRESHOLD = 3;\n\n/** Number of consecutive failures before marking a service as unhealthy */\nexport const HEALTH_CHECK_FAILURE_THRESHOLD = 5;\n\n// ─── Docker ──────────────────────────────────────────────────────────────────\n\nexport const DOCKER_COMPOSE_FILENAME = 'docker-compose.yml';\nexport const DOCKER_NETWORK_EXTERNAL = 'brewnet';\nexport const DOCKER_NETWORK_INTERNAL = 'brewnet-internal';\nexport const DOCKER_RESTART_POLICY = 'unless-stopped';\nexport const DOCKER_COMPOSE_VERSION = '3.8';\n\n// ─── File Permissions ────────────────────────────────────────────────────────\n\n/** Permission for .env files containing secrets (owner read/write only) */\nexport const ENV_FILE_PERMISSIONS = 0o600;\n\n/** Permission for SSH private keys (owner read only) */\nexport const SSH_KEY_PERMISSIONS = 0o600;\n\n/** Permission for SSH authorized_keys (owner read/write only) */\nexport const SSH_AUTHORIZED_KEYS_PERMISSIONS = 0o600;\n\n/** Permission for directories (owner rwx, group rx, others rx) */\nexport const DEFAULT_DIR_PERMISSIONS = 0o755;\n\n// ─── Storage Keys ────────────────────────────────────────────────────────────\n\n/** localStorage key for wizard state (used by demo and dashboard) */\nexport const WIZARD_STATE_STORAGE_KEY = 'brewnet_wizard_state';\n\n// ─── Service Images ─────────────────────────────────────────────────────────\n\nexport const SERVICE_IMAGES = {\n traefik: 'traefik:v3.1',\n nginx: 'nginx:1.27-alpine',\n caddy: 'caddy:2-alpine',\n nextcloud: 'nextcloud:29-apache',\n minio: 'minio/minio:latest',\n gitea: 'gitea/gitea:1.22',\n postgresql: 'postgres:18.3-alpine',\n mysql: 'mysql:8.4',\n sqlite: '',\n redis: 'redis:7-alpine',\n valkey: 'valkey/valkey:8-alpine',\n keydb: 'eqalpha/keydb:latest',\n jellyfin: 'jellyfin/jellyfin:latest',\n\n filebrowser: 'filebrowser/filebrowser:latest',\n pgadmin: 'dpage/pgadmin4:latest',\n phpmyadmin: 'phpmyadmin:latest',\n} as const;\n\n// ─── Database Versions ───────────────────────────────────────────────────────\n\nexport const DB_VERSIONS: Record<string, string[]> = {\n postgresql: ['18.3'],\n mysql: ['8.4'],\n sqlite: ['3'],\n};\n\n// ─── Default Web Server ──────────────────────────────────────────────────────\n\nexport const DEFAULT_WEB_SERVER = 'traefik' as const;\n\n// ─── Domain Defaults ─────────────────────────────────────────────────────────\n\nexport const DEFAULT_DOMAIN_PROVIDER = 'local' as const;\nexport const DEFAULT_SSL_MODE = 'self-signed' as const;\n\n// ─── Boilerplate Defaults ────────────────────────────────────────────────────\n\nexport const DEFAULT_DEV_MODE = 'hot-reload' as const;\n\n/** Git repository URL for Brewnet boilerplate templates (not yet populated) */\nexport const BOILERPLATE_REPO_URL = 'https://github.com/claude-code-expert/brewnet-boilerplate.git';\n\n// ─── CLI Metadata ────────────────────────────────────────────────────────────\n\nexport const CLI_NAME = 'brewnet';\nexport const CLI_DESCRIPTION = 'Your Home Server, Brewed Fresh';\n\n// ─── Rate Limiting ───────────────────────────────────────────────────────────\n\n/** Maximum API requests per minute for free tier */\nexport const RATE_LIMIT_FREE = 60;\n\n/** Maximum API requests per minute for Pro tier */\nexport const RATE_LIMIT_PRO = 300;\n\n// ─── Backup ──────────────────────────────────────────────────────────────────\n\n/** Maximum number of backup archives to retain */\nexport const MAX_BACKUP_RETENTION = 10;\n\n/** Default backup directory name within ~/.brewnet */\nexport const BACKUP_DIR_NAME = 'backups';\n\n// ─── Timeouts ────────────────────────────────────────────────────────────────\n\n/** Timeout for Docker image pull operations (ms) */\nexport const DOCKER_PULL_TIMEOUT_MS = 300_000;\n\n/** Timeout for Docker container start operations (ms) */\nexport const DOCKER_START_TIMEOUT_MS = 60_000;\n\n/** Timeout for SSL certificate issuance (ms) */\nexport const SSL_ISSUANCE_TIMEOUT_MS = 120_000;\n\n/** Timeout for DNS propagation check (ms) */\nexport const DNS_PROPAGATION_TIMEOUT_MS = 300_000;\n\n// ─── Logging ────────────────────────────────────────────────────────────────\n\n/** Maximum log file size per container (Docker json-file driver) */\nexport const DOCKER_LOG_MAX_SIZE = '10m';\n\n/** Maximum number of rotated log files per container */\nexport const DOCKER_LOG_MAX_FILES = '3';\n\n/** Days before CLI log files are deleted */\nexport const CLI_LOG_RETENTION_DAYS = 30;\n\n/** Maximum access/tunnel log file size before copytruncate rotation (bytes) */\nexport const ACCESS_LOG_MAX_BYTES = 50 * 1024 * 1024;\n\n/** Default page size for log queries */\nexport const LOG_QUERY_DEFAULT_LIMIT = 100;\n\n/** Maximum page size for log queries */\nexport const LOG_QUERY_MAX_LIMIT = 1000;\n\n/** Admin Panel log auto-refresh interval (ms) */\nexport const LOG_POLL_INTERVAL_MS = 5000;\n","// T010 — Error codes, backup records, log entries, and generated config types\n\n// ─── Error Codes ─────────────────────────────────────────────────────────────\n\nexport enum ErrorCode {\n /** Docker daemon not running */\n BN001 = 'BN001',\n /** Port already in use */\n BN002 = 'BN002',\n /** SSL certificate issuance failed */\n BN003 = 'BN003',\n /** Invalid license key */\n BN004 = 'BN004',\n /** Rate limit exceeded */\n BN005 = 'BN005',\n /** Build failed */\n BN006 = 'BN006',\n /** Invalid Git repository */\n BN007 = 'BN007',\n /** Resource not found */\n BN008 = 'BN008',\n /** Database error */\n BN009 = 'BN009',\n /** Feature requires Pro plan */\n BN010 = 'BN010',\n}\n\n/** Maps error codes to their corresponding HTTP status codes */\nexport const ERROR_HTTP_STATUS: Record<ErrorCode, number> = {\n [ErrorCode.BN001]: 503,\n [ErrorCode.BN002]: 409,\n [ErrorCode.BN003]: 500,\n [ErrorCode.BN004]: 401,\n [ErrorCode.BN005]: 429,\n [ErrorCode.BN006]: 500,\n [ErrorCode.BN007]: 400,\n [ErrorCode.BN008]: 404,\n [ErrorCode.BN009]: 500,\n [ErrorCode.BN010]: 403,\n};\n\n/** Human-readable descriptions for each error code */\nexport const ERROR_MESSAGES: Record<ErrorCode, string> = {\n [ErrorCode.BN001]: 'Docker daemon is not running. Please start Docker and try again.',\n [ErrorCode.BN002]: 'Port is already in use. Please free the port or choose a different one.',\n [ErrorCode.BN003]: 'SSL certificate issuance failed. Check your domain configuration.',\n [ErrorCode.BN004]: 'Invalid license key. Please verify your license.',\n [ErrorCode.BN005]: 'Rate limit exceeded. Please wait and try again.',\n [ErrorCode.BN006]: 'Build failed. Check the build logs for details.',\n [ErrorCode.BN007]: 'Invalid Git repository. Ensure the repository URL is correct.',\n [ErrorCode.BN008]: 'Resource not found.',\n [ErrorCode.BN009]: 'Database error. Check the database configuration and logs.',\n [ErrorCode.BN010]: 'This feature requires a Pro plan. Upgrade to access it.',\n};\n\n// ─── Brewnet Error Class ─────────────────────────────────────────────────────\n\nexport class BrewnetError extends Error {\n public readonly code: ErrorCode;\n public readonly httpStatus: number;\n public readonly metadata?: Record<string, unknown>;\n\n constructor(code: ErrorCode, message?: string, metadata?: Record<string, unknown>) {\n super(message ?? ERROR_MESSAGES[code]);\n this.name = 'BrewnetError';\n this.code = code;\n this.httpStatus = ERROR_HTTP_STATUS[code];\n this.metadata = metadata;\n\n // Maintain proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n// ─── Log Entry ───────────────────────────────────────────────────────────────\n\nexport type LogLevel = 'info' | 'warn' | 'error';\n\nexport interface LogEntry {\n /** Timestamp of the log entry */\n timestamp: Date;\n /** Severity level */\n level: LogLevel;\n /** CLI command that generated this log (e.g., \"brewnet add jellyfin\") */\n command: string;\n /** Human-readable log message */\n message: string;\n /** Optional structured metadata */\n metadata?: Record<string, unknown>;\n}\n\n// ─── Backup Record ───────────────────────────────────────────────────────────\n\nexport interface BackupRecord {\n /** Unique backup identifier (UUID) */\n id: string;\n /** Filesystem path to the backup archive */\n path: string;\n /** Backup archive size in bytes */\n size: number;\n /** List of service IDs included in this backup */\n services: string[];\n /** When the backup was created */\n createdAt: Date;\n /** Name of the project that was backed up */\n projectName: string;\n /** Filesystem path of the project that was backed up */\n projectPath: string;\n}\n\n// ─── Generated Config ────────────────────────────────────────────────────────\n\nexport interface GeneratedFile {\n /** Relative file path within the project directory */\n path: string;\n /** Full file content as a string */\n content: string;\n /** Unix file permissions (e.g., 0o600 for .env files) */\n permissions?: number;\n}\n\nexport interface GeneratedConfig {\n /** Absolute path to the project directory */\n projectPath: string;\n /** List of files to be written */\n files: GeneratedFile[];\n}\n","// T011 — Zod schema for WizardState validation\n// Validates the complete wizard state object including all sub-schemas.\n\nimport { z } from 'zod';\nimport type { WizardState } from '../types/wizard-state.js';\n\n// ─── Primitive Schemas ───────────────────────────────────────────────────────\n\nexport const languageSchema = z.enum([\n 'python', 'nodejs', 'java', 'rust', 'go', 'kotlin',\n]);\n\nexport const frontendTechSchema = z.enum([\n 'react', 'vue', 'none',\n]);\n\nexport const webServerServiceSchema = z.enum(['traefik', 'nginx', 'caddy']);\n\nexport const fileServerServiceSchema = z.enum(['nextcloud', 'minio', '']);\n\nexport const dbPrimarySchema = z.enum(['postgresql', 'mysql', 'sqlite', '']);\n\nexport const cacheServiceSchema = z.enum(['']);\n\nexport const domainProviderSchema = z.enum(['local', 'tunnel', 'quick-tunnel']);\n\nexport const sslModeSchema = z.enum(['self-signed', 'letsencrypt', 'cloudflare']);\n\nexport const setupTypeSchema = z.enum(['full', 'partial']);\n\nexport const fileBrowserModeSchema = z.enum(['directory', 'standalone', '']);\n\nexport const devModeSchema = z.enum(['hot-reload', 'production']);\n\n// ─── Sub-Schemas ─────────────────────────────────────────────────────────────\n\nexport const adminConfigSchema = z.object({\n username: z.string().min(1, 'Admin username is required'),\n password: z.string().min(8, 'Admin password must be at least 8 characters'),\n storage: z.literal('local'),\n});\n\nexport const webServerConfigSchema = z.object({\n enabled: z.literal(true),\n service: webServerServiceSchema,\n});\n\nexport const fileServerConfigSchema = z.object({\n enabled: z.boolean(),\n service: fileServerServiceSchema,\n});\n\nexport const gitServerConfigSchema = z.object({\n enabled: z.literal(true),\n service: z.literal('gitea'),\n port: z.number().int().min(1).max(65535),\n sshPort: z.number().int().min(1).max(65535),\n});\n\nexport const dbServerConfigSchema = z.object({\n enabled: z.boolean(),\n primary: dbPrimarySchema,\n primaryVersion: z.string(),\n dbName: z.string(),\n dbUser: z.string(),\n dbPassword: z.string(),\n adminUI: z.boolean(),\n pgadminEmail: z.string(),\n cache: cacheServiceSchema,\n});\n\nexport const mediaConfigSchema = z.object({\n enabled: z.boolean(),\n services: z.array(z.string()),\n});\n\nexport const sshServerConfigSchema = z.object({\n enabled: z.boolean(),\n port: z.number().int().min(1).max(65535),\n passwordAuth: z.boolean(),\n sftp: z.boolean(),\n});\n\nexport const appServerConfigSchema = z.object({\n enabled: z.boolean(),\n});\n\nexport const fileBrowserConfigSchema = z.object({\n enabled: z.boolean(),\n mode: fileBrowserModeSchema,\n});\n\nexport const serverComponentsSchema = z.object({\n webServer: webServerConfigSchema,\n fileServer: fileServerConfigSchema,\n gitServer: gitServerConfigSchema,\n dbServer: dbServerConfigSchema,\n media: mediaConfigSchema,\n sshServer: sshServerConfigSchema,\n appServer: appServerConfigSchema,\n fileBrowser: fileBrowserConfigSchema,\n});\n\nexport const devStackConfigSchema = z.object({\n languages: z.array(languageSchema),\n frameworks: z.record(z.string(), z.string()),\n frontend: frontendTechSchema.nullable(),\n});\n\nexport const boilerplateConfigSchema = z.object({\n generate: z.boolean(),\n sampleData: z.boolean(),\n devMode: devModeSchema,\n});\n\nexport const tunnelModeSchema = z.enum(['quick', 'named', 'none']);\n\nexport const cloudflareConfigSchema = z.object({\n enabled: z.boolean(),\n tunnelMode: tunnelModeSchema,\n quickTunnelUrl: z.string(),\n accountId: z.string(),\n apiToken: z.string(),\n tunnelId: z.string(),\n tunnelToken: z.string(),\n tunnelName: z.string(),\n zoneId: z.string(),\n zoneName: z.string(),\n});\n\nexport const domainConfigSchema = z.object({\n provider: domainProviderSchema,\n name: z.string(),\n ssl: sslModeSchema,\n cloudflare: cloudflareConfigSchema,\n});\n\nexport const domainScenarioSchema = z.enum(['A', 'B', 'C']);\n\nexport const domainConnectionSchema = z.object({\n appName: z.string().min(1, 'App name is required'),\n subdomain: z.string().min(1, 'Subdomain is required').regex(\n /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/,\n 'Subdomain must be a valid DNS label (lowercase alphanumeric + hyphens, max 63 chars)',\n ),\n domain: z.string().min(1, 'Domain is required'),\n hostname: z.string().min(1, 'Hostname is required'),\n tunnelId: z.string().min(1, 'Tunnel ID is required'),\n cnameRecordId: z.string(),\n containerPort: z.number().int().min(1).max(65535),\n connectedAt: z.string().datetime(),\n scenario: domainScenarioSchema,\n});\n\n// ─── Root Schema ─────────────────────────────────────────────────────────────\n\nexport const wizardStateSchema = z.object({\n schemaVersion: z.literal(7),\n projectName: z.string().min(1, 'Project name is required').regex(\n /^[a-z0-9][a-z0-9-]*$/,\n 'Project name must start with a lowercase letter or number and contain only lowercase letters, numbers, and hyphens',\n ),\n projectPath: z.string().min(1, 'Project path is required'),\n setupType: setupTypeSchema,\n admin: adminConfigSchema,\n servers: serverComponentsSchema,\n devStack: devStackConfigSchema,\n boilerplate: boilerplateConfigSchema,\n domain: domainConfigSchema,\n domainConnections: z.array(domainConnectionSchema),\n portRemapping: z.record(z.coerce.number(), z.number().int().min(1).max(65535)),\n}) satisfies z.ZodType<WizardState>;\n\nexport type ValidatedWizardState = z.infer<typeof wizardStateSchema>;\n\n// ─── Validation Helpers ──────────────────────────────────────────────────────\n\n/**\n * Validates a WizardState object and returns the parsed result.\n * Throws a ZodError if validation fails.\n */\nexport function validateWizardState(data: unknown): WizardState {\n return wizardStateSchema.parse(data);\n}\n\n/**\n * Safely validates a WizardState object without throwing.\n * Returns a discriminated union with success/error.\n */\nexport function safeValidateWizardState(data: unknown): z.SafeParseReturnType<unknown, WizardState> {\n return wizardStateSchema.safeParse(data);\n}\n","// T012 — Zod schema for brewnet.config.json import/export\n// A subset of WizardState used when exporting or importing wizard configurations.\n// Sensitive fields (passwords, tokens) are excluded from export by default.\n\nimport { z } from 'zod';\nimport {\n setupTypeSchema,\n webServerServiceSchema,\n fileServerServiceSchema,\n dbPrimarySchema,\n cacheServiceSchema,\n domainProviderSchema,\n sslModeSchema,\n fileBrowserModeSchema,\n devModeSchema,\n languageSchema,\n frontendTechSchema,\n} from './wizard-state.schema.js';\n\n// ─── Config Sub-Schemas (export-safe, no secrets) ────────────────────────────\n\nconst configAdminSchema = z.object({\n username: z.string().min(1),\n storage: z.literal('local'),\n});\n\nconst configWebServerSchema = z.object({\n enabled: z.literal(true),\n service: webServerServiceSchema,\n});\n\nconst configFileServerSchema = z.object({\n enabled: z.boolean(),\n service: fileServerServiceSchema,\n});\n\nconst configGitServerSchema = z.object({\n enabled: z.literal(true),\n service: z.literal('gitea'),\n port: z.number().int().min(1).max(65535),\n sshPort: z.number().int().min(1).max(65535),\n});\n\nconst configDbServerSchema = z.object({\n enabled: z.boolean(),\n primary: dbPrimarySchema,\n primaryVersion: z.string(),\n dbName: z.string(),\n dbUser: z.string(),\n adminUI: z.boolean(),\n pgadminEmail: z.string(),\n cache: cacheServiceSchema,\n // dbPassword is intentionally excluded from export\n});\n\nconst configMediaSchema = z.object({\n enabled: z.boolean(),\n services: z.array(z.string()),\n});\n\nconst configSshServerSchema = z.object({\n enabled: z.boolean(),\n port: z.number().int().min(1).max(65535),\n passwordAuth: z.boolean(),\n sftp: z.boolean(),\n});\n\nconst configAppServerSchema = z.object({\n enabled: z.boolean(),\n});\n\nconst configFileBrowserSchema = z.object({\n enabled: z.boolean(),\n mode: fileBrowserModeSchema,\n});\n\nconst configServersSchema = z.object({\n webServer: configWebServerSchema,\n fileServer: configFileServerSchema,\n gitServer: configGitServerSchema,\n dbServer: configDbServerSchema,\n media: configMediaSchema,\n sshServer: configSshServerSchema,\n appServer: configAppServerSchema,\n fileBrowser: configFileBrowserSchema,\n});\n\nconst configDevStackSchema = z.object({\n languages: z.array(languageSchema),\n frameworks: z.record(z.string(), z.string()),\n frontend: frontendTechSchema.nullable(),\n});\n\nconst configBoilerplateSchema = z.object({\n generate: z.boolean(),\n sampleData: z.boolean(),\n devMode: devModeSchema,\n});\n\nconst configCloudflareSchema = z.object({\n enabled: z.boolean(),\n tunnelName: z.string(),\n // tunnelToken is intentionally excluded from export\n});\n\nconst configDomainSchema = z.object({\n provider: domainProviderSchema,\n name: z.string(),\n ssl: sslModeSchema,\n cloudflare: configCloudflareSchema,\n});\n\n// ─── Root Config Schema ──────────────────────────────────────────────────────\n\nexport const brewnetConfigSchema = z.object({\n schemaVersion: z.literal(7),\n projectName: z.string().min(1).regex(\n /^[a-z0-9][a-z0-9-]*$/,\n 'Project name must start with a lowercase letter or number and contain only lowercase letters, numbers, and hyphens',\n ),\n projectPath: z.string().min(1),\n setupType: setupTypeSchema,\n admin: configAdminSchema,\n servers: configServersSchema,\n devStack: configDevStackSchema,\n boilerplate: configBoilerplateSchema,\n domain: configDomainSchema,\n});\n\nexport type BrewnetConfig = z.infer<typeof brewnetConfigSchema>;\n\n// ─── Validation Helpers ──────────────────────────────────────────────────────\n\n/**\n * Validates a brewnet.config.json object. Throws on failure.\n */\nexport function validateBrewnetConfig(data: unknown): BrewnetConfig {\n return brewnetConfigSchema.parse(data);\n}\n\n/**\n * Safely validates a brewnet.config.json object without throwing.\n */\nexport function safeValidateBrewnetConfig(data: unknown): z.SafeParseReturnType<unknown, BrewnetConfig> {\n return brewnetConfigSchema.safeParse(data);\n}\n"],"mappings":"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","names":["ErrorCode","z","z"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
addQuickTunnelAppLabels
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MOQNPKUG.js";
|
|
5
5
|
import {
|
|
6
6
|
BOILERPLATE_REPO_URL
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-F2M6G5C7.js";
|
|
8
8
|
|
|
9
9
|
// src/services/boilerplate-manager.ts
|
|
10
10
|
import { readFileSync, writeFileSync, rmSync, readdirSync, statSync, existsSync } from "fs";
|
|
@@ -290,4 +290,4 @@ export {
|
|
|
290
290
|
pollHealth,
|
|
291
291
|
verifyEndpoints
|
|
292
292
|
};
|
|
293
|
-
//# sourceMappingURL=chunk-
|
|
293
|
+
//# sourceMappingURL=chunk-F2Y226UA.js.map
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
startApp,
|
|
17
17
|
stopApp,
|
|
18
18
|
updateDeploySettings
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-7VX572H4.js";
|
|
20
20
|
import {
|
|
21
21
|
DomainManager,
|
|
22
22
|
addService,
|
|
@@ -25,19 +25,19 @@ import {
|
|
|
25
25
|
listBackups,
|
|
26
26
|
queryLogs,
|
|
27
27
|
removeService
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-MSVYAYKQ.js";
|
|
29
29
|
import {
|
|
30
30
|
verifyToken
|
|
31
31
|
} from "./chunk-YXFDB5YX.js";
|
|
32
32
|
import {
|
|
33
33
|
SERVICE_REGISTRY,
|
|
34
34
|
getServiceDefinition
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-MOQNPKUG.js";
|
|
36
36
|
import {
|
|
37
37
|
getLastProject,
|
|
38
38
|
loadState,
|
|
39
39
|
logger
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-BD4MDAIG.js";
|
|
41
41
|
import {
|
|
42
42
|
getStackById
|
|
43
43
|
} from "./chunk-SYV6PK3R.js";
|
|
@@ -51,9 +51,7 @@ import { fileURLToPath } from "url";
|
|
|
51
51
|
import { homedir } from "os";
|
|
52
52
|
import Dockerode from "dockerode";
|
|
53
53
|
var PKG_ROOT = join(fileURLToPath(import.meta.url), "../../../..");
|
|
54
|
-
var
|
|
55
|
-
var ADMIN_UI_MONOREPO = join(PKG_ROOT, "packages/admin-ui/dist");
|
|
56
|
-
var ADMIN_UI_DIST = existsSync(join(ADMIN_UI_BUNDLED, "index.html")) ? ADMIN_UI_BUNDLED : ADMIN_UI_MONOREPO;
|
|
54
|
+
var ADMIN_UI_DIST = join(fileURLToPath(import.meta.url), "../admin-ui");
|
|
57
55
|
var MIME_TYPES = {
|
|
58
56
|
".html": "text/html; charset=utf-8",
|
|
59
57
|
".js": "application/javascript; charset=utf-8",
|
|
@@ -916,7 +914,13 @@ function createAdminServer(options = {}) {
|
|
|
916
914
|
return;
|
|
917
915
|
}
|
|
918
916
|
res.writeHead(503, { "Content-Type": "text/plain" });
|
|
919
|
-
res.end(
|
|
917
|
+
res.end(
|
|
918
|
+
`Admin UI not found.
|
|
919
|
+
|
|
920
|
+
Expected: ${ADMIN_UI_DIST}/index.html
|
|
921
|
+
|
|
922
|
+
Reinstall: curl -fsSL https://raw.githubusercontent.com/claude-code-expert/brewnet/main/install.sh | bash`
|
|
923
|
+
);
|
|
920
924
|
return;
|
|
921
925
|
}
|
|
922
926
|
if (parts[0] === "api") {
|
|
@@ -1768,7 +1772,7 @@ async function handleCloudflareZones(res, state) {
|
|
|
1768
1772
|
const firstAccountId = zones[0]?.accountId;
|
|
1769
1773
|
if (firstAccountId) {
|
|
1770
1774
|
state.domain.cloudflare.accountId = firstAccountId;
|
|
1771
|
-
const { saveState: save } = await import("./state-
|
|
1775
|
+
const { saveState: save } = await import("./state-CJSUDM4H.js");
|
|
1772
1776
|
save(state);
|
|
1773
1777
|
}
|
|
1774
1778
|
}
|
|
@@ -1814,7 +1818,7 @@ async function handleCreateTunnel(res, body, state, projectPath) {
|
|
|
1814
1818
|
try {
|
|
1815
1819
|
const { createTunnel: cfCreateTunnel } = await import("./cloudflare-client-F2TGQXGS.js");
|
|
1816
1820
|
const result = await cfCreateTunnel(cf.apiToken, cf.accountId, tunnelName.trim());
|
|
1817
|
-
const { saveState: save } = await import("./state-
|
|
1821
|
+
const { saveState: save } = await import("./state-CJSUDM4H.js");
|
|
1818
1822
|
state.domain.cloudflare.tunnelId = result.tunnelId;
|
|
1819
1823
|
state.domain.cloudflare.tunnelToken = result.tunnelToken;
|
|
1820
1824
|
state.domain.cloudflare.tunnelName = tunnelName.trim();
|
|
@@ -1827,7 +1831,7 @@ async function handleCreateTunnel(res, body, state, projectPath) {
|
|
|
1827
1831
|
}
|
|
1828
1832
|
const zoneName = cf.zoneName;
|
|
1829
1833
|
try {
|
|
1830
|
-
const { saveGiteaConfig } = await import("./app-manager-
|
|
1834
|
+
const { saveGiteaConfig } = await import("./app-manager-6PEKSRZ2.js");
|
|
1831
1835
|
const adminUsername = state.admin?.username ?? "admin";
|
|
1832
1836
|
saveGiteaConfig("http://localhost/git", adminUsername);
|
|
1833
1837
|
logger.info("tunnel", `[${tunnelName}] gitea-config.json normalized \u2192 http://localhost/git`);
|
|
@@ -1841,7 +1845,7 @@ async function handleCreateTunnel(res, body, state, projectPath) {
|
|
|
1841
1845
|
const { existsSync: fsExists } = await import("fs");
|
|
1842
1846
|
if (fsExists(composePath)) {
|
|
1843
1847
|
try {
|
|
1844
|
-
const { patchCloudflaredToNamedTunnel } = await import("./compose-generator-
|
|
1848
|
+
const { patchCloudflaredToNamedTunnel } = await import("./compose-generator-MIAP3RBT.js");
|
|
1845
1849
|
composeUpdated = patchCloudflaredToNamedTunnel(composePath, result.tunnelToken);
|
|
1846
1850
|
logger.info("tunnel", `[${tunnelName}] compose patch: composeUpdated=${composeUpdated}`);
|
|
1847
1851
|
} catch (e) {
|
|
@@ -1895,7 +1899,7 @@ async function handleCreateTunnel(res, body, state, projectPath) {
|
|
|
1895
1899
|
}
|
|
1896
1900
|
if (zoneName) {
|
|
1897
1901
|
try {
|
|
1898
|
-
const { patchBuiltinServicesForNamedTunnel } = await import("./compose-generator-
|
|
1902
|
+
const { patchBuiltinServicesForNamedTunnel } = await import("./compose-generator-MIAP3RBT.js");
|
|
1899
1903
|
const patchedServices = patchBuiltinServicesForNamedTunnel(composePath, zoneName);
|
|
1900
1904
|
steps.push({ step: "services_env_patched", success: true, services: patchedServices });
|
|
1901
1905
|
logger.info("tunnel", `[${tunnelName}] env patched for: ${patchedServices.join(", ") || "none"}`);
|
|
@@ -2002,7 +2006,7 @@ async function handleSettingsCloudflarePut(res, body, state) {
|
|
|
2002
2006
|
});
|
|
2003
2007
|
return;
|
|
2004
2008
|
}
|
|
2005
|
-
const { saveState: save } = await import("./state-
|
|
2009
|
+
const { saveState: save } = await import("./state-CJSUDM4H.js");
|
|
2006
2010
|
state.domain.cloudflare.apiToken = apiToken;
|
|
2007
2011
|
let resolvedAccountId = accountId || state.domain.cloudflare.accountId || await (await import("./cloudflare-client-F2TGQXGS.js")).getAccounts(apiToken).then((a) => a[0]?.id ?? "").catch(() => "");
|
|
2008
2012
|
if (zoneId) state.domain.cloudflare.zoneId = zoneId;
|
|
@@ -2039,4 +2043,4 @@ async function handleSettingsCloudflarePut(res, body, state) {
|
|
|
2039
2043
|
export {
|
|
2040
2044
|
createAdminServer
|
|
2041
2045
|
};
|
|
2042
|
-
//# sourceMappingURL=chunk-
|
|
2046
|
+
//# sourceMappingURL=chunk-JMKFUHZO.js.map
|