@zoer7788/mcp-nexus-node 0.1.3 → 0.1.5
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.js +30 -4
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -90,6 +90,11 @@ function run(cmd, args, options = {}) {
|
|
|
90
90
|
return out.stdout.trim();
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
function runInteractive(cmd, args) {
|
|
94
|
+
const out = spawnSync(cmd, args, { stdio: "inherit" });
|
|
95
|
+
if (out.status !== 0) throw new Error(`${cmd} failed`);
|
|
96
|
+
}
|
|
97
|
+
|
|
93
98
|
function commandExists(cmd) {
|
|
94
99
|
return Boolean(commandPath(cmd));
|
|
95
100
|
}
|
|
@@ -147,16 +152,17 @@ function cloudflaredCommand() {
|
|
|
147
152
|
const local = join(binDir, "cloudflared");
|
|
148
153
|
if (existsSync(local)) return local;
|
|
149
154
|
ensureState();
|
|
150
|
-
console.log(
|
|
151
|
-
|
|
155
|
+
console.log(`Installing cloudflared to ${local}...`);
|
|
156
|
+
runInteractive("sh", ["-lc", `curl -L --fail -o ${quote(local)} ${quote(cloudflaredDownloadUrl())} && chmod +x ${quote(local)}`]);
|
|
152
157
|
return local;
|
|
153
158
|
}
|
|
154
159
|
|
|
155
160
|
function ensureCloudflareAuth() {
|
|
156
161
|
const certFile = join(home, ".cloudflared", "cert.pem");
|
|
157
162
|
if (existsSync(certFile)) return;
|
|
158
|
-
|
|
159
|
-
|
|
163
|
+
const cloudflared = cloudflaredCommand();
|
|
164
|
+
console.log("Cloudflare authorization required. Open the printed URL in your local browser.");
|
|
165
|
+
const out = spawnSync(cloudflared, ["tunnel", "login"], { stdio: "inherit" });
|
|
160
166
|
if (out.status !== 0) throw new Error("cloudflared tunnel login failed");
|
|
161
167
|
if (!existsSync(certFile)) throw new Error(`cloudflared login did not create ${certFile}`);
|
|
162
168
|
}
|
|
@@ -403,6 +409,25 @@ function patchProject(name, body) {
|
|
|
403
409
|
return { ...projectStatus(project), config: cfg, restart_required: true };
|
|
404
410
|
}
|
|
405
411
|
|
|
412
|
+
function renameProject(name, body) {
|
|
413
|
+
const newName = String(body.name || "").trim();
|
|
414
|
+
if (!newName) throw new Error("new name is required");
|
|
415
|
+
const items = projects();
|
|
416
|
+
const project = items.find((p) => p.name === name);
|
|
417
|
+
if (!project) throw new Error(`project not found: ${name}`);
|
|
418
|
+
if (items.some((p) => p.name === newName)) throw new Error(`project already exists: ${newName}`);
|
|
419
|
+
project.name = newName;
|
|
420
|
+
saveProjects(items);
|
|
421
|
+
for (const suffix of [".out", "-cloudflared.out"]) {
|
|
422
|
+
const oldPath = join(logDir, `${name}${suffix}`);
|
|
423
|
+
const newPath = join(logDir, `${newName}${suffix}`);
|
|
424
|
+
if (existsSync(oldPath) && !existsSync(newPath)) {
|
|
425
|
+
try { writeFileSync(newPath, readFileSync(oldPath)); } catch {}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
return projectStatus(project);
|
|
429
|
+
}
|
|
430
|
+
|
|
406
431
|
function deleteProject(name) {
|
|
407
432
|
stopProject(name);
|
|
408
433
|
saveProjects(projects().filter((p) => p.name !== name));
|
|
@@ -433,6 +458,7 @@ function serve() {
|
|
|
433
458
|
const name = decodeURIComponent(match[1]);
|
|
434
459
|
const action = match[2] || "";
|
|
435
460
|
if (req.method === "PATCH" && action === "config") return json(res, 200, patchProject(name, await readJson(req)));
|
|
461
|
+
if (req.method === "PATCH" && action === "name") return json(res, 200, renameProject(name, await readJson(req)));
|
|
436
462
|
if (req.method === "POST" && action === "start") return json(res, 200, startProject(name));
|
|
437
463
|
if (req.method === "POST" && action === "stop") return json(res, 200, stopProject(name));
|
|
438
464
|
if (req.method === "POST" && action === "restart") { stopProject(name); return json(res, 200, startProject(name)); }
|