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.
- package/cli/postinstall.cjs +74 -0
- package/dist/cli/blumen.js +112 -8
- package/dist/cli/commands/create.js +120 -2
- package/dist/cli/commands/dev.js +120 -2
- package/dist/cli/utils.js +99 -0
- package/dist/templates/app/pages/templates/BlumenDashboard.tsx +305 -507
- package/package.json +3 -1
|
@@ -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("");
|
package/dist/cli/blumen.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
600
|
+
execSync2(installCmd[pkgManager], {
|
|
483
601
|
cwd: projectDir,
|
|
484
602
|
stdio: "inherit"
|
|
485
603
|
});
|
package/dist/cli/commands/dev.js
CHANGED
|
@@ -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
|
-
|
|
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
|