chrome-cdp-cli 2.1.1 → 2.1.3
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/CLIApplication.js +10 -12
- package/dist/cli/EnhancedCLIInterface.js +48 -38
- package/dist/cli/OutputFormatter.js +77 -75
- package/dist/cli/OutputManager.js +20 -20
- package/dist/client/index.js +0 -1
- package/dist/handlers/EvaluateScriptHandler.js +74 -270
- package/dist/utils/logger.js +42 -46
- package/package.json +1 -1
- package/dist/client/ProxyClient.js +0 -278
- package/dist/handlers/RestartProxyHandler.js +0 -97
- package/dist/proxy/ProxyManager.js +0 -270
- package/dist/proxy/index.js +0 -60
- package/dist/proxy/server/CDPEventMonitor.js +0 -263
- package/dist/proxy/server/CDPProxyServer.js +0 -441
- package/dist/proxy/server/CommandExecutionService.js +0 -297
- package/dist/proxy/server/ConnectionPool.js +0 -437
- package/dist/proxy/server/FileSystemSecurity.js +0 -358
- package/dist/proxy/server/HealthMonitor.js +0 -242
- package/dist/proxy/server/MessageStore.js +0 -291
- package/dist/proxy/server/PerformanceMonitor.js +0 -277
- package/dist/proxy/server/ProxyAPIServer.js +0 -1125
- package/dist/proxy/server/SecurityManager.js +0 -337
- package/dist/proxy/server/WSProxy.js +0 -468
- package/dist/proxy/types/ProxyTypes.js +0 -2
package/dist/utils/logger.js
CHANGED
|
@@ -53,7 +53,7 @@ class Logger {
|
|
|
53
53
|
maxFiles: 5,
|
|
54
54
|
enableConsole: true,
|
|
55
55
|
enableStructured: false,
|
|
56
|
-
...config
|
|
56
|
+
...config,
|
|
57
57
|
};
|
|
58
58
|
if (this.config.file) {
|
|
59
59
|
this.initializeLogFile();
|
|
@@ -74,13 +74,15 @@ class Logger {
|
|
|
74
74
|
this.rotateLogFile();
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
|
-
this.logFileHandle = fs.createWriteStream(this.config.file, {
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
this.logFileHandle = fs.createWriteStream(this.config.file, {
|
|
78
|
+
flags: "a",
|
|
79
|
+
});
|
|
80
|
+
this.logFileHandle.on("error", (error) => {
|
|
81
|
+
console.error("Log file write error:", error);
|
|
80
82
|
});
|
|
81
83
|
}
|
|
82
84
|
catch (error) {
|
|
83
|
-
console.error(
|
|
85
|
+
console.error("Failed to initialize log file:", error);
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
88
|
rotateLogFile() {
|
|
@@ -104,25 +106,29 @@ class Logger {
|
|
|
104
106
|
fs.renameSync(this.config.file, `${this.config.file}.1`);
|
|
105
107
|
}
|
|
106
108
|
this.currentFileSize = 0;
|
|
107
|
-
this.logFileHandle = fs.createWriteStream(this.config.file, {
|
|
108
|
-
|
|
109
|
-
|
|
109
|
+
this.logFileHandle = fs.createWriteStream(this.config.file, {
|
|
110
|
+
flags: "a",
|
|
111
|
+
});
|
|
112
|
+
this.logFileHandle.on("error", (error) => {
|
|
113
|
+
console.error("Log file write error:", error);
|
|
110
114
|
});
|
|
111
115
|
}
|
|
112
116
|
catch (error) {
|
|
113
|
-
console.error(
|
|
117
|
+
console.error("Failed to rotate log file:", error);
|
|
114
118
|
}
|
|
115
119
|
}
|
|
116
120
|
formatLogEntry(entry) {
|
|
117
121
|
if (this.config.enableStructured) {
|
|
118
|
-
return JSON.stringify(entry) +
|
|
122
|
+
return JSON.stringify(entry) + "\n";
|
|
119
123
|
}
|
|
120
124
|
else {
|
|
121
125
|
const timestamp = entry.timestamp;
|
|
122
126
|
const level = entry.level.padEnd(5);
|
|
123
|
-
const component = entry.component ? `[${entry.component}]` :
|
|
124
|
-
const connectionId = entry.connectionId
|
|
125
|
-
|
|
127
|
+
const component = entry.component ? `[${entry.component}]` : "";
|
|
128
|
+
const connectionId = entry.connectionId
|
|
129
|
+
? `{conn:${entry.connectionId}}`
|
|
130
|
+
: "";
|
|
131
|
+
const clientId = entry.clientId ? `{client:${entry.clientId}}` : "";
|
|
126
132
|
let message = `${timestamp} ${level} ${component}${connectionId}${clientId} ${entry.message}`;
|
|
127
133
|
if (entry.data) {
|
|
128
134
|
message += ` | Data: ${JSON.stringify(entry.data)}`;
|
|
@@ -136,7 +142,7 @@ class Logger {
|
|
|
136
142
|
if (entry.metrics) {
|
|
137
143
|
message += ` | Metrics: ${JSON.stringify(entry.metrics)}`;
|
|
138
144
|
}
|
|
139
|
-
return message +
|
|
145
|
+
return message + "\n";
|
|
140
146
|
}
|
|
141
147
|
}
|
|
142
148
|
writeLog(entry) {
|
|
@@ -145,24 +151,12 @@ class Logger {
|
|
|
145
151
|
const consoleMessage = this.config.enableStructured
|
|
146
152
|
? formattedEntry.trim()
|
|
147
153
|
: formattedEntry.trim();
|
|
148
|
-
|
|
149
|
-
case 'ERROR':
|
|
150
|
-
console.error(consoleMessage);
|
|
151
|
-
break;
|
|
152
|
-
case 'WARN':
|
|
153
|
-
console.warn(consoleMessage);
|
|
154
|
-
break;
|
|
155
|
-
case 'INFO':
|
|
156
|
-
console.info(consoleMessage);
|
|
157
|
-
break;
|
|
158
|
-
case 'DEBUG':
|
|
159
|
-
console.debug(consoleMessage);
|
|
160
|
-
break;
|
|
161
|
-
}
|
|
154
|
+
process.stderr.write(consoleMessage + "\n");
|
|
162
155
|
}
|
|
163
156
|
if (this.logFileHandle) {
|
|
164
|
-
const entrySize = Buffer.byteLength(formattedEntry,
|
|
165
|
-
if (this.currentFileSize + entrySize >=
|
|
157
|
+
const entrySize = Buffer.byteLength(formattedEntry, "utf8");
|
|
158
|
+
if (this.currentFileSize + entrySize >=
|
|
159
|
+
(this.config.maxFileSize || 10 * 1024 * 1024)) {
|
|
166
160
|
this.rotateLogFile();
|
|
167
161
|
}
|
|
168
162
|
this.logFileHandle.write(formattedEntry);
|
|
@@ -174,7 +168,7 @@ class Logger {
|
|
|
174
168
|
timestamp: new Date().toISOString(),
|
|
175
169
|
level,
|
|
176
170
|
message,
|
|
177
|
-
component: context?.component || this.config.component
|
|
171
|
+
component: context?.component || this.config.component,
|
|
178
172
|
};
|
|
179
173
|
if (context?.connectionId)
|
|
180
174
|
entry.connectionId = context.connectionId;
|
|
@@ -188,7 +182,7 @@ class Logger {
|
|
|
188
182
|
entry.error = {
|
|
189
183
|
message: error.message,
|
|
190
184
|
stack: error.stack,
|
|
191
|
-
code: error.code
|
|
185
|
+
code: error.code,
|
|
192
186
|
};
|
|
193
187
|
}
|
|
194
188
|
return entry;
|
|
@@ -214,57 +208,59 @@ class Logger {
|
|
|
214
208
|
data = errorOrData;
|
|
215
209
|
error = undefined;
|
|
216
210
|
}
|
|
217
|
-
const entry = this.createLogEntry(
|
|
211
|
+
const entry = this.createLogEntry("ERROR", message, data, error, context);
|
|
218
212
|
this.writeLog(entry);
|
|
219
213
|
}
|
|
220
214
|
}
|
|
221
215
|
warn(message, data, context) {
|
|
222
216
|
if (this.config.level >= LogLevel.WARN) {
|
|
223
|
-
const entry = this.createLogEntry(
|
|
217
|
+
const entry = this.createLogEntry("WARN", message, data, undefined, context);
|
|
224
218
|
this.writeLog(entry);
|
|
225
219
|
}
|
|
226
220
|
}
|
|
227
221
|
info(message, data, context) {
|
|
228
222
|
if (this.config.level >= LogLevel.INFO) {
|
|
229
|
-
const entry = this.createLogEntry(
|
|
223
|
+
const entry = this.createLogEntry("INFO", message, data, undefined, context);
|
|
230
224
|
this.writeLog(entry);
|
|
231
225
|
}
|
|
232
226
|
}
|
|
233
227
|
debug(message, data, context) {
|
|
234
228
|
if (this.config.level >= LogLevel.DEBUG) {
|
|
235
|
-
const entry = this.createLogEntry(
|
|
229
|
+
const entry = this.createLogEntry("DEBUG", message, data, undefined, context);
|
|
236
230
|
this.writeLog(entry);
|
|
237
231
|
}
|
|
238
232
|
}
|
|
239
233
|
logServerEvent(event, message, data, error) {
|
|
240
|
-
const metrics = event ===
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
234
|
+
const metrics = event === "startup" || event === "shutdown"
|
|
235
|
+
? {
|
|
236
|
+
memoryUsage: process.memoryUsage(),
|
|
237
|
+
}
|
|
238
|
+
: undefined;
|
|
239
|
+
const entry = this.createLogEntry(event === "error" ? "ERROR" : "INFO", `[SERVER-${event.toUpperCase()}] ${message}`, data, error, { component: "ProxyServer", metrics });
|
|
244
240
|
this.writeLog(entry);
|
|
245
241
|
}
|
|
246
242
|
logConnectionEvent(event, connectionId, message, data, error) {
|
|
247
|
-
const entry = this.createLogEntry(error ?
|
|
243
|
+
const entry = this.createLogEntry(error ? "ERROR" : "INFO", `[CONNECTION-${event.toUpperCase()}] ${message}`, data, error, { component: "ConnectionPool", connectionId });
|
|
248
244
|
this.writeLog(entry);
|
|
249
245
|
}
|
|
250
246
|
logClientEvent(event, clientId, message, data, error) {
|
|
251
|
-
const entry = this.createLogEntry(error ?
|
|
247
|
+
const entry = this.createLogEntry(error ? "ERROR" : "INFO", `[CLIENT-${event.toUpperCase()}] ${message}`, data, error, { component: "WSProxy", clientId });
|
|
252
248
|
this.writeLog(entry);
|
|
253
249
|
}
|
|
254
250
|
logMemoryEvent(event, message, metrics) {
|
|
255
|
-
const entry = this.createLogEntry(
|
|
251
|
+
const entry = this.createLogEntry("INFO", `[MEMORY-${event.toUpperCase()}] ${message}`, undefined, undefined, { component: "MemoryManager", metrics });
|
|
256
252
|
this.writeLog(entry);
|
|
257
253
|
}
|
|
258
254
|
logAPIEvent(method, path, statusCode, duration, clientIP, error) {
|
|
259
|
-
const entry = this.createLogEntry(error ?
|
|
255
|
+
const entry = this.createLogEntry(error ? "ERROR" : "INFO", `[API] ${method} ${path} - ${statusCode} (${duration}ms)`, { clientIP, duration, statusCode }, error, { component: "ProxyAPI" });
|
|
260
256
|
this.writeLog(entry);
|
|
261
257
|
}
|
|
262
258
|
logSecurityEvent(event, message, data, error) {
|
|
263
|
-
const entry = this.createLogEntry(error ?
|
|
259
|
+
const entry = this.createLogEntry(error ? "ERROR" : "WARN", `[SECURITY-${event.toUpperCase()}] ${message}`, data, error, { component: "SecurityManager" });
|
|
264
260
|
this.writeLog(entry);
|
|
265
261
|
}
|
|
266
262
|
logPerformanceMetrics(component, metrics) {
|
|
267
|
-
const entry = this.createLogEntry(
|
|
263
|
+
const entry = this.createLogEntry("INFO", `[PERFORMANCE] ${component} metrics`, undefined, undefined, { component, metrics });
|
|
268
264
|
this.writeLog(entry);
|
|
269
265
|
}
|
|
270
266
|
close() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chrome-cdp-cli",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.3",
|
|
4
4
|
"description": "Browser automation CLI via Chrome DevTools Protocol. Designed for developers and AI assistants - combines dedicated commands for common tasks with flexible JavaScript execution for complex scenarios. Features: element interaction, screenshots, DOM snapshots, console/network monitoring. Built-in IDE integration for Cursor and Claude.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.ProxyClient = void 0;
|
|
7
|
-
const ws_1 = require("ws");
|
|
8
|
-
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
9
|
-
const ProxyManager_1 = require("../proxy/ProxyManager");
|
|
10
|
-
class ProxyClient {
|
|
11
|
-
constructor(config) {
|
|
12
|
-
this.config = {
|
|
13
|
-
proxyUrl: 'http://localhost:9223',
|
|
14
|
-
fallbackToDirect: true,
|
|
15
|
-
startProxyIfNeeded: true,
|
|
16
|
-
...config
|
|
17
|
-
};
|
|
18
|
-
this.proxyManager = ProxyManager_1.ProxyManager.getInstance();
|
|
19
|
-
}
|
|
20
|
-
async ensureProxyRunning() {
|
|
21
|
-
if (this.config.startProxyIfNeeded) {
|
|
22
|
-
return await this.proxyManager.ensureProxyReady();
|
|
23
|
-
}
|
|
24
|
-
return await this.isProxyRunning();
|
|
25
|
-
}
|
|
26
|
-
async isProxyAvailable() {
|
|
27
|
-
return await this.isProxyRunning();
|
|
28
|
-
}
|
|
29
|
-
async isProxyRunning() {
|
|
30
|
-
try {
|
|
31
|
-
const controller = new AbortController();
|
|
32
|
-
const timeout = setTimeout(() => controller.abort(), 2000);
|
|
33
|
-
const response = await (0, node_fetch_1.default)(`${this.config.proxyUrl}/api/health`, {
|
|
34
|
-
method: 'GET',
|
|
35
|
-
signal: controller.signal
|
|
36
|
-
});
|
|
37
|
-
clearTimeout(timeout);
|
|
38
|
-
return response.ok;
|
|
39
|
-
}
|
|
40
|
-
catch (error) {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
async connect(host, port, targetId) {
|
|
45
|
-
const request = {
|
|
46
|
-
host,
|
|
47
|
-
port,
|
|
48
|
-
targetId
|
|
49
|
-
};
|
|
50
|
-
try {
|
|
51
|
-
const controller = new AbortController();
|
|
52
|
-
const timeout = setTimeout(() => controller.abort(), 30000);
|
|
53
|
-
const response = await (0, node_fetch_1.default)(`${this.config.proxyUrl}/api/connect`, {
|
|
54
|
-
method: 'POST',
|
|
55
|
-
headers: {
|
|
56
|
-
'Content-Type': 'application/json'
|
|
57
|
-
},
|
|
58
|
-
body: JSON.stringify(request),
|
|
59
|
-
signal: controller.signal
|
|
60
|
-
});
|
|
61
|
-
clearTimeout(timeout);
|
|
62
|
-
if (!response.ok) {
|
|
63
|
-
throw new Error(`Proxy connect failed: ${response.status} ${response.statusText}`);
|
|
64
|
-
}
|
|
65
|
-
const result = await response.json();
|
|
66
|
-
if (!result.success) {
|
|
67
|
-
throw new Error(`Proxy connect failed: ${result.error}`);
|
|
68
|
-
}
|
|
69
|
-
this.connectionId = result.data.connectionId;
|
|
70
|
-
return this.connectionId;
|
|
71
|
-
}
|
|
72
|
-
catch (error) {
|
|
73
|
-
throw new Error(`Failed to connect through proxy: ${error instanceof Error ? error.message : error}`);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
async getConsoleMessages(filter) {
|
|
77
|
-
if (!this.connectionId) {
|
|
78
|
-
throw new Error('No active connection. Call connect() first.');
|
|
79
|
-
}
|
|
80
|
-
try {
|
|
81
|
-
const url = new URL(`${this.config.proxyUrl}/api/console/${this.connectionId}`);
|
|
82
|
-
if (filter) {
|
|
83
|
-
if (filter.types) {
|
|
84
|
-
url.searchParams.set('types', filter.types.join(','));
|
|
85
|
-
}
|
|
86
|
-
if (filter.textPattern) {
|
|
87
|
-
url.searchParams.set('textPattern', filter.textPattern);
|
|
88
|
-
}
|
|
89
|
-
if (filter.maxMessages) {
|
|
90
|
-
url.searchParams.set('maxMessages', filter.maxMessages.toString());
|
|
91
|
-
}
|
|
92
|
-
if (filter.startTime) {
|
|
93
|
-
url.searchParams.set('startTime', filter.startTime.toString());
|
|
94
|
-
}
|
|
95
|
-
if (filter.endTime) {
|
|
96
|
-
url.searchParams.set('endTime', filter.endTime.toString());
|
|
97
|
-
}
|
|
98
|
-
if (filter.source) {
|
|
99
|
-
url.searchParams.set('source', filter.source);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
const controller = new AbortController();
|
|
103
|
-
const timeout = setTimeout(() => controller.abort(), 5000);
|
|
104
|
-
const response = await (0, node_fetch_1.default)(url.toString(), {
|
|
105
|
-
method: 'GET',
|
|
106
|
-
signal: controller.signal
|
|
107
|
-
});
|
|
108
|
-
clearTimeout(timeout);
|
|
109
|
-
if (!response.ok) {
|
|
110
|
-
throw new Error(`Failed to get console messages: ${response.status} ${response.statusText}`);
|
|
111
|
-
}
|
|
112
|
-
const result = await response.json();
|
|
113
|
-
if (!result.success) {
|
|
114
|
-
throw new Error(`Failed to get console messages: ${result.error}`);
|
|
115
|
-
}
|
|
116
|
-
return result.data?.messages || [];
|
|
117
|
-
}
|
|
118
|
-
catch (error) {
|
|
119
|
-
throw new Error(`Failed to get console messages: ${error instanceof Error ? error.message : error}`);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
async getNetworkRequests(filter) {
|
|
123
|
-
if (!this.connectionId) {
|
|
124
|
-
throw new Error('No active connection. Call connect() first.');
|
|
125
|
-
}
|
|
126
|
-
try {
|
|
127
|
-
const url = new URL(`${this.config.proxyUrl}/api/network/${this.connectionId}`);
|
|
128
|
-
if (filter) {
|
|
129
|
-
if (filter.methods) {
|
|
130
|
-
url.searchParams.set('methods', filter.methods.join(','));
|
|
131
|
-
}
|
|
132
|
-
if (filter.statusCodes) {
|
|
133
|
-
url.searchParams.set('statusCodes', filter.statusCodes.join(','));
|
|
134
|
-
}
|
|
135
|
-
if (filter.urlPattern) {
|
|
136
|
-
url.searchParams.set('urlPattern', filter.urlPattern);
|
|
137
|
-
}
|
|
138
|
-
if (filter.maxRequests) {
|
|
139
|
-
url.searchParams.set('maxRequests', filter.maxRequests.toString());
|
|
140
|
-
}
|
|
141
|
-
if (filter.startTime) {
|
|
142
|
-
url.searchParams.set('startTime', filter.startTime.toString());
|
|
143
|
-
}
|
|
144
|
-
if (filter.endTime) {
|
|
145
|
-
url.searchParams.set('endTime', filter.endTime.toString());
|
|
146
|
-
}
|
|
147
|
-
if (filter.includeResponseBody !== undefined) {
|
|
148
|
-
url.searchParams.set('includeResponseBody', filter.includeResponseBody.toString());
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
const controller = new AbortController();
|
|
152
|
-
const timeout = setTimeout(() => controller.abort(), 5000);
|
|
153
|
-
const response = await (0, node_fetch_1.default)(url.toString(), {
|
|
154
|
-
method: 'GET',
|
|
155
|
-
signal: controller.signal
|
|
156
|
-
});
|
|
157
|
-
clearTimeout(timeout);
|
|
158
|
-
if (!response.ok) {
|
|
159
|
-
throw new Error(`Failed to get network requests: ${response.status} ${response.statusText}`);
|
|
160
|
-
}
|
|
161
|
-
const result = await response.json();
|
|
162
|
-
if (!result.success) {
|
|
163
|
-
throw new Error(`Failed to get network requests: ${result.error}`);
|
|
164
|
-
}
|
|
165
|
-
return result.data?.requests || [];
|
|
166
|
-
}
|
|
167
|
-
catch (error) {
|
|
168
|
-
throw new Error(`Failed to get network requests: ${error instanceof Error ? error.message : error}`);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
async createWebSocketProxy() {
|
|
172
|
-
if (!this.connectionId) {
|
|
173
|
-
throw new Error('No active connection. Call connect() first.');
|
|
174
|
-
}
|
|
175
|
-
console.log(`[DEBUG] Creating WebSocket proxy for connection: ${this.connectionId}`);
|
|
176
|
-
try {
|
|
177
|
-
const wsUrl = this.config.proxyUrl.replace('http://', 'ws://').replace('https://', 'wss://');
|
|
178
|
-
const fullWsUrl = `${wsUrl}/ws/${this.connectionId}`;
|
|
179
|
-
console.log(`[DEBUG] WebSocket URL: ${fullWsUrl}`);
|
|
180
|
-
const ws = new ws_1.WebSocket(fullWsUrl);
|
|
181
|
-
return new Promise((resolve, reject) => {
|
|
182
|
-
const timeout = setTimeout(() => {
|
|
183
|
-
console.log(`[DEBUG] WebSocket connection timeout for ${this.connectionId}`);
|
|
184
|
-
reject(new Error('WebSocket connection timeout'));
|
|
185
|
-
}, 10000);
|
|
186
|
-
ws.on('open', () => {
|
|
187
|
-
console.log(`[DEBUG] WebSocket connection opened for ${this.connectionId}`);
|
|
188
|
-
clearTimeout(timeout);
|
|
189
|
-
this.wsConnection = ws;
|
|
190
|
-
resolve(ws);
|
|
191
|
-
});
|
|
192
|
-
ws.on('error', (error) => {
|
|
193
|
-
console.log(`[DEBUG] WebSocket connection error for ${this.connectionId}:`, error);
|
|
194
|
-
clearTimeout(timeout);
|
|
195
|
-
reject(error);
|
|
196
|
-
});
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
catch (error) {
|
|
200
|
-
console.log(`[DEBUG] Failed to create WebSocket proxy for ${this.connectionId}:`, error);
|
|
201
|
-
throw new Error(`Failed to create WebSocket proxy: ${error instanceof Error ? error.message : error}`);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
async healthCheck() {
|
|
205
|
-
if (!this.connectionId) {
|
|
206
|
-
return null;
|
|
207
|
-
}
|
|
208
|
-
try {
|
|
209
|
-
const controller = new AbortController();
|
|
210
|
-
const timeout = setTimeout(() => controller.abort(), 5000);
|
|
211
|
-
const response = await (0, node_fetch_1.default)(`${this.config.proxyUrl}/api/health/${this.connectionId}`, {
|
|
212
|
-
method: 'GET',
|
|
213
|
-
signal: controller.signal
|
|
214
|
-
});
|
|
215
|
-
clearTimeout(timeout);
|
|
216
|
-
if (!response.ok) {
|
|
217
|
-
throw new Error(`Health check failed: ${response.status} ${response.statusText}`);
|
|
218
|
-
}
|
|
219
|
-
const result = await response.json();
|
|
220
|
-
if (!result.success) {
|
|
221
|
-
throw new Error(`Health check failed: ${result.error}`);
|
|
222
|
-
}
|
|
223
|
-
return result.data || null;
|
|
224
|
-
}
|
|
225
|
-
catch (error) {
|
|
226
|
-
console.warn('Health check failed:', error instanceof Error ? error.message : error);
|
|
227
|
-
return null;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
async disconnect() {
|
|
231
|
-
try {
|
|
232
|
-
if (this.connectionId) {
|
|
233
|
-
try {
|
|
234
|
-
const controller = new AbortController();
|
|
235
|
-
const timeout = setTimeout(() => controller.abort(), 5000);
|
|
236
|
-
await (0, node_fetch_1.default)(`${this.config.proxyUrl}/api/client/release`, {
|
|
237
|
-
method: 'POST',
|
|
238
|
-
headers: {
|
|
239
|
-
'Content-Type': 'application/json',
|
|
240
|
-
'x-client-id': `proxy_client_${Date.now()}`
|
|
241
|
-
},
|
|
242
|
-
signal: controller.signal
|
|
243
|
-
});
|
|
244
|
-
clearTimeout(timeout);
|
|
245
|
-
}
|
|
246
|
-
catch (error) {
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
if (this.wsConnection) {
|
|
250
|
-
this.wsConnection.close();
|
|
251
|
-
this.wsConnection = undefined;
|
|
252
|
-
}
|
|
253
|
-
if (this.connectionId) {
|
|
254
|
-
try {
|
|
255
|
-
const controller = new AbortController();
|
|
256
|
-
const timeout = setTimeout(() => controller.abort(), 5000);
|
|
257
|
-
await (0, node_fetch_1.default)(`${this.config.proxyUrl}/api/connection/${this.connectionId}`, {
|
|
258
|
-
method: 'DELETE',
|
|
259
|
-
signal: controller.signal
|
|
260
|
-
});
|
|
261
|
-
clearTimeout(timeout);
|
|
262
|
-
}
|
|
263
|
-
catch (error) {
|
|
264
|
-
}
|
|
265
|
-
this.connectionId = undefined;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
catch (error) {
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
getConnectionId() {
|
|
272
|
-
return this.connectionId;
|
|
273
|
-
}
|
|
274
|
-
getConfig() {
|
|
275
|
-
return { ...this.config };
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
exports.ProxyClient = ProxyClient;
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RestartProxyHandler = void 0;
|
|
4
|
-
const ProxyManager_1 = require("../proxy/ProxyManager");
|
|
5
|
-
class RestartProxyHandler {
|
|
6
|
-
constructor() {
|
|
7
|
-
this.name = 'restart';
|
|
8
|
-
}
|
|
9
|
-
async execute(_client, args) {
|
|
10
|
-
try {
|
|
11
|
-
const params = args;
|
|
12
|
-
const proxyManager = ProxyManager_1.ProxyManager.getInstance();
|
|
13
|
-
const status = await proxyManager.getStatus();
|
|
14
|
-
if (status.isHealthy && !params.force) {
|
|
15
|
-
return {
|
|
16
|
-
success: true,
|
|
17
|
-
data: {
|
|
18
|
-
message: 'Proxy server is already running and healthy',
|
|
19
|
-
status: status
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
const success = await proxyManager.restart();
|
|
24
|
-
if (success) {
|
|
25
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
26
|
-
const newStatus = await proxyManager.getStatus();
|
|
27
|
-
return {
|
|
28
|
-
success: true,
|
|
29
|
-
data: {
|
|
30
|
-
message: 'Proxy server restarted successfully',
|
|
31
|
-
status: newStatus
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
return {
|
|
37
|
-
success: false,
|
|
38
|
-
error: 'Failed to restart proxy server. Check logs for details.'
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
catch (error) {
|
|
43
|
-
return {
|
|
44
|
-
success: false,
|
|
45
|
-
error: error instanceof Error ? error.message : 'Unknown error occurred while restarting proxy'
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
validateArgs(args) {
|
|
50
|
-
if (typeof args !== 'object' || args === null) {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
const params = args;
|
|
54
|
-
if ('force' in params && typeof params.force !== 'boolean') {
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
return true;
|
|
58
|
-
}
|
|
59
|
-
getHelp() {
|
|
60
|
-
return `
|
|
61
|
-
restart - Restart the proxy server process
|
|
62
|
-
|
|
63
|
-
Usage:
|
|
64
|
-
cdp restart
|
|
65
|
-
cdp restart --force
|
|
66
|
-
|
|
67
|
-
Description:
|
|
68
|
-
Restarts the proxy server process. This will:
|
|
69
|
-
- Stop the current proxy server process
|
|
70
|
-
- Clear all stored console messages and network requests
|
|
71
|
-
- Start a new proxy server process
|
|
72
|
-
|
|
73
|
-
When to use:
|
|
74
|
-
Use this command when console or network command output becomes stale:
|
|
75
|
-
- Console messages are not refreshing or showing old data
|
|
76
|
-
- Network requests are not updating or displaying outdated information
|
|
77
|
-
- Logs appear to be stuck or not reflecting current browser state
|
|
78
|
-
Restarting the proxy will clear the message store and start fresh monitoring.
|
|
79
|
-
|
|
80
|
-
Options:
|
|
81
|
-
--force Force restart even if proxy is healthy
|
|
82
|
-
|
|
83
|
-
Examples:
|
|
84
|
-
# Restart the proxy server
|
|
85
|
-
cdp restart
|
|
86
|
-
|
|
87
|
-
# Force restart even if proxy is healthy
|
|
88
|
-
cdp restart --force
|
|
89
|
-
|
|
90
|
-
Note:
|
|
91
|
-
- Restarting the proxy will clear all stored console messages and network requests
|
|
92
|
-
- The proxy server must be restarted if logs are not refreshing properly
|
|
93
|
-
- After restart, you may need to reconnect to Chrome DevTools
|
|
94
|
-
`;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
exports.RestartProxyHandler = RestartProxyHandler;
|