@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,351 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Network Service
|
|
3
|
+
* Detects and manages network interfaces
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import os from "os";
|
|
7
|
+
import fs from "fs";
|
|
8
|
+
import net from "net";
|
|
9
|
+
|
|
10
|
+
interface NetworkAddress {
|
|
11
|
+
address: string;
|
|
12
|
+
family: string;
|
|
13
|
+
internal: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface NetworkInterface {
|
|
17
|
+
name: string;
|
|
18
|
+
addresses: NetworkAddress[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface BindingOption {
|
|
22
|
+
label: string;
|
|
23
|
+
value: string;
|
|
24
|
+
description: string;
|
|
25
|
+
interface: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface NetworkInfo {
|
|
29
|
+
hostname: string;
|
|
30
|
+
primaryIp: string | null;
|
|
31
|
+
interfaces: NetworkInterface[];
|
|
32
|
+
bindingOptions: BindingOption[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
class NetworkService {
|
|
36
|
+
/**
|
|
37
|
+
* Get all available network interfaces with their addresses
|
|
38
|
+
*/
|
|
39
|
+
getNetworkInterfaces(): NetworkInterface[] {
|
|
40
|
+
const interfaces = os.networkInterfaces();
|
|
41
|
+
const result: NetworkInterface[] = [];
|
|
42
|
+
|
|
43
|
+
for (const [name, addresses] of Object.entries(interfaces)) {
|
|
44
|
+
if (!addresses) continue;
|
|
45
|
+
|
|
46
|
+
const validAddresses = addresses
|
|
47
|
+
.filter((addr) => addr.family === "IPv4" && !addr.internal)
|
|
48
|
+
.map((addr) => ({
|
|
49
|
+
address: addr.address,
|
|
50
|
+
family: addr.family,
|
|
51
|
+
internal: addr.internal,
|
|
52
|
+
}));
|
|
53
|
+
|
|
54
|
+
if (validAddresses.length > 0) {
|
|
55
|
+
result.push({
|
|
56
|
+
name,
|
|
57
|
+
addresses: validAddresses,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Always include localhost option
|
|
63
|
+
result.unshift({
|
|
64
|
+
name: "localhost",
|
|
65
|
+
addresses: [
|
|
66
|
+
{
|
|
67
|
+
address: "127.0.0.1",
|
|
68
|
+
family: "IPv4",
|
|
69
|
+
internal: true,
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Always include all interfaces option
|
|
75
|
+
result.unshift({
|
|
76
|
+
name: "all",
|
|
77
|
+
addresses: [
|
|
78
|
+
{
|
|
79
|
+
address: "0.0.0.0",
|
|
80
|
+
family: "IPv4",
|
|
81
|
+
internal: false,
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Get a formatted list of binding options for UI
|
|
91
|
+
*/
|
|
92
|
+
getBindingOptions(): BindingOption[] {
|
|
93
|
+
const interfaces = this.getNetworkInterfaces();
|
|
94
|
+
const options: BindingOption[] = [];
|
|
95
|
+
|
|
96
|
+
// Always add default binding options first
|
|
97
|
+
options.push({
|
|
98
|
+
value: "0.0.0.0",
|
|
99
|
+
label: "All interfaces",
|
|
100
|
+
description: "Listen on all available network interfaces",
|
|
101
|
+
interface: "all",
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
options.push({
|
|
105
|
+
value: "127.0.0.1",
|
|
106
|
+
label: "Localhost only",
|
|
107
|
+
description: "Only accessible from this machine",
|
|
108
|
+
interface: "localhost",
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Add specific interface options (excluding duplicates of the default options)
|
|
112
|
+
for (const iface of interfaces) {
|
|
113
|
+
for (const addr of iface.addresses) {
|
|
114
|
+
// Skip if this address is already in our default options
|
|
115
|
+
if (addr.address === "0.0.0.0" || addr.address === "127.0.0.1") {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
options.push({
|
|
120
|
+
label: `${iface.name} (${addr.address})`,
|
|
121
|
+
value: addr.address,
|
|
122
|
+
description: `Accept connections on ${iface.name} network interface`,
|
|
123
|
+
interface: iface.name,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return options;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Get the current machine's primary IP address
|
|
133
|
+
*/
|
|
134
|
+
getPrimaryIpAddress(): string | null {
|
|
135
|
+
const interfaces = this.getNetworkInterfaces();
|
|
136
|
+
|
|
137
|
+
// Look for the first non-localhost, non-all interface
|
|
138
|
+
for (const iface of interfaces) {
|
|
139
|
+
if (iface.name === "localhost" || iface.name === "all") continue;
|
|
140
|
+
|
|
141
|
+
for (const addr of iface.addresses) {
|
|
142
|
+
if (!addr.internal && addr.family === "IPv4") {
|
|
143
|
+
return addr.address;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Validate if an IP address is valid for binding
|
|
153
|
+
*/
|
|
154
|
+
isValidBindingAddress(address: string): boolean {
|
|
155
|
+
// Check for special addresses
|
|
156
|
+
if (address === "0.0.0.0" || address === "127.0.0.1") {
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Check if it's one of the machine's interfaces
|
|
161
|
+
const interfaces = this.getNetworkInterfaces();
|
|
162
|
+
for (const iface of interfaces) {
|
|
163
|
+
for (const addr of iface.addresses) {
|
|
164
|
+
if (addr.address === address) {
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Format network information for display
|
|
175
|
+
*/
|
|
176
|
+
getNetworkInfo(): NetworkInfo {
|
|
177
|
+
const hostname = os.hostname();
|
|
178
|
+
const primaryIp = this.getPrimaryIpAddress();
|
|
179
|
+
const interfaces = this.getNetworkInterfaces();
|
|
180
|
+
|
|
181
|
+
return {
|
|
182
|
+
hostname,
|
|
183
|
+
primaryIp,
|
|
184
|
+
interfaces: interfaces.filter(
|
|
185
|
+
(i) => i.name !== "all" && i.name !== "localhost",
|
|
186
|
+
),
|
|
187
|
+
bindingOptions: this.getBindingOptions(),
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Check if running in Docker container
|
|
193
|
+
*/
|
|
194
|
+
isDocker(): boolean {
|
|
195
|
+
try {
|
|
196
|
+
// Check for .dockerenv file
|
|
197
|
+
// fs already imported at top
|
|
198
|
+
if (fs.existsSync("/.dockerenv")) {
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Check cgroup for docker
|
|
203
|
+
const cgroup = fs.readFileSync("/proc/self/cgroup", "utf8");
|
|
204
|
+
return cgroup.includes("docker");
|
|
205
|
+
} catch {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Get recommended binding address based on environment
|
|
212
|
+
*/
|
|
213
|
+
getRecommendedBindingAddress(): string {
|
|
214
|
+
if (this.isDocker()) {
|
|
215
|
+
// In Docker, bind to all interfaces
|
|
216
|
+
return "0.0.0.0";
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (process.env.NODE_ENV === "production") {
|
|
220
|
+
// In production, bind to primary IP
|
|
221
|
+
return this.getPrimaryIpAddress() || "0.0.0.0";
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// In development, bind to localhost
|
|
225
|
+
return "127.0.0.1";
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Parse connection string (host:port)
|
|
230
|
+
*/
|
|
231
|
+
parseConnectionString(
|
|
232
|
+
connectionString: string,
|
|
233
|
+
): { host: string; port: number } | null {
|
|
234
|
+
const parts = connectionString.split(":");
|
|
235
|
+
if (parts.length !== 2) return null;
|
|
236
|
+
|
|
237
|
+
const host = parts[0];
|
|
238
|
+
const port = parseInt(parts[1], 10);
|
|
239
|
+
|
|
240
|
+
if (isNaN(port) || port < 1 || port > 65535) return null;
|
|
241
|
+
|
|
242
|
+
return { host, port };
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Format connection URL
|
|
247
|
+
*/
|
|
248
|
+
formatConnectionUrl(
|
|
249
|
+
protocol: string,
|
|
250
|
+
host: string,
|
|
251
|
+
port: number,
|
|
252
|
+
path: string = "",
|
|
253
|
+
): string {
|
|
254
|
+
// Handle IPv6 addresses
|
|
255
|
+
const formattedHost = host.includes(":") ? `[${host}]` : host;
|
|
256
|
+
return `${protocol}://${formattedHost}:${port}${path}`;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Get network latency to a host
|
|
261
|
+
*/
|
|
262
|
+
async getLatency(
|
|
263
|
+
host: string,
|
|
264
|
+
timeout: number = 5000,
|
|
265
|
+
): Promise<number | null> {
|
|
266
|
+
const start = Date.now();
|
|
267
|
+
|
|
268
|
+
return new Promise((resolve) => {
|
|
269
|
+
// net already imported at top
|
|
270
|
+
const socket = new net.Socket();
|
|
271
|
+
|
|
272
|
+
const timer = setTimeout(() => {
|
|
273
|
+
socket.destroy();
|
|
274
|
+
resolve(null);
|
|
275
|
+
}, timeout);
|
|
276
|
+
|
|
277
|
+
socket.connect(80, host, () => {
|
|
278
|
+
clearTimeout(timer);
|
|
279
|
+
socket.destroy();
|
|
280
|
+
resolve(Date.now() - start);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
socket.on("error", () => {
|
|
284
|
+
clearTimeout(timer);
|
|
285
|
+
resolve(null);
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Check if a host is reachable
|
|
292
|
+
*/
|
|
293
|
+
async isHostReachable(
|
|
294
|
+
host: string,
|
|
295
|
+
port: number,
|
|
296
|
+
timeout: number = 5000,
|
|
297
|
+
): Promise<boolean> {
|
|
298
|
+
return new Promise((resolve) => {
|
|
299
|
+
// net already imported at top
|
|
300
|
+
const socket = new net.Socket();
|
|
301
|
+
|
|
302
|
+
const timer = setTimeout(() => {
|
|
303
|
+
socket.destroy();
|
|
304
|
+
resolve(false);
|
|
305
|
+
}, timeout);
|
|
306
|
+
|
|
307
|
+
socket.connect(port, host, () => {
|
|
308
|
+
clearTimeout(timer);
|
|
309
|
+
socket.destroy();
|
|
310
|
+
resolve(true);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
socket.on("error", () => {
|
|
314
|
+
clearTimeout(timer);
|
|
315
|
+
resolve(false);
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Get network statistics
|
|
322
|
+
*/
|
|
323
|
+
getNetworkStats(): Record<string, any> {
|
|
324
|
+
const interfaces = os.networkInterfaces();
|
|
325
|
+
const stats: Record<string, any> = {};
|
|
326
|
+
|
|
327
|
+
for (const [name, addresses] of Object.entries(interfaces)) {
|
|
328
|
+
if (!addresses) continue;
|
|
329
|
+
|
|
330
|
+
stats[name] = {
|
|
331
|
+
ipv4: addresses.filter((a) => a.family === "IPv4").length,
|
|
332
|
+
ipv6: addresses.filter((a) => a.family === "IPv6").length,
|
|
333
|
+
internal: addresses.some((a) => a.internal),
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return stats;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Singleton instance
|
|
342
|
+
let networkService: NetworkService | null = null;
|
|
343
|
+
|
|
344
|
+
export function getNetworkService(): NetworkService {
|
|
345
|
+
if (!networkService) {
|
|
346
|
+
networkService = new NetworkService();
|
|
347
|
+
}
|
|
348
|
+
return networkService;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export default NetworkService;
|