@brewnet/cli 0.0.1 → 0.0.2
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-UODBPGWR.js +16 -0
- package/dist/app-manager-FIHPVUP7.js +51 -0
- package/dist/{boilerplate-manager-P6QYUU7Q.js → boilerplate-manager-WEFTHL2O.js} +3 -3
- package/dist/{chunk-DH2VK3YI.js → chunk-54WFZCU6.js} +2 -2
- package/dist/{chunk-4TJMJZMO.js → chunk-AXSHZEB3.js} +63 -1
- package/dist/{chunk-4TJMJZMO.js.map → chunk-AXSHZEB3.js.map} +1 -1
- package/dist/chunk-FZZ3HP2G.js +1151 -0
- package/dist/chunk-FZZ3HP2G.js.map +1 -0
- package/dist/chunk-JIPAYMOA.js +58 -0
- package/dist/chunk-JIPAYMOA.js.map +1 -0
- package/dist/{chunk-SIXBB6JU.js → chunk-Q6UUZR2V.js} +238 -1171
- package/dist/chunk-Q6UUZR2V.js.map +1 -0
- package/dist/{chunk-2VWMDHGI.js → chunk-YAYXULLO.js} +9 -61
- package/dist/chunk-YAYXULLO.js.map +1 -0
- package/dist/{chunk-JFPHGZ6Z.js → chunk-YXFDB5YX.js} +17 -2
- package/dist/chunk-YXFDB5YX.js.map +1 -0
- package/dist/{cloudflare-client-TFT6VCXF.js → cloudflare-client-F2TGQXGS.js} +2 -2
- package/dist/{compose-generator-O7GSIJ2S.js → compose-generator-OFJ2YWMB.js} +4 -2
- package/dist/compose-generator-OFJ2YWMB.js.map +1 -0
- package/dist/index.js +122 -168
- package/dist/index.js.map +1 -1
- package/dist/services/admin-daemon.js +6 -4
- package/dist/services/admin-daemon.js.map +1 -1
- package/package.json +1 -1
- package/dist/admin-server-DQVIEHV3.js +0 -14
- package/dist/chunk-2VWMDHGI.js.map +0 -1
- package/dist/chunk-JFPHGZ6Z.js.map +0 -1
- package/dist/chunk-SIXBB6JU.js.map +0 -1
- /package/dist/{admin-server-DQVIEHV3.js.map → admin-server-UODBPGWR.js.map} +0 -0
- /package/dist/{boilerplate-manager-P6QYUU7Q.js.map → app-manager-FIHPVUP7.js.map} +0 -0
- /package/dist/{cloudflare-client-TFT6VCXF.js.map → boilerplate-manager-WEFTHL2O.js.map} +0 -0
- /package/dist/{chunk-DH2VK3YI.js.map → chunk-54WFZCU6.js.map} +0 -0
- /package/dist/{compose-generator-O7GSIJ2S.js.map → cloudflare-client-F2TGQXGS.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -11,7 +11,8 @@ import {
|
|
|
11
11
|
queryLogs,
|
|
12
12
|
removeService,
|
|
13
13
|
restoreBackup
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-YAYXULLO.js";
|
|
15
|
+
import "./chunk-JIPAYMOA.js";
|
|
15
16
|
import {
|
|
16
17
|
FRONTEND_REGISTRY,
|
|
17
18
|
LANGUAGE_REGISTRY,
|
|
@@ -28,7 +29,7 @@ import {
|
|
|
28
29
|
getTunnelHealth,
|
|
29
30
|
getZones,
|
|
30
31
|
verifyToken
|
|
31
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-YXFDB5YX.js";
|
|
32
33
|
import {
|
|
33
34
|
cloneStack,
|
|
34
35
|
generateEnv,
|
|
@@ -36,11 +37,11 @@ import {
|
|
|
36
37
|
reinitGit,
|
|
37
38
|
startContainers,
|
|
38
39
|
verifyEndpoints
|
|
39
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-54WFZCU6.js";
|
|
40
41
|
import {
|
|
41
42
|
composeConfigToYaml,
|
|
42
43
|
generateComposeConfig
|
|
43
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-AXSHZEB3.js";
|
|
44
45
|
import {
|
|
45
46
|
applyFullInstallDefaults,
|
|
46
47
|
applyMinimalInstallDefaults,
|
|
@@ -70,7 +71,7 @@ import {
|
|
|
70
71
|
import { Command } from "commander";
|
|
71
72
|
|
|
72
73
|
// src/commands/init.ts
|
|
73
|
-
import { existsSync as
|
|
74
|
+
import { existsSync as existsSync6 } from "fs";
|
|
74
75
|
import { resolve } from "path";
|
|
75
76
|
import { createRequire } from "module";
|
|
76
77
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
@@ -83,8 +84,7 @@ import chalk from "chalk";
|
|
|
83
84
|
var AUTO_PROPAGATED_SERVICES = [
|
|
84
85
|
"Nextcloud (File Server)",
|
|
85
86
|
"MinIO (Object Storage)",
|
|
86
|
-
"pgAdmin (DB Admin UI)"
|
|
87
|
-
"SSH Server (OpenSSH)"
|
|
87
|
+
"pgAdmin (DB Admin UI)"
|
|
88
88
|
];
|
|
89
89
|
var MANUAL_SETUP_SERVICES = [
|
|
90
90
|
"Gitea (Git server)",
|
|
@@ -1755,35 +1755,7 @@ async function runServerComponentsStep(state) {
|
|
|
1755
1755
|
next.servers.media.enabled = mediaEnabled;
|
|
1756
1756
|
next.servers.media.services = mediaEnabled ? ["jellyfin"] : [];
|
|
1757
1757
|
console.log();
|
|
1758
|
-
|
|
1759
|
-
console.log(chalk5.dim(" \uD130\uBBF8\uB110\uB85C \uC11C\uBC84\uC5D0 \uC6D0\uACA9 \uC811\uC18D\uD558\uAC70\uB098 SFTP\uB85C \uD30C\uC77C\uC744 \uC804\uC1A1\uD558\uB294 \uBCF4\uC548 \uCC44\uB110"));
|
|
1760
|
-
console.log();
|
|
1761
|
-
const sshEnabled = await confirm2({
|
|
1762
|
-
message: "Enable SSH Server?",
|
|
1763
|
-
default: next.servers.sshServer.enabled
|
|
1764
|
-
});
|
|
1765
|
-
next.servers.sshServer.enabled = sshEnabled;
|
|
1766
|
-
if (sshEnabled) {
|
|
1767
|
-
next.servers.sshServer.port = 2222;
|
|
1768
|
-
console.log(chalk5.dim(" SSH port: 2222"));
|
|
1769
|
-
const passwordAuth = await confirm2({
|
|
1770
|
-
message: "Allow password authentication? (key-only auth recommended)",
|
|
1771
|
-
default: next.servers.sshServer.passwordAuth ?? false
|
|
1772
|
-
});
|
|
1773
|
-
next.servers.sshServer.passwordAuth = passwordAuth;
|
|
1774
|
-
if (shouldAutoSuggestSftp(next)) {
|
|
1775
|
-
console.log(
|
|
1776
|
-
chalk5.dim(" SFTP auto-enabled (File Server or Media Server is active)")
|
|
1777
|
-
);
|
|
1778
|
-
next.servers.sshServer.sftp = true;
|
|
1779
|
-
} else {
|
|
1780
|
-
const sftpEnabled = await confirm2({
|
|
1781
|
-
message: "Enable SFTP subsystem?",
|
|
1782
|
-
default: next.servers.sshServer.sftp
|
|
1783
|
-
});
|
|
1784
|
-
next.servers.sshServer.sftp = sftpEnabled;
|
|
1785
|
-
}
|
|
1786
|
-
}
|
|
1758
|
+
next.servers.sshServer.enabled = false;
|
|
1787
1759
|
console.log();
|
|
1788
1760
|
const finalState = applyComponentRules(next);
|
|
1789
1761
|
const resources = estimateResources(finalState);
|
|
@@ -2240,41 +2212,25 @@ async function runDomainNetworkStep(state) {
|
|
|
2240
2212
|
description: "\uACC4\uC815 \uC5C6\uC774 \uBC14\uB85C \uC2DC\uC791. \uB2E8, \uC11C\uBC84 \uC7AC\uC2DC\uC791 \uC2DC URL\uC774 \uBCC0\uACBD\uB429\uB2C8\uB2E4."
|
|
2241
2213
|
},
|
|
2242
2214
|
{
|
|
2243
|
-
name: "2. Named Tunnel
|
|
2244
|
-
value: "2-named
|
|
2245
|
-
description: "Cloudflare \uACC4\uC815 + \uB3C4\uBA54\uC778
|
|
2215
|
+
name: "2. Named Tunnel (Cloudflare \uACC4\uC815 \uD544\uC694, \uC601\uAD6C URL)",
|
|
2216
|
+
value: "2-named",
|
|
2217
|
+
description: "Cloudflare \uACC4\uC815 + API \uD1A0\uD070 \uD544\uC694. \uB3C4\uBA54\uC778 \uC720\uBB34\uC5D0 \uB530\uB77C \uC124\uC815\uC774 \uB2EC\uB77C\uC9D1\uB2C8\uB2E4."
|
|
2246
2218
|
},
|
|
2247
2219
|
{
|
|
2248
|
-
name: "3.
|
|
2249
|
-
value: "3-
|
|
2250
|
-
description: "\uB3C4\uBA54\uC778 \uAD6C\uC785 \uAC00\uC774\uB4DC \uC81C\uACF5. \uC784\uC2DC Quick Tunnel\uB85C \uC989\uC2DC \uC811\uADFC \uAC00\uB2A5."
|
|
2251
|
-
},
|
|
2252
|
-
{
|
|
2253
|
-
name: "4. Named Tunnel\uB9CC \uC0DD\uC131 \u2014 \uB3C4\uBA54\uC778\uC740 \uB098\uC911\uC5D0 \uC5F0\uACB0",
|
|
2254
|
-
value: "4-named-only",
|
|
2255
|
-
description: "\uD130\uB110\uB9CC \uC900\uBE44. `brewnet domain connect`\uB85C \uB3C4\uBA54\uC778 \uCD94\uAC00 \uAC00\uB2A5."
|
|
2256
|
-
},
|
|
2257
|
-
{
|
|
2258
|
-
name: "5. \uB85C\uCEEC \uC804\uC6A9 (\uC678\uBD80 \uC811\uADFC \uC5C6\uC74C)",
|
|
2259
|
-
value: "5-local",
|
|
2220
|
+
name: "3. \uB85C\uCEEC \uC804\uC6A9 (\uC678\uBD80 \uC811\uADFC \uC5C6\uC74C)",
|
|
2221
|
+
value: "3-local",
|
|
2260
2222
|
description: "\uB0B4\uBD80 \uB124\uD2B8\uC6CC\uD06C\uC5D0\uC11C\uB9CC \uC811\uADFC. brewnet.local \uB3C4\uBA54\uC778 \uC0AC\uC6A9."
|
|
2261
2223
|
}
|
|
2262
2224
|
]
|
|
2263
2225
|
});
|
|
2264
2226
|
console.log();
|
|
2265
|
-
if (scenario === "
|
|
2227
|
+
if (scenario === "3-local") {
|
|
2266
2228
|
return runLocalScenario(next);
|
|
2267
2229
|
}
|
|
2268
2230
|
if (scenario === "1-quick") {
|
|
2269
2231
|
return runQuickTunnelScenario(next, tunnelLogger);
|
|
2270
2232
|
}
|
|
2271
|
-
|
|
2272
|
-
return runNamedTunnelWithDomainScenario(next, tunnelLogger);
|
|
2273
|
-
}
|
|
2274
|
-
if (scenario === "3-named-buy") {
|
|
2275
|
-
return runGuidedDomainPurchaseScenario(next, tunnelLogger);
|
|
2276
|
-
}
|
|
2277
|
-
return runNamedTunnelOnlyScenario(next, tunnelLogger);
|
|
2233
|
+
return runUnifiedNamedTunnelScenario(next, tunnelLogger);
|
|
2278
2234
|
}
|
|
2279
2235
|
function runLocalScenario(next) {
|
|
2280
2236
|
next.domain.provider = "local";
|
|
@@ -2552,63 +2508,56 @@ async function runNamedTunnelApiFlow(next, tunnelLogger, includeDns) {
|
|
|
2552
2508
|
next.domain.cloudflare.apiToken = "";
|
|
2553
2509
|
return next;
|
|
2554
2510
|
}
|
|
2555
|
-
async function
|
|
2511
|
+
async function runUnifiedNamedTunnelScenario(next, tunnelLogger) {
|
|
2556
2512
|
next.domain.provider = "tunnel";
|
|
2557
2513
|
next.domain.ssl = "cloudflare";
|
|
2558
2514
|
next.domain.cloudflare.enabled = true;
|
|
2559
2515
|
next.domain.cloudflare.tunnelMode = "named";
|
|
2516
|
+
let qtManager = null;
|
|
2560
2517
|
try {
|
|
2561
|
-
const
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
console.log(chalk7.red(` \uC624\uB958: ${err instanceof Error ? err.message : String(err)}`));
|
|
2518
|
+
const hasDomain = await confirm4({
|
|
2519
|
+
message: "Cloudflare\uC5D0 \uB4F1\uB85D\uB41C \uB3C4\uBA54\uC778\uC774 \uC774\uBBF8 \uC788\uC73C\uC2E0\uAC00\uC694?",
|
|
2520
|
+
default: true
|
|
2521
|
+
});
|
|
2566
2522
|
console.log();
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
}
|
|
2570
|
-
}
|
|
2571
|
-
async function runGuidedDomainPurchaseScenario(next, tunnelLogger) {
|
|
2572
|
-
console.log(chalk7.bold(" \uB3C4\uBA54\uC778 \uAD6C\uC785 \uC548\uB0B4"));
|
|
2573
|
-
console.log();
|
|
2574
|
-
console.log(chalk7.bold.white(" Cloudflare\uC5D0\uC11C \uB3C4\uBA54\uC778\uC744 \uB4F1\uB85D\uD558\uB294 \uBC29\uBC95:"));
|
|
2575
|
-
console.log();
|
|
2576
|
-
console.log(chalk7.dim(" 1. https://domains.cloudflare.com \u2192 \uB85C\uADF8\uC778 \uB610\uB294 \uACC4\uC815 \uC0DD\uC131"));
|
|
2577
|
-
console.log(chalk7.dim(" 2. \uB3C4\uBA54\uC778 \uAC80\uC0C9 \u2192 \uB4F1\uB85D (\uC5F0 $8~15 \uC218\uC900, .com \uAE30\uC900)"));
|
|
2578
|
-
console.log(chalk7.dim(" 3. \uB3C4\uBA54\uC778\uC774 Cloudflare \uB124\uC784\uC11C\uBC84\uB85C \uC790\uB3D9 \uC124\uC815\uB429\uB2C8\uB2E4"));
|
|
2579
|
-
console.log(chalk7.dim(" 4. \uB4F1\uB85D \uC644\uB8CC\uAE4C\uC9C0 1~5\uBD84 \uC18C\uC694"));
|
|
2580
|
-
console.log();
|
|
2581
|
-
const useBridge = await confirm4({
|
|
2582
|
-
message: "Quick Tunnel\uB85C \uC784\uC2DC \uC811\uADFC\uC744 \uC2DC\uC791\uD558\uACA0\uC2B5\uB2C8\uAE4C? (\uB3C4\uBA54\uC778 \uC900\uBE44 \uC911\uC5D0\uB3C4 \uC11C\uBE44\uC2A4\uC5D0 \uC811\uADFC \uAC00\uB2A5)",
|
|
2583
|
-
default: true
|
|
2584
|
-
});
|
|
2585
|
-
console.log();
|
|
2586
|
-
let qtManager = null;
|
|
2587
|
-
if (useBridge) {
|
|
2588
|
-
const spinner = ora3("Quick Tunnel \uC2DC\uC791 \uC911...").start();
|
|
2589
|
-
try {
|
|
2590
|
-
qtManager = new QuickTunnelManager(tunnelLogger);
|
|
2591
|
-
const url = await qtManager.start();
|
|
2592
|
-
spinner.succeed(chalk7.green(`\uC784\uC2DC URL: ${url}`));
|
|
2593
|
-
console.log(chalk7.dim(" \uB3C4\uBA54\uC778 \uC900\uBE44\uAC00 \uC644\uB8CC\uB418\uBA74 \uC544\uB798\uC5D0\uC11C Enter\uB97C \uB20C\uB7EC Named Tunnel\uB85C \uC804\uD658\uD569\uB2C8\uB2E4."));
|
|
2523
|
+
if (!hasDomain) {
|
|
2524
|
+
console.log(chalk7.bold(" \uB3C4\uBA54\uC778 \uAD6C\uC785 \uC548\uB0B4"));
|
|
2594
2525
|
console.log();
|
|
2595
|
-
|
|
2596
|
-
|
|
2526
|
+
console.log(chalk7.bold.white(" Cloudflare\uC5D0\uC11C \uB3C4\uBA54\uC778\uC744 \uB4F1\uB85D\uD558\uB294 \uBC29\uBC95:"));
|
|
2527
|
+
console.log();
|
|
2528
|
+
console.log(chalk7.dim(" 1. https://domains.cloudflare.com \u2192 \uB85C\uADF8\uC778 \uB610\uB294 \uACC4\uC815 \uC0DD\uC131"));
|
|
2529
|
+
console.log(chalk7.dim(" 2. \uB3C4\uBA54\uC778 \uAC80\uC0C9 \u2192 \uB4F1\uB85D (\uC5F0 $8~15 \uC218\uC900, .com \uAE30\uC900)"));
|
|
2530
|
+
console.log(chalk7.dim(" 3. \uB3C4\uBA54\uC778\uC774 Cloudflare \uB124\uC784\uC11C\uBC84\uB85C \uC790\uB3D9 \uC124\uC815\uB429\uB2C8\uB2E4"));
|
|
2531
|
+
console.log(chalk7.dim(" 4. \uB4F1\uB85D \uC644\uB8CC\uAE4C\uC9C0 1~5\uBD84 \uC18C\uC694"));
|
|
2532
|
+
console.log();
|
|
2533
|
+
const useBridge = await confirm4({
|
|
2534
|
+
message: "Quick Tunnel\uB85C \uC784\uC2DC \uC811\uADFC\uC744 \uC2DC\uC791\uD558\uACA0\uC2B5\uB2C8\uAE4C? (\uB3C4\uBA54\uC778 \uC900\uBE44 \uC911\uC5D0\uB3C4 \uC11C\uBE44\uC2A4\uC5D0 \uC811\uADFC \uAC00\uB2A5)",
|
|
2535
|
+
default: true
|
|
2536
|
+
});
|
|
2537
|
+
console.log();
|
|
2538
|
+
if (useBridge) {
|
|
2539
|
+
const spinner = ora3("Quick Tunnel \uC2DC\uC791 \uC911...").start();
|
|
2540
|
+
try {
|
|
2541
|
+
qtManager = new QuickTunnelManager(tunnelLogger);
|
|
2542
|
+
const url = await qtManager.start();
|
|
2543
|
+
spinner.succeed(chalk7.green(`\uC784\uC2DC URL: ${url}`));
|
|
2544
|
+
console.log(chalk7.dim(" \uB3C4\uBA54\uC778 \uC900\uBE44\uAC00 \uC644\uB8CC\uB418\uBA74 \uC544\uB798\uC5D0\uC11C Enter\uB97C \uB20C\uB7EC Named Tunnel\uB85C \uC804\uD658\uD569\uB2C8\uB2E4."));
|
|
2545
|
+
console.log();
|
|
2546
|
+
} catch (err) {
|
|
2547
|
+
spinner.fail(chalk7.yellow(`Quick Tunnel \uC2E4\uD328: ${err instanceof Error ? err.message : String(err)}`));
|
|
2548
|
+
console.log();
|
|
2549
|
+
qtManager = null;
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
await input5({
|
|
2553
|
+
message: "\uB3C4\uBA54\uC778 \uC124\uC815 \uC644\uB8CC \uD6C4 Enter\uB97C \uB204\uB974\uC138\uC694",
|
|
2554
|
+
default: ""
|
|
2555
|
+
});
|
|
2597
2556
|
console.log();
|
|
2598
|
-
|
|
2557
|
+
next.domain.cloudflare.zoneId = "";
|
|
2558
|
+
next.domain.cloudflare.zoneName = "";
|
|
2599
2559
|
}
|
|
2600
|
-
|
|
2601
|
-
await input5({
|
|
2602
|
-
message: "\uB3C4\uBA54\uC778 \uC124\uC815 \uC644\uB8CC \uD6C4 Enter\uB97C \uB204\uB974\uC138\uC694",
|
|
2603
|
-
default: ""
|
|
2604
|
-
});
|
|
2605
|
-
console.log();
|
|
2606
|
-
next.domain.provider = "tunnel";
|
|
2607
|
-
next.domain.ssl = "cloudflare";
|
|
2608
|
-
next.domain.cloudflare.enabled = true;
|
|
2609
|
-
next.domain.cloudflare.tunnelMode = "named";
|
|
2610
|
-
try {
|
|
2611
|
-
const updated = await runNamedTunnelApiFlow(next, tunnelLogger, true);
|
|
2560
|
+
const updated = await runNamedTunnelApiFlow(next, tunnelLogger, hasDomain);
|
|
2612
2561
|
if (qtManager) {
|
|
2613
2562
|
const stopSpinner = ora3("\uC784\uC2DC Quick Tunnel \uC911\uC9C0 \uC911...").start();
|
|
2614
2563
|
try {
|
|
@@ -2619,11 +2568,16 @@ async function runGuidedDomainPurchaseScenario(next, tunnelLogger) {
|
|
|
2619
2568
|
}
|
|
2620
2569
|
console.log();
|
|
2621
2570
|
}
|
|
2571
|
+
if (!hasDomain) {
|
|
2572
|
+
console.log(chalk7.dim(" \uB3C4\uBA54\uC778 \uC5F0\uACB0: `brewnet domain connect`"));
|
|
2573
|
+
console.log();
|
|
2574
|
+
}
|
|
2622
2575
|
printNetworkSummary(updated);
|
|
2623
2576
|
return updated;
|
|
2624
2577
|
} catch (err) {
|
|
2625
2578
|
if (qtManager) {
|
|
2626
|
-
await qtManager.stop().catch(() => {
|
|
2579
|
+
await qtManager.stop().catch((stopErr) => {
|
|
2580
|
+
console.warn("[Named Tunnel] Quick Tunnel \uC911\uC9C0 \uC2E4\uD328:", stopErr instanceof Error ? stopErr.message : String(stopErr));
|
|
2627
2581
|
});
|
|
2628
2582
|
}
|
|
2629
2583
|
console.log(chalk7.red(` \uC624\uB958: ${err instanceof Error ? err.message : String(err)}`));
|
|
@@ -2632,30 +2586,6 @@ async function runGuidedDomainPurchaseScenario(next, tunnelLogger) {
|
|
|
2632
2586
|
return runLocalScenario(next);
|
|
2633
2587
|
}
|
|
2634
2588
|
}
|
|
2635
|
-
async function runNamedTunnelOnlyScenario(next, tunnelLogger) {
|
|
2636
|
-
console.log(chalk7.bold(" Named Tunnel \uC0DD\uC131 (\uB3C4\uBA54\uC778 \uC5F0\uACB0\uC740 \uB098\uC911\uC5D0)"));
|
|
2637
|
-
console.log(chalk7.dim(" \uD130\uB110\uB9CC \uC0DD\uC131\uD558\uACE0, \uB3C4\uBA54\uC778 \uC5F0\uACB0\uC740 \uC124\uCE58 \uC644\uB8CC \uD6C4"));
|
|
2638
|
-
console.log(chalk7.dim(" `brewnet domain connect` \uBA85\uB839\uC73C\uB85C \uC9C4\uD589\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."));
|
|
2639
|
-
console.log();
|
|
2640
|
-
next.domain.provider = "tunnel";
|
|
2641
|
-
next.domain.ssl = "cloudflare";
|
|
2642
|
-
next.domain.cloudflare.enabled = true;
|
|
2643
|
-
next.domain.cloudflare.tunnelMode = "named";
|
|
2644
|
-
next.domain.cloudflare.zoneId = "";
|
|
2645
|
-
next.domain.cloudflare.zoneName = "";
|
|
2646
|
-
try {
|
|
2647
|
-
const updated = await runNamedTunnelApiFlow(next, tunnelLogger, false);
|
|
2648
|
-
console.log(chalk7.dim(" \uB3C4\uBA54\uC778 \uC5F0\uACB0: `brewnet domain connect`"));
|
|
2649
|
-
console.log();
|
|
2650
|
-
printNetworkSummary(updated);
|
|
2651
|
-
return updated;
|
|
2652
|
-
} catch (err) {
|
|
2653
|
-
console.log(chalk7.red(` \uC624\uB958: ${err instanceof Error ? err.message : String(err)}`));
|
|
2654
|
-
console.log();
|
|
2655
|
-
console.log(chalk7.yellow(" Local \uBAA8\uB4DC\uB85C \uC804\uD658\uD569\uB2C8\uB2E4."));
|
|
2656
|
-
return runLocalScenario(next);
|
|
2657
|
-
}
|
|
2658
|
-
}
|
|
2659
2589
|
async function waitForTunnelHealthy(apiToken, accountId, tunnelId, timeoutMs) {
|
|
2660
2590
|
const start = Date.now();
|
|
2661
2591
|
const pollIntervalMs = 2e3;
|
|
@@ -3152,7 +3082,7 @@ async function runReviewStep(state) {
|
|
|
3152
3082
|
}
|
|
3153
3083
|
|
|
3154
3084
|
// src/wizard/steps/generate.ts
|
|
3155
|
-
import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync5, readFileSync as readFileSync2, existsSync as
|
|
3085
|
+
import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync5, readFileSync as readFileSync2, existsSync as existsSync2, chmodSync as chmodSync2 } from "fs";
|
|
3156
3086
|
import { join as join3, dirname } from "path";
|
|
3157
3087
|
import { homedir as homedir2 } from "os";
|
|
3158
3088
|
import chalk9 from "chalk";
|
|
@@ -3878,6 +3808,15 @@ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\
|
|
|
3878
3808
|
box-shadow:0 0 6px rgba(34,197,94,0.4); animation:pulse 2.5s ease-in-out infinite; }
|
|
3879
3809
|
@keyframes pulse { 0%,100%{opacity:1;box-shadow:0 0 6px rgba(34,197,94,0.4)}
|
|
3880
3810
|
50%{opacity:.5;box-shadow:0 0 2px rgba(34,197,94,0.2)} }
|
|
3811
|
+
.hero-links { display:flex; align-items:center; justify-content:center; gap:.75rem;
|
|
3812
|
+
margin-top:1.5rem; flex-wrap:wrap; }
|
|
3813
|
+
.hero-links a { display:inline-flex; align-items:center; gap:.4rem; padding:.45rem 1rem;
|
|
3814
|
+
border:1px solid var(--border); border-radius:100px; font-family:var(--mono);
|
|
3815
|
+
font-size:.75rem; color:var(--text-muted); background:var(--surface-raised);
|
|
3816
|
+
text-decoration:none; transition:border-color .2s, color .2s; }
|
|
3817
|
+
.hero-links a:hover { border-color:#333; color:var(--text); }
|
|
3818
|
+
.hero-links a svg { flex-shrink:0; fill:currentColor; }
|
|
3819
|
+
.hero-domain svg { fill:none; stroke:currentColor; }
|
|
3881
3820
|
.footer { position:fixed; bottom:1.2rem; left:0; right:0; text-align:center;
|
|
3882
3821
|
font-family:var(--mono); font-size:.65rem; color:#2a2a2a; letter-spacing:.08em; z-index:1; }
|
|
3883
3822
|
.footer span { color:#333; }
|
|
@@ -3903,6 +3842,16 @@ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\
|
|
|
3903
3842
|
<span class="dot"></span>
|
|
3904
3843
|
systems operational
|
|
3905
3844
|
</div>
|
|
3845
|
+
<div class="hero-links">
|
|
3846
|
+
<a href="https://brewnet.dev" class="hero-domain" target="_blank" rel="noopener">
|
|
3847
|
+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><path d="M2 12h20"></path><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path></svg>
|
|
3848
|
+
brewnet.dev
|
|
3849
|
+
</a>
|
|
3850
|
+
<a href="https://github.com/claude-code-expert/brewnet" class="hero-github" target="_blank" rel="noopener">
|
|
3851
|
+
<svg width="16" height="16" viewBox="0 0 16 16"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path></svg>
|
|
3852
|
+
GitHub
|
|
3853
|
+
</a>
|
|
3854
|
+
</div>
|
|
3906
3855
|
</div>
|
|
3907
3856
|
<div class="footer">
|
|
3908
3857
|
brewnet.dev <span>·</span> MIT
|
|
@@ -4570,7 +4519,7 @@ async function runGenerateStep(state) {
|
|
|
4570
4519
|
pollHealth: boilerplatePollHealth,
|
|
4571
4520
|
verifyEndpoints: boilerplateVerifyEndpoints,
|
|
4572
4521
|
findFreePort
|
|
4573
|
-
} = await import("./boilerplate-manager-
|
|
4522
|
+
} = await import("./boilerplate-manager-WEFTHL2O.js");
|
|
4574
4523
|
const dbPrimary = state.servers.dbServer.primary;
|
|
4575
4524
|
const dbDriver = dbPrimary === "postgresql" ? "postgres" : dbPrimary === "mysql" ? "mysql" : "sqlite3";
|
|
4576
4525
|
const dbOpts = {
|
|
@@ -4627,7 +4576,7 @@ async function runGenerateStep(state) {
|
|
|
4627
4576
|
{
|
|
4628
4577
|
const { execa: execaFn } = await import("execa");
|
|
4629
4578
|
const stale = prevStackMetas.filter(
|
|
4630
|
-
(prev) => prev.stackId === stackId && prev.appDir !== appDir &&
|
|
4579
|
+
(prev) => prev.stackId === stackId && prev.appDir !== appDir && existsSync2(prev.appDir)
|
|
4631
4580
|
);
|
|
4632
4581
|
for (const prev of stale) {
|
|
4633
4582
|
bpSpinner.text = ` [${stackId}] \uC774\uC804 \uCEE8\uD14C\uC774\uB108 \uC815\uB9AC \uC911...`;
|
|
@@ -4640,7 +4589,7 @@ async function runGenerateStep(state) {
|
|
|
4640
4589
|
let isNextjsBasePath = false;
|
|
4641
4590
|
if (state.domain.cloudflare.tunnelMode === "quick") {
|
|
4642
4591
|
try {
|
|
4643
|
-
const { injectTraefikForQuickTunnel } = await import("./boilerplate-manager-
|
|
4592
|
+
const { injectTraefikForQuickTunnel } = await import("./boilerplate-manager-WEFTHL2O.js");
|
|
4644
4593
|
injectTraefikForQuickTunnel(appDir, stackId, backendPort);
|
|
4645
4594
|
if (stackId.startsWith("nodejs-nextjs")) isNextjsBasePath = true;
|
|
4646
4595
|
} catch {
|
|
@@ -4873,7 +4822,7 @@ async function runGenerateStep(state) {
|
|
|
4873
4822
|
});
|
|
4874
4823
|
gitea.succeed(` Gitea: admin \uACC4\uC815 \uC0DD\uC131 \uC644\uB8CC (${adminUser})`);
|
|
4875
4824
|
const tokenPath = join3(homedir2(), ".brewnet", "gitea-token");
|
|
4876
|
-
if (!
|
|
4825
|
+
if (!existsSync2(tokenPath)) {
|
|
4877
4826
|
const giteaDirectUrl = "http://localhost:3000";
|
|
4878
4827
|
const basic = Buffer.from(`${adminUser}:${adminPass}`).toString("base64");
|
|
4879
4828
|
try {
|
|
@@ -4891,6 +4840,11 @@ async function runGenerateStep(state) {
|
|
|
4891
4840
|
writeFileSync3(tokenPath, td.sha1, "utf-8");
|
|
4892
4841
|
chmodSync2(tokenPath, 384);
|
|
4893
4842
|
gitea.succeed(" Gitea: API \uD1A0\uD070 \uC0DD\uC131 \uC644\uB8CC");
|
|
4843
|
+
try {
|
|
4844
|
+
const { saveGiteaConfig } = await import("./app-manager-FIHPVUP7.js");
|
|
4845
|
+
saveGiteaConfig("http://localhost/git", adminUser);
|
|
4846
|
+
} catch {
|
|
4847
|
+
}
|
|
4894
4848
|
} else {
|
|
4895
4849
|
const errBody = await tr.text();
|
|
4896
4850
|
gitea.warn(` Gitea: API \uD1A0\uD070 \uC0DD\uC131 \uC2E4\uD328 (${tr.status}) \u2014 create-app \uC2DC \uC790\uB3D9 \uC7AC\uC2DC\uB3C4\uB429\uB2C8\uB2E4`);
|
|
@@ -4939,7 +4893,7 @@ async function runGenerateStep(state) {
|
|
|
4939
4893
|
}
|
|
4940
4894
|
|
|
4941
4895
|
// src/services/uninstall-manager.ts
|
|
4942
|
-
import { existsSync as
|
|
4896
|
+
import { existsSync as existsSync3, rmSync, readdirSync, readFileSync as readFileSync3 } from "fs";
|
|
4943
4897
|
import { homedir as homedir3 } from "os";
|
|
4944
4898
|
import { join as join4 } from "path";
|
|
4945
4899
|
import { execa as execa5 } from "execa";
|
|
@@ -4958,7 +4912,7 @@ function expandPath(p) {
|
|
|
4958
4912
|
var BREWNET_DIR = join4(homedir3(), ".brewnet");
|
|
4959
4913
|
function readManifest(projectPath) {
|
|
4960
4914
|
const manifestPath = join4(projectPath, ".brewnet-manifest.json");
|
|
4961
|
-
if (!
|
|
4915
|
+
if (!existsSync3(manifestPath)) return null;
|
|
4962
4916
|
try {
|
|
4963
4917
|
const raw = readFileSync3(manifestPath, "utf-8");
|
|
4964
4918
|
const parsed = JSON.parse(raw);
|
|
@@ -4974,7 +4928,7 @@ async function stopBoilerplateContainers(projectPath, stacks, keepData, result)
|
|
|
4974
4928
|
for (const stack of stacks) {
|
|
4975
4929
|
const stackDir = join4(projectPath, stack.directory);
|
|
4976
4930
|
const stackCompose = join4(stackDir, DOCKER_COMPOSE_FILENAME);
|
|
4977
|
-
if (!
|
|
4931
|
+
if (!existsSync3(stackCompose)) {
|
|
4978
4932
|
result.skipped.push(`Boilerplate containers [${stack.stackId}]: compose not found`);
|
|
4979
4933
|
continue;
|
|
4980
4934
|
}
|
|
@@ -4996,7 +4950,7 @@ async function stopBoilerplateContainers(projectPath, stacks, keepData, result)
|
|
|
4996
4950
|
function removeByManifest(projectPath, manifest, result) {
|
|
4997
4951
|
for (const stack of manifest.boilerplateStacks) {
|
|
4998
4952
|
const stackDir = join4(projectPath, stack.directory);
|
|
4999
|
-
if (
|
|
4953
|
+
if (existsSync3(stackDir)) {
|
|
5000
4954
|
try {
|
|
5001
4955
|
rmSync(stackDir, { recursive: true, force: true });
|
|
5002
4956
|
result.removed.push(`Boilerplate source [${stack.stackId}]: ${stackDir}`);
|
|
@@ -5009,7 +4963,7 @@ function removeByManifest(projectPath, manifest, result) {
|
|
|
5009
4963
|
}
|
|
5010
4964
|
for (const dir of manifest.generatedDirs) {
|
|
5011
4965
|
const dirPath = join4(projectPath, dir);
|
|
5012
|
-
if (
|
|
4966
|
+
if (existsSync3(dirPath)) {
|
|
5013
4967
|
try {
|
|
5014
4968
|
rmSync(dirPath, { recursive: true, force: true });
|
|
5015
4969
|
result.removed.push(`Generated dir: ${dir}/`);
|
|
@@ -5022,7 +4976,7 @@ function removeByManifest(projectPath, manifest, result) {
|
|
|
5022
4976
|
let removedFileCount = 0;
|
|
5023
4977
|
for (const file of manifest.generatedFiles) {
|
|
5024
4978
|
const filePath = join4(projectPath, file);
|
|
5025
|
-
if (
|
|
4979
|
+
if (existsSync3(filePath)) {
|
|
5026
4980
|
try {
|
|
5027
4981
|
rmSync(filePath, { force: true });
|
|
5028
4982
|
removedFileCount++;
|
|
@@ -5065,7 +5019,7 @@ function resolveProject(options) {
|
|
|
5065
5019
|
function buildUninstallTargets(projectPath, options) {
|
|
5066
5020
|
const targets = [];
|
|
5067
5021
|
if (projectPath) projectPath = expandPath(projectPath);
|
|
5068
|
-
if (projectPath &&
|
|
5022
|
+
if (projectPath && existsSync3(join4(projectPath, DOCKER_COMPOSE_FILENAME))) {
|
|
5069
5023
|
targets.push({
|
|
5070
5024
|
label: `Docker containers${options.keepData ? "" : " + volumes + images"}`,
|
|
5071
5025
|
path: join4(projectPath, DOCKER_COMPOSE_FILENAME),
|
|
@@ -5077,7 +5031,7 @@ function buildUninstallTargets(projectPath, options) {
|
|
|
5077
5031
|
if (manifest) {
|
|
5078
5032
|
for (const stack of manifest.boilerplateStacks) {
|
|
5079
5033
|
const stackCompose = join4(projectPath, stack.directory, DOCKER_COMPOSE_FILENAME);
|
|
5080
|
-
if (
|
|
5034
|
+
if (existsSync3(stackCompose)) {
|
|
5081
5035
|
targets.push({
|
|
5082
5036
|
label: `Boilerplate containers [${stack.stackId}]${options.keepData ? "" : " + volumes + images"}`,
|
|
5083
5037
|
path: stackCompose,
|
|
@@ -5103,7 +5057,7 @@ function buildUninstallTargets(projectPath, options) {
|
|
|
5103
5057
|
skipReason: options.keepConfig ? "--keep-config" : void 0
|
|
5104
5058
|
});
|
|
5105
5059
|
}
|
|
5106
|
-
if (
|
|
5060
|
+
if (existsSync3(BREWNET_DIR)) {
|
|
5107
5061
|
targets.push({
|
|
5108
5062
|
label: "~/.brewnet/ (all data, source, config)",
|
|
5109
5063
|
path: BREWNET_DIR,
|
|
@@ -5116,7 +5070,7 @@ function buildUninstallTargets(projectPath, options) {
|
|
|
5116
5070
|
"/usr/bin/brewnet"
|
|
5117
5071
|
];
|
|
5118
5072
|
for (const bin of possibleBins) {
|
|
5119
|
-
if (
|
|
5073
|
+
if (existsSync3(bin)) {
|
|
5120
5074
|
targets.push({ label: `CLI binary: ${bin}`, path: bin, type: "brewnet-meta" });
|
|
5121
5075
|
}
|
|
5122
5076
|
}
|
|
@@ -5142,7 +5096,7 @@ async function runUninstall(options = {}) {
|
|
|
5142
5096
|
await stopBoilerplateContainers(projectPath, manifest.boilerplateStacks, options.keepData ?? false, result);
|
|
5143
5097
|
}
|
|
5144
5098
|
}
|
|
5145
|
-
if (projectPath &&
|
|
5099
|
+
if (projectPath && existsSync3(join4(projectPath, DOCKER_COMPOSE_FILENAME))) {
|
|
5146
5100
|
try {
|
|
5147
5101
|
const downArgs = ["compose", "-f", DOCKER_COMPOSE_FILENAME, "down"];
|
|
5148
5102
|
if (!options.keepData) {
|
|
@@ -5201,7 +5155,7 @@ async function runUninstall(options = {}) {
|
|
|
5201
5155
|
result.skipped.push("Docker networks (not found or already removed)");
|
|
5202
5156
|
}
|
|
5203
5157
|
if (projectPath && !options.keepConfig) {
|
|
5204
|
-
if (
|
|
5158
|
+
if (existsSync3(projectPath)) {
|
|
5205
5159
|
const manifest = readManifest(projectPath);
|
|
5206
5160
|
if (manifest) {
|
|
5207
5161
|
removeByManifest(projectPath, manifest, result);
|
|
@@ -5224,7 +5178,7 @@ async function runUninstall(options = {}) {
|
|
|
5224
5178
|
} else if (options.keepConfig) {
|
|
5225
5179
|
result.skipped.push(`Project directory preserved (--keep-config): ${projectPath ?? "n/a"}`);
|
|
5226
5180
|
}
|
|
5227
|
-
if (
|
|
5181
|
+
if (existsSync3(BREWNET_DIR)) {
|
|
5228
5182
|
try {
|
|
5229
5183
|
rmSync(BREWNET_DIR, { recursive: true, force: true });
|
|
5230
5184
|
result.removed.push("~/.brewnet/ (all data, source, config)");
|
|
@@ -5236,7 +5190,7 @@ async function runUninstall(options = {}) {
|
|
|
5236
5190
|
}
|
|
5237
5191
|
if (projectName) {
|
|
5238
5192
|
const projectStateDir = getProjectDir(projectName);
|
|
5239
|
-
if (
|
|
5193
|
+
if (existsSync3(projectStateDir)) {
|
|
5240
5194
|
try {
|
|
5241
5195
|
rmSync(projectStateDir, { recursive: true, force: true });
|
|
5242
5196
|
result.removed.push(`Wizard state: ~/.brewnet/projects/${projectName}`);
|
|
@@ -5250,7 +5204,7 @@ async function runUninstall(options = {}) {
|
|
|
5250
5204
|
"/usr/bin/brewnet"
|
|
5251
5205
|
];
|
|
5252
5206
|
for (const bin of possibleBins) {
|
|
5253
|
-
if (
|
|
5207
|
+
if (existsSync3(bin)) {
|
|
5254
5208
|
try {
|
|
5255
5209
|
rmSync(bin, { force: true });
|
|
5256
5210
|
result.removed.push(`CLI binary: ${bin}`);
|
|
@@ -5267,7 +5221,7 @@ async function runUninstall(options = {}) {
|
|
|
5267
5221
|
async function cleanupForRestart(projectPath) {
|
|
5268
5222
|
const expanded = expandPath(projectPath);
|
|
5269
5223
|
const composePath = join4(expanded, DOCKER_COMPOSE_FILENAME);
|
|
5270
|
-
if (
|
|
5224
|
+
if (existsSync3(composePath)) {
|
|
5271
5225
|
try {
|
|
5272
5226
|
await execa5("docker", [
|
|
5273
5227
|
"compose",
|
|
@@ -5286,7 +5240,7 @@ async function cleanupForRestart(projectPath) {
|
|
|
5286
5240
|
} catch {
|
|
5287
5241
|
}
|
|
5288
5242
|
}
|
|
5289
|
-
if (
|
|
5243
|
+
if (existsSync3(expanded)) {
|
|
5290
5244
|
try {
|
|
5291
5245
|
rmSync(expanded, { recursive: true, force: true });
|
|
5292
5246
|
} catch {
|
|
@@ -5304,7 +5258,7 @@ function listInstallations() {
|
|
|
5304
5258
|
results.push({ name, path: rawPath });
|
|
5305
5259
|
};
|
|
5306
5260
|
const projectsDir = join4(BREWNET_DIR, "projects");
|
|
5307
|
-
if (
|
|
5261
|
+
if (existsSync3(projectsDir)) {
|
|
5308
5262
|
try {
|
|
5309
5263
|
for (const e of readdirSync(projectsDir, { withFileTypes: true })) {
|
|
5310
5264
|
if (!e.isDirectory()) continue;
|
|
@@ -5315,12 +5269,12 @@ function listInstallations() {
|
|
|
5315
5269
|
}
|
|
5316
5270
|
}
|
|
5317
5271
|
const brewnetRoot = join4(homedir3(), "brewnet");
|
|
5318
|
-
if (
|
|
5272
|
+
if (existsSync3(brewnetRoot)) {
|
|
5319
5273
|
try {
|
|
5320
5274
|
for (const e of readdirSync(brewnetRoot, { withFileTypes: true })) {
|
|
5321
5275
|
if (!e.isDirectory()) continue;
|
|
5322
5276
|
const composePath = join4(brewnetRoot, e.name, DOCKER_COMPOSE_FILENAME);
|
|
5323
|
-
if (
|
|
5277
|
+
if (existsSync3(composePath)) {
|
|
5324
5278
|
addIfNew(e.name, `~/brewnet/${e.name}`);
|
|
5325
5279
|
}
|
|
5326
5280
|
}
|
|
@@ -5334,7 +5288,7 @@ function listInstallations() {
|
|
|
5334
5288
|
import chalk10 from "chalk";
|
|
5335
5289
|
import Table3 from "cli-table3";
|
|
5336
5290
|
import { execSync as execSync3 } from "child_process";
|
|
5337
|
-
import { existsSync as
|
|
5291
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
|
|
5338
5292
|
import { join as join6 } from "path";
|
|
5339
5293
|
import { homedir as homedir5 } from "os";
|
|
5340
5294
|
|
|
@@ -5342,7 +5296,7 @@ import { homedir as homedir5 } from "os";
|
|
|
5342
5296
|
import { spawn } from "child_process";
|
|
5343
5297
|
import { join as join5, dirname as dirname2 } from "path";
|
|
5344
5298
|
import { fileURLToPath } from "url";
|
|
5345
|
-
import { openSync, mkdirSync as mkdirSync6, existsSync as
|
|
5299
|
+
import { openSync, mkdirSync as mkdirSync6, existsSync as existsSync4 } from "fs";
|
|
5346
5300
|
import { homedir as homedir4 } from "os";
|
|
5347
5301
|
import { createConnection } from "net";
|
|
5348
5302
|
var __dirname = dirname2(fileURLToPath(import.meta.url));
|
|
@@ -5355,7 +5309,7 @@ function getDaemonPath() {
|
|
|
5355
5309
|
join5(__dirname, "..", "services", "admin-daemon.js")
|
|
5356
5310
|
];
|
|
5357
5311
|
for (const p of candidates) {
|
|
5358
|
-
if (
|
|
5312
|
+
if (existsSync4(p)) return p;
|
|
5359
5313
|
}
|
|
5360
5314
|
return candidates[0];
|
|
5361
5315
|
}
|
|
@@ -5533,7 +5487,7 @@ async function runCompleteStep(state, options) {
|
|
|
5533
5487
|
}
|
|
5534
5488
|
const resolvedProjectPath = state.projectPath.startsWith("~") ? join6(homedir5(), state.projectPath.slice(1)) : state.projectPath;
|
|
5535
5489
|
const boilerplateMetaPath = join6(resolvedProjectPath, ".brewnet-boilerplate.json");
|
|
5536
|
-
if (
|
|
5490
|
+
if (existsSync5(boilerplateMetaPath)) {
|
|
5537
5491
|
try {
|
|
5538
5492
|
const raw = JSON.parse(readFileSync4(boilerplateMetaPath, "utf-8"));
|
|
5539
5493
|
const stacks = Array.isArray(raw) ? raw : raw.stackId ? [raw] : [];
|
|
@@ -5703,7 +5657,7 @@ async function runInitWizard(options = {}) {
|
|
|
5703
5657
|
let state = createState();
|
|
5704
5658
|
if (options.config) {
|
|
5705
5659
|
const configPath = resolve(options.config);
|
|
5706
|
-
if (!
|
|
5660
|
+
if (!existsSync6(configPath)) {
|
|
5707
5661
|
console.log(chalk12.red(` Config file not found: ${configPath}`));
|
|
5708
5662
|
console.log();
|
|
5709
5663
|
return;
|
|
@@ -6556,7 +6510,7 @@ function registerAdminCommand(program) {
|
|
|
6556
6510
|
return;
|
|
6557
6511
|
}
|
|
6558
6512
|
if (options.foreground) {
|
|
6559
|
-
const { createAdminServer } = await import("./admin-server-
|
|
6513
|
+
const { createAdminServer } = await import("./admin-server-UODBPGWR.js");
|
|
6560
6514
|
const spinner2 = ora11(`Starting admin panel on port ${port}...`).start();
|
|
6561
6515
|
const { start } = createAdminServer({ port, projectPath: options.path || void 0 });
|
|
6562
6516
|
try {
|
|
@@ -7598,7 +7552,7 @@ async function handleDomainList() {
|
|
|
7598
7552
|
}
|
|
7599
7553
|
|
|
7600
7554
|
// src/commands/create-app.ts
|
|
7601
|
-
import { existsSync as
|
|
7555
|
+
import { existsSync as existsSync7, rmSync as rmSync2, mkdirSync as mkdirSync7, appendFileSync as appendFileSync2 } from "fs";
|
|
7602
7556
|
import { resolve as resolve2, join as join9 } from "path";
|
|
7603
7557
|
import { homedir as homedir8 } from "os";
|
|
7604
7558
|
import chalk25 from "chalk";
|
|
@@ -7661,7 +7615,7 @@ async function runCreateApp(projectName, options) {
|
|
|
7661
7615
|
let resolvedStackId = options.stack ?? "(interactive)";
|
|
7662
7616
|
const sigintHandler = () => {
|
|
7663
7617
|
process.removeListener("SIGINT", sigintHandler);
|
|
7664
|
-
if (!cloneSucceeded &&
|
|
7618
|
+
if (!cloneSucceeded && existsSync7(projectDir)) {
|
|
7665
7619
|
rmSync2(projectDir, { recursive: true, force: true });
|
|
7666
7620
|
console.log(chalk25.yellow("\n\nAborted. Partial directory removed."));
|
|
7667
7621
|
} else {
|
|
@@ -7685,7 +7639,7 @@ async function runCreateApp(projectName, options) {
|
|
|
7685
7639
|
if (dockerCheck.status !== "pass") {
|
|
7686
7640
|
throw BrewnetError.dockerNotRunning();
|
|
7687
7641
|
}
|
|
7688
|
-
if (
|
|
7642
|
+
if (existsSync7(projectDir)) {
|
|
7689
7643
|
throw BrewnetError.directoryConflict(projectName);
|
|
7690
7644
|
}
|
|
7691
7645
|
let stack;
|
|
@@ -7809,7 +7763,7 @@ async function runCreateApp(projectName, options) {
|
|
|
7809
7763
|
});
|
|
7810
7764
|
printSuccessBox(projectName, stack, dbDriver, backendPort);
|
|
7811
7765
|
} catch (err) {
|
|
7812
|
-
if (!cloneSucceeded &&
|
|
7766
|
+
if (!cloneSucceeded && existsSync7(projectDir)) {
|
|
7813
7767
|
rmSync2(projectDir, { recursive: true, force: true });
|
|
7814
7768
|
}
|
|
7815
7769
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -7869,7 +7823,7 @@ function stripAnsi(str) {
|
|
|
7869
7823
|
// src/index.ts
|
|
7870
7824
|
function createProgram() {
|
|
7871
7825
|
const program = new Command();
|
|
7872
|
-
program.name("brewnet").description("Your Home Server, Brewed Fresh").version("0.0.
|
|
7826
|
+
program.name("brewnet").description("Your Home Server, Brewed Fresh").version("0.0.2").showHelpAfterError('(run "brewnet --help" for usage information)');
|
|
7873
7827
|
registerInitCommand(program);
|
|
7874
7828
|
registerStatusCommand(program);
|
|
7875
7829
|
registerAddCommand(program);
|