@cccarv82/freya 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/web.js +51 -12
- package/package.json +1 -1
package/cli/web.js
CHANGED
|
@@ -6,11 +6,18 @@ const path = require('path');
|
|
|
6
6
|
const { spawn } = require('child_process');
|
|
7
7
|
|
|
8
8
|
function guessNpmCmd() {
|
|
9
|
-
|
|
9
|
+
// We'll execute via cmd.exe on Windows for reliability.
|
|
10
|
+
return process.platform === 'win32' ? 'npm' : 'npm';
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
function guessNpxCmd() {
|
|
13
|
-
|
|
14
|
+
// We'll execute via cmd.exe on Windows for reliability.
|
|
15
|
+
return process.platform === 'win32' ? 'npx' : 'npx';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function guessNpxYesFlag() {
|
|
19
|
+
// npx supports --yes/-y on modern npm; use -y for broad compatibility
|
|
20
|
+
return '-y';
|
|
14
21
|
}
|
|
15
22
|
|
|
16
23
|
function guessOpenCmd() {
|
|
@@ -62,6 +69,26 @@ function safeJson(res, code, obj) {
|
|
|
62
69
|
res.end(body);
|
|
63
70
|
}
|
|
64
71
|
|
|
72
|
+
function looksLikeFreyaWorkspace(dir) {
|
|
73
|
+
// minimal check: has scripts/validate-data.js and data/
|
|
74
|
+
return (
|
|
75
|
+
exists(path.join(dir, 'package.json')) &&
|
|
76
|
+
exists(path.join(dir, 'scripts')) &&
|
|
77
|
+
exists(path.join(dir, 'data'))
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function normalizeWorkspaceDir(inputDir) {
|
|
82
|
+
const d = path.resolve(process.cwd(), inputDir);
|
|
83
|
+
if (looksLikeFreyaWorkspace(d)) return d;
|
|
84
|
+
|
|
85
|
+
// Common case: user picked parent folder that contains ./freya
|
|
86
|
+
const child = path.join(d, 'freya');
|
|
87
|
+
if (looksLikeFreyaWorkspace(child)) return child;
|
|
88
|
+
|
|
89
|
+
return d;
|
|
90
|
+
}
|
|
91
|
+
|
|
65
92
|
function readBody(req) {
|
|
66
93
|
return new Promise((resolve, reject) => {
|
|
67
94
|
const chunks = [];
|
|
@@ -74,8 +101,15 @@ function readBody(req) {
|
|
|
74
101
|
function run(cmd, args, cwd) {
|
|
75
102
|
return new Promise((resolve) => {
|
|
76
103
|
let child;
|
|
104
|
+
|
|
77
105
|
try {
|
|
78
|
-
|
|
106
|
+
// On Windows, reliably execute CLI tools through cmd.exe.
|
|
107
|
+
if (process.platform === 'win32' && (cmd === 'npx' || cmd === 'npm')) {
|
|
108
|
+
const comspec = process.env.ComSpec || 'cmd.exe';
|
|
109
|
+
child = spawn(comspec, ['/d', '/s', '/c', cmd, ...args], { cwd, shell: false, env: process.env });
|
|
110
|
+
} else {
|
|
111
|
+
child = spawn(cmd, args, { cwd, shell: false, env: process.env });
|
|
112
|
+
}
|
|
79
113
|
} catch (e) {
|
|
80
114
|
return resolve({ code: 1, stdout: '', stderr: e.message || String(e) });
|
|
81
115
|
}
|
|
@@ -90,7 +124,7 @@ function run(cmd, args, cwd) {
|
|
|
90
124
|
stderr += d.toString();
|
|
91
125
|
});
|
|
92
126
|
|
|
93
|
-
// Prevent unhandled error event (e.g., ENOENT
|
|
127
|
+
// Prevent unhandled error event (e.g., ENOENT/EINVAL)
|
|
94
128
|
child.on('error', (e) => {
|
|
95
129
|
stderr += `\n${e.message || String(e)}`;
|
|
96
130
|
resolve({ code: 1, stdout, stderr });
|
|
@@ -1007,7 +1041,8 @@ async function cmdWeb({ port, dir, open, dev }) {
|
|
|
1007
1041
|
const raw = await readBody(req);
|
|
1008
1042
|
const payload = raw ? JSON.parse(raw) : {};
|
|
1009
1043
|
|
|
1010
|
-
const
|
|
1044
|
+
const requestedDir = payload.dir || dir || './freya';
|
|
1045
|
+
const workspaceDir = normalizeWorkspaceDir(requestedDir);
|
|
1011
1046
|
|
|
1012
1047
|
if (req.url === '/api/pick-dir') {
|
|
1013
1048
|
const picked = await pickDirectoryNative();
|
|
@@ -1016,27 +1051,31 @@ async function cmdWeb({ port, dir, open, dev }) {
|
|
|
1016
1051
|
|
|
1017
1052
|
if (req.url === '/api/init') {
|
|
1018
1053
|
const pkg = '@cccarv82/freya';
|
|
1019
|
-
const r = await run(guessNpxCmd(), [pkg, 'init', workspaceDir], process.cwd());
|
|
1020
|
-
|
|
1054
|
+
const r = await run(guessNpxCmd(), [guessNpxYesFlag(), pkg, 'init', workspaceDir], process.cwd());
|
|
1055
|
+
const output = (r.stdout + r.stderr).trim();
|
|
1056
|
+
return safeJson(res, r.code === 0 ? 200 : 400, r.code === 0 ? { output } : { error: output || 'init failed', output });
|
|
1021
1057
|
}
|
|
1022
1058
|
|
|
1023
1059
|
if (req.url === '/api/update') {
|
|
1024
1060
|
const pkg = '@cccarv82/freya';
|
|
1025
1061
|
fs.mkdirSync(workspaceDir, { recursive: true });
|
|
1026
|
-
const r = await run(guessNpxCmd(), [pkg, 'init', '--here'], workspaceDir);
|
|
1027
|
-
|
|
1062
|
+
const r = await run(guessNpxCmd(), [guessNpxYesFlag(), pkg, 'init', '--here'], workspaceDir);
|
|
1063
|
+
const output = (r.stdout + r.stderr).trim();
|
|
1064
|
+
return safeJson(res, r.code === 0 ? 200 : 400, r.code === 0 ? { output } : { error: output || 'update failed', output });
|
|
1028
1065
|
}
|
|
1029
1066
|
|
|
1030
1067
|
const npmCmd = guessNpmCmd();
|
|
1031
1068
|
|
|
1032
1069
|
if (req.url === '/api/health') {
|
|
1033
1070
|
const r = await run(npmCmd, ['run', 'health'], workspaceDir);
|
|
1034
|
-
|
|
1071
|
+
const output = (r.stdout + r.stderr).trim();
|
|
1072
|
+
return safeJson(res, r.code === 0 ? 200 : 400, r.code === 0 ? { output } : { error: output || 'health failed', output });
|
|
1035
1073
|
}
|
|
1036
1074
|
|
|
1037
1075
|
if (req.url === '/api/migrate') {
|
|
1038
1076
|
const r = await run(npmCmd, ['run', 'migrate'], workspaceDir);
|
|
1039
|
-
|
|
1077
|
+
const output = (r.stdout + r.stderr).trim();
|
|
1078
|
+
return safeJson(res, r.code === 0 ? 200 : 400, r.code === 0 ? { output } : { error: output || 'migrate failed', output });
|
|
1040
1079
|
}
|
|
1041
1080
|
|
|
1042
1081
|
if (req.url === '/api/report') {
|
|
@@ -1060,7 +1099,7 @@ async function cmdWeb({ port, dir, open, dev }) {
|
|
|
1060
1099
|
// Prefer showing the actual report content when available.
|
|
1061
1100
|
const output = reportText ? reportText : out;
|
|
1062
1101
|
|
|
1063
|
-
return safeJson(res, r.code === 0 ? 200 : 400, { output, reportPath, reportText });
|
|
1102
|
+
return safeJson(res, r.code === 0 ? 200 : 400, r.code === 0 ? { output, reportPath, reportText } : { error: output || 'report failed', output, reportPath, reportText });
|
|
1064
1103
|
}
|
|
1065
1104
|
|
|
1066
1105
|
if (req.url === '/api/publish') {
|