blumenjs 0.1.5 → 0.1.6

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.
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Blumen — postinstall check
4
+ *
5
+ * Runs after `npm install -g blumenjs` to verify Go is available.
6
+ * If not, prints install instructions for the user's platform.
7
+ */
8
+
9
+ const { execSync } = require("child_process");
10
+ const os = require("os");
11
+
12
+ const c = {
13
+ reset: "\x1b[0m", bold: "\x1b[1m", dim: "\x1b[2m",
14
+ red: "\x1b[31m", green: "\x1b[32m", yellow: "\x1b[33m",
15
+ cyan: "\x1b[36m", magenta: "\x1b[35m",
16
+ };
17
+
18
+ function hasGo() {
19
+ try {
20
+ execSync("go version", { stdio: "pipe" });
21
+ return true;
22
+ } catch {
23
+ return false;
24
+ }
25
+ }
26
+
27
+ function getGoVersion() {
28
+ try {
29
+ const out = execSync("go version", { encoding: "utf-8" }).trim();
30
+ const match = out.match(/go(\d+\.\d+(\.\d+)?)/);
31
+ return match ? match[1] : out;
32
+ } catch {
33
+ return null;
34
+ }
35
+ }
36
+
37
+ console.log("");
38
+ console.log(` ${c.magenta}${c.bold}🌸 Blumen${c.reset} ${c.dim}installed successfully!${c.reset}`);
39
+ console.log(` ${c.dim}The React framework powered by Go${c.reset}`);
40
+ console.log("");
41
+
42
+ if (hasGo()) {
43
+ const ver = getGoVersion();
44
+ console.log(` ${c.green}✓${c.reset} Go ${c.bold}${ver}${c.reset} detected`);
45
+ console.log(` ${c.green}✓${c.reset} Ready to go! Run ${c.cyan}blumen create my-app${c.reset} to start.`);
46
+ } else {
47
+ console.log(` ${c.yellow}⚠${c.reset} ${c.bold}Go is not installed${c.reset}`);
48
+ console.log(` ${c.dim}Blumen uses Go for its high-performance server layer.${c.reset}`);
49
+ console.log("");
50
+
51
+ const platform = os.platform();
52
+
53
+ if (platform === "darwin") {
54
+ console.log(` ${c.bold}Install Go (macOS):${c.reset}`);
55
+ console.log(` ${c.cyan}brew install go${c.reset}`);
56
+ console.log(` ${c.dim}or download from https://go.dev/dl/${c.reset}`);
57
+ } else if (platform === "linux") {
58
+ console.log(` ${c.bold}Install Go (Linux):${c.reset}`);
59
+ console.log(` ${c.cyan}sudo apt install golang-go${c.reset} ${c.dim}(Debian/Ubuntu)${c.reset}`);
60
+ console.log(` ${c.cyan}sudo dnf install golang${c.reset} ${c.dim}(Fedora)${c.reset}`);
61
+ console.log(` ${c.dim}or download from https://go.dev/dl/${c.reset}`);
62
+ } else if (platform === "win32") {
63
+ console.log(` ${c.bold}Install Go (Windows):${c.reset}`);
64
+ console.log(` ${c.cyan}winget install GoLang.Go${c.reset}`);
65
+ console.log(` ${c.dim}or download from https://go.dev/dl/${c.reset}`);
66
+ } else {
67
+ console.log(` ${c.bold}Install Go:${c.reset} ${c.cyan}https://go.dev/dl/${c.reset}`);
68
+ }
69
+
70
+ console.log("");
71
+ console.log(` ${c.dim}After installing Go, run:${c.reset} ${c.cyan}blumen create my-app${c.reset}`);
72
+ }
73
+
74
+ console.log("");
@@ -1,11 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  // cli/commands/dev.ts
3
- import { spawn, execSync } from "child_process";
3
+ import { spawn, execSync as execSync2 } from "child_process";
4
4
 
5
5
  // cli/utils.ts
6
6
  import * as fs from "fs";
7
7
  import * as path from "path";
8
+ import * as os from "os";
8
9
  import { fileURLToPath } from "url";
10
+ import { execSync } from "child_process";
9
11
  var c = {
10
12
  reset: "\x1B[0m",
11
13
  bold: "\x1B[1m",
@@ -102,13 +104,111 @@ async function confirm(question, defaultYes = true) {
102
104
  });
103
105
  });
104
106
  }
107
+ function checkGoInstalled() {
108
+ try {
109
+ execSync("go version", { stdio: "pipe" });
110
+ return true;
111
+ } catch {
112
+ return false;
113
+ }
114
+ }
115
+ function getGoVersion() {
116
+ try {
117
+ const out = execSync("go version", { encoding: "utf-8" }).trim();
118
+ const match = out.match(/go(\d+\.\d+(\.\d+)?)/);
119
+ return match ? match[1] : out;
120
+ } catch {
121
+ return null;
122
+ }
123
+ }
124
+ async function ensureGo() {
125
+ if (checkGoInstalled()) {
126
+ const ver = getGoVersion();
127
+ log.success(`Go ${c.bold}${ver}${c.reset} detected`);
128
+ return true;
129
+ }
130
+ log.blank();
131
+ log.warn(`${c.bold}Go is not installed${c.reset}`);
132
+ log.info("Blumen uses Go for its high-performance HTTP server layer.");
133
+ log.blank();
134
+ const platform2 = os.platform();
135
+ if (platform2 === "darwin") {
136
+ let hasBrew = false;
137
+ try {
138
+ execSync("brew --version", { stdio: "pipe" });
139
+ hasBrew = true;
140
+ } catch {
141
+ }
142
+ if (hasBrew) {
143
+ const doInstall = await confirm("Install Go via Homebrew? (brew install go)");
144
+ if (doInstall) {
145
+ log.step("Installing Go via Homebrew...");
146
+ try {
147
+ execSync("brew install go", { stdio: "inherit" });
148
+ log.success("Go installed successfully!");
149
+ return true;
150
+ } catch {
151
+ log.error("Homebrew install failed. Please install manually.");
152
+ console.log(`
153
+ ${c.cyan}https://go.dev/dl/${c.reset}
154
+ `);
155
+ return false;
156
+ }
157
+ }
158
+ }
159
+ console.log(` ${c.bold}Install Go manually:${c.reset}`);
160
+ console.log(` ${c.cyan}brew install go${c.reset} ${c.dim}(if you install Homebrew first)${c.reset}`);
161
+ console.log(` ${c.dim}or download from${c.reset} ${c.cyan}https://go.dev/dl/${c.reset}`);
162
+ } else if (platform2 === "linux") {
163
+ let hasApt = false;
164
+ try {
165
+ execSync("apt --version", { stdio: "pipe" });
166
+ hasApt = true;
167
+ } catch {
168
+ }
169
+ if (hasApt) {
170
+ const doInstall = await confirm("Install Go via apt? (sudo apt install golang-go)");
171
+ if (doInstall) {
172
+ log.step("Installing Go via apt...");
173
+ try {
174
+ execSync("sudo apt update && sudo apt install -y golang-go", { stdio: "inherit" });
175
+ log.success("Go installed successfully!");
176
+ return true;
177
+ } catch {
178
+ log.error("apt install failed. Please install manually.");
179
+ console.log(`
180
+ ${c.cyan}https://go.dev/dl/${c.reset}
181
+ `);
182
+ return false;
183
+ }
184
+ }
185
+ }
186
+ console.log(` ${c.bold}Install Go:${c.reset}`);
187
+ console.log(` ${c.cyan}sudo apt install golang-go${c.reset} ${c.dim}(Debian/Ubuntu)${c.reset}`);
188
+ console.log(` ${c.cyan}sudo dnf install golang${c.reset} ${c.dim}(Fedora)${c.reset}`);
189
+ console.log(` ${c.dim}or download from${c.reset} ${c.cyan}https://go.dev/dl/${c.reset}`);
190
+ } else if (platform2 === "win32") {
191
+ console.log(` ${c.bold}Install Go (Windows):${c.reset}`);
192
+ console.log(` ${c.cyan}winget install GoLang.Go${c.reset}`);
193
+ console.log(` ${c.dim}or download from${c.reset} ${c.cyan}https://go.dev/dl/${c.reset}`);
194
+ } else {
195
+ console.log(` ${c.bold}Install Go:${c.reset} ${c.cyan}https://go.dev/dl/${c.reset}`);
196
+ }
197
+ log.blank();
198
+ log.info("After installing Go, restart your terminal and try again.");
199
+ return false;
200
+ }
105
201
 
106
202
  // cli/commands/dev.ts
107
203
  async function dev() {
108
204
  banner();
205
+ const goReady = await ensureGo();
206
+ if (!goReady) {
207
+ process.exit(1);
208
+ }
109
209
  log.step("Generating routes...");
110
210
  try {
111
- execSync("npx tsx scripts/generate-routes.ts", {
211
+ execSync2("npx tsx scripts/generate-routes.ts", {
112
212
  stdio: "pipe",
113
213
  cwd: process.cwd()
114
214
  });
@@ -220,7 +320,7 @@ async function dev() {
220
320
  }
221
321
 
222
322
  // cli/commands/build.ts
223
- import { execSync as execSync2 } from "child_process";
323
+ import { execSync as execSync3 } from "child_process";
224
324
  async function build() {
225
325
  banner();
226
326
  log.info("Creating production build...");
@@ -244,7 +344,7 @@ async function build() {
244
344
  const step = steps[i];
245
345
  log.step(`[${i + 1}/${steps.length}] ${step.label}...`);
246
346
  try {
247
- execSync2(step.cmd, { stdio: "inherit", cwd: process.cwd() });
347
+ execSync3(step.cmd, { stdio: "inherit", cwd: process.cwd() });
248
348
  log.success(step.label);
249
349
  } catch {
250
350
  log.error(`Failed: ${step.label}`);
@@ -356,7 +456,7 @@ async function start() {
356
456
  // cli/commands/create.ts
357
457
  import * as fs3 from "fs";
358
458
  import * as path2 from "path";
359
- import { execSync as execSync3 } from "child_process";
459
+ import { execSync as execSync4 } from "child_process";
360
460
  function getFrameworkRoot() {
361
461
  const cliEntry = fs3.realpathSync(process.argv[1]);
362
462
  const cliDir = path2.dirname(cliEntry);
@@ -693,6 +793,10 @@ function getTemplateFiles(projectName, template) {
693
793
  async function create(projectName) {
694
794
  banner();
695
795
  log.info("Create a new Blumen project\n");
796
+ const goReady = await ensureGo();
797
+ if (!goReady) {
798
+ process.exit(1);
799
+ }
696
800
  if (!projectName) {
697
801
  log.error("Please provide a project name.");
698
802
  console.log(
@@ -749,7 +853,7 @@ async function create(projectName) {
749
853
  bun: "bun install"
750
854
  };
751
855
  try {
752
- execSync3(installCmd[pkgManager], {
856
+ execSync4(installCmd[pkgManager], {
753
857
  cwd: projectDir,
754
858
  stdio: "inherit"
755
859
  });
@@ -771,7 +875,7 @@ async function create(projectName) {
771
875
  }
772
876
 
773
877
  // cli/commands/deploy.ts
774
- import { execSync as execSync4, spawnSync } from "child_process";
878
+ import { execSync as execSync5, spawnSync } from "child_process";
775
879
  import * as fs4 from "fs";
776
880
  import * as path3 from "path";
777
881
  var PLATFORMS = [
@@ -786,7 +890,7 @@ var PLATFORMS = [
786
890
  ];
787
891
  function hasCommand(cmd) {
788
892
  try {
789
- execSync4(`which ${cmd}`, { stdio: "pipe" });
893
+ execSync5(`which ${cmd}`, { stdio: "pipe" });
790
894
  return true;
791
895
  } catch {
792
896
  return false;
@@ -1,12 +1,14 @@
1
1
  // cli/commands/create.ts
2
2
  import * as fs2 from "fs";
3
3
  import * as path2 from "path";
4
- import { execSync } from "child_process";
4
+ import { execSync as execSync2 } from "child_process";
5
5
 
6
6
  // cli/utils.ts
7
7
  import * as fs from "fs";
8
8
  import * as path from "path";
9
+ import * as os from "os";
9
10
  import { fileURLToPath } from "url";
11
+ import { execSync } from "child_process";
10
12
  var c = {
11
13
  reset: "\x1B[0m",
12
14
  bold: "\x1B[1m",
@@ -85,6 +87,118 @@ async function select(question, options) {
85
87
  });
86
88
  });
87
89
  }
90
+ async function confirm(question, defaultYes = true) {
91
+ const readline = await import("readline");
92
+ const rl = readline.createInterface({
93
+ input: process.stdin,
94
+ output: process.stdout
95
+ });
96
+ const hint = defaultYes ? "Y/n" : "y/N";
97
+ return new Promise((resolve2) => {
98
+ rl.question(` ${c.bold}${question}${c.reset} ${c.dim}(${hint})${c.reset} `, (answer) => {
99
+ rl.close();
100
+ const a = answer.trim().toLowerCase();
101
+ if (a === "")
102
+ resolve2(defaultYes);
103
+ else
104
+ resolve2(a === "y" || a === "yes");
105
+ });
106
+ });
107
+ }
108
+ function checkGoInstalled() {
109
+ try {
110
+ execSync("go version", { stdio: "pipe" });
111
+ return true;
112
+ } catch {
113
+ return false;
114
+ }
115
+ }
116
+ function getGoVersion() {
117
+ try {
118
+ const out = execSync("go version", { encoding: "utf-8" }).trim();
119
+ const match = out.match(/go(\d+\.\d+(\.\d+)?)/);
120
+ return match ? match[1] : out;
121
+ } catch {
122
+ return null;
123
+ }
124
+ }
125
+ async function ensureGo() {
126
+ if (checkGoInstalled()) {
127
+ const ver = getGoVersion();
128
+ log.success(`Go ${c.bold}${ver}${c.reset} detected`);
129
+ return true;
130
+ }
131
+ log.blank();
132
+ log.warn(`${c.bold}Go is not installed${c.reset}`);
133
+ log.info("Blumen uses Go for its high-performance HTTP server layer.");
134
+ log.blank();
135
+ const platform2 = os.platform();
136
+ if (platform2 === "darwin") {
137
+ let hasBrew = false;
138
+ try {
139
+ execSync("brew --version", { stdio: "pipe" });
140
+ hasBrew = true;
141
+ } catch {
142
+ }
143
+ if (hasBrew) {
144
+ const doInstall = await confirm("Install Go via Homebrew? (brew install go)");
145
+ if (doInstall) {
146
+ log.step("Installing Go via Homebrew...");
147
+ try {
148
+ execSync("brew install go", { stdio: "inherit" });
149
+ log.success("Go installed successfully!");
150
+ return true;
151
+ } catch {
152
+ log.error("Homebrew install failed. Please install manually.");
153
+ console.log(`
154
+ ${c.cyan}https://go.dev/dl/${c.reset}
155
+ `);
156
+ return false;
157
+ }
158
+ }
159
+ }
160
+ console.log(` ${c.bold}Install Go manually:${c.reset}`);
161
+ console.log(` ${c.cyan}brew install go${c.reset} ${c.dim}(if you install Homebrew first)${c.reset}`);
162
+ console.log(` ${c.dim}or download from${c.reset} ${c.cyan}https://go.dev/dl/${c.reset}`);
163
+ } else if (platform2 === "linux") {
164
+ let hasApt = false;
165
+ try {
166
+ execSync("apt --version", { stdio: "pipe" });
167
+ hasApt = true;
168
+ } catch {
169
+ }
170
+ if (hasApt) {
171
+ const doInstall = await confirm("Install Go via apt? (sudo apt install golang-go)");
172
+ if (doInstall) {
173
+ log.step("Installing Go via apt...");
174
+ try {
175
+ execSync("sudo apt update && sudo apt install -y golang-go", { stdio: "inherit" });
176
+ log.success("Go installed successfully!");
177
+ return true;
178
+ } catch {
179
+ log.error("apt install failed. Please install manually.");
180
+ console.log(`
181
+ ${c.cyan}https://go.dev/dl/${c.reset}
182
+ `);
183
+ return false;
184
+ }
185
+ }
186
+ }
187
+ console.log(` ${c.bold}Install Go:${c.reset}`);
188
+ console.log(` ${c.cyan}sudo apt install golang-go${c.reset} ${c.dim}(Debian/Ubuntu)${c.reset}`);
189
+ console.log(` ${c.cyan}sudo dnf install golang${c.reset} ${c.dim}(Fedora)${c.reset}`);
190
+ console.log(` ${c.dim}or download from${c.reset} ${c.cyan}https://go.dev/dl/${c.reset}`);
191
+ } else if (platform2 === "win32") {
192
+ console.log(` ${c.bold}Install Go (Windows):${c.reset}`);
193
+ console.log(` ${c.cyan}winget install GoLang.Go${c.reset}`);
194
+ console.log(` ${c.dim}or download from${c.reset} ${c.cyan}https://go.dev/dl/${c.reset}`);
195
+ } else {
196
+ console.log(` ${c.bold}Install Go:${c.reset} ${c.cyan}https://go.dev/dl/${c.reset}`);
197
+ }
198
+ log.blank();
199
+ log.info("After installing Go, restart your terminal and try again.");
200
+ return false;
201
+ }
88
202
 
89
203
  // cli/commands/create.ts
90
204
  function getFrameworkRoot() {
@@ -423,6 +537,10 @@ function getTemplateFiles(projectName, template) {
423
537
  async function create(projectName) {
424
538
  banner();
425
539
  log.info("Create a new Blumen project\n");
540
+ const goReady = await ensureGo();
541
+ if (!goReady) {
542
+ process.exit(1);
543
+ }
426
544
  if (!projectName) {
427
545
  log.error("Please provide a project name.");
428
546
  console.log(
@@ -479,7 +597,7 @@ async function create(projectName) {
479
597
  bun: "bun install"
480
598
  };
481
599
  try {
482
- execSync(installCmd[pkgManager], {
600
+ execSync2(installCmd[pkgManager], {
483
601
  cwd: projectDir,
484
602
  stdio: "inherit"
485
603
  });
@@ -1,10 +1,12 @@
1
1
  // cli/commands/dev.ts
2
- import { spawn, execSync } from "child_process";
2
+ import { spawn, execSync as execSync2 } from "child_process";
3
3
 
4
4
  // cli/utils.ts
5
5
  import * as fs from "fs";
6
6
  import * as path from "path";
7
+ import * as os from "os";
7
8
  import { fileURLToPath } from "url";
9
+ import { execSync } from "child_process";
8
10
  var c = {
9
11
  reset: "\x1B[0m",
10
12
  bold: "\x1B[1m",
@@ -59,13 +61,129 @@ function banner() {
59
61
  function divider() {
60
62
  console.log(` ${c.dim}${"\u2500".repeat(48)}${c.reset}`);
61
63
  }
64
+ async function confirm(question, defaultYes = true) {
65
+ const readline = await import("readline");
66
+ const rl = readline.createInterface({
67
+ input: process.stdin,
68
+ output: process.stdout
69
+ });
70
+ const hint = defaultYes ? "Y/n" : "y/N";
71
+ return new Promise((resolve) => {
72
+ rl.question(` ${c.bold}${question}${c.reset} ${c.dim}(${hint})${c.reset} `, (answer) => {
73
+ rl.close();
74
+ const a = answer.trim().toLowerCase();
75
+ if (a === "")
76
+ resolve(defaultYes);
77
+ else
78
+ resolve(a === "y" || a === "yes");
79
+ });
80
+ });
81
+ }
82
+ function checkGoInstalled() {
83
+ try {
84
+ execSync("go version", { stdio: "pipe" });
85
+ return true;
86
+ } catch {
87
+ return false;
88
+ }
89
+ }
90
+ function getGoVersion() {
91
+ try {
92
+ const out = execSync("go version", { encoding: "utf-8" }).trim();
93
+ const match = out.match(/go(\d+\.\d+(\.\d+)?)/);
94
+ return match ? match[1] : out;
95
+ } catch {
96
+ return null;
97
+ }
98
+ }
99
+ async function ensureGo() {
100
+ if (checkGoInstalled()) {
101
+ const ver = getGoVersion();
102
+ log.success(`Go ${c.bold}${ver}${c.reset} detected`);
103
+ return true;
104
+ }
105
+ log.blank();
106
+ log.warn(`${c.bold}Go is not installed${c.reset}`);
107
+ log.info("Blumen uses Go for its high-performance HTTP server layer.");
108
+ log.blank();
109
+ const platform2 = os.platform();
110
+ if (platform2 === "darwin") {
111
+ let hasBrew = false;
112
+ try {
113
+ execSync("brew --version", { stdio: "pipe" });
114
+ hasBrew = true;
115
+ } catch {
116
+ }
117
+ if (hasBrew) {
118
+ const doInstall = await confirm("Install Go via Homebrew? (brew install go)");
119
+ if (doInstall) {
120
+ log.step("Installing Go via Homebrew...");
121
+ try {
122
+ execSync("brew install go", { stdio: "inherit" });
123
+ log.success("Go installed successfully!");
124
+ return true;
125
+ } catch {
126
+ log.error("Homebrew install failed. Please install manually.");
127
+ console.log(`
128
+ ${c.cyan}https://go.dev/dl/${c.reset}
129
+ `);
130
+ return false;
131
+ }
132
+ }
133
+ }
134
+ console.log(` ${c.bold}Install Go manually:${c.reset}`);
135
+ console.log(` ${c.cyan}brew install go${c.reset} ${c.dim}(if you install Homebrew first)${c.reset}`);
136
+ console.log(` ${c.dim}or download from${c.reset} ${c.cyan}https://go.dev/dl/${c.reset}`);
137
+ } else if (platform2 === "linux") {
138
+ let hasApt = false;
139
+ try {
140
+ execSync("apt --version", { stdio: "pipe" });
141
+ hasApt = true;
142
+ } catch {
143
+ }
144
+ if (hasApt) {
145
+ const doInstall = await confirm("Install Go via apt? (sudo apt install golang-go)");
146
+ if (doInstall) {
147
+ log.step("Installing Go via apt...");
148
+ try {
149
+ execSync("sudo apt update && sudo apt install -y golang-go", { stdio: "inherit" });
150
+ log.success("Go installed successfully!");
151
+ return true;
152
+ } catch {
153
+ log.error("apt install failed. Please install manually.");
154
+ console.log(`
155
+ ${c.cyan}https://go.dev/dl/${c.reset}
156
+ `);
157
+ return false;
158
+ }
159
+ }
160
+ }
161
+ console.log(` ${c.bold}Install Go:${c.reset}`);
162
+ console.log(` ${c.cyan}sudo apt install golang-go${c.reset} ${c.dim}(Debian/Ubuntu)${c.reset}`);
163
+ console.log(` ${c.cyan}sudo dnf install golang${c.reset} ${c.dim}(Fedora)${c.reset}`);
164
+ console.log(` ${c.dim}or download from${c.reset} ${c.cyan}https://go.dev/dl/${c.reset}`);
165
+ } else if (platform2 === "win32") {
166
+ console.log(` ${c.bold}Install Go (Windows):${c.reset}`);
167
+ console.log(` ${c.cyan}winget install GoLang.Go${c.reset}`);
168
+ console.log(` ${c.dim}or download from${c.reset} ${c.cyan}https://go.dev/dl/${c.reset}`);
169
+ } else {
170
+ console.log(` ${c.bold}Install Go:${c.reset} ${c.cyan}https://go.dev/dl/${c.reset}`);
171
+ }
172
+ log.blank();
173
+ log.info("After installing Go, restart your terminal and try again.");
174
+ return false;
175
+ }
62
176
 
63
177
  // cli/commands/dev.ts
64
178
  async function dev() {
65
179
  banner();
180
+ const goReady = await ensureGo();
181
+ if (!goReady) {
182
+ process.exit(1);
183
+ }
66
184
  log.step("Generating routes...");
67
185
  try {
68
- execSync("npx tsx scripts/generate-routes.ts", {
186
+ execSync2("npx tsx scripts/generate-routes.ts", {
69
187
  stdio: "pipe",
70
188
  cwd: process.cwd()
71
189
  });
package/dist/cli/utils.js CHANGED
@@ -1,7 +1,9 @@
1
1
  // cli/utils.ts
2
2
  import * as fs from "fs";
3
3
  import * as path from "path";
4
+ import * as os from "os";
4
5
  import { fileURLToPath } from "url";
6
+ import { execSync } from "child_process";
5
7
  var c = {
6
8
  reset: "\x1B[0m",
7
9
  bold: "\x1B[1m",
@@ -98,11 +100,108 @@ async function confirm(question, defaultYes = true) {
98
100
  });
99
101
  });
100
102
  }
103
+ function checkGoInstalled() {
104
+ try {
105
+ execSync("go version", { stdio: "pipe" });
106
+ return true;
107
+ } catch {
108
+ return false;
109
+ }
110
+ }
111
+ function getGoVersion() {
112
+ try {
113
+ const out = execSync("go version", { encoding: "utf-8" }).trim();
114
+ const match = out.match(/go(\d+\.\d+(\.\d+)?)/);
115
+ return match ? match[1] : out;
116
+ } catch {
117
+ return null;
118
+ }
119
+ }
120
+ async function ensureGo() {
121
+ if (checkGoInstalled()) {
122
+ const ver = getGoVersion();
123
+ log.success(`Go ${c.bold}${ver}${c.reset} detected`);
124
+ return true;
125
+ }
126
+ log.blank();
127
+ log.warn(`${c.bold}Go is not installed${c.reset}`);
128
+ log.info("Blumen uses Go for its high-performance HTTP server layer.");
129
+ log.blank();
130
+ const platform2 = os.platform();
131
+ if (platform2 === "darwin") {
132
+ let hasBrew = false;
133
+ try {
134
+ execSync("brew --version", { stdio: "pipe" });
135
+ hasBrew = true;
136
+ } catch {
137
+ }
138
+ if (hasBrew) {
139
+ const doInstall = await confirm("Install Go via Homebrew? (brew install go)");
140
+ if (doInstall) {
141
+ log.step("Installing Go via Homebrew...");
142
+ try {
143
+ execSync("brew install go", { stdio: "inherit" });
144
+ log.success("Go installed successfully!");
145
+ return true;
146
+ } catch {
147
+ log.error("Homebrew install failed. Please install manually.");
148
+ console.log(`
149
+ ${c.cyan}https://go.dev/dl/${c.reset}
150
+ `);
151
+ return false;
152
+ }
153
+ }
154
+ }
155
+ console.log(` ${c.bold}Install Go manually:${c.reset}`);
156
+ console.log(` ${c.cyan}brew install go${c.reset} ${c.dim}(if you install Homebrew first)${c.reset}`);
157
+ console.log(` ${c.dim}or download from${c.reset} ${c.cyan}https://go.dev/dl/${c.reset}`);
158
+ } else if (platform2 === "linux") {
159
+ let hasApt = false;
160
+ try {
161
+ execSync("apt --version", { stdio: "pipe" });
162
+ hasApt = true;
163
+ } catch {
164
+ }
165
+ if (hasApt) {
166
+ const doInstall = await confirm("Install Go via apt? (sudo apt install golang-go)");
167
+ if (doInstall) {
168
+ log.step("Installing Go via apt...");
169
+ try {
170
+ execSync("sudo apt update && sudo apt install -y golang-go", { stdio: "inherit" });
171
+ log.success("Go installed successfully!");
172
+ return true;
173
+ } catch {
174
+ log.error("apt install failed. Please install manually.");
175
+ console.log(`
176
+ ${c.cyan}https://go.dev/dl/${c.reset}
177
+ `);
178
+ return false;
179
+ }
180
+ }
181
+ }
182
+ console.log(` ${c.bold}Install Go:${c.reset}`);
183
+ console.log(` ${c.cyan}sudo apt install golang-go${c.reset} ${c.dim}(Debian/Ubuntu)${c.reset}`);
184
+ console.log(` ${c.cyan}sudo dnf install golang${c.reset} ${c.dim}(Fedora)${c.reset}`);
185
+ console.log(` ${c.dim}or download from${c.reset} ${c.cyan}https://go.dev/dl/${c.reset}`);
186
+ } else if (platform2 === "win32") {
187
+ console.log(` ${c.bold}Install Go (Windows):${c.reset}`);
188
+ console.log(` ${c.cyan}winget install GoLang.Go${c.reset}`);
189
+ console.log(` ${c.dim}or download from${c.reset} ${c.cyan}https://go.dev/dl/${c.reset}`);
190
+ } else {
191
+ console.log(` ${c.bold}Install Go:${c.reset} ${c.cyan}https://go.dev/dl/${c.reset}`);
192
+ }
193
+ log.blank();
194
+ log.info("After installing Go, restart your terminal and try again.");
195
+ return false;
196
+ }
101
197
  export {
102
198
  banner,
103
199
  c,
200
+ checkGoInstalled,
104
201
  confirm,
105
202
  divider,
203
+ ensureGo,
204
+ getGoVersion,
106
205
  getVersion,
107
206
  log,
108
207
  select