deckide 3.5.2 → 3.5.4
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/bin/deckide.js +60 -20
- package/dist/routes/files.js +0 -9
- package/package.json +1 -1
package/bin/deckide.js
CHANGED
|
@@ -60,38 +60,79 @@ function getRunningPid() {
|
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
/**
|
|
63
|
+
/** Wait for a process to exit, returns true if it exited */
|
|
64
|
+
function waitForExit(pid, timeoutMs = 5000) {
|
|
65
|
+
const start = Date.now();
|
|
66
|
+
while (Date.now() - start < timeoutMs) {
|
|
67
|
+
try { process.kill(pid, 0); } catch { return true; }
|
|
68
|
+
execSync('sleep 0.2', { stdio: 'ignore' });
|
|
69
|
+
}
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Build curl auth flags from settings */
|
|
74
|
+
function getAuthFlags() {
|
|
75
|
+
const s = loadSettings();
|
|
76
|
+
if (s.basicAuthEnabled && s.basicAuthUser && s.basicAuthPassword) {
|
|
77
|
+
return `-u '${s.basicAuthUser}:${s.basicAuthPassword}'`;
|
|
78
|
+
}
|
|
79
|
+
return '';
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Try HTTP shutdown on a specific port */
|
|
83
|
+
function tryHttpShutdown(port) {
|
|
84
|
+
const auth = getAuthFlags();
|
|
85
|
+
try {
|
|
86
|
+
execSync(`curl -sf ${auth} -X POST http://localhost:${port}/api/shutdown -H "Content-Type: application/json" -d '{}'`, {
|
|
87
|
+
timeout: 5000, stdio: 'ignore',
|
|
88
|
+
});
|
|
89
|
+
return true;
|
|
90
|
+
} catch {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Stop server: try HTTP shutdown, SIGTERM, then SIGKILL as last resort */
|
|
64
96
|
function stopServer() {
|
|
65
97
|
const port = getPort();
|
|
98
|
+
const pid = getRunningPid();
|
|
99
|
+
|
|
66
100
|
// Try HTTP shutdown on configured port
|
|
67
|
-
if (isServerRunningOnPort(port)) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
});
|
|
72
|
-
try { fs.unlinkSync(pidFile); } catch {}
|
|
73
|
-
return true;
|
|
74
|
-
} catch {}
|
|
101
|
+
if (isServerRunningOnPort(port) && tryHttpShutdown(port)) {
|
|
102
|
+
if (pid) waitForExit(pid, 5000);
|
|
103
|
+
try { fs.unlinkSync(pidFile); } catch {}
|
|
104
|
+
return true;
|
|
75
105
|
}
|
|
106
|
+
|
|
76
107
|
// Try default port 8787 if different
|
|
77
|
-
if (port !== 8787 && isServerRunningOnPort(8787)) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
});
|
|
82
|
-
try { fs.unlinkSync(pidFile); } catch {}
|
|
83
|
-
return true;
|
|
84
|
-
} catch {}
|
|
108
|
+
if (port !== 8787 && isServerRunningOnPort(8787) && tryHttpShutdown(8787)) {
|
|
109
|
+
if (pid) waitForExit(pid, 5000);
|
|
110
|
+
try { fs.unlinkSync(pidFile); } catch {}
|
|
111
|
+
return true;
|
|
85
112
|
}
|
|
113
|
+
|
|
86
114
|
// Fall back to killing by PID
|
|
87
|
-
const pid = getRunningPid();
|
|
88
115
|
if (pid) {
|
|
89
116
|
try {
|
|
90
117
|
process.kill(pid, 'SIGTERM');
|
|
118
|
+
if (waitForExit(pid, 5000)) {
|
|
119
|
+
try { fs.unlinkSync(pidFile); } catch {}
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
// SIGKILL as last resort
|
|
123
|
+
process.kill(pid, 'SIGKILL');
|
|
124
|
+
waitForExit(pid, 2000);
|
|
91
125
|
try { fs.unlinkSync(pidFile); } catch {}
|
|
92
126
|
return true;
|
|
93
|
-
} catch {
|
|
127
|
+
} catch {
|
|
128
|
+
// Process already gone
|
|
129
|
+
try { fs.unlinkSync(pidFile); } catch {}
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
94
132
|
}
|
|
133
|
+
|
|
134
|
+
// No PID but clean up stale pid file
|
|
135
|
+
try { fs.unlinkSync(pidFile); } catch {}
|
|
95
136
|
return false;
|
|
96
137
|
}
|
|
97
138
|
|
|
@@ -413,7 +454,6 @@ const oldPid = getRunningPid();
|
|
|
413
454
|
if (oldPid) {
|
|
414
455
|
console.log('Stopping old server...');
|
|
415
456
|
stopServer();
|
|
416
|
-
await new Promise(r => setTimeout(r, 1000));
|
|
417
457
|
}
|
|
418
458
|
|
|
419
459
|
// ── Background mode (default) ──
|
package/dist/routes/files.js
CHANGED
|
@@ -44,15 +44,6 @@ export function createFileRouter(workspaces) {
|
|
|
44
44
|
const rootInput = c.req.query('path') || DEFAULT_ROOT;
|
|
45
45
|
const requestedPath = c.req.query('subpath') || '';
|
|
46
46
|
const rootPath = normalizeWorkspacePath(rootInput);
|
|
47
|
-
// When workspaces exist, allow browsing within workspaces and ancestor directories
|
|
48
|
-
if (workspaces.size > 0) {
|
|
49
|
-
const isAllowed = [...workspaces.values()].some(ws => rootPath === ws.path ||
|
|
50
|
-
rootPath.startsWith(ws.path + path.sep) ||
|
|
51
|
-
ws.path.startsWith(rootPath + path.sep));
|
|
52
|
-
if (!isAllowed) {
|
|
53
|
-
throw createHttpError('Path outside registered workspaces', 403);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
47
|
const target = await resolveSafePath(rootPath, requestedPath);
|
|
57
48
|
const stats = await fs.stat(target);
|
|
58
49
|
if (!stats.isDirectory()) {
|