@buildepicshit/cli 0.0.7 → 0.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.
@@ -0,0 +1,51 @@
1
+ import { execSync } from "node:child_process";
2
+
3
+ /**
4
+ * Find and kill any process listening on the given port.
5
+ * Returns the PID of the first process killed, or null if the port was free.
6
+ */
7
+ export async function killProcessOnPort(
8
+ port: number,
9
+ ): Promise<number | null> {
10
+ let pids: number[];
11
+ try {
12
+ const output = execSync(`lsof -ti :${port}`, {
13
+ encoding: "utf8",
14
+ stdio: ["pipe", "pipe", "pipe"],
15
+ }).trim();
16
+ if (!output) return null;
17
+ pids = output
18
+ .split("\n")
19
+ .map((p) => Number.parseInt(p.trim(), 10))
20
+ .filter(Boolean);
21
+ } catch {
22
+ return null; // No process on that port
23
+ }
24
+
25
+ if (pids.length === 0) return null;
26
+
27
+ const first = pids[0];
28
+
29
+ // SIGTERM first
30
+ for (const pid of pids) {
31
+ try {
32
+ process.kill(pid, "SIGTERM");
33
+ } catch {
34
+ // Already exited
35
+ }
36
+ }
37
+
38
+ // Wait, then SIGKILL survivors
39
+ await new Promise((resolve) => setTimeout(resolve, 1000));
40
+
41
+ for (const pid of pids) {
42
+ try {
43
+ process.kill(pid, 0); // Check if still alive
44
+ process.kill(pid, "SIGKILL");
45
+ } catch {
46
+ // Already dead
47
+ }
48
+ }
49
+
50
+ return first;
51
+ }