portless 0.2.0 → 0.2.1
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.js +45 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -11,7 +11,7 @@ import chalk from "chalk";
|
|
|
11
11
|
import * as fs from "fs";
|
|
12
12
|
import * as path from "path";
|
|
13
13
|
import * as readline from "readline";
|
|
14
|
-
import { spawn, spawnSync } from "child_process";
|
|
14
|
+
import { execSync, spawn, spawnSync } from "child_process";
|
|
15
15
|
|
|
16
16
|
// src/cli-utils.ts
|
|
17
17
|
import * as net from "net";
|
|
@@ -85,6 +85,18 @@ function readProxyPort() {
|
|
|
85
85
|
return DEFAULT_PROXY_PORT;
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
+
function findPidOnPort(port) {
|
|
89
|
+
try {
|
|
90
|
+
const output = execSync(`lsof -ti tcp:${port} -sTCP:LISTEN`, {
|
|
91
|
+
encoding: "utf-8",
|
|
92
|
+
timeout: 5e3
|
|
93
|
+
});
|
|
94
|
+
const pid = parseInt(output.trim().split("\n")[0], 10);
|
|
95
|
+
return isNaN(pid) ? null : pid;
|
|
96
|
+
} catch {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
88
100
|
async function waitForProxy(proxyPort, maxAttempts = 20, intervalMs = 250) {
|
|
89
101
|
const port = proxyPort ?? readProxyPort();
|
|
90
102
|
for (let i = 0; i < maxAttempts; i++) {
|
|
@@ -199,11 +211,40 @@ function startProxyServer(proxyPort) {
|
|
|
199
211
|
}
|
|
200
212
|
async function stopProxy() {
|
|
201
213
|
const pidPath = store.pidPath;
|
|
214
|
+
const proxyPort = readProxyPort();
|
|
202
215
|
if (!fs.existsSync(pidPath)) {
|
|
203
|
-
|
|
216
|
+
if (await isProxyRunning(proxyPort)) {
|
|
217
|
+
console.log(chalk.yellow(`PID file is missing but port ${proxyPort} is still in use.`));
|
|
218
|
+
const pid = findPidOnPort(proxyPort);
|
|
219
|
+
if (pid !== null) {
|
|
220
|
+
try {
|
|
221
|
+
process.kill(pid, "SIGTERM");
|
|
222
|
+
try {
|
|
223
|
+
fs.unlinkSync(PROXY_PORT_PATH);
|
|
224
|
+
} catch {
|
|
225
|
+
}
|
|
226
|
+
console.log(chalk.green(`Killed process ${pid}. Proxy stopped.`));
|
|
227
|
+
} catch (err) {
|
|
228
|
+
if (isErrnoException(err) && err.code === "EPERM") {
|
|
229
|
+
console.error(chalk.red("Permission denied. The proxy runs as root."));
|
|
230
|
+
console.log(chalk.blue("Use: sudo portless proxy stop"));
|
|
231
|
+
} else {
|
|
232
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
233
|
+
console.error(chalk.red("Failed to stop proxy:"), message);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
} else if (process.getuid?.() !== 0) {
|
|
237
|
+
console.error(chalk.red("Permission denied. The proxy likely runs as root."));
|
|
238
|
+
console.log(chalk.blue("Use: sudo portless proxy stop"));
|
|
239
|
+
} else {
|
|
240
|
+
console.error(chalk.red(`Could not identify the process on port ${proxyPort}.`));
|
|
241
|
+
console.log(chalk.blue(`Try: sudo kill "$(lsof -ti tcp:${proxyPort})"`));
|
|
242
|
+
}
|
|
243
|
+
} else {
|
|
244
|
+
console.log(chalk.yellow("Proxy is not running."));
|
|
245
|
+
}
|
|
204
246
|
return;
|
|
205
247
|
}
|
|
206
|
-
const proxyPort = readProxyPort();
|
|
207
248
|
try {
|
|
208
249
|
const pid = parseInt(fs.readFileSync(pidPath, "utf-8"), 10);
|
|
209
250
|
if (isNaN(pid)) {
|
|
@@ -374,7 +415,7 @@ ${chalk.bold("Skip portless:")}
|
|
|
374
415
|
process.exit(0);
|
|
375
416
|
}
|
|
376
417
|
if (args[0] === "--version" || args[0] === "-v") {
|
|
377
|
-
console.log("0.2.
|
|
418
|
+
console.log("0.2.1");
|
|
378
419
|
process.exit(0);
|
|
379
420
|
}
|
|
380
421
|
if (args[0] === "list") {
|