@superdangerous/app-framework 4.9.0
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/LICENSE +21 -0
- package/README.md +652 -0
- package/dist/api/logsRouter.d.ts +20 -0
- package/dist/api/logsRouter.d.ts.map +1 -0
- package/dist/api/logsRouter.js +515 -0
- package/dist/api/logsRouter.js.map +1 -0
- package/dist/cli/dev-server.d.ts +7 -0
- package/dist/cli/dev-server.d.ts.map +1 -0
- package/dist/cli/dev-server.js +640 -0
- package/dist/cli/dev-server.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +26 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/StandardServer.d.ts +129 -0
- package/dist/core/StandardServer.d.ts.map +1 -0
- package/dist/core/StandardServer.js +453 -0
- package/dist/core/StandardServer.js.map +1 -0
- package/dist/core/apiResponse.d.ts +69 -0
- package/dist/core/apiResponse.d.ts.map +1 -0
- package/dist/core/apiResponse.js +127 -0
- package/dist/core/apiResponse.js.map +1 -0
- package/dist/core/healthCheck.d.ts +160 -0
- package/dist/core/healthCheck.d.ts.map +1 -0
- package/dist/core/healthCheck.js +398 -0
- package/dist/core/healthCheck.js.map +1 -0
- package/dist/core/index.d.ts +40 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +40 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/logger.d.ts +117 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +826 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/portUtils.d.ts +71 -0
- package/dist/core/portUtils.d.ts.map +1 -0
- package/dist/core/portUtils.js +240 -0
- package/dist/core/portUtils.js.map +1 -0
- package/dist/core/storageService.d.ts +119 -0
- package/dist/core/storageService.d.ts.map +1 -0
- package/dist/core/storageService.js +405 -0
- package/dist/core/storageService.js.map +1 -0
- package/dist/desktop/bundler.d.ts +40 -0
- package/dist/desktop/bundler.d.ts.map +1 -0
- package/dist/desktop/bundler.js +176 -0
- package/dist/desktop/bundler.js.map +1 -0
- package/dist/desktop/index.d.ts +25 -0
- package/dist/desktop/index.d.ts.map +1 -0
- package/dist/desktop/index.js +15 -0
- package/dist/desktop/index.js.map +1 -0
- package/dist/desktop/native-modules.d.ts +66 -0
- package/dist/desktop/native-modules.d.ts.map +1 -0
- package/dist/desktop/native-modules.js +200 -0
- package/dist/desktop/native-modules.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/logging/LogCategories.d.ts +87 -0
- package/dist/logging/LogCategories.d.ts.map +1 -0
- package/dist/logging/LogCategories.js +205 -0
- package/dist/logging/LogCategories.js.map +1 -0
- package/dist/middleware/aiErrorHandler.d.ts +31 -0
- package/dist/middleware/aiErrorHandler.d.ts.map +1 -0
- package/dist/middleware/aiErrorHandler.js +181 -0
- package/dist/middleware/aiErrorHandler.js.map +1 -0
- package/dist/middleware/auth.d.ts +101 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +230 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/cors.d.ts +56 -0
- package/dist/middleware/cors.d.ts.map +1 -0
- package/dist/middleware/cors.js +123 -0
- package/dist/middleware/cors.js.map +1 -0
- package/dist/middleware/errorHandler.d.ts +13 -0
- package/dist/middleware/errorHandler.d.ts.map +1 -0
- package/dist/middleware/errorHandler.js +85 -0
- package/dist/middleware/errorHandler.js.map +1 -0
- package/dist/middleware/fileUpload.d.ts +62 -0
- package/dist/middleware/fileUpload.d.ts.map +1 -0
- package/dist/middleware/fileUpload.js +175 -0
- package/dist/middleware/fileUpload.js.map +1 -0
- package/dist/middleware/health.d.ts +48 -0
- package/dist/middleware/health.d.ts.map +1 -0
- package/dist/middleware/health.js +143 -0
- package/dist/middleware/health.js.map +1 -0
- package/dist/middleware/index.d.ts +20 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +18 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/openapi.d.ts +64 -0
- package/dist/middleware/openapi.d.ts.map +1 -0
- package/dist/middleware/openapi.js +258 -0
- package/dist/middleware/openapi.js.map +1 -0
- package/dist/middleware/requestLogging.d.ts +22 -0
- package/dist/middleware/requestLogging.d.ts.map +1 -0
- package/dist/middleware/requestLogging.js +61 -0
- package/dist/middleware/requestLogging.js.map +1 -0
- package/dist/middleware/session.d.ts +84 -0
- package/dist/middleware/session.d.ts.map +1 -0
- package/dist/middleware/session.js +189 -0
- package/dist/middleware/session.js.map +1 -0
- package/dist/middleware/validation.d.ts +1337 -0
- package/dist/middleware/validation.d.ts.map +1 -0
- package/dist/middleware/validation.js +483 -0
- package/dist/middleware/validation.js.map +1 -0
- package/dist/services/aiService.d.ts +180 -0
- package/dist/services/aiService.d.ts.map +1 -0
- package/dist/services/aiService.js +547 -0
- package/dist/services/aiService.js.map +1 -0
- package/dist/services/conversationStorage.d.ts +38 -0
- package/dist/services/conversationStorage.d.ts.map +1 -0
- package/dist/services/conversationStorage.js +158 -0
- package/dist/services/conversationStorage.js.map +1 -0
- package/dist/services/crossPlatformBuffer.d.ts +84 -0
- package/dist/services/crossPlatformBuffer.d.ts.map +1 -0
- package/dist/services/crossPlatformBuffer.js +246 -0
- package/dist/services/crossPlatformBuffer.js.map +1 -0
- package/dist/services/index.d.ts +17 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +18 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/networkService.d.ts +81 -0
- package/dist/services/networkService.d.ts.map +1 -0
- package/dist/services/networkService.js +268 -0
- package/dist/services/networkService.js.map +1 -0
- package/dist/services/queueService.d.ts +112 -0
- package/dist/services/queueService.d.ts.map +1 -0
- package/dist/services/queueService.js +338 -0
- package/dist/services/queueService.js.map +1 -0
- package/dist/services/settingsService.d.ts +135 -0
- package/dist/services/settingsService.d.ts.map +1 -0
- package/dist/services/settingsService.js +425 -0
- package/dist/services/settingsService.js.map +1 -0
- package/dist/services/systemMonitor.d.ts +208 -0
- package/dist/services/systemMonitor.d.ts.map +1 -0
- package/dist/services/systemMonitor.js +693 -0
- package/dist/services/systemMonitor.js.map +1 -0
- package/dist/services/updateService.d.ts +78 -0
- package/dist/services/updateService.d.ts.map +1 -0
- package/dist/services/updateService.js +252 -0
- package/dist/services/updateService.js.map +1 -0
- package/dist/services/websocketEvents.d.ts +372 -0
- package/dist/services/websocketEvents.d.ts.map +1 -0
- package/dist/services/websocketEvents.js +338 -0
- package/dist/services/websocketEvents.js.map +1 -0
- package/dist/services/websocketServer.d.ts +80 -0
- package/dist/services/websocketServer.d.ts.map +1 -0
- package/dist/services/websocketServer.js +299 -0
- package/dist/services/websocketServer.js.map +1 -0
- package/dist/settings/SettingsSchema.d.ts +151 -0
- package/dist/settings/SettingsSchema.d.ts.map +1 -0
- package/dist/settings/SettingsSchema.js +424 -0
- package/dist/settings/SettingsSchema.js.map +1 -0
- package/dist/testing/TestServer.d.ts +69 -0
- package/dist/testing/TestServer.d.ts.map +1 -0
- package/dist/testing/TestServer.js +250 -0
- package/dist/testing/TestServer.js.map +1 -0
- package/dist/types/index.d.ts +137 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/appPaths.d.ts +74 -0
- package/dist/utils/appPaths.d.ts.map +1 -0
- package/dist/utils/appPaths.js +162 -0
- package/dist/utils/appPaths.js.map +1 -0
- package/dist/utils/fs-utils.d.ts +50 -0
- package/dist/utils/fs-utils.d.ts.map +1 -0
- package/dist/utils/fs-utils.js +114 -0
- package/dist/utils/fs-utils.js.map +1 -0
- package/dist/utils/index.d.ts +12 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +10 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/standardConfig.d.ts +61 -0
- package/dist/utils/standardConfig.d.ts.map +1 -0
- package/dist/utils/standardConfig.js +109 -0
- package/dist/utils/standardConfig.js.map +1 -0
- package/dist/utils/startupBanner.d.ts +34 -0
- package/dist/utils/startupBanner.d.ts.map +1 -0
- package/dist/utils/startupBanner.js +169 -0
- package/dist/utils/startupBanner.js.map +1 -0
- package/dist/utils/startupLogger.d.ts +45 -0
- package/dist/utils/startupLogger.d.ts.map +1 -0
- package/dist/utils/startupLogger.js +200 -0
- package/dist/utils/startupLogger.js.map +1 -0
- package/package.json +151 -0
- package/src/api/logsRouter.ts +600 -0
- package/src/cli/dev-server.ts +803 -0
- package/src/cli/index.ts +31 -0
- package/src/core/StandardServer.ts +587 -0
- package/src/core/apiResponse.ts +202 -0
- package/src/core/healthCheck.ts +565 -0
- package/src/core/index.ts +80 -0
- package/src/core/logger.ts +1092 -0
- package/src/core/portUtils.ts +319 -0
- package/src/core/storageService.ts +595 -0
- package/src/desktop/bundler.ts +271 -0
- package/src/desktop/index.ts +18 -0
- package/src/desktop/native-modules.ts +289 -0
- package/src/index.ts +142 -0
- package/src/logging/LogCategories.ts +302 -0
- package/src/middleware/aiErrorHandler.ts +278 -0
- package/src/middleware/auth.ts +329 -0
- package/src/middleware/cors.ts +187 -0
- package/src/middleware/errorHandler.ts +103 -0
- package/src/middleware/fileUpload.ts +252 -0
- package/src/middleware/health.ts +206 -0
- package/src/middleware/index.ts +71 -0
- package/src/middleware/openapi.ts +305 -0
- package/src/middleware/requestLogging.ts +92 -0
- package/src/middleware/session.ts +238 -0
- package/src/middleware/validation.ts +603 -0
- package/src/services/aiService.ts +789 -0
- package/src/services/conversationStorage.ts +232 -0
- package/src/services/crossPlatformBuffer.ts +341 -0
- package/src/services/index.ts +47 -0
- package/src/services/networkService.ts +351 -0
- package/src/services/queueService.ts +446 -0
- package/src/services/settingsService.ts +549 -0
- package/src/services/systemMonitor.ts +936 -0
- package/src/services/updateService.ts +334 -0
- package/src/services/websocketEvents.ts +409 -0
- package/src/services/websocketServer.ts +394 -0
- package/src/settings/SettingsSchema.ts +664 -0
- package/src/testing/TestServer.ts +312 -0
- package/src/types/index.ts +154 -0
- package/src/utils/appPaths.ts +196 -0
- package/src/utils/fs-utils.ts +130 -0
- package/src/utils/index.ts +15 -0
- package/src/utils/standardConfig.ts +178 -0
- package/src/utils/startupBanner.ts +287 -0
- package/src/utils/startupLogger.ts +268 -0
- package/ui/dist/index.d.mts +1221 -0
- package/ui/dist/index.d.ts +1221 -0
- package/ui/dist/index.js +73 -0
- package/ui/dist/index.js.map +1 -0
- package/ui/dist/index.mjs +73 -0
- package/ui/dist/index.mjs.map +1 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port utilities for checking and managing port conflicts
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { exec, execSync } from "child_process";
|
|
6
|
+
import { promisify } from "util";
|
|
7
|
+
import * as net from "net";
|
|
8
|
+
|
|
9
|
+
const execAsync = promisify(exec);
|
|
10
|
+
|
|
11
|
+
export interface ProcessInfo {
|
|
12
|
+
pid: number;
|
|
13
|
+
command: string;
|
|
14
|
+
port: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface PortStatus {
|
|
18
|
+
port: number;
|
|
19
|
+
available: boolean;
|
|
20
|
+
process: ProcessInfo | null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface PortClearResult {
|
|
24
|
+
cleared: boolean;
|
|
25
|
+
port: number;
|
|
26
|
+
error?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface PortStatusResult {
|
|
30
|
+
hasConflicts: boolean;
|
|
31
|
+
message: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Check if a port is available
|
|
36
|
+
*/
|
|
37
|
+
export async function isPortAvailable(port: number): Promise<boolean> {
|
|
38
|
+
return new Promise((resolve) => {
|
|
39
|
+
const server = net.createServer();
|
|
40
|
+
|
|
41
|
+
server.once("error", (err: any) => {
|
|
42
|
+
if (err.code === "EADDRINUSE") {
|
|
43
|
+
resolve(false);
|
|
44
|
+
} else {
|
|
45
|
+
resolve(false);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
server.once("listening", () => {
|
|
50
|
+
server.close();
|
|
51
|
+
resolve(true);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
server.listen(port, "0.0.0.0");
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Get process info for a port
|
|
60
|
+
*/
|
|
61
|
+
export async function getProcessOnPort(
|
|
62
|
+
port: number,
|
|
63
|
+
): Promise<ProcessInfo | null> {
|
|
64
|
+
try {
|
|
65
|
+
// Try lsof first (macOS/Linux)
|
|
66
|
+
const { stdout } = await execAsync(
|
|
67
|
+
`lsof -nP -iTCP:${port} -sTCP:LISTEN -t 2>/dev/null || true`,
|
|
68
|
+
);
|
|
69
|
+
const pids = stdout
|
|
70
|
+
.split(/\r?\n/)
|
|
71
|
+
.map((s) => s.trim())
|
|
72
|
+
.filter(Boolean);
|
|
73
|
+
|
|
74
|
+
for (const pid of pids) {
|
|
75
|
+
// Verify PID is still alive
|
|
76
|
+
const { stdout: alive } = await execAsync(
|
|
77
|
+
`ps -p ${pid} -o pid= 2>/dev/null || true`,
|
|
78
|
+
);
|
|
79
|
+
if (!alive.trim()) continue;
|
|
80
|
+
|
|
81
|
+
// Get process details
|
|
82
|
+
const { stdout: psOutput } = await execAsync(
|
|
83
|
+
`ps -p ${pid} -o pid,command 2>/dev/null || true`,
|
|
84
|
+
);
|
|
85
|
+
const lines = psOutput.trim().split("\n");
|
|
86
|
+
|
|
87
|
+
if (lines.length > 1) {
|
|
88
|
+
const processLine = lines[1];
|
|
89
|
+
const parts = processLine.trim().split(/\s+/);
|
|
90
|
+
const processCmd = parts.slice(1).join(" ");
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
pid: parseInt(pid, 10),
|
|
94
|
+
command: processCmd || "Unknown process",
|
|
95
|
+
port,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Fallback for Windows
|
|
101
|
+
if (process.platform === "win32") {
|
|
102
|
+
const { stdout } = await execAsync(`netstat -ano | findstr :${port}`);
|
|
103
|
+
const lines = stdout.trim().split("\n");
|
|
104
|
+
|
|
105
|
+
for (const line of lines) {
|
|
106
|
+
const parts = line.trim().split(/\s+/);
|
|
107
|
+
const pid = parts[parts.length - 1];
|
|
108
|
+
|
|
109
|
+
if (pid && pid !== "0") {
|
|
110
|
+
return {
|
|
111
|
+
pid: parseInt(pid),
|
|
112
|
+
command: "Use Task Manager to identify process",
|
|
113
|
+
port,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return null;
|
|
120
|
+
} catch (_error) {
|
|
121
|
+
// If commands fail, return null
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Check all required ports and return status
|
|
128
|
+
*/
|
|
129
|
+
export async function checkRequiredPorts(
|
|
130
|
+
ports: number[],
|
|
131
|
+
): Promise<PortStatus[]> {
|
|
132
|
+
const results: PortStatus[] = [];
|
|
133
|
+
|
|
134
|
+
// Robust sampling based purely on lsof LISTEN results to avoid false positives
|
|
135
|
+
const samplesPerPort = 6;
|
|
136
|
+
const sampleDelayMs = 120;
|
|
137
|
+
|
|
138
|
+
for (const port of ports) {
|
|
139
|
+
let conflictSamples = 0;
|
|
140
|
+
let lastProcessInfo: ProcessInfo | null = null;
|
|
141
|
+
|
|
142
|
+
for (let i = 0; i < samplesPerPort; i++) {
|
|
143
|
+
const info = await getProcessOnPort(port);
|
|
144
|
+
if (info) {
|
|
145
|
+
conflictSamples += 1;
|
|
146
|
+
lastProcessInfo = info;
|
|
147
|
+
}
|
|
148
|
+
if (i < samplesPerPort - 1) {
|
|
149
|
+
await new Promise((r) => setTimeout(r, sampleDelayMs));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const isConflict = conflictSamples >= 2 && lastProcessInfo !== null;
|
|
154
|
+
results.push({
|
|
155
|
+
port,
|
|
156
|
+
available: !isConflict,
|
|
157
|
+
process: isConflict ? lastProcessInfo : null,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return results;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Format port status for display
|
|
166
|
+
*/
|
|
167
|
+
export function formatPortStatus(portStatus: PortStatus[]): PortStatusResult {
|
|
168
|
+
const unavailable = portStatus.filter((p) => !p.available);
|
|
169
|
+
|
|
170
|
+
if (unavailable.length === 0) {
|
|
171
|
+
return {
|
|
172
|
+
hasConflicts: false,
|
|
173
|
+
message: "✅ All required ports are available",
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
let message = "\n❌ Port conflict detected!\n\n";
|
|
178
|
+
message += "The following ports are already in use:\n";
|
|
179
|
+
message += "─".repeat(60) + "\n";
|
|
180
|
+
|
|
181
|
+
for (const port of unavailable) {
|
|
182
|
+
message += `\n Port ${port.port}:\n`;
|
|
183
|
+
if (port.process) {
|
|
184
|
+
message += ` PID: ${port.process.pid}\n`;
|
|
185
|
+
message += ` Command: ${port.process.command.substring(0, 50)}${port.process.command.length > 50 ? "..." : ""}\n`;
|
|
186
|
+
message += ` Kill command: kill -9 ${port.process.pid}\n`;
|
|
187
|
+
} else {
|
|
188
|
+
message += ` Unable to identify process\n`;
|
|
189
|
+
message += ` Try: lsof -ti:${port.port} | xargs kill -9\n`;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
message += "\n" + "─".repeat(60) + "\n";
|
|
194
|
+
message += "\nTo resolve:\n";
|
|
195
|
+
message += " 1. Kill the conflicting processes using the commands above\n";
|
|
196
|
+
message += " 2. Or change the PORT in your .env file\n";
|
|
197
|
+
message += " 3. Then restart the application\n";
|
|
198
|
+
|
|
199
|
+
return {
|
|
200
|
+
hasConflicts: true,
|
|
201
|
+
message,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Find an available port starting from a base port
|
|
207
|
+
*/
|
|
208
|
+
export async function findAvailablePort(
|
|
209
|
+
startPort: number,
|
|
210
|
+
maxAttempts: number = 10,
|
|
211
|
+
): Promise<number | null> {
|
|
212
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
213
|
+
const port = startPort + i;
|
|
214
|
+
if (await isPortAvailable(port)) {
|
|
215
|
+
return port;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Clear a port by terminating the process using it
|
|
223
|
+
*/
|
|
224
|
+
export async function clearPort(port: number): Promise<PortClearResult> {
|
|
225
|
+
const processInfo = await getProcessOnPort(port);
|
|
226
|
+
|
|
227
|
+
if (!processInfo) {
|
|
228
|
+
return { cleared: true, port }; // Port is already free
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
try {
|
|
232
|
+
if (process.platform === "win32") {
|
|
233
|
+
execSync(`taskkill /F /PID ${processInfo.pid}`, { stdio: "ignore" });
|
|
234
|
+
} else {
|
|
235
|
+
execSync(`kill -9 ${processInfo.pid}`, { stdio: "ignore" });
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Wait a bit for the process to terminate
|
|
239
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
240
|
+
|
|
241
|
+
// Verify the port is now free
|
|
242
|
+
const available = await isPortAvailable(port);
|
|
243
|
+
return { cleared: available, port };
|
|
244
|
+
} catch (_error: any) {
|
|
245
|
+
console.warn(`Failed to clear port ${port}:`, _error.message);
|
|
246
|
+
return {
|
|
247
|
+
cleared: false,
|
|
248
|
+
port,
|
|
249
|
+
error: _error.message,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Get port information for display
|
|
256
|
+
*/
|
|
257
|
+
export async function getPortInfo(port: number): Promise<string> {
|
|
258
|
+
const available = await isPortAvailable(port);
|
|
259
|
+
const processInfo = available ? null : await getProcessOnPort(port);
|
|
260
|
+
|
|
261
|
+
if (available) {
|
|
262
|
+
return `Port ${port} is available`;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (processInfo) {
|
|
266
|
+
return `Port ${port} is in use by PID ${processInfo.pid}: ${processInfo.command}`;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return `Port ${port} is in use by unknown process`;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Wait for port to become available
|
|
274
|
+
*/
|
|
275
|
+
export async function waitForPort(
|
|
276
|
+
port: number,
|
|
277
|
+
timeout: number = 5000,
|
|
278
|
+
): Promise<boolean> {
|
|
279
|
+
const startTime = Date.now();
|
|
280
|
+
|
|
281
|
+
while (Date.now() - startTime < timeout) {
|
|
282
|
+
if (await isPortAvailable(port)) {
|
|
283
|
+
return true;
|
|
284
|
+
}
|
|
285
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
return false;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Get all ports in use within a range
|
|
293
|
+
*/
|
|
294
|
+
export async function getPortsInUse(
|
|
295
|
+
startPort: number = 3000,
|
|
296
|
+
endPort: number = 9999,
|
|
297
|
+
): Promise<number[]> {
|
|
298
|
+
const portsInUse: number[] = [];
|
|
299
|
+
|
|
300
|
+
for (let port = startPort; port <= endPort; port++) {
|
|
301
|
+
if (!(await isPortAvailable(port))) {
|
|
302
|
+
portsInUse.push(port);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return portsInUse;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export default {
|
|
310
|
+
isPortAvailable,
|
|
311
|
+
getProcessOnPort,
|
|
312
|
+
checkRequiredPorts,
|
|
313
|
+
formatPortStatus,
|
|
314
|
+
findAvailablePort,
|
|
315
|
+
clearPort,
|
|
316
|
+
getPortInfo,
|
|
317
|
+
waitForPort,
|
|
318
|
+
getPortsInUse,
|
|
319
|
+
};
|