blumenjs 0.1.1 → 0.1.3
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/cli/blumen.js +51 -46
- package/dist/cli/commands/build.js +24 -1
- package/dist/cli/commands/create.js +45 -33
- package/dist/cli/commands/dev.js +26 -9
- package/dist/cli/commands/start.js +26 -3
- package/dist/cli/utils.js +25 -1
- package/dist/templates/app/pages/BlumenStarter.tsx +8 -10
- package/package.json +1 -1
package/dist/cli/blumen.js
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
import { spawn, execSync } from "child_process";
|
|
4
4
|
|
|
5
5
|
// cli/utils.ts
|
|
6
|
+
import * as fs from "fs";
|
|
7
|
+
import * as path from "path";
|
|
8
|
+
import { fileURLToPath } from "url";
|
|
6
9
|
var c = {
|
|
7
10
|
reset: "\x1B[0m",
|
|
8
11
|
bold: "\x1B[1m",
|
|
@@ -24,10 +27,30 @@ var log = {
|
|
|
24
27
|
step: (msg) => console.log(` ${c.dim}\u2192${c.reset} ${msg}`),
|
|
25
28
|
blank: () => console.log("")
|
|
26
29
|
};
|
|
30
|
+
function getVersion() {
|
|
31
|
+
try {
|
|
32
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
33
|
+
let dir = path.dirname(thisFile);
|
|
34
|
+
for (let i = 0; i < 5; i++) {
|
|
35
|
+
const pkgFile = path.join(dir, "package.json");
|
|
36
|
+
if (fs.existsSync(pkgFile)) {
|
|
37
|
+
const pkg = JSON.parse(fs.readFileSync(pkgFile, "utf-8"));
|
|
38
|
+
if (pkg.name === "blumenjs" || pkg.name === "go-react-ssr") {
|
|
39
|
+
return pkg.version;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
dir = path.dirname(dir);
|
|
43
|
+
}
|
|
44
|
+
return "0.0.0";
|
|
45
|
+
} catch {
|
|
46
|
+
return "0.0.0";
|
|
47
|
+
}
|
|
48
|
+
}
|
|
27
49
|
function banner() {
|
|
50
|
+
const version = getVersion();
|
|
28
51
|
console.log("");
|
|
29
52
|
console.log(
|
|
30
|
-
` ${c.magenta}${c.bold}\u{1F338} Blumen${c.reset} ${c.dim}
|
|
53
|
+
` ${c.magenta}${c.bold}\u{1F338} Blumen${c.reset} ${c.dim}v${version}${c.reset}`
|
|
31
54
|
);
|
|
32
55
|
console.log(
|
|
33
56
|
` ${c.dim}The React framework powered by Go${c.reset}`
|
|
@@ -147,17 +170,11 @@ async function dev() {
|
|
|
147
170
|
log.success(`${c.bold}Ready!${c.reset} All services are running.`);
|
|
148
171
|
log.blank();
|
|
149
172
|
console.log(
|
|
150
|
-
` ${c.dim}\u279C${c.reset} ${c.bold}App${c.reset}:
|
|
151
|
-
);
|
|
152
|
-
console.log(
|
|
153
|
-
` ${c.dim}\u279C${c.reset} ${c.bold}SSR${c.reset}: ${c.dim}http://localhost:4000${c.reset}`
|
|
154
|
-
);
|
|
155
|
-
console.log(
|
|
156
|
-
` ${c.dim}\u279C${c.reset} ${c.bold}HMR${c.reset}: ${c.dim}http://localhost:3100${c.reset}`
|
|
173
|
+
` ${c.dim}\u279C${c.reset} ${c.bold}App${c.reset}: ${c.cyan}http://localhost:3000${c.reset}`
|
|
157
174
|
);
|
|
158
175
|
log.blank();
|
|
159
176
|
console.log(
|
|
160
|
-
` ${c.dim}Press ${c.bold}Ctrl+C${c.reset}${c.dim} to stop
|
|
177
|
+
` ${c.dim}Press ${c.bold}Ctrl+C${c.reset}${c.dim} to stop.${c.reset}`
|
|
161
178
|
);
|
|
162
179
|
log.blank();
|
|
163
180
|
divider();
|
|
@@ -231,10 +248,10 @@ async function build() {
|
|
|
231
248
|
|
|
232
249
|
// cli/commands/start.ts
|
|
233
250
|
import { spawn as spawn2 } from "child_process";
|
|
234
|
-
import * as
|
|
251
|
+
import * as fs2 from "fs";
|
|
235
252
|
async function start() {
|
|
236
253
|
banner();
|
|
237
|
-
if (!
|
|
254
|
+
if (!fs2.existsSync("dist/ssr-server.js")) {
|
|
238
255
|
log.error("Production build not found.");
|
|
239
256
|
log.info(
|
|
240
257
|
`Run ${c.bold}blumen build${c.reset} first to create a production build.`
|
|
@@ -319,23 +336,23 @@ async function start() {
|
|
|
319
336
|
}
|
|
320
337
|
|
|
321
338
|
// cli/commands/create.ts
|
|
322
|
-
import * as
|
|
323
|
-
import * as
|
|
339
|
+
import * as fs3 from "fs";
|
|
340
|
+
import * as path2 from "path";
|
|
324
341
|
import { execSync as execSync3 } from "child_process";
|
|
325
342
|
function getFrameworkRoot() {
|
|
326
|
-
const cliEntry =
|
|
327
|
-
const cliDir =
|
|
328
|
-
return
|
|
343
|
+
const cliEntry = fs3.realpathSync(process.argv[1]);
|
|
344
|
+
const cliDir = path2.dirname(cliEntry);
|
|
345
|
+
return path2.resolve(cliDir, "..");
|
|
329
346
|
}
|
|
330
347
|
function readProjectFile(relativePath) {
|
|
331
348
|
const root = getFrameworkRoot();
|
|
332
|
-
const bundledPath =
|
|
333
|
-
if (
|
|
334
|
-
return
|
|
349
|
+
const bundledPath = path2.join(root, "templates", relativePath);
|
|
350
|
+
if (fs3.existsSync(bundledPath)) {
|
|
351
|
+
return fs3.readFileSync(bundledPath, "utf-8");
|
|
335
352
|
}
|
|
336
|
-
const sourcePath =
|
|
337
|
-
if (
|
|
338
|
-
return
|
|
353
|
+
const sourcePath = path2.join(root, relativePath);
|
|
354
|
+
if (fs3.existsSync(sourcePath)) {
|
|
355
|
+
return fs3.readFileSync(sourcePath, "utf-8");
|
|
339
356
|
}
|
|
340
357
|
throw new Error(`Template file not found: ${relativePath}`);
|
|
341
358
|
}
|
|
@@ -348,14 +365,9 @@ function pkgJson(name) {
|
|
|
348
365
|
type: "module",
|
|
349
366
|
scripts: {
|
|
350
367
|
routes: "tsx scripts/generate-routes.ts",
|
|
351
|
-
dev:
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
"dev:go": "go run go-server/main.go",
|
|
355
|
-
build: "npm run routes && npm run build:client && npm run build:ssr",
|
|
356
|
-
"build:client": "webpack --mode production",
|
|
357
|
-
"build:ssr": "esbuild node-ssr/server.ts --bundle --platform=node --format=esm --outfile=dist/ssr-server.js --external:react --external:react-dom",
|
|
358
|
-
start: "node dist/ssr-server.js",
|
|
368
|
+
dev: "blumen dev",
|
|
369
|
+
build: "blumen build",
|
|
370
|
+
start: "blumen start",
|
|
359
371
|
clean: "rm -rf dist static/js/bundle.js"
|
|
360
372
|
},
|
|
361
373
|
dependencies: {
|
|
@@ -372,8 +384,8 @@ function pkgJson(name) {
|
|
|
372
384
|
"@types/node": "^20.10.0",
|
|
373
385
|
"@types/react": "^18.2.0",
|
|
374
386
|
"@types/react-dom": "^18.2.0",
|
|
387
|
+
blumenjs: "^0.1.1",
|
|
375
388
|
"babel-loader": "^9.2.1",
|
|
376
|
-
concurrently: "^8.2.2",
|
|
377
389
|
esbuild: "^0.19.0",
|
|
378
390
|
"react-refresh": "^0.14.2",
|
|
379
391
|
"ts-loader": "^9.5.1",
|
|
@@ -544,9 +556,9 @@ export function Link({ href, children, onClick, target, ...rest }: LinkProps) {
|
|
|
544
556
|
export default Link;
|
|
545
557
|
`;
|
|
546
558
|
function writeFile(base, relPath, content) {
|
|
547
|
-
const fullPath =
|
|
548
|
-
|
|
549
|
-
|
|
559
|
+
const fullPath = path2.join(base, relPath);
|
|
560
|
+
fs3.mkdirSync(path2.dirname(fullPath), { recursive: true });
|
|
561
|
+
fs3.writeFileSync(fullPath, content, "utf-8");
|
|
550
562
|
}
|
|
551
563
|
function getTemplateFiles(projectName) {
|
|
552
564
|
return [
|
|
@@ -583,8 +595,8 @@ async function create(projectName) {
|
|
|
583
595
|
);
|
|
584
596
|
process.exit(1);
|
|
585
597
|
}
|
|
586
|
-
const projectDir =
|
|
587
|
-
if (
|
|
598
|
+
const projectDir = path2.resolve(process.cwd(), projectName);
|
|
599
|
+
if (fs3.existsSync(projectDir)) {
|
|
588
600
|
log.error(`Directory ${c.bold}${projectName}${c.reset} already exists.`);
|
|
589
601
|
process.exit(1);
|
|
590
602
|
}
|
|
@@ -626,20 +638,13 @@ async function create(projectName) {
|
|
|
626
638
|
log.blank();
|
|
627
639
|
log.success(`${c.bold}Project created!${c.reset}`);
|
|
628
640
|
log.blank();
|
|
629
|
-
const runCmd = {
|
|
630
|
-
npm: "npm run dev",
|
|
631
|
-
yarn: "yarn dev",
|
|
632
|
-
pnpm: "pnpm dev",
|
|
633
|
-
bun: "bun dev"
|
|
634
|
-
};
|
|
635
641
|
console.log(` ${c.dim}Next steps:${c.reset}`);
|
|
636
642
|
console.log(` cd ${projectName}`);
|
|
637
|
-
console.log(`
|
|
643
|
+
console.log(` blumen dev`);
|
|
638
644
|
log.blank();
|
|
639
645
|
}
|
|
640
646
|
|
|
641
647
|
// cli/blumen.ts
|
|
642
|
-
var VERSION = "0.1.0";
|
|
643
648
|
async function main() {
|
|
644
649
|
const command = process.argv[2];
|
|
645
650
|
if (!command || command === "--help" || command === "-h") {
|
|
@@ -664,8 +669,8 @@ async function main() {
|
|
|
664
669
|
console.log("");
|
|
665
670
|
return;
|
|
666
671
|
}
|
|
667
|
-
if (command === "--version" || command === "-v") {
|
|
668
|
-
console.log(`blumen v${
|
|
672
|
+
if (command === "--version" || command === "-v" || command === "version") {
|
|
673
|
+
console.log(`blumen v${getVersion()}`);
|
|
669
674
|
return;
|
|
670
675
|
}
|
|
671
676
|
switch (command) {
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
import { execSync } from "child_process";
|
|
3
3
|
|
|
4
4
|
// cli/utils.ts
|
|
5
|
+
import * as fs from "fs";
|
|
6
|
+
import * as path from "path";
|
|
7
|
+
import { fileURLToPath } from "url";
|
|
5
8
|
var c = {
|
|
6
9
|
reset: "\x1B[0m",
|
|
7
10
|
bold: "\x1B[1m",
|
|
@@ -23,10 +26,30 @@ var log = {
|
|
|
23
26
|
step: (msg) => console.log(` ${c.dim}\u2192${c.reset} ${msg}`),
|
|
24
27
|
blank: () => console.log("")
|
|
25
28
|
};
|
|
29
|
+
function getVersion() {
|
|
30
|
+
try {
|
|
31
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
32
|
+
let dir = path.dirname(thisFile);
|
|
33
|
+
for (let i = 0; i < 5; i++) {
|
|
34
|
+
const pkgFile = path.join(dir, "package.json");
|
|
35
|
+
if (fs.existsSync(pkgFile)) {
|
|
36
|
+
const pkg = JSON.parse(fs.readFileSync(pkgFile, "utf-8"));
|
|
37
|
+
if (pkg.name === "blumenjs" || pkg.name === "go-react-ssr") {
|
|
38
|
+
return pkg.version;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
dir = path.dirname(dir);
|
|
42
|
+
}
|
|
43
|
+
return "0.0.0";
|
|
44
|
+
} catch {
|
|
45
|
+
return "0.0.0";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
26
48
|
function banner() {
|
|
49
|
+
const version = getVersion();
|
|
27
50
|
console.log("");
|
|
28
51
|
console.log(
|
|
29
|
-
` ${c.magenta}${c.bold}\u{1F338} Blumen${c.reset} ${c.dim}
|
|
52
|
+
` ${c.magenta}${c.bold}\u{1F338} Blumen${c.reset} ${c.dim}v${version}${c.reset}`
|
|
30
53
|
);
|
|
31
54
|
console.log(
|
|
32
55
|
` ${c.dim}The React framework powered by Go${c.reset}`
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
// cli/commands/create.ts
|
|
2
|
-
import * as
|
|
3
|
-
import * as
|
|
2
|
+
import * as fs2 from "fs";
|
|
3
|
+
import * as path2 from "path";
|
|
4
4
|
import { execSync } from "child_process";
|
|
5
5
|
|
|
6
6
|
// cli/utils.ts
|
|
7
|
+
import * as fs from "fs";
|
|
8
|
+
import * as path from "path";
|
|
9
|
+
import { fileURLToPath } from "url";
|
|
7
10
|
var c = {
|
|
8
11
|
reset: "\x1B[0m",
|
|
9
12
|
bold: "\x1B[1m",
|
|
@@ -25,10 +28,30 @@ var log = {
|
|
|
25
28
|
step: (msg) => console.log(` ${c.dim}\u2192${c.reset} ${msg}`),
|
|
26
29
|
blank: () => console.log("")
|
|
27
30
|
};
|
|
31
|
+
function getVersion() {
|
|
32
|
+
try {
|
|
33
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
34
|
+
let dir = path.dirname(thisFile);
|
|
35
|
+
for (let i = 0; i < 5; i++) {
|
|
36
|
+
const pkgFile = path.join(dir, "package.json");
|
|
37
|
+
if (fs.existsSync(pkgFile)) {
|
|
38
|
+
const pkg = JSON.parse(fs.readFileSync(pkgFile, "utf-8"));
|
|
39
|
+
if (pkg.name === "blumenjs" || pkg.name === "go-react-ssr") {
|
|
40
|
+
return pkg.version;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
dir = path.dirname(dir);
|
|
44
|
+
}
|
|
45
|
+
return "0.0.0";
|
|
46
|
+
} catch {
|
|
47
|
+
return "0.0.0";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
28
50
|
function banner() {
|
|
51
|
+
const version = getVersion();
|
|
29
52
|
console.log("");
|
|
30
53
|
console.log(
|
|
31
|
-
` ${c.magenta}${c.bold}\u{1F338} Blumen${c.reset} ${c.dim}
|
|
54
|
+
` ${c.magenta}${c.bold}\u{1F338} Blumen${c.reset} ${c.dim}v${version}${c.reset}`
|
|
32
55
|
);
|
|
33
56
|
console.log(
|
|
34
57
|
` ${c.dim}The React framework powered by Go${c.reset}`
|
|
@@ -65,19 +88,19 @@ async function select(question, options) {
|
|
|
65
88
|
|
|
66
89
|
// cli/commands/create.ts
|
|
67
90
|
function getFrameworkRoot() {
|
|
68
|
-
const cliEntry =
|
|
69
|
-
const cliDir =
|
|
70
|
-
return
|
|
91
|
+
const cliEntry = fs2.realpathSync(process.argv[1]);
|
|
92
|
+
const cliDir = path2.dirname(cliEntry);
|
|
93
|
+
return path2.resolve(cliDir, "..");
|
|
71
94
|
}
|
|
72
95
|
function readProjectFile(relativePath) {
|
|
73
96
|
const root = getFrameworkRoot();
|
|
74
|
-
const bundledPath =
|
|
75
|
-
if (
|
|
76
|
-
return
|
|
97
|
+
const bundledPath = path2.join(root, "templates", relativePath);
|
|
98
|
+
if (fs2.existsSync(bundledPath)) {
|
|
99
|
+
return fs2.readFileSync(bundledPath, "utf-8");
|
|
77
100
|
}
|
|
78
|
-
const sourcePath =
|
|
79
|
-
if (
|
|
80
|
-
return
|
|
101
|
+
const sourcePath = path2.join(root, relativePath);
|
|
102
|
+
if (fs2.existsSync(sourcePath)) {
|
|
103
|
+
return fs2.readFileSync(sourcePath, "utf-8");
|
|
81
104
|
}
|
|
82
105
|
throw new Error(`Template file not found: ${relativePath}`);
|
|
83
106
|
}
|
|
@@ -90,14 +113,9 @@ function pkgJson(name) {
|
|
|
90
113
|
type: "module",
|
|
91
114
|
scripts: {
|
|
92
115
|
routes: "tsx scripts/generate-routes.ts",
|
|
93
|
-
dev:
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
"dev:go": "go run go-server/main.go",
|
|
97
|
-
build: "npm run routes && npm run build:client && npm run build:ssr",
|
|
98
|
-
"build:client": "webpack --mode production",
|
|
99
|
-
"build:ssr": "esbuild node-ssr/server.ts --bundle --platform=node --format=esm --outfile=dist/ssr-server.js --external:react --external:react-dom",
|
|
100
|
-
start: "node dist/ssr-server.js",
|
|
116
|
+
dev: "blumen dev",
|
|
117
|
+
build: "blumen build",
|
|
118
|
+
start: "blumen start",
|
|
101
119
|
clean: "rm -rf dist static/js/bundle.js"
|
|
102
120
|
},
|
|
103
121
|
dependencies: {
|
|
@@ -114,8 +132,8 @@ function pkgJson(name) {
|
|
|
114
132
|
"@types/node": "^20.10.0",
|
|
115
133
|
"@types/react": "^18.2.0",
|
|
116
134
|
"@types/react-dom": "^18.2.0",
|
|
135
|
+
blumenjs: "^0.1.1",
|
|
117
136
|
"babel-loader": "^9.2.1",
|
|
118
|
-
concurrently: "^8.2.2",
|
|
119
137
|
esbuild: "^0.19.0",
|
|
120
138
|
"react-refresh": "^0.14.2",
|
|
121
139
|
"ts-loader": "^9.5.1",
|
|
@@ -286,9 +304,9 @@ export function Link({ href, children, onClick, target, ...rest }: LinkProps) {
|
|
|
286
304
|
export default Link;
|
|
287
305
|
`;
|
|
288
306
|
function writeFile(base, relPath, content) {
|
|
289
|
-
const fullPath =
|
|
290
|
-
|
|
291
|
-
|
|
307
|
+
const fullPath = path2.join(base, relPath);
|
|
308
|
+
fs2.mkdirSync(path2.dirname(fullPath), { recursive: true });
|
|
309
|
+
fs2.writeFileSync(fullPath, content, "utf-8");
|
|
292
310
|
}
|
|
293
311
|
function getTemplateFiles(projectName) {
|
|
294
312
|
return [
|
|
@@ -325,8 +343,8 @@ async function create(projectName) {
|
|
|
325
343
|
);
|
|
326
344
|
process.exit(1);
|
|
327
345
|
}
|
|
328
|
-
const projectDir =
|
|
329
|
-
if (
|
|
346
|
+
const projectDir = path2.resolve(process.cwd(), projectName);
|
|
347
|
+
if (fs2.existsSync(projectDir)) {
|
|
330
348
|
log.error(`Directory ${c.bold}${projectName}${c.reset} already exists.`);
|
|
331
349
|
process.exit(1);
|
|
332
350
|
}
|
|
@@ -368,15 +386,9 @@ async function create(projectName) {
|
|
|
368
386
|
log.blank();
|
|
369
387
|
log.success(`${c.bold}Project created!${c.reset}`);
|
|
370
388
|
log.blank();
|
|
371
|
-
const runCmd = {
|
|
372
|
-
npm: "npm run dev",
|
|
373
|
-
yarn: "yarn dev",
|
|
374
|
-
pnpm: "pnpm dev",
|
|
375
|
-
bun: "bun dev"
|
|
376
|
-
};
|
|
377
389
|
console.log(` ${c.dim}Next steps:${c.reset}`);
|
|
378
390
|
console.log(` cd ${projectName}`);
|
|
379
|
-
console.log(`
|
|
391
|
+
console.log(` blumen dev`);
|
|
380
392
|
log.blank();
|
|
381
393
|
}
|
|
382
394
|
export {
|
package/dist/cli/commands/dev.js
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
import { spawn, execSync } from "child_process";
|
|
3
3
|
|
|
4
4
|
// cli/utils.ts
|
|
5
|
+
import * as fs from "fs";
|
|
6
|
+
import * as path from "path";
|
|
7
|
+
import { fileURLToPath } from "url";
|
|
5
8
|
var c = {
|
|
6
9
|
reset: "\x1B[0m",
|
|
7
10
|
bold: "\x1B[1m",
|
|
@@ -23,10 +26,30 @@ var log = {
|
|
|
23
26
|
step: (msg) => console.log(` ${c.dim}\u2192${c.reset} ${msg}`),
|
|
24
27
|
blank: () => console.log("")
|
|
25
28
|
};
|
|
29
|
+
function getVersion() {
|
|
30
|
+
try {
|
|
31
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
32
|
+
let dir = path.dirname(thisFile);
|
|
33
|
+
for (let i = 0; i < 5; i++) {
|
|
34
|
+
const pkgFile = path.join(dir, "package.json");
|
|
35
|
+
if (fs.existsSync(pkgFile)) {
|
|
36
|
+
const pkg = JSON.parse(fs.readFileSync(pkgFile, "utf-8"));
|
|
37
|
+
if (pkg.name === "blumenjs" || pkg.name === "go-react-ssr") {
|
|
38
|
+
return pkg.version;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
dir = path.dirname(dir);
|
|
42
|
+
}
|
|
43
|
+
return "0.0.0";
|
|
44
|
+
} catch {
|
|
45
|
+
return "0.0.0";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
26
48
|
function banner() {
|
|
49
|
+
const version = getVersion();
|
|
27
50
|
console.log("");
|
|
28
51
|
console.log(
|
|
29
|
-
` ${c.magenta}${c.bold}\u{1F338} Blumen${c.reset} ${c.dim}
|
|
52
|
+
` ${c.magenta}${c.bold}\u{1F338} Blumen${c.reset} ${c.dim}v${version}${c.reset}`
|
|
30
53
|
);
|
|
31
54
|
console.log(
|
|
32
55
|
` ${c.dim}The React framework powered by Go${c.reset}`
|
|
@@ -122,17 +145,11 @@ async function dev() {
|
|
|
122
145
|
log.success(`${c.bold}Ready!${c.reset} All services are running.`);
|
|
123
146
|
log.blank();
|
|
124
147
|
console.log(
|
|
125
|
-
` ${c.dim}\u279C${c.reset} ${c.bold}App${c.reset}:
|
|
126
|
-
);
|
|
127
|
-
console.log(
|
|
128
|
-
` ${c.dim}\u279C${c.reset} ${c.bold}SSR${c.reset}: ${c.dim}http://localhost:4000${c.reset}`
|
|
129
|
-
);
|
|
130
|
-
console.log(
|
|
131
|
-
` ${c.dim}\u279C${c.reset} ${c.bold}HMR${c.reset}: ${c.dim}http://localhost:3100${c.reset}`
|
|
148
|
+
` ${c.dim}\u279C${c.reset} ${c.bold}App${c.reset}: ${c.cyan}http://localhost:3000${c.reset}`
|
|
132
149
|
);
|
|
133
150
|
log.blank();
|
|
134
151
|
console.log(
|
|
135
|
-
` ${c.dim}Press ${c.bold}Ctrl+C${c.reset}${c.dim} to stop
|
|
152
|
+
` ${c.dim}Press ${c.bold}Ctrl+C${c.reset}${c.dim} to stop.${c.reset}`
|
|
136
153
|
);
|
|
137
154
|
log.blank();
|
|
138
155
|
divider();
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
// cli/commands/start.ts
|
|
2
2
|
import { spawn } from "child_process";
|
|
3
|
-
import * as
|
|
3
|
+
import * as fs2 from "fs";
|
|
4
4
|
|
|
5
5
|
// cli/utils.ts
|
|
6
|
+
import * as fs from "fs";
|
|
7
|
+
import * as path from "path";
|
|
8
|
+
import { fileURLToPath } from "url";
|
|
6
9
|
var c = {
|
|
7
10
|
reset: "\x1B[0m",
|
|
8
11
|
bold: "\x1B[1m",
|
|
@@ -24,10 +27,30 @@ var log = {
|
|
|
24
27
|
step: (msg) => console.log(` ${c.dim}\u2192${c.reset} ${msg}`),
|
|
25
28
|
blank: () => console.log("")
|
|
26
29
|
};
|
|
30
|
+
function getVersion() {
|
|
31
|
+
try {
|
|
32
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
33
|
+
let dir = path.dirname(thisFile);
|
|
34
|
+
for (let i = 0; i < 5; i++) {
|
|
35
|
+
const pkgFile = path.join(dir, "package.json");
|
|
36
|
+
if (fs.existsSync(pkgFile)) {
|
|
37
|
+
const pkg = JSON.parse(fs.readFileSync(pkgFile, "utf-8"));
|
|
38
|
+
if (pkg.name === "blumenjs" || pkg.name === "go-react-ssr") {
|
|
39
|
+
return pkg.version;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
dir = path.dirname(dir);
|
|
43
|
+
}
|
|
44
|
+
return "0.0.0";
|
|
45
|
+
} catch {
|
|
46
|
+
return "0.0.0";
|
|
47
|
+
}
|
|
48
|
+
}
|
|
27
49
|
function banner() {
|
|
50
|
+
const version = getVersion();
|
|
28
51
|
console.log("");
|
|
29
52
|
console.log(
|
|
30
|
-
` ${c.magenta}${c.bold}\u{1F338} Blumen${c.reset} ${c.dim}
|
|
53
|
+
` ${c.magenta}${c.bold}\u{1F338} Blumen${c.reset} ${c.dim}v${version}${c.reset}`
|
|
31
54
|
);
|
|
32
55
|
console.log(
|
|
33
56
|
` ${c.dim}The React framework powered by Go${c.reset}`
|
|
@@ -41,7 +64,7 @@ function divider() {
|
|
|
41
64
|
// cli/commands/start.ts
|
|
42
65
|
async function start() {
|
|
43
66
|
banner();
|
|
44
|
-
if (!
|
|
67
|
+
if (!fs2.existsSync("dist/ssr-server.js")) {
|
|
45
68
|
log.error("Production build not found.");
|
|
46
69
|
log.info(
|
|
47
70
|
`Run ${c.bold}blumen build${c.reset} first to create a production build.`
|
package/dist/cli/utils.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
// cli/utils.ts
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
2
5
|
var c = {
|
|
3
6
|
reset: "\x1B[0m",
|
|
4
7
|
bold: "\x1B[1m",
|
|
@@ -20,10 +23,30 @@ var log = {
|
|
|
20
23
|
step: (msg) => console.log(` ${c.dim}\u2192${c.reset} ${msg}`),
|
|
21
24
|
blank: () => console.log("")
|
|
22
25
|
};
|
|
26
|
+
function getVersion() {
|
|
27
|
+
try {
|
|
28
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
29
|
+
let dir = path.dirname(thisFile);
|
|
30
|
+
for (let i = 0; i < 5; i++) {
|
|
31
|
+
const pkgFile = path.join(dir, "package.json");
|
|
32
|
+
if (fs.existsSync(pkgFile)) {
|
|
33
|
+
const pkg = JSON.parse(fs.readFileSync(pkgFile, "utf-8"));
|
|
34
|
+
if (pkg.name === "blumenjs" || pkg.name === "go-react-ssr") {
|
|
35
|
+
return pkg.version;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
dir = path.dirname(dir);
|
|
39
|
+
}
|
|
40
|
+
return "0.0.0";
|
|
41
|
+
} catch {
|
|
42
|
+
return "0.0.0";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
23
45
|
function banner() {
|
|
46
|
+
const version = getVersion();
|
|
24
47
|
console.log("");
|
|
25
48
|
console.log(
|
|
26
|
-
` ${c.magenta}${c.bold}\u{1F338} Blumen${c.reset} ${c.dim}
|
|
49
|
+
` ${c.magenta}${c.bold}\u{1F338} Blumen${c.reset} ${c.dim}v${version}${c.reset}`
|
|
27
50
|
);
|
|
28
51
|
console.log(
|
|
29
52
|
` ${c.dim}The React framework powered by Go${c.reset}`
|
|
@@ -80,6 +103,7 @@ export {
|
|
|
80
103
|
c,
|
|
81
104
|
confirm,
|
|
82
105
|
divider,
|
|
106
|
+
getVersion,
|
|
83
107
|
log,
|
|
84
108
|
select
|
|
85
109
|
};
|
|
@@ -7,7 +7,7 @@ interface HomeProps {
|
|
|
7
7
|
|
|
8
8
|
const HomePage: React.FC<HomeProps> = () => {
|
|
9
9
|
return (
|
|
10
|
-
|
|
10
|
+
<div className="blumen-home">
|
|
11
11
|
<style
|
|
12
12
|
dangerouslySetInnerHTML={{
|
|
13
13
|
__html: `
|
|
@@ -305,8 +305,7 @@ const HomePage: React.FC<HomeProps> = () => {
|
|
|
305
305
|
`,
|
|
306
306
|
}}
|
|
307
307
|
/>
|
|
308
|
-
|
|
309
|
-
{/* Background effects */}
|
|
308
|
+
{/* Background effects */}
|
|
310
309
|
<div className="blumen-bg" />
|
|
311
310
|
<div className="blumen-orb blumen-orb-1" />
|
|
312
311
|
<div className="blumen-orb blumen-orb-2" />
|
|
@@ -330,10 +329,10 @@ const HomePage: React.FC<HomeProps> = () => {
|
|
|
330
329
|
|
|
331
330
|
<div className="blumen-cta-row">
|
|
332
331
|
<button className="blumen-btn-primary">
|
|
333
|
-
|
|
332
|
+
→ Read the Docs
|
|
334
333
|
</button>
|
|
335
334
|
<button className="blumen-btn-secondary">
|
|
336
|
-
|
|
335
|
+
◆ Quick Start
|
|
337
336
|
</button>
|
|
338
337
|
</div>
|
|
339
338
|
|
|
@@ -348,7 +347,7 @@ const HomePage: React.FC<HomeProps> = () => {
|
|
|
348
347
|
{/* Feature cards */}
|
|
349
348
|
<div className="blumen-features">
|
|
350
349
|
<div className="blumen-feature">
|
|
351
|
-
<div className="blumen-feature-icon"
|
|
350
|
+
<div className="blumen-feature-icon">⬡</div>
|
|
352
351
|
<h3>Go-Powered SSR</h3>
|
|
353
352
|
<p>
|
|
354
353
|
Your server runs on Go — blazing fast data
|
|
@@ -356,7 +355,7 @@ const HomePage: React.FC<HomeProps> = () => {
|
|
|
356
355
|
</p>
|
|
357
356
|
</div>
|
|
358
357
|
<div className="blumen-feature">
|
|
359
|
-
<div className="blumen-feature-icon"
|
|
358
|
+
<div className="blumen-feature-icon">◈</div>
|
|
360
359
|
<h3>React Fast Refresh</h3>
|
|
361
360
|
<p>
|
|
362
361
|
Edit a component, see it update instantly.
|
|
@@ -364,7 +363,7 @@ const HomePage: React.FC<HomeProps> = () => {
|
|
|
364
363
|
</p>
|
|
365
364
|
</div>
|
|
366
365
|
<div className="blumen-feature">
|
|
367
|
-
<div className="blumen-feature-icon"
|
|
366
|
+
<div className="blumen-feature-icon">⬢</div>
|
|
368
367
|
<h3>File-Based Routing</h3>
|
|
369
368
|
<p>
|
|
370
369
|
Drop a file in{" "}
|
|
@@ -390,8 +389,7 @@ const HomePage: React.FC<HomeProps> = () => {
|
|
|
390
389
|
</p>
|
|
391
390
|
</div>
|
|
392
391
|
</div>
|
|
393
|
-
|
|
394
|
-
</>
|
|
392
|
+
</div>
|
|
395
393
|
);
|
|
396
394
|
};
|
|
397
395
|
|